Initial commit
This commit is contained in:
		
							
								
								
									
										226
									
								
								Core/BaseVariation.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								Core/BaseVariation.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,226 @@ | ||||
| { | ||||
|      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 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 BaseVariation; | ||||
|  | ||||
| interface | ||||
|  | ||||
| type | ||||
|   TCalcFunction = procedure of object; | ||||
|  | ||||
| type | ||||
|   TBaseVariation = class | ||||
|  | ||||
|   protected | ||||
|     procedure CalcFunction; virtual; abstract; | ||||
|  | ||||
|   public | ||||
|     vvar:  double; | ||||
|     FTx, FTy: ^double; | ||||
|     FPx, FPy: ^double; | ||||
|     FTz, FPz: ^double; | ||||
|  | ||||
|     // more params :) | ||||
|     color : ^double; | ||||
|     a, b, c, d, e, f : double; | ||||
|  | ||||
|     class function GetName: string; virtual; abstract; | ||||
|     class function GetInstance: TBaseVariation; virtual; abstract; | ||||
|  | ||||
|     function GetNrVariables: integer; virtual; | ||||
|     function GetVariableNameAt(const Index: integer): string; virtual; | ||||
|  | ||||
|     function GetVariable(const Name: string; var Value: double): boolean; virtual; | ||||
|     function SetVariable(const Name: string; var Value: double): boolean; virtual; | ||||
|     function ResetVariable(const Name: string): boolean; virtual; | ||||
|  | ||||
|     function GetVariableStr(const Name: string): string; virtual; | ||||
|     function SetVariableStr(const Name: string; var strValue: string): boolean; virtual; | ||||
|  | ||||
|     procedure Prepare; virtual; | ||||
|  | ||||
|     procedure GetCalcFunction(var Delphi_Suxx: TCalcFunction); virtual; | ||||
|   end; | ||||
|  | ||||
|   TBaseVariationClass = class of TBaseVariation; | ||||
|  | ||||
| type | ||||
|   TVariationLoader = class | ||||
|   public | ||||
|     Supports3D, SupportsDC : boolean; | ||||
|  | ||||
|     function GetName: string; virtual; abstract; | ||||
|     function GetInstance: TBaseVariation; virtual; abstract; | ||||
|     function GetNrVariables: integer; virtual; abstract; | ||||
|     function GetVariableNameAt(const Index: integer): string; virtual; abstract; | ||||
|   end; | ||||
|  | ||||
| type | ||||
|   TVariationClassLoader = class (TVariationLoader) | ||||
|   public | ||||
|     constructor Create(varClass : TBaseVariationClass); | ||||
|     function GetName: string; override; | ||||
|     function GetInstance: TBaseVariation; override; | ||||
|     function GetNrVariables: integer; override; | ||||
|     function GetVariableNameAt(const Index: integer): string; override; | ||||
|  | ||||
|   private | ||||
|     VariationClass : TBaseVariationClass; | ||||
|   end; | ||||
|  | ||||
| const | ||||
|   PI2 = 6.283185307179586476925286766559;  // AV | ||||
|   PI_2 = 1.5707963267948966192313216916398;  // AV | ||||
|  | ||||
| function fmod(x, y: double) : double; | ||||
| procedure SinhCosh(const v: double; var sh, ch: double);  // AV | ||||
|  | ||||
| implementation | ||||
|  | ||||
| uses SysUtils; | ||||
|  | ||||
| function fmod(x, y: double) : double; | ||||
| begin | ||||
|   Result := frac(x / y) * y; | ||||
| end; | ||||
|  | ||||
| procedure SinhCosh(const v: double; var sh, ch: double); | ||||
| // AV: calcs both hyperbolic sine and cosine | ||||
| var ep, en: double; | ||||
| begin | ||||
| 	ep := 0.5 * exp(v); | ||||
| 	en := 0.25 / ep; // 0.5 * exp(-v); | ||||
| 	sh := ep - en; | ||||
| 	ch := ep + en; | ||||
| end; | ||||
|  | ||||
| { TBaseVariation } | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function TBaseVariation.GetNrVariables: integer; | ||||
| begin | ||||
|   Result := 0; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function TBaseVariation.GetVariable(const Name: string; var value: double): boolean; | ||||
| begin | ||||
|   Result := False; | ||||
| end; | ||||
|  | ||||
| function TBaseVariation.SetVariable(const Name: string; var value: double): boolean; | ||||
| begin | ||||
|   Result := False; | ||||
| end; | ||||
|  | ||||
| function TBaseVariation.ResetVariable(const Name: string): boolean; | ||||
| var | ||||
|   zero: double; | ||||
| begin | ||||
|   zero := 0; | ||||
|   Result := SetVariable(Name, zero); | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function TBaseVariation.GetVariableStr(const Name: string): string; | ||||
| var | ||||
|   value: double; | ||||
| begin | ||||
|   if GetVariable(Name, value) then | ||||
|     Result := Format('%.6g', [value]) | ||||
|   else | ||||
|     Result := ''; | ||||
| end; | ||||
|  | ||||
| function TBaseVariation.SetVariableStr(const Name: string; var strValue: string): boolean; | ||||
| var | ||||
|   v, oldv: double; | ||||
| begin | ||||
|   if GetVariable(Name, oldv) then begin | ||||
|     try | ||||
|       v := StrToFloat(strValue); | ||||
|       SetVariable(Name, v); | ||||
|     except | ||||
|       v := oldv; | ||||
|     end; | ||||
|     strValue := Format('%.6g', [v]); | ||||
|     Result := true; | ||||
|   end | ||||
|   else Result := false; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function TBaseVariation.GetVariableNameAt(const Index: integer): string; | ||||
| begin | ||||
|   Result := '' | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TBaseVariation.Prepare; | ||||
| begin | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TBaseVariation.GetCalcFunction(var Delphi_Suxx: TCalcFunction); | ||||
| begin | ||||
|   Delphi_Suxx := CalcFunction;   // -X- lol | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| { TVariationClassLoader } | ||||
|  | ||||
| constructor TVariationClassLoader.Create(varClass : TBaseVariationClass); | ||||
| begin | ||||
|   VariationClass := varClass; | ||||
| end; | ||||
|  | ||||
| function TVariationClassLoader.GetName: string; | ||||
| begin | ||||
|   Result := VariationClass.GetName(); | ||||
| end; | ||||
|  | ||||
| function TVariationClassLoader.GetInstance: TBaseVariation; | ||||
| begin | ||||
|   Result := VariationClass.GetInstance(); | ||||
| end; | ||||
|  | ||||
| function TVariationClassLoader.GetNrVariables: integer; | ||||
| var | ||||
|   hack : TBaseVariation; | ||||
| begin | ||||
|   hack := GetInstance(); | ||||
|   Result := hack.GetNrVariables(); | ||||
|   hack.Free(); | ||||
| end; | ||||
|  | ||||
| function TVariationClassLoader.GetVariableNameAt(const Index: integer): string; | ||||
| var | ||||
|   hack : TBaseVariation; | ||||
| begin | ||||
|   hack := GetInstance(); | ||||
|   Result := hack.GetVariableNameAt(Index); | ||||
|   hack.Free(); | ||||
| end; | ||||
|  | ||||
| end. | ||||
							
								
								
									
										94
									
								
								Core/Bezier.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								Core/Bezier.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| unit Bezier; | ||||
|  | ||||
| interface | ||||
|  | ||||
| uses Math; | ||||
|  | ||||
|  | ||||
| type | ||||
|   BezierPoint = record | ||||
|     x, y: double; | ||||
|   end; | ||||
|   BezierRect = record | ||||
|     x0, y0, x1, y1: double; | ||||
|   end; | ||||
|  | ||||
|   BezierPoints = array [0..3] of BezierPoint; | ||||
|   BezierWeights = array [0..3] of double; | ||||
|  | ||||
| procedure BezierCopy(src: BezierPoints; var tgt: BezierPoints); | ||||
| procedure BezierSetRect(var points: BezierPoints; flip: boolean; rect: BezierRect); | ||||
| procedure BezierUnsetRect(var points: BezierPoints; flip: boolean; rect: BezierRect); | ||||
|  | ||||
| procedure BezierSolve(t: double; src: BezierPoints; w: BezierWeights; var solution: BezierPoint); | ||||
| function  BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double; | ||||
|  | ||||
| implementation | ||||
|   procedure BezierCopy(src: BezierPoints; var tgt: BezierPoints); | ||||
|   var | ||||
|     i, n: integer; | ||||
|   begin | ||||
|     n := Length(src); | ||||
|     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; | ||||
|     f: double; | ||||
|   begin | ||||
|     n := Length(points); | ||||
|     for i := 0 to n - 1 do | ||||
|     begin | ||||
|       if (flip) then f := 1 - points[i].y | ||||
|       else f := points[i].y; | ||||
|  | ||||
|       points[i].x := points[i].x * (rect.x1 - rect.x0) + rect.x0; | ||||
|       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; | ||||
|     f: double; | ||||
|   begin | ||||
|     if ((rect.x1 - rect.x0) = 0) or ((rect.y1 - rect.y0) = 0) then Exit; | ||||
|  | ||||
|     n := Length(points); | ||||
|     for i := 0 to n - 1 do | ||||
|     begin | ||||
|       points[i].x := (points[i].x - rect.x0) / (rect.x1 - rect.x0); | ||||
|       points[i].y := (points[i].y - rect.y0) / (rect.y1 - rect.y0); | ||||
|  | ||||
|       if (flip) then points[i].y := 1 - points[i].y; | ||||
|     end; | ||||
|   end; | ||||
|  | ||||
|   procedure BezierSolve(t: double; src: BezierPoints; w: BezierWeights; var solution: BezierPoint); | ||||
|   var | ||||
|     s, s2, s3, t2, t3, nom_x, nom_y, denom: double; | ||||
|   begin | ||||
|     s := 1 - t; | ||||
|     s2 := s * s; s3 := s * s * s; | ||||
|     t2 := t * t; t3 := t * t * t; | ||||
|  | ||||
|     nom_x := w[0] * s3 * src[0].x + w[1] * s2 * 3 * t * src[1].x + | ||||
|              w[2] * s * 3 * t2 * src[2].x + w[3] * t3 * src[3].x; | ||||
|     nom_y := w[0] * s3 * src[0].y + w[1] * s2 * 3 * t * src[1].y + | ||||
|              w[2] * s * 3 * t2 * src[2].y + w[3] * t3 * src[3].y; | ||||
|     denom := w[0] * s3 + w[1] * s2 * 3 * t + w[2] * s * 3 * t2 + w[3] * t3; | ||||
|  | ||||
|     if (IsNaN(nom_x)) or (IsNaN(nom_y)) or (IsNaN(denom)) then Exit; | ||||
|     if denom = 0 then Exit; | ||||
|      | ||||
|     solution.x := nom_x / denom; | ||||
|     solution.y := nom_y / denom; | ||||
|   end; | ||||
|   function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double; | ||||
|   var | ||||
|     p: BezierPoint; | ||||
|   begin | ||||
|     BezierSolve(t, src, w, p); | ||||
|     Result := p.y; | ||||
|   end; | ||||
| end. | ||||
							
								
								
									
										300
									
								
								Core/Chaotica.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								Core/Chaotica.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,300 @@ | ||||
| unit Chaotica; | ||||
|  | ||||
| interface | ||||
|  | ||||
| uses Global, RegularExpressionsCore, RegexHelper, Classes, SysUtils, XFormMan, Windows, | ||||
|   ShellAPI, Forms, ControlPoint, Translation; | ||||
|  | ||||
| function C_GetPathOf(filename: string; usex64: boolean): string; | ||||
| function C_SupportsDllPlugins(usex64: boolean): boolean; | ||||
| function C_IsDllPluginBlacklisted(filename: string; usex64: boolean): boolean; | ||||
| 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); | ||||
|  | ||||
| implementation | ||||
|  | ||||
| uses Main; | ||||
|  | ||||
| (*   // AV: rewrote and moved to Global unit | ||||
| function CheckX64: Boolean; | ||||
| var | ||||
|   SEInfo: TShellExecuteInfo; | ||||
|   ExitCode: DWORD; | ||||
|   ExecuteFile, ParamString, StartInString: string; | ||||
| begin | ||||
|   {$ifdef Apo7X64} | ||||
|   Result := true; | ||||
|   exit; | ||||
|   {$endif} | ||||
|  | ||||
|   ExecuteFile := ExtractFilePath(Application.ExeName) + 'chk64.exe'; | ||||
|   FillChar(SEInfo, SizeOf(SEInfo), 0); | ||||
|   SEInfo.cbSize := SizeOf(TShellExecuteInfo); | ||||
|  | ||||
|   with SEInfo do begin | ||||
|     fMask := SEE_MASK_NOCLOSEPROCESS; | ||||
|     Wnd := Application.Handle; | ||||
|     lpFile := PChar(ExecuteFile) ; | ||||
|     nShow := SW_SHOWNORMAL; | ||||
|   end; | ||||
|    | ||||
|   if ShellExecuteEx(@SEInfo) then | ||||
|   begin | ||||
|     repeat | ||||
|       Application.ProcessMessages; | ||||
|       GetExitCodeProcess(SEInfo.hProcess, ExitCode); | ||||
|     until (ExitCode <> STILL_ACTIVE) or Application.Terminated; | ||||
|     Result := (ExitCode = 0); | ||||
|   end else begin | ||||
|     Result := false; | ||||
|   end; | ||||
| end; | ||||
| *) | ||||
|  | ||||
| function C_GetPathOf(filename: string; usex64: boolean): string; | ||||
| begin | ||||
|   Result := ChaoticaPath + '\' + filename; | ||||
| end; | ||||
|  | ||||
| function C_SupportsDllPlugins(usex64: boolean): boolean; | ||||
| const | ||||
|   re_root : string = '<variation_compatibility\s+(.*?)>.*?</variation_compatibility>'; | ||||
|   re_attrib : string = 'supports_dll_plugins="(.*?)"'; | ||||
| var | ||||
|   xml_file : TStringList; | ||||
|   xml_text, attrib, value : string; | ||||
| begin | ||||
|   if usex64 then begin | ||||
|     Result := false; | ||||
|     Exit; | ||||
|   end; | ||||
|  | ||||
|   xml_file := TStringList.Create; | ||||
| // AV: for compatibility with new Chaotica versions | ||||
|   if not FileExists(ChaoticaPath + '\variation_compatibility.xml') then | ||||
|   begin | ||||
|     xml_file.Add('<variation_compatibility >' + #13#10 + '</variation_compatibility>'); | ||||
|     xml_file.SaveToFile(ChaoticaPath + '\variation_compatibility.xml'); | ||||
|     xml_file.Clear; | ||||
|   end; | ||||
|   xml_file.LoadFromFile(C_GetPathOf('variation_compatibility.xml', false)); | ||||
|   xml_text := xml_file.Text; | ||||
|   xml_file.Free; | ||||
|  | ||||
|   attrib := GetStringPart(xml_text, re_root, 1, 'supports_dll_plugins="false"'); | ||||
|   value := GetStringPart(attrib, re_attrib, 1, 'false'); | ||||
|  | ||||
|   Result := (value = 'true'); | ||||
| end; | ||||
|  | ||||
| function C_IsDllPluginBlacklisted(filename: string; usex64: boolean): boolean; | ||||
| var | ||||
|   i: integer; | ||||
|   blacklist: TStringList; | ||||
| 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.SaveToFile(ChaoticaPath + '\plugin_dll_blacklist.txt'); | ||||
|   end; | ||||
|  | ||||
|   blacklist.LoadFromFile(C_GetPathOf('plugin_dll_blacklist.txt', usex64)); | ||||
|  | ||||
|   for i := 0 to blacklist.Count - 1 do begin | ||||
|     if LowerCase(filename) = LowerCase(blacklist.Strings[i]) then begin | ||||
|       Result := true; | ||||
|       blacklist.Free; | ||||
|       Exit; | ||||
|     end; | ||||
|   end; | ||||
|  | ||||
|   blacklist.Free; | ||||
|   Result := false; | ||||
| end; | ||||
|  | ||||
| function C_IsVariationNative(name: string; usex64: boolean): boolean; | ||||
| const | ||||
|   re_root : string = '<variation_compatibility.*?>(.*?)</variation_compatibility>'; | ||||
|   re_var : string = '<variation name="(.*?)".*?/>'; | ||||
| var | ||||
|   xml, var_name : string; | ||||
|   xml_file : TStringList; | ||||
|   find_var : TPerlRegEx; | ||||
|   found_var : boolean; | ||||
| begin | ||||
|  | ||||
|   xml_file := TStringList.Create; | ||||
|   // AV: for compatibility with new Chaotica versions | ||||
|   if not FileExists(ChaoticaPath + '\variation_compatibility.xml') then | ||||
|   begin | ||||
|     xml_file.Add('<variation_compatibility >' + #13#10 + '</variation_compatibility>'); | ||||
|     xml_file.SaveToFile(ChaoticaPath + '\variation_compatibility.xml'); | ||||
|     xml_file.Clear; | ||||
|   end; | ||||
|   xml_file.LoadFromFile(C_GetPathOf('variation_compatibility.xml', false)); | ||||
|   xml := xml_file.Text; | ||||
|   xml_file.Free; | ||||
|  | ||||
|   find_var := TPerlRegEx.Create; | ||||
|   find_var.RegEx := re_var; | ||||
|   find_var.Options := [preSingleLine, preCaseless]; | ||||
|   find_var.Subject := GetStringPart(xml, re_root, 1, ''); | ||||
|   found_var := find_var.Match; | ||||
|  | ||||
|   while found_var do begin | ||||
|     var_name := String(find_var.Groups[1]); | ||||
|     found_var := find_var.MatchAgain; | ||||
|  | ||||
|     if LowerCase(name) = var_name then begin | ||||
|       find_var.Destroy; | ||||
|       Result := true; | ||||
|       Exit; | ||||
|     end; | ||||
|   end; | ||||
|  | ||||
|   find_var.Destroy; | ||||
|   Result := false; | ||||
| end; | ||||
|  | ||||
| function C_IsDllPluginInstalled(filename: string): boolean; | ||||
| var | ||||
|   path : string; | ||||
| begin | ||||
|   path := C_GetPathOf('plugins\' + filename, false); | ||||
|   Result := FileExists(path); | ||||
| end; | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| procedure C_InstallVariation(name: string); | ||||
| var | ||||
|   filename: string; | ||||
| begin | ||||
|   filename := GetFileNameOfVariation(name); | ||||
|  | ||||
|   if (filename = '') then Exit; | ||||
|   if C_IsDllPluginInstalled(filename) then Exit; | ||||
|  | ||||
|   CopyFile(PCHAR(filename), PCHAR(C_GetPathOf('plugins\' + | ||||
|     ExtractFileName(filename), false)), false); | ||||
| end; | ||||
|  | ||||
| procedure C_SyncDllPlugins; | ||||
| var | ||||
|   src_dir: string; | ||||
|   tgt_dir: string; | ||||
|  | ||||
|   searchResult: TSearchRec; | ||||
| begin | ||||
|   src_dir := PluginPath; | ||||
|   tgt_dir := C_GetPathOf('Plugins', false); | ||||
|  | ||||
|   if (not DirectoryExists(src_dir)) then Exit; | ||||
|   if (not DirectoryExists(tgt_dir)) then Exit; | ||||
|   //CreateDir(ChaoticaPath + '\Plugins'); | ||||
|  | ||||
|   // First clear all plugins on Chaotica side | ||||
|   if FindFirst(tgt_dir + '\*.dll', faAnyFile, searchResult) = 0 then | ||||
|   begin | ||||
|     repeat | ||||
|       DeleteFile(PCHAR(tgt_dir + '\' + searchResult.Name)) ; | ||||
|     until (FindNext(searchResult) <> 0); | ||||
|     SysUtils.FindClose(searchResult); | ||||
|   end; | ||||
|  | ||||
|   // Then copy all plugins from Apophysis to Chaotica | ||||
|   if FindFirst(src_dir + '*.dll', faAnyFile, searchResult) = 0 then | ||||
|   begin | ||||
|     repeat | ||||
|       if not C_IsDllPluginBlacklisted(searchResult.Name, false) | ||||
|       then CopyFile( | ||||
|         PCHAR(src_dir + '\' + searchResult.Name), | ||||
|         PCHAR(tgt_dir + '\' + searchResult.Name), | ||||
|         false); | ||||
|     until (FindNext(searchResult) <> 0); | ||||
|     SysUtils.FindClose(searchResult); | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| procedure C_ExecuteChaotica(flamexml: string; plugins: TStringList; usex64: boolean); | ||||
| var | ||||
|   i: integer; | ||||
|   name, fname: string; | ||||
|   fails: TStringList; | ||||
|   txt: TStringList; | ||||
|   fin_usex64: boolean; | ||||
| begin | ||||
|   fails := TStringList.Create; | ||||
|  | ||||
|   {$ifdef Apo7X64} | ||||
|   fin_usex64 := true; | ||||
|   {$else} | ||||
|   fin_usex64 := usex64 and CheckX64; // currently useless... | ||||
|   for i := 0 to plugins.Count - 1 do begin | ||||
|     name := GetFileNameOfVariation(plugins.Strings[i]); | ||||
|     if (name = '') then 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 | ||||
|  | ||||
|     if not C_IsVariationNative(name, fin_usex64) then begin   // not native -> try install | ||||
|       if C_SupportsDllPlugins(fin_usex64) then                // dll unsupported -> fail | ||||
|         fails.Add(plugins.Strings[i]) | ||||
|       else if C_IsDllPluginBlacklisted(name, fin_usex64) then // dll supported and blacklisted -> fail | ||||
|         fails.Add(plugins.Strings[i]); | ||||
|       //else C_InstallVariation(plugins.Strings[i]);         // dll supported and not blacklisted -> install | ||||
|        // ^^^ this is done on Apophysis startup now! | ||||
|     end; | ||||
|   end; | ||||
|   {$endif} | ||||
|  | ||||
|   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); | ||||
|     Exit; | ||||
|   end; | ||||
|  | ||||
|   if (fails.Count > 0) then begin | ||||
|     messagebox(0, PCHAR(TextByKey('main-status-oldchaotica')), | ||||
|       PCHAR('Apophysis AV'), MB_ICONHAND or MB_OK); | ||||
|   end; | ||||
|  | ||||
|   // TODO: add directory cleaning | ||||
|   fname := GetEnvironmentVariable('TEMP') + '\chaotica_export.flame'; | ||||
|   txt := TStringList.Create; | ||||
|  | ||||
|   txt.Text := flamexml; | ||||
|   txt.SaveToFile(fname); | ||||
|  | ||||
|   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); | ||||
| end; | ||||
|  | ||||
| end. | ||||
							
								
								
									
										764
									
								
								Core/Global.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										764
									
								
								Core/Global.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,764 @@ | ||||
| { | ||||
|      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 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 Global; | ||||
|  | ||||
| interface | ||||
|  | ||||
| uses | ||||
|   Windows, SysUtils, Classes, SyncObjs, Controls, Graphics, Math, | ||||
|   cmap, ControlPoint, Xform, CommDlg; | ||||
|  | ||||
| type | ||||
|   EFormatInvalid = class(Exception); | ||||
|   // AV: chanded the name to avoid conflicts with XForm | ||||
|   TMatrix2 = array[0..1, 0..1] of double; | ||||
|  | ||||
| { 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, | ||||
|                             InitialDir, | ||||
|                             Title: string; | ||||
|                             var FileName: string; | ||||
|                             MustExist, | ||||
|                             OverwritePrompt, | ||||
|                             NoChangeDir, | ||||
|                             DoOpen: Boolean): Boolean; | ||||
| procedure LoadThumbnailPlaceholder(ThumbnailSize : integer); | ||||
| function GetEnvVarValue(const VarName: string): string; | ||||
| function Round6(x: double): double; | ||||
| 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} | ||||
|   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); | ||||
| 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 | ||||
|   EnableFinalXform: boolean; | ||||
|   AppPath: string; // Path of application file | ||||
|   OpenFile: string; // Name of currently open file | ||||
|   CanDrawOnResize: boolean; | ||||
|   PreserveWeights: 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; | ||||
|  | ||||
|   // AV: GUI Theme Stuff | ||||
|   CurrentStyle: string; | ||||
|   // theme-aware system colors | ||||
|   WinColor, BrightColor, MidColor, TextColor: TColor; | ||||
|   IsDarkTheme, IsLightMenu: boolean; | ||||
|  | ||||
|   { UPR Options } | ||||
|  | ||||
|   UPRSampleDensity: integer; | ||||
|   UPRFilterRadius: double; | ||||
|   UPROversample: integer; | ||||
|   UPRAdjustDensity: boolean; | ||||
|   UPRColoringIdent: string; | ||||
|   UPRColoringFile: string; | ||||
|   UPRFormulaIdent: string; | ||||
|   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; | ||||
|   ExtEditEnabled, TransformAxisLock, RebuildXaosLinks: boolean; | ||||
|   ShowAllXforms: boolean; | ||||
|   EditorPreviewTransparency: integer; | ||||
|   EnableEditorPreview: boolean; | ||||
|   AllowResetCoefs, AllowResetLinear: boolean; // AV | ||||
|  | ||||
|   { Display } | ||||
|  | ||||
|   defSampleDensity, defPreviewDensity: Double; | ||||
|   defGamma, defBrightness, defVibrancy, defContrast, // AV | ||||
|   defFilterRadius, defGammaThreshold: Double; | ||||
|   defOversample: integer; | ||||
|   FUSE: byte; // AV: moved from ControlPoint and changed to variable | ||||
|   RhombTR, SquareTR, HexTR: single; // AV: tile radii | ||||
|  | ||||
|   { Render } | ||||
|  | ||||
|   renderDensity, renderFilterRadius: double; | ||||
|   renderOversample, renderWidth, renderHeight: integer; | ||||
|   // renderBitsPerSample: integer; | ||||
|   renderPath: string; | ||||
|   JPEGQuality: integer; | ||||
|   renderFileFormat: integer; | ||||
|   InternalBitsPerSample: integer; | ||||
|   EmbedFlame, SaveInFlame: boolean;  // AV | ||||
|  | ||||
|   NrTreads: Integer; | ||||
|   UseNrThreads: byte;  // AV: currently holds Nr CPU cores | ||||
|  | ||||
|   PNGTransparency: integer; | ||||
|   ShowTransparency: boolean; | ||||
|  | ||||
|   MainPreviewScale: double; | ||||
|   ExtendMainPreview: boolean; | ||||
|  | ||||
|   (* | ||||
|   StoreEXIF : boolean; | ||||
|   StoreParamsEXIF : boolean; | ||||
|   ExifAuthor : string; | ||||
|    *) | ||||
|  | ||||
|   { Defaults } | ||||
|  | ||||
|   LastOpenFile: string; | ||||
|   LastOpenFileEntry: integer; | ||||
|   RememberLastOpenFile: boolean; | ||||
|   UseSmallThumbnails: boolean; | ||||
|   ClassicListMode: boolean; | ||||
|   ConfirmDelete: boolean; // Flag confirmation of entry deletion | ||||
|   OldPaletteFormat: boolean; | ||||
|   ConfirmExit: boolean; | ||||
|   ConfirmStopRender: boolean; | ||||
|   ConfirmClearScript: boolean; | ||||
|   SavePath, SmoothPalettePath: string; | ||||
|   RandomPrefix, RandomDate: string; | ||||
|   RandomIndex: integer; | ||||
|   FlameFile, GradientFile, GradientEntry, FlameEntry: string; | ||||
|   ParamFolder: string; | ||||
|   prevLowQuality, prevMediumQuality, prevHighQuality: double; | ||||
|   defSmoothPaletteFile: 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; | ||||
|   defFlameFile: string; | ||||
|   defScriptFile: string; // AV | ||||
|   SetEngLayout: boolean; // AV | ||||
|   ScreenShotPath: string;  // AV | ||||
|   AutoSaveXML, ApplyFlatten: boolean; // AV | ||||
|  | ||||
|   PlaySoundOnRenderComplete: boolean; | ||||
|   RenderCompleteSoundFile: string; | ||||
|  | ||||
|   SaveIncompleteRenders: boolean; | ||||
|   ShowRenderStats, ShowRenderImage: boolean; | ||||
|   LowerRenderPriority: boolean; | ||||
|  | ||||
|   SymmetryType: integer; | ||||
|   SymmetryOrder: integer; | ||||
|   SymmetryNVars: integer; | ||||
|   Variations: array of boolean; | ||||
|   FavouriteVariations: array of boolean; | ||||
|  | ||||
|   MainForm_RotationMode: byte; // integer; | ||||
|   PreserveQuality: boolean; | ||||
|   FlameEnumMode: byte;  // AV | ||||
|  | ||||
|   { For random gradients } | ||||
|  | ||||
|   MinNodes, MaxNodes, MinHue, MaxHue, MinSat, MaxSat, MinLum, MaxLum: integer; | ||||
|   //ReferenceMode: integer; | ||||
|   BatchSize: Integer; | ||||
|   // Compatibility: integer; //0 = original, 1 = Drave's | ||||
|   Favorites: TStringList; | ||||
|   Script: string; | ||||
|   ScriptPath: string; | ||||
|   // SheepServer, SheepNick, SheepURL, SheepPW,  | ||||
|   flam3Path, helpPath: string; | ||||
|   ExportBatches, ExportOversample, ExportWidth, ExportHeight, ExportFileFormat: Integer; | ||||
|   ExportFilter, ExportDensity: Double; | ||||
|   ExportEstimator, ExportEstimatorMin, ExportEstimatorCurve: double; | ||||
|   ExportJitters: integer; | ||||
|   ExportGammaTreshold: double; | ||||
|   OpenFileType: TFileType; | ||||
| //  ResizeOnLoad: Boolean; | ||||
|   ShowProgress: Boolean; | ||||
|   defLibrary: string; | ||||
|   LimitVibrancy: Boolean; | ||||
|   DefaultPalette: TColorMap; | ||||
|  | ||||
|   ChaoticaPath: string; | ||||
|   UseX64IfPossible: boolean; | ||||
|  | ||||
|   AutoOpenLog: Boolean; | ||||
|   AutoSaveEnabled: Boolean; | ||||
|   AutoSaveFreq: integer; | ||||
|   AutoSavePath: string; | ||||
|  | ||||
|   LineCenterColor : integer; | ||||
|   LineThirdsColor : integer; | ||||
|   LineGRColor : integer; | ||||
|   EnableGuides : boolean; | ||||
|  | ||||
| implementation | ||||
|  | ||||
| function GetEnvVarValue(const VarName: string): string; | ||||
| var | ||||
|   BufSize: Integer;  // buffer size required for value | ||||
| begin | ||||
|   // Get required buffer size (inc. terminal #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); | ||||
|   end | ||||
|   else | ||||
|     // No such environment variable | ||||
|     Result := ''; | ||||
| end; | ||||
|  | ||||
| procedure LoadThumbnailPlaceholder(ThumbnailSize : integer); | ||||
| var | ||||
|   placeholderIcon: TBitmap; | ||||
| const | ||||
|   pi_width = 48; | ||||
|   pi_height = 48; | ||||
| begin | ||||
|   placeholderIcon := TBitmap.Create; | ||||
|   placeholderIcon.Handle := LoadBitmap(hInstance, 'THUMB_PLACEHOLDER'); | ||||
|   // AV:  replaced a local variable by the global one | ||||
|   ThumbnailPlaceholder.PixelFormat := pf32bit; | ||||
|   ThumbnailPlaceholder.HandleType := bmDIB; | ||||
|   ThumbnailPlaceholder.Width := ThumbnailSize; | ||||
|   ThumbnailPlaceholder.Height := ThumbnailSize; | ||||
|  | ||||
|   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); | ||||
|   end; | ||||
|  | ||||
|   placeholderIcon.Free; | ||||
| end; | ||||
|  | ||||
| function MiddleColor(const clOne, clTwo: TColor): TColor;   // AV | ||||
| begin | ||||
|   Result := (((clOne and $ff) + (clTwo and $ff)) shr 1 ) + | ||||
|     ((((clOne shr 8) and $ff) + ((clTwo shr 8) and $ff))  shr 1 ) shl 8 + | ||||
|     ((((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 | ||||
|   // --Z-- this is ridiculous: | ||||
|   //   Result := StrToFloat(Format('%.6f', [x])); | ||||
|   // and yes, this is REALLY ugly :-\ | ||||
|   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 | ||||
|   IsWow64Process := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process'); | ||||
|  | ||||
|   Wow64Process := False; | ||||
|   if Assigned(IsWow64Process) then | ||||
|     Wow64Process := IsWow64Process(GetCurrentProcess, Wow64Process) and Wow64Process; | ||||
|  | ||||
|   Result := Wow64Process; | ||||
| end; | ||||
|  | ||||
| function ReplaceStr(Str, SearchStr, ReplaceStr: string): string; | ||||
| begin | ||||
|   while Pos(SearchStr, Str) <> 0 do | ||||
|   begin | ||||
|     Insert(ReplaceStr, Str, Pos(SearchStr, Str)); | ||||
|     system.Delete(Str, Pos(SearchStr, Str), Length(SearchStr)); | ||||
|   end; | ||||
|   Result := Str; | ||||
| end; | ||||
|  | ||||
| function SplitFilter(const fText: String; const fSep: Char; fTrim: Boolean=false; fQuotes: Boolean=false):  TStringList; | ||||
| var vI: Integer; | ||||
|     vBuffer: String; | ||||
|     vOn: Boolean; | ||||
| begin | ||||
|   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 | ||||
|     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)); | ||||
|       Result.Add(vBuffer); | ||||
|       vBuffer:=''; | ||||
|     end; | ||||
|     if fQuotes then | ||||
|     begin | ||||
|       if fText[vI]='"' then | ||||
|       begin | ||||
|         vOn:=Not(vOn); | ||||
|         Continue; | ||||
|       end; | ||||
|       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]; | ||||
|   end; | ||||
|   if vBuffer<>'' then | ||||
|   begin | ||||
|     if fTrim then vBuffer:=Trim(vBuffer); | ||||
|     Result.Add(vBuffer); | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function OpenSaveFileDialog(Parent: TWinControl; | ||||
|                             const DefExt, | ||||
|                             Filter, | ||||
|                             InitialDir, | ||||
|                             Title: string; | ||||
|                             var FileName: string; | ||||
|                             MustExist, | ||||
|                             OverwritePrompt, | ||||
|                             NoChangeDir, | ||||
|                             DoOpen: Boolean): Boolean; | ||||
| // uses commdlg | ||||
| var | ||||
|   ofn: TOpenFileName; | ||||
|   szFile: array[0..260] of Char; | ||||
|   fa, fa2: TStringList; | ||||
|   h,i,j,k,c : integer; | ||||
|   cs, s : string; | ||||
| begin | ||||
|   Result := False; | ||||
|   FillChar(ofn, SizeOf(TOpenFileName), 0); | ||||
|   with ofn do | ||||
|   begin | ||||
|     lStructSize := SizeOf(TOpenFileName); | ||||
|     hwndOwner := Parent.Handle; | ||||
|     lpstrFile := szFile; | ||||
|     nMaxFile := SizeOf(szFile); | ||||
|     if (Title <> '') then | ||||
|       lpstrTitle := PChar(Title); | ||||
|     if (InitialDir <> '') then | ||||
|       lpstrInitialDir := PChar(InitialDir); | ||||
|     StrPCopy(lpstrFile, FileName); | ||||
|     lpstrFilter := PChar(ReplaceStr(Filter, '|', #0)+#0#0); | ||||
|     fa := splitFilter(Filter, '|'); | ||||
|  | ||||
|     k := 0; | ||||
|     c := (fa.Count div 2); | ||||
|     for i := 0 to c - 1 do begin | ||||
|       j := 2 * i + 1; | ||||
|       cs := LowerCase(fa.Strings[j]); | ||||
|       fa2 := splitFilter(cs, ';'); | ||||
|       for h := 0 to fa2.Count - 1 do begin | ||||
|         cs := fa2.Strings[h]; | ||||
|         s := '*.' + LowerCase(DefExt); | ||||
|         if (cs = s) then k := i; | ||||
|       end; | ||||
|       fa2.Free;  //AV: fixed multiple memory leaks! | ||||
|     end; | ||||
|     fa.Free; // AV: fixed memory leak! | ||||
|  | ||||
|     nFilterIndex := k + 1; | ||||
|     if DefExt <> '' then | ||||
|       lpstrDefExt := PChar(DefExt); | ||||
|   end; | ||||
|  | ||||
|   if MustExist then ofn.Flags := ofn.Flags or OFN_FILEMUSTEXIST; | ||||
|   if OverwritePrompt then ofn.Flags := ofn.Flags or OFN_OVERWRITEPROMPT; | ||||
|   if NoChangeDir then ofn.Flags := ofn.Flags or OFN_NOCHANGEDIR; | ||||
|  | ||||
|   if DoOpen then | ||||
|   begin | ||||
|     if GetOpenFileName(ofn) then | ||||
|     begin | ||||
|       Result := True; | ||||
|       FileName := StrPas(szFile); | ||||
|     end; | ||||
|   end | ||||
|   else | ||||
|   begin | ||||
|     if GetSaveFileName(ofn) then | ||||
|     begin | ||||
|       Result := True; | ||||
|       FileName := StrPas(szFile); | ||||
|     end; | ||||
|   end | ||||
| end; // function OpenSaveFileDialog | ||||
|  | ||||
| end. | ||||
|  | ||||
							
								
								
									
										1127
									
								
								Core/Translation.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1127
									
								
								Core/Translation.pas
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										356
									
								
								Core/XFormMan.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										356
									
								
								Core/XFormMan.pas
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,356 @@ | ||||
| { | ||||
|      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 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 XFormMan; | ||||
|  | ||||
| interface | ||||
|  | ||||
| uses | ||||
|   BaseVariation, SysUtils, Forms, Windows; | ||||
|  | ||||
| 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); | ||||
| function GetNrRegisteredVariations: integer; | ||||
| function GetRegisteredVariation(const Index: integer): TVariationLoader; | ||||
| 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; | ||||
|  | ||||
| implementation | ||||
|  | ||||
| uses | ||||
|   Classes; | ||||
|  | ||||
| var | ||||
|   VariationList: TList; | ||||
|   VariableNames: TStringlist; | ||||
|   loaderNum : integer; | ||||
|   Variable2VariationIndex : array of integer; | ||||
|   FNToVNList : array of TFNToVN; | ||||
|   FNToVNCount: integer; | ||||
|  | ||||
| procedure InitializeXFormMan; | ||||
| begin | ||||
|   VariationList := TList.Create; | ||||
|   VariableNames := TStringlist.create; | ||||
|   SetLength(Variable2VariationIndex,0); | ||||
|   SetLength(FNToVNList, 0); | ||||
|   FNToVNCount := 0; | ||||
| end; | ||||
|  | ||||
| procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean); | ||||
| const | ||||
|   supports3D_arr: array[0..NRLOCVAR-1] of boolean = ( | ||||
|     true, //'linear', | ||||
|     true, //'flatten', | ||||
|     true, //'pre_blur3D', | ||||
|     true, //'spherical', | ||||
|     true, //'swirl', | ||||
|     true, //'horseshoe', | ||||
|     true, //'polar', | ||||
|     true, //'disc', | ||||
|     true, //'spiral', | ||||
|     true, //'hyperbolic', | ||||
|     true, //'diamond', | ||||
|     true, //'eyefish', | ||||
|     true, //'bubble', | ||||
|     true, //'cylinder', | ||||
|     true, //'noise', | ||||
|     true, //'blur', | ||||
|     false, //'gaussian_blur', | ||||
|     true, //'zblur', | ||||
|     true, //'blur3D', | ||||
|     false, //'pre_blur', | ||||
|     true, //'pre_zscale', | ||||
|     true, //'pre_ztranslate', | ||||
|     true, //'pre_rotate_x', | ||||
|     true, //'pre_rotate_y', | ||||
|     true, //'zscale', | ||||
|     true, //'ztranslate', | ||||
|     true, //'zcone', | ||||
|     true, //'post_rotate_x', | ||||
|     true, //'post_rotate_y', | ||||
|     false, //'post_mirror_x', | ||||
|     false, //'post_mirror_y', | ||||
|     true, //'post_mirror_z', | ||||
|     true, //'hemisphere', | ||||
|     true, //'cross', | ||||
|     true, //'pyramid' | ||||
|     true  // polar2 | ||||
|     ); | ||||
|  supportsDC_arr: array[0..NRLOCVAR-1] of boolean = ( | ||||
|     false, //'linear', | ||||
|     false, //'flatten', | ||||
|     false, //'pre_blur3D', | ||||
|     false, //'spherical', | ||||
|     false, //'swirl', | ||||
|     false, //'horseshoe', | ||||
|     false, //'polar', | ||||
|  | ||||
|     false, //'disc', | ||||
|     false, //'spiral', | ||||
|     false, //'hyperbolic', | ||||
|     false, //'diamond', | ||||
|  | ||||
|     false, //'eyefish', | ||||
|     false, //'bubble', | ||||
|     false, //'cylinder', | ||||
|     false, //'noise', | ||||
|     false, //'blur', | ||||
|     false, //'gaussian_blur', | ||||
|     false, //'zblur', | ||||
|     false, //'blur3D', | ||||
|  | ||||
|     false, //'pre_blur', | ||||
|     false, //'pre_zscale', | ||||
|     false, //'pre_ztranslate', | ||||
|     false, //'pre_rotate_x', | ||||
|     false, //'pre_rotate_y', | ||||
|  | ||||
|     false, //'zscale', | ||||
|     false, //'ztranslate', | ||||
|     false, //'zcone', | ||||
|  | ||||
|     false, //'post_rotate_x', | ||||
|     false, //'post_rotate_y' | ||||
|  | ||||
|     false, //'post_mirror_x', | ||||
|     false, //'post_mirror_y', | ||||
|     false, //'post_mirror_z', | ||||
|  | ||||
|     false, //'hemisphere', | ||||
|     false, //'cross', | ||||
|     false, //'pyramid' | ||||
|     false //  polar2 | ||||
|     ); | ||||
| var | ||||
|   varl : TVariationLoader; | ||||
| 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]; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
|  | ||||
| procedure DestroyXFormMan; | ||||
| var i: integer; | ||||
| begin | ||||
|   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.Free; | ||||
|  | ||||
|   Finalize(Variable2VariationIndex); | ||||
|   Finalize(FNToVNList); | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function NrVar: integer; | ||||
| begin | ||||
|   Result := NRLOCVAR + VariationList.Count; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| function GetVariationIndexFromVariableNameIndex(const Index: integer): integer; | ||||
| begin | ||||
|   if (Index < 0) or (Index > High(Variable2VariationIndex)) then | ||||
|     Result := -1 | ||||
|   else | ||||
|     Result := Variable2VariationIndex[Index]; | ||||
| end; | ||||
|  | ||||
| function Varnames(const index: integer): String; | ||||
| const | ||||
|   cvarnames: array[0..NRLOCVAR-1] of string = ( | ||||
|     'linear', | ||||
|     'flatten', | ||||
|     'pre_blur3D', | ||||
|     'spherical', | ||||
|     'swirl', | ||||
|     'horseshoe', | ||||
|     'polar', | ||||
| //    'handkerchief', | ||||
| //    'heart', | ||||
|     'disc', | ||||
|     'spiral', | ||||
|     'hyperbolic', | ||||
|     'diamond', | ||||
| //    'ex', | ||||
| //    'julia', | ||||
| //    'bent', | ||||
| //    'waves', | ||||
| //    'fisheye', | ||||
| //    'popcorn', | ||||
| //    'exponential', | ||||
| //    'power', | ||||
| //    'cosine', | ||||
| //    'rings', | ||||
| //    'fan', | ||||
|     'eyefish', | ||||
|     'bubble', | ||||
|     'cylinder', | ||||
|     'noise', | ||||
|     'blur', | ||||
|     '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' | ||||
|     ); | ||||
| begin | ||||
|   if Index < NRLOCVAR then | ||||
|     Result := cvarnames[Index] | ||||
|   else | ||||
|     Result := TVariationLoader(VariationList[Index - NRLOCVAR]).GetName; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function GetVariationIndex(const str: string): integer; | ||||
| var | ||||
|   i: integer; | ||||
| begin | ||||
|   i := NRVAR-1; | ||||
|   while (i >= 0) and (Varnames(i) <> str) do Dec(i); | ||||
|   Result := i; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| procedure RegisterVariationFile(filename, name: string); | ||||
| begin | ||||
|   FNToVNCount := FNToVNCount + 1; | ||||
|   SetLength(FNToVNList, FNToVNCount); | ||||
|   FNToVNList[FNToVNCount - 1].FileName := filename; | ||||
|   FNToVNList[FNToVNCount - 1].VarName := name; | ||||
| end; | ||||
|  | ||||
| function GetFileNameOfVariation(name: string): string; | ||||
| var i: integer; | ||||
| begin | ||||
|   for i := 0 to FNToVNCount - 1 do begin | ||||
|     if FNToVNList[i].VarName = name then begin | ||||
|       Result := FNToVNList[i].FileName; | ||||
|       Exit; | ||||
|     end; | ||||
|   end; | ||||
|   Result := ''; | ||||
| end; | ||||
|  | ||||
| procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean); | ||||
| var | ||||
|   i: integer; | ||||
|   prevNumVariables:integer; | ||||
| begin | ||||
|   OutputDebugString(PChar(Variation.GetName)); | ||||
|  | ||||
|   VariationList.Add(Variation); | ||||
|   Variation.Supports3D := supports3D; | ||||
|   Variation.SupportsDC := supportsDC; | ||||
|  | ||||
|   prevNumVariables := GetNrVariableNames; | ||||
|   setLength(Variable2VariationIndex, prevNumVariables + Variation.GetNrVariables); | ||||
|   for i := 0 to Variation.GetNrVariables - 1 do begin | ||||
|     VariableNames.Add(Variation.GetVariableNameAt(i)); | ||||
|     Variable2VariationIndex[prevNumVariables + i] := NrVar-1; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function GetNrRegisteredVariations: integer; | ||||
| begin | ||||
|   Result := VariationList.count; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function GetRegisteredVariation(const Index: integer): TVariationLoader; | ||||
| begin | ||||
|   Result := TVariationLoader(VariationList[Index]); | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function GetNrVariableNames: integer; | ||||
| begin | ||||
|   Result := VariableNames.Count; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| function GetVariableNameAt(const Index: integer): string; | ||||
| begin | ||||
|   Result := VariableNames[Index]; | ||||
| end; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| initialization | ||||
|   InitializeXFormMan; | ||||
|    | ||||
| finalization | ||||
|   DestroyXFormMan; | ||||
|  | ||||
| end. | ||||
		Reference in New Issue
	
	Block a user
	 Alice Vital
					Alice Vital