diff --git a/ApophysisAV.dpr b/ApophysisAV.dpr
index e7ff67f..4470ad9 100644
--- a/ApophysisAV.dpr
+++ b/ApophysisAV.dpr
@@ -2,7 +2,8 @@
Apophysis Copyright (C) 2001-2004 Mark Townsend
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis "7X" Copyright (C) 2009-2013 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -29,14 +30,12 @@ uses
Vcl.Themes,
Vcl.Styles,
Binary in 'IO\Binary.pas',
- Base64 in 'IO\Base64.pas',
- sdStringTable in 'System\sdStringTable.pas',
- CustomDrawControl in 'System\CustomDrawControl.pas',
- LibXmlComps in 'System\LibXmlComps.pas',
LibXmlParser in 'System\LibXmlParser.pas',
+ LibXmlComps in 'System\LibXmlComps.pas',
+ CustomDrawControl in 'System\CustomDrawControl.pas',
RegexHelper in 'System\RegexHelper.pas',
CurvesControl in 'System\CurvesControl.pas',
- {$ifndef Apo7X64}
+ {$ifndef CPUX64}
AsmRandom in 'System\AsmRandom.pas',
{$endif }
Global in 'Core\Global.pas',
@@ -60,6 +59,7 @@ uses
BucketFillerThread in 'Rendering\BucketFillerThread.pas',
RenderThread in 'Rendering\RenderThread.pas',
ImageMaker in 'Rendering\ImageMaker.pas',
+ MathExpressions in 'System\MathExpressions.pas',
varSinusoidal in 'Variations\varSinusoidal.pas',
varLog in 'Variations\varLog.pas',
varModulus in 'Variations\varModulus.pas',
@@ -131,6 +131,7 @@ uses
varPreCircleCrop in 'Variations\varPreCircleCrop.pas',
varPreCrop in 'Variations\varPreCrop.pas',
varPreFalloff2 in 'Variations\varPreFalloff2.pas',
+ varPreMobius in 'Variations\varPreMobius.pas',
varPostBoarders2 in 'Variations\varPostBoarders2.pas',
varPostBwraps in 'Variations\varPostBwraps.pas',
varPostCurl in 'Variations\varPostCurl.pas',
@@ -138,6 +139,7 @@ uses
varPostCircleCrop in 'Variations\varPostCircleCrop.pas',
varPostCrop in 'Variations\varPostCrop.pas',
varPostFalloff2 in 'Variations\varPostFalloff2.pas',
+ varPostMobius in 'Variations\varPostMobius.pas',
varPostSpherical in 'Variations\varPostSpherical.pas',
varPostSinusoidal in 'Variations\varPostSinusoidal.pas',
varProjective in 'Variations\varProjective.pas',
@@ -178,30 +180,29 @@ uses
SavePreset in 'Forms\SavePreset.pas' {SavePresetForm},
SplashForm in 'Forms\SplashForm.pas' {SplashWindow},
Template in 'Forms\Template.pas' {TemplateForm},
- Curves in 'Forms\Curves.pas' {CurvesForm},
Preview in 'Forms\Preview.pas' {PreviewForm},
FormFavorites in 'Forms\FormFavorites.pas' {FavoritesForm},
ScriptForm in 'Forms\ScriptForm.pas' {ScriptEditor},
ScriptRender in 'Forms\ScriptRender.pas' {ScriptRenderForm},
ColorRangeForm in 'Forms\ColorRangeForm.pas' {ColorSelection},
Chaos in 'Forms\Chaos.pas' {ChaosForm},
- VarOrderForm in 'Forms\VarOrderForm.pas' {VarOrder};
+ VarOrderForm in 'Forms\VarOrderForm.pas' {VarOrder},
+ Animate in 'Forms\Animate.pas' {AnimateForm},
+ FlameComment in 'Forms\FlameComment.pas' {CommentForm};
{$R *.res}
- {$R Apophysis.res}
+{$R Apophysis.res}
+
begin
-
ReportMemoryLeaksOnShutdown := true;
- InitializePlugins;
-
SplashWindow := TSplashWindow.Create(Application);
SplashWindow.Show;
Application.Initialize;
SplashWindow.Update;
- {$ifdef Apo7X64}
+ {$ifdef CPUX64}
Application.Title := 'Apophysis AV (64 bit)';
{$else}
Application.Title := 'Apophysis AV (32 bit)';
@@ -222,7 +223,6 @@ begin
Application.CreateForm(TSaveForm, SaveForm);
Application.CreateForm(TSavePresetForm, SavePresetForm);
Application.CreateForm(TTemplateForm, TemplateForm);
- Application.CreateForm(TCurvesForm, CurvesForm);
Application.CreateForm(TPreviewForm, PreviewForm);
Application.CreateForm(TFavoritesForm, FavoritesForm);
Application.CreateForm(TScriptEditor, ScriptEditor);
@@ -230,6 +230,8 @@ begin
Application.CreateForm(TColorSelection, ColorSelection);
Application.CreateForm(TChaosForm, ChaosForm);
Application.CreateForm(TVarOrder, VarOrder);
+ Application.CreateForm(TAnimateForm, AnimateForm);
+ Application.CreateForm(TCommentForm, CommentForm);
Application.UpdateFormatSettings := False;
FormatSettings.DecimalSeparator := '.';
Application.Run;
diff --git a/ApophysisAV.dproj b/ApophysisAV.dproj
index 8d94345..32d412f 100644
--- a/ApophysisAV.dproj
+++ b/ApophysisAV.dproj
@@ -8,7 +8,7 @@
Application
VCL
18.8
- Win32
+ Win64
true
@@ -58,7 +58,7 @@
true
- CompanyName=;FileDescription=IFS Fractal Generator;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis Phoenix Edition;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0
+ CompanyName=;FileDescription=IFS Fractal Generator;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis Phoenix Edition;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0
$(BDS)\bin\default_app.manifest
ApophysisAV_Icon2.ico
false
@@ -86,7 +86,7 @@
ApophysisAV
true
"Cyan Night|VCLSTYLE|$(BDSCOMMONDIR)\Styles\CyanNight.vsf";"Ruby Graphite|VCLSTYLE|$(BDSCOMMONDIR)\Styles\RubyGraphite.vsf"
- 1
+ 2
..\..\Out\x86\
@@ -95,7 +95,7 @@
true
$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
- CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV "Phoenix Edition";ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0
+ CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV "Phoenix Edition";ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0
ApophysisAV_Icon.ico
@@ -105,7 +105,7 @@
Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
- CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV "Phoenix Edition";ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0
+ CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV "Phoenix Edition";ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0
ApophysisAV_Icon.ico
@@ -115,14 +115,14 @@
RELEASE;$(DCC_Define)
- CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.1.0
+ CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.2.0
true
Debug
ApophysisAV_Icon.ico
true
- CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV_64.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.1.0
+ CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV_64.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.2.0
Debug
ApophysisAV_Icon.ico
@@ -130,13 +130,13 @@
DEBUG;$(DCC_Define)
false
true
- CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.1.0;InternalName=ApophysisAV;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV "Phoenix Edition";ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0
+ CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.2.0;InternalName=ApophysisAV;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV "Phoenix Edition";ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0
true
true
Debug
- CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.1.0
+ CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.2.0
ApophysisAV_Icon1.ico
@@ -145,7 +145,7 @@
true
true
Debug
- CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV64.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.1.0
+ CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV64.exe;ProductName=Apophysis AV "Phoenix Edition";ProductVersion=1.0.2.0
ApophysisAV_Icon.ico
@@ -153,11 +153,9 @@
MainSource
-
-
-
-
+
+
@@ -182,6 +180,7 @@
+
@@ -253,6 +252,7 @@
+
@@ -260,6 +260,7 @@
+
@@ -334,9 +335,6 @@
-
-
-
@@ -358,6 +356,14 @@
+
+
+ dfm
+
+
+
+ dfm
+
Cfg_2
diff --git a/ApophysisAV.res b/ApophysisAV.res
index b396713..01751d3 100644
Binary files a/ApophysisAV.res and b/ApophysisAV.res differ
diff --git a/ColorMap/GradientHlpr.pas b/ColorMap/GradientHlpr.pas
index d26d290..3b0c75d 100644
--- a/ColorMap/GradientHlpr.pas
+++ b/ColorMap/GradientHlpr.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,19 +27,12 @@ unit GradientHlpr;
interface
uses
- windows, Graphics, Cmap;
-
-const
- PixelCountMax = 32768;
-
-type
- pRGBTripleArray = ^TRGBTripleArray;
- TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
+ Graphics, Cmap;
type
TGradientHelper = class
private
- procedure RGBBlend(a, b: integer; var Palette: TColorMap);
+ //procedure RGBBlend(a, b: integer; var Palette: TColorMap);
public
function GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap;
function RandomGradient: TColorMap;
@@ -81,7 +74,7 @@ begin
Result := BitMap;
end;
-///////////////////////////////////////////////////////////////////////////////
+{//////////////////////////////////////////////////////////////////////////////}
function TGradientHelper.RandomGradient: TColorMap;
var
a, b, i, n, nodes: integer;
@@ -143,7 +136,8 @@ begin
Result := Pal;
end;
-///////////////////////////////////////////////////////////////////////////////
+{//////////////////////////////////////////////////////////////////////////////}
+(* // AV: how many duplicated code has this app...
procedure TGradientHelper.RGBBlend(a, b: integer; var Palette: TColorMap);
{ Linear blend between to indices of a palette }
var
@@ -181,8 +175,8 @@ begin
Palette[i mod 256][2] := Round(c);
end;
end;
-
-///////////////////////////////////////////////////////////////////////////////
+*)
+{//////////////////////////////////////////////////////////////////////////////}
initialization
GradientHelper := TGradientHelper.create;
finalization
diff --git a/ColorMap/cmap.pas b/ColorMap/cmap.pas
index fd07fbc..1bbac69 100644
--- a/ColorMap/cmap.pas
+++ b/ColorMap/cmap.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -25,23 +25,32 @@ unit Cmap;
interface
-uses sysutils, classes;
+uses cmapdata, SysUtils, Classes, Windows;
+
+// AV: moved following from Main unit and deleted all duplicates
+const
+ PixelCountMax = 32768;
type
+ pRGBTripleArray = ^TRGBTripleArray;
+ TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
+
TColorMap = array[0..255, 0..3] of integer;
-type
- EFormatInvalid = class(Exception);
+ EPaletteInvalid = class(Exception); // AV: renamed due to name-space conflicts
const
RANDOMCMAP = -1;
- NRCMAPS = 704;
+ NRCMAPS = NMAPS + 1; //704;
procedure GetCmap(var Index: integer; const hue_rotation: double; out cmap: TColorMap);
procedure GetCmapName(var Index: integer; out Name: string);
procedure rgb2hsv(const rgb: array of double; out hsv: array of double);
procedure hsv2rgb(const hsv: array of double; out rgb: array of double);
function GetGradient(FileName, Entry: string): string;
+function GetVal(token: string): string; // AV: make public
+function ReplaceTabs(str: string): string; // AV: make public
+function CreatePalette(strng: string): TColorMap; // AV: moved from RndFlame
function GetPalette(strng: string; var Palette: TColorMap): boolean;
procedure GetTokens(s: string; var mlist: TStringList);
procedure HSVBlend(a, b: integer; var Palette: TColorMap); // AV
@@ -51,7 +60,7 @@ procedure Brighten(const n: byte; var r, g, b: byte); // AV
implementation
uses
- cmapdata, Math;
+ Math;
procedure rgb2hsv(const rgb: array of double; out hsv: array of double);
var
@@ -91,10 +100,6 @@ var
f, p, q, t, v: double;
begin
try
-// rgb[0] := 0;
-// rgb[1] := 0;
-// rgb[2] := 0;
-
j := floor(hsv[0]);
f := hsv[0] - j;
@@ -111,6 +116,11 @@ begin
5: begin rgb[0] := v; rgb[1] := p; rgb[2] := q; end;
end;
except on EMathError do
+ begin
+ rgb[0] := 0;
+ rgb[1] := 0;
+ rgb[2] := 0;
+ end;
end;
end;
@@ -152,7 +162,6 @@ begin
Name := CMapNames[Index];
end;
-
procedure RGBBlend(a, b: integer; var Palette: TColorMap);
{ Linear blend between to indices of a palette }
var
@@ -286,6 +295,83 @@ begin
end;
end;
+function CreatePalette(strng: string): TColorMap; // AV: moved from RndFlame
+{ 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 EPaletteInvalid.Create('No closing brace');
+ if Pos('{', Strings[0]) = 0 then raise EPaletteInvalid.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 EPaletteInvalid.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);
+ a := StrToInt(Colors[i]); // AV: added precalc
+ Result[index][0] := a mod 256;
+ Result[index][1] := trunc(a / 256) mod 256;
+ Result[index][2] := trunc(a / 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 EPaletteInvalid do
+ begin
+ //
+ end;
+ end;
+ finally
+ Tokens.Free;
+ Strings.Free;
+ Indices.Free;
+ Colors.Free;
+ end;
+end;
function GetPalette(strng: string; var Palette: TColorMap): boolean;
{ Loads a palette from a gradient string }
@@ -304,8 +390,10 @@ begin
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.');
+ if Pos('}', Strings.Text) = 0 then
+ raise EPaletteInvalid.Create('No closing brace');
+ if Pos('{', Strings[0]) = 0 then
+ raise EPaletteInvalid.Create('No opening brace.');
GetTokens(ReplaceTabs(Strings.Text), Tokens);
i := 0;
while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do
@@ -322,7 +410,8 @@ begin
Palette[i][1] := 0;
Palette[i][2] := 0;
end;
- if Indices.Count = 0 then raise EFormatInvalid.Create('No color info');
+ if Indices.Count = 0 then
+ raise EPaletteInvalid.Create('No color info');
for i := 0 to Indices.Count - 1 do
begin
try
@@ -330,8 +419,8 @@ begin
while index < 0 do inc(index, 400);
index := Round(Index * (255 / 399));
indices[i] := IntToStr(index);
- assert(index>=0);
- assert(index<256);
+ assert(index >= 0);
+ assert(index < 256);
Palette[index][0] := StrToInt(Colors[i]) mod 256;
Palette[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256;
Palette[index][2] := trunc(StrToInt(Colors[i]) / 65536);
@@ -351,7 +440,7 @@ begin
b := StrToInt(Indices[0]) + 256;
RGBBlend(a, b, Palette);
end;
- except on EFormatInvalid do
+ except on EPaletteInvalid do
begin
Result := False;
end;
diff --git a/ColorMap/cmapdata.pas b/ColorMap/cmapdata.pas
index ba368e7..9d0b0bf 100644
--- a/ColorMap/cmapdata.pas
+++ b/ColorMap/cmapdata.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -31,7 +31,7 @@ interface
Const
NMAPS = 703;
- cmaps : array[0..NMAPS,0..255,0..2] of byte =
+ cmaps : array[0..NMAPS, 0..255, 0..2] of byte =
(
// 0 south-sea-bather
((185, 234, 235), (193, 238, 235), (197, 242, 235), (201, 242, 235),
diff --git a/Core/BaseVariation.pas b/Core/BaseVariation.pas
index ac356c4..c1fbb16 100644
--- a/Core/BaseVariation.pas
+++ b/Core/BaseVariation.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -94,7 +94,7 @@ const
PI_2 = 1.5707963267948966192313216916398; // AV
function fmod(x, y: double) : double;
-procedure SinhCosh(const v: double; var sh, ch: double); // AV
+procedure SinhCosh(const v: double; var sh, ch: double); inline; // AV
implementation
diff --git a/Core/Bezier.pas b/Core/Bezier.pas
index 23bcae0..eee8fb0 100644
--- a/Core/Bezier.pas
+++ b/Core/Bezier.pas
@@ -24,6 +24,7 @@ procedure BezierSolve(t: double; src: BezierPoints; w: BezierWeights; var soluti
function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double;
implementation
+
procedure BezierCopy(src: BezierPoints; var tgt: BezierPoints);
var
i, n: integer;
@@ -32,6 +33,7 @@ implementation
for i := 0 to n - 1 do
tgt[i] := src[i];
end;
+
procedure BezierSetRect(var points: BezierPoints; flip: boolean; rect: BezierRect);
var
i, n: integer;
@@ -47,6 +49,7 @@ implementation
points[i].y := f * (rect.y1 - rect.y0) + rect.y0;
end;
end;
+
procedure BezierUnsetRect(var points: BezierPoints; flip: boolean; rect: BezierRect);
var
i, n: integer;
@@ -84,6 +87,7 @@ implementation
solution.x := nom_x / denom;
solution.y := nom_y / denom;
end;
+
function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double;
var
p: BezierPoint;
diff --git a/Core/Chaotica.pas b/Core/Chaotica.pas
index 7eb1db6..82cb195 100644
--- a/Core/Chaotica.pas
+++ b/Core/Chaotica.pas
@@ -2,8 +2,11 @@ unit Chaotica;
interface
-uses Global, RegularExpressionsCore, RegexHelper, Classes, SysUtils, XFormMan, Windows,
- ShellAPI, Forms, ControlPoint, Translation;
+uses Global, RegularExpressionsCore, RegexHelper, Classes, SysUtils,
+ Windows, ShellAPI, ControlPoint, Translation;
+
+const
+ export_flame = 'chaotica_export.flame';
function C_GetPathOf(filename: string; usex64: boolean): string;
function C_SupportsDllPlugins(usex64: boolean): boolean;
@@ -12,13 +15,11 @@ function C_IsVariationNative(name: string; usex64: boolean): boolean;
function C_IsDllPluginInstalled(filename: string): boolean;
procedure C_SyncDllPlugins;
-procedure C_InstallVariation(name: string);
procedure C_ExecuteChaotica(flamexml: string; plugins: TStringList; usex64: boolean);
+//procedure C_InstallVariation(name: string);
implementation
-uses Main;
-
(* // AV: rewrote and moved to Global unit
function CheckX64: Boolean;
var
@@ -99,19 +100,19 @@ begin
blacklist := TStringList.Create;
if not FileExists(ChaoticaPath + '\plugin_dll_blacklist.txt') then
begin
- blacklist.Add('avMobius.dll');
- blacklist.Add('Cross.dll');
- blacklist.Add('Epispiral.dll');
- blacklist.Add('EpispiralVariationPlugin.dll');
- blacklist.Add('FlowerVariationPlugin.dll');
- blacklist.Add('Lissajous.dll');
- blacklist.Add('Mandelbrot.dll');
- blacklist.Add('ShapeVariationPlugin.dll');
- blacklist.Add('slinky.dll');
- blacklist.Add('Spirograph.dll');
- blacklist.Add('Square.dll');
- blacklist.Add('Stretchy Pants.dll');
- blacklist.Add('Waffle.dll');
+ blacklist.Add('avMobius.dll');
+ blacklist.Add('Cross.dll');
+ blacklist.Add('Epispiral.dll');
+ blacklist.Add('EpispiralVariationPlugin.dll');
+ blacklist.Add('FlowerVariationPlugin.dll');
+ blacklist.Add('Lissajous.dll');
+ blacklist.Add('Mandelbrot.dll');
+ blacklist.Add('ShapeVariationPlugin.dll');
+ blacklist.Add('slinky.dll');
+ blacklist.Add('Spirograph.dll');
+ blacklist.Add('Square.dll');
+ blacklist.Add('Stretchy Pants.dll');
+ blacklist.Add('Waffle.dll');
blacklist.SaveToFile(ChaoticaPath + '\plugin_dll_blacklist.txt');
end;
@@ -182,7 +183,7 @@ begin
end;
////////////////////////////////////////////////////////////////////
-
+(*
procedure C_InstallVariation(name: string);
var
filename: string;
@@ -195,6 +196,7 @@ begin
CopyFile(PCHAR(filename), PCHAR(C_GetPathOf('plugins\' +
ExtractFileName(filename), false)), false);
end;
+*)
procedure C_SyncDllPlugins;
var
@@ -243,19 +245,17 @@ var
begin
fails := TStringList.Create;
- {$ifdef Apo7X64}
+ {$ifdef CPUX64}
fin_usex64 := true;
{$else}
- fin_usex64 := usex64 and CheckX64; // currently useless...
+ fin_usex64 := usex64; // currently useless...
for i := 0 to plugins.Count - 1 do begin
- name := GetFileNameOfVariation(plugins.Strings[i]);
- if (name = '') then name := plugins.Strings[i];
+ name := plugins.Strings[i];
fin_usex64 := fin_usex64 and C_IsVariationNative(name, usex64);
end;
for i := 0 to plugins.Count - 1 do begin
- name := GetFileNameOfVariation(plugins.Strings[i]);
- if (name = '') then name := plugins.Strings[i]; // assume built-in
+ name := plugins.Strings[i]; // assume built-in
if not C_IsVariationNative(name, fin_usex64) then begin // not native -> try install
if C_SupportsDllPlugins(fin_usex64) then // dll unsupported -> fail
@@ -271,17 +271,18 @@ begin
name := C_GetPathOf('chaotica.exe', fin_usex64);
if (not FileExists(name)) then begin
messagebox(0, PCHAR(TextByKey('main-status-nochaotica')),
- PCHAR('Apophysis AV'), MB_ICONHAND);
+ 'Apophysis AV', MB_ICONHAND);
+ fails.Free; // AV: fixed possible memory leak
Exit;
end;
if (fails.Count > 0) then begin
messagebox(0, PCHAR(TextByKey('main-status-oldchaotica')),
- PCHAR('Apophysis AV'), MB_ICONHAND or MB_OK);
+ 'Apophysis AV', MB_ICONHAND or MB_OK);
end;
- // TODO: add directory cleaning
- fname := GetEnvironmentVariable('TEMP') + '\chaotica_export.flame';
+ // TODO: add directory cleaning // <-- AV: done
+ fname := APPDATA + export_flame; // AV: moved into app folder
txt := TStringList.Create;
txt.Text := flamexml;
@@ -290,11 +291,8 @@ begin
txt.Free;
fails.Free;
- //if fin_usex64 then MessageBox(0, PCHAR('DBG:x64'), PCHAR(''), MB_OK)
- //else MessageBox(0, PCHAR('DBG:x86'), PCHAR(''), MB_OK) ;
-
- ShellExecute(application.handle, PChar('open'), pchar(name),
- PChar('"' + fname + '"'), PChar(ExtractFilePath(name)), SW_SHOWNORMAL);
+ ShellExecute(0, PChar('open'), pchar(name), PChar('"' + fname + '"'),
+ PChar(ExtractFilePath(name)), SW_SHOWNORMAL);
end;
end.
diff --git a/Core/Global.pas b/Core/Global.pas
index 8d37eff..c7e9a91 100644
--- a/Core/Global.pas
+++ b/Core/Global.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -28,29 +28,12 @@ interface
uses
Windows, SysUtils, Classes, SyncObjs, Controls, Graphics, Math,
- cmap, ControlPoint, Xform, CommDlg;
+ cmap, Xform, CommDlg;
type
- EFormatInvalid = class(Exception);
- // AV: chanded the name to avoid conflicts with XForm
- TMatrix2 = array[0..1, 0..1] of double;
+ TFileType = (ftApo, ftXML); // AV: moved here from ControlPoint
-{ Weight manipulation }
-{ Triangle transformations }
-function triangle_area(t: TTriangle): double;
-function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean;
-function line_dist(x, y, x1, y1, x2, y2: double): double;
-function dist(x1, y1, x2, y2: double): double;
-procedure MultMatrix(var s: TMatrix2; const m: TMatrix2);
-{ Parsing functions }
-function GetVal(token: string): string;
-function ReplaceTabs(str: string): string;
-{ Palette and gradient functions }
-//function GetGradient(FileName, Entry: string): string;
{ Misc }
-function det(a, b, c, d: double): double;
-function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double;
- var a, b, e: double): double;
function OpenSaveFileDialog(Parent: TWinControl;
const DefExt,
Filter,
@@ -63,66 +46,53 @@ function OpenSaveFileDialog(Parent: TWinControl;
DoOpen: Boolean): Boolean;
procedure LoadThumbnailPlaceholder(ThumbnailSize : integer);
function GetEnvVarValue(const VarName: string): string;
-function Round6(x: double): double;
+function Round6(x: double): double; inline;
function MiddleColor(const clOne, clTwo: TColor): TColor; // AV
function CheckX64: Boolean; // AV
const
APP_NAME: string = 'Apophysis AV';
APP_VERSION: string = 'Phoenix Edition';
- {$ifdef Apo7X64}
+ {$ifdef CPUX64}
APP_BUILD: string = ' - 64 bit';
{$else}
APP_BUILD: string = ' - 32 bit';
{$endif}
- MAX_TRANSFORMS: integer = 100;
- prefilter_white: integer = 1024;
- eps: double = 1E-10;
- White_level = 200;
- FT_BMP = 1; FT_PNG = 2; FT_JPG = 3;
- //clyellow1 = TColor($17FCFF);
- //clplum2 = TColor($ECA9E6);
- //clSlateGray = TColor($837365);
+ // MAX_TRANSFORMS: integer = 100; // AV: why if we have NXFORMS?
+ // eps: double = 1E-10; // AV: this one is used nowhere
+ prefilter_white: integer = 1024;
+ White_level = 200;
+ //FT_BMP = 1; FT_PNG = 2; FT_JPG = 3;
+
const
crEditArrow = 20;
crEditMove = 21;
crEditRotate = 22;
crEditScale = 23;
-const
- SingleBuffer : boolean =
- {$ifdef Apo7X64}
- false
- {$else}
- true
- {$endif};
-
var
MainSeed: integer;
- MainTriangles: TTriangles; // ControlPoint.TTriangles;
- Transforms: integer; // Count of Tranforms
+ Transforms: smallint; // Count of Tranforms
EnableFinalXform: boolean;
- AppPath: string; // Path of application file
+ AppPath, AppData: string; // Path of application file
OpenFile: string; // Name of currently open file
- CanDrawOnResize: boolean;
- PreserveWeights: boolean;
+ CanDrawOnResize: boolean;
AlwaysCreateBlankFlame : boolean;
- // StartupCheckForUpdates : boolean;
- TBWidth1 : integer;
- TBWidth2 : integer;
- TBWidth3 : integer;
- TBWidth4 : integer;
- TBWidth5 : integer;
+
ThumbnailPlaceholder : TBitmap;
WarnOnMissingPlugin : boolean;
- EmbedThumbnails : boolean;
RandomizeTemplates: boolean;
LanguageFile : string;
AvailableLanguages : TStringList;
PluginPath : string;
+ (*
+ PreserveWeights: boolean;
+ StartupCheckForUpdates : boolean;
+ EmbedThumbnails : boolean;
+ *)
- // AV: GUI Theme Stuff
+ { AV: GUI Theme Stuff }
CurrentStyle: string;
// theme-aware system colors
WinColor, BrightColor, MidColor, TextColor: TColor;
@@ -132,7 +102,7 @@ var
UPRSampleDensity: integer;
UPRFilterRadius: double;
- UPROversample: integer;
+ UPROversample: byte;
UPRAdjustDensity: boolean;
UPRColoringIdent: string;
UPRColoringFile: string;
@@ -140,59 +110,58 @@ var
UPRFormulaFile: string;
UPRWidth: Integer;
UPRHeight: Integer;
- ImageFolder: string;
UPRPath: string; // Name and folder of last UPR file
- cmap_index: integer; // Index to current gradient
- Variation: TVariation; // Current variation // ControlPoint.TVariation;
- NumTries, TryLength: integer; // Settings for smooth palette
- SmoothPaletteFile: string;
{ Editor }
UseFlameBackground, UseTransformColors: boolean;
HelpersEnabled: boolean;
- EditorBkgColor, ReferenceTriangleColor: integer;
- GridColor1, GridColor2, HelpersColor, FlipColor: integer;
+ EditorBkgColor, ReferenceTriangleColor: TColor;
+ GridColor1, GridColor2, HelpersColor, FlipColor: TColor;
ExtEditEnabled, TransformAxisLock, RebuildXaosLinks: boolean;
ShowAllXforms: boolean;
EditorPreviewTransparency: integer;
EnableEditorPreview: boolean;
- AllowResetCoefs, AllowResetLinear: boolean; // AV
+ AllowResetCoefs, AllowResetLinear, UseTriangleSync: boolean; // AV
{ Display }
- defSampleDensity, defPreviewDensity: Double;
+ defSampleDensity: Double;
defGamma, defBrightness, defVibrancy, defContrast, // AV
defFilterRadius, defGammaThreshold: Double;
- defOversample: integer;
+ defOversample: byte; // integer;
FUSE: byte; // AV: moved from ControlPoint and changed to variable
RhombTR, SquareTR, HexTR: single; // AV: tile radii
+ cmap_index: integer; // Index to current gradient
+
{ Render }
renderDensity, renderFilterRadius: double;
renderOversample, renderWidth, renderHeight: integer;
- // renderBitsPerSample: integer;
renderPath: string;
- JPEGQuality: integer;
- renderFileFormat: integer;
- InternalBitsPerSample: integer;
+ renderFileFormat: byte; // integer;
+
EmbedFlame, SaveInFlame: boolean; // AV
- NrTreads: Integer;
- UseNrThreads: byte; // AV: currently holds Nr CPU cores
+ NrTreads: smallint;
+ UseNrThreads: smallint; // AV: currently holds Nr CPU cores
- PNGTransparency: integer;
+ JPEGQuality: smallint;
+ PNGTransparency: byte; // integer;
ShowTransparency: boolean;
MainPreviewScale: double;
ExtendMainPreview: boolean;
- (*
+(*
+ renderBitsPerSample: integer;
+ InternalBitsPerSample: integer;
+
StoreEXIF : boolean;
StoreParamsEXIF : boolean;
ExifAuthor : string;
- *)
+*)
{ Defaults }
@@ -203,27 +172,23 @@ var
ClassicListMode: boolean;
ConfirmDelete: boolean; // Flag confirmation of entry deletion
OldPaletteFormat: boolean;
- ConfirmExit: boolean;
- ConfirmStopRender: boolean;
- ConfirmClearScript: boolean;
+ ConfirmExit, ConfirmStopRender: boolean;
+ ConfirmClearScript, ConfirmResetUndo: boolean; // AV
SavePath, SmoothPalettePath: string;
RandomPrefix, RandomDate: string;
RandomIndex: integer;
FlameFile, GradientFile, GradientEntry, FlameEntry: string;
ParamFolder: string;
prevLowQuality, prevMediumQuality, prevHighQuality: double;
- defSmoothPaletteFile: string;
+
+ { Settings for smooth palette }
+ SmoothPaletteFile, defSmoothPaletteFile: string;
+ NumTries, TryLength: integer;
+ ImageFolder: string;
+
BrowserPath: string; // Stored path of browser open dialog
- EditPrevQual, MutatePrevQual, AdjustPrevQual: byte; // Integer;
- ThumbPrevQual: byte; // AV
- randMinTransforms, randMaxTransforms: integer;
- mutantMinTransforms, mutantMaxTransforms: integer;
- KeepBackground: boolean;
- RandBackColor: integer; // AV
- randGradient: Integer;
- randGradientFile: string;
- randColorBlend: byte; // AV
- EqualStripes: boolean;
+ EditPrevQual, MutatePrevQual, AdjustPrevQual: byte; // AV: menu item index
+ ThumbPrevQual, AnimPrevQual: byte; // AV
defFlameFile: string;
defScriptFile: string; // AV
SetEngLayout: boolean; // AV
@@ -237,9 +202,15 @@ var
ShowRenderStats, ShowRenderImage: boolean;
LowerRenderPriority: boolean;
- SymmetryType: integer;
- SymmetryOrder: integer;
- SymmetryNVars: integer;
+ { AV: Animation parameters }
+ AnimFPS: word;
+ defAnimPrefix: string;
+ defFrameExt: shortint;
+ CreateAnimFolder: boolean;
+
+ SymmetryType: shortint;
+ SymmetryOrder: smallint;
+ SymmetryNVars: word;
Variations: array of boolean;
FavouriteVariations: array of boolean;
@@ -248,23 +219,38 @@ var
FlameEnumMode: byte; // AV
{ For random gradients }
-
MinNodes, MaxNodes, MinHue, MaxHue, MinSat, MaxSat, MinLum, MaxLum: integer;
- //ReferenceMode: integer;
+ randGradient: shortint;
+ randGradientFile: string;
+ randColorBlend: byte; // AV
+ EqualStripes: boolean;
+
BatchSize: Integer;
- // Compatibility: integer; //0 = original, 1 = Drave's
+ randMinTransforms, randMaxTransforms: smallint;
+ mutantMinTransforms, mutantMaxTransforms: smallint;
+ KeepBackground: boolean;
+ RandBackColor: TColor; // AV
+
+ { Scripting }
Favorites: TStringList;
Script: string;
ScriptPath: string;
- // SheepServer, SheepNick, SheepURL, SheepPW,
+
flam3Path, helpPath: string;
- ExportBatches, ExportOversample, ExportWidth, ExportHeight, ExportFileFormat: Integer;
- ExportFilter, ExportDensity: Double;
+ ExportWidth, ExportHeight: Integer;
+ ExportOversample, ExportFileFormat: byte; // AV
+ ExportFilter, ExportDensity, ExportGammaTreshold: Double;
ExportEstimator, ExportEstimatorMin, ExportEstimatorCurve: double;
- ExportJitters: integer;
- ExportGammaTreshold: double;
+
+ (* // AV: user cannot change them, anyway
+ ReferenceMode: integer;
+ Compatibility: integer; //0 = original, 1 = Drave's
+ SheepServer, SheepNick, SheepURL, SheepPW: string;
+ ExportBatches, ExportJitters: byte;
+ ResizeOnLoad: Boolean;
+ *)
+
OpenFileType: TFileType;
-// ResizeOnLoad: Boolean;
ShowProgress: Boolean;
defLibrary: string;
LimitVibrancy: Boolean;
@@ -275,12 +261,10 @@ var
AutoOpenLog: Boolean;
AutoSaveEnabled: Boolean;
- AutoSaveFreq: integer;
+ AutoSaveFreq: byte;
AutoSavePath: string;
- LineCenterColor : integer;
- LineThirdsColor : integer;
- LineGRColor : integer;
+ LineCenterColor, LineThirdsColor, LineGRColor : TColor;
EnableGuides : boolean;
implementation
@@ -290,14 +274,12 @@ var
BufSize: Integer; // buffer size required for value
begin
// Get required buffer size (inc. terminal #0)
- BufSize := GetEnvironmentVariable(
- PChar(VarName), nil, 0);
+ BufSize := GetEnvironmentVariable(PChar(VarName), nil, 0);
if BufSize > 0 then
begin
// Read env var value into result string
SetLength(Result, BufSize - 1);
- GetEnvironmentVariable(PChar(VarName),
- PChar(Result), BufSize);
+ GetEnvironmentVariable(PChar(VarName), PChar(Result), BufSize);
end
else
// No such environment variable
@@ -322,7 +304,8 @@ begin
with ThumbnailPlaceholder.Canvas do begin
Brush.Color := $000000;
FillRect(Rect(0, 0, ThumbnailPlaceholder.Width, ThumbnailPlaceholder.Height));
- Draw(round(ThumbnailSize / 2 - pi_width / 2), round(ThumbnailSize / 2 - pi_height / 2), placeholderIcon);
+ Draw((ThumbnailSize - pi_width) shr 1, (ThumbnailSize - pi_height) shr 1,
+ placeholderIcon);
end;
placeholderIcon.Free;
@@ -335,13 +318,6 @@ begin
((((clOne shr 16) and $ff) + ((clTwo shr 16) and $ff)) shr 1 ) shl 16;
end;
-{ IFS }
-
-function det(a, b, c, d: double): double;
-begin
- Result := (a * d - b * c);
-end;
-
function Round6(x: double): double;
// Really ugly, but it works
begin
@@ -351,281 +327,15 @@ begin
Result := RoundTo(x, -6);
end;
-procedure MultMatrix(var s: TMatrix2; const m: TMatrix2); // AV: moved from Main
-var
- a, b, c, d, e, f, g, h: double;
-begin
- a := s[0, 0];
- b := s[0, 1];
- c := s[1, 0];
- d := s[1, 1];
- e := m[0, 0];
- f := m[0, 1];
- g := m[1, 0];
- h := m[1, 1];
-{
- [a, b][e ,f] [a*e+b*g, a*f+b*h]
- [ ][ ] = [ ]
- [c, d][g, h] [c*e+d*g, c*f+d*h]
-}
- s[0, 0] := a * e + b * g;
- s[0, 1] := a * f + b * h;
- s[1, 0] := c * e + d * g;
- s[1, 1] := c * f + d * h;
-end;
-
-function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double;
- var a, b, e: double): double;
-var
- det1: double;
-begin
- det1 := x1 * det(y2, 1.0, z2, 1.0) - x2 * det(y1, 1.0, z1, 1.0)
- + 1 * det(y1, y2, z1, z2);
- if (det1 = 0.0) then
- begin
- Result := det1;
- EXIT;
- end
- else
- begin
- a := (x1h * det(y2, 1.0, z2, 1.0) - x2 * det(y1h, 1.0, z1h, 1.0)
- + 1 * det(y1h, y2, z1h, z2)) / det1;
- b := (x1 * det(y1h, 1.0, z1h, 1.0) - x1h * det(y1, 1.0, z1, 1.0)
- + 1 * det(y1, y1h, z1, z1h)) / det1;
- e := (x1 * det(y2, y1h, z2, z1h) - x2 * det(y1, y1h, z1, z1h)
- + x1h * det(y1, y2, z1, z2)) / det1;
- a := Round6(a);
- b := Round6(b);
- e := Round6(e);
- Result := det1;
- end;
-end;
-
-function dist(x1, y1, x2, y2: double): double;
-//var
-// d2: double;
-begin
-(*
- { From FDesign source
- { float pt_pt_distance(float x1, float y1, float x2, float y2) }
- d2 := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
- if (d2 = 0.0) then
- begin
- Result := 0.0;
- exit;
- end
- else
- Result := sqrt(d2);
-*)
-
- // --Z-- This is just amazing... :-\
- // Someone needed an 'FDesign source' - to compute distance between two points??!?
-
- Result := Hypot(x2-x1, y2-y1);
-end;
-
-function line_dist(x, y, x1, y1, x2, y2: double): double;
-var
- a, b, e, c: double;
-begin
- if ((x = x1) and (y = y1)) then
- a := 0.0
- else
- a := sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
- if ((x = x2) and (y = y2)) then
- b := 0.0
- else
- b := sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
- if ((x1 = x2) and (y1 = y2)) then
- e := 0.0
- else
- e := sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
- if ((a * a + e * e) < (b * b)) then
- Result := a
- else if ((b * b + e * e) < (a * a)) then
- Result := b
- else if (e <> 0.0) then
- begin
- c := (b * b - a * a - e * e) / (-2 * e);
- if ((a * a - c * c) < 0.0) then
- Result := 0.0
- else
- Result := sqrt(a * a - c * c);
- end
- else
- Result := a;
-end;
-
-function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean;
-var
- ra, rb, rc, a, b, c: double;
-begin
- Result := True;
- ra := dist(Triangles[-1].y[0], Triangles[-1].x[0],
- Triangles[-1].y[1], Triangles[-1].x[1]);
- rb := dist(Triangles[-1].y[1], Triangles[-1].x[1],
- Triangles[-1].y[2], Triangles[-1].x[2]);
- rc := dist(Triangles[-1].y[2], Triangles[-1].x[2],
- Triangles[-1].y[0], Triangles[-1].x[0]);
- a := dist(t.y[0], t.x[0], t.y[1], t.x[1]);
- b := dist(t.y[1], t.x[1], t.y[2], t.x[2]);
- c := dist(t.y[2], t.x[2], t.y[0], t.x[0]);
- if (a > ra) then
- Result := False
- else if (b > rb) then
- Result := False
- else if (c > rc) then
- Result := False
- else if ((a = ra) and (b = rb) and (c = rc)) then
- Result := False;
-end;
-
-function triangle_area(t: TTriangle): double;
-var
- base, height: double;
-begin
- try
- base := dist(t.x[0], t.y[0], t.x[1], t.y[1]);
- height := line_dist(t.x[2], t.y[2], t.x[1], t.y[1],
- t.x[0], t.y[0]);
- if (base < 1.0) then
- Result := height
- else if (height < 1.0) then
- Result := base
- else
- Result := 0.5 * base * height;
- except on E: EMathError do
- Result := 0;
- end;
-end;
-
-{ Parse }
-
-function GetVal(token: string): string;
-var
- p: integer;
-begin
- p := Pos('=', token);
- Delete(Token, 1, p);
- Result := Token;
-end;
-
-function ReplaceTabs(str: string): string;
-{Changes tab characters in a string to spaces}
-var
- i: integer;
-begin
- for i := 1 to Length(str) do
- begin
- if str[i] = #9 then
- begin
- Delete(str, i, 1);
- Insert(#32, str, i);
- end;
- end;
- Result := str;
-end;
-
-(*
-{ Palette and gradient functions }
-
-function RGBToColor(Pal: TMapPalette; index: integer): Tcolor;
-begin
- { Converts the RGB values from a palette index to the TColor type ...
- could maybe change it to SHLs }
- Result := (Pal.Blue[index] * 65536) + (Pal.Green[index] * 256)
- + Pal.Red[index];
-end;
-
-procedure rgb2hsv(const rgb: array of double; out hsv: array of double);
-var
- maxval, minval: double;
- del: double;
-begin
- Maxval := Max(rgb[0], Max(rgb[1], rgb[2]));
- Minval := Min(rgb[0], Min(rgb[1], rgb[2]));
-
- hsv[2] := maxval; // v
-
- if (Maxval > 0) and (maxval <> minval) then begin
- del := maxval - minval;
- hsv[1] := del / Maxval; //s
-
- hsv[0] := 0;
- if (rgb[0] > rgb[1]) and (rgb[0] > rgb[2]) then begin
- hsv[0] := (rgb[1] - rgb[2]) / del;
- end else if (rgb[1] > rgb[2]) then begin
- hsv[0] := 2 + (rgb[2] - rgb[0]) / del;
- end else begin
- hsv[0] := 4 + (rgb[0] - rgb[1]) / del;
- end;
-
- if hsv[0] < 0 then
- hsv[0] := hsv[0] + 6;
-
- end else begin
- hsv[0] := 0;
- hsv[1] := 0;
- end;
-end;
-
-procedure hsv2rgb(const hsv: array of double; out rgb: array of double);
-var
- j: integer;
- f, p, q, t, v: double;
-begin
- j := floor(hsv[0]);
- f := hsv[0] - j;
- v := hsv[2];
- p := hsv[2] * (1 - hsv[1]);
- q := hsv[2] * (1 - hsv[1] * f);
- t := hsv[2] * (1 - hsv[1] * (1 - f));
-
- case j of
- 0: begin rgb[0] := v; rgb[1] := t; rgb[2] := p; end;
- 1: begin rgb[0] := q; rgb[1] := v; rgb[2] := p; end;
- 2: begin rgb[0] := p; rgb[1] := v; rgb[2] := t; end;
- 3: begin rgb[0] := p; rgb[1] := q; rgb[2] := v; end;
- 4: begin rgb[0] := t; rgb[1] := p; rgb[2] := v; end;
- 5: begin rgb[0] := v; rgb[1] := p; rgb[2] := t; end;
- end;
-end;
-
-function GetGradient(FileName, Entry: string): string;
-var
- FileStrings: TStringList;
- GradStrings: TStringList;
- i: integer;
-begin
- FileStrings := TStringList.Create;
- GradStrings := TStringList.Create;
- try
- try
- FileStrings.LoadFromFile(FileName);
- for i := 0 to FileStrings.count - 1 do
- if Pos(Entry + ' ', Trim(FileStrings[i])) = 1 then break;
- GradStrings.Add(FileStrings[i]);
- repeat
- inc(i);
- GradStrings.Add(FileStrings[i]);
- until Pos('}', FileStrings[i]) <> 0;
- GetGradient := GradStrings.Text;
- except on exception do
- Result := '';
- end;
- finally
- GradStrings.Free;
- FileStrings.Free;
- end;
-end;
-*)
-
function CheckX64: Boolean; // AV
var
IsWow64Process:
function(hProcess: THandle; out Wow64Process: boolean): boolean; stdcall;
Wow64Process: boolean;
begin
+{$ifdef CPUX64}
+ Result := True;
+{$else}
IsWow64Process := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process');
Wow64Process := False;
@@ -633,6 +343,7 @@ begin
Wow64Process := IsWow64Process(GetCurrentProcess, Wow64Process) and Wow64Process;
Result := Wow64Process;
+{$endif}
end;
function ReplaceStr(Str, SearchStr, ReplaceStr: string): string;
@@ -650,36 +361,36 @@ var vI: Integer;
vBuffer: String;
vOn: Boolean;
begin
- Result:= TStringList.Create;
- vBuffer:='';
- vOn:=true;
- for vI:=1 to Length(fText) do
+ Result := TStringList.Create;
+ vBuffer := '';
+ vOn := true;
+ for vI := 1 to Length(fText) do
begin
- if (fQuotes and(fText[vI]=fSep)and vOn)or(Not(fQuotes) and (fText[vI]=fSep)) then
+ if (fQuotes and(fText[vI] = fSep)and vOn)or(Not(fQuotes) and (fText[vI] = fSep)) then
begin
- if fTrim then vBuffer:=Trim(vBuffer);
- if vBuffer='' then vBuffer:=fSep; // !!! e.g. split(',**',',')...
- if vBuffer[1]=fSep then
- vBuffer:=Copy(vBuffer,2,Length(vBuffer));
+ if fTrim then vBuffer := Trim(vBuffer);
+ if vBuffer = '' then vBuffer := fSep; // !!! e.g. split(',**',',')...
+ if vBuffer[1] = fSep then
+ vBuffer := Copy(vBuffer, 2, Length(vBuffer));
Result.Add(vBuffer);
- vBuffer:='';
+ vBuffer := '';
end;
if fQuotes then
begin
- if fText[vI]='"' then
+ if fText[vI] = '"' then
begin
- vOn:=Not(vOn);
+ vOn := Not(vOn);
Continue;
end;
- if (fText[vI]<>fSep)or((fText[vI]=fSep)and(vOn=false)) then
- vBuffer:=vBuffer+fText[vI];
+ if (fText[vI] <> fSep)or((fText[vI] = fSep)and(vOn = false)) then
+ vBuffer := vBuffer + fText[vI];
end else
- if fText[vI]<>fSep then
- vBuffer:=vBuffer+fText[vI];
+ if fText[vI] <> fSep then
+ vBuffer := vBuffer + fText[vI];
end;
- if vBuffer<>'' then
+ if vBuffer <> '' then
begin
- if fTrim then vBuffer:=Trim(vBuffer);
+ if fTrim then vBuffer := Trim(vBuffer);
Result.Add(vBuffer);
end;
end;
diff --git a/Core/Translation.pas b/Core/Translation.pas
index 8450110..7cbf7ca 100644
--- a/Core/Translation.pas
+++ b/Core/Translation.pas
@@ -1,6 +1,6 @@
{
- Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis "7X" Copyright (C) 2009-2013 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
}
unit Translation;
@@ -13,9 +13,9 @@ procedure ListLanguages;
procedure LanguageInfo(path: string; var name, localName: string);
function LanguageAuthor(path: string): string;
procedure Add(key, value: string);
-procedure LoadLanguage(path:string);
+procedure LoadLanguage(path: string);
procedure LoadEnglish();
-function TextByKey(key:string):string;
+function TextByKey(key: string):string;
type
TParser = class
@@ -121,6 +121,7 @@ begin
Add('common-keepaspect', 'Maintain aspect ratio');
Add('common-destination', 'Destination');
Add('common-filename', 'File name');
+ Add('common-comment', 'Comment');
Add('common-browse', 'Browse...');
Add('common-quality', 'Quality');
Add('common-filterradius', 'Filter Radius');
@@ -155,7 +156,7 @@ begin
Add('common-invalidformat', 'Invalid format.');
Add('common-confirmexit', 'Do you really want to exit? All unsaved data will be lost!');
Add('common-confirmdelete', 'Are you sure you want to permanently delete "%s"? ');
- Add('common-confirmrename', 'After renaming "%s", all changes made to this flame can be lost. Do you want to continue?');
+ Add('common-confirmselect', 'After new selection, all changes made to the current flame will be lost. Do you want to save its editing history?');
Add('common-deletecurrent', 'All changes made to the current flame will be lost!');
Add('common-dragpanelhint', 'Click and drag to change value');
Add('common-trace-title', 'Trace log');
@@ -198,12 +199,13 @@ begin
Add('common-filter-templatefiles', 'Apophysis Template Library (*.template;*.flame)');
Add('common-filter-undofiles', 'Apophysis Undo Parameters (*.undo;*.apo)');
Add('common-filter-scriptfiles', 'Apophysis Script (*.aposcript;*.asc)');
- Add('common-filter-allimages', 'All images (*.bmp;*.dib;*.jpg;*.jpeg)');
+ Add('common-filter-allimages', 'All images (*.bmp;*.dib;*.jpg;*.jpeg;*.png)');
Add('common-filter-bitmap', 'Windows Bitmap (*.bmp;*.dib)');
Add('common-filter-jpeg', 'JPEG (*.jpg;*.jpeg)');
Add('common-filter-png', 'Portable Network Graphics (*.png)');
Add('common-filter-allfiles', 'All files (*.*)');
Add('common-open-apoimage', 'Import Apophysis parameters from the image...');
+ Add('common-selectimage', 'Select an image file...');
Add('common-favscriptadded', 'The script "%s" was added to your favourites list.');
Add('common-favscriptexists', 'The script "%s" already exists in your favourites list.');
Add('common-screenshot-saved', 'The screenshot "%s" was successfully saved in "%s" directory.');
@@ -246,6 +248,7 @@ begin
Add('adjustment-tab-camera-ypos', 'Y-Position');
Add('adjustment-tab-camera-rotation', 'Rotation');
Add('adjustment-tab-camera-resetzoom', 'Reset zoom'); // AV
+ Add('adjustment-tab-camera-draw3daxes', 'Display coordinate axes in 3D-space'); // AV
Add('adjustment-tab-rendering-title', 'Rendering');
Add('adjustment-tab-rendering-istransparent', 'Transparent');
Add('adjustment-tab-gradient-title', 'Gradient');
@@ -309,8 +312,9 @@ begin
Add('adjustment-popup-gradient-smooth', 'Smooth Palette...');
Add('adjustment-popup-gradient-browser', 'Gradient Browser...');
Add('adjustment-popup-gradient-saveasugr', 'Save Gradient...');
- Add('adjustment-popup-gradient-saveasmap', 'Save as Map File...');
+ Add('adjustment-popup-gradient-saveasmap', 'Save as Map file...');
Add('adjustment-popup-gradient-saveasdefault', 'Save as default');
+ Add('adjustment-popup-gradient-saveasscript', 'Save as script file...');
Add('adjustment-popup-gradient-adjustfragment', 'Adjust color fragment...');
Add('editor-title', 'Transform Editor');
Add('editor-common-transform', 'Transform:');
@@ -319,15 +323,19 @@ begin
Add('editor-common-finalxformlistitem', 'Final');
Add('editor-common-fromprefix', 'from %d');
Add('editor-common-toprefix', 'to %d');
+ Add('editor-common-editcomment', 'Edit flame comment...');
Add('editor-tab-variations-title', 'Variations');
Add('editor-tab-variations-name', 'Name');
Add('editor-tab-variations-value', 'Value');
Add('editor-tab-variations-search', 'Search:'); // AV
+ Add('editor-tab-variations-searchhint', 'Type a variation name...'); // AV
Add('editor-tab-variations-order', 'Edit the Order...'); // AV
Add('editor-tab-variations-orderhint', 'Adjust the order of variations for the chosen transform'); // AV
Add('editor-tab-variations-togglehideunused', ' Hide unused variations');
Add('editor-tab-variations-toggleshowall', ' Show all variations'); // AV
Add('editor-tab-variations-togglefavourites', ' Favourite variations'); // AV
+ Add('editor-tab-variations-toggle3d', ' 3D-aware variations'); // AV
+ Add('editor-tab-variations-toggledc', ' Direct coloring variations'); // AV
Add('editor-tab-variables-title', 'Variables');
Add('editor-tab-variables-name', 'Name');
Add('editor-tab-variables-value', 'Value');
@@ -369,10 +377,13 @@ begin
Add('editor-tab-triangle-transformshint', ' Hotkey A - apply to all vectors, hotkey X - apply to OX-vector only, hotkey Y - apply to OY-vector only, hotkey O - apply to O-vector only');
Add('editor-tab-triangle-coordinates', 'Coordinates');
Add('editor-tab-triangle-menuhint', 'Adjust the transformation tools...');
+ Add('editor-tab-triangle-syncall', 'Apply operations to all triangles');
Add('editor-tab-triangle-pivot1x', 'Pivot point abscissa in the chosen coordinate system');
Add('editor-tab-triangle-pivot1y', 'Pivot point ordinate in the chosen coordinate system');
Add('editor-tab-triangle-pivot2x', 'Second point abscissa in the chosen coordinate system');
Add('editor-tab-triangle-pivot2y', 'Second point ordinate in the chosen coordinate system');
+ Add('editor-tab-triangle-enablesync', 'Synchronize operations for selected triangles');
+ Add('editor-tab-triangle-disablesync', 'Synchronization for triangles disabled');
Add('editor-tab-transform-title', 'Transform');
Add('editor-tab-transform-reset', 'Reset transform');
Add('editor-tab-transform-resethint', 'Reset all vectors to default position');
@@ -445,7 +456,9 @@ begin
Add('editor-toolbar-calcsin', 'Calculate sine of the value');
Add('editor-toolbar-calctan', 'Calculate tangent of the value');
Add('editor-toolbar-usedegrees', 'Use degrees');
+ Add('editor-toolbar-calcexpression', 'Calculate math expression...');
Add('editor-toolbar-showchaos', 'Show chaotic transitions structure...');
+ Add('editor-toolbar-savestate', 'Save current flame into the opened file');
Add('editor-popup-panel-autozoom', 'Zoom automatically');
Add('editor-popup-panel-toggleextendededit', 'Toggle extended edit mode');
Add('editor-popup-panel-locktransformaxes', 'Lock transform axes');
@@ -459,8 +472,10 @@ begin
Add('editor-popup-transform-resetflip', 'Reset reflection');
Add('editor-popup-transform-copycoords', 'Copy triangle coordinates');
Add('editor-popup-transform-pastecoords', 'Paste triangle coordinates');
- Add('editor-popup-transform-copywhole', 'Copy whole transform');
+ Add('editor-popup-transform-copywhole', 'Copy selected transform(s)');
Add('editor-popup-transform-pastewhole', 'Paste transform(s)');
+ Add('editor-popup-transform-copyvars', 'Copy variations with parameters');
+ Add('editor-popup-transform-pastevars', 'Paste variations and parameters');
Add('editor-popup-transform-resetentiretriangle', 'Reset triangle');
Add('editor-popup-chaos-rebuildlinks', 'Rebuild chaos links');
Add('editor-popup-chaos-clearall', 'Clear all current modifiers (reset to zero)');
@@ -475,6 +490,8 @@ begin
Add('editor-popup-chaos-container', 'Add container transform');
Add('editor-popup-chaos-keepweight', 'Inherit original weights');
Add('editor-popup-chaos-invert', 'Invert current settings');
+ Add('editor-popup-chaos-copy', 'Copy current weight modifiers');
+ Add('editor-popup-chaos-paste', 'Apply saved modifiers to transform(s)');
Add('editor-popup-triangle-rotateall', 'Rotate all vectors');
Add('editor-popup-triangle-rotatex', 'Rotate only X-axis');
Add('editor-popup-triangle-rotatey', 'Rotate only Y-axis');
@@ -488,7 +505,6 @@ begin
Add('editor-popup-triangle-invertstep', 'Invert current Move step');
Add('editor-popup-triangle-arcsin', 'Calculate arcsin of the scale factor');
Add('editor-popup-triangle-display', 'Display internally modified values');
- // Add('editor-status-zoomformat', 'Zoom: %f');
Add('editor-status-xformat', 'X: %f');
Add('editor-status-yformat', 'Y: %f');
Add('editor-status-rotateformat', 'Rotate: %3.2f° Inner angle: %3.2f°');
@@ -506,6 +522,7 @@ begin
Add('editor-status-warnscale', 'Current scale factor is out of range! The value inserted into the "Scale" field must be less than 100 percents.');
Add('editor-status-warninvert', 'The affine determinant is too small for this operation.');
Add('editor-status-nonumfield', 'No active numeric field found. Please select a numeric field before opening the menu.');
+ Add('editor-status-formula', 'Type the math formula: ');
Add('export-title', 'Export to flam3');
Add('export-paramoptions-title', 'Parameter options');
Add('export-paramoptions-bufferdepth', 'Buffer depth');
@@ -531,7 +548,7 @@ begin
Add('postprocess-title', 'Post-process render');
Add('postprocess-save', 'Save');
Add('postprocess-fittowindow', 'Fit to window');
- Add('render-title', 'Render flame');
+ Add('render-title', 'Render flame to disk');
Add('render-common-gotofolder', 'Open target folder...');
Add('render-tab-settings-title', 'Settings');
Add('render-tab-output-title', 'Output');
@@ -587,8 +604,10 @@ begin
Add('render-status-log-largepng-message2', 'PNG format with extreme high-resolution images is not recommended!');
Add('render-status-log-largepng-message3', 'To avoid slowdown (and possible memory problems) use BMP file format instead.');
Add('render-status-confirmstop', 'Do you want to stop the current render?');
+ Add('render-status-stop', 'Cancel current rendering');
Add('render-status-dosnapshot', 'Do snapshot');
Add('render-status-dosnapshothint', 'Save current state as a picture');
+ Add('render-status-showimage', 'Show the image state...');
Add('messages-title', 'Messages');
Add('messages-openautomatically', 'Automatically open this window');
Add('mutation-title', 'Mutation');
@@ -609,12 +628,15 @@ begin
Add('options-tab-general-bufferdepth', 'Buffer depth ');
Add('options-tab-general-jpegquality', 'JPEG quality ');
Add('options-tab-general-pngtransparency', 'PNG transparency ');
+ Add('options-tab-general-notifications', 'Notifications');
+ Add('options-tab-general-defaults', 'Defaults');
Add('options-tab-general-showextendedstatistics', 'Show extended render statistics ');
Add('options-tab-general-showrenderimage', 'Show the rendered image ');
Add('options-tab-general-confirmdelete', 'Confirm deleting flames ');
Add('options-tab-general-confirmexit', 'Confirm exit ');
Add('options-tab-general-confirmrenderstop', 'Confirm stop rendering ');
Add('options-tab-general-confirmclearscript', 'Confirm clear script ');
+ Add('options-tab-general-confirmresetundo', 'Confirm reset editing history ');
Add('options-tab-general-oldgradientformat', 'Use old gradient format ');
Add('options-tab-general-templaterandcolor', 'Randomize gradient for templates ');
Add('options-tab-general-alwaysblankflame', 'Disable templates ');
@@ -641,6 +663,7 @@ begin
Add('options-tab-general-playsound', 'Play sound ');
Add('options-tab-general-soundfile', 'Sound file: ');
Add('options-tab-general-playhint', 'Play');
+ Add('options-tab-general-createanimdir', 'Create a new folder for frames');
Add('options-tab-general-autoflatten', 'Apply flattening to old flames');
Add('options-tab-general-pluginpath', 'Plugin folder ');
Add('options-tab-editor-title', 'Editor ');
@@ -660,6 +683,7 @@ begin
Add('options-tab-editor-previewtransparency', 'Transparency');
Add('options-tab-editor-resetcoefs', 'Reset affine values by double-click');
Add('options-tab-editor-resetlinear', 'Reset linear when other variation is set');
+ Add('options-tab-editor-synctriangles', 'Allow synchronize triangles');
Add('options-tab-display-title', 'Display ');
Add('options-tab-display-rendering', 'Rendering ');
Add('options-tab-display-previewdensity', 'Preview density ');
@@ -852,6 +876,7 @@ begin
Add('main-menu-view-imagesize', 'Image size');
Add('main-menu-view-messages', 'Messages');
Add('main-menu-view-curves', 'Curves');
+ Add('main-menu-view-animator', 'Animator');
Add('main-menu-flame-title', 'Flame');
Add('main-menu-flame-reset', 'Reset location');
Add('main-menu-flame-randomize', 'Randomize all parameters');
@@ -972,6 +997,7 @@ begin
Add('main-toolbar-mutation', 'Mutation | Show randomly generated modifications of the current flame');
Add('main-toolbar-quality', 'Rendering quality | Set flame quality (density) for the main preview window');
Add('main-toolbar-imagesize', 'Image size | Change the image size');
+ Add('main-toolbar-animator', 'Animator | Show animation editor');
Add('main-toolbar-messages', 'Messages | Show error messages');
Add('main-toolbar-options', 'Settings | Change Apophysis default settings');
Add('main-toolbar-editscript', 'Edit script | Edit the script code');
@@ -1006,6 +1032,49 @@ begin
Add('varorder-byindex', 'Default order');
Add('varorder-byindexhint', 'Restore the default variation order in Transform Editor');
Add('varorder-noselected', 'Active variation not found. Please, select the variation to move.');
+ Add('formula-wrongargscount', 'Invalid number of arguments to %s: expected %d, received %d.');
+ Add('formula-wrongdatatype', 'The parameter must be a number.');
+ Add('formula-outofrange', 'The value must be in range [-1, 1].');
+ Add('formula-unsigned', 'The value must be positive.');
+ Add('formula-cannotevaluate', 'Cannot evaluate the mathematical expression.');
+ Add('animate-title', 'Animate flame');
+ Add('animate-general', 'General');
+ Add('animate-animation', 'Animation');
+ Add('animate-output', 'Output settings');
+ Add('animate-duration', 'Duration');
+ Add('animate-fps', 'Frames per second');
+ Add('animate-parameters', 'Animation parameters');
+ Add('animate-outflame', 'Output flame file');
+ Add('animate-prefix', 'Name prefix');
+ Add('animate-frame', 'Frame');
+ Add('animate-preview', 'Animation preview');
+ Add('animate-save', 'Save');
+ Add('animate-stop', 'Stop');
+ Add('animate-playhint', 'Play animation');
+ Add('animate-stophint', 'Stop current animation');
+ Add('animate-type', 'Animation type');
+ Add('animate-showframes', 'Show generated frames');
+ Add('animate-currentflame', ' (Current flame)');
+ Add('animate-status-generating', 'Generating frame %d of %d...');
+ Add('animate-status-finished', 'Frame generation finished.');
+ Add('animate-status-changeflame', 'Initial and final frames must be different.');
+ Add('animate-status-stopped', 'Frame generation is interrupted.');
+ Add('animate-kind-rotateflame', 'Rotate flame');
+ Add('animate-kind-rotatereference', 'Rotate reference triangle');
+ Add('animate-kind-rotatehue', 'Change gradient hue');
+ Add('animate-kind-rotatepalette', 'Rotate color gradient');
+ Add('animate-kind-rotatecamera', 'Rotate 3D camera');
+ Add('animate-kind-morph1', 'Morphing (interpolation: cosine, RGB)');
+ Add('animate-kind-morph2', 'Morphing (interpolation: cosine, HSV)');
+ Add('animate-kind-morph3', 'Morphing (interpolation: linear, RGB)');
+ Add('animate-kind-morph4', 'Morphing (interpolation: linear, HSV)');
+ Add('animate-render', 'Render all frames after generation');
+ Add('animate-resetlocation', 'Calculate flame location for each frame');
+ Add('animate-graphicext', 'Graphic extension');
+ Add('animate-initflame', 'Initial flame');
+ Add('animate-finalflame', 'Initial flame');
+ Add('animate-savehint', 'Save all animated frames to hard disk');
+ Add('animate-invertbg', 'Invert background color');
end;
procedure Add(key, value: string);
@@ -1087,6 +1156,7 @@ begin
self.parentTagnames.Add(self.currentTagname);
self.currentTagname := TagName;
end;
+
procedure TParser.ListXmlScannerEndTag(Sender: TObject; TagName: string);
var lastIndex : integer;
begin
@@ -1116,7 +1186,7 @@ procedure TParser.ListXmlScannerContent(Sender: TObject; Content: string);
const root: string = 'stringtable';
var key, tn: string; i: integer;
begin
- for i:=0 to self.parentTagnames.Count - 1 do begin
+ for i := 0 to self.parentTagnames.Count - 1 do begin
tn := self.parentTagnames.Strings[i];
if not (tn = '') and not (tn = root) then key := key + tn + '-';
end;
diff --git a/Core/XFormMan.pas b/Core/XFormMan.pas
index c434648..fd06289 100644
--- a/Core/XFormMan.pas
+++ b/Core/XFormMan.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,19 +27,13 @@ unit XFormMan;
interface
uses
- BaseVariation, SysUtils, Forms, Windows;
+ BaseVariation, SysUtils, System.Generics.Collections;
const
NRLOCVAR = 36;
var
NumBuiltinVars: integer;
-type
- TFNToVN = record
- FileName: string;
- VarName: string;
- end;
-
function NrVar: integer;
function Varnames(const index: integer): String;
procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean);
@@ -49,11 +43,9 @@ function GetNrVariableNames: integer;
function GetVariableNameAt(const Index: integer): string;
function GetVariationIndex(const str: string): integer;
function GetVariationIndexFromVariableNameIndex(const Index: integer): integer;
-procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean);
-procedure InitializeXFormMan;
-procedure DestroyXFormMan;
-procedure RegisterVariationFile(filename, name: string);
-function GetFileNameOfVariation(name: string): string;
+function VarSupports3D(index: smallint): boolean; // AV
+function VarSupportsDC(index: smallint): boolean; // AV
+procedure FillVarNamesList; // AV
implementation
@@ -61,23 +53,22 @@ uses
Classes;
var
- VariationList: TList;
- VariableNames: TStringlist;
- loaderNum : integer;
+ VariationList: TList; // AV: changed to generic type
+ VariationNames: TStringList; // AV
+ VariableNames: TStringList;
Variable2VariationIndex : array of integer;
- FNToVNList : array of TFNToVN;
- FNToVNCount: integer;
+ Vars3D: array of boolean;
+ VarsDC: array of boolean;
procedure InitializeXFormMan;
begin
- VariationList := TList.Create;
- VariableNames := TStringlist.create;
+ VariationList := TList.Create; // AV: changed to generic type
+ VariationNames := TStringList.Create; // AV
+ VariableNames := TStringList.create;
SetLength(Variable2VariationIndex,0);
- SetLength(FNToVNList, 0);
- FNToVNCount := 0;
end;
-procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean);
+procedure FillVarsSupport; // AV
const
supports3D_arr: array[0..NRLOCVAR-1] of boolean = (
true, //'linear',
@@ -162,38 +153,50 @@ const
false, //'pyramid'
false // polar2
);
-var
- varl : TVariationLoader;
+var i: word;
begin
-
- if (index >= NRLOCVAR) then begin
- supports3D := TVariationLoader(VariationList.Items[index - NRLOCVAR]).supports3D;
- supportsDC := TVariationLoader(VariationList.Items[index - NRLOCVAR]).supportsDC;
- end else begin
- supports3D := supports3D_arr[index];
- supportsDC := supportsDC_arr[index];
+ SetLength(Vars3D, VariationNames.Count);
+ SetLength(VarsDC, VariationNames.Count);
+ for i := 0 to NRLOCVAR-1 do
+ begin
+ Vars3D[i] := supports3D_arr[i];
+ VarsDC[i] := supportsDC_arr[i];
+ end;
+ for i := 0 to VariationList.Count - 1 do
+ begin
+ Vars3D[i + NRLOCVAR] := VariationList[i].Supports3D;
+ VarsDC[i + NRLOCVAR] := VariationList[i].SupportsDC;
end;
end;
+function VarSupports3D(index: smallint): boolean;
+begin
+ Result := Vars3D[index]; // AV: added precalc
+end;
+
+function VarSupportsDC(index: smallint): boolean;
+begin
+ Result := VarsDC[index]; // AV: added precalc
+end;
+
+{ ///////////////////////////////////////////////////////////////////////// }
procedure DestroyXFormMan;
var i: integer;
begin
+ VariationNames.Free; // AV
VariableNames.Free;
// The registered variation loaders are owned here, so we must free them.
for i := 0 to VariationList.Count-1 do
- TVariationLoader(VariationList[i]).Free;
+ VariationList[i].Free;
VariationList.Free;
-
- Finalize(Variable2VariationIndex);
- Finalize(FNToVNList);
end;
///////////////////////////////////////////////////////////////////////////////
-function NrVar: integer;
+function NrVar: integer; // AV: reduce Nr of calc since we use it thousand times
begin
- Result := NRLOCVAR + VariationList.Count;
+ Result := VariationNames.Count; // NRLOCVAR + VariationList.Count;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -206,7 +209,9 @@ begin
Result := Variable2VariationIndex[Index];
end;
-function Varnames(const index: integer): String;
+{ ////////////////////////////////////////////////////////////////////////// }
+
+procedure FillVarNamesList; // AV: this method used once at startup
const
cvarnames: array[0..NRLOCVAR-1] of string = (
'linear',
@@ -216,23 +221,10 @@ const
'swirl',
'horseshoe',
'polar',
-// 'handkerchief',
-// 'heart',
'disc',
'spiral',
'hyperbolic',
'diamond',
-// 'ex',
-// 'julia',
-// 'bent',
-// 'waves',
-// 'fisheye',
-// 'popcorn',
-// 'exponential',
-// 'power',
-// 'cosine',
-// 'rings',
-// 'fan',
'eyefish',
'bubble',
'cylinder',
@@ -241,48 +233,51 @@ const
'gaussian_blur',
'zblur',
'blur3D',
-
'pre_blur',
'pre_zscale',
'pre_ztranslate',
'pre_rotate_x',
'pre_rotate_y',
-
'zscale',
'ztranslate',
'zcone',
-
'post_rotate_x',
'post_rotate_y',
-
'post_mirror_x',
'post_mirror_y',
'post_mirror_z',
-
'hemisphere',
'cross',
'pyramid',
'polar2'
);
+var i: integer;
begin
- if Index < NRLOCVAR then
- Result := cvarnames[Index]
+ for i := 0 to High(cvarnames) do
+ VariationNames.Add(cvarnames[i]);
+ for i := 0 to VariationList.Count - 1 do
+ VariationNames.Add(VariationList[i].GetName);
+
+ VariationList.TrimExcess;
+
+ FillVarsSupport; // 3D and DC
+end;
+
+function Varnames(const index: integer): string; // AV: totally rewritten
+begin
+ if (index >= 0) and (index < VariationNames.Count) then
+ Result := VariationNames[index]
else
- Result := TVariationLoader(VariationList[Index - NRLOCVAR]).GetName;
+ Result := '';
end;
-///////////////////////////////////////////////////////////////////////////////
-function GetVariationIndex(const str: string): integer;
-var
- i: integer;
+function GetVariationIndex(const str: string): integer; // AV: totally rewritten
begin
- i := NRVAR-1;
- while (i >= 0) and (Varnames(i) <> str) do Dec(i);
- Result := i;
+ Result := VariationNames.IndexOf(str);
end;
///////////////////////////////////////////////////////////////////////////////
-
+(*
procedure RegisterVariationFile(filename, name: string);
begin
FNToVNCount := FNToVNCount + 1;
@@ -302,13 +297,14 @@ begin
end;
Result := '';
end;
+*)
procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean);
var
i: integer;
prevNumVariables:integer;
begin
- OutputDebugString(PChar(Variation.GetName));
+ // OutputDebugString(PChar(Variation.GetName));
VariationList.Add(Variation);
Variation.Supports3D := supports3D;
@@ -318,7 +314,7 @@ begin
setLength(Variable2VariationIndex, prevNumVariables + Variation.GetNrVariables);
for i := 0 to Variation.GetNrVariables - 1 do begin
VariableNames.Add(Variation.GetVariableNameAt(i));
- Variable2VariationIndex[prevNumVariables + i] := NrVar-1;
+ Variable2VariationIndex[prevNumVariables + i] := NRLOCVAR + VariationList.Count - 1; //NrVar-1;
end;
end;
@@ -331,7 +327,8 @@ end;
///////////////////////////////////////////////////////////////////////////////
function GetRegisteredVariation(const Index: integer): TVariationLoader;
begin
- Result := TVariationLoader(VariationList[Index]);
+ // AV: no more unsafe type casting here since we use generics!
+ Result := VariationList[Index];
end;
///////////////////////////////////////////////////////////////////////////////
diff --git a/Flame/ControlPoint.pas b/Flame/ControlPoint.pas
index 45f502e..d6d40db 100644
--- a/Flame/ControlPoint.pas
+++ b/Flame/ControlPoint.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,27 +27,30 @@ unit ControlPoint;
interface
//{$define VAR_STR}
+//{$define GAUSSIAN_DOF}
uses
- Classes, Windows, Cmap, XForm, XFormMan, Binary,
- SysUtils, math, ZLib, Bezier;
+ Classes, Windows, Cmap, XForm, XFormMan, Binary, SysUtils,
+ Math, Bezier (* {$ifdef CPUX86}, AsmRandom {$endif} *);
const
SUB_BATCH_SIZE = 10000;
PROP_TABLE_SIZE = 1024;
PREFILTER_WHITE = (1 shl 26);
- FILTER_CUTOFF = 1.8;
+ FILTER_CUTOFF = 1.8; // AV: maybe move it to ImageMaker?
BRIGHT_ADJUST = 2.3;
//FUSE = 15; // AV: moved to Global since it became a variable
+ vRandom = -1; // AV: index of randomly chosen variation for random flames
+
type
- TCoefsArray= array[0..2, 0..1] of double;
- pCoefsArray= ^TCoefsArray;
+
TTriangle = record
x: array[0..2] of double;
y: array[0..2] of double;
end;
TTriangles = array[-1..NXFORMS] of TTriangle;
+
TSPoint = record
x: double;
y: double;
@@ -55,34 +58,25 @@ type
TSRect = record
Left, Top, Right, Bottom: double;
end;
+
+{
TMapPalette = record
Red: array[0..255] of byte;
Green: array[0..255] of byte;
Blue: array[0..255] of byte;
end;
+
TColorMaps = record
Identifier: string;
UGRFile: string;
end;
- pPixArray = ^TPixArray;
- TPixArray = array[0..1279, 0..1023, 0..3] of integer;
- pPreviewPixArray = ^TPreviewPixArray;
- TPreviewPixArray = array[0..159, 0..119, 0..3] of integer;
- TFileType = (ftIfs, ftFla, ftXML);
-
-type //?
- PLongintArray = ^TLongintArray;
- TLongintArray = array[0..8192] of Longint;
+}
type
- TVariation = (vLinear, vCustom, vRandom = 1000); // AV: fixed outdated values
-type
TPointsArray = array of TCPpoint;
TPointsXYArray = array of TXYpoint;
-
- P2Cpoint = ^T2Cpoint;
- T2CPointsArray = array of T2Cpoint;
+ //T2CPointsArray = array of T2Cpoint;
TControlPoint = class
public
@@ -102,21 +96,20 @@ type
xform: array[0..NXFORMS] of TXForm;
noLinearFix: boolean;
- variation: TVariation;
cmap: TColorMap;
cmapindex: integer;
- time: double;
+ time: double; // AV: is used for interpolation
Fbrightness: double; // 1.0 = normal
contrast: double; // 1.0 = normal
gamma: double;
Width: integer;
Height: integer;
spatial_oversample: integer;
- name, nick, url: string;
+ name: string;
center: array[0..1] of double; // camera center
vibrancy: double; // blend between color algs (0=old,1=new)
hue_rotation: double; // applies to cmap, 0-1
- background: array[0..3] of Integer; // Changed to integers so no conversion needed - mt
+ background: array[0..3] of smallint; // Changed to integers so no conversion needed - mt
zoom: double; // effects ppu and sample density
pixels_per_unit: double; // and scale
spatial_filter_radius: double; // variance of gaussian
@@ -127,21 +120,28 @@ type
actual_density: extended; // for incomplete renders
nbatches: integer; // this much color resolution. but making it too high induces clipping
white_level: integer;
- cmap_inter: integer; // if this is true, then color map interpolates one entry
- // at a time with a bright edge
- symmetry: integer;
- pulse: array[0..1, 0..1] of double; // [i][0]=magnitute [i][1]=frequency */
- wiggle: array[0..1, 0..1] of double; // frequency is /minute, assuming 30 frames/s */
+
+ FAngle: Double;
+ symmetry: integer; // color speed
estimator, estimator_min, estimator_curve: double; // density estimator.
- jitters: integer;
+ jitters: integer; // <-- AV: deprecated
gamma_threshold: double;
enable_de : boolean;
used_plugins : TStringList;
+ comment: string; // AV: holds user's comment on flame
-// PropTable: array of TXForm;
- FAngle: Double;
- //FTwoColorDimensions: Boolean;
+ {
+ pulse: array[0..1, 0..1] of double; // [i][0]=magnitute [i][1]=frequency */
+ wiggle: array[0..1, 0..1] of double; // frequency is /minute, assuming 30 frames/s */
+ cmap_inter: integer; // if this is true, then color map interpolates one entry
+ // at a time with a bright edge
+ variation: TVariation; // <-- AV: deprecated
+ nick, url: string; // <-- AV: deprecated
+ PropTable: array of TXForm; // <-- AV: declared in TXform unit
+ FTwoColorDimensions: Boolean;
+ xdata : string;
+ }
procedure FillUsedPlugins;
@@ -150,8 +150,10 @@ type
CameraMatrix: array[0..2, 0..2] of double;
DofCoef: double;
+ {$ifdef GAUSSIAN_DOF}
gauss_rnd: array [0..3] of double;
gauss_N: integer;
+ {$endif}
sinPitch, cosPitch, sinRoll, cosRoll,
sinYaw, cosYaw: double;
@@ -169,13 +171,15 @@ type
function getppux: double;
function getppuy: double;
+ procedure PreCalcBounds(var maxx, minx, maxy, miny: double); // AV
+ procedure DirectCopy_AV(const cp1: TControlPoint);
+
function GetBrightness: double;
procedure SetBrightness(br: double);
function GetRelativeGammaThreshold: double;
procedure SetRelativeGammaThreshold(gtr: double);
public
- xdata : string;
procedure SaveToStringlist(sl: TStringlist);
procedure SaveToFile(Filename: string);
@@ -183,12 +187,9 @@ type
procedure ParseString(aString: string);
procedure ParseStringList(sl: TStringlist);
- procedure RandomCP(min: integer = 2; max: integer = NXFORMS; calc: boolean = true);
- procedure RandomCP1;
procedure CalcBoundbox;
function BlowsUp(NrPoints: integer): boolean;
-
- procedure SetVariation(vari: TVariation);
+
procedure Clear;
procedure InterpolateX(cp1, cp2: TControlPoint; Tm: double);
@@ -199,8 +200,8 @@ type
procedure Prepare;
- function Clone: TControlPoint;
- procedure Copy(cp1: TControlPoint; KeepSizes: boolean = false; nt: byte = NXFORMS); // AV
+ function Clone: TControlPoint; // AV: rewritten
+ procedure Copy(cp1: TControlPoint; KeepSizes: boolean = false); // AV: rewritten
function HasFinalXForm: boolean;
@@ -212,10 +213,6 @@ type
procedure GetTriangle(var Triangle: TTriangle; const n: integer);
procedure GetPostTriangle(var Triangle: TTriangle; const n: integer);
- procedure EqualizeWeights;
- procedure NormalizeWeights;
- procedure RandomizeWeights;
- procedure ComputeWeights(Triangles: TTriangles; t: integer);
procedure NormalizeProbabilities; // AV
procedure CalculateWeights; // AV
procedure CalculateColorSpeed; // AV
@@ -243,96 +240,65 @@ type
function add_symmetry_to_control_point(var cp: TControlPoint; sym: integer): integer;
procedure tile_control_point(var cp: TControlPoint; sym: integer);
+
function CalcUPRMagn(const cp: TControlPoint): double;
-procedure FillVarDisturb;
function CalcBinaryFlameSize(cp: TControlPoint): integer;
+procedure PrepareToInterpolation(var SourceCp, TargetCp: TControlPoint); // AV
+
+{ Math operations }
+function line_dist(x, y, x1, y1, x2, y2: double): double;
+function dist(x1, y1, x2, y2: double): double;
+function det(a, b, c, d: double): double;
+function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double;
+ var a, b, e: double): double;
+
+// AV: moved specific variables from Global here due to often name-space conflicts
+var
+ MainTriangles: TTriangles;
+ Variation: integer; // Current variation
implementation
-uses global;
-
-var
- var_distrib: array of integer;
- mixed_var_distrib: array of integer;
+uses Global;
{ TControlPoint }
-function sign(n: double): double;
-begin
- if n < 0 then Result := -1
- else if n > 0 then Result := 1
- else Result := 0;
-end;
-
procedure TControlPoint.FillUsedPlugins;
var
- i, j, k, f : integer;
+ i, j, f : integer;
v : double;
- s : String;
+ s : string;
begin
used_plugins.Clear;
- f := -1;
- if self.finalXformEnabled then f := 0;
+ if self.finalXformEnabled then // AV
+ f := Min(NumXForms, NXFORMS)
+ else
+ f := Min(NumXForms - 1, NXFORMS);
- for i := 0 to Min(NumXForms+f, NXFORMS) do
+ for i := 0 to f do
with xform[i] do begin
for j := 0 to NRVAR - 1 do begin
v := self.xform[i].GetVariation(j);
+ s := Varnames(j);
if (v <> 0) and // uses variation
- (used_plugins.IndexOf(Varnames(j)) < 0) // not listed yet
- then begin
- used_plugins.Add(Varnames(j));
- s := s + Varnames(j) + ' on TX #' + IntToStr(i + 1) + #13#10;
- end;
+ (used_plugins.IndexOf(s) < 0) // not listed yet
+ then used_plugins.Add(s);
end;
end;
- // Faulty...
- (*
- for i := 0 to NumXforms-1 do begin
- for j := NumBuiltinVars to xform[i].NumVariations-1 do begin
- v := self.xform[i].GetVariation(j);
- if (v = 0) then continue;
- s := Varnames(j);
- k := used_plugins.IndexOf(s);
- if (k < 0) or (k >= used_plugins.Count) then
- used_plugins.Add(s);
- end;
- end;
- if finalXformEnabled then begin
- for j := NumBuiltinVars to self.finalXform.NumVariations-1 do begin
- v := self.finalXform.GetVariation(j);
- s := Varnames(j);
- if (v = 0) then continue;
- k := used_plugins.IndexOf(s);
- if (k < 0) or (k >= used_plugins.Count) then
- used_plugins.Add(s);
- end;
- end;
- *)
end;
constructor TControlPoint.Create;
var
- i: Integer;
+ i: word;
begin
- for i := 0 to NXFORMS do begin
+ for i := 0 to NXFORMS do
xform[i] := TXForm.Create;
- end;
+
invalidXform := TXForm.Create;
soloXform := -1;
- pulse[0][0] := 0;
- pulse[0][1] := 60;
- pulse[1][0] := 0;
- pulse[1][1] := 60;
-
- wiggle[0][0] := 0;
- wiggle[0][1] := 60;
- wiggle[1][0] := 0;
- wiggle[1][1] := 60;
-
background[0] := 0;
background[1] := 0;
background[2] := 0;
@@ -361,23 +327,21 @@ begin
vibrancy := 1;
contrast := 1;
Fbrightness := 1;
- hue_rotation := 1; // AV
+ gamma_threshold := 0.01;
sample_density := 50;
zoom := 0;
- nbatches := 1;
-
- white_level := 200;
-
+
estimator := 9.0;
estimator_min := 0.0;
estimator_curve := 0.4;
enable_de := false;
jitters := 1;
- gamma_threshold := 0.01;
-
- //FTwoColorDimensions := False;
-
+ nbatches := 1;
+
+ white_level := 200;
+ hue_rotation := 1; // AV
+
finalXformEnabled := false;
Transparency := false;
@@ -389,12 +353,27 @@ begin
cameraDOF := 0;
used_plugins := TStringList.Create;
+ comment := '';
+
+ {
+ pulse[0][0] := 0;
+ pulse[0][1] := 60;
+ pulse[1][0] := 0;
+ pulse[1][1] := 60;
+
+ wiggle[0][0] := 0;
+ wiggle[0][1] := 60;
+ wiggle[1][0] := 0;
+ wiggle[1][1] := 60;
+
xdata := '';
+ FTwoColorDimensions := False;
+ }
end;
destructor TControlPoint.Destroy;
var
- i: Integer;
+ i: word;
begin
for i := 0 to NXFORMS do
xform[i].Free;
@@ -495,11 +474,13 @@ begin
CameraMatrix[1, 2] := cosPitch * sinRoll * sinYaw + sinPitch * cosYaw;
CameraMatrix[2, 2] := cosPitch * cosRoll;
DofCoef := 0.1 * CameraDOF;
+ {$ifdef GAUSSIAN_DOF}
gauss_rnd[0] := random;
gauss_rnd[1] := random;
gauss_rnd[2] := random;
gauss_rnd[3] := random;
gauss_N := 0;
+ {$endif}
if (CameraDOF <> 0) then begin
if (CameraRoll = 0) then
@@ -546,10 +527,10 @@ begin
for i := 0 to NrPoints - 1 do begin
xf := xf.PropTable[Random(PROP_TABLE_SIZE)];
xf.NextPointXY(px,py);
- if (xf.transOpacity = 0) or
+ if (xf.transOpacity = 0) or
((xf.transOpacity < 1) and (random > xf.transOpacity)) then
- pPoint^.x := 1e300 // MaxDouble // hack
- else begin
+ pPoint^.x := 1e300 // MaxDouble // hack
+ else begin
pPoint^.X := px;
pPoint^.Y := py;
end;
@@ -560,7 +541,7 @@ begin
for i := 0 to NrPoints - 1 do begin
xf := xf.PropTable[Random(PROP_TABLE_SIZE)];
xf.NextPointXY(px,py);
- if (xf.transOpacity = 0) or // AV
+ if (xf.transOpacity = 0) or // AV
((xf.transOpacity < 1) and (random > xf.transOpacity)) then // AV
pPoint^.x := 1e300 // MaxDouble // hack
else begin
@@ -608,7 +589,7 @@ begin
pPoint^.x := 1e300 // MaxDouble // hack
else
begin
- finalXform.NextPointTo(p, pPoint^);
+ finalXform.NextPointTo(p, pPoint^);
ProjectionFunc(pPoint);
end;
Inc(pPoint);
@@ -687,7 +668,6 @@ begin
z := CameraMatrix[1,2] * pPoint^.y + cosPitch * z;
zr := 1 - cameraPersp * z;
-//{$define GAUSSIAN_DOF}
{$ifdef GAUSSIAN_DOF}
asm
fld qword ptr [eax + gauss_rnd]
@@ -855,6 +835,8 @@ begin
end;
function TControlPoint.BlowsUp(NrPoints: integer): boolean;
+const
+ limit = 1E10; // AV
var
i, n: Integer;
px, py: double;
@@ -890,6 +872,39 @@ begin
Inc(CurrentPoint);
// random CPs don't use finalXform...
end;
+
+ // It is possible that the transformation will grow very large but remain below the overflow line
+ minx := limit; //1E10;
+ maxx := -limit; //-1E10;
+ miny := limit; //1E10;
+ maxy := -limit; //-1E10;
+ for i := 0 to n-1 do begin
+ // AV: rewrote the block to fix the crash
+ if InRange(Points[i].x, -limit, limit) then
+ begin
+ minx := min(minx, Points[i].x);
+ maxx := max(maxx, Points[i].x);
+ end
+ else
+ begin
+ minx := -limit;
+ maxx := limit;
+ end;
+ if InRange(Points[i].y, -limit, limit) then
+ begin
+ miny := min(miny, Points[i].y);
+ maxy := max(maxy, Points[i].y);
+ end
+ else
+ begin
+ miny := -limit;
+ maxy := limit;
+ end;
+ end;
+
+ if ((Maxx - MinX) > 1000) or ((Maxy - Miny) > 1000) then
+ Result := True;
+
except
on EMathError do begin
Result := True;
@@ -897,20 +912,6 @@ begin
end;
end;
- // It is possible that the transformation will grow very large but remain below the overflow line
- minx := 1E10;
- maxx := -1E10;
- miny := 1E10;
- maxy := -1E10;
- for i := 0 to n-1 do begin
- minx := min(minx, Points[i].x);
- maxx := max(maxx, Points[i].x);
- miny := min(miny, Points[i].y);
- maxy := max(maxy, Points[i].y);
- end;
-
- if ((Maxx - MinX) > 1000) or ((Maxy - Miny) > 1000) then
- Result := True;
end;
procedure TControlPoint.ParseString(aString: string);
@@ -1055,7 +1056,7 @@ begin
Inc(ParsePos);curvePoints[i][3].y := StrToFloat(ParseValues[ParsePos]);
Inc(ParsePos);curveWeights[i][3] := StrToFloat(ParseValues[ParsePos]);
end;
- end else if AnsiCompareText(CurrentToken, 'pulse') = 0 then begin
+ end {else if AnsiCompareText(CurrentToken, 'pulse') = 0 then begin
Inc(ParsePos);
pulse[0, 0] := StrToFloat(ParseValues[ParsePos]);
Inc(ParsePos);
@@ -1073,7 +1074,7 @@ begin
wiggle[1, 0] := StrToFloat(ParseValues[ParsePos]);
Inc(ParsePos);
wiggle[1, 1] := StrToFloat(ParseValues[ParsePos]);
- end else if AnsiCompareText(CurrentToken, 'pixels_per_unit') = 0 then begin
+ end} else if AnsiCompareText(CurrentToken, 'pixels_per_unit') = 0 then begin
Inc(ParsePos);
pixels_per_unit := StrToFloat(ParseValues[ParsePos]);
end else if AnsiCompareText(CurrentToken, 'spatial_filter_radius') = 0 then begin
@@ -1094,14 +1095,14 @@ begin
end else if AnsiCompareText(CurrentToken, 'cmap') = 0 then begin
Inc(ParsePos);
cmapindex := StrToInt(ParseValues[ParsePos]);
- end else if AnsiCompareText(CurrentToken, 'cmap_inter') = 0 then begin
+ end {else if AnsiCompareText(CurrentToken, 'cmap_inter') = 0 then begin
Inc(ParsePos);
cmap_inter := StrToInt(ParseValues[ParsePos]);
end else if AnsiCompareText(CurrentToken, 'palette') = 0 then begin
// Inc(ParsePos);
// cmapindex := StrToInt(ParseValues[ParsePos]);
OutputDebugString(Pchar('NYI import Palette'));
- end else if AnsiCompareText(CurrentToken, 'density') = 0 then begin
+ end} else if AnsiCompareText(CurrentToken, 'density') = 0 then begin
Inc(ParsePos);
xform[CurrentXForm].Density := StrToFloat(ParseValues[ParsePos]);
end else if AnsiCompareText(CurrentToken, 'color') = 0 then begin
@@ -1238,7 +1239,7 @@ begin
FormatSettings.DecimalSeparator := OldDecimalSperator;
end;
-
+(*
procedure TControlPoint.SetVariation(vari: TVariation);
var
i, j, v: integer;
@@ -1298,7 +1299,6 @@ begin
GetCmap(cmapindex, hue_rotation, cmap);
time := 0.0;
-//nrXforms := xform_distrib[random(13)];
nrXforms := random(Max - (Min - 1)) + Min;
FillVarDisturb;
@@ -1334,10 +1334,6 @@ begin
xform[i].SetVariation(j, 0);
end;
- {for j := 0 to NRVAR - 1 do begin
- xform[i].SetVariation(j, 0);
- end; } // AV: why do we do it twice?
-
if rv < 0 then begin
if VarPossible then begin
repeat
@@ -1352,8 +1348,7 @@ begin
xform[i].SetVariation(rv, 1);
end;
- if calc then
- CalcBoundbox;
+ if calc then CalcBoundbox;
end;
procedure TControlPoint.RandomCP1;
@@ -1362,31 +1357,27 @@ var
begin
RandomCP;
for i := 0 to NXFORMS - 1 do begin
- for j := 0 to NRVAR - 1 do begin
+ for j := 1 to NRVAR - 1 do
xform[i].SetVariation(j, 0);
- end;
xform[i].SetVariation(0, 1);
end;
CalcBoundbox;
end;
+*)
-procedure TControlPoint.CalcBoundbox;
+procedure TControlPoint.PreCalcBounds(var maxx, minx, maxy, miny: double);
const
limit = 50; // AV
var
Points: TPointsArray; // AV: fixed - was TPointsXYArray;
i, j: integer;
- deltax, minx, maxx: double;
+ deltax, deltay: double;
cntminx, cntmaxx: integer;
- deltay, miny, maxy: double;
cntminy, cntmaxy: integer;
LimitOutSidePoints: integer;
begin
-// RandSeed := 1234567;
- try
SetLength(Points, SUB_BATCH_SIZE);
- Prepare;
IterateXYC(SUB_BATCH_SIZE, points); // AV: fixed - was IterateXY
LimitOutSidePoints := Round(0.05 * SUB_BATCH_SIZE);
@@ -1487,6 +1478,15 @@ begin
Height / abs(maxy - miny))
else
pixels_per_unit := 10;
+end;
+
+procedure TControlPoint.CalcBoundbox;
+var
+ minx, maxx, miny, maxy: double;
+begin
+ try
+ Prepare;
+ PreCalcBounds(maxx, minx, maxy, miny); // AV
except on EMathError do
begin // default
center[0] := 0;
@@ -1497,134 +1497,14 @@ begin
end;
function CalcUPRMagn(const cp: TControlPoint): double;
-const
- limit = 50; // AV
var
- Points: TPointsXYArray;
- i, j: integer;
- deltax, minx, maxx: double;
- cntminx, cntmaxx: integer;
- deltay, miny, maxy: double;
- cntminy, cntmaxy: integer;
- LimitOutSidePoints: integer;
+ minx, maxx, miny, maxy: double;
xLength, yLength: double;
begin
try
- SetLength(Points, SUB_BATCH_SIZE);
- cp.iterateXY(SUB_BATCH_SIZE, Points);
+ cp.PreCalcBounds(maxx, minx, maxy, miny); // AV
- LimitOutSidePoints := Round(0.05 * SUB_BATCH_SIZE);
-
- minx := limit; // AV // 1E99;
- maxx := -limit; // AV // -1E99;
- miny := limit; // AV // 1E99;
- maxy := -limit; // AV // -1E99;
- { // AV: commented out
- for i := 0 to SUB_BATCH_SIZE - 1 do begin
- minx := min(minx, Points[i].x);
- maxx := max(maxx, Points[i].x);
- miny := min(miny, Points[i].y);
- maxy := max(maxy, Points[i].y);
- end;
- }
- for i := 0 to SUB_BATCH_SIZE - 1 do begin // AV
- if InRange(Points[i].x, -limit, limit) then
- begin
- minx := min(minx, Points[i].x);
- maxx := max(maxx, Points[i].x);
- end
- else
- begin
- minx := -limit;
- maxx := limit;
- end;
- if InRange(Points[i].y, -limit, limit) then
- begin
- miny := min(miny, Points[i].y);
- maxy := max(maxy, Points[i].y);
- end
- else
- begin
- miny := -limit;
- maxy := limit;
- end;
- end;
-
- deltax := (maxx - minx) * 0.25;
- maxx := (maxx + minx) / 2;
- minx := maxx;
-
- deltay := (maxy - miny) * 0.25;
- maxy := (maxy + miny) / 2;
- miny := maxy;
-
- for j := 0 to 10 do begin
- cntminx := 0;
- cntmaxx := 0;
- cntminy := 0;
- cntmaxy := 0;
- { // AV: commented out
- for i := 0 to SUB_BATCH_SIZE - 1 do begin
- if (Points[i].x < minx) then Inc(cntminx);
- if (Points[i].x > maxx) then Inc(cntmaxx);
- if (Points[i].y < miny) then Inc(cntminy);
- if (Points[i].y > maxy) then Inc(cntmaxy);
- end;
- }
- for i := 0 to SUB_BATCH_SIZE - 1 do begin // AV
- if InRange(Points[i].x, -limit, limit) then
- begin
- if (Points[i].x < minx) then Inc(cntminx);
- if (Points[i].x > maxx) then Inc(cntmaxx);
- end;
- if InRange(Points[i].y, -limit, limit) then
- begin
- if (Points[i].y < miny) then Inc(cntminy);
- if (Points[i].y > maxy) then Inc(cntmaxy);
- end;
- end;
-
- if (cntMinx < LimitOutSidePoints) then begin
- minx := minx + deltax;
- end else begin
- minx := minx - deltax;
- end;
-
- if (cntMaxx < LimitOutSidePoints) then begin
- maxx := maxx - deltax;
- end else begin
- maxx := maxx + deltax;
- end;
-
- deltax := deltax / 2;
-
- if (cntMiny < LimitOutSidePoints) then begin
- miny := miny + deltay;
- end else begin
- miny := miny - deltay;
- end;
-
- if (cntMaxy < LimitOutSidePoints) then begin
- maxy := maxy - deltay;
- end else begin
- maxy := maxy + deltay;
- end;
-
- deltay := deltay / 2;
- end;
-
- if ((maxx - minx) > 1000) or
- ((maxy - miny) > 1000) then
- raise EMathError.Create('Flame area too large');
-
- cp.center[0] := (minx + maxx) / 2;
- cp.center[1] := (miny + maxy) / 2;
- if ((maxx - minx) > 0.001) and ((maxy - miny) > 0.001) then
- cp.pixels_per_unit := 0.7 * Min(cp.width / (maxx - minx), cp.height / (maxy - miny))
- else
- cp.pixels_per_unit := 10;
-
- // Calculate magn for UPRs
+ // Calculate magn for UPRs
xLength := maxx - minx;
yLength := maxy - miny;
if xLength >= yLength then
@@ -1646,15 +1526,88 @@ begin
end;
end;
-// AV: this one from mine is used only for scripting, the original method was left for mutants
+procedure PrepareToInterpolation(var SourceCp, TargetCp: TControlPoint); // AV
+var
+ i, j: integer;
+ t, ns, nt, maxt: smallint;
+ vs, vt: double;
+ vn: string;
+begin
+ { reset linear variation on (temporary) invisible xforms }
+ ns := SourceCp.NumXForms;
+ nt := TargetCp.NumXForms;
+ if ns > nt then begin
+ for j := nt + 1 to ns - 1 do
+ TargetCp.xform[j].SetVariation(0, 0);
+ maxt := ns; // max number of actually used xforms
+ end
+ else if nt > ns then begin
+ for j := ns + 1 to nt - 1 do
+ SourceCp.xform[j].SetVariation(0, 0);
+ maxt := nt;
+ end
+ else // if nt = ns then
+ maxt := nt;
+
+ { adjust (temporary unused) variable values }
+ for t := 0 to maxt do
+ for i := 0 to GetNrVariableNames - 1 do
+ begin
+ j := GetVariationIndexFromVariableNameIndex(i);
+ vs := SourceCp.xform[t].GetVariation(j);
+ vt := TargetCp.xform[t].GetVariation(j);
+ if (vs <> 0) and (vt = 0) then
+ begin
+ vn := GetVariableNameAt(i);
+ SourceCp.xform[t].GetVariable(vn, vs);
+ TargetCp.xform[t].SetVariable(vn, vs);
+ end
+ else if (vt <> 0) and (vs = 0) then
+ begin
+ vn := GetVariableNameAt(i);
+ TargetCp.xform[t].GetVariable(vn, vt);
+ SourceCp.xform[t].SetVariable(vn, vt);
+ end;
+ end;
+
+ { adjust final transforms }
+ if (SourceCp.finalXformEnabled or TargetCp.finalXformEnabled)
+ and (nt <> ns) then // otherwise it's already done
+ begin
+ for i := 0 to GetNrVariableNames - 1 do
+ begin
+ j := GetVariationIndexFromVariableNameIndex(i);
+ vs := SourceCp.xform[ns].GetVariation(j);
+ vt := TargetCp.xform[nt].GetVariation(j);
+ if (vs <> 0) and (vt = 0) then
+ begin
+ vn := GetVariableNameAt(i);
+ SourceCp.xform[ns].GetVariable(vn, vs);
+ TargetCp.xform[nt].SetVariable(vn, vs);
+ end
+ else if (vt <> 0) and (vs = 0) then
+ begin
+ vn := GetVariableNameAt(i);
+ TargetCp.xform[nt].GetVariable(vn, vt);
+ SourceCp.xform[ns].SetVariable(vn, vt);
+ end;
+ end;
+ end;
+
+ { AV: improve visibility of mid-frames }
+ SourceCp.NormalizeProbabilities;
+ TargetCp.NormalizeProbabilities;
+end;
+
+// AV: this one from mine is used for scripting, the original method was left for mutants only
procedure TControlPoint.InterpolateAll(cp1, cp2: TControlPoint; Tm: double; it: integer);
var
- result: TControlPoint;
c0, c1, k: double;
i, j: integer;
numTX, numTX1, numTX2: word;
r, s, t: array[0..2] of double;
- v1, v2: double;
+ v1, v2, t1, t2: double;
+ f1, f2: boolean;
function AngOpt(ang0, ang1: double): double;
var delta: double;
@@ -1666,24 +1619,40 @@ var
end;
begin
- if (it > 3) or (it < 0) then Exit;
- if (cp2.time - cp1.time) > 1E-6 then
+ if (it > 3) or (it < 0) then exit;
+
+ t1 := cp1.time;
+ t2 := cp2.time;
+
+ if (tm = t1) then
+ begin
+ self.Copy(cp1);
+ exit;
+ end
+ else if (tm = t2) then
+ begin
+ self.Copy(cp2);
+ width := cp1.width;
+ height := cp1.height;
+ exit;
+ end;
+
+ if (t2 - t1) > 1E-6 then
begin
if (it < 2) then begin // 0 or 1: cosine interpolation
- k := (cp2.time - tm) / (cp2.time - cp1.time);
- c0 := (1 - cos(pi*k))* 0.5;
+ k := (t2 - tm) / (t2 - t1);
+ c0 := (1 - cos(pi * k)) * 0.5;
end
else // 2 or 3: linear interpolation
- c0:=(cp2.time - tm) / (cp2.time - cp1.time);
+ c0 := (t2 - tm) / (t2 - t1);
c1 := 1 - c0;
end else begin
c0 := 1;
c1 := 0;
end;
- Result := TControlPoint.Create;
- Result.time := Tm;
-
+ self.time := Tm;
+
if Odd(it) then // 1 or 3: hsv interpolation
for i := 0 to 255 do
begin
@@ -1699,179 +1668,182 @@ begin
t[1] := c0 * s[1] + c1 * t[1];
t[2] := c0 * s[2] + c1 * t[2];
hsv2rgb(t, r);
- Result.cmap[i][0] := Round(255 * r[0]);
- Result.cmap[i][1] := Round(255 * r[1]);
- Result.cmap[i][2] := Round(255 * r[2]);
+ cmap[i][0] := Round(255 * r[0]);
+ cmap[i][1] := Round(255 * r[1]);
+ cmap[i][2] := Round(255 * r[2]);
end
else // 0 or 2: rgb interpolation
for i := 0 to 255 do
begin
- Result.cmap[i][0] := Round(c0 * cp1.cmap[i][0] + c1 * cp2.cmap[i][0]);
- Result.cmap[i][1] := Round(c0 * cp1.cmap[i][1] + c1 * cp2.cmap[i][1]);
- Result.cmap[i][2] := Round(c0 * cp1.cmap[i][2] + c1 * cp2.cmap[i][2]);
+ cmap[i][0] := Round(c0 * cp1.cmap[i][0] + c1 * cp2.cmap[i][0]);
+ cmap[i][1] := Round(c0 * cp1.cmap[i][1] + c1 * cp2.cmap[i][1]);
+ cmap[i][2] := Round(c0 * cp1.cmap[i][2] + c1 * cp2.cmap[i][2]);
end;
- Result.cmapindex := -1;
+ self.cmapindex := -1;
- Result.Fbrightness := c0 * cp1.Fbrightness + c1 * cp2.Fbrightness;
- Result.contrast := c0 * cp1.contrast + c1 * cp2.contrast;
- Result.gamma := c0 * cp1.gamma + c1 * cp2.gamma;
- Result.vibrancy := c0 * cp1.vibrancy + c1 * cp2.vibrancy;
- Result.gamma_threshold := c0 * cp1.gamma_threshold + c1 * cp2.gamma_threshold;
- Result.width := cp1.width;
- Result.height := cp1.height;
- Result.spatial_oversample := Round(c0 * cp1.spatial_oversample + c1 * cp2.spatial_oversample);
- Result.center[0] := c0 * cp1.center[0] + c1 * cp2.center[0];
- Result.center[1] := c0 * cp1.center[1] + c1 * cp2.center[1];
- Result.FAngle := c0 * cp1.FAngle + c1 * AngOpt(cp1.FAngle, cp2.FAngle);
- Result.pixels_per_unit := c0 * cp1.pixels_per_unit + c1 * cp2.pixels_per_unit;
- Result.background[0] := Round(c0 * cp1.background[0] + c1 * cp2.background[0]);
- Result.background[1] := Round(c0 * cp1.background[1] + c1 * cp2.background[1]);
- Result.background[2] := Round(c0 * cp1.background[2] + c1 * cp2.background[2]);
- Result.spatial_filter_radius := c0 * cp1.spatial_filter_radius + c1 * cp2.spatial_filter_radius;
- Result.sample_density := c0 * cp1.sample_density + c1 * cp2.sample_density;
- Result.zoom := c0 * cp1.zoom + c1 * cp2.zoom;
- Result.nbatches := Round(c0 * cp1.nbatches + c1 * cp2.nbatches);
- Result.white_level := Round(c0 * cp1.white_level + c1 * cp2.white_level);
- Result.finalXformEnabled := cp1.finalXformEnabled or cp2.finalXformEnabled;
+ Fbrightness := c0 * cp1.Fbrightness + c1 * cp2.Fbrightness;
+ contrast := c0 * cp1.contrast + c1 * cp2.contrast;
+ gamma := c0 * cp1.gamma + c1 * cp2.gamma;
+ vibrancy := c0 * cp1.vibrancy + c1 * cp2.vibrancy;
+ gamma_threshold := c0 * cp1.gamma_threshold + c1 * cp2.gamma_threshold;
+ width := cp1.width;
+ height := cp1.height;
+ spatial_oversample := Round(c0 * cp1.spatial_oversample + c1 * cp2.spatial_oversample);
+ center[0] := c0 * cp1.center[0] + c1 * cp2.center[0];
+ center[1] := c0 * cp1.center[1] + c1 * cp2.center[1];
+ FAngle := c0 * cp1.FAngle + c1 * AngOpt(cp1.FAngle, cp2.FAngle);
+ pixels_per_unit := c0 * cp1.pixels_per_unit + c1 * cp2.pixels_per_unit;
+ background[0] := Round(c0 * cp1.background[0] + c1 * cp2.background[0]);
+ background[1] := Round(c0 * cp1.background[1] + c1 * cp2.background[1]);
+ background[2] := Round(c0 * cp1.background[2] + c1 * cp2.background[2]);
+ spatial_filter_radius := c0 * cp1.spatial_filter_radius + c1 * cp2.spatial_filter_radius;
+ sample_density := c0 * cp1.sample_density + c1 * cp2.sample_density;
+ zoom := c0 * cp1.zoom + c1 * cp2.zoom;
+ nbatches := Round(c0 * cp1.nbatches + c1 * cp2.nbatches);
+ // white_level := Round(c0 * cp1.white_level + c1 * cp2.white_level);
{ AV: global 3D-parameters}
- Result.cameraPitch := c0 * cp1.cameraPitch + c1 * AngOpt(cp1.cameraPitch, cp2.cameraPitch);
- Result.cameraYaw := c0 * cp1.cameraYaw + c1 * AngOpt(cp1.cameraYaw, cp2.cameraYaw);
- Result.cameraRoll := c0 * cp1.cameraRoll + c1 * AngOpt(cp1.cameraRoll, cp2.cameraRoll);
- Result.cameraPersp := c0 * cp1.cameraPersp + c1 * cp2.cameraPersp;
- Result.cameraZpos := c0 * cp1.cameraZpos + c1 * cp2.cameraZpos;
- Result.cameraDOF := c0 * cp1.cameraDOF + c1 * cp2.cameraDOF;
+ cameraPitch := c0 * cp1.cameraPitch + c1 * AngOpt(cp1.cameraPitch, cp2.cameraPitch);
+ cameraYaw := c0 * cp1.cameraYaw + c1 * AngOpt(cp1.cameraYaw, cp2.cameraYaw);
+ cameraRoll := c0 * cp1.cameraRoll + c1 * AngOpt(cp1.cameraRoll, cp2.cameraRoll);
+ cameraPersp := c0 * cp1.cameraPersp + c1 * cp2.cameraPersp;
+ cameraZpos := c0 * cp1.cameraZpos + c1 * cp2.cameraZpos;
+ cameraDOF := c0 * cp1.cameraDOF + c1 * cp2.cameraDOF;
for i := 0 to 3 do begin
- // Result.pulse[i div 2][i mod 2] := c0 * cp1.pulse[i div 2][i mod 2] + c1 * cp2.pulse[i div 2][i mod 2];
- // Result.wiggle[i div 2][i mod 2] := c0 * cp1.wiggle[i div 2][i mod 2] + c1 * cp2.wiggle[i div 2][i mod 2];
- Result.curvePoints[i][0].x := c0 * cp1.curvePoints[i][0].x + c1 * cp2.curvePoints[i][0].x;
- Result.curvePoints[i][0].y := c0 * cp1.curvePoints[i][0].y + c1 * cp2.curvePoints[i][0].y;
- Result.curveWeights[i][0] := c0 * cp1.curveWeights[i][0] + c1 * cp2.curveWeights[i][0];
- Result.curvePoints[i][1].x := c0 * cp1.curvePoints[i][1].x + c1 * cp2.curvePoints[i][1].x;
- Result.curvePoints[i][1].y := c0 * cp1.curvePoints[i][1].y + c1 * cp2.curvePoints[i][1].y;
- Result.curveWeights[i][1] := c0 * cp1.curveWeights[i][1] + c1 * cp2.curveWeights[i][1];
- Result.curvePoints[i][2].x := c0 * cp1.curvePoints[i][2].x + c1 * cp2.curvePoints[i][2].x;
- Result.curvePoints[i][2].y := c0 * cp1.curvePoints[i][2].y + c1 * cp2.curvePoints[i][2].y;
- Result.curveWeights[i][2] := c0 * cp1.curveWeights[i][2] + c1 * cp2.curveWeights[i][2];
- Result.curvePoints[i][3].x := c0 * cp1.curvePoints[i][2].x + c1 * cp2.curvePoints[i][2].x;
- Result.curvePoints[i][3].y := c0 * cp1.curvePoints[i][3].y + c1 * cp2.curvePoints[i][3].y;
- Result.curveWeights[i][3] := c0 * cp1.curveWeights[i][3] + c1 * cp2.curveWeights[i][3];
+ curvePoints[i][0].x := c0 * cp1.curvePoints[i][0].x + c1 * cp2.curvePoints[i][0].x;
+ curvePoints[i][0].y := c0 * cp1.curvePoints[i][0].y + c1 * cp2.curvePoints[i][0].y;
+ curveWeights[i][0] := c0 * cp1.curveWeights[i][0] + c1 * cp2.curveWeights[i][0];
+ curvePoints[i][1].x := c0 * cp1.curvePoints[i][1].x + c1 * cp2.curvePoints[i][1].x;
+ curvePoints[i][1].y := c0 * cp1.curvePoints[i][1].y + c1 * cp2.curvePoints[i][1].y;
+ curveWeights[i][1] := c0 * cp1.curveWeights[i][1] + c1 * cp2.curveWeights[i][1];
+ curvePoints[i][2].x := c0 * cp1.curvePoints[i][2].x + c1 * cp2.curvePoints[i][2].x;
+ curvePoints[i][2].y := c0 * cp1.curvePoints[i][2].y + c1 * cp2.curvePoints[i][2].y;
+ curveWeights[i][2] := c0 * cp1.curveWeights[i][2] + c1 * cp2.curveWeights[i][2];
+ curvePoints[i][3].x := c0 * cp1.curvePoints[i][2].x + c1 * cp2.curvePoints[i][2].x;
+ curvePoints[i][3].y := c0 * cp1.curvePoints[i][3].y + c1 * cp2.curvePoints[i][3].y;
+ curveWeights[i][3] := c0 * cp1.curveWeights[i][3] + c1 * cp2.curveWeights[i][3];
end;
numTX1 := cp1.NumXForms;
numTX2 := cp2.NumXForms;
numTX := max(numTX1, numTX2); // actual xforms including final
- if Result.finalXformEnabled then
+ f1 := cp1.FinalXformEnabled; // cp1.hasFinalXform;
+ f2 := cp2.FinalXformEnabled; // cp2.hasFinalXform;
+
+ if f1 or f2 then
begin
-
- if cp1.finalXformEnabled then
- begin
- if numTX1 < numTX then
- begin
- cp1.xform[numTX].Assign(cp1.xform[numTX1]);
- cp1.xform[numTX1].Clear;
+ if f1 then
+ begin
+ if numTX1 < numTX then
+ begin
+ cp1.xform[numTX].Assign(cp1.xform[numTX1]);
+ cp1.xform[numTX1].Clear;
+ cp1.xform[numTX1].SetVariation(0,0);
+ end;
+ end
+ else
+ cp1.xform[numTX].symmetry := 1;
+
+ if f2 then
+ begin
+ if numTX2 < numTX then
+ begin
+ cp2.xform[numTX].Assign(cp2.xform[numTX2]);
+ cp2.xform[numTX2].Clear;
+ cp2.xform[numTX2].SetVariation(0,0);
+ end;
+ end
+ else
+ cp2.xform[numTX].symmetry := 1;
+
+ // final XForm
+ finalXformEnabled := True;
+ xform[numTX].color := c0 * cp1.xform[numTX].color + c1 * cp2.xform[numTX].color;
+ xform[numTX].symmetry := c0 * cp1.xform[numTX].symmetry + c1 * cp2.xform[numTX].symmetry;
+ xform[numTX].pluginColor := c0 * cp1.xform[numTX].pluginColor + c1 * cp2.xform[numTX].pluginColor;
+ xform[numTX].ifs.Assign(cp2.xform[numTX].ifs); // AV: target variation order
+ for j := 0 to NrVar-1 do begin
+ v1 := cp1.xform[numTX].GetVariation(j);
+ v2 := cp2.xform[numTX].GetVariation(j);
+ if v1 = v2 then
+ xform[numTX].SetVariation(j, v1)
+ else
+ xform[numTX].SetVariation(j, c0 * v1 + c1 * v2);
end;
- end
- else
- cp1.xform[numTX].symmetry := 1;
-
- if cp2.finalXformEnabled then
- begin
- if numTX2 < numTX then
- begin
- cp2.xform[numTX].Assign(cp2.xform[numTX2]);
- cp2.xform[numTX2].Clear;
- end;
- end
- else
- cp2.xform[numTX].symmetry := 1;
-
- // final XForm
- Result.xform[numTX].color := c0 * cp1.xform[numTX].color + c1 * cp2.xform[numTX].color;
- Result.xform[numTX].symmetry := c0 * cp1.xform[numTX].symmetry + c1 * cp2.xform[numTX].symmetry;
- Result.xform[numTX].pluginColor := c0 * cp1.xform[numTX].pluginColor + c1 * cp2.xform[numTX].pluginColor;
- Result.xform[numTX].ifs.Assign(cp2.xform[numTX].ifs); // AV: target variation order
- for j := 0 to NrVar-1 do
- Result.xform[numTX].SetVariation(j, c0 * cp1.xform[numTX].GetVariation(j) + c1 * cp2.xform[numTX].GetVariation(j));
- for j:= 0 to GetNrVariableNames-1 do begin
- cp1.xform[numTX].GetVariable(GetVariableNameAt(j), v1);
- cp2.xform[numTX].GetVariable(GetVariableNameAt(j), v2);
- v1 := c0 * v1 + c1 * v2;
- Result.xform[numTX].SetVariable(GetVariableNameAt(j), v1);
+ for j:= 0 to GetNrVariableNames-1 do begin
+ cp1.xform[numTX].GetVariable(GetVariableNameAt(j), v1);
+ cp2.xform[numTX].GetVariable(GetVariableNameAt(j), v2);
+ if v1 <> v2 then v1 := c0 * v1 + c1 * v2;
+ xform[numTX].SetVariable(GetVariableNameAt(j), v1);
+ end;
+ for j := 0 to 2 do begin
+ xform[numTX].c[j, 0] := c0 * cp1.xform[numTX].c[j, 0] + c1 * cp2.xform[numTX].c[j, 0];
+ xform[numTX].c[j, 1] := c0 * cp1.xform[numTX].c[j, 1] + c1 * cp2.xform[numTX].c[j, 1];
+ xform[numTX].p[j, 0] := c0 * cp1.xform[numTX].p[j, 0] + c1 * cp2.xform[numTX].p[j, 0];
+ xform[numTX].p[j, 1] := c0 * cp1.xform[numTX].p[j, 1] + c1 * cp2.xform[numTX].p[j, 1];
+ end;
+ end
+ else begin
+ finalXformEnabled := False;
+ xform[numTX].symmetry := 1;
end;
- for j := 0 to 2 do begin
- Result.xform[numTX].c[j, 0] := c0 * cp1.xform[numTX].c[j, 0] + c1 * cp2.xform[numTX].c[j, 0];
- Result.xform[numTX].c[j, 1] := c0 * cp1.xform[numTX].c[j, 1] + c1 * cp2.xform[numTX].c[j, 1];
- Result.xform[numTX].p[j, 0] := c0 * cp1.xform[numTX].p[j, 0] + c1 * cp2.xform[numTX].p[j, 0];
- Result.xform[numTX].p[j, 1] := c0 * cp1.xform[numTX].p[j, 1] + c1 * cp2.xform[numTX].p[j, 1];
- end;
- end else
- Result.xform[numTX].symmetry := 1;
-
+
// regular xforms
for i := 0 to numTX-1 do begin
- Result.xform[i].density := c0 * cp1.xform[i].density + c1 * cp2.xform[i].density;
- Result.xform[i].color := c0 * cp1.xform[i].color + c1 * cp2.xform[i].color;
- Result.xform[i].symmetry := c0 * cp1.xform[i].symmetry + c1 * cp2.xform[i].symmetry;
- Result.xform[i].transOpacity := c0 * cp1.xform[i].transOpacity + c1 * cp2.xform[i].transOpacity;
- Result.xform[i].pluginColor := c0 * cp1.xform[i].pluginColor + c1 * cp2.xform[i].pluginColor;
+ xform[i].density := c0 * cp1.xform[i].density + c1 * cp2.xform[i].density;
+ xform[i].color := c0 * cp1.xform[i].color + c1 * cp2.xform[i].color;
+ xform[i].symmetry := c0 * cp1.xform[i].symmetry + c1 * cp2.xform[i].symmetry;
+ xform[i].transOpacity := c0 * cp1.xform[i].transOpacity + c1 * cp2.xform[i].transOpacity;
+ xform[i].pluginColor := c0 * cp1.xform[i].pluginColor + c1 * cp2.xform[i].pluginColor;
for j := 0 to numTX - 1 do
- Result.xform[i].modWeights[j] := c0 * cp1.xform[i].modWeights[j] + c1 * cp2.xform[i].modWeights[j];
+ self.xform[i].modWeights[j] := c0 * cp1.xform[i].modWeights[j] + c1 * cp2.xform[i].modWeights[j];
- Result.xform[i].ifs.Assign(cp2.xform[i].ifs); // AV: target variation order
- for j := 0 to NrVar-1 do
- Result.xform[i].SetVariation(j, c0 * cp1.xform[i].GetVariation(j) + c1 * cp2.xform[i].GetVariation(j));
+ xform[i].ifs.Assign(cp2.xform[i].ifs); // AV: target variation order
+ for j := 0 to NrVar-1 do begin
+ v1 := cp1.xform[i].GetVariation(j);
+ v2 := cp2.xform[i].GetVariation(j);
+ if v1 = v2 then
+ xform[i].SetVariation(j, v1)
+ else
+ xform[i].SetVariation(j, c0 * v1 + c1 * v2);
+ end;
for j:= 0 to GetNrVariableNames-1 do begin
cp1.xform[i].GetVariable(GetVariableNameAt(j), v1);
cp2.xform[i].GetVariable(GetVariableNameAt(j), v2);
- v1 := c0 * v1 + c1 * v2;
- Result.xform[i].SetVariable(GetVariableNameAt(j), v1);
+ if v1 <> v2 then v1 := c0 * v1 + c1 * v2;
+ xform[i].SetVariable(GetVariableNameAt(j), v1);
end;
// interpol matrices
for j := 0 to 2 do begin
- Result.xform[i].c[j, 0] := c0 * cp1.xform[i].c[j, 0] + c1 * cp2.xform[i].c[j, 0];
- Result.xform[i].c[j, 1] := c0 * cp1.xform[i].c[j, 1] + c1 * cp2.xform[i].c[j, 1];
- Result.xform[i].p[j, 0] := c0 * cp1.xform[i].p[j, 0] + c1 * cp2.xform[i].p[j, 0];
- Result.xform[i].p[j, 1] := c0 * cp1.xform[i].p[j, 1] + c1 * cp2.xform[i].p[j, 1];
+ xform[i].c[j, 0] := c0 * cp1.xform[i].c[j, 0] + c1 * cp2.xform[i].c[j, 0];
+ xform[i].c[j, 1] := c0 * cp1.xform[i].c[j, 1] + c1 * cp2.xform[i].c[j, 1];
+ xform[i].p[j, 0] := c0 * cp1.xform[i].p[j, 0] + c1 * cp2.xform[i].p[j, 0];
+ xform[i].p[j, 1] := c0 * cp1.xform[i].p[j, 1] + c1 * cp2.xform[i].p[j, 1];
end;
end;
- if Result.NumXForms < numTX then
- begin
- Result.xform[Result.NumXForms].Assign(Result.xform[numTX]);
- Result.xform[numTX].Clear;
- end;
-
if numTX1 < numTX then
begin
cp1.xform[numTX1].Assign(cp1.xform[numTX]);
cp1.xform[numTX].Clear;
end;
- if numTX2 < Result.NumXForms then
+ if numTX2 < numTX then
begin
cp2.xform[numTX2].Assign(cp2.xform[numTX]);
cp2.xform[numTX].Clear;
end;
-
- Copy(Result, false, numTX);
- cmap := Result.cmap;
- result.free;
end;
procedure TControlPoint.InterpolateX(cp1, cp2: TControlPoint; Tm: double);
var
- result: TControlPoint;
c0, c1: double;
i, j: integer;
- r, s, t: array[0..2] of double;
v1, v2: double;
-// totvar: double;
- {z,rhtime: double;}
- nXforms1, nXforms2: integer;
+ nXforms1, nXmax: integer;
begin
if (cp2.time - cp1.time) > 1E-6 then begin
c0 := (cp2.time - tm) / (cp2.time - cp1.time);
@@ -1881,8 +1853,9 @@ begin
c1 := 0;
end;
- Result := TControlPoint.Create;
- Result.time := Tm;
+ // AV: replaced all useless copying into temporary Result variable
+ // by direct assignments to self ControlPoint instance
+ self.time := Tm;
{ // AV: since from now this is used only for mutants, we can skip it
if cp1.cmap_inter = 0 then
@@ -1904,30 +1877,30 @@ begin
Result.cmap[i][2] := Round(255 * r[2]);
end;
}
- Result.cmap := cp1.cmap; // AV
- Result.cmapindex := -1;
+ cmap := cp1.cmap; // AV
+ cmapindex := -1;
- Result.Fbrightness := c0 * cp1.Fbrightness + c1 * cp2.Fbrightness;
- Result.contrast := c0 * cp1.contrast + c1 * cp2.contrast;
- Result.gamma := c0 * cp1.gamma + c1 * cp2.gamma;
- Result.vibrancy := c0 * cp1.vibrancy + c1 * cp2.vibrancy;
- Result.gamma_threshold := c0 * cp1.gamma_threshold + c1 * cp2.gamma_threshold;
- Result.width := cp1.width;
- Result.height := cp1.height;
- Result.spatial_oversample := Round(c0 * cp1.spatial_oversample + c1 * cp2.spatial_oversample);
- Result.center[0] := c0 * cp1.center[0] + c1 * cp2.center[0];
- Result.center[1] := c0 * cp1.center[1] + c1 * cp2.center[1];
- Result.FAngle := c0 * cp1.FAngle + c1 * cp2.FAngle;
- Result.pixels_per_unit := c0 * cp1.pixels_per_unit + c1 * cp2.pixels_per_unit;
+ Fbrightness := c0 * cp1.Fbrightness + c1 * cp2.Fbrightness;
+ contrast := c0 * cp1.contrast + c1 * cp2.contrast;
+ gamma := c0 * cp1.gamma + c1 * cp2.gamma;
+ vibrancy := c0 * cp1.vibrancy + c1 * cp2.vibrancy;
+ gamma_threshold := c0 * cp1.gamma_threshold + c1 * cp2.gamma_threshold;
+ width := cp1.width;
+ height := cp1.height;
+ spatial_oversample := Round(c0 * cp1.spatial_oversample + c1 * cp2.spatial_oversample);
+ center[0] := c0 * cp1.center[0] + c1 * cp2.center[0];
+ center[1] := c0 * cp1.center[1] + c1 * cp2.center[1];
+ FAngle := c0 * cp1.FAngle + c1 * cp2.FAngle;
+ pixels_per_unit := c0 * cp1.pixels_per_unit + c1 * cp2.pixels_per_unit;
{ // AV: since from now this is used only for mutants, we can skip it
Result.background[0] := c0 * cp1.background[0] + c1 * cp2.background[0];
Result.background[1] := c0 * cp1.background[1] + c1 * cp2.background[1];
Result.background[2] := c0 * cp1.background[2] + c1 * cp2.background[2];
}
- Result.spatial_filter_radius := c0 * cp1.spatial_filter_radius + c1 * cp2.spatial_filter_radius;
- Result.sample_density := c0 * cp1.sample_density + c1 * cp2.sample_density;
- Result.zoom := c0 * cp1.zoom + c1 * cp2.zoom;
- Result.nbatches := Round(c0 * cp1.nbatches + c1 * cp2.nbatches);
+ spatial_filter_radius := c0 * cp1.spatial_filter_radius + c1 * cp2.spatial_filter_radius;
+ sample_density := c0 * cp1.sample_density + c1 * cp2.sample_density;
+ zoom := c0 * cp1.zoom + c1 * cp2.zoom;
+ nbatches := Round(c0 * cp1.nbatches + c1 * cp2.nbatches);
{
Result.white_level := Round(c0 * cp1.white_level + c1 * cp2.white_level);
for i := 0 to 3 do begin
@@ -1935,11 +1908,12 @@ begin
Result.wiggle[i div 2][i mod 2] := c0 * cp1.wiggle[i div 2][i mod 2] + c1 * cp2.wiggle[i div 2][i mod 2];
end;
}
- Result.cameraPitch := c0 * cp1.cameraPitch; // AV
- Result.cameraYaw := c0 * cp1.cameraYaw; // AV
- Result.cameraRoll := c0 * cp1.cameraRoll; // AV
+ cameraPitch := c0 * cp1.cameraPitch; // AV
+ cameraYaw := c0 * cp1.cameraYaw; // AV
+ cameraRoll := c0 * cp1.cameraRoll; // AV
// save finalxform from mut(il)ation ;)
+ {
nXforms1 := cp1.NumXForms;
if cp1.HasFinalXForm then
begin
@@ -1967,42 +1941,60 @@ begin
cp2.xform[NXFORMS].Clear;
cp2.xform[NXFORMS].symmetry := 1;
end;
-
- for i := 0 to NXFORMS do
+ }
+ nXforms1 := cp1.NumXForms;
+ nXmax := cp2.NumXForms;
+ nXmax := max(nxForms1, nXmax);
+ // AV: since we don't change final xforms, we can speed up the calculations
+ for i := 0 to nXmax - 1 do
begin
- Result.xform[i].density := c0 * cp1.xform[i].density + c1 * cp2.xform[i].density;
- // AV: since we don't change final xforms, we can speed up the calculations
- if Result.xform[i].density = 0.0 then break;
- Result.xform[i].color := c0 * cp1.xform[i].color + c1 * cp2.xform[i].color;
- Result.xform[i].symmetry := c0 * cp1.xform[i].symmetry + c1 * cp2.xform[i].symmetry;
- Result.xform[i].transOpacity := c0 * cp1.xform[i].transOpacity + c1; // AV
+ xform[i].density := c0 * cp1.xform[i].density + c1 * cp2.xform[i].density;
+ xform[i].color := c0 * cp1.xform[i].color + c1 * cp2.xform[i].color;
+ xform[i].symmetry := c0 * cp1.xform[i].symmetry + c1 * cp2.xform[i].symmetry;
+ xform[i].transOpacity := c0 * cp1.xform[i].transOpacity + c1; // AV
- for j := 0 to NrVar-1 do
- Result.xform[i].SetVariation(j, c0 * cp1.xform[i].GetVariation(j) + c1 * cp2.xform[i].GetVariation(j));
+ for j := 0 to NrVar-1 do begin
+ //xform[i].SetVariation(j, c0 * cp1.xform[i].GetVariation(j) + c1 * cp2.xform[i].GetVariation(j));
+ v1 := cp1.xform[i].GetVariation(j);
+ v2 := cp2.xform[i].GetVariation(j);
+ if v1 = v2 then
+ xform[i].SetVariation(j, v1)
+ else
+ xform[i].SetVariation(j, c0 * v1 + c1 * v2);
+ end;
for j:= 0 to GetNrVariableNames-1 do begin
cp1.xform[i].GetVariable(GetVariableNameAt(j), v1);
cp2.xform[i].GetVariable(GetVariableNameAt(j), v2);
- v1 := c0 * v1 + c1 * v2;
- Result.xform[i].SetVariable(GetVariableNameAt(j), v1);
+ if v1 <> v2 then v1 := c0 * v1 + c1 * v2; // AV
+ xform[i].SetVariable(GetVariableNameAt(j), v1);
end;
// interpol matrix
for j := 0 to 2 do begin
- Result.xform[i].c[j, 0] := c0 * cp1.xform[i].c[j, 0] + c1 * cp2.xform[i].c[j, 0];
- Result.xform[i].c[j, 1] := c0 * cp1.xform[i].c[j, 1] + c1 * cp2.xform[i].c[j, 1];
+ xform[i].c[j, 0] := c0 * cp1.xform[i].c[j, 0] + c1 * cp2.xform[i].c[j, 0];
+ xform[i].c[j, 1] := c0 * cp1.xform[i].c[j, 1] + c1 * cp2.xform[i].c[j, 1];
// AV
- Result.xform[i].p[j, 0] := c0 * cp1.xform[i].p[j, 0] + c1 * cp2.xform[i].p[j, 0];
- Result.xform[i].p[j, 1] := c0 * cp1.xform[i].p[j, 1] + c1 * cp2.xform[i].p[j, 1];
+ xform[i].p[j, 0] := c0 * cp1.xform[i].p[j, 0] + c1 * cp2.xform[i].p[j, 0];
+ xform[i].p[j, 1] := c0 * cp1.xform[i].p[j, 1] + c1 * cp2.xform[i].p[j, 1];
end;
end;
+ finalXformEnabled := cp1.finalXformEnabled;
// finalxform was supposed to be mutate-able too, but somehow it's always
- // getting confused by random-generated mutatns :-\
- if Result.NumXForms < NXFORMS then
+ // getting confused by random-generated mutants :-\
+
+ if cp1.HasFinalXForm then begin
+ xform[nXmax].Assign(cp1.xform[nXforms1]);
+ if nXforms1 < nXmax then // reset color speed of cp1's final transform
+ xform[nXforms1].symmetry := 0;
+ end
+ else
+ xform[nXmax].Symmetry := 1;
+ {
+ if NumXForms < NXFORMS then
begin
- Result.xform[Result.NumXForms].Assign(cp1.xform[NXFORMS]); //result.xform[NXFORMS]);
- Result.xform[NXFORMS].Clear;
+ xform[NumXForms].Assign(cp1.xform[NXFORMS]);
+ xform[NXFORMS].Clear;
end;
- Result.finalXformEnabled := cp1.finalXformEnabled;
// restore finalxforms in source CPs
if nXforms1 < NXFORMS then
@@ -2015,10 +2007,7 @@ begin
cp2.xform[nXforms2].Assign(cp2.xform[NXFORMS]);
cp2.xform[NXFORMS].Clear;
end;
-
- Copy(Result, false, max(nxForms1, nxForms2)); // AV: added 2 parameters
- cmap := Result.cmap;
- result.free;
+ }
end;
procedure TControlPoint.SaveToFile(Filename: string);
@@ -2088,8 +2077,8 @@ begin
// sl.add(format('nbatches %d white_level %d background %f %f %f', - changed to integers - mt
sl.add(format('nbatches %d white_level %d background %d %d %d',
[nbatches, white_level, background[0], background[1], background[2]]));
- sl.add(format('brightness %f gamma %f contrast %f vibrancy %f gamma_threshold %f hue_rotation %f cmap_inter %d',
- [Fbrightness * BRIGHT_ADJUST, gamma, contrast, vibrancy, gamma_threshold, hue_rotation, cmap_inter])); // AV: added contrast
+ sl.add(format('brightness %f gamma %f contrast %f vibrancy %f gamma_threshold %f hue_rotation %f', {cmap_inter %d',}
+ [Fbrightness * BRIGHT_ADJUST, gamma, contrast, vibrancy, gamma_threshold, hue_rotation {, cmap_inter}])); // AV: added contrast
sl.add(format('finalxformenabled %d', [ifthen(finalxformenabled, 1, 0)]));
sl.add(format('soloxform %d', [soloXform]));
@@ -2198,12 +2187,12 @@ var
handle: File;
begin
// I'm a bit ashamed but this hack has do to it for now...
- AssignFile(handle, GetEnvironmentVariable('TEMP') + '\CalcBinaryFlameSizeTemp.bin');
+ AssignFile(handle, AppData + 'CalcBinaryFlameSizeTemp.bin');
ReWrite(handle, HIB_BLOCKSIZE);
cp.SaveToBinary(handle);
Result := FileSize(handle) * HIB_BLOCKSIZE;
CloseFile(handle);
- DeleteFile(GetEnvironmentVariable('TEMP') + '\CalcBinaryFlameSizeTemp.bin');
+ DeleteFile(AppData + 'CalcBinaryFlameSizeTemp.bin');
(*// CP data
Result := 224;
@@ -2258,12 +2247,16 @@ begin
DoubleToBlock(block, 0, cameraPitch);
DoubleToBlock(block, 8, cameraYaw);
BlockWrite(handle, block, 1);
-// AV TODO: cam_roll, contrast and var_order
- DoubleToBlock(block, 0, cameraPersp);
+
+ DoubleToBlock(block, 0, cameraRoll); // AV
DoubleToBlock(block, 8, cameraZpos);
BlockWrite(handle, block, 1);
+
+ DoubleToBlock(block, 0, cameraPersp);
+ DoubleToBlock(block, 8, cameraDOF);
+ BlockWrite(handle, block, 1);
- DoubleToBlock(block, 0, cameraDOF);
+ DoubleToBlock(block, 0, contrast); // AV
DoubleToBlock(block, 8, spatial_filter_radius);
BlockWrite(handle, block, 1);
@@ -2271,19 +2264,19 @@ begin
DoubleToBlock(block, 8, gamma_threshold);
BlockWrite(handle, block, 1);
- Int32ToBlock(block, 0, cmapindex);
+ //Int32ToBlock(block, 0, cmapindex);// TODO: replace
Int32ToBlock(block, 4, spatial_oversample);
Int32ToBlock(block, 8, Width);
Int32ToBlock(block, 12, Height);
BlockWrite(handle, block, 1);
Int32ToBlock(block, 0, nbatches);
- Int32ToBlock(block, 4, cmap_inter);
+ //Int32ToBlock(block, 4, cmap_inter); // TODO: replace
Int32ToBlock(block, 8, ifthen(finalxformenabled, 1, 0));
Int32ToBlock(block, 12, soloXform);
BlockWrite(handle, block, 1);
- Int32ToBlock(block, 0, white_level);
+ //Int32ToBlock(block, 0, white_level); // TODO: replace
Int32ToBlock(block, 4, background[0]);
Int32ToBlock(block, 8, background[1]);
Int32ToBlock(block, 12, background[2]);
@@ -2305,6 +2298,7 @@ begin
Int32ToBlock(block, 4, nvariables);
Int32ToBlock(block, 8, nchaos);
+// AV TODO: var_order
str := '';
for i := 0 to nvariations-1 do
str := str + VarNames(i) + #0;
@@ -2375,8 +2369,79 @@ begin
end;
end;
+procedure TControlPoint.DirectCopy_AV(const cp1: TControlPoint); // AV
+var
+ i, j: smallint;
+begin
+ self.name := cp1.name;
+ self.time := cp1.time;
+
+ if cp1.cmapindex >= 0 then cmapindex := cp1.cmapindex;
+ hue_rotation := cp1.hue_rotation; // AV
+ cmap := cp1.cmap;
+
+ zoom := cp1.zoom;
+ Fangle := cp1.FAngle;
+ cameraPitch := cp1.cameraPitch;
+ cameraYaw := cp1.cameraYaw;
+ cameraRoll := cp1.cameraRoll;
+ cameraPersp := cp1.cameraPersp;
+ cameraZpos := cp1.cameraZpos;
+ cameraDOF := cp1.cameraDOF;
+
+ Width := cp1.Width;
+ Height := cp1.Height;
+
+ center[0]:= cp1.center[0];
+ center[1]:= cp1.center[1];
+ pixels_per_unit := cp1.pixels_per_unit;
+
+ background[0] := cp1.background[0];
+ background[1] := cp1.background[1];
+ background[2] := cp1.background[2];
+
+ for i := 0 to 3 do
+ for j := 0 to 3 do begin
+ curveWeights[i,j] := cp1.curveWeights[i,j];
+ curvePoints[i,j].x := cp1.curvePoints[i,j].x;
+ curvePoints[i,j].y := cp1.curvePoints[i,j].y;
+ end;
+
+ spatial_oversample := cp1.spatial_oversample;
+ spatial_filter_radius := cp1.spatial_filter_radius;
+ sample_density := cp1.sample_density;
+
+ nbatches := cp1.nbatches;
+ //white_level := cp1.white_level; // <-- AV: it's const for now
+ //jitters := cp1.jitters; //<-- AV: currently unused
+ //Transparency := cp1.Transparency; // <-- do this?
+
+ brightness := cp1.brightness;
+ gamma := cp1.gamma;
+ gamma_threshold := cp1.gamma_threshold;
+ contrast := cp1.contrast; // AV
+ vibrancy := cp1.vibrancy;
+
+ finalXformEnabled := cp1.finalXformEnabled;
+ soloXform := cp1.soloXform;
+
+ estimator := cp1.estimator;
+ estimator_min := cp1.estimator_min;
+ estimator_curve := cp1.estimator_curve;
+ enable_de := cp1.enable_de;
+
+ comment := cp1.comment; // AV
+
+ // used_plugins := cp1.used_plugins; // <<--- fixed memory leak // AV
+ used_plugins.Clear; // AV: that's how we must copy strings:
+ used_plugins.AddStrings(cp1.used_plugins);
+
+ for i := 0 to NXFORMS do // was: NXFORMS-1
+ xform[i].assign(cp1.xform[i]);
+end;
function TControlPoint.Clone: TControlPoint;
+(*
var
i, j: integer;
sl: TStringList;
@@ -2397,7 +2462,8 @@ begin
Result.estimator_min := estimator_min;
Result.estimator_curve := estimator_curve;
Result.enable_de := enable_de;
- Result.xdata := xdata;
+ // Result.xdata := xdata;
+ Result.comment := comment; // AV
Result.Background[0] := background[0];
Result.Background[1] := background[1];
@@ -2419,22 +2485,31 @@ begin
Result.xform[i].assign(xform[i]);
sl.Free;
+ *)
+begin
+ Result := TControlPoint.Create;
+ Result.DirectCopy_AV(self); // AV
+ Result.Transparency := Transparency;
end;
-procedure TControlPoint.Copy(cp1: TControlPoint; KeepSizes: boolean = false; nt: byte = NXFORMS);
+procedure TControlPoint.Copy(cp1: TControlPoint; KeepSizes: boolean = false);
var
- i, j: integer;
- sl: TStringList;
+ //i, j: integer;
+ //sl: TStringList;
w, h: integer;
begin
w := Width;
h := Height;
Clear;
+ DirectCopy_AV(cp1); // AV: made it faster than ever!
+
+ if KeepSizes then AdjustScale(w, h);
+ (*
sl := TStringList.Create;
// --Z-- this is quite a weird and unoptimal way to copy things:
- cp1.SaveToStringlist(sl);
+ cp1.SaveToStringlist(sl); // <-- AV: so we must optimize it ;-)
ParseStringlist(sl);
Fangle := cp1.FAngle;
@@ -2452,7 +2527,8 @@ begin
estimator_curve := cp1.estimator_curve;
enable_de := cp1.enable_de;
// used_plugins := cp1.used_plugins; // <<--- fixed memory leak // AV
- xdata := cp1.xdata;
+ // xdata := cp1.xdata;
+ comment := cp1.comment; // AV
background[0] := cp1.background[0];
background[1] := cp1.background[1];
@@ -2480,6 +2556,7 @@ begin
finalXformEnabled := cp1.finalXformEnabled;
sl.Free;
+ *)
end;
procedure TControlPoint.ParseStringList(sl: TStringlist);
@@ -2502,7 +2579,7 @@ begin
cmapindex := -1;
hue_rotation := 1; // AV
zoom := 0;
- xdata := '';
+ comment := ''; // AV
for i := 0 to NXFORMS do xform[i].Clear;
FinalXformEnabled := false;
soloxform := -1;
@@ -2515,14 +2592,9 @@ begin
curvePoints[i][3].x := 1.00; curvePoints[i][3].y := 1.00; curveWeights[i][3] := 1;
end;
- try
- if (used_plugins <> nil) then
+ if (used_plugins <> nil) then
used_plugins.Clear;
// else used_plugins := TStringlist.Create; // AV: now it's not needed
- except
- // hack
- // used_plugins := TStringList.Create; // AV: now it's not needed
- end;
end;
function TControlPoint.HasFinalXForm: boolean;
@@ -2540,42 +2612,22 @@ begin
end;
function add_symmetry_to_control_point(var cp: TControlPoint; sym: integer): integer;
-const
- sym_distrib: array[0..14] of integer = (
- -4, -3,
- -2, -2, -2,
- -1, -1, -1,
- 2, 2, 2,
- 3, 3,
- 4, 4
- );
var
i, j, k: integer;
a: double;
begin
result := 0;
if (0 = sym) then
- if (random(1) <> 0) then
- sym := sym_distrib[random(14)]
- else if (random(32) <> 0) then // not correct
- sym := random(13) - 6
- else
- sym := random(51) - 25;
+ sym := random(13) - 6;
if (1 = sym) or (0 = sym) then
- begin
- result := 0;
- exit;
- end;
+ Exit(0); // AV
- for i := 0 to NXFORMS - 1 do
- if (cp.xform[i].density = 0.0) then break;
+ i := cp.NumXForms; // AV
+
+ if (i + abs(sym)>= NXFORMS) then // AV: take into account additional xforms
+ Exit(0);
- if (i = NXFORMS) then
- begin
- result := 0;
- exit;
- end;
cp.symmetry := sym;
if (sym < 0) then
@@ -2585,7 +2637,7 @@ begin
cp.xform[i].SetVariation(0, 1.0);
for j := 1 to NRVAR - 1 do
cp.xform[i].SetVariation(j, 0.0);
- cp.xform[i].color := 1.0;
+ cp.xform[i].color := 1.0; // AV: why if color_speed = 1?!
cp.xform[i].c[0][0] := -1.0;
cp.xform[i].c[0][1] := 0.0;
cp.xform[i].c[1][0] := 0.0;
@@ -2600,9 +2652,7 @@ begin
a := 2 * PI / sym;
-// for (k = 1; (k < sym)&&(i < NXFORMS); k + + ) {
k := 1;
-// while (k < sym) and (i < NXFORMS) do
while (k < sym) and (i < SymmetryNVars) do
begin
cp.xform[i].density := 1.0;
@@ -2611,17 +2661,12 @@ begin
for j := 1 to NRVAR - 1 do
cp.xform[i].SetVariation(j, 0);
if sym < 3 then
- cp.xform[i].color := 0
+ cp.xform[i].color := 0 // AV: why if color_speed = 1?!
else
cp.xform[i].color := (k - 1) / (sym - 2);
- if cp.xform[i].color > 1 then
- begin
-// ShowMessage('Color value larger than 1');
- repeat
- cp.xform[i].color := cp.xform[i].color - 1
- until cp.xform[i].color <= 1;
- end;
+ while cp.xform[i].color > 1 do // AV: why if color_speed = 1?!
+ cp.xform[i].color := cp.xform[i].color - 1;
cp.xform[i].c[0][0] := cos(k * a);
cp.xform[i].c[0][1] := sin(k * a);
@@ -2636,13 +2681,13 @@ begin
end;
end;
-procedure tile_control_point(var cp: TControlPoint; sym: integer);
-var k, i, j: integer;
+procedure tile_control_point(var cp: TControlPoint; sym: integer); // AV
+var
+ k, i, j: smallint;
t, cost, sint: double;
begin
- for k := 0 to NXFORMS - 1 do
- if (cp.xform[k].density = 0.0) then break;
- if (k = NXFORMS) then exit;
+ k := cp.NumXForms;
+ if (k > NXFORMS - 5) then exit;
case sym of
1:
@@ -2699,7 +2744,97 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+ //***************************************************************
+
+function det(a, b, c, d: double): double;
+begin
+ Result := (a * d - b * c);
+end;
+
+function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double;
+ var a, b, e: double): double;
+var
+ det1: double;
+begin
+ det1 := x1 * det(y2, 1.0, z2, 1.0) - x2 * det(y1, 1.0, z1, 1.0)
+ + 1 * det(y1, y2, z1, z2);
+ if (det1 = 0.0) then
+ begin
+ Result := det1;
+ EXIT;
+ end
+ else
+ begin
+ a := (x1h * det(y2, 1.0, z2, 1.0) - x2 * det(y1h, 1.0, z1h, 1.0)
+ + 1 * det(y1h, y2, z1h, z2)) / det1;
+ b := (x1 * det(y1h, 1.0, z1h, 1.0) - x1h * det(y1, 1.0, z1, 1.0)
+ + 1 * det(y1, y1h, z1, z1h)) / det1;
+ e := (x1 * det(y2, y1h, z2, z1h) - x2 * det(y1, y1h, z1, z1h)
+ + x1h * det(y1, y2, z1, z2)) / det1;
+ a := Round6(a);
+ b := Round6(b);
+ e := Round6(e);
+ Result := det1;
+ end;
+end;
+
+function dist(x1, y1, x2, y2: double): double;
+//var
+// d2: double;
+begin
+(*
+ { From FDesign source
+ { float pt_pt_distance(float x1, float y1, float x2, float y2) }
+ d2 := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
+ if (d2 = 0.0) then
+ begin
+ Result := 0.0;
+ exit;
+ end
+ else
+ Result := sqrt(d2);
+*)
+
+ // --Z-- This is just amazing... :-\
+ // Someone needed an 'FDesign source' - to compute distance between two points??!?
+
+ Result := Hypot(x2-x1, y2-y1);
+end;
+
+function line_dist(x, y, x1, y1, x2, y2: double): double;
+var
+ a, b, e, c: double;
+begin
+ if ((x = x1) and (y = y1)) then
+ a := 0.0
+ else
+ a := sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
+ if ((x = x2) and (y = y2)) then
+ b := 0.0
+ else
+ b := sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
+ if ((x1 = x2) and (y1 = y2)) then
+ e := 0.0
+ else
+ e := sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+ if ((a * a + e * e) < (b * b)) then
+ Result := a
+ else if ((b * b + e * e) < (a * a)) then
+ Result := b
+ else if (e <> 0.0) then
+ begin
+ c := (b * b - a * a - e * e) / (-2 * e);
+ if ((a * a - c * c) < 0.0) then
+ Result := 0.0
+ else
+ Result := sqrt(a * a - c * c);
+ end
+ else
+ Result := a;
+end;
+
+//**************************************************************************//
+
procedure TControlPoint.ZoomtoRect(R: TSRect);
var
scale, ppu: double;
@@ -2720,7 +2855,6 @@ begin
pixels_per_unit := pixels_per_unit * Width / abs(r.Right - r.Left);
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TControlPoint.ZoomOuttoRect(R: TSRect);
var
ppu: double;
@@ -2740,7 +2874,6 @@ begin
center[1] := center[1] - sin(FAngle) * dx - cos(FAngle) * dy;
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TControlPoint.ZoomIn(Factor: double);
var
scale: double;
@@ -2751,7 +2884,6 @@ begin
Zoom := Log2(Scale);
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TControlPoint.MoveRect(R: TSRect);
var
scale: double;
@@ -2769,13 +2901,13 @@ begin
center[1] := center[1] + sin(FAngle) * dx + cos(FAngle) * dy ;
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TControlPoint.Rotate(Angle: double);
begin
FAngle := FAngle + Angle;
end;
-///////////////////////////////////////////////////////////////////////////////
+{//////////////////////////////////////////////////////////////////////////////}
+
function TControlPoint.getppux: double;
begin
result := pixels_per_unit * power(2, zoom)
@@ -2786,7 +2918,7 @@ begin
result := pixels_per_unit * power(2, zoom)
end;
-///////////////////////////////////////////////////////////////////////////////
+{/////////////////////////////////////////////////////////////////////////////}
function TControlPoint.GetBrightness: double;
begin
Result := Fbrightness;
@@ -2800,7 +2932,7 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+{//////////////////////////////////////////////////////////////////////////////}
function TControlPoint.GetRelativeGammaThreshold: double;
begin
if Fbrightness <> 0 then
@@ -2814,7 +2946,8 @@ begin
gamma_threshold := gtr * Fbrightness;
end;
-///////////////////////////////////////////////////////////////////////////////
+{//////////////////////////////////////////////////////////////////////////////}
+(*
var
vdfilled: boolean = False;
@@ -2845,15 +2978,15 @@ begin
vdfilled := true;
end;
-
-///////////////////////////////////////////////////////////////////////////////
+ *)
+{////////////////////////////////////////////////////////////////////////////}
//
// --Z-- cp-specific functions moved here from MainForm
//
function TControlPoint.NumXForms: integer;
var
- i: integer;
+ i: smallint;
begin
//...
Result := NXFORMS;
@@ -2870,13 +3003,14 @@ end;
function TControlPoint.TrianglesFromCP(var Triangles: TTriangles): integer;
{ Sets up the triangles from the IFS code }
var
- i, j: integer;
- temp_x, temp_y, xset, yset: double;
- left, top, bottom, right: double;
+ i, j: smallint;
+ //temp_x, temp_y, xset, yset: double;
+ //left, top, bottom, right: double;
begin
- top := 0; bottom := 0; right := 0; left := 0;
Result := NumXForms;
{
+ top := 0; bottom := 0; right := 0; left := 0;
+
if ReferenceMode > 0 then
begin
for i := 0 to Result-1 do
@@ -2954,15 +3088,9 @@ begin
Triangles[j].y[i] := -Triangles[j].y[i];
end;
-procedure TControlPoint.EqualizeWeights;
-var
- t, i: integer;
-begin
- t := NumXForms;
- for i := 0 to t - 1 do
- xform[i].density := 0.5;
-end;
+//************ Weight distribution utils *************************//
+(* // AV: we have the save methods in RndFlame module
procedure TControlPoint.NormalizeWeights;
var
i: integer;
@@ -2978,14 +3106,6 @@ begin
xform[i].Density := xform[i].Density / td;
end;
-procedure TControlPoint.RandomizeWeights;
-var
- i: integer;
-begin
- for i := 0 to Transforms - 1 do
- xform[i].Density := Random;
-end;
-
procedure TControlPoint.ComputeWeights(Triangles: TTriangles; t: integer);
// Caclulate transform weight from triangle areas
var
@@ -3004,6 +3124,7 @@ begin
end;
//? cp1.NormalizeWeights;
end;
+*)
procedure TControlPoint.NormalizeProbabilities;
// AV: useful for matematicians, useless for other people :)
@@ -3026,61 +3147,58 @@ end;
procedure TControlPoint.CalculateWeights;
// AV: Calculate transform weight from its affine determinants
var
- i: integer;
- deta, detp: double;
+ i: smallint;
+ deta: double;
begin
for i := 0 to NumXForms - 1 do
begin
with xform[i] do
- begin
- deta := c[0][0] * c[1][1] - c[0][1] * c[1][0];
- detp := p[0][0] * p[1][1] - p[0][1] * p[1][0];
- end;
-
- deta := abs(deta * detp);
+ deta := abs(detC * detP);
if (deta < 1E-6) then deta := 1E-6;
- xform[i].Density := deta;
+
+ xform[i].density := deta;
end;
end;
-procedure TControlPoint.CalculateColorSpeed;
+procedure TControlPoint.CalculateColorSpeed; // AV: experimental method
var
- i: integer;
- maxw, sumw, w0, d: double;
+ i, t: smallint;
+ maxw, sumw, w0: double;
eqw: boolean;
begin
- if Transforms = 1 then exit; // single xform
+ t := NumXForms;
+ if t = 1 then exit; // single xform
eqw := True;
w0 := xform[0].density;
- maxw := w0; sumw := 0;
- for i := 0 to Transforms - 1 do
+ maxw := w0; sumw := w0;
+ for i := 1 to t - 1 do
begin
sumw := sumw + xform[i].density;
if (xform[i].density > maxw) then maxw := xform[i].density;
if eqw then if (xform[i].density <> w0) then eqw := False;
end;
-
+
if (not eqw) then
- for i := 0 to Transforms - 1 do
+ for i := 0 to t - 1 do
begin
with xform[i] do
begin
- if (GetVariation(0) = 1) then // if affine
- begin
- d := abs(c[0,0]*c[1,1] - c[0,1]*c[1,0]); // contraction factor
- symmetry := min(d, 1);
- end
+ if (GetVariation(0) = 1) then // if affine - check contraction factor
+ symmetry := min(abs(detC), 1)
else if (density > 0.01) then
symmetry := 0.85 * density / maxw
else
symmetry := -1;
end;
end
- else // equal weights
- for i := 0 to Transforms - 1 do
- xform[i].symmetry := 0;
+ else // equal weights
+ for i := 0 to t - 1 do
+ with xform[i] do
+ symmetry := min(abs(detC * detP), 0.85);
end;
+//*********************************************************************//
+
procedure TControlPoint.GetFromTriangles(const Triangles: TTriangles; const t: integer);
var
i: integer;
diff --git a/Flame/RndFlame.pas b/Flame/RndFlame.pas
index d7a432b..b54fd15 100644
--- a/Flame/RndFlame.pas
+++ b/Flame/RndFlame.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -26,9 +26,13 @@ unit RndFlame;
interface
uses
- ControlPoint, Xform;
+ ControlPoint;
-function RandomFlame(SourceCP: TControlPoint= nil; algorithm: integer = 0): TControlPoint;
+function RandomFlame(SourceCP: TControlPoint = nil; algorithm: integer = 0): TControlPoint;
+
+// AV: made the following public to get rid of duplicated code
+procedure SetVariation(cp: TControlPoint);
+procedure RandomVariation(cp: TControlPoint);
implementation
@@ -75,83 +79,6 @@ begin
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;
@@ -225,7 +152,53 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+{ ****************** Triangle transformations ******************************* }
+
+function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean;
+var
+ ra, rb, rc, a, b, c: double;
+begin
+ Result := True;
+ ra := dist(Triangles[-1].y[0], Triangles[-1].x[0],
+ Triangles[-1].y[1], Triangles[-1].x[1]);
+ rb := dist(Triangles[-1].y[1], Triangles[-1].x[1],
+ Triangles[-1].y[2], Triangles[-1].x[2]);
+ rc := dist(Triangles[-1].y[2], Triangles[-1].x[2],
+ Triangles[-1].y[0], Triangles[-1].x[0]);
+ a := dist(t.y[0], t.x[0], t.y[1], t.x[1]);
+ b := dist(t.y[1], t.x[1], t.y[2], t.x[2]);
+ c := dist(t.y[2], t.x[2], t.y[0], t.x[0]);
+ if (a > ra) then
+ Result := False
+ else if (b > rb) then
+ Result := False
+ else if (c > rc) then
+ Result := False
+ else if ((a = ra) and (b = rb) and (c = rc)) then
+ Result := False;
+end;
+
+function triangle_area(t: TTriangle): double;
+var
+ base, height: double;
+begin
+ try
+ base := dist(t.x[0], t.y[0], t.x[1], t.y[1]);
+ height := line_dist(t.x[2], t.y[2], t.x[1], t.y[1],
+ t.x[0], t.y[0]);
+ if (base < 1.0) then
+ Result := height
+ else if (height < 1.0) then
+ Result := base
+ else
+ Result := 0.5 * base * height;
+ except on E: EMathError do
+ Result := 0;
+ end;
+end;
+
+{ ************************************************************************** }
+
procedure RandomVariation(cp: TControlPoint);
{ Randomise variation parameters }
var
@@ -236,26 +209,23 @@ begin
RandSeed := MainSeed;
VarPossible := false;
- for j := 0 to NRVAR - 1 do begin
- VarPossible := VarPossible or Variations[j];
- end;
+ for j := 0 to NRVAR - 1 do
+ if Variations[j] then begin // AV: make it faster!
+ VarPossible := True;
+ break;
+ end;
+ if not VarPossible then Variations[0] := True; // AV
for i := 0 to cp.NumXForms - 1 do begin
for j := 0 to NRVAR - 1 do
cp.xform[i].SetVariation(j, 0);
- if VarPossible then begin
- repeat
- a := random(NRVAR);
- until Variations[a];
-
- repeat
- b := random(NRVAR);
- until Variations[b];
- end else begin
- a := 0;
- b := 0;
- end;
+ repeat
+ a := random(NRVAR);
+ until Variations[a];
+ repeat
+ b := random(NRVAR);
+ until Variations[b];
if (a = b) then begin
cp.xform[i].SetVariation(a, 1);
@@ -278,7 +248,7 @@ begin
for i := 0 to cp.NumXForms - 1 do begin
for j := 0 to NRVAR - 1 do
cp.xform[i].SetVariation(j, 0);
- cp.xform[i].SetVariation(integer(Variation), 1);
+ cp.xform[i].SetVariation(Variation, 1);
end;
end;
@@ -414,16 +384,17 @@ begin
end;
///////////////////////////////////////////////////////////////////////////////
+(*
procedure RandomWeights(var cp1: TControlPoint);
{ Randomizes xform weights }
var
i: integer;
begin
- for i := 0 to Transforms - 1 do
+ for i := 0 to cp1.NumXForms - 1 do // AV: was Transforms - 1
cp1.xform[i].Density := random;
NormalizeWeights(cp1);
end;
-
+*)
///////////////////////////////////////////////////////////////////////////////
function RandomFlame(SourceCP: TControlPoint; algorithm: integer): TControlPoint;
var
@@ -444,22 +415,25 @@ begin
inc(MainSeed);
RandSeed := MainSeed;
transforms := random(Max - (Min - 1)) + Min;
+
repeat
try
inc(MainSeed);
RandSeed := MainSeed;
- Result.clear;
- Result.RandomCP(transforms, transforms, false);
- Result.SetVariation(Variation);
- inc(MainSeed);
- RandSeed := MainSeed;
+ Result.Clear;
+ for i := 0 to Transforms - 1 do // AV: set starting non-zero weights...
+ Result.xform[i].density := 0.5;
+ // AV: we don't really need to randomize the same flame twice...
+ //Result.RandomCP(transforms, transforms, false);
+ //Result.SetVariation(Variation); // AV: deprecated!
+ SetVariation(Result); // AV: replaced old method from ControlPoint
case algorithm of
1: rnd := 0;
2: rnd := 7;
3: rnd := 9;
else
- if (Variation = vLinear) or (Variation = vRandom) then
+ if (Variation = 0 {vLinear}) or (Variation = vRandom) then
rnd := random(10)
else
rnd := 9;
@@ -479,11 +453,11 @@ begin
Result.xform[i].c[1, 1] := 1;
Result.xform[i].c[2, 0] := 0;
Result.xform[i].c[2, 1] := 0;
- Result.xform[i].color := 0; }
- Result.xform[i].symmetry := 0;
+ Result.xform[i].color := 0;
+ // AV: this will be done with SetVariation method!
Result.xform[i].SetVariation(0, 1);
for j := 1 to NRVAR - 1 do
- Result.xform[i].SetVariation(j, 0);
+ Result.xform[i].SetVariation(j, 0); }
// AV: hundred of useless calculations
{Result.xform[i].Translate(random * 2 - 1, random * 2 - 1);
Result.xform[i].Rotate(random * 360);
@@ -491,6 +465,7 @@ begin
Result.xform[i].Scale(random * 0.8 + 0.2)
else
Result.xform[i].Scale(random * 0.4 + 0.6); }
+ Result.xform[i].symmetry := 0;
if i > 0 then
s := random * 0.8 + 0.2
else
@@ -512,7 +487,8 @@ begin
Result.xform[i].c[2, 0] := random * 2 - 1;
Result.xform[i].c[2, 1] := random * 2 - 1;
if Random(2) = 0 then
- Result.xform[i].Multiply(1, random - 0.5, random - 0.5, 1);
+ Result.xform[i].Multiply(Result.xform[i].c,
+ 1, random - 0.5, random - 0.5, 1);
if Random(2) = 1 then
begin
@@ -529,7 +505,7 @@ begin
Result.xform[i].p[2,1] := random * 2 - 1;
end;
end;
- SetVariation(Result);
+ //SetVariation(Result);
end;
7, 8:
begin
@@ -559,20 +535,31 @@ begin
Result.xform[i].c[2][0] := random * 2 - 1;
Result.xform[i].c[2][1] := random * 2 - 1;
end;
+
+ { // AV: the following was (or will be) done!
for i := 0 to NXFORMS-1 do
Result.xform[i].density := 0;
for i := 0 to Transforms - 1 do
Result.xform[i].density := 1 / Transforms;
SetVariation(Result);
+ }
end;
9: begin
- for i := 0 to NXFORMS-1 do
+ { // AV: the following was (or will be) done!
+ for i := 0 to NXFORMS-1 do
Result.xform[i].density := 0;
for i := 0 to Transforms - 1 do
Result.xform[i].density := 1 / Transforms;
+ }
+ for i := 0 to Transforms - 1 do begin // AV
+ Result.xform[i].RandomizeCoefs(Result.xform[i].c);
+ if Random(4) = 1 then
+ Result.xform[i].RandomizeCoefs(Result.xform[i].p);
+ end;
end;
end; // case
Result.TrianglesFromCp(Triangles);
+
if Random(2) > 0 then
ComputeWeights(Result, Triangles, transforms)
else
@@ -628,8 +615,6 @@ begin
Result.background[2] := 0;
end;
Result.zoom := 0;
- //Result.Nick := SheepNick;
- //Result.URl := SheepURL;
Result.xform[Result.NumXForms].Clear;
Result.xform[Result.NumXForms].symmetry := 1;
diff --git a/Flame/XForm.pas b/Flame/XForm.pas
index 8576909..b13e4dd 100644
--- a/Flame/XForm.pas
+++ b/Flame/XForm.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -31,8 +31,7 @@ unit XForm;
interface
uses
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
AsmRandom,
{$endif}
XFormMan, BaseVariation, Classes;
@@ -60,27 +59,33 @@ type
end;
PXYpoint = ^TXYpoint;
+ {
T2Cpoint = record
x, y, c1, c2: double;
end;
+ P2Cpoint = ^T2Cpoint;
TMatrix = array[0..2, 0..2] of double;
+ }
-{$ifdef Apo7X64}
-{$else}
+// AV: rewrote all asm-code from Apo7X to make it work properly again
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
type
+ TCoefsArray = array[0..2, 0..1] of double; // AV: moved from ControlPoint
+ //pCoefsArray = ^TCoefsArray;
+
TXForm = class
public
- c: array[0..2, 0..1] of double; // the coefs to the affine part of the function
- p: array[0..2, 0..1] of double; // post-transform coefs!
- density: double; // prob is this function is chosen
- color: double; // color coord for this function. 0 - 1
- color2: double; // Second color coord for this function. 0 - 1
- vc: double; // Calculated color to be passed to the plugin
+ c: TCoefsArray; // the coefs to the affine part of the function
+ p: TCoefsArray; // post-transform coefs!
+ density: double; // prob is this function is chosen
+ color: double; // color coord for this function. 0 - 1
+ color2: double; // Second color coord for this function. 0 - 1
+ vc: double; // Calculated color to be passed to the plugin
symmetry: double;
c00, c01, c10, c11, c20, c21: double; // unnecessary duplicated variables
p00, p01, p10, p11, p20, p21: double; // :-)
@@ -104,7 +109,6 @@ type
FTx, FTy: double; // must remain in this order
FPx, FPy: double; // some asm code relies on this
-
FTz, FPz: double; // 3d hack
FAngle: double;
@@ -153,7 +157,7 @@ type
procedure Blur3D; // vars[18]
procedure PreBlur; // vars[19]
- procedure PreZScale; // vars[2]
+ procedure PreZScale; // vars[20]
procedure PreZTranslate; // vars[21]
procedure PreRotateX; // vars[22]
procedure PreRotateY; // vars[23]
@@ -175,8 +179,8 @@ type
procedure Pyramid; // vars[34]
procedure Polar2; // vars[35]
- function Mul33(const M1, M2: TMatrix): TMatrix;
- function Identity: TMatrix;
+ //function Mul33(const M1, M2: TMatrix): TMatrix;
+ //function Identity: TMatrix;
procedure BuildFunctionlist;
procedure AddRegVariations;
@@ -193,12 +197,16 @@ type
procedure NextPoint(var CPpoint: TCPpoint);
procedure NextPointTo(var CPpoint, ToPoint: TCPpoint);
procedure NextPointXY(var px, py: double);
- procedure NextPoint2C(var p: T2CPoint);
+ //procedure NextPoint2C(var p: T2CPoint);
- procedure Rotate(const degrees: double);
- procedure Translate(const x, y: double);
- procedure Multiply(const a, b, c, d: double);
- procedure Scale(const s: double);
+ // AV: extended all following methods for post-coefs support
+ procedure Rotate(var t: TCoefsArray; const degrees: double);
+ procedure Translate(var t: TCoefsArray; const x, y: double);
+ procedure Multiply(var t: TCoefsArray; const k, l, m, n: double);
+ procedure Scale(var t: TCoefsArray; const s: double);
+ procedure RandomizeCoefs(var t: TCoefsArray); // AV: for random flames
+ function detC: double; inline;
+ function detP: double; inline;
procedure GetVariable(const name: string; var Value: double);
procedure SetVariable(const name: string; var Value: double);
@@ -254,7 +262,7 @@ var i: Integer;
begin
AddRegVariations;
BuildFunctionlist;
- SetLength(vars, NRLOCVAR + Length(FRegVariations));
+ SetLength(vars, NrVar); // <-- AV // NRLOCVAR + Length(FRegVariations));
// AV: set default variations order
ifs := TStringList.Create;
for i := 0 to NrVar-1 do ifs.Add(Varnames(i));
@@ -308,6 +316,7 @@ var
CalculateAngle, CalculateSinCos, CalculateLength: boolean;
mode: double;
vn: string;
+ UsedVars: TStringList;
begin
c00 := c[0][0];
c01 := c[0][1];
@@ -347,31 +356,33 @@ begin
// CalculateLength := False;
CalculateSinCos := (vars[8] <> 0.0) or (vars[10] <> 0.0);
+ UsedVars := TStringList.Create;
+
// Pre- variations
- for i := 0 to NrVar - 1 do
+ for vn in ifs do
+ begin
+ v := GetVariationIndex(vn);
+ if (vars[v] <> 0.0) then
begin
- v := GetVariationIndex(ifs[i]);
- if (vars[v] <> 0.0) then
+ UsedVars.Add(vn); // AV: remember all used variations in the right order
+ if (LeftStr(vn, 4) = 'pre_') or (vn = 'flatten') then // AV: flatten became pre_
begin
- vn := ifs[i];
- if (LeftStr(vn, 4) = 'pre_') or (vn = 'flatten') then // AV: flatten became pre_
+ FCalcFunctionList[FNrFunctions] := FFunctionList[v];
+ Inc(FNrFunctions);
+ end
+ // AV: added some universal variations
+ else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
+ or (vn = 'spherecrop') then
+ begin
+ GetVariable(vn + '_mode', mode);
+ if (mode = 0) then
begin
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
- end
- // AV: added some universal variations
- else if (vn = 'affine3D') or (vn = 'trianglecrop')
- or (vn = 'projective') or (vn = 'spherecrop') then
- begin
- GetVariable(vn + '_mode', mode);
- if (mode = 0) then
- begin
- FCalcFunctionList[FNrFunctions] := FFunctionList[v];
- Inc(FNrFunctions);
- end;
end;
end;
end;
+ end;
// Precalc must be called after pre- vars
if CalculateAngle or CalculateSinCos then
@@ -386,53 +397,47 @@ begin
end;
// Normal variations
- for i := 0 to NrVar - 1 do
+ for vn in UsedVars do // AV: iterate through used variations only
begin
- v := GetVariationIndex(ifs[i]);
- if (vars[v] <> 0.0) then
+ if (LeftStr(vn, 4) = 'pre_') or (LeftStr(vn, 5) = 'post_') or (vn = 'flatten')
+ then continue
+ else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
+ or (vn = 'spherecrop') then
begin
- vn := ifs[i];
- if (LeftStr(vn, 4) = 'pre_') or
- (LeftStr(vn, 5) = 'post_') or
- (vn = 'flatten') then continue;
- if (vn = 'affine3D') or (vn = 'trianglecrop')
- or (vn = 'projective') or (vn = 'spherecrop') then
- begin
- GetVariable(vn + '_mode', mode);
- if (mode <> 1) then continue;
- end;
-
- FCalcFunctionList[FNrFunctions] := FFunctionList[v];
- Inc(FNrFunctions);
+ GetVariable(vn + '_mode', mode);
+ if (mode <> 1) then continue;
end;
+
+ v := GetVariationIndex(vn);
+ FCalcFunctionList[FNrFunctions] := FFunctionList[v];
+ Inc(FNrFunctions);
end;
// Post- variations
- for i := 0 to NrVar - 1 do
+ for vn in UsedVars do // AV: iterate through used variations only
begin
- v := GetVariationIndex(ifs[i]);
- if (vars[v] <> 0.0) then
+ if (LeftStr(vn, 5) = 'post_') then
+ begin
+ v := GetVariationIndex(vn);
+ FCalcFunctionList[FNrFunctions] := FFunctionList[v];
+ Inc(FNrFunctions);
+ end
+ // AV: added some universal variations
+ else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
+ or (vn = 'spherecrop') then
+ begin
+ GetVariable(vn + '_mode', mode);
+ if (mode = 2) then
begin
- vn := ifs[i];
- if (LeftStr(vn, 5) = 'post_') then
- begin
- FCalcFunctionList[FNrFunctions] := FFunctionList[v];
- Inc(FNrFunctions);
- end
- // AV: added some universal variations
- else if (vn = 'affine3D') or (vn = 'trianglecrop')
- or (vn = 'projective') or (vn = 'spherecrop') then
- begin
- GetVariable(ifs[i] + '_mode', mode);
- if (mode = 2) then
- begin
- FCalcFunctionList[FNrFunctions] := FFunctionList[v];
- Inc(FNrFunctions);
- end;
- end;
+ v := GetVariationIndex(vn);
+ FCalcFunctionList[FNrFunctions] := FFunctionList[v];
+ Inc(FNrFunctions);
end;
+ end;
end;
+ UsedVars.Free;
+
polar_vpi := vars[6]/pi;
disc_vpi := vars[7]/pi;
polar2_vpi := vars[35]/pi;
@@ -624,7 +629,7 @@ end;
procedure TXForm.Flatten;
begin
// FPz := 0;
- // AV: changed to pre_mode
+ // AV: changed to pre_mode for compatibility with "3D-Hack" flames
FTz := 0;
end;
@@ -1607,10 +1612,11 @@ begin
ToPoint.c := ToPoint.c + pluginColor * (vc - ToPoint.c);
ToPoint.x := FPx;
ToPoint.y := FPy;
- ToPoint.z := FPz; //?
+ ToPoint.z := FPz;
end;
///////////////////////////////////////////////////////////////////////////////
+(*
procedure TXForm.NextPoint2C(var p: T2CPoint);
var
i: Integer;
@@ -1631,7 +1637,7 @@ begin
p.x := FPx;
p.y := FPy;
end;
-
+*)
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.NextPointXY(var px, py: double);
var
@@ -1651,6 +1657,75 @@ begin
py := FPy;
end;
+//************ Math utils ***************************************//
+
+function TXForm.detC;
+begin
+ Result := c[0,0] * c[1,1] - c[0,1] * c[1,0];
+end;
+
+function TXForm.detP;
+begin
+ Result := p[0,0] * p[1,1] - p[0,1] * p[1,0];
+end;
+
+//************ Matrix multiplication ***************************************//
+
+procedure TXForm.Multiply(var t: TCoefsArray; const k, l, m, n: double); // AV
+var
+ ta, tb, tc, td: double;
+begin
+ ta := t[0, 0];
+ tb := -t[1, 0];
+ tc := -t[0, 1];
+ td := t[1, 1];
+
+{
+ [a, b][e ,f] [a*e+b*g, a*f+b*h]
+ [ ][ ] = [ ]
+ [c, d][g, h] [c*e+d*g, c*f+d*h]
+}
+
+ t[0, 0] := ta * k + tc * l;
+ t[0, 1] := -(ta * m + tc * n);
+ t[1, 0] := -(tb * k + td * l);
+ t[1, 1] := tb * m + td * n;
+end;
+
+procedure TXForm.Rotate(var t: TCoefsArray; const degrees: double); // AV
+var
+ v, sv, cv: double;
+begin
+ v := DegToRad(degrees);
+ SinCos(v, sv, cv);
+ Multiply(t, cv, -sv, sv, cv);
+end;
+
+procedure TXForm.Scale(var t: TCoefsArray; const s: double);
+begin
+ t[0, 0] := t[0, 0] * s;
+ t[0, 1] := t[0, 1] * s;
+ t[1, 0] := t[1, 0] * s;
+ t[1, 1] := t[1, 1] * s;
+end;
+
+procedure TXForm.Translate(var t: TCoefsArray; const x, y: double);
+begin
+ t[2,0] := t[2,0] + x;
+ t[2,1] := t[2,1] - y; // AV: notice the sign here
+end;
+
+procedure TXForm.RandomizeCoefs(var t: TCoefsArray); // AV
+begin
+ t[0][0] := 2 * random - 1;
+ t[0][1] := 2 * random - 1;
+ t[1][0] := 2 * random - 1;
+ t[1][1] := 2 * random - 1;
+ t[2][0] := 4 * random - 2;
+ t[2][1] := 4 * random - 2;
+end;
+
+(*
///////////////////////////////////////////////////////////////////////////////
{
@@ -1676,7 +1751,6 @@ begin
result[2, 2] := M1[2][0] * M2[0][2] + M1[2][1] * M2[1][2] + M1[2][2] * M2[2][2]; // AV: fixed indices
end;
-///////////////////////////////////////////////////////////////////////////////
function TXForm.Identity: TMatrix;
var
i, j: integer;
@@ -1690,6 +1764,7 @@ begin
end;
///////////////////////////////////////////////////////////////////////////////
+
procedure TXForm.Rotate(const degrees: double);
var
r: double;
@@ -1718,7 +1793,6 @@ begin
c[2, 1] := Matrix[1][2];
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Translate(const x, y: double);
var
Matrix, M1: TMatrix;
@@ -1743,7 +1817,6 @@ begin
c[2, 1] := Matrix[1][2];
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Multiply(const a, b, c, d: double);
var
Matrix, M1: TMatrix;
@@ -1769,7 +1842,6 @@ begin
Self.c[2, 1] := Matrix[1][2];
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Scale(const s: double);
var
Matrix, M1: TMatrix;
@@ -1792,7 +1864,7 @@ begin
c[2, 0] := Matrix[0][2];
c[2, 1] := Matrix[1][2];
end;
-
+*)
///////////////////////////////////////////////////////////////////////////////
destructor TXForm.Destroy;
var
@@ -1811,7 +1883,9 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.BuildFunctionlist;
begin
- SetLength(FFunctionList, NrVar + Length(FRegVariations));
+ // AV: why NRVAR is used here? maybe NRLOCVAR instead?
+ //SetLength(FFunctionList, NrVar + Length(FRegVariations));
+ SetLength(FFunctionList, NrVar); // <-- AV: reduced the length to actually used
//fixed
FFunctionList[0] := Linear3D;
@@ -1835,7 +1909,7 @@ begin
FFunctionList[18] := Blur3D;
FFunctionList[19] := PreBlur;
- FFunctionList[20] := PreZScale; // AV: index 20 is used by auto_pre_zscale option
+ FFunctionList[20] := PreZScale; // AV: index is used by auto-pre_zscale option
FFunctionList[21] := PreZTranslate;
FFunctionList[22] := PreRotateX;
FFunctionList[23] := PreRotateY;
@@ -1922,11 +1996,11 @@ begin
result := Format(' 0 then result := result + format('symmetry="%g" ', [symmetry]);
- ////// AV: write variation order
+ // AV: write variation order
strvar := '';
- for i := 0 to nrvar - 1 do begin
- if vars[GetVariationIndex(ifs[i])] <> 0 then
- strvar := strvar + ifs[i] + #32;
+ for Name in ifs do begin
+ if vars[GetVariationIndex(Name)] <> 0 then
+ strvar := strvar + Name + #32;
end;
if (strvar <> '') and (pos(#32, strvar) < length(strvar)) then
Result := Result + format('var_order="%s" ', [strvar]);
@@ -1937,9 +2011,8 @@ begin
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
end;
*)
- for i := 0 to nrvar - 1 do // AV: write in correct order
+ for Name in ifs do // AV: write in correct order
begin
- Name := ifs[i];
Value := vars[GetVariationIndex(Name)];
if Value <> 0 then
Result := Result + Name + format('="%g" ', [Value]);
@@ -1993,11 +2066,11 @@ begin
result := Format(' 0 then result := result + format('symmetry="%g" ', [symmetry]);
- ////// AV: write variation order
+ // AV: write variation order
strvar := '';
- for i := 0 to nrvar - 1 do begin
- if vars[GetVariationIndex(ifs[i])] <> 0 then
- strvar := strvar + ifs[i] + #32;
+ for Name in ifs do begin
+ if vars[GetVariationIndex(Name)] <> 0 then
+ strvar := strvar + Name + #32;
end;
if (strvar <> '') and (pos(#32, strvar) < length(strvar)) then
Result := Result + format('var_order="%s" ', [strvar]);
@@ -2008,9 +2081,8 @@ begin
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
end;
*)
- for i := 0 to nrvar - 1 do // AV: write in correct order
+ for Name in ifs do // AV: write in correct order
begin
- Name := ifs[i];
Value := vars[GetVariationIndex(Name)];
if Value <> 0 then
Result := Result + Name + format('="%g" ', [Value]);
diff --git a/Forms/About.dfm b/Forms/About.dfm
index 2b00115..1814af3 100644
--- a/Forms/About.dfm
+++ b/Forms/About.dfm
@@ -5216,11 +5216,11 @@ object AboutForm: TAboutForm
StyleElements = [seClient, seBorder]
end
object Label24: TLabel
- Left = 24
+ Left = 16
Top = 55
- Width = 100
+ Width = 136
Height = 13
- Caption = 'Copyright '#169' 2021'
+ Caption = 'Copyright '#169' 2021- 2022'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
@@ -5236,12 +5236,12 @@ object AboutForm: TAboutForm
Shape = bsBottomLine
end
object lblAuthor: TLabel
- Left = 145
+ Left = 165
Top = 54
Width = 86
Height = 13
Cursor = crHandPoint
- Hint = 'https://www.donationalerts.com/r/fract_alice'
+ Hint = 'https://www.youtube.com/channel/UCX-fyv7NmSg2OaprPvxLTlQ/featured'
Caption = 'Alice V. Koryagina'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
@@ -5341,7 +5341,7 @@ object AboutForm: TAboutForm
Top = 50
Width = 57
Height = 16
- Caption = 'v 1.0.1.0'
+ Caption = 'v 1.0.2.0'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -15
diff --git a/Forms/Adjust.dfm b/Forms/Adjust.dfm
index 5cfa560..a00f1db 100644
--- a/Forms/Adjust.dfm
+++ b/Forms/Adjust.dfm
@@ -170,7 +170,7 @@ object AdjustForm: TAdjustForm
Top = 181
Width = 451
Height = 155
- ActivePage = TabGradient
+ ActivePage = TabCamera
Anchors = [akLeft, akRight, akBottom]
Images = MainForm.Buttons
TabOrder = 1
@@ -365,10 +365,23 @@ object AdjustForm: TAdjustForm
TabOrder = 12
OnClick = btResetZoomClick
end
+ object chkDisplay3DAxes: TCheckBox
+ Left = 128
+ Top = 105
+ Width = 310
+ Height = 17
+ Caption = 'Display 3D axes'
+ TabOrder = 13
+ OnClick = chkDisplay3DAxesClick
+ end
end
object TabRendering: TTabSheet
Caption = 'Rendering'
ImageIndex = 35
+ ExplicitLeft = 0
+ ExplicitTop = 0
+ ExplicitWidth = 0
+ ExplicitHeight = 0
DesignSize = (
443
126)
@@ -406,7 +419,7 @@ object AdjustForm: TAdjustForm
Height = 15
Anchors = [akLeft, akTop, akRight]
LargeChange = 10
- Max = 500
+ Max = 1000
Min = 100
PageSize = 0
Position = 500
@@ -630,6 +643,10 @@ object AdjustForm: TAdjustForm
object TabGradient: TTabSheet
Caption = 'Gradient'
ImageIndex = 11
+ ExplicitLeft = 0
+ ExplicitTop = 0
+ ExplicitWidth = 0
+ ExplicitHeight = 0
DesignSize = (
443
126)
@@ -948,7 +965,7 @@ object AdjustForm: TAdjustForm
Left = 115
Top = 83
Width = 210
- Height = 21
+ Height = 20
BevelInner = bvLowered
BevelOuter = bvRaised
Style = csOwnerDrawFixed
@@ -1128,10 +1145,14 @@ object AdjustForm: TAdjustForm
object TabSize: TTabSheet
Caption = 'Image Size'
ImageIndex = 14
+ ExplicitLeft = 0
+ ExplicitTop = 0
+ ExplicitWidth = 0
+ ExplicitHeight = 0
object gbSize: TGroupBox
Left = 1
Top = 5
- Width = 188
+ Width = 189
Height = 105
Caption = 'Size in pixels'
Font.Charset = DEFAULT_CHARSET
@@ -1142,21 +1163,8 @@ object AdjustForm: TAdjustForm
ParentFont = False
TabOrder = 0
DesignSize = (
- 188
+ 189
105)
- object lblRatio: TLabel
- Left = 5
- Top = 78
- Width = 56
- Height = 13
- Caption = 'Aspect ratio'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'MS Sans Serif'
- Font.Style = []
- ParentFont = False
- end
object pnlWidth: TPanel
Left = 4
Top = 19
@@ -1204,7 +1212,7 @@ object AdjustForm: TAdjustForm
object txtHeight: TComboBox
Left = 91
Top = 45
- Width = 78
+ Width = 79
Height = 21
Anchors = [akLeft, akTop, akRight]
Font.Charset = DEFAULT_CHARSET
@@ -1230,7 +1238,7 @@ object AdjustForm: TAdjustForm
object txtWidth: TComboBox
Left = 91
Top = 19
- Width = 78
+ Width = 79
Height = 21
Anchors = [akLeft, akTop, akRight]
Font.Charset = DEFAULT_CHARSET
@@ -1251,8 +1259,8 @@ object AdjustForm: TAdjustForm
'1280')
end
object cbAspectRatio: TComboBox
- Left = 70
- Top = 75
+ Left = 74
+ Top = 71
Width = 113
Height = 21
Style = csDropDownList
@@ -1276,6 +1284,28 @@ object AdjustForm: TAdjustForm
'16 : 10'
'21 : 9 ')
end
+ object lblRatio: TPanel
+ Left = 4
+ Top = 71
+ Width = 70
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Aspect ratio'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 5
+ OnDblClick = DragPanelDblClick
+ OnMouseDown = DragPanelMouseDown
+ OnMouseMove = DragPanelMouseMove
+ OnMouseUp = DragPanelMouseUp
+ end
end
object gbPresets: TGroupBox
Left = 194
@@ -1507,6 +1537,10 @@ object AdjustForm: TAdjustForm
object TabCurves: TTabSheet
Caption = 'Curves'
ImageIndex = 69
+ ExplicitLeft = 0
+ ExplicitTop = 0
+ ExplicitWidth = 0
+ ExplicitHeight = 0
object CurvesPanel: TPanel
Left = 3
Top = 1
@@ -1938,6 +1972,10 @@ object AdjustForm: TAdjustForm
Caption = 'Save as Map file...'
OnClick = SaveasMapfile1Click
end
+ object SaveAsScript: TMenuItem
+ Caption = 'Save as Script file...'
+ OnClick = SaveAsScriptClick
+ end
object N6: TMenuItem
Caption = '-'
end
diff --git a/Forms/Adjust.pas b/Forms/Adjust.pas
index 7608862..c457b47 100644
--- a/Forms/Adjust.pas
+++ b/Forms/Adjust.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,19 +27,12 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, AppEvnts, CurvesControl,
+ StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, CurvesControl,
ControlPoint, Cmap, RenderingInterface, Translation;
const
WM_UPDATE_PARAMS = WM_APP + 5439;
-const
- PixelCountMax = 32768;
-
-type
- pRGBTripleArray = ^TRGBTripleArray;
- TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
-
type
TAdjustForm = class(TForm)
QualityPopup: TPopupMenu;
@@ -190,7 +183,6 @@ type
N13: TMenuItem;
mnuLuminance: TMenuItem;
cbAspectRatio: TComboBox;
- lblRatio: TLabel;
AdjustColorFragment: TMenuItem;
N14: TMenuItem;
mnuSepia: TMenuItem;
@@ -207,12 +199,13 @@ type
SmoothizeSelected: TMenuItem;
btResetZoom: TButton;
btnMenu: TButton; // AV: changed from TSpeedButton for auto-drawing the arrow
+ SaveAsScript: TMenuItem;
+ lblRatio: TPanel;
+ chkDisplay3DAxes: TCheckBox; // AV
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure DrawPreview;
-// procedure btnOKClick(Sender: TObject);
-// procedure btnCancelClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure mnuLowQualityClick(Sender: TObject);
procedure mnuMediumQualityClick(Sender: TObject);
@@ -231,20 +224,6 @@ type
procedure txtVibrancyExit(Sender: TObject);
procedure scrollCameraScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
-(*
- procedure scrollCenterXScroll(Sender: TObject; ScrollCode: TScrollCode;
- var ScrollPos: Integer);
- procedure scrollCenterYScroll(Sender: TObject; ScrollCode: TScrollCode;
- var ScrollPos: Integer);
- procedure scrollGammaScroll(Sender: TObject; ScrollCode: TScrollCode;
- var ScrollPos: Integer);
- procedure scrollBrightnessScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
- procedure scrollVibrancyScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
- procedure scrollAngleScroll(Sender: TObject; ScrollCode: TScrollCode;
- var ScrollPos: Integer);
-*)
procedure scrollVibrancyScroll(Sender: TObject);
procedure scrollGammaChange(Sender: TObject);
procedure scrollBrightnessChange(Sender: TObject);
@@ -398,6 +377,8 @@ type
procedure txtContrastKeyPress(Sender: TObject; var Key: Char);
procedure SmoothizeSelectedClick(Sender: TObject);
procedure btResetZoomClick(Sender: TObject);
+ procedure SaveAsScriptClick(Sender: TObject);
+ procedure chkDisplay3DAxesClick(Sender: TObject);
private
CurvesControl: TCurvesControl;
Resetting: boolean;
@@ -472,8 +453,8 @@ procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer);
implementation
uses
- RndFlame, Main, cmapdata, Math, Browser, Editor, Global,
- Save, Mutate, ClipBrd, GradientHlpr, Registry, Curves, ColorRangeForm;
+ RndFlame, Main, cmapdata, Math, Browser, Editor, Global, // Curves,
+ Save, Mutate, ClipBrd, GradientHlpr, Registry, ColorRangeForm;
{$R *.DFM}
@@ -494,8 +475,8 @@ begin
tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10);
tbWeightRight.Position := Round(CurvesControl.WeightRight * 10);
- pw := PrevPnl.Width -2;
- ph := PrevPnl.Height -2;
+ pw := PrevPnl.Width - 2;
+ ph := PrevPnl.Height - 2;
if (cp.width / cp.height) > (PrevPnl.Width / PrevPnl.Height) then
begin
PreviewImage.Width := pw;
@@ -572,7 +553,6 @@ begin
if EditForm.Visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
- if CurvesForm.Visible then CurvesForm.SetCp(cp);
if bBgOnly then
MainForm.tbShowAlphaClick(Self)
@@ -585,17 +565,97 @@ var
i: integer;
Row: pRGBTripleArray;
BitMap: TBitMap;
+
+procedure Draw3DAxes; // AV
+const
+ w = 60; // default axis length
+var
+ Origin, EndPoint, Rot: TPoint;
+ sinPitch, cosPitch, sinRoll, cosRoll, sinYaw, cosYaw: double;
+ sinA, cosA: double;
+ DoRotate: boolean;
+begin
+ SinCos(cp.cameraPitch, sinPitch, cosPitch);
+ SinCos(cp.cameraRoll, sinRoll, cosRoll);
+ SinCos(-cp.cameraYaw, sinYaw, cosYaw);
+
+ if cp.FAngle <> 0 then
+ begin
+ SinCos(cp.FAngle, sinA, cosA);
+ DoRotate := True;
+ end
+ else
+ DoRotate := False;
+
+ Origin.X := BM.Width shr 1;
+ Origin.Y := BM.Height shr 1;
+
+ with BM.Canvas do
+ begin
+ Pen.Width := 2;
+ Font.Color := clBlack; // clWhite;
+
+ // X - axis
+ Pen.Color := clRed;
+ Brush.Color := clRed;
+ EndPoint.X := Round(cosRoll * cosYaw * w);
+ EndPoint.Y := Round((sinPitch * sinRoll * cosYaw + cosPitch * sinYaw) * w);
+ if DoRotate then
+ begin
+ Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA);
+ Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA);
+ EndPoint := Rot;
+ end;
+ MoveTo(Origin.X, Origin.Y);
+ LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y);
+ TextOut(PenPos.X - 2, PenPos.Y - 2, 'X');
+
+ // Y - axis
+ Pen.Color := clBlue;
+ Brush.Color := clBlue;
+ EndPoint.X := Round(-cosRoll * sinYaw * w);
+ EndPoint.Y := Round((-sinPitch * sinRoll * sinYaw + cosPitch * cosYaw) * w);
+ if DoRotate then
+ begin
+ Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA);
+ Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA);
+ EndPoint := Rot;
+ end;
+ MoveTo(Origin.X, Origin.Y);
+ LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y);
+ TextOut(PenPos.X - 2, PenPos.Y - 2, 'Y');
+
+ // Z - axis
+ Pen.Color := clGreen;
+ Brush.Color := clGreen;
+ EndPoint.X := Round(sinRoll * w);
+ EndPoint.Y := Round(-sinPitch * cosRoll * w);
+ if DoRotate then
+ begin
+ Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA);
+ Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA);
+ EndPoint := Rot;
+ end;
+ MoveTo(Origin.X, Origin.Y);
+ LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y);
+ TextOut(PenPos.X - 2, PenPos.Y - 2, 'Z');
+ end;
+end;
+
begin
if Resetting then exit;
Render.Stop;
-// AdjustScale(cp, PreviewImage.Width, PreviewImage.Height);
+
cp.sample_density := PreviewDensity;
cp.spatial_oversample := defOversample;
cp.spatial_filter_radius := defFilterRadius;
Render.SetCP(cp);
Render.Render;
BM.Assign(Render.GetImage);
+
+ if chkDisplay3DAxes.Checked then Draw3DAxes; // AV
+
PreviewImage.Picture.Graphic := bm;
if mnuInstantPreview.Checked then PreviewImage.Refresh;
@@ -678,9 +738,9 @@ begin
pnlYPos.Caption := TextByKey('adjustment-tab-camera-ypos');
pnlAngle.Caption := TextByKey('adjustment-tab-camera-rotation');
btResetZoom.Caption := TextByKey('adjustment-tab-camera-resetzoom');
+ chkDisplay3DAxes.Caption := TextByKey('adjustment-tab-camera-draw3daxes');
btResetZoom.Hint := TextByKey('adjustment-hint-resetzoom');
TabRendering.Caption := TextByKey('adjustment-tab-rendering-title');
- //chkTransparent.Caption := TextByKey('adjustment-tab-rendering-istransparent');
TabGradient.Caption := TextByKey('adjustment-tab-gradient-title');
mnuRotate.Caption := TextByKey('adjustment-tab-gradient-moderotate');
mnuHue.Caption := TextByKey('adjustment-tab-gradient-modehue');
@@ -723,6 +783,7 @@ begin
SaveGradient1.Caption := TextByKey('adjustment-popup-gradient-saveasugr');
SaveasMapfile1.Caption := TextByKey('adjustment-popup-gradient-saveasmap');
mnuSaveAsDefault.Caption := TextByKey('adjustment-popup-gradient-saveasdefault');
+ SaveAsScript.Caption := TextByKey('adjustment-popup-gradient-saveasscript');
btnMenu.Caption := TextByKey('adjustment-tab-gradient-moderotate');
Red1.Caption := TextByKey('adjustment-tab-curves-red');
Green1.Caption := TextByKey('adjustment-tab-curves-green');
@@ -806,6 +867,7 @@ begin
Registry.WriteInteger('Left', AdjustForm.Left);
Registry.WriteBool('InstantPreview', mnuInstantPreview.Checked);
Registry.WriteBool('ResizeMain', chkResizeMain.Checked);
+ Registry.WriteBool('Display3DAxes', chkDisplay3DAxes.Checked); // AV
end;
finally
Registry.Free;
@@ -841,12 +903,14 @@ begin
mnuInstantPreview.Checked := Registry.ReadBool('InstantPreview');
if Registry.ValueExists('ResizeMain') then
chkResizeMain.Checked := Registry.ReadBool('ResizeMain');
+ if Registry.ValueExists('Display3DAxes') then // AV
+ chkDisplay3DAxes.Checked := Registry.ReadBool('Display3DAxes');
Registry.CloseKey;
end;
if Registry.OpenKey('Software\' + APP_NAME + '\ImageSizePresets', False) then
begin
- for i:=1 to 3 do begin
+ for i := 1 to 3 do begin
strx:='Preset' + IntToStr(i) + 'Left';
stry:='Preset' + IntToStr(i) + 'Top';
strw:='Preset' + IntToStr(i) + 'Width';
@@ -861,9 +925,7 @@ begin
end;
Preset[i].Left := MainForm.Left;
Preset[i].Top := MainForm.Top;
- // Preset[i].Width := 512;
- // Preset[i].Height := 384;
- // AV: them different by default
+ // AV: make them different by default
case i of
1: begin
Preset[1].Width := 512;
@@ -881,7 +943,7 @@ begin
end;
end
else begin
- for i:=1 to 3 do begin
+ for i := 1 to 3 do begin
Preset[i].Left := MainForm.Left;
Preset[i].Top := MainForm.Top;
end;
@@ -943,6 +1005,11 @@ begin
DrawPreview;
end;
+procedure TAdjustForm.chkDisplay3DAxesClick(Sender: TObject); // AV
+begin
+ DrawPreview; // show or hide coordinate axes
+end;
+
procedure TAdjustForm.txtZoomEnter(Sender: TObject);
begin
EditBoxValue := txtZoom.Text;
@@ -1183,38 +1250,6 @@ begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
-(*
-procedure TAdjustForm.scrollCenterXScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
-begin
- if ScrollCode = scEndScroll then UpdateFlame;
-end;
-
-procedure TAdjustForm.scrollCenterYScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
-begin
- if ScrollCode = scEndScroll then UpdateFlame;
-end;
-
-procedure TAdjustForm.scrollGammaScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
-begin
- if ScrollCode = scEndScroll then UpdateFlame;
-end;
-
-procedure TAdjustForm.scrollBrightnessScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
-begin
- if ScrollCode = scEndScroll then UpdateFlame;
-end;
-
-procedure TAdjustForm.scrollVibrancyScroll(Sender: TObject;
- ScrollCode: TScrollCode; var ScrollPos: Integer);
-begin
- if ScrollCode = scEndScroll then UpdateFlame;
-end;
- *)
-
procedure TAdjustForm.scrollVibrancyScroll(Sender: TObject);
begin
cp.Vibrancy := ScrollVibrancy.Position / 100;
@@ -1381,7 +1416,6 @@ begin
if EditForm.visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
- if CurvesForm.Visible then CurvesForm.SetCp(MainCp);
if mnuInstantPreview.Checked then DrawPreview;
@@ -1413,7 +1447,8 @@ begin
end;
CloseFile(MapFile);
except
- on EInOutError do Application.MessageBox(PChar(Format(TextByKey('common-genericopenerror'), [FileName])), 'Apophysis', 16);
+ on EInOutError do
+ raise Exception.CreateFmt(TextByKey('common-genericopenerror'), [FileName]); // AV
end;
end;
@@ -2048,6 +2083,42 @@ begin
SaveMap(SaveDialog.Filename);
end;
+procedure TAdjustForm.SaveAsScriptClick(Sender: TObject);
+var
+ gradstr: TStringList;
+ fn, s: string;
+ i: word;
+begin
+ SaveDialog.InitialDir := AppPath + 'Scripts';
+ SaveDialog.FileName := 'Palette_' + IntToStr(cmbPalette.ItemIndex) + '.asc';
+ SaveDialog.DefaultExt := 'asc';
+ SaveDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*',
+ [TextByKey('common-filter-scriptfiles'),
+ TextByKey('common-filter-allfiles')]);
+ if SaveDialog.Execute then
+ begin
+ fn := SaveDialog.FileName;
+ gradstr := TStringList.Create;
+ try
+ gradstr.Add('procedure SetCustomPalette;');
+ gradstr.Add('begin');
+ gradstr.Add(' with Flame do begin');
+ for i := 0 to 255 do
+ gradstr.Add(Format(' Gradient[%d,0] := %d; Gradient[%0:d,1] := %2:d; Gradient[%0:d,2] := %3:d;',
+ [i, Palette[i][0], palette[i][1], palette[i][2]]));
+ gradstr.Add(' end;');
+ gradstr.Add('end;');
+ s := ExtractFileName(fn);
+ for i := 1 to Length(s) do
+ if CharInSet(s[i], [#32, '-', '(', ')']) then s[i] := '_';
+ gradstr.SaveToFile(ExtractFilePath(fn) + s);
+ MainForm.GetScripts;
+ finally
+ gradstr.Free;
+ end;
+ end;
+end;
+
procedure TAdjustForm.cmbPaletteDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
@@ -2190,7 +2261,7 @@ begin
end;
procedure TAdjustForm.mnuSepiaClick(Sender: TObject);
-var i, sep: integer;
+var i, sep: smallint;
begin
for i := 0 to 255 do
begin
@@ -2205,7 +2276,7 @@ end;
procedure TAdjustForm.mnuSetColorClick(Sender: TObject);
var
- i: integer;
+ i: smallint;
col: Longint;
begin
ColorDialog.Color := RGB(Palette[selA,0], Palette[selA,1], Palette[selA,2]);
@@ -2278,8 +2349,8 @@ procedure TAdjustForm.GradImageMouseMove(Sender: TObject;
begin
j := j0 + round((i - i0) * k);
-assert(j >= 0);
-assert(j < 256);
+ assert(j >= 0);
+ assert(j < 256);
cp.cmap[i] := Palette[j];
BackupPal[i] := tmpBackupPal[j]; //?
@@ -2292,8 +2363,8 @@ assert(j < 256);
j := j0 + trunc(f);
f := frac(f);
-assert(j >= 0);
-assert(j < 256);
+ assert(j >= 0);
+ assert(j < 256);
if j < 255 then jj := j + 1
else jj := 0;
@@ -2344,8 +2415,8 @@ begin
if (selB < 0) then selB := 0
else if (selB > 255) then selB := 255;
if (selB - selA > 1) then begin
- //btnSelected.Visible := True;
- AdjustSelected.Checked := True;
+ //btnSelected.Visible := True;
+ AdjustSelected.Checked := True;
end;
GradStatusBar.Panels[2].Text := TextByKey('adjustment-tab-gradient-start') + space + IntToStr(selA);
GradStatusBar.Panels[4].Text := TextByKey('adjustment-tab-gradient-last') + space + IntToStr(selB);
@@ -2417,7 +2488,7 @@ begin
end;
end;
-// AV: operations with selected color fragments
+//*************** AV: operations with selected color fragments **********//
procedure TAdjustForm.InvertColorsClick(Sender: TObject);
var
@@ -2460,19 +2531,20 @@ begin
end;
procedure TAdjustForm.Pastefragment1Click(Sender: TObject);
-var i, j, l: integer;
+var i, j, l: smallint;
begin
l := High(tmpColors);
l := Min(selA + l, selB);
for i := selA to l do
- for j := 0 to 2 do Palette[i][j] := tmpColors[i - selA][j];
+ for j := 0 to 2 do
+ Palette[i][j] := tmpColors[i - selA][j];
UpdateGradient(palette);
Apply;
end;
procedure TAdjustForm.ReverseFragmentClick(Sender: TObject);
var
- i, j: integer;
+ i, j: byte;
pal: array of array of byte;
begin
SetLength(pal, selB - selA + 1, 3);
@@ -2490,11 +2562,11 @@ end;
function TAdjustForm.PresetToStr(n: integer): string;
begin
- Result:=IntToStr(Preset[n].Width) + ' x ' + IntToStr(Preset[n].Height)
+ Result := IntToStr(Preset[n].Width) + ' x ' + IntToStr(Preset[n].Height)
end;
procedure TAdjustForm.RandomizeSelectedClick(Sender: TObject);
-var i, j: integer;
+var i, j: byte;
tempPal: TColorMap;
begin
tempPal := GradientHelper.RandomGradient;
@@ -2513,8 +2585,8 @@ begin
txtHeight.Text := IntToStr(ImageHeight);
if chkResizeMain.Checked then begin
- MainForm.Left:=Preset[n].Left;
- MainForm.Top:=Preset[n].Top;
+ MainForm.Left := Preset[n].Left;
+ MainForm.Top := Preset[n].Top;
end;
SetMainWindowSize;
@@ -2542,7 +2614,6 @@ begin
if EditForm.Visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
- if CurvesForm.Visible then CurvesForm.SetCp(cp);
MainForm.RedrawTimer.enabled := true;
{ if ScrollCode = scEndScroll then
@@ -2595,7 +2666,7 @@ begin
if (s[1] = '-') then
start := 2;
- for i:=start to length(s) do
+ for i := start to length(s) do
if not (CharInSet(s[i],['0'..'9'])) then
begin
Result := False;
@@ -2639,10 +2710,12 @@ begin
end;
end;
-//procedure TAdjustForm.chkMaintainClick(Sender: TObject);
-//begin
-// Ratio := ImageWidth / ImageHeight;
-//end;
+{
+procedure TAdjustForm.chkMaintainClick(Sender: TObject);
+begin
+ Ratio := ImageWidth / ImageHeight;
+end;
+}
procedure TAdjustForm.SetMainWindowSize;
var
diff --git a/Forms/Animate.dfm b/Forms/Animate.dfm
new file mode 100644
index 0000000..de8da0d
--- /dev/null
+++ b/Forms/Animate.dfm
@@ -0,0 +1,981 @@
+object AnimateForm: TAnimateForm
+ Left = 0
+ Top = 0
+ BorderStyle = bsSingle
+ Caption = 'Animate Flame'
+ ClientHeight = 476
+ ClientWidth = 496
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Icon.Data = {
+ 0000010001001010000000000000680400001600000028000000100000002000
+ 000001002000000000000004000000000000000000000000000000000000FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00113D55F7285F87FB4988BDFB428DBCC12D77
+ B322FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF002E2E
+ 2ED8292929FA242424CCFFFFFF002B6583FB94C7F9FF91C9F9FF4185C9FF1C64
+ AAF310202DE0050505FF020202DCFFFFFF00FFFFFF00FFFFFF00FFFFFF003434
+ 34FA2F2F2F61353535FF575757FF4389AAFFE0F2FFFF549AD8FF1A7ABEFF4998
+ C5FF3177B0FF1B3C5A6D050505EFFFFFFF00FFFFFF00FFFFFF00FFFFFF003A3A
+ 3AFF353535C6303030F56EDF9DFE54B2A0FE7AB6D5FF90B7D1FF55C9E4FF5BDF
+ F5FF78D0EDFF3E8DCFF70F1B25FFFFFFFF00FFFFFF00FFFFFF00FFFFFF004040
+ 40D03B3B3B6C363636D54FCB5CFF57D77AFF35B883FF73B8D3FFC2F6FDFF63DF
+ F7FF5DE2F8FF79D3F0FF4291D5FD388CD820FFFFFF00FFFFFF00FFFFFF004545
+ 45DF404040C33B3B3BD04FC445FF4BBA2CFFD8BD60FFB1A87FFF77CBE7FFC7F7
+ FDFF5EDCF5FF5AE1F7FF7BD4F1FF4295DCF2368CD934FFFFFF00FFFFFF004B4B
+ 4BDA464646A2414141CF7FBF36FFDDC569FFFFC270FFFFBF67FF86C3BAFF79D3
+ EEFFC7F7FDFF5FDCF5FF5BE2F7FF7AD6F2FF4099DFE8448DCD30FFFFFF005151
+ 51D44C4C4C81474747CCF8C66EFFFFC877FFFFC572FFFFC46CFF98D8CFFF78D7
+ E9FF7BD3ECFFC4F6FDFF6CDDF6FF6DCAEDFF63A3D7FF5D9BD2EC5192CA265656
+ 56E2515151D0686868FF575757FF575757FF575757FF575757FF575757FF5757
+ 57FF275969F97CD2EAFEB2E3F9FF8BC0E7FFAED3F6FFC4E0FCFF669FD3F75B5B
+ 5BD457575781525252CD72E29EFF7CE3A4FF78E3A0FF63E095FF5AE195FF55E2
+ 93FF303030D026748BAD77BEE7FFB4D2F0FFE5F3FFFFACD2EFFF488CC7E86060
+ 60DA5C5C5CA2575757CF4FCB5CFF57D77AFF42D16AFF70C75EFFB6B850FFCBAE
+ 3FFF363636D0313131A22E5C6CE658A5D8FF85B1DBFF469DD0FF2B95D15E6464
+ 64DF606060C35C5C5CD04FC445FF4BBA2CFFD8BD60FFFFBA62FFFFB965FFDBBB
+ 7DFF3B3B3BD2363636C3313131DFFFFFFF00FFFFFF00FFFFFF00FFFFFF006868
+ 68D165656584616161D47FBF36FFDDC569FFFFC270FFFFBF67FFAECBACFF68E0
+ F9FF414141D63C3C3C6C373737D0FFFFFF00FFFFFF00FFFFFF00FFFFFF006C6C
+ 6CFF696969ED656565FAE5BA6CF6ECBC74F6EBB86EF6EBB668F680CBCDF680D7
+ EAF6474747FA424242CC3D3D3DFFFFFFFF00FFFFFF00FFFFFF00FFFFFF006F6F
+ 6FF86C6C6C9B696969FF575757FF575757FF575757FF575757FF575757FF5757
+ 57FF4D4D4DFF4848488D434343D5FFFFFF00FFFFFF00FFFFFF00FFFFFF007171
+ 71D46F6F6FF36D6D6DDDFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00525252D64D4D4DF9494949D7FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0FF
+ 0000100F0000402F0000000F0000400F00000007000000030000000100000000
+ 00000000000000010000000F0000002F0000000F0000000F00001F8F0000}
+ OldCreateOrder = False
+ OnClose = FormClose
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ OnShow = FormShow
+ DesignSize = (
+ 496
+ 476)
+ PixelsPerInch = 96
+ TextHeight = 13
+ object btSaveAnimation: TButton
+ Left = 304
+ Top = 427
+ Width = 75
+ Height = 25
+ Anchors = [akRight, akBottom]
+ Caption = 'Save'
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 0
+ OnClick = btSaveAnimationClick
+ end
+ object AnimPages: TPageControl
+ Left = 8
+ Top = 8
+ Width = 480
+ Height = 412
+ ActivePage = tsSettings
+ Anchors = [akLeft, akTop, akRight, akBottom]
+ TabOrder = 1
+ object tsSettings: TTabSheet
+ Caption = 'General'
+ object gbOutput: TGroupBox
+ Left = 5
+ Top = 5
+ Width = 450
+ Height = 125
+ Caption = ' Output settings '
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 0
+ object btSetFlame: TSpeedButton
+ Left = 420
+ Top = 24
+ 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
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F
+ 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13
+ 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708
+ 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3
+ 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367
+ 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51
+ C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF
+ 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC
+ EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67
+ D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2
+ 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8
+ FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788
+ A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6
+ A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788
+ 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89
+ 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA
+ ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ OnClick = btSetFlameClick
+ end
+ object lbSeconds: TLabel
+ Left = 390
+ Top = 56
+ Width = 39
+ Height = 13
+ Caption = 'seconds'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ end
+ object pnlFPS: TPanel
+ Left = 8
+ Top = 52
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Frames per second'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ end
+ object pnlDuration: TPanel
+ Left = 200
+ Top = 52
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Duration'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ end
+ object seDuration: TSpinEdit
+ Left = 321
+ Top = 52
+ Width = 65
+ Height = 22
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ MaxValue = 100
+ MinValue = 1
+ ParentFont = False
+ TabOrder = 2
+ Value = 1
+ end
+ object seFPS: TSpinEdit
+ Left = 129
+ Top = 52
+ Width = 65
+ Height = 22
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ MaxValue = 200
+ MinValue = 2
+ ParentFont = False
+ TabOrder = 3
+ Value = 25
+ end
+ object pnlOutFlame: TPanel
+ Left = 8
+ Top = 24
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Output flame file'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 4
+ end
+ object edOutFlame: TEdit
+ Left = 127
+ Top = 24
+ Width = 290
+ Height = 21
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 5
+ end
+ object chkListFlames: TCheckBox
+ Left = 8
+ Top = 80
+ Width = 378
+ Height = 17
+ Caption = 'Show generated flames'
+ Checked = True
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ State = cbChecked
+ TabOrder = 6
+ end
+ object chkRender: TCheckBox
+ Left = 8
+ Top = 100
+ Width = 378
+ Height = 17
+ Caption = 'Render all frames'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 7
+ OnClick = chkRenderClick
+ end
+ end
+ object gbFrame: TGroupBox
+ Left = 5
+ Top = 142
+ Width = 450
+ Height = 221
+ Caption = 'Frame'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 1
+ object pnlFrameWidth: TPanel
+ Left = 8
+ Top = 24
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Width'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ end
+ object pnlFrameHeight: TPanel
+ Left = 200
+ Top = 24
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Height'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ end
+ object seFrameHeight: TSpinEdit
+ Left = 321
+ Top = 24
+ Width = 65
+ Height = 22
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ MaxValue = 10000
+ MinValue = 1
+ ParentFont = False
+ TabOrder = 2
+ Value = 600
+ OnChange = seFrameHeightChange
+ end
+ object seFrameWidth: TSpinEdit
+ Left = 129
+ Top = 24
+ Width = 65
+ Height = 22
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ MaxValue = 10000
+ MinValue = 1
+ ParentFont = False
+ TabOrder = 3
+ Value = 800
+ OnChange = seFrameWidthChange
+ end
+ object cbAspectRatio: TComboBox
+ Left = 129
+ Top = 52
+ Width = 160
+ Height = 21
+ Style = csDropDownList
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ItemIndex = 1
+ ParentFont = False
+ TabOrder = 4
+ Text = 'Maintain aspect ratio'
+ OnChange = cbAspectRatioChange
+ Items.Strings = (
+ 'Custom'
+ 'Maintain aspect ratio'
+ '3 : 2 (Classic Film)'
+ '4 : 3 (Standart Monitor)'
+ '5 : 4 '
+ '16 : 9 (HD Video)'
+ '16 : 10'
+ '21 : 9 (CinemaScope)')
+ end
+ object pnlRatio: TPanel
+ Left = 8
+ Top = 52
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Aspect ratio'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 5
+ end
+ object pnlPrefix: TPanel
+ Left = 8
+ Top = 80
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Frame prefix'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 6
+ end
+ object edPrefix: TEdit
+ Left = 129
+ Top = 80
+ Width = 65
+ Height = 21
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 7
+ Text = 'anim-'
+ end
+ object pnlFrameExt: TPanel
+ Left = 200
+ Top = 80
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Graphic extension'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 8
+ end
+ object cbFrameExt: TComboBox
+ Left = 321
+ Top = 80
+ Width = 65
+ Height = 21
+ Style = csDropDownList
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ItemIndex = 1
+ ParentFont = False
+ TabOrder = 9
+ Text = '.png'
+ OnChange = cbAspectRatioChange
+ Items.Strings = (
+ '.bmp'
+ '.png'
+ '.jpg')
+ end
+ object gbFrameQuality: TGroupBox
+ Left = 8
+ Top = 112
+ Width = 200
+ Height = 97
+ Caption = 'Quality settings'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 10
+ object pnlDensity: TPanel
+ Left = 8
+ Top = 20
+ Width = 121
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Density'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 2
+ end
+ object pnlFilter: TPanel
+ Left = 8
+ Top = 44
+ Width = 121
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Filter radius'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 3
+ end
+ object pnlOversample: TPanel
+ Left = 8
+ Top = 68
+ Width = 121
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Oversample'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 4
+ end
+ object txtDensity: TComboBox
+ Left = 128
+ Top = 20
+ Width = 65
+ Height = 21
+ AutoComplete = False
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ Text = '200'
+ Items.Strings = (
+ '200'
+ '500'
+ '1000'
+ '2000'
+ '4000')
+ end
+ object txtFilterRadius: TEdit
+ Left = 128
+ Top = 44
+ Width = 65
+ Height = 21
+ BiDiMode = bdLeftToRight
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentBiDiMode = False
+ ParentFont = False
+ TabOrder = 1
+ Text = '0.1'
+ end
+ object sbFilterRadius: TSpinButton
+ Left = 175
+ Top = 45
+ Width = 15
+ Height = 17
+ DownGlyph.Data = {
+ 0E010000424D0E01000000000000360000002800000009000000060000000100
+ 200000000000D800000000000000000000000000000000000000008080000080
+ 8000008080000080800000808000008080000080800000808000008080000080
+ 8000008080000080800000808000000000000080800000808000008080000080
+ 8000008080000080800000808000000000000000000000000000008080000080
+ 8000008080000080800000808000000000000000000000000000000000000000
+ 0000008080000080800000808000000000000000000000000000000000000000
+ 0000000000000000000000808000008080000080800000808000008080000080
+ 800000808000008080000080800000808000}
+ FocusControl = txtFilterRadius
+ TabOrder = 5
+ UpGlyph.Data = {
+ 0E010000424D0E01000000000000360000002800000009000000060000000100
+ 200000000000D800000000000000000000000000000000000000008080000080
+ 8000008080000080800000808000008080000080800000808000008080000080
+ 8000000000000000000000000000000000000000000000000000000000000080
+ 8000008080000080800000000000000000000000000000000000000000000080
+ 8000008080000080800000808000008080000000000000000000000000000080
+ 8000008080000080800000808000008080000080800000808000000000000080
+ 8000008080000080800000808000008080000080800000808000008080000080
+ 800000808000008080000080800000808000}
+ OnDownClick = sbFilterRadiusDownClick
+ OnUpClick = sbFilterRadiusUpClick
+ end
+ object seOversample: TSpinEdit
+ Left = 128
+ Top = 68
+ Width = 65
+ Height = 22
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ MaxValue = 4
+ MinValue = 1
+ ParentFont = False
+ ReadOnly = True
+ TabOrder = 6
+ Value = 2
+ end
+ end
+ end
+ end
+ object tsAnimation: TTabSheet
+ Caption = 'Animation'
+ ImageIndex = 1
+ ExplicitLeft = 0
+ ExplicitTop = 0
+ ExplicitWidth = 0
+ ExplicitHeight = 380
+ object gbAnimType: TGroupBox
+ Left = 3
+ Top = 4
+ Width = 450
+ Height = 155
+ Caption = ' Animation parameters'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 0
+ object cbAnimType: TComboBox
+ Left = 129
+ Top = 24
+ Width = 310
+ Height = 21
+ Style = csDropDownList
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ItemIndex = 0
+ ParentFont = False
+ TabOrder = 0
+ Text = 'Rotate flame'
+ OnChange = cbAnimTypeChange
+ Items.Strings = (
+ 'Rotate flame'
+ 'Rotate reference triangle'
+ 'Rotate 3D camera'
+ 'Rotate color gradient'
+ 'Change gradient hue'
+ 'Morphing (cosine, RGB)'
+ 'Morphing (cosine, HSV)'
+ 'Morphing (linear, RGB)'
+ 'Morphing (linear, HSV)')
+ end
+ object pnlAnimType: TPanel
+ Left = 8
+ Top = 24
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Animation type'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ end
+ object pnlStartFlame: TPanel
+ Left = 8
+ Top = 52
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Initial flame'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 2
+ end
+ object cbFlames: TComboBox
+ Left = 129
+ Top = 52
+ Width = 310
+ Height = 21
+ Style = csDropDownList
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ItemIndex = 0
+ ParentFont = False
+ TabOrder = 3
+ Text = 'Current'
+ OnChange = cbFlamesChange
+ Items.Strings = (
+ 'Current')
+ end
+ object pnlEndFlame: TPanel
+ Left = 8
+ Top = 80
+ Width = 121
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Final flame'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 4
+ end
+ object cbFlamesTo: TComboBox
+ Left = 129
+ Top = 80
+ Width = 310
+ Height = 21
+ Style = csDropDownList
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ItemIndex = 0
+ ParentFont = False
+ TabOrder = 5
+ Text = 'Current'
+ OnChange = cbFlamesChange
+ Items.Strings = (
+ 'Current')
+ end
+ object chkResetLocation: TCheckBox
+ Left = 8
+ Top = 110
+ Width = 378
+ Height = 17
+ Caption = 'Reset location for each frame'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 6
+ end
+ object chkInvertBG: TCheckBox
+ Left = 8
+ Top = 130
+ Width = 378
+ Height = 17
+ Caption = 'Invert background color'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 7
+ end
+ end
+ object gbPreview: TGroupBox
+ Left = 5
+ Top = 160
+ Width = 450
+ Height = 220
+ Caption = 'Preview'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 1
+ object tbPlay: TSpeedButton
+ Left = 50
+ Top = 189
+ Width = 75
+ Height = 22
+ Hint = 'Play'
+ Caption = 'Play'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Glyph.Data = {
+ 36060000424D3606000000000000360000002800000020000000100000000100
+ 18000000000000060000120B0000120B00000000000000000000FF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFDEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFDEEAE0FF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF096314DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9FF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF11681B04600FDEEAE0FF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9DE
+ EAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF1A6F2420732C04600FDEEAE0FF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF23752E2F833D20732C04600FDEEAE0FF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9D6EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF2E7C3750A25A2F833D20732C04600FDEEAE0FF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9D6EDD9D6EDD9DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF3883415DB06850A25A2F833D20732C0B6618DEEAE0FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9D6EDD9D6EDD9D6EDD9DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF438A4C6BBF766BBF7650A25A2F7639D6EDD9FF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9D6EDD9D6EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF4B90536BBF76A3DAB02F7639D6EDD9FF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9D6EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF52945AA3DAB02F7639D6EDD9FF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF5898602F7639D6EDD9FF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
+ EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FF589860D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9FF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFD6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9FF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
+ NumGlyphs = 2
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ OnClick = tbPlayClick
+ end
+ object tbStop: TSpeedButton
+ Left = 140
+ Top = 189
+ Width = 75
+ Height = 22
+ Hint = 'Stop'
+ Caption = 'Stop'
+ Enabled = False
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Glyph.Data = {
+ 36060000424D3606000000000000360000002800000020000000100000000100
+ 18000000000000060000120B0000120B00000000000000000000FF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFE39A75B66239B05C33A7532A9D4820923E1689340D822D06812C05FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFE39770F3BCA0D7A183CE8D6DC17C59AF6B48A762409B5837812C05FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFE79B74F9C9AFF5B594EDA37EE6956CDA8559CE794EAC6543853009FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFEA9E78F9D0BBF8BDA1F4B090EF9F79E69268DC8459B46B488B360FFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFEFA37DFBD7C8F8C7ADF7B798F2AB88ED9F7AE6946DBE7755923E16FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFF3A881FBE1D3F9CEBAF8BFA5F3B394F2A885EB9F7AD08D6C9A461EFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFF6AD86FBE5DAFBDACAF9CAB3F8C2A8F6B698F3B391DCA387A24E25FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFAB08AFCE1D5FBE2D4FAD8C6F9CDB9F9CAB3F9C6ACF5BB9DAA552DFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFDB38DFAB08AF6AD86F3A881EFA37DEA9E78E79B74E39770E39A75FF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
+ C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
+ NumGlyphs = 2
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ OnClick = tbStopClick
+ end
+ object pnlPreview: TPanel
+ Left = 16
+ Top = 24
+ Width = 240
+ Height = 160
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ object AnimPreview: TImage
+ Left = 0
+ Top = 0
+ Width = 240
+ Height = 160
+ PopupMenu = QualityPopup
+ end
+ end
+ end
+ end
+ end
+ object AnimStatus: TStatusBar
+ Left = 0
+ Top = 457
+ Width = 496
+ Height = 19
+ Panels = <>
+ SimplePanel = True
+ end
+ object btClose: TButton
+ Left = 399
+ Top = 427
+ Width = 75
+ Height = 25
+ Anchors = [akRight, akBottom]
+ Caption = 'Close'
+ TabOrder = 3
+ OnClick = btCloseClick
+ end
+ object QualityPopup: TPopupMenu
+ Images = MainForm.Buttons
+ Left = 24
+ Top = 416
+ object mnuLowQuality: TMenuItem
+ Caption = 'Low Quality'
+ RadioItem = True
+ OnClick = mnuPreviewQualityClick
+ end
+ object mnuMediumQuality: TMenuItem
+ Tag = 1
+ Caption = 'Medium Quality'
+ Checked = True
+ RadioItem = True
+ OnClick = mnuPreviewQualityClick
+ end
+ object mnuHighQuality: TMenuItem
+ Tag = 2
+ Caption = 'High Quality'
+ RadioItem = True
+ OnClick = mnuPreviewQualityClick
+ end
+ end
+end
diff --git a/Forms/Animate.pas b/Forms/Animate.pas
new file mode 100644
index 0000000..70f3ef1
--- /dev/null
+++ b/Forms/Animate.pas
@@ -0,0 +1,831 @@
+{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
+
+unit Animate;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, StdCtrls, ComCtrls, ExtCtrls,
+ Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Samples.Spin, Vcl.Buttons,
+ Menus, ControlPoint, RenderingInterface, Translation;
+
+type
+ TAnimateForm = class(TForm)
+ seFPS: TSpinEdit;
+ seDuration: TSpinEdit;
+ edOutFlame: TEdit;
+ btSetFlame: TSpeedButton;
+ gbOutput: TGroupBox;
+ pnlFPS: TPanel;
+ pnlDuration: TPanel;
+ pnlOutFlame: TPanel;
+ btSaveAnimation: TButton;
+ pnlFrameWidth: TPanel;
+ pnlFrameHeight: TPanel;
+ seFrameWidth: TSpinEdit;
+ seFrameHeight: TSpinEdit;
+ pnlPrefix: TPanel;
+ edPrefix: TEdit;
+ cbAspectRatio: TComboBox;
+ pnlRatio: TPanel;
+ AnimPages: TPageControl;
+ tsSettings: TTabSheet;
+ chkListFlames: TCheckBox;
+ AnimStatus: TStatusBar;
+ gbFrame: TGroupBox;
+ tsAnimation: TTabSheet;
+ gbAnimType: TGroupBox;
+ cbAnimType: TComboBox;
+ pnlAnimType: TPanel;
+ pnlStartFlame: TPanel;
+ cbFlames: TComboBox;
+ pnlEndFlame: TPanel;
+ cbFlamesTo: TComboBox;
+ gbPreview: TGroupBox;
+ AnimPreview: TImage;
+ btClose: TButton;
+ chkResetLocation: TCheckBox;
+ chkRender: TCheckBox;
+ QualityPopup: TPopupMenu;
+ mnuLowQuality: TMenuItem;
+ mnuMediumQuality: TMenuItem;
+ mnuHighQuality: TMenuItem;
+ pnlFrameExt: TPanel;
+ cbFrameExt: TComboBox;
+ gbFrameQuality: TGroupBox;
+ pnlDensity: TPanel;
+ pnlFilter: TPanel;
+ pnlOversample: TPanel;
+ txtDensity: TComboBox;
+ txtFilterRadius: TEdit;
+ sbFilterRadius: TSpinButton;
+ seOversample: TSpinEdit;
+ lbSeconds: TLabel;
+ pnlPreview: TPanel;
+ tbPlay: TSpeedButton;
+ tbStop: TSpeedButton;
+ chkInvertBG: TCheckBox;
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure btSaveAnimationClick(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure btSetFlameClick(Sender: TObject);
+ procedure cbAspectRatioChange(Sender: TObject);
+ procedure seFrameWidthChange(Sender: TObject);
+ procedure seFrameHeightChange(Sender: TObject);
+ procedure cbFlamesChange(Sender: TObject);
+ procedure cbAnimTypeChange(Sender: TObject);
+ procedure tbPlayClick(Sender: TObject);
+ procedure btCloseClick(Sender: TObject);
+ procedure mnuPreviewQualityClick(Sender: TObject);
+ procedure chkRenderClick(Sender: TObject);
+ procedure sbFilterRadiusDownClick(Sender: TObject);
+ procedure sbFilterRadiusUpClick(Sender: TObject);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure tbStopClick(Sender: TObject);
+ private
+ { Private declarations }
+
+ totFrames: integer;
+ FrameWidth, FrameHeight: integer;
+ FrameRatio: double;
+ AnimPrefix, SaveAnimPath: string;
+ AnimType: shortint;
+ AnimCp, PreviewCp: TControlPoint;
+ PreviewDensity: double;
+ AnimRender: TRenderer;
+ AnimProc, DrawPreviewProc: TProc;
+ StatusGenerating, StatusFinished: string;
+ CurrentFlame: string;
+ StopAnimate: boolean;
+ StartBG: array [0..2] of byte;
+
+ procedure ARotateFlame;
+ procedure ARotateReference;
+ procedure ARotate3DCamera;
+ procedure ARotateGradient;
+ procedure ARotateHue;
+ procedure AMorphing;
+ procedure LerpBG(const i: integer);
+
+ procedure DoAnimate;
+ procedure FillFlameList;
+ procedure ChangeControlState(const activate: boolean);
+ public
+ { Public declarations }
+
+ procedure UpdateControls;
+ end;
+
+var
+ AnimateForm: TAnimateForm;
+
+implementation
+
+{$R *.dfm}
+
+uses
+ Main, Editor, Global, XForm, XFormMan, CMap, FormRender, Registry;
+
+procedure TAnimateForm.btCloseClick(Sender: TObject);
+begin
+ AnimRender.Stop;
+ tbStopClick(Sender);
+ Close;
+end;
+
+procedure TAnimateForm.btSaveAnimationClick(Sender: TObject);
+var
+ i: word;
+ FrameFolder: string;
+begin
+ // AV: first we must check the output directory
+ SaveAnimPath := edOutFlame.Text;
+
+ if SaveAnimPath = '' then begin
+ Application.MessageBox(PChar(TextByKey('render-status-nofilename')),
+ ApophysisSVN, 48);
+ exit;
+ end;
+
+ if not DirectoryExists(ExtractFilePath(SaveAnimPath)) then
+ raise Exception.Create(TextByKey('render-status-pathdoesnotexist')); // AV
+
+ if FileExists(SaveAnimPath) then begin
+ if Application.MessageBox(PChar(
+ Format(TextByKey('render-status-fileexists-message1'),[SaveAnimPath]) +
+ #13#10 + TextByKey('render-status-fileexists-message2')),
+ ApophysisSVN, 52) = ID_NO then exit;
+ DeleteFile(SaveAnimPath);
+ end;
+
+ AnimPrefix := edPrefix.Text;
+ cbFlamesChange(Sender);
+ AnimCp.AdjustScale(FrameWidth, FrameHeight);
+
+ StopAnimate := False;
+ ChangeControlState(false);
+
+ if chkInvertBG.Checked then
+ for i := 0 to 2 do
+ StartBG[i] := AnimCp.background[i];
+
+ AnimProc := procedure
+ begin
+ MainForm.SaveXMLFlame(AnimCp, AnimCp.name, SaveAnimPath);
+ end;
+ DoAnimate;
+
+ if StopAnimate then begin
+ AnimStatus.SimpleText := TextByKey('animate-status-stopped');
+ exit;
+ end
+ else
+ AnimStatus.SimpleText := StatusFinished;
+
+ ChangeControlState(true);
+
+ if FileExists(SaveAnimPath) then
+ begin
+ if chkListFlames.Checked then
+ begin
+ OpenFile := SaveAnimPath;
+ OpenFileType := ftXML;
+ ListXML(SaveAnimPath, 1);
+ end;
+
+ if chkRender.Checked then
+ begin
+ if Assigned(RenderForm.Renderer) then
+ if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
+ ApophysisSVN, 36) = ID_NO then exit;
+
+ if Assigned(RenderForm.Renderer) then RenderForm.Renderer.Terminate;
+ if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #1
+ RenderForm.ResetControls;
+
+ RenderForm.bRenderAll := true;
+
+ if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #2
+
+ RenderForm.RenderFlameFile := SaveAnimPath;
+ SetLength(RenderForm.FlameNames, totFrames);
+ for i := 0 to totFrames - 1 do
+ RenderForm.FlameNames[i] := AnimPrefix + Format('%.3d', [i]);
+
+ if CreateAnimFolder then begin
+ FrameFolder := RemoveExt(SaveAnimPath) + '\';
+ CreateDir(FrameFolder); // create a separate folder for flames
+ end else
+ FrameFolder := ExtractFilePath(SaveAnimPath);
+ RenderForm.Filename := FrameFolder + AnimCp.name +
+ cbFrameExt.Items[cbFrameExt.ItemIndex];
+ renderFileFormat := cbFrameExt.ItemIndex + 1;
+ renderOversample := seOversample.Value;
+ renderFilterRadius := StrToFloat(txtFilterRadius.Text);
+ renderDensity := StrToFloat(txtDensity.Text);
+ renderWidth := seFrameWidth.Value;
+ renderHeight := seFrameHeight.Value;
+ SaveInFlame := False; // all flames are already saved
+
+ RenderForm.Show;
+ self.Close;
+
+ RenderForm.btnRenderClick(Sender);
+ end;
+ end;
+
+end;
+
+procedure TAnimateForm.btSetFlameClick(Sender: TObject);
+begin
+ with MainForm.SaveDialog do begin
+ Filter := TextByKey('common-filter-flamefiles') + '|*.flame;*.xml|'
+ + TextByKey('common-filter-allfiles') + '|*.*';
+ InitialDir := ParamFolder;
+ FileName := ExtractFileName(edOutFlame.Text);
+ if Execute then
+ begin
+ if ExtractFileExt(FileName) = '' then
+ FileName := FileName + '.flame';
+ edOutFlame.Text := FileName;
+ end;
+ end;
+end;
+
+procedure TAnimateForm.cbAnimTypeChange(Sender: TObject);
+begin
+ AnimType := cbAnimType.ItemIndex;
+
+ if AnimType < 5 then
+ begin
+ cbFlamesTo.ItemIndex := cbFlames.ItemIndex;
+ cbFlamesTo.Enabled := False;
+ end
+ else begin
+ cbFlamesTo.Enabled := True;
+ end;
+end;
+
+procedure TAnimateForm.cbAspectRatioChange(Sender: TObject);
+var
+ r: double;
+begin
+ case cbAspectRatio.ItemIndex of
+ 0, 1: FrameRatio := FrameWidth / FrameHeight;
+ 2: FrameRatio := 1.5;
+ 3: FrameRatio := 4 / 3;
+ 4: FrameRatio := 1.25;
+ 5: FrameRatio := 16 / 9;
+ 6: FrameRatio := 1.6;
+ 7: FrameRatio := 21 / 9;
+ end;
+
+ if FrameRatio > (pnlPreview.Width / pnlPreview.Height) then
+ begin
+ AnimPreview.Width := pnlPreview.Width;
+ r := FrameWidth / AnimPreview.Width;
+ AnimPreview.Height := round(FrameHeight / r);
+ AnimPreview.Left := 0;
+ AnimPreview.Top := (pnlPreview.Height - AnimPreview.Height) shr 1;
+ end
+ else begin
+ AnimPreview.Height := pnlPreview.Height;
+ r := FrameHeight / AnimPreview.height;
+ AnimPreview.Width := round(FrameWidth / r);
+ AnimPreview.Top := 0;
+ AnimPreview.Left := (pnlPreview.Width - AnimPreview.Width) shr 1;
+ end;
+end;
+
+procedure TAnimateForm.cbFlamesChange(Sender: TObject);
+var
+ flameXML: string;
+ i: integer;
+begin
+ i := cbFlames.ItemIndex;
+ if i < 0 then exit;
+
+ if i < (cbFlames.Items.Count - 1) then
+ begin
+ flameXML := LoadXMLFlameText(Openfile, cbFlames.Items[i]);
+ MainForm.ParseXML(AnimCp, flameXML, true);
+ end
+ else
+ AnimCp.Copy(MainCp);
+
+ seFrameWidth.Value := AnimCp.Width;
+ seFrameHeight.Value := AnimCp.Height;
+ cbAspectRatioChange(Sender);
+
+ DrawPreviewProc;
+end;
+
+procedure TAnimateForm.chkRenderClick(Sender: TObject);
+begin
+ gbFrameQuality.Enabled := chkRender.Checked;
+ cbFrameExt.Enabled := chkRender.Checked;
+end;
+
+procedure TAnimateForm.FillFlameList;
+var FItem: TListItem;
+begin
+ cbFlames.Clear;
+ for FItem in MainForm.ListView1.Items do
+ cbFlames.AddItem(FItem.Caption, nil);
+ cbFlames.AddItem(MainCp.name + CurrentFlame, nil);
+ cbFlames.ItemIndex := cbFlames.Items.Count - 1;
+ cbFlamesTo.Items.Assign(cbFlames.Items);
+ cbFlamesTo.ItemIndex := cbFlames.ItemIndex;
+end;
+
+procedure TAnimateForm.LerpBG(const i: integer);
+var
+ k, k1: double;
+ c: byte;
+begin
+ //if (totFrames <= 1) then exit;
+ k := i / (totFrames - 1);
+ k1 := (1 - k);
+ for c := 0 to 2 do
+ AnimCp.background[c] := Round(k1 * StartBG[c] + k * (255 - StartBG[c]));
+end;
+
+procedure TAnimateForm.ARotateFlame;
+var
+ j: integer;
+ i, nx: smallint;
+ rstep: double;
+ Triangles: TTriangles;
+ fx: TXForm;
+begin
+ rstep := 2 * pi / totFrames;
+ nx := AnimCp.NumXForms;
+ fx := TXForm.Create;
+ fx.Assign(AnimCp.xform[nx]);
+ AnimCp.TrianglesFromCp(Triangles);
+
+ for j := 0 to totFrames - 1 do
+ begin
+ AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
+
+ for i := -1 to nx - 1 do
+ Triangles[i] := RotateTriangle(Triangles[i], rstep * j);
+ AnimCp.GetFromTriangles(Triangles, nx);
+ AnimCp.xform[nx].Assign(fx);
+ if chkResetLocation.Checked then AnimCp.CalcBoundbox;
+ if chkInvertBG.Checked then LerpBG(j);
+
+ AnimCp.name := AnimPrefix + Format('%.3d', [j]);
+ AnimProc;
+
+ if StopAnimate then break;
+ end;
+ fx.Free;
+end;
+
+procedure TAnimateForm.ARotateReference;
+var
+ j, nx: integer;
+ rstep: double;
+ Triangles: TTriangles;
+ fx: TXForm;
+begin
+ rstep := 2 * pi / totFrames;
+ nx := AnimCp.NumXForms;
+ fx := TXForm.Create;
+ fx.Assign(AnimCp.xform[nx]);
+ AnimCp.TrianglesFromCp(Triangles);
+
+ for j := 0 to totFrames - 1 do
+ begin
+ AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
+
+ Triangles[-1] := RotateTriangle(Triangles[-1], rstep * j);
+ AnimCp.GetFromTriangles(Triangles, nx);
+ AnimCp.xform[nx].Assign(fx);
+ if chkResetLocation.Checked then AnimCp.CalcBoundbox;
+ if chkInvertBG.Checked then LerpBG(j);
+
+ AnimCp.name := AnimPrefix + Format('%.3d', [j]);
+ AnimProc;
+
+ if StopAnimate then break;
+ end;
+ fx.Free;
+end;
+
+procedure TAnimateForm.ARotate3DCamera;
+var
+ j: integer;
+ rstep: double;
+begin
+ rstep := 2 * pi / totFrames;
+
+ for j := 0 to totFrames - 1 do
+ begin
+ AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
+
+ AnimCp.cameraPitch := AnimCp.cameraPitch + rstep;
+ AnimCp.cameraYaw := AnimCp.cameraYaw + rstep;
+ AnimCp.cameraRoll := AnimCp.cameraRoll + rstep;
+ if chkResetLocation.Checked then AnimCp.CalcBoundbox;
+ if chkInvertBG.Checked then LerpBG(j);
+
+ AnimCp.name := AnimPrefix + Format('%.3d', [j]);
+ AnimProc;
+
+ if StopAnimate then break;
+ end;
+end;
+
+procedure TAnimateForm.ARotateGradient;
+var
+ i, j, n: integer;
+ rstep: double;
+ SourceMap: TColorMap;
+begin
+ SourceMap := AnimCp.cmap;
+ rstep := 256 / totFrames;
+
+ for j := 0 to totFrames - 1 do
+ begin
+ AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
+ for i := 0 to 255 do
+ begin
+ n := (256 + i - Round(rstep * j)) mod 256;
+ AnimCp.cmap[i,0] := SourceMap[n,0];
+ AnimCp.cmap[i,1] := SourceMap[n,1];
+ AnimCp.cmap[i,2] := SourceMap[n,2];
+ end;
+ if chkInvertBG.Checked then LerpBG(j);
+ AnimCp.name := AnimPrefix + Format('%.3d', [j]);
+ AnimProc;
+
+ if StopAnimate then break;
+ end;
+end;
+
+procedure TAnimateForm.ARotateHue;
+var
+ j: integer;
+ h: double;
+begin
+ h := 1 / totFrames;
+ for j := 0 to totFrames - 1 do
+ begin
+ AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
+ AnimCp.hue_rotation := h;
+ RotateCMapHue(AnimCp);
+ AnimCp.hue_rotation := 1;
+ if chkInvertBG.Checked then LerpBG(j);
+ AnimCp.name := AnimPrefix + Format('%.3d', [j]);
+ AnimProc;
+
+ if StopAnimate then break;
+ end;
+end;
+
+procedure TAnimateForm.AMorphing;
+var
+ j: integer;
+ t: smallint;
+ SourceCp, TargetCp: TControlPoint;
+ flameXML: string;
+begin
+ j := cbFlamesTo.ItemIndex;
+ if j = cbFlames.ItemIndex then begin
+ Application.MessageBox(PChar(TextByKey('animate-status-changeflame')),
+ ApophysisSVN, 48);
+ exit;
+ end;
+
+ SourceCp := AnimCp.Clone;
+ SourceCp.time := 0;
+
+ if j < (cbFlamesTo.Items.Count - 1) then
+ begin
+ TargetCp := TControlPoint.Create;
+ flameXML := LoadXMLFlameText(Openfile, cbFlamesTo.Items[j]);
+ MainForm.ParseXML(TargetCp, flameXML, true);
+ end
+ else
+ TargetCp := MainCp.Clone;
+ TargetCp.time := totFrames - 1;
+
+ PrepareToInterpolation(SourceCp, TargetCp); // adjust non-common parameters
+
+ if chkInvertBG.Checked then
+ for j := 0 to 2 do // invert target background
+ TargetCp.background[j] := 255 - SourceCp.background[j];
+
+ t := AnimType - 5; // interpolation type
+
+ try
+ for j := 0 to totFrames - 1 do
+ begin
+ AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
+
+ AnimCp.InterpolateAll(SourceCp, TargetCp, j, t);
+ if chkResetLocation.Checked then AnimCp.CalcBoundbox;
+ AnimCp.name := AnimPrefix + Format('%.3d', [j]);
+
+ AnimProc;
+
+ if StopAnimate then break;
+ end;
+ finally
+ SourceCp.Free;
+ TargetCp.Free;
+ end;
+end;
+
+procedure TAnimateForm.DoAnimate;
+begin
+ totFrames := seFPS.Value * seDuration.Value;
+
+ try
+ case AnimType of
+ 0: ARotateFlame;
+ 1: ARotateReference;
+ 2: ARotate3DCamera;
+ 3: ARotateGradient;
+ 4: ARotateHue;
+ 5..8: AMorphing;
+ end;
+ except
+ // TODO
+ end;
+end;
+
+procedure TAnimateForm.FormClose(Sender: TObject; var Action: TCloseAction);
+var
+ Registry: TRegistry;
+begin
+ { Write position to registry }
+ Registry := TRegistry.Create;
+ try
+ Registry.RootKey := HKEY_CURRENT_USER;
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Animate', True) then
+ begin
+ Registry.WriteInteger('Top', self.Top);
+ Registry.WriteInteger('Left', self.Left);
+ Registry.WriteBool('ResetLocation', chkResetLocation.Checked);
+ Registry.WriteBool('ListFlames', chkListFlames.Checked);
+ Registry.WriteBool('RenderFrames', chkRender.Checked);
+ Registry.WriteInteger('AnimationType', cbAnimType.ItemIndex);
+ end;
+ finally
+ Registry.Free;
+ end;
+end;
+
+procedure TAnimateForm.FormCreate(Sender: TObject);
+begin
+ self.Caption := TextByKey('animate-title');
+ tsSettings.Caption := TextByKey('animate-general');
+ tsAnimation.Caption := TextByKey('animate-animation');
+ gbOutput.Caption := TextByKey('animate-output');
+ pnlOutFlame.Caption := TextByKey('animate-outflame');
+ pnlPrefix.Caption := TextByKey('animate-prefix');
+ gbPreview.Caption := TextByKey('animate-preview');
+ pnlFrameExt.Caption := TextByKey('animate-graphicext');
+ pnlDuration.Caption := TextByKey('animate-duration');
+ lbSeconds.Caption := TextByKey('common-seconds');
+ pnlFPS.Caption := TextByKey('animate-fps');
+
+ gbFrame.Caption := TextByKey('animate-frame');
+ pnlFrameWidth.Caption := TextByKey('common-width');
+ pnlFrameHeight.Caption := TextByKey('common-height');
+ pnlRatio.Caption := TextByKey('adjustment-tab-size-ratio');
+ cbAspectRatio.Items[0] := TextByKey('adjustment-tab-size-custom');
+ cbAspectRatio.Items[1] := TextByKey('common-keepaspect');
+ cbAspectRatio.ItemIndex := 1; // keep current aspect ratio
+
+ gbFrameQuality.Caption := TextByKey('common-quality');
+ pnlFilter.Caption := TextByKey('common-filterradius');
+ pnlDensity.Caption := TextByKey('common-density');
+ pnlOversample.Caption := TextByKey('common-oversample');
+
+ gbAnimType.Caption := TextByKey('animate-parameters');
+ pnlAnimType.Caption := TextByKey('animate-type');
+ chkListFlames.Caption := TextByKey('animate-showframes');
+ chkRender.Caption := TextByKey('animate-render');
+ chkResetLocation.Caption := TextByKey('animate-resetlocation');
+ chkInvertBG.Caption := TextByKey('animate-invertbg');
+ tbPlay.Caption := TextByKey('common-start');
+ btSaveAnimation.Caption := TextByKey('animate-save');
+ btClose.Caption := TextByKey('common-close');
+ btSetFlame.Hint := TextByKey('common-browse');
+ StatusGenerating := TextByKey('animate-status-generating');
+ StatusFinished := TextByKey('animate-status-finished');
+ CurrentFlame := #32 + TextByKey('animate-currentflame');
+ pnlStartFlame.Caption := TextByKey('animate-initflame');
+ pnlEndFlame.Caption := TextByKey('animate-finalflame');
+ tbPlay.Hint := TextByKey('animate-playhint');
+ tbStop.Hint := TextByKey('animate-stophint');
+ tbStop.Caption := TextByKey('animate-stop');
+ btSaveAnimation.Hint := TextByKey('animate-savehint');
+
+ cbAnimType.Items[0] := TextByKey('animate-kind-rotateflame');
+ cbAnimType.Items[1] := TextByKey('animate-kind-rotatereference');
+ cbAnimType.Items[2] := TextByKey('animate-kind-rotatecamera');
+ cbAnimType.Items[3] := TextByKey('animate-kind-rotatepalette');
+ cbAnimType.Items[4] := TextByKey('animate-kind-rotatehue');
+ cbAnimType.Items[5] := TextByKey('animate-kind-morph1');
+ cbAnimType.Items[6] := TextByKey('animate-kind-morph2');
+ cbAnimType.Items[7] := TextByKey('animate-kind-morph3');
+ cbAnimType.Items[8] := TextByKey('animate-kind-morph4');
+ cbAnimType.ItemIndex := 0;
+
+ mnuLowQuality.Caption := TextByKey('common-lowquality');
+ mnuMediumQuality.Caption := TextByKey('common-mediumquality');
+ mnuHighQuality.Caption := TextByKey('common-highquality');
+
+ case AnimPrevQual of
+ 0: begin
+ PreviewDensity := prevLowQuality;
+ mnuLowQuality.Checked := True;
+ end;
+ 1: begin
+ PreviewDensity := prevMediumQuality;
+ mnuMediumQuality.Checked := True;
+ end;
+ 2: begin
+ PreviewDensity := prevHighQuality;
+ mnuHighQuality.Checked := True;
+ end;
+ end;
+
+ AnimCp := TControlPoint.Create;
+ PreviewCp := TControlPoint.Create;
+ AnimRender := TRenderer.Create;
+
+ DrawPreviewProc := procedure
+ begin
+ PreviewCp.Copy(AnimCp);
+ PreviewCp.sample_density := PreviewDensity;
+ PreviewCp.AdjustScale(AnimPreview.Width, AnimPreview.Height);
+ AnimRender.Stop;
+ AnimRender.SetCP(PreviewCp);
+ AnimRender.Render;
+ AnimPreview.Picture.Graphic := AnimRender.GetImage;
+ Application.ProcessMessages;
+ end;
+end;
+
+procedure TAnimateForm.FormDestroy(Sender: TObject);
+begin
+ AnimCp.Free;
+ PreviewCp.Free;
+ AnimRender.Free;
+end;
+
+procedure TAnimateForm.FormShow(Sender: TObject);
+var
+ Registry: TRegistry;
+begin
+ { Read position from registry }
+ Registry := TRegistry.Create;
+ try
+ Registry.RootKey := HKEY_CURRENT_USER;
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Animate', False) then
+ begin
+ if Registry.ValueExists('Left') then
+ self.Left := Registry.ReadInteger('Left');
+ if Registry.ValueExists('Top') then
+ self.Top := Registry.ReadInteger('Top');
+
+ if Registry.ValueExists('ResetLocation') then
+ chkResetLocation.Checked := Registry.ReadBool('ResetLocation');
+ if Registry.ValueExists('ListFlames') then
+ chkListFlames.Checked := Registry.ReadBool('ListFlames');
+ if Registry.ValueExists('RenderFrames') then
+ chkRender.Checked := Registry.ReadBool('RenderFrames');
+ if Registry.ValueExists('AnimationType') then
+ cbAnimType.ItemIndex := Registry.ReadInteger('AnimationType');
+
+ Registry.CloseKey;
+ end;
+ finally
+ Registry.Free;
+ end;
+
+ cbFrameExt.ItemIndex := defFrameExt;
+ txtDensity.Text := FloatToStr(renderDensity);
+ txtFilterRadius.Text := FloatToStr(Round6(renderFilterRadius));
+ seOversample.Value := renderOversample;
+ edPrefix.Text := defAnimPrefix;
+ seFPS.Value := AnimFPS;
+
+ edOutFlame.Text := ParamFolder + MainCp.name + ' (animated).flame';
+ chkRenderClick(Sender);
+ cbAnimTypeChange(Sender);
+ UpdateControls;
+end;
+
+procedure TAnimateForm.mnuPreviewQualityClick(Sender: TObject);
+begin
+ if TMenuItem(Sender).Checked then exit; // prevent unneseccary updating
+ TMenuItem(Sender).Checked := True;
+
+ case TMenuItem(Sender).Tag of
+ 0: PreviewDensity := prevMediumQuality;
+ 1: PreviewDensity := prevMediumQuality;
+ 2: PreviewDensity := prevHighQuality;
+ end;
+ AnimPrevQual := TMenuItem(Sender).Tag;
+
+ DrawPreviewProc;
+end;
+
+procedure TAnimateForm.sbFilterRadiusDownClick(Sender: TObject);
+var n: double;
+begin
+ try
+ n := StrToFloat(txtFilterRadius.Text);
+ n := Round6(n - 0.05);
+ if (n > 0) then
+ txtFilterRadius.Text := FloatToStr(n);
+ except
+ raise Exception.Create(TextByKey('render-status-invalidfilterradius'));
+ end;
+end;
+
+procedure TAnimateForm.sbFilterRadiusUpClick(Sender: TObject);
+var n: double;
+begin
+ try
+ n := StrToFloat(txtFilterRadius.Text);
+ txtFilterRadius.Text := Format('%.3g', [n + 0.05]);
+ except
+ raise Exception.Create(TextByKey('render-status-invalidfilterradius'));
+ end;
+end;
+
+procedure TAnimateForm.seFrameHeightChange(Sender: TObject);
+begin
+ try
+ FrameHeight := seFrameHeight.Value;
+ if (cbAspectRatio.ItemIndex > 0) and seFrameHeight.Focused then
+ begin
+ FrameWidth := Round(FrameHeight * FrameRatio);
+ seFrameWidth.Value := FrameWidth;
+ end;
+ except
+ end;
+end;
+
+procedure TAnimateForm.seFrameWidthChange(Sender: TObject);
+begin
+ try
+ FrameWidth := seFrameWidth.Value;
+ if (cbAspectRatio.ItemIndex > 0) and seFrameWidth.Focused then
+ begin
+ FrameHeight := Round(FrameWidth / FrameRatio);
+ seFrameHeight.Value := FrameHeight;
+ end;
+ except
+ end;
+end;
+
+procedure TAnimateForm.tbPlayClick(Sender: TObject);
+var i: byte;
+begin
+ StopAnimate := False;
+ cbFlamesChange(Sender);
+ ChangeControlState(false);
+
+ if chkInvertBG.Checked then
+ for i := 0 to 2 do
+ StartBG[i] := AnimCp.background[i];
+
+ AnimProc := DrawPreviewProc;
+ DoAnimate;
+
+ AnimStatus.SimpleText := '';
+ ChangeControlState(true);
+end;
+
+procedure TAnimateForm.tbStopClick(Sender: TObject);
+begin
+ StopAnimate := True;
+ ChangeControlState(true);
+end;
+
+procedure TAnimateForm.ChangeControlState(const activate: boolean);
+begin
+ gbFrame.Enabled := activate;
+ gbAnimType.Enabled := activate;
+ btSaveAnimation.Enabled := activate;
+ tbPlay.Enabled := activate;
+ tbStop.Enabled := not activate;
+end;
+
+procedure TAnimateForm.UpdateControls;
+begin
+ FillFlameList;
+ cbFlamesChange(self);
+end;
+
+end.
diff --git a/Forms/Browser.dfm b/Forms/Browser.dfm
index d699304..ba6616f 100644
--- a/Forms/Browser.dfm
+++ b/Forms/Browser.dfm
@@ -204,7 +204,7 @@ object GradientBrowser: TGradientBrowser
end
end
object SmallImages: TImageList
- Left = 192
+ Left = 224
Top = 24
Bitmap = {
494C010101000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
@@ -363,12 +363,12 @@ object GradientBrowser: TGradientBrowser
object OpenDialog: TOpenDialog
DefaultExt = 'ugr'
Filter = 'Gradient files (*.ugr)|*.ugr|Fractint map files (*.map)|*.map'
- Left = 136
+ Left = 160
Top = 24
end
object TooltipTimer: TTimer
OnTimer = TooltipTimerTimer
- Left = 88
+ Left = 96
Top = 20
end
end
diff --git a/Forms/Browser.pas b/Forms/Browser.pas
index cf339aa..de8dbcc 100644
--- a/Forms/Browser.pas
+++ b/Forms/Browser.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -28,11 +28,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ComCtrls, ToolWin, ImgList, StdCtrls, System.ImageList,
- Cmap, Menus, Global, Buttons, Translation;
-
-const
- PixelCountMax = 32768;
- PaletteTooltipTimeout = 1500;
+ Cmap, Menus, Global, Buttons;
type
TGradientBrowser = class(TForm)
@@ -64,10 +60,10 @@ type
procedure ListViewInfoTip(Sender: TObject; Item: TListItem;
var InfoTip: String);
procedure TooltipTimerTimer(Sender: TObject);
- // AV: now you really can rename it :-)
- function RenameGradient(OldIdent: string; var NewIdent: string): boolean;
procedure btnRandomClick(Sender: TObject); // AV
private
+ // AV: now you really can rename it :-)
+ function RenameGradient(OldIdent: string; var NewIdent: string): boolean;
procedure DrawPalette;
procedure Apply;
public
@@ -78,22 +74,24 @@ type
function LoadFractintMap(filen: string): TColorMap;
end;
+{ // AV: we already have this declarations in other units (Cmap and Global)!
type
EFormatInvalid = class(Exception);
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
+}
var
GradientBrowser: TGradientBrowser;
-function CreatePalette(strng: string): TColorMap;
-
implementation
-uses Main, Options, Editor, Registry, Adjust, Mutate;
+uses
+ Main, Options, Editor, Registry, Adjust, Mutate, Translation;
{$R *.DFM}
+(* // AV: exactly the same functions we have in Cmap unit
function GetVal(token: string): string;
var
p: integer;
@@ -118,6 +116,7 @@ begin
end;
Result := str;
end;
+ *)
function TGradientBrowser.LoadFractintMap(filen: string): TColorMap;
var
@@ -140,10 +139,12 @@ begin
CloseFile(MapFile);
Result := Pal;
except
- on EInOutError do Application.MessageBox(PChar(Format(TextByKey('common-genericopenfailure'), [FileName])), PCHAR('Apophysis'), 16);
+ on EInOutError do
+ raise Exception.CreateFmt(TextByKey('common-genericopenfailure'), [FileName]);
end;
end;
+(* // AV: moved into Cmap unit
function CreatePalette(strng: string): TColorMap;
{ Loads a palette from a gradient string }
var
@@ -209,7 +210,7 @@ begin
RGBBlend(a, b, Result);
end;
except on EFormatInvalid do
- // Result := False;
+ //
end;
finally
Tokens.Free;
@@ -218,6 +219,7 @@ begin
Colors.Free;
end;
end;
+*)
procedure TGradientBrowser.DrawPalette;
var
@@ -338,6 +340,11 @@ begin
DeleteItem.Caption := TextByKey('common-delete');
RenameItem.Caption := TextByKey('common-rename');
btnRandom.Hint := TextByKey('adjustment-tab-gradient-presethint');
+ // AV: moved this here since it never changes
+ OpenDialog.Filter := Format('%s|*.gradient;*.ugr|%s|*.map|%s|*.*',
+ [TextByKey('common-filter-gradientfiles'),
+ TextByKey('common-filter-fractintfiles'),
+ TextByKey('common-filter-allfiles')]);
end;
procedure TGradientBrowser.FormShow(Sender: TObject);
@@ -373,8 +380,8 @@ begin
if ListView.SelCount <> 0 then
begin
if ConfirmDelete then
- c := Application.MessageBox(
- PChar(Format(TextByKey('common-confirmdelete'), [ListView.Selected.Caption])), 'Apophysis', 36) = IDYES
+ c := Application.MessageBox(PChar(Format(TextByKey('common-confirmdelete'),
+ [ListView.Selected.Caption])), 'Apophysis', 36) = IDYES
else
c := True;
if c then
@@ -415,7 +422,8 @@ begin
end
else
Result := False;
- except on Exception do Result := False;
+ except on Exception do
+ Result := False;
end;
finally
Strings.Free;
@@ -424,7 +432,7 @@ end;
procedure TGradientBrowser.RenameItemClick(Sender: TObject);
begin
- if ListView.SelCount <> 0 then
+ if ListView.Selected <> nil then
ListView.Items[ListView.Selected.Index].EditCaption;
end;
@@ -437,21 +445,15 @@ begin
end;
procedure TGradientBrowser.btnDefGradientClick(Sender: TObject);
-var
- fn:string;
begin
OpenDialog.InitialDir := BrowserPath;
- OpenDialog.Filter := Format('%s|*.gradient;*.ugr|%s|*.map|%s|*.*',
- [TextByKey('common-filter-gradientfiles'),
- TextByKey('common-filter-fractintfiles'),
- TextByKey('common-filter-allfiles')]);
OpenDialog.FileName := '';
- if OpenSaveFileDialog(GradientBrowser, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
+ //if OpenSaveFileDialog(GradientBrowser, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
+ if OpenDialog.Execute then
begin
- Filename := fn; //OpenDialog.FileName;
+ Filename := OpenDialog.FileName;
GradientFile := Filename;
- BrowserPath := ExtractFilePath(fn); //ExtractFilePath(OpenDialog.FileName);
+ BrowserPath := ExtractFilePath(Filename);
ListFileContents;
end;
end;
@@ -512,6 +514,8 @@ end;
procedure TGradientBrowser.ListViewInfoTip(Sender: TObject;
Item: TListItem; var InfoTip: String);
+const
+ PaletteTooltipTimeout = 1500;
var
i, j: integer;
Row: pRGBTripleArray;
diff --git a/Forms/ColorRangeForm.dfm b/Forms/ColorRangeForm.dfm
index c3633de..2b236de 100644
--- a/Forms/ColorRangeForm.dfm
+++ b/Forms/ColorRangeForm.dfm
@@ -61,29 +61,15 @@ object ColorSelection: TColorSelection
object StartColor: TShape
Left = 10
Top = 40
- Width = 30
+ Width = 40
Height = 22
end
object LastColor: TShape
- Left = 140
+ Left = 150
Top = 40
- Width = 30
+ Width = 40
Height = 22
end
- object lbStart: TLabel
- Left = 8
- Top = 16
- Width = 94
- Height = 13
- Caption = 'Start palette index:'
- end
- object lbLast: TLabel
- Left = 140
- Top = 16
- Width = 90
- Height = 13
- Caption = 'Last palette index:'
- end
object btOK: TButton
Left = 101
Top = 82
@@ -107,9 +93,9 @@ object ColorSelection: TColorSelection
TabOrder = 1
end
object SpinStart: TSpinEdit
- Left = 40
+ Left = 50
Top = 40
- Width = 70
+ Width = 80
Height = 22
MaxValue = 253
MinValue = 0
@@ -119,9 +105,9 @@ object ColorSelection: TColorSelection
OnKeyPress = SpinValueKeyPress
end
object SpinLast: TSpinEdit
- Left = 170
+ Left = 190
Top = 40
- Width = 70
+ Width = 80
Height = 22
MaxValue = 255
MinValue = 2
@@ -130,4 +116,22 @@ object ColorSelection: TColorSelection
OnChange = SpinLastChange
OnKeyPress = SpinValueKeyPress
end
+ object lbStart: TPanel
+ Left = 10
+ Top = 19
+ Width = 120
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Start palette index:'
+ TabOrder = 4
+ end
+ object lbLast: TPanel
+ Left = 150
+ Top = 19
+ Width = 120
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Last palette index:'
+ TabOrder = 5
+ end
end
diff --git a/Forms/ColorRangeForm.pas b/Forms/ColorRangeForm.pas
index 201859e..678edd4 100644
--- a/Forms/ColorRangeForm.pas
+++ b/Forms/ColorRangeForm.pas
@@ -5,9 +5,10 @@ unit ColorRangeForm;
interface
uses
- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
- Vcl.Controls, ComCtrls, StdCtrls, ExtCtrls, Vcl.Forms, Vcl.Dialogs, Adjust, Translation,
- Vcl.Samples.Spin;
+ Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
+ System.Classes, Vcl.Controls, ComCtrls, StdCtrls, ExtCtrls, Vcl.Dialogs,
+ Vcl.Forms, Vcl.Graphics,Vcl.Samples.Spin, Adjust, Translation;
+
type
TColorSelection = class(TForm)
btOK: TButton;
@@ -16,8 +17,8 @@ type
SpinLast: TSpinEdit;
StartColor: TShape;
LastColor: TShape;
- lbStart: TLabel;
- lbLast: TLabel;
+ lbStart: TPanel;
+ lbLast: TPanel;
procedure FormCreate(Sender: TObject);
procedure btOKClick(Sender: TObject);
procedure FormShow(Sender: TObject);
diff --git a/Forms/Curves.dfm b/Forms/Curves.dfm
deleted file mode 100644
index 3b97403..0000000
--- a/Forms/Curves.dfm
+++ /dev/null
@@ -1,125 +0,0 @@
-object CurvesForm: TCurvesForm
- Left = 197
- Top = 111
- BorderStyle = bsDialog
- Caption = 'Curves'
- ClientHeight = 492
- ClientWidth = 489
- Color = clBtnFace
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -13
- Font.Name = 'System'
- Font.Style = []
- OldCreateOrder = False
- OnClose = FormClose
- OnCreate = FormCreate
- OnShow = FormShow
- PixelsPerInch = 96
- TextHeight = 16
- object Label1: TLabel
- Left = 8
- Top = 16
- Width = 75
- Height = 13
- Caption = 'Selected curve:'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- end
- object CurvesPanel: TPanel
- Left = 8
- Top = 68
- Width = 473
- Height = 414
- BevelOuter = bvNone
- Color = clBlack
- ParentBackground = False
- TabOrder = 0
- end
- object cbChannel: TComboBox
- Left = 8
- Top = 35
- Width = 185
- Height = 21
- Style = csDropDownList
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ItemIndex = 0
- ParentFont = False
- TabOrder = 1
- Text = 'Overall'
- OnChange = cbChannelChange
- Items.Strings = (
- 'Overall'
- 'Red'
- 'Green'
- 'Blue')
- end
- object tbWeightLeft: TScrollBar
- Left = 326
- Top = 8
- Width = 155
- Height = 21
- Max = 160
- PageSize = 0
- Position = 80
- TabOrder = 2
- OnChange = tbWeightChange
- OnScroll = tbWeightScroll
- end
- object tbWeightRight: TScrollBar
- Left = 326
- Top = 35
- Width = 155
- Height = 21
- Max = 160
- PageSize = 0
- Position = 80
- TabOrder = 3
- OnChange = tbWeightChange
- OnScroll = tbWeightScroll
- end
- object Panel2: TPanel
- Left = 199
- Top = 8
- Width = 121
- Height = 21
- Cursor = crHandPoint
- BevelOuter = bvLowered
- Caption = ' First CP weight:'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- ParentShowHint = False
- ShowHint = True
- TabOrder = 4
- end
- object Panel1: TPanel
- Left = 199
- Top = 35
- Width = 121
- Height = 21
- Cursor = crHandPoint
- BevelOuter = bvLowered
- Caption = ' Second CP weight:'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- ParentShowHint = False
- ShowHint = True
- TabOrder = 5
- end
-end
diff --git a/Forms/Curves.pas b/Forms/Curves.pas
deleted file mode 100644
index 959d238..0000000
--- a/Forms/Curves.pas
+++ /dev/null
@@ -1,123 +0,0 @@
-unit Curves;
-
-interface
-
-uses Windows, Classes, Graphics, Forms, Controls, CurvesControl, Vcl.ExtCtrls,
- Vcl.StdCtrls, Vcl.ComCtrls, ControlPoint, Registry, Global;
-
-type
- TCurvesForm = class(TForm)
- CurvesPanel: TPanel;
- cbChannel: TComboBox;
- tbWeightLeft: TScrollBar;
- tbWeightRight: TScrollBar;
- Panel2: TPanel;
- Panel1: TPanel;
- Label1: TLabel;
- procedure FormShow(Sender: TObject);
- procedure cbChannelChange(Sender: TObject);
- procedure tbWeightChange(Sender: TObject);
- procedure tbWeightScroll(Sender: TObject; ScrollCode: TScrollCode;
- var ScrollPos: Integer);
- procedure FormCreate(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- private
- { Private declarations }
- published
- CurvesControl: TCurvesControl;
- public
- procedure SetCp(cp: TControlPoint);
- end;
-
-var
- CurvesForm: TCurvesForm;
-
-implementation
-
-uses Main;
-
-{$R *.DFM}
-
-procedure TCurvesForm.tbWeightScroll(Sender: TObject; ScrollCode: TScrollCode;
- var ScrollPos: Integer);
-begin
- if ScrollCode = scEndScroll then
- CurvesControl.UpdateFlame;
-end;
-
-procedure TCurvesForm.SetCp(cp: TControlPoint);
-begin
- if CurvesControl = nil then Exit;
- CurvesControl.SetCp(cp);
-end;
-
-procedure TCurvesForm.cbChannelChange(Sender: TObject);
-begin
- if CurvesControl = nil then Exit;
- CurvesControl.ActiveChannel := TCurvesChannel(cbChannel.ItemIndex);
- tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10);
- tbWeightRight.Position := Round(CurvesControl.WeightRight * 10);
-end;
-
-procedure TCurvesForm.FormClose(Sender: TObject; var Action: TCloseAction);
-var
- Registry: TRegistry;
-begin
- { Write position to registry }
- Registry := TRegistry.Create;
- try
- Registry.RootKey := HKEY_CURRENT_USER;
- if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Curves', True) then
- begin
- Registry.WriteInteger('Top', self.Top);
- Registry.WriteInteger('Left', self.Left);
- end;
- finally
- Registry.Free;
- end;
-// bStop := True;
-end;
-
-procedure TCurvesForm.FormCreate(Sender: TObject);
-begin
- //
-end;
-
-procedure TCurvesForm.FormShow(Sender: TObject);
-var Registry: TRegistry;
-begin
- if not (assigned(curvesControl)) then
- begin
- CurvesControl := TCurvesControl.Create(self);
- CurvesControl.Align := alClient;
- CurvesControl.Parent := CurvesPanel;
- end;
-
- Registry := TRegistry.Create;
- try
- Registry.RootKey := HKEY_CURRENT_USER;
- if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Curves', False) then
- begin
- if Registry.ValueExists('Left') then
- self.Left := Registry.ReadInteger('Left');
- if Registry.ValueExists('Top') then
- self.Top := Registry.ReadInteger('Top');
- Registry.CloseKey;
- end;
- finally
- Registry.Free;
- end;
-
- tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10);
- tbWeightRight.Position := Round(CurvesControl.WeightRight * 10);
-
- SetCp(MainCp);
-end;
-
-procedure TCurvesForm.tbWeightChange(Sender: TObject);
-begin
- CurvesControl.WeightLeft := tbWeightLeft.Position / 10.0;
- CurvesControl.WeightRight := tbWeightRight.Position / 10.0;
-end;
-
-end.
diff --git a/Forms/Editor.dfm b/Forms/Editor.dfm
index cc20def..4ad796d 100644
--- a/Forms/Editor.dfm
+++ b/Forms/Editor.dfm
@@ -419,6 +419,31 @@ object EditForm: TEditForm
Style = tbsDropDown
OnClick = InsertPi1Click
end
+ object ToolButton7: TToolButton
+ Left = 655
+ Top = 0
+ Width = 8
+ Caption = 'ToolButton7'
+ ImageIndex = 33
+ Style = tbsSeparator
+ end
+ object tbComment: TToolButton
+ Left = 663
+ Top = 0
+ Caption = 'tbComment'
+ ImageIndex = 45
+ ParentShowHint = False
+ ShowHint = True
+ OnClick = tbCommentClick
+ end
+ object SaveFlameState: TToolButton
+ Left = 687
+ Top = 0
+ ImageIndex = 46
+ ParentShowHint = False
+ ShowHint = True
+ OnClick = SaveFlameStateClick
+ end
end
end
object EditPnl: TPanel
@@ -497,7 +522,7 @@ object EditForm: TEditForm
Top = 79
Width = 298
Height = 413
- ActivePage = TabVariables
+ ActivePage = tabVariations
Anchors = [akLeft, akTop, akRight, akBottom]
MultiLine = True
ParentShowHint = False
@@ -541,9 +566,9 @@ object EditForm: TEditForm
TabOrder = 0
OnResize = TrianglePanelResize
object TriangleToolBar: TToolBar
- Left = 28
+ Left = 15
Top = 218
- Width = 163
+ Width = 200
Height = 28
ParentCustomHint = False
Align = alNone
@@ -622,8 +647,19 @@ object EditForm: TEditForm
ParentShowHint = False
ShowHint = True
end
+ object tbSyncTriangles: TToolButton
+ Left = 161
+ Top = 0
+ Caption = 'tbSyncTriangles'
+ DropdownMenu = mnuSyncTriangles
+ ImageIndex = 44
+ ParentShowHint = False
+ ShowHint = True
+ Style = tbsDropDown
+ OnClick = tbSyncTrianglesClick
+ end
end
- object GroupBox5: TGroupBox
+ object gbTrgOperations: TGroupBox
Left = 20
Top = 112
Width = 177
@@ -1078,7 +1114,7 @@ object EditForm: TEditForm
'0.01')
end
end
- object GroupBox6: TGroupBox
+ object gbCoordinates: TGroupBox
Left = 6
Top = 0
Width = 209
@@ -1438,7 +1474,7 @@ object EditForm: TEditForm
OnUpClick = SpinButtonUpClick
end
end
- object GroupBox3: TGroupBox
+ object gbPivot: TGroupBox
Left = 6
Top = 248
Width = 209
@@ -1623,7 +1659,7 @@ object EditForm: TEditForm
OnUpClick = SpinButtonUpClick
end
end
- object GroupBox10: TGroupBox
+ object gbFlip: TGroupBox
Left = 6
Top = 319
Width = 209
@@ -3068,7 +3104,7 @@ object EditForm: TEditForm
DesignSize = (
290
367)
- object Label4: TLabel
+ object lblSearch: TLabel
Left = 2
Top = 8
Width = 37
@@ -3137,6 +3173,7 @@ object EditForm: TEditForm
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
+ TextHint = 'type a name...'
OnChange = chkCollapseVariationsClick
end
object btnVarOrder: TBitBtn
@@ -3215,7 +3252,9 @@ object EditForm: TEditForm
Items.Strings = (
'Show all variations'
'Hide unused variations'
- 'Favourite variations')
+ 'Favourite variations'
+ '3D-aware variations'
+ 'Direct coloring variations')
end
end
object TabVariables: TTabSheet
@@ -3627,136 +3666,264 @@ object EditForm: TEditForm
Left = 313
Top = 40
Bitmap = {
- 494C01012B003000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
- 000000000000360000002800000040000000B0000000010020000000000000B0
+ 494C01012F004000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+ 000000000000360000002800000040000000C0000000010020000000000000C0
+ 000000000000000000000000000000000000A449A300A449A300A449A300A449
+ A300A449A300A449A30000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000DEE0DF009EA2
+ A0008B908E008B908E008B908E008A8F8D008A8F8D00898F8D00898E8C00898E
+ 8C00888E8C009A9E9C00DDDEDD0000000000F8F8F807C6C6C639C5C5C53AC5C5
+ C53AC5C5C53AC5C5C53AC5C5C53AC5C5C53ACACACA35FAFAFA05FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300BD6ABD00BD6ABD00BD6A
+ BD00A449A300000000000000000000000000000000006E9B7000FCFDFD000000
+ 00000000000000000000000000000000000000000000000000009EA3A100EBED
+ EC00FEFFFE00FEFFFF00FEFFFF00000000000000000000000000000000000000
+ 000000000000EEEFEF00999E9C0000000000C6C6C639F7F7F6FEF9F9F9FFFBFB
+ FBFFFBFBFBFFFCFCFCFFFDFDFDFFFFFFFFFFEAE9E9FE9C9C9AC7F5F5F50AFFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300BD6ABD00BD6ABD00A449
+ A30000000000000000000000000000000000000000004F885300619765000000
+ 00000000000000000000000000000000000000000000000000008F959200FEFE
+ FE00EAEDEC00EAEDEC00EBEEED00ECEFEE00EDEFEE00EDF0EF00EEF0EF00EEF0
+ EF00EEF0EF00FEFFFF008D929000FBFCFB00C5C5C53AF7F7F6FFF8F8F8FFFAFA
+ FAFFFBFBFBFFFCFCFCFFFDFDFDFFFEFEFEFFF4F4F4FFCCCCCCFF979793D5EDED
+ ED12FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300BD6ABD00A449A3000000
+ 0000C6D7C7005789590023662700266B2B002A712F0053995A00569D5E006FA5
+ 730000000000000000000000000000000000000000000000000091969400FDFE
+ FE00E7EAE900858A8800858A8800858A880000000000005CCE00BACFE500E9EC
+ EB00EAEDEC00FEFEFE008E939100FBFCFC00C5C5C53AF6F6F6FFF7F7F7FF9191
+ BFFFECECF1FF9595C4FFFCFCFCFFFEFEFEFFFBFBFBFFC4C4C4FFFDFDFDFF9999
+ 94D5F5F5F50AFFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300A449A30000000000C6D7
+ C7004D82500060A7680081C88C0084C98E0087CA91008ACB94008DCD970060A7
+ 6800529B5A00000000000000000000000000000000000000000092989600FDFE
+ FD00E4E8E700E3E7E500E3E8E600E4E8E600005CCE000000000036576B00005C
+ CE00B8CDE200FEFEFE0090969400FAFBFB00C5C5C53AF6F6F5FFF6F6F6FF3236
+ C2FF2A2EB8FF3339C3FFFCFCFCFFFEFEFEFFFEFEFEFFE0E0E0FFC6C6C6FFCFCF
+ CEFFA2A09FC7FAFAFA05FFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A30000000000000000007AA2
+ 7C005BA1630082C88D0051975800317A360035803B005DA4650062A96A0075B1
+ 7B00000000000000000000000000000000000000000000000000949A9700FDFD
+ FD00E1E6E300858A8800858A8800858A8800858A8800005CCE003EAFFC000079
+ F500005CCE00A2C3EC0092979500FBFBFB00C5C5C53AF5F5F4FFF5F5F5FF3337
+ C4FF0108DAFF373AC3FFFBFBFBFFFDFDFDFFFEFEFEFFFEFEFEFFFCFCFCFFFAFA
+ FAFFF0EFEFFECACACA35FFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000000000000000000000407C
+ 4400296F2E002D753300639B6800000000000000000062A3670071AE7700FEFE
+ FE00F9FCF9000000000000000000000000000000000000000000969B9900FDFD
+ FD00DDE3E000DCE1DF00DCE2DF00DDE2E000DDE2E000005CCE0000D4F5003EAF
+ FC000079F500005CCE004B7BB200FCFCFC00C5C5C53AF4F4F4FFF4F4F4FF3B3E
+ C2FF0409CFFF3E41C2FFFAFAFAFFFCFCFCFFFDFDFDFFFDFDFDFFFEFEFEFFFEFE
+ FEFFFEFEFEFFC5C5C53AFFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00CC483F00CC483F00CC48
+ 3F00CC483F00CC483F00CC483F00CC483F000000000082B98800000000000000
+ 0000000000000000000000000000000000000000000000000000979D9B00FDFD
+ FD00DAE0DD00858A8800858A8800858A8800858A8800858A8800005CCE0000D4
+ F5003EAFFC000079F500005CCE0080ADE500C5C5C53AF4F4F3FFF3F3F2FF3A3E
+ BCFF060BC3FF3D40BCFFFAFAFAFFFBFBFBFFFCFCFCFFFCFCFCFFFDFDFDFFFDFD
+ FDFFFDFDFDFFC5C5C53AFFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00E8A20000E8A20000E8A2
+ 0000E8A20000E8A20000CC483F0080B585000000000000000000241CED00241C
+ ED00241CED00241CED00241CED00241CED000000000000000000999F9D00FDFD
+ FD00D9DFDC00D6DCDA00D6DDD900D5DCD900D5DCD900D5DCD900D6DCD900005C
+ CE0000D4F5003EAFFC000079F500005CCE00C5C5C53AF2F2F2FFF1F1F1FF3336
+ B3FF080CB8FF3738B4FFF9F9F9FFFAFAFAFFFBFBFBFFFBFBFBFFFCFCFCFFFCFC
+ FCFFFCFCFCFFC5C5C53AFFFFFF00FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00E8A20000E8A20000E8A2
+ 0000E8A20000CC483F0070AE760068AC6F000000000000000000241CED00285E
+ FD00285EFD00285EFD00241CED000000000000000000000000009BA19E00FDFD
+ FD00DAE0DC00858A8800858A8800858A8800858A8800858A8800858A8800858A
+ 8800005CCE0000D4F5003EAFFC00005CCE00C5C5C53AF1F1F0FFF0F0EFFF2C2E
+ AAFF0B0DADFF3031ABFFF7F7F7FFF9F9F9FFFAFAFAFFFAFAFAFF9CDE9CFF26C0
+ 26FF0AB10AFF1DB81DE2A1E1A15EFFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00E8A20000E8A20000E8A2
+ 0000CC483F0077B17C006BB374006FB7780052A95C0057AF6100241CED00285E
+ FD00285EFD00241CED00000000000000000000000000000000009CA2A000FDFD
+ FD00DCE3E000DAE0DD00D8DFDC00D7DEDB00D6DCD900D4DBD800D1D9D500CBD2
+ CE00C6CDC900005CCE00005CCE00A1C3EC00C5C5C53AEFEFEEFFEEEEEDFF2525
+ A1FF0D0EA2FF292AA2FFF5F5F5FFF7F7F7FFF8F8F8FF9BDE9BFF01B401FF00A9
+ 17FFFFFFFFFF00B234FF02B504FD9BE09B640000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00E8A20000E8A20000CC48
+ 3F005FA566006CB474009FD5A700A2D6AA00A5D8AD00A8D9AF00241CED00285E
+ FD00241CED00D9F1DC00000000000000000000000000000000009EA4A200FDFD
+ FD00E1E6E400858A8800858A8800858A8800858A8800D7DEDB00BBC1BF00AAB0
+ AC00B1B3B200D8DBD900BABFBD0000000000C5C5C53AEEEEEDFFECECECFF1D1E
+ 9DFF0D0EA1FF21219FFFF3F3F2FFF5F5F5FFF6F6F6FF22B522FF009F03FF00A0
+ 34FFFFFFFFFF00B064FF00B033FF22B522DD0000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00E8A20000CC483F000000
+ 00000000000080BE870075BE7E0079C282005DB7670060BC6B00241CED00241C
+ ED00D9F1DC000000000000000000000000000000000000000000A0A6A300FDFE
+ FD00E5E9E700E2E7E400E0E5E300DEE4E100DCE2DF00DAE0DD00C1C6C4000000
+ 0000FCFDFC00ABAFAD00E7E8E70000000000C5C5C53AECECEBFFEBEBEAFF1C1D
+ A5FF0B0DACFF1F21A7FFF0F0F0FFF2F2F2FFF3F3F3FF099509FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFF099709F60000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00CC483F00000000000000
+ 0000000000000000000083C68A007AC583000000000000000000241CED000000
+ 0000000000000000000000000000000000000000000000000000A1A7A500FEFE
+ FE00E9ECEB00E5E9E700E3E8E500E1E6E300DEE4E100DFE5E200D8DAD900FDFD
+ FD00BCC0BF00D2D5D4000000000000000000C5C5C53AEAE9E8FFE8E8E7FF2223
+ B1FF090CB7FF2427B1FFEEEEEDFFF0F0EFFFF1F1F0FF25AC25FF1DAF1DFF29B4
+ 3FFFFFFFFFFF29BC5AFF1DB531FF26AE26D90000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F0000000000000000000000
+ 00000000000000000000FDFEFD0096D49E000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000AEB3B100EDEF
+ EE000000000000000000000000000000000000000000F9FAF900E8E9E900AFB5
+ B200D3D5D400000000000000000000000000C5C5C53AEAEAEAFFE8E8E7FF282A
+ BCFF060BC3FF2A2CBCFFEEEEEDFFF0F0EFFFF1F1F0FF96D496FF36B736FF78D1
+ 78FFFFFFFFFF78D67AFF36BB36FD9FDC9F600000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000E4E6E500AFB5
+ B300A6ACAA00A6ACA900A5ABA900A5ABA800A5ABA800A6ACAA00BFC3C100E6E8
+ E70000000000000000000000000000000000EFEFEF10C5C5C53AC5C5C53A6A6D
+ DFF08183E5F9686ADEEEC5C5C53AC5C5C53AC5C5C53AC5C5C53A79B779863EB2
+ 3EE55EC45EF942B342E29BD99B64FFFFFF000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000050101002A0E0D00250D0B00250D
0B00260D0B0026090700000000007B7B7B00E6E6E60000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300A449A300A449A300A449
+ A300A449A3000000800000008000000080000000800000008000000080000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002A0F0C00F1554A00DE4E4400DF4E
4400F653480057181400D7DEDF001A1A1A0000000000D8D8D800000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300BD6ABD00BD6ABD000000
+ 8000000080000000800000008000000080000000800000008000000080000000
+ 8000000080000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000250D0B00DE4E4400CD483F00D948
3E003A020000D6E1E20000000000000000000000000000000000E6E6E6000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000A449A300BD6ABD00000080000000
+ 8000000080000000800000008000000080000000800000008000000080000000
+ 8000000080000000800000008000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000250D0B00DF4E4500D8483E004C1C
1800CAD8D900000000000000000000000000F4F4F40010101000000000000000
000000000000000000000000000000000000000000000000000000000000FFFF
FF00FFFFFF00D7D7D7000000000000000000D7D7D700FFFFFF00FFFFFF00FFFF
- FF00000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ FF0000000000000000000000000000000000A449A30000008000000080000000
+ 8000000080000000800023662700266B2B002A712F0053995A00569D5E000000
+ 8000000080000000800000008000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000260D0B00F65348003A020000CAD8
D900000000000000000000000000000000000000000084848400000000000000
000000000000000000000000000000000000000000000000000000000000FFFF
FF00FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFFFF009191
- 9100C3C3C3000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 9100C3C3C3000000000000000000000000000000800000008000000080000000
+ 800000008000000080000000800084C98E0087CA91008ACB94008DCD970060A7
+ 6800000080000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002609060056171300D6E1E2000000
0000000000000000000000000000000000000000000000000000000000006D6D
6D00000000000000000000000000000000000000000000000000000000009191
9100FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFFFF000000
- 0000FFFFFF000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 0000FFFFFF000000000000000000000000000000800000008000000080000000
+ 80000000800000008000000080000000800035803B005DA4650062A96A0075B1
+ 7B00000000000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000052525200000000000000
00000000000000000000000000000000000000000000DAE1E100000000000000
000000000000000000000000000000000000F7F7F7000A0A0A005B5B5B000000
0000000000000000000000000000000000000000000000000000000000000000
0000FFFFFF00FFFFFF009191910000000000C3C3C300FFFFFF00FFFFFF000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000080000000800000000000407C
+ 4400000080000000800000008000000080000000800062A3670071AE7700FEFE
+ FE00F9FCF9000000000000008000000080000000000000000000000000000000
0000000000000000000000000000000000005252520000000000000000000000
000000000000000000000000000000000000F1F1F10099999900F7F7F7000000
00000000000000000000000000000000000000000000E9E9E900000000000000
0000000000000000000000000000000000000000000000000000000000000000
000091919100FFFFFF009191910000000000C3C3C300FFFFFF00FFFFFF000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000800000008000CC483F00CC48
+ 3F00CC483F000000800000008000000080000000800000008000000000000000
+ 0000000000000000000000008000000080000000000000000000000000000000
0000000000000000000000000000525252000000000000000000000000000000
000000000000000000000000000000000000929292000000000000000000E9E9
E900DFDFDF00C2C3B600C5C6B700C5C6B700C5C6B700CACABC00C4C4C100CECE
CE00000000000000000000000000000000000000000000000000000000000000
000000000000C3C3C300C3C3C3000000000091919100FFFFFF00FFFFFF000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000800000008000E8A20000E8A2
+ 0000E8A20000E8A200000000800000008000000080000000800000008000241C
+ ED00241CED00241CED0000008000000080000000000000000000000000000000
0000000000000000000052525200000000000000000000000000000000000000
000000000000000000000000000000000000626262000000000078787800BBBB
BB004C4D40000000620000006E0000006C0000006D000000850000000000B3B4
B100000000000000000000000000000000000000000000000000D7D7D7000000
00000000000091919100C3C3C3000000000091919100FFFFFF00FFFFFF000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000800000008000E8A20000E8A2
+ 0000E8A20000CC483F0070AE7600000080000000800000008000000080000000
+ 8000285EFD00285EFD0000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000DADADA0000000000F1F1F1000000
0000505139001B11EF00261DFD00261DFB00251CFF0000006F00C9C9C3000000
000000000000000000000000000000000000000000000000000091919100FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ FF00FFFFFF00000000000000000000000000000080000000800000008000E8A2
+ 0000CC483F0077B17C006BB374006FB778000000800000008000000080000000
+ 8000000080000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000D0D0D00000000000F5F5F5000000
0000505139001910E300241CEF00261DFF0009066400CDCEB800000000000000
000000000000000000000000000000000000000000000000000000000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ FF00FFFFFF000000000000000000000000000000800000008000000080000000
+ 80005FA566006CB474009FD5A700A2D6AA00A5D8AD0000008000000080000000
+ 8000000080000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000C8C8C800000000003F3F3F009F9F
9F005D5E46001910E400261DFF0000005E007A7A6A00393A3C00000000000000
000000000000E8E8E8009C9C9C00000000000000000000000000000000009191
9100D7D7D700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ FF00FFFFFF00000000000000000000000000CC483F0000008000000080000000
+ 8000000080000000800075BE7E0079C282005DB7670060BC6B00000080000000
+ 8000000080000000800000008000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000007F7F7F00000000007373
730060614B00160DF00004006700D1D2BF00DBDBDB0000000000000000004B4B
4B00F8F8F800C8C8C80000000000ADADAD000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F00CC483F00000080000000
+ 8000000080000000800000008000000080000000800000008000000080000000
+ 8000000080000000800000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F50460000005900C3C4AD000000000000000000BDBDBD00666666000000
0000000000000000000000000000424242000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000CC483F0000000000000000000000
+ 8000000080000000800000008000000080000000800000008000000080000000
+ 8000000080000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00003D3D3D00C9C9BF000000000000000000000000000000000000000000C8C8
C800D4D4D400AFAFAF0043434300000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000800000008000000080000000800000008000000080000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@@ -5038,12 +5205,16 @@ object EditForm: TEditForm
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000424D3E000000000000003E000000
- 2800000040000000B00000000100010000000000800500000000000000000000
- 000000000000000000000000FFFFFF007FFF007FFFFF0000BBFF003FFFFF0000
- DFFF031FFFFF0000EBFF071FE30F0000F7FF0F9FE3070000A80A1F0FE3170000
- F99F3F1FF11F0000FA3F1FBFF11F0000FA71000FF91F0000F8B9000FD91F0000
- F9D5101FC0070000FBEF103FE0070000FFD70039E0070000FABB8000FFFF0000
- FE7DF180FFFF0000FA3EF3E1FFFF0000FFFFFFFF0001FFFFFFE7000100010000
+ 2800000040000000C00000000100010000000000000600000000000000000000
+ 000000000000000000000000FFFFFF0003FFC00100000000079FC1F900000000
+ 0F9FC00000000000100FC000000000002007C00000000000600FC00000000000
+ E187C0000000000000BFC0000000000000C0C0000000000000C1C00000000000
+ 0003C000000000000003C001000000001807C011000000003CDFC00300000000
+ 7CFFCF8700000000FFFFC00F000000007FFF007FFFFF001FBBFF003FFFFF0007
+ DFFF031FFFFF0001EBFF071FE30F0001F7FF0F9FE3070000A80A1F0FE3170008
+ F99F3F1FF11F2004FA3F1FBFF11F003CFA71000FF91F0000F8B9000FD91F0000
+ F9D5101FC0070000FBEF103FE0070000FFD70039E0070001FABB8000FFFF0003
+ FE7DF180FFFF6007FA3EF3E1FFFFF81FFFFFFFFF0001FFFFFFE7000100010000
FFC7000100010001000300010001000200010007000700070001000D000D000E
0003001F001F001FE027003D003D003EE02700570057002B0003003D00FD007E
0001031F03FF00FF0001068D06FD017E00030FC70FFF03FFFFC71EE11EFD077E
@@ -5265,6 +5436,18 @@ object EditForm: TEditForm
object N19: TMenuItem
Caption = '-'
end
+ object mnuCopyChaos: TMenuItem
+ Caption = 'Copy settings'
+ OnClick = mnuCopyChaosClick
+ end
+ object mnuPasteChaos: TMenuItem
+ Caption = 'Paste settings'
+ Enabled = False
+ OnClick = mnuPasteChaosClick
+ end
+ object N23: TMenuItem
+ Caption = '-'
+ end
object ShowChaosMatrix: TMenuItem
Caption = 'Show chaos matrix...'
OnClick = btnFullChaosClick
@@ -5389,31 +5572,56 @@ object EditForm: TEditForm
Caption = 'Use degrees'
Checked = True
end
+ object N22: TMenuItem
+ Caption = '-'
+ end
+ object mnuCalcExpression: TMenuItem
+ Caption = 'Calculate expression...'
+ OnClick = mnuCalcExpressionClick
+ end
end
object CopyMenu: TPopupMenu
Left = 305
Top = 241
- object Copytrianglecoordinates1: TMenuItem
+ object CopyTriangleCoordinates: TMenuItem
Caption = 'Copy Triangle Coordinates'
OnClick = btnCopyTriangleClick
end
- object Copytransform1: TMenuItem
+ object CopyTransform: TMenuItem
Caption = 'Copy Whole Transform'
- OnClick = Copytransform1Click
+ OnClick = CopyTransformClick
+ end
+ object CopyVariations: TMenuItem
+ Caption = 'Copy variations '
+ OnClick = CopyVariationsClick
+ end
+ object CopyChaos: TMenuItem
+ Caption = 'Copy chaos'
+ OnClick = mnuCopyChaosClick
end
end
object PasteMenu: TPopupMenu
Left = 385
Top = 233
- object Pastetrianglecoordinates1: TMenuItem
+ object PasteTriangleCoordinates: TMenuItem
Caption = 'Paste Triangle Coordinates'
Enabled = False
OnClick = btnPasteTriangleClick
end
- object Pastetransform1: TMenuItem
+ object PasteTransform: TMenuItem
Caption = 'Paste Transform(s)'
Enabled = False
- OnClick = Pastetransform1Click
+ OnClick = PasteTransformClick
+ end
+ object PasteVariations: TMenuItem
+ Caption = 'Paste variations'
+ Enabled = False
+ OnClick = PasteVariationsClick
+ end
+ object PasteChaos: TMenuItem
+ Caption = 'Paste chaos'
+ Enabled = False
+ OnClick = mnuPasteChaosClick
end
end
object TriangleOperations: TPopupMenu
@@ -5506,6 +5714,15 @@ object EditForm: TEditForm
Caption = '-'
GroupIndex = 5
end
+ object SynchronizeAll: TMenuItem
+ Caption = 'Apply operations to all triangles'
+ GroupIndex = 5
+ OnClick = SynchronizeAllClick
+ end
+ object N20: TMenuItem
+ Caption = '-'
+ GroupIndex = 5
+ end
object InvertMovevalue1: TMenuItem
Caption = 'Invert current Move step'
GroupIndex = 5
@@ -5934,4 +6151,10 @@ object EditForm: TEditForm
FE7FFC7FFFF7FFCFFF7FFC7FFFFFFFFF00000000000000000000000000000000
000000000000}
end
+ object mnuSyncTriangles: TPopupMenu
+ AutoHotkeys = maManual
+ OwnerDraw = True
+ Left = 377
+ Top = 369
+ end
end
diff --git a/Forms/Editor.pas b/Forms/Editor.pas
index 9050180..037ff04 100644
--- a/Forms/Editor.pas
+++ b/Forms/Editor.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -33,10 +33,10 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, ComCtrls, Math, Menus, ToolWin, Registry,
- Grids, ValEdit, Buttons, ImgList, Types, StrUtils , Curves,
+ Grids, ValEdit, Buttons, ImgList, Types, StrUtils,
ControlPoint, XForm, cmap, CustomDrawControl, ClipBrd,
- RenderingInterface, Translation, RenderThread, System.ImageList,
- Vcl.Samples.Spin;
+ RenderingInterface, RenderThread, System.ImageList,
+ Vcl.Samples.Spin, Vcl.GraphUtil;
type
TEditForm = class(TForm)
@@ -156,7 +156,7 @@ type
Panel2: TPanel;
PrevPnl: TPanel;
PreviewImage: TImage;
- GroupBox5: TGroupBox;
+ gbTrgOperations: TGroupBox;
btTrgRotateLeft90: TSpeedButton;
btTrgRotateRight90: TSpeedButton;
btTrgScaleDown: TSpeedButton;
@@ -170,7 +170,7 @@ type
txtTrgScaleValue: TComboBox;
txtTrgRotateValue: TComboBox;
txtTrgMoveValue: TComboBox;
- GroupBox6: TGroupBox;
+ gbCoordinates: TGroupBox;
LabelC: TLabel;
LabelA: TLabel;
LabelB: TLabel;
@@ -246,14 +246,14 @@ type
mnuEHighQuality: TMenuItem;
mnuEMediumQuality: TMenuItem;
mnuELowQuality: TMenuItem;
- Label4: TLabel;
+ lblSearch: TLabel;
txtSearchBox: TEdit;
ToolButton5: TToolButton;
btnMathPopup: TToolButton;
tbPreLink: TToolButton;
btnFullChaos: TToolButton;
btnResetSearch: TSpeedButton;
- GroupBox3: TGroupBox;
+ gbPivot: TGroupBox;
btnResetPivot: TSpeedButton;
btnPickPivot: TSpeedButton;
btnPivotMode: TSpeedButton;
@@ -273,10 +273,10 @@ type
Insert1sqrt21: TMenuItem;
CopyMenu: TPopupMenu;
PasteMenu: TPopupMenu;
- Copytrianglecoordinates1: TMenuItem;
- Copytransform1: TMenuItem;
- Pastetrianglecoordinates1: TMenuItem;
- Pastetransform1: TMenuItem;
+ CopyTriangleCoordinates: TMenuItem;
+ CopyTransform: TMenuItem;
+ PasteTriangleCoordinates: TMenuItem;
+ PasteTransform: TMenuItem;
Squareroots1: TMenuItem;
Insertsqrt361: TMenuItem;
Insertsqrt31: TMenuItem;
@@ -296,7 +296,7 @@ type
RotateY: TMenuItem;
ScaleO: TMenuItem;
RotateO: TMenuItem;
- GroupBox10: TGroupBox;
+ gbFlip: TGroupBox;
btnShowLine: TSpeedButton;
btnResetFlip: TSpeedButton;
btnFlip: TSpeedButton;
@@ -359,6 +359,22 @@ type
btnVarOrder: TBitBtn;
cbCollapseVariations: TComboBox;
btResetParams: TButton;
+ tbSyncTriangles: TToolButton;
+ mnuSyncTriangles: TPopupMenu;
+ SynchronizeAll: TMenuItem;
+ N20: TMenuItem;
+ CopyVariations: TMenuItem;
+ PasteVariations: TMenuItem;
+ ToolButton7: TToolButton;
+ tbComment: TToolButton;
+ mnuCalcExpression: TMenuItem;
+ N22: TMenuItem;
+ SaveFlameState: TToolButton;
+ N23: TMenuItem;
+ mnuCopyChaos: TMenuItem;
+ mnuPasteChaos: TMenuItem;
+ CopyChaos: TMenuItem;
+ PasteChaos: TMenuItem;
procedure btnResetSearchClick(Sender: TObject);
procedure txtSearchBoxKeyPress(Sender: TObject; var Key: Char);
// procedure txtSearchBoxChange(Sender: TObject);
@@ -422,8 +438,6 @@ type
procedure scrlXFormColorScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
procedure scrlXFormColorChange(Sender: TObject);
-// procedure chkUseXFormColorClick(Sender: TObject);
-// procedure chkHelpersClick(Sender: TObject);
procedure txtXFormColorExit(Sender: TObject);
procedure txtXFormColorKeyPress(Sender: TObject; var Key: Char);
procedure txtSymmetrySet(Sender: TObject);
@@ -450,7 +464,6 @@ type
procedure tbEditModeClick(Sender: TObject);
procedure ValidateVariation;
-// procedure ValidateValue(Sender: TObject);
procedure VEVarsKeyPress(Sender: TObject; var Key: Char);
procedure VEVarsChange(Sender: TObject);
procedure VEVarsValidate(Sender: TObject; ACol, ARow: Integer;
@@ -523,7 +536,6 @@ type
Rect: TRect; State: TGridDrawState);
procedure mnuChaosViewToClick(Sender: TObject);
procedure mnuChaosViewFromClick(Sender: TObject);
- // procedure chkPlotModeClick(Sender: TObject);
procedure mnuChaosClearAllClick(Sender: TObject);
procedure mnuChaosSetAllClick(Sender: TObject);
procedure mnuLinkPostxformClick(Sender: TObject);
@@ -541,12 +553,11 @@ type
procedure bClearClick(Sender: TObject);
procedure ColorBarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
- // procedure btnLoadVVARClick(Sender: TObject);
procedure txtNameKeyPress(Sender: TObject; var Key: Char);
procedure txtNameExit(Sender: TObject);
procedure InsertPi1Click(Sender: TObject);
- procedure Copytransform1Click(Sender: TObject);
- procedure Pastetransform1Click(Sender: TObject);
+ procedure CopyTransformClick(Sender: TObject);
+ procedure PasteTransformClick(Sender: TObject);
procedure btResetparamsClick(Sender: TObject);
procedure SpinButtonDownClick(Sender: TObject);
procedure SpinButtonUpClick(Sender: TObject);
@@ -577,13 +588,22 @@ type
procedure mnuResetTrgFlipClick(Sender: TObject);
procedure btChaosClick(Sender: TObject);
procedure mnuChangeGridClick(Sender: TObject);
-// procedure btnInvisibleClick(Sender: TObject);
-// procedure btnSoloClick(Sender: TObject);
procedure ExtSysMenu(var Msg: TMessage); message WM_SysCommand;
procedure TriangleOperationsClick(Sender: TObject);
procedure btnFullChaosClick(Sender: TObject);
procedure btnVarOrderClick(Sender: TObject);
- procedure FormShortCut(var Msg: TWMKey; var Handled: Boolean); // AV
+ procedure FormShortCut(var Msg: TWMKey; var Handled: Boolean);
+ procedure tbSyncTrianglesClick(Sender: TObject);
+ procedure SynchronizeAllClick(Sender: TObject);
+ procedure SyncTrianglesDrawItem(Sender: TObject; ACanvas: TCanvas;
+ ARect: TRect; State: TOwnerDrawState);
+ procedure CopyVariationsClick(Sender: TObject);
+ procedure PasteVariationsClick(Sender: TObject);
+ procedure tbCommentClick(Sender: TObject);
+ procedure mnuCalcExpressionClick(Sender: TObject); // AV
+ procedure SaveFlameStateClick(Sender: TObject);
+ procedure mnuCopyChaosClick(Sender: TObject);
+ procedure mnuPasteChaosClick(Sender: TObject); // AV
private
TriangleView: TCustomDrawControl;
cmap: TColorMap;
@@ -614,6 +634,7 @@ type
showVarPreview: boolean;
ShowFlipLine: boolean; // AV
hasLinkX: boolean; // AV
+ SyncTriangles: set of 0..NXFORMS; // AV: to change several triangles at time
GraphZoom: double;
TriangleCaught, CornerCaught, EdgeCaught: boolean;
@@ -631,9 +652,9 @@ type
oldx, oldy, olddist: double;
Pivot, FlipPoint, fl: TSPoint;
- VarsCache: array of double; // AV: now length is sets dynamically
// hack: to prevent slow valuelist redraw
- // -JF- 64 wasn't big enough... buffer overrun
+ VarsCache: array of double; // AV: now length is sets dynamically
+ MemChaos: array of double; // AV
BackgroundBmp : TBitmap;
Renderer : TRenderThread;
@@ -657,13 +678,20 @@ type
procedure ShowSelectedInfo;
procedure Scale(var fx, fy: double; x, y: integer);
+ procedure RotateTriangleBy(const angle: double); // AV
procedure TriangleViewPaint(Sender: TObject);
procedure AutoZoom;
procedure KeyInput(str: string);
procedure CalcFlip;
- function ValidNumField: boolean; inline; // AV: check active edit
+ function ValidNumField: boolean; inline; // AV: check active control
+
+ // AV: methods to synchronize tranformations of triangles
+ procedure FillSyncTrianglesMenu;
+ procedure AdjustSyncTriangles;
+ procedure SyncTrianglesClick(Sender: TObject);
+ procedure UpdateSyncTriangles;
public
cp: TControlPoint;
Render: TRenderer;
@@ -674,18 +702,19 @@ type
LocalPivot, WorldPivot: TSPoint;
procedure UpdatePreview;
- procedure UpdateDisplay(PreviewOnly: boolean = false); //(?)
+ procedure UpdateDisplay(PreviewOnly: boolean = false);
function GetTriangleColor(n: integer): TColor;
function LastTriangle: integer;
function InsideTriangle(x, y: double): integer;
procedure ScriptGetPivot(var px, py: double);
- // procedure InvokeResetAll;
+
procedure UpdateColorBar;
procedure PaintBackground;
procedure CreateScreenShot;
+
procedure RedrawButtons;
end;
@@ -697,21 +726,27 @@ const
$0000ff, $00cccc, $00cc00, $cccc00, $ff4040, $cc00cc, $0080cc,
$4f0080, $228080, $608060, $808050, $804f4f, $805080, $226080 );
+ saved_variations = 'Variations.list';
+ saved_variables = 'Variables.list';
+
var
EditForm: TEditForm;
function ColorValToColor(c: TColorMap; index: double): TColor;
+
function FlipTriangleVertical(t: TTriangle): TTriangle;
function FlipTriangleHorizontal(t: TTriangle): TTriangle;
function RotateTriangle(t: TTriangle; rad: double): TTriangle;
-function OffsetTriangle(t: TTriangle; range: double): TTriangle;
function ScaleTriangle(t: TTriangle; scale: double): TTriangle;
-function RotateTriangleCenter(t: TTriangle; rad: double): TTriangle;
function RotateTrianglePoint(t: TTriangle; xr, yr: double; rad: double): TTriangle;
-function Centroid(t: TTriangle): TSPoint;
-function OffsetTriangleRandom(t: TTriangle): TTriangle;
-function ScaleTriangleCenter(t: TTriangle; scale: double): TTriangle;
function ScaleTrianglePoint(t: TTriangle; x, y, scale: double): TTriangle;
+{
+function Centroid(t: TTriangle): TSPoint;
+function RotateTriangleCenter(t: TTriangle; rad: double): TTriangle;
+function ScaleTriangleCenter(t: TTriangle; scale: double): TTriangle;
+function OffsetTriangle(t: TTriangle; range: double): TTriangle;
+function OffsetTriangleRandom(t: TTriangle): TTriangle;
+}
// AV: new operations
function ScaleTriangleXY(t: TTriangle; axis: integer; scale: double): TTriangle;
function ScaleTriangleO(t: TTriangle; x, y, scale: double): TTriangle;
@@ -722,7 +757,8 @@ function FlipTriangleLine(t: TTriangle; x, y, fx, fy: double): TTriangle;
implementation
uses
- Main, Global, Adjust, Mutate, XformMan, Chaos, VarOrderForm;
+ Main, Global, Adjust, Mutate, XformMan, Translation,
+ Chaos, VarOrderForm, FlameComment, MathExpressions;
{$R *.DFM}
@@ -941,13 +977,13 @@ end;
procedure TEditForm.UpdateVariationList; // AV: adjust the var_order
var
- i: integer;
+ s: string;
svars: TStringList;
begin
svars := TStringList.Create;
with cp.xform[SelectedTriangle] do
- for i := 0 to NrVar-1 do
- svars.AddPair(ifs[i], Round6(GetVariation(GetVariationIndex(ifs[i]))).ToString);
+ for s in ifs do
+ svars.AddPair(s, Round6(GetVariation(GetVariationIndex(s))).ToString);
VEVars.Strings.Assign(svars);
svars.Free;
end;
@@ -976,6 +1012,15 @@ begin
UpdateVariationList; // AV
chkCollapseVariablesClick(nil);
chkCollapseVariationsClick(nil);
+
+ FillSyncTrianglesMenu; // AV
+ if (SelectedTriangle < Transforms) and (SelectedTriangle >= 0) then
+ begin
+ mnuSyncTriangles.Items[SelectedTriangle].Checked := True;
+ SyncTriangles := [SelectedTriangle];
+ end
+ else
+ SyncTriangles := [];
end;
procedure TEditForm.UpdateDisplay(PreviewOnly: boolean = false);
@@ -1153,6 +1198,8 @@ begin
btChaos.Visible := True; // AV
btClearChaos.Visible := True; // AV
btResetChaos.Visible := True; // AV
+ CopyChaos.Enabled := True; // AV
+ PasteChaos.Enabled := length(MemChaos) <> 0; // AV
if cp.soloXform >= 0 then begin
chkXformSolo.Checked := true;
@@ -1171,6 +1218,8 @@ begin
btChaos.Visible := False; // AV
btClearChaos.Visible := False; // AV
btResetChaos.Visible := False; // AV
+ CopyChaos.Enabled := False; // AV
+ PasteChaos.Enabled := False; // AV
optTo.Enabled := False; // AV
optFrom.Enabled := False; // AV
//chkXformInvisible.Enabled := false;
@@ -1233,6 +1282,7 @@ begin
end;
//AV: moved checks here since Apo7X didn't refresh these pages well
+ // if cbCollapseVariations.ItemIndex = 1 then
chkCollapseVariationsClick(nil);
chkCollapseVariablesClick(nil);
@@ -1255,7 +1305,102 @@ begin
updating := false;
end;
-///////////////////////////////////////////////////
+{/////////////////////////////////////////////////// }
+
+ procedure TEditForm.FillSyncTrianglesMenu; // AV
+ var
+ i: byte;
+ t: TMenuItem;
+ pic: TBitMap;
+ defStyle: boolean;
+ begin
+ mnuSyncTriangles.Items.Clear;
+
+ pic := TBitmap.Create;
+ pic.Width := 16;
+ pic.Height := 16;
+
+ if (CurrentStyle = 'Windows') then
+ begin
+ pic.Transparent := True;
+ pic.TransparentColor := clWhite;
+ defStyle := True;
+ end
+ else
+ defStyle := False;
+
+ for i := 0 to Transforms - 1 do
+ begin
+ t := TMenuItem.Create(self);
+ t.Caption := IntToStr(i + 1);
+ t.Tag := i;
+ t.AutoCheck := True;
+ with pic.Canvas do
+ begin
+ brush.Color := clWhite;
+ FillRect(Rect(0, 0, 16, 16));
+ pen.Color := TrgColors[i mod 14];
+ brush.Color := pen.Color shr 1 and $7f7f7f;
+ Polygon([Point(15, 5), Point(15, 15), Point(5, 15)]);
+ end;
+ t.Bitmap.Assign(pic);
+ t.OnClick := SyncTrianglesClick;
+ if defStyle then
+ t.OnAdvancedDrawItem := SyncTrianglesDrawItem
+ else
+ // AV: it's better to rely on RTL rather than adjust colors for every theme manually
+ t.OnAdvancedDrawItem := nil;
+ mnuSyncTriangles.Items.Add(t);
+ end;
+ pic.Free;
+
+ i := 0;
+ while i < mnuSyncTriangles.Items.Count do
+ begin
+ mnuSyncTriangles.Items[i].Break := mbBreak;
+ inc(i, mbHeight);
+ end;
+ end;
+
+ procedure TEditForm.SynchronizeAllClick(Sender: TObject);
+ var i: smallint;
+ begin
+ for i := 0 to mnuSyncTriangles.Items.Count - 1 do
+ begin
+ mnuSyncTriangles.Items[i].Checked := True;
+ Include(SyncTriangles, i);
+ end;
+ end;
+
+ procedure TEditForm.SyncTrianglesClick(Sender: TObject); // AV
+ begin
+ if (SelectedTriangle < Transforms) and
+ (Sender = mnuSyncTriangles.Items[SelectedTriangle]) then
+ TMenuItem(Sender).Checked := True;
+ if TMenuItem(Sender).Checked then
+ Include(SyncTriangles, TMenuItem(Sender).Tag)
+ else
+ Exclude(SyncTriangles, TMenuItem(Sender).Tag);
+ end;
+
+procedure TEditForm.SyncTrianglesDrawItem(Sender: TObject; ACanvas: TCanvas;
+ ARect: TRect; State: TOwnerDrawState);
+begin
+ ACanvas.Draw(ARect.Left + 10, ARect.Top, TMenuItem(Sender).Bitmap);
+ if not (odSelected in State) then
+ begin
+ ACanvas.Brush.Color := clMenu;
+ ACanvas.Font.Color := clMenuText;
+ end;
+ if TMenuItem(Sender).Tag = SelectedTriangle then
+ ACanvas.Font.Style := [fsBold];
+ ACanvas.TextOut(ARect.Left + 30, ARect.Top + 2, TMenuItem(Sender).Caption);
+ if (odChecked in State) then
+ DrawCheck(ACanvas, Point(ARect.Left + 5, ARect.Top + 10), 3);
+end;
+
+{/////////////////////////////////////////////////// }
+
procedure TEditForm.CreateScreenShot;
begin
SaveScreenShot('Apophysis Transform Editor');
@@ -1365,7 +1510,7 @@ begin
if not AllowResetCoefs then exit;
with TEdit(Sender) do // restore defaults
begin
- if (Parent = GroupBox6) or btnCoefsRect.Down then
+ if (Parent = gbCoordinates) or btnCoefsRect.Down then
num := IntToStr(Tag)
else // if btnCoefsPolar.Down then
begin
@@ -1434,7 +1579,6 @@ begin
cp.GetFromTriangles(MainTriangles, LastTriangle);
-// if not chkPreserve.Checked then ComputeWeights(cp, MainTriangles, transforms);
DrawPreview;
ShowSelectedInfo;
TriangleView.Refresh;
@@ -1451,7 +1595,6 @@ begin
end;
if AdjustForm.Visible then AdjustForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
- if CurvesForm.Visible then CurvesForm.SetCp(MainCp);
MainForm.RedrawTimer.enabled := true;
end;
@@ -1618,7 +1761,7 @@ begin
if (not ValidNumField) then
begin
Application.MessageBox(PChar(TextByKey('editor-status-nonumfield')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
exit;
end
else if (ActiveControl = txtTrgRotateValue) then exit;
@@ -1751,7 +1894,7 @@ begin
txtTrgRotateValue.Text := Format('%.6g', [t]);
end else
Application.MessageBox(PChar(TextByKey('editor-status-warnscale')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
except
Beep;
end;
@@ -1765,7 +1908,7 @@ begin
if (not ValidNumField) then
begin
Application.MessageBox(PChar(TextByKey('editor-status-nonumfield')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
exit;
end;
@@ -1806,6 +1949,53 @@ begin
end;
end;
+procedure TEditForm.mnuCalcExpressionClick(Sender: TObject); // AV
+var
+ sn: string;
+begin
+ if (not ValidNumField) then
+ begin
+ Application.MessageBox(PChar(TextByKey('editor-status-nonumfield')),
+ ApophysisSVN, MB_ICONWARNING);
+ exit;
+ end;
+
+ try
+ if (ActiveControl is TEdit) then
+ sn := TEdit(ActiveControl).Text
+ else if (ActiveControl is TValueListEditor) then
+ sn := TValueListEditor(ActiveControl).Cells[1,
+ TValueListEditor(ActiveControl).Row]
+ else // if (ActiveControl is TComboBox) then
+ sn := TComboBox(ActiveControl).Text;
+
+ if not InputQuery(TextByKey('editor-toolbar-calcexpression'),
+ TextByKey('editor-status-formula'), sn) then exit;
+
+ MathExpressions.InDegrees := UseDegrees.Checked;
+ sn := MathExpressions.CalculateExpression(LowerCase(sn));
+ if sn = '' then exit; // expression is not evaluated
+
+ if (ActiveControl is TEdit) then
+ begin
+ TEdit(ActiveControl).Text := sn;
+ TEdit(ActiveControl).OnExit(ActiveControl);
+ end
+ else if (ActiveControl is TValueListEditor) then
+ begin
+ TValueListEditor(ActiveControl).Cells[1,
+ TValueListEditor(ActiveControl).Row] := sn;
+ TValueListEditor(ActiveControl).OnExit(ActiveControl);
+ end
+ else //if (ActiveControl is TComboBox) then
+ TComboBox(ActiveControl).Text := sn;
+
+ except
+ Application.MessageBox(PChar(TextByKey('formula-cannotevaluate')),
+ ApophysisSVN, 16);
+ end;
+end;
+
procedure TEditForm.TriangleViewPaint(Sender: TObject);
const
foc_ofs = 4;
@@ -1974,12 +2164,9 @@ begin
bm.Height := p1;
bm.Assign(Render.GetImage);
- //Windows.BitBlt(Handle, 0, 0,
Windows.AlphaBlend(Handle, 0, 0,
- TriangleView.Width, TriangleView.Height,
- bm.Canvas.Handle, 0, 0,
- //$CC0020);
- bm.Width, bm.Height, bf);
+ TriangleView.Width, TriangleView.Height,
+ bm.Canvas.Handle, 0, 0, bm.Width, bm.Height, bf);
RenderCp.Destroy;
try
@@ -2512,16 +2699,21 @@ begin
mnuHighQuality.Caption := TextByKey('common-highquality');
tbCopy.Hint := TextByKey('common-copy');
tbCopyTriangle.Hint := TextByKey('editor-popup-transform-copycoords');
- Copytrianglecoordinates1.Caption := TextByKey('editor-popup-transform-copycoords');
- Copytransform1.Caption := TextByKey('editor-popup-transform-copywhole');
+ CopyTriangleCoordinates.Caption := TextByKey('editor-popup-transform-copycoords');
+ CopyTransform.Caption := TextByKey('editor-popup-transform-copywhole');
+ CopyVariations.Caption := TextByKey('editor-popup-transform-copyvars');
tbPaste.Hint := TextByKey('common-paste');
tbPasteTriangle.Hint := TextByKey('editor-popup-transform-pastecoords');
- Pastetrianglecoordinates1.Caption := TextByKey('editor-popup-transform-pastecoords');
- Pastetransform1.Caption := TextByKey('editor-popup-transform-pastewhole');
- tbUndo.Caption := TextByKey('common-undo');
+ PasteTriangleCoordinates.Caption := TextByKey('editor-popup-transform-pastecoords');
+ PasteTransform.Caption := TextByKey('editor-popup-transform-pastewhole');
+ PasteVariations.Caption := TextByKey('editor-popup-transform-pastevars');
+ CopyChaos.Caption := TextByKey('editor-popup-chaos-copy');
+ PasteChaos.Caption := TextByKey('editor-popup-chaos-paste');
+ mnuCopyChaos.Caption := CopyChaos.Caption;
+ mnuPasteChaos.Caption := PasteChaos.Caption;
+
tbUndo.Hint := TextByKey('common-undo');
mnuUndo.Caption := TextByKey('common-undo');
- tbRedo.Caption := TextByKey('common-redo');
tbRedo.Hint := TextByKey('common-redo');
mnuRedo.Caption := TextByKey('common-redo');
bClear.Caption := TextByKey('common-clear');
@@ -2534,14 +2726,17 @@ begin
Panel1.Caption := TextByKey('editor-common-transform');
Panel2.Caption := TextByKey('editor-common-name');
pnlWeight.Caption := TextByKey('editor-common-weight');
+ tbComment.Hint := TextByKey('editor-common-editcomment');
+ SaveFlameState.Hint := TextByKey('editor-toolbar-savestate');
tabVariations.Caption := TextByKey('editor-tab-variations-title');
VEVars.TitleCaptions[0] := TextByKey('editor-tab-variations-name');
VEVars.TitleCaptions[1] := TextByKey('editor-tab-variations-value');
- //chkCollapseVariations.Caption := TextByKey('editor-tab-variations-togglehideunused');
cbCollapseVariations.Items[0] := TextByKey('editor-tab-variations-toggleshowall');
cbCollapseVariations.Items[1] := TextByKey('editor-tab-variations-togglehideunused');
cbCollapseVariations.Items[2] := TextByKey('editor-tab-variations-togglefavourites');
+ cbCollapseVariations.Items[3] := TextByKey('editor-tab-variations-toggle3d');
+ cbCollapseVariations.Items[4] := TextByKey('editor-tab-variations-toggledc');
btnVarOrder.Caption := TextByKey('editor-tab-variations-order');
btnVarOrder.Hint := TextByKey('editor-tab-variations-orderhint');
TabVariables.Caption := TextByKey('editor-tab-variables-title');
@@ -2557,7 +2752,7 @@ begin
optFrom.Caption := TextByKey('editor-tab-chaos-viewasfrom');
mnuChaosViewFrom.Caption := TextByKey('editor-tab-chaos-viewasfrom');
TriangleTab.Caption := TextByKey('editor-tab-triangle-title');
- GroupBox3.Caption := TextByKey('editor-tab-triangle-pivot');
+ gbPivot.Caption := TextByKey('editor-tab-triangle-pivot');
GroupBox7.Caption := TextByKey('editor-tab-transform-coordsystem');
GroupBox9.Caption := TextByKey('editor-tab-transform-affine');
GroupBox8.Caption := TextByKey('editor-tab-transform-postaffine');
@@ -2614,9 +2809,9 @@ begin
pnlDC.Caption := TextByKey('editor-tab-color-directcolor');
chkXFormSolo.Caption := TextByKey('editor-tab-color-togglesolo');
GroupBox2.Caption := TextByKey('editor-tab-color-varpreview');
- GroupBox10.Caption := TextByKey('editor-tab-triangle-reflection');
- GroupBox5.Caption := TextByKey('editor-tab-triangle-transforms');
- GroupBox6.Caption := TextByKey('editor-tab-triangle-coordinates');
+ gbFlip.Caption := TextByKey('editor-tab-triangle-reflection');
+ gbTrgOperations.Caption := TextByKey('editor-tab-triangle-transforms');
+ gbCoordinates.Caption := TextByKey('editor-tab-triangle-coordinates');
btnResetFlip.Hint := TextByKey('editor-tab-triangle-resetflip');
Label1.Caption := TextByKey('editor-tab-color-previewrange');
Label2.Caption := TextByKey('editor-tab-color-previewdepth');
@@ -2624,7 +2819,8 @@ begin
Label1.Hint := TextByKey('editor-tab-color-previewrangehint');
Label2.Hint := TextByKey('editor-tab-color-previewdepthhint');
Label3.Hint := TextByKey('editor-tab-color-previewdensityhint');
- Label4.Caption := TextByKey('editor-tab-variations-search'); // AV
+ lblSearch.Caption := TextByKey('editor-tab-variations-search'); // AV
+ txtSearchBox.TextHint := TextByKey('editor-tab-variations-searchhint'); // AV
tbResetAll.Hint := TextByKey('editor-toolbar-newflame');
tbAdd.Hint := TextByKey('editor-toolbar-newtransform');
mnuAdd.Caption := TextByKey('editor-toolbar-newtransform');
@@ -2672,6 +2868,7 @@ begin
mnuExtendedEdit.Caption := TextByKey('editor-popup-panel-toggleextendededit');
tbAxisLock.Hint := TextByKey('editor-popup-panel-locktransformaxes');
mnuAxisLock.Caption := TextByKey('editor-popup-panel-locktransformaxes');
+ SynchronizeAll.Caption := TextByKey('editor-tab-triangle-syncall');
btnShowLine.Caption := TextByKey('editor-tab-triangle-showline');
btnShowLine.Hint := TextByKey('editor-tab-triangle-showlinehint');
btnFlip.Caption := TextByKey('editor-tab-triangle-fliptriangle');
@@ -2720,7 +2917,7 @@ begin
GridComboBox.ItemIndex := 0;
lblGridType.Caption := TextByKey('editor-grid-type');
lblGridType.Hint := TextByKey('editor-grid-typehint');
- GroupBox5.Hint := StringReplace(TextByKey('editor-tab-triangle-transformshint'),
+ gbTrgOperations.Hint := StringReplace(TextByKey('editor-tab-triangle-transformshint'),
',', ','#13, [rfReplaceAll]);
// Math constants
RedrawButtons;
@@ -2748,6 +2945,7 @@ begin
CalcSin.Caption := TextByKey('editor-toolbar-calcsin');
CalcTan.Caption := TextByKey('editor-toolbar-calctan');
UseDegrees.Caption := TextByKey('editor-toolbar-usedegrees');
+ mnuCalcExpression.Caption := TextByKey('editor-toolbar-calcexpression');
ExtSM := GetSystemMenu(Handle, False); // AV
InsertMenu(ExtSM, UINT(5), MF_ByPosition or MF_Separator, 0, nil);
@@ -2813,9 +3011,8 @@ begin
AxisLock := TransformAxisLock;
tbAxisLock.Down := AxisLock;
ExtendedEdit := ExtEditEnabled;
-// tbExtendedEdit.Down := ExtendedEdit;
+ // tbExtendedEdit.Down := ExtendedEdit;
widgetMode := modeRotate;
-// tbExtendedEdit.ImageIndex := imgExtMove;
ShowFlipLine := False;
hasLinkX := False;
@@ -2911,8 +3108,8 @@ begin
end;
end;
- // MainForm.Buttons.GetBitmap(9, btnResetPivot.Glyph);
- // btnResetFlip.Glyph.Assign(btnResetPivot.Glyph);
+ // MainForm.Buttons.GetBitmap(9, btnResetPivot.Glyph);
+ // MainForm.Buttons.GetBitmap(9, btnResetFlip.Glyph);
PageControl.ActivePage := tabVariations; // AV
cbCollapseVariations.ItemIndex := 0; // AV
@@ -2922,6 +3119,8 @@ procedure TEditForm.FormDestroy(Sender: TObject);
begin
cp.free;
Render.free;
+ if FileExists(APPDATA + saved_variations) then DeleteFile(APPDATA + saved_variations);
+ if FileExists(APPDATA + saved_variables) then DeleteFile(APPDATA + saved_variables);
end;
procedure TEditForm.TriangleViewMouseMove(Sender: TObject; Shift: TShiftState;
@@ -3375,7 +3574,7 @@ begin
SelectedCorner := j;
// Pivot := GetPivot;
- if (j = 1) then //and ((rgPivot.ItemIndex = 1) or (rgPivot.ItemIndex = 4)) then
+ if (j = 1) then
begin
if PivotMode = pivotLocal then begin
Pivot.x := 0;
@@ -3397,6 +3596,7 @@ begin
HasChanged := false;
ShowSelectedInfo;
TriangleView.Invalidate;
+ UpdateSyncTriangles; // AV
exit;
end;
end;
@@ -3442,24 +3642,25 @@ begin
else
if AxisLock then editMode := modeRotate
else
-begin
- // hacky...
- CornerCaught := True;
- editMode := modeRotate;
- if j = 1 then SelectedCorner := 2
- else SelectedCorner := 0;
- Pivot := GetPivot;
- LocalAxisLocked := false;
- OldTriangle := MainTriangles[SelectedTriangle];
- oldx := MainTriangles[SelectedTriangle].x[SelectedCorner] - Pivot.X;
- oldy := MainTriangles[SelectedTriangle].y[SelectedCorner] - Pivot.Y;
- olddist := sqrt(sqr(oldx) + sqr(oldy));
+ begin
+ // hacky...
+ CornerCaught := True;
+ editMode := modeRotate;
+ if j = 1 then SelectedCorner := 2
+ else SelectedCorner := 0;
+ Pivot := GetPivot;
+ LocalAxisLocked := false;
+ OldTriangle := MainTriangles[SelectedTriangle];
+ oldx := MainTriangles[SelectedTriangle].x[SelectedCorner] - Pivot.X;
+ oldy := MainTriangles[SelectedTriangle].y[SelectedCorner] - Pivot.Y;
+ olddist := sqrt(sqr(oldx) + sqr(oldy));
- HasChanged := false;
- ShowSelectedInfo;
- TriangleView.Invalidate;
- exit;
-end;
+ HasChanged := false;
+ ShowSelectedInfo;
+ TriangleView.Invalidate;
+ UpdateSyncTriangles; // AV
+ exit;
+ end;
end;
goto FoundTriangle;
end;
@@ -3490,7 +3691,9 @@ FoundTriangle:
olddist := sqrt(oldx*oldx + oldy*oldy);
UpdateVariationList; // AV
- ShowSelectedInfo;
+ UpdateSyncTriangles; // AV
+
+ ShowSelectedInfo;
TriangleView.Invalidate;
exit;
end
@@ -3662,12 +3865,12 @@ begin
finally
Registry.Free;
end;
-// chkUseXFormColor.checked := UseTransformColors;
-// chkHelpers.Checked := HelpersEnabled;
if ExtendedEdit then tbExtendedEdit.Down := true
else tbMove.Down := true;
+ AdjustSyncTriangles; // AV
+
UpdateDisplay;
TrianglePanelResize(nil);
ScrollBox1Resize(nil);
@@ -3741,11 +3944,11 @@ begin
begin
with cp.xform[SelectedTriangle] do
begin
- deta := det(c[0,0], c[0,1], c[1,0], c[1,1]);
+ deta := detC; // pre-affine determinant
if (abs(deta) < 1E-4) then
begin
Application.MessageBox(PChar(TextByKey('editor-status-warninvert')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
exit;
end;
MainForm.UpdateUndo;
@@ -3761,11 +3964,11 @@ begin
begin
with cp.xform[SelectedTriangle] do
begin
- deta := det(p[0,0], p[0,1], p[1,0], p[1,1]);
+ deta := detP; // post-affine determinant
if (abs(deta) < 1E-4) then
begin
Application.MessageBox(PChar(TextByKey('editor-status-warninvert')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
exit;
end;
MainForm.UpdateUndo;
@@ -3800,8 +4003,8 @@ begin
FlipPoint.x := 1; editFlipX.Text := '1';
FlipPoint.y := 1; editFlipY.Text := '1';
end;
- if not ShowFlipLine then CalcFlip; // refresh current angle
- TriangleView.Invalidate;
+ if not ShowFlipLine then CalcFlip // refresh current angle
+ else TriangleView.Invalidate; // refresh angle and image
end;
procedure TEditForm.btnCloseClick(Sender: TObject);
@@ -4046,6 +4249,11 @@ begin
finally
Registry.Free;
end;
+
+ // AV: free memory
+ SetLength(MemChaos, 0);
+ mnuPasteChaos.Enabled := False;
+ PasteChaos.Enabled := False;
end;
procedure TEditForm.mnuUndoClick(Sender: TObject);
@@ -4061,7 +4269,7 @@ begin
if (not ValidNumField) then
begin
Application.MessageBox(PChar(TextByKey('editor-status-nonumfield')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
exit;
end;
@@ -4078,8 +4286,8 @@ begin
begin
case TMenuItem(Sender).Tag of
0: if (txtTrgScaleValue.Focused) then
- sn := Format('%.6g', [num * num * 0.01])
- else sn := Format('%.6g', [num * num]);
+ sn := Format('%.6g', [num * num * 0.01])
+ else sn := Format('%.6g', [num * num]);
1: sn := Format('%.6g', [num * 2]);
2: sn := Format('%.6g', [num * 0.5]);
else if (txtTrgScaleValue.Focused) then
@@ -4105,7 +4313,7 @@ begin
end;
procedure TEditForm.NormChaosClick(Sender: TObject);
-var i, j: integer;
+var i, j: smallint;
sum: double;
begin
MainForm.UpdateUndo;
@@ -4114,10 +4322,9 @@ begin
sum := 0;
for j := 0 to Transforms-1 do
sum := sum + cp.xform[i].modWeights[j];
- if sum = 1.0 then Exit;
- if (sum > 0) then
- for j := 0 to Transforms-1 do
- cp.xform[i].modWeights[j] := cp.xform[i].modWeights[j] / sum;
+ if (sum = 1.0) or (sum = 0.0) then continue;
+ for j := 0 to Transforms-1 do
+ cp.xform[i].modWeights[j] := cp.xform[i].modWeights[j] / sum;
end;
UpdateFlame(True);
if ChaosForm.Visible then // AV
@@ -4180,7 +4387,7 @@ end;
procedure TEditForm.mnuFlipAllVClick(Sender: TObject);
var
- i: integer;
+ i: smallint;
begin
MainForm.UpdateUndo;
for i := -1 to Transforms do
@@ -4195,7 +4402,7 @@ end;
procedure TEditForm.mnuFlipAllHClick(Sender: TObject);
var
- i: integer;
+ i: smallint;
begin
MainForm.UpdateUndo;
for i := -1 to Transforms do
@@ -4210,7 +4417,7 @@ end;
procedure TEditForm.mnuFlipAllLineClick(Sender: TObject); // AV
var
- i: integer;
+ i: smallint;
begin
if (FlipPoint.x = 0) and (FlipPoint.y = 0) then exit;
if (FlipPoint.x = 0) then mnuFlipAllH.Click
@@ -4230,15 +4437,25 @@ end;
procedure TEditForm.mnuFlipVerticalClick(Sender: TObject);
var
p: double;
+ i: integer;
begin
MainForm.UpdateUndo;
- with MainTriangles[SelectedTriangle] do
- begin
- p := GetPivot.y * 2;
- y[0] := p - y[0];
- y[1] := p - y[1];
- y[2] := p - y[2];
- end;
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ with MainTriangles[SelectedTriangle] do
+ begin
+ p := GetPivot.y * 2;
+ y[0] := p - y[0];
+ y[1] := p - y[1];
+ y[2] := p - y[2];
+ end
+ else for i in SyncTriangles do
+ with MainTriangles[i] do
+ begin
+ p := GetPivot(i).y * 2;
+ y[0] := p - y[0];
+ y[1] := p - y[1];
+ y[2] := p - y[2];
+ end;;
//AutoZoom;
UpdateFlame(True);
end;
@@ -4246,22 +4463,32 @@ end;
procedure TEditForm.mnuFlipHorizontalClick(Sender: TObject);
var
p: double;
+ i: integer;
begin
MainForm.UpdateUndo;
- with MainTriangles[SelectedTriangle] do
- begin
- p := GetPivot.x * 2;
- x[0] := p - x[0];
- x[1] := p - x[1];
- x[2] := p - x[2];
- end;
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ with MainTriangles[SelectedTriangle] do
+ begin
+ p := GetPivot.x * 2;
+ x[0] := p - x[0];
+ x[1] := p - x[1];
+ x[2] := p - x[2];
+ end
+ else for i in SyncTriangles do
+ with MainTriangles[i] do
+ begin
+ p := GetPivot(i).x * 2;
+ x[0] := p - x[0];
+ x[1] := p - x[1];
+ x[2] := p - x[2];
+ end;
//AutoZoom;
UpdateFlame(True);
end;
procedure TEditForm.cbTransformsChange(Sender: TObject);
var
- n: integer;
+ n: smallint;
begin
n := cbTransforms.ItemIndex;
@@ -4272,6 +4499,20 @@ begin
ShowSelectedInfo;
TriangleView.Invalidate;
end;
+
+ UpdateSyncTriangles; // AV
+end;
+
+procedure TEditForm.UpdateSyncTriangles;
+var n: smallint;
+begin
+ if SelectedTriangle in SyncTriangles then exit;
+
+ for n := 0 to Transforms-1 do
+ if mnuSyncTriangles.Items[n].Checked then
+ mnuSyncTriangles.Items[n].Click;
+ if SelectedTriangle < Transforms then
+ mnuSyncTriangles.Items[SelectedTriangle].Click;
end;
procedure TEditForm.cbTransformsDrawItem(Control: TWinControl;
@@ -4305,7 +4546,7 @@ begin
end;
procedure TEditForm.ChaosClearBelowClick(Sender: TObject);
-var i, n: integer;
+var i, n: smallint;
begin
n := vleChaos.Row;
if n = Transforms then exit;
@@ -4321,7 +4562,7 @@ begin
end;
procedure TEditForm.ClearAllAboveClick(Sender: TObject);
-var i, n: integer;
+var i, n: smallint;
begin
n := vleChaos.Row;
if (n < 2) then exit;
@@ -4454,7 +4695,8 @@ begin
if Result then
if (ActiveControl = txtSearchBox) or (ActiveControl = txtName) then
Exit(False);
- Result := Result or (ActiveControl is TValueListEditor) or (ActiveControl is TComboBox);
+ Result := Result or (ActiveControl is TValueListEditor) or
+ ((ActiveControl is TComboBox) and (ActiveControl.Parent = gbTrgOperations));
end;
(*
@@ -4728,8 +4970,7 @@ begin
ShowSelectedInfo;
UpdateFlame(True);
end;
- //chkCollapseVariationsClick(nil);
- //chkCollapseVariablesClick(nil);
+
end;
(*
@@ -5059,7 +5300,7 @@ begin
if not (isEdit or (ActiveControl is TValueListEditor)) then
begin
Application.MessageBox(PChar(TextByKey('editor-status-nonumfield')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ ApophysisSVN, MB_ICONWARNING);
exit;
end;
@@ -5097,7 +5338,7 @@ begin
end;
procedure TEditForm.InvertXaosClick(Sender: TObject);
-var i: integer;
+var i: smallint;
cmax: double;
begin
MainForm.UpdateUndo;
@@ -5131,9 +5372,9 @@ end;
procedure TEditForm.UpdateColorBar;
var
- BitMap:TBitmap;
- Row:pRGBTripleArray;
- i:integer;
+ BitMap: TBitmap;
+ Row: pRGBTripleArray;
+ i: smallint;
begin
BitMap := TBitMap.Create;
try
@@ -5156,6 +5397,49 @@ begin
end;
end;
+procedure TEditForm.RotateTriangleBy(const angle: double); // AV
+var
+ i: smallint;
+begin
+ MainForm.UpdateUndo;
+
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ begin
+ if RotateXYO.Checked then
+ MainTriangles[SelectedTriangle] :=
+ RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, angle)
+ else if RotateX.Checked then begin
+ MainTriangles[SelectedTriangle] :=
+ RotateTriangleXY(MainTriangles[SelectedTriangle], 0, angle);
+ if tbAutoWeights.Down then cp.CalculateWeights; // AV
+ end else if RotateY.Checked then begin
+ MainTriangles[SelectedTriangle] :=
+ RotateTriangleXY(MainTriangles[SelectedTriangle], 2, angle);
+ if tbAutoWeights.Down then cp.CalculateWeights; // AV
+ end else //if RotateO.Checked then
+ MainTriangles[SelectedTriangle] :=
+ RotateTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, angle);
+ end
+ else begin
+ if RotateXYO.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] :=
+ RotateTrianglePoint(MainTriangles[i], GetPivot(i).x, GetPivot(i).y, angle)
+ else if RotateX.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := RotateTriangleXY(MainTriangles[i], 0, angle)
+ else if RotateY.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := RotateTriangleXY(MainTriangles[i], 2, angle)
+ else //if RotateO.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := RotateTriangleO(MainTriangles[i], WorldPivot.x, WorldPivot.y, angle);
+ end;
+
+ HasChanged := True;
+ UpdateFlame(true);
+end;
+
procedure TEditForm.btTrgRotateLeftClick(Sender: TObject);
var
angle: double;
@@ -5168,32 +5452,18 @@ begin
end;
assert(angle <> 0);
- if GetKeyState(VK_CONTROL) < 0 then angle := angle/6.0
- else if GetKeyState(VK_SHIFT) < 0 then angle := angle*6.0;
+ if GetKeyState(VK_CONTROL) < 0 then angle := angle / 6.0
+ else if GetKeyState(VK_SHIFT) < 0 then angle := angle * 6.0;
// AV: to show internally modified value
if (ShowModVals.Checked) then txtTrgRotateValue.Text := Format('%.6g', [angle]);
- MainForm.UpdateUndo;
- if RotateXYO.Checked then
- MainTriangles[SelectedTriangle] :=
- RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, (PI/180)*angle)
- else if RotateX.Checked then
- MainTriangles[SelectedTriangle] := RotateTriangleXY(MainTriangles[SelectedTriangle], 0, (PI/180)*angle)
- else if RotateY.Checked then
- MainTriangles[SelectedTriangle] := RotateTriangleXY(MainTriangles[SelectedTriangle], 2, (PI/180)*angle)
- else //if RotateO.Checked then
- MainTriangles[SelectedTriangle] := RotateTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, (PI/180)*angle);
- HasChanged := True;
- UpdateFlame(true);
+ angle := PI/180 * angle; // AV
+ RotateTriangleBy(angle); // AV
end;
procedure TEditForm.btTrgRotateLeft90Click(Sender: TObject);
begin
- MainForm.UpdateUndo;
- MainTriangles[SelectedTriangle] :=
- RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, PI/2);
- HasChanged := True;
- UpdateFlame(true);
+ RotateTriangleBy(PI/2); // AV
end;
procedure TEditForm.btTrgRotateRightClick(Sender: TObject);
@@ -5213,30 +5483,13 @@ begin
// AV: to show internally modified value
if (ShowModVals.Checked) then txtTrgRotateValue.Text := Format('%.6g', [angle]);
- MainForm.UpdateUndo;
- if RotateXYO.Checked then
- MainTriangles[SelectedTriangle] :=
- RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, -(PI/180)*angle)
- else if RotateX.Checked then begin
- MainTriangles[SelectedTriangle] := RotateTriangleXY(MainTriangles[SelectedTriangle], 0, -(PI/180)*angle);
- if tbAutoWeights.Down then cp.CalculateWeights; // AV
- end else if RotateY.Checked then begin
- MainTriangles[SelectedTriangle] := RotateTriangleXY(MainTriangles[SelectedTriangle], 2, -(PI/180)*angle);
- if tbAutoWeights.Down then cp.CalculateWeights; // AV
- end else //if RotateO.Checked then
- MainTriangles[SelectedTriangle] := RotateTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, -(PI/180)*angle);
-
- HasChanged := True;
- UpdateFlame(true);
+ angle := -PI/180 * angle; // AV
+ RotateTriangleBy(angle); // AV
end;
procedure TEditForm.btTrgRotateRight90Click(Sender: TObject);
begin
- MainForm.UpdateUndo;
- MainTriangles[SelectedTriangle] :=
- RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, -PI/2);
- HasChanged := True;
- UpdateFlame(true);
+ RotateTriangleBy(-PI/2); // AV
end;
procedure TEditForm.PaintBackground;
@@ -5247,7 +5500,7 @@ end;
procedure TEditForm.TrgMove(dx, dy: double);
var
- i: integer;
+ i, j: smallint;
offset: double;
begin
try
@@ -5264,12 +5517,21 @@ begin
if (ShowModVals.Checked) then txtTrgMoveValue.Text := Format('%.6g', [offset]);
MainForm.UpdateUndo;
- for i := 0 to 2 do begin
- MainTriangles[SelectedTriangle].x[i] :=
+
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ for i := 0 to 2 do begin
+ MainTriangles[SelectedTriangle].x[i] :=
MainTriangles[SelectedTriangle].x[i] + dx*offset;
- MainTriangles[SelectedTriangle].y[i] :=
+ MainTriangles[SelectedTriangle].y[i] :=
MainTriangles[SelectedTriangle].y[i] + dy*offset;
- end;
+ end
+ else
+ for j in SyncTriangles do
+ for i := 0 to 2 do begin
+ MainTriangles[j].x[i] := MainTriangles[j].x[i] + dx * offset;
+ MainTriangles[j].y[i] := MainTriangles[j].y[i] + dy * offset;
+ end;
+
// HasChanged := True;
UpdateFlame(true);
end;
@@ -5321,6 +5583,7 @@ end;
procedure TEditForm.btTrgScaleUpClick(Sender: TObject);
var
scale: double;
+ i: smallint;
begin
try
scale := StrToFloat(txtTrgScaleValue.Text) / 100.0;
@@ -5337,15 +5600,36 @@ begin
if (ShowModVals.Checked) then txtTrgScaleValue.Text := Format('%.6g', [scale * 100.0]);
MainForm.UpdateUndo;
- if ScaleXYO.Checked then
- MainTriangles[SelectedTriangle] :=
- ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, scale)
+
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ begin
+ if ScaleXYO.Checked then
+ MainTriangles[SelectedTriangle] :=
+ ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, scale)
else if ScaleX.Checked then
MainTriangles[SelectedTriangle] := ScaleTriangleXY(MainTriangles[SelectedTriangle], 0, scale)
else if ScaleY.Checked then
- MainTriangles[SelectedTriangle] := ScaleTriangleXY(MainTriangles[SelectedTriangle], 2, scale)
- else //if ScaleO.Checked then
- MainTriangles[SelectedTriangle] := ScaleTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, scale);
+ MainTriangles[SelectedTriangle] := ScaleTriangleXY(MainTriangles[SelectedTriangle], 2, scale)
+ else //if ScaleO.Checked then
+ MainTriangles[SelectedTriangle] :=
+ ScaleTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, scale);
+ end
+ else begin
+ if ScaleXYO.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] :=
+ ScaleTrianglePoint(MainTriangles[i], GetPivot(i).x, GetPivot(i).y, scale)
+ else if ScaleX.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := ScaleTriangleXY(MainTriangles[i], 0, scale)
+ else if ScaleY.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := ScaleTriangleXY(MainTriangles[i], 2, scale)
+ else //if ScaleO.Checked then begin
+ for i in SyncTriangles do
+ MainTriangles[i] :=
+ ScaleTriangleO(MainTriangles[i], WorldPivot.x, WorldPivot.y, scale);
+ end;
if tbAutoWeights.Down then cp.CalculateWeights; // AV
HasChanged := True;
@@ -5355,6 +5639,7 @@ end;
procedure TEditForm.btTrgScaleDownClick(Sender: TObject);
var
scale: double;
+ i: smallint;
begin
try
scale := 100.0 / StrToFloat(txtTrgScaleValue.Text);
@@ -5371,15 +5656,37 @@ begin
if (ShowModVals.Checked) then txtTrgScaleValue.Text := Format('%.6g', [scale * 100.0]);
MainForm.UpdateUndo;
- if ScaleXYO.Checked then
- MainTriangles[SelectedTriangle] :=
- ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, scale)
- else if ScaleX.Checked then
- MainTriangles[SelectedTriangle] := ScaleTriangleXY(MainTriangles[SelectedTriangle], 0, scale)
- else if ScaleY.Checked then
+
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ begin
+ if ScaleXYO.Checked then
+ MainTriangles[SelectedTriangle] :=
+ ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, scale)
+ else if ScaleX.Checked then
+ MainTriangles[SelectedTriangle] := ScaleTriangleXY(MainTriangles[SelectedTriangle], 0, scale)
+ else if ScaleY.Checked then
MainTriangles[SelectedTriangle] := ScaleTriangleXY(MainTriangles[SelectedTriangle], 2, scale)
- else //if ScaleO.Checked then
- MainTriangles[SelectedTriangle] := ScaleTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, scale);
+ else //if ScaleO.Checked then
+ MainTriangles[SelectedTriangle] :=
+ ScaleTriangleO(MainTriangles[SelectedTriangle], WorldPivot.x, WorldPivot.y, scale);
+ end
+ else begin
+ if ScaleXYO.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] :=
+ ScaleTrianglePoint(MainTriangles[i], GetPivot(i).x, GetPivot(i).y, scale)
+ else if ScaleX.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := ScaleTriangleXY(MainTriangles[i], 0, scale)
+ else if ScaleY.Checked then
+ for i in SyncTriangles do
+ MainTriangles[i] := ScaleTriangleXY(MainTriangles[i], 2, scale)
+ else //if ScaleO.Checked then begin
+ for i in SyncTriangles do
+ MainTriangles[i] :=
+ ScaleTriangleO(MainTriangles[i], WorldPivot.x, WorldPivot.y, scale);
+ end;
+
if tbAutoWeights.Down then cp.CalculateWeights; // AV
HasChanged := True;
UpdateFlame(true);
@@ -5535,8 +5842,8 @@ end;
procedure TEditForm.EditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
- var num: double;
- begin
+var num: double;
+begin
case key of
VK_ADD:
if SelectedTriangle < LastTriangle then begin
@@ -5579,11 +5886,16 @@ procedure TEditForm.EditKeyDown(Sender: TObject; var Key: Word;
RotateO.Checked := True;
end;
Ord('A'):
- if (not txtName.Focused) and (not txtSearchBox.Focused) then
- begin
- ScaleXYO.Checked := True;
- RotateXYO.Checked := True;
- end;
+ if (not txtName.Focused) and (not txtSearchBox.Focused) then
+ begin
+ ScaleXYO.Checked := True;
+ RotateXYO.Checked := True;
+ end;
+ Ord('M'):
+ if (not txtName.Focused) and (not txtSearchBox.Focused) then
+ begin
+ mnuCalcExpression.Click;
+ end;
else
key_handled := false;
exit;
@@ -5595,13 +5907,18 @@ end;
procedure TEditForm.EditKeyPress(Sender: TObject; var Key: Char);
begin
if txtName.Focused then begin
- if (key = '+') or (key='-') then begin
+ {
+ if (key = '+') or (key='-') then begin
// nvm...code moved to EditKeyDown
key := #0;
end;
if (key='"') then key := #0; // we dont want that in "name" box -> XML mess!
+ }
+ // AV: we also don't want XML-tag's brackets here
+ if CharInSet(Key,['+', '-', '"', '<', '>']) then key := #0;
exit;
- end else if txtSearchBox.Focused then
+ end
+ else if txtSearchBox.Focused then
begin
if (key = #13) then key := #0; // AV: to prevent a beep
exit;
@@ -5613,7 +5930,7 @@ begin
{ AV: a lot of users type comma as the decimal separator,
but Apo discard it. It's not normally... }
if (Key = ',') then Key := '.'; // FormatSettings.DecimalSeparator;
- if key_handled or not CharinSet(Key,['0'..'9', '-', #8, #13, '.'])
+ if key_handled or not CharInSet(Key,['0'..'9', '-', #8, #13, '.'])
then Key:= #0;
end;
@@ -5641,6 +5958,30 @@ begin
SetCursorPos(MousePos.x, MousePos.y);
end;
+procedure TEditForm.tbSyncTrianglesClick(Sender: TObject);
+begin
+ UseTriangleSync := not UseTriangleSync;
+ AdjustSyncTriangles;
+end;
+
+procedure TEditForm.AdjustSyncTriangles;
+begin
+ if UseTriangleSync then begin
+ tbSyncTriangles.Style := tbsDropDown;
+ tbSyncTriangles.DropdownMenu := mnuSyncTriangles;
+ TriangleToolBar.Perform(CM_CONTROLCHANGE, WPARAM(tbSyncTriangles), 36);
+ tbSyncTriangles.ImageIndex := 44;
+ tbSyncTriangles.Hint := TextByKey('editor-tab-triangle-enablesync');
+ end
+ else begin
+ tbSyncTriangles.Style := tbsButton;
+ tbSyncTriangles.DropdownMenu := nil;
+ TriangleToolBar.Perform(CM_CONTROLCHANGE, WPARAM(tbSyncTriangles), 23);
+ tbSyncTriangles.ImageIndex := 43;
+ tbSyncTriangles.Hint := TextByKey('editor-tab-triangle-disablesync');
+ end;
+end;
+
procedure TEditForm.TriangleViewMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
@@ -5753,6 +6094,16 @@ begin
tbAxisLock.Down := AxisLock;
end;
+procedure TEditForm.tbCommentClick(Sender: TObject);
+begin
+ CommentForm.memComment.Lines.Text := cp.comment;
+ if CommentForm.ShowModal = mrOK then
+ begin
+ cp.comment := Trim(CommentForm.memComment.Lines.Text);
+ MainCp.comment := cp.comment;
+ end;
+end;
+
procedure TEditForm.tbFullViewClick(Sender: TObject);
begin
MainForm.mnuFullScreenClick(Sender);
@@ -5807,8 +6158,6 @@ begin
end;
{$endif}
- //chkCollapseVariationsClick(nil);
- //chkCollapseVariablesClick(nil);
end;
procedure TEditForm.vleVariablesExit(Sender: TObject);
@@ -5867,6 +6216,7 @@ end;
procedure TEditForm.mnuResetAllClick(Sender: TObject);
var
i: integer;
+ saved: boolean;
begin
MainForm.UpdateUndo;
for i := 0 to Transforms do cp.xform[i].Clear;
@@ -5889,7 +6239,7 @@ begin
cp.cameraDOF := 0;
Transforms := 1;
- SelectedTriangle := 1;
+ SelectedTriangle := 0; // AV: fixed - was 1;
MainTriangles[0] := MainTriangles[-1];
MainTriangles[1] := MainTriangles[-1]; // kinda reset finalxform
@@ -5904,14 +6254,44 @@ begin
if AutoSaveXML then // AV: create a flame from scratch if needed
begin
MainCp.name := 'New flame' + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
- if MainForm.SaveXMLFlame(MainCp, MainCp.name, OpenFile) then
- if MainForm.SortFlames.Checked then
- ListXML(OpenFile, 2, MainCp.name) // show the new item
- else
- ListXML(OpenFile, 0); // show the last item
+ if (OpenFileType = ftXML) then
+ saved := MainForm.SaveXMLFlame(MainCp, MainCp.name, OpenFile)
+ else
+ saved := MainForm.SaveFlame(MainCp, MainCp.name, OpenFile);
+ if saved then MainForm.AddFlameToList; // AV: show the new item
end;
end;
+procedure TEditForm.SaveFlameStateClick(Sender: TObject); // AV
+{ Saves current flame into opened file and adds it to list view }
+var
+ n: word;
+ FItem: TListItem;
+ Ftitle: string;
+ saved: boolean;
+begin
+ n := 0; //
+ for FItem in MainForm.ListView1.Items do
+ if pos(MainCp.name, FItem.Caption) = 1 then inc(n);
+
+ if (n = 0) then
+ Ftitle := MainCp.name // current flame is not in the list
+ else begin
+ Ftitle := MainCp.name + ' (' + IntToStr(n) + ')';
+
+ Fitem := MainForm.ListView1.FindCaption(0, FTitle, false, true, false);
+ if FItem <> nil then // we already have a flame with the same name
+ Ftitle := MainCp.name + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
+ end;
+
+ if (OpenFileType = ftXML) then
+ saved := MainForm.SaveXMLFlame(MainCp, Ftitle, OpenFile)
+ else
+ saved := MainForm.SaveFlame(MainCp, Ftitle, OpenFile);
+ if saved then
+ MainForm.AddFlameToList(Ftitle); // show the new item
+end;
+
// -----------------------------------------------------------------------------
procedure TEditForm.btnXcoefsClick(Sender: TObject);
@@ -6285,31 +6665,36 @@ begin
VEVars.canvas.brush.Color := col;
VEVars.canvas.fillRect(Rect);
VEVars.canvas.TextOut(Rect.Left+2, Rect.Top+2, VEVars.Cells[ACol,ARow]);
- end else col := VEVars.canvas.brush.color;
- if (Acol = 0) and (Arow > 0) then begin
+ end
+ else col := VEVars.canvas.brush.color;
+
+ if (Acol = 0) and (Arow > 0) then
+ begin
VEVars.Canvas.Font.Name := 'Arial';
VEVars.Canvas.Font.Size := 5;
- VarSupports(i, supports3D, supportsDC); // Arow - 1
+ supports3D := VarSupports3D(i); // i <-- (Arow - 1)
+ supportsDC := VarSupportsDC(i); // AV: separate methods
- frect.Left := Rect.Right - 12;
- frect.Right := Rect.Right;
- frect.Top := Rect.Top;
- frect.Bottom := Rect.Bottom;
+ if (supports3D or supportsDC) then // AV: optimized calculations
+ begin
+ frect.Left := Rect.Right - 12;
+ frect.Right := Rect.Right;
+ frect.Top := Rect.Top;
+ frect.Bottom := Rect.Bottom;
- if (supports3D or supportsDC) then begin
VEVars.canvas.brush.Color := col;
VEVars.canvas.fillRect(frect);
- end;
-
- if (supports3D) then begin
- VEVars.Canvas.Font.Color := $a00000;
- VEVars.Canvas.TextOut(frect.Left, frect.Top + 2, '3D');
- end;
- if (supportsDC) then begin
- VEVars.Canvas.Font.Color := $0000a0;
- VEVars.Canvas.TextOut(frect.Left, frect.Top + 9, 'DC');
+ if (supports3D) then begin
+ VEVars.Canvas.Font.Color := $a00000;
+ VEVars.Canvas.TextOut(frect.Left, frect.Top + 2, '3D');
+ end;
+
+ if (supportsDC) then begin
+ VEVars.Canvas.Font.Color := $0000a0;
+ VEVars.Canvas.TextOut(frect.Left, frect.Top + 9, 'DC');
+ end;
end;
end;
end;
@@ -6335,6 +6720,7 @@ begin
cp.finalXformEnabled := EnableFinalXform;
UpdateFlame(True);
TriangleView.Invalidate;
+ UpdateSyncTriangles; // AV
end;
procedure TEditForm.DragPanelMouseDown(Sender: TObject;
@@ -6758,7 +7144,7 @@ procedure TEditForm.btnCopyTriangleClick(Sender: TObject);
begin
MemTriangle := MainTriangles[SelectedTriangle];
tbPasteTriangle.Enabled := True;
- PasteTriangleCoordinates1.Enabled := True;
+ PasteTriangleCoordinates.Enabled := True;
end;
procedure TEditForm.btnFlipClick(Sender: TObject);
@@ -6777,10 +7163,7 @@ begin
end;
if (px = fx) and (py = fy) then exit;
MainForm.UpdateUndo;
- //if (px = fx) then MainTriangles[SelectedTriangle] :=
- // FlipTriangleHorizontal(MainTriangles[SelectedTriangle])
- //else if (py = fy) then MainTriangles[SelectedTriangle] :=
- // FlipTriangleVertical(MainTriangles[SelectedTriangle]) else
+
MainTriangles[SelectedTriangle] :=
FlipTriangleLine(MainTriangles[SelectedTriangle], px, py, fx, fy);
UpdateFlame(true);
@@ -6923,6 +7306,37 @@ begin
//ShowSelectedInfo;
end;
+procedure TEditForm.mnuCopyChaosClick(Sender: TObject);
+var i: smallint;
+begin
+ SetLength(MemChaos, NXFORMS);
+ if mnuChaosViewTo.Checked then
+ for i := 0 to high(MemChaos) do
+ MemChaos[i] := cp.xform[SelectedTriangle].modWeights[i]
+ else
+ for i := 0 to high(MemChaos) do
+ MemChaos[i] := cp.xform[i].modWeights[SelectedTriangle];
+
+ mnuPasteChaos.Enabled := True;
+ PasteChaos.Enabled := True;
+end;
+
+procedure TEditForm.mnuPasteChaosClick(Sender: TObject);
+var i, t: smallint;
+begin
+ MainForm.UpdateUndo;
+ if mnuChaosViewTo.Checked then
+ for t in SyncTriangles do
+ for i := 0 to high(MemChaos) do
+ cp.xform[t].modWeights[i] := MemChaos[i]
+ else
+ for t in SyncTriangles do
+ for i := 0 to high(MemChaos) do
+ cp.xform[i].modWeights[t] := MemChaos[i];
+ UpdateFlame(true);
+ if ChaosForm.Visible then ChaosForm.ChaosMatrix.Invalidate;
+end;
+
(*
procedure TEditForm.chkPlotModeClick(Sender: TObject);
var newMode: boolean;
@@ -7143,11 +7557,13 @@ procedure TEditForm.chkCollapseVariationsClick(Sender: TObject);
var
i: integer;
s: string;
+ IsSupport: boolean;
begin
s := Trim(txtSearchBox.Text);
for i := 1 to VEVars.RowCount - 1 do
begin
- if (Length(s) = 0) then
+ if (Length(s) = 0) or ((Length(s) <= Length(VEVars.Cells[0, i])) and
+ (Pos(s, VEVars.Cells[0, i]) > 0)) then // AV: search text is not empty
begin
case cbCollapseVariations.ItemIndex of
0: VEVars.RowHeights[i] := VEVars.DefaultRowHeight; // all
@@ -7159,31 +7575,23 @@ begin
2: VEVars.RowHeights[i] := // favourites
IfThen(FavouriteVariations[GetVariationIndex(VEVars.Cells[0,i])], // i-1
VEVars.DefaultRowHeight, -1);
+ 3: // 3D
+ begin
+ IsSupport := VarSupports3D(GetVariationIndex(VEVars.Cells[0,i]));
+ VEVars.RowHeights[i] := IfThen(IsSupport, VEVars.DefaultRowHeight, -1);
+ end;
+ 4: // DC
+ begin
+ IsSupport := VarSupportsDC(GetVariationIndex(VEVars.Cells[0,i]));
+ VEVars.RowHeights[i] := IfThen(IsSupport, VEVars.DefaultRowHeight, -1);
+ end;
end;
end
- else begin // AV: search text is not empty
- if (Length(s) > Length(VEVars.Cells[0, i])) then
- VEVars.RowHeights[i] := -1
- else if Pos(s, VEVars.Cells[0, i]) > 0 then
- begin
- case cbCollapseVariations.ItemIndex of
- 0: VEVars.RowHeights[i] := VEVars.DefaultRowHeight; // all
- 1: if Assigned(cp) then
- VEVars.RowHeights[i] := // active
- IfThen((VEVars.Cells[1,i] = '0'), -1, VEVars.DefaultRowHeight)
- else
- VEVars.RowHeights[i] := -1;
- 2: VEVars.RowHeights[i] := // favourites
- IfThen(FavouriteVariations[GetVariationIndex(VEVars.Cells[0,i])],
- VEVars.DefaultRowHeight, -1);
- end;
- end
- else
+ else
VEVars.RowHeights[i] := -1;
- end;
end;
-{
+ {
s := Trim(txtSearchBox.Text);
for i:= 1 to VEVars.RowCount - 1 do
begin
@@ -7214,7 +7622,7 @@ begin
VEVars.RowHeights[i] := -1;
end;
end;
-}
+ }
end;
procedure TEditForm.chkCollapseVariablesClick(Sender: TObject);
@@ -7354,9 +7762,9 @@ end;
procedure TEditForm.ColorBarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
- dx: double; //Extended;
+ dx: double;
begin
- // dx := Round(100 * X / ColorBar.Width) / 100; // AV: it's not correct
+ // dx := Round(100 * X / ColorBar.Width) / 100; // <-- AV: it's not correct
dx := X / (ColorBarPicture.Width - 1); // AV: this gives the best results
txtXFormColor.Text := FloatToStrF(dx, ffFixed, 4, 3); // AV: default presision
txtXFormColorExit(nil);
@@ -7399,7 +7807,6 @@ begin
Key := #0;
txtNameExit(sender);
end;
-
end;
procedure TEditForm.txtNameExit(Sender: TObject);
@@ -7435,10 +7842,10 @@ end;
procedure TEditForm.TrianglePanelResize(Sender: TObject);
begin
- GroupBox5.Left := (TrianglePanel.CLientWidth - GroupBox5.Width) div 2;
- GroupBox6.Left := (TrianglePanel.CLientWidth - GroupBox6.Width) div 2;
- GroupBox3.Left := (TrianglePanel.CLientWidth - GroupBox3.Width) div 2;
- GroupBox10.Left := (TrianglePanel.CLientWidth - GroupBox10.Width) div 2;
+ gbTrgOperations.Left := (TrianglePanel.CLientWidth - gbTrgOperations.Width) div 2;
+ gbCoordinates.Left := (TrianglePanel.CLientWidth - gbCoordinates.Width) div 2;
+ gbPivot.Left := (TrianglePanel.CLientWidth - gbPivot.Width) div 2;
+ gbFlip.Left := (TrianglePanel.CLientWidth - gbFlip.Width) div 2;
TriangleToolBar.Left := (TrianglePanel.CLientWidth - TriangleToolBar.Width) div 2;
end;
@@ -7450,28 +7857,52 @@ begin
PageControl.Height := ControlPanel.Height - PageControl.Top;
end;
-procedure TEditForm.Copytransform1Click(Sender: TObject);
-var txt: string;
+procedure TEditForm.CopyTransformClick(Sender: TObject);
+var
+ txt: string;
+ i, n: byte;
begin
MemCp.Clear;
MemCp.Name := 'Memorized XForm Parameters';
- MemCp.xform[0].Assign(cp.xform[SelectedTriangle]);
- txt := Trim(MainForm.RetrieveXML(MemCp));
+ if (not UseTriangleSync) or (SelectedTriangle = Transforms) then
+ MemCp.xform[0].Assign(cp.xform[SelectedTriangle])
+ else begin // AV: copy all selected transforms
+ n := 0;
+ for i in SyncTriangles do
+ begin
+ MemCp.xform[n].Assign(cp.xform[i]);
+ inc(n);
+ end;
+ end;
+ txt := Trim(FlameToXML(MemCp));
Clipboard.SetTextBuf(PChar(txt));
- Pastetransform1.Enabled := True;
+ PasteTransform.Enabled := True;
MainForm.mnuPaste.Enabled := False;
end;
-procedure TEditForm.Pastetransform1Click(Sender: TObject);
+procedure TEditForm.CopyVariationsClick(Sender: TObject);
+begin
+ try
+ VEVars.Strings.SaveToFile(APPDATA + saved_variations);
+ VLEVariables.Strings.SaveToFile(APPDATA + saved_variables);
+ PasteVariations.Enabled := True;
+ except
+ // TODO
+ PasteVariations.Enabled := False;
+ end;
+end;
+
+procedure TEditForm.PasteTransformClick(Sender: TObject);
var
TempTriangles: TTriangles;
- i: integer;
+ i, t: smallint;
begin
- if (MemCp.NumXForms > 0) and (Transforms < NXFORMS) then
+ t := MemCp.NumXForms - 1;
+ if (t >= 0) and (Transforms + t < NXFORMS) then
begin
MainForm.UpdateUndo;
MemCp.TrianglesFromCP(TempTriangles);
- for i := 0 to MemCp.NumXForms - 1 do
+ for i := 0 to t do
begin
MainTriangles[Transforms+1] := MainTriangles[Transforms];
cp.xform[Transforms+1].Assign(cp.xform[Transforms]);
@@ -7485,6 +7916,59 @@ begin
end;
end;
+procedure TEditForm.PasteVariationsClick(Sender: TObject);
+var
+ i: integer;
+ v: double;
+ s: string;
+begin
+ MainForm.UpdateUndo;
+ try
+ VEVars.Strings.LoadFromFile(APPDATA + saved_variations);
+ for i := 0 to NrVar-1 do
+ begin
+ s := VEVars.Strings.Names[i];
+ cp.xform[SelectedTriangle].SetVariation(GetVariationIndex(s),
+ StrToFloat(VEVars.Strings.Values[s]));
+ cp.xform[SelectedTriangle].ifs[i] := s;
+ end;
+
+ VLEVariables.Strings.LoadFromFile(APPDATA + saved_variables);
+ for i := 0 to GetNrVariableNames - 1 do
+ begin
+ v := StrToFloat(VLEVariables.Strings.ValueFromIndex[i]);
+ cp.xform[SelectedTriangle].SetVariable(VLEVariables.Strings.Names[i], v);
+ end;
+
+ UpdateFlame(true);
+ except
+ // restore defaults?
+ cp.xform[SelectedTriangle].SetVariation(0, 1);
+ cp.xform[SelectedTriangle].ifs[0] := 'linear';
+ VEVars.Strings.BeginUpdate;
+ VEVars.Strings[0] := 'linear=1';
+ for i := 1 to NrVar-1 do
+ begin
+ s := VarNames(i);
+ cp.xform[SelectedTriangle].SetVariation(i, 0);
+ cp.xform[SelectedTriangle].ifs[i] := s;
+ VEVars.Strings[i] := s + '=0';
+ end;
+ VEVars.Strings.EndUpdate;
+
+ VLEVariables.Strings.BeginUpdate;
+ for i := 0 to GetNrVariableNames - 1 do
+ begin
+ s := GetVariableNameAt(i);
+ cp.xform[SelectedTriangle].ResetVariable(s);
+ VLEVariables.Strings[i] := s + '=' + cp.xform[SelectedTriangle].GetVariableStr(s);
+ end;
+ VLEVariables.Strings.EndUpdate;
+
+ UpdateFlame(true);
+ end;
+end;
+
procedure TEditForm.ScrollBox2Resize(Sender: TObject);
begin // AV: done
GroupBox1.Left := (ScrollBox2.ClientWidth - GroupBox1.Width) div 2;
@@ -7549,6 +8033,7 @@ begin
tbExtendedEdit.Down := ExtEditEnabled;
tbAxisLock.Down := TransformAxisLock;
mnuChaosRebuild.Checked := RebuildXaosLinks;
+ AdjustSyncTriangles; // AV
chkCollapseVariationsClick(nil);
end;
diff --git a/Forms/FlameComment.dfm b/Forms/FlameComment.dfm
new file mode 100644
index 0000000..add08fd
--- /dev/null
+++ b/Forms/FlameComment.dfm
@@ -0,0 +1,303 @@
+object CommentForm: TCommentForm
+ Left = 0
+ Top = 0
+ BorderStyle = bsSingle
+ Caption = 'Edit Flame Comment'
+ ClientHeight = 172
+ ClientWidth = 459
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Icon.Data = {
+ 0000010001001616000000000000100800001600000028000000160000002C00
+ 000001002000000000009007000000000000000000000000000000000000FFFF
+ FF00000000070000002100000026000000260000002600000026000000260000
+ 0026000000260000002600000026000000260000002600000026000000260000
+ 002600000026000000260000002100000007FFFFFF00000000020000001C3133
+ 325E818583C58B918FFD8B908EFF8B908EFF8B908EFF8A908DFF8A8F8DFF8A8F
+ 8DFF8A8F8DFF898E8CFF898E8CFF898E8CFF888E8CFF888D8BFF898E8CFD7E82
+ 80C52F32305E0000001C00000002FFFFFF00000000078A908DB9D9DBDAFFFEFE
+ FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFD9DBDAFF878C8AB90000
+ 0007FFFFFF00FFFFFF00FFFFFF008F9593FCFEFEFEFFEBEEEDFFEAEDECFFEBEE
+ ECFFECEEEDFFECEFEEFFEDF0EFFFEEF0F0FFEFF1F0FFEFF1F0FFEFF1F1FFEFF1
+ F1FFEFF1F1FFEFF1F0FFF0F1F1FFFEFEFEFF8B908EFCFFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00909593FFFFFFFFFFEAEDECFFEBEEEDFF9AAAB4FF22313CFF6E8B
+ 9FFFB9C9D2FFD8DADAFFE4E6E5FFF1F2F2FFF2F4F3FFF2F4F3FFF2F3F3FFF1F3
+ F2FFF0F2F2FFFFFFFFFF8B908EFFFFFFFF00FFFFFF00FFFFFF00FFFFFF009196
+ 94FFFFFFFFFFEAEDECFFD0D3D2FFC7C9CAFF223542FF6A9FC4FF6DB5E8FF67B3
+ E6FF668EB8FFA7A8A8FFC0C1C1FFE7E8E8FFF0F1F1FFF2F3F3FFF1F3F2FFFFFF
+ FFFF8C9290FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00929895FFFFFFFFFFE9EC
+ EBFFEAEDECFFEBEEEDFF97C6E9FF8BC4ECFFFFFFFFFF8CBFEEFF1569D0FF7D9E
+ C5FFCBCCCCFFD5D7D6FFDFE0E0FFEAECECFFEFF1F1FFFFFFFFFF8E9391FFFFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00939997FFFFFFFFFFE8EBEAFFCFD1D0FFC7CA
+ C9FFBAC6CDFF6BB5E8FFA2D7FCFF4EAAF3FF549DE7FF1669D0FF7A9AC0FFB7B8
+ B8FFBCBDBCFFCDCFCEFFEDF0EFFFFFFFFFFF8F9492FFFFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00959A98FFFFFFFFFFE6EAE9FFE7EBE9FFE8EBEAFFE9ECEBFF72A9
+ E0FF2B7DDAFF6BBFFBFF4CAAF3FF549DE7FF176AD1FF9DBDE2FFE8EBEAFFE8EB
+ EAFFEBEDECFFFFFFFFFF909693FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00969B
+ 99FFFFFFFFFFE4E8E7FFCBCFCDFFC4C6C5FFC4C7C5FFC5C7C6FF5C90CBFF2A7C
+ D9FF6CBFFBFF4DAAF3FF539DE7FF1669D0FF85A5C8FFCED0CFFFE8EBEAFFFFFF
+ FFFF919795FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00979D9AFFFFFFFFFFE2E7
+ E5FFE3E7E5FFE3E7E6FFE4E8E6FFE4E8E7FFE5E9E7FF689EDAFF2B7DDAFF6CBF
+ FBFF4DAAF3FF539CE7FF146AD1FF9EBDDFFFE5E9E7FFFFFFFFFF939896FFFFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00989E9CFFFFFFFFFFE0E5E2FFC7CBC9FFBFC3
+ C1FFBFC4C2FFC0C4C2FFC0C4C2FFC0C5C3FF558CC9FF2A7CD9FF6CC0FBFF4DAA
+ F3FF529CE7FF1368D0FF9DBDDDFFFFFFFFFF949997FFFFFFFF00FFFFFF00FFFF
+ FF00FFFFFF009A9F9DFFFFFFFFFFDFE4E2FFE0E5E2FFE0E4E2FFDFE5E2FFE0E5
+ E2FFDFE4E2FFDFE4E2FFDFE4E2FF6198D7FF2B7FDBFF6CC0FBFF4DAAF3FF529C
+ E6FF1469D1FFA5BAD1FF959B98FFFFFFFF00FFFFFF00FFFFFF00FFFFFF009BA1
+ 9EFFFFFFFFFFE0E4E3FFC7CBC8FFBEC3C0FFBFC2C0FFBEC3C0FFBDC2BFFFBDC1
+ BFFFBDC1BFFFBCC0BFFF4F87C8FF2A7CD9FF6DC0FBFF4DAAF3FF5998D9FF858A
+ 88FF77899BFDFFFFFF00FFFFFF00FFFFFF00FFFFFF009CA29FFFFFFFFFFFE0E5
+ E3FFE0E5E2FFE0E5E2FFDFE4E2FFDFE4E1FFDEE3E1FFDEE3E1FFDDE2E0FFDCE2
+ DFFFDBE1DEFF5791D2FF2B7ED9FF6DC0FBFF6C99BAFF828787FF858A90FF6064
+ B087FFFFFF00FFFFFF00FFFFFF009DA3A1FFFFFFFFFFE1E6E4FFC7CBC9FFBFC3
+ C1FFBEC3C1FFBEC2C0FFBEC1BFFFBCC0BFFFBBC0BEFFBABFBDFFBFC4C2FFAEB1
+ AFFF6280A1FF838A8DFF92999BFFAEAFAFFF808388FF5355C2FA2828EE4DFFFF
+ FF00FFFFFF009EA5A2FFFFFFFFFFE2E7E4FFE2E6E4FFE1E6E4FFE0E5E3FFE0E5
+ E2FFDEE4E1FFDDE3E0FFDCE1DFFFDAE0DEFFD9DFDDFFB9BEBCFFFEFEFEFF7A8C
+ A7FF999DA2FFAFB2B5FF818594FE6D6DDDFF3131EED0FFFFFF00FFFFFF00A0A6
+ A3FFFFFFFFFFE4E8E6FFC9CECBFFC0C5C2FFBFC4C1FFBFC3C0FFBDC1BFFFBCC1
+ BFFFBDC2C0FFC4C9C6FFC6CCC9FFB5BAB7FFFFFFFFFFFDFDFDFF797CB1FE5E61
+ B7FE7778CEFF6868EDFF3030F0C8FFFFFF00FFFFFF00A1A7A4FFFFFFFFFFE6EA
+ E8FFE5E9E7FFE4E8E6FFE2E7E5FFE1E6E3FFDFE4E1FFDDE3E0FFDBE1DEFFDAE0
+ DDFFCAD0CDFFCCCECDFFFFFFFFFFDBDDDDFD9FA5A3D02E2EEAA02C2CEDF52E2E
+ EDDD2B2BEF30FFFFFF00FFFFFF00A2A9A6FCFEFEFEFFEBEFEDFFE7EBE9FFE6EA
+ E8FFE4E8E6FFE2E7E4FFE0E5E3FFE1E6E4FFE6EAE8FFEBEFEDFFE9EAEAFFF5F6
+ F5FFCCD0CEF7A0A7A4D89EA4A213FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00A6ADAAAEDBDEDDFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFCFCFCFFF0F2F1FFE4E7E6FFCFD3D1F8A2A8A6E9A0A6A45EA0A6
+ A302FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5AB
+ A821A7AEABAEA4AAA8FCA4AAA7FFA4AAA7FFA3AAA7FFA3A9A7FFA3A9A6FFA4AA
+ A7F5A5ABA9D2A4AAA8A0A2A8A561A1A8A506FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E0001F00C0000F00C0000F00C000
+ 0F00C0000F00C0000F00C0000F00C0000F00C0000F00C0000F00C0000F00C000
+ 0F00C0000F00C0000700C0000700C0000300C0000300C0000700C0007F00C001
+ FF00E007FF00}
+ OldCreateOrder = False
+ OnCreate = FormCreate
+ DesignSize = (
+ 459
+ 172)
+ PixelsPerInch = 96
+ TextHeight = 13
+ object btnCopy: TSpeedButton
+ Left = 8
+ Top = 58
+ Width = 23
+ Height = 22
+ Hint = 'Copy gradient to clipboard'
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000000000000000000000000000000000000FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
+ 0000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00E39A6F00FFFFFF00E3996C00E2996D00E3996D00FFFFFF000000
+ 0000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000
+ 000000000000000000000000000000000000FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00E2956600E393630000000000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00E39A6F00FFFFFF00E399
+ 6C00E2996D00E3996D00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00E3915F00E28C580000000000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00E2956600E3936300FFFF
+ FF00E3926200E2936300FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00E2916000FFFFFF0000000000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 0000FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00E3915F00E28C5800FFFF
+ FF00FFFFFF00E2936400FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF0000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00E2916000FFFFFF00FFFF
+ FF0000000000FFFFFF0000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF000000000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00000000000000000000000000000000000000
+ 000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
+ ParentShowHint = False
+ ShowHint = True
+ Transparent = False
+ OnClick = btnCopyClick
+ end
+ object btnPaste: TSpeedButton
+ Left = 8
+ Top = 82
+ Width = 23
+ Height = 22
+ Hint = 'Copy gradient to clipboard'
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000000000000000000000000000000000000FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF000000000000000000000000000000
+ 00000000000000000000000000000000000000000000FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00E39A6F00FFFF
+ FF00E3996C00E2996D00E3996D00FFFFFF0000000000FF00FF00FF00FF00FF00
+ FF000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF000000
+ 000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00E2956600E393
+ 6300FFFFFF00E3926200E2936300FFFFFF0000000000FF00FF00FF00FF000000
+ 000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF000000
+ 000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00E3915F00E28C
+ 5800FFFFFF00FFFFFF00E2936400FFFFFF0000000000FF00FF00FF00FF000000
+ 000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF0000000000000000000000000000000000FF00FF00FF00FF000000
+ 000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00E2916000FFFF
+ FF00FFFFFF0000000000FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
+ 000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF000000000000000000FF00FF00FF00FF00FF00FF00FF00FF000000
+ 000056B9F5000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00FF000000
+ 000056B9F50000000000BBE5F900BBE5F900BBE5F900BBE5F900BBE5F900BBE5
+ F9000000000056B9F50000000000FF00FF00FF00FF00FF00FF00FF00FF000000
+ 000056B9F50056B9F50000000000BBE5F9000000000000000000BBE5F9000000
+ 000056B9F50056B9F50000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF0000000000000000000000000000000000BBE5F900BBE5F900000000000000
+ 00000000000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF0000000000000000000000000000000000FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
+ ParentShowHint = False
+ ShowHint = True
+ Transparent = False
+ OnClick = btnPasteClick
+ end
+ object btnCut: TSpeedButton
+ Left = 8
+ Top = 34
+ Width = 23
+ Height = 22
+ Hint = 'Copy gradient to clipboard'
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000000000000000000000000000000000000FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00BBA19400975F450063423200A28D8200FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00CD866300AB623F008A50330062453700BDBDBE00B99F92006643
+ 34005E3F3000A8918600FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00DD835500C3B2AA00B89C8E00854E3300C0C0C000C5826100AA62
+ 3E00633C29002F252300FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00E1855700C5B3AA00BDAEA8008C523500BCB8B600D47C5200C2B2
+ AA00AE9486006B422D00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00DA987600E5865600B06641008F5538009C725D00C9754D00C1B9
+ B500BA9E90008F553600FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00C8B5AC00EB8E5D00DB8256009F5F400094604700BE744F00D57B
+ 4F00B96B4500AD877400FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00C8B6AE00DE997600DF845600C68D7000CC784D00D27C
+ 5100C6917700BDA79C00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00887366007160560086675500AB9E
+ 9900FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00B8B4B1008E8074007E6E6300695D55007672
+ 6E00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00BAB0AA00A2948B00A8A099008E817700635B
+ 5500FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00BEB1AA00A1948B00C8C6C400CDC5C0006B5F
+ 5600ADADAE00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00A99B9200B2A8A300C3C3C300E8E4E2007C6F
+ 6600A8A9AA00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00BBB8B600A3968C00BCBAB900FF00FF00DDDCDC00BCB2
+ AB00A6A19E00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00BFB8B300B3A89E00FF00FF00FF00FF00CBCBCB00E2DD
+ DA00A1979000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
+ ParentShowHint = False
+ ShowHint = True
+ Transparent = False
+ OnClick = btnCutClick
+ end
+ object btnUndo: TSpeedButton
+ Left = 8
+ Top = 10
+ Width = 23
+ Height = 22
+ Glyph.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000000000000000000000000000000000000FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FBD7
+ C500F8D5C300FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00F8DC
+ CF00F38A5700E1957100FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00EECBBA00F0855000DA865E00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00CA805C00F0885500EAC8B700FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00E1CDC300DB784700EF936700FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF008A462500954C2800A4542E00B65F3400C7693A00D6724000FF00
+ FF00FF00FF00FF00FF00AE5C3600EC865200F2CFBD00FF00FF00FF00FF00FF00
+ FF00FF00FF00954C2800DF733600EA824900F39A6A00F5B59400FF00FF00FF00
+ FF00FF00FF00FF00FF00A3664800E9845200F7C2A700FF00FF00FF00FF00FF00
+ FF00FF00FF00A3552E00EC824B00F38D5B00EC9C7600B6866F00E9D5CB00FF00
+ FF00FF00FF00FF00FF00A9745900E1825400F7BE9E00FF00FF00FF00FF00FF00
+ FF00FF00FF00B55F3400F39A6A00F49C7100F29465009D533000AA613B00DAB8
+ A700FF00FF00F6C5AE009D644600DE805100F7BDA100FF00FF00FF00FF00FF00
+ FF00FF00FF00C7693B00F7CAAE00FBDDCB00F4A37600F3946400B4623900B064
+ 3E00BF816200BB846000A15E3900EE8B5A00F6C8B000FF00FF00FF00FF00FF00
+ FF00FF00FF00D6724000FF00FF00FF00FF00FBDECF00F5A57E00F49D7200C973
+ 4700B7663C00B6653D00E2815300F6BCA100F6CBB700FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FBDACA00F5A67E00F6B6
+ 9600F5B28F00F6B09100F6C1A800F6C5AE00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FBE0
+ D200F6C3A900F7CFBB00F9DBCD00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
+ FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
+ ParentShowHint = False
+ ShowHint = True
+ Transparent = False
+ OnClick = btnUndoClick
+ end
+ object memComment: TMemo
+ Left = 40
+ Top = 8
+ Width = 397
+ Height = 113
+ Lines.Strings = (
+ '')
+ ScrollBars = ssBoth
+ TabOrder = 0
+ OnKeyPress = memCommentKeyPress
+ end
+ object btnOK: TButton
+ Left = 246
+ Top = 130
+ Width = 93
+ Height = 30
+ Anchors = [akRight, akBottom]
+ Caption = 'OK'
+ Default = True
+ ModalResult = 1
+ TabOrder = 1
+ end
+ object btnCancel: TButton
+ Left = 345
+ Top = 130
+ Width = 92
+ Height = 30
+ Anchors = [akRight, akBottom]
+ Caption = 'Cancel'
+ ModalResult = 2
+ TabOrder = 2
+ end
+end
diff --git a/Forms/FlameComment.pas b/Forms/FlameComment.pas
new file mode 100644
index 0000000..0f9d0bf
--- /dev/null
+++ b/Forms/FlameComment.pas
@@ -0,0 +1,76 @@
+{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
+
+unit FlameComment;
+
+interface
+
+uses
+ Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
+ System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
+ Vcl.StdCtrls, Vcl.Buttons, Translation;
+
+type
+ TCommentForm = class(TForm)
+ memComment: TMemo;
+ btnOK: TButton;
+ btnCancel: TButton;
+ btnCopy: TSpeedButton;
+ btnPaste: TSpeedButton;
+ btnCut: TSpeedButton;
+ btnUndo: TSpeedButton;
+ procedure FormCreate(Sender: TObject);
+ procedure memCommentKeyPress(Sender: TObject; var Key: Char);
+ procedure btnUndoClick(Sender: TObject);
+ procedure btnCopyClick(Sender: TObject);
+ procedure btnPasteClick(Sender: TObject);
+ procedure btnCutClick(Sender: TObject);
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ end;
+
+var
+ CommentForm: TCommentForm;
+
+implementation
+
+{$R *.dfm}
+
+procedure TCommentForm.btnCopyClick(Sender: TObject);
+begin
+ memComment.CopyToClipboard;
+end;
+
+procedure TCommentForm.btnCutClick(Sender: TObject);
+begin
+ memComment.CutToClipboard;
+end;
+
+procedure TCommentForm.btnPasteClick(Sender: TObject);
+begin
+ memComment.PasteFromClipboard;
+end;
+
+procedure TCommentForm.btnUndoClick(Sender: TObject);
+begin
+ if memComment.CanUndo then memComment.Undo;
+end;
+
+procedure TCommentForm.FormCreate(Sender: TObject);
+begin
+ btnOK.Caption := TextByKey('common-ok');
+ btnCancel.Caption := TextByKey('common-cancel');
+ self.Caption := TextByKey('editor-common-editcomment');
+ btnCopy.Hint := TextByKey('common-copy');
+ btnPaste.Hint := TextByKey('common-paste');
+ btnUndo.Hint := TextByKey('common-undo');
+ btnCut.Hint := TextByKey('common-cut');
+end;
+
+procedure TCommentForm.memCommentKeyPress(Sender: TObject; var Key: Char);
+begin
+ if (Key = '<') or (Key = '>') then Key := #0; // prevent XML-scanner errors
+end;
+
+end.
diff --git a/Forms/FormExport.dfm b/Forms/FormExport.dfm
index ced4273..98701a9 100644
--- a/Forms/FormExport.dfm
+++ b/Forms/FormExport.dfm
@@ -128,6 +128,12 @@ object ExportDialog: TExportDialog
Width = 337
Height = 21
Anchors = [akLeft, akTop, akRight]
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
TabOrder = 0
end
end
@@ -707,7 +713,7 @@ object ExportDialog: TExportDialog
Filter =
'JPEG Image (*.jpg)|*.jpg|PPM Image (*.ppm)|*.ppm|PNG Images (*.p' +
'ng)|*.png'
- Left = 464
- Top = 264
+ Left = 424
+ Top = 280
end
end
diff --git a/Forms/FormExport.pas b/Forms/FormExport.pas
index 4b3d023..26bfc4f 100644
--- a/Forms/FormExport.pas
+++ b/Forms/FormExport.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, Buttons, ComCtrls, ExtCtrls, Translation;
+ StdCtrls, Buttons, ComCtrls, ExtCtrls;
type
TExportDialog = class(TForm)
@@ -91,11 +91,11 @@ type
FloatFormatSettings: TFormatSettings;
public
Filename: string;
- ImageWidth, ImageHeight, Oversample, Batches, Strips: Integer;
+ ImageWidth, ImageHeight, Oversample: Integer;
Sample_Density, Filter_Radius: double;
Estimator, EstimatorMin, EstimatorCurve: double;
GammaTreshold: double;
- Jitters: integer;
+ // Batches, Jitters: Integer;
end;
var
@@ -103,7 +103,8 @@ var
Ratio: double;
implementation
-uses Global, Main, ShellAPI;
+
+uses Global, Main, ShellAPI, Translation;
{$R *.DFM}
@@ -111,14 +112,12 @@ procedure TExportDialog.btnBrowseClick(Sender: TObject);
begin
SaveDialog.InitialDir := ExtractFileDir(txtFilename.text);
SaveDialog.Filename := txtFilename.Text;
- case ExportFileFormat of
- 0: SaveDialog.DefaultExt := 'jpg';
- 1: SaveDialog.DefaultExt := 'ppm';
+ case ExportFileFormat of // AV: fixed
+ 1: SaveDialog.DefaultExt := 'jpg';
+ 2: SaveDialog.DefaultExt := 'ppm';
+ 3: SaveDialog.DefaultExt := 'png';
end;
- SaveDialog.filterIndex := ExportFileFormat;
- SaveDialog.Filter := Format('Portable Pixmap (*.ppm)|*.ppm|%s|*.jpg;*.jpeg|%s|*.png|%s|*.*',
- [TextByKey('common-filter-jpeg'), TextByKey('common-filter-png'),
- TextByKey('common-filter-allfiles')]);
+ SaveDialog.FilterIndex := ExportFileFormat;
if SaveDialog.Execute then
begin
case SaveDialog.FilterIndex of
@@ -144,11 +143,11 @@ begin
txtOversample.text := IntToSTr(Oversample);
udOversample.Position := Oversample;
Ratio := ImageWidth / ImageHeight;
- Batches := 1;
+ //Batches := 1;
+ //Jitters := 1;
Estimator := 9.0;
EstimatorMin := 0.0;
EstimatorCurve := 0.4;
- Jitters := 1;
GammaTreshold := MainCP.gamma_threshold; //0.01;
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FloatFormatSettings);
txtEstimator.Text := FloatToStr(Estimator, FloatFormatSettings);
@@ -197,18 +196,12 @@ end;
procedure TExportDialog.txtDensityChange(Sender: TObject);
begin
- try
- Sample_Density := StrToFloat(txtDensity.Text);
- except
- end;
+ Sample_Density := StrToFloatDef(txtDensity.Text, 200);
end;
procedure TExportDialog.txtFilterRadiusChange(Sender: TObject);
begin
- try
- Filter_Radius := StrToFloat(txtFilterRadius.Text);
- except
- end;
+ Filter_Radius := StrToFloatDef(txtFilterRadius.Text, 0.04);
end;
procedure TExportDialog.txtOversampleChange(Sender: TObject);
@@ -217,46 +210,31 @@ begin
txtOversample.Text := IntToStr(udOversample.Max);
if StrToInt(txtOversample.Text) < udOversample.Min then
txtOversample.Text := IntToStr(udOversample.Min);
- try
- Oversample := StrToInt(txtOversample.Text);
- except
- end;
+
+ Oversample := StrToIntDef(txtOversample.Text, 2);
end;
procedure TExportDialog.txtEstimatorChange(Sender: TObject);
begin
Estimator := 0;
- try
- Estimator := StrToFloat(txtEstimator.Text, FloatFormatSettings);
- except
- end;
+ Estimator := StrToFloatDef(txtEstimator.Text, 0, FloatFormatSettings);
end;
procedure TExportDialog.txtEstimatorMinChange(Sender: TObject);
begin
EstimatorMin := 0;
- try
- EstimatorMin := StrToFloat(txtEstimatorMin.Text, FloatFormatSettings);
- except
- end;
+ EstimatorMin := StrToFloatDef(txtEstimatorMin.Text, 0, FloatFormatSettings);
end;
procedure TExportDialog.txtEstimatorCurveChange(Sender: TObject);
begin
EstimatorCurve := 0;
- try
- EstimatorCurve := StrToFloat(txtEstimatorCurve.Text, FloatFormatSettings);
- except
- end;
+ EstimatorCurve := StrToFloatDef(txtEstimatorCurve.Text, 0, FloatFormatSettings);
end;
procedure TExportDialog.txtGammaTresholdChange(Sender: TObject);
begin
- //GammaTreshold := 0.01;
- try
- GammaTreshold := StrToFloat(txtGammaTreshold.Text, FloatFormatSettings);
- except
- end;
+ GammaTreshold := StrToFloatDef(txtGammaTreshold.Text, 0.01, FloatFormatSettings);
end;
procedure TExportDialog.lblFlam3LinkClick(Sender: TObject);
@@ -291,6 +269,9 @@ begin
chkRender.Caption := TextByKey('export-paramoptions-dorender');
Label6.Caption := TextByKey('export-paramoptions-warningtitle');
Label15.Caption := TextByKey('export-paramoptions-warningtext');
+ // AV: fixed the order and moved here here since the filter never changes
+ SaveDialog.Filter := Format('%s|*.jpg;*.jpeg|Portable Pixmap (*.ppm)|*.ppm|%s|*.png',
+ [TextByKey('common-filter-jpeg'), TextByKey('common-filter-png')]);
end;
procedure TExportDialog.Panel1Resize(Sender: TObject);
diff --git a/Forms/FormExportC.dfm b/Forms/FormExportC.dfm
deleted file mode 100644
index 929f1a4..0000000
--- a/Forms/FormExportC.dfm
+++ /dev/null
@@ -1,553 +0,0 @@
-object ExportCDialog: TExportCDialog
- Left = 313
- Top = 276
- BorderStyle = bsDialog
- Caption = 'Export Flame'
- ClientHeight = 134
- ClientWidth = 496
- Color = clBtnFace
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'MS Sans Serif'
- Font.Style = []
- OldCreateOrder = False
- Position = poScreenCenter
- OnCreate = FormCreate
- OnShow = FormShow
- DesignSize = (
- 496
- 134)
- PixelsPerInch = 96
- TextHeight = 13
- object btnOK: TButton
- Left = 254
- Top = 98
- Width = 115
- Height = 25
- Anchors = [akTop, akRight]
- Caption = '&OK'
- Default = True
- ModalResult = 1
- TabOrder = 0
- OnClick = btnOKClick
- end
- object btnCancel: TButton
- Left = 376
- Top = 98
- Width = 111
- Height = 25
- Anchors = [akTop, akRight]
- Caption = 'Cancel'
- ModalResult = 2
- TabOrder = 1
- end
- object GroupBox1: TGroupBox
- Left = 8
- Top = 237
- Width = 481
- Height = 57
- Anchors = [akLeft, akTop, akRight]
- Caption = ' Destination '
- TabOrder = 2
- Visible = False
- DesignSize = (
- 481
- 57)
- object btnBrowse: TSpeedButton
- Left = 448
- Top = 19
- Width = 24
- Height = 24
- Hint = 'Browse...'
- Anchors = [akTop, akRight]
- Flat = True
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Arial'
- Font.Style = [fsBold]
- Glyph.Data = {
- 36030000424D3603000000000000360000002800000010000000100000000100
- 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF
- FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
- FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
- 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F
- 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13
- 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708
- 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3
- 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367
- 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51
- C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF
- 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC
- EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67
- D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2
- 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8
- FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788
- A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6
- A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788
- 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89
- 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA
- ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00
- FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF
- 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
- FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
- FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
- 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
- ParentFont = False
- ParentShowHint = False
- ShowHint = True
- OnClick = btnBrowseClick
- end
- object Label10: TPanel
- Left = 8
- Top = 20
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'File name'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 1
- end
- object txtFilename: TEdit
- Left = 112
- Top = 20
- Width = 337
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- TabOrder = 0
- end
- end
- object GroupBox3: TGroupBox
- Left = 256
- Top = 10
- Width = 233
- Height = 79
- Anchors = [akTop, akRight]
- Caption = ' Quality '
- TabOrder = 3
- DesignSize = (
- 233
- 79)
- object udOversample: TUpDown
- Left = 212
- Top = 44
- Width = 12
- Height = 21
- Anchors = [akTop, akRight]
- Associate = txtOversample
- Min = 1
- Max = 4
- Position = 2
- TabOrder = 2
- end
- object Label5: TPanel
- Left = 8
- Top = 20
- Width = 113
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Filter radius'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 3
- end
- object txtFilterRadius: TEdit
- Left = 120
- Top = 20
- Width = 105
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- TabOrder = 0
- OnChange = txtFilterRadiusChange
- end
- object Label3: TPanel
- Left = 8
- Top = 44
- Width = 113
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Oversample'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 4
- end
- object txtOversample: TEdit
- Left = 120
- Top = 44
- Width = 92
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- ReadOnly = True
- TabOrder = 1
- Text = '2'
- OnChange = txtOversampleChange
- end
- end
- object GroupBox2: TGroupBox
- Left = 8
- Top = 10
- Width = 241
- Height = 111
- Anchors = [akLeft, akTop, akRight]
- Caption = ' Size '
- TabOrder = 4
- DesignSize = (
- 241
- 111)
- object Label13: TLabel
- Left = 184
- Top = 36
- Width = 26
- Height = 13
- Anchors = [akLeft, akTop, akRight]
- Caption = 'pixels'
- Visible = False
- end
- object Label16: TLabel
- Left = 168
- Top = 22
- Width = 15
- Height = 36
- Anchors = [akLeft, akTop, akRight]
- Caption = '}'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -32
- Font.Name = 'Times New Roman'
- Font.Style = []
- ParentFont = False
- Visible = False
- end
- object chkMaintain: TCheckBox
- Left = 8
- Top = 76
- Width = 225
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Maintain aspect ratio'
- Checked = True
- State = cbChecked
- TabOrder = 0
- OnClick = chkMaintainClick
- end
- object Label1: TPanel
- Left = 8
- Top = 20
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Width'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 3
- end
- object Label2: TPanel
- Left = 8
- Top = 44
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Height'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 4
- end
- object cbHeight: TComboBox
- Left = 112
- Top = 44
- Width = 121
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- ItemHeight = 13
- TabOrder = 2
- OnChange = txtHeightChange
- Items.Strings = (
- '200'
- '240'
- '480'
- '600'
- '768'
- '1024'
- '1200'
- '2048'
- '2400')
- end
- object cbWidth: TComboBox
- Left = 112
- Top = 20
- Width = 121
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- ItemHeight = 13
- TabOrder = 1
- OnChange = txtWidthChange
- Items.Strings = (
- '320'
- '640'
- '800'
- '1024'
- '1280'
- '1600'
- '1920'
- '2048'
- '2560'
- '3200')
- end
- end
- object GroupBox4: TGroupBox
- Left = 8
- Top = 392
- Width = 377
- Height = 113
- Anchors = [akLeft, akTop, akRight]
- Caption = ' Parameters '
- TabOrder = 5
- Visible = False
- DesignSize = (
- 377
- 113)
- object udStrips: TUpDown
- Left = 172
- Top = 52
- Width = 12
- Height = 21
- Associate = txtStrips
- Min = 1
- Max = 512
- Position = 1
- TabOrder = 2
- end
- object Label7: TPanel
- Left = 8
- Top = 20
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Buffer depth'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 7
- end
- object Label8: TPanel
- Left = 8
- Top = 52
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Strips'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 8
- end
- object Label9: TPanel
- Left = 8
- Top = 84
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'DE Radius'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 9
- end
- object txtEstimator: TEdit
- Left = 112
- Top = 84
- Width = 73
- Height = 21
- TabOrder = 3
- Text = '5'
- end
- object txtStrips: TEdit
- Left = 112
- Top = 52
- Width = 60
- Height = 21
- TabOrder = 1
- Text = '1'
- end
- object cmbDepth: TComboBox
- Left = 112
- Top = 20
- Width = 73
- Height = 21
- Style = csDropDownList
- ItemHeight = 13
- TabOrder = 0
- Items.Strings = (
- '16-bit'
- '32-bit'
- '32-bit float'
- '64-bit')
- end
- object Label14: TPanel
- Left = 192
- Top = 20
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Gamma threshold'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 10
- end
- object Label12: TPanel
- Left = 192
- Top = 52
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'DE Curve'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 11
- end
- object Label11: TPanel
- Left = 192
- Top = 84
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'DE Minimum'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 12
- end
- object txtGammaTreshold: TEdit
- Left = 296
- Top = 20
- Width = 73
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- TabOrder = 6
- Text = '0.01'
- OnChange = txtGammaTresholdChange
- end
- object txtEstimatorCurve: TEdit
- Left = 296
- Top = 52
- Width = 73
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- TabOrder = 5
- Text = '0.6'
- end
- object txtEstimatorMin: TEdit
- Left = 296
- Top = 84
- Width = 73
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- TabOrder = 4
- Text = '0'
- end
- end
- object chkRender: TCheckBox
- Left = 392
- Top = 398
- Width = 89
- Height = 43
- Anchors = [akTop, akRight]
- Caption = 'Render'
- Checked = True
- State = cbChecked
- TabOrder = 6
- Visible = False
- end
- object Panel1: TPanel
- Left = 8
- Top = 296
- Width = 481
- Height = 89
- Anchors = [akLeft, akTop, akRight]
- BevelKind = bkSoft
- BevelOuter = bvNone
- Color = clInfoBk
- TabOrder = 7
- Visible = False
- DesignSize = (
- 477
- 85)
- object Label6: TLabel
- Left = 8
- Top = 4
- Width = 453
- Height = 24
- Alignment = taCenter
- Anchors = [akLeft, akTop, akRight]
- AutoSize = False
- Caption = 'WARNING!'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clInfoText
- Font.Height = -19
- Font.Name = 'MS Sans Serif'
- Font.Style = [fsBold]
- ParentFont = False
- end
- object Label15: TLabel
- Left = 8
- Top = 25
- Width = 447
- Height = 26
- Alignment = taCenter
- Anchors = [akLeft, akRight]
- Caption =
- 'Fractals created with this version of Apophysis are not supporte' +
- 'd by the external renderer! To render 2D-only fractals, download' +
- ' the latest version of FLAM3 from http://www.flam3.com'
- Color = clInfoBk
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clInfoText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentColor = False
- ParentFont = False
- WordWrap = True
- end
- end
- object txtDensity: TEdit
- Left = 120
- Top = 212
- Width = 105
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- TabOrder = 8
- Visible = False
- OnChange = txtDensityChange
- end
- object Label4: TPanel
- Left = 8
- Top = 212
- Width = 113
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Density'
- ParentShowHint = False
- ShowHint = True
- TabOrder = 9
- Visible = False
- end
- object SaveDialog: TSaveDialog
- DefaultExt = 'jpg'
- Filter =
- 'JPEG Image (*.jpg)|*.jpg|PPM Image (*.ppm)|*.ppm|PNG Images (*.p' +
- 'ng)|*.png'
- Left = 464
- Top = 264
- end
-end
diff --git a/Forms/FormExportC.pas b/Forms/FormExportC.pas
deleted file mode 100644
index 7902f18..0000000
--- a/Forms/FormExportC.pas
+++ /dev/null
@@ -1,257 +0,0 @@
-{
- Apophysis Copyright (C) 2001-2004 Mark Townsend
- Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
- Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
-
- Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
- Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
-
- 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; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-}
-unit FormExportC;
-
-interface
-
-uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, Buttons, ComCtrls, ExtCtrls, Translation;
-
-type
- TExportCDialog = class(TForm)
- btnOK: TButton;
- btnCancel: TButton;
- GroupBox1: TGroupBox;
- btnBrowse: TSpeedButton;
- txtFilename: TEdit;
- SaveDialog: TSaveDialog;
- GroupBox3: TGroupBox;
- txtOversample: TEdit;
- txtFilterRadius: TEdit;
- udOversample: TUpDown;
- GroupBox2: TGroupBox;
- chkMaintain: TCheckBox;
- cbWidth: TComboBox;
- cbHeight: TComboBox;
- GroupBox4: TGroupBox;
- cmbDepth: TComboBox;
- chkRender: TCheckBox;
- txtStrips: TEdit;
- udStrips: TUpDown;
- txtEstimator: TEdit;
- txtEstimatorMin: TEdit;
- txtEstimatorCurve: TEdit;
- txtGammaTreshold: TEdit;
- Panel1: TPanel;
- Label6: TLabel;
- Label15: TLabel;
- Label13: TLabel;
- Label16: TLabel;
- Label5: TPanel;
- Label3: TPanel;
- Label1: TPanel;
- Label2: TPanel;
- Label7: TPanel;
- Label8: TPanel;
- Label9: TPanel;
- Label14: TPanel;
- Label12: TPanel;
- Label11: TPanel;
- Label10: TPanel;
- txtDensity: TEdit;
- Label4: TPanel;
- procedure FormCreate(Sender: TObject);
- procedure btnBrowseClick(Sender: TObject);
- procedure FormShow(Sender: TObject);
- procedure btnOKClick(Sender: TObject);
- procedure txtWidthChange(Sender: TObject);
- procedure chkMaintainClick(Sender: TObject);
- procedure txtHeightChange(Sender: TObject);
- procedure txtDensityChange(Sender: TObject);
- procedure txtFilterRadiusChange(Sender: TObject);
- procedure txtOversampleChange(Sender: TObject);
- procedure txtGammaTresholdChange(Sender: TObject);
- private
- FloatFormatSettings: TFormatSettings;
- Estimator, EstimatorMin, EstimatorCurve: double;
- Jitters, Batches, Strips: integer;
- public
- Filename: string;
- ImageWidth, ImageHeight, Oversample: Integer;
- Sample_Density, Filter_Radius: double;
- GammaTreshold: double;
- end;
-
-var
- ExportCDialog: TExportCDialog;
- Ratio: double;
-
-implementation
-uses Global, Main, ShellAPI;
-
-{$R *.DFM}
-
-procedure TExportCDialog.btnBrowseClick(Sender: TObject);
-begin
- SaveDialog.InitialDir := ExtractFileDir(txtFilename.text);
- SaveDialog.Filename := txtFilename.Text;
- SaveDialog.DefaultExt := 'png';
- SaveDialog.filterIndex := ExportFileFormat;
- SaveDialog.Filter := Format('%s|*.png|%s|*.*',
- [TextByKey('common-filter-png'),
- TextByKey('common-filter-allfiles')]);
- if SaveDialog.Execute then
- begin
- ExportFileFormat := SaveDialog.FilterIndex;
- renderPath := ExtractFilePath(SaveDialog.Filename);
- end;
-
-end;
-
-procedure TExportCDialog.FormShow(Sender: TObject);
-begin
- txtFilename.Text := Filename;
- cbWidth.Text := IntToStr(MainCp.Width);
- cbHeight.Text := IntToStr(MainCp.Height);
- ImageWidth := MainCp.Width;
- ImageHeight := MainCp.Height;
- txtDensity.text := FloatToStr(Sample_density);
-// if cmbDepth.ItemIndex <> 2 then
-// txtBatches.text := IntToStr(Round(Sample_density / 4));
- txtFilterRadius.text := FloatToStr(Filter_Radius);
- txtOversample.text := IntToSTr(Oversample);
- udOversample.Position := Oversample;
- Ratio := ImageWidth / ImageHeight;
- Batches := 1;
- Estimator := 9.0;
- EstimatorMin := 0.0;
- EstimatorCurve := 0.4;
- Jitters := 1;
- GammaTreshold := MainCP.gamma_threshold; //0.01;
- GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FloatFormatSettings);
- txtEstimator.Text := FloatToStr(Estimator, FloatFormatSettings);
- txtEstimatorMin.Text := FloatToStr(EstimatorMin, FloatFormatSettings);
- txtEstimatorCurve.Text := FloatToStr(EstimatorCurve, FloatFormatSettings);
-// txtJitters.Text := IntToStr(Jitters);
- txtGammaTreshold.Text := FloatToStr(GammaTreshold, FloatFormatSettings);
-end;
-
-procedure TExportCDialog.btnOKClick(Sender: TObject);
-begin
- Filename := txtFilename.text;
- ImageWidth := StrToInt(cbWidth.Text);
- ImageHeight := StrToInt(cbHeight.Text);
-end;
-
-procedure TExportCDialog.txtWidthChange(Sender: TObject);
-begin
- try
- ImageWidth := StrToInt(cbWidth.Text);
- if chkMaintain.checked and cbWidth.Focused then
- begin
- ImageHeight := Round(ImageWidth / ratio);
- cbHeight.Text := IntToStr(ImageHeight)
- end;
- except
- end;
-end;
-
-procedure TExportCDialog.chkMaintainClick(Sender: TObject);
-begin
- Ratio := ImageWidth / ImageHeight;
-end;
-
-procedure TExportCDialog.txtHeightChange(Sender: TObject);
-begin
- try
- ImageHeight := StrToInt(cbHeight.Text);
- if chkMaintain.checked and cbHeight.Focused then
- begin
- ImageWidth := Round(ImageHeight * ratio);
- cbWidth.Text := IntToStr(ImageWidth)
- end;
- except
- end;
-end;
-
-procedure TExportCDialog.txtDensityChange(Sender: TObject);
-begin
- try
- Sample_Density := StrToFloat(txtDensity.Text);
-// if cmbDepth.ItemIndex <> 2 then
-// txtBatches.text := IntToStr(Round(Sample_density / 4));
- except
- end;
-end;
-
-procedure TExportCDialog.txtFilterRadiusChange(Sender: TObject);
-begin
- try
- Filter_Radius := StrToFloat(txtFilterRadius.Text);
- except
- end;
-end;
-
-procedure TExportCDialog.txtOversampleChange(Sender: TObject);
-begin
- if StrToInt(txtOversample.Text) > udOversample.Max then
- txtOversample.Text := IntToStr(udOversample.Max);
- if StrToInt(txtOversample.Text) < udOversample.Min then
- txtOversample.Text := IntToStr(udOversample.Min);
- try
- Oversample := StrToInt(txtOversample.Text);
- except
- end;
-end;
-
-procedure TExportCDialog.txtGammaTresholdChange(Sender: TObject);
-begin
- //GammaTreshold := 0.01;
- try
- GammaTreshold := StrToFloat(txtGammaTreshold.Text, FloatFormatSettings);
- except
- end;
-end;
-
-procedure TExportCDialog.FormCreate(Sender: TObject);
-begin
- btnOK.Caption := TextByKey('common-ok');
- btnCancel.Caption := TextByKey('common-cancel');
- Label1.Caption := TextByKey('common-width');
- Label2.Caption := TextByKey('common-height');
- GroupBox2.Caption := TextByKey('common-size');
- Label13.Caption := TextByKey('common-pixels');
- chkMaintain.Caption := TextByKey('common-keepaspect');
- GroupBox1.Caption := TextByKey('common-destination');
- Label10.Caption := TextByKey('common-filename');
- btnBrowse.Hint := TextByKey('common-browse');
- GroupBox3.Caption := TextByKey('common-quality');
- Label5.Caption := TextByKey('common-filterradius');
- Label4.Caption := TextByKey('common-density');
- Label3.Caption := TextByKey('common-oversample');
- Label14.Caption := TextByKey('common-gammathreshold');
- self.Caption := TextByKey('main-menu-file-exportchaotica');
- GroupBox4.Caption := TextByKey('export-paramoptions-title');
- Label7.Caption := TextByKey('export-paramoptions-bufferdepth');
- Label8.Caption := TextByKey('export-paramoptions-strips');
- Label9.Caption := TextByKey('export-paramoptions-estimatorradius');
- Label12.Caption := TextByKey('export-paramoptions-estimatorcurve');
- Label11.Caption := TextByKey('export-paramoptions-estimatormin');
- chkRender.Caption := TextByKey('export-paramoptions-dorender');
- Label6.Caption := TextByKey('export-paramoptions-warningtitle');
- Label15.Caption := TextByKey('export-paramoptions-warningtext');
-end;
-
-end.
-
diff --git a/Forms/FormFavorites.pas b/Forms/FormFavorites.pas
index f29a2a5..87939df 100644
--- a/Forms/FormFavorites.pas
+++ b/Forms/FormFavorites.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ExtCtrls, ComCtrls, Translation, Vcl.Buttons;
+ StdCtrls, ExtCtrls, ComCtrls, Vcl.Buttons;
type
TFavoritesForm = class(TForm)
@@ -66,7 +66,8 @@ var
implementation
-uses Global, ScriptForm;
+uses Global, ScriptForm, Translation;
+
{$R *.DFM}
procedure TFavoritesForm.FormShow(Sender: TObject);
@@ -85,15 +86,9 @@ begin
Listitem.Caption := s;
end;
if Favorites.Count <> 0 then
- ScriptList.Selected := ScriptList.Items[0]
- else
- btnRemove.Enabled := False;
+ ScriptList.Selected := ScriptList.Items[0];
- if ScriptList.Items.Count <= 1 then
- begin
- btnMoveUp.Enabled := False;
- btnMoveDown.Enabled := False;
- end;
+ ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnOKClick(Sender: TObject);
@@ -130,8 +125,9 @@ var
begin
s := AppPath + 'Scripts';
if DirectoryExists(s) then
- ScriptEditor.MainOpenDialog.InitialDir := s
- else ScriptEditor.MainOpenDialog.InitialDir := ParamFolder;
+ ScriptEditor.MainOpenDialog.InitialDir := s
+ else
+ ScriptEditor.MainOpenDialog.InitialDir := ParamFolder;
ScriptEditor.MainOpenDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*',
[TextByKey('common-filter-scriptfiles'),
TextByKey('common-filter-allfiles')]);
@@ -148,14 +144,9 @@ begin
s := Copy(s, 0, length(s) - Length(ExtractFileExt(s)));
Listitem.Caption := s;
ScriptList.Selected := ScriptList.Items[ScriptList.Items.Count - 1];
- btnRemove.Enabled := True;
end;
- if ScriptList.Items.Count <= 1 then
- begin
- btnMoveUp.Enabled := False;
- btnMoveDown.Enabled := False;
- end;
+ ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnRemoveClick(Sender: TObject);
@@ -170,15 +161,9 @@ begin
if i < ScriptList.Items.Count then
ScriptList.Selected := ScriptList.Items[i]
else
- ScriptList.Selected := ScriptList.Items[ScriptList.Items.Count - 1]
- else
- btnRemove.Enabled := False;
+ ScriptList.Selected := ScriptList.Items[ScriptList.Items.Count - 1];
- if ScriptList.Items.Count <= 1 then
- begin
- btnMoveUp.Enabled := False;
- btnMoveDown.Enabled := False;
- end;
+ ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnSortClick(Sender: TObject);
@@ -200,27 +185,35 @@ begin
end;
ScriptList.Items.EndUpdate;
scripts.Free;
+ ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.ScriptListChange(Sender: TObject; Item: TListItem;
Change: TItemChange);
+var
+ n: smallint;
+ IsSel: boolean;
begin
- // TODO: optimize old code
- btnRemove.Enabled := (ScriptList.Items.Count > 0);
+ n := ScriptList.Items.Count;
+ IsSel := assigned(ScriptList.Selected);
- if (Item.Index = ScriptList.Items.Count - 1) then
- btnMoveDown.Enabled := False
- else
- btnMoveDown.Enabled := True;
- if (Item.Index = 0) then
- btnMoveUp.Enabled := False
- else
- btnMoveUp.Enabled := True;
+ btnRemove.Enabled := (n > 0) and IsSel;
+ btnSort.Enabled := (n > 1);
- if (ScriptList.Items.Count <= 1) then
+ if (n <= 1) or (not IsSel) then
begin
btnMoveDown.Enabled := False;
btnMoveUp.Enabled := False;
+ end
+ else begin
+ if (Item.Index = n - 1) then
+ btnMoveDown.Enabled := False
+ else
+ btnMoveDown.Enabled := True;
+ if (Item.Index = 0) then
+ btnMoveUp.Enabled := False
+ else
+ btnMoveUp.Enabled := True;
end;
end;
@@ -250,7 +243,7 @@ procedure TFavoritesForm.btnClearClick(Sender: TObject);
begin
ScriptList.Items.Clear;
Faves.Clear;
- btnRemove.Enabled := False;
+ ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnMoveDownClick(Sender: TObject);
diff --git a/Forms/FormRender.dfm b/Forms/FormRender.dfm
index 9de91d0..4231bb1 100644
--- a/Forms/FormRender.dfm
+++ b/Forms/FormRender.dfm
@@ -241,19 +241,6 @@ object RenderForm: TRenderForm
DesignSize = (
233
97)
- object lblRatio: TLabel
- Left = 12
- Top = 72
- Width = 56
- Height = 13
- Caption = 'Aspect ratio'
- Font.Charset = DEFAULT_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'MS Sans Serif'
- Font.Style = []
- ParentFont = False
- end
object pnlWidth: TPanel
Left = 8
Top = 20
@@ -349,9 +336,9 @@ object RenderForm: TRenderForm
'3200')
end
object cbAspectRatio: TComboBox
- Left = 101
- Top = 70
- Width = 123
+ Left = 100
+ Top = 68
+ Width = 125
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
@@ -372,6 +359,21 @@ object RenderForm: TRenderForm
'16 : 10'
'21 : 9 (CinemaScope)')
end
+ object lblRatio: TPanel
+ Left = 8
+ Top = 68
+ Width = 92
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Aspect ratio'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 5
+ end
end
object GroupBox3: TGroupBox
Left = 248
@@ -874,10 +876,6 @@ object RenderForm: TRenderForm
object TabOutput: TTabSheet
Caption = 'Output'
ImageIndex = 38
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
object Output: TMemo
Left = 0
Top = 0
@@ -958,13 +956,142 @@ object RenderForm: TRenderForm
OnClick = btnSnapshotClick
end
object SaveDialog: TSaveDialog
- Left = 456
+ Left = 448
Top = 72
end
object ProgressTaskbar: TTaskbar
- TaskBarButtons = <>
+ TaskBarButtons = <
+ item
+ Hint = 'Show image state...'
+ Icon.Data = {
+ 0000010001001616000000000000900600001600000028000000160000002C00
+ 0000010008000000000010020000000000000000000000010000000000005858
+ 5800B0B0B000F9F9F90092929200EAEAEA0083838300DBDBDB00AEAEAE004747
+ 47009F9F9F00E8E8E80081818100D9D9D90063636300BBBBBB00545454009D9D
+ 9D008E8E8E007F7F7F00D7D7D7007070700052525200AAAAAA008C8C8C00E4E4
+ E4007D7D7D00D5D5D5006E6E6E00C6C6C6005F5F5F0050505000A8A8A8007B7B
+ 7B00B5B5B5004E4E4E003F3F3F0097979700D1D1D100C2C2C2005B5B5B00B3B3
+ B300A4A4A4003D3D3D009595950086868600DEDEDE007777770068686800C0C0
+ C00059595900B1B1B1004A4A4A00A2A2A20084848400DCDCDC0075757500CDCD
+ CD006666660057575700AFAFAF004848480091919100DADADA00CBCBCB005555
+ 55009E9E9E00C9C9C90062626200BABABA009C9C9C008D8D8D007E7E7E00D6D6
+ D600C7C7C700F2F2F200E3E3E3007C7C7C00D4D4D4005E5E5E0040404000FFFF
+ FF009898980089898900E1E1E100B4B4B400FDFDFD003E3E3E00EEEEEE008787
+ 8700C1C1C100FBFBFB008585850076767600CECECE0000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000005050
+ 5050505050505050505050505050505050505050000050505050505050505050
+ 5050505050505050505050500000505050505050505050505050505050505050
+ 5050505000002A2A2A5050505050502A2A2A5050505050502A2A2A5000002A2A
+ 2A502A502A502A2A2A2A2A502A502A502A2A2A5000002A2A5050505050505050
+ 5050505050505050502A2A500000505050165151033D3D58523D3D5151415152
+ 505050500000502A502429584C332339374C583D51490952502A505000005050
+ 50472E35121041462A432A394C523D1B5050505000005008505C412A2A451F26
+ 162B4F2E402A433C502A505000005050502A3E3D2C172A0725500E102750050E
+ 5050505000000F1E502A3D5D32545139073F505D53575713502A2A5000000040
+ 50442A014B4B501C2A50444B04183E1C502A2A5000004E315021595050503B38
+ 4D0E0A5A505A0459502A2A5000005050501F0E59502149064806025050500242
+ 505050500000500D5034443F3F3F0C364D2D55505050553F502A505000005050
+ 50412830305959301C1A4A5050504A59505050500000501B50241F0101010101
+ 0101493E533E4901502A50500000505050112B24244541414141411F071F4141
+ 505050500000202E50505050505050505050505050505050502A2A5000000B4C
+ 2E5014502F504E273A152250085056502A2A2A5000005B0B195050505050501D
+ 27005050505050502A2A2A500000FFFFFF00FFFFFF00FFFFFF001F8FC7000000
+ 04000000040080000C0080000E0080000E0080000E0080000E00000006000000
+ 04000000040080000C0080000E0080000E0080000E0080000E00000006000000
+ 04001F8FC400}
+ end
+ item
+ Hint = 'Cancel current rendering'
+ Icon.Data = {
+ 0000010001001616000000000000100800001600000028000000160000002C00
+ 000001002000000000009007000000000000000000000000000000000000FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005555550E545454495454
+ 547E545454B2545454E5545454E5545454B25454547E545454495555550EFFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF0054545450545454E7515151FF4E4E4EFF4B4B4BFF4848
+ 48FF484848FF4B4B4BFF4E4E4EFF515151FF545454E754545450FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00565656115555
+ 55A4535353FF4C4C4CFF555555FF757575FF989898FFBFBFBFFFC0C0C0FF9C9C
+ 9CFF797979FF575757FF4C4C4CFF535353FF555555A456565611FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF0057575711565656E1525252FF494949FF8181
+ 81FFD9D9D9FFE5E5E5FFEBEBEBFFEEEEEEFFEFEFEFFFEEEEEEFFEBEBEBFFE2E2
+ E2FF8C8C8CFF494949FF525252FF565656E157575711FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00565656A4525252FF555555FFB1B1B1FFE1E1E1FFECECECFFF3F3
+ F3FFF8F8F8FFFBFBFBFFFBFBFBFFFBFBFBFFF8F8F8FFF3F3F3FFECECECFFC2C2
+ C2FF585858FF525252FF565656A4FFFFFF00FFFFFF00FFFFFF00575757505555
+ 55FF4A4A4AFFACACACFFE1E1E1FFEEEEEEFFF7F7F7FFFCFCFCFFFDFDFDFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFDFDFDFFFCFCFCFFF7F7F7FFEEEEEEFFC2C2C2FF4A4A
+ 4AFF555555FF57575750FFFFFF005959590E585858E74F4F4FFF7C7C7CFFDCDC
+ DCFFECECECFFF6F6F6FFE9E9E9FFEBEBEBFFEAEAEAFFE9E9E9FFE9E9E9FFE9E9
+ E9FFEAEAEAFFEBEBEBFFFAFAFAFFF7F7F7FFECECECFF8D8D8DFF4F4F4FFF5858
+ 58E75959590E5B5B5B49585858FF595959FFC8C8C8FFE5E5E5FFF3F3F3FFF2F2
+ F2FF5F5F5FFF515151FF464646FF3E3E3EFF3B3B3BFF3E3E3EFF464646FF5151
+ 51FFEBEBEBFFFCFCFCFFF3F3F3FFE2E2E2FF5B5B5BFF585858FF5B5B5B495D5D
+ 5D7E565656FF717171FFD5D5D5FFEBEBEBFFF8F8F8FFF2F2F2FF545454FF4444
+ 44FF363636FF2B2B2BFF272727FF2B2B2BFF363636FF444444FFEAEAEAFFFDFD
+ FDFFF8F8F8FFEBEBEBFF7C7C7CFF565656FF5D5D5D7E5F5F5FB2545454FF8989
+ 89FFDCDCDCFFEEEEEEFFFBFBFBFFF2F2F2FF4D4D4DFF3B3B3BFF2A2A2AFF1B1B
+ 1BFF131313FF1B1B1BFF2A2A2AFF3B3B3BFFE9E9E9FFFFFFFFFFFBFBFBFFEEEE
+ EEFF9E9E9EFF545454FF5F5F5FB2616161E5535353FFA4A4A4FFDDDDDDFFEFEF
+ EFFFFBFBFBFFF0F0F0FF4B4B4BFF383838FF252525FF121212FF000000FF1212
+ 12FF252525FF383838FFE8E8E8FFFFFFFFFFFBFBFBFFEFEFEFFFC1C1C1FF5353
+ 53FF616161E5636363E5555555FFA4A4A4FFDCDCDCFFEEEEEEFFFBFBFBFFF1F1
+ F1FF6A6A6AFF5E5E5EFF535353FF474747FF373737FF313131FF363636FF4040
+ 40FFE9E9E9FFFFFFFFFFFBFBFBFFEEEEEEFFC0C0C0FF555555FF636363E56565
+ 65B25A5A5AFF8A8A8AFFD5D5D5FFEEEEEEFFFAFAFAFFF4F4F4FF8C8C8CFF7A7A
+ 7AFF686868FF565656FF4B4B4BFF464646FF474747FF4D4D4DFFEAEAEAFFFDFD
+ FDFFF8F8F8FFEBEBEBFF9B9B9BFF5A5A5AFF656565B26767677E606060FF7575
+ 75FFDCDCDCFFF1F1F1FFF8F8F8FFF2F2F2FF939393FF838383FF747474FF6565
+ 65FF5B5B5BFF565656FF565656FF595959FFEBEBEBFFFCFCFCFFF3F3F3FFE5E5
+ E5FF7C7C7CFF606060FF6767677E6B6B6B49676767FF636363FFC5C5C5FFECEC
+ ECFFF4F4F4FFEFEFEFFF979797FF8E8E8EFF818181FF747474FF6B6B6BFF6767
+ 67FF656565FF686868FFE9E9E9FFF7F7F7FFECECECFFDADADAFF636363FF6767
+ 67FF6B6B6B497070700E6F6F6FE7636363FF828282FFDCDCDCFFEDEDEDFFF3F3
+ F3FFEEEEEEFFF1F1F1FFF1F1F1FFF3F3F3FFF3F3F3FFF4F4F4FFF3F3F3FFF3F3
+ F3FFF6F6F6FFEEEEEEFFE1E1E1FF888888FF636363FF6F6F6FE77070700EFFFF
+ FF00727272506F6F6FFF5E5E5EFFA9A9A9FFDEDEDEFFECECECFFF2F2F2FFF6F6
+ F6FFFAFAFAFFFCFCFCFFFCFCFCFFFCFCFCFFF9F9F9FFF4F4F4FFECECECFFE1E1
+ E1FFB3B3B3FF5E5E5EFF6F6F6FFF72727250FFFFFF00FFFFFF00FFFFFF007575
+ 75A46F6F6FFF686868FFAAAAAAFFD7D7D7FFE7E7E7FFECECECFFF0F0F0FFF1F1
+ F1FFF2F2F2FFF0F0F0FFEDEDEDFFE6E6E6FFDCDCDCFFAFAFAFFF686868FF6F6F
+ 6FFF757575A4FFFFFF00FFFFFF00FFFFFF00FFFFFF0079797911787878E17171
+ 71FF636363FF858585FFC2C2C2FFD6D6D6FFDFDFDFFFE3E3E3FFE3E3E3FFE0E0
+ E0FFD8D8D8FFCACACAFF858585FF636363FF717171FF787878E179797911FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007D7D7D117B7B7BA4797979FF6E6E
+ 6EFF6E6E6EFF7C7C7CFF8F8F8FFFA9A9A9FFA8A8A8FF8F8F8FFF7C7C7CFF6E6E
+ 6EFF6E6E6EFF797979FF7B7B7BA47D7D7D11FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007F7F7F507F7F7FE77B7B7BFF7676
+ 76FF727272FF6E6E6EFF6E6E6EFF727272FF767676FF7B7B7BFF7F7F7FE77F7F
+ 7F50FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF008585850E838383498383837E848484B28484
+ 84E5848484E5848484B28383837E838383498585850EFFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FF87FF00FC00FF00F0003F00E0001F00C000
+ 0F00C0000F008000070080000600800006000000020000000000000000000000
+ 0000800004008000060080000600C0000E00C0000F00E0001F00F0003F00FC00
+ FF00FF87FF00}
+ end>
ProgressMaxValue = 100
TabProperties = []
+ OnThumbButtonClick = ProgressTaskbarThumbButtonClick
Left = 432
Top = 424
end
diff --git a/Forms/FormRender.pas b/Forms/FormRender.pas
index eef8f1e..2c0ebf3 100644
--- a/Forms/FormRender.pas
+++ b/Forms/FormRender.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,10 +27,10 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ComCtrls, Math, Buttons, Registry, ExtCtrls, MMSystem, // Windows7,
+ StdCtrls, ComCtrls, Math, Buttons, Registry, ExtCtrls, MMSystem,
System.Win.TaskbarCore, Vcl.Taskbar, Vcl.Samples.Spin, // AV
- ControlPoint, RenderThread, cmap, RenderingCommon, RenderingInterface,
- ShellAPI, Translation, ActiveX, ComObj;
+ ControlPoint, cmap, RenderThread, RenderingInterface,
+ ShellAPI, ActiveX, ComObj;
const
{$ifdef T500}
@@ -38,6 +38,10 @@ const
{$else}
rendersAV = 'rendersAV.flame';
{$endif}
+
+type
+ TWin32Version = (wvUnknown, wvWin95, wvWin98, wvWinNT, wvWin2000, wvWinXP,
+ wvWinVista, wvWin7, wvWinFutureFromOuterSpace);
type
TRenderForm = class(TForm)
@@ -93,12 +97,12 @@ type
chkSaveIncompleteRenders: TCheckBox;
lblCPUCores: TLabel;
cbAspectRatio: TComboBox;
- lblRatio: TLabel;
chkEmbedFlame: TCheckBox;
chkPlaySound: TCheckBox;
btnSnapshot: TButton;
ProgressTaskbar: TTaskbar;
sbFilterRadius: TSpinButton;
+ lblRatio: TPanel;
procedure btnSaveLogClick(Sender: TObject);
procedure btnDonateClick(Sender: TObject);
procedure cbMaxMemoryChange(Sender: TObject);
@@ -133,10 +137,12 @@ type
procedure txtDensityExit(Sender: TObject);
procedure cbWidthExit(Sender: TObject);
procedure cbHeightExit(Sender: TObject);
+ procedure ProgressTaskbarThumbButtonClick(Sender: TObject;
+ AButtonID: Integer);
private
StartTime, EndTime, oldElapsed, edt: TDateTime;
oldProg: double;
-
+ PhysicalMemory, ApproxMemory, TotalPhysicalMemory: int64;
ApproxSamples: int64;
procedure DoPostProcess;
@@ -148,27 +154,28 @@ type
procedure ListPresets;
function WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean;
procedure Save(const str: string);
- function IsLimitingMemory():boolean;
-
+ function IsLimitingMemory(): boolean;
+ procedure OnProgress(prog: double);
+ procedure ShowMemoryStatus;
public
Renderer: TRenderThread;
- PhysicalMemory, ApproxMemory, TotalPhysicalMemory: int64;
- ColorMap: TColorMap;
+
+ //ColorMap: TColorMap;
cp: TControlPoint;
Filename: string;
ImageWidth, ImageHeight, Oversample: Integer;
- // BitsPerSample: integer; Brightness, Gamma, Vibrancy: double;
- zoom, Sample_Density, Filter_Radius: double;
- center: array[0..1] of double;
+ Sample_Density, Filter_Radius: double;
MaxMemory: integer;
bRenderAll: boolean;
- procedure OnProgress(prog: double);
- procedure ShowMemoryStatus;
+ RenderFlameFile: string; // AV
+ FlameNames: array of string; // AV
+
procedure ResetControls;
end;
function GetCpuCount: integer; // AV: this is used in Options
+function GetWinVersion: TWin32Version; // AV: moved from Main
var
RenderForm: TRenderForm;
@@ -177,7 +184,7 @@ var
implementation
uses
- Main, Global, SavePreset, formPostProcess, PngImage, ImageMaker,Tracer;
+ Main, Global, SavePreset, formPostProcess, ImageMaker, Tracer, Translation;
{$R *.DFM}
@@ -197,7 +204,6 @@ begin
txtOversample.Enabled := true;
//chkLimitMem.Enabled := true;
cbMaxMemory.enabled := true;
- //cbBitsPerSample.Enabled := true;
chkPostProcess.Enabled := not IsLimitingMemory;
chkSaveIncompleteRenders.Enabled := not IsLimitingMemory;
btnRender.Enabled := true;
@@ -225,7 +231,6 @@ begin
pnlOversample.Enabled := true;
pnlLimit.Enabled := true;
pnlTarget.Enabled := true;
- //pnlBufferDepth.Enabled := true;
pnlWidth.Font.Color := clWindowText;
pnlHeight.Font.Color := clWindowText;
@@ -234,27 +239,9 @@ begin
pnlOversample.Font.Color := clWindowText;
pnlLimit.Font.Color := clWindowText;
pnlTarget.Font.Color := clWindowText;
- //pnlBufferDepth.Font.Color := clWindowText;
ShowMemoryStatus;
end;
-procedure WinShellExecute(const Operation, AssociatedFile: string);
-var
- a1: string;
-begin
- a1 := Operation;
- if a1 = '' then
- a1 := 'open';
- ShellExecute(
- application.handle
- , pchar(a1)
- , pchar(AssociatedFile)
- , ''
- , ''
- , SW_SHOWNORMAL
- );
-end;
-
function GetCpuCount: integer;
var
si: TSystemInfo;
@@ -273,10 +260,11 @@ begin
TotalPhysicalMemory := GlobalMemoryInfo.dwTotalPhys div 1048576;
//TotalPhysicalMemory := TotalPhysicalMemory * 9 div 10; // assume that OS will take 10% of RAM ;)
- if SingleBuffer then
- ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 16 div 1048576
- else
- ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 32 div 1048576;
+ {$ifdef CPUX86}
+ ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 16 div 1048576;
+ {$else}
+ ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 32 div 1048576;
+ {$endif}
lblMemory.Caption := Format(TextByKey('render-resourceusage-infotext'), [ApproxMemory, PhysicalMemory]);
PBMem.Position := round(100 * (ApproxMemory / PhysicalMemory));
@@ -372,7 +360,7 @@ begin
on e: Exception do begin
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
tryAgain := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
- #13#10 + TextByKey('render-status-saveerror-message2')), 'Apophysis', MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY);
+ #13#10 + TextByKey('render-status-saveerror-message2')), ApophysisSVN, MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY);
// AV: displaying status in red
ProgressTaskBar.ProgressState := TTaskBarProgressState.Error;
end;
@@ -419,7 +407,6 @@ begin
Trace2(MsgAnotherRunning);
exit;
end;
-
{
// AV: temporary commented out since undestroyed TBaseRenderer objects
// from Renderer.GetRenderer method cause regular large memory leaks!
@@ -428,7 +415,7 @@ begin
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-renderhibernated'))
else }
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-renderterminated'));
-
+
Output.Lines.Add('');
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
@@ -466,9 +453,10 @@ begin
prog := (Renderer.Slice + Prog) / Renderer.NrSlices;
if ShowProgress then begin
- ProgressBar2.Position := round(100 * prog);
- // AV: to display the progress on the taskbar
- ProgressTaskBar.ProgressValue := ProgressBar2.Position; // AV
+ ProgressBar2.Position := round(100 * prog);
+ // AV: to display the progress on the taskbar
+ //ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
+ ProgressTaskBar.ProgressValue := ProgressBar2.Position; // AV
end;
StatusBar.Panels[0].text := Format(TextByKey('render-status-elapsed') + ': %2.2d:%2.2d:%2.2d.%2.2d',
@@ -491,13 +479,32 @@ begin
Trunc(Remaining * 24 * 60 * 60 * 100) mod 100]);
end;
StatusBar.Panels[2].text := Format(TextByKey('render-status-slicestatus'), [(Renderer.Slice + 1), (Renderer.nrSlices)]);
- //'Slice ' + IntToStr(Renderer.Slice + 1) + ' of ' + IntToStr(Renderer.nrSlices);
+
Application.ProcessMessages;
end;
+procedure TRenderForm.ProgressTaskbarThumbButtonClick(Sender: TObject;
+ AButtonID: Integer);
+begin
+ if AButtonID = 0 then
+ begin
+ if Assigned(Renderer) and (not bRenderAll) then begin
+ if Renderer.Suspended = false then
+ begin
+ Renderer.Suspend;
+ btnSnapshotClick(Sender);
+ Renderer.Resume;
+ end else
+ btnSnapshotClick(Sender);
+ end;
+ end
+ else
+ btnCancelClick(Sender);
+end;
+
procedure TRenderForm.FormCreate(Sender: TObject);
begin
-{$ifdef Apo7X64}
+{$ifdef CPUX64}
cbMaxMemory.Items.Add('2048');
cbMaxMemory.Items.Add('3072');
cbMaxMemory.Items.Add('4096');
@@ -519,12 +526,12 @@ begin
btnPause.Caption := TextByKey('common-pause');
btnCancel.Caption := TextByKey('common-close');
self.Caption := TextByKey('render-title');
+ self.Hint := self.Caption; // AV: hack
TabSettings.Caption := TextByKey('render-tab-settings-title');
TabOutput.Caption := TextByKey('render-tab-output-title');
btnGoTo.Hint := TextByKey('render-common-gotofolder');
GroupBox4.Caption := TextByKey('render-resourceusage-title');
pnlLimit.Caption := TextByKey('render-resourceusage-limit');
- //pnlBufferDepth.Caption := TextByKey('render-resourceusage-bufferdepth');
chkSave.Caption := TextByKey('render-output-saveparams1');
chkEmbedFlame.Caption := TextByKey('render-output-saveparams2');
GroupBox6.Caption := TextByKey('render-completion-title');
@@ -541,11 +548,18 @@ begin
btnDonate.Hint := TextByKey('common-donatehint');
btnSnapshot.Caption := TextByKey('render-status-dosnapshot'); // AV
btnSnapshot.Hint := TextByKey('render-status-dosnapshothint');
+ ProgressTaskbar.TaskbarButtons[1].Hint := TextByKey('render-status-stop');
+ ProgressTaskbar.TaskbarButtons[0].Hint := TextByKey('render-status-showimage');
+
+ // AV: fixed the filter order and moved this here since it never changes
+ SaveDialog.Filter := Format('%s|*.bmp;*.dib|%s|*.png|%s|*.jpg;*.jpeg|%s|*.bmp;*.dib;*.jpg;*.jpeg;*.png',
+ [TextByKey('common-filter-bitmap'), TextByKey('common-filter-png'),
+ TextByKey('common-filter-jpeg'), TextByKey('common-filter-allimages')]);
cp := TControlPoint.Create;
cbMaxMemory.ItemIndex := 0;
cbAspectRatio.ItemIndex := 1; // AV
- // BitsPerSample := 0;
+
MainForm.Buttons.GetBitmap(2, btnSavePreset.Glyph);
// MainForm.Buttons.GetBitmap(9, btnDeletePreset.Glyph);
bRenderAll := false;
@@ -576,11 +590,10 @@ end;
procedure TRenderForm.btnRenderClick(Sender: TObject);
var
- t: string;
iCurrFlame: integer;
- path, ext: string;
- lim:integer;
- ilm:boolean;
+ t, ext: string;
+ lim: integer;
+ ilm: boolean;
{ sl: TStringList;
tryAgain: boolean;
cancel: boolean;
@@ -599,10 +612,9 @@ begin
on e: Exception do begin
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
result := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
- #13#10 + TextByKey('render-status-saveerror-message2')), 'Apophysis', MB_RETRYCANCEL or MB_ICONERROR));
+ #13#10 + TextByKey('render-status-saveerror-message2')), ApophysisSVN, MB_RETRYCANCEL or MB_ICONERROR));
tryAgain := (result = IDRETRY);
cancel := (result = IDCANCEL);
- ProgressBar2.ProgressBarState := pbstError;
end;
end;
until (tryAgain = false) or (cancel = true);
@@ -624,34 +636,25 @@ begin
if not ilm then begin
if (ApproxMemory > {Total}PhysicalMemory) then
begin
- if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory1')), 'Apophysis', MB_ICONWARNING or MB_YESNO) then
- exit;
+ if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory1')),
+ ApophysisSVN, MB_ICONWARNING or MB_YESNO) then exit;
end;
-{
- if (ApproxMemory > PhysicalMemory) then
- begin
- if Application.MessageBox('There is not enough memory for this render. ' + #13 +
- 'You can use memory limiting, or - if you are sure that your system *should* ' + #13 +
- 'have the required amount of free RAM, you can try to allocate memory anyway. ' + #13#13 +
- 'Dou you want to try? (SLOW AND UNSTABLE - USE AT YOUR OWN RISK!!!)', 'Apophysis',
- MB_ICONWARNING or MB_YESNO) <> IDYES then exit;
- end;
-}
end
else if (PhysicalMemory < lim) and (Approxmemory > PhysicalMemory) then begin
- if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory2')), 'Apophysis', MB_ICONWARNING or MB_YESNO) then
- exit;
+ if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory2')),
+ ApophysisSVN, MB_ICONWARNING or MB_YESNO) then exit;
end;
t := txtFilename.Text;
- if t = '' then
- begin
- Application.MessageBox(PChar(TextByKey('render-status-nofilename')), 'Apophysis', 48);
- Exit;
+ if t = '' then begin
+ Application.MessageBox(PChar(TextByKey('render-status-nofilename')), ApophysisSVN, 48);
+ exit;
end;
+
if FileExists(t) then
- if Application.MessageBox(PChar(Format(TextByKey('render-status-fileexists-message1'), [t]) + #13#10 + TextByKey('render-status-fileexists-message2')),
- 'Apophysis', 52) = ID_NO then exit;
+ if Application.MessageBox(PChar(Format(TextByKey('render-status-fileexists-message1'),
+ [t]) + #13#10 + TextByKey('render-status-fileexists-message2')),
+ ApophysisSVN, 52) = ID_NO then exit;
if not DirectoryExists(ExtractFileDir(t)) then
raise Exception.Create(TextByKey('render-status-pathdoesnotexist')); // AV
@@ -665,7 +668,7 @@ begin
{
// AV: how is it possible, if (udOversample.Min = 1) and (txtOversample.ReadOnly = true)?
if Oversample < 1 then
- raise Exception.Create(TextByKey('render-status-invalidoversample')); // AV
+ raise Exception.Create(TextByKey('render-status-invalidoversample'));
}
if ImageWidth < 1 then
raise Exception.Create(TextByKey('render-status-invalidwidth')); // AV
@@ -676,13 +679,13 @@ begin
if (ilm) then
if lim * 1024*1024 < ImageWidth * (int64(ImageHeight) * 4 + oversample) then begin
// Must be enough memory to hold the final image (RGBA)
- if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-maxmemorytoosmall')), 'Apophysis', MB_ICONERROR or MB_YESNO) then
- exit;
+ if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-maxmemorytoosmall')),
+ ApophysisSVN, MB_ICONERROR or MB_YESNO) then exit;
end;
// AV: activate the taskbar progress
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
- ProgressTaskBar.ProgressValue := ProgressBar2.Position; // AV
+ ProgressTaskBar.ProgressValue := 0; // AV
txtFilename.Enabled := false;
btnBrowse.Enabled := false;
@@ -693,7 +696,6 @@ begin
txtOversample.Enabled := false;
//chkLimitMem.Enabled := true;
cbMaxMemory.Enabled := false;
- //cbBitsPerSample.Enabled := false;
cmbPreset.enabled := false;
chkSave.enabled := false;
chkPostProcess.enabled := false;
@@ -715,7 +717,6 @@ begin
pnlOversample.Enabled := false;
pnlLimit.Enabled := false;
pnlTarget.Enabled := false;
- //pnlBufferDepth.Enabled := false;
pnlWidth.Font.Color := clGrayText;
pnlHeight.Font.Color := clGrayText;
@@ -724,7 +725,6 @@ begin
pnlOversample.Font.Color := clGrayText;
pnlLimit.Font.Color := clGrayText;
pnlTarget.Font.Color := clGrayText;
- //pnlBufferDepth.Font.Color := clGrayText;
PageCtrl.TabIndex := 1;
@@ -732,8 +732,8 @@ begin
if bRenderAll then
begin
- path := ExtractFilePath(FileName);
- ext := ExtractFileExt(FileName);
+ renderPath := ExtractFilePath(FileName); // AV
+ ext := ExtractFileExt(FileName); // AV
if Assigned(Renderer) then begin
Output.Lines.Add(TimeToStr(Now) + TextByKey('render-status-shuttingdownrender'));
@@ -743,8 +743,9 @@ begin
Renderer := nil;
end;
- for iCurrFlame := 0 to MainForm.ListView1.Items.Count-1 do
+ for iCurrFlame := 0 to High(FlameNames) {MainForm.ListView1.Items.Count-1} do
begin
+ {
MainForm.ListView1.ItemIndex := iCurrFlame;
cp.Free;
cp := TControlPoint.Create;
@@ -753,20 +754,27 @@ begin
zoom := maincp.zoom;
Center[0] := MainForm.center[0];
Center[1] := MainForm.center[1];
- FileName := path + cp.name + ext;
+ }
+ t := LoadXMLFlameText(RenderFlameFile, FlameNames[iCurrFlame]); // AV
+ if t = '' then continue; // AV: user may delete an item from opened file
+ MainForm.ParseXML(cp, t, true); // the same was done via ListView - but slower
+
+ FileName := renderPath + cp.name + ext;
Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + ' ---');
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius]));
- if SingleBuffer then
- Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']))
- else
- Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
+
+ {$ifdef CPUX86}
+ Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']));
+ {$else}
+ Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
+ {$endif}
if (ilm) then
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [MaxMemory]))
else
- if (UpperCase(ExtractFileExt(FileName)) = '.PNG') and
+ if (UpperCase(ext) = '.PNG') and
(ImageWidth * ImageHeight >= 20000000) then
begin
Output.Lines.Add(TextByKey('render-status-log-largepng-message1'));
@@ -783,20 +791,27 @@ begin
cp.spatial_oversample := Oversample;
cp.spatial_filter_radius := Filter_Radius;
cp.AdjustScale(ImageWidth, ImageHeight);
- cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG');
- renderPath := ExtractFilePath(Filename);
- if chkSave.checked then
- MainForm.SaveXMLFlame(cp, ExtractFileName(FileName), renderPath + rendersAV);
+ cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ext) = '.PNG');
+ // renderPath := ExtractFilePath(Filename);
+ if chkSave.checked then begin // AV: added check for duplicates
+ t := ExtractFileName(FileName);
+ if XMLEntryExists(t, renderPath + rendersAV) then
+ t := t + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
+ MainForm.SaveXMLFlame(cp, t, renderPath + rendersAV);
+ end;
- oldProg:=0;
- oldElapsed:=0;
- edt:=0;
- ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
+ oldProg := 0;
+ oldElapsed := 0;
+ edt := 0;
+ ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) *
+ int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
+ ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
try
if not bRenderAll then exit;
- if iCurrFlame = MainForm.ListView1.Items.Count-1 then bRenderAll := false;
+ if iCurrFlame = High(FlameNames){MainForm.ListView1.Items.Count-1} then
+ bRenderAll := false;
Renderer := TRenderThread.Create;
assert(Renderer <> nil);
@@ -806,8 +821,8 @@ begin
else
Renderer.SetPriority(tpNormal);
}
- Renderer.ExportBuffer := chkBinary.Checked;
- // Renderer.BitsPerSample := BitsPerSample;
+ //Renderer.ExportBuffer := chkBinary.Checked;
+
if (ilm) then
Renderer.MaxMem := lim; //StrToInt(cbMaxMemory.text);
Renderer.OnProgress := OnProgress;
@@ -815,7 +830,7 @@ begin
Renderer.SetCP(cp);
if chkEmbedFlame.checked then
- Renderer.EmbedText(Trim(MainForm.RetrieveXML(cp))); // AV
+ Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
Renderer.Priority := tpLower; // tpNormal;
Renderer.NrThreads := NrTreads;
@@ -827,21 +842,23 @@ begin
except
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log'));
- //Application.MessageBox('Error while rendering!', 'Apophysis', 48);
end;
end;
end;
- end else
- begin
+
+ if not Assigned(Renderer) then SetLength(FlameNames, 0); // AV: free memory
+ end // end RenderAll
+ else begin
Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + '" ---');
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius]));
- if SingleBuffer then
- Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']))
- else
- Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
+ {$ifdef CPUX86}
+ Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']));
+ {$else}
+ Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
+ {$endif}
if (ilm) then
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [lim]))
@@ -873,28 +890,33 @@ begin
cp.AdjustScale(ImageWidth, ImageHeight);
cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG');
renderPath := ExtractFilePath(Filename);
- if chkSave.checked then
- MainForm.SaveXMLFlame(cp, ExtractFileName(FileName), renderPath + rendersAV);
- oldProg:=0;
- oldElapsed:=0;
- edt:=0;
- ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
+ if chkSave.checked then begin // AV: added check for duplicates
+ t := ExtractFileName(FileName);
+ if XMLEntryExists(t, renderPath + rendersAV) then
+ t := t + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
+ MainForm.SaveXMLFlame(cp, t, renderPath + rendersAV);
+ end;
+
+ oldProg := 0;
+ oldElapsed := 0;
+ edt := 0;
+ ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) *
+ int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
try
Renderer := TRenderThread.Create;
assert(Renderer <> nil);
- // Renderer.BitsPerSample := BitsPerSample;
if (ilm) then
Renderer.MaxMem := lim; //StrToInt(cbMaxMemory.text);
- Renderer.ExportBuffer := chkBinary.Checked;
+ //Renderer.ExportBuffer := chkBinary.Checked;
Renderer.OnProgress := OnProgress;
Renderer.TargetHandle := self.Handle;
Renderer.SetCP(cp);
if chkEmbedFlame.checked then
- Renderer.EmbedText(Trim(MainForm.RetrieveXML(cp))); // AV
+ Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
{
if chkThreadPriority.Checked then
Renderer.SetPriority(tpLower)
@@ -909,7 +931,7 @@ begin
except
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log'));
- Application.MessageBox(PChar(TextByKey('render-status-rendererror-message')), 'Apophysis', 48);
+ Application.MessageBox(PChar(TextByKey('render-status-rendererror-message')), ApophysisSVN, 48);
end;
end;
end;
@@ -951,16 +973,24 @@ begin
txtOversample.Text := IntToStr(renderOversample);
Filter_Radius := max(renderFilterRadius, 0.1); // AV: fixed!
txtFilterRadius.Text := FloatToStr(RoundTo(Filter_Radius, -3)); // AV
- cbWidth.Text := IntToStr(cp.Width);
- cbHeight.Text := IntToStr(cp.Height);
- ImageWidth := StrToInt(cbWidth.Text);
- ImageHeight := StrToInt(cbHeight.Text);
- // AV: fixed "Floating point division by zero" bug
+ // AV: fixed 'Floating point division by zero' bug
sample_density := max(renderDensity, 10);
txtDensity.Text := FloatToStr(sample_density);
- // BitsPerSample := renderBitsPerSample;
- ShowMemoryStatus;
+
+ // AV: fixed '"" is not a valid integer' bug
+ if bRenderAll then begin
+ ImageWidth := max(renderWidth, 100); // AV
+ ImageHeight := max(renderHeight, 100); // AV
+ end
+ else begin
+ ImageWidth := cp.Width; // AV
+ ImageHeight := cp.Height; // AV
+ end;
Ratio := ImageWidth / ImageHeight;
+ cbWidth.Text := IntToStr(ImageWidth); // AV
+ cbHeight.Text := IntToStr(ImageHeight); // AV
+
+ ShowMemoryStatus;
chkSaveIncompleteRenders.Checked := SaveIncompleteRenders;
chkPlaySound.Checked := PlaySoundOnRenderComplete; // AV
end;
@@ -1041,7 +1071,8 @@ begin
end;
if ConfirmStopRender then begin
- if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then exit;
+ if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
+ ApophysisSVN, 36) = ID_NO then exit;
end;
bRenderAll := false;
@@ -1056,6 +1087,7 @@ begin
ProgressTaskBar.ProgressValue := 0; // AV
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
+
end else
Close;
end;
@@ -1099,10 +1131,13 @@ begin
renderHeight := ImageHeight;
renderDensity := Sample_density;
renderOversample := Oversample;
- // renderBitsPerSample := BitsPerSample;
+
EmbedFlame := chkEmbedFlame.Checked; // AV
SaveInFlame := chkSave.Checked; // AV
+ ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
+ if not Assigned(Renderer) then SetLength(FlameNames, 0); // AV: free memory
+
{ Write position to registry }
Registry := TRegistry.Create;
try
@@ -1121,16 +1156,16 @@ procedure TRenderForm.btnPauseClick(Sender: TObject);
begin
if Assigned(Renderer) then
if Renderer.Suspended = false then begin
- renderer.Suspend;
+ Renderer.Suspend;
btnPause.caption := TextByKey('common-resume');
btnSnapshot.Visible := true; // AV
// AV: displaying progress in yellow
ProgressTaskBar.ProgressState := TTaskBarProgressState.Paused;
end else begin
- renderer.Resume;
+ Renderer.Resume;
btnPause.caption := TextByKey('common-pause');
btnSnapshot.Visible := false; // AV
- // AV: restore the taskbar progress
+ // AV: restore the taskbar progress
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal;
end;
end;
@@ -1139,8 +1174,8 @@ procedure TRenderForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
if Assigned(Renderer) then
- if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then
- CanClose := False
+ if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
+ ApophysisSVN, 36) = ID_NO then CanClose := False
else
begin
if Assigned(Renderer) then
@@ -1187,14 +1222,13 @@ begin
else
WriteLn(IFile, 'false');
WriteLn(IFile, IntToStr(cbMaxMemory.ItemIndex));
- WriteLn(IFile, cbMaxMemory.Text);
WriteLn(IFile, '}');
WriteLn(IFile, '');
CloseFile(IFile);
except on EInOutError do
begin
Application.MessageBox(PChar(TextByKey('render-prestatus-saveerror-preset')),
- PChar('Apophysis'), 16);
+ ApophysisSVN, 16);
Exit;
end;
end;
@@ -1216,7 +1250,8 @@ begin
Renderer.DoSnapshot; // AV: to save mid-render images
Renderer.SaveImage(FileName);
- if ShowRenderImage then // AV
+ // AV: show saved image if needed
+ if ShowRenderImage or (Sender = ProgressTaskbar.TaskBarButtons[0]) then
if FileExists(FileName) then
ShellExecute(Application.handle, PChar('open'),
PChar(ExtractFileName(FileName)), nil, PChar(renderPath),
@@ -1236,8 +1271,7 @@ end;
procedure TRenderForm.btnBrowseClick(Sender: TObject);
var
- fn: string;
- ext: string;
+ fn, ext: string;
begin
SaveDialog.Filename := Filename;
case renderFileFormat of
@@ -1245,28 +1279,19 @@ begin
2: SaveDialog.DefaultExt := 'png';
3: SaveDialog.DefaultExt := 'jpg';
end;
- SaveDialog.filterIndex := renderFileFormat;
- SaveDialog.Filter := Format('%s|*.bmp;*.dib;*.jpg;*.jpeg|%s|*.bmp;*.dib|%s|*.jpg;*.jpeg|%s|*.png|%s|*.*',
- [TextByKey('common-filter-allimages'), TextByKey('common-filter-bitmap'),
- TextByKey('common-filter-jpeg'), TextByKey('common-filter-png'),
- TextByKey('common-filter-allfiles')]);
- if OpenSaveFileDialog(RenderForm, SaveDialog.DefaultExt, SaveDialog.Filter, SaveDialog.InitialDir, TextByKey('common-browse'), fn, false, true, false, false) then
- //if SaveDialog.Execute then
+ SaveDialog.FilterIndex := renderFileFormat;
+ if SaveDialog.Execute then
begin
- SaveDialog.FileName := fn;
+ fn := SaveDialog.FileName;
ext := LowerCase(ExtractFileExt(fn));
- if (ext = '.bmp') then renderFileFormat := 1;
- if (ext = '.png') then renderFileFormat := 2;
- if ((ext = '.jpg') or (ext = '.jpeg')) then renderFileFormat := 3;
- {case SaveDialog.FilterIndex of
- 1: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.bmp');
- 2: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.png');
- 3: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.jpg');
- end; }
+ if (ext = '.jpg') or (ext = '.jpeg')then
+ renderFileFormat := 3
+ else if (ext = '.png') then
+ renderFileFormat := 2
+ else // if (ext = '.bmp') or (ext = '.dib') then
+ renderFileFormat := 1;
txtFileName.Text := ChangeFileExt(fn, ext);
- //renderFileFormat := SaveDialog.FilterIndex;
- renderPath := ExtractFilePath(SaveDialog.Filename);
-
+ renderPath := ExtractFilePath(fn);
end;
end;
@@ -1312,7 +1337,7 @@ end;
procedure TRenderForm.cmbPresetChange(Sender: TObject);
var
- chk: byte; //boolean; // AV
+ chk: shortint; // AV
i, j: integer;
FStrings: TStringList;
Title, Filename: string;
@@ -1329,15 +1354,12 @@ begin
for i := 0 to FStrings.Count - 1 do
if Pos(LowerCase(Title) + ' {', Lowercase(FStrings[i])) <> 0 then
begin
- //chk := chkMaintain.checked;
- //chkMaintain.Checked := False;
chk := cbAspectRatio.ItemIndex; // AV
cbAspectRatio.ItemIndex := 0;
j := i + 1;
cbWidth.Text := FStrings[j];
inc(j);
cbHeight.text := FStrings[j];
- //chkMaintain.Checked := chk;
cbAspectRatio.ItemIndex := chk;
inc(j);
txtDensity.text := FStrings[j];
@@ -1347,13 +1369,9 @@ begin
txtOversample.text := FStrings[j];
inc(j);
txtFileName.Text := ChangeFileExt(txtFileName.Text, FStrings[j]);
- inc(j);
- //if Fstrings[j] = 'true' then (not IsLimitingMemory) else chkLimitMem.checked := false;
- inc(j);
- cbMaxMemory.ItemIndex := StrToInt(Fstrings[j]);
- //cbMaxMemory.enabled := chkLimitMem.checked;
- inc(j);
- cbMaxMemory.Text := Fstrings[j];
+ inc(j, 2);
+ // AV: avoiding conflicts with 32- and 64-bit versions
+ cbMaxMemory.ItemIndex := min(StrToInt(FStrings[j]), cbMaxMemory.Items.Count-1);
break;
end;
finally
@@ -1366,13 +1384,6 @@ begin
ShowMemoryStatus;
end;
-{
-procedure TRenderForm.chkMaintainClick(Sender: TObject);
-begin
- Ratio := ImageWidth / ImageHeight;
-end;
-}
-
procedure TRenderForm.DoPostProcess;
begin
frmPostProcess.cp := cp;
@@ -1382,6 +1393,40 @@ begin
frmPostProcess.Show;
end;
+function GetWinVersion: TWin32Version;
+{ Returns current version of a host Win32 platform }
+var
+ wMinor, wMajor: integer;
+begin
+ Result := wvUnknown;
+ wMinor := Win32MinorVersion; // AV
+ wMajor := Win32MajorVersion; // AV
+ if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
+ if (wMajor > 4) or ((wMajor = 4) and (wMinor > 0)) then
+ Result := wvWin98
+ else
+ Result := wvWin95
+ else
+ if wMajor <= 4 then
+ Result := wvWinNT
+ else if wMajor = 5 then
+ begin // AV
+ if wMinor = 0 then
+ Result := wvWin2000
+ else if wMinor >= 1 then
+ Result := wvWinXP
+ end
+ else if wMajor = 6 then
+ begin // AV
+ if wMinor = 0 then
+ Result := wvWinVista
+ else if wMinor >= 1 then
+ Result := wvWin7
+ end
+ else if wMajor >= 7 then
+ Result := wvWinFutureFromOuterSpace;
+end;
+
function TRenderForm.WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean;
var
TTokenHd: THandle;
@@ -1390,15 +1435,17 @@ var
rTTokenPvg: TTokenPrivileges;
pcbtpPreviousRequired: DWORD;
tpResult: Boolean;
+ WinVersion: TWin32Version; // AV
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
- if ((GetWinVersion = wvWinNT) or
- (GetWinVersion = wvWin2000) or
- (GetWinVersion = wvWinXP) or
- (GetWinVersion = wvWinVista) or
- (GetWinVersion = wvWin7) or
- (GetWinVersion = wvWinFutureFromOuterSpace)) then
+ WinVersion := GetWinVersion; // AV: we don't need to calc it many times
+ if ((WinVersion = wvWinNT) or
+ (WinVersion = wvWin2000) or
+ (WinVersion = wvWinXP) or
+ (WinVersion = wvWinVista) or
+ (WinVersion = wvWin7) or
+ (WinVersion = wvWinFutureFromOuterSpace)) then
begin
tpResult := OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
@@ -1436,7 +1483,7 @@ end;
procedure TRenderForm.btnGoToClick(Sender: TObject);
var
- path:string;
+ path: string;
begin
path := ExtractFilePath(txtFilename.Text);
if (path <> '') then WinShellExecute('open', path);
@@ -1486,10 +1533,10 @@ var
fn: string;
sl: TStringList;
begin
- if OpenSaveFileDialog(RenderForm, '.log',
+ if OpenSaveFileDialog(RenderForm, '.log',
Format('Render-Log (*.txt;*.log)|*.txt;*.log|%s|*.*', [TextByKey('common-filter-allfiles')]),
SaveDialog.InitialDir, TextByKey('common-browse'), fn, false, true, false, false)
- then begin
+ then begin
sl := TStringList.Create;
sl.Text := Output.Text;
sl.SaveToFile(fn);
diff --git a/Forms/Fullscreen.pas b/Forms/Fullscreen.pas
index d2d7dcf..d5ea45e 100644
--- a/Forms/Fullscreen.pas
+++ b/Forms/Fullscreen.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- Menus, ExtCtrls, ControlPoint, RenderThread, Translation;
+ Menus, ExtCtrls, ControlPoint, RenderThread;
type
TFullscreenForm = class(TForm)
@@ -50,8 +50,7 @@ type
private
Remainder, StartTime, t: double;
- imgLeft, imgTop,
- imgWidth, imgHeight: integer;
+ imgLeft, imgTop, imgWidth, imgHeight: integer;
Closing: boolean;
Renderer: TRenderThread;
@@ -68,8 +67,6 @@ type
public
Calculate : boolean;
cp: TControlPoint;
- Zoom: double;
- center: array[0..1] of double;
ActiveForm: TForm;
end;
@@ -80,8 +77,7 @@ var
implementation
uses
- Main, Math, Global,
- Tracer;
+ Main, Math, Global, Tracer, Translation;
{$R *.DFM}
@@ -118,9 +114,6 @@ begin
end;
cp.AdjustScale(imgWidth, imgHeight);
-// cp.Zoom := MainForm.Zoom;
-// cp.center[0] := MainForm.center[0];
-// cp.center[1] := MainForm.center[1];
cp.sample_density := defSampleDensity;
StartTime := Now;
t := now;
@@ -294,6 +287,12 @@ begin
RenderMore.Caption := TextByKey('fullscreen-popup-rendermore');
RenderStop.Caption := TextByKey('fullscreen-popup-stoprender');
cp := TControlPoint.Create;
+
+ // AV: moved following here from MainForm.mnuFullScreenClick
+ self.Width := Screen.Width;
+ self.Height := Screen.Height;
+ self.Top := 0;
+ self.Left := 0;
end;
procedure TFullscreenForm.FormDestroy(Sender: TObject);
diff --git a/Forms/Main.dfm b/Forms/Main.dfm
index 046164d..d74da9c 100644
--- a/Forms/Main.dfm
+++ b/Forms/Main.dfm
@@ -81,16 +81,9 @@ object MainForm: TMainForm
OnKeyDown = FormKeyUpDown
OnKeyPress = FormKeyPress
OnKeyUp = FormKeyUpDown
- OnResize = FormResize
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
- object Image1: TImage
- Left = 48
- Top = 104
- Width = 105
- Height = 105
- end
object Splitter: TSplitter
Left = 161
Top = 22
@@ -139,16 +132,6 @@ object MainForm: TMainForm
Ctl3D = True
ParentCtl3D = False
TabOrder = 1
- object Shape1: TShape
- Left = 1
- Top = 1
- Width = 159
- Height = 649
- Align = alClient
- Brush.Color = clWindow
- Pen.Color = clWindow
- ExplicitHeight = 748
- end
object ListView1: TListView
Left = 1
Top = 1
@@ -175,6 +158,7 @@ object MainForm: TMainForm
OnColumnClick = ListViewColumnClick
OnDblClick = ListViewDblClick
OnEdited = ListViewEdited
+ OnSelectItem = ListViewSelectItem
end
end
object cbMain: TCoolBar
@@ -212,6 +196,7 @@ object MainForm: TMainForm
ParentShowHint = False
ShowHint = True
TabOrder = 0
+ OnResize = ToolBarResize
object btNew: TToolButton
Left = 0
Top = 0
@@ -425,9 +410,24 @@ object MainForm: TMainForm
ImageIndex = 69
OnClick = tbCurvesClick
end
- object tbMutate: TToolButton
+ object tbImageSize: TToolButton
Left = 462
Top = 0
+ Hint = 'Image size | Change the image size'
+ Caption = 'tbImageSize'
+ ImageIndex = 14
+ OnClick = mnuImageSizeClick
+ end
+ object tbAnimate: TToolButton
+ Left = 485
+ Top = 0
+ Caption = 'Animator'
+ ImageIndex = 76
+ MenuItem = mnuAnimator
+ end
+ object tbMutate: TToolButton
+ Left = 508
+ Top = 0
Hint =
'Mutation | Show randomly generated modifications of the current ' +
'flame'
@@ -435,23 +435,15 @@ object MainForm: TMainForm
ImageIndex = 17
OnClick = mnuMutateClick
end
- object tbImageSize: TToolButton
- Left = 485
- Top = 0
- Hint = 'Image size | Change the image size'
- Caption = 'tbImageSize'
- ImageIndex = 14
- OnClick = mnuImageSizeClick
- end
object tbMessages: TToolButton
- Left = 508
+ Left = 531
Top = 0
Hint = 'Messages | Show error messages'
ImageIndex = 63
OnClick = tbMessagesClick
end
object tbOptions: TToolButton
- Left = 531
+ Left = 554
Top = 0
Hint = 'Options | Change Apophysis default settings'
Caption = 'tbOptions'
@@ -459,7 +451,7 @@ object MainForm: TMainForm
OnClick = mnuOptionsClick
end
object ToolButton15: TToolButton
- Left = 554
+ Left = 577
Top = 0
Width = 8
Caption = 'ToolButton15'
@@ -467,7 +459,7 @@ object MainForm: TMainForm
Style = tbsSeparator
end
object tbShowAlpha: TToolButton
- Left = 562
+ Left = 585
Top = 0
Hint = 'Show transparency | Show the flame on a transparent background'
Caption = 'Show Alpha'
@@ -476,7 +468,7 @@ object MainForm: TMainForm
OnClick = tbShowAlphaClick
end
object tbGuides: TToolButton
- Left = 585
+ Left = 608
Top = 0
Hint = 'Show guidelines | Show flame thirds, center and golden ratio'
Caption = 'Show guides'
@@ -486,7 +478,7 @@ object MainForm: TMainForm
OnClick = tbGuidesClick
end
object ToolButton16: TToolButton
- Left = 608
+ Left = 631
Top = 0
Width = 8
Caption = 'ToolButton16'
@@ -494,7 +486,7 @@ object MainForm: TMainForm
Style = tbsSeparator
end
object tbEditScript: TToolButton
- Left = 616
+ Left = 639
Top = 0
Hint = 'Edit script | Edit the script code'
Caption = 'tbEditScript'
@@ -502,7 +494,7 @@ object MainForm: TMainForm
OnClick = mnuEditScriptClick
end
object btnRunScript: TToolButton
- Left = 639
+ Left = 662
Top = 0
Hint = 'Run script | Execute the current script'
Caption = 'btnRunScript'
@@ -510,7 +502,7 @@ object MainForm: TMainForm
OnClick = mnuRunClick
end
object btnStopScript: TToolButton
- Left = 662
+ Left = 685
Top = 0
Hint =
'Stop script | To stop an animation script, you can press any key' +
@@ -520,7 +512,7 @@ object MainForm: TMainForm
OnClick = mnuStopClick
end
object ToolButton18: TToolButton
- Left = 685
+ Left = 708
Top = 0
Width = 8
Caption = 'ToolButton18'
@@ -528,7 +520,7 @@ object MainForm: TMainForm
Style = tbsSeparator
end
object tbDrag: TToolButton
- Left = 693
+ Left = 716
Top = 0
Hint = 'Translate the image | Translate the fractal image using mouse'
Caption = 'tbDrag'
@@ -539,7 +531,7 @@ object MainForm: TMainForm
OnClick = tbDragClick
end
object tbRotate: TToolButton
- Left = 716
+ Left = 739
Top = 0
Hint = 'Rotate the camera | Rotate the fractal image using mouse'
Caption = 'tbRotate'
@@ -549,7 +541,7 @@ object MainForm: TMainForm
OnClick = tbRotateClick
end
object tbZoomIn: TToolButton
- Left = 739
+ Left = 762
Top = 0
Hint = 'Zoom in | Scale up the fractal image using mouse'
Caption = 'tbZoomIn'
@@ -559,7 +551,7 @@ object MainForm: TMainForm
OnClick = tbzoomwindowClick
end
object tbZoomOut: TToolButton
- Left = 762
+ Left = 785
Top = 0
Hint = 'Zoom out | Scale down the fractal image using mouse'
Caption = 'tbZoomOut'
@@ -569,7 +561,7 @@ object MainForm: TMainForm
OnClick = tbzoomoutwindowClick
end
object ToolButton23: TToolButton
- Left = 785
+ Left = 808
Top = 0
Width = 8
Caption = 'ToolButton23'
@@ -630,131 +622,131 @@ object MainForm: TMainForm
Left = 104
Top = 280
Bitmap = {
- 494C01014C005000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+ 494C01014D005000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000004001000001002000000000000040
0100000000000000000000000000000000000000000000000000000000000000
+ 000018435A002B6289004C8ABE0070A9CC00E3EDF50000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000004E4E4E002D2D2D00505050000000
+ 00002E67850094C7F90091C9F9004185C900276BAE002D3B4700050505002525
+ 2500000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000038383800B0B0B000353535005757
+ 57004389AA00E0F2FF00549AD8001A7ABE004998C5003177B0009EACB8001515
+ 1500000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000003A3A3A0062626200383838006FDF
+ 9D0055B2A0007AB6D50090B7D10055C9E4005BDFF50078D0ED004491D1000F1B
+ 2500000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000063636300ACACAC00575757004FCB
+ 5C0057D77A0035B8830073B8D300C2F6FD0063DFF7005DE2F80079D3F0004392
+ D500E6F1FA000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000005C5C5C006D6D6D005F5F5F004FC4
+ 45004BBA2C00D8BD6000B1A87F0077CBE700C7F7FD005EDCF5005AE1F7007BD4
+ F1004C9ADE00D6E8F70000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000006565650089898900656565007FBF
+ 3600DDC56900FFC27000FFBF670086C3BA0079D3EE00C7F7FD005FDCF5005BE2
+ F7007AD6F20051A2E200DCEAF600000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000006E6E6E00A4A4A4006C6C6C00F8C6
+ 6E00FFC87700FFC57200FFC46C0098D8CF0078D7E9007BD3EC00C4F6FD006CDD
+ F6006DCAED0063A3D70069A2D500E5EFF7000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000006969690071717100686868005757
+ 570057575700575757005757570057575700575757002C5D6D007DD2EA00B2E3
+ F9008BC0E700AED3F600C4E0FC006BA2D4000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000077777700AAAAAA007474740072E2
+ 9E007CE3A40078E3A00063E095005AE1950055E29300565656006CA1B00077BE
+ E700B4D2F000E5F3FF00ACD2EF005996CC000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000007777770097979700777777004FCB
+ 5C0057D77A0042D16A0070C75E00B6B85000CBAE3F005B5B5B007C7C7C00426C
+ 7A0058A5D80085B1DB00469DD000B1D8EE000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000077777700858585007A7A7A004FC4
+ 45004BBA2C00D8BD6000FFBA6200FFB96500DBBB7D005E5E5E00656565004B4B
+ 4B00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000083838300AFAFAF007C7C7C007FBF
+ 3600DDC56900FFC27000FFBF6700AECBAC0068E0F90060606000ACACAC005C5C
+ 5C00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000006C6C6C007474740068686800E6BC
+ 7100EDBE7900ECBB7300ECB96D0084CDCF0084D8EB004B4B4B00686868003D3D
+ 3D00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000073737300A6A6A600696969005757
+ 570057575700575757005757570057575700575757004D4D4D009A9A9A006262
+ 6200000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000008989890076767600808080000000
+ 000000000000000000000000000000000000000000006E6E6E00515151006666
+ 6600000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@@ -3194,11 +3186,11 @@ object MainForm: TMainForm
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000424D3E000000000000003E000000
2800000040000000400100000100010000000000000A00000000000000000000
- 000000000000000000000000FFFFFF0000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 0000000000000000000000000000000000000000000000000000000000000000
- 00000000000000000000000000000000FFFFFFFFFFFFFFFFFF9FF80F81FFFFFF
+ 000000000000000000000000FFFFFF00F07F000000000000100F000000000000
+ 000F000000000000000F00000000000000070000000000000003000000000000
+ 0001000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000F000000000000000F000000000000000F000000000000
+ 000F0000000000001F8F000000000000FFFFFFFFFFFFFFFFFF9FF80F81FFFFFF
F187E0078007C7FFE083C003C103C2FFC213C001C411F207C7138001C801F187
F111800188C8F10FC00080018308F903800C80019019F89387018001CC23F8FF
800380018027F07FC0818003240FFCFFC683C003203FFC1FFC17E00707FFFE1F
@@ -3283,7 +3275,6 @@ object MainForm: TMainForm
Top = 168
object MainFile: TMenuItem
Caption = '&File'
- OnClick = MainMenuClick
object New1: TMenuItem
Caption = 'New...'
ImageIndex = 65
@@ -3374,7 +3365,6 @@ object MainForm: TMainForm
end
object MainEdit: TMenuItem
Caption = '&Edit'
- OnClick = MainMenuClick
object mnuUndo: TMenuItem
Caption = '&Undo'
Enabled = False
@@ -3461,6 +3451,12 @@ object MainForm: TMainForm
ShortCut = 119
OnClick = tbCurvesClick
end
+ object mnuAnimator: TMenuItem
+ Caption = 'Animator'
+ ImageIndex = 76
+ ShortCut = 122
+ OnClick = mnuAnimatorClick
+ end
object N5: TMenuItem
Caption = '-'
end
@@ -3477,7 +3473,6 @@ object MainForm: TMainForm
end
object MainFlame: TMenuItem
Caption = 'Flame'
- OnClick = MainMenuClick
object mnuResetLocation: TMenuItem
Caption = 'Reset Location'
ImageIndex = 12
@@ -3629,7 +3624,6 @@ object MainForm: TMainForm
end
object AddTile: TMenuItem
Caption = 'Add equiaffine tile...'
- OnClick = AddTileClick
object Rhombic1: TMenuItem
Tag = 1
Caption = 'Rhombus'
@@ -3863,9 +3857,7 @@ object MainForm: TMainForm
end
end
object OpenDialog: TOpenDialog
- Filter =
- 'Apophysis Parameter Files (*.apo)|*.apo|Apophysis 1.0 Parameters' +
- ' (*fla)|*.fla|IFS Files (*.ifs)|*.ifs'
+ Filter = 'Apophysis Parameter Files (*.flame)|*.flame'
Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing]
Left = 24
Top = 456
diff --git a/Forms/Main.pas b/Forms/Main.pas
index e425288..346113d 100644
--- a/Forms/Main.pas
+++ b/Forms/Main.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -32,46 +32,41 @@ interface
uses
Windows, Forms, Dialogs, Menus, Controls, ComCtrls,
- ToolWin, StdCtrls, Classes, Messages, ExtCtrls, ImgList,
- Jpeg, SyncObjs, SysUtils, Graphics, Math,
- ExtDlgs, AppEvnts, ShellAPI, Registry, Curves,
+ StdCtrls, Classes, Messages, ExtCtrls, ImgList, System.ImageList,
+ Vcl.Imaging.Jpeg, SyncObjs, SysUtils, Graphics, Math, Vcl.ToolWin,
+ ExtDlgs, AppEvnts, ShellAPI, Registry,
Global, Xform, XFormMan, ControlPoint, CMap,
RenderThread, RenderingCommon, RenderingInterface,
- LibXmlParser, LibXmlComps, Vcl.Imaging.PngImage, XPMan,
- StrUtils, LoadTracker, CheckLst,
- CommandLine, RegularExpressionsCore, Translation,
- RegexHelper, System.ImageList, Vcl.Themes, Vcl.Styles; // AV
+ LibXmlParser, LibXmlComps, Vcl.Imaging.PngImage,
+ StrUtils, LoadTracker, CommandLine, Translation,
+ RegularExpressionsCore, RegexHelper, Vcl.Themes, Vcl.Styles; // AV
const
- PixelCountMax = 32768;
- RS_A1 = 0;
- RS_DR = 1;
- RS_XO = 2;
- RS_VO = 3;
+ mbHeight = 30; // AV: height (in items) of all styled submenus
- {$ifndef Apo7X64}
+ {$ifdef CPUX86}
randFilename = 'ApophysisAV.rand';
undoFilename = 'ApophysisAV.undo';
+ ApophysisSVN = 'Apophysis AV (32 bit)'; // AV: the caption for all dialogs
{$else}
randFilename = 'ApophysisAV_64.rand'; // AV
undoFilename = 'ApophysisAV_64.undo'; // AV
+ ApophysisSVN = 'Apophysis AV (64 bit)';
{$endif}
templateFilename = 'ApophysisAV.temp';
- templatePath = '\templates';
- scriptPath = '\scripts';
+ //templatePath = '\templates';
+ // AV: hmm, we have a global variable with the same name...
+ // scriptPath = '\scripts';
type
TMouseMoveState = (msUsual, msZoomWindow, msZoomOutWindow, msZoomWindowMove,
- msZoomOutWindowMove, msDrag, msDragMove, msRotate, msRotateMove, msPitchYaw, msHeight);
-
-type
- TWin32Version = (wvUnknown, wvWin95, wvWin98, wvWinNT, wvWin2000, wvWinXP,
- wvWinVista, wvWin7, wvWinFutureFromOuterSpace);
+ msZoomOutWindowMove, msDrag, msDragMove, msRotate,
+ msRotateMove, msPitchYaw, msHeight);
type
TThumbnailThread = class(TThread)
private
- FCount: integer;
+ FlameItems: TListItems;
class var
FPreviewDensity: double; // AV
FThumbnailSize : integer; // AV: added F to avoid of name conflicts
@@ -81,10 +76,6 @@ type
destructor Destroy; override;
end;
-type
- pRGBTripleArray = ^TRGBTripleArray;
- TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
-
TMainForm = class(TForm)
Buttons: TImageList;
MainMenu: TMainMenu;
@@ -174,10 +165,8 @@ type
mnuBuiltinVars: TMenuItem;
mnuPluginVars: TMenuItem;
UsedThumbnails: TImageList;
- Image1: TImage;
Splitter: TSplitter;
ListBackPanel: TPanel;
- Shape1: TShape;
ListView1: TListView;
cbMain: TCoolBar;
ToolBar: TToolBar;
@@ -293,7 +282,9 @@ type
EnumerateFlames: TMenuItem;
DownloadPlugins: TMenuItem;
N27: TMenuItem;
- mnuRefreshAllThumbs: TMenuItem; // AV
+ mnuRefreshAllThumbs: TMenuItem;
+ mnuAnimator: TMenuItem;
+ tbAnimate: TToolButton; // AV
procedure mnuManualClick(Sender: TObject);
procedure mnuReportFlameClick(Sender: TObject);
procedure mnuTurnFlameToScriptClick(Sender: TObject);
@@ -314,7 +305,6 @@ type
procedure mnuOptionsClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure mnuHelpTopicsClick(Sender: TObject);
- procedure mnuRefreshClick(Sender: TObject);
procedure mnuNormalWeightsClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure mnuCopyUPRClick(Sender: TObject);
@@ -323,12 +313,9 @@ type
var S: string);
procedure mnuListRenameClick(Sender: TObject);
procedure BackPanelResize(Sender: TObject);
- procedure mnuNextClick(Sender: TObject);
- procedure mnuPreviousClick(Sender: TObject);
procedure RedrawTimerTimer(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure ShowStyledWindows(Sender: TObject);
- procedure MainMenuClick(Sender: TObject);
procedure mnuVRandomClick(Sender: TObject);
procedure mnuSaveAsClick(Sender: TObject);
procedure mnuOpenClick(Sender: TObject);
@@ -361,7 +348,6 @@ type
procedure mnuStopClick(Sender: TObject);
// procedure mnuImportGimpClick(Sender: TObject); // AV: rudiment from Apo 2.02
procedure mnuManageFavoritesClick(Sender: TObject);
- procedure mnuShowFullClick(Sender: TObject);
procedure mnuImageSizeClick(Sender: TObject);
procedure ApplicationEventsActivate(Sender: TObject);
procedure mnuPasteClick(Sender: TObject);
@@ -371,6 +357,7 @@ type
procedure ListXmlScannerStartTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
+ procedure XmlScannerComment(Sender: TObject; Comment: string); // AV
procedure XMLScannerStartTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
procedure XMLScannerEmptyTag(Sender: TObject; TagName: string;
@@ -393,14 +380,12 @@ type
procedure tbShowTraceClick(Sender: TObject);
procedure XmlScannerContent(Sender: TObject; Content: String);
procedure mnuRenderAllClick(Sender: TObject);
-{ procedure ListViewChanging(Sender: TObject; Item: TListItem;
- Change: TItemChange; var AllowChange: Boolean); }
procedure btnViewIconsClick(Sender: TObject);
procedure btnViewListClick(Sender: TObject);
procedure XmlScannerEndTag(Sender: TObject; TagName: String);
procedure tbMessagesClick(Sender: TObject);
procedure btNewClick(Sender: TObject);
- procedure FormResize(Sender: TObject);
+ procedure ToolBarResize(Sender: TObject);
procedure mnuResetUIClick(Sender: TObject);
procedure AutoSaveTimerTimer(Sender: TObject);
procedure Restorelastautosave1Click(Sender: TObject);
@@ -428,6 +413,9 @@ type
procedure EnumerateFlamesClick(Sender: TObject);
procedure ListViewDblClick(Sender: TObject);
procedure DownloadPluginsClick(Sender: TObject);
+ procedure mnuAnimatorClick(Sender: TObject);
+ procedure ListViewSelectItem(Sender: TObject; Item: TListItem;
+ Selected: Boolean);
private
SubstSource: TStringList;
SubstTarget: TStringList;
@@ -465,12 +453,15 @@ type
procedure DrawZoomWindow;
procedure DrawRotatelines(Angle: double);
// procedure DrawPitchYawLines(YawAngle: double; PitchAngle:double);
+ procedure SetAutoSaveTimer; // AV
+ procedure RunThumbnailThread; inline;
procedure FillVariantMenu;
procedure VariantMenuClick(Sender: TObject);
procedure FavoriteClick(Sender: TObject);
procedure ScriptItemClick(Sender: TObject);
+ procedure StopScripter; // AV
// AV: for Apo GUI themes
procedure CreateStyleList;
@@ -485,9 +476,7 @@ type
{ Public declarations }
UndoIndex, UndoMax: integer;
Center: array[0..1] of double;
- //MainZoom: double;
StartTime: TDateTime;
- CurrentFileName: string;
ParseLoadingBatch : boolean;
SurpressHandleMissingPlugins : boolean;
@@ -497,7 +486,6 @@ type
XmlScanner : TXmlScanner;
function ReadWithSubst(Attributes: TAttrList; attrname: string): string;
- procedure InvokeLoadXML(xmltext:string);
// AV: added 3-rd parameter to be able to discard multiple updates
procedure LoadXMLFlame(filename, name: string; upd: boolean = true);
procedure DisableFavorites;
@@ -508,7 +496,7 @@ type
procedure DisplayHint(Sender: TObject);
procedure OnProgress(prog: double);
procedure ResizeImage;
- procedure DrawPreview;
+ // procedure DrawPreview;
procedure DrawFlame;
procedure UpdateUndo;
procedure LoadUndoFlame(index: integer; filename: string);
@@ -526,7 +514,7 @@ type
function ApplicationOnHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
function SystemErrorMessage: string;
function SystemErrorMessage2(errno: cardinal): string;
- function RetrieveXML(cp : TControlPoint):string;
+ // function RetrieveXML(cp : TControlPoint): string; // AV: we can call it directly
procedure ApplyThemedColors;
// AV: for reading / writing embedded parameters
@@ -538,57 +526,62 @@ type
procedure SetThumbnailProperties;
procedure RefreshThumbnail;
procedure UpdateThumbnails;
+ procedure AddFlameToList(const title: string = '');
end;
procedure ListXML(FileName: string; sel: integer; selname: string = ''); // AV
+procedure ListIFS(FileName: string; sel: integer); // AV: for loading Undo flame files
+function FlameToXML(const cp1: TControlPoint; exporting: boolean = false; title: string = ''): string; // AV: make global
+function LoadXMLFlameText(filename, name: string) : string;
+function FindFlameXML(const FlameStr: string; const Title: string) : Integer; // AV
+procedure FlameFromUndo(cp: TControlPoint; const FlameName: string; const ParamFile: string); // AV
+
function EntryExists(En, Fl: string): boolean;
function XMLEntryExists(title, filename: string): boolean;
function DeleteEntry(Entry, FileName: string): boolean;
function CleanIdentifier(ident: string): string;
function CleanUPRTitle(ident: string): string;
+
function GradientString(c: TColorMap): string;
-procedure ListFlames(FileName: string; sel: integer); // AV: outdated, for affine coefs only
-procedure ListIFS(FileName: string; sel: integer); // AV: for loading Undo flame files
-procedure NormalizeVariations(var cp1: TControlPoint);
-function GetWinVersion: TWin32Version;
-function LoadXMLFlameText(filename, name: string) : string;
-function FindFlameXML(const FlameStr: string; const Title: string) : Integer; // AV
+procedure RotateCMapHue(var cp: TControlPoint); // AV
function FlameInClipboard: boolean; // AV
function RemoveExt(filename: string): string; // AV
+function WinShellExecute(const Operation, AssociatedFile: string): Boolean; // AV
+
// AV: for making window screenshots
procedure GetFormScreenShot(const AFileName: string);
procedure SaveScreenShot(const AFormName: string);
var
MainForm: TMainForm;
- pname, ptime: String;
- //pversion: string;
+ pname, ptime: string;
+ // pversion: string;
nxform: integer;
- TbBreakWidth: integer;
MainCp: TControlPoint;
ParseCp: TControlPoint;
MemCp: TControlPoint;
- CurrentFlame, FlameString: string;
ThumbnailSize: integer;
- AboutToExit: boolean;
GeneratingThumbs: boolean; // AV
- ApophysisSVN: string; //APP_VERSION;
- AppVersionString: string; //APP_NAME+'.'+ APP_VERSION;
+ AppVersionString: string;
implementation
uses
- ClipBrd, Editor, Options, Settings, Template, MissingPlugin, Base64, Chaotica,
+ ClipBrd, Editor, Options, Settings, Template, MissingPlugin, Chaotica,
FullScreen, FormRender, Mutate, Adjust, Browser, Save, About, CmapData,
- ScriptForm, FormFavorites, FormExport, RndFlame, Tracer, Types, SplashForm;
+ ScriptForm, FormFavorites, FormExport, RndFlame, Tracer, Types, SplashForm,
+ Animate;
+
+const
+ TbBreakWidth = 810; // AV
{$R *.DFM}
-procedure AssignBitmapProperly(var Bitmap:TBitmap; Source:TBitmap);
+procedure AssignBitmapProperly(var Bitmap: TBitmap; Source: TBitmap);
begin
Bitmap.Dormant;
Bitmap.FreeImage;
@@ -596,7 +589,7 @@ begin
Bitmap.Assign(Source);
end;
-procedure FreeBitmapProperly(var Bitmap:TBitmap);
+procedure FreeBitmapProperly(var Bitmap: TBitmap);
begin
try
Bitmap.Dormant;
@@ -645,41 +638,16 @@ begin
try
GetFormScreenShot(s);
Application.MessageBox(PChar(Format(TextByKey('common-screenshot-saved'),
- [ExtractFileName(s), ExtractFilePath(s)])), PChar('Apophysis AV'), MB_ICONINFORMATION);
+ [ExtractFileName(s), ExtractFilePath(s)])),
+ ApophysisSVN, MB_ICONINFORMATION);
except
- Application.MessageBox(PChar(TextByKey('common-screenshot-error')), PChar('Apophysis AV'), MB_ICONERROR);
+ Application.MessageBox(PChar(TextByKey('common-screenshot-error')),
+ ApophysisSVN, MB_ICONERROR);
end;
end;
{//////////////////////////////////////////////////////////////////////////////}
-procedure NormalizeVariations(var cp1: TControlPoint);
-var
- totvar, v: double;
- i, j: integer;
-begin
- for i := 0 to NXFORMS - 1 do
- begin
- totvar := 0;
- for j := 0 to NRVAR - 1 do
- begin
- v := cp1.xform[i].GetVariation(j); // AV
- if v < 0 then
- cp1.xform[i].SetVariation(j, -v);
- totvar := totvar + v;
- end;
- if totVar = 0 then
- begin
- cp1.xform[i].SetVariation(0, 1)
- end
- else
- for j := 0 to NRVAR - 1 do begin
- if totVar <> 0 then
- cp1.xform[i].SetVariation(j, cp1.xform[i].GetVariation(j) / totvar);
- end;
- end;
-end;
-
function FlameInClipboard: boolean;
var
flamestr: string;
@@ -697,36 +665,6 @@ begin
end;
end;
-function GetWinVersion: TWin32Version;
-{ Returns current version of a host Win32 platform }
-begin
- Result := wvUnknown;
- if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
- if (Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and (Win32MinorVersion > 0)) then
- Result := wvWin98
- else
- Result := wvWin95
- else
- if Win32MajorVersion <= 4 then
- Result := wvWinNT
- else if Win32MajorVersion = 5 then
- begin // AV
- if Win32MinorVersion = 0 then
- Result := wvWin2000
- else if Win32MinorVersion >= 1 then
- Result := wvWinXP
- end
- else if Win32MajorVersion = 6 then
- begin // AV
- if Win32MinorVersion = 0 then
- Result := wvWinVista
- else if Win32MinorVersion >= 1 then
- Result := wvWin7
- end
- else if Win32MajorVersion >= 7 then
- Result := wvWinFutureFromOuterSpace;
-end;
-
{ ************************************* Help ********************************* }
procedure ShowHelp(Pt: TPoint; ContextId: Integer);
@@ -755,33 +693,6 @@ begin
inherited;
end;
-(*
-procedure TMainForm.RebuildListView;
-var
- i: integer;
- item: TListItem;
-begin
- ListView.Items.Clear;
-
- /// backup in old lv
- for i := 0 to ListView1.Items.Count-1 do begin
- item := ListView.Items.Add;
- item.Caption := ListView1.Items[i].Caption;
- end;
-
- // rebuild new lv
- ListView1.Items.Clear;
-
- for i := 0 to ListView.Items.Count-1 do begin
- item := ListView1.Items.Add;
- item.Caption := ListView.Items[i].Caption;
- if (not ClassicListMode) then item.ImageIndex := i;
- end;
-
- ListView.Items.Clear;
-end;
-*)
-
procedure TMainForm.InsertStrings;
begin
mnuCopy.Caption := TextByKey('common-copy');
@@ -830,8 +741,6 @@ begin
mnuSaveUPR.Caption := TextByKey('main-menu-file-exportupr');
mnuExportFlame.Caption := TextByKey('main-menu-file-exportflame');
mnuExportChaotica.Caption := TextByKey('main-menu-file-exportchaotica');
- // mnuImportGimp.Caption := TextByKey('main-menu-file-importgimp');
- // mnuImportGimp.Hint := TextByKey('main-menu-file-importgimphint');
mnuRandomBatch.Caption := TextByKey('main-menu-file-randombatch');
mnuExit.Caption := TextByKey('main-menu-file-exit');
mnuExit.Hint := TextByKey('main-menu-file-exithint');
@@ -870,6 +779,9 @@ begin
tbCurves.Hint := TextByKey('main-toolbar-curves');
mnuCurves.Hint := TextByKey('main-toolbar-curves');
mnuCurves.Caption := TextByKey('main-menu-view-curves');
+ tbAnimate.Hint := TextByKey('main-toolbar-animator');
+ mnuAnimator.Caption := TextByKey('main-menu-view-animator'); // AV
+ mnuAnimator.Hint := GetLongHint(tbAnimate.Hint); // AV
MainFlame.Caption := TextByKey('main-menu-flame-title');
mnuResetLocation.Caption := TextByKey('main-menu-flame-reset');
mnuPopResetLocation.Caption := TextByKey('main-menu-flame-reset');
@@ -986,11 +898,6 @@ begin
DihedralSym.Caption := TextByKey('options-tab-random-type-dihedral') + TextByKey('main-menu-flame-symorder');
end;
-procedure TMainForm.InvokeLoadXML(xmltext: string);
-begin
- ParseXML(MainCP, PCHAR(xmltext), false);
-end;
-
function TMainForm.ApplicationOnHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
var
Pos: TPoint;
@@ -1012,7 +919,7 @@ var
AStyle: TCustomStyleServices;
MenuC1, MenuC2: TColor;
mb: TMenuBreak;
- i: integer;
+ i: smallint;
begin
AStyle := TStyleManager.ActiveStyle;
CurrentStyle := AStyle.Name;
@@ -1044,12 +951,19 @@ begin
or (CurrentStyle = 'Cobalt XEMedia') or (CurrentStyle = 'Onyx Blue')
or (CurrentStyle = 'Ruby Graphite') or (CurrentStyle = 'Golden Graphite');
+ if (CurrentStyle = 'Windows') then mb := mbNone
+ else mb := mbBreak;
i := 0;
- if (CurrentStyle = 'Windows') then mb := mbNone else mb := mbBreak;
- while i < length(VarMenus) do
+ while i < mnuBuiltinVars.Count do
begin
- VarMenus[i].Break := mb;
- inc(i, 30);
+ mnuBuiltinVars[i].Break := mb;
+ inc(i, mbHeight);
+ end;
+ i := 0;
+ while i < mnuPluginVars.Count do
+ begin
+ mnuPluginVars[i].Break := mb;
+ inc(i, mbHeight);
end;
end;
@@ -1092,6 +1006,9 @@ begin
end;
*)
+(*
+// AV: commented out since we have the same methods in RndFlame unit!
+
procedure RandomVariation(cp: TControlPoint);
{ Randomise variation parameters }
var
@@ -1138,6 +1055,7 @@ begin
cp.xform[i].SetVariation(integer(Variation), 1);
end;
end;
+*)
function FindFlameXML(const FlameStr: string; const Title: string) : Integer;
var
@@ -1164,7 +1082,7 @@ end;
procedure TMainForm.RandomizeColorSpeed1Click(Sender: TObject);
var
- i: integer;
+ i: smallint;
begin
inc(MainSeed);
RandSeed := MainSeed;
@@ -1216,23 +1134,6 @@ begin
end;
end;
-function CleanIdentifier(ident: string): string;
-{ Strips unwanted characters from an identifier}
-var
- i: integer;
-begin
- for i := 0 to Length(ident) do
- begin
- if ident[i] = #32 then
- ident[i] := '_'
- else if ident[i] = '}' then
- ident[i] := '_'
- else if ident[i] = '{' then
- ident[i] := '_';
- end;
- Result := ident;
-end;
-
procedure TMainForm.OnProgress(prog: double);
var
Elapsed, Remaining: TDateTime;
@@ -1283,6 +1184,7 @@ begin
AdjustForm.btnRedo.enabled := false;
end;
+(*
function GradientEntries(gFilename: string): string;
var
i, p: integer;
@@ -1317,6 +1219,15 @@ begin
end;
end;
+function GradTitle(str: string): string;
+var
+ p: integer;
+begin
+ p := pos('{', str);
+ GradTitle := Trim(copy(str, 1, p - 1));
+end;
+*)
+
{ ********************************* File ************************************* }
function EntryExists(En, Fl: string): boolean;
@@ -1342,23 +1253,6 @@ begin
Result := False;
end;
-function CleanEntry(ident: string): string;
-{ Strips unwanted characters from an identifier}
-var
- i: integer;
-begin
- for i := 1 to Length(ident) do
- begin
- if ident[i] = #32 then
- ident[i] := '_'
- else if ident[i] = '}' then
- ident[i] := '_'
- else if ident[i] = '{' then
- ident[i] := '_';
- end;
- Result := ident;
-end;
-
function CleanXMLName(ident: string): string;
var
i: integer;
@@ -1373,6 +1267,16 @@ begin
Result := ident;
end;
+function CleanIdentifier(ident: string): string;
+{ Strips unwanted characters from an identifier}
+var
+ i: integer;
+begin
+ for i := 1 to Length(ident) do
+ if (ident[i] = #32) or (ident[i] = '}') or (ident[i] = '{') then
+ ident[i] := '_';
+ Result := ident;
+end;
function CleanUPRTitle(ident: string): string;
{ Strips braces but leave spaces }
@@ -1380,12 +1284,9 @@ var
i: integer;
begin
for i := 1 to Length(ident) do
- begin
- if ident[i] = '}' then
- ident[i] := '_'
- else if ident[i] = '{' then
+ if (ident[i] = '}') or (ident[i] = '{') then
ident[i] := '_';
- end;
+
Result := ident;
end;
@@ -1432,14 +1333,15 @@ begin
ReWrite(UPRFile);
WriteLn(UPRFile, MainForm.UPRString(MainCp, Entry));
CloseFile(UPRFile);
- except on E: EInOutError do
+ except on EInOutError do
begin
- Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16);
Result := False;
+ raise Exception.CreateFmt(TextByKey('common-genericsavefailure'), [FileName]);
end;
end;
end;
+(* // AV: outdated, for affine coefs only
function IFSToString(cp: TControlPoint; Title: string): string;
{ Creates a string containing a formated IFS parameter set }
var
@@ -1449,7 +1351,7 @@ var
begin
Strings := TStringList.Create;
try
- Strings.Add(CleanEntry(Title) + ' {');
+ Strings.Add(CleanIdentifier(Title) + ' {');
for i := 0 to Transforms - 1 do
begin
a := cp.xform[i].c[0][0];
@@ -1468,170 +1370,22 @@ begin
Strings.Free;
end;
end;
+*)
-function GetTitle(str: string): string;
+procedure RotateCMapHue(var cp: TControlPoint); // AV
var
- p: integer;
+ i: byte;
+ h, s, v: real;
+ hue: double;
begin
- str := Trim(str);
- p := Pos(' ', str);
- GetTitle := Trim(Copy(str, 1, p));
-end;
-
-function GetComment(str: string): string;
-{ Extracts comment form line of IFS file }
-var
- p: integer;
-begin
- str := Trim(str);
- p := Pos(';', str);
- if p <> 0 then
- GetComment := Trim(Copy(str, p + 1, Length(str) - p))
- else
- GetComment := '';
-end;
-
-function GetParameters(str: string; var a, b, c, d, e, f, p: double): boolean;
-var
- Tokens: TStringList;
-begin
- GetParameters := False;
- Tokens := TStringList.Create;
- try
- try
- GetTokens(str, tokens);
- if Tokens.Count >= 7 then {enough tokens}
- begin
- a := StrToFloat(Tokens[0]);
- b := StrToFloat(Tokens[1]);
- c := StrToFloat(Tokens[2]);
- d := StrToFloat(Tokens[3]);
- e := StrToFloat(Tokens[4]);
- f := StrToFloat(Tokens[5]);
- p := StrToFloat(Tokens[6]);
- Result := True;
- end;
- except on E: EConvertError do
- begin
- Result := False
- end;
- end;
- finally
- Tokens.Free;
- end;
-end;
-
-function StringToIFS(strng: string): boolean;
-{ Loads an IFS parameter set from string}
-var
- Strings: TStringList;
- Comments: TStringList;
- i, sTransforms: integer;
- cmnt, sTitle: string;
- a, b, c, d: double;
- e, f, p: double;
-begin
- MainCp.clear;
- StringToIFS := True;
- sTransforms := 0;
- Strings := TStringList.Create;
- Comments := 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.');
- {To Do ... !!!!}
- sTitle := GetTitle(Strings[0]);
- if sTitle = '' then raise EFormatInvalid.Create('No identifier.');
- cmnt := GetComment(Strings[0]);
- if cmnt <> '' then Comments.Add(cmnt);
- i := 1;
- try
- repeat
- cmnt := GetComment(Strings[i]);
- if cmnt <> '' then Comments.Add(cmnt);
- if (Pos(';', Trim(Strings[i])) <> 1) and (Trim(Strings[i]) <> '') then
- if GetParameters(Strings[i], a, b, c, d, e, f, p) then
- begin
- MainCp.xform[sTransforms].c[0][0] := a;
- MainCp.xform[sTransforms].c[0][1] := c;
- MainCp.xform[sTransforms].c[1][0] := b;
- MainCp.xform[sTransforms].c[1][1] := d;
- MainCp.xform[sTransforms].c[2][0] := e;
- MainCp.xform[sTransforms].c[2][1] := f;
- MainCp.xform[sTransforms].density := p;
- inc(sTransforms);
- end
- else
- EFormatInvalid.Create('Insufficient parameters.');
- inc(i);
- until (Pos('}', Strings[i]) <> 0) or (sTransforms = NXFORMS);
- except on E: EMathError do
- end;
- if sTransforms < 2 then
- raise EFormatInvalid.Create('Insufficient parameters.');
- MainCp.name := sTitle;
- Transforms := sTransforms;
- for i := 1 to Transforms - 1 do
- MainCp.xform[i].color := 0;
- MainCp.xform[0].color := 1;
-
- except on E: EFormatInvalid do
- begin
- Application.MessageBox(PChar(TextByKey('common-invalidformat')), PChar('Apophysis'), 16);
- end;
- end;
- finally
- Strings.Free;
- Comments.Free;
- end;
-end;
-
-
-function SaveIFS(cp: TControlPoint; Title, FileName: string): boolean;
-{ Saves IFS parameters to end of file }
-var
- a, b, c: double;
- d, e, f, p: double;
- m: integer;
- IFile: TextFile;
-begin
- Result := True;
- try
- AssignFile(IFile, FileName);
- if FileExists(FileName) then
+ hue := cp.hue_rotation;
+ if (hue > 0) and (hue < 1) then // has visual effect
+ for i := 0 to 255 do
begin
- if EntryExists(Title, FileName) then DeleteEntry(Title, FileName);
- Append(IFile);
- end
- else
- ReWrite(IFile);
- WriteLn(IFile, Title + ' {');
- for m := 0 to Transforms - 1 do
- begin
- a := cp.xform[m].c[0][0];
- c := cp.xform[m].c[0][1];
- b := cp.xform[m].c[1][0];
- d := cp.xform[m].c[1][1];
- e := cp.xform[m].c[2][0];
- f := cp.xform[m].c[2][1];
- p := cp.xform[m].density;
- Write(IFile, Format('%.6g %.6g %.6g %.6g %.6g %.6g %.6g',
- [a, b, c, d, e, f, p]));
- WriteLn(IFile, '');
+ RGBToHSV(cp.cmap[i][0], cp.cmap[i][1], cp.cmap[i][2], h, s, v);
+ h := Round(360 + h + (hue * 360)) mod 360;
+ HSVToRGB(h, s, v, cp.cmap[i][0], cp.cmap[i][1], cp.cmap[i][2]);
end;
- WriteLn(IFile, '}');
- WriteLn(IFile, ' ');
- CloseFile(IFile);
- except on E: EInOutError do
- begin
- Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16);
- Result := False;
- end;
- end;
end;
function TMainForm.SaveFlame(cp1: TControlPoint; title, filename: string): boolean;
@@ -1672,8 +1426,8 @@ begin
except on EInOutError do
begin
- Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16);
Result := False;
+ raise Exception.CreateFmt(TextByKey('common-genericsavefailure'), [FileName]);
end;
end;
end;
@@ -1706,140 +1460,7 @@ begin
end;
end;
-
-function FlameToXMLAS(const cp1: TControlPoint; title: string; exporting: boolean): string;
-var
- t, i{, j}: integer;
- FileList: TStringList;
- x, y: double;
- parameters: string;
- curves, str: string;
-begin
- FileList := TStringList.create;
- x := cp1.center[0];
- y := cp1.center[1];
-
-// if cp1.cmapindex >= 0 then pal := pal + 'gradient="' + IntToStr(cp1.cmapindex) + '" ';
-
- try
- parameters := 'version="' + AppVersionString + '" ';
- if cp1.time <> 0 then
- parameters := parameters + format('time="%g" ', [cp1.time]);
-
- parameters := parameters +
- 'size="' + IntToStr(cp1.width) + ' ' + IntToStr(cp1.height) +
- format('" center="%g %g" ', [x, y]) +
- format('scale="%g" ', [cp1.pixels_per_unit]);
-
- if cp1.FAngle <> 0 then
- parameters := parameters + format('angle="%g" ', [cp1.FAngle]) +
- format('rotate="%g" ', [-180 * cp1.FAngle/Pi]);
- if cp1.zoom <> 0 then
- parameters := parameters + format('zoom="%g" ', [cp1.zoom]);
-
-// 3d
- if cp1.cameraPitch <> 0 then
- parameters := parameters + format('cam_pitch="%g" ', [cp1.cameraPitch]);
- if cp1.cameraYaw <> 0 then
- parameters := parameters + format('cam_yaw="%g" ', [cp1.cameraYaw]);
- if cp1.cameraRoll <> 0 then
- parameters := parameters + format('cam_roll="%g" ', [cp1.cameraRoll]);
- if cp1.cameraPersp <> 0 then
- parameters := parameters + format('cam_perspective="%g" ', [cp1.cameraPersp]);
- if cp1.cameraZpos <> 0 then
- parameters := parameters + format('cam_zpos="%g" ', [cp1.cameraZpos]);
- if cp1.cameraDOF <> 0 then
- parameters := parameters + format('cam_dof="%g" ', [cp1.cameraDOF]);
-//
- parameters := parameters + format(
- 'oversample="%d" filter="%g" quality="%g" ',
- [cp1.spatial_oversample,
- cp1.spatial_filter_radius,
- cp1.sample_density]
- );
- if cp1.nbatches <> 1 then parameters := parameters + 'batches="' + IntToStr(cp1.nbatches) + '" ';
- if cp1.hue_rotation <> 1 then parameters := parameters + format('hue="%g" ', [cp1.hue_rotation]); // AV
-
- parameters := parameters +
- format('background="%g %g %g" ', [cp1.background[0] / 255, cp1.background[1] / 255, cp1.background[2] / 255]) +
- format('brightness="%g" ', [cp1.brightness]) +
- format('gamma="%g" ', [cp1.gamma]);
-
- if cp1.contrast <> 1 then // AV
- parameters := parameters + format('contrast="%g" ', [cp1.contrast]);
-
- if cp1.vibrancy <> 1 then
- parameters := parameters + format('vibrancy="%g" ', [cp1.vibrancy]);
-
- if cp1.gamma_threshold <> 0 then
- parameters := parameters + format('gamma_threshold="%g" ', [cp1.gamma_threshold]);
-
- if cp1.soloXform >= 0 then
- parameters := parameters + format('soloxform="%d" ', [cp1.soloXform]);
-
- parameters := parameters +
- format('estimator_radius="%g" ', [cp1.estimator]) +
- format('estimator_minimum="%g" ', [cp1.estimator_min]) +
- format('estimator_curve="%g" ', [cp1.estimator_curve]);
- if (cp1.enable_de) then
- parameters := parameters + ('enable_de="1" ')
- else parameters := parameters + ('enable_de="0" ');
-
- str := '';
- for i := 0 to cp1.used_plugins.Count-1 do begin
- str := str + cp1.used_plugins[i];
- if (i = cp1.used_plugins.Count-1) then break;
- str := str + ' ';
- end;
- parameters := parameters + format('plugins="%s" new_linear="1" ', [str]);
-
- for i := 0 to 3 do
- begin
- curves := curves + FloatToStr(cp1.curvePoints[i][0].x) + ' ';
- curves := curves + FloatToStr(cp1.curvePoints[i][0].y) + ' ';
- curves := curves + FloatToStr(cp1.curveWeights[i][0]) + ' ';
-
- curves := curves + FloatToStr(cp1.curvePoints[i][1].x) + ' ';
- curves := curves + FloatToStr(cp1.curvePoints[i][1].y) + ' ';
- curves := curves + FloatToStr(cp1.curveWeights[i][1]) + ' ';
-
- curves := curves + FloatToStr(cp1.curvePoints[i][2].x) + ' ';
- curves := curves + FloatToStr(cp1.curvePoints[i][2].y) + ' ';
- curves := curves + FloatToStr(cp1.curveWeights[i][2]) + ' ';
-
- curves := curves + FloatToStr(cp1.curvePoints[i][3].x) + ' ';
- curves := curves + FloatToStr(cp1.curvePoints[i][3].y) + ' ';
- curves := curves + FloatToStr(cp1.curveWeights[i][3]) + ' ';
- end;
-
- curves := trim(curves);
- parameters := parameters + format('curves="%s" ', [curves]);
-
- FileList.Add('');
- { Write transform parameters }
- t := cp1.NumXForms;
- for i := 0 to t - 1 do
- FileList.Add(cp1.xform[i].ToXMLString);
- if cp1.HasFinalXForm then
- begin
- // 'enabled' flag disabled in this release
- FileList.Add(cp1.xform[t].FinalToXMLString(cp1.finalXformEnabled));
- end;
-
- { Write palette data }
- if exporting or OldPaletteFormat then
- FileList.Add(ColorToXml(cp1))
- else
- FileList.Add(ColorToXmlCompact(cp1));
-
- FileList.Add('');
- result := FileList.text;
- finally
- FileList.free
- end;
-end;
-
-/////////// AV: working with embedded PNG-parameters ////////////////////////
+//************ AV: working with embedded PNG-parameters ***********************//
procedure TMainForm.ImportFromPNGClick(Sender: TObject);
begin
@@ -1862,7 +1483,7 @@ begin
PasteFlameXML(flameXML);
except
Application.MessageBox(PChar(Format(TextByKey('common-openpngerror1'),
- [ExtractFileName(FileName)])), PChar('Apophysis AV'), MB_ICONWARNING or MB_OK);
+ [ExtractFileName(FileName)])), ApophysisSVN, MB_ICONWARNING or MB_OK);
end;
end;
end;
@@ -1873,7 +1494,6 @@ var
ChunkList: TPngList;
TextChunk: TChunkTEXT;
flameXML: string;
- label loadedFlame;
begin
Result := '';
PngObject := TPngObject.Create;
@@ -1888,29 +1508,29 @@ begin
begin
if TextChunk.Keyword = 'ApoFlame' then
begin
- if FindFlameXML(String(TextChunk.Text), '') > 0 then
+ flameXML := string(TextChunk.Text);
+ if FindFlameXML(flameXML, '') > 0 then
begin
- Result := String(TextChunk.Text);
- goto loadedFlame;
+ PngObject.Free; // AV: free the memory if search is succeed
+ Exit(flameXML); // AV: XML-flame is found
end;
break;
end else
- ChunkList.RemoveChunk(TextChunk);
+ ChunkList.RemoveChunk(TextChunk); // AV: text is not an XML-flame
end;
+ // AV: XML-parameters are not found
Application.MessageBox(PChar(Format(TextByKey('common-openpngerror2'),
- [ExtractFileName(FileName)])), PChar('Apophysis AV'), MB_ICONWARNING or MB_OK);
- loadedFlame:
+ [ExtractFileName(FileName)])), ApophysisSVN, MB_ICONWARNING or MB_OK);
end;
- except
+ except // AV: error in reading parameters
Application.MessageBox(PChar(Format(TextByKey('common-openpngerror3'),
- [ExtractFileName(FileName)])), PChar('Apophysis AV'), MB_ICONWARNING or MB_OK);
+ [ExtractFileName(FileName)])), ApophysisSVN, MB_ICONWARNING or MB_OK);
end;
- PngObject.Free;
+ PngObject.Free; // AV: free the memory if search is failed
end;
-///////////////////////////////
-
-
+//*************************************************************************//
+(*
function GetThumbnailBase64(const cp1: TControlPoint) : string;
var
st: TMemoryStream;
@@ -1944,8 +1564,8 @@ begin
tempcp.Copy(cp1);
tempcp.AdjustScale(round(w), round(h));
- tempcp.Width := round(w);
- tempcp.Height := round(h);
+ // tempcp.Width := round(w);
+ // tempcp.Height := round(h);
tempcp.spatial_oversample := defOversample;
tempcp.spatial_filter_radius := defFilterRadius;
tempcp.sample_density := 10;
@@ -1971,20 +1591,25 @@ begin
result := base64;
end;
+ *)
-function FlameToXML(const cp1: TControlPoint; exporting, embedthumb: boolean): String;
+// AV: added default parameter values to get rid of duplicated code
+function FlameToXML(const cp1: TControlPoint; exporting: boolean = false; title: string = ''): string;
var
- t, i{, j}, pos: integer;
+ t, i: integer;
FileList: TStringList;
x, y: double;
parameters: string;
- curves, str, buf, xdata: string;
+ curves, str, cpName: string;
begin
FileList := TStringList.create;
x := cp1.center[0];
y := cp1.center[1];
-// if cp1.cmapindex >= 0 then pal := pal + 'gradient="' + IntToStr(cp1.cmapindex) + '" ';
+ if title = '' then // AV
+ cpName := CleanXMLName(cp1.name)
+ else
+ cpName := CleanXMLName(title);
try
parameters := 'version="' + AppVersionString + '" ';
@@ -2042,7 +1667,6 @@ begin
if cp1.soloXform >= 0 then
parameters := parameters + format('soloxform="%d" ', [cp1.soloXform]);
- //
parameters := parameters +
format('estimator_radius="%g" ', [cp1.estimator]) +
format('estimator_minimum="%g" ', [cp1.estimator_min]) +
@@ -2083,7 +1707,10 @@ begin
curves := trim(curves);
parameters := parameters + format('curves="%s" ', [curves]);
- FileList.Add('');
+ FileList.Add('');
+
+ if cp1.comment <> '' then FileList.Add(''); // AV
+
{ Write transform parameters }
t := cp1.NumXForms;
for i := 0 to t - 1 do
@@ -2094,7 +1721,9 @@ begin
FileList.Add(cp1.xform[t].FinalToXMLString(cp1.finalXformEnabled));
end;
- if (embedthumb and EmbedThumbnails) then begin
+ (*
+ // AV: too bugged... and not extremely useful thing
+ if (embedthumb and EmbedThumbnails) then begin
xdata := GetThumbnailBase64(cp1);
buf := '';
for i := 1 to length(xdata) do begin
@@ -2106,6 +1735,7 @@ begin
end;
if (Length(buf) > 0) then FileList.Add(' ');
end;
+ *)
{ Write palette data }
if exporting or OldPaletteFormat then
@@ -2114,9 +1744,9 @@ begin
FileList.Add(ColorToXmlCompact(cp1));
FileList.Add('');
- result := FileList.text;
+ Result := FileList.text;
finally
- FileList.free
+ FileList.Free;
end;
end;
@@ -2128,7 +1758,7 @@ begin
filename := ExtractFileName(filename);
ext := ExtractFileExt(filename);
p := Pos(ext, filename);
- Result := Copy(filename, 0, p - 1);
+ Result := Copy(filename, 1, p - 1); // AV: 1 <-- 0
end;
function XMLEntryExists(title, filename: string): boolean;
@@ -2147,7 +1777,7 @@ begin
FileList.Free;
end
end else
- result := false;
+ Result := false;
end;
procedure DeleteXMLEntry(title, filename: string);
@@ -2159,7 +1789,9 @@ begin
try
i := 0;
Strings.LoadFromFile(FileName);
- while Pos('name="' + title + '"', Trim(Strings[i])) = 0 do
+ { AV: fixed a bug with data corruption when the name of file or transform
+ is the same as the flame name! Was: 'name="'}
+ while Pos(' 0) then begin
//FileList[0] := '';
- // AV: fix fixed :-)
- if (pos(' 0) then
+ // AV: fix fixed :-) Apo 2.09 uses capital F in this tag
+ if (pos(' 0) then
FileList[0] := ''
else // single-flame support
FileList.Insert(0, '');
- end;
+ end
+ else // AV: if the existing file is empty
+ FileList.Add(''); // AV
if FileList.Count > 2 then
begin
// AV fix last line :-)
if (pos('', FileList[FileList.Count - 1]) = 0) then
- FileList.Add('');
+ FileList.Add('');
if pos(' 0 then
repeat
FileList.Delete(FileList.Count - 1);
until (Pos('', FileList[FileList.count - 1]) <> 0)
else
- repeat
+ repeat // AV: now condition will be true anyway
FileList.Delete(FileList.Count - 1);
- until (Pos('<' + Tag + '>', FileList[FileList.count - 1]) <> 0) or
- (Pos('', FileList[FileList.count - 1]) <> 0);
- end else
- begin
+ until (Pos('', FileList[FileList.count - 1]) <> 0) or
+ (Pos('<' + Tag + '>', FileList[FileList.count - 1]) <> 0);
+ end else if (FileList.count > 1) then // AV
FileList.Delete(FileList.Count - 1);
- end;
- FileList.Add(Trim(FlameToXML(cp1, false, true)));
+ FileList.Add(Trim(FlameToXML(cp1, false, title)));
FileList.Add('');
FileList.SaveToFile(filename);
@@ -2256,15 +1887,16 @@ begin
begin
// New file ... easy
FileList := TStringList.Create;
- FileList.Text := '' + #$0D#$0A +
- FlameToXML(cp1, false, true) + #$0D#$0A + '';
+ FileList.Add('');
+ FileList.Add(FlameToXML(cp1, false, title));
+ FileList.Add('');
FileList.SaveToFile(filename, TEncoding.UTF8);
- FileList.Destroy;
+ FileList.Free;
end;
- except // AV: fixed multi-updating
+
+ except // AV: fixed multi-updating of the flame
Result := False; // AV: first assign the value, then exit
- raise Exception.CreateFmt(TextByKey('common-genericsavefailure'), [FileName]); // AV
- //Application.MessageBox(PChar(Format(TextByKey('common-genericsavefailure'), [FileName])), 'Apophysis', 16);
+ raise Exception.CreateFmt(TextByKey('common-genericsavefailure'), [FileName]);
end;
end;
@@ -2302,7 +1934,7 @@ var
s: string;
begin
Result := True;
- NewIdent := CleanEntry(NewIdent);
+ NewIdent := CleanIdentifier(NewIdent);
Strings := TStringList.Create;
try
try
@@ -2367,7 +1999,7 @@ end;
procedure ListIFS(FileName: string; sel: integer);
-{ List identifiers in file }
+{ AV: List identifiers in Undo file }
var
i, p: integer;
Title: string;
@@ -2386,7 +2018,7 @@ begin
begin
p := Pos('{', FStrings[i]);
// AV: why do we use 2-nd condition? A rudiment from 3D-hack?
- if (p <> 0) and (Pos('(3D)', FStrings[i]) = 0) then
+ if (p <> 0) {and (Pos('(3D)', FStrings[i]) = 0)} then
begin
Title := Trim(Copy(FStrings[i], 1, p - 1));
if Title <> '' then
@@ -2395,14 +2027,20 @@ begin
MainForm.LoadSaveProgress.Position :=
round(100 * i / FStrings.Count); // AV
ListItem := MainForm.ListView1.Items.Add;
- Listitem.Caption := Title; // Trim(Copy(FStrings[i], 1, p - 1));
+ ListItem.Caption := Title;
+ // AV: hack - remember the creation order in an unused field
+ ListItem.OverlayIndex := MainForm.ListView1.Items.Count;
end;
end;
end;
end;
MainForm.LoadSaveProgress.Position := 0; // AV
- MainForm.ListView1.Items.EndUpdate;
+ if ClassicListMode then // AV: thumbs are useless
+ GeneratingThumbs := False
+ else // AV: added thumbnails support for Undo list
+ MainForm.RunThumbnailThread;
+
with MainForm.ListView1 do
if Items.Count > 0 then // AV
case sel of
@@ -2410,11 +2048,15 @@ begin
1: Selected := Items[0];
end;
finally
- FStrings.Free;
+ MainForm.ListView1.Items.EndUpdate;
+ FStrings.Free;
end;
MainForm.ParseLoadingBatch := false; // AV
+
+ if AnimateForm.Visible then AnimateForm.UpdateControls; // AV
end;
+(*
procedure ListFlames(FileName: string; sel: integer);
{ List identifiers in file }
var
@@ -2450,6 +2092,7 @@ begin
FStrings.Free;
end;
end;
+*)
{ ****************************** Display ************************************ }
@@ -2538,6 +2181,7 @@ begin
Trace1('');
end;
+(*
procedure TMainForm.DrawPreview;
var
cp : TControlPoint;
@@ -2559,13 +2203,19 @@ begin
BM.Assign(Render.GetImage);
Image.Picture.Graphic := bm;
end;
+*)
procedure TMainForm.DrawFlame;
+const
+{$ifdef CPUX86}
+ bs = 16;
+{$else}
+ bs = 32;
+{$endif}
var
GlobalMemoryInfo: TMemoryStatus; // holds the global memory status information
RenderCP: TControlPoint;
Mem, ApproxMem: cardinal;
- bs: integer;
begin
RedrawTimer.Enabled := False;
if Assigned(Renderer) then begin
@@ -2589,11 +2239,6 @@ begin
RenderCP := MainCP.Clone;
RenderCp.AdjustScale(Image.width, Image.height);
- // following needed ?
-// cp.Zoom := Zoom;
-// cp.center[0] := center[0];
-// cp.center[1] := center[1];
-
RenderCP.sample_density := defSampleDensity;
// oversample and filter are just slowing us down here...
RenderCP.spatial_oversample := 1; // defOversample;
@@ -2604,9 +2249,6 @@ begin
GlobalMemoryStatus(GlobalMemoryInfo);
Mem := GlobalMemoryInfo.dwAvailPhys;
- if (singleBuffer) then bs := 16
- else bs := 32;
-
// if Output.Lines.Count >= 1000 then Output.Lines.Clear;
Trace1('--- Previewing "' + RenderCP.name + '" ---');
Trace1(Format(' Available memory: %f Mb', [Mem / (1024*1024)]));
@@ -2648,37 +2290,8 @@ begin
end;
end;
-{ ************************** IFS and triangle stuff ************************* }
-
-function FlameToString(Title: string): string;
-{ Creates a string containing the formated flame parameter set }
-var
- I: integer;
- sl, Strings: TStringList;
-begin
- Strings := TStringList.Create;
- sl := TStringList.Create;
- try
- Strings.Add(CleanEntry(Title) + ' {');
- MainCp.SaveToStringList(sl);
- Strings.Add(sl.text);
- Strings.Add('palette:');
- for i := 0 to 255 do
- begin
- Strings.Add(IntToStr(MainCp.cmap[i][0]) + ' ' +
- IntToStr(MainCp.cmap[i][1]) + ' ' +
- IntToStr(MainCp.cmap[i][2]))
- end;
- Strings.Add('}');
- Result := Strings.Text;
- finally
- sl.Free;
- Strings.Free;
- end;
-end;
-
procedure TMainForm.RandomBatch;
-{ Write a series of random ifs to a file }
+{ Write a series of random flames to a file }
var
i: integer;
F: TextFile;
@@ -2687,9 +2300,10 @@ begin
b := IntToStr(BatchSize);
inc(MainSeed);
RandSeed := MainSeed;
+ RandFile := AppPath + randFilename;
try
- AssignFile(F, AppPath + randFilename);
- OpenFile := AppPath + randFilename;
+ AssignFile(F, RandFile);
+ OpenFile := RandFile;
ReWrite(F);
WriteLn(F, ''); // AV: fixed '');
for i := 0 to BatchSize - 1 do
@@ -2703,15 +2317,16 @@ begin
RandomizeCP(MainCp);
MainCp.CalcBoundbox;
MainCp.name := RandomPrefix + RandomDate + '-' + IntToStr(RandomIndex);
- Write(F, FlameToXML(MainCp, False, false));
+ Write(F, FlameToXML(MainCp));
end;
Write(F, ''); // AV: fixed '');
CloseFile(F);
except
on EInOutError do
- Application.MessageBox(PChar(TextByKey('main-status-batcherror')), PChar('Apophysis'), 16);
+ Application.MessageBox(PChar(TextByKey('main-status-batcherror')),
+ ApophysisSVN, 16);
end;
- RandFile := AppPath + randFilename;
+
MainCp.name := '';
end;
@@ -2750,7 +2365,7 @@ begin
p := Pos(' 0) then
begin
- MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FileStrings[i])));
+ MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FileStrings[i])));
MainForm.ListXMLScanner.Execute;
if pname <> '' then
begin
@@ -2786,40 +2401,12 @@ begin
end;
end;
-procedure AddThumbnail(renderer : TRenderer; width, height : double);
-var
- Bmp: TBitmap;
- x, y : double;
-begin
- Bmp := TBitmap.Create;
- Bmp.PixelFormat := pf24bit;
- Bmp.HandleType := bmDIB;
- Bmp.Width := ThumbnailSize;
- Bmp.Height := ThumbnailSize;
-
- x := ThumbnailSize / 2;
- y := ThumbnailSize / 2;
-
- x := x - width / 2;
- y := y - height / 2;
-
- with Bmp.Canvas do begin
- Brush.Color := GetSysColor(5); // window background
- FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
- Draw(round(x), round(y), renderer.GetImage);
- end;
-
- MainForm.UsedThumbnails.Add(bmp, nil);
-
- if (Bmp <> nil) then Bmp.Free;
-end;
-
function ScanVariations(name:string):boolean;
var
- i,count:integer;
- vname:string;
+ i,count: integer;
+ vname: string;
begin
- count:=NrVar;
+ count := NrVar;
for i:=0 to count - 1 do
begin
vname := VarNames(i);
@@ -2829,6 +2416,7 @@ begin
exit;
end;
end;
+
for i := 0 to MainForm.SubstSource.Count - 1 do
begin
vname := MainForm.SubstSource[i];
@@ -2840,12 +2428,13 @@ begin
end;
Result := false;
end;
+
function ScanVariables(name:string):boolean;
var
- i,count:integer;
+ i, count: integer;
begin
- count:=GetNrVariableNames;
- for i:=0 to count - 1 do
+ count := GetNrVariableNames;
+ for i :=0 to count - 1 do
begin
if (GetVariableNameAt(i) = name) then
begin
@@ -2868,8 +2457,7 @@ procedure TMainForm.mnuOpenClick(Sender: TObject);
var
fn: string;
begin
- //ScriptEditor.Stopped := True;
- MainMenuClick(nil); // AV
+ StopScripter; // AV
OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame;*.xml|'
+ TextByKey('common-filter-templatefiles') + ' |*.template;*.temp|'
@@ -2877,35 +2465,34 @@ begin
+ TextByKey('common-filter-allfiles') + '|*.*';
OpenDialog.InitialDir := ParamFolder;
OpenDialog.FileName := '';
- if OpenSaveFileDialog(MainForm, '.flame', OpenDialog.Filter, OpenDialog.InitialDir,
- TextByKey('common-browse'), fn, true, false, false, true) then
+ OpenDialog.Title := ''; // AV
+// AV: turn back classic dialog since OpenSaveFileDialog looks ugly then themed
+ if OpenDialog.Execute then
begin
- OpenDialog.FileName := fn;
- MainForm.CurrentFileName := OpenDialog.FileName;
- LastOpenFile := OpenDialog.FileName;
+ fn := OpenDialog.FileName; // AV
+ LastOpenFile := fn;
Maincp.name := '';
- ParamFolder := ExtractFilePath(OpenDialog.FileName);
- OpenFile := OpenDialog.FileName;
- //MainForm.Caption := AppVersionString + ' - ' + OpenFile; // --Z--
- if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + openFile
- else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + openFile;
- OpenFileType := ftXML;
- (* if UpperCase(ExtractFileExt(OpenDialog.FileName)) = '.IFS' then
- begin
- OpenFileType := ftIfs;
- Variation := vLinear;
- VarMenus[0].Checked := True;
- end; *)
- if (UpperCase(ExtractFileExt(OpenDialog.FileName)) = '.UNDO') or
- (UpperCase(ExtractFileExt(OpenDialog.FileName)) = '.APO') then
- OpenFileType := ftFla; // AV
- if OpenFileType = ftXML then
- ListXML(OpenDialog.FileName, 1)
+ ParamFolder := ExtractFilePath(fn);
+ OpenFile := fn;
+ if APP_BUILD = '' then
+ MainForm.Caption := AppVersionString + ' - ' + OpenFile
else
+ MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + OpenFile;
+
+ fn := UpperCase(ExtractFileExt(fn));
+ if (fn = '.UNDO') or (fn = '.APO') then
+ begin
+ OpenFileType := ftApo; // AV
ListIFS(OpenDialog.FileName, 1);
+ end
+ else begin
+ OpenFileType := ftXML;
+ ListXML(OpenDialog.FileName, 1);
+ end;
end;
end;
+(*
procedure TMainForm.mnuNextClick(Sender: TObject);
begin
with ListView1 do
@@ -2925,18 +2512,12 @@ begin
Selected := Items[i];
end;
end;
+*)
procedure TMainForm.mnuListRenameClick(Sender: TObject);
-var
- i: integer;
begin
- if ListView1.SelCount <> 0 then
- begin
- if (UndoIndex <> 0) then // AV
- if Application.MessageBox(PChar(Format(TextByKey('common-confirmrename'),
- [ListView1.Selected.Caption])), 'Apophysis AV', 36) <> IDYES then exit;
+ if ListView1.Selected <> nil then
ListView1.Items[ListView1.Selected.Index].EditCaption;
- end;
end;
procedure TMainForm.mnuCopyUPRClick(Sender: TObject);
@@ -2955,10 +2536,11 @@ begin
if (UndoIndex <> 0) then // AV: if the flame is not saved in the list
c := Application.MessageBox(
PChar(Format(TextByKey('common-confirmdelete'), [ListView1.Selected.Caption])
- + #32 + TextByKey('common-deletecurrent')), 'Apophysis', 36) = IDYES
+ + #32 + TextByKey('common-deletecurrent')), ApophysisSVN, 36) = IDYES
else
c := Application.MessageBox(
- PChar(Format(TextByKey('common-confirmdelete'), [ListView1.Selected.Caption])), 'Apophysis', 36) = IDYES
+ PChar(Format(TextByKey('common-confirmdelete'), [ListView1.Selected.Caption])),
+ ApophysisSVN, 36) = IDYES
end
else
c := True;
@@ -2971,6 +2553,7 @@ begin
else
DeleteEntry(ListView1.Selected.Caption, OpenFile);
{
+ // AV: do not change the sequence in order to display all icons properly
if (ListView1.Selected.Index >= 0) and (ListView1.Selected.Index < UsedThumbnails.Count)
and (not ClassicListMode) then
UsedThumbnails.Delete(ListView1.Selected.Index);
@@ -2980,6 +2563,8 @@ begin
ListView1.Selected := ListView1.ItemFocused;
// AV: re-adjust the displayed numbers...
if EnumerateFlames.Checked then EnumerateFlamesClick(EnumerateFlames);
+
+ if AnimateForm.Visible then AnimateForm.UpdateControls; // AV
(*
// AV: I set ListView1.IconOptions.AutoArrange := True;
// for auto-updating the flame list without redrawing the thumbs.
@@ -3006,26 +2591,29 @@ procedure TMainForm.mnuOptionsClick(Sender: TObject);
var isSmallThumb: boolean;
begin
isSmallThumb := UseSmallThumbnails; // AV
- OptionsForm.ShowModal;
- // --Z--
- StopThread;
- RedrawTimer.Enabled := True;
- tbQualityBox.Text := FloatToStr(defSampleDensity);
- tbShowAlpha.Down := ShowTransparency;
- if (isSmallThumb <> UseSmallThumbnails) then // update the thumbs
+ // AV: update flame ONLY if settings were changed
+ if OptionsForm.ShowModal = mrOK then
begin
- SetThumbnailProperties; // AV
- UpdateThumbnails; // AV
+ StopThread; // --Z--
+ RedrawTimer.Enabled := True;
+ tbQualityBox.Text := FloatToStr(defSampleDensity);
+ tbShowAlpha.Down := ShowTransparency;
+ if (isSmallThumb <> UseSmallThumbnails) then // update the thumbs
+ begin
+ SetThumbnailProperties; // AV
+ UpdateThumbnails; // AV
+ end;
+ if EnumerateFlames.Checked then EnumerateFlamesClick(EnumerateFlames); // AV
+ SetAutoSaveTimer; // AV: to enable autosave without restarting Apophysis
+
+ if ConfirmResetUndo then
+ ListView1.OnSelectItem := ListViewSelectItem
+ else
+ ListView1.OnSelectItem := nil;
+
+ DrawImageView;
+ UpdateWindows;
end;
- if EnumerateFlames.Checked then EnumerateFlamesClick(EnumerateFlames); // AV
-
- DrawImageView;
- UpdateWindows;
-end;
-
-procedure TMainForm.mnuRefreshClick(Sender: TObject);
-begin
- RedrawTimer.enabled := true;
end;
procedure TMainForm.mnuRefreshThumbClick(Sender: TObject);
@@ -3045,20 +2633,21 @@ begin
end;
procedure TMainForm.mnuRWeightsClick(Sender: TObject);
+var i: smallint;
begin
StopThread;
UpdateUndo;
inc(MainSeed);
RandSeed := MainSeed;
- MainCp.RandomizeWeights;
+ for i := 0 to Transforms - 1 do
+ maincp.xform[i].density := random;
RedrawTimer.Enabled := True;
UpdateWindows;
end;
procedure TMainForm.mnuRandomBatchClick(Sender: TObject);
begin
- //ScriptEditor.Stopped := True;
- MainMenuClick(nil); // AV
+ // StopScripter;
inc(MainSeed);
RandSeed := MainSeed;
@@ -3114,7 +2703,7 @@ begin
Strings := TStringList.Create;
GradStrings := TStringList.Create;
try
- Strings.Add(CleanEntry(Entry) + ' {');
+ Strings.Add(CleanIdentifier(Entry) + ' {');
Strings.Add('fractal:');
Strings.Add(' title="' + CleanUPRTitle(Entry) +
'" width=' + IntToStr(UPRWidth) + ' height=' + IntToStr(UPRHeight) + ' layers=1');
@@ -3208,11 +2797,13 @@ begin
end;
procedure TMainForm.mnuEqualizeClick(Sender: TObject);
+var i: smallint;
begin
StopThread;
UpdateUndo;
- MainCP.EqualizeWeights;
RedrawTimer.Enabled := True;
+ for i := 0 to Transforms - 1 do
+ maincp.xform[i].density := 0.5;
UpdateWindows;
end;
@@ -3223,8 +2814,6 @@ end;
procedure TMainForm.mnuExitClick(Sender: TObject);
begin
- MainMenuClick(nil); // AV
-
Close;
end;
@@ -3232,7 +2821,7 @@ procedure TMainForm.mnuSaveUPRClick(Sender: TObject);
{ Write a UPR to a file }
begin
SaveForm.SaveType := stExportUPR;
- SaveForm.Filename := UPRPath + 'Apophysis.upr'; // AV
+ SaveForm.Filename := UPRPath;
SaveForm.Title := maincp.name;
if SaveForm.ShowModal = mrOK then
begin
@@ -3241,33 +2830,98 @@ begin
end;
end;
+procedure FlameFromUndo(cp: TControlPoint; const FlameName: string; const ParamFile: string);
+{ AV: common method for loading internal-formatted flames }
+var
+ FStrings, IFSStrings, EntryStrings, Tokens: TStringList;
+ SavedPal: Boolean;
+ i, j: integer;
+ floatcolor: double;
+ s: string;
+ Palette: TColorMap;
+begin
+ SavedPal := false;
+
+ FStrings := TStringList.Create;
+ IFSStrings := TStringList.Create;
+ Tokens := TStringList.Create;
+ EntryStrings := TStringList.Create;
+
+ try
+ FStrings.LoadFromFile(ParamFile);
+ for i := 0 to FStrings.count - 1 do
+ if Pos(FlameName + ' {', Trim(FStrings[i])) = 1 then
+ break;
+ IFSStrings.Add(FStrings[i]);
+ repeat
+ inc(i);
+ IFSStrings.Add(FStrings[i]);
+ until Pos('}', FStrings[i]) <> 0;
+
+ for i := 0 to FStrings.count - 1 do
+ begin
+ if Pos(FlameName + ' {', Trim(FStrings[i])) = 1 then
+ break;
+ end;
+ inc(i);
+ while (Pos('}', FStrings[i]) = 0) and (Pos('palette:', FStrings[i]) = 0) do
+ begin
+ EntryStrings.Add(FStrings[i]);
+ inc(i);
+ end;
+ if Pos('palette:', FStrings[i]) = 1 then
+ begin
+ SavedPal := True;
+ inc(i);
+ for j := 0 to 255 do begin
+ s := FStrings[i];
+ GetTokens(s, tokens);
+ floatcolor := StrToFloat(Tokens[0]);
+ Palette[j][0] := round(floatcolor);
+ floatcolor := StrToFloat(Tokens[1]);
+ Palette[j][1] := round(floatcolor);
+ floatcolor := StrToFloat(Tokens[2]);
+ Palette[j][2] := round(floatcolor);
+ inc(i);
+ end;
+ end;
+ cp.ParseString(EntryStrings.Text);
+ if SavedPal then cp.cmap := Palette;
+ cp.name := FlameName;
+ finally
+ IFSStrings.Free;
+ FStrings.Free;
+ Tokens.free;
+ EntryStrings.free;
+ end;
+end;
+
procedure TMainForm.mnuSaveAsClick(Sender: TObject);
-{ Save parameters to a file }
-var saved: boolean; // AV
+{ Save fractal parameters to a file }
+var
+ saved: boolean; // AV
+ ext: string;
begin
SaveForm.SaveType := stSaveParameters;
SaveForm.Filename := SavePath;
SaveForm.Title := maincp.name;
+ SaveForm.Comment := maincp.comment; // AV
if SaveForm.ShowModal = mrOK then
begin
maincp.name := SaveForm.Title;
SavePath := SaveForm.Filename;
- if ExtractFileExt(SavePath) = '' then
+ maincp.comment := SaveForm.Comment;
+ ext := LowerCase(ExtractFileExt(SavePath));
+ if ext = '' then
SavePath := SavePath + '.flame';
- if (LowerCase(ExtractFileExt(SaveForm.Filename)) = '.undo') or
- (LowerCase(ExtractFileExt(SaveForm.Filename)) = '.apo') then
+ if (ext = '.undo') or (ext = '.apo') then
saved := SaveFlame(maincp, maincp.name, SavePath) // AV
else
saved := SaveXMLFlame(maincp, maincp.name, SavePath);
StatusBar.Panels[3].Text := maincp.name;
if (SavePath = OpenFile) and saved then // AV: added status check
- begin
- if OpenFileType = ftXML then
// AV: fixed re-saving error with OpenDialog.FileName!
- ListXML(OpenFile, 2, maincp.name) // AV: remember the current position
- else
- ListIFS(OpenFile, 0); // AV: fixed re-saving error!
- end;
+ AddFlameToList; // AV: show the new item
end;
end;
@@ -3276,33 +2930,55 @@ procedure TMainForm.mnuSaveAllAsClick(Sender: TObject);
var
i, current: integer;
currentXML : string;
+ cp: TControlPoint;
begin
+
SaveForm.SaveType := stSaveAllParameters;
SaveForm.Filename := SavePath;
if SaveForm.ShowModal = mrOK then
begin
- SavePath := SaveForm.Filename;
+ SavePath := SaveForm.Filename;
if ExtractFileExt(SavePath) = '' then
SavePath := SavePath + '.flame';
- current := ListView1.ItemIndex;
- currentXML := Trim(FlameToXML(Maincp, false, true));
+
+ // AV: added support for saving all Undo flames as XML
+ if OpenFileType = ftApo then
+ begin
+ cp := TControlPoint.Create;
+ try
+ for i := 0 to ListView1.Items.Count-1 do
+ begin
+ cp.Clear;
+ FlameFromUndo(cp, ListView1.Items[i].Caption, OpenFile);
+ SaveXMLFlame(cp, cp.name, SavePath);
+ LoadSaveProgress.Position := round(100 * i /(ListView1.Items.Count - 1));
+ end;
+ finally
+ LoadSaveProgress.Position := 0; // AV
+ cp.Free;
+ end;
+ exit;
+ end;
+
+ current := ListView1.ItemIndex; // AV: hmm, what if ListView1.Selected = nil?
+ currentXML := Trim(FlameToXML(Maincp));
for i := 0 to ListView1.Items.Count-1 do
begin
// -X- what if there are unsaved changes at the current CP?
// AV: this only can be if UndoIndex <> 0
if (i = current) and (UndoIndex <> 0) then begin
- ParseXML(maincp, PCHAR(currentXML), true);
+ ParseXML(maincp, currentXML, true); // AV: fixed - was PChar instead String
SaveXMLFlame(maincp, maincp.name, SavePath);
end else begin
- // AV: cancel unneseccary multiple preview updated
- LoadXMLFlame(OpenFile, ListView1.Items.Item[i].Caption, false);
+ // AV: cancel useless multiple preview updated
+ LoadXMLFlame(OpenFile, ListView1.Items[i].Caption, false);
SaveXMLFlame(maincp, maincp.name, SavePath);
end;
- MainForm.LoadSaveProgress.Position :=
- round(100 * i / (ListView1.Items.Count - 1)); // AV
+ LoadSaveProgress.Position :=
+ round(100 * i / (ListView1.Items.Count - 1)); // AV: display progress
end;
- MainForm.LoadSaveProgress.Position := 0; // AV
+ LoadSaveProgress.Position := 0; // AV
// AV: we don't need to do this because it resets the Undo history!
{
ListXML(SavePath, 2);
@@ -3313,14 +2989,6 @@ begin
end;
end;
-function GradTitle(str: string): string;
-var
- p: integer;
-begin
- p := pos('{', str);
- GradTitle := Trim(copy(str, 1, p - 1));
-end;
-
procedure TMainForm.DisplayHint(Sender: TObject);
var
T: TComponent;
@@ -3343,16 +3011,18 @@ end;
procedure TMainForm.DownloadPluginsClick(Sender: TObject);
begin
- AboutForm.lblPluginsClick(nil);
+ AboutForm.lblPluginsClick(Sender);
end;
-procedure TMainForm.MainMenuClick(Sender: TObject);
+procedure TMainForm.StopScripter;
begin
- try // AV: sometimes this damn Stopped causes AccessViolations...
- if ScriptEditor.btnPause.Down then ScriptEditor.btnPause.Click; // AV
- ScriptEditor.Stopped := True;
+ try
+ with ScriptEditor do begin
+ if btnPause.Down then btnPause.Click;
+ Stopped := True;
+ end;
except
- // ?
+ // Beep;
end;
end;
@@ -3409,13 +3079,12 @@ end;
procedure TMainForm.GetScripts;
var
- NewItem, NewItem2, MenuItem: TMenuItem;
+ NewItem, MenuItem: TMenuItem;
searchResult: TSearchRec;
i: integer;
- s, path, path1: string;
+ s, path: string;
sl: TStringList;
begin
-
sl := TStringList.Create;
if FileExists(AppPath + scriptFavsFilename) then
begin
@@ -3449,7 +3118,7 @@ begin
NewItem.Caption := s;
NewItem.Hint := Format(TextByKey('main-menu-script-run3'), [s]);
NewItem.OnClick := FavoriteClick;
- OnClick := FavoriteClick;
+ //OnClick := FavoriteClick; // AV: MainForm.OnClick - why?!
FavouriteScripts1.Add(NewItem);
end;
end;
@@ -3468,16 +3137,16 @@ begin
begin
Directory1.Enabled := True;
repeat
- NewItem2 := TMenuItem.Create(Directory1); // (Self);
+ NewItem := TMenuItem.Create(Directory1); // (Self);
s := searchResult.Name;
if (sl.IndexOf(s) < 0) then
begin
s := RemoveExt(s);
- NewItem2.AutoHotkeys := maManual; // AV: to prevent underlined letters
- NewItem2.Caption := s;
- NewItem2.Hint := Format(TextByKey('main-menu-script-run3'), [s]);
- NewItem2.OnClick := ScriptItemClick;
- if (Directory1.Find(s) = nil) then Directory1.Add(NewItem2);
+ NewItem.AutoHotkeys := maManual; // AV: to prevent underlined letters
+ NewItem.Caption := s;
+ NewItem.Hint := Format(TextByKey('main-menu-script-run3'), [s]);
+ NewItem.OnClick := ScriptItemClick;
+ if (Directory1.Find(s) = nil) then Directory1.Add(NewItem);
end;
until (FindNext(searchResult) <> 0);
FindClose(searchResult);
@@ -3488,29 +3157,41 @@ begin
begin
Directory1.Enabled := True;
repeat
- NewItem2 := TMenuItem.Create(Directory1); // (Self);
+ NewItem := TMenuItem.Create(Directory1); // (Self);
s := searchResult.Name;
if (sl.IndexOf(s) < 0) then
begin
s := RemoveExt(s);
- NewItem2.AutoHotkeys := maManual; // AV: to prevent underlined letters
- NewItem2.Caption := s;
- NewItem2.Tag := 1; // AV: to identify scripts with different extensions
- NewItem2.Hint := Format(TextByKey('main-menu-script-run3'), [s]);
- NewItem2.OnClick := ScriptItemClick;
- if (Directory1.Find(s) = nil) then Directory1.Add(NewItem2);
+ NewItem.AutoHotkeys := maManual; // AV: to prevent underlined letters
+ NewItem.Caption := s;
+ NewItem.Tag := 1; // AV: to identify scripts with different extensions
+ NewItem.Hint := Format(TextByKey('main-menu-script-run3'), [s]);
+ NewItem.OnClick := ScriptItemClick;
+ if (Directory1.Find(s) = nil) then Directory1.Add(NewItem);
end;
until (FindNext(searchResult) <> 0);
FindClose(searchResult);
end;
if (Directory1.Count = 0) then Directory1.Enabled := False; // AV
sl.Free;
+
+ i := 0;
+ while i < FavouriteScripts1.Count do
+ begin
+ FavouriteScripts1[i].Break := mbBreak;
+ inc(i, mbHeight);
+ end;
+ i := 0;
+ while i < Directory1.Count do
+ begin
+ Directory1[i].Break := mbBreak;
+ inc(i, mbHeight);
+ end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
var
dte: string;
- cmdl : TCommandLine;
Registry: TRegistry;
apoUI: string;
Layouts: array[0..7] of THandle;
@@ -3518,14 +3199,12 @@ var
ExtSM: HMenu;
extStyle: TSearchRec;
begin
- ApophysisSVN := APP_VERSION;
- AppVersionString := APP_NAME +' '+ APP_VERSION;
+ AppVersionString := APP_NAME + ' ' + APP_VERSION;
SubstSource := TStringList.Create;
SubstTarget := TStringList.Create;
CreateSubstMap;
- TbBreakWidth := 802;
ListXmlScanner := TEasyXmlScanner.Create(nil);
XmlScanner := TXmlScanner.Create(nil);
@@ -3538,13 +3217,11 @@ begin
MainForm.XmlScanner.OnEmptyTag := XMLScannerEmptyTag;
MainForm.XmlScanner.OnEndTag := XmlScannerEndTag;
MainForm.XmlScanner.OnStartTag := XMLScannerStartTag;
+ MainForm.XmlScanner.OnComment := XmlScannerComment; // AV
AppPath := ExtractFilePath(Application.ExeName); // AV: moved here
ReadSettings;
- InternalBitsPerSample := 0; // AV: now unused
- // renderBitsPerSample := 0;
-
//SaveSettings;
LoadLanguage(LanguageFile);
InsertStrings;
@@ -3553,19 +3230,18 @@ begin
AvailableLanguages.Add('');
ListLanguages;
+ SplashWindow.SetInfo(TextByKey('splash-loadingplugins'));
MissingPluginList := TStringList.Create; // AV
-
- C_SyncDllPlugins;
-
- cmdl := TCommandLine.Create;
- cmdl.Load;
+ C_SyncDllPlugins; // for Chaotica export
if (NXFORMS > 100) then
AppVersionString := AppVersionString + ' (' + TextByKey('main-common-title-t500') + ')'
- else if (NXFORMS < 100) or (cmdl.Lite) then
+ else if (NXFORMS < 100) then
AppVersionString := AppVersionString + ' (' + TextByKey('main-common-title-lite') + ')';
SplashWindow.SetInfo(TextByKey('splash-loadingui'));
+ // AV: prevent reloading of the splash window after style changing
+ SplashWindow.OnShow := nil;
{ //*************** GUI Style Stuff *****************************// }
@@ -3647,7 +3323,6 @@ begin
end;
end;
- SplashWindow.SetInfo(TextByKey('splash-loadingplugins'));
FillVariantMenu;
tbQualityBox.Text := FloatToStr(defSampleDensity);
@@ -3681,21 +3356,12 @@ begin
{ *******************************************************************}
- if not cmdl.Lite then
- begin
- if ClassicListMode = true then
- btnViewListClick(nil)
- else
- btnViewIconsClick(nil);
- end else
- begin // AV: Lite version from command line cannot change NXFORM const :(
- ListView1.ViewStyle := vsReport;
- ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(btnViewList), 0);
- ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(btnViewIcons), 0);
- ToolBar.Perform(CM_CONTROLCHANGE, WPARAM(ToolButton9), 0);
- TbBreakWidth := TbBreakWidth - (2 * 26 + 1 * 8);
- end;
- cmdl.Free; // <-- AV: fixed memory leak
+ if ClassicListMode = true then
+ btnViewListClick(nil)
+ else
+ btnViewIconsClick(nil);
+
+ if ConfirmResetUndo = False then ListView1.OnSelectItem := nil; // AV
SaveSettings; // AV: moved back from top to the end
end;
@@ -3705,7 +3371,6 @@ var
Registry: TRegistry;
i: integer;
index: integer;
- mins:integer;
cmdl : TCommandLine;
fn, flameXML : string;
openScript: string;
@@ -3746,9 +3411,12 @@ begin
finally
Registry.Free;
end;
- { Synchronize menus etc..}
- // should be defaults....
+
SplashWindow.SetInfo(TextByKey('splash-initrenderer'));
+ Application.ProcessMessages; // AV: added to update the status properly
+
+ { Synchronize menus etc..}
+ // should be defaults....
UndoIndex := 0;
UndoMax := 0;
index := 1;
@@ -3793,16 +3461,19 @@ begin
GetCMap(cmap_index, 1, maincp.cmap);
DefaultPalette := maincp.cmap;
end;
- if FileExists(AppPath + randFilename) then
- DeleteFile(AppPath + randFilename);
+
+ fn := AppPath + randFilename;
+ if FileExists(fn) then DeleteFile(fn);
+ fn := AppPath + ChangeFileExt(randFilename, '.bak'); // AV
+ if FileExists(fn) then DeleteFile(fn);
cmdl := TCommandLine.Create;
cmdl.Load;
openScript := '';
- // get filename from command line argument
SplashWindow.SetInfo(TextByKey('splash-initbatch'));
+ // get filename from command line argument
if ParamCount > 0 then
openFile := ParamStr(1)
else
@@ -3813,17 +3484,16 @@ begin
index := LastOpenFileEntry;
end;
- // if FileExists(openFile) and ((LowerCase(ExtractFileExt(OpenFile)) <> '.asc') or (LowerCase(ExtractFileExt(OpenFile)) <> '.aposcript')) then begin
- // AV: something's wrong here...
- if FileExists(openFile) and (not ((LowerCase(ExtractFileExt(OpenFile)) = '.asc') or (LowerCase(ExtractFileExt(OpenFile)) = '.aposcript'))) then begin
+ // AV: we must precalc the string that is used so often
+ fn := LowerCase(ExtractFileExt(OpenFile));
+
+ if FileExists(openFile) and (not ((fn = '.asc') or (fn = '.aposcript'))) then begin
LastOpenFile := openFile;
LastOpenFileEntry := index;
end;
- // if (openFile = '') or (not FileExists(openFile)) and ((LowerCase(ExtractFileExt(OpenFile)) <> '.asc') or (LowerCase(ExtractFileExt(OpenFile)) <> '.aposcript')) then
- // AV: something's wrong here...
if (openFile = '') or (not FileExists(openFile)) and
- (not ((LowerCase(ExtractFileExt(OpenFile)) = '.asc') or (LowerCase(ExtractFileExt(OpenFile)) = '.aposcript'))) then
+ (not ((fn = '.asc') or (fn = '.aposcript'))) then
begin
MainCp.Width := Image.Width;
MainCp.Height := Image.Height;
@@ -3833,18 +3503,18 @@ begin
else
MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + TextByKey('main-common-randombatch');
OpenFile := AppPath + randFilename;
- ListXML(OpenFile, 1);
- OpenFileType := ftXML;
+ OpenFileType := ftXML;
+ ListXML(OpenFile, 1);
if batchsize = 1 then DrawFlame;
end
else
begin
- if (LowerCase(ExtractFileExt(OpenFile)) = '.apo') or (LowerCase(ExtractFileExt(OpenFile)) = '.undo') then
+ if (fn = '.apo') or (fn = '.undo') then
begin
- ListFlames(OpenFile, 1);
- OpenFileType := ftFla;
+ OpenFileType := ftApo; // AV: we must choose a file type BEFORE updating list view
+ ListIFS(OpenFile, 1); // ListFlames(OpenFile, 1);
end else
- if (LowerCase(ExtractFileExt(OpenFile)) = '.asc') or (LowerCase(ExtractFileExt(OpenFile)) = '.aposcript') then
+ if (fn = '.asc') or (fn = '.aposcript') then
begin
openScript := OpenFile;
RandomBatch;
@@ -3853,12 +3523,12 @@ begin
else
MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + TextByKey('main-common-randombatch');
OpenFile := AppPath + randFilename;
- ListXML(OpenFile, 1);
OpenFileType := ftXML;
+ ListXML(OpenFile, 1);
if batchsize = 1 then DrawFlame;
end else begin
- ListXML(OpenFile, 2);
OpenFileType := ftXML;
+ ListXML(OpenFile, 2);
MainForm.ListView1.Selected := MainForm.ListView1.Items[index - 1];
end;
if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + openFile
@@ -3876,18 +3546,7 @@ begin
// ExportDialog.cmbDepth.ItemIndex := 2; // AV: changed inside ExportForm
// DoNotAskAboutChange := false;
- if (AutoSaveFreq = 0) then mins := 1
- else if (AutoSaveFreq = 1) then mins := 2
- else if (AutoSaveFreq = 2) then mins := 5
- else if (AutoSaveFreq = 3) then mins := 10
- else begin
- mins := 5;
- AutoSaveFreq := 2;
- AutoSaveEnabled := false;
- end;
-
- AutoSaveTimer.Interval := 60 * 1000 * mins;
- AutoSaveTimer.Enabled := AutoSaveEnabled;
+ SetAutoSaveTimer; // AV: a code block is replaced by a method
// loading done..now do what is told by cmdline ...
if (cmdl.CreateFromTemplate) then begin
@@ -3899,14 +3558,13 @@ begin
ScriptEditor.Stopped := True;
StopThread;
- InvokeLoadXML(flameXML);
+ ParseXML(MainCP, flameXML, false); //InvokeLoadXML(flameXML);
Transforms := MainCp.TrianglesFromCP(MainTriangles);
Statusbar.Panels[3].Text := MainCp.name;
ResizeImage;
RedrawTimer.Enabled := True;
Application.ProcessMessages;
UpdateWindows;
- //AdjustForm.TemplateRandomizeGradient;
AdjustForm.mnuRandomize.Click;
end;
end;
@@ -3984,18 +3642,21 @@ end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
Registry: TRegistry;
+ fn: string;
begin
if ConfirmExit and (UndoIndex <> 0) then
- if Application.MessageBox(PChar(TextByKey('common-confirmexit')), 'Apophysis', MB_ICONWARNING or MB_YESNO) <> IDYES then
+ if Application.MessageBox(PChar(TextByKey('common-confirmexit')),
+ ApophysisSVN, MB_ICONWARNING or MB_YESNO) <> IDYES then
begin
Action := caNone;
exit;
end;
- if ScriptEditor.btnPause.Down then ScriptEditor.btnPause.Click; // AV
- ScriptEditor.Stopped := True;
+ AutoSaveTimer.Enabled := False; // AV
+ StopScripter; // AV: stopping the scripter's animation
+
+ // HtmlHelp(0, nil, HH_CLOSE_ALL, 0);
- HtmlHelp(0, nil, HH_CLOSE_ALL, 0);
{ To capture secondary window positions }
if EditForm.visible then EditForm.Close;
if AdjustForm.visible then AdjustForm.close;
@@ -4027,17 +3688,24 @@ begin
finally
Registry.Free;
end;
+
Application.ProcessMessages;
CanDrawOnResize := False;
- if FileExists(AppPath + randFilename) then
- DeleteFile(AppPath + randFilename);
- if FileExists(AppPath + undoFilename) then
- DeleteFile(AppPath + undoFilename);
+
+ fn := AppPath + randFilename;
+ if FileExists(fn) then DeleteFile(fn);
+ fn := AppPath + ChangeFileExt(randFilename, '.bak'); // AV
+ if FileExists(fn) then DeleteFile(fn);
+ fn := AppPath + undoFilename;
+ if FileExists(fn) then DeleteFile(fn);
+ fn := APPDATA + export_flame; // AV
+ if FileExists(fn) then DeleteFile(fn);
if KeepBackGround then // AV
- RandBackColor := MainCp.background[2] * 65536 + MainCp.background[1] * 256 + MainCp.background[0];
+ RandBackColor := MainCp.background[2] * 65536 +
+ MainCp.background[1] * 256 + MainCp.background[0];
// AV: remember the flame position if the list was sorted
- if assigned(ListView1.Selected) then
+ if assigned(ListView1.Selected) then
LastOpenFileEntry := ListView1.Selected.Index + 1;
SaveSettings;
@@ -4046,8 +3714,8 @@ end;
procedure TMainForm.FormDestroy(Sender: TObject);
var i: word;
begin
- if assigned(Renderer) then Renderer.Terminate;
- if assigned(Renderer) then Renderer.WaitFor;
+ //if assigned(Renderer) then Renderer.Terminate;
+ //if assigned(Renderer) then Renderer.WaitFor;
if assigned(Renderer) then Renderer.Free;
if assigned(FViewImage) then FViewImage.Free;
@@ -4109,12 +3777,15 @@ end;
procedure TMainForm.BackPanelResize(Sender: TObject);
begin
+ try
StopThread;
if CanDrawOnResize then
reDrawTimer.Enabled := True;
- ResizeImage;
+ ResizeImage;
DrawImageView;
+ except
+ end;
end;
// AV: added the third parameter to prevent multiple updates of the previews
@@ -4146,8 +3817,8 @@ begin
p := Pos(' 0) then
begin
- MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FileStrings[i])));
- MainForm.ListXMLScanner.Execute;
+ ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FileStrings[i]))); // AV
+ ListXMLScanner.Execute;
if pname <> '' then
begin
if (Trim(pname) = Trim(name)) then
@@ -4172,12 +3843,12 @@ begin
ParamStrings.Add(FileStrings[i]);
until pos('', Lowercase(FileStrings[i])) <> 0;
- //ScriptEditor.Stopped := True; // AV: I hate this...
- // If script preview isnit visible, it's useless,
+ //ScriptEditor.Stopped := True; // <-- AV: I hate this...
+ // If script preview isn't visible, it's useless,
// otherwise it loads wrong flame from sripter...
StopThread;
- ParseXML(MainCp,ParamStrings.Text, true);
+ ParseXML(MainCp, ParamStrings.Text, true);
if upd then
begin // AV: to prevent redrawing when saving a batch
@@ -4269,20 +3940,22 @@ begin
if not (ClassicListMode or ParseLoadingBatch) then UpdateThumbnails;
end;
+procedure TMainForm.ListViewSelectItem(Sender: TObject; Item: TListItem;
+ Selected: Boolean);
+begin
+ if (UndoIndex <> 0) and (not Selected) then
+ if Application.MessageBox(PChar(TextByKey('common-confirmselect')),
+ ApophysisSVN, 36) = IDYES then
+ mnuSaveUndo.Click; // AV
+end;
+
procedure TMainForm.ListViewChange(Sender: TObject; Item: TListItem;
Change: TItemChange);
var
- FStrings: TStringList;
- IFSStrings: TStringList;
- EntryStrings, Tokens: TStringList;
- SavedPal: Boolean;
- i, j: integer;
- floatcolor: double;
- s: string;
- Palette: TcolorMap;
- name:string;
+ i: smallint;
begin
- if (ListView1.SelCount <> 0) and (Trim(ListView1.Selected.Caption) <> Trim(maincp.name)) then
+ if (ListView1.Selected <> nil) and
+ (Trim(ListView1.Selected.Caption) <> Trim(maincp.name)) then
begin
LastOpenFileEntry := ListView1.Selected.Index + 1;
RedrawTimer.Enabled := False; //?
@@ -4290,114 +3963,51 @@ begin
if OpenFileType = ftXML then
begin
- name := ListView1.Selected.caption;
- ParseLoadingBatch := false;
- LoadXMLFlame(OpenFile, name);
+ // ParseLoadingBatch := false; // AV: ?
+ LoadXMLFlame(OpenFile, ListView1.Selected.caption);
AnnoyUser;
end
- else
+ else // if OpenFileType = ftApo then // AV: Undo flame list
begin
- SavedPal := false;
- //ScriptEditor.Stopped := True;
+ maincp.Clear; // initialize control point for new flame;
- FStrings := TStringList.Create;
- IFSStrings := TStringList.Create;
- Tokens := TStringList.Create;
- EntryStrings := TStringList.Create;
- try
- FStrings.LoadFromFile(OpenFile);
- for i := 0 to FStrings.count - 1 do
- if Pos(ListView1.Selected.Caption + ' {', Trim(FStrings[i])) = 1 then
- break;
- IFSStrings.Add(FStrings[i]);
- repeat
- inc(i);
- IFSStrings.Add(FStrings[i]);
- until Pos('}', FStrings[i]) <> 0;
- maincp.Clear; // initialize control point for new flame;
- maincp.background[0] := 0;
- maincp.background[1] := 0;
- maincp.background[2] := 0;
- maincp.sample_density := defSampleDensity;
- maincp.spatial_oversample := defOversample;
- maincp.spatial_filter_radius := defFilterRadius;
- if OpenFileType = ftFla then // AV: Undo flame list
- begin
- for i := 0 to FStrings.count - 1 do
- begin
- if Pos(ListView1.Selected.Caption + ' {', Trim(FStrings[i])) = 1 then
- break;
- end;
- inc(i);
- while (Pos('}', FStrings[i]) = 0) and (Pos('palette:', FStrings[i]) = 0) do
- begin
- EntryStrings.Add(FStrings[i]);
- inc(i);
- end;
- if Pos('palette:', FStrings[i]) = 1 then
- begin
- SavedPal := True;
- inc(i);
- for j := 0 to 255 do begin
- s := FStrings[i];
- GetTokens(s, tokens);
- floatcolor := StrToFloat(Tokens[0]);
- Palette[j][0] := round(floatcolor);
- floatcolor := StrToFloat(Tokens[1]);
- Palette[j][1] := round(floatcolor);
- floatcolor := StrToFloat(Tokens[2]);
- Palette[j][2] := round(floatcolor);
- inc(i);
- end;
- end;
- FlameString := EntryStrings.Text;
- maincp.ParseString(FlameString);
- Transforms := MainCP.NumXForms;
- end
- else
- begin
- { Open *.ifs File }
- Variation := vLinear;
- VarMenus[0].Checked := True;
- StringToIFS(IFSStrings.Text);
- SetVariation(maincp);
- maincp.CalcBoundBox;
- end;
- Center[0] := maincp.Center[0];
- Center[1] := maincp.Center[1];
- mnuSaveUndo.Enabled := false;
- mnuUndo.Enabled := False;
- mnuPopUndo.Enabled := False;
- mnuRedo.enabled := False;
- mnuPopRedo.enabled := False;
- EditForm.mnuUndo.Enabled := False;
- EditForm.mnuRedo.enabled := False;
- EditForm.tbUndo.enabled := false;
- EditForm.tbRedo.enabled := false;
- AdjustForm.btnUndo.enabled := false;
- AdjustForm.btnRedo.enabled := false;
- btnUndo.Enabled := false;
- btnRedo.enabled := false;
- Transforms := MainCp.TrianglesFromCP(MainTriangles);
+ // AV: deleted all duplicated code here
+ FlameFromUndo(maincp, ListView1.Selected.caption, OpenFile);
+
+ maincp.sample_density := defSampleDensity;
+ maincp.spatial_oversample := defOversample;
+ maincp.spatial_filter_radius := defFilterRadius;
+
+ //Transforms := MainCP.NumXForms; // we'll change it later
+ Center[0] := maincp.Center[0];
+ Center[1] := maincp.Center[1];
+ mnuSaveUndo.Enabled := false;
+ mnuUndo.Enabled := False;
+ mnuPopUndo.Enabled := False;
+ mnuRedo.enabled := False;
+ mnuPopRedo.enabled := False;
+ EditForm.mnuUndo.Enabled := False;
+ EditForm.mnuRedo.enabled := False;
+ EditForm.tbUndo.enabled := false;
+ EditForm.tbRedo.enabled := false;
+ AdjustForm.btnUndo.enabled := false;
+ AdjustForm.btnRedo.enabled := false;
+ btnUndo.Enabled := false;
+ btnRedo.enabled := false;
+ Transforms := MainCp.TrianglesFromCP(MainTriangles);
// Fix Apophysis 1.0 parameters with negative color parameteres!
- for i := 0 to Transforms - 1 do
- if maincp.xform[i].color < 0 then maincp.xform[i].color := 0;
- if SavedPal then maincp.cmap := Palette;
- UndoIndex := 0;
- UndoMax := 0;
- if fileExists(AppPath + undoFilename) then
- DeleteFile(AppPath + undoFilename);
- maincp.name := ListView1.Selected.Caption; // AV: fixed Apo7X bug
- Statusbar.Panels[3].Text := maincp.name;
- RedrawTimer.Enabled := True;
- Application.ProcessMessages;
- UpdateWindows;
- finally
- IFSStrings.Free;
- FStrings.Free;
- Tokens.free;
- EntryStrings.free;
- end;
+ for i := 0 to Transforms - 1 do
+ if maincp.xform[i].color < 0 then maincp.xform[i].color := 0;
+
+ UndoIndex := 0;
+ UndoMax := 0;
+ if fileExists(AppPath + undoFilename) then
+ DeleteFile(AppPath + undoFilename);
+ maincp.name := ListView1.Selected.Caption; // AV: fixed Apo7X bug
+ Statusbar.Panels[3].Text := maincp.name;
+ RedrawTimer.Enabled := True;
+ Application.ProcessMessages;
+ UpdateWindows;
end;
{if ResizeOnLoad then}
ResizeImage;
@@ -4409,7 +4019,6 @@ begin
if AdjustForm.visible then AdjustForm.UpdateDisplay;
if EditForm.visible then EditForm.UpdateDisplay;
if MutateForm.visible then MutateForm.UpdateDisplay;
- if CurvesForm.Visible then CurvesForm.SetCp(MainCp);
end;
procedure TMainForm.LoadUndoFlame(index: integer; filename: string);
@@ -4464,11 +4073,10 @@ begin
end;
end;
maincp.Clear;
- FlameString := EntryStrings.Text;
maincp.zoom := 0;
maincp.center[0] := 0;
maincp.center[0] := 0;
- maincp.ParseString(FlameString);
+ maincp.ParseString(EntryStrings.Text);
maincp.sample_density := defSampleDensity;
Center[0] := maincp.Center[0];
Center[1] := maincp.Center[1];
@@ -4490,7 +4098,7 @@ begin
end;
procedure TMainForm.ResetColorSpeedClick(Sender: TObject);
-var i: integer;
+var i: smallint;
begin
StopThread;
UpdateUndo;
@@ -4501,7 +4109,7 @@ begin
end;
procedure TMainForm.ResetColorValuesClick(Sender: TObject);
-var i: integer;
+var i: smallint;
begin
StopThread;
UpdateUndo;
@@ -4532,12 +4140,12 @@ begin
// AV: fixed 'List index out of bounds' bugs
if (s = '') then
begin
- MessageBox(Handle, PChar(TextByKey('save-status-notitle')), PCHar('Apophysis AV'), 48);
+ MessageBox(Handle, PChar(TextByKey('save-status-notitle')), ApophysisSVN, 48);
Discard := True;
end else if (ListView1.FindCaption(0, s, false, true, false) <> nil) then
begin
MessageBox(Handle, PChar(Format(TextByKey('save-status-alreadyexists3'),
- [s])), PChar('Apophysis AV'), 48);
+ [s])), ApophysisSVN, 48);
Discard := True;
end
else if OpenFileType = ftXML then
@@ -4547,9 +4155,16 @@ begin
if Discard then
s := Item.Caption
- else
+ else begin
+ MainCp.name := s; // AV: prevent unnecessary flame redrawing
+ StatusBar.Panels[3].Text := s; // AV
+
+ Application.ProcessMessages;
+
+ if AnimateForm.Visible then AnimateForm.Close; // TODO
if SortFlames.Checked and EnumerateFlames.Checked then
- EnumerateFlamesClick(EnumerateFlames);
+ EnumerateFlamesClick(EnumerateFlames); // hmm
+ end;
end;
end;
@@ -4563,14 +4178,14 @@ begin
end;
procedure TMainForm.mnuVRandomClick(Sender: TObject);
-var i: integer;
begin
mnuVRandom.Checked := True;
// AV: only one variation can be active here
- for i := 0 to NRVAR - 1 do
- VarMenus[i].Checked := False;
- mnuBuiltinVars.Checked := False;
- mnuPluginVars.Checked := False;
+ if Variation > vRandom then begin
+ VarMenus[Variation].Checked := False;
+ mnuBuiltinVars.Checked := False;
+ mnuPluginVars.Checked := False;
+ end;
StopThread;
UpdateUndo;
inc(MainSeed);
@@ -4594,7 +4209,7 @@ begin
AdjustForm.Show;
end;
-///////////////////////////////////////////////////////////////////////////////
+//**************** Smooth Palette *********************//
procedure swapcolor(var clist: array of cardinal; i, j: integer);
var
@@ -4629,6 +4244,7 @@ procedure TMainForm.SmoothPalette;
var
Bitmap: TBitMap;
JPEG: TJPEGImage;
+ PNG: TPNGImage; // AV
pal: TColorMap;
strings: TStringlist;
ident, FileName: string;
@@ -4640,36 +4256,52 @@ begin
//Total := Trunc(NumTries * TryLength / 100);
//p := 0;
Bitmap := TBitmap.Create;
- JPEG := TJPEGImage.Create;
strings := TStringList.Create;
try
begin
inc(MainSeed);
RandSeed := MainSeed;
- OpenDialog.Filter := Format('%s|*.bmp;*.dib;*.jpg;*.jpeg|%s|*.bmp;*.dib|%s|*.jpg;*.jpeg|%s|*.*',
- [TextByKey('common-filter-allimages'), TextByKey('common-filter-bitmap'),
- TextByKey('common-filter-jpeg'), TextByKey('common-filter-allfiles')]);
+ OpenDialog.Filter := RenderForm.SaveDialog.Filter; // AV: added precalc
OpenDialog.InitialDir := ImageFolder;
- OpenDialog.Title := TextByKey('common-browse');
+ OpenDialog.Title := TextByKey('common-selectimage'); // AV
OpenDialog.FileName := '';
- if OpenSaveFileDialog(MainForm, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
+ if OpenDialog.Execute then
begin
- OpenDialog.FileName := fn;
- ImageFolder := ExtractFilePath(OpenDialog.FileName);
+ fn := OpenDialog.FileName; // AV
+ ImageFolder := ExtractFilePath(fn);
Application.ProcessMessages;
len_best := 0;
- if (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.BMP')
- or (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.DIB') then
- Bitmap.LoadFromFile(Opendialog.FileName);
- if (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.JPG')
- or (UpperCase(ExtractFileExt(Opendialog.FileName)) = '.JPEG') then
+ ident := UpperCase(ExtractFileExt(fn)); // AV: added precalc
+ if (ident = '.BMP') or (ident = '.DIB') then
+ Bitmap.LoadFromFile(fn)
+ else if (ident = '.JPG') or (ident = '.JPEG') then
begin
- JPEG.LoadFromFile(Opendialog.FileName);
- with Bitmap do
- begin
- Width := JPEG.Width;
- Height := JPEG.Height;
- Canvas.Draw(0, 0, JPEG);
+ JPEG := TJPEGImage.Create;
+ try
+ JPEG.LoadFromFile(fn);
+ with Bitmap do
+ begin
+ Width := JPEG.Width;
+ Height := JPEG.Height;
+ Canvas.Draw(0, 0, JPEG);
+ end;
+ finally
+ JPEG.Free;
+ end;
+ end
+ else // if (ident = '.PNG') then // <-- AV: added PNG support here
+ begin
+ PNG := TPNGImage.Create; // AV
+ try
+ PNG.LoadFromFile(fn);
+ with Bitmap do
+ begin
+ Width := PNG.Width;
+ Height := PNG.Height;
+ Canvas.Draw(0, 0, PNG);
+ end;
+ finally
+ PNG.Free;
end;
end;
iw := Bitmap.Width;
@@ -4748,7 +4380,7 @@ begin
end;
{ Convert to TColorMap, Gradient and save }
FileName := lowercase(ExtractFileName(Opendialog.FileName));
- ident := CleanEntry(FileName);
+ ident := CleanIdentifier(FileName);
strings.add(ident + ' {');
strings.add('gradient:');
strings.add(' title="' + CleanUPRTitle(FileName) + '" smooth=no');
@@ -4783,37 +4415,10 @@ begin
end;
finally
Bitmap.Free;
- JPEG.Free;
strings.Free;
end;
end;
-procedure TMainForm.SortFlamesClick(Sender: TObject);
-begin
- StopThread;
- SortFlames.Checked := not SortFlames.Checked;
- if SortFlames.Checked then
- begin
- ListView1.SortType := stText;
- // AV: to use Morph scripting method properly
- ScriptForm.FileList.Sorted := True;
- if ListView1.Items.Count > 1 then ListView1.AlphaSort;
- EnumerateFlamesClick(EnumerateFlames);
- end
- else begin
- ListView1.SortType := stNone;
- ScriptForm.FileList.Sorted := False;
- if (OpenFile <> '') then
- if OpenFileType = ftXML then
- begin
- if assigned(ListView1.Selected) then
- ListXML(OpenFile, 2, ListView1.Selected.Caption)
- else
- ListXML(OpenFile, 1);
- end;
- end;
-end;
-
procedure TMainForm.Smoothize(const oldpal: TColorMap; const a, b: byte);
{ AV: this one applies Smooth palette to the current gradient or its part }
var
@@ -4910,11 +4515,46 @@ begin
if EditForm.Visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
RedrawTimer.enabled := true;
-
+
finally
end;
end;
+//**********************************************************************//
+
+{ AV: quick sort to switch between alphabetical and chronological flame order }
+function ChronoSort(Item1, Item2: TListItem; ParamSort: integer): integer; stdcall;
+begin
+ Result := (Item1.OverlayIndex - Item2.OverlayIndex); // hacky, but fast...
+end;
+
+procedure TMainForm.SortFlamesClick(Sender: TObject);
+begin
+ SortFlames.Checked := not SortFlames.Checked;
+ if SortFlames.Checked then
+ begin
+ ListView1.SortType := stText;
+ // AV: to use Morph scripting method properly
+ ScriptForm.ScFileList.Sorted := True;
+ if ListView1.Items.Count > 1 then begin
+ ListView1.AlphaSort;
+ if EnumerateFlames.Checked then EnumerateFlamesClick(EnumerateFlames);
+ end;
+ end
+ else begin
+ ListView1.SortType := stNone;
+ ScriptForm.ScFileList.Sorted := False;
+ if ListView1.Items.Count > 1 then begin
+ ListView1.CustomSort(@ChronoSort, 0);
+ if EnumerateFlames.Checked then EnumerateFlamesClick(EnumerateFlames);
+ end;
+ end;
+
+ if AnimateForm.Visible then AnimateForm.UpdateControls;
+end;
+
+//**********************************************************************//
+
procedure TMainForm.mnuThumbnailQualityClick(Sender: TObject); // AV
begin
if TMenuItem(Sender).Checked then exit; // prevent unneseccary updating
@@ -4928,7 +4568,7 @@ begin
ThumbPrevQual := TMenuItem(Sender).Tag;
// refresh the list of flame previews
- if (OpenFile <> '') and (OpenFileType = ftXML) then
+ if (OpenFile <> '') then
if not ParseLoadingBatch then UpdateThumbnails;
end;
@@ -4993,7 +4633,7 @@ end;
procedure TMainForm.mnuUnflattenClick(Sender: TObject);
var
- i, t: integer;
+ i, t: smallint;
refresh: boolean;
begin
StopThread;
@@ -5048,7 +4688,7 @@ end;
// AV: added support for fast preview and params saving without rendering
// for absolute beginners :)
procedure TMainForm.mnuExportBitmapClick(Sender: TObject);
-var pic: TPNGObject;
+var pic: TPNGImage;
begin
SaveDialog.DefaultExt := 'png';
SaveDialog.Filter := Format('%s|*.png', [TextByKey('common-filter-png')]);
@@ -5056,10 +4696,10 @@ begin
if SaveDialog.Execute then
begin
try
- pic := TPNGObject.Create;
+ pic := TPNGImage.Create;
try
pic.Assign(Image.Picture.Bitmap);
- pic.AddtEXt('ApoFlame', AnsiString(Trim(FlameToXML(Maincp, false, false))));
+ pic.AddtEXt('ApoFlame', AnsiString(Trim(FlameToXML(Maincp))));
pic.SaveToFile(SaveDialog.Filename);
finally
pic.Free;
@@ -5072,15 +4712,16 @@ end;
procedure TMainForm.mnuFullScreenClick(Sender: TObject);
begin
- FullScreenForm.ActiveForm := Screen.ActiveForm;
+ // AV: screen size never changed while app works - moved into OnCreate handler
+ {
FullScreenForm.Width := Screen.Width;
FullScreenForm.Height := Screen.Height;
FullScreenForm.Top := 0;
FullScreenForm.Left := 0;
+ }
+ FullScreenForm.ActiveForm := Screen.ActiveForm;
FullScreenForm.cp.Copy(maincp);
FullScreenForm.cp.cmap := maincp.cmap;
- FullScreenForm.center[0] := center[0];
- FullScreenForm.center[1] := center[1];
FullScreenForm.Calculate := True;
FullScreenForm.Show;
end;
@@ -5093,7 +4734,7 @@ begin
NewRender := True;
if Assigned(RenderForm.Renderer) then
- if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then
+ if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), ApophysisSVN, 36) = ID_NO then
NewRender := false;
if NewRender then
@@ -5110,16 +4751,17 @@ begin
3: Ext := '.jpg';
end;
+ RenderForm.bRenderAll := False;
+
//RenderForm.caption := 'Render ' + #39 + maincp.name + #39 + ' to Disk';
+ RenderForm.Caption := RenderForm.Hint; // AV
RenderForm.Filename := RenderPath + maincp.name + Ext;
RenderForm.SaveDialog.FileName := RenderPath + maincp.name + Ext;
RenderForm.txtFilename.Text := ChangeFileExt(RenderForm.SaveDialog.Filename, Ext);
RenderForm.cp.Copy(MainCP);
RenderForm.cp.cmap := maincp.cmap;
- RenderForm.zoom := maincp.zoom;
- RenderForm.Center[0] := center[0];
- RenderForm.Center[1] := center[1];
+
if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #2
end;
RenderForm.Show;
@@ -5129,11 +4771,12 @@ procedure TMainForm.mnuRenderAllClick(Sender: TObject);
var
Ext: string;
NewRender: Boolean;
+ i: smallint;
begin
NewRender := True;
if Assigned(RenderForm.Renderer) then
- if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then
+ if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), ApophysisSVN, 36) = ID_NO then
NewRender := false;
if NewRender then
@@ -5150,17 +4793,24 @@ begin
3: Ext := '.jpg';
end;
- //RenderForm.caption := 'Render all flames to disk';
+ RenderForm.Caption := GetShortHint(tbRenderAll.Hint); // AV
RenderForm.bRenderAll := true;
RenderForm.Filename := RenderPath + maincp.name + Ext;
RenderForm.SaveDialog.FileName := RenderForm.Filename;
RenderForm.txtFilename.Text := ChangeFileExt(RenderForm.SaveDialog.Filename, Ext);
+ //AV: added support here for any flame-file (not only opened)
+ RenderForm.RenderFlameFile := OpenFile;
+ SetLength(RenderForm.FlameNames, ListView1.Items.Count);
+ for i := 0 to ListView1.Items.Count - 1 do
+ RenderForm.FlameNames[i] := ListView1.Items[i].Caption;
+ {
RenderForm.cp.Copy(MainCP);
RenderForm.cp.cmap := maincp.cmap;
RenderForm.zoom := maincp.zoom;
RenderForm.Center[0] := center[0];
RenderForm.Center[1] := center[1];
+ }
if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #2
end;
RenderForm.Show;
@@ -5179,6 +4829,12 @@ begin
AdjustForm.Show;
end;
+procedure TMainForm.mnuAnimatorClick(Sender: TObject);
+begin
+ StopScripter;
+ AnimateForm.Show;
+end;
+
procedure TMainForm.mnuResetLocationClick(Sender: TObject);
var
scale: double;
@@ -5234,8 +4890,9 @@ procedure TMainForm.mnuSaveUndoClick(Sender: TObject);
begin
if FileExists(AppPath + undoFilename) then
begin
- SaveDialog.DefaultExt := 'undo';
+ SaveDialog.DefaultExt := 'apo';
SaveDialog.Filter := TextByKey('common-filter-undofiles') + '|*undo;*.apo';
+ SaveDialog.InitialDir := ParamFolder;
SaveDialog.Filename := maincp.name;
if SaveDialog.Execute then
begin
@@ -5248,10 +4905,11 @@ end;
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if Assigned(RenderForm.Renderer) then
- if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then
- CanClose := False;
+ if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
+ ApophysisSVN, 36) = ID_NO then
+ CanClose := False;
- AboutToExit := CanClose;
+ // AboutToExit := CanClose;
end;
procedure TMainForm.FormActivate(Sender: TObject);
@@ -5267,19 +4925,22 @@ end;
procedure TMainForm.mnuCalculateColorsClick(Sender: TObject);
var
- i: integer;
+ i: smallint;
begin
StopThread;
UpdateUndo;
- for i := 0 to Transforms - 1 do
- maincp.xform[i].color := i / (transforms - 1);
+ if Transforms > 1 then // AV: fixed divide-by-zero bug
+ for i := 0 to Transforms - 1 do
+ maincp.xform[i].color := i / (transforms - 1)
+ else
+ maincp.xform[0].color := 0; // AV
RedrawTimer.Enabled := True;
UpdateWindows;
end;
procedure TMainForm.mnuRandomizeColorValuesClick(Sender: TObject);
var
- i: integer;
+ i: smallint;
begin
inc(MainSeed);
RandSeed := MainSeed;
@@ -5352,7 +5013,7 @@ var
begin
if FavoritesForm.ShowModal = mrOK then
begin
- if favorites.count <> 0 then
+ if Favorites.Count <> 0 then
begin
for i := 0 to Favorites.Count - 1 do
begin
@@ -5422,16 +5083,10 @@ begin
end;
end;
-procedure TMainForm.mnuShowFullClick(Sender: TObject);
-begin
- FullScreenForm.Calculate := False;
- FullScreenForm.Show;
-end;
-
procedure TMainForm.mnuImageSizeClick(Sender: TObject);
begin
AdjustForm.UpdateDisplay;
- AdjustForm.PageControl.TabIndex:=3;
+ AdjustForm.PageControl.TabIndex := 3;
AdjustForm.Show;
end;
@@ -5470,8 +5125,10 @@ begin
if ShowModal = mrOK then
begin
maincp.name := Title;
- SaveXMLFlame(maincp, maincp.name, Filename);
StatusBar.Panels[3].Text := maincp.name;
+
+ if SaveXMLFlame(maincp, maincp.name, Filename) and (FileName = OpenFile) then
+ AddFlameToList;
end;
end;
end;
@@ -5523,9 +5180,7 @@ end;
procedure TMainForm.ParseXML(var cp1: TControlPoint; const params: string; const ignoreErrors : boolean);
var
i: integer;
- h, s, v: real;
begin
- CurrentFlame := cp1.name;
nxform := 0;
FinalXformLoaded := false;
ActiveXformSet := 0;
@@ -5536,7 +5191,7 @@ begin
ParseCp.Free; // we're creating this CP from the scratch
ParseCp := TControlPoint.create; // to reset variables properly (randomize)
- XMLScanner.LoadFromBuffer(TCharType(TStringType(params)));
+ XMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(params)));
XMLScanner.Execute;
cp1.copy(ParseCp);
@@ -5548,13 +5203,7 @@ begin
{else
ShowMessage('Palette index too high')};
- if (cp1.hue_rotation > 0) and (cp1.hue_rotation < 1) then
- for i := 0 to 255 do
- begin
- RGBToHSV(cp1.cmap[i][0], cp1.cmap[i][1], cp1.cmap[i][2], h, s, v);
- h := Round(360 + h + (cp1.hue_rotation * 360)) mod 360;
- HSVToRGB(h, s, v, cp1.cmap[i][0], cp1.cmap[i][1], cp1.cmap[i][2]);
- end;
+ RotateCMapHue(cp1); // AV
end;
if FinalXformLoaded = false then begin
@@ -5582,25 +5231,23 @@ begin
if (flameXML <> '') then
begin
UpdateUndo;
- //ScriptEditor.Stopped := True;
- MainMenuClick(nil); // AV
+ // StopScripter;
StopThread;
- ParseXML(MainCP, PCHAR(flameXML), false);
+ ParseXML(MainCP, flameXML, false); // AV: fixed - was PChar instead String
AnnoyUser;
Transforms := MainCp.TrianglesFromCP(MainTriangles);
Statusbar.Panels[3].Text := MainCp.name;
if AutoSaveXML then // AV: saving loaded parameters in the current file
begin
- if XMLEntryExists(MainCp.name, OpenFile) then
+ while XMLEntryExists(MainCp.name, OpenFile) do
MainCp.name := MainCp.name + ' (new)'; // hmm...
if (OpenFile = AppPath + randfilename) then // random batch will be deleted
- SaveXMLFlame(MainCp, MainCp.name,
- IfThen(DirectoryExists(ExtractFilePath(AutoSavePath)), ExtractFilePath(AutoSavePath),
- AppPath) + 'Saved by ApophysisAV.flame'); // :)
+ SaveXMLFlame(MainCp, MainCp.name, IfThen(DirectoryExists(ExtractFilePath(AutoSavePath)),
+ ExtractFilePath(AutoSavePath), AppPath) + 'Saved by ApophysisAV.flame'); // :)
// AV: display these changes and scroll to the selected item
if SaveXMLFlame(MainCp, MainCp.name, OpenFile) then
- ListXML(OpenFile, 2, MainCp.name);
+ AddFlameToList; // AV: show the new item
end;
ResizeImage;
RedrawTimer.Enabled := True;
@@ -5621,7 +5268,7 @@ var
txt: string;
i: integer;
begin
- txt := Trim(FlameToXML(Maincp, false, false));
+ txt := Trim(FlameToXML(Maincp));
Clipboard.SetTextBuf(PChar(txt));
mnuPaste.enabled := true;
@@ -5632,7 +5279,7 @@ begin
MemCp.Clear;
for i := 0 to Maincp.NumXForms - 1 do //FIXME: skip final transform!
MemCp.xform[i].Assign(Maincp.xform[i]);
- EditForm.PasteTransform1.Enabled := True;
+ EditForm.PasteTransform.Enabled := True;
end;
function WinShellExecute(const Operation, AssociatedFile: string): Boolean;
@@ -5645,12 +5292,12 @@ begin
a1 := 'open';
r := ShellExecute(
- application.handle
- , pchar(a1)
- , pchar(AssociatedFile)
- , ''
- , ''
- , SW_SHOWNORMAL
+ application.handle,
+ pchar(a1),
+ pchar(AssociatedFile),
+ '',
+ '',
+ SW_SHOWNORMAL
);
if (r > 32) then WinShellExecute := true
else WinShellExecute := false;
@@ -5664,21 +5311,21 @@ end;
procedure TMainForm.mnuExportFlameClick(Sender: TObject);
var
FileList: Tstringlist;
- Ext, ex, Path: string;
+ Ext: string;
cp1: TControlPoint;
begin
if not FileExists(flam3Path) then
begin
- Application.MessageBox(PChar(TextByKey('main-status-noflam3')), 'Apophysis', 16);
+ Application.MessageBox(PChar(TextByKey('main-status-noflam3')), ApophysisSVN, 16);
exit;
end;
// AV: we really don't need to waste the memory and create it at startup
ExportDialog := TExportDialog.Create(Application); // AV
case ExportFileFormat of
- 1: Ext := 'jpg';
- 2: Ext := 'ppm';
- 3: Ext := 'png';
+ 1: Ext := '.jpg';
+ 2: Ext := '.ppm';
+ 3: Ext := '.png';
end;
FileList := TstringList.Create;
cp1 := TControlPoint.Create;
@@ -5689,44 +5336,49 @@ begin
ExportDialog.Filter_Radius := ExportFilter;
ExportDialog.Oversample := ExportOversample;
try
- ExportDialog.Filename := RenderPath + Maincp.name + '.' + Ext;
+ ExportDialog.Filename := RenderPath + Maincp.name + Ext;
if ExportDialog.ShowModal = mrOK then
begin
- ex := ExtractFileExt(ExportDialog.Filename);
- if ExtractFileExt(ExportDialog.Filename) = '.ppm' then
+ Ext := ExtractFileExt(ExportDialog.Filename);
+ if Ext = '.ppm' then
ExportFileFormat := 2
- else if ExtractFileExt(ExportDialog.Filename) = '.png' then
+ else if Ext = '.png' then
ExportFileFormat := 3
- else
+ else // if Ext = '.jpg' then
ExportFileFormat := 1;
+ Delete(Ext, 1, 1);
+ {
case ExportFileFormat of
1: Ext := 'jpg';
2: Ext := 'ppm';
3: Ext := 'png';
end;
+ }
+
ExportWidth := ExportDialog.ImageWidth;
ExportHeight := ExportDialog.ImageHeight;
ExportDensity := ExportDialog.Sample_density;
ExportFilter := ExportDialog.Filter_Radius;
ExportOversample := ExportDialog.Oversample;
- ExportBatches := ExportDialog.Batches;
ExportEstimator := ExportDialog.Estimator;
ExportEstimatorMin := ExportDialog.EstimatorMin;
ExportEstimatorCurve := ExportDialog.EstimatorCurve;
- ExportJitters := ExportDialog.Jitters;
ExportGammaTreshold := ExportDialog.GammaTreshold;
+ // AV: user cannot change the following, anyway
+ //ExportJitters := ExportDialog.Jitters;
+ //ExportBatches := ExportDialog.Batches;
cp1.sample_density := ExportDensity;
cp1.spatial_oversample := ExportOversample;
cp1.spatial_filter_radius := ExportFilter;
- cp1.nbatches := ExportBatches;
+ cp1.nbatches := 1; //ExportBatches;
+ cp1.jitters := 1; //ExportJitters;
if (cp1.width <> ExportWidth) or (cp1.Height <> ExportHeight) then
cp1.AdjustScale(ExportWidth, ExportHeight);
cp1.estimator := ExportEstimator;
cp1.estimator_min := ExportEstimatorMin;
cp1.estimator_curve := ExportEstimatorCurve;
- cp1.jitters := ExportJitters;
cp1.gamma_threshold := ExportGammaTreshold;
- FileList.Text := FlameToXML(cp1, true, false);
+ FileList.Text := FlameToXML(cp1, true);
FileList.SaveToFile(ChangeFileExt(ExportDialog.Filename, '.flame'));
FileList.Clear;
FileList.Add('@echo off');
@@ -5750,19 +5402,17 @@ begin
FileList.Add('@echo Rendering "' + ExportDialog.Filename + '"');
FileList.Add('"' + flam3Path + '" < "' + ChangeFileExt(ExportDialog.Filename, '.flame') + '"');
- Path := ExtractFilePath(ExtractFileDir(ExportDialog.Filename) + '\');
-
FileList.SaveToFile(ChangeFileExt(ExportDialog.Filename, '.bat'));
if ExportDialog.chkRender.Checked then
begin
- SetCurrentDir(Path);
+ SetCurrentDir(ExtractFilePath(ExportDialog.Filename));
WinShellOpen(ChangeFileExt(ExportDialog.Filename, '.bat'));
end;
end;
finally
FileList.Free;
cp1.free;
- ExportDialog.Free; // AV
+ ExportDialog.Free; // AV: destroying unnecessary form
end;
end;
@@ -5814,16 +5464,18 @@ end;
procedure TMainForm.ListXmlScannerStartTag(Sender: TObject;
TagName: string; Attributes: TAttrList);
begin
- pname := String(Attributes.value(TStringType('name')));
- ptime := String(Attributes.value(TStringType('time')));
- // pversion := String(Attributes.value(TStringType('version')));
+ if (TagName = 'flame') then begin // AV: fixed
+ pname := string(Attributes.value('name'));
+ ptime := string(Attributes.value('time'));
+ // pversion := string(Attributes.value('version'));
+ end;
end;
procedure TMainForm.XMLScannerStartTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
var
Tokens: TStringList;
- v: TStringType;
+ v: string; //TStringType;
ParsePos, i : integer;
begin
Tokens := TStringList.Create;
@@ -5831,8 +5483,8 @@ begin
if TagName='xformset' then // unused in this release...
begin
- v := Attributes.Value(TStringType('enabled'));
- if v <> '' then ParseCP.finalXformEnabled := (StrToInt(String(v)) <> 0)
+ v := string(Attributes.Value('enabled'));
+ if v <> '' then ParseCP.finalXformEnabled := (StrToInt(v) <> 0)
else ParseCP.finalXformEnabled := true;
inc(activeXformSet);
@@ -5841,110 +5493,110 @@ begin
begin
BeginParsing;
- v := Attributes.value(TStringType('version')); // AV
- if (pos('Apophysis 2.0', String(v)) > 0) or (v = '') then
+ v := string(Attributes.value('version')); // AV
+ if (pos('Apophysis 2.0', v) > 0) or (v = '') then
oldApo := true else oldApo := false;
- v := Attributes.value(TStringType('name'));
- if v <> '' then Parsecp.name := String(v) else Parsecp.name := 'untitled';
- v := Attributes.Value('time');
- if v <> '' then Parsecp.Time := StrToFloat(String(v));
- v := Attributes.value('palette');
+ v := string(Attributes.value('name'));
+ if v <> '' then Parsecp.name := v else Parsecp.name := 'untitled';
+ v := string(Attributes.Value('time'));
+ if v <> '' then Parsecp.Time := StrToFloat(v);
+ v := string(Attributes.value('palette'));
if v <> '' then
- Parsecp.cmapindex := StrToInt(String(v))
+ Parsecp.cmapindex := StrToInt(v)
else
Parsecp.cmapindex := -1;
- v := Attributes.value('gradient');
+ v := string(Attributes.value('gradient'));
if v <> '' then
- Parsecp.cmapindex := StrToInt(String(v))
+ Parsecp.cmapindex := StrToInt(v)
else
Parsecp.cmapindex := -1;
//ParseCP.hue_rotation := 1;
- v := Attributes.value('hue'); // AV: to animate the palette
+ v := string(Attributes.value('hue')); // AV: to animate the palette
if v <> '' then
- Parsecp.hue_rotation := StrToFloat(String(v))
+ Parsecp.hue_rotation := StrToFloat(v)
else
ParseCP.hue_rotation := 1;
- v := Attributes.Value('brightness');
- if v <> '' then Parsecp.Brightness := StrToFloat(String(v));
- v := Attributes.Value('gamma');
- if v <> '' then Parsecp.gamma := StrToFloat(String(v));
- v := Attributes.Value('contrast'); // AV
- if v <> '' then Parsecp.contrast := StrToFloat(String(v));
- v := Attributes.Value('vibrancy');
- if v <> '' then Parsecp.vibrancy := StrToFloat(String(v));
+ v := string(Attributes.Value('brightness'));
+ if v <> '' then Parsecp.Brightness := StrToFloat(v);
+ v := string(Attributes.Value('gamma'));
+ if v <> '' then Parsecp.gamma := StrToFloat(v);
+ v := string(Attributes.Value('contrast')); // AV
+ if v <> '' then Parsecp.contrast := StrToFloat(v);
+ v := string(Attributes.Value('vibrancy'));
+ if v <> '' then Parsecp.vibrancy := StrToFloat(v);
if (LimitVibrancy) and (Parsecp.vibrancy > 1) then Parsecp.vibrancy := 1;
- v := Attributes.Value('gamma_threshold');
- if v <> '' then Parsecp.gamma_threshold := StrToFloat(String(v))
+ v := string(Attributes.Value('gamma_threshold'));
+ if v <> '' then Parsecp.gamma_threshold := StrToFloat(v)
else Parsecp.gamma_threshold := 0;
- v := Attributes.Value('zoom');
- if v <> '' then Parsecp.zoom := StrToFloat(String(v));
- v := Attributes.Value('scale');
- if v <> '' then Parsecp.pixels_per_unit := StrToFloat(String(v));
- v := Attributes.Value('rotate');
- if v <> '' then Parsecp.FAngle := -PI * StrToFloat(String(v))/180;
- v := Attributes.Value('angle');
- if v <> '' then Parsecp.FAngle := StrToFloat(String(v));
+ v := string(Attributes.Value('zoom'));
+ if v <> '' then Parsecp.zoom := StrToFloat(v);
+ v := string(Attributes.Value('scale'));
+ if v <> '' then Parsecp.pixels_per_unit := StrToFloat(v);
+ v := string(Attributes.Value('rotate'));
+ if v <> '' then Parsecp.FAngle := -PI * StrToFloat(v)/180;
+ v := string(Attributes.Value('angle'));
+ if v <> '' then Parsecp.FAngle := StrToFloat(v);
// 3d
- v := Attributes.Value('cam_pitch');
- if v <> '' then Parsecp.cameraPitch := StrToFloat(String(v));
- v := Attributes.Value('cam_yaw');
- if v <> '' then Parsecp.cameraYaw := StrToFloat(String(v));
- v := Attributes.Value('cam_roll');
- if v <> '' then Parsecp.cameraRoll := StrToFloat(String(v));
- v := Attributes.Value('cam_dist');
- if v <> '' then Parsecp.cameraPersp := 1/StrToFloat(String(v));
- v := Attributes.Value('cam_perspective');
- if v <> '' then Parsecp.cameraPersp := StrToFloat(String(v));
- v := Attributes.Value('cam_zpos');
- if v <> '' then Parsecp.cameraZpos := StrToFloat(String(v));
- v := Attributes.Value('cam_dof');
- if v <> '' then Parsecp.cameraDOF := abs(StrToFloat(String(v)));
+ v := string(Attributes.Value('cam_pitch'));
+ if v <> '' then Parsecp.cameraPitch := StrToFloat(v);
+ v := string(Attributes.Value('cam_yaw'));
+ if v <> '' then Parsecp.cameraYaw := StrToFloat(v);
+ v := string(Attributes.Value('cam_roll'));
+ if v <> '' then Parsecp.cameraRoll := StrToFloat(v);
+ v := string(Attributes.Value('cam_dist'));
+ if v <> '' then Parsecp.cameraPersp := 1/StrToFloat(v);
+ v := string(Attributes.Value('cam_perspective'));
+ if v <> '' then Parsecp.cameraPersp := StrToFloat(v);
+ v := string(Attributes.Value('cam_zpos'));
+ if v <> '' then Parsecp.cameraZpos := StrToFloat(v);
+ v := string(Attributes.Value('cam_dof'));
+ if v <> '' then Parsecp.cameraDOF := abs(StrToFloat(v));
//density estimation
- v := Attributes.Value('estimator_radius');
- if v <> '' then Parsecp.estimator := StrToFloat(String(v));
- v := Attributes.Value('estimator_minimum');
- if v <> '' then Parsecp.estimator_min := StrToFloat(String(v));
- v := Attributes.Value('estimator_curve');
- if v <> '' then Parsecp.estimator_curve := StrToFloat(String(v));
- v := Attributes.Value('enable_de');
+ v := string(Attributes.Value('estimator_radius'));
+ if v <> '' then Parsecp.estimator := StrToFloat(v);
+ v := string(Attributes.Value('estimator_minimum'));
+ if v <> '' then Parsecp.estimator_min := StrToFloat(v);
+ v := string(Attributes.Value('estimator_curve'));
+ if v <> '' then Parsecp.estimator_curve := StrToFloat(v);
+ v := string(Attributes.Value('enable_de'));
if (v = '1') then Parsecp.enable_de := true;
- v := Attributes.Value('new_linear');
+ v := string(Attributes.Value('new_linear'));
if (v = '1') then // AV
Parsecp.noLinearFix := true
else ParseCp.noLinearFix := false;
- v := Attributes.Value('curves');
+ v := string(Attributes.Value('curves'));
if (v <> '') then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
ParsePos := -1;
for i := 0 to 3 do
begin
- Inc(ParsePos);ParseCp.curvePoints[i][0].x := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][0].y := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curveWeights[i][0] := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][1].x := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][1].y := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curveWeights[i][1] := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][2].x := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][2].y := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curveWeights[i][2] := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][3].x := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curvePoints[i][3].y := StrToFloat(Tokens[ParsePos]);
- Inc(ParsePos);ParseCp.curveWeights[i][3] := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][0].x := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][0].y := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curveWeights[i][0] := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][1].x := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][1].y := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curveWeights[i][1] := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][2].x := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][2].y := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curveWeights[i][2] := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][3].x := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curvePoints[i][3].y := StrToFloat(Tokens[ParsePos]);
+ Inc(ParsePos); ParseCp.curveWeights[i][3] := StrToFloat(Tokens[ParsePos]);
end;
end;
try
- v := Attributes.Value('center');
- GetTokens(String(v), tokens);
+ v := string(Attributes.Value('center'));
+ GetTokens(v, tokens);
Parsecp.center[0] := StrToFloat(Tokens[0]);
Parsecp.center[1] := StrToFloat(Tokens[1]);
@@ -5953,15 +5605,15 @@ begin
Parsecp.center[1] := 0;
end;
- v := Attributes.Value('size');
- GetTokens(String(v), tokens);
+ v := string(Attributes.Value('size'));
+ GetTokens(v, tokens);
Parsecp.width := StrToInt(Tokens[0]);
Parsecp.height := StrToInt(Tokens[1]);
try
- v := Attributes.Value('background');
- GetTokens(String(v), tokens);
+ v := string(Attributes.Value('background'));
+ GetTokens(v, tokens);
Parsecp.background[0] := Floor(StrToFloat(Tokens[0]) * 255);
Parsecp.background[1] := Floor(StrToFloat(Tokens[1]) * 255);
@@ -5972,11 +5624,11 @@ begin
Parsecp.background[2] := 0;
end;
- v := Attributes.Value('soloxform');
- if v <> '' then Parsecp.soloXform := StrToInt(String(v));
+ v := string(Attributes.Value('soloxform'));
+ if v <> '' then Parsecp.soloXform := StrToInt(v);
- v := Attributes.Value('plugins');
- GetTokens(String(v), tokens);
+ v := string(Attributes.Value('plugins'));
+ GetTokens(v, tokens);
if (tokens.Count > 0) then begin
ParseCP.used_plugins.Clear;
@@ -5985,23 +5637,38 @@ begin
end;
(* // AV: commented out since it's useless
v := Attributes.Value('nick');
- if Trim(String(v)) = '' then v := TStringType(SheepNick);
- Parsecp.Nick := String(v);
+ if Trim(v) = '' then v := SheepNick;
+ Parsecp.Nick := v;
v := Attributes.Value('url');
- if Trim(String(v)) = '' then v := TStringType(SheepUrl);
- Parsecp.URL := String(v);
+ if Trim(v) = '' then v := SheepUrl;
+ Parsecp.URL := v;
*)
end
else if TagName='palette' then
begin
- XMLPaletteFormat := String(Attributes.Value('format'));
- XMLPaletteCount := StrToIntDef(String(Attributes.Value('count')), 256);
+ XMLPaletteFormat := string(Attributes.Value('format'));
+ XMLPaletteCount := StrToIntDef(string(Attributes.Value('count')), 256);
end;
finally
Tokens.free;
end;
end;
+function GetComment(str: string): string;
+{ AV: Extracts comment from XML-file }
+begin
+ try
+ Result := Trim(Copy(str, 5, Length(str) - 7));
+ except
+ Result := '';
+ end;
+end;
+
+procedure TMainForm.XmlScannerComment(Sender: TObject; Comment: string);
+begin
+ ParseCP.comment := GetComment(Comment);
+end;
+
function flatten_val(Attributes: TAttrList): double;
var
vv: array of double;
@@ -6024,7 +5691,7 @@ begin
d := false;
for i := 0 to High(vn) do
begin
- s := String(Attributes.Value(TStringType(vn[i])));
+ s := string(Attributes.Value(Utf8String(vn[i])));
if (s <> '') then vv[i] := StrToFloat(s)
else vv[i] := 0;
d := d or (vv[i] <> 0);
@@ -6044,15 +5711,15 @@ var
vn: array of string;
i: integer;
s: string;
-begin
+begin
SetLength(vv, 2);
vn := ['linear3D', 'linear'];
-
+
Result := 0;
-
+
for i := 0 to 1 do
begin
- s := String(Attributes.Value(TStringType(vn[i])));
+ s := string(Attributes.Value(Utf8String(vn[i])));
if (s <> '') then vv[i] := StrToFloat(s)
else vv[i] := 0;
Result := Result + vv[i];
@@ -6063,14 +5730,11 @@ begin
end;
procedure TMainForm.XmlScannerContent(Sender: TObject; Content: String);
-var i: byte;
- h, s, v, hue: real;
begin
- if XMLPaletteCount <= 0 then begin
+ if XMLPaletteCount <= 0 then
//ShowMessage('ERROR: No colors in palette!');
- Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR);
- exit;
- end;
+ raise Exception.Create(TextByKey('common-invalidformat') + ': palette'); // AV
+
if XMLPaletteFormat = 'RGB' then
begin
ParseCompactColors(ParseCP, XMLPaletteCount, Content, false);
@@ -6079,21 +5743,13 @@ begin
begin
ParseCompactColors(ParseCP, XMLPaletteCount, Content);
end
- else begin
- Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR);
- exit;
- end;
+ else
+ raise Exception.Create(TextByKey('common-invalidformat') + ': palette'); // AV
+
Parsecp.cmapindex := -1;
// AV: restored hue rotation support, useful for animation
- hue := Parsecp.hue_rotation;
- if (hue < 1) and (hue > 0) then
- for i := 0 to 255 do
- begin
- RGBToHSV(Parsecp.cmap[i][0], Parsecp.cmap[i][1], Parsecp.cmap[i][2], h, s, v);
- h := Round(360 + h + (hue * 360)) mod 360;
- HSVToRGB(h, s, v, Parsecp.cmap[i][0], Parsecp.cmap[i][1], Parsecp.cmap[i][2]);
- end;
+ RotateCMapHue(Parsecp);
XMLPaletteFormat := '';
XMLPaletteCount := 0;
@@ -6103,7 +5759,7 @@ procedure TMainForm.XMLScannerEmptyTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
var
i, j, k, vindex: integer; // j, k - AV
- v, l, s: TStringType;
+ v, l, s: string; //TStringType;
d, floatcolor, vl, n: double;
Tokens: TStringList;
begin
@@ -6111,34 +5767,35 @@ begin
Tokens := TStringList.Create;
try
if (TagName = 'xform') or (TagName = 'finalxform') then
- if {(TagName = 'finalxform') and} (FinalXformLoaded) then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR)
+ if {(TagName = 'finalxform') and} (FinalXformLoaded) then
+ Application.MessageBox(PChar(TextByKey('common-invalidformat')), ApophysisSVN, MB_ICONERROR)
+ // ShowMessage('ERROR: No xforms allowed after FinalXform!')
else
- begin
+ begin // AV
for i := 0 to Attributes.Count - 1 do begin
- if not ScanVariations(String(attributes.Name(i))) and
- not ScanVariables(String(attributes.Name(i))) then
- CheckAttribute(String(Attributes.Name(i)));
+ if not ScanVariations(string(attributes.Name(i))) and
+ not ScanVariables(string(attributes.Name(i))) then
+ CheckAttribute(string(Attributes.Name(i)));
end;
if (TagName = 'finalxform') or (activeXformSet > 0) then FinalXformLoaded := true;
with ParseCP.xform[nXform] do begin
Clear;
- v := Attributes.Value('weight');
- if (v <> '') and (TagName = 'xform') then density := StrToFloat(String(v));
+ v := string(Attributes.Value('weight'));
+ if (v <> '') and (TagName = 'xform') then density := StrToFloat(v);
if (TagName = 'finalxform') then
begin
- v := Attributes.Value('enabled');
- if v <> '' then ParseCP.finalXformEnabled := (StrToInt(String(v)) <> 0)
+ v := string(Attributes.Value('enabled'));
+ if v <> '' then ParseCP.finalXformEnabled := (StrToInt(v) <> 0)
else ParseCP.finalXformEnabled := true;
end;
if activexformset > 0 then density := 0; // tmp...
- ///////////// AV: checking variation order ////////////////////
- // TODO: optimize!
- v := Attributes.Value('var_order');
+ //**************** AV: checking variation order ***********//
+ v := string(Attributes.Value('var_order'));
if v <> '' then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
k := -1;
for j := 0 to Tokens.Count-1 do
begin
@@ -6150,28 +5807,34 @@ begin
end;
end;
end;
- //////////////////////////////////////////////////////////////
+ //************************************************************//
- v := Attributes.Value('color');
- if v <> '' then color := StrToFloat(String(v));
- v := Attributes.Value('var_color');
- if v <> '' then pluginColor := StrToFloat(String(v));
- v := Attributes.Value('symmetry');
- if v <> '' then symmetry := StrToFloat(String(v));
- v := Attributes.Value('coefs');
- GetTokens(String(v), tokens);
- if Tokens.Count < 6 then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR);
+ v := string(Attributes.Value('color'));
+ if v <> '' then color := StrToFloat(v);
+ v := string(Attributes.Value('var_color'));
+ if v <> '' then pluginColor := StrToFloat(v);
+ v := string(Attributes.Value('symmetry'));
+ if v <> '' then symmetry := StrToFloat(v);
+ v := string(Attributes.Value('coefs'));
+ if v <> '' then begin
+ GetTokens(v, tokens);
+ if Tokens.Count < 6 then
+ Application.MessageBox(PChar(TextByKey('common-invalidformat') + ': coefs'),
+ ApophysisSVN, MB_ICONERROR);
c[0][0] := StrToFloat(Tokens[0]);
c[0][1] := StrToFloat(Tokens[1]);
c[1][0] := StrToFloat(Tokens[2]);
c[1][1] := StrToFloat(Tokens[3]);
c[2][0] := StrToFloat(Tokens[4]);
c[2][1] := StrToFloat(Tokens[5]);
+ end;
- v := Attributes.Value('post');
+ v := string(Attributes.Value('post'));
if v <> '' then begin
- GetTokens(String(v), tokens);
- if Tokens.Count < 6 then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR);
+ GetTokens(v, tokens);
+ if Tokens.Count < 6 then
+ Application.MessageBox(PChar(TextByKey('common-invalidformat') + ': post'),
+ ApophysisSVN, MB_ICONERROR);
p[0][0] := StrToFloat(Tokens[0]);
p[0][1] := StrToFloat(Tokens[1]);
p[1][0] := StrToFloat(Tokens[2]);
@@ -6180,31 +5843,31 @@ begin
p[2][1] := StrToFloat(Tokens[5]);
end;
- v := Attributes.Value('chaos');
+ v := string(Attributes.Value('chaos'));
if v <> '' then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
for i := 0 to Tokens.Count-1 do
modWeights[i] := Abs(StrToFloat(Tokens[i]));
end;
//else for i := 0 to NXFORMS-1 do modWeights[i] := 1;
// for 2.09 flames compatibility
- v := Attributes.Value('opacity');
+ v := string(Attributes.Value('opacity'));
if v <> '' then begin
- if StrToFloat(String(v)) = 0.0 then begin
+ if StrToFloat(v) = 0.0 then begin
transOpacity := 0;
end else begin
- transOpacity := StrToFloat(String(v));
+ transOpacity := StrToFloat(v);
end;
end;
// 7x.9 name tag
- v := Attributes.Value('name');
+ v := string(Attributes.Value('name'));
if v <> '' then begin
- TransformName := String(v);
+ TransformName := v;
end;
- v := Attributes.Value('plotmode');
+ v := string(Attributes.Value('plotmode'));
if v <> '' then begin
if v = 'off' then begin
transOpacity := 0;
@@ -6215,11 +5878,11 @@ begin
if ParseCp.noLinearFix then
for i := 0 to 1 do
begin
- SetVariation(i, 0);
- v := TStringType(ReadWithSubst(Attributes, varnames(i)));
- //v := Attributes.Value(AnsiString(varnames(i)));
+ v := ReadWithSubst(Attributes, varnames(i));
if v <> '' then
- SetVariation(i, StrToFloat(String(v)));
+ SetVariation(i, StrToFloat(v))
+ else
+ SetVariation(i, 0);
end
else begin
SetVariation(0, linear_val(Attributes));
@@ -6230,40 +5893,40 @@ begin
// now parse the rest of the variations...as usual
for i := 2 to NRVAR - 1 do
begin
- SetVariation(i, 0);
- v := TStringType(ReadWithSubst(Attributes, varnames(i)));
- //v := Attributes.Value(AnsiString(varnames(i)));
+ v := ReadWithSubst(Attributes, varnames(i));
if v <> '' then
- SetVariation(i, StrToFloat(String(v)));
+ SetVariation(i, StrToFloat(v))
+ else
+ SetVariation(i, 0);
end;
// and the variables
for i := 0 to GetNrVariableNames - 1 do begin
- v := TStringType(ReadWithSubst(Attributes, GetVariableNameAt(i)));
- //v := Attributes.Value(AnsiString(GetVariableNameAt(i)));
+ s := GetVariableNameAt(i);
+ v := ReadWithSubst(Attributes, s);
if v <> '' then begin
{$ifndef VAR_STR}
- d := StrToFloat(String(v));
- SetVariable(GetVariableNameAt(i), d);
+ d := StrToFloat(v);
+ SetVariable(s, d);
{$else}
- SetVariableStr(GetVariableNameAt(i), String(v));
+ SetVariableStr(s, v);
{$endif}
end;
end;
-
+
{***** AV: tryig to convert old Apo 2.0x variations into new ones *****}
if oldApo then begin
// AV: 'perspective' into 'projective'
- v := Attributes.Value('perspective');
- s := Attributes.Value('projective');
+ v := string(Attributes.Value('perspective'));
+ s := string(Attributes.Value('projective'));
if (v <> '') and (s = '') then // avoid to overwrite
begin
- d := StrToFloat(String(v));
+ d := StrToFloat(v);
SetVariation(GetVariationIndex('projective'), d);
- v := Attributes.Value('perspective_dist');
- l := Attributes.Value('perspective_angle');
- vl := StrToFloat(String(v)); // dist
- d := StrToFloat(String(l)); // angle
+ v := string(Attributes.Value('perspective_dist'));
+ l := string(Attributes.Value('perspective_angle'));
+ vl := StrToFloat(v); // dist
+ d := StrToFloat(l); // angle
n := 0;
SetVariable('pr_A', n);
SetVariable('pr_B1', n);
@@ -6280,17 +5943,17 @@ begin
SetVariable('projective_mode', n);
end
else if (v <> '') and (s <> '') then
- begin
+ begin
MissingPlugin.MissingPluginList.Add('perspective');
- MissingPlugin.MissingPluginList.Add('perspective_angle');
- MissingPlugin.MissingPluginList.Add('perspective_dist');
- end;
+ MissingPlugin.MissingPluginList.Add('perspective_angle');
+ MissingPlugin.MissingPluginList.Add('perspective_dist');
+ end;
- v := Attributes.Value('rings');
- s := Attributes.Value('rings2');
+ v := string(Attributes.Value('rings'));
+ s := string(Attributes.Value('rings2'));
if (v <> '') and (s = '') then
begin
- d := StrToFloat(String(v));
+ d := StrToFloat(v);
SetVariation(GetVariationIndex('rings2'), d);
n := c[2][0];
SetVariable('rings2_val', n);
@@ -6300,11 +5963,11 @@ begin
else if (v <> '') and (s <> '') then
MissingPlugin.MissingPluginList.Add('rings');
- v := Attributes.Value('fan');
- s := Attributes.Value('fan2');
+ v := string(Attributes.Value('fan'));
+ s := string(Attributes.Value('fan2'));
if (v <> '') and (s = '') then
begin
- d := StrToFloat(String(v));
+ d := StrToFloat(v);
SetVariation(GetVariationIndex('fan2'), d);
n := c[2][0];
SetVariable('fan2_x', n);
@@ -6316,13 +5979,13 @@ begin
else if (v <> '') and (s <> '') then
MissingPlugin.MissingPluginList.Add('fan');
- v := Attributes.Value('bent');
+ v := string(Attributes.Value('bent'));
if (v <> '') then
begin
- s := Attributes.Value('bent2');
+ s := string(Attributes.Value('bent2'));
if (s = '') then
begin
- d := StrToFloat(String(v));
+ d := StrToFloat(v);
SetVariation(GetVariationIndex('bent2'), d);
n := 2;
SetVariable('bent2_x', n);
@@ -6334,11 +5997,11 @@ begin
else MissingPlugin.MissingPluginList.Add('bent');
end;
- v := Attributes.Value('waves');
- s := Attributes.Value('waves2');
+ v := string(Attributes.Value('waves'));
+ s := string(Attributes.Value('waves2'));
if (v <> '') and (s = '') then
begin
- d := StrToFloat(String(v));
+ d := StrToFloat(v);
SetVariation(GetVariationIndex('waves2'), d);
n := c[1][0];
SetVariable('waves2_scalex', n);
@@ -6355,13 +6018,13 @@ begin
else if (v <> '') and (s <> '') then
MissingPlugin.MissingPluginList.Add('waves');
- v := Attributes.Value('popcorn');
+ v := string(Attributes.Value('popcorn'));
if (v <> '') then
begin
- s := Attributes.Value('popcorn2');
+ s := string(Attributes.Value('popcorn2'));
if (s = '') then
begin
- d := StrToFloat(String(v));
+ d := StrToFloat(v);
SetVariation(GetVariationIndex('popcorn2'), d);
n := c[2][0];
SetVariable('popcorn2_x', n);
@@ -6374,106 +6037,112 @@ begin
end;
end; // oldApo
- // AV: Droste into Escher
- v := Attributes.Value('droste');
- s := Attributes.Value('escher');
- if (v <> '') and (s = '') then
- begin
- d := StrToFloat(String(v));
- SetVariation(GetVariationIndex('escher'), d);
- v := Attributes.Value('droste_r1');
- l := Attributes.Value('droste_r2');
- try
- vl := StrToFloat(String(v)); // r1
- d := StrToFloat(String(l)); // r2
- if (vl <> d) then
- n := 2 * arctan(ln(d / vl) / 2 / pi)
- else n := 0;
- SetVariable('escher_beta', n);
- except
- n := 0;
- SetVariable('escher_beta', n);
- end;
- end
- else if (v <> '') and (s <> '') then
- begin
- MissingPlugin.MissingPluginList.Add('droste');
- MissingPlugin.MissingPluginList.Add('droste_r1');
- MissingPlugin.MissingPluginList.Add('droste_r2');
- end;
-
- // Spherical3D into inversion3D
- v := Attributes.Value('Spherical3D');
- if (v <> '') and (GetVariationIndex('Spherical3D')< 0) then
- // if plugin is NOT available
- begin
- s := Attributes.Value('inversion3D');
- if (s = '') then
+ // AV: Droste into Escher
+ v := string(Attributes.Value('droste'));
+ s := string(Attributes.Value('escher'));
+ if (v <> '') and (s = '') then
begin
- d := StrToFloat(String(v));
- SetVariation(GetVariationIndex('inversion3D'), d);
- n := 1;
- SetVariable('inversion3D_radius', n);
- n := 0;
- SetVariable('inversion3D_x0', n);
- SetVariable('inversion3D_y0', n);
- SetVariable('inversion3D_z0', n);
+ d := StrToFloat(v);
+ SetVariation(GetVariationIndex('escher'), d);
+ v := string(Attributes.Value('droste_r1'));
+ l := string(Attributes.Value('droste_r2'));
+ try
+ vl := StrToFloat(v); // r1
+ d := StrToFloat(l); // r2
+ if (vl <> d) then
+ n := 2 * arctan(ln(d / vl) / 2 / pi)
+ else n := 0;
+ SetVariable('escher_beta', n);
+ except
+ n := 0;
+ SetVariable('escher_beta', n);
+ end;
end
- else MissingPlugin.MissingPluginList.Add('Spherical3D');
- end;
-
- // secant into secant2
- v := Attributes.Value('secant');
- if (v <> '') and (GetVariationIndex('secant') < 0) then
- // if plugin is NOT available
- begin
- s := Attributes.Value('secant2');
- if (s = '') then
+ else if (v <> '') and (s <> '') then
begin
- d := StrToFloat(String(v));
- SetVariation(GetVariationIndex('secant2'), d);
- n := 1;
- SetVariable('secant2_old', n);
- end
- else MissingPlugin.MissingPluginList.Add('secant');
- end;
+ MissingPlugin.MissingPluginList.Add('droste');
+ MissingPlugin.MissingPluginList.Add('droste_r1');
+ MissingPlugin.MissingPluginList.Add('droste_r2');
+ end;
- // arch into Z_arch
- v := Attributes.Value('arch');
- if (v <> '') then
- begin
- s := Attributes.Value('Z_arch');
- if (s = '') then
+ // Spherical3D into inversion3D
+ v := string(Attributes.Value('Spherical3D'));
+ if (v <> '') and (GetVariationIndex('Spherical3D')< 0) then
+ // if plugin is NOT available
begin
- d := StrToFloat(String(v));
- SetVariation(GetVariationIndex('Z_arch'), d);
- SetVariable('Z_arch_weight', d);
- end
- else MissingPlugin.MissingPluginList.Add('arch');
- end;
+ s := string(Attributes.Value('inversion3D'));
+ if (s = '') then
+ begin
+ d := StrToFloat(v);
+ SetVariation(GetVariationIndex('inversion3D'), d);
+ n := 1;
+ SetVariable('inversion3D_radius', n);
+ n := 0;
+ SetVariable('inversion3D_x0', n);
+ SetVariable('inversion3D_y0', n);
+ SetVariable('inversion3D_z0', n);
+ end
+ else MissingPlugin.MissingPluginList.Add('Spherical3D');
+ end;
- {*****************************************************************************}
+ // secant into secant2
+ v := string(Attributes.Value('secant'));
+ if (v <> '') and (GetVariationIndex('secant') < 0) then
+ // if plugin is NOT available
+ begin
+ s := string(Attributes.Value('secant2'));
+ if (s = '') then
+ begin
+ d := StrToFloat(v);
+ SetVariation(GetVariationIndex('secant2'), d);
+ n := 1;
+ SetVariable('secant2_old', n);
+ end
+ else MissingPlugin.MissingPluginList.Add('secant');
+ end;
+
+ // arch into Z_arch
+ v := string(Attributes.Value('arch'));
+ if (v <> '') then
+ begin
+ s := string(Attributes.Value('Z_arch'));
+ if (s = '') then
+ begin
+ d := StrToFloat(v);
+ SetVariation(GetVariationIndex('Z_arch'), d);
+ SetVariable('Z_arch_weight', d);
+ end
+ else MissingPlugin.MissingPluginList.Add('arch');
+ end;
+
+ {********************************************************}
// legacy variation/variable notation
- v := Attributes.Value('var1');
+ v := string(Attributes.Value('var1'));
if v <> '' then
begin
for i := 0 to NRVAR - 1 do
SetVariation(i, 0);
- SetVariation(StrToInt(String(v)), 1);
+ SetVariation(StrToInt(v), 1);
end;
- v := Attributes.Value('var');
+ v := string(Attributes.Value('var'));
if v <> '' then
begin
for i := 0 to NRVAR - 1 do
SetVariation(i, 0);
- GetTokens(String(v), tokens);
- if Tokens.Count > NRVAR then Application.MessageBox(PChar(TextByKey('common-invalidformat')), 'Apophysis', MB_ICONERROR);
+ GetTokens(v, tokens);
+ if Tokens.Count > NRVAR then
+ Application.MessageBox(PChar(TextByKey('common-invalidformat')),
+ ApophysisSVN, MB_ICONERROR);
for i := 0 to Tokens.Count - 1 do
SetVariation(i, StrToFloat(Tokens[i]));
end;
end;
- Inc(nXform);
+ // AV: prevent crash with flames containing over 100 xforms
+ {$ifndef T500}
+ if nXform < NXFORMS then
+ {$endif}
+ Inc(nXform);
end;
if TagName = 'color' then
begin
@@ -6481,9 +6150,9 @@ begin
//if Parsecp.cmapindex = -2 then
Parsecp.cmapindex := -1;
- i := StrToInt(String(Attributes.value('index')));
- v := Attributes.value('rgb');
- GetTokens(String(v), tokens);
+ i := StrToInt(string(Attributes.value('index')));
+ v := string(Attributes.value('rgb'));
+ GetTokens(v, tokens);
floatcolor := StrToFloat(Tokens[0]);
Parsecp.cmap[i][0] := round(floatcolor);
floatcolor := StrToFloat(Tokens[1]);
@@ -6493,19 +6162,21 @@ begin
end;
if TagName = 'colors' then
begin
- ParseCompactcolors(Parsecp, StrToInt(String(Attributes.value('count'))),
- String(Attributes.value('data')));
+ ParseCompactcolors(Parsecp, StrToInt(string(Attributes.value('count'))),
+ string(Attributes.value('data')));
Parsecp.cmapindex := -1;
end;
if TagName = 'symmetry' then
begin
- i := StrToInt(String(Attributes.value('kind')));
+ i := StrToInt(string(Attributes.value('kind')));
Parsecp.symmetry := i;
end;
+ {
if TagName = 'xdata' then
begin
- Parsecp.xdata := Parsecp.xdata + String(Attributes.value('content'));
+ Parsecp.xdata := Parsecp.xdata + string(Attributes.value('content'));
end;
+ }
finally
Tokens.free;
end;
@@ -6648,7 +6319,7 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
procedure TMainForm.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
const
snap_angle = 0.261799387799149; // AV: the same as 15*pi/180;
@@ -6784,7 +6455,7 @@ begin
Result.Bottom := r.Bottom * scale;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
procedure TMainForm.ImageMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
@@ -6889,7 +6560,7 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
procedure TMainForm.DrawImageView;
var
i, j: integer;
@@ -6991,7 +6662,7 @@ begin
bm.Free;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
(*
procedure TMainForm.DrawPitchYawLines(YawAngle: double; PitchAngle: double);
var
@@ -7066,7 +6737,7 @@ begin
bkuPen.Free;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
procedure TMainForm.DrawZoomWindow;
const
cornerSize = 32;
@@ -7143,42 +6814,43 @@ begin
bkuPen.Free;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
procedure TMainForm.tbzoomwindowClick(Sender: TObject);
begin
FMouseMoveState := msZoomWindow;
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TMainForm.tbzoomoutwindowClick(Sender: TObject);
begin
FMouseMoveState := msZoomOutWindow;
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TMainForm.tbDragClick(Sender: TObject);
begin
FMouseMoveState := msDrag;
end;
-///////////////////////////////////////////////////////////////////////////////
procedure TMainForm.tbRotateClick(Sender: TObject);
begin
FMouseMoveState := msRotate;
end;
-///////////////////////////////////////////////////////////////////////////////
+//***************************************************************************//
procedure TMainForm.FillVariantMenu;
var
- i: integer;
+ i, j: smallint;
s: string;
NewMenuItem : TMenuItem;
+ svars: TStringList;
begin
SetLength(VarMenus, NrVar);
// AV: to prevent underlined letters with GUI themes
mnuBuiltinVars.AutoHotkeys := maManual;
mnuPluginVars.AutoHotkeys := maManual;
+ svars := TStringList.Create;
+ svars.Sorted := True;
+
for i := 0 to NRVAR - 1 do begin
NewMenuItem := TMenuItem.Create(self);
s := varnames(i);
@@ -7189,62 +6861,94 @@ begin
NewMenuItem.Tag := i;
NewMenuItem.GroupIndex := 2;
NewMenuItem.RadioItem := True;
- // AV: exotic GUI styles not always work well :-/
- if TStyleManager.ActiveStyle.Name <> 'Windows' then
- if (i mod 30 = 0) then NewMenuItem.Break := mbBreak;
VarMenus[i] := NewMenuItem;
- if i < NumBuiltinVars then
- mnuBuiltinVars.Add(NewMenuItem)
- else
+ if i < NumBuiltinVars then begin // AV: creating sorted menu
+ j := svars.Add(NewMenuItem.Caption); // AV: remember the position...
+ mnuBuiltinVars.Insert(j, NewMenuItem); // ...and put it at the right place
+ end
+ else // AV: plugin variations are already sorted
mnuPluginVars.Add(NewMenuItem);
end;
+
+ svars.Free;
+
+ // AV: exotic GUI styles not always work well :-/
+ if TStyleManager.ActiveStyle.Name <> 'Windows' then
+ begin
+ i := 0;
+ while i < mnuBuiltinVars.Count do
+ begin
+ mnuBuiltinVars[i].Break := mbBreak;
+ inc(i, mbHeight);
+ end;
+ i := 0;
+ while i < mnuPluginVars.Count do
+ begin
+ mnuPluginVars[i].Break := mbBreak;
+ inc(i, mbHeight);
+ end;
+ end;
end;
-///////////////////////////////////////////////////////////////////////////////
-
procedure TMainForm.VariantMenuClick(Sender: TObject);
-var i: integer;
begin
TMenuItem(Sender).Checked := True;
// AV: only one variation type can be active,
// but Apo allows to check up to 3 menu items, confusing users...
- mnuVRandom.Checked := False;
+ if Variation > vRandom then
+ VarMenus[Variation].Checked := False
+ else
+ mnuVRandom.Checked := False;
if (TMenuItem(Sender).Tag >= NumBuiltinVars) then
begin
- for i := 0 to NumBuiltinVars-1 do
- VarMenus[i].Checked := False; // AV
mnuBuiltinVars.Checked := False;
mnuPluginVars.Checked := True;
end
else begin
- for i := NumBuiltinVars to NrVar - 1 do
- VarMenus[i].Checked := False; // AV
mnuBuiltinVars.Checked := True;
mnuPluginVars.Checked := False;
end;
UpdateUndo;
- Variation := TVariation(TMenuItem(Sender).Tag); // ?
+ // AV: changed Variation to integer - no more ugly type-casting here!
+ Variation := TMenuItem(Sender).Tag;
SetVariation(maincp);
ResetLocation;
RedrawTimer.Enabled := True;
UpdateWindows;
end;
+{ /////////////////////////////////////////////////////////////////////////// }
-////////// AV: Apo UI Appearance /////////////////////
+// AV: make it a separate method to be able to call it later
+procedure TMainForm.SetAutoSaveTimer;
+var mins: shortint;
+begin
+ if (AutoSaveFreq = 0) then mins := 1
+ else if (AutoSaveFreq = 1) then mins := 2
+ else if (AutoSaveFreq = 2) then mins := 5
+ else if (AutoSaveFreq = 3) then mins := 10
+ else begin
+ mins := 5;
+ AutoSaveFreq := 2;
+ AutoSaveEnabled := false;
+ end;
+
+ AutoSaveTimer.Interval := 60 * 1000 * mins;
+ AutoSaveTimer.Enabled := AutoSaveEnabled;
+end;
+
+// AV: Apo UI Appearance /////////////////////////////
procedure TMainForm.CreateStyleList;
-var i: integer;
+var i: smallint;
s: string;
apostyle : TMenuItem;
- sm: TStyleManager;
begin
- sm := TStyleManager.Create;
- for i := 0 to Length(sm.StyleNames)-1 do
+ for i := 0 to Length(TStyleManager.StyleNames)-1 do
begin
apostyle := TMenuItem.Create(mnuApoStyle);
- s := sm.StyleNames[i];
+ s := TStyleManager.StyleNames[i];
apostyle.Caption := s;
- if (sm.ActiveStyle.Name = s) then
+ if (TStyleManager.ActiveStyle.Name = s) then
apostyle.Checked := True;
apostyle.Name := 'style' + IntToStr(i);
apostyle.RadioItem := True;
@@ -7253,7 +6957,6 @@ begin
apostyle.OnClick := StyleItemClick;
mnuApoStyle.Add(apostyle);
end;
- sm.Free;
end;
procedure TMainForm.ShowStyledWindows(Sender: TObject);
@@ -7272,10 +6975,10 @@ begin
if not TMenuItem(Sender).Checked then
begin
TMenuItem(Sender).Checked := True;
- newGUI := TStyleManager.StyleNames[TMenuItem(Sender).Tag];
+ newGUI := TMenuItem(Sender).Caption;
try
- StopThread;
+ StopThread; // ?
self.OnShow := ShowStyledWindows;
if EditForm.Visible then EditForm.Close;
@@ -7286,8 +6989,8 @@ begin
TStyleManager.TrySetStyle(newGUI, false);
except on EAccessViolation do // hmmm...
- Application.MessageBox(PChar(TextByKey('options-restartnotice')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ MessageBox(0, PChar(TextByKey('options-restartnotice')),
+ ApophysisSVN, MB_ICONWARNING);
end;
Registry := TRegistry.Create;
@@ -7301,12 +7004,13 @@ begin
end;
end;
end;
+
//--Z--////////////////////////////////////////////////////////////////////////
procedure TMainForm.tbQualityBoxKeyPress(Sender: TObject; var Key: Char);
begin
- if (Key = ',') then Key := '.'; // AV
- if not CharinSet(Key,['0'..'9', #8, #13, #27, '.']) then Key := #0; // AV
+ if (Key = ',') then Key := '.'; // AV
+ if not CharinSet(Key,['0'..'9', #8, #13, #27, '.']) then Key := #0; // AV
if key = #13 then
begin
tbQualityBoxSet(Sender);
@@ -7385,112 +7089,7 @@ begin
end;
end;
-{
-procedure TMainForm.ListViewChanging(Sender: TObject; Item: TListItem;
- Change: TItemChange; var AllowChange: Boolean);
-var sc, fc: string;
-begin
- if (Item = nil) or (Sender <> ListView1) then exit;
-
- sc := ''; fc := '';
- if (ListView1.Selected <> nil) then sc := ListView1.Selected.Caption;
- if (ListView1.ItemFocused <> nil) then fc := ListView1.ItemFocused.Caption;
-
- if (Trim(Item.Caption) = Trim(maincp.name)) and (Item.Selected) and
- (Item.Selected) and (Change = ctState) then
- begin
- if (DoNotAskAboutChange = true) then
- begin
- exit;
- end;
- if (UndoIndex <> 0) then
- begin
- // hack
- if (LastCaptionSel = sc) and (LastCaptionFoc = fc) then begin
- AllowChange := LastDecision;
- if Not AllowChange then begin
- ListView1.OnChange := nil;
- ListView1.OnChanging := nil;
- ListView1.Selected := Item;
- ListView1.ItemFocused := Item;
- ListView1.OnChanging := ListViewChanging;
- ListView1.OnChange := ListViewChange;
- end;
- Exit;
- end;
-
- LastCaptionSel := sc;
- LastCaptionFoc := fc;
-
- if Application.MessageBox('Do you really want to open another flame? All changes made to the current flame will be lost.', 'Apophysis', MB_ICONWARNING or MB_YESNO) <> IDYES then
- begin
- AllowChange := false;
- ListView1.OnChange := nil;
- ListView1.OnChanging := nil;
- ListView1.Selected := Item;
- ListView1.ItemFocused := Item;
- ListView1.OnChanging := ListViewChanging;
- ListView1.OnChange := ListViewChange;
- end
- else
- begin
- AllowChange := true;
- end;
-
- LastDecision := AllowChange;
- end;
- end;
-end;
-
-procedure TMainForm.ListViewInfoTip(Sender: TObject; Item: TListItem;
- var InfoTip: String);
-var
- Bitmap: TBitmap;
- lcp: TControlPoint;
-begin
- // flame preview in a tooltip...
-
- BitMap := TBitMap.create;
- Bitmap.PixelFormat := pf24bit;
- BitMap.Width := 100;
- BitMap.Height := 100;
-
- lcp := TControlPoint.Create;
- lcp.Copy(mainCP);
- lcp.cmap := mainCP.cmap;
-
- if Assigned(Renderer) then begin
- Renderer.WaitFor;
- Renderer.Free;
- end;
- if not Assigned(Renderer) then
- begin
- lcp.sample_density := 1;
- lcp.spatial_oversample := 1;
- lcp.spatial_filter_radius := 0.3;
- lcp.AdjustScale(100, 100);
- lcp.Transparency := false;
- end;
- try
- Renderer := TRenderThread.Create;
- assert(Renderer <> nil);
- Renderer.BitsPerSample := 0
- Renderer.TargetHandle := self.Handle;
- Renderer.SetCP(lcp);
- Renderer.Priority := tpLower;
- Renderer.NrThreads := 1
- Renderer.Resume;
- Renderer.WaitFor;
- except
- end;
-
- lcp.Free;
- Bitmap.Free;
-end;
-}
-
procedure TMainForm.btnViewIconsClick(Sender: TObject);
-var thumbs: TThumbnailThread;
begin
ListView1.ViewStyle := vsIcon;
btnViewList.Down := false;
@@ -7498,12 +7097,7 @@ begin
ClassicListMode := false;
// AV: refresh flame images ONLY if they didn't exist
- if not GeneratingThumbs then
- begin
- thumbs := TThumbnailThread.Create;
- thumbs.Start;
- GeneratingThumbs := True;
- end;
+ if not GeneratingThumbs then RunThumbnailThread;
// AV: scroll down to the selected flame preview
if MainForm.ListView1.SelCount > 0 then
@@ -7541,28 +7135,29 @@ begin
end;
procedure TMainForm.btNewClick(Sender: TObject);
+var saved: boolean;
begin
StopThread; // AV
if AlwaysCreateBlankFlame then
- EditForm.tbResetAll.Click // AV
- else
+ EditForm.mnuResetAllClick(Sender) // AV
+ else
if TemplateForm.ShowModal = mrOK then // AV
if AutoSaveXML then
// AV: create a flame from scratch (rather than replace the current) if needed
begin
MainCp.name := MainCp.name + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
- if MainForm.SaveXMLFlame(MainCp, MainCp.name, OpenFile) then
- if SortFlames.Checked then
- ListXML(OpenFile, 2, MainCp.name) // show the new item
- else
- ListXML(OpenFile, 0); // show the last item
+ if (OpenFileType = ftXML) then
+ saved := SaveXMLFlame(MainCp, MainCp.name, OpenFile)
+ else
+ saved := SaveFlame(MainCp, MainCp.name, OpenFile);
+ if saved then AddFlameToList; // AV: show the new item
end;
end;
-procedure TMainForm.FormResize(Sender: TObject);
+procedure TMainForm.ToolBarResize(Sender: TObject);
begin
- if (MainForm.Width <= TbBreakWidth) then
- Toolbar.Height := 26 * 2 + 8
+ if (Toolbar.Width <= TbBreakWidth) then
+ Toolbar.Height := 60 // 26 * 2 + 8
else Toolbar.Height := 26;
end;
@@ -7618,157 +7213,94 @@ end;
procedure TMainForm.AutoSaveTimerTimer(Sender: TObject);
var
- filename,title : string;
- Tag: string;
- IFile: TextFile;
- FileList, FileListPre: TStringList;
- i, p: integer;
- erase : boolean;
- bakname: string;
+ filename, title, bakname : string;
+ FileListPre: TStringList;
begin
- erase := false;
filename := AutoSavePath;
- title := CleanXMLName(maincp.name) + ' (' + FormatDateTime('MM-dd-yyyy hh:mm:ss', Now) + ')';
- Tag := RemoveExt(filename);
+ title := CleanXMLName(maincp.name) + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
if FileExists(filename) then begin
FileListPre := TStringList.create;
- try
- FileListPre.LoadFromFile(filename);
- if (FileListPre.Count > 1000) then erase := true;
- finally
- FileListPre.Free;
- end;
-
- if (erase) then begin
- bakname := ChangeFileExt(filename, '.bak');
- if FileExists(bakname) then DeleteFile(bakname);
- RenameFile(filename, bakname);
- end;
- end;
-
- try
- if FileExists(filename) then
- begin
- bakname := ChangeFileExt(filename, '.temp');
- if FileExists(bakname) then DeleteFile(bakname);
- RenameFile(filename, bakname);
-
- FileList := TStringList.create;
- try
- FileList.LoadFromFile(bakname);
-
- if Pos(' 0 then
+ try
+ FileListPre.LoadFromFile(filename);
+ if (FileListPre.Count > 100000) then // increased nr of flames
+ // AV: if user working on auto-saved flame, we must NOT delete it
+ if (AutoSavePath <> OpenFile) then
begin
- i := 0;
- while Pos('', FileList[i]);
- FileList.Delete(i);
- end;
+ bakname := ChangeFileExt(filename, '.tmp');
+ if FileExists(bakname) then DeleteFile(bakname);
+ RenameFile(filename, bakname);
end;
-
- // fix first line
- if (FileList.Count > 0) then begin
- FileList[0] := '';
- end;
-
- if FileList.Count > 2 then
- begin
- if pos(' 0 then
- repeat
- FileList.Delete(FileList.Count - 1);
- until (Pos('', FileList[FileList.count - 1]) <> 0)
- else
- repeat
- FileList.Delete(FileList.Count - 1);
- until (Pos('<' + Tag + '>', FileList[FileList.count - 1]) <> 0) or
- (Pos('', FileList[FileList.count - 1]) <> 0);
- end else
- begin
- FileList.Delete(FileList.Count - 1);
- end;
-
- FileList.Add(Trim(FlameToXMLAS(maincp, title, false)));
- FileList.Add('');
- FileList.SaveToFile(filename);
-
- finally
- if FileExists(bakname) and not FileExists(filename) then
- RenameFile(bakname, filename);
-
- FileList.Free;
- if FileExists(bakname) then DeleteFile(bakname);
- end;
- end
- else
- begin
- // New file ... easy
- AssignFile(IFile, filename);
- ReWrite(IFile);
- Writeln(IFile, '');
- Write(IFile, FlameToXMLAS(maincp, title, false));
- Writeln(IFile, '');
- CloseFile(IFile);
+ finally
+ FileListPre.Free;
end;
- except on EInOutError do // AV
- raise Exception.CreateFmt(TextByKey('common-genericsavefailure'),[title]);
end;
+
+ if SaveXMLFlame(maincp, title, filename) then
+ // AV: added ListView updating
+ if (FileName = OpenFile) then AddFlameToList(title);
+
+ bakname := ChangeFileExt(filename, '.bak');
+ if FileExists(bakname) then DeleteFile(bakname);
end;
procedure TMainForm.Restorelastautosave1Click(Sender: TObject);
-var fn:string;
+var fn: string;
begin
- if (not fileexists(AutoSavePath)) then
+ if (not FileExists(AutoSavePath)) then
raise Exception.Create(TextByKey('main-status-noautosave')); // AV
- //ScriptEditor.Stopped := True;
- MainMenuClick(nil); // AV
-
+ // StopScripter;
fn := AutoSavePath;
- MainForm.CurrentFileName := fn;
LastOpenFile := fn;
- Maincp.name := '';
+ Maincp.name := ''; // AV: ?
ParamFolder := ExtractFilePath(fn);
OpenFile := fn;
- //MainForm.Caption := AppVersionString + ' - ' + OpenFile; // --Z--
- if APP_BUILD = '' then MainForm.Caption := AppVersionString + ' - ' + openFile
- else MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + openFile;
+
+ if APP_BUILD = '' then
+ MainForm.Caption := AppVersionString + ' - ' + openFile
+ else
+ MainForm.Caption := AppVersionString + ' ' + APP_BUILD + ' - ' + openFile;
OpenFileType := ftXML;
ListXML(fn, 1)
end;
procedure TMainForm.mnuHelpTopicsClick(Sender: TObject);
-var
- URL, HelpTopic: string;
+// var URL, HelpTopic: string;
begin
- {if EditForm.Active then HelpTopic := 'Transform editor.htm'
-// else if GradientForm.Active then HelpTopic := 'Gradient window.htm'
+ {
+ if EditForm.Active then HelpTopic := 'Transform editor.htm'
else if AdjustForm.Active then HelpTopic := 'Adjust window.htm'
else if MutateForm.Active then HelpTopic := 'Mutation window.htm'
else if RenderForm.Active then HelpTopic := 'Render window.htm';
HtmlHelp(0, nil, HH_CLOSE_ALL, 0);
- URL := AppPath + 'Apophysis 2.0.chm';
+ URL := AppPath + Application.HelpFile;
if HelpTopic <> '' then URL := URL + '::\' + HelpTopic;
- HtmlHelp(0, PChar(URL), HH_DISPLAY_TOC, 0); }
- //if (FileExists(HelpPath)) then
- if (HelpPath <> '') then begin
- if (not WinShellExecute('open', HelpPath)) then begin
- MessageBox(self.Handle, PCHAR(Format(TextByKey('common-genericopenfailure'), [HelpPath])),
- PCHAR('Apophysis AV'), MB_ICONHAND);
- end;
- end else MessageBox(self.Handle, PCHAR(TextByKey('main-status-nohelpfile')),
- PCHAR('Apophysis AV'), MB_ICONHAND);
+ HtmlHelp(0, PChar(URL), HH_DISPLAY_TOC, 0);
+ }
+
+ if (HelpPath <> '') then
+ begin
+ if not (FileExists(HelpPath)) then // AV
+ MessageBox(self.Handle, PCHAR(TextByKey('common-noparamfile')),
+ ApophysisSVN, MB_ICONHAND)
+ else
+ if (not WinShellExecute('open', HelpPath)) then begin
+ MessageBox(self.Handle, PCHAR(Format(TextByKey('common-genericopenfailure'),
+ [HelpPath])), ApophysisSVN, MB_ICONHAND);
+ end;
+ end else
+ MessageBox(self.Handle, PCHAR(TextByKey('main-status-nohelpfile')),
+ ApophysisSVN, 48);
end;
+{
function TMainForm.RetrieveXML(cp : TControlPoint):string;
begin
- Result := FlameToXML(cp, false, false);
+ // AV: commented out since we can call it directly
+ Result := FlameToXML(cp, false);
end;
+}
procedure TMainForm.tbGuidesClick(Sender: TObject);
begin
@@ -7811,18 +7343,27 @@ procedure TMainForm.mnuTurnFlameToScriptClick(Sender: TObject);
var
txt: string;
begin
- txt := Trim(FlameToXML(Maincp, false, false));
+ txt := Trim(FlameToXML(Maincp));
ScriptEditor.ScriptFromFlame(txt);
ScriptEditor.Show;
end;
+procedure TMainForm.RunThumbnailThread;
+var
+ thumbs: TThumbnailThread;
+begin
+ thumbs := TThumbnailThread.Create;
+ thumbs.Start; // AV: Resume method is deprecated here
+ GeneratingThumbs := True;
+end;
+
constructor TThumbnailThread.Create;
begin
inherited create(True); // AV: don't run the thread immediately
- FCount := MainForm.ListView1.Items.Count - 1;
FreeOnTerminate := true; // AV: fixed - someone forgot to free the memory
Trace2('Creating ThumbnailThread #' + IntToStr(self.ThreadID));
+ FlameItems := MainForm.ListView1.Items; // AV: keep the reference to flame list
end;
destructor TThumbnailThread.Destroy;
@@ -7842,111 +7383,78 @@ var
cp : TControlPoint;
Thumbnail : TBitmap;
flameXML, fCaption : string;
- w, h, i : integer;
+ w, h: integer;
r : double;
- {
- stored_thumb : TJPegImage;
- stored_thumb_data : TBinArray;
- stored_thumb_size : integer;
- memstream : TMemoryStream;
- }
+ Fitem: TListItem;
+ FlameProc: TProc;
begin
inherited;
Renderer := TRenderer.Create;
cp := TControlPoint.Create;
Thumbnail := TBitmap.Create;
+
try // AV: added try-finally block
// AV: moved outside the loop for speed
+ Thumbnail.SetSize(FThumbnailSize, FThumbnailSize);
Thumbnail.PixelFormat := pf24bit;
Thumbnail.HandleType := bmDIB;
- Thumbnail.Width := FThumbnailSize;
- Thumbnail.Height := FThumbnailSize;
+
+ Thumbnail.Canvas.Lock; // AV: added thread-safe handling
Thumbnail.Canvas.Brush.Color := WinColor; // AV: theme-aware GetSysColor(5);
- for i := 0 to FCount do
+ if (OpenFileType = ftXML) then
+ FlameProc := procedure
+ begin
+ flameXML := LoadXMLFlameText(Openfile, fCaption);
+ MainForm.ParseXML(cp, flameXML, true);
+ end
+ else // added thumbs support for Undo (*.apo) flames
+ FlameProc := procedure
+ begin
+ FlameFromUndo(cp, fCaption, OpenFile);
+ end;
+
+ for Fitem in FlameItems do // hope this is more safety loop
begin
cp.Clear;
- fCaption := MainForm.ListView1.Items[i].Caption;
- flameXML := LoadXMLFlameText(Openfile, fCaption);
- MainForm.ParseXML(cp, PCHAR(flameXML), true);
- {
- // AV: great idea, but somehow it doesn't work and causes crashes :(
- if (cp.xdata <> '') then
+ fCaption := Fitem.Caption;
+
+ FlameProc; // AV
+
+ r := cp.Width / cp.Height;
+ w := ThumbnailSize;
+ h := w;
+ if (r < 1) then w := round(r * w)
+ else if (r > 1) then h := round(h / r);
+ cp.AdjustScale(w, h);
+
+ cp.spatial_oversample := defOversample;
+ cp.spatial_filter_radius := defFilterRadius;
+ cp.sample_density := FPreviewDensity; // AV
+
+ Renderer.SetCP(cp);
+ Renderer.Render;
+
+ Thumbnail.Canvas.FillRect(Rect(0, 0, FThumbnailSize, FThumbnailSize));
+ Thumbnail.Canvas.Draw((ThumbnailSize - w) shr 1,
+ (ThumbnailSize - h) shr 1, Renderer.GetImage);
+
+ // AV: added thread synchronization for updating visual components
+ Synchronize(
+ procedure
begin
- stored_thumb := TJPegImage.Create;
- B64Decode(cp.xdata, stored_thumb_data, stored_thumb_size);
- memstream := TMemoryStream.Create;
- memstream.Size := stored_thumb_size;
- stored_thumb_size := Length(stored_thumb_data);
- memstream.WriteBuffer(stored_thumb_data[0], stored_thumb_size);
- memstream.Seek(0, soBeginning);
- //-X- test thumbnail integrity... memstream.SaveToFile('C:\Test.jpg');
- stored_thumb.LoadFromStream(memstream);
- memstream.Free;
-
- w := stored_thumb.Width;
- h := stored_thumb.Height;
-
- Thumbnail.Canvas.FillRect(Rect(0, 0, FThumbnailSize, FThumbnailSize));
- Thumbnail.Canvas.Draw(round(FThumbnailSize / 2 - w / 2),
- round(FThumbnailSize / 2 - h / 2), stored_thumb);
-
- // AV: added thread synchronization for visual components
- Synchronize(
- procedure
- begin
- Trace2('Generating thumbnail for "' + fCaption + '"');
- MainForm.UsedThumbnails.Add(Thumbnail, nil);
- MainForm.ListView1.Items[i].ImageIndex := MainForm.UsedThumbnails.Count - 1;
- end);
-
- stored_thumb.Free;
- end else }
- begin
- w := cp.Width;
- h := cp.Height;
- r := w / h;
- if (w < h) then
- begin
- w := round(r * FThumbnailSize);
- h := FThumbnailSize;
- end else if (w > h) then
- begin
- h := round(FThumbnailSize / r);
- w := FThumbnailSize;
- end else
- begin
- w := FThumbnailSize;
- h := FThumbnailSize;
- end;
- cp.AdjustScale(w, h);
- cp.spatial_oversample := defOversample;
- cp.spatial_filter_radius := defFilterRadius;
- cp.sample_density := FPreviewDensity; // AV
-
- Renderer.SetCP(cp);
- Renderer.Render;
-
- Thumbnail.Canvas.FillRect(Rect(0, 0, FThumbnailSize, FThumbnailSize));
- Thumbnail.Canvas.Draw(round(FThumbnailSize / 2 - w / 2),
- round(FThumbnailSize / 2 - h / 2), Renderer.GetImage);
-
- // AV: added thread synchronization for updating visual components
- Synchronize(
- procedure
- begin
- MainForm.UsedThumbnails.Add(Thumbnail, nil);
- MainForm.ListView1.Items[i].ImageIndex := MainForm.UsedThumbnails.Count - 1;
- Trace2('Generating thumbnail for "' + fCaption + '"');
- end);
- end;
+ MainForm.UsedThumbnails.Add(Thumbnail, nil);
+ Fitem.ImageIndex := MainForm.UsedThumbnails.Count - 1;
+ Trace2('Generating thumbnail for "' + fCaption + '"');
+ end);
if Terminated then break; // AV
end;
finally
+ Thumbnail.Canvas.UnLock; // AV: added thread-safe handling
+ Thumbnail.Free;
+ Thumbnail := nil;
cp.Free;
Renderer.Free;
- Thumbnail.Free;
- Thumbnail := nil;
end;
end;
@@ -7955,7 +7463,6 @@ var
FStrings : TStringList;
i, p : integer;
title : string;
- thread : TThumbnailThread;
item : TListItem;
begin
MainForm.ParseLoadingBatch := true;
@@ -7980,7 +7487,7 @@ begin
p := Pos(' 0) then
begin
- MainForm.ListXMLScanner.LoadFromBuffer(TCharType(TStringType(FStrings[i])));
+ MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FStrings[i])));
MainForm.ListXMLScanner.Execute;
if Trim(pname) = '' then
@@ -7995,6 +7502,8 @@ begin
item := MainForm.ListView1.Items.Add;
item.Caption := Title;
item.ImageIndex := 0; // AV: now we can load a hourglass icon
+ // AV: hack - remember the creation order in an unused field
+ item.OverlayIndex := MainForm.ListView1.Items.Count;
end;
end;
end;
@@ -8002,13 +7511,10 @@ begin
MainForm.LoadSaveProgress.Position := 0;
//MainForm.ListView1.AllocBy := MainForm.ListView1.Items.Count;
- if ClassicListMode then // AV: thumbs are useless
+ if ClassicListMode then // AV: thumbs are useless
GeneratingThumbs := False
- else begin
- thread := TThumbnailThread.Create;
- thread.Start; // AV: thread.Resume method is deprecated here
- GeneratingThumbs := True;
- end;
+ else
+ MainForm.RunThumbnailThread; // AV: wrap it into a separate method
finally
MainForm.ListView1.Items.EndUpdate;
@@ -8025,8 +7531,63 @@ begin
if MainForm.EnumerateFlames.Checked then // AV: displaying indices
MainForm.EnumerateFlamesClick(MainForm.EnumerateFlames);
+
end;
MainForm.ParseLoadingBatch := false;
+
+ if AnimateForm.Visible then AnimateForm.UpdateControls; // AV
+end;
+
+// AV: the fast way to refresh ListView
+procedure TMainForm.AddFlameToList(const title: string = '');
+var
+ item: TListItem;
+ i: integer;
+ fname: string;
+begin
+ if title = '' then fname := MainCp.name
+ else fname := title;
+
+ ListView1.Items.BeginUpdate;
+ try
+ // first check for duplicates
+ item := ListView1.FindCaption(max(ListView1.ItemIndex, 0), fname,
+ false, true, true);
+ if item <> nil then
+ ListView1.Items.Delete(item.Index);
+
+ // AV: temporary prevent all preview updates
+ ListView1.OnChange := nil;
+ ListView1.OnSelectItem := nil;
+
+ item := ListView1.Items.Add;
+ item.Caption := fname;
+ ListView1.Selected := ListView1.Items[item.Index];
+ UsedThumbnails.Add(ThumbnailPlaceholder, nil); // add dummy hourglass icon
+ item.ImageIndex := UsedThumbnails.Count - 1;
+
+ item.OverlayIndex := ListView1.Items.Count; // remember the creation order
+ // if some flames were deleted from the list, max index is greater than the last one
+ for i := 0 to ListView1.Items.Count - 1 do
+ if ListView1.Items[i].OverlayIndex > item.OverlayIndex then
+ item.OverlayIndex := ListView1.Items[i].OverlayIndex + 1;
+
+ ListView1.Selected := ListView1.Items[item.Index];
+ ListView1.ItemFocused := ListView1.Selected;
+ if GeneratingThumbs then RefreshThumbnail;
+ finally
+ // AV: restore the default event handlers
+ ListView1.OnChange := ListViewChange;
+ if ConfirmResetUndo then
+ ListView1.OnSelectItem := ListViewSelectItem;
+ ListView1.Items.EndUpdate;
+ end;
+ // refreshing flame indices
+ if EnumerateFlames.Checked then EnumerateFlamesClick(EnumerateFlames);
+ // scroll to the new item
+ if ListView1.Selected <> nil then ListView1.Selected.MakeVisible(true);
+
+ if AnimateForm.Visible then AnimateForm.UpdateControls;
end;
procedure TMainForm.RefreshThumbnail;
@@ -8037,28 +7598,18 @@ var
i, w, h, w_old, h_old: integer;
begin
if not Assigned(ListView1.Selected) then exit;
- i := ListView1.Selected.Index;
- if (i > UsedThumbnails.Count) then exit;
+ i := ListView1.Selected.ImageIndex;
+ if (i >= UsedThumbnails.Count) then exit;
- w := Maincp.Width;
- h := Maincp.Height;
- w_old := w;
- h_old := h;
+ w_old := Maincp.Width;
+ h_old := Maincp.Height;
- r := w / h;
- if (w < h) then
- begin
- w := round(r * ThumbnailSize);
- h := ThumbnailSize;
- end else if (w > h) then
- begin
- h := round(ThumbnailSize / r);
- w := ThumbnailSize;
- end else
- begin
- w := ThumbnailSize;
- h := ThumbnailSize;
- end;
+ r := w_old / h_old;
+ w := ThumbnailSize;
+ h := w;
+ if (r < 1) then w := round(r * w)
+ else if (r > 1) then h := round(h / r);
+
sd := Maincp.sample_density;
Maincp.AdjustScale(w, h);
Maincp.spatial_oversample := defOversample;
@@ -8073,15 +7624,15 @@ begin
Thumbnail.PixelFormat := pf24bit;
Thumbnail.HandleType := bmDIB;
- Thumbnail.Width := ThumbnailSize;
- Thumbnail.Height := ThumbnailSize;
+ Thumbnail.SetSize(ThumbnailSize, ThumbnailSize);
Thumbnail.Canvas.Brush.Color := WinColor; // theme-aware system color
Thumbnail.Canvas.FillRect(Rect(0, 0, ThumbnailSize, ThumbnailSize));
- Thumbnail.Canvas.Draw(round(ThumbnailSize / 2 - w / 2),
- round(ThumbnailSize / 2 - h / 2), Renderer.GetImage);
+ Thumbnail.Canvas.Draw((ThumbnailSize - w) shr 1,
+ (ThumbnailSize - h) shr 1, Renderer.GetImage);
try
- UsedThumbnails.Replace(i + 1, Thumbnail, nil);
+ UsedThumbnails.Replace(i, Thumbnail, nil);
+ i := ListView1.Selected.Index;
ListView1.Items.Item[i].Update;
Trace2('Updating thumbnail for "' + ListView1.Items[i].Caption + '"');
except
@@ -8100,7 +7651,6 @@ end;
procedure TMainForm.UpdateThumbnails; // AV: refreshes images only
var
i: integer;
- thumbs: TThumbnailThread;
begin
UsedThumbnails.Clear;
UsedThumbnails.Add(ThumbnailPlaceholder, nil);
@@ -8112,9 +7662,7 @@ begin
EndUpdate;
end;
- thumbs := TThumbnailThread.Create;
- thumbs.Start;
- GeneratingThumbs := True;
+ RunThumbnailThread;
// hightlight the item if possible
ListView1.Selected := ListView1.ItemFocused;
@@ -8150,9 +7698,9 @@ begin
LoadForm.Output.Text := LoadForm.Output.Text + #13#10 + str + ' ' + TextByKey('main-report-noplugins') + #13#10;
exit;
end;
- for i := 0 to MainCP.used_plugins.Count-1 do begin
+ for i := 0 to MainCP.used_plugins.Count-1 do
str := str + #13#10 + ' - ' + MainCP.used_plugins[i];
- end;
+
// AV: added 3D and DC status
str := str + #13#10 + TextByKey('main-report-directcoloring') + #32 +
IfThen((pos('dc', str) > 0) or (pos('falloff', str) > 0) or (pos('affine3D', str) > 0),
@@ -8161,13 +7709,17 @@ begin
IfThen((MainCP.cameraPitch <> 0) or (MainCP.cameraRoll <> 0) or (pos('_rotate_', str) > 0),
TextByKey('common-yes'), TextByKey('common-no'));
+ if MainCp.Comment <> '' then
+ str := str + #13#10 + TextByKey('common-comment') + ': '#13#10'"' +
+ MainCp.Comment + '"';
+
LoadForm.Output.Text := LoadForm.Output.Text + #13#10 + str + #13#10;
end;
procedure TMainForm.mnuExportChaoticaClick(Sender: TObject);
begin
MainCP.FillUsedPlugins;
- C_ExecuteChaotica(FlameToXml(MainCp, false, false), MainCp.used_plugins, UseX64IfPossible);
+ C_ExecuteChaotica(FlameToXml(MainCp), MainCp.used_plugins, UseX64IfPossible);
end;
procedure TMainForm.mnuManualClick(Sender: TObject); // AV: Apo7X link is dead...
@@ -8282,19 +7834,20 @@ begin
end;
function TMainForm.ReadWithSubst(Attributes: TAttrList; attrname: string): string;
-var i: integer; v: TStringType;
+var i: integer;
+ v: string; //TStringType;
begin
- v := Attributes.Value(TStringType(attrname));
+ v := string(Attributes.Value(Utf8String(attrname)));
if (v <> '') then begin
- Result := String(v);
+ Result := v;
Exit;
end;
for i := 0 to SubstTarget.Count - 1 do begin
if (SubstTarget[i] = attrname) then begin
- v := Attributes.Value(TStringType(SubstSource[i]));
+ v := string(Attributes.Value(Utf8String(SubstSource[i])));
if (v <> '') then begin
- Result := String(v);
+ Result := v;
Exit;
end;
end;
diff --git a/Forms/Mutate.dfm b/Forms/Mutate.dfm
index 1f801f4..47b6b68 100644
--- a/Forms/Mutate.dfm
+++ b/Forms/Mutate.dfm
@@ -5,7 +5,7 @@ object MutateForm: TMutateForm
BorderStyle = bsSingle
Caption = 'Mutation'
ClientHeight = 398
- ClientWidth = 422
+ ClientWidth = 414
Color = clBtnFace
Constraints.MinHeight = 400
Constraints.MinWidth = 400
@@ -21,51 +21,28 @@ object MutateForm: TMutateForm
OnDestroy = FormDestroy
OnShow = FormShow
DesignSize = (
- 422
+ 414
398)
PixelsPerInch = 96
TextHeight = 13
- object GroupBox1: TGroupBox
- Left = 8
+ object gbDirections: TGroupBox
+ Left = 24
Top = 8
- Width = 409
+ Width = 360
Height = 273
- Anchors = [akLeft, akTop, akRight, akBottom]
Caption = 'Directions'
TabOrder = 0
DesignSize = (
- 409
+ 360
273)
- object Panel10: TPanel
+ object pnlDirections: TPanel
Left = 12
Top = 20
- Width = 384
+ Width = 335
Height = 238
Anchors = [akLeft, akTop, akRight, akBottom]
BevelOuter = bvNone
TabOrder = 0
- object Panel6: TPanel
- Left = 112
- Top = 168
- Width = 108
- Height = 80
- BevelOuter = bvLowered
- Caption = 'PrevPnl3'
- Color = clBlack
- ShowCaption = False
- TabOrder = 0
- object Image6: TImage
- Tag = 6
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
- end
object Panel7: TPanel
Left = 0
Top = 168
@@ -75,18 +52,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 1
- object Image7: TImage
- Tag = 7
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
+ TabOrder = 0
end
object Panel4: TPanel
Left = 224
@@ -97,18 +63,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 2
- object Image4: TImage
- Tag = 4
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
+ TabOrder = 1
end
object Panel0: TPanel
Left = 112
@@ -120,7 +75,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 3
+ TabOrder = 2
object Image0: TImage
Left = 1
Top = 1
@@ -130,6 +85,8 @@ object MutateForm: TMutateForm
PopupMenu = QualityPopup
Stretch = True
OnClick = Image0Click
+ ExplicitLeft = 2
+ ExplicitTop = 0
end
end
object Panel8: TPanel
@@ -141,18 +98,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 4
- object Image8: TImage
- Tag = 8
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
+ TabOrder = 3
end
object Panel3: TPanel
Left = 224
@@ -163,18 +109,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 5
- object Image3: TImage
- Tag = 3
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
+ TabOrder = 4
end
object Panel2: TPanel
Left = 112
@@ -185,18 +120,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 6
- object Image2: TImage
- Tag = 2
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
+ TabOrder = 5
end
object Panel1: TPanel
Left = 0
@@ -207,18 +131,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
- TabOrder = 7
- object Image1: TImage
- Tag = 1
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
+ TabOrder = 6
end
object Panel5: TPanel
Left = 224
@@ -229,37 +142,36 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
+ TabOrder = 7
+ end
+ object Panel6: TPanel
+ Left = 112
+ Top = 168
+ Width = 108
+ Height = 80
+ BevelOuter = bvLowered
+ Caption = 'PrevPnl3'
+ Color = clBlack
+ ShowCaption = False
TabOrder = 8
- object Image5: TImage
- Tag = 5
- Left = 1
- Top = 1
- Width = 106
- Height = 78
- Align = alClient
- PopupMenu = QualityPopup
- Stretch = True
- OnClick = MutantClick
- end
end
end
end
object GroupBox2: TGroupBox
Left = 8
Top = 288
- Width = 409
+ Width = 393
Height = 105
- Anchors = [akLeft, akRight, akBottom]
+ Anchors = [akLeft, akBottom]
TabOrder = 1
DesignSize = (
- 409
+ 393
105)
object scrollTime: TScrollBar
- Left = 120
+ Left = 114
Top = 20
Width = 202
Height = 20
- Anchors = [akLeft, akTop, akRight]
LargeChange = 5
Max = 50
Min = 1
@@ -269,23 +181,23 @@ object MutateForm: TMutateForm
OnChange = scrollTimeChange
end
object cmbTrend: TComboBox
- Left = 119
+ Left = 114
Top = 48
- Width = 282
+ Width = 262
Height = 21
Style = csDropDownList
- Anchors = [akLeft, akTop, akRight]
DropDownCount = 16
+ Sorted = True
TabOrder = 1
OnChange = cmbTrendChange
Items.Strings = (
- 'Random'
- 'Linear')
+ 'Linear'
+ 'Random')
end
object chkSameNum: TCheckBox
Left = 12
Top = 78
- Width = 389
+ Width = 373
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Same no. of transforms'
@@ -305,11 +217,10 @@ object MutateForm: TMutateForm
TabOrder = 3
end
object txtTime: TEdit
- Left = 328
+ Left = 318
Top = 20
- Width = 73
+ Width = 60
Height = 21
- Anchors = [akTop, akRight]
ReadOnly = True
TabOrder = 4
Text = '0.25'
@@ -331,8 +242,8 @@ object MutateForm: TMutateForm
Enabled = False
Interval = 100
OnTimer = TimerTimer
- Left = 168
- Top = 80
+ Left = 184
+ Top = 136
end
object QualityPopup: TPopupMenu
Images = MainForm.Buttons
diff --git a/Forms/Mutate.pas b/Forms/Mutate.pas
index 69faaac..f0bca3a 100644
--- a/Forms/Mutate.pas
+++ b/Forms/Mutate.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -28,11 +28,11 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, ControlPoint, ComCtrls, Menus, Buttons, Cmap,
- RenderingInterface, Translation, Curves;
+ RenderingInterface;
type
TMutateForm = class(TForm)
- GroupBox1: TGroupBox;
+ gbDirections: TGroupBox;
Timer: TTimer;
GroupBox2: TGroupBox;
scrollTime: TScrollBar;
@@ -48,29 +48,20 @@ type
N1: TMenuItem;
mnuMaintainSym: TMenuItem;
N2: TMenuItem;
- Panel10: TPanel;
- Panel6: TPanel;
- Image6: TImage;
+ pnlDirections: TPanel;
Panel7: TPanel;
- Image7: TImage;
Panel4: TPanel;
- Image4: TImage;
Panel0: TPanel;
Image0: TImage;
Panel8: TPanel;
- Image8: TImage;
Panel3: TPanel;
- Image3: TImage;
Panel2: TPanel;
- Image2: TImage;
Panel1: TPanel;
- Image1: TImage;
Panel5: TPanel;
- Image5: TImage;
pnlSpeed: TPanel;
txtTime: TEdit;
pnlTrend: TPanel;
- //procedure Panel10Resize(Sender: TObject);
+ Panel6: TPanel;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
@@ -80,7 +71,6 @@ type
procedure TimerTimer(Sender: TObject);
procedure scrollTimeChange(Sender: TObject);
procedure cmbTrendChange(Sender: TObject);
- procedure btnCancelClick(Sender: TObject);
procedure mnuHighQualityClick(Sender: TObject);
procedure mnuLowQualityClick(Sender: TObject);
procedure mnuMediumQualityClick(Sender: TObject);
@@ -91,11 +81,11 @@ type
procedure mnuMaintainSymClick(Sender: TObject);
private
name: string;
- bm: TBitmap;
PreviewDensity: double;
Updating: boolean;
cps: array[0..8] of TControlPoint;
Mutants: array[0..8] of TControlPoint;
+ MImages: array[1..8] of TImage; // AV
Render: TRenderer;
Time: double;
bstop: boolean;
@@ -106,6 +96,8 @@ type
procedure ShowMain;
procedure ShowMutants;
procedure Interpolate;
+ procedure RandomCP(var cp: TControlPoint; const minT, maxT: integer); // AV: removed from ControlPoint
+ procedure SetVariation(var cp: TControlPoint); // AV: wrote a local method
public
Zoom: Double;
Center: array[0..1] of double;
@@ -120,7 +112,7 @@ var
implementation
uses
- Main, Global, Registry, Editor, Adjust, XFormMan;
+ Main, Global, Registry, Editor, XFormMan, Adjust, Translation;
{$R *.DFM}
@@ -135,13 +127,12 @@ begin
MainCp.AdjustScale(width, height); // AV: restore normal size
if mnuResetLocation.checked then
begin
- //MainForm.Mainzoom := cps[0].zoom;
MainForm.Center[0] := cps[0].Center[0];
MainForm.Center[1] := cps[0].Center[1];
end;
MainForm.RedrawTimer.enabled := true;
if EditForm.Visible then EditForm.UpdateDisplay;
-// if AdjustForm.Visible then AdjustForm.UpdateDisplay;
+ if AdjustForm.Visible then AdjustForm.UpdateDisplay;
end;
procedure TMutateForm.UpdateDisplay;
@@ -167,6 +158,26 @@ begin
ShowMutants;
end;
+procedure TMutateForm.SetVariation(var cp: TControlPoint);
+var
+ i, k, n: integer;
+begin
+ if cmbTrend.ItemIndex = NRVAR then // AV: set random variations from selected
+ repeat
+ n := random(NrVar);
+ until Variations[n]
+ else // AV: sorted list is used from now
+ n := GetVariationIndex(cmbTrend.Items[cmbTrend.ItemIndex]);
+
+ for i := 0 to cp.NumXforms-1 do
+ begin
+ for k := 0 to NrVar-1 do // AV: simplified the calculations
+ cp.xform[i].SetVariation(k, 0);
+ cp.xform[i].SetVariation(n, 1);
+ end;
+
+end;
+
procedure TMutateForm.ShowMain;
begin
cps[0].Width := Image0.Width;
@@ -194,20 +205,21 @@ begin
Render.SetCP(cps[0]);
Render.Render;
- BM.Assign(Render.GetImage);
- Image0.Picture.Graphic := bm;
+ Image0.Picture.Graphic := Render.GetImage;
end;
procedure TMutateForm.ShowMutants;
var
- i: integer;
+ i: byte;
+ //t: cardinal;
begin
if Visible = false then exit;
Updating := true;
+ //t := GetTickCount;
for i := 1 to 8 do
begin
- mutants[i].Width := Image1.Width;
- mutants[i].Height := Image1.Height;
+ mutants[i].Width := Image0.Width;
+ mutants[i].Height := Image0.Height;
mutants[i].spatial_filter_radius := defFilterRadius;
mutants[i].spatial_oversample := defOversample;
mutants[i].sample_density := PreviewDensity;
@@ -230,51 +242,22 @@ begin
Render.SetCP(mutants[i]);
Render.Render;
- BM.Assign(Render.GetImage);
- case i of
- 1: begin
- Image1.Picture.Graphic := bm;
- Image1.Refresh;
- end;
- 2: begin
- Image2.Picture.Graphic := bm;
- Image2.Refresh;
- end;
- 3: begin
- Image3.Picture.Graphic := bm;
- Image3.Refresh;
- end;
- 4: begin
- Image4.Picture.Graphic := bm;
- Image4.Refresh;
- end;
- 5: begin
- Image5.Picture.Graphic := bm;
- Image5.Refresh;
- end;
- 6: begin
- Image6.Picture.Graphic := bm;
- Image6.Refresh;
- end;
- 7: begin
- Image7.Picture.Graphic := bm;
- Image7.Refresh;
- end;
- 8: begin
- Image8.Picture.Graphic := bm;
- Image8.Refresh;
- end;
- end;
+ // AV: replaced separate TImages by an array
+ MImages[i].Picture.Graphic := Render.GetImage;
+ MImages[i].Refresh;
+
Updating := false;
end;
+ //ShowMessage((GetTickCount - t).ToString);
end;
procedure TMutateForm.Interpolate;
-var i, j, k: Integer;
+var i, j: Integer;
begin
if MainCp = nil then Exit;
-
+
+ //cps[0].Time := 0;
for i := 1 to 8 do
begin
if bstop then exit;
@@ -283,45 +266,53 @@ begin
(* -X- something is not right here...
Mutants[i] may be destroyed already
Investigate? *)
- Mutants[i].clear;
+ // AV: it's OK... Mutants are just placeholders for a new flame
+ Mutants[i].Clear;
Mutants[i].InterpolateX(cps[0], cps[i], Time / 100);
- Mutants[i].cmapindex := cps[0].cmapindex;
- Mutants[i].cmap := cps[0].cmap;
Mutants[i].background := MainCp.background;
if mnuMaintainSym.Checked then // maintain symmetry
for j := 0 to transforms - 1 do
if cps[0].xform[j].Symmetry = 1 then
mutants[i].xform[j].Assign(cps[0].xform[j]);
end;
+
+end;
+
+procedure TMutateForm.RandomCP(var cp: TControlPoint; const minT, maxT: integer); // AV
+var
+ nrXforms, i: integer;
+begin
+ nrXforms := random(MaxT - MinT + 1) + MinT;
+
+ for i := 0 to nrXforms - 1 do begin
+ cp.xform[i].density := 1.0 / nrXforms;
+ cp.xform[i].color := i / (nrXforms - 1);
+ cp.xform[i].RandomizeCoefs(cp.xform[i].c);
+ end;
+
+ SetVariation(cp); //AV
end;
procedure TMutateForm.RandomSet;
-var i, j, k: Integer;
+var i: byte;
begin
RandSeed := seed;
for i := 1 to 8 do
begin
cps[i].clear;
+
if chkSameNum.checked then
- cps[i].RandomCP(transforms, transforms, false)
+ RandomCP(cps[i], transforms, transforms)
else
- cps[i].RandomCP(mutantMinTransforms, mutantMaxTransforms, false);
-
- if cmbTrend.ItemIndex = NRVAR then // AV
- cps[i].SetVariation(vRandom)
- else
- for j := 0 to cps[i].NumXforms-1 do
- begin
- for k := 0 to NrVar-1 do // AV: simplified the calculations
- cps[i].xform[j].SetVariation(k, 0);
- cps[i].xform[j].SetVariation(cmbTrend.ItemIndex, 1);
- end;
+ RandomCP(cps[i], mutantMinTransforms, mutantMaxTransforms);
+ { // AV: now it's done inside InterpolateX method
if cps[0].HasFinalXForm = false then
begin
cps[i].xform[cps[i].NumXForms].Clear;
cps[i].xform[cps[i].NumXForms].symmetry := 1;
end;
+ }
end;
Interpolate;
end;
@@ -361,7 +352,7 @@ var
i: integer;
begin
self.Caption := TextByKey('mutation-title');
- GroupBox1.Caption := TextByKey('mutation-directions');
+ gbDirections.Caption := TextByKey('mutation-directions');
pnlSpeed.Caption := TextByKey('mutation-speed');
pnlTrend.Caption := TextByKey('mutation-trend');
chkSameNum.Caption := TextByKey('mutation-keepnumberoftransforms');
@@ -375,10 +366,9 @@ begin
for i:= 0 to NRVAR -1 do // AV
cmbTrend.Items.Add(varnames(i));
+ cmbTrend.Sorted := False; // AV: 'random' item must be last
cmbTrend.Items.Add(TextByKey('mutation-randomtrend'));
- bm := TBitMap.Create;
-
case MutatePrevQual of
0: begin
mnuLowQuality.Checked := true;
@@ -401,7 +391,17 @@ begin
Mutants[i] := TControlPoint.Create;
end;
- Time := 35;
+ for i := 1 to 8 do // AV: added array for speed
+ begin
+ MImages[i] := TImage.Create(self);
+ MImages[i].Parent := TPanel(self.FindComponent('Panel' + IntToStr(i)));
+ MImages[i].Align := alClient;
+ MImages[i].Tag := i;
+ MImages[i].OnClick := MutantClick;
+ MImages[i].PopupMenu := QualityPopup;
+ end;
+
+ Time := 25; // 35;
scrollTime.Position := 25;
txtTime.Text := '0.25'; // AV
cmbTrend.ItemIndex := NRVAR; // AV
@@ -421,7 +421,6 @@ begin
cps[i].Free;
Mutants[i].Free;
end;
- bm.free;
end;
procedure TMutateForm.Image0Click(Sender: TObject);
@@ -439,30 +438,32 @@ var
cpt: TControlPoint;
begin
cpt := TControlPoint.Create;
- cpt.Copy(cps[0], false, transforms); // AV
bstop := true;
- // AV: optimized fast version without checking indices
+ // AV: optimized faster version without checking indices
i := TImage(Sender).Tag;
cps[0].Time := 0;
cps[i].Time := 1;
- cps[0].InterpolateX(cps[0], cps[i], Time / 100);
+ cpt.InterpolateX(cps[0], cps[i], Time / 100);
if mnuMaintainSym.Checked then // maintain symmetry
begin
for i := 0 to transforms - 1 do
begin
- if cpt.xform[i].Symmetry = 1 then
- cps[0].xform[i].Assign(cpt.xform[i]);
+ if cps[0].xform[i].Symmetry = 1 then
+ cpt.xform[i].Assign(cps[0].xform[i]);
end;
end;
+ // AV: it's faster to make a copy by reference that use TControlPoint.Copy()
+ cps[0].Free; // AV
+ cps[0] := cpt; // AV
+
bstop := false;
ShowMain;
Interpolate;
ShowMutants;
UpdateFlame;
- cpt.free;
end;
procedure TMutateForm.sbTimeChange(Sender: TObject);
@@ -494,28 +495,15 @@ end;
procedure TMutateForm.cmbTrendChange(Sender: TObject);
var
- i, j, k: integer;
+ i: byte;
begin
for i := 1 to 8 do
- if cmbTrend.ItemIndex = NRVAR then
- cps[i].SetVariation(VRandom) // AV
- else
- for j := 0 to cps[i].NumXforms-1 do
- begin // AV
- for k := 0 to NrVar-1 do
- cps[i].xform[j].SetVariation(k, 0);
- cps[i].xform[j].SetVariation(cmbTrend.ItemIndex, 1);
- end;
+ SetVariation(cps[i]); //AV
Interpolate;
ShowMutants;
end;
-procedure TMutateForm.btnCancelClick(Sender: TObject);
-begin
- ModalResult := mrCancel;
-end;
-
procedure TMutateForm.mnuHighQualityClick(Sender: TObject);
begin
mnuHighQuality.Checked := True;
@@ -605,30 +593,6 @@ begin
ShowMutants;
end;
-(*
- procedure TMutateForm.Panel10Resize(Sender: TObject);
- const gap:integer = 4 ;
- var
- w, h : integer;
- begin
- w := (Panel10.Width - 2*gap) div 3;
- h := (Panel10.Height - 2*gap) div 3;
-
- Panel0.Width := w; Panel1.Width := w; Panel2.Width := w;
- Panel3.Width := w; Panel4.Width := w; Panel5.Width := w;
- Panel6.Width := w; Panel7.Width := w; Panel8.Width := w;
- Panel0.Height := h; Panel1.Height := h; Panel2.Height := h;
- Panel3.Height := h; Panel4.Height := h; Panel5.Height := h;
- Panel6.Height := h; Panel7.Height := h; Panel8.Height := h;
-
- Panel2.Left := w + gap; Panel0.Left := w + gap; Panel6.Left := w + gap;
- Panel3.Left := 2*(w + gap); Panel4.Left := 2*(w + gap); Panel5.Left := 2*(w + gap);
-
- Panel8.Top := h + gap; Panel0.Top := h + gap; Panel4.Top := h + gap;
- Panel7.Top := 2*(h + gap); Panel6.Top := 2*(h + gap); Panel5.Top := 2*(h + gap);
- end;
-
-*)
end.
diff --git a/Forms/Options.dfm b/Forms/Options.dfm
index 00884a8..a3fc4da 100644
--- a/Forms/Options.dfm
+++ b/Forms/Options.dfm
@@ -1,11 +1,11 @@
object OptionsForm: TOptionsForm
Left = 899
Top = 428
- BorderIcons = [biSystemMenu, biMinimize, biMaximize, biHelp]
+ BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle
Caption = 'Options'
- ClientHeight = 498
- ClientWidth = 524
+ ClientHeight = 505
+ ClientWidth = 568
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -56,15 +56,36 @@ object OptionsForm: TOptionsForm
OnCreate = FormCreate
OnShow = FormShow
DesignSize = (
- 524
- 498)
+ 568
+ 505)
PixelsPerInch = 96
TextHeight = 13
+ object btnOK: TButton
+ Left = 374
+ Top = 477
+ Width = 86
+ Height = 25
+ Anchors = [akRight, akBottom]
+ Caption = 'OK'
+ Default = True
+ TabOrder = 0
+ OnClick = btnOKClick
+ end
+ object btnCancel: TButton
+ Left = 466
+ Top = 477
+ Width = 86
+ Height = 25
+ Anchors = [akRight, akBottom]
+ Caption = 'Cancel'
+ ModalResult = 2
+ TabOrder = 1
+ end
object Tabs: TPageControl
Left = 8
Top = 8
- Width = 512
- Height = 456
+ Width = 556
+ Height = 463
ActivePage = PathsPage
Anchors = [akLeft, akTop, akRight, akBottom]
MultiLine = True
@@ -73,15 +94,11 @@ object OptionsForm: TOptionsForm
object GeneralPage: TTabSheet
HelpContext = 1
Caption = 'General'
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 504
- 428)
- object SpeedButton1: TSpeedButton
- Left = 474
+ 548
+ 435)
+ object btnLanguage: TSpeedButton
+ Left = 518
Top = 7
Width = 24
Height = 24
@@ -123,7 +140,7 @@ object OptionsForm: TOptionsForm
ParentFont = False
ParentShowHint = False
ShowHint = True
- OnClick = SpeedButton1Click
+ OnClick = btnLanguageClick
ExplicitLeft = 437
end
object pnlJPEGQuality: TPanel
@@ -136,77 +153,8 @@ object OptionsForm: TOptionsForm
Caption = 'JPEG Quality'
ParentShowHint = False
ShowHint = True
- TabOrder = 9
- end
- object chkConfirmDel: TCheckBox
- Left = 236
- Top = 115
- Width = 258
- Height = 17
- HelpContext = 1005
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Confirm delete'
- TabOrder = 0
- end
- object chkOldPaletteFormat: TCheckBox
- Left = 236
- Top = 75
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Save gradient in old file format'
- TabOrder = 1
- WordWrap = True
- end
- object chkConfirmExit: TCheckBox
- Left = 236
- Top = 135
- Width = 258
- Height = 17
- HelpContext = 1005
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Confirm exit'
- TabOrder = 18
- end
- object chkConfirmStopRender: TCheckBox
- Left = 236
- Top = 155
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Confirm stop render'
TabOrder = 3
end
- object cbUseTemplate: TCheckBox
- Left = 236
- Top = 35
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Always create blank flame'
- TabOrder = 4
- end
- object cbMissingPlugin: TCheckBox
- Left = 236
- Top = 55
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Warn when plugins are missing'
- TabOrder = 5
- WordWrap = True
- end
- object cbEmbedThumbs: TCheckBox
- Left = 236
- Top = 255
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Enable thumbnail embedding'
- TabOrder = 6
- Visible = False
- WordWrap = True
- end
object pnlMultithreading: TPanel
Left = 8
Top = 92
@@ -217,7 +165,7 @@ object OptionsForm: TOptionsForm
Caption = 'Multithreading'
ParentShowHint = False
ShowHint = True
- TabOrder = 7
+ TabOrder = 1
end
object cbNrTheads: TComboBox
Left = 112
@@ -226,7 +174,7 @@ object OptionsForm: TOptionsForm
Height = 21
Style = csDropDownList
ItemIndex = 0
- TabOrder = 8
+ TabOrder = 2
Text = 'Off'
Items.Strings = (
'Off')
@@ -241,7 +189,7 @@ object OptionsForm: TOptionsForm
Caption = 'PNG Transparency'
ParentShowHint = False
ShowHint = True
- TabOrder = 11
+ TabOrder = 5
end
object grpGuidelines: TGroupBox
Left = 8
@@ -255,7 +203,7 @@ object OptionsForm: TOptionsForm
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
- TabOrder = 13
+ TabOrder = 7
object cbGL: TCheckBox
Left = 8
Top = 23
@@ -399,16 +347,16 @@ object OptionsForm: TOptionsForm
Caption = 'Language file'
ParentShowHint = False
ShowHint = True
- TabOrder = 14
+ TabOrder = 8
end
object txtLanguageFile: TComboBox
Left = 112
Top = 8
- Width = 360
+ Width = 404
Height = 21
Style = csDropDownList
Anchors = [akLeft, akTop, akRight]
- TabOrder = 15
+ TabOrder = 9
end
object cbPNGTransparency: TComboBox
Left = 112
@@ -417,7 +365,7 @@ object OptionsForm: TOptionsForm
Height = 21
Style = csDropDownList
ItemIndex = 0
- TabOrder = 12
+ TabOrder = 6
Text = 'Disabled'
Items.Strings = (
'Disabled'
@@ -428,7 +376,7 @@ object OptionsForm: TOptionsForm
Top = 36
Width = 113
Height = 21
- TabOrder = 10
+ TabOrder = 4
Text = '100'
OnKeyPress = NumFieldKeyPress
Items.Strings = (
@@ -436,30 +384,11 @@ object OptionsForm: TOptionsForm
'80'
'100')
end
- object chkEngLayout: TCheckBox
- Left = 236
- Top = 195
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Set English keyboard layout'
- TabOrder = 16
- end
- object chkConfirmClearScript: TCheckBox
- Left = 236
- Top = 175
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Confirm clear script'
- TabOrder = 17
- end
object GroupBox15: TGroupBox
- Left = 6
- Top = 290
- Width = 354
+ Left = 240
+ Top = 296
+ Width = 297
Height = 120
- Anchors = [akLeft, akTop, akRight]
Caption = 'On render complete'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -467,17 +396,13 @@ object OptionsForm: TOptionsForm
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
- TabOrder = 2
- DesignSize = (
- 354
- 120)
+ TabOrder = 0
object btnBrowseSound: TSpeedButton
- Left = 321
+ Left = 265
Top = 41
Width = 24
Height = 24
Hint = 'Browse...'
- Anchors = [akTop, akRight]
Flat = True
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -515,15 +440,13 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnBrowseSoundClick
- ExplicitLeft = 284
end
object btnPlay: TSpeedButton
- Left = 321
+ Left = 265
Top = 14
Width = 24
Height = 24
Hint = 'Play'
- Anchors = [akTop, akRight]
Flat = True
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -561,7 +484,6 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnPlayClick
- ExplicitLeft = 284
end
object Label44: TLabel
Left = 10
@@ -577,12 +499,17 @@ object OptionsForm: TOptionsForm
ParentFont = False
end
object txtSoundFile: TEdit
- Left = 84
+ Left = 73
Top = 42
- Width = 230
+ Width = 188
Height = 21
HelpContext = 1000
- Anchors = [akLeft, akTop, akRight]
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
ParentShowHint = False
ShowHint = False
TabOrder = 0
@@ -590,7 +517,7 @@ object OptionsForm: TOptionsForm
object chkPlaysound: TCheckBox
Left = 8
Top = 18
- Width = 270
+ Width = 251
Height = 17
Caption = 'Play sound'
Font.Charset = ANSI_CHARSET
@@ -630,46 +557,341 @@ object OptionsForm: TOptionsForm
TabOrder = 3
end
end
- object chkAutoSaveXML: TCheckBox
- Left = 236
- Top = 215
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Automatically save pasted parameters'
- TabOrder = 19
+ object gbNotifications: TGroupBox
+ Left = 240
+ Top = 35
+ Width = 297
+ Height = 145
+ Caption = 'Notifications'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 10
+ DesignSize = (
+ 297
+ 145)
+ object cbMissingPlugin: TCheckBox
+ Left = 4
+ Top = 120
+ Width = 282
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Warn when plugins are missing'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ WordWrap = True
+ end
+ object chkConfirmClearScript: TCheckBox
+ Left = 4
+ Top = 80
+ Width = 282
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Confirm clear script'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ end
+ object chkConfirmDel: TCheckBox
+ Left = 4
+ Top = 20
+ Width = 282
+ Height = 17
+ HelpContext = 1005
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Confirm delete'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 2
+ end
+ object chkConfirmExit: TCheckBox
+ Left = 4
+ Top = 40
+ Width = 282
+ Height = 17
+ HelpContext = 1005
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Confirm exit'
+ Color = clBtnFace
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentColor = False
+ ParentFont = False
+ TabOrder = 3
+ end
+ object chkConfirmStopRender: TCheckBox
+ Left = 4
+ Top = 60
+ Width = 282
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Confirm stop render'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 4
+ end
+ object chkConfirmResetUndo: TCheckBox
+ Left = 4
+ Top = 100
+ Width = 282
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Confirm reset editing history'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 5
+ end
end
- object chkRandomTemplates: TCheckBox
- Left = 236
- Top = 95
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Randomize gradient for templates'
- TabOrder = 20
- WordWrap = True
+ object gbDefaults: TGroupBox
+ Left = 240
+ Top = 185
+ Width = 297
+ Height = 105
+ Caption = 'Defaults'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 11
+ DesignSize = (
+ 297
+ 105)
+ object cbUseTemplate: TCheckBox
+ Left = 4
+ Top = 20
+ Width = 381
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Always create blank flame'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ end
+ object chkApplyFlatten: TCheckBox
+ Left = 4
+ Top = 40
+ Width = 381
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Apply flattening to old flames'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ WordWrap = True
+ end
+ object chkAutoSaveXML: TCheckBox
+ Left = 4
+ Top = 60
+ Width = 398
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Automatically save pasted parameters'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 2
+ end
+ object chkEngLayout: TCheckBox
+ Left = 4
+ Top = 80
+ Width = 398
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Set English keyboard layout'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 3
+ end
end
- object chkApplyFlatten: TCheckBox
- Left = 236
- Top = 235
- Width = 258
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Apply flattening to old flames'
- TabOrder = 21
- WordWrap = True
+ object gbAnimation: TGroupBox
+ Left = 8
+ Top = 272
+ Width = 217
+ Height = 125
+ Caption = 'Animation'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
+ TabOrder = 12
+ DesignSize = (
+ 217
+ 125)
+ object pnlFPS: TPanel
+ Left = 8
+ Top = 20
+ Width = 105
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Frames per second'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 1
+ end
+ object pnlAnimPrefix: TPanel
+ Left = 8
+ Top = 72
+ Width = 105
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Frame prefix'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 2
+ end
+ object edAnimPrefix: TEdit
+ Left = 112
+ Top = 72
+ Width = 96
+ Height = 21
+ HelpContext = 1021
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ Text = 'animate-'
+ end
+ object seFPS: TSpinEdit
+ Left = 112
+ Top = 20
+ Width = 96
+ Height = 22
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ MaxValue = 250
+ MinValue = 5
+ ParentFont = False
+ TabOrder = 3
+ Value = 25
+ OnKeyPress = NumFieldKeyPress
+ end
+ object pnlFrameExt: TPanel
+ Left = 8
+ Top = 48
+ Width = 105
+ Height = 21
+ BevelOuter = bvLowered
+ Caption = 'Graphic extension'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 4
+ end
+ object cbFrameExt: TComboBox
+ Left = 112
+ Top = 48
+ Width = 96
+ Height = 21
+ Style = csDropDownList
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ItemIndex = 1
+ ParentFont = False
+ TabOrder = 5
+ Text = '.png'
+ Items.Strings = (
+ '.bmp'
+ '.png'
+ '.jpg')
+ end
+ object chkCreateAnimFolder: TCheckBox
+ Left = 8
+ Top = 100
+ Width = 282
+ Height = 17
+ HelpContext = 1005
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Create a new folder for frames'
+ Color = clBtnFace
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentColor = False
+ ParentFont = False
+ TabOrder = 6
+ end
end
end
object EditorPage: TTabSheet
Caption = 'Editor'
ImageIndex = 8
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 504
- 428)
+ 548
+ 435)
object GroupBox1: TGroupBox
Left = 8
Top = 4
@@ -738,8 +960,8 @@ object OptionsForm: TOptionsForm
object GroupBox21: TGroupBox
Left = 231
Top = 4
- Width = 268
- Height = 128
+ Width = 312
+ Height = 145
Anchors = [akLeft, akTop, akRight]
Caption = 'Editor defaults'
Font.Charset = ANSI_CHARSET
@@ -750,12 +972,12 @@ object OptionsForm: TOptionsForm
ParentFont = False
TabOrder = 1
DesignSize = (
- 268
- 128)
+ 312
+ 145)
object chkAxisLock: TCheckBox
Left = 8
Top = 38
- Width = 257
+ Width = 301
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Lock transform axis'
@@ -772,7 +994,7 @@ object OptionsForm: TOptionsForm
object chkExtendedEdit: TCheckBox
Left = 8
Top = 18
- Width = 257
+ Width = 301
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Extended edit mode'
@@ -789,7 +1011,7 @@ object OptionsForm: TOptionsForm
object chkXaosRebuild: TCheckBox
Left = 8
Top = 58
- Width = 257
+ Width = 301
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Rebuild xaos links'
@@ -806,7 +1028,7 @@ object OptionsForm: TOptionsForm
object chkResetCoefs: TCheckBox
Left = 8
Top = 78
- Width = 257
+ Width = 301
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Reset coefs by double-click'
@@ -821,7 +1043,7 @@ object OptionsForm: TOptionsForm
object chkResetLinear: TCheckBox
Left = 8
Top = 98
- Width = 257
+ Width = 301
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Reset linear when other variation is set'
@@ -833,6 +1055,21 @@ object OptionsForm: TOptionsForm
ParentFont = False
TabOrder = 4
end
+ object chkSyncTriangles: TCheckBox
+ Left = 8
+ Top = 118
+ Width = 301
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Synchronize triangles'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 5
+ end
end
object grpEditorColors: TGroupBox
Left = 8
@@ -1067,7 +1304,7 @@ object OptionsForm: TOptionsForm
object chkEnableEditorPreview: TCheckBox
Left = 8
Top = 256
- Width = 486
+ Width = 530
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Enable editor preview'
@@ -1095,7 +1332,7 @@ object OptionsForm: TOptionsForm
object tbEPTransparency: TTrackBar
Left = 128
Top = 276
- Width = 366
+ Width = 410
Height = 25
Anchors = [akLeft, akTop, akRight]
LineSize = 4
@@ -1107,16 +1344,12 @@ object OptionsForm: TOptionsForm
end
object DisplayPage: TTabSheet
Caption = 'Display'
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 504
- 428)
+ 548
+ 435)
object GroupBox2: TGroupBox
- Left = 243
- Top = 78
+ Left = 245
+ Top = 4
Width = 226
Height = 100
Anchors = [akTop, akRight]
@@ -1236,7 +1469,7 @@ object OptionsForm: TOptionsForm
end
object grpRendering: TGroupBox
Left = 8
- Top = 78
+ Top = 4
Width = 217
Height = 245
Caption = 'Rendering'
@@ -1564,120 +1797,9 @@ object OptionsForm: TOptionsForm
OnKeyPress = NumFloatKeyPress
end
end
- object GroupBox20: TGroupBox
- Left = 8
- Top = 2
- Width = 491
- Height = 73
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Main Window Preview'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = [fsBold]
- ParentFont = False
- TabOrder = 2
- object Label48: TLabel
- Left = 188
- Top = 46
- Width = 11
- Height = 13
- Caption = '%'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- end
- object chkShowTransparency: TCheckBox
- Left = 250
- Top = 20
- Width = 233
- Height = 17
- Caption = 'Show Transparency'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- TabOrder = 2
- end
- object chkExtendMainPreview: TCheckBox
- Left = 8
- Top = 20
- Width = 225
- Height = 17
- Caption = 'Extend preview buffer'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- TabOrder = 0
- end
- object pnlExtension: TPanel
- Left = 8
- Top = 42
- Width = 105
- Height = 21
- Cursor = crArrow
- BevelOuter = bvLowered
- Caption = 'Buffer extension'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- ParentShowHint = False
- ShowHint = True
- TabOrder = 4
- end
- object cbExtendPercent: TComboBox
- Left = 112
- Top = 42
- Width = 73
- Height = 21
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- TabOrder = 1
- OnKeyPress = NumFieldKeyPress
- Items.Strings = (
- '0'
- '10'
- '25'
- '50'
- '100'
- '150'
- '200')
- end
- object chkUseSmallThumbs: TCheckBox
- Left = 250
- Top = 38
- Width = 209
- Height = 31
- Caption = 'Use small thumbnails'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- TabOrder = 3
- WordWrap = True
- end
- end
object GroupBox7: TGroupBox
- Left = 243
- Top = 179
+ Left = 245
+ Top = 110
Width = 226
Height = 100
Anchors = [akTop, akRight]
@@ -1688,7 +1810,7 @@ object OptionsForm: TOptionsForm
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
- TabOrder = 3
+ TabOrder = 2
object pnSTile: TPanel
Left = 8
Top = 24
@@ -1796,8 +1918,8 @@ object OptionsForm: TOptionsForm
end
object rgRotationMode: TRadioGroup
Left = 8
- Top = 358
- Width = 220
+ Top = 292
+ Width = 226
Height = 66
Anchors = [akLeft, akBottom]
Caption = 'Rotation Mode'
@@ -1810,25 +1932,136 @@ object OptionsForm: TOptionsForm
'Rotate image'
'Rotate frame')
ParentFont = False
- TabOrder = 4
+ TabOrder = 3
end
object rgZoomingMode: TRadioGroup
- Left = 243
- Top = 358
+ Left = 8
+ Top = 365
Width = 226
Height = 66
- Anchors = [akRight, akBottom]
+ Anchors = [akLeft, akBottom]
Caption = 'Zooming mode'
Items.Strings = (
'Preserve quality'
'Preserve speed')
+ TabOrder = 4
+ end
+ object GroupBox20: TGroupBox
+ Left = 245
+ Top = 237
+ Width = 226
+ Height = 120
+ Anchors = [akRight, akBottom]
+ Caption = 'Main Window Preview'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
TabOrder = 5
+ object Label48: TLabel
+ Left = 188
+ Top = 46
+ Width = 11
+ Height = 13
+ Caption = '%'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ end
+ object chkShowTransparency: TCheckBox
+ Left = 8
+ Top = 72
+ Width = 233
+ Height = 17
+ Caption = 'Show Transparency'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 2
+ end
+ object chkExtendMainPreview: TCheckBox
+ Left = 8
+ Top = 20
+ Width = 225
+ Height = 17
+ Caption = 'Extend preview buffer'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 0
+ end
+ object pnlExtension: TPanel
+ Left = 8
+ Top = 42
+ Width = 105
+ Height = 21
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Buffer extension'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 4
+ end
+ object cbExtendPercent: TComboBox
+ Left = 112
+ Top = 42
+ Width = 73
+ Height = 21
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ OnKeyPress = NumFieldKeyPress
+ Items.Strings = (
+ '0'
+ '10'
+ '25'
+ '50'
+ '100'
+ '150'
+ '200')
+ end
+ object chkUseSmallThumbs: TCheckBox
+ Left = 8
+ Top = 88
+ Width = 209
+ Height = 31
+ Caption = 'Use small thumbnails'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 3
+ WordWrap = True
+ end
end
object rgEnumMode: TRadioGroup
- Left = 243
- Top = 298
+ Left = 245
+ Top = 365
Width = 226
- Height = 55
+ Height = 66
Anchors = [akRight, akBottom]
Caption = 'Enumerating mode '
Items.Strings = (
@@ -1839,13 +2072,9 @@ object OptionsForm: TOptionsForm
end
object RandomPage: TTabSheet
Caption = 'Random'
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 504
- 428)
+ 548
+ 435)
object gpNumberOfTransforms: TGroupBox
Left = 8
Top = 6
@@ -1951,7 +2180,7 @@ object OptionsForm: TOptionsForm
end
end
object gpFlameTitlePrefix: TGroupBox
- Left = 269
+ Left = 235
Top = 88
Width = 217
Height = 122
@@ -2102,7 +2331,7 @@ object OptionsForm: TOptionsForm
end
end
object gpMutationTransforms: TGroupBox
- Left = 269
+ Left = 235
Top = 6
Width = 214
Height = 75
@@ -2430,15 +2659,11 @@ object OptionsForm: TOptionsForm
object VariationsPage: TTabSheet
Caption = 'Variations'
ImageIndex = 4
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 504
- 428)
+ 548
+ 435)
object btnSetAll: TButton
- Left = 410
+ Left = 454
Top = 24
Width = 91
Height = 25
@@ -2449,7 +2674,7 @@ object OptionsForm: TOptionsForm
OnClick = btnSetAllClick
end
object btnClearAll: TButton
- Left = 410
+ Left = 454
Top = 52
Width = 91
Height = 25
@@ -2460,7 +2685,7 @@ object OptionsForm: TOptionsForm
OnClick = btnClearAllClick
end
object btnInvert: TButton
- Left = 410
+ Left = 454
Top = 80
Width = 91
Height = 25
@@ -2473,22 +2698,18 @@ object OptionsForm: TOptionsForm
object VarsPages: TPageControl
Left = 0
Top = 0
- Width = 403
- Height = 426
+ Width = 447
+ Height = 433
ActivePage = tabRandomVars
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 2
object tabRandomVars: TTabSheet
Caption = 'Random choise'
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
object clbVarEnabled: TCheckListBox
Left = 0
Top = 0
- Width = 395
- Height = 398
+ Width = 439
+ Height = 405
Align = alClient
Columns = 2
ItemHeight = 13
@@ -2498,15 +2719,11 @@ object OptionsForm: TOptionsForm
end
object tabFavouriteVars: TTabSheet
Caption = 'Favourites'
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
object clbVarFavourite: TCheckListBox
Left = 0
Top = 0
- Width = 395
- Height = 398
+ Width = 439
+ Height = 405
Align = alClient
Columns = 2
ItemHeight = 13
@@ -2519,16 +2736,9 @@ object OptionsForm: TOptionsForm
object GradientPage: TTabSheet
Caption = 'Gradient'
ImageIndex = 5
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
- DesignSize = (
- 504
- 428)
object GroupBox13: TGroupBox
- Left = 8
- Top = 186
+ Left = 235
+ Top = 13
Width = 209
Height = 79
Caption = 'Smooth palette'
@@ -2721,11 +2931,10 @@ object OptionsForm: TOptionsForm
end
end
object GroupBox18: TGroupBox
- Left = 266
- Top = 8
+ Left = 8
+ Top = 188
Width = 209
Height = 81
- Anchors = [akTop, akRight]
Caption = 'Saturation range'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -2830,7 +3039,7 @@ object OptionsForm: TOptionsForm
end
object GroupBox22: TGroupBox
Left = 8
- Top = 96
+ Top = 98
Width = 209
Height = 81
Caption = 'Luminance range'
@@ -2938,11 +3147,10 @@ object OptionsForm: TOptionsForm
end
end
object GroupBox23: TGroupBox
- Left = 266
- Top = 96
+ Left = 8
+ Top = 278
Width = 209
Height = 81
- Anchors = [akTop, akRight]
Caption = 'Number of nodes'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -3051,11 +3259,10 @@ object OptionsForm: TOptionsForm
end
end
object rgColorBlend: TRadioGroup
- Left = 266
- Top = 183
- Width = 209
+ Left = 235
+ Top = 189
+ Width = 265
Height = 82
- Anchors = [akTop, akRight]
Caption = 'Color blending '
ItemIndex = 0
Items.Strings = (
@@ -3064,31 +3271,82 @@ object OptionsForm: TOptionsForm
'No blend')
TabOrder = 5
end
- object chkEqualStripes: TCheckBox
- Left = 13
- Top = 275
- Width = 491
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = ' Use equal color stripes'
- Checked = True
- State = cbChecked
+ object gbGradDefaults: TGroupBox
+ Left = 235
+ Top = 98
+ Width = 265
+ Height = 85
+ Caption = 'Defaults'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = [fsBold]
+ ParentFont = False
TabOrder = 6
- WordWrap = True
+ DesignSize = (
+ 265
+ 85)
+ object chkEqualStripes: TCheckBox
+ Left = 4
+ Top = 60
+ Width = 558
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = ' Use equal color stripes'
+ Checked = True
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ State = cbChecked
+ TabOrder = 0
+ WordWrap = True
+ end
+ object chkRandomTemplates: TCheckBox
+ Left = 4
+ Top = 40
+ Width = 342
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Randomize gradient for templates'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 1
+ WordWrap = True
+ end
+ object chkOldPaletteFormat: TCheckBox
+ Left = 5
+ Top = 20
+ Width = 342
+ Height = 17
+ Anchors = [akLeft, akTop, akRight]
+ Caption = 'Save gradient in old file format'
+ Font.Charset = ANSI_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ TabOrder = 2
+ WordWrap = True
+ end
end
end
object UPRPage: TTabSheet
Caption = 'UPR'
ImageIndex = 5
- ExplicitLeft = 0
- ExplicitTop = 0
- ExplicitWidth = 0
- ExplicitHeight = 0
DesignSize = (
- 504
- 428)
+ 548
+ 435)
object chkAdjustDensity: TCheckBox
- Left = 274
+ Left = 260
Top = 264
Width = 228
Height = 33
@@ -3098,7 +3356,7 @@ object OptionsForm: TOptionsForm
WordWrap = True
end
object GroupBox11: TGroupBox
- Left = 274
+ Left = 260
Top = 184
Width = 228
Height = 81
@@ -3294,7 +3552,7 @@ object OptionsForm: TOptionsForm
object GroupBox4: TGroupBox
Left = 8
Top = 6
- Width = 494
+ Width = 480
Height = 83
Anchors = [akLeft, akTop, akRight]
Caption = 'Coloring algorithm'
@@ -3373,7 +3631,7 @@ object OptionsForm: TOptionsForm
object GroupBox5: TGroupBox
Left = 8
Top = 95
- Width = 494
+ Width = 480
Height = 82
Anchors = [akLeft, akTop, akRight]
Caption = 'Fractal formula'
@@ -3454,11 +3712,11 @@ object OptionsForm: TOptionsForm
Caption = 'Environment'
ImageIndex = 7
DesignSize = (
- 504
- 428)
- object btnDefGradient: TSpeedButton
- Left = 474
- Top = 7
+ 548
+ 435)
+ object btnDefParams: TSpeedButton
+ Left = 520
+ Top = 5
Width = 24
Height = 24
Hint = 'Browse...'
@@ -3499,11 +3757,10 @@ object OptionsForm: TOptionsForm
ParentFont = False
ParentShowHint = False
ShowHint = True
- OnClick = btnDefGradientClick
- ExplicitLeft = 437
+ OnClick = btnDefParamsClick
end
object btnSmooth: TSpeedButton
- Left = 474
+ Left = 520
Top = 31
Width = 24
Height = 24
@@ -3546,10 +3803,9 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnSmoothClick
- ExplicitLeft = 437
end
- object SpeedButton2: TSpeedButton
- Left = 474
+ object btnDefLibrary: TSpeedButton
+ Left = 520
Top = 55
Width = 24
Height = 24
@@ -3591,12 +3847,11 @@ object OptionsForm: TOptionsForm
ParentFont = False
ParentShowHint = False
ShowHint = True
- OnClick = SpeedButton2Click
- ExplicitLeft = 437
+ OnClick = btnDefLibraryClick
end
object btnRenderer: TSpeedButton
- Left = 474
- Top = 79
+ Left = 521
+ Top = 83
Width = 24
Height = 24
Hint = 'Browse...'
@@ -3638,11 +3893,10 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnRendererClick
- ExplicitLeft = 437
end
object btnHelp: TSpeedButton
- Left = 474
- Top = 103
+ Left = 520
+ Top = 105
Width = 24
Height = 24
Hint = 'Browse...'
@@ -3684,7 +3938,6 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnHelpClick
- ExplicitLeft = 437
end
object Label49: TLabel
Left = 245
@@ -3693,52 +3946,8 @@ object OptionsForm: TOptionsForm
Height = 13
Caption = 'minutes'
end
- object btnFindDefaultSaveFile: TSpeedButton
- Left = 437
- Top = 272
- 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
- FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
- 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F
- 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13
- 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708
- 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3
- 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367
- 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51
- C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF
- 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC
- EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67
- D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2
- 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8
- FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788
- A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6
- A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788
- 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89
- 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA
- ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00
- FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF
- 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
- FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
- FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
- 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
- ParentFont = False
- ParentShowHint = False
- ShowHint = True
- OnClick = btnFindDefaultSaveFileClick
- end
object btnPluginPath: TSpeedButton
- Left = 474
+ Left = 520
Top = 128
Width = 24
Height = 24
@@ -3781,10 +3990,9 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnPluginPathClick
- ExplicitLeft = 437
end
object btnSShotPath: TSpeedButton
- Left = 474
+ Left = 520
Top = 155
Width = 24
Height = 24
@@ -3827,10 +4035,9 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnSShotPathClick
- ExplicitLeft = 437
end
object btnDefScript: TSpeedButton
- Left = 474
+ Left = 520
Top = 181
Width = 24
Height = 24
@@ -3873,7 +4080,50 @@ object OptionsForm: TOptionsForm
ParentShowHint = False
ShowHint = True
OnClick = btnDefScriptClick
- ExplicitLeft = 437
+ end
+ object btnFindDefaultSaveFile: TSpeedButton
+ Left = 440
+ Top = 272
+ 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
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F
+ 607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13
+ 18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708
+ 88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3
+ 8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367
+ 805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51
+ C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF
+ 7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC
+ EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67
+ D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2
+ 98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8
+ FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788
+ A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6
+ A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788
+ 93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89
+ 9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA
+ ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
+ FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
+ FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
+ 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
+ ParentFont = False
+ ParentShowHint = False
+ ShowHint = True
+ OnClick = btnFindDefaultSaveFileClick
end
object chkRememberLastOpen: TCheckBox
Left = 8
@@ -3900,7 +4150,7 @@ object OptionsForm: TOptionsForm
object txtDefParameterFile: TEdit
Left = 146
Top = 8
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -3926,7 +4176,7 @@ object OptionsForm: TOptionsForm
object txtDefSmoothFile: TEdit
Left = 146
Top = 32
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1001
Anchors = [akLeft, akTop, akRight]
@@ -3978,7 +4228,7 @@ object OptionsForm: TOptionsForm
object txtLibrary: TEdit
Left = 146
Top = 56
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -3990,7 +4240,7 @@ object OptionsForm: TOptionsForm
object txtRenderer: TEdit
Left = 146
Top = 80
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -4002,7 +4252,7 @@ object OptionsForm: TOptionsForm
object txtHelp: TEdit
Left = 146
Top = 104
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -4081,7 +4331,7 @@ object OptionsForm: TOptionsForm
Left = 8
Top = 329
Width = 457
- Height = 73
+ Height = 56
Caption = 'Chaotica 0.45+'
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -4092,9 +4342,9 @@ object OptionsForm: TOptionsForm
TabOrder = 16
DesignSize = (
457
- 73)
+ 56)
object btnChaotica: TSpeedButton
- Left = 425
+ Left = 429
Top = 18
Width = 24
Height = 24
@@ -4156,21 +4406,6 @@ object OptionsForm: TOptionsForm
ShowHint = True
TabOrder = 1
end
- object cbC64: TCheckBox
- Left = 8
- Top = 48
- Width = 441
- Height = 17
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Use x64-version if possible'
- Font.Charset = ANSI_CHARSET
- Font.Color = clWindowText
- Font.Height = -11
- Font.Name = 'Tahoma'
- Font.Style = []
- ParentFont = False
- TabOrder = 2
- end
object txtChaotica: TEdit
Left = 136
Top = 20
@@ -4198,7 +4433,7 @@ object OptionsForm: TOptionsForm
Caption = 'File name (x64)'
ParentShowHint = False
ShowHint = True
- TabOrder = 3
+ TabOrder = 2
Visible = False
end
end
@@ -4219,7 +4454,7 @@ object OptionsForm: TOptionsForm
object txtPluginFolder: TEdit
Left = 146
Top = 130
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -4245,7 +4480,7 @@ object OptionsForm: TOptionsForm
object txtSShotFolder: TEdit
Left = 146
Top = 156
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -4270,7 +4505,7 @@ object OptionsForm: TOptionsForm
object txtDefScript: TEdit
Left = 146
Top = 182
- Width = 329
+ Width = 373
Height = 21
HelpContext = 1000
Anchors = [akLeft, akTop, akRight]
@@ -4280,29 +4515,8 @@ object OptionsForm: TOptionsForm
end
end
end
- object btnOK: TButton
- Left = 327
- Top = 469
- Width = 86
- Height = 25
- Anchors = [akRight, akBottom]
- Caption = 'OK'
- Default = True
- TabOrder = 0
- OnClick = btnOKClick
- end
- object btnCancel: TButton
- Left = 422
- Top = 469
- Width = 86
- Height = 25
- Anchors = [akRight, akBottom]
- Caption = 'Cancel'
- TabOrder = 1
- OnClick = btnCancelClick
- end
object OpenDialog: TOpenDialog
- Left = 424
- Top = 392
+ Left = 24
+ Top = 448
end
end
diff --git a/Forms/Options.pas b/Forms/Options.pas
index b997b46..36fe4d1 100644
--- a/Forms/Options.pas
+++ b/Forms/Options.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -22,38 +22,30 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
//{$D-,L-,O+,Q-,R-,Y-,S-}
+
unit Options;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ComCtrls, ExtCtrls, Buttons, Registry, Mask, CheckLst,
- MMSystem, Translation, RegexHelper, FileCtrl, StrUtils, ShellAPI, ShlObj,
- Vcl.Samples.Spin;
+ StdCtrls, ComCtrls, ExtCtrls, Buttons, Registry, CheckLst,
+ MMSystem, FileCtrl, StrUtils, ShellAPI, ShlObj, Vcl.Samples.Spin;
type
TOptionsForm = class(TForm)
btnOK: TButton;
btnCancel: TButton;
OpenDialog: TOpenDialog;
- GroupBox15: TGroupBox;
- btnBrowseSound: TSpeedButton;
- btnPlay: TSpeedButton;
- Label44: TLabel;
- txtSoundFile: TEdit;
- chkPlaysound: TCheckBox;
Tabs: TPageControl;
GeneralPage: TTabSheet;
- SpeedButton1: TSpeedButton;
+ btnLanguage: TSpeedButton;
pnlJPEGQuality: TPanel;
chkConfirmDel: TCheckBox;
- chkOldPaletteFormat: TCheckBox;
chkConfirmExit: TCheckBox;
chkConfirmStopRender: TCheckBox;
cbUseTemplate: TCheckBox;
cbMissingPlugin: TCheckBox;
- cbEmbedThumbs: TCheckBox;
pnlMultithreading: TPanel;
cbNrTheads: TComboBox;
pnlPNGTransparency: TPanel;
@@ -72,14 +64,29 @@ type
txtLanguageFile: TComboBox;
cbPNGTransparency: TComboBox;
txtJPEGquality: TComboBox;
+ chkEngLayout: TCheckBox;
+ chkConfirmClearScript: TCheckBox;
+ GroupBox15: TGroupBox;
+ btnBrowseSound: TSpeedButton;
+ btnPlay: TSpeedButton;
+ Label44: TLabel;
+ txtSoundFile: TEdit;
+ chkPlaysound: TCheckBox;
+ chkShowRenderStats: TCheckBox;
+ chkShowRenderImage: TCheckBox;
+ chkAutoSaveXML: TCheckBox;
+ chkApplyFlatten: TCheckBox;
EditorPage: TTabSheet;
GroupBox1: TGroupBox;
chkUseXFormColor: TCheckBox;
chkHelpers: TCheckBox;
+ chkShowAllXforms: TCheckBox;
GroupBox21: TGroupBox;
chkAxisLock: TCheckBox;
chkExtendedEdit: TCheckBox;
chkXaosRebuild: TCheckBox;
+ chkResetCoefs: TCheckBox;
+ chkResetLinear: TCheckBox;
grpEditorColors: TGroupBox;
pnlBackground: TPanel;
pnlReferenceC: TPanel;
@@ -95,6 +102,9 @@ type
shGC1: TShape;
pnlGridColor2: TPanel;
shGC2: TShape;
+ pnlReflection: TPanel;
+ pnlReflectionC: TPanel;
+ shReflection: TShape;
chkEnableEditorPreview: TCheckBox;
Panel48: TPanel;
tbEPTransparency: TTrackBar;
@@ -121,6 +131,19 @@ type
txtBrightness: TEdit;
txtGamma: TEdit;
txtSampleDensity: TEdit;
+ pnlFuse: TPanel;
+ txtFuse: TSpinEdit;
+ pnlContrast: TPanel;
+ txtContrast: TEdit;
+ GroupBox7: TGroupBox;
+ pnSTile: TPanel;
+ pnRTile: TPanel;
+ pnHexTile: TPanel;
+ txtHexTile: TEdit;
+ txtRTile: TEdit;
+ txtSTile: TEdit;
+ rgRotationMode: TRadioGroup;
+ rgZoomingMode: TRadioGroup;
GroupBox20: TGroupBox;
Label48: TLabel;
chkShowTransparency: TCheckBox;
@@ -128,6 +151,7 @@ type
pnlExtension: TPanel;
cbExtendPercent: TComboBox;
chkUseSmallThumbs: TCheckBox;
+ rgEnumMode: TRadioGroup;
RandomPage: TTabSheet;
gpNumberOfTransforms: TGroupBox;
udMinXforms: TUpDown;
@@ -143,6 +167,9 @@ type
Panel12: TPanel;
txtBatchSize: TEdit;
txtRandomPrefix: TEdit;
+ pnlRandBackground: TPanel;
+ pnlRandBackColor: TPanel;
+ shRandBackColor: TShape;
gpMutationTransforms: TGroupBox;
udMinMutate: TUpDown;
udMaxMutate: TUpDown;
@@ -166,7 +193,12 @@ type
VariationsPage: TTabSheet;
btnSetAll: TButton;
btnClearAll: TButton;
+ btnInvert: TButton;
+ VarsPages: TPageControl;
+ tabRandomVars: TTabSheet;
clbVarEnabled: TCheckListBox;
+ tabFavouriteVars: TTabSheet;
+ clbVarFavourite: TCheckListBox;
GradientPage: TTabSheet;
GroupBox13: TGroupBox;
Panel28: TPanel;
@@ -201,6 +233,8 @@ type
txtMinNodes: TEdit;
udMaxNodes: TUpDown;
txtMaxNodes: TEdit;
+ rgColorBlend: TRadioGroup;
+ chkEqualStripes: TCheckBox;
UPRPage: TTabSheet;
chkAdjustDensity: TCheckBox;
GroupBox11: TGroupBox;
@@ -226,13 +260,16 @@ type
txtFFFile: TEdit;
txtFFIdent: TEdit;
PathsPage: TTabSheet;
- btnDefGradient: TSpeedButton;
+ btnDefParams: TSpeedButton;
btnSmooth: TSpeedButton;
- SpeedButton2: TSpeedButton;
+ btnDefLibrary: TSpeedButton;
btnRenderer: TSpeedButton;
btnHelp: TSpeedButton;
Label49: TLabel;
btnFindDefaultSaveFile: TSpeedButton;
+ btnPluginPath: TSpeedButton;
+ btnSShotPath: TSpeedButton;
+ btnDefScript: TSpeedButton;
chkRememberLastOpen: TCheckBox;
Panel39: TPanel;
txtDefParameterFile: TEdit;
@@ -252,62 +289,35 @@ type
GroupBox3: TGroupBox;
btnChaotica: TSpeedButton;
Panel47: TPanel;
- cbC64: TCheckBox;
txtChaotica: TEdit;
Panel49: TPanel;
- btnPluginPath: TSpeedButton;
Panel50: TPanel;
txtPluginFolder: TEdit;
- pnlReflection: TPanel;
- pnlReflectionC: TPanel;
- shReflection: TShape;
- GroupBox7: TGroupBox;
- pnSTile: TPanel;
- pnRTile: TPanel;
- pnHexTile: TPanel;
- txtHexTile: TEdit;
- txtRTile: TEdit;
- txtSTile: TEdit;
- pnlFuse: TPanel;
- txtFuse: TSpinEdit;
- chkEngLayout: TCheckBox;
- chkConfirmClearScript: TCheckBox;
pnlScreenShot: TPanel;
- btnSShotPath: TSpeedButton;
txtSShotFolder: TEdit;
- rgRotationMode: TRadioGroup;
- rgZoomingMode: TRadioGroup;
- chkShowRenderStats: TCheckBox;
- btnDefScript: TSpeedButton;
pnlScriptFile: TPanel;
txtDefScript: TEdit;
- chkAutoSaveXML: TCheckBox;
- rgColorBlend: TRadioGroup;
- chkEqualStripes: TCheckBox;
- pnlContrast: TPanel;
- txtContrast: TEdit;
+ chkSyncTriangles: TCheckBox;
+ gbNotifications: TGroupBox;
+ gbDefaults: TGroupBox;
+ chkOldPaletteFormat: TCheckBox;
chkRandomTemplates: TCheckBox;
- chkResetCoefs: TCheckBox;
- chkApplyFlatten: TCheckBox;
- pnlRandBackground: TPanel;
- pnlRandBackColor: TPanel;
- shRandBackColor: TShape;
- chkResetLinear: TCheckBox;
- btnInvert: TButton;
- chkShowAllXforms: TCheckBox;
- VarsPages: TPageControl;
- tabRandomVars: TTabSheet;
- tabFavouriteVars: TTabSheet;
- clbVarFavourite: TCheckListBox;
- rgEnumMode: TRadioGroup;
- chkShowRenderImage: TCheckBox;
+ gbGradDefaults: TGroupBox;
+ chkConfirmResetUndo: TCheckBox;
+ gbAnimation: TGroupBox;
+ pnlFPS: TPanel;
+ pnlAnimPrefix: TPanel;
+ edAnimPrefix: TEdit;
+ seFPS: TSpinEdit;
+ pnlFrameExt: TPanel;
+ cbFrameExt: TComboBox;
+ chkCreateAnimFolder: TCheckBox;
procedure chkEnableEditorPreviewClick(Sender: TObject);
procedure btnChaoticaClick(Sender: TObject);
- procedure SpeedButton1Click(Sender: TObject);
- procedure btnCancelClick(Sender: TObject);
+ procedure btnLanguageClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnOKClick(Sender: TObject);
- procedure btnDefGradientClick(Sender: TObject);
+ procedure btnDefParamsClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnSmoothClick(Sender: TObject);
procedure cmbSymTypeChange(Sender: TObject);
@@ -326,7 +336,7 @@ type
procedure txtMinMutateChange(Sender: TObject);
procedure txtMaxMutateChange(Sender: TObject);
procedure btnRendererClick(Sender: TObject);
- procedure SpeedButton2Click(Sender: TObject);
+ procedure btnDefLibraryClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure pnlBackColorClick(Sender: TObject);
procedure pnlReferenceClick(Sender: TObject);
@@ -390,12 +400,7 @@ implementation
{$R *.DFM}
uses
- Main, Global, Editor, ControlPoint, XFormMan, Adjust, FormRender;
-
-procedure TOptionsForm.btnCancelClick(Sender: TObject);
-begin
- Close;
-end;
+ Main, Global, Editor, ControlPoint, XFormMan, Adjust, FormRender, Translation;
procedure TOptionsForm.UpdateShapeColors;
begin
@@ -439,7 +444,6 @@ begin
txtNumtries.text := IntToStr(Numtries);
txtTryLength.text := IntToStr(Trylength);
udBatchSize.Position := BatchSize;
-// chkResize.checked := ResizeOnLoad;
if NrTreads <= 1 then
cbNrTheads.ItemIndex := 0 // AV: MT off
@@ -471,17 +475,17 @@ begin
chkConfirmExit.Checked := ConfirmExit;
chkConfirmStopRender.Checked := ConfirmStopRender;
chkConfirmClearScript.Checked := ConfirmClearScript; // AV
+ chkConfirmResetUndo.Checked := ConfirmResetUndo; // AV
chkRememberLastOpen.Checked := RememberLastOpenFile;
chkUseSmallThumbs.Checked := UseSmallThumbnails;
cbUseTemplate.Checked := AlwaysCreateBlankFlame;
cbMissingPlugin.Checked := WarnOnMissingPlugin;
- cbEmbedThumbs.Checked := EmbedThumbnails;
+ // cbEmbedThumbs.Checked := EmbedThumbnails;
chkEngLayout.Checked := SetEngLayout; // AV
chkAutoSaveXML.Checked := AutoSaveXML; // AV
chkEqualStripes.Checked := EqualStripes;
chkRandomTemplates.Checked := RandomizeTemplates;
chkApplyFlatten.Checked := ApplyFlatten;
- //cbSinglePrecision.Checked := SingleBuffer;
rgRotationMode.ItemIndex := MainForm_RotationMode;
if PreserveQuality then
@@ -495,7 +499,11 @@ begin
chkPlaySound.Checked := PlaySoundOnRenderComplete;
txtSoundFile.Text := RenderCompleteSoundFile;
- //cbInternalBitsPerSample.ItemIndex := InternalBitsPerSample;
+ { Animation }
+ seFPS.Value := AnimFPS;
+ edAnimPrefix.Text := defAnimPrefix;
+ cbFrameExt.ItemIndex := defFrameExt;
+ chkCreateAnimFolder.Checked := CreateAnimFolder;
{ Editor }
chkUseXFormColor.checked := UseTransformColors;
@@ -509,6 +517,7 @@ begin
chkEnableEditorPreviewClick(self);
chkResetCoefs.Checked := AllowResetCoefs;
chkResetLinear.Checked := AllowResetLinear;
+ chkSyncTriangles.Checked := UseTriangleSync;
{ Display tab }
txtSampleDensity.Text := FloatToStr(defSampleDensity);
@@ -529,12 +538,12 @@ begin
txtSTile.Text := FloatToStr(Round6(SquareTR)); // AV
txtRTile.Text := FloatToStr(RhombTR); // AV
- pnlBackColor.Color := TColor(EditorBkgColor);
+ pnlBackColor.Color := EditorBkgColor;
pnlGridColor1.Color := GridColor1;
pnlGridColor2.Color := GridColor2;
- pnlReference.color := TColor(ReferenceTriangleColor);
- pnlReflectionC.Color := TColor(FlipColor); // AV
- pnlHelpersColor.Color := TColor(HelpersColor); // AV
+ pnlReference.color := ReferenceTriangleColor;
+ pnlReflectionC.Color := FlipColor; // AV
+ pnlHelpersColor.Color := HelpersColor; // AV
cbPNGTransparency.ItemIndex := PNGTransparency;
chkShowTransparency.Checked := ShowTransparency;
@@ -560,7 +569,7 @@ begin
udSymOrder.Position := SymmetryOrder;
udSymNVars.Position := SymmetryNVars;
- pnlRandBackColor.Color := TColor(RandBackColor); // AV
+ pnlRandBackColor.Color := RandBackColor; // AV
chkKeepBackgroundClick(nil); // AV
{ Variations tab }
@@ -607,19 +616,13 @@ begin
cbEnableAutosaveClick(nil);
- pnlCenterLine.Color := TColor(LineCenterColor);
- pnlThirdsLine.Color := TColor(LineThirdsColor);
- pnlGRLine.Color := TColor(LineGRColor);
+ pnlCenterLine.Color := LineCenterColor;
+ pnlThirdsLine.Color := LineThirdsColor;
+ pnlGRLine.Color := LineGRColor;
cbGL.Checked := EnableGuides;
cbGLClick(nil);
txtChaotica.Text := ChaoticaPath;
- {$ifdef Apo7X64}
- cbc64.Checked := true;
- {$else}
- cbC64.Checked := UseX64IfPossible;
- {$endif}
-
txtPluginFolder.Text := PluginPath;
txtSShotFolder.Text := ScreenShotPath;
@@ -627,7 +630,8 @@ begin
j := -1;
txtLanguageFile.Items.Clear;
- for i := 0 to AvailableLanguages.Count-1 do begin
+ for i := 0 to AvailableLanguages.Count-1 do
+ begin
if AvailableLanguages.Strings[i] = '' then begin
txtLanguageFile.Items.Add('Default (English)');
end else begin
@@ -637,7 +641,6 @@ begin
end;
if (lowercase(AvailableLanguages.Strings[i]) = lowercase(languagefile)) then
j := i;
-
end;
txtLanguageFile.ItemIndex := j;
end;
@@ -666,8 +669,8 @@ end;
procedure TOptionsForm.NumFloatKeyPress(Sender: TObject; var Key: Char);
begin
- if (Key = ',') then Key := FormatSettings.DecimalSeparator;
- if not CharinSet(Key,['0'..'9', #8, #13, FormatSettings.DecimalSeparator])
+ if (Key = ',') then Key := '.';
+ if not CharinSet(Key,['0'..'9', #8, #13, '.'])
then Key:= #0;
end;
@@ -689,17 +692,23 @@ begin
if vars = false then
Variations[0] := true;
- warn := (LanguageFile <> AvailableLanguages[txtLanguageFile.ItemIndex])
- { or (UseSmallThumbnails <> chkUseSmallThumbs.Checked)}; // AV: fixed
+ warn := (SetEngLayout <> chkEngLayout.Checked);
+ { AV: eliminate "List index out of bounds" error and memory leak
+ if 32- and 64-bit Apophysis paths are different }
+ i := txtLanguageFile.ItemIndex;
+ if (i >= 0) then
+ warn := warn or (LanguageFile <> AvailableLanguages[i]); // AV
- { General tab }
- JPEGQuality := StrToInt(txtJPEGQuality.text);
- Numtries := StrToInt(txtNumtries.text);
- if NumTries < 1 then Numtries := 1;
- Trylength := StrToInt(txtTrylength.text);
- if Trylength < 100 then trylength := 100;
+ { General tab }
+ JPEGQuality := StrToIntDef(txtJPEGQuality.text, 100);
if JPEGQuality > 100 then JPEGQuality := 100;
if JPEGQuality < 1 then JPEGQuality := 100;
+
+ Numtries := StrToIntDef(txtNumtries.text, 1);
+ if NumTries < 1 then Numtries := 1;
+ Trylength := StrToIntDef(txtTrylength.text, 100);
+ if Trylength < 100 then trylength := 100;
+
BatchSize := udBatchSize.Position;
if BatchSize < 1 then BatchSize := 1;
if BatchSize > 300 then BatchSize := 300;
@@ -717,28 +726,35 @@ begin
RememberLastOpenFile := chkRememberLastOpen.Checked;
UseSmallThumbnails := chkUseSmallThumbs.Checked;
AlwaysCreateBlankFlame := cbUseTemplate.Checked;
- EmbedThumbnails := cbEmbedThumbs.Checked;
+ // EmbedThumbnails := cbEmbedThumbs.Checked;
WarnOnMissingPlugin := cbMissingPlugin.Checked;
SetEngLayout := chkEngLayout.Checked; // AV
ConfirmClearScript := chkConfirmClearScript.Checked; // AV
+ ConfirmResetUndo := chkConfirmResetUndo.Checked; // AV
AutoSaveXML := chkAutoSaveXML.Checked; // AV
EqualStripes := chkEqualStripes.Checked; // AV
RandomizeTemplates := chkRandomTemplates.Checked;
ApplyFlatten := chkApplyFlatten.Checked;
- LanguageFile := AvailableLanguages.Strings[txtLanguageFile.ItemIndex];
- //SingleBuffer := cbSinglePrecision.Checked;
+ { AV: eliminate "List index out of bounds" error and memory leak
+ if 32- and 64-bit Apophysis paths are different }
+ if (i >= 0) then LanguageFile := AvailableLanguages.Strings[i];
MainForm_RotationMode := rgRotationMode.ItemIndex;
PreserveQuality := (rgZoomingMode.ItemIndex = 0);
FlameEnumMode := rgEnumMode.ItemIndex; // AV
- //InternalBitsPerSample := cbInternalBitsPerSample.ItemIndex;
LineCenterColor := pnlCenterLine.Color;
LineThirdsColor := pnlThirdsLine.Color;
LineGRColor := pnlGRLine.Color;
EnableGuides := cbGL.Checked;
- // Editor
+ { Animation }
+ AnimFPS := seFPS.Value;
+ defAnimPrefix := edAnimPrefix.Text;
+ defFrameExt := cbFrameExt.ItemIndex;
+ CreateAnimFolder := chkCreateAnimFolder.Checked;
+
+ { Editor }
UseTransformColors := chkUseXFormColor.checked;
HelpersEnabled := chkHelpers.Checked;
ShowAllXforms := chkShowAllXforms.Checked;
@@ -750,101 +766,84 @@ begin
EditorPreviewTransparency := tbEPTransparency.Position;
AllowResetCoefs := chkResetCoefs.Checked;
AllowResetLinear := chkResetLinear.Checked;
+ UseTriangleSync := chkSyncTriangles.Checked;
{ Display tab }
- try
- defSampleDensity := StrToFloat(txtSampleDensity.Text);
- if defSampleDensity > 100 then defSampleDensity := 100;
- if defSampleDensity <= 0 then defSampleDensity := 0.1;
- except
- defSampleDensity := 5;
- end;
- try
- defGamma := StrToFloat(txtGamma.Text);
- if defGamma < 0.1 then defGamma := 0.1;
- except
- defGamma := 4;
- end;
- try
- defBrightness := StrToFloat(txtBrightness.Text);
- if defBrightness < 0.1 then defBrightness := 0.1;
- except
- defBrightness := 4;
- end;
- try // AV
- defContrast := StrToFloat(txtContrast.Text);
- if defContrast < 0.1 then defContrast := 0.1;
- if defContrast > 10 then defContrast := 10;
- except
- defContrast := 1;
- end;
- try
- defVibrancy := StrToFloat(txtVibrancy.Text);
- if defVibrancy < 0 then defVibrancy := 0.1;
- except
- defVibrancy := 1;
- end;
- try
- defFilterRadius := StrToFloat(txtFilterRadius.Text);
+ // AV: replaced all try-except blocks by a more convenient StrToFloatDef
+
+ defSampleDensity := StrToFloatDef(txtSampleDensity.Text, 5);
+ if defSampleDensity > 100 then
+ defSampleDensity := 100
+ else if defSampleDensity <= 0 then
+ defSampleDensity := 0.1;
+
+ defGamma := StrToFloatDef(txtGamma.Text, 4);
+ if defGamma < 0.1 then
+ defGamma := 0.1
+ else if defGamma > 10 then
+ defGamma := 10;
+
+ defBrightness := StrToFloatDef(txtBrightness.Text, 4);
+ if defBrightness < 0.1 then
+ defBrightness := 0.1
+ else if defBrightness > 100 then
+ defBrightness := 100;
+
+ defContrast := StrToFloatDef(txtContrast.Text, 1);
+ if defContrast < 0.1 then
+ defContrast := 0.1
+ else if defContrast > 10 then
+ defContrast := 10;
+
+ defVibrancy := StrToFloatDef(txtVibrancy.Text, 1);
+ if defVibrancy < 0.1 then defVibrancy := 0.1;
+
+ defFilterRadius := StrToFloatDef(txtFilterRadius.Text, 0.2);
if defFilterRadius <= 0 then defFilterRadius := 0.1;
- except
- defFilterRadius := 0.2;
- end;
- try
- defGammaThreshold := StrToFloat(txtGammaThreshold.Text);
- if defGammaThreshold < 0 then
- except
- defGammaThreshold := 0.01;
- end;
- defOversample := StrToInt(txtOversample.Text);
- if defOversample > 4 then defOversample := 4;
- if defOversample < 1 then defOversample := 1;
- try
- prevLowQuality := StrToFloat(txtLowQuality.Text);
- if prevLowQuality > 100 then prevLowQuality := 100;
- if prevLowQuality < 0.01 then
- except
- prevLowQuality := 0.1;
- end;
- try
- prevMediumQuality := StrToFloat(txtMediumQuality.Text);
- if prevMediumQuality > 1000 then prevMediumQuality := 1000;
- if prevMediumQuality < 0.01 then prevMediumQuality := 0.01;
- except
- prevMediumQuality := 1;
- end;
- try
- prevHighQuality := StrToFloat(txtHighQuality.Text);
- if prevHighQuality > 10000 then prevHighQuality := 10000;
- if prevHighQuality < 0.01 then prevHighQuality := 0.01;
- except
- prevHighQuality := 5;
- end;
+
+ defGammaThreshold := StrToFloatDef(txtGammaThreshold.Text, 0);
+ if defGammaThreshold < 0 then defGammaThreshold := 0;
+
+ defOversample := StrToIntDef(txtOversample.Text, 1);
+ if defOversample > 4 then
+ defOversample := 4
+ else if defOversample < 1 then
+ defOversample := 1;
+
+ prevLowQuality := StrToFloatDef(txtLowQuality.Text, 0.1);
+ if prevLowQuality > 100 then
+ prevLowQuality := 100
+ else if prevLowQuality < 0.01 then
+ prevLowQuality := 0.1;
+
+ prevMediumQuality := StrToFloatDef(txtMediumQuality.Text, 1);
+ if prevMediumQuality > 500 then
+ prevMediumQuality := 500
+ else if prevMediumQuality < 0.01 then
+ prevMediumQuality := 0.01;
+
+ prevHighQuality := StrToFloatDef(txtHighQuality.Text, 5);
+ if prevHighQuality > 1000 then
+ prevHighQuality := 1000
+ else if prevHighQuality < 0.01 then
+ prevHighQuality := 0.01;
Fuse := txtFuse.Value; // AV
- try
- HexTR := StrToFloat(txtHexTile.Text); // AV
+ HexTR := StrToFloatDef(txtHexTile.Text, 1); // AV
if HexTR < 0.1 then HexTR := 0.1;
- except
- HexTR := 1;
- end;
- try
- SquareTR := StrToFloat(txtSTile.Text); // AV
- if SquareTR < 0.1 then SquareTR := 0.1;
- except
- SquareTR := 1;
- end;
- try
- RhombTR := StrToFloat(txtRTile.Text); // AV
- if RhombTR < 0.1 then RhombTR := 0.1;
- except
- RhombTR := 1;
- end;
+
+ SquareTR := StrToFloatDef(txtSTile.Text, 1); // AV
+ if SquareTR < 0.1 then SquareTR := 0.1;
+
+ RhombTR := StrToFloatDef(txtRTile.Text, 1); // AV
+ if RhombTR < 0.1 then RhombTR := 0.1;
MainPreviewScale := 1 + 0.02 * StrToFloatDef(cbExtendPercent.Text, 0);
- if MainPreviewScale < 1 then MainPreviewScale := 1
- else if MainPreviewScale > 5 then MainPreviewScale := 5;
+ if MainPreviewScale < 1 then
+ MainPreviewScale := 1
+ else if MainPreviewScale > 5 then
+ MainPreviewScale := 5;
ExtendMainPreview := chkExtendMainPreview.Checked;
ShowRenderStats := chkShowRenderStats.Checked;
@@ -902,8 +901,6 @@ begin
ScreenShotPath := ScreenShotPath + '\';
defScriptFile := txtDefScript.Text; // AV
- UseX64IfPossible := cbC64.Checked;
-
PluginPath := txtPluginFolder.Text;
if (PluginPath = '') or (not DirectoryExists(PluginPath)) then
PluginPath := ExtractFilePath(Application.ExeName); // AV
@@ -918,36 +915,34 @@ begin
MainForm.mnuExportChaotica.Enabled := FileExists(chaoticaPath + '\chaotica.exe');
if (warn) then
- Application.MessageBox(PChar(TextByKey('options-restartnotice')), PChar('Apophysis'), MB_ICONWARNING);
+ Application.MessageBox(PChar(TextByKey('options-restartnotice')),
+ ApophysisSVN, MB_ICONWARNING);
- Close;
+ ModalResult := mrOK; // AV: was Close;
end;
-procedure TOptionsForm.btnDefGradientClick(Sender: TObject);
-var
- fn:string;
+procedure TOptionsForm.btnDefParamsClick(Sender: TObject);
begin
- OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame|' + TextBykey('common-filter-allfiles') + '|*.*';
+ OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame|' +
+ TextBykey('common-filter-allfiles') + '|*.*';
+ OpenDialog.InitialDir := ParamFolder; // AV
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '.flame', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- txtDefParameterFile.text := fn;
- end;
+ if OpenDialog.Execute then
+ txtDefParameterFile.text := OpenDialog.FileName;
end;
procedure TOptionsForm.btnDefScriptClick(Sender: TObject);
-var
- fn:string;
begin
- OpenDialog.Filter := TextByKey('common-filter-scriptfiles') + '|*.aposcript;*.asc|' + TextBykey('common-filter-allfiles') + '|*.*';;
+ OpenDialog.Filter := TextByKey('common-filter-scriptfiles') + '|*.aposcript;*.asc|'
+ + TextBykey('common-filter-allfiles') + '|*.*';;
if DirectoryExists(ScriptPath) then
OpenDialog.InitialDir := ScriptPath + '\'
else
OpenDialog.InitialDir := ExtractFilePath(Application.ExeName);
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '.asc', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- txtDefScript.Text := fn;
+ OpenDialog.DefaultExt := 'asc';
+ if OpenDialog.Execute then
+ txtDefScript.Text := OpenDialog.FileName;
end;
procedure TOptionsForm.FormClose(Sender: TObject; var Action: TCloseAction);
@@ -966,31 +961,26 @@ begin
finally
Registry.Free;
end;
-
end;
procedure TOptionsForm.btnSmoothClick(Sender: TObject);
-var
- fn:string;
begin
- OpenDialog.Filter := TextByKey('common-filter-gradientfiles') + '|*.gradient;*.ugr|' + TextBykey('common-filter-allfiles') + '|*.*';
+ OpenDialog.Filter := TextByKey('common-filter-gradientfiles') +'|*.gradient;*.ugr|'
+ + TextBykey('common-filter-allfiles') + '|*.*';
OpenDialog.InitialDir := ExtractFilePath(defSmoothPaletteFile);
OpenDialog.FileName := '';
OpenDialog.DefaultExt := 'ugr';
- if OpenSaveFileDialog(OptionsForm, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- txtDefSmoothFile.text := fn;
- end;
+ if OpenDialog.Execute then
+ txtDefSmoothFile.text := OpenDialog.FileName;;
end;
-procedure TOptionsForm.btnSShotPathClick(Sender: TObject);
+procedure TOptionsForm.btnSShotPathClick(Sender: TObject); // AV
var sspath: string;
begin
sspath := ScreenShotPath;
if SelectDirectory(TextByKey('options-tab-environment-screenshotshint'), '',
sspath, [sdNewFolder, sdShowEdit, sdNewUI, sdValidateDir], Self) then
- txtSShotFolder.Text := sspath + '\';
+ txtSShotFolder.Text := IfThen(RightStr(sspath, 1)='\', sspath, sspath + '\');
end;
procedure TOptionsForm.cmbSymTypeChange(Sender: TObject);
@@ -1122,32 +1112,27 @@ begin
end;
procedure TOptionsForm.btnRendererClick(Sender: TObject);
-var
- fn:string;
begin
- OpenDialog.Filter := TextBykey('common-filter-allfiles') + '|*.*';
- OpenDialog.InitialDir := ExtractFilePath(flam3Path);
- OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- txtRenderer.text := fn;
- end;
-
+ OpenDialog.Filter := TextBykey('common-filter-allfiles') + '|*.exe';
+ if FileExists(flam3Path) then
+ OpenDialog.InitialDir := ExtractFilePath(flam3Path)
+ else
+ OpenDialog.InitialDir := GetEnvironmentVariable('PROGRAMFILES');
+ OpenDialog.FileName := 'flam3-render.exe'; // AV
+ OpenDialog.DefaultExt := 'exe'; // AV
+ if OpenDialog.Execute then
+ txtRenderer.Text := OpenDialog.FileName;
end;
-procedure TOptionsForm.SpeedButton2Click(Sender: TObject);
-var
- fn:string;
+procedure TOptionsForm.btnDefLibraryClick(Sender: TObject);
begin
- OpenDialog.Filter := TextByKey('common-filter-scriptfiles') + '|*.aposcript;*.asc|' + TextBykey('common-filter-allfiles') + '|*.*';;
+ OpenDialog.Filter := TextByKey('common-filter-scriptfiles') + '|*.aposcript;*.asc|'
+ + TextBykey('common-filter-allfiles') + '|*.*';
OpenDialog.InitialDir := ExtractFilePath(defLibrary);
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '.asc', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- txtLibrary.text := fn;
- end;
+ OpenDialog.DefaultExt := '.asc';
+ if OpenDialog.Execute then
+ txtLibrary.Text := OpenDialog.FileName;
end;
procedure TOptionsForm.TilePanelDblClick(Sender: TObject);
@@ -1169,27 +1154,28 @@ begin
cbNrTheads.Items.Add(IntToStr(i));
except
cbNrTheads.Items.Clear;
- for i := 1 to 12 do
+ for i := 1 to 12 do
cbNrTheads.Items.Add(IntToStr(i));
end;
- UseNrThreads := cbNrTheads.Items.Count;
+ UseNrThreads := cbNrTheads.Items.Count; // save nr processor cores
btnOK.Caption := TextByKey('common-ok');
btnCancel.Caption := TextByKey('common-cancel');
pnlLowQ.Caption := TextByKey('common-lowquality');
pnlMediumQ.Caption := TextByKey('common-mediumquality');
pnlHighQ.Caption := TextByKey('common-highquality');
- btnDefGradient.Hint := TextByKey('common-browse');
- btnSmooth.Hint := btnDefGradient.Hint;
- SpeedButton2.Hint := btnDefGradient.Hint;
- btnRenderer.Hint := btnDefGradient.Hint;
- btnHelp.Hint := btnDefGradient.Hint;
- btnPluginPath.Hint := btnDefGradient.Hint;
- btnSShotPath.Hint := btnDefGradient.Hint;
- btnChaotica.Hint := btnDefGradient.Hint;
- btnFindDefaultSaveFile.Hint := btnDefGradient.Hint;
- btnBrowseSound.Hint := btnDefGradient.Hint;
- btnDefScript.Hint := btnDefGradient.Hint;
+ btnDefParams.Hint := TextByKey('common-browse');
+ btnSmooth.Hint := btnDefParams.Hint;
+ btnDefLibrary.Hint := btnDefParams.Hint;
+ btnRenderer.Hint := btnDefParams.Hint;
+ btnHelp.Hint := btnDefParams.Hint;
+ btnPluginPath.Hint := btnDefParams.Hint;
+ btnSShotPath.Hint := btnDefParams.Hint;
+ btnChaotica.Hint := btnDefParams.Hint;
+ btnFindDefaultSaveFile.Hint := btnDefParams.Hint;
+ btnBrowseSound.Hint := btnDefParams.Hint;
+ btnDefScript.Hint := btnDefParams.Hint;
+ btnLanguage.Hint := btnDefParams.Hint;
Panel37.Caption := TextByKey('common-width');
Panel38.Caption := TextByKey('common-height');
Panel31.Caption := TextByKey('common-filename');
@@ -1223,11 +1209,12 @@ begin
Label49.Caption := TextByKey('common-minutes');
Panel47.Caption := TextByKey('common-filename');
Panel50.Caption := TextByKey('options-tab-general-pluginpath');
- //Panel49.Caption := TextByKey('common-filename') + ' (x64)';
Panel48.Caption := TextByKey('options-tab-editor-previewtransparency');
+ gbDefaults.Caption := TextByKey('options-tab-general-defaults');
+ gbGradDefaults.Caption := TextByKey('options-tab-general-defaults');
+ gbNotifications.Caption := TextByKey('options-tab-general-notifications');
pnlScreenShot.Caption := TextByKey('options-tab-environment-screenshots');
pnlScriptFile.Caption := TextByKey('options-tab-environment-defaultscript');
- cbC64.Caption := TextByKey('options-tab-environment-usex64chaotica');
chkEnableEditorPreview.Caption := TextByKey('options-tab-editor-enablepreview');
chkAutoSaveXML.Caption := TextByKey('options-tab-general-autosavepasted');
self.Caption := TextByKey('options-title');
@@ -1235,7 +1222,6 @@ begin
Panel46.Caption := TextByKey('options-tab-general-language');
pnlMultithreading.Caption := TextByKey('options-tab-general-multithreading');
cbNrTheads.Items[0] := TextByKey('options-tab-general-multithreading-off');
- //pnlBufferDepth.Caption := TextByKey('options-tab-general-bufferdepth');
pnlJPEGQuality.Caption := TextByKey('options-tab-general-jpegquality');
pnlPNGTransparency.Caption := TextByKey('options-tab-general-pngtransparency');
chkShowRenderStats.Caption := TextByKey('options-tab-general-showextendedstatistics');
@@ -1244,11 +1230,12 @@ begin
chkConfirmExit.Caption := TextByKey('options-tab-general-confirmexit');
chkconfirmStopRender.Caption := TextByKey('options-tab-general-confirmrenderstop');
chkConfirmClearScript.Caption := TextByKey('options-tab-general-confirmclearscript');
+ chkConfirmResetUndo.Caption := TextByKey('options-tab-general-confirmresetundo');
chkOldPaletteFormat.Caption := TextByKey('options-tab-general-oldgradientformat');
cbUseTemplate.Caption := TextByKey('options-tab-general-alwaysblankflame');
chkEqualStripes.Caption := TextByKey('options-tab-gradient-equalstripes');
cbMissingplugin.Caption := TextByKey('options-tab-general-enablemissingpluginswarning');
- cbEmbedThumbs.Caption := TextByKey('options-tab-general-enablethumbnailembedding');
+ // cbEmbedThumbs.Caption := TextByKey('options-tab-general-enablethumbnailembedding');
chkEngLayout.Caption := TextByKey('options-tab-general-setenglayout');
chkRandomTemplates.Caption := TextByKey('options-tab-general-templaterandcolor');
chkApplyFlatten.Caption := TextByKey('options-tab-general-autoflatten');
@@ -1347,7 +1334,6 @@ begin
chkRememberLastOpen.Caption := TextByKey('options-tab-environment-rememberlastopen');
cbEnableAutosave.Caption := TextByKey('options-tab-environment-autosave');
panel45.Caption := TextByKey('options-tab-environment-savefrequency');
- //cbSinglePrecision.Caption := TextByKey('options-tab-general-singleprecision');
grpEditorColors.Caption := TextByKey('editor-tab-color-title');
GroupBox15.Caption := TextByKey('options-tab-general-onrendercomplete');
chkPlaySound.Caption := TextByKey('options-tab-general-playsound');
@@ -1359,18 +1345,19 @@ begin
pnSTile.Caption := TextByKey('main-menu-flame-squaretile');
GroupBox7.Caption := TextByKey('options-tab-display-tileradius');
pnlRandBackground.Caption := TextByKey('options-tab-editor-backgroundcolor');
+ chkSyncTriangles.Caption := TextByKey('options-tab-editor-synctriangles');
+
+ gbAnimation.Caption := TextByKey('animate-animation');
+ pnlFPS.Caption := TextByKey('animate-fps');
+ pnlAnimPrefix.Caption := TextByKey('animate-prefix');
+ pnlFrameExt.Caption := TextByKey('animate-graphicext');
+ chkCreateAnimFolder.Caption := TextByKey('options-tab-general-createanimdir') ;
for i:= 0 to NRVAR - 1 do begin
clbVarEnabled.Items.Add(varnames(i));
clbVarFavourite.Items.Add(varnames(i)); // AV
end;
- if not CheckX64 then // AV
- begin
- cbc64.Enabled := false;
- UseX64IfPossible := false;
- end;
-
Tabs.ActivePageIndex := 0; // AV
VarsPages.ActivePageIndex := 0; // AV
end;
@@ -1516,11 +1503,11 @@ begin
OpenDialog.InitialDir := ExtractFilePath(RenderCompleteSoundFile);
OpenDialog.Filter := 'Waveform files (*.wav)|*.wav';
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '.wav', OpenDialog.Filter, OpenDialog.InitialDir,
- TextByKey('common-openwav'), fn, true, false, false, true) then
- begin
- txtSoundFile.text := fn;
- end;
+ OpenDialog.DefaultExt := 'wav';
+ OpenDialog.Title := TextByKey('common-openwav');
+ if OpenDialog.Execute then
+ txtSoundFile.text := OpenDialog.FileName;
+ OpenDialog.Title := ''; // AV: reset caption to default "Open..."
end;
procedure TOptionsForm.btnPlayClick(Sender: TObject);
@@ -1554,17 +1541,14 @@ begin
end;
procedure TOptionsForm.btnGradientsFileClick(Sender: TObject);
-var
- fn:string;
begin
- OpenDialog.Filter := TextByKey('common-filter-gradientfiles') + '|*.gradient;*.ugr|' + TextBykey('common-filter-allfiles') + '|*.*';
+ OpenDialog.Filter := TextByKey('common-filter-gradientfiles') + '|*.gradient;*.ugr|'
+ + TextBykey('common-filter-allfiles') + '|*.*';
OpenDialog.InitialDir := ExtractFilePath(randGradientFile);
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '.ugr', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- txtGradientsFile.text := fn;
- end;
+ OpenDialog.DefaultExt := 'ugr';
+ if OpenDialog.Execute then
+ txtGradientsFile.text := OpenDialog.FileName;
end;
procedure TOptionsForm.shBackgroundMouseUp(Sender: TObject;
@@ -1632,10 +1616,10 @@ begin
if chkRememberLastOpen.Checked then begin
txtDefParameterFile.Enabled := false;
txtDefParameterFile.Text := ''; //LastOpenFile;
- btnDefGradient.Enabled := false;
+ btnDefParams.Enabled := false;
end else begin
txtDefParameterFile.Enabled := true;
- btnDefGradient.Enabled := true;
+ btnDefParams.Enabled := true;
end;
Panel39.Enabled := txtDefParameterFile.Enabled;
@@ -1645,15 +1629,12 @@ begin
end;
procedure TOptionsForm.btnFindDefaultSaveFileClick(Sender: TObject);
-var fn:string;
begin
- OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame|' + TextBykey('common-filter-allfiles') + '|*.*';
+ OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame|' +
+ TextBykey('common-filter-allfiles') + '|*.*';
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '.flame', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, false, false, false, false) then
- //if OpenDialog.Execute then
- begin
- txtDefaultSaveFile.text := fn;
- end;
+ if OpenDialog.Execute then
+ txtDefaultSaveFile.Text := OpenDialog.FileName;
end;
procedure TOptionsForm.cbEnableAutosaveClick(Sender: TObject);
@@ -1671,17 +1652,13 @@ begin
end;
procedure TOptionsForm.btnHelpClick(Sender: TObject);
-var
- fn:string;
begin
OpenDialog.Filter := TextBykey('common-filter-allfiles') + '|*.*';
OpenDialog.InitialDir := ExtractFilePath(helpPath);
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- txtHelp.text := fn;
- end;
+ OpenDialog.DefaultExt := '';
+ if OpenDialog.Execute then
+ txtHelp.text := OpenDialog.FileName;
end;
procedure TOptionsForm.btnInvertClick(Sender: TObject);
@@ -1712,21 +1689,22 @@ begin
else pnlGoldenRatio.Font.Color := clGrayText;
end;
-procedure TOptionsForm.SpeedButton1Click(Sender: TObject);
+procedure TOptionsForm.btnLanguageClick(Sender: TObject);
var fn, fn2, s1, s2:string; i : integer;
begin
OpenDialog.Filter := 'Extensible Markup Language Files (*.xml)|*.xml';
OpenDialog.InitialDir := ExtractFilePath(helpPath);
OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
+ OpenDialog.DefaultExt := '';
+ if OpenDialog.Execute then
begin
- fn2 := ExtractFilePath(Application.ExeName) + 'Languages\' + ExtractFileName(fn);
+ fn := OpenDialog.FileName; // AV
+ fn2 := AppPath + 'Languages\' + ExtractFileName(fn);
LanguageInfo(fn, s1, s2);
if s1 <> '' then begin
- if not DirectoryExists(ExtractFilePath(Application.ExeName) + 'Languages\') then
- CreateDirectory(PChar(ExtractFilePath(Application.ExeName) + 'Languages\'), nil);
- if (lowercase(ExtractFilePath(fn)) <> lowercase(ExtractFilePath(Application.ExeName) + 'Languages\')) then
+ if not DirectoryExists(AppPath + 'Languages\') then
+ CreateDir(AppPath + 'Languages\');
+ if (lowercase(ExtractFilePath(fn)) <> lowercase(AppPath + 'Languages\')) then
CopyFile(PChar(fn), PChar(fn2), False);
AvailableLanguages.Add(fn2);
i := AvailableLanguages.Count - 1;
@@ -1734,42 +1712,26 @@ begin
s1 := s2 + ' (' + s1 + ')';
txtLanguageFile.Items.Add(s1);
txtLanguageFile.ItemIndex := txtLanguageFile.Items.Count - 1;
- end else begin
- Application.MessageBox(PChar(TextByKey('common-invalidformat')), PChar('Apophysis'), MB_ICONERROR);
- end;
+ end else
+ raise Exception.Create(TextByKey('common-invalidformat')); // AV
end;
end;
procedure TOptionsForm.btnChaoticaClick(Sender: TObject);
var fn: string;
begin
-
- // new b. 1550
fn := ChaoticaPath;
if SelectDirectory(fn, [sdAllowCreate, sdPerformCreate, sdPrompt], 0) then
begin
txtChaotica.Text := fn;
if not FileExists(fn + '\chaotica.exe') then
begin
- MessageBox(0,
- PCHAR('Could not find "' + fn + '\chaotica.exe" - invalid Chaotica 0.45+ path'),
- PCHAR('Apophysis AV'), MB_ICONHAND or MB_OK);
+ MessageBox(0, PCHAR(TextByKey('main-status-nochaotica')),
+ ApophysisSVN, MB_ICONHAND or MB_OK);
txtChaotica.Text := ChaoticaPath;
fn := ChaoticaPath;
end;
end;
- {OpenDialog.Filter := TextBykey('common-filter-allfiles') + '|*.*';
- if sender = TSpeedButton(btnChaotica) then
- OpenDialog.InitialDir := ExtractFilePath(ChaoticaPath)
- else
- OpenDialog.InitialDir := ExtractFilePath(ChaoticaPath64);
- OpenDialog.FileName := '';
- if OpenSaveFileDialog(OptionsForm, '', OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
- //if OpenDialog.Execute then
- begin
- if sender = TSpeedButton(btnChaotica) then txtChaotica.text := fn
- else txtChaotica64.text := fn;
- end; }
end;
procedure TOptionsForm.chkEnableEditorPreviewClick(Sender: TObject);
diff --git a/Forms/Preview.pas b/Forms/Preview.pas
index 2f1b3d1..a8dedcf 100644
--- a/Forms/Preview.pas
+++ b/Forms/Preview.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,8 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- ExtCtrls, ControlPoint, RenderingInterface, Translation, Vcl.Menus,
- Vcl.Imaging.PNGimage;
+ ExtCtrls, ControlPoint, RenderingInterface, Vcl.Menus, Vcl.Imaging.PNGimage;
type
TPreviewForm = class(TForm)
@@ -57,7 +56,7 @@ var
implementation
-uses Main, Global, ScriptForm;
+uses Main, Global, ScriptForm, Translation;
{$R *.DFM}
@@ -100,26 +99,27 @@ end;
procedure TPreviewForm.MakeScreenShotClick(Sender: TObject);
var
- s: string;
- pic: TPNGObject;
+ s, t: string;
+ pic: TPNGImage;
begin
if not DirectoryExists(ScreenShotPath) then
begin
CreateDir(AppPath + 'ScreenShots\');
ScreenShotPath := AppPath + 'ScreenShots\';
end;
- s := ScreenShotPath + 'Apophysis Animation Preview' + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now) + '.bmp';
+ t := FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
+ s := ScreenShotPath + 'Apophysis Animation Preview' + t + '.bmp';
try
if KeepFrame.Checked then
GetFormScreenShot(s)
else
begin
try
- pic := TPNGObject.Create;
+ pic := TPNGImage.Create;
try
pic.Assign(Image.Picture.Bitmap);
- if cp.name = '' then cp.name := RemoveExt(s);
- pic.AddtEXt('ApoFlame', AnsiString(Trim(MainForm.RetrieveXML(cp))));
+ if cp.name = '' then cp.name := RemoveExt(s) + t;
+ pic.AddtEXt('ApoFlame', AnsiString(Trim(FlameToXML(cp))));
s := ChangeFileExt(s, '.png');
pic.SaveToFile(s);
finally
@@ -130,9 +130,9 @@ begin
end;
end;
Application.MessageBox(PChar(Format(TextByKey('common-screenshot-saved'),
- [ExtractFileName(s), ExtractFilePath(s)])), PChar('Apophysis AV'), MB_ICONINFORMATION);
+ [ExtractFileName(s), ExtractFilePath(s)])), ApophysisSVN, MB_ICONINFORMATION);
except
- Application.MessageBox(PChar(TextByKey('common-screenshot-error')), PChar('Apophysis AV'), MB_ICONERROR);
+ Application.MessageBox(PChar(TextByKey('common-screenshot-error')), ApophysisSVN, MB_ICONERROR);
end;
end;
diff --git a/Forms/Save.dfm b/Forms/Save.dfm
index 93f012d..7d75575 100644
--- a/Forms/Save.dfm
+++ b/Forms/Save.dfm
@@ -3,8 +3,8 @@ object SaveForm: TSaveForm
Top = 432
BorderStyle = bsDialog
Caption = 'Save Parameters'
- ClientHeight = 153
- ClientWidth = 517
+ ClientHeight = 197
+ ClientWidth = 528
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
@@ -16,17 +16,16 @@ object SaveForm: TSaveForm
OnCreate = FormCreate
OnShow = FormShow
DesignSize = (
- 517
- 153)
+ 528
+ 197)
PixelsPerInch = 120
TextHeight = 16
object btnDefGradient: TSpeedButton
- Left = 480
- Top = 9
+ Left = 485
+ Top = 8
Width = 30
Height = 29
Hint = 'Browse...'
- Anchors = [akTop, akRight]
Flat = True
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@@ -65,31 +64,10 @@ object SaveForm: TSaveForm
ShowHint = True
OnClick = btnDefGradientClick
end
- object btnSave: TButton
- Left = 310
- Top = 116
- Width = 93
- Height = 30
- Anchors = [akRight, akBottom]
- Caption = '&Save'
- Default = True
- TabOrder = 2
- OnClick = btnSaveClick
- end
- object btnCancel: TButton
- Left = 410
- Top = 116
- Width = 92
- Height = 30
- Anchors = [akRight, akBottom]
- Caption = 'Cancel'
- TabOrder = 3
- OnClick = btnCancelClick
- end
object pnlTarget: TPanel
Left = 10
Top = 10
- Width = 124
+ Width = 120
Height = 26
Cursor = crArrow
BevelOuter = bvLowered
@@ -102,7 +80,7 @@ object SaveForm: TSaveForm
object pnlName: TPanel
Left = 10
Top = 39
- Width = 124
+ Width = 120
Height = 26
Cursor = crArrow
BevelOuter = bvLowered
@@ -112,42 +90,62 @@ object SaveForm: TSaveForm
TabOrder = 5
end
object txtFilename: TEdit
- Left = 128
+ Left = 130
Top = 10
Width = 353
Height = 24
- Anchors = [akLeft, akTop, akRight]
TabOrder = 0
Text = 'txtFilename'
end
object txtTitle: TEdit
- Left = 128
+ Left = 130
Top = 39
- Width = 383
+ Width = 381
Height = 24
- Anchors = [akLeft, akTop, akRight]
TabOrder = 1
Text = 'txtTitle'
end
- object optUseOldFormat: TRadioButton
+ object pnlComment: TPanel
Left = 10
- Top = 79
- Width = 304
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Use classic flame format'
- Checked = True
+ Top = 68
+ Width = 120
+ Height = 26
+ Cursor = crArrow
+ BevelOuter = bvLowered
+ Caption = 'Comment'
+ ParentShowHint = False
+ ShowHint = True
TabOrder = 6
- TabStop = True
end
- object optUseNewFormat: TRadioButton
- Left = 10
- Top = 101
- Width = 304
- Height = 21
- Anchors = [akLeft, akTop, akRight]
- Caption = 'Use new flame format'
- Enabled = False
+ object txtComment: TMemo
+ Left = 130
+ Top = 68
+ Width = 381
+ Height = 77
+ Lines.Strings = (
+ '')
+ ScrollBars = ssBoth
TabOrder = 7
end
+ object btnCancel: TButton
+ Left = 413
+ Top = 159
+ Width = 92
+ Height = 30
+ Anchors = [akRight, akBottom]
+ Caption = 'Cancel'
+ TabOrder = 3
+ OnClick = btnCancelClick
+ end
+ object btnSave: TButton
+ Left = 305
+ Top = 159
+ Width = 93
+ Height = 30
+ Anchors = [akRight, akBottom]
+ Caption = '&Save'
+ Default = True
+ TabOrder = 2
+ OnClick = btnSaveClick
+ end
end
diff --git a/Forms/Save.pas b/Forms/Save.pas
index 4d5fcdb..eb6265f 100644
--- a/Forms/Save.pas
+++ b/Forms/Save.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -39,8 +39,8 @@ type
btnDefGradient: TSpeedButton;
pnlTarget: TPanel;
pnlName: TPanel;
- optUseOldFormat: TRadioButton;
- optUseNewFormat: TRadioButton;
+ pnlComment: TPanel;
+ txtComment: TMemo;
procedure FormCreate(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
@@ -51,6 +51,7 @@ type
public
Title: string;
Filename: string;
+ Comment: string;
SaveType : ESaveType;
end;
@@ -135,17 +136,17 @@ begin
if ((t = '') and txtTitle.Enabled) then
begin
- Application.MessageBox(PChar(TextByKey('save-status-notitle')), 'Apophysis', 48);
+ Application.MessageBox(PChar(TextByKey('save-status-notitle')), PChar(ApophysisSVN), 48);
Exit;
end;
if f = '' then
begin
- Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), 'Apophysis', 48);
+ Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), PChar(ApophysisSVN), 48);
Exit;
end;
if ExtractFileExt(f) = '' then
begin
- Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), 'Apophysis', 48);
+ Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), PChar(ApophysisSVN), 48);
Exit;
end;
@@ -166,17 +167,22 @@ begin
check := EntryExists(t, f);
end;
- if check then begin if onestr then begin
- if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists2'), [f])),
- 'Apophysis', 52) = ID_NO then exit;
- end else begin
- if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists'), [t, f])),
- 'Apophysis', 52) = ID_NO then exit;
- end end;
+ if check then begin
+ if onestr then
+ begin
+ if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists2'), [f])),
+ PChar(ApophysisSVN), 52) = ID_NO then exit;
+ end
+ else begin
+ if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists'), [t, f])),
+ PChar(ApophysisSVN), 52) = ID_NO then exit;
+ end
+ end;
if (t = '*') then t := '';
Title := t;
Filename := f;
+ Comment := Trim(txtComment.Lines.Text);
ModalResult := mrOK;
end;
@@ -189,11 +195,9 @@ procedure TSaveForm.FormShow(Sender: TObject);
begin
txtFilename.Text := Filename;
txtTitle.Text := Title;
- //btnSave.SetFocus;
+ txtComment.Lines.Text := Comment; // AV
self.Caption := TextByKey(SaveTypeTextKey(SaveType));
- {if (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters) then
- self.Height := 160
- else self.Height := 120; }
+
if (SaveType = stSaveGradient) then // AV
pnlName.Caption := TextByKey('save-namepal')
else pnlName.Caption := TextByKey('save-name');
@@ -203,8 +207,11 @@ begin
if (not txtTitle.Enabled) then pnlName.Font.Color := clGrayText
else pnlName.Font.Color := clWindowText;
- optUseOldFormat.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters);
- optUseNewFormat.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters);
+ pnlComment.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveTemplate);
+ txtComment.Visible := pnlComment.Visible;
+ if txtComment.Visible then
+ self.Height := 225
+ else self.Height := 160;
txtFileName.ReadOnly := (SaveType = stSaveTemplate); // AV
end;
@@ -234,9 +241,8 @@ begin
btnSave.Caption := TextByKey('common-ok');
btnDefGradient.Hint := TextByKey('common-browse');
pnlTarget.Caption := TextByKey('common-destination');
+ pnlComment.Caption := TextByKey('common-comment');
//pnlName.Caption := TextByKey('save-name');
- optUseOldFormat.Caption := TextByKey('save-oldformat');
- optUseNewFormat.Caption := TextByKey('save-newformat');
end;
end.
diff --git a/Forms/SavePreset.dfm b/Forms/SavePreset.dfm
index 5f28a48..09d2b27 100644
--- a/Forms/SavePreset.dfm
+++ b/Forms/SavePreset.dfm
@@ -12,14 +12,15 @@ object SavePresetForm: TSavePresetForm
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
+ Position = poDesktopCenter
OnCreate = FormCreate
DesignSize = (
349
66)
PixelsPerInch = 96
TextHeight = 13
- object Button1: TButton
- Left = 190
+ object btOK: TButton
+ Left = 180
Top = 37
Width = 75
Height = 25
@@ -28,10 +29,10 @@ object SavePresetForm: TSavePresetForm
Default = True
ModalResult = 1
TabOrder = 1
- OnClick = Button1Click
+ OnClick = btOKClick
end
- object Button2: TButton
- Left = 270
+ object btCancel: TButton
+ Left = 260
Top = 37
Width = 75
Height = 25
diff --git a/Forms/SavePreset.pas b/Forms/SavePreset.pas
index 85a3095..9d3be5e 100644
--- a/Forms/SavePreset.pas
+++ b/Forms/SavePreset.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -32,11 +32,11 @@ uses
type
TSavePresetForm = class(TForm)
txtPresetName: TEdit;
- Button1: TButton;
- Button2: TButton;
+ btOK: TButton;
+ btCancel: TButton;
pnlName: TPanel;
procedure FormCreate(Sender: TObject);
- procedure Button1Click(Sender: TObject);
+ procedure btOKClick(Sender: TObject);
private
{ Private declarations }
public
@@ -50,11 +50,11 @@ implementation
{$R *.DFM}
-procedure TSavePresetForm.Button1Click(Sender: TObject);
+procedure TSavePresetForm.btOKClick(Sender: TObject);
begin
if txtPresetName.Text = '' then
begin
- Application.MessageBox(PChar(TextByKey('savepreset-notitle')), 'Apophysis', 48);
+ Application.MessageBox(PChar(TextByKey('savepreset-notitle')), 'Apophysis AV', 48);
Exit;
end;
end;
@@ -62,8 +62,8 @@ end;
procedure TSavePresetForm.FormCreate(Sender: TObject);
begin
self.Caption := TextBykey('savepreset-title');
- button1.Caption := TextByKey('common-ok');
- button2.Caption := TextByKey('common-cancel');
+ btOK.Caption := TextByKey('common-ok');
+ btCancel.Caption := TextByKey('common-cancel');
pnlName.Caption := TextByKey('savepreset-name');
end;
diff --git a/Forms/ScriptForm.dfm b/Forms/ScriptForm.dfm
index 9a7c5c9..68180c9 100644
--- a/Forms/ScriptForm.dfm
+++ b/Forms/ScriptForm.dfm
@@ -766,7 +766,7 @@ object ScriptEditor: TScriptEditor
CallExecHookEvent = False
Left = 480
Top = 200
- end
+ end
object OpenDialog: TOpenDialog
DefaultExt = 'flame'
Filter =
@@ -994,6 +994,9 @@ object ScriptEditor: TScriptEditor
'procedure Print(data: variant)'
'procedure AddSymmetry(symmetry_type: integer)'
+ 'procedure PrepareToMorph(Flame1_Num: integer, Flame2_Num: intege' +
+ 'r)'
+
'procedure Morph(Flame1_Num: integer, Flame2_Num: integer, Speed:' +
' double, interp_type: integer = 3)'
'procedure SetRenderBounds'
@@ -1076,6 +1079,7 @@ object ScriptEditor: TScriptEditor
'property Name: string'
'property Batches: integer'
'property FinalXformEnabled: boolean'
+ 'property Comment: string'
'var LimitVibrancy: boolean'
'var DateCode: readonly'
'procedure DecodeDate(date, year, month, day)'
@@ -1228,7 +1232,7 @@ object ScriptEditor: TScriptEditor
'procedure Inc(num: integer)'
'function Odd(num: integer): boolean'
'function StringOfChar(symbol: char, count: integer): string'
- 'function GetEnvironmentVariable(sys_const: string): string;'
+ 'function GetEnvironmentVariable(sys_const: string): string'
'const PI'
'const NVARS'
'const NumVariables'
diff --git a/Forms/ScriptForm.pas b/Forms/ScriptForm.pas
index becf428..9d0ce13 100644
--- a/Forms/ScriptForm.pas
+++ b/Forms/ScriptForm.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,9 +27,9 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- ExtCtrls, StdCtrls, ControlPoint, Buttons, ComCtrls, ToolWin, Menus,
- XFormMan, XForm, GradientHlpr, cmap,LibXmlParser, LibXmlComps, Math, Translation,
- atScript, atPascal, ScripterInit, ScrMemo, Scrmps, ScrCodeList;
+ ExtCtrls, StdCtrls, ControlPoint, Buttons, ComCtrls, ToolWin, Menus, Math,
+ XFormMan, XForm, GradientHlpr, cmap, LibXmlParser, LibXmlComps, Translation,
+ atScript, atPascal, Vcl.ScripterInit, ScrMemo, Scrmps, ScrCodeList;
const
NCPS = 10; // AV: max number of flames for animation
@@ -38,9 +38,17 @@ const
type
TOptions = class
public
+ { TOptions class is used only as an interface to user's preferencies }
end;
TFlame = class
public
+ { The TFlame class is used only as an interface. The control point parameters
+ are read and set directly. Parameter ranges aren't limited but values not
+ in the correct range are ignored. }
+ end;
+ TTransform = class
+ public
+ { TTransform class only serves as an interface to active transform }
end;
TScriptRender = class
public
@@ -50,6 +58,7 @@ type
end;
TPivot = class
public
+ { TPivot class only serves as an interface to active transform's pivot point }
end;
TScriptEditor = class(TForm)
MainOpenDialog: TOpenDialog;
@@ -68,7 +77,7 @@ type
N1: TMenuItem;
BackPanel: TPanel;
Editor: TScrMemo;
- Scripter: TatPascalScripter;
+ Scripter: TatPascalScripter;
Splitter1: TSplitter;
Console: TMemo;
btnStop: TToolButton;
@@ -104,7 +113,6 @@ type
ExpandBlocks: TMenuItem;
procedure F2SXMLStartTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
- procedure F2SXMLEndTag(Sender: TObject; TagName: string);
procedure F2SXMLEmptyTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
procedure F2SXMLContent(Sender: TObject; Content: string);
@@ -154,25 +162,13 @@ type
procedure Editcaption1Click(Sender: TObject);
procedure CollapseBlocksClick(Sender: TObject);
procedure ExpandBlocksClick(Sender: TObject);
- public
- cp: TControlPoint;
- Stopped: boolean;
- cmap: TColorMap;
+ private
+ //cmap: TColorMap;
Flame: TFlame;
+ Transform: TTransform;
Options: TOptions;
Pivot: TPivot;
- Renderer: TScriptRender;
Another: TScriptRender;
- AddedXForms : integer;
- chaosLines : TStringList;
- procedure LoadRunAndClear(scriptFile:string);
- procedure LoadScriptFile(filename:string);
- procedure ScriptFromFlame(flameXML:string);
- procedure UpdateFlame;
- procedure PrepareScripter;
- procedure OpenScript;
- procedure RunScript;
- procedure AdjustScripterColors;
{ Flame interface }
procedure SetFlameNameProc(AMachine: TatVirtualMachine);
@@ -213,6 +209,8 @@ type
procedure SetFlamePaletteProc(AMachine: TatVirtualMachine);
procedure GetFlameBackgroundProc(AMachine: TatVirtualMachine);
procedure SetFlameBackgroundProc(AMachine: TatVirtualMachine);
+ procedure GetFlameCommentProc(AMachine: TatVirtualMachine);
+ procedure SetFlameCommentProc(AMachine: TatVirtualMachine);
// procedure SetFlameNickProc(AMachine: TatVirtualMachine);
// procedure GetFlameNickProc(AMachine: TatVirtualMachine);
// procedure SetFlameURLProc(AMachine: TatVirtualMachine);
@@ -243,7 +241,6 @@ type
procedure GetPreviewWidthProc(AMachine: TatVirtualMachine);
procedure SetPreviewWidthProc(AMachine: TatVirtualMachine);
-
{ Transform interface }
procedure GetTransformAProc(AMachine: TatVirtualMachine);
procedure SetTransformAProc(AMachine: TatVirtualMachine);
@@ -306,7 +303,7 @@ type
procedure TransformRotateProc(AMachine: TatVirtualMachine);
procedure TransformScaleProc(AMachine: TatVirtualMachine);
procedure TransformRotateOriginProc(AMachine: TatVirtualMachine);
-
+
// AV: added reflections
procedure TransformFlipHorizProc(AMachine: TatVirtualMachine);
procedure TransformFlipVertProc(AMachine: TatVirtualMachine);
@@ -453,39 +450,47 @@ type
// AV: moved here from TOperationLibrary
procedure CopyFileProc(AMachine: TatVirtualMachine);
- end;
- TTransform = class
public
- { Transform class only serves as an
- interface to active transform }
+ cp: TControlPoint;
+ Stopped: boolean;
+ Renderer: TScriptRender;
+
+ procedure LoadRunAndClear(scriptFile:string);
+ procedure LoadScriptFile(filename:string);
+ procedure ScriptFromFlame(flameXML:string);
+ procedure UpdateFlame;
+ procedure PrepareScripter;
+ procedure OpenScript;
+ procedure RunScript;
+ procedure AdjustScripterColors;
end;
// TMatrix = array[0..2, 0..2] of double; // AV: we already have such a type
+ EFormatInvalid = class(Exception);
var
ScriptEditor: TScriptEditor;
- LastParseError: string;
- NumTransforms: integer; // Keeps track of number of xforms in flame.
- ActiveTransform: integer; // Operations affect this transform.
+ ScFileList: TStringList; // AV: renamed due to sporadic name-space conflicts
LastError: string;
- color: double;
- cps: array[0..NCPS - 1] of TControlPoint;
- Transform: TTransform;
- Stopped, ResetLocation, UpdateIt: Boolean;
- ParamFile: string;
- FileList: TStringList;
- ErrorOutOfRange, RTError, DTError: string; // AV
implementation
-uses Main, Editor, Adjust, Global, Mutate, Registry, Preview, LoadTracker,
- ScriptRender, ap_math, ap_classes, ap_sysutils, ap_Dialogs,
- SavePreset, ap_windows, ap_FileCtrl, ap_Forms(*, bmdll32*);
+uses
+ Main, Editor, Adjust, Global, Mutate, Registry, Preview, LoadTracker,
+ ScriptRender, ap_math, ap_classes, ap_sysutils, ap_Dialogs, ap_windows,
+ ap_FileCtrl, ap_Forms;
{$R *.DFM}
-//const
-// ErrorOutOfRange = 'Transform out of range!';
+var
+ ErrorOutOfRange, RTError, DTError: string; // AV
+ chaosLines : TStringList;
+ cps: array[0..NCPS - 1] of TControlPoint;
+ ResetLocation, UpdateIt: Boolean;
+ NumTransforms: integer; // Keeps track of number of xforms in flame.
+ ActiveTransform: integer; // Operations affect this transform.
+ ParamFile: string;
+ AddedXForms : integer;
type
TOperationLibrary = class(TatScripterLibrary)
@@ -512,6 +517,7 @@ type
procedure ClearProc(AMachine: TatVirtualMachine);
procedure PreviewProc(AMachine: TatVirtualMachine);
procedure Print(AMachine: TatVirtualMachine);
+ procedure PrepareToMorphProc(AMachine: TatVirtualMachine); // AV
procedure MorphProc(AMachine: TatVirtualMachine);
procedure RenderProc(AMachine: TatVirtualMachine);
procedure AddSymmetryProc(AMachine: TatVirtualMachine);
@@ -569,9 +575,9 @@ begin
xml.Normalize := True;
xml.OnContent := F2SXMLContent; // AV: temporary unused
xml.OnEmptyTag := F2SXMLEmptyTag;
- xml.OnEndTag := F2SXMLEndTag;
+ // xml.OnEndTag := F2SXMLEndTag;
xml.OnStartTag := F2SXMLStartTag;
- xml.LoadFromBuffer(TCharType(TStringType(flameXML))); // AV: changed from ANSI
+ xml.LoadFromBuffer(PAnsiChar(Utf8String(flameXML)));
xml.Execute;
xml.Destroy;
@@ -774,7 +780,7 @@ begin
with AMachine do
begin
v := GetInputArgAsFloat(0);
- if (v >= 0.1) and (v <= 100) then defGamma := v;
+ if (v >= 0.1) and (v <= 10) then defGamma := v;
end;
end;
@@ -1486,6 +1492,7 @@ begin
Scripter.DefineMethod('Render', 0, tkNone, nil, RenderProc);
Scripter.DefineMethod('Print', 1, tkNone, nil, Print);
Scripter.DefineMethod('AddSymmetry', 1, tkNone, nil, AddSymmetryProc);
+ Scripter.DefineMethod('PrepareToMorph', 2, tkNone, nil, PrepareToMorphProc); // AV
Scripter.DefineMethod('Morph', 4, tkNone, nil, MorphProc, false, 1);
Scripter.DefineMethod('SetRenderBounds', 0, tkNone, nil, SetRenderBounds);
Scripter.DefineMethod('SetFlameFile', 1, tkNone, nil, SetParamFileProc);
@@ -1497,7 +1504,7 @@ begin
Scripter.DefineMethod('RandomGradient', 0, tkNone, nil, RandomGradientProc);
Scripter.DefineMethod('PresetGradient', 1, tkNone, nil, PresetGradientProc); // AV
Scripter.DefineMethod('SaveGradient', 2, tkNone, nil, SaveGradientProc);
- Scripter.DefineMethod('Variation', 0, tkInteger, nil, GetVariation); // AV: ?
+ Scripter.DefineMethod('Variation', 0, tkInteger, nil, GetVariation); // AV: fixed
Scripter.DefineMethod('SetVariation', 1, tkInteger, nil, SetVariation); // AV: fixed
Scripter.AddConstant('ProgramVersionString', AppVersionString);
@@ -1537,7 +1544,7 @@ begin
for i := 0 to NXFORMS - 1 do
if ScriptEditor.cp.xform[i].density = 0 then break;
NumTransforms := i;
- except on E: EMathError do
+ except on EMathError do
end;
end;
@@ -1571,10 +1578,13 @@ begin
end;
procedure TOperationLibrary.CalculateColors(AMachine: TatVirtualMachine);
-var i: integer;
+var i: smallint;
begin
+ if NumTransforms > 1 then // fixed divide-by-zero bug
for i := 0 to NumTransforms-1 do
- ScriptEditor.cp.xform[i].color := i / (NumTransforms-1);
+ ScriptEditor.cp.xform[i].color := i / (NumTransforms-1)
+ else
+ ScriptEditor.cp.xform[0].color := 0;
end;
procedure TOperationLibrary.CalculateWeights(AMachine: TatVirtualMachine);
@@ -1583,14 +1593,14 @@ begin
end;
procedure TOperationLibrary.RandomizeColors(AMachine: TatVirtualMachine);
-var i: integer;
+var i: smallint;
begin
for i := 0 to NumTransforms-1 do
ScriptEditor.cp.xform[i].color := random;
end;
procedure TOperationLibrary.RandomizeColorSpeed(AMachine: TatVirtualMachine);
-var i: integer;
+var i: smallint;
begin
for i := 0 to NumTransforms-1 do
ScriptEditor.cp.xform[i].symmetry := 2 * random - 1;
@@ -1601,9 +1611,18 @@ begin
ScriptEditor.cp.CalculateColorSpeed;
end;
-procedure TOperationLibrary.RandomizeWeights(AMachine: TatVirtualMachine);
+procedure TOperationLibrary.EqualizeWeights(AMachine: TatVirtualMachine);
+var i: smallint;
begin
- ScriptEditor.cp.RandomizeWeights;
+ for i := 0 to NumTransforms-1 do
+ ScriptEditor.cp.xform[i].density := 0.5;
+end;
+
+procedure TOperationLibrary.RandomizeWeights(AMachine: TatVirtualMachine);
+var i: smallint;
+begin
+ for i := 0 to NumTransforms-1 do
+ ScriptEditor.cp.xform[i].density := random;
end;
procedure TOperationLibrary.NormalizeWeights(AMachine: TatVirtualMachine);
@@ -1611,13 +1630,9 @@ begin
ScriptEditor.cp.NormalizeProbabilities;
end;
-procedure TOperationLibrary.EqualizeWeights(AMachine: TatVirtualMachine);
-begin
- ScriptEditor.cp.EqualizeWeights;
-end;
-
procedure TOperationLibrary.SetRenderBounds(AMachine: TatVirtualMachine);
begin
+ // AV: it actually does nothing special... just waste of time
ScriptRenderForm.SetRenderBounds;
end;
@@ -1726,16 +1741,17 @@ begin
LastError := 'SetFlameFile: ' + TextByKey('common-noparamfile');
AMachine.RuntimeError(LastError); // AV
AMachine.Halt;
- if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV
+ if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV
end;
end;
procedure TOperationLibrary.RotateProc(AMachine: TatVirtualMachine);
begin
try
- if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then raise EFormatInvalid.Create(ErrorOutOfRange);
- with AMachine do
- ScriptEditor.cp.xform[ActiveTransform].Rotate(GetInputArgAsFloat(0));
+ if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then
+ raise EFormatInvalid.Create(ErrorOutOfRange);
+ with ScriptEditor.cp.xform[ActiveTransform] do
+ Rotate(c, AMachine.GetInputArgAsFloat(0));
except on E: EFormatInvalid do
begin
// ScriptEditor.Console.Lines.Add('Rotate: ' + E.message);
@@ -1747,27 +1763,20 @@ end;
procedure TOperationLibrary.MulPXProc(AMachine: TatVirtualMachine);
-var k, m, l, n, pa, pb, pc, pd: double;
+var k, m, l, n: double;
begin
try
- if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then raise EFormatInvalid.Create(ErrorOutOfRange);
- with AMachine do
- begin
- k := GetInputArgAsFloat(0);
- m := GetInputArgAsFloat(1);
- l := GetInputArgAsFloat(2);
- n := GetInputArgAsFloat(3);
- end;
- with ScriptEditor.cp.xform[ActiveTransform] do begin
- pa := p[0,0];
- pb := -p[1,0];
- pc := -p[0,1];
- pd := p[1,1];
- p[0,0] := pa * k + pc * l;
- p[0,1] := -(pa * m + pc * n);
- p[1,0] := -(pb * k + pd * l);
- p[1,1] := pb * m + pd * n;
+ if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then
+ raise EFormatInvalid.Create(ErrorOutOfRange);
+ with AMachine do
+ begin
+ k := GetInputArgAsFloat(0);
+ m := GetInputArgAsFloat(1);
+ l := GetInputArgAsFloat(2);
+ n := GetInputArgAsFloat(3);
end;
+ with ScriptEditor.cp.xform[ActiveTransform] do
+ Multiply(p, k, l, m, n); // AV: my common method for both matrices
except on E: EFormatInvalid do
begin
// ScriptEditor.Console.Lines.Add('MultiplyPX: ' + E.message);
@@ -1778,33 +1787,23 @@ begin
end;
procedure TOperationLibrary.MulProc(AMachine: TatVirtualMachine);
-var k, m, l, n, ca, cb, cc, cd: double;
+var k, m, l, n: double;
begin
- if ScriptEditor.cp.xform[ActiveTransform].postXswap then
- begin
- MulPXProc(AMachine);
- Exit;
- end;
try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then raise EFormatInvalid.Create(ErrorOutOfRange);
with AMachine do
// ScriptEditor.cp.xform[ActiveTransform].Multiply(GetInputArgAsFloat(0), GetInputArgAsFloat(1), GetInputArgAsFloat(2), GetInputArgAsFloat(3));
begin
- k := GetInputArgAsFloat(0);
- m := GetInputArgAsFloat(1);
- l := GetInputArgAsFloat(2);
- n := GetInputArgAsFloat(3);
- end;
- with ScriptEditor.cp.xform[ActiveTransform] do begin
- ca := c[0,0];
- cb := -c[1,0];
- cc := -c[0,1];
- cd := c[1,1];
- c[0,0] := ca * k + cc * l;
- c[0,1] := -(ca * m + cc * n);
- c[1,0] := -(cb * k + cd * l);
- c[1,1] := cb * m + cd * n;
+ k := GetInputArgAsFloat(0);
+ m := GetInputArgAsFloat(1);
+ l := GetInputArgAsFloat(2);
+ n := GetInputArgAsFloat(3);
end;
+ with ScriptEditor.cp.xform[ActiveTransform] do
+ if postXswap then
+ Multiply(p, k, l, m, n) // AV: my common method for both matrices
+ else
+ Multiply(c, k, l, m, n);
except on E: EFormatInvalid do
begin
// ScriptEditor.Console.Lines.Add('Multiply: ' + E.message);
@@ -1829,15 +1828,15 @@ end;
procedure TOperationLibrary.SaveFlameProc(AMachine: TatVirtualMachine);
var
- filename: string;
+ filename, ext: string;
begin
with AMachine do
begin
filename := GetInputArgAsString(0);
- (*if (LowerCase(ExtractFileExt(filename)) = '.apo') or
- (LowerCase(ExtractFileExt(filename)) = '.fla') then
+ ext := LowerCase(ExtractFileExt(filename));
+ if (ext = '.apo') or (ext = '.fla') then // AV
MainForm.SaveFlame(ScriptEditor.cp, ScriptEditor.cp.name, filename)
- else *)
+ else
MainForm.SaveXMLFlame(ScriptEditor.cp, ScriptEditor.cp.name, filename)
end;
end;
@@ -1845,21 +1844,23 @@ end;
procedure TOperationLibrary.SaveGradientProc(AMachine: TatVirtualMachine);
var
gradstr: TStringList;
+ gradname: string;
begin
gradstr := TStringList.Create;
try
- gradstr.add(CleanIdentifier(AMachine.GetInputArgAsString(1)) + ' {');
- gradstr.add(MainForm.GradientFromPalette(ScriptEditor.cp.cmap, AMachine.GetInputArgAsString(1)));
+ gradname := AMachine.GetInputArgAsString(1); // AV
+ gradstr.add(CleanIdentifier(gradname) + ' {');
+ gradstr.add(MainForm.GradientFromPalette(ScriptEditor.cp.cmap, gradname));
gradstr.add('}');
- MainForm.SaveGradient(gradstr.text, AMachine.GetInputArgAsString(1), AMachine.GetInputArgAsString(0))
+ MainForm.SaveGradient(gradstr.text, gradname, AMachine.GetInputArgAsString(0));
finally
- gradstr.free
+ gradstr.free;
end;
end;
procedure TOperationLibrary.ListFileProc(AMachine: TatVirtualMachine);
var
- flafile: string;
+ flafile, ext: string;
i: integer;
begin
flafile := AMachine.GetInputArgAsString(0);
@@ -1867,17 +1868,15 @@ begin
begin
OpenFile := flafile;
MainForm.Caption := AppVersionString + ' - ' + OpenFile;
- (*if (LowerCase(ExtractFileExt(flafile)) = '.apo') or
- (LowerCase(ExtractFileExt(flafile)) = '.undo') then
- begin
- ListIFS(OpenFile, 1);
- OpenFileType := ftFla
+ ext := LowerCase(ExtractFileExt(flafile));
+ if (ext = '.apo') or (ext = '.undo') then begin
+ OpenFileType := ftApo;
+ ListIFS(OpenFile, 1);
end
- else
- begin*)
- ListXML(OpenFile, 1);
+ else begin
OpenFileType := ftXML;
- //end;
+ ListXML(OpenFile, 1);
+ end;
MainForm.SetFocus;
end
else
@@ -1901,7 +1900,7 @@ begin
v := AMachine.GetInputArgAsInteger(0);
if (v >= 0) and (v < NCPS) then
begin
- cps[v].copy(ScriptEditor.cp);
+ cps[v].copy(ScriptEditor.cp); // <-- AV: optimized for speed
cps[v].cmap := ScriptEditor.cp.cmap;
end
else begin
@@ -1915,22 +1914,25 @@ end;
procedure TOperationLibrary.GetFlameProc(AMachine: TatVirtualMachine);
var
- i, v: integer;
+ i, j: integer;
begin
- v := AMachine.GetInputArgAsInteger(0);
- if (v >= 0) and (v < NCPS) then
+ j := AMachine.GetInputArgAsInteger(0);
+ if (j >= 0) and (j < NCPS) then
begin
- ScriptEditor.cp.copy(cps[v]);
- ScriptEditor.cp.cmap := cps[v].cmap;
-
- for i := 0 to NXFORMS - 1 do
- if ScriptEditor.cp.xform[i].density = 0 then break;
- NumTransforms := i;
+ ScriptEditor.cp.copy(cps[j]); // <-- AV: optimized for speed
+ ScriptEditor.cp.cmap := cps[j].cmap;
+
+ for i := 0 to NXFORMS - 1 do
+ if ScriptEditor.cp.xform[i].density = 0 then break;
+ NumTransforms := i;
+
+ // AV: added a special method for easy gradient animation
+ RotateCMapHue(ScriptEditor.cp);
end
else begin
- LastError := 'GetFlame(' + IntToStr(v) + '): ' + TextByKey('script-status-varoutofrange');
- ScriptEditor.Editor.ActiveLine :=
- LineNumberFromInstruction(AMachine.CurrentInstruction); // AV
+ LastError := 'GetFlame(' + IntToStr(j) + '): ' + TextByKey('script-status-varoutofrange');
+ ScriptEditor.Editor.ActiveLine :=
+ LineNumberFromInstruction(AMachine.CurrentInstruction); // AV
ScriptEditor.Editor.ActiveLineSettings.ShowActiveLine := true; // AV
AMachine.Halt;
end;
@@ -1940,13 +1942,10 @@ procedure LoadXMLFlame(index: integer);
var
FStrings: TStringList;
IFSStrings: TStringList;
- EntryStrings, Tokens: TStringList;
i: integer;
begin
FStrings := TStringList.Create;
IFSStrings := TStringList.Create;
- Tokens := TStringList.Create;
- EntryStrings := TStringList.Create;
try
FStrings.LoadFromFile(ParamFile);
@@ -1954,9 +1953,9 @@ begin
begin
if Pos(' 0;
ScriptEditor.cp.Clear; // initialize control point for new flame;
ScriptEditor.cp.background[0] := 0;
ScriptEditor.cp.background[1] := 0;
@@ -2011,57 +1986,27 @@ begin
ScriptEditor.cp.sample_density := defSampleDensity;
ScriptEditor.cp.spatial_oversample := defOversample;
ScriptEditor.cp.spatial_filter_radius := defFilterRadius;
- for i := 0 to FStrings.count - 1 do
- begin
- if Pos(Lowercase(FileList[index]) + ' ', Trim(Lowercase(FStrings[i]))) = 1 then
- break;
- end;
- inc(i);
- while (Pos('}', FStrings[i]) = 0) and (Pos('palette:', FStrings[i]) = 0) do
- begin
- EntryStrings.Add(FStrings[i]);
- inc(i);
- end;
- if Pos('palette:', FStrings[i]) = 1 then
- begin
- SavedPal := True;
- inc(i);
- for j := 0 to 255 do begin
- s := FStrings[i];
- GetTokens(s, Tokens);
- Palette[j][0] := StrToInt(Tokens[0]);
- Palette[j][1] := StrToInt(Tokens[1]);
- Palette[j][2] := StrToInt(Tokens[2]);
- inc(i);
- end;
- end;
- FlameString := EntryStrings.Text;
- ScriptEditor.cp.ParseString(FlameString);
+
+ FlameFromUndo(ScriptEditor.cp, ScFileList[index], ParamFile); // AV
+
for i := 0 to NXFORMS - 1 do
if ScriptEditor.cp.xform[i].density = 0 then break;
NumTransforms := i;
- if SavedPal then ScriptEditor.cp.cmap := Palette;
- ScriptEditor.cp.name := FileList[index];
- finally
- IFSStrings.Free;
- FStrings.Free;
- Tokens.free;
- EntryStrings.free;
- end;
end;
procedure TOperationLibrary.LoadFlameProc(AMachine: TatVirtualMachine);
var
i: integer;
+ ext: string;
begin
i := AMachine.GetInputArgAsInteger(0);
- if (i >= 0) and (i < FileList.count) then
+ if (i >= 0) and (i < ScFileList.count) then
begin
- (*if (LowerCase(ExtractFileExt(ParamFile)) = '.undo') or
- (LowerCase(ExtractFileExt(ParamFile)) = '.apo') then
- LoadFlame(i)
- else*)
- LoadXMLFlame(i); ;
+ ext := LowerCase(ExtractFileExt(ParamFile));
+ if (ext = '.apo') or (ext = '.undo') then
+ LoadFlame(i) // AV: added support for Undo files
+ else
+ LoadXMLFlame(i);
end;
end;
@@ -2121,14 +2066,15 @@ end;
procedure TOperationLibrary.ScaleProc(AMachine: TatVirtualMachine);
begin
try
- if (ActiveTransform < 0) or (ActiveTransform >= ScriptEditor.cp.NumXForms) then raise EFormatInvalid.Create(ErrorOutOfRange);
- with AMachine do
- ScriptEditor.cp.xform[ActiveTransform].Scale(GetInputArgAsFloat(0));
+ if (ActiveTransform < 0) or (ActiveTransform >= ScriptEditor.cp.NumXForms) then
+ raise EFormatInvalid.Create(ErrorOutOfRange);
+ with ScriptEditor.cp.xform[ActiveTransform] do
+ Scale(c, AMachine.GetInputArgAsFloat(0));
except on E: EFormatInvalid do
begin
- //ScriptEditor.Console.Lines.Add('Scale: ' + E.message);
- Application.ProcessMessages;
+ //ScriptEditor.Console.Lines.Add('Scale: ' + E.message);
LastError := 'Scale: ' + E.Message;
+ Application.ProcessMessages;
end;
end;
end;
@@ -2152,26 +2098,9 @@ begin
end;
procedure TOperationLibrary.GetVariation(AMachine: TatVirtualMachine);
-var
- i, n: integer;
begin
- with AMachine do
- begin
- // AV: something was wrong here, I rewrote it...
- { i := integer(Variation);
- if (i >= NRVAR) or (i < 0) then
- i := -1; }
- i := 0;
- if MainForm.mnuVRandom.Checked then i := -1
- else
- for n := 0 to NRVAR - 1 do
- if MainForm.VarMenus[n].Checked then
- begin
- i := n;
- break;
- end;
- ReturnOutputArg(i);
- end
+ // AV: changed Variation to integer - no more ugly type-casting here!
+ AMachine.ReturnOutputArg(Variation);
end;
procedure TOperationLibrary.SetVariation(AMachine: TatVirtualMachine);
@@ -2182,32 +2111,32 @@ begin
begin
i := GetInputArgAsInteger(0);
if (i < 0) or (i >= NRVAR) then
- i := NRVAR;
- if i = NRVAR then
begin
MainForm.mnuVRandom.Checked := True;
- // AV: outdated type...
- Variation := vRandom;
// AV: only one variation type can be active
- for i := 0 to NRVAR - 1 do
- MainForm.VarMenus[i].Checked := False;
- MainForm.mnuBuiltinVars.Checked := False;
- MainForm.mnuPluginVars.Checked := False;
+ if Variation > vRandom then begin
+ MainForm.VarMenus[Variation].Checked := False;
+ MainForm.mnuBuiltinVars.Checked := False;
+ MainForm.mnuPluginVars.Checked := False;
+ end;
+ Variation := vRandom; // AV: outdated type, I changed it to integer
end else
begin
MainForm.VarMenus[i].Checked := True;
MainForm.mnuVRandom.Checked := False;
- Variation := TVariation(i);
- if (i >= NumBuiltinVars) then
+ if Variation > vRandom then
+ MainForm.VarMenus[Variation].Checked := False
+ else
+ MainForm.mnuVRandom.Checked := False;
+
+ // AV: changed Variation to integer - no more ugly type-casting here!
+ Variation := i;
+ if (i >= NumBuiltinVars) then // AV: fixme
begin
- for i := 0 to NumBuiltinVars-1 do
- MainForm.VarMenus[i].Checked := False; // AV: fixme
MainForm.mnuBuiltinVars.Checked := False;
MainForm.mnuPluginVars.Checked := True;
end
else begin
- for i := NumBuiltinVars to NrVar - 1 do
- MainForm.VarMenus[i].Checked := False; // AV: fixme
MainForm.mnuBuiltinVars.Checked := True;
MainForm.mnuPluginVars.Checked := False;
end;
@@ -2221,9 +2150,13 @@ var
str: string;
begin
with AMachine do begin
+ {
str := LowerCase(GetInputArgAsString(0));
i := NRVAR-1;
while (i >= 0) and (LowerCase(varnames(i)) <> str) do Dec(i);
+ }
+ str := GetInputArgAsString(0); // AV
+ i := GetVariationIndex(str); // AV
ReturnOutputArg(i);
end;
end;
@@ -2248,9 +2181,9 @@ var
str: string;
begin
with AMachine do begin
- str := LowerCase(GetInputArgAsString(0));
+ str := GetInputArgAsString(0);
i := GetNrVariableNames-1;
- while (i >= 0) and (LowerCase(GetVariableNameAt(i)) <> str) do Dec(i);
+ while (i >= 0) and (GetVariableNameAt(i) <> str) do Dec(i);
ReturnOutputArg(i);
end;
end;
@@ -2258,7 +2191,6 @@ end;
procedure TOperationLibrary.VariableNameProc(AMachine: TatVirtualMachine);
var
i: integer;
- str: string;
begin
with AMachine do begin
i := GetInputArgAsInteger(0);
@@ -2272,7 +2204,7 @@ end;
procedure TOperationLibrary.FileCountProc(AMachine: TatVirtualMachine);
begin
with AMachine do
- ReturnOutputArg(FileList.Count);
+ ReturnOutputArg(ScFileList.Count);
end;
procedure TOperationLibrary.ClearProc(AMachine: TatVirtualMachine);
@@ -2281,12 +2213,9 @@ var
begin
NumTransforms := 0;
ActiveTransform := -1;
-{
- for i := 0 to NXFORMS - 1 do
- ScriptEditor.cp.xform[i].density := 0;
-}
+
ScriptEditor.cp.Clear;
- ScriptEditor.cp.xform[0].symmetry := 1;
+ ScriptEditor.cp.xform[0].symmetry := 1; // AV: why?
with ScriptEditor.cp do
begin // AV: added 3D-camera resetting for new flames
@@ -2299,6 +2228,28 @@ begin
end;
end;
+procedure TOperationLibrary.PrepareToMorphProc(AMachine: TatVirtualMachine);
+var
+ a, b: integer;
+begin
+ with AMachine do
+ begin
+ a := GetInputArgAsInteger(0);
+ b := GetInputArgAsInteger(1);
+ if (a >= 0) and (a < NCPS) and (b >= 0) and (b < NCPS) then
+ begin
+ PrepareToInterpolation(cps[a], cps[b]); // adjust flame parameters
+ end
+ else begin
+ LastError := Format('PrepareToMorph(%d, %d): ', [a, b]) +
+ TextByKey('script-status-varoutofrange');
+ RuntimeError(LastError);
+ Scripter.Halt;
+ if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV: show errors
+ end;
+ end;
+end;
+
procedure TOperationLibrary.MorphProc(AMachine: TatVirtualMachine);
var
a, b, i: integer;
@@ -2325,7 +2276,7 @@ begin
TextByKey('script-status-varoutofrange');
RuntimeError(LastError);
Scripter.Halt;
- if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV: show errors
+ if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV: show errors
end;
end;
end;
@@ -2335,7 +2286,7 @@ begin
if NumTransforms > 0 then
begin
//AMachine.Paused := True; // AV: it doesn't let to pause the animation
- PreviewForm.cp.Copy(ScriptEditor.cp);
+ PreviewForm.cp.Copy(ScriptEditor.cp); // <-- AV: optimized for speed
PreviewForm.cp.AdjustScale(PreviewForm.Image.Width, PreviewForm.Image.Height);
PreviewForm.Show;
PreviewForm.DrawFlame;
@@ -2443,9 +2394,9 @@ begin
except
Application.ProcessMessages;
LastError := 'DeleteTransform: Oops!';
- i := LineNumberFromInstruction(AMachine.CurrentInstruction); // AV
- ScriptEditor.Editor.ActiveLine := i;
- ScriptEditor.Editor.ActiveLineSettings.ShowActiveLine := true; // AV
+ i := LineNumberFromInstruction(AMachine.CurrentInstruction); // AV
+ ScriptEditor.Editor.ActiveLine := i;
+ ScriptEditor.Editor.ActiveLineSettings.ShowActiveLine := true; // AV
Scripter.Halt;
end;
end;
@@ -2482,25 +2433,18 @@ end;
procedure TOperationLibrary.TranslateProc(AMachine: TatVirtualMachine);
var x, y: double;
begin
- if ScriptEditor.cp.xform[ActiveTransform].postXswap then
- begin
- TranslatePXProc(AMachine);
- Exit;
- end;
try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then // was: NXFORMS-1
raise EFormatInvalid.Create(ErrorOutOfRange);
- with AMachine do
- // AV: matrix multiplication must not affect the translation
- // ScriptEditor.cp.xform[ActiveTransform].Translate(GetInputArgAsFloat(0), GetInputArgAsFloat(1));
- begin
- x := GetInputArgAsFloat(0);
- y := -1 * GetInputArgAsFloat(1);
- end;
- with ScriptEditor.cp.xform[ActiveTransform] do begin
- c[2,0] := c[2,0] + x;
- c[2,1] := c[2,1] + y;
- end;
+ // AV: matrix multiplication must not affect the translation
+ // ScriptEditor.cp.xform[ActiveTransform].Translate(GetInputArgAsFloat(0), GetInputArgAsFloat(1));
+ x := AMachine.GetInputArgAsFloat(0);
+ y := AMachine.GetInputArgAsFloat(1);
+ with ScriptEditor.cp.xform[ActiveTransform] do
+ if postXswap then
+ Translate(p, x, y)
+ else
+ Translate(c, x, y);
except on E: EFormatInvalid do
begin
Application.ProcessMessages;
@@ -2516,15 +2460,11 @@ begin
try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then
raise EFormatInvalid.Create(ErrorOutOfRange);
- with AMachine do
- begin
- x := GetInputArgAsFloat(0);
- y := -1 * GetInputArgAsFloat(1);
- end;
- with ScriptEditor.cp.xform[ActiveTransform] do begin
- p[2,0] := p[2,0] + x;
- p[2,1] := p[2,1] + y;
- end;
+
+ x := AMachine.GetInputArgAsFloat(0);
+ y := AMachine.GetInputArgAsFloat(1);
+ with ScriptEditor.cp.xform[ActiveTransform] do
+ Translate(p, x, y);
except on E: EFormatInvalid do
begin
Application.ProcessMessages;
@@ -2534,6 +2474,33 @@ begin
end;
end;
+procedure NormalizeVariations(var cp1: TControlPoint); // AV: moved from Main
+var
+ totvar, v: double;
+ i, j: integer;
+begin
+ for i := 0 to cp1.NumXForms do
+ begin
+ totvar := 0;
+ for j := 0 to NRVAR - 1 do
+ begin
+ v := cp1.xform[i].GetVariation(j); // AV
+ if v < 0 then
+ cp1.xform[i].SetVariation(j, -v);
+ totvar := totvar + v;
+ end;
+ if totVar = 0 then
+ cp1.xform[i].SetVariation(0, 1)
+ else
+ for j := 0 to NRVAR - 1 do begin
+ v := cp1.xform[i].GetVariation(j); // AV
+ //if totVar <> 0 then // <-- AV: we've already check it!
+ if v <> 0 then // AV: because 0/totvar = 0
+ cp1.xform[i].SetVariation(j, v / totvar);
+ end;
+ end;
+end;
+
procedure TOperationLibrary.NormalizeVars(AMachine: TatVirtualMachine);
begin
NormalizeVariations(ScriptEditor.cp);
@@ -2552,7 +2519,7 @@ begin
btnSave.Hint := TextByKey('script-save');
btnRun.Hint := TextByKey('script-run');
btnStop.Hint := TextByKey('script-stop');
- btnFavorite.Hint := TextByKey('script-faves');
+ btnFavorite.Hint := TextByKey('script-faves');
CodeButton.Hint := TextByKey('script-codeblocks');
btnPause.Hint := TextByKey('script-pause');
ShowCodeHints.Caption := TextByKey('script-codeblockhints');
@@ -2581,15 +2548,23 @@ begin
DTError := #13#10 + TextByKey('script-compileerror') + #13#10 +
StringOfChar('=', length(TextByKey('script-compileerror'))) + #13#10;
+ // AV: moved this into OnCreate handler since filters never change
+ MainOpenDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*',
+ [TextByKey('common-filter-scriptfiles'),
+ TextByKey('common-filter-allfiles')]);
+ MainSaveDialog.Filter := MainOpenDialog.Filter; // AV
+
// AV: added language translation here:
SaveDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame;*rand;*.template|'
- + TextByKey('common-filter-allfiles') + '|*.*';
- OpenDialog.Filter := TextByKey('common-filter-flamefiles') + '|*.flame;*rand;*.template|' +
- TextByKey('common-filter-scriptfiles') + '|*.asc;*aposcript|' +
- TextByKey('common-filter-allfiles') + '|*.*';
+ + TextByKey('common-filter-undofiles') + '|*.undo;*.apo|'
+ + TextByKey('common-filter-allfiles') + '|*.*';
+ OpenDialog.Filter := TextByKey('common-filter-flamefiles') +'|*.flame;*rand;*.template|' +
+ TextByKey('common-filter-scriptfiles') + '|*.asc;*aposcript|' +
+ TextByKey('common-filter-undofiles') + '|*.undo;*.apo|' +
+ TextByKey('common-filter-allfiles') + '|*.*';
Transform := TTransform.create;
- FileList := TStringList.Create;
+ ScFileList := TStringList.Create;
Flame := TFlame.Create;
Options := TOptions.Create;
Pivot := TPivot.Create;
@@ -2609,15 +2584,15 @@ begin
except
Editor.Lines.Clear;
end;
-
- AdjustScripterColors; // AV: change scripter font ang background for dark themes
+ // AV: change scripter font ang background for dark themes
+ AdjustScripterColors;
end;
procedure TScriptEditor.FormDestroy(Sender: TObject);
var
i: integer;
begin
- FileList.Free;
+ ScFileList.Free;
Renderer.Free;
Another.Free;
for i := 0 to 9 do
@@ -2720,7 +2695,7 @@ begin
with AMachine do
begin
v := GetInputArgAsFloat(0);
- if (v > 0) and (v <= 5) then cp.Gamma := v; // AV: added max check
+ if (v > 0) and (v <= 10) then cp.Gamma := v; // AV: added max check
end;
end;
@@ -3059,6 +3034,16 @@ begin
AMachine.ReturnOutPutArg(cp.name);
end;
+procedure TScriptEditor.SetFlameCommentProc(AMachine: TatVirtualMachine);
+begin
+ cp.comment := AMachine.GetInputArgAsString(0);
+end;
+
+procedure TScriptEditor.GetFlameCommentProc(AMachine: TatVirtualMachine);
+begin
+ AMachine.ReturnOutPutArg(cp.comment);
+end;
+
(*
procedure TScriptEditor.SetFlameNickProc(AMachine: TatVirtualMachine);
begin
@@ -3961,7 +3946,7 @@ begin
k := SelStartY;
m := SelEndY;
end;
- BlockIndent(k, m, 4);
+ BlockIndent(k, m, 4);
if Sender = BeginEnd1 then begin
InsertTextAtXY('begin'#13#10, 0, k);
InsertTextAtXY('end;'#13#10, 0, m + 2);
@@ -4050,8 +4035,8 @@ begin
with cp.xform[ActiveTransform] do
begin
- c[0,0] := -c[0,0];
- c[1,0] := -c[1,0];
+ c[0,0] := -c[0,0];
+ c[1,0] := -c[1,0];
with EditForm do
if (PivotMode = PivotWorld) then
c[2,0] := 2 * WorldPivot.x - c[2,0];
@@ -4068,8 +4053,8 @@ begin
with cp.xform[ActiveTransform] do
begin
- p[0,0] := -p[0,0];
- p[1,0] := -p[1,0];
+ p[0,0] := -p[0,0];
+ p[1,0] := -p[1,0];
with EditForm do
if (PivotMode = PivotWorld) then
p[2,0] := 2 * WorldPivot.x - p[2,0];
@@ -4092,8 +4077,8 @@ begin
with cp.xform[ActiveTransform] do
begin
- c[0,1] := -c[0,1];
- c[1,1] := -c[1,1];
+ c[0,1] := -c[0,1];
+ c[1,1] := -c[1,1];
with EditForm do
if (PivotMode = PivotWorld) then
c[2,1] := -2 * WorldPivot.y - c[2,1];
@@ -4110,8 +4095,8 @@ begin
with cp.xform[ActiveTransform] do
begin
- p[0,1] := -p[0,1];
- p[1,1] := -p[1,1];
+ p[0,1] := -p[0,1];
+ p[1,1] := -p[1,1];
with EditForm do
if (PivotMode = PivotWorld) then
p[2,1] := -2 * WorldPivot.y - p[2,1];
@@ -4187,7 +4172,6 @@ end;
procedure TScriptEditor.TransformScalePXProc(AMachine: TatVirtualMachine);
var
- i, j: integer;
s: double;
begin
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then begin
@@ -4199,9 +4183,7 @@ begin
s := AMachine.GetInputArgAsFloat(0);
with cp.xform[ActiveTransform] do
begin
- for i := 0 to 1 do
- for j:= 0 to 1 do
- p[i,j] := p[i,j] * s;
+ Scale(p, s);
with EditForm do
if (PivotMode = PivotWorld) then
begin
@@ -4213,33 +4195,26 @@ end;
procedure TScriptEditor.TransformRotatePXProc(AMachine: TatVirtualMachine);
var
- v, tx, ty, tx0, tx1, ty0, ty1, sv, cv: double;
+ v, tx, ty, sv, cv: double;
begin
try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS) then
raise EFormatInvalid.Create('Transform.RotatePX: ' + ErrorOutOfRange);
- with AMachine do
- v := GetInputArgAsFloat(0) * PI / 180;
- SinCos(v, sv, cv);
- with cp.xform[ActiveTransform] do
- begin
- tx0 := p[0,0] * cv - (-p[0,1] * sv);
- tx1 := p[0,0] * sv + (-p[0,1] * cv);
- ty0 := -p[1,0] * cv - p[1,1] * sv;
- ty1 := -p[1,0] * sv + p[1,1] * cv;
- p[0,0] := tx0;
- p[0,1] := -tx1;
- p[1,0] := -ty0;
- p[1,1] := ty1;
- with EditForm do
- if (PivotMode = PivotWorld) then
- begin
- tx := WorldPivot.x + (p[2,0] - WorldPivot.x) * cv - (-p[2,1] - WorldPivot.y) * sv;
- ty := WorldPivot.y + (p[2,0] - WorldPivot.x) * sv + (-p[2,1] - WorldPivot.y) * cv;
- p[2,0] := tx;
- p[2,1] := -ty;
- end;
- end;
+ with AMachine do
+ v := GetInputArgAsFloat(0) * PI / 180;
+ SinCos(v, sv, cv);
+ with cp.xform[ActiveTransform] do
+ begin
+ Multiply(p, cv, -sv, sv, cv); // AV: my common method for both matrices
+ with EditForm do
+ if (PivotMode = PivotWorld) then
+ begin
+ tx := WorldPivot.x + (p[2,0] - WorldPivot.x) * cv - (-p[2,1] - WorldPivot.y) * sv;
+ ty := WorldPivot.y + (p[2,0] - WorldPivot.x) * sv + (-p[2,1] - WorldPivot.y) * cv;
+ p[2,0] := tx;
+ p[2,1] := -ty;
+ end;
+ end;
except on E: EFormatInvalid do
begin
Application.ProcessMessages;
@@ -4411,6 +4386,8 @@ end;
procedure TScriptEditor.PrepareScripter;
var
i: integer;
+ lib : TStringList;
+ s: string;
begin
Scripter.AddLibrary(TatSysUtilsLibrary);
with Scripter.defineClass(TScriptRender) do
@@ -4445,6 +4422,7 @@ begin
DefineProp('Gradient', tkInteger, GetFlamePaletteProc, SetFlamePaletteProc, nil, false, 2);
DefineProp('Background', tkInteger, GetFlameBackgroundProc, SetFlameBackgroundProc, nil, false, 1);
DefineProp('Name', tkString, GetFlameNameProc, SetFlameNameProc);
+ DefineProp('Comment', tkString, GetFlameCommentProc, SetFlameCommentProc);
// DefineProp('Nick', tkString, GetFlameNickProc, SetFlameNickProc);
// DefineProp('URL', tkString, GetFlameURLProc, SetFlameURLProc);
DefineProp('Hue', tkFloat, GetFlameHueProc, SetFlameHueProc);
@@ -4490,23 +4468,23 @@ begin
DefineMethod('Scale', 1, tkNone, nil, TransformScaleProc);
DefineMethod('RotateOrigin', 1, tkNone, nil, TransformRotateOriginProc);
- DefineMethod('RotatePXOrigin', 1, tkNone, nil, TransformRotatePXOriginProc);
- DefineMethod('RotatePX', 1, tkNone, nil, TransformRotatePXProc);
- DefineMethod('ScalePX', 1, tkNone, nil, TransformScalePXProc);
- DefineMethod('FlipPXHoriz', 0, tkNone, nil, TransformFlipPXHorizProc);
- DefineMethod('FlipHoriz', 0, tkNone, nil, TransformFlipHorizProc);
- DefineMethod('FlipPXVert', 0, tkNone, nil, TransformFlipPXVertProc);
- DefineMethod('FlipVert', 0, tkNone, nil, TransformFlipVertProc);
- DefineMethod('SwapCoefs', 0, tkNone, nil, TransformSwapCoefsProc);
- DefineMethod('ResetVariables', 0, tkNone, nil, TransformResetVariables);
+ DefineMethod('RotatePXOrigin', 1, tkNone, nil, TransformRotatePXOriginProc);
+ DefineMethod('RotatePX', 1, tkNone, nil, TransformRotatePXProc);
+ DefineMethod('ScalePX', 1, tkNone, nil, TransformScalePXProc);
+ DefineMethod('FlipPXHoriz', 0, tkNone, nil, TransformFlipPXHorizProc);
+ DefineMethod('FlipHoriz', 0, tkNone, nil, TransformFlipHorizProc);
+ DefineMethod('FlipPXVert', 0, tkNone, nil, TransformFlipPXVertProc);
+ DefineMethod('FlipVert', 0, tkNone, nil, TransformFlipVertProc);
+ DefineMethod('SwapCoefs', 0, tkNone, nil, TransformSwapCoefsProc);
+ DefineMethod('ResetVariables', 0, tkNone, nil, TransformResetVariables);
- DefineMethod('SetVariationOrder', 2, tkNone, nil, TransformMoveVarProc);
- DefineMethod('SwapVariations', 2, tkNone, nil, TransformExchangeVarsProc);
- DefineMethod('SortVariationsByName', 0, tkNone, nil, TransformSortVarsProc);
- DefineMethod('SortVariationsByIndex', 0, tkNone, nil, TransformDefaultVarOrderProc);
- DefineMethod('GetVariationOrder', 1, tkInteger, nil, TransformGetVarOrderProc);
- DefineMethod('CopyVariationsOrder', 1, tkInteger, nil, TransformCopyVarOrderProc);
- DefineMethod('PrintVariationsOrder', 0, tkNone, nil, TransformDisplayVarsProc);
+ DefineMethod('SetVariationOrder', 2, tkNone, nil, TransformMoveVarProc);
+ DefineMethod('SwapVariations', 2, tkNone, nil, TransformExchangeVarsProc);
+ DefineMethod('SortVariationsByName', 0, tkNone, nil, TransformSortVarsProc);
+ DefineMethod('SortVariationsByIndex', 0, tkNone, nil, TransformDefaultVarOrderProc);
+ DefineMethod('GetVariationOrder', 1, tkInteger, nil, TransformGetVarOrderProc);
+ DefineMethod('CopyVariationsOrder', 1, tkInteger, nil, TransformCopyVarOrderProc);
+ DefineMethod('PrintVariationsOrder', 0, tkNone, nil, TransformDisplayVarsProc);
DefineProp('a', tkFloat, GetTransformAProc, SetTransformAProc);
DefineProp('b', tkFloat, GetTransformBProc, SetTransformBProc);
@@ -4520,8 +4498,8 @@ begin
DefineProp('PlotMode', tkInteger, GetTransformPlotModeProc, SetTransformPlotModeProc);
DefineProp('Opacity', tkFloat, GetTransformOpacityProc, SetTransformOpacityProc);
- DefineProp('PostXformEnabled', tkInteger, GetTransformPostxformEnabledProc, SetTransformPostxformEnabledProc);
- DefineProp('Name', tkString, GetTransformNameProc, SetTransformNameProc);
+ DefineProp('PostXformEnabled', tkInteger, GetTransformPostxformEnabledProc, SetTransformPostxformEnabledProc);
+ DefineProp('Name', tkString, GetTransformNameProc, SetTransformNameProc);
end;
Scripter.AddObject('Transform', Transform);
@@ -4637,7 +4615,7 @@ begin
{ Variations }
Scripter.AddConstant('V_LINEAR', 0);
- Scripter.AddConstant('V_RANDOM', -1);
+ Scripter.AddConstant('V_RANDOM', vRandom);
// Scripter.AddLibrary(TatWindowsLibrary);
// Scripter.AddLibrary(TatFormsLibrary);
@@ -4646,8 +4624,7 @@ begin
Scripter.AddLibrary(TatSysUtilsLibrary);
Scripter.AddLibrary(TatFileCtrlLibrary);
Scripter.AddLibrary(TatClassesLibrary);
- { Nonsense - it's the only way to get the last real
- library to work! }
+ { Nonsense - it's the only way to get the last real library to work! }
Scripter.AddObject('Not_Any_Thing_Useful', Another);
Scripter.AddObject('IglooFunkyRubber', Another);
Scripter.AddObject('Scrumptious', Another);
@@ -4660,7 +4637,21 @@ begin
// AV: moved into main library to let user choose which CopyFile must be called
Scripter.SystemLibrary.DefineMethod('CopyFile', 3, tkVariant, nil, CopyFileProc, false, 1);
- RegisterClasses([TButton, TLabel, TEdit, TComboBox]); // AV: to load external Delphi forms
+ if FileExists(defLibrary) then // AV: add user's defined methods
+ begin
+ lib := TStringList.Create;
+ try
+ lib.LoadFromFile(defLibrary);
+ for s in lib do
+ if (pos('procedure', LowerCase(s)) > 0) or (pos('function', LowerCase(s)) > 0) then
+ Editor.SyntaxStyles.AutoCompletion.Add(Trim(s));
+ finally
+ lib.Free;
+ end;
+ end;
+
+ // AV: to load external Delphi forms
+ RegisterClasses([TButton, TLabel, TEdit, TComboBox]);
end;
{ ************************* Buttons ***************************************** }
@@ -4672,7 +4663,7 @@ begin
if ConfirmClearScript then
begin
if Editor.LinesModified then // AV: if script changes not saved yet
- c := (Application.MessageBox(PChar(TextByKey('script-confirmclear')), 'Apophysis', 52) = IDYES)
+ c := (Application.MessageBox(PChar(TextByKey('script-confirmclear')), ApophysisSVN, 52) = IDYES)
else
c := True;
end
@@ -4689,7 +4680,7 @@ end;
procedure TScriptEditor.LoadScriptFile(filename:string);
var
s: string;
- fn:string;
+ fn: string;
begin
Editor.Lines.LoadFromFile(filename);
s := ExtractFileName(filename);
@@ -4701,22 +4692,20 @@ end;
procedure TScriptEditor.OpenScript;
var
s: string;
- fn:string;
+ fn: string;
begin
MainOpenDialog.InitialDir := ScriptPath;
MainOpenDialog.Filename := '';
- MainOpenDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*', [TextByKey('common-filter-scriptfiles'), TextByKey('common-filter-allfiles')]);
- if OpenSaveFileDialog(ScriptEditor, '.aposcript', MainOpenDialog.Filter, MainOpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
-// if MainOpenDialog.execute then
+ if MainOpenDialog.execute then
begin
- MainOpenDialog.FileName := fn;
- Script := MainOpenDialog.Filename;
- Editor.Lines.LoadFromFile(MainOpenDialog.Filename);
- s := ExtractFileName(MainOpenDialog.Filename);
+ fn := MainOpenDialog.FileName; // AV
+ Script := fn;
+ Editor.Lines.LoadFromFile(fn);
+ s := ExtractFileName(fn);
s := Copy(s, 0, length(s) - Length(ExtractFileExt(s)));
MainForm.mnuRun.Caption := Format(TextByKey('main-menu-script-run2'), [s]);
Caption := s;
- ScriptPath := ExtractFileDir(MainOpenDialog.Filename);
+ ScriptPath := ExtractFileDir(fn);
end;
end;
@@ -4746,17 +4735,14 @@ end;
procedure TScriptEditor.btnSaveClick(Sender: TObject);
var fn : string;
begin
- if Script = '' then fn := ''
- else fn := ChangeFileExt(ExtractFileName(Script), '.aposcript');
- if OpenSaveFileDialog(ScriptEditor, '.aposcript',
- Format('%s|*.aposcript;*.asc|%s|*.*',
- [TextByKey('common-filter-scriptfiles'),
- TextByKey('common-filter-allfiles')]),
- ScriptPath, TextByKey('common-browse'), fn,
- false, true, false, false) then
- //if MainSaveDialog.Execute then
+ if Script = '' then
+ MainSaveDialog.Filename := ''
+ else
+ MainSaveDialog.Filename := ChangeFileExt(ExtractFileName(Script), '.aposcript');
+ MainSaveDialog.InitialDir := ScriptPath;
+ if MainSaveDialog.Execute then
begin
- MainOpenDialog.FileName := fn;
+ fn := MainSaveDialog.FileName; // AV
Script := fn;
Editor.Lines.SaveToFile(fn);
Caption := ExtractFileName(fn);
@@ -4775,13 +4761,11 @@ begin
FStrings := TStringList.Create;
FStrings.LoadFromFile(ParamFile);
try
- FileList.Clear;
+ ScFileList.Clear;
ext := LowerCase(ExtractFileExt(ParamFile));
- (*if (ext = '.fla') or (ext = '.apo') then
- begin
-
- // Get names from .fla or .apo file
+ if (ext = '.fla') or (ext = '.apo') then // AV
+ begin // Get names from .undo or .apo file
if (Pos('{', FStrings.Text) <> 0) then
for i := 0 to FStrings.Count - 1 do
begin
@@ -4791,15 +4775,13 @@ begin
Title := Trim(Copy(FStrings[i], 1, p - 1));
if Title <> '' then
begin { Otherwise bad format }
- FileList.Add(Trim(Copy(FStrings[i], 1, p - 1)));
+ ScFileList.Add(Trim(Copy(FStrings[i], 1, p - 1)));
end;
end;
end;
-
end
else
-
- begin *)
+ begin
// Get names from .flame file
if (Pos(' 0) then
begin
@@ -4809,17 +4791,16 @@ begin
if (p <> 0) then
begin
pname := '';
- MainForm.ListXMLScanner.LoadFromBuffer(PANSICHAR(AnsiString(FSTrings[i])));
+ MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FStrings[i])));
MainForm.ListXMLScanner.Execute;
if Trim(pname) = '' then
Title := '*untitled ' + ptime
else
- FileList.Add(pname);
+ ScFileList.Add(pname);
end;
end;
-
end;
- //end;
+ end;
finally
FStrings.Free;
end;
@@ -4852,7 +4833,7 @@ begin
LastError := 'CopyFile: ' + TextByKey('common-genericcopyfailure');
RuntimeError(LastError); // AV
Halt;
- if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV
+ if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV
end
else begin
if not FileExists(src) then
@@ -4861,7 +4842,7 @@ begin
LastError := 'CopyFile: ' + TextByKey('render-status-pathdoesnotexist');
RuntimeError(LastError); // AV
Halt;
- if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV
+ if LoadForm.CheckBox1.Checked then LoadForm.Show; // AV
end;
end;
end;
@@ -4902,7 +4883,7 @@ begin
ActiveTransform := EditForm.SelectedTriangle;
NumTransforms := Transforms;
cp.copy(MainCp);
- cmap := MainCp.cmap;
+ //cmap := MainCp.cmap; // <-- is used nowhere
Application.ProcessMessages;
Randomize;
StatusBar.SimpleText := TextByKey('script-status-executing');
@@ -4914,6 +4895,7 @@ begin
MainForm.mnuStop.Enabled := True;
MainForm.btnStopScript.Enabled := True;
end;
+
with Scripter do
begin
SourceCode.Assign(Editor.Lines);
@@ -4934,10 +4916,20 @@ begin
//Compile;
Execute;
end;
+
if (NumTransforms < 1) and UpdateIt then
+ Console.Lines.Add(TextByKey('script-status-notransforms'))
+ else if (LastError = '') and UpdateIt then
begin
- Console.Lines.Add(TextByKey('script-status-notransforms'));
- ScriptRenderForm.Close;
+ MainForm.UpdateUndo;
+ MainCp.Copy(cp);
+ UpdateFlame;
+ if ResetLocation then MainForm.ResetLocation;
+ end
+ else
+ Console.Lines.Add(LastError);
+
+ if ScriptRenderForm.Visible then ScriptRenderForm.Close;
btnRun.Enabled := True;
btnStop.Enabled := False;
MainForm.btnRunScript.Enabled := True;
@@ -4945,38 +4937,11 @@ begin
MainForm.mnuRun.Enabled := True;
MainForm.mnuStop.Enabled := False;
btnBreak.Enabled := False;
- btnPause.Enabled := False;
- StatusBar.SimpleText := StatusBar.Hint;
- // AV: to continue work with these scripts
+ btnPause.Enabled := False;
+ // AV: restore the status of submenus to continue work with these scripts
MainForm.FavouriteScripts1.Enabled := favs;
MainForm.Directory1.Enabled := defs;
- Exit;
- end
- else
- if (LastError = '') and UpdateIt then
- begin
- MainForm.UpdateUndo;
- MainCp.Copy(cp);
- UpdateFlame;
- if ResetLocation then MainForm.ResetLocation;
- end
- else
- begin
- Console.Lines.Add(LastError);
- end;
- ScriptRenderForm.Close;
- btnRun.Enabled := True;
- btnStop.Enabled := False;
- MainForm.btnRunScript.Enabled := True;
- MainForm.btnStopScript.Enabled := False;
- MainForm.mnuRun.Enabled := True;
- MainForm.mnuStop.Enabled := False;
- btnBreak.Enabled := False;
- btnPause.Enabled := False;
- // restore the status of submenus
- MainForm.FavouriteScripts1.Enabled := favs;
- MainForm.Directory1.Enabled := defs;
- StatusBar.SimpleText := StatusBar.Hint;
+ StatusBar.SimpleText := StatusBar.Hint;
end;
procedure TScriptEditor.btnRunClick(Sender: TObject);
@@ -5148,8 +5113,8 @@ begin
for i:= 0 to GetNrVariableNames - 1 do begin
ALIst.AddObject('property ' + GetVariableNameAt(i) + ': double', TObject(ttProp));
end;
- end;
- if (LowerCase(AToken) = 'flame.') then
+ end
+ else if (LowerCase(AToken) = 'flame.') then
begin
ALIst.AddObject('property Gamma: double', TObject(ttProp));
ALIst.AddObject('property GammaThreshold: double', TObject(ttProp));
@@ -5172,6 +5137,7 @@ begin
ALIst.AddObject('property Y: double', TObject(ttProp));
ALIst.AddObject('property DOF: double', TObject(ttProp));
ALIst.AddObject('property Name: string', TObject(ttProp));
+ ALIst.AddObject('property Comment: string', TObject(ttProp));
ALIst.AddObject('property SampleDensity: double', TObject(ttProp));
ALIst.AddObject('property Quality: double', TObject(ttProp));
ALIst.AddObject('property Time: double', TObject(ttProp));
@@ -5181,24 +5147,24 @@ begin
ALIst.AddObject('property FinalXformEnabled: boolean', TObject(ttProp));
ALIst.AddObject('property Background[]: array of integer', TObject(ttProp));
ALIst.AddObject('property Gradient[][]: array of integer', TObject(ttProp));
- end;
- if (LowerCase(AToken) = 'pivot.') then
+ end
+ else if (LowerCase(AToken) = 'pivot.') then
begin
ALIst.AddObject('property X: double', TObject(ttProp));
ALIst.AddObject('property Y: double', TObject(ttProp));
ALIst.AddObject('property Mode: integer', TObject(ttProp));
ALIst.AddObject('procedure Set( X: double, Y: double)', TObject(ttMethod));
ALIst.AddObject('procedure Reset', TObject(ttMethod));
- end;
- if (LowerCase(AToken) = 'renderer.') then
+ end
+ else if (LowerCase(AToken) = 'renderer.') then
begin
ALIst.AddObject('property Filename: string', TObject(ttProp));
ALIst.AddObject('property Width: integer', TObject(ttProp));
ALIst.AddObject('property Height: integer', TObject(ttProp));
ALIst.AddObject('property MaxMemory: integer', TObject(ttProp));
ALIst.AddObject('property EmbedParameters: boolean', TObject(ttProp));
- end;
- if (LowerCase(AToken) = 'options.') then
+ end
+ else if (LowerCase(AToken) = 'options.') then
begin
ALIst.AddObject('property JPEGQuality: integer', TObject(ttProp));
ALIst.AddObject('property BatchSize: integer', TObject(ttProp));
@@ -5237,14 +5203,15 @@ begin
ALIst.AddObject('property ColorBlending: integer', TObject(ttProp));
ALIst.AddObject('property EvenGradientStripes: boolean', TObject(ttProp));
ALIst.AddObject('property ExportRenderer: string', TObject(ttProp));
- end;
- if pos('tstringlist', LowerCase(AToken))> 0 then
- ALIst.AddObject('constructor Create', TObject(ttMethod));
+ end
+ else if pos('tstringlist', LowerCase(AToken))> 0 then
+ ALIst.AddObject('constructor Create', TObject(ttMethod))
// AV: easter eggs ;-)
- if ((pos('apo', LowerCase(AToken))> 0) or (pos('ifs', LowerCase(AToken))> 0)) then
+ else if (((pos('apo', LowerCase(AToken))> 0) and (LowerCase(AToken) <> 'apophysis.'))
+ or (pos('ifs', LowerCase(AToken))> 0)) then
begin
- AList.Clear;
+ //AList.Clear;
ALIst.AddObject('procedure LoadFromFile(full_filename: string)', TObject(ttProc));
ALIst.AddObject('procedure SaveToFile(full_filename: string)', TObject(ttProc));
ALIst.AddObject('function Add(text: string): integer', TObject(ttFunc));
@@ -5269,25 +5236,24 @@ begin
ALIst.AddObject('property Sorted: boolean', TObject(ttProp));
ALIst.AddObject('procedure Assign(sourse: TStrings)', TObject(ttProc));
ALIst.AddObject('procedure AddStrings(strings: TStrings)', TObject(ttProc));
- end;
-
+ end
+ else
if (LowerCase(AToken) = 'apophysis.') or (LowerCase(AToken) = 'application.') then
begin
- AList.Clear;
ALIst.AddObject('function MessageBox(Promt, Caption: string, DlgStyle: integer = 0): integer;',
TObject(ttFunc));
ALIst.AddObject('property Icon', TObject(ttProp));
ALIst.AddObject('property Title', TObject(ttProp));
ALIst.AddObject('property ExeName', TObject(ttProp));
ALIst.AddObject('procedure ProcessMessages', TObject(ttMethod));
- end;
-
- if pos('ttaskdialog', LowerCase(AToken))> 0 then
- ALIst.AddObject('constructor Create(nil)', TObject(ttMethod));
-
+ end
+ else
+ if (LowerCase(AToken) = 'ttaskdialog.') then
+ ALIst.AddObject('constructor Create(nil)', TObject(ttMethod))
+ else
if (pos('tdlg', LowerCase(AToken))> 0) then
begin
- AList.Clear;
+ //AList.Clear;
ALIst.AddObject('destructor Destroy', TObject(ttMethod));
ALIst.AddObject('property Title: string', TObject(ttProp));
ALIst.AddObject('property Caption: string', TObject(ttProp));
@@ -5389,7 +5355,7 @@ end;
procedure TScriptEditor.ScripterCompileError(Sender: TObject;
var msg: string; row, col: Integer; var ShowException: Boolean);
-var ps: integer;
+var ps, n: integer;
begin
btnRun.Enabled := True;
btnStop.Enabled := False;
@@ -5409,7 +5375,8 @@ begin
StatusBar.SimpleText := TextByKey('script-status-compileerror'); // AV
- Editor.ActiveLine := row - 1;
+ n := min(row, Editor.Lines.Count) - 1; // AV
+ Editor.ActiveLine := n;
Editor.ActiveLineSettings.ShowActiveLine := True;
if LanguageFile <> '' then // AV: if we need to translate from/to English
begin
@@ -5478,9 +5445,9 @@ begin
end;
end;
end;
- Console.Lines.Add(TextByKey('script-line') + #32 + IntToStr(row) + ' : '+ msg);
+ Console.Lines.Add(TextByKey('script-line') + #32 + IntToStr(n+1) + ' : '+ msg);
LoadForm.Output.Text := LoadForm.Output.Text + DTError + TextByKey('script-line') + ': '#39 +
- Editor.Lines[row-1] + #39', '+ TextByKey('script-position') +
+ Editor.Lines[n] + #39', '+ TextByKey('script-position') +
': '+ IntToStr(col) + #13#10 + msg + #13#10; // AV
ScriptRenderForm.Close;
ShowException := true;
@@ -5508,7 +5475,7 @@ begin
if (MainForm.Directory1.Count > 0) then
MainForm.Directory1.Enabled := True; // AV
- Editor.ActiveLine := row - 1;
+ Editor.ActiveLine := min(row, Editor.Lines.Count) - 1; // AV
Editor.ActiveLineSettings.ShowActiveLine := True;
if LanguageFile <> '' then
{ AV: We don't need to translate from-to English }
@@ -5521,7 +5488,7 @@ begin
TextByKey('script-status-noformfile'), []);
end;
LoadForm.Output.Text := LoadForm.Output.Text + RTError + TextByKey('script-line') + ': '#39 +
- Editor.Lines[row-1] + #39', '+ TextByKey('script-position') +
+ Editor.Lines[Editor.ActiveLine] + #39', '+ TextByKey('script-position') +
': '+ IntToStr(col) + #13#10 + msg + #13#10;
ScriptRenderForm.Close;
ShowException := true;
@@ -5559,7 +5526,6 @@ begin
Editor.BlockColor := MidColor;
Editor.Gutter.GutterColor := BrightColor;
Editor.Gutter.GutterColorTo := MidColor;
- Editor.Gutter.GutterColorTo := MidColor;
Editor.Gutter.Font.Color := TextColor;
ScrCodeList1.Font.Color := Editor.Font.Color;
@@ -5629,7 +5595,7 @@ begin
end;
if there then begin
Application.MessageBox(PChar(Format(TextByKey('common-favscriptexists'),
- [ExtractFileName(Script)])), PChar('Apophysis AV'), MB_ICONWARNING);
+ [ExtractFileName(Script)])), PChar(ApophysisSVN), MB_ICONWARNING);
exit;
end;
@@ -5639,7 +5605,7 @@ begin
Favorites.SaveToFile(AppPath + scriptFavsFilename);
MainForm.GetScripts;
Application.MessageBox(PChar(Format(TextByKey('common-favscriptadded'),
- [ExtractFileName(Script)])), PChar('Apophysis AV'), MB_ICONINFORMATION);
+ [ExtractFileName(Script)])), ApophysisSVN, MB_ICONINFORMATION);
end;
end;
@@ -5674,8 +5640,8 @@ end;
procedure TScriptEditor.F2SXMLEmptyTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
var
- i,n: integer;
- v,w: TStringType;
+ i, n: integer;
+ v, w: string; //TStringType;
d, floatcolor: double;
Tokens: TStringList;
begin
@@ -5689,19 +5655,19 @@ begin
Editor.Lines.Add('Flame.FinalXformEnabled := True;');
Editor.Lines.Add('SetActiveTransform(transforms);');
end else begin
- w := TStringType('{ Transform ' + IntToStr(AddedXForms + 1));
- v := Attributes.Value('name');
+ w := '{ Transform ' + IntToStr(AddedXForms + 1);
+ v := string(Attributes.Value('name'));
if (v <> '') then w := w + ' (' + v + ')';
w := w + ' }';
- Editor.Lines.Add(String(w));
+ Editor.Lines.Add(w);
Editor.Lines.Add('AddTransform;');
end;
Editor.Lines.Add('with Transform do begin');
//Editor.Lines.Add(' for i := 0 to NXFORMS do Chaos[i] := 1;');
- v := Attributes.Value('var_order');
+ v := string(Attributes.Value('var_order'));
if v <> '' then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
n := -1;
for i := 0 to Tokens.Count-1 do
if (GetVariationIndex(Tokens[i]) >= 0) then begin
@@ -5710,42 +5676,44 @@ begin
end;
end;
- v := Attributes.Value(TStringType(varnames(0)));
- if v = '' then
- Editor.Lines.Add(' Variation[0] := 0; // linear');
+ v := string(Attributes.Value('linear')); // varnames(0)
+ if v = '' then
+ Editor.Lines.Add(' Variation[0] := 0; // linear');
for i := 0 to NRVAR - 1 do
begin
- v := Attributes.Value(TStringType(varnames(i)));
+ w := varnames(i);
+ v := string(Attributes.Value(Utf8String(w)));
if v <> '' then
- //Editor.Lines.Add(' ' + varnames(i) + ' := ' + String(v) + ';');
- Editor.Lines.Add(Format(' %s := %.6g;', [varnames(i), StrToFloat(String(v))]));
+ Editor.Lines.Add(Format(' %s := %.6g;', [w, StrToFloat(v)]));
end;
for i := 0 to GetNrVariableNames - 1 do begin
- v := Attributes.Value(TStringType(GetVariableNameAt(i)));
+ w := GetVariableNameAt(i);
+ v := string(Attributes.Value(Utf8String(w)));
if v <> '' then begin
- Editor.Lines.Add(' ' + GetVariableNameAt(i) + ' := ' + String(v) + ';');
+ Editor.Lines.Add(' ' + w + ' := ' + v + ';');
end;
end;
- v := Attributes.Value('weight');
+ v := string(Attributes.Value('weight'));
if (v <> '') and (TagName = 'xform') then
- Editor.Lines.Add(Format(' Weight := %.6g;', [StrToFloat(String(v))]));
- v := Attributes.Value('color');
- if (v <> '') then Editor.Lines.Add(' Color := ' + String(v) + ';');
- v := Attributes.Value('var_color');
- if (v <> '') then Editor.Lines.Add(' VarColor := ' + String(v) + ';');
- v := Attributes.Value('symmetry');
- if (v <> '') and (TagName = 'xform') then Editor.Lines.Add(' Symmetry := ' + String(v) + ';');
- v := Attributes.Value('opacity');
+ Editor.Lines.Add(Format(' Weight := %.6g;', [StrToFloat(v)]));
+ v := string(Attributes.Value('color'));
+ if (v <> '') then Editor.Lines.Add(' Color := ' + v+ ';');
+ v := string(Attributes.Value('var_color'));
+ if (v <> '') then Editor.Lines.Add(' VarColor := ' + v + ';');
+ // AV: fixed - final xforms can have ColorSpeed <> 1
+ v := string(Attributes.Value('symmetry'));
+ if (v <> '') then Editor.Lines.Add(' Symmetry := ' + v + ';');
+ v := string(Attributes.Value('opacity'));
if v <> '' then begin
- Editor.Lines.Add(' Opacity := ' + String(v) + ';');
+ Editor.Lines.Add(' Opacity := ' + v + ';');
end;
- v := Attributes.Value('coefs');
+ v := string(Attributes.Value('coefs'));
if (v <> '') then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
Editor.Lines.Add(Format(' coefs[0,0] := %.6g; // a', [StrToFloat(Tokens[0])]));
Editor.Lines.Add(Format(' coefs[1,0] := %.6g; // b', [StrToFloat(Tokens[2]) * (-1)]));
Editor.Lines.Add(Format(' coefs[0,1] := %.6g; // c', [StrToFloat(Tokens[1]) * (-1)]));
@@ -5754,9 +5722,9 @@ begin
Editor.Lines.Add(Format(' coefs[2,1] := %.6g; // f', [StrToFloat(Tokens[5]) * (-1)]));
end;
- v := Attributes.Value('post');
+ v := string(Attributes.Value('post'));
if v <> '' then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
Editor.Lines.Add(Format(' post[0,0] := %.6g;', [StrToFloat(Tokens[0])]));
Editor.Lines.Add(Format(' post[0,1] := %.6g;', [StrToFloat(Tokens[1]) * (-1)]));
Editor.Lines.Add(Format(' post[1,0] := %.6g;', [StrToFloat(Tokens[2]) * (-1)]));
@@ -5766,13 +5734,13 @@ begin
end;
- v := Attributes.Value('chaos');
+ v := string(Attributes.Value('chaos'));
if v <> '' then begin
chaosLines.Add('');
chaosLines.Add('{ Weight modifiers for transform ' + IntToStr(AddedXForms + 1) + ' }');
chaosLines.Add('SetActiveTransform(' + IntToStr(AddedXForms) + ');');
chaosLines.Add('with Transform do begin');
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
for i := 0 to Tokens.Count-1 do
chaosLines.Add(' chaos[' + IntToStr(i) + '] := ' + Tokens[i] + ';') ;
chaosLines.Add('end;');
@@ -5785,16 +5753,11 @@ begin
end;
end;
-procedure TScriptEditor.F2SXMLEndTag(Sender: TObject; TagName: string);
-begin
-//
-end;
-
procedure TScriptEditor.F2SXMLStartTag(Sender: TObject; TagName: string;
Attributes: TAttrList);
var
Tokens: TStringList;
- v: TStringType;
+ v: string; //TStringType;
f, b: double;
begin
Tokens := TStringList.Create;
@@ -5809,64 +5772,65 @@ begin
// Editor.Lines.Add(' AngleTransform := 180 / PI else AngleTransform := 1;');
Editor.Lines.Add('with Flame do begin');
- v := Attributes.Value(TStringType('size'));
+ v := string(Attributes.Value('size'));
if (v <> '') then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
Editor.Lines.Add(' Width := ' + Tokens[0] + ';');
Editor.Lines.Add(' Height := ' + Tokens[1] + ';');
f := 100 / StrToFloat(Tokens[0]);
end else f := 0;
- b := 0;
-
- v := Attributes.Value(TStringType('brightness'));
+
+ b := 0;
+ v := string(Attributes.Value('brightness'));
if (v <> '') then begin
- Editor.Lines.Add(' Brightness := ' + String(v) + ';');
- b := StrToFloat(String(v));
+ Editor.Lines.Add(' Brightness := ' + v + ';');
+ b := StrToFloat(v);
end;
- v := Attributes.Value(TStringType('gamma'));
- if (v <> '') then Editor.Lines.Add(' Gamma := ' + String(v) + ';');
- v := Attributes.Value(TStringType('vibrancy'));
- if (v <> '') then Editor.Lines.Add(' Vibrancy := ' + String(v) + ';');
- v := Attributes.Value(TStringType('contrast'));
- if (v <> '') then Editor.Lines.Add(' Contrast := ' + String(v) + ';');
- v := Attributes.Value(TStringType('gamma_threshold'));
+ v := string(Attributes.Value('gamma'));
+ if (v <> '') then Editor.Lines.Add(' Gamma := ' + v + ';');
+ v := string(Attributes.Value('vibrancy'));
+ if (v <> '') then Editor.Lines.Add(' Vibrancy := ' + v + ';');
+ v := string(Attributes.Value('contrast'));
+ if (v <> '') then Editor.Lines.Add(' Contrast := ' + v + ';');
+ v := string(Attributes.Value('gamma_threshold'));
if (v <> '') then begin
- if b <> 0 then b := StrToFloat(String(v)) / b;
+ if b <> 0 then b := StrToFloat(v) / b;
Editor.Lines.Add(' GammaThreshold := ' + FloatToStr(b) + ';');
end;
- v := Attributes.Value(TStringType('zoom'));
- if (v <> '') then Editor.Lines.Add(' Zoom := ' + String(v) + ';');
- v := Attributes.Value(TStringType('scale'));
- if (v <> '') then Editor.Lines.Add(Format(' Scale := %.6g;', [StrToFloat(String(v)) * f]));
- v := Attributes.Value(TStringType('angle'));
- if (v <> '') then
+ v := string(Attributes.Value('zoom'));
+ if (v <> '') then Editor.Lines.Add(' Zoom := ' + v + ';');
+ v := string(Attributes.Value('scale'));
+ if (v <> '') then
+ Editor.Lines.Add(Format(' Scale := %.6g;', [StrToFloat(v) * f]));
+ v := string(Attributes.Value('angle'));
+ if (v <> '') then
// Editor.Lines.Add(' Angle := ' + FloatToStr(StrToFloat(String(v))* 180 / PI) + '; ');
- Editor.Lines.Add(Format(' Angle := %.6g; // Flame rotation', [StrToFloat(String(v)) * 180 / PI]));
+ Editor.Lines.Add(Format(' Angle := %.6g; // Flame rotation', [StrToFloat(v) * 180 / PI]));
// 3d
- v := Attributes.Value(TStringType('cam_pitch'));
- if (v <> '') then
- Editor.Lines.Add(Format(' Pitch := %.6g;', [StrToFloat(String(v)) * 180 / PI]));
- v := Attributes.Value(TStringType('cam_roll')); // AV
+ v := string(Attributes.Value('cam_pitch'));
if (v <> '') then
- Editor.Lines.Add(Format(' Roll := %.6g;', [StrToFloat(String(v)) * 180 / PI]));
- v := Attributes.Value(TStringType('cam_yaw'));
- if (v <> '') then
- Editor.Lines.Add(Format(' Yaw := %.6g;', [StrToFloat(String(v)) * 180 / PI]));
- v := Attributes.Value(TStringType('cam_perspective'));
- if (v <> '') then Editor.Lines.Add(' Perspective := ' + String(v) + ';');
- v := Attributes.Value(TStringType('cam_zpos'));
- if (v <> '') then Editor.Lines.Add(' Z := ' + String(v) + ';');
- v := Attributes.Value(TStringType('cam_dof'));
- if (v <> '') then Editor.Lines.Add(' DOF := ' + String(v) + ';');
+ Editor.Lines.Add(Format(' Pitch := %.6g;', [StrToFloat(v) * 180 / PI]));
+ v := string(Attributes.Value('cam_roll')); // AV
+ if (v <> '') then
+ Editor.Lines.Add(Format(' Roll := %.6g;', [StrToFloat(v) * 180 / PI]));
+ v := string(Attributes.Value('cam_yaw'));
+ if (v <> '') then
+ Editor.Lines.Add(Format(' Yaw := %.6g;', [StrToFloat(v) * 180 / PI]));
+ v :=string( Attributes.Value('cam_perspective'));
+ if (v <> '') then Editor.Lines.Add(' Perspective := ' + v + ';');
+ v := string(Attributes.Value('cam_zpos'));
+ if (v <> '') then Editor.Lines.Add(' Z := ' + v + ';');
+ v := string(Attributes.Value('cam_dof'));
+ if (v <> '') then Editor.Lines.Add(' DOF := ' + v + ';');
try
- v := Attributes.Value(TStringType('center'));
+ v := string(Attributes.Value('center'));
if (v <> '') then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
Editor.Lines.Add(' X := ' + Tokens[0] + ';');
Editor.Lines.Add(' Y := ' + Tokens[1] + ';');
end;
@@ -5876,9 +5840,9 @@ begin
end;
try
- v := Attributes.Value(TStringType('background'));
+ v := string(Attributes.Value('background'));
if (v <> '') then begin
- GetTokens(String(v), tokens);
+ GetTokens(v, tokens);
Editor.Lines.Add(Format(' Background[0] := %g; // red component', [Int(StrToFloat(Tokens[0]) * 255)]));
Editor.Lines.Add(Format(' Background[1] := %g; // green component', [Int(StrToFloat(Tokens[1]) * 255)]));
@@ -5891,8 +5855,8 @@ begin
Editor.Lines.Add(' Background[2] := 0; // blue component');
end;
- v := Attributes.Value(TStringType('soloxform'));
- if (v <> '') then Editor.Lines.Add('SoloXform := ' + String(v) + ';');
+ v := string(Attributes.Value('soloxform'));
+ if (v <> '') then Editor.Lines.Add('SoloXform := ' + v + ';');
Editor.Lines.Add('end;');
end;
@@ -5901,7 +5865,7 @@ begin
end;
end;
-procedure TScriptEditor.LoadRunAndClear(scriptFile:string);
+procedure TScriptEditor.LoadRunAndClear(scriptFile: string);
begin
LoadScriptFile(scriptFile);
RunScript;
diff --git a/Forms/ScriptRender.pas b/Forms/ScriptRender.pas
index ea971ff..f4c8b0e 100644
--- a/Forms/ScriptRender.pas
+++ b/Forms/ScriptRender.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- ComCtrls, StdCtrls, RenderThread, cmap, ControlPoint, Translation;
+ ComCtrls, StdCtrls, RenderThread, ControlPoint;
type
TScriptRenderForm = class(TForm)
@@ -37,9 +37,9 @@ type
procedure FormCreate(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
private
-// PixelsPerUnit: double;
StartTime: TDateTime;
Remainder: TDateTime;
+ Filename: string;
procedure HandleThreadCompletion(var Message: TMessage);
message WM_THREAD_COMPLETE;
@@ -47,12 +47,8 @@ type
message WM_THREAD_TERMINATE;
public
Renderer: TRenderThread;
- ColorMap: TColorMap;
cp: TControlPoint;
- Filename: string;
- ImageWidth, ImageHeight, Oversample: Integer;
- zoom, Sample_Density, Brightness, Gamma, Vibrancy, Filter_Radius: double;
- center: array[0..1] of double;
+
procedure OnProgress(prog: double);
procedure Render;
procedure SetRenderBounds;
@@ -64,20 +60,20 @@ var
implementation
-uses Global, Math, FormRender, ScriptForm, Main;
+uses Global, Math, FormRender, ScriptForm, Main, Translation;
+
{$R *.DFM}
procedure TScriptRenderForm.SetRenderBounds;
+// AV: do not use it - just waste of time
begin
cp.copy(ScriptEditor.cp);
cp.AdjustScale(ScriptEditor.Renderer.Width, ScriptEditor.Renderer.Height);
- // --?-- cp.CalcBoundBox;
- cp.center[0] := ScriptEditor.cp.center[0];
- cp.center[1] := ScriptEditor.cp.center[1];
- cp.zoom := ScriptEditor.cp.zoom;
end;
procedure TScriptRenderForm.Render;
+var
+ ScrRender: TScriptRender; // AV
begin
assert(not Assigned(Renderer));
Renderer := TRenderThread.Create;
@@ -86,27 +82,27 @@ begin
ScriptEditor.Scripter.Paused := True;
StartTime := Now;
Remainder := 1;
- cp.copy(ScriptEditor.cp);
- Filename := ScriptEditor.Renderer.Filename;
+ //cp.copy(ScriptEditor.cp); // <-- AV: already done by RenderProc
+ ScrRender := ScriptEditor.Renderer; // AV: for speed
+ Filename := ScrRender.Filename;
- cp.AdjustScale(ScriptEditor.Renderer.Width, ScriptEditor.Renderer.Height);
+ cp.AdjustScale(ScrRender.Width, ScrRender.Height);
- //cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(ScriptEditor.Renderer.FileName)) = '.PNG');
- if (UpperCase(ExtractFileExt(ScriptEditor.Renderer.FileName)) = '.PNG') then
+ if (UpperCase(ExtractFileExt(FileName)) = '.PNG') then
begin // AV: added new property
cp.Transparency := (PNGTransparency <> 0);
- if ScriptEditor.Renderer.EmbedParameters then
- Renderer.EmbedText(Trim(MainForm.RetrieveXML(cp))); // AV
+ if ScrRender.EmbedParameters then
+ Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
end
else
cp.Transparency := False; // AV
Renderer.OnProgress := OnProgress;
Renderer.SetCP(cp);
- if (ScriptEditor.Renderer.MaxMemory > 0) then
- Renderer.MaxMem := ScriptEditor.Renderer.MaxMemory;
+ if (ScrRender.MaxMemory > 0) then
+ Renderer.MaxMem := ScrRender.MaxMemory;
Renderer.TargetHandle := Handle;
- renderPath := ExtractFilePath(ScriptEditor.Renderer.Filename);
+ renderPath := ExtractFilePath(Filename);
Renderer.Priority := tpLower;
Renderer.NrThreads := NrTreads; // AV: now works fine
@@ -135,7 +131,6 @@ end;
procedure TScriptRenderForm.FormCreate(Sender: TObject);
begin
- //Renderer := TRenderThread.Create;
self.Hint := TextByKey('script-rendering');
btnCancel.Caption := TextByKey('common-cancel');
cp := TControlPoint.Create;
@@ -145,7 +140,7 @@ procedure TScriptRenderForm.btnCancelClick(Sender: TObject);
begin
ScriptEditor.Scripter.Halt;
Cancelled := True;
-// Renderer.Stop;
+
if Assigned(Renderer) then begin
Renderer.Terminate;
Renderer.WaitFor;
diff --git a/Forms/SplashForm.pas b/Forms/SplashForm.pas
index 0848c37..be3ca73 100644
--- a/Forms/SplashForm.pas
+++ b/Forms/SplashForm.pas
@@ -20,7 +20,7 @@ type
public
procedure SetInfo(info:string);
end;
-const DURATION: integer = 900;
+
var
SplashWindow: TSplashWindow;
@@ -28,6 +28,9 @@ implementation
{$R *.dfm}
+const
+ DURATION = 900;
+
procedure TSplashWindow.FormCreate(Sender: TObject);
begin
lblVersion.Caption := APP_VERSION + APP_BUILD;
diff --git a/Forms/Template.pas b/Forms/Template.pas
index 338a318..f946281 100644
--- a/Forms/Template.pas
+++ b/Forms/Template.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -27,9 +27,9 @@ unit Template;
interface
uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Translation,
- Dialogs, StdCtrls, ComCtrls, ImgList, ControlPoint, cmap, RenderingInterface, Main,
- Global, Adjust, System.ImageList;
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, StdCtrls, ComCtrls, ImgList, System.ImageList,
+ ControlPoint, cmap, RenderingInterface, Main, Global, Adjust, Translation;
type
TTemplateForm = class(TForm)
@@ -47,54 +47,55 @@ type
private
{ Private declarations }
Files: TStringList; // AV: replaced "useless" hidded TListBox
+
+ procedure ListTemplateByFileName(filename: string);
+ procedure LoadUserTemplates;
+ procedure DropBlank;
+ procedure DropListItem(FileName: string; FlameName: string);
+ procedure ListTemplate;
public
{ Public declarations }
end;
var
TemplateForm: TTemplateForm;
-const
- blankFlameXML1 = '';
- blankFlameXML2 = '';
- blankFlameXML3 = '';
-
- procedure ListTemplateByFileName(filename:string);
implementation
{$R *.dfm}
-function LoadUserTemplates2(mask: string): integer;
-var
- FindResult: integer;
- SearchRec : TSearchRec;
- Path : string;
-begin
- Path := AppPath + 'Templates\'; // AV
- result := 0;
+procedure TTemplateForm.LoadUserTemplates;
+ procedure LoadUserTemplates2(mask: string);
+ var
+ FindResult: integer;
+ SearchRec : TSearchRec;
+ Path : string;
+ begin
+ Path := AppPath + 'Templates\'; // AV
- FindResult := FindFirst(Path + Mask, faAnyFile - faDirectory, SearchRec);
- while FindResult = 0 do
- begin
- ListTemplateByFileName(Path + SearchRec.Name);
- result := result + 1;
+ FindResult := FindFirst(Path + Mask, faAnyFile - faDirectory, SearchRec);
+ while FindResult = 0 do
+ begin
+ ListTemplateByFileName(Path + SearchRec.Name);
- FindResult := FindNext(SearchRec);
- end;
- { free memory }
- FindClose(SearchRec);
-end;
-
-function LoadUserTemplates: integer;
+ FindResult := FindNext(SearchRec);
+ end;
+ { free memory }
+ FindClose(SearchRec);
+ end;
begin
LoadUserTemplates2('*.flame');
LoadUserTemplates2('*.template');
- Result := 0; // make RTL happy
end;
+(*
function BlankXML: string;
+const
+ blankFlameXML1 = '';
+ blankFlameXML2 = '';
+ blankFlameXML3 = '';
var
- i: integer;
+ i: smallint;
s: string;
const
break = ' ';
@@ -107,10 +108,10 @@ begin
s := s + '';
Result := s;
end;
+*)
-procedure DropBlank();
+procedure TTemplateForm.DropBlank;
var
- flameXML: string;
cp: TControlPoint;
bm: TBitmap;
Render: TRenderer;
@@ -120,38 +121,37 @@ begin
Render := TRenderer.Create;
bm := TBitmap.Create;
- cp.Clear;
- flameXML := BlankXML;
- MainForm.ParseXML(cp, PCHAR(flameXML), true);
- cp.AdjustScale(TemplateForm.UsedThumbnails.Width, TemplateForm.UsedThumbnails.Height);
+ // AV: we don't need any parsing and cleaning here
+ cp.xform[0].density := 0.5; // AV: that's all we need to create a new flame
+ cp.cmap := MainCp.cmap; // AV: make black dots visible
+ cp.pixels_per_unit := 5; // AV: decrease the scale
+ cp.AdjustScale(UsedThumbnails.Width, UsedThumbnails.Height);
// start preview
- cp.Width := TemplateForm.UsedThumbnails.Width;
- cp.Height := TemplateForm.UsedThumbnails.Height;
- cp.spatial_oversample := 1;
- cp.spatial_filter_radius := 0.1;
- cp.sample_density := 0.5; //3;
- try
- Render.SetCP(cp);
- Render.Render;
- finally
- BM.Assign(Render.GetImage);
- cp.Free;
- Render.free;
- end;
-// Thumbnails
- TemplateForm.UsedThumbnails.Add(bm, nil);
+ //cp.spatial_oversample := 1; // <-- AV: true by default
+ cp.spatial_filter_radius := 0.1;
+ cp.sample_density := 3;
+ try
+ Render.SetCP(cp);
+ Render.Render;
+ BM.Assign(Render.GetImage);
+ UsedThumbnails.Add(bm, nil);
+ finally
+ cp.Free;
+ Render.free;
bm.Free; // AV: fixed multiple memory leaks!
- ListItem := TemplateForm.TemplateList.Items.Add;
- ListItem.Caption := 'Blank Flame';
- ListItem.ImageIndex := 0;
- TemplateForm.Files.Add('n/a');
+ end;
+ { Thumbnails}
+ ListItem := TemplateList.Items.Add;
+ ListItem.Caption := 'Blank Flame';
+ ListItem.ImageIndex := 0;
+ Files.Add('n/a');
//end preview
- //
+
Application.ProcessMessages;
end;
-procedure DropListItem(FileName: string; FlameName: string);
+procedure TTemplateForm.DropListItem(FileName: string; FlameName: string);
var
flameXML: string;
cp: TControlPoint;
@@ -163,46 +163,42 @@ begin
Render := TRenderer.Create;
bm := TBitmap.Create;
- cp.Clear;
+ //cp.Clear;
flameXML := LoadXMLFlameText(filename, FlameName);
- MainForm.ParseXML(cp, PCHAR(flameXML), true);
- cp.AdjustScale(TemplateForm.UsedThumbnails.Width, TemplateForm.UsedThumbnails.Height);
+ MainForm.ParseXML(cp, flameXML, true); // AV: fixed - was PChar instead String
+ cp.AdjustScale(UsedThumbnails.Width, UsedThumbnails.Height);
// start preview
- cp.Width := TemplateForm.UsedThumbnails.Width;
- cp.Height := TemplateForm.UsedThumbnails.Height;
- cp.spatial_oversample := 1;
- cp.spatial_filter_radius := 0.1;
- cp.sample_density := 3;
- try
- Render.SetCP(cp);
- Render.Render;
- finally
- BM.Assign(Render.GetImage);
- cp.Free;
- Render.free;
- end;
-// Thumbnails
- TemplateForm.UsedThumbnails.Add(bm, nil);
+ //cp.spatial_oversample := 1; // <-- AV: true by default
+ cp.spatial_filter_radius := 0.1;
+ cp.sample_density := 3;
+ try
+ Render.SetCP(cp);
+ Render.Render;
+ BM.Assign(Render.GetImage);
+ UsedThumbnails.Add(bm, nil);
+ finally
+ cp.Free;
+ Render.free;
bm.Free; // AV: fixed multiple memory leaks!
- ListItem := TemplateForm.TemplateList.Items.Add;
- ListItem.Caption := FlameName;
- ListItem.ImageIndex := TemplateForm.TemplateList.Items.Count - 1;
- TemplateForm.Files.Add(FileName);
+ end;
+ { Thumbnails }
+ ListItem := TemplateList.Items.Add;
+ ListItem.Caption := FlameName;
+ ListItem.ImageIndex := TemplateList.Items.Count - 1;
+ Files.Add(FileName);
//end preview
- //
+
Application.ProcessMessages;
end;
-procedure ListTemplateByFileName(filename:string);
+procedure TTemplateForm.ListTemplateByFileName(filename:string);
{ List .flame file }
var
- sel: integer;
i, p: integer;
Title: string;
FStrings: TStringList;
begin
- sel := 0;
if not FileExists(FileName) then exit;
FStrings := TStringList.Create;
FStrings.LoadFromFile(FileName);
@@ -214,17 +210,15 @@ begin
p := Pos(' 0) then
begin
- MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FSTrings[i])));
+ MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FStrings[i]))); // AV
MainForm.ListXMLScanner.Execute;
if Length(pname) = 0 then
Title := '*untitled ' + ptime
else
Title := Trim(pname);
- if Title <> '' then
- begin { Otherwise bad format }
+ if Title <> '' then // Otherwise bad format
DropListItem(FileName, Title);
- end;
end;
end;
end;
@@ -233,27 +227,21 @@ begin
end;
end;
-procedure ListTemplate;
+procedure TTemplateForm.ListTemplate;
begin
- TemplateForm.TemplateList.Items.BeginUpdate;
- TemplateForm.TemplateList.Items.Clear;
- TemplateForm.UsedThumbnails.Clear;
+ TemplateList.Items.BeginUpdate;
+ TemplateList.Items.Clear;
+ UsedThumbnails.Clear;
// AV: fixed - someone forgot to refresh the file list
- TemplateForm.Files.Clear;
- // hmmm...
- (*for i := 0 to TemplateForm.UsedThumbnails.Count - 1 do
- begin
- TemplateForm.UsedThumbnails.GetBitmap(i, bm);
- bm.Free;
- end; *)
+ Files.Clear;
DropBlank;
ListTemplateByFileName(AppPath + templateFileName);
LoadUserTemplates;
- TemplateForm.TemplateList.Items.EndUpdate;
- TemplateForm.TemplateList.Selected := TemplateForm.TemplateList.Items[0];
+ TemplateList.Items.EndUpdate;
+ TemplateList.Selected := TemplateList.Items[0];
end;
procedure TTemplateForm.FormCreate(Sender: TObject);
@@ -273,20 +261,21 @@ procedure TTemplateForm.TemplateListChange(Sender: TObject;
Item: TListItem; Change: TItemChange);
var
fn : string;
+ i: integer; // AV
begin
if (TemplateList.Selected = nil) then
btnOK.Enabled := false
else begin
- if (TemplateList.Selected.Index >= 0) then begin
+ i := TemplateList.Selected.Index;
+ if (i >= 0) then begin
btnOK.Enabled := true;
- if (TemplateList.Selected.Index > 0) then begin
- fn := ChangeFileExt(ExtractFileName(Files[TemplateList.Selected.Index]), '');
+ if (i > 0) then begin
+ fn := ChangeFileExt(ExtractFileName(Files[i]), '');
if (LowerCase(fn) <> 'apophysisav') then
- lblFile.Caption := TextByKey('template-filename') + fn
+ lblFile.Caption := TextByKey('template-filename') + #32 + fn
else lblFile.Caption := '';
- end else begin
+ end else
lblFile.Caption := '';
- end;
end else
btnOK.Enabled := false;
end;
@@ -295,46 +284,66 @@ end;
procedure TTemplateForm.btnOKClick(Sender: TObject);
var
flameXML: string;
- fn: string;
- ci: integer;
- blank: boolean;
+ i: integer;
begin
- fn := Files[TemplateList.Selected.Index];
- blank := (TemplateList.Selected.Index = 0);
- if blank then
- flameXML := BlankXML
- else
- flameXML := LoadXMLFlameText(fn, TemplateList.Selected.Caption);
MainForm.UpdateUndo;
- MainForm.StopThread;
- MainForm.InvokeLoadXML(flameXML);
- Transforms := MainCp.TrianglesFromCP(MainTriangles);
+ // MainForm.StopThread; // AV: this is already done in the Main unit
+
+ i := TemplateList.Selected.Index; // AV
+
+ if (i = 0) then // AV: we don't need to waste time to parse an empty flame
+ begin
+ with MainCp do begin // AV: make a blank flame easier!
+ Clear;
+ name := 'Blank Flame';
+ // AV: fixed a bug with black flames on the black background
+ brightness := defBrightness;
+ gamma := defGamma;
+ gammaThreshRelative := defGammaThreshold;
+ contrast := defContrast;
+ vibrancy := defVibrancy;
+ sample_density := defSampleDensity;
+ { AV: 2D-camera resetting }
+ center[0] := 0;
+ center[1] := 0;
+ zoom := 0;
+ FAngle := 0;
+ { AV: 3D-camera resetting }
+ cameraPitch := 0;
+ cameraYaw := 0;
+ cameraRoll := 0;
+ cameraPersp := 0;
+ cameraZPos := 0;
+ cameraDOF := 0;
+ xform[0].density := 0.5; // AV: make the single xform visible
+ xform[1].symmetry := 1; // AV: hide final xform
+ CalcBoundBox;
+ end;
+ Transforms := 1;
+ EnableFinalXform := false;
+ end
+ else begin
+ flameXML := LoadXMLFlameText(Files[i], TemplateList.Selected.Caption);
+ MainForm.ParseXML(MainCP, flameXML, false);
+ Transforms := MainCp.TrianglesFromCP(MainTriangles);
+ end;
+
MainForm.Statusbar.Panels[3].Text := MainCp.name;
{if ResizeOnLoad then}
MainForm.ResizeImage;
MainForm.RedrawTimer.Enabled := True;
- Application.ProcessMessages;
- MainForm.UpdateWindows;
- // AV: fixed a bug with black flames on the black background
- if RandomizeTemplates or blank then // AV
+ if RandomizeTemplates then // AV
if (randGradient = 3) then // AV: only if user prefer new palettes
AdjustForm.mnuRandomize.Click
else begin // AV: use preset palette
- ci := Random(NRCMAPS);
- GetCMap(ci, 1, MainCp.cmap);
- MainCp.cmapIndex := ci;
+ i := Random(NRCMAPS);
+ GetCMap(i, 1, MainCp.cmap);
+ MainCp.cmapIndex := i;
end;
- if blank then // AV: fixed resetting values to 1
- begin
- MainCp.brightness := defBrightness;
- MainCp.gamma := defGamma;
- MainCp.gammaThreshRelative := defGammaThreshold;
- MainCp.contrast := defContrast;
- MainCp.Vibrancy := defVibrancy;
- Maincp.sample_density := defSampleDensity;
- end;
+ Application.ProcessMessages;
+ MainForm.UpdateWindows;
ModalResult := mrOK; // AV
end;
diff --git a/Forms/Tracer.dfm b/Forms/Tracer.dfm
index 80e13ef..0131a3f 100644
--- a/Forms/Tracer.dfm
+++ b/Forms/Tracer.dfm
@@ -96,6 +96,10 @@ object TraceForm: TTraceForm
object TabFullscreen: TTabSheet
Caption = 'Fullscreen'
ImageIndex = 52
+ ExplicitLeft = 0
+ ExplicitTop = 0
+ ExplicitWidth = 0
+ ExplicitHeight = 0
object FullscreenTrace: TMemo
Left = 0
Top = 0
@@ -116,9 +120,9 @@ object TraceForm: TTraceForm
end
end
object cbTraceLevel: TComboBox
- Left = 280
+ Left = 240
Top = 0
- Width = 121
+ Width = 147
Height = 21
Style = csDropDownList
Anchors = [akTop, akRight]
diff --git a/Forms/Tracer.pas b/Forms/Tracer.pas
index 5353fef..06fe5d2 100644
--- a/Forms/Tracer.pas
+++ b/Forms/Tracer.pas
@@ -5,6 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -23,13 +24,13 @@
unit Tracer;
-{$define TRACEFORM_HIDDEN}
+//{$define TRACEFORM_HIDDEN}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, ComCtrls, Translation;
+ Dialogs, StdCtrls, ComCtrls;
type
TTraceForm = class(TForm)
@@ -50,9 +51,7 @@ type
var
TraceForm: TTraceForm;
-
-var
- TraceLevel: integer;
+ TraceLevel: shortint;
const
MsgComplete = '< Received WM_THREAD_COMPLETE from RenderThread #';
@@ -65,8 +64,7 @@ implementation
{$R *.dfm}
uses
- Registry,
- Global, Main;
+ Registry, Global, Main, Translation;
procedure TTraceForm.cbTraceLevelSelect(Sender: TObject);
begin
@@ -92,26 +90,17 @@ begin
if Registry.ValueExists('Height') then
self.Height := Registry.ReadInteger('Height');
-{$ifndef TRACEFORM_HIDDEN}
+ {$ifndef TRACEFORM_HIDDEN}
if Registry.ValueExists('TraceLevel') then
TraceLevel := Registry.ReadInteger('TraceLevel')
else
TraceLevel := 0;
- MainForm.tbShowTrace.Visible := true;
- MainForm.tbShowTrace.Enabled := true;
- MainForm.tbTraceSeparator.Visible := true;
- MainForm.tbTraceSeparator.Enabled := true;
-
-{$else}
+ {$else}
TraceLevel := 0;
- //MainForm.tbShowTrace.Visible := false;
- //MainForm.tbShowTrace.Enabled := false;
- //MainForm.tbTraceSeparator.Visible := false;
- //MainForm.tbTraceSeparator.Enabled := false;
-
-{$endif}
+ MainForm.mnuTrace.Visible := False; // AV
+ {$endif}
end;
Registry.CloseKey;
diff --git a/Forms/VarOrderForm.pas b/Forms/VarOrderForm.pas
index eba08eb..22b3dc0 100644
--- a/Forms/VarOrderForm.pas
+++ b/Forms/VarOrderForm.pas
@@ -1,4 +1,4 @@
-{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
+{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit VarOrderForm;
@@ -6,9 +6,8 @@ interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, StrUtils, System.Variants,
- System.Classes, Vcl.Graphics,
- Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Editor, Translation, Vcl.StdCtrls,
- Vcl.ComCtrls, Vcl.ExtCtrls, Vcl.Buttons;
+ System.Classes, Vcl.Graphics, Vcl.Forms, Vcl.Dialogs, Vcl.Buttons,
+ Vcl.Controls, Vcl.StdCtrls,Vcl.ComCtrls, Vcl.ExtCtrls, Editor;
type
TVarOrder = class(TForm)
@@ -56,7 +55,7 @@ var
implementation
uses
- XFormMan, Global; // to get default variation order
+ XFormMan, Global, Translation; // to get default variation order
{$R *.dfm}
@@ -66,7 +65,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ 'Apophysis AV', MB_ICONWARNING);
exit;
end;
@@ -108,7 +107,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ 'Apophysis AV', MB_ICONWARNING);
exit;
end;
@@ -123,7 +122,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ 'Apophysis AV', MB_ICONWARNING);
exit;
end;
@@ -150,7 +149,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
- PChar('Apophysis AV'), MB_ICONWARNING);
+ 'Apophysis AV', MB_ICONWARNING);
exit;
end;
@@ -255,7 +254,7 @@ begin
or (s = 'affine3D') or (s = 'spherecrop') then
ListItem.ImageIndex := 6 // violet
else
- ListItem.ImageIndex := 5 // blue;
+ ListItem.ImageIndex := 5 // green;
end;
procedure TVarOrder.ShowSelected(const i: integer);
diff --git a/Forms/formPostProcess.dfm b/Forms/formPostProcess.dfm
index 6dcef9a..b31d5ad 100644
--- a/Forms/formPostProcess.dfm
+++ b/Forms/formPostProcess.dfm
@@ -250,8 +250,8 @@ object frmPostProcess: TfrmPostProcess
end
end
object btnSave: TButton
- Left = 588
- Top = 510
+ Left = 580
+ Top = 509
Width = 97
Height = 25
Anchors = [akRight, akBottom]
@@ -270,7 +270,6 @@ object frmPostProcess: TfrmPostProcess
State = cbChecked
TabOrder = 3
Visible = False
- OnClick = chkFitToWindowClick
end
object ColorDialog: TColorDialog
Left = 612
diff --git a/Forms/formPostProcess.pas b/Forms/formPostProcess.pas
index 6f7d6ed..f374a95 100644
--- a/Forms/formPostProcess.pas
+++ b/Forms/formPostProcess.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -28,8 +28,7 @@ interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, ExtCtrls, RenderingInterface, controlpoint, StdCtrls, ComCtrls,
- Translation;
+ Dialogs, ExtCtrls, RenderingInterface, ControlPoint, StdCtrls, ComCtrls;
type
TfrmPostProcess = class(TForm)
@@ -56,7 +55,7 @@ type
btnApply: TButton;
pnlRelGamma: TPanel;
txtRelGamma: TEdit;
- procedure chkFitToWindowClick(Sender: TObject);
+ // procedure chkFitToWindowClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnApplyClick(Sender: TObject);
@@ -87,18 +86,13 @@ type
mousepos: TPoint;
BkgColor: TColor;
- Filter,
- Gamma, Brightness, RelGamma,
- Contrast, Vibrancy: double;
-
+ Filter, Gamma, Brightness, RelGamma, Contrast, Vibrancy: double;
ImCount: shortint; // AV: the number of saved images
- NewName: string; // AV
procedure UpdateFlame;
procedure SetDefaultValues;
procedure OnProgress(prog: double);
-
public
cp : TControlPoint;
@@ -113,7 +107,7 @@ var
implementation
uses
- Registry, Global, Main;
+ Registry, Global, Main, Translation;
{$R *.dfm}
@@ -319,6 +313,7 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TfrmPostProcess.btnSaveClick(Sender: TObject);
+var NewName: string; // AV
begin
inc(ImCount);
if ImCount = 0 then
@@ -554,15 +549,16 @@ begin
chkFitToWindow.Caption := TextByKey('postprocess-fittowindow');
end;
+{
procedure TfrmPostProcess.chkFitToWindowClick(Sender: TObject);
begin
- {if (chkFitToWindow.Checked) then begin
+ if (chkFitToWindow.Checked) then begin
Image.Stretch := true;
Image.Align := alClient;
end else begin
Image.Stretch := false;
Image.Align := alNone;
- end; }
+ end;
end;
-
+}
end.
diff --git a/HARLOWSI.TTF b/HARLOWSI.TTF
deleted file mode 100644
index 3c59ef9..0000000
Binary files a/HARLOWSI.TTF and /dev/null differ
diff --git a/IO/Binary.pas b/IO/Binary.pas
new file mode 100644
index 0000000..80fb6c0
--- /dev/null
+++ b/IO/Binary.pas
@@ -0,0 +1,177 @@
+unit Binary;
+
+interface
+
+const
+
+ HIB_BLOCKSIZE = $10; // 16 bytes
+ HIB_MAXOFFSET = $0F; // HIB_BLOCKSIZE - 1
+
+type
+
+ // low-level binary types
+ TBlock = array[0..HIB_MAXOFFSET] of byte;
+ TWord = array[0..1] of byte;
+ TDWord = array[0..3] of byte;
+ TQWord = array[0..7] of byte;
+ THibRawString = array of byte;
+
+// procedures to write blocks at low level
+procedure WriteData2(var target: TBlock; data: TWord; pos: integer);
+procedure WriteData4(var target: TBlock; data: TDWord; pos: integer);
+procedure WriteData8(var target: TBlock; data: TQWord; pos: integer);
+
+// procedures to read blocks at low level
+procedure ReadData2(source: TBlock; var data: TWord; pos: integer);
+procedure ReadData4(source: TBlock; var data: TDWord; pos: integer);
+procedure ReadData8(source: TBlock; var data: TQWord; pos: integer);
+
+// procedures to write typed data to blocks
+procedure Int16ToBlock(var target: TBlock; pos: integer; data: SmallInt);
+procedure Int32ToBlock(var target: TBlock; pos: integer; data: Integer);
+procedure LongWordToBlock(var target: TBlock; pos: integer; data: LongWord);
+procedure Int64ToBlock(var target: TBlock; pos: integer; data: Int64);
+procedure SingleToBlock(var target: TBlock; pos: integer; data: Single);
+procedure DoubleToBlock(var target: TBlock; pos: integer; data: Double);
+
+// procedures to read typed data from blocks
+function BlockToInt16(source: TBlock; pos: integer): SmallInt;
+function BlockToInt32(source: TBlock; pos: integer): Integer;
+function BlockToLongWord(source: TBlock; pos: integer): LongWord;
+function BlockToInt64(source: TBlock; pos: integer): Int64;
+function BlockToSingle(source: TBlock; pos: integer): Single;
+function BlockToDouble(source: TBlock; pos: integer): Double;
+
+implementation
+
+procedure ReadData2(source: TBlock; var data: TWord; pos: integer);
+const size = 2;
+var i: integer;
+begin
+ for i := 0 to size - 1 do
+ if i + pos < HIB_BLOCKSIZE then
+ data[i] := source[i + pos];
+end;
+procedure ReadData4(source: TBlock; var data: TDWord; pos: integer);
+const size = 4;
+var i: integer;
+begin
+ for i := 0 to size - 1 do
+ if i + pos < HIB_BLOCKSIZE then
+ data[i] := source[i + pos];
+end;
+procedure ReadData8(source: TBlock; var data: TQWord; pos: integer);
+const size = 8;
+var i: integer;
+begin
+ for i := 0 to size - 1 do
+ if i + pos < HIB_BLOCKSIZE then
+ data[i] := source[i + pos];
+end;
+
+procedure WriteData2(var target: TBlock; data: TWord; pos: integer);
+const size = 2;
+var i: integer;
+begin
+ for i := 0 to size - 1 do
+ if i + pos < HIB_BLOCKSIZE then
+ target[i + pos] := data[i];
+end;
+procedure WriteData4(var target: TBlock; data: TDWord; pos: integer);
+const size = 4;
+var i: integer;
+begin
+ for i := 0 to size - 1 do
+ if i + pos < HIB_BLOCKSIZE then
+ target[i + pos] := data[i];
+end;
+procedure WriteData8(var target: TBlock; data: TQWord; pos: integer);
+const size = 8;
+var i: integer;
+begin
+ for i := 0 to size - 1 do
+ if i + pos < HIB_BLOCKSIZE then
+ target[i + pos] := data[i];
+end;
+
+function BlockToInt16(source: TBlock; pos: integer): SmallInt;
+var temp: TWord; data: SmallInt;
+begin
+ ReadData2(source, temp, pos);
+ Move(temp, data, SizeOf(TWord));
+ Result := data;
+end;
+function BlockToInt32(source: TBlock; pos: integer): Integer;
+var temp: TDWord; data: Integer;
+begin
+ ReadData4(source, temp, pos);
+ Move(temp, data, SizeOf(TDWord));
+ Result := data;
+end;
+function BlockToLongWord(source: TBlock; pos: integer): LongWord;
+var temp: TDWord; data: LongWord;
+begin
+ ReadData4(source, temp, pos);
+ Move(temp, data, SizeOf(TDWord));
+ Result := data;
+end;
+function BlockToInt64(source: TBlock; pos: integer): Int64;
+var temp: TQWord; data: Int64;
+begin
+ ReadData8(source, temp, pos);
+ Move(temp, data, SizeOf(TQWord));
+ Result := data;
+end;
+function BlockToSingle(source: TBlock; pos: integer): Single;
+var temp: TDWord; data: Single;
+begin
+ ReadData4(source, temp, pos);
+ Move(temp, data, SizeOf(TDWord));
+ Result := data;
+end;
+function BlockToDouble(source: TBlock; pos: integer): Double;
+var temp: TQWord; data: Double;
+begin
+ ReadData8(source, temp, pos);
+ Move(temp, data, SizeOf(TQWord));
+ Result := data;
+end;
+
+procedure Int16ToBlock(var target: TBlock; pos: integer; data: SmallInt);
+var temp: TWord;
+begin
+ Move(data, temp, SizeOf(TWord));
+ WriteData2(target, temp, pos);
+end;
+procedure Int32ToBlock(var target: TBlock; pos: integer; data: Integer);
+var temp: TDWord;
+begin
+ Move(data, temp, SizeOf(TDWord));
+ WriteData4(target, temp, pos);
+end;
+procedure LongWordToBlock(var target: TBlock; pos: integer; data: LongWord);
+var temp: TDWord;
+begin
+ Move(data, temp, SizeOf(TDWord));
+ WriteData4(target, temp, pos);
+end;
+procedure Int64ToBlock(var target: TBlock; pos: integer; data: Int64);
+var temp: TQWord;
+begin
+ Move(data, temp, SizeOf(TQWord));
+ WriteData8(target, temp, pos);
+end;
+procedure SingleToBlock(var target: TBlock; pos: integer; data: single);
+var temp: TDWord;
+begin
+ Move(data, temp, SizeOf(TDWord));
+ WriteData4(target, temp, pos);
+end;
+procedure DoubleToBlock(var target: TBlock; pos: integer; data: double);
+var temp: TQWord;
+begin
+ Move(data, temp, SizeOf(TQWord));
+ WriteData8(target, temp, pos);
+end;
+
+end.
diff --git a/IO/CommandLine.pas b/IO/CommandLine.pas
new file mode 100644
index 0000000..e727894
--- /dev/null
+++ b/IO/CommandLine.pas
@@ -0,0 +1,48 @@
+unit CommandLine;
+
+interface
+
+uses RegularExpressionsCore;
+
+type TCommandLine = class
+ public
+ CreateFromTemplate: boolean;
+ TemplateFile: string;
+ TemplateName: string;
+ //Lite: boolean;
+
+ procedure Load;
+ end;
+
+implementation
+
+procedure TCommandLine.Load;
+var
+ Regex: TPerlRegEx;
+begin
+ Regex := TPerlRegEx.Create;
+ Regex.RegEx := '-template\s+"(.+)"\s+"(.+)"';
+ Regex.Options := [preSingleLine, preCaseless];
+ Regex.Subject := CmdLine; // Utf8String(CmdLine);
+ CreateFromTemplate := false;
+ if Regex.Match then
+ if Regex.GroupCount = 2 then begin
+ CreateFromTemplate := true;
+ TemplateFile := Regex.Groups[1];
+ TemplateName := Regex.Groups[2];
+ end;
+ Regex.Destroy;
+
+ { // AV: this is not so useful since NXFORMS still equals to 100
+ Regex := TPerlRegEx.Create;
+ Regex.RegEx := '-lite';
+ Regex.Options := [preSingleLine, preCaseless];
+ Regex.Subject := CmdLine; // Utf8String(CmdLine);
+ CreateFromTemplate := false;
+ if Regex.Match then
+ Lite := true;
+ Regex.Destroy;
+ }
+end;
+
+end.
diff --git a/IO/MissingPlugin.pas b/IO/MissingPlugin.pas
new file mode 100644
index 0000000..b853089
--- /dev/null
+++ b/IO/MissingPlugin.pas
@@ -0,0 +1,99 @@
+{
+ Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+}
+
+unit MissingPlugin;
+
+interface
+
+ uses Windows, Global, Classes, LoadTracker, ComCtrls, SysUtils,
+ ControlPoint, Translation;
+
+ const RegisteredAttributes : array[0..29] of string = (
+ 'weight', 'color', 'symmetry', 'color_speed', 'coefs', 'chaos',
+ 'plotmode', 'opacity', 'post', 'var', 'var1', 'var_color',
+ 'name', 'linear3D', 'GlynnSim3_thickness2', 'var_order',
+ 'perspective', 'perspective_dist', 'perspective_angle',
+ 'fan', 'rings', 'waves', 'popcorn', 'bent', 'secant', 'arch',
+ 'droste', 'droste_r1', 'droste_r2', 'Spherical3D'
+ );
+
+ var MissingPluginList : TStringList;
+ Parsing : boolean;
+ ErrorMessageString : string;
+
+ procedure BeginParsing;
+ procedure CheckAttribute(attr: string);
+ function EndParsing(cp : TControlPoint; var statusPanelText : string): boolean;
+ procedure AnnoyUser;
+
+implementation
+
+ procedure BeginParsing;
+ begin
+ // AV: moved into main unit to be sure that it's created only 1 time
+ //MissingPluginList := TStringList.Create;
+ MissingPluginList.Clear; // AV
+ if (AutoOpenLog = true) then
+ if (LoadForm.Showing = false) then
+ LoadForm.Show;
+ end;
+
+ procedure CheckAttribute(attr: string);
+ var i : integer;
+ begin
+ for i := 0 to Length(RegisteredAttributes)-1 do
+ if attr = RegisteredAttributes[i] then exit;
+
+ if MissingPluginList.IndexOf(attr) < 0 then
+ MissingPluginList.Add(attr);
+ end;
+
+ function EndParsing(cp : TControlPoint; var statusPanelText : string): boolean;
+ var
+ str, str2 : string;
+ i : integer;
+ newl : TStringList;
+ begin
+ str2 := TextByKey('main-status-variationsorvariables');
+ if (cp.used_plugins.Count > 0) then begin
+ newl := TStringList.Create;
+ for i := 0 to MissingPluginList.Count - 1 do begin
+ if cp.used_plugins.IndexOf(MissingPluginList[i]) >= 0 then
+ newl.Add(MissingPluginList[i]);
+ end;
+ str2 := TextByKey('main-status-plugins');
+ // MissingPluginList.Free;
+ // MissingPluginList := newl; // AV: here was a memory leak
+ MissingPluginList.Clear; // AV
+ MissingPluginList.Assign(newl); // AV
+ newl.Free; // AV
+ end;
+
+ if MissingPluginList.Count > 0 then
+ begin
+ statusPanelText := Format(TextByKey('main-status-loadingerrorcount'), [MissingPluginList.Count]);
+
+ for i := 0 to MissingPluginList.Count - 1 do
+ str := str + #13#10 + ' - ' + MissingPluginList[i];
+ ErrorMessageString := Format(TextByKey('main-status-morepluginsneeded'), [cp.name, str2]) + str;
+ LoadForm.Output.Text := LoadForm.Output.Text +
+ ErrorMessageString + #13#10#13#10;
+ Result := false;
+ end else begin
+ statusPanelText := TextByKey('main-status-noloadingerrors');
+ ErrorMessageString := '';
+ Result := true;
+ end;
+ // AV: moved into main unit to be sure that it's destroyed only 1 time
+ //MissingPluginList.Free;
+ MissingPluginList.Clear; // AV
+ end;
+
+ procedure AnnoyUser;
+ begin
+ if (ErrorMessageString = '') or (not WarnOnMissingPlugin) then exit;
+ MessageBox($00000000, PChar(ErrorMessageString), PChar('Apophysis AV'), MB_ICONHAND or MB_OK);
+ end;
+end.
diff --git a/IO/Settings.pas b/IO/Settings.pas
new file mode 100644
index 0000000..b79d044
--- /dev/null
+++ b/IO/Settings.pas
@@ -0,0 +1,1474 @@
+{
+ Apophysis Copyright (C) 2001-2004 Mark Townsend
+ Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
+ Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
+
+ Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
+ Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+unit Settings;
+
+interface
+
+uses Graphics;
+
+function ReadPluginDir: string;
+procedure ReadSettings;
+procedure SaveSettings;
+
+implementation
+
+uses
+ Windows, Classes, SysUtils, StrUtils, Forms, Registry, Global, Dialogs,
+ XFormMan;
+
+(*
+function ReadPluginDir: string;
+var
+ settingFileName: string;
+ sl : TStringList;
+begin
+ sl := TStringList.Create;
+
+ settingFileName := ExtractFilePath(Application.ExeName) + 'ApoPluginSrc.dat';
+ if FileExists(settingFileName) then
+ sl.LoadFromFile(settingFileName)
+ else begin
+ settingFileName := GetEnvVarValue('APPDATA') + '\ApoPluginSrc.dat';
+
+ if FileExists(settingFileName) then
+ sl.LoadFromFile(settingFileName)
+ else
+ sl.Text := ExtractFilePath(Application.ExeName) + 'Plugins\';
+ end;
+
+ if Trim(sl.Text) = '' then
+ sl.Text := ExtractFilePath(Application.ExeName) + 'Plugins\';
+
+ Result := Trim(sl.Text);
+ if (RightStr(Result, 1) <> '\') and (Result <> '') then
+ Result := Result + '\';
+
+ sl.Free;
+end;
+
+procedure SavePluginDir(data: string);
+ var
+ settingFileName: string;
+ sl : TStringList;
+ begin
+ settingFileName := ExtractFilePath(Application.ExeName) + 'ApoPluginSrc.dat';
+ sl := TStringList.Create;
+ sl.Text := PluginPath;
+
+ try
+ sl.SaveToFile(settingFileName);
+ sl.Destroy;
+ except
+ // not elevated?
+ settingFileName := GetEnvVarValue('APPDATA') + '\ApoPluginSrc.dat';
+ try
+ sl.SaveToFile(settingFileName);
+ except
+ MessageBox(0, PCHAR(TextByKey('main-status-pluginpath-ioerror')),
+ PCHAR('Apophysis'), MB_ICONWARNING);
+ end;
+ sl.Free;
+ end;
+end;
+*)
+
+// AV: rewrote to save the plugin directory in the Windows registry
+// because this 'ApoPluginSrc.dat' always resets my settings!
+function ReadPluginDir: string;
+var
+ Registry: TRegistry;
+ plugdir: string;
+begin
+ plugdir := ExtractFilePath(Application.ExeName) + 'Plugins\';
+ Result := plugdir;
+ Registry := TRegistry.Create;
+ try
+ Registry.RootKey := HKEY_CURRENT_USER;
+ if Registry.OpenKey('Software\' + APP_NAME + '\Defaults', False) then
+ begin
+ if Registry.ValueExists('PluginPath') then
+ begin
+ Result := Trim(Registry.ReadString('PluginPath'));
+ if (RightStr(Result, 1) <> '\') and (Result <> '') then
+ Result := Result + '\';
+ end
+ else
+ Result := plugdir;
+
+ Registry.CloseKey;
+ end
+ else
+ Result := plugdir;
+ finally
+ Registry.Free;
+
+ if (Result = '') or (not DirectoryExists(Result)) then
+ Result := ExtractFilePath(Application.ExeName); // AV
+ end;
+end;
+
+procedure ReadSettings;
+var
+ Registry: TRegistry;
+ DefaultPath: string;
+ i: integer;
+ VarUsed: byte;
+begin
+ // DefaultPath := GetEnvVarValue('USERPROFILE');
+ DefaultPath := AppPath; // AV: backward compatibility is more convenient
+ PluginPath := ReadPluginDir; // AV
+ Registry := TRegistry.Create;
+ try
+ Registry.RootKey := HKEY_CURRENT_USER;
+
+ { Defaults }
+ if Registry.OpenKey('Software\' + APP_NAME + '\Defaults', False) then
+ begin
+ if Registry.ValueExists('DefaultFlameFile3D') then
+ defFlameFile := Registry.ReadString('DefaultFlameFile3D')
+ else
+ defFlameFile := '';
+
+ if Registry.ValueExists('AlwaysCreateBlankFlame') then
+ AlwaysCreateBlankFlame := Registry.ReadBool('AlwaysCreateBlankFlame')
+ else
+ AlwaysCreateBlankFlame := false;
+
+ if Registry.ValueExists('GradientFile') then
+ GradientFile := Registry.ReadString('GradientFile')
+ else
+ GradientFile := '';
+
+ if Registry.ValueExists('SavePath3D') then
+ SavePath := Registry.ReadString('SavePath3D')
+ else
+ SavePath := DefaultPath + 'Flames.flame';
+
+ if Registry.ValueExists('RandomizeTemplates') then
+ RandomizeTemplates := Registry.ReadBool('RandomizeTemplates')
+ else
+ RandomizeTemplates := True;
+
+ if Registry.ValueExists('WarnOnMissingPlugin') then
+ WarnOnMissingPlugin := Registry.ReadBool('WarnOnMissingPlugin')
+ else WarnOnMissingPlugin := true;
+
+ if Registry.ValueExists('SetEnglishLayout') then
+ SetEngLayout := Registry.ReadBool('SetEnglishLayout')
+ else SetEngLayout := false;
+
+ if Registry.ValueExists('ApplyFlatten') then
+ ApplyFlatten := Registry.ReadBool('ApplyFlatten')
+ else ApplyFlatten := true;
+
+ if Registry.ValueExists('LanguageFile') then
+ LanguageFile := Registry.ReadString('LanguageFile')
+ else LanguageFile := '';
+
+ if Registry.ValueExists('SmoothPaletteFile') then
+ defSmoothPaletteFile := Registry.ReadString('SmoothPaletteFIle')
+ else
+ defSmoothPaletteFile := DefaultPath + 'Gradients\SmoothPalette.ugr';
+
+ if Registry.ValueExists('PlaySoundOnRenderComplete') then
+ PlaySoundOnRenderComplete := Registry.ReadBool('PlaySoundOnRenderComplete')
+ else
+ PlaySoundOnRenderComplete := false;
+ if Registry.ValueExists('RenderCompleteSoundFile') then
+ RenderCompleteSoundFile := Registry.ReadString('RenderCompleteSoundFile')
+ else
+ RenderCompleteSoundFile := '';
+
+ if Registry.ValueExists('ConfirmDelete') then
+ ConfirmDelete := Registry.ReadBool('ConfirmDelete')
+ else
+ ConfirmDelete := True;
+ if Registry.ValueExists('OldPaletteFormat') then
+ OldPaletteFormat := Registry.ReadBool('OldPaletteFormat')
+ else
+ OldPaletteFormat := false;
+
+ if Registry.ValueExists('ConfirmExit') then
+ ConfirmExit := Registry.ReadBool('ConfirmExit')
+ else
+ ConfirmExit := True;
+
+ if Registry.ValueExists('ConfirmClearScript') then // AV
+ ConfirmClearScript := Registry.ReadBool('ConfirmClearScript')
+ else
+ ConfirmClearScript := False;
+
+ if Registry.ValueExists('ConfirmResetUndo') then // AV
+ ConfirmResetUndo := Registry.ReadBool('ConfirmResetUndo')
+ else
+ ConfirmResetUndo := False;
+
+ if Registry.ValueExists('PreserveQuality') then
+ PreserveQuality := Registry.ReadBool('PreserveQuality')
+ else
+ PreserveQuality := true;
+
+ if Registry.ValueExists('KeepBackground') then
+ KeepBackground := Registry.ReadBool('KeepBackground')
+ else
+ KeepBackground := False;
+
+ if Registry.ValueExists('NumTries') then
+ NumTries := Registry.ReadInteger('NumTries')
+ else
+ NumTries := 10;
+ if Registry.ValueExists('TryLength') then
+ TryLength := Registry.ReadInteger('TryLength')
+ else
+ TryLength := 100000;
+
+ if Registry.ValueExists('MinTransforms') then
+ begin
+ randMinTransforms := Registry.ReadInteger('MinTransforms');
+ if randMinTransforms < 2 then randMinTransforms := 2;
+ end
+ else
+ randMinTransforms := 2;
+
+ if Registry.ValueExists('MaxTransforms') then
+ begin
+ randMaxTransforms := Registry.ReadInteger('MaxTransforms');
+ if randMaxTransforms < randMinTransforms then randMaxTransforms := randMinTransforms;
+ end
+ else
+ randMaxTransforms := randMinTransforms + 1;
+
+ if Registry.ValueExists('MutationMinTransforms') then
+ begin
+ mutantMinTransforms := Registry.ReadInteger('MutationMinTransforms');
+ if mutantMinTransforms < 2 then mutantMinTransforms := 2;
+ end
+ else
+ mutantMinTransforms := 2;
+
+ if Registry.ValueExists('MutationMaxTransforms') then
+ begin
+ mutantMaxTransforms := Registry.ReadInteger('MutationMaxTransforms');
+ if mutantMaxTransforms < mutantMinTransforms then mutantMinTransforms := mutantMinTransforms;
+ end
+ else
+ mutantMaxTransforms := mutantMinTransforms + 1;
+
+ if Registry.ValueExists('RandomGradient') then
+ randGradient := Registry.ReadInteger('RandomGradient')
+ else
+ randGradient := 0;
+
+ if Registry.ValueExists('ParameterFolder3D') then
+ ParamFolder := Registry.ReadString('ParameterFolder3D')
+ else
+ ParamFolder := DefaultPath;
+
+ if Registry.ValueExists('UPRPath') then
+ UPRPath := Registry.ReadString('UPRPath')
+ else
+ UPRPath := DefaultPath + 'ApophysisAV_export.upr'; // AV
+
+ if Registry.ValueExists('ImageFolder') then
+ ImageFolder := Registry.ReadString('ImageFolder')
+ else
+ ImageFolder := GetEnvVarValue('USERPROFILE') + '\Pictures\'; // AV
+
+ if Registry.ValueExists('ScreenshotsFolder') then // AV
+ ScreenShotPath := Registry.ReadString('ScreenshotsFolder')
+ else
+ ScreenShotPath := DefaultPath + 'ScreenShots\';
+
+ if Registry.ValueExists('DefaultScript') then // AV
+ defScriptFile := Registry.ReadString('DefaultScript')
+ else
+ defScriptFile := '';
+
+ if Registry.ValueExists('AutoSaveXML') then // AV
+ AutoSaveXML := Registry.ReadBool('AutoSaveXML')
+ else
+ AutoSaveXML := true;
+
+ if Registry.ValueExists('UPRWidth') then
+ UPRWidth := Registry.ReadInteger('UPRWidth')
+ else
+ UPRWidth := 640;
+
+ if Registry.ValueExists('UPRHeight') then
+ UPRHeight := Registry.ReadInteger('UPRHeight')
+ else
+ UPRHeight := 480;
+
+ if Registry.ValueExists('BrowserPath') then
+ BrowserPath := Registry.ReadString('BrowserPath')
+ else
+ BrowserPath := DefaultPath;
+
+ if Registry.ValueExists('EditPreviewQaulity') then
+ EditPrevQual := Registry.ReadInteger('EditPreviewQaulity')
+ else
+ EditPrevQual := 1;
+
+ if Registry.ValueExists('MutatePreviewQaulity') then
+ MutatePrevQual := Registry.ReadInteger('MutatePreviewQaulity')
+ else
+ MutatePrevQual := 0; // AV: hack, to speed up the calculations
+
+ if Registry.ValueExists('AdjustPreviewQaulity') then
+ AdjustPrevQual := Registry.ReadInteger('AdjustPreviewQaulity')
+ else
+ AdjustPrevQual := 1;
+
+ if Registry.ValueExists('ThumbPrevQuality') then // AV
+ ThumbPrevQual := Registry.ReadInteger('ThumbPrevQuality')
+ else
+ ThumbPrevQual := 1;
+
+ if Registry.ValueExists('AnimPrevQuality') then // AV
+ AnimPrevQual := Registry.ReadInteger('AnimPrevQuality')
+ else
+ AnimPrevQual := 1;
+
+ if Registry.ValueExists('RandomPrefix') then
+ RandomPrefix := Registry.ReadString('RandomPrefix')
+ else
+ RandomPrefix := 'ApoAV-';
+ if Registry.ValueExists('RandomDate') then
+ RandomDate := Registry.ReadString('RandomDate')
+ else
+ RandomDate := '';
+ if Registry.ValueExists('RandomIndex') then
+ RandomIndex := Registry.ReadInteger('RandomIndex')
+ else
+ RandomIndex := 0;
+
+ if Registry.ValueExists('SymmetryType') then
+ SymmetryType := Registry.ReadInteger('SymmetryType')
+ else
+ SymmetryType := 0;
+
+ if Registry.ValueExists('SymmetryOrder') then
+ SymmetryOrder := Registry.ReadInteger('SymmetryOrder')
+ else
+ SymmetryOrder := 4;
+
+ if Registry.ValueExists('SymmetryNVars') then
+ SymmetryNVars := Registry.ReadInteger('SymmetryNVars')
+ else
+ SymmetryNVars := 12;
+
+ if Registry.ValueExists('RandBackColor') then
+ RandBackColor := Registry.ReadInteger('RandBackColor')
+ else
+ RandBackColor := $000000;
+
+ if Registry.ValueExists('MinNodes') then
+ begin
+ MinNodes := Registry.ReadInteger('MinNodes');
+ if MinNodes < 2 then MinNodes := 2;
+ end
+ else
+ MinNodes := 2;
+
+ if Registry.ValueExists('MinHue') then
+ MinHue := Registry.ReadInteger('MinHue')
+ else
+ MinHue := 0;
+
+ if Registry.ValueExists('MinSat') then
+ MinSat := Registry.ReadInteger('MinSat')
+ else
+ MinSat := 0;
+
+ if Registry.ValueExists('MinLum') then
+ MinLum := Registry.ReadInteger('MinLum')
+ else
+ MinLum := 0;
+
+ if Registry.ValueExists('MaxNodes') then
+ begin
+ MaxNodes := Registry.ReadInteger('MaxNodes');
+ if MaxNodes < MinNodes then MaxNodes := MinNodes;
+ end
+ else
+ MaxNodes := 10;
+
+ if Registry.ValueExists('MaxHue') then
+ begin
+ MaxHue := Registry.ReadInteger('MaxHue');
+ if MaxHue < 0 then MaxHue := 0;
+ end
+ else
+ MaxHue := 600;
+
+ if Registry.ValueExists('MaxSat') then
+ begin
+ MaxSat := Registry.ReadInteger('MaxSat');
+ if MaxSat < 0 then MaxSat := 0;
+ end
+ else
+ MaxSat := 100;
+
+ if Registry.ValueExists('EqualStripes') then // AV
+ EqualStripes := Registry.ReadBool('EqualStripes')
+ else
+ EqualStripes := True; // gradient color stripes' width
+
+ if Registry.ValueExists('ColorBlendType') then // AV
+ randColorBlend := Registry.ReadInteger('ColorBlendType')
+ else
+ randColorBlend := 0; // RGB-blending
+
+ if Registry.ValueExists('RandomGradientFile') then
+ randGradientFile := Registry.ReadString('RandomGradientFile')
+ else
+ randGradientFile := '';
+
+ if Registry.ValueExists('RotationMode') then
+ MainForm_RotationMode := Registry.ReadInteger('RotationMode')
+ else MainForm_RotationMode := 0;
+
+ if Registry.ValueExists('EnumerationMode') then // AV
+ FlameEnumMode := Registry.ReadInteger('EnumerationMode')
+ else FlameEnumMode := 0;
+
+ if Registry.ValueExists('MaxLum') then
+ begin
+ MaxLum := Registry.ReadInteger('MaxLum');
+ if MaxLum <= 0 then MaxLum := 100;
+ end
+ else
+ MaxLum := 100;
+
+ if Registry.ValueExists('BatchSize') then
+ begin
+ BatchSize := Registry.ReadInteger('BatchSize');
+ if BatchSize <= 0 then BatchSize := 10;
+ end
+ else
+ BatchSize := 10;
+
+ if Registry.ValueExists('ScriptPath') then
+ ScriptPath := Registry.ReadString('ScriptPath')
+ else
+ ScriptPath := DefaultPath + 'Scripts\';
+
+ if Registry.ValueExists('FunctionLibrary') then
+ defLibrary := Registry.ReadString('FunctionLibrary')
+ else // AV: moved back into the scripting folder
+ defLibrary := DefaultPath + 'Scripts\Functions.asc';
+
+ if Registry.ValueExists('ExportFileFormat') then
+ ExportFileFormat := Registry.ReadInteger('ExportFileFormat')
+ else
+ ExportFileFormat := 1;
+
+ if Registry.ValueExists('ExportWidth') then
+ begin
+ ExportWidth := Registry.ReadInteger('ExportWidth');
+ if ExportWidth <= 0 then ExportWidth := 640;
+ end
+ else
+ ExportWidth := 640;
+
+ if Registry.ValueExists('ExportHeight') then
+ begin
+ ExportHeight := Registry.ReadInteger('ExportHeight');
+ if ExportHeight <= 0 then ExportHeight := 480;
+ end
+ else
+ ExportHeight := 480;
+
+ if Registry.ValueExists('ExportDensity') then
+ begin
+ ExportDensity := Registry.ReadFloat('ExportDensity');
+ if ExportDensity <= 0 then ExportDensity := 100;
+ end
+ else
+ ExportDensity := 100;
+
+ if Registry.ValueExists('ExportOversample') then
+ begin
+ ExportOversample := Registry.ReadInteger('ExportOversample');
+ if ExportOversample <= 0 then ExportOversample := 2;
+ end
+ else
+ ExportOversample := 2;
+
+ if Registry.ValueExists('ExportFilter') then
+ begin
+ ExportFilter := Registry.ReadFloat('ExportFilter');
+ if ExportFilter <= 0 then ExportFilter := 0.6;
+ end
+ else
+ ExportFilter := 0.6;
+
+ // AV: don't need to waste our time for these properties
+ (*
+ if Registry.ValueExists('ExportBatches') then
+ begin
+ ExportBatches := Registry.ReadInteger('ExportBatches');
+ if ExportBatches <= 0 then ExportBatches := 3;
+ end
+ else
+ ExportBatches := 3;
+
+ if Registry.ValueExists('Nick') then
+ begin
+ SheepNick := Registry.ReadString('Nick');
+ end
+ else
+ begin
+ SheepNick := '';
+ end;
+ if Registry.ValueExists('URL') then
+ begin
+ SheepURL := Registry.ReadString('URL');
+ end
+ else
+ begin
+ SheepURL := '';
+ end;
+ if Registry.ValueExists('Pass') then
+ begin
+ SheepPW := Registry.ReadString('Pass');
+ end
+ else
+ begin
+ SheepPW := '';
+ end;
+ if Registry.ValueExists('Server') then
+ begin
+ SheepServer := Registry.ReadString('Server');
+ end
+ else
+ begin
+ SheepServer := 'http://v2d5.sheepserver.net/';
+ end;
+ *)
+
+ if Registry.ValueExists('Renderer') then
+ flam3Path := Registry.ReadString('Renderer')
+ else
+ flam3Path := GetEnvVarValue('PROGRAMFILES') + '\flam3-3.0.1\flam3-render.exe'; // AV
+
+ if Registry.ValueExists('ShowProgress') then
+ ShowProgress := Registry.ReadBool('ShowProgress')
+ else
+ ShowProgress := true;
+
+ if Registry.ValueExists('LineCenterColor') then
+ LineCenterColor := Registry.ReadInteger('LineCenterColor')
+ else
+ LineCenterColor := $FFFFFF;
+
+ if Registry.ValueExists('LineThirdsColor') then
+ LineThirdsColor := Registry.ReadInteger('LineThirdsColor')
+ else
+ LineThirdsColor := $0000FF;
+
+ if Registry.ValueExists('LineGRColor') then
+ LineGRColor := Registry.ReadInteger('LineGRColor')
+ else
+ LineGRColor := $00FF00;
+
+ if Registry.ValueExists('EnableGuides') then
+ EnableGuides := Registry.ReadBool('EnableGuides')
+ else
+ EnableGuides := false;
+
+ { FormRender }
+ if Registry.ValueExists('SaveIncompleteRenders') then
+ SaveIncompleteRenders := Registry.ReadBool('SaveIncompleteRenders')
+ else
+ SaveIncompleteRenders := false;
+
+ if Registry.ValueExists('ShowRenderStats') then
+ ShowRenderStats := Registry.ReadBool('ShowRenderStats')
+ else
+ ShowRenderStats := false;
+ if Registry.ValueExists('ShowRenderImage') then // AV
+ ShowRenderImage := Registry.ReadBool('ShowRenderImage')
+ else
+ ShowRenderImage := false;
+ if Registry.ValueExists('LowerRenderPriority') then
+ LowerRenderPriority := Registry.ReadBool('LowerRenderPriority')
+ else
+ LowerRenderPriority := false;
+
+ if Registry.ValueExists('PNGTransparency') then begin
+ PNGTransparency := Registry.ReadInteger('PNGTransparency');
+ if PNGTransparency > 1 then PNGTransparency := 1; // tmp
+ end else
+ PNGTransparency := 0;
+
+ if Registry.ValueExists('ShowTransparency') then
+ ShowTransparency := Registry.ReadBool('ShowTransparency')
+ else
+ ShowTransparency := False;
+
+ if Registry.ValueExists('ExtendMainPreview') then
+ ExtendMainPreview := Registry.ReadBool('ExtendMainPreview')
+ else
+ ExtendMainPreview := true;
+
+ if Registry.ValueExists('MainPreviewScale') then begin
+ MainPreviewScale := Registry.ReadFloat('MainPreviewScale');
+ if MainPreviewScale < 1 then MainPreviewScale := 1
+ else if MainPreviewScale > 3 then MainPreviewScale := 3;
+ end else
+ MainPreviewScale := 1.2;
+
+ if Registry.ValueExists('NrTreads') then begin
+ NrTreads := Registry.ReadInteger('NrTreads');
+ if NrTreads < 1 then NrTreads := 1; // AV
+ end else
+ NrTreads := 1;
+
+ if Registry.ValueExists('UseNrThreads') then begin
+ UseNrThreads := Registry.ReadInteger('UseNrThreads');
+ if UseNrThreads < 1 then UseNrThreads := 1;
+ end else
+ UseNrThreads := 1;
+
+ (*
+ if Registry.ValueExists('StartupCheckForUpdates') then begin
+ StartupCheckForUpdates := Registry.ReadBool('StartupCheckForUpdates');
+ end else begin
+ StartupCheckForUpdates := true;
+ end;
+ *)
+
+ // AV: animation defaults
+ if Registry.ValueExists('AnimPrefix') then
+ defAnimPrefix := Registry.ReadString('AnimPrefix')
+ else
+ defAnimPrefix := 'animate-';
+ if Registry.ValueExists('AnimFPS') then
+ AnimFPS := Registry.ReadInteger('AnimFPS')
+ else
+ AnimFPS := 25;
+ if Registry.ValueExists('FrameExt') then
+ defFrameExt := Registry.ReadInteger('FrameExt')
+ else
+ defFrameExt := 1;
+ if Registry.ValueExists('CreateAnimFolder') then
+ CreateAnimFolder := Registry.ReadBool('CreateAnimFolder')
+ else
+ CreateAnimFolder := True;
+
+ if Registry.ValueExists('AutoOpenLog') then
+ AutoOpenLog := Registry.ReadBool('AutoOpenLog')
+ else
+ AutoOpenLog := false;
+
+ if Registry.ValueExists('ClassicListMode') then
+ ClassicListMode := Registry.ReadBool('ClassicListMode')
+ else
+ ClassicListMode := true;
+
+ if Registry.ValueExists('LastOpenFile') then
+ LastOpenFile := Registry.ReadString('LastOpenFile')
+ else
+ LastOpenFile := '';
+
+ if Registry.ValueExists('LastOpenFileEntry') then
+ LastOpenFileEntry := Registry.ReadInteger('LastOpenFileEntry')
+ else
+ LastOpenFileEntry := 1;
+
+ if Registry.ValueExists('RememberLastOpenFile') then
+ RememberLastOpenFile := Registry.ReadBool('RememberLastOpenFile')
+ else
+ RememberLastOpenFile := false;
+
+ if Registry.ValueExists('UseSmallThumbnails') then
+ UseSmallThumbnails := Registry.ReadBool('UseSmallThumbnails')
+ else
+ UseSmallThumbnails := true;
+
+ if Registry.ValueExists('HelpPath') then
+ HelpPath := Registry.ReadString('HelpPath')
+ else
+ HelpPath := DefaultPath + 'Apophysis AV.chm'; // TODO
+
+ if Registry.ValueExists('ChaoticaPath') then
+ ChaoticaPath := Registry.ReadString('ChaoticaPath')
+ else
+ ChaoticaPath := '';
+ {
+ if Registry.ValueExists('UseX64IfPossible') then
+ UseX64IfPossible := Registry.ReadBool('UseX64IfPossible')
+ else
+ UseX64IfPossible := false;
+ }
+ end
+ else
+ begin
+ // StartupCheckForUpdates := true;
+ AlwaysCreateBlankFlame := false;
+ MainForm_RotationMode := 0;
+ FlameEnumMode := 0; // AV
+ EditPrevQual := 1;
+ MutatePrevQual := 0; // AV: hack, to speed up the calculations
+ AdjustPrevQual := 1;
+ ThumbPrevQual := 1; // AV
+ AnimPrevQual := 1; // AV
+ GradientFile := '';
+ defFlameFile := '';
+ SavePath := DefaultPath + 'Flames.flame';
+ WarnOnMissingPlugin := true;
+ SetEngLayout := false;
+ ApplyFlatten := true;
+ LanguageFile := '';
+ HelpPath := DefaultPath + 'Apophysis AV.chm';
+ defSmoothPaletteFile := DefaultPath + 'Gradients\SmoothPalette.ugr';
+ ConfirmDelete := True;
+ ConfirmExit := True;
+ ConfirmClearScript := False; // AV
+ ConfirmResetUndo := False; // AV
+ OldPaletteFormat := false;
+ NumTries := 10;
+ TryLength := 100000;
+ randMinTransforms := 2;
+ randMaxTransforms := 3;
+ mutantMinTransforms := 2;
+ mutantMaxTransforms := 6;
+ randGradient := 0;
+ PreserveQuality := false;
+ KeepBackground := False;
+ RandBackColor := $000000;
+ RandomizeTemplates := True;
+ UPRPath := DefaultPath + 'ApophysisAV_export.upr'; // AV
+ ImageFolder := GetEnvVarValue('USERPROFILE') + '\Pictures\'; // AV
+ ParamFolder := DefaultPath;
+ ScreenShotPath := DefaultPath + 'ScreenShots\'; // AV
+ defScriptFile := ''; // AV
+ AutoSaveXML := True; // AV
+ UPRWidth := 640;
+ UPRHeight := 480;
+ AnimFPS := 25;
+ defFrameExt := 1;
+ defAnimPrefix := 'animate-';
+ CreateAnimFolder := True;
+ RandomPrefix := 'ApoAV-';
+ RandomIndex := 0;
+ RandomDate := '';
+ SymmetryType := 0;
+ SymmetryOrder := 4;
+ SymmetryNVars := 12;
+ MinNodes := 2;
+ MaxNodes := 10;
+ MinHue := 0;
+ MinSat := 0;
+ MinLum := 0;
+ MaxHue := 600;
+ MaxSat := 100;
+ MaxLum := 100;
+ randGradientFile := '';
+ randColorBlend := 0; // AV
+ EqualStripes := True; // AV
+ BatchSize := 10;
+ ScriptPath := DefaultPath + 'Scripts\';
+ defLibrary := DefaultPath + 'Scripts\Functions.asc'; // AV
+ ExportFileFormat := 1;
+ ExportWidth := 640;
+ ExportHeight := 480;
+ ExportDensity := 100;
+ ExportOversample := 2;
+ ExportFilter := 0.6;
+ (*
+ ExportBatches := 3;
+ SheepNick := '';
+ SheepURL := '';
+ SheepPW := '';
+ SheepServer := 'http://v2d5.sheepserver.net/';
+ *)
+ flam3Path := GetEnvVarValue('PROGRAMFILES') + '\flam3-3.0.1\flam3-render.exe'; // AV
+ ShowProgress := true;
+ SaveIncompleteRenders := false;
+ LowerRenderPriority := false;
+ ShowRenderStats := false;
+ ShowRenderImage := false;
+ PNGTransparency := 0;
+ ShowTransparency := False;
+ MainPreviewScale := 1.2;
+ ExtendMainPreview := true;
+ NrTreads := 1;
+ UseNrThreads := 1;
+ AutoOpenLog := false;
+ ClassicListMode := true;
+ LastOpenFile := '';
+ LastOpenFileEntry := 1;
+ RememberLastOpenFile := false;
+ UseSmallThumbnails := true;
+ LineCenterColor := $FFFFFF;
+ LineThirdsColor := $0000FF;
+ LineGRColor := $00FF00;
+ EnableGuides := false;
+ ChaoticaPath := '';
+ //UseX64IfPossible := false;
+ end;
+ Registry.CloseKey;
+
+ SetLength(Variations, NRVAR);
+ SetLength(FavouriteVariations, NRVAR); // AV
+ if Registry.OpenKey('Software\' + APP_NAME + '\Variations', False) then
+ begin
+ for i := 0 to NRVAR-1 do
+ begin
+ if Registry.ValueExists(Varnames(i)) then
+ begin
+ VarUsed := Registry.ReadInteger(Varnames(i));
+ Variations[i] := (VarUsed and 1) <> 0;
+ FavouriteVariations[i] := (VarUsed and 2) <> 0;
+ end
+ else
+ Variations[i] := false;
+ end;
+ end
+ else begin
+ // AV: we dont't need multiple z- and pre_ variations by default...
+ Variations[0] := True; // linear
+ Variations[3] := True; // spherical
+ for i := 10 to 14 do
+ Variations[i] := True;
+ Variations[46] := True; // pdj
+ Variations[47] := True; // julian
+ end;
+ Registry.CloseKey;
+
+ { Editor } // --Z-- moved from EditForm
+ if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Editor', False) then
+ begin
+ if Registry.ValueExists('UseTransformColors') then
+ UseTransformColors := Registry.ReadBool('UseTransformColors')
+ else
+ UseTransformColors := False;
+ if Registry.ValueExists('HelpersEnabled') then
+ HelpersEnabled := Registry.ReadBool('HelpersEnabled')
+ else
+ HelpersEnabled := true;
+ if Registry.ValueExists('ShowAllXforms') then
+ ShowAllXforms := Registry.ReadBool('ShowAllXforms')
+ else
+ ShowAllXforms := true;
+
+ if Registry.ValueExists('AllowResetCoefs') then // AV
+ AllowResetCoefs := Registry.ReadBool('AllowResetCoefs')
+ else
+ AllowResetCoefs := false;
+ if Registry.ValueExists('AllowResetLinear') then // AV
+ AllowResetLinear := Registry.ReadBool('AllowResetLinear')
+ else
+ AllowResetLinear := true;
+ if Registry.ValueExists('SyncTriangles') then // AV
+ UseTriangleSync := Registry.ReadBool('SyncTriangles')
+ else
+ UseTriangleSync := false;
+
+ if Registry.ValueExists('EnableEditorPreview') then
+ EnableEditorPreview := Registry.ReadBool('EnableEditorPreview')
+ else
+ EnableEditorPreview := false;
+ if Registry.ValueExists('EditorPreviewTransparency') then
+ EditorPreviewTransparency := Registry.ReadInteger('EditorPreviewTransparency')
+ else
+ EditorPreviewTransparency := 192;
+
+ if Registry.ValueExists('BackgroundColor') then
+ EditorBkgColor := Registry.ReadInteger('BackgroundColor')
+ else
+ EditorBkgColor := integer(clBlack);
+ if Registry.ValueExists('GridColor1') then
+ GridColor1 := Registry.ReadInteger('GridColor1')
+ else
+ GridColor1 := $444444;
+ if Registry.ValueExists('GridColor2') then
+ GridColor2 := Registry.ReadInteger('GridColor2')
+ else
+ GridColor2 := $333333;
+ if Registry.ValueExists('HelpersColor') then
+ HelpersColor := Registry.ReadInteger('HelpersColor')
+ else
+ HelpersColor := $808080;
+ if Registry.ValueExists('ReferenceTriangleColor') then
+ ReferenceTriangleColor := Registry.ReadInteger('ReferenceTriangleColor')
+ else
+ ReferenceTriangleColor := $7f7f7f;
+ if Registry.ValueExists('FlipColor') then
+ FlipColor := Registry.ReadInteger('FlipColor')
+ else
+ FlipColor := $808080;
+ if Registry.ValueExists('ExtendedEdit') then
+ ExtEditEnabled := Registry.ReadBool('ExtendedEdit')
+ else ExtEditEnabled := true;
+ if Registry.ValueExists('LockTransformAxis') then
+ TransformAxisLock := Registry.ReadBool('LockTransformAxis')
+ else TransformAxisLock := true;
+ if Registry.ValueExists('RebuildXaosLinks') then
+ RebuildXaosLinks := Registry.ReadBool('RebuildXaosLinks')
+ else RebuildXaosLinks := true;
+ end
+ else begin
+ UseTransformColors := false;
+ HelpersEnabled := true;
+ ShowAllXforms := true;
+ EnableEditorPreview := false;
+ EditorPreviewTransparency := 192;
+ EditorBkgColor := $000000;
+ GridColor1 := $444444;
+ GridColor2 := $333333;
+ HelpersColor := $808080;
+ FlipColor := $808080;
+ ReferenceTriangleColor := integer(clGray);
+ ExtEditEnabled := true;
+ TransformAxisLock := true;
+ RebuildXaosLinks := true;
+ AllowResetCoefs := false; // AV
+ AllowResetLinear := true; // AV
+ UseTriangleSync := false; // AV
+ end;
+ Registry.CloseKey;
+
+ { Render }
+ if Registry.OpenKey('Software\' + APP_NAME + '\Render', False) then
+ begin
+ if Registry.ValueExists('Path') then
+ RenderPath := Registry.ReadString('Path')
+ else
+ RenderPath := DefaultPath;
+
+ if Registry.ValueExists('SampleDensity') then
+ renderDensity := Registry.ReadFloat('SampleDensity')
+ else
+ renderDensity := 200;
+
+ if Registry.ValueExists('FilterRadius') then
+ renderFilterRadius := Registry.ReadFloat('FilterRadius')
+ else
+ renderFilterRadius := 0.4;
+
+ if Registry.ValueExists('Oversample') then
+ renderOversample := Registry.ReadInteger('Oversample')
+ else
+ renderOversample := 2;
+
+ if Registry.ValueExists('Width') then
+ renderWidth := Registry.ReadInteger('Width')
+ else
+ renderWidth := 1024;
+
+ if Registry.ValueExists('Height') then
+ renderHeight := Registry.ReadInteger('Height')
+ else
+ renderHeight := 768;
+
+ if Registry.ValueExists('JPEGQuality') then
+ JPEGQuality := Registry.ReadInteger('JPEGQuality')
+ else
+ JPEGQuality := 100;
+
+ if Registry.ValueExists('FileFormat') then
+ renderFileFormat := Registry.ReadInteger('FileFormat')
+ else
+ renderFileFormat := 3;
+
+ if Registry.ValueExists('EmbedFlame') then // AV
+ EmbedFlame := Registry.ReadBool('EmbedFlame')
+ else
+ EmbedFlame := True;
+ if Registry.ValueExists('SaveInFlame') then // AV
+ SaveInFlame := Registry.ReadBool('SaveInFlame')
+ else
+ SaveInFlame := True;
+ {
+ if Registry.ValueExists('BitsPerSample') then
+ renderBitsPerSample := Registry.ReadInteger('BitsPerSample')
+ else
+ renderBitsPerSample := 0;
+
+ if Registry.ValueExists('StoreEXIF') then begin
+ StoreEXIF := Registry.ReadBool('StoreEXIF');
+ end else begin
+ StoreEXIF := false;
+ end;
+ if Registry.ValueExists('StoreParamsEXIF') then begin
+ StoreParamsEXIF := Registry.ReadBool('StoreParamsEXIF');
+ end else begin
+ StoreParamsEXIF := false;
+ end;
+ if Registry.ValueExists('ExifAuthor') then begin
+ ExifAuthor := Registry.ReadString('ExifAuthor');
+ end else begin
+ ExifAuthor := '';
+ end;
+ }
+ end
+ else
+ begin
+ renderFileFormat := 2;
+ JPEGQuality := 100;
+ renderPath := DefaultPath;
+ renderDensity := 200;
+ renderOversample := 2;
+ renderFilterRadius := 0.4;
+ renderWidth := 1024;
+ renderHeight := 768;
+ EmbedFlame := True; // AV
+ SaveInFlame := True; // AV
+ {
+ renderBitsPerSample := 0;
+ StoreEXIF := false;
+ ExifAuthor := '';
+ StoreParamsEXIF := false;
+ }
+ end;
+ Registry.CloseKey;
+
+ {UPR}
+ if Registry.OpenKey('Software\' + APP_NAME + '\UPR', False) then
+ begin
+ if Registry.ValueExists('FlameColoringFile') then
+ UPRColoringFile := Registry.ReadString('FlameColoringFile')
+ else
+ UPRColoringFile := 'apophysis.ucl';
+
+ if Registry.ValueExists('FlameColoringIdent') then
+ UPRColoringIdent := Registry.ReadString('FlameColoringIdent')
+ else
+ UPRColoringIdent := 'apophysis-205'; // AV: fixed
+
+ if Registry.ValueExists('FlameFormulaFile') then
+ UPRFormulaFile := Registry.ReadString('FlameFormulaFile')
+ else
+ UPRFormulaFile := 'mt.ufm';
+ if Registry.ValueExists('FlameFormulaIdent') then
+ UPRFormulaIdent := Registry.ReadString('FlameFormulaIdent')
+ else
+ UPRFormulaIdent := 'mt-pixel';
+
+ if Registry.ValueExists('FlameIterDensity') then
+ UPRSampleDensity := Registry.ReadInteger('FlameIterDensity')
+ else
+ UPRSampleDensity := 35;
+ if Registry.ValueExists('FlameFilterRadius') then
+ UPRFilterRadius := Registry.ReadFloat('FlameFilterRadius')
+ else
+ UPRFilterRadius := 0.7;
+ if Registry.ValueExists('FlameOversample') then
+ UPROversample := Registry.ReadInteger('FlameOversample')
+ else
+ UPROversample := 3;
+ if Registry.ValueExists('FlameAdjustDensity') then
+ UPRAdjustDensity := Registry.ReadBool('FlameAdjustDensity')
+ else
+ UPRAdjustDensity := true;
+ end
+ else
+ begin
+ UPRColoringFile := 'apophysis.ucl';
+ UPRColoringIdent := 'apophysis-205';
+ UPRFormulaFile := 'mt.ufm';
+ UPRFormulaIdent := 'mt-pixel';
+ UPRSampleDensity := 35;
+ UPRFilterRadius := 0.7;
+ UPROversample := 3;
+ UPRAdjustDensity := True; ;
+ end;
+ Registry.CloseKey;
+
+ if Registry.OpenKey('Software\' + APP_NAME + '\Display', False) then
+ begin
+ if Registry.ValueExists('SampleDensity') then
+ defSampleDensity := Registry.ReadFloat('SampleDensity')
+ else
+ defSampleDensity := 5;
+ if Registry.ValueExists('Gamma') then
+ defGamma := Registry.ReadFloat('Gamma')
+ else
+ defGamma := 4;
+ if Registry.ValueExists('Brightness') then
+ defBrightness := Registry.ReadFloat('Brightness')
+ else
+ defBrightness := 4;
+ if Registry.ValueExists('Contrast') then // AV
+ defContrast := Registry.ReadFloat('Contrast')
+ else
+ defContrast := 1; // AV
+ if Registry.ValueExists('Vibrancy') then
+ defVibrancy := Registry.ReadFloat('Vibrancy')
+ else
+ defVibrancy := 1;
+ if Registry.ValueExists('FilterRadius') then
+ defFilterRadius := Registry.ReadFloat('FilterRadius')
+ else
+ defFilterRadius := 0.2;
+ if Registry.ValueExists('GammaThreshold') then
+ defGammaThreshold := Registry.ReadFloat('GammaThreshold')
+ else
+ defGammaThreshold := 0.01;
+ if Registry.ValueExists('Oversample') then
+ defOversample := Registry.ReadInteger('Oversample')
+ else
+ defOversample := 1;
+ if Registry.ValueExists('Fuse') then // AV
+ Fuse := Registry.ReadInteger('Fuse')
+ else
+ Fuse := 15;
+
+ if Registry.ValueExists('RhombicTileRadius') then // AV
+ RhombTR := Registry.ReadFloat('RhombicTileRadius')
+ else
+ RhombTR := 1;
+ if Registry.ValueExists('SquareTileRadius') then // AV
+ SquareTR := Registry.ReadFloat('SquareTileRadius')
+ else
+ SquareTR := 1.414214; //Round6(sqrt(2));
+ if Registry.ValueExists('HexagonalTileRadius') then // AV
+ HexTR := Registry.ReadFloat('HexagonalTileRadius')
+ else
+ HexTR := 2;
+
+ if Registry.ValueExists('PreviewLowQuality') then
+ prevLowQuality := Registry.ReadFloat('PreviewLowQuality')
+ else
+ prevLowQuality := 0.1;
+ if Registry.ValueExists('PreviewMediumQuality') then
+ prevMediumQuality := Registry.ReadFloat('PreviewMediumQuality')
+ else
+ prevMediumQuality := 1;
+ if Registry.ValueExists('PreviewHighQuality') then
+ prevHighQuality := Registry.ReadFloat('PreviewHighQuality')
+ else
+ prevHighQuality := 5;
+ end
+ else
+ begin
+ defSampleDensity := 5;
+ defGamma := 4;
+ defBrightness := 4;
+ defVibrancy := 1;
+ defContrast := 1; // AV
+ defFilterRadius := 0.2;
+ defOversample := 1;
+ defGammaThreshold := 0.01;
+ prevLowQuality := 0.1;
+ prevMediumQuality := 1;
+ prevHighQuality := 5;
+ Fuse := 15;
+ RhombTR := 1;
+ HexTR := 2;
+ SquareTR := 1.414214; //Round6(sqrt(2));
+ end;
+ Registry.CloseKey;
+
+ if Registry.OpenKey('Software\' + APP_NAME + '\Autosave', False) then
+ begin
+ if Registry.ValueExists('AutoSaveEnabled') then
+ AutoSaveEnabled := Registry.ReadBool('AutoSaveEnabled')
+ else
+ AutoSaveEnabled := false;
+
+ if Registry.ValueExists('AutoSaveFreq') then
+ AutoSaveFreq := Registry.ReadInteger('AutoSaveFreq')
+ else
+ AutoSaveFreq := 2;
+
+ if Registry.ValueExists('AutoSavePath') then
+ AutoSavePath := Registry.ReadString('AutoSavePath')
+ else
+ AutoSavePath := DefaultPath + 'autosave.flame';
+ end else begin
+ AutoSaveEnabled := false;
+ AutoSaveFreq := 2;
+ AutoSavePath := DefaultPath + 'autosave.flame';
+ end;
+ Registry.CloseKey;
+ finally
+ Registry.Free;
+ end;
+
+ PluginPath := ReadPluginDir;
+
+ // AV: create a folder for Apophysis temp files
+ AppData := GetEnvVarValue('APPDATA') + '\Apophysis AV\';
+ if not DirectoryExists(AppData) then // AV
+ if not CreateDir(AppData) then AppData := AppPath;
+
+ UseX64IfPossible := CheckX64;
+end;
+
+procedure SaveSettings;
+var
+ Registry: TRegistry;
+ i: integer;
+ VarUsed: byte;
+
+ function VarState(const a, b: boolean): byte; inline;
+ begin
+ Result := 0;
+ if a and b then Exit(3)
+ else if a then Exit(1)
+ else if b then Exit(2);
+ end;
+
+begin
+ // SavePluginDir(PluginPath); // AV: moved into main procedure
+
+ Registry := TRegistry.Create;
+ try
+ Registry.RootKey := HKEY_CURRENT_USER;
+ { Defaults }
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Defaults', True) then
+ begin
+ // Registry.WriteBool('StartupCheckForUpdates', StartupCheckForUpdates);
+ Registry.WriteBool('AlwaysCreateBlankFlame', AlwaysCreateBlankFlame);
+ Registry.WriteString('GradientFile', GradientFile);
+ Registry.WriteString('PluginPath', PluginPath); // AV
+ Registry.WriteString('HelpPath', HelpPath);
+ Registry.WriteString('SmoothPaletteFile', SmoothPaletteFile);
+ Registry.WriteString('DefaultScript', defScriptFile); // AV
+ Registry.WriteBool('PlaySoundOnRenderComplete', PlaySoundOnRenderComplete);
+ Registry.WriteString('RenderCompleteSoundFile', RenderCompleteSoundFile);
+ Registry.WriteBool('AutoOpenLog', AutoOpenLog);
+ Registry.WriteBool('ClassicListMode', ClassicListMode);
+
+ Registry.WriteBool('WarnOnMissingPlugin', WarnOnMissingPlugin);
+ Registry.WriteBool('SetEnglishLayout', SetEngLayout);
+ Registry.WriteBool('RandomizeTemplates', RandomizeTemplates);
+ Registry.WriteBool('ConfirmClearScript', ConfirmClearScript);
+ Registry.WriteBool('ConfirmResetUndo', ConfirmResetUndo);
+ Registry.WriteBool('AutoSaveXML', AutoSaveXML);
+ Registry.WriteBool('ApplyFlatten', ApplyFlatten);
+ Registry.WriteString('LanguageFile', LanguageFile);
+ Registry.WriteString('LastOpenFile', LastOpenFile);
+ Registry.WriteInteger('LastOpenFileEntry', LastOpenFileEntry);
+ Registry.WriteBool('RememberLastOpenFile', RememberLastOpenFile);
+ Registry.WriteBool('UseSmallThumbnails', UseSmallThumbnails);
+ Registry.WriteInteger('LineCenterColor', LineCenterColor);
+ Registry.WriteInteger('LineThirdsColor', LineThirdsColor);
+ Registry.WriteInteger('LineGRColor', LineGRColor);
+ Registry.WriteBool('EnableGuides', EnableGuides);
+ Registry.WriteString('ChaoticaPath', ChaoticaPath);
+ //Registry.WriteBool('UseX64IfPossible', UseX64IfPossible);
+
+ Registry.WriteBool('ConfirmDelete', ConfirmDelete);
+ Registry.WriteBool('OldPaletteFormat', OldPaletteFormat);
+ Registry.WriteBool('ConfirmExit', ConfirmExit);
+ Registry.WriteInteger('NumTries', NumTries);
+ Registry.WriteInteger('TryLength', TryLength);
+ Registry.WriteInteger('MinTransforms', randMinTransforms);
+ Registry.WriteInteger('MaxTransforms', randMaxTransforms);
+ Registry.WriteInteger('MutationMinTransforms', mutantMinTransforms);
+ Registry.WriteInteger('MutationMaxTransforms', mutantMaxTransforms);
+ Registry.WriteInteger('RandomGradient', randGradient);
+ Registry.WriteString('ParameterFolder3D', ParamFolder);
+ Registry.WriteString('UPRPath', UPRPath);
+ Registry.WriteString('ImageFolder', ImageFolder);
+ Registry.WriteString('SavePath3D', SavePath);
+ Registry.WriteInteger('UPRWidth', UPRWidth);
+ Registry.WriteInteger('UPRHeight', UPRHeight);
+ Registry.WriteString('BrowserPath', BrowserPath);
+ Registry.WriteInteger('EditPreviewQaulity', EditPrevQual);
+ Registry.WriteInteger('MutatePreviewQaulity', MutatePrevQual);
+ Registry.WriteInteger('AdjustPreviewQaulity', AdjustPrevQual);
+ Registry.WriteInteger('ThumbPrevQuality', ThumbPrevQual); // AV
+ Registry.WriteInteger('AnimPrevQuality', AnimPrevQual); // AV
+ Registry.WriteString('RandomPrefix', RandomPrefix);
+ Registry.WriteString('RandomDate', RandomDate);
+ Registry.WriteInteger('RandomIndex', RandomIndex);
+ Registry.WriteString('DefaultFlameFile3D', defFlameFile);
+ Registry.WriteString('SmoothPalettePath', SmoothPalettePath);
+ Registry.WriteString('GradientFile', GradientFile);
+ Registry.WriteInteger('TryLength', TryLength);
+ Registry.WriteInteger('NumTries', NumTries);
+ Registry.WriteString('SmoothPaletteFile', defSmoothPaletteFile);
+ Registry.WriteInteger('SymmetryType', SymmetryType);
+ Registry.WriteInteger('SymmetryOrder', SymmetryOrder);
+ Registry.WriteInteger('SymmetryNVars', SymmetryNVars);
+ Registry.WriteInteger('RotationMode', MainForm_RotationMode);
+ Registry.WriteInteger('EnumerationMode', FlameEnumMode); // AV
+ Registry.WriteInteger('MinNodes', MinNodes);
+ Registry.WriteInteger('MinHue', MinHue);
+ Registry.WriteInteger('MinSat', MinSat);
+ Registry.WriteInteger('MinLum', MinLum);
+ Registry.WriteInteger('MaxNodes', MaxNodes);
+ Registry.WriteInteger('MaxHue', MaxHue);
+ Registry.WriteInteger('MaxSat', MaxSat);
+ Registry.WriteInteger('MaxLum', MaxLum);
+ Registry.WriteString('RandomGradientFile', randGradientFile);
+ Registry.WriteInteger('ColorBlendType', randColorBlend); //AV
+ Registry.WriteBool('EqualStripes', EqualStripes); // AV
+ Registry.WriteInteger('BatchSize', BatchSize);
+ Registry.WriteString('ScriptPath', ScriptPath);
+ Registry.WriteInteger('ExportFileFormat', ExportFileFormat);
+ Registry.WriteInteger('ExportWidth', ExportWidth);
+ Registry.WriteInteger('ExportHeight', ExportHeight);
+ Registry.WriteFloat('ExportDensity', ExportDensity);
+ Registry.WriteFloat('ExportFilter', ExportFilter);
+ Registry.WriteInteger('ExportOversample', ExportOversample);
+ (*
+ Registry.WriteInteger('ExportBatches', ExportBatches);
+ Registry.WriteString('Nick', SheepNick);
+ Registry.WriteString('URL', SheepURL);
+ Registry.WriteString('Server', SheepServer);
+ Registry.WriteString('Pass', SheepPW);
+ *)
+ Registry.WriteString('Renderer', flam3Path);
+ Registry.WriteBool('ShowProgress', ShowProgress);
+ Registry.WriteBool('KeepBackground', KeepBackground);
+ Registry.WriteInteger('RandBackColor', RandBackColor);
+ Registry.WriteBool('PreserveQuality', PreserveQuality);
+ Registry.WriteString('FunctionLibrary', defLibrary);
+ Registry.WriteString('ScreenshotsFolder', ScreenShotPath); // AV
+
+ Registry.WriteBool('ShowTransparency', ShowTransparency);
+ Registry.WriteInteger('PNGTransparency', PNGTransparency);
+ Registry.WriteBool('ExtendMainPreview', ExtendMainPreview);
+ Registry.WriteFloat('MainPreviewScale', MainPreviewScale);
+
+ Registry.WriteBool('SaveIncompleteRenders', SaveIncompleteRenders);
+ Registry.WriteBool('ShowRenderStats', ShowRenderStats);
+ Registry.WriteBool('ShowRenderImage', ShowRenderImage);
+ Registry.WriteBool('LowerRenderPriority', LowerRenderPriority);
+
+ // AV: for animation
+ Registry.WriteInteger('AnimFPS', AnimFPS);
+ Registry.WriteString('AnimPrefix', defAnimPrefix);
+ Registry.WriteInteger('FrameExt', defFrameExt);
+ Registry.WriteBool('CreateAnimFolder', CreateAnimFolder);
+
+ Registry.WriteInteger('NrTreads', NrTreads);
+ Registry.WriteInteger('UseNrThreads', UseNrThreads);
+ end;
+ Registry.CloseKey;
+
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Variations', True) then
+ begin
+ for i := 0 to NRVAR-1 do
+ begin
+ VarUsed := 0;
+ if Registry.ValueExists(Varnames(i)) then
+ begin
+ VarUsed := VarState(Variations[i], FavouriteVariations[i]);
+ if Registry.ReadInteger(Varnames(i)) = VarUsed then continue; //?
+ end;
+ Registry.WriteInteger(Varnames(i), VarUsed);
+ end;
+ end;
+ Registry.CloseKey;
+
+ { Editor }
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Editor', True) then
+ begin
+ Registry.WriteBool('UseTransformColors', UseTransformColors);
+ Registry.WriteBool('HelpersEnabled', HelpersEnabled);
+ Registry.WriteBool('ShowAllXforms', ShowAllXforms);
+ Registry.WriteBool('EnableEditorPreview', EnableEditorPreview);
+ Registry.WriteInteger('EditorPreviewTransparency', EditorPreviewTransparency);
+ Registry.WriteInteger('BackgroundColor', EditorBkgColor);
+ Registry.WriteInteger('GridColor1', GridColor1);
+ Registry.WriteInteger('GridColor2', GridColor2);
+ Registry.WriteInteger('HelpersColor', HelpersColor);
+ Registry.WriteInteger('FlipColor', FlipColor);
+ Registry.WriteInteger('ReferenceTriangleColor', ReferenceTriangleColor);
+ Registry.WriteBool('ExtendedEdit', ExtEditEnabled);
+ Registry.WriteBool('LockTransformAxis', TransformAxisLock);
+ Registry.WriteBool('RebuildXaosLinks', RebuildXaosLinks);
+ Registry.WriteBool('AllowResetCoefs', AllowResetCoefs); // AV
+ Registry.WriteBool('AllowResetLinear', AllowResetLinear); // AV
+ Registry.WriteBool('SyncTriangles', UseTriangleSync); // AV
+ end;
+ Registry.CloseKey;
+
+ { Display }
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Display', True) then
+ begin
+ Registry.WriteFloat('SampleDensity', defSampleDensity);
+ Registry.WriteFloat('Gamma', defGamma);
+ Registry.WriteFloat('Brightness', defBrightness);
+ Registry.WriteFloat('Contrast', defContrast);
+ Registry.WriteFloat('Vibrancy', defVibrancy);
+ Registry.WriteFloat('FilterRadius', defFilterRadius);
+ Registry.WriteInteger('Oversample', defOversample);
+ Registry.WriteInteger('Fuse', Fuse);
+ Registry.WriteFloat('GammaThreshold', defGammaThreshold);
+ Registry.WriteFloat('PreviewLowQuality', prevLowQuality);
+ Registry.WriteFloat('PreviewMediumQuality', prevMediumQuality);
+ Registry.WriteFloat('PreviewHighQuality', prevHighQuality);
+ Registry.WriteFloat('HexagonalTileRadius', HexTR);
+ Registry.WriteFloat('SquareTileRadius', SquareTR);
+ Registry.WriteFloat('RhombicTileRadius', RhombTR);
+ end;
+ Registry.CloseKey;
+
+ { UPR }
+ if Registry.OpenKey('\Software\' + APP_NAME + '\UPR', True) then
+ begin
+ Registry.WriteString('FlameColoringFile', UPRColoringFile);
+ Registry.WriteString('FlameColoringIdent', UPRColoringIdent);
+ Registry.WriteString('FlameFormulaFile', UPRFormulaFile);
+ Registry.WriteString('FlameFormulaIdent', UPRFormulaIdent);
+ Registry.WriteInteger('FlameIterDensity', UPRSampleDensity);
+ Registry.WriteFloat('FlameFilterRadius', UPRFilterRadius);
+ Registry.WriteInteger('FlameOversample', UPROversample);
+ Registry.WriteBool('FlameAdjustDensity', UPRAdjustDensity);
+ end;
+ Registry.CloseKey;
+
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Render', True) then
+ begin
+ Registry.WriteString('Path', renderPath);
+ Registry.WriteFloat('SampleDensity', renderDensity);
+ Registry.WriteInteger('Oversample', renderOversample);
+ Registry.WriteFloat('FilterRadius', renderFilterRadius);
+ Registry.WriteInteger('Width', renderWidth);
+ Registry.WriteInteger('Height', renderHeight);
+ Registry.WriteInteger('JPEGQuality', JPEGQuality);
+ Registry.WriteInteger('FileFormat', renderFileFormat);
+ Registry.WriteBool('EmbedFlame', EmbedFlame); // AV
+ Registry.WriteBool('SaveInFlame', SaveInFlame); // AV
+ {
+ Registry.WriteBool('StoreEXIF', StoreEXIF);
+ Registry.WriteBool('StoreParamsEXIF', StoreParamsEXIF);
+ Registry.WriteString('ExifAuthor', ExifAuthor);
+ }
+ end;
+ Registry.CloseKey;
+
+ if Registry.OpenKey('\Software\' + APP_NAME + '\Autosave', True) then
+ begin
+ Registry.WriteBool('AutoSaveEnabled', AutoSaveEnabled);
+ Registry.WriteInteger('AutoSaveFreq', AutoSaveFreq);
+ Registry.WriteString('AutoSavePath', AutoSavePath);
+ end;
+ Registry.CloseKey;
+ finally
+ Registry.Free;
+ end;
+end;
+
+end.
+
diff --git a/Rendering/BucketFillerThread.pas b/Rendering/BucketFillerThread.pas
index 308a177..ea4e4ac 100644
--- a/Rendering/BucketFillerThread.pas
+++ b/Rendering/BucketFillerThread.pas
@@ -5,6 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -26,7 +27,7 @@ unit BucketFillerThread;
interface
uses
- Classes, Windows, ControlPoint, RenderingInterface, XForm;
+ Classes, Windows, ControlPoint;
type
TBucketFillerThread = class(TThread)
@@ -39,7 +40,7 @@ type
nrbatches: integer;
batchcounter: Pinteger;
- ColorMap: TColorMapArray;
+ //ColorMap: TColorMapArray;
CriticalSection: TRTLCriticalSection;
AddPointsProc: procedure (const points: TPointsArray) of object;
@@ -53,8 +54,6 @@ type
implementation
-//uses SysUtils, FormRender;
-
///////////////////////////////////////////////////////////////////////////////
constructor TBucketFillerThread.Create(cp: TControlPoint);
begin
diff --git a/Rendering/ImageMaker.pas b/Rendering/ImageMaker.pas
index edd0285..7291094 100644
--- a/Rendering/ImageMaker.pas
+++ b/Rendering/ImageMaker.pas
@@ -27,7 +27,7 @@ unit ImageMaker;
interface
uses
- Windows, Graphics, ControlPoint, RenderingCommon, PngImage, Bezier;
+ Windows, Graphics, ControlPoint, RenderingCommon, Vcl.Imaging.PngImage, Bezier;
type TPalette = record
logpal : TLogPalette;
@@ -97,7 +97,7 @@ type
implementation
uses
- Math, SysUtils, JPEG, Global, Types;
+ Math, SysUtils, Vcl.Imaging.JPEG, Global, Types;
{ TImageMaker }
@@ -108,12 +108,11 @@ type
red: byte;
end;
+ // AV: specific types used only for transparency
PByteArray = ^TByteArray;
- TByteArray = array[0..0] of byte;
-// PLongintArray = ^TLongintArray;
-// TLongintArray = array[0..0] of Longint;
+ TByteArray = array[0..0] of byte; // AV: single-element array?! why not [word] instead [0..0]?!
PRGBArray = ^TRGBArray;
- TRGBArray = array[0..0] of TRGB;
+ TRGBArray = array[0..0] of TRGB; // AV: single-element array?! why not [word] instead [0..0]?!
///////////////////////////////////////////////////////////////////////////////
constructor TImageMaker.Create;
@@ -394,7 +393,6 @@ var
f_select : double;
f_select_int, f_coef_idx : integer;
arr_filt_width : integer;
- c : array of double;
ss : integer;
scf:boolean;
scfact : double;
@@ -407,7 +405,6 @@ var
bx, by: integer;
label zero_alpha;
begin
- SetLength(c, 4);
if fcp.gamma = 0 then
gamma := fcp.gamma
@@ -716,7 +713,7 @@ end;
procedure TImageMaker.SaveImage(FileName: String);
var
i,row: integer;
- PngObject: TPngObject;
+ PngObject: TPNGImage;
rowbm, rowpng: PByteArray;
JPEGImage: TJPEGImage;
PNGerror: boolean;
@@ -725,7 +722,7 @@ begin
if UpperCase(ExtractFileExt(FileName)) = '.PNG' then begin
pngError := false;
- PngObject := TPngObject.Create;
+ PngObject := TPNGImage.Create;
try
PngObject.Assign(FBitmap);
if fcp.Transparency then // PNGTransparency <> 0
diff --git a/Rendering/RenderThread.pas b/Rendering/RenderThread.pas
index 8d5871c..f61a85d 100644
--- a/Rendering/RenderThread.pas
+++ b/Rendering/RenderThread.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
diff --git a/Rendering/RenderingCommon.pas b/Rendering/RenderingCommon.pas
index 5522c03..0867551 100644
--- a/Rendering/RenderingCommon.pas
+++ b/Rendering/RenderingCommon.pas
@@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
- ``Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
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
@@ -28,7 +28,7 @@ type
TOnFinish = procedure of object;
TOnProgress = procedure(prog: double) of object;
- {$ifdef Apo7X64}
+ {$ifdef CPUX64}
TBucket = Record
Red,
Green,
@@ -55,6 +55,7 @@ type
procedure TrimWorkingSet;
implementation
+
uses Windows;
procedure TrimWorkingSet;
diff --git a/Rendering/RenderingImplementation.pas b/Rendering/RenderingImplementation.pas
index 65d7659..b032dae 100644
--- a/Rendering/RenderingImplementation.pas
+++ b/Rendering/RenderingImplementation.pas
@@ -23,16 +23,14 @@
}
unit RenderingImplementation;
-{$ifdef Apo7X64}
-{$else}
+{$ifndef CPUX64}
{$define _ASM_}
{$endif}
interface
uses
-{$ifndef _ASM_}
-{$else}
+{$ifdef _ASM_}
AsmRandom,
{$endif}
Windows, Classes, Forms, Graphics, Global,
diff --git a/Rendering/RenderingInterface.pas b/Rendering/RenderingInterface.pas
index 1d06a5b..a66fb03 100644
--- a/Rendering/RenderingInterface.pas
+++ b/Rendering/RenderingInterface.pas
@@ -26,8 +26,8 @@ unit RenderingInterface;
interface
uses
- Windows, Graphics, Classes, RenderingCommon,
- Controlpoint, ImageMaker, PngImage, Translation;
+ Windows, Graphics, Classes, RenderingCommon, ImageMaker,
+ ControlPoint, Vcl.Imaging.PngImage, Translation;
///////////////////////////////////////////////////////////////////////////////
//
@@ -51,7 +51,7 @@ type
Green,
Blue:
- {$ifdef Apo7X64}
+ {$ifdef CPUX64}
double
{$else}
single
@@ -71,9 +71,6 @@ type
const
MAX_FILTER_WIDTH = 25;
-//const
- //SizeOfBucket: array[0..3] of byte = (32, 32, 32, 32);
-
function TimeToString(t: TDateTime): string;
type
@@ -296,9 +293,7 @@ type
implementation
uses
- Math, SysUtils, Forms,
- RenderingImplementation,
- Binary, Global;
+ Math, SysUtils, Forms, RenderingImplementation, Binary, Global;
///////////////////////////////////////////////////////////////////////////////
//
@@ -309,6 +304,7 @@ procedure TBaseRenderer.Hibernate(filePath: string);
begin
// todo
end;
+
procedure TBaseRenderer.Resume(filePath: string);
begin
// todo
@@ -344,10 +340,11 @@ begin
// entered memory - imagesize
MaxMemory := FMaxMem * 1024 * 1024 - 4 * image_Height * int64(image_Width);
- if (SingleBuffer) then
- ApproxMemory := 16 * sqr(oversample) * image_Height * int64(image_Width)
- else
- ApproxMemory := 32 * sqr(oversample) * image_Height * int64(image_Width);
+ {$ifdef CPUX86}
+ ApproxMemory := 16 * sqr(oversample) * image_Height * int64(image_Width);
+ {$else}
+ ApproxMemory := 32 * sqr(oversample) * image_Height * int64(image_Width);
+ {$endif}
assert(MaxMemory > 0);
if MaxMemory <= 0 then exit;
@@ -816,10 +813,12 @@ begin
try
// FStop := 0;
// TrimWorkingSet;
- if SingleBuffer then
- TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 16 / 1048576]))
- else
- TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 32 / 1048576]));
+
+ {$ifdef CPUX86}
+ TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 16 / 1048576]));
+ {$else}
+ TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 32 / 1048576]));
+ {$endif}
AllocateBuckets;
diff --git a/System/CurvesControl.pas b/System/CurvesControl.pas
index 9947a44..ecf43e9 100644
--- a/System/CurvesControl.pas
+++ b/System/CurvesControl.pas
@@ -3,15 +3,9 @@ unit CurvesControl;
interface
uses
- Windows, Messages, SysUtils, Variants, Classes, Math, ControlPoint,
+ Windows, SysUtils, Classes, Math, ControlPoint,
Graphics, Controls, Forms, Bezier, CustomDrawControl, Vcl.ExtCtrls;
-const
- point_size: double = 8;
- accurancy: double = 3;
- channel_count: integer = 4;
- padding = 3;
-
const
MAX_CHANNEL = 3;
@@ -73,6 +67,9 @@ implementation
uses Main, Editor, Mutate, Adjust;
+const
+ point_size: double = 8;
+
constructor TCurvesControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
@@ -94,6 +91,7 @@ begin
FrameCreate;
end;
+
destructor TCurvesControl.Destroy;
begin
FCP.Destroy;
@@ -101,7 +99,7 @@ begin
end;
procedure TCurvesControl.SetCp(cp: TControlPoint);
-var i, j: integer;
+var i, j: smallint;
begin
FCP.Copy(cp, true);
for i := 0 to 3 do
@@ -113,6 +111,7 @@ begin
Invalidate;
FFrame.Invalidate;
end;
+
procedure TCurvesControl.UpdateFlame;
begin
MainForm.StopThread;
@@ -130,6 +129,7 @@ procedure TCurvesControl.FrameMouseLeave(Sender: TObject);
begin
FrameMouseUp(nil, mbLeft, [], 0, 0);
end;
+
procedure TCurvesControl.FrameMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ps_half: double;
@@ -152,12 +152,12 @@ begin
Break;
end;
end;
+
procedure TCurvesControl.FrameMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
m: BezierPoints;
tmp: BezierPoint;
- i: Integer;
- j: Integer;
+ i, j: shortint;
begin
if (y < 0) then Exit;
@@ -194,10 +194,10 @@ begin
FCP.curvePoints[i,j].y := FPoints[i,j].y;
end;
-
FFrame.Refresh;
end;
end;
+
procedure TCurvesControl.FrameMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FDragIndex := -1;
@@ -207,9 +207,9 @@ begin
end;
procedure TCurvesControl.FrameCreate;
-var i: integer;
+var i: shortint;
begin
- for i := 0 to channel_count - 1 do
+ for i := 0 to MAX_CHANNEL do
begin
FPoints[i][0].x := 0.00; FPoints[i][0].y := 0.00; FWeights[i][0] := 1;
FPoints[i][1].x := 0.00; FPoints[i][1].y := 0.00; FWeights[i][1] := 1;
@@ -220,12 +220,14 @@ begin
FDragIndex := -1;
FDragging := false;
end;
+
procedure TCurvesControl.FrameResize(Sender: TObject);
begin
FRect.x0 := 0; FRect.y0 := 0;
FRect.x1 := self.Width - 1;
FRect.y1 := self.Height - 1;
end;
+
procedure TCurvesControl.FramePaint(Sender: TObject);
var
clientRect: TRect;
@@ -261,7 +263,7 @@ begin
LineTo(Round(FRect.x1), Round(0.25 * y * FRect.y1));
end;
- for i := 0 to channel_count - 1 do begin
+ for i := 0 to MAX_CHANNEL do begin
for j := 0 to 3 do
wsum[i] := wsum[i] + FWeights[i][j];
for j := 0 to 3 do
@@ -282,9 +284,11 @@ begin
end;
procedure TCurvesControl.PaintCurve(Bitmap: TBitmap; c: integer; p: BezierPoints; w: BezierWeights; widgets: boolean);
+const
+ step = 0.001; // AV
var
pos0, pos1: BezierPoint;
- t, step: Double;
+ t: Double;
r, g, b: array [0 .. MAX_CHANNEL] of integer;
rgbv: integer;
begin
@@ -303,7 +307,6 @@ begin
rgbv := RGB(r[c], g[c], b[c]);
t := 0;
- step := 0.001;
BezierSolve(0, p, w, pos1);
pos0.x := 0; pos0.y := pos1.y;
@@ -332,18 +335,19 @@ begin
LineTo(Round(FRect.x1), Round(pos0.y));
if widgets then begin
+ t := point_size / 2.0; // AV
Brush.Color := rgbv;
Ellipse(
- Round(p[1].x - point_size / 2.0),
- Round(p[1].y - point_size / 2.0),
- Round(p[1].x + point_size / 2.0),
- Round(p[1].y + point_size / 2.0)
+ Round(p[1].x - t),
+ Round(p[1].y - t),
+ Round(p[1].x + t),
+ Round(p[1].y + t)
);
Ellipse(
- Round(p[2].x - point_size / 2.0),
- Round(p[2].y - point_size / 2.0),
- Round(p[2].x + point_size / 2.0),
- Round(p[2].y + point_size / 2.0)
+ Round(p[2].x - t),
+ Round(p[2].y - t),
+ Round(p[2].x + t),
+ Round(p[2].y + t)
);
end;
end;
@@ -355,12 +359,14 @@ begin
FChannelIndex := Integer(value);
FFrame.Refresh;
end;
+
procedure TCurvesControl.SetWeightLeft(value: double);
begin
FWeights[FChannelIndex][1] := value;
FCP.curveWeights[FChannelIndex][1] := value;
FFrame.Refresh;
end;
+
procedure TCurvesControl.SetWeightRight(value: double);
begin
FWeights[FChannelIndex][2] := value;
@@ -372,10 +378,12 @@ function TCurvesControl.GetChannel: TCurvesChannel;
begin
Result := FActiveChannel;
end;
+
function TCurvesControl.GetWeightLeft: double;
begin
Result := FWeights[FChannelIndex][1];
end;
+
function TCurvesControl.GetWeightRight: double;
begin
Result := FWeights[FChannelIndex][2];
diff --git a/System/CustomDrawControl.pas b/System/CustomDrawControl.pas
index d2b687f..dbf5dfe 100644
--- a/System/CustomDrawControl.pas
+++ b/System/CustomDrawControl.pas
@@ -5,6 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
diff --git a/System/MathExpressions.pas b/System/MathExpressions.pas
new file mode 100644
index 0000000..9647446
--- /dev/null
+++ b/System/MathExpressions.pas
@@ -0,0 +1,337 @@
+{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
+
+unit MathExpressions;
+
+interface
+
+uses
+ System.Rtti, System.SysUtils, System.Bindings.EvalProtocol,
+ System.Bindings.Evaluator, System.Bindings.EvalSys, System.Bindings.Methods;
+
+function CalculateExpression(const Expr: string): string;
+
+var
+ InDegrees: boolean;
+
+implementation
+
+uses
+ System.Math, Windows, Translation;
+
+var
+ LScope: IScope;
+
+function Sine: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IAValue: IValue;
+ ANum: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 1 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['Sin()', 1, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IAValue := Args[0];
+
+ try
+ ANum := IAValue.GetValue.AsExtended; // AV: check the parameter type
+ if InDegrees then // AV: translate the parameter into radians
+ ANum := DegToRad(ANum);
+ Exit(TValueWrapper.Create(RoundTo(sin(ANum), -6)));
+ except
+ MessageBox(0, PChar('Sin(): ' + TextByKey('formula-wrongdatatype')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function CoSine: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IAValue: IValue;
+ ANum: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 1 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['Cos()', 1, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IAValue := Args[0];
+
+ try
+ ANum := IAValue.GetValue.AsExtended;
+ if InDegrees then // AV: translate the parameter into radians
+ ANum := DegToRad(ANum);
+ Exit(TValueWrapper.Create(RoundTo(cos(ANum), -6)));
+ except
+ MessageBox(0, PChar('Cos(): ' + TextByKey('formula-wrongdatatype')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function ArcSine: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IAValue: IValue;
+ AValue: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 1 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['ArcSin()', 1, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IAValue := Args[0];
+
+ try
+ AValue := IAValue.GetValue.AsExtended;
+ if InRange(AValue, -1, 1) then
+ begin
+ AValue := arcsin(AValue);
+ if InDegrees then
+ AValue := RadToDeg(AValue);
+ Exit(TValueWrapper.Create(RoundTo(AValue, -6)));
+ end
+ else
+ MessageBox(0, PChar('ArcSin(): ' + TextByKey('formula-outofrange')),
+ 'Apophysis AV', 48);
+ except
+ MessageBox(0, PChar('ArcSin(): ' + TextByKey('formula-wrongdatatype')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function ArcCoSine: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IAValue: IValue;
+ AValue: Double;
+ begin
+ //AV: check the number of passed parameters
+ if Length(Args) <> 1 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['ArcCos()', 1, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IAValue := Args[0];
+
+ try
+ AValue := IAValue.GetValue.AsExtended;
+ if InRange(AValue, -1, 1) then
+ begin
+ AValue := arccos(AValue);
+ if InDegrees then
+ AValue := RadToDeg(AValue);
+ Exit(TValueWrapper.Create(RoundTo(AValue, -6)));
+ end
+ else
+ MessageBox(0, PChar('ArcCos(): ' + TextByKey('formula-outofrange')),
+ 'Apophysis AV', 48);
+ except
+ MessageBox(0, PChar('ArcCos(): ' + TextByKey('formula-wrongdatatype')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function ArcTangentYX: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IYValue, IXValue: IValue;
+ AValue: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 2 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['ArcTan2()', 2, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IYValue := Args[0];
+ IXValue := Args[1];
+
+ try
+ AValue := arctan2(IYValue.GetValue.AsExtended,
+ IXValue.GetValue.AsExtended);
+ if InDegrees then
+ AValue := RadToDeg(AValue);
+ Exit(TValueWrapper.Create(RoundTo(AValue, -6)));
+ except
+ MessageBox(0, PChar('ArcTan2(): ' + TextByKey('common-invalidformat')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function SquareRoot: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IAValue: IValue;
+ ANum: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 1 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['Sqrt()', 1, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IAValue := Args[0];
+
+ try
+ ANum := IAValue.GetValue.AsExtended;
+ if ANum >= 0 then
+ Exit(TValueWrapper.Create(RoundTo(sqrt(ANum), -6)))
+ else
+ MessageBox(0, PChar('Sqrt(): ' + TextByKey('formula-unsigned')),
+ 'Apophysis AV', 48);
+ except
+ MessageBox(0, PChar('Sqrt(): ' + TextByKey('formula-wrongdatatype')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function NatLog: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IAValue: IValue;
+ ANum: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 1 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['Ln()', 1, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IAValue := Args[0];
+
+ try
+ ANum := IAValue.GetValue.AsExtended;
+ if ANum > 0 then
+ Exit(TValueWrapper.Create(RoundTo(ln(ANum), -6)))
+ else
+ MessageBox(0, PChar('Ln(): ' + TextByKey('formula-unsigned')),
+ 'Apophysis AV', 48);
+ except
+ MessageBox(0, PChar('Ln(): ' + TextByKey('formula-wrongdatatype')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+function PowerXY: IInvokable;
+begin
+ Result := MakeInvokable(
+ function(Args: TArray): IValue
+ var
+ IYValue, IXValue: IValue;
+ ANum: Double;
+ begin
+ // AV: check the number of passed parameters
+ if Length(Args) <> 2 then begin
+ MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
+ ['Power()', 2, Length(Args)])), 'Apophysis AV', 48);
+ exit;
+ end;
+
+ IXValue := Args[0];
+ IYValue := Args[1];
+
+ try
+ ANum := IXValue.GetValue.AsExtended;
+ if ANum >= 0 then
+ Result := TValueWrapper.Create(RoundTo(power(ANum,
+ IYValue.GetValue.AsExtended), -6))
+ else
+ MessageBox(0, PChar('Power(): ' + TextByKey('formula-unsigned')),
+ 'Apophysis AV', 48);
+ except
+ MessageBox(0, PChar('Power(): ' + TextByKey('common-invalidformat')),
+ 'Apophysis AV', 16);
+ end;
+ end
+ );
+end;
+
+procedure RegisterMathFunctions;
+begin
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ Sine, 'sin', 'sin', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ CoSine, 'cos', 'cos', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ ArcSine, 'arcsin', 'arcsin', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ ArcCoSine, 'arccos', 'arccos', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ ArcTangentYX, 'arctan2', 'arctan2', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ SquareRoot, 'sqrt', 'sqrt', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ PowerXY, 'power', 'power', '', True, '', nil));
+ TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
+ NatLog, 'ln', 'ln', '', True, '', nil));
+
+ LScope := BasicOperators;
+ TDictionaryScope(LScope).Map.Add('pi', TValueWrapper.Create(pi));
+ TDictionaryScope(LScope).Map.Add('exp', TValueWrapper.Create(exp(1)));
+ // AV: add the registered methods
+ LScope := TNestedScope.Create(LScope, TBindingMethodsFactory.GetMethodScope);
+end;
+
+function CalculateExpression(const Expr: string): string;
+var
+ LCompiledExpr : ICompiledBinding;
+ LResult : TValue;
+begin
+ Result := '';
+
+ try
+ LCompiledExpr := Compile(Expr, LScope);
+ LResult := LCompiledExpr.Evaluate(LScope, nil, nil).GetValue;
+ if not LResult.IsEmpty then
+ Result := LResult.ToString;
+ except
+ Result := '';
+ MessageBox(0, PChar(TextByKey('formula-cannotevaluate')),
+ 'Apophysis AV', 16);
+ end;
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+initialization
+ RegisterMathFunctions;
+
+end.
diff --git a/System/RegexHelper.pas b/System/RegexHelper.pas
index c3279cd..d6f2686 100644
--- a/System/RegexHelper.pas
+++ b/System/RegexHelper.pas
@@ -33,27 +33,31 @@ begin
Regex.Subject := text;
if Regex.Match and (Regex.GroupCount >= group) then
- Result := String(Regex.Groups[group])
+ Result := Regex.Groups[group]
else Result := def;
Regex.Free;
end;
+
function GetBoolPart(text, expression: string; group: integer; def: boolean): boolean;
begin
Result := GetFloatPart(text, expression, group, StrToFloat(IfThen(def, '1', '0'))) <> 0;
end;
+
function GetIntPart(text, expression: string; group: integer; def: integer): integer;
var str: string;
begin
str := GetStringPart(text, expression, group, '');
Result := StrToIntDef(str, def);
end;
+
function GetFloatPart(text, expression: string; group: integer; def: extended): extended;
var str: string;
begin
str := GetStringPart(text, expression, group, '');
Result := StrToFloatDef(str, def);
end;
+
function Get2IntPart(text, expression: string; group: integer; def: integer): T2Int;
const expr : string = '(\d+)\s+(\d+)';
var str, s1, s2: string;
@@ -64,6 +68,7 @@ begin
Result.i1 := StrToIntDef(s1, def);
Result.i2 := StrToIntDef(s2, def);
end;
+
function Get2FloatPart(text, expression: string; group: integer; def: extended): T2Float;
const expr : string = '([\d.eE+-]+)\s+([\d.eE+-]+)';
var str, s1, s2: string;
@@ -74,6 +79,7 @@ begin
Result.f1 := StrToFloatDef(s1, def);
Result.f2 := StrToFloatDef(s2, def);
end;
+
function GetRGBPart(text, expression: string; group: integer; def: integer): TRGB;
const expr : string = '(\d+)\s+(\d+)\s+(\d+)';
var str, s1, s2, s3: string;
diff --git a/System/sdStringTable.pas b/System/sdStringTable.pas
deleted file mode 100644
index 1b31cca..0000000
--- a/System/sdStringTable.pas
+++ /dev/null
@@ -1,633 +0,0 @@
-{ unit sdStringTable
-
- Author: Nils Haeck M.Sc. (n.haeck@simdesign.nl)
- Original Date: 28 May 2007
- Version: 1.1
- Copyright (c) 2007 - 2010 Simdesign BV
-
- It is NOT allowed under ANY circumstances to publish or copy this code
- without accepting the license conditions in accompanying LICENSE.txt
- first!
-
- This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
- ANY KIND, either express or implied.
-
- Please visit http://www.simdesign.nl/xml.html for more information.
-}
-unit sdStringTable;
-
-interface
-
-{$i NativeXml.inc}
-
-uses
- Classes, SysUtils, Contnrs;
-
-type
-
- // A record describing a string by its first position and length (Count)
- TsdStringRec = record
- First: Pbyte;
- Count: integer;
- end;
-
- // A string reference item used in string reference lists (do not use directly)
- TsdRefString = class
- private
- FID: integer;
- FFrequency: integer;
- FFirst: Pbyte;
- FCharCount: integer;
- protected
- procedure SetString(const SR: TsdStringRec);
- function CompareToSR(const SR: TsdStringRec): integer;
- function StringRec: TsdStringRec;
- public
- destructor Destroy; override;
- function AsString: UTF8String;
- property CharCount: integer read FCharCount;
- property Frequency: integer read FFrequency;
- end;
-
- // A list of string reference items (do not use directly)
- TsdRefStringList = class(TObjectList)
- private
- function GetItems(Index: integer): TsdRefString;
- protected
- // Assumes list is sorted by StringID
- function IndexOfID(AID: integer; var Index: integer): boolean;
- // Assumes list is sorted by string rec
- function IndexOfSR(const AStringRec: TsdStringRec; var Index: integer): boolean;
- public
- property Items[Index: integer]: TsdRefString read GetItems; default;
- end;
-
- // A string table, holding a collection of unique strings, sorted in 2 ways
- // for fast access. Strings can be added with AddString or AddStringRec,
- // and should be updated with SetString. When a string is added or updated,
- // an ID is returned which the application can use to retrieve the string,
- // using GetString.
- TsdStringTable = class(TPersistent)
- private
- FByID: TsdRefStringList;
- FBySR: TsdRefStringList;
- protected
- procedure DecFrequency(AItem: TsdRefString; ByIdIndex: integer);
- function NextUniqueID: integer;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Clear;
- // Add a new string rec, return fresh ID or ID of existing item, and increase
- // the existing item's ref count
- function AddStringRec(const SR: TsdStringRec): integer;
- // Add a new string S to the table, the function returns its ID.
- function AddString(const S: UTF8String): integer;
- // Get the refstring by ID
- function ById(index: integer): TsdRefString;
- // Delete refstring by ID
- procedure Delete(ByIdIndex: integer);
- // determine if the stringrec exists
- function ExistStringRec(const SR: TsdStringRec): boolean;
- // Get the string of refstring with ID
- function GetString(ID: integer): UTF8String;
- // Set the string value of refstring with ID.
- procedure SetString(var ID: integer; const S: UTF8String);
- // Number of refstrings
- function StringCount: integer;
- procedure SaveToFile(const AFileName: string);
- procedure SaveToStream(S: TStream);
- end;
-
-{utility functions}
-
-// convert a string into a string rec
-function sdStringToSR(const S: Utf8String): TsdStringRec;
-
-// convert a string rec into a string
-function sdSRToString(const SR: TsdStringRec): Utf8String;
-
-// compare two string recs. This is NOT an alphabetic compare. SRs are first
-// compared by length, then by first byte, then last byte then second, then
-// N-1, until all bytes are compared.
-function sdCompareSR(const SR1, SR2: TsdStringRec): integer;
-
-// compare 2 bytes
-function sdCompareByte(Byte1, Byte2: byte): integer;
-
-// compare 2 integers
-function sdCompareInteger(Int1, Int2: integer): integer;
-
-function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer;
-function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer;
-procedure sdStreamWrite(S: TStream; const AString: AnsiString);
-procedure sdStreamWriteStringRec(S: TStream; const AStringRec: TsdStringRec);
-procedure sdStreamWriteRefString(S: TStream; ARefString: TsdRefString);
-
-implementation
-
-{ TsdRefString }
-
-function TsdRefString.AsString: UTF8String;
-begin
- Result := sdSRToString(StringRec);
-end;
-
-function TsdRefString.CompareToSR(const SR: TsdStringRec): integer;
-begin
- if SR.Count = 0 then
- begin
- // shortcut
- Result := 1;
- exit;
- end;
- Result := sdCompareSR(StringRec, SR);
-end;
-
-destructor TsdRefString.Destroy;
-begin
- FreeMem(FFirst);
- inherited;
-end;
-
-procedure TsdRefString.SetString(const SR: TsdStringRec);
-begin
- FCharCount := SR.Count;
- ReallocMem(FFirst, FCharCount);
- Move(SR.First^, FFirst^, FCharCount);
-end;
-
-function TsdRefString.StringRec: TsdStringRec;
-begin
- Result.First := FFirst;
- Result.Count := FCharCount;
-end;
-
-{ TsdRefStringList }
-
-function TsdRefStringList.GetItems(Index: integer): TsdRefString;
-begin
- Result := Get(Index);
-end;
-
-function TsdRefStringList.IndexOfID(AID: integer; var Index: integer): boolean;
-var
- Min, Max: integer;
-begin
- Result := False;
-
- // Find position - binary method
- Index := 0;
- Min := 0;
- Max := Count;
- while Min < Max do
- begin
- Index := (Min + Max) div 2;
- case sdCompareInteger(Items[Index].FID, AID) of
- -1: Min := Index + 1;
- 0: begin
- Result := True;
- exit;
- end;
- 1: Max := Index;
- end;
- end;
-
- Index := Min;
-end;
-
-function TsdRefStringList.IndexOfSR(const AStringRec: TsdStringRec; var Index: integer): boolean;
-var
- Min, Max: integer;
- SR: TsdStringRec;
-begin
- Result := False;
-
- // Find position - binary method
- Index := 0;
- Min := 0;
- Max := Count;
- while Min < Max do
- begin
- Index := (Min + Max) div 2;
- SR := TsdRefString(Get(Index)).StringRec;
- case sdCompareSR(SR, AStringRec) of
- -1: Min := Index + 1;
- 0: begin
- Result := True;
- exit;
- end;
- 1: Max := Index;
- end;
- end;
-
- Index := Min;
-end;
-
-{ TsdStringTable }
-
-function TsdStringTable.AddString(const S: UTF8String): integer;
-var
- SR: TsdStringRec;
-begin
- SR := sdStringToSR(S);
- Result := AddStringRec(SR);
-end;
-
-function TsdStringTable.AddStringRec(const SR: TsdStringRec): integer;
-var
- BySRIndex: integer;
- Item: TsdRefString;
- NewSR: TsdStringRec;
- Res: boolean;
-begin
- // zero-length string
- if SR.Count = 0 then
- begin
- Result := 0;
- exit;
- end;
-
- // Try to find the new string
- if FBySR.IndexOfSR(SR, BySRIndex) then
- begin
- Item := FBySR.Items[BySRIndex];
- inc(Item.FFrequency);
- Result := Item.FID;
- exit;
- end;
-
- // Not found.. must make new item
- Item := TsdRefString.Create;
- Item.SetString(SR);
- NewSR := Item.StringRec;
- Item.FID := NextUniqueID;
- FById.Add(Item);
- Item.FFrequency := 1;
-
- // debug:
- //SetLength(Item.FValue, Item.FCount);
- //Move(Item.FirstPtr(FBase)^, Item.FValue[1], Item.FCount);
-
- // Insert in BySR lists
- Res := FBySR.IndexOfSR(NewSR, BySRIndex);
- assert(Res = False);
- FBySR.Insert(BySRIndex, Item);
- Result := Item.FID;
-end;
-
-function TsdStringTable.ById(index: integer): TsdRefString;
-begin
- Result := FById[Index];
-end;
-
-procedure TsdStringTable.Clear;
-begin
- FByID.Clear;
- FBySR.Clear;
-end;
-
-constructor TsdStringTable.Create;
-begin
- inherited Create;
- FByID := TsdRefStringList.Create(False);
- FBySR := TsdRefStringList.Create(True);
-end;
-
-procedure TsdStringTable.DecFrequency(AItem: TsdRefString; ByIdIndex: integer);
-var
- BySRIndex: integer;
- Res: boolean;
-begin
- dec(AItem.FFrequency);
- assert(AItem.FFrequency >= 0);
-
- if AItem.FFrequency = 0 then
- begin
- // We must remove it
- FById.Delete(ByIdIndex);
- Res := FBySR.IndexOfSR(AItem.StringRec, BySRIndex);
- assert(Res = True);
- FBySR.Delete(BySRIndex);
- end;
-end;
-
-procedure TsdStringTable.Delete(ByIdIndex: integer);
-var
- Item: TsdRefString;
- BySRIndex: integer;
- Res: boolean;
-begin
- Item := FById[ByIdIndex];
- if Item = nil then
- exit;
- FById.Delete(ByIdIndex);
- Res := FBySR.IndexOfSR(Item.StringRec, BySRIndex);
- assert(Res = True);
- FBySR.Delete(BySRIndex);
-end;
-
-destructor TsdStringTable.Destroy;
-begin
- FreeAndNil(FByID);
- FreeAndNil(FBySR);
- inherited;
-end;
-
-function TsdStringTable.ExistStringRec(const SR: TsdStringRec): boolean;
-var
- BySRIndex: integer;
-begin
- // zero-length string
- if SR.Count = 0 then
- begin
- Result := False;
- exit;
- end;
-
- // Try to find the new string
- Result := FBySR.IndexOfSR(SR, BySRIndex);
-
-end;
-
-function TsdStringTable.GetString(ID: integer): UTF8String;
-var
- Index, Count: integer;
- Item: TsdRefString;
-begin
- if ID = 0 then
- begin
- Result := '';
- exit;
- end;
-
- // Find the ID
- if FByID.IndexOfID(ID, Index) then
- begin
- Item := FById[Index];
- Count := Item.FCharCount;
- SetLength(Result, Count);
- Move(Item.FFirst^, Result[1], Count);
- exit;
- end;
-
- Result := '';
-end;
-
-function TsdStringTable.NextUniqueID: integer;
-begin
- if FById.Count = 0 then
- Result := 1
- else
- Result := FByID[FByID.Count - 1].FID + 1;
-end;
-
-procedure TsdStringTable.SaveToFile(const AFileName: string);
-var
- F: TFileStream;
-begin
- F := TFileStream.Create(AFileName, fmCreate);
- try
- SaveToStream(F);
- finally
- F.Free;
- end;
-end;
-
-procedure TsdStringTable.SaveToStream(S: TStream);
-var
- i: integer;
- R: UTF8String;
-begin
- for i := 0 to FBySR.Count - 1 do
- begin
- R := FBySR[i].AsString + #13#10;
- S.Write(R[1], length(R));
- end;
-end;
-
-procedure TsdStringTable.SetString(var ID: integer; const S: UTF8String);
-var
- ByIdIndex: integer;
- Item: TsdRefString;
- SR: TsdStringRec;
-begin
- // Make temp string record
- SR := sdStringtoSR(S);
-
- // Do we have a ref string with this ID?
- if (ID > 0) and FByID.IndexOfID(ID, ByIdIndex) then
- begin
- // Is the string still the same?
- Item := FById[ByIdIndex];
- if Item.CompareToSR(SR) = 0 then
- exit;
- // The string changed..
- DecFrequency(Item, ByIdIndex);
- end;
-
- ID := AddStringRec(SR);
-end;
-
-{utility functions}
-
-function TsdStringTable.StringCount: integer;
-begin
- Result := FBySR.Count;
-end;
-
-function sdStringToSR(const S: UTF8String): TsdStringRec;
-begin
- Result.Count := length(S);
- if Result.Count = 0 then
- Result.First := nil
- else
- Result.First := @S[1];
-end;
-
-function sdSRToString(const SR: TsdStringRec): UTF8String;
-begin
- SetLength(Result, SR.Count);
- if SR.Count > 0 then
- Move(SR.First^, Result[1], SR.Count);
-end;
-
-function sdCompareByte(Byte1, Byte2: byte): integer;
-begin
- if Byte1 < Byte2 then
- Result := -1
- else
- if Byte1 > Byte2 then
- Result := 1
- else
- Result := 0;
-end;
-
-function sdCompareInteger(Int1, Int2: integer): integer;
-begin
- if Int1 < Int2 then
- Result := -1
- else
- if Int1 > Int2 then
- Result := 1
- else
- Result := 0;
-end;
-
-function sdCompareSR(const SR1, SR2: TsdStringRec): integer;
-var
- Count: integer;
- First1, First2, Last1, Last2: Pbyte;
-begin
- // Compare string length first
- Result := sdCompareInteger(SR1.Count, SR2.Count);
- if Result <> 0 then
- exit;
-
- // Compare first
- Result := sdCompareByte(SR1.First^, SR2.First^);
- if Result <> 0 then
- exit;
- Count := SR1.Count;
-
- // Setup First & Last pointers
- First1 := SR1.First;
- First2 := SR2.First;
- Last1 := First1; inc(Last1, Count);
- Last2 := First2; inc(Last2, Count);
-
- // Compare each time last ptrs then first ptrs, until they meet in the middle
- repeat
- dec(Last1);
- dec(Last2);
- if First1 = Last1 then
- exit;
- Result := sdCompareByte(Last1^, Last2^);
- if Result <> 0 then
- exit;
- inc(First1); inc(First2);
- if First1 = Last1 then
- exit;
- Result := sdCompareByte(First1^, First2^);
- if Result <> 0 then
- exit;
- until False;
-end;
-
-function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer;
-// Convert an Unicode (UTF16 LE) memory block to UTF8. This routine will process
-// Count wide characters (2 bytes size) to Count UTF8 characters (1-3 bytes).
-// Therefore, the block at Dst must be at least 1.5 the size of the source block.
-// The function returns the number of *bytes* written.
-var
- W: word;
- DStart: Pbyte;
-begin
- DStart := Dst;
- while Count > 0 do
- begin
- W := Src^;
- inc(Src);
- if W <= $7F then
- begin
- Dst^ := byte(W);
- inc(Dst);
- end else
- begin
- if W > $7FF then
- begin
- Dst^ := byte($E0 or (W shr 12));
- inc(Dst);
- Dst^ := byte($80 or ((W shr 6) and $3F));
- inc(Dst);
- Dst^ := byte($80 or (W and $3F));
- inc(Dst);
- end else
- begin // $7F < W <= $7FF
- Dst^ := byte($C0 or (W shr 6));
- inc(Dst);
- Dst^ := byte($80 or (W and $3F));
- inc(Dst);
- end;
- end;
- dec(Count);
- end;
- Result := integer(Dst) - integer(DStart);
-end;
-
-function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer;
-// Convert an UTF8 memory block to Unicode (UTF16 LE). This routine will process
-// Count *bytes* of UTF8 (each character 1-3 bytes) into UTF16 (each char 2 bytes).
-// Therefore, the block at Dst must be at least 2 times the size of Count, since
-// many UTF8 characters consist of just one byte, and are mapped to 2 bytes. The
-// function returns the number of *wide chars* written. Note that the Src block must
-// have an exact number of UTF8 characters in it, if Count doesn't match then
-// the last character will be converted anyway (going past the block boundary!)
-var
- W: word;
- C: byte;
- DStart: Pword;
- SClose: Pbyte;
-begin
- DStart := Dst;
- SClose := Src;
- inc(SClose, Count);
- while integer(Src) < integer(SClose) do
- begin
- // 1st byte
- W := Src^;
- inc(Src);
- if W and $80 <> 0 then
- begin
- W := W and $3F;
- if W and $20 <> 0 then
- begin
- // 2nd byte
- C := Src^;
- inc(Src);
- if C and $C0 <> $80 then
- // malformed trail byte or out of range char
- Continue;
- W := (W shl 6) or (C and $3F);
- end;
- // 2nd or 3rd byte
- C := Src^;
- inc(Src);
- if C and $C0 <> $80 then
- // malformed trail byte
- Continue;
- Dst^ := (W shl 6) or (C and $3F);
- inc(Dst);
- end else
- begin
- Dst^ := W;
- inc(Dst);
- end;
- end;
- Result := (integer(Dst) - integer(DStart)) div 2;
-end;
-
-procedure sdStreamWrite(S: TStream; const AString: AnsiString);
-var
- L: integer;
-begin
- L := Length(AString);
- if L > 0 then
- begin
- S.Write(AString[1], L);
- end;
-end;
-
-procedure sdStreamWriteStringRec(S: TStream; const AStringRec: TsdStringRec);
-begin
- S.Write(PAnsiChar(AStringRec.First)^, AStringRec.Count);
-end;
-
-procedure sdStreamWriteRefString(S: TStream; ARefString: TsdRefString);
-begin
- if ARefString = nil then
- exit;
- S.Write(PAnsiChar(ARefString.FFirst)^, ARefString.FCharCount);
-end;
-
-end.
diff --git a/Variations/varAffine3D.pas b/Variations/varAffine3D.pas
index 763a2c8..f106ffa 100644
--- a/Variations/varAffine3D.pas
+++ b/Variations/varAffine3D.pas
@@ -10,13 +10,13 @@ uses
type
TVariationAffine3D = class(TBaseVariation)
private
- affine3D_a00, affine3D_a01, affine3D_a02,
- affine3D_a10, affine3D_a11, affine3D_a12,
- affine3D_a20, affine3D_a21, affine3D_a22,
- affine3D_bx, affine3D_by, affine3D_bz: double;
- x0, y0, z0: double;
+ affine3D_a00, affine3D_a01, affine3D_a02,
+ affine3D_a10, affine3D_a11, affine3D_a12,
+ affine3D_a20, affine3D_a21, affine3D_a22,
+ affine3D_bx, affine3D_by, affine3D_bz: double;
+ x0, y0, z0: double;
affine3D_mode: byte;
- procedure CalcPre;
+ procedure CalcPre;
procedure CalcPost;
public
constructor Create;
@@ -53,13 +53,13 @@ end;
procedure TVariationAffine3D.CalcPre;
var x, y, z, dn: double;
begin
- x := affine3D_a00 * FTx^ - affine3D_a01 * FTy^ + affine3D_a02 * FTz^ + affine3D_bx;
- y := -(affine3D_a10 * FTx^ - affine3D_a11 * FTy^ + affine3D_a12 * FTz^ + affine3D_by);
+ x := affine3D_a00 * FTx^ - affine3D_a01 * FTy^ + affine3D_a02 * FTz^ + affine3D_bx;
+ y := -(affine3D_a10 * FTx^ - affine3D_a11 * FTy^ + affine3D_a12 * FTz^ + affine3D_by);
z := affine3D_a20 * FTx^ - affine3D_a21 * FTy^ + affine3D_a22 * FTz^ + affine3D_bz;
FTx^ := VVAR * x;
- FTy^ := VVAR * y;
- FTz^ := VVAR * z;
+ FTy^ := VVAR * y;
+ FTz^ := VVAR * z;
dn := hypot(x - x0, y - y0, z - z0);
if (dn <> 0) then color^ := abs(cos(hypot(x - x0, y - y0) / dn))
@@ -70,13 +70,13 @@ procedure TVariationAffine3D.CalcFunction;
var x, y, z, dn: double;
begin
- x := affine3D_a00 * FTx^ - affine3D_a01 * FTy^ + affine3D_a02 * FTz^ + affine3D_bx;
- y := -(affine3D_a10 * FTx^ - affine3D_a11 * FTy^ + affine3D_a12 * FTz^ + affine3D_by);
+ x := affine3D_a00 * FTx^ - affine3D_a01 * FTy^ + affine3D_a02 * FTz^ + affine3D_bx;
+ y := -(affine3D_a10 * FTx^ - affine3D_a11 * FTy^ + affine3D_a12 * FTz^ + affine3D_by);
z := affine3D_a20 * FTx^ - affine3D_a21 * FTy^ + affine3D_a22 * FTz^ + affine3D_bz;
- FPx^ := FPx^ + VVAR * x;
- FPy^ := FPy^ + VVAR * y;
- FPz^ := FPz^ + VVAR * z;
+ FPx^ := FPx^ + VVAR * x;
+ FPy^ := FPy^ + VVAR * y;
+ FPz^ := FPz^ + VVAR * z;
dn := hypot(x - x0, y - y0, z - z0);
if (dn <> 0) then color^ := abs(cos(hypot(x - x0, y - y0) / dn))
@@ -87,13 +87,13 @@ procedure TVariationAffine3D.CalcPost;
var x, y, z, dn: double;
begin
- x := affine3D_a00 * FPx^ - affine3D_a01 * FPy^ + affine3D_a02 * FPz^ + affine3D_bx;
- y := -(affine3D_a10 * FPx^ - affine3D_a11 * FPy^ + affine3D_a12 * FPz^ + affine3D_by);
+ x := affine3D_a00 * FPx^ - affine3D_a01 * FPy^ + affine3D_a02 * FPz^ + affine3D_bx;
+ y := -(affine3D_a10 * FPx^ - affine3D_a11 * FPy^ + affine3D_a12 * FPz^ + affine3D_by);
z := affine3D_a20 * FPx^ - affine3D_a21 * FPy^ + affine3D_a22 * FPz^ + affine3D_bz;
- FPx^ := VVAR * x;
- FPy^ := VVAR * y;
- FPz^ := VVAR * z;
+ FPx^ := VVAR * x;
+ FPy^ := VVAR * y;
+ FPz^ := VVAR * z;
dn := hypot(x - x0, y - y0, z - z0);
if (dn <> 0) then color^ := abs(cos(hypot(x - x0, y - y0) / dn))
@@ -204,6 +204,7 @@ begin
Result := True;
end
end;
+
function TVariationAffine3D.ResetVariable(const Name: string): boolean;
begin
Result := False;
diff --git a/Variations/varCothSpiral.pas b/Variations/varCothSpiral.pas
index 53154b7..59d82bc 100644
--- a/Variations/varCothSpiral.pas
+++ b/Variations/varCothSpiral.pas
@@ -40,7 +40,7 @@ procedure TVariationCothSpiral.CalcFunction;
var
t, aux, sn, cn, snh, cnh: double;
begin
- t := (random - 0.5) * 6.28318530717959;
+ t := (random - 0.5) * PI2;
SinCos(ta * t, sn, cn);
SinhCosh(t, snh, cnh);
diff --git a/Variations/varCurl.pas b/Variations/varCurl.pas
index 08321da..a6e75ff 100644
--- a/Variations/varCurl.pas
+++ b/Variations/varCurl.pas
@@ -35,8 +35,7 @@ const
var_c1_name='curl_c1';
var_c2_name='curl_c2';
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varDisc2.pas b/Variations/varDisc2.pas
index 18d47c9..e8d859b 100644
--- a/Variations/varDisc2.pas
+++ b/Variations/varDisc2.pas
@@ -7,15 +7,14 @@ interface
uses
BaseVariation, XFormMan;
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
type
TVariationDisc2 = class(TBaseVariation)
private
- rot, add, c, k, sinadd, cosadd: double;
+ rot, add, p, k, sinadd, cosadd: double;
public
constructor Create;
@@ -49,7 +48,7 @@ end;
procedure TVariationDisc2.Prepare;
var t: double;
begin
- c := vvar / PI;
+ p := vvar / PI;
k := rot * PI;
SinCos(add, sinadd, cosadd);
cosadd := cosadd - 1;
@@ -73,7 +72,7 @@ var
r, sinr, cosr: extended;
begin
SinCos(k * (FTx^ + FTy^), sinr, cosr);
- r := c * arctan2(FTx^, FTy^);
+ r := p * arctan2(FTx^, FTy^);
FPx^ := FPx^ + (sinr + cosadd) * r;
FPy^ := FPy^ + (cosr + sinadd) * r;
{$else}
@@ -82,7 +81,7 @@ asm
fld qword ptr [edx]
fld qword ptr [edx + 8]
fpatan
- fmul qword ptr [eax + c]
+ fmul qword ptr [eax + p]
fld qword ptr [edx]
fadd qword ptr [edx + 8]
fmul qword ptr [eax + k]
diff --git a/Variations/varExponential.pas b/Variations/varExponential.pas
index 1565456..ffd3b0e 100644
--- a/Variations/varExponential.pas
+++ b/Variations/varExponential.pas
@@ -6,8 +6,7 @@ interface
uses
BaseVariation, XFormMan;
- {$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varGenericPlugin.pas b/Variations/varGenericPlugin.pas
index ee2f2c0..7d6edcc 100644
--- a/Variations/varGenericPlugin.pas
+++ b/Variations/varGenericPlugin.pas
@@ -5,6 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
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
@@ -40,9 +41,8 @@ interface
uses
BaseVariation, XFormMan, Settings, // Translation,
- Classes, //TStrings/TStringList
- SysUtils, //FindFirst/FindNext/FindClose
- Forms; //MessageBox
+ Classes, //TFileStream
+ SysUtils; //FindFirst/FindNext/FindClose
type
TPluginVariationClass = class of TPluginVariation;
@@ -108,10 +108,10 @@ type
PluginData : TPluginData;
end;
-procedure InitializePlugins;
+//procedure InitializePlugins;
const CurrentPlatform =
-{$ifdef Apo7X64}
+{$ifdef CPUX64}
$00000040
{$else}
$00000020
@@ -122,7 +122,7 @@ const CurrentPlatform =
implementation
uses
- Windows, //LoadLibrary
+ Windows, //LoadLibrary / MessageBox
Global;
{ TPluginVariation }
@@ -206,31 +206,31 @@ begin
Result := '';
end;
-///////////////////////////////////////////////////////////////////////////////
+{ //////////////////////////////////////////////////////////////////////////}
function TPluginVariation.GetNrVariables: integer;
begin
Result := PluginData.PluginVarGetNrVariables;
end;
-///////////////////////////////////////////////////////////////////////////////
+{////////////////////////////////////////////////////////////////////////////}
function TPluginVariation.GetVariableNameAt(const Index: integer): string;
begin
Result := String(PluginData.PluginVarGetVariableNameAt(Index));
end;
-///////////////////////////////////////////////////////////////////////////////
+{////////////////////////////////////////////////////////////////////////////}
function TPluginVariation.SetVariable(const Name: string; var value: double): boolean;
begin
Result := PluginData.PluginVarSetVariable(MyVariation,PAnsiChar(AnsiString(Name)),value);
end;
-///////////////////////////////////////////////////////////////////////////////
+{////////////////////////////////////////////////////////////////////////////}
function TPluginVariation.GetVariable(const Name: string; var value: double): boolean;
begin
Result := PluginData.PluginVarGetVariable(MyVariation,PAnsiChar(AnsiString(Name)),value);
end;
-///////////////////////////////////////////////////////////////////////////////
+{ ////////////////////////////////////////////////////////////////////////}
function TPluginVariation.ResetVariable(const Name: string) : boolean;
var
dummy: double;
@@ -281,7 +281,7 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+{////////////////////////////////////////////////////////////////////////////}
procedure InitializePlugins;
var
searchResult: TSearchRec;
@@ -334,8 +334,7 @@ begin
@PluginVarResetVariable := GetProcAddress(PluginHandle,'PluginVarResetVariable');
RegisterVariation(TVariationPluginLoader.Create(PluginData), @PluginVarInit3D <> nil, @PluginVarInitDC <> nil);
- //RegisterVariationFile(ExtractFilePath(Application.ExeName) + 'Plugins\' + searchResult.Name, name);
- RegisterVariationFile(PluginPath + searchResult.Name, name); // AV: fixed!
+ //RegisterVariationFile(PluginPath + searchResult.Name, name); // AV: fixed!
end;
end else begin
errno := GetLastError;
@@ -346,14 +345,20 @@ begin
until (FindNext(searchResult) <> 0);
SysUtils.FindClose(searchResult); //Since we use Windows unit (LoadLibrary)
+ // AV: now we can build the list of variation names
+ FillVarNamesList;
+
+ // AV: replaced Application.MessageBox by a more faster one from Windows unit
if msg <> '' then
- Application.MessageBox(
+ MessageBox(0,
PChar('There were problems with some of the plugins:' + #13#10#13#10 + msg),
- 'Warning', MB_ICONWARNING or MB_OK); // TextByKey('common-loaderror1')
+ 'Apophysis AV Warning', MB_ICONWARNING or MB_OK); // TextByKey('common-loaderror1')
end;
end;
-///////////////////////////////////////////////////////////////////////////////
+{ ////////////////////////////////////////////////////////////////////////// }
+initialization
+ InitializePlugins;
end.
diff --git a/Variations/varHeart.pas b/Variations/varHeart.pas
index 1022ee2..77f32d0 100644
--- a/Variations/varHeart.pas
+++ b/Variations/varHeart.pas
@@ -9,14 +9,22 @@ uses
type
TVariationHeart = class(TBaseVariation)
private
-
+ use3D: byte;
+ procedure Calc3D;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
+ function GetNrVariables: integer; override;
+ function GetVariableNameAt(const Index: integer): string; override;
+
+ function SetVariable(const Name: string; var value: double): boolean; override;
+ function GetVariable(const Name: string; var value: double): boolean; override;
+
procedure CalcFunction; override;
+ procedure GetCalcFunction(var f: TCalcFunction); override;
end;
@@ -26,6 +34,12 @@ uses
Math;
////////////////////////
+procedure TVariationHeart.GetCalcFunction(var f: TCalcFunction);
+begin
+ if use3D <> 0 then
+ f := Calc3D
+ else f := CalcFunction;
+end;
procedure TVariationHeart.CalcFunction;
var
@@ -39,9 +53,26 @@ begin
FPy^ := FPy^ - r * cosr;
end;
+procedure TVariationHeart.Calc3D;
+var
+ FAngle, r, sinr, cosr: double;
+begin
+ FAngle := arctan2(FTx^, FTy^);
+ r := sqrt(sqr(FTx^) + sqr(FTy^));
+ Sincos(r * FAngle, sinr, cosr);
+ r := r * vvar;
+ FPx^ := FPx^ + r * sinr;
+ FPy^ := FPy^ - r * cosr;
+ FAngle := arctan2(FTz^, FTy^);
+ r := sqrt(sqr(FTx^) + sqr(FTz^));
+ cosr := cos(r * FAngle);
+ FPz^ := FPz^ - vvar * r * cosr;
+end;
+
constructor TVariationHeart.Create;
begin
inherited Create;
+ use3D := 0;
end;
class function TVariationHeart.GetInstance: TBaseVariation;
@@ -54,8 +85,43 @@ begin
Result := 'heart';
end;
+///////////////////////////////////////////////////////////////////////////////
+function TVariationHeart.GetVariableNameAt(const Index: integer): string;
+begin
+ case Index of
+ 0: Result := 'heart_use3D';
+ else
+ Result := '';
+ end;
+end;
+
+function TVariationHeart.GetNrVariables: integer;
+begin
+ Result := 1;
+end;
+///////////////////////////////////////////////////////////////////////////////
+function TVariationHeart.SetVariable(const Name: string; var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'heart_use3D' then begin
+ if (Value > 1) then Value := 1;
+ if (Value < 0) then Value := 0;
+ use3D := Round(Value);
+ Result := True;
+ end;
+end;
+
+function TVariationHeart.GetVariable(const Name: string; var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'heart_use3D' then begin
+ Value := use3D;
+ Result := True;
+ end;
+end;
+
//////////////////////////////
initialization
- RegisterVariation(TVariationClassLoader.Create(TVariationHeart), false, false);
+ RegisterVariation(TVariationClassLoader.Create(TVariationHeart), true, false);
end.
diff --git a/Variations/varJulia.pas b/Variations/varJulia.pas
index 7a4feda..735c873 100644
--- a/Variations/varJulia.pas
+++ b/Variations/varJulia.pas
@@ -4,14 +4,12 @@ unit varJulia;
interface
uses
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varJulia3Djf.pas b/Variations/varJulia3Djf.pas
index 289b18e..6b666ae 100644
--- a/Variations/varJulia3Djf.pas
+++ b/Variations/varJulia3Djf.pas
@@ -26,8 +26,7 @@ unit varJulia3Djf; // original variation code by Joel Faber, modified & optimize
interface
uses
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@@ -36,8 +35,7 @@ const
var_name = 'julia3D';
var_n_name='julia3D_power';
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varJulia3Dz.pas b/Variations/varJulia3Dz.pas
index 86bb865..6038802 100644
--- a/Variations/varJulia3Dz.pas
+++ b/Variations/varJulia3Dz.pas
@@ -26,8 +26,7 @@ unit varJulia3Dz;
interface
uses
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@@ -36,8 +35,7 @@ const
var_name = 'julia3Dz';
var_n_name='julia3Dz_power';
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varJuliaN.pas b/Variations/varJuliaN.pas
index 7afa266..de00fda 100644
--- a/Variations/varJuliaN.pas
+++ b/Variations/varJuliaN.pas
@@ -3,8 +3,7 @@ unit varJuliaN;
interface
uses
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@@ -14,8 +13,7 @@ const
var_n_name='julian_power';
var_c_name='julian_dist';
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varJuliaScope.pas b/Variations/varJuliaScope.pas
index 0238c8c..5aba82c 100644
--- a/Variations/varJuliaScope.pas
+++ b/Variations/varJuliaScope.pas
@@ -26,8 +26,7 @@ unit varJuliaScope;
interface
uses
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@@ -37,8 +36,7 @@ const
var_n_name='juliascope_power';
var_c_name='juliascope_dist';
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varNGon.pas b/Variations/varNGon.pas
index 6efcebe..234e923 100644
--- a/Variations/varNGon.pas
+++ b/Variations/varNGon.pas
@@ -60,7 +60,7 @@ uses
procedure TVariationNGon.Prepare;
begin
cpower := -0.5 * ngon_power;
- csides := 2.0 * PI / ngon_sides;
+ csides := PI2 / ngon_sides; // AV: replaced 2.0 * PI by the const
csidesinv := 1.0 / csides;
end;
@@ -68,9 +68,11 @@ procedure TVariationNGon.CalcFunction;
var
r_factor, theta, phi, amp: double;
begin
-
- if (FTX^ = 0) and (FTY^ = 0) then r_factor := 0
- else r_factor := Power(FTx^ * FTx^ + FTy^ * FTy^, cpower);
+ // AV: this check for a single case just slow down overall calculations
+ // since these 2 conditions are evaluated in every point
+ { if (FTX^ = 0) and (FTY^ = 0) then
+ else } // <-- this will be true anyway
+ r_factor := Power(FTx^ * FTx^ + FTy^ * FTy^, cpower);
theta := ArcTan2(FTy^, FTx^);
@@ -78,11 +80,12 @@ begin
if (phi > 0.5 * csides) then
phi := phi - csides;
+ // AV: and yeah, if (r_factor = 0) then also (amp = 0) so we must not calc it
amp := (ngon_corners * (1.0 / cos(phi) - 1.0) + ngon_circle) * VVAR * r_factor;
FPx^ := FPx^ + amp * FTx^;
FPy^ := FPy^ + amp * FTy^;
- FPz^ := FPz^ + VVAR * FTz^;
+ FPz^ := FPz^ + VVAR * FTz^; // <-- AV: I don't like this since we have pre_zscale
end;
///////////////////////////////////////////////////////////////////////////////
diff --git a/Variations/varPDJ.pas b/Variations/varPDJ.pas
index 5fe73e3..97b30ea 100644
--- a/Variations/varPDJ.pas
+++ b/Variations/varPDJ.pas
@@ -29,8 +29,7 @@ interface
uses
BaseVariation, XFormMan;
-{$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varPopcorn2.pas b/Variations/varPopcorn2.pas
index 346f0b5..8326997 100644
--- a/Variations/varPopcorn2.pas
+++ b/Variations/varPopcorn2.pas
@@ -46,11 +46,11 @@ begin
else
sn := 0;
FPx^ := FPx^ + vvar * (FTx^ + p2x * sn);
- SinCos(p2c * FTx^, sn, cn);
+ SinCos(p2c * FTx^, sn, cn);
if cn <> 0 then // AV: safety tangent
- sn := sin(sn / cn)
+ sn := sin(sn / cn)
else
- sn := 0;
+ sn := 0;
FPy^ := FPy^ + vvar * (FTy^ + p2y * sn);
end;
diff --git a/Variations/varPostFalloff2.pas b/Variations/varPostFalloff2.pas
index 948c31f..22a3ad5 100644
--- a/Variations/varPostFalloff2.pas
+++ b/Variations/varPostFalloff2.pas
@@ -87,6 +87,7 @@ begin
else if blurtype = 2 then f := CalcFunctionGaussian
else f := CalcFunction;
end;
+
procedure TVariationPostFalloff2.CalcFunction;
var
in_x, in_y, in_z, d: double;
@@ -104,6 +105,7 @@ begin
FPz^ := VVAR * (in_z + mul_z * random * d);
color^ := Abs(Frac(color^ + mul_c * random * d));
end;
+
procedure TVariationPostFalloff2.CalcFunctionRadial;
var
in_x, in_y, in_z, d, r_in: double;
@@ -130,6 +132,7 @@ begin
FPz^ := VVAR * (sins);
color^ := Abs(Frac(color^ + mul_c * random * d));
end;
+
procedure TVariationPostFalloff2.CalcFunctionGaussian;
var
in_x, in_y, in_z, d: double;
diff --git a/Variations/varPostMobius.pas b/Variations/varPostMobius.pas
new file mode 100644
index 0000000..28c91f9
--- /dev/null
+++ b/Variations/varPostMobius.pas
@@ -0,0 +1,254 @@
+{
+ Apophysis Copyright (C) 2001-2004 Mark Townsend
+ Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
+ Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
+
+ Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
+ Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+
+unit varPostMobius;
+
+interface
+
+uses
+ BaseVariation, XFormMan;
+
+type
+ TVariationPostMobius = class(TBaseVariation)
+ private
+ Re_A, Im_A, Re_B, Im_B, Re_C, Im_C, Re_D, Im_D: double;
+ mobius_invert : byte;
+ procedure CalcInvert;
+ public
+ constructor Create;
+
+ class function GetName: string; override;
+ class function GetInstance: TBaseVariation; override;
+
+ function GetNrVariables: integer; override;
+ function GetVariableNameAt(const Index: integer): string; override;
+
+ function SetVariable(const Name: string; var value: double): boolean; override;
+ function GetVariable(const Name: string; var value: double): boolean; override;
+ function ResetVariable(const Name: string): boolean; override;
+
+ procedure CalcFunction; override;
+ procedure GetCalcFunction(var f: TCalcFunction); override;
+ end;
+
+implementation
+
+uses
+ Math;
+
+///////////////////////////////////////////////////////////////////////////////
+procedure TVariationPostMobius.GetCalcFunction(var f: TCalcFunction);
+begin // AV: this helps to increase the calc speed
+ if (mobius_invert <> 0) then
+ f := CalcInvert
+ else f := CalcFunction;
+end;
+
+procedure TVariationPostMobius.CalcFunction;
+const EPS = 1E-100;
+var
+ uRe, uIm, vRe, vIm, vDenom : double;
+begin
+ uRe := (Re_A) * FPX^ - (Im_A) * FPY^ + (Re_B);
+ uIm := (Re_A) * FPY^ + (Im_A) * FPX^ + (Im_B);
+ vRe := (Re_C) * FPX^ - (Im_C) * FPY^ + (Re_D);
+ vIm := (Re_C) * FPY^ + (Im_C) * FPX^ + (Im_D);
+
+ vDenom := vRe * vRe + vIm * vIm;
+ if abs(vDenom) < EPS then vDenom := EPS;
+
+ FPx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
+ FPy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
+end;
+
+procedure TVariationPostMobius.CalcInvert; // inverse Mobius transformation
+const EPS = 1E-100;
+var
+ uRe, uIm, vRe, vIm, vDenom : double;
+begin
+ uRe := (Re_D) * FPX^ - (Im_D) * FPY^ - (Re_B);
+ uIm := (Re_D) * FPY^ + (Im_D) * FPX^ - (Im_B);
+ vRe := -(Re_C) * FPX^ + (Im_C) * FPY^ + (Re_A);
+ vIm := -(Re_C) * FPY^ - (Im_C) * FPX^ + (Im_A);
+
+ vDenom := vRe * vRe + vIm * vIm;
+ if abs(vDenom) < EPS then vDenom := EPS;
+
+ FPx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
+ FPy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+constructor TVariationPostMobius.Create;
+begin
+ Re_A := 1; Im_A := 0;
+ Re_B := 0; Im_B := 0;
+ Re_C := 0; Im_C := 0;
+ Re_D := 1; Im_D := 0;
+ mobius_invert := 0;
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+class function TVariationPostMobius.GetInstance: TBaseVariation;
+begin
+ Result := TVariationPostMobius.Create;
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+class function TVariationPostMobius.GetName: string;
+begin
+ Result := 'post_mobius';
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPostMobius.GetVariableNameAt(const Index: integer): string;
+begin
+ case Index of
+ 0: Result := 'post_mobius_Re_A';
+ 1: Result := 'post_mobius_Im_A';
+ 2: Result := 'post_mobius_Re_B';
+ 3: Result := 'post_mobius_Im_B';
+ 4: Result := 'post_mobius_Re_C';
+ 5: Result := 'post_mobius_Im_C';
+ 6: Result := 'post_mobius_Re_D';
+ 7: Result := 'post_mobius_Im_D';
+ 8: Result := 'post_mobius_invert';
+ else
+ Result := '';
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPostMobius.SetVariable(const Name: string; var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'post_mobius_Re_A' then begin
+ Re_A := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Im_A' then begin
+ Im_A := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Re_B' then begin
+ Re_B := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Im_B' then begin
+ Im_B := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Re_C' then begin
+ Re_C := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Im_C' then begin
+ Im_C := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Re_D' then begin
+ Re_D := Value;
+ Result := True;
+ end else if Name = 'post_mobius_Im_D' then begin
+ Im_D := Value;
+ Result := True;
+ end else if Name = 'post_mobius_invert' then begin
+ if (Value > 1) then Value := 1;
+ if (Value < 0) then Value := 0;
+ mobius_invert := Round(Value);
+ Result := True;
+ end
+end;
+function TVariationPostMobius.ResetVariable(const Name: string): boolean;
+begin
+ Result := False;
+ if Name = 'post_mobius_Re_A' then begin
+ Re_A := 1;
+ Result := True;
+ end else if Name = 'post_mobius_Im_A' then begin
+ Im_A := 0;
+ Result := True;
+ end else if Name = 'post_mobius_Re_B' then begin
+ Re_B := 0;
+ Result := True;
+ end else if Name = 'post_mobius_Im_B' then begin
+ Im_B := 0;
+ Result := True;
+ end else if Name = 'post_mobius_Re_C' then begin
+ Re_C := 0;
+ Result := True;
+ end else if Name = 'post_mobius_Im_C' then begin
+ Im_C := 0;
+ Result := True;
+ end else if Name = 'post_mobius_Re_D' then begin
+ Re_D := 1;
+ Result := True;
+ end else if Name = 'post_mobius_Im_D' then begin
+ Im_D := 0;
+ Result := True;
+ end else if Name = 'post_mobius_invert' then begin
+ mobius_invert := 0;
+ Result := True;
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPostMobius.GetNrVariables: integer;
+begin
+ Result := 9
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPostMobius.GetVariable(const Name: string; var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'post_mobius_Re_A' then begin
+ Value := Re_A;
+ Result := True;
+ end else if Name = 'post_mobius_Im_A' then begin
+ Value := Im_A;
+ Result := True;
+ end else if Name = 'post_mobius_Re_B' then begin
+ Value := Re_B;
+ Result := True;
+ end else if Name = 'post_mobius_Im_B' then begin
+ Value := Im_B;
+ Result := True;
+ end else if Name = 'post_mobius_Re_C' then begin
+ Value := Re_C;
+ Result := True;
+ end else if Name = 'post_mobius_Im_C' then begin
+ Value := Im_C;
+ Result := True;
+ end else if Name = 'post_mobius_Re_D' then begin
+ Value := Re_D;
+ Result := True;
+ end else if Name = 'post_mobius_Im_D' then begin
+ Value := Im_D;
+ Result := True;
+ end else if Name = 'post_mobius_invert' then begin
+ Value := mobius_invert;
+ Result := True;
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+initialization
+ RegisterVariation(TVariationClassLoader.Create(TVariationPostMobius), false, false);
+end.
\ No newline at end of file
diff --git a/Variations/varPostSinusoidal.pas b/Variations/varPostSinusoidal.pas
index bd3bcce..695229a 100644
--- a/Variations/varPostSinusoidal.pas
+++ b/Variations/varPostSinusoidal.pas
@@ -7,8 +7,7 @@ interface
uses
BaseVariation, XFormMan;
- {$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varPower.pas b/Variations/varPower.pas
index dc2aa40..14a0d90 100644
--- a/Variations/varPower.pas
+++ b/Variations/varPower.pas
@@ -1,4 +1,4 @@
-{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
+{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit varPower;
@@ -9,14 +9,22 @@ uses
type
TVariationPower = class(TBaseVariation)
private
-
+ use3D: byte;
+ procedure Calc3D;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
+ function GetNrVariables: integer; override;
+ function GetVariableNameAt(const Index: integer): string; override;
+
+ function SetVariable(const Name: string; var value: double): boolean; override;
+ function GetVariable(const Name: string; var value: double): boolean; override;
+
procedure CalcFunction; override;
+ procedure GetCalcFunction(var f: TCalcFunction); override;
end;
@@ -27,14 +35,35 @@ uses
////////////////////////
+procedure TVariationPower.GetCalcFunction(var f: TCalcFunction);
+begin
+ if use3D <> 0 then f := Calc3D // AV: added optional 3d-support
+ else f := CalcFunction;
+end;
+
+procedure TVariationPower.Calc3D; // AV
+var
+ r, FSinA, FCosA: double;
+begin
+ r := sqrt(sqr(FTx^) + sqr(FTy^) + sqr(FTz^)) + 1E-300;
+ FSinA := FTx^ / r;
+ FCosA := FTy^ / r;
+ r := vvar * Math.Power(r, FSinA);
+ FPx^ := FPx^ + r * FCosA;
+ FPy^ := FPy^ + r * FSinA;
+ // transform the plane into 3d-shape
+ r := vvar * Math.Power(r, FCosA);
+ FPz^ := FPz^ + r * FCosA; //FSinA;
+end;
+
procedure TVariationPower.CalcFunction;
var
- r, FLength, FSinA, FCosA: double;
+ r, FSinA, FCosA: double;
begin
- FLength := sqrt(sqr(FTx^) + sqr(FTy^)) + 1E-300;
- FSinA := FTx^ / FLength;
- FCosA := FTy^ / FLength;
- r := vvar * Math.Power(FLength, FSinA);
+ r := sqrt(sqr(FTx^) + sqr(FTy^)) + 1E-300;
+ FSinA := FTx^ / r;
+ FCosA := FTy^ / r;
+ r := vvar * Math.Power(r, FSinA);
FPx^ := FPx^ + r * FCosA;
FPy^ := FPy^ + r * FSinA;
end;
@@ -42,6 +71,7 @@ end;
constructor TVariationPower.Create;
begin
inherited Create;
+ use3D := 0;
end;
class function TVariationPower.GetInstance: TBaseVariation;
@@ -54,8 +84,44 @@ begin
Result := 'power';
end;
+function TVariationPower.GetNrVariables: integer;
+begin
+ Result := 1;
+end;
+
+function TVariationPower.GetVariableNameAt(const Index: integer): string;
+begin
+ case Index of
+ 0: Result := 'power_use3D';
+ else
+ Result := '';
+ end;
+end;
+
+function TVariationPower.GetVariable(const Name: string;
+ var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'power_use3D' then begin
+ Value := use3D;
+ Result := True;
+ end;
+end;
+
+function TVariationPower.SetVariable(const Name: string;
+ var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'power_use3D' then begin
+ if (Value > 1) then Value := 1;
+ if (Value < 0) then Value := 0;
+ use3D := Round(Value);
+ Result := True;
+ end;
+end;
+
//////////////////////////////
initialization
- RegisterVariation(TVariationClassLoader.Create(TVariationPower), false, false);
+ RegisterVariation(TVariationClassLoader.Create(TVariationPower), true, false);
end.
diff --git a/Variations/varPreMobius.pas b/Variations/varPreMobius.pas
new file mode 100644
index 0000000..f63c144
--- /dev/null
+++ b/Variations/varPreMobius.pas
@@ -0,0 +1,254 @@
+{
+ Apophysis Copyright (C) 2001-2004 Mark Townsend
+ Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
+ Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
+
+ Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
+ Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
+ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+
+unit varPreMobius;
+
+interface
+
+uses
+ BaseVariation, XFormMan;
+
+type
+ TVariationPreMobius = class(TBaseVariation)
+ private
+ Re_A, Im_A, Re_B, Im_B, Re_C, Im_C, Re_D, Im_D: double;
+ mobius_invert : byte;
+ procedure CalcInvert;
+ public
+ constructor Create;
+
+ class function GetName: string; override;
+ class function GetInstance: TBaseVariation; override;
+
+ function GetNrVariables: integer; override;
+ function GetVariableNameAt(const Index: integer): string; override;
+
+ function SetVariable(const Name: string; var value: double): boolean; override;
+ function GetVariable(const Name: string; var value: double): boolean; override;
+ function ResetVariable(const Name: string): boolean; override;
+
+ procedure CalcFunction; override;
+ procedure GetCalcFunction(var f: TCalcFunction); override;
+ end;
+
+implementation
+
+uses
+ Math;
+
+///////////////////////////////////////////////////////////////////////////////
+procedure TVariationPreMobius.GetCalcFunction(var f: TCalcFunction);
+begin // AV: this helps to increase the calc speed
+ if (mobius_invert <> 0) then
+ f := CalcInvert
+ else f := CalcFunction;
+end;
+
+procedure TVariationPreMobius.CalcFunction;
+const EPS = 1E-100;
+var
+ uRe, uIm, vRe, vIm, vDenom : double;
+begin
+ uRe := (Re_A) * FTx^ - (Im_A) * FTy^ + (Re_B);
+ uIm := (Re_A) * FTy^ + (Im_A) * FTx^ + (Im_B);
+ vRe := (Re_C) * FTx^ - (Im_C) * FTy^ + (Re_D);
+ vIm := (Re_C) * FTy^ + (Im_C) * FTx^ + (Im_D);
+
+ vDenom := vRe * vRe + vIm * vIm;
+ if abs(vDenom) < EPS then vDenom := EPS;
+
+ FTx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
+ FTy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
+end;
+
+procedure TVariationPreMobius.CalcInvert; // inverse Mobius transformation
+const EPS = 1E-100;
+var
+ uRe, uIm, vRe, vIm, vDenom : double;
+begin
+ uRe := (Re_D) * FTX^ - (Im_D) * FTY^ - (Re_B);
+ uIm := (Re_D) * FTY^ + (Im_D) * FTx^ - (Im_B);
+ vRe := -(Re_C) * FTx^ + (Im_C) * FTy^ + (Re_A);
+ vIm := -(Re_C) * FTy^ - (Im_C) * FTx^ + (Im_A);
+
+ vDenom := vRe * vRe + vIm * vIm;
+ if abs(vDenom) < EPS then vDenom := EPS;
+
+ FTx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
+ FTy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+constructor TVariationPreMobius.Create;
+begin
+ Re_A := 1; Im_A := 0;
+ Re_B := 0; Im_B := 0;
+ Re_C := 0; Im_C := 0;
+ Re_D := 1; Im_D := 0;
+ mobius_invert := 0;
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+class function TVariationPreMobius.GetInstance: TBaseVariation;
+begin
+ Result := TVariationPreMobius.Create;
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+class function TVariationPreMobius.GetName: string;
+begin
+ Result := 'pre_mobius';
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPreMobius.GetVariableNameAt(const Index: integer): string;
+begin
+ case Index of
+ 0: Result := 'pre_mobius_Re_A';
+ 1: Result := 'pre_mobius_Im_A';
+ 2: Result := 'pre_mobius_Re_B';
+ 3: Result := 'pre_mobius_Im_B';
+ 4: Result := 'pre_mobius_Re_C';
+ 5: Result := 'pre_mobius_Im_C';
+ 6: Result := 'pre_mobius_Re_D';
+ 7: Result := 'pre_mobius_Im_D';
+ 8: Result := 'pre_mobius_invert';
+ else
+ Result := '';
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPreMobius.SetVariable(const Name: string; var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'pre_mobius_Re_A' then begin
+ Re_A := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_A' then begin
+ Im_A := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_B' then begin
+ Re_B := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_B' then begin
+ Im_B := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_C' then begin
+ Re_C := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_C' then begin
+ Im_C := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_D' then begin
+ Re_D := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_D' then begin
+ Im_D := Value;
+ Result := True;
+ end else if Name = 'pre_mobius_invert' then begin
+ if (Value > 1) then Value := 1;
+ if (Value < 0) then Value := 0;
+ mobius_invert := Round(Value);
+ Result := True;
+ end
+end;
+function TVariationPreMobius.ResetVariable(const Name: string): boolean;
+begin
+ Result := False;
+ if Name = 'pre_mobius_Re_A' then begin
+ Re_A := 1;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_A' then begin
+ Im_A := 0;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_B' then begin
+ Re_B := 0;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_B' then begin
+ Im_B := 0;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_C' then begin
+ Re_C := 0;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_C' then begin
+ Im_C := 0;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_D' then begin
+ Re_D := 1;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_D' then begin
+ Im_D := 0;
+ Result := True;
+ end else if Name = 'pre_mobius_invert' then begin
+ mobius_invert := 0;
+ Result := True;
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPreMobius.GetNrVariables: integer;
+begin
+ Result := 9
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+function TVariationPreMobius.GetVariable(const Name: string; var value: double): boolean;
+begin
+ Result := False;
+ if Name = 'pre_mobius_Re_A' then begin
+ Value := Re_A;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_A' then begin
+ Value := Im_A;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_B' then begin
+ Value := Re_B;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_B' then begin
+ Value := Im_B;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_C' then begin
+ Value := Re_C;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_C' then begin
+ Value := Im_C;
+ Result := True;
+ end else if Name = 'pre_mobius_Re_D' then begin
+ Value := Re_D;
+ Result := True;
+ end else if Name = 'pre_mobius_Im_D' then begin
+ Value := Im_D;
+ Result := True;
+ end else if Name = 'pre_mobius_invert' then begin
+ Value := mobius_invert;
+ Result := True;
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+initialization
+ RegisterVariation(TVariationClassLoader.Create(TVariationPreMobius), false, false);
+end.
\ No newline at end of file
diff --git a/Variations/varPreSinusoidal.pas b/Variations/varPreSinusoidal.pas
index 03d7bc6..ce94f58 100644
--- a/Variations/varPreSinusoidal.pas
+++ b/Variations/varPreSinusoidal.pas
@@ -29,8 +29,7 @@ interface
uses
BaseVariation, XFormMan;
- {$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varSinusoidal.pas b/Variations/varSinusoidal.pas
index fdbcb1a..4e96db2 100644
--- a/Variations/varSinusoidal.pas
+++ b/Variations/varSinusoidal.pas
@@ -28,8 +28,7 @@ interface
uses
BaseVariation, XFormMan;
- {$ifdef Apo7X64}
-{$else}
+{$ifdef CPUX86}
{$define _ASM_}
{$endif}
diff --git a/Variations/varTanhSpiral.pas b/Variations/varTanhSpiral.pas
index c7be793..3c0639e 100644
--- a/Variations/varTanhSpiral.pas
+++ b/Variations/varTanhSpiral.pas
@@ -40,7 +40,7 @@ procedure TVariationTanhSpiral.CalcFunction;
var
t, aux, sn, cn, snh, cnh: double;
begin
- t := (random - 0.5) * 6.28318530717959;
+ t := (random - 0.5) * PI2;
SinCos(ta * t, sn, cn);
SinhCosh(t, snh, cnh);