xfractint-20.4.10.orig/0000755000000000000000000000000011456315520011507 5ustar xfractint-20.4.10.orig/ifs/0000755000000000000000000000000011456314746012301 5ustar xfractint-20.4.10.orig/ifs/fractint.ifs0000644000000000000000000001310610150633601014577 0ustar binary { ; comment allowed here ; and here .5 .0 .0 .5 -2.563477 -0.000003 .333333 ; also comment allowed here .5 .0 .0 .5 2.436544 -0.000003 .333333 .0 -.5 .5 .0 4.873085 7.563492 .333333 } coral { .307692 -.531469 -.461538 -.293706 5.401953 8.655175 .40 .307692 -.076923 .153846 -.447552 -1.295248 4.152990 .15 .000000 .545455 .692308 -.195804 -4.893637 7.269794 .45 } crystal { .696970 -.481061 -.393939 -.662879 2.147003 10.310288 .747826 .090909 -.443182 .515152 -.094697 4.286558 2.925762 .252174 } dragon { .824074 .281482 -.212346 .864198 -1.882290 -0.110607 .787473 .088272 .520988 -.463889 -.377778 0.785360 8.095795 .212527 } fern { 0 0 0 .16 0 0 .01 .85 .04 -.04 .85 0 1.6 .85 .2 -.26 .23 .22 0 1.6 .07 -.15 .28 .26 .24 0 .44 .07 } 3dfern (3D) { .00 .00 0 .0 .18 .0 0 0.0 0.00 0 0.0 0 .01 .85 .00 0 .0 .85 .1 0 -0.1 0.85 0 1.6 0 .85 .20 -.20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07 -.20 .20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07 } floor { .0 -.5 .5 .0 -1.732366 3.366182 .333333 .5 .0 .0 .5 -0.027891 5.014877 .333333 .0 .5 -.5 .0 1.620804 3.310401 .333333 } koch3 { .307692 -.000000 .000000 .294118 4.119164 1.604278 .151515 .192308 -.205882 .653846 .088235 -0.688840 5.978916 .253788 .192308 .205882 -.653846 .088235 0.668580 5.962514 .253788 .307692 -.000000 .000000 .294118 -4.136530 1.604278 .151515 .384615 -.000000 .000000 -.294118 -0.007718 2.941176 .189394 } spiral { .787879 -.424242 .242424 .859848 1.758647 1.408065 .895652 -.121212 .257576 .151515 .053030 -6.721654 1.377236 .052174 .181818 -.136364 .090909 .181818 6.086107 1.568035 .052174 } swirl5 { .745455 -.459091 .406061 .887121 1.460279 0.691072 .912675 -.424242 -.065152 -.175758 -.218182 3.809567 6.741476 .087325 } tree { 0 0 0 .5 0 0 .05 .42 -.42 .42 .42 0 .2 .4 .42 .42 -.42 .42 0 .2 .4 .1 0 0 .1 0 .2 .15 } triangle { .5 0 0 .5 0 0 .33 .5 0 0 .5 0 1 .33 .5 0 0 .5 1 1 .34 } zigzag2 { -.632407 -.614815 -.545370 .659259 3.840822 1.282321 .888128 -.036111 .444444 .210185 .037037 2.071081 8.330552 .111872 } 3dTetrahedron (3D) { ; by Alex Matulich 0.50 0 0 0 0.50 0 0 0 0.50 0.00 0.00 1.00 0.25 0.50 0 0 0 0.50 0 0 0 0.50 0.00 0.87 -0.50 0.25 0.50 0 0 0 0.50 0 0 0 0.50 -0.87 -0.50 -0.50 0.25 0.50 0 0 0 0.50 0 0 0 0.50 0.87 -0.50 -0.50 0.25 } 3d5Tetrahedron (3D) { ; by Alex Matulich 0.44 0 0 0 0.44 0 0 0 0.44 0.00 0.00 1.00 0.20 0.44 0 0 0 0.44 0 0 0 0.44 0.00 0.87 -0.50 0.20 0.44 0 0 0 0.44 0 0 0 0.44 -0.87 -0.50 -0.50 0.20 0.44 0 0 0 0.44 0 0 0 0.44 0.87 -0.50 -0.50 0.20 0.44 0 0 0 0.44 0 0 0 0.44 0.00 0.00 0.00 0.20 } 3dHexahedron (3D) { ; by Alex Matulich 0.44 0 0 0 0.44 0 0 0 0.44 0.00 0.00 0.90 0.20 0.44 0 0 0 0.44 0 0 0 0.44 0.87 -0.50 0.00 0.20 0.44 0 0 0 0.44 0 0 0 0.44 -0.87 -0.50 0.00 0.20 0.44 0 0 0 0.44 0 0 0 0.44 0.00 1.00 0.00 0.20 0.44 0 0 0 0.44 0 0 0 0.44 0.00 0.00 -0.90 0.20 } 3dCube (3D) { ; by Alex Matulich 0.35 0 0 0 0.35 0 0 0 0.35 1.00 1.00 1.00 0.12 0.35 0 0 0 0.35 0 0 0 0.35 1.00 1.00 -1.00 0.13 0.35 0 0 0 0.35 0 0 0 0.35 1.00 -1.00 1.00 0.12 0.35 0 0 0 0.35 0 0 0 0.35 1.00 -1.00 -1.00 0.13 0.35 0 0 0 0.35 0 0 0 0.35 -1.00 1.00 1.00 0.12 0.35 0 0 0 0.35 0 0 0 0.35 -1.00 1.00 -1.00 0.13 0.35 0 0 0 0.35 0 0 0 0.35 -1.00 -1.00 1.00 0.12 0.35 0 0 0 0.35 0 0 0 0.35 -1.00 -1.00 -1.00 0.13 } 3dOctahedron (3D) { ; by Alex Matulich 0.40 0 0 0 0.40 0 0 0 0.40 0.00 0.00 1.00 0.17 0.40 0 0 0 0.40 0 0 0 0.40 1.00 0.00 0.00 0.16 0.40 0 0 0 0.40 0 0 0 0.40 0.00 1.00 0.00 0.17 0.40 0 0 0 0.40 0 0 0 0.40 -1.00 0.00 0.00 0.17 0.40 0 0 0 0.40 0 0 0 0.40 0.00 -1.00 0.00 0.16 0.40 0 0 0 0.40 0 0 0 0.40 0.00 0.00 -1.00 0.17 } 3dDuodecahedron (3D) { ; by Alex Matulich 0.28 0 0 0 0.28 0 0 0 0.28 0.00 0.00 0.96 0.09 0.28 0 0 0 0.28 0 0 0 0.28 0.00 0.85 0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 0.81 0.26 0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 -0.81 0.26 0.43 0.09 0.28 0 0 0 0.28 0 0 0 0.28 0.50 -0.69 0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 -0.50 -0.69 0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 0.50 0.69 -0.43 0.09 0.28 0 0 0 0.28 0 0 0 0.28 -0.50 0.69 -0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 0.81 -0.26 -0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 -0.81 -0.26 -0.43 0.09 0.28 0 0 0 0.28 0 0 0 0.28 0.00 -0.85 -0.43 0.08 0.28 0 0 0 0.28 0 0 0 0.28 0.00 0.00 -0.96 0.08 } fractint { ; by Pieter Branderhorst 0.00 -0.11 0.22 0.00 -6.25 4.84 0.06 0.11 0.02 0.00 0.11 -6.30 5.99 0.03 0.06 0.02 0.00 0.10 -6.25 4.51 0.02 0.00 -0.11 0.22 0.00 -4.34 4.84 0.06 0.08 0.00 0.00 0.11 -4.50 5.99 0.02 0.00 0.11 -0.08 0.00 -4.30 6.15 0.02 -0.09 0.00 -0.01 -0.13 -4.15 5.94 0.02 0.06 0.11 -0.13 0.00 -4.69 4.15 0.04 0.03 -0.11 0.23 0.11 -2.26 4.43 0.07 0.03 0.11 -0.25 0.00 -2.57 4.99 0.07 0.06 0.00 0.00 0.11 -2.40 4.46 0.02 0.00 0.11 -0.19 0.00 -1.62 4.99 0.06 0.09 -0.01 0.00 0.10 -0.58 2.96 0.03 -0.09 0.00 0.00 -0.11 -0.65 7.10 0.03 0.12 0.00 -0.00 0.11 1.24 6.00 0.03 0.00 0.11 -0.22 0.00 0.68 4.80 0.06 -0.12 0.00 0.00 -0.13 6.17 7.18 0.03 0.00 -0.11 0.22 0.00 6.78 4.84 0.06 0.00 0.08 -0.25 0.02 2.21 4.95 0.07 0.00 -0.11 0.22 0.00 4.10 4.84 0.06 0.00 -0.11 0.22 0.00 5.25 5.23 0.06 0.08 0.11 -0.25 0.00 3.57 4.99 0.08 } xfractint-20.4.10.orig/ifs/fract205.ifs0000644000000000000000000000606210330023321014306 0ustar bmc0884x {; Anthony Hanmer 27/1/2005, Designed with BRAZIL: ; One of my very best "BMC spirals", originating from play with ; Blancmange Curve variations ; a.hanmer@gmail.com ; More work & details to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ -0.5000000 0.0000000 -0.5000000 0.5000000 3.0000000 2.5000000 0.1428818 0.4999245 0.4999245 -0.4999245 0.4999245 -2.5005285 2.5003775 0.2856773 0.4999245 0.4999245 -0.4999245 0.4999245 -2.5005285 2.5003775 0.2856773 -0.5000000 0.0000000 0.0000000 -0.5000000 -3.0000000 4.5000000 0.1428818 0.5000000 0.0000000 0.0000000 -0.5000000 3.0000000 4.5000000 0.1428818 } DC022b6c {; Tony Hanmer 3/2002, Designed with Brazil: ; Dragon Curve variation, a favourite, showing play with linear elements ; a.hanmer@gmail.com ; More work & details to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ 0.3535534 0.3535534 0.3535534 0.3535534 -3.5251263 4.9362330 -0.1428571 0.4999245 -0.4999245 0.4999245 0.4999245 0.1356225 2.4994715 0.4901932 -0.4999245 -0.4999245 0.4999245 -0.4999245 4.2405285 7.4996225 0.4901932 0.001 0 0 0.5 5.586 2.284 0.0098068 0.5 0 0 0.001 -3 1.057 0.0098068 } Sq0002d {; Anthony Hanmer 18/12/2003, Designed with BRAZIL: ; One of my best probability-altered Squares ; a.hanmer@gmail.com ; More work & details to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ 0.3330000 0.0000000 0.0000000 0.3330000 -4.0020000 -0.6670000 0.1108890 0.3330000 0.0000000 0.0000000 0.6670000 -4.0020000 3.6630000 0.2921110 -0.6670000 0.0000000 0.0000000 0.3330000 1.9980000 -0.6670000 0.1521110 -0.6670000 0.0000000 0.0000000 -0.6670000 1.9980000 10.3330000 0.4448890 } sq441 {; Tony Hanmer 5/2002, Designed with BRAZIL: ; sq079 variation, unaltered post-Brazil ; One of my best probability-altered Squares: Temples ; a.hanmer@gmail.com ; More work & details to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ -0.25 0 0 0.75 4.5 -0.25 0.1153846 0.25 0 0 -0.75 -4.5 10.25 0.1153846 0.75 0 0 0.25 -1.5 -0.75 0.1153846 0.5 0 0 0.5 0 2.5 0.1538462 -0.25 0 0 0.75 4.5 -0.25 0.1153846 -0.5 0 0 0.5 0 2.5 0.1538462 -0.75 0 0 -0.25 1.5 10.75 0.1153846 -0.75 0 0 -0.25 -1.5 1.75 0.1153846 } td081 {; Tony Hanmer 4/2002, Designed with BRAZIL: ; One of my best TwinDragon variations, showing play with linear elements ; a.hanmer@gmail.com ; More work & details to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ -0.4999245 0.4999245 -0.4999245 -0.4999245 -6.0996225 7.5005285 0.2403469 -1 0 0 -1 0 10 0.4808390 0.4999245 -0.4999245 0.4999245 0.4999245 -1.1003775 2.4994715 0.2403469 -0.001 0 0 -0.1 0.594 5.5 0.0048084 0 0.1 -0.001 0 -0.5 5.594 0.0048084 -0.001 0 0 -0.1 -0.606 5.5 0.0048084 0 0.1 -0.001 0 -0.5 4.394 0.0048084 0.0007071 0.0997021 -0.0007071 0.0997021 -1.0960553 5.0954594 0.0048084 -0.0007071 0.0997021 -0.0007071 -0.0997021 -1.1045406 4.8960553 0.0048084 -0.0007071 0.0997021 -0.0007071 -0.0997021 0.0954594 6.0960553 0.0048084 0.0007071 0.0997021 -0.0007071 0.0997021 0.1039447 3.8954594 0.0048084 } xfractint-20.4.10.orig/lsystem/0000755000000000000000000000000011456314752013215 5ustar xfractint-20.4.10.orig/lsystem/penrose.l0000644000000000000000000001223010150633601015026 0ustar { Generation of Penrose aperiodic tilings Thanks to Herb Savage, who showed it was possible to generate those tilings with L-systems and Fractint. Based on decomposition of tilings described in Tilings and Pattern, by Branko Grunbaum and G.C. Shepard, W.H. Freeman and Company, chapter 10 Philippe Hurbain 49 rue Jules Fossier 95380 LOUVRES FRANCE } Penrose1 { ;; by Herb Savage ;; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ;; Roger Penrose's rhombuses Angle 10 Axiom +WF--XF---YF--ZF W=YF++ZF----XF[-YF----WF]++ X=+YF--ZF[---WF--XF]+ Y=-WF++XF[+++YF++ZF]- Z=--YF++++WF[+ZF++++XF]--XF F= } Losanges { ;; by Philippe Hurbain ;; Penrose's rhombuses, generated by decomposition rules ;; x generate the fat rhombus, y the thin one ;; Individualization of rhombuses allows easy coloring ;; 0.618034 is ({5-1)/2 Angle 10 Axiom x x=@.618034+f[|y]--f[|x][|+@.618034g@i.618034x]---[x]f--[y]f y=@.618034++[x]f|+f[|y]-[y]f|+f[|x] f=g } PentaColor { ;; by Philippe Hurbain ;; Simple coloring of Penrose's rhombuses, showing pentagons Angle 20 Axiom c04[x]++++[x]++++[x]++++[x]++++[x] x=@.618034++f[c10@1.1755-------f][|y]----f[|x] x=[|++@.618034g@i.618034x]------[x]f----[y]f y=@.618034++++[x]f|++f[|y]--[y]f|++f[|x] f=g } Penta { ;; by Philippe Hurbain ;; Same as PentaColor, but showing only the coloring Angle 20 Axiom [x]++++[x]++++[x]++++[x]++++[x] x=@.618034++g[@1.1755-------f][|y]----g[|x] x=[|++@.618034g@i.618034x]------[x]g----[y]g y=@.618034++++[x]g|++g[|y]--[y]g|++g[|x] f=g } Kites&Darts { ;; by Philippe Hurbain ;; Penrose's kites and darts ;; k generates the kite, a generates the dart Angle 10 Axiom k k=+[@.618034a]f@.618034---[-k]f-f---[-k]@i.618034f[@.618034|a] a=[@.618034k]+f@.618034[|a]----f+f----[a]@i.618034f f=g } Kites&Darts2 { ;; by Philippe Hurbain ;; Penrose's kites and darts, with kites seed Angle 10 Axiom [k]++[k]++[k]++[k]++[k] k=+[@.618034a]f@.618034---[-k]f-f---[-k]@i.618034f[@.618034|a] a=[@.618034k]+f@.618034[|a]----f+f----[a]@i.618034f f=g } Kites&Darts3 { ;; by Philippe Hurbain ;; Penrose's kites and darts, with darts seed Angle 10 Axiom [a]++[a]++[a]++[a]++[a] k=+[@.618034a]f@.618034---[-k]f-f---[-k]@i.618034f[@.618034|a] a=[@.618034k]+f@.618034[|a]----f+f----[a]@i.618034f f=g } Kites&DartsColor { ;; by Philippe Hurbain ;; Penrose's kites and darts, with serpentine coloring Angle 10 Axiom c4[k]++[k]++[k]++[k]++[k] k=+[@.618034a[g---@.618c10f][--g+++@.618c10f]] k=f@.618034---[-k]f-f---[-k]@i.618034f[@.618034|a] a=[@.618034k]+f@.618034[|a][|g++@.382c10f]----f+ a=f----[a][g--@.382c10f]@i.618034f f=g } AmmannPolyColor { ;; by Philippe Hurbain ;; Ammann's coloring of Penrose's rhombuses, giving an ;; aperiodic tiling of 2 pentagons and 1 hexagon Angle 10 Axiom c1x x=@.618034/36[c3\9@.66D]D[c3/196.5@.363D][/180y]\72D[/180x] x=[\144@.618034M@i.618034x]\108[c3\36@.509D@1.18\30D][x]D[c3\153@.66D]\72[y]D y=@.618034/72[x][c3\36@.509D]D\144[c3\9@.66D]D[/180y][c3/196.5@.363D] y=\36[y]D\144D[/180x] D=M } AmmannPoly { ;; by Philippe Hurbain ;; Same as AmmanPolyColor, showing only the ;; pentagon/hexagon tiling Angle 10 Axiom x x=@.618034/36[\9@.66D]M[/196.5@.363D][/180y]\72M[/180x] x=[\144@.618034M@i.618034x]\108[\36@.509D@1.18\30D][x]M[\153@.66D]\72[y]M y=@.618034/72[x][\36@.509D]M\144[\9@.66D]M[/180y][/196.5@.363D] y=\36[y]M\144M[/180x] D=M } Stars&PentasColor { ;; by Philippe Hurbain ;; Penrose's stars and pentagon tiling, generated as ;; a coloring of kites and darts Angle 20 Axiom c04k k=++[@.618034[g-c10@.5878[f]------ff++++f]a]f@.618034------ k=[--k]f--f------[--k]@i.618034f[@.618034|a] a=[@.618034k]++f@.618034[|[gc10@.5878+++++++f]a]--------f a=++f--------[c10g@.5878-------f][a]@i.618034f f=g } Stars&Pentas1 { ;; by Philippe Hurbain ;; Same as Stars&PentasColor, showing only coloring Angle 20 Axiom [k]++++[k]++++[k]++++[k]++++[k] k=++[@.618034[g-@.5878[f]------ff++++f]a]g@.618034------ k=[--k]g--g------[--k]@i.618034g[@.618034|a] a=[@.618034k]++g@.618034[|[g@.5878+++++++f]a]--------g a=++g--------[g@.5878-------f][a]@i.618034g f=g } Stars&Pentas2 { ;; by Philippe Hurbain ;; Penrose's stars and pentagons, generated from ;; decomposition rules ;; u is the star, v is the boat, w is the thin rhombus ;; x, y and z are the pentagons Angle 10 Axiom u u=@.381966[v]F[|y][-u]++F|+[v]F[|y]++F|+[v]F[|y]++F|+ u=[v]F[|y]++F|+[v]F[|y]++F v=@.381966[v]F[|y]++F|+[v]F[|y]-[u]F-F|+[v]F[|y]++F w=@.381966G++[u]F|+F-F|+[v]F[|y] y=@.381966[x][y][w]F[|!y]++F++[y][w]F[|!y]++F++[z]F x=@.381966G++G++[!x][!z]F--[!z]F--[!z]F--[!z]F--[!z]F z=@.381966[z][x]F++[z]F++[w][y]F[|!y]++F++[z]F F=G } xfractint-20.4.10.orig/lsystem/fract205.l0000644000000000000000000000300710330023321014673 0ustar adh6894 { ; Anthony Hanmer 2001, a.hanmer@gmail.com Angle 8 ; DC from 6829: Axiom x ; My only irregular-interior DC so far ; More work to be found at: ; http://spanky.triumf.ca/pub/fractals/LSYSTEMS/ ; in TDC.l x=f[@iq2-x]|[+!+!@.5x]f[@iq2+x] } hc043 { ; Hanmer Curve variation ; Anthony Hanmer 2001, a.hanmer@gmail.com angle 4; one of the best ; More work to be found at: ; http://spanky.triumf.ca/pub/fractals/LSYSTEMS/ ; in HCVar.l axiom |f f=f[@.5f]f|f+ } sq50217r { ; Anthony Hanmer 1/9/2003, a.hanmer@gmail.com Angle 4 ; One of my VERY best Hanmer Tiles: ; WAY COOL, a personal all-parallel favourite ; More work to be found at: ; http://spanky.triumf.ca/pub/fractals/LSYSTEMS/ ; in HanmerTiles.zip Axiom +c53f+g+c12f f=GGGGG|FFFFF|GGGGG+G+ffggf|fggff+G+fgfgg|ggfgf+G+ffgfg|gfgff+G+gffgg|ggffg+G+GGGGG+GGGGG+GGGGG g=ggggg } ST40028* { ; Anthony Hanmer 6/2002, a.hanmer@gmail.com Angle 4 ; non-crossing; and 4 together make a tile ; More work to be found at: ; http://spanky.triumf.ca/pub/fractals/LSYSTEMS/ ; in STiles.zip Axiom c9f+c10f+c12f+c14f f=f+ff-f-ff+f+ff-f } tr20001* { ; Anthony Hanmer 2000, a.hanmer@gmail.com Angle 6 ; My 2nd Hanmer Tile ; (& 1st 2x2 triangular HT) ; I think there are no more 2x2 triangular HTs to be found. ; (I am later proved to be SO wrong.) ; One of my VERY best HTs ; More work to be found at: ; http://spanky.triumf.ca/pub/fractals/LSYSTEMS/ ; in HanmerTiles.zip Axiom c9f++c12f++c14f f=f+f|f++f } xfractint-20.4.10.orig/lsystem/fractint.l0000644000000000000000000002652210150633601015176 0ustar Koch1 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 6 Axiom F--F--F F=F+F--F+F } Koch2 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 12 Axiom F---F---F---F F=-F+++F---F+ } Koch3 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 4 Axiom F-F-F-F F=F-F+F+FF-F-F+F } Koch6 { ; Adrian Mariano axiom f+f+f+f f=f-ff+ff+f+f-f-ff+f+f-f-ff-ff+f angle 4 } Dragon { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 8 Axiom FX F= y=+FX--FY+ x=-FX++FY- } Peano1 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 4 Axiom F-F-F-F F=F-F+F+F+F-F-F-F+F } Cesaro { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 34 Axiom FX F= X=----F!X!++++++++F!X!---- } DoubleCesaro { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 4 axiom D\90D\90D\90D\90 D=\42!D!/84!D!\42 } FlowSnake { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle=6; axiom FL L=FL-FR--FR+FL++FLFL+FR-", R=+FL-FRFR--FR-FL++FL+FR", F= } CantorDust { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 6 Axiom F F=FGF G=GGG } Snowflake2 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 12 axiom F F=++!F!F--F--F@IQ3|+F!F-- F=F--F!+++@Q3F@QI3|+F!F@Q3|+F!F } SnowflakeColor { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 12 axiom F F=--!F<1!F<1++F<1++F<1@IQ3|-F<1!F<1++ F=F<1++F<1!---@Q3F<1@QI3|-F<1!F<1@Q3|-F<1!F<1 F= } Island1 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 4 axiom F+F+F+F F=FFFF-F+F+F-F[-GFF+F+FF+F]FF G=@8G@I8 } Island2 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 4 axiom f+f+f+f f=f+gf-ff-f-ff+g+ff-gf+ff+f+ff-g-fff g=@6G@I6 } Quartet { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 4 axiom fb A=FBFA+HFA+FB-FA B=FB+FA-FB-JFBFA F= H=- J=+ } SnowFlake1 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 12 Axiom FR R=++!FRFU++FU++FU!---@Q3FU|-@IQ3!FRFU! U=!FRFU!|+@Q3FR@IQ3+++!FR--FR--FRFU!-- F= } SnowFlake3 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 12 axiom fx x=++f!x!fy--fx--fy|+@iq3fyf!x!++f!y!++f!y!fx@q3+++f!y!fx y=fyf!x!+++@iq3fyf!x!++f!x!++f!y!fx@q3|+fx--fy--fxf!y!++ f= } Tree1 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle=12; axiom +++FX X=@.6[-FX]+FX } Peano2 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot Angle 8 Axiom FXY++F++FXY++F X=XY@Q2-F@IQ2-FXY++F++FXY Y=-@Q2F-@IQ2FXY } Sierpinski1 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 3 axiom F F=FXF X=+FXF-FXF-FXF+ } Koch4 { ; Adrian Mariano ; from The Fractal Geometry of Nature by Mandelbrot angle 12 axiom f++++f++++f f=+f--f++f- } Plant07 { ; Ken Philip, from The Science of Fractal Images p.285b axiom Z z=zFX[+Z][-Z] x=x[-FFF][+FFF]FX angle 14 } Plant08 { ; Ken Philip, from The Science of Fractal Images, p.286 axiom SLFFF s=[+++Z][---Z]TS z=+H[-Z]L h=-Z[+H]L t=TL l=[-FFF][+FFF]F angle 20 } Hilbert { ; Ken Philip, from The Science of Fractal Images axiom x x=-YF+XFX+FY- y=+XF-YFY-FX+ angle 4 } Sierpinski3 { ; From Jim Hanan via Corbit axiom F-F-F f=F[-F]F angle 3 } Peano3 { axiom x x=XFYFX+F+YFXFY-F-XFYFX y=YFXFY-F-XFYFX+F+YFXFY angle 4 } Koch5 { axiom f+F+F+F f=F+F-F-FFF+F+F-F angle 4 } Sierpinski2 { ; from The Science of Fractal Images axiom FXF--FF--FF f=FF x=--FXF++FXF++FXF-- angle 6 } SierpinskiSquare { axiom F+F+F+F f=FF+F+F+F+FF angle 4 } Pentagram { ; created by Adrian Mariano angle 10 axiom fx++fx++fx++fx++fx ; f=f[++++@1.618033989f] x=[++++@i1.618033989f@.618033989f!x!@i.618033989f] } QuadKoch { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Quadratic Koch island, Figure 1.7a p.9 angle 4 AXIOM F-F-F-F- F=F+FF-FF-F-F+F+FF-F-F+F+FF+FF-F } Fass1 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; FASS curve (3x3 tiles form macrotile), Figure 1.16a p.17 axiom -l angle 4 L=LF+RFR+FL-F-LFLFL-FRFR+ R=-LFLF+RFRFR+F+RF-LFL-FR } Fass2 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; FASS curve (4x4 tiles form macrotile), Figure 1.16b p.17 angle 4 axiom -l L=LFLF+RFR+FLFL-FRF-LFL-FR+F+RF-LFL-FRFRFR+ R=-LFLFLF+RFR+FL-F-LF+RFR+FLF+RFRF-LFL-FRFR } QuadGosper { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Quadratic Gosper curve, Figure 1.11b p.12 angle 4 axiom -Fr l=FlFl-Fr-Fr+Fl+Fl-Fr-FrFl+Fr+FlFlFr-Fl+Fr+FlFl+Fr-FlFr-Fr-Fl+Fl+FrFr- r=+FlFl-Fr-Fr+Fl+FlFr+Fl-FrFr-Fl-Fr+FlFrFr-Fl-FrFl+Fl+Fr-Fr-Fl+Fl+FrFr f= } Plant01 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Plant-like structure, figure 1.24a p.25 ; also p.285a The Science of Fractal Images angle 14 axiom f f=F[+F]F[-F]F } Plant02 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Plant-like structure, figure 1.24b p.25 angle 18 axiom f f=F[+F]F[-F][F] } Plant03 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Plant-like structure, figure 1.24c p.25 angle 16 axiom f f=FF-[-F+F+F]+[+F-F-F] } Plant04 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Plant-like structure, figure 1.24d p.25 angle 18 axiom x X=F[+X]F[-X]+X F=FF } Plant05 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Plant-like structure, figure 1.24e p.25 angle 14 axiom x X=f[+X][-X]FX F=FF } Plant06 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Plant-like structure, figure 1.24f p.25 angle 16 axiom x X=F-[[X]+X]+F[+FX]-X F=FF } Plant09 { ; Adrian Mariano axiom y x=X[-FFF][+FFF]FX y=YFX[+Y][-Y] angle 14 } Plant10 { ; Adrian Mariano axiom f f=f[+ff][-ff]f[+ff][-ff]f angle 10 } Plant11 { ; Adrian Mariano axiom f f=F[+F[+F][-F]F][-F[+F][-F]F]F[+F][-F]F angle 12 } Curve1 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; curve from figure 1.9a p.10 angle 4 axiom F-F-F-F- f=FF-F-F-F-F-F+F } Curve2 { ; Adrian Mariano, from the Algorithmic Beauty of Plants angle 4 axiom F-F-F-F- f=FF-F+F-F-FF } Curve3 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; curve from figure 1.9e p.10 axiom F-F-F-F- angle 4 F=F-FF--F-F } Curve4 { ; Adrian Mariano axiom yf x=YF+XF+Y y=XF-YF-X angle 6 } Leaf1 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Compound leaf with alternating branches, Figure 5.12b p.130 angle 8 axiom x a=n n=o o=p p=x b=e e=h h=j j=y x=F[+A(4)]Fy y=F[-B(4)]Fx F=@1.18F@i1.18 } Leaf2 { ; Adrian Mariano, from the Algorithmic Beauty of Plants ; Compound leaf with alternating branches, Figure 5.12a p.130 angle 8 axiom a a=f[+x]fb b=f[-y]fa x=a y=b f=@1.36f@i1.36 } Bush { ; Adrian Mariano Angle 16 Axiom ++++F F=FF-[-F+F+F]+[+F-F-F] } MyTree { ; Adrian Mariano Angle 16 Axiom ++++F F=FF-[XY]+[XY] X=+FY Y=-FX } ColorTriangGasket { ; Adrian Mariano Angle 6 Axiom --X X=++FXF++FXF++FXF>1 F=FF } SquareGasket { ; Adrian Mariano Angle 4 Axiom X X=+FXF+FXF+FXF+FXF F=FF } DragonCurve { ; Adrian Mariano Angle 4 Axiom X X=X-YF- Y=+FX+Y } Square { ; Adrian Mariano Angle 4 Axiom F+F+F+F F=FF+F+F+F+FF } KochCurve { ; Adrian Mariano Angle 6 Axiom F F=F+F--F+F } Penrose1 { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses Angle 10 Axiom +WF--XF---YF--ZF W=YF++ZF----XF[-YF----WF]++ X=+YF--ZF[---WF--XF]+ Y=-WF++XF[+++YF++ZF]- Z=--YF++++WF[+ZF++++XF]--XF F= } ColorPenrose1 { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses ; Uses color to show the edge matching rules to force nonperiodicy Angle 10 Axiom +WC02F--XC04F---YC04F--ZC02F W=YC04F++ZC02F----XC04F[-YC04F----WC02F]++ X=+YC04F--ZC02F[---WC02F--XC04F]+ Y=-WC02F++XC04F[+++YC04F++ZC02F]- Z=--YC04F++++WC02F[+ZC02F++++XC04F]--XC04F F= } Penrose2 { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses Angle 10 Axiom ++ZF----XF-YF----WF W=YF++ZF----XF[-YF----WF]++ X=+YF--ZF[---WF--XF]+ Y=-WF++XF[+++YF++ZF]- Z=--YF++++WF[+ZF++++XF]--XF F= } Penrose3 { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses Angle 10 Axiom [X]++[X]++[X]++[X]++[X] W=YF++ZF----XF[-YF----WF]++ X=+YF--ZF[---WF--XF]+ Y=-WF++XF[+++YF++ZF]- Z=--YF++++WF[+ZF++++XF]--XF F= } Penrose4 { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses Angle 10 Axiom [Y]++[Y]++[Y]++[Y]++[Y] W=YF++ZF----XF[-YF----WF]++ X=+YF--ZF[---WF--XF]+ Y=-WF++XF[+++YF++ZF]- Z=--YF++++WF[+ZF++++XF]--XF F= } DoublePenrose { ; by Herb Savage ; This is Penrose3 and Penrose4 superimposed Angle 10 Axiom [X][Y]++[X][Y]++[X][Y]++[X][Y]++[X][Y] W=YF++ZF----XF[-YF----WF]++ X=+YF--ZF[---WF--XF]+ Y=-WF++XF[+++YF++ZF]- Z=--YF++++WF[+ZF++++XF]--XF F= } Sphinx { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers" ; This is an example of a "reptile" Angle 6 Axiom X X=+FF-YFF+FF--FFF|X|F--YFFFYFFF| Y=-FF+XFF-FF++FFF|Y|F++XFFFXFFF| F=GG G=GG } PentaPlexity { ; Manual construction by Roger Penrose as a prelude to his development of ; the famous Penrose tiles (the kites and darts) that tile the plane ; only non-periodically. ; Translated first to a "dragon curve" and finally to an L-system ; by Joe Saverino. Angle 10 Axiom F++F++F++F++F F=F++F++F|F-F++F } ; old PentaPlexity: ; Angle 10 ; Axiom F++F++F++F++Fabxjeabxykabxyelbxyeahxyeabiye ; F= ; a=Fabxjea ; b=++F--bxykab ; x=++++F----xyelbx ; y=----F++++yeahxy ; e=--F++eabiye ; h=+++++F-----hijxlh ; i=---F+++ijkyhi ; j=-F+jkleij ; k=+F-klhajk ; l=+++F---lhibkl CircularTile { ; Adrian Mariano axiom X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X x=[F+F+F+F[---X-Y]+++++F++++++++F-F-F-F] y=[F+F+F+F[---Y]+++++F++++++++F-F-F-F] angle 24 } Lars1{ ; By Jonathan Osuch [73277,1432] ; Based on a suggestion by Lars Vangsgaard Angle 8 ; angle increment/decrement is 45 axiom [F]++[F]++[F]++F F=F[+F][-F] } Lars2{ ; By Jonathan Osuch [73277,1432] ; Based on a suggestion by Lars Vangsgaard Angle 8 ; angle increment/decrement is 45 axiom +[F]++[F]++[F]++F F=F[+F][-F] } Lars1Color{ ; By Jonathan Osuch [73277,1432] ; Based on a suggestion by Lars Vangsgaard Angle 8 ; angle increment/decrement is 45 axiom C1[F]++[F]++[F]++F F=F<1[+F][-F]>1 } Lars2Color{ ; By Jonathan Osuch [73277,1432] ; Based on a suggestion by Lars Vangsgaard Angle 8 ; angle increment/decrement is 45 axiom C1+[F]++[F]++[F]++F F=F<1[+F][-F]>1 } Man { ; From Ivan Daunis daunis@teleline.es ; looks like man with an odd number of iterations Angle 8 Axiom F++F++F++F F=-F-FF+++F+FF-F } Lace { ; From Ivan Daunis daunis@teleline.es Angle 8 Axiom F++F++F++F F=F+++F---F+F---F++F--F++F } xfractint-20.4.10.orig/lsystem/tiling.l0000644000000000000000000000663210150633601014652 0ustar ; These LSystems are designed to be run from FRACTINT. No compilation is ; necessary, just copy this file to the FRACTINT directory and run FRACTINT. ; Select the lsystem fractal type and press F6 to select a file. ; This is the old ColorPenrose1 with three changes. ; 1. A brighter red and green ; 2. The name was changed to group the Penrose tilings together ; 3. The comment was corrected. Penrose1Color { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses ; Uses color to show similar lines Angle 10 Axiom +WC10F--XC12F---YC12F--ZC10F W=YC12F++ZC10F----XC12F[-YC12F----WC10F]++ X=+YC12F--ZC10F[---WC10F--XC12F]+ Y=-WC10F++XC12F[+++YC12F++ZC10F]- Z=--YC12F++++WC10F[+ZC10F++++XC12F]--XC12F F= } ; This tiling actually does what the old comment for ColorPenrose1 said ; it did. Penrose1Forced { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's rhombuses ; Uses color to show the edge matching rules to force nonperiodicy Angle 10 Axiom +WC10FC12F--XC11FC10F---YC10FC11F--ZC12FC10F W=YC10FC11F++ZC12FC10F----XC11FC10F[-YC10FC11F----WC10FC12F]++ X=+YC10FC11F--ZC12FC10F[---WC10FC12F--XC11FC10F]+ Y=-WC10FC12F++XC11FC10F[+++YC10FC11F++ZC12FC10F]- Z=--YC10FC11F++++WC10FC12F[+ZC12FC10F++++XC11FC10F]--XC11FC10F F= } KitesAndDarts { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's kites and darts Angle 10 Axiom WG+XG+WG+XG+WG+XG+WG+XG+WG+X W=[F][++@1.618033989F][++G---@.618033989G|X-Y|G|W] X=[F+++@1.618033989F][++@.618033989GZ|X|-G|W] Y=[+F][@1.618033989F][+G@.618033989|Y+X] Z=[-F][@1.618033989F][@.618033989G--WG|+Z] F= } KitesAndDartsColor { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; Roger Penrose's kites and darts Angle 10 Axiom WG+XG+WG+XG+WG+XG+WG+XG+WG+X W=[C10F][++@1.618033989C12F][++G---@.618033989G|X-Y|G|W] X=[C10F+++@1.618033989C12F][++@.618033989GZ|X|-G|W] Y=[+C10F][@1.618033989C12F][+G@.618033989|Y+X] Z=[-C10F][@1.618033989C12F][@.618033989G--WG|+Z] F= } SpiralTile { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers" angle 16 axiom X++X++X++X++|G|X++X++X++X X=[C12FX+++++@.7653668647C10F@I.7653668647[-----Y]+++++C12F] Y=[C12F+++++@.7653668647C10F@I.7653668647[-----Y]+++++C12F] } VoderbergTile { ; by Herb Savage ; based on Martin Gardner's "Penrose Tiles to Trapdoor Ciphers", ; A spiral tiling by Heinz Voderberg angle 30 axiom \84.1A\96@4.783386117M@I4.783386117/96A A=X\12X\12X\12X\12X\12X\12X\12X\12X\12X\12X\12X\12X\12X\12X\12Z X=[D\78D\46.37236@3.393427D@I3.393427/46.37236D\114[\168X\24Y]D\78D\46.37236@3.393427D@I3.393427/46.37236D/78D] Y=[D\78D\46.37236@3.393427D@I3.393427/46.37236D/78D\168[\192Y]D\78D\46.37236@3.393427D@I3.393427/46.37236D] Z=[D\78D\46.37236@3.393427D@I3.393427/46.37236D\114D\78D\46.37236@3.393427D@I3.393427/46.37236D/78D] } ; These two aren't tilings but simple spiral patterns done by my 12 year old ; son Morgan that really need the warning from "Fractal Creations" about ; color cycling introducing hypnotic states. Vertigo1 { ; by Morgan Savage ; Try order 13 and color cycle in both 256 and 16 color modes Angle 46 Axiom X X=X>1F+@.9997X } Vertigo2 { ; by Morgan Savage ; Try order 13 and color cycle in both 256 and 16 color modes Angle 49 Axiom X X=X>1F+@.9997X } xfractint-20.4.10.orig/key/0000755000000000000000000000000011456314752012305 5ustar xfractint-20.4.10.orig/key/new19-5.key0000644000000000000000000000136510150636277014130 0ustar ;; Demo of new Fractint version 19.4 features ;; Created by Sylvie Gallet ;; ;; This demo goes through once and then exits. ;; The new recordcolors= command is demonstrated ;; The new comment= command is demonstrated WAIT 3 F3 "v" RIGHT DOWN "2" WAIT 1 ENTER CALCWAIT "e" WAIT 0.5 ENTER WAIT 0.5 "l" WAIT 0.5 "default" WAIT 0.5 ENTER WAIT 0.5 ESC "g" "recordcolors=comment" MESSAGE 0.5 MESSAGE 5New "recordcolors=" command ENTER WAIT 1 "g" "comment=$date$/$xdots$_x_$ydots$/On_a_Pentium_166/$calctime$" MESSAGE 0.5 MESSAGE 5"New comment=" command ENTER WAIT 2 ;; save the par "b" WAIT 2 "demo195.par" WAIT 5 ENTER WAIT 0.4 ENTER WAIT 1 "2" WAIT 1 F2 MESSAGE 0.5 MESSAGE 12Complete par entry ESC ESC MESSAGE 5 The End ! ESC ESC "y" xfractint-20.4.10.orig/key/auto.key0000644000000000000000000000066010150636277013770 0ustar WAIT 2.9 "t" WAIT 0.8 "fo" ENTER WAIT 3.2 F6 WAIT 1.6 DOWN DOWN DOWN DOWN DOWN DOWN RIGHT RIGHT RIGHT RIGHT WAIT 0.7 ENTER DOWN DOWN DOWN WAIT 0.8 ENTER WAIT 3.1 "1" WAIT 0.6 "5" WAIT 0.6 "0" WAIT 1.2 ENTER WAIT 10.3 TAB WAIT 3.7 TAB WAIT 16.5 "t" WAIT 1.4 ENTER WAIT 1.7 UP WAIT 1.9 F2 WAIT 2.7 F2 WAIT 1.3 ENTER WAIT 1.3 ENTER WAIT 13.5 TAB WAIT 4.7 TAB WAIT 5.6 TAB WAIT 3.9 TAB WAIT 76.8 ESC ESC WAIT 0.9 "yxfractint-20.4.10.orig/key/new19-6.key0000644000000000000000000000305510150636277014127 0ustar ;; Demo of new Fractint version 19.6 features ;; Created by Sylvie Gallet ;; ;; New fastrestore command ;; Text scrolling in screen ;; DELETE ;; Set video mode WAIT 2 F3 CALCWAIT ; change savename and draw the Mandel set at 320x200 WAIT 2 "x" DOWN "f" DOWN * 6 "demo1961" DOWN * 2 "o" WAIT 1.5 ENTER CALCWAIT ; save the image demo1961.gif "s" CALCWAIT MESSAGE 4 File saved as demo1961.gif (320x200) ; new window size: 160x160 MESSAGE 2 Set view window size to 160 x 160 "v" RIGHT DOWN * 4 WAIT 1.0 "160" DOWN "160" WAIT 1.0 ENTER ; draw the new image and save it as demo1962.gif CALCWAIT "s" CALCWAIT MESSAGE 4 File saved as demo1962.gif (160x160) ; load demo1961.gif F3 CALCWAIT MESSAGE 2 Load demo1961.gif "r" "demo1961" ENTER WAIT 3 ENTER CALCWAIT WAIT 2 ; load demo1962.gif MESSAGE 2 Load demo1962.gif "r" "demo1962" ENTER WAIT 3 ENTER WAIT 3 ENTER CALCWAIT WAIT 2 ; command: fastrestore=yes & askvideo=no MESSAGE 3 fastrestore = yes and askvideo = no "g" "fastrestore=yes" WAIT 2 ENTER "g" "askvideo=no" WAIT 2 ENTER ; load demo1961.gif MESSAGE 2 Load demo1961.gif "r" "demo1961" ENTER CALCWAIT WAIT 2 ; load demo1962.gif MESSAGE 2 Load demo1962.gif "r" "demo1962" ENTER CALCWAIT WAIT 3 MESSAGE 2 Text scrolling in screen "t" "formula" ENTER F6 "fract196" ENTER "fractint" WAIT 1 ENTER CTRL_DOWN * 8 WAIT 0.5 CTRL_RIGHT * 2 WAIT 0.5 CTRL_LEFT * 2 WAIT 0.5 CTRL_RIGHT * 2 WAIT 0.5 CTRL_LEFT * 2 WAIT 0.5 CTRL_DOWN * 8 WAIT 0.5 CTRL_UP * 10 WAIT 0.5 CTRL_END WAIT 1 CTRL_HOME WAIT 1 ENTER CALCWAIT MESSAGE 5 The End ! ESC ESC "y xfractint-20.4.10.orig/key/advanced.key0000644000000000000000000000323610150636277014567 0ustar ;; Demo of advanced Fractint features ;; Created by Jonathan Osuch ;; ;; This demo goes through once and then exits. ;; mandel/julia toggle ;; orbits ;; rds WAIT 3 "m" DOWN * 2 WAIT 1 "x" WAIT 1 DOWN * 3 "0" ;; inside = 0 WAIT 1 ENTER WAIT 2 DELETE ;; Set video mode WAIT 2 F3 WAIT 0.5 CALCWAIT " " ;; space bar WAIT 7.0 LEFT * 20 WAIT 0.5 UP * 7 WAIT 7.0 "v" ;; turn on view window WAIT 0.5 LEFT WAIT 0.5 ENTER CALCWAIT ;; mandelbrot set " " ;; space bar WAIT 5 " " ;; space bar CALCWAIT ;; julia set WAIT 3.0 "v" ;; turn off view window WAIT 0.5 "n" WAIT 0.5 ENTER CALCWAIT WAIT 3.0 " " ;; space bar, back to mandelbrot WAIT 0.1 "v" ;; turn on view window WAIT 0.5 "y" WAIT 0.5 ENTER "x" "1" ENTER "o" ;; orbits during calculation CALCWAIT "o" ;; orbits after calculation WAIT 1.0 "h" ;; hide the mandelbrot set WAIT 0.5 UP WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 UP WAIT 1.0 UP WAIT 1.0 UP WAIT 1.0 RIGHT WAIT 1.0 UP WAIT 1.0 "c" ;; orbits with circles WAIT 1.0 UP WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 UP WAIT 1.0 RIGHT WAIT 1.0 "c" "l" ;; orbits with lines WAIT 1.0 UP WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 "c" ;; orbits with lines and circles WAIT 1.0 RIGHT WAIT 1.0 RIGHT WAIT 1.0 DOWN WAIT 1.0 RIGHT WAIT 1.0 DOWN WAIT 1.0 RIGHT WAIT 1.0 DOWN WAIT 1.0 ;; make an image suitable for rds ESC WAIT 1 "v" WAIT .5 "n" WAIT .5 ENTER "x" "g" DOWN * 2 "500" WAIT 1 ENTER "y" DOWN "255" DOWN "300" WAIT 1 ENTER "t" WAIT .5 ENTER ENTER CALCWAIT 19 ;; control-s for rds WAIT 2 ENTER WAIT 20 UP ESC ESC WAIT 0.5 ESC WAIT 0.5 "y" xfractint-20.4.10.orig/key/new19-4.key0000644000000000000000000000340610150636277014125 0ustar ;; Demo of new Fractint version 19.4 features ;; Created by Sylvie Gallet ;; ;; This demo goes through once and then exits. ;; The new rounding functions are demonstrated ;; The new showdot turtle is demonstrated ;; The ability to load images into a view window is demonstrated ;; (The last point is disabled for now) CALCWAIT WAIT 2.0 "g" "askvideo=no" ENTER F3 CALCWAIT MESSAGE 6New rounding function: trunc "x" "b" DOWN * 3 "1" DOWN * 4 "new19401" DOWN * 5 "0" ENTER 6 ;; ctrl-f DOWN * 4 "15" WAIT 1.5 ENTER ; draw the classic Mandel and save it as new19401.gif "t" "mandel" ENTER DOWN * 2 RIGHT * 4 ENTER CALCWAIT WAIT 2 "g" "symmetry=xaxis" ENTER CALCWAIT WAIT 2 "g" MESSAGE 4 now remembers the last command. "showdot=auto/10" MESSAGE 4New larger showdot "turtle" ENTER F3 CALCWAIT WAIT 2 ;;"s" CALCWAIT ;; Uncomment when loading full-sized images ;; in view window is enabled again "g" "showdot=-1" ENTER CALCWAIT ;; Remove when loading full-sized images GOTO skipped ;; in view window is enabled again ; zoom in and save image as new19402.gif PAGEUP * 13 LEFT * 40 UP * 15 ENTER CALCWAIT "s" CALCWAIT WAIT 3 ; zoom in, rotate and save image as new19403.gif PAGEUP *2 1144 * 12 ENTER CALCWAIT "s" CALCWAIT WAIT 3 MESSAGE 5Load an image into a view window ; set viewwindows = yes/2 "v" RIGHT DOWN "2" WAIT 1.5 ENTER "r" "new19401" ENTER CALCWAIT WAIT 3 ; set autobrowsing = yes 2 WAIT 0.8 RIGHT WAIT 1.5 ENTER CALCWAIT UP WAIT 1 UP WAIT 1 UP WAIT 1 ; load image #1 ENTER CALCWAIT WAIT 6.0 ; load image #2 ENTER CALCWAIT WAIT 6.0 ; load image #3 UP WAIT 7.0 ENTER CALCWAIT WAIT 4.0 ;; Remove when loading full-sized images skipped: ;; in view window is enabled again ESC MESSAGE 5 The End ! ESC ESC "y" xfractint-20.4.10.orig/key/explore.key0000644000000000000000000000652510150636277014504 0ustar MESSAGE 4 Start at the beginning INSERT MESSAGE 4 Lets explore the julia sets "t" WAIT 0.6 "juli" WAIT 1.9 "a" ENTER "0" DOWN "0" WAIT 1.0 ENTER MESSAGE 4 high res is best, SF5 for demo SF5 "x" MESSAGE 4 Guessing is bad for small windows "1" MESSAGE 4 And black interior helps contrast DOWN DOWN DOWN WAIT 1.0 "0" WAIT 1.5 ENTER CALCWAIT MESSAGE 2 This is the basic set MESSAGE 2 Now to vary the parameters on screen. MESSAGE 3 Ctrl-E to access the evolver controls 5 MESSAGE 4 Then switch on evolver mode "y" MESSAGE 2 Hit F6 F6 MESSAGE 1 ... MESSAGE 4 and switch the random variations to "x" DOWN "y" MESSAGE 4 something more controllable ENTER MESSAGE 4 Lets use the parameter zoom box too. DOWN DOWN "y" WAIT 2 ENTER CALCWAIT MESSAGE 2 There they are! MESSAGE 3 Too coarse though so... 5 MESSAGE 5 Increase the number of images: DOWN "21" WAIT 3.0 ENTER CALCWAIT MESSAGE 6 Squint and you'll see the Mset! MESSAGE 4 Now to take a closer look MESSAGE 4 at the way they change MESSAGE 4 Hit pageup to get the zoom box PAGEUP MESSAGE 4 CTRL PGUP shrinks the parm zoombox 1132 1132 1132 1132 1132 1132 1132 1132 MESSAGE 5 then move to an area of interest CTRL_RIGHT CTRL_RIGHT CTRL_UP CTRL_RIGHT CTRL_UP MESSAGE 4 Hit enter to concentrate on this bit ENTER CALCWAIT MESSAGE 5 A better colour scheme? Hit C "c" WAIT 0.9 "l" WAIT 2 "chro" WAIT 1.8 "ma" WAIT 3 ENTER ESC MESSAGE 4 Colour cycling is nice! "+" WAIT 14.8 ESC MESSAGE 5 Zoom in on an area of interest MESSAGE 4 The same as in the normal view MESSAGE 5 let's look at the upper spiral PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP UP UP UP UP LEFT LEFT UP LEFT LEFT PAGEUP WAIT 3 ENTER CALCWAIT MESSAGE 4 now select fewer images MESSAGE 4 to see more detail in them 5 WAIT 1.9 DOWN "1" "5" ENTER CALCWAIT PAGEUP MESSAGE 4 and repeat at will! CTRL_UP CTRL_LEFT CTRL_LEFT CTRL_LEFT 1132 1132 1132 1132 1132 CTRL_LEFT CTRL_DOWN 1132 WAIT 5 ENTER CALCWAIT WAIT 5 PAGEUP CTRL_UP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT DOWN DOWN DOWN DOWN DOWN DOWN RIGHT DOWN DOWN DOWN RIGHT RIGHT RIGHT PAGEUP PAGEUP ENTER CALCWAIT MESSAGE 5 more iterations are needed, hit x "x" DOWN DOWN "512" WAIT 2 ENTER CALCWAIT WAIT 5 5 DOWN "9" ENTER CALCWAIT "+" WAIT 10.0 ESC PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT RIGHT UP UP UP UP UP UP PAGEDOWN PAGEDOWN UP MESSAGE 4 Look for the areas of rapid change MESSAGE 4 this is where the parameter space MESSAGE 4 goes chaotic. 1132 1132 CTRL_UP ENTER CALCWAIT MESSAGE 5 Large numbers of images can look MESSAGE 4 pretty good! 5 DOWN WAIT 3 "29" ENTER CALCWAIT MESSAGE 5 Lots of tiles mean a lot of grout, MESSAGE 5 switch it off to help fill the screen 5 DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN WAIT 2 "n" WAIT 2 ENTER CALCWAIT "+" WAIT 10.1 ESC MESSAGE 5 Over to you! MESSAGE 5 Learn the hotkeys MESSAGE 5 for faster navigation MESSAGE 5 Hit F1 and go down to evolver commands MESSAGE 5 Try this with any of the parameters MESSAGE 5 Use a formula type with lots of parms MESSAGE 5 and go and explore! ESC ESC "y" xfractint-20.4.10.orig/key/basic.key0000644000000000000000000000226610150636277014105 0ustar ;; Demo of basic Fractint features ;; Created by Jonathan Osuch ;; ;; This demo goes through once and then exits. ;; sets the savename ;; sets the video mode ;; saves the image ;; shows screen ;; zooms in ;; color cycles ;; displays help screens ;; restores the image ;; exits WAIT 3 "m" WAIT 1 DOWN * 8 WAIT 1 ;; Set save name "x" WAIT 1 DOWN * 3 "0" ;; inside = 0 DOWN * 4 "basic001" WAIT 1 ENTER WAIT 2 DELETE ;; Set video mode WAIT 2 F3 CALCWAIT MESSAGE 2Pressing S saves your image "s" ;; save the image CALCWAIT WAIT 2 UP ;; do this to clear "image saved as ..." message MESSAGE 2Pressing TAB views fractal data TAB WAIT 3.0 ESC WAIT 1.0 PAGEUP * 23 WAIT 0.5 MESSAGE 2Pressing Page Up zooms in CTRL_LEFT * 11 LEFT * 7 WAIT 0.5 MESSAGE 2Using arrow keys, pressing ENTER ENTER CALCWAIT MESSAGE 2Pressing + color cycles "+" WAIT 5 MESSAGE 2Pressing - cycles other direction "-" WAIT 4 ESC MESSAGE 2Pressing F1 brings up help F1 WAIT 3 F1 WAIT 3 ESC MESSAGE 2Pressing R restores your image "r" ;; restore the image "basic001" WAIT 1.0 ENTER WAIT 1.0 ENTER CALCWAIT MESSAGE 2Pressing ESC or M for the menu ESC WAIT 0.5 RIGHT DOWN * 9 WAIT 1.0 ESC WAIT 0.5 "y" xfractint-20.4.10.orig/key/new19.key0000644000000000000000000000434110150636277013763 0ustar ;; Demo of new Fractint version 19 features ;; Created by Jonathan Osuch ;; ;; This demo goes through once and then exits. ;; The new bailout tests are demonstrated ;; The browser feature is demonstrated ;; The new outside=atan is demonstrated ;; The extended bailout value is demonstrated ;; The new ant fractal type is demonstrated WAIT 3 ;; Set up first image ESC WAIT 1.0 DOWN * 8 ;; "x" "x" WAIT 1.0 DOWN "y" ;; turn on floating point ;; comment out above the line if floating point is too slow ;; note that if you do, bailout=40000 will really be bailout=127 ;; the integer limit for bailout DOWN * 2 "0" ;; inside = 0 WAIT 1.0 DOWN * 4 "new19001" WAIT 1.0 ENTER ESC WAIT 1.0 ;; Set up the browse parameters for demo DOWN * 12 ;; Ctrl-B 2 WAIT 1.0 DOWN "n" ;; Don't ask about video mode WAIT 1.0 DOWN * 6 "new19*.gif" WAIT 1.0 ENTER ESC WAIT 1.0 DOWN * 10 ;; "z" "z" WAIT 1.0 DOWN * 2 "r" ;; real WAIT 2.0 ENTER ;; Make the first image DELETE WAIT 2.0 F3 CALCWAIT MESSAGE 2bailout test=real "s" CALCWAIT ;; Zoom in and save are for later browser use PAGEUP * 23 WAIT 1.0 CTRL_LEFT * 11 LEFT * 7 WAIT 1.0 ENTER CALCWAIT "s" CALCWAIT PAGEUP * 10 WAIT 1.0 ENTER CALCWAIT "s" CALCWAIT "t" WAIT 1.0 ENTER DOWN * 2 "i" ;; imag WAIT 2.0 ENTER CALCWAIT MESSAGE 2bailout test=imag PAGEUP * 25 CTRL_UP * 3 UP * 6 CTRL_LEFT * 4 LEFT * 3 WAIT 2 ENTER CALCWAIT "s" CALCWAIT "t" WAIT 1.0 ENTER WAIT 1.0 DOWN * 2 "o" ;; or WAIT 2.0 ENTER CALCWAIT MESSAGE 2bailout test=or "z" DOWN * 2 "a" ;; and WAIT 2.0 ENTER CALCWAIT MESSAGE 2bailout test=and ;; Start outside=atan demo "x" WAIT 1.0 DOWN * 2 "500" WAIT 1.0 DOWN * 4 "a" ;; atan WAIT 2.0 ENTER "c" "l" "chroma" WAIT 1.0 ENTER ESC CALCWAIT MESSAGE 2outside=atan "z" UP "40000" WAIT 2.0 ENTER CALCWAIT MESSAGE 2bailout=40000 Startbrowse: ;; Start demo of browse features "r" "new19001.gif" ENTER CALCWAIT "l" CALCWAIT WAIT 2.0 ENTER CALCWAIT WAIT 2.0 "l" CALCWAIT WAIT 2.0 ENTER CALCWAIT WAIT 2.0 "\" CALCWAIT WAIT 2.0 "\" CALCWAIT WAIT 1.0 "l" CALCWAIT WAIT 2.0 RIGHT WAIT 2.0 RIGHT WAIT 2.0 ENTER CALCWAIT WAIT 5.0 "t" "julia" ENTER DOWN * 2 "mmm" ;; mod ENTER CALCWAIT WAIT 5.0 ;; Start of ant demo 1 ;; ctrl-a ;;"1101" WAIT 1.0 ENTER WAIT 20.0 MESSAGE 2type=ant End: ESC ESC "y" xfractint-20.4.10.orig/key/snddemo1.key0000644000000000000000000001265510150636277014541 0ustar ;;demo of Fractint v.20 sound capabilities ;;created by Bill Jemison WAIT 3.3 ENTER WAIT 1.8 ENTER WAIT 1.5 ENTER WAIT 3.4 "x" WAIT 2.8 MESSAGE 0 MESSAGE 6 FOR SOUND I USUALLY USE MESSAGE 6 PASSES=1 AND A VIEWWINDOW "1" WAIT 2.7 ENTER WAIT 3.7 "v" WAIT 4.7 "y" WAIT 3.6 ENTER WAIT 4.2 PAGEUP WAIT 0.9 PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP UP UP UP UP UP UP UP UP UP UP ENTER PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP PAGEUP DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN DOWN UP UP UP ENTER MESSAGE 0 MESSAGE 6 enter Ctrl+F for sound parameters 6 WAIT 6 MESSAGE 0 MESSAGE 6 SOUND=X, Y OR Z FOR SOUNDS WAIT 2 "x" WAIT 3 DOWN DOWN DOWN DOWN DOWN DOWN DOWN MESSAGE 0 MESSAGE 6 SHOWORBIT = "YES" FOR SOUND WAIT 2 "y" WAIT 3.0 ENTER WAIT 9.0 6 WAIT 2.5 DOWN DOWN DOWN DOWN MESSAGE 0 MESSAGE 6 SLOW THE ORBITS DOWN WAIT 3.8 "1000" WAIT 2.0 ENTER WAIT 13.4 6 DOWN WAIT 3.7 MESSAGE 0 MESSAGE 6 TURN OFF PC SPEAKER WAIT 3 "n" DOWN MESSAGE 0 MESSAGE 6 TURN ON SOUND CARD WAIT 3 "y" WAIT 3 ENTER WAIT 24.0 6 DOWN DOWN DOWN DOWN DOWN MESSAGE 0 MESSAGE 6 CHANGE BASIC PITCH WAIT 3 "1000" WAIT 3 ENTER WAIT 8.4 6 DOWN DOWN DOWN DOWN DOWN "2500" WAIT 3 ENTER WAIT 5.1 6 DOWN DOWN DOWN DOWN DOWN "0" WAIT 3 ENTER WAIT 9.4 6 DOWN DOWN DOWN DOWN DOWN "100" WAIT 3 ENTER WAIT 10.3 6 MESSAGE 0 MESSAGE 6 USE PC SPEAKER AND SOUNDCARD TOGETHER DOWN "y" WAIT 3.0 ENTER WAIT 22.9 6 MESSAGE 0 MESSAGE 6 HIT F6 FOR SYNTH CONTROLS WAIT 3 F6 WAIT 3.7 DOWN "5" WAIT 3 ENTER ENTER WAIT 14.5 6 WAIT 1 F6 "3" WAIT 3 ENTER ENTER WAIT 14.2 6 MESSAGE 0 MESSAGE 6 LETS LIMIT THE NOTES PLAYED WAIT 3 DOWN DOWN DOWN "y" WAIT 3.1 MESSAGE 0 MESSAGE 6 HIT F7 TO CONTROL NOTES WAIT 3 F7 DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" DOWN "1" WAIT 3 ENTER ENTER WAIT 12.1 6 DOWN DOWN DOWN "n" WAIT 3 ENTER WAIT 11.5 6 DOWN DOWN DOWN "y" WAIT 3 F7 MESSAGE 0 MESSAGE 6 ALL "BLACK" KEYS (PIANO) "2" DOWN "2" DOWN "4" DOWN "4" DOWN "7" DOWN "7" DOWN "9" DOWN "9" DOWN "11" DOWN "11" DOWN "2" DOWN "4" WAIT 3 ENTER ENTER WAIT 16.5 6 WAIT 3.7 F7 MESSAGE 0 MESSAGE 6 C, D, E, F, G, A AND B ON PIANO "1" DOWN "3" DOWN "5" DOWN "6" DOWN "8" DOWN "10" DOWN "12" DOWN "1" DOWN "3" DOWN "5" DOWN "6" DOWN "8" WAIT 3 ENTER ENTER WAIT 17.7 6 MESSAGE 0 MESSAGE 6 TRY SOME OTHER SYNTH CONTROLS F6 WAIT 2 "7" WAIT 3 ENTER ENTER WAIT 8 6 F6 WAIT 2 "1" WAIT 2 DOWN "2" WAIT 3 ENTER ENTER WAIT 11.6 6 WAIT 3.0 DOWN MESSAGE 0 MESSAGE 6 TURN PC SPEAKER OFF WAIT 1.3 "n" WAIT 2 ENTER WAIT 2 6 WAIT 2.0 F6 DOWN WAIT 2 "4" WAIT 2 ENTER WAIT 1.7 ENTER WAIT 6.4 6 F6 WAIT 1.4 DOWN DOWN DOWN DOWN DOWN "15" WAIT 1.3 ENTER WAIT 1.0 ENTER WAIT 13.5 6 WAIT 2.0 F6 WAIT 2 "3" WAIT 1.0 ENTER WAIT 0.8 ENTER WAIT 11.3 6 F6 WAIT 2.5 "1" WAIT 1.8 DOWN WAIT 1.1 "2" WAIT 2.2 DOWN WAIT 2.6 "1" WAIT 0.7 "0" WAIT 2.9 DOWN WAIT 0.5 DOWN WAIT 4.4 ENTER WAIT 1.4 ENTER WAIT 9.0 6 WAIT 2.0 F6 MESSAGE 0 MESSAGE 6 RESET SYNTH WITH F4 F4 WAIT 2.1 ENTER ENTER WAIT 42.4 6 WAIT 2.0 MESSAGE 0 MESSAGE 6 RESET SOUND PARAMETERS TO DEFAULT MESSAGE 6 BY USING F4 ON EACH SCREEN WAIT 1.5 6 WAIT .5 F7 WAIT .5 F4 WAIT .5 F6 WAIT .5 F4 WAIT .5 F6 WAIT .5 F6 WAIT .5 F4 WAIT .5 ENTER WAIT .5 ESC WAIT .5 ESC WAIT .5 "Y" xfractint-20.4.10.orig/extra/0000755000000000000000000000000011456314750012636 5ustar xfractint-20.4.10.orig/extra/fractint.prj0000755000000000000000000006163410150522423015166 0ustar Turbo C Project File  2R                 "#$%&'+k[]^bcdefghmnoqsuvwxyz{|}~-DIN.C:\BORLANDC\INCLUDECPP\PLAY;C:\TCPP\GEN/C:\BORLANDC\LIB032102034*5*6*7*8*9*:*;*<*=*>*?*@debug=10000st=?%\\ 332 """?: 23AD32767E8192FC.CG32O%  ~GREPGREP-n+ $MEM(128) $NOSWAP $PROMPT $CAP MSG(GREP2MSG)void *.c~Turbo AssemblerTASM\TASM/ML /ZI /O /jJUMPS /m2 $TASMTurbo ~Debuggertd $EXENAMETurbo ~Profilertprof $EXENAMER~esource CompilerRC$RC~Import LibrarianIMPLIB$IMPLIB~Help CompilerBCHELP.EXE/c $EDNAMEME4MCP 9/12/92 Enabaled optimizations for fastest code. Added LYAPUNOV.ASM module Changed $MEM to 64k for GREP transfer item Enabled break on error 5 5N% 3D.CRLANDC\FRASRC\3D.C0N% 3ANT.CLANDC\FRASRC\ANT.CN%5.N BIGFLT.CDC\FRASRC\BIGFLT.CN%nrBIGINIT.CC\FRASRC\BIGINIT.CN%(BIGNUM.CDC\FRASRC\BIGNUM.CN%) BIGNUMC.CC\FRASRC\BIGNUMC.C5N%l aCALCFRAC.C\FRASRC\CALCFRAC.C;N%J~ CMDFILES.C\FRASRC\CMDFILES.C@N%+DECODER.CC\FRASRC\DECODER.CCN%DISKVID.CC\FRASRC\DISKVID.C,\N%@P EDITPAL.CC\FRASRC\EDITPAL.C6N%cENCODER.CC\FRASRC\ENCODER.C9N%=sEVOLVE.CDC\FRASRC\EVOLVE.C<N%k\F16.CLANDC\FRASRC\F16.CCN%>:FRACSUBR.C\FRASRC\FRACSUBR.CFN%^-w#FRACTALB.C\FRASRC\FRACTALB.CIN%0EQ FRACTALP.C\FRASRC\FRACTALP.CPN%Ec FRACTALS.C\FRASRC\FRACTALS.CSN%c]FRACTINT.C\FRASRC\FRACTINT.C[N%; FRAMAIN2.C\FRASRC\FRAMAIN2.CaN%# FRASETUP.C\FRASRC\FRASETUP.C~}dN%;GIFVIEW.CC\FRASRC\GIFVIEW.C|{zgN%DbHCMPLX.CDC\FRASRC\HCMPLX.CyxwlN%*KAHELP.CANDC\FRASRC\HELP.CnN%yINTRO.CNDC\FRASRC\INTRO.CvutqN%LJB.CRLANDC\FRASRC\JB.CsrqvN%7# JIIM.CANDC\FRASRC\JIIM.Cpon}N%`PP LINE3D.CDC\FRASRC\LINE3D.CmlkN%< FLOADFDOS.C\FRASRC\LOADFDOS.CjihN%+LOADFILE.C\FRASRC\LOADFILE.CgfeN%,TLOADMAP.CC\FRASRC\LOADMAP.CdcbN%\$ LORENZ.CDC\FRASRC\LORENZ.Ca`_N%LSYS.CANDC\FRASRC\LSYS.C^]\N%w,LSYSF.CNDC\FRASRC\LSYSF.C[ZYN%Y"MEMORY.CDC\FRASRC\MEMORY.CN%jHY* MISCFRAC.C\FRASRC\MISCFRAC.CXWVDN%QP MISCOVL.CC\FRASRC\MISCOVL.CUTSN%<MISCRES.CC\FRASRC\MISCRES.CRQPN%{MPMATH_C.C\FRASRC\MPMATH_C.CONM~N%jPARSER.CDC\FRASRC\PARSER.CLKJN%^4PARSERFP.C\FRASRC\PARSERFP.CIHG{N% /PLOT3D.CDC\FRASRC\PLOT3D.CFEDxN%'PRINTER.CC\FRASRC\PRINTER.CCBAvN%^SD PROMPTS1.C\FRASRC\PROMPTS1.C@?>N%HPROMPTS2.C\FRASRC\PROMPTS2.C=<;rN%63ZREALDOS.CC\FRASRC\REALDOS.C:98p"N%r nROTATE.CDC\FRASRC\ROTATE.C765n%N%_NSLIDESHW.C\FRASRC\SLIDESHW.C432l*N%gNSOI.CLANDC\FRASRC\SOI.Ci.N% ZSOI1.CANDC\FRASRC\SOI1.C2O% 0SOUND.CNDC\FRASRC\SOUND.C=1N%sSTEREO.CDC\FRASRC\STEREO.C10/g4N% TARGA.CNDC\FRASRC\TARGA.C.-,e5N%iTESTPT.CDC\FRASRC\TESTPT.C+*)c7N%>TGAVIEW.CC\FRASRC\TGAVIEW.C('&a:N% +TPLUS.CNDC\FRASRC\TPLUS.C%$#\<N%YOURVID.CC\FRASRC\YOURVID.C"! ZBN%T 2ZOOM.CANDC\FRASRC\ZOOM.CXBN%CALCMAND.ASMRASRC\CALCMAND.ASMVCN%CALMANFP.ASMRASRC\CALMANFP.ASM9CN%CALMANP5.ASMRASRC\CALMANP5.ASMTDN%FPU087.ASM\FRASRC\FPU087.ASMRDN%FPU387.ASM\FRASRC\FPU387.ASM OEN%FR8514A.ASMFRASRC\FR8514A.ASM MEN%FRACSUBA.ASMRASRC\FRACSUBA.ASMKFN%GENERAL.ASMFRASRC\GENERAL.ASMHFN%HGCFRA.ASM\FRASRC\HGCFRA.ASMFGN%LSYSA.ASMC\FRASRC\LSYSA.ASMGN%LSYSAF.ASM\FRASRC\LSYSAF.ASMGN%LYAPUNOV.ASMRASRC\LYAPUNOV.ASMHN%MPMATH_A.ASMRASRC\MPMATH_A.ASMHN%NEWTON.ASM\FRASRC\NEWTON.ASMIN%PARSERA.ASMFRASRC\PARSERA.ASMIN%SSCHOICE.ASMRASRC\SSCHOICE.ASMJN%TPLUS_A.ASMFRASRC\TPLUS_A.ASMKN%VIDEO.ASMDEO.ASM6b,~&&&&$&&&&''%'1'@'M'Z'i'w''''J'W''U#'e$$'#'q$ ((|$'(7($$$$F(U(e(r(~(((;%(W(s((((q(),)D)P)^)m)})A*%))i ) ) F%)) )} **) _%(*97*F*Iv%U*%l*|*%*q%%****%"*U**M+++.+G+R+i+y++++++++,(,@,X,l&[Z&?J&#9&'&&= e!E"!w EaM9!1 = &*x2O%@@@@@ @@@ /B$@@XN%| jno"jno"jno"d$jno"XN%S"| jno"jno"SOUND.C}/B$@@@s@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%ZV3$V3$8b $ $8bV#!L%!L%8bT | | 8bS(D$D$8bPZV3$V3$8bN $ $8bM7.$.$8bL7.$.$8bL##8bL| | 8bH TN%N%8bG | | 8bF 3""8bF| | 8bF $ $8bF#!L%CALMANP5.ASM.#!L%!L%8bCړ%%8bC $ $8bC/B$@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%}" /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| !# @@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%| _@y@jno" }" /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%| | ","""TESTP%}"@@@ @ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%$jno"| jno"jno"'WV3$@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"| jno"jno"2M$@@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| 7$x#@@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| )!#@@@@@ @ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| +Ed#@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"| jno"jno"-XN%@@@y@@A@t@]@_@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"jno"/XN%@@@@y@@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"@@3@jno"d$1铂$@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"jno"4"|@@y@@_@t@B@ @s@@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"| 6{" /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%S"| 8Xb~#@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| jno": $@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| jno"< $ /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| >WV3$@@@@@@@s@y@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"jno" CWN%@@@@@@@A@s@y@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"@@3@jno"d$E /B$@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%S"| jno"jno"?}$@@@@@@y@@s@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| jno"G#@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%Ijno"| jno"jno"J"x#@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%Ijno"| jno"jno"LWN%@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%S"| jno"jno"jno"N"@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%Q;=%@@@@B@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"| jno"jno"d$jno"SW$@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"| jno"jno"jno"UB#@@ /B$@@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%W!x#@@@s@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"S"jno"Yv" /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"S"jno"jno"jno"d$["@@ /B$@@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"| jno"jno"jno"`!#y@@@_@@@@^@t@]@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%PT"| jno"be" /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| dVN%@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%fVN%@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"S"jno"hVN%@@@@y@@s@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"jno"jno"jno"kVN%@@@@P@y@@s@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"jno"jno"mXV3$@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"S"jno"o# /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"S"jno"jno"jno"d$q:#@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"S"jno"uVN%s@@j@t@@ /B$@@@@@@@XN%| jno"jno"jno"d$jno"XN%S"| ws"@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%| | jno"jno"; $ /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%S"PT"jno"jno"jno"d$zV$@@@@y@@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"| jno")D$@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%xE# /B$@@@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%| UN%@@@@@@|@ /B$@@@@@XN%| jno"jno"jno"d$jno"XN%S"| UN%@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%S"| jno"q"@@@@ /B$@@@@@@jno"jno"jno"@q"@@@ /B$@@@@@@jno"jno"jno"@@@@@jno""@@@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%S"| jno"p"@@@ /B$@@@@@@jno"jno"jno"@@@@@jno"p"@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%PT"o"XN%XN%X&b"@@@ /B$@@@@@@XN%| jno"jno"jno"d$jno"XN%XN%M$SOI1.C$x#SOI.C $EVOLVE.C}$MEMORY.C@..\INCLUDE\CONIO.H@..\INCLUDE\DIR.H@..\INCLUDE\DIRECT.H@..\INCLUDE\PROCESS.H@..\INCLUDE\ERRNO.H@..\INCLUDE\SIGNAL.H@..\INCLUDE\SYS\TIMEB.H@..\INCLUDE\STDARG.H@..\INCLUDE\BIOS.H@..\INCLUDE\CTYPE.H@..\INCLUDE\LIMITS.H@..\INCLUDE\MEM.H@..\INCLUDE\MEMORY.H@..\INCLUDE\ALLOC.H@..\INCLUDE\MALLOC.H $VIDEO.ASM#!L%TPLUS_A.ASM | SSCHOICE.ASM(D$PARSERA.ASMZV3$NEWTON.ASM $MPMATH_A.ASM7.$LYAPUNOV.ASM7.$LSYSAF.ASM#LSYSA.ASM| HGCFRA.ASMTN%GENERAL.ASM| FRACSUBA.ASM3"FR8514A.ASM| FPU387.ASM $FPU087.ASMړ%CALMANFP.ASM $CALCMAND.ASM/B$ZOOM.C}"YOURVID.C| TPLUS.H!#TPLUS.C}"TGAVIEW.C,"TESTPT.Cjno"TARGA.H}"TARGA.CWV3$STEREO.C!#SLIDESHW.CEd#ROTATE.CXN%REALDOS.CXN%PROMPTS2.C铂$PROMPTS1.C"PRINTER.C{"PLOT3D.CXb~#PARSERFP.C $PARSER.C $MPMATH_C.CWV3$MISCRES.CWN%MISCOVL.C /B$MISCFRAC.C#LSYSF.Cjno"LSYS.H"x#LSYS.CWN%LORENZ.C"LOADMAP.C;=%LOADFILE.CW$LOADFDOS.CB#LINE3D.C!x#JIIM.Cv"JB.C"INTRO.C@..\INCLUDE\SYS\STAT.H@..\INCLUDE\ASSERT.H@..\INCLUDE\FCNTL.H!#HELP.Ce"HCMPLX.CVN%GIFVIEW.CVN%FRASETUP.CVN%FRAMAIN2.CVN%FRACTINT.CXV3$FRACTALS.C#FRACTALP.C:#FRACTALB.C@..\INCLUDE\SYS\TYPES.HVN%FRACSUBR.Cs"F16.C@..\INCLUDE\IO.HV$ENCODER.C/B$EDITPAL.C)D$DISKVID.CxE#DECODER.C@..\INCLUDE\TIME.HUN%CMDFILES.C| TARGA_LC.HUN%CALCFRAC.Cq"BIGNUMC.Cq"BIGNUM.CS"FRACTYPE.H"BIGINIT.Cp"BIGFLT.CPT"HELPDEFS.Hp"ANT.CXN%EXTERNS.Hjno"HELPCOM.Hjno"BIGINIT.H@..\INCLUDE\STDLIB.Hjno"BIG.H@..\INCLUDE\MATH.Hd$FRACTINT.H@..\INCLUDE\FLOAT.H@..\INCLUDE\DOS.H /B$PORT.Hjno"CMPLX.H| MPMATH.HXN%PROTOTYP.H@..\INCLUDE\STRING.H@..\INCLUDE\_NULL.H@..\INCLUDE\_NFILE.H@..\INCLUDE\_DEFS.H@..\INCLUDE\STDIO.Hb"3D.C7MN_`arst&'(|}~OPQRSTUVWmnopqrXYZ[\]^_`abcghi  def   stuvwxyz{jklL;:;*)9('&<=N%$#"! ~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assembler~Turbo Assemblerxfractint-20.4.10.orig/extra/frmtut.zip0000755000000000000000000011720010253142173014677 0ustar PK*XtĔ FRMTUTOR.TXT[ms~UX$/ų^lg89ʖv-"]8pE}~f(;W,=FO7:ԓ?/:M= n.Ʒ㫛?1^o>~.k?B_@]nF7z%_STd'SR'FGs=;z{|xx;|{ܘLl6XIQb~ڢ߻y}u;>^AtFU=_W.3*$K*]AW0 \_qF]–F]M6)G|CR#\WjX3[duյ.JSes19KR[{m+)l4WF72pd3NtDǼO: gsQBI'l,퍘uYgSj23|~lN<6ƽuue-<+^VThnVy:WxFd3\D:3Qhe?4Q qG.$#Sn.=IzMIjJM ?xYN .A3;󃛰X¬&̴a>%G\hyn7 ^=,)tfy93ܸ^ά>W |S4W\Zdy[+-œ!4IP96qKO!ϰN8 "nqVL$>詙α;'L¾~"Kly`Ov -ʭ뤚>^(!OhNcC@V`'5 Mz6 ;"9 ؞m>O r-OQiOŁ6]UYn ?]#v3 @2@8%tefB> u6 7]/L:ќ'̞=BGp,,A0]|0L"e.W<FOҺIUPoζ7ƞ7*`v=Ơ=ISUP&cP!ں3VVU*-dR&UOV!͔.9RFK|DV*+uy5Vej ;tpS^dED(X"K3C4iD󕓈$SNǞq%xn - 8P_x6 Żv6!47R>ĺ}l_3$ݷWGGjWcdjH:w!IJϑ^?<8<|jmd;t~Ӌ9d [T:R(U/JՉ)* ~j2,>Eq/P 1qd'3a mkMmP?;/bK\fu40(WXqھVqH$Br̅.ԵQ&)?üdE3}ǹsmt?L UdT Vk ܊9#5AqѬ31L3&Jaļh].7X:xSBpdҔhԄ`j mh5ÈIpf:k`&JO|,Aei4n91LJ'ډ 4щ! B4ta= ju;t]~ `xRT+3^g'2S|XQt4A! 1agMck٬c9$ʠ2ΰ:/'wֳw`VI1j#Cȱ t&؈i䉰 9Y6lr悝dF @.0sbyMJF--2n ͽIB rNKs9'LmU zs*-%ˁIV[`Kcee7Ĺ>^ܾɠWX L Ktv[N06Y5j}xV5HzI㿤jTV4kR ۘ)![BQ>w:LjqqH&)gPiWlS/FqW&(/3!@JX-ӂ%SFha DA.ٓ\,t;GpQ]Tơi]XxI2w?N$^)ؼfs hH[B9Sɨt`sXH< e n,to6W|q7\٘!k] r$q3J5D0a[q J}=16֏fSu}{s}5:UWgx;!>ܲQ_ _s AsFyIPܪ^qH#s>=f[hi&\=x́ei궴3x:ɯ a}2Ӗ{07A m.C~*!UB1%˞֜Dt]۬A4wp*.Kt"m4*^R%e H-Fd#!EֳB K}PtG.d%F{u@h2 9~ kz4Ic՗5i?P LxɑNq剻,Z0؜ LR8fg0s6Jz ͖@;Hp$°eHN!LWJ\ȱe̯uBL569fe$L-4ê kGg&ZP@ECjDeC=*+/-p9tFoR;qt!\w+klD`5L !>}Ww юVғ<=^!Ͻ?d>0o䎛sD7Q4KLԁ$3Y.9߉AK͈^;`|`wp>Zȭ(/ -s$&-Jүıl0\R8w(MaotUt.Rgpjc#ֻ;R64AZվ) [s]XQ:@?n;%i IX%6CAs.`9 m N]'#%BuUNU%9ns5@NV]5wg7.}1:4l|R/ܗK*#q%H-'" .hnv wc^Eb/&FVw gs"V;=xC:dT6hځ{NUIr㄁q%J36˵͠YZy~B9!6Zh&`>yU;o ؜%u=*S=i̙l`ȉ"oyJz:D{%Ų G<0S֌R0S{ΙիgOnKg'*W8\rpv>`,G{d.#66ѭe˳/P!n)$ R2,kw:.`" &.qH]þp|~QW.kk::"U]KļʣoڗRO@j|o5ӽ{ƸV3"U{kwx&[m__Fٌ_\4ܿW5C"c['wkTҳRBЋ4`?/@DH>7I $/ |n3\ˎ//>"W :7J 1 ݝh 5eo ouR4vikw+g_}Y/wmnʲD߈ҘK"%CAR.dTVGUGH9$ lg8d&%yN܈g?^ f`8x{NG)$$W8 Pܮ_xKHW&`e s#s5$0VWyb;ӵ*J^pE""WtG/sEm^&'Dk6Gȴ^o5g?߄d?_nF|%ۄ>sj7oow>4""E 䴒,}ei,0RrQ̱.u_noEuJ9Wѣ1$Kφ Ȱ5* e[tmQ-wrsXhKsQkɩ+tbأi&vp)8{{q܍뉰z_gU*xZB]jJ*CNa^W\7%kyCt~:[njr5qa֓0ĉG:|~v]Mw |IJf,= 8i$aoAR` ӳËwɯɯO~~itv1z=:?Gv뻁3\mѻj˚חBj .hP*pݶ ȯJ&\)۰.8Vדӗ.WM /ѯy$;:_JۿfWo.޿~=8.O#8ۓ_N..Ľow{Q,[ԧ58 P% !+mV:P Pr]-| rf۪"Zh7UTȁ:TM?֣"7ZL\N9y:\H;RY^~6 lO.[n+ j#kPeRaKB$ ٍhZϤ }1 ;kx +5X- QD"~AQzgp04Є:B?7WĝjE*λrkYQV.<.浐"n7Q^x^WU{ٷ};!DRͮ6xW#lsMe.Ƚ9[<]aWn`"렇)ޠ׶fFOѣؕJ_ &clocQ5SP"s\uQ:j8z.p˫@r*qW&z^pHg\jHY-6[V@g{>wӎJfU{7BK(w1?h% jf?,l)n{p gl;|s.0Zz}[LEH)b2a'}xB¨(DRd74d.6<\l-YRwNt.Es~yƃl[ܟ-V:7 [P րk*_ CZZy!YܸNq%9m )QnRB 8L7W-"s`|}:u-$ 7s%ԫI^,l O_AC2h3i2ۇKѼ~ːV絃|)(/YQ n%ԓfHqRey]$W_QR/]p*x%g ΒDѬa.KU(6bb~߲t4n\sucAepZVdem!{E3# eKxԧpB%YxrI]Of ]/go+ z=xuh_-yR`8Wf h xK!~YHF@&GcfP?]$HfH0Y']po5"(1_8}(rȃRn`WHX##JtN¬e@ d &mXrs}[4H7%NV)S%3[̙gǢQwBW00lnlKꭨ S2^;_6%%W-5ЮˉItÞmC׷K5w&D%x{F3 ǂ<)gE]|&ZB , Zx(ʦ ߖ+~ݙVci7Qnxx(JO&cAXL7:YGR(Ry 1 "?XN޿4/賸+Z6 .hNM8_^;Beχ%DB7y$Ӥ ehu ,R%4VbW/Ȕ 8ps m%|5qG! leU S/}Sq$ےB[ɒ-˘59 L [kٗz(S5`ra=7lߥ*@' G@ jA$`G8o#zRrzOegӵɹPm`G{OR>v;w.s fg>N)p> geO=3>lq3Q齺~Wjka湶$ada>"PugU`0 a8 ՇٲOƟq5HWYY{I)+MJۈ@G9+łc ?f *M?~ǮM!Vw}0trBN# ws@Z&trN;y!& Q)QhGb?Tg&&- `?V }U1r"9]([iL6,ꓞ<,xpUY@nTNfM H{øJ[Y߆۹. 4hS W}?쯎@k;&M3/`hf.O]{=Rޞ^me2=辻OOp? R+By$Nw ӟ<l\XcR>e9CVߕĕT -z]e~,B ,H֚f  \w@ :%v/'(W}g/P #Κ+4Y>́N-´Kѧ̤6|颴~x|͡ I\fsu|L!*iRv%dQJ3NCpq$']=Mūv]0ߕH$};س-g) zJs"MhSa>T*A[ %tѦlqW=v})044d7J6K^)@!G4"4JMsg%3%cw9 "9ex$1(T).+z'>݁ۉGcMhu;:L?Oq2"Umtj˞QꞕIF/d(2;P?B m#k-q>g#Y%B{z^wt ѹHQD&@M#$r払y% _zKT8ʴmcPqFEPcY1YIΓH>{烮 K.`%jkGc@%$ ~ I)y <&ϭAH3K 2VΤZ,#u#""R:&}hjjq|AZZe0( LՈ Xîk}*s1Ǐ_U_(AM-L^(}.7Ar+qZMN})" Ib40Y5&w6zAl4e{( n3_rGIlڜx)>S _G o +g (zv@Pd̾!Y!9R':,;TN8LNjj$6q$`R(WCz- R$w'Wf/O^aIiݼh'E'Q qA?5t#񔓭Q7 {SA՝yT~2^MH鄈 ?pFOW{XSϲ3!Ma3l$tne`<^ ?{))z'2-c$ f|+86~WUf%Q|yzxvsC ]SF< be5IqЀGf.~\{;BR¡FUiief}L*R9%.jXx%&8)F酙Hƒgt-4i'5DdӔa`!e-q#V;3X9%!u)ȧ(BnV뙕N7GM5jk/4sr-$UR)&qZ zJ݌`+)jܤTYaᚲ9]I9ȿ>b}S@I a{8rg[9!e))1$b|Iv/0./cr՟Exlt T7b%>l) ,ώwRj8X#dMEaFk'CKh jIPj)֛Gs#"zPo~o[l3RJxJ ur2(.ЭR5 зQ@_=ݵ*72| D4.?LX vN7}4Rap) $BrgR$[Jr-"K(T!%n|`YKRZrC]Mqp=>7lpLaZPOǠn2| F vQR.❁ ӌKE»l t&ڳZ~t?Zl+IBKmŦٶ^Kd07ژŽ^#` fJ:BrF// BM!~[Ok+2- 2ZќJvwaD9֢hrmA}Sj"ܱ9 }cAϿqPM#uQV2a`ؖL|Ө(u84NXm]IңgZ^6?aI7E=-YCUs B }UM,ja jb-*JE.!mG^0`fO:惆K!uc>5o2^PqȀGD_ē\-n ABb[z3oDM.e)$(hWH]16!Jq p"]_1aj&:"CwF4HGbEYNX4d kJp,hI_9/7|.ͳm p~CMV v:^YFeM'e8%A9K-s2Bpru?8H]=I'[Bw4T+9zrӂ8)HEOC7k\ck8ŋIx^:ژݗkʂiF0>mq.=}ݜ}LOk&=݈*5CϿRjf4(H\\J$ ^=niBʰGtzpF%н@D65 \? a>悈|vKO= %LCk!6Wlo7Њ-Vd[/9<>w3}6g%7d3=F%! i߄)#. X3,!*19,%8q֊!UC }d)I#F݉({XtiAR9*J9.(zb)< }ZPc_i N:n(5[ɤ!~Yhi&]y{+L;C~Mh!}NpoO\>j+-Ò=**n aw M_6)LS "X4ZD $_C|EU/U˔}6ocOկa794p O8i}[ ܸBKHεESzHzS^ {}ЏLO;5MS&+S>i9iiȅc(Pm0F؅MO#uYRj +|B0C+)]T-L;vtڱܲ%^o\kbNa{i^))iعXw.ޙWy[O%yuKJc׭FM!naZUп-QOzf2Fq(riG5q)1 }lXiKjej尺_Sq Xٛt8u{!+6i620Jm @Zor ;yJpk 1?gΆ>Y[{b˻CEr=BYydRBLdդ@{bSzȤundĥł9i^i׺ף5ͩ~75KwFv8XҠB[^mE> Zqr0#]Ő㭥o (W_ 'F\ tg%uuv.*jKcq*Joiq,F Gz,siKGg9CЋԑCtSZ-$B Q`CRQ*J,- ޶2%;*%F#5G'iD1Mgʨ$dPsGFD :ٜ+m-+)O1sj5_`_蝮BX(WW;c P]fHM˓w㳷5Ý 5]٫lD.){6?w.+y%8d#;eU^@\)peKrmT3Lٕ*{1q TzKWv8P)f>Ufo?3ayף-zh<4#G1bm6Hоԗ7Ɯ R Q)t9"0]0el}*(O4SGyصZ [36X8;Uu[V(Qc~JE9M2A$ R4+dSCX6:MK) {H|C2˚ח*dw (R[i4@%]DdcTu#[(3dB5+!~C?t  sGrN.3/=e?R&nQ>aQn{UNymZC9#W@4&gc RKRH_Ks *F>=AiJhmsʋ, мJˣN*rB\*:{j]Ř}zr98tz$Xg fʔ} v _p;8m&?=9h/!?C؍ÜEPϷ *!8֣`^xRl҅9K2q%~*g~=L XKV{Rv*"yN_56%ֆ2sSo`xgÀ144;Jjӭ_oFoOxP[: ;v̶ZiI ]KOUh-22 _#h-7oi6 nEm3a,XXDSOΠUdNVGo_eW'Ww)D'\ԷÝl;׍#z]s)Wj*['K]]e.xfgQ3ҤP lb1X  UԕQ΁xHz#qJZSXc}&KT[V Gzl 8*@h_e((b fX?BY !Z6E&¥:Jm{.Jm|*v^GQV!ϋs,)~U{ïsŶcT0;?]PjC]W [Ed %\7։"_Y,L^Yg?y7|u O K݈:Qh+@fI3ygBnXIyx'PT/K;[uzunw9Rr/pYqO(< {Vv_<.vIs0;5{u-xɄt^9Kϋ` vo]fL9V=3)@)| W Lu_!֓"{zI?u]y929$D \tɗ>;7ވJr)y%/nQj\oy$Q,]3Aƌ=W:7yj%xI#h"A¯rL\)iC6LWL双8]Rg6ýׇH]B1PBN :)iVk[.>=هg3H{_2 2fKp餢{0[|OûΦi5FvJ35`<5gnkㆴr!~S{K+0i; O { kϟXHBZ.c:RRLVwHZC%C~,@`yHHϐ6hԄ!,⿈kKaТ R8\*NE 4 8\vO9jB rH4=*C DAg2\6Gw1X8DYe QRhY( 4^a7< BEt3=fRrK`ea{ cCҔ ]7`}uY{[u^BJKu^(EHYFv'hb*xi .|KQF[=Hh C$0\O g#4]SpKToQ2*[rʈ%aWL3{[ ǔ w(zr.8#r~i?pv|zఁ *>TlLԤJ>ϴ؎UL#8²2h˕O!h}p)@$qzbBn:;h%DѤQ .[QEme/iٿ;zsltz9zkD᧨($\ Cp "1NDGB1(JޘNsYXHBs5o)G9姂9z%ȧ-:r_k_zv_aAFb@Q7%N ?a<<;^%gyMsLu@^_Hkr2?QV0"ʓ[{gth.pͨG.z`9:9F/ONVδwjd)6x單w4)skڞZ^dgtd^̟~wvד_wv^z~BɅu!yV4/g 1Jܨ)BWMNK4c, c7[d,%qYT!{wT#"1NCe&`{J0VD#XMUIae "fɜCf^;!L>@ONjg!{-E9j$*lLD2lrhUQge~Ǵt)8U ;!,$үjKց+-\#Xζg`oqm:yXX[+D>uV,rmm4*.ۄ{9,\ݩ}̂@qO*s<.Pj-Œo!f1n[-wZfJ=KD)S#'|f>íJJC-an:ecW=i=}#0 2 b}uXή732J ˔Vdty @CNxSښX4BUu .X5]SKSq{"DsrI&i&ˀK0gM1R,oĺr3MQ=B Dd5wL3YPg9!d\.԰HEYBL 1͔V: z 8 |ٯI1Cbx T)=`ŁX6*Zen@)26 u 6'F[[ᴟcR44i(!i9p)צ[ ֥I\dZ=@zA8S"o] 8?iq-c" B*7.O`7B]B.,^c`7rtY6qڛ!cQgن\4D?uᛖ§8X&ISS8#u !a?ZLs s:xJ ~GE  DO2de,0% [=r!RICSvTZ:CXO"YI~Ujy[ A=6Ű>??9y <78tRRsFgvv6zIg!11@,#Q6(б="Mc~њ(n|LWqҽ3\\xMIQ N#֣{xQb=c_:>5DFP=Mɽ̌YQUQ)T<Ю6BC}=hȕjȕ^ 7sGLG5!j]bsJ;8v}_n3M\)zAɐ&#b!Ll X#3Mb0C^jZ,=\%WϪM+ư$WX|v%#[E~ޙƦ/ Ll<=U=7=F\D|2 >⫴G pM)ҽ vt1 _beiF| #w-;dx_bM$Fs&hETVUUhOHr'Dg6<~b>1G]=qhsҁ}1 z.YʂU&ܞ1D.)Ol [EyAQ3 W!liQî<@ +ƙG<(ҵ%|-WDa+6ZX"pE0W!R[(!RU$5fuӋ調GHEpb+Rkfar 6zbD!/+YTXfQd=~u{TLX"؈XH<1;2¸V~T!10a&va{bg3/AXz`ǩ2u#e܌4}viokkGky52(09bfH*uRDU`cu $ix׈b4ۢ\݄ѯ3O~>+T+jۡG틥&'v`~M`sf(0ox-3#,Hb1kL\S=w%7b:e ఊ1 KdvA 3OŖb=XZ6%G]U JBcL p Bߌ IDZzHPpTEfP o8\XN [QWe ɔ֯|:v/(>XcMp-_$:y@?ڴ.O6dغd^r[$y [;e;'CLEnO?bZK7wŨJ#l-J׽k9@; N5ùXg;F"d\( ,)z_1DsT:U /j!|MaQ 41yTf:"1%ĠcDcS¢b8oK4 P>ѻwN#nYpIA.]w \Jx[,) ɟ NEFEVTmk-0**`Br5 aigMR_Znl[/BQ*DYxb8IkV G+!3kkF35˵ń7wsek͗%Ö3ܔ='=חgdr9mG/% )]m6L*unӱ Vl!)zIs5 Xڵy4 '>~ɶh34u3di Ï6J9#P;lپzJ]e3<߸넅E8); NꕤSqˬ89_KΪTL'px]!FM?a$. )I^ s@T+g)+cc%L0R4?<$y~":!aU ,{fpLWm]MVFYMDkia Qwž1p ئry3ti R>=.T7^H'/2^5eQ=) i 8(bY"F8Q%%tE{^-9J+hw}NRzұrzܰx{@$?&(X$GUm@2)m9hzQi(Kr_coE"O%" ULg>X[1 rtB$E6r,$l>~M CtG7&]-uMxz?5?  hvtKT!gUB+ּ P^+o(#6-8Q S ];:yuvqpoI"S4i9y:ك~Ƿ4$5_21iO_$x g)ߦ$n-]o"W&"E>XT`[Ki3?fAC NuݫK*`RQH̴'<|f 4lJ,0e.% lMݻWk}ϼ9[P0nyGN],3 =UDeRFp`E˩Lo34ya[qu/_#{I-H|<7P᫳@8bgԓhe[^r-A#GѹͅVu^^#$cyB[qm ܈̗I#5VW%؉Y#-w=${MѼ]B'J(T$#`}.,2ʆXtMB\`wbJ!ɦ}15a|#>F_D,4P{F$R%fQ\;~rQc [{6tKvu4yjsDCLi+}WW,['x2 xf. JH?<&Ov IlLb5t~Po!mȹ9r7?kV3@~:?$&BƣMEfy\-]#[@;1ز/R_4]34hRt9-~k,DT0wwUI F-/@^FK~u>JJGrv!ܴm"A,#(/hsJ5hŚ,p>9eM/o*݇$هyq>7[jXQ(tQެI3/GzjC]D&)}ZKz,Zn4; EўYY`5z+Mpq"{| L)$d'R+g$[?w^\eLXO~ )8(1ESlG{rDê*ʘ58~紶y*w.ӊF,4(. j \5uWҚDV+`Y2nk̛bq_Y^k@HxM-F:@vg9/N$\pMFnWlUb:_.zx}~ S[s9=Pn=4Zy)L^'s)yk,}xK:Ъr۱RcLc% c]wU87T]>r\2Xσ;MX".6ByM333G~B`՞@RldY4vcKe[ϒo53(> ^}n|pȄ{Bt5r5Z=A lbf} K\/ #,r`)&GXw T>3ktH<$^-*$H$Iok,YՊV)D7dYG%8 "}@N\S&(wɻ'Y=&Hm4=eB(B)#ʢc% gk@΀hKzmC2K[wݪEg&Tz"*)1o/Ghzn }̰V8E-`1Nff?v3J!9,nM0#zhS"qߦPk 5WٛG#1x%dHiSG/n5P&Wt% h:Z!T9z\k9)f9Sz{g8Z;3̜~sߕ };H߃$^){^^msK3qCA}mX"/͡&dp|F&6/Q*{P/֠˓vصmЂl IRٻo+wr5 A#pXϢ#sl*KsD'Ǵ'CA7*+%$ &Z;OVᦨ@S1%\?YԗS8p<d? ? Lsaǥ-撌g%pY^=h aWJޤ{m߃/e"^7~uH|B^PaY=vKvq`RNAxH/n'#=01+vel,tw?$6Ra[>RW!1e$_:~(r We=ftp7]l Yp}#aVpey9ց ÇH ѺRa/ԼID&E(*cӽ|[q?C 0>yu H哔oDā)7eՆQ!ʥ9{#utqDZBɕT HAH|G~ƥ@פuN&|{<2+kO>a ̈v[cw˾GKݢ;n+Iwi8 o'H/8ZXOL(Ž }8Me%D#ɪ|%1 y0㘾j&GٿIqV8llfx8ԛʹ4= m=SZd$NZz 'b*P4˲?>yG?#3l(L/j/|`~D  ?zjЮ' E]7cl}_7 /g:^Tyŋ҅ƴ /Y8fg/KZ&3 󴪣%jۜzCν-90 (4yeS4pp ,ʍ %>=,cX.Sp4Z >lc,\_bv=3`RrvRy[(X,;n| C)#5h!,N}۔ge'c},(4Q#?եO_ cc5F^a-Z.-@/FMQPྜSaOa`J70`;uNs"oL!F"/+e#%̪SW!X>@kBuvV+_~/AJ °\ucm/C0d.eHXQLYSc$Ʋp̌d%(~B ׀ k6JF@lҚY= VՑmx@7@'wXt|߈=[wVdGs*e@$0̃6u\K&⠃I̩ Cӄi+ue=` ihU*yJn~LhYHP8[iU%uӒe4 qmHfj4-^l׵o.ᎆoc8&m7˧%Y ߲ ~" eo; Ɩ`,&eVQ[j\*\{OsʴIY"uo(e&`v4aږAKiL8" +e4c۸n htn<ܷ,8J溁PWw"0xQ#8qJe !VLd ^m?4zR.s99~p$в8nTxKN:kJw>l1#ȔW}aorާ:xA连""G}ujw#$d<V1emS}D$鳞3g}|k\2DH<6\>HsPҎ|Ya4WL DE0d.tR`h rƁ.OKu@CKҨ7Y1lO2 }.9Ȃ[}CA&h1_Ps'[DSZW ٸțҦK_L7:Qb֫+j?5z7+cȯʎR%D6#́$-q%!MK$f(pأG݄AQ޷ mw2QLw0lq?Ϳ.^m Ӱ4;Ң x*FAW%w*9|̂z̪H:E;{0Q)4{T'p<*TAaL2Ce]wRy(HBsr'l)⯣o!Ud:Aq+!h`u9]Rl[ШQU^pY " d|iEvJі4`ܬ rΙkFN$O0"]AmSMIqC R4‹F}W"  0Iu tῨ_>jkFfZc):_O+kE>kXpR]楣>Cָn߾*nTPY]ez-i1iR`=sй6JFHM=oԖܞ5Cw'NWM޳{R19 0\؊F o' 6 $IB,8'JZԾtk IKj2UU~<r M'|A0H<тoCHh{ұlu 㺇nf ˃Ur[9TX-J>zGDE5lmr%kṣ l5Xm9z{?q#gmDCWXjW6_"q1' Vğ꽈ol 51,wn0Fk҂_HOypjDlr]dQfMMcコ[H Մ6j$(7.&췻WBRQ1ϓE_< $XMYӃ\@?&?0tI6 l&ESMe{ڕ'U8;z{[)%*j%'-"E[lM] 4XvQk vh#^#Ϯtގ8{wru$~%e6 ]jˆՏGB-Q\ז0WeAzʱ w^;PSI_aS֛B$%3l8}T1zO{5<ΏH <Vofo8ʶ?Ӄ\l鐲;\ J(GEsj#6|LzͪPIS;h_5Y":E%*=SUݙC}@iR.Qhl1A\ ócCHFr)% ҬLampl%Zk'xf& q\=)'BG,{=+»n'y^u\n7&k3&!&a 8.@Q笞RWLKs -_/X;;9 WV#,H[.M /ק_ JYq;s*xiO:J C;" t"{,aߦ~|nJ9)ԾW;$), Xt']::S:Z6B`j,G{&!pN IFO/]]{m8(":;?;ky)8!G}Qq6Բ%YY߮ UWzD׷DwАF4N/ 4f,)kk+ё66,ҮYn5~VSV)ѫ}*syTCZp .0++Ib.n?yބ~p9AT1g;j%jǶpA; d;| Pi-Ϋ4 nlB]䇾 U³ܦq)GɷlSt?aI_/N./X$>=8y~ikR7.6ˆUU8xgD=.6ow,W/Ĵsf$IvJ!! 4fZ̻;s, {6z,HȑY`(RJ),g/~N{o!P6n'oaA~.8Bt1w-,AWQfM/;j{ʓVt~4*sd%Gbf<R<:'쉠΄B1e:ыwʵy0 l{9lOӲf2WvT0h<rcx }N܎Boix;iS1тDVdL噭Szz -aꦸIX!@YQ,,s)]Y#r޸N/f֘/`V/&t(69k$1*OJ,MD#8$~x)Ͳ_W?9+1Γ#5BD_u}ٱxO\ᩨ2!,G l`aLo *G뾾!+WӵdUQ EeJ."%u.bmObX>p_XT-ox 1Mb%(./缘H\^ǘ5% 5Ϥ'a8\|mo.˫/v Jr  ;>[S# wB>`^x\uao}A# o%lۜ$D7UjQy]ERJ*qiY[hbUxG*QXvt2J_~tF􃝬{i?aDLi-W >1?~Pwï/x]Ф0 kPX?C'uoͷ57;ɅABK)tN?f-!t:?DhS+3Xb(apoUӵ6sPJndE+6Ơm/ r6j'n|3Yk%,W׬$U\7i??a?:wN}J{C$S_b=,O7Af"&YIQ24QR}Q2K[0r+A!ؿw2%H$n`ߦaF[Kx!>))3X%IZ'pS䔜'pl~H};u8d^ ̇c[v"Q—gP[Y^"P -r&\ R'9mz:dml7FsIA'wF63sm7ɪ)=U Xaj#(\iN.`  W#H ^45)uDh%lNLOT2ry9AyBJdQX5kq2tmhɓdR6>-Jg-,tzNq=b:Z "kO'jfcߩzA;leWLacX]/;MlerfxL-Ջ@͟&5nfl `5 \z%SSqF''PDZ]q vq0T%GDYsu1 0/'ҥus N% .(8#I˝-9koJ'GԽ&L7izo*&U&-o#4g,~q!FG@̢3DU6Esm 회K]#GidaJT~^;6,KMIsfy"S΄V,j2N6d܃lS$'Wr2SI)z044 T#IrķmM0b[7?[V6 Fz)o)s=_S( (e's3]Rm,ϭZ;BmAc8ğwDT^*ͨ*P .<6 \IJJܓ HF +zli9/#:G3 t-=gx?A$jEi@(sRC-#nu´~e9ƏQNJqpQ8FC~)7eB59u? ޙbEmw;!ϠNnkqj#=PvւbL*˨8IbD|ST.SZ(*R&0=D:v#Pf9,ynU%Yq$",H@ tN`p-p$Q,Mj2:LMMq)6$:^#/|?h wRڙa tjs1 BM_&W 7iye]h{` k0vmիdÐa-7-M M<+DwauRbн䝩݅YŪ7]: pU=^[\oq`A8Ҍ?R)ZKRRPݽp^fʎޝ=%;}vy{N)(98+<;3L.Y@}wEcMos+ #iL6^WFBaUyuMڋ÷ ˛oLrR˩&˅"inUƥo:CHYO;P, >e[KYkKTX2g/߽增52l`&o&hi0k+{Fka)}2hψW"/!Ί%*_$breM<BuSsX AnBl7P|G{],Qvy{&C[kBkMYS<ѿA>\iI\_w= _E;Wr Ϧ(4uUŦq$uU*(F6S`\EV6yA㗒y\>9zZ!&<~sxv<{wW:=9<h=` }Ϡ^L.LY242laŋs@Kɦ'T McU3( : ͢V,fکPx.r`-^񟝽q w^[V#B.t?hoj2>xQWIp[$.3}شQ~B RoNlM>9 Q1'.unz;˰슽kzlY M '4LB42HfiQhCjZ@ǿQ,8! a%.E`,L@֦K*,uT9xtrWL$$v K߃Vz.!gp52Y"s ) h=vX,{,ڎ2\vx_7YeXS'ᛵlj/~nR6BhbCM-פ_*9:WSW O«AS2]X('/g0P{RI|0Y ۱'Wo_/._NDTnd>(BSS;`t_? 'TRmV%W v|k^|(c:Ws[X欐j <_3&Z>/%Y<>˓1KZ9JL-lD%yx O-*q%^B'%|ҺukJ\8zaӺހ\d =ttCGYs1 %JKt,ܺA |,6tc~|vSAmʝ)}4.MSb%]x]0EU5zFi3oya^T%j^i8)+flt2ۖ MJ3OS!:Y*>) R}+6x)y3TZ(ePKsXlۗ FRMTUTOR.FRMX[s۸~L$K^qfgVփ/֝:Jm;5I(iK\ulgd( 4Y~}B6`\r35cB\1c9qt)K9z5S:-nX,MT#b&3i }Ƴ,JVŮnN]w}da `A`p<)!#oʨMcfY)`2 ~ -.b I[r{º_menױT2F"_aPH Cl}˔ϫWR|u"e:Ѫgd?dD9ED71W{Y-Y],4Z HY 9[*6 1ҨT?cF2t"pe0(q9X2l%K|<0 ,rwi ^mLt40@΃!wЈ[ lD±t(B@72QEr3K!bH|Rʭ!-@;J KU,k jh!Ȗ%ײva%@ŸL@hO Z.UAgX)JcYDZ|*x(دĊDBcQG&44~57WX,AnN  9wXJ l UEO C5>ƒbo9eexNL# &P51iA(O\& # V6x(Xa[롿}gEg;r_ytݽ9ǟ؂L,LOm(Ҧ" 7A-CT J{ڸUJ:[@׶8+xp8?jeXxP.oYv#lvf= gRT| 1g)6Z@P_ 8Mo`[V]3&zL\RF4Iqt̀!!8&tH.Rr 37υ]1E[^m7A" ^,6ѽTY@_Gdb=ղOUʯ\8^&I֨ 7YX>%ӡJ LP á&kv.x)c$ _N^EOL ܌[9WѣɵxЩ EA F!tjኣwzBO9 ` 4SEہh@ѻV ZzUX1<8z'OWB+)#p6 SuGd؀{kx ̰j؋bAV3 3#^H<|ov9Qmgr" O![ݖ#{Uy{2 9MEZk."|Ч}G .֜BtNӴI (xJ2G#4&#daglN-oT69ZFx$>QvΔ‘`^gZjֹcx>Z롴 ln7QR6 A 즄ʩٌ;DS82~83NȔ$(^6F .T٥zܠ<|PKJ)'_}  sschoice.asmPK: xfractint-20.4.10.orig/extra/makecfg.zip0000755000000000000000000035454210150522423014763 0ustar PKb-p& MAKEFCFG.EXE \0<;,A]#ŏUHe/tG(JTYalئMlCMڴMDMT FM`0$&4D}Ϲw49{=s 2 cdb~)` EGUrIv%kuF[E&#d|pq])8&6s/)71N6{F)d)%:jĘ 3ɲB7YWRaPi4oذ'2f7fl,PdTlPYX_f3R•¸fvc9_Q^e[6C;ľ6{tTEɦ56WFIefB37`PSYA6on\S^qCI%&Hd`sg\rM@D߭$a mSRTtT¼uØoNg)%ě $}?֗͘N8=itZBÅEYyX}ݣݚ∞t7wUڠ=fdD6WZTޖìόԾIBud&?q4k<_HK59½?|{_œ%|dUijTCLDI½fFf5#w½#Nfna-s|2S6pWm-Mg8ĤYqf(k4Ba s`|>t zSJqƏ#QFDqjǗJ"G!LqFsf#I i/0f׽#*5J['MZ^)Nk5IԩQ d;` 8 M]MXl¨xFV)b5@DsXI QF^[3=pu̞ LrEMrÙdcW"-!Z5A a00:cE08pF9|(}#]iq(f^h_w-x5F&ҐeJRx0tVe ތZ< ȩ{jrV٣ܻ[cr_!B($lIP6ί`1ٖbwj$B^KpwcFִh5LRk/{5 ӬW?ArY?^3GclQ535Ɩ|Zݩ)-IGi=Fi#FTſԔ:ӤN唩+eSڹ Q%?)\ᤦ#s^݁G ^<ĺ9"u ҷ́ G~8Pzj96@樥Xf4ym=+ `^^xf̘eu7o@)Z%79D-*LL\fDib)k+וo0G6M%*'l.& g$t*nڍ|c,X+ BО-T^`u Ϩ@}@ldE3/r1NmaB!8F$[íahra\>/$/#pRwMcV5v(BNǠf;I nG%hۿ.a@ 2j.eM7le0GuUmf.1wRbܣXHNF/k#HNp"mM(_/4mωF+G `Ǎ@FcHxUDm?1`tOHr7E-!]Bn {౮>RޟA7s]3h#{2U*'3!H:1 5Jh t}-1a:U!ڏ4 9ܴ5R#Զ}۞ Q0ۣVzi#$KF@/Pb,/fN L iX=w־qw&rH\gMNwI);YŪMt@l'XFof |w~~rJI"ȼ=wȰڟU_ > R ,2SPrW5n ȂN| n ztV 'zB&ಢPk;(;Y:Kݨ@ehPuǸC@bV)W',T]]}LWFwg?mAV;OC#-=&~'oȩ#8xíKKZ8H[x$x͌oF|x91j!h XUݧnɷ̐]Gz]:}CU6{,$kjg4AS;Jx\+ĄP%I+0@PxBZHcD׎jx}%<+ ) +1( 8}H|>nW*C^Y[=l7\ f^@+SRu̫h#tץ+S2\ _AUڽbؠL,yҭu.Kp&q4 h(నWN7melkr6sIkms;g 9 y&s Qs*n4n^Xf3Y+*c2c1ofe }F6#޷n2-۴d3W5'ڔsFZl,c.P@q]Iڊ ܆ͤ562}z䙶i'C&)ZG.fL~2c1!=woq e[(1ty%8z\oήAapo$5æ"m댑DY6~bK7Z&v\@0̎꾷d ~UP'i3dj@T З'ܺcLltgHb:GRpSn ΪH` Kq&c> BăڭCW*sH3 i%X;ߧQjRcQUZ]{A_YT3m `´{0 ^ž=*xό!oD`nL}nv=% / ^aW2,c/0翦-b;sn_LI-{~3|rXNU%2-˽rJnMpa} z*Q[X0椲l dۆJhnCƄe\e ٸuv(5[^xQQ \L KUl;,)1˶R'8;^RД7}VB[ \*e`q6Ⱥ~#g\/LP40]`?Yɞ /e& ń3#q TNaHv?,'>NbbKTA[$ }dSZӹ@c2KoLⅧda\ cf#V}̝S]#5Aݑ /rCh9hOQ=}au[:ҎaDwݷ&kl耕 ~`QB`4 fQwx j E}̞?c6[+4!=sȼ$_,1;bǫ~tH2%L&z 7m;.,Fa-L;r<*L/*m3Htt]Y»8²S]N<` \ߑ VL!ɪ@԰^["ncRw,RiI^Ks>"e^%_A4 =ИKQaXM@ :w il9_v6Ex%M%WW"y: p*4ބ鯂 t17F4q`9R=G! G!; N@~D2SwRhQu&KO ABJ^Fkła6w %>Bh :L@+fꠌULy2gHrzCDJ'?)L44+Қ \ dX& M$sOdmj-Լ(*1rR#.7A9ᓀU7uH}F:rj`OFN\iVi5B\j?k 6rw]SoeBfR#fh9y Bۣk]0VOn)mU:1u6$pWD UaHW7s ÐIIs\_=> 8Ja#p8^Ju2O8!srYQX0‰LQR ryBh1.mZ=886cֿ̆LQܑrɓ%ᬻ \A+*(]qg} eǗJc5 ,k$݄XpluY)+".-k;!kJ‹8G]kx9? n$ } zCpL~xMcRjz=W7=kn*?)8?Mʎ *JJ#NQݺr7Vwe4hyr61 $~w_ -3ex]%ev/ {z/ڄeHF%!:lBƲ2F Gٯc=,3y^ah+|Fw3jS.~V̂< z¹rj@tM!Tw [)t`":oGZp'Ƀ.L* 8^2-(=SGd1E=*1!3FEmL]*a|sƉLZ>V4Yw+tw4Nyc0|1C]BPVzKԩ˯Da1K$58[ʕ2n7 n;H+IMAdA)\OlNw9kR9K$ u -_rLW*>q6NWqnx T8?5oU\Gх]krsEh4qGX"Gx*Xz#.*Z??kceR$o1qD%(%P=B窦)0ʌL4pA?+Y˕KbTl.l\[QL+k}8<0o^]tp\ɦr6!ݥr\ ~^ Ёnټ y%xx$V̀uO46nα]`RkjYf;*dȻ@!\M`~WA@C$Q?Teɗ*idt2)@Fq~.k3TS E5dCC4~uw0mPN,^:M{.|ĤNԕRxNS64Jƽ |P͗>~Jޞ ڧߡ}%~~L8/_ &VO϶:F=|g>d͞/Jl–kQO#E'.ByxNx`w)k L3URҢB̄vv?N7sTp֙յtдʠVĵJ_/% ҝ|._akljYӶx"RCdLt6LIWTfjK'xҨ 61}"S%w[zW<9!֯V2ÓAn jq46]oRoPo&wCxٮ>wv+9uʝLM۸LQYkAF\bUv`}9Pef&'5 ưbIW4 uv,g=Nx:ZSn ӸtM]颡 <_ v0)[ӭ b{ |4wV&t@6OG\}$qꔩ9mJMSy{"1;f2fQ U+iP&5語@ca?2H mY$.<<՗ߢ(+.$H޾ N~\V@Gf; U꽛A~ːTit1v"eOhv.mQXI k}+A0oV›^)wf;T\P&FzQ޸R74k(ՕR-eG%9Ү΁AHҿ2߅ Z[ҞL*V|( ' <#<'aVv'vM~hmUͩĴ ؁7EKM0O-*qWĉx/Z1bBjݹ1ݭGStf-xT@`m{KbuBuI ͌Xihm{̓W+Yfufb7xƺ$/I`Ib /kI$=m=MW ng Gs${aG9NfXaV(-"۸&dOx";Avg{ll Se@N!KLM/bN+Ihj›*h:2 ʺVY{:̌<__j'+2`q07tz3A#;BKԕdϣi#Z$9I!Fu&2ڶ)`aK27czPhɢvK]@"+# L2#KG@cSi~w FCB2Og1u*s lh+Up;hw1%F,0Ogl*Y%Ǖf!fMV!H8Á6՝LXBRH&J] p^CVr6nkJpzC«~oiՄ&Ew0Exה$)e*koj<Z,3ƥ&+XGW[&{o U,e2@LK6$)h60hw dK6&;qҭonW'gt`6]Lb!` f6 &{y/r7_R2cAb&#*>4/!>m5`s?}<0bB. b_)TZ%O~MZ-*ٖ f\fF2ECk16{]k=vLsc_8J|z.Xt-yF|zJ FFhĔgq7!M;vÑ=c1hK:)Vp 27_ ,&Aħ$Eh,f7;sD7x?bQv8Y@HW4; DGw)1ح2xj]"0u2%hX|*H8<Eg߂S$%a]`jg|H[58˫A$tQ<Q@r"]IDZP.!cC)K5 ^aFT 2nTXɫed#,Pj]!_ FA>K8-hjCLPR:Ӱ\Z\wtp̣.㿠c9 RVmG'KMCmD|:zu༽Hz,tunZnkXJh;X:GF^vZ:ʗ Er6j<҇14q)3KC[QӠGA GJz4 X+RIX99!:T_ Ľ/Fmqa:?V8Pc@lhtH ӃÞ72IP@vE "m|jzV7[tYdA: HHզwҕ" #>7Xh.^;6( ]x T1k^1Z R]HI؈qcu0VB]N7nuhu SGq! O$H ho $aZzNRnx"p.ӁSȾc%4֚Xk&rəp2Ũ5jM\kNdG+28}b>Ƣ)"zI߇%BXax4CpL7phH =1qsS#鐼 PG^FP7x& ]|]3OdbI+~ϣ eB|Фlfwɜw(nQaA@jf8P"d[P YqjɊLcap Pl?[+= =Bfc]+{`jcFAm;[nntnӻ_!_+>ud] .:$t2lCZ`Ig%n+ NPf_ gV X!U8-R׷ *WXO6}Mf2(D+EB<8:=!~]( xw6N+{|[FY -ER<ڥǎxW#WCR] Y.UJe@`*KzMz;=)hl7p]#&KxCyn5TXiaJԗdHlמprvGP;NU;hCxʊc@VTak?l)xgew~2Q^9l!!qv|!\eMvvoTtsvo;Cw! ƍk""Dl܈75kK\!ervt8m|BwLO9:EǣPke^svgl~o^4~h:i#.+5ڿ]JV-/1hRIo2爵-s]S- a0L+1aZUU TiICׇt26nX7ɑ4Lb gX׬/1L9mZQTpMI6kd=oQd 3o573.n73YeKwYe͆k?S1ǝ:p`Xɬ(YPyHvQ<&A~=ard܃ۍK*ʘxBNc4nq5%ٸa. q$uT^0-l*16Pwеa6lqCJ#W(IeFؿcZ媲;g'#.0 Xy$m WE3dJ1;NJ6l[[Bwo6se,Y[4K -[@DFƸPLc[=+Ӡ~+yג:r@҃wyPYWɔT2Jf}%SYdckm\$%1FJxTIY:JG `[G~߆:{QGxv'BGX XFQHAU,$k3&/o K @-f2]k͔9%fƙ2MCeP7ɱ)$zuNuڿƅD\-&}ATgɎcP&m6qLHx8P3Rs4֎(c v`P[JS)QPCF}D"R=z96sZa>EH Z|BAg"\ nJgJ7xUz4g3[Mi/Bre Ow z,h'J4t XgW!oh'z\H=CKadz5cz(Z-"ZlUj<*mJSmCw?M}W! xPUFI:5ڎH T_W0ҡwGB csvD!wЅ#i~0D%ehi]dI5hgdI1ٌZh7l #v%Y|$eЖd8=4$S8$HƉɞ9m~r;&;il7|$=nL rT!ȟSoΉ>p9h\ZK^ǀcq[wďWDJE,bEJ)cX;qHB SPa .؛ͮpOuDIwA>/h_& vӕpdUm?.:t1 MK:K7pTߝktL!dPt'\tA[:61mQ4cbQlQ\B]%ɃOLxc\($ 䕎6T-|& dv\>n\ L?:k$ Wf d~D9!׫8 #u&5&1' r18-N}GzFCU+f%hH|}mO4q5+.֊E:,ζ'g5e:^_͙8^fŜxhh/^ǽ ?½f}!뾏tK/4\htտ7 >m5B߈>]Z$C-3,TQnhXܖSRnh9qPNBIpğTN<-e%k*D7Ux\M\ .F%g\YJ經CHeTdiEJlVXtW7ʉ.??&V'*,d!Cq'R^F7ڹ1bnl6 D^+)BWVw]ApϠE[ A䆎}@hmY gvUY9=rRއ$OǕJA eVQ] Q7Jē+ x,:gːi">^w^ZUt[W /`Y1}Q!lH,.s՘H|Ctla`ՎV؄-B g([؄DM)il{ :F̍Ⱦ-:JE‘/n6#)YEe[J6#+l/qu)ۆ J09K*\,'37n‘h,ffl$Td1JY:ipTK Fɶc|@v{ǧHg_+ [ˀiQ#;k2t43~1RF8HύvTvpGEvLbpۋwG&^m*5G,9)]xq"|nj&m\UFFuhKӊI{NG" ]#^lSX|6+hQ:#od$V8!t o+ܟ7",JN$yrW 2}W{ @K:H8a ?oGjDu5@@h>æ9pq9bdWj.H3|yDA:DnbU7;*mwkDj*Zzҭһ@{}zc 4_z0V9@  F3̗>ݣjmQ Vyd'ܯ~{ `ֺFYd[[OD_ӄ]4DgnXLȚ/}J7Mj,?>*͠t #ɶ81F+Ʀ=Η=Q-SM\W&$Vyzz@X顸SjDۆDY؀ _7v oUAujkpa*,UI1fnک\ tgFd3ReoЅs nfaM5m"ƙE턱)(^ٜxМ_$m VigQ'{wkB{ 1tiSVK"\=՜gBpt0Ž'.GFD5O=j?6Qwؖ{{"4@g$m3B؋˃Hpqju't/PnD#{2/=" &kE0%qCq-aV"VhbÙy$%'tA:MjǦFl(N;ASb3)uJ\aR@vKiuCk6zr?vqXs»d͓ ɧkrc)u8*R%$ϓ%4;biXL:36œSJM\E(?(1ҽ$W;2#=5O: N[ձ]ut<j#Ѝj%Yz;QtKpYrOIw1j߁|5ǭά`58PKcW\voVrXd{6q'NwNC[\g[L/^\EpqM^L8u3|HpSڽmV4+dEYGNxĽQ7"S@܅*θ;P5rH%i~Zy-?TjGSḹWeTx_Y;:Gt?t] /UH?_'٤-A3]BOqZ p/9C^r5+Βac14FhBu$KF;kPIZimT2 m7pW* fu>_*}DKeTBt}҇]ѷϻJ[>(w>\T/l6ڋ mQ;Pf\F$TBҦdﺓYqD&)))0 $K' U:@ GWשj53TwZN~3!ܨ v✕T sgD}h55U ɥvj+ǔnEE0zb*kv1g8tZLAlki`)3ܹ=J0kQejҫl0_zs p3 %E,:*#B$!<C൙58y2.[$#7'4\1/t.2:].#T`JnO5< ?!˓VNwB5&jSK½[ Au.J5T}1Uams%SO9{7}Mjv7kS!;!ݘ}2܆K;?ъåCtsh(V8$^Wa6ݳ9\4$wAGq#O2VXvhZy$]4H<| "NrvZ)\v*eL|ܷY$=p5 H2Ҷ4U DZEJ(ckz4Jg}+NJų3X2mdQW TMc]}t圀%0 OLos(tG~Q+Q-A *̐B iܩp_rCȒ 6l^ r68: q~gTgWn=uD?Ci'jKhdahME7BHTzrzijּ|3|[HQ w?划7+y:5SE=بtP#A*:vCj(oaFrM'~Có/|JΝx'WH-b#2ed(lavGirpO =b韒W,`C Tb٤=QW'x A+CfvF$D&E׵04y|{>~P dUl fd?0… z;C@Z"u>ߛ$,F# w&IowL|,iI1QK6}ggb3{yAn%X傶y~s1\:hm}&tt6qM\$!O`<"8R}oxx*"MQG@L,l%S<3IL d]Eu.\ˢl6&kg w.hNIzDig̜u=)5]Wb dd,ٌܮ;hYꤟjcmk!XQ:Q3l'C,uZ_;KDHOp. Gѡ1pwCEu \vRr_ ݛO"ĨDM_뼾M?Аz ǿ;+EٽajߦG`cuWroLw}}{]Vq9%8ew 6\Kwd4nQF'wD6n%my;HQ@u^>kwg]0Ii'o'tժ`yu`pWˑCȂ/4N&wy^#X$Ð>1;ia_zv~7 ~ ?nwrP69Z4xB[ ~qRv)1#Άq=i*&Fk|rG S?f EaAz?]6eoَE8F nN)w=PEDxqutcfrzj]iq-}ZBLGz^|tPr#-Z1D\3$")1'  wo :g*8GTkAԱ3HȎ*[ANSBµB AT{b ?>.|za㲅ډI_h'aB]LXPQJnS%(VX^Sז Γ $~(bx<>ҙV͆X]C'&ĸAnxٰwa"|䦋a~L\ BPS;6 K؎! Rv48meu\,"%9=Иw O8`GYPR bHJ.-ݾB|>\xwQ"7*3Kc!Bt|!eWy>f}D4p43ɍ@lZE񭣾Gn edUJC a/IޠNlA:,^y*IIS㦺 nOR[`90tɺO8ryHх?Σk|\k~Ll,LR$jL<s;Qc<}{ 먨@GURU EPx7G dȃ@_K8ESO> ah"u}I$erGI5cc4.j>i`'zN$"ZV8&w-yD< n1߳tۇlث羾kSBbl8D[T&g&1 żmկUOV2mzmLi~ZCh~`9+XZU >6⎞.kbp;.b) ]xEmʻJ?7خl$ ^XoAwAQ*?hmK_%m1nL\/;m~;$dH9E\r\MXN?+$HMup۔gtSEa*S^!29xRc۔CphuMWV] 㼡qĄ]wjLC'qV;—U. 0Ɲ_Pcro'Mava:J__'iVm'l's,74 L41kU~qʲ`rQ4h E`sLQ[K?.9G*KWJ wx0?Vy#mE^پm>!S ge1 `Z1iEHﶴZ/|Ib]Q2' bǿ VK+ZZE1y Y!P1eD5uu֋o^:MW#tate0IA]*޳ [ 2ߖQ!,C9@ɩ ɐ,Í"⇙V%Tj8L㾥9LQf Vk4eW Qtq{?Go_+vKlcD>N\_W`PsemS^.$^ vܘ8nL3(ǍZtYC{CEBW۔F jw@dЅNuyA!C75v l^ "϶U_mҘҀ]' ]a"ޫr18kKs?yw_)Sxc>07fc%Rpw^9$x΢ j5ٮf͔kPh&e ^H?Al©k_5P {MxCtijqY:SO8rqE 3 duAT47 tny ;]=9xjߠMit][M{(:k-ajf eњE̼6S |,cw2L8<^Ef'!ԏ~*l rpj22c)X$]j爳p6=0Dd8IXAjcs~|%PƲDz瑨;GMϋft:Fh~]֏[izkl (<p.]&9 rK,2zye}B|[.5!sfOB?L>Sܢ[; h!u<@vX=vU׌>V&g=7u,1Sj׷5مˉ][w MGu~߭cdh7t@:ng{Ѐy͞ |*=:SV *~tG7gU<i,} AZ( *,HVkϚJO۵Q!σ)[[72(cM!'ĬJ_6. 5al;m"pl9[ 6~͙[8lEd[-M7/CyHk(KvdycP9y`HyBWXּgiAvbǨb@-4JD.UJπoe J+J6'$$%$g h)孨'ILa/~I؝{|\puƉn AؗKd(b1ȮC5u/0r |`oE)Sk ga/B~EW*fL3$'Pۂ^3*(0_>Cfd@`. WqxB) LGhmn ,|Mp$&$"lcxnM׍@( ЏW<7Rq`{~1={"~l[ 70skl,9ҙVÁ(Qd,@-^?[(= / @Hskވ9/|I]vl?BBiNMZF4wgBj2EA``bk-%l $L YS`ހ~R>fMdPK(r$!+|2ڞhr>:kp4Cp3u|&WZLT{Ib\"8 B sCB"vK5O.CWr[+ž8++[tJfi/B|QgJy: f*Kύr3`16sD@qHPry}Id*|,(JJtˣx*ODFphJtt ;t!O@"d9v / %_l|lqoC ,:%I^?2T@ap.E+5-t g'P,+VW&T-$g{PO _O2zP6aHvL?NxYdnV1!L?9 Sx~AUu*t|/ z}9׺ QܥZ4 + KJ;Z;0>l4,JكeV5J(7HK>kJMf]{~Q!hl9be6pPJEP$}4׻JFB%~'|cЫoA{r#Ҝ`Sl ͢{^r !$taҋlC66:53p0k <؋mdA/O*HW:aaЙFbnrY\sk-◈]U#r(БCy;~} LMi\#!u3VNzb:nD&nhy]ZD`ΖW?+)lz.\'M`jom^cDiۇWiVbP'9qBA'ċV1>DNm ݫ'vL^d]6ͶHPgN71PhQwٷA~jK)odmdXδ\ӴǗFRciQO7)@/#B=VN79;{B (2|$a"9| V\+g}ƧpK쫦K;sN\1a?UzU+?:|Eʘ1|:=Ku Og' &K;]A8|q )C C%$fQNZBȆsL#ͣ?4h:ۙ 64c(Q3f9OLf= B軎9J{IIaS^n=Ҟʆ ŷ_RJTD"9:G||-}yj]}:ZW>bjxɋT{ OvI_CeGP@@h7>,t*A WEI.4Mk w/{/ePf}PXKHFCw@^ V'KzS] 3sP݁sZ,Tbk*U"PtQE׊.] TU2񚂞:[>=zNZAjbX%Ntw:,\jTJ $StEЦ^}u=TBph*wGa9/kO5v(TWm\ j#c sI\RU ӹ-W 261k#<'ψ*WÎ@5ͬ7*?O3z _jo8P{̝J#\O`Ħh9M|;,NPk zA߮¦ {-Rb' |ndVu)> ow:4 0TxPHVxm#p+?҈%Ž&ֲBS7ny(NCtlM>c۵55J2@xI[s,T@ LSlHM ؜i4@솗 2>l${ +B+@K{\mF>mSqw߶! _J~o-|կ A/+mp?/*qί}0iZg*ߟ?6}w9}ovu(s'3!vgsm$),Е*^>[ A 6CjpHt\dS|-yԃ渏VX8~pfT|vp󯇆oK|BK:=a2 ]29P7ʫZ8KǍ[÷.t|0q獸b8AH,?5w:[H-=Dhg٠4lY|^,DϽK<Ss4?>.>7Noõs9_P!g fHhB3S-*<Z'vAH& p蝦[$njc>^Ty@Mu8AQӠwzn҂ _HHWG'"V7Mf0 ҾaJTVDL+DhJ)չ {K YBYV;Nk LDZ*oS1! U/lxZhS.XǠJM<@$2>% kvzhZo~ Wk_Tevթ*x? -x[t~2X,3l#la UZxࢦXх|2BZV"ґ MpD'(lc8bN̗z PK˗+|p4\?(WA!~\Ј.IR+" xUoa]3q8}Mnu0V ~VNfx$t_myGo_K|H )pn ؏X c"O|e7Pp({:ņ]&\b2"W n-Z asVKJnkNCB ."YpU,&}$u]ɖf~F1Y[ ȀA6 t,2QUBO{ AGeOHW ݥjPB#J8kA<U\5?5 9q7` 4S~Rej Iek+j ;O]Rkxiu6i3|c8^#ΚTnX+Ufs{  9@M\#VLJ25UĊy%u UqTBO!I b&j=u=wI[yX_d-~&fkȀ<5Ǯ;hؠ~'kiH҃m!ͷ6*G4_ف+;|݊H#hd c@[i!mwyHv54S#Ul Q`dP|PReJp k1zdkp-(DN'E>5Ա:4qg* # K;I= U`YCIE]P?x.M"75t&mLUm Q!MPܝDXH4_Gep 5 QS͆GkhӒ3)ljqybA \<\[dI[/HVYou@¼YTjw㷛do{(LcCZq J>,5ˁ"_""}d^rFl"a !F_*+R2THyR/w L)M8ovB)!Po wsT cBJG`թ=w8x֯Vb(Ljx\Im8ҮU@i HZqw RFv@dh4Id9Oy#Iͺ^Y:~m ZfEBh& KSsU{Rq,:J^14_c3xhlaxX$'w놂 Ds( #K Bd!!4NPA$ZAm'I,m7C@ &JyBdI\qc"jGJBRĉfgե+&@'Irde5MA}a{m(vFuO;w8jPDD Zh:9*_W/eQ`G~eKEaBrKg"WC.יp"or"7U8ߟVCX2fs?_3gU@hjR@2`Hdw]4Ceo*7O`X[? OX 04u%#@ *=pGS ŃV(x<}C]t!P6ـ=m m7$˅TpYZ/TT3B!NrsぇQ(O*teA!G]b4:ࡺ\TG$W2*s:?90k=Gͺ%~Jr0ub뤒^e^0Qtt0wh]~>%X|iӣ~R ~FLlىg;Ј.x q11f'Nqc5Ie'('蝌s@oqLc͖Ǥ–hsv1>BPuq2s]4P:G+˻Bkv'XZ9td vw`7Jv:WX% ˅CcV5 }֢ l7 㑧e1 cak yIB|G:!Sq?} 6^2SaիJ9sx7&JOa")j3;nsuZ^+L t\$a,lh!mHiT%8HtpCϫH70,&ЌuuxKPJ,!s7m=r{e6 t{e4)wEo]>m*m] ]@U@|'翂J}g02Hkn BcCGK*RjrO-T*pr;K 6Dbp=E?Sgq4vUdnXs].Zǜ1}*]uC̎5{>~Ss2~3_P@Q{z@뫸ԔUt]?%J}AQbUu1z *d&聰\,A!XSJ0Od\(,&S"s[SBH)ԍΩ]uq>δS_ƍuܜ-ɛ+5oC +5#eK:vnT6ΪlVLhnNe1(zQNh DXJ^E Dst$G2Db.f50m\[+j|LX( wlowIL cag֪?w9 o8] ʊ(KmЊzFV,,֭NҤh.m0uYi;*zIb1P?64~.4sop4Psr2䌆|d#hy6y]>kpu`sd0ꓲ@/t ==©vVm ^_cζӇHztV54Epv绡9˳1Y>%6ʘnۘChVH#nAKx6 '+ 7 ]'C ?Cu10V%8]%$ j zgj{y}0Z#sޫ[?:}p.@Jܤe68q&Ǵy2ozqNHjX)CCWcG\g #^jY 5hlgBx)i4YB,2u݋v?ȱv E[]Άu; 5@f@V@׍ZHNJYAU(YIm9{~̎twhw?Des1`g fnBy؍`Ь<2{FE=6򿁿 Jbԕ`F ? ,pqܘݑA]YfrܘSvքS}cmn.X 3%'c#ާx{iYӍ̈_6v#ChJؙ9;8uK$0V=n(wXA0+Sd/aIxW*ްHРx5TH>lקQx;҃rY(Ƚd:O۶ͫy['hq12Jym_WN]SchE6Lo'5ۢAR۬5Oz1bG딙IT6kK*w^310!׸/1{*w {#Zc< "jOBu *~.kt9<⺺{{Ux#Ppcw̘͢,:>_ۇh517{;5Ohcn~GX`:$cN7}1tA!# Lg0A#47~zѱec!k((Ӆ$=ݡwsBA1Z[7ȑUWec\DϹVy@ʝyrU&wӔr 7=BPCز׾!BN{ $psQ jQv+ݺi%W[]DR)Fr}©V`С'ѵM> ab5^xJhtǐ' &M|C(m8OD@I/;BWT='Z>j-FzE|"S%G +rcV7gFr ,oO"&X#44 &待MTIhgr'9Q:4& 6MkMrRMW/q[ˤ?R_gJ0;<ҾoiH꒿fа%-ëNKoZ5M¬Xgߓ `,QsnYHʍ`bH\"澻5s @S@ܖN3 'Y2NֻNcHΡ W_gUϸB.kQ ض('[EbG1i)"9@XqXQqj7v}"Xphyםi]UO%B1ihzgp`hP@ qxx ldAxEENrݿs_6P ྲgXsB3nVq@-Zl'##7y`Xmo}VXߣEPUs^>wM-p gepӴL2(ʻBk /g=habK_TE.TuX/`仉by7],OϩjH倳Q-ϐ(͵'H$)fnoC.=YH>][EKn-!2KirESыpQY,gM;_3HX"ZZ2]7aR=.h@,:0l]an`{>K+Cà|Y2O[UPyZע6]8@]岋$g)JLۈY"m!*:_It3-a:tۺ'ҸcO4ʊ{%{-YF Pv/5!d_۟Ȣ1dB{Uu*3A7EYfkp]27*ԴpĄC)>{PoK|+f\DT =-đv>4$TwnV$eD0W2hAKwׄe^an#%#h!v@w{Rc鈗j۴1ve3iI%BaN=ܲKuK|vņ55K]SQ^f|~|~c>|ZnQٖfT6n:iތELfƨ7FUd¥Iz}29|{I_1y'P\~u\Vcz tuFTCMvso s5s}`!PqƵKK. ;-7%#F\$t1 .7o 1C+.oCqrV~ӊ q00asr/bZHs~rC<~7mTȔ"lBZݫ.-ϊs[Rune+~Azgu;ϓ8mt\y]pv7ڙϡ},0 %ns fV9,h1%cLϙ \bPVkyqwq&ZY +W؟:ߍTpJ_f1lvU _a/Z2~A7cT3[u6*ώR\tb^W<d2 sl衽h@t&)~ؽ h5= %GxL-x]2: ϑ "Ts8&Ug6N6Q-h*X[G<|m4ȼ[0xk}EZr}8[ @FShޅ6wr)BUtDr ZF+2w&FK8P2l.8[BzIWA s 'Ѵ`4݉}8MЙ@-TЭߝ`whr5 S@_\9o (1SkhC*d q`%Il1Nq'd uH+|r\" t'H~6cABT~??»  jPЉVg%uN|5EGAhg*3`XՉKĮ ÅY2Ejpe 2QohhOpU%uTY1Hm :oܑ%_[;!#&auY,;4wȳ>h9D %֯>ϵυ鍭d \L쾣|/"\L܉;r/R,+# D6| uV!T@GqAje;p \+\p0\\p=׳p=Sp= pU*UFpߓyfXƍ\k|߰3BhnL6Rӧ͞<{ ۍ׮5NOJIJ6&0&ĪoS^Qm;F 3wƃeܘhz<رB;\j(\ઇqr 8Yx^-`CDh# :,n;Gms؄q8q)ISCߊ='577>q+*9~mYrѪ;sָ~xP'vyɽ?S?/o^~ҁ?//|CcO4ks˩o֙}w?k~.}ǟ\ϥ/+\m׵7n|Bm O~MG_'.<잃'4ѱCH9$bTG5-|+2~ֿ? c@X(hcv? ?N` WvUy WVUBKU~UgT-ȃkyRH~iN\Kͅk\K !EUE WfUp/p͂nT-bZ>Z|*}a?/"?9YAvkԮSߕŚ#(p/4ԗ,O{~g{?g,\dyݚ⬩[-Ylq9ݜoQ<7R| Ϩs[틷O/Y3;w|϶:swڏr_G~lOʏ?6p[yCw//oZpWɡYW2_KپS_)>}<;o_l?ߕ|\·nwg=b?ˋ֖.,~⋞Ow_*}io&>ZOZ/4Hף?gi\ʿ8t.^]՚?|2[|eLu񷊥cڻ>wKOo<{w`K{Oݰwr?/cGh֒/5k4~D޷mAv몴:5[p G_6a'@m&+%͉gN.p?,M׻i[~\Mih0<3Ë́ItL8{ɡ;5,$Q`Gt,. gd; q^8)?qjّ4N ;[4}N߆7OI!)RLÿPQӓvy {iJg#<=e |qhi4(wL8/qFdFOBԓ`ǫ/=d>͢)G 7v&(eiQ= ;O:Oot\?nohT. 0'2Ld Dь EJ $BQOC4L8Ci@#6ג;G?&BҕZI}EF"bal60k+iILدdy7BAz_Fi ҙA}P}  䑒2n郳G@*zwH8G@~ }n}Gr se!+O޿`H8N,'m8>g,8Гcdo>I} ?}  $+ن$ sC8E %[í!.fj(u_+Ea8%ն5%%(*iq$@> L'ar! 2@E A&a{L$@NALp эBp!p8}0BS8p!BBB3<$4?!4?!4{!Bsm8\!4;!py[8̅2<Bh!4!uBs 4P1s!a! B0! Be5= B%N8Bh6Cs!EBpyy8\!4!!T6A$PIh áe*AfntB}PrUr-aJρ08)r`LBi~ E C)Pzx(=aJ3af[ w Axh`LVp!!}B$v9B!$qaBDg8jjg8|=BhN!4C!柇Cͯ )7 ܵw t& T&pLTR T6 Px2 2ERJDiRȄP a4ӘN Мrah Ө!!o}!ɗ'AH6!܂s-BB0CH. $pȌ@(`ũ1_<_GM[~y6лPI߮ C{7˂y9^'H-x}u,eVo,L><]|s!M@4P6lٰPHRIF<0M%} :p%cq4%D!H)$@; K+DՋγ3L ΄ӳ:BB6SHՙ†œEbV KhR$ hqtd Q} {2@ U!A 9}r+i9 CK |ZVNelsEp] eHSB[X߃07X"9B_2%pIra A*UK-_˪%ؤ //ص+] >8  > A2ed,鴅A~} d: hgt ],=+Q\! >dȝ} i{pI ?>?>cjz89CO2LQ2 S@h2djJL>7@RCFB5tsW ;+AJ p$ VDnqF!/ "܈uyUD)]`´:ĈpGᅨG#kֈZ:ϢUZbHӵDX XAepqk νm mJ` Hۿ?hs]۟_ks^ٟC"|N|.|s:Nn@bM!E4BE (R$7$@P`AEÌʴS52J+ґXR ΢LZ6:e}ُ횽woɆtOt|(4?JٗAsAS3h62f4gLϠyuS͙e l͇/f|f~'3h,f4MM_:D@kH"4"#+iȕ*D2?iBdD؝ɘL=&BdfD2L͢&|;Ea y!y H "gu4IRfl LCH"K@d=r"/a |$@F#2& &2TD*4Dn2@F*bggV%K|Y}^ٞE3,:>EhV%fhV?f,}~:iy~+4?;4?y9?/iO?u ?f~3^:4@g bF[t0@e_L"@ ygs;;t+@g:=3ЙxD't&Й32L4>Ddә:DMt&Z6nʦ3l:%L1D[Lh6Φ3Ѿl:$Dgәx6'DdәȗCgk)r-"s.PM|@C )GѤ3G$d!"r"wY7"/@nB@#D~d)"o'l5yHS@!"cN&M*jxW,Gd.D@$Y =< 'D$ȁ1|OI~d"{4-8"cN0t\7$@"2 H?"b?&3s2r " "r3o"m<+v[k8<vD"@6!; w"¿{DF4r" r-lEن }lmDΣ;v #  W{=W|/sZy8aHͣwrzuRkTGΣkZ5Zgr햊53m~8ZݳIk_j_<ص@ש_jߪ}ƈSOqlPzii}gmIk߬jٵum|sHR=[O=ra^uTu6iۧmvrvDM0}s8p]@9HBd9W;~l 1='}09X).byor뚫'Qۋ1'xhMC^ W>c҇GSf1~M0ڶ".=#?HO_{0 OK),GGWG?~gg+J9kET-mqDFjd9$C$nqTۺDXL7~xďsΊ,Ot9,5k`eM8F2]Z,GeػbNrCyIro.ՃO?R=e=D vv"l^>М+6I:*}%t+,Vӵrq4" ƵYd ^Q")pѺzl^s0Qtc)}˜ΞIpJ['3IXhTIA<1!|X‰ksklkZf͙Wݨj Zji)"574tiR-Ұh6RR#%WM'~ C*\d9 ~ r2'7KD+!Mpt>˄>m}4էGPebuE,+uO~'3v?Gg=s gNuϜ̘8Q<79ᗘx_a>; tٯ5qt+&OY16+Xi#bI}ʯrOOkQOq]Umji3RbvN`~Yk "AĸQl4qY;iaSN1#7lD_zӆQ"FJ"+ik?ḵAqc嬈 a2(ǝ})3zCGσy^`h4+0] ttL0TMg''L6"2O6w~ @} bNcՍֵON1m*"#S$`ڈ{DKGoWDi⨙u]nԕd9J^['B.1~B;w8tssQͯXdP'=C2g@$TaP DB &ZiADF[Hy7V '_I%:}>w& aFV"ȯRxA~^,3Zu]z%KPg펠^{c*ӺGULzv{{N7%j~g[,lOoZv/OfsҰ9onU٘?VE+ُIfuק&q8I2 u>L܇U%4t)=sU>Q҇i.Y!j,5}Kscw7]ln{Ujv!!5,Z'gci`ŚT[SM#)Jv9!Uj6ZD>,=DcRv$=IMYÏJ !U!Q NqF9Ix&eiԱфԳLBX"r4$H6lFo%p5a:^)5ߺ2{< IMr԰IYClSw`# sM-]lb - @>X3mf{M-64gaz֕mĦml 6@vjvTĦ6쌲ɑRſD9 ޓCwx)t t+cߥ돇7NS1Dhg_{9 B̗7ʶK_JGx^Mi{`mwuR#Ix#hW-m&R$z,t\1}4sjee)%@d:< CD^$?-5Z77&4.c)-ǒcjNj.†˥hl`sN@6 4W6D}e0#ux9)t[y*JS҇|I]0Rjucmx"ngW "5K2H.ͥF1:V_e5_4s|*YY_ ^[s{V'WɆ[ZOEuEE) 23RR$:zyt˚H͛Ruv/1}xzy(z#%K$Z>/y"\QJz}o /BTzZ z'6֝\#´O5%f la<]a FJ=:>%f=VYS>aE'&jm4'_z\{eeeJaEbc,C˥F'n=HOJOkҳS?GԳ[r{Z9WԳI籤;]t j"5K"n떎h<^L4cCCR/Lޙڵ?EeV]xaszT+DM"ޮݴ]H͒xjnHxZBouu`yCLaxq4U[ScpTc}=meOZ`Og;s{i1Vv5O ~mE6 f"/).~>`]7TH}a*$i{#G,/eوd !z;ЃCq;ɫfLDnRF`( &M"A.<8j"Z<!D^$HYgwL$y?p[L2K7|)2|uHP7,¤Kμ]YYb"}ѡSՊp,zj&Rs̬"5/&.Pk? y4X*:pk5WT%Y?TzZ l?=ʪΌ:(hD-000Uy`ձg{u}>xY-+eNE *1I-V k9m`JѐTV}~gg 3z~:w4=zNiꙤ>?=5=Mz:>G=s4=gEϜSghzS`XznQ\[(~~K2ғM%-'$aʴKDj?ْzxZ |R3w+'25L6gN DKz HGP1#d6Mlu~SƓ'2kl8I۽Idmm+[ _SjɘswwT/Mw9'sיzF|IM|"}_s,Hyd/}z÷^ nqaK$3}oN㜷;H͂GNw4)5l>],p_39FzPh>J} KOS8{͂GNw!k_ 5;5Ğ^r5 ~CADGR\Bs(9VlL~D|ǹ{l\aXDXYK$#\z5p+Tqyyy]Ɣ}ݴB\'5 \/YՏ͂mIXUͦdWs$5 !knmqͺih44wJ'"z4P>댞wjYRO2-W&=C" Ol5wJ́\͛ ͛ ͛ <EIFJ ew36<죶SrX*Ӱ#=yH=L]2IntG2JSV"zP&o* dcj1k5ʑ9 O̱R6r,˱2♼5++. d_ as6܍R^8({hWr, "B,8+pBp4o%9ۘ׈'_3YCہWk&"4 }& [Q 3WG5F^2 IO]&WVX~~e '?}CenCnٟRJea\i'A iÆÆ# d#yv<;Ls|8*|>>;\3{¯,V{ىeIyf"Vk{JaV ߗ_O=;<)yibƻx[iX0fK OTjw;B*ȅ]*4:hh44J [Rsqތ'd=cHϚјaV?͂|IsQJ%5dF)ai"5qd_39zRhߛΥp47I Ьcгuj}ԩ?NN>f<1G&2֍/R9|gS\~56gP.K {-x+ټ05{Jp~(v.5[1h+`.vCvCv:R`Xi-{LDh ZjNc4}>Cs<U_N9+RQ_Ns; ; ;fJAKW^6:2gR>_'5m;glO544dF%‹ >3Eb-+~/tf%(3bCulfs lj$O7|#K˧nTM GW?w"B VGNy՞nW5'w~DfA}]VȚmME ѣfTMj :*[˯oKb%ׁ'V`-Zn6 $sRvMk!9m&Ix@<i;V.2]|; moĸB|!It1ŪTcCjBʷT\ѱRm6uo+ \J﨡 m@_ ߣLT?lCSc~pjKgp$?/{P+g xȫ@Ni_+ cT5Լgm: #j]yUl;;7 |h;Q?VryPh.=Nb%4odi'{zcCfe3nj{(vob=3g.buM#ikwQ9n¦EAH @RY =HF)ERRGr1N$( TI}KF+#LI JZH(i! " 0Tf)3Z!:^!Wy-LPlPՒZƮȘZ< Iq<;cG5kßz8۳neJ=ZC~ubylEK+R$jMdm-S!62~kg΃ewV#r&!:}%EIK8Yuºv DU튍EqS_բظ/TlwCN:_dyUxI*(qngwPK\s(/a r̅JKL+Og@EA8bs( P-Kd]S8_An Ιީ__3wBhe?OltCYE /姦F2Z~#S-{># !9ׯ5 I;DÍ>"O ҄5+6HfY)"nb(%GI C=領x%WyJ- @+U>]+tW*'zWQ:D2icǑ FR(eS&NWhwO+C$ ޓ(}דԍ$=Iѓԏ$ GNI= ^K,qŶ\.2bz-6xCpJΟB!1@L 6{׫m EG|R'yk?|+)t7";c~fC Ah`X@Nx' fI ߨB{y!%n/՘{O!jTN&{g*O˱/Mar '¯-65=dVأMl.9Ƨh3k6f"CfwZ u?xZYXGkҦGuk"{LhS9ZI$Sti~TZ+Tr+ *IY'S1PZ{Byg5:2 u*59yJۺ"Ğqu1-i-Z2J2cqX~{[Ӡ_d@#ӧŮv(6C$ˀlmQ@vHO!/[4֬Z`sL+h0 @ \&}15_M j68 Q~ eZWorzJwMب1ύVzrŚ_c3i'MXz=̮gbkz1H\?NHnRӤe@~m44|w{kצ>-Zht17֎p΁\OnO3INnr@ܤ)ռ:9"9ΐEr9 mpB57;$6 I=v'epN.FdzN'>*O8ǩír"AxWUOg"qzz.HLP˂,w !K#%O{+|XSF%WΤHk3 IEւnP{,I!d6 ٗ)do: w6;fҹ0HI5c(ɵ]nt+A Dy݅ZͤsWf&VFf ,$dzXdC^7 r[_'WաM'ti~ GY-G:m6_̢jHvhm՘ZK [~|J*gh/ǀl%ԲVy2Ǩ=g[fNHzۨJ2Ok9V#w6Apøxǐ"̝5: pjYrȱwϕR 7,81gƾ;$cli@F7NJnT SӳNCFz qV͹ߩG|^>=2Gho<6C0ww BY}tܱl13ZH+X= c DI+ȫ?v/s_#kNkevf-j]޺rR6cE޺`;ġŠ1ݤgX2e?C5MF|ņ܃t lKkێW" 3 Z!0\ΓWvw Uܙ3oRɖJu/Ij &l`- Ή]5OW麘p=RZC4'5yn3.s's.4pw!C*TxC '"x˹Lz(Ӷ㦝Oq!"Ԯ^*߱0'pKv](A:oT{=j"X;G&ȯTgܻΫTU\tM_$]60ijv.7jJ̈́YS~l\*&uI}z0B2'c%8*gGqxnSCkب5^ЕF >lҜpZ#zL !18/v 9cKgȊ&UF+'Y" 9\8%iđrd~#!HDGMɩ~ +q~,+44o,GĶ:Fj#?V#v4ao!ݐ5v!<&>vdO_@QOF*s,ؑVOXal/;몟95"r?pT a}D՜WǬ[yEz^歗yk۪šX9w( l`(>eb$oos|;8xwRmbM7ԗKG(yR쵍66~o"m/MyekS>7 S~eʯM)_[;V6ye^ٱWv}e_W`m1Xgs-kb-kbpn18 i6sS0Wڔߘ)5U6ye^ٱWv}e_W`m1Xgs-kb-kbpn1H\q-Y8gY,oeq=e r\"eLr\&er\*er\.e s\2eLsPy -co2Hq)F: Ů?C~TXw]֛C3eh'$fмϺZT 掰x(c>u7p3Wo""d# 3$)ZXXt/~0V,D'}eo tJA퍔qSsйrVs0i\_km]F1rA;&a.–uMx 3=c()$*&E7_͚kQw%MzU/8*C;Muc-(fmr 1u`r?q,.!ǐ!3JK?xy<U1?^@ Ǵ޲B IWO'P PͲ~khXO4~ uƈwv`-/ߚJ*^UsӢCL%ع}s\J0P7oN@o_&Ч}_:U@ӏ8 :䥲7%IroDמ0Xuf כ6>񖉆`8^lzB_y[ն(.3a6,u Ju[*oPt^:[v쮅W>ӵ*_D]6B6dU ݊>WZЌ,8}l x#> :F/W" PU Գb}Bg߲$2%! ;,]z?~ՠ [P) ]wVļW?'h u}/(!Oe-˳~cPQ( #6-e n !96׬~Y>+~*^X*%u]-A7d]JCD.tCz!|ȭcS՝+Jne;B"L9hrg6~ef_T7B;Av`7F1zl&RS,K1P)A^HHrNw05<@IJ3,~(o˖fL {>VH/tTya{xOr"2z`v7Z~oZp"z8l5o>~$gt|篷WwOwzioXQ@j$VQYrEZ:=bFпӲ`.>G;Ƀ:at-$+cKmaYfzemMb#ۄש :4u",.ݧ.ej*N}|$́ˉ+=nv;ɻJyĩq_Ԛ\@g' >\o==v%׃C C|y~ƲRmW 7 Lb{v#R6ȋၻpލX%> s d<ZǓТ%Rl1{CI"i$T8pI?5h *뛠*B,GM=ȵ f~wUPC|S^ʦ[]ZӠh"\GFj.JP?y[`( ]s pV F2 o5؋C3*2$~bq蟼h{y Af:q'}A7#?Z!&;";5J33xu ?R1&e)VMۡgM:})'ӵhY$Sˀ_\}nILVB-JImVL8 Zp|Bb/ENz*+&#Q~i)7OL-cD'Fm5L M?IV!Y޳DBX rL%i-Dכ'B/^ YEz$[[\;Ȓ7AxG&4y{;QUly{zA5ʂFay"EƆKvuIPƀ2AץD6Yv~'oR;1AF7S"N~dQB>qoeH}uX"]ԭQ$y{YF BH՝RQ=Ĺz~ Q$2K \'((K9;]rwy5q\I9*mPKN^&B README.TXT1k1 %Phdg'پ#>vҽFw$Vd`E<1ߤN‰$؈F4}w(!y.TqEa,!u⹹*c6M< ߯km~ѓ*WҊDi)Ti6%6T QI N8 }PKd&jzmd VESAINFO.EXEļ \TG8|lVAQ|b06hmAJP0,܋:mӲrmpםw!#3ѠdGFC8&\$! jΩ݀I?LnߪSN:uԩs]0,0f* 23zY ^ؒlsV8ygn!-,%ee[yeenʢE)VfK\rZd&ۋ줲Ym)dUV.-Ӳ#IRgyeu3pVo/)fUW '|EqZjKq.KP]U ,waQť5qVP"Tl,)J%ZRYQR\UU^Fx`yE*TT ֭ΚRr2=92*2qyɢ!RJy5eNʂ9ԐpRҳ$BiN@ؿm.Z&%Pv!L#k]RGrbt !9{Fx54MD_NV-F- Aq6'/M|o!mJnc MٗX"k QNOt9b];᯿׭'6j{Vk" KhZsiND/Z';jq FLݢw/0 볘Fm6n:ء},Ӡ[%KMϽn:O\lb=|DROH]og4)>׺?SǜԋѧR]|eBˌ۷uJ~k@ϵu}R5k bq3iE + \jȷs*Fp U 'sq&[91!eꀉW!fuS|_ U A}@79=9pv\\V[btֶKVsZ /LJ+%$0|W%&׉q 8i3RBN.Y[#MÜv;?bFN`! Ծ?:ɘ.YkTTYبj׉ctg>`AoT @PT5dA~iaW@ƝQoǫ頴TdM057w\I0FB㒂*Tgwp;91z @?&-qg>3:"&,uuL%kY:hŌh{\gj-L|ld؈XL!M :`%$NE9:mcxk (q -_ -^n?N5'ҵyht>dޟ ʜء:N^EڼqZ9 KX9i 49Uɍc9֬>Cw|s?~ќXsd@Y&Cx]I{q9/Aݸ?yݘ-kTRQfeڄ~ݺ2⿩̊KWG{ilFs{qA[mie.M6C.C褛Ş38ޑ!%m$pJإ,EEWV9+ IXTl\έ#[Rmi5N5+*-.Zf[rekMI[_ZEV[;WVJp¦yTR Sq;5aRJ.?`xFj^E³a^6Ӈ$Ν<3C,$ Cxd~w"a}"1v= @Q6׋zO'1 xhUŋenyrtȋTbl1dn wJgeVXO0|?ـRT s-qP3[Xk5]߰~*ߙ0W~qi"pztkq= XРD5 I|<@Q!HKȪ9 Q\S# NDZ [/rΑ&& =I5jUdw+X?Q"҂QJ.&g#W73[!N4s8 67eoj@de":WcsZ0k%@|)XO &MIϫBZ-nI Gψgfh8~xu0JT|GQ!vIQs/)<9 >ك3P<lX<nL*2= (yA.[LBFHF(4UWI/9 ݰ׉Duc-ɛw!h # ^>c_!atz itt@mAz3# z)pyy]kgO:h}|fdojT+(ZfZP^>32jnT$v5\#a6oxFX*04vO:ّ.G,npp0>Y8LO9?N \qid2$-d KL0a)VQ ɖiILd(N~dQD)Bg5XTɬե|5BvKyq n9K|Vp;%LVqUR[&QcY$˲ے'U|)|ޒ\(Vd U+Yڙ¥s{zUv'Dh ioJ@{p?ƽiI MxVSF2BpAA,GjI9iՠyf7 g^23z~2(p2Y-@IiyY !-g)py#0LӍJס-O]xڸtn^qx *EsCۤXÉlA_Kc&\~NM6A#W{; PP7+ `P rD,htQs "ʣilk7BVBKP+[ïm} ^@ `dR"eXf:J :lni.$Tws(YⰔK\3C:N]Bw+i !g @麏WBkXбGQ>G6q2i@Yϐ/!hraH:7ˋehYi|;,b >čJQ:/)uW:"U,.!եyg8nò? }$w<BqMIWZ,-/@$},!55O"HMt:DuJdj!H@Qi!V aa,#&*)a` F0s 0 0p.@p>^#3 L%cCa@πp/f݉`^(y} (_&jC% ^Hу>SH6@a"4O U5a Y2\L *A0,! UUC :h@~@ĸ~بͺ['L$rf!53K>R %sRgP1%޼R*:+ 0!YTSfF&Bx z$05z;.=62xmgצwQӟD ƨzzZ5\OG '風z:#;T ]C9gD.)/wn$嫲W[ .˼&2s%U²zj51L Xd\evTz5ouVo|D`l+g,{b {~RY/Ky(joÅ7 2 ko(wj)GH<x|.d? 3=42J*# ۼzFAQ%`:Cyn jd+v?E'`Z<8G ǘUfa ,%N ;\C)+1:dn /TN3PQ[s{_c VェIYfW Zﲸ+!{n.+dĶcQT/ ч7Эn~ݚ VS0>5(7L%GD+󸁀)cafO|ad\Y]6 #|IR \GXrwj8z-1kWJڟҍMA/w粘{{lƊb+A/O n6eq+oINmk❆H&mzy㼩yDhp槩Lꙑ7zM5)vɸq Sf:z4̗3fD3{g"\i`' Zkqhw /-S32a_iebYR/+3cʢh7lH?NK c^lNļ1%7M ` O}!k Y Y l81W|#w kw`k2w{)d:YihP̲HN̚&١V=NNjYY`nݼ1,sc@A.4:f#:k/ (.F.^LǦKҗ,F1KH,Ӕ5kS ~cM^4䒥^+^HZ75„0Ndx!,+lF̊ bq ٖ"N̞BvsA";P8$;-=.pކ'ހw3OFc ڣ[/oB?amG? b p$$kV f`x;f9ˏ 3iɂ]r3JYR?Xw edO@ j("p F!d?Ny%rb=P7"uR<~;E̙[~-ON Zɰ2oM joŷ^Ѽn 5y1a\P?C\ z{:iSۡ=PF5i(iPR# J&A$`bpp[5,i' Z9!бtD +pn(!ތ@f_00ȈdƑ>\$^lT7h𴔹RpnūҦ3oVh?_$8 hQ,\ѫC|&J:s,$ `45Q\Gm bvߛC;qA2sz L,vf'k7;Q>:dGy)p¬2 爆/7џ' ffZ4z!y+n4\Ѭtǁ4j>.?/|jm: u-w wA&&Ӌ["x86gn2īr'}E(6cΠ%[" =83/+T3R~'0ۡp~}[=GKQXqؗ-h[3`/( 7CCXv|+{SpX|.tlTJ&cAOn zG5͑ q\bYʊx )ߵ]m3(QA̕X)W E8o-A=h(iMS ^{a[CL*0Æ rs*?g0yhA(ŖgHт'^5hu<tDCF o6H{uD"x QfdctCLq]vCd^@ֿћ њ3 𑓉z:mu<)׻]ktw` &/zPט;¶T׫Vw{!;hٴւ/kw+Ɵ3j[{YØvenR@t-C!^W?=ß];_I:?›꾗Ώj4?G6. Z z3[8;oڋ`@oYLפBQ\nk%]fiS=2{Cr= Q nۇ>r0Y${CW%L[*QYϵ]Xftj * >r=!G-?ˌ^g+/9o9%lM0\|G J\OK8V#`3݋{UTƠ_u`m'4^{P.YBDois3XFbdgAܐB9*4"-s  Q"{Y/k8}XW(K~Wl=gU|\&jC'J;0> әlYٔ=Z٩ #>hE%*x ^#:Kg0~x6z~sUycMw)P窂X{6}{A:d<;!=GIⵞ BdTro}#[[b_YiKq&bs: k @: @r(F&2GTY u @m48U\h 7/U؞`$?@yLGP}dԖCy[H<63'fhnz&L^NCW6)Jޡ[VGA=j$P[\^ZbY?*QkGgCdVWmY&R(Q_ ?*KU˙-6ح-%_DGAՕ" O^) -py|z(cH60)AtOut"HelԽk8;d.,'gzSO]W)==0+z [fpݠ uqZ ?ByksVgH,MDBhVbՀf0YZ̢頽N`,-w+-!5$]JT*wV@亲)p_z'q9{dg~"> d.Y=GKs_S "],&Z.2u+.!!sDԔ6K/!׍xN2G!T2J9{ ;8X >ܘs'"7cEAYU_z1u_Ђ! AZ-VvKqla$:\i~lpӠ#܁slg]6ydfӟ=V{-v4+*rF؃T[El]HL+Μ<S{l`ٮguK@oDw8dsCszhn xq'u{9hrҦWΌ)b6+ er,2K9#$+NB9us/hqMzz[0Ctmș NęM=8!19G9a5LilV7bj zA<WrwnP ܴ\1%NM9eZW=o^FN-I5Ο.I3x;_D!Vy>z 4 3n>f, j+Ywʼn]wY&  |YT>1ˎu-^-]bxV~YPް^dŕa]9#"?׍/asO"gϽ 2cN!ix1Z<{m:C7i$x w>bMG| {)Vxkj/pds; +9_{8q]t{ agwoP .UlqX6o:Imzu##nGc]N '_}ڿV8Ϣ)mйa-D՗<:?bCL1nV:3R,qž"_4z "vjU\[+LRތ?sl9?R! Ԃ/BvQxAgp!yVٷ` r҅4vޝ Tme;yZh3@@R,eO*St#YcІ;(gi[{*M zpg~爈7y"IPýz <b)N͗%ҌM"l!N$ND0B}*žQ!|Kt>r0 DpAZ CK}$nI@b#K YBA q߂~Mo t/m9E‚2:/ܡHp՞f6`6}ك9?})8p]x|穀p"z$wW0Hܑyܾ:I8}|a:C'y4{C2dc@3ld ֙/|DԛyJHuΑ6;5r:c:0B^͕٫_bwdSNc}o0tTg:~Q߁Lt/(q,nr\"<-dKQyqJs.S;16_}?W/THA ~ Yq>2tjLGPdԸ}IX;W^9z:gMt]rC$ka 4{FS,~Bho+]Nҫ&&|߈*V<")]M[Y&S5m780L?̛{&9:#k<"hk{n GՕ‡ClYt/)p20!(R6m8bveA!.d?XC D{jgM2܃n1pfdzmK glYM/˖SO 69f3? ܺn ͶMF?u6țL5!65iS!Ag:=/q?Qxt:Kp_zucVh?uF_MRs?HP#1e*U3@}pnd:8 xg$ H6mL/"=yT[{P;:,%\VĸfS– e24\# $2毓Nu0@>G~H+bI s$ܔ4P:d D%2"O~܎a- NxGDLsCn®Ƞ(pP[PIѿ`G7oN"8״[0GwqU7m9;Gx׫%Zx;3[5_|w&q PVUx5[rg S\oJ6'QDg{!>FDMcj* HVBlQT,`G`PI44C`N.#EaUoL.9Yfii< Lp x, 1F\xMqk>a.B6?pG U:YE| o]9PZ_G˞6ra5y۷H/ 1O:[ ^B"ONq!`Lsϣddl=WKS > G4к$:Vbmp?RtDז>p0,b=>gcb׽ws)hڟEόCKx:b/Hũsmp$$ 7#,Cl|#<hy{/"ɋE#!+ ,`GFv,T1!A7!@,S{£!(»B%zآ~`tH9'IHijͦ,#AO"/DGB\NZ$YQ.#S(J?](>6ƴi9Knж#P1Jco8p}Q}o`CLE !\L WONS2l R/÷ďݧtQ9#7bbt>+ta )(@0GYz{If cvR.B3IYU`'x=Ԩi7tֿN] ©7F3wq'T iԱM<Mk!gg`SHNETR$LBҏPɐ*CRtvVd}ăm8Ϫ哼$cK04 6Dp L'@_p]Uԇ_xxS^t $B:U'YBSUT=EF!~a:z=؃h{!SDx>|xNρƆI9I4" ^|T+Isܧd'Ʈe?'j?,,3ToO>ɹ4_סEX9NA\7Q{ ΃]p~5\}#,o$ +3H s=DLC[ 䐟๻}a0'/tw9iT}CK ;xOme,תNanIt3/=IfNp>cpiL ~[Tu/oDeErNt}g#A74 {xW? Ǖoc_ƨBW rXΛ -[K̬|o& 0cetI1 ޾YA/ˋ!ۇ.#;{qZ \^e?c믘G^'$0ne.@%տ;(vUeiyH[Jg Bi@CxxGI旐v"`bXzn~MA56nv#כjT}{w<52LffOd'tgQ!R|WvbhW?[pb#ݔ侻px.oL]oH:3ڬ;bR<67k! 훥ܔX){P, +')"6D7!%FPFzbf*mO| $+Y:;hў"<S##nՑ^e,Һ@A7Y^RF==ZrIKGHxʛTV9B0e?|*c^ #:λ̝kٔ)+=@ OujwW!~΀=!ѺmqC Dt\<ߩ8RTB$cƵϮ^z]ߋ ^4CA2^"ςa^N)eCtJ0ui=O UB%TfƲUCxB'C>&.dd83CsLLjz^$sX"SYGyγ w<)$(sKcLt1Q#vC3<|qK')Ǝ@ CYBR,'#[y K* a$|bʘUi?`f[GVҎ^26Aof_-϶?S(ƘEь1Y%oRO?%BNzNem]/Aڷ^C8F+pU-CT R>r]1:t)VLtT%jHS夔h:HtZQTRSc2E9EF~D6RdmƑoNe93TldIh" kkOձxd312lgc/Ʈc8)Wp`drr]7JG zQ;B u ՞ A8{tyOF|4-dsrG[y_JU׾Ko!v9/-U3s55fcxKpӽ\KCՠxnoumLZ {{:p+CNuvО( Ҧi+}~f݁ _.#ynA=;\WC*랝]r'^B|uo=#w?xKorߓr_Տy=gTy_uP [}-޷EYEEgT [(x) (((Œ`ŀlfu[wW]Ze)hm) X?y3@oܞSZamЕqam}%gjlckPxi6K|sq3]i.$~š#aW%/Î>s>\^Gz̿1U  ϭ?">UC6[*AjUW#Mx%iř_F~Ιzr$J+D+Օ{Tļ+zxtp/?h>bE itZbU%Qt=jrSyAͶ>`߶|G$d19sXfC-L8A&V_s[GYQ(z`b}d3lBʑ k(_eXxiSsLeр6SA7R4[1O4A۽$?AjsD(Рʋ}>>ud!¦G5VU:l*LXQP!ֵ TUٳjoֆvnCLކp5(]cPQB͞lu/IzD؂}yw$d0=Ztil߽D$A\abyhX{'L0FSFPblp V(M#ޤge)8[bY2Oq|;NN>vLD5KBq# b4P#nnq{Sr G cClfH gjb H.m`蘀bYtVwhhGm,/s|K,~^,,AusmX'uR:k?=Х޷4=QB`YnC~r)u7wlTfgӓ򞳈.S{Z!},Gbm-\a/zwoe%<W Q?xȜ_`&q.x81 }9Kj_w93v zpÕ;{Y'0a˒p<Ĩ]\F tj=wOQ{Sn`HQku){ߥ/vx e+|W.to5]0b "$-lu͑*^WWN(}RTiDLx(eB;;tNCxq:1nM9&&p a~>cļN 9_hO!,@'I-;]ϋS움ٺhGkv~Ei^apY)Γ6bp"ubi?qW3}qKx -Vm_ ,3RNWm }.BGʆnl]$6 bg8{-QV,QαM<ϚByF\([ywoO7\ dbr5a [L?j#atVc_XlNH4z*dPנ{e~2n}5]RXDs}j ++iZ?Cā]h2=1O0ݫ!5oZӿkkEm@پ.:y+#Wў,oTcv$·ۂ#B Vsʰcڋ,+S~30,(zwmup c_)XI/Y nqE:, sG1#U!\Qk,N4swEgz_ٕ(S&n {vTiL,YTj3:Y(P!^v fAb–W'"Ё3k-`kIl%bD>; QVLvD0 (+bT U1CBuH)zL񁩰@vWө>LJ'@SI]j8";n9Av8? o-zaV#L CրbԄR yZsFۺ: p#5 fo:"?hȯ hWZ0˕<aV{kzLx_.[}cK eV#8,@/(k=adQ`:~=fًNrj|>dМ >OITOںA,%oZߞfE闰fn\xc^@~S{H-QF#8(.,_y(#tcQZ?3sYGNqLуR89!iZqtU*-И!^U{=>\+>OQXX?\m?\^kPN ?5's4'u%uWtŃAb b.28χ#b8޸Sw7nr/|&_RF sh|k íSD k:4[qSODZ:9ډ~X@SRtLQn %p\#tPwF5@*=[ܣAQ4sH mM}F59t62"e#YY [DDl?o%2tQ:׷G:'B`s|68e]dXV:+b+ǣT]P+ KDH-e,ƜIxt] 探\Y{;7hԔn?$/5Iqx[Ê]i`+PfkʽkǗe"0yrlzYKpEmǍ@`(_t8'9 PPk'i;T+bRLWHe˃uL5εw2QSa!W\S)J%(6h~!~>!#6KI7Q ~+ O8+zQA)| ̳tn?6 f J6os}|Y8|`6!׹Z2Xhk{> <$C #q?Nd~Q4=ZF8]5}f>hO6om)%xQGvqN!- uZ;-;y@UPAaVᯀy[Bs|*iy[[uo2w V|*kĤQ7K1H_u>Wtac^Vs_q֞ j܋eLק΁aULWuxvXlE9ab]֫y\^7;ˍ45Ϋòέ=XD$FC]t]\:GpſҌ;f9HUB"037M;!Ϙ֜7KĽ&Nf0 +8w,DEw#>݋gzĿ*~o~|OwwkkY LRS⮨vr=fe?-zʼ֪ko֝F+\Gݯkâu]4hf p[/G2;Vk 杙)q[wt&\Qb9 w;rw{IAYavAQ4|y:PXӟm!:89.Eϊ>;o^wXL /wN@=`axHxN| Lgj9>v-fZ hG8o o3"VjG͙ޙh35ORlLrc/=豻[BkfгBQZ*7ixo)6҂~b3ydxǭO8 ;粝tw ˄D/I-f\ӛ·`ExmwٮOb!7^1@hYb#pwUI{"6QzQ|)_h5Y6ޮL QQ +V7WB}PیX2M?nikӸ/]ty⯆79fmm`dav33O$OmZvTykNw[$C~1ě.b#YjzQy S|D(uG2~bqi,%6܃u+0Wr㌚LَFF\l aLm$ CbLډ"q-VwkDgʿJ>_k:v,^bo6s5P`[<EMm^KX-m`d*e` wTw3ϋ[Wa?r@x|>̀D _\&e_> ^~ 6P(ݫO'VwkAe O8Qb7U:æ\US-ŚWdz0$є#񤭮$sBXGѻ _)|sY\N74J0?@wVߘ .8dF 3B]efJ/T n.{CaO󕶚C"owCI3_?fNk9>-.O3K7ay7UTwڻO!ifFIR1AxaQP҅ږYf,  9&4B=%vϰBȁw>+?̬U_ zST֌=>~wdܥk`=z}[~ǝAw2tp힅1cǍHaIe-O\m]#sO\^־'*r/}ez /M/-ݺmWwwO޻o_/u|{wC~Uܺ#g?jJ{^ -}/P!=sO1ӗus糍?S5zt~_kK<P^wmDF,v"*y/`O^Zx>GҋqzGxiZ ~`\bXe d%.-tIDf@)P7dU!H U_J4Rܐ<4I_iEqJ 9"nrVKW‘q/Ini~|[ߓ*tK3ގƑYo!+]nv ;emxvBI5,9ɚ԰ѣ] [MHa [TZ4}qưE<]عp (CBC#eȈP\p3ɑ9GDa6 ADD C*CF!ҹAɮ ¥J1r=$#H:#H:#H:#Hz5G> w9!T]z09j5#0#pGOGP A=5d$2,p3GI`{1(r.r5A0$ 9[\ap]og#ȹ?!8iӠ\ru(Euڕ#O`>x>) Hj#?Z]Ӡ\8|q%CFz +`YI |2yb#OR#p'G * 狼,j]UdGW_!3GP{8 c8|b9|9R<d8#ՅAK83Bb%GcAOs9#G 9k9 2wG( g G A87p9or伓!d8p9|#   gs ` 9Or~#9#yGAίq9r>\|!ȹWCsG r9'sl# d#pGa9CHcAb";.`i4ȹ. w0"#(*Pv cAIrGH`J#(^8R\`HJQ*GP #R2l#Ar&ډ@8 2"2}i!y CB$rHJb=GPMA)vs>(!V4_w,}GI\(49B ABC< Jq!4iHrQ 6ir*ehxy~ b*ݨs=}K:׬sV׹@s3sSLuAuL׹ E6Ch!<Z{62֞֯=jhK!k-F* ŨP#b¥mj ! ! !Bi !B 0 [8uA)1=cqf%{tadb?DJ6~Ob?UYnu7~(E>s[x6?oY!h,4>C4dBSc)EPgcJ3zؒaZ3ZH]44!B,`Sbx|X*InZ'ZZQkyqң)X>MȤ YRu[nHI[|5zi84 MPXɶ&-z41f5D[>s੥n?BUi"$Ezi5GYi|֬EE}) ?o%deZ-snU9 gjsH=g Q8+a-眭rN^!}rT5Cc !%6ܣG2JrI BmiCPY !r&_4TC(͗r\,Bα4*}/EXjUWrlo}傮pCx1>Z/H1AMٺ-Բ7K4RHn2jp}kJ`y=E 27CemcչRk޴ѪXɫukbZFNn$C=8oClHS8gJHۼӓVumtӫgZi+>T>9YK)-}j2M|=CB0z V4Ʊ4TE)| vTcZ+HflJxV|ziǔgDcy n}!GPAu$=#Hv nAҍ\H+'~wgL4̜`e=NP|x ZچV'ܫy{#(nG9Y_Ő(7AI86q%5ާjlrܗ#N EcGH AAi-C}2Z [C 40͑P hC$#Xجب\FOs՞cj oQx0P[i0qbST,가#(KAmjG]Q< >wp؟FqBDe+Vxbݨ |jg- ֊~\*[{7nOФO?od6gg')--CKM+I$f&-IGW_LүM-O{&#>_9B? DY+',MtL1|2/ _b9a ˙ChbgR4&zҫ !B9b?E?!"{C"C)C !&0DbUzƶ0)q'Wma^t.쭶p]$-lm'k}АK$GٟHѳ8M֣/D~Xb ZYyk^Ett!˓j=:>A# M>aT2x~`=KCY4w[P\bN: i.MgCWILfJ !TV*CvVƲyKN"ލO͞Z~;V?^e` C ye %!>ѾBe}P-`y!nGӷmt"&No[e{4oS!d Sd C@i8\~P>]gcƙ(=hӕ5#,`38B9j]}\|;~ާ"qrKeOѠLgfJ=#Y<%&}粫y̹#Xz  u؃!Ԙps~#t#5q5G.0?s4J|ODnn|Z t3E> no+>""7>a-I|u3=O63 LXM33۠eCACOOCI`YKB'⸁A_Sn# 813$.ZiM+C-䖉e9S{[o뽅LZʕ_e_4,qgZ`鱬c8ivc|>ms>13cHpG}O4tCYZ9G0AovA]m*Ge'eV4S?pu~ڙ'p#XG !1688|qڲ?Q< ݇h#(3Z|]Y6Hzʒ Udٱq*"> {"%tW5Chtc|Fm,CdJژ<`ibOg +! .)NM;Xq/>#M,g42tf, !+,|FPߒ!g;C(FG +X(,|':M"ber/+1 ӤL&;lSX>fzf*-A)892>, -9i^,GK l&;>5c0G < 2y=CFR}4t'Orb I?'xn4t#G,j), $EM"\WV_dO|#X;)< "r>f}v氖`O"dceal, >!t -Aه44`YsyX_'Y4oiP{yΤ |Hn &~zK=R/( z`4\4!Mfț%9L 7gih?i#4iNBӠVBL?uj Ю=>G_3F39l>O6O1P-qj0pri(G2O*GP#({ G6g{mAIs#s=Yx̜/xzTa-OT=fٲS[9sy Q~]B@!!rCO_׏R:Eh Fm<4%%'][q~χyw3l-zAs=8zp]u4έ߇v3]fC-FypvGvd& (U߯!m'g VRf';2Y>dӟx1}|!Ǟ|^fIQ}]`Uʧ1mN_J:mr^ߪu?r=: cwΤD۩ ;A#t܈sLiA ֤I_IWLi&(z)4D=7>QsY^!rzWx*[F_XVǝ&r4.{h,2Or!`ШP!÷U/UBBV%?m>6޶F44yt~֏ !#Yʧ) [syep5[~ @ݐJ@Td%3V!} Ohyl#ʵEjqoVhS3Sy[])*9Ii-69kr"!d"duR{BscPʢ+Mzu~} ?!gi,NET-5m$Zyj 64$2sV#%N X)^d|,= $cmx$ie?BMP:BH)_v^VCgbB&LJJDCA۳f7zg5 ~N3O3gX{UqD,e-qakA?5juGe֊G|mڮQңC46hHCC}'h.I3O0) !*{1^Fx#TֹǸM3شLģqE-ʑ1ChogR m5i;cϏd4Ig[3v ޽{X +N]}y:j5KL 뺷gz֘Lŝ?V_ۥ]@)E^>Uy__e*Vi~³FBţ.2aKs25ksz˥~ficQ[)ySG;v.kEj=}ڹ !ٳj5!`[SȎ YZ5lf;.Yʬڬ_!KLv*T \}ԟD&5R7ghߪ,}>c\rk .7>a˥~vɜB z!O+I[QZ1YrQر dnG 3d;nv~?}vyѐʞE,0Zsܾx:lU6 rA۶h=|I{ϰV3 QSBw~h\\z:ꊫC\:|D0jFy[&*nۼ7msA bNp޲nZc;zrޞ9Y`[yL<\Lv9WxίsKkvt=UY#EhW;,9k 8"d)܎2AVs{UK)R]ryrI}m ;Ί&U)cT)ž/ƤR}ɖD)(UI Ygt\W:S?U r`ٲ#Bٍ.N~lq^́h xOпv.G3ZmzR4ܯN4<Ǽ)Fgܲ,ez]HB^2s'G^=@uHLZr8j>NG4?x?@Vi #_4wiyDRcb۳D4[ [J+>Ij[?rJex YB9lh{ݼB.ʡOiͥ:w+w+c4{15Ɩ@NPlr-v ~Į d=ZoD9+aQ>:lX+1ф\2pG߄>l8r#H|ȼ1 @F4g=nC dwק^w`xa a8]Qe ?͈QKz}'3ZXAl1F߭|H9mp 5Bl~dQ͔7~u6oЧzUAVə̧پ,Zcy XfP@;qU Y2 ]v4=ßЌ +7 17=j,WZ*j)ĕ{7L/NMFo+EN/R΃."hȟ-GKq~| 4 |{M?*e]Qzި h~;gCҭ@qw=|Hϧ I2k|Ȗc,"<$ӽzR^}VQe #W:oЈ@3IDny&1ܭBjIƣMG@!V;pv'qx[ Zc2$/pV-GdVeR՘;)SjE4sՠWAVS?螺ǒH0z$v;(n@{M1 PcyJJi6316YDpbAx(; ~M! 5f :DYtB=^iI}'or8s6|$4qcӚ8PEsI^dZ[>dGt~Ϗ) q爾!J+EfZjma|D`/2u S:aDM(  e5OUS$#[!GJ)m7GۦO;1 Av1/ 04:P搘dV;i{B4>?-b4g7'f>rpO&p%qjn Oר^VTp-?L`{GFڍr4G塨R10s l%dB@yՇwq>ь\ȹqU@G%  p-/L˖K|R #\W(4¸i.|bSrbN1"G6$Q2k4l+ynwoKP`;x|9Xq^jƢ 5 feÍ-zPY,[y9KEEAZ:ވU zvs=!`ⱓ i {S~~Dwb5q A22E|RIR1EL\)&_i|I;2ĩXƺЏUc nDϛŪ X*'&"><\sa#8U\-kdB0!qOz=!'qXc,DXcM[yĂ.V zoN!$A|avp(F֦tߧyr\` p2<V1D+@΂XYud5 T|E`xũB 3U'Z9)VEX &d@ds" "5d0o7 8l >f*<1UK<·>Qbkԛ-β2IDo<9`{fKQ6+._ѽEtߡtCިW\I6*.ܛtE_} {!!tCBB: D&6MDm"jQ`H[P>RIUwUN'D)K" 8ț>DLW2,$D1Ǝ"f;:qn+-vVE|*~98TtGٗ%k1K3kryZ"ׅO\GD* &naS:KLmgq2Ռ蜀.rp6*Df Z]dc\-eX>*nh-^|.C$l6uԵ+9;'N#Z`dj%;1orͤ0%WtXE3x6gq y§MpYilfkcT2QsQckГV1C ֊5*m5}?~0h㙒2\ԈvҖ vmFOv_ֲ;Wm0+ELjZ܍5Su3[0v cFCkL F}m,j5ThptZ痰KKCf"'8=D̎СA(," 2키f2bjVĕNеq*e:ZvٓX (=+XvE#!,|B!?l5Rf6"Zגb|/)DNxuI!$U55OVPyv r͚LG$9өFS CE®B8hI,ƉNYۖ8[Eemm*/}~_kp$[RKLѧC(&4)ľ gDi L%AiŭT 4cIu܄&p#O:M lV {.Jl ']ݣ_jGօ`8X4eOa_~v> k~[9RQaovܳ謨 "O oL%0Oy纾5߸_oi'h ˚&n7v{\Y#DBAX*+T1(2l-~NUʭ< np;5[kL87C> fU݄RhIcI> NiE$xD&<__,;XЋ^2h]r?omo]̱~BUQLknfK@BBlbJDWفt gv5O CA8څZ领\Ʒy++1_+E6~Dǯ%9aaLgU n̓ >>͔11H`>շKF97%kN*s܍RU!{Bxnxc=cc;ˮnb؈ʈ)|YŵR+̧8.w#ϑPKl #> .7 VESAINFO.C[S8SCO8Bpspp0a[ʫJ±s~H~$~ _Z-e!#; Y=bE?~oO|=Q? M{~g{4~I/E7My1'Cֈ.^$Qx`L9.˗ʇ@cN5:~0Rt⤚FfM9QrLAh.k/9&b8y{Cpj}{mR_z* K¼FchV`GAh:i{W5Hw^tiġd&UIDD6M6Ͼ^wGmƈk= Tf6M&qGlW*:Dʸ:ʮ{#E_xU@E8AS44z:vx%R^OW0D.%a1{OIB38y9EM&} y|_ⶇ΂ն\ou{.i]!&L.W.6\#'r,F-:{A'5Mmgf9btgp_Sƽ=l_ FW>_ ^Z !T=ֲfǝ-Bf`M!bMփl'Lμftw5~Dn݈f8[bZ}8X?S hͻf}% X& "燬/ lxӭ)x9ifwFɹt҇CD6ĔI湈a :2/ x"?s߱al۴tvEa30#20x;.")ƏOmН CIӰf2}KqaM ~f[)q5/c'ۈd<{7 Q y+G48%nx``={WADZMG<0LۧUq I`d6(tRZ9<19-jh hCkFۑfނ+TF Ψ/*|;khpJР aq%HjC~/[{ LL8xۈ\L#c*d<לij&S#ie9u;IЈ=[ZV d:T.CxAD>^d%$LwA[{OF װ" /eDΡz/9\.얪YIȫh[ƙ*rg^*XT=ҽWʴitpV8!,[I~e4ǟ z>pOHs"ѥj j1Z*PM0(|i`_,2E3p/X\z?ZP("Ш?Ds 4t.׶x[w>p(X=^vKUK%MoE YA~k)kvIT=J-խE˫S9Ɨ!e,v:?̥˜>x̡F: vZ>dΙK0J׽ߺi ? MQ-i24Ŋ$v=u=OgOI@y W@×(7h&fjV Y-jz"N3m6U=<(;/wSy#|/ ߁sRZ22o*cmEC/hb*q }3vDԶ`pPaȤ53DZl VC|mShjD֩FV$p?FNqjH1!% X"dc|n Gvt\] 9Α{1~ϮX^9GP)uU$y^oQ$j)dXb$Øȝ4ET(~Ě}TȦT"qSnO {9?h~ڗoӾdBҿ*)lYav}=4VW8^]C[8ʻeYM5+A) OCvSTzT1`=( Uږr ve!w8(rPKY\#OGW ALLEGRO.H{wF>|!&ZlN(QCRN$ DM 7 -ξGz^]]x@"? eM!kJgD_ sa e~e[___#x&Sz" vE8S?}yi~  ۔/\j=^?¾[;Gؾq3Om{t=QhBҕ} $ " W‹};phr=jw D0/@ l8B3hF(Y`} -u2\u+9h 8KiU:'O6͇:!j:zj: /?/}J0DMkJD &dXh'ǀLD-!σhF(mտ{#^ "ͼ vqDk'A7ϲ/M}4YQ˟W7UOŽM0s?vfN"cI͋3O~Y?]Vs,Ԏ)zu,u8dY8owtSԋwuKSA#S BP$(-"Q >ؔ)Hx8w%z.\=wh95{(VO4EOsĚ< ef/=A ]W3/7瞡LH?Lez^դ*+#!5Fez5٢<:PG2Lӻ?=p) uGA/<6IN"#py.ng\uqb'8VJO+ 9 'YV1v2Я ! w͌ 8C[b%ʘ)c bh~-FJjlp*h 8+jqkzcgta3xk&ψ^'i*MbOy.vM7ge4hHXg`Y3ߞK+g]o|ͭ,Arb]eRnoi#oJp%dпCt.<9sQAUؾ?Ѧoc.{V%U{%mh7z:19#j3*wa;xKGFJ>#/ѤO ɭYcss>J֠_5F^󆁉їlڿMod{ 2Oa[;[E賵U.{C-5]j%f [b2NZFy$L~z* zޤάu+ [luji&S 'j$ My*!@h㊽:#]m(p 刓lӛ<|V3u4#QE#ˤ`*Z 52Ly|O Wsaka840lÀ4PJ9RKJxm.O 8s >vY=dbx?aBʚ'uA>#L dHTu{sE^hˎϳh֊tZ^dY(*t$QWdUu$m{IG'ko"ӁFRt.h]nBѺ80)PVPWBO:uy% P(:p"#EBPt: B)8ˑrNT2R Et ER(:I(^Օܚ'CѩOBt˱xBS;VtcݱSyP'NGPtzNJN/D6_(:&k3Km>Qtz'N/ID6k(:lT 5Ht|>R(^(:};R,vJB慢SnB)(RK'NLf^(:] E[):ysR(:_{#ISE=u?Utz3ϥ)TmmӝjmLt>`?>t ,S(Բ(5 KXE#mVWddc,K22JenkX9E٣ڌ>ĉ|6㿳L`)MSs 8^r O\b{}]>df44l 3׷ _NDdذg~_l".lٽv'lGB UJ @"z3t3Zza;Lrb"ZΎ@ѽ /z07yDAJ=tg7[Koܕ :&Z3i* ^W y ºjZ΄e+QE퉴V@pn"h4)E E7Q/.E)Ph4%bԿ]MC4EorjdJqR( }f2v`3LMw\X3c~ySŨ. 3VPPAX5y vx-qqI"5h(qZ!qO] ԺrrsZn 5/9FC'RB߯ke9]0!!`JpkX5 dIK`B,L#:[-bϱ}Tww^mu^qNFf/vTT8rsqxFȋ!>p '0*6ʎl׋1lPgVB|762tVg/j,:Av~ WG|t7tf`/xlPVU2#s$tq3bLھ 0Vƨ/y(Xgg4&.|/N5(5〖"YAwǓ>{uho w=["ZGKEl5@{"*$W bA@(Л!0MI2 lD_a#uîK4%I"d$^6H2,'K$ɦ͊o~$Q{Su]~]H U%ѷs{Ia$ZϐX8dN^pA|UM}$Cu>+]ZK#lZQ}[$F;|i\u<{JrK">0kfF{#d#$lyloeĴi 3mﬣO EwnIJ$?Kˤf`ڇ&`nk `R&`z7+(n$}.Cޒ?\1OS =E56 1Kf,1]V|H1݀c;?)ZljKl*h/ beZ~i5^,L9>5^|)GN";}/\JyUA5^"0NǯopX$sexR#eqNZvqqBA)=qSgsvZpm* E?Țѽm\0Wo#k+IHizG'*T'W U!}q [Z=5>iN9h;ٓ3Udod$~Z1 v2Sb;h]n&ow3{ { `l/Wē bvU)Mmwvz--Vk'lOJe%w&=[m8l()<AE ųLV h#T X$ (Mߩr ܈z)2Ep3aKU,*#Bq)g>J =`;Ic虊.t0Ϩ_fb{LN;nZ摍7n`#To7Id0&&B#S91=WTp=< @: Vb<77Eqº/qp6e9~hvGHQ*D,X> /+ʎȭ[z*m-70{jI-l Ɩ3&ͰQ=NL!|x꽿^_itB督i񒃌z$H;EI>>  Dr '͜ -Gyo$Z#M% O2 9bwIЉ&&FN0NPec&}FY+O'?5RL)^ Fo [QZߡBlwBڹ#BnD܃F}#ͯ2c&.-́"t F4J@% +\fi?㩌. ^cU)!;jFРD$ |՟HtH8x-ПIPO¸GuHPVNץē!A9ai+1GzX#]gVѵ0lKai4 j&z4ɜ # ('Cgx~Cǿ= `{pFj޼WQ͛hzfHHL;{'C>%tָ_=7Do &NhFo;h.%f<,y7a3CqM%\;_^0bd8Z^Xബ^Q45#˚x7"59u#,L"8p?tOh!xR ⴤA"эy\}0!^;QNT1|كiG"_`=04vl[Њⓓ'Gr'f=B*߬6/ۗfl~Z@go.D|_I%d݊6o*FoG]zaFZ2T:zFMyBv!gKhaWs6~ Ŀ-\'5[=؜E9U2U{ Ŭ 'y`J,RUvURD5))k[`+uH*va϶9}dх[znF+Ҟ Nٛ uB?&Jțm<` !Z6k zVN~! tsƿ #:U8$ǘنuK¨EpD74Sߔ'''񑪓W+gblFߓ/̈;`X F/R=J̙RFȰw)LJm-81e#9@#R4#@sP};yoOړi$+PJ8JHɲD2K2U6sD(Z&bRM:x'͋XMY YvcUdm}ll(>Wa|.d1W&B/xK\ܓDcW$*djF\&:$KSJvWNdb.YZ,lP@Rڼ۳2gaK=-ŎX-?Psj=)v,ˮb?_GlL]?'ĨM?;/ @! f ,OɮΫ`UiLaaRaR*pXU0AT$cǘ:^aG߲[d lžWoD +%jNY J 9`4)v̜YDy!`y1/̇&s3qj֔s{erdYNYˍv(Č*F(^hvEt 1idZ|Lw_B/>LaSaS5* U/[,^;ơQE6TjVdwPi|[gSF](|и֚IfjM'oN= ybyv0jsȾ*7,yyw8J<raB\9IM=u{`uU#-)}oo},2sTrl߱:ԇ(q`)r3? *%ez] ޓ& WyIgd.˲1ʏyHd79Ӹp9b_ ȇ0!~; _V`)pW`yUs '\ 0ΌYU/^tRp4P'݊3r}Iw pi:0bתfYqk.8v`Ks MZ)MлjT"T盪/^Q~L͐|XhTe%JHrQ@tF}A0d owb-p/p9L> MjA{`łR_ٹhsɬ˃5V-M;)Xpĵ Dazˌ@p(sV>vv=XÛ%>8$1c^ k| CIt]%X{AG Ira1ccB0/,Jj\сΎZo^?HUb $딝^YSS@Ǚ?L} ' ;pn7^ 7iMN㟩J0C@k߷pf$b< #/y(H[cF% n~[{WAÕE*!Ur(9 xbeG0Z(a];&vͦhZ5~" l\M<{#81Z_~_,@1uMK.D `H"2K_y,<1k{{'^J]9>/V&0 yCbݼ[҇HjAvºCd]/DlÙГGZo9 `^iU_tjQvK6#B~¡Nё1tP.gE~‰JVqpX&1{z+bп}odIއ}ջ._zKG=T ^Whʢ] R}i o" X[ _[[4A8 W7rMuE(Lu%\\IWEOU]ܓ2}&ܻն6s1WPɋH:3V\o%FLA8.9YΔ VdOV8:/`=(>c\2tf\b_*zy8,IX.mJ)l+dmqz%l j 'I,^oʦ֘'3xtQ*^bK>P-:aD_ȝ*@)W|3k\2Yn W[H2U(O/t`-,7 35yI jRrH؉gVBU=')EL_`~l&f3)2=ƫ6@f(fmH؁X&R@: afI ,v&E`/]Z)$H"^ A08#{ҼiJS8qoϬd'\Ǟ6K/hۛ"40Fweq˧f̼ >dOW7GvyN*DBC`/=lv}-BWFRboª|\0b6}daK`eQqf_XJ0f=TsF*˴_2p$tF5\H6 €F}ai/B%8e'4 쓒!@> *C` p( @xX^B$jIwⒺ&K&T ޙ;Nkwj!8 r/2LWBx ӌęZDY$Knգkyӏ--ufja%{n]HK,\oO_@74ǯک1Ό62" ˜""*D8 SOFiIj*N!s+XY`z]t!QCWN2JQ>ċr8;(Cy=If$pDs nohՈLg20$9@.V9UeR T3XI>tA9-/Rbdkפ6XUq3VUPE8@x~p ǠjXElضPr$ !:-&Cs a E -qv.j1b !r}sNuM,grU>rCoIbƫ%& ]AX\㍀W7T Hg-\c^ù6%),&"EeKR .Lwc}ۭ4XIBяN{kZdj`}>?%u@[ @ޢAbN,hSoNj\${SqML" ;}&H$ J `\/5H0,D]nӄ{nGY f_v,_~_k}֨l>p SZ{/Y9ܛSܼ/OX7z$JX'!C꟟x}{EC|'NΈlgA<]e2odyqxr~ri2Wp|.i%K&.G˰zX陂{˅ʑ^#V8pS" kTyUY[9V$/FS k $dZ3-ڐȣZO^hwL遳XKSAviP$ 3{˯>x@GQ!VU;2pHIquюPx B>{L0b1&ߘݠGv+:M3b W]5'd,2&JŊyG$ߙjTޝ p`hjn3.><5K'C@+J'8 'zwt=<40%MB}Ty&FkdvBda Z~p:1]!fr2Y t^Ey[dѹCkL 'j*Ȓb:efA1R*FYjdֲ\e J,f'ݷ_5iI, }GZcAX73+dЊ(X r!r ` !gj3PK?"#8zOru&^ s[[ iEY")1zZ{X'XwϴC1:ED"aJ̊e)D?"1G݅d\et'Vf7MiK_$F˗)|p*{^ʙ"~>Vh@,8eJg<='x.RZkB!|5SxgJoT8b s#iH X^* HbGyeuc9yy/3qQ 60{/ *0]<+SځF{גlM7.X.W4Rp90 9+@yTgsx/-s8;l3lœaan`l=2F-0&5r1M6·":r]M ZT4M,ˊrMw1o,2y3z~9GZ>e1RWYU3{;?udm֫,<)ί-d 27GĽ$L?.6K>)\Ihz`_jcͨ`n;"6,S\tyqYEgXGQQoԽ~;S͋KCSHKt;C!ya tr||xzZ/)cJ;&Xቖg%Zt z:ߣ$8ۉ<M$d儱L}^KI! Rl\)E&?˒#Ң[16!^'d췲{ALzV[=o %Oۤc 74v7;.WZgȝ%;i’6tܮ=(/KM|Dö t,2t TRn̼: .eW8>T Q%q7m3J*ICqZ3Y"NsVTY>D,QBR.;bQy-bEڥa)Ά-}IX%-ƽ筣(p5)eŋ]oih?@${DA?,WC`Zdӿ{mFʟPR$L7MGU<[ q;,VMy1 ?j:J>OU5Ht}1w;lxOI=ʍD]Ǡa69E6zah۠.YkF,un:Gۇ]]U|vZDMq" OW3ڛ'.pr@r>Ƿ4.wߡ,%(ſV9?,P?8iR@wGyvw2Vfur 5@l`/,,l*VE)3{]&F/!Vk"*`*)+13aZ))44s? n2 ihZ>K 2s! =Y{;Bv5Hw?"!ir~rl<Gjk2~'Hd.|EJ(ݥ|$K!_*rڵ#[hq@xw{{H/Ʀ ' [,:仟fEDYs[dMa Cn-LLrGrMi.H~ϑ*ӍKl$) 3N.;*19:Aε" #|QWr*TYWrJv]|!`f.Vn R&Kf 'M_G2YB,e$8sm䚆%egxt9#VP9Ӧq@a8PY:"?n 6#OmN2TlA-5Ѿ)p]&PLN*XN:h8BDrts}D<5hY^lD~y'RUOPbV52UmP^-O *W½ P!B_\Ȭ oL6&H3IMӽyc_evj.,4W&%٥ۀ<)ػc O%w:K,8V:`e0`ˊqd'=Su(SS3Vޠ7Yݣ:@NIw:oйItQatrEb= cےBR~HW9l= hvANvCv"TU=+~ *=|pBEZd\O$yrs6 v#S6 v#zٴ-f@2}H&dr8vCB(,e%vp@F3%@MsB5&_ пAQ`@xi cƏmnt_nܣÇH^ Mijc=En84@/sJ^$lq Z1H_W{EFƤ-Tl,b c^)E"gjY~1fa,Fob&Fnb&Fmba0)M6>fw7_o_,D2Vv5mL_uâ7vuPidi7ky߿J,P(ǼA)P'j9NZ@OvNv 3j]6°&BPs[j=~ׅw)0ʲ̖o34&;HAiHDJE6P~qFw'MtF$ɉ!Oebn/j$eA~JyўV ~_JV%@z&BrfH) G3e[Jvi&d@%"@;H/GVcΟI/qA{(;a@}EϽIJc\V ({ȑ!Mq%x?;~/:'1IɊnW~Z&1—< _g/Hmm4!+5Ѩ0m1ymW^|1u3q<|5d~8?+<|yCvB/9ݯ牖ISO+/N+IfC 2ߌ/G*f$z^Hb<@4Wgn>? p4q",$.`r.bOLv3;wE}I!5bޒtSKv4wuTll^INުe<;\DPKb-p& MAKEFCFG.EXEPKN^&B README.TXTPKd&jzmd VESAINFO.EXEPK#B90_G\ {<  smakefcfg.cPKl #> .7  ƃVESAINFO.CPKY\#OGW  ALLEGRO.HPKSxfractint-20.4.10.orig/extra/tru.c0000755000000000000000000000376110150636277013627 0ustar /* Fractint writes the escape iteration of fractal to a 24 bit Targa file called ITERATES.TGA. This program reads that file and recovers the iteration value. You can write your own truecolor mapping algorithm. It should go in the routine rgbmap(). */ #include static long maxi = -1; void rgbmap(long maxiter, long iter, unsigned char *r, unsigned char *g, unsigned char *b) { if(iter > maxi) maxi = iter; *b = iter & 0xff; *g = (iter>>8) & 0xff; *r = (iter>>16) & 0xff; } main() { int xdots, ydots, i, j, err; long iter, maxiter; char red, green, blue; FILE *fpin, *fpout; char buf1[12]; char buf2[2]; if((fpin = fopen("iterates.tga","rb"))==NULL) { fprintf(stderr,"Can't open flat.out\n"); exit(1); } if((fpout = fopen("new.tga","wb"))==NULL) { fprintf(stderr,"Can't open new.tga\n"); exit(1); } fread (buf1, 12,1,fpin); /* read 12 bytes */ fread (&xdots, 2,1,fpin); /* read xdots */ fread (&ydots, 2,1,fpin); /* read ydots */ fread (buf2, 2,1,fpin); /* read 2 bytes */ fread (&maxiter,4,1,fpin); /* read 4 bytes */ buf1[0] = 0; /* were not writing maxiter */ fwrite (buf1, 12,1,fpout); /* write 12 bytes */ fwrite (&xdots, 2,1,fpout); /* write xdots */ fwrite (&ydots, 2,1,fpout); /* write ydots */ fwrite (buf2, 2,1,fpout); /* write 2 bytes */ printf("xdots %d ydots %d maxiter %ld\n",xdots,ydots,maxiter); for(j=0;j{ow?w4|>|ޕLJp]Z|40 x.N.p=oшG `1M 7&L6">ݡ/W>%u|w5^ Ċa7'ķX(J$I 9RMnI4!z'NU:4 3gf~꤮s9Js66I(K*֝<5_\) Iczpk ]oK&%d i;!*f9vp!2 |`^;|t86G|hC4x3"#g#gJ&S\pq`ï=V]=}8BbMN \u?RG!rft*_1 ).G'tWґ< /ɁqZ@6ڋMFܤq  fHKRZF[*FD,5FZ"ÁeX@C Mi5Z,!x`#Ga~'1V1##ԃb*:)r6>@Z ߝ,ZU-Nj҄~k}0n]+%bSZZiqIUG{oނ s {]>q8^{Wx w}X>E5\P$D}4T9a/t#=x XIؖEn{Ĵ̝ь7t;q)^hȤd G'v䄼!_CɝB@Bjt0,;g{gS ww(O0}y+ FF?[+3Y۲m۶onс׏~4qM^ud&Lxᰮ-r';Cɭ&_RR$6է!)͖i-uh_/ҘJ,EL=_)Flavvڝt& ma! eIqM4fr4M\/ hRom5ܗclڽ]CBMXI Ɋi8UAHIDW.;7LJ EGF~)A{I3/DQ m'H(^}:1V0c£!e 9-|_hhqIr ҈ӗтyL%yڀZf:) , kI=sVPz+5[;eYؕ2Q緼Ń"j.ajGnM!MfۺT ]Sƈ˶mDά͕&e[#nL=2Ozj8<>[Xa%d%XSb-Vzj|leTp!>;'~M$q42kʧhEIRcWjVm})d{mU^/#7l Y[ZJqnZ+Eg !fK%s,siLv56~7ߪuԩ= `gljslS:ѐYߛs0eCgU8伯.Y1ܽ%I29R&t&ע(@Eۂ>R} ,cQ]{ϧtSCq}#E^BOF<Dg[ d)'S4tV3qy/kP$mb f0 RRZ}հwh qQmWMmetA;^7!%զ,ǺGr[^S=r5nSƮ=mS*y`1L`>A om{o |Fgk=e5o`W}MXt Φϟ0BrPk\z|00z( 2c)OeiYWʻ;|Cs֓n[".0Ž/!lC>u?\nh+:I m 2BRژYp5lnIζXI∱%i`uwYqrᥥ*U:Wc`EsH@6(,,})ņ4\[)Жʔw Lj\_.XVFxж|tW"j]Ĕ:i@PuW@@(( &MmUz@ҮDIJdO(8=qSN[ 1/h^}f,۪;qr_nC,*pu$308+~ D^{xS`[?GhiQ@KSåu.P(_mb_N5)wZnm9d\d9j]E*d|@2ՄÛ:Cbq{t%LQPeNx )N5,`N6rmٙ+|h~(,*S8 2[ˍaTҢϕ %a[3e]֌y#] KTt4uYĝ`@l0e֒R%MmLq|^442i kJ[;.+ D@Q \ !\ i=fpR~,!U] "_.+D,RKIi!45?a}m Vi- c:GJW7! 4e?z7TkD*BOPFJPB$qYK}f|gv#vn⠦ѐ񧽬n:}lWh[M7V7(/r_XDxmXSkb n{)k _a>kYt K_A" ]sLi);öoH _& B 2gX glF[ B%kDWJC@΍% !>(VձK֠Ei4(WN19@΍K3|`F*i=- E/a(*!PҷqhBKsI)YFfQ1A)F!%C%Ӻd^ƞW>Ig${]0!Z[GVNA4[TL:z3@yV&pcܲ+'g9hL DEρc XWzeBŗZ0YMbi$mMD-+g4HQ+A1%98{eCPF Xk=srLLIlbXz c=BYyH%X'#9xuچM6 Ȃ0Ht+cAi>/MxCޢwc2BCJqs]; IV7UaW?gͮ qWAfAB`i^iX  FIȘ$q.QҚ@սGN K"ՠR<rV!}߶l 66*v3J]Uk a ^0BQfBA҉Rp!(@kH6'56meY/CVW@@\/r[$\bǠ0^--XG8w=ECJkya\ "CYf 'C/u!$ͧyl?ß#O_BӐ۠hhK%[QrkʅjK ^ }4.A(lȱ!3dm9aȀ5 ks&av8Q%-shz\^8FaB50QF+ <l(>!l_e#XK,?G\wOӆ30|ţh[kv0bfbg#Y"dU "!Kf9GH p!.X'ˍ,2:>~=r;w";Qֆf j1uUt>1jSN-OcW:mV7ZJ6XY^&s0bP1?\X5X;F E]Hvcc@oXtEc [G6`T$ЩDۅ4%/x-npZ5])a*ݎ n"(dI hEQ1.[upkq@Pekr'1W~,6l݌K.bR!fHкsmTл(]B >(9ѫ^qs7r]8dN xU h,9*mǟ/jC_aw'8 xO!I9W&[+[Ȓbk=˺sѷ'HO/l;(k ԛN2㘌Vt"B7rL9^tIPY:7lV% +~;Qz^|z! V;b;-yhP 4bSaQV]\ ;@Y-Bϡ.`R/RsaG/Ԭw0-Jוxcw2 ll Pch2Fthtzz$QVsOȺ)ζd~<_G%}?__# |z8g!|݊ǖh6=Q2>m8lO9'tv'L%ͰTag?}jg~%d9HF 7dL~3dO^Cai;``m-l,VnӋXAf aުWg J!&/OcVXApJOy}zF3?u%&@kA{/)Y&Ldv{t8Uݫ9*O%iA3@v>xzgq΀w}䬂rU ;B5ڂY%GC~\ϴX_@/HuŲ+8|:>:sͶzqtPkQw͉$Ɩ8@B֘b76-\`;PGcÑ8|URE]IsG ټ-HWL7݄ }Zc`UVwS )Az(kXHO{v0OrFǀeF~3P03覻4'4XB%&r QXjώU ?CHaڊH@Y.ÖiX|vXVN(|"יFavN-ܽ~mHL 88 <ٮ!iWցtU%F^+{L1$?JCr/=g+cTB74xjXS]rWA @3")U%2xɠtum01?,_RAOcd4.ه(۰AA#@Qw)ar{Iݵ=<`=?Ukؙu'9Fɧ]br*1P ](!E^l3fh8%d?>H[l oR" "'dX.Q?xpiw!2a%)>˧]x鵇y/$$Xӣ@T٦k@ĔC)=u ;F.##-1dX8^n!u_UvJWH!vX9lwUcbOR9D`O27')IqReբdc.$' AbJsǡ)I&NGTzqq(8;oL7 :{:\l!l!!!1\([H\6[] Ʉݶ ؽm2k ߇O>rcoxSmkOו1w?PK79w1j0r 1  if_else.frmPKJ)'R1  if_else.txtPKrxfractint-20.4.10.orig/extra/hc.prj0000755000000000000000000001204310150522423013734 0ustar Turbo C Project File  2R           d      "#$%&'+k[]^bcdefghmnoqsuvwxyz{|}~-DIN.C:\BORLANDC\INCLUDECPP\PLAY;C:\TCPP\GEN/C:\BORLANDC\LIB032125210034*5*6*7*8*9*:*;*<*=*>*?*@/c/mhc.cest=?%\\ 332 """?: 23AD32767E8192FC.CG3G ~GREPGREP-n+ $MEM(128) $NOSWAP $PROMPT $CAP MSG(GREP2MSG)void *.c~Turbo AssemblerTASM/MX /ZI /O $TASMTurbo ~Debuggertd $EXENAMETurbo ~Profilertprof $EXENAMER~esource CompilerRC$RC~Import LibrarianIMPLIB$IMPLIB5nGmTHC.C\STUFF\HC.C6=(3nM+ (S@@@@@ @ @ @ @ @@@S0:@PORT.HHELPCOM.HC:\BORLANDC\INCLUDE\ASSERT.HC:\BORLANDC\INCLUDE\DIR.HC:\BORLANDC\INCLUDE\CTYPE.HC:\BORLANDC\INCLUDE\STRING.HC:\BORLANDC\INCLUDE\STDLIB.HC:\BORLANDC\INCLUDE\FCNTL.HC:\BORLANDC\INCLUDE\STDARG.HC:\BORLANDC\INCLUDE\IO.HC:\BORLANDC\INCLUDE\_NULL.HC:\BORLANDC\INCLUDE\_NFILE.HC:\BORLANDC\INCLUDE\_DEFS.HC:\BORLANDC\INCLUDE\STDIO.HHC.C7 xfractint-20.4.10.orig/extra/all_maps.zip0000755000000000000000000027561610400711714015163 0ustar PK|'CU{>9  123maps.zip}OȿumZI BEO )eۖ6yﻡ–a<E@R݂$;HmT Lۡ]@2= /HQ&Ykp b0ҳ@m x1(gP^ fKz`.@=S@ pWP^ ?og.#@h@yH\Y8< )ğY a K@yHOHSgY=@z%< E甍y ]<o$f3@yHg*YMgxɤ<( W O\e /M`~ rGRzh~?O|&Ii>Z*6Xg;J (Z S=7S9+TgjQA/N%8}"mrlsoup*?1YB=g߰ZCiXkuȺh62(]L}'*qqLn>?QM6C}<ָoŝͳ79v'GSmt0 fqV{B={z[}fu:k7(`FȂz={ȳGފÎ5d曻4@:[.$؎A8 dž̖?̴tm_&fyS%ha1z)lΪ2LldS[vZ7mk3OEj ^7g `>|^7!7|Zzf6UNF@Ck̐`5rjYZoy1pd<^7!7|Zzf6UNF9$OY$y%|˰!:YXrˆ{FFI#ԴsdOE)^7!7|Zzf6UNF@ɬ5@-E_EBlpO֍ֹä!ˈII [m- }.F)]\a~f.{Y.EaiHAvQS8KoD}h$qϿAoKC8 .i~|O|nhOlد@HhDuu?_{^{ TKT'qs91:^nZJز4{۳*wi+JCK:-5J ME.u݁MRAƣ:Υ,RSbՊ JTb G8>鷍ÊegmWA)Vj͠bb֑ج؅R[ŨV2ՔmsyʦLTb&5=@ⱘ/;xX$ai7!"A𤋮*"'22-Ao>5(z NAoNovzKo*v +fL&#'vUj onI$ Jqi*ٕ%œ`44XD*Ssٞx, =" *")sh^EFsnڭJm=HO\r$)xD#17@-&Ls8@=: L,TN8U+ؓ.@k9[6,+2b^+3rjl,@ d\KeZNێC}o^YIlw(rN/kͭ =͉t3+feZ硗POӕXYfN5 {[yǧDC\y͞j ^'cZl}N.͹7UŔx Q5^PV^Cv^.44_[UA?8OyC(7O8u&LlMeaC6'Na?1K8o;Tew+TIq}ԙ+oiNK[[=Fj`uy`!:U}Jgp&А& ii @s~Noždؠ7l2h*WP^< qh \Q3cr2!{ rɪ+;"S mX.@DB ^:RsIX$\2R iI|= [ ]ġ1KwI.E,A* v vQmhӚ\Zh5B+ ‹6Rh%9S=S<<(@fWHC3g8PV>IQJwS4)D_c; GC6jq)Pk4Ʈ+}ߟߜQOt~dXLf99mZ6 e¦:mzqXXOOTvQ/*:-,:#";@g6`Ib_ЖzUYb*9}kU_\C:;\ z9qa)o@mhS N8@ӠG4`-,oQܡtXET@y"J݋][چ፬t,ދl@oY%_RRߓHj8X4Bs|!l끞34;3hui `7 6*\.(^ȞMUv$R,6hx/@$3͌A%:4kSbRA}ZgH;x(.\GC"%pҰ{~{HȭL! =bqB*{iCP4r**YD@o4|N"6i͙&--ffҟ-@ fN>Զн;$c&6@U[VPs,6j(" H`fA[OENT$Xi@хF:PP$DM;T2؈!LD)U:/6-kKrӆʝ72O35I ou*nmEu*p4{aŁ `5YW>A-J ;*Y!M9NTqɿkM4D"ΪWeD|$>DNf`pG  INHd]%HFHkͬD>./ۿ^Rp\G1,9ڃv{vysv8 y{&oAU4J]Ycp zL%#v Y, kކвЋ7Qb2څ)eUZ%vB\t@'d'(RМh=)QT=? :{ >ԏ \1 NDFe̻ؕޝ̥8k`ڜR!skNXNfJ>=y2@f۹?+7s*aC83F'؋>EVv%5G4ISb~ȍ[F:GΑmwĶ-^r:QЁM)NE|Fx 4׌{`s|im2 P(hZ}-ޞY޶|giAl?KO# i`ND'{ cWJj|NWj/UAрr'$ LwG ?H#䷷-YZ۶zӅ8N2'ɽsbߪ8*@ @ DVSRMmPߵ47mE ԰_3ۖ,-m[ZgBH'҉#Pll2OAɏ#J D GhVs#P85@ ߿ miڟ "uhNH'ܵ?~7? <ٵ}{B!u)Zhum/.hT0uiZku.ޜ:eW\:9ΡuQfUWTd0t/-YlJ4T0Vz61%W 5 C ESN:UT3u֡:tXa:Cu֡jCu֡:tX a6Æuذa:lX a6Æuذa:lX a6ÆuذVqRRҡb+VXj#茟^zu׭z0v+YawXV܊nN^f ^.x]0fw#llO2B1F(#cbP1B1F(#cbP1B1F(#cbP1B1F(8#gP3BqF(8#gP3BqF(8#gP3B1F#tcnЍ1B7F#tcnЍ1B7F#tcnЍ1B7F#tcН3BwF;#tgН3BwF;#tgН3BwF]f-+u+Z*VU>}~6-柠hcE ] 9YjeQ-XVooVzhKW^zXJ5׬^zz٭^7jt7ް^wX/wX#Pɛv/:4^7 ѢׅE{]샒wuaɥxC}lȥEۜ||hOG;CDAZ0;#VG`qq,ً^7{0u|.>u} xE[n'2Y@ P& `L@ 0& `L@ 0& `L@ 0& `L@ 0& \@ p. \@ p. \@ p. \@ p. \@ p. \@ p. \@ p. \@ p* & j& j& j& j& j& j& j& j& j. . . . bH W=?I͏|c?KI٬]\>(;?s_8[RI3A >3]ȥ6BzrIh6!&Dd i.xd-d GdvuӉ  $Z>si7 zpP~i9<)qJ-}V@ٝ%c0c*Eh]$Н|n|ȉ@dS~ n=2tZÜȤĐC്s, wPpJrE TH^IA qm2evP'<}zӃn--iXN )m$M\ I2+.F*JNǣj_@I݀ksVPn0N1t(ʣ _G0- pIV73FXM+Uub8_w[#)4k 9F2Om۸M`@d *-yVx"\v(۞ AH@DJm3!!0zwCDBh&7F6}%m\ ]S&SRjW d &"F,DC@­$X;AH1‰g`!H"cf=砈{wog0X&/~t,68EeY*Zqs^PԲd !t i_e:f q 7BC/Qbq⿪M$*h6ZNTYmc/\b"8î@C?T=y̗'[JǴ~7^#?g@) `J:5vp6b<  A 0VI0c `xs5a3` !A dp6oM~D$baQqe S,H,YM~@҉eQNF2^gMɺ;dغar(խICL΀ M~d3պɒG! ^NZi(E`6 stoaħ>O=$j1ϲXVNpզ5C.=9Ԕ4/rV!`t=g53ؒA,I& @&S_2L;{'xpU0F)M& :Rd_ޞ;Ufw LgPΠ%Ă0Ftj2HZt69$VaC $('-ҟR/\Tx .!C| P11)( pT%D) =w^([E!.`U"UZHV$joPoU5LT[D,fvv`m&Ȧ)Y7~tC&GCsS$Um" bRvs>ȊwVcc#ysٞOgZM{h=פVȪ\Ȫ\ȪvȪ\IȪȒ]ncmJc=KcҢlQ 'Cva7Jocv@iGs)rGd^O2 D!$ru;Mubm`.JV6lbL&bXScN9nJ"BȔ wӡBj*$JJ+7!JP_(o MIqMD "P QP̞n44>!o~haX=m/u ȇN񓽌w.GGT&*y2 LMmts2%$LvN%* n4W m9GҴ4 1yFT t茑2mFT6ۇBUZf>fPj$fGUAS06YT+ڱP]{V5k~Qݳ$&luM#BoOK}_zc)uhgO$`0\PBsA|>A h-j7Ġ hgaa *$3U$ֹG23Hrɰ8)q k88QQbx^D $bR6 !y­!k; ɨl{p/-8r$[pR4 ؐB ^na.b}w@^RA5p1­-ZƑ$"[VWEXۅbPu;Ukh!msK7$*o:1"8]Uhl>Dt͜]hDQ1-иI 656hDoP6y(g+HCl/$"PN@5%cbĒ<@MeD`rTΪb2-_'70K) Hس*?ggC4d1H_4o`W3PG(HGXAj@]1%@ո"f)E]]1U< "FQE,u7 h"Jnu iZ 5 ŋU"ZNb=6eDZ6GViNuKr-5XT\}p 4k+hg?3P E|ˁP-PhtV.@$8*q.@"VVN` Q.@"V To'p5vPCrQ~w nAl\!4\ YP@MzVW0Ѣ[@-5ٺUKi%_M\Pe:_GQCh΍sO D#([Ѿ0;"@C|Gَ7&W H-L 1bɇFq6M+ЙhFĆ J'`Π\lJde J8@Fve,2@p-Vv$uf;b=!i Y#j$FGP'9h@+`g#Ȇ̡V3A9,{q#]n̵;413и1V@@"'=$wz3wc܁BEfaZ+͵PL}]vWzA Ԏ\Ptl@TS+M=ҿKn[%<\k]l!ɶtC_HC^UMbD@ W_,@ֈza{[=bzt)nѡܢ߹ .m=` \Xp!ډ^!E3lXN9QÈӠ+H0hκl }7@NVMxvd9F G gVg0F80F80J8pzapad@7dD'#8=&BW2¶eP¾:1n^:>@%܂{$hsѫcQ~Tt=*@ףSRNL=q⤀mh+g><~xM`w49̈irV m<Rz[5wqUBfO3pĭgkⵡ\2㤛89e69qnvw~F\}[ u⭚M@wV <wr̟|vg(!(Ax ~Cm<!OR_Rʉ,&qx /%3DBo@H2^*Sx/2aό^¼_"e_*e뉒$.]gi !0܁BtCCvZ]v4[]UD@]BPDHx^а](5Ar6 x!Q,-kzҐBdmFm%DZʲΙR(hKj4O&%",RVB7K`eAҼ % uenG91c5!&]N@y$]8wW-(]dcWxP0m'L,Hm~IХ-.>;@؎ez^6}6>Tգp+Pe X x44倬)9씝;!SǪ묉17=yg375}^͕՟<$GۛUbs{]Jtov$ _{z^lvR7041qg5#2 @t"}fnTWEzQ taS^.,+Ѕ^}@+Ѕw ta_]X|x@?+Ѕc taqG]X|@]W ˖+Ѕe?-1-7Oڍ}'Ytm(bm A.id$AE 4NsSk$fvFӠףy"J/] M|ڲ|-fh%l1Do-n-1?!s(`RC[PC"Sq{#_4GKҳ7tĤUǎׇx7R8Dqy9a,$^J{/#2!'2)9U~$|1! # +h.4vC WPCS^x+܀4cqC '@o^8z#="0 $ L (g`G 5 "Nzbr߃q9/ߏ[J?ǒ /M0£^baG,pa^%)̟uf l\'2X%CȝU"]ʷEح21f"aAEtGtWفbݸyFw_*v^.erw>-}Z@ݧlQie{pH+n'uzCSH.\dՌ4?!gR8զAGCv#n [ h1yiY1z̗c&sl}c D}T~%&ǃQ GIȤXW*[v`A ZF"i: |@C[5pZѺIkΖg``4`풔)5]y; 4VbGψ=#PGbOroyu\\#g@bmz8"@d1yv@:ce$f|[ lzC4ݤMt,u|a%"+M9BJ-E bu+D`9f1XIrLlcxk]ȱ    1Z-<[ӗ-HQCQXgG4X-[ɻ>f1U:r˘FC0. +W-i 7 EL|!o,Y,jGW#EXΠݪ8QYԢEaZT_$RG7፥t}'2\D8xV~5[~uu6@f˹@"PR% z KVd  gk1z5HB\Ha&S3 hvY/38SvTبK"K\%}> *lg2[![d![$-d%?y⋭ݕGQYu-vnmՀg󔛺O]vjx1wI=1~,aɳC¾mqZmr%x@х(vt,Xe}*2. #߮r+'N4u<-_kU/çSSRܰݻl{W.6T(jJo{W&VYH1 /1 U%ggAl":f鷍 7ܡo#%l:ZwJ}MV/5J7͟>O}?qƋO[?L?^]?O|s7/Gk>[ۻ|ws/ ߼|/?Ws_{?_{ws?~7? u?ywi?/W'?[kJ]RIΚb2>ydş_S'# \m ɍOmJ?-ePn4߫G[/'_PKc'.6k blackmap.zip]=-WQ# 6V rQ={YE0" (x!RgB,-TLg)baZg5眛˛!=s}>k/|ck/{`|r_|/W))=B`;@o^`d[fP @Vi6l鉯6I1@ T $@u,b ڎ@UHdLζNu6C (&@씨L\pdT&.*2QŴ@&dT\!VIaYjuɀ@%lbÎf&6쒯uSp&b'XI'O&I U&rǀhg3ʬEA;Y;w =E`ţ@' @[K}7XeY'݁;H0׷tO|_,)=5SD f_TR1SDRQZYK&~VCk55&S+TfI?^8#b~M=o)Am1%hͦfZM5~nvɦEvFvZ*@TzZM9%js/al"a}*|rF-h*650|7h2aM\]Scc6w2NoA !HA⬉TwE77սy]Bӂ6P`Nx0Ǡ[tfT5ftǶ 40=nѴ =p{ ڧW[\< BϨ =[&"5n]eά::UCh@rԷ^f26~\ꧠK%V5'-*O_,)>ձt/IplWm#bpK5] TOv'luA\!슻Zn4A|Qɶ\DN2b> nQTя:OouRR)UsMVNKFֲwNhJCI:4fa! a:$ʩb0qæHpUU]UM ~,Ǭd\87p7Sn~W?͇/t=lt?9a#$mV؄yaTOهl en ZQTfv /{quRHqTjeŲ" (n7 otY g!#EmY%풕vIadq]rbD.qj!pd*9.IXaaƚW*ms`H"#ec{ :pnF dĞ98'zLSS(檈-X=-ᴂY{H[˄ b0ߐUg|CS/QD qgo|SZ<`JbP~ӥӉ'֕Q $% !Ѩ &4qap}eĹ|427L|XX#qY27H-V=Ҍ,Ş,PgޏOwO[~vSB*+'# P4n7v ::8eL  1<c C>p"aT` `Qt͠LΊS9Lũ* nlYqYl.y5 'm:- ES%̌V״[oU=9:S( >sU3/j2c-s#X{qPvX'iHmTXޛ8!s<;3 iI(U`qY=gJ✃pYڜ9F2' ρ&$LU>Mr\+lIoaysMy!Fe׳-L;76&Eڙ3+`=y0"P2o٧ #s-hHz]4ImCBݙa!-ʖNDFwTw8L`U0j!B!XT! 4fsV/iP PΈWq&pQv ߄{bk9o<08av* Oq1fMk)B`z4&P;VhBKor'saRU7*tʼnT$WAKwCXek޹1zdVH!wc˵rcW'T\M;QD^.APDA60Cقh_8I5RU_ ]* sLܝrȉ Z-;K`xjxL0h܋U<-f 2=A (ƹB5-Xw1qġwp| F[iu/CdJº9S\5n[EEJfWAݳ,N/vՑ0 Ċב)ӡ sF kĉz`f9Ӿ 9{-!ݒ(W]ωg݌P=QxI0 YuzfuNvC73-dY!'ݔ2in'afWW0K:<$7Hj7zȰֻ㌏O+ܵN`/B&[05'xd5OSz7|SZ4{3pV3˲'"Kg}d"]+G}T/7-1}\ ;*N= )X2n=HfcnJhg݌4hu(T]"nt{0Gc =ZO;&`<}, r"j%QbNgt]dRí5fP+'i&&5E3N˚)]Pb|FyM;?3&1*2Vw,%^20r-!(yҴG恾}m}'ɴqB%qBw4h`FR(¥ ґy>nn_ҳ?yo?]cxJ!{ۋDhUDmt7}'@,dCUM2bX~O`W, /? 0~ӒGIR$N*ww6 j*ڃErD.s}P6u9vg\;]w (>򁨋c*xW z`ܙ"Ghnp7=cP2^{vD/s \ 'Nmlv@|c7' y,$Voө9A\ `Y")>lGucmj{Dexs 6ǬǝYk>ni9k){Jw9p7p7haõ`i*7]L_OUaF̗2w<^`:`:Y=㵇\ZyM%N97QhlR@ (buP鍛ܷy4p+s<.3C'sJh^k-<'$TŎ0.5er@.\ q2j?ԼAu·܍ KRy$azM*ZRh圹9g*08yGvV[>3Q/y />7w^z޸۟;/b/Q*Ɲ)>Pw+w^؍;;/y/^xO̽{6PK'7)"g*c jewelmap.zip]5IU FWneENWWWH&4DMtd cc4&$0č +V7. cʅ|3<ֽU9uxs/<} =G>'/Fg^)~O-KZzeiT4 vP ;4att3t)a:+vP ;Avat@)a: "! HD/A:4 '@$,VXF\)D (/e@؀ˆ$3>6Ɯ2YK{Pick _hƀf]WQƥnK[c6ڬCoˉ/kqiO.Re\P5긴ѱ_hF_~ie6.me\n|YKeq=ӡzlc뫐mn jg[!93Xwz,pmr7k *E3|$m8:&w|Pс~4Px8jxFۼ>Fzb(%:t ͇jBFx<(7 D7ѦΨ2ycaT翌UƆT` 5-aA㨳m<7Vj`1t?<(9Pb̈ff&&$R1^XbMm-'Ser2=-HҕS`荱rA'U+GA]Fk@ @FA++", |iZM.=EGFT4Hbrsp#:IGE臱A|p> )I&ӹTSdī*kE5AIT-:$#kQr%&&\ rFac4DB Qw~Xxn#ܸԘ~Ą"Lċ6weVRij5qoe{4ZM6j >#̴ӡ!J u w[,N B;%sQ pazE?Z(e , Ɠ3G%0;a\hљ}(\?¼<96YLff2 %0ŮNS~3Z H0W ,n2#&%nFJ2֕ɌN#j[Q7z^o~{Ho$'Az3[i` 29s릢Sg#0ޮU0bi9ɼL9!؜ތU:QVpA7\z$i(W>]3nc>ѽTj&E];WK$wK5:P "e~h8l(ՆNL%ay׷/@1`S(80ml '^Qs =]f\uZf0s5P2qMa0i` LT8n2X6LFWp[ tME $54\ɕ""7NٌXNWN5T_b[VKk8 q}TYl&CQѮ=4kY "B\Աb,ĤV=VS'D!i,aKTisVw!!e>̉(`,hpcC-&b40&ܴѠazpvH^iu]VFۜφ>x3%6mޠۮ:}6pneTc"t 1O7kO5W KXHC$†_E"F3d4eB dc$WT!B4L!L.9 *[lgZJ_7/Ʒ|wdlJlQC:<.:oфuY}psTwcM㛅q4UkN\Apl\{s7L\H`e+Mu6Occ%t)-FFf0Љp ]oUȐv\ԖtX.kpLSd[xwD.X^G1hd)νFig000jOiAN[huXvb̬ 2JndQSN\[E>/ 5֨ 1_ `o=aalaa>ak1.j kUmic~R[1%ӝwM˰x5Xn\yܭ`bG9^@[nzQXUOXin3n=s׽gJ¤z %V="[[S$fjp>vء"MոrL FFf` `Va+|J5 V<`6 a-p'#V&cjᨆՒ^ҧ,46~/[xO-:'4!`VTe<&ъ[(YDk 6޻V!eT5?+¢š( Zaի@Zv*YS+ȹhg00000SAN[huX{!D5mSO=(Q@0xfE48)`ln~vW{oo$jNJl!uAc>^^|;?Zߘy^hcyYǟzߘ󾬭Ɍ%|KQ*ޖR̵oL!-}q[[v =@9fs3`1`ߺ_XB]ly@Ύ<}[mK@rxdrYiנ%q7 ķs@oisƀ({?MңvЍ#5ƞK2H*1!t]LgGeku;{^j_>Nn[i܀Z'Xa1=V9|?n_޿^@'zV鮛x.%~iYC`9p7}P} *A= }̞}0 9O@LL'7w _lk=BGq~0Bhoaf,!U5ku0Dq!Y- 40ب1|L0c {0g? ;0a3 t*?C$U|d۪`ڮ&(7qT'ao=Tyi4m-C}fݴs`;Nw3o] 3_I` c_;α|s>5OaQp)L$5.}jB-K.r5>v71;27d}jLLI%WkOSJg%Wkdմ[r.~ 7·999999Ca}mﻭ6owmNeڇf?c*Sȇ>U}}ٛ;vM}]9fa7Ӷ^rXY^lUǽ:C;{{_J aX{ dfgjԫ˗~w]cPJ jpV8jV͌o2&{";$[&{rov^]d"{t]d"{mR͋.UVO>&+Y]hJxYel['YՖ ث%Nъ *FA+wY44nokP/3eY]ߥ$ߎ-1 $0Lj8&Ma4v~PK3äj(B083L,$yI|L|b ǪIB1380@2}MNma"$zG|bSC0FtHt戂h~clPU7I_a f5QfցFP @"(3 z?c\q7S+51< ̾r;N 󿏏۸*~vʨ4?m5@}o}j7#C % 'VXA%*Et(f#h@XգؤAD,ڈ\u~nYb^dd.;R|'Q^p5k11*/;_q'Srp7,ě[E–pSMiҾ7>HVaQLkԪmtd#-j͠"'k OmsvU'Lˌ ;bY3Ú cy% ;#4gR1+۷rjm/ѧo?gܸ^{嗓lܳ$ +{d%, rY.Q}Xk0[erY.YƒX.1'erY.aX1XlfIe]zY]:] 0 eazY%]\Zd,Y/LKMWh!VΪ[ur, m]ł,|,e/(4hjf(R6PnݭM l^Yҍl߱⋖k7)45E$'YöRѪ3r&:X7]ufjְ}PZ“4/J-Z/QRMj H3ju tqG&@i6l$+ޒH%pšfx)X@>۵hiai&,m҂E rVæ}Ӂ{Z`łƕ V=^ !#ζ>^h faUMUФ\-5[5W3 +mjZ CwDlJYuW3RV}7͒ZW7ZK=]KӬݫ5xi/&kD9 줗8C/^=|=\W-zIK (V֭i%VGȵ5me5eMtڰ$HaIڜ $1sy fL\JXYȅJ"`)a)#(6ɲqY=`땠`0(lYSPn)oXJsFyP UXIJ=@' S6]p:AvoV,q-' K6 I-C֠ 6-& $jiIu6[ȪIK}IkABkTK'D$Po ʟ\/myr,'Ϭ`mqӰ9Y$/plL34L34L34L34LnkWmR@´@"Òraq)pڎ;P [J'K`K.בW)6F:y gzy Y8u&YatyZ>3}貵^=s}@YALq:\3CeWyqgQkUZ;ǟdm5j.ZWnCe*a)u)gf%L6c? k޽p%eoMjZ;YHsbha[7^ѸnZN^y ЫmLoXߦa6͑ QVw zHTV\6+I*VN%O݃kgpQCY`Y;U ~qD$nt.-%{%LjX5̧;᭜FgG;*:5T {c.V28AuԴLoX -33MZB/vS6L6=e4i-!5t:jwvSӶշ7*+{ǵW8C\d^.3fDuz_ۛ,1zIϽ擲vA.Vؑ9Z4{MBU xxц'4=h))b)9"ڐN%@]Po&tm `j)b0P Dž@2)`Et}8,Wiu!.$\><.&Z27];Lbja Č\ڊx&3fTNNh<@ @$"!/[xO-:'t+XU@s !שtrTHKӸ_){X(! o%K'R)- az!x\_v<y vXO ' NggM B' 8ф-X>H8P1뚨 Z6\ ]Ev}r ͆P`=.>Ȼgkw ,^O#Dq#@FR5PZAx}2 Lo͎&גkϲS\4X"xPa*6 Z;"c, nSUxUf; )c(оX6$u@S;,ݟ SJO{Q73L^בQ͘8K 7 o[뽎.ZhwtW^׌*jFeieJSDX;oR엂ӂqv46]xÍJ̴ vlt@DDz5tm{!q ݝ;z8˥c[0YnXݤ4 Qf,Bf0 %o\v (,DL* c֩7,,wZtXMWAO&P ]c @И7(֨e2ڏv6\3M$/ R%͊#E inJC-f/ʞHʞ`5fg;\`l0_u*>ʞl@‹k[z4,X~0sr^#JWt'*zW=vzh9iں့2F ~-o'b+} =G>-"_;ӯ|O}˯>;S?޿yW}ǟo~4=yg{On7|ؓ/'?r(My<};;=p>Yq9~  )o' 'b9ð'=擿X<6nY| g?~)C3|F??8~;ɻ6Z PK'.b@  midtones.zip{~_vܦ*M$K/{>h.JHHqqhf&'5QZJ#T$xhE!$Xmz4Q *ƦJ ={Y9(a>/k˳ g3[~Gw3u`?_,K?%7 X 6Az7zCn gA.I z7Moޠ AIIܠ ĢXtb_.\v\M>7et.vX_f2?̩e\We\Ve]Ve^Ve]_Ve/\vɢ7X539?nGg/A<0cg#3>???cQ?\ ??FϏXuXeXi_p( qA˿ă^ry#:l,̧O7A2:qMF2Cq.3vɜ&:6Ve-ƖxYC꽮$+nO5KƄh|2v'(qK`Cժ=;t 8a1a7N2ŦpA?$?lu;X΃bL=ڎ1-L4>_&:d38G\c-vb1Cg-7n/qMix>[ק}M+wvNqцA^΂ |OEn,A)d+',eVUBx}3ٲL`Ky?MWN+~+i5+ 礝T\C3.2 4-y.`/oϠ מz  3olPyT]7XUoPUo 6A4A XjvI]h8Z1f ;k3Vf:&fnEihzB*(8o] OL_ A\Ҙ>@:f8>Rx8P.ŷ'dw4"b*9Ow]A|q F4@ x6^3~_rc?AmtR4 "eί+w3|J]ϯJ%cm[cYmy .`Lv M ;̳lPTb6ao JWMM8Ns#in:c!Uŝ%@+?@CϠǺ\q>3yCqx9:dڷW\!5M/cg@ǻ+O8]ɛq-7MP @EYt\W3$ao06S,zQUH(1P]ry@62.`CHǵ}3k!q^ ;KR VUL$/v6@0ȁQG:ϟGfsJJoyJjn%W gq|+|N0!+,wUA LPsu`~1 OgF];qL+X _P}Vk4,k\kh[Rx*+ie`H5Zu&ٙ/u1U.gF|LϏ(Uss$bt-"z e.a@ )]A+SñV.:&xkp7)VH?XDK2“e Nyj^Kz\&x(Ak-`wx@Pm[SZQQPBqooI ]C/-=8uq$m&0 {R/4cEܑŇʕi؆5~̶k<`r̪}nilD:`AKX4+I6wGcaJn*}_.ct{ApDi'%pGQ&@0<@. x7ZTeԤ*IPbX E-+H㛺&7[^[=XeΜ$Ģ\*10ġ\"_YXVX烚1eG@Ura`)@NIAU 7φEoPEo VATAlzMoMo` fĬubA,:E ĢXtbA,:E Ģx]o8B{ˀ\:fS%Zbs]b(fΨf$Xʂeu%X;U"ZS0#98:֦ *`+\O;?VtG,ʏ.>F[^[^^pG[_%;Օ̧oE4PFNэ@ GU?Ʋ5Mo]?뭻^և\@Y4BVzi7*VD݊h;7EߴN=s+gnEL NѬ:c@v 6Mgv ݊u3+{;(a]eS&hSmpW ܸQ; 01ѝvݼ nÍdr%s z9nLt$x/UwȪ;Cԁ <69pAp⊃8Ⴋq+An|x(Z8h, oA@`zVaT)uK-%N /^:mn gxp)nK&wP& qpMNCm0FGMo]?뭻^և\G&f}\cY4f}ӼMi7Mi7-%Mi7-BBKB[4{\Wy޷&ʔO; #Sg8l7KNJgV|GG?N+>}40n..ܾKFyL۠w!IFMBp/M8Am¼oB/A [kHBrK4=Bs3&ƒ$Y(KP FS>"JnJPv}ı;HI$Up)İ "{K3$_2Ӑ;*zW(BD62%K@rg! qL.Lǘ*36m FO/$r+ KEhǕS"#.ڣ|Q-c퓬{SR`I5a >%*[noNLk!?Kj 7%j5US/iL7j*%}Ɇ$vߧ^2/yjLC闟ʯٞ ^ғՔh5]# 0Rq!&54l K}0fRD+/ 6UE 4`a^0bĀYW@"9_6d+̂B8NCϳCO:ȴ\kyKm,Y% W> =Ӕ'\9,!!TUFԄ`c4i|9:&gU>_~I4I)9ghveݜn%'gQO΢u6xt, DɮNySʬkv-?CYz. RUҢ֥0ZzVUqkvUݬq?XjI.-uVfK9 "T6rz?U "A (UK]kI+dܥsIˬi+Rnr0ݺzU#DY' ,w8 hrT|WKP4Y:O,@yQa/xQ*w M@Ie.`- k(;ajCA^ݘTEA- Mm~%&WT@]'}Oi宠&UAJ3`pE[UAVM=݂ 8)) +@K+셙_ P4~i(?P6T_SEɹP2 tђByMTnA} BE՟+ Յ.`U]tQB1zMTPA} m?.ZͻgI Th}?A"J'DuJktDҕSGƓ)4܋ąPe Oe>R'p/>c/t 5E%ݗJKP:ˢ\`gS X5Aڙ7=M_;sz,;^dՀ))UJAX@J3`UG!?'@=qqjEmm;RcRSO *RM(\uZ r pl/K.(h^ iQ4 ]@ {QK uHe(^ժ^USLB ^5"~TO?YAUZ2=%'6 <[6Ctk=}I} 3 ʹEh{fUk•q=DjصOs92 (ɋ;yWd²^T1A, `Q7wE\@A`o~7 (jGNۂl<}?c3x~0ձ}9uR*p8Ʋnc96XnRO7Z#~wR rxѭqjr^0xRZ}%ہd|ɻ;l͈$bK._χ 4٧N< Â]C'6cŦ>1mysDMiy*"L{cýb`ƒI fp+nK >w|o E0m}c/nw=oƄ 7tyN:|Q5|}\r>6Kh|9my>9Hc>gnuc p~ kOis.!ƿvK\'td{|SNxϞڇׯvNٓ\n󷃚O;{4]S K+w :T?7}៳qÿß76?ǵܻ y$ß҇?ݯ8go,N}$P'6Sp5߹$74wO}L1NdM'z=8kw8Sk\~ sןBe,aWuwmles&P9'mlN1<$9ciuWƄ|d˩pL?Hc")=k~Ô>Xd?8a]r'>~\@6RQ3Te]'~^Lsr)C,M9л{ ?%ϵ*!`6[ *לc^j]xn8Va1%89\nΧ=9LYk|(5qgxɅ=`XٷwrSH,ا>b6:أgFd-yr|8BNea bd:eO`NwG$N]**flɸi_ǡR|alc} 2p#iK=59`;Lk|ㄷ7%~ǏƓ~O?0w3+OfٸmhY=h, IέUTĞBlmp/5"y).E*0Ƙuc cTӖ8/ͤ:@Oyw4*'\ ,4(>㛔Dhi~HYQ^ h0$Qd)a4;SܺӚ=Z߸K?%u|C#8ʆy8ŕ#ev?bc7YYjHStBpaoXs~|x0&7 <Vס2Dxs홒>X_Y!+UTDtEBp?kS{d3lwkdulk<*wsQijt {*'YT:LpZ\yDQܼm>2Vs \׌ u&\a]oUS0+ JBI|} ZGc0;N1&.N{l-UqfFq* 4q.izאdơ 49g~!2q* L^/v|]DZKKgM^ SأD:j9kvrƉ;%g=fv/8y^\VC9t>c 61/^3~:BWW&bw sL|A5!^t1i)d.[LAKŤ'15 n[sAn1wŌ)Q\Մ-b{>ZYgwх:qG]$YXckK9&F|.LeBĦ-fdaBr<2sL/-i+GmL8߷!wgɣl8 Wmy;\͜* mN*f wcfPp_AKMT=22`L,MMPG<>DTfM!,a<=LBG-ؤs7|0fuyj/6Ůᨏ_fA} m86@1ST Z_SBWΓ.vF}!FXk˟ xU!fRc5bc+9u NS쫛S96;9Ch?q@6W(1sQNuuVGwS?\=庙uh5 'kKM?xĞS{Tv׷P`znΰn}zǑqF Kh [ s7(uD9ϛnj`eD17j9A0CN[/6nqfoFZ}T3=ܔ3 |ao7>j=x^z[@ƄԐCaoh-D&XFui.'}ZV0lKj~~<>9Xs΁?'dNR۹)Qa̳;ɍ}bshFVN) X0b6NIڰNi aC>t `d1p7Ŷ\Wڼ 4bMq`Đ" rkܞPk8G޷4+et. oc."+ۮΡs:H M1wŜٟ̲i; 7d)_WtMu k!V6߬dfeF\A)Dيͯ}* RoK~ >RG`3Qܔ};hQh#27־y`lC }wQsNjh> cčacnD}퍮iRw =S39N431'tSikRWl;3Y#%C pm-g$_3zLǘw,|5\lM/cp59sTS6qNڝS֖8{y,r1/+q-TP]Du].::o҇׊d'|]PuDQE5s*S#Z\6 T?򡿷|}~OW7w ~䞯8.76iC@0blV %ۗj![f#C0f2‡h Os#|8rvXӀ)(x$aE1\+hU cW7Oz,Ո!&-=xQ0WvPg<s.P-sxkdG.`8`vA.k8)sU8f!z1wYlKX {E "I&\-u:O̠f^cZWƻvs+p~fVyZ}\|1aAwS(`XfGwQ!6=|M3psRxBx`p5e~q2;6"4$A_-x_j* ms $Kqnב-;i^17mz%~3j?6}P\],n WC-lН:w|lG,l3ac8I 2W `@wZT:r^P57c uaqjcvц7lg2N)Të";V()nsu8hkx{&gT0S"ElxRv) tLp?,a.b[ sɚRa9' *rL~q0ߴL)6Za+)`w>M\qIv=d g3U k :Ca&R'cCxʸ9VyNag@TͷliRΗ '[^dL -o6]6]"n&'b3-0l5eOYV9H*f2!h̀z`4Sy-YnF79hb P-b/l꾏&|N qaywS1R.a C5ғY>t6 c^vO*+Cqw y I RLe'W~}sygPYm(˗<_bTjѰ<{kpD4wh113ʲ>c7Zv_C:P-2$;J~WWl(W<*"lMxfTl݂[p[Pnz K0M"o>muqN1<_tL'sG8$g 0<YpZjQ];-V&VXzݘO(xЩ꿂e7tb^QԹ񕗎.kbw> ];n Scڂvi/&6dWlZ[B@De 꼁3" 'Yƿ_ v/96wevnOʸ~p74O$䕴6̜Ԡ/!MM1 NʳQi.I:"PID+/HY8#J3Nq `{l0ݒ4N˲bgS|k0QOvү7 ._qSxk[8NEI|ryoڍKt@Z6-Kn_Km-B3 C?,䆐؜go{ y $J#܈K&Ea$7|0ku7EGyO>wg8QG>'%n2z3NZ2\G W|2w έD?ιp(.a,nL闐G$T3%&Ǫq3(c|Js6xa;cHQb~|.V7smf:-¶^)kC@dҰj0ln mj-J@ճ|QҨ*U 6:Wu%[_Q&M'z3-s[Bj]G=eYJJCw['3#,!ƌݽ0TM]tp&S6jb7}'oH <`\h"+HEnwe]z;cY.zu@'K4(4 Ҙp0i@cj4(Y B,B) V6T)pw/-Bs2R>@h:Cy*vǿW|}?٘w9woS[y쁏-OLW}ˎ-0O!skOJS"jx<&c,Շ v[О@nsv;p%ߴjl;ʫ7R]k4pOc\|>=%6^]q^jc_Y{?+K|˜=_Zm)+L `ø_Rv@J}^`4"X^JE~,+N`|~.=tTN6xsuv[2:cC7XM5b ·5q=-qW(Έ~I0e3p&X13[yH4QoNf<-7KaEx.#| 3vJz-ʛrNewk٬sg18lw;4ꖦ _YHꪰv?Ra;jџ@;{Mw%TE_ap5 ٚr=j{lvknar-M\[7jڸ; hZYQ 7|~j<[G@fiyR~< `ZoPSQOgX(hћ1?clUw\PQ7s9|-wAND~B w>=gB8!FW[5 J '9sǓM, cqْ睚: sА8<:)j{nW:/2i[cYLnvVQYt %7Y\+mՔc-c~A[k%=\ > ™ӗFYA6:p-!X稚~υ[$Ew2ԋաp8 1 Kc03fnC;F`hVOܰ7nK @` 1o^4iVժ-XM,٫z=i!xEhJ}do35<-w0{ٌt3iVuYūBq9m7P`bqj 9 Ƶvnjc-v2UbbMFN7n.٣2z6HgK\NUW2D-}m[[sSMYkދ]!6~V{,nNteϰ6Dpw2feu 9*ehn`nf .v΁7KFQYko[P>s_Xdg4gZ!$ ?}k_Nk!ĎB<) PA~&&s!`X 2'@;RPhT.IJD$xԋ٤zF_h k9u VA7nl~.N]:[zS 4hOУ[l\*]cÅ^hM^j$;R<wP)B'h}lj.GRgzo% 1%Y{aML[}}FݸAc{6Zpӣm| z"{qDo6z]ø M["ORiQXk(p5o2! *cGtJPft4G# o3FΎh&6q2GsF! ۅwѱ\4[a v/] TtE Pޔ!ѯ5LcBy/XV{QOSh xkomzԶާRg[zn@XpJ5^:P*3_˲T^_!ڤ@Yf%JXl(nH\  QSU :,^{TYHv42QQlL"-i;+ݖ)0 {W5(\T&v]ebbRzde"6 #8d`@qrk? )"(T ʔK"Br\BzƊ5PO`ׯ܀\(i.D8(OEzNXT&fYe2ɳj `)춵e.i t6thbF4vp4}t+:4 ʁ7 PLSe .[ .[CoGQиŠ5l(ŜPZ®@=Ι);݊&Vdz$]F\ѝݼ! m11zgOb :Vm΍b.f; `ef]o^6"e"ZQ]X)a~noRR ?>l)y& ;}7cwnbP_yh$ʃ}j*ط-_Zn}xڳU%G&Qkh2Ȯ+M}RpK@a¹GѸ=1+}=,`oԞEbiQ=hCGt2E7$ZVMHl4xWqM@?EM>.KeDdJ@7Zh♶]dawwsP(=!Cȶ*%W{&W{v86n~}]%W+f!h0&?][S?Ѯ3Ί*ѻ,]IEJTIfJ0$`ٮTPȣCe^C%]A%i@_CnZYE%MUlcsXT%{4Hz{ҟ'`zY;,s:ҘvKl+]fkܩɝʶ_:(s%-vN];l&޽8@*lqLEa+7F]0*rAtw\[&Sx$vz Lqbjaάհ,gPwz;t׭'M;"bgX"ƥA(lc\霣6qH$+wbK48 YXRosL)ZŢE5&Y atu{r|cV/..2N]?Ap^r|h"\@M4_g2kc<&qOQAw[kb\m?k{0:OkDhkvѦyvػ cw ŞT1*{WsSQtp. Q`1 [=^!>c~%Ik * ó++a;B]]Ö]=wEbKi|=nM[-kYd393J & H`apg*?eG4#e6b8pλÑW$~Q;FS-]끶B/)TF|V6Ɩ$~ăyPcTXjz x<~qpy9v8b@Cx8%iLpL}}\rYHzzz",nu36lּlv֍~b= 5!tOW)"B&^IO"J}J}B}{-}0jO#$z} ';iJ`Y*п8c,E@ ")>` uxU_xJ"x:-h& PA )KJ71LdܘX"V{ŕړ ip~~ίn 0Ju,0ZL,0ZL-\R@"X$!y,IH/A% aP*Il+oDXޠ,Y"" +on9 RZ,uJbQ 0QlJJ`nf*ū(yV(:av`w4 )OXpEi0AO >]v,LNDw;U = HUIAW P@U^e2"T2$8IJI I A:r=!2<9ܕD?.^sK8Ss!íÓREıdslM%[G٨t*u!n Í8Tڊr6  N:F\$[$s›q)Gn uyotwAx'%qe кJڄWd @.[d 3epk]ݖ!CLgD!h⾪b 8Fk!a8q^ %<+3mA#ǣ^aq".'DLr"* q[L!i9:F铒/0ބiP n Į<a 6m#fu#٧_ԾfK*WmXߍU4vj([f2c0H\6R%Ç&W42Wef4IX9BV_C+aj]BR5Yԅ-`,)!<9*P=0b@z6s8K<*<ϒgIX ;&z*@$9lܦ \VMA`bUHe-҆6KKer@/H=nqMGA}i|⥿8/`-VK9(/bR:^"&bS"(Gz=$Z#Jpm. BIp3~i)}촔~y?dyJb 1,NJlְlS.'7+b<v"u@׋ޘDUty4D* 25׋N{vzp쐣$T9-12)O$ 7U'aМQUZ܀=T$92nH? xin Z|)ןqL7ď'h[κL[B ~MF\1752U$pV:f8N(gZ?cL7v  OsMo%5Ȟvb\/[]lԪ#l 46U+FkݩpofSiȝtxlRZ~&CTU:UU~MSp]iÔ|A(qMBOV*ڸ"g@vl0|c` [W4:-, iCB BfF3&ȿsp E kQG]3X~AƨZ?XxwfeX:>d07S!G1 Ec-НfS4O336OaF r1Gr2K(ݦ5)1RkR3ۓS8ڪdƺ^KP_4scG> X[ N c3ױ$ɂ\EQf'Lܛa.QX1#+fB:o&X4w(\h$/]ExBS. MMSMBO ?Ǯ d*%;os;@|ԃؕ 9Jd/8vR%ufR_ȧЬkwbpLngй^'lL鑈FsςRv  iN2$8[Y \0t 뗌𶅆AM&54t1"Gm0 4*I~,%ͧ Ki3KiGpeFFFFB;TLPtIR=UL0 )wZl|OUKd&um$B﬍0wFJƇyM 6YhRZWs{tOOWr5\^lu5V |;jf}1AójEO>:9K%<ϛaiC~Pf8fFT7YkX 5 5vQ N e9 ;0#r&@Ft,FV%x/ɕw XjK8 %١zB4DPԎGwpzÇ|G*UI,^^7q3G`ɏ*$R"()$Qu B2P+.~gw4Z }2*|왻nڽ9b򚄔FCY(K[ub0xaJ]<aAU@24T x§:,LP^+&  p@=ACԄe(aNtZwMtL,X\k#O ;h;<ܙ:O<<}xu!"$u,,T!6&HR툹3ѥ(@YI"ͬh 2| g=WWͱLsKqR賒}uЋXBҕQBR h0g>}&+ ptANT)pph i%݂8#QlI5) 6emmngM57~֗+ᄚڌ)ݳY JKG\l׵5"yzhADc@8#vqsi.c:Ls79RiH%c \rlX 0,[^sЍ$!d^0: `݁r&. G132d:I#/2&+ ҫ!=+T%di/,%.S ;raf1xl ХPRLF%Ay MGZEEe8 IH@ hɪ&)9ru]G3]ͶLnBQ@ U-Q1V ن͕.YZDLxTZH(]fvBUɚ `4lǯًXa6V$u$û$)Duqt2xp'w]Į"F4IT&9:K8rv)Ԍn i`JYm0f,p^+KAI +ȀLgc@XdihU8 {Pט%?Kv}2X٬ C:`̋]AĭH~J 1H֙QG}Q˝Ғ@#0u~n{TV L Bdp0jzNpuV+U?iVgPêgJϧXٟbeeeOKwRm{_XJ;-[5jFZL?[5hx %M?KUϒy\7DĴvIL11MSbY?&E& If p. S2 \.^aKOvzQ"*Oa{7裙\Ť6E]LC6ƇJ8G(j0EQ"ÚQ;%Gw_JIAGTljLQ&0%) P.b6q f7}VdߤETA].LǬa̠\(QOQRϤ?  9wxQ/O+=J8XFq ,Dkk}FH'"u /t:;u@2ZnHݣ pC2&IB?˕.`P+rvRJ%r@R@6T)0XI26ac覅bc0;DE.%A.%Ae kqêeP?UG,z x?؊WX,cҺAyE_mí!)H̆ᚍٗ Ѳh=Go1Ku,l̤%C(m%8 K.ta1\/cOcH`dWyc(=y_h-Qؘc<aBЙyzX?<3,%c2Y,%ӈRb 1R0oMG'u#. %LF1 "dŅ+' 9D;$dV]v*8(&& PK?G $@=tKuԥX0_!;l՘Dl TIClDR;dU0 Bp5cڙԙf/y D&ے&7bdHM .,VՕch`ܾW hc3Dl " zlMB-)2:{q)`>U/\2VOŦir@iH!=o{/,ڲ4,tKPxB6ٗ-T@ʴl q@R UyUvL< 4 R*rg+̌ܦ#^ (E,GS@t9{VFk"[@%=R珢Ey&b]?v ڰq3u Tbynjٚmt%3o0DhQDjTRDZ"sdb3! pBr_:sVJ}6 2Py03I$<.^MSuh$ȂчE1z-#/NeӴOer#F\C jȐ5\bQRWPe]DZܙ|!ӓ#4$,eDD*~ qbD8KN#UgW'`&?BAމz j+jDUG"TW(2*(?Uբ$ ӌYk(4P44(*Q HY3 .dUVf+LYy?갌N>pԕ*j?jW=i2AOև% Qҟl1yi)dyJh 'X>zY"K铓VJU 33D[X.ģ=+=''M艭鹩)IgX!yn]q.z .]e@.CuĒtu1O;hD$QUv PeX5ͼ`Ǐgg5Z_zrnI>6`߇O O<%>h <:rY4ɀ0%vɮ[u2MwIҊaa/[|A4oC=/%x˝^$?Kߙ5#ҟ`O30z"OĀ }2R5}`Bip4v#{g9R;eZ=EyP+HG "HOB  ?vwE!׀-DEn{^5 <%P4ijHњ09Mx+QFҽGf$9\=2-'!tCoNpHS?>& wAC]$!2[bFMd[a*OC_ҭgāBWSv=`^sU٨Vz^e-?9|kmc/wJVjBIW]U݋uA oS[L8_te[S:=ԯz+?2TPS9϶Z9Ri)dyJ)J͈*vdiT=Dhz@g͝A]GL%]rNۤ\d˦[2pXF{{ .b9bEr>Ëx1PmT.I(3cն@)5{-`&rs8NYR3s1Gl=ڬUNZB}?rTZԮJWj"gcCAԤ pn 5%Q$i`ݹ+p.1^Y{޺˗txx›%㵓 E*3䬅ԎdEͳpG/uYȳkmRg=p1hܚf{4_pW;;q7 2M,sfnnstsg͏($ŭYմDfVA<>K;.C6CRpt" olJgCv.EdS#CE*KݗKmaqQ"w a4!rEptt& E'm8Rdwn)qY E%$|fz?Otpn2Wͺ=5hݘ;9B2ak'vS(*HDul'%uZ=a ̦ @ QpmҬpT):TS4YJ,`~c~u^l]a%Ⱥ-=kt.T&U̡XL3#+VhOiFMQ9GXTGeSwU0 M .\eo373Eh Jj[9#U{f'B # ٣-W"L| ^fl6/BFNe2h2[dg2P(I lr@??HÙf!IsP6O`ktmbVZq=MTBTaH=7dW8zz8[9IV>TfUI6FIRXyTawecA\-_#$a$E܋InˣQB80/.LnGsRu"兎6"tQL k+r jBN"WF1ّSfޡUE|oinC_I9҃6{3d ?ZdxqLD=v1,#eyzq^ZDS-]SI׳7VOZ23 UNd;Sي7kieP4I|y~%k'Ъi6UvxТ( m>h&ϴ>BZJ}Ͽo| :uc1iQqLc։>uѧ.:)J)E%}ނ~([@;d@/m;[@Oނ~r >[K,ʺSuin/ɞZÛuܮtK7-Jc^(']傔0rS>I[j0*ڻ =Fl T]@. 7(z7>TTAT7MoMo vAtAzCnfV 7:Y1 fĬ .iV &[GBA:@zdx&؄stP 7hU*GqѢ#,T6)nR:Gh`梘(B}W h` Yf꽵Q :J-Z|&J,UO3 ?uJ{K Pքp/<_ZZf,1Ywor诶^3Ԅ7rV6;kS' vh3J-gflMC{mȖ[po[ЯeT^[fqz+j0[9Nփ}oq; Gk"'`d"`~K'd3]Zڻk2ƭ%|9݂{܂{ނ[Br%]`[ɺ& E}Z/[Zn޺ݴ [kjS_nz6:=u׻ȭgS,Vr묓u@'+de+:YY'uN[det7ɺu@'3r:YE'uN[d+ɺ}ɺ½˧eφPzK@;͢@}OW[Цfu5wP=;@ڲr $/ z&A>;PA545_>rH˱;.;PAk5Pu;vZzUҷ(r $A Ҫ 8.xx[Ű\nAJU,+w`U pKPoAky;5Q[A}B_{_-h=݂v߁hoJJ "m_VF/aXEu'B- ~4з3= 7ؔoi9og[ok֙'dvz;{jJ7|ӻ7M[>-J/w}$MCECWP%VT_{ZrwFx8"]aVҿb$V.@- z>$88'BZgg!-8f%r4d~o }p:85ih'?Od-A)jz"`$`4^;$O]T Ar @!gDnPrBWwӗMrOwݛ~7 ޠ\Q?/c.2s:>R/@o^ &"X+W"OVDPXF|s S:w R:lTEdMvcc* ȷ<.0͕`' |t:k;@)RW"K(ۣ|ǚ6Do |*]x؟I1i4`dF]zlnvGN;rv{#ܒתK2s؃mi`#_Ɓ+^gC:8IsZ"JN}{nL͡+zXxso(l |@%yJs,ݵͮwKw kt^g/}_2uk2@)p\ ~3â*+ #&\RrŒPu.MϢDs r J"P*b#3Y 搴9~!J֖pIޒHI.8)lH?hQp{.==?G lyà߁]'†zoήpKA*lbolmv%]6JzO+i"s!ˠfo2ϣ(et_,K]ʬ ͂lgd}_57Zi%@_.\vɘvyjC(h]YXdUfYϪ*)>5=H TYV|z/kz/.UJ%~-x)w-R"Sm;_fUK׾UWg  ]Ή aY PsT1@7g\\[fҼ .]\:^AD wDl;nP8鯝>}'l] o26Κ}n9JyŧXVg%ʊ+GѤe|.L5jq܂V[P;vނV`L7vA^ނV`/Է@ :e|T2N%*pDh"ʳdBDP~tH8"3YE{%D&m$qWVfJzdD%د@.W._t)wy4k_2*\]Nl+ j7˄z LR)/,d)y3G=ʤ:J,]sKUȿ4\1#D0ٰЭPb{q/Z=IŽHE?t<0nlʐ؍IyVs0*OFt.zUFw#Ģ&w7USEKݰGtɎ J햤~$v[/QumU:+FY $FM廡!`WP.!Ey+o1:EG4SX)&=:glknFeZWUTcٞ`cY&]Urf'X;O46쬽Ic&uڸNd֍~@*ڷ1B<^QIWe.͔J}g%~iG;ؗ?IU쒢?S4a\xI V&t;;ҳ7@= y.lM > (tlXPOTwގzSapa;3w0u&{ٯbo>#ic VOI XS< 1T,^'(+7CS9uMc6T2W# #y2mf5&o1L#M s3e-wܪ\iur4f562ϊF4BYP#"p=!yڕ@HD?@t33j?kr&(p3@ewcٰ(\ ފ|(ԤXKRϽF]eBew69t0H,c:)IvvD_;C?`i)Rzs׽vRyg/t3`_^*KkP * $⼂#w] #`׀+Hw`Gd}D>$y *7$]:u=}jo @i ͦ ԗ 00<[\ANoq"Zt@MPA}"oeg$fW߼F;0an>:^ %pHQ~Nr&W)RHO_A0Q_0lޣZ]BUYmƋ8:3QBo .7x #< }.o2 %,htm .c14z}v^C`n]cd\C(zq1NO$O1K46q.SZTPժdxKbD$,g+aitR\B.g #W#BUcDB#)5"m&ڬ0Q  z0YI|Ӗf .Zֻvwgox }6l[e^ڑ>)p&Pg𞡍ٿ1F} mQh#\CSס[ m|B]Bj6y} mԇ8GJ0B;{81fwgH %q6zA h<6ٴӭDo"3pPwC`I Anxx뮖O7=[J9}*C?̶Gcw;qఌ\́~|FEXJ1m(6oOԹEE70 ff(|Ʌ.uw~ۢlM{\۾(ej|)}FΰJ#T?PfyjyXDQ|T:?יۛeZuEQ,2zՄ!W~YPwEu80Eǒ'G[W LO'mMG ~2Onci7Wk骪Q觶mt۔e꧎O9:r>?Rzi)}RzQ%\= ]LR?WL?Vww|>AWe^_߮ZG^_K?Ϯjo7~\[Ϋ~_}~#Gㅿ l/_ W/_e>^k iE.~ɇ cߚ^_Y>Ez>;<;WO~?~ouO#{w~ߗO?ӟc߁u?靿??~گO+|_'wϼ\w|_u_?K8/?s}/i`~7|m_QuTZy|C1=? ?>o__ʧ9畟W>M+y?ʧosw__{ʧm?Kw__g?7|ZW> ,_w}WW}@z=WW/+c|/|}=?~^~W_W>緟W/OG҉ zw}_9_Z_>=!{K__9)/|Zz >58/.W7DN]:q蕯j+ğxߥ2^6ӼoTj+_*+K^?L.L~e^}f^ʷ;}OW}<yߧPK'Q0@g shortmap.zip]=vIR~/00qB#".;" :4HDC#MCL Uu]u~ߙ 40]}N>]UW}tu?+'/Wo/b]_]o|i1zkbdXLHLz^Bbku\ψ"Q\ (EB/bV@\Y.#rr DrU.&D<u c;D4AAdADׁ0szu ?D4AekaZb&?"] !LB.¬5rX,,)a&Q  <&xBJ0["*I*H{X)&ByKuݶ. 8XKLi#l_*s-TN֧9pAa˗PSVJ`T!P(5[)Ab%;Fw (AQqN%!"\C>"\"JLm{G*Z#X4כf‡Ǻql֜h6kvk^Ʋz7jp ff1Ӱ꽹 zF͚ k8Kga=sA)k^6 r><IO׃ogݞKɏ3bO}%S aO"GyD@tÞJoĞNɯŞ@{HĞ@{H|x=uS {si=9cO؃G[ؓ=G쩟=Һcؓ\=_= ؓL`O{D`x=sį4_bO{#yǞf_/_kŹٚV&hDCtwiî4D gJT2íAe}&E>bRjd.s$&QFbu;,E@BX :E{,+#,I Q3/b&EUɚJW yN2$!-x-I@:61!"J:oZgx#X2'e E&P[y ThWЎEoEYSM,.5':Ҭ`hHZnO3K&G=PDH4+8/+5 0;_|[(+6:prMPg<3 f_gh:$E䙑aYW7l1Q0:!9@|\WIM4("֙3AA5íϬ#@Y7 LUT#0ÖK#wKφd&}˽("!;͓ud vTWFhY~e:tӸrY̸ BADcz_ sBAOhCk3EL[ܚfI`snmDׁ(ZҋM^icW8ӁQ+\·J"2Zg8K2 \Tì4-zU]fpttbFkɃfT U~}E?[`!Wɯ8 hKF`]Jصe~j2L ҥ?:ãc[&BU j^ pil}L="#4ERuYt1>*HU%IL`9 vyȟx eBdwϗȞm3 K~Ꙋ]-ꠉ X$SoL]|52Y&Y** !2Z¯(t"K1- *EަJdl.јI|e3x8jS'iO( ̢`n&R ʩd*p,vq\$x[yS<" UR8t<8I9~z,e> ϠGŦ9z:rUHZ%t!oefhZh_k<x>6= ]Ӝm'iU<1j 4/DbȮs 7Ei K P,j_BYs g!}xM( 0à GO-O}[ګWtY]8Rejl=5)`? /[ٗXZ: |^QyE9 ۖM_KW kaj5PERH*lY- -ރ[QA̅)t H]:&}ϓ ⿴jPpsaP_Y:E`͑3s4 )\tHW$h+ 9sK HK/ |]*k^']X% H /`p(jXu>fpKwo׮hbђh{GEGwdlBZW/n=6gC7W"4ҌĚi~KFG5RRVP-[-H:򂩳]!`>.YjZuXeVxJ9R|Paa^[ A ytB'"YkIT%TuE\BNTTN%'aa-?z!tdE'0+cE̞f(uiϨAo*Di5+Ҝ𖗈KI2aJY\=|42HirNC䨺ܭ3M+4=0trNsBB-5;G+UT= \͒ `E3r RL̚ \5-(A>E[ h=9<|lA4PK5FhHQ᩿$Ԑh*lC 8Q_AX.QmE_`f"F$ë*Qp®"] GPn%Z.Y1UfS( 3!HLq ѲlX^iA'e+a_/;q[2з"2!5:S0":8O?Vs Np{L ALaob9P)nO˭ot!X;: lT.$i:urU0OMZIDc s-fI2wD~6b# M]!|m=3Q]M/wӔlr=ٛatMdsb~'7(? eU:؜`eE.PBcejpjCLfC|#2 [@ ѹuoxB!.Ϧ (n“d<[\s[Fw8R4jXunlcT3Fjvh8djT0~ab{OMlT+cAf#Y6qB~O'?8 ջ7Z9& pω?}'}a;uט~R,#(6*`6 Ctn O6uB6Ʀ. uQO|Mw0߄햡A:z"2R̮Ď``HD]}I|I|I%^2tjDѹ"YnY′OsɗHY6H"<мq:t+B+hd|_nz6osf6o  KTFAfsLd`]i~Iv&XxB~ϖy+;ͥ#wW11Qnnܞv{m~lQ߿_ZԺWe/;I:끨<^vࣛdKHTY& V,J0I,v΅(r*8&kz( {k=jI8x=I_nz>?ۨosٹmFos}3)slu37>A&0u:zlBEE n߼bT'3R^J$~bn'G ul-{Kc4l m'IG*)DwtB.a8]üoҁL`Ǩ͏'Kv؛}"^ҿ|_x)}cF-1IdCCG$ :cf˙`I']|u(̰H\甭+@(`dsjk mՄ/La54J(}eᢝGgud"-\=nBfV1#؉6Ki A2-p_9#. bC/'䋐_>ɹZ,)2q_Qf=ܶ1:EζOѝtu+ohJ9﹘cz[K^;'Vj"QCe}>uOTb3&zf$sv Y]{޿0!B,Jr'ȟ]6]("Ln6^om\wg5]hf'.}ɲ9& zɅ@/y:#PXYr?be[>;3@F#퐛[xӸX2T<FLO,zSyJO3:..xB( a%Jk 0^HXMLv[>6FTWCYw5J-?-74`Y.gNw+R˟|'ҐH)u':P;թPL0C䠻 I1_6XBN= iUybe\&TK/fuXgxƜNQ = XT`9!,]`(CwqU5jFDag}_ޥ!;_r'[B=GMc13] h>أj+NޱM`VT!.$ڐ^LV>su=qMLYV`ӄ- )\eY=k:a`вsL.YdPdk evêV&J%)$F R& g jPRv5BiT.0ŕu\ZYNɏˠ =_vH0OƄ` I\ ؖ .$gfQ,G0}6Yf\#Rt+cbj[P X)=Wy @nl'9]qwN2c/יּmٛkK*sGvnbk+\ }q HȣyM۹ٝ]^nMb|d * Fq*LΤpedxJ\i ^%SMU!HqC޷w>UvVx{?Ksx{WO~=߼Aoӓ}.G}K>Z*_kkO|=:_S iLvTNk6صNٖMADB)DW2(@ը׽^pӺ4I4J4KLȴMشNO"E((RiK%TQGƦ2G]SixpzZwLN랹L UNTF d䕔 lT5uGS"*1|'~'6۴aKj| _W Z*A}جn8vԛw훉Bl$JdAAT&D jv `-L^ &`"&`""(ڼA~Y.sA, E6(Axڂ|* i*he*׸QABNZva T2PQ ieP-Z9(wP~(vk>P} Lj4crVcصYoAb=>NPBP" JB-Z5o~T6j͕>ݕ1tå1긔1~nC(@Jˆ*]4B JRrMܢ\ tP:)G54&]ӵsF`vM(sBIM9I7G5ܝ6mB}ix8{kgwuww<]8n"x`͌~Z17v7b:n]9 q#QئFܟX3cH&9˸>uH >Txwtq#}ʫ(č)]qGw7p(lS@o37>o7rw7rϏq#ZQ}JX77gRlzлo^/[owg}'xϗ7qQp_7io}cy?| .O*T:Xj-yCB.mQ}"W۟tOv{R7?c%BX?h;m"V9PJNM(e٤.#-=DI]LH90FZ`xQy/U`6{Z* t$ד5LvE]#λ s7pKöpcB.]\$ p"#\x@`?nM8JrlpY=J d<ߺ]' 9w/8æ!™̻dȁ@`Rգ\` Iϗ˰J,oQ`):鰃0r#o1^ &k}Ii6l Wޛi:L&Ckk*SM$ph!>3 M 'MR4 dX,H H ζ$oPx9xH..:IA'Ųh2T}E+nBx Ϥ"yC@sk`Tl@k. tYR:yav`{{h3 fAf)?gf&dEzyOJ+]k-|퉯G+622jz"JN-geT)"@(B@(qJP jSeG9@5lyHǤyPGEXZĥE`ZDEhZĦEpZDExGG]T)3]R(JƎgܣ.xPă"t$:O;ZG9^9ʼnxLUWă" O%TOeuu fGORi CQhx&ɯ٤K5tin2te<;xVJQ <,G7BSgj_]ըwe&S#ilX?~zX GϞ%ݲ բOlq-z4ZBV. IOQRm|B7 طƛ W/|Ja}uAD r!_+`_j?-q`ëޜal-r[AcrAЇm GY_U-[ ΀QKA#e^.`N ȨFPPAb,2W;/ +ngV(t,:`xg|V8rZ,i!O,xg\P;)W;)Z=-~Z(7n+Wia|?s[e(^rL_deeZ^i9닌,ԳsY(I™9l(QԄUW fwK~,R_Yei7 WB9-LK"~Y[~7?cTn잮o٫o~Po4e-ӹڗ ӎyR_l_/\߭A |>I\/krʌ}WI'%ǭ~gI:L :/(@ M:u'|Q8; 7Afw_N~B\|~ԥ4:?&o0-۴v랙'sVP|Z fW9_p?[OWe˲i9ee][޴n~Y]X?-ڲ_kwmInYCǵ-KuLtuutG>u2Ż42ƮwnbFRF\:~FR髑 *׌KT#䇨Wr[p Άp~p,-jE-P=biYc{vZ;e|e^J|ڥ2.1 ͵KY\|wBJ\N6bo8՗B/Fo Kh}sH񿮯HU#7ejWևZ ~KM/k7kW\Ub~ӯ혘ڝC:sn#CCZ֮]Kzk"fl+)XT,J,AU=H}bi;wrQO>mdڧ6}jsn7n\w>^6OnuOm퓍#UOÕqsN}ȟ:Җm*Z#ZRZmF[jXJT.mk~׵ҲTc쮇Z(urJv>Bk56W 2kK(?*GTcY.4~[XnηFZ^~u3`תr۩>nk)0shǥ5V.ceЇ|9bq4ZeS3_uۙY'{)=JYi:[7Vzi~]W}6/&NڸR{R-J :ylήJlՕz /=U'$bG׻ Wd"Pfeت./:v_+u{h.@ϴ]V>S];ڡ]CS{kkcrk+|nCͧ2sCخڕN7bJYc=do[9ڮ.lq=ZnYwRͣuk>Vrf_asox5Ej-],Zw֯N357(_CS(_҅Usy}x׿~n_>ŧŻ-WS+~uڔ/;cV}g.5Q7ٿ+_ۥ䯻_˲h^!{0q|q>e8,eЦ7N}Q2:a5[{<ަze6h}l}b6^X3Ow\\CsJL$|,m5ۤIu4cXBCr}SZP!D3ػE_M?l?)Pf;y)O_T n5Q1[ Bru˃;Ou:1qL."wumz5-]lXHNH1X!qh?[؆6*\jCxL8S?:GB{Q~>2cнgW+s w_ەR˿2o)z|5 XnPbF\JQ.4j-wsmsGQ^~++㱹&~y{u޻ WMGA}R iQ_ Z)gdX]ٺ^zniLЉ&Ͽ[\x1ʜWik2J/̆fv+Q.4 mQbk[c/l^:%Ϩ)l]6YF!2(gPB=P@}aԉ0VsB"=ZDX+ÈnGP^G+%<0JVFvySo?2l͔ʖMjQKA0VBSF#NVsٷQϤʏPa-v9F 꼥O +Xv+Sۖn-Waz\xm}OO0ΖPj{mar͕'1eaZLT xꏶ806? 9o5DJo[$vFj$]A[l#ڦʨݍK'oCI5h?Fekm\ZBKmbceer^kn7?JǯqN1Bˈ)KtC΍-5e% !_|; #mkͬlc)ꘐ Ci3+~%1Nѯ?!.ȝXwkg zFjDž lǒjf[hclqNrr61VI=0B v[0V eVsa_3IIBKi7|2K(g+GV \At8Z! NUżfBm6aZ%%-۲o1b,uFl ϕ[W2[TvK~gi =~j0zVv}U1֩^['T92z/oHna^lNm7 鯽S[\P#k 1z^R:6c=ҏ%ݦ453>*}~g}NQ&}R60dRΜ2g50JG1A1tµGE;'^+XTo1ē辌K_eEk&*8G"9Up+oxJpһu7.10˜bލw *Oi8m8Gmp#q@v?܌q(OIvIyJę(9#)kR;GeeC2AqVs{elQyJWvʖcp|PR=rLjY^PwS*[9JIM^9G=it^9G{nSҮCM%ם#ߓs/ρSsJtONwJ-bx55B3|R:4?mrb^36yܦrr S*ӝRb4܍]yJ~ؕTQ9[7jVrTc9*#T2\$)S)#9*W S OO/krhO/ˏeuܜvrtA9G}_&<Tg/(O˅miy](XvTpHׅ0!$W28 /ױD9GkĐ<1)h8sTq)W*XfRQ"w9[TwS*Ljs2({6޻cWRp|z+Obx7# UCyJdFl#)IΨTI{J#ȶ>qSrmD9aPM]ш,u$҈Օ[IJ%)N9G#BUs4"Tu5PŔ$Ȗژ%FPFP]-Ҫ=% UCyJd$@J"0:4Xڙ8>* 1x*7qz$t))Oik6t0RTnӲGkHCKcJrFPjoh1$(4qcȑ#^^;G0CLW3_cOi{Jp8G{)uBf(4v6hHLɫftcĔ)mQv3$śTqxJt3v'!RB]SJAǔ͐0oĔ6F :O;G4V}Uev#mct*;:ԞbJfDp# N=R^DFTLUv6%)iC2Jmk(jI'ܭ:$<0j 9 vh8FZu*)rȹ! wCĻ*YAyJN;G0BSF]\Іa$Vdi6Bk6Ըξ#xSuLi1]ǔv}c w0ξSr:. #f커͐RL7CXKé'xJka$w3z⇧Խ:L7C 6t39fsO)9 7cĔtƛ!aߌ}tIm:=%n0ze#XULi=Ow5u_'H:.)OFTvkQݩa$)ش$FJ7c V9tbDh7#0#}7nsO <%h,6y"O)=zJIŔ֝#1Q=s1#:$ƒnSqKr? `nS㓧똒Kr7R7뗧oO);cJ&!OgXuLi՞6SZξӆXuSRa$c7nYw) c7CNś;$ic[ 4nIBL7C.4Rm}GCǔc-̈́98{ToFw)I&SArSU9Z!Qd=ERڏwpC9f0CLiSҤ5&q)Sq ep#ߌpnHnć{t yLi1%cDUT*nxJp3DsC>I+ƮKQ53I5fDI7<wwé|8GKmjf4SZt`,ZhO FpZC锤@zxJ))nFEe sf ȾC6d1<%=%mu m S) c7#;) cI7cUҢS$Tvڭ;G-;#Q x;Gdu{JK1 #iҢIoĔ$(SJ7CD5)3˒5ʔ%%2Cb Uvra(x3/Ծw/50}Hr5[B$|mm0 Dl|ǀz48dKG-Wi:C= f09 YI`_bRC.Mr38C 2 3x1@Ā c@0`‹ٲfL`X@^1UTEEV (  '!&h % $E< H@1!NnyA4 d@ddTjwoql܌qf,H:J7x@\ja@`WWB}K{S=Dr30 G>!b3/O|-pA3]0BԄCyJ! zG18f``S F`"e>@)$@s, MyJCYQC>$P{^=eUjy#&2xQCnסU<}3֝9CP 9dF)qKOpeYk)6 n?fCm\Cf-j~Z$PIa4А?e!rH^%SQ,(!>cEHÔ {7ʪ"ԾF M/%b]ϕ5=pZ[qt D ,Ν:@ 0'*Oi,jh6q< x) gǠu@ܮ2 (7X6׀Xc 5K3P4 3ʀ$Ur*C p/ Sne3& 0,  *BgQ@D1pOM  `K@*8 x$@:b@#-B"^b x7c~yd(>Xoa 1Pg`b5x@\jqY]\QQ '@nƔFB#!H8Ü}~&auJ8`P 3Hvf0`H +fC0@R @300 ) F`S HO!0O΂~xz}HULiheyL:] MrƍR\ÇH9vSmm4jl+vO2kfbjVPIa4А?~&rH^SZjOJdS<>DHLOtBkRfb]ϕ}1EdbJ`Cҏd‡;lxSѦ;a:&d!F#o@AL)ۛS:DHh@12fIf^Ŕ"T!=^) Š[@k9 +w *D8Q@D1pO|M@2L-ОZ@:bA# 'bJ` h`~y'dbJH[A94䐍OV>[vS=Up[6Pc64se5F?-g0Y<9Cls(S3̱2sx x1@Ā c@0ϸ9)Zd)leTy< (2GnrDiC 56\Cf e5OC2 4BC 3D5C 2(Cl^5s舛K31TC; 0C y=a/^x=V:d*\o1-_Nϩc=M̊k閭&x4tu MgS&ǐqzؒ o@1`E`6bԐKϜ:빳ċ IF"T,%^@xnM>EcX,yE`++xQA1ܓH70 *pH uĀF-"b8!#Y4@ #( {h@v1sYZPjhȆjHf  .€,V-> TJqPHn"iLDYk1OPr>Idʆ<})}w&j8T 2H + %shYL?( %| CY?C>TC{=CG<C<CI;TCnEbw1lڠ.rơ8zpHnȹh:mHƆkȬiH0ZhȟxfH^`eȒDzcH*aȅ(:`Hͫ{Bk^'^}p!5/Yy- BiT!Z#Kjl7p< h9;@N@%ꨉPҪyʍ | 5RC. P4>XB:b@S3"T 9^uE[,ERdK^9LoTEŀS&$Kpܹ'cmtM T h8 y$@:b@#^g'rA ٕ4h ܙyd(w0`qↆl@i`ad$=H_wd57SyJPS &L HX@Bq? sGɷL<%ouJ8T 2H + %shYL?( %| CY?C>TC{=CG4'!2x9 vv!\ӱҀrĔ&cJCP 9dPC=8$P}CmbJ@Snӆ4jljd*igkeQ,ĔՉ~?Xaȅ(:`Hͫ{Y׼NO1%SfV"nFY:С݇ΗK 8&t+Oi՞A=S8x4tAwZ84Lpȿ;flFCjȥgD ƌX,!D 0uɩAxn)Q1(`+pO-2ʀa蘒G #4=^rhO)8rBXGt I+ S:FF ,7@А ( 30na$mλT 1P áA]&3%E$( ;cJc~SnԱ6X - &6p z`f0 F , .PPC?dPC>$PC=PCT=PC  xJs};$PCn<%#OGsH͡.rơ8zpHnȹh:mHƆkȬiH0ZhȟxfH^`eȒDzcH*aȅ(:`H`G9\ .%x: 0d@Z@OMƇ;P{6A{Jh20 @)fdha H}oM4h2P@&3Ɉ"sA40uE[洖݃4*@b)h20)aqpO0KQ4h?#N3u!h4E~0ʠ脻UV}gR2eCM;~ Jfi`qQ4e~0K3Ҁ ~, 2h?:n&1%H.ⶴL4ǰD^7oP`8T 2H + %shYL?( %| CY?C>TC{=CGobJx䡉 wݡo*vסU7tRs!(q(!p!rn(!چNl!2k(!~i!g(!rRf!XFd(!>c!$vra(! _{ǐ#:y+Ʌ Ku H?h?)hi?e~d1tJ-SBZ3)g­У  M$dd~Gjd`uE[ &W: *Gҭh  )QF8e(qʆcl4)f`ʆ3 *i?)fiwdl`qU=Ylet,S6L bi;; 4+~0eòֳǔ8Y`ʦl?w@O\_GOiD q Mg0@`0S7 (nP,(!ip~ZToH6 0)\"f9@ʀ U_$9\@hHZL?ʷB|:z-gf] 7mC?ۥ~HiLnН3.7{f/ѐC6ng|҃o~nȹ{:!͆lh!63>7?SIC -4P<3ޖ)  4ʐ%Clyl%VH 0PQpfj_|酌]# ܉Z[k Dh E!:.*<*5p3>!|6?<Πf09 7m{z˦_:,ّܹ4(>scXd1U?`~@]n1#Θ,؊᫬*)V ( h '@h xp#XHDh8! B2T;:@@6JCg:Z`KOX ?w!ϛZ`W\JFO6a)o#4,!z@ 0 fS<%:h @5h:2kb N7 OA `@ `pzsK/iF&0o;X`hWc&.op+Ǜ!Lo^bWxC9>Dkǔ~ {|ҝ4SCP 9dF)aໟ!rn:fjl(J];Q̈Yz5[ObJ9pY2(C %{MH \ a# >{!n&2^(wXW;rd~,SBK+ :  m6\{Stg/&Zg39䀌c`8H|ݝe| 5.M ΀1 H2^O~  p/ b8.)݌ +׫堨3f B P'nb&S"e  U?έrh!7J;Ozpnȹ gUcC 5dFY_!g("gԏU/C 2dP"1?\ (cվB /S.ǪpEe,kgTH?>npϦ tc:`2omd# 5S. gV$c,/^? p/ 2帠~,L`X@^leWAXp X)!(u&h”TB8 KC"'ݭKs)cwq0tih%wi=,<ǧ'i@nP 02@6nH +Ly xk6smSC1%$Zbj0ڒ 4`o1y0B @GYDo~ wx.ꡣy@2x#vvS?ZH᭕E|.rgJA 7ݐsN{ƆkȬ~A% a4А?C|9~,C Y2wqL3!1Ð C!|~Ծ˝r(OixܽuY?s.B^{=@`ҏ<"|@=`y耙L8yۀe| 5. PNs 3ʀ$x̝14e .& 0, rxxJQ@DrO:t 4 m2I DĔ hDoBC h@ $=4;t́-ↆlǵX bʻ WaPhi0#a`>ξ/v1)o>orMK9?Q^mMnAwzC-=Ֆթ-U_hʹF[v}4ߍj?ux]N,)UsR3<U_׌`#)L}3JhEь1Px1][ft#W0JF3j.A3bF6ʨkM80a7z721Dx[y.nDe5Z~3O'(H52͝Et^IXq-#_hÒ2\~9uuV\b$d| GH1lR~l?Jcl)x(g[3YԙğdK).cm%wk o u7 Ҳn[͖L.JfK-ZT_}mɝCLhl)&\Ңܓ-5~DhY-]ף'ޱ-NK+~#goiQn)V4NߢSFn[juIHG3@o)sR*[\Rnl-鶥Lgo[ZG-ejXS`JQqg߲E[bWk+tm-2+(h\ٲ$-Y@}߷ %[d+ufL % x,mxJwyJ+L/K.y2JP;1)^[ྜ3ʩ[\m ~ڴ'[:F^V5U痭~,ײLV u~j?sY0}je}DԮB?>%grgy\j-w}BB95kȿ<CCl-pj쏿`悪9)0<^R?J ӧik'!r@ y_bɲv6j=ތRXF0e=|/[I{ؐ(*ō(pk Eօ~LYR>{]ьНh$l4K[EhVwS(~S#R4K}CiS<سiCߒn嶶sug~*׋Y']?~c8]?~ 9␣'90CE%* ާjiL!Gޠǂr0p/z<6Ɯ¿tN<lk?_{#3{jW#?;_e##3~~GG?ɑz·D#gIG~4}:"q4Ǒj#g\q92,Ǒ^R9;G~[_A>rG ٺ8+XzW_zg>ŋ}gPKL$'J@k README.TXT ,VM,PHIM.S(O,rs 2sRS*3rRSsyx9   123maps.zipPKc'.6k  >blackmap.zipPK'7)"g*c  AQjewelmap.zipPK'.b@   {midtones.zipPK'Q0@g  shortmap.zipPKˠ's,UG  ospecimap.zipPKܠ'h 6HI  0stripmap.zipPKL$'J@k  xREADME.TXTPKyxfractint-20.4.10.orig/extra/bc5fract.zip0000755000000000000000000001040110150522423015036 0ustar PKbN"t(v BC5FRACT.BATA@E&&b4aait4dtf fTW~Z7^o1E$\V戝iPkaö 1ɞ4,YqΝ""QYJ>T*=;P@g WjˆH2FJq?]*~dKPKO"&-E\ BC5FRAC.CFGM5\ e$AD#AL Qºy`83H{x9y>@PKO"DF\ BC5FRAC2.CFGM5\ e$ADH'HnAf.LҞzz1~>.@d9rPKZP") BC5FRACT.DOCmUMoFbPڱR$@-YeKrPp "G&]bw)=wfIr[^l÷cf5{X}Y,lXoi .xB??`{;xGq-!B" "^ f@HMY ߱TѮ, sVzao,LU}rP;8*E$?Pi$;J ExP2UJT qhT Ku&WZ߂6c'=1᱊_?9 [>EZ55QW葁Ks`Z,$ӻQj{vhr3VŃ3M Ҧ3Z9co).+lΉgaى)a*(Q? )wa֌v=lAi"9EX.AP9boZN(v蔙USqȖ hT{k`ey2u1}8lZ)dZm7?%c{ch'sKRɥ-@1:^{X)iz/XkW @j{cǛWwdynngd㭍Ǘ^?^3٣~:UQI{n\:PORgqq2Go\aOk;x 7l3y\(s寍Pjo[NN #z30?q$=dri@7HqNI):}ys{Qt!#<;+y>6:M`E ֘%tqh T6uweLRaNx4P:{?PK'+? BC5FRACT.LKŔMr0 TqY&L&͔12Ķ\!!Sgskz=^v{mWi!\QnГ2 ^v q$)TAȎJuMZo>$yDY h Y4 AVJ G(HTov%4i5kvZF;*|6,F5rjJ %VRd9,<žYoEQ";PX7K l}#zM$v&=R=upd찴E^a)&S&QC&c۲4,!`p93궙VD+Q3N/%x*Ax}ٷ D깻MG6P,gq~0Gb>?HZ{wm~֘>mK.n |1zXsx`PK| rH<MBC5HC.LKUH6Ot2A\@:"L&rd&U&d@`/PK'O BC5FRACT.MAK]o6 `W֋[nX9ݦ#;(P(4e3$M2쿏Ǒ.\<>)y+rٿ𝬖ZSXqDϜSҾOg#4K)#~_%g٦$O&'9 5Y\tGx{l>@JdIxB͒i?ZQJ]!a,┗v19x-J~Rϋ?ȿޢYiޡxQq@TG}!a_4 PP}sH.LunX[EՔAx;1^O`aU[ iD+'b q`9oZГ% ƌ%Kxqձ5.))i6mO߾z}vv-<`hYT:ԵWt%5%mj R*5nĎz @sQD5+U |@^Nf%PK bvxFZ BCFRACT2.CFGM5\ e$AD C   [=b2sJSR< sPKL&'~TG BCFRACT.LNKn %7tڷa|}vVv 5@g]8vct|:t ̙M< F^M6;JP)(  WiH@UYҠfLJ.3ӝ}]CUѡF(XrYn%i #( R+bn^a# ͞bXI3 2Jx:#8CGi8q1\ꌝ$tAXNv”D'F!:LnD%OR| '_/fo?sOOK/%>_/È<%:쪍p |0Na#n)&=36+>m֎|ۆL:kx&rdnr{h_PK| rH=MBCHC.LNKUH6Ot2A\@:"L&rd&U&d@`/PKL&'rV BCFRACT.MAK]o6 `Wڋ[nX9#;(P0e3$M2쿏d.֋|ޗ2El^ +Tf㤈p芆,a%K IcRHD(JBt!^Q>p/û^E jMhfc"ij0NQb<gF7)#v/ɟ%ɲuuxsZќ?L{lJ+D*f-R5!lě8a%[GT ^G?Aw􏐷HyG(<# i? w2a!tѧ,bN=[Q%su\ 0%i@sql4Mm _mRQ^+js~.1K:nEA˵XpwO&|?0fGO; q ƙ4ya\TD1Y2bEuEE*qNY| 3Ysf998 Rk%.)"beGH~T^ 4Uo҂YηE\BrFؑc%!p[XT ZtR XXBwZ1j5[o(q6 n٤w+4 {H^Ac,)щž"(W* Mh߉֘ūJkL^%5N[!h@1hx'A[PH^\A ٙO(% W!!χ t=@ऑ>ƌH{42 $NhLlR(& M} EI;{$I} M=ݟ4y=׬}@6)+#|<@  BQ g@2 +t5dg%bR>%/&06sq`D'.5l\n80 MCL" NP6<~`Pj+s3\msO5x6k4mφѳhO !b)\O|V˷+@R;;Y  &{X{7&Mné {9=py퍉YA5t!j*Z!FϮ:g띨*_{5Vؖs?[\jk(o:c`2덤.+_{-UP_imIG/30wHΡ&ǡO窱t1 :Pmzkqo 8+;5HWUTތ~i@M]V-侬m{bAS|s5PR~G??PK| -|v BCFRACT.BATUK 0Elufqi| MJTC9D>YϲbpηXR+7 =M$S.RhϿ#%Yc?!K%vOPK:p er BCFRACT.DOCuTMS0{NevӃcM1a&5K/Nd +ٱ E]ooJ~ Zjw3Å œu8j#IcWE4F?p]|5hYGxnSm'8c',(Cpk ;J@ 8đmW4Įt [-dq:'TESqSa6Xӫƺo j$ 7wxuCi_dL;G}?[KniwCƁҤ]TuCt{is6_vmrdΚ-4gz0N,-n#ݝkB^8u0Ga#Xcїұ OܬIT8iIpVE=;cp)~=KՋtc>Ȍ tpqZ qƏ0&}{uPmЕ2Ŀʑ(/FHO`S6$Y[G[ƃvhQXS "8*dY-$rݚ8U|ۭm}o^!6Wm;M ~FGרw~OοчPK | $JJ|  BCAUTO.BATPK | G;Ty  rBCLINKF.BATPK | 3B  BCMAKALL.BATPK  e+DY  LBCFRACT.CFGPK  bvxFZ  BCFRACT2.CFGPK L&'~TG  )BCFRACT.LNKPK | rH=M BCHC.LNKPK L&'rV  tBCFRACT.MAKPK | -|v  @ BCFRACT.BATPK :p er  BCFRACT.DOCPK 8zxfractint-20.4.10.orig/extra/simplgif.exe0000755000000000000000000022740410241007314015151 0ustar MZ '`T stub.h generated from stub.asm by djasm, on Tue Jan 30 23:43:58 1996 The STUB.EXE stub loader is Copyright (C) 1993-1995 DJ Delorie. Permission granted to use for any purpose provided this copyright remains present and unmodified. This only applies to the stub, and not neccessarily the whole program. $Id: stub.asm built 01/30/96 23:43:58 by djasm $ @(#) stub.asm built 01/30/96 23:43:58 by djasm go32stub, v 2.00T@CWSDPMI.EXE$`0!sip 9sÉ ǹJ!s ω &,10&=PAu&=THu &==uG>uW1tkm uAr/ ut>6_>*6b>,t#,GtCf.EXEb=d!ù?!11ɋLtMZ  tډB!?!u>Lwfffffff+ff fKfOfff9sff1f t H!"&(؉"11r11f16>1 ɁQɛ1I11 Yɓ1I11ss1j f6f>fIf6 f>#f'7f>KfOf1fgf>!1fd.ffff&f>"6>f6B:FBN>G?( u &; v Bf1ɋFf>"f"f)&f1gff&uÀ:t/t\þd&G8tt FutúHV`Rb$ds sR;[a L!C!$u $PQW1*_YXø!1f*10_ދ>;Rdt7t\Fr7DCFuW*dK!_r M!*>ir"X!gX!hX!X!Ü>irPSXh0!Xg0![XLoad error: $: cannot open$: not EXE$: not COFF$no DPMI$no DOS memory$need DOS 3$can't switch mode$no DPMI selectors$no DPMI memory$L X .textX .data @.bss u%=|fd51۹v1ff 1sL!f0<f fɃfɓ1tff1ff1s%t{^f1sL!fNf^fVpf¹l1f 1%%  1f1ftf 1K=19tff1Kf Kd ˉf-P<dKdPGSd 1Kd 9}ȣKPtKff҉1& D$1fff f1f0<f1tftf1f f1p;fsf1Ku1SB(ft1=pfB"ʾz=K5Kffмff1f.-p,tVWP|$ft$f1X_^6L$suD$VWS66; tv%P=Kf5Kf 1PpX1ZE=Kf5K KfKЋ ) KP"JP%‰f1XRfSfQY+ K9 t أ6;fsKStJ;SvQSffˉ1uff1f0<1f0<Kf K1SB`t"= )1@tᆳ 6[_^UVS]u f]fufEf9tYDTUʉMjEPSP' DTPhTSP' f9DTvfEfETve[^ÐU P'‰Í6U PE PjEP'‰v-i SIMPLGIF is a basic GIF decoder/re-encoder program that takes what may be a tricky GIF file with interlaced images, multiple images, GIF89a extension blocks, etc, and converts it into a simple, single-image, non-interlaced GIF87a file with no extension blocks. Note that while it is doing this, SIMPLGIF uses as workaspace a temporary file (SIMPLGIF.TMP) based on the size of the overall image. Processing a 1024x768 image involves a 786K temporary file. SIMPLGIF needs two filename arguments - the names of the input and output files ie, SIMPLGIF OLDGIF NEWGIF .GIFrb Oops - I cannot open %s as a GIF file Oops - I cannot read screen descriptor GIF87a Oops - I cannot find a valid GIF header Oops - error reading global color map *** Cannot Open the temporary file! *** creating a temporary disk file %dx%d bytes long (note that we're talking about a %d+MB file here) ... writing line %d of %d *** Cannot write the temporary file (disk full?) *** Oops - error reading input file Oops - error reading local color map processing input image at offset %d,%d generating output image of size %dx%d using compress compression done. UTS]]f]f]"EEf}v*hE R"uEEEUB9v$EU BRhS"EU9v$EU BRhPT"=St =PTuh!"aj.hS"uhhS"j.hPT"uhhPT"hhS" = uhSh " Pjj EP th!jhEP|# u'}/v!}9w}/v}9w}@v }zwh!jt#EE׊E$pÈ]ՊE$È]֊EEMָfEfEfUff f]fEfUff f]Ѐ}t= PEPjhTU9th j"6fEfDTfEfThh h" fSfuhB~ EDT]T]؉]؁E@BmE؉ETPDTPhm+ }vEPh DTPjhT]" ET9Er6MȻ 1uTPEPh DTPhTSP;" f9DTv5hSP"h"-E]h(FfSfT\E܃};u}!uFA<‰Uu'vEE9Ew6E6ɍ6v}, Pjj EPthPj 6EE͊E€Uˀ}tE$È]M̸fE 6fEEfEfUff f]fEfUff f]fEfUff f]fEfUff f]ƀ}t< PEPjhTU9thrjfEfHTfEfWfEfWfEfSf]fSffWPHTPh: EP؉]jj}uvfHTfWfDTfWfTfSTPDTPh hjj Ph<hTjjEPTPDTPhPT SPhh@h/31]ÍvUVS]u f]fuf=TtfLTf9Euvf=StufLTf9Eti DTMLTMȉMHTEjEPSPW WPHTTRSP fSfEfLTf}u fTj DTMLTMȉMHTEjEPSP WPHTTRSP fTe[^UVS]u f]fujfEfWREHTT6e[^ÐUVS] uf]fujfEfWRDEHTMTfSe[^UjffWRE PEPHTTR fSf=u ftP t6tgfff9Swffgvfff9Swff;vfff9Swffvf61Í6U1Í6U4S]]f]f]&fUf} U6f}~ f}  6f]fCf, ,fEMfEf]fCf]fEf@fUfUEEfEfEЇf4f0fEfEf9EEfEЇfEEЧEЧ]]6fEfEf9Euf}} 1 6fEf9Ef]fCf,fEfEEfEЇ ,fEfEfEf9Et66fEf9EufEf9EfEfEfEEՋEUEfEfEfEf9E+fEf9E}SfEfEfEfEEUՈEfEfEf9E~6EfEЇfUfUf}EU)…fEEUMW]Њ]ЈEfEgfUfMf}vč6E܊UfEEEE)E}uVE-ЧPhЧfUf} UV6t ?vEЧ]]"EUWEEfEgfUf}u EUEfEf9E~FEUfUЇfCfEЇEUUՈWEfUfEgfEfEfEfEf9Ef=,  fef,}Чwj6ME܋U EM}uME-ЧPhЧfUf}U0t 6EЧ]]v1]ÍvUSf=4f=0S@<f0f}0Cv!6f=0t0Ph<@$@f4f 0$4)f(f,f94|f=0Q@<+f0f}0!6f=0t0Ph<@$@$ 4f (f4f 0Rvf,f)4,f(f#Eʉ]ÍvUWVS1E$E $$ؤܤ$UM DMPHMIMM$ $A $$ФEPCEE̤~6Ev+MM̤Uu$P*EPljuܤ ĤMM]M3u9Luu|U묍v6É%PjW<(e[^_ÐUVS]u Ct2u-Ss<}C t soCtCtPsQCCCC CCe[^UVW}u M=_^EÐUWVS}GuDwt=_)~4w1GuG SVw:  O )ƅGtgGG1e[^_UE@%UVS]M p1Hy QS=Q؈%Ae[^UWVS}]u uGHW H9~ t GCGWPC<tYNR9}2~PSw G+7WPCe<tN97|VSw~w)7E"} tM D11M)1e[^_ÐUVSu] Et€0 ~'IKuE)PAPj e[^ÐUEwe$D1EE,EE1EE,E$EEE,EEEEE,E1E#Ð.Ð-Ðuu!Ãxu/Ãytu 'Ð"Call frame traceback EIPs: 0x 0x UWVS1SU;Xj h_Ej j;p 19]v<3t6[jhEj jSG t;9Xw,sjhEj e[^_Alignment CheckCoprocessor ErrorPage faultGeneral Protection FaultStack FaultSegment Not PresentInvalid TSSCoprocessor overrunDouble FaultCoprocessor not availableInvalid OpcodeBounds CheckOverflowBreakpointNMIDebugDivision by ZeroFloating Point exceptionControl-Break PressedControl-C PressedException at eip=, error= eax= ebx= ecx= edx= esi= edi= ebp= esp= cs= ds= es= fs= gs= ss=UWVS;X8= t%f Ife8t `a1w4uuGu4GyuJGu=j h\GjjSjhgGji j;p >0HPVj4jhgGj&j;p yujw/t&;X4tjhpGjjSjhyGjj;0`jhGj j;p@jhGjj;p#jhGjm(j;p jhGjMj;pjhGj0(j;pjhGjj;pjhGj(j;pjhGjj;@(PjjhGj(j;@*PHjhGjj;@,P)jhGjs(j;@.PjhGjQj;@0PjhGj2(j;@2PjhEjjUUM Á@E EøABRTFPE ILL SEGVTERMALRMHUP INT KILLPIPEQUITUSR1USR2NOFPTRAPExiting due to signal SIGExiting due to signal 0xBad signal handler, UVSu~@~ Eupw%jh4KjjJPjjhNKjjVzjhEj =;tj=v=,vjhgKj lV1e[^Cannot continue from exception, exiting due to signal US;p8#S;x8v 0Pj6hPLjjSjhEj ]ÐUS1ېURS4u t JRS4UM J $JCv]Sju4hJju4UMJ JSj 4hJj 4UMJ J =t#hJ54hJ4;hJ55hJhJh< 5hJ54]U1 E@=?~;;f f; K;M\=;MUR4fUE91UM J $JE@vfUfJfJJ4<= tJL<+J<E=URj#f3E=URj$Q3h;j 3=thLP4f IfeÐUf;Ѓ}t f;Ðf;Ë|$D$Gfg.fo0_OW ofG2wG<&G*&FG&FG&F G &FG(&FG$&FGfG,fW2;_^ϐUWVSԷuG@F18t>u4>%??u&>t>f&.f1^^ÐU5(1MuuSV<4M)ĉPWV#4V419U~B9UEe[^_ÐUMf1s f]ÐUS]fU fMf1s f1[]ÐUSWf0<f]} J=Ju f fG ffG.ffG0fG fG.fG0f1s f1 J_[]ÐUSVf1s fu&Ff^NvV1^[]ÐUVWfff]fEu }M,ff_^]ÐUVSu=xKu\xKj访%)} xKtQ艿tm1ۺxKvC9w|KxKH9w1۹‹|Kt$C9wKuS+Ku1KZBe[^ÐUWVS}O~GxK9} щș 2Q躾ƒtK Ke[^_ÐUSMtYyuQKAK]ÐUWVS}uu wGHxK9st2tVt HxK9}D9u w 9E vQt_uWKGKu Ãu19tE 9vPWS؍e[^_ÐUjh jj|No memory to gather arguments UumujhUjj5ÐUU fmetB)ÐUS]1;t QЃ ~QɃC;u]ÐUSjujjSa؋]ÐUVSut PFt*1ۃ8t4CF<uvFt PKVe[^ÐUVS]jƉSFSjPe[^ÐUVSu19~F4EC9vQVKe[^'"U WVSE}U UMME9$9}vGE;u9}EU}uE;9u}t9Eu-EFa<'t<"uEFMAA>\u3FPhWttEH9sFFCUBFC}tE;cM ME)CPXUSWP M~9}u01UCM FQ U9u؍e[^_ÐUWVS}119~=GPt1:t@<u@t PÃCF97Ɖ؍e[^_UWVS}1] KX]t=1҃;td@] C@BK@<u/PtRWǃ] CF] 93ve[^_UWVSEUBMxut8@umj@P2+ǃ|[jjW jjW F$)ĉVSW+W,VSËUBMXBpeEUM9ie[^_ÐUVSu19~:FPt Rxu0,‹FPC9ȍe[^!proxy!proxy2UWVSDžttx:uڀ;t<:t<\tUWVSh`jP3%ÃDž|jjSxPEjjSxuS%S&xM| u Ux D uE[UU]:t"Ph`tKMC;uߍ]U:t M<.t%AMC9u]Cuu>t< t< uF>uuU: tBU< uM9AMDt#t[u-EPVDž|uDž|s|cx$)ĉt瀽D=tCG;=ut9+uAtQ<%{%u %GDžhDždDž`Dž\DžXDžTCPh`1C-$bccccccccccccccccccccccccccccccccccccccccccccccDžh:Džd.DžX"DžTDž` Dž\CSH{tH9%t AH9u鋕HpHCP@l8t@B@Vh`tl`t =\t ÊXt\u/Tt/u\G@:uhtldt @t;GptHCCG;Gta#9u4[^_ÐU4MU EEBEfM܉fEfUEPj!VEtEP(ÐfUEÐUWVS}u uVW ƒ Lj)PWkڃ ht(19}<3tC9|~RVN%ƒtЍe[^_Ð|UVS]Ct CC@{u3Ct US쐐5V0tH8uNFEPuVXuE9!u6E@t"-dqEuOEEF}tC9](vFOC9](w0FuMtHFl1hE@EP-XqɃ <$m}E Em$Zm~900FOuE@tujFPu$j <$yE$؋MtOt*0FOut9u$sN>0tH8tF؉+E$؍e[^_Ð?@@U WVSm}u]U E@tj-xD@u<؀;.uC<0t<2t <4t<6t<8uEEE@OEP-xɃ <$1؀018~ 1}ƒP$}-xmEu2H8uK <9~?09u uF1N-KѐM$9-u H8uK;0u9uM$K㐐e[^_ÐU\WVSuM EF}-+F ~mȿ ~ 900Kȿ Ń~90ʀ0K9s0CF9r$0F~90ʀ0F[^_NaNInfUULfEf=t1ÐE u}tzL zÐ|UVS,,t/1S9}ѐTztf@9|{uuՅu&jXÃu1ACj‹CTփtjjVLC1e[^ÐUWVSE %=u#ut( } u= uE €U ]%Pu3 ƃuE tSuƃtE tjjVH {4 PV WVSE t jjVpe[^_ÐUh|;ÐUS]S{~S$]ÐU4VS]u fEDf]fEEPj!EuAMt $߄}TfEDf]%fEEPj!NEtEP(9u4Ph $h$ ȍe[^ÐUWVS}u 1hMtuu QE1E]9t<9=s<t P=W6u(S} 'M9 u E FEFKu֋]MىMQ5u9|؍e[^_ÐUuUÐU4tfECqE EfU CfUu1} uEfEfEfEEPj!hEuEÐEP(ÐLFNU49t 1hhFtnu ̐fEGqfEfffUСfEfEfEfEEPj!f}qtEt  UE|ow ĨøÐ~Itu$UWVS} Gt $GGu Gt9wGUG_)9_ ~} uwۉtEEuwueSeƉwu OxO _ ,u%5@ t <50E1O@_)wG SVw" ~)ƅGu GUGEe[^_ÐUS]f1s f ] fK1[]US]E fHf1s f1[]US]f1s f ] fK1[]US]E fHf1s f1[]US] ffK]f1s f1[]ÐUEffHf1s f1]US]f1s f ] ffK1[]ÐUVWf0<fu} f1s f EffH1_^]ÐUSVWEfHfX fxfpf1s f1_^[]ÐUS]t!j…tZ1]ÐUSWf0<f]} f1s f1_[]nulU4S94t4KKh fE=fEfEEPj!^ EtEP(]uS؋]UWVSu} 94t4KK|/K9DKP5K$Ku"ڋ K9} B9|K<1e[^_ÐUU94t4KK|9K1áKÐUu u PufؘPU8S] }u(UREPj t Eu|tfElqf]fEfE E=]fEfEfEEPj!EujEPMEEP(]ÐU@WVS}uƒt7MQEPj҃ t$EEP( ME9usufE?EfEfuffMfEEPj!Eu)]]ątu S5 ] t9tEče[^_ÐU8uƒtMQEPj҃ tEÐE>EfE܍EPj!2Eu1(ÐU EPjjuuEÐ1UVSuu VÃt VjS0؍e[^ÐUVSuUt$] CAuJtAJuJue[^UVSu]t%M >tB:uBKt Aue[^ÐUWVS0}HEj=uH+Ep9Ht7H@Է8t@@<u@D1ۡԷ8Vu4l ueԷP2tTE@PQԷ W{uԷ41CԷ<xM<u1D9@|O DPà @P5ԷS 5ԷԷE@PË@Էt_uSr@@Է1?WԷ@L DJ@1<e[^_ÐU4WVS9`t`dhL}||dC9Er`wXdhlj=hLd)PjhP EgdfE܍EPj!hU Me[^_ÐUVSMU 1< tAFCJue[^Ð||U帨ÐUS] MtUB9uBIu1]ÐUVS]M p1Hy QSQ؈%Ae[^UmE}fU fUmm8US(ju(t 1]ÐU8S] }u(UREPj7 t EutfElqfEfEfE Eu܍JE 9rZef E: t KtKt\ut K)Ӎs)SRđ1t FO)ȃ u j:tBR~50j5V5Kƒ .S=Kt-1҄t'  **B*uj  LtI0ҋщtFKV@PC KKKts覧tiuj¼ÃtS0P蟼‰Su Sѽ"RtKKKP6ƒ1[^_UWVSE Uu1 KKKKKKKK/Qu=KKKtus}truj虻Ãt\0}PyCu S譼0uPSKKKK1ۨt^t*KPv|Ft'EKP‰Vu tPjR8 KF=Kt) KKVAKQû=KuK@uhPj5KFPyK1$[^_UUE 02ü||LFN32UxWVS]u tu(0SfENqfMfMfEfUf}fUfUfEM̉Qj!蚸E1Rh>RVVVRVRlfpfVj*SSu0j?SDu!fUfUfEqj!fEfUfVVV 1yf}fUE]Sj!褷ENfEfUfMfMSj!}EuVj,R1UR(|[^_ÐUtVSuu(fEOqfVfUfu(&`fEfUfE]Sj!EuoRh>5VVVRVRKVV 1UR(& fFfEqSj!EUR(rfEfUE]Sj!ҵ5h"VyEOSj!赵EtUR:(Vj,51[^Ð*?[\UWVS}u G?t8t"*tRH[\1>%rMF_\t/uEtJG*tu8E8t\t /t@8u1% \t/u^EtX8t\t /t@8u1ƅ"uVW }\t}/u EFMuMF\t/uEtj1MM?!%Et_1C<]MMt;-uSKMtI]tD8E| M8M|}t'%M=8=wE8=r$8Et}tЋM=8=uC<]u19}t؉DžEu6Gt/Ph0MtGu\OF8P\t/u<\t=K9}w1VuKЃ~ K9U9}tKu)"+5K9ur9}t?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Abort! .(null)@@@ @ @4@p+ŝi@զIx@GA~QCǑF uuvHM]=];Z R`%u? ףp= ף?,eX?aw̫?[Mľ?9Eϔ?9'*?d|FU>:zc%C1<#2IZ9Wڥ2-64OSk%ޟݦ @@?|  %&"  @YYYYYYYYYYSSSSSSSSSSSSSSSSSSSSSSSSSSssssssssssssssssssssssssss  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~L .l,4PԬ.file!gcrt0.ssel_buf#5pFpUtzerovdzvK :Giexitt6@yK!X(bv7.textR.data.bss.filegsimplgif.c<<L8L9L7_fpin L10L11LC0LC1!LC2LC3LC4LC5LC6LC7LC8LC9BLC10mLC11LC12LC13LC14(LC15PLC16rLC17LC18LC19LC20LC21/L13L14L15L16L18L17 L12"L19GL20nL21L22L24 L238L25L26L27<L28L29L32L30\L33L34TL31TL35{L37L36!L38L39L41L40L42L45L43L44L46!L47!L48 L49X L50b L51!L52!_cury_Pass"L53!L54!L56"L55#L57;#L58X#L59$L60e$L62$L63%L67$%L74$L65$L73%L69P%L71|%L66%L64%L68K%L70w%L61%_curx.text<T.data.bss.filegdecoder.c%%L7%L9%L8)L11%L10%,40L12d&L15p&L13&L14~&L16&)L18&L17)L19&L20`'L21'L23 'L22$'L244'L25D'L26J)L27'L28'L29'L31'L30(L32(L33'L35(L36$(L34((L37(L38x(L39(L40(L41(L42*)L43J)L44J)L45K)L47X)L46)L48)L49)L50)_b1.18$$(L52f*L53C*1<_pbytes@L54$*L51`+L55C*L56C*L57*L59*L584+L60*L61*L62*L63*.text%M.data.bss$ .file5ggifcompr.ch+h+_maxbitsĤ<Ȥ_hsize̤HФRԤ]ؤhܤr}$$_offset$_n_bitsD_maxcodeH$_EOFCode$/L8$,L110,L9<,L103,_cl_hash(/_output-L12i,L14,L13d-_htabLL15,_codetab|L16,L17,L18-L19,L20,L21,L22 -L23-L24X-L25]-.L7-_masksL27-L28-L29-L31-L30./L33.L32.L34P.L35.L36p.L37.L38.L39.L41.L40. 0L42./L26.L43$/L45G/L47z/L48/L46/L49/L52/L50/L51/L44/LC0/L53/_a_count$L54/_accum$L560L550L58e0L57e0_fsize$.texth+`.dataĤl.bssDpv.filegggifencod.ch0h0_Pass0h0_curx%_Width%L8P1%L90_cury%L10P1L140L210L120L20P1L161L18D1_Height%L130L11P1L151L17B1L7P1%L23l1L221LC01LC11LC21L25T2L26Z2L272_Putwordd4L28$3L3103L293L303L324L334L24_4L354L344.texth04>.data0.bss%.filesgnpxsetup.c44_nofpsig4 %.text4,.data4.bss%.file}gident.c66.text6.data4t.bss%.filegcrt1.c666,7;t7R8.text65.data.bss%.filegfakee%u :forced;=:limitFix;;4;stack_ok:ds_limit;A<[=.text9$.data.bss%@.fileginfostrc.c`=`=.text`=.data.bssE.fileglseek.stub.text`=.data.bssE.filegread.stub.texth=.data.bssE.fileggetc.cp=p=.textp=$.data.bssE.filegfread.c==.text=.data.bssE.fileg_main.c>>.text>D.data.bssE.filegstrcmp.c\>\>.text\>(.data.bssE.filegstrcpy.c>>.text>(.data.bssE.filegprintf.c>>.text>(.data.bssE.filegstrchr.c>>.text>,.data.bssE.file gstrcat.c??.text?0.data.bssE.filegfopen.c0?0?.text0?<.data.bssE.filegstrncmp.cl@l@.textl@<.data.bssE.file'gexit.c@@.text@\.data.bssE.file/gopen.stub.textA.data.bssE.file7gmemset.s.text A@.data.bssE.file?gwrite.stub.textLA.data.bssE.fileGgclose.stub.textTA.data.bssE.fileQgremove.c\A\A.text\A.data.bssE.file[gfclose.c B B.text B.data.bssE.filecgmemcpy.s.textB.data.bssE.filemgfflush.cBB.textBx.data.bssE.filewgferror.cLCLC.textLC.data.bssE.filegfputc.c\C\C.text\C4.data.bssE.filegfwrite.cCC.textC.data.bssE.filegdpmiexcp.cpDpD_buf.46E_itoxpDDE$5@G\ EiJs J_npx_oriJ_kbd_oriJJJJ.textpD .datah.bssE.filegfake.textxOt.data.bssJ.fileggetenv.cOO.textOh.data.bssJ.filegct_lower.cTPTP.textTP.data.bssJ.filegd0e01.S.textTP(.data .bssJ.filegfake.text|PL.data .bssJ.fileg_write.cPP.textP .data .bssJ.filegdxeload.cQQ.textQ.data .bssJ.filegd0000.S.textXR$.data .bssJ.filegd0008.S.text|R,.data .bssJ.filegd0300_z.SJ.textR.data .bssJ.file gd0400.S.text(S8.data .bssK.filegmd.S.text`S,.data .bssK.filegmalloc.cSS_pageszxK|K_nextfKhT.textSP.data .bssK.file*gabort.cUU_msg .textU.data  .bssK.file@gc1args.cUUV@V_atohex`V_new_argVVTW WW'Y3pY>ZUZ.textU C.data,.bssK.fileJgc1loadef.c``.text`E.data,.bssK.fileTglseek.c e e.text ed.data,.bssK.file^gread.cee.textex.data,.bssK.filehgfilbuf.cee.texte  .data,.bssK.filergstdout.cgg.textg.data,.bssK.filegdoprnt.c g g_decimalH_nanLgP_cvtlpq_ptenX_ptenneg_INVPREC_PRECqz_roundlx}z.text g.dataH`.bssK.filegallocfil.c0{0{.text0{.data.bssK.filegfmode.c{{.text{.data.bssK.filegopen.c{{.text{ .data.bssK.filegstdiohk.c|||.text|4.data.bssK.filegsetmode.c||.text|.data.bssK.filegwrite.c}}_sbuf_sbuflen.text}.data .bssK.filegclose.c~~.text~.data.bssK.fileg_chmod.c~~.text~.data.bssK.fileg_use_lfn.chh_use_lfn.texth.data.bssK.filegdoserr2e.c@@_mapĨ.text@ .dataĨp.bssK.filegerrno.c``.text`.data4.bssK.filegdjmd.sjhbig_movez.text`(.data4.bssK.filegflsbuf.c.text@.data4.bssK.filegd0202.S.textȁ,.data4.bssK.file"gd0203.S.text,.data4.bssK.file*gd0204.S.text ,.data4.bssK.file2gd0205.S.textL,.data4.bssK.file:gd0201.S.textx0.data4.bssK.fileBgd0304.S.text(.data4.bssK.fileJgd0200.S.textЂ0.data4.bssK.fileRgd0303.S.textD.data4.bssK.fileZgd0600.S.textD8.data4.bssK.filedgatexit.c||.text|8.data4.bssK.filelgd0300.S.text8.data4.bssK.fileygfsext.c4_num_fdsKK.textt.data4.bssK.filegdmp.c``.text` .data8.bssK.fileg_open.c.text .data8.bssK.fileg_read.cPP.textP.data8.bssK.fileg_close.c00.text0d.data8.bssK.filegct_flags.c.text.data8.bssK.filegc1pglob.c.text$.data<.bssK.filegcalloc.c.text0.data<.bssK.filegstrncpy.c.text<.data<.bssK.filegstrncat.c$$.text$@.data<.bssK.filegct_upper.cdd.textd.data<.bssK.filegputenv.cdd_ecount@_emaxDH.textd).data@ .bssK.filegdosio.cxxL `_countd.textx.dataL .bssK.filegcrlf2nl.c44.text40.datal.bssK.file gstdin.cdd.textd.datal.bssK.filegstderr.chh.texth.data.bssK.file"glconv.cll_ESTR_DSTR1.textl .data0 .bssK.file,gmemchr.cxx.textx0.dataԬ.bssK.file6gputc.c.text4.dataԬ.bssK.file>gfake.text܋,.dataԬ.bssK.fileIgfrlist.c;Ԭ.text.dataԬ\.bssK.fileSgfexistp.c.text0.data0.bssK.file]g_creat.c88.text8 .data0.bssK.fileggfwalk.c.text@.data0.bssK.fileqgputpath.cDD.textD .data0.bssK.file{gisatty.c44.text48.data0.bssK.filegfse_open.cll0.textlp.data0.bssK.filegdmg.c܎܎.text܎ .data4.bssK.filegglob.cO_glob2ȑ_pathbufKZKeKqK_slashKK_flagsK_errfuncKP.texth .data4.bssK .filegstdprn.cdd.textd.data4.bssK.filegstdaux.chh.texth.dataP.bssK.filegfindfirs.cll.textl.datal.bssK.filegfindnext.chh.texth.datal.bssK.filegfnmatch.c00.text0 .datal.bssK.filegqsort.c_qst_qszK_mthreshK_qcmpK_threshK.text!.datal.bssKpDT1x__exitp,[;_freeT_strcat?_strcmp\>$;A=OsL;_ylenS_longjmpxOh__flsbufM__writePS_putc_etextآ_getcp= |P)`__readP6lBH;_n_strncat$~S__open|Rnedatal_fputc\C__filbuff;L<4___lseek eP ) #4 4_environԷ_ferrorLC> з_suffixWR Sa ;q _openA 8__doprntHg_raise|K_fwriteC_strncpy S ط 5 l$_xtotalDT__stklenK \9__chmod~ Ђ_memcpyB___sbrk\_memset A \=_prefixg R <end,_remove\A___modfl܋_xoffHT_fflushBetextآ& LT2 L^ Ї___main>l hx K _lseek`= PT ; <___globL  $ `S d" t/ ,_fread=__creat8@ $_fopen0?K _calloc__fmodek < = ܷ 4{ 1 ܎ T ,_reallocU_memchrx   < Ч_getenvO l( @; HOO _strchr>_dstackЧk L _signalJ (S_mallocS_fclose B___open{ h+_strcpy>  4< XR_atexit|__fwalk ; |_abortU& 43 KO %[ <r 8 T  l ` l_decoder%___brkt_strncmpl@  ;__close0_writeLA_edatal_end,S,___close~7K =a;_ytotalTrTP|T0<start_errno(9___write}_readh=S_exit@;_xlenW_printf>2D=___readeJȁ_qsortyQx$`; _main8_yoffW_closeTA4___djgpp_memory_handle_pointersbrk16_first_bytesbrk16_last_bytesbrk16_api_ofssbrk16_api_segexit16_first_byteexit16_last_bytehook_387_emulatords_alias_okdos_alloc_ok__what_size_dpmi_thinks_we_arelock_memoryuse_stubinfo_stack_sizeno_memory__what_size_app_thinks_it_is__what_we_return_to_app_as_old_sizebrk_commonbrk_nochangebrk_errorno_fill_sbrk_memoryno_deadbeefbrk_returngcc2_compiled.___gnu_compiled_c_last_line.14_workname.21_Interlaced_getcurrentline_code_mask_curr_size_nbits_left_navail_bytes_get_next_code_ret_code.19_byte_buff_maxmaxcode_free_ent_exit_stat_clear_flg_in_count_out_count_g_init_bits_g_outfile_ClearCode_char_init_cl_block_cur_accum_cur_bits_char_out_flush_char_writeerr_BumpPixel_Interlace_CountDown__emu_entry_setup_core_selector_setup_screens_setup_go32_info_block_setup_environmentexception_stackexception_handlernot_forcedexception_statedpmi_exception_proc1hw_to_excpalready_forced_been_there_done_that.2_old_video_mode_cbrk_vect_except_to_sig_show_call_frame_exception_names_has_error_do_faulting_finish_message_signal_list_signames_cbrk_hooked_except_ori_cbrk_ori_cbrk_rmcb_cbrk_regs_veryfirst.63dpmi_busy_pagebucket_morecore_c1xmalloc_far_strlen_delete_arg_delete_arglist_new_arglist_parse_bytes_count_args_fill_args_expand_response_files_expand_wildcards_NULL_REP_isspeciall_exponentl_fcloseall_helper_write_count_use_lfn_bss_countsmall_movemod_4_checkalign_mod_4_init_count.8_func_list_putenv_bss_count_init_file_handle_modes_dosio_bss_count___lconv____initial_file_rec_glob_dirs_save_list_save_count_use_lower_case_wildcard_nesting_str_compare__put_path2___dpmi_lock_linear_region_GIFNextPixel___dpmi_set_real_mode_interrupt_vector___crt0_setup_arguments___djgpp_our_DS___djgpp_exception_state_ptr___djgpp_iret___dpmi_allocate_real_mode_callback___djgpp_exception_toggledjgpp_first_dtor__go32_info_block___djgpp_old_timer___file_handle_modes___djgpp_exception_setup_workfiledjgpp_last_ctor__detect_80387___dpmi_int_sp___dosmemput___dj_stdin___djgpp_save_interrupt_regs___dpmi_int_ssdjgpp_last_dtor_bad_code_count___dpmi_set_segment_limit___libc_sccs_ident___djgpp_hwint_flags___djgpp_kbd_hdlr___libc_ident_string___dj_stdaux___dpmi_simulate_real_mode_interrupt_get_pixel___isatty___emu387_load_hook_bufferchanged___djgpp_app_DSdjgpp_first_ctor___fnmatch_inputname___crt0_argc__npxsetup_out_line___crt1_startup___dpmi_get_real_mode_interrupt_vector___djgpp_hw_lock_end___dpmi_int___dj_ctype_toupper_bufferline___dpmi_set_protected_mode_interrupt_vector_sizeofstring___findnext___djgpp_base_address___dpmi_set_processor_exception_handler_vector_outputname___djgpp_dos_sel_GetPixel___FSEXT_alloc_fd___setmode_stdio_hook___movedata___putenv___findfirst___file_rec_list_put_pixel___dpmi_free_real_mode_callback___djgpp_timer_hdlr___djgpp_i24___crt0_argv___alloc_file_GIFEncode___dosmemget_bufferisvalid___dj_stdout___stdio_cleanup_hook___bss_count___djgpp_cbrk_hdlr_decoderline__use_lfn___doserr_to_errno___djgpp_set_ctrl_c___FSEXT_call_open_handlers___djgpp_exception_processor___FSEXT_get_function___dpmi_get_version_compress___atexit_ptr___djgpp_npx_hdlr___dpmi_allocate_ldt_descriptors__crt0_init_mcount___stdio_cleanup_proc___dj_stdprn___djgpp_memory_handle_list_keypressed___djgpp_kbd_hdlr_pc98___dj_ctype_flags_screenbuf___dpmi_get_protected_mode_interrupt_vector_localeconv___dj_movedata___FSEXT_add_open_handler___dos_argv0___djgpp_hw_lock_start___djgpp_selector_limit_get_bytes___dj_ctype_tolower___djgpp_hw_exception___djgpp_old_kbd___dpmi_set_coprocessor_emulation___setmode_colormap___djgpp_ds_alias___djgpp_exception_table__crt0_startup_flags___file_exists__stubinfo___djgpp_timer_countdown___FSEXT_set_function__put_path___dj_stderr___dpmi_get_processor_exception_handler_vector___dpmi_error__dxe_load___file_handle_set___crt0_load_environment_file___djgpp_cbrk_count___dpmi_int_flags_get_byte___crlf2nl___crt0_glob_functionxfractint-20.4.10.orig/extra/fractint.dsk0000755000000000000000000000002510150633601015140 0ustar Turbo C Context File xfractint-20.4.10.orig/extra/phctutor.zip0000755000000000000000000001743510253142173015237 0ustar PKJ)'= phctutor.frmWnF}7$nIA؍&-j(PC xQIʎ߻7R) @j3g ϧ'Pz_y̱`xf/'Lt*}.={ ѻ~t<%UJu=Eh$L?́i[î= (AU.5S}JU==9=`< cx_c'o :R5K~K[ߺNE6 |wǕf'mv}ӲF;2g^A{|,8˥ hDdCLbz}ԧŒ|m<D<'YXcX.ܩޣs!Y }RyK񳯼nmh=,pDhD*0Εt|$w iHȋxvp˗/T,2ϷWHnkG H/}0<12 kyi_ji[bW8fD4j YUC2 jCҥ6l9'%zM?8 W Y)eXrJhO7]UQK[2 *Y v7"rVFI+웉Q)" 8V"g\6v2iT͡|4u7L{%5v ]+N{%?Jk\ӯ #m&d< Ni5I3^q+ TDC,9+}z(8hT_XFnjzTfR-gm0cUKĦ:z8 8Wǘw EtPNᵓ0(Pu]Z5r(%%8xN("m^\\T3©CWĽnKmBbŒ S`@S.9{BjC uFeJT!09c$ASB$bJ"4p2% ڒN-J&$.H߬V0 0RDiz UkZZ.sP~VH,hd3zoB|K$YmOAXainYcNkKˏLVfC}W2i}iI{owqY1qiE ^Qw;G)rOuk*_nFWOgUTiʘe )(PKJ)'njʹU phctutor.txt\[s~w>!zHbDJcxe'TwkkA\n`CIYn*194Ѝ{{S-:mlJ߮(43Am:հx?4ҫ`=~ёvuĤ~i:>Wo:IUH$ "r<8wG"uPy~!= L*t|y YUGxV3ďedU,g֯H95xa`jC|i><ԯ*ioub @&i0N0N L*g&ByjJ hi¤I fePy-UDaq|M\?Z*+AڼLH"3Vitl&Kf" Y]~E\k#WZ)Z& #u=+1A oۍΒR9ڷk@NL蒽WqCa#`2^3נ+bP 8+ "' $D `fAAU'dhĔc~A%_xFQ׽!Wm U <ľ\N´@,X@|?Jp:PbmyJׄ Ksk5Fթ{a UбsLAVc)pv,JBq$-o` GYK+vn%Y}adcOE_WigH!p'`S&SB;FZR*3jWɼO.ʙ" ڶ78l!Ɇ IțaG VY3mRgRልu絎JG'M1Q:nPQӎQ<)bA;Hk8mlE+pM b  iwZNX: db#ȧ z;=*dH\5j/TDzzDwI>__*kSo(t|Ni <;%J(Ӛ r5@(e*S&/xMr9.D}"5oI N[9Iɀ'IDi:FrXɂO'5zRSV|V[bMhE)Lqxq.%r$^  Pskr!xَ9NWlIwF f@{X@B {j_'yc~x|3|R1}4–+P_L`g0zM% !wdFЦk'oCrjqzoD6ZM~{n϶y(vS–jin̗ ;=HrruHT  ӨLf颻1͉*'F 2ғ4a% 9wSNͨ:/Bީ 砉z>x:^hȸZ4yy.j!iC>tbsZӎU8M) dKډ&/+;;b?BFMǎ.7yـH͈H; Bq"-ę#\@1o;_T* qlm6B2Yi|8yrPp^u(c!V-)O<&s$N6j] W#"jS0Ns?p?7Nxƚv5 ڣs`Ywu,rl~oZ*\j%_ J>-*?ngC n ᝝;;S& [ܩ _- 2mټ%Ɔ _lʀ͋:ѿr46/4k**8w 7w7CV׺p>4 ͨ֯Qܞr-t[#jϖp eMbrZ8D0ݣ2D*:v~2\:+¾s? @6Xv#Ϙn%}'^wS%*b[f\ {#N!\IL++]I!?\^&rm '1)5iH9R`WnF?nWORm6}0 *;;kA][Fhϖrͩ%xQ*]ِ2\Na@R;[H1V9ܪt\i˝ 8"7eS'-n V L3*n_8w!rxZ s9.%=zDW \&5pcUC*pH2m=<:vnE65GóOl0 XS[H@L<`}tQ@%Kl-ˋH]aTL~26zH-ת0YY6D4(ʩtV#n!oߘMu "wφ.sb3t7TeW־: 3ҹBȶ$59 S~ETf&'60NHN( @S&F`̟eQdeaI"4X7X`V9^y[6nU&?`HRg٫ 0Ȇx,I7`!ipdOӱLD˖-)#G9s̘ \+B dq$mS>O D|ز9J~bxsrtwN9"zxt4,*qhԘ~?OV-倇ZGK9zbeBKxjM輲y@ɔu[O]tugaqN.P wNtuŷTNjliyaήE{Fj9_#Qv!m<6YHj/,Lbv̮D 3B/^ח\,y+NDE6MtM92]KUb [ S|*uY$JqU,^Kwz-AXWKMJ4ʄnX' w_[ӧ0UyրpB;F4NKW6o~2@VcSTNST7E'jЦt)rDUTZ uٮBjb dkgzvNϼs*|φMpd3,dЕVPtAQՍٓd)LhNsrq Owf dOU] x,w_]1II^:b/܁hҭgO~~`g|0,7bcrʴ\6fHD×lVs _GOZM[(]6מ[o$ĀK4@1]Lv嚞B4X_Z&:&rOd`v*6YZTl؀]KcCWxP wJñݤwTpI7BPKJ)'=  phctutor.frmPKJ)'njʹU  phctutor.txtPKtxfractint-20.4.10.orig/hc.txt0000644000000000000000000004133210616226653012652 0ustar ... First version documentation is followed by additional notes ... for features added in subsequent versions. FRACTINT Help Compiler Source File Format 0. Contents 1.0 Help compiler input/output. 1.1 The source input file. 1.2 The header (.H) output file. 1.3 The binary (.HLP) output file. 2.0 Source (.SRC) file format. 2.1 Comments. 2.2 Defining the output filenames. 2.3 Defining the help file version. 2.4.0 Help topics. 2.4.1 Starting a help topic. 2.4.2.0 The help text. 2.4.2.1 Special characters. 2.4.3 Starting another page. 2.5.0 Labels. 2.5.1 The help index label (HELP_INDEX). 2.5.2 Private labels. 2.6.0 Hot-links. 2.6.1 Special hot-links. 2.7 Tables. 1.0 Help compiler input/output. The Help Compiler converts a source file into two output files: a "C" header file which is #included in FRACTINT and a binary file used at run- time. 1.1 The source input file. The Help compiler takes as input a help source file (.SRC). See x.x.x for the .SRC file format. HELP.SRC is FRACTINT's help file source. 1.2 The header (.H) output file. The header (.H) file contains a #define macro for each non-private label (see 2.5.0) and for the help file version (see 2.3). The .H file is included in FRACTINT and the macros are used to set the current help mode. The Help Compiler will only modify the .H file when a non-private label (see 2.5.0) is added or deleted or when the help file version (see 2.3) is changed. This minimizes the times when FRACTINT will need to be re- compiled. However, when the Help Compiler does modify the .H file it is necessary to re-compile FRACTINT. In FRACTINT this file is named HELPDEFS.H 1.3 The binary (.HLP) output file. The .HLP file is the binary file where compiled help informnation is stored. See HC.C and HELP.C if you're interested in the file format. In FRACTINT the file is named FRACTINT.HLP. This file may be appended to FRACTINT.EXE for distribution, see the Help Compiler command-line help (type "HC" at the DOS prompt) more info. 2.0 Source (.SRC) file format. The source file defines output files, help file version, topics, labels and hypertext-style hot-links with commands and hot-links. Commands start with a tilde ('~') in the first column of a line and continue to the end of the line. Hot-links, defined within the text, are surrounded by curly- braces ('{' and '}'). Comment lines, which may appear anywhere in the file, start with a semicolon (';') in the first column and continue to the end of the line. 2.1 Comments. Any line starting with a semicolon (;) is a comment. The comment continues to the end of the line and may appear anywhere in the file. The semicolon must be in the first column of the line. 2.2 Defining the output filenames. The output filenames are defined in the source file by the following commands: ~HdrFile=H_FILE ~HlpFile=HLP_FILE H_FILE is the .H filename and HLP_FILE is the .HLP filename. These commands must appear before the first topic. 2.3 Defining the help file version. The help file version number is stored in a special #define in the .H file (named HELP_VERSION) and stored in the .HLP file header. If the version number in HELP_VERSION does not match the version in the .HLP file the file will not be used. This is mainly to make sure FRACTINT doesn't try to read a help file other than the one the .EXE is expecting. To define the help version: ~Version=nnn Where nnn is a positive decimal version number. (Suggested format is 100 for version 1.00, 150 for version 1.50, etc.) This command must appear before the first help topic. -1 will be used if the version is not defined in the .SRC file. 2.4.0 Help topics. The help topics come after the HdrFile=, HlpFile= and Version= commands and continue until end-of-file. 2.4.1 Starting a help topic. To start a new help topic use the following format: ~Topic=TITLE "~Topic=" is the command to start a topic and TITLE is the text to display at the top of each page. The title continues to the '\n' and may contain up to 65 characters. In the example: ~Title=Command Keys available while in Display Mode "Command Keys avail..." is the TITLE which would displayed at the top of each page. 2.4.2.0 The help text. The help text for each topic can be several pages long. Each page is 22 rows by 78 columns. The first and last rows should be blank for the best appearance. 2.4.2.1 Special characters. To insert reserved characters (like ';', '~', '\' and '{') into the help text precede the character with a backslash ('\'). To insert any character (except null) into the text follow a backslash with a decimal (not hex or octal) ASCII character code. For example: \~ - puts a tilde in the text. \24 - places an up-arrow in the text. 2.4.3 Starting another page. To start a new page in the same topic put two tildes (~~) at the start of a line. No other text is allowed on the line. Each page can be up to 22 lines long. (The Help Compiler will warn you if any page gets longer than 22 lines.) For the best appearance the first and last lines should be blank. 2.5.0 Labels. A label is a name which in used to refer to a help topic. A label is used in hot-links or in FRACTINT for context-sensitive help. When help goes to a label (when a hot-link is selected or context-sensitive help is called from FRACTINT) it goes to the page of the topic where the label was defined. To define a label for a topic insert the following command into the topic's text: ~(NAME) NAME is the name of the label. The name follows "C"-style conventions for variable names. Case is significant. The label should start at the beginning of a line and have no text following it on the line. The line line will not appear in the help text. For example, if this line: ~(HELPPLASMA) was placed in page three of a topic using it in a hot-link (see 2.6.0) or as context-sensitive help would "go to" page three of that topic. The user would then be free to page up and down through the entire topic. Each topic must have at least one label otherwise it could not be referred to. 2.5.1 The help index label (HELP_INDEX). When the user wants to go to the "help index" (by pressing F1 while in help) help will go to a special label named "HELP_INDEX". Other than the requirement that it be in every .SRC file you may treat it as any other label. It can be used in links or as context-sensitive help. 2.5.2 Private labels. A private label is a label which is local to the help file. It can be used in hot-links but cannot be used as context-sensitive help. A private label is a label with an "at sign" ('@') as the first character of its name. The "at sign" is part of the name. In the example: ~(@HELPPLASMA) "@HELPPLASMA" is a private label. Private labels are not included in the .H file so you may add or delete private labels without re-compiling FRACTINT. Each non-private label takes up some memory (4 bytes) in FRACTINT so it's best to use private labels whenever possible. Use private labels except when you want to use the label as context-sensitive help. 2.6.0 Hot-links. A hypertext-style hot-link to a label can appear anywhere in the help text. To define a hot-link use the following syntax: {LABEL TEXT} LABEL is the label to link to and TEXT is the text that will be highlighted. Only the TEXT field will appear on the help screen. No blanks are allowed before the LABEL. In the sample hot-link: {HELPMAIN Command Keys in display mode} "HELPMAIN" is the LABEL and "Command keys in display mode" is the TEXT to will be hightlighted. 2.6.1 Special hot-links. In addition to normal hot-links to labels "special" links to custom functions (built into HELP.C) are allowed. These hot-links have a negative number (-2..) in place of the LABEL. No special hot-links are currently supported in FRACTINT. 2.7 Tables. A table is a way of arranging a group of hot-links into evenly-spaced columns. The format for a table is: ~Table=WIDTH COLS INDENT << LINKS... >> ~EndTable WIDTH is the width of each item, COLS is the number of columns in the table and INDENT is the number of spaces to indent the table. LINKS is a list of hot-links (see 2.6.0) which will be arranged. Only blanks and new-lines are allowed between the hot-links; other characters generate an error. In the example table: ~Table=20 3 9 {@ONE One} {@TWO Two} {@THREE Three} {@FOUR Four} {@FIVE Five} {SIX Six} {SEVEN Seven} {EIGHT Eight} ~EndTable 20 is the WIDTH, 3 is COLS and INDENT is 9. The following text would be produced by the table: One Two Three Four Five Six Seven Eight Each item would be a hot-link linking to its corresponding label (@ONE for "One", etc.) Any legal hot-link (to private or non-private labels) may be used in a table. The same effect could be produced by arranging the hot-links into columns yourself but using a table is usually easier (especially if the label names vary in length). ... Second version additional documentation: New features of the Help Compiler (HC) ====================================== Expanded command format ======================= Several commands may be "strung together" by separating them with commas. For example: ~Topic=Help on help, Label=HELPONHELP, Format- To have a comma as part of a command (like in a topic) precede it with a backslash. Commands can be imbedded in the text with the following format: ~(command) The text before the tilde and immediately after the ending parend will be part of the help text. New commands ============ Format[+/-] L turns formatting on/off. Online[+/-] L enables/disables display of text in the online help. Doc[+/-] L enables/disables display of text in the printed document. (Currently ignored.) FormatExclude=NUM G/L Set the column number in which formatting is automatically disabled. (ie. all text after column NUM is unformatted.) If before any topics sets global value, if in a topic sets only for that topic. FormatExclude=n G/L Turn this feature off. This is the default at the start of the source file. Global if before topic, local otherwise FormatExclude[+/-] G/L Temporarily enable/disable this feature. Has no effect if "FormatDisable=n" is in effect. FormatExclude= L Resets FormatExclude to its global value. Center[+/-] L Enable/Disable automatic centering of text. All commands with a "L" are local in scope -- they effect only the current topic. All commands with a "G" are global in scope. Commands with "G/L" are global if used before any topics are defined and local otherwise. At the start of each topic the following local settings are in effect: ~Online+,Doc+,FormatExclude=,Format+,Center- Modified commands ================= Label=NAME replaces the ~(...) command FF replaces the ~~ command Hot-Links ========= Hot-links have been expanded to support "implicit" links. These are links which link to the topic whose title matches the highlighted text. They have no label field. In the example: Press to goto {Color Cycling Mode}. The link will link to the topic whose title is "Color Cycling Mode". The link must match the topics' title exactly except for case and leading or trailing blanks. Normal "explicit" hot-links to labels must now have an equal sign immediately after the opening curly-brace. For example: {=HELPONHELP How do I use help?} Links to the label named "HELPONHELP". (The equal sign is not part of the labels name.) Paragraph formatting ==================== The HC determines the end of a paragraph when it encounters: o a blank line. o a change of indentation after the second line of a paragraph. o a line ending with a backslash ('\'). o If FormatExclude is enabled any line starting beyond the cut-off value. The HC only looks at the left margin of the text to determine paragraph breaks. If your not sure the HC can determine a paragraph boundry append a backslash to the end of the last line of the paragraph. The following examples illustrate when you need to use a backslash to make HC format correctly: 1. Paragraph headings. Heading Text which follows the heading. This text is supposed to be a separate "paragraph" from the heading but the HC doesn't know that! This text would be formatted into a single paragraph. (The word "Text" would immediately follow "Heading".) To make it format correctly append a backslash to the end of "Heading". 2. Single-line bullets. o Don't branch. o Use string instructions, but don't go much out of your way to do so. o Keep memory accesses to a minimum by avoiding memory operands and keeping instructions short. Since the HC cannot tell that the first bullet is a separate paragraph from the second bullet it would put both bullets into one paragraph. Any bullet of two lines or more (assuming the intentation for the second line of the bullet is different from the first) is OK. Always add a backslash to the end of single-line bullets. In general, if you cannot determine where a paragraph boundry is by looking at the indentation of each line use a backslash to force a paragraph break. ... Third version additional documentation: New Commands ============ ~Comment, ~EndComment Use to start/end multi-line comments. ~CompressSpaces[+/-] Turn on/off the automatic compression of spaces. Used for data topics and when reading normal topics with read_topic() ~Data=label_name Starts a topic which contains data. Think of it as a macro for: ~Topic=, Label=label_name, Format-, CompressSpaces- Data labels cannot be part of the document or displayed as online help. ~BinInc filename Includes a file in binray format (no processing) into a data topic. This command only works for data topics. Example: ~Data=TPLUS_DAT ~BinInc tplus.dat ~DocContents Defines the documents table of contents. Text is allowed. Table of content entries have the following format: { id, indent, name, [topic, ...] [, FF] } id is it's identification (ie, 1.2.1) indent is the indentation level, (ie. 2) name is the text to display to display (ie. Fractint Commands) If name is in quotes it is also assumed to also be the title of the first topic. topic list of 0 or more topics to print under this item. Entries in quotes are assumed to be the title of a topic, other entries are assumed to be labels. FF If this keyword is present the entry will start on a new page in the document. It isn't as complex as it sounds; see "~DocContents" in HELP.SRC for examples. Quoted implicit hot-links ========================= HC will ignore quotes areound implicit hot-links when searching for the matching title. This allows hot-links like: {"Video adapter notes"} intead of: "{Video adapter notes}" This is so that the hot-link page numbers don't end up inside the quotes like: "Video adapter notes (p. 21)". It also keeps quotes from being separated from the text in the online-help. Document printing ================= The new /p command-line option compiles the .SRC file and prints the document. It does NOT write the .HLP file. The old /p option (set swap path) has been changed to /r. Printing the document ===================== The function prototype (in HELP.C) to print the document is: void print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg); outfname is the file to "print" to (usually "FRACTINT.DOC"), msg_func is a function which is called at the top of each page, and save_extraseg is true if the data in the extraseg should be preserved. See print_doc_msg_func() in HELP.C for an example of how to use msg_func. If msg_func is NULL no msg_func is called. Printing from help ================== There are hooks to print the document from a help topic by selecting a "special" hot-link. I suggest a format like: ~Topic=Generating FRACINT.DOC Explain that selecting yes will print the document, etc... {=-2 Yes, generate FRACTINT.DOC now. } {=-1 No, do NOT generate FRACTINT.DOC. } Selecting yes will generate the document and then return to the previous topic. Selecting no will simply return to the previous topic (like backspace does.) xfractint-20.4.10.orig/maps/0000755000000000000000000000000011456314747012461 5ustar xfractint-20.4.10.orig/maps/chroma.map0000644000000000000000000000743110150633601014415 0ustar 48 48 48 'chromatic' color map 56 48 56 by Todd Hedenstrom 64 48 64 72 48 72 80 48 80 88 48 88 96 48 96 104 48 104 112 48 112 120 48 120 128 48 128 136 48 136 144 48 144 152 48 152 160 48 160 168 48 168 176 48 176 184 48 184 192 48 192 200 48 200 208 48 208 216 48 216 224 48 224 216 48 224 208 48 224 200 48 224 192 48 224 184 48 224 176 48 224 168 48 224 160 48 224 152 48 224 144 48 224 136 48 224 128 48 224 120 48 224 112 48 224 104 48 224 96 48 224 88 48 224 80 48 224 72 48 224 64 48 224 56 48 224 48 48 224 48 56 224 48 64 224 48 72 224 48 80 224 48 88 224 48 96 224 48 104 224 48 112 224 48 120 224 48 128 224 48 136 224 48 144 224 48 152 224 48 160 224 48 168 224 48 176 224 48 184 224 48 192 224 48 200 224 48 208 224 48 216 224 48 224 224 48 224 216 48 224 208 48 224 200 48 224 192 48 224 184 48 224 176 48 224 168 48 224 160 48 224 152 48 224 144 48 224 136 48 224 128 48 224 120 48 224 112 48 224 104 48 224 96 48 224 88 48 224 80 48 224 72 48 224 64 48 224 56 48 224 48 56 224 56 64 224 64 72 224 72 80 224 80 88 224 88 96 224 96 104 224 104 112 224 112 120 224 120 128 224 128 136 224 136 144 224 144 152 224 152 160 224 160 168 224 168 176 224 176 184 224 184 192 224 192 200 224 200 208 224 208 216 224 216 224 224 224 224 224 216 224 224 208 224 224 200 224 224 192 224 224 184 224 224 176 224 224 168 224 224 160 224 224 152 224 224 144 224 224 136 224 224 128 224 224 120 224 224 112 224 224 104 224 224 96 224 224 88 224 224 80 224 224 72 224 224 64 224 224 56 224 224 48 224 216 48 224 208 48 224 200 48 224 192 48 224 184 48 224 176 48 224 168 48 224 160 48 224 152 48 224 144 48 224 136 48 224 128 48 224 120 48 224 112 48 224 104 48 224 96 48 224 88 48 224 80 48 224 72 48 224 64 48 224 56 48 224 48 48 216 48 48 208 48 48 200 48 48 192 48 48 184 48 48 176 48 48 168 48 48 160 48 48 152 48 48 144 48 48 136 48 48 128 48 48 120 48 48 112 48 48 104 48 48 96 48 48 88 48 48 80 48 48 72 48 48 64 48 48 56 48 48 48 48 48 40 48 48 48 48 48 56 48 56 64 48 64 72 48 72 80 48 80 88 48 88 96 48 96 104 48 104 112 48 112 120 48 120 128 48 128 136 48 136 144 48 144 152 48 152 160 48 160 168 48 168 176 48 176 184 48 184 192 48 192 200 48 200 208 48 208 216 48 216 224 48 224 216 48 224 208 48 224 200 48 224 192 48 224 184 48 224 176 48 224 168 48 224 160 48 224 152 48 224 144 48 224 136 48 224 128 48 224 120 48 224 112 48 224 104 48 224 96 48 224 88 48 224 80 48 224 72 48 224 64 48 224 56 48 224 48 48 224 48 56 224 48 64 224 48 72 224 48 80 224 48 88 224 48 96 224 48 104 224 48 112 224 48 120 224 48 128 224 48 136 224 48 144 224 48 152 224 48 160 224 48 168 224 48 176 224 48 184 224 48 192 224 48 200 224 48 208 224 48 216 224 48 224 224 48 224 216 48 224 208 48 224 200 48 224 192 48 224 184 48 224 176 48 224 168 48 224 160 48 224 152 48 224 144 48 224 136 48 224 128 48 224 120 48 224 112 48 224 104 48 224 96 48 224 88 48 224 80 48 224 72 48 224 64 48 224 56 48 224 48 56 224 56 64 224 64 72 224 72 80 224 80 88 224 88 96 224 96 104 224 104 112 224 112 120 224 120 128 224 128 136 224 136 144 224 144 152 224 152 160 224 160 168 224 168 176 224 176 184 224 184 192 224 192 200 224 200 208 224 208 216 224 216 224 224 224 224 224 216 224 224 208 224 224 200 224 224 192 224 224 184 224 224 176 224 224 168 224 224 160 224 224 152 224 224 144 224 224 136 224 224 128 224 224 120 224 224 112 224 224 104 224 224 96 224 224 88 224 224 80 224 224 72 224 224 64 224 224 56 224 224 48 224 216 48 224 208 48 224 200 48 224 192 48 224 184 48 224 176 48 224 168 48 224 160 48 224 152 48 224 144 48 224 136 48 224 128 48 224 120 48 224 112 48 224 104 48 224 96 48 224 88 48 224 80 48 224 72 48 224 64 48 224 56 48 224 48 48 216 48 48 208 48 48 200 48 48 192 48 48 184 48 48 176 48 48 168 48 48 160 48 48 152 48 48 144 48 48 136 48 48 128 48 48 120 48 48 112 48 48 104 48 48 96 48 48 88 48 48 80 48 48 72 48 48 64 48 48 56 48 48 48 48 48 40 48 48 xfractint-20.4.10.orig/maps/goodega.map0000644000000000000000000000663710150633601014560 0ustar 0 0 0 This is just one of many EGA-optimized MAP files sent to us 0 0 84 by K.A. Eastwood of Townsville, Queensland. His secret to 0 0 168 generating good-looking EGA MAP files: 0 0 252 0 84 252 1) Fractint treats the EGA adapter as if it is a sort of 0 168 252 "brain damaged" VGA adapter with only two bits of depth in 0 252 252 its RGB palettes. So, act accordingly, and pick four 252 252 168 palette values that will map into the four possible values 252 252 0 of the EGA's RGB values. The numbers 0, 84, 168, and 252 252 168 0 do nicely. 252 84 0 252 0 0 2) Generate 16 palettes using the above numbers for R, G, and 168 0 0 B values and fill up the first 16 lines of a MAP file. 84 0 0 252 252 84 3) to get Fractint's color-cycling to work correctly (and 252 84 0 to get these maps to display correctly on VGA equipment), 0 0 0 copy those 16 palettes another 15 times to get a full 256 0 0 84 line palette MAP. 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 0 0 0 0 0 84 0 0 168 0 0 252 0 84 252 0 168 252 0 252 252 252 252 168 252 252 0 252 168 0 252 84 0 252 0 0 168 0 0 84 0 0 252 252 84 252 84 0 xfractint-20.4.10.orig/maps/neon.map0000644000000000000000000000603510150633601014102 0ustar 0 0 0 A flashy map ... by D. Egnor 0 0 0 8 0 0 16 4 4 24 4 8 32 8 12 40 12 16 48 12 20 56 16 24 64 20 28 72 20 32 80 24 36 88 28 40 96 28 44 104 32 48 112 36 52 120 36 56 128 40 60 136 40 64 144 44 68 152 48 72 160 48 76 168 52 80 176 56 84 184 56 88 192 60 92 200 64 96 208 64 100 216 68 104 224 72 108 232 72 112 240 76 116 252 80 120 248 80 120 240 76 116 232 76 112 224 72 108 216 68 104 208 68 100 200 64 96 192 60 92 184 60 88 176 56 84 168 56 80 160 52 76 152 48 72 144 48 68 136 44 64 128 40 60 120 40 60 112 36 56 104 36 52 96 32 48 88 28 44 80 28 40 72 24 36 64 20 32 56 20 28 48 16 24 40 16 20 32 12 16 24 8 12 16 8 8 8 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 12 0 0 20 0 0 28 0 0 36 0 0 44 0 0 52 0 0 60 0 0 68 0 0 76 0 0 84 0 0 92 0 0 100 0 0 108 0 0 116 0 0 124 0 0 132 0 0 140 0 0 148 0 0 156 0 0 164 0 0 172 0 0 180 0 0 188 0 0 196 0 0 204 0 0 212 0 0 220 0 0 228 0 0 236 0 0 244 0 0 252 0 0 248 0 0 240 0 0 232 0 0 224 0 0 216 0 0 208 0 0 200 0 0 192 0 0 184 0 0 176 0 0 168 0 0 160 0 0 152 0 0 144 0 0 136 0 0 128 0 0 120 0 0 112 0 0 104 0 0 96 0 0 88 0 0 80 0 0 72 0 0 64 0 0 56 0 0 48 0 0 40 0 0 32 0 0 24 0 0 16 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 12 12 0 20 20 0 28 28 0 36 36 0 44 44 0 52 52 0 60 60 0 68 68 0 76 76 0 84 84 0 92 92 0 100 100 0 108 108 0 116 116 0 124 124 0 132 132 0 140 140 0 148 148 0 156 156 0 164 164 0 172 172 0 180 180 0 188 188 0 196 196 0 204 204 0 212 212 0 220 220 0 228 228 0 236 236 0 244 244 0 252 252 0 248 248 0 240 240 0 232 232 0 224 224 0 216 216 0 208 208 0 200 200 0 192 192 0 184 184 0 176 176 0 168 168 0 160 160 0 152 152 0 144 144 0 136 136 0 128 128 0 120 120 0 112 112 0 104 104 0 96 96 0 88 88 0 80 80 0 72 72 0 64 64 0 56 56 0 48 48 0 40 40 0 32 32 0 24 24 0 16 16 0 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 xfractint-20.4.10.orig/maps/grey.map0000644000000000000000000000536310150633601014114 0ustar 0 0 0 Full 256-color TARGA/GIF grey-scale map 255 255 255 254 254 254 253 253 253 252 252 252 251 251 251 250 250 250 249 249 249 248 248 248 247 247 247 246 246 246 245 245 245 244 244 244 243 243 243 242 242 242 241 241 241 240 240 240 239 239 239 238 238 238 237 237 237 236 236 236 235 235 235 234 234 234 233 233 233 232 232 232 231 231 231 230 230 230 229 229 229 228 228 228 227 227 227 226 226 226 225 225 225 224 224 224 223 223 223 222 222 222 221 221 221 220 220 220 219 219 219 218 218 218 217 217 217 216 216 216 215 215 215 214 214 214 213 213 213 212 212 212 211 211 211 210 210 210 209 209 209 208 208 208 207 207 207 206 206 206 205 205 205 204 204 204 203 203 203 202 202 202 201 201 201 200 200 200 199 199 199 198 198 198 197 197 197 196 196 196 195 195 195 194 194 194 193 193 193 192 192 192 191 191 191 190 190 190 189 189 189 188 188 188 187 187 187 186 186 186 185 185 185 184 184 184 183 183 183 182 182 182 181 181 181 180 180 180 179 179 179 178 178 178 177 177 177 176 176 176 175 175 175 174 174 174 173 173 173 172 172 172 171 171 171 170 170 170 169 169 169 168 168 168 167 167 167 166 166 166 165 165 165 164 164 164 163 163 163 162 162 162 161 161 161 160 160 160 159 159 159 158 158 158 157 157 157 156 156 156 155 155 155 154 154 154 153 153 153 152 152 152 151 151 151 150 150 150 149 149 149 148 148 148 147 147 147 146 146 146 145 145 145 144 144 144 143 143 143 142 142 142 141 141 141 140 140 140 139 139 139 138 138 138 137 137 137 136 136 136 135 135 135 134 134 134 133 133 133 132 132 132 131 131 131 130 130 130 129 129 129 128 128 128 127 127 127 126 126 126 125 125 125 124 124 124 123 123 123 122 122 122 121 121 121 120 120 120 119 119 119 118 118 118 117 117 117 116 116 116 115 115 115 114 114 114 113 113 113 112 112 112 111 111 111 110 110 110 109 109 109 108 108 108 107 107 107 106 106 106 105 105 105 104 104 104 103 103 103 102 102 102 101 101 101 100 100 100 99 99 99 98 98 98 97 97 97 96 96 96 95 95 95 94 94 94 93 93 93 92 92 92 91 91 91 90 90 90 89 89 89 88 88 88 87 87 87 86 86 86 85 85 85 84 84 84 83 83 83 82 82 82 81 81 81 80 80 80 79 79 79 78 78 78 77 77 77 76 76 76 75 75 75 74 74 74 73 73 73 72 72 72 71 71 71 70 70 70 69 69 69 68 68 68 67 67 67 66 66 66 65 65 65 64 64 64 63 63 63 62 62 62 61 61 61 60 60 60 59 59 59 58 58 58 57 57 57 56 56 56 55 55 55 54 54 54 53 53 53 52 52 52 51 51 51 50 50 50 49 49 49 48 48 48 47 47 47 46 46 46 45 45 45 44 44 44 43 43 43 42 42 42 41 41 41 40 40 40 39 39 39 38 38 38 37 37 37 36 36 36 35 35 35 34 34 34 33 33 33 32 32 32 31 31 31 30 30 30 29 29 29 28 28 28 27 27 27 26 26 26 25 25 25 24 24 24 23 23 23 22 22 22 21 21 21 20 20 20 19 19 19 18 18 18 17 17 17 16 16 16 15 15 15 14 14 14 13 13 13 12 12 12 11 11 11 10 10 10 9 9 9 8 8 8 7 7 7 6 6 6 5 5 5 4 4 4 3 3 3 2 2 2 1 1 1 0 0 0 xfractint-20.4.10.orig/maps/froth6.map0000644000000000000000000000600010150633601014343 0ustar 0 0 0 252 0 252 248 0 248 244 0 244 240 0 240 236 0 236 232 0 232 228 0 228 224 0 224 220 0 220 216 0 216 212 0 212 208 0 208 204 0 204 200 0 200 196 0 196 192 0 192 188 0 188 184 0 184 180 0 180 176 0 176 172 0 172 168 0 168 164 0 164 160 0 160 156 0 156 152 0 152 148 0 148 144 0 144 140 0 140 136 0 136 132 0 132 128 0 128 124 0 124 120 0 120 116 0 116 112 0 112 108 0 108 104 0 104 100 0 100 96 0 96 92 0 92 88 0 88 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 168 0 0 164 0 0 160 0 0 156 0 0 152 0 0 148 0 0 144 0 0 140 0 0 136 0 0 132 0 0 128 0 0 124 0 0 120 0 0 116 0 0 112 0 0 108 0 0 104 0 0 100 0 0 96 0 0 92 0 0 88 0 0 252 252 0 248 248 0 244 244 0 240 240 0 236 236 0 232 232 0 228 228 0 224 224 0 220 220 0 216 216 0 212 212 0 208 208 0 204 204 0 200 200 0 196 196 0 192 192 0 188 188 0 184 184 0 180 180 0 176 176 0 172 172 0 168 168 0 164 164 0 160 160 0 156 156 0 152 152 0 148 148 0 144 144 0 140 140 0 136 136 0 132 132 0 128 128 0 124 124 0 120 120 0 116 116 0 112 112 0 108 108 0 104 104 0 100 100 0 96 96 0 92 92 0 88 88 0 0 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 168 0 0 164 0 0 160 0 0 156 0 0 152 0 0 148 0 0 144 0 0 140 0 0 136 0 0 132 0 0 128 0 0 124 0 0 120 0 0 116 0 0 112 0 0 108 0 0 104 0 0 100 0 0 96 0 0 92 0 0 88 0 0 0 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 168 0 0 164 0 0 160 0 0 156 0 0 152 0 0 148 0 0 144 0 0 140 0 0 136 0 0 132 0 0 128 0 0 124 0 0 120 0 0 116 0 0 112 0 0 108 0 0 104 0 0 100 0 0 96 0 0 92 0 0 88 0 252 252 0 248 248 0 244 244 0 240 240 0 236 236 0 232 232 0 228 228 0 224 224 0 220 220 0 216 216 0 212 212 0 208 208 0 204 204 0 200 200 0 196 196 0 192 192 0 188 188 0 184 184 0 180 180 0 176 176 0 172 172 0 168 168 0 164 164 0 160 160 0 156 156 0 152 152 0 148 148 0 144 144 0 140 140 0 136 136 0 132 132 0 128 128 0 124 124 0 120 120 0 116 116 0 112 112 0 108 108 0 104 104 0 100 100 0 96 96 0 92 92 0 88 88 0 0 0 0 0 0 252 252 252 xfractint-20.4.10.orig/maps/gamma1.map0000644000000000000000000000602610150633601014306 0ustar 0 0 0 Pseudo-gray sequence optimized for images encoded at a gamma near 1.0 20 12 20 Modification of the Peterson/Vigneau Sequence by Lee Daniel Crocker 24 20 28 24 28 32 32 32 28 32 36 40 44 36 36 36 44 44 44 44 48 44 48 52 48 52 44 52 52 56 60 52 52 52 60 52 64 56 60 64 60 60 64 64 56 64 64 72 72 64 68 72 68 64 76 68 68 72 72 76 72 76 68 76 76 72 72 80 76 84 76 80 80 80 84 80 84 76 84 84 80 84 84 92 92 84 84 88 88 88 84 92 88 88 92 92 92 92 92 88 96 92 92 96 96 96 96 96 92 100 96 104 96 96 100 100 100 100 100 108 100 104 100 104 104 100 108 104 100 104 108 100 108 108 100 108 108 112 112 108 108 116 108 108 112 112 108 108 116 108 112 116 108 120 112 116 116 116 116 116 116 124 120 116 124 120 120 112 120 120 120 124 120 120 124 120 128 120 124 128 124 124 128 128 124 124 128 124 132 124 128 132 128 128 128 124 132 128 132 128 136 132 132 124 132 132 132 132 132 140 132 136 128 132 136 136 136 136 132 132 140 132 132 140 140 144 136 136 144 136 144 140 140 144 136 144 140 144 140 148 148 140 144 144 144 140 140 148 140 140 148 148 144 148 144 148 148 140 148 148 148 148 148 156 152 148 152 156 148 148 156 148 156 152 152 152 152 152 160 152 156 148 160 152 152 160 152 160 156 156 156 156 156 164 156 160 152 164 156 156 164 156 164 160 160 160 160 160 168 164 160 164 168 160 160 160 164 168 164 164 164 168 164 160 160 168 168 164 168 164 168 168 160 168 168 164 168 168 172 172 168 168 168 172 164 168 172 172 176 168 176 172 172 172 172 172 180 168 176 176 172 176 172 176 176 168 176 176 172 176 176 180 172 180 176 176 180 172 184 176 176 176 180 184 180 180 180 176 184 176 184 180 180 180 184 176 180 184 184 188 180 188 184 184 184 180 188 180 188 184 184 188 184 192 184 188 188 192 184 192 188 188 188 184 192 184 192 188 188 192 188 196 188 192 192 196 188 196 192 192 192 188 196 188 196 192 192 192 196 188 200 192 192 192 196 200 196 196 196 196 196 200 192 200 196 200 196 200 196 200 196 204 196 200 200 200 196 200 200 204 200 200 208 196 204 204 204 200 208 200 204 204 208 200 208 204 204 204 204 204 208 200 208 204 208 204 208 204 208 204 212 204 208 208 208 204 208 208 208 212 208 204 212 208 208 208 212 204 216 208 208 212 212 204 212 212 208 212 212 216 212 212 220 208 216 216 216 212 220 212 216 216 212 216 220 216 216 216 216 216 220 216 216 224 212 220 220 220 216 224 216 220 220 216 220 224 220 220 220 220 220 224 220 220 228 216 224 224 224 220 228 220 224 224 224 224 216 224 224 220 224 224 228 224 224 232 228 224 224 224 228 220 232 224 224 228 228 220 228 228 224 228 228 228 224 232 224 232 228 228 232 228 232 228 232 228 236 228 232 236 228 236 232 232 232 232 232 236 232 232 240 228 236 236 236 232 240 240 232 232 236 236 228 236 236 232 236 236 236 232 240 232 240 236 236 240 236 240 236 240 236 236 240 240 244 236 244 240 240 240 240 240 244 240 240 248 244 240 240 240 244 236 248 240 240 248 240 244 244 244 240 244 244 244 244 244 248 244 244 252 240 248 248 244 248 240 252 244 244 248 248 240 248 248 244 248 248 248 248 248 252 244 252 248 244 252 252 248 252 244 248 252 248 252 252 244 252 252 248 252 252 252 xfractint-20.4.10.orig/maps/landscap.map0000644000000000000000000000434210150633601014727 0ustar 0 0 0 My Favorite Landscape Map by Guruka Singh Khalsa 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 64 90 0 64 90 0 64 89 0 64 89 0 64 88 0 64 87 0 64 86 0 64 85 0 64 84 0 64 83 0 64 82 0 64 81 0 64 80 0 64 79 0 64 78 0 64 77 0 64 76 0 64 75 0 64 74 0 64 73 0 64 72 0 64 71 0 64 70 0 64 69 0 64 68 0 64 67 0 64 66 0 64 65 0 64 64 0 64 63 0 64 62 0 64 61 0 64 60 0 64 59 0 64 58 0 64 57 0 64 56 0 64 55 0 64 54 0 64 53 0 64 52 0 64 51 0 64 50 0 64 49 0 64 48 0 64 47 0 64 46 0 64 45 0 64 44 0 64 43 0 64 42 0 64 41 0 64 40 0 64 39 0 64 38 0 64 37 0 64 36 0 64 35 0 64 34 0 64 33 0 64 32 0 64 31 0 64 30 0 64 29 0 64 28 0 64 27 0 64 26 0 64 25 0 64 24 0 64 23 0 64 22 0 64 21 0 64 20 0 64 19 0 64 18 0 64 17 0 64 17 0 64 16 0 64 16 0 64 15 0 64 15 0 64 14 0 64 14 0 64 13 0 64 13 0 64 12 0 64 12 0 64 11 0 64 11 0 64 10 0 64 10 0 64 9 0 64 9 0 64 8 0 64 8 0 64 7 0 64 7 0 64 6 0 64 6 0 64 5 0 64 5 0 64 4 0 64 4 0 64 3 0 64 3 0 64 2 0 64 2 0 64 1 0 64 1 0 64 0 0 64 0 0 200 200 255 200 200 255 200 200 255 200 200 255 205 205 255 205 205 255 205 205 255 205 205 255 210 210 255 210 210 255 210 210 255 210 210 255 215 215 255 215 215 255 215 215 255 215 215 255 220 220 255 220 220 255 220 220 255 220 220 255 225 225 255 225 225 255 225 225 255 225 225 255 230 230 255 230 230 255 230 230 255 230 230 255 235 235 255 235 235 255 235 235 255 235 235 255 240 240 255 240 240 255 240 240 255 240 240 255 245 245 255 245 245 255 245 245 255 245 245 255 250 250 255 250 250 255 250 250 255 250 250 255 255 255 255 255 255 255 xfractint-20.4.10.orig/maps/froth3.map0000644000000000000000000000600010150633601014340 0ustar 0 0 0 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 172 0 0 172 0 0 168 0 0 168 0 0 168 0 0 164 0 0 164 0 0 164 0 0 160 0 0 160 0 0 160 0 0 156 0 0 156 0 0 156 0 0 152 0 0 152 0 0 152 0 0 148 0 0 148 0 0 148 0 0 144 0 0 144 0 0 144 0 0 140 0 0 140 0 0 140 0 0 136 0 0 136 0 0 136 0 0 132 0 0 132 0 0 132 0 0 128 0 0 128 0 0 128 0 0 124 0 0 124 0 0 124 0 0 120 0 0 120 0 0 120 0 0 116 0 0 116 0 0 116 0 0 112 0 0 112 0 0 112 0 0 108 0 0 108 0 0 108 0 0 104 0 0 104 0 0 104 0 0 100 0 0 100 0 0 100 0 0 96 0 0 96 0 0 96 0 0 92 0 0 92 0 0 92 0 0 88 0 0 88 0 0 0 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 172 0 0 172 0 0 168 0 0 168 0 0 168 0 0 164 0 0 164 0 0 164 0 0 160 0 0 160 0 0 160 0 0 156 0 0 156 0 0 156 0 0 152 0 0 152 0 0 152 0 0 148 0 0 148 0 0 148 0 0 144 0 0 144 0 0 144 0 0 140 0 0 140 0 0 140 0 0 136 0 0 136 0 0 136 0 0 132 0 0 132 0 0 132 0 0 128 0 0 128 0 0 128 0 0 124 0 0 124 0 0 124 0 0 120 0 0 120 0 0 120 0 0 116 0 0 116 0 0 116 0 0 112 0 0 112 0 0 112 0 0 108 0 0 108 0 0 108 0 0 104 0 0 104 0 0 104 0 0 100 0 0 100 0 0 100 0 0 96 0 0 96 0 0 96 0 0 92 0 0 92 0 0 92 0 0 88 0 0 88 0 0 0 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 172 0 0 172 0 0 168 0 0 168 0 0 168 0 0 164 0 0 164 0 0 164 0 0 160 0 0 160 0 0 160 0 0 156 0 0 156 0 0 156 0 0 152 0 0 152 0 0 152 0 0 148 0 0 148 0 0 148 0 0 144 0 0 144 0 0 144 0 0 140 0 0 140 0 0 140 0 0 136 0 0 136 0 0 136 0 0 132 0 0 132 0 0 132 0 0 128 0 0 128 0 0 128 0 0 124 0 0 124 0 0 124 0 0 120 0 0 120 0 0 120 0 0 116 0 0 116 0 0 116 0 0 112 0 0 112 0 0 112 0 0 108 0 0 108 0 0 108 0 0 104 0 0 104 0 0 104 0 0 100 0 0 100 0 0 100 0 0 96 0 0 96 0 0 96 0 0 92 0 0 92 0 0 92 0 0 88 0 0 88 xfractint-20.4.10.orig/maps/green.map0000644000000000000000000000610010150633601014234 0ustar 0 0 0 The famous Peterson-Vigneau Pseudo-Grey Sequence 0 252 0 0 252 0 0 248 0 0 248 0 0 248 0 0 248 0 0 244 0 0 244 0 0 244 0 0 244 0 0 240 0 0 240 0 0 240 0 0 240 0 0 236 0 0 236 0 0 236 0 0 236 0 0 232 0 0 232 0 0 232 0 0 232 0 0 228 0 0 228 0 0 228 0 0 228 0 0 224 0 0 224 0 0 224 0 0 224 0 0 220 0 0 220 0 0 220 0 0 220 0 0 216 0 0 216 0 0 216 0 0 216 0 0 212 0 0 212 0 0 212 0 0 212 0 0 208 0 0 208 0 0 208 0 0 208 0 0 204 0 0 204 0 0 204 0 0 204 0 0 200 0 0 200 0 0 200 0 0 200 0 0 196 0 0 196 0 0 196 0 0 196 0 0 192 0 0 192 0 0 192 0 0 192 0 0 188 0 0 188 0 0 188 0 0 188 0 0 184 0 0 184 0 0 184 0 0 184 0 0 180 0 0 180 0 0 180 0 0 180 0 0 176 0 0 176 0 0 176 0 0 176 0 0 172 0 0 172 0 0 172 0 0 172 0 0 168 0 0 168 0 0 168 0 0 168 0 0 164 0 0 164 0 0 164 0 0 164 0 0 160 0 0 160 0 0 160 0 0 160 0 0 156 0 0 156 0 0 156 0 0 156 0 0 152 0 0 152 0 0 152 0 0 152 0 0 148 0 0 148 0 0 148 0 0 148 0 0 144 0 0 144 0 0 144 0 0 144 0 0 140 0 0 140 0 0 140 0 0 140 0 0 136 0 0 136 0 0 136 0 0 136 0 0 132 0 0 132 0 0 132 0 0 132 0 0 128 0 0 128 0 0 128 0 0 128 0 0 124 0 0 124 0 0 124 0 0 124 0 0 120 0 0 120 0 0 120 0 0 120 0 0 116 0 0 116 0 0 116 0 0 116 0 0 112 0 0 112 0 0 112 0 0 112 0 0 108 0 0 108 0 0 108 0 0 108 0 0 104 0 0 104 0 0 104 0 0 104 0 0 100 0 0 100 0 0 100 0 0 100 0 0 96 0 0 96 0 0 96 0 0 96 0 0 92 0 0 92 0 0 92 0 0 92 0 0 88 0 0 88 0 0 88 0 0 88 0 0 84 0 0 84 0 0 84 0 0 84 0 0 80 0 0 80 0 0 80 0 0 80 0 0 76 0 0 76 0 0 76 0 0 76 0 0 72 0 0 72 0 0 72 0 0 72 0 0 68 0 0 68 0 0 68 0 0 68 0 0 64 0 0 64 0 0 64 0 0 64 0 0 60 0 0 60 0 0 60 0 0 60 0 0 56 0 0 56 0 0 56 0 0 56 0 0 52 0 0 52 0 0 52 0 0 52 0 0 48 0 0 48 0 0 48 0 0 48 0 0 44 0 0 44 0 0 44 0 0 44 0 0 40 0 0 40 0 0 40 0 0 40 0 0 36 0 0 36 0 0 36 0 0 36 0 0 32 0 0 32 0 0 32 0 0 32 0 0 28 0 0 28 0 0 28 0 0 28 0 0 24 0 0 24 0 0 24 0 0 24 0 0 20 0 0 20 0 0 20 0 0 20 0 0 16 0 0 16 0 0 16 0 0 16 0 0 12 0 0 12 0 0 12 0 0 12 0 0 8 0 0 8 0 0 8 0 0 8 0 0 4 0 0 4 0 0 4 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 xfractint-20.4.10.orig/maps/headache.map0000644000000000000000000000605310150633601014665 0ustar 0 0 0 headache.map contributed by Daniel Egnor 240 0 0 0 252 0 240 0 0 0 252 0 240 0 0 0 248 4 240 4 0 0 248 4 240 4 0 0 244 8 240 8 0 0 244 8 240 8 0 0 240 12 240 12 0 0 240 12 240 12 0 0 236 16 240 16 0 0 236 16 240 16 0 0 232 20 240 20 0 0 232 20 240 20 0 0 228 24 240 24 0 0 228 24 240 24 0 0 224 28 240 28 0 0 224 28 240 28 0 0 220 32 240 32 0 0 220 32 240 32 0 0 216 36 240 36 0 0 216 36 240 36 0 0 212 40 240 40 0 0 212 40 240 40 0 0 208 44 240 44 0 0 208 44 240 44 0 0 204 48 240 48 0 0 204 48 240 48 0 0 200 52 240 52 0 0 200 52 240 52 0 0 196 56 240 56 0 0 196 56 240 56 0 0 192 60 240 60 0 0 192 60 240 60 0 0 188 64 240 64 0 0 188 64 240 64 0 0 184 68 240 68 0 0 184 68 240 68 0 0 180 72 240 72 0 0 180 72 240 72 0 0 176 76 240 76 0 0 176 76 240 76 0 0 172 80 240 80 0 0 172 80 240 80 0 0 168 84 244 84 0 0 168 84 244 84 0 0 164 88 244 88 0 0 164 88 244 88 0 0 160 92 244 92 0 0 160 92 244 92 0 0 156 96 244 96 0 0 156 96 244 96 0 0 152 100 244 100 0 0 152 100 244 100 0 0 148 104 244 104 0 0 148 104 244 104 0 0 144 108 244 108 0 0 144 108 244 108 0 0 140 112 244 112 0 0 140 112 244 112 0 0 136 116 244 116 0 0 136 116 244 116 0 0 132 120 244 120 0 0 132 120 244 120 0 0 128 124 244 124 0 0 128 124 244 124 0 0 124 128 244 128 0 0 124 128 244 128 0 0 120 132 244 132 0 0 120 132 244 132 0 0 116 136 244 136 0 0 116 136 244 136 0 0 112 140 244 140 0 0 112 140 244 140 0 0 108 144 244 144 0 0 108 144 244 144 0 0 104 148 244 148 0 0 104 148 244 148 0 0 100 152 244 152 0 0 100 152 244 152 0 0 96 156 244 156 0 0 96 156 244 156 0 0 92 160 244 160 0 0 92 160 244 160 0 0 88 164 244 164 0 0 88 164 244 164 0 0 84 168 248 168 0 0 84 168 248 168 0 0 80 172 248 172 0 0 80 172 248 172 0 0 76 176 248 176 0 0 76 176 248 176 0 0 72 180 248 180 0 0 72 180 248 180 0 0 68 184 248 184 0 0 68 184 248 184 0 0 64 188 248 188 0 0 64 188 248 188 0 0 60 192 248 192 0 0 60 192 248 192 0 0 56 196 248 196 0 0 56 196 248 196 0 0 52 200 248 200 0 0 52 200 248 200 0 0 48 204 248 204 0 0 48 204 248 204 0 0 44 208 248 208 0 0 44 208 248 208 0 0 40 212 248 212 0 0 40 212 248 212 0 0 36 216 248 216 0 0 36 216 248 216 0 0 32 220 248 220 0 0 32 220 248 220 0 0 28 224 248 224 0 0 28 224 248 224 0 0 24 228 248 228 0 0 24 228 248 228 0 0 20 232 248 232 0 0 20 232 248 232 0 0 16 236 248 236 0 0 16 236 248 236 0 0 12 240 248 240 0 0 12 240 248 240 0 0 8 244 248 244 0 0 8 244 248 244 0 0 4 248 248 248 0 0 4 248 252 252 0 252 128 0 0 128 128 xfractint-20.4.10.orig/maps/gamma2.map0000644000000000000000000000550010150633601014303 0ustar 0 0 0 Pseudo-gray sequence optimized for images encoded at a gamma near 2.0 0 0 4 Modification of the Peterson/Vigneau Sequence by Lee Daniel Crocker 4 0 0 0 4 0 4 4 4 8 0 8 8 4 8 4 8 8 8 8 8 12 8 4 12 8 12 8 12 12 16 8 16 16 12 8 16 12 16 20 12 12 20 12 20 20 16 12 20 16 20 24 16 16 24 16 24 24 20 16 24 20 24 28 20 20 28 20 28 28 24 20 28 24 28 32 24 24 32 24 32 32 28 24 32 28 32 36 28 28 32 32 28 32 32 36 36 32 36 40 32 32 36 36 32 36 36 40 40 36 40 44 36 36 40 40 36 40 40 44 44 40 44 48 40 40 48 40 48 44 44 48 40 48 44 44 48 44 52 44 52 48 48 52 44 52 48 48 52 48 56 48 56 52 52 56 48 56 52 52 56 52 52 56 60 56 56 60 52 60 56 56 60 56 56 60 64 60 60 64 56 64 60 64 60 68 60 64 68 64 64 68 68 64 64 68 64 72 68 68 60 68 68 68 72 68 68 72 68 76 72 72 64 72 72 72 76 72 72 76 72 80 76 76 68 76 76 76 76 76 84 80 76 84 80 80 72 80 80 80 80 80 88 80 84 76 88 80 84 84 84 84 84 84 92 84 88 80 92 84 88 88 88 88 88 88 96 88 92 84 96 88 92 92 92 92 92 92 100 92 96 88 92 96 96 96 96 96 92 100 92 96 100 92 96 100 100 100 100 100 96 104 96 96 104 104 100 104 104 104 104 100 108 104 100 100 108 108 104 108 108 108 108 104 104 112 104 112 108 112 108 112 112 112 112 108 108 116 108 108 116 116 112 116 116 116 116 112 112 120 112 112 120 120 124 116 116 120 120 116 120 120 124 116 124 124 128 120 120 124 124 120 124 124 128 120 128 128 132 124 124 128 128 124 128 128 132 124 132 132 136 128 128 136 128 136 132 132 136 136 132 132 132 136 132 140 132 140 136 136 140 140 136 136 136 140 136 144 136 144 140 140 144 144 140 140 140 144 140 140 144 148 144 144 148 148 144 144 144 148 144 144 148 152 148 148 152 152 148 148 152 148 156 148 152 156 152 152 152 148 156 152 156 152 160 156 156 148 156 156 156 152 160 156 160 156 164 160 160 152 160 160 160 156 164 160 164 160 168 164 164 156 164 164 164 164 164 172 168 164 172 168 168 160 168 168 168 168 168 176 168 172 164 176 168 172 172 172 172 172 172 180 172 176 168 180 172 176 176 176 176 176 176 184 176 180 172 184 176 180 180 180 180 180 180 188 180 184 176 180 184 184 184 184 184 188 184 180 184 188 180 184 188 188 188 188 184 192 188 184 192 188 192 188 192 192 192 192 188 188 196 188 196 192 196 192 196 196 196 196 192 192 200 192 192 200 200 196 200 200 200 200 196 196 204 196 196 204 204 208 200 200 204 204 200 204 204 208 200 208 208 212 204 204 208 208 204 208 208 212 204 212 212 216 208 208 212 212 208 212 212 216 208 216 216 220 212 212 220 212 220 216 216 220 220 216 216 224 216 216 224 216 224 220 220 224 224 220 220 220 224 220 228 220 228 224 224 228 228 224 224 224 228 224 224 228 232 228 228 232 232 228 228 228 232 228 228 232 236 232 232 236 236 232 232 236 232 240 232 236 240 236 236 236 232 240 236 240 236 244 240 240 232 240 240 240 236 244 240 244 240 248 244 244 236 244 244 244 240 248 244 248 244 252 248 248 240 248 248 248 244 252 248 248 252 244 252 252 244 252 252 252 xfractint-20.4.10.orig/maps/blues.map0000644000000000000000000000605110150633601014253 0ustar 0 0 0 For them rainy days ... by Daniel Egnor 0 0 0 0 0 4 0 0 12 0 0 16 0 0 24 0 0 32 0 0 36 0 0 44 0 0 48 0 0 56 0 0 64 0 0 68 0 0 76 0 0 80 0 0 88 0 0 96 0 0 100 0 0 108 0 0 116 0 0 120 0 0 128 0 0 132 0 0 140 0 0 148 0 0 152 0 0 160 0 0 164 0 0 172 0 0 180 0 0 184 0 0 192 0 0 200 0 4 200 0 12 200 0 16 204 0 24 204 0 28 208 0 36 208 0 40 208 0 48 212 0 56 212 0 60 216 0 68 216 0 72 216 0 80 220 0 84 220 0 92 224 0 100 224 0 104 224 0 112 228 0 116 228 0 124 232 0 128 232 0 136 232 0 140 236 0 148 236 0 156 240 0 160 240 0 168 240 0 172 244 0 180 244 0 184 248 0 192 248 0 200 252 4 200 252 12 200 252 20 204 252 28 204 252 36 208 252 44 208 252 52 208 252 60 212 252 68 212 252 76 216 252 84 216 252 92 216 252 100 220 252 108 220 252 116 224 252 124 224 252 132 224 252 140 228 252 148 228 252 156 232 252 164 232 252 172 232 252 180 236 252 188 236 252 196 240 252 204 240 252 212 240 252 220 244 252 228 244 252 236 248 252 244 248 252 252 252 252 248 252 252 244 252 252 240 252 252 232 252 252 228 252 252 224 252 252 216 252 252 212 252 252 208 252 252 200 252 252 196 252 252 192 252 252 184 252 252 180 252 252 176 252 252 168 252 252 164 252 252 160 252 252 156 252 252 148 252 252 144 252 252 140 252 252 132 252 252 128 252 252 124 252 252 116 252 252 112 252 252 108 252 252 100 252 252 96 252 252 92 252 252 84 252 252 80 252 252 76 252 252 72 252 252 64 252 252 60 252 252 56 252 252 48 252 252 44 252 252 40 252 252 32 252 252 28 252 252 24 252 252 16 252 252 12 252 252 8 252 252 0 252 252 0 248 252 0 244 252 0 240 252 0 232 252 0 228 252 0 224 252 0 216 252 0 212 252 0 208 252 0 200 252 0 196 252 0 192 252 0 184 252 0 180 252 0 176 252 0 168 252 0 164 252 0 160 252 0 156 252 0 148 252 0 144 252 0 140 252 0 132 252 0 128 252 0 124 252 0 116 252 0 112 252 0 108 252 0 100 252 0 96 252 0 92 252 0 84 252 0 80 252 0 76 252 0 72 252 0 64 252 0 60 252 0 56 252 0 48 252 0 44 252 0 40 252 0 32 252 0 28 252 0 24 252 0 16 252 0 12 252 0 8 252 0 0 252 0 0 248 0 0 244 0 0 240 0 0 236 0 0 232 0 0 228 0 0 224 0 0 220 0 0 216 0 0 212 0 0 208 0 0 204 0 0 200 0 0 196 0 0 192 0 0 188 0 0 184 0 0 180 0 0 176 0 0 172 0 0 168 0 0 164 0 0 160 0 0 156 0 0 152 0 0 148 0 0 144 0 0 140 0 0 136 0 0 132 0 0 128 0 0 124 0 0 120 0 0 116 0 0 112 0 0 108 0 0 104 0 0 100 0 0 96 0 0 92 0 0 88 0 0 84 0 0 80 0 0 76 0 0 72 0 0 68 0 0 64 0 0 60 0 0 56 0 0 52 0 0 48 0 0 44 0 0 40 0 0 36 0 0 32 0 0 28 0 0 24 0 0 20 0 0 16 0 0 12 0 0 8 0 0 0 0 0 0 xfractint-20.4.10.orig/maps/defaultw.map0000644000000000000000000000606410400460601014754 0ustar 0 0 0 A reasonable default 256-color map for Windows 0 0 188 0 188 0 188 188 0 188 0 0 188 0 188 0 188 188 192 192 192 192 220 192 164 200 240 128 0 0 0 128 0 128 128 0 0 0 128 128 0 128 0 128 128 60 92 60 92 92 60 124 92 60 156 92 60 188 92 60 220 92 60 252 92 60 60 124 60 92 124 60 124 124 60 156 124 60 188 124 60 220 124 60 252 124 60 60 156 60 92 156 60 124 156 60 156 156 60 188 156 60 220 156 60 252 156 60 60 188 60 92 188 60 124 188 60 156 188 60 188 188 60 220 188 60 252 188 60 60 220 60 92 220 60 124 220 60 156 220 60 188 220 60 220 220 60 252 220 60 60 252 60 92 252 60 124 252 60 156 252 60 188 252 60 220 252 60 252 252 60 60 60 92 92 60 92 124 60 92 156 60 92 188 60 92 220 60 92 252 60 92 60 92 92 92 92 92 124 92 92 156 92 92 188 92 92 220 92 92 252 92 92 60 124 92 92 124 92 124 124 92 156 124 92 188 124 92 220 124 92 252 124 92 60 156 92 92 156 92 124 156 92 156 156 92 188 156 92 220 156 92 252 156 92 60 188 92 92 188 92 124 188 92 156 188 92 188 188 92 220 188 92 252 188 92 60 220 92 92 220 92 124 220 92 156 220 92 188 220 92 220 220 92 252 220 92 60 252 92 92 252 92 124 252 92 156 252 92 188 252 92 220 252 92 252 252 92 60 60 124 92 60 124 124 60 124 156 60 124 188 60 124 220 60 124 252 60 124 60 92 124 92 92 124 124 92 124 156 92 124 188 92 124 220 92 124 252 92 124 60 124 124 92 124 124 124 124 124 156 124 124 188 124 124 220 124 124 252 124 124 60 156 124 92 156 124 124 156 124 156 156 124 188 156 124 220 156 124 252 156 124 60 188 124 92 188 124 124 188 124 156 188 124 188 188 124 220 188 124 252 188 124 60 220 124 92 220 124 124 220 124 156 220 124 188 220 124 220 220 124 252 220 124 60 252 124 92 252 124 124 252 124 156 252 124 188 252 124 220 252 124 252 252 124 60 60 156 92 60 156 124 60 156 156 60 156 188 60 156 220 60 156 252 60 156 60 92 156 92 92 156 124 92 156 156 92 156 188 92 156 220 92 156 252 92 156 60 124 156 92 124 156 124 124 156 156 124 156 188 124 156 220 124 156 252 124 156 60 156 156 92 156 156 124 156 156 156 156 156 188 156 156 220 156 156 252 156 156 60 188 156 92 188 156 124 188 156 156 188 156 188 188 156 220 188 156 252 188 156 60 220 156 92 220 156 124 220 156 156 220 156 188 220 156 220 220 156 252 220 156 60 252 156 92 252 156 124 252 156 156 252 156 188 252 156 220 252 156 252 252 156 60 60 188 92 60 188 124 60 188 156 60 188 188 60 188 220 60 188 252 60 188 60 92 188 92 92 188 124 92 188 156 92 188 188 92 188 220 92 188 252 92 188 60 124 188 92 124 188 124 124 188 156 124 188 188 124 188 220 124 188 252 124 188 60 156 188 92 156 188 124 156 188 156 156 188 188 156 188 220 156 188 252 156 188 60 188 188 92 188 188 124 188 188 156 188 188 188 188 188 220 188 188 252 188 188 60 220 188 92 220 188 124 220 188 156 220 188 188 220 188 220 220 188 252 248 240 160 160 164 128 128 128 252 0 0 0 252 0 252 252 0 0 0 252 252 0 252 0 252 252 252 252 252 xfractint-20.4.10.orig/maps/firestrm.map0000644000000000000000000000605410150633601014777 0ustar 0 0 0 "Fire Storm" Palette Map by Mark Peterson 144 10 229 147 9 227 150 8 225 153 6 223 156 6 221 159 5 218 162 4 216 165 3 214 168 2 212 171 2 209 174 1 207 177 1 204 180 1 202 183 0 199 186 0 197 189 0 194 191 0 191 194 0 189 197 0 186 199 0 183 202 1 180 204 1 177 207 1 174 209 2 171 212 2 168 214 3 165 216 4 162 218 5 159 221 6 156 223 6 153 225 8 150 227 9 147 229 10 144 231 11 141 232 12 138 234 14 135 236 15 131 238 17 128 239 18 125 241 20 122 242 22 119 243 23 116 245 25 113 246 27 109 247 29 106 248 31 103 249 33 100 250 35 97 251 38 94 252 40 91 252 42 88 253 45 85 253 47 82 254 49 79 254 52 76 255 54 73 255 57 71 255 60 68 255 62 65 255 65 62 255 68 60 255 71 57 255 73 54 254 76 52 254 79 49 253 82 47 253 85 45 252 88 42 252 91 40 251 94 38 250 97 35 249 100 33 248 103 31 247 106 29 246 109 27 245 113 25 243 116 23 242 119 22 241 122 20 239 125 18 238 128 17 236 131 15 234 135 14 232 138 12 231 141 11 229 144 10 227 147 9 225 150 8 223 153 6 221 156 6 218 159 5 216 162 4 214 165 3 212 168 2 209 171 2 207 174 1 204 177 1 202 180 1 199 183 0 197 186 0 194 189 0 191 191 0 189 194 0 186 197 0 183 199 0 180 202 1 177 204 1 174 207 1 171 209 2 168 212 2 165 214 3 162 216 4 159 218 5 156 221 6 153 223 6 150 225 8 147 227 9 144 229 10 141 231 11 138 232 12 135 234 14 131 236 15 128 238 17 125 239 18 122 241 20 119 242 22 116 243 23 113 245 25 109 246 27 106 247 29 103 248 31 100 249 33 97 250 35 94 251 38 91 252 40 88 252 42 85 253 45 82 253 47 79 254 49 76 254 52 73 255 54 71 255 57 68 255 60 65 255 62 62 255 65 60 255 68 57 255 71 54 255 73 52 254 76 49 254 79 47 253 82 45 253 85 42 252 88 40 252 91 38 251 94 35 250 97 33 249 100 31 248 103 29 247 106 27 246 109 25 245 113 23 243 116 22 242 119 20 241 122 18 239 125 17 238 128 15 236 131 14 234 135 12 232 138 11 231 141 10 229 144 9 227 147 8 225 150 6 223 153 6 221 156 5 218 159 4 216 162 3 214 165 2 212 168 2 209 171 1 207 174 1 204 177 1 202 180 0 199 183 0 197 186 0 194 189 0 191 191 0 189 194 0 186 197 0 183 199 1 180 202 1 177 204 1 174 207 2 171 209 2 168 212 3 165 214 4 162 216 5 159 218 6 156 221 6 153 223 8 150 225 9 147 227 10 144 229 11 141 231 12 138 232 14 135 234 15 131 236 17 128 238 18 125 239 20 122 241 22 119 242 23 116 243 25 113 245 27 109 246 29 106 247 31 103 248 33 100 249 35 97 250 38 94 251 40 91 252 42 88 252 45 85 253 47 82 253 49 79 254 52 76 254 54 73 255 57 71 255 60 68 255 62 65 255 65 62 255 68 60 255 71 57 255 73 54 255 76 52 254 79 49 254 82 47 253 85 45 253 88 42 252 91 40 252 94 38 251 97 35 250 100 33 249 103 31 248 106 29 247 109 27 246 113 25 245 116 23 243 119 22 242 122 20 241 125 18 239 128 17 238 131 15 236 135 14 234 138 12 232 141 11 230 xfractint-20.4.10.orig/maps/froth316.map0000644000000000000000000000030010150633601014504 0ustar 0 0 0 252 0 0 212 0 0 168 0 0 124 0 0 80 0 0 0 252 0 0 212 0 0 168 0 0 124 0 0 80 0 0 0 252 0 0 212 0 0 168 0 0 124 0 0 80 xfractint-20.4.10.orig/maps/paintjet.map0000644000000000000000000000045010150633601014754 0ustar 24 20 12 A map with the PaintJet's 8 primary colors repeated twice. 244 240 232 Use these colors for 180dpi PaintJet images. 196 68 72 48 132 92 240 232 72 52 48 116 188 48 108 40 116 196 24 20 12 244 240 232 196 68 72 48 132 92 240 232 72 52 48 116 188 48 108 40 116 196 xfractint-20.4.10.orig/maps/altern.map0000644000000000000000000000610010150633601014421 0ustar 0 0 0 The famous Peterson-Vigneau Pseudo-Grey Sequence 252 252 252 248 252 252 252 248 252 252 248 248 248 248 248 244 248 248 248 244 252 248 244 244 244 244 244 240 244 244 244 240 248 244 240 240 240 240 240 236 240 240 240 236 244 240 236 236 236 236 236 232 236 236 236 232 240 236 232 232 232 232 232 228 232 232 232 228 236 232 228 228 228 228 228 224 228 228 228 224 232 228 224 224 224 224 224 220 224 224 224 220 228 224 220 220 220 220 220 216 220 220 220 216 224 220 216 216 216 216 216 212 216 216 216 212 220 216 212 212 212 212 212 208 212 212 212 208 216 212 208 208 208 208 208 204 208 208 208 204 212 208 204 204 204 204 204 200 204 204 204 200 208 204 200 200 200 200 200 196 200 200 200 196 204 200 196 196 196 196 196 192 196 196 196 192 200 196 192 192 192 192 192 188 192 192 192 188 196 192 188 188 188 188 188 184 188 188 188 184 192 188 184 184 184 184 184 180 184 184 184 180 188 184 180 180 180 180 180 176 180 180 180 176 184 180 176 176 176 176 176 172 176 176 176 172 180 176 172 172 172 172 172 168 172 172 172 168 176 172 168 168 168 168 168 164 168 168 168 164 172 168 164 164 164 164 164 160 164 164 164 160 168 164 160 160 160 160 160 156 160 160 160 156 164 160 156 156 156 156 156 152 156 156 156 152 160 156 152 152 152 152 152 148 152 152 152 148 156 152 148 148 148 148 148 144 148 148 148 144 152 148 144 144 144 144 144 140 144 144 144 140 148 144 140 140 140 140 140 136 140 140 140 136 144 140 136 136 136 136 136 132 136 136 136 132 140 136 132 132 132 132 132 128 132 132 132 128 136 132 128 128 128 128 128 124 128 128 128 124 132 128 124 124 124 124 124 120 124 124 124 120 128 124 120 120 120 120 120 116 120 120 120 116 124 120 116 116 116 116 116 112 116 116 116 112 120 116 112 112 112 112 112 108 112 112 112 108 116 112 108 108 108 108 108 104 108 108 108 104 112 108 104 104 104 104 104 100 104 104 104 100 108 104 100 100 100 100 100 96 100 100 100 96 104 100 96 96 96 96 96 92 96 96 96 92 100 96 92 92 92 92 92 88 92 92 92 88 96 92 88 88 88 88 88 84 88 88 88 84 92 88 84 84 84 84 84 80 84 84 84 80 88 84 80 80 80 80 80 76 80 80 80 76 84 80 76 76 76 76 76 72 76 76 76 72 80 76 72 72 72 72 72 68 72 72 72 68 76 72 68 68 68 68 68 64 68 68 68 64 72 68 64 64 64 64 64 60 64 64 64 60 68 64 60 60 60 60 60 56 60 60 60 56 64 60 56 56 56 56 56 52 56 56 56 52 60 56 52 52 52 52 52 48 52 52 52 48 56 52 48 48 48 48 48 44 48 48 48 44 52 48 44 44 44 44 44 40 44 44 44 40 48 44 40 40 40 40 40 36 40 40 40 36 44 40 36 36 36 36 36 32 36 36 36 32 40 36 32 32 32 32 32 28 32 32 32 28 36 32 28 28 28 28 28 24 28 28 28 24 32 28 24 24 24 24 24 20 24 24 24 20 28 24 20 20 20 20 20 16 20 20 20 16 24 20 16 16 16 16 16 12 16 16 16 12 20 16 12 12 12 12 12 8 12 12 12 8 16 12 8 8 8 8 8 4 8 8 8 4 12 8 4 4 4 4 4 0 4 4 4 0 8 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 xfractint-20.4.10.orig/maps/glasses1.map0000644000000000000000000000600010150633601014655 0ustar 0 0 0 0 0 0 4 0 0 4 0 0 8 0 0 8 0 0 12 0 0 12 0 0 16 0 0 16 0 0 20 0 0 20 0 0 24 0 0 24 0 0 28 0 0 28 0 0 32 0 0 32 0 0 36 0 0 36 0 0 40 0 0 40 0 0 44 0 0 44 0 0 48 0 0 48 0 0 52 0 0 52 0 0 56 0 0 56 0 0 60 0 0 60 0 0 64 0 0 64 0 0 68 0 0 68 0 0 72 0 0 72 0 0 76 0 0 76 0 0 80 0 0 80 0 0 84 0 0 84 0 0 88 0 0 88 0 0 92 0 0 92 0 0 96 0 0 96 0 0 100 0 0 100 0 0 104 0 0 104 0 0 108 0 0 108 0 0 112 0 0 112 0 0 116 0 0 116 0 0 120 0 0 120 0 0 124 0 0 124 0 0 128 0 0 128 0 0 132 0 0 132 0 0 136 0 0 136 0 0 140 0 0 140 0 0 144 0 0 144 0 0 148 0 0 148 0 0 152 0 0 152 0 0 156 0 0 156 0 0 160 0 0 160 0 0 164 0 0 164 0 0 168 0 0 168 0 0 172 0 0 172 0 0 176 0 0 176 0 0 180 0 0 180 0 0 184 0 0 184 0 0 188 0 0 188 0 0 192 0 0 192 0 0 196 0 0 196 0 0 200 0 0 200 0 0 204 0 0 204 0 0 208 0 0 208 0 0 212 0 0 212 0 0 216 0 0 216 0 0 220 0 0 220 0 0 224 0 0 224 0 0 228 0 0 228 0 0 232 0 0 232 0 0 236 0 0 236 0 0 240 0 0 240 0 0 244 0 0 244 0 0 248 0 0 248 0 0 252 0 0 252 0 0 0 0 0 0 0 0 0 0 4 0 0 4 0 0 8 0 0 8 0 0 12 0 0 12 0 0 16 0 0 16 0 0 20 0 0 20 0 0 24 0 0 24 0 0 28 0 0 28 0 0 32 0 0 32 0 0 36 0 0 36 0 0 40 0 0 40 0 0 44 0 0 44 0 0 48 0 0 48 0 0 52 0 0 52 0 0 56 0 0 56 0 0 60 0 0 60 0 0 64 0 0 64 0 0 68 0 0 68 0 0 72 0 0 72 0 0 76 0 0 76 0 0 80 0 0 80 0 0 84 0 0 84 0 0 88 0 0 88 0 0 92 0 0 92 0 0 96 0 0 96 0 0 100 0 0 100 0 0 104 0 0 104 0 0 108 0 0 108 0 0 112 0 0 112 0 0 116 0 0 116 0 0 120 0 0 120 0 0 124 0 0 124 0 0 128 0 0 128 0 0 132 0 0 132 0 0 136 0 0 136 0 0 140 0 0 140 0 0 144 0 0 144 0 0 148 0 0 148 0 0 152 0 0 152 0 0 156 0 0 156 0 0 160 0 0 160 0 0 164 0 0 164 0 0 168 0 0 168 0 0 172 0 0 172 0 0 176 0 0 176 0 0 180 0 0 180 0 0 184 0 0 184 0 0 188 0 0 188 0 0 192 0 0 192 0 0 196 0 0 196 0 0 200 0 0 200 0 0 204 0 0 204 0 0 208 0 0 208 0 0 212 0 0 212 0 0 216 0 0 216 0 0 220 0 0 220 0 0 224 0 0 224 0 0 228 0 0 228 0 0 232 0 0 232 0 0 236 0 0 236 0 0 240 0 0 240 0 0 244 0 0 244 0 0 248 0 0 248 0 0 252 0 0 252 xfractint-20.4.10.orig/maps/royal.map0000644000000000000000000000604110150633601014266 0ustar 0 0 0 The royal purple ... by D. Egnor 60 0 80 60 0 80 60 0 84 64 0 84 64 0 84 64 0 88 64 0 88 68 0 88 68 0 92 68 0 92 68 0 92 72 0 96 72 0 96 72 0 96 72 0 100 76 0 100 76 0 100 76 0 104 76 0 104 76 0 104 80 0 104 80 0 108 80 0 108 80 0 108 84 0 112 84 0 112 84 0 112 84 0 116 88 0 116 88 0 116 88 0 120 88 0 120 92 0 120 92 0 124 92 0 124 92 0 124 96 0 128 96 0 128 96 0 128 96 0 132 96 0 132 100 0 132 100 0 132 100 0 136 100 0 136 104 0 136 104 0 140 104 0 140 104 0 140 108 0 144 108 0 144 108 0 144 108 0 148 112 0 148 112 0 148 112 0 152 112 0 152 116 0 152 116 0 156 116 0 156 116 0 156 120 0 160 120 0 160 124 4 160 124 8 164 128 12 164 128 16 164 132 20 168 132 24 168 136 28 168 136 32 172 140 36 172 140 40 172 144 44 176 144 48 176 148 52 180 148 56 180 152 60 180 152 64 184 156 68 184 156 72 184 160 76 188 160 80 188 164 84 188 164 88 192 168 92 192 168 96 192 172 100 196 172 104 196 176 108 200 176 112 200 180 116 200 180 120 204 184 124 204 188 128 204 188 132 208 192 136 208 192 140 208 196 144 212 196 148 212 200 152 216 200 156 216 204 160 216 204 164 220 208 168 220 208 172 220 212 176 224 212 180 224 216 184 224 216 188 228 220 192 228 220 196 228 224 200 232 224 204 232 228 208 236 228 212 236 232 216 236 232 220 240 236 224 240 236 228 240 240 232 244 240 236 244 244 240 244 244 244 248 248 248 248 252 252 252 252 252 252 252 252 248 252 252 244 252 252 240 252 252 236 252 252 232 252 252 228 252 252 224 252 252 220 252 252 216 252 252 212 252 252 208 252 252 204 252 252 200 252 252 196 252 252 192 252 252 188 252 252 184 252 252 180 252 252 176 252 252 172 252 252 168 252 252 164 252 252 160 252 252 156 252 252 152 252 252 148 252 252 144 252 252 140 252 252 136 252 252 132 252 252 128 252 252 124 252 252 120 252 252 116 252 252 112 252 252 108 252 252 104 252 252 100 252 252 96 252 252 92 252 252 88 252 252 84 252 252 80 252 252 76 252 252 72 252 252 68 252 252 64 252 252 60 252 252 56 252 252 52 252 252 48 252 252 44 252 252 40 252 252 36 252 252 32 252 252 28 252 252 24 252 252 20 252 252 16 252 252 12 252 252 8 252 252 4 252 252 0 252 248 0 248 244 0 244 240 0 240 236 4 240 232 4 236 228 4 232 224 8 228 220 8 228 216 8 224 212 12 220 208 12 216 204 12 212 200 16 212 196 16 208 192 16 204 188 20 200 184 20 200 180 20 196 176 24 192 172 24 188 168 24 184 164 28 184 160 28 180 156 28 176 152 32 172 148 32 172 144 32 168 140 36 164 136 36 160 132 36 160 128 36 156 124 40 152 120 40 148 116 40 144 112 44 144 108 44 140 104 44 136 100 48 132 96 48 132 92 48 128 88 52 124 84 52 120 80 52 116 76 56 116 72 56 112 68 56 108 64 60 104 60 60 104 56 60 100 52 64 96 48 64 92 44 64 88 40 68 88 36 68 84 32 68 80 28 72 76 24 72 76 20 72 72 16 76 68 12 76 64 8 76 60 0 80 60 0 80 60 0 80 60 0 80 xfractint-20.4.10.orig/maps/lyapunov.map0000644000000000000000000000600010150633601015010 0ustar 0 0 0 252 192 0 252 192 0 252 192 0 252 192 0 248 188 0 248 188 0 248 188 0 248 188 0 244 184 0 244 184 0 244 184 0 244 184 0 240 180 0 240 180 0 240 180 0 240 180 0 236 176 0 236 176 0 236 176 0 236 176 0 232 172 0 232 172 0 232 172 0 232 172 0 228 168 0 228 168 0 228 168 0 228 168 0 224 164 0 224 164 0 224 164 0 224 164 0 220 160 0 220 160 0 220 160 0 220 160 0 216 156 0 216 156 0 216 156 0 216 156 0 212 152 0 212 152 0 212 152 0 212 152 0 208 148 0 208 148 0 208 148 0 208 148 0 204 144 0 204 144 0 204 144 0 204 144 0 200 140 0 200 140 0 200 140 0 200 140 0 196 136 0 196 136 0 196 136 0 196 136 0 192 132 0 192 132 0 192 132 0 192 132 0 188 128 0 188 128 0 188 128 0 188 128 0 184 124 0 184 124 0 184 124 0 184 124 0 180 120 0 180 120 0 180 120 0 180 120 0 176 116 0 176 116 0 176 116 0 176 116 0 172 112 0 172 112 0 172 112 0 172 112 0 168 108 0 168 108 0 168 108 0 168 108 0 164 104 0 164 104 0 164 104 0 164 104 0 160 100 0 160 100 0 160 100 0 160 100 0 156 96 0 156 96 0 156 96 0 156 96 0 152 92 0 152 92 0 152 92 0 152 92 0 148 88 0 148 88 0 148 88 0 148 88 0 144 84 0 144 84 0 144 84 0 144 84 0 140 80 0 140 80 0 140 80 0 140 80 0 136 76 0 136 76 0 136 76 0 136 76 0 132 72 0 132 72 0 132 72 0 132 72 0 128 68 0 128 68 0 128 68 0 128 68 0 124 64 0 124 64 0 124 64 0 124 64 0 120 60 0 120 60 0 120 60 0 120 60 0 116 56 0 116 56 0 116 56 0 116 56 0 112 52 0 112 52 0 112 52 0 112 52 0 108 48 0 108 48 0 108 48 0 108 48 0 104 44 0 104 44 0 104 44 0 104 44 0 100 40 0 100 40 0 100 40 0 100 40 0 96 36 0 96 36 0 96 36 0 96 36 0 92 32 0 92 32 0 92 32 0 92 32 0 88 28 0 88 28 0 88 28 0 88 28 0 84 24 0 84 24 0 84 24 0 84 24 0 80 20 0 80 20 0 80 20 0 80 20 0 76 16 0 76 16 0 76 16 0 76 16 0 72 12 0 72 12 0 72 12 0 72 12 0 68 8 0 68 8 0 68 8 0 68 8 0 64 4 0 64 4 0 64 4 0 64 4 0 60 0 0 60 0 0 60 0 0 60 0 0 56 0 0 56 0 0 56 0 0 56 0 0 52 0 0 52 0 0 52 0 0 52 0 0 48 0 0 48 0 0 48 0 0 48 0 0 44 0 0 44 0 0 44 0 0 44 0 0 40 0 0 40 0 0 40 0 0 40 0 0 36 0 0 36 0 0 36 0 0 36 0 0 32 0 0 32 0 0 32 0 0 32 0 0 28 0 0 28 0 0 28 0 0 28 0 0 24 0 0 24 0 0 24 0 0 24 0 0 20 0 0 20 0 0 20 0 0 20 0 0 16 0 0 16 0 0 16 0 0 16 0 0 12 0 0 12 0 0 12 0 0 12 0 0 8 0 0 8 0 0 8 0 0 8 0 0 4 0 0 4 0 0 4 0 0 4 0 0 0 0 0 0 0 0 0 0 0 xfractint-20.4.10.orig/maps/glasses2.map0000644000000000000000000000600010150633601014656 0ustar 0 0 0 16 0 0 32 0 0 48 0 0 64 0 0 80 0 0 96 0 0 112 0 0 128 0 0 144 0 0 160 0 0 176 0 0 192 0 0 208 0 0 224 0 0 240 0 0 0 0 16 16 0 16 32 0 16 48 0 16 64 0 16 80 0 16 96 0 16 112 0 16 128 0 16 144 0 16 160 0 16 176 0 16 192 0 16 208 0 16 224 0 16 240 0 16 0 0 32 16 0 32 32 0 32 48 0 32 64 0 32 80 0 32 96 0 32 112 0 32 128 0 32 144 0 32 160 0 32 176 0 32 192 0 32 208 0 32 224 0 32 240 0 32 0 0 48 16 0 48 32 0 48 48 0 48 64 0 48 80 0 48 96 0 48 112 0 48 128 0 48 144 0 48 160 0 48 176 0 48 192 0 48 208 0 48 224 0 48 240 0 48 0 0 64 16 0 64 32 0 64 48 0 64 64 0 64 80 0 64 96 0 64 112 0 64 128 0 64 144 0 64 160 0 64 176 0 64 192 0 64 208 0 64 224 0 64 240 0 64 0 0 80 16 0 80 32 0 80 48 0 80 64 0 80 80 0 80 96 0 80 112 0 80 128 0 80 144 0 80 160 0 80 176 0 80 192 0 80 208 0 80 224 0 80 240 0 80 0 0 96 16 0 96 32 0 96 48 0 96 64 0 96 80 0 96 96 0 96 112 0 96 128 0 96 144 0 96 160 0 96 176 0 96 192 0 96 208 0 96 224 0 96 240 0 96 0 0 112 16 0 112 32 0 112 48 0 112 64 0 112 80 0 112 96 0 112 112 0 112 128 0 112 144 0 112 160 0 112 176 0 112 192 0 112 208 0 112 224 0 112 240 0 112 0 0 128 16 0 128 32 0 128 48 0 128 64 0 128 80 0 128 96 0 128 112 0 128 128 0 128 144 0 128 160 0 128 176 0 128 192 0 128 208 0 128 224 0 128 240 0 128 0 0 144 16 0 144 32 0 144 48 0 144 64 0 144 80 0 144 96 0 144 112 0 144 128 0 144 144 0 144 160 0 144 176 0 144 192 0 144 208 0 144 224 0 144 240 0 144 0 0 160 16 0 160 32 0 160 48 0 160 64 0 160 80 0 160 96 0 160 112 0 160 128 0 160 144 0 160 160 0 160 176 0 160 192 0 160 208 0 160 224 0 160 240 0 160 0 0 176 16 0 176 32 0 176 48 0 176 64 0 176 80 0 176 96 0 176 112 0 176 128 0 176 144 0 176 160 0 176 176 0 176 192 0 176 208 0 176 224 0 176 240 0 176 0 0 192 16 0 192 32 0 192 48 0 192 64 0 192 80 0 192 96 0 192 112 0 192 128 0 192 144 0 192 160 0 192 176 0 192 192 0 192 208 0 192 224 0 192 240 0 192 0 0 208 16 0 208 32 0 208 48 0 208 64 0 208 80 0 208 96 0 208 112 0 208 128 0 208 144 0 208 160 0 208 176 0 208 192 0 208 208 0 208 224 0 208 240 0 208 0 0 224 16 0 224 32 0 224 48 0 224 64 0 224 80 0 224 96 0 224 112 0 224 128 0 224 144 0 224 160 0 224 176 0 224 192 0 224 208 0 224 224 0 224 240 0 224 0 0 240 16 0 240 32 0 240 48 0 240 64 0 240 80 0 240 96 0 240 112 0 240 128 0 240 144 0 240 160 0 240 176 0 240 192 0 240 208 0 240 224 0 240 240 0 240 xfractint-20.4.10.orig/maps/grid.map0000644000000000000000000000600110150633601014061 0ustar 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 xfractint-20.4.10.orig/maps/froth616.map0000644000000000000000000000030010150633601014507 0ustar 0 0 0 252 0 252 160 0 160 252 0 0 160 0 0 252 252 0 160 160 0 0 252 0 0 160 0 0 0 252 0 0 160 0 252 252 0 160 160 0 0 0 0 0 0 252 252 252 xfractint-20.4.10.orig/maps/volcano.map0000644000000000000000000000604510150633601014605 0ustar 0 0 0 An explosion of lava ... by D. Egnor 60 60 60 64 60 60 72 60 60 76 56 56 84 56 56 88 52 52 96 52 52 100 48 48 108 48 48 112 44 44 120 44 44 128 40 40 132 40 40 140 36 36 144 36 36 152 32 32 156 32 32 164 28 28 168 28 28 176 24 24 180 24 24 188 20 20 196 20 20 200 16 16 208 16 16 212 12 12 220 12 12 224 8 8 232 8 8 236 4 4 244 4 4 252 0 0 252 4 0 252 12 0 252 20 0 252 28 0 252 36 0 252 44 0 252 52 0 252 60 0 252 68 0 252 76 0 252 84 0 252 92 0 252 100 0 252 108 0 252 116 0 252 124 0 252 132 0 252 140 0 252 148 0 252 156 0 252 164 0 252 172 0 252 180 0 252 188 0 252 196 0 252 204 0 252 212 0 252 220 0 252 228 0 252 236 0 252 244 0 252 252 0 252 252 4 252 252 12 252 252 20 252 252 28 252 252 36 252 252 44 252 252 52 252 252 60 252 252 68 252 252 76 252 252 84 252 252 92 252 252 100 252 252 108 252 252 116 252 252 124 252 252 132 252 252 140 252 252 148 252 252 156 252 252 164 252 252 172 252 252 180 252 252 188 252 252 196 252 252 204 252 252 212 252 252 220 252 252 228 252 252 236 252 252 244 252 252 252 252 252 252 252 248 248 252 248 244 252 244 240 252 244 236 252 240 232 252 240 228 252 236 224 252 236 220 252 232 216 252 232 212 252 228 208 252 228 204 252 224 200 252 224 196 252 220 192 252 220 188 252 216 184 252 216 180 252 212 176 252 212 172 252 208 168 252 208 164 252 204 160 252 204 156 252 200 152 252 200 148 252 196 144 252 196 140 252 192 136 252 192 132 252 188 128 252 184 124 252 184 120 252 180 116 252 180 112 252 176 108 252 176 104 252 172 100 252 172 96 252 168 92 252 168 88 252 164 84 252 164 80 252 160 76 252 160 72 252 156 68 252 156 64 252 152 60 252 152 56 252 148 52 252 148 48 252 144 44 252 144 40 252 140 36 252 140 32 252 136 28 252 136 24 252 132 20 252 132 16 252 128 12 252 128 8 252 124 4 252 120 0 252 120 0 252 116 0 252 112 0 252 108 0 252 104 0 252 100 0 252 96 0 252 92 0 252 88 0 252 84 0 252 80 0 252 76 0 252 72 0 252 68 0 252 64 0 252 60 0 252 60 0 252 56 0 252 52 0 252 48 0 252 44 0 252 40 0 252 36 0 252 32 0 252 28 0 252 24 0 252 20 0 252 16 0 252 12 0 252 8 0 252 4 0 252 0 0 252 0 0 248 0 0 244 0 0 244 0 0 240 0 0 236 0 0 232 0 0 232 0 0 228 0 0 224 0 0 224 0 0 220 0 0 216 0 0 212 0 0 212 0 0 208 0 0 204 0 0 204 0 0 200 0 0 196 0 0 192 0 0 192 0 0 188 0 0 184 0 0 184 0 0 180 0 0 176 0 0 172 0 0 172 0 0 168 0 0 164 0 0 160 0 0 160 0 0 156 4 4 152 4 4 148 8 8 144 8 8 140 12 12 140 12 12 136 16 16 132 16 16 128 20 20 124 20 20 120 24 24 120 24 24 116 28 28 112 28 28 108 32 32 104 32 32 100 36 36 100 36 36 96 40 40 92 40 40 88 44 44 84 44 44 80 48 48 80 48 48 76 52 52 72 52 52 68 56 56 64 56 56 60 60 60 60 60 60 xfractint-20.4.10.orig/maps/default.map0000644000000000000000000000475210150633601014573 0ustar 0 0 0 The default VGA color map 0 0 168 0 168 0 0 168 168 168 0 0 168 0 168 168 84 0 168 168 168 84 84 84 84 84 252 84 252 84 84 252 252 252 84 84 252 84 252 252 252 84 252 252 252 0 0 0 20 20 20 32 32 32 44 44 44 56 56 56 68 68 68 80 80 80 96 96 96 112 112 112 128 128 128 144 144 144 160 160 160 180 180 180 200 200 200 224 224 224 252 252 252 0 0 252 64 0 252 124 0 252 188 0 252 252 0 252 252 0 188 252 0 124 252 0 64 252 0 0 252 64 0 252 124 0 252 188 0 252 252 0 188 252 0 124 252 0 64 252 0 0 252 0 0 252 64 0 252 124 0 252 188 0 252 252 0 188 252 0 124 252 0 64 252 124 124 252 156 124 252 188 124 252 220 124 252 252 124 252 252 124 220 252 124 188 252 124 156 252 124 124 252 156 124 252 188 124 252 220 124 252 252 124 220 252 124 188 252 124 156 252 124 124 252 124 124 252 156 124 252 188 124 252 220 124 252 252 124 220 252 124 188 252 124 156 252 180 180 252 196 180 252 216 180 252 232 180 252 252 180 252 252 180 232 252 180 216 252 180 196 252 180 180 252 196 180 252 216 180 252 232 180 252 252 180 232 252 180 216 252 180 196 252 180 180 252 180 180 252 196 180 252 216 180 252 232 180 252 252 180 232 252 180 216 252 180 196 252 0 0 112 28 0 112 56 0 112 84 0 112 112 0 112 112 0 84 112 0 56 112 0 28 112 0 0 112 28 0 112 56 0 112 84 0 112 112 0 84 112 0 56 112 0 28 112 0 0 112 0 0 112 28 0 112 56 0 112 84 0 112 112 0 84 112 0 56 112 0 28 112 56 56 112 68 56 112 84 56 112 96 56 112 112 56 112 112 56 96 112 56 84 112 56 68 112 56 56 112 68 56 112 84 56 112 96 56 112 112 56 96 112 56 84 112 56 68 112 56 56 112 56 56 112 68 56 112 84 56 112 96 56 112 112 56 96 112 56 84 112 56 68 112 80 80 112 88 80 112 96 80 112 104 80 112 112 80 112 112 80 104 112 80 96 112 80 88 112 80 80 112 88 80 112 96 80 112 104 80 112 112 80 104 112 80 96 112 80 88 112 80 80 112 80 80 112 88 80 112 96 80 112 104 80 112 112 80 104 112 80 96 112 80 88 112 0 0 64 16 0 64 32 0 64 48 0 64 64 0 64 64 0 48 64 0 32 64 0 16 64 0 0 64 16 0 64 32 0 64 48 0 64 64 0 48 64 0 32 64 0 16 64 0 0 64 0 0 64 16 0 64 32 0 64 48 0 64 64 0 48 64 0 32 64 0 16 64 32 32 64 40 32 64 48 32 64 56 32 64 64 32 64 64 32 56 64 32 48 64 32 40 64 32 32 64 40 32 64 48 32 64 56 32 64 64 32 56 64 32 48 64 32 40 64 32 32 64 32 32 64 40 32 64 48 32 64 56 32 64 64 32 56 64 32 48 64 32 40 64 44 44 64 48 44 64 52 44 64 60 44 64 64 44 64 64 44 60 64 44 52 64 44 48 64 44 44 64 48 44 64 52 44 64 60 44 64 64 44 60 64 44 52 64 44 48 64 44 44 64 44 44 64 48 44 64 52 44 64 60 44 64 64 44 60 64 44 52 64 44 48 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 xfractint-20.4.10.orig/maps/topo.map0000644000000000000000000000612310150633601014122 0ustar 0 0 0 "Topographic" color map - M. Davis 0 0 168 4 0 172 4 8 172 4 12 172 4 16 172 8 20 176 8 24 176 8 28 176 12 32 176 12 36 180 16 40 184 16 44 184 20 48 184 20 52 188 24 56 192 24 60 192 28 64 192 28 68 196 32 72 200 32 76 200 36 80 200 36 84 204 40 88 208 40 92 208 44 96 208 44 100 212 48 104 216 48 108 216 52 112 216 52 116 220 56 120 224 60 124 224 60 128 224 64 132 228 64 136 232 68 132 232 68 136 232 68 140 232 68 144 232 72 148 236 72 152 240 76 156 240 76 160 240 80 164 244 80 168 248 84 172 248 84 176 248 waterline 40 124 0 40 124 0 44 124 0 44 124 0 44 124 4 44 124 4 44 128 4 44 128 4 48 128 4 48 128 4 48 128 8 48 128 8 48 132 8 48 132 8 52 132 8 52 132 8 56 132 12 56 132 12 60 132 12 60 132 12 60 136 12 60 136 12 60 136 16 60 136 16 60 140 16 60 140 16 64 140 16 64 140 16 64 140 20 64 140 20 64 144 20 64 144 20 68 144 20 68 144 20 68 144 24 68 144 24 68 148 24 72 148 24 72 148 28 72 152 28 72 152 32 76 152 32 76 156 32 80 156 32 80 156 36 80 160 36 80 160 40 84 160 40 84 164 40 88 164 40 88 164 44 88 168 44 88 168 48 92 168 48 92 172 48 96 172 48 96 172 52 96 176 52 100 176 52 100 176 56 100 180 56 100 180 56 104 180 60 104 184 60 104 184 64 108 184 64 108 188 64 108 188 68 112 188 68 112 188 72 112 192 72 112 192 76 116 192 76 116 196 76 116 196 80 120 196 80 120 200 80 120 200 84 124 200 84 124 204 84 124 204 88 128 204 88 128 208 88 128 208 92 132 208 92 132 212 92 136 212 92 136 212 96 136 216 96 136 216 100 140 216 100 140 220 100 140 220 104 144 220 104 144 224 104 144 224 108 148 224 108 148 228 108 152 228 108 152 228 108 156 228 108 156 228 108 160 228 108 164 228 108 168 228 108 168 228 108 172 228 108 172 228 108 176 228 108 176 228 108 180 228 108 180 228 108 184 228 108 184 228 108 188 228 108 188 228 108 192 228 108 196 228 108 196 228 108 200 228 108 204 228 108 204 228 108 208 228 108 208 228 108 212 228 108 212 228 108 216 228 108 220 228 108 220 228 108 224 228 108 228 228 108 228 228 108 232 228 108 232 228 108 232 228 104 232 228 104 232 228 100 232 228 100 232 228 96 232 228 96 232 228 92 232 224 92 232 224 92 232 220 88 232 216 84 232 216 80 232 212 80 232 212 76 232 208 76 232 204 72 232 204 68 232 200 68 232 200 64 232 200 64 232 196 64 232 196 60 232 192 60 232 192 56 232 188 56 232 188 52 232 184 52 232 184 48 232 180 48 232 180 44 232 180 44 232 176 44 232 176 44 232 176 40 232 176 40 232 172 40 232 172 36 232 168 36 232 168 36 228 164 32 228 164 32 228 160 32 228 160 32 224 156 28 224 152 24 224 152 24 224 148 20 220 148 20 220 140 16 220 140 16 220 132 16 216 132 16 216 124 8 216 124 8 216 116 8 128 128 128 Rocks 128 128 128 252 252 252 Snow 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 192 192 192 Rocks 192 192 192 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 xfractint-20.4.10.orig/debugfla.txt0000644000000000000000000000772210616226653014036 0ustar This list complete as of version 20. None of these are necessarily supported in future. Add one to any debug value to trigger writing benchmark values to the file "bench". This gets stripped at startup; so all values used for other purposes are even. Example: "fractint debug=8088" forces Fractint to think you have an 8088/8086 CPU and ignore all of the tricky 186/286/386-specific stuff. "Fractint 8089" does the same thing, but also turns on the benchmark timer. 16 video.asm pretend not a vga 22 lorenz.c force float for 3D perspective 50 fractint.c compare estored files 70 fractint.c set fpu = 0 72 fractint.c don't use fast >= 287 fpu routines 90 fractals.c force "C" mandel & julia code (no calcmand or calmanfp) 90 fractals.c force generic code for fn+fn etc types 90 parser.c force "C" parser code even if FPU >= 387 92 parser.c print out list of FRM files searched 94 parsera.asm Use old buggy pwr() 94 mpmath_c.c Use old buggy pwr() 96 frasetup.c Use real formula for popcorn in the old case. 96 parserfp.c write debug messages to disk files(3) 100 calcmand.asm force use of 'code32bit' logic 110 cmdfiles.c turns off first-time initialization of variables 200 fractint.c time encoder 322 parserfp.c disable optimizer (FPU >= 387 only) 324 realdos.c disables help ESC in screen messages 420 diskvid.c don't use extended/expanded mem (force disk) 420 memory.c same for screen save (force disk) 420 editpal.c same for screen save (force disk) 422 diskvid.c don't use expanded mem (force extended or disk) 422 memory.c same for screen save (force extended or disk) 450 fractint.c abort in batch mode if savename exists 470 calcfract.c disable prevention of color 0 for BTM 472 calcfract.c enable solid guessing at bottom and right 600 printer.c paintjet, no form feed 602 printer.c paintjet, flip image 7nn miscovl.c set getprec() digits variable to nn 750 miscovl.c print out as many params digits as possible in PAR 870 fractint.c set fpu to max 87 900 printer.c color test (commented out) 902 printer.c color test (commented out) 910 miscovl.c disables Sylvie Gallet's colors= color compression fix. 920 miscovl.c makes colors= compression lossless. 1010 fractals.c force fp for newton & newtbasin (no mpc math) 1012 fractals.c swap sign bit of zero for mandelbrotmix4 1234 fractint.c force larger integer arithmetic bitshift value 2222 line3d.c show amount of extra seg memory used 2224 line3d.c old just-the-dots logic, probably a temporary thing 2870 fractint.c set fpu to max 287 3000 general.asm '~' goes to color play mode 3002 realdos.c don't show development in heading 3200 fracsubr.c disable auto switch back from arbitrary precision 3400 fracsubr.c disable auto switch from integer to float 3444 calcfrac.c turns on long double soi algorithm (passes=s) 3600 miscfrac.c pins the plasma corners to 1 3800 fracsubr.c turns off grid pixel lookup 4000 miscres.c turn on math error message (off otherwise) 4010 miscres.c use pre-19.3 centermag conversion. 4020 fracsubr.c use old timer. 4030 fracsubr.c use old orbit->sound code w/integer overflow. 4200 diskvid.c sets disk video cache size to minimum 6000 frasetup turns off optimization of using realzzpower types instead of complexzpower when imaginary part of parameter is zero 8088 general.asm set cpu = 86, ie dont use 32 bit stuff 8088 fractint.c set cpu = 86, (case in general.asm is redundant?) 9002-9100 fractint.c reduce video_type to (debug-9000)/2 if init was higher 10000 fractint.c display cpu, fpu, and free memory at startup 10000 fractint.c ? (try extra hard for minimal startup memory?) nonzero value, line3d.c, show "normal vector" errors instead of just fixing nonzero value, prompts.c, show info if fullscreen_prompt2 array invalid xfractint-20.4.10.orig/unix/0000755000000000000000000000000011456314747012504 5ustar xfractint-20.4.10.orig/unix/xfcurses.c0000644000000000000000000003561210777673554014532 0ustar #ifndef NCURSES #ifndef __XFCURSES_LOADED #define __XFCURSES_LOADED 1 #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _AIX #include #endif #ifdef __hpux #include #endif #include #include "xfcurses.h" #include "helpdefs.h" #include "port.h" #include "prototyp.h" #define BRIGHT_INVERSE 0xC000 #define ATTRSIZE sizeof(short) extern int ctrl_window; extern int Xwinwidth ,Xwinheight; extern int helpmode; extern XImage *Ximage; extern int screenctr; extern int unixDisk; extern int resize_flag; extern void error_display(); static GC Xwcgc = None; static XFontStruct * font, * fontbold; static unsigned long black, white; static XSetWindowAttributes Xwatt; unsigned long pixel[48]; static char * xc[16] = { "#000000", /* black */ "#0000A8", /* dark blue */ "#00A800", /* dark green */ "#00A8A8", /* dark cyan */ "#A80000", /* dark red */ "#A800A8", /* dark magenta */ "#A85400", /* brown */ "#CCCCCC", /* grey80 */ "#333333", /* grey20 */ "#5454FC", /* light blue */ "#54FC54", /* light green */ "#54FCFC", /* light cyan */ "#FC5454", /* light red */ "#FC54FC", /* light magenta */ "#FCFC54", /* light yellow */ "#FFFFFF" /* white */ }; int charx, chary; static int charwidth, charheight, ascent, descent; static int Xwcwidth, Xwcheight; static Screen *Xwcsc; int COLS = 80; int LINES = 25 ; int textmargin = 40; WINDOW * curwin; Window Xwc = None, Xwp = None; char * Xmessage = NULL; char * Xfontname = NULL; char * Xfontnamebold = NULL; void Open_XDisplay() { if (Xdp != NULL) return; Xdp = XOpenDisplay(Xdisplay); if (Xdp == NULL) { error_display(); exit(-1); } Xdscreen = XDefaultScreen(Xdp); Xdepth = DefaultDepth(Xdp, Xdscreen); } void cbreak(void) { curwin = newwin(LINES, COLS, 0, 0); } void nocbreak(void) { } void echo(void) { } void noecho(void) { } void clear(void) { wclear(curwin); } int standout(void) { if (screenctr) XSetFont(Xdp, Xwcgc, fontbold->fid); return 1; } int standend(void) { if (screenctr) XSetFont(Xdp, Xwcgc, font->fid); return 1; } void endwin(void) { } void delwin(WINDOW *win) { if (curwin) free(curwin->_text); free(curwin); XClearWindow(Xdp, Xwc); standend(); } void fill_rectangle(int x, int y, int n) { int u, v; if (screenctr == 0) return; u = (y==0)?descent:0; v = (y==LINES-1)? descent+4:0; XFillRectangle(Xdp, Xwc, Xwcgc, charx + x * charwidth, chary + y * charheight - ascent - u - 1, charwidth * n, charheight + u + v); } void setcolor_bg(WINDOW *win, int j) { int attr = (j<0)?win->_cur_attr : win->_attr[j]; XSetForeground(Xdp, Xwcgc, pixel[(attr>>4) & 0xF]); } void setcolor_fg(WINDOW *win, int j) { int attr = (j<0)?win->_cur_attr : win->_attr[j]; XSetForeground(Xdp, Xwcgc, pixel[attr & 0xF]); } void waddch(WINDOW *win, const chtype ch) { char str[4]; int j; if (win->_cur_x<0 || win->_cur_x>=win->_num_x) return; if (win->_cur_y<0 || win->_cur_y>=win->_num_y) return; *str = (char) ch; j = win->_cur_y*win->_num_x + win->_cur_x; if (ch) win->_text[j] = (char) ch; win->_attr[j] = (short) win->_cur_attr; if (win->_cur_attr & BRIGHT_INVERSE) standout(); else standend(); setcolor_bg(win, -1); fill_rectangle(win->_cur_x, win->_cur_y, 1); *str = win->_text[j]; if (*str) { setcolor_fg(win, j); XDrawString(Xdp, Xwc, Xwcgc, charx + win->_cur_x * charwidth, chary + win->_cur_y * charheight, str, 1); } win->_cur_x += 1; if (win->_cur_x >= win->_num_x) { win->_cur_x = 0; win->_cur_y += 1; } } void waddstr(WINDOW *win, const char *str) { int i, j, n = strlen(str); if (win->_cur_y<0 || win->_cur_y>=win->_num_y) return; for (i=0; i_cur_y*win->_num_x + win->_cur_x + i; if (win->_cur_x+i<0 || win->_cur_x+i>=win->_num_x) continue; win->_text[j] = str[i]; win->_attr[j] = (short) win->_cur_attr; } setcolor_bg(win, -1); fill_rectangle(win->_cur_x, win->_cur_y, n); if (win->_cur_attr & BRIGHT_INVERSE) standout(); else standend(); setcolor_fg(win, -1); XDrawString(Xdp, Xwc, Xwcgc, charx + win->_cur_x * charwidth, chary + win->_cur_y * charheight, str, n); win->_cur_x += n; if (win->_cur_x >= win->_num_x) { win->_cur_y += win->_cur_x / win->_num_x; win->_cur_x = win->_cur_x % win->_num_x; } } void draw_caret(WINDOW *win, int y, int x) { int j; char str[4]; if (screenctr == 0) goto caret_end; if (win->_car_x>=0 && win->_car_x_car_y>=0 && win->_car_y_car_y * win->_num_x + win->_car_x; *str = win->_text[j]; if (win->_attr[j] & BRIGHT_INVERSE) standout(); else standend(); setcolor_bg(win, j); if (win->_car_x>=0 && win->_car_x_car_y>=0 && win->_car_y_car_x * charwidth + 2, chary + win->_car_y * charheight + 2 , charwidth-2, 2); if (*str) { setcolor_fg(win, j); XDrawString(Xdp, Xwc, Xwcgc, charx + win->_car_x * charwidth, chary + win->_car_y * charheight, str, 1); } } XSetForeground(Xdp, Xwcgc, pixel[4]); if (x>=0 && x=0 && y_car_y = y; win->_car_x = x; } void mvcur(int oldrow, int oldcol, int newrow, int newcol) { curwin->_cur_y = newrow; curwin->_cur_x = newcol; draw_caret(curwin, newrow, newcol); } void wclear(WINDOW *win) { int n; if (!win) return; n = (win->_num_x)*(win->_num_y); win->_cur_attr = 0; memset(win->_text, 0, n); memset(win->_attr, 0, n*sizeof(short)); XClearWindow(Xdp, Xwc); } void wdeleteln(WINDOW *win) { int j, k; if (win->_cur_y<0 || win->_cur_y>=win->_num_y) return; for (j=win->_cur_y; j _num_y-1 ; j++) { k = j*win->_num_x; memcpy(&win->_text[k], &win->_text[k+win->_num_x], win->_num_x); memcpy(&win->_attr[k], &win->_attr[k+win->_num_x], win->_num_x*ATTRSIZE); } k = (win->_num_y-1)*win->_num_x; memset(&win->_text[k], 0, win->_num_x); memset(&win->_attr[k], 0, win->_num_x*ATTRSIZE); } void winsertln(WINDOW *win) { int j, k; if (win->_cur_y<0 || win->_cur_y>=win->_num_y) return; for (j = win->_num_y - 1; j> win->_cur_y; j--) { k = j*win->_num_x; memcpy(&win->_text[k], &win->_text[k-win->_num_x], win->_num_x); memcpy(&win->_attr[k], &win->_attr[k-win->_num_x], win->_num_x*ATTRSIZE); } k = win->_cur_y*win->_num_x; memset(&win->_text[k], 0, win->_num_x); memset(&win->_attr[k], 0, win->_num_x*ATTRSIZE); xrefresh(win, win->_cur_y, win->_num_y); } void wmove(WINDOW *win, int y, int x) { draw_caret(win, y, x); win->_cur_y = y; win->_cur_x = x; } void wrefresh(WINDOW *win) { } void refresh(int line1, int line2) { xrefresh(curwin, line1, line2); } void xrefresh(WINDOW *win, int line1, int line2) { char str[4]; int x, y, j, topline; if (screenctr == 0 && !ctrl_window) { if (resize_flag & 2) { resize_flag &= ~2; ungetakey('d'); } else XPutImage(Xdp, Xw, Xgc, Ximage, 0, 0, 0, 0, Xwinwidth, Xwinheight); return; } if (line1 < 0) line1 = 0; if (line1 >= win->_num_y) line1 = win->_num_y; if (line2 >= win->_num_y) line2 = win->_num_y; if (line1 > line2) return; str[1] = '\0'; for (y=line1; y_num_x; x++) { j = y*win->_num_x + x; setcolor_bg(win, j); fill_rectangle(x, y, 1); setcolor_fg(win, j); if (win->_attr[j] & BRIGHT_INVERSE) standout(); else standend(); if (win->_text[j]) str[0] = win->_text[j]; else str[0] = ' '; XDrawString(Xdp, Xwc, Xwcgc, charx + x * charwidth, chary + y * charheight, str, 1); } } XFlush(Xdp); } void touchwin(WINDOW *win) { } void wtouchln(WINDOW *win, int y, int n, int changed) { } void wstandout(WINDOW *win) { standout(); } void wstandend(WINDOW *win) { standend(); } WINDOW *newwin(int nlines, int ncols, int begin_y, int begin_x) { WINDOW *win; int n; win = (WINDOW *) malloc(sizeof(WINDOW)); if (!win) return NULL; win->_num_y = nlines; win->_num_x = ncols; win->_car_y = begin_y; win->_car_x = begin_x; win->_cur_x = 0; win->_cur_y = 0; win->_cur_attr = 0; n = 2*(ncols+1)*(nlines+1); win->_attr = (short *)malloc(n*ATTRSIZE); win->_text = (char *)malloc(n); if (!win->_text || !win->_attr) { if (win->_text) free(win->_text); if (win->_attr) free(win->_attr); free(win); return NULL; } memset(win->_text, 0, n); memset(win->_attr, 0, n*ATTRSIZE); return win; } WINDOW *initscr(void) { XGCValues Xgcvals; XColor xcolor, junk; int i, Xwinx = 0, Xwiny = 0; Open_XDisplay(); Xwcsc = ScreenOfDisplay(Xdp, Xdscreen); if (Xfontname == NULL) Xfontname = "9x15"; if (Xfontnamebold == NULL) Xfontnamebold = "9x15bold"; Xwatt.background_pixel = BlackPixelOfScreen(Xwcsc); Xwatt.bit_gravity = StaticGravity; if (DoesBackingStore(Xwcsc)) { Xwatt.backing_store = Always; } else { Xwatt.backing_store = NotUseful; } Xroot = DefaultRootWindow(Xdp); font = XLoadQueryFont(Xdp, Xfontname); if (font == (XFontStruct *)NULL) { fprintf(stderr, "xfractint: can't open font `%s'\n", Xfontname); exit(-1); } fontbold = XLoadQueryFont(Xdp, Xfontnamebold); if (fontbold == (XFontStruct *)NULL) { fprintf(stderr, "xfractint: can't open font `%s', using `%s'\n", Xfontnamebold, Xfontname); /* no need to exit since at this point we know Xfontname is good */ fontbold = XLoadQueryFont(Xdp, Xfontname); } ascent = font->max_bounds.ascent; descent = font->max_bounds.descent; charwidth = XTextWidth(font, "m", 1); charheight = ascent + descent + 2; Xwcwidth = (COLS*charwidth+3)&-4; Xwcheight = (LINES*charheight+2*(charheight/4)+3)&-4; if (!ctrl_window || unixDisk) { i = 2*textmargin; Xwcwidth += i; Xwcheight += i; if (Xgeometry) { XParseGeometry(Xgeometry, &Xwinx, &Xwiny, (unsigned int *) &Xwinwidth, (unsigned int *) &Xwinheight); } Xwinwidth &= -4; Xwinheight &= -4; if (Xwinwidth > Xwcwidth) Xwcwidth = Xwinwidth; if (Xwinheight > Xwcheight) Xwcheight = Xwinheight; if (Xwcheight<(i=(3*Xwcwidth)/4)) Xwcheight = (i+3)&-4; if (Xwcwidth<(i=(4*Xwcheight)/3)) Xwcwidth = (i+3)&-4; } charx = (Xwcwidth - COLS*charwidth)/2; chary = (Xwcheight - (LINES*charheight+2*(charheight/4)))/2 + ascent + (charheight/4); if (Xwc == None) Xwc = XCreateWindow(Xdp, Xroot, Xwinx, Xwiny, Xwcwidth, Xwcheight, 0, Xdepth, InputOutput, CopyFromParent, CWBackPixel | CWBitGravity | CWBackingStore, &Xwatt); XSelectInput(Xdp, Xwc, ExposureMask|StructureNotifyMask| KeyPressMask|KeyReleaseMask| ButtonPressMask|ButtonReleaseMask|PointerMotionMask); wm_protocols = XInternAtom(Xdp, "WM_PROTOCOLS", False); wm_delete_window = XInternAtom(Xdp, "WM_DELETE_WINDOW", False); XSetWMProtocols(Xdp, Xwc, &wm_delete_window, 1); XStoreName(Xdp, Xwc, (ctrl_window)?"Xfractint controls":"Xfractint"); white = WhitePixelOfScreen(Xwcsc); black = BlackPixelOfScreen(Xwcsc); Xcmap = DefaultColormapOfScreen(Xwcsc); for (i=0; i<16; i++) if (XAllocNamedColor(Xdp, Xcmap, xc[i], &xcolor, &junk)) pixel[i] = xcolor.pixel; else pixel[i] = (i<=6)? black:white; Xgcvals.font = font->fid; Xgcvals.foreground = white; Xgcvals.background = black; Xwcgc = XCreateGC(Xdp, Xwc, GCForeground | GCBackground | GCFont, &Xgcvals); clear(); if (ctrl_window) XMapRaised(Xdp, Xwc); standend(); return NULL; } void set_margins(int width, int height) { int i, j; i = width - ((COLS*charwidth+3)&-4); j = height - ((LINES*charheight+2*(charheight/4)+3)&-4); if (i<0 || j<0) textmargin = 0; else if (i0) XClearArea(Xdp, Xw, 0, 0, width, j, True); j = chary+LINES*charheight-ascent+descent+4; if (j0) { XClearArea(Xdp, Xw, 0, 0, charx, height, True); XClearArea(Xdp, Xw, width-charx, 0, charx, height, True); } } } void xpopup(char *str) { Window child; XSizeHints size_hints; char *ptr1, *ptr2; int x, y, j, n; unsigned int junk; if (!Xwc) return; /* if str==NULL refresh message */ if (!str && Xwp && Xmessage) { display_text: ptr1 = str = strdup(Xmessage); XSetForeground(Xdp, Xwcgc, pixel[15]); n = 0; iter: if ((ptr2=strchr(ptr1, '\n'))) *ptr2 = '\0'; XDrawImageString(Xdp, Xwp, Xwcgc, charwidth/2, ascent + (charheight/4)+2+n*charheight, ptr1, strlen(ptr1)); XFlush(Xdp); usleep(100000); if (ptr2) { ptr1 = ptr2+1; n++; goto iter; } free(str); return; } /* otherwise create popup */ if (Xwp) XDestroyWindow(Xdp, Xwp); if (Xmessage) free(Xmessage); Xmessage = strdup(str); j = 1; n = 1; ptr1 = str; while ((ptr2=strchr(ptr1, '\n'))) { ++n; if (ptr2-ptr1>j) j = (int)(ptr2-ptr1); ptr1 = ptr2+1; } if (ptr1 && strlen(ptr1)>j) j = strlen(ptr1); size_hints.flags = USPosition | USSize | PBaseSize | PResizeInc; size_hints.base_width = charwidth*(j+1); size_hints.base_height = charheight*n + 2*(charheight/4); size_hints.width_inc = 4; size_hints.height_inc = 4; XTranslateCoordinates(Xdp, Xw, Xroot, 0, 0, &x, &y, &child); size_hints.x = x+20; size_hints.y = y+20; Xwp = XCreateWindow(Xdp, Xroot, size_hints.x, size_hints.y, size_hints.base_width, size_hints.base_height, 0, Xdepth, InputOutput, CopyFromParent, CWBackPixel | CWBitGravity | CWBackingStore, &Xwatt); XSelectInput(Xdp, Xwp, ExposureMask); XSetWMProtocols(Xdp, Xwp, &wm_delete_window, 1); XStoreName(Xdp, Xwp, "Xfractint message"); XSetWMNormalHints(Xdp, Xwp, &size_hints); XMapRaised(Xdp, Xwp); XFlush(Xdp); usleep(10000); goto display_text; } #endif /* __XFCURSES_LOADED */ #endif /* not NCURSES */ xfractint-20.4.10.orig/unix/fracsuba.c0000644000000000000000000000037010150633601014415 0ustar #include "port.h" #include "prototyp.h" int FManOWarfpFractal(void) {return(0);} int FJuliafpFractal(void) {return(0);} int FBarnsley1FPFractal(void) {return(0);} int FBarnsley2FPFractal(void) {return(0);} int FLambdaFPFractal(void) {return(0);} xfractint-20.4.10.orig/unix/xfractint.man0000755000000000000000000001036311451656645015212 0ustar .TH "XFRACTINT" "1" "20.04" "" "" .SH "NAME" xfractint \- fractal generation program .SH "SYNOPSIS" .B xfractint [options] [; comments] .SH "DESCRIPTION" .I Xfractint draws a wide variety of fractals. Xfractint is a port of the IBM PC program fractint. Xfractint has online documentation which should be referenced for most operation information. Note that the online documentation is from fractint, and does not always accurately describe xfractint. A text version of the online documentation can be generated by running ``make doc''. .SH "OPTIONS" .TP \-display \fIdisplay_name\fR Specifies the X11 display to use. .TP \-onroot Indicates the resulting images should appear on the root window. Note: rubberband zoom boxes don't work on the root window. .TP \-private Indicates that xfractint should allocate as many colors as possible in a private colormap. Normally xfractint will use 128 colors; this flag will let you use all 256, but may mess up the colors in other windows. This is not necessary if you are using greater than 8\-bit color. .TP \-slowdisplay Indicates that the machine has a slow display, so the scrolling window should be updated infrequently. Use this flag if xfractint hangs on the title screen. .TP \-fast Indicates that xfractint should use the faster drawing mode. Instead of drawing each pixel immediately, xfractint will save up pixels and then refresh the screen every 5 seconds. Depending on your X implementation, this may make drawing twice as fast. .TP \-disk Use disk video. That is, generate the picture in memory instead of to the screen. The resulting picture can be saved as a gif file or printer file. .TP \-fixcolors \fInum\fR Specifies the number of colors to use. This number must be a power of two. Also, this number can't be greater than the number of colors available. And, it can't be greater than 256. .TP \-geometry \fIWxH[{+\-X}{+\-Y}]\fR This sets the size and position of the image window. The default is 800x600 pixels. .TP \-share Indicates that xfractint should share the current colormap. That is, xfractint uses as many colors as possible, but doesn't modify the colormap. This is not necessary with greater than 8\-bit colors. .TP \-simple Uses simpler keyboard handling. Use this flag if you wish to debug xfractint with gdb, or else you may get "(gdb)" repeated infinitely. .TP xxx=yyy Sets variable xxx to value yyy. See the online documentation for more details on the possible variables. .TP @filename .br Loads parameters from the specified file. .TP @filename/groupname .br Reads a named group of parameters from the specified file. .TP \-psviewer Allows the user to change the default postscript viewer. The viewer is called when the user prints an image with ctrl\-p. The default viewer is gv. .TP \-ctrlwindow Allows the user to have a separate control window similar to the ncurses interface. .TP \-font Loads the selected font. .TP \-fontbold Loads the selected bold font. .SH "BUGS" There are many bugs and things that haven't been implemented. .TP Boundary tracing sometimes locks up. .TP Passes=2 has problems?? .TP Symmetry that is offset slightly doesn't always complete the image. .TP The top of the help screens are messed up. Starting your xterm with \-geometry 80x25 fixes this. .PP Xfractint uses a bizarre (to Unix users) user interface which was directly copied from the IBM version. If you don't have the appropriate keys, use the following key mappings: .nf IBM Unix F1 to F10 Shift\-1 to Shift\-0 INSERT I DELETE D PAGE_UP U PAGE_DOWN N LEFT_ARROW H RIGHT_ARROW L UP_ARROW K DOWN_ARROW J HOME O END E CTL_PLUS } CTL_MINUS { .fi .SH "COPYRIGHT" Copyright 1991 \- 2010 by The Stone Soup Group .SH "AUTHORS" .nf The original Unix port was done by Ken Shirriff (shirriff@eng.sun.com). Xfractint was updated to Fractint 19.5 by Tim Wegner (twegner@fractint.org) under Linux 2.0. Please report updates for other platforms to Tim Wegner. The current official release is 20.0. The primary authors of Fractint 20.0 are: Timothy Wegner twegner@fractint.org Jonathan Osuch josuch@fractint.org George Martin ggmartin@compuserve.com Robin Bussell robin.b2@ukonline.co.uk .fi xfractint-20.4.10.orig/unix/general.c0000644000000000000000000005570511451656645014302 0ustar /* generalasm.c * This file contains routines to replace general.asm. * * This file Copyright 1991 Ken Shirriff. It may be used according to the * fractint license conditions, blah blah blah. */ #include #ifndef NOBSTRING #ifndef sun /* If this gives you an error, read the README and modify the Makefile. */ #include #endif #endif #include #include #include #include #include #include "port.h" #include "prototyp.h" int overflow = 0; int boxx[2304], boxy[1024]; int boxvalues[512]; char tstack[4096]; BYTE dacbox[256][3]; BYTE olddacbox[256][3]; extern int tabmode; int DivideOverflow = 0; int cpu=0; /* cpu type: 86, 186, 286, or 386 */ int fpu=0; /* fpu type: 0, 87, 287, 387 */ SEGTYPE extraseg=0; /* extra 64K segment (allocated by init) */ /* ********************** Mouse Support Variables ************************** */ int lookatmouse=0; /* see notes at mouseread routine */ long savebase=0; /* base clock ticks */ long saveticks=0; /* save after this many ticks */ int finishrow=0; /* save when this row is finished */ int inside_help = 0; extern int slides; /* 1 for playback */ unsigned int toextra(tooffset, fromaddr, fromcount) unsigned int tooffset; char *fromaddr; int fromcount; { bcopy(fromaddr,(char *)(extraseg+tooffset),fromcount); return tooffset; } unsigned int fromextra(fromoffset, toaddr, tocount) unsigned int fromoffset; char *toaddr; int tocount; { bcopy((char *)(extraseg+fromoffset),toaddr,tocount); return fromoffset; } unsigned int cmpextra(cmpoffset,cmpaddr,cmpcount) unsigned int cmpoffset; char *cmpaddr; int cmpcount; { return bcmp((char *)(extraseg+cmpoffset),cmpaddr,cmpcount); } /* ; ****************** Function initasmvars() ***************************** */ void initasmvars(void) { if (cpu!=0) return; overflow = 0; extraseg = malloc(0x18000); /* set cpu type */ cpu = 1; /* set fpu type */ /* not needed, set fpu in sstools.ini */ } void fpe_handler(int signum) { signal(SIGFPE, fpe_handler); overflow = 1; } /* ; ; 32-bit integer multiply routine with an 'n'-bit shift. ; Overflow condition returns 0x7fffh with overflow = 1; ; ; long x, y, z, multiply(); ; int n; ; ; z = multiply(x,y,n) ; */ /* * 32 bit integer multiply with n bit shift. * Note that we fake integer multiplication with floating point * multiplication. */ long multiply(x, y, n) long x,y; int n; { register long l; l = ((float)x)* ((float)y)/(float)(1<info_id,(char *)bufPtr,8); } else { strncpy((char *)bufPtr,info->info_id,8); } bufPtr += 8; getInt(&info->iterationsold,&bufPtr,dir); getInt(&info->fractal_type,&bufPtr,dir); getDouble(&info->xmin,&bufPtr,dir); getDouble(&info->xmax,&bufPtr,dir); getDouble(&info->ymin,&bufPtr,dir); getDouble(&info->ymax,&bufPtr,dir); getDouble(&info->creal,&bufPtr,dir); getDouble(&info->cimag,&bufPtr,dir); getInt(&info->videomodeax,&bufPtr,dir); getInt(&info->videomodebx,&bufPtr,dir); getInt(&info->videomodecx,&bufPtr,dir); getInt(&info->videomodedx,&bufPtr,dir); getInt(&info->dotmode,&bufPtr,dir); getInt(&info->xdots,&bufPtr,dir); getInt(&info->ydots,&bufPtr,dir); getInt(&info->colors,&bufPtr,dir); getInt(&info->version,&bufPtr,dir); getFloat(&info->parm3,&bufPtr,dir); getFloat(&info->parm4,&bufPtr,dir); getFloat(&info->potential[0],&bufPtr,dir); getFloat(&info->potential[1],&bufPtr,dir); getFloat(&info->potential[2],&bufPtr,dir); getInt(&info->rseed,&bufPtr,dir); getInt(&info->rflag,&bufPtr,dir); getInt(&info->biomorph,&bufPtr,dir); getInt(&info->inside,&bufPtr,dir); getInt(&info->logmap,&bufPtr,dir); getFloat(&info->invert[0],&bufPtr,dir); getFloat(&info->invert[1],&bufPtr,dir); getFloat(&info->invert[2],&bufPtr,dir); getInt(&info->decomp[0],&bufPtr,dir); getInt(&info->decomp[1],&bufPtr,dir); getInt(&info->symmetry,&bufPtr,dir); for (i=0;i<16;i++) { getInt(&info->init3d[i],&bufPtr,dir); } getInt(&info->previewfactor,&bufPtr,dir); getInt(&info->xtrans,&bufPtr,dir); getInt(&info->ytrans,&bufPtr,dir); getInt(&info->red_crop_left,&bufPtr,dir); getInt(&info->red_crop_right,&bufPtr,dir); getInt(&info->blue_crop_left,&bufPtr,dir); getInt(&info->blue_crop_right,&bufPtr,dir); getInt(&info->red_bright,&bufPtr,dir); getInt(&info->blue_bright,&bufPtr,dir); getInt(&info->xadjust,&bufPtr,dir); getInt(&info->eyeseparation,&bufPtr,dir); getInt(&info->glassestype,&bufPtr,dir); getInt(&info->outside,&bufPtr,dir); getDouble(&info->x3rd,&bufPtr,dir); getDouble(&info->y3rd,&bufPtr,dir); getChar(&info->stdcalcmode,&bufPtr,dir); getChar(&info->useinitorbit,&bufPtr,dir); getInt(&info->calc_status,&bufPtr,dir); getLong(&info->tot_extend_len,&bufPtr,dir); getInt(&info->distest,&bufPtr,dir); getInt(&info->floatflag,&bufPtr,dir); getInt(&info->bailoutold,&bufPtr,dir); getLong(&info->calctime,&bufPtr,dir); for (i=0;i<4;i++) { getChar(&info->trigndx[i],&bufPtr,dir); } getInt(&info->finattract,&bufPtr,dir); getDouble(&info->initorbit[0],&bufPtr,dir); getDouble(&info->initorbit[1],&bufPtr,dir); getInt(&info->periodicity,&bufPtr,dir); getInt(&info->pot16bit,&bufPtr,dir); getFloat(&info->faspectratio,&bufPtr,dir); getInt(&info->system,&bufPtr,dir); getInt(&info->release,&bufPtr,dir); getInt(&info->flag3d,&bufPtr,dir); getInt(&info->transparent[0],&bufPtr,dir); getInt(&info->transparent[1],&bufPtr,dir); getInt(&info->ambient,&bufPtr,dir); getInt(&info->haze,&bufPtr,dir); getInt(&info->randomize,&bufPtr,dir); getInt(&info->rotate_lo,&bufPtr,dir); getInt(&info->rotate_hi,&bufPtr,dir); getInt(&info->distestwidth,&bufPtr,dir); getDouble(&info->dparm3,&bufPtr,dir); getDouble(&info->dparm4,&bufPtr,dir); getInt(&info->fillcolor,&bufPtr,dir); getDouble(&info->mxmaxfp,&bufPtr,dir); getDouble(&info->mxminfp,&bufPtr,dir); getDouble(&info->mymaxfp,&bufPtr,dir); getDouble(&info->myminfp,&bufPtr,dir); getInt(&info->zdots,&bufPtr,dir); getFloat(&info->originfp,&bufPtr,dir); getFloat(&info->depthfp,&bufPtr,dir); getFloat(&info->heightfp,&bufPtr,dir); getFloat(&info->widthfp,&bufPtr,dir); getFloat(&info->distfp,&bufPtr,dir); getFloat(&info->eyesfp,&bufPtr,dir); getInt(&info->orbittype,&bufPtr,dir); getInt(&info->juli3Dmode,&bufPtr,dir); getInt(&info->maxfn,&bufPtr,dir); getInt(&info->inversejulia,&bufPtr,dir); getDouble(&info->dparm5,&bufPtr,dir); getDouble(&info->dparm6,&bufPtr,dir); getDouble(&info->dparm7,&bufPtr,dir); getDouble(&info->dparm8,&bufPtr,dir); getDouble(&info->dparm9,&bufPtr,dir); getDouble(&info->dparm10,&bufPtr,dir); getLong(&info->bailout,&bufPtr,dir); getInt(&info->bailoutest,&bufPtr,dir); getLong(&info->iterations,&bufPtr,dir); getInt(&info->bf_math,&bufPtr,dir); getInt(&info->bflength,&bufPtr,dir); getInt(&info->yadjust,&bufPtr,dir); getInt(&info->old_demm_colors,&bufPtr,dir); getLong(&info->logmap,&bufPtr,dir); getLong(&info->distest,&bufPtr,dir); getDouble(&info->dinvert[0],&bufPtr,dir); getDouble(&info->dinvert[1],&bufPtr,dir); getDouble(&info->dinvert[2],&bufPtr,dir); getInt(&info->logcalc,&bufPtr,dir); getInt(&info->stoppass,&bufPtr,dir); getInt(&info->quick_calc,&bufPtr,dir); getDouble(&info->closeprox,&bufPtr,dir); getInt(&info->nobof,&bufPtr,dir); getLong(&info->orbit_interval,&bufPtr,dir); getInt(&info->orbit_delay,&bufPtr,dir); getDouble(&info->math_tol[0],&bufPtr,dir); getDouble(&info->math_tol[1],&bufPtr,dir); for (i=0;i<(sizeof(info->future)/sizeof(short));i++) { getInt(&info->future[i],&bufPtr,dir); } if (bufPtr-buf != FRACTAL_INFO_SIZE) { printf("Warning: loadfile miscount on fractal_info structure.\n"); printf("Components add up to %d bytes, but FRACTAL_INFO_SIZE = %d\n", bufPtr-buf, FRACTAL_INFO_SIZE); } if (dir==0) { bcopy((char *)buf,(char *)info,FRACTAL_INFO_SIZE); } free(buf); } /* * This routine gets a char out of the buffer. * It updates the buffer pointer accordingly. */ static void getChar(dst,src,dir) unsigned char *dst; unsigned char **src; int dir; { if (dir==1) { *dst = **src; } else { **src = *dst; } (*src)++; } /* * This routine gets an int out of the buffer. * It updates the buffer pointer accordingly. */ static void getInt(dst,src,dir) short *dst; unsigned char **src; int dir; { if (dir==1) { *dst = (*src)[0] + ((((char *)(*src))[1])<<8); } else { (*src)[0] = (*dst)&0xff; (*src)[1] = ((*dst)&0xff00)>>8; } (*src) += 2; /* sizeof(int) in MS_DOS */ } /* * This routine gets a long out of the buffer. * It updates the buffer pointer accordingly. */ static void getLong(dst,src,dir) long *dst; unsigned char **src; int dir; { if (dir==1) { *dst = ((unsigned long)((*src)[0])) + (((unsigned long)((*src)[1]))<<8) + (((unsigned long)((*src)[2]))<<16) + (((long)(((char *)(*src))[3]))<<24); } else { (*src)[0] = (*dst)&0xff; (*src)[1] = ((*dst)&0xff00)>>8; (*src)[2] = ((*dst)&0xff0000)>>16; #ifdef __SVR4 (*src)[3] = (unsigned)((*dst)&0xff000000)>>24; #else (*src)[3] = ((*dst)&0xff000000)>>24; #endif } (*src) += 4; /* sizeof(long) in MS_DOS */ } #define P4 16. #define P7 128. #define P8 256. #define P12 4096. #define P15 32768. #define P20 1048576. #define P23 8388608. #define P28 268435456. #define P36 68719476736. #define P44 17592186044416. #define P52 4503599627370496. /* * This routine gets a double out of the buffer, or puts a double into the * buffer; * It updates the buffer pointer accordingly. */ static void getDouble(dst,src,dir) double *dst; unsigned char **src; int dir; { int e; double f; int i; if (dir==1) { for (i=0;i<8;i++) { if ((*src)[i] != 0) break; } if (i==8) { *dst = 0; } else { #ifdef __SVR4 e = (((*src)[7]&0x7f)<<4) + ((int)((*src)[6]&0xf0)>>4) - 1023; f = 1 + (int)((*src)[6]&0x0f)/P4 + (int)((*src)[5])/P12 + (int)((*src)[4])/P20 + (int)((*src)[3])/P28 + (int)((*src)[2])/P36 + (int)((*src)[1])/P44 + (int)((*src)[0])/P52; #else e = (((*src)[7]&0x7f)<<4) + (((*src)[6]&0xf0)>>4) - 1023; f = 1 + ((*src)[6]&0x0f)/P4 + (*src)[5]/P12 + (*src)[4]/P20 + (*src)[3]/P28 + (*src)[2]/P36 + (*src)[1]/P44 + (*src)[0]/P52; #endif f *= pow(2.,(double)e); if ((*src)[7]&0x80) { f = -f; } *dst = f; } } else { if (*dst==0) { bzero((char *)(*src),8); } else { int s=0; f = *dst; if (f<0) { s = 0x80; f = -f; } e = log(f)/log(2.); f = f/pow(2.,(double)e) - 1; if (f<0) { e--; f = (f+1)*2-1; } else if (f>=1) { e++; f = (f+1)/2-1; } e += 1023; (*src)[7] = s | ((e&0x7f0)>>4); f *= P4; (*src)[6] = ((e&0x0f)<<4) | (((int)f)&0x0f); f = (f-(int)f)*P8; (*src)[5] = (((int)f)&0xff); f = (f-(int)f)*P8; (*src)[4] = (((int)f)&0xff); f = (f-(int)f)*P8; (*src)[3] = (((int)f)&0xff); f = (f-(int)f)*P8; (*src)[2] = (((int)f)&0xff); f = (f-(int)f)*P8; (*src)[1] = (((int)f)&0xff); f = (f-(int)f)*P8; (*src)[0] = (((int)f)&0xff); } } *src += 8; /* sizeof(double) in MSDOS */ } /* * This routine gets a float out of the buffer. * It updates the buffer pointer accordingly. */ static void getFloat(dst,src,dir) float *dst; unsigned char **src; int dir; { int e; double f; int i; if (dir==1) { for (i=0;i<4;i++) { if ((*src)[i] != 0) break; } if (i==4) { *dst = 0; } else { #ifdef __SVR4 e = ((((*src)[3]&0x7f)<<1) | ((int)((*src)[2]&0x80)>>7)) - 127; f = 1 + (int)((*src)[2]&0x7f)/P7 + (int)((*src)[1])/P15 + (int)((*src)[0])/P23; #else e = ((((*src)[3]&0x7f)<<1) | (((*src)[2]&0x80)>>7)) - 127; f = 1 + ((*src)[2]&0x7f)/P7 + (*src)[1]/P15 + (*src)[0]/P23; #endif f *= pow(2.,(double)e); if ((*src)[3]&0x80) { f = -f; } *dst = f; } } else { if (*dst==0) { bzero((char *)(*src),4); } else { int s=0; f = *dst; if (f<0) { s = 0x80; f = -f; } e = log(f)/log(2.); f = f/pow(2.,(double)e) - 1; if (f<0) { e--; f = (f+1)*2-1; } else if (f>=1) { e++; f = (f+1)/2-1; } e += 127; (*src)[3] = s | ((e&0xf7)>>1); f *= P7; (*src)[2] = ((e&0x01)<<7) | (((int)f)&0x7f); f = (f-(int)f)*P8; (*src)[1] = (((int)f)&0xff); f = (f-(int)f)*P8; (*src)[0] = (((int)f)&0xff); } } *src += 4; /* sizeof(float) in MSDOS */ } /* * Fix up the ranges data. */ void fix_ranges(ranges,num,dir) int *ranges, num; int dir; { unsigned char *buf; unsigned char *bufPtr; int i; if (dir==1) { buf = (unsigned char *)malloc(num*2); bufPtr = buf; bcopy((char *)ranges, (char *)buf, num*2); } else { buf = (unsigned char *)malloc(num*sizeof(int)); bufPtr = buf; bcopy((char *)ranges, (char *)buf, num*sizeof(int)); } for (i=0;ievolving,&bufPtr,dir); getInt(&info->gridsz,&bufPtr,dir); getInt(&info->this_gen_rseed,&bufPtr,dir); getDouble(&info->fiddlefactor,&bufPtr,dir); getDouble(&info->paramrangex,&bufPtr,dir); getDouble(&info->paramrangey,&bufPtr,dir); getDouble(&info->opx,&bufPtr,dir); getDouble(&info->opy,&bufPtr,dir); getInt(&info->odpx,&bufPtr,dir); getInt(&info->odpy,&bufPtr,dir); getInt(&info->px,&bufPtr,dir); getInt(&info->py,&bufPtr,dir); getInt(&info->sxoffs,&bufPtr,dir); getInt(&info->syoffs,&bufPtr,dir); getInt(&info->xdots,&bufPtr,dir); getInt(&info->ydots,&bufPtr,dir); for (i=0;imutate[i],&bufPtr,dir); } getInt(&info->ecount,&bufPtr,dir); for (i=0;i<(sizeof(info->future)/sizeof(short));i++) { getInt(&info->future[i],&bufPtr,dir); } if (bufPtr-buf != EVOLVER_INFO_SIZE) { printf("Warning: loadfile miscount on evolution_info structure.\n"); printf("Components add up to %d bytes, but EVOLVER_INFO_SIZE = %d\n", bufPtr-buf, EVOLVER_INFO_SIZE); } if (dir==0) { bcopy((char *)buf,(char *)info,EVOLVER_INFO_SIZE); } free(buf); } void decode_orbits_info(info,dir) struct orbits_info *info; int dir; { unsigned char *buf; unsigned char *bufPtr; int i; if (dir==1) { buf = (unsigned char *)malloc(ORBITS_INFO_SIZE); bufPtr = buf; bcopy((char *)info,(char *)buf,ORBITS_INFO_SIZE); } else { buf = (unsigned char *)malloc(sizeof(struct orbits_info)); bufPtr = buf; bcopy((char *)info,(char *)buf,sizeof(struct orbits_info)); } getDouble(&info->oxmin,&bufPtr,dir); getDouble(&info->oxmax,&bufPtr,dir); getDouble(&info->oymin,&bufPtr,dir); getDouble(&info->oymax,&bufPtr,dir); getDouble(&info->ox3rd,&bufPtr,dir); getDouble(&info->oy3rd,&bufPtr,dir); getInt(&info->keep_scrn_coords,&bufPtr,dir); getChar(&info->drawmode,&bufPtr,dir); getChar(&info->dummy,&bufPtr,dir); for (i=0;i<(sizeof(info->future)/sizeof(short));i++) { getInt(&info->future[i],&bufPtr,dir); } if (bufPtr-buf != ORBITS_INFO_SIZE) { printf("Warning: loadfile miscount on orbits_info structure.\n"); printf("Components add up to %d bytes, but ORBITS_INFO_SIZE = %d\n", bufPtr-buf, ORBITS_INFO_SIZE); } if (dir==0) { bcopy((char *)buf,(char *)info,ORBITS_INFO_SIZE); } free(buf); } xfractint-20.4.10.orig/unix/calmanfx.o0000755000000000000000000001342010150633601014437 0ustar ELF@4(p : H(`0 @?)=}=} ÐUVW)=t=t-$,׾  =u5=t =}= u-f=t<f=otf=Ou+Ë =IPQS[Y t=X됐,$OT=ftX$fPA,AfX١ Ð9s&TfXtsB=tIuU- y))u@)=t=~أ=t _^]ÐUSQRVWP=<=F=P=Z=d5 555f-d-Z-P-F-<_^ZY[]Ð=nf5nf n -n=u1t %=u.t%=uEfPfXu t%_=u(t%+=u ;v)=r =ufn-nThe Netwide Assembler 0.98.35.data.text.comment.shstrtab.symtab.strtab.rel.textS[d?r} $,4<FPZd-nKZ)in !0: \p(>HXiq<DoRT#j,:IR]kz)TT^v +3>JOTX^ems} &3;G5s@calmanfx.asmPTRSZINTSZDBLSZkeypressedgetakeyplot_orbitscrub_orbitinitparmnewmaxitinsideoutsiderqlimcoloriteroldcoloriterrealcoloriterperiodicitycheckreset_periodicityclosenufffractypekbdcountdotmodeshow_orbitorbit_ptrmagnitudenextsavedincrfirstsavedandbad_outsidesave_releaseshowdotorbit_delayatan_colorsJULIAFPMANDELFPKEYPRESSDELAYorbit_realorbit_imaground_down_halftmp_dwordinside_colorperiodicity_colorsavedx_p5savedy_p5closenuff_p5tmp_ten_byte_1tmp_ten_byte_2tmp_ten_byte_3tmp_ten_byte_4tmp_ten_byte_5Controlcalcmandfpasmstart_p5non_neg_insidenon_neg_periodicitycheckcalcmandfpasm_p5initoldcolorinitparmsslowkbdquickkbdorbitkeykeyhitnokeyDoKeyChecksave_new_old_valueSkipKeyCheckdo_check_p5_fastdojulia_p5bottom_of_dojulia_p5LoopStartper_check_p5_ret_fastSkipTasksJustAfterFnstswno_show_orbit_p5LoopEndoverbailout_p5no_fix_underflow_p5zero_color_fix_p5to_special_outside_p5overiteration_p5calcmandfpasm_ret_p5show_orbit_xy_p5special_outside_p5over_bad_realover_good_realnot_realover_bad_imagover_good_imagnot_imagnon_zero_yover_bad_multover_good_multnot_multover_bad_summover_good_summnot_sumnot_atancheck_colorcheck_releasespecial_outside_retPOV*0TIVUW`OjTr]ZZ\dcZ[ZHZ I\\)S2O8T>YOLUL[RcMoMH_X XO#T,U1<MBMHRNLXL\OTU^T OUZQ+Q6QFNLNUS[]fKkSJ!)/Q=aIValQzaQaQa#+Q=eKPVO`byxfractint-20.4.10.orig/unix/xfract_a.inc0000644000000000000000000000302510150633601014745 0ustar ; This file includes macros and equates that will be needed in any ; assembly language files used by Xfractint. 1/27/2002 JCO PTRSZ equ 4 INTSZ equ 4 DBLSZ equ 8 ; --------------------------------------------------------------------------- ; The following two macros take care of the case where gcc uses ; underscores for assembly identifiers. ; Define the variable U_SCORE in the Make file if underscores are required. %macro CGLOBAL 1 %ifdef U_SCORE global _%1 %define %1 _%1 %else global %1 %endif %endmacro %macro CEXTERN 1 %ifdef U_SCORE extern _%1 %define %1 _%1 %else extern %1 %endif %endmacro ; --------------------------------------------------------------------------- ; The following two macros frame and unframe the operations in a routine ; Note that the order of the passed parameters is the same in both. %macro FRAME 1-* ; build a stack frame push ebp mov ebp, esp %rep %0 push %1 %rotate 1 %endrep %endmacro %macro UNFRAME 1-* ; unframe before return %rep %0 %rotate -1 pop %1 %endrep pop ebp %endmacro ; --------------------------------------------------------------------------- ; The following defines change the format of the fpu instructions from ; the nasm style to the Intel style %ifdef NEED_PARENS %define st0 st(0) %define st1 st(1) %define st2 st(2) %define st3 st(3) %define st4 st(4) %define st5 st(5) %define st6 st(6) %define st7 st(7) %endif xfractint-20.4.10.orig/unix/diskvidu.c0000644000000000000000000001226410762306640014467 0ustar /* "Disk-Video" for Unix routines. All the expanded memory caching stuff has been removed for the Unix version. We just keep the data in memory and write it out to a file when we're done. (Let virtual memory look after the details.) */ #include #include #include "port.h" #include "prototyp.h" #define BOXROW 6 #define BOXCOL 11 #define BOXWIDTH 57 #define BOXDEPTH 12 #define TIMETODISPLAY 10000 int disk16bit=0; /* storing 16 bit values for continuous potential */ static int timetodisplay; static FILE *fp = NULL; int disktarga; static int headerlength; static unsigned int rowsize = 0; /* doubles as a disk video not ok flag */ static unsigned int colsize; /* sydots, *2 when pot16bit */ static BYTE *dataPtr = NULL; int startdisk(),pot_startdisk(); void enddisk(); int targa_startdisk(FILE *, int); void targa_readdisk (unsigned int, unsigned int, BYTE *, BYTE *, BYTE *); void targa_writedisk(unsigned int, unsigned int, BYTE, BYTE, BYTE); void dvid_status(int,char *); int made_dsktemp = 0; int startdisk() { if (!diskisactive) return(0); headerlength = disktarga = 0; return (common_startdisk(sxdots,sydots,colors)); } int pot_startdisk() { int i; if (dotmode == 11) /* ditch the original disk file */ enddisk(); else showtempmsg("clearing 16bit pot work area"); headerlength = disktarga = 0; i = common_startdisk(sxdots,sydots<<1,colors); cleartempmsg(); disk16bit = 1; return (i); } int targa_startdisk(FILE *targafp,int overhead) { int i; if (dotmode == 11) { /* ditch the original disk file, make just the targa */ enddisk(); /* close the 'screen' */ setnullvideo(); /* set readdot and writedot routines to do nothing */ } headerlength = overhead; fp = targafp; disktarga = 1; i = common_startdisk(sxdots*3,sydots,colors); return (i); } int _fastcall near common_startdisk(long newrowsize, long newcolsize, int colors) { int i; long memorysize; if (diskflag) enddisk(); if (dotmode == 11) { /* otherwise, real screen also in use, don't hit it */ char buf[20]; helptitle(); setattr(1,0,C_DVID_BKGRD,24*80); /* init rest to background */ for (i = 0; i < BOXDEPTH; ++i) setattr(BOXROW+i,BOXCOL,C_DVID_LO,BOXWIDTH); /* init box */ putstring(BOXROW+2,BOXCOL+4,C_DVID_HI,"'Disk-Video' mode"); putstring(BOXROW+4,BOXCOL+4,C_DVID_LO,"Screen resolution: "); sprintf(buf,"%d x %d",sxdots,sydots); putstring(-1,-1,C_DVID_LO,buf); if (disktarga) putstring(-1,-1,C_DVID_LO," 24 bit Targa"); else { putstring(-1,-1,C_DVID_LO," Colors: "); sprintf(buf,"%d",colors); putstring(-1,-1,C_DVID_LO,buf); } putstring(BOXROW+6,BOXCOL+4,C_DVID_LO,"Save name: "); sprintf(buf,"%s",savename); putstring(-1,-1,C_DVID_LO,buf); putstring(BOXROW+8,BOXCOL+4,C_DVID_LO,"Status:"); dvid_status(0,"clearing the 'screen'"); } timetodisplay = TIMETODISPLAY; /* time-to-display-status counter */ memorysize = (long)(newcolsize) * newrowsize; diskflag = 1; rowsize = newrowsize; colsize = newcolsize; if (dataPtr != NULL) { free(dataPtr); } dataPtr = (BYTE *)malloc(memorysize); bzero(dataPtr,memorysize); /* common_okend: */ if (dotmode == 11) dvid_status(0,""); return(0); } void enddisk() { diskflag = rowsize = disk16bit = 0; fp = NULL; } int readdisk(int col, int row) { char buf[41]; if (--timetodisplay < 0) { /* time to display status? */ if (dotmode == 11) { sprintf(buf," reading line %4d", (row >= sydots) ? row-sydots : row); /* adjust when potfile */ dvid_status(0,buf); } timetodisplay = TIMETODISPLAY; } if (row>=colsize || col>=rowsize) { return 0; } return dataPtr[row*rowsize+col]; } int FromMemDisk(long offset, int size, void far *dest) { far_memcpy(dest, (void far *) (dataPtr+offset), size); return 1; } void targa_readdisk(unsigned int col, unsigned int row, BYTE *red, BYTE *green, BYTE *blue) { col *= 3; *blue = readdisk(col,row); *green = readdisk(++col,row); *red = readdisk(col+1,row); } void writedisk(int col, int row, int color) { char buf[41]; if (--timetodisplay < 0) { /* time to display status? */ if (dotmode == 11) { sprintf(buf," writing line %4d", (row >= sydots) ? row-sydots : row); /* adjust when potfile */ dvid_status(0,buf); } timetodisplay = TIMETODISPLAY; } if (row>=colsize || col>=rowsize) { return; } dataPtr[row*rowsize+col] = color; } int ToMemDisk(long offset, int size, void far *src) { far_memcpy((void far *) (dataPtr+offset), src, size); return 1; } void targa_writedisk(unsigned int col, unsigned int row, BYTE red, BYTE green, BYTE blue) { writedisk(col*=3,row,blue); writedisk(++col, row,green); writedisk(col+1, row,red); } void dvid_status(int line,char *msg) { char buf[41]; int attrib; memset(buf,' ',40); memcpy(buf,msg,strlen(msg)); buf[40] = 0; attrib = C_DVID_HI; if (line >= 100) { line -= 100; attrib = C_STOP_ERR; } putstring(BOXROW+8+line,BOXCOL+12,attrib,buf); movecursor(25,80); } xfractint-20.4.10.orig/unix/calmanfx.asm0000644000000000000000000006541410150633601014770 0ustar ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; calmanp5.asm - pentium floating point version of the calcmand.asm file ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This code started from calmanfp.asm as a base. This provided the code that ; takes care of the overhead that is needed to interface with the Fractint ; engine. The initial pentium optimizations where provided by Daniele ; Paccaloni back in March of 1995. For whatever reason, these optimizations ; didn't make it into version 19.6, which was released in May of 1997. In ; July of 1997, Tim Wegner brought to my attention an article by Agner Fog ; Titled "Pentium Optimizations". This article can currently be found at: ; http://www.azillionmonkeys.com/qed/p5opt.html ; It's a good article that claims to compare the Mandelbrot FPU code similar ; to what is in Fractint with his (and other's) pentium optimized code. The ; only similarity I was able to find was they both calculate the Mandelbrot ; set. Admittedly, the Fractint FPU Mandelbrot code was not optimized for a ; pentium. So, taking the code segments provided by Agner Fog, Terje Mathisen, ; Thomas Jentzsch, and Damien Jones, I set out to optimize Fractint's FPU ; Mandelbrot code. Unfortunately, it is not possible to just drop someone ; elses Mandelbrot code into Fractint. I made good progress, but lost ; interest after several months. ; In April of 1998, Rees Acheson (author of MANDELB), contacted me about ; included his pentium optimized Mandelbrot code in the next release of ; Fractint. This started a flurry of correspondence resulting in ; faster code in Fractint and faster code in MANDELB. His code didn't ; drop right in, but his input and feedback are much appreciated. The ; code in this file is largely due to his efforts. ; July 1998, Jonathan Osuch ; ; Updated 10 Oct 1998 by Chuck Ebbert (CAE) -- 5.17% speed gain on a P133 ; Fixed keyboard/periodicity conflict JCO 10 DEC 1999 ; %include "xfract_a.inc" ; external functions CEXTERN keypressed ;:FAR ; this routine is in 'general.asm' CEXTERN getakey ;:FAR ; this routine is in 'general.asm' CEXTERN plot_orbit ;:FAR ; this routine is in 'fracsubr.c' CEXTERN scrub_orbit ;:FAR ; this routine is in 'fracsubr.c' ; external data CEXTERN init ;:QWORD ; declared as type complex CEXTERN parm ;:QWORD ; declared as type complex CEXTERN new ;:QWORD ; declared as type complex CEXTERN maxit ;:DWORD CEXTERN inside ;:DWORD CEXTERN outside ;:DWORD CEXTERN rqlim ;:QWORD ; bailout (I never did figure out ; what "rqlim" stands for. -Wes) CEXTERN coloriter ;:DWORD CEXTERN oldcoloriter ;:DWORD CEXTERN realcoloriter ;:DWORD CEXTERN periodicitycheck ;:DWORD CEXTERN reset_periodicity ;:DWORD CEXTERN closenuff ;:QWORD CEXTERN fractype ;:DWORD ; Mandelbrot or Julia CEXTERN kbdcount ;:DWORD ; keyboard counter CEXTERN dotmode ;:DWORD CEXTERN show_orbit ;:DWORD ; "show-orbit" flag CEXTERN orbit_ptr ;:DWORD ; "orbit pointer" flag CEXTERN magnitude ;:QWORD ; when using potential CEXTERN nextsavedincr ;:dword ; for incrementing AND value CEXTERN firstsavedand ;:dword ; AND value CEXTERN bad_outside ;:dword ; old FPU code with bad ;: real,imag,mult,summ CEXTERN save_release ;:dword CEXTERN showdot ;:DWORD CEXTERN orbit_delay ;:DWORD CEXTERN atan_colors ;:DWORD JULIAFP EQU 3 ; from FRACTYPE.H MANDELFP EQU 0 KEYPRESSDELAY equ 16383 ; 3FFFh initx EQU init ; just to make life easier inity EQU init+DBLSZ parmx EQU parm parmy EQU parm+DBLSZ newx EQU new newy EQU new+8 section .data ;align 4 orbit_real DQ 0.0 orbit_imag DQ 0.0 round_down_half DQ 0.5 tmp_dword DD 0 inside_color DD 0 periodicity_color DD 7 %define savedincr edi ; space, but it doesn't hurt either ;;savedand_p5 DD 0 ;EQU EDX savedx_p5 DQ 0.0 ;:QWORD savedy_p5 DQ 0.0 ;:QWORD closenuff_p5 DQ 0.0 ;:QWORD tmp_ten_byte_1 DT 0.0 ;:tbyte tmp_ten_byte_2 DT 0.0 ;:tbyte tmp_ten_byte_3 DT 0.0 ;:tbyte tmp_ten_byte_4 DT 0.0 ;:tbyte tmp_ten_byte_5 DT 0.0 ;:tbyte Control DW 0 ;:word ;calmanp5_text: section .text ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This routine is called once per image. ; Put things here that won't change from one pixel to the next. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CGLOBAL calcmandfpasmstart_p5 calcmandfpasmstart_p5: sub eax,eax mov eax,[inside] cmp eax,0 ; if (inside color == maxiter) jnl non_neg_inside mov eax,[maxit] ; use maxit as inside_color non_neg_inside: ; else mov [inside_color],eax ; use inside as inside_color cmp dword [periodicitycheck],0 ; if periodicitycheck < 0 jnl non_neg_periodicitycheck mov eax,7 ; use color 7 (default white) non_neg_periodicitycheck: ; else mov [periodicity_color],eax ; use inside_color still in ax mov dword [oldcoloriter],0 ; no periodicity checking on 1st pixel ret ;;_calcmandfpasmstart_p5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; pentium floating point version of calcmandasm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CGLOBAL calcmandfpasm_p5 ALIGN 16 calcmandfpasm_p5: ; Register usage: eax: ?????? ebx:oldcoloriter ; ecx:counter edx:savedand_p5 ; di:???? esi:0ffffh FRAME esi, edi ; {Set up FPU stack for quick access while in the loop} ; initialization stuff sub eax,eax ; clear eax ; cmp periodicitycheck,ax ; periodicity checking? cmp dword [periodicitycheck],0 ; periodicity checking? je initoldcolor ; no, set oldcolor 0 to disable it ; cmp reset_periodicity,ax ; periodicity reset? cmp dword [reset_periodicity],0 ; periodicity reset? je initparms ; no, inherit oldcolor from prior invocation mov eax,[maxit] ; yup. reset oldcolor to maxit-250 sub eax,250 ; (avoids slowness at high maxits) initoldcolor: mov [oldcoloriter],eax ; reset oldcolor initparms: ; fld qword [closenuff] ; fstp qword [closenuff_p5] fldz ; sub eax,eax ; clear ax for below mov dword [orbit_ptr],0 ; clear orbits mov edx,1 ; edx = savedand_p5 = 1 fst qword [savedx_p5] ; savedx = 0.0 fstp qword [savedy_p5] ; savedy = 0.0 ; mov savedincr,dx mov edi,edx ; savedincr is in edi = 1 ; mov savedincr,1 ; savedincr = 1 ; mov edx,firstsavedand mov esi,0FFFFh dec dword [kbdcount] ; decrement the keyboard counter jns near nokey ; skip keyboard test if still positive mov dword [kbdcount],10 ; stuff in a low kbd count cmp dword [show_orbit],0 ; are we showing orbits? jne quickkbd ; yup. leave it that way. cmp dword [orbit_delay],0 ; are we delaying orbits? je slowkbd ; nope. change it. cmp dword [showdot],0 ; are we showing the current pixel? jge quickkbd ; yup. leave it that way. ;this may need to be adjusted, I'm guessing at the "appropriate" values -Wes slowkbd: mov dword [kbdcount],5000 ; else, stuff an appropriate count val cmp dword [dotmode],11 ; disk video? jne quickkbd ; no, leave as is shr dword [kbdcount],2 ; yes, reduce count quickkbd: call keypressed ; has a key been pressed? cmp ax,0 ; ... je nokey ; nope. proceed mov dword [kbdcount],0 ; make sure it goes negative again cmp ax,'o' ; orbit toggle hit? je orbitkey ; yup. show orbits cmp ax,'O' ; orbit toggle hit? jne keyhit ; nope. normal key. orbitkey: call getakey ; read the key for real mov eax,1 ; reset orbittoggle = 1 - orbittoggle sub eax,[show_orbit] ; ... mov [show_orbit],eax ; ... jmp short nokey ; pretend no key was hit keyhit: fninit mov eax,-1 ; return with -1 mov [coloriter],eax ; set color to -1 mov edx,eax ; put results in ax,dx ; shr edx,16 ; all 1's anyway, don't bother w/shift ret ; bail out! nokey: mov ecx,[maxit] ; initialize counter mov ebx,[oldcoloriter] cmp dword [fractype],JULIAFP ; julia or mandelbrot set? je near dojulia_p5 ; julia set - go there ; Mandelbrot _p5 initialization of stack dec ecx ; always do one already ; the fpu stack is shown below ; st(0) ... st(7) fld qword [initx] ; Cx fld qword [inity] ; Cy Cx fld qword [rqlim] ; b Cy Cx fld st2 ; Cx b Cy Cx fadd qword [parmx] ; Px+Cx b Cy Cx fld st0 ; Px+Cx Px+Cx b Cy Cx fmul st0,st0 ; (Px+Cx)^2 Px+Cx b Cy Cx fld st3 ; Cy (Px+Cx)^2 Px+Cx b Cy Cx fadd qword [parmy] ; Py+Cy (Px+Cx)^2 Px+Cx b Cy Cx jmp bottom_of_dojulia_p5 align 16 DoKeyCheck: push eax push ecx push ebx call keypressed ; has a key been pressed? pop ebx pop ecx ; cmp ax,0 ; ... or eax,eax je SkipKeyCheck ; nope. proceed pop eax jmp keyhit ALIGN 16 save_new_old_value: fld st2 ; y y^2 x^2 y x b Cy Cx fstp qword [savedy_p5] ; y^2 x^2 y x b Cy Cx fld st3 ; x y^2 x^2 y x b Cy Cx fstp qword [savedx_p5] ; y^2 x^2 y x b Cy Cx dec savedincr ; time to lengthen the periodicity? jnz near JustAfterFnstsw ; if not 0, then skip ; add edx,edx ; savedand = (savedand * 2) + 1 ; inc edx ; for longer periodicity lea edx,[edx*2+1] mov savedincr,[nextsavedincr] ; and restart counter ; test cx,KEYPRESSDELAY ; ecx holds the loop count ; test cx,0FFFFh ; test ecx,esi ; put 0FFFFh into esi above test cx,si jz DoKeyCheck jmp JustAfterFnstsw SkipKeyCheck: pop eax jmp JustAfterFnstsw ALIGN 16 do_check_p5_fast: ; call near ptr periodicity_check_p5 ; y x b Cy Cx ; REMEMBER, the cx counter is counting BACKWARDS from maxit to 0 ; fpu stack is ; y2 x2 y x b Cy Cx fld qword [savedx_p5] ; savedx y2 x2 y x ... fsub st0,st4 ; x-savedx y2 x2 y x ... fabs ; |x-savedx| y2 x2 y x ... fcomp qword [closenuff] ; y2 x2 y x ... push ax ; push AX for later fnstsw ax and ah,41h ; if |x-savedx| > closenuff jz near per_check_p5_ret_fast ; we're done fld qword [savedy_p5] ; savedy y2 x2 y x ... fsub st0,st3 ; y-savedy y2 x2 y x ... fabs ; |y-savedy| y2 x2 y x ... fcomp qword [closenuff] ; y2 x2 y x ... fnstsw ax and ah,41h ; if |y-savedy| > closenuff jz near per_check_p5_ret_fast ; we're done ; caught a cycle!!! pop ax ; undo push fcompp ; pop off y2 and x2, leaving y x ... mov eax,[maxit] mov dword [oldcoloriter],-1 ; check periodicity immediately next time mov [realcoloriter],eax ; save unadjusted realcolor as maxit mov eax,[periodicity_color] ; set color jmp overiteration_p5 dojulia_p5: ; Julia p5 initialization of stack ; note that init and parm are "reversed" fld qword [parmx] ; Cx fld qword [parmy] ; Cy Cx fld qword [rqlim] ; b Cy Cx fld qword [initx] ; x b Cy Cx fld st0 ; x x b Cy Cx fmul st0,st0 ; x^2 x b Cy Cx fld qword [inity] ; y x^2 x b Cy Cx bottom_of_dojulia_p5: fmul st2,st0 ; y x^2 xy b Cy Cx fmul st0,st0 ; y^2 x^2 xy b Cy Cx fsubp st1,st0 ; x^2-y^2 xy b Cy Cx fadd st0,st4 ; x^2-y^2+Cx xy b Cy Cx fxch ; xy x^2-y^2+Cx b Cy Cx fadd st0,st0 ; 2xy x^2-y^2+Cx b Cy Cx fadd st0,st3 ; 2xy+Cy x^2-y^2+Cx b Cy Cx ; first iteration complete ; {FPU stack all set, we're ready for the start of the loop} align 16 LoopStart: ; {While (Sqr(x) + Sqr(y) < b) and (Count < MaxIterations) do} ; {square both numbers} fld st1 ; {x, y, x, b, Cy, Cx} fmul st0,st0 ; {x^2, y, x, b, Cy, Cx} fld st1 ; {y, x^2, y, x, b, Cy, Cx} fmul st0,st0 ; {y^2, x^2, y, x, b, Cy, Cx} ; {add both squares and leave at top of stack ready for the compare} fld st1 ; {x^2, y^2, x^2, y, x, b, Cy, Cx} fadd st0,st1 ; {(y^2)+(x^2), y^2, x^2, y, x, b, Cy, Cx} ; {Check to see if (x^2)+(y^2) < b and discard (x^2)+(y^2)} fcomp st5 ; {y^2, x^2, y, x, b, Cy, Cx} cmp ecx,ebx ; put oldcoloriter in ebx above jae SkipTasks ; don't check periodicity fnstsw ax ;Get the pending NPX info into AX test ecx,edx ; save on 0, check on anything else jnz near do_check_p5_fast ; time to save a new "old" value jmp save_new_old_value ; jz save_new_old_value ; jmp do_check_p5_fast ; time to save a new "old" value align 16 per_check_p5_ret_fast: pop ax ;pop AX to continue with the FCOMP test jz short JustAfterFnstsw ;test that got us here, & pairable jmp short JustAfterFnstsw ;since we have done the FNSTSW, ; Skip over next instruction align 4 SkipTasks: fnstsw ax ; {Store the NPX status word in AX, no FWAIT} JustAfterFnstsw: ; {FPU stack again has all the required elements for terminating the loop } ; {Continue with the FCOMP test.} ; {The following does the same as SAHF; JA @LoopEnd; but in 3 fewer cycles} shr ah,1 ; {Shift right, shifts low bit into carry flag } jnc short overbailout_p5 ; {Jmp if not carry. Do while waiting for FPU } ; {Temp = Sqr(x) - Sqr(y) + Cx} {Temp = Newx} ; {Subtract y^2 from Cx ...} fsubr st0,st6 ; {Cx-y^2, x^2, y, x, b, Cy, Cx} ; CAE changed this around for Pentium, 10 Oct 1998 ; exchange this pending result with y so there's no wait for fsubr to finish fxch st2 ; {y, x^2, Cx-y^2, x, b, Cy, Cx} ; now compute x*y while the above fsubr is still running fmulp st3,st0 ; {x^2, Cx-y^2, xy, b, Cy, Cx} ; {... then add x^2 to Cx-y^2} faddp st1,st0 ; {Newx, xy, b, Cy, Cx} ; {Place the temp (Newx) in the x slot ready for next time in the ; loop, while placing xy in ST(0) to use below.} fxch st1 ; {xy, Newx, b, Cy, Cx} ; {y = (y * x * 2) + Cy (Use old x, not temp)} ; {multiply y * x was already done above so it was removed here -- CAE} ; {Now multiply x*y by 2 (add ST to ST)} fadd st0,st0 ; {x*y*2, Newx, b, Cy, Cx} ; compare was moved down so it would run concurrently with above add -- CAE cmp dword [show_orbit],0 ; is show_orbit clear ; {Finally, add Cy to x*y*2} fadd st0,st3 ; {Newy, Newx, b, Cy, Cx} jz no_show_orbit_p5 ; if so then skip call show_orbit_xy_p5 ; y x b Cy Cx align 4 no_show_orbit_p5: dec ecx jnz LoopStart ; jmp LoopStart ; {FPU stack has required elements for next loop} align 4 LoopEnd: ; {Newy, Newx, b, Cy, Cx} ; reached maxit, inside mov eax,[maxit] mov dword [oldcoloriter],-1 ; check periodicity immediately next time mov [realcoloriter],eax ; save unadjusted realcolor mov eax,[inside_color] jmp short overiteration_p5 align 4 overbailout_p5: faddp st1,st0 ; x^2+y^2 y x b Cy Cx mov eax,ecx fstp qword [magnitude] ; y x b Cy Cx sub eax,10 ; 10 more next time before checking jns no_fix_underflow_p5 ; if the number of iterations was within 10 of maxit, then subtracting ; 10 would underflow and cause periodicity checking to start right ; away. Catching a period doesn't occur as often in the pixels at ; the edge of the set anyway. sub eax,eax ; don't check next time no_fix_underflow_p5: mov [oldcoloriter],eax ; check when past this - 10 next time mov eax,[maxit] sub eax,ecx ; leave 'times through loop' in eax ; zero color fix jnz zero_color_fix_p5 inc eax ; if (eax == 0 ) eax = 1 zero_color_fix_p5: mov [realcoloriter],eax ; save unadjusted realcolor sub [kbdcount],eax ; adjust the keyboard count cmp dword [outside],-1 ; iter ? (most common case) je overiteration_p5 cmp dword [outside],-2 ; outside <= -2 ? jle to_special_outside_p5 ; yes, go do special outside options ; sub eax,eax ; clear top half of eax for next mov eax,[outside] ; use outside color jmp short overiteration_p5 to_special_outside_p5: call special_outside_p5 align 4 overiteration_p5: fstp qword [newy] ; x b Cy Cx fstp qword [newx] ; b Cy Cx ; {Pop 3 used registers from FPU stack, discarding the values. ; All we care about is ECX, the count.} fcompp fstp st0 mov [coloriter],eax cmp dword [orbit_ptr],0 ; any orbits to clear? je calcmandfpasm_ret_p5 ; nope. call scrub_orbit ; clear out any old orbits mov eax,[coloriter] ; restore color ; speed not critical here in orbit land calcmandfpasm_ret_p5: ; mov edx,eax ; {The low 16 bits already in AX} ; shr edx,16 ; {Shift high 16 bits to low 16 bits position} UNFRAME esi, edi ret ;;; _calcmandfpasm_p5 ALIGN 16 show_orbit_xy_p5: ;PROC NEAR USES ebx ecx edx esi edi ; USES is needed because in all likelyhood, plot_orbit surely ; uses these registers. It's ok to have to push/pop's here in the ; orbits as speed is not crucial when showing orbits. FRAME ebx, ecx, edx, esi, edi ; fpu stack is either ; y x b Cx Cy (p5) fld st1 ; ; x y ... ; and needs to returned as ; y ... fstp qword [orbit_real] ; y ... fst qword [orbit_imag] ; y ... mov eax,-1 ; color for plot orbit push eax ; ... ; since the number fpu registers that plot_orbit() preserves is compiler ; dependant, it's best to fstp the entire stack into 10 byte memories ; and fld them back after plot_orbit() returns. fstp tword [tmp_ten_byte_1] ; store the stack in 80 bit form fstp tword [tmp_ten_byte_2] fstp tword [tmp_ten_byte_3] fstp tword [tmp_ten_byte_4] fstp tword [tmp_ten_byte_5] ; fwait ; just to be safe ; push word ptr orbit_imag+6 ; co-ordinates for plot orbit push dword [orbit_imag+4] ; ... ; push word ptr orbit_imag+2 ; ... push dword [orbit_imag] ; ... ; push word ptr orbit_real+6 ; co-ordinates for plot orbit push dword [orbit_real+4] ; ... ; push word ptr orbit_real+2 ; ... push dword [orbit_real] ; ... call plot_orbit ; display the orbit add sp,5*4 ; clear out the parameters fld tword [tmp_ten_byte_5] fld tword [tmp_ten_byte_4] fld tword [tmp_ten_byte_3] fld tword [tmp_ten_byte_2] fld tword [tmp_ten_byte_1] ; fwait ; just to be safe UNFRAME ebx, ecx, edx, esi, edi ret ;;; show_orbit_xy_p5 ENDP ALIGN 16 special_outside_p5: ; PROC NEAR ; When type casting floating point variables to integers in C, the decimal ; is truncated. When using FIST in asm, the value is rounded. Using ; "FSUB round_down_half" causes the values to be rounded down. ; Boo-Hiss if values are negative, change FPU control word to truncate values. fstcw [Control] push word [Control] ; Save control word on the stack or word [Control], 0000110000000000b fldcw [Control] ; Set control to round towards zero cmp dword [outside],-2 jne short not_real fld st1 ; newx test dword [bad_outside],1h jz over_bad_real fsub qword [round_down_half] jmp over_good_real over_bad_real: frndint over_good_real: fistp dword [tmp_dword] add eax,7 add eax,[tmp_dword] jmp check_color not_real: cmp dword [outside],-3 jne short not_imag fld st0 ; newy test dword [bad_outside],1h jz short over_bad_imag fsub qword [round_down_half] jmp short over_good_imag over_bad_imag: frndint over_good_imag: fistp dword [tmp_dword] add eax,7 add eax,[tmp_dword] jmp check_color not_imag: cmp dword [outside],-4 jne short not_mult push ax ; save current ax value fld st0 ; newy ftst ; check to see if newy == 0 fstsw ax sahf pop ax ; retrieve ax (does not affect flags) jne short non_zero_y fcomp st0 ; pop it off the stack ; ret ; if y==0, return with normal ax jmp special_outside_ret non_zero_y: fdivr st0,st2 ; newx/newy mov [tmp_dword],eax fimul dword [tmp_dword] ; (ax,dx)*newx/newy (Use FIMUL instead of MUL test dword [bad_outside],1h jz short over_bad_mult fsub qword [round_down_half] ; to make it match the C code.) jmp short over_good_mult over_bad_mult: frndint over_good_mult: fistp dword [tmp_dword] ; fwait mov eax,[tmp_dword] jmp short check_color not_mult: cmp dword [outside],-5 jne short not_sum fld st1 ; newx fadd st0,st1 ; newx+newy test dword [bad_outside],1h jz short over_bad_summ fsub qword [round_down_half] jmp short over_good_summ over_bad_summ: frndint over_good_summ: fistp dword [tmp_dword] ; fwait add eax,[tmp_dword] jmp short check_color not_sum: cmp dword [outside],-6 ; currently always equal, but put here jne short not_atan ; for future outside types fld st0 ; newy fld st2 ; newx newy fpatan ; arctan(y/x) fimul dword [atan_colors] ; atan_colors*atan fldpi ; pi atan_colors*atan fdivp st1,st0 ; atan_colors*atan/pi fabs frndint fistp dword [tmp_dword] ; fwait mov eax,[tmp_dword] not_atan: check_color: cmp eax,[maxit] ; use UNSIGNED comparison jbe short check_release ; color < 0 || color > maxit sub eax,eax ; eax = 0 check_release: cmp dword [save_release],1961 jb short special_outside_ret cmp eax,0 jne special_outside_ret mov eax,1 ; eax = 1 special_outside_ret: pop word [Control] fldcw [Control] ; Restore control word ret ;;; special_outside_p5 ENDP ;;;calmanp5_text ENDS ;END xfractint-20.4.10.orig/unix/fpu087.c0000644000000000000000000001137111455577757013717 0ustar /* Fpu087.c * This file contains routines to replace fpu087.asm. * * This file Copyright 1991 Ken Shirriff. It may be used according to the * fractint license conditions, blah blah blah. */ #include "port.h" #include "prototyp.h" /* *---------------------------------------------------------------------- * * xxx086 -- * * Simulate integer math routines using floating point. * This will of course slow things down, so this should all be * changed at some point. * *---------------------------------------------------------------------- */ double _2_ = 2.0; double _1_ = 1.0; double PointFive = 0.5; double infinity = 1.0E+300; void FPUaptan387(double *y, double *x, double *atan) { if (isnan(*x) || isnan(*y) || isinf(*x) || isinf(*y)) *atan = 1.0; else *atan = (double)atan2l(*y,*x); } void FPUcplxmul(_CMPLX *x, _CMPLX *y, _CMPLX *z) { LDBL tx, ty; tx = (LDBL)x->x * (LDBL)y->x - (LDBL)x->y * (LDBL)y->y; ty = (LDBL)x->x * (LDBL)y->y + (LDBL)x->y * (LDBL)y->x; if (isnan(ty) || isinf(ty)) z->y = infinity; else z->y = (double)ty; if (isnan(tx) || isinf(tx)) z->x = infinity; else z->x = (double)tx; } void FPUcplxdiv(_CMPLX *x, _CMPLX *y, _CMPLX *z) { LDBL mod,tx,yxmod,yymod, yx, yy; yx = y->x; yy = y->y; mod = yx * yx + yy * yy; if (mod == 0.0 || fabs(mod) <= DBL_MIN) { z->x = infinity; z->y = infinity; overflow = 1; } else { yxmod = yx/mod; yymod = - yy/mod; tx = x->x * yxmod - x->y * yymod; z->y = (double)(x->x * yymod + x->y * yxmod); z->x = (double)tx; } } void FPUsincos(double *Angle, double *Sin, double *Cos) { if (isnan(*Angle) || isinf(*Angle)){ *Sin = 0.0; *Cos = 1.0; } else { *Sin = (double)sinl(*Angle); *Cos = (double)cosl(*Angle); } } void FPUsinhcosh(double *Angle, double *Sinh, double *Cosh) { if (isnan(*Angle) || isinf(*Angle)){ *Sinh = 1.0; *Cosh = 1.0; } else { *Sinh = (double)sinhl(*Angle); *Cosh = (double)coshl(*Angle); } if (isnan(*Sinh) || isinf(*Sinh)) *Sinh = 1.0; if (isnan(*Cosh) || isinf(*Cosh)) *Cosh = 1.0; } void FPUcplxlog(_CMPLX *x, _CMPLX *z) { LDBL mod, xx, xy; xx = x->x; xy = x->y; if (xx == 0.0 && xy == 0.0) { z->x = z->y = 0.0; overflow = 1; return; } mod = xx*xx + xy*xy; if (isnan(mod) || islessequal(mod,0) || isinf(mod)) z->x = 0.5; else z->x = (double)(0.5 * logl(mod)); if (isnan(xx) || isnan(xy) || isinf(xx) || isinf(xy)) z->y = 1.0; else z->y = (double)atan2l(xy,xx); } void FPUcplxexp387(_CMPLX *x, _CMPLX *z) { LDBL pwr,y; y = x->y; pwr = expl(x->x); if (isnan(pwr) || isinf(pwr)) pwr = 1.0; z->x = (double)(pwr*cosl(y)); z->y = (double)(pwr*sinl(y)); } /* Integer Routines */ void SinCos086(long x, long *sinx, long *cosx) { double a; a = x/(double)(1<<16); *sinx = (long) (sin(a)*(double)(1<<16)); *cosx = (long) (cos(a)*(double)(1<<16)); } void SinhCosh086(long x, long *sinx, long *cosx) { double a; a = x/(double)(1<<16); *sinx = (long) (sinh(a)*(double)(1<<16)); *cosx = (long) (cosh(a)*(double)(1<<16)); } long Exp086(x) long x; { return (long) (exp((double)x/(double)(1<<16))*(double)(1<<16)); } #define em2float(l) (*(float *)&(l)) #define float2em(f) (*(long *)&(f)) /* * Input is a 16 bit offset number. Output is shifted by Fudge. */ unsigned long ExpFudged(x, Fudge) long x; int Fudge; { return (long) (exp((double)x/(double)(1<<16))*(double)(1<0) { f *= (1 << Shift); } else { f /= (1 << -Shift); } return float2em(f); } xfractint-20.4.10.orig/unix/calcmand.c0000644000000000000000000000065710150633601014401 0ustar /* calcmand.c * This file contains routines to replace calcmand.asm. * * This file Copyright 1991 Ken Shirriff. It may be used according to the * fractint license conditions, blah blah blah. */ #include "port.h" unsigned long savedmask; long linitx, linity; int calcmandasm(void) { printf("Warning: called calcmandasm\n"); return(0); } #if 0 /* not used */ code16bit() {} checkperiod() {} code32bit() {} #endif xfractint-20.4.10.orig/unix/calmanfp.c0000644000000000000000000001110310150633601014404 0ustar /* calmanfp.c * This file contains routines to replace calmanfp.asm. * * This file Copyright 1992 Ken Shirriff. It may be used according to the * fractint license conditions, blah blah blah. */ #include "port.h" #include "prototyp.h" #include "fractype.h" extern int atan_colors; extern long firstsavedand; extern int nextsavedincr; static int inside_color, periodicity_color; void calcmandfpasmstart(void) { if (inside<0) { inside_color = maxit; } else { inside_color = inside; } if (periodicitycheck < 0) { periodicity_color = 7; } else { periodicity_color = inside_color; } oldcoloriter = 0; } #define ABS(x) ((x)<0?-(x):(x)) /* If USE_NEW is 1, the magnitude is used for periodicity checking instead of the x and y values. This is experimental. */ #define USE_NEW 0 long calcmandfpasm_c(void) { long cx; long savedand; int savedincr; long tmpfsd; #if USE_NEW double x,y,x2, y2, xy, Cx, Cy, savedmag; #else double x,y,x2, y2, xy, Cx, Cy, savedx, savedy; #endif if (periodicitycheck==0) { oldcoloriter = 0; /* don't check periodicity */ } else if (reset_periodicity!=0) { oldcoloriter = maxit - 255; } tmpfsd = maxit - firstsavedand; if (oldcoloriter > tmpfsd) /* this defeats checking periodicity immediately */ oldcoloriter = tmpfsd; /* but matches the code in StandardFractal() */ /* initparms */ #if USE_NEW savedmag = 0; #else savedx = 0; savedy = 0; #endif orbit_ptr = 0; savedand = firstsavedand; savedincr = 1; /* start checking the very first time */ kbdcount--; /* Only check the keyboard sometimes */ if (kbdcount<0) { int key; kbdcount = 1000; key = keypressed(); if (key) { if (key=='o' || key=='O') { getakey(); show_orbit = 1-show_orbit; } else { coloriter = -1; return -1; } } } cx = maxit; if (fractype != JULIAFP && fractype != JULIA) { /* Mandelbrot_87 */ Cx = init.x; Cy = init.y; x = parm.x+Cx; y = parm.y+Cy; } else { /* dojulia_87 */ Cx = parm.x; Cy = parm.y; x = init.x; y = init.y; x2 = x*x; y2 = y*y; xy = x*y; x = x2-y2+Cx; y = 2*xy+Cy; } x2 = x*x; y2 = y*y; xy = x*y; /* top_of_cs_loop_87 */ while (--cx > 0) { x = x2-y2+Cx; y = 2*xy+Cy; x2 = x*x; y2 = y*y; xy = x*y; magnitude = x2+y2; if (magnitude >= rqlim) { goto over_bailout_87; } /* no_save_new_xy_87 */ if (cx 0) */ /* reached maxit */ /* oldcoloriter = 65535; */ /* check periodicity immediately next time, remember we count down from maxit */ oldcoloriter = maxit; kbdcount -= maxit; realcoloriter = maxit; coloriter = inside_color; pop_stack: if (orbit_ptr) { scrub_orbit(); } return coloriter; over_bailout_87: if (outside<=-2) { new.x = x; new.y = y; } if (cx-10>0) { oldcoloriter = cx-10; } else { oldcoloriter = 0; } coloriter = realcoloriter = maxit-cx; /* if (realcoloriter==0) realcoloriter = 1; */ if (coloriter==0) coloriter = 1; kbdcount -= realcoloriter; if (outside==-1) { } else if (outside>-2) { coloriter = outside; } else { /* special_outside */ if (outside==REAL) { coloriter += (long)new.x + 7; } else if (outside==IMAG) { coloriter += (long)new.y + 7; } else if (outside==MULT && new.y!=0.0) { coloriter = (long)((double)coloriter * (new.x/new.y)); } else if (outside==SUM) { coloriter += (long)(new.x + new.y); } else if (outside==ATAN) { coloriter = (long)fabs(atan2(new.y,new.x)*atan_colors/PI); } /* check_color */ if ((coloriter <= 0 || coloriter > maxit) && outside!=FMOD) { if (save_release < 1961) coloriter = 0; else coloriter = 1; } } goto pop_stack; } xfractint-20.4.10.orig/unix/video.c0000644000000000000000000004670711007123103013744 0ustar #include #ifdef NCURSES #include #else #include "xfcurses.h" #endif #include "port.h" #include "prototyp.h" /* * This file contains Unix versions of the routines in video.asm * Copyright 1992 Ken Shirriff */ WINDOW *curwin; extern unsigned char *xgetfont (void); extern int startdisk (void); extern int waitkeypressed (int); extern int ctrl_window; #ifndef NCURSES extern unsigned long pixel[48]; #endif int fake_lut = 0; int istruecolor = 0; int daclearn = 0; int dacnorm = 0; int daccount = 0; int ShadowColors; int goodmode = 0; /* if non-zero, OK to read/write pixels */ void (*dotwrite) (int, int, int); /* write-a-dot routine */ int (*dotread) (int, int); /* read-a-dot routine */ void (*linewrite) (); /* write-a-line routine */ void (*lineread) (); /* read-a-line routine */ int andcolor = 0; /* "and" value used for color selection */ int diskflag = 0; /* disk video active flag */ int videoflag = 0; /* special "your-own-video" flag */ void (*swapsetup) (void) = NULL; /* setfortext/graphics setup routine */ int color_dark = 0; /* darkest color in palette */ int color_bright = 0; /* brightest color in palette */ int color_medium = 0; /* nearest to medbright grey in palette Zoom-Box values (2K x 2K screens max) */ int boxcolor = 0; /* Zoom-Box color */ int reallyega = 0; /* 1 if its an EGA posing as a VGA */ int gotrealdac = 0; /* 1 if loaddac has a dacbox */ int rowcount = 0; /* row-counter for decoder and out_line */ int video_type = 0; /* actual video adapter type: 0 = type not yet determined 1 = Hercules 2 = CGA (assumed if nothing else) 3 = EGA 4 = MCGA 5 = VGA 6 = VESA (not yet checked) 11 = 8514/A (not yet checked) 12 = TIGA (not yet checked) 13 = TARGA (not yet checked) 100 = x monochrome 101 = x 256 colors */ int svga_type = 0; /* (forced) SVGA type 1 = ahead "A" type 2 = ATI 3 = C&T 4 = Everex 5 = Genoa 6 = Ncr 7 = Oak-Tech 8 = Paradise 9 = Trident 10 = Tseng 3000 11 = Tseng 4000 12 = Video-7 13 = ahead "B" type 14 = "null" type (for testing only) */ int mode7text = 0; /* nonzero for egamono and hgc */ int textaddr = 0xb800; /* b800 for mode 3, b000 for mode 7 */ int textsafe = 0; /* 0 = default, runup chgs to 1 1 = yes 2 = no, use 640x200 3 = bios, yes plus use int 10h-1Ch 4 = save, save entire image */ #ifdef NCURSES int text_type = 1; #else int text_type = 0; #endif /* current mode's type of text: 0 = real text, mode 3 (or 7) 1 = 640x200x2, mode 6 2 = some other mode, graphics */ int textrow = 0; /* for putstring(-1,...) */ int textcol = 0; /* for putstring(..,-1,...) */ int textrbase = 0; /* textrow is relative to this */ int textcbase = 0; /* textcol is relative to this */ int vesa_detect = 1; /* set to 0 to disable VESA-detection */ int virtual = 0; /* no virtual screens, it's a DOS thing */ int video_scroll = 0; int video_startx = 0; int video_starty = 0; int vesa_xres; int vesa_yres; int chkd_vvs = 0; int video_vram = 0; /* ; |--Adapter/Mode-Name------|-------Comments-----------| ; |------INT 10H------|Dot-|--Resolution---| ; |key|--AX---BX---CX---DX|Mode|--X-|--Y-|Color| */ struct videoinfo videotable[MAXVIDEOTABLE] = { {"xfractint mode ", " ", 999, 0, 0, 0, 0, 19, 800, 600, 256}, {"unused mode ", " ", 0, 0, 0, 0, 0, 0, 0, 0, 0}, }; void setforgraphics (); void nullwrite (a, b, c) int a, b, c; { } int nullread (a, b) int a, b; { return 0; } void setnullvideo (void) { dotwrite = nullwrite; dotread = nullread; } void normalineread (); void normaline (); void putprompt (void) { wclear (curwin); /* ???? */ #ifdef NCURSES putstring (0, 0, 15, "Press operation key ('d' = redraw), or to return to Main Menu"); wrefresh (curwin); #else if (ctrl_window) putstring (0, 0, 15, "Press operation key ('d' = redraw), or to return to Main Menu"); #endif return; } /* ; ********************** Function setvideotext() ************************ ; Sets video to text mode, using setvideomode to do the work. */ void setvideotext (void) { initmode = adapter; dotmode = 0; setvideomode (3, 0, 0, 0); } void loaddac (void) { readvideopalette (); } /* ; **************** Function setvideomode(ax, bx, cx, dx) **************** ; This function sets the (alphanumeric or graphic) video mode ; of the monitor. Called with the proper values of AX thru DX. ; No returned values, as there is no particular standard to ; adhere to in this case. ; (SPECIAL "TWEAKED" VGA VALUES: if AX==BX==CX==0, assume we have a ; genuine VGA or register compatable adapter and program the registers ; directly using the coded value in DX) ; Unix: We ignore ax,bx,cx,dx. dotmode is the "mode" field in the video ; table. We use mode 19 for the X window. */ void setvideomode (ax, bx, cx, dx) int ax, bx, cx, dx; { if (diskflag) { enddisk (); } if (videoflag) { endvideo (); videoflag = 0; } goodmode = 1; switch (dotmode) { case 0: /* text */ clear (); /* touchwin(curwin); */ wrefresh (curwin); break; case 11: startdisk (); dotwrite = writedisk; dotread = readdisk; lineread = normalineread; linewrite = normaline; break; case 19: /* X window */ putprompt (); dotwrite = writevideo; dotread = readvideo; lineread = readvideoline; linewrite = writevideoline; videoflag = 1; startvideo (); setforgraphics (); break; default: printf ("Bad mode %d\n", dotmode); exit (-1); } if (dotmode != 0) { loaddac (); andcolor = colors - 1; boxcount = 0; } vesa_xres = sxdots; vesa_yres = sydots; } /* ; **************** Function getcolor(xdot, ydot) ******************* ; Return the color on the screen at the (xdot,ydot) point */ int getcolor (xdot, ydot) int xdot, ydot; { int x1, y1; x1 = xdot + sxoffs; y1 = ydot + syoffs; if (x1 < 0 || y1 < 0 || x1 >= sxdots || y1 >= sydots) return 0; return dotread (x1, y1); } /* ; ************** Function putcolor_a(xdot, ydot, color) ******************* ; write the color on the screen at the (xdot,ydot) point */ void putcolor_a (xdot, ydot, color) int xdot, ydot, color; { dotwrite (xdot + sxoffs, ydot + syoffs, color & andcolor); } /* ; **************** Function movecursor(row, col) ********************** ; Move the cursor (called before printfs) */ void movecursor (row, col) int row, col; { if (row == -1) { row = textrow; } else { textrow = row; } if (col == -1) { col = textcol; } else { textcol = col; } wmove (curwin, row, col); } /* ; **************** Function keycursor(row, col) ********************** ; Subroutine to wait cx ticks, or till keystroke pending */ int keycursor (row, col) int row, col; { movecursor (row, col); wrefresh (curwin); waitkeypressed (0); return getakey (); } /* ; PUTSTR.asm puts a string directly to video display memory. Called from C by: ; putstring(row, col, attr, string) where ; row, col = row and column to start printing. ; attr = color attribute. ; string = far pointer to the null terminated string to print. ; Written for the A86 assembler (which has much less 'red tape' than MASM) ; by Bob Montgomery, Orlando, Fla. 7-11-88 ; Adapted for MASM 5.1 by Tim Wegner 12-11-89 ; Furthur mucked up to handle graphics ; video modes by Bert Tyler 1-07-90 ; Reworked for: row,col update/inherit; ; 620x200x2 inverse video; far ptr to string; ; fix to avoid scrolling when last posn chgd; ; divider removed; newline ctl chars; PB 9-25-90 */ void putstring (row, col, attr, msg) int row, col, attr; CHAR far *msg; { int so = 0; if (row != -1) textrow = row; if (col != -1) textcol = col; #ifndef NCURSES curwin->_cur_attr = attr; #endif if (attr & INVERSE || attr & BRIGHT) { wstandout (curwin); so = 1; } wmove (curwin, textrow + textrbase, textcol + textcbase); while (1) { if (*msg == '\0') break; if (*msg == '\n') { textcol = 0; textrow++; wmove (curwin, textrow + textrbase, textcol + textcbase); } else { char *ptr; ptr = strchr (msg, '\n'); if (ptr == NULL) { waddstr (curwin, msg); break; } else { waddch (curwin, *msg); } } msg++; } if (so) { wstandend (curwin); } #ifdef NCURSES wrefresh (curwin); fflush (stdout); #else XFlush(Xdp); #endif getyx (curwin, textrow, textcol); textrow -= textrbase; textcol -= textcbase; } /* ; setattr(row, col, attr, count) where ; row, col = row and column to start printing. ; attr = color attribute. ; count = number of characters to set ; This routine works only in real color text mode. */ void setattr (row, col, attr, count) int row, col, attr, count; { int i,j; int so = 0; if (row != -1) textrow = row; if (col != -1) textcol = col; if (attr & INVERSE || attr & BRIGHT) { wstandout (curwin); so = 1; } wmove (curwin, textrow + textrbase, textcol + textcbase); #ifndef NCURSES curwin->_cur_attr = attr; for (i=0; i colors ? colors - 1 : rotate_hi; dacbot = (unsigned char *) dacbox + 3 * rotate_lo; len = (top - rotate_lo) * 3 * sizeof (unsigned char); if (dir > 0) { for (i = 0; i < inc; i++) { bcopy (dacbot, tmp, 3 * sizeof (unsigned char)); bcopy (dacbot + 3 * sizeof (unsigned char), dacbot, len); bcopy (tmp, dacbot + len, 3 * sizeof (unsigned char)); } } else { for (i = 0; i < inc; i++) { bcopy (dacbot + len, tmp, 3 * sizeof (unsigned char)); bcopy (dacbot, dacbot + 3 * sizeof (unsigned char), len); bcopy (tmp, dacbot, 3 * sizeof (unsigned char)); } } } writevideopalette (); delay (colors - daccount - 1); } /* ; ---- Help (Video) Support ; ********* Functions setfortext() and setforgraphics() ************ ; setfortext() resets the video for text mode and saves graphics data ; setforgraphics() restores the graphics mode and data ; setclear() clears the screen after setfortext() */ void setfortext (void) { } void setclear (void) { wclear (curwin); wrefresh (curwin); } void setforgraphics () { startvideo (); spindac (0, 1); } unsigned char *fontTab = NULL; /* ; ************** Function findfont(n) ****************************** ; findfont(0) returns far pointer to 8x8 font table if it can ; find it, NULL otherwise; ; nonzero parameter reserved for future use */ BYTE * findfont (fontparm) int fontparm; { if (fontTab == NULL) { fontTab = xgetfont (); } return (BYTE *) fontTab; } /* ; ******************** Zoombox functions ************************** */ /* * The IBM method is that boxx[],boxy[] is a set of locations, and boxvalues * is the values in these locations. * Instead of using this box save/restore technique, we'll put the corners * in boxx[0],boxy[0],1,2,3 and then use xor. */ void dispbox (void) { if (boxcount) { setlinemode (1); drawline (boxx[0], boxy[0], boxx[1], boxy[1]); drawline (boxx[1], boxy[1], boxx[2], boxy[2]); drawline (boxx[2], boxy[2], boxx[3], boxy[3]); drawline (boxx[3], boxy[3], boxx[0], boxy[0]); setlinemode (0); xsync (); } } void clearbox (void) { dispbox (); } int CheckForTPlus (void) { return 0; } /* ; Passing this routine 0 turns off shadow, nonzero turns it on. */ int ShadowVideo (on) int on; { return 0; } int SetupShadowVideo (void) { return 0; } /* ; adapter_detect: ; This routine performs a few quick checks on the type of ; video adapter installed. ; It sets variables video_type and textsafe, ; and fills in a few bank-switching routines. */ int done_detect = 0; void adapter_detect (void) { if (done_detect) return; done_detect = 1; textsafe = 2; if (colors == 2) { video_type = 100; } else { video_type = 101; } } /* ; **************** internal Read/Write-a-line routines ********************* ; ; These routines are called by out_line(), put_line() and get_line(). */ void normaline (y, x, lastx, pixels) int x, y, lastx; BYTE *pixels; { int i, width; width = lastx - x + 1; for (i = 0; i < width; i++) { dotwrite (x + i, y, pixels[i]); } } void normalineread (y, x, lastx, pixels) int x, y, lastx; BYTE *pixels; { int i, width; width = lastx - x + 1; for (i = 0; i < width; i++) { pixels[i] = dotread (x + i, y); } } /* ; *************** Function find_special_colors ******************** ; Find the darkest and brightest colors in palette, and a medium ; color which is reasonably bright and reasonably grey. */ void find_special_colors (void) { int maxb = 0; int minb = 9999; int med = 0; int maxgun, mingun; int brt; int i; color_dark = 0; color_medium = 7; color_bright = 15; if (colors == 2) { color_medium = 1; color_bright = 1; return; } if (!(gotrealdac || fake_lut)) return; for (i = 0; i < colors; i++) { brt = (int) dacbox[i][0] + (int) dacbox[i][1] + (int) dacbox[i][2]; if (brt > maxb) { maxb = brt; color_bright = i; } if (brt < minb) { minb = brt; color_dark = i; } if (brt < 150 && brt > 80) { maxgun = mingun = (int) dacbox[i][0]; if ((int) dacbox[i][1] > (int) dacbox[i][0]) { maxgun = (int) dacbox[i][1]; } else { mingun = (int) dacbox[i][1]; } if ((int) dacbox[i][2] > maxgun) { maxgun = (int) dacbox[i][2]; } if ((int) dacbox[i][2] < mingun) { mingun = (int) dacbox[i][2]; } if (brt - (maxgun - mingun) / 2 > med) { color_medium = i; med = brt - (maxgun - mingun) / 2; } } } } /* ; *************** Functions get_a_char, put_a_char ******************** ; Get and put character and attribute at cursor ; Hi nybble=character, low nybble attribute. Text mode only */ char get_a_char (void) { return (char) getakey (); } void put_a_char (ch) int ch; { } /* ; ***Function get_line(int row,int startcol,int stopcol, unsigned char *pixels) ; This routine is a 'line' analog of 'getcolor()', and gets a segment ; of a line from the screen and stores it in pixels[] at one byte per ; pixel ; Called by the GIF decoder */ void get_line (row, startcol, stopcol, pixels) int row, startcol, stopcol; BYTE *pixels; { if (startcol + sxoffs >= sxdots || row + syoffs >= sydots) return; lineread (row + syoffs, startcol + sxoffs, stopcol + sxoffs, pixels); } /* ; ***Function put_line(int row,int startcol,int stopcol, unsigned char *pixels) ; This routine is a 'line' analog of 'putcolor()', and puts a segment ; of a line from the screen and stores it in pixels[] at one byte per ; pixel ; Called by the GIF decoder */ void put_line (row, startcol, stopcol, pixels) int row, startcol, stopcol; BYTE *pixels; { if (startcol + sxoffs >= sxdots || row + syoffs > sydots) return; linewrite (row + syoffs, startcol + sxoffs, stopcol + sxoffs, pixels); } /* ; ***************Function out_line(pixels,linelen) ********************* ; This routine is a 'line' analog of 'putcolor()', and sends an ; entire line of pixels to the screen (0 <= xdot < xdots) at a clip ; Called by the GIF decoder */ int out_line (pixels, linelen) BYTE *pixels; int linelen; { if (rowcount + syoffs >= sydots) return 0; linewrite (rowcount + syoffs, sxoffs, linelen + sxoffs - 1, pixels); rowcount++; return 0; } /* ; far move routine for savegraphics/restoregraphics */ void movewords (len, fromptr, toptr) int len; BYTE *fromptr, *toptr; { bcopy (fromptr, toptr, len); } void swapnormread (void) { } void swapnormwrite (void) { } /* * Implement stack and unstack window functions by using multiple curses * windows. */ void savecurses (ptr) WINDOW **ptr; { ptr[0] = curwin; #ifdef NCURSES curwin = newwin (0, 0, 0, 0); #else curwin = newwin (LINES, COLS, 0, 0); #endif touchwin (curwin); wrefresh (curwin); } void restorecurses (ptr) WINDOW **ptr; { delwin (curwin); curwin = ptr[0]; touchwin (curwin); wrefresh (curwin); #ifndef NCURSES refresh(0, LINES); #endif } /* Moved the following from realdos.c to more cleanly separate the XFRACT * code. Now curses.h is only required in the unix directory. JCO 11/26/2005 */ /* * The stackscreen()/unstackscreen() functions were originally * ported to Xfractint. * These functions are useful for switching between different text screens. * For example, looking at a parameter entry using F2. */ int screenctr = 0; #define MAXSCREENS 3 static BYTE far *savescreen[MAXSCREENS]; static int saverc[MAXSCREENS+1]; void stackscreen() { int i; BYTE far *ptr; saverc[screenctr+1] = textrow*80 + textcol; if (++screenctr) { /* already have some stacked */ static char far msg[]={"stackscreen overflow"}; if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */ stopmsg(1,msg); exit(1); } if ((ptr = (savescreen[i] = (BYTE far *)farmemalloc(sizeof(int *))))) savecurses((WINDOW **)ptr); else { stopmsg(1,msg); exit(1); } setclear(); } else setfortext(); } void unstackscreen() { BYTE far *ptr; textrow = saverc[screenctr] / 80; textcol = saverc[screenctr] % 80; if (--screenctr >= 0) { /* unstack */ ptr = savescreen[screenctr]; restorecurses((WINDOW **)ptr); farmemfree(ptr); } else setforgraphics(); movecursor(-1,-1); } void discardscreen() { if (--screenctr >= 0) { /* unstack */ if (savescreen[screenctr]) { farmemfree(savescreen[screenctr]); } } else discardgraphics(); } xfractint-20.4.10.orig/unix/unixscr.c0000644000000000000000000016147011451656645014355 0ustar /* Unixscr.c * This file contains routines for the Unix port of fractint. * It uses the current window for text and creates an X window for graphics. * * This file Copyright 1991 Ken Shirriff. It may be used according to the * fractint license conditions, blah blah blah. * * Some of the X stuff is based on xloadimage by Jim Frost. * The FindWindowRoot routine is from ssetroot by Tom LaStrange. * Other root window stuff is based on xmartin, by Ed Kubaitis. * Some of the colormap stuff is from Mike Yang (mikey@sgi.com). * Some of the zoombox code is from Bill Broadley. * David Sanderson straightened out a bunch of include file problems. */ #include #include #include #ifdef NCURSES #include #endif #include #include #include #include #include #include #include #include #include #ifdef _AIX #include #endif #ifdef FPUERR #include #endif #ifdef __hpux #include #endif #include #include "helpdefs.h" #include "port.h" #include "prototyp.h" #ifndef NCURSES #include "xfcurses.h" #endif #ifdef LINUX #ifndef FNDELAY #define FNDELAY O_NDELAY #endif #endif #ifdef __SVR4 # include # define FNDELAY O_NONBLOCK #endif #include #ifdef CYGWIN #include #endif /* Check if there is a character waiting for us. */ #define input_pending() (ioctl(0,FIONREAD,&iocount),(int)iocount) /* external variables (set in the FRACTINT.CFG file, but findable here */ extern int dotmode; /* video access method (= 19) */ extern int sxdots, sydots; /* total # of dots on the screen */ extern int sxoffs, syoffs; /* offset of drawing area */ extern int colors; /* maximum colors available */ extern int adapter; extern int gotrealdac; extern int inside_help; extern float finalaspectratio; extern float screenaspect; extern int lookatmouse; extern int exitpending; #ifndef NCURSES extern int textmargin; #endif extern struct videoinfo videotable[]; /* the video-palette array (named after the VGA adapter's video-DAC) */ extern unsigned char dacbox[256][3]; extern void drawbox(); extern int text_type; extern int helpmode; extern int rotate_hi; extern void fpe_handler(); extern WINDOW *curwin; extern int screenctr; #define DEFX 800 #define DEFY 600 #define DEFXY "800x600+0+0" Display *Xdp = NULL; Window Xw = None; Window Xroot = None; GC Xgc = NULL; Visual *Xvi; Screen *Xsc = NULL; Atom wm_delete_window, wm_protocols; Colormap Xcmap; int Xdscreen; int Xdepth; char *Xdisplay = ""; char *Xgeometry = NULL; char *PSviewer = "gv"; XImage *Ximage =NULL; int Xwinwidth=DEFX,Xwinheight=DEFY; int unixDisk = 0; /* Flag if we use the disk video mode */ static Pixmap Xpixmap = 0; static XSizeHints *size_hints = NULL; static int gravity; static int xlastcolor = -1; static int xlastfcn = GXcopy; static BYTE *pixbuf = NULL; static int step = 0; static int cyclic[][3] = { {1,3,5}, {1,5,3}, {3,1,5}, {3,5,1}, {5,1,3}, {5,3,1}, {1,3,7}, {1,7,3}, {3,1,7}, {3,7,1}, {7,1,3}, {7,3,1}, {1,5,7}, {1,7,5}, {5,1,7}, {5,7,1}, {7,1,5}, {7,5,1}, {3,5,7}, {3,7,5}, {5,3,7}, {5,7,3}, {7,3,5}, {7,5,3} }; static int onroot = 0; static int fullscreen = 0; static int sharecolor = 0; static int privatecolor = 0; static int fixcolors = 0; static int synch = 0; /* Run X events synchronously (debugging) */ static int simple_input = 0; /* Use simple input (debugging) */ static int drawing_or_drawn = 0; /* Is image (being) drawn ? */ static int old_fcntl; static int doesBacking; int ctrl_window = 0; /* Don't use a control window by default */ int slowdisplay = 0; /* We have a slow display, so don't print too much */ int resize_flag = 1; /* Window resize flags */ /* Bit 2^0 : we are on start-up */ /* Bit 2^1 : Ximage recreated - needs recalculation */ /* Bit 2^2 : window has been resized from WM */ /* * The pixtab stuff is so we can map from fractint pixel values 0-n to * the actual color table entries which may be anything. */ static int usepixtab = 0; static int ipixtab[256]; static unsigned long pixtab[256]; typedef unsigned long XPixel; static XPixel cmap_pixtab[256]; /* for faking a LUTs on non-LUT visuals */ static int cmap_pixtab_alloced; static unsigned long do_fake_lut(int idx) { return fake_lut ? cmap_pixtab[idx] : idx; } #define FAKE_LUT(idx_) do_fake_lut(idx_) static int fastmode = 0; /* Don't draw pixels 1 at a time */ static int alarmon = 0; /* 1 if the refresh alarm is on */ static int doredraw = 0; /* 1 if we have a redraw waiting */ /* Static routines */ static Window FindRootWindow(Display *dpy, int screen); static Window pr_dwmroot(Display *dpy, Window pwin); static int errhand(Display *dp, XErrorEvent *xe); static int ioerrhand(Display *dp); static int getachar(void); static int handleesc(void); static int translatekey(int ch); static int xcmapstuff(void); static void xhandleevents(void); static void RemoveRootPixmap(void); static void doneXwindow(void); static void initdacbox(void); static void setredrawscreen(void); static void clearXwindow(void); #ifdef FPUERR static void continue_hdl(int sig, int code, struct sigcontext *scp, char *addr); #endif static int mousefkey[4][4] /* [button][dir] */ = { {RIGHT_ARROW,LEFT_ARROW,DOWN_ARROW,UP_ARROW}, {0,0,PAGE_DOWN,PAGE_UP}, {CTL_PLUS,CTL_MINUS,CTL_DEL,CTL_INSERT}, {CTL_END,CTL_HOME,CTL_PAGE_DOWN,CTL_PAGE_UP} }; /* *---------------------------------------------------------------------- * * unixarg -- * * See if we want to do something with the argument. * * Results: * Returns 1 if we parsed the argument. * * Side effects: * Increments i if we use more than 1 argument. * *---------------------------------------------------------------------- */ int unixarg(argc,argv,i) int argc; char **argv; int *i; { if (strcmp(argv[*i],"-display")==0 && (*i)+1200) textmargin = 200; (*i)++; return 1; } else if (strcmp(argv[*i],"-font")==0 && *i+1=sizeof(FLOAT4)\n"); exit(-1); } initscr(); curwin = stdscr; cbreak(); noecho(); #ifdef NCURSES if (standout()) { standend(); } #endif initdacbox(); if (!simple_input) { signal(SIGINT,(SignalHandler)goodbye); } signal(SIGFPE, fpe_handler); /* signal(SIGTSTP,goodbye); */ #ifdef FPUERR signal(SIGABRT,SIG_IGN); /* setup the IEEE-handler to forget all common ( invalid, divide by zero, overflow ) signals. Here we test, if such ieee trapping is supported. */ if (ieee_handler("set","common",continue_hdl) != 0 ) printf("ieee trapping not supported here \n"); #endif } /* *---------------------------------------------------------------------- * * UnixDone -- * * Cleanup windows and stuff. * * Results: * None. * * Side effects: * Cleans up. * *---------------------------------------------------------------------- */ void UnixDone() { if (!unixDisk) { doneXwindow(); } if (!simple_input) { fcntl(0,F_SETFL,old_fcntl); } while (screenctr) discardscreen(); #ifdef NCURSES mvcur(0,COLS-1, LINES-1,0); #endif nocbreak(); echo(); endwin(); } /* *---------------------------------------------------------------------- * * errhand -- * * Called on an X server error. * * Results: * None. * * Side effects: * Prints the error message. * *---------------------------------------------------------------------- */ static int errhand(dp,xe) Display *dp; XErrorEvent *xe; { char buf[200]; fflush(stdout); printf("X Error: %d %d %d %d\n",xe->type,xe->error_code, xe->request_code, xe->minor_code); XGetErrorText(dp,xe->error_code,buf,200); printf("%s\n",buf); return(0); } /* *---------------------------------------------------------------------- * * ioerrhand -- * * Called on an X IO server error. * * Results: * None. * * Side effects: * Prints the error message. * *---------------------------------------------------------------------- */ static int ioerrhand(dp) Display *dp; { UnixDone(); fflush(stdout); printf("Fatal X IO error on display %s\n", DisplayString(dp)); return(0); } #ifdef FPUERR /* *---------------------------------------------------------------------- * * continue_hdl -- * * Handle an IEEE fpu error. * This routine courtesy of Ulrich Hermes * * * Results: * None. * * Side effects: * Clears flag. * *---------------------------------------------------------------------- */ static void continue_hdl(sig,code,scp,addr) int sig, code; struct sigcontext *scp; char *addr; { int i; char out[20]; /* if you want to get all messages enable this statement. */ /* printf("ieee exception code %x occurred at pc %X\n",code,scp->sc_pc); */ /* clear all excaption flags */ i = ieee_flags("clear","exception","all",out); } #endif static void select_visual(void) { Xvi = XDefaultVisualOfScreen(Xsc); Xdepth = DefaultDepth(Xdp, Xdscreen); switch (Xvi->class) { case StaticGray: case StaticColor: colors = 1 << Xdepth; gotrealdac = 0; fake_lut = 0; istruecolor = 0; break; case GrayScale: case PseudoColor: colors = 1 << Xdepth; gotrealdac = 1; fake_lut = 0; istruecolor = 0; break; case TrueColor: case DirectColor: colors = 256; gotrealdac = 0; fake_lut = 1; istruecolor = 0; break; default: /* those should be all the visual classes */ assert(1); break; } if (colors > 256) colors = 256; if (gotrealdac) active_system = 0; else active_system = 1; } /* *---------------------------------------------------------------------- * * initUnixWindow -- * * Make the X window. * * Results: * None. * * Side effects: * Makes window. * *---------------------------------------------------------------------- */ void error_display() { fprintf(stderr, "Could not open display %s\n", Xdisplay); fprintf(stderr, "Note: 'fractint -disk' can run without X\n"); } void initUnixWindow() { XSetWindowAttributes Xwatt; XGCValues Xgcvals; int i, Xwinx = 0, Xwiny = 0; if (Xdp != NULL #ifdef NCURSES ) { #else && Xsc != NULL) { #endif /* We are already initialized */ return; } if (!simple_input) { old_fcntl = fcntl(0, F_GETFL); fcntl(0, F_SETFL, FNDELAY); } adapter = 0; /* We have to do some X stuff even for disk video, to parse the geometry * string */ if (unixDisk) { #ifndef NCURSES Xw = Xwc; stackscreen(); #endif fastmode = 0; fake_lut = 0; istruecolor = 0; gotrealdac = 1; colors = 256; for (i = 0; i < colors; i++) { pixtab[i] = i; ipixtab[i] = i; } if (fixcolors > 0) { colors = fixcolors; } if (Xgeometry) { XParseGeometry(Xgeometry, &Xwinx, &Xwiny, (unsigned int *) &Xwinwidth, (unsigned int *) &Xwinheight); } Xwinwidth &= -4; Xwinheight &= -4; sxdots = Xwinwidth; sydots = Xwinheight; } else { /* Use X window */ size_hints = XAllocSizeHints(); if (size_hints == NULL) { error_display(); UnixDone(); exit(-1); } #ifdef NCURSES Xdp = XOpenDisplay(Xdisplay); if (Xdp == NULL) { error_display(); UnixDone(); exit(-1); } Xdscreen = XDefaultScreen(Xdp); #else Open_XDisplay(); #endif if (Xgeometry && !onroot) { XParseGeometry(Xgeometry, &Xwinx, &Xwiny, (unsigned int *) &Xwinwidth, (unsigned int *) &Xwinheight); /* next line breaks -geometry, JCO XWMGeometry(Xdp, Xdscreen, Xgeometry, DEFXY, 0, size_hints, &Xwinx, &Xwiny, &Xwinwidth, &Xwinheight, &gravity); */ } if (synch) { XSynchronize(Xdp, True); } XSetErrorHandler(errhand); XSetIOErrorHandler(ioerrhand); Xsc = ScreenOfDisplay(Xdp, Xdscreen); select_visual(); if (fixcolors > 0) { colors = fixcolors; } if (fullscreen || onroot) { Xwinwidth = DisplayWidth(Xdp, Xdscreen); Xwinheight = DisplayHeight(Xdp, Xdscreen); } sxdots = Xwinwidth; sydots = Xwinheight; size_hints->flags = USPosition | USSize | PBaseSize | PResizeInc; size_hints->base_width = 320; size_hints->base_height = 200; size_hints->width_inc = 4; size_hints->height_inc = 4; size_hints->x = Xwinx; size_hints->y = Xwiny; Xwatt.background_pixel = BlackPixelOfScreen(Xsc); Xwatt.bit_gravity = StaticGravity; doesBacking = DoesBackingStore(Xsc); if (doesBacking) { Xwatt.backing_store = Always; } else { Xwatt.backing_store = NotUseful; } if (onroot) { Xroot = FindRootWindow(Xdp, Xdscreen); RemoveRootPixmap(); Xgc = XCreateGC(Xdp, Xroot, 0, &Xgcvals); Xpixmap = XCreatePixmap(Xdp, Xroot, Xwinwidth, Xwinheight, Xdepth); Xw = Xroot; XFillRectangle(Xdp, Xpixmap, Xgc, 0, 0, Xwinwidth, Xwinheight); XSetWindowBackgroundPixmap(Xdp, Xroot, Xpixmap); } else { Xroot = DefaultRootWindow(Xdp); #ifndef NCURSES if (Xwc && !ctrl_window) Xw = Xwc; else #endif Xw = XCreateWindow(Xdp, Xroot, Xwinx, Xwiny, Xwinwidth, Xwinheight, 0, Xdepth, InputOutput, CopyFromParent, CWBackPixel | CWBitGravity | CWBackingStore, &Xwatt); XSelectInput(Xdp, Xw, ExposureMask|StructureNotifyMask| KeyPressMask|KeyReleaseMask| ButtonPressMask|ButtonReleaseMask|PointerMotionMask); XStoreName(Xdp, Xw, Fractint); Xgc = XCreateGC(Xdp, Xw, 0, &Xgcvals); } colors = xcmapstuff(); if (rotate_hi == 255) rotate_hi = colors-1; XSetWMNormalHints(Xdp, Xw, size_hints); wm_protocols = XInternAtom(Xdp, "WM_PROTOCOLS", False); wm_delete_window = XInternAtom(Xdp, "WM_DELETE_WINDOW", False); XSetWMProtocols(Xdp, Xw, &wm_delete_window, 1); if (!onroot) { XSetBackground(Xdp, Xgc, FAKE_LUT(pixtab[0])); XSetForeground(Xdp, Xgc, FAKE_LUT(pixtab[1])); Xwatt.background_pixel = FAKE_LUT(pixtab[0]); XChangeWindowAttributes(Xdp, Xw, CWBackPixel, &Xwatt); XMapRaised(Xdp, Xw); } } writevideopalette(); videotable[0].xdots = sxdots; videotable[0].ydots = sydots; videotable[0].colors = colors; videotable[0].dotmode = (unixDisk) ? 11 : 19; } /* *---------------------------------------------------------------------- * * doneXwindow -- * * Clean up the X stuff. * * Results: * None. * * Side effects: * Frees window, etc. * *---------------------------------------------------------------------- */ static void doneXwindow() { if (Xdp==NULL) { return; } if (Xgc) { XFreeGC(Xdp,Xgc); Xgc = None; } if (Xpixmap) { XFreePixmap(Xdp,Xpixmap); Xpixmap = (Pixmap)NULL; } XFlush(Xdp); if (size_hints) { XFree(size_hints); } #ifndef NCURSES if (Xwc!=Xw) { XDestroyWindow(Xdp, Xwc); Xwc = None; } if (Xwp) XDestroyWindow(Xdp, Xwp); Xwp = None; #endif if (Xw) XDestroyWindow(Xdp, Xw); Xw = None; XCloseDisplay(Xdp); Xdp = NULL; } /* *---------------------------------------------------------------------- * * clearXwindow -- * * Clears X window. * * Results: * None. * * Side effects: * Clears window. * *---------------------------------------------------------------------- */ static void clearXwindow() { int i; if (fake_lut) { int j; for (j = 0; j < Ximage->height; j++) for (i = 0; i < Ximage->width; i++) XPutPixel(Ximage, i, j, cmap_pixtab[pixtab[0]]); } else if (pixtab[0] != 0) { /* * Initialize image to pixtab[0]. */ if (colors == 2) { for (i = 0; i < Ximage->bytes_per_line; i++) { Ximage->data[i] = 0xff; } } else { for (i = 0; i < Ximage->bytes_per_line; i++) { Ximage->data[i] = pixtab[0]; } } for (i = 1; i < Ximage->height; i++) { bcopy(Ximage->data, Ximage->data+i*Ximage->bytes_per_line, Ximage->bytes_per_line); } } else { /* * Initialize image to 0's. */ bzero(Ximage->data, Ximage->bytes_per_line*Ximage->height); } xlastcolor = -1; XSetForeground(Xdp, Xgc, FAKE_LUT(pixtab[0])); if (onroot) { XFillRectangle(Xdp, Xpixmap, Xgc, 0, 0, Xwinwidth, Xwinheight); } XFillRectangle(Xdp, Xw, Xgc, 0, 0, Xwinwidth, Xwinheight); xsync(); drawing_or_drawn = 0; } /* *---------------------------------------------------------------------- * * initdacbox -- * * Put something nice in the dac. * * The conditions are: * Colors 1 and 2 should be bright so ifs fractals show up. * Color 15 should be bright for lsystem. * Color 1 should be bright for bifurcation. * Colors 1,2,3 should be distinct for periodicity. * The color map should look good for mandelbrot. * The color map should be good if only 128 colors are used. * * Results: * None. * * Side effects: * Loads the dac. * *---------------------------------------------------------------------- */ static void initdacbox() { int i, j, k, s0, sp; if (mapdacbox || colorpreloaded) return; /* map= specified */ s0 = step & 1; sp = step/2; if (sp) { --sp; s0 = 1-s0; for (i=0; i<256; i++) { for (j=0; j<3; j++) { k = (i*(cyclic[sp][j])) & 127; if (k < 64) dacbox[i][j] = k; else dacbox[i][j] = (127 - k); } } } else { for (i=0;i<256;i++) { dacbox[i][0] = (i>>5)*8+7; dacbox[i][1] = (((i+16)&28)>>2)*8+7; dacbox[i][2] = (((i+2)&3))*16+15; } dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; dacbox[1][0] = dacbox[1][1] = dacbox[1][2] = 63; dacbox[2][0] = 47; dacbox[2][1] = dacbox[2][2] = 63; } if (s0) for (i=0; i<256; i++) for (j=0; j<3; j++) dacbox[i][j] = 63 - dacbox[i][j]; } int startvideo() { clearXwindow(); return(0); } int endvideo() { return(0); /* set flag: video ended */ } /* *---------------------------------------------------------------------- * * resizeWindow -- * * Look after resizing the window if necessary. * * Results: * Returns 1 for resize, 0 for no resize. * * Side effects: * May reallocate data structures. * *---------------------------------------------------------------------- */ int resizeWindow() { static int oldx = -1, oldy = -1; int junki; unsigned int junkui; Window junkw; unsigned int width, height; int Xmwidth, Xpad; #ifdef NCURSES if (unixDisk) return 0; #endif if (resize_flag & 4) { Window root, parent, *children; resize_flag &= ~4; parent = 0; XQueryTree(Xdp, Xw, &root, &parent, &children, &junkui); if (!parent) parent = Xw; XGetGeometry(Xdp, parent, &root, &junki, &junki, &width, &height, &junkui, &junkui); #ifndef NCURSES if (!ctrl_window || unixDisk) { set_margins(width, height); refresh(0, LINES); } #endif } else XGetGeometry(Xdp,Xw,&junkw,&junki, &junki, &width, &height, &junkui, &junkui); if (oldx != width || oldy != height) { sxdots = width & -4; sydots = height & -4; videotable[0].xdots = sxdots; videotable[0].ydots = sydots; oldx = sxdots; oldy = sydots; Xwinwidth = sxdots; Xwinheight = sydots; screenaspect = sydots/(float)sxdots; finalaspectratio = screenaspect; Xpad = 8; /* default, unless changed below */ if (Xdepth==1) Xmwidth = 1 + sxdots/8; else if (Xdepth<=8) Xmwidth = sxdots; else if (Xdepth<=16) { /* 15 or 16 bpp */ Xmwidth = 2*sxdots; Xpad = 16; } else { /* 24 or 32 bpp */ Xmwidth = 4*sxdots; Xpad = 32; } if (pixbuf != NULL) { free(pixbuf); } pixbuf = (BYTE *) malloc(Xwinwidth *sizeof(BYTE)); if (Ximage != NULL) XDestroyImage(Ximage); Ximage = XCreateImage(Xdp, Xvi, Xdepth, ZPixmap, 0, NULL, sxdots, sydots, Xpad, Xmwidth); if (Ximage == NULL) { fprintf(stderr,"XCreateImage failed\n"); UnixDone(); exit(-1); } Ximage->data = malloc(Ximage->bytes_per_line * Ximage->height); if (Ximage->data==NULL) { fprintf(stderr,"Malloc failed: %d\n", Ximage->bytes_per_line * Ximage->height); exit(-1); } if (screenctr) { bzero(Ximage->data, Ximage->bytes_per_line*Ximage->height); drawing_or_drawn = 0; } if (resize_flag & 1) resize_flag &= ~1; else resize_flag |= 2; XSync(Xdp, True); usleep(10000); return 1; } else { return 0; } } /* *---------------------------------------------------------------------- * * xcmapstuff -- * * Set up the colormap appropriately * * Results: * Number of colors. * * Side effects: * Sets colormap. * *---------------------------------------------------------------------- */ static int xcmapstuff() { int ncells, i, powr; if (onroot) { privatecolor = 0; } for (i = 0; i < colors; i++) { pixtab[i] = i; ipixtab[i] = 999; } if (!gotrealdac) { Xcmap = DefaultColormapOfScreen(Xsc); if (fake_lut) writevideopalette(); } else if (sharecolor) { gotrealdac = 0; } else if (privatecolor) { Xcmap = XCreateColormap(Xdp, Xw, Xvi, AllocAll); XSetWindowColormap(Xdp, Xw, Xcmap); } else { Xcmap = DefaultColormap(Xdp, Xdscreen); for (powr = Xdepth; powr >= 1; powr--) { ncells = 1 << powr; if (ncells > colors) continue; if (XAllocColorCells(Xdp, Xcmap, False, NULL, 0, pixtab, (unsigned int) ncells)) { colors = ncells; fprintf(stderr,"%d colors\n", colors); usepixtab = 1; break; } } if (!usepixtab) { fprintf(stderr,"Couldn't allocate any colors\n"); gotrealdac = 0; } } for (i = 0; i < colors; i++) { ipixtab[pixtab[i]] = i; } /* We must make sure if any color uses position 0, that it is 0. * This is so we can clear the image with bzero. * So, suppose fractint 0 = cmap 42, cmap 0 = fractint 55. * Then want fractint 0 = cmap 0, cmap 42 = fractint 55. * I.e. pixtab[55] = 42, ipixtab[42] = 55. */ if (ipixtab[0] == 999) { ipixtab[0] = 0; } else if (ipixtab[0] != 0) { int other; other = ipixtab[0]; pixtab[other] = pixtab[0]; ipixtab[pixtab[other]] = other; pixtab[0] = 0; ipixtab[0] = 0; } if (!gotrealdac && colors == 2 && BlackPixelOfScreen(Xsc) != 0) { pixtab[0] = ipixtab[0] = 1; pixtab[1] = ipixtab[1] = 0; usepixtab = 1; } return colors; } /* *---------------------------------------------------------------------- * * writevideoline -- * * Write a line of pixels to the screen. * * Results: * None. * * Side effects: * Draws pixels. * *---------------------------------------------------------------------- */ void writevideoline(y,x,lastx,pixels) int x,y,lastx; BYTE *pixels; { int width; int i; BYTE *pixline; drawing_or_drawn = 1; #if 1 if (x==lastx) { writevideo(x,y,pixels[0]); return; } width = lastx-x+1; if (usepixtab) { for (i=0;i=colors || color < 0) { fprintf(stderr,"Color %d too big %d\n", color, colors); } if (x>=sxdots || x<0 || y>=sydots || y<0) { fprintf(stderr,"Bad coord %d %d\n", x,y); } #endif if (xlastcolor != color) { XSetForeground(Xdp, Xgc, FAKE_LUT(pixtab[color])); xlastcolor = color; } XPutPixel(Ximage, x, y, FAKE_LUT(pixtab[color])); if (fastmode == 1 && helpmode != HELPXHAIR) { if (!alarmon) { schedulealarm(0); } } else { XDrawPoint(Xdp,Xw,Xgc,x,y); if (onroot) { XDrawPoint(Xdp,Xpixmap,Xgc,x,y); } } } /* *---------------------------------------------------------------------- * * readvideo -- * * Read a point from the screen * * Results: * Value of point. * * Side effects: * None. * *---------------------------------------------------------------------- */ int readvideo(int x, int y) { #ifdef DEBUG /* Debugging checks */ if (x>=sxdots || x<0 || y>=sydots || y<0) { fprintf(stderr,"Bad coord %d %d\n", x,y); } #endif if (fake_lut) { int i; XPixel pixel = XGetPixel(Ximage, x, y); for (i = 0; i < colors; i++) if (cmap_pixtab[i] == pixel) return i; return 0; } else return ipixtab[XGetPixel(Ximage, x, y)]; } XColor cols[256]; /* *---------------------------------------------------------------------- * * readvideopalette -- * Reads the current video palette into dacbox. * * * Results: * None. * * Side effects: * Fills in dacbox. * *---------------------------------------------------------------------- */ int readvideopalette() { int i; if (gotrealdac==0 && istruecolor && truemode) return -1; for (i=0;i truecolor, directcolor displays */ static unsigned char last_dac[256][3]; static int last_dac_inited = False; for (i = 0; i < colors; i++) { if (!last_dac_inited || last_dac[i][0] != dacbox[i][0] || last_dac[i][1] != dacbox[i][1] || last_dac[i][2] != dacbox[i][2]) { cols[i].flags = DoRed | DoGreen | DoBlue; cols[i].red = dacbox[i][0]*1024; cols[i].green = dacbox[i][1]*1024; cols[i].blue = dacbox[i][2]*1024; /* This seems not to work in truecolor modes, so commented out! if (cmap_pixtab_alloced) { XFreeColors(Xdp, Xcmap, cmap_pixtab + i, 1, None); } */ if (XAllocColor(Xdp, Xcmap, &cols[i])) { cmap_pixtab[i] = cols[i].pixel; } else { assert(1); fprintf(stderr,"Allocating color %d failed.\n", i); } last_dac[i][0] = dacbox[i][0]; last_dac[i][1] = dacbox[i][1]; last_dac[i][2] = dacbox[i][2]; } } cmap_pixtab_alloced = True; last_dac_inited = True; } else { /* !gotrealdac, !fake_lut => static color, static gray displays */ assert(1); } } else { /* gotrealdac => grayscale or pseudocolor displays */ for (i = 0; i < colors; i++) { cols[i].pixel = pixtab[i]; cols[i].flags = DoRed | DoGreen | DoBlue; cols[i].red = dacbox[i][0]*1024; cols[i].green = dacbox[i][1]*1024; cols[i].blue = dacbox[i][2]*1024; } if (!unixDisk) { XStoreColors(Xdp, Xcmap, cols, colors); XFlush(Xdp); /* None of these changed the colors without redrawing the fractal XSetWindowColormap(Xdp, Xw, Xcmap); XDrawRectangle(Xdp, Xw, Xgc, 0, 0, Xwinwidth, Xwinheight); XPutImage(Xdp,Xw,Xgc,Ximage,0,0,0,0,Xwinwidth,Xwinheight); XCopyArea(Xdp,Xw,Xw,Xgc,0,0,Xwinwidth,Xwinheight,0,0); XFlush(Xdp); */ } } return 0; } /* *---------------------------------------------------------------------- * * setlinemode -- * * Set line mode to 0=draw or 1=xor. * * Results: * None. * * Side effects: * Sets mode. * *---------------------------------------------------------------------- */ void setlinemode(mode) int mode; { if (unixDisk) return; xlastcolor = -1; if (mode==0) { XSetFunction(Xdp, Xgc, GXcopy); xlastfcn = GXcopy; } else { XSetForeground(Xdp, Xgc, WhitePixel(Xdp, Xdscreen)); xlastcolor = -1; XSetFunction(Xdp, Xgc, GXxor); xlastfcn = GXxor; } } /* *---------------------------------------------------------------------- * * drawline -- * * Draw a line. * * Results: * None. * * Side effects: * Modifies window. * *---------------------------------------------------------------------- */ void drawline(x1,y1,x2,y2) int x1,y1,x2,y2; { if (!unixDisk) { XDrawLine(Xdp,Xw,Xgc,x1,y1,x2,y2); } } /* *---------------------------------------------------------------------- * * xsync -- * * Sync the x server * * Results: * None. * * Side effects: * Modifies window. * *---------------------------------------------------------------------- */ void xsync() { if (!unixDisk) { XSync(Xdp,False); } } /* *---------------------------------------------------------------------- * * getachar -- * * Gets a character. * * Results: * Key. * * Side effects: * Reads key. * *---------------------------------------------------------------------- */ static int getachar() { if (simple_input) { return getchar(); } else { char ch; int status; status = read(0,&ch,1); if (status<0) { return -1; } else { return ch; } } } static int xbufkey = 0; /* Buffered X key */ /* *---------------------------------------------------------------------- * * xgetkey -- * * Get a key from the keyboard or the X server. * Blocks if block = 1. * * Results: * Key, or 0 if no key and not blocking. * Times out after .5 second. * * Side effects: * Processes X events. * *---------------------------------------------------------------------- */ int xgetkey(block) int block; { static int skipcount = 0; int ch; fd_set reads; int status; static struct timeval tout; tout.tv_sec = 0; tout.tv_usec = 500000; while (1) { #if 0 if (input_pending()) { ch = getachar(); if (ch == ESC) { return handleesc(); } else { return translatekey(ch); } } #endif /* Don't check X events every time, since that is expensive */ skipcount++; if (block==0 && skipcount<25) break; skipcount = 0; #ifdef NCURSES if (!unixDisk) { xhandleevents(); } #else xhandleevents(); #endif if (xbufkey) { ch = xbufkey; xbufkey = 0; skipcount = 9999; /* If we got a key, check right away next time */ if (ch == ESC) { return handleesc(); } else { return translatekey(ch); } } if (!block) break; FD_ZERO(&reads); FD_SET(0,&reads); if (unixDisk) { status = select(1,&reads,NULL,NULL,&tout); } else { FD_SET(ConnectionNumber(Xdp),&reads); status = select(ConnectionNumber(Xdp)+1,&reads,NULL,NULL,&tout); } if (status<=0) { return 0; } } return 0; } /* *---------------------------------------------------------------------- * * translatekey -- * * Translate an input key into MSDOS format. The purpose of this * routine is to do the mappings like U -> PAGE_UP. * * Results: * New character; * * Side effects: * None. * *---------------------------------------------------------------------- */ static int translatekey(ch) int ch; { if (ch>='a' && ch<='z') { return ch; } else { switch (ch) { case 'I': return INSERT; case 'D': return DELETE; case 'U': return PAGE_UP; case 'N': return PAGE_DOWN; case CTL('O'): return CTL_HOME; #if 0 case CTL('E'): return CTL_END; #endif case 'H': return LEFT_ARROW; case 'L': return RIGHT_ARROW; case 'K': return UP_ARROW; case 'J': return DOWN_ARROW; case 1115: return LEFT_ARROW_2; case 1116: return RIGHT_ARROW_2; case 1141: return UP_ARROW_2; case 1145: return DOWN_ARROW_2; case 'O': return HOME; case 'E': return END; case '\n': return ENTER; case CTL('T'): return CTL_ENTER; case -2: return CTL_ENTER_2; case CTL('U'): return CTL_PAGE_UP; case CTL('N'): return CTL_PAGE_DOWN; case '{': return CTL_MINUS; case '}': return CTL_PLUS; /* we need ^I for tab */ #if 0 case CTL('I'): return CTL_INSERT; #endif case CTL('D'): return CTL_DEL; case '!': return F1; case '@': return F2; #if 0 case '#': return F3; #endif case '$': return F4; case '%': return F5; case '^': return F6; case '&': return F7; case '*': return F8; case '(': return F9; case ')': return F10; default: return ch; } } } /* *---------------------------------------------------------------------- * * handleesc -- * * Handle an escape key. This may be an escape key sequence * indicating a function key was pressed. * * Results: * Key. * * Side effects: * Reads keys. * *---------------------------------------------------------------------- */ static int handleesc() { int ch1,ch2,ch3; if (simple_input) { return ESC; } #ifdef __hpux /* HP escape key sequences. */ ch1 = getachar(); if (ch1==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch1 = getachar(); } if (ch1==-1) { return ESC; } switch (ch1) { case 'A': return UP_ARROW; case 'B': return DOWN_ARROW; case 'D': return LEFT_ARROW; case 'C': return RIGHT_ARROW; case 'd': return HOME; } if (ch1 != '[') return ESC; ch1 = getachar(); if (ch1==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch1 = getachar(); } if (ch1==-1 || !isdigit(ch1)) return ESC; ch2 = getachar(); if (ch2==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch2 = getachar(); } if (ch2==-1) return ESC; if (isdigit(ch2)) { ch3 = getachar(); if (ch3==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch3 = getachar(); } if (ch3 != '~') return ESC; ch2 = (ch2-'0')*10+ch3-'0'; } else if (ch3 != '~') { return ESC; } else { ch2 = ch2-'0'; } switch (ch2) { case 5: return PAGE_UP; case 6: return PAGE_DOWN; case 29: return F1; /* help */ case 11: return F1; case 12: return F2; case 13: return F3; case 14: return F4; case 15: return F5; case 17: return F6; case 18: return F7; case 19: return F8; default: return ESC; } #else /* SUN escape key sequences */ ch1 = getachar(); if (ch1==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch1 = getachar(); } if (ch1 != '[') { /* See if we have esc [ */ return ESC; } ch1 = getachar(); if (ch1==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch1 = getachar(); } if (ch1==-1) { return ESC; } switch (ch1) { case 'A': /* esc [ A */ return UP_ARROW; case 'B': /* esc [ B */ return DOWN_ARROW; case 'C': /* esc [ C */ return RIGHT_ARROW; case 'D': /* esc [ D */ return LEFT_ARROW; default: break; } ch2 = getachar(); if (ch2==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch2 = getachar(); } if (ch2 == '~') { /* esc [ ch1 ~ */ switch (ch1) { case '2': /* esc [ 2 ~ */ return INSERT; case '3': /* esc [ 3 ~ */ return DELETE; case '5': /* esc [ 5 ~ */ return PAGE_UP; case '6': /* esc [ 6 ~ */ return PAGE_DOWN; default: return ESC; } } else if (ch2==-1) { return ESC; } else { ch3 = getachar(); if (ch3==-1) { delay(250); /* Wait 1/4 sec to see if a control sequence follows */ ch3 = getachar(); } if (ch3 != '~') { /* esc [ ch1 ch2 ~ */ return ESC; } if (ch1=='1') { switch (ch2) { case '1': /* esc [ 1 1 ~ */ return F1; case '2': /* esc [ 1 2 ~ */ return F2; case '3': /* esc [ 1 3 ~ */ return F3; case '4': /* esc [ 1 4 ~ */ return F4; case '5': /* esc [ 1 5 ~ */ return F5; case '6': /* esc [ 1 6 ~ */ return F6; case '7': /* esc [ 1 7 ~ */ return F7; case '8': /* esc [ 1 8 ~ */ return F8; case '9': /* esc [ 1 9 ~ */ return F9; default: return ESC; } } else if (ch1=='2') { switch (ch2) { case '0': /* esc [ 2 0 ~ */ return F10; case '8': /* esc [ 2 8 ~ */ return F1; /* HELP */ default: return ESC; } } else { return ESC; } } #endif } extern int editpal_cursor; extern void Cursor_SetPos(); int XZoomWaiting = 0; static int ctl_mode = 0; static int shift_mode = 0; #define SENS 1 #define ABS(x) ((x) > 0?(x):-(x)) #define MIN(x, y) ((x) < (y)?(x):(y)) #define SIGN(x) ((x) > 0?1:-1) /* *---------------------------------------------------------------------- * * xhandleevents -- * * Handles X events. * * Results: * None. * * Side effects: * Does event action. * *---------------------------------------------------------------------- */ static void xhandleevents() { XEvent xevent; int drawn; int bnum; int bandx0,bandy0,bandx1,bandy1; static int lastx,lasty; static int dx,dy; bnum = 0; if (doredraw) { redrawscreen(); } while (XPending(Xdp) && !xbufkey) { XNextEvent(Xdp,&xevent); switch (((XAnyEvent *)&xevent)->type) { case ClientMessage: if (xevent.xclient.message_type == wm_protocols && xevent.xclient.format == 32 && xevent.xclient.data.l[0] == wm_delete_window) { #ifndef NCURSES if (xevent.xexpose.window == Xwp) { /* Popup window */ XDestroyWindow(Xdp, Xwp); Xwp = None; if (Xmessage) free(Xmessage); Xmessage = NULL; return; } #endif if (exitpending) goodbye(); stackscreen(); check_exit(); unstackscreen(); xbufkey = ESC; return; } break; case KeyRelease: { char buffer[1]; KeySym keysym; (void) XLookupString(&xevent.xkey,buffer,1,&keysym,NULL); switch (keysym) { case XK_Control_L: case XK_Control_R: ctl_mode = 0; break; case XK_Shift_L: case XK_Shift_R: shift_mode = 0; break; } } break; case KeyPress: { int charcount; char buffer[1]; KeySym keysym; charcount = XLookupString(&xevent.xkey,buffer,1,&keysym,NULL); switch (keysym) { case XK_Control_L: case XK_Control_R: ctl_mode = 1; return; case XK_Shift_L: case XK_Shift_R: shift_mode = 1; break; case XK_Home: case XK_R7: xbufkey = ctl_mode ? CTL_HOME : HOME; return; case XK_Left: case XK_R10: xbufkey = ctl_mode ? LEFT_ARROW_2 : LEFT_ARROW; return; case XK_Right: case XK_R12: xbufkey = ctl_mode ? RIGHT_ARROW_2 : RIGHT_ARROW; return; case XK_Down: case XK_R14: xbufkey = ctl_mode ? DOWN_ARROW_2 : DOWN_ARROW; return; case XK_Up: case XK_R8: xbufkey = ctl_mode ? UP_ARROW_2 : UP_ARROW; return; case XK_Insert: xbufkey = ctl_mode ? CTL_INSERT : INSERT; return; case XK_Delete: xbufkey = ctl_mode ? CTL_DEL : DELETE; return; case XK_End: case XK_R13: xbufkey = ctl_mode ? CTL_END : END; return; case XK_Help: xbufkey = F1; return; case XK_Prior: case XK_R9: xbufkey = ctl_mode ? CTL_PAGE_UP : PAGE_UP; return; case XK_Next: case XK_R15: xbufkey = ctl_mode ? CTL_PAGE_DOWN : PAGE_DOWN; return; case XK_F1: case XK_L1: xbufkey = shift_mode ? SF1: F1; return; case XK_F2: case XK_L2: xbufkey = shift_mode ? SF2: F2; return; case XK_F3: case XK_L3: xbufkey = shift_mode ? SF3: F3; return; case XK_F4: case XK_L4: xbufkey = shift_mode ? SF4: F4; return; case XK_F5: case XK_L5: xbufkey = shift_mode ? SF5: F5; return; case XK_F6: case XK_L6: xbufkey = shift_mode ? SF6: F6; return; case XK_F7: case XK_L7: xbufkey = shift_mode ? SF7: F7; return; case XK_F8: case XK_L8: xbufkey = shift_mode ? SF8: F8; return; case XK_F9: case XK_L9: xbufkey = shift_mode ? SF9: F9; return; case XK_F10: case XK_L10: xbufkey = shift_mode ? SF10: F10; return; case '+': xbufkey = ctl_mode ? CTL_PLUS : '+'; return; case '-': xbufkey = ctl_mode ? CTL_MINUS : '-'; return; break; #if 1 /* The following need to be somewhere else, otherwise these keys are not available */ /* in any other mode. For example, the '0' and '=' keys won't work with the command */ /* or the command. JCO 06-23-2001 */ case XK_dollar: step = 0; initdacbox(); if (drawing_or_drawn) xbufkey = 'd'; return; case XK_exclam: step = (step & 126) + 1 - (step & 1); initdacbox(); if (drawing_or_drawn) xbufkey = 'd'; return; case XK_greater: step = (step+2) % 50; initdacbox(); xbufkey = 'd'; return; case XK_less: step = (step+48) % 50; initdacbox(); if (drawing_or_drawn) xbufkey = 'd'; return; case XK_parenright: step = (step+12) % 50; initdacbox(); if (drawing_or_drawn) xbufkey = 'd'; return; case XK_parenleft: step = (step+38) % 50; initdacbox(); if (drawing_or_drawn) xbufkey = 'd'; return; /* case XK_equal: see comments above */ case XK_KP_Equal: xbufkey = 'd'; return; #endif case XK_Return: case XK_KP_Enter: xbufkey = ctl_mode ? CTL('T') : '\n'; return; } if (charcount==1) { xbufkey = buffer[0]; if (xbufkey=='\003') { goodbye(); } } } break; case MotionNotify: { if (screenctr) break; if (editpal_cursor && !inside_help) { while ( XCheckWindowEvent(Xdp,Xw,PointerMotionMask, &xevent)) {} if (xevent.xmotion.state&Button2Mask || (xevent.xmotion.state&Button1Mask && xevent.xmotion.state&Button3Mask)) { bnum = 3; } else if (xevent.xmotion.state&Button1Mask) { bnum = 1; } else if (xevent.xmotion.state&Button3Mask) { bnum = 2; } else { bnum = 0; } #define MSCALE 1 if (lookatmouse==3 && bnum != 0) { dx += (xevent.xmotion.x-lastx)/MSCALE; dy += (xevent.xmotion.y-lasty)/MSCALE; lastx = xevent.xmotion.x; lasty = xevent.xmotion.y; } else { Cursor_SetPos(xevent.xmotion.x, xevent.xmotion.y); xbufkey = ENTER; } } } break; case ButtonPress: { int done = 0; int banding = 0; if (screenctr) break; if (lookatmouse==3 || zoomoff == 0) { lastx = xevent.xbutton.x; lasty = xevent.xbutton.y; break; } bandx1 = bandx0 = xevent.xbutton.x; bandy1 = bandy0 = xevent.xbutton.y; while (!done) { XNextEvent(Xdp,&xevent); switch (xevent.type) { case MotionNotify: while ( XCheckWindowEvent(Xdp,Xw,PointerMotionMask, &xevent)) {} if (banding) { XDrawRectangle(Xdp,Xw,Xgc,MIN(bandx0,bandx1), MIN(bandy0,bandy1), ABS(bandx1-bandx0), ABS(bandy1-bandy0)); } bandx1 = xevent.xmotion.x; bandy1 = xevent.xmotion.y; if (ABS(bandx1-bandx0)*finalaspectratio > ABS(bandy1-bandy0)) { bandy1 = SIGN(bandy1-bandy0)*ABS(bandx1-bandx0)* finalaspectratio + bandy0; } else { bandx1 = SIGN(bandx1-bandx0)*ABS(bandy1-bandy0)/ finalaspectratio + bandx0; } if (!banding) { /* Don't start rubber-banding until the mouse gets moved. Otherwise a click messes up the window */ if (ABS(bandx1-bandx0)>10 || ABS(bandy1-bandy0)>10) { banding = 1; XSetForeground(Xdp, Xgc, colors-1); XSetFunction(Xdp, Xgc, GXxor); } } if (banding) { XDrawRectangle(Xdp,Xw,Xgc,MIN(bandx0,bandx1), MIN(bandy0,bandy1), ABS(bandx1-bandx0), ABS(bandy1-bandy0)); } XFlush(Xdp); break; case ButtonRelease: done = 1; break; } } if (!banding) { break; } XDrawRectangle(Xdp,Xw,Xgc,MIN(bandx0,bandx1), MIN(bandy0,bandy1), ABS(bandx1-bandx0), ABS(bandy1-bandy0)); if (bandx1==bandx0) { bandx1 = bandx0+1; } if (bandy1==bandy0) { bandy1 = bandy0+1; } zrotate = 0; zskew = 0; zbx = (MIN(bandx0,bandx1)-sxoffs)/dxsize; zby = (MIN(bandy0,bandy1)-syoffs)/dysize; zwidth = ABS(bandx1-bandx0)/dxsize; zdepth = zwidth; if (!inside_help) { xbufkey = ENTER; } if (xlastcolor != -1) { XSetForeground(Xdp, Xgc, xlastcolor); } XSetFunction(Xdp, Xgc, xlastfcn); XZoomWaiting = 1; drawbox(0); } break; case ConfigureNotify: resize_flag |= 4; if (resizeWindow()) { if (!ctrl_window && screenctr) xbufkey = 0; else xbufkey = 'd'; } break; case Expose: #ifndef NCURSES if (xevent.xexpose.window == Xwp) { xpopup(NULL); break; } if ((ctrl_window && (xevent.xexpose.window == Xwc)) || (!ctrl_window && screenctr)) { refresh(0, LINES); break; } #endif if (!doesBacking) { int x,y,w,h; x = xevent.xexpose.x; y = xevent.xexpose.y; w = xevent.xexpose.width; h = xevent.xexpose.height; if (x+w>sxdots) { w = sxdots-x; } if (y+h>sydots) { h = sydots-y; } if (x0 && h>0) { XPutImage(Xdp,Xw,Xgc,Ximage,xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.x, xevent.xexpose.y, xevent.xexpose.width, xevent.xexpose.height); } } break; default: /* All events selected by StructureNotifyMask * except ConfigureNotify are thrown away here, * since nothing is done with them */ break; } /* End switch */ } /* End while */ if (!xbufkey && editpal_cursor && !inside_help && lookatmouse == 3 && (dx != 0 || dy != 0)) { if (ABS(dx)>ABS(dy)) { if (dx>0) { xbufkey = mousefkey[bnum][0]; /* right */ dx--; } else if (dx<0) { xbufkey = mousefkey[bnum][1]; /* left */ dx++; } } else { if (dy>0) { xbufkey = mousefkey[bnum][2]; /* down */ dy--; } else if (dy<0) { xbufkey = mousefkey[bnum][3]; /* up */ dy++; } } } } /* *---------------------------------------------------------------------- * * pr_dwmroot -- * * Search for a dec window manager root window. * * Results: * Returns the root window. * * Side effects: * None. * *---------------------------------------------------------------------- */ static Window pr_dwmroot(dpy, pwin) Display *dpy; Window pwin; { /* search for DEC Window Manager root */ XWindowAttributes pxwa,cxwa; Window root,parent,*child; unsigned int i,nchild; if (!XGetWindowAttributes(dpy,pwin,&pxwa)) { printf("Search for root: XGetWindowAttributes failed\n"); return RootWindow(dpy, Xdscreen); } if (XQueryTree(dpy,pwin,&root,&parent,&child,&nchild)) { for (i = 0; i < nchild; i++) { if (!XGetWindowAttributes(dpy,child[i],&cxwa)) { printf("Search for root: XGetWindowAttributes failed\n"); return RootWindow(dpy, Xdscreen); } if (pxwa.width == cxwa.width && pxwa.height == cxwa.height) { return(pr_dwmroot(dpy, child[i])); } } return(pwin); } else { printf("xfractint: failed to find root window\n"); return RootWindow(dpy, Xdscreen); } } /* *---------------------------------------------------------------------- * * FindRootWindow -- * * Find the root or virtual root window. * * Results: * Returns the root window. * * Side effects: * None. * *---------------------------------------------------------------------- */ #define w_root Xroot static Window FindRootWindow(Display *dpy, int screen) { int i; w_root = RootWindow(dpy, screen); w_root = pr_dwmroot(dpy, w_root); /* search for DEC wm root */ { /* search for swm/tvtwm root (from ssetroot by Tom LaStrange) */ Atom __SWM_VROOT = None; Window rootReturn, parentReturn, *children; unsigned int numChildren; __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False); XQueryTree(dpy, w_root, &rootReturn, &parentReturn, &children, &numChildren); for (i = 0; i < numChildren; i++) { Atom actual_type; int actual_format; unsigned long nitems, bytesafter; Window *newRoot = NULL; if (XGetWindowProperty (dpy, children[i], __SWM_VROOT,(long)0,(long)1, False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) { w_root = *newRoot; break; } } } return w_root; } /* *---------------------------------------------------------------------- * * RemoveRootPixmap -- * * Clean up old pixmap on the root window. * * Results: * None. * * Side effects: * Pixmap is cleaned up. * *---------------------------------------------------------------------- */ static void RemoveRootPixmap() { Atom prop,type; int format; unsigned long nitems,after; Pixmap *pm; prop = XInternAtom(Xdp,"_XSETROOT_ID",False); if (XGetWindowProperty(Xdp,Xroot,prop,(long)0,(long)1,1,AnyPropertyType, &type, &format, &nitems, &after, (unsigned char **)&pm) == Success && nitems == 1) { if (type==XA_PIXMAP && format==32 && after==0) { XKillClient(Xdp,(XID)*pm); XFree((char *)pm); } } } static unsigned char *fontPtr = NULL; /* *---------------------------------------------------------------------- * * xgetfont -- * * Get an 8x8 font. * * Results: * Returns a pointer to the bits. * * Side effects: * None. * *---------------------------------------------------------------------- */ unsigned char * xgetfont() { XFontStruct *font_info; XImage *font_image; char str[8]; int i, j, k, l; int width; Pixmap font_pixmap; XGCValues values; GC font_gc; fontPtr = (unsigned char *)malloc(128*8); bzero(fontPtr, 128*8); xlastcolor = -1; #define FONT "-*-*-medium-r-*-*-9-*-*-*-*-*-iso8859-*" font_info = XLoadQueryFont(Xdp, FONT); if (font_info == NULL) { printf("No %s\n", FONT); } if (font_info == NULL || font_info->max_bounds.width > 8 || font_info->max_bounds.width != font_info->min_bounds.width) { printf("Bad font: %s\n", FONT); sleep(2); font_info = XLoadQueryFont(Xdp, "6x12"); } if (font_info == NULL) return NULL; width = font_info->max_bounds.width; if (font_info->max_bounds.width > 8 || font_info->max_bounds.width != font_info->min_bounds.width) { printf("Bad font\n"); return NULL; } font_pixmap = XCreatePixmap(Xdp, Xw, 64, 8, Xdepth); assert(font_pixmap); values.background = 0; values.foreground = 1; values.font = font_info->fid; font_gc = XCreateGC(Xdp, font_pixmap, GCForeground | GCBackground | GCFont, &values); assert(font_gc); for (i = 0; i < 128; i+=8) { for (j = 0; j < 8; j++) { str[j] = i+j; } XDrawImageString(Xdp, font_pixmap, Xgc, 0, 8, str, 8); font_image = XGetImage(Xdp, font_pixmap, 0, 0, 64, 8, AllPlanes, XYPixmap); assert(font_image); for (j = 0; j < 8; j++) { for (k = 0; k < 8; k++) { for (l = 0; l < width; l++) { if (XGetPixel(font_image, j*width+l, k)) { fontPtr[(i+j)*8+k] = (fontPtr[(i+j)*8+k] << 1) | 1; } else { fontPtr[(i+j)*8+k] = (fontPtr[(i+j)*8+k] << 1); } } } } XDestroyImage(font_image); } XFreeGC(Xdp, font_gc); XFreePixmap(Xdp, font_pixmap); return fontPtr; } #if 0 /* Don't need this since we can open a terminal externally. JCO *---------------------------------------------------------------------- * * shell_to_dos -- * * Exit to a unix shell. * * Results: * None. * * Side effects: * Goes to shell * *---------------------------------------------------------------------- */ #define SHELL "/bin/csh" void shell_to_dos() { #ifndef NCURSES char cmd[256]; sprintf(cmd, "xterm -geometry 80x32 -fn \"%s\" &", Xfontname); system(cmd); #else SignalHandler sigint; char *shell; char *argv[2]; int pid, donepid; sigint = (SignalHandler)signal(SIGINT, SIG_IGN); shell = getenv("SHELL"); if (shell==NULL) { shell = SHELL; } argv[0] = shell; argv[1] = NULL; /* Clean up the window */ if (!simple_input) { fcntl(0,F_SETFL,old_fcntl); } mvcur(0,COLS-1, LINES-1,0); nocbreak(); echo(); endwin(); /* Fork the shell */ pid = fork(); if (pid < 0) { perror("fork to shell"); } if (pid==0) { execvp(shell, argv); perror("fork to shell"); exit(1); } /* Wait for the shell to finish */ while (1) { donepid = wait(0); if (donepid<0 || donepid==pid) break; } /* Go back to curses mode */ initscr(); curwin = stdscr; cbreak(); noecho(); if (!simple_input) { old_fcntl = fcntl(0,F_GETFL); fcntl(0,F_SETFL,FNDELAY); } signal(SIGINT, (SignalHandler)sigint); putchar('\n'); #endif } #endif /* *---------------------------------------------------------------------- * * schedulealarm -- * * Start the refresh alarm * * Results: * None. * * Side effects: * Starts the alarm. * *---------------------------------------------------------------------- */ #define DRAW_INTERVAL 6 void schedulealarm(soon) int soon; { if (!fastmode) return; signal(SIGALRM, (SignalHandler)setredrawscreen); if (soon) { alarm(1); } else { alarm(DRAW_INTERVAL); } alarmon = 1; } /* *---------------------------------------------------------------------- * * setredrawscreen -- * * Set the screen refresh flag * * Results: * None. * * Side effects: * Sets the flag. * *---------------------------------------------------------------------- */ static void setredrawscreen() { doredraw = 1; } /* *---------------------------------------------------------------------- * * redrawscreen -- * * Refresh the screen. * * Results: * None. * * Side effects: * Redraws the screen. * *---------------------------------------------------------------------- */ void redrawscreen() { if (alarmon) { XPutImage(Xdp, Xw, Xgc, Ximage, 0, 0, 0, 0, sxdots, sydots); if (onroot) { XPutImage(Xdp, Xpixmap, Xgc, Ximage, 0, 0, 0, 0, sxdots, sydots); } alarmon = 0; } doredraw = 0; } xfractint-20.4.10.orig/unix/Makefile0000755000000000000000000000234210762306640014140 0ustar SHELL=/bin/sh ifeq ($(AS),/usr/bin/nasm) OBJS = \ calcmand.o calmanfp.o diskvidu.o fpu087.o fracsuba.o general.o \ unix.o unixscr.o video.o xfcurses.o \ calmanfx.o else OBJS = \ calcmand.o calmanfp.o diskvidu.o fpu087.o fracsuba.o general.o \ unix.o unixscr.o video.o xfcurses.o endif #Need to prevent lex from doing fractint.l -> fractint.c .SUFFIXES: .SUFFIXES: .o .c .s .h .asm all: $(OBJS) tidy: rm -f $(OBJS) clean: rm -f $(OBJS) ifeq ($(AS),/usr/bin/nasm) calmanfx.o: calmanfx.asm $(AS) $(AFLAGS) calmanfx.asm endif unix.o: unix.c $(CC) $(CFLAGS) -DSRCDIR=\"$(SRCDIR)\" -c unix.c copy: $(FILES) mv $(FILES) backup # DO NOT DELETE THIS LINE -- make depend depends on it. calcmand.o: calcmand.c ${HFD}/port.h calmanfp.o: calmanfp.c ${HFD}/port.h ${HFD}/fractype.h ifeq ($(AS),/usr/bin/nasm) calmanfx.o: calmanfx.asm xfract_a.inc endif diskvidu.o: diskvidu.c ${HFD}/port.h fpu087.o: fpu087.c ${HFD}/port.h fracsuba.o: fracsuba.c ${HFD}/port.h general.o: general.c ${HFD}/port.h unix.o: unix.c ${HFD}/port.h unixscr.o: unixscr.c ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/helpdefs.h ${HFD}/xfcurses.h video.o: video.c ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/xfcurses.h xfcurses.o: xfcurses.c ${HFD}/port.h ${HFD}/xfcurses.h xfractint-20.4.10.orig/unix/unix.c0000644000000000000000000002362610756132210013625 0ustar /* Unix.c * This file contains compatibility routines. * * This file Copyright 1991 Ken Shirriff. It may be used according to the * fractint license conditions, blah blah blah. */ #include #include #include #include #include #include #include #include #include "port.h" int iocount; /* *---------------------------------------------------------------------- * * clock_ticks -- * * Return time in CLK_TCK ticks. * * Results: * Time. * * Side effects: * None. * *---------------------------------------------------------------------- */ long clock_ticks() { struct timeval tim; gettimeofday(&tim,NULL); return tim.tv_sec*CLK_TCK + tim.tv_usec*CLK_TCK/1000000; } /* stub */ void intdos() {} /* *---------------------------------------------------------------------- * * kbhit -- * * Get a key. * * Results: * 1 if key, 0 otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int kbhit() { return 0; } /* *---------------------------------------------------------------------- * * stackavail -- * * Returns amout of stack available. * * Results: * Available stack. * * Side effects: * None. * *---------------------------------------------------------------------- */ long stackavail() { return 8192; } #ifndef HAVESTRI /* *---------------------------------------------------------------------- * * stricmp -- * * Compare strings, ignoring case. * * Results: * -1,0,1. * * Side effects: * None. * *---------------------------------------------------------------------- */ int stricmp(s1, s2) char *s1, *s2; /* Strings to compare. */ { int c1, c2; while (1) { c1 = *s1++; c2 = *s2++; if (isupper(c1)) c1 = tolower(c1); if (isupper(c2)) c2 = tolower(c2); if (c1 != c2) { return c1 - c2; } if (c1 == 0) { return 0; } } } /* *---------------------------------------------------------------------- * * strnicmp -- * * Compare strings, ignoring case. Maximum length is specified. * * Results: * -1,0,1. * * Side effects: * None. * *---------------------------------------------------------------------- */ int strnicmp(s1, s2, numChars) char *s1, *s2; /* Strings to compare. */ int numChars; /* Max number of chars to compare. */ { register char c1, c2; for ( ; numChars > 0; --numChars) { c1 = *s1++; c2 = *s2++; if (isupper(c1)) c1 = tolower(c1); if (isupper(c2)) c2 = tolower(c2); if (c1 != c2) { return c1 - c2; } if (c1 == '\0') { return 0; } } return 0; } #endif /* *---------------------------------------------------------------------- * * strlwr -- * * Convert string to lower case. * * Results: * The string. * * Side effects: * Modifies the string. * *---------------------------------------------------------------------- */ char * strlwr(s) char *s; { register char *sptr=s; while (*sptr != '\0') { if (isupper(*sptr)) { *sptr = tolower(*sptr); } sptr++; } return s; } /* *---------------------------------------------------------------------- * * strupr -- * * Convert string to upper case. * * Results: * The string. * * Side effects: * Modifies the string. * *---------------------------------------------------------------------- */ char * strupr(s) char *s; { register char *sptr=s; while (*sptr != '\0') { if (islower(*sptr)) { *sptr = toupper(*sptr); } sptr++; } return s; } /* *---------------------------------------------------------------------- * * memicmp -- * * Compare memory (like memcmp), but ignoring case. * * Results: * -1,0,1. * * Side effects: * None. * *---------------------------------------------------------------------- */ int memicmp(s1, s2, n) char *s1, *s2; int n; { register char c1,c2; while (--n >= 0) { c1 = *s1++; if (isupper(c1)) c1 = tolower(c1); c2 = *s2++; if (isupper(c2)) c2 = tolower(c2); if (c1 != c2) return (c1 - c2); } return (0); } /* *---------------------------------------------------------------------- * * findpath -- * * Find where a file is. * We return filename if it is an absolute path. * Otherwise we first try FRACTDIR/filename, SRCDIR/filename, * and then ./filename. * * Results: * Returns full pathname in fullpathname. * * Side effects: * None. * *---------------------------------------------------------------------- */ void findpath(filename, fullpathname) char *filename, *fullpathname; { int fd; char *fractdir; if (filename[0]=='/') { strcpy(fullpathname,filename); fd = open(fullpathname,O_RDONLY); if (fd != -1) { close(fd); return; } } fractdir = getenv("FRACTDIR"); if (fractdir != NULL) { strcpy(fullpathname,fractdir); strcat(fullpathname,"/"); strcat(fullpathname,filename); fd = open(fullpathname,O_RDONLY); if (fd != -1) { close(fd); return; } } strcpy(fullpathname,SRCDIR); strcat(fullpathname,"/"); strcat(fullpathname,filename); fd = open(fullpathname,O_RDONLY); if (fd != -1) { close(fd); return; } strcpy(fullpathname,"./"); strcat(fullpathname,filename); fd = open(fullpathname,O_RDONLY); if (fd != -1) { close(fd); return; } fullpathname=NULL; } /* *---------------------------------------------------------------------- * * ltoa -- * * Convert long to string. * * Results: * 0. * * Side effects: * Prints number into the string. * *---------------------------------------------------------------------- */ int ltoa(num,str,len) long num; char *str; int len; { sprintf(str,"%10d",(int)num); return 0; } /* *---------------------------------------------------------------------- * * filelength -- * * Find length of a file. * * Results: * Length. * * Side effects: * None. * *---------------------------------------------------------------------- */ int filelength(fd) int fd; { struct stat buf; fstat(fd,&buf); return buf.st_size; } /* *---------------------------------------------------------------------- * * splitpath -- * * This is the splitpath code from prompts.c * * Results: * Returns drive, dir, base, and extension. * * Side effects: * None. * *---------------------------------------------------------------------- */ int splitpath(char *template,char *drive,char *dir,char *fname,char *ext) { int length; int len; int offset; char *tmp; if(drive) drive[0] = 0; if(dir) dir[0] = 0; if(fname) fname[0] = 0; if(ext) ext[0] = 0; if((length = strlen(template)) == 0) return(0); offset = 0; /* get drive */ if(length >= 2) if(template[1] == ':') { if(drive) { drive[0] = template[offset++]; drive[1] = template[offset++]; drive[2] = 0; } else { offset++; offset++; } } /* get dir */ if(offset < length) { tmp = strrchr(template,SLASHC); if(tmp) { tmp++; /* first character after slash */ len = tmp - &template[offset]; if(len >=0 && len < FILE_MAX_DIR && dir) strncpy(dir,&template[offset],min(len,FILE_MAX_DIR)); if(len < FILE_MAX_DIR && dir) dir[len] = 0; offset += len; } } else return(0); /* get fname */ if(offset < length) { tmp = strrchr(template,'.'); if(tmp < strrchr(template,SLASHC) || tmp < strrchr(template,':')) tmp = 0; /* in this case the '.' must be a directory */ if(tmp) { /* tmp++; */ /* first character past "." */ len = tmp - &template[offset]; if((len > 0) && (offset+len < length) && fname) { strncpy(fname,&template[offset],min(len,FILE_MAX_FNAME)); if(len < FILE_MAX_FNAME) fname[len] = 0; else fname[FILE_MAX_FNAME-1] = 0; } offset += len; if((offset < length) && ext) { strncpy(ext,&template[offset],FILE_MAX_EXT); ext[FILE_MAX_EXT-1] = 0; } } else if((offset < length) && fname) { strncpy(fname,&template[offset],FILE_MAX_FNAME); fname[FILE_MAX_FNAME-1] = 0; } } return(0); } int _splitpath(char *template,char *drive,char *dir,char *fname,char *ext) { return splitpath(template,drive,dir,fname,ext); } /* This ftime simulation routine is from Frank Chen */ void ftimex(tp) struct timebx *tp; { struct timeval timep; struct timezone timezp; if ( gettimeofday(&timep,&timezp) != 0) { perror("error in gettimeofday"); exit(0); } tp->time = timep.tv_sec; tp->millitm = timep.tv_usec/1000; tp->timezone = timezp.tz_minuteswest; tp->dstflag = timezp.tz_dsttime; } unsigned short _rotl(unsigned short num, short bits) { unsigned long ll; ll = (((unsigned long)num << 16) + num) << (bits&15); return((unsigned short)(ll>>16)); } /* sound.c file prototypes */ int get_sound_params(void) { return(0); } void soundon(int i) { } void soundoff(void) { } void mute(void) { } int initfm(void) { return(0); } /* tenths of millisecond timewr routine */ static struct timeval tv_start; void restart_uclock(void) { gettimeofday(&tv_start, NULL); } typedef unsigned long uclock_t; uclock_t usec_clock(void) { uclock_t result; struct timeval tv, elapsed; gettimeofday(&tv, NULL); elapsed.tv_usec = tv.tv_usec - tv_start.tv_sec; elapsed.tv_sec = tv.tv_sec - tv_start.tv_sec; if(elapsed.tv_usec < 0) { /* "borrow */ elapsed.tv_usec += 1000000; elapsed.tv_sec--; } result = (unsigned long)(elapsed.tv_sec*10000 + elapsed.tv_usec/100); return(result); } xfractint-20.4.10.orig/headers/0000755000000000000000000000000011456314753013131 5ustar xfractint-20.4.10.orig/headers/dosprot.h0000644000000000000000000001241310400460450014755 0ustar #ifndef DOSPROT_H #define DOSPROT_H /* This file contains prototypes for dos specific functions. */ /* calmanp5 -- assembler file prototypes */ extern long cdecl calcmandfpasm_p5(void); extern void cdecl calcmandfpasmstart_p5(void); /* general -- assembler file prototypes */ extern long cdecl multiply(long, long, int); extern long cdecl divide(long, long, int); extern int cdecl getakey(void); /*extern void cdecl buzzer(int); */ extern void cdecl buzzerpcspkr(int); extern void cdecl farmemfree(VOIDFARPTR ); extern int cdecl far_strlen( char far *); extern int cdecl far_strnicmp(char far *, char far *,int); extern void cdecl far_strcpy( char far *, char far *); extern int cdecl far_strcmp( char far *, char far *); extern int cdecl far_stricmp(char far *, char far *); extern void cdecl far_strcat( char far *, char far *); extern void cdecl far_memset( VOIDFARPTR , int , unsigned); extern void cdecl far_memcpy( VOIDFARPTR , VOIDFARPTR , int); extern int cdecl far_memcmp( VOIDFARPTR , VOIDFARPTR , int); extern void cdecl far_memicmp(VOIDFARPTR , VOIDFARPTR , int); extern BYTE far *cdecl emmquery(void); extern unsigned int cdecl emmgetfree(void); extern unsigned int cdecl emmallocate(unsigned int); extern void cdecl emmdeallocate(unsigned int); extern void cdecl emmgetpage(unsigned int, unsigned int); extern void cdecl emmclearpage(unsigned int, unsigned int); extern unsigned int *cdecl xmmquery(void); extern unsigned int cdecl xmmlongest(void); extern unsigned int cdecl xmmfree(void); extern unsigned int cdecl xmmallocate(unsigned int); extern void cdecl xmmdeallocate(unsigned int); extern unsigned int cdecl xmmreallocate(unsigned int, unsigned int); extern unsigned int cdecl xmmmoveextended(struct XMM_Move *); extern int cdecl keypressed(void); extern long cdecl readticker( void ); extern void cdecl snd( int ); extern void cdecl nosnd( void ); extern void cdecl initasmvars( void ); #ifndef __BORLANDC__ extern void cdecl enable( void ); extern void cdecl disable( void ); extern void cdecl delay( int ); #endif extern int cdecl farread(int, VOIDFARPTR, unsigned); extern int cdecl farwrite(int, VOIDFARPTR, unsigned); extern long cdecl normalize(char far *); extern void cdecl erasesegment(int, int); extern int cdecl getakeynohelp( void ); extern unsigned int cdecl cmpextra( unsigned int, char *, int ); extern unsigned int cdecl fromextra( unsigned int, char *, int ); extern unsigned int cdecl toextra( unsigned int, char *, int ); extern void cdecl load_mat(double (*)[4]); extern VOIDFARPTR cdecl farmemalloc(long); /* sound.c file prototypes */ extern int get_sound_params(void); extern void buzzer(int); extern int soundon(int); extern void soundoff(void); extern int initfm(void); extern void mute(void); /* tplus -- C file prototypes */ extern void WriteTPWord(unsigned int ,unsigned int ); extern void WriteTPByte(unsigned int ,unsigned int ); extern unsigned int ReadTPWord(unsigned int ); extern BYTE ReadTPByte(unsigned int ); extern void DisableMemory(void ); extern void EnableMemory(void ); extern int TargapSys(int ,unsigned int ); extern int _SetBoard(int ); extern int TPlusLUT(BYTE far *,unsigned int ,unsigned int ,unsigned int ); extern int SetVGA_LUT(void ); extern int SetColorDepth(int ); extern int SetBoard(int ); extern int ResetBoard(int ); extern int CheckForTPlus(void ); extern int SetTPlusMode(int ,int ,int ,int ); extern int FillTPlusRegion(unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned long ); extern void BlankScreen(unsigned long ); extern void UnBlankScreen(void ); extern void EnableOverlayCapture(void ); extern void DisableOverlayCapture(void ); extern void ClearTPlusScreen(void ); extern int MatchTPlusMode(unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned int ); extern void TPlusZoom(int ); /* video -- assembler file prototypes */ extern void cdecl adapter_detect(void); extern void cdecl scroll_center(int, int); extern void cdecl scroll_relative(int, int); extern void cdecl scroll_state(int); extern void cdecl setvideotext(void); extern void cdecl setnullvideo(void); extern void cdecl setfortext(void); extern void cdecl setforgraphics(void); extern void cdecl swapnormwrite(void); extern void cdecl setclear(void); extern int cdecl keycursor(int,int); extern void cdecl swapnormread(void); extern void cdecl setvideomode(int, int, int, int); extern void cdecl movewords(int,BYTE far*,BYTE far*); extern void cdecl movecursor(int, int); extern void cdecl get_line(int, int, int, BYTE *); extern void cdecl put_line(int, int, int, BYTE *); extern void cdecl setattr(int, int, int, int); extern void cdecl putstring(int,int,int,char far *); extern void cdecl spindac(int, int); extern void cdecl find_special_colors(void); extern char cdecl get_a_char(void); extern void cdecl put_a_char(int); extern void cdecl scrollup(int, int); extern void cdecl home(void); extern BYTE far *cdecl findfont(int); extern int _fastcall getcolor(int, int); extern void _fastcall putcolor_a(int, int, int); extern void gettruecolor(int, int, int*, int*, int*); extern void puttruecolor(int, int, int, int, int); extern int out_line(BYTE *, int); extern void (*swapsetup)(void); #endif xfractint-20.4.10.orig/headers/xfcurses.h0000644000000000000000000000361410762306640015143 0ustar #include #include #include #include #include #include #include struct _win_st { int _cur_y, _cur_x; int _car_y, _car_x; int _num_y, _num_x; int _cur_attr; char *_text; short *_attr; }; #define WINDOW struct _win_st #define stdscr NULL typedef unsigned chtype; extern Display *Xdp; extern Window Xw; extern Window Xwc; extern Window Xwp; extern Window Xroot; extern GC Xgc; extern Visual *Xvi; extern Screen *Xsc; extern Colormap Xcmap; extern int Xdscreen; extern int Xdepth; extern char *Xmessage; extern char *Xdisplay; extern char *Xgeometry; extern char *Xfontname; extern char *Xfontnamebold; extern Atom wm_delete_window, wm_protocols; extern int COLS; extern int LINES; extern void Open_XDisplay(); extern void cbreak(void); extern void nocbreak(void); extern void echo(void); extern void noecho(void); extern void clear(void); extern int standout(void); extern int standend(void); extern void endwin(void); extern void refresh(int line1, int line2); extern void xpopup(char *str); extern void mvcur(int oldrow, int oldcol, int newrow, int newcol); extern void delwin(WINDOW *win); extern void waddch(WINDOW *win, const chtype ch); extern void waddstr(WINDOW *win, const char *str); extern void wclear(WINDOW *win); extern void wdeleteln(WINDOW *win); extern void winsertln(WINDOW *win); extern void wmove(WINDOW *win, int y, int x); extern void wrefresh(WINDOW *win); extern void xrefresh(WINDOW *win, int line1, int line2); extern void touchwin(WINDOW *win); extern void wtouchln(WINDOW *win, int y, int n, int changed); extern void wstandout(WINDOW *win); extern void wstandend(WINDOW *win); extern WINDOW *newwin(int nlines, int ncols, int begin_y, int begin_x); extern WINDOW *initscr(void); extern void set_margins(int width, int height); #define getyx(win,y,x) (y = (win)->_cur_y, x = (win)->_cur_x) xfractint-20.4.10.orig/headers/port.h0000644000000000000000000002663711253454200014267 0ustar /************************************** ** ** PORT.H : Miscellaneous definitions for portability. Please add ** to this file for any new machines/compilers you may have. ** ** XFRACT file "SHARED.H" merged into PORT.H on 3/14/92 by --CWM-- ** TW also merged in Wes Loewer's BIGPORT.H. */ #ifndef PORT_H /* If this is defined, this file has been */ #define PORT_H /* included already in this module. */ #ifndef XFRACT #include #else #include #endif #include #include #include #include #if (defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER) || defined(__TURBOC__)) && !defined(STDC) # define STDC #endif #if (defined(LINUX)) && !defined(STDC) # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const # endif #endif #ifdef __TURBOC__ #define _matherr matherr #define _stackavail stackavail #define USE_BIGNUM_C_CODE #endif /* If endian.h is not present, it can be handled in the code below, */ /* but if you have this file, it can make it more fool proof. */ #if (defined(XFRACT) && !defined(__sun)) #if defined(sgi) #include #else #include #endif #endif #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */ #endif #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #define MSDOS 1 #define overwrite fract_overwrite /* avoid name conflict with curses */ #ifdef XFRACT /* XFRACT forces unix configuration! --CWM-- */ #ifdef BIG_ANSI_C /* remove far's */ #ifdef far #undef far #endif #define far #ifdef _far #undef _far #endif #define _far #ifdef __far #undef __far #endif #define __far #define _fmemcpy memcpy #define _fmemset memset #define _fmemmove memmove #ifndef USE_BIGNUM_C_CODE #define USE_BIGNUM_C_CODE #endif #endif /* CAE added ltoa, overwrite fix for HP-UX v9 26Jan95 */ #ifdef _HPUX_SOURCE #define ltoa fr_ltoa #endif #ifdef MSDOS #undef MSDOS #endif #ifdef __MSDOS__ #undef __MSDOS__ #endif #ifndef unix #define unix #endif #endif /* XFRACT */ #ifdef __TURBOC__ #define __cdecl cdecl #endif #ifdef MSDOS /* Microsoft C 5.1 for OS/2 and MSDOS */ /* NOTE: this is always true on DOS! */ /* (MSDOS is defined above) */ #define timebx timeb #ifndef BYTE_ORDER #define BYTE_ORDER LITTLE_ENDIAN #endif #ifdef _MSC_VER /* MSC assert does nothing under MSDOS */ #ifdef assert #undef assert #define assert(X) #endif #endif typedef unsigned char U8; typedef signed char S8; typedef unsigned short U16; typedef signed short S16; typedef unsigned long U32; typedef signed long S32; typedef unsigned char BYTE; typedef unsigned char CHAR; typedef void *VOIDPTR; typedef void far *VOIDFARPTR; typedef const void *VOIDCONSTPTR; #define CONST const #define PRINTER "/dev/prn" #define LOBYTEFIRST 1 #define SLASHC '\\' #define SLASH "\\" #define SLASHSLASH "\\\\" #define SLASHDOT "\\." #define DOTSLASH ".\\" #define DOTDOTSLASH "..\\" #define READMODE "rb" /* Correct DOS text-mode */ #define WRITEMODE "wb" /* file open "feature". */ #define write1(ptr,len,n,stream) fwrite(ptr,len,n,stream) #define write2(ptr,len,n,stream) fwrite(ptr,len,n,stream) #define rand15() rand() #else /* Have to nest because #elif is not portable */ #ifdef AMIGA /* Lattice C 3.02 for Amiga */ typedef UBYTE U8; typedef BYTE S8; typedef UWORD U16; typedef WORD S16; typedef unsigned int U32; typedef int S32; typedef UBYTE BYTE; typedef UBYTE CHAR; typedef void *VOIDPTR; typedef void *VOIDFARPTR; typedef const void *VOIDCONSTPTR; #define PRINTER "PRT:" #define LOBYTEFIRST 0 #define SLASHC '/' #define SLASH "/" #define SLASHSLASH "//" #define SLASHDOT "/." #define DOTSLASH "./" #define DOTDOTSLASH "../" #define READMODE "rb" #define WRITEMODE "wb" #define write1(ptr,len,n,stream) (fputc(*(ptr),stream),1) #define write2(ptr,len,n,stream) (fputc((*(ptr))&255,stream),fputc((*(ptr))>>8,stream),1) #define rand15() (rand()&0x7FFF) #define BYTE_ORDER BIG_ENDIAN #define USE_BIGNUM_C_CODE #define BIG_ANSI_C #else #ifdef unix /* Unix machine */ typedef unsigned char U8; typedef signed char S8; typedef unsigned short U16; typedef short S16; typedef unsigned long U32; typedef long S32; typedef unsigned char BYTE; typedef char CHAR; #ifndef __cdecl #define __cdecl #endif #ifdef __SVR4 typedef void *VOIDPTR; typedef void *VOIDFARPTR; typedef const void *VOIDCONSTPTR; #else # ifdef BADVOID typedef char *VOIDPTR; typedef char *VOIDFARPTR; typedef char *VOIDCONSTPTR; # else typedef void *VOIDPTR; typedef void *VOIDFARPTR; typedef const void *VOIDCONSTPTR; # endif #endif #ifdef __SVR4 # include typedef void sigfunc(int); #else typedef int sigfunc(int); #endif #ifndef BYTE_ORDER /* change for little endians that don't have this defined elsewhere (endian.h) */ #ifdef LINUX #define BYTE_ORDER LITTLE_ENDIAN #else #define BYTE_ORDER BIG_ENDIAN /* the usual case */ #endif #endif #ifndef USE_BIGNUM_C_CODE #define USE_BIGNUM_C_CODE #endif #ifndef BIG_ANSI_C #define BIG_ANSI_C #endif # define CONST const # define PRINTER "/dev/lp" # define SLASHC '/' # define SLASH "/" # define SLASHSLASH "//" # define SLASHDOT "/." # define DOTSLASH "./" # define DOTDOTSLASH "../" # define READMODE "r" # define WRITEMODE "w" # define write1(ptr,len,n,stream) (fputc(*(ptr),stream),1) # define write2(ptr,len,n,stream) (fputc((*(ptr))&255,stream),fputc((*(ptr))>>8,stream),1) # define rand15() (rand()&0x7FFF) # include "unix.h" #endif #endif #endif /* The following FILE_* #defines were moved here from fractint.h to * avoid inconsistent declarations in dos_help/hc.c and unix/unix.c. */ /* these are used to declare arrays for file names */ #ifdef XFRACT #define FILE_MAX_PATH 256 /* max length of path+filename */ #define FILE_MAX_DIR 256 /* max length of directory name */ #else #define FILE_MAX_PATH 80 /* max length of path+filename */ #define FILE_MAX_DIR 80 /* max length of directory name */ #endif #define FILE_MAX_DRIVE 3 /* max length of drive letter */ #if 1 #define FILE_MAX_FNAME 9 /* max length of filename */ #define FILE_MAX_EXT 5 /* max length of extension */ #else /* The filename limits were increased in Xfract 3.02. But alas, in this poor program that was originally developed on the nearly-brain-dead DOS operating system, quite a few things in the UI would break if file names were bigger than DOS 8-3 names. So for now humor us and let's keep the names short. */ #define FILE_MAX_FNAME 64 /* max length of filename */ #define FILE_MAX_EXT 64 /* max length of extension */ #endif #define MAX_NAME FILE_MAX_FNAME+FILE_MAX_EXT-1 struct DIR_SEARCH /* Allocate DTA and define structure */ { char path[21]; /* DOS path and filespec */ char attribute; /* File attributes wanted */ int ftime; /* File creation time */ int fdate; /* File creation date */ long size; /* File size in bytes */ char filename[MAX_NAME+1]; /* Filename and extension */ }; extern struct DIR_SEARCH DTA; /* Disk Transfer Area */ /* Uses big_access32(), big_set32(),... functions instead of macros. */ /* Some little endian machines may require this as well. */ #if BYTE_ORDER == BIG_ENDIAN #define ACCESS_BY_BYTE #endif #ifdef LOBYTEFIRST #define GET16(c,i) (i) = *((U16*)(&(c))) #else #define GET16(c,i) (i) = (*(unsigned char *)&(c))+\ ((*((unsigned char*)&(c)+1))<<8) #endif /* Some compiler libraries don't correctly handle long double.*/ /* If you want to force the use of doubles, or */ /* if the compiler supports long doubles, but does not allow */ /* scanf("%Lf", &longdoublevar); */ /* to read in a long double, then uncomment this next line */ /* #define DO_NOT_USE_LONG_DOUBLE */ /* #define USE_BIGNUM_C_CODE */ /* ASM code requires using long double */ /* HP-UX support long doubles and allows them to be read in with */ /* scanf(), but does not support the functions sinl, cosl, fabsl, etc. */ /* CAE added this 26Jan95 so it would compile (altered by Wes to new macro) */ #ifdef _HPUX_SOURCE #define DO_NOT_USE_LONG_DOUBLE #endif /* Solaris itself does not provide long double arithmetics like sinl. * However, the "sunmath" library that comes bundled with Sun C does * provide them. */ #ifdef sun #ifdef USE_SUNMATH #include #else #define DO_NOT_USE_LONG_DOUBLE #endif #endif /* This should not be neccessary, but below appears to not work */ #ifdef CYGWIN #define DO_NOT_USE_LONG_DOUBLE #endif #ifndef DO_NOT_USE_LONG_DOUBLE #ifdef LDBL_DIG /* this is what we're hoping for */ #define USE_LONG_DOUBLE typedef long double LDBL; #else #define DO_NOT_USE_LONG_DOUBLE #endif /* #ifdef LDBL_DIG */ #endif /* #ifndef DO_NOT_USE_LONG_DOUBLE */ #ifdef DO_NOT_USE_LONG_DOUBLE #ifdef USE_LONG_DOUBLE #undef USE_LONG_DOUBLE #endif /* long double isn't supported */ /* impliment LDBL as double */ typedef double LDBL; #if !defined(LDBL_DIG) #define LDBL_DIG DBL_DIG /* # of decimal digits of precision */ #endif #if !defined(LDBL_EPSILON) #define LDBL_EPSILON DBL_EPSILON /* smallest such that 1.0+LDBL_EPSILON != 1.0 */ #endif #if !defined(LDBL_MANT_DIG) #define LDBL_MANT_DIG DBL_MANT_DIG /* # of bits in mantissa */ #endif #if !defined(LDBL_MAX) #define LDBL_MAX DBL_MAX /* max value */ #endif #if !defined(LDBL_MAX_10_EXP) #define LDBL_MAX_10_EXP DBL_MAX_10_EXP /* max decimal exponent */ #endif #if !defined(LDBL_MAX_EXP) #define LDBL_MAX_EXP DBL_MAX_EXP /* max binary exponent */ #endif #if !defined(LDBL_MIN) #define LDBL_MIN DBL_MIN /* min positive value */ #endif #if !defined(LDBL_MIN_10_EXP) #define LDBL_MIN_10_EXP DBL_MIN_10_EXP /* min decimal exponent */ #endif #if !defined(LDBL_MIN_EXP) #define LDBL_MIN_EXP DBL_MIN_EXP /* min binary exponent */ #endif #if !defined(LDBL_RADIX) #define LDBL_RADIX DBL_RADIX /* exponent radix */ #endif #if !defined(LDBL_ROUNDS) #define LDBL_ROUNDS DBL_ROUNDS /* addition rounding: near */ #endif #define sqrtl sqrt #define logl log #define log10l log10 #define atanl atan #define fabsl fabs #define sinl sin #define cosl cos #endif #endif /* PORT_H */ xfractint-20.4.10.orig/headers/fractint.h0000644000000000000000000010416711257714555015130 0ustar /* FRACTINT.H - common structures and values for the FRACTINT routines */ #ifndef FRACTINT_H #define FRACTINT_H typedef BYTE BOOLEAN; #ifndef C6 #ifndef _fastcall #define _fastcall /* _fastcall is a Microsoft C6.00 extension */ #endif #endif #ifndef XFRACT #define ftimex ftime typedef int SEGTYPE; typedef unsigned USEGTYPE; #ifdef __TURBOC__ # define _bios_printer(a,b,c) biosprint((a),(c),(b)) # define _bios_serialcom(a,b,c) bioscom((a),(c),(b)) #else #ifndef __WATCOMC__ #ifndef MK_FP # define MK_FP(seg,off) (VOIDFARPTR )( (((long)(seg))<<16) | \ ((unsigned)(off)) ) #endif #endif #endif #else typedef char * SEGTYPE; typedef char * USEGTYPE; # define MK_FP(seg,off) (VOIDFARPTR )((long)seg + (long)off) #include /* need size_t */ #endif #ifndef XFRACT #define clock_ticks() clock() #endif #ifdef XFRACT #define difftime(now,then) ((now)-(then)) #endif /* for gotos in former FRACTINT.C pieces */ #define RESTART 1 #define IMAGESTART 2 #define RESTORESTART 3 #define CONTINUE 4 #define MAXMAXLINELENGTH 128 /* upper limit for maxlinelength for PARs */ #define MINMAXLINELENGTH 40 /* lower limit for maxlinelength for PARs */ #define MSGLEN 80 /* handy buffer size for messages */ #define MAXCMT 57 /* length of par comments */ #define MAXPARAMS 10 /* maximum number of parameters */ #define MAXPIXELS 32767 /* Maximum pixel count across/down the screen */ #define OLDMAXPIXELS 2048 /* Limit of some old fixed arrays */ #define MINPIXELS 10 /* Minimum pixel count across/down the screen */ #define DEFAULTASPECT ((float)0.75)/* Assumed overall screen dimensions, y/x */ #define DEFAULTASPECTDRIFT ((float)0.02) /* drift of < 2% is forced to 0% */ struct videoinfo { /* All we need to know about a Video Adapter */ char name[26]; /* Adapter name (IBM EGA, etc) */ char comment[26]; /* Comments (UNTESTED, etc) */ int keynum; /* key number used to invoked this mode */ /* 2-10 = F2-10, 11-40 = S,C,A{F1-F10} */ int videomodeax; /* begin with INT 10H, AX=(this) */ int videomodebx; /* ...and BX=(this) */ int videomodecx; /* ...and CX=(this) */ int videomodedx; /* ...and DX=(this) */ /* NOTE: IF AX==BX==CX==0, SEE BELOW */ int dotmode; /* video access method used by asm code */ /* 1 == BIOS 10H, AH=12,13 (SLOW) */ /* 2 == access like EGA/VGA */ /* 3 == access like MCGA */ /* 4 == Tseng-like SuperVGA*256 */ /* 5 == P'dise-like SuperVGA*256 */ /* 6 == Vega-like SuperVGA*256 */ /* 7 == "Tweaked" IBM-VGA ...*256 */ /* 8 == "Tweaked" SuperVGA ...*256 */ /* 9 == Targa Format */ /* 10 = Hercules */ /* 11 = "disk video" (no screen) */ /* 12 = 8514/A */ /* 13 = CGA 320x200x4, 640x200x2 */ /* 14 = Tandy 1000 */ /* 15 = TRIDENT SuperVGA*256 */ /* 16 = Chips&Tech SuperVGA*256 */ int xdots; /* number of dots across the screen */ int ydots; /* number of dots down the screen */ int colors; /* number of colors available */ }; typedef struct videoinfo far VIDEOINFO; #define INFO_ID "Fractal" typedef struct fractal_info FRACTAL_INFO; /* * Note: because non-MSDOS machines store structures differently, we have * to do special processing of the fractal_info structure in loadfile.c. * Make sure changes to the structure here get reflected there. */ #ifndef XFRACT #define FRACTAL_INFO_SIZE sizeof(FRACTAL_INFO) #else /* This value should be the MSDOS size, not the Unix size. */ #define FRACTAL_INFO_SIZE 504 #endif #define VERSION 17 /* file version, independent of system */ /* increment this EVERY time the fractal_info structure changes */ struct fractal_info /* for saving data in GIF file */ { char info_id[8]; /* Unique identifier for info block */ short iterationsold; /* Pre version 18.24 */ short fractal_type; /* 0=Mandelbrot 1=Julia 2= ... */ double xmin; double xmax; double ymin; double ymax; double creal; double cimag; short videomodeax; short videomodebx; short videomodecx; short videomodedx; short dotmode; short xdots; short ydots; short colors; short version; /* used to be 'future[0]' */ float parm3; float parm4; float potential[3]; short rseed; short rflag; short biomorph; short inside; short logmapold; float invert[3]; short decomp[2]; short symmetry; /* version 2 stuff */ short init3d[16]; short previewfactor; short xtrans; short ytrans; short red_crop_left; short red_crop_right; short blue_crop_left; short blue_crop_right; short red_bright; short blue_bright; short xadjust; short eyeseparation; short glassestype; /* version 3 stuff, release 13 */ short outside; /* version 4 stuff, release 14 */ double x3rd; /* 3rd corner */ double y3rd; char stdcalcmode; /* 1/2/g/b */ char useinitorbit; /* init Mandelbrot orbit flag */ short calc_status; /* resumable, finished, etc */ long tot_extend_len; /* total length of extension blocks in .gif file */ short distestold; short floatflag; short bailoutold; long calctime; BYTE trigndx[4]; /* which trig functions selected */ short finattract; double initorbit[2]; /* init Mandelbrot orbit values */ short periodicity; /* periodicity checking */ /* version 5 stuff, release 15 */ short pot16bit; /* save 16 bit continuous potential info */ float faspectratio; /* finalaspectratio, y/x */ short system; /* 0 for dos, 1 for windows */ short release; /* release number, with 2 decimals implied */ short flag3d; /* stored only for now, for future use */ short transparent[2]; short ambient; short haze; short randomize; /* version 6 stuff, release 15.x */ short rotate_lo; short rotate_hi; short distestwidth; /* version 7 stuff, release 16 */ double dparm3; double dparm4; /* version 8 stuff, release 17 */ short fillcolor; /* version 9 stuff, release 18 */ double mxmaxfp; double mxminfp; double mymaxfp; double myminfp; short zdots; float originfp; float depthfp; float heightfp; float widthfp; float distfp; float eyesfp; short orbittype; short juli3Dmode; short maxfn; short inversejulia; double dparm5; double dparm6; double dparm7; double dparm8; double dparm9; double dparm10; /* version 10 stuff, release 19 */ long bailout; short bailoutest; long iterations; short bf_math; short bflength; short yadjust; /* yikes! we left this out ages ago! */ short old_demm_colors; long logmap; long distest; double dinvert[3]; short logcalc; short stoppass; short quick_calc; double closeprox; short nobof; long orbit_interval; short orbit_delay; double math_tol[2]; short future[7]; /* for stuff we haven't thought of yet */ }; #define ITEMNAMELEN 18 /* max length of names in .frm/.l/.ifs/.fc */ struct history_info { short fractal_type; double xmin; double xmax; double ymin; double ymax; double creal; double cimag; double potential[3]; short rseed; short rflag; short biomorph; short inside; long logmap; double invert[3]; short decomp; short symmetry; short init3d[16]; short previewfactor; short xtrans; short ytrans; short red_crop_left; short red_crop_right; short blue_crop_left; short blue_crop_right; short red_bright; short blue_bright; short xadjust; short eyeseparation; short glassestype; short outside; double x3rd; double y3rd; long distest; short bailoutold; BYTE trigndx[4]; short finattract; double initorbit[2]; short periodicity; short pot16bit; short release; short save_release; short flag3d; short transparent[2]; short ambient; short haze; short randomize; short rotate_lo; short rotate_hi; short distestwidth; double dparm3; double dparm4; short fillcolor; double mxmaxfp; double mxminfp; double mymaxfp; double myminfp; short zdots; float originfp; float depthfp; float heightfp; float widthfp; float distfp; float eyesfp; short orbittype; short juli3Dmode; short major_method; short minor_method; double dparm5; double dparm6; double dparm7; double dparm8; double dparm9; double dparm10; long bailout; short bailoutest; long iterations; short bf_math; short bflength; short yadjust; short old_demm_colors; char filename[FILE_MAX_PATH]; char itemname[ITEMNAMELEN+1]; unsigned char dac[256][3]; char maxfn; char stdcalcmode; char three_pass; char useinitorbit; short logcalc; short stoppass; short ismand; double closeprox; short nobof; double math_tol[2]; short orbit_delay; long orbit_interval; double oxmin; double oxmax; double oymin; double oymax; double ox3rd; double oy3rd; short keep_scrn_coords; char drawmode; }; typedef struct history_info HISTORY; struct formula_info /* for saving formula data in GIF file */ { char form_name[40]; short uses_p1; short uses_p2; short uses_p3; short uses_ismand; short ismand; short uses_p4; short uses_p5; short future[6]; /* for stuff we haven't thought of, yet */ }; #ifndef XFRACT enum stored_at_values { NOWHERE, EXTRA, FARMEM, EXPANDED, EXTENDED, DISK }; #endif #ifdef XFRACT enum stored_at_values { NOWHERE, FARMEM, DISK }; #endif #define NUMGENES 21 typedef struct evolution_info EVOLUTION_INFO; /* * Note: because non-MSDOS machines store structures differently, we have * to do special processing of the evolution_info structure in loadfile.c and * encoder.c. See decode_evolver_info() in general.c. * Make sure changes to the structure here get reflected there. */ #ifndef XFRACT #define EVOLVER_INFO_SIZE sizeof(evolution_info) #else /* This value should be the MSDOS size, not the Unix size. */ #define EVOLVER_INFO_SIZE 200 #endif struct evolution_info /* for saving evolution data in a GIF file */ { short evolving; short gridsz; unsigned short this_gen_rseed; double fiddlefactor; double paramrangex; double paramrangey; double opx; double opy; short odpx; short odpy; short px; short py; short sxoffs; short syoffs; short xdots; short ydots; short mutate[NUMGENES]; short ecount; /* count of how many images have been calc'ed so far */ short future[68 - NUMGENES]; /* total of 200 bytes */ }; typedef struct orbits_info ORBITS_INFO; /* * Note: because non-MSDOS machines store structures differently, we have * to do special processing of the orbits_info structure in loadfile.c and * encoder.c. See decode_orbits_info() in general.c. * Make sure changes to the structure here get reflected there. */ #ifndef XFRACT #define ORBITS_INFO_SIZE sizeof(orbits_info) #else /* This value should be the MSDOS size, not the Unix size. */ #define ORBITS_INFO_SIZE 200 #endif struct orbits_info /* for saving orbits data in a GIF file */ { double oxmin; double oxmax; double oymin; double oymax; double ox3rd; double oy3rd; short keep_scrn_coords; char drawmode; char dummy; /* need an even number of bytes */ short future[74]; /* total of 200 bytes */ }; #define MAXVIDEOMODES 300 /* maximum entries in fractint.cfg */ #ifndef XFRACT #define MAXVIDEOTABLE 40 /* size of the resident video modes table */ #else #define MAXVIDEOTABLE 2 /* size of the resident video modes table */ #endif #define AUTOINVERT -123456.789 #define ENDVID 22400 /* video table uses extra seg up to here */ #define N_ATTR 8 /* max number of attractors */ extern long l_at_rad; /* finite attractor radius */ extern double f_at_rad; /* finite attractor radius */ #define NUMIFS 64 /* number of ifs functions in ifs array */ #define IFSPARM 7 /* number of ifs parameters */ #define IFS3DPARM 13 /* number of ifs 3D parameters */ struct moreparams { int type; /* index in fractalname of the fractal */ char far *param[MAXPARAMS-4]; /* name of the parameters */ double paramvalue[MAXPARAMS-4]; /* default parameter values */ }; typedef struct moreparams far MOREPARAMS; struct fractalspecificstuff { char *name; /* name of the fractal */ /* (leading "*" supresses name display) */ char far *param[4]; /* name of the parameters */ double paramvalue[4]; /* default parameter values */ int helptext; /* helpdefs.h HT_xxxx, -1 for none */ int helpformula; /* helpdefs.h HF_xxxx, -1 for none */ unsigned flags; /* constraints, bits defined below */ float xmin; /* default XMIN corner */ float xmax; /* default XMAX corner */ float ymin; /* default YMIN corner */ float ymax; /* default YMAX corner */ int isinteger; /* 1 if integerfractal, 0 otherwise */ int tojulia; /* mandel-to-julia switch */ int tomandel; /* julia-to-mandel switch */ int tofloat; /* integer-to-floating switch */ int symmetry; /* applicable symmetry logic 0 = no symmetry -1 = y-axis symmetry (If No Params) 1 = y-axis symmetry -2 = x-axis symmetry (No Parms) 2 = x-axis symmetry -3 = y-axis AND x-axis (No Parms) 3 = y-axis AND x-axis symmetry -4 = polar symmetry (No Parms) 4 = polar symmetry 5 = PI (sin/cos) symmetry 6 = NEWTON (power) symmetry */ #ifdef XFRACT int (*orbitcalc)(); /* function that calculates one orbit */ #else int (*orbitcalc)(void); /* function that calculates one orbit */ #endif int (*per_pixel)(void); /* once-per-pixel init */ int (*per_image)(void); /* once-per-image setup */ int (*calctype)(void); /* name of main fractal function */ long orbit_bailout; /* usual bailout value for orbit calc */ }; struct alternatemathstuff { int type; /* index in fractalname of the fractal */ int math; /* kind of math used */ #ifdef XFRACT int (*orbitcalc)(); /* function that calculates one orbit */ #else int (*orbitcalc)(void); /* function that calculates one orbit */ #endif int (*per_pixel)(void); /* once-per-pixel init */ int (*per_image)(void); /* once-per-image setup */ }; typedef struct alternatemathstuff ALTERNATE; /* defines for symmetry */ #define NOSYM 0 #define XAXIS_NOPARM -1 #define XAXIS 1 #define YAXIS_NOPARM -2 #define YAXIS 2 #define XYAXIS_NOPARM -3 #define XYAXIS 3 #define ORIGIN_NOPARM -4 #define ORIGIN 4 #define PI_SYM_NOPARM -5 #define PI_SYM 5 #define XAXIS_NOIMAG -6 #define XAXIS_NOREAL 6 #define NOPLOT 99 #define SETUP_SYM 100 /* defines for inside/outside */ #define ITER -1 #define REAL -2 #define IMAG -3 #define MULT -4 #define SUM -5 #define ATAN -6 #define FMOD -7 #define TDIS -8 #define ZMAG -59 #define BOF60 -60 #define BOF61 -61 #define EPSCROSS -100 #define STARTRAIL -101 #define PERIOD -102 #define FMODI -103 #define ATANI -104 /* defines for bailoutest */ enum bailouts { Mod, Real, Imag, Or, And, Manh, Manr }; enum Major {breadth_first, depth_first, random_walk, random_run}; enum Minor {left_first, right_first}; /* bitmask defines for fractalspecific flags */ #define NOZOOM 1 /* zoombox not allowed at all */ #define NOGUESS 2 /* solid guessing not allowed */ #define NOTRACE 4 /* boundary tracing not allowed */ #define NOROTATE 8 /* zoombox rotate/stretch not allowed */ #define NORESUME 16 /* can't interrupt and resume */ #define INFCALC 32 /* this type calculates forever */ #define TRIG1 64 /* number of trig functions in formula */ #define TRIG2 128 #define TRIG3 192 #define TRIG4 256 #define WINFRAC 512 /* supported in WinFrac */ #define PARMS3D 1024 /* uses 3d parameters */ #define OKJB 2048 /* works with Julibrot */ #define MORE 4096 /* more than 4 parms */ #define BAILTEST 8192 /* can use different bailout tests */ #define BF_MATH 16384 /* supports arbitrary precision */ #define LD_MATH 32768 /* supports long double */ /* more bitmasks for evolution mode flag */ #define FIELDMAP 1 /*steady field varyiations across screen */ #define RANDWALK 2 /* newparm = lastparm +- rand() */ #define RANDPARAM 4 /* newparm = constant +- rand() */ #define NOGROUT 8 /* no gaps between images */ extern struct fractalspecificstuff far fractalspecific[]; extern struct fractalspecificstuff far *curfractalspecific; #define DEFAULTFRACTALTYPE ".gif" #define ALTERNATEFRACTALTYPE ".fra" #ifndef sqr #define sqr(x) ((x)*(x)) #endif #ifndef lsqr #define lsqr(x) (multiply((x),(x),bitshift)) #endif #define CMPLXmod(z) (sqr((z).x)+sqr((z).y)) #define CMPLXconj(z) ((z).y = -((z).y)) #define LCMPLXmod(z) (lsqr((z).x)+lsqr((z).y)) #define LCMPLXconj(z) ((z).y = -((z).y)) #define PER_IMAGE (fractalspecific[fractype].per_image) #define PER_PIXEL (fractalspecific[fractype].per_pixel) #define ORBITCALC (fractalspecific[fractype].orbitcalc) typedef _LCMPLX LCMPLX; /* 3D stuff - formerly in 3d.h */ #ifndef dot_product #define dot_product(v1,v2) ((v1)[0]*(v2)[0]+(v1)[1]*(v2)[1]+(v1)[2]*(v2)[2]) /* TW 7-09-89 */ #endif #define CMAX 4 /* maximum column (4 x 4 matrix) */ #define RMAX 4 /* maximum row (4 x 4 matrix) */ #define DIM 3 /* number of dimensions */ typedef double MATRIX [RMAX] [CMAX]; /* matrix of doubles */ typedef int IMATRIX [RMAX] [CMAX]; /* matrix of ints */ typedef long LMATRIX [RMAX] [CMAX]; /* matrix of longs */ /* A MATRIX is used to describe a transformation from one coordinate system to another. Multiple transformations may be concatenated by multiplying their transformation matrices. */ typedef double VECTOR [DIM]; /* vector of doubles */ typedef int IVECTOR [DIM]; /* vector of ints */ typedef long LVECTOR [DIM]; /* vector of longs */ /* A VECTOR is an array of three coordinates [x,y,z] representing magnitude and direction. A fourth dimension is assumed to always have the value 1, but is not in the data structure */ #ifdef PI #undef PI #endif #define PI 3.14159265358979323846 #define SPHERE init3d[0] /* sphere? 1 = yes, 0 = no */ #define ILLUMINE (FILLTYPE>4) /* illumination model */ /* regular 3D */ #define XROT init3d[1] /* rotate x-axis 60 degrees */ #define YROT init3d[2] /* rotate y-axis 90 degrees */ #define ZROT init3d[3] /* rotate x-axis 0 degrees */ #define XSCALE init3d[4] /* scale x-axis, 90 percent */ #define YSCALE init3d[5] /* scale y-axis, 90 percent */ /* sphere 3D */ #define PHI1 init3d[1] /* longitude start, 180 */ #define PHI2 init3d[2] /* longitude end , 0 */ #define THETA1 init3d[3] /* latitude start,-90 degrees */ #define THETA2 init3d[4] /* latitude stop, 90 degrees */ #define RADIUS init3d[5] /* should be user input */ /* common parameters */ #define ROUGH init3d[6] /* scale z-axis, 30 percent */ #define WATERLINE init3d[7] /* water level */ #define FILLTYPE init3d[8] /* fill type */ #define ZVIEWER init3d[9] /* perspective view point */ #define XSHIFT init3d[10] /* x shift */ #define YSHIFT init3d[11] /* y shift */ #define XLIGHT init3d[12] /* x light vector coordinate */ #define YLIGHT init3d[13] /* y light vector coordinate */ #define ZLIGHT init3d[14] /* z light vector coordinate */ #define LIGHTAVG init3d[15] /* number of points to average */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* Math definitions (normally in float.h) that are missing on some systems. */ #ifndef FLT_MIN #define FLT_MIN 1.17549435e-38 #endif #ifndef FLT_MAX #define FLT_MAX 3.40282347e+38 #endif #ifndef DBL_EPSILON #define DBL_EPSILON 2.2204460492503131e-16 #endif #ifndef XFRACT #define UPARR "\x18" #define DNARR "\x19" #define RTARR "\x1A" #define LTARR "\x1B" #define UPARR1 "\x18" #define DNARR1 "\x19" #define RTARR1 "\x1A" #define LTARR1 "\x1B" #define FK_F1 "F1" #define FK_F2 "F2" #define FK_F3 "F3" #define FK_F4 "F4" #define FK_F5 "F5" #define FK_F6 "F6" #define FK_F7 "F7" #define FK_F8 "F8" #define FK_F9 "F9" #else #define UPARR "K" #define DNARR "J" #define RTARR "L" #define LTARR "H" #define UPARR1 "up(K)" #define DNARR1 "down(J)" #define RTARR1 "left(L)" #define LTARR1 "right(H)" #define FK_F1 "F1" #define FK_F2 "F2" #define FK_F3 "F3" #define FK_F4 "F4" #define FK_F5 "F5" #define FK_F6 "F6" #define FK_F7 "F7" #define FK_F8 "F8" #define FK_F9 "F9" #endif #ifndef XFRACT #define Fractint "Fractint" #define FRACTINT "FRACTINT" #else #define Fractint "Xfractint" #define FRACTINT "XFRACTINT" #endif #define JIIM 0 #define ORBIT 1 struct workliststuff /* work list entry for std escape time engines */ { int xxstart; /* screen window for this entry */ int xxstop; int yystart; int yystop; int yybegin; /* start row within window, for 2pass/ssg resume */ int sym; /* if symmetry in window, prevents bad combines */ int pass; /* for 2pass and solid guessing */ int xxbegin; /* start col within window, =0 except on resume */ }; typedef struct workliststuff WORKLIST; #define MAXCALCWORK 12 struct coords { int x,y; }; struct dblcoords { double x,y; }; extern BYTE trigndx[]; extern void (*ltrig0)(void), (*ltrig1)(void), (*ltrig2)(void), (*ltrig3)(void); extern void (*dtrig0)(void), (*dtrig1)(void), (*dtrig2)(void), (*dtrig3)(void); struct trig_funct_lst { char *name; void (*lfunct)(void); void (*dfunct)(void); void (*mfunct)(void); } ; extern struct trig_funct_lst trigfn[]; /* function prototypes */ extern void (_fastcall *plot)(int, int, int); /* for overlay return stack */ #define BIG 100000.0 #define CTL(x) ((x)&0x1f) /* nonalpha tests if we have a control character */ #define nonalpha(c) ((c)<32 || (c)>127) /* keys */ #define INSERT 1082 #define DELETE 1083 #define PAGE_UP 1073 #define PAGE_DOWN 1081 #define CTL_HOME 1119 #define CTL_END 1117 #define LEFT_ARROW 1075 #define RIGHT_ARROW 1077 #define UP_ARROW 1072 #define DOWN_ARROW 1080 #define LEFT_ARROW_2 1115 #define RIGHT_ARROW_2 1116 #define UP_ARROW_2 1141 #define DOWN_ARROW_2 1145 #define HOME 1071 #define END 1079 #define ENTER 13 #define ENTER_2 1013 #define CTL_ENTER 10 #define CTL_ENTER_2 1010 #define CTL_PAGE_UP 1132 #define CTL_PAGE_DOWN 1118 #define CTL_MINUS 1142 #define CTL_PLUS 1144 #define CTL_INSERT 1146 #define CTL_DEL 1147 #define CTL_BACKSLASH 28 #define F1 1059 #define F2 1060 #define F3 1061 #define F4 1062 #define F5 1063 #define F6 1064 #define F7 1065 #define F8 1066 #define F9 1067 #define F10 1068 #define BACKSPACE 8 #define TAB 9 #define CTL_TAB 1148 #define ALT_TAB 1165 #define BACK_TAB 1015 /* shift tab */ #define ESC 27 #define SPACE 32 #define SF1 1084 #define SF2 1085 #define SF3 1086 #define SF4 1087 #define SF5 1088 #define SF6 1089 #define SF7 1090 #define SF8 1091 #define SF9 1092 #define SF10 1093 /* text colors */ #define BLACK 0 #define BLUE 1 #define GREEN 2 #define CYAN 3 #define RED 4 #define MAGENTA 5 #define BROWN 6 /* dirty yellow on cga */ #define WHITE 7 /* use values below this for foreground only, they don't work background */ #define GRAY 8 /* don't use this much - is black on cga */ #define L_BLUE 9 #define L_GREEN 10 #define L_CYAN 11 #define L_RED 12 #define L_MAGENTA 13 #define YELLOW 14 #define L_WHITE 15 #define INVERSE 0x8000 /* when 640x200x2 text or mode 7, inverse */ #define BRIGHT 0x4000 /* when mode 7, bright */ /* and their use: */ extern BYTE txtcolor[]; #define C_TITLE txtcolor[0]+BRIGHT #define C_TITLE_DEV txtcolor[1] #define C_HELP_HDG txtcolor[2]+BRIGHT #define C_HELP_BODY txtcolor[3] #define C_HELP_INSTR txtcolor[4] #define C_HELP_LINK txtcolor[5]+BRIGHT #define C_HELP_CURLINK txtcolor[6]+INVERSE #define C_PROMPT_BKGRD txtcolor[7] #define C_PROMPT_TEXT txtcolor[8] #define C_PROMPT_LO txtcolor[9] #define C_PROMPT_MED txtcolor[10] #ifndef XFRACT #define C_PROMPT_HI txtcolor[11]+BRIGHT #else #define C_PROMPT_HI txtcolor[11] #endif #define C_PROMPT_INPUT txtcolor[12]+INVERSE #define C_PROMPT_CHOOSE txtcolor[13]+INVERSE #define C_CHOICE_CURRENT txtcolor[14]+INVERSE #define C_CHOICE_SP_INSTR txtcolor[15] #define C_CHOICE_SP_KEYIN txtcolor[16]+BRIGHT #define C_GENERAL_HI txtcolor[17]+BRIGHT #define C_GENERAL_MED txtcolor[18] #define C_GENERAL_LO txtcolor[19] #define C_GENERAL_INPUT txtcolor[20]+INVERSE #define C_DVID_BKGRD txtcolor[21] #define C_DVID_HI txtcolor[22]+BRIGHT #define C_DVID_LO txtcolor[23] #define C_STOP_ERR txtcolor[24]+BRIGHT #define C_STOP_INFO txtcolor[25]+BRIGHT #define C_TITLE_LOW txtcolor[26] #define C_AUTHDIV1 txtcolor[27]+INVERSE #define C_AUTHDIV2 txtcolor[28]+INVERSE #define C_PRIMARY txtcolor[29] #define C_CONTRIB txtcolor[30] /* structure for xmmmoveextended parameter */ struct XMM_Move { unsigned long Length; unsigned int SourceHandle; unsigned long SourceOffset; unsigned int DestHandle; unsigned long DestOffset; }; /* structure passed to fullscreen_prompts */ struct fullscreenvalues { int type; /* 'd' for double, 'f' for float, 's' for string, */ /* 'D' for integer in double, '*' for comment */ /* 'i' for integer, 'y' for yes=1 no=0 */ /* 0x100+n for string of length n */ /* 'l' for one of a list of strings */ /* 'L' for long */ union { double dval; /* when type 'd' or 'f' */ int ival; /* when type is 'i' */ long Lval; /* when type is 'L' */ char sval[16]; /* when type is 's' */ char far *sbuf; /* when type is 0x100+n */ struct { /* when type is 'l' */ int val; /* selected choice */ int vlen; /* char len per choice */ char **list; /* list of values */ int llen; /* number of values */ } ch; } uval; }; #define FILEATTR 0x37 /* File attributes; select all but volume labels */ #define HIDDEN 2 #define SYSTEM 4 #define SUBDIR 16 /* structure definition moved to port.h to take advantage of defines */ /* extern struct DIR_SEARCH DTA; Disk Transfer Area */ typedef struct palett { BYTE red; BYTE green; BYTE blue; } Palettetype; #define MAX_JUMPS 200 /* size of JUMP_CONTROL array */ typedef struct frm_jmpptrs_st { int JumpOpPtr; int JumpLodPtr; int JumpStoPtr; } JUMP_PTRS_ST; typedef struct frm_jump_st { int type; JUMP_PTRS_ST ptrs; int DestJumpIndex; } JUMP_CONTROL_ST; struct ext_blk_2 { char got_data; int length; int resume_data; }; struct ext_blk_3 { char got_data; int length; char form_name[40]; short uses_p1; short uses_p2; short uses_p3; short uses_ismand; short ismand; short uses_p4; short uses_p5; }; struct ext_blk_4 { char got_data; int length; int far *range_data; }; struct ext_blk_5 { char got_data; int length; char far *apm_data; }; /* parameter evolution stuff */ struct ext_blk_6 { char got_data; int length; short evolving; short gridsz; unsigned short this_gen_rseed; double fiddlefactor; double paramrangex; double paramrangey; double opx; double opy; short odpx; short odpy; short px; short py; short sxoffs; short syoffs; short xdots; short ydots; short ecount; short mutate[NUMGENES]; }; struct ext_blk_7 { char got_data; int length; double oxmin; double oxmax; double oymin; double oymax; double ox3rd; double oy3rd; short keep_scrn_coords; char drawmode; }; struct SearchPath { char par[FILE_MAX_PATH]; char frm[FILE_MAX_PATH]; char ifs[FILE_MAX_PATH]; char lsys[FILE_MAX_PATH]; } ; struct affine { /* weird order so a,b,e and c,d,f are vectors */ double a; double b; double e; double c; double d; double f; }; struct baseunit { /* smallest part of a fractint 'gene' */ void *addr ; /* address of variable to be referenced */ void (*varyfunc)(struct baseunit*,int,int); /* pointer to func used to vary it */ /* takes random number and pointer to var*/ int mutate ; /* flag to switch on variation of this variable */ /* 0 for no mutation, 1 for x axis, 2 for y axis */ /* in steady field maps, either x or y=yes in random modes*/ char name[16]; /* name of variable (for menu ) */ char level; /* mutation level at which this should become active */ }; typedef struct baseunit GENEBASE; #define sign(x) (((x) < 0) ? -1 : ((x) != 0) ? 1 : 0) /* * The following typedefs allow declaring based data * types that are stored in the code segment under MSC, * and thus may be overlaid. Use only for constant data. * Be sure to use the data right away, since arrays thus * declared do not exist when the overlay they belong to * is swapped out. */ #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef char __based(__segname("_CODE")) FCODE; #else typedef char far FCODE; #endif /* pointer to FCODE */ #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef FCODE * __based(__segname("_CODE")) PFCODE; #else typedef FCODE * PFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef BYTE __based(__segname("_CODE")) BFCODE; #else typedef BYTE far BFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef short __based(__segname("_CODE")) SIFCODE; #else typedef short far SIFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef short __based(__segname("_CODE")) USFCODE; #else typedef short far USFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef int __based(__segname("_CODE")) IFCODE; #else typedef int far IFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef unsigned int __based(__segname("_CODE")) UIFCODE; #else typedef unsigned int far UIFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef long __based(__segname("_CODE")) LFCODE; #else typedef long far LFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef unsigned long __based(__segname("_CODE")) ULFCODE; #else typedef unsigned long far ULFCODE; #endif #if (_MSC_VER >= 700 && !defined(WINFRACT)) typedef double __based(__segname("_CODE")) DFCODE; #else typedef double far DFCODE; #endif #endif #if _MSC_VER == 800 #ifndef FIXTAN_DEFINED /* !!!!! stupid MSVC tan(x) bug fix !!!!!!!! */ /* tan(x) can return -tan(x) if -pi/2 < x < pi/2 */ /* if tan(x) has been called before outside this range. */ double fixtan( double x ); #define tan fixtan #define FIXTAN_DEFINED #endif #endif xfractint-20.4.10.orig/headers/fmath.h0000644000000000000000000001537010150633601014371 0ustar #ifndef FMATH_H #define FMATH_H /* FMath.h (C) 1989, Mark C. Peterson, CompuServe [70441,3353] All rights reserved. Code may be used in any program provided the author is credited either during program execution or in the documentation. Source code may be distributed only in combination with public domain or shareware source code. Source code may be modified provided the copyright notice and this message is left unchanged and all modifications are clearly documented. I would appreciate a copy of any work which incorporates this code, however this is optional. Mark C. Peterson 128 Hamden Ave., F Waterbury, CT 06704 (203) 754-1162 Notes below document changes to Mark's original file: Date Change Changer ============================================================ 07-16-89 - Added sqrt define per Mark's suggestion TIW 07-26-89 - Added documentation and complex support MCP */ /***************** * Documentation * ***************** #include "fmath.h" float x, y, z; int Pot, Fudge; 23-bit accuracy (limit of type float) Regular Implementation Fast Math Implementation -------------------------------------------------------------------- z = x + y; fAdd(x, y, z); z = x * y; fMul(x, y, z); z = x * x; fSqr(x, z); z = x / y; fDiv(x, y, z); z = x * 2; fShift(x, 1, z); z = x * 16; fShift(x, 4, z); z = x / 32; fShift(x, -5, z); z = x / (pow(2.0, (double)Pot)); fShift(x, -Pot, z); z = (float)Pot * (1L << Fudge); Fg2Float(Pot, Fudge, z); Pot = (int)(z / (1L << Fudge)); Pot = Float2Fg(z, Fudge); Complex numbers using fComplex structures z = x**2 fSqrZ(&x, &z); mod updated z.mod = (z.x*z.x)+(z.y*z.y) fModZ(&z); mod updated z = 1 / x fInvZ(&x, &z); mod updated z = x * y fMulZ(&x, &y, &z); mod updated z = x / y fDivZ(&x, &y, &z); mod updated 16-bit accuracy Regular Implementation Fast Math Implementation -------------------------------------------------------------------- z = x * y; fMul16(x, y, z); z = x * x; fSqr16(x, z); 14-bit accuracy Regular Implementation Fast Math Implementation -------------------------------------------------------------------- z = log(x); fLog14(x, z); z = exp(x); fExp14(x, z); z = pow(x, y); fPow14(x, y, z); 12-bit accuracy Regular Implementation Fast Math Implementation -------------------------------------------------------------------- z = sin(x); fSin12(x, z); z = cos(x); fCos12(x, z); z = sinh(x); fSinh12(x, z); z = cosh(x); fCosh12(x, z); Complex numbers using fComplex structures z = sin(x) fSinZ(&x, &z); z = cos(x) fCosZ(&x, &z); z = tan(x) fTagZ(&x, &z); z = sinh(x) fSinhZ(&x, &z); z = cosh(x) fCoshZ(&x, &z); z = tanh(x) fCoshZ(&x, &z); Just be sure to declare x, y, and z as type floats instead of type double. */ long #ifndef XFRACT far RegFg2Float(long x, char FudgeFact), far RegSftFloat(long x, char Shift), #else far RegFg2Float(long x, int FudgeFact), far RegSftFloat(long x, int Shift), #endif far RegFloat2Fg(long x, int Fudge), far RegAddFloat(long x, long y), far RegDivFloat(long x, long y), far RegMulFloat(long x, long y), far RegSqrFloat(long x), far RegSubFloat(long x, long y); long far r16Mul(long x, long y), far r16Sqr(long x); int far sin13(long x), far cos13(long x), far FastCosine(int x), far FastSine(int x); long far FastHypCosine(int x), far FastHypSine(int x), far sinh13(long x), far cosh13(long x); long far LogFudged(unsigned long x, int Fudge); long far LogFloat14(unsigned long x); unsigned long far ExpFudged(long x, int Fudge); long far ExpFloat14(long x); #define fAdd(x, y, z) (void)((*(long*)&z) = RegAddFloat(*(long*)&x, *(long*)&y)) #define fMul(x, y, z) (void)((*(long*)&z) = RegMulFloat(*(long*)&x, *(long*)&y)) #define fDiv(x, y, z) (void)((*(long*)&z) = RegDivFloat(*(long*)&x, *(long*)&y)) #define fSub(x, y, z) (void)((*(long*)&z) = RegSubFloat(*(long*)&x, *(long*)&y)) #define fMul16(x, y, z) (void)((*(long*)&z) = r16Mul(*(long*)&x, *(long*)&y)) #define fSqr16(x, z) (void)((*(long*)&z) = r16Sqr(*(long*)&x)) #define fSqr(x, z) (void)((*(long*)&z) = RegSqrFloat(*(long*)&x)) #define fShift(x, Shift, z) (void)((*(long*)&z) = \ RegSftFloat(*(long*)&x, Shift)) #define Fg2Float(x, f, z) (void)((*(long*)&z) = RegFg2Float(x, f)) #define Float2Fg(x, f) RegFloat2Fg(*(long*)&x, f) #define fSin12(x, z) (void)((*(long*)&z) = \ RegFg2Float((long)sin13(Float2Fg(x, 13)), 13)) #define fCos12(x, z) (void)((*(long*)&z) = \ RegFg2Float((long)cos13(Float2Fg(x, 13)), 13)) #define fSinh12(x, z) (void)((*(long*)&z) = \ RegFg2Float(sinh13(Float2Fg(x, 13)), 13)) #define fCosh12(x, z) (void)((*(long*)&z) = \ RegFg2Float(cosh13(Float2Fg(x, 13)), 13)) #define fLog14(x, z) (void)((*(long*)&z) = \ RegFg2Float(LogFloat14(*(long*)&x), 16)) #define fExp14(x, z) (void)((*(long*)&z) = ExpFloat14(*(long*)&x)); #define fPow14(x, y, z) fLog14(x, z); fMul16(z, y, z); fExp14(z, z) #define fSqrt14(x, z) fLog14(x, z); fShift(z, -1, z); fExp14(z, z) struct fComplex { float x, y, mod; }; void fSqrZ(struct fComplex *x, struct fComplex *z), fMod(struct fComplex *x), fInvZ(struct fComplex *x, struct fComplex *z), fMulZ(struct fComplex *x, struct fComplex *y, struct fComplex *z), fDivZ(struct fComplex *x, struct fComplex *y, struct fComplex *z), fSinZ(struct fComplex *x, struct fComplex *z), fCosZ(struct fComplex *x, struct fComplex *z), fTanZ(struct fComplex *x, struct fComplex *z), fSinhZ(struct fComplex *x, struct fComplex *z), fCoshZ(struct fComplex *x, struct fComplex *z), fTanhZ(struct fComplex *x, struct fComplex *z); #endif xfractint-20.4.10.orig/headers/MATHTOOL.H0000644000000000000000000000203110400460450014445 0ustar #define ID_PERCENT 3001 #define ID_SB_PERCENT 3002 #define ID_X_COORD 1007 #define ID_X_NAME 1009 #define ID_Y_COORD 1008 #define ID_Y_NAME 1010 #define IDM_DEGREES 2005 #define IDM_GRAD 2006 #define IDM_MT_COORD 1005 #define IDM_MT_GRID 1002 #define IDM_MT_LOAD 1003 #define IDM_MT_POINT_INFO 1006 #define IDM_MT_SAVE 1004 #define IDM_PIXEL 2003 #define IDM_POLAR 2001 #define IDM_RADIANS 2004 #define IDM_RECT 2002 extern void MathToolBox(HWND); extern BOOL RegisterMathWindows(HANDLE); extern void SizeWindow(HWND); extern void ReSizeWindow(HWND); extern void WindowSizing(HWND); extern void ExecuteZoom(void); extern void StartZoomTracking(DWORD); extern void TrackZoom(DWORD); extern void EndZoom(DWORD); extern void PaintMathTools(void); extern void CancelZoom(void); extern void UpdateCoordBox(DWORD); extern void ZoomBar(HWND); extern void CoordinateBox(HWND); extern void CheckMathTools(void); xfractint-20.4.10.orig/headers/SELECT.H0000644000000000000000000000147010400460450014203 0ustar /* These defines determine the meaning of the fFlags variable. The low byte * is used for the various types of "boxes" to draw. The high byte is * available for special commands. */ #define SL_BOX 1 /* Draw a solid border around the rectangle */ #define SL_BLOCK 2 /* Draw a solid rectangle */ #define SL_ZOOM 3 #define SL_EXTEND 256 /* Extend the current pattern */ #define SL_TYPE 0x00FF /* Mask out everything but the type flags */ #define SL_SPECIAL 0xFF00 /* Mask out everything but the special flags */ void FAR PASCAL StartSelection(HWND, POINT, LPRECT, int); void FAR PASCAL UpdateSelection(HWND, POINT, LPRECT, int); void FAR PASCAL EndSelection(POINT, LPRECT); void FAR PASCAL ClearSelection(HWND, LPRECT, int); xfractint-20.4.10.orig/headers/lsys.h0000644000000000000000000000541010150633601014256 0ustar /* lsys.h * Header file for L-system code. * Nicholas Wilt, 6/26/93. */ #ifndef LSYS_H #define LSYS_H #define size ssize /* Needed for use of asm -- helps decide which pointer to function * to put into the struct lsys_cmds. */ /* Macro to take an FP number and turn it into a * 16/16-bit fixed-point number. */ #define FIXEDMUL 524288L #define FIXEDPT(x) ((long) (FIXEDMUL * (x))) /* The number by which to multiply sines, cosines and other * values with magnitudes less than or equal to 1. * sins and coss are a 3/29 bit fixed-point scheme (so the * range is +/- 2, with good accuracy. The range is to * avoid overflowing when the aspect ratio is taken into * account. */ #define FIXEDLT1 536870912.0 #define ANGLE2DOUBLE (2.0*PI / 4294967296.0) #define MAXRULES 27 /* this limits rules to 25 */ #define MAX_LSYS_LINE_LEN 255 /* this limits line length to 255 */ struct lsys_turtlestatei { char counter, angle, reverse, stackoflow; /* dmaxangle is maxangle - 1 */ char maxangle, dmaxangle, curcolor, dummy; /* dummy ensures longword alignment */ long size; long realangle; long xpos, ypos; /* xpos and ypos are long, not fixed point */ long xmin, ymin, xmax, ymax; /* as are these */ long aspect; /* aspect ratio of each pixel, ysize/xsize */ long num; }; struct lsys_turtlestatef { char counter, angle, reverse, stackoflow; /* dmaxangle is maxangle - 1 */ char maxangle, dmaxangle, curcolor, dummy; /* dummy ensures longword alignment */ LDBL size; LDBL realangle; LDBL xpos, ypos; LDBL xmin, ymin, xmax, ymax; LDBL aspect; /* aspect ratio of each pixel, ysize/xsize */ union { long n; LDBL nf; } parm; }; extern char maxangle; /* routines in lsysa.asm */ #ifdef XFRACT #define lsysi_doat_386 lsys_doat #define lsysi_dosizegf_386 lsys_dosizegf #define lsysi_dodrawg_386 lsys_dodrawg #else extern void lsysi_doat_386(struct lsys_turtlestatei *cmd); extern void lsysi_dosizegf_386(struct lsys_turtlestatei *cmd); extern void lsysi_dodrawg_386(struct lsys_turtlestatei *cmd); #endif /* routines in lsysaf.asm */ extern void lsys_prepfpu(struct lsys_turtlestatef *); extern void lsys_donefpu(struct lsys_turtlestatef *); /* routines in lsysf.c */ extern struct lsys_cmd far * _fastcall drawLSysF(struct lsys_cmd far *command,struct lsys_turtlestatef *ts, struct lsys_cmd far **rules,int depth); extern int _fastcall lsysf_findscale(struct lsys_cmd far *command, struct lsys_turtlestatef *ts, struct lsys_cmd far **rules, int depth); extern struct lsys_cmd far *LSysFSizeTransform(char far *s, struct lsys_turtlestatef *ts); extern struct lsys_cmd far *LSysFDrawTransform(char far *s, struct lsys_turtlestatef *ts); extern void _fastcall lsysf_dosincos(void); #endif xfractint-20.4.10.orig/headers/targa_lc.h0000644000000000000000000000126410150633601015043 0ustar #ifndef TARGA_LC_H #define TARGA_LC_H #define HEADERSIZE 18 /* Size, offsets, and masks for the */ #define O_COMMENTLEN 0 /* TGA file header. This is not a */ #define O_MAPTYPE 1 /* structure to avoid problems with */ #define O_FILETYPE 2 /* byte-packing and such. */ #define O_MAPORG 3 #define O_MAPLEN 5 #define O_MAPSIZE 7 #define O_XORIGIN 8 #define O_YORIGIN 10 #define O_HSIZE 12 #define O_VSIZE 14 #define O_ESIZE 16 #define O_FLAGS 17 #define M_ORIGIN 0x20 #define T_NODATA 0 #define T_RAWMAP 1 #define T_RAWRGB 2 #define T_RAWMON 3 #define T_RLEMAP 9 #define T_RLERGB 10 #define T_RLEMON 11 #endif xfractint-20.4.10.orig/headers/cmplx.h0000644000000000000000000000101510150633601014404 0ustar /* various complex number defs */ #ifndef _CMPLX_DEFINED #define _CMPLX_DEFINED struct DHyperComplex { double x,y; double z,t; }; struct LHyperComplex { long x,y; long z,t; }; struct DComplex { double x,y; }; struct LDComplex { LDBL x,y; }; struct LComplex { long x,y; }; typedef struct DComplex _CMPLX; typedef struct LDComplex _LDCMPLX; typedef struct LComplex _LCMPLX; typedef struct DHyperComplex _HCMPLX; typedef struct LHyperComplex _LHCMPLX; #endif xfractint-20.4.10.orig/headers/targa.h0000644000000000000000000002667010150633601014375 0ustar /* targa.h */ #ifndef TARGA_H #define TARGA_H extern unsigned int _dataseg_xx; /****************************************************************/ #ifdef __TURBOC__ # define PEEK(a,b,c,d) movedata( b, a, _DS, c, d) # define POKE(a,b,c,d) movedata( _DS, c, b, a, d ) # define OUTPORTB outportb # define INPORTB inportb # define OUTPORTW outport # define INPORTW inport #else # define PEEK(a,b,c,d) movedata( b, a, _dataseg_xx, c, d) # define POKE(a,b,c,d) movedata( _dataseg_xx, c, b, a, d ) # define OUTPORTB outp # define INPORTB inp # define OUTPORTW outpw # define INPORTW inpw #endif #define FALSE 0 #ifdef TRUE #undef TRUE #endif #define TRUE 1 /****************************************************************/ #define TSEG 0xA000 #define TIOBASE 0x220 /****************************************************************/ #define TYPE_8 8 #define TYPE_16 16 #define TYPE_24 24 #define TYPE_32 32 #define TYPE_M8 -8 /* * TARGA: 400 to 482 rows x 512 pixels/row X 16 bits/pixel */ #define XMIN 0 #define YMIN 0 #define XMAX 512 /* maximum X value */ #define YMAX 512 /* maximum Y value */ #define XRES 512 /* X resolution */ #define YRES 512 /* Y Resolution */ #define YVISMAX (2*targa.LinesPerField) /* Maximum visible Y coordinate */ #define YVISMIN 0 /* Minimum visible Y coordiate */ #define DEF_ROWS 400 /* Default number of rows */ #define IOBASE targa.iobase /* io base location of graphics registers */ #define MEMSEG targa.memloc /* use the variable so we can use */ #define SCNSEG targa.memloc /* the one defined in TARGA */ #define SRCBANK (targa.memloc+0x0800) /* use high-bank as source bank */ #define DESTBANK targa.memloc /* use lo-bank as destination bank */ /* Output register definitions */ #define MODEREG (IOBASE+0xC00) /* Mode Register address */ #define MASKREG (IOBASE+0x800) /* Mask Registers */ #define UNDERREG (IOBASE+0x800) /* Underscan register */ #define OVERREG (IOBASE+0x802) /* overscan register */ #define DESTREG (IOBASE+0x802) /* Address of Page Select Lower Register */ #define SRCREG (IOBASE+0x803) /* Address of Page Select Upper Register */ #define VCRCON (IOBASE+0x400) /* Address of Contrast/VidSrc Register */ #define BLNDREG VCRCON #define SATHUE (IOBASE+0x402) /* Satuation/Hue Register address */ #define DRREG (IOBASE+0x401) /* ADDRESS OF Controller Write Register */ #define VERTPAN (IOBASE+0x403) /* Address of Vertical Pan Register */ #define BORDER (IOBASE) /* Address of Page Select Lower Register */ /* Input register definitions */ #define VIDEOSTATUS (IOBASE+0xC02) /* Video Status Register */ #define RASTERREG (IOBASE+0xC00) /* Raster counter register */ /* Default register values */ #define DEF_MODE 1 /* Default mode register value */ /* Memory selected, 512x512, 1x */ /* Display mode */ #define DEF_MASK 0 /* default memory mask */ #define DEF_SATURATION 0x4 /* default saturation value */ #define DEF_HUE 0x10 /* default hue value */ #define DEF_CONTRAST 0x10 /* default contrast value */ #define DEF_VIDSRC 0 /* default video source value - Composite */ #define DEF_VERTPAN 56 /* assumes 400-line output */ #define DEF_BORDER 0 /* default border color */ /* MASK AND SHIFT VALUE FOR REGISTERS CONTAINING SUBFIELDS */ /* * ****************************************************** * MODE REGISTERS * ****************************************************** */ #define MSK_MSEL 0xfffC /* memory select bits */ #define SHF_MSEL 0x0000 #define MSEL 1 #define MSK_IBIT 0xfffb /* Interlace bit */ #define SHF_IBIT 2 #define MSK_RES 0xFFC7 /* disp. resolution and screen select bits */ #define SHF_RES 3 #define S0_512X512_0 0 /* 512x512 resolution screen */ #define S1_512X512_1 1 #define S2_512X256_0 2 /* 512x256 resolution screen 0 */ #define S3_512X256_1 3 /* 512x256 resolution screen 1 */ #define S4_256X256_0 4 /* 256x256 resolution screen 0 */ #define S5_256X256_1 5 /* .... */ #define S6_256X256_2 6 #define S7_256X256_3 7 #define MSK_REGWRITE 0xFFBF /* mask for display register write */ #define SHF_REGWRITE 6 #define REGINDEX 0 /* to write an index value */ #define REGVALUE 1 /* to write a value */ #define MSK_BIT9 0xFF7F /* maks for high-order bit of DR's */ #define SHF_BIT9 7 #define MSK_TAPBITS 0xFCFF /* mask for setting the tap bits */ #define SHF_TAPBITS 8 #define MSK_ZOOM 0xF3FF /* Mask for zoom factor */ #define SHF_ZOOM 10 #define MSK_DISPLAY 0xCFFF /* Mask for display mode */ #define SHF_DISPLAY 12 #define MEMORY_MODE 0 #define LIVE_FIXED 1 #define OVERLAY_MODE 2 #define LIVE_LIVE 3 #define DEF_DISPLAY 0 #define MSK_CAPTURE 0xBFFF /* Mask for capture bit */ #define SHF_CAPTURE 14 #define MSK_GENLOCK 0x7FFF /* MASK FOR GENLOCK */ #define SHF_GENLOCK 15 #define DEF_GENLOCK 0 /* Video status input register */ #define FIELDBIT 0x0001 #define VIDEOLOSS 0x0002 /* VIDEO SOURCE/CONTROL REGISTER */ #define MSK_CONTRAST 0xFFC1 #define SHF_CONTRAST 1 #define MAX_CONTRAST 0x1f #define MSK_RGBORCV 0xBF #define SHF_RGBORCV 6 #define RGB 1 #define CV 0 #define MSK_VCRORCAMERA 0x7F #define SHF_VCRORCAMERA 7 #define VCR 1 #define CAMERA 0 /* HUE/SATUATION REGISTER */ #define MSK_HUE 0xE0 #define SHF_HUE 0 #define MAX_HUE 0x1f #define MSK_SATURATION 0x1F #define SHF_SATURATION 5 #define MAX_SATURATION 0x07 /* * ********************************************* * Display register settings * ********************************************* * * Screen Positioning Registers: * DR 0-3 */ #define LEFTBORDER 0 #define DEF_LEFT 85 #define MIN_LEFT 75 #define MAX_LEFT 95 #define RIGHTBORDER 1 #define DEF_RIGHT (DEF_LEFT+256) #define TOPBORDER 2 #define DEF_TOP 40 #define MIN_TOP 20 #define BOTTOMBORDER 3 #define DEF_BOTTOM (DEFTOP+DEFROWS/2) #define MAX_BOTTOM 261 /* REgisters which track 0-3 */ #define DR8 8 #define PRESHIFT DR8 #define EQU_DR8 DR0 #define DR9 9 #define EQU_DR9 DR1 #define DR10 10 #define EQU_DR10 DR2 #define DR11 11 #define EQU_DR11 DR3 /* REQUIRED REGISTERS */ #define DR4 4 #define DEF_DR4 352 #define DR5 5 #define DEF_DR5 1 #define DR6 6 #define DEF_DR6 0 #define DR7 7 #define DEF_DR7 511 #define DR12 12 #define DEF_DR12 20 #define DR13 13 #define DEF_DR13 22 #define DR14 14 #define DEF_DR14 0 #define DR15 15 #define DEF_DR15 511 #define DR16 16 #define DEF_DR16 0 #define DR17 17 #define DEF_DR17 0 #define DR18 18 #define DEF_DR18 0 #define DR19 19 #define DEF_DR19 4 /* interlace mode register & parameters */ #define DR20 20 #define INTREG 0x14 #define DEF_INT 0 /* default to interlace mode 0 */ #define MSK_INTERLACE 0x0003 /**************************************************************/ typedef struct { /* Board Configuration */ int memloc; /* memory segment */ int iobase; /* IOBASE segment */ int BytesPerPixel; /* number of words per pixel */ int RowsPerBank; /* number of row per 64K bank */ int MaxBanks; /* maximum bank id */ int AddressShift; /* number of bits to shift address */ /* Control registers */ int mode; /* mode register */ int Mask; /* mask register */ int PageMode; /* current page mode (screen res. and page) */ unsigned PageLower; /* Lower Page Select register */ unsigned PageUpper; /* upper Page select register */ int VCRCon; /* VCRContract register */ int SatHue; /* Hue and Saturation register */ long BorderColor; /* Border color register */ int VertShift; /* Vertical Pan Register */ int PanXOrig, PanYOrig; /* x,y pan origin */ /* TARGA-SET PARAMETERS */ int boardType; /* See TYPE_XX IN THIS FILE */ /* FOR DEFINITION OF Board Types */ int xOffset; /* X-offset */ int yOffset; /* Y-Offset */ int LinesPerField; /* maximum visible row count */ int InterlaceMode; /* desired interlace mode */ int AlwaysGenLock; /* Genlock always on or not */ int Contrast; /* Desired Contrast */ int Hue; /* Desired Hue */ int Saturation; /* Desired Satuation */ int RGBorCV; /* CV or RGB Input */ int VCRorCamera; /* VCR or Camera */ int ovrscnAvail, ovrscnOn; /* ovrscnAvail 1 if Overscan installed */ /* ovrscnOn 1 if overscan is stretching */ /* Display Registers */ int DisplayRegister[22]; } TARStruct; /****************************************************************/ /* Data Definitions */ #ifdef TARGA_DATA # define _x_ # define eq( val ) =val #else # define _x_ extern # define eq( val ) #endif _x_ int tseg eq( TSEG ); _x_ int tiobase eq( TIOBASE ); _x_ TARStruct targa; #undef _x_ #undef eq #endif xfractint-20.4.10.orig/headers/WINFRACT.H0000644000000000000000000001436011133770665014463 0ustar /* file menu items */ #define ID_CANCEL 102 #define IDM_NEW 100 #define IDM_OPEN 101 #define IDM_SAVE 102 #define IDM_SAVEAS 103 #define IDM_PRINT 104 #define IDM_MAPIN 115 #define IDM_MAPOUT 116 #define IDM_3D 113 #define IDM_3DOVER 114 #define IDM_EXIT 105 #define IDM_ABOUT 106 #define IDM_COPY 117 #define IDM_PARFILE 118 #define IDM_SAVEPAR 119 #define IDM_HELP_INDEX 107 #define IDM_HELP_KEYBOARD 108 #define IDM_HELP_HELP 109 #define IDM_HELP_FRACTINT 201 #define ID_VERSION 110 #define ID_COMMENT 111 #define ID_COMMENT2 112 #define ID_COMMENT3 113 #define ID_COMMENT4 114 #define ID_COMMENT5 115 #define ID_COMMENT6 116 #define ID_COMMENT7 117 #define ID_COMMENT8 118 #define ID_COMMENT9 119 #define ID_COMMENT10 120 #define ID_FILETITLE 112 #define ID_LISTTITLE 112 #define IDS_STATUS 340 /* fractal formula stuff */ #define IDM_FRACTAL 171 #define IDM_FORMULA 172 #define IDM_IMAGE 173 #define IDM_DOODADX 174 #define IDM_DOODADY 175 #define IDM_DOODADZ 176 #define IDM_CYCLE 177 #define IDM_IFS3D 178 #define IDM_STARFIELD 179 #define IDM_PIXELS 180 #define IDM_ORBITS 181 #define IDM_RESTART 182 #define IDM_PASSES 183 #define ID_GIF89A 113 #define ID_GIF87A 114 #define ID_BMP 115 /* Control IDs */ #define IDC_FILENAME 400 #define IDC_EDIT 401 #define IDC_FILES 402 #define IDC_PATH 403 #define IDC_LISTBOX 404 /* hot-keys (Fractint-compatible accelerator keys) */ #define IDF_FRACTINTSTYLE 599 #define IDF_WINFRACTSTYLE 598 #define IDF_HELP_INDEX 500 #define IDF_HELP_FRACTINT 501 #define IDF_HOTNOZOOM 502 #define IDF_HOTCYCLEON 503 #define IDF_HOTCYCLERIGHT 504 #define IDF_HOTCYCLELEFT 505 #define IDF_HOTCYCLERAND 506 #define IDF_HOTCYCLEFAST 507 #define IDF_HOTCYCLESLOW 508 #define IDF_STATUS 509 #define IDF_IMAGE 510 #define IDF_FORMULA 511 #define IDF_OPEN 512 #define IDF_SAVE 513 #define IDF_3D 514 #define IDF_3DOVER 515 #define IDF_PRINT 516 #define IDF_DOODADX 517 #define IDF_DOODADY 518 #define IDF_DOODADZ 519 #define IDF_CYCLE 520 #define IDF_PARFILE 521 #define IDF_SAVEPAR 522 #define IDF_MAPIN 523 #define IDF_MAPOUT 524 #define IDF_HOTCYCLELSTEP 525 #define IDF_HOTCYCLERSTEP 526 #define IDF_IFS3D 527 #define IDF_STARFIELD 528 #define IDF_RESTART 529 #define IDF_PASSES 530 #define IDF_CMDSTRING 534 #define IDF_HISTORY_B 535 #define IDF_HISTORY_F 536 /* Math Tools */ #define IDM_MATH_TOOLS 1001 #define IDM_COORD 1002 #define IDM_ZOOM 1003 #define IDM_SIZING 1004 #define IDM_TRACKING 1005 /* #define IDM_ZOOMIN 1006 this is odd!! */ #define IDM_ZOOMIN 1060 #define IDM_ZOOMOUT 1007 /* Print stuff */ #define ID_PR_DEVICE 450 #define ID_PR_ORIENT 451 #define ID_PRO_PORTR 452 #define ID_PRO_LANDS 453 #define ID_PR_SIZE 454 #define ID_PRS_MAX 455 #define ID_PRS_MAXSIZ 456 #define ID_PRS_CUST 457 #define ID_PRS_WIDTH 458 /* Windows 3.0 vs 3.1 SDK patch */ #ifndef COLOR_ENDCOLORS #define COLOR_ENDCOLORS 18 #endif #define WINMAXPIXELS 4096 /* Maximum pixel count across/down the screen */ int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int); BOOL InitApplication(HANDLE); BOOL InitInstance(HANDLE, int); LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SaveStatusProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK About(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK HelpBox(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectFractal(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectFracParams(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectImage(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectDoodads(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectExtended(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectSavePar(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectCycle(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK Select3D(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK Select3DPlanar(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK Select3DSpherical(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectFullScreen(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK Status(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectIFS3D(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectFunnyGlasses(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectLightSource(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK SelectStarfield(HWND, UINT, WPARAM, LPARAM); void SeparateFile(HWND, LPSTR, LPSTR, LPSTR); void UpdateListBox(HWND); void AddExt(PSTR, PSTR); void ChangeDefExt(PSTR, PSTR); HDC PASCAL GetPrinterDC(); void OpenStatusBox(HWND, HANDLE); void CloseStatusBox(void); void UpdateStatusBox(unsigned long, unsigned long); extern char far StatusTitle[]; void SaveBitmapFile(HWND, char *); extern void win_title_text(int); int set_win_offset(void); void win_savedac(void); int default_dib_palette(void); void win_kill_all_zooming(void); int win_stop_cycling(void); int win_oktocycle(void); int win_copy_to_clipboard(void); void check_funnyglasses_name(void); int get_formula_names(void); int parse_formula_names(void); int get_lsys_name(void); BOOL cant_clip(void); extern void mono_dib_palette(void); extern int rgb_dib_palette(void); extern void SecondaryWndProc(void); /* prototypes are here because windows.h doesn't play nice with others */ /* BOOL is defined in windows.h */ /* profile -- C file prototypes */ extern void SetToolsPath(void); extern BOOL GetParamSwitch(char *); extern void SaveParamSwitch(char *, BOOL); extern void PositionWindow(HWND, char *); extern void SaveWindowPosition(HWND, char *); extern void InitializeParameters(HWND); extern void SaveParameters(HWND); extern void SaveIntParam(char *, int); /* wintext -- C file prototypes */ extern BOOL wintext_initialize(HANDLE, HWND, LPSTR); xfractint-20.4.10.orig/headers/tplus.h0000644000000000000000000000465610150633601014446 0ustar /* TPLUS.H, (C) 1991 The Yankee Programmer All Rights Reserved This code may be distributed only when bundled with the Fractint source code. Mark C. Peterson The Yankee Programmer 405-C Queen Street, Suite #181 Southington, CT 06489 (203) 276-9721 */ #ifndef TPLUS_H #define TPLUS_H #ifdef CTL #undef CTL #endif #ifdef __TURBOC__ #define OUTPORTB outportb #define INPORTB inportb #define OUTPORTW outport #define INPORTW inport #else #define OUTPORTB outp #define INPORTB inp #define OUTPORTW outpw #define INPORTW inpw #endif struct TPWrite { unsigned COLOR0, COLOR1, COLOR2, COLOR3, VIDCON, INDIRECT, HUESAT, OVSTRT, MASKL, MASKH, LBNK, HBNK, MODE1, MODE2, WBL, WBH; }; struct TPRead { unsigned VIDSTAT, CTL, MASKL, LBNK, READAD, MODE1, OVSTRT, USCAN, MASKH, OSCAN, HBNK, ROWCNT, MODE2, RBL, RBH; }; /* TPlus Register Data Offsets */ #define XDOTS 0 #define YDOTS 1 #define ASP_RATIO 2 #define DEPTH 4 #define PAGE 5 #define BOTBANK 7 #define TOPBANK 8 #define ZOOM 10 #define DISPMODE 11 #define DAC567DATA 15 #define VTOP 19 #define TOP 51 #define BOT 53 #define VPAN 55 #define NOT_INT 56 #define HIRES 61 #define PERM 64 #define BYCAP 68 #define PE 69 #define OVLE 70 #define HPAN 71 #define MEM_BASE 73 #define MEM_MAP 74 #define LIVEMIXSRC 91 #define RGB 93 #define SVIDEO 97 #define BUFFPORTSRC 98 #define CM1 101 #define CM2 102 #define LUTBYPASS 107 #define CM3 113 #define LIVEPORTSRC 115 #define LIVE8 116 #define VGASRC 123 struct _BOARD { int ThisBoard, ClearScreen; BYTE far *Screen; unsigned VerPan, HorPan, Top, Bottom; unsigned xdots, ydots, Bank64k, RowBytes, RowsPerBank; unsigned Reg[128]; #ifndef XFRACT void (*Plot)(int x, int y, unsigned long Color); unsigned long (*GetColor)(int x, int y); #else void (*Plot)(); unsigned long (*GetColor)(); #endif struct TPRead Read; struct TPWrite Write; }; extern struct _BOARD far TPlus; #endif xfractint-20.4.10.orig/headers/big.h0000644000000000000000000002763210532116313014037 0ustar /* big.h */ /* Wesley Loewer's Big Numbers. (C) 1994, Wesley B. Loewer */ #ifndef _BIG_H #define _BIG_H /************************************************************* The following allows the programmer to customize routines. They can be selected here or on the compiler command line. **************************************************************/ /* different pointer versions: near, based, far */ /* huge pointers is not supported in assembly, only in C */ /* uncomment only ONE of these or declare on compiler command line */ /* #define BIG_NEAR */ #if defined(_MSC_VER) # define BIG_BASED #elif defined( __BORLANDC__) # define BIG_FAR #endif /* #define BIG_HUGE */ /* C code only */ /* #define BIG_ANSI_C */ /* C code only */ /* In DOS, BIG_ANSI_C uses default pointer for model selected */ /* Number of bytes to use for integer part for fixed decimal math, */ /* does not effect floating point math at all. */ #define BN_INT_LENGTH 4 /* #define CALCULATING_BIG_PI */ /* define for generating big_pi[] table */ /**************************************************************** The rest is handled by the compiler ****************************************************************/ #ifndef BIG_NEAR #ifndef BIG_BASED #ifndef BIG_FAR #ifndef BIG_HUGE #ifndef BIG_ANSI_C #error BIG_NEAR, BIG_BASED, BIG_FAR, BIG_HUGE, or BIG_ANSI_C must be defined. #endif #endif #endif #endif #endif #define LOG10_256 2.4082399653118 #define LOG_256 5.5451774444795 /* values that bf_math can hold, */ /* 0 = bf_math is not being used */ /* 1 = bf_math is being used */ #define BIGNUM 1 /* bf_math is being used with bn_t numbers */ #define BIGFLT 2 /* bf_math is being used with bf_t numbers */ /* use this for dynamic allocation */ #ifdef BIG_NEAR extern _segment bignum_seg; #define BIGDIST __near #define BIG_NULL NULL #define BIG_SIZE_T size_t #define big_malloc(size) _nmalloc(size) #define big_free(ptr) _nfree(ptr) #endif #ifdef BIG_BASED extern _segment bignum_seg; #define BIGDIST __based(bignum_seg) #define BIG_NULL _NULLOFF #define BIG_SIZE_T size_t #define big_malloc(size) _bmalloc(bignum_seg, (size)) #define big_free(ptr) _bfree( bignum_seg, (ptr)) #endif #ifdef BIG_FAR #define BIGDIST __far #define BIG_NULL NULL #define BIG_SIZE_T size_t #define big_malloc(size) _fmalloc( size ) #define big_free(ptr) _ffree(ptr) #endif #ifdef BIG_HUGE #define BIGDIST __huge #define BIG_NULL NULL #define BIG_SIZE_T long #define big_malloc(size) _halloc( (size), 1 ) #define big_free(ptr) _hfree(ptr) #endif #ifdef BIG_ANSI_C #define USE_BIGNUM_C_CODE #define BIGDIST #define BIG_NULL NULL #define BIG_SIZE_T size_t #define big_malloc(size) malloc(size) #define big_free(ptr) free(ptr) #endif typedef unsigned char BIGDIST * big_t; #define bn_t big_t /* for clarification purposes */ #define bf_t big_t #define bf10_t big_t #if 0 /* remove for Fractint */ struct Complex { LDBL x; LDBL y; }; typedef struct Complex _CMPLX; #else #include "cmplx.h" #endif struct BFComplex { bn_t x; bn_t y; }; typedef struct BFComplex _BFCMPLX; struct BNComplex { bn_t x; bn_t y; }; typedef struct BNComplex _BNCMPLX; /* globals */ extern int fpu; extern int cpu; extern int bf_math; extern int bnstep, intlength; extern int bnlength, rlength, padding, decimals, shiftfactor; extern int bflength, rbflength, bfpadding, bfdecimals; extern bn_t bntmp1, bntmp2, bntmp3, bntmp4, bntmp5, bntmp6; /* rlength */ extern bn_t bntest1, bntest2, bntest3; /* rlength */ extern bn_t bntmpcpy1, bntmpcpy2; /* bnlength */ extern bn_t bn_pi; extern bn_t bntmp; /* rlength */ extern bf_t bftmp1, bftmp2, bftmp3, bftmp4, bftmp5, bftmp6; /* rbflength+2 */ extern bf_t bftest1, bftest2, bftest3; /* rbflength+2 */ extern bf_t bftmpcpy1, bftmpcpy2; /* bflength+2 */ extern bf_t bf_pi; extern bf_t bftmp; /* rbflength */ extern bf10_t bf10tmp; /* dec+4 */ extern big_t big_pi; /* functions defined in biginit.c */ big_t big_alloc(size_t size); /* void big_free(big_t memblock); now defined as a macro above */ void calc_lengths(void); void init_big_dec(int dec); void init_big_length(int bnl); void init_big_pi(void); /* functions defined in bignuma.asm or bignumc.c */ extern bn_t clear_bn(bn_t r); extern bn_t max_bn(bn_t r); extern bn_t copy_bn(bn_t r, bn_t n); extern int cmp_bn(bn_t n1, bn_t n2); extern int is_bn_neg(bn_t n); extern int is_bn_not_zero(bn_t n); extern bn_t add_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t add_a_bn(bn_t r, bn_t n); extern bn_t sub_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t sub_a_bn(bn_t r, bn_t n); extern bn_t neg_bn(bn_t r, bn_t n); extern bn_t neg_a_bn(bn_t r); extern bn_t double_bn(bn_t r, bn_t n); extern bn_t double_a_bn(bn_t r); extern bn_t half_bn(bn_t r, bn_t n); extern bn_t half_a_bn(bn_t r); extern bn_t unsafe_full_mult_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t unsafe_mult_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t unsafe_full_square_bn(bn_t r, bn_t n); extern bn_t unsafe_square_bn(bn_t r, bn_t n); extern bn_t mult_bn_int(bn_t r, bn_t n, U16 u); extern bn_t mult_a_bn_int(bn_t r, U16 u); extern bn_t unsafe_div_bn_int(bn_t r, bn_t n, U16 u); extern bn_t div_a_bn_int(bn_t r, U16 u); /* used to be in bigflta.asm or bigfltc.c */ extern bf_t clear_bf(bf_t r); extern bf_t copy_bf(bf_t r, bf_t n); extern bf_t floattobf(bf_t r, LDBL f); extern LDBL bftofloat(bf_t n); extern LDBL bntofloat(bn_t n); extern LDBL extract_256(LDBL f, int *exp_ptr); extern LDBL scale_256( LDBL f, int n ); /* functions defined in bignum.c */ #ifdef ACCESS_BY_BYTE /* prototypes */ extern U32 big_access32(BYTE BIGDIST *addr); extern U16 big_access16(BYTE BIGDIST *addr); extern S16 big_accessS16(S16 BIGDIST *addr); extern U32 big_set32(BYTE BIGDIST *addr, U32 val); extern U16 big_set16(BYTE BIGDIST *addr, U16 val); extern S16 big_setS16(S16 BIGDIST *addr, S16 val); #else /* equivalent defines */ #define big_access32(addr) (*(U32 BIGDIST *)(addr)) #define big_access16(addr) (*(U16 BIGDIST *)(addr)) #define big_accessS16(addr) (*(S16 BIGDIST *)(addr)) #define big_set32(addr, val) (*(U32 BIGDIST *)(addr) = (U32)(val)) #define big_set16(addr, val) (*(U16 BIGDIST *)(addr) = (U16)(val)) #define big_setS16(addr, val) (*(S16 BIGDIST *)(addr) = (S16)(val)) #endif extern void bn_hexdump(bn_t r); extern bn_t strtobn(bn_t r, char *s); extern char *unsafe_bntostr(char *s, int dec, bn_t r); extern bn_t inttobn(bn_t r, long longval); extern long bntoint(bn_t n); extern int sign_bn(bn_t n); extern bn_t abs_bn(bn_t r, bn_t n); extern bn_t abs_a_bn(bn_t r); extern bn_t unsafe_inv_bn(bn_t r, bn_t n); extern bn_t unsafe_div_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t sqrt_bn(bn_t r, bn_t n); extern bn_t exp_bn(bn_t r, bn_t n); extern bn_t unsafe_ln_bn(bn_t r, bn_t n); extern bn_t unsafe_sincos_bn(bn_t s, bn_t c, bn_t n); extern bn_t unsafe_atan_bn(bn_t r, bn_t n); extern bn_t unsafe_atan2_bn(bn_t r, bn_t ny, bn_t nx); extern int convert_bn(bn_t new,bn_t old,int newbnlength,int newintlength,int oldbnlength,int oldintlength); /* "safe" versions */ extern bn_t full_mult_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t mult_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t full_square_bn(bn_t r, bn_t n); extern bn_t square_bn(bn_t r, bn_t n); extern bn_t div_bn_int(bn_t r, bn_t n, U16 u); extern char *bntostr(char *s, int dec, bn_t r); extern bn_t inv_bn(bn_t r, bn_t n); extern bn_t div_bn(bn_t r, bn_t n1, bn_t n2); extern bn_t ln_bn(bn_t r, bn_t n); extern bn_t sincos_bn(bn_t s, bn_t c, bn_t n); extern bn_t atan_bn(bn_t r, bn_t n); extern bn_t atan2_bn(bn_t r, bn_t ny, bn_t nx); /* misc */ extern int is_bn_zero(bn_t n); extern bn_t floattobn(bn_t r, LDBL f); /************/ /* bigflt.c */ extern void bf_hexdump(bf_t r); extern bf_t strtobf(bf_t r, char *s); extern int strlen_needed_bf(); extern char *unsafe_bftostr(char *s, int dec, bf_t r); extern char *unsafe_bftostr_e(char *s, int dec, bf_t r); extern char *unsafe_bftostr_f(char *s, int dec, bf_t r); extern bn_t bftobn(bn_t n, bf_t f); extern bn_t bntobf(bf_t f, bn_t n); extern long bftoint(bf_t f); extern bf_t inttobf(bf_t r, long longval); extern int sign_bf(bf_t n); extern bf_t abs_bf(bf_t r, bf_t n); extern bf_t abs_a_bf(bf_t r); extern bf_t unsafe_inv_bf(bf_t r, bf_t n); extern bf_t unsafe_div_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t unsafe_sqrt_bf(bf_t r, bf_t n); extern bf_t exp_bf(bf_t r, bf_t n); extern bf_t unsafe_ln_bf(bf_t r, bf_t n); extern bf_t unsafe_sincos_bf(bf_t s, bf_t c, bf_t n); extern bf_t unsafe_atan_bf(bf_t r, bf_t n); extern bf_t unsafe_atan2_bf(bf_t r, bf_t ny, bf_t nx); extern bf_t add_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t add_a_bf(bf_t r, bf_t n); extern bf_t sub_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t sub_a_bf(bf_t r, bf_t n); extern bf_t full_mult_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t mult_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t full_square_bf(bf_t r, bf_t n); extern bf_t square_bf(bf_t r, bf_t n); extern bf_t mult_bf_int(bf_t r, bf_t n, U16 u); extern bf_t div_bf_int(bf_t r, bf_t n, U16 u); extern char *bftostr(char *s, int dec, bf_t r); extern char *bftostr_e(char *s, int dec, bf_t r); extern char *bftostr_f(char *s, int dec, bf_t r); extern bf_t inv_bf(bf_t r, bf_t n); extern bf_t div_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t sqrt_bf(bf_t r, bf_t n); extern bf_t ln_bf(bf_t r, bf_t n); extern bf_t sincos_bf(bf_t s, bf_t c, bf_t n); extern bf_t atan_bf(bf_t r, bf_t n); extern bf_t atan2_bf(bf_t r, bf_t ny, bf_t nx); extern int is_bf_zero(bf_t n); extern int convert_bf(bf_t new, bf_t old, int newbflength, int oldbflength); extern LDBL extract_value(LDBL f, LDBL b, int *exp_ptr); extern LDBL scale_value( LDBL f, LDBL b , int n ); extern LDBL extract_10(LDBL f, int *exp_ptr); extern LDBL scale_10( LDBL f, int n ); extern bf10_t unsafe_bftobf10(bf10_t s, int dec, bf_t n); extern bf10_t mult_a_bf10_int(bf10_t s, int dec, U16 n); extern bf10_t div_a_bf10_int (bf10_t s, int dec, U16 n); extern char *bf10tostr_e(char *s, int dec, bf10_t n); extern char *bf10tostr_f(char *s, int dec, bf10_t n); /* functions defined in bigfltc.c */ extern bf_t norm_bf(bf_t r); extern void norm_sign_bf(bf_t r, int positive); extern S16 adjust_bf_add(bf_t n1, bf_t n2); extern bf_t max_bf(bf_t r); extern int cmp_bf(bf_t n1, bf_t n2); extern int is_bf_neg(bf_t n); extern int is_bf_not_zero(bf_t n); extern bf_t unsafe_add_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t unsafe_add_a_bf(bf_t r, bf_t n); extern bf_t unsafe_sub_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t unsafe_sub_a_bf(bf_t r, bf_t n); extern bf_t neg_bf(bf_t r, bf_t n); extern bf_t neg_a_bf(bf_t r); extern bf_t double_bf(bf_t r, bf_t n); extern bf_t double_a_bf(bf_t r); extern bf_t half_bf(bf_t r, bf_t n); extern bf_t half_a_bf(bf_t r); extern bf_t unsafe_full_mult_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t unsafe_mult_bf(bf_t r, bf_t n1, bf_t n2); extern bf_t unsafe_full_square_bf(bf_t r, bf_t n); extern bf_t unsafe_square_bf(bf_t r, bf_t n); extern bf_t unsafe_mult_bf_int(bf_t r, bf_t n, U16 u); extern bf_t mult_a_bf_int(bf_t r, U16 u); extern bf_t unsafe_div_bf_int(bf_t r, bf_t n, U16 u); extern bf_t div_a_bf_int(bf_t r, U16 u); /****************************/ /* bigcmplx.c */ extern _CMPLX cmplxbntofloat(_BNCMPLX *s); extern _CMPLX cmplxbftofloat(_BFCMPLX *s); extern _BFCMPLX *cmplxlog_bf(_BFCMPLX *t, _BFCMPLX *s); extern _BFCMPLX *cplxmul_bf( _BFCMPLX *t, _BFCMPLX *x, _BFCMPLX *y); extern _BFCMPLX *ComplexPower_bf(_BFCMPLX *t, _BFCMPLX *xx, _BFCMPLX *yy); extern _BNCMPLX *ComplexPower_bn(_BNCMPLX *t, _BNCMPLX *xx, _BNCMPLX *yy); extern _BNCMPLX *cmplxlog_bn(_BNCMPLX *t, _BNCMPLX *s); extern _BNCMPLX *cplxmul_bn( _BNCMPLX *t, _BNCMPLX *x, _BNCMPLX *y); #include "biginit.h" /* fractint only */ #endif /* _BIG_H */ xfractint-20.4.10.orig/headers/helpcom.h0000644000000000000000000005105410150633601014720 0ustar /* * helpcom.h * * * Common #defines, structures and code for HC.C and HELP.C * */ #ifndef HELPCOM_H #define HELPCOM_H /* * help file signature * If you get a syntax error, remove the LU from the end of the number. */ #define HELP_SIG (0xAFBC1823LU) /* * commands imbedded in the help text */ #define CMD_LITERAL 1 /* next char taken literally */ #define CMD_PARA 2 /* paragraph start code */ #define CMD_LINK 3 /* hot-link start/end code */ #define CMD_FF 4 /* force a form-feed */ #define CMD_XONLINE 5 /* exclude from online help on/off */ #define CMD_XDOC 6 /* exclude from printed document on/off */ #define CMD_CENTER 7 /* center this line */ #define CMD_SPACE 8 /* next byte is count of spaces */ #define MAX_CMD 8 /* * on-line help dimensions */ #define SCREEN_WIDTH (78) #define SCREEN_DEPTH (22) #define SCREEN_INDENT (1) /* * printed document dimensions */ #define PAGE_WIDTH (72) /* width of printed text */ #define PAGE_INDENT (2) /* indent all text by this much */ #define TITLE_INDENT (1) /* indent titles by this much */ #define PAGE_RDEPTH (59) /* the total depth (inc. heading) */ #define PAGE_HEADING_DEPTH (3) /* depth of the heading */ #define PAGE_DEPTH (PAGE_RDEPTH-PAGE_HEADING_DEPTH) /* depth of text */ /* * Document page-break macros. Goto to next page if this close (or closer) * to end of page when starting a CONTENT, TOPIC, or at a BLANK line. */ #define CONTENT_BREAK (7) /* start of a "DocContent" entry */ #define TOPIC_BREAK (4) /* start of each topic under a DocContent entry */ #define BLANK_BREAK (2) /* a blank line */ /* * tokens returned by find_token_length */ #define TOK_DONE (0) /* len == 0 */ #define TOK_SPACE (1) /* a run of spaces */ #define TOK_LINK (2) /* an entire link */ #define TOK_PARA (3) /* a CMD_PARA */ #define TOK_NL (4) /* a new-line ('\n') */ #define TOK_FF (5) /* a form-feed (CMD_FF) */ #define TOK_WORD (6) /* a word */ #define TOK_XONLINE (7) /* a CMD_XONLINE */ #define TOK_XDOC (8) /* a CMD_XDOC */ #define TOK_CENTER (9) /* a CMD_CENTER */ /* * modes for find_token_length() and find_line_width() */ #define ONLINE 1 #define DOC 2 /* * struct PD_INFO used by process_document() */ typedef struct { /* used by process_document -- look but don't touch! */ int pnum, lnum; /* PD_GET_TOPIC is allowed to change these */ char far *curr; unsigned len; /* PD_GET_CONTENT is allowed to change these */ char far *id; char far *title; int new_page; /* general parameters */ char far *s; int i; } PD_INFO; /* * Commands passed to (*get_info)() and (*output)() by process_document() */ enum PD_COMMANDS { /* commands sent to pd_output */ PD_HEADING, /* call at the top of each page */ PD_FOOTING, /* called at the end of each page */ PD_PRINT, /* called to send text to the printer */ PD_PRINTN, /* called to print a char n times */ PD_PRINT_SEC, /* called to print the section title line */ PD_START_SECTION, /* called at the start of each section */ PD_START_TOPIC, /* called at the start of each topic */ PD_SET_SECTION_PAGE, /* set the current sections page number */ PD_SET_TOPIC_PAGE, /* set the current topics page number */ PD_PERIODIC, /* called just before curr is incremented to next token */ /* commands sent to pd_get_info */ PD_GET_CONTENT, PD_GET_TOPIC, PD_RELEASE_TOPIC, PD_GET_LINK_PAGE } ; typedef int (*PD_FUNC)(int cmd, PD_INFO *pd, VOIDPTR info); int _find_token_length(char far *curr, unsigned len, int *size, int *width); int find_token_length(int mode, char far *curr, unsigned len, int *size, int *width); int find_line_width(int mode, char far *curr, unsigned len); int process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info); /* * Code common to both HC.C and HELP.C (in Fractint). * #include INCLUDE_COMMON once for each program */ #endif #ifdef INCLUDE_COMMON #ifndef XFRACT #define getint(ptr) (*(int far *)(ptr)) #define setint(ptr,n) (*(int far *)(ptr)) = n #else /* Get an int from an unaligned pointer * This routine is needed because this program uses unaligned 2 byte * pointers all over the place. */ int getint(ptr) char *ptr; { int s; bcopy(ptr,&s,sizeof(int)); return s; } /* Set an int to an unaligned pointer */ void setint(ptr, n) int n; char *ptr; { bcopy(&n,ptr,sizeof(int)); } #endif static int is_hyphen(char far *ptr) /* true if ptr points to a real hyphen */ { /* checkes for "--" and " -" */ if ( *ptr != '-' ) return (0); /* that was easy! */ --ptr; return ( *ptr!=' ' && *ptr!='-' ); } int _find_token_length(register char far *curr, unsigned len, int *size, int *width) { register int _size = 0; register int _width = 0; int tok; if (len == 0) tok = TOK_DONE; else { switch ( *curr ) { case ' ': /* it's a run of spaces */ tok = TOK_SPACE; while ( *curr == ' ' && _size < (int)len ) { ++curr; ++_size; ++_width; } break; case CMD_SPACE: tok = TOK_SPACE; ++curr; ++_size; _width = *curr; ++curr; ++_size; break; case CMD_LINK: tok = TOK_LINK; _size += 1+3*sizeof(int); /* skip CMD_LINK + topic_num + topic_off + page_num */ curr += 1+3*sizeof(int); while ( *curr != CMD_LINK ) { if ( *curr == CMD_LITERAL ) { ++curr; ++_size; } ++curr; ++_size; ++_width; assert(_size < len); } ++_size; /* skip ending CMD_LINK */ break; case CMD_PARA: tok = TOK_PARA; _size += 3; /* skip CMD_PARA + indent + margin */ break; case CMD_XONLINE: tok = TOK_XONLINE; ++_size; break; case CMD_XDOC: tok = TOK_XDOC; ++_size; break; case CMD_CENTER: tok = TOK_CENTER; ++_size; break; case '\n': tok = TOK_NL; ++_size; break; case CMD_FF: tok = TOK_FF; ++_size; break; default: /* it must be a word */ tok = TOK_WORD; for(;;) { if ( _size >= (int)len ) break; else if ( *curr == CMD_LITERAL ) { curr += 2; _size += 2; _width += 1; } else if ( *curr == '\0' ) { assert(0); } else if ((unsigned)*curr <= MAX_CMD || *curr == ' ' || *curr == '\n') break; else if ( *curr == '-' ) { ++curr; ++_size; ++_width; if ( is_hyphen(curr-1) ) break; } else { ++curr; ++_size; ++_width; } } break; } /* switch */ } if (size != NULL) *size = _size; if (width != NULL) *width = _width; return (tok); } int find_token_length(int mode, char far *curr, unsigned len, int *size, int *width) { int tok; int t; int _size; tok = _find_token_length(curr, len, &t, width); if ( (tok == TOK_XONLINE && mode == ONLINE) || (tok == TOK_XDOC && mode == DOC) ) { _size = 0; for(;;) { curr += t; len -= t; _size += t; tok = _find_token_length(curr, len, &t, NULL); if ( (tok == TOK_XONLINE && mode == ONLINE) || (tok == TOK_XDOC && mode == DOC) || (tok == TOK_DONE) ) break; } _size += t; } else _size = t; if (size != NULL ) *size = _size; return (tok); } int find_line_width(int mode, char far *curr, unsigned len) { int size = 0, width = 0, lwidth = 0, done = 0, tok; do { tok = find_token_length(mode, curr, len, &size, &width); switch(tok) { case TOK_DONE: case TOK_PARA: case TOK_NL: case TOK_FF: done = 1; break; case TOK_XONLINE: case TOK_XDOC: case TOK_CENTER: curr += size; len -= size; break; default: /* TOK_SPACE, TOK_LINK or TOK_WORD */ lwidth += width; curr += size; len -= size; break; } } while ( !done ); return (lwidth); } #define DO_PRINTN(ch,n) ( pd.s = &(ch), pd.i = (n), output(PD_PRINTN, &pd, info) ) #define DO_PRINT(str,n) ( pd.s = (str), pd.i = (n), output(PD_PRINT, &pd, info) ) int process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info) { int skip_blanks; int tok; int size, width; int col; char page_text[10]; PD_INFO pd; char nl = '\n', sp = ' '; int first_section, first_topic; pd.pnum = 1; pd.lnum = 0; col = 0; output(PD_HEADING, &pd, info); first_section = 1; while ( get_info(PD_GET_CONTENT, &pd, info) ) { if ( !output(PD_START_SECTION, &pd, info) ) return (0); if ( pd.new_page && pd.lnum != 0 ) { if ( !output(PD_FOOTING, &pd, info) ) return (0); ++pd.pnum; pd.lnum = 0; if ( !output(PD_HEADING, &pd, info) ) return (0); } else { if ( pd.lnum+2 > PAGE_DEPTH-CONTENT_BREAK ) { if ( !output(PD_FOOTING, &pd, info) ) return (0); ++pd.pnum; pd.lnum = 0; if ( !output(PD_HEADING, &pd, info) ) return (0); } else if (pd.lnum > 0) { if ( !DO_PRINTN(nl, 2) ) return (0); pd.lnum += 2; } } if ( !output(PD_SET_SECTION_PAGE, &pd, info) ) return (0); if ( !first_section ) { if ( !output(PD_PRINT_SEC, &pd, info) ) return (0); ++pd.lnum; } col = 0; first_topic = 1; while ( get_info(PD_GET_TOPIC, &pd, info) ) { if ( !output(PD_START_TOPIC, &pd, info) ) return (0); skip_blanks = 0; col = 0; if ( !first_section ) /* do not skip blanks for DocContents */ { while (pd.len > 0) { tok = find_token_length(DOC, pd.curr, pd.len, &size, NULL); if (tok != TOK_XDOC && tok != TOK_XONLINE && tok != TOK_NL && tok != TOK_DONE ) break; pd.curr += size; pd.len -= size; } if ( first_topic && pd.len != 0 ) { if ( !DO_PRINTN(nl, 1) ) return (0); ++pd.lnum; } } if ( pd.lnum > PAGE_DEPTH-TOPIC_BREAK ) { if ( !output(PD_FOOTING, &pd, info) ) return (0); ++pd.pnum; pd.lnum = 0; if ( !output(PD_HEADING, &pd, info) ) return (0); } else if ( !first_topic ) { if ( !DO_PRINTN(nl, 1) ) return (0); pd.lnum++; } if ( !output(PD_SET_TOPIC_PAGE, &pd, info) ) return (0); do { if ( !output(PD_PERIODIC, &pd, info) ) return (0); tok = find_token_length(DOC, pd.curr, pd.len, &size, &width); switch ( tok ) { case TOK_PARA: { int indent, margin; unsigned holdlen = 0; char far *holdcurr = 0; int in_link = 0; ++pd.curr; indent = *pd.curr++; margin = *pd.curr++; pd.len -= 3; if ( !DO_PRINTN(sp, indent) ) return (0); col = indent; for(;;) { if ( !output(PD_PERIODIC, &pd, info) ) return (0); tok = find_token_length(DOC, pd.curr, pd.len, &size, &width); if ( tok == TOK_NL || tok == TOK_FF ) break; if ( tok == TOK_DONE ) { if (in_link == 0) { col = 0; ++pd.lnum; if ( !DO_PRINTN(nl, 1) ) return (0); break; } else if (in_link == 1) { tok = TOK_SPACE; width = 1; size = 0; ++in_link; } else if (in_link == 2) { tok = TOK_WORD; width = strlen(page_text); col += 8 - width; size = 0; pd.curr = page_text; ++in_link; } else if (in_link == 3) { pd.curr = holdcurr; pd.len = holdlen; in_link = 0; continue; } } if ( tok == TOK_PARA ) { col = 0; /* fake a nl */ ++pd.lnum; if ( !DO_PRINTN(nl, 1) ) return (0); break; } if (tok == TOK_XONLINE || tok == TOK_XDOC ) { pd.curr += size; pd.len -= size; continue; } if ( tok == TOK_LINK ) { pd.s = pd.curr+1; if ( get_info(PD_GET_LINK_PAGE, &pd, info) ) { in_link = 1; sprintf(page_text, "(p. %d)", pd.i); } else in_link = 3; holdcurr = pd.curr + size; holdlen = pd.len - size; pd.len = size - 2 - 3*sizeof(int); pd.curr += 1 + 3*sizeof(int); continue; } /* now tok is TOK_SPACE or TOK_WORD */ if (col+width > PAGE_WIDTH) { /* go to next line... */ if ( !DO_PRINTN(nl, 1) ) return (0); if ( ++pd.lnum >= PAGE_DEPTH ) { if ( !output(PD_FOOTING, &pd, info) ) return (0); ++pd.pnum; pd.lnum = 0; if ( !output(PD_HEADING, &pd, info) ) return (0); } if ( tok == TOK_SPACE ) width = 0; /* skip spaces at start of a line */ if ( !DO_PRINTN(sp, margin) ) return (0); col = margin; } if (width > 0) { if (tok == TOK_SPACE) { if ( !DO_PRINTN(sp, width) ) return (0); } else { if ( !DO_PRINT(pd.curr, (size==0) ? width : size) ) return (0); } } col += width; pd.curr += size; pd.len -= size; } skip_blanks = 0; width = size = 0; break; } case TOK_NL: if (skip_blanks && col == 0) break; ++pd.lnum; if ( pd.lnum >= PAGE_DEPTH || (col == 0 && pd.lnum >= PAGE_DEPTH-BLANK_BREAK) ) { if ( col != 0 ) /* if last wasn't a blank line... */ { if ( !DO_PRINTN(nl, 1) ) return (0); } if ( !output(PD_FOOTING, &pd, info) ) return (0); ++pd.pnum; pd.lnum = 0; skip_blanks = 1; if ( !output(PD_HEADING, &pd, info) ) return (0); } else { if ( !DO_PRINTN(nl, 1) ) return (0); } col = 0; break; case TOK_FF: if (skip_blanks) break; if ( !output(PD_FOOTING, &pd, info) ) return (0); col = 0; pd.lnum = 0; ++pd.pnum; if ( !output(PD_HEADING, &pd, info) ) return (0); break; case TOK_CENTER: width = (PAGE_WIDTH - find_line_width(DOC,pd.curr,pd.len)) / 2; if ( !DO_PRINTN(sp, width) ) return (0); break; case TOK_LINK: skip_blanks = 0; if ( !DO_PRINT(pd.curr+1+3*sizeof(int), size-3*sizeof(int)-2) ) return (0); pd.s = pd.curr+1; if ( get_info(PD_GET_LINK_PAGE, &pd, info) ) { width += 9; sprintf(page_text, " (p. %d)", pd.i); if ( !DO_PRINT(page_text, strlen(page_text)) ) return (0); } break; case TOK_WORD: skip_blanks = 0; if ( !DO_PRINT(pd.curr, size) ) return (0); break; case TOK_SPACE: skip_blanks = 0; if ( !DO_PRINTN(sp, width) ) return (0); break; case TOK_DONE: case TOK_XONLINE: /* skip */ case TOK_XDOC: /* ignore */ break; } /* switch */ pd.curr += size; pd.len -= size; col += width; } while (pd.len > 0); get_info(PD_RELEASE_TOPIC, &pd, info); first_topic = 0; } /* while */ first_section = 0; } /* while */ if ( !output(PD_FOOTING, &pd, info) ) return (0); return (1); } #undef DO_PRINT #undef DO_PRINTN #undef INCLUDE_COMMON #endif /* #ifdef INCLUDE_COMMON */ xfractint-20.4.10.orig/headers/fractype.h0000644000000000000000000001666011045730226015117 0ustar #ifndef FRACTYPE_H #define FRACTYPE_H #define SIN 0 #define COS 1 /* Beware this is really COSXX */ #define SINH 2 #define COSH 3 #define EXP 4 #define LOG 5 #define SQR 6 #define TAN 10 /* These MUST match the corresponding fractalspecific record in fractals.c */ #define NOFRACTAL -1 #define MANDEL 0 #define JULIA 1 #define NEWTBASIN 2 #define LAMBDA 3 #define MANDELFP 4 #define NEWTON 5 #define JULIAFP 6 #define PLASMA 7 #define LAMBDASINE 8 /* obsolete */ #define MANDELTRIGFP 8 #define LAMBDACOS 9 /* obsolete */ #define MANOWARFP 9 #define LAMBDAEXP 10 /* obsolete */ #define MANOWAR 10 #define TEST 11 #define SIERPINSKI 12 #define BARNSLEYM1 13 #define BARNSLEYJ1 14 #define BARNSLEYM2 15 #define BARNSLEYJ2 16 #define MANDELSINE 17 /* obsolete */ #define SQRTRIG 17 #define MANDELCOS 18 /* obsolete */ #define SQRTRIGFP 18 #define MANDELEXP 19 /* obsolete */ #define TRIGPLUSTRIG 19 #define MANDELLAMBDA 20 #define MARKSMANDEL 21 #define MARKSJULIA 22 #define UNITY 23 #define MANDEL4 24 #define JULIA4 25 #define IFS 26 #define IFS3D 27 #define BARNSLEYM3 28 #define BARNSLEYJ3 29 #define DEMM 30 /* obsolete */ #define TRIGSQR 30 #define DEMJ 31 /* obsolete */ #define TRIGSQRFP 31 #define BIFURCATION 32 #define MANDELSINH 33 /* obsolete */ #define TRIGPLUSTRIGFP 33 #define LAMBDASINH 34 /* obsolete */ #define TRIGXTRIG 34 #define MANDELCOSH 35 /* obsolete */ #define TRIGXTRIGFP 35 #define LAMBDACOSH 36 /* obsolete */ #define SQR1OVERTRIG 36 #define LMANDELSINE 37 /* obsolete */ #define SQR1OVERTRIGFP 37 #define LLAMBDASINE 38 /* obsolete */ #define ZXTRIGPLUSZ 38 #define LMANDELCOS 39 /* obsolete */ #define ZXTRIGPLUSZFP 39 #define LLAMBDACOS 40 /* obsolete */ #define KAMFP 40 #define LMANDELSINH 41 /* obsolete */ #define KAM 41 #define LLAMBDASINH 42 /* obsolete */ #define KAM3DFP 42 #define LMANDELCOSH 43 /* obsolete */ #define KAM3D 43 #define LLAMBDACOSH 44 /* obsolete */ #define LAMBDATRIG 44 #define LMANTRIGPLUSZSQRD 45 #define LJULTRIGPLUSZSQRD 46 #define FPMANTRIGPLUSZSQRD 47 #define FPJULTRIGPLUSZSQRD 48 #define LMANDELEXP 49 /* obsolete */ #define LAMBDATRIGFP 49 #define LLAMBDAEXP 50 /* obsolete */ #define MANDELTRIG 50 #define LMANDELZPOWER 51 #define LJULIAZPOWER 52 #define FPMANDELZPOWER 53 #define FPJULIAZPOWER 54 #define FPMANZTOZPLUSZPWR 55 #define FPJULZTOZPLUSZPWR 56 #define LMANTRIGPLUSEXP 57 #define LJULTRIGPLUSEXP 58 #define FPMANTRIGPLUSEXP 59 #define FPJULTRIGPLUSEXP 60 #define FPPOPCORN 61 #define LPOPCORN 62 #define FPLORENZ 63 #define LLORENZ 64 #define LLORENZ3D 65 #define MPNEWTON 66 #define MPNEWTBASIN 67 #define COMPLEXNEWTON 68 #define COMPLEXBASIN 69 #define COMPLEXMARKSMAND 70 #define COMPLEXMARKSJUL 71 #define FORMULA 72 #define FFORMULA 73 #define SIERPINSKIFP 74 #define LAMBDAFP 75 #define BARNSLEYM1FP 76 #define BARNSLEYJ1FP 77 #define BARNSLEYM2FP 78 #define BARNSLEYJ2FP 79 #define BARNSLEYM3FP 80 #define BARNSLEYJ3FP 81 #define MANDELLAMBDAFP 82 #define JULIBROT 83 #define FPLORENZ3D 84 #define LROSSLER 85 #define FPROSSLER 86 #define LHENON 87 #define FPHENON 88 #define FPPICKOVER 89 #define FPGINGERBREAD 90 #define DIFFUSION 91 #define UNITYFP 92 #define SPIDERFP 93 #define SPIDER 94 #define TETRATEFP 95 #define MAGNET1M 96 #define MAGNET1J 97 #define MAGNET2M 98 #define MAGNET2J 99 #define LBIFURCATION 100 #define LBIFLAMBDA 101 #define BIFLAMBDA 102 #define BIFADSINPI 103 #define BIFEQSINPI 104 #define FPPOPCORNJUL 105 #define LPOPCORNJUL 106 #define LSYSTEM 107 #define MANOWARJFP 108 #define MANOWARJ 109 #define FNPLUSFNPIXFP 110 #define FNPLUSFNPIXLONG 111 #define MARKSMANDELPWRFP 112 #define MARKSMANDELPWR 113 #define TIMSERRORFP 114 #define TIMSERROR 115 #define LBIFEQSINPI 116 #define LBIFADSINPI 117 #define BIFSTEWART 118 #define LBIFSTEWART 119 #define FPHOPALONG 120 #define FPCIRCLE 121 #define FPMARTIN 122 #define LYAPUNOV 123 #define FPLORENZ3D1 124 #define FPLORENZ3D3 125 #define FPLORENZ3D4 126 #define LLAMBDAFNFN 127 #define FPLAMBDAFNFN 128 #define LJULFNFN 129 #define FPJULFNFN 130 #define LMANLAMFNFN 131 #define FPMANLAMFNFN 132 #define LMANFNFN 133 #define FPMANFNFN 134 #define LBIFMAY 135 #define BIFMAY 136 #define MPHALLEY 137 #define HALLEY 138 #define DYNAMICFP 139 #define QUATFP 140 #define QUATJULFP 141 #define CELLULAR 142 #define JULIBROTFP 143 #define INVERSEJULIA 144 #define INVERSEJULIAFP 145 #define MANDELCLOUD 146 #define PHOENIX 147 #define PHOENIXFP 148 #define MANDPHOENIX 149 #define MANDPHOENIXFP 150 #define HYPERCMPLXFP 151 #define HYPERCMPLXJFP 152 #define FROTH 153 #define FROTHFP 154 #define MANDEL4FP 155 #define JULIA4FP 156 #define MARKSMANDELFP 157 #define MARKSJULIAFP 158 #define ICON 159 #define ICON3D 160 #define PHOENIXCPLX 161 #define PHOENIXFPCPLX 162 #define MANDPHOENIXCPLX 163 #define MANDPHOENIXFPCPLX 164 #define ANT 165 #define CHIP 166 #define QUADRUPTWO 167 #define THREEPLY 168 #define VL 169 #define ESCHER 170 #define LATOO 171 /* #define MANDELBROTMIX4 172 */ #define DIVIDEBROT5 172 #endif xfractint-20.4.10.orig/headers/biginit.h0000644000000000000000000000430510150633601014713 0ustar /* biginit.h */ /* Used for fractint only. */ /* Many of these are redundant from big.h */ /* but the fractint specific ones are not. */ #ifndef BIGINIT_H #define BIGINIT_H #define MATHBITS 32 #define MATHBYTES (MATHBITS/8) #define NUMVARS 30 /* room for this many on stack */ #define CURRENTREZ 1 #define MAXREZ 0 /* globals */ extern int bnstep, bnlength, intlength, rlength, padding, shiftfactor; extern int decimals, bflength, rbflength, bfshiftfactor, bfdecimals; /* used internally by bignum.c routines */ extern bn_t bntmp1, bntmp2, bntmp3, bntmp4, bntmp5, bntmp6; /* rlength */ extern bn_t bntmpcpy1, bntmpcpy2; /* bnlength */ /* used by other routines */ extern bn_t bnxmin, bnxmax, bnymin, bnymax, bnx3rd, bny3rd; /* bnlength */ extern bn_t bnxdel, bnydel, bnxdel2, bnydel2, bnclosenuff; /* bnlength */ extern bn_t bntmpsqrx, bntmpsqry, bntmp; /* rlength */ extern _BNCMPLX bnold, /* bnnew, */ bnparm, bnsaved; /* bnlength */ extern _BNCMPLX bnnew; /* rlength */ extern bn_t bn_pi; /* TAKES NO SPACE */ extern bf_t bftmp1, bftmp2, bftmp3, bftmp4, bftmp5, bftmp6; /* rbflength+2 */ extern bf_t bftmpcpy1, bftmpcpy2; /* rbflength+2 */ extern bf_t bfxdel, bfydel, bfxdel2, bfydel2, bfclosenuff; /* rbflength+2 */ extern bf_t bftmpsqrx, bftmpsqry; /* rbflength+2 */ extern _BFCMPLX /* bfold, bfnew, */ bfparm, bfsaved; /* bflength+2 */ extern _BFCMPLX bfold, bfnew; /* rbflength+2 */ extern bf_t bf_pi; /* TAKES NO SPACE */ extern bf_t big_pi; /* bflength+2 */ /* for testing only */ /* used by other routines */ extern bf_t bfxmin, bfxmax, bfymin, bfymax, bfx3rd, bfy3rd; /* bflength+2 */ extern bf_t bfsxmin, bfsxmax, bfsymin,bfsymax,bfsx3rd,bfsy3rd;/* bflength+2 */ extern bf_t bfparms[10]; /* (bflength+2)*10 */ extern bf_t bftmp; extern bf_t bf10tmp; /* dec+4 */ #endif xfractint-20.4.10.orig/headers/externs.h0000644000000000000000000010655511253454200014771 0ustar #ifndef EXTERNS_H #define EXTERNS_H #if 0 /* #ifndef DEBUG */ #define DEBUG 1 #endif /* keep var names in column 30 for sorting via sort /+30 out */ extern int active_system; extern int adapter; extern ALTERNATE far alternatemath[]; extern int Ambient; extern int andcolor; extern struct MP Ans; extern int Ap1deg; extern int AplusOne; extern int askvideo; extern float aspectdrift; extern int attractors; extern int attrperiod[]; extern _CMPLX attr[]; extern int autobrowse; extern char autoname[]; extern char autoshowdot; extern int AutoStereo_depth; extern double AutoStereo_width; extern BYTE back_color[]; extern int badconfig; extern int bad_code_count; extern int bad_outside; extern int bad_value; extern long bailout; extern enum bailouts bailoutest; extern int basehertz; extern int basin; extern int bf_save_len; extern int bfdigits; extern int biomorph; extern unsigned int bits; extern int bitshift; extern int bitshiftless1; extern BYTE block[]; extern int blue_bright; extern int blue_crop_left; extern int blue_crop_right; extern int boxcolor; extern int boxcount; extern int boxvalues[]; extern int boxx[]; extern int boxy[]; extern int BRIEF; extern char browsemask[MAX_NAME]; extern char browsename[]; extern int browsing; extern char brwscheckparms; extern char brwschecktype; extern char busy; extern long calctime; extern int (* calctype)(void); extern int calc_status; extern char calibrate; extern int checkcurdir; extern int chkd_vvs; extern long cimag; extern double closenuff; extern double closeprox; extern _CMPLX coefficient; extern int col; extern int color; extern char colorfile[]; extern long coloriter; extern int colorpreloaded; extern int ColorPS; extern int colors; extern int colorstate; extern int color_bright; extern int color_dark; extern int color_medium; extern char CommandComment[4][MAXCMT]; extern char CommandFile[FILE_MAX_PATH]; extern char CommandName[ITEMNAMELEN + 1]; extern int comparegif; extern long con; extern double cosx; extern int cpu; extern long creal; extern int curcol; extern int curpass; extern int currow; extern int cyclelimit; extern int c_exp; extern double d1overd; extern BYTE dacbox[256][3]; extern int daccount; extern int daclearn; extern double ddelmin; extern int debugflag; extern int decimals; extern BYTE decoderline[]; extern int decomp[]; extern int degree; extern long delmin; extern long delx2; extern long delx; extern LDBL delxx2; extern LDBL delxx; extern long dely2; extern long dely; extern LDBL delyy2; extern LDBL delyy; extern float depthfp; extern unsigned long dif_counter; extern unsigned long dif_limit; extern int disk16bit; extern int diskflag; extern int diskisactive; extern int disktarga; extern int diskvideo; extern int display3d; extern long distest; extern int distestwidth; extern float distfp; extern int Distribution; extern int dither_flag; extern char dontreadcolor; extern int dotmode; extern int doublecaution; extern double dpx; extern double dpy; extern char drawmode; extern BYTE dstack[]; extern U16 dv_handle; extern double far * dx0; extern double far * dx1; extern double (_fastcall * dxpixel)(void); /* set in FRACTALS.C */ extern double dxsize; extern double far * dy0; extern double far * dy1; extern double (_fastcall * dypixel)(void); /* set in FRACTALS.C */ extern double dysize; extern int EPSFileType; extern int escape_exit; extern BYTE exitmode; extern SEGTYPE extraseg; extern int evolving; extern U16 evolve_handle; extern int eyeseparation; extern float eyesfp; extern int fastrestore; extern long FgHalf; extern double fgLimit; extern long FgOne; extern long FgTwo; extern int gridsz; extern double fiddlefactor; extern double fiddle_reduction; extern float fileaspectratio; extern int filecolors; extern int filetype; extern int filexdots; extern int fileydots; extern char file_name_stack[16][MAX_NAME]; extern int fillcolor; extern float finalaspectratio; extern int finattract; extern int finishrow; extern int first_init; extern char floatflag; extern double floatmax; extern double floatmin; extern _CMPLX * floatparm; extern int fm_attack; extern int fm_decay; extern int fm_release; extern int fm_sustain; extern int fm_wavetype; extern int fm_vol; /*volume of OPL-3 soundcard output*/ extern int forcesymmetry; extern char FormFileName[]; extern char FormName[]; extern int fpu; extern int fractype; extern char * fract_dir1; extern char * fract_dir2; extern char fromtext_flag; extern long fudge; extern int functionpreloaded; extern double f_at_rad; extern double f_radius; extern double f_xcenter; extern double f_ycenter; extern U16 gene_handle; extern int get_corners(void); extern int gif87a_flag; extern char gifmask[]; extern char Glasses1Map[]; extern int glassestype; extern int goodmode; extern int gotrealdac; extern int got_status; extern char grayflag; extern char GreyFile[]; extern int hasinverse; extern int haze; extern unsigned int height; extern float heightfp; extern int helpmode; extern int hi_atten; extern U16 history; extern int historyflag; extern int historyptr; extern char IFSFileName[]; extern char IFSName[]; extern float far * ifs_defn; extern int ifs_type; extern int imgboxcount; extern U16 imgboxhandle; extern char image_map; extern int init3d[20]; extern _CMPLX init; extern int initbatch; extern int initcyclelimit; extern int initmode; extern _CMPLX initorbit; extern int initsavetime; extern int inside; extern FCODE insufficient_ifs_mem[]; extern int integerfractal; extern double inversion[]; extern int invert; extern int istruecolor; extern short ismand; extern int ixstart; extern int ixstop; extern int iystart; extern int iystop; extern char * JIIMleftright[]; extern char * JIIMmethod[]; extern int juli3Dmode; extern char * juli3Doptions[]; extern int julibrot; extern int kbdcount; extern int keep_scrn_coords; extern int keybuffer; extern long l16triglim; extern int LastInitOp; extern unsigned LastOp; extern int lastorbittype; extern _LCMPLX lattr[]; extern long lclosenuff; extern _LCMPLX lcoefficient; extern int ldcheck; extern char LFileName[]; extern char light_name[]; extern BYTE * line_buff; extern _LCMPLX linit; extern _LCMPLX linitorbit; extern long linitx; extern long linity; extern long llimit2; extern long llimit; extern long lmagnitud; extern char LName[]; extern _LCMPLX lnew; extern int loaded3d; extern int LodPtr; extern int Log_Auto_Calc; extern int Log_Calc; extern int Log_Fly_Calc; extern long LogFlag; extern BYTE far * LogTable; extern _LCMPLX lold; extern _LCMPLX * longparm; extern int lookatmouse; extern _LCMPLX lparm2; extern _LCMPLX lparm; extern int LPTNumber; extern long ltempsqrx; extern long ltempsqry; extern _LCMPLX ltmp; extern long far * lx0; extern long far * lx1; extern long (_fastcall * lxpixel)(void); /* set in FRACTALS.C */ extern long far * ly0; extern long far * ly1; extern long (_fastcall * lypixel)(void); /* set in FRACTALS.C */ extern int lzw[2]; extern long l_at_rad; extern MATRIX m; extern double magnitude; extern enum Major major_method; extern BYTE far * mapdacbox; extern int mapset; extern char MAP_name[]; extern int matherr_ct; extern double math_tol[2]; extern int maxcolor; extern long maxct; extern char maxfn; extern long maxit; extern int maxlinelength; extern long MaxLTSize; extern unsigned Max_Args; extern unsigned Max_Ops; extern long maxptr; extern int max_colors; extern int max_kbdcount; extern int maxhistory; extern int max_rhombus_depth; extern int minbox; extern enum Minor minor_method; extern int minstack; extern int minstackavail; extern int mode7text; extern MOREPARAMS moreparams[]; extern struct MP mpAp1deg; extern struct MP mpAplusOne; extern struct MPC MPCone; extern struct MPC * MPCroots; extern struct MPC mpctmpparm; extern struct MP mpd1overd; extern struct MP mpone; extern int MPOverflow; extern struct MP mproverd; extern struct MP mpt2; extern struct MP mpthreshold; extern struct MP mptmpparm2x; extern double mxmaxfp; extern double mxminfp; extern double mymaxfp; extern double myminfp; extern int name_stack_ptr; extern _CMPLX new; extern char newodpx; extern char newodpy; extern double newopx; extern double newopy; extern int neworbittype; extern int nextsavedincr; extern int no_sub_images; extern int no_mag_calc; extern int nobof; extern int numaffine; extern unsigned numcolors; extern const int numtrigfn; extern int num_fractal_types; extern int num_worklist; extern int nxtscreenflag; extern int Offset; extern int oktoprint; extern _CMPLX old; extern long oldcoloriter; extern BYTE olddacbox[256][3]; extern U16 oldhistory_handle; extern int old_demm_colors; extern char old_stdcalcmode; extern char odpx; extern char odpy; extern double opx; extern double opy; extern int orbitsave; extern int orbit_color; extern int orbit_delay; extern long orbit_interval; extern int orbit_ptr; extern char orgfrmdir[]; extern int orgfrmsearch; extern float originfp; extern int (* outln) (BYTE *, int); extern void (* outln_cleanup) (void); extern int outside; extern int overflow; extern int overlay3d; extern char overwrite; extern double ox3rd; extern double oxmax; extern double oxmin; extern double oy3rd; extern double oymax; extern double oymin; extern double param[]; extern double paramrangex; extern double paramrangey; extern double parmzoom; extern _CMPLX parm2; extern _CMPLX parm; extern int passes; extern int patchlevel; extern int periodicitycheck; extern struct fls far * pfls; extern int pixelpi; extern void (_fastcall * plot)(int,int,int); extern double plotmx1; extern double plotmx2; extern double plotmy1; extern double plotmy2; extern int polyphony; extern unsigned posp; extern int pot16bit; extern int potflag; extern double potparam[]; #ifndef XFRACT extern U16 prefix[]; #endif extern char preview; extern int previewfactor; extern int px; extern int py; extern int Printer_BAngle; extern int Printer_BFrequency; extern int Printer_BStyle; extern int Printer_ColorXlat; extern int Printer_Compress; extern int Printer_CRLF; extern int Printer_GAngle; extern int Printer_GFrequency; extern int Printer_GStyle; extern int Printer_RAngle; extern int Printer_Resolution; extern int Printer_RFrequency; extern int Printer_RStyle; extern int Printer_SAngle; extern int Printer_SetScreen; extern int Printer_SFrequency; extern int Printer_SStyle; extern int Printer_Titleblock; extern int Printer_Type; extern char PrintName[]; extern int Print_To_File; extern U16 prmboxhandle; extern int prmboxcount; extern int pseudox; extern int pseudoy; extern void (_fastcall * putcolor)(int,int,int); extern _CMPLX pwr; extern double qc; extern double qci; extern double qcj; extern double qck; extern int quick_calc; extern int RANDOMIZE; extern int far * ranges; extern int rangeslen; extern int RAY; extern char ray_name[]; extern char readname[]; extern long realcoloriter; extern int reallyega; extern char recordcolors; extern int red_bright; extern int red_crop_left; extern int red_crop_right; extern int release; extern int resave_flag; extern int reset_periodicity; extern U16 resume_info; extern int resume_len; extern int resuming; extern int rflag; extern char rlebuf[]; extern int rhombus_stack[]; extern int root; extern _CMPLX * roots; extern int rotate_hi; extern int rotate_lo; extern double roverd; extern int row; extern int rowcount; extern double rqlim2; extern double rqlim; extern int rseed; extern long savebase; extern _CMPLX SaveC; extern int savedac; extern char savename[]; extern long saveticks; extern int far * save_orbit; extern int save_release; extern int save_system; extern int scale_map[]; extern float screenaspect; extern char scrnfile[]; extern struct SearchPath searchfor; extern int set_orbit_corners; extern char showbox; extern int showdot; extern int showfile; extern int show_orbit; extern double sinx; extern int sizedot; extern short far sizeofstring[]; extern short skipxdots; extern short skipydots; extern int slides; extern int Slope; extern int soundflag; extern int sound_rollover; extern char speed_prompt[]; extern void (_fastcall* standardplot)(int,int,int); extern char start_showorbit; extern int started_resaves; extern _CMPLX staticroots[]; extern char stdcalcmode; extern char stereomapname[]; extern int StoPtr; extern int stoppass; extern unsigned int strlocn[]; extern BYTE suffix[]; extern char supervga_list; extern int svga_type; extern double sx3rd; extern int sxdots; extern double sxmax; extern double sxmin; extern int sxoffs; extern double sy3rd; extern int sydots; extern double symax; extern double symin; extern int symmetry; extern int syoffs; extern char s_16bit[]; extern char s_387[]; extern char s_3dmode[]; extern char s_3d[]; extern char s_abs[]; extern char s_adapter[]; extern char s_afi[]; extern char s_ambient[]; extern char s_and[]; extern char s_askvideo[]; extern char s_acos[]; extern char s_acosh[]; extern char s_asin[]; extern char s_asinh[]; extern char s_atan[]; extern char s_atanh[]; extern char s_attack[]; extern char s_atten[]; extern char s_autokeyname[]; extern char s_autokey[]; extern char s_background[]; extern char s_bailoutest[]; extern char s_bailout[]; extern char s_batch[]; extern char s_beep[]; extern char s_biomorph[]; extern char s_biospalette[]; extern char s_bof60[]; extern char s_bof61[]; extern char s_brief[]; extern char s_bright[]; extern char s_cabs[]; extern char s_cantcreate[]; extern char s_cantfind[]; extern char s_cantunderstand[]; extern char s_cantwrite[]; extern char s_ceil[]; extern char s_centermag[]; extern char s_cga[]; extern char s_coarse[]; extern char s_colorps[]; extern char s_colors[]; extern char s_comport[]; extern char s_conj[]; extern char s_converge[]; extern char s_corners[]; extern char s_cosh[]; extern char s_cosxx[]; extern char s_cos[]; extern char s_cotanh[]; extern char s_cotan[]; extern char s_crlf[]; extern char s_crop[]; extern char s_cr[]; extern char s_cyclelimit[]; extern char s_cyclerange[]; extern char s_debugflag[]; extern char s_debug[]; extern char s_decay[]; extern char s_decomp[]; extern char s_distest[]; extern char s_dither[]; extern char s_egamono[]; extern char s_ega[]; extern char s_epscross[]; extern char s_epsf[]; extern char s_exitmode[]; extern char s_exitnoask[]; extern char s_exp[]; extern char s_filename[]; extern char s_fillcolor[]; extern char s_filltype[]; extern char s_finattract[]; extern char s_flip[]; extern char s_float[]; extern char s_floor[]; extern char s_fmod[]; extern char s_fn1[]; extern char s_fn2[]; extern char s_fn3[]; extern char s_fn4[]; extern char s_formulafile[]; extern char s_formulaname[]; extern char s_fpu[]; extern char s_fract001prn[]; extern char s_fullcolor[]; extern char s_function[]; extern char s_gif87a[]; extern char s_halftone[]; extern char s_haze[]; extern char s_hertz[]; extern char s_hgc[]; extern char s_high[]; extern char s_ident[]; extern char s_ifs3d[]; extern char s_ifsfile[]; extern char s_ifs[]; extern char s_imag[]; extern char s_initorbit[]; extern char s_inside[]; extern char s_interocular[]; extern char s_invert[]; extern char s_ismand[]; extern char s_iterincr[]; extern char s_iter[]; extern char s_julibrot3d[]; extern char s_julibroteyes[]; extern char s_julibrotfromto[]; extern char s_latitude[]; extern char s_lfile[]; extern char s_lf[]; extern char s_lightname[]; extern char s_lightsource[]; extern char s_linefeed[]; extern char s_lname[]; extern char s_logmap[]; extern char s_logmode[]; extern char s_log[]; extern char s_longitude[]; extern char s_low[]; extern char s_makedoc[]; extern char s_makemig[]; extern char s_makepar[]; extern char s_manh[]; extern char s_manr[]; extern char s_map[]; extern char s_mathtolerance[]; extern char s_maxcolorres[]; extern char s_maxiter[]; extern char s_mcga[]; extern char s_mid[]; extern char s_miim[]; extern char s_mod[]; extern char s_mono[]; extern char s_mult[]; extern char s_nobof[]; extern char s_none[]; extern char s_noninterlaced[]; extern char s_normal[]; extern char s_no[]; extern char s_numframes[]; extern char s_off[]; extern char s_olddemmcolors[]; extern char s_one[]; extern char s_orbitcorners[]; extern char s_orbitdelay[]; extern char s_orbitdrawmode[]; extern char s_orbitinterval[]; extern char s_orbitname[]; extern char s_orbitsave[]; extern char s_orgfrmdir[]; extern char s_origin[]; extern char s_or[]; extern char s_outside[]; extern char s_overlay[]; extern char s_overwrite[]; extern char s_params[]; extern char s_parmfile[]; extern char s_passes[]; extern char s_periodicity[]; extern char s_period[]; extern char s_perspective[]; extern char s_pixelzoom[]; extern char s_pixel[]; extern char s_pi[]; extern char s_play[]; extern char s_plotstyle[]; extern char s_polyphony[]; extern char s_potential[]; extern char far s_pressanykeytocontinue[]; extern char s_preview[]; extern char s_printer[]; extern char s_printfile[]; extern char s_prox[]; extern char s_radius[]; extern char s_ramvideo[]; extern char s_randomize[]; extern char s_ranges[]; extern char s_ray[]; extern char s_real[]; extern char s_recip[]; extern char s_record[]; extern char s_release[]; extern char s_reset[]; extern char s_rleps[]; extern char s_rotation[]; extern char s_roughness[]; extern char s_round[]; extern char s_rseed[]; extern char s_savename[]; extern char s_savetime[]; extern char s_scalemap[]; extern char s_scalexyz[]; extern char s_screencoords[]; extern char s_showbox[]; extern char s_showdot[]; extern char s_showorbit[]; extern char s_sinh[]; extern char s_sin[]; extern char s_smoothing[]; extern char s_sound[]; extern char s_sphere[]; extern char s_sqr[]; extern char s_sqrt[]; extern char s_srand[]; extern char s_srelease[]; extern char s_startrail[]; extern char s_stereo[]; extern char s_sum[]; extern char s_sustain[]; extern char s_symmetry[]; extern char s_tanh[]; extern char s_tan[]; extern char s_targa_out[]; extern char s_targa_overlay[]; extern char s_tdis[]; extern char s_tempdir[]; extern char s_textcolors[]; extern char s_textsafe[]; extern char s_title[]; extern char s_tplus[]; extern char s_translate[]; extern char s_transparent[]; extern char s_trunc[]; extern char s_type[]; extern char s_usegrayscale[]; extern char s_vesadetect[]; extern char s_vga[]; extern char s_video[]; extern char s_viewwindows[]; extern char s_volume[]; extern char s_warn[]; extern char s_waterline[]; extern char s_wavetype[]; extern char s_workdir[]; extern char s_xaxis[]; extern char s_xyadjust[]; extern char s_xyaxis[]; extern char s_xyshift[]; extern char s_x[]; extern char s_yaxis[]; extern char s_yes[]; extern char s_y[]; extern char s_zero[]; extern char s_zmag[]; extern char s_z[]; extern int tabmode; extern int taborhelp; extern int Targa_Out; extern int Targa_Overlay; extern char temp1[]; extern double tempsqrx; extern double tempsqry; extern BYTE teststring[]; extern int textaddr; extern int textcbase; extern int textcol; extern int textrbase; extern int textrow; extern int textsafe2; extern int textsafe; extern int text_type; extern unsigned int this_gen_rseed; extern unsigned far * tga16; extern long far * tga32; extern char three_pass; extern double threshold; extern int timedsave; extern int timerflag; extern long timer_interval; extern long timer_start; extern _CMPLX tmp; extern char tempdir[]; extern double toosmall; extern int totpasses; extern long total_formula_mem; extern int TPlusErr; extern int transparent[]; extern BYTE trigndx[]; extern int truecolor; extern int truemode; extern char tstack[]; extern double twopi; extern VOIDFARPTR typespecific_workarea; extern char useinitorbit; extern BYTE used_extra; extern int use_grid; extern BYTE usemag; extern short uses_ismand; extern short uses_p1; extern short uses_p2; extern short uses_p3; extern short uses_p4; extern short uses_p5; extern int use_old_distest; extern int use_old_period; extern int using_jiim; extern int usr_biomorph; extern long usr_distest; extern char usr_floatflag; extern int usr_periodicitycheck; extern char usr_stdcalcmode; extern int vesa_detect; extern int vesa_xres; extern int vesa_yres; extern struct videoinfo videoentry; extern VIDEOINFO videotable[]; extern int video_cutboth; extern int video_scroll; extern int video_startx; extern int video_starty; extern int video_type; extern int video_vram; extern VIDEOINFO * vidtbl; extern int vidtbllen; extern VECTOR view; extern int viewcrop; extern float viewreduction; extern int viewwindow; extern int viewxdots; extern int viewydots; extern int virtual; extern unsigned vsp; extern int vxdots; extern int whichimage; extern float widthfp; extern char workdir[]; extern WORKLIST worklist[MAXCALCWORK]; extern int workpass; extern int worksym; extern long x3rd; extern int xadjust; extern double xcjul; extern int xdots; extern long xmax; extern long xmin; extern int xorTARGA; extern int xshift1; extern int xshift; extern int xtrans; extern double xx3rd; extern int xxadjust1; extern int xxadjust; extern double xxmax; extern double xxmin; extern long XXOne; extern int xxstart; extern int xxstop; extern long y3rd; extern int yadjust; extern double ycjul; extern int ydots; extern long ymax; extern long ymin; extern int yshift1; extern int yshift; extern int ytrans; extern double yy3rd; extern int yyadjust1; extern int yyadjust; extern int yyadjust; extern double yymax; extern double yymin; extern int yystart; extern int yystop; extern double zbx; extern double zby; extern double zdepth; extern int zdots; extern int zoomoff; extern int zrotate; extern int zscroll; extern double zskew; extern double zwidth; #ifdef XFRACT extern int fake_lut; #endif #endif xfractint-20.4.10.orig/headers/winprot.h0000644000000000000000000001336410521463724015006 0ustar #ifndef WINPROT_H #define WINPROT_H /* This file contains prototypes for win specific functions. */ /* calmanp5 -- assembler file prototypes */ extern long cdecl calcmandfpasm_p5(void); extern void cdecl calcmandfpasmstart_p5(void); /* wgeneral -- assembler file prototypes */ extern long cdecl multiply(long, long, int); extern long cdecl divide(long, long, int); /* dialog -- C file prototypes */ extern void PrintFile(void); extern int Win_OpenFile(unsigned char *); extern Win_SaveFile(unsigned char *); /* mainfrac -- C file prototypes */ extern int fractint_main(void); /* prompts1 -- C file prototypes */ extern void set_default_parms(void); /* windos -- C file prototypes */ extern void debugmessage(char *, char *); extern void texttempmsg(char far *); extern int stopmsg(int , char far *); extern int keypressed(void); extern int getakey(void); extern int farread(int, VOIDFARPTR, unsigned); extern int farwrite(int, VOIDFARPTR, unsigned); extern void far_memcpy(void far *, void far *, int); extern void far_memset(void far *, int , int); extern int getcolor(int, int); extern int out_line(BYTE *, int); extern void putcolor_a (int, int, int); extern int clear_screen(int); extern void spindac(int, int); extern void buzzer (int); extern int thinking(int, char far *); extern void CalibrateDelay(void); extern void start_wait(void); extern void end_wait(void); extern int get_video_mode(struct fractal_info *,struct ext_blk_3 *); extern int check_vidmode_keyname(char *); extern void vidmode_keyname(int, char *); extern int check_vidmode_key(int, int); extern int put_line(int, int, int, BYTE *); extern int get_line(int, int, int, BYTE *); extern void restoredac(void); extern void reset_zoom_corners(void); extern void flush_screen(void); extern int win_load(void); extern void win_save(void); extern void win_cycle(void); extern void far * cdecl farmemalloc(long); extern void farmemfree(void far *); extern int far_memcmp(void far *, void far *, int); extern int far_strlen (char far *); extern void far_strcpy (char far *, char far *); extern int far_strcmp (char far *, char far *); extern int far_strnicmp (char far *, char far *, int); extern void far_strcat (char far *, char far *); extern void winfract_help(void); /* windos2 -- C file prototypes */ extern void movecursor(int, int); extern void setattr(int, int, int, int); extern int putstringcenter(int, int, int, int, char far *); extern void putstring(int, int, int, unsigned char far *); extern int fullscreen_choice( int, char far *, char far *, char far *, int, char far * far *, int far *, int, int, int, int, void (*)(), char *, int (*)(), int (*)()); extern int strncasecmp(char far *,char far *,int); extern int input_field(int, int, char *, int, int, int, int (*)(int) ); extern int field_prompt(int, char far *, char far *, char *, int, int (*)(int) ); extern void helptitle(void); extern void stackscreen(void); extern void unstackscreen(void); extern void discardscreen(void); extern void discardgraphics(void); extern int load_palette(void); extern void save_palette(void); extern void fractint_help(void); extern int getakeynohelp(void); extern int win_make_batch_file(void); extern int fractint_getkeypress(int); extern int keycursor(int, int); extern char *despace(char *str); extern int savegraphics(void); extern int restoregraphics(void); extern int main_menu(int); /* winfract -- C file prototypes */ extern void win_set_title_text(void); extern void win_savedac(void); /* winstubs -- C file prototypes */ extern void rotate(int); extern void find_special_colors(void); extern int spawnl(int, char *, char *); extern int showtempmsg(char far *); extern void cleartempmsg(void); extern void freetempmsg(void); extern int FromMemDisk(long, int, void far *); extern int ToMemDisk(long, int, void far *); extern int _fastcall common_startdisk(long, long, int); extern long cdecl normalize(char far *); extern void drawbox(int); extern void farmessage(unsigned char far *); extern void setvideomode(int, int, int, int); extern int fromvideotable(void); extern void home(void); extern int intro_overlay(void); extern int rotate_overlay(void); extern int printer_overlay(void); extern int pot_startdisk(void); extern void SetTgaColors(void); extern int startdisk(void); extern void enddisk(void); extern int readdisk(unsigned int,unsigned int); extern void writedisk(unsigned int,unsigned int,unsigned int); extern int targa_startdisk(FILE *,int); extern void targa_writedisk(unsigned int,unsigned int,BYTE,BYTE,BYTE); extern void targa_readdisk(unsigned int,unsigned int,BYTE *,BYTE *,BYTE *); extern int SetColorPaletteName(char *); extern BYTE far *findfont(int); extern long cdecl readticker(void); extern void EndTGA(void); extern int key_count(int); extern void dispbox(void); extern void clearbox(void); extern void _fastcall addbox(struct coords); extern void _fastcall drawlines(struct coords, struct coords, int, int); extern int showvidlength(void); extern int get_sound_params(void); extern int soundon(int); extern void soundoff(void); extern int initfm(void); extern void mute(void); extern void dvid_status(int, char far *); extern int tovideotable(void); extern void TranspPerPixel(void); extern void stopslideshow(void); extern void aspectratio_crop(float, float); extern void setvideotext(void); extern int load_fractint_cfg(int); /* wintext -- C file prototypes */ extern void wintext_destroy(void); extern int wintext_texton(void); extern int wintext_textoff(void); extern void wintext_putstring(int, int, int, char far *); extern void wintext_paintscreen(int, int, int, int); extern void wintext_cursor(int, int, int); extern int wintext_look_for_activity(int); extern void wintext_addkeypress(unsigned int); extern unsigned int wintext_getkeypress(int); #endif xfractint-20.4.10.orig/headers/unixprot.h0000644000000000000000000000573111257714555015203 0ustar #ifndef UNIXPROT_H #define UNIXPROT_H /* This file contains prototypes for unix/linux specific functions. */ /* calmanp5 -- assembler file prototypes */ extern long cdecl calcmandfpasm_c(void); extern long cdecl calcmandfpasm_p5(void); extern void cdecl calcmandfpasmstart_p5(void); /* * general.c -- C file prototypes */ extern int waitkeypressed(int); extern void fix_ranges(int *, int, int); extern void decode_evolver_info(struct evolution_info *, int); extern void decode_fractal_info(struct fractal_info *, int); extern void decode_orbits_info(struct orbits_info *, int); extern VOIDPTR cdecl farmemalloc(long); extern long cdecl normalize(char *); /* * unix.c -- C file prototypes */ extern long clock_ticks(void); #ifndef HAVESTRI extern int stricmp(char *, char *); extern int strnicmp(char *, char *, int); #endif extern int memicmp(char *, char *, int); extern unsigned short _rotl(unsigned short, short); extern int ltoa(long, char *, int); extern void ftimex(struct timebx *); extern long stackavail(void); extern int kbhit(void); /* unixscr.c -- C file prototypes */ int unixarg(int argc, char **argv, int *i); /* Parses xfractint-specific command line arguments */ void UnixInit(void); /* initializes curses text window and the signal handlers. */ void initUnixWindow(void); /* initializes the graphics window, colormap, etc. */ void UnixDone(void); /* cleans up X window and curses. */ int startvideo(void); /* clears the graphics window */ int endvideo(void); /* just a stub. */ int readvideo(int x, int y); /* reads a pixel from the screen. */ void readvideoline(int y, int x, int lastx, BYTE *pixels); /* reads a line of pixels from the screen. */ void writevideo(int x, int y, int color); /* writes a pixel to the screen. */ void writevideoline(int y, int x, int lastx, BYTE *pixels); /* writes a line of pixels to the screen. */ int readvideopalette(void); /* reads the current colormap into dacbox. */ int writevideopalette(void); /* writes the current colormap from dacbox. */ int resizeWindow(void); /* Checks if the window has been resized, and handles the resize. */ int xgetkey(int block); /* Checks if a key has been pressed. */ unsigned char * xgetfont(void); /* Returns bitmap of an 8x8 font. */ void drawline(int x1, int y1, int x2, int y2); /* Draws a line from (x1,y1) to (x2,y2). */ void setlinemode(int mode); /* Sets line mode to draw or xor. */ void xsync(void); /* Forces all window events to be processed. */ void redrawscreen(void); /* Used with schedulealarm. Xfractint has a delayed write mode, * where the screen is updated only every few seconds. */ void schedulealarm(int soon); /* Schedules the next delayed update. */ /* * video.c -- C file prototypes */ extern void putprompt(void); extern void loaddac(void); extern void putcolor_a(int, int, int); extern int out_line(BYTE *, int); extern int getcolor(int, int); extern void setvideomode(int, int, int, int); extern void putstring(int,int,int,char far *); extern BYTE *findfont (int); #endif xfractint-20.4.10.orig/headers/uclock.h0000644000000000000000000000225210150633601014545 0ustar /* ** UCLOCK.H ** ** Original Copyright 1988-1991 by Bob Stout as part of ** the MicroFirm Function Library (MFL) ** ** This subset version is functionally identical to the ** version originally published by the author in Tech Specialist ** magazine and is hereby donated to the public domain. */ #ifndef UCLOCK_H_INCLUDED #define UCLOCK_H_INCLUDED #include #include #if defined(__ZTC__) #include #undef int_on #undef int_off #elif defined(__TURBOC__) #define int_on enable #define int_off disable #ifndef inp #define inp inportb #endif #ifndef outp #define outp outportb #endif #else /* assume MSC/QC */ #include #define int_on _enable #define int_off _disable #ifndef MK_FP #define MK_FP(seg,offset) \ ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) #endif #endif /* ANSI-equivalent declarations and prototypes */ typedef unsigned long uclock_t; #define UCLK_TCK 1000000L /* Usec per second - replaces CLK_TCK */ #if __cplusplus extern "C" { #endif uclock_t usec_clock(void); void restart_uclock(void); #if __cplusplus } #endif #endif xfractint-20.4.10.orig/headers/PROFILE.H0000644000000000000000000000031710400460450014323 0ustar extern char WindowSizingStr[], ImageWidthStr[], ImageHeightStr[], ZoomBoxStr[], CoordBoxStr[], Winfract[]; extern char WinfractPosStr[], ZoomBoxPosStr[], CoordBoxPosStr[]; extern char *ProgStr; xfractint-20.4.10.orig/headers/unix.h0000644000000000000000000000420610756132210014253 0ustar /* UNIX.H - unix port declarations */ #ifndef _UNIX_H #define _UNIX_H #define far #define cdecl #define huge #define near #ifndef RAND_MAX #define RAND_MAX 0x7fffffff #endif #ifndef O_BINARY #define O_BINARY 0 #endif #ifdef CLK_TCK #undef CLK_TCK #endif #define CLK_TCK 1000 typedef float FLOAT4; typedef short INT2; typedef unsigned short UINT2; typedef int INT4; typedef unsigned int UINT4; #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define remove(x) unlink(x) #define chsize(fd,len) ftruncate(fd,len) #define inp(x) 0 #define outp(x,y) #ifndef labs #define labs(x) ((x)>0?(x):-(x)) #endif /* We get a problem with connect, since it is used by X */ #define connect connect1 /* dysize may conflict with time.h */ #define dysize dysize1 /* inline is a reserved word, so fixed lsys.c */ /* #define inline inline1 */ typedef void (*SignalHandler)(int); #ifdef NOSIGHAND typedef void (*SignalHandler)(int); #endif /* Some stdio.h's don't have this */ #ifndef SEEK_SET #define SEEK_SET 0 #endif #ifndef SEEK_CUR #define SEEK_CUR 1 #endif #ifndef SEEK_END #define SEEK_END 2 #endif extern int iocount; char *strlwr(char *s); char *strupr(char *s); #ifndef LINUX #ifndef __SVR4 /* bcopy is probably faster than memmove, memcpy */ # ifdef memcpy # undef memcpy # endif # ifdef memmove # undef memmove # endif # define memcpy(dst,src,n) bcopy(src,dst,n) # define memmove(dst,src,n) bcopy(src,dst,n) #else # define bcopy(src,dst,n) memcpy(dst,src,n) # define bzero(buf,siz) memset(buf,0,siz) # define bcmp(buf1,buf2,len) memcmp(buf1,buf2,len) #endif #endif /* For Unix, all memory is FARMEM */ #define EXPANDED FARMEM #define EXTENDED FARMEM /* * These defines are so movedata, etc. will work properly, without worrying * about the silly segment stuff. */ #define movedata(s_seg,s_off,d_seg,d_off,len) bcopy(s_off,d_off,len) struct SREGS { int ds; }; #define FP_SEG(x) 0 #define FP_OFF(x) ((char *)(x)) #define segread(x) /* ftime replacement */ #include typedef struct timebx { time_t time; unsigned short millitm; int timezone; int dstflag; } timebx; #endif xfractint-20.4.10.orig/headers/DIALOG.H0000644000000000000000000001502410427460177014202 0ustar /* fractal image stuff */ #define IDM_SIZE1 151 #define IDM_SIZE2 152 #define IDM_SIZE3 153 #define IDM_SIZE4 154 #define IDM_ITER1 161 #define IDM_ITER2 162 #define IDM_ITER3 163 /* fractal formula stuff */ #define ID_FRACNAME 200 #define ID_FRACPARAM1 201 #define ID_FRACPARAM2 202 #define ID_FRACPARAM3 203 #define ID_FRACPARAM4 204 #define ID_FRACPARAM5 205 #define ID_FRACPARAM6 206 #define ID_FRACPARTX1 207 #define ID_FRACPARTX2 208 #define ID_FRACPARTX3 209 #define ID_FRACPARTX4 210 #define ID_FRACPARTX5 211 #define ID_FRACPARTX6 212 #define ID_BAILOUT 220 #define ID_FRACXMIN 221 #define ID_FRACXMAX 222 #define ID_FRACYMIN 223 #define ID_FRACYMAX 224 #define ID_BAILOUTEST 230 #define ID_BAILOUTESTMOD 231 #define ID_BAILOUTESTREAL 232 #define ID_BAILOUTESTIMAG 233 #define ID_BAILOUTESTOR 234 #define ID_BAILOUTESTAND 235 #define ID_BAILOUTESTMANH 236 #define ID_BAILOUTESTMANR 237 /* window sizing stuff */ #define ID_ISIZE 250 #define ID_ISIZE1 251 #define ID_ISIZE2 252 #define ID_ISIZE3 253 #define ID_ISIZE4 254 #define ID_ISIZE5 255 #define ID_ISIZE6 256 #define ID_ISIZE7 257 #define ID_ISIZE8 258 #define ID_ISIZEX 259 #define ID_ISIZEY 260 #define ID_ICOLORS 270 #define ID_ICOLORS1 271 #define ID_ICOLORS2 272 #define ID_ICOLORS3 273 /* options and doodads menu */ #define ID_DEBUGFLAG 290 #define ID_PASS 300 #define ID_PASS1 301 #define ID_PASS2 302 #define ID_PASSG 303 #define ID_PASSB 304 #define ID_PASST 305 #define ID_PASSD 306 #define ID_PASSO 307 #define ID_MATHF 310 #define ID_MAXIT 320 #define ID_BIOMORPH 330 #define ID_DECOMP 340 #define ID_INSIDE 345 #define ID_INSIDE2 356 #define ID_INSIDEC 346 #define ID_INSIDEM 347 #define ID_INSIDEZ 348 #define ID_INSIDE60 349 #define ID_INSIDE61 350 #define ID_INSIDEE 351 #define ID_INSIDES 352 #define ID_INSIDEPER 353 #define ID_INSIDEAT 354 #define ID_INSIDEFM 355 #define ID_OUTSIDE 360 #define ID_OUTSIDE2 370 #define ID_OUTSIDEN 361 #define ID_OUTSIDEIT 362 #define ID_OUTSIDER 363 #define ID_OUTSIDEIM 364 #define ID_OUTSIDEM 365 #define ID_OUTSIDES 366 #define ID_OUTSIDEAT 367 #define ID_OUTSIDEFM 368 #define ID_OUTSIDETD 369 #define ID_FILL 380 #define ID_FILLC 381 #define ID_LOGP 390 /* extended options and doodads menu */ #define ID_FINITE 300 #define ID_POTENTMAX 310 #define ID_POTENTSLOPE 311 #define ID_POTENTBAIL 312 #define ID_POTENT16 313 #define ID_DISTEST 320 #define ID_DISTESTWID 321 #define ID_INVERTRAD 330 #define ID_INVERTX 331 #define ID_INVERTY 332 #define ID_COLORMIN 340 #define ID_COLORMAX 341 #define ID_NUMSTARS 350 #define ID_CLUMPINESS 351 #define ID_DIMRATIO 352 /* Parameter (Batch) Save stuff */ #define ID_PFILE 210 #define ID_PENTRY 211 #define ID_PCOM1 212 #define ID_PCOM2 213 #define ID_PCOM3 214 #define ID_PCOM4 215 #define ID_PCOL1 221 #define ID_PCOL2 222 #define ID_PCOL3 223 #define ID_PCFILE 231 #define ID_PCNUM 232 /* Color-Cycling stuff */ #define ID_CYCLEOFF 330 #define ID_CYCLEON 331 #define ID_CYCLEOUT 332 #define ID_CYCLEIN 333 #define ID_CYCLESTAT 334 #define ID_CYCLECHG 335 #define ID_CYCLELOW 336 #define ID_CYCLEMED 337 #define ID_CYCLEHIGH 338 /* 3D stuff */ #define ID_PREVIEW 201 #define ID_SHOWBOX 202 #define ID_SPHERICAL 203 #define ID_PREVIEWFACTOR 204 #define ID_STEREO1 241 #define ID_STEREO2 242 #define ID_STEREO3 243 #define ID_STEREO4 244 #define ID_FILL1 211 #define ID_FILL2 212 #define ID_FILL3 213 #define ID_FILL4 214 #define ID_FILL5 215 #define ID_FILL6 216 #define ID_FILL7 217 #define ID_FILL8 218 #define ID_RAY0 220 #define ID_RAY1 221 #define ID_RAY2 222 #define ID_RAY3 223 #define ID_RAY4 224 #define ID_RAY5 225 #define ID_RAY6 226 #define ID_RAYB 227 #define ID_RAYN 228 #define ID_TARGA 231 #define ID_ANS1 201 #define ID_ANS2 202 #define ID_ANS3 203 #define ID_ANS4 204 #define ID_ANS5 205 #define ID_ANS6 206 #define ID_ANS7 207 #define ID_ANS8 208 #define ID_ANS9 209 #define ID_ANS10 210 #define ID_ANS11 211 #define ID_ANS12 212 #define ID_ANS13 213 #define ID_ANS14 214 #define ID_ANS15 215 /* generic fullscreen stuff */ #define ID_PROMPT00 300 #define ID_PROMPT01 301 #define ID_PROMPT02 302 #define ID_PROMPT03 303 #define ID_PROMPT04 304 #define ID_PROMPT05 305 #define ID_PROMPT06 306 #define ID_PROMPT07 307 #define ID_PROMPT08 308 #define ID_PROMPT09 309 #define ID_PROMPT10 310 #define ID_PROMPT11 311 #define ID_PROMPT12 312 #define ID_PROMPT13 313 #define ID_PROMPT14 314 #define ID_PROMPT15 315 #define ID_PROMPT16 316 #define ID_PROMPT17 317 #define ID_PROMPT18 318 #define ID_PROMPT19 319 #define ID_ANSWER01 321 #define ID_ANSWER02 322 #define ID_ANSWER03 323 #define ID_ANSWER04 324 #define ID_ANSWER05 325 #define ID_ANSWER06 326 #define ID_ANSWER07 327 #define ID_ANSWER08 328 #define ID_ANSWER09 329 #define ID_ANSWER10 330 #define ID_ANSWER11 331 #define ID_ANSWER12 332 #define ID_ANSWER13 333 #define ID_ANSWER14 334 #define ID_ANSWER15 335 #define ID_ANSWER16 336 #define ID_ANSWER17 337 #define ID_ANSWER18 338 #define ID_ANSWER19 339 /* status box */ #define IDS_LINE1 341 #define IDS_LINE2 342 #define IDS_LINE3 343 #define IDS_LINE4 344 #define IDS_LINE5 345 #define IDS_LINE6 346 #define IDS_LINE7 347 #define IDS_LINE8 348 #define IDS_LINE9 349 xfractint-20.4.10.orig/headers/prototyp.h0000644000000000000000000012036411451656645015214 0ustar #ifndef PROTOTYP_H #define PROTOTYP_H /* includes needed to define the prototypes */ #include "mpmath.h" #include "big.h" #include "fractint.h" #include "helpcom.h" #include "externs.h" /* maintain the common prototypes in this file * split the dos/win/unix prototypes into separate files. */ #ifdef XFRACT #include "unixprot.h" #endif #ifdef WINFRACT #include "winprot.h" #endif #if (!defined(XFRACT) && !defined(WINFRACT)) #include "dosprot.h" #endif /* calcmand -- assembler file prototypes */ extern long cdecl calcmandasm(void); /* calmanfp -- assembler file prototypes */ extern void cdecl calcmandfpasmstart(void); /* extern long cdecl calcmandfpasm(void); */ extern long cdecl calcmandfpasm_287(void); extern long cdecl calcmandfpasm_87(void); extern long (*calcmandfpasm)(void); /* fpu087 -- assembler file prototypes */ extern void cdecl FPUcplxmul(_CMPLX *, _CMPLX *, _CMPLX *); extern void cdecl FPUcplxdiv(_CMPLX *, _CMPLX *, _CMPLX *); extern void cdecl FPUsincos(double *, double *, double *); extern void cdecl FPUsinhcosh(double *, double *, double *); extern void cdecl FPUcplxlog(_CMPLX *, _CMPLX *); extern void cdecl SinCos086(long , long *, long *); extern void cdecl SinhCosh086(long , long *, long *); extern long far cdecl r16Mul(long , long ); extern long far cdecl RegFloat2Fg(long , int ); extern long cdecl Exp086(long); extern unsigned long far cdecl ExpFudged(long , int ); extern long far cdecl RegDivFloat(long , long ); extern long far cdecl LogFudged(unsigned long , int ); extern long far cdecl LogFloat14(unsigned long ); #ifndef XFRACT extern long far cdecl RegFg2Float(long, char); extern long far cdecl RegSftFloat(long, char); #else extern long far cdecl RegFg2Float(long , int ); extern long far cdecl RegSftFloat(long , int ); #endif /* fpu387 -- assembler file prototypes */ extern void cdecl FPUaptan387(double *, double *, double *); extern void cdecl FPUcplxexp387(_CMPLX *, _CMPLX *); /* fracsuba -- assembler file prototypes */ extern int near asmlMODbailout(void); extern int near asmlREALbailout(void); extern int near asmlIMAGbailout(void); extern int near asmlORbailout(void); extern int near asmlANDbailout(void); extern int near asmlMANHbailout(void); extern int near asmlMANRbailout(void); extern int near asm386lMODbailout(void); extern int near asm386lREALbailout(void); extern int near asm386lIMAGbailout(void); extern int near asm386lORbailout(void); extern int near asm386lANDbailout(void); extern int near asm386lMANHbailout(void); extern int near asm386lMANRbailout(void); extern int FManOWarfpFractal( void ); extern int FJuliafpFractal( void ); extern int FBarnsley1FPFractal( void ); extern int FBarnsley2FPFractal( void ); extern int FLambdaFPFractal( void ); extern int near asmfpMODbailout(void); extern int near asmfpREALbailout(void); extern int near asmfpIMAGbailout(void); extern int near asmfpORbailout(void); extern int near asmfpANDbailout(void); extern int near asmfpMANHbailout(void); extern int near asmfpMANRbailout(void); /* mpmath_a -- assembler file prototypes */ extern struct MP * MPmul086(struct MP , struct MP ); extern struct MP * MPdiv086(struct MP , struct MP ); extern struct MP * MPadd086(struct MP , struct MP ); extern int MPcmp086(struct MP , struct MP ); extern struct MP * d2MP086(double ); extern double * MP2d086(struct MP ); extern struct MP * fg2MP086(long , int ); extern struct MP * MPmul386(struct MP , struct MP ); extern struct MP * MPdiv386(struct MP , struct MP ); extern struct MP * MPadd386(struct MP , struct MP ); extern int MPcmp386(struct MP , struct MP ); extern struct MP * d2MP386(double ); extern double * MP2d386(struct MP ); extern struct MP * fg2MP386(long , int ); extern double * MP2d(struct MP ); extern int MPcmp(struct MP , struct MP ); extern struct MP * MPmul(struct MP , struct MP ); extern struct MP * MPadd(struct MP , struct MP ); extern struct MP * MPdiv(struct MP , struct MP ); extern struct MP * d2MP(double ); /* Convert double to type MP */ extern struct MP * fg2MP(long , int ); /* Convert fudged to type MP */ /* newton -- assembler file prototypes */ extern int cdecl NewtonFractal2( void ); extern void cdecl invertz2(_CMPLX *); /* tplus_a -- assembler file prototypes */ extern void WriteTPlusBankedPixel(int, int, unsigned long); extern unsigned long ReadTPlusBankedPixel(int, int); /* 3d -- C file prototypes */ extern void identity(MATRIX); extern void mat_mul(MATRIX,MATRIX,MATRIX); extern void scale(double ,double ,double ,MATRIX); extern void xrot(double ,MATRIX); extern void yrot(double ,MATRIX); extern void zrot(double ,MATRIX); extern void trans(double ,double ,double ,MATRIX); extern int cross_product(VECTOR,VECTOR,VECTOR); extern int normalize_vector(VECTOR); extern int vmult(VECTOR,MATRIX,VECTOR); extern void mult_vec(VECTOR); extern int perspective(VECTOR); extern int longvmultpersp(LVECTOR,LMATRIX,LVECTOR,LVECTOR,LVECTOR,int); extern int longpersp(LVECTOR,LVECTOR,int ); extern int longvmult(LVECTOR,LMATRIX,LVECTOR,int ); /* biginit -- C file prototypes */ /* CAE removed static functions from header 28 Jan 95 */ void free_bf_vars(void); bn_t alloc_stack(size_t size); int save_stack(void); void restore_stack(int old_offset); void init_bf_dec(int dec); void init_bf_length(int bnl); void init_big_pi(void); /* calcfrac -- C file prototypes */ extern int calcfract(void); extern int calcmand(void); extern int calcmandfp(void); extern int StandardFractal(void); extern int test(void); extern int plasma(void); extern int diffusion(void); extern int Bifurcation(void ); extern int BifurcLambda(void); extern int BifurcSetTrigPi(void); extern int LongBifurcSetTrigPi(void); extern int BifurcAddTrigPi(void); extern int LongBifurcAddTrigPi(void); extern int BifurcMay(void); extern int BifurcMaySetup(void); extern int LongBifurcMay(void); extern int BifurcLambdaTrig(void); extern int LongBifurcLambdaTrig(void); extern int BifurcVerhulstTrig(void); extern int LongBifurcVerhulstTrig(void); extern int BifurcStewartTrig(void); extern int LongBifurcStewartTrig(void); extern int popcorn(void); extern int lyapunov(void); extern int lya_setup(void); extern int cellular(void); extern int CellularSetup(void); extern int calcfroth(void); extern int froth_per_pixel(void); extern int froth_per_orbit(void); extern int froth_setup(void); extern int logtable_in_extra_ok(void); extern int find_alternate_math(int, int); /* cmdfiles -- C file prototypes */ extern int cmdfiles(int ,char **); extern int load_commands(FILE *); extern void set_3d_defaults(void); extern int get_curarg_len(char *curarg); extern int get_max_curarg_len(char *floatvalstr[], int totparm); extern int init_msg(int,char *,char far *,int); extern int cmdarg(char *curarg,int mode); extern int getpower10(LDBL x); extern void dopause(int); /* decoder -- C file prototypes */ extern short decoder(short ); extern void set_byte_buff(BYTE *ptr); /* diskvid -- C file prototypes */ extern int pot_startdisk(void); extern int targa_startdisk(FILE *,int ); extern void enddisk(void); #ifndef XFRACT extern int readdisk(unsigned int, unsigned int ); extern void writedisk(unsigned int, unsigned int, unsigned int ); #else extern int readdisk(int, int ); extern void writedisk(int, int, int ); #endif extern void targa_readdisk(unsigned int ,unsigned int ,BYTE *,BYTE *,BYTE *); extern void targa_writedisk(unsigned int ,unsigned int ,BYTE ,BYTE ,BYTE ); extern void dvid_status(int ,char far *); extern int _fastcall common_startdisk(long, long, int); extern int FromMemDisk(long,int,void far *); extern int ToMemDisk(long,int,void far *); /* editpal -- C file prototypes */ extern void EditPalette(void ); extern VOIDPTR mem_alloc(unsigned size); void putrow(int x, int y, int width, char *buff); void getrow(int x, int y, int width, char *buff); void mem_init(VOIDPTR block, unsigned size); /* void hline(int x, int y, int width, int color); */ int Cursor_WaitKey(void); void Cursor_CheckBlink(void); #ifdef XFRACT void Cursor_StartMouseTracking(void); void Cursor_EndMouseTracking(void); #endif void clip_putcolor(int x, int y, int color); int clip_getcolor(int x, int y); BOOLEAN Cursor_Construct (void); void Cursor_Destroy (void); void Cursor_SetPos (int x, int y); void Cursor_Move (int xoff, int yoff); int Cursor_GetX (void); int Cursor_GetY (void); void Cursor_Hide (void); void Cursor_Show (void); extern void displayc(int, int, int, int, int); /* encoder -- C file prototypes */ extern int savetodisk(char *); extern int encoder(void); extern int _fastcall new_to_old(int new_fractype); /* evolve -- C file prototypes */ extern void initgene(void); extern void param_history(int); extern int get_variations(void); extern int get_evolve_Parms(void); extern void set_current_params(void); extern void fiddleparms(GENEBASE gene[], int ecount); extern void set_evolve_ranges(void); extern void set_mutation_level(int); extern void drawparmbox(int); extern void spiralmap(int); extern int unspiralmap(void); extern int explore_check(void); extern void SetupParamBox(void); extern void ReleaseParamBox(void); /* f16 -- C file prototypes */ extern FILE *t16_open(char *,int *,int *,int *,U8 *); extern int t16_getline(FILE *,int ,U16 *); /* fracsubr -- C file prototypes */ extern void calcfracinit(void); extern void adjust_corner(void); #ifndef USE_VARARGS extern int put_resume(int ,... ); extern int get_resume(int ,... ); #else extern int put_resume(); extern int get_resume(); #endif extern int alloc_resume(int ,int ); extern int start_resume(void); extern void end_resume(void); extern void sleepms(long ); extern void reset_clock(void); extern void iplot_orbit(long ,long ,int ); extern void plot_orbit(double ,double ,int ); extern void scrub_orbit(void); extern int add_worklist(int ,int, int ,int ,int ,int ,int ,int ); extern void tidy_worklist(void); extern void get_julia_attractor(double ,double ); extern int ssg_blocksize(void); extern void _fastcall symPIplot(int ,int ,int ); extern void _fastcall symPIplot2J(int ,int ,int ); extern void _fastcall symPIplot4J(int ,int ,int ); extern void _fastcall symplot2(int ,int ,int ); extern void _fastcall symplot2Y(int ,int ,int ); extern void _fastcall symplot2J(int ,int ,int ); extern void _fastcall symplot4(int ,int ,int ); extern void _fastcall symplot2basin(int ,int ,int ); extern void _fastcall symplot4basin(int ,int ,int ); extern void _fastcall noplot(int ,int ,int ); extern void fractal_floattobf(void); extern void adjust_cornerbf(void); extern void set_grid_pointers(void); extern void fill_dx_array(void); extern void fill_lx_array(void); extern int snd_open(void); extern void w_snd(int); extern void snd_time_write(void); extern void close_snd(void); /* fractalp -- C file prototypes */ extern int typehasparm(int,int,char *); extern int paramnotused(int); /* fractals -- C file prototypes */ extern void FloatPreCalcMagnet2(void); extern void cpower(_CMPLX *,int ,_CMPLX *); extern int lcpower(_LCMPLX *,int ,_LCMPLX *,int ); extern int lcomplex_mult(_LCMPLX ,_LCMPLX ,_LCMPLX *,int ); extern int MPCNewtonFractal(void); extern int Barnsley1Fractal(void); extern int Barnsley1FPFractal(void); extern int Barnsley2Fractal(void); extern int Barnsley2FPFractal(void); extern int JuliaFractal(void); extern int JuliafpFractal(void); extern int LambdaFPFractal(void); extern int LambdaFractal(void); extern int SierpinskiFractal(void); extern int SierpinskiFPFractal(void); extern int LambdaexponentFractal(void); extern int LongLambdaexponentFractal(void); extern int FloatTrigPlusExponentFractal(void); extern int LongTrigPlusExponentFractal(void); extern int MarksLambdaFractal(void); extern int MarksLambdafpFractal(void); extern int UnityFractal(void); extern int UnityfpFractal(void); extern int Mandel4Fractal(void); extern int Mandel4fpFractal(void); extern int floatZtozPluszpwrFractal(void); extern int longZpowerFractal(void); extern int longCmplxZpowerFractal(void); extern int floatZpowerFractal(void); extern int floatCmplxZpowerFractal(void); extern int Barnsley3Fractal(void); extern int Barnsley3FPFractal(void); extern int TrigPlusZsquaredFractal(void); extern int TrigPlusZsquaredfpFractal(void); extern int Richard8fpFractal(void); extern int Richard8Fractal(void); extern int PopcornFractal(void); extern int LPopcornFractal(void); extern int PopcornFractal_Old(void); extern int LPopcornFractal_Old(void); extern int PopcornFractalFn(void); extern int LPopcornFractalFn(void); extern int MarksCplxMand(void ); extern int SpiderfpFractal(void ); extern int SpiderFractal(void ); extern int TetratefpFractal(void); extern int ZXTrigPlusZFractal(void); extern int ScottZXTrigPlusZFractal(void); extern int SkinnerZXTrigSubZFractal(void); extern int ZXTrigPlusZfpFractal(void); extern int ScottZXTrigPlusZfpFractal(void); extern int SkinnerZXTrigSubZfpFractal(void); extern int Sqr1overTrigFractal(void); extern int Sqr1overTrigfpFractal(void); extern int TrigPlusTrigFractal(void); extern int TrigPlusTrigfpFractal(void); extern int ScottTrigPlusTrigFractal(void); extern int ScottTrigPlusTrigfpFractal(void); extern int SkinnerTrigSubTrigFractal(void); extern int SkinnerTrigSubTrigfpFractal(void); extern int TrigXTrigfpFractal(void); extern int TrigXTrigFractal(void); extern int TrigPlusSqrFractal(void); extern int TrigPlusSqrfpFractal(void); extern int ScottTrigPlusSqrFractal(void); extern int ScottTrigPlusSqrfpFractal(void); extern int SkinnerTrigSubSqrFractal(void); extern int SkinnerTrigSubSqrfpFractal(void); extern int TrigZsqrdfpFractal(void); extern int TrigZsqrdFractal(void); extern int SqrTrigFractal(void); extern int SqrTrigfpFractal(void); extern int Magnet1Fractal(void); extern int Magnet2Fractal(void); extern int LambdaTrigFractal(void); extern int LambdaTrigfpFractal(void); extern int LambdaTrigFractal1(void); extern int LambdaTrigfpFractal1(void); extern int LambdaTrigFractal2(void); extern int LambdaTrigfpFractal2(void); extern int ManOWarFractal(void); extern int ManOWarfpFractal(void); extern int MarksMandelPwrfpFractal(void); extern int MarksMandelPwrFractal(void); extern int TimsErrorfpFractal(void); extern int TimsErrorFractal(void); extern int CirclefpFractal(void); extern int VLfpFractal(void); extern int EscherfpFractal(void); extern int long_julia_per_pixel(void); extern int long_richard8_per_pixel(void); extern int long_mandel_per_pixel(void); extern int julia_per_pixel(void); extern int marks_mandelpwr_per_pixel(void); extern int mandel_per_pixel(void); extern int marksmandel_per_pixel(void); extern int marksmandelfp_per_pixel(void); extern int marks_mandelpwrfp_per_pixel(void); extern int mandelfp_per_pixel(void); extern int juliafp_per_pixel(void); extern int MPCjulia_per_pixel(void); extern int otherrichard8fp_per_pixel(void); extern int othermandelfp_per_pixel(void); extern int otherjuliafp_per_pixel(void); extern int MarksCplxMandperp(void ); extern int LambdaTrigOrTrigFractal(void); extern int LambdaTrigOrTrigfpFractal(void); extern int JuliaTrigOrTrigFractal(void); extern int JuliaTrigOrTrigfpFractal(void); extern int HalleyFractal(void); extern int Halley_per_pixel(void); extern int MPCHalleyFractal(void); extern int MPCHalley_per_pixel(void); extern int dynamfloat(double *,double *,double*); extern int mandelcloudfloat(double *,double *,double*); extern int dynam2dfloat(void); extern int QuaternionFPFractal(void); extern int quaternionfp_per_pixel(void); extern int quaternionjulfp_per_pixel(void); extern int LongPhoenixFractal(void); extern int PhoenixFractal(void); extern int long_phoenix_per_pixel(void); extern int phoenix_per_pixel(void); extern int long_mandphoenix_per_pixel(void); extern int mandphoenix_per_pixel(void); extern int HyperComplexFPFractal(void); extern int LongPhoenixFractalcplx(void); extern int PhoenixFractalcplx(void); extern int (near *floatbailout)(void); extern int (near *longbailout)(void); extern int (near *bignumbailout)(void); extern int (near *bigfltbailout)(void); extern int near fpMODbailout(void); extern int near fpREALbailout(void); extern int near fpIMAGbailout(void); extern int near fpORbailout(void); extern int near fpANDbailout(void); extern int near fpMANHbailout(void); extern int near fpMANRbailout(void); extern int near bnMODbailout(void); extern int near bnREALbailout(void); extern int near bnIMAGbailout(void); extern int near bnORbailout(void); extern int near bnANDbailout(void); extern int near bnMANHbailout(void); extern int near bnMANRbailout(void); extern int near bfMODbailout(void); extern int near bfREALbailout(void); extern int near bfIMAGbailout(void); extern int near bfORbailout(void); extern int near bfANDbailout(void); extern int near bfMANHbailout(void); extern int near bfMANRbailout(void); extern int ant(void); extern int LongPhoenixFractal(void); extern int PhoenixFractal(void); extern int LongPhoenixFractalcplx(void); extern int PhoenixFractalcplx(void); extern int LongPhoenixPlusFractal(void); extern int PhoenixPlusFractal(void); extern int LongPhoenixMinusFractal(void); extern int PhoenixMinusFractal(void); extern int LongPhoenixCplxPlusFractal(void); extern int PhoenixCplxPlusFractal(void); extern int LongPhoenixCplxMinusFractal(void); extern int PhoenixCplxMinusFractal(void); extern int long_phoenix_per_pixel(void); extern int phoenix_per_pixel(void); extern int long_mandphoenix_per_pixel(void); extern int mandphoenix_per_pixel(void); extern void set_pixel_calc_functions(void); extern int MandelbrotMix4fp_per_pixel(void); extern int MandelbrotMix4fpFractal(void); extern int MandelbrotMix4Setup(void); extern int DivideBrot5fp_per_pixel(void); extern int DivideBrot5fpFractal(void); extern int DivideBrot5Setup(void); /* fractint -- C file prototypes */ #ifdef XFRACT extern int main(int argc,char **argv ); #else extern void main(int argc,char **argv ); #endif extern int elapsed_time(int); /* framain2 -- C file prototypes */ extern int big_while_loop(int *,char *,int); extern int check_key(void); extern int cmp_line(BYTE *,int ); extern int key_count(int); extern int main_menu_switch(int *,int *,int *,char *,int); extern int pot_line(BYTE *,int ); extern int sound_line(BYTE *,int ); #ifdef XFRACT extern int XZoomWaiting; #endif #ifndef USE_VARARGS extern int timer(int,int (*subrtn)(),...); #else extern int timer(); #endif extern void clear_zoombox(void); extern void flip_image(int kbdchar); #ifndef WINFRACT extern void reset_zoom_corners(void); #endif extern void setup287code(void); extern void checkfreemem(int); /* frasetup -- C file prototypes */ extern int VLSetup(void); extern int MandelSetup(void); extern int MandelfpSetup(void); extern int JuliaSetup(void); extern int NewtonSetup(void); extern int StandaloneSetup(void); extern int UnitySetup(void); extern int JuliafpSetup(void); extern int MandellongSetup(void); extern int JulialongSetup(void); extern int TrigPlusSqrlongSetup(void); extern int TrigPlusSqrfpSetup(void); extern int TrigPlusTriglongSetup(void); extern int TrigPlusTrigfpSetup(void); extern int FnPlusFnSym(void); extern int ZXTrigPlusZSetup(void); extern int LambdaTrigSetup(void); extern int JuliafnPlusZsqrdSetup(void); extern int SqrTrigSetup(void); extern int FnXFnSetup(void); extern int MandelTrigSetup(void); extern int MarksJuliaSetup(void); extern int MarksJuliafpSetup(void); extern int SierpinskiSetup(void); extern int SierpinskiFPSetup(void); extern int StandardSetup(void); extern int LambdaTrigOrTrigSetup(void); extern int JuliaTrigOrTrigSetup(void); extern int ManlamTrigOrTrigSetup(void); extern int MandelTrigOrTrigSetup(void); extern int HalleySetup(void); extern int dynam2dfloatsetup(void); extern int PhoenixSetup(void); extern int MandPhoenixSetup(void); extern int PhoenixCplxSetup(void); extern int MandPhoenixCplxSetup(void); /* gifview -- C file prototypes */ extern int get_byte(void); extern int get_bytes(BYTE *,int ); extern int gifview(void); /* hcmplx -- C file prototypes */ extern void HComplexTrig0(_HCMPLX *,_HCMPLX *); /* help -- C file prototypes */ extern int _find_token_length(char far *,unsigned int ,int *,int *); extern int find_token_length(int ,char far *,unsigned int ,int *,int *); extern int find_line_width(int ,char far *,unsigned int ); extern int process_document(PD_FUNC ,PD_FUNC ,VOIDPTR ); extern int help(int ); extern int read_help_topic(int ,int ,int ,VOIDFARPTR ); extern int makedoc_msg_func(int ,int ); extern void print_document(char *,int (*)(int ,int ),int ); extern int init_help(void ); extern void end_help(void ); /* history -- C file prototypes */ void _fastcall restore_history_info(int); void _fastcall save_history_info(void); /* intro -- C file prototypes */ extern void intro(void ); /* jb -- C file prototypes */ extern int JulibrotSetup(void ); extern int JulibrotfpSetup(void ); extern int jb_per_pixel(void ); extern int jbfp_per_pixel(void ); extern int zline(long ,long ); extern int zlinefp(double ,double ); extern int Std4dFractal(void ); extern int Std4dfpFractal(void ); /* jiim -- C file prototypes */ extern void Jiim(int); extern LCMPLX PopLong (void); extern _CMPLX PopFloat (void); extern LCMPLX DeQueueLong (void); extern _CMPLX DeQueueFloat (void); extern LCMPLX ComplexSqrtLong (long , long); extern _CMPLX ComplexSqrtFloat(double, double); extern int Init_Queue (unsigned long); extern void Free_Queue (void); extern void ClearQueue (void); extern int QueueEmpty (void); extern int QueueFull (void); extern int QueueFullAlmost (void); extern int PushLong (long , long); extern int PushFloat (float, float); extern int EnQueueLong (long , long); extern int EnQueueFloat (float, float); /* line3d -- C file prototypes */ extern int line3d(BYTE *,unsigned int ); extern int _fastcall targa_color(int ,int ,int ); extern int targa_validate(char *); extern int startdisk1(char *, FILE *, int); /* loadfdos -- C file prototypes */ #ifndef WINFRACT extern int get_video_mode(struct fractal_info *,struct ext_blk_3 *); #endif /* loadfile -- C file prototypes */ extern int read_overlay(void); extern void set_if_old_bif(void); extern void set_function_parm_defaults(void); extern int fgetwindow(void); extern void backwards_v18(void); extern void backwards_v19(void); extern void backwards_v20(void); extern int check_back(void); /* loadmap -- C file prototypes */ extern void SetTgaColors(void); extern int ValidateLuts(char *); extern int SetColorPaletteName(char *); /* lorenz -- C file prototypes */ extern int orbit3dlongsetup(void); extern int orbit3dfloatsetup(void); extern int lorenz3dlongorbit(long *,long *,long *); extern int lorenz3d1floatorbit(double *,double *,double *); extern int lorenz3dfloatorbit(double *,double *,double *); extern int lorenz3d3floatorbit(double *,double *,double *); extern int lorenz3d4floatorbit(double *,double *,double *); extern int henonfloatorbit(double *,double *,double *); extern int henonlongorbit(long *,long *,long *); extern int inverse_julia_orbit(double *,double *,double *); extern int Minverse_julia_orbit(void); extern int Linverse_julia_orbit(void); extern int inverse_julia_per_image(void); extern int rosslerfloatorbit(double *,double *,double *); extern int pickoverfloatorbit(double *,double *,double *); extern int gingerbreadfloatorbit(double *,double *,double *); extern int rosslerlongorbit(long *,long *,long *); extern int kamtorusfloatorbit(double *,double *,double *); extern int kamtoruslongorbit(long *,long *,long *); extern int hopalong2dfloatorbit(double *,double *,double *); extern int chip2dfloatorbit(double *,double *,double *); extern int quadruptwo2dfloatorbit(double *,double *,double *); extern int threeply2dfloatorbit(double *,double *,double *); extern int martin2dfloatorbit(double *,double *,double *); extern int orbit2dfloat(void); extern int orbit2dlong(void); extern int funny_glasses_call(int (*)(void)); extern int ifs(void); extern int orbit3dfloat(void); extern int orbit3dlong(void); extern int iconfloatorbit(double *, double *, double *); /* dmf */ extern int latoofloatorbit(double *, double *, double *); /* hb */ extern int setup_convert_to_screen(struct affine *); extern int plotorbits2dsetup(void); extern int plotorbits2dfloat(void); /* lsys -- C file prototypes */ extern LDBL _fastcall getnumber(char far **); extern int _fastcall ispow2(int); extern int Lsystem(void); extern int LLoad(void); /* miscfrac -- C file prototypes */ extern void froth_cleanup(void); /* miscovl -- C file prototypes */ extern void make_batch_file(void); extern void shell_to_dos(void); extern long fr_farfree(void); extern void showfreemem(void); extern int edit_text_colors(void); extern int select_video_mode(int ); extern void format_vid_table(int choice,char *buf); extern void make_mig(unsigned int, unsigned int); extern int getprecdbl(int); extern int getprecbf(int); extern int getprecbf_mag(void); extern void parse_comments(char *value); extern void init_comments(void); extern void write_batch_parms(char *, int, int, int, int); extern void expand_comments(char far *, char far *); /* miscres -- C file prototypes */ extern void restore_active_ovly(void); extern void findpath(char far *,char *); extern void notdiskmsg(void); extern void cvtcentermag(double *,double *,LDBL *, double *,double *,double *); extern void cvtcorners(double,double,LDBL,double,double,double); extern void cvtcentermagbf(bf_t, bf_t, LDBL *, double *, double *, double *); extern void cvtcornersbf(bf_t, bf_t, LDBL,double,double,double); extern void updatesavename(char *); extern int check_writefile(char *,char *); extern int check_key(void); extern void showtrig(char *); extern int set_trig_array(int ,char *); extern void set_trig_pointers(int ); extern int tab_display(void); extern int endswithslash(char far *); extern int ifsload(void); extern int find_file_item(char *,char *,FILE **, int); extern int file_gets(char *,int ,FILE *); extern void roundfloatd(double *); extern void fix_inversion(double *); extern int ungetakey(int); extern void get_calculation_time(char *, long); #ifndef XFRACT extern int _cdecl _matherr(struct exception *); #endif /* mpmath_c -- C file prototypes */ extern struct MP *MPsub(struct MP ,struct MP ); extern struct MP *MPsub086(struct MP ,struct MP ); extern struct MP *MPsub386(struct MP ,struct MP ); extern struct MP *MPabs(struct MP ); extern struct MPC MPCsqr(struct MPC ); extern struct MP MPCmod(struct MPC ); extern struct MPC MPCmul(struct MPC ,struct MPC ); extern struct MPC MPCdiv(struct MPC ,struct MPC ); extern struct MPC MPCadd(struct MPC ,struct MPC ); extern struct MPC MPCsub(struct MPC ,struct MPC ); extern struct MPC MPCpow(struct MPC ,int ); extern int MPCcmp(struct MPC ,struct MPC ); extern _CMPLX MPC2cmplx(struct MPC ); extern struct MPC cmplx2MPC(_CMPLX ); extern void setMPfunctions(void ); extern _CMPLX ComplexPower(_CMPLX ,_CMPLX ); extern void SetupLogTable(void ); extern long logtablecalc(long); extern long far ExpFloat14(long ); extern int ComplexNewtonSetup(void ); extern int ComplexNewton(void ); extern int ComplexBasin(void ); extern int GausianNumber(int ,int ); extern void Arcsinz(_CMPLX z, _CMPLX *rz); extern void Arccosz(_CMPLX z, _CMPLX *rz); extern void Arcsinhz(_CMPLX z, _CMPLX *rz); extern void Arccoshz(_CMPLX z, _CMPLX *rz); extern void Arctanhz(_CMPLX z, _CMPLX *rz); extern void Arctanz(_CMPLX z, _CMPLX *rz); /* msccos -- C file prototypes */ extern double _cos(double ); /* parser -- C file prototypes */ struct fls { /* function, load, store pointers CAE fp */ void (near *function)(void); union Arg near *operand; }; extern unsigned int SkipWhiteSpace(char *); extern unsigned long NewRandNum(void ); extern void lRandom(void ); extern void dRandom(void ); extern void mRandom(void ); extern void SetRandFnct(void ); extern void RandomSeed(void ); extern void lStkSRand(void ); extern void mStkSRand(void ); extern void dStkSRand(void ); extern void dStkAbs(void ); extern void mStkAbs(void ); extern void lStkAbs(void ); extern void dStkSqr(void ); extern void mStkSqr(void ); extern void lStkSqr(void ); extern void dStkAdd(void ); extern void mStkAdd(void ); extern void lStkAdd(void ); extern void dStkSub(void ); extern void mStkSub(void ); extern void lStkSub(void ); extern void dStkConj(void ); extern void mStkConj(void ); extern void lStkConj(void ); extern void dStkZero(void ); extern void mStkZero(void ); extern void lStkZero(void ); extern void dStkOne(void ); extern void mStkOne(void ); extern void lStkOne(void ); extern void dStkReal(void ); extern void mStkReal(void ); extern void lStkReal(void ); extern void dStkImag(void ); extern void mStkImag(void ); extern void lStkImag(void ); extern void dStkNeg(void ); extern void mStkNeg(void ); extern void lStkNeg(void ); extern void dStkMul(void ); extern void mStkMul(void ); extern void lStkMul(void ); extern void dStkDiv(void ); extern void mStkDiv(void ); extern void lStkDiv(void ); extern void StkSto(void ); extern void StkLod(void ); extern void dStkMod(void ); extern void mStkMod(void ); extern void lStkMod(void ); extern void StkClr(void ); extern void dStkFlip(void ); extern void mStkFlip(void ); extern void lStkFlip(void ); extern void dStkSin(void ); extern void mStkSin(void ); extern void lStkSin(void ); extern void dStkTan(void ); extern void mStkTan(void ); extern void lStkTan(void ); extern void dStkTanh(void ); extern void mStkTanh(void ); extern void lStkTanh(void ); extern void dStkCoTan(void ); extern void mStkCoTan(void ); extern void lStkCoTan(void ); extern void dStkCoTanh(void ); extern void mStkCoTanh(void ); extern void lStkCoTanh(void ); extern void dStkRecip(void ); extern void mStkRecip(void ); extern void lStkRecip(void ); extern void StkIdent(void ); extern void dStkSinh(void ); extern void mStkSinh(void ); extern void lStkSinh(void ); extern void dStkCos(void ); extern void mStkCos(void ); extern void lStkCos(void ); extern void dStkCosXX(void ); extern void mStkCosXX(void ); extern void lStkCosXX(void ); extern void dStkCosh(void ); extern void mStkCosh(void ); extern void lStkCosh(void ); extern void dStkLT(void ); extern void mStkLT(void ); extern void lStkLT(void ); extern void dStkGT(void ); extern void mStkGT(void ); extern void lStkGT(void ); extern void dStkLTE(void ); extern void mStkLTE(void ); extern void lStkLTE(void ); extern void dStkGTE(void ); extern void mStkGTE(void ); extern void lStkGTE(void ); extern void dStkEQ(void ); extern void mStkEQ(void ); extern void lStkEQ(void ); extern void dStkNE(void ); extern void mStkNE(void ); extern void lStkNE(void ); extern void dStkOR(void ); extern void mStkOR(void ); extern void lStkOR(void ); extern void dStkAND(void ); extern void mStkAND(void ); extern void lStkAND(void ); extern void dStkLog(void ); extern void mStkLog(void ); extern void lStkLog(void ); extern void FPUcplxexp(_CMPLX *,_CMPLX *); extern void dStkExp(void ); extern void mStkExp(void ); extern void lStkExp(void ); extern void dStkPwr(void ); extern void mStkPwr(void ); extern void lStkPwr(void ); extern void dStkASin(void ); extern void mStkASin(void ); extern void lStkASin(void ); extern void dStkASinh(void ); extern void mStkASinh(void ); extern void lStkASinh(void ); extern void dStkACos(void ); extern void mStkACos(void ); extern void lStkACos(void ); extern void dStkACosh(void ); extern void mStkACosh(void ); extern void lStkACosh(void ); extern void dStkATan(void ); extern void mStkATan(void ); extern void lStkATan(void ); extern void dStkATanh(void ); extern void mStkATanh(void ); extern void lStkATanh(void ); extern void dStkCAbs(void ); extern void mStkCAbs(void ); extern void lStkCAbs(void ); extern void dStkSqrt(void ); extern void mStkSqrt(void ); extern void lStkSqrt(void ); extern void dStkFloor(void ); extern void mStkFloor(void ); extern void lStkFloor(void ); extern void dStkCeil(void ); extern void mStkCeil(void ); extern void lStkCeil(void ); extern void dStkTrunc(void ); extern void mStkTrunc(void ); extern void lStkTrunc(void ); extern void dStkRound(void ); extern void mStkRound(void ); extern void lStkRound(void ); extern void (*mtrig0)(void); extern void (*mtrig1)(void); extern void (*mtrig2)(void); extern void (*mtrig3)(void); extern void EndInit(void ); extern struct ConstArg far *isconst(char *,int ); extern void NotAFnct(void ); extern void FnctNotFound(void ); extern int whichfn(char *,int ); extern int CvtStk(void); extern int fFormula(void ); #ifndef XFRACT extern void (far *isfunct(char *,int ))(void ); #else extern void (far *isfunct(char *,int ))(); #endif extern void RecSortPrec(void ); extern int Formula(void ); extern int BadFormula(void ); extern int form_per_pixel(void ); extern int frm_get_param_stuff (char * ); extern int RunForm(char *, int); extern int fpFormulaSetup(void ); extern int intFormulaSetup(void ); extern void init_misc(void); extern void free_workarea(void); extern int fill_if_group(int endif_index, JUMP_PTRS_ST *jump_data); /* plot3d -- C file prototypes */ extern void cdecl draw_line(int ,int ,int ,int ,int ); extern void _fastcall plot3dsuperimpose16(int ,int ,int ); extern void _fastcall plot3dsuperimpose256(int ,int ,int ); extern void _fastcall plotIFS3dsuperimpose256(int ,int ,int ); extern void _fastcall plot3dalternate(int ,int ,int ); extern void plot_setup(void); /* printer -- C file prototypes */ extern void Print_Screen(void); /* prompts1 -- C file prototypes */ extern int fullscreen_prompt(char far*,int ,char far **,struct fullscreenvalues *,int ,char far *); extern long get_file_entry(int,char *,char *,char *,char *); extern int get_fracttype(void); extern int get_fract_params(int ); extern int get_fract3d_params(void); extern int get_3d_params(void); extern int prompt_valuestring(char *buf,struct fullscreenvalues *val); extern void setbailoutformula(enum bailouts); extern int find_extra_param(int); extern void load_params(int fractype); extern int check_orbit_name(char *); extern int scan_entries(FILE *infile, void far *ch, char *itemname); /* prompts2 -- C file prototypes */ extern int get_toggles(void); extern int get_toggles2(void); extern int passes_options(void); extern int get_view_params(void); extern int get_starfield_params(void ); extern int get_commands(void); extern void goodbye(void); extern int isadirectory(char *s); extern int getafilename(char *,char *,char *); extern int splitpath(char far *template,char *drive,char *dir,char *fname,char *ext); extern int makepath(char *template,char *drive,char *dir,char *fname,char *ext); extern int fr_findfirst(char *path); extern int fr_findnext(void ); extern void shell_sort(void far *,int n,unsigned,int (__cdecl *fct)(VOIDFARPTR,VOIDFARPTR)); extern void far_strncpy(char far *, char far *, int len); extern char far *far_strchr(char far *str, char c); extern char far *far_strrchr(char far *str, char c); extern void fix_dirname(char *dirname); extern int merge_pathnames(char *, char *, int); extern int get_browse_params(void); extern int get_cmd_string(void); extern int get_rds_params(void); extern int starfield(void); extern int get_a_number(double *, double *); extern int lccompare(VOIDFARPTR, VOIDFARPTR); extern int dir_open(char *, char *, int, int); extern int dir_remove(char *,char *); extern FILE *dir_fopen(char *, char *, char *); extern void extract_filename(char *, char *); extern char *has_ext(char *source); /* realdos -- C file prototypes */ #ifndef WINFRACT extern int showvidlength(void); extern int stopmsg(int ,char far *); extern int texttempmsg(char far *); extern int showtempmsg(char far *); extern void cleartempmsg(void); extern void blankrows(int ,int ,int ); extern void helptitle(void); extern int putstringcenter(int ,int ,int ,int ,char far *); extern void stackscreen(void); extern void unstackscreen(void); extern void discardscreen(void); extern int fullscreen_choice(int options, char far *hdg, char far *hdg2, char far *instr, int numchoices, char far *far *choices, int far *attributes, int boxwidth, int boxdepth, int colwidth, int current , void (*formatitem)(int, char *), char *speedstring, int (*speedprompt)(int, int, int, char *, int), int (*checkkey)(int, int)); #ifndef XFRACT /* Unix should have this in string.h */ extern int strncasecmp(char far *,char far *,int ); #endif extern int main_menu(int ); extern int input_field(int ,int ,char *,int ,int ,int ,int (*)(int)); extern int field_prompt(int ,char far *,char far *,char *,int ,int (*)(int)); extern int thinking(int ,char far *); extern void clear_screen(int ); extern int savegraphics(void); extern int restoregraphics(void); extern void discardgraphics(void); extern int load_fractint_cfg(int ); extern void bad_fractint_cfg_msg(void); extern void load_videotable(int ); extern int check_vidmode_key(int ,int ); extern int check_vidmode_keyname(char *); extern void vidmode_keyname(int ,char *); extern void freetempmsg(void); extern char *despace(char *); extern int menu_checkkey(int ,int ); #endif /* rotate -- C file prototypes */ extern void rotate(int ); extern void save_palette(void); extern int load_palette(void ); /* slideshw -- C file prototypes */ extern int slideshw(void); extern int startslideshow(void); extern void stopslideshow(void); extern void recordshw(int ); /* stereo -- C file prototypes */ extern int do_AutoStereo(void); extern int outline_stereo(BYTE *, int); /* targa -- C file prototypes */ extern void WriteTGA(int ,int ,int ); extern int ReadTGA(int ,int ); extern void EndTGA(void ); extern void StartTGA(void); extern void ReopenTGA(void); /* testpt -- C file prototypes */ extern int teststart(void); extern void testend(void); extern int testpt(double ,double ,double ,double ,long ,int ); /* tgaview -- C file prototypes */ extern int tgaview(void); extern int outlin16(BYTE*,int ); /* yourvid -- C file prototypes */ extern int startvideo(void); extern int endvideo(void); extern void writevideo(int ,int ,int ); extern int readvideo(int ,int ); extern int readvideopalette(void); extern int writevideopalette(void); #ifdef XFRACT extern void readvideoline(int ,int, int, BYTE * ); extern void writevideoline(int ,int, int, BYTE * ); #endif /* zoom -- C file prototypes */ extern void drawbox(int ); extern void moveboxf(double ,double ); extern void resizebox(int ); extern void chgboxi(int ,int ); extern void zoomout(void); extern void aspectratio_crop(float ,float ); extern int init_pan_or_recalc(int ); extern void _fastcall drawlines(struct coords, struct coords, int, int); extern void _fastcall addbox(struct coords); extern void clearbox(void); extern void dispbox(void); /* fractalb.c -- C file prototypes */ extern _CMPLX cmplxbntofloat(_BNCMPLX *); extern _CMPLX cmplxbftofloat(_BFCMPLX *); extern void comparevalues(char *,LDBL,bn_t); extern void comparevaluesbf(char *,LDBL,bf_t); extern void show_var_bf(char *s, bf_t n); extern void show_two_bf(char *,bf_t,char *, bf_t, int); extern void bfcornerstofloat(void); extern void showcornersdbl(char *); extern int MandelbnSetup(void); extern int mandelbn_per_pixel(void); extern int juliabn_per_pixel(void); extern int dividebrot5bn_per_pixel(void); extern int JuliabnFractal(void); extern int JuliaZpowerbnFractal(void); extern int DivideBrot5bnFractal(void); extern _BNCMPLX *cmplxlog_bn(_BNCMPLX *t, _BNCMPLX *s); extern _BNCMPLX *cplxmul_bn( _BNCMPLX *t, _BNCMPLX *x, _BNCMPLX *y); extern _BNCMPLX *cplxdiv_bn( _BNCMPLX *t, _BNCMPLX *x, _BNCMPLX *y); extern _BNCMPLX *ComplexPower_bn(_BNCMPLX *t, _BNCMPLX *xx, _BNCMPLX *yy); extern int MandelbfSetup(void); extern int mandelbf_per_pixel(void); extern int juliabf_per_pixel(void); extern int dividebrot5bf_per_pixel(void); extern int JuliabfFractal(void); extern int JuliaZpowerbfFractal(void); extern int DivideBrot5bfFractal(void); extern _BFCMPLX *cmplxlog_bf(_BFCMPLX *t, _BFCMPLX *s); extern _BFCMPLX *cplxmul_bf( _BFCMPLX *t, _BFCMPLX *x, _BFCMPLX *y); extern _BFCMPLX *cplxdiv_bf( _BFCMPLX *t, _BFCMPLX *x, _BFCMPLX *y); extern _BFCMPLX *ComplexPower_bf(_BFCMPLX *t, _BFCMPLX *xx, _BFCMPLX *yy); /* memory -- C file prototypes */ extern void DisplayMemory (void); extern void DisplayHandle (U16 handle); extern int MemoryType (U16 handle); extern void InitMemory (void); extern void ExitCheck (void); extern U16 MemoryAlloc(U16 size, long count, int stored_at); extern void MemoryRelease(U16 handle); extern int MoveToMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle); extern int MoveFromMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle); extern int SetMemory(int value,U16 size,long count,long offset,U16 handle); /* soi -- C file prototypes */ extern void soi (void); extern void soi_ldbl (void); /* * uclock -- C file prototypes * The uclock_t typedef placed here because uclock.h * prototype is for DOS version only. */ typedef unsigned long uclock_t; extern uclock_t usec_clock(void); extern void restart_uclock(void); extern void wait_until(int index, uclock_t wait_time); #ifndef DEBUG /*#define DEBUG */ #endif #endif xfractint-20.4.10.orig/headers/mpmath.h0000644000000000000000000001574410436745515014604 0ustar /* * REMOVED FORMAL PARAMETERS FROM FUNCTION DEFINITIONS (1/4/92) */ #ifndef MPMATH_H #define MPMATH_H #ifndef _CMPLX_DEFINED #include "cmplx.h" #endif #ifdef XFRACT #define far #endif #ifndef XFRACT struct MP { int Exp; unsigned long Mant; }; #else struct MP { double val; }; #endif struct MPC { struct MP x, y; }; extern int MPOverflow; extern int DivideOverflow; /* Mark Peterson's expanded floating point operators. Automatically uses either the 8086 or 80386 processor type specified in global 'cpu'. If the operation results in an overflow (result < 2**(2**14), or division by zero) the global 'MPoverflow' is set to one. */ /* function pointer support added by Tim Wegner 12/07/89 */ extern int (*pMPcmp)(struct MP , struct MP ); extern struct MP *(*pMPmul)(struct MP , struct MP ); extern struct MP *(*pMPdiv)(struct MP , struct MP ); extern struct MP *(*pMPadd)(struct MP , struct MP ); extern struct MP *(*pMPsub)(struct MP , struct MP ); extern struct MP *(*pd2MP)(double ) ; extern double *(*pMP2d)(struct MP ) ; /*** Formula Declarations ***/ #ifndef XFRACT enum MATH_TYPE { D_MATH, M_MATH, L_MATH }; #else enum MATH_TYPE { D_MATH}; #endif extern enum MATH_TYPE MathType; #define fDiv(x, y, z) (void)((*(long*)&z) = RegDivFloat(*(long*)&x, *(long*)&y)) #define fMul16(x, y, z) (void)((*(long*)&z) = r16Mul(*(long*)&x, *(long*)&y)) #define fShift(x, Shift, z) (void)((*(long*)&z) = \ RegSftFloat(*(long*)&x, Shift)) #define Fg2Float(x, f, z) (void)((*(long*)&z) = RegFg2Float(x, f)) #define Float2Fg(x, f) RegFloat2Fg(*(long*)&x, f) #define fLog14(x, z) (void)((*(long*)&z) = \ RegFg2Float(LogFloat14(*(long*)&x), 16)) #define fExp14(x, z) (void)((*(long*)&z) = ExpFloat14(*(long*)&x)); #define fSqrt14(x, z) fLog14(x, z); fShift(z, -1, z); fExp14(z, z) /* the following are declared 4 dimensional as an experiment */ /* changeing declarations to _CMPLX and _LCMPLX restores the code */ /* to 2D */ union Arg { _CMPLX d; struct MPC m; _LCMPLX l; /* _DHCMPLX dh; _LHCMPLX lh; */ }; struct ConstArg { char *s; int len; union Arg a; }; extern union Arg *Arg1,*Arg2; extern void lStkSin(void),lStkCos(void),lStkSinh(void),lStkCosh(void),lStkLog(void),lStkExp(void),lStkSqr(void); extern void dStkSin(void),dStkCos(void),dStkSinh(void),dStkCosh(void),dStkLog(void),dStkExp(void),dStkSqr(void); extern void (*ltrig0)(void); extern void (*ltrig1)(void); extern void (*ltrig2)(void); extern void (*ltrig3)(void); extern void (*dtrig0)(void); extern void (*dtrig1)(void); extern void (*dtrig2)(void); extern void (*dtrig3)(void); /* -------------------------------------------------------------------- */ /* The following #defines allow the complex transcendental functions */ /* in parser.c to be used here thus avoiding duplicated code. */ /* -------------------------------------------------------------------- */ #ifndef XFRACT #define CMPLXmod(z) (sqr((z).x)+sqr((z).y)) #define CMPLXconj(z) ((z).y = -((z).y)) #define LCMPLXmod(z) (lsqr((z).x)+lsqr((z).y)) #define LCMPLXconj(z) ((z).y = -((z).y)) #define LCMPLXtrig0(arg,out) Arg1->l = (arg); ltrig0(); (out)=Arg1->l #define LCMPLXtrig1(arg,out) Arg1->l = (arg); ltrig1(); (out)=Arg1->l #define LCMPLXtrig2(arg,out) Arg1->l = (arg); ltrig2(); (out)=Arg1->l #define LCMPLXtrig3(arg,out) Arg1->l = (arg); ltrig3(); (out)=Arg1->l #endif /* XFRACT */ #define CMPLXtrig0(arg,out) Arg1->d = (arg); dtrig0(); (out)=Arg1->d #define CMPLXtrig1(arg,out) Arg1->d = (arg); dtrig1(); (out)=Arg1->d #define CMPLXtrig2(arg,out) Arg1->d = (arg); dtrig2(); (out)=Arg1->d #define CMPLXtrig3(arg,out) Arg1->d = (arg); dtrig3(); (out)=Arg1->d #ifndef XFRACT #define LCMPLXsin(arg,out) Arg1->l = (arg); lStkSin(); (out) = Arg1->l #define LCMPLXcos(arg,out) Arg1->l = (arg); lStkCos(); (out) = Arg1->l #define LCMPLXsinh(arg,out) Arg1->l = (arg); lStkSinh(); (out) = Arg1->l #define LCMPLXcosh(arg,out) Arg1->l = (arg); lStkCosh(); (out) = Arg1->l #define LCMPLXlog(arg,out) Arg1->l = (arg); lStkLog(); (out) = Arg1->l #define LCMPLXexp(arg,out) Arg1->l = (arg); lStkExp(); (out) = Arg1->l /* #define LCMPLXsqr(arg,out) Arg1->l = (arg); lStkSqr(); (out) = Arg1->l */ #define LCMPLXsqr(arg,out) \ (out).x = lsqr((arg).x) - lsqr((arg).y);\ (out).y = multiply((arg).x, (arg).y, bitshiftless1) #define LCMPLXsqr_old(out) \ (out).y = multiply(lold.x, lold.y, bitshiftless1);\ (out).x = ltempsqrx - ltempsqry #define LCMPLXpwr(arg1,arg2,out) Arg2->l = (arg1); Arg1->l = (arg2);\ lStkPwr(); Arg1++; Arg2++; (out) = Arg2->l #define LCMPLXmult(arg1,arg2,out) Arg2->l = (arg1); Arg1->l = (arg2);\ lStkMul(); Arg1++; Arg2++; (out) = Arg2->l #define LCMPLXadd(arg1,arg2,out) \ (out).x = (arg1).x + (arg2).x; (out).y = (arg1).y + (arg2).y #define LCMPLXsub(arg1,arg2,out) \ (out).x = (arg1).x - (arg2).x; (out).y = (arg1).y - (arg2).y #define LCMPLXtimesreal(arg,real,out) \ (out).x = multiply((arg).x,(real),bitshift);\ (out).y = multiply((arg).y,(real),bitshift) #define LCMPLXrecip(arg,out) \ { long denom; denom = lsqr((arg).x) + lsqr((arg).y);\ if(denom==0L) overflow=1; else {(out).x = divide((arg).x,denom,bitshift);\ (out).y = -divide((arg).y,denom,bitshift);}} #endif /* XFRACT */ #define CMPLXsin(arg,out) Arg1->d = (arg); dStkSin(); (out) = Arg1->d #define CMPLXcos(arg,out) Arg1->d = (arg); dStkCos(); (out) = Arg1->d #define CMPLXsinh(arg,out) Arg1->d = (arg); dStkSinh(); (out) = Arg1->d #define CMPLXcosh(arg,out) Arg1->d = (arg); dStkCosh(); (out) = Arg1->d #define CMPLXlog(arg,out) Arg1->d = (arg); dStkLog(); (out) = Arg1->d #define CMPLXexp(arg,out) FPUcplxexp(&(arg), &(out)) /* #define CMPLXsqr(arg,out) Arg1->d = (arg); dStkSqr(); (out) = Arg1->d */ #define CMPLXsqr(arg,out) \ (out).x = sqr((arg).x) - sqr((arg).y);\ (out).y = ((arg).x+(arg).x) * (arg).y #define CMPLXsqr_old(out) \ (out).y = (old.x+old.x) * old.y;\ (out).x = tempsqrx - tempsqry #define CMPLXpwr(arg1,arg2,out) (out)= ComplexPower((arg1), (arg2)) #define CMPLXmult1(arg1,arg2,out) Arg2->d = (arg1); Arg1->d = (arg2);\ dStkMul(); Arg1++; Arg2++; (out) = Arg2->d #define CMPLXmult(arg1,arg2,out) \ {\ _CMPLX TmP;\ TmP.x = (arg1).x*(arg2).x - (arg1).y*(arg2).y;\ TmP.y = (arg1).x*(arg2).y + (arg1).y*(arg2).x;\ (out) = TmP;\ } #define CMPLXadd(arg1,arg2,out) \ (out).x = (arg1).x + (arg2).x; (out).y = (arg1).y + (arg2).y #define CMPLXsub(arg1,arg2,out) \ (out).x = (arg1).x - (arg2).x; (out).y = (arg1).y - (arg2).y #define CMPLXtimesreal(arg,real,out) \ (out).x = (arg).x*(real);\ (out).y = (arg).y*(real) #define CMPLXrecip(arg,out) \ { double denom; denom = sqr((arg).x) + sqr((arg).y);\ if(denom==0.0) {(out).x = 1.0e10;(out).y = 1.0e10;}else\ { (out).x = (arg).x/denom;\ (out).y = -(arg).y/denom;}} #define CMPLXneg(arg,out) (out).x = -(arg).x; (out).y = -(arg).y #endif xfractint-20.4.10.orig/fractsrc.txt0000644000000000000000000004217710616226653014077 0ustar The source code for Fractint is freely available. Enhancements to it are appreciated. If you want to add something to Fractint and join the Stone Soup Group, please do! To submit changes, see "Contacting the Authors" in Fractint's online help. Copyright Information: ====================== Some parts of the source are from the public domain and are not copyrighted. Some parts of the source bear explicit copyright notices from the author and are subject to the conditions listed there by the author. The remainder of the source (not already public domain, no explicit author's copyright notice) is Copyright 1990, 1991 by the Stone Soup Group (a loosely associated and ever-growing group of fanatic programmers). The source code may be copied freely and may be used in other programs under the following conditions: It may not be used in a commercial program which produces fractal images. Please credit the author (in general, credit Fractint and the Stone Soup Group) as the source of the code. Distribution of modified versions of Fractint: ============================================== If you enhance Fractint and want to distribute the results to others, the preferred approach is to join the Stone Soup Group - send us your enhancements and get your name in lights in future versions of Fractint. We prefer that a modified Fractint executable program not be distributed to others, but understand that you might want to give copies to friends. This is permitted, under the following conditions: o The modified executable has a different name than "fractint.exe". o The distribution includes a full unmodified copy of the corresponding original version of fraint.exe. (The easiest way is to copy fraint.exe to yournew.exe, then "pkzip -a fraint.exe newfract.exe" to add your version, and perhaps add a read.me file to describe it.) o The heading displayed by the modified program clearly indicates that it is a non-standard release. E.g. you might change the heading to say "Non-standard Fractint, Modified by John Doe". o All author credits and distribution information in the online help are unchanged (adding lines for your work is of course ok.) The source code for a modified version of Fractint may not be distributed. (This is because we don't want any chance of confusion over which version of a source file is the official release.) Compiling Fractint: =================== FRASRC.EXE includes the complete source code for FRACTINT (.C and .ASM). Recognizing that not everyone HAS (or even wants) an assembler, much less either MASM 5.1 or Turbo-ASM, which are the only two assemblers that the authors are aware of that can handle these particular files, it also contains a complete set of .OBJ files from the assembler code, The distributed source will not compile to exactly match the Fractint release - it compiles with a different version number and heading. The Microsoft 6.00A C compiler and Microsoft 5.1 assembler are used for Fractint releases, so that is the one combination of compiler/assembler which is pretty much guaranteed to handle FRACTINT in all of its various mutations. Given that several of FRACTINT's co-authors now prefer (or only have!) alternate combinations, we have re-arranged the code to (usually) handle several popular alternatives. In particular: Microsoft C 6.00A and MASM 5.1: ------------------------------- Just run MAKEFRAC.BAT, which invokes the Microsoft NMK utility using the files FRACHELP.MAK, FRACTINT.MAK, and FRACTINT.LNK. Note that the assembler .OBJ files have been included in the .ZIP file, so that you don't really need MASM unless you are going to modify one or more of them. If you ARE going to modify one of the assembler files, note that the distributed versions rely on some nifty features added to version 5.1 (like the '.model medium,c' option) and will not assemble under older versions of MASM without a LOT of work. Note that C 6.00 (the original release) had some problems. We never used it for a Fractint release. If you don't have the fixed version (6.00A) you should compile parser.c, loadfile.c, and calcfrac.c with no optimization, using the /qc option. There might be other problems, those are the only ones we're aware of... Warning: FRACTINT.MAK uses C6.00A's most aggressive optimizations. It is assumed there is no aliasing. See Microsoft's documentation on the /Oa and /Oz options. Microsoft C 5.1: ---------------- Edit MAKEFRAC.BAT: comment out the two "nmk ..." lines and uncomment the lines for C5.1. Then run MAKEFRAC. Quick-C: -------- FRACTINT is just too big for the interactive Quick-C (QC) environment. You have to use the command-line variant of Quick-C (QCL). Edit MAKEFRAC.BAT: comment out the two "nmk ..." lines and uncomment the lines for QuickC. Then run MAKEFRAC. We're not sure all versions of QuickC work. 2.01 works as of Fractint version 16. Depending on how much memory you have available, you may have to manually compile some modules without the /O option. Turbo-C, Turbo-C++ and TASM --------------------------- Sorry, Turbo-C fans, but since version 14.0, FRACTINT requires TC++. The lack of initialized FAR arrays and structures just did the older Turbo-C product in. The *good* news is that some of the FRACTINT authors now use Turbo-C++, so the odds of released FRACTINT distributions that do not compile with Turbo products are lower than they used to be. A TCFRACT.PRJ and TCHELP.PRJ file is included for Turbo-C users. You should rename these to FRACTINT.PRJ and HC.PRJ before compiling fractint. With TC++ you'll have to do a manual step for the help system each time you create a new fractint.exe - see notes in next section. Borland C++ 3.0 and 3.1 Users ----------------------------- Rename the BCFRACT.PRJ and BCHELP.PRJ files to FRACTINT.PRJ and HC.PRJ. The project file will generate the FRACTINT.HLP file, but you will still have to run "hc /a" from the DOS command line to append the help information. Help System =========== You'll need to set up the help files to get any online help from a modified version of Fractint. For MSC users the MAKEFRAC.BAT file contains the necessary steps, you don't need to do anything special. TC++ users should: start by creating HC.EXE using the supplied HC.PRJ file run "hc /c" to create the file FRACTINT.HLP each time you create a new fractint.exe, afterward run "hc /a" to append FRACTINT.HLP to the new FRACTINT.EXE You don't need to understand the rest of this section unless you have a problem. The source for Fractint's help is in the files HELP.SRC, HELP2.SRC, HELP3.SRC, HELP4.SRC, and HELP5.SRC. The format of these files is described in HC.DOC. The program HC.C ("help compiler") is used to convert the help text into the form Fractint uses at run time. Running "hc /c" compiles HELPx.SRC. It produces the file HELPDEFS.H for use when compiling Fractint, and the file FRACTINT.HLP. Running "hc /a" appends the FRACTINT.HLP file to FRACTINT.EXE to make the compiled help info available at run time. Overlays ======== Note: generally you won't have to worry about this! Only the addition of huge code (new overlays), or work which changes the relationship between major components of Fractint, are likely to affect the overlay structure. However, if you make changes in a module which has a comment at the start saying it is an overlay, please follow the guidelines for use of ENTER_OVLY and EXIT_OVLY described after the next paragraph. Fractint uses the Microsoft Link overlay feature, to reduce the runtime memory required (which would otherwise exceed what DOS can give it.) Some caution is required with overlays. Those source modules which are part of an overlay have a comment to indicate this at the start. See the fractint.lnk file for the current overlay structure. Some notes about overlays: o The obvious one: control should not switch to different overlays frequently, else Fractint will become sluggish. If the overlay structure changes, a test from floppy disk with no disk caching is a good idea. o The linker cannot detect indirect calls (e.g. thing=routinename; (*thing)();) to an overlay. Routines in overlays should not be called indirectly, except from within the same overlay. o The overlay manager logic (inserted by the linker) does handle calls from within one overlay to another - the new overlay is brought in from disk (displacing the old one in memory), when the subroutine finishes the old overlay is brought back into memory. o The overlay manager logic does not handle situations like the following: overlayA calls residentB(), which calls overlayC(). OverlayC is loaded and executed ok, eventually control returns to residentB ok, BUT the return from there to overlayA does NOT reload overlayA! Fractint has constructs called ENTER_OVLY and EXIT_OVLY to circumvent this problem. Guidelines for routines in overlayed modules: o If the routine is local, declare it "static" to ensure this and to make analysis of relationships among overlays easier. o If the routine is called from external code (resident, or in another overlay), the first executable line in the routine must be: ENTER_OVLY(OVLY_XXX); /* XXX is the module name */ Each "return" from the routine (incl. the implicit one at the end) must be preceded by: EXIT_OVLY; o When creating a new overlay XXX, add a new OVLY_XXX value to Fractint: Fractint.h has a define for each OVLY_XXX value. Miscres.c has a routine "restore_active_ovly" which needs a new line for OVLY_XXX. The source module needs a dummy routine "xxx_overlay". Where the Goodies are ===================== It has come to our attention that people who have no interest in fractals at all have been wandering through the FRACTINT source code just to get at some of the neat tricks buried therein. Here are a few hints as to where to look: FRACTINT.C - The main routine. Nothing special here. FRACTINT.H - General Include file. Nothing special here, either. FRACTYPE.H - Fractal type-specific Include file. PROMPTS.C - The full-screen prompting code (using support routines in VIDEO.ASM) CMDFILES.C - Command line and sstools.ini parsing. FRACTALS.C, - Most of the fractal-specific code. If you want to know CALCFRAC.C, how a fractal is calculated, look in here. Specific FRACSUBR.C speed-em-up support for special fractal types is in: FRACSUBA.ASM CALCMAND.ASM - Mandelbrot/Julia set calculations. NEWTON.ASM - Newton calculations LORENZ.C - Attractor fractals and IFS JB.C - "Julibrot" fractal type calculations TESTPT.C - "Roll-your-own" fractal routine MPMATH_C.C, - Mark Peterson's "fast-math" support routines. MPMATH_A.ASM, (this stuff puts some of the routines supplied by your FPU387.ASM, favorite "C" compiler to shame!) FPU087.ASM, ... FMATH.H, ... MPMATH.H ... PARSER.C - The "type=formula" formula parser routines LSYS.C - L-Systems code VIDEO.ASM - Assembler code containing all of the video routines (setting up the video, reading/writing pixels, zoom-box code, color-cycling, graphics-to-text "help" switch, ... with help from the routines below for special adapters: LOADMAP.C - Load .map files. TARGA.C, - TARGA Video Routines TARGA.H, ... FR8514A.ASM - 8514/A Routines TPLUS.C - Targa+ video routines TPLUS.H ... TPLUS_A.ASM ... HGCFRA.ASM - Hercules Video Routines DISKVID.C - "DISK'RAM" video routines YOURVID.C - "Roll-your-own" video routines GENERAL.ASM - General assembler code having nothing to do with fractals. Lots of the tricky stuff is in here, and many of the "C" routines that perform tricky functions rely on support code buried in here. In particular, this routine has the: CPU, FPU Detectors Keyboard routines Mouse routines Expanded memory routines 32-bit scaled integer multiply and divide routines ENCODER.C - GIF Encoder routine. GIFVIEW.C, - GIF Decoder routines. DECODER.C, TGAVIEW.C, (including a TARGA-format decoder currently used only for F16.C, loading obsolete .tga format "Continuous Potential" files) TARGA_LC.H ... LOADFILE.C - Loads the Fractint parameter info from a GIF file. LOADFDOS.C subroutines for DOS Fractint only LINE3D.C, - 3D manipulation routines 3D.C PLOT3D - 3D subroutines for LINE3D.C and LORENZ.C ROTATE.C - routines which "spin" the VGA video-DAC. EDITPAL.C - palette-editing mode HELP.C - HELP support INTRO.C - title screen ZOOM.C - Zoombox manipulation. PRINTER.C, - The Printer Routines PRINTERA.ASM Data used by PRINTER.C MISCRES.C - Miscellaneous resident subroutines; nothing special. MISCOVL.C - Miscellaneous overlayed subroutines; includes atch command. REALDOS.C - Some subroutines isolated from Windows development work; nothing special in here. PORT.H - Some portability stuff, nothing special here. How things are set up ===================== I've had to go through a lot of the code to figure out how things are set up. These are my rough notes, which I'm including in case they can help someone else. -- Ken Shirriff The control flow is very confusing. Here are some details: Each fractal type has an entry in the fractalspecific table in fractalp.c. Entries that are not displayed are marked with an asterisk. Each entry is marked as int or not int, and either has a pointer to another entry (tofloat) or NOFRACTAL. If you select float and the type is int or vice versa, you will end up with the tofloat type. (e.g. If you select entry MANDEL, and select floating point, you will get entry MANDELFP). There are also pointers tojulia and tomandel, which allow you to switch between mandel and julia. The four functions listed are curfractalspecific->orbitcalc, curfractalspecific->per_pixel, curfractalspecific->per_image, and curfractalspecific->calctype. main calls calcfracinit. calcfractint: this sets up curfractalspecific, which is the appropriate entry from the fractalspecific table. This routine does the int/float conversion. main calls calcfract, which calls timer, which calls perform_worklist perform_worklist calls curfractalspecific->per_image, which is eg. MandelSetup MandelSetup: sets calctype to curfractalspecific->calctype, or for special cases (eg. decomposition) to StandardFractal perform_worklist calls solidguess (or whatever drawing system) solidguess calls *calctype for each pixel; calctype is eg. StandardFractal StandardFractal calls curfractalspecific->per_pixel once, and then loops over each iteration calling curfractalspecific->orbitcalc. These routines are eg. mandel_per_pixel and JuliaFractal. Here is the structure of the main routine: main() { initialize things restorestart: if loading, look after specifying image imagestart: while (adapter<0) { process keys from short main menu } while (1) { if (calc_status != 2 || showfile==0) { initialize videoentry from videotable[adapter] initialize size, color, etc. from videoentry setvideomode() } if (showfile==0) { load file } calcfracinit(); save corners, zoom data if (showfile != 0) { calcfract(); /* calculates the fractal until interrupted */ } resumeloop: if (no key pressed) { set keypress = 13 to continue } else if (key pressed) { check input key } else if (batch mode) { look after batch key } process key from long menu } } How the video entries are managed: get_video_mode(fractal_info): This routine is used to select a video mode to match a picture we're loading. It loads vidtbl and then tries to find a video mode that matches that in fractal_info. Asks the user to select one if there's no good match. Figures out how to reduce the image to fit the screen. select_video_mode(curmode): This is the main-menu routine for the user to pick a video mode. picks default video mode, lets user select mode from menu, copies entry to videoentry, puts entry in videotable if not there, calls update_fractint_cfg if key reassigned, returns key corresponding to mode check_vidmode_key(option, keypress): if keypress corresponds to a videomode in videotable (for option 0) or vidtbl (for option 1) return the videomode index, else -1. check_vidmode_keyname: converts ascii key name into key number adapter_detect: checks for type of video (ega, cga, etc) and set video_type, mode7text, textsafe. load_videotable: reads the entries in fractint.cfg into vidtbl copies entries with an associated function key into videotable load_fractint_cfg: reads video modes in fractint.cfg into vidtbl (or copies from videotable) if fractint.cfg missing or bad update_fractint_cfg: writes the entry in videoentry into the fractint.cfg file. vidtbl: contains the video modes from fractint.cfg videotable: contains video modes with function keys; initialized in video.asm video_type: contains type: hgc, egc, cga, mcga Here is how the floating point modes are set up. parser.c uses the MathTypes: D_MATH: uses double precision routines, such as dStkMul, and FPUsincos This is used if we have a fpu. M_MATH: uses MP type (mantissa, exponent). These routines such as mStkAdd call MPCadd, which call pMPadd, which calls MPadd086 or MPadd386. The MP routines work on multiple precision, MPC works on complex pairs of multiple precision. L_MATH: uses integer math. Routines such as lStkAdd. xfractint-20.4.10.orig/formulas/0000755000000000000000000000000011456314750013343 5ustar xfractint-20.4.10.orig/formulas/newton.frm0000644000000000000000000000053510150633601015353 0ustar Newton_poly { ; Tim Wegner - use float=yes ; fractal generated by Newton formula z^3 - 3z z = pixel, z2 = z*z, z3 = z*z2: z = (2*z3) / (3*z2 - 3); z2 = z*z; z3 = z*z2, .004 <= |z3 - 3*z| } newtz3 { ; Note use floating point z = pixel: z2 = z * z, z3 = z2 * z, z = (2 * z3) / (3 * (z2 - 1)), 0.004 <= |z3 - 3 * z| } xfractint-20.4.10.orig/formulas/fractint.frm0000644000000000000000000010725410627420161015665 0ustar comment { This iteration of FRACTINT.FRM was first released with Fractint 19.0 The formulas at the beginning of this file are from Mark Peterson, who built this fractal interpreter feature. The rest are grouped by contributor. Formulas by unidentified authors are grouped at the end. If you would like to contribute formulas for future versions of this file, please contact one of the authors listed in FRACTINT.DOC. All contributions are assumed to belong to the public domain. There are several hard-coded restrictions in the formula interpreter: 1) The fractal name through the open curly bracket must be on a single line. 2) There is a hard-coded limit of 2000 formulas per formula file, only because of restrictions in the prompting routines. 3) Formulas can contain at most 250 operations (references to variables and arithmetic); this is bigger than it sounds. 4) Comment blocks can be set up using dummy formulas with no formula name or with the special name "comment". Note that the builtin "cos" function had a bug which was corrected in version 16. To recreate an image from a formula which used cos before v16, change "cos" in the formula to "cosxx" which is a new function provided for backward compatibility with that bug. } {--- MARK PETERSON -------------------------------------------------------} Mandelbrot(XAXIS) {; Mark Peterson ; Classical fractal showing LastSqr speedup z = Pixel, z = Sqr(z): ; Start with z**2 to initialize LastSqr z = z + Pixel z = Sqr(z) LastSqr <= 4 ; Use LastSqr instead of recalculating } Dragon (ORIGIN) {; Mark Peterson z = Pixel: z = sqr(z) + (-0.74543, 0.2) |z| <= 4 } Daisy (ORIGIN) {; Mark Peterson z = pixel: z = z*z + (0.11031, -0.67037) |z| <= 4 } InvMandel (XAXIS) {; Mark Peterson c = z = 1 / pixel: z = sqr(z) + c |z| <= 4 } DeltaLog(XAXIS) {; Mark Peterson z = pixel, c = log(pixel): z = sqr(z) + c |z| <= 4 } Newton4(XYAXIS)[float=y] {; Mark Peterson ; Note that floating-point is required to make this compute accurately z = pixel, Root = 1: z3 = z*z*z z4 = z3 * z z = (3 * z4 + Root) / (4 * z3) .004 <= |z4 - Root| } {--- DON ARCHER ----------------------------------------------------------} DAFRM01 {; Don Archer, 1993 z = pixel : z = z ^ (z - 1) * (fn1(z) + pixel) |z| <= 4 } DAFRM07 { z = pixel, c = p1 : z = z ^ (z - 1) * fn1(z) + pixel |z| <= 4 } DAFRM09 { z = pixel, c = z + z^ (z - 1): tmp = fn1(z) real(tmp) = real(tmp) * real(c) - imag(tmp) * imag(c) imag(tmp) = real(tmp) * imag(c) - imag(tmp) * real(c) z = tmp + pixel + 12 |z| <= 4 } dafrm21 { z = pixel: x = real(z), y = imag(z) x1 = -fn1((x*x*x + y*y*y - 1) - 6*x)*x/(2*x*x*x + y*y*y - 1) y1 = -fn2((x*x*x + y*y*y - 1) + 6*x)*y/(2*x*x*x + y*y*y - 1) x2 = x1*x1*x1 - y1*y1*y1 + p1 + 5 y2 = 4*x*y - 18 z = x2 + flip(y2) |z| <= 100 } 3daMand01 {; Mandelbrot/Zexpe via Lee Skinner ; based on 4dFRACT.FRM by Gordon Lamb (CIS: 100272,3541) z=real(pixel)+flip(imag(pixel)*p1) c=p2+p1*real(pixel)+flip(imag(pixel)): z=z^2.71828182845905 + c |z|<=100 } 3daMand02 {; Mandelbrot/Xexpe/Feigenbaum's alpha constant=exponent ; based on 4dFRACT.FRM by Gordon Lamb (CIS: 100272,3541) z=real(pixel)+flip(imag(pixel)*p1) c=p2+p1*real(pixel)+flip(imag(pixel)): z=z^2.502907875095 + c |z|<=100 } {--- RON BARNETT ---------------------------------------------------------} Julike { ; Ron Barnett, 1993 ; a Julia function based upon the Ikenaga function z = Pixel: z = z*z*z + (P1-1)*z - P1 |z| <= 4 } Mask [float=y] { ; Ron Barnett, 1993 ; try fn1 = log, fn2 = sinh, fn3 = cosh ;P1 = (0,1), P2 = (0,1) ;Use floating point z = fn1(pixel): z = P1*fn2(z)^2 + P2*fn3(z)^2 + pixel |z| <= 4 } JMask { ; Ron Barnett, 1993 z = fn1(pixel): z = P1*fn2(z)^2 + P2 |z| <= 4 } PseudoZeePi {; Ron Barnett, 1993 z = pixel: x = 1-z^p1; z = z*((1-x)/(1+x))^(1/p1) + p2 |z| <= 4 } ZeePi { ; Ron Barnett, 1993 ; This Julia function is based upon Ramanujan's iterative ; function for calculating pi z = pixel: x = (1-z^p1)^(1/p1) z = z*(1-x)/(1+x) + p2 |z| <= 4 } IkeNewtMand {; Ron Barnett, 1993 z = c = pixel: zf = z*z*z + (c-1)*z - c zd = 3*z*z + c-1 z = z - p1*zf/zd 0.001 <= |zf| } Frame-RbtM(XAXIS) {; Ron Barnett, 1993 ; from Mazes for the Mind by Pickover z = c = pixel: z = z*z*z/5 + z*z + c |z| <= 100 } FrRbtGenM {; Ron Barnett, 1993 z = pixel: z = p1*z*z*z + z*z + pixel |z| <= 100 } FlipLambdaJ { ; Ron Barnett, 1993 z = pixel: z = p1*z*(1-flip(z)*flip(z)) |z| <= 100 } REBRefInd2[float=y] { ; Ron Barnett, 1993 ; Use floating point z = pixel: z = (z*z-1)/(z*z+2)*fn1(z)*fn2(z) + p1 |z| <= 100 } GopalsamyFn { z = pixel: x = real(z), y = imag(z) x1 = fn1(x)*fn2(y) y1 = fn3(x)*fn4(y) x2 = -2*x1*y1 + p1 y = y1*y1 - x1*x1 z = x2 + flip(y) |z| <= 100 } REB004A {; Ron Barnett, 1993 z = pixel: z =p1*fn1(z) + p1*p1*fn2(p2*z) + pixel |z| <= 100 } REB004K[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = flip(pixel + fn1(3/z - z/4)) z = x*z + p1 |z| <= 100 } REB004L[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = flip(pixel + fn1(p1/z - z/(p2+1))) z = x*z + pixel |z| <= 100 } REB004M[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = real(z), y = imag(z) const = x*x + y*y x1 = -fn1(const - 12*x)*x/(4*const) y1 = -fn2(const + 12*x)*y/(4*const) x2 = x1*x1 - y1*y1 + p1 y2 = 2*x*y z = x2 + flip(y2) |z| <= 100 } REB005A[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = real(z), y = imag(z) const = x*x + y*y x1 = -fn1(const - 12*x)*x/(4*const) y1 = -fn2(const + 12*y)*y/(4*const) x2 = x1*x1 - y1*y1 + p1 y2 = 2*x1*y1 z = x2 + flip(y2) |z| <= 100 } REB005E[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = real(z), y = imag(z) const = x*x + y*y x1 = -fn1((const - x)*x/const) y1 = -fn2((const + y)*y/const) x2 = x1*x1 - y1*y1 + p1 y2 = 2*x1*y1 z = x2 + flip(y2) |z| <= 100 } REB005F[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = real(z), y = imag(z) const = x*x + y*y x1 = -fn1((const - 12*x)*x/(4*const)) y1 = -fn2((const + 12*y)*y/(4*const)) x2 = x1*x1 - y1*y1 + p1 y2 = 2*x1*y1 z = x2 + flip(y2) |z| <= 100 } REB005G[float=y] {; Ron Barnett, 1993 ; floating point required z = pixel: x = real(z), y = imag(z) const = x*x + y*y x1 = -fn1(const + p1*x)*y/const y1 = -fn2(const + y)*x/const x2 = x1*x1 - y1*y1 + p2 y2 = 2*x1*y1 z = x2 + flip(y2) |z| <= 100 } {--- BRADLEY BEACHAM -----------------------------------------------------} OK-01 { ;TRY P1 REAL = 10000, FN1 = SQR z = 0, c = pixel: z = (c^z) + c z = fn1(z) |z| <= (5 + p1) } OK-04 { ;TRY FN2 = SQR, DIFFERENT FUNCTIONS FOR FN1 z = 0, c = fn1(pixel): z = fn2(z) + c |z| <= (5 + p1) } OK-08 { z = pixel, c = fn1(pixel): z = z^z / fn2(z) z = c / z |z| <= (5 + p1) } OK-21 { z = pixel, c = fn1(pixel): z = fn2(z) + c fn3(z) <= p1 } OK-22 { z = v = pixel: v = fn1(v) * fn2(z) z = fn1(z) / fn2(v) |z| <= (5 + p1) } OK-32 { z = y = x = pixel, k = 1 + p1: a = fn1(z) b = (a <= y) * ((a * k) + y) e = (a > y) * ((a * k) + x) x = y y = z z = b + e |z| <= (5 + p2) } OK-34 { z = pixel, c = (fn1(pixel) * p1): x = abs(real(z)) y = abs(imag(z)) a = (x <= y) * (fn2(z) + y + c) b = (x > y) * (fn2(z) + x + c) z = a + b |z| <= (10 + p2) } OK-35 { z = pixel, k = 1 + p1: v = fn1(z) x = (z*v) y = (z/v) a = (|x| <= |y|) * ((z + y) * k) b = (|x| > |y|) * ((z + x) * k) z = fn2((a + b) * v) + v |z| <= (10 + p2) } OK-36 { ; DISSECTED MANDELBROT ; TO GENERATE "STANDARD" MANDELBROT, SET P1 = 0,0 & ALL FN = IDENT z = pixel, cx = fn1(real(z)), cy = fn2(imag(z)), k = 2 + p1: zx = real(z), zy = imag(z) x = fn3(zx*zx - zy*zy) + cx y = fn4(k * zx * zy) + cy z = x + flip(y) |z| < (10 + p2) } OK-38 { ; DISSECTED CUBIC MANDELBROT ; TO GENERATE "STANDARD" CUBIC MANDELBROT, SET P1 = 0,0 & ALL FN = IDENT z = pixel, cx = fn1(real(pixel)), cy = fn2(imag(pixel)), k = 3 + p1: zx = real(z), zy = imag(z) x = fn3(zx*zx*zx - k*zx*zy*zy) + cx y = fn4(k*zx*zx*zy - zy*zy*zy) + cy z = x + flip(y) |z| < (4 + p2) } OK-42 { ; MUTATION OF FN + FN z = pixel, p1x = real(p1)+1, p1y = imag(p1)+1 p2x = real(p2)+1, p2y = imag(p2)+1: zx = real(z), zy = imag(z) x = fn1(zx*p1x - zy*p1y) + fn2(zx*p2x - zy*p2y) y = fn3(zx*p1y + zy*p1x) + fn4(zx*p2y + zy*p2x) z = x + flip(y) |z| <= 20 } OK-43 { ; DISSECTED SPIDER ; TO GENERATE "STANDARD" SPIDER, SET P1 = 0,0 & ALL FN = IDENT z = c = pixel, k = 2 + p1: zx = real(z), zy = imag(z) cx = real(c), cy = imag(c) x = fn1(zx*zx - zy*zy) + cx y = fn2(k*zx*zy) + cy z = x + flip(y) c = fn3((cx + flip(cy))/k) + z |z| < (10 + p2) } Larry { ; Mutation of 'Michaelbrot' and 'Element' ; Original formulas by Michael Theroux [71673,2767] ; For 'Michaelbrot', set FN1 & FN2 =IDENT and P1 & P2 = default ; For 'Element', set FN1=IDENT & FN2=SQR and P1 & P2 = default ; p1 = Parameter (default 0.5,0), real(p2) = Bailout (default 4) z = pixel ; The next line sets c=default if p1=0, else c=p1 c = ((0.5,0) * (|p1|<=0) + p1) ; The next line sets test=4 if real(p2)<=0, else test=real(p2) test = (4 * (real(p2)<=0) + real(p2) * (0=|0.01| } F'M-SetInNewtonA(XAXIS)[float=y] {; use float=yes ; jon horner 100112,1700, 12 feb 93 z = 0, c = fn1(pixel), cminusone = c-1: oldz = z, nm = p1*c-2*z*cminusone, dn = p1*(3*z*z+cminusone) z = nm/dn+2*z/p1 |(z-oldz)|>=|0.01| } F'M-SetInNewtonC(XAXIS)[float=y periodicity=0] { ; same as F'M-SetInNewtonB except for bailout ; use float=yes, periodicity=no ; (3 <= p1 <= ?) and (1e-30 < p2 < .01) z=0, c=fn1(pixel), cm1=c-1, cm1x2=cm1*2, twoop1=2/p1, p1xc=c*real(p1): z = (p1xc - z*cm1x2 )/( (sqr(z)*3 + cm1 ) * real(p1) ) + z*real(twoop1) abs(|z| - real(lastsqr) ) >= p2 } {--- CHRIS GREEN ---------------------------------------------------------} comment { These fractals all use Newton's or Halley's formula for approximation of a function. In all of these fractals, p1 real is the "relaxation coefficient". A value of 1 gives the conventional newton or halley iteration. Values <1 will generally produce less chaos than values >1. 1-1.5 is probably a good range to try. P1 imag is the imaginary component of the relaxation coefficient, and should be zero but maybe a small non-zero value will produce something interesting. Who knows? For more information on Halley maps, see "Computers, Pattern, Chaos, and Beauty" by Pickover. } Halley (XYAXIS) [float=y] {; Chris Green. Halley's formula applied to x^7-x=0. ; P1 real usually 1 to 1.5, P1 imag usually zero. Use floating point. ; Setting P1 to 1 creates the picture on page 277 of Pickover's book z=pixel: z5=z*z*z*z*z z6=z*z5 z7=z*z6 z=z-p1*((z7-z)/ ((7.0*z6-1)-(42.0*z5)*(z7-z)/(14.0*z6-2))) 0.0001 <= |z7-z| } CGhalley (XYAXIS) [float=y] {; Chris Green -- Halley's formula ; P1 real usually 1 to 1.5, P1 imag usually zero. Use floating point. z=(1,1): z5=z*z*z*z*z z6=z*z5 z7=z*z6 z=z-p1*((z7-z-pixel)/ ((7.0*z6-1)-(42.0*z5)*(z7-z-pixel)/(14.0*z6-2))) 0.0001 <= |z7-z-pixel| } halleySin (XYAXIS) [float=y] {; Chris Green. Halley's formula applied to sin(x)=0. ; Use floating point. ; P1 real = 0.1 will create the picture from page 281 of Pickover's book. z=pixel: s=sin(z), c=cos(z) z=z-p1*(s/(c-(s*s)/(c+c))) 0.0001 <= |s| } NewtonSinExp (XAXIS) [float=y] {; Chris Green ; Newton's formula applied to sin(x)+exp(x)-1=0. ; Use floating point. z=pixel: z1=exp(z) z2=sin(z)+z1-1 z=z-p1*z2/(cos(z)+z1) .0001 < |z2| } CGNewtonSinExp (XAXIS) { z=pixel: z1=exp(z) z2=sin(z)+z1-z z=z-p1*z2/(cos(z)+z1) .0001 < |z2| } CGNewton3 [float=y] {; Chris Green -- A variation on newton iteration. ; The initial guess is fixed at (1,1), but the equation solved ; is different at each pixel ( x^3-pixel=0 is solved). ; Use floating point. ; Try P1=1.8. z=(1,1): z2=z*z z3=z*z2 z=z-p1*(z3-pixel)/(3.0*z2) 0.0001 < |z3-pixel| } HyperMandel [float=y] {; Chris Green. ; A four dimensional version of the mandelbrot set. ; Use P1 to select which two-dimensional plane of the ; four dimensional set you wish to examine. ; Use floating point. a=(0,0),b=(0,0): z=z+1 anew=sqr(a)-sqr(b)+pixel b=2.0*a*b+p1 a=anew |a|+|b| <= 4 } OldHalleySin (XYAXIS) { z=pixel: s=sin(z) c=cosxx(z) z=z-p1*(s/(c-(s*s)/(c+c))) 0.0001 <= |s| } {--- RICHARD HUGHES ------------------------------------------------------} phoenix_m { ; Mandelbrot style map of the Phoenix curves z=x=y=nx=ny=x1=y1=x2=y2=0: x2 = sqr(x), y2 = sqr(y) x1 = x2 - y2 + real(pixel) + imag(pixel) * nx y1 = 2 * x * y + imag(pixel) * ny nx=x, ny=y, x=x1, y=y1, z=x + flip(y) |z| <= 4 } {--- GORDON LAMB ---------------------------------------------------------} SJMAND01 {;Mandelbrot z=real(pixel)+flip(imag(pixel)*p1) c=p2+p1*real(pixel)+flip(imag(pixel)): z=z*z+c |z|<=64 } 3RDIM01 {;Mandelbrot z=p1*real(pixel)+flip(imag(pixel)) c=p2+real(pixel)+flip(imag(pixel)*p1): z=z*z+c |z|<=64 } SJMAND03 {;Mandelbrot function z=real(pixel)+p1*(flip(imag(pixel))) c=p2+p1*real(pixel)+flip(imag(pixel)): z=fn1(z)+c |z|<=64 } SJMAND05 {;Mandelbrot lambda function z=real(pixel)+flip(imag(pixel)*p1) c=p2+p1*real(pixel)+flip(imag(pixel)): z=fn1(z)*c |z|<=64 } 3RDIM05 {;Mandelbrot lambda function z=p1*real(pixel)+flip(imag(pixel)) c=p2+real(pixel)+flip(imag(pixel)*p1): z=fn1(z)*c |z|<=64 } SJMAND10 {;Mandelbrot power function z=real(pixel),c=p2+flip(imag(pixel)): z=(fn1(z)+c)^p1 |z|<=4 } SJMAND11 {;Mandelbrot lambda function - lower bailout z=real(pixel)+flip(imag(pixel)*p1) c=p2+p1*real(pixel)+flip(imag(pixel)): z=fn1(z)*c |z|<=4 } {--- KEVIN LEE -----------------------------------------------------------} LeeMandel1(XYAXIS) {; Kevin Lee z=Pixel: ;; c=sqr(pixel)/z, c=z+c, z=sqr(z), this line was an error in v16 c=sqr(pixel)/z, c=z+c, z=sqr(c) |z|<4 } LeeMandel2(XYAXIS) {; Kevin Lee z=Pixel: c=sqr(pixel)/z, c=z+c, z=sqr(c*pixel) |z|<4 } LeeMandel3(XAXIS) {; Kevin Lee z=Pixel, c=Pixel-sqr(z): c=Pixel+c/z, z=c-z*pixel |z|<4 } {--- RON LEWEN -----------------------------------------------------------} RCL_Cross1 [float=y] { ; Ron Lewen ; Try p1=(0,1), fn1=sin and fn2=sqr. Set corners at ; -10/10/-7.5/7.5 to see a cross shape. The larger ; lakes at the center of the cross have good detail ; to zoom in on. ; Use floating point. z=pixel: z=p1*fn1(fn2(z+p1)) |z| <= 4 } RCL_Pick13 [float=y] { ; Ron Lewen ; Formula from Frontpiece for Appendix C ; and Credits in Pickover's book. ; Set p1=(3,0) to generate the Frontpiece ; for Appendix C and to (2,0) for Credits ; Use Floating Point z=.001: z=z^p1+(1/pixel)^p1 |z| <= 100 } RCL_1 (XAXIS) [float=y] { ; Ron Lewen ; An interesting Biomorph inspired by Pickover's ; Computers, Pattern, Choas and Beauty. ; Use Floating Point z=pixel: z=pixel/z-z^2 |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Cosh (XAXIS) [float=y] { ; Ron Lewen, 76376,2567 ; Try corners=2.008874/-3.811126/-3.980167/3.779833/ ; -3.811126/3.779833 to see Figure 9.7 (P. 123) in ; Pickover's Computers, Pattern, Chaos and Beauty. ; Figures 9.9 - 9.13 can be found by zooming. ; Use floating point z=0: z=cosh(z) + pixel abs(z) < 40 } Mothra (XAXIS) { ; Ron Lewen, 76376,2567 ; Remember Mothra, the giant Japanese-eating moth? ; Well... here he (she?) is as a fractal! z=pixel: a=z^5 + z^3 + z + pixel b=z^4 + z^2 + pixel z=b^2/a, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_10 { ; Ron Lewen, 76376,2567 z=pixel: z=flip((z^2+pixel)/(pixel^2+z)) |z| <= 4 } {--- JONATHAN OSUCH ------------------------------------------------------} BirdOfPrey (XAXIS_NOPARM) { ; Optimized by Sylvie Gallet z = p1 : z = cosxx(sqr(z) + pixel) + pixel |z| <= 4 } ; Original version ; BirdOfPrey(XAXIS_NOPARM) { ; z=p1, x=1: ; (x<10)*(z=sqr(z)+pixel) ; (10<=x)*(z=cosxx(z)+pixel) ; x=x+1 ; |z|<=4 ; } FractalFenderCa(XAXIS_NOPARM) {;Spectacular! z=p1,x=|z|: if (0.9999999999 < x) z=cosh(z)+pixel endif z=sqr(z)+pixel,x=|z| x<=4 } {--- LEE SKINNER ---------------------------------------------------------} MTet (XAXIS) {; Mandelbrot form 1 of the Tetration formula --Lee Skinner z = pixel: z = (pixel ^ z) + pixel |z| <= (P1 + 3) } AltMTet(XAXIS) {; Mandelbrot form 2 of the Tetration formula --Lee Skinner z = 0: z = (pixel ^ z) + pixel |z| <= (P1 + 3) } JTet (XAXIS) {; Julia form 1 of the Tetration formula --Lee Skinner z = pixel: z = (pixel ^ z) + P1 |z| <= (P2 + 3) } AltJTet (XAXIS) {; Julia form 2 of the Tetration formula --Lee Skinner z = P1: z = (pixel ^ z) + P1 |z| <= (P2 + 3) } Cubic (XYAXIS) {; Lee Skinner p = pixel, test = p1 + 3 t3 = 3*p, t2 = p*p a = (t2 + 1)/t3, b = 2*a*a*a + (t2 - 2)/t3 aa3 = a*a*3, z = 0 - a : z = z*z*z - aa3*z + b |z| < test } Fzppfnre {; Lee Skinner z = pixel, f = 1./(pixel): z = fn1(z) + f |z| <= 50 } Fzppfnpo {; Lee Skinner z = pixel, f = (pixel)^(pixel): z = fn1(z) + f |z| <= 50 } Fzppfnsr {; Lee Skinner z = pixel, f = (pixel)^.5: z = fn1(z) + f |z| <= 50 } Fzppfnta {; Lee Skinner z = pixel, f = tan(pixel): z = fn1(z) + f |z|<= 50 } Fzppfnct {; Lee Skinner z = pixel, f = cos(pixel)/sin(pixel): z = fn1(z) + f |z|<= 50 } Fzppfnse {; Lee Skinner z = pixel, f = 1./sin(pixel): z = fn1(z) + f |z| <= 50 } Fzppfncs {; Lee Skinner z = pixel, f = 1./cos(pixel): z = fn1(z) + f |z| <= 50 } Fzppfnth {; Lee Skinner z = pixel, f = tanh(pixel): z = fn1(z)+f |z|<= 50 } Fzppfnht {; Lee Skinner z = pixel, f = cosh(pixel)/sinh(pixel): z = fn1(z)+f |z|<= 50 } Fzpfnseh {; Lee Skinner z = pixel, f = 1./sinh(pixel): z = fn1(z) + f |z| <= 50 } Fzpfncoh {; Lee Skinner z = pixel, f = 1./cosh(pixel): z = fn1(z) + f |z| <= 50 } Zexpe (XAXIS) { s = exp(1.,0.), z = Pixel: z = z ^ s + pixel |z| <= 100 } comment { s = log(-1.,0.) / (0.,1.) is (3.14159265358979, 0.0 } Exipi (XAXIS) { s = log(-1.,0.) / (0.,1.), z = Pixel: z = z ^ s + pixel |z| <= 100 } Fzppchco { z = pixel, f = cosxx (pixel): z = cosh (z) + f |z| <= 50 } Fzppcosq { z = pixel, f = sqr (pixel): z = cosxx (z) + f |z| <= 50 } Fzppcosr { z = pixel, f = (pixel) ^ 0.5: z = cosxx (z) + f |z| <= 50 } Leeze (XAXIS) { s = exp(1.,0.), z = Pixel, f = Pixel ^ s: z = cosxx (z) + f |z| <= 50 } OldManowar (XAXIS) { z0 = 0 z1 = 0 test = p1 + 3 c = pixel : z = z1*z1 + z0 + c z0 = z1 z1 = z |z| < test } ScSkLMS(XAXIS) { z = pixel, TEST = (p1+3): z = log(z) - sin(z) |z|-0.025) ) || (y>0.175) f = ( (x<-1.2) || ty2 ) && ( (x>-1.25) && (x<-1) ) r = ( (x<-0.9) || ty2 ) && ( (x>-0.95) && (x<-0.8) ) r = r || ((cabs(sqrt(|z+(0.8,-0.1)|)-0.1)<0.025) && (x>-0.8)) r = r || (((y<(-x1-1.44)) && (y>(-x1-1.53))) && (y<0.025)) a = (y>(x3+1.5)) || (y>(-x3-1.2)) || ((y>-0.125) && (y<-0.075)) a = a && ((y<(x3+1.65)) && (y<(-x3-1.05))) c = (cabs(sqrt(|z+0.05|)-0.2)<0.025) && (x<0.05) t1 = ((x>0.225) && (x<0.275) || (y>0.175)) && ((x>0.1) && (x<0.4)) i = (x>0.45) && (x<0.5) n = (x<0.6) || (x>0.8) || ((y>-x1+1.215) && (y<-x1+1.305)) n = n && (x>0.55) && (x<0.85) t2 = ((x>1.025) && (x<1.075) || (y>0.175)) && ((x>0.9) && (x<1.2)) test = 1 - (real(f||r||a||c||t1||i||n||t2)*real(y>-0.225)*real(y<0.225)) z = 1+(0.0,-0.65)/(pixel+(0.0,.75)) : z2 = z*z , z4 = z2*z2 , n = z4*z2-1 , z = z-n/(6*z4*z) (|n|>=0.0001) && test } comment { This formula uses Newton's formula applied to the real equation : F(x,y) = 0 where F(x,y) = (x^3 + y^2 - 1 , y^3 - x^2 + 1) starting with (x_0,y_0) = z0 = pixel It calculates: (x_(n+1),y_(n+1)) = (x_n,y_n) - (F'(x_n,y_n))^-1 * F(x_n,y_n) where (F'(x_n,y_n))^-1 is the inverse of the Jacobian matrix of F. } Newton_real [float=y] { ; Sylvie Gallet [101324,3444], 1996 ; Newton's method applied to x^3 + y^2 - 1 = 0 ; y^3 - x^2 + 1 = 0 ; solution (0,-1) ; One parameter : real(p1) = bailout value z = pixel , x = real(z) , y = imag(z) : xy = x*y d = 9*xy+4 , x2 = x*x , y2 = y*y c = 6*xy+2 x1 = x*c - (y*y2 - 3*y - 2)/x y1 = y*c + (x*x2 + 2 - 3*x)/y z = (x1+flip(y1))/d , x = real(z) , y = imag(z) (|x| >= p1) || (|y+1| >= p1) } xfractint-20.4.10.orig/formulas/ikenaga.frm0000644000000000000000000002057510150633601015446 0ustar { ======================================================================== } { File originally distributed with FRAC'Cetera Vol 2 Iss 7 } {========================================================================== = Compiled by Jon Horner for FRAC'Cetera from several sources - Jul 93 = = F'names, where present, represent FRAC'Cetera created variations or = = derivatives based, often quite loosely, on the author's originals. = ==========================================================================} { IKENAGA - Formula originally discovered by Bruce Ikenaga, at Western Reserve University, Indiana. Documented in Dewdney's `Armchair Universe". The Ikenaga set is: Z(n+1) =Z(n)^3 + (C-1) * Z(n) - C where: Z(n) = x + yi and C = a + bi In Basic (with Mandelbrot for comparison): Mandelbrot: Ikenaga: newX = x*x - y*y + a newX = x*x*x - 3*x*y*y + a*x - b*y - x - a newY = 2*x*y + b newY = 3*x*x*y - y*y*y + a*y + b*x - y - b Ikenaga is also in R.F.J. Stewart's MANDPLOT; Larry Cobb's DRAGONS4; Mike Curnow's !Fractal for the Archimedes, and Tim Harris's CAL. ==========================================================================} !_Press_F2_! {; There is text in this formula file. Shell to DOS with ; the key and use a text reader to browse the file. } Ikenaga(XAXIS) { ; this version correct per Roderick Stewart - ; announcement in Fractal Report 25 p2. ; same as letter, Joyce Haslam Mar 1993 ; z=z*z*z+ (c-1)*z-c produces same results. z = (0,0), c = pixel : z = z * z * z + z * (c-1) - c , |z|<=4 } IkenagaJ.1(XAXIS) { ; this version correct per Roderick Stewart - ; announcement in Fractal Report 25 p2. ; same as letter, Joyce Haslam Mar 1993 ; z=z*z*z+ (c-1)*z-c produces same results. z = (0,0), c = pixel : z = z * (z * z + (c-1)) - c , |z|<=4 } IkenagaJUL { ; formula from a letter from Joyce Haslam Mar 1993. ; Asymmetric. try p1 = (0.56667, 0.36) ; Next line, from Haslam article Fractal Report 24 p5 ; z=z*z*z+ (c-1)*z-c produces same results. ; Same as Julike in REB001.FRM z = pixel, c = p1 : z = z * z * z + z * (c-1) - c , |z| <= 4 } IkenagaJULJ.1 { ; formula from a letter from Joyce Haslam Mar 1993. ; Asymmetric. try p1 = (0.56667, 0.36) ; Next line, from Haslam article Fractal Report 24 p5 ; z=z*z*z+ (c-1)*z-c produces same results. ; Same as Julike in REB001.FRM z = pixel, c = p1 : z = z * (z * z + (c-1)) - c , |z| <= 4 } { The rest are all variations on the two basic formulas } IkenagaPwr(XAXIS) { ; from Jon Horner z = (0,0), c = pixel : z = z * z * z + z * (c-1) - c ^ p1 , z| <=4 } IkenagaPwrJul { ; from Jon Horner - asymmetric ; try p1 = (0.035, -0.35), p2 = 2 z = pixel, c = p1 : z = z * z * z + z * (c-1) - c ^ p2 , |z| <=4 } Ikenaga4(XAXIS) { ; CAL v3.8 calls it Ikenaga-4Set ; Per Haslam, Fractal Report 25 p2 (IKE4) ; z^4 is used instead of z^3 and multiplication ; is used in place of addition. z = (0,0), c = pixel: z = z * z * z * z * (c-1) - c , |z|<= 4 } Ikenaga4JUL(ORIGIN) { ; Jon Horner, from IKE4 - Fractal Report 25 p2 ; try p1 = (0.3874, 0.85) z = pixel, c = p1 : z = z * z * z * z * (c-1) - c, |z| <= 4 } IkenagaABS(XAXIS) { ; Jon Horner ; Ikenaga with alternative bailout z = (0,0), c = pixel : z = z * z * z + z * (c-1) - c , abs(z)<=4 } IkenagaABSJUL { ; Jon Horner ; IkenagaJul with alternative bailout z = pixel, c = p1 : z = z * z * z + z * (c-1) - c , abs(z) <= 4 } Ikenaga4BIO(XAXIS) { ; Ikenaga4 variation - Jon Horner ; float=y z = (0,0), c = pixel : z = z * z * z * z * (c-1) - c , |real(z)|<=4 || |imag(z)|<=4 } Ikenaga4BIOJUL(ORIGIN){ ; Jon Horner, from IKE4 - FR 25, p2 ; try p1 = (0.3874, 0.85) float=y z = pixel, c = p1 : z = z * z * z * z * (c-1) - c, |real(z)|<=4 || |imag(z)|<=4 } IkenagaFN(XAXIS) {; Jon Horner ; derived from Ikenaga z = (0,0), c = fn1(pixel) : z = z * z * z + z * (c-1) - c , |z| <=4 } IkenagaFNJUL { ; Jon Horner ; derived from IkenagaJul ; asymmetric: try p1 = (0.56667, 0.36) z = fn1(pixel), c = p1 : z = z * z * z + z * (c-1) - c, |z| <= 4 } IkenagaJUL1+(ORIGIN){ ; formula from an article by Joyce Haslam ; in Fractal Report 24 (w/+pixel stead of +c) ; symmetric z = pixel, c = p1 : z = z * z * z + (c-1) * z + pixel , |z|<=4 } Ikenaga2(XAXIS) { ; from Joyce Haslam article, Fractal Report Iss 24 p5. ; Uses pixel instead of c !!!! ; CAL v4.0 calls it UnamiSet. FR 25 calls it Unknown. ; CAL v4.0 IkenagaSet(XAXIS) = ; {z=0:z=z*z*z+z*(pixel-1)-pixel,|z|<=|2| z = pixel: z = z * z * z + (pixel-1) * z - pixel, |z|<=4 } IkenagaMap(XAXIS) {; from REB001.FRM - by Ron Barnett 70153,1233 ; The initial starting point allows the function to provide ; a "map" for the corresponding Julia (IkenagaJul) z = ((1-pixel)/3)^0.5: z = z*z*z + (pixel-1)*z - pixel, |z| <= 4 } IkeNewtMand { ; from REB001.FRM - by Ron Barnett 70153,1233 ; p1 > 0, < 2, float=yes z = c = pixel: zf = z*z*z + (c-1)*z - c; zd = 3*z*z + c-1; z = z - p1*zf/zd, 0.001 <= |zf| } IkeNewtJul { ; from REB001.FRM - by Ron Barnett 70153,1233 ; p1 > 0, < 2, float=yes z = pixel: zf = z*z*z + (p2-1)*z - p2; zd = 3*z*z + p2-1; z = z - p1*zf/zd, 0.001 <= |zf| } RecipIke { ; from REB001.FRM - by Ron Barnett 70153,1233 z = pixel: z = 1/(z*z*z + (p1-1)*z - p1), |z| <= 4 } F'FunctionIke { ; generalized by Jon Horner ; from RecipIke in REB001.FRM : - by Ron Barnett 70153,1233 z = pixel: z = fn1(z*z*z + (p1-1) * z - p1), |z| <= 4 } IkeGenM {; from REB002.FRM - by Ron Barnett 70153,1233 z = ((1-pixel)/(3*p1))^0.5: z =p1*z*z*z + (pixel-1)*z - pixel, |z| <= 100 } IkeGenJ {; from REB002.FRM - by Ron Barnett 70153,1233 z = pixel: z =p1*z*z*z + (p2-1)*z - p2, |z| <= 100 } IkeFrRbtGenM {; from REB002.FRM - by Ron Barnett 70153,1233 z = 2*(1-pixel)/(3*p1): z = p1*z*z*z + (pixel-1)*z*z - pixel, |z| <= 100 } IkeFrRbtGenJ {; from REB002.FRM - by Ron Barnett 70153,1233 z = pixel: z = p1*z*z*z + (p2-1)*z*z - p2, |z| <= 100 } xfractint-20.4.10.orig/formulas/fract002.frm0000644000000000000000000006236310627420161015375 0ustar IslandOfChaos(XAXIS_NOPARM)[float=y function=sqr/sin/cosxx] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=sqr, fn2=sin, fn3=cosxx ; Note: use floating point z = p1, x = 1: IF (x < 10) z=fn1(z) + pixel ELSE z=fn2(z) / fn3(z) + pixel ENDIF x = x+1, |z| <= p2 } j1 {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2, |z| <= 4 } jc {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2*c, |z| <= 4 } jfnc {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2*fn1(c), |z| <= 4 } jfnz {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2*fn1(z), |z| <= 4 } JMask = {; Ron Barnett [70153,1233] ; try p1 = (1,0), p2 = (0,0.835), fn1 = sin, fn2 = sqr z = fn1(pixel): z = P1*fn2(z)^2 + P2, |z| <= 4 } joc {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2/c, |z| <= 4 } joz {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2/z, |z| <= 4 } jz {; from EXPLOD.FRM z=pixel, c=p1: z=sqr(z)+c, c=c+p2*z, |z| <= 4 } JSomethingelse (xyaxis) = { z = pixel: z = p1 * (z*z + 1/z/z), |z| <= 1000000 } J_Lagandre2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (3 * z*z - 1) / 2 + c |z| < 100 } J_Lagandre3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = z * (5 * z*z - 3) / 2 + c |z| < 100 } J_Lagandre4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z*z*(35 * z*z - 30) + 3) / 8 + c |z| < 100 } J_Lagandre5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = z* (z*z*(63 * z*z - 70) + 15 ) / 8 + c |z| < 100 } J_Lagandre6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z*z*(z*z*(231 * z*z - 315) + 105 ) - 5) / 16 + c |z| < 100 } J_Lagandre7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = z* (z*z*(z*z*(429 * z*z - 693) + 315) - 35 ) / 16 + c |z| < 100 } J_Laguerre2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z*(z - 4) +2 ) / 2 + c, |z| < 100 } J_Laguerre3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z*(z*(-z + 9) -18) + 6 ) / 6 + c, |z| < 100 } J_Laguerre4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z * ( z * ( z * ( z - 16)+ 72) - 96)+ 24 ) / 24 + c, |z| < 100 } J_Laguerre5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z * ( z * ( z * ( z * (-z +25) -200) +600) -600) + 120 ) / 120 + c, |z| < 100 } J_Laguerre6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = (z *(z *(z *(z *(z*(z -36) +450) -2400) + 5400)-4320)+ 720) / 720 + c, |z| < 100 } J_TchebychevC2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z-2), |z|<100 } J_TchebychevC3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z-3), |z|<100 } J_TchebychevC4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(z*z-4)+2), |z|<100 } J_TchebychevC5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(z*z-5)+5), |z|<100 } J_TchebychevC6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(z*z*(z*z-6)+9)-2), |z|<100 } J_TchebychevC7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(z*z*(z*z-7)+14)-7), |z|<100 } J_TchebychevS2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z-1), |z|<100 } J_TchebychevS3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z-2), |z|<100 } J_TchebychevS4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(z*z-3)+1), |z|<100 } J_TchebychevS5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(z*z-4)+3), |z|<100 } J_TchebychevS6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(z*z*(z*z-5)+6)-1), |z|<100 } J_TchebychevS7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(z*z*(z*z-6)+10)-4), |z|<100 } J_TchebychevT2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(2*z*z-1), |z|<100 } J_TchebychevT3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(4*z*z-3), |z|<100 } J_TchebychevT4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(8*z*z+8)+1), |z|<100 } J_TchebychevT5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*(z*z*(16*z*z-20)+5)), |z|<100 } J_TchebychevT6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(z*z*(32*z*z-48)+18)-1), |z|<100 } J_TchebychevT7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(z*z*(64*z*z-112)+56)-7), |z|<100 } J_TchebychevU2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(4*z*z-1), |z|<100 } J_TchebychevU3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(8*z*z-4), |z|<100 } J_TchebychevU4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(16*z*z-12)+1), |z|<100 } J_TchebychevU5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(32*z*z-32)+6), |z|<100 } J_TchebychevU6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*(z*z*(z*z*(64*z*z-80)+24)-1), |z|<100 } J_TchebychevU7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = pixel, z = P1: z = c*z*(z*z*(z*z*(128*z*z-192)+80)-8), |z|<100 } JuliaConj(Origin) {; Paul J. Horn - a conjugate Julia (I think) ; try real part of p1 = -1.1 and imag part of p1 = .09 z = pixel: z = Sqr(conj(z)) + P1, |z| <= 4 } JuliConj01(Origin) {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = -.93, imag(p1) = .3, map = blues z = pixel: z = Sqr(z) + Conj(P1), |z| <= 4 } JuliConj02(Origin) {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = .3, imag(p1) = .25, map = neon z = pixel: z = Sqr(Conj(z)) + Conj(P1), |z| <= 4 } JuliConj03 {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = .40, imag(p1) = 0, map = glasses2 z = pixel: z = Sqr(conj(z))*conj(z) + P1, |z| <= 4 } JuliConj04 {; Paul J. Horn - a conjugate Julia (I think) ;Try real(p1) = .53, imag(p1) = .63, map = volcano z = pixel: z = Sqr(z)*z + Conj(P1), |z| <= 4 } JuliConj05 {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = .6, imag(p1) = .4, map = chroma z = pixel: z = Sqr(conj(z))*conj(z) + Conj(P1), |z| <= 4 } JuliConj06(Origin) {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = .99, imag(p1) = .72 z = pixel: z = Sqr(Sqr((conj(z)))) + P1, |z| <= 4 } JuliConj07(Origin) {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = -.245, imag(p1) = .44, map = royal z = pixel: z = Sqr(Sqr(z)) + Conj(P1), |z| <= 4 } JuliConj08(Origin) {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = -1, imag(p1) = .11, map = blues z = pixel: z = Sqr(Sqr((conj(z)))) + Conj(P1), |z| <= 4 } JuliConj09 {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = -.677, imag(p1) = .333, real(p2) = 9, map = blues z = pixel: z = (conj(z))^P2 + P1, |z| <= 4 } JuliConj10 {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = .1005, imag(p1) = .68, real(p2) = 5, map = chroma z = pixel: z = (z)^P2 + Conj(P1), |z| <= 4 } JuliConj11 {; Paul J. Horn - a conjugate Julia (I think) ; Try real(p1) = -.37, imag(p1) = .6, real(p2) = 6, map = volcano z = pixel: z = (conj(z))^P2 + Conj(P1), |z| <= 4 } JulibrotSlice1 = {; Randy Hutson - 2D slice of 4D Julibrot z = real(p1)+flip(imag(pixel)), c = real(pixel)+flip(imag(p1)): z = sqr(z)+c, LastSqr <= 4 } LambdaPwr {; Ron Barnett [70153,1233] ; try p1 = (0.75,0.75), p2 = (2.5,0) z = pixel: z = p1*z*(1 - z^p2), |z| <= 100 } Leeze (XAXIS) = {; Lee Skinner [75450,3631] s = exp(1.,0.), z = Pixel, f = Pixel ^ s: z = cosxx (z) + f, |z| <= 50 } Liar1 { ; by Chuck Ebbert. [76306,1226] ; X: X is as true as Y ; Y: Y is as true as X is false ; Calculate new x and y values simultaneously. ; y(n+1)=abs((1-x(n) )-y(n) ), x(n+1)=1-abs(y(n)-x(n) ) z = pixel: z = 1 - abs(imag(z)-real(z) ) + flip(1 - abs(1-real(z)-imag(z) ) ), |z| <= 1 } Liar2 { ; by Chuck Ebbert. [76306,1226] ; Same as Liar1 but uses sequential reasoning, calculating ; new y value using new x value. ; x(n+1) = 1 - abs(y(n)-x(n) ); ; y(n+1) = 1 - abs((1-x(n+1) )-y(n) ); z = pixel: x = 1 - abs(imag(z)-real(z)), z = flip(1 - abs(1-real(x)-imag(z) ) ) + real(x), |z| <= 1 } M-SetInNewton(XAXIS) {; use float=yes ; jon horner 100112,1700, 12 feb 93 z = 0, c = pixel, cminusone = c-1: oldz = z, nm = 3*c-2*z*cminusone, dn = 3*(3*z*z+cminusone), z = nm/dn+2*z/3, |(z-oldz)|>=|0.01| } m1 {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1, |z| <= 4 } MandelConj(XAXIS) {; Paul J. Horn , this was mentioned in Pickover's book ; Computers, Chaos, Patterns and Beauty. He didn't give the forumula, so ; I came up with this z = c = Pixel: z = Sqr(conj(z)) + Pixel, |z| <= 4 } MandConj01(XAXIS) {; Paul J. Horn, see MandelConj. ; This is a variation on a theme. z = c = Pixel: z = Sqr(z) + Conj(Pixel), |z| <= 4 } MandConj02(XAXIS) {; Paul J. Horn, see MandelConj. ; Another variation on the theme. z = c = Pixel: z = Sqr(Conj(z)) + Conj(Pixel), |z| <= 4 } MandConj03(XAXIS) {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = Sqr(conj(z))*conj(z) + Pixel, |z| <= 4 } MandConj04(XAXIS) {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = Sqr((z))*(z) + Conj(Pixel), |z| <= 4 } MandConj05(XAXIS) {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = Sqr(conj(z))*conj(z) + Conj(Pixel), |z| <= 4 } MandConj06(XAXIS) {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = Sqr(Sqr(conj(z))) + Pixel, |z| <= 4 } MandConj07(XAXIS) {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = Sqr(Sqr((z))) + Conj(Pixel), |z| <= 4 } MandConj08(XAXIS) {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = Sqr(Sqr(conj(z))) + Conj(Pixel), |z| <= 4 } MandConj09 {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = (conj(z))^p1 + Pixel, |z| <= 4 } MandConj10 {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = z^p1 + Conj(Pixel), |z| <= 4 } MandConj11 {; Paul J. Horn ; yet another variation on the theme z = c = Pixel: z = (conj(z))^p1 + Conj(Pixel), |z| <= 4 } MandellambdaPwr {; Ron Barnett [70153,1233] ; This provide a "map" for LambdaPwr z = (1/(p1+1))^(1/p1): z = pixel*z*(1 - z^p1), |z| <= 100 } Mask = {; Ron Barnett [70153,1233] ; try fn1 = log, fn2 = sinh, fn3 = cosh ;P1 = (0,1), P2 = (0,1) ;Use floating point z = fn1(pixel): z = P1*fn2(z)^2 + P2*fn3(z)^2 + pixel, |z| <= 4 } mc {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1*c, |z| <= 4 } mfnc {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1*fn1(c), |z| <= 4 } mfnz {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1*fn1(z), |z| <= 4 } Michaelbrot {; Michael Theroux [71673,2767] ; Fix and generalization by Ron Barnett [70153,1233] ; Try p1 = 2.236067977 for the golden mean ;based on Golden Mean z = pixel: z = sqr(z) + ((p1 + 1)/2), |z| <= 4 } moc {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1/c, |z| <= 4 } Mothra (XAXIS) { ; Ron Lewen, 76376,2567 ; Remember Mothra, the giant Japanese-eating moth? ; Well... here he (she?) is as a fractal! ; z=pixel: z2=z*z, z3=z2*z, z4=z3*z, a=z4*z + z3 + z + pixel, b=z4 + z2 + pixel, z=b*b/a, |real(z)| <= 100 || |imag(z)| <= 100 } moz {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1/z, |z| <= 4 } mz {; from EXPLOD.FRM z=0, c=pixel: z=sqr(z)+c, c=c+p1*z, |z| <= 4 } M_Lagandre2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (3 * z*z - 1) / 2 + c |z| < 100 } M_Lagandre3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = z * (5 * z*z - 3) / 2 + c |z| < 100 } M_Lagandre4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z*z*(35 * z*z - 30) + 3) / 8 + c |z| < 100 } M_Lagandre5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = z* (z*z*(63 * z*z - 70) + 15 ) / 8 + c |z| < 100 } M_Lagandre6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z*z*(z*z*(231 * z*z - 315) + 105 ) - 5) / 16 + c |z| < 100 } M_Lagandre7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = z* (z*z*(z*z*(429 * z*z - 693) + 315) - 35 ) / 16 + c |z| < 100 } M_Laguerre2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z*(z - 4) +2 ) / 2 + c, |z| < 100 } M_Laguerre3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z*(z*(-z + 9) -18) + 6 ) / 6 + c, |z| < 100 } M_Laguerre4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z * ( z * ( z * ( z - 16)+ 72) - 96)+ 24 ) / 24 + c, |z| < 100 } M_Laguerre5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z * ( z * ( z * ( z * (-z +25) -200) +600) -600) + 120 ) / 120 + c, |z| < 100 } M_Laguerre6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = (z *(z *(z *(z *(z*(z -36) +450) -2400) +5400) -4320) +720) / 720 + c, |z| < 100 } M_TchebychevC2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z-2), |z|<100 } M_TchebychevC3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z-3), |z|<100 } M_TchebychevC4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(z*z-4)+2), |z|<100 } M_TchebychevC5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(z*z-5)+5), |z|<100 } M_TchebychevC6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(z*z*(z*z-6)+9)-2), |z|<100 } M_TchebychevC7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(z*z*(z*z-7)+14)-7), |z|<100 } M_TchebychevS2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z-1), |z|<100 } M_TchebychevS3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z-2), |z|<100 } M_TchebychevS4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(z*z-3)+1), |z|<100 } M_TchebychevS5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(z*z-4)+3), |z|<100 } M_TchebychevS6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(z*z*(z*z-5)+6)-1), |z|<100 } M_TchebychevS7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(z*z*(z*z-6)+10)-4), |z|<100 } M_TchebychevT2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(2*z*z-1), |z|<100 } M_TchebychevT3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(4*z*z-3), |z|<100 } M_TchebychevT4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(8*z*z+8)+1), |z|<100 } M_TchebychevT5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*(z*z*(16*z*z-20)+5)), |z|<100 } M_TchebychevT6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(z*z*(32*z*z-48)+18)-1), |z|<100 } M_TchebychevT7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(z*z*(64*z*z-112)+56)-7), |z|<100 } M_TchebychevU2 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(4*z*z-1), |z|<100 } M_TchebychevU3 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(8*z*z-4), |z|<100 } M_TchebychevU4 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(16*z*z-12)+1), |z|<100 } M_TchebychevU5 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(32*z*z-32)+6), |z|<100 } M_TchebychevU6 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*(z*z*(z*z*(64*z*z-80)+24)-1), |z|<100 } M_TchebychevU7 {; Rob den Braasem [rdb@KTIBV.UUCP] c = P1, z = Pixel: z = c*z*(z*z*(z*z*(128*z*z-192)+80)-8), |z|<100 } Natura {; Michael Theroux [71673,2767] ; Fix and generalization by Ron Barnett [70153,1233] ;phi yoni ; try p1 = 2.236067977 for the golden mean z = pixel: z = z*z*z + ((p1 + 1)/2) |z| <= 4 } Newducks(XAXIS) = { z=pixel,t=1+pixel: z=sqr(z)+t, |z|<=4 } non-conformal {; Richard Hughes (Brainy Smurf) [70461,3272] ; From Media Magic Calender - August z=x=y=x2=y2=0: t = x * y, x = x2 + t + real(pixel), y = y2 - t + imag(pixel), x2 = sqr(x), y2 = sqr(y), z=x + flip(y), |z| <= 4 } No_name(xaxis) = { z = pixel: z=z+z*z+(1/z*z)+pixel, |z| <= 4 } OldCGNewtonSinExp (XAXIS) {; Chris Green ; For images using old incorrect cos function ; Use floating point. z=pixel: z1=exp(z), z2=sin(z)+z1-z, z=z-p1*z2/(cosxx(z)+z1), .0001 < |z2| } OldHalleySin (XYAXIS) {; Chris Green ; For images using old incorrect cos function ; Use floating point. z=pixel: s=sin(z), c=cosxx(z), z=z-p1*(s/(c-(s*s)/(c+c))), 0.0001 <= |s| } OldManowar (XAXIS) {; Lee Skinner [75450,3631] z0 = 0, z1 = 0, test = p1 + 3, c = pixel : z = z1*z1 + z0 + c, z0 = z1, z1 = z, |z| < test } OldNewtonSinExp (XAXIS) {; Chris Green ; Newton's formula applied to sin(x)+exp(x)-1=0. ; For images using old incorrect cos function ; Use floating point. z=pixel: z1=exp(z), z2=sin(z)+z1-1 z=z-p1*z2/(cosxx(z)+z1), .0001 < |z2| } phoenix_j (XAXIS) {; Richard Hughes (Brainy Smurf) [70461,3272] ; Use P1=0.56667/-0.5 & .1/.8 ; Use floating point. x=real(pixel), y=imag(pixel), z=nx=ny=x1=x2=y1=y2=0: x2 = sqr(x), y2 = sqr(y), x1 = x2 - y2 + real(p1) + imag(p1) * nx, y1 = 2 * x * y + imag(p1) * ny, nx=x, ny=y, x=x1, y=y1, z=nx + flip(ny), |z| <= 4 } phoenix_m {; Richard Hughes (Brainy Smurf) [70461,3272] ; Mandelbrot style map of the Phoenix curves ; Use floating point. z=x=y=nx=ny=x1=y1=x2=y2=0: x2 = sqr(x), y2 = sqr(y), x1 = x2 - y2 + real(pixel) + imag(pixel) * nx, y1 = 2 * x * y + imag(pixel) * ny, nx=x, ny=y, x=x1, y=y1, z=x + flip(y), |z| <= 4 } PolyGen = {; Ron Barnett [70153,1233] ;p1 must not be zero ;zero can be simulated with a small ;value for p1 ;use floating point ;try p1 = 1 and p2 = 0.3 z=(-p2+(p2*p2+(1-pixel)*3*p1)^0.5)/(3*p1): z=p1*z*z*z+p2*z*z+(pixel-1)*z-pixel, |z| <= 100 } PseudoLambda {; Ron Barnett [70153,1233] ; Use floating point. ; try p1 = (-1,0.45), p2 = (1,0) z = pixel: x = real(z), y = imag(z), x1 = -p1*(x - x*x + y*y) + p2, y = -p1*(y - 2*x*y), z = x1 + flip(y), |z| <= 100 } PseudoMandelLambda {; Ron Barnett [70153,1233] ; Use floating point. z = 0.5, c = pixel: x = real(z), y = imag(z), x1 = -c*(x - x*x + y*y) + p1, y = -c*(y - 2*x*y), z = x1 + flip(y), |z| <= 100 } PseudoZeePi = {; Ron Barnett [70153,1233] ; try p1 = 0.1, p2 = 0.39 z = pixel: x = 1-z^p1; z = z*((1-x)/(1+x))^(1/p1) + p2, |z| <= 4 } Ramanujan1(ORIGIN) = { z = pixel: z = (cosh(p1 * sqr(z)) - sinh(p2 * sqr(z))/(p2 * sqr(z)))/z, |z|<= 4 } Raphaelbrot {; Michael Theroux [71673,2767] ; Fix and generalization by Ron Barnett [70153,1233] ;phi ; try p1 = 2.236067977 for the golden mean z = pixel: z = sqr(z) + ((p1 - 1)/2) |z| <= 4 } RCL_1 (XAXIS) { ; Ron Lewen [76376,2567] ; An interesting Biomorph inspired by Pickover's ; Computers, Pattern, Choas and Beauty. ; Use Floating Point z=pixel: z=pixel/z-z^2, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_11 { ; Ron Lewen, 76376,2567 ; A variation on the formula used to generate ; Figure 9.18 (p. 134) from Pickover's book. ; P1 sets the initial value for z. ; Try p1=.75, or p1=2, or just experiment! z=real(p1): z=z*pixel-pixel/sqr(z) z=flip(z), abs(z) < 8 } RCL_2 (XAXIS) { ; Ron Lewen [76376,2567] ; A biomorph flower? Simply a change in initial ; conditions from RCL_1 above ; Use Floating Point z=1/pixel: z=pixel/z-z^2 |real(z)| <= 100 || |imag(z)| <= 100 } RCL_3 (XAXIS) { ; Ron Lewen [76376,2567] ; A seemingly endless vertical pattern. The most activity ; is around the center of the image. ; Use Floating Point z=pixel: z=pixel^z+z^pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_4_M (XAXIS) { ; Ron Lewen, 76376,2567 ; A Mandelbrot-style variation on Pickover's book, ; Figure 8.9 (p. 105). ; Use floating point z=pixel: z=sin(z^2) + sin(z) + sin(pixel), |z| <= 4 } RCL_4_J { ; Ron Lewen, 76376,2567 ; A julia-style variation of the formula in Figure 8.9 ; (p. 105) of Pickover's book. z=pixel: z=sin(z^2) + sin(z) + sin(p1), |z| <= 4 } RCL_5_M (XAXIS) { Ron Lewen, 76376,2567 ; A variation on the classical Mandelbrot set ; formula. ; Use floating point z=pixel: z=sin(z^2+pixel), |z| <= 4 } RCL_5_J (ORIGIN) { Ron Lewen, 76376,2567 ; A variation on the classical Julia set. ; Use floating point z=pixel: z=sin(z^2+p1), |z| <= 4 } RCL_6_M (XAXIS) { ; Ron Lewen, 76376,2567 ; A variation on the classic Mandelbrot formula ; Use floating point z=pixel: z=sin(z)^2 + pixel, |z| <= 4 } RCL_6_J (ORIGIN) { ; Ron Lewen, 76376,2567 ; A variation on the classic Julia formula ; use floating point z=pixel: z=sin(z)^2 + p1, |z| <= 4 } RCL_7 (XAXIS) { ; Ron Lewen, 76376,2567 ; Inspired by the Spider ; fractal type included with Fractint z=c=pixel: z=z^2+pixel+c c=c^2+pixel+z |z| <= 4 } RCL_8_M { ; Ron Lewen, 76376,2567 ; Another variation on the classic Mandelbrot ; set. z=pixel: z=z^2+flip(pixel) |real(z)| <= 100 || |imag(z)| <= 100 } RCL_8_J (ORIGIN) { ; Ron Lewen, 76376,2567 z=pixel: z=z^2+flip(p1) |real(z)| <= 100 || |imag(z)| <= 100 } RCL_9 (XAXIS) { ; Ron Lewen, 76376,2567 z=pixel: z=(z^2+pixel)/(pixel^2+z) |z| <= 4 } RCL_10 { ; Ron Lewen, 76376,2567 z=pixel: z=flip((z^2+pixel)/(pixel^2+z)) |z| <= 4 } RCL_12 (XAXIS) { ; Ron Lewen, 76376,2567 z=pixel: z=(z^2+3z+pixel)/(z^2-3z-pixel) |z| <= 10 } RCL_13 (XAXIS) { ; Ron Lewen, 76376,2567 z=pixel: z=(z^2+2z+pixel)/(z^2-2z+pixel) |z| <= 100 } RCL_14 (XAXIS) { ; Ron Lewen, 76376,2567 z=pixel: z=z^pixel+pixel^z |z| <= 96 } RCL_15 (XAXIS) { ; Ron Lewen, 76376,2567 ; Adapted from Pickover's Biomorph Zoo Collection in ; Figure 8.7 (p. 102). z=pixel: z=z^2.71828 + pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_16 (XAXIS) { ; Ron Lewen, 76376,2567 ; Set fn1 to sqr to generate Figure 9.18 (p. 134) ; from Pickover's book. ; Set maxiter >= 1000 to see good detail in the spirals ; in the three large lakes. Also set inside=0. z=0.5: z=z*pixel-pixel/fn1(z), abs(z) < 8 } RCL_Cosh (XAXIS) { ; Ron Lewen, 76376,2567 ; Try corners=2.008874/-3.811126/-3.980167/3.779833/ ; -3.811126/3.779833 to see Figure 9.7 (P. 123) in ; Pickover's Computers, Pattern, Chaos and Beauty. ; Figures 9.9 - 9.13 can be found by zooming. ; Use floating point z=0: z=cosh(z) + pixel, abs(z) < 40 } RCL_Cosh_Flip (XAXIS) { ; Ron Lewen, 76376,2567 ; A FLIPed version of RCL_Cosh. ; An interesting repeating pattern with lots ; of detail. ; Use floating point z=0: z=flip(cosh(z) + pixel), abs(z) < 40 } RCL_Cosh_J { ; Ron Lewen, 76376,2567 ; A julia-style version of RCL_Cosh above. ; Lots of interesting detail to zoom in on. ; Use floating point z=pixel: z=cosh(z) + p1, abs(z) < 40 } RCL_Cross1 { ; Ron Lewen, 76376,2567 ; Try p1=(0,1), fn1=sin and fn2=sqr. Set corners at ; -10/10/-7.5/7.5 to see a cross shape. The larger ; lakes at the center of the cross have good detail ; to zoom in on. ; Use floating point. z=pixel: z=p1*fn1(fn2(z+p1)), |z| <= 4 } RCL_Cross2 { ; Ron Lewen, 76376,2567 ; Try p1=(0,1), fn1=sin and fn2=sqr. Set corners at ; -10/10/-7.5/7.5 to see a deformed cross shape. ; The larger lakes at the center of the cross have ; good detail to zoom in on. ; Try corner=-1.58172/.976279/-1.21088/-.756799 to see ; a deformed mandelbrot set. ; Use floating point. z=pixel: z=pixel*fn1(fn2(z+p1)), |z| <= 4 } RCL_Logistic_1 (XAXIS) { ; Ron Lewen, 76376,2567 ; Based on logistic equation x -> c(x)(1-x) used ; to model animal populations. Try p1=(3,0.1) to ; see a family of spiders out for a walk ! z=pixel: z=p1*z*(1-z), |z| <= 1 } RCL_Mandel (XAXIS) { ; Ron Lewen, 76376,2567 ; The traditional Mandelbrot formula with a different ; escape condition. Try p1=(1,0). This is basically the M-Set ; with more chaos outside. p1=(0,0) yields a distorted M-set. ; Use floating point z=pixel: z=sqr(z) + pixel, sin(z) <= p1 } xfractint-20.4.10.orig/formulas/fract200.frm0000644000000000000000000000061010150633601015354 0ustar comment { Formula file released with Fractint 20.0 } {--- SYLVIE GALLET -------------------------------------------------------} ismand_demo { ; sylvie_gallet@compuserve.com ; uses the Pokorny formula z -> 1/(z^2+c) ; ; Use the spacebar to toggle between mandel and julia sets ; if (ismand) z = 0 , c = pixel else z = pixel , c = p1 endif : z = 1 / (z*z + c) |z| <= p2 } xfractint-20.4.10.orig/formulas/fract001.frm0000644000000000000000000005161510627420161015372 0ustar a---mand {; Eli Brandt, (c) 1992 z = c = pixel: z = z^c + sin(c); |z|=|0.01| } F'M-SetInNewtonB(XAXIS) { ; use float=yes, periodicity=no ; set p1 >= 3, 1e-30 < p2 < .01 z=0, c=fn1(pixel), cm1=c-1, cm1x2=cm1*2, twoop1=2/p1, p1xc=c*real(p1): oldz = z, z= (p1xc - z*cm1x2 )/( (sqr(z)*3 + cm1 ) * real(p1) ) + z*real(twoop1), |z - oldz| >= p2 } F'M-SetInNewtonC(XAXIS) { ; same as F'M-SetInNewtonB except for bailout ; use float=yes, periodicity=no ; (3 <= p1 <= ?) and (1e-30 < p2 < .01) z=0, c=fn1(pixel), cm1=c-1, cm1x2=cm1*2, twoop1=2/p1, p1xc=c*real(p1): z = (p1xc - z*cm1x2 )/( (sqr(z)*3 + cm1 ) * real(p1) ) + z*real(twoop1), abs(|z| - real(lastsqr) ) >= p2 } flip0_man_j(ORIGIN) {; Richard Hughes (Brainy Smurf) [70461,3272] z=pixel: z = flip(sqr(z) + p1), |z| <= 4 } flip0_man_m(XAXIS) {; Richard Hughes (Brainy Smurf) [70461,3272] z=0: z = flip(sqr(z) + pixel), |z| <= 4 } flip1_man_j(ORIGIN) {; Richard Hughes (Brainy Smurf) [70461,3272] z=pixel, q = p1: q = flip(q), z = sqr(z) + q, |z| <= 4 } flip1_man_m {; Richard Hughes (Brainy Smurf) [70461,3272] z=0, q = pixel: q = flip(q), z = sqr(z) + q, |z| <= 4 } flip2_man_j(ORIGIN) {; Richard Hughes (Brainy Smurf) [70461,3272] z=pixel, q = p1: q = flip(q), z = flip(sqr(z) + q), |z| <= 4 } flip2_man_m {; Richard Hughes (Brainy Smurf) [70461,3272] z=0, q = pixel: q = flip(q), z = flip(sqr(z) + q), |z| <= 4 } flip3_man_j {; Richard Hughes (Brainy Smurf) [70461,3272] z = pixel: z = 1/flip(sqr(z) + p1), |z| <= 4 } flip3_man_m(XAXIS) {; Richard Hughes (Brainy Smurf) [70461,3272] z = 0: z = 1/flip(sqr(z) + pixel), |z| <= 4 } FlipLambdaJ = {; Ron Barnett [70153,1233] ; try p1 = (0.737, 0.949) z = pixel: z = p1*z*(1-flip(z)*flip(z)), |z| <= 100 } FlipLambdaM = {; Ron Barnett [70153,1233] ; provides a "map" of locations for FlipLambdaJ ; Try "center-mag" with center = (0.49,0.31) ; mag = 10.4 z = 0.5: z = pixel*z*(1-flip(z)*flip(z)), |z| <= 100 } FlipProbJ1 = {; Ron Barnett [70153,1233] ; try p1 = (1,1) z = pixel: z = flip(z)*(1-z) + p1, |z| <= 100 } FlipProbJ2 = {; Ron Barnett [70153,1233] ; try p1 = (-0.88,0.625) z = pixel: z = z*(p1-flip(z)) + p1, |z| <= 100 } FlipProbM1 = {; Ron Barnett [70153,1233] ; provides a "map" of locations for FlipProbJ1 z = pixel: z = flip(z)*(1-z) + pixel, |z| <= 100 } FlipProbM2 = {; Ron Barnett [70153,1233] ; provides a "map" of locations for FlipProbJ2 z = pixel: z = z*(pixel-flip(z)) + pixel, |z| <= 100 } Fly(XAXIS_NOPARM)[float=y function=sqr/sqr] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=sqr, fn2=sqr ; Note: use floating point z = p1: x = real(z), IF (x < 0) z = fn1(z)+pixel ELSE z = fn2(z)-pixel ENDIF |z|< = p2 } FlyingSquirrel(XAXIS_NOPARM)[float=y function=sin/cosxx/sqr] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=sin, fn2=cosxx, fn3=sqr ; Note: use floating point z = p1, x = |z|: IF (1 < x) z=fn1(z) / fn2(z) + pixel ENDIF z = fn3(z)+pixel, x = |z|, x <= p2 } Form3 (XAXIS) = { ;Peter Lewman's formulas for Fractint. z = Pixel, c = Pixel: z = c * z * ( p1 - z ), |z| < 4 } Form4 (XAXIS) = {;Peter Lewman's formulas for Fractint. z = Pixel, c = P1: z = c * z * ( p2 - z ), |z| < 4 } Form5 (XAXIS) = {;Peter Lewman's formulas for Fractint. z = Pixel, c = Pixel: z = p1 / ( fn1(z) + c ), |z| < 4 } Form6 (XAXIS) = {;Peter Lewman's formulas for Fractint. z = Pixel, c = Pixel: z = z^6 + fn1(z) + c, |z| < 4 } Form7 (XYAXIS) = {;Peter Lewman's formulas for Fractint. z = Pixel, c = Pixel: z = ( c * fn1( fn2(z) + 1 ) ) / ( z * ( fn3(z) - 1) ), |z| < 4 } FractalFender(XAXIS_NOPARM)[float=y function=cosh/sqr] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=cosh, fn2=sqr ; Try p1=0, p2=4, fn1=cosxx, fn2=sqr ; Note: use floating point z = p1, x = |z|: IF (1 < x) z=fn1(z)+pixel ENDIF z = fn2(z)+pixel, x = |z|, x <= p2 } Frame-RbtJ = {; Ron Barnett [70153,1233] ; try p1 = (-1.37, 0.57) z = pixel: z = z*z*z/5 + z*z + p1, |z| <= 100 } Frame-RbtM(XAXIS) = {; Ron Barnett [70153,1233] ;from Mazes for the Mind by Pickover ; provide a "map" of locations for Frame-RbtJ z = c = pixel: z = z*z*z/5 + z*z + c, |z| <= 100 } Frog(XAXIS_NOPARM)[float=y function=tanh/sqr] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=tanh, fn2=sqr ; Note: use floating point z = p1, x = |z|: IF (1 < x) z=fn1(z)+pixel ENDIF z = fn2(z)+pixel, x = |z|, x <= p2 } FrRbtGenJ = {; Ron Barnett [70153,1233] z = pixel: z = p1*z*z*z + z*z + p2, |z| <= 100 } FrRbtGenM = {; Ron Barnett [70153,1233] z = pixel: z = p1*z*z*z + z*z + pixel, |z| <= 100 } Fzpcocoh {; Lee Skinner [75450,3631] z = pixel, f = 1. / cosh(pixel): z = cosxx (z) + f, |z| <= 50 } Fzpcopch {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (cosh(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcopcs {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (1. / cosxx(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcopct {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (cosxx(pixel) / sin(pixel) ): z = cosxx (z) + f, |z|<= 50 } Fzpcophc {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (1. / cosh(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcophs {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (1. / sinh(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcopht {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ cotanh(pixel) : z = cosxx (z) + f, |z|<= 50 } Fzpcopse {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (1. / sin(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcopsh {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (sinh(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcopsq {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (sqr(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzpcopta {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (sin(pixel) / cosxx(pixel) ): z = cosxx (z) + f, |z|<= 50 } Fzpcopth {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ tanh(pixel): z = cosxx (z) + f, |z|<= 50 } Fzpcoseh {; Lee Skinner [75450,3631] z = pixel, f = 1. / sinh(pixel): z = cosxx (z) + f, |z| <= 50 } Fzppchco {; Lee Skinner [75450,3631] z = pixel, f = cosxx (pixel): z = cosh (z) + f, |z| <= 50 } Fzppchex {; Lee Skinner [75450,3631] z = pixel, f = exp (pixel): z = cosh (z) + f, |z| <= 50 } Fzppchlo {; Lee Skinner [75450,3631] z = pixel, f = log (pixel): z = cosh (z) + f, |z| <= 50 } Fzppchsh {; Lee Skinner [75450,3631] z = pixel, f = sinh (pixel): z = cosh (z) + f, |z| <= 50 } Fzppchsi {; Lee Skinner [75450,3631] z = pixel, f = sin (pixel): z = cosh (z) + f, |z| <= 50 } Fzppchsq {; Lee Skinner [75450,3631] z = pixel, f = sqr (pixel): z = cosh (z) + f, |z| <= 50 } Fzppcoch {; Lee Skinner [75450,3631] z = pixel, f = cosh (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcocs {; Lee Skinner [75450,3631] z = pixel, f = 1. / cosxx(pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcoct {; Lee Skinner [75450,3631] z = pixel, f = cosxx(pixel) / sin(pixel): z = cosxx (z) + f, |z|<= 50 } Fzppcoex {; Lee Skinner [75450,3631] z = pixel, f = exp (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcohs {; Lee Skinner [75450,3631] z = pixel, f = sinh (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcoht {; Lee Skinner [75450,3631] z = pixel, f = cotanh(pixel): z = cosxx (z)+f, |z|<= 50 } Fzppcolo {; Lee Skinner [75450,3631] z = pixel, f = log (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcopc {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (cosxx(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzppcope {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (exp(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzppcopl {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (log(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzppcopo {; Lee Skinner [75450,3631] z = pixel, f = (pixel) ^ (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcopr {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (1. / pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcops {; Lee Skinner [75450,3631] z = pixel, f = pixel ^ (sin(pixel) ): z = cosxx (z) + f, |z| <= 50 } Fzppcore {; Lee Skinner [75450,3631] z = pixel, f = 1. / (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcos {; Lee Skinner [75450,3631] z = pixel, f = cosxx (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcose {; Lee Skinner [75450,3631] z = pixel, f = 1. / sin(pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcosh {; Lee Skinner [75450,3631] z = pixel, f = cosh (pixel): z = cosh (z) + f, |z| <= 50 } Fzppcosi {; Lee Skinner [75450,3631] z = pixel, f = sin (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcosq {; Lee Skinner [75450,3631] z = pixel, f = sqr (pixel): z = cosxx (z) + f, |z| <= 50 } Fzppcosr {; Lee Skinner [75450,3631] z = pixel, f = (pixel) ^ 0.5: z = cosxx (z) + f, |z| <= 50 } Fzppcota {; Lee Skinner [75450,3631] z = pixel, f = sin(pixel) / cosxx(pixel): z = cosxx (z) + f, |z|<= 50 } Fzppcoth {; Lee Skinner [75450,3631] z = pixel, f = tanh(pixel): z = cosxx (z)+f, |z|<= 50 } Fzppexch {; Lee Skinner [75450,3631] z = pixel, f = cosh (pixel): z = exp (z) + f, |z| <= 50 } Fzppexco {; Lee Skinner [75450,3631] z = pixel, f = cosxx (pixel): z = exp (z) + f, |z| <= 50 } Fzppexlo {; Lee Skinner [75450,3631] z = pixel, f = log (pixel): z = exp (z) + f, |z| <= 50 } Fzppexp {; Lee Skinner [75450,3631] z = pixel, f = exp (pixel): z = exp (z) + f, |z| <= 50 } Fzppexsh {; Lee Skinner [75450,3631] z = pixel, f = sinh (pixel): z = exp (z) + f, |z| <= 50 } Fzppexsi {; Lee Skinner [75450,3631] z = pixel, f = sin (pixel): z = exp (z) + f, |z| <= 50 } Fzppexsq {; Lee Skinner [75450,3631] z = pixel, f = sqr (pixel): z = exp (z) + f, |z| <= 50 } Fzppshch {; Lee Skinner [75450,3631] z = pixel, f = cosh (pixel): z = sinh (z) + f, |z| <= 50 } Fzppshco {; Lee Skinner [75450,3631] z = pixel, f = cosxx (pixel): z = sinh (z) + f, |z| <= 50 } Fzppshex {; Lee Skinner [75450,3631] z = pixel, f = exp (pixel): z = sinh (z) + f, |z| <= 50 } Fzppshlo {; Lee Skinner [75450,3631] z = pixel, f = log (pixel): z = sinh (z) + f, |z| <= 50 } Fzppshsi {; Lee Skinner [75450,3631] z = pixel, f = sin (pixel): z = sinh (z) + f, |z| <= 50 } Fzppshsq {; Lee Skinner [75450,3631] z = pixel, f = sqr (pixel): z = sinh (z) + f, |z| <= 50 } Fzppsich {; Lee Skinner [75450,3631] z = pixel, f = cosh (pixel): z = sin (z) + f, |z| <= 50 } Fzppsico {; Lee Skinner [75450,3631] z = pixel, f = cosxx (pixel): z = sin (z) + f, |z| <= 50 } Fzppsiex {; Lee Skinner [75450,3631] z = pixel, f = exp (pixel): z = sin (z) + f, |z| <= 50 } Fzppsinh {; Lee Skinner [75450,3631] z = pixel, f = sinh (pixel): z = sinh (z) + f, |z| <= 50 } Fzppsish {; Lee Skinner [75450,3631] z = pixel, f = sinh (pixel): z = sin (z) + f, |z| <= 50 } Fzppsisq {; Lee Skinner [75450,3631] z = pixel, f = sqr (pixel): z = sin (z) + f, |z| <= 50 } Fzppsqlo {; Lee Skinner [75450,3631] z = pixel, f = log (pixel): z = sqr (z) + f, |z| <= 50 } Fzppsqsh {; Lee Skinner [75450,3631] z = pixel, f = sinh (pixel): z = sqr (z) + f, |z| <= 50 } Fzppsqsi {; Lee Skinner [75450,3631] z = pixel, f = sin (pixel): z = sqr (z) + f, |z| <= 50 } GLYNN(XAXIS) {; Based on an illustration in Science PROBE! and a ; formula by Earl Glynn in Computers and the Imagination, ; by Clifford Pickover. Try p1 = 1.5, p2 = -0.2 ; Jon Horner, FRAC'Cetera ; z = pixel : z = z ^ p1 + p2 , |z| <=4 } Gopalsamy1 {; Ron Barnett [70153,1233] ; try p1 = (0.29,0.29) z = pixel: x = real(z), y = imag(z), x1 = -2*x*y + p1, y = y*y - x*x, z = x1 + flip(y), |z| <= 4 } Gopalsamy2 {; Ron Barnett [70153,1233] ; try p1 = 0.25 z = pixel: x = real(z), y = imag(z), x1 = -4*x*y + p1, y = 4*y*y - x*x, z = x1 + flip(y), |z| <= 4 } Gopalsamy3 {; Ron Barnett [70153,1233] ; try p1 = 1.099 z = pixel: x = real(z), y = imag(z), x1 = 3*x*y*y - x*x*x + p1, y = y*y*y - 3*x*x*y, z = x1 + flip(y), |z| <= 4 } Gopalsamy4 {; Ron Barnett [70153,1233] ; p1 = 0.31 z = pixel: x = real(z), y = imag(z), x1 = -x*y + p1, y = 2*y*y - 3*x*x, z = x1 + flip(y), |z| <= 4 } Gopalsamy5 {; Ron Barnett [70153,1233] ; try p1 = 0.835 z = pixel: x = real(z), y = imag(z), x1 = 2*x*y, y1 = x*x - y*y, x2 = -2*x1*y1 + p1, y = y1*y1 - x1*x1, z = x2 + flip(y), |z| <= 4 } GopalsamySin2 {; Ron Barnett [70153,1233] ; use floating point z = pixel: x = real(z), y = imag(z), x1 = sin(x)*cosh(y), y1 = cos(x)*sinh(y), x2 = -2*x1*y1 + p1, y = y1*y1 - x1*x1, z = x2 + flip(y), |z| <= 100 } GopalsamySin {; Ron Barnett [70153,1233] z = pixel: x = real(z), y = imag(z), x1 = -sin(x)*cosh(y) + p1, y = -cos(x)*sinh(y), z = x1 + flip(y), |z| <= 100 } GopalsamyExp {; Ron Barnett [70153,1233] z = pixel: x = real(z), y = imag(z), x1 = -exp(x)*cos(y) + p1, y = -exp(x)*sin(y), z = x1 + flip(y), |z| <= 100 } GopalsamyExp2 {; Ron Barnett [70153,1233] z = pixel: x = real(z), y = imag(z), x1 = exp(x)*cos(y), y1 = exp(x)*sin(y), x2 = -2*x1*y1 + p1, y = y1*y1 - x1*x1, z = x2 + flip(y), |z| <= 100 } GopalsamySinh2 {; Ron Barnett [70153,1233] z = pixel: x = real(z), y = imag(z), x1 = sinh(x)*cos(y), y1 = cosh(x)*sin(y), x2 = -2*x1*y1 + p1, y = y1*y1 - x1*x1, z = x2 + flip(y), |z| <= 100 } GopalsamySinh {; Ron Barnett [70153,1233] z = pixel: x = real(z), y = imag(z), x1 = -sin(x)*cosh(y) + p1, y = -cos(x)*sinh(y), z = x1 + flip(y), |z| <= 100 } GopalsamyFn {; Ron Barnett [70153,1233] z = pixel: x = real(z), y = imag(z), x1 = fn1(x)*fn2(y), y1 = fn3(x)*fn4(y), x2 = -2*x1*y1 + p1, y = y1*y1 - x1*x1, z = x2 + flip(y), |z| <= 100 } IkeFrRbtGenJ = {; Ron Barnett [70153,1233] z = pixel: z = p1*z*z*z + (p2-1)*z*z - p2, |z| <= 100 } IkeFrRbtGenM = {; Ron Barnett [70153,1233] z = 2*(1-pixel)/(3*p1): z = p1*z*z*z + (pixel-1)*z*z - pixel, |z| <= 100 } IkeGenJ = {; Ron Barnett [70153,1233] z = pixel: z =p1*z*z*z + (p2-1)*z - p2, |z| <= 100 } IkeGenM = {; Ron Barnett [70153,1233] z = ((1-pixel)/(3*p1))^0.5: z =p1*z*z*z + (pixel-1)*z - pixel, |z| <= 100 } xfractint-20.4.10.orig/formulas/fract003.frm0000644000000000000000000005647010627420161015400 0ustar RCL_Pick1 (XAXIS) { ; Ron Lewen, 76376,2567 ; Try corners=2.008874/-3.811126/-3.980167/3.779833/ ; -3.811126/3.779833 to see Figure 9.7 (P. 123) in ; Pickover's Computers, Pattern, Chaos and Beauty. ; Figures 9.9 - 9.13 can be found by zooming. ; Use floating point z=0: z=cosh(z) + pixel, abs(z) < 40 } RCL_Pick10 (XAXIS) { ; Ron Lewen, 76376,2567 ; Variation of Figure 9.18 (p.134) from Pickover's ; Book. Generates an interesting Biomorph. z=pixel: z=z/pixel-pixel*sqr(z), abs(z) < 8 } RCL_Pick11 (XAXIS) { ; Ron Lewen, 76376,2567 ; Formula from Figure 8.3 (p. 98) of Pickover's ; book. Generates a biomorph. Figure 8.3 is a ; zoom on one of the shapes at the corner of the ; biomorph. ; Use Floating Point z=pixel: z=z^2+0.5 |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Pick12 { ; Ron Lewen, 76376,2567 ; Formula from Figure 12.7 (p. 202) of Pickover's ; book. ; Use Floating Point z=pixel: z=(2.71828^(p1)) * z * (1-z), abs(real(z)) < 10 || abs(imag(z)) < 10 } RCL_Pick13 { ; Ron Lewen, 76376,2567 ; Formula from Frontpiece for Appendix C ; and Credits in Pickover's book. ; Set p1=(3,0) to generate the Frontpiece ; for Appendix C and to (2,0) for Credits ; Use Floating Point z=.001: z=z^p1+(1/pixel)^p1, |z| <= 100 } RCL_Pick2_J { ; Ron Lewen, 76376,2567 ; A julia set based on the formula in Figure 8.9 ; (p. 105) of Pickover's book. Very similar to ; the Frontpiece for Appendix A. z=pixel: z=sin(z) + z^2 + p1, abs(real(z)) < 100 || abs(imag(z)) < 100 } RCL_Pick2_M (XAXIS) { ; Ron Lewen, 76376,2567 ; Generates a biomorph of a Pseudo-Mandelbrot set with ; extra tails. Part of Pickover's Biomorph Zoo Collection ; Formula is adapted from Pickover's book, Figure 8.9 ; (p. 105) but the result is different. Set corners= ; -2.640801/1.359199/-1.5/1.5 to center image. I use the ; color map that comes as default in WINFRACT. (I guess I ; like purple ). ; Use floating point z=pixel: z=sin(z) + z^2 + pixel, |real(z)| < 100 || |imag(z)| < 100 } RCL_Pick3 (XAXIS) { ; Ron Lewen, 76376,2567 ; Generates Figure 9.18 (p. 134) from Pickover's book. ; Set maxiter >= 1000 to see good detail in the spirals ; in the three large lakes. Also set inside=0. z=0.5: z=z*pixel-pixel/sqr(z), abs(z) < 8 } RCL_Pick4 (XAXIS) { ; Ron Lewen, 76376,2567 ; Variation of formula for Figure 9.18 (p. 134) from Pickover's ; book. ; Set inside=0 to see three large lakes around a blue "core". z=pixel: z=z*pixel-pixel/sqr(z), |z| <= 4 } RCL_Pick5 (XAXIS) { ; Ron Lewen, 76376,2567 ; Adapted from Pickover's Biomorph Zoo Collection in ; Figure 8.7 (p. 102). z=pixel: z=z^z + z^5 + pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Pick6 (XAXIS) { ; Ron Lewen, 76376,2567 ; Adapted from Pickover's Biomorph Zoo Collection in ; Figure 8.7 (p. 102). z=pixel: z=z^z + z^6 + pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Pick7 (XAXIS) { ; Ron Lewen, 76376,2567 ; Adapted from Pickover's Biomorph Zoo Collection in ; Figure 8.7 (p. 102). z=pixel: z=z^5 + pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Pick8 (XAXIS) { ; Ron Lewen, 76376,2567 ; Adapted from Pickover's Biomorph Zoo Collection in ; Figure 8.7 (p. 102). z=pixel: z=z^3 + pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Pick9 (XAXIS) { ; Ron Lewen, 76376,2567 ; Adapted from Pickover's Biomorph Zoo Collection in ; Figure 8.7 (p. 102). z=pixel: z=sin(z) + 2.71828^z + pixel, |real(z)| <= 100 || |imag(z)| <= 100 } RCL_Quaternion_J (ORIGIN) { ; Ron Lewen, 76376,2567 ; From Pseudocode 10.56 (p. 169) of Pickover's book. ; Looks at Julia set for a0,a2 plane. p1 selects ; slice in to look at. ; p2 corresponds to a point on the Quaternion ; Mandelbrot set (see below). ; Try (-.745,.113) as a starting point. a0=real(pixel), a2=imag(pixel), a1=real(p1), a3=imag(p1): savea0=a0^2-a1^2-a2^2-a3^2+p2, savea2=2*a0*a2+p2, a0=savea0, a2=savea2, (a0^2+a1^2+a2^2+a3^2) <= 2 } RCL_Quaternion_M (XAXIS) { ; Ron Lewen, 76376,2567 ; From Pseudocode 10.5 (p. 169) of Pickover's book. ; Looks at Mandelbrot set for a0,a2 plane. ; p1 selects slice in to look at. p1 should ; not be (0,0) (this yields a blank screen!). a0=a2=pixel, a1=real(p1), a3=imag(p1): savea0=a0^2-a1^2-a2^2-a3^2+pixel, savea2=2*a0*a2+pixel, a0=savea0, a2=savea2, (a0^2+a1^2+a2^2+a3^2) <= 2 } REB004A = {; Ron Barnett [70153,1233] ; try p1 = 0.9, p2 = 2, fn1 = sin, fn2 = cos z = pixel: z =p1*fn1(z) + p1*p1*fn2(p2*z) + pixel, |z| <= 100 } REB004B = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = 3 z = pixel: z = pixel + p1*(z/2 + z*z/6 + z*z*z/12), |z| <= 100 } REB004C = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = 3, p2 = (-0.009,1.225) z = pixel: z = p2 + p1*(z/2 + z*z/6 + z*z*Z/12), |z| <= 100 } REB004D = {; Ron Barnett [70153,1233] ; try p1 = -1, fn1 = sin z = pixel: z = pixel + fn1(2*z+1)/(2*z+p1), |z| <= 100 } REB004E = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = -1, p2 = -1, fn1 = sin, fn2 = cos z = pixel: z = pixel + fn1(2*z+1)/(2*z+p1); z = z + fn2(4*z+1)/(4*z+p2), |z| <= 100 } REB004F = {; Ron Barnett [70153,1233] ; try p1 = -1, p2 = (-0.92, 0.979), fn1 = sin z = pixel: z = p2 + fn1(2*z+1)/(2*z+p1), |z| <= 100 } REB004G = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = -1, p2 = (0.849,0.087), fn1 = sin, fn2 = cos z = pixel: z = p2 + fn1(2*z+1)/(2*z+p1); z = z + fn2(4*z+1)/(4*z+p1), |z| <= 100 } REB004H = {; Ron Barnett [70153,1233] ; floating point required ; try fn1 = sqr z = pixel: z = pixel + fn1(3/z - z/4), |z| <= 100 } REB004I = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = (-1.354, 0.625) fn1 = sqr z = pixel: z = p1 + fn1(3/z - z/4), |z| <= 100 } REB004J = {; Ron Barnett [70153,1233] ; floating point required ; try fn1 = tan z = pixel: x = flip(pixel + fn1(3/z - z/4)); z = x*z + pixel, |z| <= 100 } REB004K = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = (-0.564, 0.045), fn1 = tan z = pixel: x = flip(pixel + fn1(3/z - z/4)); z = x*z + p1, |z| <= 100 } REB004L = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = 1, p2 - 2, fn1 = tan z = pixel: x = flip(pixel + fn1(p1/z - z/(p2+1))); z = x*z + pixel, |z| <= 100 } REB004M = {; Ron Barnett [70153,1233] ; floating point required ;try p1 = (0.4605, 0.8), fn1 = tan, fn2 = cos z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1(const - 12*x)*x/(4*const); y1 = -fn2(const + 12*x)*y/(4*const); x2 = x1*x1 - y1*y1 + p1; y2 = 2*x*y; z = x2 + flip(y2), |z| <= 100 } REB004N = {; Ron Barnett [70153,1233] z = 0.5: x = pixel*(z - 1/z) + p1, z = pixel*(x - 1/sqr(x) + p2), |z| <= 100 } REB005A = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = 0.77, fn1 = ident, fn2 = ident z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1(const - 12*x)*x/(4*const); y1 = -fn2(const + 12*y)*y/(4*const); x2 = x1*x1 - y1*y1 + p1; y2 = 2*x1*y1; z = x2 + flip(y2), |z| <= 100 } REB005B = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = 0.01, fn1 = ident, fn2 = ident z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1(const - x)*x/const; y1 = -fn2(const + y)*y/const; x2 = x1*x1 - y1*y1 + p1; y2 = 2*x1*y1; z = x2 + flip(y2), |z| <= 100 } REB005C = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = -0.5, p2 = -0.1, fn1 = ident, fn2 = ident z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1(const + p1*x)*x/const; y1 = -fn2(const + y)*y/const; x2 = x1*x1 - y1*y1 + p2; y2 = 2*x1*y1; z = x2 + flip(y2), |z| <= 100 } REB005D = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = -1, p2 = -1, fn1 = sin, fn2 = ident z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1((const + p1*x)*x/const); y1 = -fn2((const + y)*y/const); x2 = x1*x1 - y1*y1 + p2; y2 = 2*x1*y1; z = x2 + flip(y2), |z| <= 100 } REB005E = {; Ron Barnett [70153,1233] ; floating point required ; try p1 = (0,0.09), fn1 = sin, fn2 = tan z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1((const - x)*x/const); y1 = -fn2((const + y)*y/const); x2 = x1*x1 - y1*y1 + p1; y2 = 2*x1*y1; z = x2 + flip(y2), |z| <= 100 } REB005G = {; Ron Barnett [70153,1233] ; floating point required ; try fn1 = ident, fn2 = sin z = pixel: x = real(z), y = imag(z); const = x*x + y*y; x1 = -fn1(const + p1*x)*y/const; y1 = -fn2(const + y)*x/const; x2 = x1*x1 - y1*y1 + p2; y2 = 2*x1*y1; z = x2 + flip(y2), |z| <= 100 } REBRefInd1 = {; Ron Barnett [70153,1233] ; Use floating point ; p1 = 1, p2 = 2, fn1 = sin, fn2 = sqr z = pixel: z = (z*z-p1)/(z*z+p2)*fn1(z)*fn2(z) + pixel, |z| <= 100 } REBRefInd2 = {; Ron Barnett [70153,1233] ; Use floating point ; try p1 = (0.489, 0.844), fn1 = sin, fn2 = sqr z = pixel: z = (z*z-1)/(z*z+2)*fn1(z)*fn2(z) + p1, |z| <= 100 } REBRefInd3 = {; Ron Barnett [70153,1233] ; Use floating point ; p1 = (0.48, 0.67), fn1 = sin z = pixel: z = (z*z-1)/(z*z+2)*fn1(z) + p1, |z| <= 100 } REBRefInd4 = {; Ron Barnett [70153,1233] ; Use floating point ; try p1 = 1, p2 = 2, fn1 = cosh, fn2 = sqr z = pixel: z = flip(z); z = (z*z-p1)/(z*z+p2)*fn1(z)*fn2(z) + pixel, |z| <= 100 } REBRefInd5 = {; Ron Barnett [70153,1233] ; Use floating point ; try p1 = (0.46, 0.482), fn1 = cosh, fn2 = sqr z = pixel: z = flip(z); z = (z*z-1)/(z*z+2)*fn1(z)*fn2(z) + p1, |z| <= 100 } RecipIke = {; Ron Barnett [70153,1233] ; try p1 = (-1.44,-0.4) with royal.map z = pixel: z = 1/(z*z*z + (p1-1)*z - p1), |z| <= 4 } quadrants { ; floating point is recommended z=0, c=pixel, r1=(0.0,1.0), r2=(-1.0,0.0), r3=(0.0,-1.0), r4=1: z=sqr(z)+c, x=real(z), y=imag(z), xp=(0 < x), xn=(x < 0), yp=(0 < y), yn=(y < 0), k1=xp*yp, k2=xn*yp, k3=xn*yn, k4=xp*yn, k=k1*r1+k2*r2+k3*r3+k4*r4, c=c+k*p1/z, |z| <= 4 } Sam_0(XAXIS) = {; from SAM.FRM z = Pixel: z = z^z - pixel } Sam_1(XAXIS) = {; from SAM.FRM z = Pixel: z = z^(-z) - pixel } Sam_10(XYAXIS) = {; from SAM.FRM z = Pixel: z = sin(1/z) } Sam_11(XAXIS) = {; from SAM.FRM ;Try this with periodicity=none command line z = Pixel: z = sinh(1/z) } Sam_2(XAXIS) = {; from SAM.FRM ; use integer math, not floating point or you will get a blank screen z = Pixel: z = z^(1/z) - pixel } Sam_3(XAXIS) = {; from SAM.FRM z = Pixel: z = z^z^z - pixel } Sam_4(XAXIS) = {; from SAM.FRM z = Pixel: z = z^(z^(1/z)) - pixel } Sam_5(XAXIS) = {; from SAM.FRM z = Pixel: z = z^2.718281828 + pixel } Sam_6(XYAXIS) = {; from SAM.FRM z = Pixel: z = z*cos(z) - pixel } Sam_7(XAXIS) = {; from SAM.FRM z = Pixel: z = z*sin(z) - pixel } Sam_8 = {; from SAM.FRM ;fix by Ron Barnett [70153,1233] z = c = Pixel: z = z^c } Sam_9(XYAXIS) = {; from SAM.FRM z = Pixel: z = z*tanh(z) } ScottLPC(XAXIS) {; Lee Skinner [75450,3631] z = pixel, TEST = (p1+3): z = log(z)+cosxx(z), |z| lastsqr } SinEgg(XAXIS_NOPARM)[float=y function=sin/sqr] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=sin, fn2=sqr ; Try p1=0, p2=4, fn1=sinh, fn2=sqr ; Use floating point. z = p1, x = |z|: IF (1 < x) z=fn1(z) + pixel ENDIF z = fn2(z)+pixel x = |z| x <= p2 } SinInvZ(XYAXIS) = { z=pixel, inv=1/pixel+p1: z=sin(inv/z), |z|<=4 } SinhInvZ(XYAXIS) = { z=pixel, inv=1/pixel+p1: z=sinh(inv/z), |z|<=4 } Something (xaxis) = { z = pixel: z = pixel + z*z + 1/z/z, |z| <= 4 } Somethingelse (xyaxis) = { z = 1: z = pixel * (z*z + 1/z/z), |z| <= 1000000 } SymmIcon {; Darell Shaffer [76040,2017] z = P1, x = P2, bar = (1,-1), l = real(P1), a = imag(P2), b = .2, g = .1, w = 0, n = 5: zbar = z*bar; z = ((l +(a *z *zbar) +(b *real(z^n)) +(w *i)) *z) +g *(zbar^(n-1)) +pixel; } SymmIconFix {; Darell Shaffer [76040,2017] ; Fix by Jonathan Osuch z = P1, x = P2, l = real(P1), a = imag(P2), b = .2, g = .1, w = 0, n = 5: zbar = conj(z); z = ((l +(a *z *zbar) +(b *real(z^n)) +(w *i)) *z) +g *(zbar^(n-1)) +pixel; } TanInvZ(XYAXIS) = { z=pixel, inv=1/pixel+p1: t=inv/z, z=sin(t)/cos(t), |z|<=4 } TanhInvZ(XYAXIS) = { z=pixel, inv=1/pixel+p1: z=tanh(inv/z), |z|<=4 } test {; Michael Theroux [71673,2767] ;fix and generalization by Ron Barnett [70153,1233] ;=phi ; try p1 = 2.236067977 for the golden mean z = ((p1 + 1)/2)/pixel: z = z*z + pixel*((p1 + 1)/2), |z| <= 4; } test1 {; Michael Theroux [71673,2767] ;fix and generalization by Ron Barnett [70153,1233] ;=phi ; try p1 = 2.236067977 for the golden mean c = pixel, z = ((p1 + 1)/2): z = z*z + pixel*((p1 + 1)/2) + c, |z| <= 4; } test2 {; Michael Theroux [71673,2767] ;fix and generalization by Ron Barnett [70153,1233] ;=phi ; try p1 = 2.236067977 for the golden mean z = ((p1 + 1)/2)/pixel: z = z*z*z + pixel*((p1 + 1)/2), |z| <= 4; } test3 {; Michael Theroux [71673,2767] ;fix and generalization by Ron Barnett [70153,1233] ;=phi ; try p1 = 2.236067977 for the golden mean z = ((p1 + 1)/2)/pixel: z = z*z + pixel*((p1 + 1)/2)/((p1 - 1)/2), |z| <= 4; } testm { ; Try p1=0.25 and p2=0.15 with float=y or potential=255/800/255 z = 0, c=pixel: z = sqr(z)+c, c=c+(p1 * (|z| <= p2)), |z| <= 4 } TjerCGhalley (XYAXIS) {; Chris Green -- Halley's formula ; Modified by Tobey J. E. Reed [76437,375] ; P1 usually 1 to 1.5, P2 usually zero. Use floating point. z=(1,1): z5=z*z*z*z*z, z6=z*z5, z7=z*z6, z=z-p1*((z7-z+pixel)/ ((p1*z6-3)-(8.0*z5)*(z7+z-pixel)/(3.30*z6-12))), 0.0001 <= |z7-z-pixel| } TjerCubic (XYAXIS) {; Lee Skinner [75450,3631] ; Modified by Tobey J. E. Reed [76437,375] p = pixel, test = p1 + 3, t3 = 5*p, t2 = p*p, a = (t2 + 1)/t3+t2, b = 3.149*a*a*a + (t2 - 5)/t2, aa3 = a*a*p1, z = 0 - a : z = z*z - aa3*z + a, |z| < test } TjerDeltaLog(XAXIS) {; Mark Peterson ; Modified by Tobey J. E. Reed [76437,375] z = pixel, c = log(pixel): z = cosh(z) + c/2, |z| <= 4 } TjerDragon {; Mark Peterson ; Modified by Tobey J. E. Reed [76437,375] z = Pixel: z = tan(z) + (-0.74543, 0.2), |z| <= 4 } TjerEnt {; Scott Taylor ; Modified by Tobey J. E. Reed [76437,375] ; Try params=.5/.75 and the first function as exp. ; Zoom in on the swirls around the middle. There's a ; symmetrical area surrounded by an asymmetric area. z = Pixel, y = fn1(z)+p1, base = log(p1): z = y * 3.1416 * log(z)/base, |z| <= 5 } TjerFzppfnpo {; Lee Skinner [75450,3631] ; Modified by Tobey J. E. Reed [76437,375] z = pixel, f = 2*(pixel)^(pixel): z = fn1(z) + f, |z| <= 50 } TjerFzppfnre {; Lee Skinner [75450,3631] ; Modified by Tobey J. E. Reed [76437,375] z = pixel, f = 1./(pixel): z = fn1(z) + f * p1, |z| <= 50 } TjerHyperMandel {; Chris Green. ; Modified and Generalized by Tobey J. E. Reed [76437,375] ; A four dimensional version of the mandelbrot set. ; Use P1 to select which two-dimensional plane of the ; four dimensional set you wish to examine. ; Use floating point. a=(0,0),b=(0,0): z=z+1, anew=fn1(a)-fn1(b)+pixel, b=3.17*a*b-p1, a=anew, |a|+|b| <= 4 } TjerInvMandel (XAXIS) {; Mark Peterson ; Modified by Tobey J. E. Reed [76437,375] c = z = 1 / pixel: z = cos(z) + 2*c; |z| <= 4 } TjerMandelTangent {; Fractal Creations example (revised for v.16) ; Modified by Tobey J. E. Reed [76437,375] z = pixel: z = pixel * tan(z) * 3.14159 * p1, |real(z)| < 32 } TjerMTet (XAXIS) {;Mandelbrot form 1 of the Tetration formula -- Lee Skinner ; Modified and Generalized by Tobey J. E. Reed [76437,375] z = pixel: z = (pixel ^ z + pixel) + fn1(pixel), |z| <= (P1 + 3) } TjerNewton4(XYAXIS) {; Mark Peterson ; Modified by Tobey J. E. Reed [76437,375] z = pixel, Root = 1: z3 = z*z*z, z4 = z3 * z, z = (3 / z4 - Root) / (6 * z3), .004 <= |z4 - Root| } TjerNewtonSinExp (XAXIS) {; Chris Green ; Generalized by Tobey J. E. Reed [76437,375] ; Newton's formula applied to sin(x)+exp(x)-1=0. ; Use floating point. z=pixel: z1=exp(z), z2=sin(z)+z1-1, z=z-p1*z2/(fn1(z)-z1), .0001 < |z2| } TLog (XAXIS) = {; Lee Skinner [75450,3631] z = c = log(pixel): z = c ^ z, z <= (p1 + 3) } Tobey3(XAXIS) = { z = pixel: c = pixel - sqr(z), c = pixel + c/z, z = c - z * pixel, |z| < 4 } TobeyCGNewton3 {; Chris Green -- A variation on newton iteration. ; Modified and Generalized by Tobey J. E. Reed [76437,375] ; The initial guess is fixed at (1,1), but the equation solved ; is different at each pixel ( x^3-pixel=0 is solved). ; Use floating point. ; Try P1=1.8. z=(1,1): z2=z*z, z3=z*z2, z=z-p1*fn1((z2-pixel)/(2.13*z2)), 0.0001 < |z3-pixel| } TobeyHalley (XYAXIS) {; Chris Green. Halley's formula applied to x^7-x=0. ; Modified and Generalized by Tobey J. E. Reed [76437,375] ; P1 usually 1 to 1.5, P2 usually zero. Use floating point. ; Setting P1 to 1 creates the picture on page 277 of Pickover's book z=pixel: z5=z*z*z*z*z, z6=fn1(z*z5), z7=fn2(z*z6), z=fn2(z-p1*((z7-z))/ (fn1((7.0*z6-1)-(42.0*z5)*(z7-z)/(14.0*z6-2)))), 0.0001 <= |z7-z| } TobeyHalleySin (XYAXIS) {; Chris Green. Halley's formula applied to sin(x)=0. ; Generalized by Tobey J. E. Reed [76437,375] ; Use floating point. ; P1 = 0.1 will create the picture from page 281 of Pickover's book. z=pixel: s=fn1(z), c=fn2(z) z=z+p1*(s/(c-(s-s)/(c*c))), 0.0001 <= |s| } TobeyLeeMandel1(XYAXIS) {; Kevin Lee ; Generalized by Tobey J. E. Reed [76437,375] z=Pixel: c=fn1(pixel)/z, c=z+2*c, z=fn2(z+1), |z|<4 } TobeyLeeMandel2(XYAXIS) {; Kevin Lee ; Generalized by Tobey J. E. Reed [76437,375] z=Pixel: c=fn1(pixel)/z, c=z+c, z=fn2(c*pixel), |z|<4 } TobeyLeeMandel3(XAXIS) {; Kevin Lee ; Generalized by Tobey J. E. Reed [76437,375] z=Pixel, c=Pixel-fn1(z): c=Pixel+c/z, z=c-fn2(z*pixel), |z|<4 } TobeyMyFractal {; Fractal Creations example ; Generalized by Tobey J. E. Reed [76437,375] c = z = 1/pixel: z = fn1(z) + c/p1, |z| <= 4 } TobeyPsudoMandel(XAXIS) {; davisl - try center=0,0/magnification=28 ; Generalized by Tobey J. E. Reed [76437,375] z = Pixel: z = ((z/2.7182818)^z)*fn1(6.2831853*z) + pixel, |z| <= 4 } TobeyRichard1 (XYAXIS) {; Jm Richard-Collard ; Generalized by Tobey J. E. Reed [76437,375] z = pixel: sq=z*z, z=(sq*fn1(sq)+sq)+pixel, |z|<=50 } TobeyRichard2 (XYAXIS) {; Jm Richard-Collard ; Generalized by Tobey J. E. Reed [76437,375] z = pixel: z=1/(fn1(z*z+pixel*pixel)), |z|<=50 } TobeyRichard3 (XAXIS) {; Jm Richard-Collard ; Generalized by Tobey J. E. Reed [76437,375] z = pixel: sh=fn1(z), z=(1/(sh*sh))+pixel, |z|<=50 } TobeySterling(XYAXIS) {; davisl ; Generalized by Tobey J. E. Reed [76437,375] z = Pixel: z = (fn1((z/2.7182818)^z))/fn2(6.2831853*z), |z| <= 4 } TobeySterling2(XAXIS) {; davisl ; Generalized by Tobey J. E. Reed [76437,375] z = Pixel: z = ((z/2.7182818)^z)/fn1(6.2831853*z) + pixel, |z| <= 4 } TobeyWineglass(XAXIS) {; Pieter Branderhorst ; Modified and Generalized by Tobey J. E. Reed [76437,375] c = z = pixel: z = z * z + c, c = (1+flip(imag(fn1(c)))) * real(fn1(c)) / 3 + z, |z| <= 4 } TSinh (XAXIS) = {; Lee Skinner [75450,3631] z = c = sinh(pixel): z = c ^ z, z <= (p1 + 3) } TurtleC(XAXIS_NOPARM)[float=y function=sqr/sqr] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=sqr, fn2=sqr ; Note: use floating point z = p1: x = real(z), IF (x < 0) z = fn1(z) + pixel ELSE z = fn2(z) - pixel ENDIF |z| <= p2 } ULI_1 = {; from ULI.FRM z = Pixel: z = fn1(1/fn2(z)), |z| <= 4 } ULI_2 = {; from ULI.FRM z = Pixel: z = fn1(1/fn2(z+p1)), |z| <= p2 } ULI_3 = {; from ULI.FRM z = Pixel: z = fn1(1/fn2(z+p1)+p1), |z| <= p2 } ULI_4 = {; from ULI.FRM z = Pixel: z = fn1(1/(z+p1))*fn2(z+p1), |z| <= p2 } ULI_5 = {; from ULI.FRM z = Pixel, c = fn1(pixel): z = fn2(1/(z+c))*fn3(z+c), |z| <= p1 } ULI_6 = {; from ULI.FRM z = Pixel: z = fn1(p1+z)*fn2(p2-z), |z| <= p2+16 } WaldoTwinsC(XAXIS_NOPARM)[float=y function=cosxx/sin] {; Jonathan Osuch ; Generalized by Tobey J. E. Reed [76437,375] ; Try p1=0, p2=4, fn1=cosxx, fn2=sin ; Note: use floating point z = p1: z = fn1(fn2(z+pixel)) + pixel, |z| <= p2 } Whatever_the_name(XAXIS) = { z = pixel: z=z*z+(1/z*z)+pixel, } z^3-1=0(XAXIS) { ; Advanced Fractal Programming in C - Stevens ; Run with inside = ZMAG to turn off periodicity checking x=real(pixel), y=imag(pixel): x2 = x*x, y2 = y*y, xold = x, yold = y, xmy = x2 - y2, d = 3 * (xmy * xmy + 4*x2*y2), x = .66666667*x + xmy/d, y = .66666667*y - 2*x*y/d, x != xold && y != yold } Ze2 (XAXIS) = {; Lee Skinner [75450,3631] s1 = exp(1.,0.), s = s1 * s1, z = Pixel: z = z ^ s + pixel, |z| <= 100 } Zexpe (XAXIS) = {; Lee Skinner [75450,3631] s = exp(1.,0.), z = Pixel: z = z ^ s + pixel, |z| <= 100 } Zexpe2 (XAXIS) = {; Lee Skinner [75450,3631] s = exp(1.,0.), z = Pixel: z = z ^ s + z ^ (s * pixel), |z| <= 100 } Zppchco8 {; Lee Skinner [75450,3631] z = pixel, f = cosxx (pixel): z = cosh (z) + f, |z|<=8192 } xfractint-20.4.10.orig/formulas/julitile.frm0000644000000000000000000000354610150633601015667 0ustar {========================================================================= = File originally distributed with FRAC'Cetera Vol 2 Iss 7 = ========================================================================== = Original idea submitted to FRAC'Cetera by : Ray Girvan. Generalized = = by Jon Horner. = F'names, where present, represent FRAC'Cetera created variations or = = derivatives based, often quite loosely, on the author's originals. = =========================================================================} !_Press_F2_! {; There is text in this formula file. Shell to DOS with ; the key and use a text reader to browse the file. } Julitile1 { ; Based on an idea by Ray Girvan z = fn1(real(pixel))+p1*fn2(imag(pixel)) : z = z * z + p2 |z| <=4 } Julitile2XY(XYaxis) { ; force x/y symmetry - Jon Horner z = (0,0), z = fn1(real(pixel))+p1*fn2(imag(pixel)) : z = z * z + p2 |real(z)| <=10 || |imag(z)| <=10 } Julitile3b { ; No sym - Jon Horner z = fn1(real(pixel))+p1*fn2(imag(pixel)) : z = z * z + p2 |real(z)| <=10 || |imag(z)| <=10 } Julitile3c { ; Jon Horner z = fn1(real(pixel))+p1*fn2(imag(pixel)), c = pixel : z = z * z + c |real(z)| <=10 || |imag(z)| <=10 } Julitile3d { ; Jon Horner z = c = pixel, z = fn1(real(pixel)) + c*fn2(imag(pixel)), test = p1 + 10 : z = z * z + p2 |real(z)| <=test || |imag(z)| <=test } Julitile3e { ; Jon Horner z = c = pixel, z = fn1(real(pixel)) + c*fn2(imag(pixel)) : z = z ^ p1 + p2 |real(z)| <=10 || |imag(z)| <=10 } xfractint-20.4.10.orig/formulas/fract196.frm0000644000000000000000000006132310150633601015402 0ustar comment { This formula file, released with Fractint 19.6, contains the new versions of all the Fractint.frm formulas that use conditional statements, followed by the original version commented out. } {--- BRADLEY BEACHAM -----------------------------------------------------} OK-32 { ; Modified for if..else logic 3/19/97 by Sylvie Gallet z = y = x = pixel , k = 1 + p1 , test = 5 + p2 : a = fn1(z) IF (a <= y) b = y ELSE b = x ENDIF x = y , y = z , z = a*k + b |z| <= test } ; Original version ; OK-32 { ; z = y = x = pixel, k = 1 + p1: ; a = fn1(z) ; b = (a <= y) * ((a * k) + y) ; e = (a > y) * ((a * k) + x) ; x = y ; y = z ; z = b + e ; |z| <= (5 + p2) ; } OK-34 { ; Modified for if..else logic 3/19/97 by Sylvie Gallet z = pixel , c = fn1(pixel) * p1 , test = 10 + p2 : x = abs(real(z)) , y = abs(imag(z)) IF (x <= y) z = fn2(z) + y + c ELSE z = fn2(z) + x + c ENDIF |z| <= test } ; Original version ; OK-34 { ; z = pixel, c = (fn1(pixel) * p1): ; x = abs(real(z)) ; y = abs(imag(z)) ; a = (x <= y) * (fn2(z) + y + c) ; b = (x > y) * (fn2(z) + x + c) ; z = a + b ; |z| <= (10 + p2) ; } OK-35 { ; Modified for if..else logic 3/19/97 by Sylvie Gallet z = pixel, k = 1 + p1 , test = 10 + p2 : v = fn1(z) , x = z*v , y = z/v IF (|x| <= |y|) z = fn2((z + y) * k * v) + v ELSE z = fn2((z + x) * k * v) + v ENDIF |z| <= test } ; Original version ; OK-35 { ; z = pixel, k = 1 + p1: ; v = fn1(z) ; x = (z*v) ; y = (z/v) ; a = (|x| <= |y|) * ((z + y) * k) ; b = (|x| > |y|) * ((z + x) * k) ; z = fn2((a + b) * v) + v ; |z| <= (10 + p2) ; } Larry { ; Mutation of 'Michaelbrot' and 'Element' ; Original formulas by Michael Theroux [71673,2767] ; Modified for if..else logic 3/19/97 by Sylvie Gallet ; For 'Michaelbrot', set FN1 & FN2 =IDENT and P1 & P2 = default ; For 'Element', set FN1=IDENT & FN2=SQR and P1 & P2 = default ; p1 = Parameter (default 0.5,0), real(p2) = Bailout (default 4) z = pixel ; The next line sets c=default if p1=0, else c=p1 IF (real(p1) || imag(p1)) c = p1 ELSE c = 0.5 ENDIF ; The next line sets test=4 if real(p2)<=0, else test=real(p2) IF (real(p2) <= 0) test = 4 ELSE test = real(p2) ENDIF : z = fn1(fn2(z*z)) + c |z| <= test } ; Original version ; Larry { ; Mutation of 'Michaelbrot' and 'Element' ; ; Original formulas by Michael Theroux [71673,2767] ; ; For 'Michaelbrot', set FN1 & FN2 =IDENT and P1 & P2 = default ; ; For 'Element', set FN1=IDENT & FN2=SQR and P1 & P2 = default ; ; p1 = Parameter (default 0.5,0), real(p2) = Bailout (default 4) ; z = pixel ; ; The next line sets c=default if p1=0, else c=p1 ; c = ((0.5,0) * (|p1|<=0) + p1) ; ; The next line sets test=4 if real(p2)<=0, else test=real(p2) ; test = (4 * (real(p2)<=0) + real(p2) * (0 moldz) c = c*k ENDIF oldz = z , moldz = mz , z = fn1(z*z) + c , mz = |z| mz <= test } ; Original version ; inandout04 { ; ;p1 = Parameter (default 1), real(p2) = Bailout (default 4) ; ;The next line sets k=default if p1=0, else k=p1 ; k = ((1) * (|p1|<=0) + p1) ; ;The next line sets test=4 if real(p2)<=0, else test=real(p2) ; test = (4 * (real(p2)<=0) + real(p2) * (0 -0.225 && y < 0.225) x1 = x*1.8 , x3 = 3*x ty2 = y < 0.025 && y > -0.025 || y > 0.175 IF ( x < -1.2 || ty2 && x > -1.25 && x < -1 ) text = 1 ELSEIF ( x < -0.9 || ty2 && x > -0.95 && x < -0.8 \ || (cabs(sqrt(|z+(0.8,-0.1)|)-0.1) < 0.025 && x > -0.8) \ || (y < -x1-1.44 && y > -x1-1.53 && y < 0.025) ) text = 1 ELSEIF ( y > x3+1.5 || y > -x3-1.2 || (y > -0.125 && y < -0.075) \ && y < x3+1.65 && y < -x3-1.05 ) text = 1 ELSEIF ( cabs(sqrt(|z+0.05|)-0.2) < 0.025 && x < 0.05 ) text = 1 ELSEIF ( (x > 0.225 && x < 0.275 || y > 0.175) && x > 0.1 && x < 0.4 ) text = 1 ELSEIF ( x > 0.45 && x < 0.5 ) text = 1 ELSEIF ( x < 0.6 || x > 0.8 || ((y > -x1+1.215) && (y < -x1+1.305)) \ && x > 0.55 && x < 0.85 ) text = 1 ELSEIF ( x > 1.025 && x < 1.075 || y > 0.175 && x > 0.9 && x < 1.2 ) text = 1 ENDIF ENDIF z = 1 + (0.0,-0.65) / (pixel+(0.0,.75)) : IF (text == 0) z2 = z*z , z4 = z2*z2 , n = z4*z2-1 , z = z-n/(6*z4*z) IF (|n| >= 0.0001) continue = 1 ELSE continue = 0 ENDIF ENDIF continue } ; Original version ; Fractint {; Sylvie Gallet [101324,3444], 1996 ; ; requires 'periodicity=0' ; z = pixel-0.025 , x=real(z) , y=imag(z) , x1=x*1.8 , x3=3*x ; ty2 = ( (y<0.025) && (y>-0.025) ) || (y>0.175) ; f = ( (x<-1.2) || ty2 ) && ( (x>-1.25) && (x<-1) ) ; r = ( (x<-0.9) || ty2 ) && ( (x>-0.95) && (x<-0.8) ) ; r = r || ((cabs(sqrt(|z+(0.8,-0.1)|)-0.1)<0.025) && (x>-0.8)) ; r = r || (((y<(-x1-1.44)) && (y>(-x1-1.53))) && (y<0.025)) ; a = (y>(x3+1.5)) || (y>(-x3-1.2)) || ((y>-0.125) && (y<-0.075)) ; a = a && ((y<(x3+1.65)) && (y<(-x3-1.05))) ; c = (cabs(sqrt(|z+0.05|)-0.2)<0.025) && (x<0.05) ; t1 = ((x>0.225) && (x<0.275) || (y>0.175)) && ((x>0.1) && (x<0.4)) ; i = (x>0.45) && (x<0.5) ; n = (x<0.6) || (x>0.8) || ((y>-x1+1.215) && (y<-x1+1.305)) ; n = n && (x>0.55) && (x<0.85) ; t2 = ((x>1.025) && (x<1.075) || (y>0.175)) && ((x>0.9) && (x<1.2)) ; test = 1 - (real(f||r||a||c||t1||i||n||t2)*real(y>-0.225)*real(y<0.225)) ; z = 1+(0.0,-0.65)/(pixel+(0.0,.75)) : ; z2 = z*z , z4 = z2*z2 , n = z4*z2-1 , z = z-n/(6*z4*z) ; (|n|>=0.0001) && test ; } comment { Five-Mandels shows five Mandelbrot sets that fit into each other. It uses the following algorithm: z=c=pixel FOR iter:=0 to l1-1 IF the orbit of z*z + c escapes THEN end ELSE z:=z1 FOR iter:=L1+1 to l2-1 IF the orbit of z*z + z1 escapes THEN end ELSE z:=z2 FOR iter:=L2+1 to l3-1 ... To work correctly, this formula requires the use of periodicity=0. } Five-Mandels (XAXIS) {; Sylvie Gallet [101324,3444], 1996 ; 0 < real(p1) < imag(p1) < real(p2) < imag(p2) < maxiter, periodicity=0 ; Modified for if..else logic 3/17/97 by Sylvie Gallet c = z = zorig = pixel bailout = 16 , iter = 0 : IF (iter == p1) z = c = 1.5 * zorig ELSEIF (iter == imag(p1)) z = c = 2.25 * zorig ELSEIF (iter == p2) z = c = 3.375 * zorig ELSEIF (iter == imag(p2)) z = c = 5.0625 * zorig ENDIF z = z*z + c iter = iter + 1 |z| <= bailout } ; Original version ; Five-Mandels (XAXIS) {; Sylvie Gallet [101324,3444], 1996 ; ; 0 < real(p1) < imag(p1) < real(p2) < imag(p2) < maxiter, periodicity=0 ; c = z = pixel ; z1 = 1.5*z , z2 = 2.25*z , z3 = 3.375*z , z4 = 5.0625*z ; l1 = real(p1) , l2 = imag(p1) , l3 = real(p2) , l4 = imag(p2) ; bailout = 16 , iter = 0 : ; t1 = (iter==l1) , t2 = (iter==l2) , t3 = (iter==l3) , t4 = (iter==l4) ; t = 1-(t1||t2||t3||t4) , ct = z1*t1 + z2*t2 + z3*t3 + z4*t4 ; z = z*t + ct , c = c*t + ct ; z = z*z + c ; iter = iter+1 ; |z| <= bailout ; } comment { The following formula draws the graphs of 4 real functions at a time. } Graph { ; Sylvie Gallet [101324,3444], 1996 ; Modified for if..else logic 3/17/97 by Sylvie Gallet ; 2 parameters: curves thickness = real(p1) ; axes thickness = imag(p1) ; choose for example real(p1) = 0.002 and imag(p1) = 0.001 epsilon = abs(real(p1)) , axes = abs(imag(p1)) z = 0 , x = round(real(pixel)/epsilon) * epsilon IF ((|real(pixel)| <= axes) || (|imag(pixel)| <= axes)) z = z + 1 ENDIF IF (|x + flip(fn1(x))-pixel| <= epsilon) z = z + 2 ENDIF IF (|x + flip(fn2(x))-pixel| <= epsilon) z = z + 4 ENDIF IF (|x + flip(fn3(x))-pixel| <= epsilon) z = z + 8 ENDIF IF (|x + flip(fn4(x))-pixel| <= epsilon) z = z + 16 ENDIF IF (z == 0) z = z + 100 ENDIF : z = z - 1 z > 0 } ; Original version ; Graph { ; Sylvie Gallet [101324,3444], 1996 ; ; 2 parameters: curves thickness = real(p1) ; ; axes thickness = imag(p1) ; ; choose for example real(p1) = 0.002 and imag(p1) = 0.001 ; epsilon = abs(real(p1)) , axes = abs(imag(p1)) ; x = round(real(pixel)/epsilon) * epsilon ; z1 = x + flip(fn1(x)) , z2 = x + flip(fn2(x)) ; z3 = x + flip(fn3(x)) , z4 = x + flip(fn4(x)) ; testaxes = (|real(pixel)|<=axes) || (|imag(pixel)|<=axes) ; testfn1 = 2*(|z1-pixel|<=epsilon) , testfn2 = 4*(|z2-pixel|<=epsilon) ; testfn3 = 8*(|z3-pixel|<=epsilon) , testfn4 = 16*(|z4-pixel|<=epsilon) ; z = testaxes + testfn1 + testfn2 + testfn3 + testfn4 ; z = z + 100*(z==0) : ; z = z - 1 ; z > 0 ; } comment { The following formula overlays a Mandel and a reverse-Mandel, using a checkerboard dithering invisible at very high resolutions. Since it uses the new predefined variable "whitesq", it's now resolution independent and the image can be interrupted, saved and restored. Panning an even number of pixels is now possible. } JD-SG-04-1 { ; Sylvie Gallet [101324,3444], 1996 ; On an original idea by Jim Deutch [104074,3171] ; Modified for if..else logic 3/21/97 by Sylvie Gallet ; use p1 and p2 to adjust the inverted Mandel ; 16-bit Pseudo-HiColor IF (whitesq) z = c = pixel ELSE z = c = p1 / (pixel+p2) ENDIF : z = z*z + c |z| < 4 } ; Original version ; JD-SG-04-1 { ; Sylvie Gallet [101324,3444], 1996 ; ; On an original idea by Jim Deutch [104074,3171] ; ; use p1 and p2 to adjust the inverted Mandel ; ; 16-bit Pseudo-HiColor ; z = c = pixel * whitesq + (p1 / (pixel+p2)) * (whitesq==0) : ; z = z*z + c ; |z| < 4 ; } comment { These formula overlay 3 or 4 fractals. } ptc+mjn { ; Sylvie Gallet [101324,3444], 1996 ; Modified for if..else logic 3/19/97 by Sylvie Gallet ; 24-bit Pseudo-TrueColor ; Mandel: z^2 + c , Julia: z^2 + p1 , Newton: z^p2 - 1 = 0 cr = real(scrnpix) + imag(scrnpix) r = cr - 3 * trunc(cr / real(3)) , z = pixel IF (r == 0) c = pixel , b1 = 256 ELSEIF (r == 1) c = p1 , b1 = 256 ELSE c = 0 , b2 = 0.000001 , ex = p2 - 1 ENDIF : IF (r == 2) zd = z^ex , n = zd*z - 1 z = z - n / (p2*zd) , continue = (|n| >= b2) ELSE z = z*z + c , continue = (|z| <= b1) ENDIF continue } ; Original version ; ptc+mjn { ; Sylvie Gallet [101324,3444], 1996 ; ; 24-bit Pseudo-TrueColor ; ; Mandel: z^2 + c , Julia: z^2 + p1 , Newton: z^p2 - 1 = 0 ; cr = real(scrnpix) + imag(scrnpix) ; r = cr - 3 * trunc(cr / real(3)) ; z = pixel , b1 = 256 , b2 = 0.000001 , ex = p2 - 1 ; c = pixel * (r==0) + p1 * (r==1) : ; zd = z^ex , zn = zd*z , n = zn - 1 , d = p2 * zd ; z = (z*z + c) * (r!=2) + (z - n/d) * (r==2) ; ((|z| <= b1) && (r!=2)) || ((|n| >= b2 ) && (r==2)) ; } ptc+4mandels { ; Sylvie Gallet [101324,3444], 1996 ; 32-bit Pseudo-TrueColor ; Modified for if..else logic 3/21/97 by Sylvie Gallet cr = real(scrnpix) + 2*imag(scrnpix) r = cr - 4 * trunc(cr / 4) IF (r == 0) z = c = pixel ELSEIF (r == 1) z = c = pixel * p1 ELSEIF (r == 2) z = c = pixel * p2 ELSE z = c = pixel * p3 ENDIF : z = z * z + c |z| <= 4 } ; Original version ; ptc+4mandels { ; Sylvie Gallet [101324,3444], 1996 ; ; 32-bit Pseudo-TrueColor ; cr = real(scrnpix) + 2*imag(scrnpix) ; r = cr - 4 * trunc(cr / 4) ; c = r == 0 , c1 = p1 * (r == 1) ; c2 = p2 * (r == 2) , c3 = p3 * (r == 3) ; z = c = pixel * (c + c1 + c2 + c3) : ; z = z * z + c ; |z| <= 4 ; } Gallet-8-21 { ; Sylvie Gallet [101324,3444], Apr 1997 ; Requires periodicity = 0 and decomp = 256 ; p1 = parameter for a Julia set (0 for the Mandelbrot set) ; 0 < real(p2) , 0 < imag(p2) im2 = imag(p2) IF (p1 || imag(p1)) c = p1 ELSE c = pixel ENDIF z = -1 , zn = pixel , zmin = zmin0 = abs(real(p2)) cmax = trunc(abs(real(p3))) IF (cmax < 2) cmax = 2 ENDIF k = flip(6.28318530718/(zmin*real(cmax))) , cnt = -1 : cnt = cnt + 1 IF (cnt == cmax) cnt = 0 ENDIF zn = zn*zn + c , znc = cabs(im2*real(zn) + flip(imag(zn))) IF (znc < zmin) zmin = znc , z = exp((cnt*zmin0 + zmin)*k) ENDIF znc <= 4 } {--- JONATHAN OSUCH ------------------------------------------------------} BirdOfPrey (XAXIS_NOPARM) { ; Optimized by Sylvie Gallet z = p1 : z = cosxx(sqr(z) + pixel) + pixel |z| <= 4 } ; Original version ; BirdOfPrey(XAXIS_NOPARM) { ; z=p1, x=1: ; (x<10)*(z=sqr(z)+pixel) ; (10<=x)*(z=cosxx(z)+pixel) ; x=x+1 ; |z|<=4 ; } FractalFenderC (XAXIS_NOPARM) { ; Spectacular! ; Modified for if..else logic 3/18/97 by Sylvie Gallet z = p1 , x = |z| : IF (1 < x) z = cosh(z) + pixel ENDIF z = sqr(z) + pixel , x = |z| x <= 4 } ; Original version ; FractalFenderC(XAXIS_NOPARM) {;Spectacular! ; z=p1,x=|z|: ; (z=cosh(z)+pixel)*(1 0) mag = real(p2) ELSE mag = 1/3 ENDIF IF (imag(p2) > 0) numtiles = imag(p2) ELSE numtiles = 3 ENDIF omega = numtiles*2*pi/3 x = asin(sin(omega*real(pixel))) , y = asin(sin(omega*imag(pixel))) z = c = (x+flip(y)) / mag + center : z = z*z + c |z| <= 4 } ; Original version ; TileMandel { ; Terren Suydam (terren@io.com), 1996 ; ; modified by Sylvie Gallet [101324,3444] ; ; p1 = center = coordinates for a good Mandel ; ; 0 <= real(p2) = magnification. Default for magnification is 1/3 ; ; 0 <= imag(p2) = numtiles. Default for numtiles is 3 ; center = p1 , mag = real(p2)*(p2>0) + (p2<=0)/3 ; numtiles = imag(p2)*(flip(p2)>0) + 3*(flip(p2)<=0) ; omega = numtiles*2*pi/3 ; x = asin(sin(omega*real(pixel))) , y = asin(sin(omega*imag(pixel))) ; z = c = (x+flip(y)) / mag + center : ; z = z*z + c ; |z| <= 4 ; } TileJulia { ; Terren Suydam (terren@io.com), 1996 ; modified by Sylvie Gallet [101324,3444] ; Modified for if..else logic 3/19/97 by Sylvie Gallet ; p1 = center = coordinates for a good Julia ; 0 <= real(p2) = magnification. Default for magnification is 1/3 ; 0 <= imag(p2) = numtiles. Default for numtiles is 3 ; p3 is the Julia set parameter center = p1 IF (p2 > 0) mag = real(p2) ELSE mag = 1/3 ENDIF IF (imag(p2) > 0) numtiles = imag(p2) ELSE numtiles = 3 ENDIF omega = numtiles*2*pi/3 x = asin(sin(omega*real(pixel))) , y = asin(sin(omega*imag(pixel))) z = (x+flip(y)) / mag + center : z = z*z + p3 |z| <= 4 } ; Original version ; TileJulia { ; Terren Suydam (terren@io.com), 1996 ; ; modified by Sylvie Gallet [101324,3444] ; ; p1 = center = coordinates for a good Julia ; ; 0 <= real(p2) = magnification. Default for magnification is 1/3 ; ; 0 <= imag(p2) = numtiles. Default for numtiles is 3 ; ; p3 is the Julia set parameter ; center = p1 , mag = real(p2)*(p2>0) + (p2<=0)/3 ; numtiles = imag(p2)*(flip(p2)>0) + 3*(flip(p2)<=0) ; omega = numtiles*2*pi/3 ; x = asin(sin(omega*real(pixel))) , y = asin(sin(omega*imag(pixel))) ; z = (x+flip(y)) / mag + center : ; z = z*z + p3 ; |z| <= 4 ; } xfractint-20.4.10.orig/formulas/new_if.frm0000644000000000000000000000772010150633601015313 0ustar Gallet-8-01 { ; Sylvie Gallet [101324,3444], Mar 1997 z = c = pixel , zc = 0 : IF (zc < 0) z = z - p1 ELSE z = z - zc - p1 ENDIF zc = z*c |z| <= p2 } Gallet-8-03 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = c = zn = pixel : zn = zn*zn + c IF (|zn| < |z|) z = 0.6*zn ENDIF |zn| <= 4 } Gallet-8-04 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = zn = pixel , ex = p1 - 1 IF (p2 || imag(p2)) k = p2 ELSE k = 1 ENDIF : znex = zn^ex , num = znex*zn - 1 , den = p1*znex , zn = zn - num/den IF (|num| > |z^p1-1|) z = zn * k ENDIF |num| >= 0.001 } Gallet-8-05 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = c = zn = pixel IF (p1 || imag(p1)) k = p1 ELSE k = 1 ENDIF : zn = zn*zn + c IF (abs(zn) < abs(z) || flip(abs(zn)) < flip(abs(z))) z = k*zn ENDIF |zn| <= 4 } Gallet-8-06 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = c = zn = pixel IF (p1 || imag(p1)) k = p1 ELSE k = 1 ENDIF : zn = zn*zn + c IF (abs(zn) < abs(z) && flip(abs(zn)) < flip(abs(z))) z = k*zn ENDIF |zn| <= 4 } Gallet-8-07 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = c = zn = pixel IF (p1 || imag(p1)) k = p1 ELSE k = 1 ENDIF : zn = zn*zn + c IF (abs(zn) < abs(z)) z = k*real(zn) + flip(imag(z)) ENDIF IF (flip(abs(zn)) < flip(abs(z))) z = real(z) + k*flip(imag(zn)) ENDIF |zn| <= 4 } Gallet-8-08 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = zn = pixel IF (p2 || imag(p2)) k = p2 ELSE k = 1 ENDIF : zn = zn*zn + p1 IF (abs(zn) < abs(z) && flip(abs(zn)) < flip(abs(z))) z = k*zn ENDIF |zn| <= 4 } Gallet-8-11 { ; Sylvie Gallet [101324,3444], Mar 1997 ; PHC, requires periodicity = 0 and passes=1 h = cabs(pixel) , r = real(p3) , ir = imag(p3) IF (h >= r) IF (whitesq) z = pixel , c = p1 ;trunc(p2*pixel)/p2 ELSE z = 200 ENDIF ELSE beta = asin(h/r) , alpha = asin(h/r/ir) h2 = h - sqrt(r*r - h*h) * tan(beta - alpha) z = h2*pixel/h, c = p1 ENDIF : z = z*z + c |z| <= 128 } Gallet-8-12 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 h = cabs(pixel) , pinv = 1/p1 bailout = 2*p1 , r = real(p2) , ir = imag(p2) IF (h >= r) z = pixel ELSE beta = asin(h/r) , alpha = asin(h/(r*ir)) z = (h - sqrt(r*r - h*h) * tan(beta - alpha)) * pixel / h ENDIF center = round(p1*z) * pinv IF (cabs(z-center) < 0.45*pinv) z = cabs(center) ELSE z = cabs(center) + p1 ENDIF : z = z + pinv z <= bailout } Gallet-8-14 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = 0 , c = zn = pixel , zmin = p1 , k = flip(2*pi/zmin) : zn = zn*zn + c , znc = cabs(zn) IF (znc < zmin) zmin = znc , z = exp(zmin*k) ENDIF znc <= 4 } Gallet-8-15 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = 0 , zn = x = y = pixel , zmin = imag(p2) , k = flip(2*pi/zmin) : zn = zn*zn - 0.5*zn + p1 , x = zn*zn - 0.5*y + p1 y = zn , zn = x , znc = cabs(zn) IF (znc < zmin) zmin = znc , z = exp(zmin*k) ENDIF znc <= real(p2) } Gallet-8-16 { ; Sylvie Gallet [101324,3444], Mar 1997 ; Requires periodicity = 0 z = -1 , c = zn = pixel , xmin = ymin = p1 odd = 0 , k = flip(pi/xmin) : zn = zn*zn + c , odd = odd==0 IF (odd) IF (abs(zn) < xmin) xmin = abs(zn) , z = exp(xmin*k) ENDIF ELSE IF (abs(imag(zn)) < ymin) ymin = abs(imag(zn)) , z = exp(-ymin*k) ENDIF ENDIF |zn| <= 16 } xfractint-20.4.10.orig/sstools.ini0000644000000000000000000000070310614633524013720 0ustar [fractint] inside=0 map=maps\default.map ifsfile=ifs\fractint.ifs parmfile=pars\fractint.par lfile=lsystem\fractint.l formulafile=formulas\fractint.frm autokeyname=key\auto.key [xfractint] inside=0 map=maps/default.map ifsfile=ifs/fractint.ifs parmfile=pars/fractint.par lfile=lsystem/fractint.l formulafile=formulas/fractint.frm [Winfract] WinfractPosition=140, 100 ImageWidth=800 ImageHeight=600 WindowSizing=True FractintMenus=True ZoomOut=False xfractint-20.4.10.orig/Makefile0000755000000000000000000003226511340251005013147 0ustar SHELL = /bin/sh STRIP = strip INSTALL = /usr/bin/install # Architecture # automatic detection ARCH = `uname -m | tr "_" "-"` # ARCH = pentium # ARCH = x86-64 # ARCH = athlon64 # Optimization flags OPT = -O2 # OPT = -O # Uncomment the second line if you want to compile with ncurses support # (as in older versions of xfractint) NCURSES = # NCURSES = -DNCURSES ifndef PREFIX PREFIX = /usr endif ifndef DESTDIR DESTDIR = $(PREFIX) endif # SRCDIR should be a path to the directory that will hold fractint.hlp # SRCDIR should also hold the .par, .frm, etc. files SRCDIR = $(DESTDIR)/share/xfractint SHRDIR = $(PREFIX)/share/xfractint # BINDIR is where you put your X11 binaries BINDIR = $(DESTDIR)/bin # MANDIR is where you put your chapter 1 man pages MANDIR = $(DESTDIR)/share/man/man1 HFD = ./headers UDIR = ./unix COMDIR = ./common DOSHELPDIR = ./dos_help FDIR = formulas IDIR = ifs LDIR = lsystem MDIR = maps PDIR = pars XDIR = extra PWD = $(shell pwd) BASEDIR = $(shell basename ${PWD}) NOBSTRING = HAVESTRI = DEBUG = # For Ultrix, uncomment the NOBSTRING line below. # For SunOS or Solaris, uncomment the NOBSTRING and HAVESTRI lines below, so # bstring.h will not be included, and the library stricmp will be used. # (Actually newer Solaris versions do not provide stricmp, so try without # HAVESTRI if you run into problems.) # For HPUX, uncomment the NOBSTRING line, change the DEFINES line, the CFLAGS # line, the CC line, and the LIBS line. # For AIX or OSF/1, change the DEFINES and LIB lines. # For Apollo, uncomment the NOBSTRING line. You must also remove the # source references to unistd.h, malloc.h, and alloc.h. # For 386BSD, uncomment the NOBSTRING line. Depending on your system, you # may have to change the "#elif !defined(__386BSD__)" at the top of # prompts2.c to "#else". # For Red Hat Linux, uncomment the NOBSTRING line. # For Cygwin, uncomment the NOBSTRING and HAVESTRI lines below. # NOBSTRING = -DNOBSTRING #HAVESTRI = -DHAVESTRI #DEBUG adds some sanity checking but will slow xfractint down #DEBUG = -DEBUG # If your compiler doesn't handle void *, define -DBADVOID # If you get SIGFPE errors define -DFPUERR # For HPUX, add -DSYS5 # and maybe add -DSYSV -D_CLASSIC_ANSI_TYPES # For AIX, add -DNOBSTRING and -DDIRENT # AIX may also need -D_POSIX_SOURCE -D_ALL_SOURCE -D_NONSTD_TYPES # AIX may need -D_ALL_SOURCE -D_NONSTD_TYPES to compile help.c # For Dec Alpha, add -DFTIME -DNOBSTRING -DDIRENT # For SGI, you may have to add -DSYSVSGI DEFINES = -DXFRACT $(NCURSES) $(NOBSTRING) $(HAVESTRI) $(DEBUG) # Uncomment this if you get errors about "stdarg.h" missing. #DEFINES += -DUSE_VARARGS # To enable the long double type on Solaris, uncomment this and add # "-lsunmath" to the LIBS definition below. Requires the sunmath library # bundled with Sun C. #DEFINES += -DUSE_SUNMATH # Uncomment this for Cygwin #DEFINES += -DCYGWIN -DDIRENT # For using nasm, set: #AS = /usr/bin/nasm # Note that because of the differences between the assembler syntaxes, # nasm is the only one that will work. AS = foo # Below is for Linux with output file type of elf, turn all warnings on AFLAGS = -f elf -w+orphan-labels #Maybe -D_CONST will fix problems with constant type in include files? #For HPUX, use CFLAGS = -I. $(DEFINES) -I/usr/include/X11R4 +O3 +Obb1000 #For SGI, add -cckr to CFLAGS #For 386BSD, add -I/usr/X386/include to CFLAGS #For Apollo add -I/usr/include/X11 to CFLAGS #Some systems need -static on the CFLAGS. #For Linux, add -DLINUX to CFLAGS #If your version of Linux doesn't define SignalHandler add -DNOSIGHAND to CFLAGS #For Solaris, use CFLAGS = -I. -I/usr/openwin/include $(DEFINES) -g #If you have the nasm assembler on your system add -DNASM to CFLAGS ifeq ($(AS),/usr/bin/nasm) CFLAGS = -I$(HFD) $(DEFINES) -g -DBIG_ANSI_C -DLINUX -DNASM -fno-builtin #CFLAGS = -I. -D_CONST $(DEFINES) #CFLAGS = -I$(HFD) $(DEFINES) -g -DBIG_ANSI_C -DLINUX \ # -march=$(ARCH) -DNASM -fno-builtin #CFLAGS = -I. $(DEFINES) -g -DBIG_ANSI_C -DLINUX -Os -DNASM -fno-builtin else CFLAGS = -I$(HFD) $(DEFINES) -g -DBIG_ANSI_C -DLINUX -fno-builtin #CFLAGS = -I$(HFD) $(DEFINES) -g -DBIG_ANSI_C -DLINUX \ # -march=$(ARCH) -fno-builtin #CFLAGS = -I. $(DEFINES) -g -DBIG_ANSI_C -DLINUX -Os -fno-builtin endif # Gcc is often the only compiler that works for this # For HPUX, use CC = cc -Aa -D_HPUX_SOURCE # For AIX, maybe use CC = xlc, but other AIX users found cc works, xlc doesn't. # For Apollo use CC = cc -A cpu,mathlib_sr10 -A systype,bsd4.3 # For Sun Solaris 2.x w/SparcCompilerC (cc), use CC = cc. # For Sun Solaris 2.x w/GNU gcc, use CC = gcc #CC = gcc CC = /usr/bin/gcc # For HPUX, use LIBS = -L/usr/lib/X11R4 -lX11 -lm -lcurses -ltermcap # For AIX or OSF/1, add -lbsd # For 386BSD, add -L/usr/X386/lib to LIBS # For Apollo, change -lX11 to -L/usr/X11/libX11 # For Solaris, add -L/usr/openwin/lib; change -lncurses to -lcurses # if you get undefined symbols like "w32addch". # For Linux, use # LIBS = -L/usr/X11R6/lib -lX11 -lm -lncurses # LIBS = -lX11 -lm -lcurses ifeq ($(ARCH),athlon64) LIBS = -L/usr/X11R6/lib64 -lX11 -lm else LIBS = -L/usr/X11R6/lib -lX11 -lm endif ifeq ($(NCURSES),-DNCURSES) LIBS += -lncurses endif # HPUX fixes thanks to David Allport, Bill Broadley, and R. Lloyd. # AIX fixes thanks to David Sanderson & Elliot Jaffe. # OSF/1 fixes thanks to Ronald Record. # 386BSD fixes thanks to Paul Richards and Andreas Gustafsson. # Apollo fixes thanks to Carl Heidrich # Linux fixes thanks to Darcy Boese # Makefile dependency fixes thanks to Paul Roberts. # Solaris fixes thanks to Darryl House OLDSRC = \ $(COMDIR)/3d.c $(COMDIR)/ant.c $(COMDIR)/bigflt.c $(COMDIR)/biginit.c \ $(COMDIR)/bignum.c $(COMDIR)/bignumc.c $(COMDIR)/calcfrac.c \ $(COMDIR)/cmdfiles.c $(COMDIR)/decoder.c $(COMDIR)/editpal.c \ $(COMDIR)/encoder.c $(COMDIR)/evolve.c $(COMDIR)/f16.c \ $(COMDIR)/fracsubr.c $(COMDIR)/fractalb.c $(COMDIR)/fractalp.c \ $(COMDIR)/fractals.c $(COMDIR)/fractint.c $(COMDIR)/framain2.c \ $(COMDIR)/frasetup.c $(COMDIR)/gifview.c $(COMDIR)/hcmplx.c \ $(COMDIR)/help.c $(COMDIR)/history.c $(COMDIR)/intro.c \ $(COMDIR)/jb.c $(COMDIR)/jiim.c $(COMDIR)/line3d.c \ $(COMDIR)/loadfdos.c $(COMDIR)/loadfile.c $(COMDIR)/loadmap.c \ $(COMDIR)/lorenz.c $(COMDIR)/lsys.c $(COMDIR)/lsysf.c \ $(COMDIR)/memory.c $(COMDIR)/miscfrac.c $(COMDIR)/miscovl.c \ $(COMDIR)/miscres.c $(COMDIR)/mpmath_c.c $(COMDIR)/parser.c \ $(COMDIR)/parserfp.c $(COMDIR)/plot3d.c $(COMDIR)/printer.c \ $(COMDIR)/prompts1.c $(COMDIR)/prompts2.c $(COMDIR)/realdos.c \ $(COMDIR)/rotate.c $(COMDIR)/slideshw.c $(COMDIR)/soi.c \ $(COMDIR)/soi1.c $(COMDIR)/stereo.c $(COMDIR)/targa.c \ $(COMDIR)/testpt.c $(COMDIR)/tgaview.c $(COMDIR)/zoom.c $(COMDIR)/Makefile NEWSRC = \ $(UDIR)/calcmand.c $(UDIR)/calmanfp.c $(UDIR)/diskvidu.c \ $(UDIR)/fpu087.c $(UDIR)/fracsuba.c $(UDIR)/general.c \ $(UDIR)/xfcurses.c $(UDIR)/video.c $(UDIR)/unix.c $(UDIR)/unixscr.c \ $(UDIR)/Makefile $(UDIR)/xfract_a.inc $(UDIR)/calmanfx.asm HEADERS = \ $(HFD)/big.h $(HFD)/biginit.h $(HFD)/cmplx.h $(HFD)/externs.h \ $(HFD)/fmath.h $(HFD)/fractint.h $(HFD)/fractype.h $(HFD)/helpcom.h \ $(HFD)/lsys.h $(HFD)/mpmath.h $(HFD)/port.h $(HFD)/prototyp.h \ $(HFD)/targa.h $(HFD)/targa_lc.h $(HFD)/tplus.h $(HFD)/unix.h \ $(HFD)/xfcurses.h DOCS = debugfla.txt fractsrc.txt hc.txt HELPFILES = \ $(DOSHELPDIR)/help.src $(DOSHELPDIR)/help2.src $(DOSHELPDIR)/help3.src \ $(DOSHELPDIR)/help4.src $(DOSHELPDIR)/help5.src SRCFILES = $(OLDSRC) $(NEWSRC) $(HELPFILES) $(HEADERS) $(DOCS) PARFILES = \ $(PDIR)/cellular.par $(PDIR)/demo.par $(PDIR)/fract18.par \ $(PDIR)/fract19.par $(PDIR)/fract200.par $(PDIR)/fractint.par \ $(PDIR)/icons.par $(PDIR)/lyapunov.par $(PDIR)/music.par \ $(PDIR)/newphoen.par $(PDIR)/orbits.par $(PDIR)/phoenix.par FRMFILES = \ $(FDIR)/fractint.frm $(FDIR)/fract200.frm $(FDIR)/fract196.frm \ $(FDIR)/fract001.frm $(FDIR)/fract002.frm $(FDIR)/fract003.frm \ $(FDIR)/fract_sy.frm $(FDIR)/ikenaga.frm $(FDIR)/julitile.frm \ $(FDIR)/new_if.frm $(FDIR)/newton.frm IFSFILES = $(IDIR)/fractint.ifs LFILES = $(LDIR)/fractint.l $(LDIR)/penrose.l $(LDIR)/tiling.l MAPFILES = \ $(MDIR)/altern.map $(MDIR)/blues.map $(MDIR)/chroma.map \ $(MDIR)/default.map $(MDIR)/firestrm.map $(MDIR)/froth3.map \ $(MDIR)/froth316.map $(MDIR)/froth6.map $(MDIR)/froth616.map \ $(MDIR)/gamma1.map $(MDIR)/gamma2.map $(MDIR)/glasses1.map \ $(MDIR)/glasses2.map $(MDIR)/goodega.map $(MDIR)/green.map \ $(MDIR)/grey.map $(MDIR)/grid.map $(MDIR)/headache.map \ $(MDIR)/landscap.map $(MDIR)/lyapunov.map $(MDIR)/neon.map \ $(MDIR)/paintjet.map $(MDIR)/royal.map $(MDIR)/topo.map $(MDIR)/volcano.map XTRAFILES = \ $(XDIR)/all_maps.zip $(XDIR)/frmtut.zip $(XDIR)/if_else.zip \ $(XDIR)/phctutor.zip OLDRUN = $(PARFILES) $(FRMFILES) $(IFSFILES) $(LFILES) $(MAPFILES) NEWRUN = fractint.doc read.me $(UDIR)/xfractint.man NEWFILES = $(UDIR)/$(NEWSRC) $(NEWRUN) RUNFILES = $(OLDRUN) $(NEWRUN) FILES = $(SRCFILES) $(RUNFILES) OBJS = \ $(COMDIR)/3d.o $(COMDIR)/ant.o $(COMDIR)/bigflt.o $(COMDIR)/biginit.o \ $(COMDIR)/bignum.o $(COMDIR)/bignumc.o $(COMDIR)/calcfrac.o \ $(COMDIR)/cmdfiles.o $(COMDIR)/decoder.o $(COMDIR)/editpal.o \ $(COMDIR)/encoder.o $(COMDIR)/evolve.o $(COMDIR)/f16.o $(COMDIR)/fracsubr.o \ $(COMDIR)/fractalb.o $(COMDIR)/fractalp.o $(COMDIR)/fractals.o \ $(COMDIR)/fractint.o $(COMDIR)/framain2.o $(COMDIR)/frasetup.o \ $(COMDIR)/gifview.o $(COMDIR)/hcmplx.o $(COMDIR)/help.o $(COMDIR)/history.o\ $(COMDIR)/intro.o $(COMDIR)/jb.o $(COMDIR)/jiim.o $(COMDIR)/line3d.o \ $(COMDIR)/loadfdos.o $(COMDIR)/loadfile.o $(COMDIR)/loadmap.o \ $(COMDIR)/lorenz.o $(COMDIR)/lsys.o $(COMDIR)/lsysf.o $(COMDIR)/memory.o \ $(COMDIR)/miscfrac.o $(COMDIR)/miscovl.o $(COMDIR)/miscres.o \ $(COMDIR)/mpmath_c.o $(COMDIR)/parser.o $(COMDIR)/parserfp.o \ $(COMDIR)/plot3d.o $(COMDIR)/printer.o $(COMDIR)/prompts1.o \ $(COMDIR)/prompts2.o $(COMDIR)/realdos.o $(COMDIR)/rotate.o \ $(COMDIR)/slideshw.o $(COMDIR)/soi.o $(COMDIR)/soi1.o $(COMDIR)/stereo.o \ $(COMDIR)/targa.o $(COMDIR)/testpt.o $(COMDIR)/tgaview.o \ $(COMDIR)/zoom.o ifeq ($(AS),/usr/bin/nasm) U_OBJS = \ $(UDIR)/calcmand.o $(UDIR)/calmanfp.o $(UDIR)/diskvidu.o $(UDIR)/fpu087.o \ $(UDIR)/fracsuba.o $(UDIR)/general.o $(UDIR)/unix.o $(UDIR)/xfcurses.o \ $(UDIR)/unixscr.o $(UDIR)/video.o \ $(UDIR)/calmanfx.o else U_OBJS = \ $(UDIR)/calcmand.o $(UDIR)/calmanfp.o $(UDIR)/diskvidu.o $(UDIR)/fpu087.o \ $(UDIR)/fracsuba.o $(UDIR)/general.o $(UDIR)/unix.o $(UDIR)/xfcurses.o \ $(UDIR)/unixscr.o $(UDIR)/video.o endif HOBJS = $(DOSHELPDIR)/hc.o unix.o #Need to prevent lex from doing fractint.l -> fractint.c .SUFFIXES: .SUFFIXES: .o .c .s .h .asm xfractint: fractint.hlp $(SRCFILES) if [ -f $(DOSHELPDIR)/helpdefs.h ] ; then mv -f $(DOSHELPDIR)/helpdefs.h $(HFD) ; fi cd common ; ${MAKE} all "CC=${CC}" "CFLAGS= -I.${HFD} ${CFLAGS} ${OPT}" "SRCDIR=${SHRDIR}" \ "HFD=.${HFD}" cd unix ; ${MAKE} all "CC=${CC}" "CFLAGS= -I.${HFD} ${CFLAGS} ${OPT}" "SRCDIR=${SHRDIR}" \ "AS=${AS}" "AFLAGS=${AFLAGS}" "HFD=.${HFD}" $(CC) -o xfractint $(CFLAGS) $(OPT) $(OBJS) $(U_OBJS) $(LIBS) # strip xfractint fractint: if [ -x xfractint ] ; then mv -f xfractint xfractint.x11 ; fi rm -f common/encoder.o common/help.o common/realdos.o rm -f unix/unixscr.o unix/video.o unix/xfcurses.o make NCURSES=-DNCURSES ; mv xfractint fractint rm -f common/encoder.o common/help.o common/realdos.o rm -f unix/unixscr.o unix/video.o unix/xfcurses.o if [ -x xfractint.x11 ] ; then mv -f xfractint.x11 xfractint ; fi # tar: $(FILES) # tar cvfj xfractint.tar.bz2 $(FILES) tar: clean cd .. ; tar cvfj $(BASEDIR).tar.bz2 $(BASEDIR) tidy: rm -f $(HOBJS) cd common ; ${MAKE} tidy cd unix ; ${MAKE} tidy clean: rm -f build-stamp *~ */*~ core rm -f $(HOBJS) fractint.doc fractint.hlp hc fractint xfractint rm -f $(HFD)/helpdefs.h cd $(COMDIR) ; ${MAKE} clean cd $(UDIR) ; ${MAKE} clean install: xfractint fractint.hlp $(STRIP) xfractint $(INSTALL) -d $(BINDIR) $(MANDIR) $(SRCDIR)/$(PDIR) $(SRCDIR)/$(FDIR) \ $(SRCDIR)/$(IDIR) $(SRCDIR)/$(LDIR) $(SRCDIR)/$(MDIR) $(SRCDIR)/$(XDIR) $(INSTALL) xfractint -T $(BINDIR)/xfractint; $(INSTALL) -m 644 -T $(UDIR)/xfractint.man $(MANDIR)/xfractint.1; $(INSTALL) -m 644 -t $(SRCDIR) fractint.hlp sstools.ini $(DOCS) $(INSTALL) -m 644 -t $(SRCDIR)/$(PDIR) $(PARFILES) $(INSTALL) -m 644 -t $(SRCDIR)/$(FDIR) $(FRMFILES) $(INSTALL) -m 644 -t $(SRCDIR)/$(IDIR) $(IFSFILES) $(INSTALL) -m 644 -t $(SRCDIR)/$(LDIR) $(LFILES) $(INSTALL) -m 644 -t $(SRCDIR)/$(MDIR) $(MAPFILES) $(INSTALL) -m 644 -t $(SRCDIR)/$(XDIR) $(XTRAFILES) uninstall: cd $(SRCDIR); rm -f $(PARFILES) cd $(SRCDIR); rm -f $(FRMFILES) cd $(SRCDIR); rm -f $(IFSFILES) cd $(SRCDIR); rm -f $(LFILES) cd $(SRCDIR); rm -f $(MAPFILES) cd $(SRCDIR); rm -f $(XTRAFILES) cd $(SRCDIR); rm -f fractint.hlp sstools.ini $(DOCS) cd $(SRCDIR); rmdir $(PDIR) $(FDIR) $(IDIR) $(LDIR) $(MDIR) $(XDIR) # only next 2 lines might need su cd $(SRCDIR); cd ..; rmdir $(SRCDIR) rm -f $(BINDIR)/xfractint $(MANDIR)/xfractint.1 fractint.hlp: hc $(DOSHELPDIR)/$(HELP) cd $(DOSHELPDIR); ../hc /c; mv fractint.hlp .. fractint.doc: doc doc: hc $(HELPFILES) cd $(DOSHELPDIR) ; ../hc /p ; mv -f fractint.doc .. hc: $(HOBJS) $(CC) -o hc $(CFLAGS) $(HOBJS) unix.o: $(UDIR)/unix.c $(CC) $(CFLAGS) $(OPT) -DSRCDIR=\"$(SHRDIR)\" -c $(UDIR)/unix.c copy: $(FILES) mv $(FILES) backup # DO NOT DELETE THIS LINE -- make depend depends on it. hc.o: $(DOSHELPDIR)/hc.c $(HFD)/helpcom.h $(HFD)/port.h xfractint-20.4.10.orig/read.me0000644000000000000000000000237510756132210012747 0ustar FRACTINT: Fractint 20.4 complete C and ASM source for the DOS-based fractal generator. Requires Microsoft C/C++ 7.0 or later or Borland C/C++ 3.1 or later. Object code of ASM modules supplied so an assembler is not required. Note that the Borland project files are in the extra directory and have not been updated to use the new source tree structure. Copyrighted freeware. XFRACTINT: Download the source tarball (for example: xfract20.3.02.tar.gz), put it in your home directory, and untar it with the command: tar -xzf xfract20.3.02.tar.gz This will create the directory xfractint-20.03p02 containing the source. You might want to change the directory name to xfractint for convenience. You will need to have gcc installed. You also need the XFree86-libs package installed for the X11 libraries. This package should already be installed, but if it isn't and your distribution doesn't have it, then you need the XFree86-devel package. The Makefile is set up for my convenience, so if you want to put files in different directories, you will need to change the SRCDIR setting. Otherwise, just run "make" from the source directory and it should compile. Run ./xfractint to start it up. Or, run "make install" to be able to run xfractint from anywhere. Jonathan xfractint-20.4.10.orig/pars/0000755000000000000000000000000011456314752012462 5ustar xfractint-20.4.10.orig/pars/newphoen.par0000644000000000000000000000132610150633601014776 0ustar mandphoenixclx1 { ; by Jonathan Osuch reset=1822 type=mandphoenixclx corners=-0.291827917/-0.281810939/0.125888824/0.133397639 params=0/0/0.5 inside=0 } phoenixcplx1 { ; by Jonathan Osuch reset=1822 type=phoenixcplx corners=0.75775444/1.157748/-0.20638394/0.093626022 params=-0.29027599096298218/0.12787967920303345/0.5 inside=0 } mandphoenixclx2 { ; by Jonathan Osuch reset=1822 type=mandphoenixclx corners=-0.30382085/0.30695587/0.19807309/-0.077459633/0.034962296/-0.27\ 305287 params=0/0/0.5/1 inside=0 } phoenixcplx2 { ; by Jonathan Osuch reset=1822 type=phoenixcplx corners=-2/2.000007/-1.500002/1.5 params=-0.029776036739349365/0.39949685335159302/0.5/0.5 inside=0 } xfractint-20.4.10.orig/pars/music.par0000644000000000000000000000220710150633601014272 0ustar ; The following pars illustrate the sound capabilities of Fractint. Music_Fractal-1 { ; Intro to the sound of chaos by Bill Jemison [70400,2537] reset=1930 type=mandel passes=1 hertz=220 orbitdelay=1000 sound=y video=SF7 showorbit=yes center-mag=-0.223108/0.641995/1354.059/0.1539/-7.499/-51.996 params=0/0 maxiter=1000 viewwindows=16/0.75/yes/0/0 colors=@default.map } Music_Fractal-2 { ; (c) Sylvie Gallet [101324,3444], 1996 reset=1930 type=barnsleyj3 passes=1 hertz=1200 orbitdelay=1000 sound=z video=SF7 maxiter=1000 showorbit=yes center-mag=0.207059/0/1.893939 params=0.1/0.36 float=y periodicity=0 viewwindows=16/0.75/yes/0/0 colors=@default.map } Pop_Piccolo { ; (c) Bill Jemison [70400,2537], 1996 reset=1930 type=popcornjul passes=1 hertz=1200 orbitdelay=1000 sound=z video=SF7 maxiter=100 showorbit=yes center-mag=-0.05295861129553414/-0.72472986547206800/149.6573 params=0.1 float=y viewwindows=16/0.75/yes/0/0 colors=@default.map } Silence! { ; reset type=mandel passes=g sound=yes maxiter=150 orbitdelay=0 viewwindows=4.2/0.75/yes/0/0 showorbit=no colors=@default.map } xfractint-20.4.10.orig/pars/icons.par0000644000000000000000000002737110150633601014276 0ustar Sand_Dollar { reset type=icons corners=-1.424/1.424/-1.068/1.068 params=-2.34/2/0.2/0.1/0.0/5 float=y inside=0 colors=000ypa<29>UPF000<4>888000BBB<23>ppp<31>000PFF<27>vcDwdDxeDzfCyfCxeC<2\ 0>_NE } Sand_Dollar_3d { reset type=icons3d corners=-2.242152/2.242152/-1.681614/1.681614 params=-2.34/2/0.2/0.1/0.0/5 inside=0 maxiter=32767 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Sand_Dollar_3d_II { ; Rotated view reset type=icons3d corners=-2.134489/2.036423/-1.519231/1.608953 params=-2.34/2/0.2/0.1/0.0/5 maxiter=32767 inside=0 rotation=90/45/270 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Halloween { reset type=icons corners=-1.0496/1.0496/-0.7872/0.7872 params=-2.7/5/1.5/1/0.0/6 float=y inside=0 colors=000TgsSfsSestYS<3>zvErMY<39>fZEqMY<32>FUyrMY<62>0V4rMYqNXqNW } Halloween3d { reset type=icons3d corners=-2.0/2.0/-1.5/1.5 params=-2.7/5/1.5/1/0.0/6 inside=0 maxiter=32767 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Mayan_Bracelet { reset type=icons corners=-1.712/1.712/-1.284/1.284 params=-2.08/1/-0.1/0.167/0.0/7 float=y inside=0 colors=000dOD<6>ii0d8P<2>sQNZ4PX6OX9QV8N<10>9SD<6>UHPY9M<7>TIIbCN<2>icE`7O<1\ 2>Xw5`3O<9>W56a5Q<11>naa_4Q<19>BTr`3P<22>ULI`5R<11>gXta5P<5>hJP } Mayan_Bracelet3d { reset type=icons3d corners=-2.55102/2.55102/-1.913265/1.913265 params=-2.08/1/-0.1/0.167/0.0/7 maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Mayan_Brac_3d_II { ; Rotated version reset type=icons3d corners=-2.064835/1.935164/-1.789359/1.21064 params=-2.08/1/-0.1/0.167/0.0/7 maxiter=32767 inside=0 rotation=-60/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Emperors_Cloak { reset type=icons corners=-1.064/1.064/-0.798/0.798 params=-1.806/1.806/0/1/0.0/3 inside=0 } Emperors_Cloak3d { reset type=icons3d corners=-2.045102/1.555646/-1.35028/1.35028 params=-1.806/1.806/0/1/0/3 maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-4 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Trampoline { reset type=icons corners=-1.64/1.64/-1.23/1.23 params=1.56/-1/0.1/-0.82/0.0/3 float=y inside=0 colors=0001O4<2>1F0KF1<6>hZ0<6>OI0KF0F0F<6>Z0U<7>F0FKF0<6>hZ0<7>KF000A<6>00k\ <7>00AA00<6>z00<7>A00<6>2r00z00u0<7>0A0<6>eXU<7>0A0AKK<6>mmK<7>AKMFF0<6>zz0<\ 7>FF0F00M01 } Trampoline3d { reset type=icons3d corners=-2.1935/2.1935/-1.645125/1.645125 params=1.56/-1/0.1/-0.82/0.0/3 inside=0 float=y maxiter=32767 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Pentagon_Attractor { reset type=icons corners=-1.64/1.64/-1.23/1.23 params=2.6/-2/0/-0.5/0.0/5 float=y inside=0 colors=000AGe<3>8NtDEE<2>4s`M4F<4>xLtF28<19>IScJUeH17<4>W1BI2B<9>qDuG38<14>c\ g`K67<5>qe2F58<3>IPCBwNG48<14>_yUG18<10>U1PG28<21>n`_F39<14>Mbk } Pentagon_Attract3d { reset type=icons3d corners=-2.841922/2.841922/-2.131441/2.131441 params=2.6/-2/0/-0.5/0.0/5 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Kachina_Dolls { reset type=icons corners=-1.28/1.28/-0.96/0.96 params=2.409/-2.5/0/0.9/0.0/23 float=y inside=0 colors=000JYA<9>DTC_l7<40>7jkck7<4>weCUb8OT9IIB_l7<72>gK5_l7<12>bhE } Kachina_Dolls3d { reset type=icons3d corners=-2.182691/2.182691/-1.637018/1.637018 params=2.409/-2.5/0/0.9/0.0/23 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Santa_Chiara_Icon { reset type=icons corners=-1.28/1.28/-0.96/0.96 params=2.409/-2.5/-0.2/0.81/0.0/24 float=y inside=0 colors=000UFL<26>z00MKS<7>sCMLKP<6>fQ2FNX<3>3_tIKS<36>dLXIKS<27>JHqKKT<11>qW\ eIKS<18>D_S } Santa_Chiara3d { reset type=icons3d corners=-2.931235/1.170054/-2.283148/0.784799 params=2.409/-2.5/-0.2/0.81/0.0/24 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } French_Glass { reset type=icons corners=-0.992/0.992/-0.744/0.744 params=-2.05/3/-16.79/1/0.0/9 float=y inside=0 colors=000VK`<75>w7Fw7Fw8F<70>qbQ } French_Glass3d { reset type=icons3d corners=-1.478161/1.478161/-1.108621/1.108621 params=-2.05/3/-16.79/1/0.0/9 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } The_Pentangle { reset type=icons corners=-1.352/1.352/-1.014/1.014 params=-2.32/2.32/0/0.75/0.0/5 float=y inside=0 colors=000AOf<22>I81AOg<16>4RvBOg<28>djZARc<7>Eu4BOg<27>g4dCOg<5>TMkANf<14>H\ 7HBOg<15>WV` } The_Pentangle3d { reset type=icons3d corners=-2.155172/2.155172/-1.616379/1.616379 params=-2.32/2.32/0/0.75/0.0/5 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Fuzzy_Hex_Knot { ; Have patience. This one takes a while! ; By DMF reset type=icons corners=-1.371568/1.371568/-1.028676/1.028676 params=-1.806/1.807/-0.07/1.08/0.0/6 float=y inside=0 colors=0005BD<148>cWHccc<103>ccc } Fuzzy_Hex_Knot3d { ; By DMF ; Have patience. It's slow! reset type=icons3d corners=-1.648964/1.648964/-1.236723/1.236723 params=-1.806/1.807/-0.07/1.08/0.0/6 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Square { ; By DMF reset type=icons corners=-0.948083/0.948083/-0.711062/0.711062 params=-2.7/5/1.5/1/0.0/4 float=y inside=0 colors=000JYA<9>DTC_l7<40>7jkck7<4>weCUb8OT9IIB_l7<72>gK5_l7<12>bhE } Square3d { ; By DMF reset type=icons3d corners=-1.801941/1.801941/-1.351455/1.351455 params=-2.7/5/1.5/1/0.0/4 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } 12_Spoke_Wheel { ; By DMF reset type=icons corners=-1.157312/1.157312/-0.867984/0.867984 params=-2.6/4/1.5/1/0.0/12 inside=0 colors=000LXt<13>JesONt<13>r3iMOr<18>CdELOs<18>1DZMOs<28>FKRUXsberMOt<39>M9v\ N8wMOt<4>QTq } 12_Spoke_Wheel3d { ; By DMF reset type=icons3d corners=-2.1125/2.1125/-1.584375/1.584375 params=-2.6/4/1.5/1/0.0/12 maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } 36_Spoke_Wheel { ; By DMF ; Takes quite a while to fully "develop" reset type=icons corners=-1.352/1.352/-1.014/1.014 params=-2.57/3.2/1.2/-1.75/0.0/36 float=y inside=0 colors=000mP6<2>rS4NED<2>291UFH<25>Q2vUFG<27>K2MTGH<3>POLVGGOQM<15>5tc<17>xm\ K<31>cq9<10>0WM0VM0UN } 36_Spoke_Wheel3d { ; By DMF ; Takes quite a while to fully "develop" reset type=icons3d corners=-2.183546/2.183546/-1.637659/1.637659 params=-2.57/3.2/1.2/-1.75/0.0/36 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Champagne_Glasses { ; By DMF reset type=icons corners=-1.352/1.352/-1.014/1.014 params=-2.57/3.2/1.35/1.75/0.0/12 float=y maxiter=256 inside=0 colors=000lSJ<47>tYxkRA<15>xJYkR9<85>h4FkR9<37>rS8kR9<50>MmEkR9MmE<8>HqF } Champagne_Glass3d { ; By DMF reset type=icons3d corners=-2.11155/2.11155/-1.583662/1.583662 params=-2.57/3.2/1.35/1.75/0.0/12 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Orgami { ; By DMF reset type=icons corners=-1.568/1.568/-1.176/1.176 params=2.409/-2.5/0/0.9/0.0/4 float=y inside=0 colors=000U0U<7>M0Mz00<40>M00zz0<40>MM00z0<40>0M000z<13>00l } Orgami_3d { ; By DMF reset type=icons3d corners=-2.600703/2.600703/-1.950528/1.950528 params=2.409/-2.5/0/0.9/0.0/4 maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Two_Triangles { ; By DMF reset type=icons corners=-1.342208/1.342208/-1.006656/1.006656 params=2.4/-2.5/-0.9/0.9/0.0/3 float=y inside=0 colors=000VQ7<59>9Y_VQ8<33>7FyVQ7<38>mVUUP7<12>AA5 } Two_Triangles3d { ; By DMF reset type=icons3d corners=-2.366346/2.196342/-1.711008/1.711008 params=2.4/-2.5/-0.9/0.9/0.0/3 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Christmas_Bow { ; By DMF reset type=icons corners=-1.352/1.352/-1.014/1.014 params=-2.34/2.2/0.4/0.05/0.0/5 float=y maxiter=32767 inside=0 colors=000bcj<4>fkqI6M<4>3KsIBE<2>CZ8K4G<3>J4FJ4EL5G<26>oe6qg5tk4wn3zr2K6G<2\ 5>iu8K4Izzz<16>zzzK4H<26>WSjK5G<23>Y_OK5H<25>glvH4HD4I94KL6G<8>VOFL5G<19>vX9\ M5I<15>qQuK5H<22>abi } Christmas_Bow3d { ; By DMF reset type=icons3d corners=-2.269619/2.269619/-1.702214/1.702214 params=-2.34/2.2/0.4/0.05/0.0/5 float=y maxiter=32767 inside=0 rotation=0/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Penti_ummm? { reset type=icons corners=-0.742016/0.742016/-0.556512/0.556512 params=-2.5/8/-0.7/1/0.0/5 float=y inside=0 colors=000Aca9_b8VcU5V<16>L9MP3SF3I538_4`<11>lGcZ4`<38>xfQ_5_<15>xgJZ4`<20>Y\ dOXfNZ4`<23>lXqY4`<6>PIV } French_Glass3d_II { ; Awesome! Closeup of French_Glass_3d!! ; Let run "full term" for best effect. reset type=icons3d corners=-0.520313/0.520313/-0.390235/0.390235 params=-2.05/3/-16.79/1/0.0/9 float=y maxiter=32767 inside=0 rotation=-90/0/0 perspective=180 xyshift=0/0 stereo=2 interocular=3 converge=-3 crop=4/0/0/4 bright=100/100 colors=@glasses2.map } Warriors_Shield { ; By DMF reset type=icons corners=-1.064/1.064/-0.798/0.798 params=-1.806/1.806/0/1.5/0.0/7 float=y inside=0 colors=000zX0<42>z10z00z00y01<82>00z00z11y<17>EEk } Pendulum_Swing { ; By DMF ; Slow. Have patience. reset type=icons corners=-1.242991/1.242991/-0.932243/0.932243 params=-1.9/1.806/-0.85/1.8/0.0/7 float=y inside=0 colors=000BDQ<17>DBV9FF<27>G289FF<16>HKHBJGIKI<8>MNJ9FF<71>fnZ } Clam_Triple { ; Figure 1.8 in "Symmetry in Chaos" reset=1732 type=icons corners=-1.712/1.712/-1.186216/1.381784 params=1.56/-1/0.1/-0.82/0.1/3 float=y inside=0 colors=000z00<82>zy0zz0zz0zz1<82>zzzzzzzyy<82>z00 } Chaotic_Flower { reset=1732 type=icons corners=-0.949088/0.949088/-0.711816/0.711816 params=-2.5/5/-1.9/1/0.2/5 float=y inside=0 colors=00000z<83>0z00z01z1<82>zzzzzzyyz<82>00z } Wingz { reset type=icons center-mag=-6.26166e-14/-0.161292/0.782258 params=1.56/-1/0.1/-0.82/-0.3/3 float=y inside=0 colors=000ZBD<31>_Ua`VbZ9B<33>uGpZ9B<38>o6sZ9B<25>GHjgFMpLYySjZAA<39>VxN\ Z9A<32>AE2_BB<9>qVPZ9C<17>SMpZAAaGAZBB<7>`MH } test { reset=1732 type=icons corners=-2.0/2.0/-1.5/1.5 params=1/2/3/4/5.0/6 float=y inside=0 colors=00000z<83>0z00z01z1<82>zzzzzzyyz<82>00z } xfractint-20.4.10.orig/pars/cellular.par0000644000000000000000000001040410150633601014753 0ustar test_41 { reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=23.0/3311100320.0/41.0 inside=0 colors=000e00AXADCTwuI } BYTE_Photo_6 { ; From page 188 of 12/86 BYTE, Article by Kenneth E. Perry ; Titled: Abstract Mathematical Art reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1.0/323310210.0/41.0 colors=000e00AXADCTwuI } BYTE_Photo_6_rev1 { reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=101.0/323310210.0/41.0 colors=000e00AXADCTwuI } BYTE_Photo_6_rev2 { reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1011011.0/323310210.0/41.0 colors=000e00AXADCTwuI } Wolfram_1 { ; Example on page 142 of A. K. Dewdney's book The Armchair ; Universe reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=0.0/10100.0/22.0 colors=000e00AXADCTwuI } BYTE_Photo_6_rev3 { reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=2321.0/323310210.0/41.0 colors=000e00AXADCTwuI } X-mas_tree { reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=11.0/232033113.0/41.0 inside=0 colors=000e00AZADCTwuI } pyramid_of_fire { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=11.0/300132123.0/41.0 inside=0 colors=000e00AZADCTwuI } checkerboard { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=30000003.0/133322310.0/41.0 inside=0 colors=000e00AZADCTwuI } checkerboard_not { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=300000003.0/133322310.0/41.0 inside=0 colors=000e00AZADCTwuI } triangles { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=30000003.0/3210331001.0/41.0 inside=0 colors=000e00AZADCTwuI } triangles2 { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=11.0/3210331001.0/41.0 inside=0 colors=000e00AZADCTwuI } triangles3 { ; Jonathan Osuch ; Beautiful reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=22.0/3210331001.0/41.0 inside=0 colors=000e00AZADCTwuI } triangles4 { ; Jonathan Osuch ; Beautiful reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=3113.0/3210331001.0/41.0 inside=0 colors=000e00AZADCTwuI } triangles5 { ; Jonathan Osuch ; Beautiful reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=232.0/3210331001.0/41.0 inside=0 colors=000e00AZADCTwuI } bugs { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1133111.0/132011210.0/41.0 inside=0 colors=000e00AZADCTwuI } Type_61 { ; Jonathan Osuch reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=11.0/2111000355004045.0/61.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#3 { ; From September 1984 Scientific American, page 199, # 3 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1.0/331240.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#1 { ; From September 1984 Scientific American, page 199, # 1 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1.0/2213310.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#2 { ; From September 1984 Scientific American, page 199, # 2 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1.0/4200410.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#4 { ; From September 1984 Scientific American, page 199, # 4 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=1.0/2024310.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#5 { ; From September 1984 Scientific American, page 199, # 5 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=0.0/1100400.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#6 { ; From September 1984 Scientific American, page 199, # 6 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=0.0/2231000.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#7 { ; From September 1984 Scientific American, page 199, # 7 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=0.0/131210.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } Sci_Am_p199#8 { ; From September 1984 Scientific American, page 199, # 8 reset type=cellular corners=-1.0/1.0/-1.0/1.0 params=0.0/3211310.0/51.0 inside=0 colors=000e00AZADCTwuIeL0 } xfractint-20.4.10.orig/pars/fract18.par0000644000000000000000000001116110150633601014421 0ustar ; This file is the "newparm.par" file that was included with versions ; 18.0 thru 19.2. ; The following illustrate a few features new in Fractint 18.0 daisy { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=recip/sqr corners=-0.655441/0.663666/-0.493652/0.49321 params=1/0.9/1 maxiter=500 inside=0 biomorph=0 colors=00000e0e00eee00e0eeL0eeeLLLLLzLzLLzzzLLzLzzzLzzz000555<3>HHHKKKOOOSSS\ WWW___ccchhhmmmssszzz00z<3>z0z<3>z00<3>zz0<3>0z0<3>0zz<2>0GzVVz<3>zVz<3>zVV<\ 3>zzV<3>VzV<3>Vzz<2>Vbzhhz<3>zhz<3>zhh<3>zzh<3>hzh<3>hzz<2>hlz00S<3>S0S<3>S0\ 0<3>SS0<3>0S0<3>0SS<2>07SEES<3>SES<3>SEE<3>SSE<3>ESE<3>ESS<2>EHSKKS<2>QKSSKS\ SKQSKOSKMSKK<2>SQKSSKQSKOSKMSKKSK<2>KSQKSSKQSKOSKMS00G<3>G0G<3>G00<3>GG0<3>0\ G0<3>0GG<2>04G88G<2>E8GG8GG8EG8CG8AG88<2>GE8GG8EG8CG8AG88G8<2>8GE8GG8EG8CG8A\ GBBG<2>FBGGBGGBFGBDGBCGBB<2>GFBGGBFGBDGBCGBBGB<2>BGFBGGBFGBDGBCG000<6>000 } snow_storm { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=conj/cosh corners=-0.655441/0.663666/-0.493652/0.49321 params=1/0.9/1 maxiter=500 inside=0 colors=000DDD<51>000zzz<200>DDD } cat's_eye { ; Jonathan Osuch [73277,1432] reset type=manlam(fn||fn) function=tan/exp corners=-4.0/4.002258/-3.000122/3.0 params=0/0/10 maxiter=500 inside=0 colors=0007S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>\ 7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0U\ SA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<12>7S0USA7S0<5>7S0USA7\ S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4\ >7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0USA7S0<5>7S0USA7S0<4>7S0\ USA7S0<5>7S0USA7S0<3>7S0000000 } logfnbifurc { ; Jonathan Osuch [73277,1432] reset type=bif+sinpi function=log corners=-1.017556/0.202374/-0.185711/1.52232 params=5/0.66 maxiter=30 inside=0 } twirlbifurc { ; Jonathan Osuch [73277,1432] reset type=bif=sinpi function=cotan corners=-0.070738/0.07079/-0.09937/0.098708 params=5/0.77 float=y maxiter=30 inside=0 } bifurclambdafn { ; Jonathan Osuch [73277,1432] reset type=biflambda function=sqr corners=-3.50002366/-3.49890184/-0.836589396/-0.836031914 params=300/0.66 float=y maxiter=300 inside=0 } bifurclambdafnexp { ; Jonathan Osuch [73277,1432] reset type=biflambda function=exp corners=0.464147/5.931557/-1.876942/0.856763 params=9/0.9 float=y maxiter=30 inside=0 } star_burst { ; Jonathan Osuch [73277,1432] reset type=bifstewart function=cotanh corners=0.7/1.999998/-0.558294/1.641709 params=1000/0.66 inside=0 } fireworks { ; Jonathan Osuch [73277,1432] reset type=bifstewart function=cotanh corners=1.07614/1.281547/0.025189/1.168775 params=1000/0.66 inside=0 } bifmay_test { ; Jonathan Osuch [73277,1432] reset type=bifmay corners=57.48834/82.879774/-0.564521/6.948902 params=300/0.9/5 float=y inside=0 colors=@default } bazzaro { ; Jonathan Osuch [73277,1432] reset type=manlam(fn||fn) function=exp/tanh corners=-0.54303/0.547302/2.500732/3.317551 params=0/0/10 inside=0 } eggface { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=exp/tanh corners=-4.0/4.002258/-3.000122/3.0 params=0.443054199148903/3.23751068170854/10 float=y inside=0 colors=00000e0e00eee00e0eeL0eeeLLLLLzLzLLzzzLLzLzzzLzzz000555<3>HHHKKKOOOSSS\ WWW___ccchhhmmmssszzz00z<3>z0z<3>z00<3>zz0<3>0z0<3>0zz<2>0GzVVz<3>zVz<3>zVV<\ 3>zzV<3>VzV<3>Vzz<2>Vbzhhz<3>zhz<3>zhh<3>zzh<3>hzh<3>hzz<2>hlz00S<3>S0S<3>S0\ 0<3>SS0<3>0S0<3>0SS<2>07SEES<3>SES<3>SEE<3>SSE<3>ESE<3>ESSEOSELS } face2 { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=exp/tanh corners=-4.0/4.0/-3.0/3.0 params=-0.110656738224139/2.5479354841206/10 float=y inside=0 } twisted_pairs { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=sin/sqr corners=0.038671912/0.038951912/-0.003221834/-0.003011834 params=3.63636363636368/8.88178419700125e-015/32 float=y maxiter=500 inside=0 } sunburst { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=sin/sinh corners=1.208435/1.685455/0.151367/0.509674 params=1/0.1/32 float=y inside=0 colors=000rr7<29>zz0AAANNHffJ<44>__QzcE<7>zAAPP`<10>Z3w_0zaaO<24>``PzcE<21>z\ QD } testbifstewart { ; Jonathan Osuch [73277,1432] reset type=bifstewart function=ident corners=0.7/1.999998/-1.100003/1.1 params=1/0.56 inside=0 } triple_swirl { ; Jonathan Osuch [73277,1432] reset type=lambda(fn||fn) function=sin/sqr corners=-1.119186/1.123398/-0.84111/0.839951 params=1/0.1/32 float=y maxiter=1000 inside=0 } xfractint-20.4.10.orig/pars/fract19.par0000644000000000000000000003650710150633601014435 0ustar ; The following illustrate a few features new in Fractint 19.X Achute { ; (c) 1995 Bradley Beacham [74223,2745] ; No commercial use without permission reset=1827 type=lambda(fn||fn) function=sin/acos passes=t center-mag=+0.01258241500000004/+0.00965899999999986/1.518465/1/37.499 params=1/0.1/0.1 float=y inside=zmag colors=000sKS<5>a00<11>z00sKS<6>zA0<15>zz0<14>w03<8>O0b000<7>0001Uf<7>11\ 0<9>553000<7>000001001012013<45>1Sc1Sd1Te1Ue1Uf2Uf<58>xyb<7>1Uf000<14>00\ 0000200<10>O00 } Aguay { ; (c) 1995 Bradley Beacham [74223,2745] ; No commercial use without permission reset=1827 type=julia(fn||fn) function=cabs/sqr center-mag=+0.00000000000000000/+0.00000000000000000/0.9257613 params=-0.48/-0.6/0.045 float=y inside=zmag colors=000000<15>zzz<15>000<15>zn0<15>000<15>zzz<15>004<12>G0jH0nI0qK0uJ\ 0rI0n<11>308204333<14>zzz<15>000<15>z0G<15>000<15>zzz<15>000<15>0gg<14>0\ 33 } Lumber { ; (c) 1995 Bradley Beacham [74223,2745] ; No commercial use without permission reset=1827 type=barnsleyj1 passes=b center-mag=-1.1286/0.281351/1.570196 params=1.4/1.4 float=y bailoutest=and decomp=128 colors=000ePFgQG<4>iVOjXQjWP<3>iSJhRHfQG<24>000<24>ZWK_XLaXL<4>maP<2>g`O\ e_NcZN`YM_XL<21>553332221000011<23>HbUIdVKeV<4>VlZ<3>NhXLgXJeWIcV<21>254\ 243122000111223<20>QTbRVcSWeUXfVYf<4>dch<2>``hZ_hXZhVYgTXf<24>110<22>dOF } Maculated_1 { ; (c) 1995 Bradley Beacham [74223,2745] ; No commercial use without permission reset=1827 type=julfn+zsqrd function=cabs passes=t center-mag=-0.08850817135000003/+0.93466740749999990/5.642831/1/92.5 params=-0.14/1 float=y bailout=16 bailoutest=real fillcolor=1 colors=000MMs<2>JJlIIjHHgGGd<2>CCWBBS99P88L66H55D33A226210110<3>HD3KG4OJ\ 4RL5VO6YR6`T7dW8<3>ncApeArfAthBviBwjB<4>zsKzqIzoFylCykC<2>uhBsgBqeAodAmb\ 9<3>bU7_S7WP6<2>MH4IE3EB2A82751202000<6>I6LL7ON8QP8T<3>XBaZCc_Cd<3>dEjeE\ keEkfElgHliKlkOl<2>gHleEkdEj<2>aDe_CdZCbXB`VAZTAX<2>N7PK6NI6KF5HD4F<3>20\ 3300<5>Q55U55X66_77<3>k99m99pAArAAsBBuBBwBBxCCyCCyCC<2>zMM<2>yCC<2>uBBtB\ BrAApAA<2>i99f88c77`77Y66<5>C22811400000120251<5>BN5CP6ES7FU7GX8<3>KdALe\ AMgBMhBNiB<2>OlC<2>YlM<2>OlC<3>MhBLfALeAKcAJa9<2>GW8ET7DR6CO6AL5<4>37124\ 1001002<5>99PBBSCCWDDZFFa<2>IIjJJlKKoLLqMMs<3>OOxOOyQQySSyUUzSSzQQzOOy<3\ >MMt } Zorro { ; (c) 1995 Bradley Beacham [74223,2745] ; No commercial use without permission reset=1827 type=mandel passes=b center-mag=-0.15293261576971000/+1.03977151032970000/6060606 params=0/0 float=y maxiter=5000 bailoutest=and fillcolor=1 colors=000`8i<17>yw2zz0yw1<3>ul5tj6sg7qe9nd9<13>0LL<23>0Xh0Yi0Zi0_j0`k<6\ >2gq<10>dtz<7>JjjGhhDgfBfdAeb8c_<25>zwbwtb<8>SHS<4>eHXhGYjEY<3>t8Wv7Wv9W\ <23>yubywbxu`<8>peNocLncL<10>bVJ<6>9RC<4>4P73O62N51M40L3<12>xu2<11>000AA\ C<2>J3SM0YN0_<5>W0mY0pZ2n_5l } 30,000-Feet { ; (c) Robert W. Carr [73753,2420], 1996 reset=1960 type=formula formulafile=fract196.frm formulaname=Carr2289 corners=-0.6675049/0.6648699/-0.50270801/0.49657301 params=100/150/200/250 float=y maxiter=300 periodicity=0 colors=00000L012<12>AFSBGUAFS<14>0007Mw<4>e00<4>zz0<4>UFw00`<5>`oz<4>YFw\ <2>sff0o`000<14>zo`<15>000000<14>KAc<15>0z`<14>Zky`jzaky<14>svc<15>WFx<1\ 5>zo`<15>0F0MMU<13>_mx`hz<30>CHS } Ant { ; Draw it at 1024 x 768 ; (c) Sylvie Gallet [101324,3444], 1996 reset=1930 type=ant center-mag=+0.00000000000000000/+0.00000000000000000/1/1.3333 params=112112112/1200000/3/1/1/0 float=y maxiter=10 colors=AAACLLBLLAKK<3>0cc<9>zz0<15>z00<35>F00zrc<41>MD7LB6LB6<61>000kkkw\ ww<76>CMM } Barnsleyj2-manh { ; (c) Sylvie Gallet [101324,3444], 1996 ; uses the new manh bailout test reset=1930 type=barnsleyj2 passes=1 center-mag=6.165e-006/-8.65e-007/0.1034588 params=-0.1/-1 float=y maxiter=175 bailout=100 bailoutest=manh inside=bof61 outside=atan periodicity=0 colors=O0L0W0<9>000<15>zrZ<15>000<15>z0r<8>S0PK0I<4>000<15>www<15>000<14\ >IeqKhuJfr<14>000<15>zrZ<15>000<15>z00<15>000<15>www<15>000<15>0m0<4>0Z0 } Barnsleyj2-manr { ; (c) Sylvie Gallet [101324,3444], 1996 ; uses the new manr bailout test reset=1930 type=barnsleyj2 passes=1 center-mag=6.165e-006/-8.65e-007/0.1433644 params=-0.5666666666666667/0.9333333333333333 float=y maxiter=50 bailout=75 bailoutest=manr inside=bof61 outside=mult logmap=old periodicity=0 colors=000K05<4>000<15>zzz<15>000<15>0gg<15>000<15>zzz<15>000<15>zn0<15>\ 000<15>zzz<15>004<12>G0jH0nI0qK0uJ0rI0n<11>308204333<14>zzz<15>000<15>z0\ G<9>O06 } Chip { ; (c) Sylvie Gallet [101324,3444], 1996 reset=1930 type=chip center-mag=-81.0031/-74.4724/0.001885008 params=-158/-258/2.5 float=y maxiter=1000 colors=000tq5SUVEab0ijd6GdiC`QK<2>La8hHXlCfp7pDzNWMW<2>1PvgTL<2>npAYHI<2\ >A00eKM<2>eCF`PNWTMQXKgOTjRYJzoaFUX7`cNWaPc_Rk`zOeMX<2>eLwzBykOYrRgNPY3S\ gkPLqTIwXFWPX<2>2YwcNZ`OiYQtWUSMbXBkaA0rbTHZ`9fPQhSSjVVZQNSULkXPrgRPfTeS\ GdY8mMPuNQCd9eRKeXGebCdh7eWJ<2>ey3aJV<2>Q7o3itdUXcafbipaKNYIMUFLYq1ZJO<2\ >D9PTRZFXi1btDWsjVLpdHvnDQAJ7eNYFbZWN<2>EyKcTOa_N_fMgKK<2>nC8hYTliYpvbZT\ LS`HLhDgWQieSlpUjE4GZBcMU<2>WLnYft`DHW49jMHoNAuO3QmBiVOmdNqnMeVR<2>hx`nQ\ PwUR_KUTI_MGf`UK<2>Jt56fvfMKgLGhKBV_GKm7YOIPQCGT5eHJfBDgPW<2>pZtQb`9tmwM\ 8jJIoGCtD5aNK<2>PS6cFhcO_`QkYTxeWW<2>gyuNVL3dIeJTeFYeBcQLNeWdfevXSK<2>5j\ 6`NN<2>LTHYSO<2>8jPXKNOHLEEJeUO<2>csRXTO<2>5mMeMOdNNdONcPMdWOceOaoOfOR<2\ >jUahPWSAzkTdnXm<2>NX0<3>7`e<2>YgNkT_zDlOSh } Fractint { ; A Newton fractal and the word 'FRACTINT' ; (c) Sylvie Gallet [101324,3444], 1996 ; uses a large formula reset=1960 type=formula formulafile=fract196.frm formulaname=fractint center-mag=0/0/0.6905982 float=y periodicity=0 colors=000000`Y_<6>nrt<15>OI4<6>eYIg_KiaMkcOneQ<4>zp`<4>jdVgaUcZS`WRYUQ<\ 6>AAJ<3>ALPAORARTBUVBXX<6>DqkDtmCqk<6>7T`<6>L4Q<8>VHH<5>rH4vH1zH0<8>SDE<\ 3>N3IL0JL1JM2JN3JO4I<10>tq2wu0zz0<2>pp2mm3jj5<2>``8YY9XVA<6>KAIMAJOAL<12\ >ziE<13>K8B412<3>CC7EF9IIC<10>svbsvbsvbsvb<10>_ULYRJUMGSJE<6>EAa<6>7Nt5P\ w5Nt<5>A5b<2>D6VE7TG8RH9PJAMKBK<2>QIOSKPUNRWPTYSW_VY cyclerange=2/255 } Newton-real { ; Newton's method applied to a real equation ; (c) Sylvie Gallet [101324,3444], 1996 reset=1920 type=formula formulafile=fractint.frm formulaname=newton_real passes=1 center-mag=-2.00627/1.71859/0.6666667/-1 params=0.001/0 float=y maxiter=500 inside=0 outside=summ colors=00F7GL<8>IeqKhuJfr<14>000<3>FD8ABBNKD<9>zrZ<15>000<15>z00<15>000<\ 15>www<15>000<15>0m0<15>000<15>zrZ<15>000<15>z0r<8>S0PK0I<4>000<15>www<1\ 5>000<4>6EI } Threeply { ; (c) Sylvie Gallet [101324,3444], 1996 reset=1930 type=threeply center-mag=-50.1567/-180.905/0.0003030303 params=-350/-350/100 float=y maxiter=1000 colors=000kdp<91>vyijcp<151>ufFufFvfFwfFufF<4>ufD } TileJulia { ; Your new wallpaper for Windows... ; (c) Sylvie Gallet [101324,3444], 1996 reset=1960 type=formula formulafile=fract196.frm formulaname=tilejulia center-mag=0/0/0.6666667 params=0.001/0.005/500/0/-1.44/0 float=y periodicity=0 colors=O0LBBB<12>www<15>000<14>IeqKhuJfr<14>000<15>zrZ<15>000<15>z00<15>\ 000<15>www<15>000<15>0m0<15>000<15>zrZ<15>000<15>z0r<8>S0PK0I<4>00033377\ 7 } TileMandel { ; ...or the background for your Web page? ; (c) Sylvie Gallet [101324,3444], 1996 reset=1960 type=formula formulafile=fract196.frm formulaname=tilemandel center-mag=0/0/0.6666667 params=-1.238825/0.163073/40/0 float=y periodicity=0 colors=CCCrdL<12>uoYvpZuoZ<23>DJR<14>WhQXiQYkQ_lQ`nQbpP<19>bXGbVFcVI<5>j\ _`l`dl`d<29>fPCeOBcOB<14>3UO0UP0UP<4>0QR1QR1PR1PS1OS<12>2EY<8>nTe<29>coe\ bpd`peYqgdYk<8>vek<9>UE_<4>soS<8>OSp<7>pWA<9>rcK } Caverns_Of_Mongue { ; Par and Image Copyright 1996 by Lee H. Skinner reset=1960 type=formula formulafile=fract196.frm formulaname=Five-Mandels passes=1 corners=-0.94645508/-0.12360225/-0.30856981/0.30856981 params=100/150/200/250/0/0 float=y maxiter=1023 inside=0 logmap=yes periodicity=0 colors=0Q0oEpuWK<3>sSKrRJrQK<11>hB_g9af8be6df6a<4>k5Ml4Jm4Gn3Co2Ap28q16<\ 2>z01w11<14>wR4wT4wW4<9>yw7zz8yx8<3>rpApnBmmB<4>ciD`hEYgD<9>AT47R37R4<2>\ JOANMCRLEVJGYJK<2>hIWhJYR0CiLk<8>HRxDSzCTu<4>9_Z8aU8aS9`Q9`Q9`P<6>FRJ<15\ >z6BK5DH3FzcHI0ZB22<5>RFAUICWKB<10>zj0z_7<2>z7Rs6Sm9T<14>mzzGJp0fzM10<4>\ f00zZ2z30x42<3>n41<6>ur1wz2ws2<14>oz0oTC<8>v_Iv_Iw`Jw`KxaK<6>uXK cyclerange=2/255 } Mandel-virus { ; Image and Par Copyright by Lee H. Skinner, 1995 reset=1960 type=formula formulafile=fract196.frm formulaname=shifter01 passes=1 center-mag=-0.57764380315000000/+0.63032279420000000/1065.972 params=101/0/0/0 float=y maxiter=1023 inside=bof61 logmap=yes periodicity=0 colors=000zzzATIAWKAZM8_R<3>LacPbgSchVdhMRu_fi<7>vnn<2>tnmtYmsom<9>mript\ k0sinrg<11>XeF<6>ulG<7>xKEyHEyDEz9Dy9Ew9F<14>T16Q05Q15<30>rZAs_AtaBtcB<5\ >vj9vk9wm8wo8xq9<9>ciD`hEYgD<9>AT47R37R4<2>JOANMCRLEVJGYJK<2>hIWhJYhK_<3\ 9>XH7WH7WH6VG5WH5<19>rV6IJRIJPz7Rs6S00Gf3T`1UY4U<2>KFV<2>TGPWHNZILaJJUJJ\ MJIGLGANEAQG cyclerange=2/255 } NutcrackerMonsters { ; Microscopic Creatures Battling With Nutcrackers ; Par and Image Copyright 1996 by Lee H. Skinner reset=1930 type=mandphoenixclx passes=1 corners=-0.2813104698/-0.2742954917/0.1535485472/0.1588097809 params=0/0/0.5/0/0 float=y maxiter=1023 inside=0 logmap=yes colors=000zzz1R1<2>4P45P55N5<8>A0A<19>c5be6de7c<2>f9bfAbgBc<11>kNh04V<33\ >xvx<2>_XXRONIFD963B75<3>HBD<9>z00<2>zR0NYxPZvQYvz_0zh0<13>zhezgixgh<14>\ UfKReIOcIMbHJaGG_FDYC<7>MQCOPCONC<7>J09<8>hD7kF6lG4mH2oJ0<5>xP0zQ0zR0<13\ >ud0te0uf0<8>wo0xq0xq0<6>yx0zz0zy5zwBzuH<7>zzzMKLIJGHLHGMI<9>MYy cyclerange=115/255 } Sliced-Tomato { ; Par and Image Copyright 1995 by Lee H. Skinner reset=1930 type=phoenixcplx passes=1 corners=-2/2/-1.5/1.5 params=0.2/0/0.3/0/0 float=y maxiter=1023 inside=0 logmap=yes colors=000NEpn3Co2Ap28q16<2>z01<12>TB1<4>tV2<3>vc4ve5wf5<2>xl7xn7yp8zr9<\ 10>ciD`hEYgD<9>AT47R37R4<2>JOANMCRLEVJGYJK<2>hIW<4>iNf<7>DSz<5>9_Z8aU8aS\ 9`Q<3>9_OUD0<8>hL0<2>WO5R67<4>T97<5>B0J<12>DSM<6>zi0<3>z7R<4>U0VO8VIGW<2\ >0bd5TVANEBSECYEDcN_J58_KGJhO_zV10<4>z00zlpzWnzW0yLTXb0ze00kazp0zz0zx0yv\ 1xt1xs1xr2<16>oz0oTC<8>v_Iv_Iw`Jw`KxaK<11>sSKrRJrQK<11>hB_g9af8be6df6a<6\ >m4G cyclerange=2/255 } Graphs { ; Better than a graphic calculator! ; (c) Sylvie Gallet [101324,3444], 1996 reset=1960 type=formula formulafile=fract196.frm formulaname=Graph function=sin/abs/ceil/log passes=1 center-mag=0/0/0.2 params=0.002/0.001 float=y maxiter=99 inside=255 colors=000hhhzK0zzz0zKzzzzzzzzz0Kzzzz<5>zzzww0zzz<236>zzz000 } G-3-03-M { ; Uses the new round function. ; (c) Sylvie Gallet [101324,3444], 1996 reset=1940 type=formula formulafile=fractint.frm formulaname=G-3-03-M function=sinh/atanh passes=1 center-mag=-0.292907/-0.345016/0.1164033/1/44.999 params=10/0/5/15 float=y outside=atan decomp=256 periodicity=0 colors=bbb<11>xxx<30>N22L00M11<30>xxx<31>3D8<11>OVQQWSSYUUZWW`Y<4>cgeehf\ gjhilj<7>xxx<31>33D<18>bbdddeffghhi<8>zzz<32>333<18>``` cyclerange=0/255 } Spirals { ; Uses the new trunc function. ; (c) Sylvie Gallet [101324,3444], 1996 reset=1940 type=lambda(fn||fn) function=sin/trunc passes=1 center-mag=+0.00682136237476394/-0.00456388921647477/0.9998262 params=1/0.1/1 float=y maxiter=1023 inside=bof61 symmetry=origin colors=Z4EY2ER0F<6>WjtXqzWmv<12>P00<37>G00G10G10G20H20<26>MG1MG1NF1<12>R\ H2RH2SH2TI2TI2<6>YK2ZL3ZL5<3>XODXOFXPF<7>dYJ<3>tf9<4>vl4<2>gcTa``XYhRVqT\ Wq<7>jdpmfophp<2>wmszotznp<10>vX4sW4qU4oT4<2>dJ4`G5XD5T96S96<7>IB7HB7HB7\ <3>HE9HF9HG9IG9JH9<13>LS9MT9OV9<2>Ub9<7>ld8nd8qe7sf7<19>_6D cyclerange=0/255 } jdsg4101 { ; Par and Image Copyright 1996 by Lee H. Skinner ; time: 13mins 38s at 1600x1200 on a Pentium 166 reset=1960 type=formula formulafile=fract196.frm formulaname=JD-SG-04-1 passes=1 center-mag=-0.21379120971899780/+0.65418802540150260/902.2811 params=0.75/0/2/0 float=y maxiter=1023 inside=0 logmap=yes symmetry=none colors=000ylPwl7<9>xi9xiAxiAxhAxhAXMVCNDO00c20zb90FY0`Tz00h7BQFM0_KOEzzz\ XbU6d000hzxhB<7>zeDzzr<4>V0_A0fmkInf9lN0f`EYaSPaOGbJ<6>8KJ6HJ6HM<3>3H`2I\ d1Hc0Fb<6>6FW7EV7EV7EU<22>F97F96G85G74<3>I00<11>ZC3`D3aE3cF4eI4gL4<6>ug1\ zj1yn0<20>zqzz00<6>umptuxrnv<5>e6d<10>x14z00z10<13>sSCrUDrVDrWD<11>vj9vk\ 9wm8wo8xq9zuA<17>zaay_cy``<9>yk7yl4xl5wl7wl7 cyclerange=2/255 } ptcmjn01 { ; Copyright Sylvie Gallet [101324,3444], Aug 1996 ; t= 0:25:20.78 on a Pentium 166 at 1600x1200 reset=1960 type=formula formulafile=fract196.frm formulaname=ptc+mjn passes=1 center-mag=-0.555949/0.589869/13.92602 params=0.077/0.626/6/0 float=y maxiter=1023 inside=0 logmap=3 colors=00000K00U<13>0fj0ik2ik<15>mww<15>zrw<15>ww0<14>yn7zm8zkA<14>z4c<1\ 5>www<30>VndUmcUmcUmc<47>UmmVmmVmmWmmWmm<52>vvm000kkk cyclerange=2/255 } ptc4m01 { ; Copyright Sylvie Gallet [101324,3444], Aug 1996 ; t= 0:02:31.26 on a Pentium 166 at 1600x1200 reset=1960 type=formula formulafile=fract196.frm formulaname=ptc+4mandels passes=1 center-mag=0/0/0.6666667 params=-1/0/1.4/0/-1.4/0 float=y maxiter=255 inside=0 decomp=256 symmetry=none periodicity=0 colors=06W<11>0fj0ik2ik<15>mww<15>zrw<15>ww0<14>yn7zm8zkA<14>z4c<13>xptx\ suxtuwuuvvuuwv<27>VndUmcUmcUmc<47>UmmVmmVmmWmmWmm<41>ptm<15>00U03V cyclerange=0/255 } EJ_01 { ; "Escher-Julia #1" t= 0:32:35.06 ; t=calc time [h:mm:ss.] using 486DX2-66 at 1024x768 ; (c) 1997 by Les St Clair 101461.2032@compuserve.com ; parameters created on Apr 13, 1997 reset=1960 type=escher_julia passes=1 center-mag=+0.42798355610118920/+0.29420988317529780/3.4153 params=0.005/0.641 float=y bailout=100 inside=bof60 logmap=4 decomp=256 colors=000H51<39>ywezxfzxf<40>H51G40G40<40>ywezxfzxf<40>H51G40G40<40>ywe\ zxfzxf<39>I62 cyclerange=0/255 } Oortcld { ; The Oort Cloud, Birthplace of Comets t= 0:05:37.90 ; on a P166 at 1600x1200 Apr 14, 1997 12:56:49 ; Image Copyright 1997 by Lee H. Skinner reset=1960 type=volterra-lotka passes=1 center-mag=+0.99920743436292140/+1.00133132442466400/91.55482 params=1/1 float=y maxiter=1023 inside=0 outside=atan logmap=yes logmode=fly symmetry=none periodicity=0 colors=000<47>087<5>zul<3>oYUMdgiML<3>z00<7>C00E00000<2>7O8<2>WlHGgG<3>M\ OCNNCOLB<4>EE70W0JC7<3>T85W74X64X64Y53aA6fF9kKC<3>zf4<4>ysV<2>ybNyUG<5>x\ BOx7Qz6Q<7>S6FO79G6C<2>42763A00003C<3>0H46O2CW0<3>FON<5>bOu<4>zvz<2>c`eX\ TYPMRHEJB9D6570002345680E0<7>8VfAYlDYk<3>RXh<9>68A00D233000232<10>5Pw<6>\ zo`<5>5Pw<6>000CC9<7>bbVfeYgcY<7>pGd000000 cyclerange=2/255 } SG8-21-12 { ; New color scheme for Julia and Mandel sets ; Copyright Sylvie Gallet [101324,3444], April 1997 ; t= 0:10:49.33 at 1600 x 1200 on a P166 reset=1960 type=formula formulafile=fract196.frm formulaname=gallet-8-21 passes=1 center-mag=0.152211/0.485915/5.161535/1/14.997 params=0.078/-0.64/0.12/0.18/0/0 float=y maxiter=2047 inside=0 decomp=256 periodicity=0 colors=wwc<21>j`DiZBiZB<13>aM2`L1`L1`K1<11>WD3WC3VB4UB4<5>S75R66R66R66<2\ 8>J11I00I00H00H00<28>000wvy<4>ssursuqrtqrtpqs<13>chgchgbgfbgfafe<10>VaZU\ `YU`YU`Y<13>OVSOVSOVSOURNUR<67>000 cyclerange=0/255 } xfractint-20.4.10.orig/pars/fractint.par0000644000000000000000000004320210150633601014764 0ustar Filament { ; A Mandelbrot Ian Adam reset type=mandel corners=-1.86057396488642/-1.86057395514533/-0.00000093796272/-0.00000093078\ 577 float=y maxiter=1500 inside=0 colors=000512<3>E44G55I66K77M88<13>mCBoCBqBA<2>v97w97y77<2>z11z00z00<9>z00z0\ 0x02<28>20w00y00z<10>00z<5>``zffzllzsszzzz00z<6>00z<5>``zffzllzsszzzz00z<6>0\ 0z<5>``zffzllzsszzzz00K00M00O00Q11S22U44W66Y98_<2>LKePOgTRiXUk`Yldam00z<8>00\ e00c00b<14>00O00O00N00N00M<21>00B00B009<17>000000000000000<24>000301 } Hypnoteyes { ; try color cycling and hitting F4 Pieter Branderhorst reset type=julia corners=-0.162458/0.17487/0.734422/0.984935 params=0.258919/1.76951e-007 colors=@chroma.map } Hypnoteyes2 { ; with decomp, try fast cycling Pieter Branderhorst reset type=julia corners=-0.162458/0.17487/0.734422/0.984935 params=0.258919/1.76951e-007 decomp=256 colors=@blues.map } AtomicGlow { ; try gamma2.map & grey.map too Pieter Branderhorst reset type=sqr(fn) function=cosh corners=0.706238/0.321106/0.622375/0.792267/0.487701/0.915131 potential=255/820/20 colors=0000KN<26>8RL8RL8RL9RL9SL9SL<26>GYKGYKHZJIZJ<39>WjFWjFXkEYkE<25>nqIoq\ JoqJoqJpqJpqJ<4>roFroErnDsmC<17>sECrCCqCC<11>UCCSCDQCDOCEMCEKCFICFGCG<21>GCW\ FCXFCXECYECZ<20>DCrCCsCEs<12>CcsCesChtCku<4>CzzCzz } Mousies { ; sqr(1/cos), with maxiter just 15! Pieter Branderhorst ; (they look like my son's "Mousie" stuffed animal) reset type=sqr(1/fn) function=cos corners=-3.839996/0.692047/-1.723389/1.6745 maxiter=15 inside=0 colors=0000tc0e0wmVc660oQzz0Tunhzlpi`sd0L`fkkk000000000 } MiniMandelbrot { ; try random cycling Pieter Branderhorst reset type=mandel corners=-0.74543892033/-0.74541806988/-0.11300775036/-0.1130095385/-0.745431\ 29839/-0.11299945787 maxiter=1000 inside=0 colors=000000QBr<5>8Gv<11>VSGWTDXSH<8>_Oj_OmZMk<14>S0P<6>LEUKGVJHVJIW<6>GPf4\ zD<10>DZ_EWaEVbFTcGReQ_h`il<10>JSgHQgEJrFLnGNjEGf<2>FMZilU<5>ZhSXoaWm`Vl_hDY\ <5>S_k<12>e0Z<14>mDQmDQnEO<13>yR5<9>G1dzzIyzG<13>cdZbc_`ca<7>NcjMckKclJcmGhh\ <2>9wU<2>tsa<3>jd_ha_f_W<2>bUNaTKbXIb_H<4>7pO<14>3q1Dh9M_HZHVcIXl9du1k<7>X9q } Insectarm { ; barnsleyj2 with decomp Pieter Branderhorst reset type=barnsleyj2 corners=0.220596/0.3306656/0.2319299/0.2133/0.2663158/0.1675801 params=0.757642/1.07726 decomp=256 colors=A0AJ0S<13>p0u8B36B34B32B32B52B7000<100>000zzK<2>_yHRxGIwF8vD0uB<3>Usu\ <8>tcl<6>tlc000<96>000U0m<4>A0K } Rna? { ; barnsleym1 Pieter Branderhorst reset type=barnsleym1 corners=1.35740495/1.36174238/-0.42260021/-0.4214974/1.3584317/-0.42392069 params=0.5555/0.7676 periodicity=-256 } Newton_6 { ; try cycling and F5; try volcano.map Pieter Branderhorst reset type=newton corners=-0.194363/0.194333/1.21358/1.5 params=6 periodicity=-256 colors=000000<25>qqq00z<7>z0z<3>z00<3>zz0<3>0z0<3>0zz<2>0GzVVz<3>zVz<3>zVV<3\ >zzV<3>VzV<3>Vzz<2>Vbzhhz<3>zhz<3>zhh<3>zzh<3>hzh<3>hzz<2>hlz<46>hlz } Spiral { ; A julia Pieter Branderhorst reset type=julia corners=-0.0864522/-0.1012557/0.1608274/0.1801619/-0.1012557/0.1801619 params=-0.204812/-0.663316 maxiter=255 inside=0 colors=@neon.map } Spiral2 { ; Another julia Pieter Branderhorst reset type=julia corners=-1.032595/-0.907029/-0.07522/0.0185483 params=-0.833062/0.194798 maxiter=2000 colors=@royal.map } Bows { ; ribbon and bows Pieter Branderhorst reset type=lambdafn function=exp corners=-0.143341/0.119507/1.09465/1.292023 params=1/0.4 maxiter=5000 decomp=256 colors=xZJhpzxWL<2>zNSzKUyKU<41>UAFhpz<46>hpz2S2<5>GcEIeGLhIOkK<4>czZ<2>XtTU\ qRSoPPlMNkL<9>3S2hpz<67>hpzc00<30>zq1<24>xaH } Reach { ; a stretched wineglass formula Pieter Branderhorst reset type=formula formulafile=fractint.frm formulaname=Wineglass corners=0.23862567/0.24167464/0.58484177/0.58636416 float=y maxiter=255 colors=000zzm<20>zzmfdb<5>fdbzz0<4>z0G0wz<7>00zw2z<13>BFx<29>P_vQ`uQ`uQ`u<16\ 2>www } Float { ; a stretched wineglass formula Pieter Branderhorst reset type=formula formulafile=fractint.frm formulaname=wineglass corners=0.09857260478/0.09856737821/0.14981300096/0.14979180221/0.0985776646\ 3/0.14978712961 float=y colors=653CJbNbMLbbjGJYJ_`QIfdbMMKCWmZjNckroRSWWWwvNxwu653653653ECDEEEHFGMMK\ NONORRWWWZWXfdbckdEFYxwuxwuckr<2>ckrOboOboOboCWmCWmATlrcIreKwuIZjN<6>Zj`Zkb_\ kf<2>ckroRS<5>sePsgPtiPtlPunO<2>wvN<9>xwfHRJCXN<3>ckd<5>xwu<7>sej<4>ckd<6>ee\ cfdbeca<2>`YZZWXZWX<2>WWWVWWUVVSUURTTQSSORRORRORONONNONMNMMMKMMKMMKHJKHJKHFG\ HFGEEEEEEEEEECDECDECD653653653 } Shell { ; this one is a good Rorschach Pieter Branderhorst reset type=manowarj corners=-0.385088301/-0.38385805/-0.018227188/-0.017669901/-0.384912909/-0.0\ 18461045 params=-0.385482666666669/-0.018571636363635 float=y maxiter=850 inside=0 logmap=yes colors=000000<30>zKU<30>211000000<94>000110330<29>zz0<30>220000000<29>000 } RubberDucky { ; a stretched wineglass formula Pieter Branderhorst reset type=formula formulafile=fractint.frm formulaname=wineglass corners=0.2408521729/0.2406268424/0.5851913634/0.5851407676/0.240706247/0.58\ 52776043 float=y maxiter=85 colors=000<32>000AbE<12>HrM<2>czpczp<7>0hez_p<3>zII<3>zaJzgKxrBww0<2>wwi`za<\ 3>EwH000<4>000 } Butterfly { ; type sqr(1/cos) Pieter Branderhorst reset type=sqr(1/fn) function=cos corners=-3.591669/-2.692763/0.449396/1.125021 float=y maxiter=10 decomp=256 colors=0RHwwhcwc<33>0RHvcX<20>m22<12>tTFtVGtWG<5>uaMvbNvbNvbO<13>sYYsYYsXX<1\ 1>mOOmNNlMMkLL<13>W22U00V11<18>qRRsTTsTT<11>t__t__t_Z<13>vbLwcKwaJ<16>m22<21\ >vcX0RH<32>`tb0RHgzj } Cheshire { ; reminds me of Alice in Wonderland Pieter Branderhorst reset type=spider corners=-0.488343/-0.27876/0.140556/-0.138888/-0.27876/-0.138888 maxiter=255 inside=0 invert=0.331101/-0.0974796/0 periodicity=4 colors=qqqqqqqqq000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAA\ AmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP0\ 00rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rA\ AAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP000rAAAmP\ 000rAAAmPGKPDNRFOQLKODPQKRPBVUDYTreKjGJ000<15>000_iKEJQjGJreKsej000<120>000 } Lambdafn { ; beautiful inversion (an fpu helps) Michael Coddington reset type=lambdafn function=cos corners=0.13159977/0.15118976/0.12827285/0.11423222/0.14539167/0.10988365 params=4.72675/0.00145555 float=y maxiter=900 inside=0 invert=0.5/0.2/0.5 colors=00040N91X<5>NCYB4P<18>zmn<9>ua`u`_u`_<2>u_YtZXtZXtYX<27>tOUtOUuNTuMT<\ 9>q8Up6Vq8U<6>_9RY9QV8QS8PQ8P<2>C7IF8JI9LLAN<3>QEOSGPTGP<22>kSWlSXmTXnUYoVY<\ 5>t_bu`bvacwbcxcd<2>zefzefydf<44>WGRVFQVFQUFQ<51>40NoEj } CoolComplexNewton { ; complexnewton using chroma.map Michael Coddington reset type=complexnewton corners=-2.0/2.0/-1.5/1.5 params=4/-3/1/1 float=y inside=bof60 invert=0.5/0.125/-0.125 colors=CCCssC<20>sECsCCqCC<21>ACCCCC<21>sCs<20>ECsCCsCEs<19>CqsCssCsq<8>Cs_C\ sYECE<20>sCs<20>ECsCCsCEs<19>CqsCssCsq<19>CsECsCEsE<19>qsqsssssq<19>ssE } FieryMandelbrot { ; resembles lightning Michael Coddington reset type=mandel corners=-0.59695729/-0.58756756/-0.62374772/-0.61683133 inside=0 colors=000aiu_kxZmzgbmpS`N`8<13>wINF5E<19>wHO7xu<8>tLRz`p<22>yIQyHPwzD<22>yI\ OBR`<23>wHOCxF<5>rNN3DX<3>nHP6`W<9>tIOptH<9>yKORCG<14>wHOlEe<30>yHO8_1<25>wH\ O_uF<7>hgIieJiX`<4>kVc<4>bfr } DinnerPlate { ; Looks like china on tablecloth Dan Farmer reset type=formula formulafile=fractint.frm formulaname=LeeMandel2 corners=-0.0233229/0.0233249/0.2569835/0.291958 inside=0 potential=255/500/500 colors=000DP_Uoq<20>A4XVqq<18>nwjoIRFns0kuUqq<22>ieiUqo<19>HjCTqq<17>4riUqq<\ 20>9ggUqq<14>SxqRyqTpq<6>LgmUqp<11>Pm`XfjPlZ<4>MjSy3J<5>YEB<15>eOFeOFdOF<11>\ ZMAl`AzoAIjb<10>sOD<22>1ZC<3>9SS } Batman { ; Cont Pot... looks like a bat Dan Farmer reset type=manfn+zsqrd function=cosxx corners=1.591553/-3.133835/-3.158447/3.144699/-3.133835/3.144699 maxiter=32000 inside=0 potential=255/300/150 decomp=256 colors=000zk0<253>000 } Tonsils { ; LeeMandel3 forumula, cont. pot. Dan Farmer reset type=formula formulafile=fractint.frm formulaname=leemandel3 corners=1.66875/-1.668761/-2.225006/2.225/-1.668761/2.225 inside=0 potential=255/500/500 colors=000zk0<253>000 } NYUF004 { ; delicate & beautiful Dan Farmer reset type=formula formulafile=fractint.frm formulaname=Richard1 corners=1.0942183/1.0642116/-0.0205947/0.0193983/1.0642116/0.0193983 inside=0 potential=255/600/500 colors=000S9jLSd<147>hwXixWiwW<30>Z7wY5xY5x<69>T9j } NYUF008 { ; Hard to describe. Try it. Dan Farmer reset type=barnsleyj1 corners=2.023155/-0.005196/-1.352236/1.352223/-0.005196/1.352223 params=0.599999905/1.099998949 maxiter=256 inside=0 potential=255/1000/1 colors=000zk0<253>000 } NYUF009 { ; pretty bug if changed to float=n Dan Farmer reset type=fn(z)+fn(pix) function=sin/sqr float=y corners=12.801548/-3.196652/-10.911614/10.419413/-3.196652/10.419413 params=0/0/1 inside=0 potential=255/200/250 colors=000gK4fJ3hPCohbrokpkjmghhZelJ3<2>tM4HC2<13>FZSJD2<9>ieGHB4<9>MCeGD8<6\ >8XyGC3<11>4V`HB3<14>4HhIC6<7>XKjJE3<10>dt_HF1HJ1HO2HH7<3>GeXGF1<10>3y3OCB<3\ >pGpKF8<3>ZZ_HD3<7>ITQIVSGG5IXV<2>Jbc<8>SqFUsCTrD<14>2P`<12>Se4Vg1Ve3<14>_1f\ <3>_7b<2>LHIKMMJPOJRRIUTGa_FdaFfcDnjCqlBto<3>DulEvi<6>IxcVnU<3>tUA<12>hL4 } Arrow { ; formula Wineglass Richard Hughes reset type=formula formulafile=fractint.frm formulaname=Wineglass corners=-0.650529/-0.306983/-0.128843/0.128827 maxiter=256 inside=0 outside=mult logmap=yes symmetry=xaxis colors=00000S88YBBaDDeEEiFFmHHsKKwNNzOOz<2>WWzZZzccz00522755977BAAF<11>cchee\ jffl<2>mmrppurrvttwuuxP0P<2>c0cg0gj0jm0mp0p<3>z0zzFz<6>zmzgfoZ`iTVdPR`<2>HJU\ FHUCHS9LV0OY0Tc0Yh<2>0jw5mz0ozFpz<5>hpzmpzppz000555<18>zzz00V88Y<6>NNz<13>nn\ zppzttzvvzP0PU0UZ0Zc0cg2gh0hm0mr0rw0wz0zzCzzKzzRzzYzzczzhz000555<3>HHHKKKOOO\ SSSWWW___ccchhhmmmssszzzz00zICzNGzQNzTS<3>zbbzeezhizjkzlozopzts000555<3>HHHK\ KKOOOSSSWWW___ccchhhmmmssszzz00P00X08_8DaCFcHEgKHlNGrLOqJVqHar5gtTjv_nwduzlw\ z000555<3>HHHKKKOOOSSSWWW___ccchhhmmmssszzzV0W_0_c4de9fg2gi9jlAmoDprCst0uwCu\ z5zzRzzYzzczzhzzkzzoz<3>zzz00z0z0z00 } Egg { ; FN*FN SINH/SQR Richard Hughes reset type=fn*fn function=sinh/sqr corners=-0.0067631/0.0187092/1.991193/2.0105618 float=y maxiter=256 inside=0 outside=real logmap=yes colors=000ssEssC<20>sECsCCqCC<21>ACCCCC<21>sCs<20>ECsCCsCEs<19>CqsCssCsq<8>C\ s_CsYECE<20>sCs<20>ECsCCsCEs<19>CqsCssCsq<19>CsECsCEsE<19>qsqsssssq<18>ssG } mandala { ; Sqr(1/FN) IDENT Richard Hughes reset type=sqr(1/fn) function=ident ; TW changed - cotan was broken corners=-1.984573/1.98143/-1.486908/1.487839 maxiter=256 inside=0 outside=real colors=000ztn<49>zV1zU0zU0zT0<28>z10z00z00y00<30>c00b11a11`22_22<23>GEEFFFFF\ FFFF<29>x11z00z10<29>zx0zz0zz1<29>zzxzzzzzz<10>zto } Mounts { ; Fn(z)+Fn(pix) COTAN/SQR Richard Hughes reset type=fn(z)+fn(pix) function=cotan/sqr corners=0.494267/0.906929/0.5978/0.907317 params=0/0/1 maxiter=256 inside=0 outside=summ logmap=yes colors=000FFF<29>x11z00z10<29>zx0zz0zz1<29>zzxzzzzzz<61>zV1zU0zU0zT0<28>z10z\ 00z00y00<30>c00b11a11`22_22<25>FFF } SpiderPlant { ; Manowarj Richard Hughes reset type=manowarj corners=-0.18194276/-0.19649744/0.08981478/0.06949806/-0.17743176/0.08380193 maxiter=250 inside=0 outside=imag logmap=yes colors=00000S<25>002000000000<29>00k00m01m<29>0ky0mz1mz<30>zzz<46>2zz0zz0yz<\ 45>02z00z00y<27>00Y } Stripes { ; Mandelfn IDENT Richard Hughes reset type=mandelfn function=ident corners=-1.367645/-0.958344/0.296143/-0.24617/-0.958344/-0.24617 maxiter=100 inside=0 outside=real colors=000s_C<10>sECsCCqCC<21>ACCCCC<21>sCs<20>ECsCCsCEs<17>Cms } Autumn { ; You guessed it! Peter Moreland reset type=ifs ifsfile=fractint.ifs ifs=fern corners=-8.0/8.000351/-0.999954/11.0 colors=000DGT<4>jQ1<2>bgO`lVWmZ<5>5np<3>pky<2>Avk<5>l7KhGaeOrPKq9Hp<5>Mjy<4>\ 11`1cR<6>GlJ<2>_J8OSFC`M<7>J7XOFWSNWXVVbXb`bVUor_lfGKp<4>`fYwL6<6>fgSdeQdhTf\ Se<5>dhWWcBAHB<6>agTQB8<3>acRa0pMC9J`APcGUeL_hQgYifbdef_G3xPInXXdFny<2>Zkalc\ E`Vg<4>dhXJEP<3>`dUK5XRJWYXVKlWQkVVkV_jVcWL<3>deS } The_Eye { ; Kamtora is watching you! Peter Moreland reset type=kamtorus corners=-0.282135/0.424988/-0.237793/0.292328 params=0.3/0.005/5/500 colors=000mme<12>hBAnph000555<3>HHHKKKOOOSSSWWW___ccchhhmmmssszzz00z<3>z0z<3\ >z00<3>zz0<3>0z0<3>0zz<2>0GzVVz<3>zVz<3>zVV<3>zzV<3>VzV<3>Vzz<2>Vbzhhz<3>zhz\ <3>zhh<3>zzh<3>hzh<3>hzz<2>hlz00S<3>S0S<3>S00<3>SS0<3>0S0<3>0SS<2>07SEES<3>S\ ES<3>SEE<3>SSE<3>ESE<3>ESSEOSELS } Blue { ; I like it, no more to say... Peter Moreland reset type=julfn+zsqrd function=cosxx passes=b corners=-2.0/1.99765/-1.501511/1.5 params=-0.5/0.5 maxiter=2250 bailout=30 decomp=256 biomorph=0 colors=000Iaf<27>PtVQuUPrT<5>DZIBVGBVG<15>B_KCOj<27>02FDQm<38>V`bDQl<33>Vt5H\ Ti<8>sxADQm<62>VelMT_VWLdZ6DQm<6>FVjFRmFWj<8>Haf } Orc_Insignia { ; hmmmm..... Peter Moreland reset type=mandelfn function=sin corners=-0.0362244/0.0369263/1.7957306/1.8505707 maxiter=32767 colors=000GNPEPWCRbNKL<2>_NlTLMcOWnRetVAKxPCBL42UHTI<2>Bv_MJAPJ7HJG<2>AHVPCJ\ ONFURI_WLQ4RPbLVwUXLXHNCERCBVDVStNGD<2>`6GZYYnmsd_SzpgTTJ<2>vyeRML<2>nYlS`Ga\ rKMF8QB3JIQKGcLEqIZNGnYXWJjhQxuYWE8h94u40JVCJfCKrBLLF<2>RRPHMJ<2>8VfTcHcyNd`\ Ozr_Xa`kuzKTrAQO0X`PML<2>iYnLyYGEZD9vLQKNYTRSB_`Ahj8LNDNSFPXHSaJTO_cTwUGTeCi\ PXRVje`xtIHGHFKGCPGc_CywbERw9fCMB4QALPC<2>ShEs7R6gnPIFVHIaFLXXDjkESIB`H9jG7S\ mPv_oVXLfkULUINdOPoULJCXVOkf_5zIYNImRPTE8b94l40KGL<2>Q4mprqXBVj3mFXFAkI5zLMf\ YL`YOss_6EZFxbbFvvJM`CQsCTNKbSSlX`wLdTRK<2>vqhMGE<2>V4MNFI<2>_0bFGhGJ9CI6UHG\ eFKOFJ<2>b2cIPLGVVEadJbAJw8FU9Ad65p3_44CVU4glHMG<2>AWUc58SPC`VCi`DFPM<2>1gpb\ oMREI_9OQJMXKWdLeFQJ<2>1mdFDCB7D61EHIH<2>8CXTJBbJAmK8HCjMSO<2>HZQF`QB`l9Kr72\ yuRv<3>YWh<3>mzTlYm } YinFinite { ; like Yin-Yang symbol, infinity sign Ethan Nagel reset type=julia corners=-0.1328505/0.1261121/-0.0104325/0.0093564/-0.0491231/-0.1220701 params=0.252235/0.000169836 maxiter=5000 inside=255 logmap=75 colors=@chroma.map } Rich8z3 { ; Fractal Creations cover Lee Skinner reset type=fn(z)+fn(pix) function=sin/sin corners=0.58152919/0.59067959/1.17166377/1.17852657 maxiter=1023 inside=0 bailout=50 float=y colors=000ww3<3>zz0zz0zy0<81>z10z00z00y01<82>00z00z11y<77>vv4 } Owl { ; fn*z+z, TANH Scott Taylor reset type=fn*z+z function=tanh symmetry=yaxis corners=-1.996257/1.996259/0.79092/3.785347 params=1/0/1 maxiter=512 inside=255 potential=255/355/0 colors=@volcano.map } SWT-018 { ; fn+fn, SINH/COSH Scott Taylor reset type=fn+fn function=sinh/cosh corners=-1.093216/2.098724/2.127304/-2.128159/2.098724/-2.128159 params=1/0/1 maxiter=512 inside=255 potential=255/355/0 colors=@volcano.map } SWT-023 { ; color cycle and press "2" for fun Scott Taylor reset type=mandelfn function=cos symmetry=xyaxis corners=-3.679993/3.681534/-2.759262/2.759003 maxiter=512 inside=255 outside=summ potential=255/400/0 colors=@headache.map } SWT-027 { ; magnet2m Scott Taylor reset type=magnet2m passes=b symmetry=xaxis corners=-4.552174/6.752174/-4.239131/4.239131 maxiter=512 inside=255 outside=summ potential=255/400/0 colors=@headache.map } SWT-029 { ; lambdafn, EXP Scott Taylor reset type=lambdafn function=exp symmetry=xaxis corners=-4.340851/4.336975/-3.250305/3.254669 params=1.9/0.4 maxiter=512 inside=255 potential=255/455/0 colors=@royal.map } SWT-030 { ; lambdafn, COSH Scott Taylor reset type=lambdafn function=cosh corners=-3.949829/3.947968/-2.958694/2.961563 params=1.9/0.4 maxiter=512 inside=255 potential=255/455/0 colors=@neon.map } EvilFrog { ; Kermit with rabies Wesley Loewer reset type=frothybasin passes=1 corners=0.1987794025371462/0.1987794025306378/-1.287290394040766/-1.2872\ 90394029171/0.1987794025292465/-1.287290394030193 params=6/1 float=y maxiter=100 colors=000z00<82>M00z0z<40>M0M0z0<40>0M000z<40>00Mzz0<40>MM0000000000 } Horsetail { ; MIIM Julia Michael Snyder ; Reminds me of a horsetail fern ; Give it your highest 16-color resolution. reset=1732 type=julia_inverse miim=depth/left corners=-1.303326/1.303335/-1.0648/1.064791 params=-0.194/0.6557/3/1024 } SeaHorse { ; MIIM Julia Michael Snyder ; The famous Seahorse Julia -- from a different angle! ; Give it your highest 16-color resolution. reset=1732 type=julia_inverse miim=depth/left corners=-0.213794/0.213791/-1.003197/1.003186/-1.812457/0.013164 params=-0.74543/0.11301/3/1024 } SeaShell { ; MIIM Julia Michael Snyder ; Like a Chambered Nautilus cut in half; my favorite. ; Give it your highest 16-color resolution. reset=1732 type=julia_inverse miim=depth/right corners=0.839251/-0.839269/-1.119046/1.119006/-0.839269/1.119006 params=0.27334/0.00742/5/1024 } xfractint-20.4.10.orig/pars/demo.par0000644000000000000000000000111310150633601014071 0ustar Mandel_Demo { ; PAR for initialization of Fractint demo reset=1900 type=mandel corners=-2.5/1.5/-1.5/1.5 params=0/0 inside=0 sound=no } trunc_demo { ; PAR for initialization of Fractint demo (New in 19.4) reset=1940 type=lambda(fn||fn) function=conj/trunc center-mag=-4.44089e-015/3.55271e-015/0.2339956 params=-0.7398119122257053/1.28140703517588/52 float=y maxiter=255 bailoutest=or inside=0 decomp=256 sound=no colors=DUH<2>EXJFZKFYK<29>121000110<30>rZ0<30>220000011<13>0OL0QM2RM<14>\ ZhZ<30>222000110<30>zkK<30>221000010<25>CTG cyclerange=0/255 } xfractint-20.4.10.orig/pars/fract205.par0000644000000000000000000000505110330023321014470 0ustar BMC0884x { ; 0:11:55.47, 1.3 GHz PIII ; Fractint Version 2004 Patchlevel 2 ; Anthony Hanmer 2000-2005, a.hanmer@gmail.com ; More work to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ reset=2004 type=ifs ifsfile=fract205.ifs ifs=bmc0884x passes=1 center-mag=-0.0100063/4.02919/0.2228164/-1 params=0 float=y maxiter=29000 colors=000006<3>00800900A<9>K04M04O03<2>U01W00W00<10>d00e00f00<14>u70v70\ w80x80z90<79>zm0zm0zn0<43>zx0zy0zy0zy0zy0<68>zzz } DC022b6c { ; 0:45:36.71, 1.3 GHz PIII ; Fractint Version 2004 Patchlevel 2 ; Anthony Hanmer 2000-2005, a.hanmer@gmail.com ; More work to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ reset=2004 type=ifs ifsfile=fract205.ifs ifs=dc022b6c passes=1 center-mag=0.3202/4.5196/0.203252 params=0 float=y maxiter=120000 colors=000006<3>00800900A<9>K04M04O03<2>U01W00W00<10>d00e00f00<14>u70v70\ w80x80z90<79>zm0zm0zn0<43>zx0zy0zy0zy0zy0<68>zzz } Sq0002d { ; 0:23:29.99, 1.3 GHz PIII ; Fractint Version 2004 Patchlevel 2 ; Anthony Hanmer 2000-2005, a.hanmer@gmail.com ; More work to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ reset=2004 type=ifs ifsfile=fract205.ifs ifs=Sq0002d passes=1 center-mag=0/5/0.1666667 params=0 maxiter=57000 viewwindows=1/1/yes/0/0 colors=000006<3>00800900A<9>K04M04O03<2>U01W00W00<10>d00e00f00<14>u70v70\ w80x80z90<79>zm0zm0zn0<43>zx0zy0zy0zy0zy0<68>zzz } Sq441 { ; 0:25:74.97, 1.3 GHz PIII ; Fractint Version 2004 Patchlevel 2 ; Anthony Hanmer 2000-2005, a.hanmer@gmail.com ; More work to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ reset=2004 type=ifs ifsfile=fract205.ifs ifs=sq441 center-mag=0/5/0.1666667 params=0 float=y maxiter=32000 sound=off viewwindows=1/1/yes/0/0 colors=000006<3>00800900A<9>K04M04O03<2>U01W00W00<10>d00e00f00<14>u70v70\ w80x80z90<79>zm0zm0zn0<43>zx0zy0zy0zy0zy0<68>zzz } TD081 { ; 0:20:11.22, 1.3 GHz PIII ; Fractint Version 2004 Patchlevel 2 ; Anthony Hanmer 2000-2005, a.hanmer@gmail.com ; More work to be found in HanmerIFS_01.ZIP at: ; http://spanky.triumf.ca/pub/fractals/FORMULAS/ reset=2004 type=ifs ifsfile=fract205.ifs ifs=td081 passes=1 center-mag=-7.99361e-015/5/0.1572327 params=0 maxiter=46000 colors=000006<3>00800900A<9>K04M04O03<2>U01W00W00<10>d00e00f00<14>u70v70\ w80x80z90<79>zm0zm0zn0<43>zx0zy0zy0zy0zy0<68>zzz } xfractint-20.4.10.orig/pars/lyapunov.par0000644000000000000000000000475610150633601015042 0ustar Blob1 { ; ; moderately slow reset type=lyapunov corners=2.719/3.178/3.26/3.604 params=65/0.05 maxiter=25 colors=@gamma1.map } Blob2 { ; with boomerang ; moderately slow reset type=lyapunov corners=3.269576/3.436403/3.532501/3.657621 params=20/0.5 maxiter=25 colors=@royal } bug { reset type=lyapunov corners=3.82/3.87/3.82/3.8575 params=2/0.025 maxiter=150 colors=@chroma } Flames { ; ; merely slow reset type=lyapunov passes=1 corners=3.5/3.2/4.0/3.6/3.2/3.6 params=60/0.5 maxiter=15 colors=000FFF<29>x11z00z10<29>zx0zz0zz1<29>zzxzzzzzz<61>zV1zU0zU0zT0<28>z10z\ 00z00y00<30>c00b11a11`22_22<25>FFF } Hydra { ; a two headed snail ; very slow reset type=lyapunov corners=3.5718145/3.6718145/3.7886837/3.8636837 params=5/0.5 float=y colors=@chroma.map } Snail1 { ; ; merely slow reset type=lyapunov corners=3.008/3.658667/3.409266/3.897266 params=32/0.5 maxiter=15 colors=000F3HG5JG7KI8JI9ML9LJBNLBOLCPMDNNDQPDPNFPQERQFRQGQQGUSGTSHSTHTSIVSJT\ TJUSKVVJWUKXULVVLWVLZXLXWMYVNYWNZXNZWOZXO_YO_XP__O_ZP`ZPbZQ`_Q``Q`_R``R``Rca\ RbbRbaSb`TbaTbcSdbTdbTfcTfcUccUedUedUgcVgdVgeVfeVhdWheWgdXgfWifXffXhfXjfYgfY\ igYhfZhfZjiYiiYkhZkg_jiZljZki_jh`jh`li`kj`jj`lj`nk`ml`ll`nkamkaokblmammaolbn\ lbplcmnbnnbpmcomcqncpocomdqndpodomeqnepoeooepoerpeqofpofrqespfrpftogspgrqgqq\ grqgtphsqhrsgsqhurhtqisshtrisriuthvsiurjttiutiwsjvuiwtjvskuujvujxtkwvjxukwtl\ vvkwulvwkwulyvlxvlyumxwlyvmxxlywmxwmzwmzvnzxmzwnzymz<2>wozynzxozznzyozyozzoz\ zozypzzoz<3>zpzyqzzpz<4>zqzzrzzqz<4>zrzzszzrz<5>zszztzzsz<2>ztzzuzztzztzzuzz\ tz<3>zuzzvzzuz<3>zvzzwzzvzzvzzwzzwzzvz<3>zwzzxzzwz<5>zyzzyzzxz<10>zzz } Snail2 { ; ; merely slow reset type=lyapunov corners=2.393981/3.620648/2.962111/3.882111 params=20/0.5 float=y maxiter=15 colors=@gamma1.map } Swallow { ; The swallow from the Scientific American article ; pretty slow reset type=lyapunov corners=3.8066559/3.8798065/3.809082/3.8639221 params=0/0.5 maxiter=15 colors=@lyapunov.map } smbird1 { ; simpler than the swallow ; merely slow reset type=lyapunov corners=2.736/3.195/3.662/4.0 params=63/0.5 maxiter=15 colors=@blues.map } smbird2 { ; smbird1 with 50 iterations instead of 15 ; merely slow reset type=lyapunov corners=2.736/3.195/3.662/4.0 params=63/0.5 maxiter=50 colors=@blues.map } xfractint-20.4.10.orig/pars/orbits.par0000644000000000000000000000653410210346240014460 0ustar demonic_moose { ; Jonathan Osuch josuch@fractint.org reset=2004 type=tetrate passes=o center-mag=0.325467/4.44089e-16/0.5788618/1/-90/3.88578058618804789e-16 params=0/0 float=y inside=0 outside=summ orbitdelay=30 orbitinterval=5 colors=000FFF<24>p33r33s22<2>x11z00z10<24>zn0zp0zr0<2>zx0zz0zz1<24>zznzz\ pzzr<2>zzxzzzzzz<57>zX5zX4zW3zW2zV1<27>z50z40z30z20z10z00<28>f00e00d00<3\ 1>FFF } space_debris { ; Jonathan Osuch josuch@fractint.org reset=2004 type=mandelfn function=sin passes=o center-mag=-3.9968e-15/3.10862e-15/0.3360215 params=0/0 float=y inside=0 outside=summ orbitdelay=40 colors=000FFF<24>p33r33s22<2>x11z00z10<24>zn0zp0zr0<2>zx0zz0zz1<24>zznzz\ pzzr<2>zzxzzzzzz<57>zX5zX4zW3zW2zV1<27>z50z40z30z20z10z00<28>f00e00d00<3\ 1>FFF } solar_flares { ; Jonathan Osuch josuch@fractint.org reset=2004 type=fn(z)+fn(pix) function=recip/sqr passes=o center-mag=-1.55431e-15/1.11022e-15/0.613196 params=0/0/1/0 float=y inside=0 outside=summ orbitdelay=50 orbitinterval=7 colors=000FFF<24>p33r33s22<2>x11z00z10<24>zn0zp0zr0<2>zx0zz0zz1<24>zznzz\ pzzr<2>zzxzzzzzz<57>zX5zX4zW3zW2zV1<27>z50z40z30z20z10z00<28>f00e00d00<3\ 1>FFF } spaghetti { ; Jonathan Osuch josuch@fractint.org reset=2004 type=mandel passes=o center-mag=-0.116813/0.0273794/2.73224 params=0/0 float=y inside=0 colors=00000z<3>00i00a<3>00L00H00D<2>000<10>d0Lg0Nk0P<3>z0Xv0Vr0Tp0Sn0R<\ 6>O0CK0AG08<3>000<9>X0a_0dc0h<3>p0w<9>K0NH0JD0F<3>000<9>bbbfffjjj<3>zzz<\ 9>OOOKKKGGG<3>000L00<8>k00<4>z00<2>p00l00h00d00a00<3>N00J00F00<3>000<9>b\ L0fN0jP0<3>zX0<9>OC0KA0G80<3>000<9>__0cb0gf0<3>ut0<9>ML0II0FE0<3>000GA4<\ 7>7c26g25k2<2>2v10z00w0<8>0O00K00G0<3>000<14>00v } line_orbit01 { ; Jonathan Osuch josuch@fractint.org reset=2004 type=mandel passes=o center-mag=-0.393884/0.629234/1.336065 params=0/0 float=y maxiter=5000 inside=0 outside=summ periodicity=0 screencoords=yes orbitcorners=-1/1/-0.5/1 orbitdrawmode=l } zoomed_line_orbit { ; Jonathan Osuch josuch@fractint.org reset=2004 type=mandel passes=o corners=-2.5/1.5/-1.5/1.5 params=0/0 float=y maxiter=5000 inside=0 periodicity=0 orbitdelay=30 screencoords=yes orbitcorners=-1/0.5/-1/0.5 orbitdrawmode=l colors=000w000z0w000z0w000y1w100y1w100x2w200x2w200w3w300w3w300v4w400v4w4\ 00u5w500u5w500t6w600t6w600s7w700s7w700r8w800r8w800q9w900q9w900pAwA00pAwA\ 00oBwB00oBwB00nCwC00nCwC00mDwD00mDwD00lEwE00lEwE00kFwF00kFwF00jGwG00jGwG\ 00iHwH00iHwH00hIwI00hIwI00gJwJ00gJwJ00fKwK00fKwK00eLxL00eLxL00dMxM00dMxM\ 00cNxN00cNxN00bOxO00bOxO00aPxP00aPxP00`QxQ00`QxQ00_RxR00_RxR00ZSxS00ZSxS\ 00YTxT00YTxT00XUxU00XUxU00WVxV00WVxV00VWxW00VWxW00UXxX00UXxX00TYxY00TYxY\ 00SZxZ00SZxZ00R_x_00R_x_00Q`x`00Q`x`00Paxa00Paxa00Obxb00Obxb00Ncxc00Ncxc\ 00Mdxd00Mdxd00Leye00Leye00Kfyf00Kfyf00Jgyg00Jgyg00Ihyh00Ihyh00Hiyi00Hiyi\ 00Gjyj00Gjyj00Fkyk00Fkyk00Elyl00Elyl00Dmym00Dmym00Cnyn00Cnyn00Boyo00Boyo\ 00Apyp00Apyp009qyq009qyq008ryr008ryr007sys007sys006tyt006tyt005uyu005uyu\ 004vyv004vyv003wyw003wyw002xyx002xyx001yyy001yzz0zW00WW } line_orbit02 { ; Jonathan Osuch josuch@fractint.org ; Variation found using the evolver reset=2004 type=mandel passes=o center-mag=-0.393884/0.629234/1.336065 params=-0.097511530549969305/-0.16060705571929321 float=y maxiter=5000 inside=0 outside=summ periodicity=0 screencoords=yes orbitcorners=-1/1/-0.5/1 orbitdrawmode=l } xfractint-20.4.10.orig/pars/phoenix.par0000644000000000000000000000101310150633601014616 0ustar Wolf { ; Jonathan Osuch reset type=phoenix corners=-1.557441/2.234555/-1.422003/1.421998 params=-0.75078049362069/1.40200999374372/2 inside=0 } 3rd_power { ; Jonathan Osuch reset=1733 type=phoenix corners=-1.6838728/-0.80580664/-0.32926887/0.32927984 params=1.1000000000000001/1/3 float=y maxiter=500 inside=0 } totem { ; Jonathan Osuch reset=1733 type=phoenix corners=-0.92/0.92/-1.378935/0.001064718 params=1.1000000000000001/1/-3 float=y maxiter=500 inside=0 } xfractint-20.4.10.orig/pars/fract200.par0000644000000000000000000001756510150633601014510 0ustar comment { par file released with Fractint 20.0 } ismand_demo_julia { ; Image and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=formula formulafile=fract200.frm formulaname=ismand_demo ismand=n passes=d center-mag=0/0/0.6666667 params=-0.1542022284011214/0.6137691202307978/4/0 float=y maxiter=1000 inside=0 decomp=256 periodicity=0 cyclerange=0/255 sound=off colors=05F<63>DISDISDIS<89>uxxuxxvyyvyywzz<94>05F } ismand_demo_mandel { ; Image and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=formula formulafile=fract200.frm formulaname=ismand_demo ismand=y passes=d center-mag=0/0/0.6666667 params=0/0/4/0 float=y maxiter=1000 inside=0 decomp=256 periodicity=0 cyclerange=0/255 sound=off colors=05F<63>DISDISDIS<89>uxxuxxvyyvyywzz<94>05F } Latoocarfian-09 { ; Image and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=latoocarfian function=sin/sin/sin/sinh passes=1 center-mag=+0.00290330359295909/+0.00092771550057891/0.83056\ 69 params=-0.95/2.75/0.075/-0.5600000000000001 float=y maxiter=1000 sound=off colors=000z8W<4>zUMzYJzbH<3>zt8<10>zwfzxizxm<3>zzz<11>LkkIjj\ Eii<3>0cc<27>aqWbqVdrV<2>hsUitUjtV<6>swWtxXuxXvyXwyXyzY<9>yz\ lyzmyzo<2>yzszzuyyt<24>OCOMANL8M<2>G2IE0GE0G333E0G<25>94C95B\ 85B<2>85B76A98E<3>JETLGXNI`QKd<3>YVl_Yna`pccr<9>SShRRgPPf<2>\ MMcKKbKKa<9>EEREEQDDP<5>99H88G77E77D66B55A<3>335223112000<3>\ D2AG2DK3FQ4L<5>j8`<2>v8X } Latoocarfian-11 { ; Image and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=latoocarfian function=sin/sin/sin/sin passes=1 center-mag=-0.00000000000000044/+0.00000000000000033/0.81300\ 81/1/-5 params=-1.751/1.505/1.39/0.001 float=y maxiter=1000 sound=off colors=000n8_<2>z8W<4>zUMzYJzbH<3>zt8<10>zwfzxizxm<3>zzz<11>\ LkkIjjEii<3>0cc<27>aqWbqVdrV<2>hsUitUjtV<6>swWtxXuxXvyXwyXyz\ Y<9>yzlyzmyzo<2>yzszzuyyt<24>OCOMANL8M<2>G2IE0GE0G333E0G<25>\ 94C95B85B<2>85B76A98E<3>JETLGXNI`QKd<3>YVl_Yna`pccr<9>SShRRg\ PPf<2>MMcKKbKKa<9>EEREEQDDP<5>99H88G77E77D66B55A<3>335223112\ 000<3>D2AG2DK3FQ4L<5>j8` } Latoocarfian-12 { ; Image and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=latoocarfian function=sin/sin/sin/cosxx passes=1 center-mag=-0.33504046793695770/-0.51374300838841750/0.97462\ 83/1/64.999 params=-0.85/2.19/0.64/-0.75 float=y maxiter=2000 sound=off colors=000c6V<3>p9VsAVvBVzCU<3>zUMzYJzbH<3>zt8<10>zwfzxizxm<\ 3>zzz<11>LkkIjjEii<3>0cc<27>aqWbqVdrV<2>hsUitUjtV<6>swWtxXux\ XvyXwyXyzY<9>yzlyzmyzo<2>yzszzuyyt<24>OCOMANL8M<2>G2IE0GE0G3\ 33E0G<25>94C95B85B<2>85B76A98E<3>JETLGXNI`QKd<3>YVl_Yna`pccr\ <9>SShRRgPPf<2>MMcKKbKKa<9>EEREEQDDP<5>99H88G77E77D66B55A<3>\ 335223112000<5>K3FQ4L<2>_6T } Latoocarfian-17 { ; Image and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=latoocarfian function=sin/atan/sin/conj passes=1 center-mag=+0.00000000000000044/+0.00000000000000000/0.57886\ 18 params=4.11/2.71828182845905/0.41/0.1 float=y maxiter=2000 sound=off colors=000fbp<3>rptvtvvtv<42>GGfFFfEEf<3>AAcAAbAAa<13>B6MC6L\ C6KC5JC5HC5G<79>NTuNTuNTvOUw<76>K5QK5QK5P<2>K4OJ3NL4P<3>R8_T\ 9bVBe<4>hYn } music_1 { ; Music and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=gingerbreadman passes=1 corners=3.751879/0.07802473/7.537395/-3.930215/6.557631/2.54\ 9392 params=8.01/2 float=y maxiter=100 bailout=128 inside=3 viewwindows=4.2/0.75/yes/0/0 hertz=150 sound=x/fm/quant polyphony=9 wavetype=5 attack=1 sustain=10 srelease=15 scalemap=1/2/1/3/1/4/1/5/1/6/1/7 orbitdelay=1300 showorbit=yes colors=@default.map } music_2 { ; Music and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=quadruptwo passes=1 corners=-2.523687/37.52171/-51.15019/-34.31792 params=-33/1/5 float=y maxiter=20 bailout=64 inside=3 viewwindows=4.2/0.75/yes/0/0 hertz=10 sound=z/fm/quant polyphony=3 attack=1 decay=6 sustain=7 srelease=14 scalemap=1/2/1/3/1/4/1/5/1/6/1/7 orbitdelay=1900 showorbit=yes colors=@default.map } music_3 { ; Music and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=quadruptwo passes=1 corners=-36.04249/11.80311/-35.97947/-15.86855 params=-25/1/5 float=y maxiter=20 bailout=64 inside=3 viewwindows=4.2/0.75/yes/0/0 hertz=10 sound=z/fm/quant polyphony=9 wavetype=2 attack=1 decay=7 sustain=10 srelease=13 scalemap=1/2/1/3/1/4/1/5/1/6/1/7 orbitdelay=1900 showorbit=yes colors=@default.map } music_4 { ; Music and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=quadruptwo passes=1 corners=-29.41428/9.819112/-37.59262/-21.10167 params=-25/1/5 float=y maxiter=12 bailout=64 inside=3 viewwindows=4.2/0.75/yes/0/0 hertz=8 sound=z/fm/quant polyphony=6 wavetype=2 attack=9 decay=9 sustain=11 srelease=13 scalemap=1/1/3/3/3/6/6/8/8/10/10/12 orbitdelay=1625 showorbit=yes colors=@default.map } music_5 { ; Music and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=hopalong passes=1 center-mag=-0.406464/-0.371105/0.2523325/0.784/-43.558/0.968 params=-1/1.101/0.995 float=y maxiter=3 viewwindows=4.2/0.75/yes/0/0 hertz=150 sound=x/fm/quant polyphony=5 wavetype=1 attack=8 decay=8 sustain=11 scalemap=1/1/3/3/3/6/6/8/8/10/10/11 orbitdelay=1600 showorbit=yes colors=@default.map } music_6 { ; Music and par Copyright (c) Sylvie Gallet, 1999 ; sylvie_gallet@compuserve.com reset=2000 type=threeply passes=1 center-mag=4.54747e-013/-4.54747e-013/0.0005274262 params=1/-1/1 float=y maxiter=3 viewwindows=4.2/0.75/yes/0/0 hertz=50 sound=x/fm/quant polyphony=9 attack=9 sustain=8 scalemap=1/1/3/3/3/6/6/8/8/10/10/11 orbitdelay=1500 showorbit=yes colors=@default.map } Waterfall { ; Music par Copyright (c) Bill Jemison [70400,2537] 1999 ; Fractint ver. 20.0 ; Compatible with most SB compatible cards (OPL-3 chip) reset=2000 type=chip passes=1 center-mag=0/0/0.001754386 params=-15/-19/1 float=y viewwindows=12/0.75/yes/0/0 hertz=-100 sound=x/fm/quant polyphony=3 decay=8 sustain=14 srelease=10 scalemap=1/3/5/6/8/10/12/1/3/5/8/10 orbitdelay=1000 showorbit=yes } Mariah { ; Music par Copyright (c) Bill Jemison [70400,2537] 1999 ; Fractint ver. 20.0 ; Compatible with most SB compatible cards (OPL-3 chip) reset=2000 type=mandel passes=1 center-mag=-0.215153/0.643042/1353.996/0.1539/-7.499/-51.994 params=0/0 maxiter=1000 viewwindows=16/0.75/yes/0/0 hertz=220 sound=y/fm polyphony=6 wavetype=4 orbitdelay=1000 showorbit=yes } The_Sorceress { ; Music par Copyright (c) Bill Jemison [70400,2537] 1999 ; Fractint ver. 20.0 ; Compatible with most SB compatible cards (OPL-3 chip) reset=2000 type=chip passes=1 center-mag=0/0/0.001754386 params=-15/-19/1 float=y viewwindows=12/0.75/yes/0/0 hertz=-200 sound=x/pc/fm/quant polyphony=6 attack=9 decay=8 sustain=14 srelease=10 scalemap=1/4/4/8/8/4/1/4/8/4/4/1 orbitdelay=1000 showorbit=yes } Pod_Racers { ; Music par Copyright (c) Bill Jemison [70400,2537] 1999 ; Fractint ver. 20.0 ; Compatible with most SB compatible cards (OPL-3 chip) reset=2000 type=mandelcloud passes=1 center-mag=-0.5/0/0.6666667 params=50 float=y maxiter=500 viewwindows=12/0.75/yes/0/0 hertz=512 sound=x/pc/fm polyphony=3 wavetype=1 decay=8 sustain=14 srelease=10 orbitdelay=1000 showorbit=yes } xfractint-20.4.10.orig/common/0000755000000000000000000000000011456314752013005 5ustar xfractint-20.4.10.orig/common/lsysf.c0000644000000000000000000004231610150633601014302 0ustar #include #ifdef __TURBOC__ #include #else #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "lsys.h" #ifdef max #undef max #endif struct lsys_cmd { void (*f)(struct lsys_turtlestatef *); int ptype; union { long n; LDBL nf; } parm; char ch; }; #define sins_f ((LDBL *)(boxy)) #define coss_f (((LDBL *)(boxy)+50)) static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_turtlestatef *, struct lsys_cmd far **,int); /* Define blanks for portability */ #ifdef XFRACT void lsysf_prepfpu(struct lsys_turtlestatef *x) { } void lsysf_donefpu(struct lsys_turtlestatef *x) { } #endif #ifdef XFRACT static void lsysf_doplus(struct lsys_turtlestatef *cmd) { if (cmd->reverse) { if (++cmd->angle == cmd->maxangle) cmd->angle = 0; } else { if (cmd->angle) cmd->angle--; else cmd->angle = cmd->dmaxangle; } } #else extern void lsysf_doplus(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT /* This is the same as lsys_doplus, except maxangle is a power of 2. */ static void lsysf_doplus_pow2(struct lsys_turtlestatef *cmd) { if (cmd->reverse) { cmd->angle++; cmd->angle &= cmd->dmaxangle; } else { cmd->angle--; cmd->angle &= cmd->dmaxangle; } } #else extern void lsysf_doplus_pow2(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dominus(struct lsys_turtlestatef *cmd) { if (cmd->reverse) { if (cmd->angle) cmd->angle--; else cmd->angle = cmd->dmaxangle; } else { if (++cmd->angle == cmd->maxangle) cmd->angle = 0; } } #else extern void lsysf_dominus(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dominus_pow2(struct lsys_turtlestatef *cmd) { if (cmd->reverse) { cmd->angle--; cmd->angle &= cmd->dmaxangle; } else { cmd->angle++; cmd->angle &= cmd->dmaxangle; } } #else extern void lsysf_dominus_pow2(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_doslash(struct lsys_turtlestatef *cmd) { if (cmd->reverse) cmd->realangle -= cmd->parm.nf; else cmd->realangle += cmd->parm.nf; } #else extern void lsysf_doslash(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dobslash(struct lsys_turtlestatef *cmd) { if (cmd->reverse) cmd->realangle += cmd->parm.nf; else cmd->realangle -= cmd->parm.nf; } #else extern void lsysf_dobslash(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_doat(struct lsys_turtlestatef *cmd) { cmd->size *= cmd->parm.nf; } #else extern void lsysf_doat(struct lsys_turtlestatef *cmd, long n); #endif static void lsysf_dopipe(struct lsys_turtlestatef *cmd) { cmd->angle = (char)(cmd->angle + cmd->maxangle / 2); cmd->angle %= cmd->maxangle; } #ifdef XFRACT static void lsysf_dopipe_pow2(struct lsys_turtlestatef *cmd) { cmd->angle += cmd->maxangle >> 1; cmd->angle &= cmd->dmaxangle; } #else extern void lsysf_dopipe_pow2(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dobang(struct lsys_turtlestatef *cmd) { cmd->reverse = ! cmd->reverse; } #else extern void lsysf_dobang(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dosizedm(struct lsys_turtlestatef *cmd) { double angle = (double) cmd->realangle; double s, c; s = sin(angle); c = cos(angle); cmd->xpos += cmd->size * cmd->aspect * c; cmd->ypos += cmd->size * s; if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos; if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos; if (cmd->xposxmin) cmd->xmin=cmd->xpos; if (cmd->yposymin) cmd->ymin=cmd->ypos; } #else extern void lsysf_dosizedm(struct lsys_turtlestatef *cmd, long n); #endif #ifdef XFRACT static void lsysf_dosizegf(struct lsys_turtlestatef *cmd) { cmd->xpos += cmd->size * coss_f[(int)cmd->angle]; cmd->ypos += cmd->size * sins_f[(int)cmd->angle]; if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos; if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos; if (cmd->xposxmin) cmd->xmin=cmd->xpos; if (cmd->yposymin) cmd->ymin=cmd->ypos; } #else extern void lsysf_dosizegf(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dodrawd(struct lsys_turtlestatef *cmd) { double angle = (double) cmd->realangle; double s, c; int lastx, lasty; s = sin(angle); c = cos(angle); lastx=(int) cmd->xpos; lasty=(int) cmd->ypos; cmd->xpos += cmd->size * cmd->aspect * c; cmd->ypos += cmd->size * s; draw_line(lastx, lasty, (int) cmd->xpos, (int) cmd->ypos, cmd->curcolor); } #else extern void lsysf_dodrawd(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dodrawm(struct lsys_turtlestatef *cmd) { double angle = (double) cmd->realangle; double s, c; s = sin(angle); c = cos(angle); cmd->xpos += cmd->size * cmd->aspect * c; cmd->ypos += cmd->size * s; } #else extern void lsysf_dodrawm(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dodrawg(struct lsys_turtlestatef *cmd) { cmd->xpos += cmd->size * coss_f[(int)cmd->angle]; cmd->ypos += cmd->size * sins_f[(int)cmd->angle]; } #else extern void lsysf_dodrawg(struct lsys_turtlestatef *cmd); #endif #ifdef XFRACT static void lsysf_dodrawf(struct lsys_turtlestatef *cmd) { int lastx = (int) cmd->xpos; int lasty = (int) cmd->ypos; cmd->xpos += cmd->size * coss_f[(int)cmd->angle]; cmd->ypos += cmd->size * sins_f[(int)cmd->angle]; draw_line(lastx,lasty,(int) cmd->xpos, (int) cmd->ypos, cmd->curcolor); } #else extern void lsysf_dodrawf(struct lsys_turtlestatef *cmd); #endif static void lsysf_dodrawc(struct lsys_turtlestatef *cmd) { cmd->curcolor = (char)(((int) cmd->parm.n) % colors); } static void lsysf_dodrawgt(struct lsys_turtlestatef *cmd) { cmd->curcolor = (char)(cmd->curcolor - cmd->parm.n); if ((cmd->curcolor %= colors) == 0) cmd->curcolor = (char)(colors-1); } static void lsysf_dodrawlt(struct lsys_turtlestatef *cmd) { cmd->curcolor = (char)(cmd->curcolor + cmd->parm.n); if ((cmd->curcolor %= colors) == 0) cmd->curcolor = 1; } static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *command, struct lsys_turtlestatef *ts, struct lsys_cmd far **rules, int depth) { struct lsys_cmd far **rulind; int tran; if (overflow) /* integer math routines overflowed */ return NULL; if (stackavail() < 400) { /* leave some margin for calling subrtns */ ts->stackoflow = 1; return NULL; } while (command->ch && command->ch !=']') { if (! (ts->counter++)) { static FCODE msg[]={"L-System thinking (higher orders take longer)"}; /* let user know we're not dead */ if (thinking(1,msg)) { ts->counter--; return NULL; } } tran=0; if (depth) { for(rulind=rules;*rulind;rulind++) if ((*rulind)->ch==command->ch) { tran=1; if (findsize((*rulind)+1,ts,rules,depth-1) == NULL) return(NULL); } } if (!depth || !tran) { if (command->f) { switch (command->ptype) { case 4: ts->parm.n = command->parm.n; break; case 10: ts->parm.nf = command->parm.nf; break; default: break; } (*command->f)(ts); } else if (command->ch == '[') { char saveang,saverev; LDBL savesize,savex,savey,saverang; lsys_donefpu(ts); saveang=ts->angle; saverev=ts->reverse; savesize=ts->size; saverang=ts->realangle; savex=ts->xpos; savey=ts->ypos; lsys_prepfpu(ts); if ((command=findsize(command+1,ts,rules,depth)) == NULL) return(NULL); lsys_donefpu(ts); ts->angle=saveang; ts->reverse=saverev; ts->size=savesize; ts->realangle=saverang; ts->xpos=savex; ts->ypos=savey; lsys_prepfpu(ts); } } command++; } return command; } int _fastcall lsysf_findscale(struct lsys_cmd far *command, struct lsys_turtlestatef *ts, struct lsys_cmd far **rules, int depth) { float horiz,vert; LDBL xmin, xmax, ymin, ymax; LDBL locsize; LDBL locaspect; struct lsys_cmd far *fsret; locaspect=screenaspect*xdots/ydots; ts->aspect = locaspect; ts->xpos = ts->ypos = ts->xmin = ts->xmax = ts->ymax = ts->ymin = 0; ts->angle = ts->reverse = ts->counter = 0; ts->realangle = 0; ts->size = 1; lsys_prepfpu(ts); fsret = findsize(command,ts,rules,depth); lsys_donefpu(ts); thinking(0, NULL); /* erase thinking message if any */ xmin = ts->xmin; xmax = ts->xmax; ymin = ts->ymin; ymax = ts->ymax; /* locsize = ts->size; */ if (fsret == NULL) return 0; if (xmax == xmin) horiz = (float)1E37; else horiz = (float)((xdots-10)/(xmax-xmin)); if (ymax == ymin) vert = (float)1E37; else vert = (float)((ydots-6) /(ymax-ymin)); locsize = (vertxpos = xdots/2; else /* ts->xpos = -xmin*(locsize)+5+((xdots-10)-(locsize)*(xmax-xmin))/2; */ ts->xpos = (xdots-locsize*(xmax+xmin))/2; if (vert == 1E37) ts->ypos = ydots/2; else /* ts->ypos = -ymin*(locsize)+3+((ydots-6)-(locsize)*(ymax-ymin))/2; */ ts->ypos = (ydots-locsize*(ymax+ymin))/2; ts->size = locsize; return 1; } struct lsys_cmd far * _fastcall drawLSysF(struct lsys_cmd far *command,struct lsys_turtlestatef *ts, struct lsys_cmd far **rules,int depth) { struct lsys_cmd far **rulind; int tran; if (overflow) /* integer math routines overflowed */ return NULL; if (stackavail() < 400) { /* leave some margin for calling subrtns */ ts->stackoflow = 1; return NULL; } while (command->ch && command->ch !=']') { if (!(ts->counter++)) { if (keypressed()) { ts->counter--; return NULL; } } tran=0; if (depth) { for(rulind=rules;*rulind;rulind++) if ((*rulind)->ch == command->ch) { tran=1; if (drawLSysF((*rulind)+1,ts,rules,depth-1) == NULL) return NULL; } } if (!depth||!tran) { if (command->f) { switch (command->ptype) { case 4: ts->parm.n = command->parm.n; break; case 10: ts->parm.nf = command->parm.nf; break; default: break; } (*command->f)(ts); } else if (command->ch == '[') { char saveang,saverev,savecolor; LDBL savesize,savex,savey,saverang; lsys_donefpu(ts); saveang=ts->angle; saverev=ts->reverse; savesize=ts->size; saverang=ts->realangle; savex=ts->xpos; savey=ts->ypos; savecolor=ts->curcolor; lsys_prepfpu(ts); if ((command=drawLSysF(command+1,ts,rules,depth)) == NULL) return(NULL); lsys_donefpu(ts); ts->angle=saveang; ts->reverse=saverev; ts->size=savesize; ts->realangle=saverang; ts->xpos=savex; ts->ypos=savey; ts->curcolor=savecolor; lsys_prepfpu(ts); } } command++; } return command; } struct lsys_cmd far * LSysFSizeTransform(char far *s, struct lsys_turtlestatef *ts) { struct lsys_cmd far *ret; struct lsys_cmd far *doub; int max = 10; int n = 0; void (*f)(); long num; int ptype; double PI180 = PI / 180.0; void (*plus)() = (ispow2(ts->maxangle)) ? lsysf_doplus_pow2 : lsysf_doplus; void (*minus)() = (ispow2(ts->maxangle)) ? lsysf_dominus_pow2 : lsysf_dominus; void (*pipe)() = (ispow2(ts->maxangle)) ? lsysf_dopipe_pow2 : lsysf_dopipe; void (*slash)() = lsysf_doslash; void (*bslash)() = lsysf_dobslash; void (*at)() = lsysf_doat; void (*dogf)() = lsysf_dosizegf; ret = (struct lsys_cmd far *) farmemalloc((long) max * sizeof(struct lsys_cmd)); if (ret == NULL) { ts->stackoflow = 1; return NULL; } while (*s) { f = NULL; num = 0; ptype = 4; ret[n].ch = *s; switch (*s) { case '+': f = plus; break; case '-': f = minus; break; case '/': f = slash; ptype = 10; ret[n].parm.nf = getnumber(&s) * PI180; break; case '\\': f = bslash; ptype = 10; ret[n].parm.nf = getnumber(&s) * PI180; break; case '@': f = at; ptype = 10; ret[n].parm.nf = getnumber(&s); break; case '|': f = pipe; break; case '!': f = lsysf_dobang; break; case 'd': case 'm': f = lsysf_dosizedm; break; case 'g': case 'f': f = dogf; break; case '[': num = 1; break; case ']': num = 2; break; default: num = 3; break; } #ifdef XFRACT ret[n].f = (void (*)())f; #else ret[n].f = (void (*)(struct lsys_turtlestatef *))f; #endif if (ptype == 4) ret[n].parm.n = num; ret[n].ptype = ptype; if (++n == max) { doub = (struct lsys_cmd far *) farmemalloc((long) max*2*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, max*sizeof(struct lsys_cmd)); farmemfree(ret); ret = doub; max <<= 1; } s++; } ret[n].ch = 0; ret[n].f = NULL; ret[n].parm.n = 0; n++; doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, n*sizeof(struct lsys_cmd)); farmemfree(ret); return doub; } struct lsys_cmd far * LSysFDrawTransform(char far *s, struct lsys_turtlestatef *ts) { struct lsys_cmd far *ret; struct lsys_cmd far *doub; int max = 10; int n = 0; void (*f)(); LDBL num; int ptype; LDBL PI180 = PI / 180.0; void (*plus)() = (ispow2(ts->maxangle)) ? lsysf_doplus_pow2 : lsysf_doplus; void (*minus)() = (ispow2(ts->maxangle)) ? lsysf_dominus_pow2 : lsysf_dominus; void (*pipe)() = (ispow2(ts->maxangle)) ? lsysf_dopipe_pow2 : lsysf_dopipe; void (*slash)() = lsysf_doslash; void (*bslash)() = lsysf_dobslash; void (*at)() = lsysf_doat; void (*drawg)() = lsysf_dodrawg; ret = (struct lsys_cmd far *) farmemalloc((long) max * sizeof(struct lsys_cmd)); if (ret == NULL) { ts->stackoflow = 1; return NULL; } while (*s) { f = NULL; num = 0; ptype = 4; ret[n].ch = *s; switch (*s) { case '+': f = plus; break; case '-': f = minus; break; case '/': f = slash; ptype = 10; ret[n].parm.nf = getnumber(&s) * PI180; break; case '\\': f = bslash; ptype = 10; ret[n].parm.nf = getnumber(&s) * PI180; break; case '@': f = at; ptype = 10; ret[n].parm.nf = getnumber(&s); break; case '|': f = pipe; break; case '!': f = lsysf_dobang; break; case 'd': f = lsysf_dodrawd; break; case 'm': f = lsysf_dodrawm; break; case 'g': f = drawg; break; case 'f': f = lsysf_dodrawf; break; case 'c': f = lsysf_dodrawc; num = getnumber(&s); break; case '<': f = lsysf_dodrawlt; num = getnumber(&s); break; case '>': f = lsysf_dodrawgt; num = getnumber(&s); break; case '[': num = 1; break; case ']': num = 2; break; default: num = 3; break; } #ifdef XFRACT ret[n].f = (void (*)())f; #else ret[n].f = (void (*)(struct lsys_turtlestatef *))f; #endif if (ptype == 4) ret[n].parm.n = (long)num; ret[n].ptype = ptype; if (++n == max) { doub = (struct lsys_cmd far *) farmemalloc((long) max*2*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, max*sizeof(struct lsys_cmd)); farmemfree(ret); ret = doub; max <<= 1; } s++; } ret[n].ch = 0; ret[n].f = NULL; ret[n].parm.n = 0; n++; doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, n*sizeof(struct lsys_cmd)); farmemfree(ret); return doub; } void _fastcall lsysf_dosincos(void) { LDBL locaspect; LDBL TWOPI = 2.0 * PI; LDBL twopimax; LDBL twopimaxi; int i; locaspect=screenaspect*xdots/ydots; twopimax = TWOPI / maxangle; for(i=0;ix = arg1->x * arg2->x - arg1->y * arg2->y - arg1->z * arg2->z + arg1->t * arg2->t; out->y = arg1->y * arg2->x + arg1->x * arg2->y - arg1->t * arg2->z - arg1->z * arg2->t; out->z = arg1->z * arg2->x - arg1->t * arg2->y + arg1->x * arg2->z - arg1->y * arg2->t; out->t = arg1->t * arg2->x + arg1->z * arg2->y + arg1->y * arg2->z + arg1->x * arg2->t; } void HComplexSqr(_HCMPLX *arg, _HCMPLX *out) { out->x = arg->x * arg->x - arg->y * arg->y - arg->z * arg->z + arg->t * arg->t; out->y = 2 * arg->x * arg->y - 2 * arg->z * arg->t; out->z = 2 * arg->z * arg->x - 2 * arg->t * arg->y; out->t = 2 * arg->t * arg->x + 2 * arg->z * arg->y; } int HComplexInv(_HCMPLX *arg, _HCMPLX *out) { double det, mod, xt_minus_yz; det = (sqr(arg->x - arg->t) + sqr(arg->y + arg->z))* (sqr(arg->x + arg->t) + sqr(arg->y - arg->z)); if(det == 0.0) return(-1); mod = sqr(arg->x) + sqr(arg->y) + sqr(arg->z) + sqr(arg->t); xt_minus_yz = arg->x * arg->t - arg->y * arg->z; out->x = ( arg->x * mod - 2 * arg->t * xt_minus_yz)/det; out->y = (-arg->y * mod - 2 * arg->z * xt_minus_yz)/det; out->z = (-arg->z * mod - 2 * arg->y * xt_minus_yz)/det; out->t = ( arg->t * mod - 2 * arg->x * xt_minus_yz)/det; return(0); } void HComplexAdd(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out) { out->x = arg1->x + arg2->x; out->y = arg1->y + arg2->y; out->z = arg1->z + arg2->z; out->t = arg1->t + arg2->t; } void HComplexSub(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out) { out->x = arg1->x - arg2->x; out->y = arg1->y - arg2->y; out->z = arg1->z - arg2->z; out->t = arg1->t - arg2->t; } void HComplexMinus(_HCMPLX *arg1, _HCMPLX *out) { out->x = -arg1->x; out->y = -arg1->y; out->z = -arg1->z; out->t = -arg1->t; } /* extends the unary function f to *h1 */ void HComplexTrig0(_HCMPLX *h, _HCMPLX *out) { /* This is the whole beauty of Hypercomplex numbers - *ANY* unary complex valued function of a complex variable can easily be generalized to hypercomplex numbers */ _CMPLX a,b, resulta,resultb; /* convert to duplex form */ a.x = h->x - h->t; a.y = h->y + h->z; b.x = h->x + h->t; b.y = h->y - h->z; /* apply function to each part */ CMPLXtrig0(a,resulta); CMPLXtrig0(b,resultb); /* convert back */ out->x = (resulta.x + resultb.x)/2; out->y = (resulta.y + resultb.y)/2; out->z = (resulta.y - resultb.y)/2; out->t = (resultb.x - resulta.x)/2; } xfractint-20.4.10.orig/common/f16.c0000644000000000000000000000536511257714555013562 0ustar /************************************** ** ** F16.C : Code to read 16-bit fractal data sets. Uses ** strictly Targa16 type 10 files (run-length encoded 16-bit RGB). */ /* Lee Daniel Crocker CompuServe: 73407,2030 <== Preferred ** 1380 Jewett Ave. BIX: lcrocker ** Pittsburg, CA 94565 Usenet: ...!ames!pacbell!sactoh0!siva!lee ** ** This code is hereby placed in the public domain. You are free to ** use, modify, usurp, laugh at, destroy, or otherwise abuse it in any ** way you see fit. ** ** "If you steal from one author it's plagiarism; if you steal from ** many it's research." --Wilson Mizner */ /* 16 bit .tga files were generated for continuous potential "potfile"s from version 9.? thru version 14. Replaced by double row gif type file (.pot) in version 15. Delete this code after a few more revs. The part which wrote 16 bit .tga files has already been deleted. */ #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "targa_lc.h" #ifdef XFRACT char rlebuf[258]; /* RLE-state variables */ #endif static int state, count, bufp; /************************************** ** ** Open previously saved Targa16 type 10 file filling in hs, vs, and ** csize with values in the header. If *csize is not zero, the block ** pointed to by cp is filled with the comment block. The caller ** _must_ allocate 256 bytes for this purpose before calling. */ FILE *t16_open(char *fname, int *hs, int *vs, int *csize, U8 *cp) { char filename[64]; U8 header[HEADERSIZE]; FILE *fp; int dummy; /* to quiet compiler */ strcpy(filename, fname); if (has_ext(filename) == NULL) strcat(filename, ".TGA"); if ((fp = fopen(filename, READMODE)) == NULL) return NULL; dummy = fread(header, HEADERSIZE, 1, fp); if ((header[O_FILETYPE] != T_RLERGB) || (header[O_ESIZE] != 16)) { fclose(fp); return NULL; } GET16(header[O_HSIZE], *hs); GET16(header[O_VSIZE], *vs); if ((*csize = header[O_COMMENTLEN]) != 0) dummy = fread(cp, *csize, 1, fp); state = count = bufp = 0; return fp; } int t16_getline(FILE *fp, int hs, U16 *data) { int i; for (i=0; i 127) { state = 1; count -= 127; dummy = fread(rlebuf, 2, 1, fp); } else { state = 2; ++count; dummy = fread(rlebuf, 2, count, fp); } } GET16(rlebuf[bufp], data[i]); if (--count == 0) state = 0; if (state == 2) bufp += 2; } return 0; } xfractint-20.4.10.orig/common/ant.c0000644000000000000000000003235210150633601013723 0ustar /* The Ant Automaton is based on an article in Scientific American, July 1994. * The original Fractint implementation was by Tim Wegner in Fractint 19.0. * This routine is a major rewrite by Luciano Genero & Fulvio Cappelli using * tables for speed, and adds a second ant type, multiple ants, and random * rules. * * Revision history: * 20 Mar 95 LG/FC First release of table driven version * 31 Mar 95 LG/FC Fixed a bug that writes one pixel off the screen * 31 Mar 95 LG/FC Changed ant type 1 to produce the same pattern as the * original implementation (they were mirrored on the * x axis) * 04 Apr 95 TW Added wrap option and further modified the code to match * the original algorithm. It now matches exactly. * 10 Apr 95 TW Suffix array does not contain enough memory. Crashes at * over 1024x768. Changed to extraseg. * 12 Apr 95 TW Added maxants range check. */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #define RANDOM(n) ((int)((long)((long)rand() * (long)(n)) >> 15)) /* Generate Random * Number 0 <= r < n */ #define MAX_ANTS 256 #define XO (xdots/2) #define YO (ydots/2) #define DIRS 4 #define INNER_LOOP 100 /* possible value of idir e relative movement in the 4 directions * for x 0, 1, 0, -1 * for y 1, 0, -1, 0 */ static int far *incx[DIRS]; /* tab for 4 directions */ static int far *incy[DIRS]; void setwait(long *wait) { char msg[30]; int kbdchar; for (;;) { sprintf(msg, "Delay %4ld", *wait); while ((int)strlen(msg) < 15) strcat(msg, " "); msg[15] = '\0'; showtempmsg((char far *) msg); kbdchar = getakey(); switch (kbdchar) { case RIGHT_ARROW_2: case UP_ARROW_2: (*wait) += 100; break; case RIGHT_ARROW: case UP_ARROW: (*wait) += 10; break; case DOWN_ARROW_2: case LEFT_ARROW_2: (*wait) -= 100; break; case LEFT_ARROW: case DOWN_ARROW: (*wait) -= 10; break; default: cleartempmsg(); return; } if (*wait < 0) *wait = 0; } } /* turkmite from scientific american july 1994 pag 91 * Tweaked by Luciano Genero & Fulvio Cappelli */ void TurkMite1(int maxtur, int rule_len, char *ru, long maxpts, long wait) { int color, ix, iy, idir, pixel, i; int kbdchar, step, antwrap; int x[MAX_ANTS + 1], y[MAX_ANTS + 1]; int next_col[MAX_ANTS + 1], rule[MAX_ANTS + 1], dir[MAX_ANTS + 1]; long count; antwrap = ((param[4] == 0) ? 0 : 1); step = (int) wait; if (step == 1) wait = 0; else step = 0; if (rule_len == 0) { /* random rule */ for (color = 0; color < MAX_ANTS; color++) { /* init the rules and colors for the * turkmites: 1 turn left, -1 turn right */ rule[color] = 1 - (RANDOM(2) * 2); next_col[color] = color + 1; } /* close the cycle */ next_col[color] = 0; } else { /* user defined rule */ for (color = 0; color < rule_len; color++) { /* init the rules and colors for the * turkmites: 1 turn left, -1 turn right */ rule[color] = (ru[color] * 2) - 1; next_col[color] = color + 1; } /* repeats to last color */ for (color = rule_len; color < MAX_ANTS; color++) { /* init the rules and colors for the * turkmites: 1 turn left, -1 turn right */ rule[color] = rule[color % rule_len]; next_col[color] = color + 1; } /* close the cycle */ next_col[color] = 0; } for (color = maxtur; color; color--) { /* init the various turmites N.B. non usa * x[0], y[0], dir[0] */ if (rule_len) { dir[color] = 1; x[color] = XO; y[color] = YO; } else { dir[color] = RANDOM(DIRS); x[color] = RANDOM(xdots); y[color] = RANDOM(ydots); } } maxpts = maxpts / (long) INNER_LOOP; for (count = 0; count < maxpts; count++) { /* check for a key only every inner_loop times */ kbdchar = keypressed(); if (kbdchar || step) { int done = 0; if (kbdchar == 0) kbdchar = getakey(); switch (kbdchar) { case SPACE: step = 1 - step; break; case ESC: done = 1; break; case RIGHT_ARROW: case UP_ARROW: case DOWN_ARROW: case LEFT_ARROW: case RIGHT_ARROW_2: case UP_ARROW_2: case DOWN_ARROW_2: case LEFT_ARROW_2: setwait(&wait); break; default: done = 1; break; } if (done) goto exit_ant; if (keypressed()) getakey(); } for (i = INNER_LOOP; i; i--) { if (wait > 0 && step == 0) { for (color = maxtur; color; color--) { /* move the various turmites */ ix = x[color]; /* temp vars */ iy = y[color]; idir = dir[color]; pixel = getcolor(ix, iy); putcolor(ix, iy, 15); sleepms(wait); putcolor(ix, iy, next_col[pixel]); idir += rule[pixel]; idir &= 3; if (antwrap == 0) if ((idir == 0 && iy == ydots - 1) || (idir == 1 && ix == xdots - 1) || (idir == 2 && iy == 0) || (idir == 3 && ix == 0)) goto exit_ant; x[color] = incx[idir][ix]; y[color] = incy[idir][iy]; dir[color] = idir; } } else { for (color = maxtur; color; color--) { /* move the various turmites without delay */ ix = x[color]; /* temp vars */ iy = y[color]; idir = dir[color]; pixel = getcolor(ix, iy); putcolor(ix, iy, next_col[pixel]); idir += rule[pixel]; idir &= 3; if (antwrap == 0) if ((idir == 0 && iy == ydots - 1) || (idir == 1 && ix == xdots - 1) || (idir == 2 && iy == 0) || (idir == 3 && ix == 0)) goto exit_ant; x[color] = incx[idir][ix]; y[color] = incy[idir][iy]; dir[color] = idir; } } } } exit_ant: return; } /* this one ignore the color of the current cell is more like a white ant */ void TurkMite2(int maxtur, int rule_len, char *ru, long maxpts, long wait) { int color, ix, iy, idir, pixel, dir[MAX_ANTS + 1], i; int kbdchar, step, antwrap; int x[MAX_ANTS + 1], y[MAX_ANTS + 1]; int rule[MAX_ANTS + 1], rule_mask; long count; antwrap = ((param[4] == 0) ? 0 : 1); step = (int) wait; if (step == 1) wait = 0; else step = 0; if (rule_len == 0) { /* random rule */ for (color = MAX_ANTS - 1; color; color--) { /* init the various turmites N.B. don't use * x[0], y[0], dir[0] */ dir[color] = RANDOM(DIRS); rule[color] = (rand() << RANDOM(2)) | RANDOM(2); x[color] = RANDOM(xdots); y[color] = RANDOM(ydots); } } else { /* the same rule the user wants for every * turkmite (max rule_len = 16 bit) */ rule_len = min(rule_len, 8 * sizeof(int)); for (i = 0, rule[0] = 0; i < rule_len; i++) rule[0] = (rule[0] << 1) | ru[i]; for (color = MAX_ANTS - 1; color; color--) { /* init the various turmites N.B. non usa * x[0], y[0], dir[0] */ dir[color] = 0; rule[color] = rule[0]; x[color] = XO; y[color] = YO; } } /* use this rule when a black pixel is found */ rule[0] = 0; rule_mask = 1; maxpts = maxpts / (long) INNER_LOOP; for (count = 0; count < maxpts; count++) { /* check for a key only every inner_loop times */ kbdchar = keypressed(); if (kbdchar || step) { int done = 0; if (kbdchar == 0) kbdchar = getakey(); switch (kbdchar) { case SPACE: step = 1 - step; break; case ESC: done = 1; break; case RIGHT_ARROW: case UP_ARROW: case DOWN_ARROW: case LEFT_ARROW: case RIGHT_ARROW_2: case UP_ARROW_2: case DOWN_ARROW_2: case LEFT_ARROW_2: setwait(&wait); break; default: done = 1; break; } if (done) goto exit_ant; if (keypressed()) getakey(); } for (i = INNER_LOOP; i; i--) { for (color = maxtur; color; color--) { /* move the various turmites */ ix = x[color]; /* temp vars */ iy = y[color]; idir = dir[color]; pixel = getcolor(ix, iy); putcolor(ix, iy, 15); if (wait > 0 && step == 0) sleepms(wait); if (rule[pixel] & rule_mask) { /* turn right */ idir--; putcolor(ix, iy, 0); } else { /* turn left */ idir++; putcolor(ix, iy, color); } idir &= 3; if (antwrap == 0) if ((idir == 0 && iy == ydots - 1) || (idir == 1 && ix == xdots - 1) || (idir == 2 && iy == 0) || (idir == 3 && ix == 0)) goto exit_ant; x[color] = incx[idir][ix]; y[color] = incy[idir][iy]; dir[color] = idir; } rule_mask = _rotl(rule_mask, 1); } } exit_ant: return; } /* N.B. use the common memory in extraseg - suffix not large enough*/ int ant(void) { int maxants, type, i; int oldhelpmode, rule_len; long maxpts, wait; char rule[MAX_ANTS]; char far *extra; extra = MK_FP(extraseg,0); for (i = 0; i < DIRS; i++) { incx[i] = (int far *) (extra + (xdots + 2) * sizeof(int) * i); /* steal some memory */ incy[i] = (int far *) (extra + (xdots + 2) * sizeof(int) * DIRS + (ydots + 2) *sizeof(int) * i); /* steal some memory */ } /* In this vectors put all the possible point that the ants can visit. * Wrap them from a side to the other insted of simply end calculation */ for (i = 0; i < xdots; i++) { incx[0][i] = i; incx[2][i] = i; } for(i = 0; i < xdots; i++) incx[3][i] = i + 1; incx[3][xdots-1] = 0; /* wrap from right of the screen to left */ for(i = 1; i < xdots; i++) incx[1][i] = i - 1; incx[1][0] = xdots-1; /* wrap from left of the screen to right */ for (i = 0; i < ydots; i++) { incy[1][i] = i; incy[3][i] = i; } for (i = 0; i < ydots; i++) incy[0][i] = i + 1; incy[0][ydots - 1] = 0; /* wrap from the top of the screen to the * bottom */ for (i = 1; i < ydots; i++) incy[2][i] = i - 1; incy[2][0] = ydots - 1; /* wrap from the bottom of the screen to the * top */ oldhelpmode = helpmode; helpmode = ANTCOMMANDS; maxpts = (long) param[1]; maxpts = labs(maxpts); wait = abs(orbit_delay); sprintf(rule, "%.17g", param[0]); rule_len = strlen(rule); if (rule_len > 1) { /* if rule_len == 0 random rule */ for (i = 0; i < rule_len; i++) { if (rule[i] != '1') rule[i] = (char) 0; else rule[i] = (char) 1; } } else rule_len = 0; /* set random seed for reproducibility */ if ((!rflag) && param[5] == 1) --rseed; if (param[5] != 0 && param[5] != 1) rseed = (int)param[5]; srand(rseed); if (!rflag) ++rseed; maxants = (int) param[2]; if (maxants < 1) /* if maxants == 0 maxants random */ maxants = 2 + RANDOM(MAX_ANTS - 2); else if (maxants > MAX_ANTS) param[2] = maxants = MAX_ANTS; type = (int) param[3] - 1; if (type < 0 || type > 1) type = RANDOM(2); /* if type == 0 choose a random type */ switch (type) { case 0: TurkMite1(maxants, rule_len, rule, maxpts, wait); break; case 1: TurkMite2(maxants, rule_len, rule, maxpts, wait); break; } helpmode = oldhelpmode; return 0; } xfractint-20.4.10.orig/common/testpt.c0000644000000000000000000000354710150633601014470 0ustar /* Write your fractal program here. initreal and initimag are the values in the complex plane; parm1, and parm2 are paramaters to be entered with the "params=" option (if needed). The function should return the color associated with initreal and initimag. FRACTINT will repeatedly call your function with the values of initreal and initimag ranging over the rectangle defined by the "corners=" option. Assuming your formula is iterative, "maxit" is the maximum iteration. If "maxit" is hit, color "inside" should be returned. Note that this routine could be sped up using external variables/arrays rather than the current parameter-passing scheme. The goal, however was to make it as easy as possible to add fractal types, and this looked like the easiest way. This module is part of an overlay, with calcfrac.c. The routines in it must not be called by any part of Fractint other than calcfrac. The sample code below is a straightforward Mandelbrot routine. */ extern int getakey(void); int teststart() /* this routine is called just before the fractal starts */ { return( 0 ); } void testend() /* this routine is called just after the fractal ends */ { } /* this routine is called once for every pixel */ /* (note: possibly using the dual-pass / solif-guessing options */ int testpt(double initreal,double initimag,double parm1,double parm2, long maxit,int inside) { double oldreal, oldimag, newreal, newimag, magnitude; long color; oldreal=parm1; oldimag=parm2; magnitude = 0.0; color = 0; while ((magnitude < 4.0) && (color < maxit)) { newreal = oldreal * oldreal - oldimag * oldimag + initreal; newimag = 2 * oldreal * oldimag + initimag; color++; oldreal = newreal; oldimag = newimag; magnitude = newreal * newreal + newimag * newimag; } if (color >= maxit) color = inside; return((int)color); } xfractint-20.4.10.orig/common/soi.c0000644000000000000000000006320310150633601013732 0ustar /* * soi.c -- SOI * * Simultaneous Orbit Iteration Image Generation Method. Computes * rectangular regions by tracking the orbits of only a few key points. * * Copyright (c) 1994-1997 Michael R. Ganss. All Rights Reserved. * * This file is distributed under the same conditions as * AlmondBread. For further information see * . * */ #include #include #include #include "port.h" #include "prototyp.h" #define DBLS LDBL #define FABS(x) fabsl(x) /* the following needs to be changed back to frexpl once the portability issue has been addressed JCO */ #ifndef XFRACT #define FREXP(x,y) frexpl(x,y) #else #define FREXP(x,y) frexp(x,y) #endif #define TRUE 1 #define FALSE 0 #define EVERY 15 #define BASIN_COLOR 0 int rhombus_stack[10]; int rhombus_depth; int max_rhombus_depth; int minstackavail; /* int minstack=1700; */ /* need this much stack to recurse */ int minstack=2200; /* and this much stack to not crash when is pressed */ static DBLS twidth; static DBLS equal; static char baxinxx = FALSE; long iteration(register DBLS cr, register DBLS ci, register DBLS re, register DBLS im, long start) { register long iter,offset=0; int k,n; register DBLS ren,imn,sre,sim; #ifdef INTEL register float mag; register unsigned long bail=0x41800000,magi; /* bail=16.0 */ register unsigned long eq=*(unsigned long *)&equal; #else register DBLS mag; #endif DBLS d; int exponent; if(baxinxx) { sre=re; sim=im; ren=re*re; imn=im*im; if(start!=0) { offset=maxit-start+7; iter=offset>>3; offset&=7; offset=(8-offset); } else iter=maxit>>3; k=n=8; do { im=im*re; re=ren-imn; im+=im; re+=cr; im+=ci; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; #ifdef INTEL mag=FABS(sre-re); magi=*(unsigned long *)&mag; if(magi>3; offset&=7; offset=(8-offset); } else iter=maxit>>3; do { im=im*re; re=ren-imn; im+=im; re+=cr; im+=ci; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*re; ren=re+im; re=re-im; imn+=imn; re=ren*re; im=imn+ci; re+=cr; imn=im*im; ren=re*re; mag=ren+imn; #ifdef INTEL magi=*(unsigned long *)&mag; #endif } #ifdef INTEL while (magi>3])); } } static void puthline(int x1,int y1,int x2,int color) { int x; for(x=x1;x<=x2;x++) (*plot)(x,y1,color); } static void putbox(int x1, int y1, int x2, int y2, int color) { for(; y1<=y2; y1++) puthline(x1,y1,x2,color); } /* maximum side length beyond which we start regular scanning instead of subdividing */ #define SCAN 16 /* pixel interleave used in scanning */ #define INTERLEAVE 4 /* compute the value of the interpolation polynomial at (x,y) */ #define GET_REAL(x,y) \ interpolate(cim1,midi,cim2,\ interpolate(cre1,midr,cre2,zre1,zre5,zre2,x),\ interpolate(cre1,midr,cre2,zre6,zre9,zre7,x),\ interpolate(cre1,midr,cre2,zre3,zre8,zre4,x),y) #define GET_IMAG(x,y) \ interpolate(cre1,midr,cre2,\ interpolate(cim1,midi,cim2,zim1,zim6,zim3,y),\ interpolate(cim1,midi,cim2,zim5,zim9,zim8,y),\ interpolate(cim1,midi,cim2,zim2,zim7,zim4,y),x) /* compute the value of the interpolation polynomial at (x,y) from saved values before interpolation failed to stay within tolerance */ #define GET_SAVED_REAL(x,y) \ interpolate(cim1,midi,cim2,\ interpolate(cre1,midr,cre2,sr1,sr5,sr2,x),\ interpolate(cre1,midr,cre2,sr6,sr9,sr7,x),\ interpolate(cre1,midr,cre2,sr3,sr8,sr4,x),y) #define GET_SAVED_IMAG(x,y) \ interpolate(cre1,midr,cre2,\ interpolate(cim1,midi,cim2,si1,si6,si3,y),\ interpolate(cim1,midi,cim2,si5,si9,si8,y),\ interpolate(cim1,midi,cim2,si2,si7,si4,y),x) /* compute the value of the interpolation polynomial at (x,y) during scanning. Here, key values do not change, so we can precompute coefficients in one direction and simply evaluate the polynomial during scanning. */ #define GET_SCAN_REAL(x,y) \ interpolate(cim1,midi,cim2,\ EVALUATE(cre1,midr,br10,br11,br12,x),\ EVALUATE(cre1,midr,br20,br21,br22,x),\ EVALUATE(cre1,midr,br30,br31,br32,x),y) #define GET_SCAN_IMAG(x,y) \ interpolate(cre1,midr,cre2,\ EVALUATE(cim1,midi,bi10,bi11,bi12,y),\ EVALUATE(cim1,midi,bi20,bi21,bi22,y),\ EVALUATE(cim1,midi,bi30,bi31,bi32,y),x) /* compute coefficients of Newton polynomial (b0,..,b2) from (x0,w0),..,(x2,w2). */ #define INTERPOLATE(x0,x1,x2,w0,w1,w2,b0,b1,b2) \ b0=w0;\ b1=(w1-w0)/(LDBL)(x1-x0);\ b2=((w2-w1)/(LDBL)(x2-x1)-b1)/(x2-x0) /* evaluate Newton polynomial given by (x0,b0),(x1,b1) at x:=t */ #define EVALUATE(x0,x1,b0,b1,b2,t) \ ((b2*(t-x1)+b1)*(t-x0)+b0) /* Newton Interpolation. It computes the value of the interpolation polynomial given by (x0,w0)..(x2,w2) at x:=t */ static DBLS interpolate(DBLS x0, DBLS x1, DBLS x2, DBLS w0, DBLS w1, DBLS w2, DBLS t) { register DBLS b0=w0,b1=w1,b2=w2,b; /*b0=(r0*b1-r1*b0)/(x1-x0); b1=(r1*b2-r2*b1)/(x2-x1); b0=(r0*b1-r2*b0)/(x2-x0); return (DBLS)b0;*/ b=(b1-b0)/(x1-x0); return (DBLS)((((b2-b1)/(x2-x1)-b)/(x2-x0))*(t-x1)+b)*(t-x0)+b0; /* if(t= 700) #pragma code_seg ("soi2_text") /* place following in an overlay */ #endif /* SOICompute - Perform simultaneous orbit iteration for a given rectangle Input: cre1..cim2 : values defining the four corners of the rectangle x1..y2 : corresponding pixel values zre1..zim9 : intermediate iterated values of the key points (key values) (cre1,cim1) (cre2,cim1) (zre1,zim1) (zre5,zim5) (zre2,zim2) +------------+------------+ | | | | | | (zre6,zim6) (zre9,zim9) (zre7,zim7) | | | | | | +------------+------------+ (zre3,zim3) (zre8,zim8) (zre4,zim4) (cre1,cim2) (cre2,cim2) iter : current number of iterations */ static DBLS zre1, zim1, zre2, zim2, zre3, zim3, zre4, zim4, zre5, zim5, zre6, zim6, zre7, zim7, zre8, zim8, zre9, zim9; /* The purpose of this macro is to reduce the number of parameters of the function rhombus(), since this is a recursive function, and stack space under DOS is extremely limited. */ #define RHOMBUS(CRE1,CRE2,CIM1,CIM2,X1,X2,Y1,Y2,ZRE1,ZIM1,ZRE2,ZIM2,ZRE3,ZIM3,\ ZRE4, ZIM4, ZRE5, ZIM5,ZRE6, ZIM6, ZRE7, ZIM7, ZRE8, ZIM8, ZRE9, ZIM9,ITER) \ zre1=(ZRE1);zim1=(ZIM1);\ zre2=(ZRE2);zim2=(ZIM2);\ zre3=(ZRE3);zim3=(ZIM3);\ zre4=(ZRE4);zim4=(ZIM4);\ zre5=(ZRE5);zim5=(ZIM5);\ zre6=(ZRE6);zim6=(ZIM6);\ zre7=(ZRE7);zim7=(ZIM7);\ zre8=(ZRE8);zim8=(ZIM8);\ zre9=(ZRE9);zim9=(ZIM9);\ status=rhombus((CRE1),(CRE2),(CIM1),(CIM2),(X1),(X2),(Y1),(Y2),(ITER)) static int rhombus(DBLS cre1, DBLS cre2, DBLS cim1, DBLS cim2, int x1, int x2, int y1, int y2, long iter) { /* The following variables do not need their values saved */ /* used in scanning */ static long far savecolor, color, helpcolor; static int far x,y,z,savex; #if 0 static DBLS far re,im,restep,imstep,interstep,helpre; static DBLS far zre,zim; /* interpolation coefficients */ static DBLS far br10,br11,br12,br20,br21,br22,br30,br31,br32; static DBLS far bi10,bi11,bi12,bi20,bi21,bi22,bi30,bi31,bi32; /* ratio of interpolated test point to iterated one */ static DBLS far l1,l2; /* squares of key values */ static DBLS far rq1,iq1; static DBLS far rq2,iq2; static DBLS far rq3,iq3; static DBLS far rq4,iq4; static DBLS far rq5,iq5; static DBLS far rq6,iq6; static DBLS far rq7,iq7; static DBLS far rq8,iq8; static DBLS far rq9,iq9; /* test points */ static DBLS far cr1,cr2; static DBLS far ci1,ci2; static DBLS far tzr1,tzi1,tzr2,tzi2,tzr3,tzi3,tzr4,tzi4; static DBLS far trq1,tiq1,trq2,tiq2,trq3,tiq3,trq4,tiq4; #else #define re mem_static[ 0] #define im mem_static[ 1] #define restep mem_static[ 2] #define imstep mem_static[ 3] #define interstep mem_static[ 4] #define helpre mem_static[ 5] #define zre mem_static[ 6] #define zim mem_static[ 7] #define br10 mem_static[ 8] #define br11 mem_static[ 9] #define br12 mem_static[10] #define br20 mem_static[11] #define br21 mem_static[12] #define br22 mem_static[13] #define br30 mem_static[14] #define br31 mem_static[15] #define br32 mem_static[16] #define bi10 mem_static[17] #define bi11 mem_static[18] #define bi12 mem_static[19] #define bi20 mem_static[20] #define bi21 mem_static[21] #define bi22 mem_static[22] #define bi30 mem_static[23] #define bi31 mem_static[24] #define bi32 mem_static[25] #define l1 mem_static[26] #define l2 mem_static[27] #define rq1 mem_static[28] #define iq1 mem_static[29] #define rq2 mem_static[30] #define iq2 mem_static[31] #define rq3 mem_static[32] #define iq3 mem_static[33] #define rq4 mem_static[34] #define iq4 mem_static[35] #define rq5 mem_static[36] #define iq5 mem_static[37] #define rq6 mem_static[38] #define iq6 mem_static[39] #define rq7 mem_static[40] #define iq7 mem_static[41] #define rq8 mem_static[42] #define iq8 mem_static[43] #define rq9 mem_static[44] #define iq9 mem_static[45] #define cr1 mem_static[46] #define cr2 mem_static[47] #define ci1 mem_static[48] #define ci2 mem_static[49] #define tzr1 mem_static[50] #define tzi1 mem_static[51] #define tzr2 mem_static[52] #define tzi2 mem_static[53] #define tzr3 mem_static[54] #define tzi3 mem_static[55] #define tzr4 mem_static[56] #define tzi4 mem_static[57] #define trq1 mem_static[58] #define tiq1 mem_static[59] #define trq2 mem_static[60] #define tiq2 mem_static[61] #define trq3 mem_static[62] #define tiq3 mem_static[63] #define trq4 mem_static[64] #define tiq4 mem_static[65] #endif /* number of iterations before SOI iteration cycle */ static long far before; static int far avail; /* the variables below need to have local copis for recursive calls */ DBLS far *mem; DBLS far *mem_static; /* center of rectangle */ DBLS midr=(cre1+cre2)/2,midi=(cim1+cim2)/2; #if 0 /* saved values of key values */ DBLS sr1,si1,sr2,si2,sr3,si3,sr4,si4; DBLS sr5,si5,sr6,si6,sr7,si7,sr8,si8,sr9,si9; /* key values for subsequent rectangles */ DBLS re10,re11,re12,re13,re14,re15,re16,re17,re18,re19,re20,re21; DBLS im10,im11,im12,im13,im14,im15,im16,im17,im18,im19,im20,im21; DBLS re91,re92,re93,re94,im91,im92,im93,im94; #else #define sr1 mem[ 0] #define si1 mem[ 1] #define sr2 mem[ 2] #define si2 mem[ 3] #define sr3 mem[ 4] #define si3 mem[ 5] #define sr4 mem[ 6] #define si4 mem[ 7] #define sr5 mem[ 8] #define si5 mem[ 9] #define sr6 mem[10] #define si6 mem[11] #define sr7 mem[12] #define si7 mem[13] #define sr8 mem[14] #define si8 mem[15] #define sr9 mem[16] #define si9 mem[17] #define re10 mem[18] #define re11 mem[19] #define re12 mem[20] #define re13 mem[21] #define re14 mem[22] #define re15 mem[23] #define re16 mem[24] #define re17 mem[25] #define re18 mem[26] #define re19 mem[27] #define re20 mem[28] #define re21 mem[29] #define im10 mem[30] #define im11 mem[31] #define im12 mem[32] #define im13 mem[33] #define im14 mem[34] #define im15 mem[35] #define im16 mem[36] #define im17 mem[37] #define im18 mem[38] #define im19 mem[39] #define im20 mem[40] #define im21 mem[41] #define re91 mem[42] #define re92 mem[43] #define re93 mem[44] #define re94 mem[45] #define im91 mem[46] #define im92 mem[47] #define im93 mem[48] #define im94 mem[49] #endif int status = 0; rhombus_depth++; #if 1 /* what we go through under DOS to deal with memory! We re-use the sizeofstring array (8k). The first 660 bytes is for static variables, then we make our own "stack" with copies for each recursive call of rhombus() for the rest. */ mem_static = (DBLS far *)sizeofstring; mem = mem_static+ 66 + 50*rhombus_depth; #endif if((avail = stackavail()) < minstackavail) minstackavail = avail; if(rhombus_depth > max_rhombus_depth) max_rhombus_depth = rhombus_depth; rhombus_stack[rhombus_depth] = avail; if(keypressed()) { status = 1; goto rhombus_done; } if(iter>maxit) { putbox(x1,y1,x2,y2,0); status = 0; goto rhombus_done; } if((y2-y1<=SCAN) || (avail < minstack)) { /* finish up the image by scanning the rectangle */ scan: INTERPOLATE(cre1,midr,cre2,zre1,zre5,zre2,br10,br11,br12); INTERPOLATE(cre1,midr,cre2,zre6,zre9,zre7,br20,br21,br22); INTERPOLATE(cre1,midr,cre2,zre3,zre8,zre4,br30,br31,br32); INTERPOLATE(cim1,midi,cim2,zim1,zim6,zim3,bi10,bi11,bi12); INTERPOLATE(cim1,midi,cim2,zim5,zim9,zim8,bi20,bi21,bi22); INTERPOLATE(cim1,midi,cim2,zim2,zim7,zim4,bi30,bi31,bi32); restep=(cre2-cre1)/(x2-x1); imstep=(cim2-cim1)/(y2-y1); interstep=INTERLEAVE*restep; for(y=y1, im=cim1; yx-INTERLEAVE; z--,helpre-=restep) { zre=GET_SCAN_REAL(helpre,im); zim=GET_SCAN_IMAG(helpre,im); helpcolor=iteration(helpre,im,zre,zim,iter); if(helpcolor < 0) { status = 1; goto rhombus_done; } else if(helpcolor==savecolor) break; (*plot)(z,y,(int)(helpcolor&255)); } if(savexsavex; z--,helpre-=restep) { zre=GET_SCAN_REAL(helpre,im); zim=GET_SCAN_IMAG(helpre,im); helpcolor=iteration(helpre,im,zre,zim,iter); if(helpcolor < 0) { status = 1; goto rhombus_done; } else if(helpcolor==savecolor) break; (*plot)(z,y,(int)(helpcolor&255)); } if(savex16.0|| (rq2+iq2)>16.0|| (rq3+iq3)>16.0|| (rq4+iq4)>16.0|| (rq5+iq5)>16.0|| (rq6+iq6)>16.0|| (rq7+iq7)>16.0|| (rq8+iq8)>16.0|| (rq9+iq9)>16.0|| (trq1+tiq1)>16.0|| (trq2+tiq2)>16.0|| (trq3+tiq3)>16.0|| (trq4+tiq4)>16.0) break; /* if maximum number of iterations is reached, the whole rectangle can be assumed part of M. This is of course best case behavior of SOI, we seldomly get there */ if(iter>maxit) { putbox(x1,y1,x2,y2,0); status = 0; goto rhombus_done; } /* now for all test points, check whether they exceed the allowed tolerance. if so, subdivide */ l1=GET_REAL(cr1,ci1); l1=(tzr1==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr1; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr1,ci1); l2=(tzi1==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi1; if(FABS(1.0-l2)>twidth) break; l1=GET_REAL(cr2,ci1); l1=(tzr2==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr2; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr2,ci1); l2=(tzi2==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi2; if(FABS(1.0-l2)>twidth) break; l1=GET_REAL(cr1,ci2); l1=(tzr3==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr3; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr1,ci2); l2=(tzi3==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi3; if(FABS(1.0-l2)>twidth) break; l1=GET_REAL(cr2,ci2); l1=(tzr4==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr4; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr2,ci2); l2=(tzi4==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi4; if(FABS(1.0-l2)>twidth) break; } iter--; /* this is a little heuristic I tried to improve performance. */ if(iter-before<10) { zre1=sr1; zim1=si1; zre2=sr2; zim2=si2; zre3=sr3; zim3=si3; zre4=sr4; zim4=si4; zre5=sr5; zim5=si5; zre6=sr6; zim6=si6; zre7=sr7; zim7=si7; zre8=sr8; zim8=si8; zre9=sr9; zim9=si9; goto scan; } /* compute key values for subsequent rectangles */ re10=interpolate(cre1,midr,cre2,sr1,sr5,sr2,cr1); im10=interpolate(cre1,midr,cre2,si1,si5,si2,cr1); re11=interpolate(cre1,midr,cre2,sr1,sr5,sr2,cr2); im11=interpolate(cre1,midr,cre2,si1,si5,si2,cr2); re20=interpolate(cre1,midr,cre2,sr3,sr8,sr4,cr1); im20=interpolate(cre1,midr,cre2,si3,si8,si4,cr1); re21=interpolate(cre1,midr,cre2,sr3,sr8,sr4,cr2); im21=interpolate(cre1,midr,cre2,si3,si8,si4,cr2); re15=interpolate(cre1,midr,cre2,sr6,sr9,sr7,cr1); im15=interpolate(cre1,midr,cre2,si6,si9,si7,cr1); re16=interpolate(cre1,midr,cre2,sr6,sr9,sr7,cr2); im16=interpolate(cre1,midr,cre2,si6,si9,si7,cr2); re12=interpolate(cim1,midi,cim2,sr1,sr6,sr3,ci1); im12=interpolate(cim1,midi,cim2,si1,si6,si3,ci1); re14=interpolate(cim1,midi,cim2,sr2,sr7,sr4,ci1); im14=interpolate(cim1,midi,cim2,si2,si7,si4,ci1); re17=interpolate(cim1,midi,cim2,sr1,sr6,sr3,ci2); im17=interpolate(cim1,midi,cim2,si1,si6,si3,ci2); re19=interpolate(cim1,midi,cim2,sr2,sr7,sr4,ci2); im19=interpolate(cim1,midi,cim2,si2,si7,si4,ci2); re13=interpolate(cim1,midi,cim2,sr5,sr9,sr8,ci1); im13=interpolate(cim1,midi,cim2,si5,si9,si8,ci1); re18=interpolate(cim1,midi,cim2,sr5,sr9,sr8,ci2); im18=interpolate(cim1,midi,cim2,si5,si9,si8,ci2); re91=GET_SAVED_REAL(cr1,ci1); re92=GET_SAVED_REAL(cr2,ci1); re93=GET_SAVED_REAL(cr1,ci2); re94=GET_SAVED_REAL(cr2,ci2); im91=GET_SAVED_IMAG(cr1,ci1); im92=GET_SAVED_IMAG(cr2,ci1); im93=GET_SAVED_IMAG(cr1,ci2); im94=GET_SAVED_IMAG(cr2,ci2); RHOMBUS(cre1,midr,cim1,midi,x1,((x1+x2)>>1),y1,((y1+y2)>>1), sr1,si1, sr5,si5, sr6,si6, sr9,si9, re10,im10, re12,im12, re13,im13, re15,im15, re91,im91, iter); RHOMBUS(midr,cre2,cim1,midi,(x1+x2)>>1,x2,y1,(y1+y2)>>1, sr5,si5, sr2,si2, sr9,si9, sr7,si7, re11,im11, re13,im13, re14,im14, re16,im16, re92,im92, iter); RHOMBUS(cre1,midr,midi,cim2,x1,(x1+x2)>>1,(y1+y2)>>1,y2, sr6,si6, sr9,si9, sr3,si3, sr8,si8, re15,im15, re17,im17, re18,im18, re20,im20, re93,im93, iter); RHOMBUS(midr,cre2,midi,cim2,(x1+x2)>>1,x2,(y1+y2)>>1,y2, sr9,si9, sr7,si7, sr8,si8, sr4,si4, re16,im16, re18,im18, re19,im19, re21,im21, re94,im94, iter); rhombus_done: rhombus_depth--; return(status); } #if (_MSC_VER >= 700) #pragma code_seg () #endif void soi_ldbl(void) { int status; DBLS tolerance=0.1; DBLS stepx, stepy; DBLS xxminl, xxmaxl, yyminl, yymaxl; minstackavail = 30000; rhombus_depth = -1; max_rhombus_depth = 0; if(bf_math) { xxminl = bftofloat(bfxmin); yyminl = bftofloat(bfymin); xxmaxl = bftofloat(bfxmax); yymaxl = bftofloat(bfymax); } else { xxminl = xxmin; yyminl = yymin; xxmaxl = xxmax; yymaxl = yymax; } twidth=tolerance/(xdots-1); stepx = (xxmaxl - xxminl) / xdots; stepy = (yyminl - yymaxl) / ydots; equal = (stepx < stepy ? stepx : stepy); RHOMBUS(xxminl,xxmaxl,yymaxl,yyminl, 0,xdots,0,ydots, xxminl,yymaxl, xxmaxl,yymaxl, xxminl,yyminl, xxmaxl,yyminl, (xxmaxl+xxminl)/2,yymaxl, xxminl,(yymaxl+yyminl)/2, xxmaxl,(yymaxl+yyminl)/2, (xxmaxl+xxminl)/2,yyminl, (xxminl+xxmaxl)/2,(yymaxl+yyminl)/2, 1); } xfractint-20.4.10.orig/common/line3d.c0000644000000000000000000026746711253454200014341 0ustar /************************************************************************/ /* This file contains a 3D replacement for the out_line function called */ /* by the decoder. The purpose is to apply various 3D transformations */ /* before displaying points. Called once per line of the input file. */ /* */ /* Original Author Tim Wegner, with extensive help from Marc Reinig. */ /* July 1994 - TW broke out several pieces of code and added pragma */ /* to eliminate compiler warnings. Did a long-overdue */ /* formatting cleanup. */ /************************************************************************/ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" struct point { int x; int y; int color; }; struct f_point { float x; float y; float color; }; struct minmax { int minx; int maxx; }; /* routines in this module */ int line3d(BYTE *, unsigned); int _fastcall targa_color(int, int, int); int targa_validate(char *); static int first_time(int, VECTOR); static int H_R(BYTE *, BYTE *, BYTE *, unsigned long, unsigned long, unsigned long); static int line3dmem(void); static int R_H(BYTE, BYTE, BYTE, unsigned long *, unsigned long *, unsigned long *); static int set_pixel_buff(BYTE *, BYTE far *, unsigned); int startdisk1(char *, FILE *, int); static void set_upr_lwr(void); static int _fastcall end_object(int); static int _fastcall offscreen(struct point); static int _fastcall out_triangle(struct f_point, struct f_point, struct f_point, int, int, int); static int _fastcall RAY_Header(void); static int _fastcall start_object(void); static void corners(MATRIX, int, double *, double *, double *, double *, double *, double *); static void draw_light_box(double *, double *, MATRIX); static void draw_rect(VECTOR, VECTOR, VECTOR, VECTOR, int, int); static void File_Error(char *, int); static void line3d_cleanup(void); static void _fastcall clipcolor(int, int, int); static void _fastcall interpcolor(int, int, int); static void _fastcall putatriangle(struct point, struct point, struct point, int); static void _fastcall putminmax(int, int, int); static void _fastcall triangle_bounds(float pt_t[3][3]); static void _fastcall T_clipcolor(int, int, int); static void _fastcall vdraw_line(double *, double *, int color); static void (_fastcall * fillplot) (int, int, int); static void (_fastcall * normalplot) (int, int, int); /* static variables */ static float deltaphi; /* increment of latitude, longitude */ static double rscale; /* surface roughness factor */ static long xcenter, ycenter; /* circle center */ static double sclx, scly, sclz; /* scale factors */ static double R; /* radius values */ static double Rfactor; /* for intermediate calculation */ static LMATRIX llm; /* "" */ static LVECTOR lview; /* for perspective views */ static double zcutoff; /* perspective backside cutoff value */ static float twocosdeltaphi; static float cosphi, sinphi; /* precalculated sin/cos of longitude */ static float oldcosphi1, oldsinphi1; static float oldcosphi2, oldsinphi2; static BYTE far *fraction; /* float version of pixels array */ static float min_xyz[3], max_xyz[3]; /* For Raytrace output */ static int line_length1; static int T_header_24 = 18;/* Size of current Targa-24 header */ static FILE *File_Ptr1 = NULL; static unsigned int IAmbient; static int rand_factor; static int HAZE_MULT; static void File_Error(char *File_Name1, int ERROR); static BYTE T24 = 24; static BYTE T32 = 32; static BYTE upr_lwr[4]; static int T_Safe; /* Original Targa Image successfully copied to targa_temp */ static VECTOR light_direction; static BYTE Real_Color; /* Actual color of cur pixel */ static int RO, CO, CO_MAX; /* For use in Acrospin support */ static FCODE acro_s1[] = {"Set Layer 1\nSet Color 2\nEndpointList X Y Z Name\n"}; static FCODE acro_s2[] = {"LineList From To\n"}; static FCODE s3[] = {"{ Created by FRACTINT Ver. "}; static FCODE s3a[] = {" }\n\n"}; #ifndef XFRACT static char banner[] = "%Fs%#4.2f%Fs"; #else static char banner[] = "%s%#4.2f%s"; #endif static int localpreviewfactor; static int zcoord = 256; static double aspect; /* aspect ratio */ static int evenoddrow; static float far *sinthetaarray; /* all sine thetas go here */ static float far *costhetaarray; /* all cosine thetas go here */ static double rXrscale; /* precalculation factor */ static int persp; /* flag for indicating perspective transformations */ static struct point p1, p2, p3; static struct f_point f_bad;/* out of range value */ static struct point bad; /* out of range value */ static long num_tris; /* number of triangles output to ray trace file */ /* global variables defined here */ struct f_point far *f_lastrow; void (_fastcall * standardplot) (int, int, int); MATRIX m; /* transformation matrix */ int Ambient; int RANDOMIZE; int haze; int Real_V = 0; /* mrr Actual value of V for fillytpe>4 monochrome images */ char light_name[FILE_MAX_PATH] = "fract001"; int Targa_Overlay, error; char targa_temp[MAX_NAME] = "fractemp.tga"; int P = 250; /* Perspective dist used when viewing light vector */ BYTE back_color[3]; char ray_name[FILE_MAX_PATH] = "fract001"; char preview = 0; char showbox = 0; int previewfactor = 20; int xadjust = 0; int yadjust = 0; int xxadjust; int yyadjust; int xshift; int yshift; int bad_value = -10000; /* set bad values to this */ int bad_check = -3000; /* check values against this to determine if good */ struct point far *lastrow; /* this array remembers the previous line */ int RAY = 0; /* Flag to generate Ray trace compatible files in 3d */ int BRIEF = 0; /* 1 = short ray trace files */ /* array of min and max x values used in triangle fill */ struct minmax far *minmax_x; VECTOR view; /* position of observer for perspective */ VECTOR cross; VECTOR tmpcross; struct point oldlast = { 0, 0, 0 }; /* old pixels */ int line3d(BYTE * pixels, unsigned linelen) { int tout; /* triangle has been sent to ray trace file */ int RND; float f_water = (float)0.0; /* transformed WATERLINE for ray trace files */ double r0; int xcenter0 = 0; int ycenter0 = 0; /* Unfudged versions */ double r; /* sphere radius */ float costheta, sintheta; /* precalculated sin/cos of latitude */ int next; /* used by preview and grid */ int col; /* current column (original GIF) */ struct point cur; /* current pixels */ struct point old; /* old pixels */ struct f_point f_cur; struct f_point f_old; VECTOR v; /* double vector */ VECTOR v1, v2; VECTOR crossavg; char crossnotinit; /* flag for crossavg init indication */ LVECTOR lv; /* long equivalent of v */ LVECTOR lv0; /* long equivalent of v */ int lastdot; long fudge; fudge = 1L << 16; if (transparent[0] || transparent[1]) plot = normalplot = T_clipcolor; /* Use transparent plot function */ else /* Use the usual FRACTINT plot function with * clipping */ plot = normalplot = clipcolor; currow = rowcount; /* use separate variable to allow for * pot16bit files */ if (pot16bit) currow >>= 1; /************************************************************************/ /* This IF clause is executed ONCE per image. All precalculations are */ /* done here, with out any special concern about speed. DANGER - */ /* communication with the rest of the program is generally via static */ /* or global variables. */ /************************************************************************/ if (rowcount++ == 0) { int err; if ((err = first_time(linelen, v)) != 0) return (err); if(xdots > OLDMAXPIXELS) return(-1); tout = 0; crossavg[0] = 0; crossavg[1] = 0; crossavg[2] = 0; xcenter0 = (int) (xcenter = xdots / 2 + xshift); ycenter0 = (int) (ycenter = ydots / 2 - yshift); } /* make sure these pixel coordinates are out of range */ old = bad; f_old = f_bad; /* copies pixels buffer to float type fraction buffer for fill purposes */ if (pot16bit) { if (set_pixel_buff(pixels, fraction, linelen)) return (0); } else if (grayflag) /* convert color numbers to grayscale values */ for (col = 0; col < (int) linelen; col++) { int pal, colornum; colornum = pixels[col]; /* effectively (30*R + 59*G + 11*B)/100 scaled 0 to 255 */ pal = ((int) dacbox[colornum][0] * 77 + (int) dacbox[colornum][1] * 151 + (int) dacbox[colornum][2] * 28); pal >>= 6; pixels[col] = (BYTE) pal; } crossnotinit = 1; col = 0; CO = 0; /*************************************************************************/ /* This section of code allows the operation of a preview mode when the */ /* preview flag is set. Enabled, it allows the drawing of only the first */ /* line of the source image, then every 10th line, until and including */ /* the last line. For the undrawn lines, only necessary calculations are */ /* made. As a bonus, in non-sphere mode a box is drawn to help visualize */ /* the effects of 3D transformations. Thanks to Marc Reinig for this idea*/ /* and code -- BTW, Marc did NOT put the goto in, but WE did, to avoid */ /* copying code here, and to avoid a HUGE "if-then" construct. Besides, */ /* we have ALREADY sinned, so why not sin some more? */ /*************************************************************************/ lastdot = min(xdots - 1, (int) linelen - 1); if (FILLTYPE >= 5) if (haze && Targa_Out) { HAZE_MULT = (int) (haze * ( (float) ((long) (ydots - 1 - currow) * (long) (ydots - 1 - currow)) / (float) ((long) (ydots - 1) * (long) (ydots - 1)))); HAZE_MULT = 100 - HAZE_MULT; } if (previewfactor >= ydots || previewfactor > lastdot) previewfactor = min(ydots - 1, lastdot); localpreviewfactor = ydots / previewfactor; tout = 0; /* Insure last line is drawn in preview and filltypes <0 */ if ((RAY || preview || FILLTYPE < 0) && (currow != ydots - 1) && (currow % localpreviewfactor) && /* Draw mod preview lines */ !(!RAY && (FILLTYPE > 4) && (currow == 1))) /* Get init geometry in lightsource modes */ goto reallythebottom; /* skip over most of the line3d calcs */ if (dotmode == 11) { static FCODE mapping[] = {"mapping to 3d, reading line "}; char s[40]; #ifndef XFRACT sprintf(s, "%Fs%d", (char far *)mapping, currow); #else sprintf(s, "%s%d", mapping, currow); #endif dvid_status(1, s); } if (!col && RAY && currow != 0) start_object(); /* PROCESS ROW LOOP BEGINS HERE */ while (col < (int) linelen) { if ((RAY || preview || FILLTYPE < 0) && (col != lastdot) &&/* if this is not the last col */ /* if not the 1st or mod factor col */ (col % (int) (aspect * localpreviewfactor)) && (!(!RAY && FILLTYPE > 4 && col == 1))) goto loopbottom; f_cur.color = cur.color = Real_Color = pixels[col]; if (RAY || preview || FILLTYPE < 0) { next = (int) (col + aspect * localpreviewfactor); if (next == col) next = col + 1; } else next = col + 1; if (next >= lastdot) next = lastdot; if (cur.color > 0 && cur.color < WATERLINE) f_cur.color = cur.color = Real_Color = (BYTE)WATERLINE; /* "lake" */ else if (pot16bit) f_cur.color += ((float) fraction[col]) / (float) (1 << 8); if (SPHERE) /* sphere case */ { sintheta = sinthetaarray[col]; costheta = costhetaarray[col]; if (sinphi < 0 && !(RAY || FILLTYPE < 0)) { cur = bad; f_cur = f_bad; goto loopbottom; /* another goto ! */ } /************************************************************/ /* KEEP THIS FOR DOCS - original formula -- */ /* if(rscale < 0.0) */ /* r = 1.0+((double)cur.color/(double)zcoord)*rscale; */ /* else */ /* r = 1.0-rscale+((double)cur.color/(double)zcoord)*rscale;*/ /* R = (double)ydots/2; */ /* r = r*R; */ /* cur.x = xdots/2 + sclx*r*sintheta*aspect + xup ; */ /* cur.y = ydots/2 + scly*r*costheta*cosphi - yup ; */ /************************************************************/ if (rscale < 0.0) r = R + Rfactor * (double) f_cur.color * costheta; else if (rscale > 0.0) r = R - rXrscale + Rfactor * (double) f_cur.color * costheta; else r = R; /* Allow Ray trace to go through so display ok */ if (persp || RAY) { /* mrr how do lv[] and cur and f_cur all relate */ /* NOTE: fudge was pre-calculated above in r and R */ /* (almost) guarantee negative */ lv[2] = (long) (-R - r * costheta * sinphi); /* z */ if ((lv[2] > zcutoff) && !FILLTYPE < 0) { cur = bad; f_cur = f_bad; goto loopbottom; /* another goto ! */ } lv[0] = (long) (xcenter + sintheta * sclx * r); /* x */ lv[1] = (long) (ycenter + costheta * cosphi * scly * r); /* y */ if ((FILLTYPE >= 5) || RAY) { /* calculate illumination normal before persp */ r0 = r / 65536L; f_cur.x = (float) (xcenter0 + sintheta * sclx * r0); f_cur.y = (float) (ycenter0 + costheta * cosphi * scly * r0); f_cur.color = (float) (-r0 * costheta * sinphi); } if (!(usr_floatflag || RAY)) { if (longpersp(lv, lview, 16) == -1) { cur = bad; f_cur = f_bad; goto loopbottom; /* another goto ! */ } cur.x = (int) (((lv[0] + 32768L) >> 16) + xxadjust); cur.y = (int) (((lv[1] + 32768L) >> 16) + yyadjust); } if (usr_floatflag || overflow || RAY) { v[0] = lv[0]; v[1] = lv[1]; v[2] = lv[2]; v[0] /= fudge; v[1] /= fudge; v[2] /= fudge; perspective(v); cur.x = (int) (v[0] + .5 + xxadjust); cur.y = (int) (v[1] + .5 + yyadjust); } } /* mrr Not sure how this an 3rd if above relate */ else if (!(persp && RAY)) { /* mrr Why the xx- and yyadjust here and not above? */ cur.x = (int) (f_cur.x = (float) (xcenter + sintheta * sclx * r + xxadjust)); cur.y = (int) (f_cur.y = (float) (ycenter + costheta * cosphi * scly * r + yyadjust)); if (FILLTYPE >= 5 || RAY) /* mrr why do we do this for * filltype>5? */ f_cur.color = (float) (-r * costheta * sinphi * sclz); v[0] = v[1] = v[2] = 0; /* MRR Why do we do this? */ } } else /* non-sphere 3D */ { if (!usr_floatflag && !RAY) { if (FILLTYPE >= 5) /* flag to save vector before * perspective */ lv0[0] = 1; /* in longvmultpersp calculation */ else lv0[0] = 0; /* use 32-bit multiply math to snap this out */ lv[0] = col; lv[0] = lv[0] << 16; lv[1] = currow; lv[1] = lv[1] << 16; if (filetype || pot16bit) /* don't truncate fractional * part */ lv[2] = (long) (f_cur.color * 65536.0); else /* there IS no fractaional part here! */ { lv[2] = (long) f_cur.color; lv[2] = lv[2] << 16; } if (longvmultpersp(lv, llm, lv0, lv, lview, 16) == -1) { cur = bad; f_cur = f_bad; goto loopbottom; } cur.x = (int) (((lv[0] + 32768L) >> 16) + xxadjust); cur.y = (int) (((lv[1] + 32768L) >> 16) + yyadjust); if (FILLTYPE >= 5 && !overflow) { f_cur.x = (float) lv0[0]; f_cur.x /= (float)65536.0; f_cur.y = (float) lv0[1]; f_cur.y /= (float)65536.0; f_cur.color = (float) lv0[2]; f_cur.color /= (float)65536.0; } } if (usr_floatflag || overflow || RAY) /* do in float if integer math overflowed or doing Ray trace */ { /* slow float version for comparison */ v[0] = col; v[1] = currow; v[2] = f_cur.color; /* Actually the z value */ mult_vec(v); /* matrix*vector routine */ if (FILLTYPE > 4 || RAY) { f_cur.x = (float) v[0]; f_cur.y = (float) v[1]; f_cur.color = (float) v[2]; if (RAY == 6) { f_cur.x = f_cur.x * ((float)2.0 / xdots) - (float)1.0; f_cur.y = f_cur.y * ((float)2.0 / ydots) - (float)1.0; f_cur.color = -f_cur.color * ((float)2.0 / numcolors) - (float)1.0; } } if (persp && !RAY) perspective(v); cur.x = (int) (v[0] + xxadjust + .5); cur.y = (int) (v[1] + yyadjust + .5); v[0] = 0; v[1] = 0; v[2] = WATERLINE; mult_vec(v); f_water = (float) v[2]; } } if (RANDOMIZE) if (cur.color > WATERLINE) { RND = rand15() >> 8; /* 7-bit number */ RND = RND * RND >> rand_factor; /* n-bit number */ if (rand() & 1) RND = -RND; /* Make +/- n-bit number */ if ((int) (cur.color) + RND >= colors) cur.color = colors - 2; else if ((int) (cur.color) + RND <= WATERLINE) cur.color = WATERLINE + 1; else cur.color = cur.color + RND; Real_Color = (BYTE)cur.color; } if (RAY) { if (col && currow && old.x > bad_check && old.x < (xdots - bad_check) && lastrow[col].x > bad_check && lastrow[col].y > bad_check && lastrow[col].x < (xdots - bad_check) && lastrow[col].y < (ydots - bad_check)) { /* Get rid of all the triangles in the plane at the base of * the object */ if (f_cur.color == f_water && f_lastrow[col].color == f_water && f_lastrow[next].color == f_water) goto loopbottom; if (RAY != 6) /* Output the vertex info */ out_triangle(f_cur, f_old, f_lastrow[col], cur.color, old.color, lastrow[col].color); tout = 1; draw_line(old.x, old.y, cur.x, cur.y, old.color); draw_line(old.x, old.y, lastrow[col].x, lastrow[col].y, old.color); draw_line(lastrow[col].x, lastrow[col].y, cur.x, cur.y, cur.color); num_tris++; } if (col < lastdot && currow && lastrow[col].x > bad_check && lastrow[col].y > bad_check && lastrow[col].x < (xdots - bad_check) && lastrow[col].y < (ydots - bad_check) && lastrow[next].x > bad_check && lastrow[next].y > bad_check && lastrow[next].x < (xdots - bad_check) && lastrow[next].y < (ydots - bad_check)) { /* Get rid of all the triangles in the plane at the base of * the object */ if (f_cur.color == f_water && f_lastrow[col].color == f_water && f_lastrow[next].color == f_water) goto loopbottom; if (RAY != 6) /* Output the vertex info */ out_triangle(f_cur, f_lastrow[col], f_lastrow[next], cur.color, lastrow[col].color, lastrow[next].color); tout = 1; draw_line(lastrow[col].x, lastrow[col].y, cur.x, cur.y, cur.color); draw_line(lastrow[next].x, lastrow[next].y, cur.x, cur.y, cur.color); draw_line(lastrow[next].x, lastrow[next].y, lastrow[col].x, lastrow[col].y, lastrow[col].color); num_tris++; } if (RAY == 6) /* Output vertex info for Acrospin */ { fprintf(File_Ptr1, "% #4.4f % #4.4f % #4.4f R%dC%d\n", f_cur.x, f_cur.y, f_cur.color, RO, CO); if (CO > CO_MAX) CO_MAX = CO; CO++; } goto loopbottom; } switch (FILLTYPE) { case -1: if (col && old.x > bad_check && old.x < (xdots - bad_check)) draw_line(old.x, old.y, cur.x, cur.y, cur.color); if (currow && lastrow[col].x > bad_check && lastrow[col].y > bad_check && lastrow[col].x < (xdots - bad_check) && lastrow[col].y < (ydots - bad_check)) draw_line(lastrow[col].x, lastrow[col].y, cur.x, cur.y, cur.color); break; case 0: (*plot) (cur.x, cur.y, cur.color); break; case 1: /* connect-a-dot */ if ((old.x < xdots) && (col) && old.x > bad_check && old.y > bad_check) /* Don't draw from old to cur on col * 0 */ draw_line(old.x, old.y, cur.x, cur.y, cur.color); break; case 2: /* with interpolation */ case 3: /* no interpolation */ /*************************************************************/ /* "triangle fill" - consider four points: current point, */ /* previous point same row, point opposite current point in */ /* previous row, point after current point in previous row. */ /* The object is to fill all points inside the two triangles.*/ /* */ /* lastrow[col].x/y___ lastrow[next] */ /* / 1 / */ /* / 1 / */ /* / 1 / */ /* oldrow/col ________ trow/col */ /*************************************************************/ if (currow && !col) putatriangle(lastrow[next], lastrow[col], cur, cur.color); if (currow && col) /* skip first row and first column */ { if (col == 1) putatriangle(lastrow[col], oldlast, old, old.color); if (col < lastdot) putatriangle(lastrow[next], lastrow[col], cur, cur.color); putatriangle(old, lastrow[col], cur, cur.color); } break; case 4: /* "solid fill" */ if (SPHERE) { if (persp) { old.x = (int) (xcenter >> 16); old.y = (int) (ycenter >> 16); } else { old.x = (int) xcenter; old.y = (int) ycenter; } } else { lv[0] = col; lv[1] = currow; lv[2] = 0; /* apply fudge bit shift for integer math */ lv[0] = lv[0] << 16; lv[1] = lv[1] << 16; /* Since 0, unnecessary lv[2] = lv[2] << 16; */ if (longvmultpersp(lv, llm, lv0, lv, lview, 16)) { cur = bad; f_cur = f_bad; goto loopbottom; /* another goto ! */ } /* Round and fudge back to original */ old.x = (int) ((lv[0] + 32768L) >> 16); old.y = (int) ((lv[1] + 32768L) >> 16); } if (old.x < 0) old.x = 0; if (old.x >= xdots) old.x = xdots - 1; if (old.y < 0) old.y = 0; if (old.y >= ydots) old.y = ydots - 1; draw_line(old.x, old.y, cur.x, cur.y, cur.color); break; case 5: case 6: /* light-source modulated fill */ if (currow && col) /* skip first row and first column */ { if (f_cur.color < bad_check || f_old.color < bad_check || f_lastrow[col].color < bad_check) break; v1[0] = f_cur.x - f_old.x; v1[1] = f_cur.y - f_old.y; v1[2] = f_cur.color - f_old.color; v2[0] = f_lastrow[col].x - f_cur.x; v2[1] = f_lastrow[col].y - f_cur.y; v2[2] = f_lastrow[col].color - f_cur.color; cross_product(v1, v2, cross); /* normalize cross - and check if non-zero */ if (normalize_vector(cross)) { if (debugflag) { static FCODE msg[] = {"debug, cur.color=bad"}; stopmsg(0, msg); } cur.color = (int)(f_cur.color = bad.color); } else { /* line-wise averaging scheme */ if (LIGHTAVG > 0) { if (crossnotinit) { /* initialize array of old normal vectors */ crossavg[0] = cross[0]; crossavg[1] = cross[1]; crossavg[2] = cross[2]; crossnotinit = 0; } tmpcross[0] = (crossavg[0] * LIGHTAVG + cross[0]) / (LIGHTAVG + 1); tmpcross[1] = (crossavg[1] * LIGHTAVG + cross[1]) / (LIGHTAVG + 1); tmpcross[2] = (crossavg[2] * LIGHTAVG + cross[2]) / (LIGHTAVG + 1); cross[0] = tmpcross[0]; cross[1] = tmpcross[1]; cross[2] = tmpcross[2]; if (normalize_vector(cross)) { /* this shouldn't happen */ if (debugflag) { static FCODE msg[] = {"debug, normal vector err2"}; stopmsg(0, msg); /* use next instead if you ever need details: * static char far tmp[] = {"debug, vector err"}; * char msg[200]; #ifndef XFRACT * sprintf(msg,"%Fs\n%f %f %f\n%f %f %f\n%f %f * %f", #else sprintf(msg,"%s\n%f %f %f\n%f %f * %f\n%f %f %f", #endif tmp, f_cur.x, f_cur.y, * f_cur.color, f_lastrow[col].x, * f_lastrow[col].y, f_lastrow[col].color, * f_lastrow[col-1].x, * f_lastrow[col-1].y,f_lastrow[col-1].color); * stopmsg(0,msg); */ } cur.color = (int)(f_cur.color = colors); } } crossavg[0] = tmpcross[0]; crossavg[1] = tmpcross[1]; crossavg[2] = tmpcross[2]; /* dot product of unit vectors is cos of angle between */ /* we will use this value to shade surface */ cur.color = (int) (1 + (colors - 2) * (1.0 - dot_product(cross, light_direction))); } /* if colors out of range, set them to min or max color index * but avoid background index. This makes colors "opaque" so * SOMETHING plots. These conditions shouldn't happen but just * in case */ if (cur.color < 1) /* prevent transparent colors */ cur.color = 1;/* avoid background */ if (cur.color > colors - 1) cur.color = colors - 1; /* why "col < 2"? So we have sufficient geometry for the fill */ /* algorithm, which needs previous point in same row to have */ /* already been calculated (variable old) */ /* fix ragged left margin in preview */ if (col == 1 && currow > 1) putatriangle(lastrow[next], lastrow[col], cur, cur.color); if (col < 2 || currow < 2) /* don't have valid colors * yet */ break; if (col < lastdot) putatriangle(lastrow[next], lastrow[col], cur, cur.color); putatriangle(old, lastrow[col], cur, cur.color); plot = standardplot; } break; } /* End of CASE statement for fill type */ loopbottom: if (RAY || (FILLTYPE != 0 && FILLTYPE != 4)) { /* for triangle and grid fill purposes */ oldlast = lastrow[col]; old = lastrow[col] = cur; /* for illumination model purposes */ f_old = f_lastrow[col] = f_cur; if (currow && RAY && col >= lastdot) /* if we're at the end of a row, close the object */ { end_object(tout); tout = 0; if (ferror(File_Ptr1)) { fclose(File_Ptr1); remove(light_name); File_Error(ray_name, 2); return (-1); } } } col++; } /* End of while statement for plotting line */ RO++; reallythebottom: /* stuff that HAS to be done, even in preview mode, goes here */ if (SPHERE) { /* incremental sin/cos phi calc */ if (currow == 0) { sinphi = oldsinphi2; cosphi = oldcosphi2; } else { sinphi = twocosdeltaphi * oldsinphi2 - oldsinphi1; cosphi = twocosdeltaphi * oldcosphi2 - oldcosphi1; oldsinphi1 = oldsinphi2; oldsinphi2 = sinphi; oldcosphi1 = oldcosphi2; oldcosphi2 = cosphi; } } return (0); /* decoder needs to know all is well !!! */ } /* vector version of line draw */ static void _fastcall vdraw_line(double *v1, double *v2, int color) { int x1, y1, x2, y2; x1 = (int) v1[0]; y1 = (int) v1[1]; x2 = (int) v2[0]; y2 = (int) v2[1]; draw_line(x1, y1, x2, y2, color); } static void corners(MATRIX m, int show, double *pxmin, double *pymin, double *pzmin, double *pxmax, double *pymax, double *pzmax) { int i, j; VECTOR S[2][4]; /* Holds the top an bottom points, * S[0][]=bottom */ /* define corners of box fractal is in in x,y,z plane "b" stands for * "bottom" - these points are the corners of the screen in the x-y plane. * The "t"'s stand for Top - they are the top of the cube where 255 color * points hit. */ *pxmin = *pymin = *pzmin = (int) INT_MAX; *pxmax = *pymax = *pzmax = (int) INT_MIN; for (j = 0; j < 4; ++j) for (i = 0; i < 3; i++) S[0][j][i] = S[1][j][i] = 0; S[0][1][0] = S[0][2][0] = S[1][1][0] = S[1][2][0] = xdots - 1; S[0][2][1] = S[0][3][1] = S[1][2][1] = S[1][3][1] = ydots - 1; S[1][0][2] = S[1][1][2] = S[1][2][2] = S[1][3][2] = zcoord - 1; for (i = 0; i < 4; ++i) { /* transform points */ vmult(S[0][i], m, S[0][i]); vmult(S[1][i], m, S[1][i]); /* update minimums and maximums */ if (S[0][i][0] <= *pxmin) *pxmin = S[0][i][0]; if (S[0][i][0] >= *pxmax) *pxmax = S[0][i][0]; if (S[1][i][0] <= *pxmin) *pxmin = S[1][i][0]; if (S[1][i][0] >= *pxmax) *pxmax = S[1][i][0]; if (S[0][i][1] <= *pymin) *pymin = S[0][i][1]; if (S[0][i][1] >= *pymax) *pymax = S[0][i][1]; if (S[1][i][1] <= *pymin) *pymin = S[1][i][1]; if (S[1][i][1] >= *pymax) *pymax = S[1][i][1]; if (S[0][i][2] <= *pzmin) *pzmin = S[0][i][2]; if (S[0][i][2] >= *pzmax) *pzmax = S[0][i][2]; if (S[1][i][2] <= *pzmin) *pzmin = S[1][i][2]; if (S[1][i][2] >= *pzmax) *pzmax = S[1][i][2]; } if (show) { if (persp) { for (i = 0; i < 4; i++) { perspective(S[0][i]); perspective(S[1][i]); } } /* Keep the box surrounding the fractal */ for (j = 0; j < 2; j++) for (i = 0; i < 4; ++i) { S[j][i][0] += xxadjust; S[j][i][1] += yyadjust; } draw_rect(S[0][0], S[0][1], S[0][2], S[0][3], 2, 1); /* Bottom */ draw_rect(S[0][0], S[1][0], S[0][1], S[1][1], 5, 0); /* Sides */ draw_rect(S[0][2], S[1][2], S[0][3], S[1][3], 6, 0); draw_rect(S[1][0], S[1][1], S[1][2], S[1][3], 8, 1); /* Top */ } } /* This function draws a vector from origin[] to direct[] and a box around it. The vector and box are transformed or not depending on FILLTYPE. */ static void draw_light_box(double *origin, double *direct, MATRIX light_m) { VECTOR S[2][4]; int i, j; double temp; S[1][0][0] = S[0][0][0] = origin[0]; S[1][0][1] = S[0][0][1] = origin[1]; S[1][0][2] = direct[2]; for (i = 0; i < 2; i++) { S[i][1][0] = S[i][0][0]; S[i][1][1] = direct[1]; S[i][1][2] = S[i][0][2]; S[i][2][0] = direct[0]; S[i][2][1] = S[i][1][1]; S[i][2][2] = S[i][0][2]; S[i][3][0] = S[i][2][0]; S[i][3][1] = S[i][0][1]; S[i][3][2] = S[i][0][2]; } /* transform the corners if necessary */ if (FILLTYPE == 6) for (i = 0; i < 4; i++) { vmult(S[0][i], light_m, S[0][i]); vmult(S[1][i], light_m, S[1][i]); } /* always use perspective to aid viewing */ temp = view[2]; /* save perspective distance for a later * restore */ view[2] = -P * 300.0 / 100.0; for (i = 0; i < 4; i++) { perspective(S[0][i]); perspective(S[1][i]); } view[2] = temp; /* Restore perspective distance */ /* Adjust for aspect */ for (i = 0; i < 4; i++) { S[0][i][0] = S[0][i][0] * aspect; S[1][i][0] = S[1][i][0] * aspect; } /* draw box connecting transformed points. NOTE order and COLORS */ draw_rect(S[0][0], S[0][1], S[0][2], S[0][3], 2, 1); vdraw_line(S[0][0], S[1][2], 8); /* sides */ draw_rect(S[0][0], S[1][0], S[0][1], S[1][1], 4, 0); draw_rect(S[0][2], S[1][2], S[0][3], S[1][3], 5, 0); draw_rect(S[1][0], S[1][1], S[1][2], S[1][3], 3, 1); /* Draw the "arrow head" */ for (i = -3; i < 4; i++) for (j = -3; j < 4; j++) if (abs(i) + abs(j) < 6) plot((int) (S[1][2][0] + i), (int) (S[1][2][1] + j), 10); } static void draw_rect(VECTOR V0, VECTOR V1, VECTOR V2, VECTOR V3, int color, int rect) { VECTOR V[4]; int i; /* Since V[2] is not used by vdraw_line don't bother setting it */ for (i = 0; i < 2; i++) { V[0][i] = V0[i]; V[1][i] = V1[i]; V[2][i] = V2[i]; V[3][i] = V3[i]; } if (rect) /* Draw a rectangle */ { for (i = 0; i < 4; i++) if (fabs(V[i][0] - V[(i + 1) % 4][0]) < -2 * bad_check && fabs(V[i][1] - V[(i + 1) % 4][1]) < -2 * bad_check) vdraw_line(V[i], V[(i + 1) % 4], color); } else /* Draw 2 lines instead */ { for (i = 0; i < 3; i += 2) if (fabs(V[i][0] - V[i + 1][0]) < -2 * bad_check && fabs(V[i][1] - V[i + 1][1]) < -2 * bad_check) vdraw_line(V[i], V[i + 1], color); } return; } /* replacement for plot - builds a table of min and max x's instead of plot */ /* called by draw_line as part of triangle fill routine */ static void _fastcall putminmax(int x, int y, int color) { color = 0; /* to supress warning only */ if (y >= 0 && y < ydots) { if (x < minmax_x[y].minx) minmax_x[y].minx = x; if (x > minmax_x[y].maxx) minmax_x[y].maxx = x; } } /* This routine fills in a triangle. Extreme left and right values for each row are calculated by calling the line function for the sides. Then rows are filled in with horizontal lines */ #define MAXOFFSCREEN 2 /* allow two of three points to be off screen */ static void _fastcall putatriangle(struct point pt1, struct point pt2, struct point pt3, int color) { int miny, maxy; int x, y, xlim; /* Too many points off the screen? */ if ((offscreen(pt1) + offscreen(pt2) + offscreen(pt3)) > MAXOFFSCREEN) return; p1 = pt1; /* needed by interpcolor */ p2 = pt2; p3 = pt3; /* fast way if single point or single line */ if (p1.y == p2.y && p1.x == p2.x) { plot = fillplot; if (p1.y == p3.y && p1.x == p3.x) (*plot) (p1.x, p1.y, color); else draw_line(p1.x, p1.y, p3.x, p3.y, color); plot = normalplot; return; } else if ((p3.y == p1.y && p3.x == p1.x) || (p3.y == p2.y && p3.x == p2.x)) { plot = fillplot; draw_line(p1.x, p1.y, p2.x, p2.y, color); plot = normalplot; return; } /* find min max y */ miny = maxy = p1.y; if (p2.y < miny) miny = p2.y; else maxy = p2.y; if (p3.y < miny) miny = p3.y; else if (p3.y > maxy) maxy = p3.y; /* only worried about values on screen */ if (miny < 0) miny = 0; if (maxy >= ydots) maxy = ydots - 1; for (y = miny; y <= maxy; y++) { minmax_x[y].minx = (int) INT_MAX; minmax_x[y].maxx = (int) INT_MIN; } /* set plot to "fake" plot function */ plot = putminmax; /* build table of extreme x's of triangle */ draw_line(p1.x, p1.y, p2.x, p2.y, 0); draw_line(p2.x, p2.y, p3.x, p3.y, 0); draw_line(p3.x, p3.y, p1.x, p1.y, 0); for (y = miny; y <= maxy; y++) { xlim = minmax_x[y].maxx; for (x = minmax_x[y].minx; x <= xlim; x++) (*fillplot) (x, y, color); } plot = normalplot; } static int _fastcall offscreen(struct point pt) { if (pt.x >= 0) if (pt.x < xdots) if (pt.y >= 0) if (pt.y < ydots) return (0); /* point is ok */ if (abs(pt.x) > 0 - bad_check || abs(pt.y) > 0 - bad_check) return (99); /* point is bad */ return (1); /* point is off the screen */ } static void _fastcall clipcolor(int x, int y, int color) { if (0 <= x && x < xdots && 0 <= y && y < ydots && 0 <= color && color < filecolors) { standardplot(x, y, color); if (Targa_Out) /* standardplot modifies color in these types */ if (!(glassestype == 1 || glassestype == 2)) targa_color(x, y, color); } } /*********************************************************************/ /* This function is the same as clipcolor but checks for color being */ /* in transparent range. Intended to be called only if transparency */ /* has been enabled. */ /*********************************************************************/ static void _fastcall T_clipcolor(int x, int y, int color) { if (0 <= x && x < xdots && /* is the point on screen? */ 0 <= y && y < ydots && /* Yes? */ 0 <= color && color < colors && /* Colors in valid range? */ /* Lets make sure its not a transparent color */ (transparent[0] > color || color > transparent[1])) { standardplot(x, y, color);/* I guess we can plot then */ if (Targa_Out) /* standardplot modifies color in these types */ if (!(glassestype == 1 || glassestype == 2)) targa_color(x, y, color); } } /************************************************************************/ /* A substitute for plotcolor that interpolates the colors according */ /* to the x and y values of three points (p1,p2,p3) which are static in */ /* this routine */ /* */ /* In Light source modes, color is light value, not actual color */ /* Real_Color always contains the actual color */ /************************************************************************/ static void _fastcall interpcolor(int x, int y, int color) { int D, d1, d2, d3; /* this distance formula is not the usual one - but it has the virtue that * it uses ONLY additions (almost) and it DOES go to zero as the points * get close. */ d1 = abs(p1.x - x) + abs(p1.y - y); d2 = abs(p2.x - x) + abs(p2.y - y); d3 = abs(p3.x - x) + abs(p3.y - y); D = (d1 + d2 + d3) << 1; if (D) { /* calculate a weighted average of colors long casts prevent integer overflow. This can evaluate to zero */ color = (int) (((long) (d2 + d3) * (long) p1.color + (long) (d1 + d3) * (long) p2.color + (long) (d1 + d2) * (long) p3.color) / D); } if (0 <= x && x < xdots && 0 <= y && y < ydots && 0 <= color && color < colors && (transparent[1] == 0 || (int) Real_Color > transparent[1] || transparent[0] > (int) Real_Color)) { if (Targa_Out) /* standardplot modifies color in these types */ if (!(glassestype == 1 || glassestype == 2)) D = targa_color(x, y, color); if (FILLTYPE >= 5) { if (Real_V && Targa_Out) color = D; else { color = (1 + (unsigned) color * IAmbient) / 256; if (color == 0) color = 1; } } standardplot(x, y, color); } } /* In non light source modes, both color and Real_Color contain the actual pixel color. In light source modes, color contains the light value, and Real_Color contains the origninal color This routine takes a pixel modifies it for lightshading if appropriate and plots it in a Targa file. Used in plot3d.c */ int _fastcall targa_color(int x, int y, int color) { unsigned long H, S, V; BYTE RGB[3]; if (FILLTYPE == 2 || glassestype == 1 || glassestype == 2 || truecolor) Real_Color = (BYTE)color; /* So Targa gets interpolated color */ switch (truemode) { case 0: default: { RGB[0] = (BYTE)(dacbox[Real_Color][0] << 2); /* Move color space to */ RGB[1] = (BYTE)(dacbox[Real_Color][1] << 2); /* 256 color primaries */ RGB[2] = (BYTE)(dacbox[Real_Color][2] << 2); /* from 64 colors */ break; } case 1: { RGB[0] = (BYTE)((realcoloriter >> 16) & 0xff); /* red */ RGB[1] = (BYTE)((realcoloriter >> 8 ) & 0xff); /* green */ RGB[2] = (BYTE)((realcoloriter ) & 0xff); /* blue */ break; } } /* Now lets convert it to HSV */ R_H(RGB[0], RGB[1], RGB[2], &H, &S, &V); /* Modify original S and V components */ if (FILLTYPE > 4 && !(glassestype == 1 || glassestype == 2)) /* Adjust for Ambient */ V = (V * (65535L - (unsigned) (color * IAmbient))) / 65535L; if (haze) { /* Haze lowers sat of colors */ S = (unsigned long) (S * HAZE_MULT) / 100; if (V >= 32640) /* Haze reduces contrast */ { V = V - 32640; V = (unsigned long) ((V * HAZE_MULT) / 100); V = V + 32640; } else { V = 32640 - V; V = (unsigned long) ((V * HAZE_MULT) / 100); V = 32640 - V; } } /* Now lets convert it back to RGB. Original Hue, modified Sat and Val */ H_R(&RGB[0], &RGB[1], &RGB[2], H, S, V); if (Real_V) V = (35 * (int) RGB[0] + 45 * (int) RGB[1] + 20 * (int) RGB[2]) / 100; /* Now write the color triple to its transformed location */ /* on the disk. */ targa_writedisk(x + sxoffs, y + syoffs, RGB[0], RGB[1], RGB[2]); return ((int) (255 - V)); } static int set_pixel_buff(BYTE * pixels, BYTE far * fraction, unsigned linelen) { int i; if ((evenoddrow++ & 1) == 0) /* even rows are color value */ { for (i = 0; i < (int) linelen; i++) /* add the fractional part in * odd row */ fraction[i] = pixels[i]; return (1); } else /* swap */ { BYTE tmp; for (i = 0; i < (int) linelen; i++) /* swap so pixel has color */ { tmp = pixels[i]; pixels[i] = fraction[i]; fraction[i] = tmp; } } return (0); } /************************************************************************** Common routine for printing error messages to the screen for Targa and other files **************************************************************************/ #ifndef XFRACT static char s_f[] = "%Fs%Fs"; static char s_fff[] = "%Fs%Fs%Fs"; #else static char s_f[] = "%s%s"; static char s_fff[] = "%s%s%s"; #endif static FCODE OOPS[] = {"OOPS, "}; static FCODE E1[] = {"can't handle this type of file.\n"}; static FCODE str1[] = {"couldn't open < "}; static FCODE str3[] = {"image wrong size\n"}; static FCODE outofdisk[] = {"ran out of disk space. < "}; static void File_Error(char *File_Name1, int ERROR) { char msgbuf[200]; error = ERROR; switch (ERROR) { case 1: /* Can't Open */ #ifndef XFRACT sprintf(msgbuf, "%Fs%Fs%s >", (char far *)OOPS, (char far *)str1, File_Name1); #else sprintf(msgbuf, "%s%s%s >", OOPS, str1, File_Name1); #endif break; case 2: /* Not enough room */ #ifndef XFRACT sprintf(msgbuf, "%Fs%Fs%s >", (char far *)OOPS, (char far *)outofdisk, File_Name1); #else sprintf(msgbuf, "%s%s%s >", OOPS, outofdisk, File_Name1); #endif break; case 3: /* Image wrong size */ sprintf(msgbuf, s_f, (char far *)OOPS, (char far *)str3); break; case 4: /* Wrong file type */ sprintf(msgbuf, s_f, (char far *)OOPS, (char far *)E1); break; } stopmsg(0, msgbuf); return; } /************************************************************************/ /* */ /* This function opens a TARGA_24 file for reading and writing. If */ /* its a new file, (overlay == 0) it writes a header. If it is to */ /* overlay an existing file (overlay == 1) it copies the original */ /* header whose lenght and validity was determined in */ /* Targa_validate. */ /* */ /* It Verifies there is enough disk space, and leaves the file */ /* at the start of the display data area. */ /* */ /* If this is an overlay, closes source and copies to "targa_temp" */ /* If there is an error close the file. */ /* */ /* **********************************************************************/ int startdisk1(char *File_Name2, FILE * Source, int overlay) { int i, j, k, inc; FILE *fps; /* Open File for both reading and writing */ if ((fps = dir_fopen(workdir,File_Name2, "w+b")) == NULL) { File_Error(File_Name2, 1); return (-1); /* Oops, somethings wrong! */ } inc = 1; /* Assume we are overlaying a file */ /* Write the header */ if (overlay) /* We are overlaying a file */ for (i = 0; i < T_header_24; i++) /* Copy the header from the Source */ fputc(fgetc(Source), fps); else { /* Write header for a new file */ /* ID field size = 0, No color map, Targa type 2 file */ for (i = 0; i < 12; i++) { if (i == 0 && truecolor != 0) { set_upr_lwr(); fputc(4, fps); /* make room to write an extra number */ T_header_24 = 18 + 4; } else if (i == 2) fputc(i, fps); else fputc(0, fps); } /* Write image size */ for (i = 0; i < 4; i++) fputc(upr_lwr[i], fps); fputc(T24, fps); /* Targa 24 file */ fputc(T32, fps); /* Image at upper left */ inc = 3; } if(truecolor) /* write maxit */ { fputc((BYTE)(maxit & 0xff), fps); fputc((BYTE)((maxit>>8 ) & 0xff), fps); fputc((BYTE)((maxit>>16) & 0xff), fps); fputc((BYTE)((maxit>>24) & 0xff), fps); } /* Finished with the header, now lets work on the display area */ for (i = 0; i < ydots; i++) /* "clear the screen" (write to the disk) */ { for (j = 0; j < line_length1; j = j + inc) { if (overlay) fputc(fgetc(Source), fps); else for (k = 2; k > -1; k--) fputc(back_color[k], fps); /* Targa order (B, G, R) */ } if (ferror(fps)) { /* Almost certainly not enough disk space */ fclose(fps); if(overlay) fclose(Source); dir_remove(workdir,File_Name2); File_Error(File_Name2, 2); return (-2); } if (keypressed()) return (-3); } if (targa_startdisk(fps, T_header_24) != 0) { enddisk(); dir_remove(workdir,File_Name2); return (-4); } return (0); } int targa_validate(char *File_Name) { FILE *fp; int i; #if 0 int j = 0; #endif /* Attempt to open source file for reading */ if ((fp = dir_fopen(workdir,File_Name, "rb")) == NULL) { File_Error(File_Name, 1); return (-1); /* Oops, file does not exist */ } T_header_24 += fgetc(fp); /* Check ID field and adjust header size */ if (fgetc(fp)) /* Make sure this is an unmapped file */ { File_Error(File_Name, 4); return (-1); } if (fgetc(fp) != 2) /* Make sure it is a type 2 file */ { File_Error(File_Name, 4); return (-1); } /* Skip color map specification */ for (i = 0; i < 5; i++) fgetc(fp); for (i = 0; i < 4; i++) { /* Check image origin */ fgetc(fp); #if 0 if (j != 0) { File_Error(File_Name, 4); return (-1); } #endif } /* Check Image specs */ for (i = 0; i < 4; i++) if (fgetc(fp) != (int) upr_lwr[i]) { File_Error(File_Name, 3); return (-1); } if (fgetc(fp) != (int) T24) error = 4; /* Is it a targa 24 file? */ if (fgetc(fp) != (int) T32) error = 4; /* Is the origin at the upper left? */ if (error == 4) { File_Error(File_Name, 4); return (-1); } rewind(fp); /* Now that we know its a good file, create a working copy */ if (startdisk1(targa_temp, fp, 1)) return (-1); fclose(fp); /* Close the source */ T_Safe = 1; /* Original file successfully copied to * targa_temp */ return (0); } static int R_H(BYTE R, BYTE G, BYTE B, unsigned long *H, unsigned long *S, unsigned long *V) { unsigned long R1, G1, B1, DENOM; BYTE MIN; *V = R; MIN = G; if (R < G) { *V = G; MIN = R; if (G < B) *V = B; if (B < R) MIN = B; } else { if (B < G) MIN = B; if (R < B) *V = B; } DENOM = *V - MIN; if (*V != 0 && DENOM != 0) { *S = ((DENOM << 16) / *V) - 1; } else *S = 0; /* Color is black! and Sat has no meaning */ if (*S == 0) /* R=G=B => shade of grey and Hue has no meaning */ { *H = 0; *V = *V << 8; return (1); /* v or s or both are 0 */ } if (*V == MIN) { *H = 0; *V = *V << 8; return (0); } R1 = (((*V - R) * 60) << 6) / DENOM; /* distance of color from red */ G1 = (((*V - G) * 60) << 6) / DENOM; /* distance of color from green */ B1 = (((*V - B) * 60) << 6) / DENOM; /* distance of color from blue */ if (*V == R) { if (MIN == G) *H = (300 << 6) + B1; else *H = (60 << 6) - G1; } if (*V == G) { if (MIN == B) *H = (60 << 6) + R1; else *H = (180 << 6) - B1; } if (*V == B) { if (MIN == R) *H = (180 << 6) + G1; else *H = (300 << 6) - R1; } *V = *V << 8; return (0); } static int H_R(BYTE *R, BYTE *G, BYTE *B, unsigned long H, unsigned long S, unsigned long V) { unsigned long P1, P2, P3; int RMD, I; if (H >= 23040) H = H % 23040; /* Makes h circular */ I = (int) (H / 3840); RMD = (int) (H % 3840); /* RMD = fractional part of H */ P1 = ((V * (65535L - S)) / 65280L) >> 8; P2 = (((V * (65535L - (S * RMD) / 3840)) / 65280L) - 1) >> 8; P3 = (((V * (65535L - (S * (3840 - RMD)) / 3840)) / 65280L)) >> 8; V = V >> 8; switch (I) { case 0: *R = (BYTE) V; *G = (BYTE) P3; *B = (BYTE) P1; break; case 1: *R = (BYTE) P2; *G = (BYTE) V; *B = (BYTE) P1; break; case 2: *R = (BYTE) P1; *G = (BYTE) V; *B = (BYTE) P3; break; case 3: *R = (BYTE) P1; *G = (BYTE) P2; *B = (BYTE) V; break; case 4: *R = (BYTE) P3; *G = (BYTE) P1; *B = (BYTE) V; break; case 5: *R = (BYTE) V; *G = (BYTE) P1; *B = (BYTE) P2; break; } return (0); } /***************************************************************************/ /* */ /* EB & DG fiddled with outputs for Rayshade so they work. with v4.x. */ /* EB == eli brandt. ebrandt@jarthur.claremont.edu */ /* DG == dan goldwater. daniel_goldwater@brown.edu & dgold@math.umass.edu */ /* (NOTE: all the stuff we fiddled with is commented with "EB & DG" ) */ /* general raytracing code info/notes: */ /* */ /* ray == 0 means no raytracer output ray == 7 is for dxf */ /* ray == 1 is for dkb/pov ray == 4 is for mtv */ /* ray == 2 is for vivid ray == 5 is for rayshade */ /* ray == 3 is for raw ray == 6 is for acrospin */ /* */ /* rayshade needs counterclockwise triangles. raytracers that support */ /* the 'heightfield' primitive include rayshade and pov. anyone want to */ /* write code to make heightfields? they are *MUCH* faster to trace than */ /* triangles when doing landscapes... */ /* */ /* stuff EB & DG changed: */ /* made the rayshade output create a "grid" aggregate object (one of */ /* rayshade's primitives), instead of a global grid. as a result, the */ /* grid can be optimized based on the number of triangles. */ /* the z component of the grid can always be 1 since the surface formed */ /* by the triangles is flat */ /* (ie, it doesnt curve over itself). this is a major optimization. */ /* the x and y grid size is also optimized for a 4:3 aspect ratio image, */ /* to get the fewest possible traingles in each grid square. */ /* also, we fixed the rayshade code so it actually produces output that */ /* works with rayshade. */ /* (maybe the old code was for a really old version of rayshade?). */ /* */ /***************************************************************************/ /********************************************************************/ /* */ /* This routine writes a header to a ray tracer data file. It */ /* Identifies the version of FRACTINT which created it an the */ /* key 3D parameters in effect at the time. */ /* */ /********************************************************************/ static FCODE declare[] = {"DECLARE "}; static FCODE frac_default[] = {"F_Dflt"}; static FCODE s_color[] = {"COLOR "}; static FCODE dflt[] = {"RED 0.8 GREEN 0.4 BLUE 0.1\n"}; static FCODE d_color[] = {"0.8 0.4 0.1"}; static FCODE r_surf[] = {"0.95 0.05 5 0 0\n"}; static FCODE surf[] = {"surf={diff="}; /* EB & DG: changed "surface T" to "applysurf" and "diff" to "diffuse" */ static FCODE rs_surf[] = {"applysurf diffuse "}; static FCODE end[] = {"END_"}; static FCODE plane[] = {"PLANE"}; static FCODE m1[] = {"-1.0 "}; static FCODE one[] = {" 1.0 "}; static FCODE z[] = {" 0.0 "}; static FCODE bnd_by[] = {" BOUNDED_BY\n"}; static FCODE end_bnd[] = {" END_BOUND\n"}; static FCODE inter[] = {"INTERSECTION\n"}; #ifndef XFRACT static char fmt[] = " %Fs <%Fs%Fs%Fs> % #4.3f %Fs%Fs\n"; #else static char fmt[] = " %s <%s%s%s> % #4.3f %s%s\n"; #endif static char dxf_begin[] = {" 0\nSECTION\n 2\nTABLES\n 0\nTABLE\n 2\nLAYER\n\ 70\n 2\n 0\nLAYER\n 2\n0\n 70\n 0\n 62\n 7\n 6\nCONTINUOUS\n\ 0\nLAYER\n 2\nFRACTAL\n 70\n 64\n 62\n 1\n 6\nCONTINUOUS\n 0\n\ ENDTAB\n 0\nENDSEC\n 0\nSECTION\n 2\nENTITIES\n"}; static char dxf_3dface[] = {" 0\n3DFACE\n 8\nFRACTAL\n 62\n%3d\n"}; static char dxf_vertex[] = {"%3d\n%g\n"}; static char dxf_end[] = {" 0\nENDSEC\n 0\nEOF\n"}; static FCODE composite[] = {"COMPOSITE"}; static FCODE object[] = {"OBJECT"}; static FCODE triangle[] = {"TRIANGLE "}; static FCODE l_tri[] = {"triangle"}; static FCODE texture[] = {"TEXTURE\n"}; /* static FCODE end_texture[] = {" END_TEXTURE\n"}; */ static FCODE red[] = {"RED"}; static FCODE green[] = {"GREEN"}; static FCODE blue[] = {"BLUE"}; static FCODE frac_texture[] = {" AMBIENT 0.25 DIFFUSE 0.75"}; static FCODE polygon[] = {"polygon={points=3;"}; static FCODE vertex[] = {" vertex = "}; static FCODE d_vert[] = {" <"}; static char f1[] = "% #4.4f "; /* EB & DG: changed this to much better values */ static FCODE grid[] = {"screen 640 480\neyep 0 2.1 0.8\nlookp 0 0 -0.95\nlight 1 point -2 1 1.5\n"}; static FCODE grid2[] = {"background .3 0 0\nreport verbose\n"}; static char s_n[] = "\n"; static char f2[] = "R%dC%d R%dC%d\n"; static FCODE ray_comment1[] = {"/* make a gridded aggregate. this size grid is fast for landscapes. */\n"}; static FCODE ray_comment2[] = {"/* make z grid = 1 always for landscapes. */\n\n"}; static FCODE grid3[] = {"grid 33 25 1\n"}; static int _fastcall RAY_Header(void) { /* Open the ray tracing output file */ check_writefile(ray_name, ".ray"); if ((File_Ptr1 = fopen(ray_name, "w")) == NULL) return (-1); /* Oops, somethings wrong! */ if (RAY == 2) fprintf(File_Ptr1, "//"); if (RAY == 4) fprintf(File_Ptr1, "#"); if (RAY == 5) fprintf(File_Ptr1, "/*\n"); if (RAY == 6) fprintf(File_Ptr1, "--"); if (RAY == 7) fprintf(File_Ptr1, dxf_begin); if (RAY != 7) fprintf(File_Ptr1, banner, (char far *)s3, release / 100., (char far *)s3a); if (RAY == 5) fprintf(File_Ptr1, "*/\n"); /* Set the default color */ if (RAY == 1) { fprintf(File_Ptr1, s_f, (char far *)declare, (char far *)frac_default); fprintf(File_Ptr1, " = "); fprintf(File_Ptr1, s_f, (char far *)s_color, (char far *)dflt); } if (BRIEF) { if (RAY == 2) { fprintf(File_Ptr1, s_f, (char far *)surf, (char far *)d_color); fprintf(File_Ptr1, ";}\n"); } if (RAY == 4) { fprintf(File_Ptr1, "f "); fprintf(File_Ptr1, s_f, (char far *)d_color, (char far *)r_surf); } if (RAY == 5) fprintf(File_Ptr1, s_f, (char far *)rs_surf, (char far *)d_color); } if (RAY != 7) fprintf(File_Ptr1, s_n); /* EB & DG: open "grid" opject, a speedy way to do aggregates in rayshade */ if (RAY == 5) fprintf(File_Ptr1, s_fff, (char far *)ray_comment1, (char far *)ray_comment2, (char far *)grid3); if (RAY == 6) #ifndef XFRACT fprintf(File_Ptr1, "%Fs", (char far *)acro_s1); #else fprintf(File_Ptr1, "%s", acro_s1); #endif return (0); } /********************************************************************/ /* */ /* This routine describes the triangle to the ray tracer, it */ /* sets the color of the triangle to the average of the color */ /* of its verticies and sets the light parameters to arbitrary */ /* values. */ /* */ /* Note: numcolors (number of colors in the source */ /* file) is used instead of colors (number of colors avail. with */ /* display) so you can generate ray trace files with your LCD */ /* or monochrome display */ /* */ /********************************************************************/ static int _fastcall out_triangle(struct f_point pt1, struct f_point pt2, struct f_point pt3, int c1, int c2, int c3) { int i, j; float c[3]; float pt_t[3][3]; /* Normalize each vertex to screen size and adjust coordinate system */ pt_t[0][0] = 2 * pt1.x / xdots - 1; pt_t[0][1] = (2 * pt1.y / ydots - 1); pt_t[0][2] = -2 * pt1.color / numcolors - 1; pt_t[1][0] = 2 * pt2.x / xdots - 1; pt_t[1][1] = (2 * pt2.y / ydots - 1); pt_t[1][2] = -2 * pt2.color / numcolors - 1; pt_t[2][0] = 2 * pt3.x / xdots - 1; pt_t[2][1] = (2 * pt3.y / ydots - 1); pt_t[2][2] = -2 * pt3.color / numcolors - 1; /* Color of triangle is average of colors of its verticies */ if (!BRIEF) for (i = 0; i <= 2; i++) #ifdef __SVR4 c[i] = (float) ((int)(dacbox[c1][i] + dacbox[c2][i] + dacbox[c3][i]) / (3 * 63)); #else c[i] = (float) (dacbox[c1][i] + dacbox[c2][i] + dacbox[c3][i]) / (3 * 63); #endif /* get rid of degenerate triangles: any two points equal */ if ((pt_t[0][0] == pt_t[1][0] && pt_t[0][1] == pt_t[1][1] && pt_t[0][2] == pt_t[1][2]) || (pt_t[0][0] == pt_t[2][0] && pt_t[0][1] == pt_t[2][1] && pt_t[0][2] == pt_t[2][2]) || (pt_t[2][0] == pt_t[1][0] && pt_t[2][1] == pt_t[1][1] && pt_t[2][2] == pt_t[1][2])) return (0); /* Describe the triangle */ #ifndef XFRACT if (RAY == 1) fprintf(File_Ptr1, " %Fs\n %Fs", (char far *)object, (char far *)triangle); if (RAY == 2 && !BRIEF) fprintf(File_Ptr1, "%Fs", (char far *)surf); #else if (RAY == 1) fprintf(File_Ptr1, " %s\n %s", object, triangle); if (RAY == 2 && !BRIEF) fprintf(File_Ptr1, "%s", surf); #endif if (RAY == 4 && !BRIEF) fprintf(File_Ptr1, "f"); if (RAY == 5 && !BRIEF) #ifndef XFRACT fprintf(File_Ptr1, "%Fs", (char far *)rs_surf); #else fprintf(File_Ptr1, "%s", rs_surf); #endif if (!BRIEF && RAY != 1 && RAY != 7) for (i = 0; i <= 2; i++) fprintf(File_Ptr1, f1, c[i]); if (RAY == 2) { if (!BRIEF) fprintf(File_Ptr1, ";}\n"); #ifndef XFRACT fprintf(File_Ptr1, "%Fs", (char far *)polygon); #else fprintf(File_Ptr1, "%s", polygon); #endif } if (RAY == 4) { if (!BRIEF) #ifndef XFRACT fprintf(File_Ptr1, "%Fs", (char far *)r_surf); #else fprintf(File_Ptr1, "%s", r_surf); #endif fprintf(File_Ptr1, "p 3"); } if (RAY == 5) { if (!BRIEF) fprintf(File_Ptr1, s_n); /* EB & DG: removed "T" after "triangle" */ #ifndef XFRACT fprintf(File_Ptr1, "%Fs", (char far *)l_tri); #else fprintf(File_Ptr1, "%s", l_tri); #endif } if (RAY == 7) fprintf(File_Ptr1, dxf_3dface, min(255, max(1, c1))); for (i = 0; i <= 2; i++) /* Describe each Vertex */ { if (RAY != 7) fprintf(File_Ptr1, s_n); #ifndef XFRACT if (RAY == 1) fprintf(File_Ptr1, "%Fs", (char far *)d_vert); if (RAY == 2) fprintf(File_Ptr1, "%Fs", (char far *)vertex); #else if (RAY == 1) fprintf(File_Ptr1, "%s", d_vert); if (RAY == 2) fprintf(File_Ptr1, "%s", vertex); #endif if (RAY > 3 && RAY != 7) fprintf(File_Ptr1, " "); for (j = 0; j <= 2; j++) { if (RAY == 7) { /* write 3dface entity to dxf file */ fprintf(File_Ptr1, dxf_vertex, 10 * (j + 1) + i, pt_t[i][j]); if (i == 2) /* 3dface needs 4 vertecies */ fprintf(File_Ptr1, dxf_vertex, 10 * (j + 1) + i + 1, pt_t[i][j]); } else if (!(RAY == 4 || RAY == 5)) fprintf(File_Ptr1, f1, pt_t[i][j]); /* Right handed */ else fprintf(File_Ptr1, f1, pt_t[2 - i][j]); /* Left handed */ } if (RAY == 1) fprintf(File_Ptr1, ">"); if (RAY == 2) fprintf(File_Ptr1, ";"); } if (RAY == 1) { #ifndef XFRACT fprintf(File_Ptr1, " %Fs%Fs\n", (char far *)end, (char far *)triangle); #else fprintf(File_Ptr1, " %s%s\n", end, triangle); #endif if (!BRIEF) { #ifndef XFRACT fprintf(File_Ptr1, " %Fs" " %Fs%Fs% #4.4f %Fs% #4.4f %Fs% #4.4f\n" "%Fs" " %Fs%Fs", #else fprintf(File_Ptr1, " %s %s%s% #4.4f %s% #4.4f %s% #4.4f\n%s %s%s", #endif (char far *)texture, (char far *)s_color, (char far *)red, c[0], (char far *)green, c[1], (char far *)blue, c[2], (char far *)frac_texture, (char far *)end, (char far *)texture); } #ifndef XFRACT fprintf(File_Ptr1, " %Fs%Fs %Fs%Fs", #else fprintf(File_Ptr1, " %s%s %s%s", #endif (char far *)s_color, (char far *)frac_default, (char far *)end, (char far *)object); triangle_bounds(pt_t); /* update bounding info */ } if (RAY == 2) fprintf(File_Ptr1, "}"); if (RAY == 3 && !BRIEF) fprintf(File_Ptr1, s_n); if (RAY != 7) fprintf(File_Ptr1, s_n); return (0); } /********************************************************************/ /* */ /* This routine calculates the min and max values of a triangle */ /* for use in creating ray tracer data files. The values of min */ /* and max x, y, and z are assumed to be global. */ /* */ /********************************************************************/ static void _fastcall triangle_bounds(float pt_t[3][3]) { int i, j; for (i = 0; i <= 2; i++) for (j = 0; j <= 2; j++) { if (pt_t[i][j] < min_xyz[j]) min_xyz[j] = pt_t[i][j]; if (pt_t[i][j] > max_xyz[j]) max_xyz[j] = pt_t[i][j]; } return; } /********************************************************************/ /* */ /* This routine starts a composite object for ray trace data files */ /* */ /********************************************************************/ static int _fastcall start_object(void) { if (RAY != 1) return (0); /* Reset the min/max values, for bounding box */ min_xyz[0] = min_xyz[1] = min_xyz[2] = (float)999999.0; max_xyz[0] = max_xyz[1] = max_xyz[2] = (float)-999999.0; #ifndef XFRACT fprintf(File_Ptr1, "%Fs\n", (char far *)composite); #else fprintf(File_Ptr1, "%s\n", composite); #endif return (0); } /********************************************************************/ /* */ /* This routine adds a bounding box for the triangles drawn */ /* in the last block and completes the composite object created. */ /* It uses the globals min and max x,y and z calculated in */ /* z calculated in Triangle_Bounds(). */ /* */ /********************************************************************/ static int _fastcall end_object(int triout) { if (RAY == 7) return (0); if (RAY == 1) { if (triout) { /* Make sure the bounding box is slightly larger than the object */ int i; for (i = 0; i <= 2; i++) { if (min_xyz[i] == max_xyz[i]) { min_xyz[i] -= (float)0.01; max_xyz[i] += (float)0.01; } else { min_xyz[i] -= (max_xyz[i] - min_xyz[i]) * (float)0.01; max_xyz[i] += (max_xyz[i] - min_xyz[i]) * (float)0.01; } } /* Add the bounding box info */ #ifndef XFRACT fprintf(File_Ptr1, "%Fs %Fs", (char far *)bnd_by, (char far *)inter); #else fprintf(File_Ptr1, "%s %s", bnd_by, inter); #endif fprintf(File_Ptr1, fmt, (char far *)plane, (char far *)m1, (char far *)z, (char far *)z, -min_xyz[0], (char far *)end, (char far *)plane); fprintf(File_Ptr1, fmt, (char far *)plane, (char far *)one, (char far *)z, (char far *)z, max_xyz[0], (char far *)end, (char far *)plane); fprintf(File_Ptr1, fmt, (char far *)plane, (char far *)z, (char far *)m1, (char far *)z, -min_xyz[1], (char far *)end, (char far *)plane); fprintf(File_Ptr1, fmt, (char far *)plane, (char far *)z, (char far *)one, (char far *)z, max_xyz[1], (char far *)end, (char far *)plane); fprintf(File_Ptr1, fmt, (char far *)plane, (char far *)z, (char far *)z, (char far *)m1, -min_xyz[2], (char far *)end, (char far *)plane); fprintf(File_Ptr1, fmt, (char far *)plane, (char far *)z, (char far *)z, (char far *)one, max_xyz[2], (char far *)end, (char far *)plane); #ifndef XFRACT fprintf(File_Ptr1, " %Fs%Fs%Fs", (char far *)end, (char far *)inter, (char far *)end_bnd); #else fprintf(File_Ptr1, " %s%s%s", end, inter, end_bnd); #endif } /* Complete the composite object statement */ #ifndef XFRACT fprintf(File_Ptr1, "%Fs%Fs\n", (char far *)end, (char far *)composite); #else fprintf(File_Ptr1, "%s%s\n", end, composite); #endif } if (RAY != 6 && RAY != 5) fprintf(File_Ptr1, s_n); /* EB & DG: too many newlines */ return (0); } static void line3d_cleanup(void) { int i, j; if (RAY && File_Ptr1) { /* Finish up the ray tracing files */ static FCODE n_ta[] = {"{ No. Of Triangles = "}; if (RAY != 5 && RAY != 7) fprintf(File_Ptr1, s_n); /* EB & DG: too many newlines */ if (RAY == 2) fprintf(File_Ptr1, "\n\n//"); if (RAY == 4) fprintf(File_Ptr1, "\n\n#"); if (RAY == 5) #ifndef XFRACT /* EB & DG: end grid aggregate */ fprintf(File_Ptr1, "end\n\n/*good landscape:*/\n%Fs%Fs\n/*", (char far *)grid, (char far *)grid2); #else /* EB & DG: end grid aggregate */ fprintf(File_Ptr1, "end\n\n/*good landscape:*/\n%s%s\n/*", grid, grid2); #endif if (RAY == 6) { #ifndef XFRACT fprintf(File_Ptr1, "%Fs", (char far *)acro_s2); #else fprintf(File_Ptr1, "%s", acro_s2); #endif for (i = 0; i < RO; i++) for (j = 0; j <= CO_MAX; j++) { if (j < CO_MAX) fprintf(File_Ptr1, f2, i, j, i, j + 1); if (i < RO - 1) fprintf(File_Ptr1, f2, i, j, i + 1, j); if (i && i < RO && j < CO_MAX) fprintf(File_Ptr1, f2, i, j, i - 1, j + 1); } fprintf(File_Ptr1, "\n\n--"); } if (RAY != 7) #ifndef XFRACT fprintf(File_Ptr1, "%Fs%ld }*/\n\n", (char far *)n_ta, num_tris); #else fprintf(File_Ptr1, "%s%ld }*/\n\n", n_ta, num_tris); #endif if (RAY == 7) fprintf(File_Ptr1, dxf_end); fclose(File_Ptr1); File_Ptr1 = NULL; } if (Targa_Out) { /* Finish up targa files */ T_header_24 = 18; /* Reset Targa header size */ enddisk(); if (!debugflag && (!T_Safe || error) && Targa_Overlay) { dir_remove(workdir, light_name); rename(targa_temp, light_name); } if (!debugflag && Targa_Overlay) dir_remove(workdir, targa_temp); } usr_floatflag &= 1; /* strip second bit */ error = T_Safe = 0; } static void set_upr_lwr(void) { upr_lwr[0] = (BYTE)(xdots & 0xff); upr_lwr[1] = (BYTE)(xdots >> 8); upr_lwr[2] = (BYTE)(ydots & 0xff); upr_lwr[3] = (BYTE)(ydots >> 8); line_length1 = 3 * xdots; /* line length @ 3 bytes per pixel */ } static int first_time(int linelen, VECTOR v) { int err; MATRIX lightm; /* m w/no trans, keeps obj. on screen */ float twocosdeltatheta; double xval, yval, zval; /* rotation values */ /* corners of transformed xdotx by ydots x colors box */ double xmin, ymin, zmin, xmax, ymax, zmax; int i, j; double v_length; VECTOR origin, direct, tmp; float theta, theta1, theta2; /* current,start,stop latitude */ float phi1, phi2; /* current start,stop longitude */ float deltatheta; /* increment of latitude */ outln_cleanup = line3d_cleanup; calctime = evenoddrow = 0; /* mark as in-progress, and enable timer display */ calc_status = 1; IAmbient = (unsigned int) (255 * (float) (100 - Ambient) / 100.0); if (IAmbient < 1) IAmbient = 1; num_tris = 0; /* Open file for RAY trace output and write header */ if (RAY) { RAY_Header(); xxadjust = yyadjust = 0; /* Disable shifting in ray tracing */ xshift = yshift = 0; } CO_MAX = CO = RO = 0; set_upr_lwr(); error = 0; if (whichimage < 2) T_Safe = 0; /* Not safe yet to mess with the source image */ if (Targa_Out && !((glassestype == 1 || glassestype == 2) && whichimage == 2)) { if (Targa_Overlay) { /* Make sure target file is a supportable Targa File */ if (targa_validate(light_name)) return (-1); } else { check_writefile(light_name, ".tga"); if (startdisk1(light_name, NULL, 0)) /* Open new file */ return (-1); } } rand_factor = 14 - RANDOMIZE; zcoord = filecolors; if((err=line3dmem()) != 0) return(err); /* get scale factors */ sclx = XSCALE / 100.0; scly = YSCALE / 100.0; if (ROUGH) sclz = -ROUGH / 100.0; else rscale = sclz = -0.0001; /* if rough=0 make it very flat but plot * something */ /* aspect ratio calculation - assume screen is 4 x 3 */ aspect = (double) xdots *.75 / (double) ydots; if (SPHERE == FALSE) /* skip this slow stuff in sphere case */ { /*********************************************************************/ /* What is done here is to create a single matrix, m, which has */ /* scale, rotation, and shift all combined. This allows us to use */ /* a single matrix to transform any point. Additionally, we create */ /* two perspective vectors. */ /* */ /* Start with a unit matrix. Add scale and rotation. Then calculate */ /* the perspective vectors. Finally add enough translation to center */ /* the final image plus whatever shift the user has set. */ /*********************************************************************/ /* start with identity */ identity(m); identity(lightm); /* translate so origin is in center of box, so that when we rotate */ /* it, we do so through the center */ trans((double) xdots / (-2.0), (double) ydots / (-2.0), (double) zcoord / (-2.0), m); trans((double) xdots / (-2.0), (double) ydots / (-2.0), (double) zcoord / (-2.0), lightm); /* apply scale factors */ scale(sclx, scly, sclz, m); scale(sclx, scly, sclz, lightm); /* rotation values - converting from degrees to radians */ xval = XROT / 57.29577; yval = YROT / 57.29577; zval = ZROT / 57.29577; if (RAY) { xval = yval = zval = 0; } xrot(xval, m); xrot(xval, lightm); yrot(yval, m); yrot(yval, lightm); zrot(zval, m); zrot(zval, lightm); /* Find values of translation that make all x,y,z negative */ /* m current matrix */ /* 0 means don't show box */ /* returns minimum and maximum values of x,y,z in fractal */ corners(m, 0, &xmin, &ymin, &zmin, &xmax, &ymax, &zmax); } /* perspective 3D vector - lview[2] == 0 means no perspective */ /* set perspective flag */ persp = 0; if (ZVIEWER != 0) { persp = 1; if (ZVIEWER < 80) /* force float */ usr_floatflag |= 2; /* turn on second bit */ } /* set up view vector, and put viewer in center of screen */ lview[0] = xdots >> 1; lview[1] = ydots >> 1; /* z value of user's eye - should be more negative than extreme negative * part of image */ if (SPHERE) /* sphere case */ lview[2] = -(long) ((double) ydots * (double) ZVIEWER / 100.0); else /* non-sphere case */ lview[2] = (long) ((zmin - zmax) * (double) ZVIEWER / 100.0); view[0] = lview[0]; view[1] = lview[1]; view[2] = lview[2]; lview[0] = lview[0] << 16; lview[1] = lview[1] << 16; lview[2] = lview[2] << 16; if (SPHERE == FALSE) /* sphere skips this */ { /* translate back exactly amount we translated earlier plus enough to * center image so maximum values are non-positive */ trans(((double) xdots - xmax - xmin) / 2, ((double) ydots - ymax - ymin) / 2, -zmax, m); /* Keep the box centered and on screen regardless of shifts */ trans(((double) xdots - xmax - xmin) / 2, ((double) ydots - ymax - ymin) / 2, -zmax, lightm); trans((double) (xshift), (double) (-yshift), 0.0, m); /* matrix m now contains ALL those transforms composed together !! * convert m to long integers shifted 16 bits */ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) llm[i][j] = (long) (m[i][j] * 65536.0); } else /* sphere stuff goes here */ { /* Sphere is on side - north pole on right. Top is -90 degrees * latitude; bottom 90 degrees */ /* Map X to this LATITUDE range */ theta1 = (float) (THETA1 * PI / 180.0); theta2 = (float) (THETA2 * PI / 180.0); /* Map Y to this LONGITUDE range */ phi1 = (float) (PHI1 * PI / 180.0); phi2 = (float) (PHI2 * PI / 180.0); theta = theta1; /*********************************************************************/ /* Thanks to Hugh Bray for the following idea: when calculating */ /* a table of evenly spaced sines or cosines, only a few initial */ /* values need be calculated, and the remaining values can be */ /* gotten from a derivative of the sine/cosine angle sum formula */ /* at the cost of one multiplication and one addition per value! */ /* */ /* This idea is applied once here to get a complete table for */ /* latitude, and near the bottom of this routine to incrementally */ /* calculate longitude. */ /* */ /* Precalculate 2*cos(deltaangle), sin(start) and sin(start+delta). */ /* Then apply recursively: */ /* sin(angle+2*delta) = sin(angle+delta) * 2cosdelta - sin(angle) */ /* */ /* Similarly for cosine. Neat! */ /*********************************************************************/ deltatheta = (float) (theta2 - theta1) / (float) linelen; /* initial sin,cos theta */ sinthetaarray[0] = (float) sin((double) theta); costhetaarray[0] = (float) cos((double) theta); sinthetaarray[1] = (float) sin((double) (theta + deltatheta)); costhetaarray[1] = (float) cos((double) (theta + deltatheta)); /* sin,cos delta theta */ twocosdeltatheta = (float) (2.0 * cos((double) deltatheta)); /* build table of other sin,cos with trig identity */ for (i = 2; i < (int) linelen; i++) { sinthetaarray[i] = sinthetaarray[i - 1] * twocosdeltatheta - sinthetaarray[i - 2]; costhetaarray[i] = costhetaarray[i - 1] * twocosdeltatheta - costhetaarray[i - 2]; } /* now phi - these calculated as we go - get started here */ deltaphi = (float) (phi2 - phi1) / (float) height; /* initial sin,cos phi */ sinphi = oldsinphi1 = (float) sin((double) phi1); cosphi = oldcosphi1 = (float) cos((double) phi1); oldsinphi2 = (float) sin((double) (phi1 + deltaphi)); oldcosphi2 = (float) cos((double) (phi1 + deltaphi)); /* sin,cos delta phi */ twocosdeltaphi = (float) (2.0 * cos((double) deltaphi)); /* affects how rough planet terrain is */ if (ROUGH) rscale = .3 * ROUGH / 100.0; /* radius of planet */ R = (double) (ydots) / 2; /* precalculate factor */ rXrscale = R * rscale; sclz = sclx = scly = RADIUS / 100.0; /* Need x,y,z for RAY */ /* adjust x scale factor for aspect */ sclx *= aspect; /* precalculation factor used in sphere calc */ Rfactor = rscale * R / (double) zcoord; if (persp) /* precalculate fudge factor */ { double radius; double zview; double angle; xcenter = xcenter << 16; ycenter = ycenter << 16; Rfactor *= 65536.0; R *= 65536.0; /* calculate z cutoff factor attempt to prevent out-of-view surfaces * from being written */ zview = -(long) ((double) ydots * (double) ZVIEWER / 100.0); radius = (double) (ydots) / 2; angle = atan(-radius / (zview + radius)); zcutoff = -radius - sin(angle) * radius; zcutoff *= 1.1; /* for safety */ zcutoff *= 65536L; } } /* set fill plot function */ if (FILLTYPE != 3) fillplot = interpcolor; else { fillplot = clipcolor; if (transparent[0] || transparent[1]) /* If transparent colors are set */ fillplot = T_clipcolor;/* Use the transparent plot function */ } /* Both Sphere and Normal 3D */ direct[0] = light_direction[0] = XLIGHT; direct[1] = light_direction[1] = -YLIGHT; direct[2] = light_direction[2] = ZLIGHT; /* Needed because sclz = -ROUGH/100 and light_direction is transformed in * FILLTYPE 6 but not in 5. */ if (FILLTYPE == 5) direct[2] = light_direction[2] = -ZLIGHT; if (FILLTYPE == 6) /* transform light direction */ { /* Think of light direction as a vector with tail at (0,0,0) and head * at (light_direction). We apply the transformation to BOTH head and * tail and take the difference */ v[0] = 0.0; v[1] = 0.0; v[2] = 0.0; vmult(v, m, v); vmult(light_direction, m, light_direction); for (i = 0; i < 3; i++) light_direction[i] -= v[i]; } normalize_vector(light_direction); if (preview && showbox) { normalize_vector(direct); /* move light vector to be more clear with grey scale maps */ origin[0] = (3 * xdots) / 16; origin[1] = (3 * ydots) / 4; if (FILLTYPE == 6) origin[1] = (11 * ydots) / 16; origin[2] = 0.0; v_length = min(xdots, ydots) / 2; if (persp && ZVIEWER <= P) v_length *= (long) (P + 600) / ((long) (ZVIEWER + 600) * 2); /* Set direct[] to point from origin[] in direction of untransformed * light_direction (direct[]). */ for (i = 0; i < 3; i++) direct[i] = origin[i] + direct[i] * v_length; /* center light box */ for (i = 0; i < 2; i++) { tmp[i] = (direct[i] - origin[i]) / 2; origin[i] -= tmp[i]; direct[i] -= tmp[i]; } /* Draw light source vector and box containing it, draw_light_box will * transform them if necessary. */ draw_light_box(origin, direct, lightm); /* draw box around original field of view to help visualize effect of * rotations 1 means show box - xmin etc. do nothing here */ if (!SPHERE) corners(m, 1, &xmin, &ymin, &zmin, &xmax, &ymax, &zmax); } /* bad has values caught by clipping */ f_bad.x = bad.x = bad_value; f_bad.y = bad.y = bad_value; f_bad.color = bad.color = bad_value; for (i = 0; i < (int) linelen; i++) { lastrow[i] = bad; f_lastrow[i] = f_bad; } got_status = 3; return (0); } /* end of once-per-image intializations */ /* This pragma prevents optimizer failure in MSC/C++ 7.0. Program compiles ok without pragma, but error message is real ugly, paraphrasing loosely, something like "optimizer screwed up big time, call Bill Gates collect ... (Note: commented out pragma because we removed the compiler "/Og" option in MAKEFRACT.BAT - left these notes as a warning... */ #ifdef _MSC_VER #if (_MSC_VER >= 600) /* #pragma optimize( "g", off ) */ #endif #endif static int line3dmem(void) { /*********************************************************************/ /* Memory allocation - assumptions - a 64K segment starting at */ /* extraseg has been grabbed. It may have other purposes elsewhere, */ /* but it is assumed that it is totally free for use here. Our */ /* strategy is to assign all the far pointers needed here to various*/ /* spots in the extra segment, depending on the pixel dimensions of */ /* the video mode, and check whether we have run out. There is */ /* basically one case where the extra segment is not big enough */ /* -- SPHERE mode with a fill type that uses putatriangle() (array */ /* minmax_x) at the largest legal resolution of MAXPIXELSxMAXPIXELS */ /* or thereabouts. In that case we use farmemalloc to grab memory */ /* for minmax_x. This memory is never freed. */ /*********************************************************************/ long check_extra; /* keep track ofd extraseg array use */ /* lastrow stores the previous row of the original GIF image for the purpose of filling in gaps with triangle procedure */ /* first 8k of extraseg now used in decoder TW 3/95 */ lastrow = MK_FP(extraseg, 0); check_extra = sizeof(*lastrow) * xdots; if (SPHERE) { sinthetaarray = (float far *) (lastrow + xdots); check_extra += sizeof(*sinthetaarray) * xdots; costhetaarray = (float far *) (sinthetaarray + xdots); check_extra += sizeof(*costhetaarray) * xdots; f_lastrow = (struct f_point far *) (costhetaarray + xdots); } else f_lastrow = (struct f_point far *) (lastrow + xdots); check_extra += sizeof(*f_lastrow) * (xdots); if (pot16bit) { fraction = (BYTE far *) (f_lastrow + xdots); check_extra += sizeof(*fraction) * xdots; } minmax_x = (struct minmax *) NULL; /* these fill types call putatriangle which uses minmax_x */ if (FILLTYPE == 2 || FILLTYPE == 3 || FILLTYPE == 5 || FILLTYPE == 6) { /* end of arrays if we use extra segement */ check_extra += sizeof(struct minmax) * ydots; if (check_extra > (1L << 16)) /* run out of extra segment? */ { static FCODE msg[] = {"farmemalloc minmax"}; static struct minmax far *got_mem = NULL; if(debugflag == 2222) stopmsg(0,msg); /* not using extra segment so decrement check_extra */ check_extra -= sizeof(struct minmax) * ydots; if (got_mem == NULL) got_mem = (struct minmax far *) (farmemalloc(OLDMAXPIXELS * sizeof(struct minmax))); if (got_mem) minmax_x = got_mem; else return (-1); } else /* ok to use extra segment */ { if (pot16bit) minmax_x = (struct minmax far *) (fraction + xdots); else minmax_x = (struct minmax far *) (f_lastrow + xdots); } } if (debugflag == 2222 || check_extra > (1L << 16)) { char tmpmsg[70]; static FCODE extramsg[] = {" of extra segment"}; #ifndef XFRACT sprintf(tmpmsg, "used %ld%Fs", check_extra, (char far *)extramsg); #else sprintf(tmpmsg, "used %ld%s", check_extra, extramsg); #endif stopmsg(4, tmpmsg); } return(0); } #ifdef _MSC_VER #if (_MSC_VER >= 600) #pragma optimize( "g", on ) #endif #endif xfractint-20.4.10.orig/common/fractalb.c0000644000000000000000000010360611064332143014722 0ustar /* ----------------------------------------------------------------- This file contains the "big number" high precision versions of the fractal routines. -------------------------------------------------------------------- */ #include #include #ifdef __TURBOC__ #include #elif !defined(__386BSD__) #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #include "fractype.h" int bf_math = 0; double b_const; #if (_MSC_VER >= 700) #pragma code_seg ("bigsetup_text") /* place following in an overlay */ #endif #ifdef DEBUG /**********************************************************************/ void show_var_bn(char *s, bn_t n) { char msg[200]; strcpy(msg,s); strcat(msg," "); bntostr(msg+strlen(s),40,n); msg[79] = 0; stopmsg(0,(char far *)msg); } void showcornersdbl(char *s) { char msg[400]; sprintf(msg,"%s\n\ xxmin= %.20f xxmax= %.20f\n\ yymin= %.20f yymax= %.20f\n\ xx3rd= %.20f yy3rd= %.20f\n\ delxx= %.20Lf delyy= %.20Lf\n\ delx2= %.20Lf dely2= %.20Lf",s,xxmin,xxmax,yymin,yymax,xx3rd,yy3rd, delxx, delyy,delxx2, delyy2); if(stopmsg(0,msg)==-1) goodbye(); } /* show floating point and bignumber corners */ void showcorners(char *s) { int dec=20; char msg[100],msg1[100],msg3[100]; bntostr(msg,dec,bnxmin); sprintf(msg1,"bnxmin=%s\nxxmin= %.20f\n\n",msg,xxmin); strcpy(msg3,s); strcat(msg3,"\n"); strcat(msg3,msg1); bntostr(msg,dec,bnxmax); sprintf(msg1,"bnxmax=%s\nxxmax= %.20f\n\n",msg,xxmax); strcat(msg3,msg1); bntostr(msg,dec,bnymin); sprintf(msg1,"bnymin=%s\nyymin= %.20f\n\n",msg,yymin); strcat(msg3,msg1); bntostr(msg,dec,bnymax); sprintf(msg1,"bnymax=%s\nyymax= %.20f\n\n",msg,yymax); strcat(msg3,msg1); bntostr(msg,dec,bnx3rd); sprintf(msg1,"bnx3rd=%s\nxx3rd= %.20f\n\n",msg,xx3rd); strcat(msg3,msg1); bntostr(msg,dec,bny3rd); sprintf(msg1,"bny3rd=%s\nyy3rd= %.20f\n\n",msg,yy3rd); strcat(msg3,msg1); if(stopmsg(0,msg3)==-1) goodbye(); } /* show globals */ void showbfglobals(char *s) { char msg[300]; sprintf(msg, "%s\n\ bnstep=%d bnlength=%d intlength=%d rlength=%d padding=%d\n\ shiftfactor=%d decimals=%d bflength=%d rbflength=%d \n\ bfdecimals=%d ", s, bnstep, bnlength, intlength, rlength, padding, shiftfactor, decimals, bflength, rbflength, bfdecimals); if(stopmsg(0,msg)==-1) goodbye(); } void showcornersbf(char *s) { int dec=decimals; char msg[100],msg1[100],msg3[600]; if(dec > 20) dec = 20; bftostr(msg,dec,bfxmin); sprintf(msg1,"bfxmin=%s\nxxmin= %.20f decimals %d bflength %d\n\n", msg,xxmin,decimals,bflength); strcpy(msg3,s); strcat(msg3,"\n"); strcat(msg3,msg1); bftostr(msg,dec,bfxmax); sprintf(msg1,"bfxmax=%s\nxxmax= %.20f\n\n",msg,xxmax); strcat(msg3,msg1); bftostr(msg,dec,bfymin); sprintf(msg1,"bfymin=%s\nyymin= %.20f\n\n",msg,yymin); strcat(msg3,msg1); bftostr(msg,dec,bfymax); sprintf(msg1,"bfymax=%s\nyymax= %.20f\n\n",msg,yymax); strcat(msg3,msg1); bftostr(msg,dec,bfx3rd); sprintf(msg1,"bfx3rd=%s\nxx3rd= %.20f\n\n",msg,xx3rd); strcat(msg3,msg1); bftostr(msg,dec,bfy3rd); sprintf(msg1,"bfy3rd=%s\nyy3rd= %.20f\n\n",msg,yy3rd); strcat(msg3,msg1); if(stopmsg(0,msg3)==-1) goodbye(); } void showcornersbfs(char *s) { int dec=20; char msg[100],msg1[100],msg3[500]; bftostr(msg,dec,bfsxmin); sprintf(msg1,"bfsxmin=%s\nxxmin= %.20f\n\n",msg,xxmin); strcpy(msg3,s); strcat(msg3,"\n"); strcat(msg3,msg1); bftostr(msg,dec,bfsxmax); sprintf(msg1,"bfsxmax=%s\nxxmax= %.20f\n\n",msg,xxmax); strcat(msg3,msg1); bftostr(msg,dec,bfsymin); sprintf(msg1,"bfsymin=%s\nyymin= %.20f\n\n",msg,yymin); strcat(msg3,msg1); bftostr(msg,dec,bfsymax); sprintf(msg1,"bfsymax=%s\nyymax= %.20f\n\n",msg,yymax); strcat(msg3,msg1); bftostr(msg,dec,bfsx3rd); sprintf(msg1,"bfsx3rd=%s\nxx3rd= %.20f\n\n",msg,xx3rd); strcat(msg3,msg1); bftostr(msg,dec,bfsy3rd); sprintf(msg1,"bfsy3rd=%s\nyy3rd= %.20f\n\n",msg,yy3rd); strcat(msg3,msg1); if(stopmsg(0,msg3)==-1) goodbye(); } void show_two_bf(char *s1,bf_t t1,char *s2, bf_t t2, int digits) { char msg1[200],msg2[200], msg3[400]; bftostr_e(msg1,digits,t1); bftostr_e(msg2,digits,t2); sprintf(msg3,"\n%s->%s\n%s->%s",s1,msg1,s2,msg2); if(stopmsg(0,msg3)==-1) goodbye(); } void show_three_bf(char *s1,bf_t t1,char *s2, bf_t t2, char *s3, bf_t t3, int digits) { char msg1[200],msg2[200], msg3[200], msg4[600]; bftostr_e(msg1,digits,t1); bftostr_e(msg2,digits,t2); bftostr_e(msg3,digits,t3); sprintf(msg4,"\n%s->%s\n%s->%s\n%s->%s",s1,msg1,s2,msg2,s3,msg3); if(stopmsg(0,msg4)==-1) goodbye(); } /* for aspect ratio debugging */ void showaspect(char *s) { bf_t bt1,bt2,aspect; char msg[100],str[100]; int saved; saved = save_stack(); bt1 = alloc_stack(rbflength+2); bt2 = alloc_stack(rbflength+2); aspect = alloc_stack(rbflength+2); sub_bf(bt1,bfxmax,bfxmin); sub_bf(bt2,bfymax,bfymin); div_bf(aspect,bt2,bt1); bftostr(str,10,aspect); sprintf(msg,"aspect %s\nfloat %13.10f\nbf %s\n\n", s, (yymax-yymin)/(xxmax-xxmin), str); if(stopmsg(0,msg)==-1) goodbye(); restore_stack(saved); } /* compare a double and bignumber */ void comparevalues(char *s, LDBL x, bn_t bnx) { int dec=40; char msg[100],msg1[100]; bntostr(msg,dec,bnx); sprintf(msg1,"%s\nbignum=%s\ndouble=%.20Lf\n\n",s,msg,x); if(stopmsg(0,msg1)==-1) goodbye(); } /* compare a double and bignumber */ void comparevaluesbf(char *s, LDBL x, bf_t bfx) { int dec=40; char msg[300],msg1[300]; bftostr_e(msg,dec,bfx); sprintf(msg1,"%s\nbignum=%s\ndouble=%.20Lf\n\n",s,msg,x); if(stopmsg(0,msg1)==-1) goodbye(); } /**********************************************************************/ void show_var_bf(char *s, bf_t n) { char msg[200]; strcpy(msg,s); strcat(msg," "); bftostr_e(msg+strlen(s),40,n); msg[79] = 0; if(stopmsg(0,msg)==-1) goodbye(); } #endif void bfcornerstofloat(void) { int i; if(bf_math) { xxmin = (double)bftofloat(bfxmin); yymin = (double)bftofloat(bfymin); xxmax = (double)bftofloat(bfxmax); yymax = (double)bftofloat(bfymax); xx3rd = (double)bftofloat(bfx3rd); yy3rd = (double)bftofloat(bfy3rd); } for(i=0;i= 700) #pragma code_seg ( ) /* back to normal segment */ #endif /* -------------------------------------------------------------------- */ /* Bignumber Bailout Routines */ /* -------------------------------------------------------------------- */ /* mandel_bntoint() can only be used for intlength of 1 */ #define mandel_bntoint(n) (*(n + bnlength - 1)) /* assumes intlength of 1 */ /* Note: */ /* No need to set magnitude */ /* as color schemes that need it calculate it later. */ int near bnMODbailout() { long longmagnitude; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); add_bn(bntmp, bntmpsqrx+shiftfactor, bntmpsqry+shiftfactor); longmagnitude = bntoint(bntmp); /* works with any fractal type */ if (longmagnitude >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return 0; } int near bnREALbailout() { long longtempsqrx; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); longtempsqrx = bntoint(bntmpsqrx+shiftfactor); if (longtempsqrx >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return 0; } int near bnIMAGbailout() { long longtempsqry; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); longtempsqry = bntoint(bntmpsqry+shiftfactor); if (longtempsqry >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return(0); } int near bnORbailout() { long longtempsqrx, longtempsqry; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); longtempsqrx = bntoint(bntmpsqrx+shiftfactor); longtempsqry = bntoint(bntmpsqry+shiftfactor); if(longtempsqrx >= (long)rqlim || longtempsqry >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return(0); } int near bnANDbailout() { long longtempsqrx, longtempsqry; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); longtempsqrx = bntoint(bntmpsqrx+shiftfactor); longtempsqry = bntoint(bntmpsqry+shiftfactor); if(longtempsqrx >= (long)rqlim && longtempsqry >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return(0); } int near bnMANHbailout() { long longtempmag; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); /* note: in next five lines, bnold is just used as a temporary variable */ abs_bn(bnold.x,bnnew.x); abs_bn(bnold.y,bnnew.y); add_bn(bntmp, bnold.x, bnold.y); square_bn(bnold.x, bntmp); longtempmag = bntoint(bnold.x+shiftfactor); if(longtempmag >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return(0); } int near bnMANRbailout() { long longtempmag; square_bn(bntmpsqrx, bnnew.x); square_bn(bntmpsqry, bnnew.y); add_bn(bntmp, bnnew.x, bnnew.y); /* don't need abs since we square it next */ /* note: in next two lines, bnold is just used as a temporary variable */ square_bn(bnold.x, bntmp); longtempmag = bntoint(bnold.x+shiftfactor); if(longtempmag >= (long)rqlim) return 1; copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); return(0); } int near bfMODbailout() { LDBL doublemagnitude; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); add_bf(bftmp, bftmpsqrx, bftmpsqry); doublemagnitude = bftofloat(bftmp); if (doublemagnitude >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return 0; } int near bfREALbailout() { LDBL doubletempsqrx; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); doubletempsqrx = bftofloat(bftmpsqrx); if (doubletempsqrx >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return 0; } int near bfIMAGbailout() { LDBL doubletempsqry; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); doubletempsqry = bftofloat(bftmpsqry); if (doubletempsqry >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return(0); } int near bfORbailout() { LDBL doubletempsqrx, doubletempsqry; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); doubletempsqrx = bftofloat(bftmpsqrx); doubletempsqry = bftofloat(bftmpsqry); if(doubletempsqrx >= rqlim || doubletempsqry >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return(0); } int near bfANDbailout() { LDBL doubletempsqrx, doubletempsqry; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); doubletempsqrx = bftofloat(bftmpsqrx); doubletempsqry = bftofloat(bftmpsqry); if(doubletempsqrx >= rqlim && doubletempsqry >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return(0); } int near bfMANHbailout() { LDBL doubletempmag; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); /* note: in next five lines, bfold is just used as a temporary variable */ abs_bf(bfold.x,bfnew.x); abs_bf(bfold.y,bfnew.y); add_bf(bftmp, bfold.x, bfold.y); square_bf(bfold.x, bftmp); doubletempmag = bftofloat(bfold.x); if(doubletempmag >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return(0); } int near bfMANRbailout() { LDBL doubletempmag; square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); add_bf(bftmp, bfnew.x, bfnew.y); /* don't need abs since we square it next */ /* note: in next two lines, bfold is just used as a temporary variable */ square_bf(bfold.x, bftmp); doubletempmag = bftofloat(bfold.x); if(doubletempmag >= rqlim) return 1; copy_bf(bfold.x, bfnew.x); copy_bf(bfold.y, bfnew.y); return(0); } #if (_MSC_VER >= 700) #pragma code_seg ("bigsetup_text") /* place following in an overlay */ #endif int MandelbnSetup() { /* this should be set up dynamically based on corners */ bn_t bntemp1, bntemp2; int saved; saved = save_stack(); bntemp1 = alloc_stack(bnlength); bntemp2 = alloc_stack(bnlength); bftobn(bnxmin,bfxmin); bftobn(bnxmax,bfxmax); bftobn(bnymin,bfymin); bftobn(bnymax,bfymax); bftobn(bnx3rd,bfx3rd); bftobn(bny3rd,bfy3rd); bf_math = BIGNUM; /* bnxdel = (bnxmax - bnx3rd)/(xdots-1) */ sub_bn(bnxdel, bnxmax, bnx3rd); div_a_bn_int(bnxdel, (U16)(xdots - 1)); /* bnydel = (bnymax - bny3rd)/(ydots-1) */ sub_bn(bnydel, bnymax, bny3rd); div_a_bn_int(bnydel, (U16)(ydots - 1)); /* bnxdel2 = (bnx3rd - bnxmin)/(ydots-1) */ sub_bn(bnxdel2, bnx3rd, bnxmin); div_a_bn_int(bnxdel2, (U16)(ydots - 1)); /* bnydel2 = (bny3rd - bnymin)/(xdots-1) */ sub_bn(bnydel2, bny3rd, bnymin); div_a_bn_int(bnydel2, (U16)(xdots - 1)); abs_bn(bnclosenuff,bnxdel); if(cmp_bn(abs_bn(bntemp1,bnxdel2),bnclosenuff) > 0) copy_bn(bnclosenuff,bntemp1); if(cmp_bn(abs_bn(bntemp1,bnydel),abs_bn(bntemp2,bnydel2)) > 0) { if(cmp_bn(bntemp1,bnclosenuff) > 0) copy_bn(bnclosenuff,bntemp1); } else if(cmp_bn(bntemp2,bnclosenuff) > 0) copy_bn(bnclosenuff,bntemp2); { int t; t = abs(periodicitycheck); while(t--) half_a_bn(bnclosenuff); } switch (fractype) { case JULIAFP: bftobn(bnparm.x, bfparms[0]); bftobn(bnparm.y, bfparms[1]); break; case FPMANDELZPOWER: c_exp = (int)param[2]; init_big_pi(); if((double)c_exp == param[2] && (c_exp & 1)) /* odd exponents */ symmetry = XYAXIS_NOPARM; if(param[3] != 0) symmetry = NOSYM; break; case FPJULIAZPOWER: c_exp = (int)param[2]; init_big_pi(); bftobn(bnparm.x, bfparms[0]); bftobn(bnparm.y, bfparms[1]); if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] ) symmetry = NOSYM; break; case DIVIDEBROT5: init_big_pi(); c_exp = -((int)param[0] - 2); /* use negative here so only need it once */ b_const = param[1] + 0.00000000000000000001; break; } /* at the present time, parameters are kept in float, but want to keep the arbitrary precision logic intact. The next two lines, if used, would disguise any breaking of the arbitrary precision logic */ /* floattobn(bnparm.x,param[0]); floattobn(bnparm.y,param[1]); */ restore_stack(saved); return (1); } int MandelbfSetup() { /* this should be set up dynamically based on corners */ bf_t bftemp1, bftemp2; int saved; saved = save_stack(); bftemp1 = alloc_stack(bflength+2); bftemp2 = alloc_stack(bflength+2); bf_math = BIGFLT; /* bfxdel = (bfxmax - bfx3rd)/(xdots-1) */ sub_bf(bfxdel, bfxmax, bfx3rd); div_a_bf_int(bfxdel, (U16)(xdots - 1)); /* bfydel = (bfymax - bfy3rd)/(ydots-1) */ sub_bf(bfydel, bfymax, bfy3rd); div_a_bf_int(bfydel, (U16)(ydots - 1)); /* bfxdel2 = (bfx3rd - bfxmin)/(ydots-1) */ sub_bf(bfxdel2, bfx3rd, bfxmin); div_a_bf_int(bfxdel2, (U16)(ydots - 1)); /* bfydel2 = (bfy3rd - bfymin)/(xdots-1) */ sub_bf(bfydel2, bfy3rd, bfymin); div_a_bf_int(bfydel2, (U16)(xdots - 1)); abs_bf(bfclosenuff,bfxdel); if(cmp_bf(abs_bf(bftemp1,bfxdel2),bfclosenuff) > 0) copy_bf(bfclosenuff,bftemp1); if(cmp_bf(abs_bf(bftemp1,bfydel),abs_bf(bftemp2,bfydel2)) > 0) { if(cmp_bf(bftemp1,bfclosenuff) > 0) copy_bf(bfclosenuff,bftemp1); } else if(cmp_bf(bftemp2,bfclosenuff) > 0) copy_bf(bfclosenuff,bftemp2); { int t; t = abs(periodicitycheck); while(t--) half_a_bf(bfclosenuff); } c_exp = (int)param[2]; switch (fractype) { case JULIAFP: copy_bf(bfparm.x, bfparms[0]); copy_bf(bfparm.y, bfparms[1]); break; case FPMANDELZPOWER: init_big_pi(); if((double)c_exp == param[2] && (c_exp & 1)) /* odd exponents */ symmetry = XYAXIS_NOPARM; if(param[3] != 0) symmetry = NOSYM; break; case FPJULIAZPOWER: init_big_pi(); copy_bf(bfparm.x, bfparms[0]); copy_bf(bfparm.y, bfparms[1]); if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] ) symmetry = NOSYM; break; case DIVIDEBROT5: init_big_pi(); c_exp = -((int)param[0] - 2); /* use negative here so only need it once */ b_const = param[1] + 0.00000000000000000001; break; } restore_stack(saved); return (1); } #if (_MSC_VER >= 700) #pragma code_seg ( ) /* back to normal segment */ #endif int mandelbn_per_pixel() { /* parm.x = xxmin + col*delx + row*delx2 */ mult_bn_int(bnparm.x, bnxdel, (U16)col); mult_bn_int(bntmp, bnxdel2, (U16)row); add_a_bn(bnparm.x, bntmp); add_a_bn(bnparm.x, bnxmin); /* parm.y = yymax - row*dely - col*dely2; */ /* note: in next four lines, bnold is just used as a temporary variable */ mult_bn_int(bnold.x, bnydel, (U16)row); mult_bn_int(bnold.y, bnydel2, (U16)col); add_a_bn(bnold.x, bnold.y); sub_bn(bnparm.y, bnymax, bnold.x); copy_bn(bnold.x, bnparm.x); copy_bn(bnold.y, bnparm.y); if((inside == BOF60 || inside == BOF61) && !nobof) { /* kludge to match "Beauty of Fractals" picture since we start Mandelbrot iteration with init rather than 0 */ floattobn(bnold.x,param[0]); /* initial pertubation of parameters set */ floattobn(bnold.y,param[1]); coloriter = -1; } else { floattobn(bnnew.x,param[0]); floattobn(bnnew.y,param[1]); add_a_bn(bnold.x,bnnew.x); add_a_bn(bnold.y,bnnew.y); } /* square has side effect - must copy first */ /* not true, square restores the sign after the call to unsafe_square */ /* copy_bn(bnnew.x, bnold.x); */ /* copy_bn(bnnew.y, bnold.y); */ /* Square these to rlength bytes of precision */ square_bn(bntmpsqrx, bnold.x); square_bn(bntmpsqry, bnold.y); return (1); /* 1st iteration has been done */ } int mandelbf_per_pixel() { /* parm.x = xxmin + col*delx + row*delx2 */ mult_bf_int(bfparm.x, bfxdel, (U16)col); mult_bf_int(bftmp, bfxdel2, (U16)row); add_a_bf(bfparm.x, bftmp); add_a_bf(bfparm.x, bfxmin); /* parm.y = yymax - row*dely - col*dely2; */ /* note: in next four lines, bfold is just used as a temporary variable */ mult_bf_int(bfold.x, bfydel, (U16)row); mult_bf_int(bfold.y, bfydel2, (U16)col); add_a_bf(bfold.x, bfold.y); sub_bf(bfparm.y, bfymax, bfold.x); copy_bf(bfold.x, bfparm.x); copy_bf(bfold.y, bfparm.y); if((inside == BOF60 || inside == BOF61) && !nobof) { /* kludge to match "Beauty of Fractals" picture since we start Mandelbrot iteration with init rather than 0 */ floattobf(bfold.x,param[0]); /* initial pertubation of parameters set */ floattobf(bfold.y,param[1]); coloriter = -1; } else { floattobf(bfnew.x,param[0]); floattobf(bfnew.y,param[1]); add_a_bf(bfold.x,bfnew.x); add_a_bf(bfold.y,bfnew.y); } /* square has side effect - must copy first */ /* not true, square saves a copy before call to unsafe_square */ /* copy_bf(bfnew.x, bfold.x); */ /* copy_bf(bfnew.y, bfold.y); */ /* Square these to rbflength bytes of precision */ square_bf(bftmpsqrx, bfold.x); square_bf(bftmpsqry, bfold.y); return (1); /* 1st iteration has been done */ } int juliabn_per_pixel() { /* old.x = xxmin + col*delx + row*delx2 */ mult_bn_int(bnold.x, bnxdel, (U16)col); mult_bn_int(bntmp, bnxdel2, (U16)row); add_a_bn(bnold.x, bntmp); add_a_bn(bnold.x, bnxmin); /* old.y = yymax - row*dely - col*dely2; */ /* note: in next four lines, bnnew is just used as a temporary variable */ mult_bn_int(bnnew.x, bnydel, (U16)row); mult_bn_int(bnnew.y, bnydel2, (U16)col); add_a_bn(bnnew.x, bnnew.y); sub_bn(bnold.y, bnymax, bnnew.x); /* square has side effect - must copy first */ /* not true, square restores the sign after the call to unsafe_square */ /* copy_bn(bnnew.x, bnold.x); */ /* copy_bn(bnnew.y, bnold.y); */ /* Square these to rlength bytes of precision */ square_bn(bntmpsqrx, bnold.x); square_bn(bntmpsqry, bnold.y); return (1); /* 1st iteration has been done */ } int juliabf_per_pixel() { /* old.x = xxmin + col*delx + row*delx2 */ mult_bf_int(bfold.x, bfxdel, (U16)col); mult_bf_int(bftmp, bfxdel2, (U16)row); add_a_bf(bfold.x, bftmp); add_a_bf(bfold.x, bfxmin); /* old.y = yymax - row*dely - col*dely2; */ /* note: in next four lines, bfnew is just used as a temporary variable */ mult_bf_int(bfnew.x, bfydel, (U16)row); mult_bf_int(bfnew.y, bfydel2, (U16)col); add_a_bf(bfnew.x, bfnew.y); sub_bf(bfold.y, bfymax, bfnew.x); /* square has side effect - must copy first */ /* not true, square saves a copy before call to unsafe_square */ /* copy_bf(bfnew.x, bfold.x); */ /* copy_bf(bfnew.y, bfold.y); */ /* Square these to rbflength bytes of precision */ square_bf(bftmpsqrx, bfold.x); square_bf(bftmpsqry, bfold.y); return (1); /* 1st iteration has been done */ } int dividebrot5bn_per_pixel() { /* parm.x = xxmin + col*delx + row*delx2 */ mult_bn_int(bnparm.x, bnxdel, (U16)col); mult_bn_int(bntmp, bnxdel2, (U16)row); add_a_bn(bnparm.x, bntmp); add_a_bn(bnparm.x, bnxmin); /* parm.y = yymax - row*dely - col*dely2; */ /* note: in next four lines, bnold is just used as a temporary variable */ mult_bn_int(bnold.x, bnydel, (U16)row); mult_bn_int(bnold.y, bnydel2, (U16)col); add_a_bn(bnold.x, bnold.y); sub_bn(bnparm.y, bnymax, bnold.x); clear_bn(bntmpsqrx); clear_bn(bntmpsqry); clear_bn(bnold.x); clear_bn(bnold.y); return (0); /* 1st iteration has NOT been done */ } int dividebrot5bf_per_pixel() { /* parm.x = xxmin + col*delx + row*delx2 */ mult_bf_int(bfparm.x, bfxdel, (U16)col); mult_bf_int(bftmp, bfxdel2, (U16)row); add_a_bf(bfparm.x, bftmp); add_a_bf(bfparm.x, bfxmin); /* parm.y = yymax - row*dely - col*dely2; */ /* note: in next four lines, bfold is just used as a temporary variable */ mult_bf_int(bfold.x, bfydel, (U16)row); mult_bf_int(bfold.y, bfydel2, (U16)col); add_a_bf(bfold.x, bfold.y); sub_bf(bfparm.y, bfymax, bfold.x); clear_bf(bftmpsqrx); clear_bf(bftmpsqry); clear_bf(bfold.x); clear_bf(bfold.y); return (0); /* 1st iteration has NOT been done */ } int JuliabnFractal() { /* Don't forget, with bn_t numbers, after multiplying or squaring */ /* you must shift over by shiftfactor to get the bn number. */ /* bntmpsqrx and bntmpsqry were previously squared before getting to */ /* this function, so they must be shifted. */ /* new.x = tmpsqrx - tmpsqry + parm.x; */ sub_a_bn(bntmpsqrx+shiftfactor, bntmpsqry+shiftfactor); add_bn(bnnew.x, bntmpsqrx+shiftfactor, bnparm.x); /* new.y = 2 * bnold.x * bnold.y + parm.y; */ mult_bn(bntmp, bnold.x, bnold.y); /* ok to use unsafe here */ double_a_bn(bntmp+shiftfactor); add_bn(bnnew.y, bntmp+shiftfactor, bnparm.y); return bignumbailout(); } int JuliabfFractal() { /* new.x = tmpsqrx - tmpsqry + parm.x; */ sub_a_bf(bftmpsqrx, bftmpsqry); add_bf(bfnew.x, bftmpsqrx, bfparm.x); /* new.y = 2 * bfold.x * bfold.y + parm.y; */ mult_bf(bftmp, bfold.x, bfold.y); /* ok to use unsafe here */ double_a_bf(bftmp); add_bf(bfnew.y, bftmp, bfparm.y); return bigfltbailout(); } int JuliaZpowerbnFractal() { _BNCMPLX parm2; int saved; saved = save_stack(); parm2.x = alloc_stack(bnlength); parm2.y = alloc_stack(bnlength); floattobn(parm2.x,param[2]); floattobn(parm2.y,param[3]); ComplexPower_bn(&bnnew,&bnold,&parm2); add_bn(bnnew.x,bnparm.x,bnnew.x+shiftfactor); add_bn(bnnew.y,bnparm.y,bnnew.y+shiftfactor); restore_stack(saved); return bignumbailout(); } int JuliaZpowerbfFractal() { _BFCMPLX parm2; int saved; saved = save_stack(); parm2.x = alloc_stack(bflength+2); parm2.y = alloc_stack(bflength+2); floattobf(parm2.x,param[2]); floattobf(parm2.y,param[3]); ComplexPower_bf(&bfnew,&bfold,&parm2); add_bf(bfnew.x,bfparm.x,bfnew.x); add_bf(bfnew.y,bfparm.y,bfnew.y); restore_stack(saved); return bigfltbailout(); } int DivideBrot5bnFractal() { _BNCMPLX bntmpnew, bnnumer, bnc_exp; bn_t tmp1, tmp2; int saved; saved = save_stack(); bntmpnew.x = alloc_stack(rlength); bntmpnew.y = alloc_stack(rlength); bnnumer.x = alloc_stack(rlength); bnnumer.y = alloc_stack(rlength); bnc_exp.x = alloc_stack(bnlength); bnc_exp.y = alloc_stack(bnlength); tmp1 = alloc_stack(bnlength); tmp2 = alloc_stack(rlength); /* bntmpsqrx and bntmpsqry were previously squared before getting to */ /* this function, so they must be shifted. */ /* sqr(z) */ /* bnnumer.x = bntmpsqrx - bntmpsqry; */ sub_bn(bnnumer.x, bntmpsqrx+shiftfactor, bntmpsqry+shiftfactor); /* bnnumer.y = 2 * bnold.x * bnold.y; */ mult_bn(tmp2, bnold.x, bnold.y); double_a_bn(tmp2+shiftfactor); copy_bn(bnnumer.y, tmp2+shiftfactor); /* z^(a) */ inttobn(bnc_exp.x, c_exp); clear_bn(bnc_exp.y); ComplexPower_bn(&bntmpnew, &bnold, &bnc_exp); /* then add b */ floattobn(tmp1, b_const); add_bn(bntmpnew.x, tmp1, bntmpnew.x+shiftfactor); /* need to shiftfactor bntmpnew.y */ copy_bn(tmp2, bntmpnew.y+shiftfactor); copy_bn(bntmpnew.y, tmp2); /* sqr(z)/(z^(a)+b) */ cplxdiv_bn(&bnnew, &bnnumer, &bntmpnew); add_a_bn(bnnew.x, bnparm.x); add_a_bn(bnnew.y, bnparm.y); restore_stack(saved); return bignumbailout(); } int DivideBrot5bfFractal() { _BFCMPLX bftmpnew, bfnumer, bfc_exp; bf_t tmp1; int saved; saved = save_stack(); bftmpnew.x = alloc_stack(rbflength+2); bftmpnew.y = alloc_stack(rbflength+2); bfnumer.x = alloc_stack(rbflength+2); bfnumer.y = alloc_stack(rbflength+2); bfc_exp.x = alloc_stack(bflength+2); bfc_exp.y = alloc_stack(bflength+2); tmp1 = alloc_stack(bflength+2); /* sqr(z) */ /* bfnumer.x = bftmpsqrx - bftmpsqry; */ sub_bf(bfnumer.x, bftmpsqrx, bftmpsqry); /* bfnumer.y = 2 * bfold.x * bfold.y; */ mult_bf(bfnumer.y, bfold.x, bfold.y); double_a_bf(bfnumer.y); /* z^(a) */ inttobf(bfc_exp.x, c_exp); clear_bf(bfc_exp.y); ComplexPower_bf(&bftmpnew, &bfold, &bfc_exp); /* then add b */ floattobf(tmp1, b_const); add_a_bf(bftmpnew.x, tmp1); /* sqr(z)/(z^(a)+b) */ cplxdiv_bf(&bfnew, &bfnumer, &bftmpnew); add_a_bf(bfnew.x, bfparm.x); add_a_bf(bfnew.y, bfparm.y); restore_stack(saved); return bigfltbailout(); } #if 0 /* the following is an example of how you can take advantage of the bn_t format to squeeze a little more precision out of the calculations. */ int JuliabnFractal() { int oldbnlength; bn_t mod; /* using partial precision multiplications */ /* bnnew.x = bntmpsqrx - bntmpsqry + bnparm.x; */ /* * Since tmpsqrx and tmpsqry where just calculated to rlength bytes of * precision, we might as well keep that extra precision in this next * subtraction. Therefore, use rlength as the length. */ oldbnlength = bnlength; bnlength = rlength; sub_a_bn(bntmpsqrx, bntmpsqry); bnlength = oldbnlength; /* * Now that bntmpsqry has been sutracted from bntmpsqrx, we need to treat * tmpsqrx as a single width bignumber, so shift to bntmpsqrx+shiftfactor. */ add_bn(bnnew.x, bntmpsqrx + shiftfactor, bnparm.x); /* new.y = 2 * bnold.x * bnold.y + old.y; */ /* Multiply bnold.x*bnold.y to rlength precision. */ mult_bn(bntmp, bnold.x, bnold.y); /* * Double bnold.x*bnold.y by shifting bits, including one of those bits * calculated in the previous mult_bn(). Therefore, use rlength. */ bnlength = rlength; double_a_bn(bntmp); bnlength = oldbnlength; /* Convert back to a single width bignumber and add bnparm.y */ add_bn(bnnew.y, bntmp + shiftfactor, bnparm.y); copy_bn(bnold.x, bnnew.x); copy_bn(bnold.y, bnnew.y); /* Square these to rlength bytes of precision */ square_bn(bntmpsqrx, bnold.x); square_bn(bntmpsqry, bnold.y); /* And add the full rlength precision to get those extra bytes */ bnlength = rlength; add_bn(bntmp, bntmpsqrx, bntmpsqry); bnlength = oldbnlength; mod = bntmp + (rlength) - (intlength << 1); /* where int part starts * after mult */ /* * equivalent to, but faster than, mod = bn_int(tmp+shiftfactor); */ if ((magnitude = *mod) >= rqlim) return (1); return (0); } #endif _CMPLX cmplxbntofloat(_BNCMPLX *s) { _CMPLX t; t.x = (double)bntofloat(s->x); t.y = (double)bntofloat(s->y); return(t); } _CMPLX cmplxbftofloat(_BFCMPLX *s) { _CMPLX t; t.x = (double)bftofloat(s->x); t.y = (double)bftofloat(s->y); return(t); } _BFCMPLX *cmplxlog_bf(_BFCMPLX *t, _BFCMPLX *s) { if (is_bf_zero(s->x) && is_bf_zero(s->y)) { clear_bf(t->x); clear_bf(t->y); } else { square_bf(t->x,s->x); square_bf(t->y,s->y); add_a_bf(t->x,t->y); ln_bf(t->x,t->x); half_a_bf(t->x); atan2_bf(t->y,s->y,s->x); } return(t); } _BFCMPLX *cplxmul_bf( _BFCMPLX *t, _BFCMPLX *x, _BFCMPLX *y) { bf_t tmp1; int saved; saved = save_stack(); tmp1 = alloc_stack(rbflength+2); mult_bf(t->x, x->x, y->x); mult_bf(t->y, x->y, y->y); sub_bf(t->x,t->x,t->y); mult_bf(tmp1, x->x, y->y); mult_bf(t->y, x->y, y->x); add_bf(t->y,tmp1,t->y); restore_stack(saved); return(t); } _BFCMPLX *cplxdiv_bf( _BFCMPLX *t, _BFCMPLX *x, _BFCMPLX *y) { bf_t tmp1, denom; int saved; saved = save_stack(); tmp1 = alloc_stack(rbflength+2); denom = alloc_stack(rbflength+2); square_bf(t->x, y->x); square_bf(t->y, y->y); add_bf(denom,t->x,t->y); if (is_bf_zero(denom)) { overflow = 1; } else { mult_bf(tmp1, x->x, y->x); mult_bf(t->x, x->y, y->y); add_bf(t->x,tmp1,t->x); div_bf(t->x, t->x, denom); mult_bf(tmp1, x->y, y->x); mult_bf(t->y, x->x, y->y); sub_bf(t->y,tmp1,t->y); div_bf(t->y, t->y, denom); } restore_stack(saved); return(t); } _BFCMPLX *ComplexPower_bf(_BFCMPLX *t, _BFCMPLX *xx, _BFCMPLX *yy) { _BFCMPLX tmp; bf_t e2x, siny, cosy; int saved; saved = save_stack(); e2x = alloc_stack(rbflength+2); siny = alloc_stack(rbflength+2); cosy = alloc_stack(rbflength+2); tmp.x = alloc_stack(rbflength+2); tmp.y = alloc_stack(rbflength+2); /* 0 raised to anything is 0 */ if (is_bf_zero(xx->x) && is_bf_zero(xx->y)) { clear_bf(t->x); clear_bf(t->y); } else { cmplxlog_bf(t, xx); cplxmul_bf(&tmp, t, yy); exp_bf(e2x,tmp.x); sincos_bf(siny,cosy,tmp.y); mult_bf(t->x, e2x, cosy); mult_bf(t->y, e2x, siny); } restore_stack(saved); return(t); } _BNCMPLX *cmplxlog_bn(_BNCMPLX *t, _BNCMPLX *s) { if (is_bn_zero(s->x) && is_bn_zero(s->y)) { clear_bn(t->x); clear_bn(t->y); } else { square_bn(t->x,s->x); square_bn(t->y,s->y); add_bn(t->x, t->x+shiftfactor,t->y+shiftfactor); ln_bn(t->x,t->x); half_a_bn(t->x); atan2_bn(t->y,s->y,s->x); } return(t); } _BNCMPLX *cplxmul_bn( _BNCMPLX *t, _BNCMPLX *x, _BNCMPLX *y) { bn_t tmp1; int saved; saved = save_stack(); tmp1 = alloc_stack(rlength); mult_bn(t->x, x->x, y->x); mult_bn(t->y, x->y, y->y); sub_bn(t->x,t->x+shiftfactor,t->y+shiftfactor); mult_bn(tmp1, x->x, y->y); mult_bn(t->y, x->y, y->x); add_bn(t->y,tmp1+shiftfactor,t->y+shiftfactor); restore_stack(saved); return(t); } _BNCMPLX *cplxdiv_bn( _BNCMPLX *t, _BNCMPLX *x, _BNCMPLX *y) { bn_t tmp1, tmp2, denom; int saved; saved = save_stack(); tmp1 = alloc_stack(rlength); tmp2 = alloc_stack(rlength); denom = alloc_stack(rlength); square_bn(tmp1, y->x); square_bn(tmp2, y->y); add_bn(denom,tmp1+shiftfactor,tmp2+shiftfactor); if (is_bn_zero(x->x) && is_bn_zero(x->y)) { clear_bn(t->x); clear_bn(t->y); } else if (is_bn_zero(denom)) { overflow = 1; } else { mult_bn(tmp1, x->x, y->x); mult_bn(t->x, x->y, y->y); add_bn(tmp2,tmp1+shiftfactor,t->x+shiftfactor); div_bn(t->x, tmp2, denom); mult_bn(tmp1, x->y, y->x); mult_bn(t->y, x->x, y->y); sub_bn(tmp2,tmp1+shiftfactor,t->y+shiftfactor); div_bn(t->y, tmp2, denom); } restore_stack(saved); return(t); } /* note: ComplexPower_bn() returns need to be +shiftfactor'ed */ _BNCMPLX *ComplexPower_bn(_BNCMPLX *t, _BNCMPLX *xx, _BNCMPLX *yy) { _BNCMPLX tmp; bn_t e2x, siny, cosy; int saved; saved = save_stack(); e2x = alloc_stack(rlength); siny = alloc_stack(rlength); cosy = alloc_stack(rlength); tmp.x = alloc_stack(rlength); tmp.y = alloc_stack(rlength); /* 0 raised to anything is 0 */ if (is_bn_zero(xx->x) && is_bn_zero(xx->y)) { clear_bn(t->x); clear_bn(t->y); } else { cmplxlog_bn(t, xx); cplxmul_bn(&tmp, t, yy); exp_bn(e2x,tmp.x); sincos_bn(siny,cosy,tmp.y); mult_bn(t->x, e2x, cosy); mult_bn(t->y, e2x, siny); } restore_stack(saved); return(t); } xfractint-20.4.10.orig/common/loadfdos.c0000644000000000000000000004246310150633601014740 0ustar /* loadfdos.c - subroutine of loadfile.c (read_overlay) which sets up video (mode, screen size). This module is linked as an overlay, should only be called from loadfile.c This code was split to a separate module to isolate the DOS only aspects of loading an image. get_video_mode should return with: return code 0 for ok, -1 for error or cancelled by user video parameters setup for the mainline, in the dos case this means setting initmode to video mode, based on this fractint.c will set up for and call setvideomode set viewwindow on if file going to be loaded into a view smaller than physical screen, in this case also set viewreduction, viewxdots, viewydots, and finalaspectratio set skipxdots and skipydots, to 0 if all pixels are to be loaded, to 1 for every 2nd pixel, 2 for every 3rd, etc In WinFract, at least initially, get_video_mode can do just the following: set overall image x & y dimensions (sxdots and sydots) to filexdots and fileydots (note that filecolors is the number of colors in the gif, not sure if that is of any use...) if current window smaller than new sxdots and sydots, use scroll bars, if larger perhaps reduce the window size? whatever set viewwindow to 0 (no need? it always is for now in windows vsn?) set finalaspectratio to .75 (ditto?) set skipxdots and skipydots to 0 return 0 */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" /* routines in this module */ #ifndef XFRACT static int vidcompare(VOIDCONSTPTR ,VOIDCONSTPTR ); static void format_item(int,char *); static int check_modekey(int,int); static void format_vid_inf(int i,char *err,char *buf); #endif static double vid_aspect(int tryxdots,int tryydots); struct vidinf { int entnum; /* videoentry subscript */ unsigned flags; /* flags for sort's compare, defined below */ }; /* defines for flags; done this way instead of bit union to ensure ordering; these bits represent the sort sequence for video mode list */ #define VI_EXACT 0x8000 /* unless the one and only exact match */ #define VI_NOKEY 512 /* if no function key assigned */ #define VI_DISK1 256 /* disk video and size not exact */ #define VI_SSMALL 128 /* screen smaller than file's screen */ #define VI_SBIG 64 /* screen bigger than file's screen */ #define VI_VSMALL 32 /* screen smaller than file's view */ #define VI_VBIG 16 /* screen bigger than file's view */ #define VI_CSMALL 8 /* mode has too few colors */ #define VI_CBIG 4 /* mode has excess colors */ #define VI_DISK2 2 /* disk video */ #define VI_ASPECT 1 /* aspect ratio bad */ #ifndef XFRACT static int vidcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2) { struct vidinf CONST *ptr1,*ptr2; ptr1 = (struct vidinf CONST *)p1; ptr2 = (struct vidinf CONST *)p2; if (ptr1->flags < ptr2->flags) return(-1); if (ptr1->flags > ptr2->flags) return(1); if (vidtbl[ptr1->entnum].keynum < vidtbl[ptr2->entnum].keynum) return(-1); if (vidtbl[ptr1->entnum].keynum > vidtbl[ptr2->entnum].keynum) return(1); if (ptr1->entnum < ptr2->entnum) return(-1); return(1); } static void format_vid_inf(int i,char *err,char *buf) { char kname[5]; far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i], sizeof(videoentry)); vidmode_keyname(videoentry.keynum,kname); sprintf(buf,"%-5s %-25s %-4s %5d %5d %3d %-25s", /* 78 chars */ kname, videoentry.name, err, videoentry.xdots, videoentry.ydots, videoentry.colors, videoentry.comment); videoentry.xdots = 0; /* so tab_display knows to display nothing */ } #endif static double vid_aspect(int tryxdots,int tryydots) { /* calc resulting aspect ratio for specified dots in current mode */ return (double)tryydots / (double)tryxdots * (double)videoentry.xdots / (double)videoentry.ydots * screenaspect; } #ifndef XFRACT static struct vidinf *vidptr; #endif int get_video_mode(struct fractal_info *info,struct ext_blk_3 *blk_3_info) { static FCODE o_hdg2[]={"key...name......................err...xdot..ydot.clr.comment.................."}; static FCODE o_warning[]={"\nWARNING: non-standard aspect ratio; loading will change your iew settings"}; static FCODE o_select_msg[]={"\ Select a video mode. Use the cursor keypad to move the pointer.\n\ Press ENTER for selected mode, or use a video mode function key.\n\ Press F1 for help, "}; char far *hdg2, far *warning, far *select_msg, far *ptr; struct vidinf vid[MAXVIDEOMODES]; int i,j; int gotrealmode; double ftemp,ftemp2; unsigned tmpflags; int tmpxdots,tmpydots; float tmpreduce; #ifndef XFRACT char *nameptr; int *attributes; int oldhelpmode; #endif VIDEOINFO *vident; /* save overlayed strings to extraseg memory */ ptr = (char far *)MK_FP(extraseg,ENDVID); /* ENDVID is to avoid videotable */ hdg2 = ptr; ptr += sizeof(o_hdg2); warning = ptr; ptr += sizeof(o_warning); select_msg = ptr; far_strcpy(hdg2,o_hdg2); far_strcpy(warning,o_warning); far_strcpy(select_msg,o_select_msg); initmode = -1; load_fractint_cfg(0); /* get fractint.cfg into *vidtbl (== extraseg) */ /* try to change any VESA entries to fit the loaded image size */ if (virtual && video_vram && initmode == -1) { unsigned long vram = (unsigned long)video_vram << 16, need = (unsigned long)info->xdots * info->ydots; if (need <= vram) { char over[25]; /* overwrite comments with original resolutions */ int bppx; /* bytesperpixel multiplier */ for (i = 0; i < vidtbllen; ++i) { vident = &vidtbl[i]; if (vident->dotmode%100 == 28 && vident->colors >= 256 && (info->xdots > vident->xdots || info->ydots > vident->ydots) && vram >= (unsigned long) (info->xdots < vident->xdots ? vident->xdots : info->xdots) * (info->ydots < vident->ydots ? vident->ydots : info->ydots) * ((bppx = vident->dotmode/1000) < 2 ? ++bppx : bppx)) { sprintf(over,"<-VIRTUAL! at %4u x %4u",vident->xdots,vident->ydots); far_strcpy((char far *)vident->comment,(char far *)over); if (info->xdots > vident->xdots) vident->xdots = info->xdots; if (info->ydots > vident->ydots) vident->ydots = info->ydots; } /* change entry to force VESA virtual scanline setup */ } } } /* try to find exact match for vid mode */ for (i = 0; i < vidtbllen; ++i) { vident = &vidtbl[i]; if (info->xdots == vident->xdots && info->ydots == vident->ydots && filecolors == vident->colors && info->videomodeax == vident->videomodeax && info->videomodebx == vident->videomodebx && info->videomodecx == vident->videomodecx && info->videomodedx == vident->videomodedx && info->dotmode%100 == vident->dotmode%100) { initmode = i; break; } } /* exit in makepar mode if no exact match of video mode in file */ if(*s_makepar == '\0' && initmode == -1) return(0); if (initmode == -1) /* try to find very good match for vid mode */ for (i = 0; i < vidtbllen; ++i) { vident = &vidtbl[i]; if (info->xdots == vident->xdots && info->ydots == vident->ydots && filecolors == vident->colors) { initmode = i; break; } } /* setup table entry for each vid mode, flagged for how well it matches */ for (i = 0; i < vidtbllen; ++i) { far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i], sizeof(videoentry)); tmpflags = VI_EXACT; if (videoentry.keynum == 0) tmpflags |= VI_NOKEY; if (info->xdots > videoentry.xdots || info->ydots > videoentry.ydots) tmpflags |= VI_SSMALL; else if (info->xdots < videoentry.xdots || info->ydots < videoentry.ydots) tmpflags |= VI_SBIG; if (filexdots > videoentry.xdots || fileydots > videoentry.ydots) tmpflags |= VI_VSMALL; else if (filexdots < videoentry.xdots || fileydots < videoentry.ydots) tmpflags |= VI_VBIG; if (filecolors > videoentry.colors) tmpflags |= VI_CSMALL; if (filecolors < videoentry.colors) tmpflags |= VI_CBIG; if (i == initmode) tmpflags -= VI_EXACT; if (videoentry.dotmode%100 == 11) { tmpflags |= VI_DISK2; if ((tmpflags & (VI_SBIG+VI_SSMALL+VI_VBIG+VI_VSMALL)) != 0) tmpflags |= VI_DISK1; } if (fileaspectratio != 0 && videoentry.dotmode%100 != 11 && (tmpflags & VI_VSMALL) == 0) { ftemp = vid_aspect(filexdots,fileydots); if ( ftemp < fileaspectratio * 0.98 || ftemp > fileaspectratio * 1.02) tmpflags |= VI_ASPECT; } vid[i].entnum = i; vid[i].flags = tmpflags; } if (fastrestore && !askvideo) initmode = adapter; #ifndef XFRACT gotrealmode = 0; if ((initmode < 0 || (askvideo && !initbatch)) && *s_makepar != '\0') { /* no exact match or (askvideo=yes and batch=no), and not in makepar mode, talk to user */ qsort(vid,vidtbllen,sizeof(vid[0]),vidcompare); /* sort modes */ attributes = (int *)&dstack[1000]; for (i = 0; i < vidtbllen; ++i) attributes[i] = 1; vidptr = &vid[0]; /* for format_item */ /* format heading */ if (info->info_id[0] == 'G') strcpy(temp1," Non-fractal GIF"); else { nameptr = curfractalspecific->name; if (*nameptr == '*') ++nameptr; if (display3d) nameptr = "3D Transform"; if ((!strcmp(nameptr,"formula")) || (!strcmp(nameptr,"lsystem")) || (!strncmp(nameptr,"ifs",3))) /* for ifs and ifs3d */ sprintf(temp1,"Type: %s -> %s",nameptr,blk_3_info->form_name); else sprintf(temp1,"Type: %s",nameptr); } sprintf((char *)dstack,"File: %-44s %d x %d x %d\n%-52s", readname,filexdots,fileydots,filecolors,temp1); if (info->info_id[0] != 'G') { if (save_system) strcat((char *)dstack,"WinFract "); sprintf(temp1,"v%d.%01d",save_release/100,(save_release%100)/10); if (save_release%100) { i = strlen(temp1); temp1[i] = (char)((save_release%10) + '0'); temp1[i+1] = 0; } if (save_system == 0 && save_release <= 1410) strcat(temp1," or earlier"); strcat((char *)dstack,temp1); } strcat((char *)dstack,"\n"); if (info->info_id[0] != 'G' && save_system == 0) if (initmode < 0) strcat((char *)dstack,"Saved in unknown video mode."); else { format_vid_inf(initmode,"",temp1); strcat((char *)dstack,temp1); } if (fileaspectratio != 0 && fileaspectratio != screenaspect) far_strcat((char *)dstack,warning); strcat((char *)dstack,"\n"); /* set up instructions */ far_strcpy(temp1,select_msg); if (info->info_id[0] != 'G') strcat(temp1,"TAB for fractal information, "); strcat(temp1,"ESCAPE to back out."); oldhelpmode = helpmode; helpmode = HELPLOADFILE; i = fullscreen_choice(0,(char *)dstack,hdg2,temp1,vidtbllen,NULL,attributes, 1,13,78,0,format_item,NULL,NULL,check_modekey); helpmode = oldhelpmode; if (i == -1) return(-1); if (i < 0) { /* returned -100 - videotable entry number */ initmode = -100 - i; gotrealmode = 1; } else initmode = vid[i].entnum; } #else initmode = 0; j = vidtbl[0].keynum; gotrealmode = 0; #endif if (gotrealmode == 0) { /* translate from temp table to permanent */ if ((j = vidtbl[i=initmode].keynum) != 0) { for (initmode = 0; initmode < MAXVIDEOTABLE-1; ++initmode) if (videotable[initmode].keynum == j) break; if (initmode >= MAXVIDEOTABLE-1) j = 0; } if (j == 0) /* mode has no key, add to reserved slot at end */ far_memcpy((char far *)&videotable[initmode=MAXVIDEOTABLE-1], (char far *)&vidtbl[i],sizeof(*vidtbl)); } /* ok, we're going to return with a video mode */ far_memcpy((char far *)&videoentry,(char far *)&videotable[initmode], sizeof(videoentry)); if (viewwindow && filexdots == videoentry.xdots && fileydots == videoentry.ydots) { /* pull image into a view window */ if (calc_status != 4) /* if not complete */ calc_status = 0; /* can't resume anyway */ if (viewxdots) { viewreduction = videoentry.xdots / viewxdots; viewxdots = viewydots = 0; /* easier to use auto reduction */ } viewreduction = (float)((int)(viewreduction + 0.5)); /* need integer value */ skipxdots = skipydots = (short)(viewreduction - 1); return(0); } skipxdots = skipydots = 0; /* set for no reduction */ if (videoentry.xdots < filexdots || videoentry.ydots < fileydots) { /* set up to load only every nth pixel to make image fit */ if (calc_status != 4) /* if not complete */ calc_status = 0; /* can't resume anyway */ skipxdots = skipydots = 1; while (skipxdots * videoentry.xdots < filexdots) ++skipxdots; while (skipydots * videoentry.ydots < fileydots) ++skipydots; i = j = 0; for(;;) { tmpxdots = (filexdots + skipxdots - 1) / skipxdots; tmpydots = (fileydots + skipydots - 1) / skipydots; if (fileaspectratio == 0 || videoentry.dotmode%100 == 11) break; /* reduce further if that improves aspect */ if ((ftemp = vid_aspect(tmpxdots,tmpydots)) > fileaspectratio) { if (j) break; /* already reduced x, don't reduce y */ ftemp2 = vid_aspect(tmpxdots,(fileydots+skipydots)/(skipydots+1)); if (ftemp2 < fileaspectratio && ftemp/fileaspectratio *0.9 <= fileaspectratio/ftemp2) break; /* further y reduction is worse */ ++skipydots; ++i; } else { if (i) break; /* already reduced y, don't reduce x */ ftemp2 = vid_aspect((filexdots+skipxdots)/(skipxdots+1),tmpydots); if (ftemp2 > fileaspectratio && fileaspectratio/ftemp *0.9 <= ftemp2/fileaspectratio) break; /* further x reduction is worse */ ++skipxdots; ++j; } } filexdots = tmpxdots; fileydots = tmpydots; --skipxdots; --skipydots; } if ((finalaspectratio = fileaspectratio) == 0) /* assume display correct */ finalaspectratio = (float)vid_aspect(filexdots,fileydots); if (finalaspectratio >= screenaspect-0.02 && finalaspectratio <= screenaspect+0.02) finalaspectratio = screenaspect; i = (int)(finalaspectratio * 1000.0 + 0.5); finalaspectratio = (float)(i/1000.0); /* chop precision to 3 decimals */ /* setup view window stuff */ viewwindow = viewxdots = viewydots = 0; if (filexdots != videoentry.xdots || fileydots != videoentry.ydots) { /* image not exactly same size as screen */ viewwindow = 1; ftemp = finalaspectratio * (double)videoentry.ydots / (double)videoentry.xdots / screenaspect; if (finalaspectratio <= screenaspect) { i = (int)((double)videoentry.xdots / (double)filexdots * 20.0 + 0.5); tmpreduce = (float)(i/20.0); /* chop precision to nearest .05 */ i = (int)((double)videoentry.xdots / tmpreduce + 0.5); j = (int)((double)i * ftemp + 0.5); } else { i = (int)((double)videoentry.ydots / (double)fileydots * 20.0 + 0.5); tmpreduce = (float)(i/20.0); /* chop precision to nearest .05 */ j = (int)((double)videoentry.ydots / tmpreduce + 0.5); i = (int)((double)j / ftemp + 0.5); } if (i != filexdots || j != fileydots) { /* too bad, must be explicit */ viewxdots = filexdots; viewydots = fileydots; } else viewreduction = tmpreduce; /* ok, this works */ } if (*s_makepar && !fastrestore && !initbatch && (fabs(finalaspectratio - screenaspect) > .00001 || viewxdots != 0)) { static FCODE msg[] = {"\ Warning: iew parameters are being set to non-standard values.\n\ Remember to reset them when finished with this image!"}; stopmsg(4,msg); } return(0); } #ifndef XFRACT static void format_item(int choice,char *buf) { char errbuf[10]; unsigned tmpflags; errbuf[0] = 0; tmpflags = vidptr[choice].flags; if (tmpflags & (VI_VSMALL+VI_CSMALL+VI_ASPECT)) strcat(errbuf,"*"); if (tmpflags & VI_VSMALL) strcat(errbuf,"R"); if (tmpflags & VI_CSMALL) strcat(errbuf,"C"); if (tmpflags & VI_ASPECT) strcat(errbuf,"A"); if (tmpflags & VI_VBIG) strcat(errbuf,"v"); if (tmpflags & VI_CBIG) strcat(errbuf,"c"); format_vid_inf(vidptr[choice].entnum,errbuf,buf); } static int check_modekey(int curkey,int choice) { int i; i=choice; /* avoid warning */ return (((i = check_vidmode_key(0,curkey)) >= 0) ? -100-i : 0); } #endif xfractint-20.4.10.orig/common/yourvid.c0000644000000000000000000001100010150633601014625 0ustar /* Roll-Your-Own video mode (DOTMODE 19) routines. Even if you don't have an assembler, you can add your own video-mode routines to FRACTINT by adding a video mode of the appropriate resolution to FRACTINT.CFG that uses dotmode 19 (which calls these routines to perform all the dirty work) and modifying these routines accordingly. The four routines are: startvideo() Do whatever you have to do to throw your adapter into the appropriate video mode (in case it can't be accomplished the "normal" way, with INT 10H and the AX/BX/CX/DX values available via FRACTINT.CFG or FARVIDEO.ASM). This routine will typically be empty (in which case the AX/BX/CX/DX values in FRACTINT.CFG or FARVIDEO.ASM must be encoded appropriately to accomplish the task), but some adapters like the 8514/A and TARGA need special handling which would go here. If you DO have to put something here, you should encode AX = 0xFF so as to effectively convert the regular video-switching code inside VIDEO.ASM to use an invalid INT 10H call - "do-nothing" logic. endvideo() do whatever you have to do to get it out of that special video mode (in case 'setvideo(3,0,0,0)' won't do it) - this routine will typically be empty, but some adapters like the 8514/A and TARGA need special handling which would go here. writevideo(int x, int y, int color) write a pixel using color number 'color' at screen coordinates x,y (where 0,0 is the top left corner, and sxdots,0 is the top right corner) int readvideo(int x, int y) return the color number of pixel x,y using the same coordinate logic as 'writevideo()' int readvideopalette() read the contents of the adapter's video palette into the 'BYTE dacbox[256][3]' array (up to 256 R/G/B triplets, each with values from 0 to 63). Set dacbox[0][0] = 255 if there is no such palette. Return a -1 if you want the normal internal EGA/VGA routines to handle this function. int writevideopalette() write the contents of the adapter's video palette from the 'BYTE dacbox[256][3]' array (up to 256 R/G/B triplets, each with values from 0 to 63). Return a -1 if you want the normal internal EGA/VGA routines to handle this function. Finally, note that, although these example routines are written in "C", they could just as easily (or maybe more easily!) have been written in assembler. */ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" /* external variables (set in the FRACTINT.CFG file, but findable here */ /* these are declared in PROTOTYPE.H */ #if 0 int dotmode; /* video access method (= 19) */ int sxdots, sydots; /* total # of dots on the screen */ int colors; /* maximum colors available */ /* the video-palette array (named after the VGA adapter's video-DAC) */ BYTE dacbox[256][3]; #endif /* for demo purposes, these routines use VGA mode 13h - 320x200x256 */ int startvideo() { /* assume that the encoded values in FRACTINT.CFG or FARVIDEO.ASM have been set to accomplish this (AX = 0x13, BX = CX = DX = 0) */ return(0); /* set flag: video started */ /* or, we could have done this instead and encoded AX = 0xFF in FRACTINT.CFG/FARVIDEO.ASM: union REGS regs; regs.x.ax = 0x13; int86(0x10,®s,®s); */ } int endvideo() { return(0); /* set flag: video ended */ } void writevideo(int x, int y, int color) { union REGS regs; regs.h.ah = 0x0c; /* invoke INT 10H with AH = 0CH */ regs.h.al = (char)color; regs.x.bx = 0; regs.x.cx = x; regs.x.dx = y; int86(0x10,®s,®s); } int readvideo(int x, int y) { union REGS regs; regs.x.ax = 0x0d00; /* invoke INT 10H with AH = 0DH */ regs.x.bx = 0; regs.x.cx = x; regs.x.dx = y; int86(0x10,®s,®s); return((unsigned int)regs.h.al); /* return pixel color */ } int readvideopalette() { return (-1); /* let the internal routines do it */ } int writevideopalette() { return (-1); /* let the internal routines do it */ } xfractint-20.4.10.orig/common/parserfp.c0000644000000000000000000015117410150633601014767 0ustar /* PARSERFP.C -- Part of FRACTINT fractal drawer. */ /* By Chuck Ebbert CompuServe [76306,1226] */ /* internet: 76306.1226@compuserve.com */ /* Fast floating-point parser code. The functions beginning with */ /* "fStk" are in PARSERA.ASM. PARSER.C calls this code after */ /* it has parsed the formula. */ /* Converts the function pointers/load pointers/store pointers */ /* built by parsestr() into an optimized array of function */ /* pointer/operand pointer pairs. */ /* As of 31 Dec 93, also generates executable code in memory. */ /* Define the varible COMPILER to generate executable code. */ /* COMPILER must also be defined in PARSERA.ASM. */ /* Revision history: */ /* 15 Mar 1997 TIW */ /* Fixed if/else bug, replaced stopmsg with pstopmsg */ /* 09 Mar 1997 TIW/GGM */ /* Added support for if/else */ /* 30 Jun 1996 TIW */ /* Removed function names if TESTFP not defined to save memory */ /* Function fStkFloor added to support new 'floor' function */ /* Function fStkCeil added to support new 'ceil' function */ /* Function fStkTrunc added to support new 'trunc' function */ /* Function fStkRound added to support new 'round' function */ /* 15 Feb 1995 CAE */ /* added safety tests to pointer conversion code */ /* added the capability for functions to require 4 free regs */ /* 8 Feb 1995 CAE */ /* Comments changed. */ /* 8 Jan 1995 JCO */ /* Function fStkASin added to support new 'asin' function in v19 */ /* Function fStkASinh added to support new 'asinh' function in v19 */ /* Function fStkACos added to support new 'acos' function in v19 */ /* Function fStkACosh added to support new 'acosh' function in v19 */ /* Function fStkATan added to support new 'atan' function in v19 */ /* Function fStkATanh added to support new 'atanh' function in v19 */ /* Function fStkSqrt added to support new 'sqrt' function in v19 */ /* Function fStkCAbs added to support new 'cabs' function in v19 */ /* Added support for a third parameter p3 */ /* 31 Dec 1993 CAE */ /* Fixed optimizer bug discovered while testing compiler. */ /* 29 Dec 1993 CAE */ /* Added compiler. */ /* 04 Dec 1993 CAE */ /* Added optimizations for LodImagAdd/Sub/Mul. */ /* 06 Nov 1993 CAE */ /* Added optimizer support for LodRealPwr and ORClr2 functions. */ /* If stack top is a real, a simpler sqr() or mod() fn will be */ /* called (fStkSqr3() was added.) */ /* The identities x^0=1, x^1=x, and x^-1=recip(x) are now used by the */ /* optimizer. (fStkOne() was added for this.) */ /* 31 Oct 1993 CAE */ /* Optimizer converts '2*x' and 'x*2' to 'x+x'. */ /* " recognizes LastSqr as a real if not stored to. */ /* 9 Oct 1993 CAE */ /* Functions are now converted via table search. */ /* Added "real" stack count variable and debug msgs for stack size. */ /* Added optimizer extension for commutative multiply. */ /* P1, P2 will be treated as consts if they are never stored to. */ /* Function fStkStoClr2 now emitted for sto,clr with 2 on stack. */ /* " fStkZero added to support new 'zero' function in v18 */ /* Added optimization for x^2 -> sqr(x). */ /* Changed "stopmsg" to "DBUGMSG" and made all macros upper case. */ /* (debugflag=324 now needed for debug msgs to print.) */ /* 12 July 1993 (for v18.1) by CAE to fix optimizer bug */ /* 22 MAR 1993 (for Fractint v18.0) */ /* ******************************************************************* */ /* */ /* (c) Copyright 1992-1995 Chuck Ebbert. All rights reserved. */ /* */ /* This code may be freely distributed and used in non-commercial */ /* programs provided the author is credited either during program */ /* execution or in the documentation, and this copyright notice */ /* is left intact. Sale of this code, or its use in any commercial */ /* product requires permission from the author. Nominal */ /* distribution and handling fees may be charged by shareware and */ /* freeware distributors. */ /* */ /* ******************************************************************* */ /* Uncomment the next line to enable debug messages. */ /* #define TESTFP 1 */ /* Use startup parameter "debugflag=324" to show debug messages after */ /* compiling with above #define uncommented. */ #include #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" /* global data */ struct fls far *pfls = (struct fls far *)0; #ifndef XFRACT /* -- */ /* not moved to PROTOTYPE.H because these only communicate within PARSER.C and other parser modules */ extern union Arg *Arg1, *Arg2; extern double _1_, _2_; extern union Arg s[20], far * far *Store, far * far *Load; extern int StoPtr, LodPtr, OpPtr; extern unsigned int vsp, LastOp; extern struct ConstArg far *v; extern int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp; extern void (far * far *f)(void); extern JUMP_CONTROL_ST far *jump_control; extern int uses_jump, jump_index; typedef void OLD_FN(void); /* old C functions */ OLD_FN StkLod, StkClr, StkSto, EndInit, StkJumpLabel; OLD_FN dStkAdd, dStkSub, dStkMul, dStkDiv; OLD_FN dStkSqr, dStkMod; OLD_FN dStkSin, dStkCos, dStkSinh, dStkCosh, dStkCosXX; OLD_FN dStkTan, dStkTanh, dStkCoTan, dStkCoTanh; OLD_FN dStkLog, dStkExp, dStkPwr; OLD_FN dStkLT, dStkLTE; OLD_FN dStkFlip, dStkReal, dStkImag; OLD_FN dStkConj, dStkNeg, dStkAbs; OLD_FN dStkRecip, StkIdent; OLD_FN dStkGT, dStkGTE, dStkNE, dStkEQ; OLD_FN dStkAND, dStkOR; OLD_FN dStkZero; OLD_FN dStkSqrt; OLD_FN dStkASin, dStkACos, dStkASinh, dStkACosh; OLD_FN dStkATanh, dStkATan; OLD_FN dStkCAbs; OLD_FN dStkFloor; OLD_FN dStkCeil; OLD_FN dStkTrunc; OLD_FN dStkRound; OLD_FN StkJump, dStkJumpOnTrue, dStkJumpOnFalse; OLD_FN dStkOne; typedef void (near NEW_FN)(void); /* new 387-only ASM functions */ NEW_FN fStkPull2; /* pull up fpu stack from 2 to 4 */ NEW_FN fStkPush2; /* push down fpu stack from 8 to 6 */ NEW_FN fStkPush2a; /* push down fpu stack from 6 to 4 */ NEW_FN fStkPush4; /* push down fpu stack from 8 to 4 */ NEW_FN fStkLodDup; /* lod, dup */ NEW_FN fStkLodSqr; /* lod, sqr, dont save magnitude(i.e. lastsqr) */ NEW_FN fStkLodSqr2; /* lod, sqr, save lastsqr */ NEW_FN fStkStoDup; /* store, duplicate */ NEW_FN fStkStoSqr; /* store, sqr, save lastsqr */ NEW_FN fStkStoSqr0; /* store, sqr, dont save lastsqr */ NEW_FN fStkLodDbl; /* load, double */ NEW_FN fStkStoDbl; /* store, double */ NEW_FN fStkReal2; /* fast ver. of real */ NEW_FN fStkSqr; /* sqr, save magnitude in lastsqr */ NEW_FN fStkSqr0; /* sqr, no save magnitude */ NEW_FN fStkClr1; /* clear fpu */ NEW_FN fStkClr2; /* test stack top, clear fpu */ NEW_FN fStkStoClr1; /* store, clr1 */ NEW_FN fStkAdd, fStkSub; NEW_FN fStkSto, fStkSto2; /* fast ver. of sto */ NEW_FN fStkLod, fStkEndInit; NEW_FN fStkMod, fStkMod2; /* faster mod */ NEW_FN fStkLodMod2, fStkStoMod2; NEW_FN fStkLTE, fStkLodLTEMul, fStkLTE2, fStkLodLTE; NEW_FN fStkLodLTE2, fStkLodLTEAnd2; NEW_FN fStkLT, fStkLodLTMul, fStkLT2, fStkLodLT; NEW_FN fStkLodLT2; NEW_FN fStkGTE, fStkLodGTE, fStkLodGTE2; NEW_FN fStkGT, fStkGT2, fStkLodGT, fStkLodGT2; NEW_FN fStkEQ, fStkLodEQ, fStkNE, fStkLodNE; NEW_FN fStkAND, fStkANDClr2, fStkOR, fStkORClr2; NEW_FN fStkSin, fStkSinh, fStkCos, fStkCosh, fStkCosXX; NEW_FN fStkTan, fStkTanh, fStkCoTan, fStkCoTanh; NEW_FN fStkLog, fStkExp, fStkPwr; NEW_FN fStkMul, fStkDiv; NEW_FN fStkFlip, fStkReal, fStkImag, fStkRealFlip, fStkImagFlip; NEW_FN fStkConj, fStkNeg, fStkAbs, fStkRecip; NEW_FN fStkLodReal, fStkLodRealC, fStkLodImag; NEW_FN fStkLodRealFlip, fStkLodRealAbs; NEW_FN fStkLodRealMul, fStkLodRealAdd, fStkLodRealSub, fStkLodRealPwr; NEW_FN fStkLodImagMul, fStkLodImagAdd, fStkLodImagSub; /* CAE 4Dec93 */ NEW_FN fStkLodImagFlip, fStkLodImagAbs; NEW_FN fStkLodConj; NEW_FN fStkLodAdd, fStkLodSub, fStkLodSubMod, fStkLodMul; NEW_FN fStkPLodAdd, fStkPLodSub; /* push-lod-add/sub */ NEW_FN fStkIdent; NEW_FN fStkStoClr2; /* store, clear stack by popping */ NEW_FN fStkZero; /* to support new parser fn. */ NEW_FN fStkDbl; /* double the stack top CAE 31OCT93 */ NEW_FN fStkOne, fStkSqr3; /* sqr3 is sqr/mag of a real CAE 09NOV93 */ NEW_FN fStkSqrt; NEW_FN fStkASin, fStkACos, fStkASinh, fStkACosh; NEW_FN fStkATanh, fStkATan; NEW_FN fStkCAbs; NEW_FN fStkFloor, fStkCeil, fStkTrunc, fStkRound; /* rounding functions */ NEW_FN fStkJump, fStkJumpOnTrue, fStkJumpOnFalse, fStkJumpLabel; /* flow */ NEW_FN fStkOne; /* to support new parser fn. */ /* check to see if a const is being loaded */ /* the really awful hack below gets the first char of the name */ /* of the variable being accessed */ /* if first char not alpha, or const p1, p2, or p3 are being accessed */ /* then this is a const. */ #define IS_CONST(x) \ (!isalpha(**(((char * far *)x ) - 2 ) ) \ || (x==&PARM1 && p1const ) \ || (x==&PARM2 && p2const ) \ || (x==&PARM3 && p3const ) \ || (x==&PARM4 && p4const ) \ || (x==&PARM5 && p5const ) ) /* is stack top a real? */ #define STACK_TOP_IS_REAL \ ( prevfptr == fStkReal || prevfptr == fStkReal2 \ || prevfptr == fStkLodReal || prevfptr == fStkLodRealC \ || prevfptr == fStkLodRealAbs \ || prevfptr == fStkImag || prevfptr == fStkLodImag ) /* remove push operator from stack top */ #define REMOVE_PUSH --cvtptrx, stkcnt+=2 #define CLEAR_STK 127 #define FNPTR(x) pfls[(x)].function /* function pointer */ #define OPPTR(x) pfls[(x)].operand /* operand pointer */ #define NO_OPERAND (union Arg near *)0 #define NO_FUNCTION (void (near *)(void))0 #define LASTSQR v[4].a #define PARM1 v[1].a #define PARM2 v[2].a #define PARM3 v[8].a #define PARM4 v[17].a #define PARM5 v[18].a #define MAX_STACK 8 /* max # of stack register avail */ #ifdef TESTFP int pstopmsg(int x,char far *msg) { static FILE *fp = NULL; if(fp == NULL) fp = fopen("fpdebug.txt","w"); if(fp) { #ifndef XFRACT fprintf(fp,"%Fs\n",msg); #else fprintf(fp,"%s\n",msg); #endif fflush(fp); } return(x); /* just to quiet warnings */ } #define stopmsg pstopmsg #define DBUGMSG(x,y) if (debugflag==324 || debugflag==322 ) stopmsg((x), (y)) #define DBUGMSG1(x,y,p) \ if (debugflag==324 || debugflag==322 ){ \ sprintf(cDbgMsg, (y), (p) ); \ stopmsg((x), cDbgMsg ); \ } #define DBUGMSG2(x,y,p,q) \ if (debugflag==324 || debugflag==322 ){ \ sprintf(cDbgMsg, (y), (p), (q) ); \ stopmsg((x), cDbgMsg ); \ } #define DBUGMSG3(x,y,p,q,r) \ if (debugflag==324 || debugflag==322 ){ \ sprintf(cDbgMsg, (y), (p), (q), (r) ); \ stopmsg((x), cDbgMsg ); \ } #define DBUGMSG4(x,y,p,q,r,s) \ if (debugflag==324 || debugflag==322 ){ \ sprintf(cDbgMsg, (y), (p), (q), (r), (s) ); \ stopmsg((x), cDbgMsg ); \ } #define FNAME(a,b,c,d,e,f) a,b,c,d,e,f /* use the function name string */ #else #define DBUGMSG(x,y) #define DBUGMSG1(x,y,p) #define DBUGMSG2(x,y,p,q) #define DBUGMSG3(x,y,p,q,r) #define DBUGMSG4(x,y,p,q,r,s) #define FNAME(a,b,c,d,e,f) b,c,d,e,f /* don't use the function name string */ #endif /* TESTFP */ #define FN_LOD 0 #define FN_CLR 1 #define FN_ADD 2 #define FN_SUB 3 #define FN_MUL 4 #define FN_DIV 5 #define FN_STO 6 #define FN_SQR 7 #define FN_ENDINIT 8 #define FN_MOD 9 #define FN_LTE 10 #define FN_SIN 11 #define FN_COS 12 #define FN_SINH 13 #define FN_COSH 14 #define FN_COSXX 15 #define FN_TAN 16 #define FN_TANH 17 #define FN_COTAN 18 #define FN_COTANH 19 #define FN_LOG 20 #define FN_EXP 21 #define FN_PWR 22 #define FN_LT 23 #define FN_FLIP 24 #define FN_REAL 25 #define FN_IMAG 26 #define FN_CONJ 27 #define FN_NEG 28 #define FN_ABS 29 #define FN_RECIP 30 #define FN_IDENT 31 #define FN_GT 32 #define FN_GTE 33 #define FN_NE 34 #define FN_EQ 35 #define FN_AND 36 #define FN_OR 37 #define FN_ZERO 38 #define FN_SQRT 39 #define FN_ASIN 40 #define FN_ACOS 41 #define FN_ASINH 42 #define FN_ACOSH 43 #define FN_ATANH 44 #define FN_ATAN 45 #define FN_CABS 46 #define FN_FLOOR 47 #define FN_CEIL 48 #define FN_TRUNC 49 #define FN_ROUND 50 #define FN_JUMP 51 #define FN_JUMP_ON_TRUE 52 #define FN_JUMP_ON_FALSE 53 #define FN_JUMP_LABEL 54 #define FN_ONE 55 /* number of "old" functions in the table. */ /* these are the ones that the parser outputs */ #define LAST_OLD_FN FN_ONE #define NUM_OLD_FNS LAST_OLD_FN + 1 /* total number of functions in the table. */ #define LAST_FN FN_ONE #define NUM_FNS LAST_FN + 1 static unsigned char realstkcnt, /* how many scalars are really on stack */ stkcnt, /* # scalars on FPU stack */ lastsqrused, /* was lastsqr loaded in the formula? */ lastsqrreal, /* was lastsqr stored explicitly in the formula? */ p1const, /* is p1 a constant? */ p2const, /* ...and p2? */ p3const, /* ...and p3? */ p4const, /* ...and p4? */ p5const; /* ...and p5? */ static unsigned int cvtptrx; /* subscript of next free entry in pfls */ static void (near *prevfptr )(void); /* previous function pointer */ /* the entries in this table must be in the same order as */ /* the #defines above */ /* this table is searched sequentially */ struct fn_entry { #ifdef TESTFP char far *fname; /* function name */ #endif void (far *infn)(void); /* 'old' function pointer */ /* (infn points to an operator fn in parser.c) */ void (near *outfn)(void); /* pointer to equiv. fast fn. */ char min_regs; /* min regs needed on stack by this fn. */ /* (legal values are 0, 2, 4) */ char free_regs; /* free regs required by this fn */ /* (legal values are 0, 2, 4) */ char delta; /* net change to # of values on the fp stack */ /* (legal values are -2, 0, +2) */ } static far afe[NUM_OLD_FNS] = { /* array of function entries */ {FNAME("Lod", StkLod, fStkLod, 0, 2, +2) }, /* 0 */ {FNAME("Clr", StkClr, fStkClr1, 0, 0, CLEAR_STK) }, /* 1 */ {FNAME("+", dStkAdd, fStkAdd, 4, 0, -2) }, /* 2 */ {FNAME("-", dStkSub, fStkSub, 4, 0, -2) }, /* 3 */ {FNAME("*", dStkMul, fStkMul, 4, 2, -2) }, /* 4 */ {FNAME("/", dStkDiv, fStkDiv, 4, 2, -2) }, /* 5 */ {FNAME("Sto", StkSto, fStkSto, 2, 0, 0) }, /* 6 */ {FNAME("Sqr", dStkSqr, fStkSqr, 2, 2, 0) }, /* 7 */ {FNAME(":", EndInit, fStkEndInit,0, 0, CLEAR_STK) }, /* 8 */ {FNAME("Mod", dStkMod, fStkMod, 2, 0, 0) }, /* 9 */ {FNAME("<=", dStkLTE, fStkLTE, 4, 0, -2) }, /* 10 */ {FNAME("Sin", dStkSin, fStkSin, 2, 2, 0) }, /* 11 */ {FNAME("Cos", dStkCos, fStkCos, 2, 2, 0) }, /* 12 */ {FNAME("Sinh", dStkSinh, fStkSinh, 2, 2, 0) }, /* 13 */ {FNAME("Cosh", dStkCosh, fStkCosh, 2, 2, 0) }, /* 14 */ {FNAME("Cosxx", dStkCosXX, fStkCosXX, 2, 2, 0) }, /* 15 */ {FNAME("Tan", dStkTan, fStkTan, 2, 2, 0) }, /* 16 */ {FNAME("Tanh", dStkTanh, fStkTanh, 2, 2, 0) }, /* 17 */ {FNAME("CoTan", dStkCoTan, fStkCoTan, 2, 2, 0) }, /* 18 */ {FNAME("CoTanh", dStkCoTanh, fStkCoTanh, 2, 2, 0) }, /* 19 */ {FNAME("Log", dStkLog, fStkLog, 2, 2, 0) }, /* 20 */ {FNAME("Exp", dStkExp, fStkExp, 2, 2, 0) }, /* 21 */ {FNAME("^", dStkPwr, fStkPwr, 4, 2, -2) }, /* 22 */ {FNAME("<", dStkLT, fStkLT, 4, 0, -2) }, /* 23 */ {FNAME("Flip", dStkFlip, fStkFlip, 2, 0, 0) }, /* 24 */ {FNAME("Real", dStkReal, fStkReal, 2, 0, 0) }, /* 25 */ {FNAME("Imag", dStkImag, fStkImag, 2, 0, 0) }, /* 26 */ {FNAME("Conj", dStkConj, fStkConj, 2, 0, 0) }, /* 27 */ {FNAME("Neg", dStkNeg, fStkNeg, 2, 0, 0) }, /* 28 */ {FNAME("Abs", dStkAbs, fStkAbs, 2, 0, 0) }, /* 29 */ {FNAME("Recip", dStkRecip, fStkRecip, 2, 2, 0) }, /* 30 */ {FNAME("Ident", StkIdent, fStkIdent, 2, 0, 0) }, /* 31 */ {FNAME(">", dStkGT, fStkGT, 4, 0, -2) }, /* 32 */ {FNAME(">=", dStkGTE, fStkGTE, 4, 0, -2) }, /* 33 */ {FNAME("!=", dStkNE, fStkNE, 4, 0, -2) }, /* 34 */ {FNAME("==", dStkEQ, fStkEQ, 4, 0, -2) }, /* 35 */ {FNAME("&&", dStkAND, fStkAND, 4, 0, -2) }, /* 36 */ {FNAME("||", dStkOR, fStkOR, 4, 0, -2) }, /* 37 */ {FNAME("Zero", dStkZero, fStkZero, 2, 0, 0) }, /* 38 */ {FNAME("Sqrt", dStkSqrt, fStkSqrt, 2, 2, 0) }, /* 39 */ {FNAME("ASin", dStkASin, fStkASin, 2, 4, 0) }, /* 40 */ {FNAME("ACos", dStkACos, fStkACos, 2, 4, 0) }, /* 41 */ {FNAME("ASinh", dStkASinh, fStkASinh, 2, 4, 0) }, /* 42 */ {FNAME("ACosh", dStkACosh, fStkACosh, 2, 4, 0) }, /* 43 */ {FNAME("ATanh", dStkATanh, fStkATanh, 2, 4, 0) }, /* 44 */ {FNAME("ATan", dStkATan, fStkATan, 2, 4, 0) }, /* 45 */ {FNAME("CAbs", dStkCAbs, fStkCAbs, 2, 0, 0) }, /* 46 */ {FNAME("Floor", dStkFloor, fStkFloor, 2, 0, 0) }, /* 47 */ {FNAME("Ceil", dStkCeil, fStkCeil, 2, 0, 0) }, /* 48 */ {FNAME("Trunc", dStkTrunc, fStkTrunc, 2, 0, 0) }, /* 49 */ {FNAME("Round", dStkRound, fStkRound, 2, 0, 0) }, /* 50 */ {FNAME("Jump", StkJump, fStkJump, 0, 0, 0)},/* 51 */ {FNAME("JumpOnTrue", dStkJumpOnTrue, fStkJumpOnTrue, 2, 0, 0)},/* 52 */ {FNAME("JumpOnFalse", dStkJumpOnFalse, fStkJumpOnFalse,2, 0, 0)},/* 53 */ {FNAME("JumpLabel", StkJumpLabel, fStkJumpLabel, 0, 0, 0)},/* 54 */ {FNAME("One", dStkOne, fStkOne, 2, 0, 0) } /* 55 */ }; #ifdef TESTFP static char cDbgMsg[255]; #endif /* TESTFP */ static int CvtFptr(void (near * ffptr)(void), int MinStk, int FreeStk, int Delta ) { union Arg near *otemp; /* temp operand ptr */ union Arg far *testload; #ifdef TESTFP int prevstkcnt; #endif double dTemp; int Max_On_Stack = MAX_STACK - FreeStk; /* max regs allowed on stack */ int Num_To_Push; /* number of regs to push */ /* first do some sanity checks */ /* CAE 15Feb95 */ if ( (Delta != -2 && Delta != 0 && Delta != 2 && Delta != CLEAR_STK) || (FreeStk != 0 && FreeStk != 2 && FreeStk != 4) || (MinStk != 0 && MinStk != 2 && MinStk != 4) ){ awful_error: stopmsg (0,"FATAL INTERNAL PARSER ERROR!"); return 0; /* put out dire message and revert to old parser */ } /* this if statement inserts a stack push or pull into the token array */ /* it would be much better to do this *after* optimization */ if ((int)stkcnt < MinStk ) { /* not enough operands on fpu stack */ DBUGMSG2(0, "Inserted pull. Stack: %2d --> %2d", stkcnt, stkcnt+2 ); OPPTR(cvtptrx) = NO_OPERAND; FNPTR(cvtptrx++) = fStkPull2; /* so adjust the stack, pull operand */ stkcnt += 2; } else if ((int)stkcnt > Max_On_Stack ) { /* too many operands */ Num_To_Push = stkcnt - Max_On_Stack; if (Num_To_Push == 2 ){ if (stkcnt == MAX_STACK ){ /* push stack down from max to max-2 */ FNPTR(cvtptrx) = fStkPush2; } else if (stkcnt == MAX_STACK - 2 ){ /* push stack down from max-2 to max-4 */ FNPTR(cvtptrx) = fStkPush2a; } else { goto awful_error; } DBUGMSG2(0, "Inserted push. Stack: %2d --> %2d", stkcnt, stkcnt-2 ); OPPTR(cvtptrx++) = NO_OPERAND; stkcnt -= 2; } else if (Num_To_Push == 4 ){ /* push down from max to max-4 */ FNPTR(cvtptrx) = fStkPush4; DBUGMSG2(0, "Inserted push. Stack: %2d --> %2d", stkcnt, stkcnt-4 ); OPPTR(cvtptrx++) = NO_OPERAND; stkcnt -= 4; } else { goto awful_error; } } /* set the operand pointer here for store function */ if (ffptr == fStkSto ){ OPPTR(cvtptrx) = (void near *)FP_OFF((Store[StoPtr++])); } else if (ffptr == fStkLod && debugflag == 322 ){ /* when disabling optimizer, set load pointer here */ OPPTR(cvtptrx) = (void near *)FP_OFF((Load[LodPtr++])); } else { /* the optimizer will set the pointer for load fn. */ OPPTR(cvtptrx) = NO_OPERAND; } if (debugflag == 322 ){ goto SkipOptimizer; } /* -------------------------- begin optimizer --------------------- */ /* This optimizer grew from a simple if statement into a monster. */ /* Most of the bugs in the optimizer have been in the code that */ /* juggles the overflow stack. */ /* For the following: */ /* * == cvtptrx points to this */ /* () == this is about to be added to the array */ /* ******************************************************************** */ if (ffptr == fStkLod) { /* about to add Lod to the array */ if (prevfptr == fStkLod && Load[LodPtr-1] == Load[LodPtr] ) { /* previous non-adjust operator was Lod of same operand */ /* ? lodx ? (*lodx) */ if (FNPTR(--cvtptrx) == fStkPush2 ){ /* prev fn was push */ /* ? lod *push (lod) */ --cvtptrx; /* found *lod push (lod) */ if (FNPTR(cvtptrx-1) == fStkPush2){ /* always more ops here */ DBUGMSG(0, "push *lod push (lod) -> push4 (*loddup)" ); FNPTR(cvtptrx-1) = fStkPush4; } else { /* prev op not push */ DBUGMSG(0, "op *lod push (lod) -> op pusha(p=0) (*loddup)" ); OPPTR(cvtptrx) = NO_OPERAND; /* use 'alternate' push fn. */ FNPTR(cvtptrx++) = fStkPush2a; /* push w/2 free on stack */ /* operand ptr will be set below */ } } else { /* never push *lod (lod) so must be */ DBUGMSG(0, "op *lod (lod) -> op (*loddup)" ); } ffptr = fStkLodDup; } else if (prevfptr == fStkSto2 && Store[StoPtr-1] == Load[LodPtr] ){ /* store, load of same value */ /* only one operand on stack here when prev oper is Sto2 */ DBUGMSG(0, "*sto2 (lod) -> (*stodup)" ); --cvtptrx; ffptr = fStkStoDup; } /* This may cause roundoff problems when later operators */ /* use the rounded value that was stored here, while the next */ /* operator uses the more accurate internal value. */ else if (prevfptr == fStkStoClr2 && Store[StoPtr-1] == Load[LodPtr] ){ /* store, clear, load same value found */ /* only one operand was on stack so this is safe */ DBUGMSG (0, "*StoClr2 (Lod) -> (*Sto2)" ); --cvtptrx; ffptr = fStkSto2; /* use different Sto fn */ } else { testload = Load[LodPtr]; if (testload == &LASTSQR && lastsqrreal ){ /* -- LastSqr is a real. CAE 31OCT93 */ DBUGMSG(0, "(*lod[lastsqr]) -> (*lodreal)" ); ffptr = fStkLodReal; } else if (IS_CONST(testload) && testload->d.y == 0.0 ){ DBUGMSG(0, "(*lod) -> (*lodrealc)" ); ffptr = fStkLodRealC; /* a real const is being loaded */ } } /* set the operand ptr here */ OPPTR(cvtptrx) = (void near *)FP_OFF((Load[LodPtr++])); } /* ******************************************************************** */ else if (ffptr == fStkAdd ){ if (prevfptr == fStkLodDup ){ /* there is never a push before add */ --cvtptrx; /* found ? *loddup (add) */ if (cvtptrx!=0 && FNPTR(cvtptrx-1) == fStkPush2a ){ /* because push lod lod is impossible so is push loddup */ DBUGMSG(0, "pusha *loddup (add) -> (*loddbl),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptr */ } else if (cvtptrx!=0 && FNPTR(cvtptrx-1) == fStkPush4 ){ DBUGMSG(0, "push4 *loddup (add) -> push2 (*loddbl),stk+=2" ); FNPTR(cvtptrx-1) = fStkPush2; stkcnt += 2; /* CAE added 12 July 1993 to fix bug */ } else { DBUGMSG(0, "op *loddup (add) -> op (*loddbl)" ); } ffptr = fStkLodDbl; } else if (prevfptr == fStkStoDup ){ DBUGMSG(0, "stodup (*add) -> (*stodbl)" ); /* there are always exactly 4 on stack here */ --cvtptrx; ffptr = fStkStoDbl; } else if (prevfptr == fStkLod ){ /* have found lod (*add) */ --cvtptrx; /* ? *lod (add) */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "*push load (add) -> (*plodadd),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptrs */ ffptr = fStkPLodAdd; } else { DBUGMSG(0, "op *lod (add) -> op (*lodadd)" ); ffptr = fStkLodAdd; } } else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ --cvtptrx; /* found ? *lodreal (add) */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "*push lodreal (add) -> (*lodrealadd),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptrs */ } else { DBUGMSG(0, "*lodreal (add) -> (*lodrealadd)" ); } ffptr = fStkLodRealAdd; } else if (prevfptr == fStkLodImag ){ /* CAE 4DEC93 */ --cvtptrx; /* found ? *lodimag (add) */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "*push lodimag (add) -> (*lodimagadd),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptrs */ } else { DBUGMSG(0, "*lodimag (add) -> (*lodimagadd)" ); } ffptr = fStkLodImagAdd; } } /* ******************************************************************** */ else if (ffptr == fStkSub ){ if (prevfptr == fStkLod ){ /* found lod (*sub) */ --cvtptrx; /* *lod (sub) */ /* there is never a sequence (lod push sub ) */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "*push lod (sub) -> (*plodsub),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptrs */ ffptr = fStkPLodSub; } else { DBUGMSG(0, "*lod (sub) -> (*lodsub)" ); ffptr = fStkLodSub; } } else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ --cvtptrx; /* ? *lodreal (sub) */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "*push lodreal (sub) -> (*lodrealsub),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptrs */ } else { DBUGMSG(0, "*lodreal (sub) -> (*lodrealsub)" ); } ffptr = fStkLodRealSub; } else if (prevfptr == fStkLodImag ){ /* CAE 4DEC93 */ --cvtptrx; /* ? *lodimag (sub) */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "*push lodimag (sub) -> (*lodimagsub),stk+=2" ); REMOVE_PUSH; OPPTR(cvtptrx) = OPPTR(cvtptrx+1); /* fix opptrs */ } else { DBUGMSG(0, "*lodimag (sub) -> (*lodimagsub)" ); } ffptr = fStkLodImagSub; } } /* ******************************************************************** */ else if (ffptr == fStkMul ){ if (prevfptr == fStkLodDup ){ /* found loddup ? (*mul) */ if (FNPTR(--cvtptrx) == fStkPush2 ){ DBUGMSG(0, "loddup *push (mul) -> (*lodsqr),stk+=2" ); REMOVE_PUSH; } else { DBUGMSG(0, "*loddup (mul) -> (*lodsqr)" ); } ffptr = fStkLodSqr; } else if (prevfptr == fStkStoDup ){ /* no pushes here, 4 on stk. */ DBUGMSG(0, "stodup (mul) -> (*stosqr0)" ); --cvtptrx; ffptr = fStkStoSqr0; /* dont save lastsqr here ever */ } else if (prevfptr == fStkLod ){ --cvtptrx; /* lod *? (mul) */ if (FNPTR(cvtptrx) == fStkPush2 ){ /* lod *push (mul) */ --cvtptrx; /* ? *lod push (mul) */ if(FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "push *lod push (mul) -> push4 (*lodmul)" ); FNPTR(cvtptrx-1) = fStkPush4; } else { DBUGMSG(0, "op *lod push (mul) -> op pusha (*lodmul)" ); OPPTR(cvtptrx+1) = OPPTR(cvtptrx); /* fix operand ptr */ FNPTR(cvtptrx) = fStkPush2a; OPPTR(cvtptrx) = NO_OPERAND; cvtptrx++; } } else { DBUGMSG(0, "*lod (mul) -> (*lodmul)" ); } ffptr = fStkLodMul; /********************** begin extension *** CAE 9 Oct 93 ****/ /* change loadreal a, lodmul b --> lod b, lodrealmul a */ FNPTR(cvtptrx) = NO_FUNCTION; /* mark the pending fn as null */ if (FNPTR(cvtptrx-1) == fStkPush4 || FNPTR(cvtptrx-1) == fStkPush2a ){ --cvtptrx; /* look back past this push */ } if (FNPTR(cvtptrx-1) == fStkLodRealC && Load[LodPtr-2]->d.x == _2_ ){ /* -- Convert '2*a' into 'a+a'. CAE 31OCT93 */ if (FNPTR(cvtptrx) == NO_FUNCTION ){ DBUGMSG(0, "lodreal[2] (*lodmul[b])" " -> (*loddbl[b])" ); OPPTR(cvtptrx-1) = OPPTR(cvtptrx); } else if (FNPTR(cvtptrx) == fStkPush2a ){ DBUGMSG(0, "lodreal[2] *pusha (lodmul[b])" " -> loddbl[b],stk+=2" ); OPPTR(cvtptrx-1) = OPPTR(cvtptrx+1); stkcnt += 2; } else if (FNPTR(cvtptrx) == fStkPush4 ){ DBUGMSG(0, "lodreal[2] *push4 (lodmul[b])" " -> loddbl[b],stk+=4" ); OPPTR(cvtptrx-1) = OPPTR(cvtptrx+1); stkcnt += 4; } FNPTR(--cvtptrx) = NO_FUNCTION; /* so no increment later */ ffptr = fStkLodDbl; } else if (FNPTR(cvtptrx-1) == fStkLodReal || FNPTR(cvtptrx-1) == fStkLodRealC ){ /* lodreal *?push?? (*?lodmul) */ otemp = OPPTR(cvtptrx-1); /* save previous fn's operand */ FNPTR(cvtptrx-1) = fStkLod; /* prev fn = lod */ /* Moved setting of prev lodptr to below CAE 31DEC93 */ /* This was a bug causing a bad loadptr to be set here */ /* 3 lines marked 'prev lodptr=this' below replace this line */ if (FNPTR(cvtptrx) == NO_FUNCTION ){ DBUGMSG(0, "lodreal[a] (*lodmul[b])" " -> lod[b] (*lodrealmul[a])" ); OPPTR(cvtptrx-1) = OPPTR(cvtptrx); /* prev lodptr=this */ } else if (FNPTR(cvtptrx) == fStkPush2a ){ DBUGMSG(0, "lodreal[a] *pusha (lodmul[b])" " -> lod[b] (*lodrealmul[a]),stk+=2" ); /* set this fn ptr to null so cvtptrx won't be incr later */ FNPTR(cvtptrx) = NO_FUNCTION; OPPTR(cvtptrx-1) = OPPTR(cvtptrx+1); /* prev lodptr=this */ stkcnt += 2; } else if (FNPTR(cvtptrx) == fStkPush4 ){ DBUGMSG(0, "lodreal[a] *push4 (lodmul[b])" " -> lod[b] push2 (*lodrealmul[a]),stk+=2" ); FNPTR(cvtptrx++) = fStkPush2; OPPTR(cvtptrx-2) = OPPTR(cvtptrx); /* prev lodptr=this */ /* we know cvtptrx points to a null function now */ stkcnt += 2; } OPPTR(cvtptrx) = otemp; /* switch the operands */ ffptr = fStkLodRealMul; /* next fn is now lodrealmul */ } if (FNPTR(cvtptrx) != NO_FUNCTION ){ cvtptrx++; /* adjust cvtptrx back to normal if needed */ } /* ********************** end extension *********************** */ } else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ --cvtptrx; /* found lodreal *? (mul) */ if (FNPTR(cvtptrx) == fStkPush2 ){ DBUGMSG(0, "lodreal *push2 (mul) -> (*lodrealmul),stk+=2" ); REMOVE_PUSH; } else { DBUGMSG(0, "*lodreal (mul) -> (*lodrealmul)" ); } ffptr = fStkLodRealMul; /********************** begin extension *** CAE 31OCT93 ****/ if (prevfptr == fStkLodRealC /* use prevfptr here */ && Load[LodPtr-1]->d.x == _2_ ){ if (FNPTR(cvtptrx) == fStkPush2 ){ DBUGMSG(0, "push (*lodrealmul[2]) -> (*dbl),stk+=2" ); REMOVE_PUSH; } else { DBUGMSG(0, "*lodrealmul[2] -> (*dbl)" ); } OPPTR(cvtptrx) = NO_OPERAND; ffptr = fStkDbl; if (FNPTR(cvtptrx-1) == fStkLod ){ DBUGMSG(0, "lod (*dbl) -> (*loddbl)" ); --cvtptrx; ffptr = fStkLodDbl; } else if (FNPTR(cvtptrx-1) == fStkSto2 ){ DBUGMSG(0, "sto2 (*dbl) -> (*stodbl)" ); --cvtptrx; ffptr = fStkStoDbl; } } /************************ end extension *** CAE 31OCT93 ****/ } else if (prevfptr == fStkLodImag ){ /* CAE 4DEC93 */ --cvtptrx; /* found lodimag *? (mul) */ if (FNPTR(cvtptrx) == fStkPush2 ){ DBUGMSG(0, "lodimag *push2 (mul) -> (*lodimagmul),stk+=2" ); REMOVE_PUSH; } else { DBUGMSG(0, "*lodimag (mul) -> (*lodimagmul)" ); } ffptr = fStkLodImagMul; } else if (prevfptr == fStkLodLT && FNPTR(cvtptrx-1) != fStkPull2 ){ /* this shortcut fails if Lod LT Pull Mul found */ DBUGMSG(0, "LodLT (*Mul) -> (*LodLTMul)" ); --cvtptrx; /* never lod LT Push Mul here */ ffptr = fStkLodLTMul; } else if (prevfptr == fStkLodLTE && FNPTR(cvtptrx-1) != fStkPull2 ){ DBUGMSG(0, "LodLTE (*mul) -> (*LodLTEmul)" ); --cvtptrx; ffptr = fStkLodLTEMul; } } /* ******************************************************************** */ else if (ffptr == fStkClr1 && prevfptr == fStkSto ){ --cvtptrx; if (stkcnt == 2 ){ DBUGMSG(0, "sto (*clr1) -> (*stoclr2)" ); ffptr = fStkStoClr2; } else { DBUGMSG(0, "sto (*clr1) -> (*stoclr1)" ); ffptr = fStkStoClr1; } } /* ******************************************************************** */ else if (ffptr == fStkDiv ){ if (prevfptr == fStkLodRealC && vsp < Max_Args - 1 ){ /* have found a divide by a real constant */ /* and there is space to create a new one */ /* lodrealc ? (*div) */ if (FNPTR(--cvtptrx) == fStkPush2 ){ DBUGMSG(0, "lodrealc *push (div) -> (*lodrealmul),stk+=2" ); REMOVE_PUSH; } else { DBUGMSG(0, "*lodrealc (div) -> (*lodrealmul)" ); } v[vsp].s = (void near *)0; /* this constant has no name */ v[vsp].len = 0; v[vsp].a.d.x = _1_ / Load[LodPtr-1]->d.x; v[vsp].a.d.y = 0.0; { void far *p = &v[vsp++].a; OPPTR(cvtptrx) = (void near *)FP_OFF(p); /* isn't C fun! */ } ffptr = fStkLodRealMul; } } /* ******************************************************************** */ else if (ffptr == fStkReal ){ if (prevfptr == fStkLod ){ DBUGMSG(0, "lod (*real) -> (*lodreal)" ); --cvtptrx; ffptr = fStkLodReal; } else if (stkcnt < MAX_STACK ){ DBUGMSG(0, "(*real) -> (*real2)" ); ffptr = fStkReal2; } } /* ******************************************************************** */ else if (ffptr == fStkImag && prevfptr == fStkLod ){ DBUGMSG(0, "lod (*imag) -> lodimag" ); --cvtptrx; ffptr = fStkLodImag; } /* ******************************************************************** */ else if (ffptr == fStkConj && prevfptr == fStkLod ){ DBUGMSG(0, "lod (*conj) -> (*lodconj)" ); --cvtptrx; ffptr = fStkLodConj; } /* ******************************************************************** */ else if (ffptr == fStkMod && stkcnt < MAX_STACK ){ DBUGMSG(0, "(*mod) -> (*mod2)" ); ffptr = fStkMod2; /* use faster version if room on stack */ if (prevfptr == fStkLod ){ DBUGMSG(0, "lod (*mod2) -> (*lodmod2)" ); --cvtptrx; ffptr = fStkLodMod2; } else if (prevfptr == fStkSto || prevfptr == fStkSto2 ){ DBUGMSG(0, "sto (*mod2) -> (*stomod2)" ); --cvtptrx; ffptr = fStkStoMod2; } else if (prevfptr == fStkLodSub ){ DBUGMSG(0, "lodsub (*mod2) -> (*lodsubmod)" ); --cvtptrx; ffptr = fStkLodSubMod; } else if (STACK_TOP_IS_REAL){ /* CAE 06NOV93 */ DBUGMSG(0, "(*mod2[st real]) -> (*sqr3)" ); ffptr = fStkSqr3; } } /* ******************************************************************** */ else if (ffptr == fStkFlip ){ if (prevfptr == fStkReal || prevfptr == fStkReal2 ){ DBUGMSG(0, "real (*flip) -> (*realflip)" ); --cvtptrx; ffptr = fStkRealFlip; } else if (prevfptr == fStkImag ){ DBUGMSG(0, "imag (*flip) -> (*imagflip)" ); --cvtptrx; ffptr = fStkImagFlip; } else if (prevfptr == fStkLodReal ){ DBUGMSG(0, "lodreal (*flip) -> (*lodrealflip)" ); --cvtptrx; ffptr = fStkLodRealFlip; } else if (prevfptr == fStkLodImag ){ DBUGMSG(0, "lodimag (*flip) -> (*lodimagflip)" ); --cvtptrx; ffptr = fStkLodImagFlip; } } /* ******************************************************************** */ else if (ffptr == fStkAbs ){ if (prevfptr == fStkLodReal ){ DBUGMSG(0, "lodreal (*abs) -> (*lodrealabs)" ); --cvtptrx; ffptr = fStkLodRealAbs; } else if (prevfptr == fStkLodImag ){ DBUGMSG(0, "lodimag (*abs) -> (*lodimagabs)" ); --cvtptrx; ffptr = fStkLodImagAbs; } } /* ******************************************************************** */ else if (ffptr == fStkSqr ){ if (prevfptr == fStkLod && FNPTR(cvtptrx-1) != fStkPush2 ){ DBUGMSG(0, "lod (*sqr) -> (*lodsqr)" ); --cvtptrx; ffptr = fStkLodSqr; /* assume no need to save lastsqr */ if (lastsqrused){ DBUGMSG(0, "(*lodsqr) -> (*lodsqr2)" ); ffptr = fStkLodSqr2; /* lastsqr is being used */ } } else if (prevfptr == fStkSto2 ){ DBUGMSG(0, "sto2 (*sqr) -> (*stosqr0)" ); --cvtptrx; ffptr = fStkStoSqr0; /* assume no need to save lastsqr */ if (lastsqrused) { DBUGMSG(0, "(*stosqr0) -> (*stosqr)" ); ffptr = fStkStoSqr; /* save lastsqr */ } } else { if (!lastsqrused) { DBUGMSG(0, "(*sqr) -> (*sqr0)" ); ffptr = fStkSqr0; /* don't save lastsqr */ if (STACK_TOP_IS_REAL){ /* CAE 06NOV93 */ DBUGMSG(0, "(*sqr0[st real]) -> (*sqr3)" ); ffptr = fStkSqr3; } } } } /* ******************************************************************** */ else if (ffptr == fStkPwr ){ if (prevfptr == fStkLodRealC ){ dTemp = Load[LodPtr-1]->d.x; if (dTemp == _2_ || dTemp == _1_ || dTemp == -1.0 || dTemp == 0.0 ){ /* change ^[-1,0,1,or 2] to recip,one,ident,sqr CAE 06NOV93 */ if (FNPTR(cvtptrx-1) == fStkPush2 ){ DBUGMSG(0, "LodRealC[-1,0,1,2] Push (*Pwr)" " -> (*[recip,1,ident,Sqr0]), stk+=2" ); REMOVE_PUSH; /* lod[?] (push) *pwr */ } else { DBUGMSG(0, "LodRealC[-1,0,1,2] (*Pwr)" " -> (*[recip,1,ident,sqr0])" ); } --cvtptrx; OPPTR(cvtptrx) = NO_OPERAND; if (dTemp == _2_ ){ DBUGMSG(0, "[]=Sqr0" ); ffptr = fStkSqr0; /* no need to compute lastsqr here */ if (FNPTR(cvtptrx-1) == fStkLod ){ DBUGMSG(0, "Lod (*Sqr0) -> (*LodSqr)" ); --cvtptrx; ffptr = fStkLodSqr; /* dont save lastsqr */ } else if (FNPTR(cvtptrx-1) == fStkSto2 ){ DBUGMSG(0, "Sto2 (*Sqr0) -> (*StoSqr0)" ); --cvtptrx; ffptr = fStkStoSqr0; /* dont save lastsqr */ } } else if (dTemp == _1_ ){ DBUGMSG(0, "[]=Ident" ); ffptr = fStkIdent; } else if (dTemp == 0.0 ){ DBUGMSG(0, "[]=One" ); ffptr = fStkOne; } else if (dTemp == -1.0 ){ DBUGMSG(0, "[]=Recip" ); ffptr = fStkRecip; } } else if (FNPTR(cvtptrx-1) == prevfptr ){ --cvtptrx; ffptr = fStkLodRealPwr; /* see comments below */ } } else if (prevfptr == fStkLodReal && FNPTR(cvtptrx-1) == prevfptr ){ /* CAE 6NOV93 */ /* don't handle pushes here, lodrealpwr needs 4 free */ DBUGMSG(0, "LodReal (*Pwr) -> (*LodRealPwr)" ); --cvtptrx; ffptr = fStkLodRealPwr; } } /* ******************************************************************** */ else if (ffptr == fStkLTE ){ if (prevfptr == fStkLod || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ DBUGMSG(0, "Lod (*LTE) -> (*LodLTE)" ); --cvtptrx; ffptr = fStkLodLTE; } } /* ******************************************************************** */ else if (ffptr == fStkLT ){ if (prevfptr == fStkLod || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ DBUGMSG(0, "Lod (*LT) -> (*LodLT)" ); --cvtptrx; ffptr = fStkLodLT; } } /* ******************************************************************** */ else if (ffptr == fStkGT ){ if (prevfptr == fStkLod || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ DBUGMSG(0, "Lod (*GT) -> (*LodGT)" ); --cvtptrx; ffptr = fStkLodGT; } } /* ******************************************************************** */ else if (ffptr == fStkGTE ){ if (prevfptr == fStkLod || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ DBUGMSG(0, "Lod (*GTE) -> (*LodGTE)" ); --cvtptrx; ffptr = fStkLodGTE; } } /* ******************************************************************** */ else if (ffptr == fStkNE ){ if (prevfptr == fStkLod || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ DBUGMSG(0, "Lod (*NE) -> (*LodNE)" ); --cvtptrx; ffptr = fStkLodNE; } } /* ******************************************************************** */ else if (ffptr == fStkEQ ){ if (prevfptr == fStkLod || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){ DBUGMSG(0, "Lod (*EQ) -> (*LodEQ)" ); --cvtptrx; ffptr = fStkLodEQ; } } /* ******************************************************************** */ SkipOptimizer: /* ------------- end of optimizer ----------------------- */ FNPTR(cvtptrx++) = prevfptr = ffptr; #ifdef TESTFP prevstkcnt = stkcnt; #endif if (Delta == CLEAR_STK ){ realstkcnt = stkcnt = 0; } else { stkcnt = (unsigned char)(stkcnt + Delta); realstkcnt = (unsigned char)(realstkcnt + Delta); } DBUGMSG3(0, "Stack: %2d --> %2d, Real stack: %2d", prevstkcnt, stkcnt, realstkcnt ); return 1; /* return 1 for success */ } int fpfill_jump_struct(void) { /* Completes all entries in jump structure. Returns 1 on error) */ /* On entry, jump_index is the number of jump functions in the formula*/ int i = 0; int checkforelse = 0; NEW_FN near * JumpFunc = NULL; int find_new_func = 1; JUMP_PTRS_ST jump_data[MAX_JUMPS]; for (OpPtr = 0; OpPtr < (int) LastOp; OpPtr++) { if(find_new_func) { switch (jump_control[i].type) { case 1: JumpFunc = fStkJumpOnFalse; break; case 2: checkforelse = !checkforelse; if(checkforelse) JumpFunc = fStkJump; else JumpFunc = fStkJumpOnFalse; break; case 3: JumpFunc = fStkJump; break; case 4: JumpFunc = fStkJumpLabel; break; default: break; } find_new_func = 0; } if(pfls[OpPtr].function == JumpFunc) { jump_data[i].JumpOpPtr = OpPtr*4; i++; find_new_func = 1; } } /* Following for safety only; all should always be false */ if(i != jump_index || jump_control[i - 1].type != 4 || jump_control[0].type != 1) { return 1; } while(i > 0) { i--; i = fill_if_group(i, jump_data); } return i < 0 ? 1 : 0; } extern int fform_per_pixel(void); /* these fns are in parsera.asm */ extern int BadFormula(void); extern void (far Img_Setup )(void); int CvtStk() { /* convert the array of ptrs */ extern char FormName[]; void (far *ftst)(void); void (near *ntst)(void); union Arg far *testoperand; struct fn_entry far *pfe; int fnfound; lastsqrreal = 1; /* assume lastsqr is real (not stored explicitly) */ p1const = p2const = p3const = (unsigned char)1; /* . . . p1, p2, p3 const */ p4const = p5const = (unsigned char)1; /* . . . p4, p5 const */ lastsqrused = 0; /* ... and LastSqr is not used */ /* now see if the above assumptions are true */ for (OpPtr = LodPtr = StoPtr = 0; OpPtr < (int)LastOp; OpPtr++ ){ ftst = f[OpPtr]; if (ftst == StkLod ){ if (Load[LodPtr++] == &LASTSQR ){ lastsqrused = 1; } } else if (ftst == StkSto ){ testoperand = Store[StoPtr++]; if (testoperand == &PARM1 ){ p1const = 0; } else if (testoperand == &PARM2 ){ p2const = 0; } else if (testoperand == &PARM3 ){ p3const = 0; } else if (testoperand == &PARM4 ){ p4const = 0; } else if (testoperand == &PARM5 ){ p5const = 0; } else if (testoperand == &LASTSQR ){ lastsqrreal = 0; } } } if (!p1const) { DBUGMSG(0, "p1 not constant" ); } if (!p2const) { DBUGMSG(0, "p2 not constant" ); } if (!p3const) { DBUGMSG(0, "p3 not constant" ); } if (!p4const) { DBUGMSG(0, "p4 not constant" ); } if (!p5const) { DBUGMSG(0, "p5 not constant" ); } if (lastsqrused) { DBUGMSG(0, "LastSqr loaded" ); if (!lastsqrreal) { DBUGMSG(0, "LastSqr stored" ); } } if (f[LastOp-1] != StkClr ){ DBUGMSG(0, "Missing clr added at end" ); /* should be safe to modify this */ f[LastOp++] = StkClr; } prevfptr = (void (near *)(void))0; cvtptrx = realstkcnt = stkcnt = 0; for (OpPtr = LodPtr = StoPtr = 0; OpPtr < (int)LastOp; OpPtr++) { ftst = f[OpPtr]; fnfound = 0; for (pfe = &afe[0]; pfe <= &afe[LAST_OLD_FN]; pfe++ ){ if (ftst == pfe->infn ){ fnfound = 1; ntst = pfe->outfn; if (ntst == fStkClr1 && OpPtr == (int)(LastOp-1) ){ ntst = fStkClr2; /* convert the last clear to a clr2 */ DBUGMSG(0, "Last fn (CLR) --> (is really CLR2)" ); } if (ntst == fStkIdent && debugflag != 322 ){ /* ident will be skipped here */ /* this is really part of the optimizer */ DBUGMSG(0, "IDENT was skipped" ); } else { #ifndef XFRACT DBUGMSG4(0, "fn=%Fs, minstk=%1i, freestk=%1i, delta=%3i", pfe->fname, (int)(pfe->min_regs), (int)(pfe->free_regs), (int)(pfe->delta) ); #else DBUGMSG4(0, "fn=%s, minstk=%1i, freestk=%1i, delta=%3i", pfe->fname, (int)(pfe->min_regs), (int)(pfe->free_regs), (int)(pfe->delta) ); #endif if (!CvtFptr(ntst, pfe->min_regs, pfe->free_regs, pfe->delta) ){ return 1; } } } } if (!fnfound ){ /* return success so old code will be used */ /* stopmsg(0, "Fast 387 parser failed, reverting to slower code." );*/ return 1; /* this should only happen if random numbers are used */ } } /* end for */ if (debugflag == 322 ){ goto skipfinalopt; } /* ------------------------------ final optimizations ---------- */ /* cvtptrx -> one past last operator (always clr2) */ --cvtptrx; /* now it points to the last operator */ ntst = FNPTR(cvtptrx-1); /* ntst is the next-to-last operator */ if (ntst == fStkLT ){ DBUGMSG(0, "LT Clr2 -> LT2" ); FNPTR(cvtptrx-1) = fStkLT2; } else if (ntst == fStkLodLT ){ DBUGMSG(0, "LodLT Clr2 -> LodLT2" ); FNPTR(cvtptrx-1) = fStkLodLT2; } else if (ntst == fStkLTE ){ DBUGMSG(0, "LTE Clr2 -> LTE2" ); FNPTR(cvtptrx-1) = fStkLTE2; } else if (ntst == fStkLodLTE ){ DBUGMSG(0, "LodLTE Clr2 -> LodLTE2" ); FNPTR(cvtptrx-1) = fStkLodLTE2; } else if (ntst == fStkGT ){ DBUGMSG(0, "GT Clr2 -> GT2" ); FNPTR(cvtptrx-1) = fStkGT2; } else if (ntst == fStkLodGT ){ DBUGMSG(0, "LodGT Clr2 -> LodGT2" ); FNPTR(cvtptrx-1) = fStkLodGT2; } else if (ntst == fStkLodGTE ){ DBUGMSG(0, "LodGTE Clr2 -> LodGTE2" ); FNPTR(cvtptrx-1) = fStkLodGTE2; } else if (ntst == fStkAND ){ DBUGMSG(0, "AND Clr2 -> ANDClr2" ); FNPTR(cvtptrx-1) = fStkANDClr2; ntst = FNPTR(cvtptrx-2); if (ntst == fStkLodLTE ){ DBUGMSG(0, "LodLTE ANDClr2 -> LodLTEAnd2" ); --cvtptrx; FNPTR(cvtptrx-1) = fStkLodLTEAnd2; } } else if (ntst == fStkOR ){ /* CAE 06NOV93 */ DBUGMSG(0, "OR Clr2 -> ORClr2" ); FNPTR(cvtptrx-1) = fStkORClr2; } else { ++cvtptrx; /* adjust this back since no optimization was found */ } skipfinalopt: /* -------------- end of final optimizations ------------ */ LastOp = cvtptrx; /* save the new operator count */ LASTSQR.d.y = 0.0; /* do this once per image */ /* now change the pointers */ if (FormName[0] != 0 && (uses_jump == 0 || fpfill_jump_struct() == 0)){ /* but only if parse succeeded */ curfractalspecific->per_pixel = fform_per_pixel; curfractalspecific->orbitcalc = fFormula; } else { curfractalspecific->per_pixel = BadFormula; curfractalspecific->orbitcalc = BadFormula; } Img_Setup(); /* call assembler setup code */ return 1; } #endif /* XFRACT */ xfractint-20.4.10.orig/common/editpal.c0000644000000000000000000025672311257714555014616 0ustar /* * editpal.c * * Edits VGA 256-color palettes. * * Key to initials: * * EAN - Ethan Nagel [70022,2552] * * JJB - Juan J. Buhler [jbuhler@gidef.edu.ar] * * TIW - Tim Wegner * * AMC - Andrew McCarthy [andrewmc@netsoc.ucd.ie] * * Revision History: * * 10-22-90 EAN Initial release. * * 10-23-90 EAN "Discovered" get_line/put_line functions, integrated * them in (instead of only getcolor/putcolor). Much * faster! * Redesigned color editors (now at top of palette) and * re-assigned some keys. * Added (A)uto option. * Fixed memory allocation problem. Now uses shared * FRACTINT data area (strlocn). Uses 6 bytes DS. * * 10-27-90 EAN Added save to memory option - will save screen image to * memory, if enough mem avail. (disk otherwise). * Added s(T)ripe mode - works like (S)hade except only * changes every n'th entry. * Added temporary palette save/restore. (Can work like * an undo feature.) Thanks to Pieter Branderhorst for * idea. * * 10-28-90 EAN The (H)ide function now makes the palette invisible, * while allowing any other operations (except '\\' - * move/resize) to continue. * * 10-29-90 PB (in EAN's absence, ) * Change 'c' to 'd' and 's' to '=' for below. * Add 'l' to load palette from .map, 's' to store .map. * Add 'c' to invoke color cycling. * Change cursor to use whatever colors it can from * the palette (not fixed 0 and 255). * Restore colors 0 and 255 to real values whenever * palette is not on display. * Rotate 255 colors instead of 254. * Reduce cursor blink rate. * * 11-15-90 EAN Minor "bug" fixes. Continuous rotation now at a fixed * rate - once every timer tick (18.2 sec); Blanks out * color samples when rotating; Editors no longer rotate * with the colors in color rotation mode; Eliminated * (Z)oom mode; other minor fixes. * * 01-05-91 PB Add 'w' function to convert to greyscale. * * 01-16-91 PB Change rotate function to use new cyclerange stuff. * * 01-29-91 EAN Made all colors editable. The two reserved colors are * X'ed out. They can be edited but the color is not * visible. (There is an X over the sample instead.) * Changed default reserved colors to 254 & 255. * Added 'v' command to set the reserved colors to those * under the editors. * Added 'o' command to set the rotate range to between * the two editors. * Modified 'w' function: * uses internal function to do conversion (not BIOS) * will convert only current color if in 'x' mode or * range between editors in 'y' mode or entire palette * if in "normal" mode. * * 02-08-91 EAN Improved 16 color support. In 16 color mode, colors * 16-255 have a dot over them and are editable but not * visible (like the two reserved colors). * * 09-08-91 SWT Added 'n' command to make a negative color palette: * will convert only current color if in 'x' mode or * range between editors in 'y' mode or entire palette * if in "normal" mode. * * 03-03-92 JJB Added '!', '@' and '#' commands to swap RG, GB and * RB columns (sorry, I didn't find better keys) * * 10-03-92 TIW Minor changes for Jiim support, primarily changing * variables from static to global. * * 2-11-93 EAN Added full Undo ('U' key) and Redo ('E' key) * capability. Works pretty much as you'd expect * it to. * * 3-6-93 EAN Modified "freestyle" mode, written by RB, to integrate * into palette editor more completely and work with * undo logic. * Added status area under the "fractint" message to * display current state of editor. A = Auto mode, * X, Y = exclusion modes, F = freesyle mode, T = stripe * mode is waiting for #. * * 03-21-97 AMC Made '"' work the same as '@' and made '�' work like * '#' for those of us on this side of the Atlantic! * The original palette is now stored in the other slots * on startup, so you can 'undo all' if you haven't * overwritten them already. Undo could do this, but * this is handy. * 05-22-97 TIW Replaced movedata with far_memcopy() */ #ifdef DEBUG_UNDO #include "mdisp.h" /* EAN 930211 *** Debug Only *** */ #endif #include #ifndef USE_VARARGS #include #else #include #endif #ifdef __TURBOC__ # include /* to get mem...() declarations */ #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" /* * misc. #defines */ #define FONT_DEPTH 8 /* font size */ #define CSIZE_MIN 8 /* csize cannot be smaller than this */ #define CURSOR_SIZE 5 /* length of one side of the x-hair cursor */ #ifndef XFRACT #define CURSOR_BLINK_RATE 3 /* timer ticks between cursor blinks */ #else #define CURSOR_BLINK_RATE 300 /* timer ticks between cursor blinks */ #endif #define FAR_RESERVE 8192L /* amount of far mem we will leave avail. */ #define MAX_WIDTH 1024 /* palette editor cannot be wider than this */ char scrnfile[] = "FRACTINT.$$1"; /* file where screen portion is */ /* stored */ char undofile[] = "FRACTINT.$$2"; /* file where undo list is stored */ #define TITLE "FRACTINT" #define TITLE_LEN (8) #define newx(size) mem_alloc(size) #define new(class) (class *)(mem_alloc(sizeof(class))) #define delete(block) block=NULL /* just for warning */ #ifdef XFRACT int editpal_cursor = 0; #endif /* * Stuff from fractint */ #if 0 /* declarations moved to PRORTOTYPE.H - this left for docs */ BYTE dacbox[256][3]; /* DAC spindac() will use */ int sxdots; /* width of physical screen */ int sydots; /* depth of physical screen */ int sxoffs; /* start of logical screen */ int syoffs; /* start of logical screen */ int lookatmouse; /* mouse mode for getakey(), etc */ int strlocn[]; /* 10K buffer to store classes in */ int colors; /* # colors avail. */ int color_bright; /* brightest color in palette */ int color_dark; /* darkest color in palette */ int color_medium; /* nearest to medbright gray color */ int rotate_lo, rotate_hi; int debugflag; #endif int using_jiim = 0; /* * basic data types */ typedef struct { BYTE red, green, blue; } PALENTRY; /* * static data */ static BYTE far *font8x8 = NULL; BYTE *line_buff; /* must be alloced!!! */ static BYTE fg_color, bg_color; static BOOLEAN reserve_colors; static BOOLEAN inverse; static float gamma_val = 1; /* * Interface to FRACTINT's graphics stuff */ static void setpal(int pal, int r, int g, int b) { dacbox[pal][0] = (BYTE)r; dacbox[pal][1] = (BYTE)g; dacbox[pal][2] = (BYTE)b; spindac(0,1); } static void setpalrange(int first, int how_many, PALENTRY *pal) { memmove(dacbox+first, pal, how_many*3); spindac(0,1); } static void getpalrange(int first, int how_many, PALENTRY *pal) { memmove(pal, dacbox+first, how_many*3); } static void rotatepal(PALENTRY *pal, int dir, int lo, int hi) { /* rotate in either direction */ PALENTRY hold; int size; size = 1 + (hi-lo); if ( dir > 0 ) { while ( dir-- > 0 ) { memmove(&hold, &pal[hi], 3); memmove(&pal[lo+1], &pal[lo], 3*(size-1)); memmove(&pal[lo], &hold, 3); } } else if ( dir < 0 ) { while ( dir++ < 0 ) { memmove(&hold, &pal[lo], 3); memmove(&pal[lo], &pal[lo+1], 3*(size-1)); memmove(&pal[hi], &hold, 3); } } } static void clip_put_line(int row, int start, int stop, BYTE *pixels) { if ( row < 0 || row >= sydots || start > sxdots || stop < 0 ) return ; if ( start < 0 ) { pixels += -start; start = 0; } if ( stop >= sxdots ) stop = sxdots - 1; if ( start > stop ) return ; put_line(row, start, stop, pixels); } static void clip_get_line(int row, int start, int stop, BYTE *pixels) { if ( row < 0 || row >= sydots || start > sxdots || stop < 0 ) return ; if ( start < 0 ) { pixels += -start; start = 0; } if ( stop >= sxdots ) stop = sxdots - 1; if ( start > stop ) return ; get_line(row, start, stop, pixels); } void clip_putcolor(int x, int y, int color) { if ( x < 0 || y < 0 || x >= sxdots || y >= sydots ) return ; putcolor(x, y, color); } int clip_getcolor(int x, int y) { if ( x < 0 || y < 0 || x >= sxdots || y >= sydots ) return (0); return ( getcolor(x, y) ); } static void hline(int x, int y, int width, int color) { memset(line_buff, color, width); clip_put_line(y, x, x+width-1, line_buff); } static void vline(int x, int y, int depth, int color) { while (depth-- > 0) clip_putcolor(x, y++, color); } void getrow(int x, int y, int width, char *buff) { clip_get_line(y, x, x+width-1, (BYTE *)buff); } void putrow(int x, int y, int width, char *buff) { clip_put_line(y, x, x+width-1, (BYTE *)buff); } static void vgetrow(int x, int y, int depth, char *buff) { while (depth-- > 0) *buff++ = (char)clip_getcolor(x, y++); } static void vputrow(int x, int y, int depth, char *buff) { while (depth-- > 0) clip_putcolor(x, y++, (BYTE)(*buff++)); } static void fillrect(int x, int y, int width, int depth, int color) { while (depth-- > 0) hline(x, y++, width, color); } static void rect(int x, int y, int width, int depth, int color) { hline(x, y, width, color); hline(x, y+depth-1, width, color); vline(x, y, depth, color); vline(x+width-1, y, depth, color); } void displayc(int x, int y, int fg, int bg, int ch) { int xc, yc; BYTE t; BYTE far *ptr; if( font8x8 == NULL) if ( (font8x8 = findfont(0)) == NULL ) return ; ptr = ((BYTE far *)font8x8) + ch*FONT_DEPTH; for (yc=0; ycred - (int) p1->red ) / num, gm = (double)((int) p2->green - (int) p1->green) / num, bm = (double)((int) p2->blue - (int) p1->blue ) / num; for (curr=0; currred == p2->red ) ? p1->red : (int) p1->red + (int) ( rm * curr )); pal[curr].green = (BYTE)((p1->green == p2->green) ? p1->green : (int) p1->green + (int) ( gm * curr )); pal[curr].blue = (BYTE)((p1->blue == p2->blue ) ? p1->blue : (int) p1->blue + (int) ( bm * curr )); } else { pal[curr].red = (BYTE)((p1->red == p2->red ) ? p1->red : (int) (p1->red + pow(curr/(double)(num-1),gamma_val)*num*rm)); pal[curr].green = (BYTE)((p1->green == p2->green) ? p1->green : (int) (p1->green + pow(curr/(double)(num-1),gamma_val)*num*gm)); pal[curr].blue = (BYTE)((p1->blue == p2->blue ) ? p1->blue : (int) (p1->blue + pow(curr/(double)(num-1),gamma_val)*num*bm)); } } } /* Swap RG GB & RB columns */ static void rotcolrg(PALENTRY pal[], int num) { int curr; int dummy; for (curr=0; curr<=num; curr++) { dummy = pal[curr].red; pal[curr].red = pal[curr].green; pal[curr].green = (BYTE)dummy; } } static void rotcolgb(PALENTRY pal[], int num) { int curr; int dummy; for (curr=0; curr<=num; curr++) { dummy = pal[curr].green; pal[curr].green = pal[curr].blue; pal[curr].blue = (BYTE)dummy; } } static void rotcolbr(PALENTRY pal[], int num) { int curr; int dummy; for (curr=0; curr<=num; curr++) { dummy = pal[curr].red; pal[curr].red = pal[curr].blue; pal[curr].blue = (BYTE)dummy; } } /* * convert a range of colors to grey scale */ static void palrangetogrey(PALENTRY pal[], int first, int how_many) { PALENTRY *curr; BYTE val; for (curr = &pal[first]; how_many>0; how_many--, curr++) { val = (BYTE) ( ((int)curr->red*30 + (int)curr->green*59 + (int)curr->blue*11) / 100 ); curr->red = curr->green = curr->blue = (BYTE)val; } } /* * convert a range of colors to their inverse */ static void palrangetonegative(PALENTRY pal[], int first, int how_many) { PALENTRY *curr; for (curr = &pal[first]; how_many>0; how_many--, curr++) { curr->red = (BYTE)(63 - curr->red); curr->green = (BYTE)(63 - curr->green); curr->blue = (BYTE)(63 - curr->blue); } } /* * draw and horizontal/vertical dotted lines */ static void hdline(int x, int y, int width) { int ctr; BYTE *ptr; for (ctr=0, ptr=line_buff; ctr= bx) && (y >= by) && (x < bx+bw) && (y < by+bd)) ); } static void draw_diamond(int x, int y, int color) { putcolor (x+2, y+0, color); hline (x+1, y+1, 3, color); hline (x+0, y+2, 5, color); hline (x+1, y+3, 3, color); putcolor (x+2, y+4, color); } /* * Class: Cursor * * Purpose: Draw the blinking cross-hair cursor. * * Note: Only one Cursor can exist (referenced through the_cursor). * IMPORTANT: Call Cursor_Construct before you use any other * Cursor_ function! Call Cursor_Destroy before exiting to * deallocate memory. */ struct _Cursor { int x, y; int hidden; /* >0 if mouse hidden */ long last_blink; BOOLEAN blink; #if 0 char t[CURSOR_SIZE], /* save line segments here */ b[CURSOR_SIZE], l[CURSOR_SIZE], r[CURSOR_SIZE]; #endif char t[CURSOR_SIZE]; /* save line segments here */ char b[CURSOR_SIZE]; char l[CURSOR_SIZE]; char r[CURSOR_SIZE]; } ; #define Cursor struct _Cursor /* private: */ static void Cursor__Draw (void); static void Cursor__Save (void); static void Cursor__Restore (void); /* public: */ #ifdef NOT_USED static BOOLEAN Cursor_IsHidden (void); #endif static Cursor *the_cursor = NULL; BOOLEAN Cursor_Construct(void) { if (the_cursor != NULL) return(FALSE); the_cursor = new(Cursor); the_cursor->x = sxdots/2; the_cursor->y = sydots/2; the_cursor->hidden = 1; the_cursor->blink = FALSE; the_cursor->last_blink = 0; return (TRUE); } void Cursor_Destroy(void) { if (the_cursor != NULL) delete(the_cursor); the_cursor = NULL; } static void Cursor__Draw(void) { int color; find_special_colors(); color = (the_cursor->blink) ? color_medium : color_dark; vline(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, color); vline(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, color); hline(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, color); hline(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, color); } static void Cursor__Save(void) { vgetrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t); vgetrow(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, the_cursor->b); getrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, the_cursor->l); getrow(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, the_cursor->r); } static void Cursor__Restore(void) { vputrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t); vputrow(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, the_cursor->b); putrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, the_cursor->l); putrow(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, the_cursor->r); } void Cursor_SetPos(int x, int y) { if (!the_cursor->hidden) Cursor__Restore(); the_cursor->x = x; the_cursor->y = y; if (!the_cursor->hidden) { Cursor__Save(); Cursor__Draw(); } } #ifdef NOT_USED static int Cursor_IsHidden(void) { return ( the_cursor->hidden ); } #endif void Cursor_Move(int xoff, int yoff) { if ( !the_cursor->hidden ) Cursor__Restore(); the_cursor->x += xoff; the_cursor->y += yoff; if (the_cursor->x < 0) the_cursor->x = 0; if (the_cursor->y < 0) the_cursor->y = 0; if (the_cursor->x >= sxdots) the_cursor->x = sxdots-1; if (the_cursor->y >= sydots) the_cursor->y = sydots-1; if ( !the_cursor->hidden ) { Cursor__Save(); Cursor__Draw(); } } int Cursor_GetX(void) { return(the_cursor->x); } int Cursor_GetY(void) { return(the_cursor->y); } void Cursor_Hide(void) { if ( the_cursor->hidden++ == 0 ) Cursor__Restore(); } void Cursor_Show(void) { if ( --the_cursor->hidden == 0) { Cursor__Save(); Cursor__Draw(); } } #ifdef XFRACT void Cursor_StartMouseTracking() { editpal_cursor = 1; } void Cursor_EndMouseTracking() { editpal_cursor = 0; } #endif /* See if the cursor should blink yet, and blink it if so */ void Cursor_CheckBlink(void) { long tick; tick = readticker(); if ( (tick - the_cursor->last_blink) > CURSOR_BLINK_RATE ) { the_cursor->blink = (BOOLEAN)((the_cursor->blink) ? FALSE : TRUE); the_cursor->last_blink = tick; if ( !the_cursor->hidden ) Cursor__Draw(); } else if ( tick < the_cursor->last_blink ) the_cursor->last_blink = tick; } int Cursor_WaitKey(void) /* blink cursor while waiting for a key */ { #ifndef XFRACT while ( !keypressed() ) { Cursor_CheckBlink(); } #else while ( !waitkeypressed(1) ) { Cursor_CheckBlink(); } #endif return( keypressed() ); } /* * Class: MoveBox * * Purpose: Handles the rectangular move/resize box. */ struct _MoveBox { int x, y; int base_width, base_depth; int csize; BOOLEAN moved; BOOLEAN should_hide; char *t, *b, *l, *r; } ; #define MoveBox struct _MoveBox /* private: */ static void MoveBox__Draw (MoveBox *this); static void MoveBox__Erase (MoveBox *this); static void MoveBox__Move (MoveBox *this, int key); /* public: */ static MoveBox *MoveBox_Construct (int x, int y, int csize, int base_width, int base_depth); static void MoveBox_Destroy (MoveBox *this); static BOOLEAN MoveBox_Process (MoveBox *this); /* returns FALSE if ESCAPED */ static BOOLEAN MoveBox_Moved (MoveBox *this); static BOOLEAN MoveBox_ShouldHide (MoveBox *this); static int MoveBox_X (MoveBox *this); static int MoveBox_Y (MoveBox *this); static int MoveBox_CSize (MoveBox *this); static void MoveBox_SetPos (MoveBox *this, int x, int y); static void MoveBox_SetCSize (MoveBox *this, int csize); static MoveBox *MoveBox_Construct(int x, int y, int csize, int base_width, int base_depth) { MoveBox *this = new(MoveBox); this->x = x; this->y = y; this->csize = csize; this->base_width = base_width; this->base_depth = base_depth; this->moved = FALSE; this->should_hide = FALSE; this->t = newx(sxdots); this->b = newx(sxdots); this->l = newx(sydots); this->r = newx(sydots); return(this); } static void MoveBox_Destroy(MoveBox *this) { delete(this->t); delete(this->b); delete(this->l); delete(this->r); delete(this); } static BOOLEAN MoveBox_Moved(MoveBox *this) { return(this->moved); } static BOOLEAN MoveBox_ShouldHide(MoveBox *this) { return(this->should_hide); } static int MoveBox_X(MoveBox *this) { return(this->x); } static int MoveBox_Y(MoveBox *this) { return(this->y); } static int MoveBox_CSize(MoveBox *this) { return(this->csize); } static void MoveBox_SetPos(MoveBox *this, int x, int y) { this->x = x; this->y = y; } static void MoveBox_SetCSize(MoveBox *this, int csize) { this->csize = csize; } static void MoveBox__Draw(MoveBox *this) /* private */ { int width = this->base_width + this->csize*16+1, depth = this->base_depth + this->csize*16+1; int x = this->x, y = this->y; getrow (x, y, width, this->t); getrow (x, y+depth-1, width, this->b); vgetrow(x, y, depth, this->l); vgetrow(x+width-1, y, depth, this->r); hdline(x, y, width); hdline(x, y+depth-1, width); vdline(x, y, depth); vdline(x+width-1, y, depth); } static void MoveBox__Erase(MoveBox *this) /* private */ { int width = this->base_width + this->csize*16+1, depth = this->base_depth + this->csize*16+1; vputrow(this->x, this->y, depth, this->l); vputrow(this->x+width-1, this->y, depth, this->r); putrow(this->x, this->y, width, this->t); putrow(this->x, this->y+depth-1, width, this->b); } #define BOX_INC 1 #define CSIZE_INC 2 static void MoveBox__Move(MoveBox *this, int key) { BOOLEAN done = FALSE; BOOLEAN first = TRUE; int xoff = 0, yoff = 0; while ( !done ) { switch(key) { case RIGHT_ARROW_2: xoff += BOX_INC*4; break; case RIGHT_ARROW: xoff += BOX_INC; break; case LEFT_ARROW_2: xoff -= BOX_INC*4; break; case LEFT_ARROW: xoff -= BOX_INC; break; case DOWN_ARROW_2: yoff += BOX_INC*4; break; case DOWN_ARROW: yoff += BOX_INC; break; case UP_ARROW_2: yoff -= BOX_INC*4; break; case UP_ARROW: yoff -= BOX_INC; break; default: done = TRUE; } if (!done) { if (!first) getakey(); /* delete key from buffer */ else first = FALSE; key = keypressed(); /* peek at the next one... */ } } xoff += this->x; yoff += this->y; /* (xoff,yoff) = new position */ if (xoff < 0) xoff = 0; if (yoff < 0) yoff = 0; if (xoff+this->base_width+this->csize*16+1 > sxdots) xoff = sxdots - (this->base_width+this->csize*16+1); if (yoff+this->base_depth+this->csize*16+1 > sydots) yoff = sydots - (this->base_depth+this->csize*16+1); if ( xoff!=this->x || yoff!=this->y ) { MoveBox__Erase(this); this->y = yoff; this->x = xoff; MoveBox__Draw(this); } } static BOOLEAN MoveBox_Process(MoveBox *this) { int key; int orig_x = this->x, orig_y = this->y, orig_csize = this->csize; MoveBox__Draw(this); #ifdef XFRACT Cursor_StartMouseTracking(); #endif for(;;) { Cursor_WaitKey(); key = getakey(); if (key==ENTER || key==ENTER_2 || key==ESC || key=='H' || key=='h') { if (this->x != orig_x || this->y != orig_y || this->csize != orig_csize) this->moved = TRUE; else this->moved = FALSE; break; } switch(key) { case UP_ARROW: case DOWN_ARROW: case LEFT_ARROW: case RIGHT_ARROW: case UP_ARROW_2: case DOWN_ARROW_2: case LEFT_ARROW_2: case RIGHT_ARROW_2: MoveBox__Move(this, key); break; case PAGE_UP: /* shrink */ if (this->csize > CSIZE_MIN) { int t = this->csize - CSIZE_INC; int change; if (t < CSIZE_MIN) t = CSIZE_MIN; MoveBox__Erase(this); change = this->csize - t; this->csize = t; this->x += (change*16) / 2; this->y += (change*16) / 2; MoveBox__Draw(this); } break; case PAGE_DOWN: /* grow */ { int max_width = min(sxdots, MAX_WIDTH); if (this->base_depth+(this->csize+CSIZE_INC)*16+1 < sydots && this->base_width+(this->csize+CSIZE_INC)*16+1 < max_width ) { MoveBox__Erase(this); this->x -= (CSIZE_INC*16) / 2; this->y -= (CSIZE_INC*16) / 2; this->csize += CSIZE_INC; if (this->y+this->base_depth+this->csize*16+1 > sydots) this->y = sydots - (this->base_depth+this->csize*16+1); if (this->x+this->base_width+this->csize*16+1 > max_width) this->x = max_width - (this->base_width+this->csize*16+1); if (this->y < 0) this->y = 0; if (this->x < 0) this->x = 0; MoveBox__Draw(this); } } break; } } #ifdef XFRACT Cursor_EndMouseTracking(); #endif MoveBox__Erase(this); this->should_hide = (BOOLEAN)((key == 'H' || key == 'h') ? TRUE : FALSE); return( (BOOLEAN)((key==ESC) ? FALSE : TRUE) ); } /* * Class: CEditor * * Purpose: Edits a single color component (R, G or B) * * Note: Calls the "other_key" function to process keys it doesn't use. * The "change" function is called whenever the value is changed * by the CEditor. */ struct _CEditor { int x, y; char letter; int val; BOOLEAN done; BOOLEAN hidden; #ifndef XFRACT void (*other_key)(int key, struct _CEditor *ce, VOIDPTR info); void (*change)(struct _CEditor *ce, VOIDPTR info); #else void (*other_key)(); void (*change)(); #endif void *info; } ; #define CEditor struct _CEditor /* public: */ #ifndef XFRACT static CEditor *CEditor_Construct( int x, int y, char letter, void (*other_key)(int,CEditor*,void*), void (*change)(CEditor*,void*), VOIDPTR info); static void CEditor_Destroy (CEditor *this); static void CEditor_Draw (CEditor *this); static void CEditor_SetPos (CEditor *this, int x, int y); static void CEditor_SetVal (CEditor *this, int val); static int CEditor_GetVal (CEditor *this); static void CEditor_SetDone (CEditor *this, BOOLEAN done); static void CEditor_SetHidden (CEditor *this, BOOLEAN hidden); static int CEditor_Edit (CEditor *this); #else static CEditor *CEditor_Construct( int , int , char , void (*other_key)(), void (*change)(), VOIDPTR ); static void CEditor_Destroy (CEditor *); static void CEditor_Draw (CEditor *); static void CEditor_SetPos (CEditor *, int , int ); static void CEditor_SetVal (CEditor *, int ); static int CEditor_GetVal (CEditor *); static void CEditor_SetDone (CEditor *, BOOLEAN ); static void CEditor_SetHidden (CEditor *, BOOLEAN ); static int CEditor_Edit (CEditor *); #endif #define CEditor_WIDTH (8*3+4) #define CEditor_DEPTH (8+4) #ifndef XFRACT static CEditor *CEditor_Construct( int x, int y, char letter, void (*other_key)(int,CEditor*,VOIDPTR), void (*change)(CEditor*, VOIDPTR), VOIDPTR info) #else static CEditor *CEditor_Construct( int x, int y, char letter, void (*other_key)(), void (*change)(), VOIDPTR info) #endif { CEditor *this = new(CEditor); this->x = x; this->y = y; this->letter = letter; this->val = 0; this->other_key = other_key; this->hidden = FALSE; this->change = change; this->info = info; return(this); } #ifdef __TURBOC__ # pragma argsused /* kills "arg not used" warning */ #endif #ifdef __CLINT__ # pragma argsused /* kills "arg not used" warning */ #endif static void CEditor_Destroy(CEditor *this) { delete(this); } static void CEditor_Draw(CEditor *this) { if (this->hidden) return; Cursor_Hide(); displayf(this->x+2, this->y+2, fg_color, bg_color, "%c%02d", this->letter, this->val); Cursor_Show(); } static void CEditor_SetPos(CEditor *this, int x, int y) { this->x = x; this->y = y; } static void CEditor_SetVal(CEditor *this, int val) { this->val = val; } static int CEditor_GetVal(CEditor *this) { return(this->val); } static void CEditor_SetDone(CEditor *this, BOOLEAN done) { this->done = done; } static void CEditor_SetHidden(CEditor *this, BOOLEAN hidden) { this->hidden = hidden; } static int CEditor_Edit(CEditor *this) { int key = 0; int diff; this->done = FALSE; if (!this->hidden) { Cursor_Hide(); rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, fg_color); Cursor_Show(); } #ifdef XFRACT Cursor_StartMouseTracking(); #endif while ( !this->done ) { Cursor_WaitKey(); key = getakey(); switch( key ) { case PAGE_UP: if (this->val < 63) { this->val += 5; if (this->val > 63) this->val = 63; CEditor_Draw(this); this->change(this, this->info); } break; case '+': case CTL_PLUS: /*RB*/ diff = 1; while ( keypressed() == key ) { getakey(); ++diff; } if (this->val < 63) { this->val += diff; if (this->val > 63) this->val = 63; CEditor_Draw(this); this->change(this, this->info); } break; case PAGE_DOWN: if (this->val > 0) { this->val -= 5; if (this->val < 0) this->val = 0; CEditor_Draw(this); this->change(this, this->info); } break; case '-': case CTL_MINUS: /*RB*/ diff = 1; while ( keypressed() == key ) { getakey(); ++diff; } if (this->val > 0) { this->val -= diff; if (this->val < 0) this->val = 0; CEditor_Draw(this); this->change(this, this->info); } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': this->val = (key - '0') * 10; if (this->val > 63) this->val = 63; CEditor_Draw(this); this->change(this, this->info); break; default: this->other_key(key, this, this->info); break; } /* switch */ } /* while */ #ifdef XFRACT Cursor_EndMouseTracking(); #endif if (!this->hidden) { Cursor_Hide(); rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, bg_color); Cursor_Show(); } return(key); } /* * Class: RGBEditor * * Purpose: Edits a complete color using three CEditors for R, G and B */ struct _RGBEditor { int x, y; /* position */ int curr; /* 0=r, 1=g, 2=b */ int pal; /* palette number */ BOOLEAN done; BOOLEAN hidden; CEditor *color[3]; /* color editors 0=r, 1=g, 2=b */ #ifndef XFRACT void (*other_key)(int key, struct _RGBEditor *e, VOIDPTR info); void (*change)(struct _RGBEditor *e, VOIDPTR info); #else void (*other_key)(); void (*change)(); #endif void *info; } ; #define RGBEditor struct _RGBEditor /* private: */ static void RGBEditor__other_key (int key, CEditor *ceditor, VOIDPTR info); static void RGBEditor__change (CEditor *ceditor, VOIDPTR info); /* public: */ #ifndef XFRACT static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(int,RGBEditor*,void*), void (*change)(RGBEditor*,void*), VOIDPTR info); #else static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(), void (*change)(), VOIDPTR info); #endif static void RGBEditor_Destroy (RGBEditor *this); static void RGBEditor_SetPos (RGBEditor *this, int x, int y); static void RGBEditor_SetDone (RGBEditor *this, BOOLEAN done); static void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden); static void RGBEditor_BlankSampleBox(RGBEditor *this); static void RGBEditor_Update (RGBEditor *this); static void RGBEditor_Draw (RGBEditor *this); static int RGBEditor_Edit (RGBEditor *this); static void RGBEditor_SetRGB (RGBEditor *this, int pal, PALENTRY *rgb); static PALENTRY RGBEditor_GetRGB (RGBEditor *this); #define RGBEditor_WIDTH 62 #define RGBEditor_DEPTH (1+1+CEditor_DEPTH*3-2+2) #define RGBEditor_BWIDTH ( RGBEditor_WIDTH - (2+CEditor_WIDTH+1 + 2) ) #define RGBEditor_BDEPTH ( RGBEditor_DEPTH - 4 ) #ifndef XFRACT static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(int,RGBEditor*,void*), void (*change)(RGBEditor*,void*), VOIDPTR info) #else static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(), void (*change)(), VOIDPTR info) #endif { RGBEditor *this = new(RGBEditor); static FCODE letter[] = "RGB"; int ctr; for (ctr=0; ctr<3; ctr++) this->color[ctr] = CEditor_Construct(0, 0, letter[ctr], RGBEditor__other_key, RGBEditor__change, this); RGBEditor_SetPos(this, x, y); this->curr = 0; this->pal = 1; this->hidden = FALSE; this->other_key = other_key; this->change = change; this->info = info; return(this); } static void RGBEditor_Destroy(RGBEditor *this) { CEditor_Destroy(this->color[0]); CEditor_Destroy(this->color[1]); CEditor_Destroy(this->color[2]); delete(this); } static void RGBEditor_SetDone(RGBEditor *this, BOOLEAN done) { this->done = done; } static void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden) { this->hidden = hidden; CEditor_SetHidden(this->color[0], hidden); CEditor_SetHidden(this->color[1], hidden); CEditor_SetHidden(this->color[2], hidden); } static void RGBEditor__other_key(int key, CEditor *ceditor, VOIDPTR info) /* private */ { RGBEditor *this = (RGBEditor *)info; switch( key ) { case 'R': case 'r': if (this->curr != 0) { this->curr = 0; CEditor_SetDone(ceditor, TRUE); } break; case 'G': case 'g': if (this->curr != 1) { this->curr = 1; CEditor_SetDone(ceditor, TRUE); } break; case 'B': case 'b': if (this->curr != 2) { this->curr = 2; CEditor_SetDone(ceditor, TRUE); } break; case DELETE: /* move to next CEditor */ case CTL_ENTER_2: /*double click rt mouse also! */ if ( ++this->curr > 2) this->curr = 0; CEditor_SetDone(ceditor, TRUE); break; case INSERT: /* move to prev CEditor */ if ( --this->curr < 0) this->curr = 2; CEditor_SetDone(ceditor, TRUE); break; default: this->other_key(key, this, this->info); if (this->done) CEditor_SetDone(ceditor, TRUE); break; } } #ifdef __TURBOC__ # pragma argsused /* kills "arg not used" warning */ #endif #ifdef __CLINT__ # pragma argsused /* kills "arg not used" warning */ #endif static void RGBEditor__change(CEditor *ceditor, VOIDPTR info) /* private */ { RGBEditor *this = (RGBEditor *)info; ceditor = NULL; /* just for warning */ if ( this->pal < colors && !is_reserved(this->pal) ) setpal(this->pal, CEditor_GetVal(this->color[0]), CEditor_GetVal(this->color[1]), CEditor_GetVal(this->color[2])); this->change(this, this->info); } static void RGBEditor_SetPos(RGBEditor *this, int x, int y) { this->x = x; this->y = y; CEditor_SetPos(this->color[0], x+2, y+2); CEditor_SetPos(this->color[1], x+2, y+2+CEditor_DEPTH-1); CEditor_SetPos(this->color[2], x+2, y+2+CEditor_DEPTH-1+CEditor_DEPTH-1); } static void RGBEditor_BlankSampleBox(RGBEditor *this) { if (this->hidden) return ; Cursor_Hide(); fillrect(this->x+2+CEditor_WIDTH+1+1, this->y+2+1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color); Cursor_Show(); } static void RGBEditor_Update(RGBEditor *this) { int x1 = this->x+2+CEditor_WIDTH+1+1, y1 = this->y+2+1; if (this->hidden) return ; Cursor_Hide(); if ( this->pal >= colors ) { fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color); draw_diamond(x1+(RGBEditor_BWIDTH-5)/2, y1+(RGBEditor_BDEPTH-5)/2, fg_color); } else if ( is_reserved(this->pal) ) { int x2 = x1+RGBEditor_BWIDTH-3, y2 = y1+RGBEditor_BDEPTH-3; fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color); draw_line(x1, y1, x2, y2, fg_color); draw_line(x1, y2, x2, y1, fg_color); } else fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, this->pal); CEditor_Draw(this->color[0]); CEditor_Draw(this->color[1]); CEditor_Draw(this->color[2]); Cursor_Show(); } static void RGBEditor_Draw(RGBEditor *this) { if (this->hidden) return ; Cursor_Hide(); drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH); fillrect(this->x+1, this->y+1, RGBEditor_WIDTH-2, RGBEditor_DEPTH-2, bg_color); rect(this->x+1+CEditor_WIDTH+2, this->y+2, RGBEditor_BWIDTH, RGBEditor_BDEPTH, fg_color); RGBEditor_Update(this); Cursor_Show(); } static int RGBEditor_Edit(RGBEditor *this) { int key = 0; this->done = FALSE; if (!this->hidden) { Cursor_Hide(); rect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH, fg_color); Cursor_Show(); } while ( !this->done ) key = CEditor_Edit( this->color[this->curr] ); if (!this->hidden) { Cursor_Hide(); drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH); Cursor_Show(); } return (key); } static void RGBEditor_SetRGB(RGBEditor *this, int pal, PALENTRY *rgb) { this->pal = pal; CEditor_SetVal(this->color[0], rgb->red); CEditor_SetVal(this->color[1], rgb->green); CEditor_SetVal(this->color[2], rgb->blue); } static PALENTRY RGBEditor_GetRGB(RGBEditor *this) { PALENTRY pal; pal.red = (BYTE)CEditor_GetVal(this->color[0]); pal.green = (BYTE)CEditor_GetVal(this->color[1]); pal.blue = (BYTE)CEditor_GetVal(this->color[2]); return(pal); } /* * Class: PalTable * * Purpose: This is where it all comes together. Creates the two RGBEditors * and the palette. Moves the cursor, hides/restores the screen, * handles (S)hading, (C)opying, e(X)clude mode, the "Y" exclusion * mode, (Z)oom option, (H)ide palette, rotation, etc. * */ /* enum stored_at_values { NOWHERE, DISK, MEMORY } ; */ /* Modes: Auto: "A", " " Exclusion: "X", "Y", " " Freestyle: "F", " " S(t)ripe mode: "T", " " */ struct _PalTable { int x, y; int csize; int active; /* which RGBEditor is active (0,1) */ int curr[2]; RGBEditor *rgb[2]; MoveBox *movebox; BOOLEAN done; BOOLEAN exclude; BOOLEAN auto_select; PALENTRY pal[256]; FILE *undo_file; BOOLEAN curr_changed; int num_redo; int hidden; int stored_at; FILE *file; char far *memory; PALENTRY far *save_pal[8]; PALENTRY fs_color; int top,bottom; /* top and bottom colours of freestyle band */ int bandwidth; /*size of freestyle colour band */ BOOLEAN freestyle; } ; #define PalTable struct _PalTable /* private: */ static void PalTable__DrawStatus (PalTable *this, BOOLEAN stripe_mode); static void PalTable__HlPal (PalTable *this, int pnum, int color); static void PalTable__Draw (PalTable *this); static BOOLEAN PalTable__SetCurr (PalTable *this, int which, int curr); static BOOLEAN PalTable__MemoryAlloc (PalTable *this, long size); static void PalTable__SaveRect (PalTable *this); static void PalTable__RestoreRect (PalTable *this); static void PalTable__SetPos (PalTable *this, int x, int y); static void PalTable__SetCSize (PalTable *this, int csize); static int PalTable__GetCursorColor(PalTable *this); static void PalTable__DoCurs (PalTable *this, int key); static void PalTable__Rotate (PalTable *this, int dir, int lo, int hi); static void PalTable__UpdateDAC (PalTable *this); static void PalTable__other_key (int key, RGBEditor *rgb, VOIDPTR info); static void PalTable__SaveUndoData(PalTable *this, int first, int last); static void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last); static void PalTable__UndoProcess (PalTable *this, int delta); static void PalTable__Undo (PalTable *this); static void PalTable__Redo (PalTable *this); static void PalTable__change (RGBEditor *rgb, VOIDPTR info); /* public: */ static PalTable *PalTable_Construct (void); static void PalTable_Destroy (PalTable *this); static void PalTable_Process (PalTable *this); static void PalTable_SetHidden (PalTable *this, BOOLEAN hidden); static void PalTable_Hide (PalTable *this, RGBEditor *rgb, BOOLEAN hidden); #define PalTable_PALX (1) #define PalTable_PALY (2+RGBEditor_DEPTH+2) #define UNDO_DATA (1) #define UNDO_DATA_SINGLE (2) #define UNDO_ROTATE (3) /* - Freestyle code - */ static void PalTable__CalcTopBottom(PalTable *this) { if (this->curr[this->active] < this->bandwidth ) this->bottom = 0; else this->bottom = (this->curr[this->active]) - this->bandwidth; if (this->curr[this->active] > (255-this->bandwidth) ) this->top = 255; else this->top = (this->curr[this->active]) + this->bandwidth; } static void PalTable__PutBand(PalTable *this, PALENTRY *pal) { int r,b,a; /* clip top and bottom values to stop them running off the end of the DAC */ PalTable__CalcTopBottom(this); /* put bands either side of current colour */ a = this->curr[this->active]; b = this->bottom; r = this->top; pal[a] = this->fs_color; if (r != a && a != b) { mkpalrange(&pal[a], &pal[r], &pal[a], r-a, 1); mkpalrange(&pal[b], &pal[a], &pal[b], a-b, 1); } } /* - Undo.Redo code - */ static void PalTable__SaveUndoData(PalTable *this, int first, int last) { int num; if ( this->undo_file == NULL ) return ; num = (last - first) + 1; #ifdef DEBUG_UNDO mprintf("%6ld Writing Undo DATA from %d to %d (%d)", ftell(this->undo_file), first, last, num); #endif fseek(this->undo_file, 0, SEEK_CUR); if ( num == 1 ) { putc(UNDO_DATA_SINGLE, this->undo_file); putc(first, this->undo_file); fwrite(this->pal+first, 3, 1, this->undo_file); putw( 1 + 1 + 3 + sizeof(int), this->undo_file); } else { putc(UNDO_DATA, this->undo_file); putc(first, this->undo_file); putc(last, this->undo_file); fwrite(this->pal+first, 3, num, this->undo_file); putw(1 + 2 + (num*3) + sizeof(int), this->undo_file); } this->num_redo = 0; } static void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last) { if ( this->undo_file == NULL ) return ; #ifdef DEBUG_UNDO mprintf("%6ld Writing Undo ROTATE of %d from %d to %d", ftell(this->undo_file), dir, first, last); #endif fseek(this->undo_file, 0, SEEK_CUR); putc(UNDO_ROTATE, this->undo_file); putc(first, this->undo_file); putc(last, this->undo_file); putw(dir, this->undo_file); putw(1 + 2 + sizeof(int), this->undo_file); this->num_redo = 0; } static void PalTable__UndoProcess(PalTable *this, int delta) /* undo/redo common code */ { /* delta = -1 for undo, +1 for redo */ int cmd = getc(this->undo_file); switch( cmd ) { case UNDO_DATA: case UNDO_DATA_SINGLE: { int first, last, num; PALENTRY temp[256]; int dummy; /* to quiet compiler */ if ( cmd == UNDO_DATA ) { first = (unsigned char)getc(this->undo_file); last = (unsigned char)getc(this->undo_file); } else /* UNDO_DATA_SINGLE */ first = last = (unsigned char)getc(this->undo_file); num = (last - first) + 1; #ifdef DEBUG_UNDO mprintf(" Reading DATA from %d to %d", first, last); #endif dummy = fread(temp, 3, num, this->undo_file); fseek(this->undo_file, -(num*3), SEEK_CUR); /* go to start of undo/redo data */ fwrite(this->pal+first, 3, num, this->undo_file); /* write redo/undo data */ memmove(this->pal+first, temp, num*3); PalTable__UpdateDAC(this); RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); RGBEditor_Update(this->rgb[0]); RGBEditor_Update(this->rgb[1]); break; } case UNDO_ROTATE: { int first = (unsigned char)getc(this->undo_file); int last = (unsigned char)getc(this->undo_file); int dir = getw(this->undo_file); #ifdef DEBUG_UNDO mprintf(" Reading ROTATE of %d from %d to %d", dir, first, last); #endif PalTable__Rotate(this, delta*dir, first, last); break; } default: #ifdef DEBUG_UNDO mprintf(" Unknown command: %d", cmd); #endif break; } fseek(this->undo_file, 0, SEEK_CUR); /* to put us in read mode */ getw(this->undo_file); /* read size */ } static void PalTable__Undo(PalTable *this) { int size; long pos; if ( ftell(this->undo_file) <= 0 ) /* at beginning of file? */ { /* nothing to undo -- exit */ return ; } fseek(this->undo_file, -(int)sizeof(int), SEEK_CUR); /* go back to get size */ size = getw(this->undo_file); fseek(this->undo_file, -size, SEEK_CUR); /* go to start of undo */ #ifdef DEBUG_UNDO mprintf("%6ld Undo:", ftell(this->undo_file)); #endif pos = ftell(this->undo_file); PalTable__UndoProcess(this, -1); fseek(this->undo_file, pos, SEEK_SET); /* go to start of this block */ ++this->num_redo; } static void PalTable__Redo(PalTable *this) { if ( this->num_redo <= 0 ) return ; #ifdef DEBUG_UNDO mprintf("%6ld Redo:", ftell(this->undo_file)); #endif fseek(this->undo_file, 0, SEEK_CUR); /* to make sure we are in "read" mode */ PalTable__UndoProcess(this, 1); --this->num_redo; } /* - everything else - */ #define STATUS_LEN (4) static void PalTable__DrawStatus(PalTable *this, BOOLEAN stripe_mode) { int color, hunds, tens, ones; int width = 1+(this->csize*16)+1+1; if ( !this->hidden && ( width - (RGBEditor_WIDTH*2+4) >= STATUS_LEN*8 ) ) { int x = this->x + 2 + RGBEditor_WIDTH, y = this->y + PalTable_PALY - 10; color = PalTable__GetCursorColor(this); if (color < 0 || color >= colors) /* hmm, the border returns -1 */ color = 0; Cursor_Hide(); displayc(x+(0*8), y, fg_color, bg_color, (this->auto_select) ? 'A' : 254); displayc(x+(1*8), y, fg_color, bg_color, (this->exclude==1) ? 'X' : (this->exclude==2) ? 'Y' : 254); displayc(x+(2*8), y, fg_color, bg_color, (this->freestyle) ? 'F' : 254); displayc(x+(3*8), y, fg_color, bg_color, (stripe_mode) ? 'T' : 254); y = y - 10; hunds = (int)(color/100); displayc(x+(0*8), y, fg_color, bg_color, (char)(hunds) + '0' ); tens = (int)((color - (hunds * 100)) / 10); displayc(x+(1*8), y, fg_color, bg_color, (char)(tens) + '0' ); ones = (int)(color - (hunds * 100) - (tens * 10)); displayc(x+(2*8), y, fg_color, bg_color, (char)(ones) + '0' ); Cursor_Show(); } } static void PalTable__HlPal(PalTable *this, int pnum, int color) { int x = this->x + PalTable_PALX + (pnum%16)*this->csize, y = this->y + PalTable_PALY + (pnum/16)*this->csize, size = this->csize; if (this->hidden) return ; Cursor_Hide(); if (color < 0) drect(x, y, size+1, size+1); else rect(x, y, size+1, size+1, color); Cursor_Show(); } static void PalTable__Draw(PalTable *this) { int pal; int xoff, yoff; int width; if (this->hidden) return ; Cursor_Hide(); width = 1+(this->csize*16)+1+1; rect(this->x, this->y, width, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1, fg_color); fillrect(this->x+1, this->y+1, width-2, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1-2, bg_color); hline(this->x, this->y+PalTable_PALY-1, width, fg_color); if ( width - (RGBEditor_WIDTH*2+4) >= TITLE_LEN*8 ) { int center = (width - TITLE_LEN*8) / 2; displayf(this->x+center, this->y+RGBEditor_DEPTH/2-6, fg_color, bg_color, TITLE); } RGBEditor_Draw(this->rgb[0]); RGBEditor_Draw(this->rgb[1]); for (pal=0; pal<256; pal++) { xoff = PalTable_PALX + (pal%16) * this->csize; yoff = PalTable_PALY + (pal/16) * this->csize; if ( pal >= colors ) { fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color); draw_diamond(this->x + xoff + this->csize/2 - 1, this->y + yoff + this->csize/2 - 1, fg_color); } else if ( is_reserved(pal) ) { int x1 = this->x + xoff + 1, y1 = this->y + yoff + 1, x2 = x1 + this->csize - 2, y2 = y1 + this->csize - 2; fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color); draw_line(x1, y1, x2, y2, fg_color); draw_line(x1, y2, x2, y1, fg_color); } else fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, pal); } if (this->active == 0) { PalTable__HlPal(this, this->curr[1], -1); PalTable__HlPal(this, this->curr[0], fg_color); } else { PalTable__HlPal(this, this->curr[0], -1); PalTable__HlPal(this, this->curr[1], fg_color); } PalTable__DrawStatus(this, FALSE); Cursor_Show(); } static BOOLEAN PalTable__SetCurr(PalTable *this, int which, int curr) { BOOLEAN redraw = (BOOLEAN)((which < 0) ? TRUE : FALSE); if ( redraw ) { which = this->active; curr = this->curr[which]; } else if ( curr == this->curr[which] || curr < 0 ) return (FALSE); Cursor_Hide(); PalTable__HlPal(this, this->curr[0], bg_color); PalTable__HlPal(this, this->curr[1], bg_color); PalTable__HlPal(this, this->top, bg_color); PalTable__HlPal(this, this->bottom, bg_color); if ( this->freestyle ) { this->curr[which] = curr; PalTable__CalcTopBottom(this); PalTable__HlPal(this, this->top, -1); PalTable__HlPal(this, this->bottom, -1); PalTable__HlPal(this, this->curr[this->active], fg_color); RGBEditor_SetRGB(this->rgb[which], this->curr[which], &this->fs_color); RGBEditor_Update(this->rgb[which]); PalTable__UpdateDAC(this); Cursor_Show(); return (TRUE); } this->curr[which] = curr; if (this->curr[0] != this->curr[1]) PalTable__HlPal(this, this->curr[this->active==0?1:0], -1); PalTable__HlPal(this, this->curr[this->active], fg_color); RGBEditor_SetRGB(this->rgb[which], this->curr[which], &(this->pal[this->curr[which]])); if (redraw) { int other = (which==0) ? 1 : 0; RGBEditor_SetRGB(this->rgb[other], this->curr[other], &(this->pal[this->curr[other]])); RGBEditor_Update(this->rgb[0]); RGBEditor_Update(this->rgb[1]); } else RGBEditor_Update(this->rgb[which]); if (this->exclude) PalTable__UpdateDAC(this); Cursor_Show(); this->curr_changed = FALSE; return(TRUE); } static BOOLEAN PalTable__MemoryAlloc(PalTable *this, long size) { char far *temp; if (debugflag == 420) { this->stored_at = NOWHERE; return (FALSE); /* can't do it */ } temp = (char far *)farmemalloc(FAR_RESERVE); /* minimum free space */ if (temp == NULL) { this->stored_at = NOWHERE; return (FALSE); /* can't do it */ } this->memory = (char far *)farmemalloc( size ); farmemfree(temp); if ( this->memory == NULL ) { this->stored_at = NOWHERE; return (FALSE); } else { this->stored_at = FARMEM; return (TRUE); } } static void PalTable__SaveRect(PalTable *this) { char buff[MAX_WIDTH]; int width = PalTable_PALX + this->csize*16 + 1 + 1, depth = PalTable_PALY + this->csize*16 + 1 + 1; int yoff; /* first, do any de-allocationg */ switch( this->stored_at ) { case NOWHERE: break; case DISK: break; case FARMEM: if (this->memory != NULL) farmemfree(this->memory); this->memory = NULL; break; } ; /* allocate space and store the rect */ if ( PalTable__MemoryAlloc(this, (long)width*depth) ) { char far *ptr = this->memory; char far *bufptr = buff; /* MSC needs this indirection to get it right */ Cursor_Hide(); for (yoff=0; yoffx, this->y+yoff, width, buff); hline (this->x, this->y+yoff, width, bg_color); far_memcpy(ptr,bufptr, width); ptr = (char far *)normalize(ptr+width); } Cursor_Show(); } else /* to disk */ { this->stored_at = DISK; if ( this->file == NULL ) { this->file = dir_fopen(tempdir,scrnfile, "w+b"); if (this->file == NULL) { this->stored_at = NOWHERE; buzzer(3); return ; } } rewind(this->file); Cursor_Hide(); for (yoff=0; yoffx, this->y+yoff, width, buff); hline (this->x, this->y+yoff, width, bg_color); if ( fwrite(buff, width, 1, this->file) != 1 ) { buzzer(3); break; } } Cursor_Show(); } } static void PalTable__RestoreRect(PalTable *this) { char buff[MAX_WIDTH]; int width = PalTable_PALX + this->csize*16 + 1 + 1, depth = PalTable_PALY + this->csize*16 + 1 + 1; int yoff; if (this->hidden) return; switch ( this->stored_at ) { case DISK: rewind(this->file); Cursor_Hide(); for (yoff=0; yofffile) != 1 ) { buzzer(3); break; } putrow(this->x, this->y+yoff, width, buff); } Cursor_Show(); break; case FARMEM: { char far *ptr = this->memory; char far *bufptr = buff; /* MSC needs this indirection to get it right */ Cursor_Hide(); for (yoff=0; yoffx, this->y+yoff, width, buff); ptr = (char far *)normalize(ptr+width); } Cursor_Show(); break; } case NOWHERE: break; } /* switch */ } static void PalTable__SetPos(PalTable *this, int x, int y) { int width = PalTable_PALX + this->csize*16 + 1 + 1; this->x = x; this->y = y; RGBEditor_SetPos(this->rgb[0], x+2, y+2); RGBEditor_SetPos(this->rgb[1], x+width-2-RGBEditor_WIDTH, y+2); } static void PalTable__SetCSize(PalTable *this, int csize) { this->csize = csize; PalTable__SetPos(this, this->x, this->y); } static int PalTable__GetCursorColor(PalTable *this) { int x = Cursor_GetX(), y = Cursor_GetY(), size; int color = getcolor(x, y); if ( is_reserved(color) ) { if ( is_in_box(x, y, this->x, this->y, 1+(this->csize*16)+1+1, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1) ) { /* is the cursor over the editor? */ x -= this->x + PalTable_PALX; y -= this->y + PalTable_PALY; size = this->csize; if (x < 0 || y < 0 || x > size*16 || y > size*16) return (-1); if ( x == size*16 ) --x; if ( y == size*16 ) --y; return ( (y/size)*16 + x/size ); } else return (color); } return (color); } #define CURS_INC 1 static void PalTable__DoCurs(PalTable *this, int key) { BOOLEAN done = FALSE; BOOLEAN first = TRUE; int xoff = 0, yoff = 0; while ( !done ) { switch(key) { case RIGHT_ARROW_2: xoff += CURS_INC*4; break; case RIGHT_ARROW: xoff += CURS_INC; break; case LEFT_ARROW_2: xoff -= CURS_INC*4; break; case LEFT_ARROW: xoff -= CURS_INC; break; case DOWN_ARROW_2: yoff += CURS_INC*4; break; case DOWN_ARROW: yoff += CURS_INC; break; case UP_ARROW_2: yoff -= CURS_INC*4; break; case UP_ARROW: yoff -= CURS_INC; break; default: done = TRUE; } if (!done) { if (!first) getakey(); /* delete key from buffer */ else first = FALSE; key = keypressed(); /* peek at the next one... */ } } Cursor_Move(xoff, yoff); if (this->auto_select) PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); } #ifdef __TURBOC__ # pragma argsused #endif #ifdef __CLINT__ # pragma argsused #endif static void PalTable__change(RGBEditor *rgb, VOIDPTR info) { PalTable *this = (PalTable *)info; int pnum = this->curr[this->active]; if ( this->freestyle ) { this->fs_color = RGBEditor_GetRGB(rgb); PalTable__UpdateDAC(this); return ; } if ( !this->curr_changed ) { PalTable__SaveUndoData(this, pnum, pnum); this->curr_changed = TRUE; } this->pal[pnum] = RGBEditor_GetRGB(rgb); if (this->curr[0] == this->curr[1]) { int other = this->active==0 ? 1 : 0; PALENTRY color; color = RGBEditor_GetRGB(this->rgb[this->active]); RGBEditor_SetRGB(this->rgb[other], this->curr[other], &color); Cursor_Hide(); RGBEditor_Update(this->rgb[other]); Cursor_Show(); } } static void PalTable__UpdateDAC(PalTable *this) { if ( this->exclude ) { memset(dacbox, 0, 256*3); if (this->exclude == 1) { int a = this->curr[this->active]; memmove(dacbox[a], &this->pal[a], 3); } else { int a = this->curr[0], b = this->curr[1]; if (a>b) { int t=a; a=b; b=t; } memmove(dacbox[a], &this->pal[a], 3*(1+(b-a))); } } else { memmove(dacbox[0], this->pal, 3*colors); if ( this->freestyle ) PalTable__PutBand(this, (PALENTRY *)dacbox); /* apply band to dacbox */ } if ( !this->hidden ) { if (inverse) { memset(dacbox[fg_color], 0, 3); /* dacbox[fg] = (0,0,0) */ memset(dacbox[bg_color], 48, 3); /* dacbox[bg] = (48,48,48) */ } else { memset(dacbox[bg_color], 0, 3); /* dacbox[bg] = (0,0,0) */ memset(dacbox[fg_color], 48, 3); /* dacbox[fg] = (48,48,48) */ } } spindac(0,1); } static void PalTable__Rotate(PalTable *this, int dir, int lo, int hi) { rotatepal(this->pal, dir, lo, hi); Cursor_Hide(); /* update the DAC. */ PalTable__UpdateDAC(this); /* update the editors. */ RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); RGBEditor_Update(this->rgb[0]); RGBEditor_Update(this->rgb[1]); Cursor_Show(); } static void PalTable__other_key(int key, RGBEditor *rgb, VOIDPTR info) { PalTable *this = (PalTable *)info; switch(key) { case '\\': /* move/resize */ { if (this->hidden) break; /* cannot move a hidden pal */ Cursor_Hide(); PalTable__RestoreRect(this); MoveBox_SetPos(this->movebox, this->x, this->y); MoveBox_SetCSize(this->movebox, this->csize); if ( MoveBox_Process(this->movebox) ) { if ( MoveBox_ShouldHide(this->movebox) ) PalTable_SetHidden(this, TRUE); else if ( MoveBox_Moved(this->movebox) ) { PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox)); PalTable__SetCSize(this, MoveBox_CSize(this->movebox)); PalTable__SaveRect(this); } } PalTable__Draw(this); Cursor_Show(); RGBEditor_SetDone(this->rgb[this->active], TRUE); if (this->auto_select) PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); break; } case 'Y': /* exclude range */ case 'y': if ( this->exclude==2 ) this->exclude = 0; else this->exclude = 2; PalTable__UpdateDAC(this); break; case 'X': case 'x': /* exclude current entry */ if ( this->exclude==1 ) this->exclude = 0; else this->exclude = 1; PalTable__UpdateDAC(this); break; case RIGHT_ARROW: case LEFT_ARROW: case UP_ARROW: case DOWN_ARROW: case RIGHT_ARROW_2: case LEFT_ARROW_2: case UP_ARROW_2: case DOWN_ARROW_2: PalTable__DoCurs(this, key); break; case ESC: this->done = TRUE; RGBEditor_SetDone(rgb, TRUE); break; case ' ': /* select the other palette register */ this->active = (this->active==0) ? 1 : 0; if (this->auto_select) PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); else PalTable__SetCurr(this, -1, 0); if (this->exclude || this->freestyle) PalTable__UpdateDAC(this); RGBEditor_SetDone(rgb, TRUE); break; case ENTER: /* set register to color under cursor. useful when not */ case ENTER_2: /* in auto_select mode */ if ( this->freestyle ) { PalTable__SaveUndoData(this, this->bottom, this->top); PalTable__PutBand(this, this->pal); } PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); if (this->exclude || this->freestyle ) PalTable__UpdateDAC(this); RGBEditor_SetDone(rgb, TRUE); break; case 'D': /* copy (Duplicate?) color in inactive to color in active */ case 'd': { int a = this->active, b = (a==0) ? 1 : 0; PALENTRY t; t = RGBEditor_GetRGB(this->rgb[b]); Cursor_Hide(); RGBEditor_SetRGB(this->rgb[a], this->curr[a], &t); RGBEditor_Update(this->rgb[a]); PalTable__change(this->rgb[a], this); PalTable__UpdateDAC(this); Cursor_Show(); colorstate = 1; break; } case '=': /* create a shade range between the two entries */ { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); if (a != b) { mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, 1); PalTable__UpdateDAC(this); colorstate = 1; } break; } case '!': /* swap r<->g */ { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); if (a != b) { rotcolrg(&this->pal[a], b-a); PalTable__UpdateDAC(this); colorstate = 1; } break; } case '@': /* swap g<->b */ case '"': /* UK keyboards */ case 151: /* French keyboards */ { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); if (a != b) { rotcolgb(&this->pal[a], b-a); PalTable__UpdateDAC(this); colorstate = 1; } break; } case '#': /* swap r<->b */ case 156: /* UK keyboards (pound sign) */ case '$': /* For French keyboards */ { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); if (a != b) { rotcolbr(&this->pal[a], b-a); PalTable__UpdateDAC(this); colorstate = 1; } break; } case 'T': case 't': /* s(T)ripe mode */ { int key; Cursor_Hide(); PalTable__DrawStatus(this, TRUE); key = getakeynohelp(); Cursor_Show(); if (key >= '1' && key <= '9') { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); if (a != b) { mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, key-'0'); PalTable__UpdateDAC(this); colorstate = 1; } } break; } case 'M': /* set gamma */ case 'm': { static FCODE o_msg[] = {"Enter gamma value"}; char msg[sizeof(o_msg)]; int i; char buf[20]; far_strcpy(msg,o_msg); sprintf(buf,"%.3f",1./gamma_val); stackscreen(); i = field_prompt(0,msg,NULL,buf,20,NULL); unstackscreen(); if (i != -1) { sscanf(buf,"%f",&gamma_val); if (gamma_val==0) { gamma_val = (float)0.0000000001; } gamma_val = (float)(1./gamma_val); } } break; case 'A': /* toggle auto-select mode */ case 'a': this->auto_select = (BOOLEAN)((this->auto_select) ? FALSE : TRUE); if (this->auto_select) { PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); if (this->exclude) PalTable__UpdateDAC(this); } break; case 'H': case 'h': /* toggle hide/display of palette editor */ Cursor_Hide(); PalTable_Hide(this, rgb, (BOOLEAN)((this->hidden) ? FALSE : TRUE)); Cursor_Show(); break; case '.': /* rotate once */ case ',': { int dir = (key=='.') ? 1 : -1; PalTable__SaveUndoRotate(this, dir, rotate_lo, rotate_hi); PalTable__Rotate(this, dir, rotate_lo, rotate_hi); if (colorstate == 0 || colorstate == 2) colorstate = 3; break; } case '>': /* continuous rotation (until a key is pressed) */ case '<': { int dir; long tick; int diff = 0; Cursor_Hide(); if ( !this->hidden ) { RGBEditor_BlankSampleBox(this->rgb[0]); RGBEditor_BlankSampleBox(this->rgb[1]); RGBEditor_SetHidden(this->rgb[0], TRUE); RGBEditor_SetHidden(this->rgb[1], TRUE); } do { dir = (key=='>') ? 1 : -1; while ( !keypressed() ) { tick = readticker(); PalTable__Rotate(this, dir, rotate_lo, rotate_hi); diff += dir; while (readticker() == tick) ; /* wait until a tick passes */ } key = getakey(); } while (key=='<' || key=='>'); if ( !this->hidden ) { RGBEditor_SetHidden(this->rgb[0], FALSE); RGBEditor_SetHidden(this->rgb[1], FALSE); RGBEditor_Update(this->rgb[0]); RGBEditor_Update(this->rgb[1]); } if ( diff != 0 ) { PalTable__SaveUndoRotate(this, diff, rotate_lo, rotate_hi); if (colorstate == 0 || colorstate == 2) colorstate = 3; } Cursor_Show(); break; } case 'I': /* invert the fg & bg colors */ case 'i': inverse = (BOOLEAN)!inverse; PalTable__UpdateDAC(this); break; case 'V': case 'v': /* set the reserved colors to the editor colors */ if ( this->curr[0] >= colors || this->curr[1] >= colors || this->curr[0] == this->curr[1] ) { buzzer(2); break; } fg_color = (BYTE)this->curr[0]; bg_color = (BYTE)this->curr[1]; if ( !this->hidden ) { Cursor_Hide(); PalTable__UpdateDAC(this); PalTable__Draw(this); Cursor_Show(); } RGBEditor_SetDone(this->rgb[this->active], TRUE); break; case 'O': /* set rotate_lo and rotate_hi to editors */ case 'o': if (this->curr[0] > this->curr[1]) { rotate_lo = this->curr[1]; rotate_hi = this->curr[0]; } else { rotate_lo = this->curr[0]; rotate_hi = this->curr[1]; } break; case F2: /* restore a palette */ case F3: case F4: case F5: case F6: case F7: case F8: case F9: { int which = key - F2; if ( this->save_pal[which] != NULL ) { Cursor_Hide(); PalTable__SaveUndoData(this, 0, 255); far_memcpy(this->pal,this->save_pal[which],256*3); PalTable__UpdateDAC(this); PalTable__SetCurr(this, -1, 0); Cursor_Show(); RGBEditor_SetDone(this->rgb[this->active], TRUE); colorstate = 1; } else buzzer(3); /* error buzz */ break; } case SF2: /* save a palette */ case SF3: case SF4: case SF5: case SF6: case SF7: case SF8: case SF9: { int which = key - SF2; if ( this->save_pal[which] != NULL ) { far_memcpy(this->save_pal[which],this->pal,256*3); } else buzzer(3); /* oops! short on memory! */ break; } case 'L': /* load a .map palette */ case 'l': { PalTable__SaveUndoData(this, 0, 255); load_palette(); #ifndef XFRACT getpalrange(0, colors, this->pal); #else getpalrange(0, 256, this->pal); #endif PalTable__UpdateDAC(this); RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); RGBEditor_Update(this->rgb[0]); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); RGBEditor_Update(this->rgb[1]); break; } case 'S': /* save a .map palette */ case 's': { #ifndef XFRACT setpalrange(0, colors, this->pal); #else setpalrange(0, 256, this->pal); #endif save_palette(); PalTable__UpdateDAC(this); break; } case 'C': /* color cycling sub-mode */ case 'c': { BOOLEAN oldhidden = (BOOLEAN)this->hidden; PalTable__SaveUndoData(this, 0, 255); Cursor_Hide(); if ( !oldhidden ) PalTable_Hide(this, rgb, TRUE); setpalrange(0, colors, this->pal); rotate(0); getpalrange(0, colors, this->pal); PalTable__UpdateDAC(this); if ( !oldhidden ) { RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); PalTable_Hide(this, rgb, FALSE); } Cursor_Show(); break; } case 'F': case 'f': /* toggle freestyle palette edit mode */ this->freestyle= (BOOLEAN)((this->freestyle) ? FALSE :TRUE); PalTable__SetCurr(this, -1, 0); if ( !this->freestyle ) /* if turning off... */ PalTable__UpdateDAC(this); colorstate = 1; break; case CTL_DEL: /* rt plus down */ if (this->bandwidth >0 ) this->bandwidth --; else this->bandwidth=0; PalTable__SetCurr(this, -1, 0); break; case CTL_INSERT: /* rt plus up */ if (this->bandwidth <255 ) this->bandwidth ++; else this->bandwidth = 255; PalTable__SetCurr(this, -1, 0); break; case 'W': /* convert to greyscale */ case 'w': { switch ( this->exclude ) { case 0: /* normal mode. convert all colors to grey scale */ PalTable__SaveUndoData(this, 0, 255); palrangetogrey(this->pal, 0, 256); break; case 1: /* 'x' mode. convert current color to grey scale. */ PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]); palrangetogrey(this->pal, this->curr[this->active], 1); break; case 2: /* 'y' mode. convert range between editors to grey. */ { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); palrangetogrey(this->pal, a, 1+(b-a)); break; } } PalTable__UpdateDAC(this); RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); RGBEditor_Update(this->rgb[0]); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); RGBEditor_Update(this->rgb[1]); colorstate = 1; break; } case 'N': /* convert to negative color */ case 'n': { switch ( this->exclude ) { case 0: /* normal mode. convert all colors to grey scale */ PalTable__SaveUndoData(this, 0, 255); palrangetonegative(this->pal, 0, 256); break; case 1: /* 'x' mode. convert current color to grey scale. */ PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]); palrangetonegative(this->pal, this->curr[this->active], 1); break; case 2: /* 'y' mode. convert range between editors to grey. */ { int a = this->curr[0], b = this->curr[1]; if (a > b) { int t = a; a = b; b = t; } PalTable__SaveUndoData(this, a, b); palrangetonegative(this->pal, a, 1+(b-a)); break; } } PalTable__UpdateDAC(this); RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); RGBEditor_Update(this->rgb[0]); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); RGBEditor_Update(this->rgb[1]); colorstate = 1; break; } case 'U': /* Undo */ case 'u': PalTable__Undo(this); break; case 'e': /* Redo */ case 'E': PalTable__Redo(this); break; } /* switch */ PalTable__DrawStatus(this, FALSE); } static void PalTable__MkDefaultPalettes(PalTable *this) /* creates default Fkey palettes */ { int i; for(i=0; i<8; i++) /* copy original palette to save areas */ { if (this->save_pal[i] != NULL) { far_memcpy(this->save_pal[i], this->pal, 256*3); } } } static PalTable *PalTable_Construct(void) { PalTable *this = new(PalTable); int csize; int ctr; PALENTRY far *mem_block; void far *temp; temp = (void far *)farmemalloc(FAR_RESERVE); if ( temp != NULL ) { mem_block = (PALENTRY far *)farmemalloc(256L*3 * 8); if ( mem_block == NULL ) { for (ctr=0; ctr<8; ctr++) this->save_pal[ctr] = NULL; } else { for (ctr=0; ctr<8; ctr++) this->save_pal[ctr] = mem_block + (256*ctr); } farmemfree(temp); } this->rgb[0] = RGBEditor_Construct(0, 0, PalTable__other_key, PalTable__change, this); this->rgb[1] = RGBEditor_Construct(0, 0, PalTable__other_key, PalTable__change, this); this->movebox = MoveBox_Construct(0,0,0, PalTable_PALX+1, PalTable_PALY+1); this->active = 0; this->curr[0] = 1; this->curr[1] = 1; this->auto_select = TRUE; this->exclude = FALSE; this->hidden = FALSE; this->stored_at = NOWHERE; this->file = NULL; this->memory = NULL; this->fs_color.red = 42; this->fs_color.green = 42; this->fs_color.blue = 42; this->freestyle = FALSE; this->bandwidth = 15; this->top = 255; this->bottom = 0 ; this->undo_file = dir_fopen(tempdir,undofile, "w+b"); this->curr_changed = FALSE; this->num_redo = 0; RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]); if (video_scroll) { PalTable__SetPos(this, video_startx, video_starty); csize = ( (vesa_yres-(PalTable_PALY+1+1)) / 2 ) / 16; } else { PalTable__SetPos(this, 0, 0); csize = ( (sydots-(PalTable_PALY+1+1)) / 2 ) / 16; } if (csizehidden = hidden; RGBEditor_SetHidden(this->rgb[0], hidden); RGBEditor_SetHidden(this->rgb[1], hidden); PalTable__UpdateDAC(this); } static void PalTable_Hide(PalTable *this, RGBEditor *rgb, BOOLEAN hidden) { if (hidden) { PalTable__RestoreRect(this); PalTable_SetHidden(this, TRUE); reserve_colors = FALSE; if (this->auto_select) PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); } else { PalTable_SetHidden(this, FALSE); reserve_colors = TRUE; if (this->stored_at == NOWHERE) /* do we need to save screen? */ PalTable__SaveRect(this); PalTable__Draw(this); if (this->auto_select) PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); RGBEditor_SetDone(rgb, TRUE); } } static void PalTable_Destroy(PalTable *this) { if (this->file != NULL) { fclose(this->file); dir_remove(tempdir,scrnfile); } if (this->undo_file != NULL) { fclose(this->undo_file); dir_remove(tempdir,undofile); } if (this->memory != NULL) farmemfree(this->memory); if (this->save_pal[0] != NULL) farmemfree((BYTE far *)this->save_pal[0]); RGBEditor_Destroy(this->rgb[0]); RGBEditor_Destroy(this->rgb[1]); MoveBox_Destroy(this->movebox); delete(this); } static void PalTable_Process(PalTable *this) { int ctr; getpalrange(0, colors, this->pal); /* Make sure all palette entries are 0-63 */ for(ctr=0; ctr<768; ctr++) ((char *)this->pal)[ctr] &= 63; PalTable__UpdateDAC(this); RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]); RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]); if (!this->hidden) { MoveBox_SetPos(this->movebox, this->x, this->y); MoveBox_SetCSize(this->movebox, this->csize); if ( !MoveBox_Process(this->movebox) ) { setpalrange(0, colors, this->pal); return ; } PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox)); PalTable__SetCSize(this, MoveBox_CSize(this->movebox)); if ( MoveBox_ShouldHide(this->movebox) ) { PalTable_SetHidden(this, TRUE); reserve_colors = FALSE; /* */ } else { reserve_colors = TRUE; /* */ PalTable__SaveRect(this); PalTable__Draw(this); } } PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); PalTable__SetCurr(this, (this->active==1)?0:1, PalTable__GetCursorColor(this)); Cursor_Show(); PalTable__MkDefaultPalettes(this); this->done = FALSE; while ( !this->done ) RGBEditor_Edit(this->rgb[this->active]); Cursor_Hide(); PalTable__RestoreRect(this); setpalrange(0, colors, this->pal); } /* * interface to FRACTINT */ void EditPalette(void) /* called by fractint */ { int oldlookatmouse = lookatmouse; int oldsxoffs = sxoffs; int oldsyoffs = syoffs; PalTable *pt; mem_init(strlocn, 10*1024); if ( (font8x8 = findfont(0)) == NULL ) return ; if (sxdots < 133 || sydots < 174) return; /* prevents crash when physical screen is too small */ plot = putcolor; line_buff = newx(max(sxdots,sydots)); lookatmouse = 3; sxoffs = syoffs = 0; reserve_colors = TRUE; inverse = FALSE; fg_color = (BYTE)(255%colors); bg_color = (BYTE)(fg_color-1); Cursor_Construct(); pt = PalTable_Construct(); PalTable_Process(pt); PalTable_Destroy(pt); Cursor_Destroy(); lookatmouse = oldlookatmouse; sxoffs = oldsxoffs; syoffs = oldsyoffs; delete(line_buff); } xfractint-20.4.10.orig/common/fracsubr.c0000644000000000000000000014523711045730226014764 0ustar /* FRACSUBR.C contains subroutines which belong primarily to CALCFRAC.C and FRACTALS.C, i.e. which are non-fractal-specific fractal engine subroutines. */ #ifndef USE_VARARGS #include #else #include #endif #ifndef XFRACT #include #endif #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /* routines in this module */ static long _fastcall fudgetolong(double d); static double _fastcall fudgetodouble(long l); static void _fastcall adjust_to_limits(double); static void _fastcall smallest_add(double *); static int _fastcall ratio_bad(double,double); static void _fastcall plotdorbit(double,double,int); static int _fastcall combine_worklist(void); static void _fastcall adjust_to_limitsbf(double); static void _fastcall smallest_add_bf(bf_t); int resume_len; /* length of resume info */ static int resume_offset; /* offset in resume info gets */ int taborhelp; /* kludge for sound and tab or help key press */ #define FUDGEFACTOR 29 /* fudge all values up by 2**this */ #define FUDGEFACTOR2 24 /* (or maybe this) */ void set_grid_pointers() { dx0 = MK_FP(extraseg,0); dy1 = (dx1 = (dy0 = dx0 + xdots) + ydots) + ydots; lx0 = (long far *) dx0; ly1 = (lx1 = (ly0 = lx0 + xdots) + ydots) + ydots; set_pixel_calc_functions(); } void fill_dx_array(void) { int i; if(use_grid) { dx0[0] = xxmin; /* fill up the x, y grids */ dy0[0] = yymax; dx1[0] = dy1[0] = 0; for (i = 1; i < xdots; i++ ) { dx0[i] = (double)(dx0[0] + i*delxx); dy1[i] = (double)(dy1[0] - i*delyy2); } for (i = 1; i < ydots; i++ ) { dy0[i] = (double)(dy0[0] - i*delyy); dx1[i] = (double)(dx1[0] + i*delxx2); } } } void fill_lx_array(void) { int i; /* note that lx1 & ly1 values can overflow into sign bit; since */ /* they're used only to add to lx0/ly0, 2s comp straightens it out */ if(use_grid) { lx0[0] = xmin; /* fill up the x, y grids */ ly0[0] = ymax; lx1[0] = ly1[0] = 0; for (i = 1; i < xdots; i++ ) { lx0[i] = lx0[i-1] + delx; ly1[i] = ly1[i-1] - dely2; } for (i = 1; i < ydots; i++ ) { ly0[i] = ly0[i-1] - dely; lx1[i] = lx1[i-1] + delx2; } } } void fractal_floattobf(void) { int i; init_bf_dec(getprecdbl(CURRENTREZ)); floattobf(bfxmin,xxmin); floattobf(bfxmax,xxmax); floattobf(bfymin,yymin); floattobf(bfymax,yymax); floattobf(bfx3rd,xx3rd); floattobf(bfy3rd,yy3rd); for (i = 0; i < MAXPARAMS; i++) if(typehasparm(fractype,i,NULL)) floattobf(bfparms[i],param[i]); calc_status = 0; } #ifdef _MSC_VER #if _MSC_VER == 800 /* MSC8 doesn't correctly calculate the address of certain arrays here */ #pragma optimize( "", off ) #endif #endif int use_grid; void calcfracinit(void) /* initialize a *pile* of stuff for fractal calculation */ { int tries = 0; int i, gotprec; long xytemp; double ftemp; coloriter=oldcoloriter = 0L; for(i=0;i<10;i++) rhombus_stack[i] = 0; /* set up grid array compactly leaving space at end */ /* space req for grid is 2(xdots+ydots)*sizeof(long or double) */ /* space available in extraseg is 65536 Bytes */ xytemp = xdots + ydots; if( ((usr_floatflag == 0) && (xytemp * sizeof(long) > 32768)) || ((usr_floatflag == 1) && (xytemp * sizeof(double) > 32768)) || debugflag == 3800) { use_grid=0; floatflag = usr_floatflag = 1; } else use_grid=1; set_grid_pointers(); if(!(curfractalspecific->flags & BF_MATH)) { int tofloat; if((tofloat=curfractalspecific->tofloat) == NOFRACTAL) bf_math = 0; else if(!(fractalspecific[tofloat].flags & BF_MATH)) bf_math = 0; else if(bf_math) { curfractalspecific = &fractalspecific[tofloat]; fractype = tofloat; } } /* switch back to double when zooming out if using arbitrary precision */ if(bf_math) { gotprec=getprecbf(CURRENTREZ); if((gotprec <= DBL_DIG+1 && debugflag != 3200) || math_tol[1] >= 1.0) { bfcornerstofloat(); bf_math = 0; } else init_bf_dec(gotprec); } else if((fractype==MANDEL || fractype==MANDELFP) && debugflag==3200) { fractype=MANDELFP; curfractalspecific = &fractalspecific[MANDELFP]; fractal_floattobf(); usr_floatflag = 1; } else if((fractype==JULIA || fractype==JULIAFP) && debugflag==3200) { fractype=JULIAFP; curfractalspecific = &fractalspecific[JULIAFP]; fractal_floattobf(); usr_floatflag = 1; } else if((fractype==LMANDELZPOWER || fractype==FPMANDELZPOWER) && debugflag==3200) { fractype=FPMANDELZPOWER; curfractalspecific = &fractalspecific[FPMANDELZPOWER]; fractal_floattobf(); usr_floatflag = 1; } else if((fractype==LJULIAZPOWER || fractype==FPJULIAZPOWER) && debugflag==3200) { fractype=FPJULIAZPOWER; curfractalspecific = &fractalspecific[FPJULIAZPOWER]; fractal_floattobf(); usr_floatflag = 1; } else if((fractype==DIVIDEBROT5) && debugflag==3200) { fractype=DIVIDEBROT5; curfractalspecific = &fractalspecific[DIVIDEBROT5]; fractal_floattobf(); usr_floatflag = 1; } else free_bf_vars(); if(bf_math) floatflag=1; else floatflag = usr_floatflag; if (calc_status == 2) { /* on resume, ensure floatflag correct */ if (curfractalspecific->isinteger) floatflag = 0; else floatflag = 1; } /* if floating pt only, set floatflag for TAB screen */ if (!curfractalspecific->isinteger && curfractalspecific->tofloat == NOFRACTAL) floatflag = 1; if (usr_stdcalcmode == 's') { if (fractype == MANDEL || fractype == MANDELFP) floatflag = 1; else usr_stdcalcmode = '1'; } init_restart: /* the following variables may be forced to a different setting due to calc routine constraints; usr_xxx is what the user last said is wanted, xxx is what we actually do in the current situation */ stdcalcmode = usr_stdcalcmode; periodicitycheck = usr_periodicitycheck; distest = usr_distest; biomorph = usr_biomorph; if(inside == ATANI && save_release >= 2004) periodicitycheck = 0; potflag = 0; if (potparam[0] != 0.0 && colors >= 64 && (curfractalspecific->calctype == StandardFractal || curfractalspecific->calctype == calcmand || curfractalspecific->calctype == calcmandfp)) { potflag = 1; distest = usr_distest = 0; /* can't do distest too */ } if (distest) floatflag = 1; /* force floating point for dist est */ if (floatflag) { /* ensure type matches floatflag */ if (curfractalspecific->isinteger != 0 && curfractalspecific->tofloat != NOFRACTAL) fractype = curfractalspecific->tofloat; } else { if (curfractalspecific->isinteger == 0 && curfractalspecific->tofloat != NOFRACTAL) fractype = curfractalspecific->tofloat; } /* match Julibrot with integer mode of orbit */ if(fractype == JULIBROTFP && fractalspecific[neworbittype].isinteger) { int i; if((i=fractalspecific[neworbittype].tofloat) != NOFRACTAL) neworbittype = i; else fractype = JULIBROT; } else if(fractype == JULIBROT && fractalspecific[neworbittype].isinteger==0) { int i; if((i=fractalspecific[neworbittype].tofloat) != NOFRACTAL) neworbittype = i; else fractype = JULIBROTFP; } curfractalspecific = &fractalspecific[fractype]; integerfractal = curfractalspecific->isinteger; /* if (fractype == JULIBROT) rqlim = 4; else */ if (potflag && potparam[2] != 0.0) rqlim = potparam[2]; /* else if (decomp[0] > 0 && decomp[1] > 0) rqlim = (double)decomp[1]; */ else if (bailout) /* user input bailout */ rqlim = bailout; else if (biomorph != -1) /* biomorph benefits from larger bailout */ rqlim = 100; else rqlim = curfractalspecific->orbit_bailout; if (integerfractal) /* the bailout limit mustn't be too high here */ if (rqlim > 127.0) rqlim = 127.0; if ((curfractalspecific->flags&NOROTATE) != 0) { /* ensure min xxmax) { ftemp = xxmax; xxmax = xxmin; xxmin = ftemp; } if (yymin > yymax) { ftemp = yymax; yymax = yymin; yymin = ftemp; } xx3rd = xxmin; yy3rd = yymin; } /* set up bitshift for integer math */ bitshift = FUDGEFACTOR2; /* by default, the smaller shift */ if (integerfractal > 1) /* use specific override from table */ bitshift = integerfractal; if (integerfractal == 0) { /* float? */ if ((i = curfractalspecific->tofloat) != NOFRACTAL) /* -> int? */ { if (fractalspecific[i].isinteger > 1) /* specific shift? */ bitshift = fractalspecific[i].isinteger; } else bitshift = 16; /* to allow larger corners */ } /* We want this code if we're using the assembler calcmand */ if (fractype == MANDEL || fractype == JULIA) { /* adust shift bits if.. */ if (potflag == 0 /* not using potential */ && (param[0] > -2.0 && param[0] < 2.0) /* parameters not too large */ && (param[1] > -2.0 && param[1] < 2.0) && !invert /* and not inverting */ && biomorph == -1 /* and not biomorphing */ && rqlim <= 4.0 /* and bailout not too high */ && (outside > -2 || outside < -6) /* and no funny outside stuff */ && debugflag != 1234 /* and not debugging */ && closeprox <= 2.0 /* and closeprox not too large */ && bailoutest == Mod) /* and bailout test = mod */ bitshift = FUDGEFACTOR; /* use the larger bitshift */ } fudge = 1L << bitshift; l_at_rad = fudge/32768L; f_at_rad = 1.0/32768L; /* now setup arrays of real coordinates corresponding to each pixel */ if(bf_math) adjust_to_limitsbf(1.0); /* make sure all corners in valid range */ else { adjust_to_limits(1.0); /* make sure all corners in valid range */ delxx = (LDBL)(xxmax - xx3rd) / (LDBL)dxsize; /* calculate stepsizes */ delyy = (LDBL)(yymax - yy3rd) / (LDBL)dysize; delxx2 = (LDBL)(xx3rd - xxmin) / (LDBL)dysize; delyy2 = (LDBL)(yy3rd - yymin) / (LDBL)dxsize; fill_dx_array(); } if(fractype != CELLULAR && fractype != ANT) /* fudgetolong fails w >10 digits in double */ { creal = fudgetolong(param[0]); /* integer equivs for it all */ cimag = fudgetolong(param[1]); xmin = fudgetolong(xxmin); xmax = fudgetolong(xxmax); x3rd = fudgetolong(xx3rd); ymin = fudgetolong(yymin); ymax = fudgetolong(yymax); y3rd = fudgetolong(yy3rd); delx = fudgetolong((double)delxx); dely = fudgetolong((double)delyy); delx2 = fudgetolong((double)delxx2); dely2 = fudgetolong((double)delyy2); } /* skip this if plasma to avoid 3d problems */ /* skip if bf_math to avoid extraseg conflict with dx0 arrays */ /* skip if ifs, ifs3d, or lsystem to avoid crash when mathtolerance */ /* is set. These types don't auto switch between float and integer math */ if (fractype != PLASMA && bf_math == 0 && fractype != IFS && fractype != IFS3D && fractype != LSYSTEM) { if (integerfractal && !invert && use_grid) { if ( (delx == 0 && delxx != 0.0) || (delx2 == 0 && delxx2 != 0.0) || (dely == 0 && delyy != 0.0) || (dely2 == 0 && delyy2 != 0.0) ) goto expand_retry; fill_lx_array(); /* fill up the x,y grids */ /* past max res? check corners within 10% of expected */ if ( ratio_bad((double)lx0[xdots-1]-xmin,(double)xmax-x3rd) || ratio_bad((double)ly0[ydots-1]-ymax,(double)y3rd-ymax) || ratio_bad((double)lx1[(ydots>>1)-1],((double)x3rd-xmin)/2) || ratio_bad((double)ly1[(xdots>>1)-1],((double)ymin-y3rd)/2) ) { expand_retry: if (integerfractal /* integer fractal type? */ && curfractalspecific->tofloat != NOFRACTAL) floatflag = 1; /* switch to floating pt */ else adjust_to_limits(2.0); /* double the size */ if (calc_status == 2) /* due to restore of an old file? */ calc_status = 0; /* whatever, it isn't resumable */ goto init_restart; } /* end if ratio bad */ /* re-set corners to match reality */ xmax = lx0[xdots-1] + lx1[ydots-1]; ymin = ly0[ydots-1] + ly1[xdots-1]; x3rd = xmin + lx1[ydots-1]; y3rd = ly0[ydots-1]; xxmin = fudgetodouble(xmin); xxmax = fudgetodouble(xmax); xx3rd = fudgetodouble(x3rd); yymin = fudgetodouble(ymin); yymax = fudgetodouble(ymax); yy3rd = fudgetodouble(y3rd); } /* end if (integerfractal && !invert && use_grid) */ else { double dx0,dy0,dx1,dy1; /* set up dx0 and dy0 analogs of lx0 and ly0 */ /* put fractal parameters in doubles */ dx0 = xxmin; /* fill up the x, y grids */ dy0 = yymax; dx1 = dy1 = 0; /* this way of defining the dx and dy arrays is not the most accurate, but it is kept because it is used to determine the limit of resolution */ for (i = 1; i < xdots; i++ ) { dx0 = (double)(dx0 + (double)delxx); dy1 = (double)(dy1 - (double)delyy2); } for (i = 1; i < ydots; i++ ) { dy0 = (double)(dy0 - (double)delyy); dx1 = (double)(dx1 + (double)delxx2); } if(bf_math == 0) /* redundant test, leave for now */ { double testx_try, testx_exact; double testy_try, testy_exact; /* Following is the old logic for detecting failure of double precision. It has two advantages: it is independent of the representation of numbers, and it is sensitive to resolution (allows depper zooms at lower resolution. However it fails for rotations of exactly 90 degrees, so we added a safety net by using the magnification. */ if(++tries < 2) /* for safety */ { static FCODE err[] = {"precision-detection error"}; if(tries > 1) stopmsg(0, err); /* Previously there were four tests of distortions in the zoom box used to detect precision limitations. In some cases of rotated/skewed zoom boxs, this causes the algorithm to bail out to arbitrary precision too soon. The logic now only tests the larger of the two deltas in an attempt to repair this bug. This should never make the transition to arbitrary precision sooner, but always later.*/ if(fabs(xxmax-xx3rd) > fabs(xx3rd-xxmin)) { testx_exact = xxmax-xx3rd; testx_try = dx0-xxmin; } else { testx_exact = xx3rd-xxmin; testx_try = dx1; } if(fabs(yy3rd-yymax) > fabs(yymin-yy3rd)) { testy_exact = yy3rd-yymax; testy_try = dy0-yymax; } else { testy_exact = yymin-yy3rd; testy_try = dy1; } if(ratio_bad(testx_try,testx_exact) || ratio_bad(testy_try,testy_exact)) { if(curfractalspecific->flags & BF_MATH) { fractal_floattobf(); goto init_restart; } goto expand_retry; } /* end if ratio_bad etc. */ } /* end if tries < 2 */ } /* end if bf_math == 0 */ /* if long double available, this is more accurate */ fill_dx_array(); /* fill up the x, y grids */ /* re-set corners to match reality */ xxmax = (double)(xxmin + (xdots-1)*delxx + (ydots-1)*delxx2); yymin = (double)(yymax - (ydots-1)*delyy - (xdots-1)*delyy2); xx3rd = (double)(xxmin + (ydots-1)*delxx2); yy3rd = (double)(yymax - (ydots-1)*delyy); } /* end else */ } /* end if not plasma */ /* for periodicity close-enough, and for unity: */ /* min(max(delx,delx2),max(dely,dely2) */ ddelmin = fabs((double)delxx); if (fabs((double)delxx2) > ddelmin) ddelmin = fabs((double)delxx2); if (fabs((double)delyy) > fabs((double)delyy2)) { if (fabs((double)delyy) < ddelmin) ddelmin = fabs((double)delyy); } else if (fabs((double)delyy2) < ddelmin) ddelmin = fabs((double)delyy2); delmin = fudgetolong(ddelmin); /* calculate factors which plot real values to screen co-ords */ /* calcfrac.c plot_orbit routines have comments about this */ ftemp = (double)((0.0-delyy2) * delxx2 * dxsize * dysize - (xxmax-xx3rd) * (yy3rd-yymax)); if(ftemp != 0) { plotmx1 = (double)(delxx2 * dxsize * dysize / ftemp); plotmx2 = (yy3rd-yymax) * dxsize / ftemp; plotmy1 = (double)((0.0-delyy2) * dxsize * dysize / ftemp); plotmy2 = (xxmax-xx3rd) * dysize / ftemp; } if(bf_math == 0) free_bf_vars(); else { /* zap all of extraseg except high area to flush out bugs */ /* in production version this code can be deleted */ char far *extra; extra = (char far *)MK_FP(extraseg,0); far_memset(extra,0,(unsigned int)(0x10000l-(bflength+2)*22U)); } } #ifdef _MSC_VER #if _MSC_VER == 800 #pragma optimize( "", on ) /* restore optimization options */ #endif #endif static long _fastcall fudgetolong(double d) { if ((d *= fudge) > 0) d += 0.5; else d -= 0.5; return (long)d; } static double _fastcall fudgetodouble(long l) { char buf[30]; double d; sprintf(buf,"%.9g",(double)l / fudge); #ifndef XFRACT sscanf(buf,"%lg",&d); #else sscanf(buf,"%lf",&d); #endif return d; } void adjust_cornerbf(void) { /* make edges very near vert/horiz exact, to ditch rounding errs and */ /* to avoid problems when delta per axis makes too large a ratio */ double ftemp; double Xmagfactor, Rotation, Skew; LDBL Magnification; bf_t bftemp, bftemp2; bf_t btmp1; int saved; saved = save_stack(); bftemp = alloc_stack(rbflength+2); bftemp2 = alloc_stack(rbflength+2); btmp1 = alloc_stack(rbflength+2); /* While we're at it, let's adjust the Xmagfactor as well */ /* use bftemp, bftemp2 as bfXctr, bfYctr */ cvtcentermagbf(bftemp, bftemp2, &Magnification, &Xmagfactor, &Rotation, &Skew); ftemp = fabs(Xmagfactor); if (ftemp != 1 && ftemp >= (1-aspectdrift) && ftemp <= (1+aspectdrift)) { Xmagfactor = sign(Xmagfactor); cvtcornersbf(bftemp, bftemp2, Magnification, Xmagfactor, Rotation, Skew); } /* ftemp=fabs(xx3rd-xxmin); */ abs_a_bf(sub_bf(bftemp,bfx3rd,bfxmin)); /* ftemp2=fabs(xxmax-xx3rd);*/ abs_a_bf(sub_bf(bftemp2,bfxmax,bfx3rd)); /* if( (ftemp=fabs(xx3rd-xxmin)) < (ftemp2=fabs(xxmax-xx3rd)) ) */ if(cmp_bf(bftemp,bftemp2) < 0) { /* if (ftemp*10000 < ftemp2 && yy3rd != yymax) */ if (cmp_bf(mult_bf_int(btmp1,bftemp,10000),bftemp2) < 0 && cmp_bf(bfy3rd,bfymax) != 0 ) /* xx3rd = xxmin; */ copy_bf(bfx3rd, bfxmin); } /* else if (ftemp2*10000 < ftemp && yy3rd != yymin) */ if (cmp_bf(mult_bf_int(btmp1,bftemp2,10000),bftemp) < 0 && cmp_bf(bfy3rd,bfymin) != 0 ) /* xx3rd = xxmax; */ copy_bf(bfx3rd, bfxmax); /* ftemp=fabs(yy3rd-yymin); */ abs_a_bf(sub_bf(bftemp,bfy3rd,bfymin)); /* ftemp2=fabs(yymax-yy3rd); */ abs_a_bf(sub_bf(bftemp2,bfymax,bfy3rd)); /* if( (ftemp=fabs(yy3rd-yymin)) < (ftemp2=fabs(yymax-yy3rd)) ) */ if(cmp_bf(bftemp,bftemp2) < 0) { /* if (ftemp*10000 < ftemp2 && xx3rd != xxmax) */ if (cmp_bf(mult_bf_int(btmp1,bftemp,10000),bftemp2) < 0 && cmp_bf(bfx3rd,bfxmax) != 0 ) /* yy3rd = yymin; */ copy_bf(bfy3rd, bfymin); } /* else if (ftemp2*10000 < ftemp && xx3rd != xxmin) */ if (cmp_bf(mult_bf_int(btmp1,bftemp2,10000),bftemp) < 0 && cmp_bf(bfx3rd,bfxmin) != 0 ) /* yy3rd = yymax; */ copy_bf(bfy3rd, bfymax); restore_stack(saved); } void adjust_corner(void) { /* make edges very near vert/horiz exact, to ditch rounding errs and */ /* to avoid problems when delta per axis makes too large a ratio */ double ftemp,ftemp2; double Xctr, Yctr, Xmagfactor, Rotation, Skew; LDBL Magnification; if(!integerfractal) { /* While we're at it, let's adjust the Xmagfactor as well */ cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); ftemp = fabs(Xmagfactor); if (ftemp != 1 && ftemp >= (1-aspectdrift) && ftemp <= (1+aspectdrift)) { Xmagfactor = sign(Xmagfactor); cvtcorners(Xctr, Yctr, Magnification, Xmagfactor, Rotation, Skew); } } if( (ftemp=fabs(xx3rd-xxmin)) < (ftemp2=fabs(xxmax-xx3rd)) ) { if (ftemp*10000 < ftemp2 && yy3rd != yymax) xx3rd = xxmin; } if (ftemp2*10000 < ftemp && yy3rd != yymin) xx3rd = xxmax; if( (ftemp=fabs(yy3rd-yymin)) < (ftemp2=fabs(yymax-yy3rd)) ) { if (ftemp*10000 < ftemp2 && xx3rd != xxmax) yy3rd = yymin; } if (ftemp2*10000 < ftemp && xx3rd != xxmin) yy3rd = yymax; } static void _fastcall adjust_to_limitsbf(double expand) { LDBL limit; bf_t bcornerx[4],bcornery[4]; bf_t blowx,bhighx,blowy,bhighy,blimit,bftemp; bf_t bcenterx,bcentery,badjx,badjy,btmp1,btmp2; bf_t bexpand; int i; int saved; saved = save_stack(); bcornerx[0] = alloc_stack(rbflength+2); bcornerx[1] = alloc_stack(rbflength+2); bcornerx[2] = alloc_stack(rbflength+2); bcornerx[3] = alloc_stack(rbflength+2); bcornery[0] = alloc_stack(rbflength+2); bcornery[1] = alloc_stack(rbflength+2); bcornery[2] = alloc_stack(rbflength+2); bcornery[3] = alloc_stack(rbflength+2); blowx = alloc_stack(rbflength+2); bhighx = alloc_stack(rbflength+2); blowy = alloc_stack(rbflength+2); bhighy = alloc_stack(rbflength+2); blimit = alloc_stack(rbflength+2); bftemp = alloc_stack(rbflength+2); bcenterx = alloc_stack(rbflength+2); bcentery = alloc_stack(rbflength+2); badjx = alloc_stack(rbflength+2); badjy = alloc_stack(rbflength+2); btmp1 = alloc_stack(rbflength+2); btmp2 = alloc_stack(rbflength+2); bexpand = alloc_stack(rbflength+2); limit = 32767.99; /* if (bitshift >= 24) limit = 31.99; if (bitshift >= 29) limit = 3.99; */ floattobf(blimit,limit); floattobf(bexpand,expand); add_bf(bcenterx,bfxmin,bfxmax); half_a_bf(bcenterx); /* centery = (yymin+yymax)/2; */ add_bf(bcentery,bfymin,bfymax); half_a_bf(bcentery); /* if (xxmin == centerx) { */ if (cmp_bf(bfxmin,bcenterx)==0) { /* ohoh, infinitely thin, fix it */ smallest_add_bf(bfxmax); /* bfxmin -= bfxmax-centerx; */ sub_a_bf(bfxmin,sub_bf(btmp1,bfxmax,bcenterx)); } /* if (bfymin == centery) */ if (cmp_bf(bfymin,bcentery)==0) { smallest_add_bf(bfymax); /* bfymin -= bfymax-centery; */ sub_a_bf(bfymin,sub_bf(btmp1,bfymax,bcentery)); } /* if (bfx3rd == centerx) */ if (cmp_bf(bfx3rd,bcenterx)==0) smallest_add_bf(bfx3rd); /* if (bfy3rd == centery) */ if (cmp_bf(bfy3rd,bcentery)==0) smallest_add_bf(bfy3rd); /* setup array for easier manipulation */ /* cornerx[0] = xxmin; */ copy_bf(bcornerx[0],bfxmin); /* cornerx[1] = xxmax; */ copy_bf(bcornerx[1],bfxmax); /* cornerx[2] = xx3rd; */ copy_bf(bcornerx[2],bfx3rd); /* cornerx[3] = xxmin+(xxmax-xx3rd); */ sub_bf(bcornerx[3],bfxmax,bfx3rd); add_a_bf(bcornerx[3],bfxmin); /* cornery[0] = yymax; */ copy_bf(bcornery[0],bfymax); /* cornery[1] = yymin; */ copy_bf(bcornery[1],bfymin); /* cornery[2] = yy3rd; */ copy_bf(bcornery[2],bfy3rd); /* cornery[3] = yymin+(yymax-yy3rd); */ sub_bf(bcornery[3],bfymax,bfy3rd); add_a_bf(bcornery[3],bfymin); /* if caller wants image size adjusted, do that first */ if (expand != 1.0) { for (i=0; i<4; ++i) { /* cornerx[i] = centerx + (cornerx[i]-centerx)*expand; */ sub_bf(btmp1,bcornerx[i],bcenterx); mult_bf(bcornerx[i],btmp1,bexpand); add_a_bf(bcornerx[i],bcenterx); /* cornery[i] = centery + (cornery[i]-centery)*expand; */ sub_bf(btmp1,bcornery[i],bcentery); mult_bf(bcornery[i],btmp1,bexpand); add_a_bf(bcornery[i],bcentery); } } /* get min/max x/y values */ /* lowx = highx = cornerx[0]; */ copy_bf(blowx,bcornerx[0]); copy_bf(bhighx,bcornerx[0]); /* lowy = highy = cornery[0]; */ copy_bf(blowy,bcornery[0]); copy_bf(bhighy,bcornery[0]); for (i=1; i<4; ++i) { /* if (cornerx[i] < lowx) lowx = cornerx[i]; */ if (cmp_bf(bcornerx[i],blowx) < 0) copy_bf(blowx,bcornerx[i]); /* if (cornerx[i] > highx) highx = cornerx[i]; */ if (cmp_bf(bcornerx[i],bhighx) > 0) copy_bf(bhighx,bcornerx[i]); /* if (cornery[i] < lowy) lowy = cornery[i]; */ if (cmp_bf(bcornery[i],blowy) < 0) copy_bf(blowy,bcornery[i]); /* if (cornery[i] > highy) highy = cornery[i]; */ if (cmp_bf(bcornery[i],bhighy) > 0) copy_bf(bhighy,bcornery[i]); } /* if image is too large, downsize it maintaining center */ /* ftemp = highx-lowx; */ sub_bf(bftemp,bhighx,blowx); /* if (highy-lowy > ftemp) ftemp = highy-lowy; */ if (cmp_bf(sub_bf(btmp1,bhighy,blowy),bftemp) > 0) copy_bf(bftemp,btmp1); /* if image is too large, downsize it maintaining center */ floattobf(btmp1,limit*2.0); copy_bf(btmp2,bftemp); div_bf(bftemp,btmp1,btmp2); floattobf(btmp1,1.0); if (cmp_bf(bftemp,btmp1) < 0) for (i=0; i<4; ++i) { /* cornerx[i] = centerx + (cornerx[i]-centerx)*ftemp; */ sub_bf(btmp1,bcornerx[i],bcenterx); mult_bf(bcornerx[i],btmp1,bftemp); add_a_bf(bcornerx[i],bcenterx); /* cornery[i] = centery + (cornery[i]-centery)*ftemp; */ sub_bf(btmp1,bcornery[i],bcentery); mult_bf(bcornery[i],btmp1,bftemp); add_a_bf(bcornery[i],bcentery); } /* if any corner has x or y past limit, move the image */ /* adjx = adjy = 0; */ clear_bf(badjx); clear_bf(badjy); for (i=0; i<4; ++i) { /* if (cornerx[i] > limit && (ftemp = cornerx[i] - limit) > adjx) adjx = ftemp; */ if (cmp_bf(bcornerx[i],blimit) > 0 && cmp_bf(sub_bf(bftemp,bcornerx[i],blimit),badjx) > 0) copy_bf(badjx,bftemp); /* if (cornerx[i] < 0.0-limit && (ftemp = cornerx[i] + limit) < adjx) adjx = ftemp; */ if (cmp_bf(bcornerx[i],neg_bf(btmp1,blimit)) < 0 && cmp_bf(add_bf(bftemp,bcornerx[i],blimit),badjx) < 0) copy_bf(badjx,bftemp); /* if (cornery[i] > limit && (ftemp = cornery[i] - limit) > adjy) adjy = ftemp; */ if (cmp_bf(bcornery[i],blimit) > 0 && cmp_bf(sub_bf(bftemp,bcornery[i],blimit),badjy) > 0) copy_bf(badjy,bftemp); /* if (cornery[i] < 0.0-limit && (ftemp = cornery[i] + limit) < adjy) adjy = ftemp; */ if (cmp_bf(bcornery[i],neg_bf(btmp1,blimit)) < 0 && cmp_bf(add_bf(bftemp,bcornery[i],blimit),badjy) < 0) copy_bf(badjy,bftemp); } /* if (calc_status == 2 && (adjx != 0 || adjy != 0) && (zwidth == 1.0)) calc_status = 0; */ if (calc_status == 2 && (is_bf_not_zero(badjx)|| is_bf_not_zero(badjy)) && (zwidth == 1.0)) calc_status = 0; /* xxmin = cornerx[0] - adjx; */ sub_bf(bfxmin,bcornerx[0],badjx); /* xxmax = cornerx[1] - adjx; */ sub_bf(bfxmax,bcornerx[1],badjx); /* xx3rd = cornerx[2] - adjx; */ sub_bf(bfx3rd,bcornerx[2],badjx); /* yymax = cornery[0] - adjy; */ sub_bf(bfymax,bcornery[0],badjy); /* yymin = cornery[1] - adjy; */ sub_bf(bfymin,bcornery[1],badjy); /* yy3rd = cornery[2] - adjy; */ sub_bf(bfy3rd,bcornery[2],badjy); adjust_cornerbf(); /* make 3rd corner exact if very near other co-ords */ restore_stack(saved); } static void _fastcall adjust_to_limits(double expand) { double cornerx[4],cornery[4]; double lowx,highx,lowy,highy,limit,ftemp; double centerx,centery,adjx,adjy; int i; limit = 32767.99; if (integerfractal) { if (save_release > 1940) /* let user reproduce old GIF's and PAR's */ limit = 1023.99; if (bitshift >= 24) limit = 31.99; if (bitshift >= 29) limit = 3.99; } centerx = (xxmin+xxmax)/2; centery = (yymin+yymax)/2; if (xxmin == centerx) { /* ohoh, infinitely thin, fix it */ smallest_add(&xxmax); xxmin -= xxmax-centerx; } if (yymin == centery) { smallest_add(&yymax); yymin -= yymax-centery; } if (xx3rd == centerx) smallest_add(&xx3rd); if (yy3rd == centery) smallest_add(&yy3rd); /* setup array for easier manipulation */ cornerx[0] = xxmin; cornerx[1] = xxmax; cornerx[2] = xx3rd; cornerx[3] = xxmin+(xxmax-xx3rd); cornery[0] = yymax; cornery[1] = yymin; cornery[2] = yy3rd; cornery[3] = yymin+(yymax-yy3rd); /* if caller wants image size adjusted, do that first */ if (expand != 1.0) { for (i=0; i<4; ++i) { cornerx[i] = centerx + (cornerx[i]-centerx)*expand; cornery[i] = centery + (cornery[i]-centery)*expand; } } /* get min/max x/y values */ lowx = highx = cornerx[0]; lowy = highy = cornery[0]; for (i=1; i<4; ++i) { if (cornerx[i] < lowx) lowx = cornerx[i]; if (cornerx[i] > highx) highx = cornerx[i]; if (cornery[i] < lowy) lowy = cornery[i]; if (cornery[i] > highy) highy = cornery[i]; } /* if image is too large, downsize it maintaining center */ ftemp = highx-lowx; if (highy-lowy > ftemp) ftemp = highy-lowy; /* if image is too large, downsize it maintaining center */ if ((ftemp = limit*2/ftemp) < 1.0) { for (i=0; i<4; ++i) { cornerx[i] = centerx + (cornerx[i]-centerx)*ftemp; cornery[i] = centery + (cornery[i]-centery)*ftemp; } } /* if any corner has x or y past limit, move the image */ adjx = adjy = 0; for (i=0; i<4; ++i) { if (cornerx[i] > limit && (ftemp = cornerx[i] - limit) > adjx) adjx = ftemp; if (cornerx[i] < 0.0-limit && (ftemp = cornerx[i] + limit) < adjx) adjx = ftemp; if (cornery[i] > limit && (ftemp = cornery[i] - limit) > adjy) adjy = ftemp; if (cornery[i] < 0.0-limit && (ftemp = cornery[i] + limit) < adjy) adjy = ftemp; } if (calc_status == 2 && (adjx != 0 || adjy != 0) && (zwidth == 1.0)) calc_status = 0; xxmin = cornerx[0] - adjx; xxmax = cornerx[1] - adjx; xx3rd = cornerx[2] - adjx; yymax = cornery[0] - adjy; yymin = cornery[1] - adjy; yy3rd = cornery[2] - adjy; adjust_corner(); /* make 3rd corner exact if very near other co-ords */ } static void _fastcall smallest_add(double *num) { *num += *num * 5.0e-16; } static void _fastcall smallest_add_bf(bf_t num) { bf_t btmp1; int saved; saved = save_stack(); btmp1 = alloc_stack(bflength+2); mult_bf(btmp1,floattobf(btmp1, 5.0e-16),num); add_a_bf(num,btmp1); restore_stack(saved); } static int _fastcall ratio_bad(double actual, double desired) { double ftemp, tol; if(integerfractal) tol = math_tol[0]; else tol = math_tol[1]; if(tol <= 0.0) return(1); else if(tol >= 1.0) return(0); ftemp = 0; if (desired != 0 && debugflag != 3400) { ftemp = actual / desired; if (ftemp < (1.0-tol) || ftemp > (1.0+tol)) return(1); } return(0); } /* Save/resume stuff: Engines which aren't resumable can simply ignore all this. Before calling the (per_image,calctype) routines (engine), calcfract sets: "resuming" to 0 if new image, nonzero if resuming a partially done image "calc_status" to 1 If an engine is interrupted and wants to be able to resume it must: store whatever status info it needs to be able to resume later set calc_status to 2 and return If subsequently called with resuming!=0, the engine must restore status info and continue from where it left off. Since the info required for resume can get rather large for some types, it is not stored directly in save_info. Instead, memory is dynamically allocated as required, and stored in .fra files as a separate block. To save info for later resume, an engine routine can use: alloc_resume(maxsize,version) Maxsize must be >= max bytes subsequently saved + 2; over-allocation is harmless except for possibility of insufficient mem available; undersize is not checked and probably causes serious misbehaviour. Version is an arbitrary number so that subsequent revisions of the engine can be made backward compatible. Alloc_resume sets calc_status to 2 (resumable) if it succeeds; to 3 if it cannot allocate memory (and issues warning to user). put_resume({bytes,&argument,} ... 0) Can be called as often as required to store the info. Arguments must not be far addresses. Is not protected against calls which use more space than allocated. To reload info when resuming, use: start_resume() initializes and returns version number get_resume({bytes,&argument,} ... 0) inverse of store_resume end_resume() optional, frees the memory area sooner than would happen otherwise Example, save info: alloc_resume(sizeof(parmarray)+100,2); put_resume(sizeof(row),&row, sizeof(col),&col, sizeof(parmarray),parmarray, 0); restore info: vsn = start_resume(); get_resume(sizeof(row),&row, sizeof(col),&col, 0); if (vsn >= 2) get_resume(sizeof(parmarray),parmarray,0); end_resume(); Engines which allocate a large far memory chunk of their own might directly set resume_info, resume_len, calc_status to avoid doubling transient memory needs by using these routines. StandardFractal, calcmand, solidguess, and bound_trace_main are a related set of engines for escape-time fractals. They use a common worklist structure for save/resume. Fractals using these must specify calcmand or StandardFractal as the engine in fractalspecificinfo. Other engines don't get btm nor ssg, don't get off-axis symmetry nor panning (the worklist stuff), and are on their own for save/resume. */ #ifndef USE_VARARGS int put_resume(int len, ...) #else int put_resume(va_alist) va_dcl #endif { va_list arg_marker; /* variable arg list */ BYTE *source_ptr; #ifdef USE_VARARGS int len; #endif if (resume_info == 0) return(-1); #ifndef USE_VARARGS va_start(arg_marker,len); #else va_start(arg_marker); len = va_arg(arg_marker,int); #endif while (len) { source_ptr = (BYTE *)va_arg(arg_marker,char *); /* far_memcpy(resume_info+resume_len,source_ptr,len); */ MoveToMemory(source_ptr,(U16)1,(long)len,resume_len,resume_info); resume_len += len; len = va_arg(arg_marker,int); } va_end(arg_marker); return(0); } int alloc_resume(int alloclen, int version) { /* WARNING! if alloclen > 4096B, problems may occur with GIF save/restore */ if (resume_info != 0) /* free the prior area if there is one */ MemoryRelease(resume_info); if ((resume_info = MemoryAlloc((U16)sizeof(alloclen), (long)alloclen, FARMEM)) == 0) { static FCODE msg[] = {"\ Warning - insufficient free memory to save status.\n\ You will not be able to resume calculating this image."}; stopmsg(0,msg); calc_status = 3; return(-1); } resume_len = 0; put_resume(sizeof(version),&version,0); calc_status = 2; return(0); } #ifndef USE_VARARGS int get_resume(int len, ...) #else int get_resume(va_alist) va_dcl #endif { va_list arg_marker; /* variable arg list */ BYTE *dest_ptr; #ifdef USE_VARARGS int len; #endif if (resume_info == 0) return(-1); #ifndef USE_VARARGS va_start(arg_marker,len); #else va_start(arg_marker); len = va_arg(arg_marker,int); #endif while (len) { dest_ptr = (BYTE *)va_arg(arg_marker,char *); /* far_memcpy(dest_ptr,resume_info+resume_offset,len); */ MoveFromMemory(dest_ptr,(U16)1,(long)len,resume_offset,resume_info); resume_offset += len; len = va_arg(arg_marker,int); } va_end(arg_marker); return(0); } int start_resume(void) { int version; if (resume_info == 0) return(-1); resume_offset = 0; get_resume(sizeof(version),&version,0); return(version); } void end_resume(void) { if (resume_info != 0) /* free the prior area if there is one */ { MemoryRelease(resume_info); resume_info = 0; } } /* Showing orbit requires converting real co-ords to screen co-ords. Define: Xs == xxmax-xx3rd Ys == yy3rd-yymax W == xdots-1 D == ydots-1 We know that: realx == lx0[col] + lx1[row] realy == ly0[row] + ly1[col] lx0[col] == (col/width) * Xs + xxmin lx1[row] == row * delxx ly0[row] == (row/D) * Ys + yymax ly1[col] == col * (0-delyy) so: realx == (col/W) * Xs + xxmin + row * delxx realy == (row/D) * Ys + yymax + col * (0-delyy) and therefore: row == (realx-xxmin - (col/W)*Xs) / Xv (1) col == (realy-yymax - (row/D)*Ys) / Yv (2) substitute (2) into (1) and solve for row: row == ((realx-xxmin)*(0-delyy2)*W*D - (realy-yymax)*Xs*D) / ((0-delyy2)*W*delxx2*D-Ys*Xs) */ /* sleep N * a tenth of a millisecond */ void sleepms_old(long ms) { static long scalems = 0L; int savehelpmode,savetabmode; struct timebx t1,t2; #define SLEEPINIT 250 /* milliseconds for calibration */ savetabmode = tabmode; savehelpmode = helpmode; tabmode = 0; helpmode = -1; if(scalems==0L) /* calibrate */ { /* selects a value of scalems that makes the units 10000 per sec independent of CPU speed */ int i,elapsed; scalems = 1L; if(keypressed()) /* check at start, hope to get start of timeslice */ goto sleepexit; /* calibrate, assume slow computer first */ showtempmsg("Calibrating timer"); do { scalems *= 2; ftimex(&t2); do { /* wait for the start of a new tick */ ftimex(&t1); } while (t2.time == t1.time && t2.millitm == t1.millitm); sleepms_old(10L * SLEEPINIT); /* about 1/4 sec */ ftimex(&t2); if(keypressed()) { scalems = 0L; cleartempmsg(); goto sleepexit; } } while ((elapsed = (int)(t2.time-t1.time)*1000 + t2.millitm-t1.millitm) < SLEEPINIT); /* once more to see if faster (eg multi-tasking) */ do { /* wait for the start of a new tick */ ftimex(&t1); } while (t2.time == t1.time && t2.millitm == t1.millitm); sleepms_old(10L * SLEEPINIT); ftimex(&t2); if ((i = (int)(t2.time-t1.time)*1000 + t2.millitm-t1.millitm) < elapsed) elapsed = (i == 0) ? 1 : i; scalems = (long)((float)SLEEPINIT/(float)(elapsed) * scalems); cleartempmsg(); } if(ms > 10L * SLEEPINIT) { /* using ftime is probably more accurate */ ms /= 10; ftimex(&t1); for(;;) { if(keypressed()) break; ftimex(&t2); if ((long)((t2.time-t1.time)*1000 + t2.millitm-t1.millitm) >= ms) break; } } else if(!keypressed()) { ms *= scalems; while(ms-- >= 0); } sleepexit: tabmode = savetabmode; helpmode = savehelpmode; } static void sleepms_new(long ms) { uclock_t next_time; uclock_t now = usec_clock(); next_time = now + ms*100; while ((now = usec_clock()) < next_time) if(keypressed()) break; } void sleepms(long ms) { if(debugflag == 4020) sleepms_old(ms); else sleepms_new(ms); } /* * wait until wait_time microseconds from the * last call has elapsed. */ #define MAX_INDEX 2 static uclock_t next_time[MAX_INDEX]; void wait_until(int index, uclock_t wait_time) { if(debugflag == 4020) sleepms_old(wait_time); else { uclock_t now; while ( (now = usec_clock()) < next_time[index]) if(keypressed()) break; next_time[index] = now + wait_time*100; /* wait until this time next call */ } } void reset_clock(void) { int i; restart_uclock(); for(i=0;i= 1500) return; i = (int)(dy * plotmx1 - dx * plotmx2); i += sxoffs; if (i < 0 || i >= sxdots) return; j = (int)(dx * plotmy1 - dy * plotmy2); j += syoffs; if (j < 0 || j >= sydots) return; save_sxoffs = sxoffs; save_syoffs = syoffs; sxoffs = syoffs = 0; /* save orbit value */ if(color == -1) { *(save_orbit + orbit_ptr++) = i; *(save_orbit + orbit_ptr++) = j; *(save_orbit + orbit_ptr++) = c = getcolor(i,j); putcolor(i,j,c^orbit_color); } else putcolor(i,j,color); sxoffs = save_sxoffs; syoffs = save_syoffs; if(debugflag == 4030) { if((soundflag&7) == 2) /* sound = x */ w_snd((int)(i*1000/xdots+basehertz)); else if((soundflag&7) > 2) /* sound = y or z */ w_snd((int)(j*1000/ydots+basehertz)); else if(orbit_delay > 0) { wait_until(0,orbit_delay); } } else { if((soundflag&7) == 2) /* sound = x */ w_snd((int)(i+basehertz)); else if((soundflag&7) == 3) /* sound = y */ w_snd((int)(j+basehertz)); else if((soundflag&7) == 4) /* sound = z */ w_snd((int)(i+j+basehertz)); else if(orbit_delay > 0) { wait_until(0,orbit_delay); } } /* placing sleepms here delays each dot */ } void iplot_orbit(long ix, long iy, int color) { plotdorbit((double)ix/fudge-xxmin,(double)iy/fudge-yymax,color); } void plot_orbit(double real,double imag,int color) { plotdorbit(real-xxmin,imag-yymax,color); } void scrub_orbit(void) { int i,j,c; int save_sxoffs,save_syoffs; mute(); save_sxoffs = sxoffs; save_syoffs = syoffs; sxoffs = syoffs = 0; while(orbit_ptr > 0) { c = *(save_orbit + --orbit_ptr); j = *(save_orbit + --orbit_ptr); i = *(save_orbit + --orbit_ptr); putcolor(i,j,c); } sxoffs = save_sxoffs; syoffs = save_syoffs; } int add_worklist(int xfrom, int xto, int xbegin, int yfrom, int yto, int ybegin, int pass, int sym) { if (num_worklist >= MAXCALCWORK) return(-1); worklist[num_worklist].xxstart = xfrom; worklist[num_worklist].xxstop = xto; worklist[num_worklist].xxbegin = xbegin; worklist[num_worklist].yystart = yfrom; worklist[num_worklist].yystop = yto; worklist[num_worklist].yybegin = ybegin; worklist[num_worklist].pass = pass; worklist[num_worklist].sym = sym; ++num_worklist; tidy_worklist(); return(0); } static int _fastcall combine_worklist(void) /* look for 2 entries which can freely merge */ { int i,j; for (i=0; i= N_ATTR) /* space for more attractors ? */ return; /* Bad luck - no room left ! */ savper = periodicitycheck; savmaxit = maxit; periodicitycheck = 0; old.x = real; /* prepare for f.p orbit calc */ old.y = imag; tempsqrx = sqr(old.x); tempsqry = sqr(old.y); lold.x = (long)real; /* prepare for int orbit calc */ lold.y = (long)imag; ltempsqrx = (long)tempsqrx; ltempsqry = (long)tempsqry; lold.x = lold.x << bitshift; lold.y = lold.y << bitshift; ltempsqrx = ltempsqrx << bitshift; ltempsqry = ltempsqry << bitshift; if (maxit < 500) /* we're going to try at least this hard */ maxit = 500; coloriter = 0; overflow = 0; while (++coloriter < maxit) if(curfractalspecific->orbitcalc() || overflow) break; if (coloriter >= maxit) /* if orbit stays in the lake */ { if (integerfractal) /* remember where it went to */ lresult = lnew; else result = new; for (i=0;i<10;i++) { overflow = 0; if(!curfractalspecific->orbitcalc() && !overflow) /* if it stays in the lake */ { /* and doesn't move far, probably */ if (integerfractal) /* found a finite attractor */ { if(labs(lresult.x-lnew.x) < lclosenuff && labs(lresult.y-lnew.y) < lclosenuff) { lattr[attractors] = lnew; attrperiod[attractors] = i+1; attractors++; /* another attractor - coloured lakes ! */ break; } } else { if(fabs(result.x-new.x) < closenuff && fabs(result.y-new.y) < closenuff) { attr[attractors] = new; attrperiod[attractors] = i+1; attractors++; /* another attractor - coloured lakes ! */ break; } } } else { break; } } } if(attractors==0) periodicitycheck = savper; maxit = savmaxit; } #define maxyblk 7 /* must match calcfrac.c */ #define maxxblk 202 /* must match calcfrac.c */ int ssg_blocksize(void) /* used by solidguessing and by zoom panning */ { int blocksize,i; /* blocksize 4 if <300 rows, 8 if 300-599, 16 if 600-1199, 32 if >=1200 */ blocksize=4; i=300; while(i<=ydots) { blocksize+=blocksize; i+=i; } /* increase blocksize if prefix array not big enough */ while(blocksize*(maxxblk-2) /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "big.h" #ifndef BIG_ANSI_C #include #endif #define LOG10_256 2.4082399653118 #define LOG_256 5.5451774444795 #if (_MSC_VER >= 700) /* for Fractint */ #pragma code_seg ("bigflt1_text") /* place following in an overlay */ #endif /********************************************************************/ /* bf_hexdump() - for debugging, dumps to stdout */ void bf_hexdump(bf_t r) { int i; for (i=0; i= '0' && *l <= '9') /* while a digit */ { onesbyte = (BYTE)(*(l--) - '0'); inttobf(bftmp1,onesbyte); unsafe_add_a_bf(r, bftmp1); div_a_bf_int(r, 10); } if (*(l--) == '.') /* the digit was found */ { keeplooping = *l >= '0' && *l <= '9' && l>=s; while (keeplooping) /* while a digit */ { onesbyte = (BYTE)(*(l--) - '0'); inttobf(bftmp1,onesbyte); unsafe_add_a_bf(r, bftmp1); keeplooping = *l >= '0' && *l <= '9' && l>=s; if (keeplooping) { div_a_bf_int(r, 10); powerten++; /* increase the power of ten */ } } } } else { keeplooping = *l >= '0' && *l <= '9' && l>=s; while (keeplooping) /* while a digit */ { onesbyte = (BYTE)(*(l--) - '0'); inttobf(bftmp1,onesbyte); unsafe_add_a_bf(r, bftmp1); keeplooping = *l >= '0' && *l <= '9' && l>=s; if (keeplooping) { div_a_bf_int(r, 10); powerten++; /* increase the power of ten */ } } } if (powerten > 0) { for (; powerten>0; powerten--) { mult_a_bf_int(r, 10); } } else if (powerten < 0) { for (; powerten<0; powerten++) { div_a_bf_int(r, 10); } } if (signflag) neg_a_bf(r); return r; } /********************************************************************/ /* strlen_needed() - returns string length needed to hold bigfloat */ int strlen_needed_bf() { int length; /* first space for integer part */ length = 1; length += decimals; /* decimal part */ length += 2; /* decimal point and sign */ length += 2; /* e and sign */ length += 4; /* exponent */ length += 4; /* null and a little extra for safety */ return(length); } /********************************************************************/ /* bftostr() - converts a bigfloat into a scientific notation string */ /* s - string, must be large enough to hold the number. */ /* dec - decimal places, 0 for max */ /* r - bigfloat */ /* will convert to a floating point notation */ /* SIDE-EFFECT: the bigfloat, r, is destroyed. */ /* Copy it first if necessary. */ /* USES: bftmp1 - bftmp2 */ /********************************************************************/ char *unsafe_bftostr(char *s, int dec, bf_t r) { LDBL value; int power; value = bftofloat(r); if (value == 0.0) { strcpy(s, "0.0"); return s; } copy_bf(bftmp1, r); unsafe_bftobf10(bf10tmp, dec, bftmp1); power = (S16)big_access16(bf10tmp+dec+2); /* where the exponent is stored */ if (power > -4 && power < 6) /* tinker with this */ bf10tostr_f(s, dec, bf10tmp); else bf10tostr_e(s, dec, bf10tmp); return s; } /********************************************************************/ /* the e version puts it in scientific notation, (like printf's %e) */ char *unsafe_bftostr_e(char *s, int dec, bf_t r) { LDBL value; value = bftofloat(r); if (value == 0.0) { strcpy(s, "0.0"); return s; } copy_bf(bftmp1, r); unsafe_bftobf10(bf10tmp, dec, bftmp1); bf10tostr_e(s, dec, bf10tmp); return s; } /********************************************************************/ /* the f version puts it in decimal notation, (like printf's %f) */ char *unsafe_bftostr_f(char *s, int dec, bf_t r) { LDBL value; value = bftofloat(r); if (value == 0.0) { strcpy(s, "0.0"); return s; } copy_bf(bftmp1, r); unsafe_bftobf10(bf10tmp, dec, bftmp1); bf10tostr_f(s, dec, bf10tmp); return s; } #if (_MSC_VER >= 700) #pragma code_seg ( ) /* back to normal segment */ #endif /*********************************************************************/ /* bn = floor(bf) */ /* Converts a bigfloat to a bignumber (integer) */ /* bflength must be at least bnlength+2 */ bn_t bftobn(bn_t n, bf_t f) { int fexp; int movebytes; BYTE hibyte; fexp = (S16)big_access16(f+bflength); if (fexp >= intlength) { /* if it's too big, use max value */ max_bn(n); if (is_bf_neg(f)) neg_a_bn(n); return n; } if (-fexp > bnlength - intlength) /* too small, return zero */ { clear_bn(n); return n; } /* already checked for over/underflow, this should be ok */ movebytes = bnlength - intlength + fexp + 1; _fmemcpy(n, f+bflength-movebytes-1, movebytes); hibyte = *(f+bflength-1); _fmemset(n+movebytes, hibyte, bnlength-movebytes); /* sign extends */ return n; } /*********************************************************************/ /* bf = bn */ /* Converts a bignumber (integer) to a bigfloat */ /* bflength must be at least bnlength+2 */ bf_t bntobf(bf_t f, bn_t n) { _fmemcpy(f+bflength-bnlength-1, n, bnlength); _fmemset(f, 0, bflength - bnlength - 1); *(f+bflength-1) = (BYTE)(is_bn_neg(n) ? 0xFF : 0x00); /* sign extend */ big_set16(f+bflength, (S16)(intlength - 1)); /* exp */ norm_bf(f); return f; } /*********************************************************************/ /* b = l */ /* Converts a long to a bigfloat */ bf_t inttobf(bf_t r, long longval) { clear_bf(r); big_set32(r+bflength-4, (S32)longval); big_set16(r+bflength, (S16)2); norm_bf(r); return r; } /*********************************************************************/ /* l = floor(b), floor rounds down */ /* Converts a bigfloat to a long */ /* note: a bf value of 2.999... will be return a value of 2, not 3 */ long bftoint(bf_t f) { int fexp; long longval; fexp = (S16)big_access16(f+bflength); if (fexp > 3) { longval = 0x7FFFFFFFL; if (is_bf_neg(f)) longval = -longval; return longval; } longval = big_access32(f+bflength-5); longval >>= 8*(3-fexp); return longval; } /********************************************************************/ /* sign(r) */ int sign_bf(bf_t n) { return is_bf_neg(n) ? -1 : is_bf_not_zero(n) ? 1 : 0; } /********************************************************************/ /* r = |n| */ bf_t abs_bf(bf_t r, bf_t n) { copy_bf(r,n); if (is_bf_neg(r)) { neg_a_bf(r); } return r; } /********************************************************************/ /* r = |r| */ bf_t abs_a_bf(bf_t r) { if (is_bf_neg(r)) neg_a_bf(r); return r; } /********************************************************************/ /* r = 1/n */ /* uses bftmp1 - bftmp2 - global temp bigfloats */ /* SIDE-EFFECTS: */ /* n ends up as |n|/256^exp Make copy first if necessary. */ bf_t unsafe_inv_bf(bf_t r, bf_t n) { int signflag=0, i; int fexp, rexp; LDBL f; bf_t orig_r, orig_n; /* orig_bftmp1 not needed here */ int orig_bflength, orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor, orig_rbflength; /* use Newton's recursive method for zeroing in on 1/n : r=r(2-rn) */ if (is_bf_neg(n)) { /* will be a lot easier to deal with just positives */ signflag = 1; neg_a_bf(n); } fexp = (S16)big_access16(n+bflength); big_set16(n+bflength, (S16)0); /* put within LDBL range */ f = bftofloat(n); if (f == 0) /* division by zero */ { max_bf(r); return r; } f = 1/f; /* approximate inverse */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bflength = bflength; orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_rbflength = rbflength; orig_r = r; orig_n = n; /* orig_bftmp1 = bftmp1; */ /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; /* bftmp1 = orig_bftmp1 + orig_bflength - bflength; */ floattobf(r, f); /* start with approximate inverse */ for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; /* bftmp1 = orig_bftmp1 + orig_bflength - bflength; */ unsafe_mult_bf(bftmp1, r, n); /* bftmp1=rn */ inttobf(bftmp2, 1); /* will be used as 1.0 */ /* There seems to very little difficulty getting bftmp1 to be EXACTLY 1 */ if (bflength == orig_bflength && cmp_bf(bftmp1, bftmp2) == 0) break; inttobf(bftmp2, 2); /* will be used as 2.0 */ unsafe_sub_a_bf(bftmp2, bftmp1); /* bftmp2=2-rn */ unsafe_mult_bf(bftmp1, r, bftmp2); /* bftmp1=r(2-rn) */ copy_bf(r, bftmp1); /* r = bftmp1 */ } /* restore original values */ bflength = orig_bflength; bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; rbflength = orig_rbflength; r = orig_r; n = orig_n; /* bftmp1 = orig_bftmp1; */ if (signflag) { neg_a_bf(r); } rexp = (S16)big_access16(r+bflength); rexp -= fexp; big_set16(r+bflength, (S16)rexp); /* adjust result exponent */ return r; } /********************************************************************/ /* r = n1/n2 */ /* r - result of length bflength */ /* uses bftmp1 - bftmp2 - global temp bigfloats */ /* SIDE-EFFECTS: */ /* n1, n2 end up as |n1|/256^x, |n2|/256^x */ /* Make copies first if necessary. */ bf_t unsafe_div_bf(bf_t r, bf_t n1, bf_t n2) { int aexp, bexp, rexp; LDBL a, b; /* first, check for valid data */ aexp = (S16)big_access16(n1+bflength); big_set16(n1+bflength, (S16)0); /* put within LDBL range */ a = bftofloat(n1); if (a == 0) /* division into zero */ { clear_bf(r); /* return 0 */ return r; } bexp = (S16)big_access16(n2+bflength); big_set16(n2+bflength, (S16)0); /* put within LDBL range */ b = bftofloat(n2); if (b == 0) /* division by zero */ { max_bf(r); return r; } unsafe_inv_bf(r, n2); unsafe_mult_bf(bftmp1, n1, r); copy_bf(r, bftmp1); /* r = bftmp1 */ rexp = (S16)big_access16(r+bflength); rexp += aexp - bexp; big_set16(r+bflength, (S16)rexp); /* adjust result exponent */ return r; } /********************************************************************/ /* sqrt(r) */ /* uses bftmp1 - bftmp3 - global temp bigfloats */ /* SIDE-EFFECTS: */ /* n ends up as |n| */ bf_t unsafe_sqrt_bf(bf_t r, bf_t n) { int i, comp, almost_match=0; LDBL f; bf_t orig_r, orig_n; int orig_bflength, orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor, orig_rbflength; /* use Newton's recursive method for zeroing in on sqrt(n): r=.5(r+n/r) */ if (is_bf_neg(n)) { /* sqrt of a neg, return 0 */ clear_bf(r); return r; } f = bftofloat(n); if (f == 0) /* division by zero will occur */ { clear_bf(r); /* sqrt(0) = 0 */ return r; } f = sqrtl(f); /* approximate square root */ /* no need to check overflow */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bflength = bflength; orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_rbflength = rbflength; orig_r = r; orig_n = n; /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; floattobf(r, f); /* start with approximate sqrt */ for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; unsafe_div_bf(bftmp3, n, r); unsafe_add_a_bf(r, bftmp3); half_a_bf(r); if (bflength == orig_bflength && (comp=abs(cmp_bf(r, bftmp3))) < 8 ) /* if match or almost match */ { if (comp < 4 /* perfect or near perfect match */ || almost_match == 1) /* close enough for 2nd time */ break; else /* this is the first time they almost matched */ almost_match++; } } /* restore original values */ bflength = orig_bflength; bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; rbflength = orig_rbflength; r = orig_r; n = orig_n; return r; } /********************************************************************/ /* exp(r) */ /* uses bftmp1, bftmp2, bftmp3 - global temp bigfloats */ bf_t exp_bf(bf_t r, bf_t n) { U16 fact=1; S16 BIGDIST * testexp, BIGDIST * rexp; testexp = (S16 BIGDIST *)(bftmp2+bflength); rexp = (S16 BIGDIST *)(r+bflength); if (is_bf_zero(n)) { inttobf(r, 1); return r; } /* use Taylor Series (very slow convergence) */ inttobf(r, 1); /* start with r=1.0 */ copy_bf(bftmp2, r); for (;;) { copy_bf(bftmp1, n); unsafe_mult_bf(bftmp3, bftmp2, bftmp1); unsafe_div_bf_int(bftmp2, bftmp3, fact); if (big_accessS16(testexp) < big_accessS16(rexp)-(bflength-2)) break; /* too small to register */ unsafe_add_a_bf(r, bftmp2); fact++; } return r; } /********************************************************************/ /* ln(r) */ /* uses bftmp1 - bftmp6 - global temp bigfloats */ /* SIDE-EFFECTS: */ /* n ends up as |n| */ bf_t unsafe_ln_bf(bf_t r, bf_t n) { int i, comp, almost_match=0; LDBL f; bf_t orig_r, orig_n, orig_bftmp5; int orig_bflength, orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor, orig_rbflength; /* use Newton's recursive method for zeroing in on ln(n): r=r+n*exp(-r)-1 */ if (is_bf_neg(n) || is_bf_zero(n)) { /* error, return largest neg value */ max_bf(r); neg_a_bf(r); return r; } f = bftofloat(n); f = logl(f); /* approximate ln(x) */ /* no need to check overflow */ /* appears to be ok, do ln */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bflength = bflength; orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_rbflength = rbflength; orig_r = r; orig_n = n; orig_bftmp5 = bftmp5; /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; bftmp5 = orig_bftmp5 + orig_bflength - bflength; floattobf(r, f); /* start with approximate ln */ neg_a_bf(r); /* -r */ copy_bf(bftmp5, r); /* -r */ for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; bftmp5 = orig_bftmp5 + orig_bflength - bflength; exp_bf(bftmp6, r); /* exp(-r) */ unsafe_mult_bf(bftmp2, bftmp6, n); /* n*exp(-r) */ inttobf(bftmp4, 1); unsafe_sub_a_bf(bftmp2, bftmp4); /* n*exp(-r) - 1 */ unsafe_sub_a_bf(r, bftmp2); /* -r - (n*exp(-r) - 1) */ if (bflength == orig_bflength && (comp=abs(cmp_bf(r, bftmp5))) < 8 ) /* if match or almost match */ { if (comp < 4 /* perfect or near perfect match */ || almost_match == 1) /* close enough for 2nd time */ break; else /* this is the first time they almost matched */ almost_match++; } copy_bf(bftmp5, r); /* -r */ } /* restore original values */ bflength = orig_bflength; bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; rbflength = orig_rbflength; r = orig_r; n = orig_n; bftmp5 = orig_bftmp5; neg_a_bf(r); /* -(-r) */ return r; } /********************************************************************/ /* sincos_bf(r) */ /* uses bftmp1 - bftmp2 - global temp bigfloats */ /* SIDE-EFFECTS: */ /* n ends up as |n| mod (pi/4) */ bf_t unsafe_sincos_bf(bf_t s, bf_t c, bf_t n) { U16 fact=2; int k=0, i, halves; int signcos=0, signsin=0, switch_sincos=0; int sin_done=0, cos_done=0; S16 BIGDIST * testexp, BIGDIST * cexp, BIGDIST * sexp; testexp = (S16 BIGDIST *)(bftmp1+bflength); cexp = (S16 BIGDIST *)(c+bflength); sexp = (S16 BIGDIST *)(s+bflength); #ifndef CALCULATING_BIG_PI /* assure range 0 <= x < pi/4 */ if (is_bf_zero(n)) { clear_bf(s); /* sin(0) = 0 */ inttobf(c, 1); /* cos(0) = 1 */ return s; } if (is_bf_neg(n)) { signsin = !signsin; /* sin(-x) = -sin(x), odd; cos(-x) = cos(x), even */ neg_a_bf(n); } /* n >= 0 */ double_bf(bftmp1, bf_pi); /* 2*pi */ /* this could be done with remainders, but it would probably be slower */ while (cmp_bf(n, bftmp1) >= 0) /* while n >= 2*pi */ { copy_bf(bftmp2, bftmp1); unsafe_sub_a_bf(n, bftmp2); } /* 0 <= n < 2*pi */ copy_bf(bftmp1, bf_pi); /* pi */ if (cmp_bf(n, bftmp1) >= 0) /* if n >= pi */ { unsafe_sub_a_bf(n, bftmp1); signsin = !signsin; signcos = !signcos; } /* 0 <= n < pi */ half_bf(bftmp1, bf_pi); /* pi/2 */ if (cmp_bf(n, bftmp1) > 0) /* if n > pi/2 */ { copy_bf(bftmp2, bf_pi); unsafe_sub_bf(n, bftmp2, n); signcos = !signcos; } /* 0 <= n < pi/2 */ half_bf(bftmp1, bf_pi); /* pi/2 */ half_a_bf(bftmp1); /* pi/4 */ if (cmp_bf(n, bftmp1) > 0) /* if n > pi/4 */ { copy_bf(bftmp2, n); half_bf(bftmp1, bf_pi); /* pi/2 */ unsafe_sub_bf(n, bftmp1, bftmp2); /* pi/2 - n */ switch_sincos = !switch_sincos; } /* 0 <= n < pi/4 */ /* this looks redundant, but n could now be zero when it wasn't before */ if (is_bf_zero(n)) { clear_bf(s); /* sin(0) = 0 */ inttobf(c, 1); /* cos(0) = 1 */ return s; } /* at this point, the double angle trig identities could be used as many */ /* times as desired to reduce the range to pi/8, pi/16, etc... Each time */ /* the range is cut in half, the number of iterations required is reduced */ /* by "quite a bit." It's just a matter of testing to see what gives the */ /* optimal results. */ /* halves = bflength / 10; */ /* this is experimental */ halves = 1; for (i = 0; i < halves; i++) half_a_bf(n); #endif /* use Taylor Series (very slow convergence) */ copy_bf(s, n); /* start with s=n */ inttobf(c, 1); /* start with c=1 */ copy_bf(bftmp1, n); /* the current x^n/n! */ do { /* even terms for cosine */ copy_bf(bftmp2, bftmp1); unsafe_mult_bf(bftmp1, bftmp2, n); div_a_bf_int(bftmp1, fact++); if (!cos_done) { cos_done = (big_accessS16(testexp) < big_accessS16(cexp)-(bflength-2)); /* too small to register */ if (!cos_done) { if (k) /* alternate between adding and subtracting */ unsafe_add_a_bf(c, bftmp1); else unsafe_sub_a_bf(c, bftmp1); } } /* odd terms for sine */ copy_bf(bftmp2, bftmp1); unsafe_mult_bf(bftmp1, bftmp2, n); div_a_bf_int(bftmp1, fact++); if (!sin_done) { sin_done = (big_accessS16(testexp) < big_accessS16(sexp)-(bflength-2)); /* too small to register */ if (!sin_done) { if (k) /* alternate between adding and subtracting */ unsafe_add_a_bf(s, bftmp1); else unsafe_sub_a_bf(s, bftmp1); } } k = !k; /* toggle */ #ifdef CALCULATING_BIG_PI printf("."); /* lets you know it's doing something */ #endif } while (!cos_done || !sin_done); #ifndef CALCULATING_BIG_PI /* now need to undo what was done by cutting angles in half */ for (i = 0; i < halves; i++) { unsafe_mult_bf(bftmp2, s, c); /* no need for safe mult */ double_bf(s, bftmp2); /* sin(2x) = 2*sin(x)*cos(x) */ unsafe_square_bf(bftmp2,c); double_a_bf(bftmp2); inttobf(bftmp1, 1); unsafe_sub_bf(c, bftmp2, bftmp1); /* cos(2x) = 2*cos(x)*cos(x) - 1 */ } if (switch_sincos) { copy_bf(bftmp1, s); copy_bf(s, c); copy_bf(c, bftmp1); } if (signsin) neg_a_bf(s); if (signcos) neg_a_bf(c); #endif return s; /* return sine I guess */ } /********************************************************************/ /* atan(r) */ /* uses bftmp1 - bftmp5 - global temp bigfloats */ /* SIDE-EFFECTS: */ /* n ends up as |n| or 1/|n| */ bf_t unsafe_atan_bf(bf_t r, bf_t n) { int i, comp, almost_match=0, signflag=0; LDBL f; bf_t orig_r, orig_n, orig_bf_pi, orig_bftmp3; int orig_bflength, orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor, orig_rbflength; int large_arg; /* use Newton's recursive method for zeroing in on atan(n): r=r-cos(r)(sin(r)-n*cos(r)) */ if (is_bf_neg(n)) { signflag = 1; neg_a_bf(n); } /* If n is very large, atanl() won't give enough decimal places to be a */ /* good enough initial guess for Newton's Method. If it is larger than */ /* say, 1, atan(n) = pi/2 - acot(n) = pi/2 - atan(1/n). */ f = bftofloat(n); large_arg = f > 1.0; if (large_arg) { unsafe_inv_bf(bftmp3, n); copy_bf(n, bftmp3); f = bftofloat(n); } clear_bf(bftmp3); /* not really necessary, but makes things more consistent */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bflength = bflength; orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_rbflength = rbflength; orig_bf_pi = bf_pi; orig_r = r; orig_n = n; orig_bftmp3 = bftmp3; /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; bf_pi = orig_bf_pi + orig_bflength - bflength; bftmp3 = orig_bftmp3 + orig_bflength - bflength; f = atanl(f); /* approximate arctangent */ /* no need to check overflow */ floattobf(r, f); /* start with approximate atan */ copy_bf(bftmp3, r); for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bflength - bflength; n = orig_n + orig_bflength - bflength; bf_pi = orig_bf_pi + orig_bflength - bflength; bftmp3 = orig_bftmp3 + orig_bflength - bflength; #ifdef CALCULATING_BIG_PI printf("\natan() loop #%i, bflength=%i\nsincos() loops\n", i, bflength); #endif unsafe_sincos_bf(bftmp4, bftmp5, bftmp3); /* sin(r), cos(r) */ copy_bf(bftmp3, r); /* restore bftmp3 from sincos_bf() */ copy_bf(bftmp1, bftmp5); unsafe_mult_bf(bftmp2, n, bftmp1); /* n*cos(r) */ unsafe_sub_a_bf(bftmp4, bftmp2); /* sin(r) - n*cos(r) */ unsafe_mult_bf(bftmp1, bftmp5, bftmp4); /* cos(r) * (sin(r) - n*cos(r)) */ /* copy_bf(bftmp3, r); already done above! */ unsafe_sub_a_bf(r, bftmp1); /* r - cos(r) * (sin(r) - n*cos(r)) */ #ifdef CALCULATING_BIG_PI putchar('\n'); bf_hexdump(r); #endif if (bflength == orig_bflength && (comp=abs(cmp_bf(r, bftmp3))) < 8 ) /* if match or almost match */ { #ifdef CALCULATING_BIG_PI printf("atan() loop comp=%i\n", comp); #endif if (comp < 4 /* perfect or near perfect match */ || almost_match == 1) /* close enough for 2nd time */ break; else /* this is the first time they almost matched */ almost_match++; } #ifdef CALCULATING_BIG_PI if (bflength == orig_bflength && comp >= 8) printf("atan() loop comp=%i\n", comp); #endif /* the following gets set above and not altered before we use it! */ /* copy_bf(bftmp3, r); */ /* make a copy for later comparison */ } /* restore original values */ bflength = orig_bflength; bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; rbflength = orig_rbflength; bf_pi = orig_bf_pi; r = orig_r; n = orig_n; bftmp3 = orig_bftmp3; if (large_arg) { half_bf(bftmp3, bf_pi); /* pi/2 */ sub_a_bf(bftmp3, r); /* pi/2 - atan(1/n) */ copy_bf(r, bftmp3); } if (signflag) neg_a_bf(r); return r; } /********************************************************************/ /* atan2(r,ny,nx) */ /* uses bftmp1 - bftmp6 - global temp bigfloats */ bf_t unsafe_atan2_bf(bf_t r, bf_t ny, bf_t nx) { int signx, signy; signx = sign_bf(nx); signy = sign_bf(ny); if (signy == 0) { if (signx < 0) copy_bf(r, bf_pi); /* negative x axis, 180 deg */ else /* signx >= 0 positive x axis, 0 */ clear_bf(r); return(r); } if (signx == 0) { copy_bf(r, bf_pi); /* y axis */ half_a_bf(r); /* +90 deg */ if (signy < 0) neg_a_bf(r); /* -90 deg */ return(r); } if (signy < 0) neg_a_bf(ny); if (signx < 0) neg_a_bf(nx); unsafe_div_bf(bftmp6,ny,nx); unsafe_atan_bf(r, bftmp6); if (signx < 0) sub_bf(r,bf_pi,r); if(signy < 0) neg_a_bf(r); return(r); } /**********************************************************************/ /* The rest of the functions are "safe" versions of the routines that */ /* have side effects which alter the parameters. */ /* Most bf routines change values of parameters, not just the sign. */ /**********************************************************************/ /**********************************************************************/ bf_t add_bf(bf_t r, bf_t n1, bf_t n2) { copy_bf(bftmpcpy1, n1); copy_bf(bftmpcpy2, n2); unsafe_add_bf(r, bftmpcpy1, bftmpcpy2); return r; } /**********************************************************************/ bf_t add_a_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_add_a_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t sub_bf(bf_t r, bf_t n1, bf_t n2) { copy_bf(bftmpcpy1, n1); copy_bf(bftmpcpy2, n2); unsafe_sub_bf(r, bftmpcpy1, bftmpcpy2); return r; } /**********************************************************************/ bf_t sub_a_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_sub_a_bf(r, bftmpcpy1); return r; } /**********************************************************************/ /* mult and div only change sign */ bf_t full_mult_bf(bf_t r, bf_t n1, bf_t n2) { copy_bf(bftmpcpy1, n1); copy_bf(bftmpcpy2, n2); unsafe_full_mult_bf(r, bftmpcpy1, bftmpcpy2); return r; } /**********************************************************************/ bf_t mult_bf(bf_t r, bf_t n1, bf_t n2) { copy_bf(bftmpcpy1, n1); copy_bf(bftmpcpy2, n2); unsafe_mult_bf(r, bftmpcpy1, bftmpcpy2); return r; } /**********************************************************************/ bf_t full_square_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_full_square_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t square_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_square_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t mult_bf_int(bf_t r, bf_t n, U16 u) { copy_bf(bftmpcpy1, n); unsafe_mult_bf_int(r, bftmpcpy1, u); return r; } /**********************************************************************/ bf_t div_bf_int(bf_t r, bf_t n, U16 u) { copy_bf(bftmpcpy1, n); unsafe_div_bf_int(r, bftmpcpy1, u); return r; } /**********************************************************************/ char *bftostr(char *s, int dec, bf_t r) { copy_bf(bftmpcpy1, r); unsafe_bftostr(s, dec, bftmpcpy1); return s; } /**********************************************************************/ char *bftostr_e(char *s, int dec, bf_t r) { copy_bf(bftmpcpy1, r); unsafe_bftostr_e(s, dec, bftmpcpy1); return s; } /**********************************************************************/ char *bftostr_f(char *s, int dec, bf_t r) { copy_bf(bftmpcpy1, r); unsafe_bftostr_f(s, dec, bftmpcpy1); return s; } /**********************************************************************/ bf_t inv_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_inv_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t div_bf(bf_t r, bf_t n1, bf_t n2) { copy_bf(bftmpcpy1, n1); copy_bf(bftmpcpy2, n2); unsafe_div_bf(r, bftmpcpy1, bftmpcpy2); return r; } /**********************************************************************/ bf_t sqrt_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_sqrt_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t ln_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_ln_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t sincos_bf(bf_t s, bf_t c, bf_t n) { copy_bf(bftmpcpy1, n); return unsafe_sincos_bf(s, c, bftmpcpy1); } /**********************************************************************/ bf_t atan_bf(bf_t r, bf_t n) { copy_bf(bftmpcpy1, n); unsafe_atan_bf(r, bftmpcpy1); return r; } /**********************************************************************/ bf_t atan2_bf(bf_t r, bf_t ny, bf_t nx) { copy_bf(bftmpcpy1, ny); copy_bf(bftmpcpy2, nx); unsafe_atan2_bf(r, bftmpcpy1, bftmpcpy2); return r; } /**********************************************************************/ int is_bf_zero(bf_t n) { return !is_bf_not_zero(n); } /************************************************************************/ /* convert_bf -- convert bigfloat numbers from old to new lengths */ int convert_bf(bf_t new, bf_t old, int newbflength, int oldbflength) { int savebflength; /* save lengths so not dependent on external environment */ savebflength = bflength; bflength = newbflength; clear_bf(new); bflength = savebflength; if(newbflength > oldbflength) _fmemcpy(new+newbflength-oldbflength,old,oldbflength+2); else _fmemcpy(new,old+oldbflength-newbflength,newbflength+2); return(0); } /* The following used to be in bigfltc.c */ /********************************************************************/ /* normalize big float */ bf_t norm_bf(bf_t r) { int scale; BYTE hi_byte; S16 BIGDIST *rexp; rexp = (S16 BIGDIST *)(r+bflength); /* check for overflow */ hi_byte = r[bflength-1]; if (hi_byte != 0x00 && hi_byte != 0xFF) { _fmemmove(r, r+1, bflength-1); r[bflength-1] = (BYTE)(hi_byte & 0x80 ? 0xFF : 0x00); big_setS16(rexp,big_accessS16(rexp)+(S16)1); /* exp */ } /* check for underflow */ else { for (scale = 2; scale < bflength && r[bflength-scale] == hi_byte; scale++) ; /* do nothing */ if (scale == bflength && hi_byte == 0) /* zero */ big_setS16(rexp,0); else { scale -= 2; if (scale > 0) /* it did underflow */ { _fmemmove(r+scale, r, bflength-scale-1); _fmemset(r, 0, scale); big_setS16(rexp,big_accessS16(rexp)-(S16)scale); /* exp */ } } } return r; } /********************************************************************/ /* normalize big float with forced sign */ /* positive = 1, force to be positive */ /* = 0, force to be negative */ void norm_sign_bf(bf_t r, int positive) { norm_bf(r); r[bflength-1] = (BYTE)(positive ? 0x00 : 0xFF); } /******************************************************/ /* adjust n1, n2 for before addition or subtraction */ /* by forcing exp's to match. */ /* returns the value of the adjusted exponents */ S16 adjust_bf_add(bf_t n1, bf_t n2) { int scale, fill_byte; S16 rexp; S16 BIGDIST *n1exp, BIGDIST *n2exp; /* scale n1 or n2 */ /* compare exp's */ n1exp = (S16 BIGDIST *)(n1+bflength); n2exp = (S16 BIGDIST *)(n2+bflength); if (big_accessS16(n1exp) > big_accessS16(n2exp)) { /* scale n2 */ scale = big_accessS16(n1exp) - big_accessS16(n2exp); /* n1exp - n2exp */ if (scale < bflength) { fill_byte = is_bf_neg(n2) ? 0xFF : 0x00; _fmemmove(n2, n2+scale, bflength-scale); _fmemset(n2+bflength-scale, fill_byte, scale); } else clear_bf(n2); big_setS16(n2exp,big_accessS16(n1exp)); /* *n2exp = *n1exp; set exp's = */ rexp = big_accessS16(n2exp); } else if (big_accessS16(n1exp) < big_accessS16(n2exp)) { /* scale n1 */ scale = big_accessS16(n2exp) - big_accessS16(n1exp); /* n2exp - n1exp */ if (scale < bflength) { fill_byte = is_bf_neg(n1) ? 0xFF : 0x00; _fmemmove(n1, n1+scale, bflength-scale); _fmemset(n1+bflength-scale, fill_byte, scale); } else clear_bf(n1); big_setS16(n1exp,big_accessS16(n2exp)); /* *n1exp = *n2exp; set exp's = */ rexp = big_accessS16(n2exp); } else rexp = big_accessS16(n1exp); return rexp; } /********************************************************************/ /* r = max positive value */ bf_t max_bf(bf_t r) { inttobf(r, 1); big_set16(r+bflength, (S16)(LDBL_MAX_EXP/8)); return r; } /****************************************************************************/ /* n1 != n2 ? */ /* RETURNS: */ /* if n1 == n2 returns 0 */ /* if n1 > n2 returns a positive (bytes left to go when mismatch occurred) */ /* if n1 < n2 returns a negative (bytes left to go when mismatch occurred) */ int cmp_bf(bf_t n1, bf_t n2) { int i; int sign1, sign2; S16 BIGDIST *n1exp, BIGDIST *n2exp; U16 value1, value2; /* compare signs */ sign1 = sign_bf(n1); sign2 = sign_bf(n2); if (sign1 > sign2) return bflength; else if (sign1 < sign2) return -bflength; /* signs are the same */ /* compare exponents, using signed comparisons */ n1exp = (S16 BIGDIST *)(n1+bflength); n2exp = (S16 BIGDIST *)(n2+bflength); if (big_accessS16(n1exp) > big_accessS16(n2exp)) return sign1*(bflength); else if (big_accessS16(n1exp) < big_accessS16(n2exp)) return -sign1*(bflength); /* To get to this point, the signs must match */ /* so unsigned comparison is ok. */ /* two bytes at a time */ for (i=bflength-2; i>=0; i-=2) { if ( (value1=big_access16(n1+i)) > (value2=big_access16(n2+i)) ) { /* now determine which of the two bytes was different */ if ( (value1&0xFF00) > (value2&0xFF00) ) /* compare just high bytes */ return (i+2); /* high byte was different */ else return (i+1); /* low byte was different */ } else if (value1 < value2) { /* now determine which of the two bytes was different */ if ( (value1&0xFF00) < (value2&0xFF00) ) /* compare just high bytes */ return -(i+2); /* high byte was different */ else return -(i+1); /* low byte was different */ } } return 0; } /********************************************************************/ /* r < 0 ? */ /* returns 1 if negative, 0 if positive or zero */ int is_bf_neg(bf_t n) { return (S8)n[bflength-1] < 0; } /********************************************************************/ /* n != 0 ? */ /* RETURNS: if n != 0 returns 1 */ /* else returns 0 */ int is_bf_not_zero(bf_t n) { int bnl; int retval; bnl = bnlength; bnlength = bflength; retval = is_bn_not_zero(n); bnlength = bnl; return retval; } /********************************************************************/ /* r = n1 + n2 */ /* SIDE-EFFECTS: n1 and n2 can be "de-normalized" and lose precision */ bf_t unsafe_add_bf(bf_t r, bf_t n1, bf_t n2) { int bnl; S16 BIGDIST *rexp; if (is_bf_zero(n1)) { copy_bf(r, n2); return r; } if (is_bf_zero(n2)) { copy_bf(r, n1); return r; } rexp = (S16 BIGDIST *)(r+bflength); big_setS16(rexp,adjust_bf_add(n1, n2)); bnl = bnlength; bnlength = bflength; add_bn(r, n1, n2); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r += n */ bf_t unsafe_add_a_bf(bf_t r, bf_t n) { int bnl; if (is_bf_zero(r)) { copy_bf(r, n); return r; } if (is_bf_zero(n)) { return r; } adjust_bf_add(r, n); bnl = bnlength; bnlength = bflength; add_a_bn(r, n); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r = n1 - n2 */ /* SIDE-EFFECTS: n1 and n2 can be "de-normalized" and lose precision */ bf_t unsafe_sub_bf(bf_t r, bf_t n1, bf_t n2) { int bnl; S16 BIGDIST *rexp; if (is_bf_zero(n1)) { neg_bf(r, n2); return r; } if (is_bf_zero(n2)) { copy_bf(r, n1); return r; } rexp = (S16 BIGDIST *)(r+bflength); big_setS16(rexp,adjust_bf_add(n1, n2)); bnl = bnlength; bnlength = bflength; sub_bn(r, n1, n2); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r -= n */ bf_t unsafe_sub_a_bf(bf_t r, bf_t n) { int bnl; if (is_bf_zero(r)) { neg_bf(r,n); return r; } if (is_bf_zero(n)) { return r; } adjust_bf_add(r, n); bnl = bnlength; bnlength = bflength; sub_a_bn(r, n); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r = -n */ bf_t neg_bf(bf_t r, bf_t n) { int bnl; S16 BIGDIST *rexp, BIGDIST *nexp; rexp = (S16 BIGDIST *)(r+bflength); nexp = (S16 BIGDIST *)(n+bflength); big_setS16(rexp, big_accessS16(nexp)); /* *rexp = *nexp; */ bnl = bnlength; bnlength = bflength; neg_bn(r, n); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r *= -1 */ bf_t neg_a_bf(bf_t r) { int bnl; bnl = bnlength; bnlength = bflength; neg_a_bn(r); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r = 2*n */ bf_t double_bf(bf_t r, bf_t n) { int bnl; S16 BIGDIST *rexp, BIGDIST *nexp; rexp = (S16 BIGDIST *)(r+bflength); nexp = (S16 BIGDIST *)(n+bflength); big_setS16(rexp, big_accessS16(nexp)); /* *rexp = *nexp; */ bnl = bnlength; bnlength = bflength; double_bn(r, n); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r *= 2 */ bf_t double_a_bf(bf_t r) { int bnl; bnl = bnlength; bnlength = bflength; double_a_bn(r); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r = n/2 */ bf_t half_bf(bf_t r, bf_t n) { int bnl; S16 BIGDIST *rexp, BIGDIST *nexp; rexp = (S16 BIGDIST *)(r+bflength); nexp = (S16 BIGDIST *)(n+bflength); big_setS16(rexp, big_accessS16(nexp)); /* *rexp = *nexp; */ bnl = bnlength; bnlength = bflength; half_bn(r, n); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r /= 2 */ bf_t half_a_bf(bf_t r) { int bnl; bnl = bnlength; bnlength = bflength; half_a_bn(r); bnlength = bnl; norm_bf(r); return r; } /************************************************************************/ /* r = n1 * n2 */ /* Note: r will be a double wide result, 2*bflength */ /* n1 and n2 can be the same pointer */ /* SIDE-EFFECTS: n1 and n2 are changed to their absolute values */ bf_t unsafe_full_mult_bf(bf_t r, bf_t n1, bf_t n2) { int bnl, dbfl; S16 BIGDIST *rexp, BIGDIST *n1exp, BIGDIST *n2exp; if (is_bf_zero(n1) || is_bf_zero(n2) ) { bflength <<= 1; clear_bf(r); bflength >>= 1; return r; } dbfl = 2*bflength; /* double width bflength */ rexp = (S16 BIGDIST *)(r+dbfl); /* note: 2*bflength */ n1exp = (S16 BIGDIST *)(n1+bflength); n2exp = (S16 BIGDIST *)(n2+bflength); /* add exp's */ big_setS16(rexp, (S16)(big_accessS16(n1exp) + big_accessS16(n2exp)) ); bnl = bnlength; bnlength = bflength; unsafe_full_mult_bn(r, n1, n2); bnlength = bnl; /* handle normalizing full mult on individual basis */ return r; } /************************************************************************/ /* r = n1 * n2 calculating only the top rlength bytes */ /* Note: r will be of length rlength */ /* 2*bflength <= rlength < bflength */ /* n1 and n2 can be the same pointer */ /* SIDE-EFFECTS: n1 and n2 are changed to their absolute values */ bf_t unsafe_mult_bf(bf_t r, bf_t n1, bf_t n2) { int positive; int bnl, bfl, rl; int rexp; S16 BIGDIST *n1exp, BIGDIST *n2exp; if (is_bf_zero(n1) || is_bf_zero(n2) ) { clear_bf(r); return r; } n1exp = (S16 BIGDIST *)(n1+bflength); n2exp = (S16 BIGDIST *)(n2+bflength); /* add exp's */ rexp = big_accessS16(n1exp) + big_accessS16(n2exp); positive = is_bf_neg(n1) == is_bf_neg(n2); /* are they the same sign? */ bnl = bnlength; bnlength = bflength; rl = rlength; rlength = rbflength; unsafe_mult_bn(r, n1, n2); bnlength = bnl; rlength = rl; bfl = bflength; bflength = rbflength; big_set16(r+bflength, (S16)(rexp+2)); /* adjust after mult */ norm_sign_bf(r, positive); bflength = bfl; _fmemmove(r, r+padding, bflength+2); /* shift back */ return r; } /************************************************************************/ /* r = n^2 */ /* because of the symmetry involved, n^2 is much faster than n*n */ /* for a bignumber of length l */ /* n*n takes l^2 multiplications */ /* n^2 takes (l^2+l)/2 multiplications */ /* which is about 1/2 n*n as l gets large */ /* uses the fact that (a+b+c+...)^2 = (a^2+b^2+c^2+...)+2(ab+ac+bc+...)*/ /* */ /* SIDE-EFFECTS: n is changed to its absolute value */ bf_t unsafe_full_square_bf(bf_t r, bf_t n) { int bnl, dbfl; S16 BIGDIST *rexp, BIGDIST *nexp; if (is_bf_zero(n)) { bflength <<= 1; clear_bf(r); bflength >>= 1; return r; } dbfl = 2*bflength; /* double width bflength */ rexp = (S16 BIGDIST *)(r+dbfl); /* note: 2*bflength */ nexp = (S16 BIGDIST *)(n+bflength); big_setS16(rexp, 2 * big_accessS16(nexp)); bnl = bnlength; bnlength = bflength; unsafe_full_square_bn(r, n); bnlength = bnl; /* handle normalizing full mult on individual basis */ return r; } /************************************************************************/ /* r = n^2 */ /* because of the symmetry involved, n^2 is much faster than n*n */ /* for a bignumber of length l */ /* n*n takes l^2 multiplications */ /* n^2 takes (l^2+l)/2 multiplications */ /* which is about 1/2 n*n as l gets large */ /* uses the fact that (a+b+c+...)^2 = (a^2+b^2+c^2+...)+2(ab+ac+bc+...)*/ /* */ /* Note: r will be of length rlength */ /* 2*bflength >= rlength > bflength */ /* SIDE-EFFECTS: n is changed to its absolute value */ bf_t unsafe_square_bf(bf_t r, bf_t n) { int bnl, bfl, rl; int rexp; S16 BIGDIST *nexp; if (is_bf_zero(n)) { clear_bf(r); return r; } nexp = (S16 BIGDIST *)(n+bflength); rexp = (S16)(2 * big_accessS16(nexp)); bnl = bnlength; bnlength = bflength; rl = rlength; rlength = rbflength; unsafe_square_bn(r, n); bnlength = bnl; rlength = rl; bfl = bflength; bflength = rbflength; big_set16(r+bflength, (S16)(rexp+2)); /* adjust after mult */ norm_sign_bf(r, 1); bflength = bfl; _fmemmove(r, r+padding, bflength+2); /* shift back */ return r; } /********************************************************************/ /* r = n * u where u is an unsigned integer */ /* SIDE-EFFECTS: n can be "de-normalized" and lose precision */ bf_t unsafe_mult_bf_int(bf_t r, bf_t n, U16 u) { int positive; int bnl; S16 BIGDIST *rexp, BIGDIST *nexp; rexp = (S16 BIGDIST *)(r+bflength); nexp = (S16 BIGDIST *)(n+bflength); big_setS16(rexp, big_accessS16(nexp)); /* *rexp = *nexp; */ positive = !is_bf_neg(n); /* if u > 0x00FF, then the integer part of the mantissa will overflow the 2 byte (16 bit) integer size. Therefore, make adjustment before multiplication is performed. */ if (u > 0x00FF) { /* un-normalize n */ _fmemmove(n, n+1, bflength-1); /* this sign extends as well */ big_setS16(rexp,big_accessS16(rexp)+(S16)1); } bnl = bnlength; bnlength = bflength; mult_bn_int(r, n, u); bnlength = bnl; norm_sign_bf(r, positive); return r; } /********************************************************************/ /* r *= u where u is an unsigned integer */ bf_t mult_a_bf_int(bf_t r, U16 u) { int positive; int bnl; S16 BIGDIST *rexp; rexp = (S16 BIGDIST *)(r+bflength); positive = !is_bf_neg(r); /* if u > 0x00FF, then the integer part of the mantissa will overflow the 2 byte (16 bit) integer size. Therefore, make adjustment before multiplication is performed. */ if (u > 0x00FF) { /* un-normalize n */ _fmemmove(r, r+1, bflength-1); /* this sign extends as well */ big_setS16(rexp,big_accessS16(rexp)+(S16)1); } bnl = bnlength; bnlength = bflength; mult_a_bn_int(r, u); bnlength = bnl; norm_sign_bf(r, positive); return r; } /********************************************************************/ /* r = n / u where u is an unsigned integer */ bf_t unsafe_div_bf_int(bf_t r, bf_t n, U16 u) { int bnl; S16 BIGDIST *rexp, BIGDIST *nexp; if (u == 0) /* division by zero */ { max_bf(r); if (is_bf_neg(n)) neg_a_bf(r); return r; } rexp = (S16 BIGDIST *)(r+bflength); nexp = (S16 BIGDIST *)(n+bflength); big_setS16(rexp, big_accessS16(nexp)); /* *rexp = *nexp; */ bnl = bnlength; bnlength = bflength; unsafe_div_bn_int(r, n, u); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* r /= u where u is an unsigned integer */ bf_t div_a_bf_int(bf_t r, U16 u) { int bnl; if (u == 0) /* division by zero */ { if (is_bf_neg(r)) { max_bf(r); neg_a_bf(r); } else { max_bf(r); } return r; } bnl = bnlength; bnlength = bflength; div_a_bn_int(r, u); bnlength = bnl; norm_bf(r); return r; } /********************************************************************/ /* extracts the mantissa and exponent of f */ /* finds m and n such that 1<=|m|= 0 ? f: -f; /* abs value */ ff = af > 1 ? af : 1/af; n = 0; powertwo = 1; while (b < ff) { value[n] = b; n++; powertwo <<= 1; b *= b; } *exp_ptr = 0; for (; n > 0; n--) { powertwo >>= 1; if (value[n-1] < ff) { ff /= value[n-1]; *exp_ptr += powertwo; } } if (f < 0) ff = -ff; if (af < 1) { ff = orig_b/ff; *exp_ptr = -*exp_ptr - 1; } return ff; } /********************************************************************/ /* calculates and returns the value of f*b^n */ /* sort of like ldexp() */ LDBL scale_value( LDBL f, LDBL b , int n ) { LDBL total=1; int an; if (b == 0 || f == 0) return 0; if (n == 0) return f; an = abs(n); while (an != 0) { if (an & 0x0001) total *= b; b *= b; an >>= 1; } if (n > 0) f *= total; else /* n < 0 */ f /= total; return f; } /********************************************************************/ /* extracts the mantissa and exponent of f */ /* finds m and n such that 1<=|m|<10 and f = m*10^n */ /* n is stored in *exp_ptr and m is returned, sort of like frexp() */ LDBL extract_10(LDBL f, int *exp_ptr) { return extract_value(f, 10, exp_ptr); } /********************************************************************/ /* calculates and returns the value of f*10^n */ /* sort of like ldexp() */ LDBL scale_10( LDBL f, int n ) { return scale_value( f, 10, n ); } /* big10flt.c - C routines for base 10 big floating point numbers */ /********************************************************** (Just when you thought it was safe to go back in the water.) Just when you thought you seen every type of format possible, 16 bit integer, 32 bit integer, double, long double, mpmath, bn_t, bf_t, I now give you bf10_t (big float base 10)! Why, because this is the only way (I can think of) to properly do a bftostr() without rounding errors. With out this, then -1.9999999999( > LDBL_DIG of 9's)9999999123456789... will round to -2.0. The good news is that we only need to do two mathematical operations: multiplication and division by integers bf10_t format: (notice the position of the MSB and LSB) MSB LSB _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ n <><------------- dec --------------><> <-> 1 byte pad 1 byte rounding 2 byte exponent. total length = dec + 4 ***********************************************************/ /**********************************************************************/ /* unsafe_bftobf10() - converts a bigfloat into a bigfloat10 */ /* n - pointer to a bigfloat */ /* r - result array of BYTE big enough to hold the bf10_t number */ /* dec - number of decimals, not including the one extra for rounding */ /* SIDE-EFFECTS: n is changed to |n|. Make copy of n if necessary. */ bf10_t unsafe_bftobf10(bf10_t r, int dec, bf_t n) { int d; int power256; int p; int bnl; bf_t onesbyte; bf10_t power10; if (is_bf_zero(n)) { /* in scientific notation, the leading digit can't be zero */ r[1] = (BYTE)0; /* unless the number is zero */ return r; } onesbyte = n + bflength - 1; /* really it's n+bflength-2 */ power256 = (S16)big_access16(n + bflength) + 1; /* so adjust power256 by 1 */ if (dec == 0) dec = decimals; dec++; /* one extra byte for rounding */ power10 = r + dec + 1; if (is_bf_neg(n)) { neg_a_bf(n); r[0] = 1; /* sign flag */ } else r[0] = 0; p = -1; /* multiply by 10 right away */ bnl = bnlength; bnlength = bflength; for (d=1; d<=dec; d++) { /* pretend it's a bn_t instead of a bf_t */ /* this leaves n un-normalized, which is what we want here */ mult_a_bn_int(n, 10); r[d] = *onesbyte; if (d == 1 && r[d] == 0) { d = 0; /* back up a digit */ p--; /* and decrease by a factor of 10 */ } *onesbyte = 0; } bnlength = bnl; big_set16(power10, (U16)p); /* save power of ten */ /* the digits are all read in, now scale it by 256^power256 */ if (power256 > 0) for (d=0; dpower256; d--) div_a_bf10_int(r, dec, 256); /* else power256 is zero, don't do anything */ /* round the last digit */ if (r[dec] >= 5) { d = dec-1; while (d > 0) /* stop before you get to the sign flag */ { r[d]++; /* round up */ if (r[d] < 10) { d = -1; /* flag for below */ break; /* finished rounding */ } r[d] = 0; d--; } if (d == 0) /* rounding went back to the first digit and it overflowed */ { r[1] = 0; _fmemmove(r+2, r+1, dec-1); r[1] = 1; p = (S16)big_access16(power10); big_set16(power10, (U16)(p+1)); } } r[dec] = 0; /* truncate the rounded digit */ return r; } /**********************************************************************/ /* mult_a_bf10_int() */ /* r *= n */ /* dec - number of decimals, including the one extra for rounding */ bf10_t mult_a_bf10_int(bf10_t r, int dec, U16 n) { int signflag; int d, p; unsigned value, overflow; bf10_t power10; if (r[1] == 0 || n == 0) { r[1] = 0; return r; } power10 = r + dec + 1; p = (S16)big_access16(power10); signflag = r[0]; /* r[0] to be used as a padding */ overflow = 0; for (d = dec; d>0; d--) { value = r[d] * n + overflow; r[d] = (BYTE)(value % 10); overflow = value / 10; } while (overflow) { p++; _fmemmove(r+2, r+1, dec-1); r[1] = (BYTE)(overflow % 10); overflow = overflow / 10; } big_set16(power10, (U16)p); /* save power of ten */ r[0] = (BYTE)signflag; /* restore sign flag */ return r; } /**********************************************************************/ /* div_a_bf10_int() */ /* r /= n */ /* dec - number of decimals, including the one extra for rounding */ bf10_t div_a_bf10_int (bf10_t r, int dec, U16 n) { int src, dest, p; unsigned value, remainder; bf10_t power10; if (r[1] == 0 || n == 0) { r[1] = 0; return r; } power10 = r + dec + 1; p = (S16)big_access16(power10); remainder = 0; for (src=dest=1; src<=dec; dest++, src++) { value = 10*remainder + r[src]; r[dest] = (BYTE)(value / n); remainder = value % n; if (dest == 1 && r[dest] == 0) { dest = 0; /* back up a digit */ p--; /* and decrease by a factor of 10 */ } } for (; dest<=dec; dest++) { value = 10*remainder; r[dest] = (BYTE)(value / n); remainder = value % n; if (dest == 1 && r[dest] == 0) { dest = 0; /* back up a digit */ p--; /* and decrease by a factor of 10 */ } } big_set16(power10, (U16)p); /* save power of ten */ return r; } /*************************************************************************/ /* bf10tostr_e() */ /* Takes a bf10 number and converts it to an ascii string, sci. notation */ /* dec - number of decimals, not including the one extra for rounding */ char *bf10tostr_e(char *s, int dec, bf10_t n) { int d, p; bf10_t power10; if (n[1] == 0) { strcpy(s, "0.0"); return s; } if (dec == 0) dec = decimals; dec++; /* one extra byte for rounding */ power10 = n + dec + 1; p = (S16)big_access16(power10); /* if p is negative, it is not necessary to show all the decimal places */ if (p < 0 && dec > 8) /* 8 sounds like a reasonable value */ { dec = dec + p; if (dec < 8) /* let's keep at least a few */ dec = 8; } if (n[0] == 1) /* sign flag */ *(s++) = '-'; *(s++) = (char)(n[1] + '0'); *(s++) = '.'; for (d=2; d<=dec; d++) { *(s++) = (char)(n[d] + '0'); } /* clean up trailing 0's */ while (*(s-1) == '0') s--; if (*(s-1) == '.') /* put at least one 0 after the decimal */ *(s++) = '0'; sprintf(s, "e%d", p); return s; } /****************************************************************************/ /* bf10tostr_f() */ /* Takes a bf10 number and converts it to an ascii string, decimal notation */ char *bf10tostr_f(char *s, int dec, bf10_t n) { int d, p; bf10_t power10; if (n[1] == 0) { strcpy(s, "0.0"); return s; } if (dec == 0) dec = decimals; dec++; /* one extra byte for rounding */ power10 = n + dec + 1; p = (S16)big_access16(power10); /* if p is negative, it is not necessary to show all the decimal places */ if (p < 0 && dec > 8) /* 8 sounds like a reasonable value */ { dec = dec + p; if (dec < 8) /* let's keep at least a few */ dec = 8; } if (n[0] == 1) /* sign flag */ *(s++) = '-'; if (p >= 0) { for (d=1; d<=p+1; d++) *(s++) = (char)(n[d] + '0'); *(s++) = '.'; for (; d<=dec; d++) *(s++) = (char)(n[d] + '0'); } else { *(s++) = '0'; *(s++) = '.'; for (d=0; d>p+1; d--) *(s++) = '0'; for (d=1; d<=dec; d++) *(s++) = (char)(n[d] + '0'); } /* clean up trailing 0's */ while (*(s-1) == '0') s--; if (*(s-1) == '.') /* put at least one 0 after the decimal */ *(s++) = '0'; *s = '\0'; /* terminating nul */ return s; } xfractint-20.4.10.orig/common/plot3d.c0000644000000000000000000003420110150633601014341 0ustar /* This file includes miscellaneous plot functions and logic for 3D, used by lorenz.c and line3d.c By Tim Wegner and Marc Reinig. */ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /* Use these palette indices for red/blue - same on ega/vga */ #define PAL_BLUE 1 #define PAL_RED 2 #define PAL_MAGENTA 3 int whichimage; int xxadjust1; int yyadjust1; int eyeseparation = 0; int glassestype = 0; int xshift1; int yshift1; int xtrans = 0; int ytrans = 0; int red_local_left; int red_local_right; int blue_local_left; int blue_local_right; int red_crop_left = 4; int red_crop_right = 0; int blue_crop_left = 0; int blue_crop_right = 4; int red_bright = 80; int blue_bright = 100; BYTE T_RED; /* Bresenham's algorithm for drawing line */ void cdecl draw_line (int X1, int Y1, int X2, int Y2, int color) { /* uses Bresenham algorithm to draw a line */ int dX, dY; /* vector components */ int row, col, final, /* final row or column number */ G, /* used to test for new row or column */ inc1, /* G increment when row or column doesn't change */ inc2; /* G increment when row or column changes */ char pos_slope; dX = X2 - X1; /* find vector components */ dY = Y2 - Y1; pos_slope = (char)(dX > 0); /* is slope positive? */ if (dY < 0) pos_slope = (char)!pos_slope; if (abs (dX) > abs (dY)) /* shallow line case */ { if (dX > 0) /* determine start point and last column */ { col = X1; row = Y1; final = X2; } else { col = X2; row = Y2; final = X1; } inc1 = 2 * abs (dY); /* determine increments and initial G */ G = inc1 - abs (dX); inc2 = 2 * (abs (dY) - abs (dX)); if (pos_slope) while (col <= final) /* step through columns checking for new row */ { (*plot) (col, row, color); col++; if (G >= 0) /* it's time to change rows */ { row++; /* positive slope so increment through the rows */ G += inc2; } else /* stay at the same row */ G += inc1; } else while (col <= final) /* step through columns checking for new row */ { (*plot) (col, row, color); col++; if (G > 0) /* it's time to change rows */ { row--; /* negative slope so decrement through the rows */ G += inc2; } else /* stay at the same row */ G += inc1; } } /* if |dX| > |dY| */ else /* steep line case */ { if (dY > 0) /* determine start point and last row */ { col = X1; row = Y1; final = Y2; } else { col = X2; row = Y2; final = Y1; } inc1 = 2 * abs (dX); /* determine increments and initial G */ G = inc1 - abs (dY); inc2 = 2 * (abs (dX) - abs (dY)); if (pos_slope) while (row <= final) /* step through rows checking for new column */ { (*plot) (col, row, color); row++; if (G >= 0) /* it's time to change columns */ { col++; /* positive slope so increment through the columns */ G += inc2; } else /* stay at the same column */ G += inc1; } else while (row <= final) /* step through rows checking for new column */ { (*plot) (col, row, color); row++; if (G > 0) /* it's time to change columns */ { col--; /* negative slope so decrement through the columns */ G += inc2; } else /* stay at the same column */ G += inc1; } } } /* draw_line */ #if 0 /* use this for continuous colors later */ void _fastcall plot3dsuperimpose16b(int x,int y,int color) { int tmp; if (color != 0) /* Keeps index 0 still 0 */ { color = colors - color; /* Reverses color order */ color = color / 4; if(color == 0) color = 1; } color = 3; tmp = getcolor(x,y); /* map to 4 colors */ if(whichimage == 1) /* RED */ { if(red_local_left < x && x < red_local_right) { putcolor(x,y,color|tmp); if (Targa_Out) targa_color(x, y, color|tmp); } } else if(whichimage == 2) /* BLUE */ if(blue_local_left < x && x < blue_local_right) { color = color <<2; putcolor(x,y,color|tmp); if (Targa_Out) targa_color(x, y, color|tmp); } } #endif void _fastcall plot3dsuperimpose16(int x,int y,int color) { int tmp; tmp = getcolor(x,y); if(whichimage == 1) /* RED */ { color = PAL_RED; if(tmp > 0 && tmp != color) color = PAL_MAGENTA; if(red_local_left < x && x < red_local_right) { putcolor(x,y,color); if (Targa_Out) targa_color(x, y, color); } } else if(whichimage == 2) /* BLUE */ if(blue_local_left < x && x < blue_local_right) { color = PAL_BLUE; if(tmp > 0 && tmp != color) color = PAL_MAGENTA; putcolor(x,y,color); if (Targa_Out) targa_color(x, y, color); } } void _fastcall plot3dsuperimpose256(int x,int y,int color) { int tmp; BYTE t_c; t_c = (BYTE)(255-color); if (color != 0) /* Keeps index 0 still 0 */ { color = colors - color; /* Reverses color order */ if (max_colors == 236) color = 1 + color / 21; /* Maps colors 1-255 to 13 even ranges */ else color = 1 + color / 18; /* Maps colors 1-255 to 15 even ranges */ } tmp = getcolor(x,y); /* map to 16 colors */ if(whichimage == 1) /* RED */ { if(red_local_left < x && x < red_local_right) { /* Overwrite prev Red don't mess w/blue */ putcolor(x,y,color|(tmp&240)); if (Targa_Out) { if (!ILLUMINE) targa_color(x, y, color|(tmp&240)); else targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0); } } } else if(whichimage == 2) /* BLUE */ if(blue_local_left < x && x < blue_local_right) { /* Overwrite previous blue, don't mess with existing red */ color = color <<4; putcolor(x,y,color|(tmp&15)); if (Targa_Out) { if (!ILLUMINE) targa_color(x, y, color|(tmp&15)); else { targa_readdisk (x+sxoffs, y+syoffs, &T_RED, (BYTE *)&tmp, (BYTE *)&tmp); targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c); } } } } void _fastcall plotIFS3dsuperimpose256(int x,int y,int color) { int tmp; BYTE t_c; t_c = (BYTE)(255-color); if (color != 0) /* Keeps index 0 still 0 */ { /* my mind is fried - lower indices = darker colors is EASIER! */ color = colors - color; /* Reverses color order */ if (max_colors == 236) color = 1 + color / 21; /* Maps colors 1-255 to 13 even ranges */ else color = 1 + color / 18; /* Looks weird but maps colors 1-255 to 15 relatively even ranges */ } tmp = getcolor(x,y); /* map to 16 colors */ if(whichimage == 1) /* RED */ { if(red_local_left < x && x < red_local_right) { putcolor(x,y,color|tmp); if (Targa_Out) { if (!ILLUMINE) targa_color(x, y, color|tmp); else targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0); } } } else if(whichimage == 2) /* BLUE */ if(blue_local_left < x && x < blue_local_right) { color = color <<4; putcolor(x,y,color|tmp); if (Targa_Out) { if (!ILLUMINE) targa_color(x, y, color|tmp); else { targa_readdisk (x+sxoffs, y+syoffs, &T_RED, (BYTE *)&tmp, (BYTE *)&tmp); targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c); } } } } void _fastcall plot3dalternate(int x,int y,int color) { BYTE t_c; t_c = (BYTE)(255-color); /* lorez high color red/blue 3D plot function */ /* if which image = 1, compresses color to lower 128 colors */ /* my mind is STILL fried - lower indices = darker colors is EASIER! */ color = colors - color; if((whichimage == 1) && !((x+y)&1)) /* - lower half palette */ { if(red_local_left < x && x < red_local_right) { putcolor(x,y,color>>1); if (Targa_Out) { if (!ILLUMINE) targa_color(x, y, color>>1); else targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0); } } } else if((whichimage == 2) && ((x+y)&1) ) /* - upper half palette */ { if(blue_local_left < x && x < blue_local_right) { putcolor(x,y,(color>>1)+(colors>>1)); if (Targa_Out) { if (!ILLUMINE) targa_color(x, y, (color>>1)+(colors>>1)); else targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c); } } } } void _fastcall plot3dcrosseyedA(int x,int y,int color) { x /= 2; y /= 2; if(whichimage == 2) x += xdots/2; if(rowcount >= ydots/2) /* hidden surface kludge */ if(getcolor(x,y) != 0) return; putcolor(x,y,color); } void _fastcall plot3dcrosseyedB(int x,int y,int color) { x /= 2; y /= 2; if(whichimage == 2) x += xdots/2; putcolor(x,y,color); } void _fastcall plot3dcrosseyedC(int x,int y,int color) { if(rowcount >= ydots/2) /* hidden surface kludge */ if(getcolor(x,y) != 0) return; putcolor(x,y,color); } void plot_setup() { double d_red_bright = 0; double d_blue_bright = 0; int i; /* set funny glasses plot function */ switch(glassestype) { case 1: standardplot = plot3dalternate; break; case 2: if(colors == 256) if (fractype != IFS3D) standardplot = plot3dsuperimpose256; else standardplot = plotIFS3dsuperimpose256; else standardplot = plot3dsuperimpose16; break; case 4: /* crosseyed mode */ if(sxdots < 2*xdots) { if(XROT == 0 && YROT == 0) standardplot = plot3dcrosseyedA; /* use hidden surface kludge */ else standardplot = plot3dcrosseyedB; } else if(XROT == 0 && YROT == 0) standardplot = plot3dcrosseyedC; /* use hidden surface kludge */ else standardplot = putcolor; break; default: standardplot = putcolor; break; } xshift1 = xshift = (int)((XSHIFT * (double)xdots)/100); yshift1 = yshift = (int)((YSHIFT * (double)ydots)/100); if(glassestype) { red_local_left = (int)((red_crop_left * (double)xdots)/100.0); red_local_right = (int)(((100 - red_crop_right) * (double)xdots)/100.0); blue_local_left = (int)((blue_crop_left * (double)xdots)/100.0); blue_local_right = (int)(((100 - blue_crop_right) * (double)xdots)/100.0); d_red_bright = (double)red_bright/100.0; d_blue_bright = (double)blue_bright/100.0; switch(whichimage) { case 1: xshift += (int)((eyeseparation* (double)xdots)/200); xxadjust = (int)(((xtrans+xadjust)* (double)xdots)/100); xshift1 -= (int)((eyeseparation* (double)xdots)/200); xxadjust1 = (int)(((xtrans-xadjust)* (double)xdots)/100); if(glassestype == 4 && sxdots >= 2*xdots) sxoffs = sxdots / 2 - xdots; break; case 2: xshift -= (int)((eyeseparation* (double)xdots)/200); xxadjust = (int)(((xtrans-xadjust)* (double)xdots)/100); if(glassestype == 4 && sxdots >= 2*xdots) sxoffs = sxdots / 2; break; } } else xxadjust = (int)((xtrans* (double)xdots)/100); yyadjust = (int)(-(ytrans* (double)ydots)/100); if (mapset) { ValidateLuts(MAP_name); /* read the palette file */ if(glassestype==1 || glassestype==2) { if(glassestype == 2 && colors < 256) { dacbox[PAL_RED ][0] = 63; dacbox[PAL_RED ][1] = 0; dacbox[PAL_RED ][2] = 0; dacbox[PAL_BLUE ][0] = 0; dacbox[PAL_BLUE ][1] = 0; dacbox[PAL_BLUE ][2] = 63; dacbox[PAL_MAGENTA][0] = 63; dacbox[PAL_MAGENTA][1] = 0; dacbox[PAL_MAGENTA][2] = 63; } for (i=0;i<256;i++) { dacbox[i][0] = (BYTE)(dacbox[i][0] * d_red_bright); dacbox[i][2] = (BYTE)(dacbox[i][2] * d_blue_bright); } } spindac(0,1); /* load it, but don't spin */ } } xfractint-20.4.10.orig/common/calcfrac.c0000644000000000000000000042072211451656645014723 0ustar /* CALCFRAC.C contains the high level ("engine") code for calculating the fractal images (well, SOMEBODY had to do it!). Original author Tim Wegner, but just about ALL the authors have contributed SOME code to this routine at one time or another, or contributed to one of the many massive restructurings. The following modules work very closely with CALCFRAC.C: FRACTALS.C the fractal-specific code for escape-time fractals. FRACSUBR.C assorted subroutines belonging mainly to calcfrac. CALCMAND.ASM fast Mandelbrot/Julia integer implementation Additional fractal-specific modules are also invoked from CALCFRAC: LORENZ.C engine level and fractal specific code for attractors. JB.C julibrot logic PARSER.C formula fractals and more -------------------------------------------------------------------- */ #include #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "targa_lc.h" /* routines in this module */ static void perform_worklist(void); static int OneOrTwoPass(void); static int _fastcall StandardCalc(int); static int _fastcall potential(double,long); static void decomposition(void); static int bound_trace_main(void); static void step_col_row(void); static int solidguess(void); static int _fastcall guessrow(int,int,int); static void _fastcall plotblock(int,int,int,int); static void _fastcall setsymmetry(int,int); static int _fastcall xsym_split(int,int); static int _fastcall ysym_split(int,int); static void _fastcall puttruecolor_disk(int,int,int); static int diffusion_engine (void); static int sticky_orbits(void); /**CJLT new function prototypes: */ static int tesseral(void); static int _fastcall tesschkcol(int,int,int); static int _fastcall tesschkrow(int,int,int); static int _fastcall tesscol(int,int,int); static int _fastcall tessrow(int,int,int); /* new drawing method by HB */ static int diffusion_scan(void); /* lookup tables to avoid too much bit fiddling : */ char far dif_la[] = { 0, 8, 0, 8,4,12,4,12,0, 8, 0, 8,4,12,4,12, 2,10, 2,10,6,14,6,14,2,10, 2,10, 6,14,6,14,0, 8,0, 8, 4,12,4,12,0, 8, 0, 8, 4,12,4,12,2,10,2,10, 6,14, 6,14,2,10,2,10,6,14, 6,14,1, 9,1, 9, 5,13, 5,13,1, 9,1, 9,5,13, 5,13, 3,11,3,11,7,15,7,15, 3,11,3,11,7,15, 7,15, 1, 9,1, 9,5,13,5,13, 1, 9, 1, 9,5,13,5,13,3,11, 3,11,7,15,7,15, 3,11, 3,11,7,15,7,15,0, 8, 0, 8, 4,12,4,12,0, 8,0, 8, 4,12,4,12,2,10, 2,10, 6,14,6,14,2,10,2,10, 6,14, 6,14,0, 8,0, 8,4,12, 4,12,0, 8,0, 8, 4,12, 4,12,2,10,2,10,6,14, 6,14, 2,10,2,10,6,14,6,14, 1, 9,1, 9,5,13, 5,13, 1, 9,1, 9,5,13,5,13, 3,11, 3,11,7,15,7,15,3,11, 3,11,7,15,7,15, 1, 9, 1, 9,5,13,5,13,1, 9, 1, 9, 5,13,5,13,3,11,3,11, 7,15,7,15,3,11, 3,11, 7,15,7,15 }; char far dif_lb[] = { 0, 8, 8, 0, 4,12,12, 4, 4,12,12, 4, 8, 0, 0, 8, 2,10,10, 2, 6,14,14, 6, 6,14,14, 6,10, 2, 2,10, 2,10,10, 2, 6,14,14, 6, 6,14,14, 6,10, 2, 2,10, 4,12,12, 4, 8, 0, 0, 8, 8, 0, 0, 8,12, 4, 4,12, 1, 9, 9, 1, 5, 13,13, 5, 5,13,13, 5, 9, 1, 1, 9, 3,11,11, 3, 7,15,15, 7, 7,15,15, 7, 11, 3, 3,11, 3,11,11, 3, 7,15,15, 7, 7,15,15, 7,11, 3, 3,11, 5,13,13, 5, 9, 1, 1, 9, 9, 1, 1, 9,13, 5, 5,13, 1, 9, 9, 1, 5,13,13, 5, 5,13, 13, 5, 9, 1, 1, 9, 3,11,11, 3, 7,15,15, 7, 7,15,15, 7,11, 3, 3,11, 3, 11,11, 3, 7,15,15, 7, 7,15,15, 7,11, 3, 3,11, 5,13,13, 5, 9, 1, 1, 9, 9, 1, 1, 9,13, 5, 5,13, 2,10,10, 2, 6,14,14, 6, 6,14,14, 6,10, 2, 2, 10, 4,12,12, 4, 8, 0, 0, 8, 8, 0, 0, 8,12, 4, 4,12, 4,12,12, 4, 8, 0, 0, 8, 8, 0, 0, 8,12, 4, 4,12, 6,14,14, 6,10, 2, 2,10,10, 2, 2,10,14, 6, 6,14 }; /* added for testing autologmap() */ static long autologmap(void); _LCMPLX linitorbit; long lmagnitud, llimit, llimit2, lclosenuff, l16triglim; _CMPLX init,tmp,old,new,saved; int color; long coloriter, oldcoloriter, realcoloriter; int row, col, passes; int iterations, invert; double f_radius,f_xcenter, f_ycenter; /* for inversion */ void (_fastcall *putcolor)(int,int,int) = putcolor_a; void (_fastcall *plot)(int,int,int) = putcolor_a; typedef void (_fastcall *PLOTC)(int,int,int); typedef void (_fastcall *GETC)(int,int,int); double magnitude, rqlim, rqlim2, rqlim_save; int no_mag_calc = 0; int use_old_period = 0; int use_old_distest = 0; int old_demm_colors = 0; int (*calctype)(void); int (*calctypetmp)(void); int quick_calc = 0; double closeprox = 0.01; double closenuff; int pixelpi; /* value of pi in pixels */ unsigned long lm; /* magnitude limit (CALCMAND) */ /* ORBIT variables */ int show_orbit; /* flag to turn on and off */ int orbit_ptr; /* pointer into save_orbit array */ int far *save_orbit; /* array to save orbit values */ int orbit_color=15; /* XOR color */ int ixstart, ixstop, iystart, iystop; /* start, stop here */ int symmetry; /* symmetry flag */ int reset_periodicity; /* nonzero if escape time pixel rtn to reset */ int kbdcount, max_kbdcount; /* avoids checking keyboard too often */ U16 resume_info = 0; /* handle to resume info if allocated */ int resuming; /* nonzero if resuming after interrupt */ int num_worklist; /* resume worklist for standard engine */ WORKLIST worklist[MAXCALCWORK]; int xxstart,xxstop,xxbegin; /* these are same as worklist, */ int yystart,yystop,yybegin; /* declared as separate items */ int workpass,worksym; /* for the sake of calcmand */ VOIDFARPTR typespecific_workarea = NULL; static double dem_delta, dem_width; /* distance estimator variables */ static double dem_toobig; static int dem_mandel; #define DEM_BAILOUT 535.5 /* (pb: not sure if this is special or arbitrary) */ /* variables which must be visible for tab_display */ int got_status; /* -1 if not, 0 for 1or2pass, 1 for ssg, */ /* 2 for btm, 3 for 3d, 4 for tesseral, 5 for diffusion_scan */ /* 6 for orbits */ int curpass,totpasses; int currow,curcol; /* static vars for diffusion scan */ unsigned bits=0; /* number of bits in the counter */ unsigned long dif_counter; /* the diffusion counter */ unsigned long dif_limit; /* the diffusion counter */ /* static vars for solidguess & its subroutines */ char three_pass; static int maxblock,halfblock; static int guessplot; /* paint 1st pass row at a time? */ static int right_guess,bottom_guess; #define maxyblk 7 /* maxxblk*maxyblk*2 <= 4096, the size of "prefix" */ #define maxxblk 202 /* each maxnblk is oversize by 2 for a "border" */ /* maxxblk defn must match fracsubr.c */ /* next has a skip bit for each maxblock unit; 1st pass sets bit [1]... off only if block's contents guessed; at end of 1st pass [0]... bits are set if any surrounding block not guessed; bits are numbered [..][y/16+1][x+1]&(1<<(y&15)) */ /* Original array */ /* extern unsigned int prefix[2][maxyblk][maxxblk]; */ typedef int (*TPREFIX)[2][maxyblk][maxxblk]; #define tprefix (*((TPREFIX)prefix)) /* size of next puts a limit of MAXPIXELS pixels across on solid guessing logic */ #ifdef XFRACT BYTE dstack[4096]; /* common temp, two put_line calls */ unsigned int prefix[2][maxyblk][maxxblk]; /* common temp */ #endif int nxtscreenflag; /* for cellular next screen generation */ int attractors; /* number of finite attractors */ _CMPLX attr[N_ATTR]; /* finite attractor vals (f.p) */ _LCMPLX lattr[N_ATTR]; /* finite attractor vals (int) */ int attrperiod[N_ATTR]; /* period of the finite attractor */ /***** vars for new btm *****/ enum direction {North,East,South,West}; enum direction going_to; int trail_row, trail_col; #ifndef sqr #define sqr(x) ((x)*(x)) #endif #ifndef lsqr #define lsqr(x) (multiply((x),(x),bitshift)) #endif /* -------------------------------------------------------------------- */ /* These variables are external for speed's sake only */ /* -------------------------------------------------------------------- */ int periodicitycheck; /* For periodicity testing, only in StandardFractal() */ int nextsavedincr; long firstsavedand; static BYTE *savedots = NULL; static BYTE *fillbuff; static int savedotslen; static int showdotcolor; int atan_colors = 180; static int showdot_width = 0; #define SAVE 1 #define RESTORE 2 #define JUST_A_POINT 0 #define LOWER_RIGHT 1 #define UPPER_RIGHT 2 #define LOWER_LEFT 3 #define UPPER_LEFT 4 /* FMODTEST routine. */ /* Makes the test condition for the FMOD coloring type that of the current bailout method. 'or' and 'and' methods are not used - in these cases a normal modulus test is used */ double fmodtest(void) { double result; if (inside==FMODI && save_release <= 2000) /* for backwards compatibility */ { if (magnitude == 0.0 || no_mag_calc == 0 || integerfractal) result=sqr(new.x)+sqr(new.y); else result=magnitude; /* don't recalculate */ return (result); } switch(bailoutest) { case (Mod): { if (magnitude == 0.0 || no_mag_calc == 0 || integerfractal) result=sqr(new.x)+sqr(new.y); else result=magnitude; /* don't recalculate */ }break; case (Real): { result=sqr(new.x); }break; case (Imag): { result=sqr(new.y); }break; case (Or): { double tmpx, tmpy; if ((tmpx = sqr(new.x)) > (tmpy = sqr(new.y))) result=tmpx; else result=tmpy; }break; case (Manh): { result=sqr(fabs(new.x)+fabs(new.y)); }break; case (Manr): { result=sqr(new.x+new.y); }break; default: { result=sqr(new.x)+sqr(new.y); }break; } return (result); } /* The sym_fill_line() routine was pulled out of the boundary tracing code for re-use with showdot. It's purpose is to fill a line with a solid color. This assumes that BYTE *str is already filled with the color. The routine does write the line using symmetry in all cases, however the symmetry logic assumes that the line is one color; it is not general enough to handle a row of pixels of different colors. */ static void sym_fill_line(int row, int left, int right, BYTE *str) { int i,j,k, length; length = right-left+1; put_line(row,left,right,str); /* here's where all the symmetry goes */ if (plot == putcolor) kbdcount -= length >> 4; /* seems like a reasonable value */ else if (plot == symplot2) /* X-axis symmetry */ { i = yystop-(row-yystart); if (i > iystop && i < ydots) { put_line(i,left,right,str); kbdcount -= length >> 3; } } else if (plot == symplot2Y) /* Y-axis symmetry */ { put_line(row,xxstop-(right-xxstart),xxstop-(left-xxstart),str); kbdcount -= length >> 3; } else if (plot == symplot2J) /* Origin symmetry */ { i = yystop-(row-yystart); j = min(xxstop-(right-xxstart),xdots-1); k = min(xxstop-(left -xxstart),xdots-1); if (i > iystop && i < ydots && j <= k) put_line(i,j,k,str); kbdcount -= length >> 3; } else if (plot == symplot4) /* X-axis and Y-axis symmetry */ { i = yystop-(row-yystart); j = min(xxstop-(right-xxstart),xdots-1); k = min(xxstop-(left -xxstart),xdots-1); if (i > iystop && i < ydots) { put_line(i,left,right,str); if(j <= k) put_line(i,j,k,str); } if(j <= k) put_line(row,j,k,str); kbdcount -= length >> 2; } else /* cheap and easy way out */ { for (i = left; i <= right; i++) /* DG */ (*plot)(i,row,str[i-left]); kbdcount -= length >> 1; } } /* The sym_put_line() routine is the symmetry-aware version of put_line(). It only works efficiently in the no symmetry or XAXIS symmetry case, otherwise it just writes the pixels one-by-one. */ static void sym_put_line(int row, int left, int right, BYTE *str) { int length,i; length = right-left+1; put_line(row,left,right,str); if (plot == putcolor) kbdcount -= length >> 4; /* seems like a reasonable value */ else if (plot == symplot2) /* X-axis symmetry */ { i = yystop-(row-yystart); if (i > iystop && i < ydots) put_line(i,left,right,str); kbdcount -= length >> 3; } else { for (i = left; i <= right; i++) /* DG */ (*plot)(i,row,str[i-left]); kbdcount -= length >> 1; } } void showdotsaverestore(int startx, int stopx, int starty, int stopy, int direction, int action) { int j,ct; ct = 0; if(direction != JUST_A_POINT) { if(savedots == NULL) { stopmsg(0,"savedots NULL"); exit(0); } if(fillbuff == NULL) { stopmsg(0,"fillbuff NULL"); exit(0); } } switch(direction) { case LOWER_RIGHT: for(j=starty; j<=stopy; startx++,j++) { if(action==SAVE) { get_line(j,startx,stopx,savedots+ct); sym_fill_line(j,startx,stopx,fillbuff); } else sym_put_line(j,startx,stopx,savedots+ct); ct += stopx-startx+1; } break; case UPPER_RIGHT: for(j=starty; j>=stopy; startx++,j--) { if(action==SAVE) { get_line(j,startx,stopx,savedots+ct); sym_fill_line(j,startx,stopx,fillbuff); } else sym_put_line(j,startx,stopx,savedots+ct); ct += stopx-startx+1; } break; case LOWER_LEFT: for(j=starty; j<=stopy; stopx--,j++) { if(action==SAVE) { get_line(j,startx,stopx,savedots+ct); sym_fill_line(j,startx,stopx,fillbuff); } else sym_put_line(j,startx,stopx,savedots+ct); ct += stopx-startx+1; } break; case UPPER_LEFT: for(j=starty; j>=stopy; stopx--,j--) { if(action==SAVE) { get_line(j,startx,stopx,savedots+ct); sym_fill_line(j,startx,stopx,fillbuff); } else sym_put_line(j,startx,stopx,savedots+ct); ct += stopx-startx+1; } break; } if(action == SAVE) (*plot) (col,row, showdotcolor); } int calctypeshowdot(void) { int out, startx, starty, stopx, stopy, direction, width; direction = JUST_A_POINT; startx = stopx = col; starty = stopy = row; width = showdot_width+1; if(width > 0) { if(col+width <= ixstop && row+width <= iystop) { /* preferred showdot shape */ direction = UPPER_LEFT; startx = col; stopx = col+width; starty = row+width; stopy = row+1; } else if(col-width >= ixstart && row+width <= iystop) { /* second choice */ direction = UPPER_RIGHT; startx = col-width; stopx = col; starty = row+width; stopy = row+1; } else if(col-width >= ixstart && row-width >= iystart) { direction = LOWER_RIGHT; startx = col-width; stopx = col; starty = row-width; stopy = row-1; } else if(col+width <= ixstop && row-width >= iystart) { direction = LOWER_LEFT; startx = col; stopx = col+width; starty = row-width; stopy = row-1; } } showdotsaverestore(startx, stopx, starty, stopy, direction, SAVE); if(orbit_delay > 0) sleepms(orbit_delay); out = (*calctypetmp)(); showdotsaverestore(startx, stopx, starty, stopy, direction, RESTORE); return(out); } /* use top of extraseg for LogTable if room */ int logtable_in_extra_ok(void) { if(((2L*(long)(xdots+ydots)*sizeof(double)+MaxLTSize+1) < (1L<<16)) && (bf_math==0) && (fractype != FORMULA) && (fractype != FFORMULA)) return(1); else return(0); } /******* calcfract - the top level routine for generating an image *******/ #if (_MSC_VER >= 700) #pragma code_seg ("calcfra1_text") /* place following in an overlay */ #endif int calcfract(void) { matherr_ct = 0; attractors = 0; /* default to no known finite attractors */ display3d = 0; basin = 0; /* added yet another level of indirection to putcolor!!! TW */ putcolor = putcolor_a; if (istruecolor && truemode) /* Have to force passes=1 */ usr_stdcalcmode = stdcalcmode = '1'; if(truecolor) { check_writefile(light_name, ".tga"); if(startdisk1(light_name,NULL,0)==0) { /* Have to force passes=1 */ usr_stdcalcmode = stdcalcmode = '1'; putcolor = puttruecolor_disk; } else truecolor = 0; } if(!use_grid || (xdots > OLDMAXPIXELS || ydots > OLDMAXPIXELS)) { if (usr_stdcalcmode != 'o') usr_stdcalcmode = stdcalcmode = '1'; } init_misc(); /* set up some variables in parser.c */ reset_clock(); /* following delta values useful only for types with rotation disabled */ /* currently used only by bifurcation */ if (integerfractal) distest = 0; parm.x = param[0]; parm.y = param[1]; parm2.x = param[2]; parm2.y = param[3]; if (LogFlag && colors < 16) { static FCODE msg[]={"Need at least 16 colors to use logmap"}; stopmsg(0,msg); LogFlag = 0; } if (use_old_period == 1) { nextsavedincr = 1; firstsavedand = 1; } else { nextsavedincr = (int)log10(maxit); /* works better than log() */ if(nextsavedincr < 4) nextsavedincr = 4; /* maintains image with low iterations */ firstsavedand = (long)((nextsavedincr*2) + 1); } LogTable = NULL; MaxLTSize = maxit; Log_Calc = 0; /* below, INT_MAX=32767 only when an integer is two bytes. Which is not true for Xfractint. */ /* Since 32767 is what was meant, replaced the instances of INT_MAX with 32767. */ if(LogFlag && (((maxit > 32767) && (save_release > 1920)) || Log_Fly_Calc == 1)) { Log_Calc = 1; /* calculate on the fly */ SetupLogTable(); } else if(LogFlag && (((maxit > 32767) && (save_release <= 1920)) || Log_Fly_Calc == 2)) { MaxLTSize = 32767; Log_Calc = 0; /* use logtable */ } else if(rangeslen && (maxit >= 32767)) { MaxLTSize = 32766; } if ((LogFlag || rangeslen) && !Log_Calc) { if(logtable_in_extra_ok()) LogTable = (BYTE far *)(dx0 + 2*(xdots+ydots)); else LogTable = (BYTE far *)farmemalloc((long)MaxLTSize + 1); if(LogTable == NULL) { if (rangeslen || Log_Fly_Calc == 2) { static FCODE msg[]={"Insufficient memory for logmap/ranges with this maxiter"}; stopmsg(0,msg); } else { static FCODE msg[]={"Insufficient memory for logTable, using on-the-fly routine"}; stopmsg(0,msg); Log_Fly_Calc = 1; Log_Calc = 1; /* calculate on the fly */ SetupLogTable(); } } else if (rangeslen) { /* Can't do ranges if MaxLTSize > 32767 */ int i,k,l,m,numval,flip,altern; i = k = l = 0; LogFlag = 0; /* ranges overrides logmap */ while (i < rangeslen) { m = flip = 0; altern = 32767; if ((numval = ranges[i++]) < 0) { altern = ranges[i++]; /* sub-range iterations */ numval = ranges[i++]; } if (numval > (int)MaxLTSize || i >= rangeslen) numval = (int)MaxLTSize; while (l <= numval) { LogTable[l++] = (BYTE)(k + flip); if (++m >= altern) { flip ^= 1; /* Alternate colors */ m = 0; } } ++k; if (altern != 32767) ++k; } } else SetupLogTable(); } lm = 4L << bitshift; /* CALCMAND magnitude limit */ if (save_release > 2002) atan_colors = colors; else atan_colors = 180; /* ORBIT stuff */ save_orbit = (int far *)((double huge *)dx0 + 4*OLDMAXPIXELS); show_orbit = start_showorbit; orbit_ptr = 0; orbit_color = 15; if(colors < 16) orbit_color = 1; if(inversion[0] != 0.0) { f_radius = inversion[0]; f_xcenter = inversion[1]; f_ycenter = inversion[2]; if (inversion[0] == AUTOINVERT) /* auto calc radius 1/6 screen */ { inversion[0] = min(fabs(xxmax - xxmin), fabs(yymax - yymin)) / 6.0; fix_inversion(&inversion[0]); f_radius = inversion[0]; } if (invert < 2 || inversion[1] == AUTOINVERT) /* xcenter not already set */ { inversion[1] = (xxmin + xxmax) / 2.0; fix_inversion(&inversion[1]); f_xcenter = inversion[1]; if (fabs(f_xcenter) < fabs(xxmax-xxmin) / 100) inversion[1] = f_xcenter = 0.0; } if (invert < 3 || inversion[2] == AUTOINVERT) /* ycenter not already set */ { inversion[2] = (yymin + yymax) / 2.0; fix_inversion(&inversion[2]); f_ycenter = inversion[2]; if (fabs(f_ycenter) < fabs(yymax-yymin) / 100) inversion[2] = f_ycenter = 0.0; } invert = 3; /* so values will not be changed if we come back */ } closenuff = ddelmin*pow(2.0,-(double)(abs(periodicitycheck))); rqlim_save = rqlim; rqlim2 = sqrt(rqlim); if (integerfractal) /* for integer routines (lambda) */ { lparm.x = (long)(parm.x * fudge); /* real portion of Lambda */ lparm.y = (long)(parm.y * fudge); /* imaginary portion of Lambda */ lparm2.x = (long)(parm2.x * fudge); /* real portion of Lambda2 */ lparm2.y = (long)(parm2.y * fudge); /* imaginary portion of Lambda2 */ llimit = (long)(rqlim * fudge); /* stop if magnitude exceeds this */ if (llimit <= 0) llimit = 0x7fffffffL; /* klooge for integer math */ llimit2 = (long)(rqlim2 * fudge); /* stop if magnitude exceeds this */ lclosenuff = (long)(closenuff * fudge); /* "close enough" value */ l16triglim = 8L<<16; /* domain limit of fast trig functions */ linitorbit.x = (long)(initorbit.x * fudge); linitorbit.y = (long)(initorbit.y * fudge); } resuming = (calc_status == 2); if (!resuming) /* free resume_info memory if any is hanging around */ { end_resume(); if (resave_flag) { updatesavename(savename); /* do the pending increment */ resave_flag = started_resaves = 0; } calctime = 0; } if (curfractalspecific->calctype != StandardFractal && curfractalspecific->calctype != calcmand && curfractalspecific->calctype != calcmandfp && curfractalspecific->calctype != lyapunov && curfractalspecific->calctype != calcfroth) { calctype = curfractalspecific->calctype; /* per_image can override */ symmetry = curfractalspecific->symmetry; /* calctype & symmetry */ plot = putcolor; /* defaults when setsymmetry not called or does nothing */ iystart = ixstart = yystart = xxstart = yybegin = xxbegin = 0; iystop = yystop = ydots -1; ixstop = xxstop = xdots -1; calc_status = 1; /* mark as in-progress */ distest = 0; /* only standard escape time engine supports distest */ /* per_image routine is run here */ if (curfractalspecific->per_image()) { /* not a stand-alone */ /* next two lines in case periodicity changed */ closenuff = ddelmin*pow(2.0,-(double)(abs(periodicitycheck))); lclosenuff = (long)(closenuff * fudge); /* "close enough" value */ setsymmetry(symmetry,0); timer(0,calctype); /* non-standard fractal engine */ } if (check_key()) { if (calc_status == 1) /* calctype didn't set this itself, */ calc_status = 3; /* so mark it interrupted, non-resumable */ } else calc_status = 4; /* no key, so assume it completed */ } else /* standard escape-time engine */ { if(stdcalcmode == '3') /* convoluted 'g' + '2' hybrid */ { int oldcalcmode; oldcalcmode = stdcalcmode; if(!resuming || three_pass) { stdcalcmode = 'g'; three_pass = 1; timer(0,(int(*)())perform_worklist); if(calc_status == 4) { if(xdots >= 640) /* '2' is silly after 'g' for low rez */ stdcalcmode = '2'; else stdcalcmode = '1'; timer(0,(int(*)())perform_worklist); three_pass = 0; } } else /* resuming '2' pass */ { if(xdots >= 640) stdcalcmode = '2'; else stdcalcmode = '1'; timer(0,(int(*)())perform_worklist); } stdcalcmode = (char)oldcalcmode; } else /* main case, much nicer! */ { three_pass = 0; timer(0,(int(*)())perform_worklist); } } calctime += timer_interval; if(LogTable && !Log_Calc) { if(!logtable_in_extra_ok()) farmemfree(LogTable); /* free if not using extraseg */ LogTable = NULL; } if(typespecific_workarea) { free_workarea(); } if (curfractalspecific->calctype == calcfroth) froth_cleanup(); if((soundflag&7)>1) /* close sound write file */ close_snd(); if(truecolor) enddisk(); return((calc_status == 4) ? 0 : -1); } /* locate alternate math record */ int find_alternate_math(int type, int math) { int i,ret,curtype /* ,curmath=0 */; /* unsigned umath; */ ret = -1; if(math==0) return(ret); i= -1; #if 0 /* for now at least, the only alternatemath is bignum and bigflt math */ umath = math; umath <<= 14; /* BF_MATH or DL_MATH */ /* this depends on last two bits of flags */ if(fractalspecific[type].flags & umath) { while(((curtype=alternatemath[++i].type ) != type || (curmath=alternatemath[i].math) != math) && curtype != -1); if(curtype == type && curmath == math) ret = i; } #else while ((curtype=alternatemath[++i].type) != type && curtype != -1) ; if(curtype == type && alternatemath[i].math) ret = i; #endif return(ret); } /**************** general escape-time engine routines *********************/ static void perform_worklist() { int (*sv_orbitcalc)(void) = NULL; /* function that calculates one orbit */ int (*sv_per_pixel)(void) = NULL; /* once-per-pixel init */ int (*sv_per_image)(void) = NULL; /* once-per-image setup */ int i, alt; if((alt=find_alternate_math(fractype,bf_math)) > -1) { sv_orbitcalc = curfractalspecific->orbitcalc; sv_per_pixel = curfractalspecific->per_pixel; sv_per_image = curfractalspecific->per_image; curfractalspecific->orbitcalc = alternatemath[alt].orbitcalc; curfractalspecific->per_pixel = alternatemath[alt].per_pixel; curfractalspecific->per_image = alternatemath[alt].per_image; } else bf_math = 0; if (potflag && pot16bit) { int tmpcalcmode = stdcalcmode; stdcalcmode = '1'; /* force 1 pass */ if (resuming == 0) if (pot_startdisk() < 0) { pot16bit = 0; /* startdisk failed or cancelled */ stdcalcmode = (char)tmpcalcmode; /* maybe we can carry on??? */ } } if (stdcalcmode == 'b' && (curfractalspecific->flags & NOTRACE)) stdcalcmode = '1'; if (stdcalcmode == 'g' && (curfractalspecific->flags & NOGUESS)) stdcalcmode = '1'; if (stdcalcmode == 'o' && (curfractalspecific->calctype != StandardFractal)) stdcalcmode = '1'; /* default setup a new worklist */ num_worklist = 1; worklist[0].xxstart = worklist[0].xxbegin = 0; worklist[0].yystart = worklist[0].yybegin = 0; worklist[0].xxstop = xdots - 1; worklist[0].yystop = ydots - 1; worklist[0].pass = worklist[0].sym = 0; if (resuming) /* restore worklist, if we can't the above will stay in place */ { int vsn; vsn = start_resume(); get_resume(sizeof(num_worklist),&num_worklist,sizeof(worklist),worklist,0); end_resume(); if (vsn < 2) xxbegin = 0; } if (distest) /* setup stuff for distance estimator */ { double ftemp,ftemp2,delxx,delyy2,delyy,delxx2,dxsize,dysize; double aspect; if(pseudox && pseudoy) { aspect = (double)pseudoy/(double)pseudox; dxsize = pseudox-1; dysize = pseudoy-1; } else { aspect = (double)ydots/(double)xdots; dxsize = xdots-1; dysize = ydots-1; } delxx = (xxmax - xx3rd) / dxsize; /* calculate stepsizes */ delyy = (yymax - yy3rd) / dysize; delxx2 = (xx3rd - xxmin) / dysize; delyy2 = (yy3rd - yymin) / dxsize; if (save_release < 1827) /* in case it's changed with */ use_old_distest = 1; else use_old_distest = 0; rqlim = rqlim_save; /* just in case changed to DEM_BAILOUT earlier */ if (distest != 1 || colors == 2) /* not doing regular outside colors */ if (rqlim < DEM_BAILOUT) /* so go straight for dem bailout */ rqlim = DEM_BAILOUT; if (curfractalspecific->tojulia != NOFRACTAL || use_old_distest || fractype == FORMULA || fractype == FFORMULA) dem_mandel = 1; /* must be mandel type, formula, or old PAR/GIF */ else dem_mandel = 0; dem_delta = sqr(delxx) + sqr(delyy2); if ((ftemp = sqr(delyy) + sqr(delxx2)) > dem_delta) dem_delta = ftemp; if (distestwidth == 0) distestwidth = 1; ftemp = distestwidth; if (distestwidth > 0) dem_delta *= sqr(ftemp)/10000; /* multiply by thickness desired */ else dem_delta *= 1/(sqr(ftemp)*10000); /* multiply by thickness desired */ dem_width = ( sqrt( sqr(xxmax-xxmin) + sqr(xx3rd-xxmin) ) * aspect + sqrt( sqr(yymax-yymin) + sqr(yy3rd-yymin) ) ) / distest; ftemp = (rqlim < DEM_BAILOUT) ? DEM_BAILOUT : rqlim; ftemp += 3; /* bailout plus just a bit */ ftemp2 = log(ftemp); if(use_old_distest) dem_toobig = sqr(ftemp) * sqr(ftemp2) * 4 / dem_delta; else dem_toobig = fabs(ftemp) * fabs(ftemp2) * 2 / sqrt(dem_delta); } while (num_worklist > 0) { /* per_image can override */ calctype = curfractalspecific->calctype; symmetry = curfractalspecific->symmetry; /* calctype & symmetry */ plot = putcolor; /* defaults when setsymmetry not called or does nothing */ /* pull top entry off worklist */ ixstart = xxstart = worklist[0].xxstart; ixstop = xxstop = worklist[0].xxstop; xxbegin = worklist[0].xxbegin; iystart = yystart = worklist[0].yystart; iystop = yystop = worklist[0].yystop; yybegin = worklist[0].yybegin; workpass = worklist[0].pass; worksym = worklist[0].sym; --num_worklist; for (i=0; iper_image(); if(showdot >= 0) { find_special_colors(); switch(autoshowdot) { case 'd': showdotcolor = color_dark%colors; break; case 'm': showdotcolor = color_medium%colors; break; case 'b': case 'a': showdotcolor = color_bright%colors; break; default: showdotcolor = showdot%colors; break; } if(sizedot <= 0) showdot_width = -1; else { double dshowdot_width; dshowdot_width = (double)sizedot*xdots/1024.0; /* Arbitrary sanity limit, however showdot_width will overflow if dshowdot width gets near 256. */ if(dshowdot_width > 150.0) showdot_width = 150; else if(dshowdot_width > 0.0) showdot_width = (int)dshowdot_width; else showdot_width = -1; } #ifdef SAVEDOTS_USES_MALLOC while(showdot_width >= 0) { /* We're using near memory, so get the amount down to something reasonable. The polynomial used to calculate savedotslen is exactly right for the triangular-shaped shotdot cursor. The that cursor is changed, this formula must match. */ while((savedotslen=sqr(showdot_width)+5*showdot_width+4) > 1000) showdot_width--; if((savedots = (BYTE *)malloc(savedotslen)) != NULL) { savedotslen /= 2; fillbuff = savedots + savedotslen; memset(fillbuff,showdotcolor,savedotslen); break; } /* There's even less free memory than we thought, so reduce showdot_width still more */ showdot_width--; } if(savedots == NULL) showdot_width = -1; #else while((savedotslen=sqr(showdot_width)+5*showdot_width+4) > 2048) showdot_width--; savedots = (BYTE *)decoderline; savedotslen /= 2; fillbuff = savedots + savedotslen; memset(fillbuff,showdotcolor,savedotslen); #endif calctypetmp = calctype; calctype = calctypeshowdot; } /* some common initialization for escape-time pixel level routines */ closenuff = ddelmin*pow(2.0,-(double)(abs(periodicitycheck))); lclosenuff = (long)(closenuff * fudge); /* "close enough" value */ kbdcount=max_kbdcount; setsymmetry(symmetry,1); if (!(resuming)&&(labs(LogFlag) ==2 || (LogFlag && Log_Auto_Calc))) { /* calculate round screen edges to work out best start for logmap */ LogFlag = ( autologmap() * (LogFlag / labs(LogFlag))); SetupLogTable(); } /* call the appropriate escape-time engine */ switch (stdcalcmode) { case 's': if(debugflag==3444) soi_ldbl(); else soi(); break; case 't': tesseral(); break; case 'b': bound_trace_main(); break; case 'g': solidguess(); break; case 'd': diffusion_scan(); break; case 'o': sticky_orbits(); break; default: OneOrTwoPass(); } #ifdef SAVEDOTS_USES_MALLOC if(savedots != NULL) { free(savedots); savedots = NULL; fillbuff = NULL; } #endif if (check_key()) /* interrupted? */ break; } if (num_worklist > 0) { /* interrupted, resumable */ alloc_resume(sizeof(worklist)+20,2); put_resume(sizeof(num_worklist),&num_worklist,sizeof(worklist),worklist,0); } else calc_status = 4; /* completed */ if(sv_orbitcalc != NULL) { curfractalspecific->orbitcalc = sv_orbitcalc; curfractalspecific->per_pixel = sv_per_pixel; curfractalspecific->per_image = sv_per_image; } } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif static int diffusion_scan(void) { double log2; log2 = (double) log (2.0); got_status = 5; /* note: the max size of 2048x2048 gives us a 22 bit counter that will */ /* fit any 32 bit architecture, the maxinum limit for this case would */ /* be 65536x65536 (HB) */ bits = (unsigned) (min ( log (iystop-iystart+1), log(ixstop-ixstart+1) )/log2 ); bits <<= 1; /* double for two axes */ dif_limit = 1l << bits; if (diffusion_engine() == -1) { add_worklist(xxstart,xxstop,xxstart,yystart,yystop, (int)(dif_counter >> 16), /* high, */ (int)(dif_counter & 0xffff), /* low order words */ worksym); return(-1); } return(0); } /* little macro that plots a filled square of color c, size s with top left cornet at (x,y) with optimization from sym_fill_line */ #define plot_block(x,y,s,c) \ memset(dstack,(c),(s)); \ for(ty=(y); ty<(y)+(s); ty++) \ sym_fill_line(ty, (x), (x)+(s)-1, dstack) /* macro that does the same as above, but checks the limits in x and y */ #define plot_block_lim(x,y,s,c) \ memset(dstack,(c),(s)); \ for(ty=(y); ty>=8; \ x <<=4; x+=dif_la[tC&0xFF]; y <<=4; y+=dif_lb[tC&0xFF]; tC>>=8; \ x <<=4; x+=dif_la[tC&0xFF]; y <<=4; y+=dif_lb[tC&0xFF]; tC>>=8; \ x >>= dif_offset; y >>= dif_offset /* end of inlined function */ /* REMOVED: counter byte 3 */ \ /* (x) <<=4; (x)+=dif_la[tC&0(x)FF]; (y) <<=4; (y)+=dif_lb[tC&0(x)FF]; tC>>=8; --> eliminated this and made (*) because fractint user coordinates up to 2048(x)2048 what means a counter of 24 bits or 3 bytes */ /* Calculate the point */ #define calculate \ reset_periodicity = 1; \ if ((*calctype)() == -1) \ return(-1); \ reset_periodicity = 0 static int diffusion_engine (void) { double log2 = (double) log (2.0); int i,j; int nx,ny; /* number of tyles to build in x and y dirs */ /* made this to complete the area that is not */ /* a square with sides like 2 ** n */ int rem_x,rem_y; /* what is left on the last tile to draw */ int ty; /* temp for y */ long unsigned tC; /* temp for dif_counter */ int dif_offset; /* offset for adjusting looked-up values */ int sqsz; /* size of the block being filled */ int colo, rowo; /* original col and row */ int s = 1 << (bits/2); /* size of the square */ nx = (int) floor( (ixstop-ixstart+1)/s ); ny = (int) floor( (iystop-iystart+1)/s ); rem_x = (ixstop-ixstart+1) - nx * s; rem_y = (iystop-iystart+1) - ny * s; if (yybegin == iystart && workpass == 0) { /* if restarting on pan: */ dif_counter =0l; } else { /* yybegin and passes contain data for resuming the type: */ dif_counter = (((long) ((unsigned)yybegin))<<16) | ((unsigned)workpass); } dif_offset = 12-(bits/2); /* offset to adjust coordinates */ /* (*) for 4 bytes use 16 for 3 use 12 etc. */ /*************************************/ /* only the points (dithering only) :*/ if ( fillcolor==0 ){ while (dif_counter < (dif_limit>>1)) { count_to_int(dif_counter, colo, rowo); i=0; col = ixstart + colo; /* get the right tiles */ do { j=0; row = iystart + rowo ; do { calculate; (*plot)(col,row,color); j++; row += s; /* next tile */ } while (j < ny); /* in the last y tile we may not need to plot the point */ if (rowo < rem_y) { calculate; (*plot)(col,row,color); } i++; col += s; } while (i < nx); /* in the last x tiles we may not need to plot the point */ if (colo < rem_x) { row = iystart + rowo; j=0; do { calculate; (*plot)(col,row,color); j++; row += s; /* next tile */ } while (j < ny); if (rowo < rem_y) { calculate; (*plot)(col,row,color); } } dif_counter++; } } else { /*********************************/ /* with progressive filling : */ while (dif_counter < (dif_limit>>1)) { sqsz=1<<( (int)(bits-(int)( log(dif_counter+0.5)/log2 )-1)/2 ); count_to_int(dif_counter, colo, rowo); i=0; do { j=0; do { col = ixstart + colo + i * s; /* get the right tiles */ row = iystart + rowo + j * s; calculate; plot_block(col,row,sqsz,color); j++; } while (j < ny); /* in the last tile we may not need to plot the point */ if (rowo < rem_y) { row = iystart + rowo + ny * s; calculate; plot_block_lim(col,row,sqsz,color); } i++; } while (i < nx); /* in the last tile we may not need to plot the point */ if (colo < rem_x) { col = ixstart + colo + nx * s; j=0; do { row = iystart + rowo + j * s; /* get the right tiles */ calculate; plot_block_lim(col,row,sqsz,color); j++; } while (j < ny); if (rowo < rem_y) { row = iystart + rowo + ny * s; calculate; plot_block_lim(col,row,sqsz,color); } } dif_counter++; } } /* from half dif_limit on we only plot 1x1 points :-) */ while (dif_counter < dif_limit) { count_to_int(dif_counter, colo, rowo); i=0; do { j=0; do { col = ixstart + colo + i * s; /* get the right tiles */ row = iystart + rowo + j * s; calculate; (*plot)(col,row,color); j++; } while (j < ny); /* in the last tile we may not need to plot the point */ if (rowo < rem_y) { row = iystart + rowo + ny * s; calculate; (*plot)(col,row,color); } i++; } while (i < nx); /* in the last tile we may nnt need to plot the point */ if (colo < rem_x) { col = ixstart + colo + nx * s; j=0; do { row = iystart + rowo + j * s; /* get the right tiles */ calculate; (*plot)(col,row,color); j++; } while (j < ny); if (rowo < rem_y) { row = iystart + rowo + ny * s; calculate; (*plot)(col,row,color); } } dif_counter++; } return(0); } /* OLD function (less eficient than the lookup code above: static void count_to_int (long unsigned C, int *r, int *l) { int i; *r = *l = 0; for (i = bits; i>0; i -= 2){ *r <<=1; *r += C % 2; C >>= 1; *l <<=1; *l += C % 2; C >>= 1; } *l = (*l+*r)%(1<<(bits/2)); * a+b mod 2^k * } */ char drawmode = 'r'; static int sticky_orbits(void) { got_status = 6; /* for screen */ totpasses = 1; if (plotorbits2dsetup() == -1) { stdcalcmode = 'g'; return(-1); } switch (drawmode) { case 'r': default: /* draw a rectangle */ row = yybegin; col = xxbegin; while (row <= iystop) { currow = row; while (col <= ixstop) { if (plotorbits2dfloat() == -1) { add_worklist(xxstart,xxstop,col,yystart,yystop,row,0,worksym); return(-1); /* interrupted */ } ++col; } col = ixstart; ++row; } break; case 'l': { int dX, dY; /* vector components */ int final, /* final row or column number */ G, /* used to test for new row or column */ inc1, /* G increment when row or column doesn't change */ inc2; /* G increment when row or column changes */ char pos_slope; dX = ixstop - ixstart; /* find vector components */ dY = iystop - iystart; pos_slope = (char)(dX > 0); /* is slope positive? */ if (dY < 0) pos_slope = (char)!pos_slope; if (abs (dX) > abs (dY)) /* shallow line case */ { if (dX > 0) /* determine start point and last column */ { col = xxbegin; row = yybegin; final = ixstop; } else { col = ixstop; row = iystop; final = xxbegin; } inc1 = 2 * abs (dY); /* determine increments and initial G */ G = inc1 - abs (dX); inc2 = 2 * (abs (dY) - abs (dX)); if (pos_slope) while (col <= final) /* step through columns checking for new row */ { if (plotorbits2dfloat() == -1) { add_worklist(xxstart,xxstop,col,yystart,yystop,row,0,worksym); return(-1); /* interrupted */ } col++; if (G >= 0) /* it's time to change rows */ { row++; /* positive slope so increment through the rows */ G += inc2; } else /* stay at the same row */ G += inc1; } else while (col <= final) /* step through columns checking for new row */ { if (plotorbits2dfloat() == -1) { add_worklist(xxstart,xxstop,col,yystart,yystop,row,0,worksym); return(-1); /* interrupted */ } col++; if (G > 0) /* it's time to change rows */ { row--; /* negative slope so decrement through the rows */ G += inc2; } else /* stay at the same row */ G += inc1; } } /* if |dX| > |dY| */ else /* steep line case */ { if (dY > 0) /* determine start point and last row */ { col = xxbegin; row = yybegin; final = iystop; } else { col = ixstop; row = iystop; final = yybegin; } inc1 = 2 * abs (dX); /* determine increments and initial G */ G = inc1 - abs (dY); inc2 = 2 * (abs (dX) - abs (dY)); if (pos_slope) while (row <= final) /* step through rows checking for new column */ { if (plotorbits2dfloat() == -1) { add_worklist(xxstart,xxstop,col,yystart,yystop,row,0,worksym); return(-1); /* interrupted */ } row++; if (G >= 0) /* it's time to change columns */ { col++; /* positive slope so increment through the columns */ G += inc2; } else /* stay at the same column */ G += inc1; } else while (row <= final) /* step through rows checking for new column */ { if (plotorbits2dfloat() == -1) { add_worklist(xxstart,xxstop,col,yystart,yystop,row,0,worksym); return(-1); /* interrupted */ } row++; if (G > 0) /* it's time to change columns */ { col--; /* negative slope so decrement through the columns */ G += inc2; } else /* stay at the same column */ G += inc1; } } } /* end case 'l' */ break; case 'f': /* this code does not yet work??? */ { double Xctr,Yctr; LDBL Magnification; /* LDBL not really needed here, but used to match function parameters */ double Xmagfactor,Rotation,Skew; int angle; double factor = PI / 180.0; double theta; double xfactor = xdots / 2.0; double yfactor = ydots / 2.0; angle = xxbegin; /* save angle in x parameter */ cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); if (Rotation <= 0) Rotation += 360; while (angle < Rotation) { theta = (double)angle * factor; col = (int)(xfactor + (Xctr + Xmagfactor * cos(theta))); row = (int)(yfactor + (Yctr + Xmagfactor * sin(theta))); if (plotorbits2dfloat() == -1) { add_worklist(angle,0,0,0,0,0,0,worksym); return(-1); /* interrupted */ } angle++; } } /* end case 'f' */ break; } /* end switch */ return(0); } static int OneOrTwoPass(void) { int i; totpasses = 1; if (stdcalcmode == '2') totpasses = 2; if (stdcalcmode == '2' && workpass == 0) /* do 1st pass of two */ { if (StandardCalc(1) == -1) { add_worklist(xxstart,xxstop,col,yystart,yystop,row,0,worksym); return(-1); } if (num_worklist > 0) /* worklist not empty, defer 2nd pass */ { add_worklist(xxstart,xxstop,xxstart,yystart,yystop,yystart,1,worksym); return(0); } workpass = 1; xxbegin = xxstart; yybegin = yystart; } /* second or only pass */ if (StandardCalc(2) == -1) { i = yystop; if (iystop != yystop) /* must be due to symmetry */ i -= row - iystart; add_worklist(xxstart,xxstop,col,row,i,row,workpass,worksym); return(-1); } return(0); } static int _fastcall StandardCalc(int passnum) { got_status = 0; curpass = passnum; row = yybegin; col = xxbegin; while (row <= iystop) { currow = row; reset_periodicity = 1; while (col <= ixstop) { /* on 2nd pass of two, skip even pts */ if (quick_calc && !resuming) if ((color = getcolor(col,row)) != inside) { ++col; continue; } if (passnum == 1 || stdcalcmode == '1' || (row&1) != 0 || (col&1) != 0) { if ((*calctype)() == -1) /* StandardFractal(), calcmand() or calcmandfp() */ return(-1); /* interrupted */ resuming = 0; /* reset so quick_calc works */ reset_periodicity = 0; if (passnum == 1) /* first pass, copy pixel and bump col */ { if ((row&1) == 0 && row < iystop) { (*plot)(col,row+1,color); if ((col&1) == 0 && col < ixstop) (*plot)(col+1,row+1,color); } if ((col&1) == 0 && col < ixstop) (*plot)(++col,row,color); } } ++col; } col = ixstart; if (passnum == 1 && (row&1) == 0) ++row; ++row; } return(0); } int calcmand(void) /* fast per pixel 1/2/b/g, called with row & col set */ { /* setup values from far array to avoid using es reg in calcmand.asm */ linitx = lxpixel(); linity = lypixel(); if (calcmandasm() >= 0) { if ((LogTable || Log_Calc) /* map color, but not if maxit & adjusted for inside,etc */ && (realcoloriter < maxit || (inside < 0 && coloriter == maxit))) coloriter = logtablecalc(coloriter); color = abs((int)coloriter); if (coloriter >= colors) { /* don't use color 0 unless from inside/outside */ if (save_release <= 1950) { if (colors < 16) color &= andcolor; else color = ((color - 1) % andcolor) + 1; /* skip color zero */ } else { if (colors < 16) color = (int)(coloriter & andcolor); else color = (int)(((coloriter - 1) % andcolor) + 1); } } if(debugflag != 470) if(color <= 0 && stdcalcmode == 'b' ) /* fix BTM bug */ color = 1; (*plot) (col, row, color); } else color = (int)coloriter; return (color); } long (*calcmandfpasm)(void); /************************************************************************/ /* added by Wes Loewer - sort of a floating point version of calcmand() */ /* can also handle invert, any rqlim, potflag, zmag, epsilon cross, */ /* and all the current outside options -Wes Loewer 11/03/91 */ /************************************************************************/ int calcmandfp(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); init.y = dypixel(); } if (calcmandfpasm() >= 0) { if (potflag) coloriter = potential(magnitude, realcoloriter); if ((LogTable || Log_Calc) /* map color, but not if maxit & adjusted for inside,etc */ && (realcoloriter < maxit || (inside < 0 && coloriter == maxit))) coloriter = logtablecalc(coloriter); color = abs((int)coloriter); if (coloriter >= colors) { /* don't use color 0 unless from inside/outside */ if (save_release <= 1950) { if (colors < 16) color &= andcolor; else color = ((color - 1) % andcolor) + 1; /* skip color zero */ } else { if (colors < 16) color = (int)(coloriter & andcolor); else color = (int)(((coloriter - 1) % andcolor) + 1); } } if(debugflag != 470) if(color == 0 && stdcalcmode == 'b' ) /* fix BTM bug */ color = 1; (*plot) (col, row, color); } else color = (int)coloriter; return (color); } #define STARTRAILMAX FLT_MAX /* just a convenient large number */ #define green 2 #define yellow 6 #if 0 #define NUMSAVED 40 /* define this to save periodicity analysis to file */ #endif #if 0 #define MINSAVEDAND 3 /* if not defined, old method used */ #endif int StandardFractal(void) /* per pixel 1/2/b/g, called with row & col set */ { #ifdef NUMSAVED _CMPLX savedz[NUMSAVED]; long caught[NUMSAVED]; long changed[NUMSAVED]; int zctr = 0; #endif long savemaxit; double tantable[16]; int hooper = 0; long lcloseprox; double memvalue = 0.0; double min_orbit = 100000.0; /* orbit value closest to origin */ long min_index = 0; /* iteration of min_orbit */ long cyclelen = -1; long savedcoloriter = 0; int caught_a_cycle; long savedand; int savedincr; /* for periodicity checking */ _LCMPLX lsaved; int i, attracted; _LCMPLX lat; _CMPLX at; _CMPLX deriv; long dem_color = -1; _CMPLX dem_new; int check_freq; double totaldist = 0.0; _CMPLX lastz; lcloseprox = (long)(closeprox*fudge); savemaxit = maxit; #ifdef NUMSAVED for(i=0;i 1824) maxit = 16; } if (periodicitycheck == 0 || inside == ZMAG || inside == STARTRAIL) oldcoloriter = 2147483647L; /* don't check periodicity at all */ else if (inside == PERIOD) /* for display-periodicity */ oldcoloriter = (maxit/5)*4; /* don't check until nearly done */ else if (reset_periodicity) oldcoloriter = 255; /* don't check periodicity 1st 250 iterations */ /* Jonathan - how about this idea ? skips first saved value which never works */ #ifdef MINSAVEDAND if(oldcoloriter < MINSAVEDAND) oldcoloriter = MINSAVEDAND; #else if (oldcoloriter < firstsavedand) /* I like it! */ oldcoloriter = firstsavedand; #endif /* really fractal specific, but we'll leave it here */ if (!integerfractal) { if (useinitorbit == 1) saved = initorbit; else { saved.x = 0; saved.y = 0; } #ifdef NUMSAVED savedz[zctr++] = saved; #endif if(bf_math) { if(decimals > 200) kbdcount = -1; if (bf_math == BIGNUM) { clear_bn(bnsaved.x); clear_bn(bnsaved.y); } else if (bf_math == BIGFLT) { clear_bf(bfsaved.x); clear_bf(bfsaved.y); } } init.y = dypixel(); if (distest) { if (use_old_distest) { rqlim = rqlim_save; if (distest != 1 || colors == 2) /* not doing regular outside colors */ if (rqlim < DEM_BAILOUT) /* so go straight for dem bailout */ rqlim = DEM_BAILOUT; dem_color = -1; } deriv.x = 1; deriv.y = 0; magnitude = 0; } } else { if (useinitorbit == 1) lsaved = linitorbit; else { lsaved.x = 0; lsaved.y = 0; } linit.y = lypixel(); } orbit_ptr = 0; coloriter = 0; if(fractype==JULIAFP || fractype==JULIA) coloriter = -1; caught_a_cycle = 0; if (inside == PERIOD) { savedand = 16; /* begin checking every 16th cycle */ } else { /* Jonathan - don't understand such a low savedand -- how about this? */ #ifdef MINSAVEDAND savedand = MINSAVEDAND; #else savedand = firstsavedand; /* begin checking every other cycle */ #endif } savedincr = 1; /* start checking the very first time */ if (inside <= BOF60 && inside >= BOF61) { magnitude = 0.0; lmagnitud = 0; min_orbit = 100000.0; } overflow = 0; /* reset integer math overflow flag */ curfractalspecific->per_pixel(); /* initialize the calculations */ attracted = FALSE; if (outside == TDIS) { if(integerfractal) { old.x = ((double)lold.x) / fudge; old.y = ((double)lold.y) / fudge; } else if (bf_math == BIGNUM) old = cmplxbntofloat(&bnold); else if (bf_math==BIGFLT) old = cmplxbftofloat(&bfold); lastz.x = old.x; lastz.y = old.y; } if (((soundflag&7) > 2 || showdot >= 0) && orbit_delay > 0) check_freq = 16; else check_freq = 2048; if(show_orbit) snd_time_write(); while (++coloriter < maxit) { /* calculation of one orbit goes here */ /* input in "old" -- output in "new" */ if (coloriter % check_freq == 0) { if (check_key()) return (-1); } if (distest) { double ftemp; /* Distance estimator for points near Mandelbrot set */ /* Original code by Phil Wilson, hacked around by PB */ /* Algorithms from Peitgen & Saupe, Science of Fractal Images, p.198 */ if (dem_mandel) ftemp = 2 * (old.x * deriv.x - old.y * deriv.y) + 1; else ftemp = 2 * (old.x * deriv.x - old.y * deriv.y); deriv.y = 2 * (old.y * deriv.x + old.x * deriv.y); deriv.x = ftemp; if (use_old_distest) { if (sqr(deriv.x)+sqr(deriv.y) > dem_toobig) break; } else if (save_release > 1950) if (max(fabs(deriv.x),fabs(deriv.y)) > dem_toobig) break; /* if above exit taken, the later test vs dem_delta will place this point on the boundary, because mag(old)orbitcalc() || (overflow && save_release > 1826)) { if (use_old_distest) { if (dem_color < 0) { dem_color = coloriter; dem_new = new; } if (rqlim >= DEM_BAILOUT || magnitude >= (rqlim = DEM_BAILOUT) || magnitude == 0) break; } else break; } old = new; } /* the usual case */ else if ((curfractalspecific->orbitcalc() && inside != STARTRAIL) || overflow) break; if (show_orbit) { if (!integerfractal) { if (bf_math == BIGNUM) new = cmplxbntofloat(&bnnew); else if (bf_math==BIGFLT) new = cmplxbftofloat(&bfnew); plot_orbit(new.x, new.y, -1); } else iplot_orbit(lnew.x, lnew.y, -1); } if( inside < -1) { if (bf_math == BIGNUM) new = cmplxbntofloat(&bnnew); else if (bf_math == BIGFLT) new = cmplxbftofloat(&bfnew); if(inside == STARTRAIL) { if(0 < coloriter && coloriter < 16) { if (integerfractal) { new.x = lnew.x; new.x /= fudge; new.y = lnew.y; new.y /= fudge; } if (save_release > 1824) { if(new.x > STARTRAILMAX) new.x = STARTRAILMAX; if(new.x < -STARTRAILMAX) new.x = -STARTRAILMAX; if(new.y > STARTRAILMAX) new.y = STARTRAILMAX; if(new.y < -STARTRAILMAX) new.y = -STARTRAILMAX; tempsqrx = new.x * new.x; tempsqry = new.y * new.y; magnitude = tempsqrx + tempsqry; old = new; } { int tmpcolor; tmpcolor = (int)(((coloriter - 1) % andcolor) + 1); tantable[tmpcolor-1] = new.y/(new.x+.000001); } } } else if(inside == EPSCROSS) { hooper = 0; if(integerfractal) { if(labs(lnew.x) < labs(lcloseprox)) { hooper = (lcloseprox>0? 1 : -1); /* close to y axis */ goto plot_inside; } else if(labs(lnew.y) < labs(lcloseprox)) { hooper = (lcloseprox>0 ? 2: -2); /* close to x axis */ goto plot_inside; } } else { if(fabs(new.x) < fabs(closeprox)) { hooper = (closeprox>0? 1 : -1); /* close to y axis */ goto plot_inside; } else if(fabs(new.y) < fabs(closeprox)) { hooper = (closeprox>0? 2 : -2); /* close to x axis */ goto plot_inside; } } } else if (inside == FMODI) { double mag; if(integerfractal) { new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; } mag = fmodtest(); if(mag < closeprox) memvalue = mag; } else if (inside <= BOF60 && inside >= BOF61) { if (integerfractal) { if (lmagnitud == 0 || no_mag_calc == 0) lmagnitud = lsqr(lnew.x) + lsqr(lnew.y); magnitude = lmagnitud; magnitude = magnitude / fudge; } else if (magnitude == 0.0 || no_mag_calc == 0) magnitude = sqr(new.x) + sqr(new.y); if (magnitude < min_orbit) { min_orbit = magnitude; min_index = coloriter + 1; } } } if (outside == TDIS || outside == FMOD) { if (bf_math == BIGNUM) new = cmplxbntofloat(&bnnew); else if (bf_math == BIGFLT) new = cmplxbftofloat(&bfnew); if (outside == TDIS) { if(integerfractal) { new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; } totaldist += sqrt(sqr(lastz.x-new.x)+sqr(lastz.y-new.y)); lastz.x = new.x; lastz.y = new.y; } else if (outside == FMOD) { double mag; if(integerfractal) { new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; } mag = fmodtest(); if(mag < closeprox) memvalue = mag; } } if (attractors > 0) /* finite attractor in the list */ { /* NOTE: Integer code is UNTESTED */ if (integerfractal) { for (i = 0; i < attractors; i++) { lat.x = lnew.x - lattr[i].x; lat.x = lsqr(lat.x); if (lat.x < l_at_rad) { lat.y = lnew.y - lattr[i].y; lat.y = lsqr(lat.y); if (lat.y < l_at_rad) { if ((lat.x + lat.y) < l_at_rad) { attracted = TRUE; if (finattract<0) coloriter = (coloriter%attrperiod[i])+1; break; } } } } } else { for (i = 0; i < attractors; i++) { at.x = new.x - attr[i].x; at.x = sqr(at.x); if (at.x < f_at_rad) { at.y = new.y - attr[i].y; at.y = sqr(at.y); if ( at.y < f_at_rad) { if ((at.x + at.y) < f_at_rad) { attracted = TRUE; if (finattract<0) coloriter = (coloriter%attrperiod[i])+1; break; } } } } } if (attracted) break; /* AHA! Eaten by an attractor */ } if (coloriter > oldcoloriter) /* check periodicity */ { if ((coloriter & savedand) == 0) /* time to save a new value */ { savedcoloriter = coloriter; if (integerfractal) lsaved = lnew;/* integer fractals */ else if (bf_math == BIGNUM) { copy_bn(bnsaved.x,bnnew.x); copy_bn(bnsaved.y,bnnew.y); } else if (bf_math == BIGFLT) { copy_bf(bfsaved.x,bfnew.x); copy_bf(bfsaved.y,bfnew.y); } else { saved = new; /* floating pt fractals */ #ifdef NUMSAVED if(zctr < NUMSAVED) { changed[zctr] = coloriter; savedz[zctr++] = saved; } #endif } if (--savedincr == 0) /* time to lengthen the periodicity? */ { savedand = (savedand << 1) + 1; /* longer periodicity */ savedincr = nextsavedincr;/* restart counter */ } } else /* check against an old save */ { if (integerfractal) /* floating-pt periodicity chk */ { if (labs(lsaved.x - lnew.x) < lclosenuff) if (labs(lsaved.y - lnew.y) < lclosenuff) caught_a_cycle = 1; } else if (bf_math == BIGNUM) { if (cmp_bn(abs_a_bn(sub_bn(bntmp,bnsaved.x,bnnew.x)), bnclosenuff) < 0) if (cmp_bn(abs_a_bn(sub_bn(bntmp,bnsaved.y,bnnew.y)), bnclosenuff) < 0) caught_a_cycle = 1; } else if (bf_math == BIGFLT) { if (cmp_bf(abs_a_bf(sub_bf(bftmp,bfsaved.x,bfnew.x)), bfclosenuff) < 0) if (cmp_bf(abs_a_bf(sub_bf(bftmp,bfsaved.y,bfnew.y)), bfclosenuff) < 0) caught_a_cycle = 1; } else { if (fabs(saved.x - new.x) < closenuff) if (fabs(saved.y - new.y) < closenuff) caught_a_cycle = 1; #ifdef NUMSAVED int i; for(i=0;i<=zctr;i++) { if(caught[i] == 0) { if (fabs(savedz[i].x - new.x) < closenuff) if (fabs(savedz[i].y - new.y) < closenuff) caught[i] = coloriter; } } #endif } if(caught_a_cycle) { #ifdef NUMSAVED char msg[MSGLEN]; static FILE *fp = NULL; static char c; if(fp==NULL) fp = dir_fopen(workdir,"cycles.txt","w"); #endif cyclelen = coloriter-savedcoloriter; #ifdef NUMSAVED fprintf(fp,"row %3d col %3d len %6ld iter %6ld savedand %6ld\n", row,col,cyclelen,coloriter,savedand); if(zctr > 1 && zctr < NUMSAVED) { int i; for(i=0;i= maxit) oldcoloriter = 0; /* check periodicity immediately next time */ else { oldcoloriter = coloriter + 10; /* check when past this + 10 next time */ if (coloriter == 0) coloriter = 1; /* needed to make same as calcmand */ } if (potflag) { if (integerfractal) /* adjust integer fractals */ { new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; } else if (bf_math==BIGNUM) { new.x = (double)bntofloat(bnnew.x); new.y = (double)bntofloat(bnnew.y); } else if (bf_math==BIGFLT) { new.x = (double)bftofloat(bfnew.x); new.y = (double)bftofloat(bfnew.y); } magnitude = sqr(new.x) + sqr(new.y); coloriter = potential(magnitude, coloriter); if (LogTable || Log_Calc) coloriter = logtablecalc(coloriter); goto plot_pixel; /* skip any other adjustments */ } if (coloriter >= maxit) /* an "inside" point */ goto plot_inside; /* distest, decomp, biomorph don't apply */ if (outside < -1) /* these options by Richard Hughes modified by TW */ { if (integerfractal) { new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; } else if(bf_math==1) { new.x = (double)bntofloat(bnnew.x); new.y = (double)bntofloat(bnnew.y); } /* Add 7 to overcome negative values on the MANDEL */ if (outside == REAL) /* "real" */ coloriter += (long)new.x + 7; else if (outside == IMAG) /* "imag" */ coloriter += (long)new.y + 7; else if (outside == MULT && new.y) /* "mult" */ coloriter = (long)((double)coloriter * (new.x/new.y)); else if (outside == SUM) /* "sum" */ coloriter += (long)(new.x + new.y); else if (outside == ATAN) /* "atan" */ coloriter = (long)fabs(atan2(new.y,new.x)*atan_colors/PI); else if (outside == FMOD) coloriter = (long)(memvalue * colors / closeprox); else if (outside == TDIS) { coloriter = (long)(totaldist); } /* eliminate negative colors & wrap arounds */ if ((coloriter <= 0 || coloriter > maxit) && outside!=FMOD) { if (save_release < 1961) coloriter = 0; else coloriter = 1; } } if (distest) { double dist,temp; dist = sqr(new.x) + sqr(new.y); if (dist == 0 || overflow) dist = 0; else { temp = log(dist); dist = dist * sqr(temp) / ( sqr(deriv.x) + sqr(deriv.y) ); } if (dist < dem_delta) /* point is on the edge */ { if (distest > 0) goto plot_inside; /* show it as an inside point */ coloriter = 0 - distest; /* show boundary as specified color */ goto plot_pixel; /* no further adjustments apply */ } if (colors == 2) { coloriter = !inside; /* the only useful distest 2 color use */ goto plot_pixel; /* no further adjustments apply */ } if (distest > 1) /* pick color based on distance */ { if (old_demm_colors) /* this one is needed for old color scheme */ coloriter = (long)sqrt(sqrt(dist) / dem_width + 1); else if (use_old_distest) coloriter = (long)sqrt(dist / dem_width + 1); else coloriter = (long)(dist / dem_width + 1); coloriter &= LONG_MAX; /* oops - color can be negative */ goto plot_pixel; /* no further adjustments apply */ } if (use_old_distest) { coloriter = dem_color; new = dem_new; } /* use pixel's "regular" color */ } if (decomp[0] > 0) decomposition(); else if (biomorph != -1) { if (integerfractal) { if (labs(lnew.x) < llimit2 || labs(lnew.y) < llimit2) coloriter = biomorph; } else if (fabs(new.x) < rqlim2 || fabs(new.y) < rqlim2) coloriter = biomorph; } if (outside >= 0 && attracted == FALSE) /* merge escape-time stripes */ coloriter = outside; else if (LogTable || Log_Calc) coloriter = logtablecalc(coloriter); goto plot_pixel; plot_inside: /* we're "inside" */ if (periodicitycheck < 0 && caught_a_cycle) coloriter = 7; /* show periodicity */ else if (inside >= 0) coloriter = inside; /* set to specified color, ignore logpal */ else { if(inside == STARTRAIL) { int i; double diff; coloriter = 0; for(i=1;i<16;i++) { diff = tantable[0] - tantable[i]; if(fabs(diff) < .05) { coloriter = i; break; } } } else if(inside== PERIOD) { if (cyclelen>0) { coloriter = cyclelen; } else { coloriter = maxit; } } else if(inside == EPSCROSS) { if(hooper==1) coloriter = green; else if(hooper==2) coloriter = yellow; else if( hooper==0) coloriter = maxit; if (show_orbit) scrub_orbit(); } else if(inside == FMODI) { coloriter = (long)(memvalue * colors / closeprox); } else if (inside == ATANI) /* "atan" */ if (integerfractal) { new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; coloriter = (long)fabs(atan2(new.y,new.x)*atan_colors/PI); } else coloriter = (long)fabs(atan2(new.y,new.x)*atan_colors/PI); else if (inside == BOF60) coloriter = (long)(sqrt(min_orbit) * 75); else if (inside == BOF61) coloriter = min_index; else if (inside == ZMAG) { if (integerfractal) { /* new.x = ((double)lnew.x) / fudge; new.y = ((double)lnew.y) / fudge; coloriter = (long)((((double)lsqr(lnew.x))/fudge + ((double)lsqr(lnew.y))/fudge) * (maxit>>1) + 1); */ coloriter = (long)(((double)lmagnitud/fudge) * (maxit>>1) + 1); } else coloriter = (long)((sqr(new.x) + sqr(new.y)) * (maxit>>1) + 1); } else /* inside == -1 */ coloriter = maxit; if (LogTable || Log_Calc) coloriter = logtablecalc(coloriter); } plot_pixel: color = abs((int)coloriter); if (coloriter >= colors) { /* don't use color 0 unless from inside/outside */ if (save_release <= 1950) { if (colors < 16) color &= andcolor; else color = ((color - 1) % andcolor) + 1; /* skip color zero */ } else { if (colors < 16) color = (int)(coloriter & andcolor); else color = (int)(((coloriter - 1) % andcolor) + 1); } } if(debugflag != 470) if(color <= 0 && stdcalcmode == 'b' ) /* fix BTM bug */ color = 1; (*plot) (col, row, color); maxit = savemaxit; if ((kbdcount -= abs((int)realcoloriter)) <= 0) { if (check_key()) return (-1); kbdcount = max_kbdcount; } return (color); } #undef green #undef yellow #define cos45 sin45 #define lcos45 lsin45 /**************** standardfractal doodad subroutines *********************/ static void decomposition(void) { /* static double cos45 = 0.70710678118654750; */ /* cos 45 degrees */ static double sin45 = 0.70710678118654750; /* sin 45 degrees */ static double cos22_5 = 0.92387953251128670; /* cos 22.5 degrees */ static double sin22_5 = 0.38268343236508980; /* sin 22.5 degrees */ static double cos11_25 = 0.98078528040323040; /* cos 11.25 degrees */ static double sin11_25 = 0.19509032201612820; /* sin 11.25 degrees */ static double cos5_625 = 0.99518472667219690; /* cos 5.625 degrees */ static double sin5_625 = 0.09801714032956060; /* sin 5.625 degrees */ static double tan22_5 = 0.41421356237309500; /* tan 22.5 degrees */ static double tan11_25 = 0.19891236737965800; /* tan 11.25 degrees */ static double tan5_625 = 0.09849140335716425; /* tan 5.625 degrees */ static double tan2_8125 = 0.04912684976946725; /* tan 2.8125 degrees */ static double tan1_4063 = 0.02454862210892544; /* tan 1.4063 degrees */ /* static long lcos45 ;*/ /* cos 45 degrees */ static long lsin45 ; /* sin 45 degrees */ static long lcos22_5 ; /* cos 22.5 degrees */ static long lsin22_5 ; /* sin 22.5 degrees */ static long lcos11_25 ; /* cos 11.25 degrees */ static long lsin11_25 ; /* sin 11.25 degrees */ static long lcos5_625 ; /* cos 5.625 degrees */ static long lsin5_625 ; /* sin 5.625 degrees */ static long ltan22_5 ; /* tan 22.5 degrees */ static long ltan11_25 ; /* tan 11.25 degrees */ static long ltan5_625 ; /* tan 5.625 degrees */ static long ltan2_8125 ; /* tan 2.8125 degrees */ static long ltan1_4063 ; /* tan 1.4063 degrees */ static long reset_fudge = -1; int temp = 0; int save_temp = 0; int i; _LCMPLX lalt; _CMPLX alt; coloriter = 0; if (integerfractal) /* the only case */ { if (reset_fudge != fudge) { reset_fudge = fudge; /* lcos45 = (long)(cos45 * fudge); */ lsin45 = (long)(sin45 * fudge); lcos22_5 = (long)(cos22_5 * fudge); lsin22_5 = (long)(sin22_5 * fudge); lcos11_25 = (long)(cos11_25 * fudge); lsin11_25 = (long)(sin11_25 * fudge); lcos5_625 = (long)(cos5_625 * fudge); lsin5_625 = (long)(sin5_625 * fudge); ltan22_5 = (long)(tan22_5 * fudge); ltan11_25 = (long)(tan11_25 * fudge); ltan5_625 = (long)(tan5_625 * fudge); ltan2_8125 = (long)(tan2_8125 * fudge); ltan1_4063 = (long)(tan1_4063 * fudge); } if (lnew.y < 0) { temp = 2; lnew.y = -lnew.y; } if (lnew.x < 0) { ++temp; lnew.x = -lnew.x; } if (decomp[0] == 2 && save_release >= 1827) { save_temp = temp; if(temp==2) save_temp = 3; if(temp==3) save_temp = 2; } if (decomp[0] >= 8) { temp <<= 1; if (lnew.x < lnew.y) { ++temp; lalt.x = lnew.x; /* just */ lnew.x = lnew.y; /* swap */ lnew.y = lalt.x; /* them */ } if (decomp[0] >= 16) { temp <<= 1; if (multiply(lnew.x,ltan22_5,bitshift) < lnew.y) { ++temp; lalt = lnew; lnew.x = multiply(lalt.x,lcos45,bitshift) + multiply(lalt.y,lsin45,bitshift); lnew.y = multiply(lalt.x,lsin45,bitshift) - multiply(lalt.y,lcos45,bitshift); } if (decomp[0] >= 32) { temp <<= 1; if (multiply(lnew.x,ltan11_25,bitshift) < lnew.y) { ++temp; lalt = lnew; lnew.x = multiply(lalt.x,lcos22_5,bitshift) + multiply(lalt.y,lsin22_5,bitshift); lnew.y = multiply(lalt.x,lsin22_5,bitshift) - multiply(lalt.y,lcos22_5,bitshift); } if (decomp[0] >= 64) { temp <<= 1; if (multiply(lnew.x,ltan5_625,bitshift) < lnew.y) { ++temp; lalt = lnew; lnew.x = multiply(lalt.x,lcos11_25,bitshift) + multiply(lalt.y,lsin11_25,bitshift); lnew.y = multiply(lalt.x,lsin11_25,bitshift) - multiply(lalt.y,lcos11_25,bitshift); } if (decomp[0] >= 128) { temp <<= 1; if (multiply(lnew.x,ltan2_8125,bitshift) < lnew.y) { ++temp; lalt = lnew; lnew.x = multiply(lalt.x,lcos5_625,bitshift) + multiply(lalt.y,lsin5_625,bitshift); lnew.y = multiply(lalt.x,lsin5_625,bitshift) - multiply(lalt.y,lcos5_625,bitshift); } if (decomp[0] == 256) { temp <<= 1; if (multiply(lnew.x,ltan1_4063,bitshift) < lnew.y) if ((lnew.x*ltan1_4063 < lnew.y)) ++temp; } } } } } } } else /* double case */ { if (new.y < 0) { temp = 2; new.y = -new.y; } if (new.x < 0) { ++temp; new.x = -new.x; } if (decomp[0] == 2 && save_release >= 1827) { save_temp = temp; if(temp==2) save_temp = 3; if(temp==3) save_temp = 2; } if (decomp[0] >= 8) { temp <<= 1; if (new.x < new.y) { ++temp; alt.x = new.x; /* just */ new.x = new.y; /* swap */ new.y = alt.x; /* them */ } if (decomp[0] >= 16) { temp <<= 1; if (new.x*tan22_5 < new.y) { ++temp; alt = new; new.x = alt.x*cos45 + alt.y*sin45; new.y = alt.x*sin45 - alt.y*cos45; } if (decomp[0] >= 32) { temp <<= 1; if (new.x*tan11_25 < new.y) { ++temp; alt = new; new.x = alt.x*cos22_5 + alt.y*sin22_5; new.y = alt.x*sin22_5 - alt.y*cos22_5; } if (decomp[0] >= 64) { temp <<= 1; if (new.x*tan5_625 < new.y) { ++temp; alt = new; new.x = alt.x*cos11_25 + alt.y*sin11_25; new.y = alt.x*sin11_25 - alt.y*cos11_25; } if (decomp[0] >= 128) { temp <<= 1; if (new.x*tan2_8125 < new.y) { ++temp; alt = new; new.x = alt.x*cos5_625 + alt.y*sin5_625; new.y = alt.x*sin5_625 - alt.y*cos5_625; } if (decomp[0] == 256) { temp <<= 1; if ((new.x*tan1_4063 < new.y)) ++temp; } } } } } } } for (i = 1; temp > 0; ++i) { if (temp & 1) coloriter = (1 << i) - 1 - coloriter; temp >>= 1; } if (decomp[0] == 2 && save_release >= 1827) { if(save_temp & 2) coloriter = 1; else coloriter = 0; if (colors == 2) coloriter++; } else if (decomp[0] == 2 && save_release < 1827) coloriter &= 1; if (colors > decomp[0]) coloriter++; } /******************************************************************/ /* Continuous potential calculation for Mandelbrot and Julia */ /* Reference: Science of Fractal Images p. 190. */ /* Special thanks to Mark Peterson for his "MtMand" program that */ /* beautifully approximates plate 25 (same reference) and spurred */ /* on the inclusion of similar capabilities in FRACTINT. */ /* */ /* The purpose of this function is to calculate a color value */ /* for a fractal that varies continuously with the screen pixels */ /* locations for better rendering in 3D. */ /* */ /* Here "magnitude" is the modulus of the orbit value at */ /* "iterations". The potparms[] are user-entered paramters */ /* controlling the level and slope of the continuous potential */ /* surface. Returns color. - Tim Wegner 6/25/89 */ /* */ /* -- Change history -- */ /* */ /* 09/12/89 - added floatflag support and fixed float underflow */ /* */ /******************************************************************/ static int _fastcall potential(double mag, long iterations) { float f_mag,f_tmp,pot; double d_tmp; int i_pot; long l_pot; if(iterations < maxit) { pot = (float)(l_pot = iterations+2); if(l_pot <= 0 || mag <= 1.0) pot = (float)0.0; else /* pot = log(mag) / pow(2.0, (double)pot); */ { if(l_pot < 120 && !floatflag) /* empirically determined limit of fShift */ { f_mag = (float)mag; fLog14(f_mag,f_tmp); /* this SHOULD be non-negative */ fShift(f_tmp,(char)-l_pot,pot); } else { d_tmp = log(mag)/(double)pow(2.0,(double)pot); if(d_tmp > FLT_MIN) /* prevent float type underflow */ pot = (float)d_tmp; else pot = (float)0.0; } } /* following transformation strictly for aesthetic reasons */ /* meaning of parameters: potparam[0] -- zero potential level - highest color - potparam[1] -- slope multiplier -- higher is steeper potparam[2] -- rqlim value if changeable (bailout for modulus) */ if(pot > 0.0) { if(floatflag) pot = (float)sqrt((double)pot); else { fSqrt14(pot,f_tmp); pot = f_tmp; } pot = (float)(potparam[0] - pot*potparam[1] - 1.0); } else pot = (float)(potparam[0] - 1.0); if(pot < 1.0) pot = (float)1.0; /* avoid color 0 */ } else if(inside >= 0) pot = inside; else /* inside < 0 implies inside=maxit, so use 1st pot param instead */ pot = (float)potparam[0]; i_pot = (int)((l_pot = (long)(pot * 256)) >> 8); if(i_pot >= colors) { i_pot = colors - 1; l_pot = 255; } if(pot16bit) { if (dotmode != 11) /* if putcolor won't be doing it for us */ writedisk(col+sxoffs,row+syoffs,i_pot); writedisk(col+sxoffs,row+sydots+syoffs,(int)l_pot); } return(i_pot); } /******************* boundary trace method *************************** Fractint's original btm was written by David Guenther. There were a few rare circumstances in which the original btm would not trace or fill correctly, even on Mandelbrot Sets. The code below was adapted from "Mandelbrot Sets by Wesley Loewer" (see calmanfp.asm) which was written before I was introduced to Fractint. It should be noted that without David Guenther's implimentation of a btm, I doubt that I would have been able to impliment my own code into Fractint. There are several things in the following code that are not original with me but came from David Guenther's code. I've noted these places with the initials DG. Wesley Loewer 3/8/92 *********************************************************************/ #define bkcolor 0 /* I have some ideas for the future with this. -Wes */ #define advance_match() coming_from = ((going_to = (going_to - 1) & 0x03) - 1) & 0x03 #define advance_no_match() going_to = (going_to + 1) & 0x03 static int bound_trace_main(void) { enum direction coming_from; unsigned int match_found, continue_loop; int trail_color, fillcolor_used, last_fillcolor_used = -1; int max_putline_length; int right, left, length; static FCODE btm_cantbeused[]={"Boundary tracing cannot be used with "}; if (inside == 0 || outside == 0) { static FCODE inside_outside[] = {"inside=0 or outside=0"}; char msg[MSGLEN]; far_strcpy(msg,btm_cantbeused); far_strcat(msg,inside_outside); stopmsg(0,msg); return(-1); } if (colors < 16) { char msg[MSGLEN]; static FCODE lessthansixteen[] = {"< 16 colors"}; far_strcpy(msg,btm_cantbeused); far_strcat(msg,lessthansixteen); stopmsg(0,msg); return(-1); } got_status = 2; max_putline_length = 0; /* reset max_putline_length */ for (currow = iystart; currow <= iystop; currow++) { reset_periodicity = 1; /* reset for a new row */ color = bkcolor; for (curcol = ixstart; curcol <= ixstop; curcol++) { if (getcolor(curcol, currow) != bkcolor) continue; trail_color = color; row = currow; col = curcol; if ((*calctype)()== -1) /* color, row, col are global */ { if (showdot != bkcolor) /* remove showdot pixel */ (*plot)(col,row,bkcolor); if (iystop != yystop) /* DG */ iystop = yystop - (currow - yystart); /* allow for sym */ add_worklist(xxstart,xxstop,curcol,currow,iystop,currow,0,worksym); return -1; } reset_periodicity = 0; /* normal periodicity checking */ /* This next line may cause a few more pixels to be calculated, but at the savings of quite a bit of overhead */ if (color != trail_color) /* DG */ continue; /* sweep clockwise to trace outline */ trail_row = currow; trail_col = curcol; trail_color = color; fillcolor_used = fillcolor > 0 ? fillcolor : trail_color; coming_from = West; going_to = East; match_found = 0; continue_loop = TRUE; do { step_col_row(); if (row >= currow && col >= ixstart && col <= ixstop && row <= iystop) { /* the order of operations in this next line is critical */ if ((color = getcolor(col, row)) == bkcolor && (*calctype)()== -1) /* color, row, col are global for (*calctype)() */ { if (showdot != bkcolor) /* remove showdot pixel */ (*plot)(col,row,bkcolor); if (iystop != yystop) /* DG */ iystop = yystop - (currow - yystart); /* allow for sym */ add_worklist(xxstart,xxstop,curcol,currow,iystop,currow,0,worksym); return -1; } else if (color == trail_color) { if (match_found < 4) /* to keep it from overflowing */ match_found++; trail_row = row; trail_col = col; advance_match(); } else { advance_no_match(); continue_loop = going_to != coming_from || match_found; } } else { advance_no_match(); continue_loop = going_to != coming_from || match_found; } } while (continue_loop && (col != curcol || row != currow)); if (match_found <= 3) /* DG */ { /* no hole */ color = bkcolor; reset_periodicity = 1; continue; } /* Fill in region by looping around again, filling lines to the left whenever going_to is South or West */ trail_row = currow; trail_col = curcol; coming_from = West; going_to = East; do { match_found = FALSE; do { step_col_row(); if (row >= currow && col >= ixstart && col <= ixstop && row <= iystop && getcolor(col,row) == trail_color) /* getcolor() must be last */ { if (going_to == South || (going_to == West && coming_from != East)) { /* fill a row, but only once */ right = col; while (--right >= ixstart && (color = getcolor(right,row)) == trail_color) ; /* do nothing */ if (color == bkcolor) /* check last color */ { left = right; while (getcolor(--left,row) == bkcolor) /* Should NOT be possible for left < ixstart */ ; /* do nothing */ left++; /* one pixel too far */ if (right == left) /* only one hole */ (*plot)(left,row,fillcolor_used); else { /* fill the line to the left */ length=right-left+1; if (fillcolor_used != last_fillcolor_used || length > max_putline_length) { /* only reset dstack if necessary */ memset(dstack,fillcolor_used,length); last_fillcolor_used = fillcolor_used; max_putline_length = length; } sym_fill_line(row, left, right, dstack); } } /* end of fill line */ #if 0 /* don't interupt with a check_key() during fill */ if(--kbdcount<=0) { if(check_key()) { if (iystop != yystop) iystop = yystop - (currow - yystart); /* allow for sym */ add_worklist(xxstart,xxstop,curcol,currow,iystop,currow,0,worksym); return(-1); } kbdcount=max_kbdcount; } #endif } trail_row = row; trail_col = col; advance_match(); match_found = TRUE; } else advance_no_match(); } while (!match_found && going_to != coming_from); if (!match_found) { /* next one has to be a match */ step_col_row(); trail_row = row; trail_col = col; advance_match(); } } while (trail_col != curcol || trail_row != currow); reset_periodicity = 1; /* reset after a trace/fill */ color = bkcolor; } } return 0; } /*******************************************************************/ /* take one step in the direction of going_to */ static void step_col_row() { switch (going_to) { case North: col = trail_col; row = trail_row - 1; break; case East: col = trail_col + 1; row = trail_row; break; case South: col = trail_col; row = trail_row + 1; break; case West: col = trail_col - 1; row = trail_row; break; } } /******************* end of boundary trace method *******************/ /************************ super solid guessing *****************************/ /* I, Timothy Wegner, invented this solidguessing idea and implemented it in more or less the overall framework you see here. I am adding this note now in a possibly vain attempt to secure my place in history, because Pieter Branderhorst has totally rewritten this routine, incorporating a *MUCH* more sophisticated algorithm. His revised code is not only faster, but is also more accurate. Harrumph! */ static int solidguess(void) { int i,x,y,xlim,ylim,blocksize; unsigned int *pfxp0,*pfxp1; unsigned int u; guessplot=(plot!=putcolor && plot!=symplot2 && plot!=symplot2J); /* check if guessing at bottom & right edges is ok */ bottom_guess = (plot == symplot2 || (plot == putcolor && iystop+1 == ydots)); right_guess = (plot == symplot2J || ((plot == putcolor || plot == symplot2) && ixstop+1 == xdots)); /* there seems to be a bug in solid guessing at bottom and side */ if(debugflag != 472) bottom_guess = right_guess = 0; /* TIW march 1995 */ i = maxblock = blocksize = ssg_blocksize(); totpasses = 1; while ((i >>= 1) > 1) ++totpasses; /* ensure window top and left are on required boundary, treat window as larger than it really is if necessary (this is the reason symplot routines must check for > xdots/ydots before plotting sym points) */ ixstart &= -1 - (maxblock-1); iystart = yybegin; iystart &= -1 - (maxblock-1); got_status = 1; if (workpass == 0) /* otherwise first pass already done */ { /* first pass, calc every blocksize**2 pixel, quarter result & paint it */ curpass = 1; if (iystart <= yystart) /* first time for this window, init it */ { currow = 0; memset(&tprefix[1][0][0],0,maxxblk*maxyblk*2); /* noskip flags off */ reset_periodicity = 1; row=iystart; for(col=ixstart; col<=ixstop; col+=maxblock) { /* calc top row */ if((*calctype)()== -1) { add_worklist(xxstart,xxstop,xxbegin,yystart,yystop,yybegin,0,worksym); goto exit_solidguess; } reset_periodicity = 0; } } else memset(&tprefix[1][0][0],-1,maxxblk*maxyblk*2); /* noskip flags on */ for(y=iystart; y<=iystop; y+=blocksize) { currow = y; i = 0; if(y+blocksize<=iystop) { /* calc the row below */ row=y+blocksize; reset_periodicity = 1; for(col=ixstart; col<=ixstop; col+=maxblock) { if((i=(*calctype)()) == -1) break; reset_periodicity = 0; } } reset_periodicity = 0; if (i == -1 || guessrow(1,y,blocksize) != 0) /* interrupted? */ { if (y < yystart) y = yystart; add_worklist(xxstart,xxstop,xxstart,yystart,yystop,y,0,worksym); goto exit_solidguess; } } if (num_worklist) /* work list not empty, just do 1st pass */ { add_worklist(xxstart,xxstop,xxstart,yystart,yystop,yystart,1,worksym); goto exit_solidguess; } ++workpass; iystart = yystart & (-1 - (maxblock-1)); /* calculate skip flags for skippable blocks */ xlim=(ixstop+maxblock)/maxblock+1; ylim=((iystop+maxblock)/maxblock+15)/16+1; if(right_guess==0) /* no right edge guessing, zap border */ for(y=0;y<=ylim;++y) tprefix[1][y][xlim]= 0xffff; if(bottom_guess==0) /* no bottom edge guessing, zap border */ { i=(iystop+maxblock)/maxblock+1; y=i/16+1; i=1<<(i&15); for(x=0;x<=xlim;++x) tprefix[1][y][x]|=i; } /* set each bit in tprefix[0] to OR of it & surrounding 8 in tprefix[1] */ for(y=0;++y>1)|(u<<1) |((*(pfxp1-(maxxblk+1))|*(pfxp1-maxxblk)|*(pfxp1-(maxxblk-1)))>>15) |((*(pfxp1+(maxxblk-1))|*(pfxp1+maxxblk)|*(pfxp1+(maxxblk+1)))<<15); } } } else /* first pass already done */ memset(&tprefix[0][0][0],-1,maxxblk*maxyblk*2); /* noskip flags on */ if(three_pass) goto exit_solidguess; /* remaining pass(es), halve blocksize & quarter each blocksize**2 */ i = workpass; while (--i > 0) /* allow for already done passes */ blocksize = blocksize>>1; reset_periodicity = 0; while((blocksize=blocksize>>1)>=2) { if(stoppass > 0) if(workpass >= stoppass) goto exit_solidguess; curpass = workpass + 1; for(y=iystart; y<=iystop; y+=blocksize) { currow = y; if(guessrow(0,y,blocksize) != 0) { if (y < yystart) y = yystart; add_worklist(xxstart,xxstop,xxstart,yystart,yystop,y,workpass,worksym); goto exit_solidguess; } } ++workpass; if (num_worklist /* work list not empty, do one pass at a time */ && blocksize>2) /* if 2, we just did last pass */ { add_worklist(xxstart,xxstop,xxstart,yystart,yystop,yystart,workpass,worksym); goto exit_solidguess; } iystart = yystart & (-1 - (maxblock-1)); } exit_solidguess: return(0); } #define calcadot(c,x,y) { col=x; row=y; if((c=(*calctype)())== -1) return -1; } static int _fastcall guessrow(int firstpass,int y,int blocksize) { int x,i,j,color; int xplushalf,xplusblock; int ylessblock,ylesshalf,yplushalf,yplusblock; int c21,c31,c41; /* cxy is the color of pixel at (x,y) */ int c12,c22,c32,c42; /* where c22 is the topleft corner of */ int c13,c23,c33; /* the block being handled in current */ int c24, c44; /* iteration */ int guessed23,guessed32,guessed33,guessed12,guessed13; int prev11,fix21,fix31; unsigned int *pfxptr,pfxmask; c44 = c41 = c42 = 0; /* just for warning */ halfblock=blocksize>>1; i=y/maxblock; pfxptr= (unsigned int *)&tprefix[firstpass][(i>>4)+1][ixstart/maxblock]; pfxmask=1<<(i&15); ylesshalf=y-halfblock; ylessblock=y-blocksize; /* constants, for speed */ yplushalf=y+halfblock; yplusblock=y+blocksize; prev11= -1; c24=c12=c13=c22=getcolor(ixstart,y); c31=c21=getcolor(ixstart,(y>0)?ylesshalf:0); if(yplusblock<=iystop) c24=getcolor(ixstart,yplusblock); else if(bottom_guess==0) c24= -1; guessed12=guessed13=0; for(x=ixstart; x<=ixstop;) /* increment at end, or when doing continue */ { if((x&(maxblock-1))==0) /* time for skip flag stuff */ { ++pfxptr; if(firstpass==0 && (*pfxptr&pfxmask)==0) /* check for fast skip */ { /* next useful in testing to make skips visible */ /* if(halfblock==1) { (*plot)(x+1,y,0); (*plot)(x,y+1,0); (*plot)(x+1,y+1,0); } */ x+=maxblock; prev11=c31=c21=c24=c12=c13=c22; guessed12=guessed13=0; continue; } } if(firstpass) /* 1st pass, paint topleft corner */ plotblock(0,x,y,c22); /* setup variables */ xplusblock=(xplushalf=x+halfblock)+halfblock; if(xplushalf>ixstop) { if(right_guess==0) c31= -1; } else if(y>0) c31=getcolor(xplushalf,ylesshalf); if(xplusblock<=ixstop) { if(yplusblock<=iystop) c44=getcolor(xplusblock,yplusblock); c41=getcolor(xplusblock,(y>0)?ylesshalf:0); c42=getcolor(xplusblock,y); } else if(right_guess==0) c41=c42=c44= -1; if(yplusblock>iystop) c44=(bottom_guess)?c42:-1; /* guess or calc the remaining 3 quarters of current block */ guessed23=guessed32=guessed33=1; c23=c32=c33=c22; if(yplushalf>iystop) { if(bottom_guess==0) c23=c33= -1; guessed23=guessed33= -1; guessed13=0; /* fix for ydots not divisible by four bug TW 2/16/97 */ } if(xplushalf>ixstop) { if(right_guess==0) c32=c33= -1; guessed32=guessed33= -1; } for(;;) /* go around till none of 23,32,33 change anymore */ { if(guessed33>0 && (c33!=c44 || c33!=c42 || c33!=c24 || c33!=c32 || c33!=c23)) { calcadot(c33,xplushalf,yplushalf); guessed33=0; } if(guessed32>0 && (c32!=c33 || c32!=c42 || c32!=c31 || c32!=c21 || c32!=c41 || c32!=c23)) { calcadot(c32,xplushalf,y); guessed32=0; continue; } if(guessed23>0 && (c23!=c33 || c23!=c24 || c23!=c13 || c23!=c12 || c23!=c32)) { calcadot(c23,x,yplushalf); guessed23=0; continue; } break; } if(firstpass) /* note whether any of block's contents were calculated */ if(guessed23==0 || guessed32==0 || guessed33==0) *pfxptr|=pfxmask; if(halfblock>1) { /* not last pass, check if something to display */ if(firstpass) /* display guessed corners, fill in block */ { if(guessplot) { if(guessed23>0) (*plot)(x,yplushalf,c23); if(guessed32>0) (*plot)(xplushalf,y,c32); if(guessed33>0) (*plot)(xplushalf,yplushalf,c33); } plotblock(1,x,yplushalf,c23); plotblock(0,xplushalf,y,c32); plotblock(1,xplushalf,yplushalf,c33); } else /* repaint changed blocks */ { if(c23!=c22) plotblock(-1,x,yplushalf,c23); if(c32!=c22) plotblock(-1,xplushalf,y,c32); if(c33!=c22) plotblock(-1,xplushalf,yplushalf,c33); } } /* check if some calcs in this block mean earlier guesses need fixing */ fix21=((c22!=c12 || c22!=c32) && c21==c22 && c21==c31 && c21==prev11 && y>0 && (x==ixstart || c21==getcolor(x-halfblock,ylessblock)) && (xplushalf>ixstop || c21==getcolor(xplushalf,ylessblock)) && c21==getcolor(x,ylessblock)); fix31=(c22!=c32 && c31==c22 && c31==c42 && c31==c21 && c31==c41 && y>0 && xplushalf<=ixstop && c31==getcolor(xplushalf,ylessblock) && (xplusblock>ixstop || c31==getcolor(xplusblock,ylessblock)) && c31==getcolor(x,ylessblock)); prev11=c31; /* for next time around */ if(fix21) { calcadot(c21,x,ylesshalf); if(halfblock>1 && c21!=c22) plotblock(-1,x,ylesshalf,c21); } if(fix31) { calcadot(c31,xplushalf,ylesshalf); if(halfblock>1 && c31!=c22) plotblock(-1,xplushalf,ylesshalf,c31); } if(c23!=c22) { if(guessed12) { calcadot(c12,x-halfblock,y); if(halfblock>1 && c12!=c22) plotblock(-1,x-halfblock,y,c12); } if(guessed13) { calcadot(c13,x-halfblock,yplushalf); if(halfblock>1 && c13!=c22) plotblock(-1,x-halfblock,yplushalf,c13); } } c22=c42; c24=c44; c13=c33; c31=c21=c41; c12=c32; guessed12=guessed32; guessed13=guessed33; x+=blocksize; } /* end x loop */ if(firstpass==0 || guessplot) return 0; /* paint rows the fast way */ for(i=0;i=xxstart;) { color=dstack[i]; dstack[i]=dstack[j=ixstop-(i-xxstart)]; dstack[j]=(BYTE)color; j+=OLDMAXPIXELS; color=dstack[i+OLDMAXPIXELS]; dstack[i+OLDMAXPIXELS]=dstack[j]; dstack[j]=(BYTE)color; } for(i=0;iiystop && jiystop && jixstop) xlim=ixstop+1; if(buildrow>=0 && guessplot==0) /* save it for later put_line */ { if(buildrow==0) for(i=x;i=xxstart) /* when x reduced for alignment, paint those dots too */ return; /* the usual case */ } /* paint it */ if((ylim=y+halfblock)>iystop) { if(y>iystop) return; ylim=iystop+1; } for(i=x;++i= yystop) return(1); /* axis not in window */ i = xaxis_row + (xaxis_row - yystart); if (xaxis_between) ++i; if (i > yystop) /* split into 2 pieces, bottom has the symmetry */ { if (num_worklist >= MAXCALCWORK-1) /* no room to split */ return(1); iystop = xaxis_row - (yystop - xaxis_row); if (!xaxis_between) --iystop; add_worklist(xxstart,xxstop,xxstart,iystop+1,yystop,iystop+1,workpass,0); yystop = iystop; return(1); /* tell set_symmetry no sym for current window */ } if (i < yystop) /* split into 2 pieces, top has the symmetry */ { if (num_worklist >= MAXCALCWORK-1) /* no room to split */ return(1); add_worklist(xxstart,xxstop,xxstart,i+1,yystop,i+1,workpass,0); yystop = i; } iystop = xaxis_row; worksym |= 1; } symmetry = 0; return(0); /* tell set_symmetry its a go */ } static int _fastcall ysym_split(int yaxis_col,int yaxis_between) { int i; if ((worksym&0x22) == 0x20) /* already decided not sym */ return(1); if ((worksym&2) != 0) /* already decided on sym */ ixstop = (xxstart+xxstop)/2; else /* new window, decide */ { worksym |= 0x20; if (yaxis_col <= xxstart || yaxis_col >= xxstop) return(1); /* axis not in window */ i = yaxis_col + (yaxis_col - xxstart); if (yaxis_between) ++i; if (i > xxstop) /* split into 2 pieces, right has the symmetry */ { if (num_worklist >= MAXCALCWORK-1) /* no room to split */ return(1); ixstop = yaxis_col - (xxstop - yaxis_col); if (!yaxis_between) --ixstop; add_worklist(ixstop+1,xxstop,ixstop+1,yystart,yystop,yystart,workpass,0); xxstop = ixstop; return(1); /* tell set_symmetry no sym for current window */ } if (i < xxstop) /* split into 2 pieces, left has the symmetry */ { if (num_worklist >= MAXCALCWORK-1) /* no room to split */ return(1); add_worklist(i+1,xxstop,i+1,yystart,yystop,yystart,workpass,0); xxstop = i; } ixstop = yaxis_col; worksym |= 2; } symmetry = 0; return(0); /* tell set_symmetry its a go */ } #ifdef _MSC_VER #pragma optimize ("ea", off) #endif #if (_MSC_VER >= 700) #pragma code_seg ("calcfra1_text") /* place following in an overlay */ #endif static void _fastcall setsymmetry(int sym, int uselist) /* set up proper symmetrical plot functions */ { int i; int parmszero, parmsnoreal, parmsnoimag; int xaxis_row, yaxis_col; /* pixel number for origin */ int xaxis_between=0, yaxis_between=0; /* if axis between 2 pixels, not on one */ int xaxis_on_screen=0, yaxis_on_screen=0; double ftemp; bf_t bft1; int saved=0; symmetry = 1; if(stdcalcmode == 's' || stdcalcmode == 'o') return; if(sym == NOPLOT && forcesymmetry == 999) { plot = noplot; return; } /* NOTE: 16-bit potential disables symmetry */ /* also any decomp= option and any inversion not about the origin */ /* also any rotation other than 180deg and any off-axis stretch */ if(bf_math) if(cmp_bf(bfxmin,bfx3rd) || cmp_bf(bfymin,bfy3rd)) return; if ((potflag && pot16bit) || (invert && inversion[2] != 0.0) || decomp[0] != 0 || xxmin!=xx3rd || yymin!=yy3rd) return; if(sym != XAXIS && sym != XAXIS_NOPARM && inversion[1] != 0.0 && forcesymmetry == 999) return; if(forcesymmetry < 999) sym = forcesymmetry; else if(forcesymmetry == 1000) forcesymmetry = sym; /* for backwards compatibility */ else if(outside==REAL || outside==IMAG || outside==MULT || outside==SUM || outside==ATAN || bailoutest==Manr || outside==FMOD) return; else if(inside==FMODI || outside==TDIS) return; parmszero = (parm.x == 0.0 && parm.y == 0.0 && useinitorbit != 1); parmsnoreal = (parm.x == 0.0 && useinitorbit != 1); parmsnoimag = (parm.y == 0.0 && useinitorbit != 1); switch (fractype) { case LMANLAMFNFN: /* These need only P1 checked. */ case FPMANLAMFNFN: /* P2 is used for a switch value */ case LMANFNFN: /* These have NOPARM set in fractalp.c, */ case FPMANFNFN: /* but it only applies to P1. */ case FPMANDELZPOWER: /* or P2 is an exponent */ case LMANDELZPOWER: case FPMANZTOZPLUSZPWR: case MARKSMANDEL: case MARKSMANDELFP: case MARKSJULIA: case MARKSJULIAFP: break; case FORMULA: /* Check P2, P3, P4 and P5 */ case FFORMULA: parmszero = (parmszero && param[2] == 0.0 && param[3] == 0.0 && param[4] == 0.0 && param[5] == 0.0 && param[6] == 0.0 && param[7] == 0.0 && param[8] == 0.0 && param[9] == 0.0); parmsnoreal = (parmsnoreal && param[2] == 0.0 && param[4] == 0.0 && param[6] == 0.0 && param[8] == 0.0); parmsnoimag = (parmsnoimag && param[3] == 0.0 && param[5] == 0.0 && param[7] == 0.0 && param[9] == 0.0); break; default: /* Check P2 for the rest */ parmszero = (parmszero && parm2.x == 0.0 && parm2.y == 0.0); } xaxis_row = yaxis_col = -1; if(bf_math) { saved = save_stack(); bft1 = alloc_stack(rbflength+2); xaxis_on_screen = (sign_bf(bfymin) != sign_bf(bfymax)); yaxis_on_screen = (sign_bf(bfxmin) != sign_bf(bfxmax)); } else { xaxis_on_screen = (sign(yymin) != sign(yymax)); yaxis_on_screen = (sign(xxmin) != sign(xxmax)); } if (xaxis_on_screen) /* axis is on screen */ { if(bf_math) { /* ftemp = (0.0-yymax) / (yymin-yymax); */ sub_bf(bft1,bfymin,bfymax); div_bf(bft1,bfymax,bft1); neg_a_bf(bft1); ftemp = (double)bftofloat(bft1); } else ftemp = (0.0-yymax) / (yymin-yymax); ftemp *= (ydots-1); ftemp += 0.25; xaxis_row = (int)ftemp; xaxis_between = (ftemp - xaxis_row >= 0.5); if (uselist == 0 && (!xaxis_between || (xaxis_row+1)*2 != ydots)) xaxis_row = -1; /* can't split screen, so dead center or not at all */ } if (yaxis_on_screen) /* axis is on screen */ { if(bf_math) { /* ftemp = (0.0-xxmin) / (xxmax-xxmin); */ sub_bf(bft1,bfxmax,bfxmin); div_bf(bft1,bfxmin,bft1); neg_a_bf(bft1); ftemp = (double)bftofloat(bft1); } else ftemp = (0.0-xxmin) / (xxmax-xxmin); ftemp *= (xdots-1); ftemp += 0.25; yaxis_col = (int)ftemp; yaxis_between = (ftemp - yaxis_col >= 0.5); if (uselist == 0 && (!yaxis_between || (yaxis_col+1)*2 != xdots)) yaxis_col = -1; /* can't split screen, so dead center or not at all */ } switch(sym) /* symmetry switch */ { case XAXIS_NOREAL: /* X-axis Symmetry (no real param) */ if (!parmsnoreal) break; goto xsym; case XAXIS_NOIMAG: /* X-axis Symmetry (no imag param) */ if (!parmsnoimag) break; goto xsym; case XAXIS_NOPARM: /* X-axis Symmetry (no params)*/ if (!parmszero) break; xsym: case XAXIS: /* X-axis Symmetry */ if (xsym_split(xaxis_row,xaxis_between) == 0) { if(basin) plot = symplot2basin; else plot = symplot2; } break; case YAXIS_NOPARM: /* Y-axis Symmetry (No Parms)*/ if (!parmszero) break; case YAXIS: /* Y-axis Symmetry */ if (ysym_split(yaxis_col,yaxis_between) == 0) plot = symplot2Y; break; case XYAXIS_NOPARM: /* X-axis AND Y-axis Symmetry (no parms)*/ if(!parmszero) break; case XYAXIS: /* X-axis AND Y-axis Symmetry */ xsym_split(xaxis_row,xaxis_between); ysym_split(yaxis_col,yaxis_between); switch (worksym & 3) { case 1: /* just xaxis symmetry */ if(basin) plot = symplot2basin; else plot = symplot2 ; break; case 2: /* just yaxis symmetry */ if (basin) /* got no routine for this case */ { ixstop = xxstop; /* fix what split should not have done */ symmetry = 1; } else plot = symplot2Y; break; case 3: /* both axes */ if(basin) plot = symplot4basin; else plot = symplot4 ; } break; case ORIGIN_NOPARM: /* Origin Symmetry (no parms)*/ if (!parmszero) break; case ORIGIN: /* Origin Symmetry */ originsym: if ( xsym_split(xaxis_row,xaxis_between) == 0 && ysym_split(yaxis_col,yaxis_between) == 0) { plot = symplot2J; ixstop = xxstop; /* didn't want this changed */ } else { iystop = yystop; /* in case first split worked */ symmetry = 1; worksym = 0x30; /* let it recombine with others like it */ } break; case PI_SYM_NOPARM: if (!parmszero) break; case PI_SYM: /* PI symmetry */ if(bf_math) { if((double)bftofloat(abs_a_bf(sub_bf(bft1,bfxmax,bfxmin))) < PI/4) break; /* no point in pi symmetry if values too close */ } else { if(fabs(xxmax - xxmin) < PI/4) break; /* no point in pi symmetry if values too close */ } if(invert && forcesymmetry == 999) goto originsym; plot = symPIplot ; symmetry = 0; if ( xsym_split(xaxis_row,xaxis_between) == 0 && ysym_split(yaxis_col,yaxis_between) == 0) if(parm.y == 0.0) plot = symPIplot4J; /* both axes */ else plot = symPIplot2J; /* origin */ else { iystop = yystop; /* in case first split worked */ worksym = 0x30; /* don't mark pisym as ysym, just do it unmarked */ } if(bf_math) { sub_bf(bft1,bfxmax,bfxmin); abs_a_bf(bft1); pixelpi = (int)((PI/(double)bftofloat(bft1)*xdots)); /* PI in pixels */ } else pixelpi = (int)((PI/fabs(xxmax-xxmin))*xdots); /* PI in pixels */ if ( (ixstop = xxstart+pixelpi-1 ) > xxstop) ixstop = xxstop; if (plot == symPIplot4J && ixstop > (i = (xxstart+xxstop)/2)) ixstop = i; break; default: /* no symmetry */ break; } if(bf_math) restore_stack(saved); } #ifdef _MSC_VER #pragma optimize ("ea", on) #endif #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif /**************** tesseral method by CJLT begins here*********************/ /* reworked by PB for speed and resumeability */ struct tess { /* one of these per box to be done gets stacked */ int x1,x2,y1,y2; /* left/right top/bottom x/y coords */ int top,bot,lft,rgt; /* edge colors, -1 mixed, -2 unknown */ }; static int tesseral(void) { struct tess *tp; guessplot = (plot != putcolor && plot != symplot2); tp = (struct tess *)&dstack[0]; tp->x1 = ixstart; /* set up initial box */ tp->x2 = ixstop; tp->y1 = iystart; tp->y2 = iystop; if (workpass == 0) { /* not resuming */ tp->top = tessrow(ixstart,ixstop,iystart); /* Do top row */ tp->bot = tessrow(ixstart,ixstop,iystop); /* Do bottom row */ tp->lft = tesscol(ixstart,iystart+1,iystop-1); /* Do left column */ tp->rgt = tesscol(ixstop,iystart+1,iystop-1); /* Do right column */ if (check_key()) { /* interrupt before we got properly rolling */ add_worklist(xxstart,xxstop,xxstart,yystart,yystop,yystart,0,worksym); return(-1); } } else { /* resuming, rebuild work stack */ int i,mid,curx,cury,xsize,ysize; struct tess *tp2; tp->top = tp->bot = tp->lft = tp->rgt = -2; cury = yybegin & 0xfff; ysize = 1; i = (unsigned)yybegin >> 12; while (--i >= 0) ysize <<= 1; curx = workpass & 0xfff; xsize = 1; i = (unsigned)workpass >> 12; while (--i >= 0) xsize <<= 1; for(;;) { tp2 = tp; if (tp->x2 - tp->x1 > tp->y2 - tp->y1) { /* next divide down middle */ if (tp->x1 == curx && (tp->x2 - tp->x1 - 2) < xsize) break; mid = (tp->x1 + tp->x2) >> 1; /* Find mid point */ if (mid > curx) { /* stack right part */ memcpy(++tp,tp2,sizeof(*tp)); tp->x2 = mid; } tp2->x1 = mid; } else { /* next divide across */ if (tp->y1 == cury && (tp->y2 - tp->y1 - 2) < ysize) break; mid = (tp->y1 + tp->y2) >> 1; /* Find mid point */ if (mid > cury) { /* stack bottom part */ memcpy(++tp,tp2,sizeof(*tp)); tp->y2 = mid; } tp2->y1 = mid; } } } got_status = 4; /* for tab_display */ while (tp >= (struct tess *)&dstack[0]) { /* do next box */ curcol = tp->x1; /* for tab_display */ currow = tp->y1; if (tp->top == -1 || tp->bot == -1 || tp->lft == -1 || tp->rgt == -1) goto tess_split; /* for any edge whose color is unknown, set it */ if (tp->top == -2) tp->top = tesschkrow(tp->x1,tp->x2,tp->y1); if (tp->top == -1) goto tess_split; if (tp->bot == -2) tp->bot = tesschkrow(tp->x1,tp->x2,tp->y2); if (tp->bot != tp->top) goto tess_split; if (tp->lft == -2) tp->lft = tesschkcol(tp->x1,tp->y1,tp->y2); if (tp->lft != tp->top) goto tess_split; if (tp->rgt == -2) tp->rgt = tesschkcol(tp->x2,tp->y1,tp->y2); if (tp->rgt != tp->top) goto tess_split; { int mid,midcolor; if (tp->x2 - tp->x1 > tp->y2 - tp->y1) { /* divide down the middle */ mid = (tp->x1 + tp->x2) >> 1; /* Find mid point */ midcolor = tesscol(mid, tp->y1+1, tp->y2-1); /* Do mid column */ if (midcolor != tp->top) goto tess_split; } else { /* divide across the middle */ mid = (tp->y1 + tp->y2) >> 1; /* Find mid point */ midcolor = tessrow(tp->x1+1, tp->x2-1, mid); /* Do mid row */ if (midcolor != tp->top) goto tess_split; } } { /* all 4 edges are the same color, fill in */ int i,j; i = 0; if(fillcolor != 0) { if(fillcolor > 0) tp->top = fillcolor %colors; if (guessplot || (j = tp->x2 - tp->x1 - 1) < 2) { /* paint dots */ for (col = tp->x1 + 1; col < tp->x2; col++) for (row = tp->y1 + 1; row < tp->y2; row++) { (*plot)(col,row,tp->top); if (++i > 500) { if (check_key()) goto tess_end; i = 0; } } } else { /* use put_line for speed */ memset(&dstack[OLDMAXPIXELS],tp->top,j); for (row = tp->y1 + 1; row < tp->y2; row++) { put_line(row,tp->x1+1,tp->x2-1,&dstack[OLDMAXPIXELS]); if (plot != putcolor) /* symmetry */ if ((j = yystop-(row-yystart)) > iystop && j < ydots) put_line(j,tp->x1+1,tp->x2-1,&dstack[OLDMAXPIXELS]); if (++i > 25) { if (check_key()) goto tess_end; i = 0; } } } } --tp; } continue; tess_split: { /* box not surrounded by same color, sub-divide */ int mid,midcolor; struct tess *tp2; if (tp->x2 - tp->x1 > tp->y2 - tp->y1) { /* divide down the middle */ mid = (tp->x1 + tp->x2) >> 1; /* Find mid point */ midcolor = tesscol(mid, tp->y1+1, tp->y2-1); /* Do mid column */ if (midcolor == -3) goto tess_end; if (tp->x2 - mid > 1) { /* right part >= 1 column */ if (tp->top == -1) tp->top = -2; if (tp->bot == -1) tp->bot = -2; tp2 = tp; if (mid - tp->x1 > 1) { /* left part >= 1 col, stack right */ memcpy(++tp,tp2,sizeof(*tp)); tp->x2 = mid; tp->rgt = midcolor; } tp2->x1 = mid; tp2->lft = midcolor; } else --tp; } else { /* divide across the middle */ mid = (tp->y1 + tp->y2) >> 1; /* Find mid point */ midcolor = tessrow(tp->x1+1, tp->x2-1, mid); /* Do mid row */ if (midcolor == -3) goto tess_end; if (tp->y2 - mid > 1) { /* bottom part >= 1 column */ if (tp->lft == -1) tp->lft = -2; if (tp->rgt == -1) tp->rgt = -2; tp2 = tp; if (mid - tp->y1 > 1) { /* top also >= 1 col, stack bottom */ memcpy(++tp,tp2,sizeof(*tp)); tp->y2 = mid; tp->bot = midcolor; } tp2->y1 = mid; tp2->top = midcolor; } else --tp; } } } tess_end: if (tp >= (struct tess *)&dstack[0]) { /* didn't complete */ int i,xsize,ysize; xsize = ysize = 1; i = 2; while (tp->x2 - tp->x1 - 2 >= i) { i <<= 1; ++xsize; } i = 2; while (tp->y2 - tp->y1 - 2 >= i) { i <<= 1; ++ysize; } add_worklist(xxstart,xxstop,xxstart,yystart,yystop, (ysize<<12)+tp->y1,(xsize<<12)+tp->x1,worksym); return(-1); } return(0); } /* tesseral */ static int _fastcall tesschkcol(int x,int y1,int y2) { int i; i = getcolor(x,++y1); while (--y2 > y1) if (getcolor(x,y2) != i) return -1; return i; } static int _fastcall tesschkrow(int x1,int x2,int y) { int i; i = getcolor(x1,y); while (x2 > x1) { if (getcolor(x2,y) != i) return -1; --x2; } return i; } static int _fastcall tesscol(int x,int y1,int y2) { int colcolor,i; col = x; row = y1; reset_periodicity = 1; colcolor = (*calctype)(); reset_periodicity = 0; while (++row <= y2) { /* generate the column */ if ((i = (*calctype)()) < 0) return -3; if (i != colcolor) colcolor = -1; } return colcolor; } static int _fastcall tessrow(int x1,int x2,int y) { int rowcolor,i; row = y; col = x1; reset_periodicity = 1; rowcolor = (*calctype)(); reset_periodicity = 0; while (++col <= x2) { /* generate the row */ if ((i = (*calctype)()) < 0) return -3; if (i != rowcolor) rowcolor = -1; } return rowcolor; } /* added for testing autologmap() */ /* CAE 9211 fixed missing comment */ /* insert at end of CALCFRAC.C */ static long autologmap(void) /*RB*/ { /* calculate round screen edges to avoid wasted colours in logmap */ long mincolour; int lag; int xstop = xdots - 1; /* don't use symetry */ int ystop = ydots - 1; /* don't use symetry */ long old_maxit; mincolour=LONG_MAX; row=0; reset_periodicity = 0; old_maxit = maxit; for (col=0;col=32 ) (*plot)(col-32,row,0); } /* these lines tidy up for BTM etc */ for (lag=32;lag>0;lag--) (*plot)(col-lag,row,0); col=xstop; for (row=0;row=32 ) (*plot)(col,row-32,0); } for (lag=32;lag>0;lag--) (*plot)(col,row-lag,0); col=0; for (row=0;row=32 ) (*plot)(col,row-32,0); } for (lag=32;lag>0;lag--) (*plot)(col,row-lag,0); row=ystop ; for (col=0;col=32 ) (*plot)(col-32,row,0); } for (lag=32;lag>0;lag--) (*plot)(col-lag,row,0); ack: /* bailout here if key is pressed */ if (mincolour==2) resuming=1; /* insure autologmap not called again */ maxit = old_maxit; return ( mincolour ); } /* Symmetry plot for period PI */ void _fastcall symPIplot(int x, int y, int color) { while(x <= xxstop) { putcolor(x, y, color) ; x += pixelpi; } } /* Symmetry plot for period PI plus Origin Symmetry */ void _fastcall symPIplot2J(int x, int y, int color) { int i,j; while(x <= xxstop) { putcolor(x, y, color) ; if ((i=yystop-(y-yystart)) > iystop && i < ydots && (j=xxstop-(x-xxstart)) < xdots) putcolor(j, i, color) ; x += pixelpi; } } /* Symmetry plot for period PI plus Both Axis Symmetry */ void _fastcall symPIplot4J(int x, int y, int color) { int i,j; while(x <= (xxstart+xxstop)/2) { j = xxstop-(x-xxstart); putcolor( x , y , color) ; if (j < xdots) putcolor(j , y , color) ; if ((i=yystop-(y-yystart)) > iystop && i < ydots) { putcolor(x , i , color) ; if (j < xdots) putcolor(j , i , color) ; } x += pixelpi; } } /* Symmetry plot for X Axis Symmetry */ void _fastcall symplot2(int x, int y, int color) { int i; putcolor(x, y, color) ; if ((i=yystop-(y-yystart)) > iystop && i < ydots) putcolor(x, i, color) ; } /* Symmetry plot for Y Axis Symmetry */ void _fastcall symplot2Y(int x, int y, int color) { int i; putcolor(x, y, color) ; if ((i=xxstop-(x-xxstart)) < xdots) putcolor(i, y, color) ; } /* Symmetry plot for Origin Symmetry */ void _fastcall symplot2J(int x, int y, int color) { int i,j; putcolor(x, y, color) ; if ((i=yystop-(y-yystart)) > iystop && i < ydots && (j=xxstop-(x-xxstart)) < xdots) putcolor(j, i, color) ; } /* Symmetry plot for Both Axis Symmetry */ void _fastcall symplot4(int x, int y, int color) { int i,j; j = xxstop-(x-xxstart); putcolor( x , y, color) ; if (j < xdots) putcolor( j , y, color) ; if ((i=yystop-(y-yystart)) > iystop && i < ydots) { putcolor( x , i, color) ; if (j < xdots) putcolor(j , i, color) ; } } /* Symmetry plot for X Axis Symmetry - Striped Newtbasin version */ void _fastcall symplot2basin(int x, int y, int color) { int i,stripe; putcolor(x, y, color) ; if(basin==2 && color > 8) stripe=8; else stripe = 0; if ((i=yystop-(y-yystart)) > iystop && i < ydots) { color -= stripe; /* reconstruct unstriped color */ color = (degree+1-color)%degree+1; /* symmetrical color */ color += stripe; /* add stripe */ putcolor(x, i,color) ; } } /* Symmetry plot for Both Axis Symmetry - Newtbasin version */ void _fastcall symplot4basin(int x, int y, int color) { int i,j,color1,stripe; if(color == 0) /* assumed to be "inside" color */ { symplot4(x, y, color); return; } if(basin==2 && color > 8) stripe = 8; else stripe = 0; color -= stripe; /* reconstruct unstriped color */ color1 = degree/2+degree+2 - color; if(color < degree/2+2) color1 = degree/2+2 - color; else color1 = degree/2+degree+2 - color; j = xxstop-(x-xxstart); putcolor( x, y, color+stripe) ; if (j < xdots) putcolor( j, y, color1+stripe) ; if ((i=yystop-(y-yystart)) > iystop && i < ydots) { putcolor( x, i, stripe + (degree+1 - color)%degree+1) ; if (j < xdots) putcolor(j, i, stripe + (degree+1 - color1)%degree+1) ; } } static void _fastcall puttruecolor_disk(int x, int y, int color) { putcolor_a(x,y,color); targa_color(x, y, color); /* writedisk(x*=3,y,(BYTE)((realcoloriter ) & 0xff)); */ /* blue */ /* writedisk(++x, y,(BYTE)((realcoloriter >> 8 ) & 0xff)); */ /* green */ /* writedisk(x+1, y,(BYTE)((realcoloriter >> 16) & 0xff)); */ /* red */ } /* Do nothing plot!!! */ #ifdef __CLINT__ #pragma argsused #endif void _fastcall noplot(int x,int y,int color) { x = y = color = 0; /* just for warning */ } xfractint-20.4.10.orig/common/jb.c0000644000000000000000000002625610150633601013542 0ustar /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #include "fractype.h" /* these need to be accessed elsewhere for saving data */ double mxminfp = -.83; double myminfp = -.25; double mxmaxfp = -.83; double mymaxfp = .25; static long mxmin, mymin; static long x_per_inch, y_per_inch, inch_per_xdot, inch_per_ydot; static double x_per_inchfp, y_per_inchfp, inch_per_xdotfp, inch_per_ydotfp; static int bbase; static long xpixel, ypixel; static double xpixelfp, ypixelfp; static long initz, djx, djy, dmx, dmy; static double initzfp, djxfp, djyfp, dmxfp, dmyfp; static long jx, jy, mx, my, xoffset, yoffset; static double jxfp, jyfp, mxfp, myfp, xoffsetfp, yoffsetfp; struct Perspective { long x, y, zx, zy; }; struct Perspectivefp { double x, y, zx, zy; }; struct Perspective LeftEye, RightEye, *Per; struct Perspectivefp LeftEyefp, RightEyefp, *Perfp; _LCMPLX jbc; _CMPLX jbcfp; #ifndef XFRACT static double fg, fg16; #endif int zdots = 128; float originfp = (float)8.0; float heightfp = (float)7.0; float widthfp = (float)10.0; float distfp = (float)24.0; float eyesfp = (float)2.5; float depthfp = (float)8.0; float brratiofp = (float)1.0; static long width, dist, depth, brratio; #ifndef XFRACT static long eyes; #endif int juli3Dmode = 0; int neworbittype = JULIA; int JulibrotSetup(void) { #ifndef XFRACT long origin; #endif int r = 0; char *mapname; #ifndef XFRACT if (colors < 255) { static FCODE msg[] = {"Sorry, but Julibrots require a 256-color video mode"}; stopmsg(0, msg); return (0); } #endif xoffsetfp = (xxmax + xxmin) / 2; /* Calculate average */ yoffsetfp = (yymax + yymin) / 2; /* Calculate average */ dmxfp = (mxmaxfp - mxminfp) / zdots; dmyfp = (mymaxfp - myminfp) / zdots; floatparm = &jbcfp; x_per_inchfp = (xxmin - xxmax) / widthfp; y_per_inchfp = (yymax - yymin) / heightfp; inch_per_xdotfp = widthfp / xdots; inch_per_ydotfp = heightfp / ydots; initzfp = originfp - (depthfp / 2); if(juli3Dmode == 0) RightEyefp.x = 0.0; else RightEyefp.x = eyesfp / 2; LeftEyefp.x = -RightEyefp.x; LeftEyefp.y = RightEyefp.y = 0; LeftEyefp.zx = RightEyefp.zx = distfp; LeftEyefp.zy = RightEyefp.zy = distfp; bbase = 128; #ifndef XFRACT if (fractalspecific[fractype].isinteger > 0) { long jxmin, jxmax, jymin, jymax, mxmax, mymax; if (fractalspecific[neworbittype].isinteger == 0) { static FCODE msg[] = {"Julibrot orbit type isinteger mismatch"}; stopmsg(0, (char far *)msg); } if (fractalspecific[neworbittype].isinteger > 1) bitshift = fractalspecific[neworbittype].isinteger; fg = (double) (1L << bitshift); fg16 = (double) (1L << 16); jxmin = (long) (xxmin * fg); jxmax = (long) (xxmax * fg); xoffset = (jxmax + jxmin) / 2; /* Calculate average */ jymin = (long) (yymin * fg); jymax = (long) (yymax * fg); yoffset = (jymax + jymin) / 2; /* Calculate average */ mxmin = (long) (mxminfp * fg); mxmax = (long) (mxmaxfp * fg); mymin = (long) (myminfp * fg); mymax = (long) (mymaxfp * fg); origin = (long) (originfp * fg16); depth = (long) (depthfp * fg16); width = (long) (widthfp * fg16); dist = (long) (distfp * fg16); eyes = (long) (eyesfp * fg16); brratio = (long) (brratiofp * fg16); dmx = (mxmax - mxmin) / zdots; dmy = (mymax - mymin) / zdots; longparm = &jbc; x_per_inch = (long) ((xxmin - xxmax) / widthfp * fg); y_per_inch = (long) ((yymax - yymin) / heightfp * fg); inch_per_xdot = (long) ((widthfp / xdots) * fg16); inch_per_ydot = (long) ((heightfp / ydots) * fg16); initz = origin - (depth / 2); if(juli3Dmode == 0) RightEye.x = 0l; else RightEye.x = eyes / 2; LeftEye.x = -RightEye.x; LeftEye.y = RightEye.y = 0l; LeftEye.zx = RightEye.zx = dist; LeftEye.zy = RightEye.zy = dist; bbase = (int) (128.0 * brratiofp); } #endif if (juli3Dmode == 3) { savedac = 0; mapname = Glasses1Map; } else mapname = GreyFile; if(savedac != 1) { if (ValidateLuts(mapname) != 0) return (0); spindac(0, 1); /* load it, but don't spin */ if(savedac == 2) savedac = 1; } return (r >= 0); } int jb_per_pixel(void) { jx = multiply(Per->x - xpixel, initz, 16); jx = divide(jx, dist, 16) - xpixel; jx = multiply(jx << (bitshift - 16), x_per_inch, bitshift); jx += xoffset; djx = divide(depth, dist, 16); djx = multiply(djx, Per->x - xpixel, 16) << (bitshift - 16); djx = multiply(djx, x_per_inch, bitshift) / zdots; jy = multiply(Per->y - ypixel, initz, 16); jy = divide(jy, dist, 16) - ypixel; jy = multiply(jy << (bitshift - 16), y_per_inch, bitshift); jy += yoffset; djy = divide(depth, dist, 16); djy = multiply(djy, Per->y - ypixel, 16) << (bitshift - 16); djy = multiply(djy, y_per_inch, bitshift) / zdots; return (1); } int jbfp_per_pixel(void) { jxfp = ((Perfp->x - xpixelfp) * initzfp / distfp - xpixelfp) * x_per_inchfp; jxfp += xoffsetfp; djxfp = (depthfp / distfp) * (Perfp->x - xpixelfp) * x_per_inchfp / zdots; jyfp = ((Perfp->y - ypixelfp) * initzfp / distfp - ypixelfp) * y_per_inchfp; jyfp += yoffsetfp; djyfp = depthfp / distfp * (Perfp->y - ypixelfp) * y_per_inchfp / zdots; return (1); } static int zpixel, plotted; static long n; int zline(long x, long y) { xpixel = x; ypixel = y; mx = mxmin; my = mymin; switch(juli3Dmode) { case 0: case 1: Per = &LeftEye; break; case 2: Per = &RightEye; break; case 3: if ((row + col) & 1) Per = &LeftEye; else Per = &RightEye; break; } jb_per_pixel(); for (zpixel = 0; zpixel < zdots; zpixel++) { lold.x = jx; lold.y = jy; jbc.x = mx; jbc.y = my; if (keypressed()) return (-1); ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); for (n = 0; n < maxit; n++) if (fractalspecific[neworbittype].orbitcalc()) break; if (n == maxit) { if (juli3Dmode==3) { color = (int) (128l * zpixel / zdots); if ((row + col) & 1) { (*plot) (col, row, 127 - color); } else { color = (int) (multiply((long) color << 16, brratio, 16) >> 16); if (color < 1) color = 1; if (color > 127) color = 127; (*plot) (col, row, 127 + bbase - color); } } else { color = (int) (254l * zpixel / zdots); (*plot) (col, row, color + 1); } plotted = 1; break; } mx += dmx; my += dmy; jx += djx; jy += djy; } return (0); } int zlinefp(double x, double y) { #ifdef XFRACT static int keychk = 0; #endif xpixelfp = x; ypixelfp = y; mxfp = mxminfp; myfp = myminfp; switch(juli3Dmode) { case 0: case 1: Perfp = &LeftEyefp; break; case 2: Perfp = &RightEyefp; break; case 3: if ((row + col) & 1) Perfp = &LeftEyefp; else Perfp = &RightEyefp; break; } jbfp_per_pixel(); for (zpixel = 0; zpixel < zdots; zpixel++) { /* Special initialization for Mandelbrot types */ if ((neworbittype == QUATFP || neworbittype == HYPERCMPLXFP) && save_release > 2002) { old.x = 0.0; old.y = 0.0; jbcfp.x = 0.0; jbcfp.y = 0.0; qc = jxfp; qci = jyfp; qcj = mxfp; qck = myfp; } else { old.x = jxfp; old.y = jyfp; jbcfp.x = mxfp; jbcfp.y = myfp; qc = param[0]; qci = param[1]; qcj = param[2]; qck = param[3]; } #ifdef XFRACT if (keychk++ > 500) { keychk = 0; if (keypressed()) return (-1); } #else if (keypressed()) return (-1); #endif tempsqrx = sqr(old.x); tempsqry = sqr(old.y); for (n = 0; n < maxit; n++) if (fractalspecific[neworbittype].orbitcalc()) break; if (n == maxit) { if (juli3Dmode == 3) { color = (int) (128l * zpixel / zdots); if ((row + col) & 1) (*plot) (col, row, 127 - color); else { color = (int)(color * brratiofp); if (color < 1) color = 1; if (color > 127) color = 127; (*plot) (col, row, 127 + bbase - color); } } else { color = (int) (254l * zpixel / zdots); (*plot) (col, row, color + 1); } plotted = 1; break; } mxfp += dmxfp; myfp += dmyfp; jxfp += djxfp; jyfp += djyfp; } return (0); } int Std4dFractal(void) { long x, y; int xdot, ydot; c_exp = (int)param[2]; if(neworbittype == LJULIAZPOWER) { if(c_exp < 1) c_exp = 1; if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2]) fractalspecific[neworbittype].orbitcalc = longZpowerFractal; else fractalspecific[neworbittype].orbitcalc = longCmplxZpowerFractal; } for (y = 0, ydot = (ydots >> 1) - 1; ydot >= 0; ydot--, y -= inch_per_ydot) { plotted = 0; x = -(width >> 1); for (xdot = 0; xdot < xdots; xdot++, x += inch_per_xdot) { col = xdot; row = ydot; if (zline(x, y) < 0) return (-1); col = xdots - col - 1; row = ydots - row - 1; if (zline(-x, -y) < 0) return (-1); } if (plotted == 0) { if (y == 0) plotted = -1; /* no points first pass; don't give up */ else break; } } return (0); } int Std4dfpFractal(void) { double x, y; int xdot, ydot; c_exp = (int)param[2]; if(neworbittype == FPJULIAZPOWER) { if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2]) fractalspecific[neworbittype].orbitcalc = floatZpowerFractal; else fractalspecific[neworbittype].orbitcalc = floatCmplxZpowerFractal; get_julia_attractor (param[0], param[1]); /* another attractor? */ } for (y = 0, ydot = (ydots >> 1) - 1; ydot >= 0; ydot--, y -= inch_per_ydotfp) { plotted = 0; x = -widthfp / 2; for (xdot = 0; xdot < xdots; xdot++, x += inch_per_xdotfp) { col = xdot; row = ydot; if (zlinefp(x, y) < 0) return (-1); col = xdots - col - 1; row = ydots - row - 1; if (zlinefp(-x, -y) < 0) return (-1); } if (plotted == 0) { if (y == 0) plotted = -1; /* no points first pass; don't give up */ else break; } } return (0); } xfractint-20.4.10.orig/common/printer.c0000644000000000000000000021006111257714555014640 0ustar /* Printer.c * Simple screen printing functions for FRACTINT * By Matt Saucier CIS: [72371,3101] 7/2/89 * "True-to-the-spirit" of FRACTINT, this code makes few checks that you * have specified a valid resolution for the printer (just in case yours * has more dots/line than the Standard HP and IBM/EPSON, * (eg, Wide Carriage, etc.)) * * PostScript support by Scott Taylor [72401,410] / (DGWM18A) 10/8/90 * For PostScript, use 'printer=PostScript/resolution' where resolution * is ANY NUMBER between 10 and 600. Common values: 300,150,100,75. * Default resolution for PostScript is 150 pixels/inch. * At 200 DPI, a fractal that is 640x480 prints as a 3.2"x2.4" picture. * PostScript printer names: * * PostScript/PS = Portrait printing * PostScriptH/PostScriptL/PSH/PSL = Landscape printing * * This code supports printers attached to a LPTx (1-3) parallel port. * It also now supports serial printers AFTER THEY ARE CONFIGURED AND * WORKING WITH THE DOS MODE COMMAND, eg. MODE COM1:9600,n,8,1 (for HP) * (NOW you can also configure the serial port with the comport= command) * Printing calls are made directly to the BIOS for DOS can't handle fast * transfer of data to the HP. (Or maybe visa-versa, HP can't handle the * slow transfer of data from DOS) * * I just added direct port access for COM1 and COM2 **ONLY**. This method * does a little more testing than BIOS, and may work (especially on * serial printer sharing devices) where the old method doesn't. I noticed * maybe a 5% speed increase at 9600 baud. These are selected in the * printer=.../.../31 for COM1 or 32 for COM2. * * I also added direct parallel port access for LPT1 and LPT2 **ONLY**. * This toggles the "INIT" line of the parallel port to reset the printer * for each print session. It will also WAIT for a error / out of paper / * not selected condition instead of quitting with an error. * * Supported Printers: Tested Ok: * HP LaserJet * LJ+,LJII MDS * Toshiba PageLaser MDS (Set FRACTINT to use HP) * IBM Graphics MDS * EPSON * Models? Untested. * IBM LaserPrinter * with PostScript SWT * HP Plotter SWT * * Future support to include OKI 20 (color) printer, and just about * any printer you request. * * Future modifications to include a more flexible, standard interface * with the surrounding program, for easier portability to other * programs. * * PostScript Styles: * 0 Dot * 1 Dot* [Smoother] * 2 Inverted Dot * 3 Ring * 4 Inverted Ring * 5 Triangle [45-45-90] * 6 Triangle* [30-75-75] * 7 Grid * 8 Diamond * 9 Line * 10 Microwaves * 11 Ellipse * 12 RoundBox * 13 Custom * 14 Star * 15 Random * 16 Line* [Not much different] * * * Alternate style * */ #ifndef XFRACT #include #include #endif #include #include #include #ifndef XFRACT #include #endif #ifndef USE_VARARGS #include #else #include #endif #ifdef XFRACT extern char *PSviewer; #endif #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /* macros for near-space-saving purposes */ /* CAE 9211 changed these for BC++ */ #define PRINTER_PRINTF1(X) {\ static FCODE tmp[] = X;\ Printer_printf(tmp);\ } #define PRINTER_PRINTF2(X,Y) {\ static FCODE tmp[] = X;\ Printer_printf(tmp,(Y));\ } #define PRINTER_PRINTF3(X,Y,Z) {\ static FCODE tmp[] = X;\ Printer_printf(tmp,(Y),(Z));\ } #define PRINTER_PRINTF4(X,Y,Z,W) {\ static FCODE tmp[] = X;\ Printer_printf(tmp,(Y),(Z),(W));\ } #define PRINTER_PRINTF5(X,Y,Z,W,V) {\ static FCODE tmp[] = X;\ Printer_printf(tmp,(Y),(Z),(W),(V));\ } #define PRINTER_PRINTF6(X,Y,Z,W,V,U) {\ static FCODE tmp[] = X;\ Printer_printf(tmp,(Y),(Z),(W),(V),(U));\ } #define PRINTER_PRINTF7(X,Y,Z,W,V,U,T) {\ static FCODE tmp[] = X;\ Printer_printf(tmp,(Y),(Z),(W),(V),(U),(T));\ } /******** PROTOTYPES ********/ #ifndef USE_VARARGS static void Printer_printf(char far *fmt,...); #else static void Printer_printf(); #endif static int _fastcall printer(int c); static void _fastcall print_title(int,int,char *); static void printer_reset(void); static void rleprolog(int x,int y); static void _fastcall graphics_init(int,int,char *); /******** GLOBALS ********/ int Printer_Resolution, /* 75,100,150,300 for HP; */ /* 60,120,240 for IBM; */ /* 90 or 180 for the PaintJet; */ /* 10-600 for PS */ /* 1-20 for Plotter */ LPTNumber, /* ==1,2,3 LPTx; or 11,12,13,14 for COM1-4 */ /* 21,22 for direct port access for LPT1-2 */ /* 31,32 for direct port access for COM1-2 */ Printer_Type, /* ==1 HP, ==2 IBM/EPSON, ==3 Epson color, ==4 HP PaintJet, ==5,6 PostScript, ==7 HP Plotter */ Printer_Titleblock, /* Print info about the fractal? */ Printer_Compress, /* PostScript only - rle encode output */ Printer_ColorXlat, /* PostScript only - invert colors */ Printer_SetScreen, /* PostScript only - reprogram halftone ? */ Printer_SFrequency, /* PostScript only - Halftone Frequency K */ Printer_SAngle, /* PostScript only - Halftone angle K */ Printer_SStyle, /* PostScript only - Halftone style K */ Printer_RFrequency, /* PostScript only - Halftone Frequency R */ Printer_RAngle, /* PostScript only - Halftone angle R */ Printer_RStyle, /* PostScript only - Halftone style R */ Printer_GFrequency, /* PostScript only - Halftone Frequency G */ Printer_GAngle, /* PostScript only - Halftone angle G */ Printer_GStyle, /* PostScript only - Halftone style G */ Printer_BFrequency, /* PostScript only - Halftone Frequency B */ Printer_BAngle, /* PostScript only - Halftone angle B */ Printer_BStyle, /* PostScript only - Halftone style B */ Print_To_File, /* Print to file toggle */ EPSFileType, /* EPSFileType - 1 = well-behaved, 2 = much less behaved, 3 = not well behaved */ Printer_CRLF, /* (0) CRLF (1) CR (2) LF */ ColorPS; /* (0) B&W (1) Color */ int pj_width; double ci,ck; static int repeat, item, count, repeatitem, itembuf[128], rlebitsperitem, rlebitshift, bitspersample, rleitem, repeatcount, itemsperline, items, /* bitsperitem, */ bitshift2; /* * The tables were copied from Lee Crocker's PGIF program, with * the 8 undithered colors moved to the first 8 table slots. * * This file contains various lookup tables used by PJGIF. Patterns contains * unsigned values representing each of the 330 HP PaintJet colors. Each color * at 90 DPI is composed of four dots in 8 colors. Each hex digit of these * unsigned values represents one of the four dots. Although the PaintJet will * produce these patterns automatically in 90 DPI mode, it is much faster to do * it in software with the PaintJet in 8-color 180 DPI mode. * * 920501 Hans Wolfgang Schulze converted from printera.asm for xfractint. * (hans@garfield.metal2.polymtl.ca) */ static UIFCODE pj_patterns [] = { 0x7777,0x0000,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666, 0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 0x0110,0x0120,0x0130,0x0140,0x0150,0x0160,0x0170,0x0220, 0x0230,0x0240,0x0250,0x0260,0x0270,0x0330,0x0340,0x0350, 0x0360,0x0370,0x0440,0x0450,0x0460,0x0470,0x0550,0x0560, 0x0570,0x0660,0x0670,0x0770,0x0111,0x0112,0x0113,0x0114, 0x0115,0x0116,0x0117,0x2012,0x0123,0x0124,0x0125,0x0126, 0x0127,0x3013,0x0134,0x0135,0x0136,0x0137,0x4014,0x0145, 0x0146,0x0147,0x5015,0x0156,0x0157,0x6016,0x0167,0x7017, 0x0222,0x0223,0x0224,0x0225,0x0226,0x0227,0x3023,0x0234, 0x0235,0x0236,0x0237,0x4024,0x0245,0x0246,0x0247,0x5025, 0x0256,0x0257,0x6026,0x0267,0x7027,0x0333,0x0334,0x0335, 0x0336,0x0337,0x4034,0x0345,0x0346,0x0347,0x5035,0x0356, 0x0357,0x6036,0x0367,0x7037,0x0444,0x0445,0x0446,0x0447, 0x5045,0x0456,0x0457,0x6046,0x0467,0x7047,0x0555,0x0556, 0x0557,0x6056,0x0567,0x7057,0x0666,0x0667,0x7067,0x0777, 0x1112,0x1113,0x1114,0x1115,0x1116,0x1117,0x2112, 0x1123,0x2114,0x2115,0x2116,0x2117,0x3113,0x3114,0x3115, 0x3116,0x3117,0x4114,0x4115,0x4116,0x4117,0x5115,0x5116, 0x5117,0x6116,0x6117,0x7117,0x1222,0x1223,0x1224,0x1225, 0x1226,0x1227,0x3123,0x1234,0x1235,0x1236,0x1237,0x4124, 0x1245,0x1246,0x1247,0x5125,0x1256,0x1257,0x6126,0x1267, 0x7127,0x1333,0x1334,0x1335,0x1336,0x1337,0x4134,0x1345, 0x1346,0x1347,0x5135,0x1356,0x1357,0x6136,0x1367,0x7137, 0x1444,0x1445,0x1446,0x1447,0x5145,0x1456,0x1457,0x6146, 0x1467,0x7147,0x1555,0x1556,0x1557,0x6156,0x1567,0x7157, 0x1666,0x1667,0x7167,0x1777, 0x2223,0x2224,0x2225, 0x2226,0x2227,0x3223,0x3224,0x3225,0x3226,0x3227,0x4224, 0x4225,0x4226,0x4227,0x5225,0x5226,0x5227,0x6226,0x6227, 0x7227,0x2333,0x2334,0x2335,0x2336,0x2337,0x4234,0x2345, 0x2346,0x2347,0x5235,0x2356,0x2357,0x6236,0x2367,0x7237, 0x2444,0x2445,0x2446,0x2447,0x5245,0x2456,0x2457,0x6246, 0x2467,0x7247,0x2555,0x2556,0x2557,0x6256,0x2567,0x7257, 0x2666,0x2667,0x7267,0x2777, 0x3334,0x3335,0x3336, 0x3337,0x4334,0x4335,0x4336,0x4337,0x5335,0x5336,0x5337, 0x6336,0x6337,0x7337,0x3444,0x3445,0x3446,0x3447,0x5345, 0x3456,0x3457,0x6346,0x3467,0x7347,0x3555,0x3556,0x3557, 0x6356,0x3567,0x7357,0x3666,0x3667,0x7367,0x3777, 0x4445,0x4446,0x4447,0x5445,0x5446,0x5447,0x6446,0x6447, 0x7447,0x4555,0x4556,0x4557,0x6456,0x4567,0x7457,0x4666, 0x4667,0x7467,0x4777, 0x5556,0x5557,0x6556,0x6557, 0x7557,0x5666,0x5667,0x7567,0x5777, 0x6667,0x7667, 0x6777}; /* * The 3 tables below contain the red, green, and blue values (on a scale of * 0..255) of each of the 330 PaintJet colors. These values are based on data * generously provided by HP customer service. * 11 <- changed black's value from this, seemed wrong * 135 <- changed red's value from this * 11 <- changed blue's value from this */ #ifndef XFRACT static BFCODE pj_reds[] = { 229, 2,145, 7,227, 9,136, 5, 17, 10, 17, 10, 16, 10, 16, 29, 16, 32, 15, 30, 15, 31, 9, 15, 10, 15, 9, 13, 37, 15, 32, 16, 36, 10, 15, 9, 13, 30, 15, 31, 8, 13, 38, 62, 26, 68, 26, 63, 26, 68, 16, 35, 16, 33, 16, 33, 77, 26, 69, 29, 77, 16, 31, 16, 31, 64, 27, 71, 16, 36, 81, 9, 15, 10, 15, 8, 13, 37, 15, 31, 15, 33, 10, 15, 9, 13, 29, 15, 28, 8, 12, 28, 98, 28, 79, 32, 94, 16, 34, 17, 35, 73, 30, 82, 17, 43,101, 11, 15, 10, 13, 29, 15, 27, 9, 13, 25, 65, 27, 71, 16, 35, 88, 7, 12, 39,110, 54,146, 53,136, 58,144, 29, 57, 28, 53, 29, 56,159, 54,144, 61,160, 27, 51, 28, 52,135, 55, 144, 30, 60,159, 14, 23, 15, 22, 14, 21, 64, 30, 58, 32, 64, 15, 22, 15, 21, 54, 31, 56, 14, 22, 64,185, 59,160, 69,185, 29, 57, 31, 60,145, 63,162, 33, 71,186, 15, 22, 16, 21, 50, 30, 52, 15, 21, 54,134, 58,145, 30, 60,161, 15, 22, 69,187, 13, 9, 14, 6, 11, 31, 14, 27, 12, 27, 10, 14, 9, 12, 24, 9, 23, 6, 9, 22, 76, 23, 61, 25, 74, 15, 29, 14, 28, 55, 23, 62, 12, 30, 73, 11, 15, 10, 12, 25, 14, 23, 8, 11, 20, 50, 22, 53, 13, 26, 61, 5, 8, 21, 71, 71,189, 87,227, 30, 63, 32, 69,164, 76,190, 37, 89,227, 15, 22, 14, 20, 54, 31, 57, 14, 21, 63,147, 67,163, 33, 72,191, 13, 24, 94,228, 15, 10, 13, 26, 14, 23, 10, 13, 20, 50, 23, 50, 15, 26, 52, 8, 11, 23, 65, 60,147, 32, 67, 166, 14, 24, 77,194, 8, 32, 97}; /* * 11 <- changed black's value from this, seemed wrong * 65 <- changed green from this */ static BFCODE pj_greens[] = { 224, 2, 20, 72,211, 10, 11, 55, 12, 15, 19, 11, 11, 14, 17, 14, 18, 22, 12, 13, 16, 19, 24, 29, 16, 17, 23, 27, 41, 17, 22, 29, 39, 11, 10, 14, 14, 11, 14, 17, 21, 25, 40, 16, 21, 28, 14, 16, 19, 25, 28, 37, 18, 20, 26, 33, 48, 20, 26, 33, 46, 13, 12, 16, 18, 14, 18, 22, 24, 30, 42, 40, 49, 25, 27, 39, 50, 69, 27, 33, 48, 66, 17, 17, 24, 27, 19, 28, 35, 38, 48, 68,100, 32, 46, 65, 98, 18, 22, 29, 36, 27, 39, 54, 49, 71,105, 11, 10, 14, 12, 10, 14, 13, 20, 20, 25, 11, 15, 18, 22, 29, 49, 36, 46, 69,111, 23, 31, 16, 19, 22, 28, 30, 37, 20, 22, 28, 34, 54, 22, 29, 36, 53, 14, 15, 17, 19, 17, 19, 26, 25, 32, 46, 43, 50, 27, 28, 41, 49, 68, 29, 37, 51, 68, 19, 19, 25, 28, 22, 30, 36, 40, 47, 66,104, 35, 51, 68,105, 20, 24, 31, 37, 30, 38, 56, 50, 69,103, 13, 12, 15, 14, 13, 15, 16, 21, 21, 26, 14, 16, 22, 23, 28, 44, 35, 42, 62,102, 78, 40, 44, 65, 78, 98, 43, 53, 76, 99, 26, 27, 36, 40, 29, 43, 50, 63, 75, 99,136, 49, 69, 98,142, 28, 32, 42, 51, 39, 52, 73, 77,103,145, 17, 17, 21, 21, 18, 22, 24, 34, 37, 43, 19, 23, 30, 40, 48, 69, 62, 76,101,147, 72,113,145,218, 33, 42, 52, 71, 61, 77,116, 105,148,221, 18, 17, 21, 23, 21, 26, 30, 37, 43, 64, 30, 35, 48, 50, 69,115, 77, 99,149,224, 10, 13, 11, 10, 12, 11, 17, 16, 15, 9, 11, 12, 17, 17, 22, 26, 27, 36, 61, 14, 18, 21, 26, 48, 34, 41, 68,115, 69, 99,149}; /* 15 <- changed black's value from this, seemed wrong * 56 <- changed green from this * 163 <- changed cyan from this */ static BFCODE pj_blues[] = { 216, 2, 34, 48, 33, 73, 64,168, 18, 19, 18, 20, 19, 22, 21, 22, 24, 22, 26, 24, 27, 24, 27, 24, 29, 27, 31, 29, 22, 27, 25, 30, 28, 31, 29, 33, 33, 28, 32, 32, 41, 40, 46, 28, 32, 28, 34, 30, 36, 31, 35, 32, 38, 34, 41, 35, 27, 35, 31, 39, 34, 40, 37, 44, 40, 34, 42, 37, 49, 47, 45, 40, 36, 43, 40, 47, 43, 33, 40, 36, 45, 41, 44, 41, 49, 46, 40, 49, 45, 58, 56, 58, 30, 38, 34, 44, 40, 42, 39, 49, 46, 38, 49, 46, 59, 62, 67, 49, 46, 55, 52, 44, 55, 52, 64, 64, 66, 43, 55, 53, 66, 70, 78, 87, 91,101,115, 39, 34, 42, 37, 43, 36, 45, 38, 47, 42, 49, 43, 34, 41, 36, 44, 38, 49, 45, 52, 46, 40, 47, 42, 56, 51, 45, 49, 45, 52, 48, 56, 50, 40, 47, 44, 52, 47, 54, 51, 59, 55, 47, 58, 50, 66, 60, 56, 34, 44, 38, 48, 42, 52, 47, 56, 50, 42, 51, 46, 64, 59, 57, 60, 56, 64, 61, 52, 61, 57, 72, 67, 64, 48, 58, 53, 69, 65, 65, 87, 83, 87, 94, 53, 59, 55, 64, 60, 46, 53, 49, 59, 54, 60, 56, 65, 62, 53, 62, 58, 76, 71, 68, 41, 50, 45, 56, 51, 58, 53, 63, 59, 49, 60, 56, 74, 71, 71, 66, 63, 73, 70, 60, 69, 67, 84, 81, 79, 55, 67, 64, 84, 81, 83, 104,104,106,116, 32, 40, 53, 48, 54, 50, 61, 57, 46, 59, 56, 76, 75, 80, 64, 59, 70, 67, 57, 69, 65, 83, 81, 85, 54, 68, 66, 86, 88, 96,110,114,125,137, 71, 81, 78, 68, 77, 76, 93, 92, 90, 65, 77, 75, 92, 93, 96,117,119,126,138, 78, 79, 98,102, 110,124,131,143,157, 173,185,200}; #endif static void putitem(void); static void rleputxelval(int); static void rleflush(void); static void rleputrest(void); static int LPTn; /* printer number we're gonna use */ static FILE *PRFILE; #define TONES 17 /* Number of PostScript halftone styles */ #if 1 static FCODE ht00[] = {"D mul exch D mul add 1 exch sub"}; static FCODE ht01[] = {"abs exch abs 2 copy add 1 gt {1 sub D mul exch 1 sub D mul add 1 sub} {D mul exch D mul add 1 exch sub} ifelse"}; static FCODE ht02[] = {"D mul exch D mul add 1 sub"}; static FCODE ht03[] = {"D mul exch D mul add 0.6 exch sub abs -0.5 mul"}; static FCODE ht04[] = {"D mul exch D mul add 0.6 exch sub abs 0.5 mul"}; static FCODE ht05[] = {"add 2 div"}; static FCODE ht06[] = {"2 exch sub exch abs 2 mul sub 3 div"}; static FCODE ht07[] = {"2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div"}; static FCODE ht08[] = {"abs exch abs add 1 exch sub"}; static FCODE ht09[] = {"pop"}; static FCODE ht10[] = {"/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos"}; static FCODE ht11[] = {"D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub"}; static FCODE ht12[] = {"D mul D mul exch D mul D mul add 1 exch sub"}; static FCODE ht13[] = {"D mul exch D mul add sqrt 1 exch sub"}; static FCODE ht14[] = {"abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div"}; static FCODE ht15[] = {"pop pop rand 1 add 10240 mod 5120 div 1 exch sub"}; static FCODE ht16[] = {"pop abs 2 mul 1 exch sub"}; #endif static FCODE *HalfTone[TONES]= {ht00,ht01,ht02,ht03,ht04,ht05,ht06,ht07, ht08,ht09,ht10,ht11,ht12,ht13,ht14,ht15,ht16}; #if 0 "D mul exch D mul add 1 exch sub", "abs exch abs 2 copy add 1 gt {1 sub D mul exch 1 sub D mul add 1 sub} {D mul exch D mul add 1 exch sub} ifelse", "D mul exch D mul add 1 sub", "D mul exch D mul add 0.6 exch sub abs -0.5 mul", "D mul exch D mul add 0.6 exch sub abs 0.5 mul", "add 2 div", "2 exch sub exch abs 2 mul sub 3 div", "2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div", "abs exch abs add 1 exch sub", "pop", "/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos", "D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub", "D mul D mul exch D mul D mul add 1 exch sub", "D mul exch D mul add sqrt 1 exch sub", "abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div", "pop pop rand 1 add 10240 mod 5120 div 1 exch sub", "pop abs 2 mul 1 exch sub" }; #endif #ifdef __BORLANDC__ #if(__BORLANDC__ > 2) #pragma warn -eff #endif #endif static char EndOfLine[3]; /* workaround for the old illicit decflaration of dstack */ typedef int (*TRIPLE)[2][3][400]; #define triple (*((TRIPLE)dstack)) void Print_Screen (void) { int y,j; char buff[192]; /* buffer for 192 sets of pixels */ /* This is very large so that we can*/ /* get reasonable times printing */ /* from modes like MAXPIXELSxMAXPIXELS disk-*/ /* video. When this was 24, a MAXPIXELS*/ /* by MAXPIXELS pic took over 2 hours to*/ /* print. It takes about 15 min now*/ int BuffSiz; /* how much of buff[] we'll use */ char far *es; /* pointer to extraseg for buffer */ int i,x,k, /* more indices */ imax, /* maximum i value (ydots/8) */ res, /* resolution we're gonna' use */ high, /* if LPTn>10 COM == com port to use*/ low, /* misc */ /************************************/ ptrid; /* Printer Id code. */ /* Currently, the following are */ /* assigned: */ /* 1. HPLJ (all) */ /* Toshiba PageLaser*/ /* 2. IBM Graphics */ /* 3. Color Printer */ /* 4. HP PaintJet */ /* 5. PostScript */ /************************************/ int pj_color_ptr[256]; /* Paintjet color translation */ /******** SETUP VARIABLES ********/ memset(buff,0,192); i = 0; EndOfLine[0]=(char)(((Printer_CRLF==1) || (Printer_CRLF==0)) ? 0x0D : 0x0A); EndOfLine[1]=(char)((Printer_CRLF==0) ? 0x0A : 0x00); EndOfLine[2]=0x00; if (Print_To_File>0) { while ((PRFILE = fopen(PrintName,"r")) != NULL) { j = fgetc(PRFILE); fclose(PRFILE); if (j == EOF) break; updatesavename((char *)PrintName); } if ((PRFILE = fopen(PrintName,"wb")) == NULL) Print_To_File = 0; } #ifdef XFRACT /* putstring(3,0,0,"Printing to:"); putstring(4,0,0,PrintName); putstring(5,0,0," "); */ #endif es=MK_FP(extraseg,0); LPTn=LPTNumber-1; if (((LPTn>2)&&(LPTn<10))|| ((LPTn>13)&&(LPTn<20))|| ((LPTn>21)&&(LPTn<30))|| (LPTn<0)||(LPTn>31)) LPTn=0; /* default of LPT1 (==0) */ ptrid=Printer_Type; if ((ptrid<1)||(ptrid>7)) ptrid=2; /* default of IBM/EPSON */ res=Printer_Resolution; #ifndef XFRACT if ((LPTn==20)||(LPTn==21)) { k = (inp((LPTn==20) ? 0x37A : 0x27A)) & 0xF7; outp((LPTn==20) ? 0x37A : 0x27A,k); k = k & 0xFB; outp((LPTn==20) ? 0x37A : 0x27A,k); k = k | 0x0C; outp((LPTn==20) ? 0x37A : 0x27A,k); } if ((LPTn==30)||(LPTn==31)) { outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00); outp((LPTn==30) ? 0x3FC : 0x2FC,0x00); outp((LPTn==30) ? 0x3FC : 0x2FC,0x03); } #endif switch (ptrid) { case 1: if (res<75) res=75; if ( (res<= 75)&&(ydots> 600)) res=100; if ( (res<=100)&&(ydots> 800)) res=150; if (((res<=150)&&(ydots>1200))||(res>300)) res=300; break; case 2: case 3: if (res<60) res=60; if ((res<=60)&&(ydots>480)) res=120; if (((res<=120)&&(ydots>960))||(res>240)) res=240; break; case 4: /****** PaintJet *****/ { #ifndef XFRACT /* Pieter Branderhorst: My apologies if the numbers and approach here seem to be picked out of a hat. They were. They happen to result in a tolerable mapping of screen colors to printer colors on my machine. There are two sources of error in getting colors to come out right. 1) Must match some dacbox values to the 330 PaintJet dithered colors so that they look the same. For this we use HP's color values in printera.asm and modify by gamma separately for each of red/green/blue. This mapping is ok if the preview shown on screen is a fairly close match to what gets printed. The defaults are what work for me. 2) Must find nearest color in HP palette to each color in current image. For this we use Lee Crocker's least sum of differences squared approach, modified to spread the values using gamma 1.7. This mods was arrived at by trial and error, just because it improves the mapping. */ long ldist; int r,g,b; double gamma_val,gammadiv; BYTE convert[256]; BYTE scale[64]; BYTE far *table_ptr = NULL; res = (res < 150) ? 90 : 180; /* 90 or 180 dpi */ if (Printer_SetScreen == 0) { Printer_SFrequency = 21; /* default red gamma */ Printer_SAngle = 19; /* green gamma */ Printer_SStyle = 16; /* blue gamma */ } /* Convert the values in printera.asm. We might do this just */ /* once per run, but we'd need separate memory for that - can't */ /* just convert table in-place cause it could be in an overlay, */ /* might be paged out and then back in in original form. Also, */ /* user might change gammas with a .par file entry mid-run. */ for (j = 0; j < 3; ++j) { switch (j) { case 0: table_ptr = pj_reds; i = Printer_SFrequency; break; case 1: table_ptr = pj_greens; i = Printer_SAngle; break; case 2: table_ptr = pj_blues; i = Printer_SStyle; } gamma_val = 10.0 / i; gammadiv = pow(255,gamma_val) / 255; for (i = 0; i < 256; ++i) { /* build gamma conversion table */ static FCODE msg[]={"Calculating color translation"}; if ((i & 15) == 15) thinking(1,msg); convert[i] = (BYTE)((pow((double)i,gamma_val) / gammadiv) + 0.5); } for (i = 0; i < 330; ++i) { k = convert[table_ptr[i]]; if (k > 252) k = 252; triple[0][j][i] = (k + 2) >> 2; } } /* build comparison lookup table */ gamma_val = 1.7; gammadiv = pow(63,gamma_val) / 63; for (i = 0; i < 64; ++i) { if ((j = (int)((pow((double)i,gamma_val) / gammadiv) * 4 + 0.5)) < i) j = i; scale[i] = (char)j; } for (i = 0; i < 3; ++i) /* convert values via lookup */ for (j = 0; j < 330; ++j) triple[1][i][j] = scale[triple[0][i][j]]; /* Following code and the later code which writes to Paintjet */ /* using pj_patterns was adapted from Lee Crocker's PGIF program */ for (i = 0; i < colors; ++i) { /* find nearest match colors */ r = scale[dacbox[i][0]]; g = scale[dacbox[i][1]]; b = scale[dacbox[i][2]]; ldist = 9999999L; /* check variance vs each PaintJet color */ /* if high-res 8 color mode, consider only 1st 8 colors */ j = (res == 90) ? 330 : 8; while (--j >= 0) { long dist; dist = (unsigned)(r-triple[1][0][j]) * (r-triple[1][0][j]); dist += (unsigned)(g-triple[1][1][j]) * (g-triple[1][1][j]); dist += (unsigned)(b-triple[1][2][j]) * (b-triple[1][2][j]); if (dist < ldist) { ldist = dist; k = j; } } pj_color_ptr[i] = k; /* remember best fit */ } thinking(0,NULL); /* if (debugflag == 900 || debugflag == 902) { color_test(); return; } */ if (dotmode != 11) { /* preview */ static char far msg[] = {"Preview. Enter=go, Esc=cancel, k=keep"}; memcpy(triple[1],dacbox,768); for (i = 0; i < colors; ++i) for (j = 0; j < 3; ++j) dacbox[i][j] = (BYTE)triple[0][j][pj_color_ptr[i]]; spindac(0,1); texttempmsg(msg); i = getakeynohelp(); if (i == 'K' || i == 'k') { return; } memcpy(dacbox,triple[1],768); spindac(0,1); if (i == 0x1B) { return; } } break; #endif } case 5: case 6: /***** PostScript *****/ if ( res < 10 && res != 0 ) res = 10; /* PostScript scales... */ if ( res > 600 ) res = 600; /* it can handle any range! */ if ((Printer_SStyle < 0) || (Printer_SStyle >= TONES)) Printer_SStyle = 0; break; } /***** Set up buffer size for immediate user gratification *****/ /***** AKA, if we don't have to, don't buffer the data *****/ BuffSiz=8; if (xdots>1024) BuffSiz=192; /***** Initialize printer *****/ if (Print_To_File < 1) { printer_reset(); /* wait a bit, some printers need time after reset */ delay((ptrid == 4) ? 2000 : 500); } /****** INITIALIZE GRAPHICS MODES ******/ graphics_init(ptrid,res,EndOfLine); if (keypressed()) { /* one last chance before we start...*/ return; } memset(buff,0,192); /***** Get And Print Screen **** */ switch (ptrid) { case 1: /* HP LaserJet (et al) */ imax=(ydots/8)-1; for (x=0;((x=0)&&(!keypressed()));i--) { for (y=7;((y>=0)&&(!keypressed()));y--) { for (j=0;j=0)&&(!keypressed()));i--) { printer(*(es+j+BuffSiz*i)); } } } } if (!keypressed()) PRINTER_PRINTF1("\033*rB\014"); break; case 2: /* IBM Graphics/Epson */ for (x=0;((x=0);y--) { buff[0]=0; for (i=0;i<8;i++) { buff[0]<<=1; buff[0]=(char)(buff[0]+(char)(getcolor(x+i,y)&1)); } printer(buff[0]); } if (keypressed()) break; Printer_printf(EndOfLine); } if (!keypressed()) printer(12); break; case 3: /* IBM Graphics/Epson Color */ high=ydots/256; low=ydots%256; for (x=0;((x=0;y--) { buff[0]=0; for (i=0;i<8;i++) { buff[0]<<=1; if ((getcolor(x+i,y)%8)==k) buff[0]++; } printer(buff[0]); } if (Printer_CRLF<2) printer(13); } if ((Printer_CRLF==0) || (Printer_CRLF==2)) printer(10); } printer(12); printer(12); printer_reset(); break; case 4: /* HP PaintJet */ { unsigned int fetchrows,fetched; BYTE far *pixels = NULL, far *nextpixel = NULL; /* for reasonable speed when using disk video, try to fetch and store the info for 8 columns at a time instead of doing getcolor calls down each column in separate passes */ fetchrows = 16; for(;;) { if ((pixels = (BYTE far *)farmemalloc((long)(fetchrows)*ydots)) != NULL) break; if ((fetchrows >>= 1) == 0) { static char far msg[]={"insufficient memory"}; stopmsg(0,msg); break; } } if (!pixels) break; fetched = 0; for (x = 0; (x < xdots && !keypressed()); ++x) { if (fetched == 0) { if ((fetched = xdots-x) > fetchrows) fetched = fetchrows; for (y = ydots-1; y >= 0; --y) { if (debugflag == 602) /* flip image */ nextpixel = pixels + y; else /* reverse order for unflipped */ nextpixel = pixels + ydots-1 - y; for (i = 0; i < (int)fetched; ++i) { *nextpixel = (BYTE)getcolor(x+i,y); nextpixel += ydots; } } nextpixel = pixels; } --fetched; if (res == 180) { /* high-res 8 color mode */ int offset; BYTE bitmask; offset = -1; bitmask = 0; for (y = ydots - 1; y >= 0; --y) { BYTE color; if ((bitmask >>= 1) == 0) { ++offset; triple[0][0][offset] = triple[0][1][offset] = triple[0][2][offset] = 0; bitmask = 0x80; } /* translate 01234567 to 70123456 */ color = (BYTE)(pj_color_ptr[*(nextpixel++)] - 1); if ((color & 1)) triple[0][0][offset] += bitmask; if ((color & 2)) triple[0][1][offset] += bitmask; if ((color & 4)) triple[0][2][offset] += bitmask; } } else { /* 90 dpi, build 2 lines, 2 dots per pixel */ int bitct,offset; bitct = offset = 0; for (y = ydots - 1; y >= 0; --y) { unsigned int color; color = pj_patterns[pj_color_ptr[*(nextpixel++)]]; for (i = 0; i < 3; ++i) { BYTE *bufptr; bufptr = (BYTE *)&triple[0][i][offset]; *bufptr <<= 2; if ((color & 0x1000)) *bufptr += 2; if ((color & 0x0100)) ++*bufptr; bufptr = (BYTE *)&triple[1][i][offset]; *bufptr <<= 2; if ((color & 0x0010)) *bufptr += 2; if ((color & 0x0001)) ++*bufptr; color >>= 1; } if (++bitct == 4) { bitct = 0; ++offset; } } } for (i = 0; i < ((res == 90) ? 2 : 1); ++i) { for (j = 0; j < 3; ++j) { BYTE *bufptr,*bufend; Printer_printf((j < 2) ? "\033*b%dV" : "\033*b%dW", pj_width); bufend = pj_width + (bufptr = (BYTE *)(triple[i][j])); do { while (printer(*bufptr)) { } } while (++bufptr < bufend); } } } PRINTER_PRINTF1("\033*r0B"); /* end raster graphics */ if (!keypressed()) { if (debugflag != 600) printer(12); /* form feed */ else Printer_printf("\n\n"); } farmemfree(pixels); break; } case 5: case 6: /***** PostScript Portrait & Landscape *****/ { char convert[513]; if (!ColorPS) { for (i=0; i<256; ++i) if (Printer_Compress) { convert[i] = (char)((.3*255./63. * (double)dacbox[i][0])+ (.59*255./63. * (double)dacbox[i][1])+ (.11*255./63. * (double)dacbox[i][2])); } else { sprintf(&convert[2*i], "%02X", (int)((.3*255./63. * (double)dacbox[i][0])+ (.59*255./63. * (double)dacbox[i][1])+ (.11*255./63. * (double)dacbox[i][2]))); } } i=0; j=0; for (y=0;((y=64) { strcpy(&buff[i]," "); Printer_printf("%s%s",buff,EndOfLine); i=0; j++; if (j>9) { j=0; Printer_printf(EndOfLine); } } } } } if (Printer_Compress) { rleputrest(); } else { strcpy(&buff[i]," "); Printer_printf("%s%s",buff,EndOfLine); i=0; j++; if (j>9) { j=0; Printer_printf(EndOfLine); } } if ( (EPSFileType > 0) && (EPSFileType <3) ) { PRINTER_PRINTF4("%s%%%%Trailer%sEPSFsave restore%s",EndOfLine, EndOfLine,EndOfLine); } else { #ifndef XFRACT PRINTER_PRINTF4("%sshowpage%s%c",EndOfLine,EndOfLine,4); #else PRINTER_PRINTF3("%sshowpage%s",EndOfLine,EndOfLine); #endif } break; } case 7: /* HP Plotter */ { double parm1=0,parm2=0; for (i=0;i<3;i++) { PRINTER_PRINTF4("%sSP %d;%s\0",EndOfLine,(i+1),EndOfLine); for (y=0;(y0) { switch(Printer_SStyle) { case 0: ci=0.004582144*(double)j; ck= -.007936057*(double)j; parm1 = (double)x+.5+ci+(((double)i-1.0)/3); parm2 = (double)y+.5+ck; break; case 1: ci= -.004582144*(double)j+(((double)i+1.0)/8.0); ck= -.007936057*(double)j; parm1 = (double)x+.5+ci; parm2 = (double)y+.5+ck; break; case 2: ci= -.0078125*(double)j+(((double)i+1.0)*.003906250); ck= -.0078125*(double)j; parm1 = (double)x+.5+ci; parm2 = (double)y+.5+ck; break; } PRINTER_PRINTF5("PA %f,%f;PD;PR %f,%f;PU;\0", parm1,parm2, ci*((double)-2), ck*((double)-2)); } } } } PRINTER_PRINTF3("%s;SC;PA 0,0;SP0;%s\0",EndOfLine,EndOfLine); PRINTER_PRINTF2(";;SP 0;%s\0",EndOfLine); break; } } if (Print_To_File > 0) fclose(PRFILE); #ifdef XFRACT /* putstring(5,0,0,"Printing done\n"); */ { char cmd[256]; int dummy; /* to clear up compiler warning */ sprintf(cmd, "%s %s &", PSviewer, PrintName); dummy = system(cmd); } #else if ((LPTn==30)||(LPTn==31)) { for (x=0;x<2000;x++); outp((LPTn==30) ? 0x3FC : 0x2FC,0x00); outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00); } #endif } static void _fastcall graphics_init(int ptrid,int res,char *EndOfLine) { int i,j; switch (ptrid) { case 1: print_title(ptrid,res,EndOfLine); PRINTER_PRINTF2("\033*t%iR\033*r0A",res);/* HP */ break; case 2: case 3: print_title(ptrid,res,EndOfLine); PRINTER_PRINTF1("\033\063\030");/* IBM */ break; case 4: /****** PaintJet *****/ print_title(ptrid,res,EndOfLine); pj_width = ydots; if (res == 90) pj_width <<= 1; PRINTER_PRINTF2("\033*r0B\033*t180R\033*r3U\033*r%dS\033*b0M\033*r0A", pj_width); pj_width >>= 3; break; case 5: /***** PostScript *****/ case 6: /***** PostScript Landscape *****/ if (!((EPSFileType > 0) && (ptrid==5))) PRINTER_PRINTF2("%%!PS-Adobe%s",EndOfLine); if ((EPSFileType > 0) && /* Only needed if saving to .EPS */ (ptrid == 5)) { PRINTER_PRINTF2("%%!PS-Adobe-1.0 EPSF-2.0%s",EndOfLine); if (EPSFileType==1) i=xdots+78; else i=(int)((double)xdots * (72.0 / (double)res))+78; if (Printer_Titleblock==0) { if (EPSFileType==1) { j = ydots + 78; } else { j = (int)(((double)ydots * (72.0 / (double)res) / (double)finalaspectratio)+78); } } else { if (EPSFileType==1) { j = ydots + 123; } else { j = (int)(((double)ydots * (72.0 / (double)res))+123); } } PRINTER_PRINTF4("%%%%TemplateBox: 12 12 %d %d%s",i,j,EndOfLine); PRINTER_PRINTF4("%%%%BoundingBox: 12 12 %d %d%s",i,j,EndOfLine); PRINTER_PRINTF4("%%%%PrinterRect: 12 12 %d %d%s",i,j,EndOfLine); PRINTER_PRINTF2("%%%%Creator: Fractint PostScript%s",EndOfLine); PRINTER_PRINTF5("%%%%Title: A %s fractal - %s - Fractint EPSF Type %d%s", curfractalspecific->name[0]=='*' ? &curfractalspecific->name[1] : curfractalspecific->name, PrintName, EPSFileType, EndOfLine); if (Printer_Titleblock==1) PRINTER_PRINTF2("%%%%DocumentFonts: Helvetica%s",EndOfLine); PRINTER_PRINTF2("%%%%EndComments%s",EndOfLine); PRINTER_PRINTF2("/EPSFsave save def%s",EndOfLine); PRINTER_PRINTF2("0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin%s",EndOfLine); PRINTER_PRINTF2("10 setmiterlimit [] 0 setdash newpath%s",EndOfLine); } /* Common code for all PostScript */ PRINTER_PRINTF2("/Tr {translate} def%s",EndOfLine); PRINTER_PRINTF2("/Mv {moveto} def%s",EndOfLine); PRINTER_PRINTF2("/D {dup} def%s",EndOfLine); PRINTER_PRINTF2("/Rh {readhexstring} def%s",EndOfLine); PRINTER_PRINTF2("/Cf {currentfile} def%s",EndOfLine); PRINTER_PRINTF2("/Rs {readstring} def%s",EndOfLine); if (Printer_Compress) { rleprolog(xdots,ydots); } else { PRINTER_PRINTF3("/picstr %d string def%s", ColorPS?xdots*3:xdots,EndOfLine); PRINTER_PRINTF7("/dopic { gsave %d %d 8 [%d 0 0 %d 0 %d]%s", xdots, ydots, xdots, -ydots, ydots, EndOfLine); PRINTER_PRINTF2("{ Cf picstr Rh pop }%s", EndOfLine); if (ColorPS) { PRINTER_PRINTF2(" false 3 colorimage grestore } def%s", EndOfLine); } else { PRINTER_PRINTF2(" image grestore } def%s", EndOfLine); } } if (Printer_Titleblock==1) { PRINTER_PRINTF2("/Helvetica findfont 8 scalefont setfont%s",EndOfLine); if (ptrid==5) {PRINTER_PRINTF1("30 60 Mv ");} else {PRINTER_PRINTF1("552 30 Mv 90 rotate ");} print_title(ptrid,res,EndOfLine); if (ptrid==6) {PRINTER_PRINTF1("-90 rotate ");} } if (EPSFileType != 1) /* Do not use on a WELL BEHAVED .EPS */ { if (ptrid == 5 && EPSFileType==2 && (Printer_ColorXlat || Printer_SetScreen)) PRINTER_PRINTF2("%%%%BeginFeature%s",EndOfLine); if (ColorPS) { if (Printer_ColorXlat==1) PRINTER_PRINTF2("{1 exch sub} D D D setcolortransfer%s",EndOfLine); if (Printer_ColorXlat>1) PRINTER_PRINTF4("{%d mul round %d div} D D D setcolortransfer%s", Printer_ColorXlat,Printer_ColorXlat,EndOfLine); if (Printer_ColorXlat<-1) PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} D D D setcolortransfer", Printer_ColorXlat,Printer_ColorXlat,EndOfLine); if (Printer_SetScreen==1) { #ifndef XFRACT static char far fmt_str[] = "%d %d {%Fs}%s"; #else static char fmt_str[] = "%d %d {%s}%s"; #endif Printer_printf(fmt_str, Printer_RFrequency, Printer_RAngle, (char far *)HalfTone[Printer_RStyle], EndOfLine); Printer_printf(fmt_str, Printer_GFrequency, Printer_GAngle, (char far *)HalfTone[Printer_GStyle], EndOfLine); Printer_printf(fmt_str, Printer_BFrequency, Printer_BAngle, (char far *)HalfTone[Printer_BStyle], EndOfLine); Printer_printf(fmt_str, Printer_SFrequency, Printer_SAngle, (char far *)HalfTone[Printer_SStyle], EndOfLine); PRINTER_PRINTF2("setcolorscreen%s", EndOfLine); } } else { if (Printer_ColorXlat!=-2 && Printer_ColorXlat!=2) { /* b&w case requires no mask building */ if (Printer_ColorXlat==1) PRINTER_PRINTF2("{1 exch sub} settransfer%s",EndOfLine); if (Printer_ColorXlat>1) PRINTER_PRINTF4("{%d mul round %d div} settransfer%s", Printer_ColorXlat,Printer_ColorXlat,EndOfLine); if (Printer_ColorXlat<-1) PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} settransfer", Printer_ColorXlat,Printer_ColorXlat,EndOfLine); if (Printer_SetScreen==1) { #ifndef XFRACT PRINTER_PRINTF5("%d %d {%Fs} setscreen%s", Printer_SFrequency, Printer_SAngle, (char far *)HalfTone[Printer_SStyle], EndOfLine); #else Printer_printf("%d %d {%s} setscreen%s", Printer_SFrequency, Printer_SAngle, (char far *)HalfTone[Printer_SStyle], EndOfLine); #endif } } } if (ptrid == 5) { if ((EPSFileType==2) && (Printer_ColorXlat || Printer_SetScreen)) PRINTER_PRINTF2("%%%%EndFeature%s",EndOfLine); if (res == 0) { PRINTER_PRINTF2("30 191.5 Tr 552 %4.1f", (552.0*(double)finalaspectratio)); } else { PRINTER_PRINTF4("30 %d Tr %f %f", 75 - ((Printer_Titleblock==1) ? 0 : 45), ((double)xdots*(72.0/(double)res)), ((double)xdots*(72.0/(double)res)*(double)finalaspectratio)); } } else /* For Horizontal PostScript */ { if (res == 0) { PRINTER_PRINTF2("582 30 Tr 90 rotate 732 %4.1f", (732.0*(double)finalaspectratio)); } else { PRINTER_PRINTF4("%d 30 Tr 90 rotate %f %f", 537 + ((Printer_Titleblock==1) ? 0 : 45), ((double)xdots*(72.0/(double)res)), ((double)xdots*(72.0/(double)res)*(double)finalaspectratio)); } } PRINTER_PRINTF2(" scale%s",EndOfLine); } else if (ptrid == 5) /* To be used on WELL-BEHAVED .EPS */ PRINTER_PRINTF5("30 %d Tr %d %d scale%s", 75 - ((Printer_Titleblock==1) ? 0 : 45), xdots,ydots,EndOfLine); PRINTER_PRINTF2("dopic%s",EndOfLine); break; case 7: /* HP Plotter */ if (res<1) res=1; if (res>10) res=10; ci = (((double)xdots*((double)res-1.0))/2.0); ck = (((double)ydots*((double)res-1.0))/2.0); PRINTER_PRINTF6(";IN;SP0;SC%d,%d,%d,%d;%s\0", (int)(-ci),(int)((double)xdots+ci), (int)((double)ydots+ck),(int)(-ck),EndOfLine); break; } } static void _fastcall print_title(int ptrid,int res,char *EndOfLine) { char buff[80]; int postscript; if (Printer_Titleblock == 0) return; postscript = (ptrid == 5 || ptrid ==6); if (!postscript) Printer_printf(EndOfLine); else Printer_printf("("); Printer_printf((curfractalspecific->name[0]=='*') ? &curfractalspecific->name[1] : curfractalspecific->name); if (fractype == FORMULA || fractype == FFORMULA) Printer_printf(" %s",FormName); if (fractype == LSYSTEM) Printer_printf(" %s",LName); if (fractype == IFS || fractype == IFS3D) Printer_printf(" %s",IFSName); PRINTER_PRINTF4(" - %dx%d - %d DPI", xdots, ydots, res); if (!postscript) Printer_printf(EndOfLine); else { PRINTER_PRINTF2(") show%s",EndOfLine); if (ptrid==5) {PRINTER_PRINTF1("30 50 moveto (");} else PRINTER_PRINTF1("-90 rotate 562 30 moveto 90 rotate ("); } PRINTER_PRINTF5("Corners: Top-Left=%.16g/%.16g Bottom-Right=%.16g/%.16g", xxmin,yymax,xxmax,yymin); if (xx3rd != xxmin || yy3rd != yymin) { if (!postscript) Printer_printf("%s ",EndOfLine); PRINTER_PRINTF3(" Bottom-Left=%4.4f/%4.4f",xx3rd,yy3rd); } if (!postscript) Printer_printf(EndOfLine); else { PRINTER_PRINTF2(") show%s",EndOfLine); if (ptrid==5) {PRINTER_PRINTF1("30 40 moveto (");} else PRINTER_PRINTF1("-90 rotate 572 30 moveto 90 rotate ("); } showtrig(buff); PRINTER_PRINTF6("Parameters: %4.4f/%4.4f/%4.4f/%4.4f %s", param[0],param[1],param[2],param[3],buff); if (!postscript) Printer_printf(EndOfLine); else PRINTER_PRINTF2(") show%s",EndOfLine); } /* This function prints a string to the the printer with BIOS calls. */ #ifndef USE_VARARGS static void Printer_printf(char far *fmt,...) #else static void Printer_printf(va_alist) va_dcl #endif { int i; char s[500]; int x=0; va_list arg; #ifndef USE_VARARGS va_start(arg,fmt); #else char far *fmt; va_start(arg); fmt = va_arg(arg,char far *); #endif { /* copy far to near string */ char fmt1[100]; i=0; while(fmt[i]) { fmt1[i] = fmt[i]; i++; } fmt1[i] = '\0'; vsprintf(s,fmt1,arg); } if (Print_To_File>0) /* This is for printing to file */ fprintf(PRFILE,"%s",s); else /* And this is for printing to printer */ while (s[x]) if (printer(s[x++]) != 0) while (!keypressed()) { if (printer(s[x-1])==0) break; } } /* This function standardizes both _bios_printer and _bios_serialcom * in one function. It takes its arguments and rearranges them and calls * the appropriate bios call. If it then returns result !=0, there is a * problem with the printer. */ static int _fastcall printer(int c) { if (Print_To_File>0) return ((fprintf(PRFILE,"%c",c))<1); #ifndef XFRACT if (LPTn<9) return (((_bios_printer(0,LPTn,c))+0x0010)&0x0010); if (LPTn<19) return ((_bios_serialcom(1,(LPTn-10),c))&0x9E00); if ((LPTn==20)||(LPTn==21)) { int PS=0; while ((PS & 0xF8) != 0xD8) { PS = inp((LPTn==20) ? 0x379 : 0x279); if (keypressed()) return(1); } outp((LPTn==20) ? 0x37C : 0x27C,c); PS = inp((LPTn==20) ? 0x37A : 0x27A); outp((LPTn==20) ? 0x37A : 0x27A,(PS | 0x01)); outp((LPTn==20) ? 0x37A : 0x27A,PS); return(0); } if ((LPTn==30)||(LPTn==31)) { while (((inp((LPTn==30) ? 0x3FE : 0x2FE)&0x30)!=0x30) || ((inp((LPTn==30) ? 0x3FD : 0x2FD)&0x60)!=0x60)) { if (keypressed()) return (1); } outp((LPTn==30) ? 0x3F8 : 0x2F8,c); return(0); } #endif /* MCP 7-7-91, If we made it down to here, we may as well error out. */ return(-1); } #ifdef __BORLANDC__ #if(__BORLANDC__ > 2) #pragma warn +eff #endif #endif static void printer_reset(void) { #ifndef XFRACT if (Print_To_File < 1) if (LPTn<9) _bios_printer(1,LPTn,0); else if (LPTn<19) _bios_serialcom(3,(LPTn-10),0); #endif } /** debug code for pj_ color table checkout color_test() { int x,y,color,i,j,xx,yy; int bw,cw,bh,ch; setvideomode(videoentry.videomodeax, videoentry.videomodebx, videoentry.videomodecx, videoentry.videomodedx); bw = xdots/25; cw = bw * 2 / 3; bh = ydots/10; ch = bh * 2 / 3; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 60; if (debugflag == 902) dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for (x = 0; x < 25; ++x) for (y = 0; y < 10; ++y) { if (x < 11) i = (32 - x) * 10 + y; else i = (24 - x) * 10 + y; color = x * 10 + y + 1; dacbox[color][0] = triple[0][0][i]; dacbox[color][1] = triple[0][1][i]; dacbox[color][2] = triple[0][2][i]; for (i = 0; i < cw; ++i) { xx = x * bw + bw / 6 + i; yy = y * bh + bh / 6; for (j = 0; j < ch; ++j) putcolor(xx,yy++,color); } } spindac(0,1); getakey(); } **/ /* * The following code for compressed PostScript is based on pnmtops.c. It is * copyright (C) 1989 by Jef Poskanzer, and carries the following notice: * "Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. This software is provided "as is" without express or * implied warranty." */ static void rleprolog(int x,int y) { itemsperline = 0; items = 0; bitspersample = 8; repeat = 1; rlebitsperitem = 0; rlebitshift = 0; count = 0; PRINTER_PRINTF2( "/rlestr1 1 string def%s", EndOfLine ); PRINTER_PRINTF2( "/rdrlestr {%s", EndOfLine ); /* s -- nr */ PRINTER_PRINTF2( " /rlestr exch def%s", EndOfLine ); /* - */ PRINTER_PRINTF2( " Cf rlestr1 Rh pop%s", EndOfLine ); /* s1 */ PRINTER_PRINTF2( " 0 get%s", EndOfLine ); /* c */ PRINTER_PRINTF2( " D 127 le {%s", EndOfLine ); /* c */ PRINTER_PRINTF2( " Cf rlestr 0%s", EndOfLine ); /* c f s 0 */ PRINTER_PRINTF2( " 4 3 roll%s", EndOfLine ); /* f s 0 c */ PRINTER_PRINTF2( " 1 add getinterval%s", EndOfLine ); /* f s */ PRINTER_PRINTF2( " Rh pop%s", EndOfLine ); /* s */ PRINTER_PRINTF2( " length%s", EndOfLine ); /* nr */ PRINTER_PRINTF2( " } {%s", EndOfLine ); /* c */ PRINTER_PRINTF2( " 256 exch sub D%s", EndOfLine ); /* n n */ PRINTER_PRINTF2( " Cf rlestr1 Rh pop%s", EndOfLine );/* n n s1 */ PRINTER_PRINTF2( " 0 get%s", EndOfLine ); /* n n c */ PRINTER_PRINTF2( " exch 0 exch 1 exch 1 sub {%s", EndOfLine ); /* n c 0 1 n-1*/ PRINTER_PRINTF2( " rlestr exch 2 index put%s", EndOfLine ); PRINTER_PRINTF2( " } for%s", EndOfLine ); /* n c */ PRINTER_PRINTF2( " pop%s", EndOfLine ); /* nr */ PRINTER_PRINTF2( " } ifelse%s", EndOfLine ); /* nr */ PRINTER_PRINTF2( "} bind def%s", EndOfLine ); PRINTER_PRINTF2( "/Rs {%s", EndOfLine ); /* s -- s */ PRINTER_PRINTF2( " D length 0 {%s", EndOfLine ); /* s l 0 */ PRINTER_PRINTF2( " 3 copy exch%s", EndOfLine ); /* s l n s n l*/ PRINTER_PRINTF2( " 1 index sub%s", EndOfLine ); /* s l n s n r*/ PRINTER_PRINTF2( " getinterval%s", EndOfLine ); /* s l n ss */ PRINTER_PRINTF2( " rdrlestr%s", EndOfLine ); /* s l n nr */ PRINTER_PRINTF2( " add%s", EndOfLine ); /* s l n */ PRINTER_PRINTF2( " 2 copy le { exit } if%s", EndOfLine ); /* s l n */ PRINTER_PRINTF2( " } loop%s", EndOfLine ); /* s l l */ PRINTER_PRINTF2( " pop pop%s", EndOfLine ); /* s */ PRINTER_PRINTF2( "} bind def%s", EndOfLine ); if (ColorPS) { PRINTER_PRINTF3( "/rpicstr %d string def%s", x,EndOfLine ); PRINTER_PRINTF3( "/gpicstr %d string def%s", x,EndOfLine ); PRINTER_PRINTF3( "/bpicstr %d string def%s", x,EndOfLine ); } else { PRINTER_PRINTF3( "/picstr %d string def%s", x,EndOfLine ); } PRINTER_PRINTF2( "/dopic {%s", EndOfLine); PRINTER_PRINTF2( "/gsave%s", EndOfLine); if (ColorPS) { PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine); } else { /* b&w */ if (Printer_ColorXlat==-2) { PRINTER_PRINTF4( "%d %d true%s", x, y, EndOfLine); } else if (Printer_ColorXlat==2) { PRINTER_PRINTF4( "%d %d false%s", x, y, EndOfLine); } else { PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine); } } PRINTER_PRINTF5( "[%d 0 0 %d 0 %d]%s", x, -y, y, EndOfLine); if (ColorPS) { PRINTER_PRINTF2( "{rpicstr Rs}%s", EndOfLine); PRINTER_PRINTF2( "{gpicstr Rs}%s", EndOfLine); PRINTER_PRINTF2( "{bpicstr Rs}%s", EndOfLine); PRINTER_PRINTF2( "true 3 colorimage%s", EndOfLine); } else { if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) { /* save file space and printing time (if scaling is right) */ PRINTER_PRINTF2( "{picstr Rs} imagemask%s", EndOfLine); } else { PRINTER_PRINTF2( "{picstr Rs} image%s", EndOfLine); } } PRINTER_PRINTF2( "} def%s", EndOfLine); } static void rleputbuffer(void) { int i; if ( repeat ) { item = 256 - count; putitem(); item = repeatitem; putitem(); } else { item = count - 1; putitem(); for ( i = 0; i < count; ++i ) { item = itembuf[i]; putitem(); } } repeat = 1; count = 0; } static void rleputitem(void) { int i; if ( count == 128 ) rleputbuffer(); if ( repeat && count == 0 ) { /* Still initializing a repeat buf. */ itembuf[count] = repeatitem = rleitem; ++count; } else if ( repeat ) { /* Repeating - watch for end of run. */ if ( rleitem == repeatitem ) { /* Run continues. */ itembuf[count] = rleitem; ++count; } else { /* Run ended - is it long enough to dump? */ if ( count > 2 ) { /* Yes, dump a repeat-mode buffer and start a new one. */ rleputbuffer(); itembuf[count] = repeatitem = rleitem; ++count; } else { /* Not long enough - convert to non-repeat mode. */ repeat = 0; itembuf[count] = repeatitem = rleitem; ++count; repeatcount = 1; } } } else { /* Not repeating - watch for a run worth repeating. */ if ( rleitem == repeatitem ) { /* Possible run continues. */ ++repeatcount; if ( repeatcount > 3 ) { /* Long enough - dump non-repeat part and start repeat. */ count = count - ( repeatcount - 1 ); rleputbuffer(); count = repeatcount; for ( i = 0; i < count; ++i ) itembuf[i] = rleitem; } else { /* Not long enough yet - continue as non-repeat buf. */ itembuf[count] = rleitem; ++count; } } else { /* Broken run. */ itembuf[count] = repeatitem = rleitem; ++count; repeatcount = 1; } } rleitem = 0; rlebitsperitem = 0; } static void putitem (void) { char* hexits = "0123456789abcdef"; if ( itemsperline == 30 ) { Printer_printf("%s",EndOfLine); itemsperline = 0; } Printer_printf("%c%c", hexits[item >> 4], hexits[item & 15] ); ++itemsperline; ++items; item = 0; /* bitsperitem = 0; */ bitshift2 = 8 - bitspersample; } static void rleputxelval( int xv ) { if ( rlebitsperitem == 8 ) rleputitem(); rleitem += xv< 0 ) rleputitem(); if ( count > 0 ) rleputbuffer(); } static void rleputrest(void) { rleflush(); Printer_printf( "%s",EndOfLine ); Printer_printf( "grestore%s",EndOfLine ); } xfractint-20.4.10.orig/common/common.mak0000755000000000000000000001107110541650033014757 0ustar # Note that frachelp.mak and fractint.mak can't be combined into a single # make file because with MSC6 we need to use "NMK", to have enough memory # available for the compiler. NMK would not trigger subsequent recompiles # due to a rebuild of helpdefs.h file if we used a single step. OBJ = 3d.obj ant.obj bigflt.obj biginit.obj bignum.obj calcfrac.obj \ cmdfiles.obj decoder.obj diskvid.obj editpal.obj encoder.obj evolve.obj \ f16.obj fracsubr.obj fractals.obj fractalp.obj fractalb.obj fractint.obj \ framain2.obj frasetup.obj gifview.obj hcmplx.obj help.obj \ history.obj intro.obj \ jb.obj jiim.obj line3d.obj loadfile.obj loadfdos.obj loadmap.obj \ lorenz.obj lsys.obj lsysf.obj memory.obj miscfrac.obj miscovl.obj \ miscres.obj mpmath_c.obj parser.obj parserfp.obj plot3d.obj printer.obj \ prompts1.obj prompts2.obj realdos.obj rotate.obj slideshw.obj soi.obj \ soi1.obj stereo.obj targa.obj testpt.obj tgaview.obj \ yourvid.obj zoom.obj HFD = ..\headers # Next is a pseudo-target for nmake/nmk. It just generates harmless # warnings with make. all : $(OBJ) .c.obj: $(CC) /I$(HFD) $(OptT) $*.c >> f_errs.txt Optsize = $(CC) /I$(HFD) $(OptS) $*.c >> f_errs.txt Optnoalias = $(CC) /I$(HFD) $(OptN) $*.c >> f_errs.txt 3d.obj : 3d.c $(HFD)\fractint.h ant.obj : ant.c $(HFD)\helpdefs.h bigflt.obj : bigflt.c $(HFD)\big.h $(Optnoalias) biginit.obj : biginit.c $(HFD)\big.h $(Optnoalias) bignum.obj : bignum.c $(HFD)\big.h $(Optnoalias) # only used for non ASM version #bignumc.obj : bignumc.c $(HFD)\big.h # $(Optnoalias) calcfrac.obj : calcfrac.c $(HFD)\fractint.h $(HFD)\mpmath.h cmdfiles.obj : cmdfiles.c $(HFD)\fractint.h $(Optsize) decoder.obj : decoder.c $(HFD)\fractint.h diskvid.obj : diskvid.c $(HFD)\fractint.h editpal.obj : editpal.c $(HFD)\fractint.h $(Optsize) encoder.obj : encoder.c $(HFD)\fractint.h $(HFD)\fractype.h evolve.obj : evolve.c $(HFD)\fractint.h $(Optnoalias) f16.obj : f16.c $(HFD)\targa_lc.h fracsubr.obj : fracsubr.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(Optnoalias) fractals.obj : fractals.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\mpmath.h $(HFD)\helpdefs.h fractalp.obj : fractalp.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\mpmath.h $(HFD)\helpdefs.h fractalb.obj : fractalb.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\big.h $(HFD)\helpdefs.h fractint.obj : fractint.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) framain2.obj : framain2.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) frasetup.obj : frasetup.c gifview.obj : gifview.c $(HFD)\fractint.h hcmplx.obj : hcmplx.c $(HFD)\fractint.h help.obj : help.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(HFD)\helpcom.h $(Optsize) history.obj : history.c $(HFD)\fractint.h $(HFD)\fractype.h $(Optsize) intro.obj : intro.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(Optsize) jb.obj : jb.c $(HFD)\fractint.h $(HFD)\helpdefs.h jiim.obj : jiim.c $(HFD)\helpdefs.h line3d.obj : line3d.c $(HFD)\fractint.h loadfile.obj : loadfile.c $(HFD)\fractint.h $(HFD)\fractype.h $(Optsize) loadfdos.obj : loadfdos.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(Optsize) loadmap.obj : loadmap.c $(HFD)\targa.h $(HFD)\fractint.h $(Optsize) lorenz.obj : lorenz.c $(HFD)\fractint.h $(HFD)\fractype.h lsys.obj : lsys.c $(HFD)\fractint.h $(HFD)\lsys.h lsysf.obj : lsysf.c $(HFD)\fractint.h $(HFD)\lsys.h memory.obj : memory.c miscfrac.obj : miscfrac.c $(HFD)\fractint.h $(HFD)\mpmath.h miscovl.obj : miscovl.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) miscres.obj : miscres.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) mpmath_c.obj : mpmath_c.c $(HFD)\mpmath.h parser.obj : parser.c $(HFD)\fractint.h $(HFD)\mpmath.h $(Optnoalias) parserfp.obj : parserfp.c $(HFD)\fractint.h $(HFD)\mpmath.h $(Optnoalias) plot3d.obj : plot3d.c $(HFD)\fractint.h $(HFD)\fractype.h $(Optnoalias) printer.obj : printer.c $(HFD)\fractint.h $(Optsize) prompts1.obj : prompts1.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) prompts2.obj : prompts2.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) realdos.obj : realdos.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(Optsize) rotate.obj : rotate.c $(HFD)\\fractint.h $(HFD)\\helpdefs.h $(Optsize) slideshw.obj : slideshw.c $(Optsize) soi.obj : soi.c soi1.obj : soi1.c stereo.obj : stereo.c $(HFD)\helpdefs.h targa.obj : targa.c $(HFD)\targa.h $(HFD)\fractint.h testpt.obj: testpt.c $(HFD)\fractint.h tgaview.obj : tgaview.c $(HFD)\fractint.h $(HFD)\targa_lc.h $(HFD)\port.h yourvid.obj : yourvid.c zoom.obj : zoom.c $(HFD)\fractint.h $(Optnoalias) # $(Optsize) xfractint-20.4.10.orig/common/fractint.c0000644000000000000000000005233311253454200014755 0ustar /* FRACTINT - The Ultimate Fractal Generator Main Routine */ #include #include #include #ifndef XFRACT #include #endif #ifndef USE_VARARGS #include #else #include #endif #include /* #include hierarchy for fractint is a follows: Each module should include port.h as the first fractint specific include. port.h includes , , , ; and, ifndef XFRACT, . Most modules should include prototyp.h, which incorporates by direct or indirect reference the following header files: mpmath.h cmplx.h fractint.h big.h biginit.h helpcom.h externs.h Other modules may need the following, which must be included separately: fractype.h helpdefs.h lsys.y targa.h targa_lc.h tplus.h If included separately from prototyp.h, big.h includes cmplx.h and biginit.h; and mpmath.h includes cmplx.h */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" struct videoinfo videoentry; int helpmode; long timer_start,timer_interval; /* timer(...) start & total */ int adapter; /* Video Adapter chosen from list in ...h */ char *fract_dir1="", *fract_dir2=""; #ifdef __TURBOC__ /* yes, I *know* it's supposed to be compatible with Microsoft C, but some of the routines need to know if the "C" code has been compiled with Turbo-C. This flag is a 1 if FRACTINT.C (and presumably the other routines as well) has been compiled with Turbo-C. */ int compiled_by_turboc = 1; /* set size to be used for overlays, a bit bigger than largest (help) */ unsigned _ovrbuffer = 54 * 64; /* that's 54k for overlays, counted in paragraphs */ #else int compiled_by_turboc = 0; #endif /* the following variables are out here only so that the calcfract() and assembler routines can get at them easily */ int active_system = 0; /* 0 for DOS, WINFRAC for Windows */ int dotmode; /* video access method */ int textsafe2; /* textsafe override from videotable */ int oktoprint; /* 0 if printf() won't work */ int sxdots,sydots; /* # of dots on the physical screen */ int sxoffs,syoffs; /* physical top left of logical screen */ int xdots, ydots; /* # of dots on the logical screen */ double dxsize, dysize; /* xdots-1, ydots-1 */ int colors = 256; /* maximum colors available */ long maxit; /* try this many iterations */ int boxcount; /* 0 if no zoom-box yet */ int zrotate; /* zoombox rotation */ double zbx,zby; /* topleft of zoombox */ double zwidth,zdepth,zskew; /* zoombox size & shape */ int fractype; /* if == 0, use Mandelbrot */ char stdcalcmode; /* '1', '2', 'g', 'b' */ long creal, cimag; /* real, imag'ry parts of C */ long delx, dely; /* screen pixel increments */ long delx2, dely2; /* screen pixel increments */ LDBL delxx, delyy; /* screen pixel increments */ LDBL delxx2, delyy2; /* screen pixel increments */ long delmin; /* for calcfrac/calcmand */ double ddelmin; /* same as a double */ double param[MAXPARAMS]; /* parameters */ double potparam[3]; /* three potential parameters*/ long fudge; /* 2**fudgefactor */ long l_at_rad; /* finite attractor radius */ double f_at_rad; /* finite attractor radius */ int bitshift; /* fudgefactor */ int badconfig = 0; /* 'fractint.cfg' ok? */ int diskisactive; /* disk-video drivers flag */ int diskvideo; /* disk-video access flag */ int hasinverse = 0; /* note that integer grid is set when integerfractal && !invert; */ /* otherwise the floating point grid is set; never both at once */ long far *lx0, far *ly0; /* x, y grid */ long far *lx1, far *ly1; /* adjustment for rotate */ /* note that lx1 & ly1 values can overflow into sign bit; since */ /* they're used only to add to lx0/ly0, 2s comp straightens it out */ double far *dx0, far *dy0; /* floating pt equivs */ double far *dx1, far *dy1; int integerfractal; /* TRUE if fractal uses integer math */ /* usr_xxx is what the user wants, vs what we may be forced to do */ char usr_stdcalcmode; int usr_periodicitycheck; long usr_distest; char usr_floatflag; int viewwindow; /* 0 for full screen, 1 for window */ float viewreduction; /* window auto-sizing */ int viewcrop; /* nonzero to crop default coords */ float finalaspectratio; /* for view shape and rotation */ int viewxdots,viewydots; /* explicit view sizing */ int video_cutboth; /* nonzero to keep virtual aspect */ int zscroll; /* screen/zoombox 0 fixed, 1 relaxed */ /* HISTORY far *history = NULL; */ U16 history = 0; int maxhistory = 10; /* variables defined by the command line/files processor */ int comparegif=0; /* compare two gif files flag */ int timedsave=0; /* when doing a timed save */ int resave_flag=0; /* tells encoder not to incr filename */ int started_resaves=0; /* but incr on first resave */ int save_system; /* from and for save files */ int tabmode = 1; /* tab display enabled */ /* for historical reasons (before rotation): */ /* top left corner of screen is (xxmin,yymax) */ /* bottom left corner of screen is (xx3rd,yy3rd) */ /* bottom right corner of screen is (xxmax,yymin) */ double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */ long xmin, xmax, ymin, ymax, x3rd, y3rd; /* integer equivs */ double sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */ double plotmx1,plotmx2,plotmy1,plotmy2; /* real->screen multipliers */ int calc_status = -1; /* -1 no fractal */ /* 0 parms changed, recalc reqd */ /* 1 actively calculating */ /* 2 interrupted, resumable */ /* 3 interrupted, not resumable */ /* 4 completed */ long calctime; int max_colors; /* maximum palette size */ int zoomoff; /* = 0 when zoom is disabled */ int savedac; /* save-the-Video DAC flag */ int browsing; /* browse mode flag */ char file_name_stack[16][MAX_NAME]; /* array of file names used while browsing */ int name_stack_ptr ; double toosmall; int minbox; int no_sub_images; int autobrowse,doublecaution; char brwscheckparms,brwschecktype; char browsemask[MAX_NAME]; int scale_map[12] = {1,2,3,4,5,6,7,8,9,10,11,12}; /*RB, array for mapping notes to a (user defined) scale */ #define RESTART 1 #define IMAGESTART 2 #define RESTORESTART 3 #define CONTINUE 4 static void check_samename(void) { char drive[FILE_MAX_DRIVE]; char dir[FILE_MAX_DIR]; char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char path[FILE_MAX_PATH]; splitpath(savename,drive,dir,fname,ext); if(strcmp(fname,"fract001")) { makepath(path,drive,dir,fname,"gif"); if(access(path,0)==0) exit(0); } } /* Do nothing if math error */ static void my_floating_point_err(int sig) { if(sig != 0) overflow = 1; } #ifdef XFRACT int #else void #endif main(int argc, char **argv) { int resumeflag; int kbdchar; /* keyboard key-hit value */ int kbdmore; /* continuation variable */ char stacked=0; /* flag to indicate screen stacked */ /* this traps non-math library floating point errors */ signal( SIGFPE, my_floating_point_err ); initasmvars(); /* initialize ASM stuff */ InitMemory(); checkfreemem(0); load_videotable(1); /* load fractint.cfg, no message yet if bad */ init_help(); restart: /* insert key re-starts here */ autobrowse = FALSE; brwschecktype = TRUE; brwscheckparms = TRUE; doublecaution = TRUE; no_sub_images = FALSE; toosmall = 6; minbox = 3; strcpy(browsemask,"*.gif"); strcpy(browsename," "); name_stack_ptr= -1; /* init loaded files stack */ evolving = FALSE; paramrangex = 4; opx = newopx = -2.0; paramrangey = 3; opy = newopy = -1.5; odpx = odpy = 0; gridsz = 9; fiddlefactor = 1; fiddle_reduction = 1.0; this_gen_rseed = (unsigned int)clock_ticks(); srand(this_gen_rseed); initgene(); /*initialise pointers to lots of fractint variables for the evolution engine*/ start_showorbit = 0; showdot = -1; /* turn off showdot if entered with command */ calc_status = -1; /* no active fractal image */ fract_dir1 = getenv("FRACTDIR"); if (fract_dir1==NULL) { fract_dir1 = "."; } #ifdef SRCDIR fract_dir2 = SRCDIR; #else fract_dir2 = "."; #endif cmdfiles(argc,argv); /* process the command-line */ #ifdef XFRACT UnixInit(); #endif dopause(0); /* pause for error msg if not batch */ init_msg(0,"",NULL,0); /* this causes getakey if init_msg called on runup */ checkfreemem(1); if(debugflag==450 && initbatch==1) /* abort if savename already exists */ check_samename(); #ifdef XFRACT initUnixWindow(); #endif memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */ if (debugflag == 8088) cpu = 86; /* for testing purposes */ if (debugflag == 2870 && fpu >= 287 ) { fpu = 287; /* for testing purposes */ cpu = 286; } if (debugflag == 870 && fpu >= 87 ) { fpu = 87; /* for testing purposes */ cpu = 86; } if (debugflag == 70) fpu = 0; /* for testing purposes */ if (getenv("NO87")) fpu = 0; if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ setup287code(); adapter_detect(); /* check what video is really present */ if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */ if (video_type > (debugflag-9000)/2) /* adjust the video value */ video_type = (debugflag-9000)/2; diskisactive = 0; /* disk-video is inactive */ diskvideo = 0; /* disk driver is not in use */ setvideotext(); /* switch to text mode */ savedac = 0; /* don't save the VGA DAC */ #ifndef XFRACT if (debugflag == 10000) /* check for free memory */ showfreemem(); if (badconfig < 0) /* fractint.cfg bad, no msg yet */ bad_fractint_cfg_msg(); #endif max_colors = 256; /* the Windows version is lower */ max_kbdcount=(cpu>=386) ? 80 : 30; /* check the keyboard this often */ if (showfile && initmode < 0) { intro(); /* display the credits screen */ if (keypressed() == ESC) { getakey(); /* JPD : do not exit automatically under credits screen ... goodbye(); */ } } browsing = FALSE; if (!functionpreloaded) set_if_old_bif(); stacked = 0; restorestart: if (colorpreloaded) memcpy(dacbox,olddacbox,256*3); /* restore in case colors= present */ lookatmouse = 0; /* ignore mouse */ while (showfile <= 0) { /* image is to be loaded */ char *hdg; tabmode = 0; if (!browsing ) /*RB*/ { if (overlay3d) { hdg = "Select File for 3D Overlay"; helpmode = HELP3DOVLY; } else if (display3d) { hdg = "Select File for 3D Transform"; helpmode = HELP3D; } else { hdg = "Select File to Restore"; helpmode = HELPSAVEREST; } if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) { showfile = 1; /* cancelled */ initmode = -1; break; } name_stack_ptr = 0; /* 'r' reads first filename for browsing */ strcpy(file_name_stack[name_stack_ptr],browsename); } evolving = viewwindow = 0; showfile = 0; helpmode = -1; tabmode = 1; if(stacked) { discardscreen(); setvideotext(); stacked = 0; } if (read_overlay() == 0) /* read hdr, get video mode */ break; /* got it, exit */ if (browsing) /* break out of infinite loop, but lose your mind */ showfile = 1; else showfile = -1; /* retry */ } helpmode = HELPMENU; /* now use this help mode */ tabmode = 1; lookatmouse = 0; /* ignore mouse */ if (((overlay3d && !initbatch) || stacked) && initmode < 0) { /* overlay command failed */ unstackscreen(); /* restore the graphics screen */ stacked = 0; overlay3d = 0; /* forget overlays */ display3d = 0; /* forget 3D */ if (calc_status ==3) calc_status = 0; resumeflag = 1; goto resumeloop; /* ooh, this is ugly */ } savedac = 0; /* don't save the VGA DAC */ imagestart: /* calc/display a new image */ if(stacked) { discardscreen(); stacked = 0; } #ifdef XFRACT usr_floatflag = 1; #endif got_status = -1; /* for tab_display */ if (showfile) if (calc_status > 0) /* goto imagestart implies re-calc */ calc_status = 0; if (initbatch == 0) lookatmouse = -PAGE_UP; /* just mouse left button, == pgup */ cyclelimit = initcyclelimit; /* default cycle limit */ adapter = initmode; /* set the video adapter up */ initmode = -1; /* (once) */ while (adapter < 0) { /* cycle through instructions */ if (initbatch) { /* batch, nothing to do */ initbatch = 4; /* exit with error condition set */ goodbye(); } kbdchar = main_menu(0); if (kbdchar == INSERT) goto restart; /* restart pgm on Insert Key */ if (kbdchar == DELETE) /* select video mode list */ kbdchar = select_video_mode(-1); if ((adapter = check_vidmode_key(0,kbdchar)) >= 0) break; /* got a video mode now */ #ifndef XFRACT if ('A' <= kbdchar && kbdchar <= 'Z') kbdchar = tolower(kbdchar); #endif #ifndef XFRACT if (kbdchar == 'd') { /* shell to DOS */ setclear(); printf("\n\nShelling to DOS - type 'exit' to return\n\n"); shell_to_dos(); goto imagestart; } #else if (kbdchar == 'd') { /* redraw image in Xfractint */ initmode = adapter; goto imagestart; } #endif #ifndef XFRACT if (kbdchar == '@' || kbdchar == '2') { /* execute commands */ #else if (kbdchar == F2 || kbdchar == '@') { /* We mapped @ to F2 */ #endif if ((get_commands() & 4) == 0) goto imagestart; kbdchar = '3'; /* 3d=y so fall thru '3' code */ } #ifndef XFRACT if (kbdchar == 'r' || kbdchar == '3' || kbdchar == '#') { #else if (kbdchar == 'r' || kbdchar == '3' || kbdchar == F3) { #endif display3d = 0; if (kbdchar == '3' || kbdchar == '#' || kbdchar == F3) display3d = 1; if(colorpreloaded) memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */ setvideotext(); /* switch to text mode */ showfile = -1; goto restorestart; } if (kbdchar == 't') { /* set fractal type */ julibrot = 0; get_fracttype(); goto imagestart; } if (kbdchar == 'x') { /* generic toggle switch */ get_toggles(); goto imagestart; } if (kbdchar == 'y') { /* generic toggle switch */ get_toggles2(); goto imagestart; } if (kbdchar == 'z') { /* type specific parms */ get_fract_params(1); goto imagestart; } if (kbdchar == 'v') { /* view parameters */ get_view_params(); goto imagestart; } if (kbdchar == 2) { /* ctrl B = browse parms*/ get_browse_params(); goto imagestart; } if (kbdchar == 6) { /* ctrl f = sound parms*/ get_sound_params(); goto imagestart; } if (kbdchar == 'f') { /* floating pt toggle */ if (usr_floatflag == 0) usr_floatflag = 1; else usr_floatflag = 0; goto imagestart; } if (kbdchar == 'i') { /* set 3d fractal parms */ get_fract3d_params(); /* get the parameters */ goto imagestart; } if (kbdchar == 'g') { get_cmd_string(); /* get command string */ goto imagestart; } /* buzzer(2); */ /* unrecognized key */ } zoomoff = 1; /* zooming is enabled */ helpmode = HELPMAIN; /* now use this help mode */ resumeflag = 0; /* allows taking goto inside big_while_loop() */ resumeloop: param_history(0); /* save old history */ /* this switch processes gotos that are now inside function */ switch(big_while_loop(&kbdmore,&stacked,resumeflag)) { case RESTART: goto restart; case IMAGESTART: goto imagestart; case RESTORESTART: goto restorestart; default: break; } #ifdef XFRACT return(0); #endif } int check_key() { int key; if((key = keypressed()) != 0) { if (show_orbit) scrub_orbit(); if(key != 'o' && key != 'O') { fflush(stdout); return(-1); } getakey(); if (dotmode != 11) show_orbit = 1 - show_orbit; } return(0); } /* timer function: timer(0,(*fractal)()) fractal engine timer(1,NULL,int width) decoder timer(2) encoder */ #ifndef USE_VARARGS int timer(int timertype,int(*subrtn)(),...) #else int timer(va_alist) va_dcl #endif { va_list arg_marker; /* variable arg list */ char *timestring; time_t ltime; FILE *fp = NULL; int out=0; int i; int do_bench; #ifndef USE_VARARGS va_start(arg_marker,subrtn); #else int timertype; int (*subrtn)(); va_start(arg_marker); timertype = va_arg(arg_marker, int); subrtn = (int (*)())va_arg(arg_marker, int *); #endif do_bench = timerflag; /* record time? */ if (timertype == 2) /* encoder, record time only if debug=200 */ do_bench = (debugflag == 200); if(do_bench) fp=dir_fopen(workdir,"bench","a"); timer_start = clock_ticks(); switch(timertype) { case 0: out = (*(int(*)(void))subrtn)(); break; case 1: i = va_arg(arg_marker,int); out = (int)decoder((short)i); /* not indirect, safer with overlays */ break; case 2: out = encoder(); /* not indirect, safer with overlays */ break; } /* next assumes CLK_TCK is 10^n, n>=2 */ timer_interval = (clock_ticks() - timer_start) / (CLK_TCK/100); if(do_bench) { time(<ime); timestring = ctime(<ime); timestring[24] = 0; /*clobber newline in time string */ switch(timertype) { case 1: fprintf(fp,"decode "); break; case 2: fprintf(fp,"encode "); break; } fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%ld", timestring, curfractalspecific->name, xdots, ydots, maxit); fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100); if(fp != NULL) fclose(fp); } return(out); } xfractint-20.4.10.orig/common/mpmath_c.c0000644000000000000000000004414011455577757014763 0ustar /* MPMath_c.c (C) 1989, Mark C. Peterson, CompuServe [70441,3353] All rights reserved. Code may be used in any program provided the author is credited either during program execution or in the documentation. Source code may be distributed only in combination with public domain or shareware source code. Source code may be modified provided the copyright notice and this message is left unchanged and all modifications are clearly documented. I would appreciate a copy of any work which incorporates this code, however this is optional. Mark C. Peterson 405-C Queen St. Suite #181 Southington, CT 06489 (203) 276-9721 */ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif struct MP *MPsub(struct MP x, struct MP y) { y.Exp ^= 0x8000; return(MPadd(x, y)); } /* added by TW */ struct MP *MPsub086(struct MP x, struct MP y) { y.Exp ^= 0x8000; return(MPadd086(x, y)); } /* added by TW */ struct MP *MPsub386(struct MP x, struct MP y) { y.Exp ^= 0x8000; return(MPadd386(x, y)); } struct MP *MPabs(struct MP x) { Ans = x; Ans.Exp &= 0x7fff; return(&Ans); } struct MPC MPCsqr(struct MPC x) { struct MPC z; z.x = *pMPsub(*pMPmul(x.x, x.x), *pMPmul(x.y, x.y)); z.y = *pMPmul(x.x, x.y); z.y.Exp++; return(z); } struct MP MPCmod(struct MPC x) { return(*pMPadd(*pMPmul(x.x, x.x), *pMPmul(x.y, x.y))); } struct MPC MPCmul(struct MPC x, struct MPC y) { struct MPC z; z.x = *pMPsub(*pMPmul(x.x, y.x), *pMPmul(x.y, y.y)); z.y = *pMPadd(*pMPmul(x.x, y.y), *pMPmul(x.y, y.x)); return(z); } struct MPC MPCdiv(struct MPC x, struct MPC y) { struct MP mod; mod = MPCmod(y); y.y.Exp ^= 0x8000; y.x = *pMPdiv(y.x, mod); y.y = *pMPdiv(y.y, mod); return(MPCmul(x, y)); } struct MPC MPCadd(struct MPC x, struct MPC y) { struct MPC z; z.x = *pMPadd(x.x, y.x); z.y = *pMPadd(x.y, y.y); return(z); } struct MPC MPCsub(struct MPC x, struct MPC y) { struct MPC z; z.x = *pMPsub(x.x, y.x); z.y = *pMPsub(x.y, y.y); return(z); } struct MPC MPCone = { {0x3fff, 0x80000000l}, {0, 0l} }; struct MPC MPCpow(struct MPC x, int exp) { struct MPC z; struct MPC zz; if(exp & 1) z = x; else z = MPCone; exp >>= 1; while(exp) { zz.x = *pMPsub(*pMPmul(x.x, x.x), *pMPmul(x.y, x.y)); zz.y = *pMPmul(x.x, x.y); zz.y.Exp++; x = zz; if(exp & 1) { zz.x = *pMPsub(*pMPmul(z.x, x.x), *pMPmul(z.y, x.y)); zz.y = *pMPadd(*pMPmul(z.x, x.y), *pMPmul(z.y, x.x)); z = zz; } exp >>= 1; } return(z); } int MPCcmp(struct MPC x, struct MPC y) { struct MPC z; if(pMPcmp(x.x, y.x) || pMPcmp(x.y, y.y)) { z.x = MPCmod(x); z.y = MPCmod(y); return(pMPcmp(z.x, z.y)); } else return(0); } _CMPLX MPC2cmplx(struct MPC x) { _CMPLX z; z.x = *pMP2d(x.x); z.y = *pMP2d(x.y); return(z); } struct MPC cmplx2MPC(_CMPLX z) { struct MPC x; x.x = *pd2MP(z.x); x.y = *pd2MP(z.y); return(x); } /* function pointer versions added by Tim Wegner 12/07/89 */ /* int (*ppMPcmp)() = MPcmp086; */ int (*pMPcmp)(struct MP x, struct MP y) = MPcmp086; struct MP *(*pMPmul)(struct MP x, struct MP y)= MPmul086; struct MP *(*pMPdiv)(struct MP x, struct MP y)= MPdiv086; struct MP *(*pMPadd)(struct MP x, struct MP y)= MPadd086; struct MP *(*pMPsub)(struct MP x, struct MP y)= MPsub086; struct MP *(*pd2MP)(double x) = d2MP086 ; double *(*pMP2d)(struct MP m) = MP2d086 ; /* struct MP *(*pfg2MP)(long x, int fg) = fg2MP086; */ void setMPfunctions(void) { if(cpu >= 386) { pMPmul = MPmul386; pMPdiv = MPdiv386; pMPadd = MPadd386; pMPsub = MPsub386; pMPcmp = MPcmp386; pd2MP = d2MP386 ; pMP2d = MP2d386 ; /* pfg2MP = fg2MP386; */ } else { pMPmul = MPmul086; pMPdiv = MPdiv086; pMPadd = MPadd086; pMPsub = MPsub086; pMPcmp = MPcmp086; pd2MP = d2MP086 ; pMP2d = MP2d086 ; /* pfg2MP = fg2MP086; */ } } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif #endif /* XFRACT */ #ifndef sqr #define sqr(x) ((x)*(x)) #endif _CMPLX ComplexPower(_CMPLX xx, _CMPLX yy) { _CMPLX z, cLog, t; LDBL e2x; double siny, cosy; /* fixes power bug - if any complaints, backwards compatibility hook goes here TIW 3/95 */ if(ldcheck == 0) if(xx.x == 0.0 && xx.y == 0.0) { overflow = 1; z.x = z.y = 0.0; return(z); } FPUcplxlog(&xx, &cLog); FPUcplxmul(&cLog, &yy, &t); if(fpu >= 387) FPUcplxexp387(&t, &z); else { if(t.x < -690) e2x = 0.0; else e2x = expl(t.x); #ifdef XFRACT if (isnan(e2x) || isinf(e2x)) e2x = 1.0; #endif FPUsincos(&t.y, &siny, &cosy); z.x = (double) (e2x * cosy); z.y = (double) (e2x * siny); } return(z); } /* The following Complex function routines added by Tim Wegner November 1994. */ #define Sqrtz(z,rz) (*(rz) = ComplexSqrtFloat((z).x, (z).y)) /* rz=Arcsin(z)=-i*Log{i*z+sqrt(1-z*z)} */ void Arcsinz(_CMPLX z,_CMPLX *rz) { _CMPLX tempz1,tempz2; FPUcplxmul( &z, &z, &tempz1); tempz1.x = 1 - tempz1.x; tempz1.y = -tempz1.y; /* tempz1 = 1 - tempz1 */ Sqrtz( tempz1, &tempz1); tempz2.x = -z.y; tempz2.y = z.x; /* tempz2 = i*z */ tempz1.x += tempz2.x; tempz1.y += tempz2.y; /* tempz1 += tempz2 */ FPUcplxlog( &tempz1, &tempz1); rz->x = tempz1.y; rz->y = -tempz1.x; /* rz = (-i)*tempz1 */ } /* end. Arcsinz */ /* rz=Arccos(z)=-i*Log{z+sqrt(z*z-1)} */ void Arccosz(_CMPLX z,_CMPLX *rz) { _CMPLX temp; FPUcplxmul( &z, &z, &temp); temp.x -= 1; /* temp = temp - 1 */ Sqrtz( temp, &temp); temp.x += z.x; temp.y += z.y; /* temp = z + temp */ FPUcplxlog( &temp, &temp); rz->x = temp.y; rz->y = -temp.x; /* rz = (-i)*tempz1 */ } /* end. Arccosz */ void Arcsinhz(_CMPLX z,_CMPLX *rz) { _CMPLX temp; FPUcplxmul( &z, &z, &temp); temp.x += 1; /* temp = temp + 1 */ Sqrtz( temp, &temp); temp.x += z.x; temp.y += z.y; /* temp = z + temp */ FPUcplxlog( &temp, rz); } /* end. Arcsinhz */ /* rz=Arccosh(z)=Log(z+sqrt(z*z-1)} */ void Arccoshz(_CMPLX z,_CMPLX *rz) { _CMPLX tempz; FPUcplxmul( &z, &z, &tempz); tempz.x -= 1; /* tempz = tempz - 1 */ Sqrtz( tempz, &tempz); tempz.x = z.x + tempz.x; tempz.y = z.y + tempz.y; /* tempz = z + tempz */ FPUcplxlog( &tempz, rz); } /* end. Arccoshz */ /* rz=Arctanh(z)=1/2*Log{(1+z)/(1-z)} */ void Arctanhz(_CMPLX z,_CMPLX *rz) { _CMPLX temp0,temp1,temp2; if( z.x == 0.0){ rz->x = 0; rz->y = atan( z.y); return; } else{ if( fabs(z.x) == 1.0 && z.y == 0.0){ return; } else if( fabs( z.x) < 1.0 && z.y == 0.0){ rz->x = log((1+z.x)/(1-z.x))/2; rz->y = 0; return; } else{ temp0.x = 1 + z.x; temp0.y = z.y; /* temp0 = 1 + z */ temp1.x = 1 - z.x; temp1.y = -z.y; /* temp1 = 1 - z */ FPUcplxdiv( &temp0, &temp1, &temp2); FPUcplxlog( &temp2, &temp2); rz->x = .5*temp2.x; rz->y = .5*temp2.y; /* rz = .5*temp2 */ return; } } } /* end. Arctanhz */ /* rz=Arctan(z)=i/2*Log{(1-i*z)/(1+i*z)} */ void Arctanz(_CMPLX z,_CMPLX *rz) { _CMPLX temp0,temp1,temp2,temp3; if( z.x == 0.0 && z.y == 0.0) rz->x = rz->y = 0; else if( z.x != 0.0 && z.y == 0.0){ rz->x = atan( z.x); rz->y = 0; } else if( z.x == 0.0 && z.y != 0.0){ temp0.x = z.y; temp0.y = 0.0; Arctanhz( temp0, &temp0); rz->x = -temp0.y; rz->y = temp0.x; /* i*temp0 */ } else if( z.x != 0.0 && z.y != 0.0){ temp0.x = -z.y; temp0.y = z.x; /* i*z */ temp1.x = 1 - temp0.x; temp1.y = -temp0.y; /* temp1 = 1 - temp0 */ temp2.x = 1 + temp0.x; temp2.y = temp0.y; /* temp2 = 1 + temp0 */ FPUcplxdiv( &temp1, &temp2, &temp3); FPUcplxlog( &temp3, &temp3); rz->x = -temp3.y*.5; rz->y = .5*temp3.x; /* .5*i*temp0 */ } } /* end. Arctanz */ #define SinCosFudge 0x10000L #ifdef LONGSQRT long lsqrt(long f) { int N; unsigned long y0, z; static long a=0, b=0, c=0; /* constant factors */ if (f == 0) return f; if (f < 0) return 0; if (a==0) /* one-time compute consts */ { a = (long)(fudge * .41731); b = (long)(fudge * .59016); c = (long)(fudge * .7071067811); } N = 0; while (f & 0xff000000L) /* shift arg f into the */ { /* range: 0.5 <= f < 1 */ N++; f /= 2; } while (!(f & 0xff800000L)) { N--; f *= 2; } y0 = a + multiply(b, f, bitshift); /* Newton's approximation */ z = y0 + divide (f, y0, bitshift); y0 = (z>>2) + divide(f, z, bitshift); if (N % 2) { N++; y0 = multiply(c,y0, bitshift); } N /= 2; if (N >= 0) return y0 << N; /* correct for shift above */ else return y0 >> -N; } #endif LCMPLX ComplexSqrtLong(long x, long y) { double mag, theta; long maglong, thetalong; LCMPLX result; #ifndef LONGSQRT mag = sqrt(sqrt(((double) multiply(x,x,bitshift))/fudge + ((double) multiply(y,y,bitshift))/ fudge)); maglong = (long)(mag * fudge); #else maglong = lsqrt(lsqrt(multiply(x,x,bitshift)+multiply(y,y,bitshift))); #endif theta = atan2((double) y/fudge, (double) x/fudge)/2; thetalong = (long)(theta * SinCosFudge); SinCos086(thetalong, &result.y, &result.x); result.x = multiply(result.x << (bitshift - 16), maglong, bitshift); result.y = multiply(result.y << (bitshift - 16), maglong, bitshift); return result; } _CMPLX ComplexSqrtFloat(double x, double y) { double mag; double theta; _CMPLX result; if(x == 0.0 && y == 0.0) result.x = result.y = 0.0; else { mag = sqrt(sqrt(x*x + y*y)); theta = atan2(y, x) / 2; FPUsincos(&theta, &result.y, &result.x); result.x *= mag; result.y *= mag; } return result; } /***** FRACTINT specific routines and variables *****/ #ifndef TESTING_MATH BYTE far *LogTable = (BYTE far *)0; long MaxLTSize; int Log_Calc = 0; static double mlf; static unsigned long lf; /* int LogFlag; LogFlag == 1 -- standard log palettes LogFlag == -1 -- 'old' log palettes LogFlag > 1 -- compress counts < LogFlag into color #1 LogFlag < -1 -- use quadratic palettes based on square roots && compress */ void SetupLogTable(void) { float l, f, c, m; unsigned long prev, limit, sptop; unsigned n; if (save_release > 1920 || Log_Fly_Calc == 1) { /* set up on-the-fly variables */ if (LogFlag > 0) { /* new log function */ lf = (LogFlag > 1) ? LogFlag : 0; if (lf >= (unsigned long)MaxLTSize) lf = MaxLTSize - 1; mlf = (colors - (lf?2:1)) / log(MaxLTSize - lf); } else if (LogFlag == -1) { /* old log function */ mlf = (colors - 1) / log(MaxLTSize); } else if (LogFlag <= -2) { /* sqrt function */ if ((lf = 0 - LogFlag) >= (unsigned long)MaxLTSize) lf = MaxLTSize - 1; mlf = (colors - 2) / sqrt(MaxLTSize - lf); } } if (Log_Calc) return; /* LogTable not defined, bail out now */ if (save_release > 1920 && !Log_Calc) { Log_Calc = 1; /* turn it on */ for (prev = 0; prev <= (unsigned long)MaxLTSize; prev++) LogTable[prev] = (BYTE)logtablecalc((long)prev); Log_Calc = 0; /* turn it off, again */ return; } if (LogFlag > -2) { lf = (LogFlag > 1) ? LogFlag : 0; if (lf >= (unsigned long)MaxLTSize) lf = MaxLTSize - 1; Fg2Float((long)(MaxLTSize-lf), 0, m); fLog14(m, m); Fg2Float((long)(colors-(lf?2:1)), 0, c); fDiv(m, c, m); for (prev = 1; prev <= lf; prev++) LogTable[prev] = 1; for (n = (lf?2:1); n < (unsigned int)colors; n++) { Fg2Float((long)n, 0, f); fMul16(f, m, f); fExp14(f, l); limit = (unsigned long)Float2Fg(l, 0) + lf; if (limit > (unsigned long)MaxLTSize || n == (unsigned int)(colors-1)) limit = MaxLTSize; while (prev <= limit) LogTable[prev++] = (BYTE)n; } } else { if ((lf = 0 - LogFlag) >= (unsigned long)MaxLTSize) lf = MaxLTSize - 1; Fg2Float((long)(MaxLTSize-lf), 0, m); fSqrt14(m, m); Fg2Float((long)(colors-2), 0, c); fDiv(m, c, m); for (prev = 1; prev <= lf; prev++) LogTable[prev] = 1; for (n = 2; n < (unsigned int)colors; n++) { Fg2Float((long)n, 0, f); fMul16(f, m, f); fMul16(f, f, l); limit = (unsigned long)(Float2Fg(l, 0) + lf); if (limit > (unsigned long)MaxLTSize || n == (unsigned int)(colors-1)) limit = MaxLTSize; while (prev <= limit) LogTable[prev++] = (BYTE)n; } } LogTable[0] = 0; if (LogFlag != -1) for (sptop = 1; sptop < (unsigned long)MaxLTSize; sptop++) /* spread top to incl unused colors */ if (LogTable[sptop] > LogTable[sptop-1]) LogTable[sptop] = (BYTE)(LogTable[sptop-1]+1); } long logtablecalc(long citer) { long ret = 0; if (LogFlag == 0 && !rangeslen) /* Oops, how did we get here? */ return(citer); if (LogTable && !Log_Calc) return(LogTable[(long)min(citer, MaxLTSize)]); if (LogFlag > 0) { /* new log function */ if ((unsigned long)citer <= lf + 1) ret = 1; else if((citer - lf) / log(citer - lf) <= mlf) { if (save_release < 2002) ret = (long)(citer - lf + (lf?1:0)); else ret = (long)(citer - lf); } else ret = (long)(mlf * log(citer - lf)) + 1; } else if (LogFlag == -1) { /* old log function */ if (citer == 0) ret = 1; else ret = (long)(mlf * log(citer)) + 1; } else if (LogFlag <= -2) { /* sqrt function */ if ((unsigned long)citer <= lf) ret = 1; else if((unsigned long)(citer - lf) <= (unsigned long)(mlf * mlf)) ret = (long)(citer - lf + 1); else ret = (long)(mlf * sqrt(citer - lf)) + 1; } return (ret); } long far ExpFloat14(long xx) { static float fLogTwo = (float)0.6931472; int f; long Ans; f = 23 - (int)RegFloat2Fg(RegDivFloat(xx, *(long*)&fLogTwo), 0); Ans = ExpFudged(RegFloat2Fg(xx, 16), f); return(RegFg2Float(Ans, (char)f)); } double TwoPi; _CMPLX temp, BaseLog; _CMPLX cdegree = { 3.0, 0.0 }, croot = { 1.0, 0.0 }; int ComplexNewtonSetup(void) { threshold = .001; periodicitycheck = 0; if(param[0] != 0.0 || param[1] != 0.0 || param[2] != 0.0 || param[3] != 0.0) { croot.x = param[2]; croot.y = param[3]; cdegree.x = param[0]; cdegree.y = param[1]; FPUcplxlog(&croot, &BaseLog); TwoPi = asin(1.0) * 4; } return(1); } int ComplexNewton(void) { _CMPLX cd1; /* new = ((cdegree-1) * old**cdegree) + croot ---------------------------------- cdegree * old**(cdegree-1) */ cd1.x = cdegree.x - 1.0; cd1.y = cdegree.y; temp = ComplexPower(old, cd1); FPUcplxmul(&temp, &old, &new); tmp.x = new.x - croot.x; tmp.y = new.y - croot.y; if((sqr(tmp.x) + sqr(tmp.y)) < threshold) return(1); FPUcplxmul(&new, &cd1, &tmp); tmp.x += croot.x; tmp.y += croot.y; FPUcplxmul(&temp, &cdegree, &cd1); FPUcplxdiv(&tmp, &cd1, &old); if(overflow) { return(1); } new = old; return(0); } int ComplexBasin(void) { _CMPLX cd1; double mod; /* new = ((cdegree-1) * old**cdegree) + croot ---------------------------------- cdegree * old**(cdegree-1) */ cd1.x = cdegree.x - 1.0; cd1.y = cdegree.y; temp = ComplexPower(old, cd1); FPUcplxmul(&temp, &old, &new); tmp.x = new.x - croot.x; tmp.y = new.y - croot.y; if((sqr(tmp.x) + sqr(tmp.y)) < threshold) { if(fabs(old.y) < .01) old.y = 0.0; FPUcplxlog(&old, &temp); FPUcplxmul(&temp, &cdegree, &tmp); mod = tmp.y/TwoPi; coloriter = (long)mod; if(fabs(mod - coloriter) > 0.5) { if(mod < 0.0) coloriter--; else coloriter++; } coloriter += 2; if(coloriter < 0) coloriter += 128; return(1); } FPUcplxmul(&new, &cd1, &tmp); tmp.x += croot.x; tmp.y += croot.y; FPUcplxmul(&temp, &cdegree, &cd1); FPUcplxdiv(&tmp, &cd1, &old); if(overflow) { return(1); } new = old; return(0); } /* * Generate a gaussian distributed number. * The right half of the distribution is folded onto the lower half. * That is, the curve slopes up to the peak and then drops to 0. * The larger slope is, the smaller the standard deviation. * The values vary from 0+offset to range+offset, with the peak * at range+offset. * To make this more complicated, you only have a * 1 in Distribution*(1-Probability/Range*con)+1 chance of getting a * Gaussian; otherwise you just get offset. */ int GausianNumber(int Probability, int Range) { int n, r; long Accum = 0, p; p = divide((long)Probability << 16, (long)Range << 16, 16); p = multiply(p, con, 16); p = multiply((long)Distribution << 16, p, 16); if(!(rand15() % (Distribution - (int)(p >> 16) + 1))) { for(n = 0; n < Slope; n++) Accum += rand15(); Accum /= Slope; r = (int)(multiply((long)Range << 15, Accum, 15) >> 14); r = r - Range; if(r < 0) r = -r; return(Range - r + Offset); } return(Offset); } #endif xfractint-20.4.10.orig/common/memory.c0000644000000000000000000010362410541274375014467 0ustar #include #include #include #if (!defined(XFRACT) && !defined(WINFRACT)) #include #endif #ifndef USE_VARARGS #include #else #include #endif #include #include "port.h" #include "prototyp.h" /* Memory allocation routines. */ #if 1 /* For extra seg memory: */ #define EXTRA_RESERVE 4096L /* amount of extra mem we will leave avail. */ /* For far memory: */ #define FAR_RESERVE 8192L /* amount of far mem we will leave avail. */ /* For expanded memory: */ #define EXPWRITELEN 16384L /* max # bytes transferred to/from expanded mem at once */ /* For extended memory: */ #define XMMWRITELEN 8192L /* max # bytes transferred to/from extended mem at once */ /* For disk memory: */ #define DISKWRITELEN 2048L /* max # bytes transferred to/from disk mem at once */ BYTE far *charbuf = NULL; int numEXThandles; long ext_xfer_size; U16 start_avail_extra = 0; #endif #define MAXHANDLES 256 /* arbitrary #, suitably big */ char memfile[] = "handle.$$$"; int numTOTALhandles; #if (!defined(XFRACT) && !defined(WINFRACT)) char memstr[6][9] = {"nowhere", "extraseg", "far", "expanded", "extended", "disk"}; #endif #if (defined(XFRACT) || defined(WINFRACT)) char memstr[3][9] = {{"nowhere"}, {"far"}, {"disk"}}; #endif struct nowhere { enum stored_at_values stored_at; /* first 2 entries must be the same */ long size; /* for each of these data structures */ }; struct farmem { enum stored_at_values stored_at; long size; BYTE far *farmemory; }; struct disk { enum stored_at_values stored_at; long size; FILE *file; }; #if (!defined(XFRACT) && !defined(WINFRACT)) struct extra { enum stored_at_values stored_at; long size; BYTE far *extramemory; }; struct expanded { enum stored_at_values stored_at; long size; int oldexppage; int mempages; int emmhandle; BYTE far *expmemory; }; struct extended { enum stored_at_values stored_at; long size; int mempages; int xmmhandle; }; #endif union mem { struct nowhere Nowhere; struct farmem Farmem; struct disk Disk; #if (!defined(XFRACT) && !defined(WINFRACT)) struct extra Extra; struct expanded Expanded; struct extended Extended; #endif }; union mem far handletable[MAXHANDLES]; /* Routines in this module */ #ifndef XFRACT U32 GetDiskSpace(void); static void _fastcall near exp_seek(U16 handle, int page); /* expanded mem seek */ #endif static int _fastcall near CheckDiskSpace(long howmuch); static int check_for_mem(int stored_at, long howmuch); static U16 next_handle(void); static int CheckBounds (long start, long length, U16 handle); static void WhichDiskError(int); static void DisplayError(int stored_at, long howmuch); /* Routines in this module, visible to outside routines */ void DisplayMemory (void); void DisplayHandle (U16 handle); int MemoryType (U16 handle); void InitMemory (void); void ExitCheck (void); U16 MemoryAlloc(U16 size, long count, int stored_at); void MemoryRelease(U16 handle); int MoveToMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle); int MoveFromMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle); int SetMemory(int value,U16 size,long count,long offset,U16 handle); /* Memory handling support routines */ #ifndef XFRACT U32 GetDiskSpace(void) { /* Returns the number of bytes available on the current disk drive. */ U32 available = 0; union REGS regs; regs.h.ah = 0x36; /* Function 36, Get Disk Free Space */ regs.h.dl = 0; /* Check the default drive */ intdos(®s, ®s); if (regs.x.ax != 0xFFFF) /* Drive is valid */ available = (U32)regs.x.ax * regs.x.bx * regs.x.cx; return (available); } #endif static int _fastcall near CheckDiskSpace(long howmuch) { int EnoughSpace = FALSE; #ifndef XFRACT U32 available; available = GetDiskSpace(); if (available > (U32)howmuch) EnoughSpace = TRUE; #endif #ifdef XFRACT /* This will need to be fixed for XFRACT ????? */ EnoughSpace = TRUE; #endif return(EnoughSpace); } static void WhichDiskError(int I_O) { /* Set I_O == 1 after a file create, I_O == 2 after a file set value */ /* Set I_O == 3 after a file write, I_O == 4 after a file read */ #if (!defined(XFRACT) && !defined(WINFRACT)) char buf[MSGLEN]; char nmsg[MSGLEN]; static FCODE fmsg1[] = {"Disk file creation error"}; static FCODE fmsg2[] = {"Disk file set error"}; static FCODE fmsg3[] = {"Disk file write error"}; static FCODE fmsg4[] = {"Disk file read error"}; /* The following and the associated sprintf eat up 432 bytes of near memory. Only marginally useful for debugging purposes. static FCODE fmsg1[] = {"Create file error %d: %s"}; static FCODE fmsg2[] = {"Set file error %d: %s"}; static FCODE fmsg3[] = {"Write file error %d: %s"}; static FCODE fmsg4[] = {"Read file error %d: %s"}; */ switch (I_O) { default: case 1: far_strcpy(nmsg,fmsg1); break; case 2: far_strcpy(nmsg,fmsg2); break; case 3: far_strcpy(nmsg,fmsg3); break; case 4: far_strcpy(nmsg,fmsg4); break; } sprintf(buf,nmsg); /* sprintf(buf,nmsg,errno,strerror(errno)); */ if (debugflag == 10000) if(stopmsg(6,(char far *)buf) == -1) goodbye(); /* bailout if ESC */ #endif } #if (!defined(XFRACT) && !defined(WINFRACT)) static void _fastcall near exp_seek(U16 handle, int page) /* expanded mem seek */ { static U16 lasthandle = 0; if (page != handletable[handle].Expanded.oldexppage || page == 0 || lasthandle != handle) { /* time to get a new page? */ handletable[handle].Expanded.oldexppage = page; lasthandle = handle; emmgetpage(page, handletable[handle].Expanded.emmhandle); } } #endif int MemoryType (U16 handle) { return (handletable[handle].Nowhere.stored_at); } static void DisplayError(int stored_at, long howmuch) { /* This routine is used to display an error message when the requested */ /* memory type cannot be allocated due to insufficient memory, AND there */ /* is also insufficient disk space to use as memory. */ char buf[MSGLEN*2]; char nmsg[MSGLEN*2]; static FCODE fmsg[] = {"Allocating %ld Bytes of %s memory failed.\nAlternate disk space is also insufficient. Goodbye"}; far_strcpy(nmsg,fmsg); sprintf(buf,nmsg,howmuch,memstr[stored_at]); stopmsg(0,(char far *)buf); } static int check_for_mem(int stored_at, long howmuch) { /* This function returns an adjusted stored_at value. */ /* This is where the memory requested can be allocated. */ #if (!defined(XFRACT) && !defined(WINFRACT)) long usedmem, totalmem; long longtmp; int counter; #endif long maxmem; BYTE far *temp; int use_this_type; use_this_type = NOWHERE; maxmem = (long)USHRT_MAX; /* limit EXTRA and FARMEM to 64K */ /* limit EXPANDED and EXTENDED to 64K blocks */ if (debugflag == 420) stored_at = DISK; if (debugflag == 422) stored_at = EXTENDED; switch (stored_at) { #if (!defined(XFRACT) && !defined(WINFRACT)) case EXTRA: /* check_for_mem */ usedmem = 0L; for(counter = 0; counter < MAXHANDLES; counter++) if (handletable[counter].Nowhere.stored_at == EXTRA) usedmem += handletable[counter].Extra.size; if ((maxmem - usedmem) > howmuch) { use_this_type = EXTRA; break; } /* failed, fall through and try far memory */ #endif case FARMEM: /* check_for_mem */ if (maxmem > howmuch) { temp = (BYTE far *)farmemalloc(howmuch + FAR_RESERVE); if (temp != NULL) { /* minimum free space + requested amount */ farmemfree(temp); use_this_type = FARMEM; break; } } #if (!defined(XFRACT) && !defined(WINFRACT)) /* Failed, fall through and try expanded memory */ case EXPANDED: /* check_for_mem */ totalmem = (howmuch + 16383) >> 14; /* # of 16 KB blocks */ if ((totalmem < (long)USHRT_MAX) && (emmquery() != NULL)) { maxmem = emmgetfree(); /* reuse maxmem, so may not be good below */ if (maxmem > totalmem) { use_this_type = EXPANDED; break; } } /* Failed, fall through and try extended memory */ case EXTENDED: /* check_for_mem */ longtmp = (howmuch + 1023) >> 10; /* # of 1 KB blocks */ if (longtmp <= 0) longtmp = 1; if (xmmquery() != 0) if ((longtmp < (long)USHRT_MAX) && ((long)xmmfree() > longtmp)) { use_this_type = EXTENDED; break; } /* failed, fall through and try disk memory */ #endif case DISK: /* check_for_mem */ default: /* just in case a nonsense number gets used */ if (CheckDiskSpace(howmuch)) { use_this_type = DISK; break; } /* failed, fall through, no memory available */ case NOWHERE: /* check_for_mem */ use_this_type = NOWHERE; break; } /* end of switch */ return(use_this_type); } static U16 next_handle() { U16 counter = 1; /* don't use handle 0 */ while(handletable[counter].Nowhere.stored_at != NOWHERE && counter < MAXHANDLES) counter++; return (counter); } static int CheckBounds (long start, long length, U16 handle) { if(handletable[handle].Nowhere.size - start - length < 0) { static FCODE msg[] = {"Memory reference out of bounds."}; stopmsg(20,msg); DisplayHandle(handle); return (1); } if(length > (long)USHRT_MAX) { static FCODE msg[] = {"Tried to move > 65,535 bytes."}; stopmsg(20,msg); DisplayHandle(handle); return (1); } if(handletable[handle].Nowhere.stored_at == DISK && (stackavail() <= DISKWRITELEN) ) { static FCODE msg[] = {"Stack space insufficient for disk memory."}; stopmsg(20,msg); DisplayHandle(handle); return (1); } if(length <= 0) { static FCODE msg[] = {"Zero or negative length."}; stopmsg(20,msg); DisplayHandle(handle); return (1); } if(start < 0) { static FCODE msg[] = {"Negative offset."}; stopmsg(20,msg); DisplayHandle(handle); return (1); } return (0); } void DisplayMemory (void) { #if (!defined(XFRACT) && !defined(WINFRACT)) long tmpfar; U32 tmpdisk; char buf[MSGLEN]; char nmsg[MSGLEN]; /* #ifdef XFRACT static FCODE fmsg[] = {"far=%ld, disk=%lu"}; */ static FCODE fmsg[] = {"extra=%ld, far=%ld, expanded=%ld,\nextended=%ld, disk=%lu"}; long tmpextra, tmpexp, tmpext; tmpextra = USHRT_MAX - start_avail_extra; if (emmquery() != NULL) tmpexp = (long)emmgetfree() * 16L * 1024L; else tmpexp = 0; if (xmmquery() != 0) tmpext = (long)xmmfree() * 1024L; else tmpext = 0; tmpdisk = GetDiskSpace(); /* fix this for XFRACT ????? */ tmpfar = fr_farfree(); far_strcpy(nmsg,fmsg); sprintf(buf,nmsg,tmpextra,tmpfar,tmpexp,tmpext,tmpdisk); stopmsg(20,(char far *)buf); #endif } void DisplayHandle (U16 handle) { char buf[MSGLEN]; char nmsg[MSGLEN]; static FCODE fmsg[] = {"Handle %u, type %s, size %li"}; far_strcpy(nmsg,fmsg); sprintf(buf,nmsg,handle,memstr[handletable[handle].Nowhere.stored_at], handletable[handle].Nowhere.size); if(stopmsg(6,(char far *)buf) == -1) goodbye(); /* bailout if ESC, it's messy, but should work */ } void InitMemory (void) { int counter; #if (!defined(XFRACT) && !defined(WINFRACT)) long longtmp; #endif numTOTALhandles = 0; for (counter = 0; counter < MAXHANDLES; counter++) { handletable[counter].Nowhere.stored_at = NOWHERE; handletable[counter].Nowhere.size = 0; } #if (!defined(XFRACT) && !defined(WINFRACT)) numEXThandles = 0; longtmp = fr_farfree(); ext_xfer_size = XMMWRITELEN; /* 8192 */ if (longtmp < (long)XMMWRITELEN * 8) ext_xfer_size = XMMWRITELEN / 2; /* 4096 */ if (longtmp < (long)XMMWRITELEN) ext_xfer_size = XMMWRITELEN / 8; /* 1024, won't work, try anyway */ #endif } void ExitCheck (void) { U16 i; if(/*charbuf != NULL ||*/ numEXThandles != 0 || numTOTALhandles != 0) { static FCODE msg[] = {"Error - not all memory released, I'll get it."}; stopmsg(0,msg); for (i = 1; i < MAXHANDLES; i++) if (handletable[i].Nowhere.stored_at != NOWHERE) { char buf[MSGLEN]; char nmsg[MSGLEN]; static FCODE fmsg[] = {"Memory type %s still allocated. Handle = %i."}; far_strcpy(nmsg,fmsg); sprintf(buf,nmsg,memstr[handletable[i].Nowhere.stored_at],i); stopmsg(0,(char far *)buf); MemoryRelease(i); } } } /* * * * * */ /* Memory handling routines */ U16 MemoryAlloc(U16 size, long count, int stored_at) { /* Returns handle number if successful, 0 or NULL if failure */ U16 handle = 0; int success, use_this_type; long toallocate; #if (!defined(XFRACT) && !defined(WINFRACT)) BYTE far *temp; long longtmp; int mempages = 0; struct XMM_Move MoveStruct; #endif success = FALSE; toallocate = count * size; if (toallocate <= 0) /* we failed, can't allocate > 2,147,483,647 */ return((U16)success); /* or it wraps around to negative */ #if (defined(XFRACT) || defined(WINFRACT)) /* this is ugly, but keeps us from having to change every call to */ /* MemoryAlloc(). JCO */ stored_at = FARMEM; #endif /* check structure for requested memory type (add em up) to see if sufficient amount is available to grant request */ use_this_type = check_for_mem(stored_at, toallocate); if (use_this_type == NOWHERE) { DisplayError(stored_at, toallocate); goodbye(); } /* get next available handle */ handle = next_handle(); if (handle >= MAXHANDLES || handle <= 0) { DisplayHandle(handle); return((U16)success); /* Oops, do something about this! ????? */ } /* attempt to allocate requested memory type */ switch (use_this_type) { case NOWHERE: /* MemoryAlloc */ use_this_type = NOWHERE; /* in case nonsense value is passed */ break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXTRA: /* MemoryAlloc */ handletable[handle].Extra.size = toallocate; handletable[handle].Extra.stored_at = EXTRA; handletable[handle].Extra.extramemory = (BYTE far *)MK_FP(extraseg,start_avail_extra); start_avail_extra += (U16)toallocate; numTOTALhandles++; success = TRUE; break; #endif case FARMEM: /* MemoryAlloc */ /* Availability of far memory checked in check_for_mem() */ handletable[handle].Farmem.farmemory = (BYTE far *)farmemalloc(toallocate); handletable[handle].Farmem.size = toallocate; handletable[handle].Farmem.stored_at = FARMEM; numTOTALhandles++; success = TRUE; break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXPANDED: /* MemoryAlloc */ mempages = (int)((toallocate + 16383) >> 14); if (emmquery() != NULL) { handletable[handle].Expanded.mempages = mempages; handletable[handle].Expanded.expmemory = emmquery(); if ((handletable[handle].Expanded.emmhandle = emmallocate(mempages)) != 0) { handletable[handle].Expanded.oldexppage = 0; handletable[handle].Expanded.size = toallocate; handletable[handle].Expanded.stored_at = EXPANDED; numTOTALhandles++; success = TRUE; break; } } case EXTENDED: /* MemoryAlloc */ /* This is ugly! Need far memory to use extended memory. */ if (charbuf == NULL) { /* first time through, allocate buffer */ temp = (BYTE far *)farmemalloc((long)ext_xfer_size + FAR_RESERVE); if (temp != NULL) /* minimum free space + requested amount */ { farmemfree(temp); charbuf = (BYTE far *)farmemalloc((long)ext_xfer_size); } else goto dodisk; } if (toallocate < ext_xfer_size) longtmp = (ext_xfer_size + 1023) >> 10; else longtmp = (toallocate + 1023) >> 10; if (xmmquery() != 0 && (handletable[handle].Extended.xmmhandle = xmmallocate((U16)(longtmp))) != 0) { longtmp /= (ext_xfer_size >> 10); handletable[handle].Extended.mempages = (int)longtmp; far_memset(charbuf, 0, (int)ext_xfer_size); /* zero the buffer */ MoveStruct.SourceHandle = 0; /* Source is in conventional memory */ MoveStruct.SourceOffset = (U32)charbuf; MoveStruct.DestHandle = handletable[handle].Extended.xmmhandle; MoveStruct.DestOffset = 0; MoveStruct.Length = (long)ext_xfer_size; while (--longtmp >= 0) { if ((success = xmmmoveextended(&MoveStruct)) == 0) break; MoveStruct.DestOffset += ext_xfer_size; } if (success) { /* put in structure */ success = TRUE; handletable[handle].Extended.size = toallocate; handletable[handle].Extended.stored_at = EXTENDED; numTOTALhandles++; numEXThandles++; break; } xmmdeallocate(handletable[handle].Extended.xmmhandle); /* Clear the memory */ handletable[handle].Extended.xmmhandle = 0; /* Signal same */ } /* need to fall through and use disk memory, or will crash fractint */ dodisk: #endif default: case DISK: /* MemoryAlloc */ memfile[9] = (char)(handle % 10 + (int)'0'); memfile[8] = (char)((handle % 100) / 10 + (int)'0'); memfile[7] = (char)((handle % 1000) / 100 + (int)'0'); if (disktarga) handletable[handle].Disk.file = dir_fopen(workdir,light_name, "a+b"); else handletable[handle].Disk.file = dir_fopen(tempdir,memfile, "w+b"); rewind(handletable[handle].Disk.file); if (fseek(handletable[handle].Disk.file,toallocate,SEEK_SET) != 0) handletable[handle].Disk.file = NULL; if (handletable[handle].Disk.file == NULL) { handletable[handle].Disk.stored_at = NOWHERE; use_this_type = NOWHERE; WhichDiskError(1); DisplayMemory(); buzzer(3); break; } numTOTALhandles++; success = TRUE; fclose(handletable[handle].Disk.file); /* so clusters aren't lost if we crash while running */ if (disktarga) handletable[handle].Disk.file = dir_fopen(workdir,light_name, "r+b"); else handletable[handle].Disk.file = dir_fopen(tempdir,memfile,"r+b"); /* reopen */ rewind(handletable[handle].Disk.file); handletable[handle].Disk.size = toallocate; handletable[handle].Disk.stored_at = DISK; use_this_type = DISK; break; } /* end of switch */ if (stored_at != use_this_type && debugflag == 10000) { char buf[MSGLEN]; char nmsg[MSGLEN]; static FCODE fmsg[] = {"Asked for %s, allocated %lu bytes of %s, handle = %u."}; far_strcpy(nmsg,fmsg); sprintf(buf,nmsg,memstr[stored_at],toallocate,memstr[use_this_type],handle); stopmsg(20,(char far *)buf); DisplayMemory(); } if (success) return (handle); else /* return 0 if failure */ return 0; } void MemoryRelease(U16 handle) { switch(handletable[handle].Nowhere.stored_at) { case NOWHERE: /* MemoryRelease */ break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXTRA: /* MemoryRelease */ /* Deallocate in the reverse order of allocation. */ start_avail_extra -= (U16)handletable[handle].Extra.size; handletable[handle].Extra.size = 0; handletable[handle].Extra.stored_at = NOWHERE; handletable[handle].Extra.extramemory = NULL; numTOTALhandles--; break; #endif case FARMEM: /* MemoryRelease */ farmemfree(handletable[handle].Farmem.farmemory); handletable[handle].Farmem.farmemory = NULL; handletable[handle].Farmem.size = 0; handletable[handle].Farmem.stored_at = NOWHERE; numTOTALhandles--; break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXPANDED: /* MemoryRelease */ emmdeallocate(handletable[handle].Expanded.emmhandle); handletable[handle].Expanded.emmhandle = 0; handletable[handle].Expanded.size = 0; handletable[handle].Expanded.stored_at = NOWHERE; numTOTALhandles--; break; case EXTENDED: /* MemoryRelease */ /* far memory allocated for this must be released */ numEXThandles--; xmmdeallocate(handletable[handle].Extended.xmmhandle); if (numEXThandles == 0) { farmemfree(charbuf); charbuf = NULL; } handletable[handle].Extended.xmmhandle = 0; handletable[handle].Extended.size = 0; handletable[handle].Extended.stored_at = NOWHERE; numTOTALhandles--; break; #endif case DISK: /* MemoryRelease */ memfile[9] = (char)(handle % 10 + (int)'0'); memfile[8] = (char)((handle % 100) / 10 + (int)'0'); memfile[7] = (char)((handle % 1000) / 100 + (int)'0'); fclose(handletable[handle].Disk.file); dir_remove(tempdir,memfile); handletable[handle].Disk.file = NULL; handletable[handle].Disk.size = 0; handletable[handle].Disk.stored_at = NOWHERE; numTOTALhandles--; break; } /* end of switch */ } int MoveToMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle) { /* buffer is a pointer to local memory */ /* Always start moving from the beginning of buffer */ /* offset is the number of units from the start of the allocated "Memory" */ /* to start moving the contents of buffer to */ /* size is the size of the unit, count is the number of units to move */ /* Returns TRUE if successful, FALSE if failure */ #if (!defined(XFRACT) && !defined(WINFRACT)) int currpage; long tmplength; struct XMM_Move MoveStruct; #endif BYTE diskbuf[DISKWRITELEN]; long start; /* offset to first location to move to */ long tomove; /* number of bytes to move */ U16 numwritten, i; int success; success = FALSE; start = (long)offset * size; tomove = (long)count * size; if (debugflag == 10000) if (CheckBounds(start, tomove, handle)) return(success); /* out of bounds, don't do it */ switch(handletable[handle].Nowhere.stored_at) { case NOWHERE: /* MoveToMemory */ DisplayHandle(handle); break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXTRA: /* MoveToMemory */ far_memcpy(handletable[handle].Extra.extramemory+start, buffer, (U16)tomove); success = TRUE; /* No way to gauge success or failure */ break; #endif case FARMEM: /* MoveToMemory */ for(i=0;i tomove) tmplength = tomove; far_memcpy(handletable[handle].Expanded.expmemory+start, buffer, (U16)tmplength); buffer += tmplength; tomove -= tmplength; /* At a page boundary, move until less than a page left */ while (tomove >= EXPWRITELEN) { currpage++; exp_seek(handle, currpage); far_memcpy(handletable[handle].Expanded.expmemory, buffer, (U16)EXPWRITELEN); buffer += EXPWRITELEN; tomove -= EXPWRITELEN; } /* Less than a page left, move it */ if (tomove > 0) /* still some left */ { currpage++; exp_seek(handle, currpage); far_memcpy(handletable[handle].Expanded.expmemory, buffer, (U16)tomove); } exp_seek(handle, 0); /* flush the last page out of the page frame */ success = TRUE; /* No way to gauge success or failure */ break; case EXTENDED: /* MoveToMemory */ MoveStruct.Length = ext_xfer_size; MoveStruct.SourceHandle = 0; /* Source is conventional memory */ MoveStruct.SourceOffset = (U32)charbuf; MoveStruct.DestHandle = handletable[handle].Extended.xmmhandle; MoveStruct.DestOffset = (U32)start; while (tomove > ext_xfer_size) { far_memcpy(charbuf,buffer,(int)ext_xfer_size); xmmmoveextended(&MoveStruct); start += ext_xfer_size; tomove -= ext_xfer_size; buffer += ext_xfer_size; MoveStruct.DestOffset = (U32)(start); } far_memcpy(charbuf,buffer,(U16)tomove); MoveStruct.Length = (tomove % 2) ? tomove + 1 : tomove; /* must be even */ success = xmmmoveextended(&MoveStruct); break; #endif case DISK: /* MoveToMemory */ rewind(handletable[handle].Disk.file); fseek(handletable[handle].Disk.file,start,SEEK_SET); while (tomove > DISKWRITELEN) { far_memcpy(diskbuf,buffer,(U16)DISKWRITELEN); numwritten = (U16)write1(diskbuf,(U16)DISKWRITELEN,1,handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(3); goto diskerror; } tomove -= DISKWRITELEN; buffer += DISKWRITELEN; } far_memcpy(diskbuf,buffer,(U16)tomove); numwritten = (U16)write1(diskbuf,(U16)tomove,1,handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(3); break; } success = TRUE; diskerror: break; } /* end of switch */ if (!success && debugflag == 10000) DisplayHandle(handle); return (success); } int MoveFromMemory(BYTE far *buffer,U16 size,long count,long offset,U16 handle) { /* buffer points is the location to move the data to */ /* offset is the number of units from the beginning of buffer to start moving */ /* size is the size of the unit, count is the number of units to move */ /* Returns TRUE if successful, FALSE if failure */ #if (!defined(XFRACT) && !defined(WINFRACT)) int currpage; long tmplength; struct XMM_Move MoveStruct; #endif BYTE diskbuf[DISKWRITELEN]; long start; /* first location to move */ long tomove; /* number of bytes to move */ U16 numread, i; int success; success = FALSE; start = (long)offset * size; tomove = (long)count * size; if (debugflag == 10000) if (CheckBounds(start, tomove, handle)) return(success); /* out of bounds, don't do it */ switch(handletable[handle].Nowhere.stored_at) { case NOWHERE: /* MoveFromMemory */ DisplayHandle(handle); break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXTRA: /* MoveFromMemory */ far_memcpy(buffer, handletable[handle].Extra.extramemory+start, (U16)tomove); success = TRUE; /* No way to gauge success or failure */ break; #endif case FARMEM: /* MoveFromMemory */ for(i=0;i tomove) tmplength = tomove; far_memcpy(buffer, handletable[handle].Expanded.expmemory+start, (U16)tmplength); buffer += tmplength; tomove -= tmplength; /* At a page boundary, move until less than a page left */ while (tomove >= EXPWRITELEN) { currpage++; exp_seek(handle, currpage); far_memcpy(buffer, handletable[handle].Expanded.expmemory, (U16)EXPWRITELEN); buffer += EXPWRITELEN; tomove -= EXPWRITELEN; } /* Less than a page left, move it */ if (tomove > 0) /* still some left */ { currpage++; exp_seek(handle, currpage); far_memcpy(buffer, handletable[handle].Expanded.expmemory, (U16)tomove); } exp_seek(handle, 0); /* flush the last page out of the page frame */ success = TRUE; /* No way to gauge success or failure */ break; case EXTENDED: /* MoveFromMemory */ MoveStruct.Length = ext_xfer_size; MoveStruct.SourceHandle = handletable[handle].Extended.xmmhandle; MoveStruct.SourceOffset = (U32)start; MoveStruct.DestHandle = 0; /* Destination is conventional memory */ MoveStruct.DestOffset = (U32)charbuf; while (tomove > ext_xfer_size) { xmmmoveextended(&MoveStruct); far_memcpy(buffer,charbuf,(int)ext_xfer_size); buffer += ext_xfer_size; tomove -= ext_xfer_size; start += ext_xfer_size; MoveStruct.SourceOffset = (U32)start; } MoveStruct.Length = (tomove % 2) ? tomove + 1 : tomove; /* must be even */ success = xmmmoveextended(&MoveStruct); far_memcpy(buffer,charbuf,(U16)tomove); break; #endif case DISK: /* MoveFromMemory */ rewind(handletable[handle].Disk.file); fseek(handletable[handle].Disk.file,start,SEEK_SET); while (tomove > DISKWRITELEN) { numread = (U16)fread(diskbuf,(U16)DISKWRITELEN,1,handletable[handle].Disk.file); if (numread != 1 && !feof(handletable[handle].Disk.file)) { WhichDiskError(4); goto diskerror; } far_memcpy(buffer,diskbuf,(U16)DISKWRITELEN); tomove -= DISKWRITELEN; buffer += DISKWRITELEN; } numread = (U16)fread(diskbuf,(U16)tomove,1,handletable[handle].Disk.file); if (numread != 1 && !feof(handletable[handle].Disk.file)) { WhichDiskError(4); break; } far_memcpy(buffer,diskbuf,(U16)tomove); success = TRUE; diskerror: break; } /* end of switch */ if (!success && debugflag == 10000) DisplayHandle(handle); return (success); } int SetMemory(int value,U16 size,long count,long offset,U16 handle) { /* value is the value to set memory to */ /* offset is the number of units from the start of allocated memory */ /* size is the size of the unit, count is the number of units to set */ /* Returns TRUE if successful, FALSE if failure */ #if (!defined(XFRACT) && !defined(WINFRACT)) int currpage; long tmplength; struct XMM_Move MoveStruct; #endif BYTE diskbuf[DISKWRITELEN]; long start; /* first location to set */ long tomove; /* number of bytes to set */ U16 numwritten, i; int success; success = FALSE; start = (long)offset * size; tomove = (long)count * size; if (debugflag == 10000) if (CheckBounds(start, tomove, handle)) return(success); /* out of bounds, don't do it */ switch(handletable[handle].Nowhere.stored_at) { case NOWHERE: /* SetMemory */ DisplayHandle(handle); break; #if (!defined(XFRACT) && !defined(WINFRACT)) case EXTRA: /* SetMemory */ far_memset(handletable[handle].Extra.extramemory+start, value, (U16)tomove); success = TRUE; /* No way to gauge success or failure */ break; #endif case FARMEM: /* SetMemory */ for(i=0;i tomove) tmplength = tomove; far_memset(handletable[handle].Expanded.expmemory+start, value, (U16)tmplength); tomove -= tmplength; /* At a page boundary, move until less than a page left */ while (tomove >= EXPWRITELEN) { currpage++; exp_seek(handle, currpage); far_memcpy(handletable[handle].Expanded.expmemory, &value, (U16)EXPWRITELEN); tomove -= EXPWRITELEN; } /* Less than a page left, move it */ if (tomove > 0) /* still some left */ { currpage++; exp_seek(handle, currpage); far_memcpy(handletable[handle].Expanded.expmemory, &value, (U16)tomove); } exp_seek(handle, 0); /* flush the last page out of the page frame */ success = TRUE; /* No way to gauge success or failure */ break; case EXTENDED: /* SetMemory */ MoveStruct.Length = ext_xfer_size; MoveStruct.SourceHandle = 0; /* Source is conventional memory */ MoveStruct.SourceOffset = (U32)charbuf; MoveStruct.DestHandle = handletable[handle].Extended.xmmhandle; MoveStruct.DestOffset = (U32)start; far_memset(charbuf, value, (int)ext_xfer_size); while (tomove > ext_xfer_size) { xmmmoveextended(&MoveStruct); start += ext_xfer_size; tomove -= ext_xfer_size; MoveStruct.DestOffset = (U32)(start); } MoveStruct.Length = (tomove % 2) ? tomove + 1 : tomove; /* must be even */ success = xmmmoveextended(&MoveStruct); break; #endif case DISK: /* SetMemory */ far_memset(diskbuf, value, (U16)DISKWRITELEN); rewind(handletable[handle].Disk.file); fseek(handletable[handle].Disk.file,start,SEEK_SET); while (tomove > DISKWRITELEN) { numwritten = (U16)write1(diskbuf,(U16)DISKWRITELEN,1,handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(2); goto diskerror; } tomove -= DISKWRITELEN; } numwritten = (U16)write1(diskbuf,(U16)tomove,1,handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(2); break; } success = TRUE; diskerror: break; } /* end of switch */ if (!success && debugflag == 10000) DisplayHandle(handle); return (success); } xfractint-20.4.10.orig/common/help.c0000644000000000000000000012163111257714555014111 0ustar /* * help.c * * * * Revision history: * * 2-26-90 EAN Initial version. * * */ #ifndef TEST /* kills all those assert macros in production version */ #define NDEBUG #endif #define INCLUDE_COMMON /* include common code in helpcom.h */ #ifndef XFRACT #include #endif #include #include #include #include #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #define MAX_HIST 16 /* number of pages we'll remember */ #define ALT_F1 1104 #define ACTION_CALL 0 /* values returned by help_topic() */ #define ACTION_PREV 1 #define ACTION_PREV2 2 /* special - go back two topics */ #define ACTION_INDEX 3 #define ACTION_QUIT 4 #define F_HIST (1<<0) /* flags for help_topic() */ #define F_INDEX (1<<1) #define MAX_PAGE_SIZE (80*25) /* no page of text may be larger */ #define TEXT_START_ROW 2 /* start print the help text here */ typedef struct { BYTE r, c; int width; unsigned offset; int topic_num; unsigned topic_off; } LINK; typedef struct { int topic_num; unsigned topic_off; } LABEL; typedef struct { unsigned offset; unsigned len; int margin; } PAGE; typedef struct { int topic_num; unsigned topic_off; int link; } HIST; struct help_sig_info { unsigned long sig; int version; unsigned long base; /* only if added to fractint.exe */ } ; void print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg ); static int print_doc_msg_func(int pnum, int num_pages); /* stuff from fractint */ static int help_file = -1; /* help file handle */ static long base_off; /* offset to help info in help file */ static int max_links; /* max # of links in any page */ static int max_pages; /* max # of pages in any topic */ static int num_label; /* number of labels */ static int num_topic; /* number of topics */ static int curr_hist = 0; /* current pos in history */ /* these items alloc'ed in init_help... */ static long far *topic_offset; /* 4*num_topic */ static LABEL far *label; /* 4*num_label */ static HIST far *hist; /* 6*MAX_HIST (96 bytes) */ /* these items alloc'ed only while help is active... */ static char far *buffer; /* MAX_PAGE_SIZE (2048 bytes) */ static LINK far *link_table; /* 10*max_links */ static PAGE far *page_table; /* 4*max_pages */ static void help_seek(long pos) { lseek(help_file, base_off+pos, SEEK_SET); } static void displaycc(int row, int col, int color, int ch) { #ifndef XFRACT static char *s = "?"; #else static char s[] = "?"; #endif if (text_type == 1) /* if 640x200x2 mode */ { /* * This is REALLY ugly, but it works. Non-current links (ones that * would be bold if 640x200 supported it) are in upper-case and the * current item is inversed. * */ if (color & INVERSE) /* active link */ color = (signed int)INVERSE; else if (color & BRIGHT) /* inactive link */ { color = 0; /* normal */ if (ch>='a' && ch<='z') ch += 'A' - 'a'; } else /* normal */ color = 0; } s[0] = (char)ch; putstring(row, col, color, s); } static void display_text(int row, int col, int color, char far *text, unsigned len) { while (len-- != 0) { if (*text == CMD_LITERAL) { ++text; --len; } displaycc(row, col++, color, *text++); } } static void display_parse_text(char far *text, unsigned len, int start_margin, int *num_link, LINK far *link) { char far *curr; int row, col; int tok; int size, width; textcbase = SCREEN_INDENT; textrbase = TEXT_START_ROW; curr = text; row = 0; col = 0; size = width = 0; if (start_margin >= 0) tok = TOK_PARA; else tok = -1; for(;;) { switch ( tok ) { case TOK_PARA: { int indent, margin; if (size > 0) { ++curr; indent = *curr++; margin = *curr++; len -= 3; } else { indent = start_margin; margin = start_margin; } col = indent; for(;;) { tok = find_token_length(ONLINE, curr, len, &size, &width); if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF ) break; if (tok == TOK_PARA) { col = 0; /* fake a new-line */ row++; break; } if (tok == TOK_XONLINE || tok == TOK_XDOC) { curr += size; len -= size; continue; } /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */ if (col+width > SCREEN_WIDTH) { /* go to next line... */ col = margin; ++row; if ( tok == TOK_SPACE ) width = 0; /* skip spaces at start of a line */ } if (tok == TOK_LINK) { display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width); if (num_link != NULL) { link[*num_link].r = (BYTE)row; link[*num_link].c = (BYTE)col; link[*num_link].topic_num = getint(curr+1); link[*num_link].topic_off = getint(curr+1+sizeof(int)); link[*num_link].offset = (unsigned) ((curr+1+3*sizeof(int)) - text); link[*num_link].width = width; ++(*num_link); } } else if (tok == TOK_WORD ) display_text(row, col, C_HELP_BODY, curr, width); col += width; curr += size; len -= size; } width = size = 0; break; } case TOK_CENTER: col = find_line_width(ONLINE, curr, len); col = (SCREEN_WIDTH-col)/2; if (col < 0) col = 0; break; case TOK_NL: col = 0; ++row; break; case TOK_LINK: display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width); if (num_link != NULL) { link[*num_link].r = (BYTE)row; link[*num_link].c = (BYTE)col; link[*num_link].topic_num = getint(curr+1); link[*num_link].topic_off = getint(curr+1+sizeof(int)); link[*num_link].offset = (unsigned) ((curr+1+3*sizeof(int)) - text); link[*num_link].width = width; ++(*num_link); } break; case TOK_XONLINE: /* skip */ case TOK_FF: /* ignore */ case TOK_XDOC: /* ignore */ case TOK_DONE: case TOK_SPACE: break; case TOK_WORD: display_text(row, col, C_HELP_BODY, curr, width); break; } /* switch */ curr += size; len -= size; col += width; if (len == 0) break; tok = find_token_length(ONLINE, curr, len, &size, &width); } /* for(;;) */ textcbase = 0; textrbase = 0; } static void color_link(LINK far *link, int color) { textcbase = SCREEN_INDENT; textrbase = TEXT_START_ROW; if (text_type == 1) /* if 640x200x2 mode */ display_text(link->r, link->c, color, buffer+link->offset, link->width); else setattr(link->r, link->c, color, link->width); textcbase = 0; textrbase = 0; } /* #define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR_KEYS,name), putstring(-1,-1,C_HELP_INSTR," "descrip" ") */ #ifndef XFRACT #define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR,name); putstring(-1,-1,C_HELP_INSTR,":"descrip" ") #else #define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR,name);\ putstring(-1,-1,C_HELP_INSTR,":");\ putstring(-1,-1,C_HELP_INSTR,descrip);\ putstring(-1,-1,C_HELP_INSTR," ") #endif static void helpinstr(void) { int ctr; for (ctr=0; ctr<80; ctr++) putstring(24, ctr, C_HELP_INSTR, " "); movecursor(24, 1); PUT_KEY("F1", "Index"); #ifndef XFRACT PUT_KEY("\030\031\033\032", "Select"); #else PUT_KEY("K J H L", "Select"); #endif PUT_KEY("Enter", "Go to"); PUT_KEY("Backspace", "Last topic"); PUT_KEY("Escape", "Exit help"); } static void printinstr(void) { int ctr; for (ctr=0; ctr<80; ctr++) putstring(24, ctr, C_HELP_INSTR, " "); movecursor(24, 1); PUT_KEY("Escape", "Abort"); } #undef PUT_KEY static void display_page(char far *title, char far *text, unsigned text_len, int page, int num_pages, int start_margin, int *num_link, LINK far *link) { char temp[9]; helptitle(); helpinstr(); setattr(2, 0, C_HELP_BODY, 80*22); putstringcenter(1, 0, 80, C_HELP_HDG, title); sprintf(temp, "%2d of %d", page+1, num_pages); #ifndef XFRACT putstring(1, 79-(6 + ((num_pages>=10)?2:1)), C_HELP_INSTR, temp); #else /* Some systems (Ultrix) mess up if you write to column 80 */ putstring(1, 78-(6 + ((num_pages>=10)?2:1)), C_HELP_INSTR, temp); #endif if (text != NULL) display_parse_text(text, text_len, start_margin, num_link, link); movecursor(25, 80); /* hide cursor */ } /* * int overlap(int a, int a2, int b, int b2); * * If a, a2, b, and b2 are points on a line, this function returns the * distance of intersection between a-->a2 and b-->b2. If there is no * intersection between the lines this function will return a negative number * representing the distance between the two lines. * * There are six possible cases of intersection between the lines: * * a a2 * | | * b b2 | | b b2 * |---(1)---| | | |---(2)---| * | | * b | b2 b | b2 * |------(3)----| |------(4)-----| * | | * b | | b2 * |------+--------(5)----------+---| * | | * | b b2 | * | |--(6)--| | * | | * | | * */ static int overlap(int a, int a2, int b, int b2) { if ( b < a ) { if ( b2 >= a2 ) return ( a2 - a ); /* case (5) */ return ( b2 - a ); /* case (1), case (3) */ } if ( b2 <= a2 ) return ( b2 - b ); /* case (6) */ return ( a2 - b ); /* case (2), case (4) */ } static int dist1(int a, int b) { int t = a - b; return (abs(t)); } #ifdef __TURBOC__ # pragma warn -def /* turn off "Possible use before definition" warning */ #endif static int find_link_updown(LINK far *link, int num_link, int curr_link, int up) { int ctr, curr_c2, best_overlap = 0, temp_overlap; LINK far *curr, far *temp, far *best; int temp_dist; curr = &link[curr_link]; best = NULL; curr_c2 = curr->c + curr->width - 1; for (ctr=0, temp=link; ctrr < curr->r) || (!up && temp->r > curr->r) ) ) { temp_overlap = overlap(curr->c, curr_c2, temp->c, temp->c+temp->width-1); /* if >= 3 lines between, prioritize on vertical distance: */ if ((temp_dist = dist1(temp->r, curr->r)) >= 4) temp_overlap -= temp_dist * 100; if (best != NULL) { if ( best_overlap >= 0 && temp_overlap >= 0 ) { /* if they're both under curr set to closest in y dir */ if ( dist1(best->r, curr->r) > temp_dist ) best = NULL; } else { if ( best_overlap < temp_overlap ) best = NULL; } } if (best == NULL) { best = temp; best_overlap = temp_overlap; } } } return ( (best==NULL) ? -1 : (int)(best-link) ); } static int find_link_leftright(LINK far *link, int num_link, int curr_link, int left) { int ctr, curr_c2, best_c2 = 0, temp_c2, best_dist = 0, temp_dist; LINK far *curr, far *temp, far *best; curr = &link[curr_link]; best = NULL; curr_c2 = curr->c + curr->width - 1; for (ctr=0, temp=link; ctrc + temp->width - 1; if ( ctr != curr_link && ( (left && temp_c2 < (int)curr->c) || (!left && (int)temp->c > curr_c2) ) ) { temp_dist = dist1(curr->r, temp->r); if (best != NULL) { if ( best_dist == 0 && temp_dist == 0 ) /* if both on curr's line... */ { if ( ( left && dist1(curr->c, best_c2) > dist1(curr->c, temp_c2) ) || ( !left && dist1(curr_c2, best->c) > dist1(curr_c2, temp->c) ) ) best = NULL; } else { if ( best_dist >= temp_dist ) /* if temp is closer... */ best = NULL; } } /* if (best...) */ if (best == NULL) { best = temp; best_dist = temp_dist; best_c2 = temp_c2; } } } /* for */ return ( (best==NULL) ? -1 : (int)(best-link) ); } #ifdef __TURBOC__ # pragma warn .def /* back to default */ # pragma warn -par /* now turn off "Parameter not used" warning */ #endif #ifdef __CLINT__ # pragma argsused #endif static int find_link_key(LINK far *link, int num_link, int curr_link, int key) { link = NULL; /* just for warning */ switch (key) { case TAB: return ( (curr_link>=num_link-1) ? -1 : curr_link+1 ); case BACK_TAB: return ( (curr_link<=0) ? -1 : curr_link-1 ); default: assert(0); return (-1); } } #ifdef __TURBOC__ # pragma warn .par /* back to default */ #endif static int do_move_link(LINK far *link, int num_link, int *curr, int (*f)(LINK far *,int,int,int), int val) { int t; if (num_link > 1) { if ( f == NULL ) t = val; else t = (*f)(link, num_link, *curr, val); if ( t >= 0 && t != *curr ) { color_link(&link[*curr], C_HELP_LINK); *curr = t; color_link(&link[*curr], C_HELP_CURLINK); return (1); } } return (0); } static int help_topic(HIST *curr, HIST *next, int flags) { int len; int key; int num_pages; int num_link; int page; int curr_link; char title[81]; long where; int draw_page; int action; BYTE ch; int dummy; /* to quiet compiler */ where = topic_offset[curr->topic_num]+sizeof(int); /* to skip flags */ curr_link = curr->link; help_seek(where); dummy = read(help_file, (char *)&num_pages, sizeof(int)); assert(num_pages>0 && num_pages<=max_pages); farread(help_file, (char far *)page_table, 3*sizeof(int)*num_pages); dummy = read(help_file, &ch, 1); len = ch; assert(len<81); dummy = read(help_file, (char *)title, len); title[len] = '\0'; where += sizeof(int) + num_pages*3*sizeof(int) + 1 + len + sizeof(int); for(page=0; pagetopic_off >= page_table[page].offset && curr->topic_off < page_table[page].offset+page_table[page].len ) break; assert(page < num_pages); action = -1; draw_page = 2; do { if (draw_page) { help_seek(where+page_table[page].offset); farread(help_file, buffer, page_table[page].len); num_link = 0; display_page(title, buffer, page_table[page].len, page, num_pages, page_table[page].margin, &num_link, link_table); if (draw_page==2) { assert(num_link<=0 || (curr_link>=0 && curr_link 0) color_link(&link_table[curr_link], C_HELP_CURLINK); draw_page = 0; } key = getakey(); switch(key) { case PAGE_DOWN: if (page0) { page--; draw_page = 1; } break; case HOME: if ( page != 0 ) { page = 0; draw_page = 1; } else do_move_link(link_table, num_link, &curr_link, NULL, 0); break; case END: if ( page != num_pages-1 ) { page = num_pages-1; draw_page = 3; } else do_move_link(link_table, num_link, &curr_link, NULL, num_link-1); break; case TAB: if ( !do_move_link(link_table, num_link, &curr_link, find_link_key, key) && page0 ) { --page; draw_page = 3; } break; case DOWN_ARROW: if ( !do_move_link(link_table, num_link, &curr_link, find_link_updown, 0) && page0 ) { --page; draw_page = 3; } break; case LEFT_ARROW: do_move_link(link_table, num_link, &curr_link, find_link_leftright, 1); break; case RIGHT_ARROW: do_move_link(link_table, num_link, &curr_link, find_link_leftright, 0); break; case ESC: /* exit help */ action = ACTION_QUIT; break; case BACKSPACE: /* prev topic */ case ALT_F1: if (flags & F_HIST) action = ACTION_PREV; break; case F1: /* help index */ if (!(flags & F_INDEX)) action = ACTION_INDEX; break; case ENTER: case ENTER_2: if (num_link > 0) { next->topic_num = link_table[curr_link].topic_num; next->topic_off = link_table[curr_link].topic_off; action = ACTION_CALL; } break; } /* switch */ } while ( action == -1 ); curr->topic_off = page_table[page].offset; curr->link = curr_link; return (action); } int help(int action) { static FCODE unknowntopic_msg[] = "Unknown Help Topic"; HIST curr; int oldlookatmouse; int oldhelpmode; int flags; HIST next; if (helpmode == -1) /* is help disabled? */ { return (0); } if (help_file == -1) { buzzer(2); return (0); } buffer = (char far *)farmemalloc((long)MAX_PAGE_SIZE + sizeof(LINK)*max_links + sizeof(PAGE)*max_pages); if (buffer == NULL) { buzzer(2); return (0); } link_table = (LINK far *)(&buffer[MAX_PAGE_SIZE]); page_table = (PAGE far *)(&link_table[max_links]); oldlookatmouse = lookatmouse; lookatmouse = 0; timer_start -= clock_ticks(); stackscreen(); if (helpmode >= 0) { next.topic_num = label[helpmode].topic_num; next.topic_off = label[helpmode].topic_off; } else { next.topic_num = helpmode; next.topic_off = 0; } oldhelpmode = helpmode; if (curr_hist <= 0) action = ACTION_CALL; /* make sure it isn't ACTION_PREV! */ do { switch(action) { case ACTION_PREV2: if (curr_hist > 0) curr = hist[--curr_hist]; /* fall-through */ case ACTION_PREV: if (curr_hist > 0) curr = hist[--curr_hist]; break; case ACTION_QUIT: break; case ACTION_INDEX: next.topic_num = label[HELP_INDEX].topic_num; next.topic_off = label[HELP_INDEX].topic_off; /* fall-through */ case ACTION_CALL: curr = next; curr.link = 0; break; } /* switch */ flags = 0; if (curr.topic_num == label[HELP_INDEX].topic_num) flags |= F_INDEX; if (curr_hist > 0) flags |= F_HIST; if ( curr.topic_num >= 0 ) action = help_topic(&curr, &next, flags); else { if ( curr.topic_num == -100 ) { print_document("FRACTINT.DOC", print_doc_msg_func, 1); action = ACTION_PREV2; } else if ( curr.topic_num == -101 ) action = ACTION_PREV2; else { display_page(unknowntopic_msg, NULL, 0, 0, 1, 0, NULL, NULL); action = -1; while (action == -1) { switch (getakey()) { case ESC: action = ACTION_QUIT; break; case ALT_F1: action = ACTION_PREV; break; case F1: action = ACTION_INDEX; break; } /* switch */ } /* while */ } } /* else */ if ( action != ACTION_PREV && action != ACTION_PREV2 ) { if (curr_hist >= MAX_HIST) { int ctr; for (ctr=0; ctr= 300) /* DOS version 3.00+ ? */ { #ifdef __TURBOC__ strcpy(path, _argv[0]); #else /* assume MSC */ extern char **__argv; strcpy(path, __argv[0]); /* note: __argv may be undocumented in MSC */ #endif if(strcmp(filename,s_fractintexe)==0) if (can_read_file(path)) return (1); ptr = strrchr(path, SLASHC); if (ptr == NULL) ptr = path; else ++ptr; strcpy(ptr, filename); return (1); } return (0); #else strcpy(path,SRCDIR); strcat(path,"/"); strcat(path,filename); return 1; #endif } static int find_file(char *filename, char *path) { if ( exe_path(filename, path) ) if( can_read_file(path)) return (1); findpath(filename,path); return ( (path[0]) ? 1 : 0); } static int _read_help_topic(int topic, int off, int len, VOIDFARPTR buf) { static int curr_topic = -1; static long curr_base; static int curr_len; int read_len; if ( topic != curr_topic ) { int t; char ch; int dummy; /* to quiet compiler */ curr_topic = topic; curr_base = topic_offset[topic]; curr_base += sizeof(int); /* skip flags */ help_seek(curr_base); dummy = read(help_file, (char *)&t, sizeof(int)); /* read num_pages */ curr_base += sizeof(int) + t*3*sizeof(int); /* skip page info */ if (t>0) help_seek(curr_base); dummy = read(help_file, &ch, 1); /* read title_len */ t = ch; curr_base += 1 + t; /* skip title */ if (t>0) help_seek(curr_base); dummy = read(help_file, (char *)&curr_len, sizeof(int)); /* read topic len */ curr_base += sizeof(int); } read_len = (off+len > curr_len) ? curr_len - off : len; if (read_len > 0) { help_seek(curr_base + off); farread(help_file, (char far *)buf, read_len); } return ( curr_len - (off+len) ); } int read_help_topic(int label_num, int off, int len, VOIDFARPTR buf) /* * reads text from a help topic. Returns number of bytes from (off+len) * to end of topic. On "EOF" returns a negative number representing * number of bytes not read. */ { int ret; ret = _read_help_topic(label[label_num].topic_num, label[label_num].topic_off + off, len, buf); return ( ret ); } #define PRINT_BUFFER_SIZE (32767) /* max. size of help topic in doc. */ #define TEMP_FILE_NAME "HELP.$$$" /* temp file for storing extraseg */ /* while printing document */ #define MAX_NUM_TOPIC_SEC (10) /* max. number of topics under any */ /* single section (CONTENT) */ typedef struct PRINT_DOC_INFO { int cnum; /* current CONTENT num */ int tnum; /* current topic num */ long content_pos; /* current CONTENT item offset in file */ int num_page; /* total number of pages in document */ int num_contents, /* total number of CONTENT entries */ num_topic; /* number of topics in current CONTENT */ int topic_num[MAX_NUM_TOPIC_SEC]; /* topic_num[] for current CONTENT entry */ char far *buffer; /* text buffer */ char id[81]; /* buffer to store id in */ char title[81]; /* buffer to store title in */ #ifndef XFRACT int (*msg_func)(int pnum, int num_page); #else int (*msg_func)(); int pnum; #endif FILE *file; /* file to sent output to */ int margin; /* indent text by this much */ int start_of_line; /* are we at the beginning of a line? */ int spaces; /* number of spaces in a row */ } PRINT_DOC_INFO; void print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg ); static void printerc(PRINT_DOC_INFO *info, int c, int n) { while ( n-- > 0 ) { if (c==' ') ++info->spaces; else if (c=='\n' || c=='\f') { info->start_of_line = 1; info->spaces = 0; /* strip spaces before a new-line */ fputc(c, info->file); } else { if (info->start_of_line) { info->spaces += info->margin; info->start_of_line = 0; } while (info->spaces > 0) { fputc(' ', info->file); --info->spaces; } fputc(c, info->file); } } } static void printers(PRINT_DOC_INFO *info, char far *s, int n) { if (n > 0) { while ( n-- > 0 ) printerc(info, *s++, 1); } else { while ( *s != '\0' ) printerc(info, *s++, 1); } } static int print_doc_get_info(int cmd, PD_INFO *pd, PRINT_DOC_INFO *info) { int t; BYTE ch; int dummy; /* to quiet compiler */ switch (cmd) { case PD_GET_CONTENT: if ( ++info->cnum >= info->num_contents ) return (0); help_seek( info->content_pos ); dummy = read(help_file, (char *)&t, sizeof(int)); /* read flags */ info->content_pos += sizeof(int); pd->new_page = (t & 1) ? 1 : 0; dummy = read(help_file, &ch, 1); /* read id len */ t = ch; assert(t<80); dummy = read(help_file, (char *)info->id, t); /* read the id */ info->content_pos += 1 + t; info->id[t] = '\0'; dummy = read(help_file, (char *)&ch, 1); /* read title len */ t = ch; assert(t<80); dummy = read(help_file, (char *)info->title, t); /* read the title */ info->content_pos += 1 + t; info->title[t] = '\0'; dummy = read(help_file, (char *)&ch, 1); /* read num_topic */ t = ch; assert(ttopic_num, t*sizeof(int)); /* read topic_num[] */ info->num_topic = t; info->content_pos += 1 + t*sizeof(int); info->tnum = -1; pd->id = info->id; pd->title = info->title; return (1); case PD_GET_TOPIC: if ( ++info->tnum >= info->num_topic ) return (0); t = _read_help_topic(info->topic_num[info->tnum], 0, PRINT_BUFFER_SIZE, info->buffer); assert(t <= 0); pd->curr = info->buffer; pd->len = PRINT_BUFFER_SIZE + t; /* same as ...SIZE - abs(t) */ return (1); case PD_GET_LINK_PAGE: pd->i = getint(pd->s+sizeof(long)); return ( (pd->i == -1) ? 0 : 1 ); case PD_RELEASE_TOPIC: return (1); default: return (0); } } static int print_doc_output(int cmd, PD_INFO *pd, PRINT_DOC_INFO *info) { switch (cmd) { case PD_HEADING: { char line[81]; char buff[40]; int width = PAGE_WIDTH + PAGE_INDENT; int keep_going; if ( info->msg_func != NULL ) keep_going = (*info->msg_func)(pd->pnum, info->num_page); else keep_going = 1; info->margin = 0; memset(line, ' ', 81); sprintf(buff, "Fractint Version %d.%01d%c",release/100, (release%100)/10, ( (release%10) ? '0'+(release%10) : ' ') ); memmove(line + ((width-(int)(strlen(buff))) / 2)-4, buff, strlen(buff)); sprintf(buff, "Page %d", pd->pnum); memmove(line + (width - (int)strlen(buff)), buff, strlen(buff)); printerc(info, '\n', 1); printers(info, line, width); printerc(info, '\n', 2); info->margin = PAGE_INDENT; return ( keep_going ); } case PD_FOOTING: info->margin = 0; printerc(info, '\f', 1); info->margin = PAGE_INDENT; return (1); case PD_PRINT: printers(info, pd->s, pd->i); return (1); case PD_PRINTN: printerc(info, *pd->s, pd->i); return (1); case PD_PRINT_SEC: info->margin = TITLE_INDENT; if (pd->id[0] != '\0') { printers(info, pd->id, 0); printerc(info, ' ', 1); } printers(info, pd->title, 0); printerc(info, '\n', 1); info->margin = PAGE_INDENT; return (1); case PD_START_SECTION: case PD_START_TOPIC: case PD_SET_SECTION_PAGE: case PD_SET_TOPIC_PAGE: case PD_PERIODIC: return (1); default: return (0); } } static int print_doc_msg_func(int pnum, int num_pages) { char temp[10]; int key; if ( pnum == -1 ) /* successful completion */ { static FCODE msg[] = {"Done -- Press any key"}; buzzer(0); putstringcenter(7, 0, 80, C_HELP_LINK, msg); getakey(); return (0); } if ( pnum == -2 ) /* aborted */ { static FCODE msg[] = {"Aborted -- Press any key"}; buzzer(1); putstringcenter(7, 0, 80, C_HELP_LINK, msg); getakey(); return (0); } if (pnum == 0) /* initialization */ { static FCODE msg[] = {"Generating FRACTINT.DOC"}; helptitle(); printinstr(); setattr(2, 0, C_HELP_BODY, 80*22); putstringcenter(1, 0, 80, C_HELP_HDG, msg); putstring(7, 30, C_HELP_BODY, "Completed:"); movecursor(25,80); /* hide cursor */ } sprintf(temp, "%d%%", (int)( (100.0 / num_pages) * pnum ) ); putstring(7, 41, C_HELP_LINK, temp); while ( keypressed() ) { key = getakey(); if ( key == ESC ) return (0); /* user abort */ } return (1); /* AOK -- continue */ } int makedoc_msg_func(int pnum, int num_pages) { if (pnum >= 0) { printf("\rcompleted %d%%", (int)( (100.0 / num_pages) * pnum ) ); return (1); } if ( pnum == -2 ) printf("\n*** aborted"); printf("\n"); return (0); } void print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg ) { static FCODE err_no_temp[] = "Unable to create temporary file.\n"; static FCODE err_no_out[] = "Unable to create output file.\n"; static FCODE err_badwrite[] = "Error writing temporary file.\n"; static FCODE err_badread[] = "Error reading temporary file.\nSystem may be corrupt!\nSave your image and re-start FRACTINT!\n"; PRINT_DOC_INFO info; int success = 0; int temp_file = -1; char far *msg = NULL; int dummy; /* to quiet compiler */ info.buffer = MK_FP(extraseg, 0); /* help_seek((long)sizeof(int)+sizeof(long)); Strange -- should be 8 -- CWM */ help_seek(8L); /* indeed it should - Bert */ dummy = read(help_file, (char *)&info.num_contents, sizeof(int)); dummy = read(help_file, (char *)&info.num_page, sizeof(int)); info.cnum = info.tnum = -1; info.content_pos = sizeof(long)+4*sizeof(int) + num_topic*sizeof(long) + num_label*2*sizeof(int); info.msg_func = msg_func; if ( msg_func != NULL ) msg_func(0, info.num_page); /* initialize */ if ( save_extraseg ) { if ( (temp_file=open(TEMP_FILE_NAME, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE)) == -1 ) { msg = err_no_temp; goto ErrorAbort; } if ( farwrite(temp_file, info.buffer, PRINT_BUFFER_SIZE) != PRINT_BUFFER_SIZE ) { msg = err_badwrite; goto ErrorAbort; } } if ( (info.file = fopen(outfname, "wt")) == NULL ) { msg = err_no_out; goto ErrorAbort; } info.margin = PAGE_INDENT; info.start_of_line = 1; info.spaces = 0; success = process_document((PD_FUNC)print_doc_get_info, (PD_FUNC)print_doc_output, &info); fclose(info.file); if ( save_extraseg ) { if ( lseek(temp_file, 0L, SEEK_SET) != 0L ) { msg = err_badread; goto ErrorAbort; } if ( farread(temp_file, info.buffer, PRINT_BUFFER_SIZE) != PRINT_BUFFER_SIZE ) { msg = err_badread; goto ErrorAbort; } } ErrorAbort: if (temp_file != -1) { close(temp_file); remove(TEMP_FILE_NAME); temp_file = -1; } if ( msg != NULL ) { helptitle(); stopmsg(1, msg); } else if ( msg_func != NULL ) msg_func((success) ? -1 : -2, info.num_page ); } int init_help(void) { struct help_sig_info hs; char path[FILE_MAX_PATH+1]; int dummy; /* to quiet compiler */ help_file = -1; #ifndef WINFRACT #ifndef XFRACT if (help_file == -1) /* now look for help files in FRACTINT.EXE */ { static FCODE err_no_open[] = "Help system was unable to open FRACTINT.EXE!\n"; static FCODE err_no_exe[] = "Help system couldn't find FRACTINT.EXE!\n"; static FCODE err_wrong_ver[] = "Wrong help version in FRACTINT.EXE!\n"; /* static FCODE err_not_in_exe[] = "Help not found in FRACTINT.EXE!\n"; */ if ( find_file(s_fractintexe, path) ) { #ifdef __TURBOC__ if ( (help_file = open(path, O_RDONLY|O_BINARY|O_DENYWRITE)) != -1 ) #else if ( (help_file = open(path, O_RDONLY|O_BINARY)) != -1 ) #endif { long help_offset; for (help_offset = -((long)sizeof(hs)); help_offset >= -128L; help_offset--) { lseek(help_file, help_offset, SEEK_END); dummy = read(help_file, (char *)&hs, sizeof(hs)); if (hs.sig == HELP_SIG) break; } if ( hs.sig != HELP_SIG ) { close(help_file); help_file = -1; /* (leave out the error message) stopmsg(1, err_not_in_exe); */ } else { if ( hs.version != HELP_VERSION ) { close(help_file); help_file = -1; stopmsg(1, err_wrong_ver); } else base_off = hs.base; } } else stopmsg(1, err_no_open); } else stopmsg(1, err_no_exe); } #endif #endif if (help_file == -1) /* look for FRACTINT.HLP */ { if ( find_file("fractint.hlp", path) ) { #ifdef __TURBOC__ if ( (help_file = open(path, O_RDONLY|O_BINARY|O_DENYWRITE)) != -1 ) #else if ( (help_file = open(path, O_RDONLY|O_BINARY)) != -1 ) #endif { dummy = read(help_file, (char *)&hs, sizeof(long)+sizeof(int)); if ( hs.sig != HELP_SIG ) { static FCODE msg[] = {"Invalid help signature in FRACTINT.HLP!\n"}; close(help_file); stopmsg(1, msg); } else if ( hs.version != HELP_VERSION ) { static FCODE msg[] = {"Wrong help version in FRACTINT.HLP!\n"}; close(help_file); stopmsg(1, msg); } else base_off = sizeof(long)+sizeof(int); } } } if (help_file == -1) /* Can't find the help files anywhere! */ { static FCODE msg[] = #ifndef XFRACT {"Help Files aren't in FRACTINT.EXE, and couldn't find FRACTINT.HLP!\n"}; #else {"Couldn't find fractint.hlp; set FRACTDIR to proper directory with setenv.\n"}; #endif stopmsg(1, msg); } help_seek(0L); dummy = read(help_file, (char *)&max_pages, sizeof(int)); dummy = read(help_file, (char *)&max_links, sizeof(int)); dummy = read(help_file, (char *)&num_topic, sizeof(int)); dummy = read(help_file, (char *)&num_label, sizeof(int)); help_seek((long)6*sizeof(int)); /* skip num_contents and num_doc_pages */ assert(max_pages > 0); assert(max_links >= 0); assert(num_topic > 0); assert(num_label > 0); /* allocate one big chunk for all three arrays */ topic_offset = (long far *)farmemalloc(sizeof(long)*num_topic + 2L*sizeof(int)*num_label + sizeof(HIST)*MAX_HIST); if (topic_offset == NULL) { static FCODE err_no_mem[] = "Not enough memory for help system!\n"; close(help_file); help_file = -1; stopmsg(1, err_no_mem); return (-2); } /* split off the other arrays */ label = (LABEL far *)(&topic_offset[num_topic]); hist = (HIST far *)(&label[num_label]); /* read in the tables... */ farread(help_file, topic_offset, num_topic*sizeof(long)); farread(help_file, label, num_label*2*sizeof(int)); /* finished! */ return (0); /* success */ } void end_help(void) { if (help_file != -1) { close(help_file); farmemfree((BYTE far *)topic_offset); help_file = -1; } } xfractint-20.4.10.orig/common/targa.c0000644000000000000000000005617210532116313014245 0ustar /** targa.c **/ #ifdef __TURBOC__ # pragma warn -par #endif #define TARGA_DATA #include #ifndef XFRACT #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "targa.h" /************* ****************/ void WriteTGA( int x, int y, int index ); int ReadTGA ( int x, int y ); void EndTGA ( void ); void StartTGA( void ); void ReopenTGA( void ); /************* ****************/ static unsigned _fastcall near Row16Calculate(unsigned,unsigned); static void _fastcall near PutPix16(int,int,int); static unsigned _fastcall near GetPix16(int,int); static unsigned _fastcall near Row32Calculate(unsigned,unsigned); static void _fastcall near PutPix32(int,int,int); static unsigned _fastcall near GetPix32(int,int); static void _fastcall near DoFirstPixel(int,int,int); static void _fastcall fatalerror(char far *); static int GetLine(int); static void _fastcall near SetDispReg(int,int); static int VWait(void); static void _fastcall SetVBorder(int,int); static void _fastcall SetBorderColor(long); static void _fastcall SetVertShift(int); static void _fastcall SetInterlace(int); static void _fastcall SetBlndReg(int); static void _fastcall SetRGBorCV(int); static void _fastcall SetVCRorCamera(int); static void _fastcall SetMask(int); static void _fastcall SetBlndReg(int); static void _fastcall SetContrast(int); static void _fastcall SetHue(int); static void _fastcall SetSaturation(int); static void _fastcall SetHBorder(int,int); static void SetFixedRegisters(void); static void _fastcall VCenterDisplay(int); static void _fastcall SetOverscan(int); static void _fastcall near TSetMode(int); static int GraphInit(void); static void GraphEnd(void); /************* ****************/ int xorTARGA; unsigned far *tga16 = NULL; /* [256] */ long far *tga32; /* [256] */ static int last = 0; /************* ****************/ static int initialized; /************* ****************/ static void (near _fastcall *DoPixel) ( int x, int y, int index ); static void (near _fastcall *PutPixel)( int x, int y, int index ); static unsigned (near _fastcall *GetPixel)( int x, int y ); /**************************************************************************/ #ifdef __BORLANDC__ #if(__BORLANDC__ > 2) #pragma warn -eff #endif #endif static unsigned _fastcall near Row16Calculate( unsigned line, unsigned x1 ) { outp( DESTREG, (line >> 5) ); return( ((line & 31) << 10) | (x1 << 1) ); /* calc the pixel offset */ } /**************************************************************************/ static void _fastcall near PutPix16( int x, int y, int index ) { unsigned far * ip; /**************/ ip = MK_FP( MEMSEG, Row16Calculate( y, x ) ); if( ! xorTARGA ) *ip = tga16[index]; else *ip = *ip ^ 0x7fff; } /**************************************************************************/ static unsigned _fastcall near GetPix16( int x, int y ) { register unsigned pixel, index; unsigned far * ip; /**************/ ip = MK_FP( MEMSEG, Row16Calculate( y, x ) ); pixel = *ip & 0x7FFF; if( pixel == tga16[last] ) return( last ); for( index = 0; index < 256; index++ ) if( pixel == tga16[index] ) { last = index; return( index ); } return( 0 ); } /**************************************************************************/ static unsigned _fastcall near Row32Calculate( unsigned line, unsigned x1 ) { outp( DESTREG, (line >> 4) ); return ( ((line & 15) << 11) | (x1 << 2) ); /* calc the pixel offset */ } /**************************************************************************/ static void _fastcall near PutPix32( int x, int y, int index ) { long far * lp; lp = MK_FP( MEMSEG, Row32Calculate( y, x ) ); if( ! xorTARGA ) *lp = tga32[index]; else *lp = *lp ^ 0x00FFFFFFL; } /**************************************************************************/ static unsigned _fastcall near GetPix32( int x, int y ) { register int index; long pixel; long far * lp; lp = MK_FP( MEMSEG, Row32Calculate( y, x ) ); pixel = *lp & 0x00FFFFFFL; if( pixel == tga32[last] ) return( last ); for( index = 0; index < 256; index++ ) if( pixel == tga32[index] ) { last = index; return( index ); } return( 0 ); } /**************************************************************************/ static void _fastcall near DoFirstPixel( int x, int y, int index ) { int cnt; TSetMode( targa.mode | 1 ); for( cnt = 0; cnt < targa.MaxBanks; cnt += 2 ) { /* erase */ outp( DESTREG, cnt ); outp( SRCREG, cnt + 1 ); erasesegment(targa.memloc,0); /** general.asm **/ } TSetMode( targa.mode & 0xFFFE ); PutPixel = DoPixel; (*PutPixel)( x, y, index ); } #ifdef __BORLANDC__ #if(__BORLANDC__ > 2) #pragma warn +eff #endif #endif /***************************************************************************/ void WriteTGA( int x, int y, int index ) { OUTPORTB(MODEREG, targa.mode |= 1 ); /* TSetMode inline for speed */ (*PutPixel)( x, sydots-y, index&0xFF ); /* fix origin to match EGA/VGA */ OUTPORTB(MODEREG, targa.mode &= 0xFFFE ); } /***************************************************************************/ int ReadTGA( int x, int y ) { int val; OUTPORTB(MODEREG, targa.mode |= 1 ); /* TSetMode inline for speed */ val = (*GetPixel)( x, sydots-y ); OUTPORTB(MODEREG, targa.mode &= 0xFFFE ); return( val ); } /***************************************************************************/ void EndTGA( void ) { if( initialized ) { GraphEnd(); initialized = 0; } } /***************************************************************************/ void StartTGA() { int i; /* This overlayed data safe because used in this file, any only used for fatal error message! */ static FCODE couldntfind[]={"Could not find Targa card"}; static FCODE noenvvar[]={"TARGA environment variable missing"}; static FCODE insuffmem[]={"Insufficient memory for Targa"}; /****************/ if( initialized ) return; initialized = 1; /****************/ /* note that video.asm has already set the regualar video adapter */ /* to text mode (ax in Targa table entries is 3); */ /* that's necessary because TARGA can live at 0xA000, we DO NOT */ /* want to have an EGA/VGA in graphics mode!! */ ReopenTGA(); /* clear text screen and display message */ /****************/ /*** look for and activate card ***/ if ((i = GraphInit()) != 0) fatalerror((i == -1) ? couldntfind : noenvvar); VCenterDisplay( sydots + 1 ); if (tga16 == NULL) if ( (tga16 = (unsigned far *)farmemalloc(512L)) == NULL || (tga32 = (long far *)farmemalloc(1024L)) == NULL) fatalerror(insuffmem); SetTgaColors(); if( targa.boardType == 16 ) { GetPixel = (unsigned (near _fastcall *)(int, int))GetPix16; DoPixel = PutPix16; } else { GetPixel = (unsigned (near _fastcall *)(int, int))GetPix32; DoPixel = PutPix32; } PutPixel = DoFirstPixel; /* on first pixel --> erase */ if( sydots == 482 ) SetOverscan( 1 ); TSetMode( targa.mode & 0xFFFE ); /****************/ if (mapdacbox == NULL && SetColorPaletteName("default") != 0) exit( 1 ); /* stopmsg has already been issued */ } void ReopenTGA() { static FCODE runningontarga[]={"Running On TrueVision TARGA Card"}; helptitle(); putstring(2,20,7,runningontarga); movecursor(6,0); /* in case of brutal exit */ } static void _fastcall fatalerror(char far *msg) { static FCODE abortmsg[]={"...aborting!"}; putstring(4,20,15,msg); putstring(5,20,15,abortmsg); movecursor(8,0); exit(1); } /*** the rest of this module used to be separate, in tgasubs.c, ***/ /*** has now been merged into a single source ***/ /*******************************************************************/ static void _fastcall VCenterDisplay( int nLines ) { int lines; int top, bottom; long color; lines = nLines >> 1; /* half value of last line 0..x */ top = 140 - (lines >> 1); bottom = top + lines; SetVBorder( top, bottom ); SetVertShift( 255 - lines ); /* skip lines we're not using */ if( targa.boardType == 16 ) color = (12 << 10) | (12 << 5) | 12; else color = ((long)80 << 16) | (80 << 8) | 80; SetBorderColor( color ); } /*****************************************************************/ static void _fastcall near SetDispReg(int reg, int value) { targa.DisplayRegister[reg] = value; TSetMode(targa.mode&MSK_REGWRITE); /* select Index Register write */ OUTPORTB(DRREG, reg); /* select sync register */ /* * Set Mask register to write value to * display register and to set Bit 9 in the DR */ TSetMode( ((targa.mode|(~MSK_REGWRITE)) /* turn on write bit */ & MSK_BIT9 ) /* turn off Bit 9 */ | ((value&0x0100)>>1)); /* set bit 9 for value */ OUTPORTB(DRREG, value); /* select sync register */ } /*****************************************************************/ #define WAITCOUNT 60000L static int VWait() { int rasterreg; unsigned GiveUp; rasterreg = RASTERREG; /* * If beyond bottom of frame wait for next field */ GiveUp= WAITCOUNT; while ( (--GiveUp) && (GetLine(rasterreg) == 0) ) { } if (GiveUp) { /* * Wait for the bottom of the border */ GiveUp= WAITCOUNT; while ( (--GiveUp) && (GetLine(rasterreg) > 0) ) { } } return ( ( GiveUp ) ? 0 : -1); } /*****************************************************************/ static void _fastcall SetVBorder(int top, int bottom) { /* top border */ if ( top < MIN_TOP ) top=MIN_TOP; SetDispReg(TOPBORDER,top); /* bottom border */ if ( bottom > MAX_BOTTOM ) bottom=MAX_BOTTOM; SetDispReg(BOTTOMBORDER,bottom); SetDispReg(DR10,top); SetDispReg(DR11,bottom); } /*****************************************************************/ static void _fastcall SetRGBorCV(int type) { /* set the contrast level */ targa.RGBorCV = type; targa.VCRCon = ( targa.VCRCon & MSK_RGBORCV ) | (targa.RGBorCV<>16)); } /*****************************************************************/ static void _fastcall SetMask(int mask) { /* mask to valid values and output to mode register */ targa.Mask = mask; OUTPORTB(MASKREG, mask); } /*****************************************************************/ static void _fastcall SetVertShift(int preshift) { /* set the Vertical Preshift count level */ targa.VertShift = preshift; OUTPORTB(VERTPAN, preshift); } /*****************************************************************/ static void _fastcall SetOverscan(int mode) { long tempColor; targa.ovrscnOn = mode; if ( mode == 0 ) { INPORTB(UNDERREG); /* select underscan mode */ SetHBorder( (DEF_LEFT+targa.xOffset), (DEF_RIGHT+targa.xOffset)); SetDispReg(4,352); SetDispReg(5,1); SetBorderColor(targa.BorderColor); } else { INPORTB(OVERREG); /* select overrscan mode */ SetDispReg(0,64); /* Set four of the display registers */ SetDispReg(1,363); /* to values required for Overscan */ SetDispReg(4,363); SetDispReg(5,17); tempColor = targa.BorderColor; SetBorderColor(0L); targa.BorderColor = tempColor; } } /*****************************************************************/ static void _fastcall SetInterlace(int type) { targa.InterlaceMode= type & MSK_INTERLACE; SetDispReg(INTREG, targa.InterlaceMode); /* * SET THE INTERLACE BIT TO MATCH THE INTERLACE MODE AND * SCREEN RESOLUTION - SCREEN PAGE */ if ( ( targa.InterlaceMode >= 2 ) && ( targa.PageMode> 1 ) && ( (targa.PageMode&1) != 0 ) ) TSetMode(targa.mode|(~MSK_IBIT) ); else TSetMode(targa.mode& MSK_IBIT); } /*****************************************************************/ static void _fastcall SetBlndReg(int value) { /* set the Vertical Preshift count level */ if ( targa.boardType == 32 ) { targa.VCRCon = (targa.VCRCon&0xfe) | value; OUTPORTB(BLNDREG, value); } } /*****************************************************************/ static void _fastcall near TSetMode(int mode) { /* mask to valid values and output to mode register */ OUTPORTB(MODEREG, mode ); targa.mode = mode; } /*****************************************************************/ static void _fastcall SetContrast(int level) { /* set the contrast level */ targa.Contrast = level &((~MSK_CONTRAST)>>SHF_CONTRAST); targa.VCRCon = ( targa.VCRCon & MSK_CONTRAST ) | (targa.Contrast<>SHF_HUE); /* mask to valid range */ targa.SatHue = (targa.SatHue&MSK_HUE) | (targa.Hue<>SHF_SATURATION); targa.SatHue = (targa.SatHue&MSK_SATURATION) | (targa.Saturation<= 2 ) && ( pageMode> 1 ) && ( (pageMode&1) != 0 ) ) TSetMode(targa.mode|(~MSK_IBIT) ); else TSetMode(targa.mode& MSK_IBIT); } ***/ /*****************************************************************/ static void _fastcall SetHBorder(int left, int right) { SetDispReg(LEFTBORDER, left); /* set horizontal left border */ SetDispReg(RIGHTBORDER,right); /* set horizontal right border */ /* * Set DR 8 and 9 since they * default to tracking DR0 and DR 1 */ SetDispReg(DR8,left); SetDispReg(DR9,left); } /*****************************************************************/ /*** UNUSED static void _fastcall SetGenlock(int OnOrOff) { TSetMode( (targa.mode)&(MSK_GENLOCK) |((OnOrOff<= '2' && *envptr <= '8') switches |= (1 << ('8' - *envptr)); ++envptr; } if (got_switches == 0) { /* all blanks, use default */ targa.memloc = (signed int)0xA000; targa.iobase = 0x220; } else { targa.memloc = 0x8000 + ((switches & 0x70) << 8); targa.iobase = 0x200 + ((switches & 0x0f) << 4); } if ((envptr = getenv("TARGASET")) != NULL) { for(;;) { /* parse next parameter */ while (*envptr == ' ' || *envptr == ',') ++envptr; if (*envptr == 0) break; if (*envptr >= 'a' && *envptr <= 'z') *envptr -= ('a'-'A'); i = atoi(envptr+1); switch (*envptr) { case 'T': if (i == 16) targa.boardType = TYPE_16; if (i == 24) targa.boardType = TYPE_24; if (i == 32) targa.boardType = TYPE_32; break; /* case 'E' not done, meaning not clear */ case 'X': targa.xOffset = i; break; case 'Y': targa.yOffset = i; break; case 'I': targa.InterlaceMode = i; break; /* case 'N' not done, I don't know how to handle it */ case 'R': targa.RGBorCV = RGB; break; case 'B': targa.VCRorCamera = CAMERA; break; case 'V': targa.VCRorCamera = VCR; break; case 'G': targa.AlwaysGenLock = 1; break; case 'C': targa.Contrast = i * 31 / 100; break; case 'S': targa.Saturation = i * 7 / 100; break; case 'H': targa.Hue = i * 31 / 100; break; /* note: 'A' and 'O' defined but apply only to type M8 */ /* case 'P' not handled cause I don't know how */ } while (*(++envptr) >= '0' && *envptr <= '9') { } } } if ( targa.boardType == TYPE_16 ) { targa.MaxBanks = 16; targa.BytesPerPixel = 2; } if ( targa.boardType == TYPE_24 ) { targa.MaxBanks = 32; targa.BytesPerPixel = 3; } if ( targa.boardType == TYPE_32 ) { targa.MaxBanks = 32; targa.BytesPerPixel = 4; } /****** Compute # of rows per 32K bank ********/ targa.RowsPerBank = 512/(targa.MaxBanks); targa.AddressShift = targa.MaxBanks>>4; /* if initializing CVA: set these before we quit */ SetSaturation(targa.Saturation); SetHue(targa.Hue); SetContrast( targa.Contrast); /* Set Genlock bit if always genlocked */ /* Set before flipping and jerking screen */ TSetMode( (targa.AlwaysGenLock< #include #include #include #ifndef XFRACT #include #endif #ifndef USE_VARARGS #include #else #include #endif /*#ifdef __TURBOC__ #include #endif */ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" /* routines in this module */ static void trigdetails(char *); static void area(void); /* TW's static string consolidation campaign to help brain-dead compilers */ char s_cantwrite[] = {"Can't write %s"}; char s_cantcreate[] = {"Can't create %s"}; char s_cantunderstand[] = {"Can't understand %s"}; char s_cantfind[] = {"Can't find %s"}; #ifndef XFRACT void findpath(char far *filename, char *fullpathname) /* return full pathnames */ { char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char temp_path[FILE_MAX_PATH]; splitpath(filename ,NULL,NULL,fname,ext); makepath(temp_path,"" ,"" ,fname,ext); if(checkcurdir != 0 && access(temp_path,0)==0) { /* file exists */ strcpy(fullpathname,temp_path); return; } far_strcpy(temp_path,filename); /* avoid side effect changes to filename */ if (temp_path[0] == SLASHC || (temp_path[0] && temp_path[1] == ':')) { if(access(temp_path,0)==0) { /* file exists */ strcpy(fullpathname,temp_path); return; } else { splitpath(temp_path ,NULL,NULL,fname,ext); makepath(temp_path,"" ,"" ,fname,ext); } } fullpathname[0] = 0; /* indicate none found */ /* #ifdef __TURBOC__ */ /* look for the file */ /* strcpy(fullpathname,searchpath(temp_path)); */ /* #else */ _searchenv(temp_path,"PATH",fullpathname); /* #endif */ if (fullpathname[0] != 0) /* found it! */ if (strncmp(&fullpathname[2],SLASHSLASH,2) == 0) /* stupid klooge! */ strcpy(&fullpathname[3],temp_path); } #endif void notdiskmsg() { static FCODE sorrymsg[]={ "This type may be slow using a real-disk based 'video' mode, but may not \n\ be too bad if you have enough expanded or extended memory. Press to \n\ abort if it appears that your disk drive is working too hard."}; stopmsg(0,sorrymsg); } /* Wrapping version of putstring for long numbers */ /* row -- pointer to row variable, internally incremented if needed */ /* col1 -- starting column */ /* col2 -- last column */ /* color -- attribute (same as for putstring) */ /* maxrow -- max number of rows to write */ /* returns 0 if success, 1 if hit maxrow before done */ int putstringwrap(int *row,int col1,int col2,int color,char far *str,int maxrow) { char save1, save2; int length, decpt, padding, startrow, done; done = 0; startrow = *row; length = far_strlen(str); padding = 3; /* space between col1 and decimal. */ /* find decimal point */ for(decpt=0;decpt < length; decpt++) if(str[decpt] == '.') break; if(decpt >= length) decpt = 0; if(decpt < padding) padding -= decpt; else padding = 0; col1 += padding; decpt += col1+1; /* column just past where decimal is */ while(length > 0) { if(col2-col1 < length) { if((*row - startrow + 1) >= maxrow) done = 1; else done = 0; save1 = str[col2-col1+1]; save2 = str[col2-col1+2]; if(done) str[col2-col1+1] = '+'; else str[col2-col1+1] = '\\'; str[col2-col1+2] = 0; putstring(*row,col1,color,str); if(done == 1) break; str[col2-col1+1] = save1; str[col2-col1+2] = save2; str += col2-col1; (*row)++; } else putstring(*row,col1,color,str); length -= col2-col1; col1 = decpt; /* align with decimal */ } return(done); } #define rad_to_deg(x) ((x)*(180.0/PI)) /* most people "think" in degrees */ #define deg_to_rad(x) ((x)*(PI/180.0)) /* convert corners to center/mag Rotation angles indicate how much the IMAGE has been rotated, not the zoom box. Same goes for the Skew angles */ #ifdef _MSC_VER #pragma optimize( "", off ) #endif void cvtcentermag(double *Xctr, double *Yctr, LDBL *Magnification, double *Xmagfactor, double *Rotation, double *Skew) { double Width, Height; double a, b; /* bottom, left, diagonal */ double a2, b2, c2; /* squares of above */ double tmpx1, tmpx2, tmpy1, tmpy2, tmpa; /* temporary x, y, angle */ /* simple normal case first */ if (xx3rd == xxmin && yy3rd == yymin) { /* no rotation or skewing, but stretching is allowed */ Width = xxmax - xxmin; Height = yymax - yymin; *Xctr = (xxmin + xxmax)/2.0; *Yctr = (yymin + yymax)/2.0; *Magnification = 2.0/Height; *Xmagfactor = Height / (DEFAULTASPECT * Width); *Rotation = 0.0; *Skew = 0.0; } else { /* set up triangle ABC, having sides abc */ /* side a = bottom, b = left, c = diagonal not containing (x3rd,y3rd) */ tmpx1 = xxmax - xxmin; tmpy1 = yymax - yymin; c2 = tmpx1*tmpx1 + tmpy1*tmpy1; tmpx1 = xxmax - xx3rd; tmpy1 = yymin - yy3rd; a2 = tmpx1*tmpx1 + tmpy1*tmpy1; a = sqrt(a2); *Rotation = -rad_to_deg(atan2( tmpy1, tmpx1 )); /* negative for image rotation */ tmpx2 = xxmin - xx3rd; tmpy2 = yymax - yy3rd; b2 = tmpx2*tmpx2 + tmpy2*tmpy2; b = sqrt(b2); tmpa = acos((a2+b2-c2)/(2*a*b)); /* save tmpa for later use */ *Skew = 90.0 - rad_to_deg(tmpa); *Xctr = (xxmin + xxmax)*0.5; *Yctr = (yymin + yymax)*0.5; Height = b * sin(tmpa); *Magnification = 2.0/Height; /* 1/(h/2) */ *Xmagfactor = Height / (DEFAULTASPECT * a); /* if vector_a cross vector_b is negative */ /* then adjust for left-hand coordinate system */ if ( tmpx1*tmpy2 - tmpx2*tmpy1 < 0 && debugflag != 4010) { *Skew = -*Skew; *Xmagfactor = -*Xmagfactor; *Magnification = -*Magnification; } } /* just to make par file look nicer */ if (*Magnification < 0) { *Magnification = -*Magnification; *Rotation += 180; } #ifdef DEBUG { double txmin, txmax, tx3rd, tymin, tymax, ty3rd; double error; txmin = xxmin; txmax = xxmax; tx3rd = xx3rd; tymin = yymin; tymax = yymax; ty3rd = yy3rd; cvtcorners(*Xctr, *Yctr, *Magnification, *Xmagfactor, *Rotation, *Skew); error = sqr(txmin - xxmin) + sqr(txmax - xxmax) + sqr(tx3rd - xx3rd) + sqr(tymin - yymin) + sqr(tymax - yymax) + sqr(ty3rd - yy3rd); if(error > .001) showcornersdbl("cvtcentermag problem"); xxmin = txmin; xxmax = txmax; xx3rd = tx3rd; yymin = tymin; yymax = tymax; yy3rd = ty3rd; } #endif return; } /* convert center/mag to corners */ void cvtcorners(double Xctr, double Yctr, LDBL Magnification, double Xmagfactor, double Rotation, double Skew) { double x, y; double h, w; /* half height, width */ double tanskew, sinrot, cosrot; if (Xmagfactor == 0.0) Xmagfactor = 1.0; h = (double)(1/Magnification); w = h / (DEFAULTASPECT * Xmagfactor); if (Rotation == 0.0 && Skew == 0.0) { /* simple, faster case */ xx3rd = xxmin = Xctr - w; xxmax = Xctr + w; yy3rd = yymin = Yctr - h; yymax = Yctr + h; return; } /* in unrotated, untranslated coordinate system */ tanskew = tan(deg_to_rad(Skew)); xxmin = -w + h*tanskew; xxmax = w - h*tanskew; xx3rd = -w - h*tanskew; yymax = h; yy3rd = yymin = -h; /* rotate coord system and then translate it */ Rotation = deg_to_rad(Rotation); sinrot = sin(Rotation); cosrot = cos(Rotation); /* top left */ x = xxmin * cosrot + yymax * sinrot; y = -xxmin * sinrot + yymax * cosrot; xxmin = x + Xctr; yymax = y + Yctr; /* bottom right */ x = xxmax * cosrot + yymin * sinrot; y = -xxmax * sinrot + yymin * cosrot; xxmax = x + Xctr; yymin = y + Yctr; /* bottom left */ x = xx3rd * cosrot + yy3rd * sinrot; y = -xx3rd * sinrot + yy3rd * cosrot; xx3rd = x + Xctr; yy3rd = y + Yctr; return; } /* convert corners to center/mag using bf */ void cvtcentermagbf(bf_t Xctr, bf_t Yctr, LDBL *Magnification, double *Xmagfactor, double *Rotation, double *Skew) { /* needs to be LDBL or won't work past 307 (-DBL_MIN_10_EXP) or so digits */ LDBL Width, Height; LDBL a, b; /* bottom, left, diagonal */ LDBL a2, b2, c2; /* squares of above */ LDBL tmpx1, tmpx2, tmpy=0.0, tmpy1, tmpy2 ; double tmpa; /* temporary x, y, angle */ bf_t bfWidth, bfHeight; bf_t bftmpx, bftmpy; int saved; int signx; saved = save_stack(); /* simple normal case first */ /* if (xx3rd == xxmin && yy3rd == yymin) */ if(!cmp_bf(bfx3rd, bfxmin) && !cmp_bf(bfy3rd, bfymin)) { /* no rotation or skewing, but stretching is allowed */ bfWidth = alloc_stack(bflength+2); bfHeight = alloc_stack(bflength+2); /* Width = xxmax - xxmin; */ sub_bf(bfWidth, bfxmax, bfxmin); Width = bftofloat(bfWidth); /* Height = yymax - yymin; */ sub_bf(bfHeight, bfymax, bfymin); Height = bftofloat(bfHeight); /* *Xctr = (xxmin + xxmax)/2; */ add_bf(Xctr, bfxmin, bfxmax); half_a_bf(Xctr); /* *Yctr = (yymin + yymax)/2; */ add_bf(Yctr, bfymin, bfymax); half_a_bf(Yctr); *Magnification = 2/Height; *Xmagfactor = (double)(Height / (DEFAULTASPECT * Width)); *Rotation = 0.0; *Skew = 0.0; } else { bftmpx = alloc_stack(bflength+2); bftmpy = alloc_stack(bflength+2); /* set up triangle ABC, having sides abc */ /* side a = bottom, b = left, c = diagonal not containing (x3rd,y3rd) */ /* IMPORTANT: convert from bf AFTER subtracting */ /* tmpx = xxmax - xxmin; */ sub_bf(bftmpx, bfxmax, bfxmin); tmpx1 = bftofloat(bftmpx); /* tmpy = yymax - yymin; */ sub_bf(bftmpy, bfymax, bfymin); tmpy1 = bftofloat(bftmpy); c2 = tmpx1*tmpx1 + tmpy1*tmpy1; /* tmpx = xxmax - xx3rd; */ sub_bf(bftmpx, bfxmax, bfx3rd); tmpx1 = bftofloat(bftmpx); /* tmpy = yymin - yy3rd; */ sub_bf(bftmpy, bfymin, bfy3rd); tmpy1 = bftofloat(bftmpy); a2 = tmpx1*tmpx1 + tmpy1*tmpy1; a = sqrtl(a2); /* divide tmpx and tmpy by |tmpx| so that double version of atan2() can be used */ /* atan2() only depends on the ratio, this puts it in double's range */ signx = sign(tmpx1); tmpy = tmpy1; /* otherwise tmpy could be undefined below */ if(signx) tmpy = tmpy1/tmpx1 * signx; /* tmpy = tmpy / |tmpx| */ *Rotation = (double)(-rad_to_deg(atan2( (double)tmpy, signx ))); /* negative for image rotation */ /* tmpx = xxmin - xx3rd; */ sub_bf(bftmpx, bfxmin, bfx3rd); tmpx2 = bftofloat(bftmpx); /* tmpy = yymax - yy3rd; */ sub_bf(bftmpy, bfymax, bfy3rd); tmpy2 = bftofloat(bftmpy); b2 = tmpx2*tmpx2 + tmpy2*tmpy2; b = sqrtl(b2); tmpa = acos((double)((a2+b2-c2)/(2*a*b))); /* save tmpa for later use */ *Skew = 90 - rad_to_deg(tmpa); /* these are the only two variables that must use big precision */ /* *Xctr = (xxmin + xxmax)/2; */ add_bf(Xctr, bfxmin, bfxmax); half_a_bf(Xctr); /* *Yctr = (yymin + yymax)/2; */ add_bf(Yctr, bfymin, bfymax); half_a_bf(Yctr); Height = b * sin(tmpa); *Magnification = 2/Height; /* 1/(h/2) */ *Xmagfactor = (double)(Height / (DEFAULTASPECT * a)); /* if vector_a cross vector_b is negative */ /* then adjust for left-hand coordinate system */ if ( tmpx1*tmpy2 - tmpx2*tmpy1 < 0 && debugflag != 4010) { *Skew = -*Skew; *Xmagfactor = -*Xmagfactor; *Magnification = -*Magnification; } } if (*Magnification < 0) { *Magnification = -*Magnification; *Rotation += 180; } restore_stack(saved); return; } /* convert center/mag to corners using bf */ void cvtcornersbf(bf_t Xctr, bf_t Yctr, LDBL Magnification, double Xmagfactor, double Rotation, double Skew) { LDBL x, y; LDBL h, w; /* half height, width */ LDBL xmin, ymin, xmax, ymax, x3rd, y3rd; double tanskew, sinrot, cosrot; bf_t bfh, bfw; bf_t bftmp; int saved; saved = save_stack(); bfh = alloc_stack(bflength+2); bfw = alloc_stack(bflength+2); if (Xmagfactor == 0.0) Xmagfactor = 1.0; h = 1/Magnification; floattobf(bfh, h); w = h / (DEFAULTASPECT * Xmagfactor); floattobf(bfw, w); if (Rotation == 0.0 && Skew == 0.0) { /* simple, faster case */ /* xx3rd = xxmin = Xctr - w; */ sub_bf(bfxmin, Xctr, bfw); copy_bf(bfx3rd, bfxmin); /* xxmax = Xctr + w; */ add_bf(bfxmax, Xctr, bfw); /* yy3rd = yymin = Yctr - h; */ sub_bf(bfymin, Yctr, bfh); copy_bf(bfy3rd, bfymin); /* yymax = Yctr + h; */ add_bf(bfymax, Yctr, bfh); restore_stack(saved); return; } bftmp = alloc_stack(bflength+2); /* in unrotated, untranslated coordinate system */ tanskew = tan(deg_to_rad(Skew)); xmin = -w + h*tanskew; xmax = w - h*tanskew; x3rd = -w - h*tanskew; ymax = h; y3rd = ymin = -h; /* rotate coord system and then translate it */ Rotation = deg_to_rad(Rotation); sinrot = sin(Rotation); cosrot = cos(Rotation); /* top left */ x = xmin * cosrot + ymax * sinrot; y = -xmin * sinrot + ymax * cosrot; /* xxmin = x + Xctr; */ floattobf(bftmp, x); add_bf(bfxmin, bftmp, Xctr); /* yymax = y + Yctr; */ floattobf(bftmp, y); add_bf(bfymax, bftmp, Yctr); /* bottom right */ x = xmax * cosrot + ymin * sinrot; y = -xmax * sinrot + ymin * cosrot; /* xxmax = x + Xctr; */ floattobf(bftmp, x); add_bf(bfxmax, bftmp, Xctr); /* yymin = y + Yctr; */ floattobf(bftmp, y); add_bf(bfymin, bftmp, Yctr); /* bottom left */ x = x3rd * cosrot + y3rd * sinrot; y = -x3rd * sinrot + y3rd * cosrot; /* xx3rd = x + Xctr; */ floattobf(bftmp, x); add_bf(bfx3rd, bftmp, Xctr); /* yy3rd = y + Yctr; */ floattobf(bftmp, y); add_bf(bfy3rd, bftmp, Yctr); restore_stack(saved); return; } #ifdef _MSC_VER #pragma optimize( "", on ) #endif void updatesavename(char *filename) /* go to the next file name */ { char *save, *hold; char drive[FILE_MAX_DRIVE]; char dir[FILE_MAX_DIR]; char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; splitpath(filename ,drive,dir,fname,ext); hold = fname + strlen(fname) - 1; /* start at the end */ while(hold >= fname && (*hold == ' ' || isdigit(*hold))) /* skip backwards */ hold--; hold++; /* recover first digit */ while (*hold == '0') /* skip leading zeros */ hold++; save = hold; while (*save) { /* check for all nines */ if (*save != '9') break; save++; } if (!*save) /* if the whole thing is nines then back */ save = hold - 1; /* up one place. Note that this will eat */ /* your last letter if you go to far. */ else save = hold; sprintf(save,"%ld",atol(hold)+1); /* increment the number */ makepath(filename,drive,dir,fname,ext); } int check_writefile(char *name,char *ext) { /* after v16 release, change encoder.c to also use this routine */ char openfile[FILE_MAX_DIR]; char opentype[20]; /* int i; */ char *period; nextname: strcpy(openfile,name); strcpy(opentype,ext); #if 0 for (i = 0; i < (int)strlen(openfile); i++) if (openfile[i] == '.') { strcpy(opentype,&openfile[i]); openfile[i] = 0; } #endif if((period = has_ext(openfile)) != NULL) { strcpy(opentype,period); *period = 0; } strcat(openfile,opentype); if (access(openfile,0) != 0) /* file doesn't exist */ { strcpy(name,openfile); return 0; } /* file already exists */ if (overwrite == 0) { updatesavename(name); goto nextname; } return 1; } /* ('check_key()' was moved to FRACTINT.C for MSC7-overlay speed purposes) */ /* ('timer()' was moved to FRACTINT.C for MSC7-overlay speed purposes) */ BYTE trigndx[] = {SIN,SQR,SINH,COSH}; #ifndef XFRACT void (*ltrig0)(void) = lStkSin; void (*ltrig1)(void) = lStkSqr; void (*ltrig2)(void) = lStkSinh; void (*ltrig3)(void) = lStkCosh; void (*mtrig0)(void) = mStkSin; void (*mtrig1)(void) = mStkSqr; void (*mtrig2)(void) = mStkSinh; void (*mtrig3)(void) = mStkCosh; #endif void (*dtrig0)(void) = dStkSin; void (*dtrig1)(void) = dStkSqr; void (*dtrig2)(void) = dStkSinh; void (*dtrig3)(void) = dStkCosh; /* struct trig_funct_lst trigfn[] was moved to prompts1.c */ void showtrig(char *buf) /* return display form of active trig functions */ { char tmpbuf[30]; *buf = 0; /* null string if none */ trigdetails(tmpbuf); if (tmpbuf[0]) sprintf(buf," function=%s",tmpbuf); } static void trigdetails(char *buf) { int i, numfn; char tmpbuf[20]; if(fractype==JULIBROT || fractype==JULIBROTFP) numfn = (fractalspecific[neworbittype].flags >> 6) & 7; else numfn = (curfractalspecific->flags >> 6) & 7; if(curfractalspecific == &fractalspecific[FORMULA] || curfractalspecific == &fractalspecific[FFORMULA] ) numfn = maxfn; *buf = 0; /* null string if none */ if (numfn>0) { strcpy(buf,trigfn[trigndx[0]].name); i = 0; while(++i < numfn) { sprintf(tmpbuf,"/%s",trigfn[trigndx[i]].name); strcat(buf,tmpbuf); } } } /* set array of trig function indices according to "function=" command */ int set_trig_array(int k, char *name) { char trigname[10]; int i; char *slash; strncpy(trigname,name,6); trigname[6] = 0; /* safety first */ if ((slash = strchr(trigname,'/')) != NULL) *slash = 0; strlwr(trigname); for(i=0;i 24.855 days)"}; void get_calculation_time(char *msg, long ctime) { if (ctime >= 0) { sprintf(msg,"%3ld:%02ld:%02ld.%02ld", ctime/360000L, (ctime%360000L)/6000, (ctime%6000)/100, ctime%100); } else far_strcpy(msg,sreallylongtime); } static void show_str_var(char *name, char *var, int *row, char *msg) { if(var == NULL) return; if(*var != 0) { sprintf(msg,"%s=%s",name,var); putstring((*row)++,2,C_GENERAL_HI,msg); } } int tab_display_2(char *msg) { extern long maxptr, maxstack, startstack; int s_row,key,ret=0; helptitle(); setattr(1,0,C_GENERAL_MED,24*80); /* init rest to background */ s_row = 1; putstringcenter(s_row++,0,80,C_PROMPT_HI, sstopsecret); sprintf(msg,"Version %d patch %d",release, patchlevel); putstring(++s_row,2,C_GENERAL_HI,msg); sprintf(msg,"%lu bytes conventional stack free",stackavail()); putstring(++s_row,2,C_GENERAL_HI,msg); sprintf(msg,"%ld of %ld bignum memory used",maxptr,maxstack); putstring(++s_row,2,C_GENERAL_HI,msg); sprintf(msg," %ld used for bignum globals", startstack); putstring(++s_row,2,C_GENERAL_HI,msg); sprintf(msg," %ld stack used == %ld variables of length %d", maxptr-startstack,(long)((maxptr-startstack)/(rbflength+2)),rbflength+2); putstring(++s_row,2,C_GENERAL_HI,msg); if(bf_math) { sprintf(msg,"intlength %-d bflength %-d ",intlength, bflength); putstring(++s_row,2,C_GENERAL_HI,msg); } s_row++; show_str_var(s_tempdir, tempdir, &s_row, msg); show_str_var(s_workdir, workdir, &s_row, msg); show_str_var(s_printfile, PrintName, &s_row, msg); show_str_var(s_filename, readname, &s_row, msg); show_str_var(s_formulafile,FormFileName, &s_row, msg); show_str_var(s_savename, savename, &s_row, msg); show_str_var(s_parmfile, CommandFile, &s_row, msg); show_str_var(s_ifsfile, IFSFileName, &s_row, msg); show_str_var(s_autokeyname,autoname, &s_row, msg); show_str_var(s_lightname, light_name, &s_row, msg); show_str_var(s_map, MAP_name, &s_row, msg); sprintf(msg,"Sizeof fractalspecific array %d", num_fractal_types*(int)sizeof(struct fractalspecificstuff)); putstring(s_row++,2,C_GENERAL_HI,msg); sprintf(msg,"calc_status %d pixel [%d,%d]",calc_status,col,row); putstring(s_row++,2,C_GENERAL_HI,msg); if(fractype==FORMULA || fractype==FFORMULA) { sprintf(msg,"total_formula_mem %ld Max_Ops (posp) %u Max_Args (vsp) %u Used_extra %u", total_formula_mem,posp,vsp,used_extra); putstring(s_row++,2,C_GENERAL_HI,msg); sprintf(msg," Store ptr %d Loadptr %d Max_Ops var %u Max_Args var %u LastInitOp %d", StoPtr,LodPtr,Max_Ops,Max_Args,LastInitOp); putstring(s_row++,2,C_GENERAL_HI,msg); } else if(rhombus_stack[0]) { sprintf(msg,"SOI Recursion %d stack free %d %d %d %d %d %d %d %d %d %d", max_rhombus_depth+1, rhombus_stack[0], rhombus_stack[1], rhombus_stack[2], rhombus_stack[3], rhombus_stack[4], rhombus_stack[5], rhombus_stack[6], rhombus_stack[7], rhombus_stack[8], rhombus_stack[9]); putstring(s_row++,2,C_GENERAL_HI,msg); } /* sprintf(msg,"xdots %d ydots %d sxdots %d sydots %d",xdots,ydots,sxdots,sydots); putstring(s_row++,2,C_GENERAL_HI,msg); */ sprintf(msg,"xxstart %d xxstop %d yystart %d yystop %d %s uses_ismand %d", xxstart,xxstop,yystart,yystop, #ifndef XFRACT curfractalspecific->orbitcalc == fFormula?"fast parser": #endif curfractalspecific->orbitcalc == Formula?"slow parser": curfractalspecific->orbitcalc == BadFormula?"bad formula": "",uses_ismand); putstring(s_row++,2,C_GENERAL_HI,msg); /* sprintf(msg,"ixstart %d ixstop %d iystart %d iystop %d bitshift %d", ixstart,ixstop,iystart,iystop,bitshift); */ { sprintf(msg,"minstackavail %d llimit2 %ld use_grid %d", minstackavail,llimit2,use_grid); } putstring(s_row++,2,C_GENERAL_HI,msg); putstringcenter(24,0,80,C_GENERAL_LO,spressanykey1); *msg = 0; again: putstring(s_row,2,C_GENERAL_HI,msg); key=getakeynohelp(); if(key != ESC && key != BACKSPACE && key != TAB) { sprintf(msg,"%d ",key); goto again; } if(key == BACKSPACE || key == TAB) ret = 1; return(ret); } int tab_display() /* display the status of the current image */ { int s_row, i, j, addrow=0; double Xctr, Yctr; LDBL Magnification; double Xmagfactor, Rotation, Skew; bf_t bfXctr=NULL, bfYctr=NULL; char msg[350]; char far *msgptr; int key; int saved=0; int dec; int k; U16 save_extra_handle = 0; BYTE far *ptr_to_extraseg = NULL; int hasformparam = 0; if (calc_status < 0) { /* no active fractal image */ return(0); /* (no TAB on the credits screen) */ } if (calc_status == 1) /* next assumes CLK_TCK is 10^n, n>=2 */ calctime += (clock_ticks() - timer_start) / (CLK_TCK/100); stackscreen(); if(bf_math) { /* Save memory from the beginning of extraseg to ENDVID=22400 */ /* This is so the bf_math manipulations here don't corrupt */ /* the video modes or screen prompts. */ ptr_to_extraseg = MK_FP(extraseg,0); save_extra_handle = MemoryAlloc((U16)22400, 1L, FARMEM); MoveToMemory(ptr_to_extraseg,(U16)22400,1L,0L,save_extra_handle); saved = save_stack(); bfXctr = alloc_stack(bflength+2); bfYctr = alloc_stack(bflength+2); } if (fractype == FORMULA || fractype == FFORMULA) for (i = 0; i < MAXPARAMS; i += 2) if (!paramnotused(i)) hasformparam++; top: k = 0; /* initialize here so parameter line displays correctly on return from control-tab */ helptitle(); setattr(1,0,C_GENERAL_MED,24*80); /* init rest to background */ s_row = 2; putstring(s_row,2,C_GENERAL_MED,sfractal_type); if (display3d > 0) putstring(s_row,16,C_GENERAL_HI,s3D_transform); else { putstring(s_row,16,C_GENERAL_HI, curfractalspecific->name[0] == '*' ? &curfractalspecific->name[1] : curfractalspecific->name); i = 0; if (fractype == FORMULA || fractype == FFORMULA) { putstring(s_row+1,3,C_GENERAL_MED,sitem_name); putstring(s_row+1,16,C_GENERAL_HI,FormName); i = strlen(FormName)+1; putstring(s_row+2,3,C_GENERAL_MED,sitem_file); if((int)strlen(FormFileName) >= 29) addrow = 1; putstring(s_row+2+addrow,16,C_GENERAL_HI,FormFileName); } trigdetails(msg); putstring(s_row+1,16+i,C_GENERAL_HI,msg); if (fractype == LSYSTEM) { putstring(s_row+1,3,C_GENERAL_MED,sitem_name); putstring(s_row+1,16,C_GENERAL_HI,LName); putstring(s_row+2,3,C_GENERAL_MED,sitem_file); if((int)strlen(LFileName) >= 28) addrow = 1; putstring(s_row+2+addrow,16,C_GENERAL_HI,LFileName); } if (fractype == IFS || fractype == IFS3D) { putstring(s_row+1,3,C_GENERAL_MED,sitem_name); putstring(s_row+1,16,C_GENERAL_HI,IFSName); putstring(s_row+2,3,C_GENERAL_MED,sitem_file); if((int)strlen(IFSFileName) >= 28) addrow = 1; putstring(s_row+2+addrow,16,C_GENERAL_HI,IFSFileName); } } switch (calc_status) { case 0: msgptr = sparms_chgd; break; case 1: msgptr = sstill_being; break; case 2: msgptr = sinterrupted_resumable; break; case 3: msgptr = sinterrupted_non_resumable; break; case 4: msgptr = simage_completed; break; default: msgptr = ""; } putstring(s_row,45,C_GENERAL_HI,msgptr); if(initbatch && calc_status != 0) putstring(-1,-1,C_GENERAL_HI,sbatch); if (helpmode == HELPCYCLING) putstring(s_row+1,45,C_GENERAL_HI,syou_are_cycling); ++s_row; /* if(bf_math == 0) */ ++s_row; i = j = 0; if (display3d > 0) { if (usr_floatflag) j = 1; } else if (floatflag) j = (usr_floatflag) ? 1 : 2; if(bf_math==0) { if (j) { putstring(s_row,45,C_GENERAL_HI,sfloating_point); putstring(-1,-1,C_GENERAL_HI,(j == 1) ? sflag_is_activated : sin_use_required ); i = 1; } else { putstring(s_row,45,C_GENERAL_HI,sinteger_math); i = 1; } } else { sprintf(msg,"(%-d decimals)",decimals /*getprecbf(CURRENTREZ)*/); putstring(s_row,45,C_GENERAL_HI,sarbitrary_precision); putstring(-1,-1,C_GENERAL_HI,msg); i = 1; } s_row += i; if (calc_status == 1 || calc_status == 2) if (curfractalspecific->flags&NORESUME) { static FCODE msg[] = {"Note: can't resume this type after interrupts other than and "}; putstring(s_row++,2,C_GENERAL_HI,msg); } s_row += addrow; putstring(s_row,2,C_GENERAL_MED,ssavename); putstring(s_row,-1,C_GENERAL_HI,savename); /* if(bf_math == 0) */ ++s_row; if (got_status >= 0 && (calc_status == 1 || calc_status == 2)) { switch (got_status) { case 0: sprintf(msg,"%d Pass Mode",totpasses); putstring(s_row,2,C_GENERAL_HI,msg); if(usr_stdcalcmode=='3') putstring(s_row,-1,C_GENERAL_HI,sthreepass); break; case 1: putstring(s_row,2,C_GENERAL_HI,ssolid_guessing); if(usr_stdcalcmode=='3') putstring(s_row,-1,C_GENERAL_HI,sthreepass); break; case 2: putstring(s_row,2,C_GENERAL_HI,sboundary_tracing); break; case 3: sprintf(msg,"Processing row %d (of %d) of input image",currow,fileydots); putstring(s_row,2,C_GENERAL_HI,msg); break; case 4: putstring(s_row,2,C_GENERAL_HI,stesseral); break; case 5: putstring(s_row,2,C_GENERAL_HI,sdiffusion); break; case 6: putstring(s_row,2,C_GENERAL_HI,sorbits); break; } ++s_row; if (got_status == 5 ) { sprintf(msg,"%2.2f%% done, counter at %lu of %lu (%u bits)", (100.0 * dif_counter)/dif_limit, dif_counter,dif_limit,bits); putstring(s_row,2,C_GENERAL_MED,msg); ++s_row; } else if (got_status != 3) { sprintf(msg,"Working on block (y,x) [%d,%d]...[%d,%d], ", yystart,xxstart,yystop,xxstop); putstring(s_row,2,C_GENERAL_MED,msg); if (got_status == 2 || got_status == 4) { /* btm or tesseral */ putstring(-1,-1,C_GENERAL_MED,"at "); sprintf(msg,"[%d,%d]",currow,curcol); putstring(-1,-1,C_GENERAL_HI,msg); } else { if (totpasses > 1) { putstring(-1,-1,C_GENERAL_MED,"pass "); sprintf(msg,"%d",curpass); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED," of "); sprintf(msg,"%d",totpasses); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,", "); } putstring(-1,-1,C_GENERAL_MED,"at row "); sprintf(msg,"%d",currow); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED," col "); sprintf(msg,"%d",col); putstring(-1,-1,C_GENERAL_HI,msg); } ++s_row; } } putstring(s_row,2,C_GENERAL_MED,scalculation_time); get_calculation_time(msg,calctime); putstring(-1,-1,C_GENERAL_HI,msg); if ((got_status == 5) && (calc_status == 1)) { /* estimate total time */ putstring(-1,-1,C_GENERAL_MED," estimated total time: "); get_calculation_time( msg,(long)(calctime*((dif_limit*1.0)/dif_counter)) ); putstring(-1,-1,C_GENERAL_HI,msg); } if ((curfractalspecific->flags&INFCALC) && (coloriter != 0)) { putstring(s_row,-1,C_GENERAL_MED,siterations); sprintf(msg," %ld of %ld",coloriter-2,maxct); putstring(s_row,-1,C_GENERAL_HI,msg); } ++s_row; if(bf_math == 0) ++s_row; if (videoentry.xdots && bf_math==0) { sprintf(msg,"Video: %dx%dx%d %s %s", videoentry.xdots, videoentry.ydots, videoentry.colors, videoentry.name, videoentry.comment); putstring(s_row++,2,C_GENERAL_MED,msg); } if(!(curfractalspecific->flags&NOZOOM)) { adjust_corner(); /* make bottom left exact if very near exact */ if(bf_math) { int truncate, truncaterow; dec = min(320,decimals); adjust_cornerbf(); /* make bottom left exact if very near exact */ cvtcentermagbf(bfXctr, bfYctr, &Magnification, &Xmagfactor, &Rotation, &Skew); /* find alignment information */ msg[0] = 0; truncate = 0; if(dec < decimals) truncate = 1; truncaterow = row; putstring(++s_row,2,C_GENERAL_MED,scenter); putstring(s_row,8,C_GENERAL_MED,s_x); bftostr(msg,dec,bfXctr); if(putstringwrap(&s_row,10,78,C_GENERAL_HI,msg,5)==1) truncate = 1; putstring(++s_row,8,C_GENERAL_MED,s_y); bftostr(msg,dec,bfYctr); if(putstringwrap(&s_row,10,78,C_GENERAL_HI,msg,5)==1 || truncate) putstring(truncaterow,2,C_GENERAL_MED,struncate); putstring(++s_row,2,C_GENERAL_MED,smag); #ifdef USE_LONG_DOUBLE sprintf(msg,"%10.8Le",Magnification); #else sprintf(msg,"%10.8le",Magnification); #endif putstring(-1,11,C_GENERAL_HI,msg); putstring(++s_row,2,C_GENERAL_MED,sxmag); sprintf(msg,"%11.4f ",Xmagfactor); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,srot); sprintf(msg,"%9.3f ",Rotation); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,sskew); sprintf(msg,"%9.3f",Skew); putstring(-1,-1,C_GENERAL_HI,msg); } else /* bf != 1 */ { putstring(s_row,2,C_GENERAL_MED,scornersxy); putstring(++s_row,3,C_GENERAL_MED,stop_left); sprintf(msg,"%20.16f %20.16f",xxmin,yymax); putstring(-1,17,C_GENERAL_HI,msg); putstring(++s_row,3,C_GENERAL_MED,sbottom_right); sprintf(msg,"%20.16f %20.16f",xxmax,yymin); putstring(-1,17,C_GENERAL_HI,msg); if (xxmin != xx3rd || yymin != yy3rd) { putstring(++s_row,3,C_GENERAL_MED,sbottom_left); sprintf(msg,"%20.16f %20.16f",xx3rd,yy3rd); putstring(-1,17,C_GENERAL_HI,msg); } cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); putstring(s_row+=2,2,C_GENERAL_MED,scenter); sprintf(msg,"%20.16f %20.16f ",Xctr,Yctr); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,smag); #ifdef USE_LONG_DOUBLE sprintf(msg," %10.8Le",Magnification); #else sprintf(msg," %10.8le",Magnification); #endif putstring(-1,-1,C_GENERAL_HI,msg); putstring(++s_row,2,C_GENERAL_MED,sxmag); sprintf(msg,"%11.4f ",Xmagfactor); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,srot); sprintf(msg,"%9.3f ",Rotation); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,sskew); sprintf(msg,"%9.3f",Skew); putstring(-1,-1,C_GENERAL_HI,msg); } } if(typehasparm(fractype,0,msg) || hasformparam) for (i = 0; i < MAXPARAMS; i++) { int col; char p[50]; if(typehasparm(fractype,i,p)) { if(k%4 == 0) { s_row++; col = 9; } else col = -1; if(k == 0) /* only true with first displayed parameter */ putstring(++s_row,2,C_GENERAL_MED,sparams); sprintf(msg,"%3d: ",i+1); putstring(s_row,col,C_GENERAL_MED,msg); if(*p == '+') sprintf(msg,"%-12d",(int)param[i]); else if(*p == '#') sprintf(msg,"%-12lu",(U32)param[i]); else sprintf(msg,"%-12.9f",param[i]); putstring(-1,-1,C_GENERAL_HI,msg); k++; } } putstring(s_row+=2,2,C_GENERAL_MED,siteration_maximum); sprintf(msg,"%ld (%ld)",coloriter,maxit); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,seffective_bailout); sprintf(msg,"%f",rqlim); putstring(-1,-1,C_GENERAL_HI,msg); if (fractype == PLASMA || fractype == ANT || fractype == CELLULAR) { putstring(++s_row,2,C_GENERAL_MED,scurrent_rseed); sprintf(msg,"%d",rseed); putstring(-1,-1,C_GENERAL_HI,msg); } if(invert) { putstring(++s_row,2,C_GENERAL_MED,sinversion_radius); sprintf(msg,"%12.9f",f_radius); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,sxcenter); sprintf(msg,"%12.9f",f_xcenter); putstring(-1,-1,C_GENERAL_HI,msg); putstring(-1,-1,C_GENERAL_MED,sycenter); sprintf(msg,"%12.9f",f_ycenter); putstring(-1,-1,C_GENERAL_HI,msg); } if ((s_row += 2) < 23) ++s_row; /*waitforkey:*/ putstringcenter(/*s_row*/24,0,80,C_GENERAL_LO,spressanykey); movecursor(25,80); #ifdef XFRACT while (keypressed()) { getakey(); } #endif key = getakeynohelp(); if (key==F6) { unstackscreen(); area(); stackscreen(); /* goto waitforkey;*/ goto top; } else if(key==CTL_TAB || key==BACK_TAB || key==F7) { if(tab_display_2(msg)) goto top; } unstackscreen(); timer_start = clock_ticks(); /* tab display was "time out" */ if(bf_math) { restore_stack(saved); MoveFromMemory(ptr_to_extraseg,(U16)22400,1L,0L,save_extra_handle); MemoryRelease(save_extra_handle); save_extra_handle = 0; } return(0); } static void area(void) { /* apologies to UNIX folks, we PC guys have to save near space */ static FCODE warning[] = {"Warning: inside may not be unique\n"}; static FCODE total_area[] = {". Total area "}; char far *msg; int x,y; char buf[160]; long cnt=0; if (inside<0) { static FCODE msg[] = {"Need solid inside to compute area"}; stopmsg(0,msg); return; } for (y=0;y0 && outside<0 && maxit>inside) { msg = warning; } else { msg = (char far *)""; } #ifndef XFRACT sprintf(buf,"%Fs%ld inside pixels of %ld%Fs%f", msg,cnt,(long)xdots*(long)ydots,(char far *)total_area, cnt/((float)xdots*(float)ydots)*(xxmax-xxmin)*(yymax-yymin)); #else sprintf(buf,"%s%ld inside pixels of %ld%s%f", msg,cnt,(long)xdots*(long)ydots,total_area, cnt/((float)xdots*(float)ydots)*(xxmax-xxmin)*(yymax-yymin)); #endif stopmsg(4,buf); } int endswithslash(char far *fl) { int len; len = far_strlen(fl); if(len) if(fl[--len] == SLASHC) return(1); return(0); } /* --------------------------------------------------------------------- */ static char seps[] = {"' ','\t',\n',\r'"}; char *get_ifs_token(char *buf,FILE *ifsfile) { char *bufptr; for(;;) { if(file_gets(buf,200,ifsfile) < 0) return(NULL); else { if((bufptr = strchr(buf,';')) != NULL) /* use ';' as comment to eol */ *bufptr = 0; if((bufptr = strtok(buf, seps)) != NULL) return(bufptr); } } } FCODE insufficient_ifs_mem[]={"Insufficient memory for IFS"}; int numaffine; int ifsload() /* read in IFS parameters */ { int i; FILE *ifsfile; char buf[201]; char *bufptr; int ret,rowsize; if (ifs_defn) { /* release prior parms */ farmemfree((char far *)ifs_defn); ifs_defn = NULL; } ifs_type = 0; rowsize = IFSPARM; if (find_file_item(IFSFileName,IFSName,&ifsfile, 3) < 0) return(-1); file_gets(buf,200,ifsfile); if((bufptr = strchr(buf,';')) != NULL) /* use ';' as comment to eol */ *bufptr = 0; strlwr(buf); bufptr = &buf[0]; while (*bufptr) { if (strncmp(bufptr,"(3d)",4) == 0) { ifs_type = 1; rowsize = IFS3DPARM; } ++bufptr; } for (i = 0; i < (NUMIFS+1)*IFS3DPARM; ++i) ((float *)tstack)[i] = 0; i = ret = 0; bufptr = get_ifs_token(buf,ifsfile); while(bufptr != NULL) { if(sscanf(bufptr," %f ",&((float *)tstack)[i]) != 1) break ; if (++i >= NUMIFS*rowsize) { static FCODE msg[]={"IFS definition has too many lines"}; stopmsg(0,msg); ret = -1; break; } if((bufptr = strtok( NULL, seps ))==NULL) { if((bufptr = get_ifs_token(buf,ifsfile)) == NULL) { ret = -1; break; } } if(ret == -1) break; if(*bufptr == '}') break; } if ((i % rowsize) != 0 || *bufptr != '}') { static FCODE msg[]={"invalid IFS definition"}; stopmsg(0,msg); ret = -1; } if (i == 0 && ret == 0) { static FCODE msg[]={"Empty IFS definition"}; stopmsg(0,msg); ret = -1; } fclose(ifsfile); if (ret == 0) { numaffine = i/rowsize; if ((ifs_defn = (float far *)farmemalloc( (long)((NUMIFS+1)*IFS3DPARM*sizeof(float)))) == NULL) { stopmsg(0,insufficient_ifs_mem); ret = -1; } else for (i = 0; i < (NUMIFS+1)*IFS3DPARM; ++i) ifs_defn[i] = ((float *)tstack)[i]; } return(ret); } /* TW 5-31-94 - added search of current directory for entry files if entry item not found */ int find_file_item(char *filename,char *itemname,FILE **fileptr, int itemtype) { FILE *infile=NULL; int found = 0; char parsearchname[ITEMNAMELEN + 6]; char drive[FILE_MAX_DRIVE]; char dir[FILE_MAX_DIR]; char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char fullpath[FILE_MAX_PATH]; char defaultextension[FILE_MAX_EXT]; splitpath(filename,drive,dir,fname,ext); makepath(fullpath,"","",fname,ext); if(stricmp(filename, CommandFile)) { if((infile=fopen(filename, "rb")) != NULL) { if(scan_entries(infile, NULL, itemname) == -1) { found = 1; } else { fclose(infile); infile = NULL; } } if(!found && checkcurdir) { makepath(fullpath,"",DOTSLASH,fname,ext); if((infile=fopen(fullpath, "rb")) != NULL) { if(scan_entries(infile, NULL, itemname) == -1) { strcpy(filename, fullpath); found = 1; } else { fclose(infile); infile = NULL; } } } } switch (itemtype) { case 1: strcpy(parsearchname, "frm:"); strcat(parsearchname, itemname); parsearchname[ITEMNAMELEN + 5] = (char) 0; /*safety*/ strcpy(defaultextension, ".frm"); splitpath(searchfor.frm,drive,dir,NULL,NULL); break; case 2: strcpy(parsearchname, "lsys:"); strcat(parsearchname, itemname); parsearchname[ITEMNAMELEN + 5] = (char) 0; /*safety*/ strcpy(defaultextension, ".l"); splitpath(searchfor.lsys,drive,dir,NULL,NULL); break; case 3: strcpy(parsearchname, "ifs:"); strcat(parsearchname, itemname); parsearchname[ITEMNAMELEN + 5] = (char) 0; /*safety*/ strcpy(defaultextension, ".ifs"); splitpath(searchfor.ifs,drive,dir,NULL,NULL); break; default: strcpy(parsearchname, itemname); parsearchname[ITEMNAMELEN + 5] = (char) 0; /*safety*/ strcpy(defaultextension, ".par"); splitpath(searchfor.par,drive,dir,NULL,NULL); break; } if(!found) { if((infile=fopen(CommandFile, "rb")) != NULL) { if(scan_entries(infile, NULL, parsearchname) == -1) { strcpy(filename, CommandFile); found = 1; } else { fclose(infile); infile = NULL; } } } if(!found) { makepath(fullpath,drive,dir,fname,ext); if((infile=fopen(fullpath, "rb")) != NULL) { if(scan_entries(infile, NULL, itemname) == -1) { strcpy(filename, fullpath); found = 1; } else { fclose(infile); infile = NULL; } } } if(!found) { /* search for file */ int out; makepath(fullpath,drive,dir,"*",defaultextension); out = fr_findfirst(fullpath); while(out == 0) { char msg[200]; DTA.filename[MAX_NAME-1]=0; if(!(DTA.attribute & SUBDIR) && strcmp(DTA.filename,".")&& strcmp(DTA.filename,"..")) { sprintf(msg,"Searching %s for %s ",DTA.filename,itemname); showtempmsg(msg); #ifndef XFRACT strlwr(DTA.filename); #endif splitpath(DTA.filename,NULL,NULL,fname,ext); makepath(fullpath,drive,dir,fname,ext); if((infile=fopen(fullpath, "rb")) != NULL) { if(scan_entries(infile, NULL, itemname) == -1) { strcpy(filename, fullpath); found = 1; break; } else { fclose(infile); infile = NULL; } } } out = fr_findnext(); } cleartempmsg(); } if (!found && orgfrmsearch && itemtype == 1) { splitpath(orgfrmdir,drive,dir,NULL,NULL); fname[0] = '_'; fname[1] = (char) 0; if (isalpha(itemname[0])) { if (strnicmp(itemname, "carr", 4)) { fname[1] = itemname[0]; fname[2] = (char) 0; } else if (isdigit(itemname[4])) { strcat(fname, "rc"); fname[3] = itemname[4]; fname[4] = (char) 0; } else { strcat(fname, "rc"); } } else if (isdigit(itemname[0])) { strcat(fname, "num"); } else { strcat(fname, "chr"); } makepath(fullpath,drive,dir,fname,defaultextension); if((infile=fopen(fullpath, "rb")) != NULL) { if(scan_entries(infile, NULL, itemname) == -1) { strcpy(filename, fullpath); found = 1; } else { fclose(infile); infile = NULL; } } } if(!found) { sprintf(fullpath,"'%s' file entry item not found",itemname); stopmsg(0,fullpath); return(-1); } /* found file */ if(fileptr != NULL) *fileptr = infile; else if(infile != NULL) fclose(infile); return(0); } int file_gets(char *buf,int maxlen,FILE *infile) { int len,c; /* similar to 'fgets', but file may be in either text or binary mode */ /* returns -1 at eof, length of string otherwise */ if (feof(infile)) return -1; len = 0; while (len < maxlen) { if ((c = getc(infile)) == EOF || c == '\032') { if (len) break; return -1; } if (c == '\n') break; /* linefeed is end of line */ if (c != '\r') buf[len++] = (char)c; /* ignore c/r */ } buf[len] = 0; return len; } int matherr_ct = 0; #ifndef XFRACT #ifdef WINFRACT /* call this something else to dodge the QC4WIN bullet... */ int win_matherr( struct exception *except ) #else int _cdecl _matherr( struct exception *except ) #endif { if(debugflag != 0) { static FILE *fp=NULL; static FCODE msg[]={"Math error, but we'll try to keep going"}; if(matherr_ct++ == 0) if(debugflag == 4000 || debugflag == 3200) stopmsg(0,msg); if(fp==NULL) fp = fopen("matherr","w"); if(matherr_ct < 100) { fprintf(fp,"err #%d: %d\nname: %s\narg: %e\n", matherr_ct, except->type, except->name, except->arg1); fflush(fp); } else matherr_ct = 100; } if( except->type == DOMAIN ) { char buf[40]; sprintf(buf,"%e",except->arg1); /* This test may be unnecessary - from my experiments if the argument is too large or small the error is TLOSS not DOMAIN */ if(strstr(buf,"IN")||strstr(buf,"NAN")) /* trashed arg? */ /* "IND" with MSC, "INF" with BC++ */ { if( strcmp( except->name, s_sin ) == 0 ) { except->retval = 0.0; return(1); } else if( strcmp( except->name, s_cos ) == 0 ) { except->retval = 1.0; return(1); } else if( strcmp( except->name, s_log ) == 0 ) { except->retval = 1.0; return(1); } } } if( except->type == TLOSS ) { /* try valiantly to keep going */ if( strcmp( except->name, s_sin ) == 0 ) { except->retval = 0.5; return(1); } else if( strcmp( except->name, s_cos ) == 0 ) { except->retval = 0.5; return(1); } } /* shucks, no idea what went wrong, but our motto is "keep going!" */ except->retval = 1.0; return(1); } #endif void roundfloatd(double *x) /* make double converted from float look ok */ { char buf[30]; sprintf(buf,"%-10.7g",*x); *x = atof(buf); } void fix_inversion(double *x) /* make double converted from string look ok */ { char buf[30]; sprintf(buf,"%-1.15lg",*x); *x = atof(buf); } /* fake a keystroke, returns old pending key */ int ungetakey(int key) { int old; old = keybuffer; keybuffer = key; return(old); } #if _MSC_VER == 800 #ifdef FIXTAN_DEFINED #undef tan /* !!!!! stupid MSVC tan(x) bug fix !!!!!!!! */ /* tan(x) can return -tan(x) if -pi/2 < x < pi/2 */ /* if tan(x) has been called before outside this range. */ double fixtan( double x ) { double y; y = tan(x); if ((x > -PI/2 && x < 0 && y > 0) || (x > 0 && x < PI/2 && y < 0)) y = -y; return y; } #define tan fixtan #endif #endif xfractint-20.4.10.orig/common/diskvid.c0000644000000000000000000005211110720106706014575 0ustar /* "Disk-Video" (and RAM-Video and Expanded-Memory Video) routines Reworked with fast caching July '90 by Pieter Branderhorst. (I'm proud of this cache handler, had to get my name on it!) Caution when modifying any code in here: bugs are possible which slow the cache substantially but don't cause incorrect results. Do timing tests for a variety of situations after any change. */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #define BOXROW 6 #define BOXCOL 11 #define BOXWIDTH 57 #define BOXDEPTH 12 int disk16bit = 0; /* storing 16 bit values for continuous potential */ static int timetodisplay; static FILE *fp = NULL; int disktarga; #define BLOCKLEN 2048 /* must be a power of 2, must match next */ #define BLOCKSHIFT 11 /* must match above */ #define CACHEMIN 4 /* minimum cache size in Kbytes */ #define CACHEMAX 64 /* maximum cache size in Kbytes */ #define FREEMEM 33 /* try to leave this much far memory unallocated */ #define HASHSIZE 1024 /* power of 2, near CACHEMAX/(BLOCKLEN+8) */ static struct cache { /* structure of each cache entry */ long offset; /* pixel offset in image */ BYTE pixel[BLOCKLEN]; /* one pixel per byte (this *is* faster) */ unsigned int hashlink; /* ptr to next cache entry with same hash */ unsigned int dirty : 1; /* changed since read? */ unsigned int lru : 1; /* recently used? */ } far *cache_end, far *cache_lru, far *cur_cache; struct cache far *cache_start = NULL; long high_offset; /* highwater mark of writes */ long seek_offset; /* what we'll get next if we don't seek */ long cur_offset; /* offset of last block referenced */ int cur_row; long cur_row_base; unsigned int far *hash_ptr = NULL; int pixelshift; int headerlength; unsigned int rowsize = 0; /* doubles as a disk video not ok flag */ unsigned int colsize; /* sydots, *2 when pot16bit */ BYTE far *membuf; U16 dv_handle = 0; long memoffset = 0; long oldmemoffset = 0; BYTE far *membufptr; static void _fastcall near findload_cache(long); static struct cache far * _fastcall near find_cache(long); static void near write_cache_lru(void); static void _fastcall near mem_putc(BYTE); static BYTE near mem_getc(void); static void _fastcall near mem_seek(long); int startdisk() { if (!diskisactive) return(0); headerlength = disktarga = 0; return (common_startdisk(sxdots,sydots,colors)); } int pot_startdisk() { int i; if (dotmode == 11) /* ditch the original disk file */ enddisk(); else { static FCODE msg[] = {"clearing 16bit pot work area"}; showtempmsg(msg); } headerlength = disktarga = 0; i = common_startdisk(sxdots,sydots<<1,colors); cleartempmsg(); if (i == 0) disk16bit = 1; return (i); } int targa_startdisk(FILE *targafp,int overhead) { int i; if (dotmode == 11) { /* ditch the original disk file, make just the targa */ enddisk(); /* close the 'screen' */ setnullvideo(); /* set readdot and writedot routines to do nothing */ } headerlength = overhead; fp = targafp; disktarga = 1; /* i = common_startdisk(sxdots*3,sydots,colors); */ i = common_startdisk(xdots*3,ydots,colors); high_offset = 100000000L; /* targa not necessarily init'd to zeros */ return (i); } int _fastcall common_startdisk(long newrowsize, long newcolsize, int colors) { int i,freemem; long memorysize, offset; unsigned int far *fwd_link = NULL; struct cache far *ptr1 = NULL; long longtmp; unsigned int cache_size; BYTE far *tempfar = NULL; if (diskflag) enddisk(); if (dotmode == 11) { /* otherwise, real screen also in use, don't hit it */ char buf[20]; static FCODE fmsg1[] = {"'Disk-Video' mode"}; static FCODE fmsg2[] = {"Screen resolution: "}; static FCODE fsname[] = {"Save name: "}; static FCODE stat[] = {"Status:"}; helptitle(); setattr(1,0,C_DVID_BKGRD,24*80); /* init rest to background */ for (i = 0; i < BOXDEPTH; ++i) setattr(BOXROW+i,BOXCOL,C_DVID_LO,BOXWIDTH); /* init box */ putstring(BOXROW+2,BOXCOL+4,C_DVID_HI,fmsg1); putstring(BOXROW+4,BOXCOL+4,C_DVID_LO,fmsg2); sprintf(buf,"%d x %d",sxdots,sydots); putstring(-1,-1,C_DVID_LO,buf); if (disktarga) { static FCODE tarmsg[] = {" 24 bit Targa"}; putstring(-1,-1,C_DVID_LO,tarmsg); } else { static FCODE clrmsg[] = {" Colors: "}; putstring(-1,-1,C_DVID_LO,clrmsg); sprintf(buf,"%d",colors); putstring(-1,-1,C_DVID_LO,buf); } putstring(BOXROW+6,BOXCOL+4,C_DVID_LO,fsname); sprintf(buf,"%s",savename); putstring(-1,-1,C_DVID_LO,buf); putstring(BOXROW+10,BOXCOL+4,C_DVID_LO,stat); { static FCODE o_msg[] = {"clearing the 'screen'"}; char far msg[sizeof(o_msg)]; far_strcpy(msg,o_msg); dvid_status(0,msg); } } cur_offset = seek_offset = high_offset = -1; cur_row = -1; if (disktarga) pixelshift = 0; else { pixelshift = 3; i = 2; while (i < colors) { i *= i; --pixelshift; } } if(bf_math) timetodisplay = 10; /* time-to-display-status counter */ else timetodisplay = 1000; /* time-to-display-status counter */ /* allocate cache: try for the max; leave FREEMEMk free if we can get that much or more; if we can't get that much leave 1/2 of whatever there is free; demand a certain minimum or nogo at all */ freemem = FREEMEM; for (cache_size = CACHEMAX; cache_size >= CACHEMIN; --cache_size) { longtmp = ((int)cache_size < freemem) ? (long)cache_size << 11 : (long)(cache_size+freemem) << 10; if ((tempfar = farmemalloc(longtmp)) != NULL) { farmemfree(tempfar); break; } } if(debugflag==4200) cache_size = CACHEMIN; longtmp = (long)cache_size << 10; cache_start = (struct cache far *)farmemalloc(longtmp); if (cache_size == 64) --longtmp; /* safety for next line */ cache_end = (cache_lru = cache_start) + longtmp / sizeof(*cache_start); hash_ptr = (unsigned int far *)farmemalloc((long)(HASHSIZE<<1)); membuf = (BYTE far *)farmemalloc((long)BLOCKLEN); if (cache_start == NULL || hash_ptr == NULL || membuf == NULL) { static FCODE msg[]={"*** insufficient free memory for cache buffers ***"}; stopmsg(0,msg); return(-1); } if (dotmode == 11) { char buf[50]; sprintf(buf,"Cache size: %dK\n\n",cache_size); putstring(BOXROW+8,BOXCOL+4,C_DVID_LO,buf); } /* preset cache to all invalid entries so we don't need free list logic */ for (i = 0; i < HASHSIZE; ++i) hash_ptr[i] = 0xffff; /* 0xffff marks the end of a hash chain */ longtmp = 100000000L; for (ptr1 = cache_start; ptr1 < cache_end; ++ptr1) { ptr1->dirty = ptr1->lru = 0; fwd_link = hash_ptr + (((unsigned short)(longtmp+=BLOCKLEN) >> BLOCKSHIFT) & (HASHSIZE-1)); ptr1->offset = longtmp; ptr1->hashlink = *fwd_link; *fwd_link = (char far *)ptr1 - (char far *)cache_start; } memorysize = (long)(newcolsize) * newrowsize + headerlength; if ((i = (short)memorysize & (BLOCKLEN-1)) != 0) memorysize += BLOCKLEN - i; memorysize >>= pixelshift; memorysize >>= BLOCKSHIFT; diskflag = 1; rowsize = (unsigned int) newrowsize; colsize = (unsigned int) newcolsize; if (disktarga) { /* Retrieve the header information first */ BYTE far *tmpptr; tmpptr = membuf; fseek(fp, 0L,SEEK_SET); for (i = 0; i < headerlength; i++) *tmpptr++ = (BYTE)fgetc(fp); fclose(fp); dv_handle = MemoryAlloc((U16)BLOCKLEN, memorysize, DISK); } else dv_handle = MemoryAlloc((U16)BLOCKLEN, memorysize, EXPANDED); if (dv_handle == 0) { static FCODE msg[]={"*** insufficient free memory/disk space ***"}; stopmsg(0,msg); goodmode = 0; rowsize = 0; return(-1); } if (dotmode == 11) switch (MemoryType(dv_handle)) { static FCODE fmsg1[] = {"Using no Memory, it's broke"}; static FCODE fmsg2[] = {"Using your Expanded Memory"}; static FCODE fmsg3[] = {"Using your Extended Memory"}; static FCODE fmsg4[] = {"Using your Disk Drive"}; case NOWHERE: default: putstring(BOXROW+2,BOXCOL+23,C_DVID_LO,fmsg1); break; case EXPANDED: putstring(BOXROW+2,BOXCOL+23,C_DVID_LO,fmsg2); break; case EXTENDED: putstring(BOXROW+2,BOXCOL+23,C_DVID_LO,fmsg3); break; case DISK: putstring(BOXROW+2,BOXCOL+23,C_DVID_LO,fmsg4); break; } membufptr = membuf; if (!disktarga) for (offset = 0; offset < memorysize; offset++) { static FCODE cancel[] = {"Disk Video initialization interrupted:\n"}; SetMemory(0, (U16)BLOCKLEN, 1L, offset, dv_handle); if (keypressed()) /* user interrupt */ if (stopmsg(2, cancel)) /* esc to cancel, else continue */ { enddisk(); goodmode = 0; return -2; /* -1 == failed, -2 == cancel */ } } if (disktarga) { /* Put header information in the file */ MoveToMemory(membuf, (U16)headerlength, 1L, 0, dv_handle); } if (dotmode == 11) dvid_status(0,""); return(0); } void enddisk() { if (fp != NULL) { if (disktarga) /* flush the cache */ for (cache_lru = cache_start; cache_lru < cache_end; ++cache_lru) if (cache_lru->dirty) write_cache_lru(); fclose(fp); } if (dv_handle != 0) { MemoryRelease(dv_handle); dv_handle = 0; } if (hash_ptr != NULL) farmemfree((void far *)hash_ptr); if (cache_start != NULL) farmemfree((void far *)cache_start); if (membuf != NULL) farmemfree((void far *)membuf); diskflag = rowsize = disk16bit = 0; hash_ptr = NULL; cache_start = NULL; fp = NULL; } int readdisk(unsigned int col, unsigned int row) { int col_subscr; long offset; char buf[41]; if (--timetodisplay < 0) { /* time to display status? */ if (dotmode == 11) { sprintf(buf," reading line %4d", (row >= (unsigned int)sydots) ? row-sydots : row); /* adjust when potfile */ dvid_status(0,buf); } if(bf_math) timetodisplay = 10; /* time-to-display-status counter */ else timetodisplay = 1000; /* time-to-display-status counter */ } if (row != (unsigned int)cur_row) { /* try to avoid ghastly code generated for multiply */ if (row >= colsize) /* while we're at it avoid this test if not needed */ return(0); cur_row_base = (long)(cur_row = row) * rowsize; } if (col >= rowsize) return(0); offset = cur_row_base + col; col_subscr = (short)offset & (BLOCKLEN-1); /* offset within cache entry */ if (cur_offset != (offset & (0L-BLOCKLEN))) /* same entry as last ref? */ findload_cache(offset & (0L-BLOCKLEN)); return (cur_cache->pixel[col_subscr]); } int FromMemDisk(long offset, int size, void far *dest) { int col_subscr = (int)(offset & (BLOCKLEN - 1)); if (col_subscr + size > BLOCKLEN) /* access violates a */ return 0; /* cache boundary */ if (cur_offset != (offset & (0L-BLOCKLEN))) /* same entry as last ref? */ findload_cache (offset & (0L-BLOCKLEN)); far_memcpy(dest, (void far *) &cur_cache->pixel[col_subscr], size); cur_cache->dirty = 0; return 1; } void targa_readdisk(unsigned int col, unsigned int row, BYTE *red, BYTE *green, BYTE *blue) { col *= 3; *blue = (BYTE)readdisk(col,row); *green = (BYTE)readdisk(++col,row); *red = (BYTE)readdisk(col+1,row); } void writedisk(unsigned int col, unsigned int row, unsigned int color) { int col_subscr; long offset; char buf[41]; if (--timetodisplay < 0) { /* time to display status? */ if (dotmode == 11) { sprintf(buf," writing line %4d", (row >= (unsigned int)sydots) ? row-sydots : row); /* adjust when potfile */ dvid_status(0,buf); } timetodisplay = 1000; } if (row != (unsigned int)cur_row) { /* try to avoid ghastly code generated for multiply */ if (row >= colsize) /* while we're at it avoid this test if not needed */ return; cur_row_base = (long)(cur_row = row) * rowsize; } if (col >= rowsize) return; offset = cur_row_base + col; col_subscr = (short)offset & (BLOCKLEN-1); if (cur_offset != (offset & (0L-BLOCKLEN))) /* same entry as last ref? */ findload_cache(offset & (0L-BLOCKLEN)); if (cur_cache->pixel[col_subscr] != (color & 0xff)) { cur_cache->pixel[col_subscr] = (BYTE)color; cur_cache->dirty = 1; } } int ToMemDisk(long offset, int size, void far *src) { int col_subscr = (int)(offset & (BLOCKLEN - 1)); if (col_subscr + size > BLOCKLEN) /* access violates a */ return 0; /* cache boundary */ if (cur_offset != (offset & (0L-BLOCKLEN))) /* same entry as last ref? */ findload_cache (offset & (0L-BLOCKLEN)); far_memcpy((void far *) &cur_cache->pixel[col_subscr], src, size); cur_cache->dirty = 1; return 1; } void targa_writedisk(unsigned int col, unsigned int row, BYTE red, BYTE green, BYTE blue) { writedisk(col*=3,row,blue); writedisk(++col, row,green); writedisk(col+1, row,red); } static void _fastcall near findload_cache(long offset) /* used by read/write */ { #ifndef XFRACT unsigned int tbloffset; int i,j; unsigned int far *fwd_link; BYTE far *pixelptr; BYTE tmpchar; cur_offset = offset; /* note this for next reference */ /* check if required entry is in cache - lookup by hash */ tbloffset = hash_ptr[ ((unsigned short)offset >> BLOCKSHIFT) & (HASHSIZE-1) ]; while (tbloffset != 0xffff) { /* follow the hash chain */ cur_cache = (struct cache far *)((char far *)cache_start + tbloffset); if (cur_cache->offset == offset) { /* great, it is in the cache */ cur_cache->lru = 1; return; } tbloffset = cur_cache->hashlink; } /* must load the cache entry from backing store */ for(;;) { /* look around for something not recently used */ if (++cache_lru >= cache_end) cache_lru = cache_start; if (cache_lru->lru == 0) break; cache_lru->lru = 0; } if (cache_lru->dirty) /* must write this block before reusing it */ write_cache_lru(); /* remove block at cache_lru from its hash chain */ fwd_link = hash_ptr + (((unsigned short)cache_lru->offset >> BLOCKSHIFT) & (HASHSIZE-1)); tbloffset = (char far *)cache_lru - (char far *)cache_start; while (*fwd_link != tbloffset) fwd_link = &((struct cache far *)((char far *)cache_start+*fwd_link))->hashlink; *fwd_link = cache_lru->hashlink; /* load block */ cache_lru->dirty = 0; cache_lru->lru = 1; cache_lru->offset = offset; pixelptr = &cache_lru->pixel[0]; if (offset > high_offset) { /* never been this high before, just clear it */ high_offset = offset; for (i = 0; i < BLOCKLEN; ++i) *(pixelptr++) = 0; } else { if (offset != seek_offset) mem_seek(offset >> pixelshift); seek_offset = offset + BLOCKLEN; switch (pixelshift) { case 0: for (i = 0; i < BLOCKLEN; ++i) *(pixelptr++) = mem_getc(); break; case 1: for (i = 0; i < BLOCKLEN/2; ++i) { tmpchar = mem_getc(); *(pixelptr++) = (BYTE)(tmpchar >> 4); *(pixelptr++) = (BYTE)(tmpchar & 15); } break; case 2: for (i = 0; i < BLOCKLEN/4; ++i) { tmpchar = mem_getc(); for (j = 6; j >= 0; j -= 2) *(pixelptr++) = (BYTE)((tmpchar >> j) & 3); } break; case 3: for (i = 0; i < BLOCKLEN/8; ++i) { tmpchar = mem_getc(); for (j = 7; j >= 0; --j) *(pixelptr++) = (BYTE)((tmpchar >> j) & 1); } break; } } /* add new block to its hash chain */ fwd_link = hash_ptr + (((unsigned short)offset >> BLOCKSHIFT) & (HASHSIZE-1)); cache_lru->hashlink = *fwd_link; *fwd_link = (char far *)cache_lru - (char far *)cache_start; cur_cache = cache_lru; #endif } static struct cache far * _fastcall near find_cache(long offset) /* lookup for write_cache_lru */ { #ifndef XFRACT unsigned int tbloffset; struct cache far *ptr1; tbloffset = hash_ptr[ ((unsigned short)offset >> BLOCKSHIFT) & (HASHSIZE-1) ]; while (tbloffset != 0xffff) { ptr1 = (struct cache far *)((char far *)cache_start + tbloffset); if (ptr1->offset == offset) return (ptr1); tbloffset = ptr1->hashlink; } return (NULL); #endif } static void near write_cache_lru() { int i,j; BYTE far *pixelptr; long offset; BYTE tmpchar = 0; struct cache far *ptr1, far *ptr2; #define WRITEGAP 4 /* 1 for no gaps */ /* scan back to also write any preceding dirty blocks, skipping small gaps */ ptr1 = cache_lru; offset = ptr1->offset; i = 0; while (++i <= WRITEGAP) { if ((ptr2 = find_cache(offset -= BLOCKLEN)) != NULL && ptr2->dirty) { ptr1 = ptr2; i = 0; } } /* write all consecutive dirty blocks (often whole cache in 1pass modes) */ /* keep going past small gaps */ write_seek: mem_seek(ptr1->offset >> pixelshift); write_stuff: pixelptr = &ptr1->pixel[0]; switch (pixelshift) { case 0: for (i = 0; i < BLOCKLEN; ++i) mem_putc(*(pixelptr++)); break; case 1: for (i = 0; i < BLOCKLEN/2; ++i) { tmpchar = (BYTE)(*(pixelptr++) << 4); tmpchar = (BYTE)(tmpchar + *(pixelptr++)); mem_putc(tmpchar); } break; case 2: for (i = 0; i < BLOCKLEN/4; ++i) { for (j = 6; j >= 0; j -= 2) tmpchar = (BYTE)((tmpchar << 2) + *(pixelptr++)); mem_putc(tmpchar); } break; case 3: for (i = 0; i < BLOCKLEN/8; ++i) { mem_putc((BYTE) ((((((((((((((*pixelptr << 1) | *(pixelptr+1) ) << 1) | *(pixelptr+2) ) << 1) | *(pixelptr+3) ) << 1) | *(pixelptr+4) ) << 1) | *(pixelptr+5) ) << 1) | *(pixelptr+6) ) << 1) | *(pixelptr+7))); pixelptr += 8; } break; } ptr1->dirty = 0; offset = ptr1->offset + BLOCKLEN; if ((ptr1 = find_cache(offset)) != NULL && ptr1->dirty != 0) goto write_stuff; i = 1; while (++i <= WRITEGAP) { if ((ptr1 = find_cache(offset += BLOCKLEN)) != NULL && ptr1->dirty != 0) goto write_seek; } seek_offset = -1; /* force a seek before next read */ } /* Seek, mem_getc, mem_putc routines follow. Note that the calling logic always separates mem_getc and mem_putc sequences with a seek between them. A mem_getc is never followed by a mem_putc nor v.v. without a seek between them. */ static void _fastcall near mem_seek(long offset) /* mem seek */ { offset += headerlength; memoffset = offset >> BLOCKSHIFT; if (memoffset != oldmemoffset) { MoveToMemory(membuf, (U16)BLOCKLEN, 1L, oldmemoffset, dv_handle); MoveFromMemory(membuf, (U16)BLOCKLEN, 1L, memoffset, dv_handle); } oldmemoffset = memoffset; membufptr = membuf + (offset & (BLOCKLEN - 1)); } static BYTE near mem_getc() /* memory get_char */ { if (membufptr - membuf >= BLOCKLEN) { MoveToMemory(membuf, (U16)BLOCKLEN, 1L, memoffset, dv_handle); memoffset++; MoveFromMemory(membuf, (U16)BLOCKLEN, 1L, memoffset, dv_handle); membufptr = membuf; oldmemoffset = memoffset; } return (*(membufptr++)); } static void _fastcall near mem_putc(BYTE c) /* memory get_char */ { if (membufptr - membuf >= BLOCKLEN) { MoveToMemory(membuf, (U16)BLOCKLEN, 1L, memoffset, dv_handle); memoffset++; MoveFromMemory(membuf, (U16)BLOCKLEN, 1L, memoffset, dv_handle); membufptr = membuf; oldmemoffset = memoffset; } *(membufptr++) = c; } void dvid_status(int line,char far *msg) { char buf[41]; int attrib; memset(buf,' ',40); far_memcpy(buf,msg,far_strlen(msg)); buf[40] = 0; attrib = C_DVID_HI; if (line >= 100) { line -= 100; attrib = C_STOP_ERR; } putstring(BOXROW+10+line,BOXCOL+12,attrib,buf); movecursor(25,80); } xfractint-20.4.10.orig/common/miscfrac.c0000644000000000000000000021230710532116313014730 0ustar /* Miscellaneous fractal-specific code (formerly in CALCFRAC.C) */ #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "targa_lc.h" /* routines in this module */ static void set_Plasma_palette(void); static U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb); static void _fastcall subDivide(int x1,int y1,int x2,int y2); static int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur); static void verhulst(void); static void Bif_Period_Init(void); static int _fastcall Bif_Periodic(long); static void set_Cellular_palette(void); U16 (_fastcall *getpix)(int,int) = (U16(_fastcall *)(int,int))getcolor; typedef void (_fastcall *PLOT)(int,int,int); /***************** standalone engine for "test" ********************/ int test(void) { int startrow,startpass,numpasses; startrow = startpass = 0; if (resuming) { start_resume(); get_resume(sizeof(startrow),&startrow,sizeof(startpass),&startpass,0); end_resume(); } if(teststart()) /* assume it was stand-alone, doesn't want passes logic */ return(0); numpasses = (stdcalcmode == '1') ? 0 : 1; for (passes=startpass; passes <= numpasses ; passes++) { for (row = startrow; row <= iystop; row=row+1+numpasses) { for (col = 0; col <= ixstop; col++) /* look at each point on screen */ { register int color; init.x = dxpixel(); init.y = dypixel(); if(keypressed()) { testend(); alloc_resume(20,1); put_resume(sizeof(row),&row,sizeof(passes),&passes,0); return(-1); } color = testpt(init.x,init.y,parm.x,parm.y,maxit,inside); if (color >= colors) { /* avoid trouble if color is 0 */ if (colors < 16) color &= andcolor; else color = ((color-1) % andcolor) + 1; /* skip color zero */ } (*plot)(col,row,color); if(numpasses && (passes == 0)) (*plot)(col,row+1,color); } } startrow = passes + 1; } testend(); return(0); } /***************** standalone engine for "plasma" ********************/ static int iparmx; /* iparmx = parm.x * 8 */ static int shiftvalue; /* shift based on #colors */ static int recur1=1; static int pcolors; static int recur_level = 0; U16 max_plasma; /* returns a random 16 bit value that is never 0 */ U16 rand16(void) { U16 value; value = (U16)rand15(); value <<= 1; value = (U16)(value + (rand15()&1)); if(value < 1) value = 1; return(value); } void _fastcall putpot(int x, int y, U16 color) { if(color < 1) color = 1; putcolor(x, y, color >> 8 ? color >> 8 : 1); /* don't write 0 */ /* we don't write this if dotmode==11 because the above putcolor was already a "writedisk" in that case */ if (dotmode != 11) writedisk(x+sxoffs,y+syoffs,color >> 8); /* upper 8 bits */ writedisk(x+sxoffs,y+sydots+syoffs,color&255); /* lower 8 bits */ } /* fixes border */ void _fastcall putpotborder(int x, int y, U16 color) { if((x==0) || (y==0) || (x==xdots-1) || (y==ydots-1)) color = (U16)outside; putpot(x,y,color); } /* fixes border */ void _fastcall putcolorborder(int x, int y, int color) { if((x==0) || (y==0) || (x==xdots-1) || (y==ydots-1)) color = outside; if(color < 1) color = 1; putcolor(x,y,color); } U16 _fastcall getpot(int x, int y) { U16 color; color = (U16)readdisk(x+sxoffs,y+syoffs); color = (U16)((color << 8) + (U16) readdisk(x+sxoffs,y+sydots+syoffs)); return(color); } static int plasma_check; /* to limit kbd checking */ static U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb) { S32 pseudorandom; pseudorandom = ((S32)iparmx)*((rand15()-16383)); /* pseudorandom = pseudorandom*(abs(xa-xb)+abs(ya-yb));*/ pseudorandom = pseudorandom * recur1; pseudorandom = pseudorandom >> shiftvalue; pseudorandom = (((S32)getpix(xa,ya)+(S32)getpix(xb,yb)+1)>>1)+pseudorandom; if(max_plasma == 0) { if (pseudorandom >= pcolors) pseudorandom = pcolors-1; } else if (pseudorandom >= (S32)max_plasma) pseudorandom = max_plasma; if(pseudorandom < 1) pseudorandom = 1; plot(x,y,(U16)pseudorandom); return((U16)pseudorandom); } static int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur) { int x,y; int nx1; int nx; int ny1, ny; S32 i, v; struct sub { BYTE t; /* top of stack */ int v[16]; /* subdivided value */ BYTE r[16]; /* recursion level */ }; static struct sub subx, suby; /* recur1=1; for (i=1;i<=recur;i++) recur1 = recur1 * 2; recur1=320/recur1; */ recur1 = (int)(320L >> recur); suby.t = 2; ny = suby.v[0] = y2; ny1 = suby.v[2] = y1; suby.r[0] = suby.r[2] = 0; suby.r[1] = 1; y = suby.v[1] = (ny1 + ny) >> 1; while (suby.t >= 1) { if ((++plasma_check & 0x0f) == 1) if(keypressed()) { plasma_check--; return(1); } while (suby.r[suby.t-1] < (BYTE)recur) { /* 1. Create new entry at top of the stack */ /* 2. Copy old top value to new top value. */ /* This is largest y value. */ /* 3. Smallest y is now old mid point */ /* 4. Set new mid point recursion level */ /* 5. New mid point value is average */ /* of largest and smallest */ suby.t++; ny1 = suby.v[suby.t] = suby.v[suby.t-1]; ny = suby.v[suby.t-2]; suby.r[suby.t] = suby.r[suby.t-1]; y = suby.v[suby.t-1] = (ny1 + ny) >> 1; suby.r[suby.t-1] = (BYTE)(max(suby.r[suby.t], suby.r[suby.t-2])+1); } subx.t = 2; nx = subx.v[0] = x2; nx1 = subx.v[2] = x1; subx.r[0] = subx.r[2] = 0; subx.r[1] = 1; x = subx.v[1] = (nx1 + nx) >> 1; while (subx.t >= 1) { while (subx.r[subx.t-1] < (BYTE)recur) { subx.t++; /* move the top ofthe stack up 1 */ nx1 = subx.v[subx.t] = subx.v[subx.t-1]; nx = subx.v[subx.t-2]; subx.r[subx.t] = subx.r[subx.t-1]; x = subx.v[subx.t-1] = (nx1 + nx) >> 1; subx.r[subx.t-1] = (BYTE)(max(subx.r[subx.t], subx.r[subx.t-2])+1); } if ((i = getpix(nx, y)) == 0) i = adjust(nx,ny1,nx,y ,nx,ny); v = i; if ((i = getpix(x, ny)) == 0) i = adjust(nx1,ny,x ,ny,nx,ny); v += i; if(getpix(x,y) == 0) { if ((i = getpix(x, ny1)) == 0) i = adjust(nx1,ny1,x ,ny1,nx,ny1); v += i; if ((i = getpix(nx1, y)) == 0) i = adjust(nx1,ny1,nx1,y ,nx1,ny); v += i; plot(x,y,(U16)((v + 2) >> 2)); } if (subx.r[subx.t-1] == (BYTE)recur) subx.t = (BYTE)(subx.t - 2); } if (suby.r[suby.t-1] == (BYTE)recur) suby.t = (BYTE)(suby.t - 2); } return(0); } static void _fastcall subDivide(int x1,int y1,int x2,int y2) { int x,y; S32 v,i; if ((++plasma_check & 0x7f) == 1) if(keypressed()) { plasma_check--; return; } if(x2-x1<2 && y2-y1<2) return; recur_level++; recur1 = (int)(320L >> recur_level); x = (x1+x2)>>1; y = (y1+y2)>>1; if((v=getpix(x,y1)) == 0) v=adjust(x1,y1,x ,y1,x2,y1); i=v; if((v=getpix(x2,y)) == 0) v=adjust(x2,y1,x2,y ,x2,y2); i+=v; if((v=getpix(x,y2)) == 0) v=adjust(x1,y2,x ,y2,x2,y2); i+=v; if((v=getpix(x1,y)) == 0) v=adjust(x1,y1,x1,y ,x1,y2); i+=v; if(getpix(x,y) == 0) plot(x,y,(U16)((i+2)>>2)); subDivide(x1,y1,x ,y); subDivide(x ,y1,x2,y); subDivide(x ,y ,x2,y2); subDivide(x1,y ,x ,y2); recur_level--; } int plasma() { int i,k, n; U16 rnd[4]; int OldPotFlag, OldPot16bit; OldPotFlag=OldPot16bit=plasma_check = 0; if(colors < 4) { static FCODE plasmamsg[]={ "\ Plasma Clouds can currently only be run in a 4-or-more-color video\n\ mode (and color-cycled only on VGA adapters [or EGA adapters in their\n\ 640x350x16 mode])." }; stopmsg(0,plasmamsg); return(-1); } iparmx = (int)(param[0] * 8); if (parm.x <= 0.0) iparmx = 0; if (parm.x >= 100) iparmx = 800; param[0] = (double)iparmx / 8.0; /* let user know what was used */ if (param[1] < 0) param[1] = 0; /* limit parameter values */ if (param[1] > 1) param[1] = 1; if (param[2] < 0) param[2] = 0; /* limit parameter values */ if (param[2] > 1) param[2] = 1; if (param[3] < 0) param[3] = 0; /* limit parameter values */ if (param[3] > 1) param[3] = 1; if ((!rflag) && param[2] == 1) --rseed; if (param[2] != 0 && param[2] != 1) rseed = (int)param[2]; max_plasma = (U16)param[3]; /* max_plasma is used as a flag for potential */ if(max_plasma != 0) { if (pot_startdisk() >= 0) { /* max_plasma = (U16)(1L << 16) -1; */ max_plasma = 0xFFFF; if(outside >= 0) plot = (PLOT)putpotborder; else plot = (PLOT)putpot; getpix = getpot; OldPotFlag = potflag; OldPot16bit = pot16bit; } else { max_plasma = 0; /* can't do potential (startdisk failed) */ param[3] = 0; if(outside >= 0) plot = putcolorborder; else plot = putcolor; getpix = (U16(_fastcall *)(int,int))getcolor; } } else { if(outside >= 0) plot = putcolorborder; else plot = putcolor; getpix = (U16(_fastcall *)(int,int))getcolor; } srand(rseed); if (!rflag) ++rseed; if (colors == 256) /* set the (256-color) palette */ set_Plasma_palette(); /* skip this if < 256 colors */ if (colors > 16) shiftvalue = 18; else { if (colors > 4) shiftvalue = 22; else { if (colors > 2) shiftvalue = 24; else shiftvalue = 25; } } if(max_plasma != 0) shiftvalue = 10; if(max_plasma == 0) { pcolors = min(colors, max_colors); for(n = 0; n < 4; n++) rnd[n] = (U16)(1+(((rand15()/pcolors)*(pcolors-1))>>(shiftvalue-11))); } else for(n = 0; n < 4; n++) rnd[n] = rand16(); if(debugflag==3600) for(n = 0; n < 4; n++) rnd[n] = 1; plot( 0, 0, rnd[0]); plot(xdots-1, 0, rnd[1]); plot(xdots-1,ydots-1, rnd[2]); plot( 0,ydots-1, rnd[3]); recur_level = 0; if (param[1] == 0) subDivide(0,0,xdots-1,ydots-1); else { recur1 = i = k = 1; while(new_subD(0,0,xdots-1,ydots-1,i)==0) { k = k * 2; if (k >(int)max(xdots-1,ydots-1)) break; if (keypressed()) { n = 1; goto done; } i++; } } if (! keypressed()) n = 0; else n = 1; done: if(max_plasma != 0) { potflag = OldPotFlag; pot16bit = OldPot16bit; } plot = putcolor; getpix = (U16(_fastcall *)(int,int))getcolor; return(n); } #define dac ((Palettetype *)dacbox) static void set_Plasma_palette() { static Palettetype Red = { 63, 0, 0 }; static Palettetype Green = { 0, 63, 0 }; static Palettetype Blue = { 0, 0,63 }; int i; if (mapdacbox || colorpreloaded) return; /* map= specified */ dac[0].red = 0 ; dac[0].green= 0 ; dac[0].blue = 0 ; for(i=1;i<=85;i++) { #ifdef __SVR4 dac[i].red = (BYTE)((i*(int)Green.red + (86-i)*(int)Blue.red)/85); dac[i].green = (BYTE)((i*(int)Green.green + (86-i)*(int)Blue.green)/85); dac[i].blue = (BYTE)((i*(int)Green.blue + (86-i)*(int)Blue.blue)/85); dac[i+85].red = (BYTE)((i*(int)Red.red + (86-i)*(int)Green.red)/85); dac[i+85].green = (BYTE)((i*(int)Red.green + (86-i)*(int)Green.green)/85); dac[i+85].blue = (BYTE)((i*(int)Red.blue + (86-i)*(int)Green.blue)/85); dac[i+170].red = (BYTE)((i*(int)Blue.red + (86-i)*(int)Red.red)/85); dac[i+170].green = (BYTE)((i*(int)Blue.green + (86-i)*(int)Red.green)/85); dac[i+170].blue = (BYTE)((i*(int)Blue.blue + (86-i)*(int)Red.blue)/85); #else dac[i].red = (BYTE)((i*Green.red + (86-i)*Blue.red)/85); dac[i].green = (BYTE)((i*Green.green + (86-i)*Blue.green)/85); dac[i].blue = (BYTE)((i*Green.blue + (86-i)*Blue.blue)/85); dac[i+85].red = (BYTE)((i*Red.red + (86-i)*Green.red)/85); dac[i+85].green = (BYTE)((i*Red.green + (86-i)*Green.green)/85); dac[i+85].blue = (BYTE)((i*Red.blue + (86-i)*Green.blue)/85); dac[i+170].red = (BYTE)((i*Blue.red + (86-i)*Red.red)/85); dac[i+170].green = (BYTE)((i*Blue.green + (86-i)*Red.green)/85); dac[i+170].blue = (BYTE)((i*Blue.blue + (86-i)*Red.blue)/85); #endif } SetTgaColors(); /* TARGA 3 June 89 j mclain */ spindac(0,1); } /***************** standalone engine for "diffusion" ********************/ #define RANDOM(x) (rand()%(x)) int diffusion() { int xmax,ymax,xmin,ymin; /* Current maximum coordinates */ int border; /* Distance between release point and fractal */ int mode; /* Determines diffusion type: 0 = central (classic) */ /* 1 = falling particles */ /* 2 = square cavity */ int colorshift; /* If zero, select colors at random, otherwise shift */ /* the color every colorshift points */ int colorcount,currentcolor; int i; double cosine,sine,angle; int x,y; float r, radius; if (diskvideo) notdiskmsg(); x = y = -1; bitshift = 16; fudge = 1L << 16; border = (int)param[0]; mode = (int)param[1]; colorshift = (int)param[2]; colorcount = colorshift; /* Counts down from colorshift */ currentcolor = 1; /* Start at color 1 (color 0 is probably invisible)*/ if (mode > 2) mode=0; if (border <= 0) border = 10; srand(rseed); if (!rflag) ++rseed; if (mode == 0) { xmax = xdots / 2 + border; /* Initial box */ xmin = xdots / 2 - border; ymax = ydots / 2 + border; ymin = ydots / 2 - border; } if (mode == 1) { xmax = xdots / 2 + border; /* Initial box */ xmin = xdots / 2 - border; ymin = ydots - border; } if (mode == 2) { if (xdots > ydots) radius = ydots - border; else radius = xdots - border; } if (resuming) /* restore worklist, if we can't the above will stay in place */ { start_resume(); if (mode != 2) get_resume(sizeof(xmax),&xmax,sizeof(xmin),&xmin,sizeof(ymax),&ymax, sizeof(ymin),&ymin,0); else get_resume(sizeof(xmax),&xmax,sizeof(xmin),&xmin,sizeof(ymax),&ymax, sizeof(radius),&radius,0); end_resume(); } switch (mode) { case 0: /* Single seed point in the center */ putcolor(xdots / 2, ydots / 2,currentcolor); break; case 1: /* Line along the bottom */ for (i=0;i<=xdots;i++) putcolor(i,ydots-1,currentcolor); break; case 2: /* Large square that fills the screen */ if (xdots > ydots) for (i=0;i> 1; /* divide by 2 */ y = y >> 1; break; case 1: /* Release new point on the line ymin somewhere between xmin and xmax */ y=ymin; x=RANDOM(xmax-xmin) + (xdots-xmax+xmin)/2; break; case 2: /* Release new point on a circle inside the box with radius given by the radius variable */ angle=2*(double)rand()/(RAND_MAX/PI); FPUsincos(&angle,&sine,&cosine); x = (int)(cosine*radius + xdots); y = (int)(sine *radius + ydots); x = x >> 1; y = y >> 1; break; } /* Loop as long as the point (x,y) is surrounded by color 0 */ /* on all eight sides */ while((getcolor(x+1,y+1) == 0) && (getcolor(x+1,y) == 0) && (getcolor(x+1,y-1) == 0) && (getcolor(x ,y+1) == 0) && (getcolor(x ,y-1) == 0) && (getcolor(x-1,y+1) == 0) && (getcolor(x-1,y) == 0) && (getcolor(x-1,y-1) == 0)) { /* Erase moving point */ if (show_orbit) putcolor(x,y,0); if (mode==0){ /* Make sure point is inside the box */ if (x==xmax) x--; else if (x==xmin) x++; if (y==ymax) y--; else if (y==ymin) y++; } if (mode==1) /* Make sure point is on the screen below ymin, but we need a 1 pixel margin because of the next random step.*/ { if (x>=xdots-1) x--; else if (x<=1) x++; if (yxmax) || ((x-border)ymax)) { /* Increase box size, but not past the edge of the screen */ ymin--; ymax++; xmin--; xmax++; if ((ymin==0) || (xmin==0)) return 0; } break; case 1: /* Decrease ymin, but not past top of screen */ if (y-border < ymin) ymin--; if (ymin==0) return 0; break; case 2: /* Decrease the radius where points are released to stay away from the fractal. It might be decreased by 1 or 2 */ r = sqr((float)x-xdots/2) + sqr((float)y-ydots/2); if (r<=border*border) return 0; while ((radius-border)*(radius-border) > r) radius--; break; } } } /************ standalone engine for "bifurcation" types ***************/ /***************************************************************/ /* The following code now forms a generalised Fractal Engine */ /* for Bifurcation fractal typeS. By rights it now belongs in */ /* CALCFRACT.C, but it's easier for me to leave it here ! */ /* Original code by Phil Wilson, hacked around by Kev Allen. */ /* Besides generalisation, enhancements include Periodicity */ /* Checking during the plotting phase (AND halfway through the */ /* filter cycle, if possible, to halve calc times), quicker */ /* floating-point calculations for the standard Verhulst type, */ /* and new bifurcation types (integer bifurcation, f.p & int */ /* biflambda - the real equivalent of complex Lambda sets - */ /* and f.p renditions of bifurcations of r*sin(Pi*p), which */ /* spurred Mitchel Feigenbaum on to discover his Number). */ /* To add further types, extend the fractalspecific[] array in */ /* usual way, with Bifurcation as the engine, and the name of */ /* the routine that calculates the next bifurcation generation */ /* as the "orbitcalc" routine in the fractalspecific[] entry. */ /* Bifurcation "orbitcalc" routines get called once per screen */ /* pixel column. They should calculate the next generation */ /* from the doubles Rate & Population (or the longs lRate & */ /* lPopulation if they use integer math), placing the result */ /* back in Population (or lPopulation). They should return 0 */ /* if all is ok, or any non-zero value if calculation bailout */ /* is desirable (eg in case of errors, or the series tending */ /* to infinity). Have fun ! */ /***************************************************************/ #define DEFAULTFILTER 1000 /* "Beauty of Fractals" recommends using 5000 (p.25), but that seems unnecessary. Can override this value with a nonzero param1 */ #define SEED 0.66 /* starting value for population */ static int far *verhulst_array; unsigned long filter_cycles; static unsigned int half_time_check; static long lPopulation, lRate; double Population, Rate; static int mono, outside_x; static long LPI; int Bifurcation(void) { unsigned long array_size; int row, column; column = 0; if (resuming) { start_resume(); get_resume(sizeof(column),&column,0); end_resume(); } array_size = (iystop + 1) * sizeof(int); /* should be iystop + 1 */ if ((verhulst_array = (int far *) farmemalloc(array_size)) == NULL) { static FCODE msg[]={"Insufficient free memory for calculation."}; stopmsg(0,msg); return(-1); } LPI = (long)(PI * fudge); for (row = 0; row <= iystop; row++) /* should be iystop */ verhulst_array[row] = 0; mono = 0; if (colors == 2) mono = 1; if (mono) { if (inside) { outside_x = 0; inside = 1; } else outside_x = 1; } filter_cycles = (parm.x <= 0) ? DEFAULTFILTER : (long)parm.x; half_time_check = FALSE; if (periodicitycheck && (unsigned long)maxit < filter_cycles) { filter_cycles = (filter_cycles - maxit + 1) / 2; half_time_check = TRUE; } if (integerfractal) linit.y = ymax - iystop*dely; /* Y-value of */ else init.y = (double)(yymax - iystop*delyy); /* bottom pixels */ while (column <= ixstop) { if(keypressed()) { farmemfree((char far *)verhulst_array); alloc_resume(10,1); put_resume(sizeof(column),&column,0); return(-1); } if (integerfractal) lRate = xmin + column*delx; else Rate = (double)(xxmin + column*delxx); verhulst(); /* calculate array once per column */ for (row = iystop; row >= 0; row--) /* should be iystop & >=0 */ { int color; color = verhulst_array[row]; if(color && mono) color = inside; else if((!color) && mono) color = outside_x; else if (color>=colors) color = colors-1; verhulst_array[row] = 0; (*plot)(column,row,color); /* was row-1, but that's not right? */ } column++; } farmemfree((char far *)verhulst_array); return(0); } static void verhulst() /* P. F. Verhulst (1845) */ { unsigned int pixel_row, errors; unsigned long counter; if (integerfractal) lPopulation = (parm.y == 0) ? (long)(SEED*fudge) : (long)(parm.y*fudge); else Population = (parm.y == 0 ) ? SEED : parm.y; errors = overflow = FALSE; for (counter=0 ; counter < filter_cycles ; counter++) { errors = curfractalspecific->orbitcalc(); if (errors) return; } if (half_time_check) /* check for periodicity at half-time */ { Bif_Period_Init(); for (counter=0 ; counter < (unsigned long)maxit ; counter++) { errors = curfractalspecific->orbitcalc(); if (errors) return; if (periodicitycheck && Bif_Periodic(counter)) break; } if (counter >= (unsigned long)maxit) /* if not periodic, go the distance */ { for (counter=0 ; counter < filter_cycles ; counter++) { errors = curfractalspecific->orbitcalc(); if (errors) return; } } } if (periodicitycheck) Bif_Period_Init(); for (counter=0 ; counter < (unsigned long)maxit ; counter++) { errors = curfractalspecific->orbitcalc(); if (errors) return; /* assign population value to Y coordinate in pixels */ if (integerfractal) pixel_row = iystop - (int)((lPopulation - linit.y) / dely); /* iystop */ else pixel_row = iystop - (int)((Population - init.y) / delyy); /* if it's visible on the screen, save it in the column array */ if (pixel_row <= (unsigned int)iystop) /* JCO 6/6/92 */ verhulst_array[ pixel_row ] ++; if (periodicitycheck && Bif_Periodic(counter)) { if (pixel_row <= (unsigned int)iystop) /* JCO 6/6/92 */ verhulst_array[ pixel_row ] --; break; } } } static long lBif_closenuf, lBif_savedpop; /* poss future use */ static double Bif_closenuf, Bif_savedpop; static int Bif_savedinc; static long Bif_savedand; static void Bif_Period_Init() { Bif_savedinc = 1; Bif_savedand = 1; if (integerfractal) { lBif_savedpop = -1; lBif_closenuf = dely / 8; } else { Bif_savedpop = -1.0; Bif_closenuf = (double)delyy / 8.0; } } static int _fastcall Bif_Periodic (long time) /* Bifurcation Population Periodicity Check */ /* Returns : 1 if periodicity found, else 0 */ { if ((time & Bif_savedand) == 0) /* time to save a new value */ { if (integerfractal) lBif_savedpop = lPopulation; else Bif_savedpop = Population; if (--Bif_savedinc == 0) { Bif_savedand = (Bif_savedand << 1) + 1; Bif_savedinc = 4; } } else /* check against an old save */ { if (integerfractal) { if (labs(lBif_savedpop-lPopulation) <= lBif_closenuf) return(1); } else { if (fabs(Bif_savedpop-Population) <= Bif_closenuf) return(1); } } return(0); } /**********************************************************************/ /* */ /* The following are Bifurcation "orbitcalc" routines... */ /* */ /**********************************************************************/ #ifdef XFRACT int BifurcLambda() /* Used by lyanupov */ { Population = Rate * Population * (1 - Population); return (fabs(Population) > BIG); } #endif /* Modified formulas below to generalize bifurcations. JCO 7/3/92 */ #define LCMPLXtrig0(arg,out) Arg1->l = (arg); ltrig0(); (out)=Arg1->l #define CMPLXtrig0(arg,out) Arg1->d = (arg); dtrig0(); (out)=Arg1->d int BifurcVerhulstTrig() { /* Population = Pop + Rate * fn(Pop) * (1 - fn(Pop)) */ tmp.x = Population; tmp.y = 0; CMPLXtrig0(tmp, tmp); Population += Rate * tmp.x * (1 - tmp.x); return (fabs(Population) > BIG); } int LongBifurcVerhulstTrig() { #ifndef XFRACT ltmp.x = lPopulation; ltmp.y = 0; LCMPLXtrig0(ltmp, ltmp); ltmp.y = ltmp.x - multiply(ltmp.x,ltmp.x,bitshift); lPopulation += multiply(lRate,ltmp.y,bitshift); #endif return (overflow); } int BifurcStewartTrig() { /* Population = (Rate * fn(Population) * fn(Population)) - 1.0 */ tmp.x = Population; tmp.y = 0; CMPLXtrig0(tmp, tmp); Population = (Rate * tmp.x * tmp.x) - 1.0; return (fabs(Population) > BIG); } int LongBifurcStewartTrig() { #ifndef XFRACT ltmp.x = lPopulation; ltmp.y = 0; LCMPLXtrig0(ltmp, ltmp); lPopulation = multiply(ltmp.x,ltmp.x,bitshift); lPopulation = multiply(lPopulation,lRate, bitshift); lPopulation -= fudge; #endif return (overflow); } int BifurcSetTrigPi() { tmp.x = Population * PI; tmp.y = 0; CMPLXtrig0(tmp, tmp); Population = Rate * tmp.x; return (fabs(Population) > BIG); } int LongBifurcSetTrigPi() { #ifndef XFRACT ltmp.x = multiply(lPopulation,LPI,bitshift); ltmp.y = 0; LCMPLXtrig0(ltmp, ltmp); lPopulation = multiply(lRate,ltmp.x,bitshift); #endif return (overflow); } int BifurcAddTrigPi() { tmp.x = Population * PI; tmp.y = 0; CMPLXtrig0(tmp, tmp); Population += Rate * tmp.x; return (fabs(Population) > BIG); } int LongBifurcAddTrigPi() { #ifndef XFRACT ltmp.x = multiply(lPopulation,LPI,bitshift); ltmp.y = 0; LCMPLXtrig0(ltmp, ltmp); lPopulation += multiply(lRate,ltmp.x,bitshift); #endif return (overflow); } int BifurcLambdaTrig() { /* Population = Rate * fn(Population) * (1 - fn(Population)) */ tmp.x = Population; tmp.y = 0; CMPLXtrig0(tmp, tmp); Population = Rate * tmp.x * (1 - tmp.x); return (fabs(Population) > BIG); } int LongBifurcLambdaTrig() { #ifndef XFRACT ltmp.x = lPopulation; ltmp.y = 0; LCMPLXtrig0(ltmp, ltmp); ltmp.y = ltmp.x - multiply(ltmp.x,ltmp.x,bitshift); lPopulation = multiply(lRate,ltmp.y,bitshift); #endif return (overflow); } #define LCMPLXpwr(arg1,arg2,out) Arg2->l = (arg1); Arg1->l = (arg2);\ lStkPwr(); Arg1++; Arg2++; (out) = Arg2->l long beta; int BifurcMay() { /* X = (lambda * X) / (1 + X)^beta, from R.May as described in Pickover, Computers, Pattern, Chaos, and Beauty, page 153 */ tmp.x = 1.0 + Population; tmp.x = pow(tmp.x, -beta); /* pow in math.h included with mpmath.h */ Population = (Rate * Population) * tmp.x; return (fabs(Population) > BIG); } int LongBifurcMay() { #ifndef XFRACT ltmp.x = lPopulation + fudge; ltmp.y = 0; lparm2.x = beta * fudge; LCMPLXpwr(ltmp, lparm2, ltmp); lPopulation = multiply(lRate,lPopulation,bitshift); lPopulation = divide(lPopulation,ltmp.x,bitshift); #endif return (overflow); } int BifurcMaySetup() { beta = (long)param[2]; if(beta < 2) beta = 2; param[2] = (double)beta; timer(0,curfractalspecific->calctype); return(0); } /* Here Endeth the Generalised Bifurcation Fractal Engine */ /* END Phil Wilson's Code (modified slightly by Kev Allen et. al. !) */ /******************* standalone engine for "popcorn" ********************/ int popcorn() /* subset of std engine */ { int start_row; start_row = 0; if (resuming) { start_resume(); get_resume(sizeof(start_row),&start_row,0); end_resume(); } kbdcount=max_kbdcount; plot = noplot; tempsqrx = ltempsqrx = 0; /* PB added this to cover weird BAILOUTs */ for (row = start_row; row <= iystop; row++) { reset_periodicity = 1; for (col = 0; col <= ixstop; col++) { if (StandardFractal() == -1) /* interrupted */ { alloc_resume(10,1); put_resume(sizeof(row),&row,0); return(-1); } reset_periodicity = 0; } } calc_status = 4; return(0); } /******************* standalone engine for "lyapunov" *********************/ /*** Roy Murphy [76376,721] ***/ /*** revision history: ***/ /*** initial version: Winter '91 ***/ /*** Fall '92 integration of Nicholas Wilt's ASM speedups ***/ /*** Jan 93' integration with calcfrac() yielding boundary tracing, ***/ /*** tesseral, and solid guessing, and inversion, inside=nnn ***/ /*** save_release behavior: ***/ /*** 1730 & prior: ignores inside=, calcmode='1', (a,b)->(x,y) ***/ /*** 1731: other calcmodes and inside=nnn ***/ /*** 1732: the infamous axis swap: (b,a)->(x,y), ***/ /*** the order parameter becomes a long int ***/ /**************************************************************************/ int lyaLength, lyaSeedOK; int lyaRxy[34]; #define WES 1 /* define WES to be 0 to use Nick's lyapunov.obj */ #if WES int lyapunov_cycles(double, double); #else int lyapunov_cycles(int, double, double, double); #endif int lyapunov_cycles_in_c(long, double, double); int lyapunov () { double a, b; if (keypressed()) { return -1; } overflow=FALSE; if (param[1]==1) Population = (1.0+rand())/(2.0+RAND_MAX); else if (param[1]==0) { if (fabs(Population)>BIG || Population==0 || Population==1) Population = (1.0+rand())/(2.0+RAND_MAX); } else Population = param[1]; (*plot)(col, row, 1); if (invert) { invertz2(&init); a = init.y; b = init.x; } else { a = dypixel(); b = dxpixel(); } #ifndef XFRACT /* the assembler routines don't work for a & b outside the ranges 0 < a < 4 and 0 < b < 4. So, fall back on the C routines if part of the image sticks out. */ #if WES color=lyapunov_cycles(a, b); #else if (lyaSeedOK && a>0 && b>0 && a<=4 && b<=4) color=lyapunov_cycles(filter_cycles, Population, a, b); else color=lyapunov_cycles_in_c(filter_cycles, a, b); #endif #else color=lyapunov_cycles_in_c(filter_cycles, a, b); #endif if (inside>0 && color==0) color = inside; else if (color>=colors) color = colors-1; (*plot)(col, row, color); return color; } int lya_setup () { /* This routine sets up the sequence for forcing the Rate parameter to vary between the two values. It fills the array lyaRxy[] and sets lyaLength to the length of the sequence. The sequence is coded in the bit pattern in an integer. Briefly, the sequence starts with an A the leading zero bits are ignored and the remaining bit sequence is decoded. The sequence ends with a B. Not all possible sequences can be represented in this manner, but every possible sequence is either represented as itself, as a rotation of one of the representable sequences, or as the inverse of a representable sequence (swapping 0s and 1s in the array.) Sequences that are the rotation and/or inverses of another sequence will generate the same lyapunov exponents. A few examples follow: number sequence 0 ab 1 aab 2 aabb 3 aaab 4 aabbb 5 aabab 6 aaabb (this is a duplicate of 4, a rotated inverse) 7 aaaab 8 aabbbb etc. */ long i; int t; if ((filter_cycles=(long)param[2])==0) filter_cycles=maxit/2; lyaSeedOK = param[1]>0 && param[1]<=1 && debugflag!=90; lyaLength = 1; i = (long)param[0]; #ifndef XFRACT if (save_release<1732) i &= 0x0FFFFL; /* make it a short to reporduce prior stuff*/ #endif lyaRxy[0] = 1; for (t=31; t>=0; t--) if (i & (1<=0; t--) lyaRxy[lyaLength++] = (i & (1<=0; t--) lyaRxy[t] = !lyaRxy[t]; if (save_release<1731) { /* ignore inside=, stdcalcmode */ stdcalcmode='1'; if (inside==1) inside = 0; } if (inside<0) { static FCODE msg[]= {"Sorry, inside options other than inside=nnn are not supported by the lyapunov"}; stopmsg(0,(char far *)msg); inside=1; } if (usr_stdcalcmode == 'o') { /* Oops,lyapunov type */ usr_stdcalcmode = '1'; /* doesn't use new & breaks orbits */ stdcalcmode = '1'; } return 1; } int lyapunov_cycles_in_c(long filter_cycles, double a, double b) { int color, count, lnadjust; long i; double lyap, total, temp; /* e10=22026.4657948 e-10=0.0000453999297625 */ total = 1.0; lnadjust = 0; for (i=0; iorbitcalc()) { overflow = TRUE; goto jumpout; } } } for (i=0; i < maxit/2; i++) { for (count = 0; count < lyaLength; count++) { Rate = lyaRxy[count] ? a : b; if (curfractalspecific->orbitcalc()) { overflow = TRUE; goto jumpout; } temp = fabs(Rate-2.0*Rate*Population); if ((total *= (temp))==0) { overflow = TRUE; goto jumpout; } } while (total > 22026.4657948) { total *= 0.0000453999297625; lnadjust += 10; } while (total < 0.0000453999297625) { total *= 22026.4657948; lnadjust -= 10; } } jumpout: if (overflow || total <= 0 || (temp = log(total) + lnadjust) > 0) color = 0; else { if (LogFlag) lyap = -temp/((double) lyaLength*i); else lyap = 1 - exp(temp/((double) lyaLength*i)); color = 1 + (int)(lyap * (colors-1)); } return color; } /******************* standalone engine for "cellular" ********************/ /* Originally coded by Ken Shirriff. Modified beyond recognition by Jonathan Osuch. Original or'd the neighborhood, changed to sum the neighborhood Changed prompts and error messages Added CA types Set the palette to some standard? CA colors Changed *cell_array to near and used dstack so put_line and get_line could be used all the time Made space bar generate next screen Increased string/rule size to 16 digits and added CA types 9/20/92 */ #define BAD_T 1 #define BAD_MEM 2 #define STRING1 3 #define STRING2 4 #define TABLEK 5 #define TYPEKR 6 #define RULELENGTH 7 #define INTERUPT 8 #define CELLULAR_DONE 10 #ifndef XFRACT static BYTE *cell_array[2]; #else static BYTE far *cell_array[2]; #endif S16 r, k_1, rule_digits; int lstscreenflag; void abort_cellular(int err, int t) { int i; switch (err) { case BAD_T: { char msg[30]; sprintf(msg,"Bad t=%d, aborting\n", t); stopmsg(0,(char far *)msg); } break; case BAD_MEM: { static FCODE msg[]={"Insufficient free memory for calculation" }; stopmsg(0,msg); } break; case STRING1: { static FCODE msg[]={"String can be a maximum of 16 digits" }; stopmsg(0,msg); } break; case STRING2: { static FCODE msg[]={"Make string of 0's through 's" }; msg[27] = (char)(k_1 + 48); /* turn into a character value */ stopmsg(0,msg); } break; case TABLEK: { static FCODE msg[]={"Make Rule with 0's through 's" }; msg[27] = (char)(k_1 + 48); /* turn into a character value */ stopmsg(0,msg); } break; case TYPEKR: { static FCODE msg[]={"Type must be 21, 31, 41, 51, 61, 22, 32, \ 42, 23, 33, 24, 25, 26, 27" }; stopmsg(0,msg); } break; case RULELENGTH: { static FCODE msg[]={"Rule must be digits long" }; i = rule_digits / 10; if(i==0) msg[14] = (char)(rule_digits + 48); else { msg[13] = (char)(i+48); msg[14] = (char)((rule_digits % 10) + 48); } stopmsg(0,msg); } break; case INTERUPT: { static FCODE msg[]={"Interrupted, can't resume" }; stopmsg(0,msg); } break; case CELLULAR_DONE: break; } if(cell_array[0] != NULL) #ifndef XFRACT cell_array[0] = NULL; #else farmemfree((char far *)cell_array[0]); #endif if(cell_array[1] != NULL) #ifndef XFRACT cell_array[1] = NULL; #else farmemfree((char far *)cell_array[1]); #endif } int cellular () { S16 start_row; S16 filled, notfilled; U16 cell_table[32]; U16 init_string[16]; U16 kr, k; U32 lnnmbr; U16 i, twor; S16 t, t2; S32 randparam; double n; char buf[30]; set_Cellular_palette(); randparam = (S32)param[0]; lnnmbr = (U32)param[3]; kr = (U16)param[2]; switch (kr) { case 21: case 31: case 41: case 51: case 61: case 22: case 32: case 42: case 23: case 33: case 24: case 25: case 26: case 27: break; default: abort_cellular(TYPEKR, 0); return -1; /* break; */ } r = (S16)(kr % 10); /* Number of nearest neighbors to sum */ k = (U16)(kr / 10); /* Number of different states, k=3 has states 0,1,2 */ k_1 = (S16)(k - 1); /* Highest state value, k=3 has highest state value of 2 */ rule_digits = (S16)((r * 2 + 1) * k_1 + 1); /* Number of digits in the rule */ if ((!rflag) && randparam == -1) --rseed; if (randparam != 0 && randparam != -1) { n = param[0]; sprintf(buf,"%.16g",n); /* # of digits in initial string */ t = (S16)strlen(buf); if (t>16 || t <= 0) { abort_cellular(STRING1, 0); return -1; } for (i=0;i<16;i++) init_string[i] = 0; /* zero the array */ t2 = (S16) ((16 - t)/2); for (i=0;i<(U16)t;i++) { /* center initial string in array */ init_string[i+t2] = (U16)(buf[i] - 48); /* change character to number */ if (init_string[i+t2]>(U16)k_1) { abort_cellular(STRING2, 0); return -1; } } } srand(rseed); if (!rflag) ++rseed; /* generate rule table from parameter 1 */ #ifndef XFRACT n = param[1]; #else /* gcc can't manage to convert a big double to an unsigned long properly. */ if (param[1]>0x7fffffff) { n = (param[1]-0x7fffffff); n += 0x7fffffff; } else { n = param[1]; } #endif if (n == 0) { /* calculate a random rule */ n = rand()%(int)k; for (i=1;i<(U16)rule_digits;i++) { n *= 10; n += rand()%(int)k; } param[1] = n; } sprintf(buf,"%.*g",rule_digits ,n); t = (S16)strlen(buf); if (rule_digits < t || t < 0) { /* leading 0s could make t smaller */ abort_cellular(RULELENGTH, 0); return -1; } for (i=0;i<(U16)rule_digits;i++) /* zero the table */ cell_table[i] = 0; for (i=0;i<(U16)t;i++) { /* reverse order */ cell_table[i] = (U16)(buf[t-i-1] - 48); /* change character to number */ if (cell_table[i]>(U16)k_1) { abort_cellular(TABLEK, 0); return -1; } } start_row = 0; #ifndef XFRACT /* two 4096 byte arrays, at present at most 2024 + 1 bytes should be */ /* needed in each array (max screen width + 1) */ cell_array[0] = (BYTE *)&dstack[0]; /* dstack is in general.asm */ cell_array[1] = (BYTE *)&boxy[0]; /* boxy is in general.asm */ #else cell_array[0] = (BYTE far *)farmemalloc(ixstop+1); cell_array[1] = (BYTE far *)farmemalloc(ixstop+1); #endif if (cell_array[0]==NULL || cell_array[1]==NULL) { abort_cellular(BAD_MEM, 0); return(-1); } /* nxtscreenflag toggled by space bar in fractint.c, 1 for continuous */ /* 0 to stop on next screen */ filled = 0; notfilled = (S16)(1-filled); if (resuming && !nxtscreenflag && !lstscreenflag) { start_resume(); get_resume(sizeof(start_row),&start_row,0); end_resume(); get_line(start_row,0,ixstop,cell_array[filled]); } else if (nxtscreenflag && !lstscreenflag) { start_resume(); end_resume(); get_line(iystop,0,ixstop,cell_array[filled]); param[3] += iystop + 1; start_row = -1; /* after 1st iteration its = 0 */ } else { if(rflag || randparam==0 || randparam==-1){ for (col=0;col<=ixstop;col++) { cell_array[filled][col] = (BYTE)(rand()%(int)k); } } /* end of if random */ else { for (col=0;col<=ixstop;col++) { /* Clear from end to end */ cell_array[filled][col] = 0; } i = 0; for (col=(ixstop-16)/2;col<(ixstop+16)/2;col++) { /* insert initial */ cell_array[filled][col] = (BYTE)init_string[i++]; /* string */ } } /* end of if not random */ if (lnnmbr != 0) lstscreenflag = 1; else lstscreenflag = 0; put_line(start_row,0,ixstop,cell_array[filled]); } start_row++; /* This section calculates the starting line when it is not zero */ /* This section can't be resumed since no screen output is generated */ /* calculates the (lnnmbr - 1) generation */ if (lstscreenflag) { /* line number != 0 & not resuming & not continuing */ U32 big_row; for (big_row = (U32)start_row; big_row < lnnmbr; big_row++) { static FCODE msg[]={"Cellular thinking (higher start row takes longer)"}; thinking(1,msg); if(rflag || randparam==0 || randparam==-1){ /* Use a random border */ for (i=0;i<=(U16)r;i++) { cell_array[notfilled][i]=(BYTE)(rand()%(int)k); cell_array[notfilled][ixstop-i]=(BYTE)(rand()%(int)k); } } else { /* Use a zero border */ for (i=0;i<=(U16)r;i++) { cell_array[notfilled][i]=0; cell_array[notfilled][ixstop-i]=0; } } t = 0; /* do first cell */ for (twor=(U16)(r+r),i=0;i<=twor;i++) t = (S16)(t + (S16)cell_array[filled][i]); if (t>rule_digits || t<0) { thinking(0, NULL); abort_cellular(BAD_T, t); return(-1); } cell_array[notfilled][r] = (BYTE)cell_table[t]; /* use a rolling sum in t */ for (col=r+1;colrule_digits || t<0) { thinking(0, NULL); abort_cellular(BAD_T, t); return(-1); } cell_array[notfilled][col] = (BYTE)cell_table[t]; } filled = notfilled; notfilled = (S16)(1-filled); if (keypressed()) { thinking(0, NULL); abort_cellular(INTERUPT, 0); return -1; } } start_row = 0; thinking(0, NULL); lstscreenflag = 0; } /* This section does all the work */ contloop: for (row = start_row; row <= iystop; row++) { if(rflag || randparam==0 || randparam==-1){ /* Use a random border */ for (i=0;i<=(U16)r;i++) { cell_array[notfilled][i]=(BYTE)(rand()%(int)k); cell_array[notfilled][ixstop-i]=(BYTE)(rand()%(int)k); } } else { /* Use a zero border */ for (i=0;i<=(U16)r;i++) { cell_array[notfilled][i]=0; cell_array[notfilled][ixstop-i]=0; } } t = 0; /* do first cell */ for (twor=(U16)(r+r),i=0;i<=twor;i++) t = (S16)(t + (S16)cell_array[filled][i]); if (t>rule_digits || t<0) { thinking(0, NULL); abort_cellular(BAD_T, t); return(-1); } cell_array[notfilled][r] = (BYTE)cell_table[t]; /* use a rolling sum in t */ for (col=r+1;colrule_digits || t<0) { thinking(0, NULL); abort_cellular(BAD_T, t); return(-1); } cell_array[notfilled][col] = (BYTE)cell_table[t]; } filled = notfilled; notfilled = (S16)(1-filled); put_line(row,0,ixstop,cell_array[filled]); if (keypressed()) { abort_cellular(CELLULAR_DONE, 0); alloc_resume(10,1); put_resume(sizeof(row),&row,0); return -1; } } if(nxtscreenflag) { param[3] += iystop + 1; start_row = -1; /* after 1st iteration its = 0 */ goto contloop; } abort_cellular(CELLULAR_DONE, 0); return 1; } int CellularSetup(void) { if (!resuming) { nxtscreenflag = 0; /* initialize flag */ } timer(0,curfractalspecific->calctype); return(0); } static void set_Cellular_palette() { static Palettetype Red = { 42, 0, 0 }; static Palettetype Green = { 10,35,10 }; static Palettetype Blue = { 13,12,29 }; static Palettetype Yellow = { 60,58,18 }; static Palettetype Brown = { 42,21, 0 }; if (mapdacbox && colorstate != 0) return; /* map= specified */ dac[0].red = 0 ; dac[0].green= 0 ; dac[0].blue = 0 ; dac[1].red = Red.red; dac[1].green = Red.green; dac[1].blue = Red.blue; dac[2].red = Green.red; dac[2].green = Green.green; dac[2].blue = Green.blue; dac[3].red = Blue.red; dac[3].green = Blue.green; dac[3].blue = Blue.blue; dac[4].red = Yellow.red; dac[4].green = Yellow.green; dac[4].blue = Yellow.blue; dac[5].red = Brown.red; dac[5].green = Brown.green; dac[5].blue = Brown.blue; SetTgaColors(); spindac(0,1); } /* frothy basin routines */ #define FROTH_BITSHIFT 28 #define FROTH_D_TO_L(x) ((long)((x)*(1L<fl.f.a*fsp->fl.f.a/4) static char froth3_256c[] = "froth3.map"; static char froth6_256c[] = "froth6.map"; static char froth3_16c[] = "froth316.map"; static char froth6_16c[] = "froth616.map"; struct froth_double_struct { double a; double halfa; double top_x1; double top_x2; double top_x3; double top_x4; double left_x1; double left_x2; double left_x3; double left_x4; double right_x1; double right_x2; double right_x3; double right_x4; }; struct froth_long_struct { long a; long halfa; long top_x1; long top_x2; long top_x3; long top_x4; long left_x1; long left_x2; long left_x3; long left_x4; long right_x1; long right_x2; long right_x3; long right_x4; }; struct froth_struct { int repeat_mapping; int altcolor; int attractors; int shades; union { /* This was made into a union to save 56 malloc()'ed bytes. */ struct froth_double_struct f; struct froth_long_struct l; } fl; }; struct froth_struct *fsp=NULL; /* froth_struct pointer */ /* color maps which attempt to replicate the images of James Alexander. */ static void set_Froth_palette(void) { char *mapname; if (colorstate != 0) /* 0 means dacbox matches default */ return; if (colors >= 16) { if (colors >= 256) { if (fsp->attractors == 6) mapname = froth6_256c; else mapname = froth3_256c; } else /* colors >= 16 */ { if (fsp->attractors == 6) mapname = froth6_16c; else mapname = froth3_16c; } if (ValidateLuts(mapname) != 0) return; colorstate = 0; /* treat map as default */ spindac(0,1); } } int froth_setup(void) { double sin_theta, cos_theta, x0, y0; sin_theta = SQRT3/2; /* sin(2*PI/3) */ cos_theta = -0.5; /* cos(2*PI/3) */ /* check for NULL as safety net */ if (fsp == NULL) fsp = (struct froth_struct *)malloc(sizeof (struct froth_struct)); if (fsp == NULL) { static FCODE msg[]= {"Sorry, not enough memory to run the frothybasin fractal type"}; stopmsg(0,(char far *)msg); return 0; } /* for the all important backwards compatibility */ if (save_release <= 1821) /* book version is 18.21 */ { /* use old release parameters */ fsp->repeat_mapping = ((int)param[0] == 6 || (int)param[0] == 2); /* map 1 or 2 times (3 or 6 basins) */ fsp->altcolor = (int)param[1]; param[2] = 0; /* throw away any value used prior to 18.20 */ fsp->attractors = !fsp->repeat_mapping ? 3 : 6; /* use old values */ /* old names */ fsp->fl.f.a = 1.02871376822; /* A */ fsp->fl.f.halfa = fsp->fl.f.a/2; /* A/2 */ fsp->fl.f.top_x1 = -1.04368901270; /* X1MIN */ fsp->fl.f.top_x2 = 1.33928675524; /* X1MAX */ fsp->fl.f.top_x3 = -0.339286755220; /* XMIDT */ fsp->fl.f.top_x4 = -0.339286755220; /* XMIDT */ fsp->fl.f.left_x1 = 0.07639837810; /* X3MAX2 */ fsp->fl.f.left_x2 = -1.11508950586; /* X2MIN2 */ fsp->fl.f.left_x3 = -0.27580275066; /* XMIDL */ fsp->fl.f.left_x4 = -0.27580275066; /* XMIDL */ fsp->fl.f.right_x1 = 0.96729063460; /* X2MAX1 */ fsp->fl.f.right_x2 = -0.22419724936; /* X3MIN1 */ fsp->fl.f.right_x3 = 0.61508950585; /* XMIDR */ fsp->fl.f.right_x4 = 0.61508950585; /* XMIDR */ } else /* use new code */ { if (param[0] != 2) param[0] = 1; fsp->repeat_mapping = (int)param[0] == 2; if (param[1] != 0) param[1] = 1; fsp->altcolor = (int)param[1]; fsp->fl.f.a = param[2]; fsp->attractors = fabs(fsp->fl.f.a) <= FROTH_CRITICAL_A ? (!fsp->repeat_mapping ? 3 : 6) : (!fsp->repeat_mapping ? 2 : 3); /* new improved values */ /* 0.5 is the value that causes the mapping to reach a minimum */ x0 = 0.5; /* a/2 is the value that causes the y value to be invariant over the mappings */ y0 = fsp->fl.f.halfa = fsp->fl.f.a/2; fsp->fl.f.top_x1 = froth_top_x_mapping(x0); fsp->fl.f.top_x2 = froth_top_x_mapping(fsp->fl.f.top_x1); fsp->fl.f.top_x3 = froth_top_x_mapping(fsp->fl.f.top_x2); fsp->fl.f.top_x4 = froth_top_x_mapping(fsp->fl.f.top_x3); /* rotate 120 degrees counter-clock-wise */ fsp->fl.f.left_x1 = fsp->fl.f.top_x1 * cos_theta - y0 * sin_theta; fsp->fl.f.left_x2 = fsp->fl.f.top_x2 * cos_theta - y0 * sin_theta; fsp->fl.f.left_x3 = fsp->fl.f.top_x3 * cos_theta - y0 * sin_theta; fsp->fl.f.left_x4 = fsp->fl.f.top_x4 * cos_theta - y0 * sin_theta; /* rotate 120 degrees clock-wise */ fsp->fl.f.right_x1 = fsp->fl.f.top_x1 * cos_theta + y0 * sin_theta; fsp->fl.f.right_x2 = fsp->fl.f.top_x2 * cos_theta + y0 * sin_theta; fsp->fl.f.right_x3 = fsp->fl.f.top_x3 * cos_theta + y0 * sin_theta; fsp->fl.f.right_x4 = fsp->fl.f.top_x4 * cos_theta + y0 * sin_theta; } /* if 2 attractors, use same shades as 3 attractors */ fsp->shades = (colors-1) / max(3,fsp->attractors); /* rqlim needs to be at least sq(1+sqrt(1+sq(a))), */ /* which is never bigger than 6.93..., so we'll call it 7.0 */ if (rqlim < 7.0) rqlim=7.0; set_Froth_palette(); /* make the best of the .map situation */ orbit_color = fsp->attractors != 6 && colors >= 16 ? (fsp->shades<<1)+1 : colors-1; if (integerfractal) { struct froth_long_struct tmp_l; tmp_l.a = FROTH_D_TO_L(fsp->fl.f.a); tmp_l.halfa = FROTH_D_TO_L(fsp->fl.f.halfa); tmp_l.top_x1 = FROTH_D_TO_L(fsp->fl.f.top_x1); tmp_l.top_x2 = FROTH_D_TO_L(fsp->fl.f.top_x2); tmp_l.top_x3 = FROTH_D_TO_L(fsp->fl.f.top_x3); tmp_l.top_x4 = FROTH_D_TO_L(fsp->fl.f.top_x4); tmp_l.left_x1 = FROTH_D_TO_L(fsp->fl.f.left_x1); tmp_l.left_x2 = FROTH_D_TO_L(fsp->fl.f.left_x2); tmp_l.left_x3 = FROTH_D_TO_L(fsp->fl.f.left_x3); tmp_l.left_x4 = FROTH_D_TO_L(fsp->fl.f.left_x4); tmp_l.right_x1 = FROTH_D_TO_L(fsp->fl.f.right_x1); tmp_l.right_x2 = FROTH_D_TO_L(fsp->fl.f.right_x2); tmp_l.right_x3 = FROTH_D_TO_L(fsp->fl.f.right_x3); tmp_l.right_x4 = FROTH_D_TO_L(fsp->fl.f.right_x4); fsp->fl.l = tmp_l; } return 1; } void froth_cleanup(void) { if (fsp != NULL) free(fsp); /* set to NULL as a flag that froth_cleanup() has been called */ fsp = NULL; } /* Froth Fractal type */ int calcfroth(void) /* per pixel 1/2/g, called with row & col set */ { int found_attractor=0; if (check_key()) { return -1; } if (fsp == NULL) { /* error occured allocating memory for fsp */ return 0; } orbit_ptr = 0; coloriter = 0; if(showdot>0) (*plot) (col, row, showdot%colors); if (!integerfractal) /* fp mode */ { if(invert) { invertz2(&tmp); old = tmp; } else { old.x = dxpixel(); old.y = dypixel(); } while (!found_attractor && ((tempsqrx=sqr(old.x)) + (tempsqry=sqr(old.y)) < rqlim) && (coloriter < maxit)) { /* simple formula: z = z^2 + conj(z*(-1+ai)) */ /* but it's the attractor that makes this so interesting */ new.x = tempsqrx - tempsqry - old.x - fsp->fl.f.a*old.y; old.y += (old.x+old.x)*old.y - fsp->fl.f.a*old.x; old.x = new.x; if (fsp->repeat_mapping) { new.x = sqr(old.x) - sqr(old.y) - old.x - fsp->fl.f.a*old.y; old.y += (old.x+old.x)*old.y - fsp->fl.f.a*old.x; old.x = new.x; } coloriter++; if (show_orbit) { if (keypressed()) break; plot_orbit(old.x, old.y, -1); } if (fabs(fsp->fl.f.halfa-old.y) < FROTH_CLOSE && old.x >= fsp->fl.f.top_x1 && old.x <= fsp->fl.f.top_x2) { if ((!fsp->repeat_mapping && fsp->attractors == 2) || (fsp->repeat_mapping && fsp->attractors == 3)) found_attractor = 1; else if (old.x <= fsp->fl.f.top_x3) found_attractor = 1; else if (old.x >= fsp->fl.f.top_x4) { if (!fsp->repeat_mapping) found_attractor = 1; else found_attractor = 2; } } else if (fabs(FROTH_SLOPE*old.x - fsp->fl.f.a - old.y) < FROTH_CLOSE && old.x <= fsp->fl.f.right_x1 && old.x >= fsp->fl.f.right_x2) { if (!fsp->repeat_mapping && fsp->attractors == 2) found_attractor = 2; else if (fsp->repeat_mapping && fsp->attractors == 3) found_attractor = 3; else if (old.x >= fsp->fl.f.right_x3) { if (!fsp->repeat_mapping) found_attractor = 2; else found_attractor = 4; } else if (old.x <= fsp->fl.f.right_x4) { if (!fsp->repeat_mapping) found_attractor = 3; else found_attractor = 6; } } else if (fabs(-FROTH_SLOPE*old.x - fsp->fl.f.a - old.y) < FROTH_CLOSE && old.x <= fsp->fl.f.left_x1 && old.x >= fsp->fl.f.left_x2) { if (!fsp->repeat_mapping && fsp->attractors == 2) found_attractor = 2; else if (fsp->repeat_mapping && fsp->attractors == 3) found_attractor = 2; else if (old.x >= fsp->fl.f.left_x3) { if (!fsp->repeat_mapping) found_attractor = 3; else found_attractor = 5; } else if (old.x <= fsp->fl.f.left_x4) { if (!fsp->repeat_mapping) found_attractor = 2; else found_attractor = 3; } } } } else /* integer mode */ { if(invert) { invertz2(&tmp); lold.x = (long)(tmp.x * fudge); lold.y = (long)(tmp.y * fudge); } else { lold.x = lxpixel(); lold.y = lypixel(); } while (!found_attractor && ((lmagnitud = (ltempsqrx=lsqr(lold.x)) + (ltempsqry=lsqr(lold.y))) < llimit) && (lmagnitud >= 0) && (coloriter < maxit)) { /* simple formula: z = z^2 + conj(z*(-1+ai)) */ /* but it's the attractor that makes this so interesting */ lnew.x = ltempsqrx - ltempsqry - lold.x - multiply(fsp->fl.l.a,lold.y,bitshift); lold.y += (multiply(lold.x,lold.y,bitshift)<<1) - multiply(fsp->fl.l.a,lold.x,bitshift); lold.x = lnew.x; if (fsp->repeat_mapping) { lmagnitud = (ltempsqrx=lsqr(lold.x)) + (ltempsqry=lsqr(lold.y)); if ((lmagnitud > llimit) || (lmagnitud < 0)) break; lnew.x = ltempsqrx - ltempsqry - lold.x - multiply(fsp->fl.l.a,lold.y,bitshift); lold.y += (multiply(lold.x,lold.y,bitshift)<<1) - multiply(fsp->fl.l.a,lold.x,bitshift); lold.x = lnew.x; } coloriter++; if (show_orbit) { if (keypressed()) break; iplot_orbit(lold.x, lold.y, -1); } if (labs(fsp->fl.l.halfa-lold.y) < FROTH_LCLOSE && lold.x > fsp->fl.l.top_x1 && lold.x < fsp->fl.l.top_x2) { if ((!fsp->repeat_mapping && fsp->attractors == 2) || (fsp->repeat_mapping && fsp->attractors == 3)) found_attractor = 1; else if (lold.x <= fsp->fl.l.top_x3) found_attractor = 1; else if (lold.x >= fsp->fl.l.top_x4) { if (!fsp->repeat_mapping) found_attractor = 1; else found_attractor = 2; } } else if (labs(multiply(FROTH_LSLOPE,lold.x,bitshift)-fsp->fl.l.a-lold.y) < FROTH_LCLOSE && lold.x <= fsp->fl.l.right_x1 && lold.x >= fsp->fl.l.right_x2) { if (!fsp->repeat_mapping && fsp->attractors == 2) found_attractor = 2; else if (fsp->repeat_mapping && fsp->attractors == 3) found_attractor = 3; else if (lold.x >= fsp->fl.l.right_x3) { if (!fsp->repeat_mapping) found_attractor = 2; else found_attractor = 4; } else if (lold.x <= fsp->fl.l.right_x4) { if (!fsp->repeat_mapping) found_attractor = 3; else found_attractor = 6; } } else if (labs(multiply(-FROTH_LSLOPE,lold.x,bitshift)-fsp->fl.l.a-lold.y) < FROTH_LCLOSE) { if (!fsp->repeat_mapping && fsp->attractors == 2) found_attractor = 2; else if (fsp->repeat_mapping && fsp->attractors == 3) found_attractor = 2; else if (lold.x >= fsp->fl.l.left_x3) { if (!fsp->repeat_mapping) found_attractor = 3; else found_attractor = 5; } else if (lold.x <= fsp->fl.l.left_x4) { if (!fsp->repeat_mapping) found_attractor = 2; else found_attractor = 3; } } } } if (show_orbit) scrub_orbit(); realcoloriter = coloriter; if ((kbdcount -= abs((int)realcoloriter)) <= 0) { if (check_key()) return (-1); kbdcount = max_kbdcount; } /* inside - Here's where non-palette based images would be nice. Instead, */ /* we'll use blocks of (colors-1)/3 or (colors-1)/6 and use special froth */ /* color maps in attempt to replicate the images of James Alexander. */ if (found_attractor) { if (colors >= 256) { if (!fsp->altcolor) { if (coloriter > fsp->shades) coloriter = fsp->shades; } else coloriter = fsp->shades * coloriter / maxit; if (coloriter == 0) coloriter = 1; coloriter += fsp->shades * (found_attractor-1); } else if (colors >= 16) { /* only alternate coloring scheme available for 16 colors */ long lshade; /* Trying to make a better 16 color distribution. */ /* Since their are only a few possiblities, just handle each case. */ /* This is a mostly guess work here. */ lshade = (coloriter<<16)/maxit; if (fsp->attractors != 6) /* either 2 or 3 attractors */ { if (lshade < 2622) /* 0.04 */ coloriter = 1; else if (lshade < 10486) /* 0.16 */ coloriter = 2; else if (lshade < 23593) /* 0.36 */ coloriter = 3; else if (lshade < 41943L) /* 0.64 */ coloriter = 4; else coloriter = 5; coloriter += 5 * (found_attractor-1); } else /* 6 attractors */ { if (lshade < 10486) /* 0.16 */ coloriter = 1; else coloriter = 2; coloriter += 2 * (found_attractor-1); } } else /* use a color corresponding to the attractor */ coloriter = found_attractor; oldcoloriter = coloriter; } else /* outside, or inside but didn't get sucked in by attractor. */ coloriter = 0; color = abs((int)(coloriter)); (*plot)(col, row, color); return color; } /* These last two froth functions are for the orbit-in-window feature. Normally, this feature requires StandardFractal, but since it is the attractor that makes the frothybasin type so unique, it is worth putting in as a stand-alone. */ int froth_per_pixel(void) { if (!integerfractal) /* fp mode */ { old.x = dxpixel(); old.y = dypixel(); tempsqrx=sqr(old.x); tempsqry=sqr(old.y); } else /* integer mode */ { lold.x = lxpixel(); lold.y = lypixel(); ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); } return 0; } int froth_per_orbit(void) { if (!integerfractal) /* fp mode */ { new.x = tempsqrx - tempsqry - old.x - fsp->fl.f.a*old.y; new.y = 2.0*old.x*old.y - fsp->fl.f.a*old.x + old.y; if (fsp->repeat_mapping) { old = new; new.x = sqr(old.x) - sqr(old.y) - old.x - fsp->fl.f.a*old.y; new.y = 2.0*old.x*old.y - fsp->fl.f.a*old.x + old.y; } if ((tempsqrx=sqr(new.x)) + (tempsqry=sqr(new.y)) >= rqlim) return 1; old = new; } else /* integer mode */ { lnew.x = ltempsqrx - ltempsqry - lold.x - multiply(fsp->fl.l.a,lold.y,bitshift); lnew.y = lold.y + (multiply(lold.x,lold.y,bitshift)<<1) - multiply(fsp->fl.l.a,lold.x,bitshift); if (fsp->repeat_mapping) { if ((ltempsqrx=lsqr(lnew.x)) + (ltempsqry=lsqr(lnew.y)) >= llimit) return 1; lold = lnew; lnew.x = ltempsqrx - ltempsqry - lold.x - multiply(fsp->fl.l.a,lold.y,bitshift); lnew.y = lold.y + (multiply(lold.x,lold.y,bitshift)<<1) - multiply(fsp->fl.l.a,lold.x,bitshift); } if ((ltempsqrx=lsqr(lnew.x)) + (ltempsqry=lsqr(lnew.y)) >= llimit) return 1; lold = lnew; } return 0; } xfractint-20.4.10.orig/common/rotate.c0000644000000000000000000004457711253454200014454 0ustar /* rotate.c - Routines that manipulate the Video DAC on VGA Adapters */ #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" /* routines in this module */ static void pauserotate(void); static void set_palette(BYTE start[3], BYTE finish[3]); static void set_palette2(BYTE start[3], BYTE finish[3]); static void set_palette3(BYTE start[3], BYTE middle[3], BYTE finish[3]); static int paused; /* rotate-is-paused flag */ static BYTE Red[3] = {63, 0, 0}; /* for shifted-Fkeys */ static BYTE Green[3] = { 0,63, 0}; static BYTE Blue[3] = { 0, 0,63}; static BYTE Black[3] = { 0, 0, 0}; static BYTE White[3] = {63,63,63}; static BYTE Yellow[3] = {63,63, 0}; static BYTE Brown[3] = {31,31, 0}; char mapmask[MAX_NAME] = {"*.map"}; void rotate(int direction) /* rotate-the-palette routine */ { int kbdchar, more, last, next; int fkey, step, fstep, istep, jstep, oldstep; int incr, fromred=0, fromblue=0, fromgreen=0, tored=0, toblue=0, togreen=0; int i, changecolor, changedirection; int oldhelpmode; int rotate_max,rotate_size; int oldcolorstate; static int fsteps[] = {2,4,8,12,16,24,32,40,54,100}; /* (for Fkeys) */ #ifndef XFRACT if (gotrealdac == 0 /* ??? no DAC to rotate! */ #else /* if (!(gotrealdac || fake_lut) */ /* ??? no DAC to rotate! */ if (!(gotrealdac) || (fake_lut) /* ??? no DAC to rotate! */ #endif || colors < 16) { /* strange things happen in 2x modes */ buzzer(2); return; } oldhelpmode = helpmode; /* save the old help mode */ helpmode = HELPCYCLING; /* new help mode */ oldcolorstate = colorstate; /* save the old colorstate */ paused = 0; /* not paused */ fkey = 0; /* no random coloring */ oldstep = step = 1; /* single-step */ fstep = 1; changecolor = -1; /* no color (rgb) to change */ changedirection = 0; /* no color direction to change */ incr = 999; /* ready to randomize */ srand((unsigned)time(NULL)); /* randomize things */ if (direction == 0) { /* firing up in paused mode? */ pauserotate(); /* then force a pause */ direction = 1; /* and set a rotate direction */ } rotate_max = (rotate_hi < colors) ? rotate_hi : colors-1; rotate_size = rotate_max - rotate_lo + 1; last = rotate_max; /* last box that was filled */ next = rotate_lo; /* next box to be filled */ if (direction < 0) { last = rotate_lo; next = rotate_max; } more = 1; while (more) { if (dotmode == 11) { if (!paused) pauserotate(); } else while(!keypressed()) { /* rotate until key hit, at least once so step=oldstep ok */ if (fkey > 0) { /* randomizing is on */ for (istep = 0; istep < step; istep++) { jstep = next + (istep * direction); while (jstep < rotate_lo) jstep += rotate_size; while (jstep > rotate_max) jstep -= rotate_size; if (++incr > fstep) { /* time to randomize */ incr = 1; fstep = ((fsteps[fkey-1]* (rand15() >> 8)) >> 6) + 1; fromred = dacbox[last][0]; fromgreen = dacbox[last][1]; fromblue = dacbox[last][2]; tored = rand15() >> 9; togreen = rand15() >> 9; toblue = rand15() >> 9; } dacbox[jstep][0] = (BYTE)(fromred + (((tored - fromred )*incr)/fstep)); dacbox[jstep][1] = (BYTE)(fromgreen + (((togreen - fromgreen)*incr)/fstep)); dacbox[jstep][2] = (BYTE)(fromblue + (((toblue - fromblue )*incr)/fstep)); } } if (step >= rotate_size) step = oldstep; spindac(direction, step); } if (step >= rotate_size) step = oldstep; kbdchar = getakey(); if (paused && (kbdchar != ' ' && kbdchar != 'c' && kbdchar != HOME && kbdchar != 'C' )) paused = 0; /* clear paused condition */ switch (kbdchar) { case '+': /* '+' means rotate forward */ case RIGHT_ARROW: /* RightArrow = rotate fwd */ fkey = 0; direction = 1; last = rotate_max; next = rotate_lo; incr = 999; break; case '-': /* '-' means rotate backward */ case LEFT_ARROW: /* LeftArrow = rotate bkwd */ fkey = 0; direction = -1; last = rotate_lo; next = rotate_max; incr = 999; break; case UP_ARROW: /* UpArrow means speed up */ daclearn = 1; if (++daccount >= colors) --daccount; break; case DOWN_ARROW: /* DownArrow means slow down */ daclearn = 1; if (daccount > 1) daccount--; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': step = kbdchar - '0'; /* change step-size */ if (step > rotate_size) step = rotate_size; break; case F1: /* F1 - F10: */ case F2: /* select a shading factor */ case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: #ifndef XFRACT fkey = kbdchar-1058; #else switch (kbdchar) { case F1: fkey = 1;break; case F2: fkey = 2;break; case F3: fkey = 3;break; case F4: fkey = 4;break; case F5: fkey = 5;break; case F6: fkey = 6;break; case F7: fkey = 7;break; case F8: fkey = 8;break; case F9: fkey = 9;break; case F10: fkey = 10;break; } #endif if (reallyega) fkey = (fkey+1)>>1; /* limit on EGA */ fstep = 1; incr = 999; break; case ENTER: /* enter key: randomize all colors */ case ENTER_2: /* also the Numeric-Keypad Enter */ fkey = rand15()/3277 + 1; if (reallyega) /* limit on EGAs */ fkey = (fkey+1)>>1; fstep = 1; incr = 999; oldstep = step; step = rotate_size; colorstate = 1; /* not a known color map */ break; case 'r': /* color changes */ if (changecolor == -1) changecolor = 0; case 'g': /* color changes */ if (changecolor == -1) changecolor = 1; case 'b': /* color changes */ if (changecolor == -1) changecolor = 2; if (changedirection == 0) changedirection = -1; case 'R': /* color changes */ if (changecolor == -1) changecolor = 0; case 'G': /* color changes */ if (changecolor == -1) changecolor = 1; case 'B': /* color changes */ if (dotmode == 11) break; if (changecolor == -1) changecolor = 2; if (changedirection == 0) changedirection = 1; if (reallyega) break; /* no sense on real EGAs */ for (i = 1; i < 256; i++) { dacbox[i][changecolor] = (BYTE)(dacbox[i][changecolor] + changedirection); if (dacbox[i][changecolor] == 64) dacbox[i][changecolor] = 63; if (dacbox[i][changecolor] == 255) dacbox[i][changecolor] = 0; } changecolor = -1; /* clear flags for next time */ changedirection = 0; paused = 0; /* clear any pause */ colorstate = 1; /* not a known color map */ case ' ': /* use the spacebar as a "pause" toggle */ case 'c': /* for completeness' sake, the 'c' too */ case 'C': if (colorstate == 0 || colorstate == 2) colorstate = 3; pauserotate(); /* pause */ break; case '>': /* single-step */ case '.': case '<': case ',': if (colorstate == 0 || colorstate == 2) colorstate = 3; if (kbdchar == '>' || kbdchar == '.') { direction = -1; last = rotate_lo; next = rotate_max; incr = 999; } else { direction = 1; last = rotate_max; next = rotate_lo; incr = 999; } fkey = 0; spindac(direction,1); if (! paused) pauserotate(); /* pause */ break; case 'd': /* load colors from "default.map" */ case 'D': if (ValidateLuts("default") != 0) break; fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case 'a': /* load colors from "altern.map" */ case 'A': if (ValidateLuts("altern") != 0) break; fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case 'l': /* load colors from a specified map */ #ifndef XFRACT /* L is used for RIGHT_ARROW in Unix keyboard mapping */ case 'L': #endif load_palette(); fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case 's': /* save the palette */ case 'S': save_palette(); fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case ESC: /* escape */ more = 0; /* time to bail out */ break; case HOME: /* restore palette */ memcpy(dacbox,olddacbox,256*3); pauserotate(); /* pause */ colorstate = oldcolorstate; break; default: /* maybe a new palette */ if (reallyega) break; /* no sense on real EGAs */ fkey = 0; /* disable random generation */ if (kbdchar == 1084) set_palette(Black, White); if (kbdchar == SF2) set_palette(Red, Yellow); if (kbdchar == SF3) set_palette(Blue, Green); if (kbdchar == SF4) set_palette(Black, Yellow); if (kbdchar == SF5) set_palette(Black, Red); if (kbdchar == SF6) set_palette(Black, Blue); if (kbdchar == SF7) set_palette(Black, Green); if (kbdchar == SF8) set_palette(Blue, Yellow); if (kbdchar == SF9) set_palette(Red, Green); if (kbdchar == 1093) set_palette(Green, White); if (kbdchar == 1094) set_palette2(Black, White); if (kbdchar == 1095) set_palette2(Red, Yellow); if (kbdchar == 1096) set_palette2(Blue, Green); if (kbdchar == 1097) set_palette2(Black, Yellow); if (kbdchar == 1098) set_palette2(Black, Red); if (kbdchar == 1099) set_palette2(Black, Blue); if (kbdchar == 1100) set_palette2(Black, Green); if (kbdchar == 1101) set_palette2(Blue, Yellow); if (kbdchar == 1102) set_palette2(Red, Green); if (kbdchar == 1103) set_palette2(Green, White); if (kbdchar == 1104) set_palette3(Blue, Green, Red); if (kbdchar == 1105) set_palette3(Blue, Yellow, Red); if (kbdchar == 1106) set_palette3(Red, White, Blue); if (kbdchar == 1107) set_palette3(Red, Yellow, White); if (kbdchar == 1108) set_palette3(Black, Brown, Yellow); if (kbdchar == 1109) set_palette3(Blue, Brown, Green); if (kbdchar == 1110) set_palette3(Blue, Green, Green); if (kbdchar == 1111) set_palette3(Blue, Green, White); if (kbdchar == 1112) set_palette3(Green, Green, White); if (kbdchar == 1113) set_palette3(Red, Blue, White); pauserotate(); /* update palette and pause */ colorstate = 1; /* not a known color map */ break; } } helpmode = oldhelpmode; /* return to previous help mode */ } static void pauserotate() /* pause-the-rotate routine */ { int olddaccount; /* saved dac-count value goes here */ BYTE olddac0,olddac1,olddac2; if (paused) /* if already paused , just clear */ paused = 0; else { /* else set border, wait for a key */ olddaccount = daccount; olddac0 = dacbox[0][0]; olddac1 = dacbox[0][1]; olddac2 = dacbox[0][2]; daccount = 256; dacbox[0][0] = 48; dacbox[0][1] = 48; dacbox[0][2] = 48; spindac(0,1); /* show white border */ if (dotmode == 11) { static FCODE o_msg[] = {" Paused in \"color cycling\" mode "}; char msg[sizeof(o_msg)]; far_strcpy(msg,o_msg); dvid_status(100,msg); } #ifndef XFRACT while (!keypressed()); /* wait for any key */ #else waitkeypressed(0); /* wait for any key */ #endif if (dotmode == 11) dvid_status(0,""); dacbox[0][0] = olddac0; dacbox[0][1] = olddac1; dacbox[0][2] = olddac2; spindac(0,1); /* show black border */ daccount = olddaccount; paused = 1; } } static void set_palette(BYTE start[3], BYTE finish[3]) { int i, j; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for(i=1;i<=255;i++) /* fill the palette */ for (j = 0; j < 3; j++) #ifdef __SVR4 dacbox[i][j] = (BYTE)((int)(i*start[j] + (256-i)*finish[j])/255); #else dacbox[i][j] = (BYTE)((i*start[j] + (256-i)*finish[j])/255); #endif } static void set_palette2(BYTE start[3], BYTE finish[3]) { int i, j; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for(i=1;i<=128;i++) for (j = 0; j < 3; j++) { #ifdef __SVR4 dacbox[i][j] = (BYTE)((int)(i*finish[j] + (128-i)*start[j] )/128); dacbox[i+127][j] = (BYTE)((int)(i*start[j] + (128-i)*finish[j])/128); #else dacbox[i][j] = (BYTE)((i*finish[j] + (128-i)*start[j] )/128); dacbox[i+127][j] = (BYTE)((i*start[j] + (128-i)*finish[j])/128); #endif } } static void set_palette3(BYTE start[3], BYTE middle[3], BYTE finish[3]) { int i, j; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for(i=1;i<=85;i++) for (j = 0; j < 3; j++) { #ifdef __SVR4 dacbox[i][j] = (BYTE)((int)(i*middle[j] + (86-i)*start[j] )/85); dacbox[i+85][j] = (BYTE)((int)(i*finish[j] + (86-i)*middle[j])/85); dacbox[i+170][j] = (BYTE)((int)(i*start[j] + (86-i)*finish[j])/85); #else dacbox[i][j] = (BYTE)((i*middle[j] + (86-i)*start[j] )/85); dacbox[i+85][j] = (BYTE)((i*finish[j] + (86-i)*middle[j])/85); dacbox[i+170][j] = (BYTE)((i*start[j] + (86-i)*finish[j])/85); #endif } } void save_palette() { char palname[FILE_MAX_PATH]; static FCODE o_msg[] = {"Name of map file to write"}; char msg[sizeof(o_msg)]; FILE *dacfile; int i,oldhelpmode; far_strcpy(msg,o_msg); strcpy(palname,MAP_name); oldhelpmode = helpmode; stackscreen(); temp1[0] = 0; helpmode = HELPCOLORMAP; i = field_prompt(0,msg,NULL,temp1,60,NULL); unstackscreen(); if (i != -1 && temp1[0]) { if (strchr(temp1,'.') == NULL) strcat(temp1,".map"); merge_pathnames(palname,temp1,2); dacfile = fopen(palname,"w"); if (dacfile == NULL) buzzer(2); else { int start = 0; if (colorstate >= 2) { char tmpfilename[FILE_MAX_PATH]; extract_filename(tmpfilename, colorfile); fprintf(dacfile, "%3d %3d %3d Rotated version of map file %s\n", dacbox[start][0] << 2, dacbox[start][1] << 2, dacbox[start][2] << 2, tmpfilename); start++; } #ifndef XFRACT for (i = start; i < colors; i++) #else for (i = start; i < 256; i++) #endif fprintf(dacfile, "%3d %3d %3d\n", dacbox[i][0] << 2, dacbox[i][1] << 2, dacbox[i][2] << 2); memcpy(olddacbox,dacbox,256*3); colorstate = 2; strcpy(colorfile,temp1); } fclose(dacfile); } helpmode = oldhelpmode; } int load_palette(void) { int i,oldhelpmode; char filename[FILE_MAX_PATH]; oldhelpmode = helpmode; strcpy(filename,MAP_name); stackscreen(); helpmode = HELPCOLORMAP; i = getafilename("Select a MAP File",mapmask,filename); unstackscreen(); if (i >= 0) { if (ValidateLuts(filename) == 0) memcpy(olddacbox,dacbox,256*3); merge_pathnames(MAP_name,filename,0); } helpmode = oldhelpmode; return (i); } xfractint-20.4.10.orig/common/3d.c0000644000000000000000000002464510150633601013455 0ustar /* A word about the 3D library. Even though this library supports three dimensions, the matrices are 4x4 for the following reason. With normal 3 dimensional vectors, translation is an ADDITION, and rotation is a MULTIPLICATION. A vector {x,y,z} is represented as a 4-tuple {x,y,z,1}. It is then possible to define a 4x4 matrix such that multiplying the vector by the matrix translates the vector. This allows combinations of translation and rotation to be obtained in a single matrix by multiplying a translation matrix and a rotation matrix together. Note that in the code, vectors have three components; since the fourth component is always 1, that value is not included in the vector variable to save space, but the routines make use of the fourth component (see vec_mult()). Similarly, the fourth column of EVERY matrix is always 0 0 0 1 but currently the C version of a matrix includes this even though it could be left out of the data structure and assumed in the routines. Vectors are ROW vectors, and are always multiplied with matrices FROM THE LEFT (e.g. vector*matrix). Also note the order of indices of a matrix is matrix[row][column], and in usual C fashion, numbering starts with 0. TRANSLATION MATRIX = 1 0 0 0 0 1 0 0 0 0 1 0 Tx Ty Tz 1 SCALE MATRIX = Sx 0 0 0 0 Sy 0 0 0 0 Sz 0 0 0 0 1 Rotation about x axis i degrees: ROTX(i) = 1 0 0 0 0 cosi sini 0 0 -sini cosi 0 0 0 0 1 Rotation about y axis i degrees: ROTY(i) = cosi 0 -sini 0 0 1 0 0 sini 0 cosi 0 0 0 0 1 Rotation about z axis i degrees: ROTZ(i) = cosi sini 0 0 -sini cosi 0 0 0 0 1 0 0 0 0 1 -- Tim Wegner April 22, 1989 */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" /* initialize a matrix and set to identity matrix (all 0's, 1's on diagonal) */ void identity(MATRIX m) { int i,j; for(i=0;i FLT_MAX) return(-1); vlength = sqrt(vlength); if(vlength < FLT_MIN) return(-1); v[0] /= vlength; v[1] /= vlength; v[2] /= vlength; return(0); } /* multiply source vector s by matrix m, result in target t */ /* used to apply transformations to a vector */ int vmult(VECTOR s, MATRIX m, VECTOR t) { VECTOR tmp; int i,j; for(j=0;j= 0.0) { v[0] = bad_value; /* clipping will catch these values */ v[1] = bad_value; /* so they won't plot values BEHIND viewer */ v[2] = bad_value; return(-1); } v[0] = (v[0]*view[2] - view[0]*v[2])/denom; v[1] = (v[1]*view[2] - view[1]*v[2])/denom; /* calculation of z if needed later */ /* v[2] = v[2]/denom;*/ return(0); } /* long version of vmult and perspective combined for speed */ int longvmultpersp(LVECTOR s, LMATRIX m, LVECTOR t0, LVECTOR t, LVECTOR lview, int bitshift) { /* s: source vector */ /* m: transformation matrix */ /* t0: after transformation, before persp */ /* t: target vector */ /* lview: perspective viewer coordinates */ /* bitshift: fixed point conversion bitshift */ LVECTOR tmp; int i,j, k; overflow = 0; k = CMAX-1; /* shorten the math if non-perspective and non-illum */ if (lview[2] == 0 && t0[0] == 0) k--; for(j=0;j= 0) /* bail out if point is "behind" us */ { t[0] = bad_value; t[0] = t[0]<= 0) /* bail out if point is "behind" us */ { lv[0] = bad_value; lv[0] = lv[0]< /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" /***************************************************************************/ #define dac ((Palettetype *)dacbox) #ifndef WINFRACT void SetTgaColors() { unsigned r, g, b, index; if (tga16 != NULL) for( index = 0; index < 256; index++ ) { r = dac[index].red << 2; g = dac[index].green << 2; b = dac[index].blue << 2; tga16[index] = ((r&248)<<7) | ((g&248)<<2) | (b>>3); tga32[index] = ((long)r<<16) | (g<<8) | b; } } #endif void get_map_name( char * from_str, char * to_str) { /* called once we know from_str contains ".map" */ /* returns xxxxxxxx.map in to_str */ char *temp_map_name, *dot_position; unsigned int position, name_length; temp_map_name = strstr(from_str,".map"); dot_position = temp_map_name; while(*temp_map_name != ' ' && /* find space before map name */ *temp_map_name != '@') /* find @ symbol before map name */ temp_map_name--; temp_map_name++; /* start of map name */ name_length = (unsigned int)(dot_position - temp_map_name + 4); for( position = 0; position < (name_length); position++) to_str[position] = *temp_map_name++; to_str[position] = '\0'; /* add NULL termination */ } int ValidateLuts( char * fn ) { FILE * f; unsigned r, g, b, index; char line[160]; char temp[FILE_MAX_PATH+1]; char temp_fn[FILE_MAX_PATH]; char *dummy; /* to quiet compiler */ strcpy(temp,MAP_name); strcpy(temp_fn,fn); #ifdef XFRACT merge_pathnames(temp,temp_fn,3); #else merge_pathnames(temp,temp_fn,0); #endif if (has_ext(temp) == NULL) /* Did name have an extension? */ strcat(temp,".map"); /* No? Then add .map */ findpath( temp, line); /* search the dos path */ f = fopen( line, "r" ); if (f == NULL) { sprintf(line,"Could not load color map %s",fn); stopmsg(0,line); return 1; } dummy = fgets(line,100,f); if (strstr(line,".map") != NULL) { /* found a map name */ get_map_name(line, fn); } sscanf( line, "%u %u %u", &r, &g, &b ); /** load global dac values **/ dac[0].red = (BYTE)((r%256) >> 2);/* maps default to 8 bits */ dac[0].green = (BYTE)((g%256) >> 2);/* DAC wants 6 bits */ dac[0].blue = (BYTE)((b%256) >> 2); for( index = 1; index < 256; index++ ) { if (fgets(line,100,f) == NULL) break; sscanf( line, "%u %u %u", &r, &g, &b ); /** load global dac values **/ dac[index].red = (BYTE)((r%256) >> 2);/* maps default to 8 bits */ dac[index].green = (BYTE)((g%256) >> 2);/* DAC wants 6 bits */ dac[index].blue = (BYTE)((b%256) >> 2); } fclose( f ); while (index < 256) { /* zap unset entries */ dac[index].red = dac[index].blue = dac[index].green = 40; ++index; } SetTgaColors(); colorstate = 2; strcpy(colorfile,fn); return 0; } /***************************************************************************/ int SetColorPaletteName( char * fn ) { if( ValidateLuts( fn ) != 0) return 1; if( mapdacbox == NULL && (mapdacbox = (char far *)farmemalloc(768L)) == NULL) { static FCODE o_msg[]={"Insufficient memory for color map."}; char msg[sizeof(o_msg)]; far_strcpy(msg,o_msg); stopmsg(0,msg); return 1; } far_memcpy((char far *)mapdacbox,(char far *)dacbox,768); /* PB, 900829, removed atexit(RestoreMap) stuff, goodbye covers it */ return 0; } xfractint-20.4.10.orig/common/realdos.c0000644000000000000000000017461011132521161014574 0ustar /* Miscellaneous C routines used only in DOS Fractint. */ #include #ifndef XFRACT #include #include #endif #include #include #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" int menu_checkkey(int curkey,int choice); /* uncomment following for production version */ /* #define PRODUCTION */ int release=2004; /* this has 2 implied decimals; increment it every synch */ int patchlevel=10; /* patchlevel for DOS version */ /* fullscreen_choice options */ #define CHOICERETURNKEY 1 #define CHOICEMENU 2 #define CHOICEHELP 4 #define CHOICESCRUNCH 16 #define CHOICESNOTSORTED 32 /* int stopmsg(flags,message) displays message and waits for a key: message should be a max of 9 lines with \n's separating them; no leading or trailing \n's in message; no line longer than 76 chars for best appearance; flag options: &1 if already in text display mode, stackscreen is not called and message is displayed at (12,0) instead of (4,0) &2 if continue/cancel indication is to be returned; when not set, "Any key to continue..." is displayed when set, "Escape to cancel, any other key to continue..." -1 is returned for cancel, 0 for continue &4 set to suppress buzzer &8 for Fractint for Windows & parser - use a fixed pitch font &16 for info only message (green box instead of red in DOS vsn) */ #ifdef XFRACT static char far s_errorstart[] = {"*** Error during startup:"}; extern char * Xmessage; #endif static char far s_escape_cancel[] = {"Escape to cancel, any other key to continue..."}; static char far s_anykey[] = {"Any key to continue..."}; #ifndef PRODUCTION static char far s_custom[] = {"Customized Version"}; static char far s_incremental[] = {"Incremental release"}; #endif int stopmsg (int flags, char far *msg) { int ret,toprow,color,savelookatmouse; static unsigned char batchmode = 0; if(debugflag != 0 || initbatch >= 1) { static FILE *fp = NULL; if(fp==NULL && initbatch == 0) fp=dir_fopen(workdir,"stopmsg.txt","w"); else fp=dir_fopen(workdir,"stopmsg.txt","a"); if(fp != NULL) #ifndef XFRACT fprintf(fp,"%Fs\n",msg); #else fprintf(fp,"%s\n",msg); #endif fclose(fp); } if (active_system == 0 /* DOS */ && first_init) { /* & cmdfiles hasn't finished 1st try */ #ifdef XFRACT #ifdef NCURSES setvideotext(); buzzer(2); putstring(0,0,15,s_errorstart); putstring(2,0,15,msg); movecursor(8,0); sleep(1); #else fprintf(stderr, "%s\n", msg); #endif UnixDone(); exit(1); #else printf("%Fs\n",msg); dopause(1); /* pause deferred until after cmdfiles */ return(0); #endif } if (initbatch >= 1 || batchmode) { /* in batch mode */ initbatch = 4; /* used to set errorlevel */ batchmode = 1; /* fixes *second* stopmsg in batch mode bug */ return (-1); } ret = 0; savelookatmouse = lookatmouse; lookatmouse = -13; if ((flags & 1)) blankrows(toprow=12,10,7); else { stackscreen(); toprow = 4; movecursor(4,0); } textcbase = 2; /* left margin is 2 */ putstring(toprow,0,7,msg); if (flags & 2) putstring(textrow+2,0,7,s_escape_cancel); else putstring(textrow+2,0,7,s_anykey); textcbase = 0; /* back to full line */ color = (flags & 16) ? C_STOP_INFO : C_STOP_ERR; setattr(toprow,0,color,(textrow+1-toprow)*80); movecursor(25,80); /* cursor off */ if ((flags & 4) == 0) buzzer((flags & 16) ? 0 : 2); while (keypressed()) /* flush any keyahead */ getakey(); if(debugflag != 324) if (getakeynohelp() == ESC) ret = -1; if ((flags & 1)) blankrows(toprow,10,7); else unstackscreen(); lookatmouse = savelookatmouse; return ret; } static U16 temptextsave = 0; static int textxdots,textydots; /* texttempmsg(msg) displays a text message of up to 40 characters, waits for a key press, restores the prior display, and returns (without eating the key). It works in almost any video mode - does nothing in some very odd cases (HCGA hi-res with old bios), or when there isn't 10k of temp mem free. */ int texttempmsg(char far *msgparm) { #if defined(XFRACT) && !defined(NCURSES) xpopup(msgparm); return(-1); #else if (showtempmsg(msgparm)) return(-1); while (!keypressed()) ; /* wait for a keystroke but don't eat */ cleartempmsg(); return(0); #endif } void freetempmsg() { #if defined(XFRACT) && !defined(NCURSES) if (Xmessage) free(Xmessage); Xmessage = NULL; #else if(temptextsave != 0) MemoryRelease(temptextsave); temptextsave = 0; #endif } int showtempmsg(char far *msgparm) { static long size = 0; char msg[41]; BYTE buffer[640]; BYTE far *fontptr; BYTE *bufptr; int i,j,k,fontchar,charnum; int xrepeat = 0; int yrepeat = 0; int save_sxoffs,save_syoffs; far_strncpy(msg,msgparm,40); msg[40] = 0; /* ensure max message len of 40 chars */ if (dotmode == 11) { /* disk video, screen in text mode, easy */ dvid_status(0,msg); return(0); } if (active_system == 0 /* DOS */ && first_init) { /* & cmdfiles hasn't finished 1st try */ printf("%s\n",msg); return(0); } if ((fontptr = findfont(0)) == NULL) { /* old bios, no font table? */ if (oktoprint == 0 /* can't printf */ || sxdots > 640 || sydots > 200) /* not willing to trust char cell size */ return(-1); /* sorry, message not displayed */ textydots = 8; textxdots = sxdots; } else { xrepeat = (sxdots >= 640) ? 2 : 1; yrepeat = (sydots >= 300) ? 2 : 1; textxdots = strlen(msg) * xrepeat * 8; textydots = yrepeat * 8; } /* worst case needs 10k */ if(temptextsave != 0) if(size != (long)textxdots * (long)textydots) freetempmsg(); size = (long)textxdots * (long)textydots; save_sxoffs = sxoffs; save_syoffs = syoffs; if (video_scroll) { sxoffs = video_startx; syoffs = video_starty; } else sxoffs = syoffs = 0; if(temptextsave == 0) /* only save screen first time called */ { if ((temptextsave = MemoryAlloc((U16)textxdots,(long)textydots,FARMEM)) == 0) return(-1); /* sorry, message not displayed */ for (i = 0; i < textydots; ++i) { get_line(i,0,textxdots-1,buffer); MoveToMemory(buffer,(U16)textxdots,1L,(long)i,temptextsave); } } if (fontptr == NULL) { /* bios must do it for us */ home(); printf(msg); } else { /* generate the characters */ find_special_colors(); /* get color_dark & color_medium set */ for (i = 0; i < 8; ++i) { memset(buffer,color_dark,640); bufptr = buffer; charnum = -1; while (msg[++charnum] != 0) { fontchar = *(fontptr + msg[charnum]*8 + i); for (j = 0; j < 8; ++j) { for (k = 0; k < xrepeat; ++k) { if ((fontchar & 0x80) != 0) *bufptr = (BYTE)color_medium; ++bufptr; } fontchar <<= 1; } } for (j = 0; j < yrepeat; ++j) put_line(i*yrepeat+j,0,textxdots-1,buffer); } } sxoffs = save_sxoffs; syoffs = save_syoffs; return(0); } void cleartempmsg() { BYTE buffer[640]; int i; int save_sxoffs,save_syoffs; if (dotmode == 11) /* disk video, easy */ dvid_status(0,""); else if (temptextsave != 0) { save_sxoffs = sxoffs; save_syoffs = syoffs; if (video_scroll) { sxoffs = video_startx; syoffs = video_starty; } else sxoffs = syoffs = 0; for (i = 0; i < textydots; ++i) { MoveFromMemory(buffer,(U16)textxdots,1L,(long)i,temptextsave); put_line(i,0,textxdots-1,buffer); } if(using_jiim == 0) /* jiim frees memory with freetempmsg() */ { MemoryRelease(temptextsave); temptextsave = 0; } sxoffs = save_sxoffs; syoffs = save_syoffs; } } void blankrows(int row,int rows,int attr) { char buf[81]; memset(buf,' ',80); buf[80] = 0; while (--rows >= 0) putstring(row++,0,attr,buf); } #if (_MSC_VER >= 700) #pragma code_seg ("realdos1_text") /* place following in an overlay */ #endif void helptitle() { char msg[MSGLEN],buf[MSGLEN]; setclear(); /* clear the screen */ #ifdef XFRACT strcpy(msg,"X"); #else *msg=0; #endif sprintf(buf,"FRACTINT Version %d.%01d",release/100,(release%100)/10); strcat(msg,buf); if (release%10) { sprintf(buf,"%01d",release%10); strcat(msg,buf); } if (patchlevel) { sprintf(buf,".%d",patchlevel); strcat(msg,buf); } putstringcenter(0,0,80,C_TITLE,msg); /* uncomment next for production executable: */ #ifdef PRODUCTION return; /*NOTREACHED*/ #else if (debugflag == 3002) return; #define DEVELOPMENT #ifdef DEVELOPMENT putstring(0,2,C_TITLE_DEV,"Development Version"); #else putstring(0,3,C_TITLE_DEV, s_custom); #endif putstring(0,55,C_TITLE_DEV,s_incremental); #endif } void footer_msg(int *i, int options, char *speedstring) { static FCODE choiceinstr1a[]="Use the cursor keys to highlight your selection"; static FCODE choiceinstr1b[]="Use the cursor keys or type a value to make a selection"; static FCODE choiceinstr2a[]="Press ENTER for highlighted choice, or ESCAPE to back out"; static FCODE choiceinstr2b[]="Press ENTER for highlighted choice, ESCAPE to back out, or F1 for help"; static FCODE choiceinstr2c[]="Press ENTER for highlighted choice, or "FK_F1" for help"; putstringcenter((*i)++,0,80,C_PROMPT_BKGRD, (speedstring) ? choiceinstr1b : choiceinstr1a); putstringcenter(*(i++),0,80,C_PROMPT_BKGRD, (options&CHOICEMENU) ? choiceinstr2c : ((options&CHOICEHELP) ? choiceinstr2b : choiceinstr2a)); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif int putstringcenter(int row, int col, int width, int attr, char far *msg) { char buf[81]; int i,j,k; i = 0; #ifdef XFRACT #if 0 if (width>=80) width=79; /* Some systems choke in column 80 */ #endif #endif while (msg[i]) ++i; /* strlen for a far */ if (i == 0) return(-1); if (i >= width) i = width - 1; /* sanity check */ j = (width - i) / 2; j -= (width + 10 - i) / 20; /* when wide a bit left of center looks better */ memset(buf,' ',width); buf[width] = 0; i = 0; k = j; while (msg[i]) buf[k++] = msg[i++]; /* strcpy for a far */ putstring(row,col,attr,buf); return j; } /* * The stackscreen()/unstackscreen() functions for XFRACT have been * moved to unix/video.c to more cleanly separate the XFRACT code. */ #ifndef XFRACT static int screenctr = -1; #define MAXSCREENS 3 static U16 savescreen[MAXSCREENS]; static int saverc[MAXSCREENS+1]; void stackscreen() { BYTE far *vidmem; int savebytes; int i; if (video_scroll) { scroll_state(0); /* save position */ scroll_center(0,0); } if(*s_makepar == 0) return; saverc[screenctr+1] = textrow*80 + textcol; if (++screenctr) { /* already have some stacked */ static char far msg[]={"stackscreen overflow"}; if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */ stopmsg(1,msg); exit(1); } vidmem = MK_FP(textaddr,0); savebytes = (text_type == 0) ? 4000 : 16384; savescreen[i] = MemoryAlloc((U16)savebytes,1L,FARMEM); if (savescreen[i] != 0) MoveToMemory(vidmem,(U16)savebytes,1L,0L,savescreen[i]); else { static char far msg[]={"insufficient memory, aborting"}; stopmsg(1,msg); exit(1); } setclear(); } else setfortext(); if (video_scroll) { if (boxcount) moveboxf(0.0,0.0); } } void unstackscreen() { BYTE far *vidmem; int savebytes; if(*s_makepar == 0) return; textrow = saverc[screenctr] / 80; textcol = saverc[screenctr] % 80; if (--screenctr >= 0) { /* unstack */ vidmem = MK_FP(textaddr,0); savebytes = (text_type == 0) ? 4000 : 16384; if (savescreen[screenctr] != 0) { MoveFromMemory(vidmem,(U16)savebytes,1L,0L,savescreen[screenctr]); MemoryRelease(savescreen[screenctr]); savescreen[screenctr] = 0; } } else setforgraphics(); movecursor(-1,-1); if (video_scroll) { if (boxcount) moveboxf(0.0,0.0); scroll_state(1); /* restore position */ } } void discardscreen() { if (--screenctr >= 0) { /* unstack */ if (savescreen[screenctr]) { MemoryRelease(savescreen[screenctr]); savescreen[screenctr] = 0; } } else discardgraphics(); } #endif /* ------------------------------------------------------------------------ */ char speed_prompt[]="Speed key string"; /* For file list purposes only, it's a directory name if first char is a dot or last char is a slash */ static int isadirname(char far *name) { if(*name == '.' || endswithslash(name)) return 1; else return 0; } #if (_MSC_VER >= 700) #pragma code_seg ("realdos1_text") /* place following in an overlay */ #endif void show_speedstring(int speedrow, char *speedstring, int (*speedprompt)(int,int,int,char *,int)) { int speed_match = 0; int i,j; char buf[81]; memset(buf,' ',80); buf[80] = 0; putstring(speedrow,0,C_PROMPT_BKGRD,buf); if (*speedstring) { /* got a speedstring on the go */ putstring(speedrow,15,C_CHOICE_SP_INSTR," "); if (speedprompt) j = speedprompt(speedrow,16,C_CHOICE_SP_INSTR,speedstring,speed_match); else { putstring(speedrow,16,C_CHOICE_SP_INSTR,speed_prompt); j = sizeof(speed_prompt)-1; } strcpy(buf,speedstring); i = strlen(buf); while (i < 30) buf[i++] = ' '; buf[i] = 0; putstring(speedrow,16+j,C_CHOICE_SP_INSTR," "); putstring(speedrow,17+j,C_CHOICE_SP_KEYIN,buf); movecursor(speedrow,17+j+strlen(speedstring)); } else movecursor(25,80); } void process_speedstring(char *speedstring, char far*far*choices, /* array of choice strings */ int curkey, int *pcurrent, int numchoices, int is_unsorted) { int i, comp_result; i = strlen(speedstring); if (curkey == 8 && i > 0) /* backspace */ speedstring[--i] = 0; if (33 <= curkey && curkey <= 126 && i < 30) { #ifndef XFRACT curkey = tolower(curkey); #endif speedstring[i] = (char)curkey; speedstring[++i] = 0; } if (i > 0) { /* locate matching type */ *pcurrent = 0; while (*pcurrent < numchoices && (comp_result = strncasecmp(speedstring,choices[*pcurrent],i))!=0) { if (comp_result < 0 && !is_unsorted) { *pcurrent -= *pcurrent ? 1 : 0; break; } else ++*pcurrent; } if (*pcurrent >= numchoices) /* bumped end of list */ *pcurrent = numchoices - 1; /*if the list is unsorted, and the entry found is not the exact entry, then go looking for the exact entry. */ else if (is_unsorted && choices[*pcurrent][i]) { int temp = *pcurrent; while(++temp < numchoices) { if (!choices[temp][i] && !strncasecmp(speedstring, choices[temp], i)) { *pcurrent = temp; break; } } } } } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif int fullscreen_choice( int options, /* &2 use menu coloring scheme */ /* &4 include F1 for help in instructions */ /* &8 add caller's instr after normal set */ /* &16 menu items up one line */ char far *hdg, /* heading info, \n delimited */ char far *hdg2, /* column heading or NULL */ char far *instr, /* instructions, \n delimited, or NULL */ int numchoices, /* How many choices in list */ char far*far*choices, /* array of choice strings */ int far *attributes, /* &3: 0 normal color, 1,3 highlight */ /* &256 marks a dummy entry */ int boxwidth, /* box width, 0 for calc (in items) */ int boxdepth, /* box depth, 0 for calc, 99 for max */ int colwidth, /* data width of a column, 0 for calc */ int current, /* start with this item */ void (*formatitem)(int,char*),/* routine to display an item or NULL */ char *speedstring, /* returned speed key value, or NULL */ int (*speedprompt)(int,int,int,char *,int),/* routine to display prompt or NULL */ int (*checkkey)(int,int) /* routine to check keystroke or NULL */ ) /* return is: n>=0 for choice n selected, -1 for escape k for checkkey routine return value k (if not 0 nor -1) speedstring[0] != 0 on return if string is present */ { int titlelines,titlewidth; int reqdrows; int topleftrow,topleftcol; int topleftchoice; int speedrow = 0; /* speed key prompt */ int boxitems; /* boxwidth*boxdepth */ int curkey,increment,rev_increment = 0; int redisplay; int i,j,k = 0; char far *charptr; char buf[81]; char curitem[81]; char far *itemptr; int ret,savelookatmouse; int scrunch; /* scrunch up a line */ if(options&CHOICESCRUNCH) scrunch = 1; else scrunch = 0; savelookatmouse = lookatmouse; lookatmouse = 0; ret = -1; if (speedstring && (i = strlen(speedstring)) > 0) { /* preset current to passed string */ current = 0; if(options&CHOICESNOTSORTED) { while (current < numchoices && (k = strncasecmp(speedstring,choices[current],i)) != 0) ++current; if(k != 0) current = 0; } else { while (current < numchoices && (k = strncasecmp(speedstring,choices[current],i)) > 0) ++current; if (k < 0 && current > 0) /* oops - overshot */ --current; } if (current >= numchoices) /* bumped end of list */ current = numchoices - 1; } for(;;) { if (current >= numchoices) /* no real choice in the list? */ goto fs_choice_end; if ((attributes[current] & 256) == 0) break; ++current; /* scan for a real choice */ } titlelines = titlewidth = 0; if (hdg) { charptr = hdg; /* count title lines, find widest */ i = 0; titlelines = 1; while (*charptr) { if (*(charptr++) == '\n') { ++titlelines; i = -1; } if (++i > titlewidth) titlewidth = i; } } if (colwidth == 0) /* find widest column */ for (i = 0; i < numchoices; ++i) { int len; if ((len=far_strlen(choices[i])) > colwidth) colwidth = len; } /* title(1), blank(1), hdg(n), blank(1), body(n), blank(1), instr(?) */ reqdrows = 3 - scrunch; /* calc rows available */ if (hdg) reqdrows += titlelines + 1; if (instr) { /* count instructions lines */ charptr = instr; ++reqdrows; while (*charptr) if (*(charptr++) == '\n') ++reqdrows; if ((options & 8)) /* show std instr too */ reqdrows += 2; } else reqdrows += 2; /* standard instructions */ if (speedstring) ++reqdrows; /* a row for speedkey prompt */ if (boxdepth > (i = 25 - reqdrows)) /* limit the depth to max */ boxdepth = i; if (boxwidth == 0) { /* pick box width and depth */ if (numchoices <= i - 2) { /* single column is 1st choice if we can */ boxdepth = numchoices; boxwidth = 1; } else { /* sort-of-wide is 2nd choice */ boxwidth = 60 / (colwidth + 1); if (boxwidth == 0 || (boxdepth = (numchoices+boxwidth-1)/boxwidth) > i - 2) { boxwidth = 80 / (colwidth + 1); /* last gasp, full width */ if ((boxdepth = (numchoices+boxwidth-1)/boxwidth) > i) boxdepth = i; } } } #if 0 if ((i = 77 / boxwidth - colwidth) > 3) /* spaces to add @ left each choice */ i = 3; if (i == 0) i = 1; #else if ((i = (80 / boxwidth - colwidth) / 2 - 1) == 0) /* to allow wider prompts */ i = 1; if (i < 0) i = 0; if (i > 3) i = 3; #endif j = boxwidth * (colwidth += i) + i; /* overall width of box */ if (j < titlewidth+2) j = titlewidth + 2; if (j > 80) j = 80; if (j <= 70 && boxwidth == 2) { /* special case makes menus nicer */ ++j; ++colwidth; } k = (80 - j) / 2; /* center the box */ k -= (90 - j) / 20; topleftcol = k + i; /* column of topleft choice */ i = (25 - reqdrows - boxdepth) / 2; i -= i / 4; /* higher is better if lots extra */ topleftrow = 3 + titlelines + i; /* row of topleft choice */ /* now set up the overall display */ helptitle(); /* clear, display title line */ setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest to background */ for (i = topleftrow-1-titlelines; i < topleftrow+boxdepth+1; ++i) setattr(i,k,C_PROMPT_LO,j); /* draw empty box */ if (hdg) { textcbase = (80 - titlewidth) / 2; /* set left margin for putstring */ textcbase -= (90 - titlewidth) / 20; /* put heading into box */ putstring(topleftrow-titlelines-1,0,C_PROMPT_HI,hdg); textcbase = 0; } if (hdg2) /* display 2nd heading */ putstring(topleftrow-1,topleftcol,C_PROMPT_MED,hdg2); i = topleftrow + boxdepth + 1; if (instr == NULL || (options & 8)) { /* display default instructions */ if (i < 20) ++i; if (speedstring) { speedrow = i; *speedstring = 0; if (++i < 22) ++i; } i -= scrunch; footer_msg(&i,options,speedstring); } if (instr) { /* display caller's instructions */ charptr = instr; j = -1; while ((buf[++j] = *(charptr++)) != 0) if (buf[j] == '\n') { buf[j] = 0; putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf); j = -1; } putstringcenter(i,0,80,C_PROMPT_BKGRD,buf); } boxitems = boxwidth * boxdepth; topleftchoice = 0; /* pick topleft for init display */ while (current - topleftchoice >= boxitems || (current - topleftchoice > boxitems/2 && topleftchoice + boxitems < numchoices)) topleftchoice += boxwidth; redisplay = 1; topleftrow -= scrunch; for(;;) { /* main loop */ if (redisplay) { /* display the current choices */ if ((options & CHOICEMENU) == 0) { memset(buf,' ',80); buf[boxwidth*colwidth] = 0; for (i = (hdg2) ? 0 : -1; i <= boxdepth; ++i) /* blank the box */ putstring(topleftrow+i,topleftcol,C_PROMPT_LO,buf); } for (i = 0; i+topleftchoice < numchoices && i < boxitems; ++i) { /* display the choices */ if ((k = attributes[j = i+topleftchoice] & 3) == 1) k = C_PROMPT_LO; else if (k == 3) k = C_PROMPT_HI; else k = C_PROMPT_MED; if (formatitem) { (*formatitem)(j,buf); charptr=buf; } else charptr = choices[j]; putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth, k,charptr); } /*** ... format differs for summary/detail, whups, force box width to ... be 72 when detail toggle available? (2 grey margin each ... side, 1 blue margin each side) ***/ if (topleftchoice > 0 && hdg2 == NULL) putstring(topleftrow-1,topleftcol,C_PROMPT_LO,"(more)"); if (topleftchoice + boxitems < numchoices) putstring(topleftrow+boxdepth,topleftcol,C_PROMPT_LO,"(more)"); redisplay = 0; } i = current - topleftchoice; /* highlight the current choice */ if (formatitem) { (*formatitem)(current,curitem); itemptr=curitem; } else itemptr = choices[current]; putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth, C_CHOICE_CURRENT,itemptr); if (speedstring) { /* show speedstring if any */ show_speedstring(speedrow,speedstring,speedprompt); } else movecursor(25,80); #ifndef XFRACT while (!keypressed()) { } /* enables help */ #else waitkeypressed(0); /* enables help */ #endif curkey = getakey(); #ifdef XFRACT if (curkey==F10) curkey=')'; if (curkey==F9) curkey='('; if (curkey==F8) curkey='*'; #endif i = current - topleftchoice; /* unhighlight current choice */ if ((k = attributes[current] & 3) == 1) k = C_PROMPT_LO; else if (k == 3) k = C_PROMPT_HI; else k = C_PROMPT_MED; putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth, k,itemptr); increment = 0; switch (curkey) { /* deal with input key */ case ENTER: case ENTER_2: ret = current; goto fs_choice_end; case ESC: goto fs_choice_end; case DOWN_ARROW: rev_increment = 0 - (increment = boxwidth); break; case DOWN_ARROW_2: rev_increment = 0 - (increment = boxwidth); { int newcurrent = current; while((newcurrent+=boxwidth) != current) { if(newcurrent >= numchoices) newcurrent = (newcurrent % boxwidth) - boxwidth; else if(!isadirname(choices[newcurrent])) { if(current != newcurrent) current = newcurrent - boxwidth; break; /* breaks the while loop */ } } } break; case UP_ARROW: increment = 0 - (rev_increment = boxwidth); break; case UP_ARROW_2: increment = 0 - (rev_increment = boxwidth); { int newcurrent = current; while((newcurrent-=boxwidth) != current) { if(newcurrent < 0) { newcurrent = (numchoices - current) % boxwidth; newcurrent = numchoices + (newcurrent ? boxwidth - newcurrent: 0); } else if(!isadirname(choices[newcurrent])) { if(current != newcurrent) current = newcurrent + boxwidth; break; /* breaks the while loop */ } } } break; case RIGHT_ARROW: increment = 1; rev_increment = -1; break; case RIGHT_ARROW_2: /* move to next file; if at last file, go to first file */ increment = 1; rev_increment = -1; { int newcurrent = current; while(++newcurrent != current) { if(newcurrent >= numchoices) newcurrent = -1; else if(!isadirname(choices[newcurrent])) { if(current != newcurrent) current = newcurrent - 1; break; /* breaks the while loop */ } } } break; case LEFT_ARROW: increment = -1; rev_increment = 1; break; case LEFT_ARROW_2: /* move to previous file; if at first file, go to last file */ increment = -1; rev_increment = 1; { int newcurrent = current; while(--newcurrent != current) { if(newcurrent < 0) newcurrent = numchoices; else if(!isadirname(choices[newcurrent])) { if(current != newcurrent) current = newcurrent + 1; break; /* breaks the while loop */ } } } break; case PAGE_UP: if (numchoices > boxitems) { topleftchoice -= boxitems; increment = -boxitems; rev_increment = boxwidth; redisplay = 1; } break; case PAGE_DOWN: if (numchoices > boxitems) { topleftchoice += boxitems; increment = boxitems; rev_increment = -boxwidth; redisplay = 1; } break; case HOME: current = -1; increment = rev_increment = 1; break; case CTL_HOME: current = -1; increment = rev_increment = 1; { int newcurrent; for(newcurrent = 0; newcurrent < numchoices; ++newcurrent) { if(!isadirname(choices[newcurrent])) { current = newcurrent - 1; break; /* breaks the for loop */ } } } break; case END: current = numchoices; increment = rev_increment = -1; break; case CTL_END: current = numchoices; increment = rev_increment = -1; { int newcurrent; for(newcurrent = numchoices - 1; newcurrent >= 0; --newcurrent) { if(!isadirname(choices[newcurrent])) { current = newcurrent + 1; break; /* breaks the for loop */ } } } break; default: if (checkkey) { if ((ret = (*checkkey)(curkey,current)) < -1 || ret > 0) goto fs_choice_end; if (ret == -1) redisplay = -1; } ret = -1; if (speedstring) { process_speedstring(speedstring,choices,curkey,¤t, numchoices,options&CHOICESNOTSORTED); } break; } if (increment) { /* apply cursor movement */ current += increment; if (speedstring) /* zap speedstring */ speedstring[0] = 0; } for(;;) { /* adjust to a non-comment choice */ if (current < 0 || current >= numchoices) increment = rev_increment; else if ((attributes[current] & 256) == 0) break; current += increment; } if (topleftchoice > numchoices - boxitems) topleftchoice = ((numchoices+boxwidth-1)/boxwidth)*boxwidth - boxitems; if (topleftchoice < 0) topleftchoice = 0; while (current < topleftchoice) { topleftchoice -= boxwidth; redisplay = 1; } while (current >= topleftchoice + boxitems) { topleftchoice += boxwidth; redisplay = 1; } } fs_choice_end: lookatmouse = savelookatmouse; return(ret); } #if (_MSC_VER >= 700) #pragma code_seg ("realdos1_text") /* place following in an overlay */ #endif /* squeeze space out of string */ char *despace(char *str) { char *obuf, *nbuf; for (obuf = str, nbuf = str; *obuf && obuf; ++obuf) { if (!isspace(*obuf)) *nbuf++ = *obuf; } *nbuf = 0; return str; } #ifndef XFRACT /* case independent version of strncmp */ int strncasecmp(char far *s,char far *t,int ct) { for(; (tolower(*s) == tolower(*t)) && --ct ; s++,t++) if(*s == '\0') return(0); return(tolower(*s) - tolower(*t)); } #endif #define LOADPROMPTSCHOICES(X,Y) {\ static FCODE tmp[] = { Y };\ choices[X]= (char far *)tmp;\ } int exitpending = 0; static int menutype; #define MENU_HDG 3 #define MENU_ITEM 1 int check_exit() { int i; static char far s[] = "Exit from "Fractint" (y/n)? y"; exitpending = 1; helptitle(); setattr(1,0,C_GENERAL_MED,24*80); for (i = 9; i <= 11; ++i) setattr(i,18,C_GENERAL_INPUT,40); putstringcenter(10,18,40,C_GENERAL_INPUT,s); movecursor(25,80); while ((i = getakey()) != 'y' && i != 'Y' && i != 13) { if (i == 'n' || i == 'N') { exitpending = 0; return 0; } } goodbye(); return 1; } int main_menu(int fullmenu) { char far *choices[44]; /* 2 columns * 22 rows */ int attributes[44]; int choicekey[44]; int i; int nextleft,nextright; int oldtabmode /* ,oldhelpmode */; static char far MAIN_MENU[] = {"MAIN MENU"}; int showjuliatoggle; oldtabmode = tabmode; /* oldhelpmode = helpmode; */ top: menutype = fullmenu; tabmode = 0; showjuliatoggle = 0; for (i = 0; i < 44; ++i) { attributes[i] = 256; choices[i] = ""; choicekey[i] = -1; } nextleft = -2; nextright = -1; if (fullmenu) { LOADPROMPTSCHOICES(nextleft+=2," CURRENT IMAGE "); attributes[nextleft] = 256+MENU_HDG; choicekey[nextleft+=2] = 13; /* enter */ attributes[nextleft] = MENU_ITEM; if (calc_status == 2) { LOADPROMPTSCHOICES(nextleft,"continue calculation "); } else { LOADPROMPTSCHOICES(nextleft,"return to image "); } choicekey[nextleft+=2] = 9; /* tab */ attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"info about image "); choicekey[nextleft+=2] = 'o'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"orbits window "); if(!(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA)) nextleft+=2; } LOADPROMPTSCHOICES(nextleft+=2," NEW IMAGE "); attributes[nextleft] = 256+MENU_HDG; #ifdef XFRACT choicekey[nextleft+=2] = DELETE; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"draw fractal "); #else choicekey[nextleft+=2] = DELETE; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"select video mode... "); #endif choicekey[nextleft+=2] = 't'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"select fractal type "); if (fullmenu) { if ((curfractalspecific->tojulia != NOFRACTAL && param[0] == 0.0 && param[1] == 0.0) || curfractalspecific->tomandel != NOFRACTAL) { choicekey[nextleft+=2] = ' '; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"toggle to/from julia "); showjuliatoggle = 1; } if(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA) { choicekey[nextleft+=2] = 'j'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"toggle to/from inverse "); showjuliatoggle = 1; } choicekey[nextleft+=2] = 'h'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"return to prior image "); choicekey[nextleft+=2] = 8; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"reverse thru history "); } else nextleft += 2; LOADPROMPTSCHOICES(nextleft+=2," OPTIONS "); attributes[nextleft] = 256+MENU_HDG; choicekey[nextleft+=2] = 'x'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"basic options... "); choicekey[nextleft+=2] = 'y'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"extended options... "); choicekey[nextleft+=2] = 'z'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"type-specific parms... "); choicekey[nextleft+=2] = 'p'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"passes options...

key */ int passes_options(void) { static FCODE o_hdg[]={"Passes Options\n\ (not all combinations make sense)"}; static FCODE pressf2[] = {"\n(Press "FK_F2" for corner parameters)"}; static FCODE pressf6[] = {"\n(Press "FK_F6" for calculation parameters)"}; char hdg[sizeof(o_hdg)+sizeof(pressf2)+sizeof(pressf6)]; char far *ptr; char far *choices[20]; int oldhelpmode; char *passcalcmodes[] ={"rect","line"}; /* char *passcalcmodes[] ={"rect","line","func"}; */ struct fullscreenvalues uvalues[25]; int i, j, k; int ret; int old_periodicity, old_orbit_delay, old_orbit_interval; int old_keep_scrn_coords; char old_drawmode; far_strcpy(hdg,o_hdg); far_strcat(hdg,pressf2); far_strcat(hdg,pressf6); ptr = (char far *)MK_FP(extraseg,0); ret = 0; pass_option_restart: /* fill up the choices (and previous values) arrays */ k = -1; LOADCHOICES("Periodicity (0=off, <0=show, >0=on, -255..+255)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_periodicity = usr_periodicitycheck; LOADCHOICES("Orbit delay (0 = none)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_orbit_delay = orbit_delay; LOADCHOICES("Orbit interval (1 ... 255)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_orbit_interval = (int)orbit_interval; LOADCHOICES("Maintain screen coordinates"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = old_keep_scrn_coords = keep_scrn_coords; LOADCHOICES("Orbit pass shape (rect,line)"); /* LOADCHOICES("Orbit pass shape (rect,line,func)"); */ uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 5; uvalues[k].uval.ch.llen = sizeof(passcalcmodes)/sizeof(*passcalcmodes); uvalues[k].uval.ch.list = passcalcmodes; uvalues[k].uval.ch.val = (drawmode == 'r') ? 0 : (drawmode == 'l') ? 1 : /* function */ 2; old_drawmode = drawmode; oldhelpmode = helpmode; helpmode = HELPPOPTS; i = fullscreen_prompt(hdg,k+1,choices,uvalues,0x44,NULL); helpmode = oldhelpmode; if (i < 0) { return(-1); } /* now check out the results (*hopefully* in the same order ) */ k = -1; j = 0; /* return code */ usr_periodicitycheck = uvalues[++k].uval.ival; if (usr_periodicitycheck > 255) usr_periodicitycheck = 255; if (usr_periodicitycheck < -255) usr_periodicitycheck = -255; if (usr_periodicitycheck != old_periodicity) j = 1; orbit_delay = uvalues[++k].uval.ival; if (orbit_delay != old_orbit_delay) j = 1; orbit_interval = uvalues[++k].uval.ival; if (orbit_interval > 255) orbit_interval = 255; if (orbit_interval < 1) orbit_interval = 1; if (orbit_interval != old_orbit_interval) j = 1; keep_scrn_coords = uvalues[++k].uval.ch.val; if (keep_scrn_coords != old_keep_scrn_coords) j = 1; if (keep_scrn_coords == 0) set_orbit_corners = 0; { int tmp; tmp = uvalues[++k].uval.ch.val; switch (tmp) { default: case 0: drawmode = 'r'; break; case 1: drawmode = 'l'; break; case 2: drawmode = 'f'; break; } } if (drawmode != old_drawmode) j = 1; if (i == F2) { if (get_screen_corners() > 0) { ret = 1; } if (j) ret = 1; goto pass_option_restart; } if (i == F6) { if (get_corners() > 0) { ret = 1; } if (j) ret = 1; goto pass_option_restart; } return(j + ret); } /* for videomodes added new options "virtual x/y" that change "sx/ydots" */ /* for diskmode changed "viewx/ydots" to "virtual x/y" that do as above */ /* (since for diskmode they were updated by x/ydots that should be the */ /* same as sx/ydots for that mode) */ /* videotable and videoentry are now updated even for non-disk modes */ /* --------------------------------------------------------------------- */ /* get_view_params() is called from FRACTINT.C whenever the 'v' key is pressed. Return codes are: -1 routine was ESCAPEd - no need to re-generate the image. 0 minor variable changed. No need to re-generate the image. 1 View changed. Re-generate the image. */ int get_view_params() { static FCODE o_hdg[]={"View Window Options"}; char hdg[sizeof(o_hdg)]; char far *choices[16]; char far *ptr; int oldhelpmode; struct fullscreenvalues uvalues[25]; int i, k; float old_viewreduction,old_aspectratio; int old_viewwindow,old_viewxdots,old_viewydots,old_sxdots,old_sydots; unsigned long estm_xmax=32767,estm_ymax=32767; #ifndef XFRACT unsigned long vidmem = (unsigned long)video_vram << 16; int truebytes = videoentry.dotmode/1000; if (dotmode == 28) /* setvideo might have changed mode 27 to 28 */ dotmode = videoentry.dotmode%100; #endif far_strcpy(hdg,o_hdg); ptr = (char far *)MK_FP(extraseg,0); /* Because the scrolling (and virtual screen width) must be aligned to 8 bytes, that gives: 8 pixels for 8 bit (truebytes == 0; ++truebytes == 1;) 4 pixels for 15 bit (truebytes == 1; ++truebytes == 2;) 4 pixels for 16 bit (truebytes == 2;) 8 pixels for 24 bit (truebytes == 3;) 2 pixels for 32 bit (truebytes == 4;) so for odd truebytes (8 and 24 bit) it does &= ..FFF8 (&= -8) if truebytes==2 (15 and 16 bit) it does &= ..FFFC (&= -4) if truebytes==4 (32 bit) it does &= ..FFFE (&= -2) */ #ifndef XFRACT if (dotmode == 28 && virtual) { /* virtual screen limits estimation */ if (truebytes < 2) ++truebytes; vidmem /= truebytes; if (vesa_yres) estm_xmax = min(vidmem/vesa_yres,estm_xmax); else estm_xmax = 0; if (vesa_xres) estm_ymax = min(vidmem/vesa_xres,estm_ymax); else estm_ymax = 0; estm_xmax &= truebytes&1 ? -8 : truebytes - 6; } #endif old_viewwindow = viewwindow; old_viewreduction = viewreduction; old_aspectratio = finalaspectratio; old_viewxdots = viewxdots; old_viewydots = viewydots; old_sxdots = sxdots; old_sydots = sydots; get_view_restart: /* fill up the previous values arrays */ k = -1; if (dotmode != 11) { LOADCHOICES("Preview display? (no for full screen)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = viewwindow; LOADCHOICES("Auto window size reduction factor"); uvalues[k].type = 'f'; uvalues[k].uval.dval = viewreduction; LOADCHOICES("Final media overall aspect ratio, y/x"); uvalues[k].type = 'f'; uvalues[k].uval.dval = finalaspectratio; LOADCHOICES("Crop starting coordinates to new aspect ratio?"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = viewcrop; LOADCHOICES("Explicit size x pixels (0 for auto size)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = viewxdots; LOADCHOICES(" y pixels (0 to base on aspect ratio)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = viewydots; } LOADCHOICES(""); uvalues[k].type = '*'; #ifndef XFRACT if (virtual && dotmode == 28 && chkd_vvs && !video_scroll) { LOADCHOICES("Your graphics card does NOT support virtual screens."); uvalues[k].type = '*'; } #endif if (dotmode == 11 || (virtual && dotmode == 28)) { LOADCHOICES("Virtual screen total x pixels"); uvalues[k].type = 'i'; uvalues[k].uval.ival = sxdots; if (dotmode == 11) { LOADCHOICES(" y pixels"); } else { LOADCHOICES(" y pixels (0: by aspect ratio)"); } uvalues[k].type = 'i'; uvalues[k].uval.ival = sydots; } #ifndef XFRACT if (virtual && dotmode == 28) { char dim[50]; static FCODE xmsg[] = {"Video memory limits: (for y = "}; static FCODE ymsg[] = {" (for x = "}; static FCODE midxmsg[] = {") x <= "}; static FCODE midymsg[] = {") y <= "}; char *scrolltypes[] ={"fixed","relaxed"}; LOADCHOICES("Keep aspect? (cuts both x & y when either too big)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = video_cutboth; LOADCHOICES("Zoombox scrolling (f[ixed], r[elaxed])"); uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 7; uvalues[k].uval.ch.llen = sizeof(scrolltypes)/sizeof(*scrolltypes); uvalues[k].uval.ch.list = scrolltypes; uvalues[k].uval.ch.val = zscroll; LOADCHOICES(""); uvalues[k].type = '*'; sprintf(dim,"%Fs%4u%Fs%lu",(char far *)xmsg,vesa_yres,(char far *)midxmsg,estm_xmax); far_strcpy(ptr,(char far *)dim); choices[++k]= ptr; ptr += sizeof(dim); uvalues[k].type = '*'; sprintf(dim,"%Fs%4u%Fs%lu",(char far *)ymsg,vesa_xres,(char far *)midymsg,estm_ymax); far_strcpy(ptr,(char far *)dim); choices[++k]= ptr; ptr += sizeof(dim); uvalues[k].type = '*'; LOADCHOICES(""); uvalues[k].type = '*'; } #endif if (dotmode != 11) { LOADCHOICES("Press "FK_F4" to reset view parameters to defaults."); uvalues[k].type = '*'; } oldhelpmode = helpmode; /* this prevents HELP from activating */ helpmode = HELPVIEW; i = fullscreen_prompt(hdg,k+1,choices,uvalues,16,NULL); helpmode = oldhelpmode; /* re-enable HELP */ if (i < 0) { return(-1); } if (i == F4 && dotmode != 11) { viewwindow = viewxdots = viewydots = 0; viewreduction = (float)4.2; viewcrop = 1; finalaspectratio = screenaspect; if (dotmode == 28) { sxdots = vesa_xres ? vesa_xres : old_sxdots; sydots = vesa_yres ? vesa_yres : old_sydots; video_cutboth = 1; zscroll = 1; } goto get_view_restart; } /* now check out the results (*hopefully* in the same order ) */ k = -1; if (dotmode != 11) { viewwindow = uvalues[++k].uval.ch.val; viewreduction = (float)uvalues[++k].uval.dval; finalaspectratio = (float)uvalues[++k].uval.dval; viewcrop = uvalues[++k].uval.ch.val; viewxdots = uvalues[++k].uval.ival; viewydots = uvalues[++k].uval.ival; } ++k; if (virtual && dotmode == 28 && chkd_vvs && !video_scroll) ++k; /* add 1 if not supported line is inserted */ if (dotmode == 11 || (virtual && dotmode == 28)) { sxdots = uvalues[++k].uval.ival; sydots = uvalues[++k].uval.ival; #ifndef XFRACT video_cutboth = uvalues[++k].uval.ch.val; zscroll = uvalues[++k].uval.ch.val; #endif if ((unsigned long)sxdots > estm_xmax) sxdots = (int)estm_xmax; #ifndef XFRACT sxdots &= truebytes&1 ? -8 : truebytes - 6; #endif if (sxdots < 2) sxdots = 2; if (sydots == 0 && dotmode == 28) { /* auto by aspect ratio request */ if (finalaspectratio == 0.0) { if (viewwindow && viewxdots != 0 && viewydots != 0) finalaspectratio = (float)viewydots/viewxdots; else finalaspectratio = old_aspectratio; } sydots = (int)(finalaspectratio * sxdots + 0.5); } if ((unsigned long)sydots > estm_ymax) sydots = (int)estm_ymax; if (sydots < 2) sydots = 2; } #ifndef XFRACT if (virtual && dotmode == 28) { /* virtual screen smaller than physical screen, use view window */ if (sxdots < vesa_xres && sydots < vesa_yres) { viewwindow = 1; viewxdots = sxdots; viewydots = sydots; sxdots = vesa_xres; sydots = vesa_yres; } else { viewwindow = 0; /* make sure it is off */ viewxdots = 0; viewydots = 0; } /* if virtual screen is too large */ if( (unsigned long)((sxdots < vesa_xres) ? vesa_xres : sxdots) * ((sydots < vesa_yres) ? vesa_yres : sydots) > vidmem) { /* and we have to keep ratio */ if (video_cutboth) { double tmp,virtaspect = (double)sydots / sxdots; /* we need vidmem >= x * y == x * x * virtaspect */ tmp = sqrt(vidmem / virtaspect); sxdots = (tmp > (double)estm_xmax) ? (int)estm_xmax : (int)tmp; sxdots &= truebytes&1 ? -8 : truebytes - 6; if (sxdots < 2) sxdots = 2; tmp = sxdots * virtaspect; sydots = (tmp > (double)estm_ymax) ? (int)estm_ymax : (int)tmp; /* if sydots < 2 here, then sxdots > estm_xmax */ } else { /* cut only the y value */ sydots = (int)((double)vidmem / ((sxdots < vesa_xres) ? vesa_xres : sxdots)); } } } #endif if (dotmode == 11 || (virtual && dotmode == 28)) { videoentry.xdots = sxdots; videoentry.ydots = sydots; far_memcpy((char far *)&videotable[adapter],(char far *)&videoentry, sizeof(videoentry)); if (finalaspectratio == 0.0) finalaspectratio = (float)sydots/sxdots; } if (viewxdots != 0 && viewydots != 0 && viewwindow && finalaspectratio == 0.0) finalaspectratio = (float)viewydots/viewxdots; else if (finalaspectratio == 0.0 && (viewxdots == 0 || viewydots == 0)) finalaspectratio = old_aspectratio; if (finalaspectratio != old_aspectratio && viewcrop) aspectratio_crop(old_aspectratio,finalaspectratio); i = 0; if (viewwindow != old_viewwindow || sxdots != old_sxdots || sydots != old_sydots || (viewwindow && ( viewreduction != old_viewreduction || finalaspectratio != old_aspectratio || viewxdots != old_viewxdots || (viewydots != old_viewydots && viewxdots) ) ) ) i = 1; return(i); } /* get_cmd_string() is called from FRACTINT.C whenever the 'g' key is pressed. Return codes are: -1 routine was ESCAPEd - no need to re-generate the image. 0 parameter changed, no need to regenerate >0 parameter changed, regenerate */ int get_cmd_string() { static FCODE o_msg[] = {"Enter command string to use."}; char msg[sizeof(o_msg)]; int oldhelpmode; int i; static char cmdbuf[61]; far_strcpy(msg,o_msg); oldhelpmode = helpmode; helpmode = HELPCOMMANDS; i = field_prompt(0,msg,NULL,cmdbuf,60,NULL); helpmode = oldhelpmode; if (i >= 0 && cmdbuf[0] != 0) { i = cmdarg(cmdbuf, 2); if(debugflag == 98) { backwards_v18(); backwards_v19(); backwards_v20(); } } return(i); } /* --------------------------------------------------------------------- */ int Distribution = 30, Offset = 0, Slope = 25; long con; double starfield_values[4] = { 30.0,100.0,5.0,0.0 }; char GreyFile[] = "altern.map"; int starfield(void) { int c; busy = 1; if (starfield_values[0] < 1.0) starfield_values[0] = 1.0; if (starfield_values[0] > 100.0) starfield_values[0] = 100.0; if (starfield_values[1] < 1.0) starfield_values[1] = 1.0; if (starfield_values[1] > 100.0) starfield_values[1] = 100.0; if (starfield_values[2] < 1.0) starfield_values[2] = 1.0; if (starfield_values[2] > 100.0) starfield_values[2] = 100.0; Distribution = (int)(starfield_values[0]); con = (long)(((starfield_values[1]) / 100.0) * (1L << 16)); Slope = (int)(starfield_values[2]); if (ValidateLuts(GreyFile) != 0) { static FCODE msg[]={"Unable to load ALTERN.MAP"}; stopmsg(0,msg); busy = 0; return(-1); } spindac(0,1); /* load it, but don't spin */ for(row = 0; row < ydots; row++) { for(col = 0; col < xdots; col++) { if(keypressed()) { buzzer(1); busy = 0; return(1); } c = getcolor(col, row); if(c == inside) c = colors-1; putcolor(col, row, GausianNumber(c, colors)); } } buzzer(0); busy = 0; return(0); } int get_starfield_params(void) { static FCODE o_hdg[]={"Starfield Parameters"}; static FCODE o_sf1[] = {"Star Density in Pixels per Star"}; static FCODE o_sf2[] = {"Percent Clumpiness"}; static FCODE o_sf3[] = {"Ratio of Dim stars to Bright"}; char hdg[sizeof(o_hdg)]; char sf1[sizeof(o_sf1)]; char sf2[sizeof(o_sf2)]; char sf3[sizeof(o_sf3)]; struct fullscreenvalues uvalues[3]; int oldhelpmode; int i; char far *starfield_prompts[3]; far_strcpy(hdg,o_hdg); far_strcpy(sf1,o_sf1); far_strcpy(sf2,o_sf2); far_strcpy(sf3,o_sf3); starfield_prompts[0] = sf1; starfield_prompts[1] = sf2; starfield_prompts[2] = sf3; if(colors < 255) { static FCODE msg[]={"starfield requires 256 color mode"}; stopmsg(0,msg); return(-1); } for (i = 0; i < 3; i++) { uvalues[i].uval.dval = starfield_values[i]; uvalues[i].type = 'f'; } stackscreen(); oldhelpmode = helpmode; helpmode = HELPSTARFLD; i = fullscreen_prompt(hdg,3,starfield_prompts,uvalues,0,NULL); helpmode = oldhelpmode; unstackscreen(); if (i < 0) { return(-1); } for (i = 0; i < 3; i++) starfield_values[i] = uvalues[i].uval.dval; return(0); } static char *masks[] = {"*.pot","*.gif"}; int get_rds_params(void) { static FCODE o_hdg[] = {"Random Dot Stereogram Parameters"}; static FCODE o_rds0[] = {"Depth Effect (negative reverses front and back)"}; static FCODE o_rds1[] = {"Image width in inches"}; static FCODE o_rds2[] = {"Use grayscale value for depth? (if \"no\" uses color number)"}; static FCODE o_rds3[] = {"Calibration bars"}; static FCODE o_rds4[] = {"Use image map? (if \"no\" uses random dots)"}; static FCODE o_rds5[] = {" If yes, use current image map name? (see below)"}; char hdg[sizeof(o_hdg)]; char rds0[sizeof(o_rds0)]; char rds1[sizeof(o_rds1)]; char rds2[sizeof(o_rds2)]; char rds3[sizeof(o_rds3)]; char rds4[sizeof(o_rds4)]; char rds5[sizeof(o_rds5)]; char rds6[60]; char *stereobars[] = {"none", "middle", "top"}; struct fullscreenvalues uvalues[7]; char far *rds_prompts[7]; int oldhelpmode; int i,k; int ret; static char reuse = 0; stackscreen(); for(;;) { ret = 0; /* copy to make safe from overlay change */ far_strcpy(hdg,o_hdg); far_strcpy(rds0,o_rds0); far_strcpy(rds1,o_rds1); far_strcpy(rds2,o_rds2); far_strcpy(rds3,o_rds3); far_strcpy(rds4,o_rds4); far_strcpy(rds5,o_rds5); rds_prompts[0] = rds0; rds_prompts[1] = rds1; rds_prompts[2] = rds2; rds_prompts[3] = rds3; rds_prompts[4] = rds4; rds_prompts[5] = rds5; rds_prompts[6] = rds6; k=0; uvalues[k].uval.ival = AutoStereo_depth; uvalues[k++].type = 'i'; uvalues[k].uval.dval = AutoStereo_width; uvalues[k++].type = 'f'; uvalues[k].uval.ch.val = grayflag; uvalues[k++].type = 'y'; uvalues[k].type = 'l'; uvalues[k].uval.ch.list = stereobars; uvalues[k].uval.ch.vlen = 6; uvalues[k].uval.ch.llen = 3; uvalues[k++].uval.ch.val = calibrate; uvalues[k].uval.ch.val = image_map; uvalues[k++].type = 'y'; if(*stereomapname != 0 && image_map) { char *p; uvalues[k].uval.ch.val = reuse; uvalues[k++].type = 'y'; uvalues[k++].type = '*'; for(i=0;i) */ k = -1; *x = uvalues[++k].uval.dval; *y = uvalues[++k].uval.dval; unstackscreen(); return(i); } /* --------------------------------------------------------------------- */ int get_commands() /* execute commands from file */ { int ret; FILE *parmfile; long point; int oldhelpmode; ret = 0; oldhelpmode = helpmode; helpmode = HELPPARMFILE; if ((point = get_file_entry(GETPARM,"Parameter Set", commandmask,CommandFile,CommandName)) >= 0 && (parmfile = fopen(CommandFile,"rb")) != NULL) { fseek(parmfile,point,SEEK_SET); ret = load_commands(parmfile); } helpmode = oldhelpmode; return(ret); } /* --------------------------------------------------------------------- */ void goodbye() /* we done. Bail out */ { char goodbyemessage[40]; int ret; static FCODE gbm[]={" Thank You for using "FRACTINT}; #ifndef XFRACT union REGS r; #endif if (resume_info != 0) end_resume(); if (evolve_handle != 0) MemoryRelease(evolve_handle); if (gene_handle != 0) MemoryRelease(gene_handle); if (imgboxhandle != 0 || prmboxhandle != 0) ReleaseParamBox(); if (history != 0) MemoryRelease(history); if (oldhistory_handle != 0) MemoryRelease(oldhistory_handle); enddisk(); discardgraphics(); ExitCheck(); far_strcpy(goodbyemessage, gbm); #ifdef WINFRACT return; #endif if(*s_makepar != 0) setvideotext(); #ifdef XFRACT UnixDone(); printf("\n\n\n%s\n",goodbyemessage); /* printf takes far pointer */ #else if(*s_makepar != 0) { r.h.al = (char)((mode7text == 0) ? exitmode : 7); r.h.ah = 0; int86(0x10, &r, &r); printf("\n\n\n%s\n",goodbyemessage); /* printf takes far pointer */ } #endif if(*s_makepar != 0) { movecursor(6,0); discardgraphics(); /* if any emm/xmm tied up there, release it */ } stopslideshow(); end_help(); ret = 0; if (initbatch == 3) /* exit with error code for batch file */ ret = 2; else if (initbatch == 4) ret = 1; exit(ret); } /* --------------------------------------------------------------------- */ #ifdef XFRACT static char searchdir[FILE_MAX_DIR]; static char searchname[FILE_MAX_PATH]; static char searchext[FILE_MAX_EXT]; static DIR *currdir = NULL; #endif int fr_findfirst(char *path) /* Find 1st file (or subdir) meeting path/filespec */ { #ifndef XFRACT union REGS regs; regs.h.ah = 0x1A; /* Set DTA to filedata */ regs.x.dx = (unsigned)&DTA; intdos(®s, ®s); regs.h.ah = 0x4E; /* Find 1st file meeting path */ regs.x.dx = (unsigned)path; regs.x.cx = FILEATTR; intdos(®s, ®s); return(regs.x.ax); /* Return error code */ #else if (currdir != NULL) { closedir(currdir); currdir = NULL; } splitpath(path,NULL,searchdir,searchname,searchext); if (searchdir[0]=='\0') { currdir = opendir("."); } else { currdir = opendir(searchdir); } if (currdir==NULL) { return -1; } else { return fr_findnext(); } #endif } int fr_findnext() /* Find next file (or subdir) meeting above path/filespec */ { #ifndef XFRACT union REGS regs; regs.h.ah = 0x4F; /* Find next file meeting path */ regs.x.dx = (unsigned)&DTA; intdos(®s, ®s); return(regs.x.ax); #else #ifdef DIRENT struct dirent *dirEntry; #else struct direct *dirEntry; #endif struct stat sbuf; char thisname[FILE_MAX_PATH]; char tmpname[FILE_MAX_PATH]; char thisext[FILE_MAX_EXT]; for(;;) { dirEntry = readdir(currdir); if (dirEntry == NULL) { closedir(currdir); currdir = NULL; return -1; } else if (dirEntry->d_ino != 0) { splitpath(dirEntry->d_name,NULL,NULL,thisname,thisext); strncpy(DTA.filename,dirEntry->d_name,MAX_NAME); DTA.filename[MAX_NAME-1]='\0'; strcpy(tmpname,searchdir); strcat(tmpname,dirEntry->d_name); stat(tmpname,&sbuf); DTA.size = sbuf.st_size; if ((sbuf.st_mode&S_IFMT)==S_IFREG && (searchname[0]=='*' || strcmp(searchname,thisname)==0) && (searchext[0]=='*' || strcmp(searchext,thisext)==0)) { DTA.attribute = 0; return 0; } else if (((sbuf.st_mode&S_IFMT)==S_IFDIR) && ((searchname[0]=='*' || searchext[0]=='*') || (strcmp(searchname,thisname)==0))) { DTA.attribute = SUBDIR; return 0; } } } #endif } #if 0 void heap_sort(void far *ra1, int n, unsigned sz, int (__cdecl *fct)(VOIDFARPTR arg1,VOIDFARPTR arg2)) { int ll,j,ir,i; void far *rra; char far *ra; ra = (char far *)ra1; ra -= sz; ll=(n>>1)+1; ir=n; for(;;) { if(ll>1) rra = *((char far *far *)(ra+(--ll)*sz)); else { rra = *((char far * far *)(ra+ir*sz)); *((char far * far *)(ra+ir*sz))=*((char far * far *)(ra+sz)); if(--ir == 1) { *((char far * far *)(ra+sz))=rra; return; } } i = ll; j = ll <<1; while (j <= ir) { if(jname,DTA.filename,MAX_NAME); choices[filecount]->name[MAX_NAME-1] = '\0'; choices[filecount]->type = 1; dircount++; if(strcmp(DTA.filename,"..")==0) notroot = 1; } out = fr_findnext(); } tmpmask[masklen] = 0; if(template[0]) makepath(tmpmask,drive,dir,fname,ext); do { if(numtemplates > 1) strcpy(&(tmpmask[masklen]),masks[j]); out = fr_findfirst(tmpmask); while(out == 0 && filecount < MAXNUMFILES) { if(!(DTA.attribute & SUBDIR)) { if(rds) { sprintf(speedstr,"%s",DTA.filename); putstringcenter(2,0,80,C_GENERAL_INPUT,speedstr); splitpath(DTA.filename,NULL,NULL,fname,ext); /* just using speedstr as a handy buffer */ makepath(speedstr,drive,dir,fname,ext); #ifndef XFRACT strlwr(DTA.filename); #endif far_strncpy(choices[++filecount]->name,DTA.filename,MAX_NAME); choices[filecount]->type = 0; } else { #ifndef XFRACT strlwr(DTA.filename); #endif far_strncpy(choices[++filecount]->name,DTA.filename,MAX_NAME); choices[filecount]->type = 0; } } out = fr_findnext(); } } while (++j < numtemplates); if (++filecount == 0) { far_strcpy(choices[filecount]->name,"*nofiles*"); choices[filecount]->type = 0; ++filecount; } far_strcpy(instr,o_instr); if(dosort) { far_strcat(instr,"off"); shell_sort((void far *far*)choices,filecount,sizeof(char far *),lccompare); /* sort file list */ } else far_strcat(instr,"on"); if(notroot == 0 && dir[0] && dir[0] != SLASHC) /* must be in root directory */ { splitpath(tmpmask,drive,dir,fname,ext); strcpy(dir,SLASH); makepath(tmpmask,drive,dir,fname,ext); } if(numtemplates > 1) { strcat(tmpmask," "); strcat(tmpmask,masks[0]); } strcpy(temp1,hdg); strcat(temp1,"\nTemplate: "); strcat(temp1,tmpmask); strcpy(speedstr,filename); if (speedstr[0] == 0) { for (i=0; itype == 0) break; if (i >= filecount) i = 0; } if(dosort) options = 8; else options = 8+32; i = fullscreen_choice(options,temp1,NULL,instr,filecount,(char far *far*)choices, attributes,5,99,MAX_NAME-1,i,NULL,speedstr,filename_speedstr,check_f6_key); if (i==-F4) { dosort = 1 - dosort; goto restart; } if (i==-F6) { static int lastdir=0; if (lastdir==0) { strcpy(dir,fract_dir1); } else { strcpy(dir,fract_dir2); } fix_dirname(dir); makepath(flname,drive,dir,"",""); lastdir = 1-lastdir; goto restart; } if (i < 0) { /* restore filename */ strcpy(flname,old_flname); return(-1); } if(speedstr[0] == 0 || speedstate == MATCHING) { if(choices[i]->type) { if(far_strcmp(choices[i]->name,"..") == 0) /* go up a directory */ { if(strcmp(dir,DOTSLASH) == 0) strcpy(dir,DOTDOTSLASH); else { char *s; if((s = strrchr(dir,SLASHC)) != NULL) /* trailing slash */ { *s = 0; if((s = strrchr(dir,SLASHC)) != NULL) *(s+1) = 0; } } } else /* go down a directory */ far_strcat(dir,choices[i]->name); fix_dirname(dir); makepath(flname,drive,dir,"",""); goto restart; } splitpath(choices[i]->name,NULL,NULL,fname,ext); makepath(flname,drive,dir,fname,ext); } else { if (speedstate == SEARCHPATH && strchr(speedstr,'*') == 0 && strchr(speedstr,'?') == 0 && ((fr_findfirst(speedstr) == 0 && (DTA.attribute & SUBDIR))|| strcmp(speedstr,SLASH)==0)) /* it is a directory */ speedstate = TEMPLATE; if(speedstate == TEMPLATE) { /* extract from tempstr the pathname and template information, being careful not to overwrite drive and directory if not newly specified */ char drive1[FILE_MAX_DRIVE]; char dir1[FILE_MAX_DIR]; char fname1[FILE_MAX_FNAME]; char ext1[FILE_MAX_EXT]; splitpath(speedstr,drive1,dir1,fname1,ext1); if(drive1[0]) strcpy(drive,drive1); if(dir1[0]) strcpy(dir,dir1); makepath(flname,drive,dir,fname1,ext1); if(strchr(fname1,'*') || strchr(fname1,'?') || strchr(ext1 ,'*') || strchr(ext1 ,'?')) makepath(template,"","",fname1,ext1); else if(isadirectory(flname)) fix_dirname(flname); goto restart; } else /* speedstate == SEARCHPATH */ { char fullpath[FILE_MAX_DIR]; findpath(speedstr,fullpath); if(fullpath[0]) strcpy(flname,fullpath); else { /* failed, make diagnostic useful: */ strcpy(flname,speedstr); if (strchr(speedstr,SLASHC) == NULL) { splitpath(speedstr,NULL,NULL,fname,ext); makepath(flname,drive,dir,fname,ext); } } } } makepath(browsename,"","",fname,ext); return(0); } #ifdef __CLINT__ #pragma argsused #endif static int check_f6_key(int curkey,int choice) { /* choice is dummy used by other routines called by fullscreen_choice() */ choice = 0; /* to suppress warning only */ if (curkey == F6) return 0-F6; else if (curkey == F4) return 0-F4; return 0; } static int filename_speedstr(int row, int col, int vid, char *speedstring, int speed_match) { char *prompt; if ( strchr(speedstring,':') || strchr(speedstring,'*') || strchr(speedstring,'*') || strchr(speedstring,'?')) { speedstate = TEMPLATE; /* template */ prompt = "File Template"; } else if (speed_match) { speedstate = SEARCHPATH; /* does not match list */ prompt = "Search Path for"; } else { speedstate = MATCHING; prompt = speed_prompt; } putstring(row,col,vid,prompt); return(strlen(prompt)); } int isadirectory(char *s) { int len; char sv; #ifdef _MSC_VER unsigned attrib = 0; #endif despace(s); /* scrunch out white space */ if(strchr(s,'*') || strchr(s,'?')) return(0); /* for my purposes, not a directory */ len = strlen(s); if(len > 0) sv = s[len-1]; /* last char */ else sv = 0; #ifdef _MSC_VER if(_dos_getfileattr(s, &attrib) == 0 && ((attrib&_A_SUBDIR) != 0)) { return(1); /* not a directory or doesn't exist */ } else if(sv == SLASHC) { /* strip trailing slash and try again */ s[len-1] = 0; if(_dos_getfileattr(s, &attrib) == 0 && ((attrib&_A_SUBDIR) != 0)) { s[len-1] = sv; return(1); } s[len-1] = sv; } return(0); #else if(fr_findfirst(s) != 0) /* couldn't find it */ { /* any better ideas?? */ if(sv == SLASHC) /* we'll guess it is a directory */ return(1); else return(0); /* no slashes - we'll guess it's a file */ } else if((DTA.attribute & SUBDIR) != 0) { if(sv == SLASHC) { /* strip trailing slash and try again */ s[len-1] = 0; if(fr_findfirst(s) != 0) /* couldn't find it */ return(0); else if((DTA.attribute & SUBDIR) != 0) return(1); /* we're SURE it's a directory */ else return(0); } else return(1); /* we're SURE it's a directory */ } return(0); #endif } #ifndef XFRACT /* This routine moved to unix.c so we can use it in hc.c */ int splitpath(char far *template,char *drive,char *dir,char *fname,char *ext) { int length; int len; int offset; char far *tmp; if(drive) drive[0] = 0; if(dir) dir[0] = 0; if(fname) fname[0] = 0; if(ext) ext[0] = 0; if((length = far_strlen(template)) == 0) return(0); offset = 0; /* get drive */ if(length >= 2) if(template[1] == ':') { if(drive) { drive[0] = template[offset++]; drive[1] = template[offset++]; drive[2] = 0; } else { offset++; offset++; } } /* get dir */ if(offset < length) { tmp = far_strrchr(template,SLASHC); if(tmp) { tmp++; /* first character after slash */ len = tmp - (char far *)&template[offset]; if(len >= 0 && len < FILE_MAX_DIR && dir) far_strncpy(dir,&template[offset],min(len,FILE_MAX_DIR)); if(len < FILE_MAX_DIR && dir) dir[len] = 0; offset += len; } } else return(0); /* get fname */ if(offset < length) { tmp = far_strrchr(template,'.'); if(tmp < far_strrchr(template,SLASHC) || tmp < far_strrchr(template,':')) tmp = 0; /* in this case the '.' must be a directory */ if(tmp) { /* tmp++; */ /* first character past "." */ len = tmp - (char far *)&template[offset]; if((len > 0) && (offset+len < length) && fname) { far_strncpy(fname,&template[offset],min(len,FILE_MAX_FNAME)); if(len < FILE_MAX_FNAME) fname[len] = 0; else fname[FILE_MAX_FNAME-1] = 0; } offset += len; if((offset < length) && ext) { far_strncpy(ext,&template[offset],FILE_MAX_EXT); ext[FILE_MAX_EXT-1] = 0; } } else if((offset < length) && fname) { far_strncpy(fname,&template[offset],FILE_MAX_FNAME); fname[FILE_MAX_FNAME-1] = 0; } } return(0); } #endif int makepath(char *template,char *drive,char *dir,char *fname,char *ext) { if(template) *template = 0; else return(-1); #ifndef XFRACT if(drive) strcpy(template,drive); #endif if(dir) strcat(template,dir); if(fname) strcat(template,fname); if(ext) strcat(template,ext); return(0); } /* fix up directory names */ void fix_dirname(char *dirname) { int length; despace(dirname); length = strlen(dirname); /* index of last character */ /* make sure dirname ends with a slash */ if(length > 0) if(dirname[length-1] == SLASHC) return; strcat(dirname,SLASH); } static void dir_name(char *target, char *dir, char *name) { *target = 0; if(*dir != 0) strcpy(target,dir); strcat(target,name); } /* opens file in dir directory */ int dir_open(char *dir, char *filename, int oflag, int pmode) { char tmp[FILE_MAX_PATH]; dir_name(tmp,dir,filename); return(open(tmp,oflag,pmode)); } /* removes file in dir directory */ int dir_remove(char *dir,char *filename) { char tmp[FILE_MAX_PATH]; dir_name(tmp,dir,filename); return(remove(tmp)); } /* fopens file in dir directory */ FILE *dir_fopen(char *dir, char *filename, char *mode ) { char tmp[FILE_MAX_PATH]; dir_name(tmp,dir,filename); return(fopen(tmp,mode)); } /* converts relative path to absolute path */ static int expand_dirname(char *dirname,char *drive) { #ifdef XFRACT char *dummy; /* to quiet compiler */ #endif fix_dirname(dirname); if (dirname[0] != SLASHC) { char buf[FILE_MAX_DIR+1],curdir[FILE_MAX_DIR+1]; #ifndef XFRACT int i=0; union REGS regs; struct SREGS sregs; curdir[0] = 0; regs.h.ah = 0x47; /* get current directory */ regs.h.dl = 0; if (drive[0] && drive[0] != ' ') regs.h.dl = (char)(tolower(drive[0])-'a'+1); regs.x.si = (unsigned int) &curdir[0]; segread(&sregs); intdosx(®s, ®s, &sregs); #else dummy = getcwd(curdir,FILE_MAX_DIR); #endif strcat(curdir,SLASH); #ifndef XFRACT while (curdir[i] != 0) { curdir[i] = (char)tolower(curdir[i]); i++; } #endif while (strncmp(dirname,DOTSLASH,2) == 0) { strcpy(buf,&dirname[2]); strcpy(dirname,buf); } while (strncmp(dirname,DOTDOTSLASH,3) == 0) { char *s; curdir[strlen(curdir)-1] = 0; /* strip trailing slash */ if ((s = strrchr(curdir,SLASHC)) != NULL) *s = 0; strcat(curdir,SLASH); strcpy(buf,&dirname[3]); strcpy(dirname,buf); } strcpy(buf,dirname); dirname[0] = 0; if (curdir[0] != SLASHC) strcpy(dirname,SLASH); strcat(dirname,curdir); strcat(dirname,buf); } return(0); } /* See if double value was changed by input screen. Problem is that the conversion from double to string and back can make small changes in the value, so will it twill test as "different" even though it is not */ int cmpdbl(double old, double new) { char buf[81]; struct fullscreenvalues val; /* change the old value with the same torture the new value had */ val.type = 'd'; /* most values on this screen are type d */ val.uval.dval = old; prompt_valuestring(buf,&val); /* convert "old" to string */ old = atof(buf); /* convert back */ return(fabs(old-new)xmin; xxmax = curfractalspecific->xmax; yy3rd = yymin = curfractalspecific->ymin; yymax = curfractalspecific->ymax; if (viewcrop && finalaspectratio != screenaspect) aspectratio_crop(screenaspect,finalaspectratio); if(bf_math != 0) fractal_floattobf(); goto gc_loop; } if (cmag) { if ( cmpdbl(Xctr , values[0].uval.dval) || cmpdbl(Yctr , values[1].uval.dval) || cmpdbl((double)Magnification, values[2].uval.dval) || cmpdbl(Xmagfactor , values[3].uval.dval) || cmpdbl(Rotation , values[4].uval.dval) || cmpdbl(Skew , values[5].uval.dval)) { Xctr = values[0].uval.dval; Yctr = values[1].uval.dval; Magnification = values[2].uval.dval; Xmagfactor = values[3].uval.dval; Rotation = values[4].uval.dval; Skew = values[5].uval.dval; if (Xmagfactor == 0) Xmagfactor = 1; cvtcorners(Xctr, Yctr, Magnification, Xmagfactor, Rotation, Skew); } } else { if (drawmode == 'l') { nump = 1; xxmin = values[nump++].uval.dval; yymax = values[nump++].uval.dval; nump++; xxmax = values[nump++].uval.dval; yymin = values[nump++].uval.dval; } else { nump = 1; xxmin = values[nump++].uval.dval; yymax = values[nump++].uval.dval; nump++; xxmax = values[nump++].uval.dval; yymin = values[nump++].uval.dval; nump++; xx3rd = values[nump++].uval.dval; yy3rd = values[nump++].uval.dval; if (xx3rd == 0 && yy3rd == 0) { xx3rd = xxmin; yy3rd = yymin; } } } if (prompt_ret == F7 && drawmode != 'l') { /* toggle corners/center-mag mode */ if (usemag == 0) { cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); usemag = 1; } else usemag = 0; goto gc_loop; } if(!cmpdbl(oxxmin,xxmin) && !cmpdbl(oxxmax,xxmax) && !cmpdbl(oyymin,yymin) && !cmpdbl(oyymax,yymax) && !cmpdbl(oxx3rd,xx3rd) && !cmpdbl(oyy3rd,yy3rd)) { /* no change, restore values to avoid drift */ xxmin = oxxmin; xxmax = oxxmax; yymin = oyymin; yymax = oyymax; xx3rd = oxx3rd; yy3rd = oyy3rd; return 0; } else return(1); } static int get_screen_corners(void) { char far *ptr; struct fullscreenvalues values[15]; char far *prompts[15]; static FCODE o_xprompt[]={" X"}; static FCODE o_yprompt[]={" Y"}; static FCODE o_zprompt[]={" Z"}; char xprompt[sizeof(o_xprompt)]; char yprompt[sizeof(o_yprompt)]; char zprompt[sizeof(o_zprompt)]; int i,nump,prompt_ret; int cmag; double Xctr,Yctr; LDBL Magnification; /* LDBL not really needed here, but used to match function parameters */ double Xmagfactor,Rotation,Skew; BYTE ousemag; double oxxmin,oxxmax,oyymin,oyymax,oxx3rd,oyy3rd; double svxxmin,svxxmax,svyymin,svyymax,svxx3rd,svyy3rd; static FCODE hdg[]={"Screen Coordinates"}; int oldhelpmode; far_strcpy(xprompt,o_xprompt); far_strcpy(yprompt,o_yprompt); far_strcpy(zprompt,o_zprompt); ptr = (char far *)MK_FP(extraseg,0); oldhelpmode = helpmode; ousemag = usemag; svxxmin = xxmin; /* save these for later since cvtcorners modifies them */ svxxmax = xxmax; /* and we need to set them for cvtcentermag to work */ svxx3rd = xx3rd; svyymin = yymin; svyymax = yymax; svyy3rd = yy3rd; if (!set_orbit_corners && !keep_scrn_coords) { oxmin = xxmin; oxmax = xxmax; ox3rd = xx3rd; oymin = yymin; oymax = yymax; oy3rd = yy3rd; } oxxmin = oxmin; oxxmax = oxmax; oyymin = oymin; oyymax = oymax; oxx3rd = ox3rd; oyy3rd = oy3rd; xxmin = oxmin; xxmax = oxmax; yymin = oymin; yymax = oymax; xx3rd = ox3rd; yy3rd = oy3rd; gsc_loop: for (i = 0; i < 15; ++i) values[i].type = 'd'; /* most values on this screen are type d */ cmag = usemag; cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); nump = -1; if (cmag) { LOADPROMPTS("Center X"); values[nump].uval.dval = Xctr; LOADPROMPTS("Center Y"); values[nump].uval.dval = Yctr; LOADPROMPTS("Magnification"); values[nump].uval.dval = (double)Magnification; LOADPROMPTS("X Magnification Factor"); values[nump].uval.dval = Xmagfactor; LOADPROMPTS("Rotation Angle (degrees)"); values[nump].uval.dval = Rotation; LOADPROMPTS("Skew Angle (degrees)"); values[nump].uval.dval = Skew; LOADPROMPTS(""); values[nump].type = '*'; LOADPROMPTS("Press "FK_F7" to switch to \"corners\" mode"); values[nump].type = '*'; } else { LOADPROMPTS("Top-Left Corner"); values[nump].type = '*'; prompts[++nump] = xprompt; values[nump].uval.dval = oxmin; prompts[++nump] = yprompt; values[nump].uval.dval = oymax; LOADPROMPTS("Bottom-Right Corner"); values[nump].type = '*'; prompts[++nump] = xprompt; values[nump].uval.dval = oxmax; prompts[++nump] = yprompt; values[nump].uval.dval = oymin; if (oxmin == ox3rd && oymin == oy3rd) ox3rd = oy3rd = 0; LOADPROMPTS("Bottom-left (zeros for top-left X, bottom-right Y)"); values[nump].type = '*'; prompts[++nump] = xprompt; values[nump].uval.dval = ox3rd; prompts[++nump] = yprompt; values[nump].uval.dval = oy3rd; LOADPROMPTS("Press "FK_F7" to switch to \"center-mag\" mode"); values[nump].type = '*'; } LOADPROMPTS("Press "FK_F4" to reset to type default values"); values[nump].type = '*'; oldhelpmode = helpmode; helpmode = HELPSCRNCOORDS; prompt_ret = fullscreen_prompt(hdg,nump+1, prompts, values, 0x90, NULL); helpmode = oldhelpmode; if (prompt_ret < 0) { usemag = ousemag; oxmin = oxxmin; oxmax = oxxmax; oymin = oyymin; oymax = oyymax; ox3rd = oxx3rd; oy3rd = oyy3rd; /* restore corners */ xxmin = svxxmin; xxmax = svxxmax; yymin = svyymin; yymax = svyymax; xx3rd = svxx3rd; yy3rd = svyy3rd; return(-1); } if (prompt_ret == F4) { /* reset to type defaults */ ox3rd = oxmin = curfractalspecific->xmin; oxmax = curfractalspecific->xmax; oy3rd = oymin = curfractalspecific->ymin; oymax = curfractalspecific->ymax; xxmin = oxmin; xxmax = oxmax; yymin = oymin; yymax = oymax; xx3rd = ox3rd; yy3rd = oy3rd; if (viewcrop && finalaspectratio != screenaspect) aspectratio_crop(screenaspect,finalaspectratio); oxmin = xxmin; oxmax = xxmax; oymin = yymin; oymax = yymax; ox3rd = xxmin; oy3rd = yymin; goto gsc_loop; } if (cmag) { if ( cmpdbl(Xctr , values[0].uval.dval) || cmpdbl(Yctr , values[1].uval.dval) || cmpdbl((double)Magnification, values[2].uval.dval) || cmpdbl(Xmagfactor , values[3].uval.dval) || cmpdbl(Rotation , values[4].uval.dval) || cmpdbl(Skew , values[5].uval.dval)) { Xctr = values[0].uval.dval; Yctr = values[1].uval.dval; Magnification = values[2].uval.dval; Xmagfactor = values[3].uval.dval; Rotation = values[4].uval.dval; Skew = values[5].uval.dval; if (Xmagfactor == 0) Xmagfactor = 1; cvtcorners(Xctr, Yctr, Magnification, Xmagfactor, Rotation, Skew); /* set screen corners */ oxmin = xxmin; oxmax = xxmax; oymin = yymin; oymax = yymax; ox3rd = xx3rd; oy3rd = yy3rd; } } else { nump = 1; oxmin = values[nump++].uval.dval; oymax = values[nump++].uval.dval; nump++; oxmax = values[nump++].uval.dval; oymin = values[nump++].uval.dval; nump++; ox3rd = values[nump++].uval.dval; oy3rd = values[nump++].uval.dval; if (ox3rd == 0 && oy3rd == 0) { ox3rd = oxmin; oy3rd = oymin; } } if (prompt_ret == F7) { /* toggle corners/center-mag mode */ if (usemag == 0) { cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); usemag = 1; } else usemag = 0; goto gsc_loop; } if(!cmpdbl(oxxmin,oxmin) && !cmpdbl(oxxmax,oxmax) && !cmpdbl(oyymin,oymin) && !cmpdbl(oyymax,oymax) && !cmpdbl(oxx3rd,ox3rd) && !cmpdbl(oyy3rd,oy3rd)) { /* no change, restore values to avoid drift */ oxmin = oxxmin; oxmax = oxxmax; oymin = oyymin; oymax = oyymax; ox3rd = oxx3rd; oy3rd = oyy3rd; /* restore corners */ xxmin = svxxmin; xxmax = svxxmax; yymin = svyymin; yymax = svyymax; xx3rd = svxx3rd; yy3rd = svyy3rd; return 0; } else { set_orbit_corners = 1; keep_scrn_coords = 1; /* restore corners */ xxmin = svxxmin; xxmax = svxxmax; yymin = svyymin; yymax = svyymax; xx3rd = svxx3rd; yy3rd = svyy3rd; return(1); } } /* get browse parameters , called from fractint.c and loadfile.c returns 3 if anything changes. code pinched from get_view_params */ int get_browse_params() { static FCODE o_hdg[]={"Browse ('L'ook) Mode Options"}; char hdg[sizeof(o_hdg)]; char far *ptr; char far *choices[10]; int oldhelpmode; struct fullscreenvalues uvalues[25]; int i, k; int old_autobrowse,old_brwschecktype,old_brwscheckparms,old_doublecaution; int old_minbox; double old_toosmall; char old_browsemask[MAX_NAME]; far_strcpy(hdg,o_hdg); ptr = (char far *)MK_FP(extraseg,0); old_autobrowse = autobrowse; old_brwschecktype = brwschecktype; old_brwscheckparms = brwscheckparms; old_doublecaution = doublecaution; old_minbox = minbox; old_toosmall = toosmall; strcpy(old_browsemask,browsemask); get_brws_restart: /* fill up the previous values arrays */ k = -1; LOADCHOICES("Autobrowsing? (y/n)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = autobrowse; LOADCHOICES("Ask about GIF video mode? (y/n)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = askvideo; LOADCHOICES("Check fractal type? (y/n)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = brwschecktype; LOADCHOICES("Check fractal parameters (y/n)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = brwscheckparms; LOADCHOICES("Confirm file deletes (y/n)"); uvalues[k].type='y'; uvalues[k].uval.ch.val = doublecaution; LOADCHOICES("Smallest window to display (size in pixels)"); uvalues[k].type = 'f'; uvalues[k].uval.dval = toosmall; LOADCHOICES("Smallest box size shown before crosshairs used (pix)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = minbox; LOADCHOICES("Browse search filename mask "); uvalues[k].type = 's'; strcpy(uvalues[k].uval.sval,browsemask); LOADCHOICES(""); uvalues[k].type = '*'; LOADCHOICES("Press "FK_F4" to reset browse parameters to defaults."); uvalues[k].type = '*'; oldhelpmode = helpmode; /* this prevents HELP from activating */ helpmode = HELPBRWSPARMS; i = fullscreen_prompt(hdg,k+1,choices,uvalues,16,NULL); helpmode = oldhelpmode; /* re-enable HELP */ if (i < 0) { return(0); } if (i == F4) { toosmall = 6; autobrowse = FALSE; askvideo = TRUE; brwscheckparms = TRUE; brwschecktype = TRUE; doublecaution = TRUE; minbox = 3; strcpy(browsemask,"*.gif"); goto get_brws_restart; } /* now check out the results (*hopefully* in the same order ) */ k = -1; autobrowse = uvalues[++k].uval.ch.val; askvideo = uvalues[++k].uval.ch.val; brwschecktype = (char)uvalues[++k].uval.ch.val; brwscheckparms = (char)uvalues[++k].uval.ch.val; doublecaution = uvalues[++k].uval.ch.val; toosmall = uvalues[++k].uval.dval; if (toosmall < 0 ) toosmall = 0 ; minbox = uvalues[++k].uval.ival; if (minbox < 1 ) minbox = 1; if (minbox > 10) minbox = 10; strcpy(browsemask,uvalues[++k].uval.sval); i = 0; if (autobrowse != old_autobrowse || brwschecktype != old_brwschecktype || brwscheckparms != old_brwscheckparms || doublecaution != old_doublecaution || toosmall != old_toosmall || minbox != old_minbox || !stricmp(browsemask,old_browsemask) ) i = -3; if (evolving) { /* can't browse */ autobrowse = 0; i = 0; } return(i); } /* merge existing full path with new one */ /* attempt to detect if file or directory */ #define ATFILENAME 0 #define SSTOOLSINI 1 #define ATCOMMANDINTERACTIVE 2 #define ATFILENAMESETNAME 3 #define GETPATH (mode < 2) #ifndef XFRACT #include #endif /* copies the proposed new filename to the fullpath variable */ /* does not copy directories for PAR files (modes 2 and 3) */ /* attempts to extract directory and test for existence (modes 0 and 1) */ int merge_pathnames(char *oldfullpath, char *newfilename, int mode) { int isadir = 0; int isafile = 0; int len; char drive[FILE_MAX_DRIVE]; char dir[FILE_MAX_DIR]; char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char temp_path[FILE_MAX_PATH]; char drive1[FILE_MAX_DRIVE]; char dir1[FILE_MAX_DIR]; char fname1[FILE_MAX_FNAME]; char ext1[FILE_MAX_EXT]; /* no dot or slash so assume a file */ if(strchr(newfilename,'.')==NULL && strchr(newfilename,SLASHC) == NULL) isafile=1; if((isadir = isadirectory(newfilename)) != 0) fix_dirname(newfilename); #if 0 /* if slash by itself, it's a directory */ if(strcmp(newfilename,SLASH)==0) isadir = 1; #endif #ifndef XFRACT /* if drive, colon, slash, is a directory */ if(strlen(newfilename) == 3 && newfilename[1] == ':' && newfilename[2] == SLASHC) isadir = 1; /* if drive, colon, with no slash, is a directory */ if(strlen(newfilename) == 2 && newfilename[1] == ':') { newfilename[2] = SLASHC; newfilename[3] = 0; isadir = 1; } /* if dot, slash, '0', its the current directory, set up full path */ if(newfilename[0] == '.' && newfilename[1] == SLASHC && newfilename[2] == 0) { temp_path[0] = (char)('a' + _getdrive() - 1); temp_path[1] = ':'; temp_path[2] = 0; expand_dirname(newfilename,temp_path); strcat(temp_path,newfilename); strcpy(newfilename,temp_path); isadir = 1; } /* if dot, slash, its relative to the current directory, set up full path */ if(newfilename[0] == '.' && newfilename[1] == SLASHC) { int len, test_dir=0; temp_path[0] = (char)('a' + _getdrive() - 1); temp_path[1] = ':'; temp_path[2] = 0; if (strrchr(newfilename,'.') == newfilename) test_dir = 1; /* only one '.' assume its a directory */ expand_dirname(newfilename,temp_path); strcat(temp_path,newfilename); strcpy(newfilename,temp_path); if (!test_dir) { len = strlen(newfilename); newfilename[len-1] = 0; /* get rid of slash added by expand_dirname */ } } #else findpath(newfilename,temp_path); strcpy(newfilename,temp_path); #endif /* check existence */ if(isadir==0 || isafile==1) { if(fr_findfirst(newfilename) == 0) { if(DTA.attribute & SUBDIR) /* exists and is dir */ { fix_dirname(newfilename); /* add trailing slash */ isadir = 1; isafile = 0; } else isafile = 1; } } splitpath(newfilename,drive,dir,fname,ext); splitpath(oldfullpath,drive1,dir1,fname1,ext1); if(strlen(drive) != 0 && GETPATH) strcpy(drive1,drive); if(strlen(dir) != 0 && GETPATH) strcpy(dir1,dir); if(strlen(fname) != 0) strcpy(fname1,fname); if(strlen(ext) != 0) strcpy(ext1,ext); if(isadir == 0 && isafile == 0 && GETPATH) { makepath(oldfullpath,drive1,dir1,NULL,NULL); len = strlen(oldfullpath); if(len > 0) { char save; /* strip trailing slash */ save = oldfullpath[len-1]; if(save == SLASHC) oldfullpath[len-1] = 0; if(access(oldfullpath,0)) isadir = -1; oldfullpath[len-1] = save; } } makepath(oldfullpath,drive1,dir1,fname1,ext1); return(isadir); } /* extract just the filename/extension portion of a path */ void extract_filename(char *target, char *source) { char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; splitpath(source,NULL,NULL,fname,ext); makepath(target,"","",fname,ext); } /* tells if filename has extension */ /* returns pointer to period or NULL */ char *has_ext(char *source) { char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char *ret = NULL; splitpath(source,NULL,NULL,fname,ext); if(ext != NULL) if(*ext != 0) ret = strrchr(source,'.'); return(ret); } /* I tried heap sort also - this is faster! */ void shell_sort(void far *v1, int n, unsigned sz, int (__cdecl *fct)(VOIDFARPTR arg1,VOIDFARPTR arg2)) { int gap,i,j; void far *temp; char far *v; v = (char far *)v1; for(gap = n/2; gap > 0; gap /= 2) for(i = gap; i=0; j -= gap) { if(fct((char far *far*)(v+j*sz),(char far *far*)(v+(j+gap)*sz)) <= 0) break; temp = *(char far *far*)(v+j*sz); *(char far *far*)(v+j*sz) = *(char far *far*)(v+(j+gap)*sz); *(char far *far*)(v+(j+gap)*sz) = temp; } } #if (_MSC_VER >= 700) #pragma code_seg ("prompts3_text") /* place following in an overlay */ #endif void far_strncpy(char far *t, char far *s, int len) { while((len-- && (*t++ = *s++) != 0)); } char far *far_strchr(char far *str, char c) { int len,i; len = far_strlen(str); i= -1; while (++i < len && c != str[i]); if(i == len) return(NULL); else return(&str[i]); } char far *far_strrchr(char far *str, char c) { int len; len = far_strlen(str); while (--len > -1 && c != str[len]); if(len == -1) return(NULL); else return(&str[len]); } #if (_MSC_VER >= 700) #pragma code_seg ("") #endif xfractint-20.4.10.orig/common/fractalp.c0000644000000000000000000022667311070025736014756 0ustar /* This module consists only of the fractalspecific structure and a *slew* of defines needed to get it to compile */ /* includes needed for fractalspecific */ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #include "fractype.h" /* functions defined elswhere needed for fractalspecific */ /* moved to prototyp.h */ /* parameter descriptions */ /* Note: parameters preceded by + are integer parameters */ /* parameters preceded by # are U32 parameters */ /* for Mandelbrots */ static char far realz0[] = "Real Perturbation of Z(0)"; static char far imagz0[] = "Imaginary Perturbation of Z(0)"; /* for Julias */ static char far realparm[] = "Real Part of Parameter"; static char far imagparm[] = "Imaginary Part of Parameter"; /* for Newtons */ static char far newtdegree[] = "+Polynomial Degree (>= 2)"; /* for MarksMandel/Julia */ static char far exponent[] = "Real part of Exponent"; static char far imexponent[] = "Imag part of Exponent"; /* for Complex Newton */ static char far realroot[] = "Real part of Root"; static char far imagroot[] = "Imag part of Root"; static char far realdegree[] = "Real part of Degree"; static char far imagdegree[] = "Imag part of Degree"; /* for Lorenz */ static char far timestep[] = "Time Step"; /* for formula */ static char far p1real[] = "Real portion of p1"; static char far p2real[] = "Real portion of p2"; static char far p3real[] = "Real portion of p3"; static char far p4real[] = "Real portion of p4"; static char far p5real[] = "Real portion of p5"; static char far p1imag[] = "Imaginary portion of p1"; static char far p2imag[] = "Imaginary portion of p2"; static char far p3imag[] = "Imaginary portion of p3"; static char far p4imag[] = "Imaginary portion of p4"; static char far p5imag[] = "Imaginary portion of p5"; /* trig functions */ static char far recoeftrg1[] = "Real Coefficient First Function"; static char far imcoeftrg1[] = "Imag Coefficient First Function"; static char far recoeftrg2[] = "Real Coefficient Second Function"; static char far imcoeftrg2[] = "Imag Coefficient Second Function"; /* MCP 7-7-91 static char far recoefsqr[] = "Real Coefficient Square Term"; static char far imcoefsqr[] = "Imag Coefficient Square Term"; */ static char far recoef2nd[] = "Real Coefficient Second Term"; static char far imcoef2nd[] = "Imag Coefficient Second Term"; /* KAM Torus */ static char far kamangle[] = "Angle (radians)"; static char far kamstep[] = "Step size"; static char far kamstop[] = "Stop value"; static char far pointsperorbit[] = "+Points per orbit"; /* Newtbasin */ static char far stripes[] = "Enter non-zero value for stripes"; /* Gingerbreadman */ static char far initx[] = "Initial x"; static char far inity[] = "Initial y"; /* popcorn and julia popcorn generalized */ static char far step_x[] = "Step size (real)"; static char far step_y[] = "Step size (imaginary)"; static char far constant_x[] = "Constant C (real)"; static char far constant_y[] = "Constant C (imaginary)"; /* bifurcations */ static char far filt[] = "+Filter Cycles"; static char far seed[] = "Seed Population"; /* frothy basins */ static char far frothmapping[] = "+Apply mapping once (1) or twice (2)"; static char far frothshade[] = "+Enter non-zero value for alternate color shading"; static char far frothavalue[] = "A (imaginary part of C)"; /* symmetrical icon fractals */ static char far s_lambda[] = "Lambda"; static char far s_alpha[] = "Alpha"; static char far s_beta[] = "Beta"; static char far s_gamma[] = "Gamma"; static char far s_omega[] = "Omega"; static char far symdegree[] = "+Degree of symmetry"; static char far shiftval[] = "Function Shift Value"; /* plasma and ant */ static char far s_randomseed[] = "+Random Seed Value (0 = Random, 1 = Reuse Last)"; /* ifs */ static char far color_method[] = "+Coloring method (0,1)"; /* orbit fractals */ static char A[] = "a"; static char B[] = "b"; static char D[] = "d"; static char H[] = "h"; static char P[] = "p"; /* 4D fractals */ static char C[] = "c"; static char C1[] = "c1"; static char CI[] = "ci"; static char CJ[] = "cj"; static char CK[] = "ck"; static char ZJ[] = "zj"; static char ZK[] = "zk"; static char far notused[] = "notused"; /* phoenix fractals */ static char far degreeZ[] = "Degree = 0 | >= 2 | <= -3"; /* empty string */ static char far ES[] = ""; /* julia inverse */ static char far s_maxhits[] = "Max Hits per Pixel"; #ifdef RANDOM_RUN static char far randomruninterval[] = "Random Run Interval"; #endif /* halley */ static char far order[] = {"+Order (integer > 1)"}; static char far real_relax[] = {"Real Relaxation coefficient"}; static char far epsilon[] = {"Epsilon"}; static char far imag_relax[] = {"Imag Relaxation coefficient"}; /* cellular */ static char far cell_init[] = {"#Initial String | 0 = Random | -1 = Reuse Last Random"}; static char far cell_rule[] = {"#Rule = # of digits (see below) | 0 = Random"}; static char far cell_type[] = {"+Type (see below)"}; static char far cell_strt[] = {"#Starting Row Number"}; /* bailout defines */ #define FTRIGBAILOUT 2500 #define LTRIGBAILOUT 64 #define FROTHBAILOUT 7 #define STDBAILOUT 4 #define NOBAILOUT 0 MOREPARAMS moreparams[] = { {ICON ,{ s_omega, symdegree, ES,ES,ES,ES},{0,3,0,0,0,0}}, {ICON3D ,{ s_omega, symdegree, ES,ES,ES,ES},{0,3,0,0,0,0}}, {HYPERCMPLXJFP ,{ ZJ, ZK, ES,ES,ES,ES},{0,0,0,0,0,0}}, {QUATJULFP ,{ ZJ, ZK, ES,ES,ES,ES},{0,0,0,0,0,0}}, {PHOENIXCPLX ,{ degreeZ, ES, ES,ES,ES,ES},{0,0,0,0,0,0}}, {PHOENIXFPCPLX ,{ degreeZ, ES, ES,ES,ES,ES},{0,0,0,0,0,0}}, {MANDPHOENIXCPLX ,{ degreeZ, ES, ES,ES,ES,ES},{0,0,0,0,0,0}}, {MANDPHOENIXFPCPLX,{ degreeZ, ES, ES,ES,ES,ES},{0,0,0,0,0,0}}, {FORMULA ,{ p3real,p3imag,p4real,p4imag,p5real,p5imag},{0,0,0,0,0,0}}, {FFORMULA ,{ p3real,p3imag,p4real,p4imag,p5real,p5imag},{0,0,0,0,0,0}}, {ANT ,{ "+Wrap?",s_randomseed,ES,ES,ES,ES},{1,0,0,0,0,0}}, /* {MANDELBROTMIX4 ,{ p3real,p3imag, ES,ES,ES,ES},{0,0,0,0,0,0}}, */ {-1 ,{ NULL,NULL,NULL,NULL,NULL,NULL },{0,0,0,0,0,0}} }; /* type math orbitcalc fnct per_pixel fnct per_image fnct |-----|----|--------------|--------------|--------------| */ struct alternatemathstuff far alternatemath[] = { #define USEBN #ifdef USEBN {JULIAFP, 1,JuliabnFractal,juliabn_per_pixel, MandelbnSetup}, {MANDELFP,1,JuliabnFractal,mandelbn_per_pixel, MandelbnSetup}, #else {JULIAFP, 2,JuliabfFractal,juliabf_per_pixel, MandelbfSetup}, {MANDELFP,2,JuliabfFractal,mandelbf_per_pixel, MandelbfSetup}, #endif /* NOTE: The default precision for bf_math=BIGNUM is not high enough for JuliaZpowerbnFractal. If you want to test BIGNUM (1) instead of the usual BIGFLT (2), then set bfdigits on the command to increase the precision. */ #define USEBF #ifdef USEBF {FPJULIAZPOWER,2,JuliaZpowerbfFractal,juliabf_per_pixel, MandelbfSetup }, {FPMANDELZPOWER,2,JuliaZpowerbfFractal,mandelbf_per_pixel, MandelbfSetup}, {DIVIDEBROT5,2,DivideBrot5bfFractal,dividebrot5bf_per_pixel, MandelbfSetup}, #else {FPJULIAZPOWER,1,JuliaZpowerbnFractal,juliabn_per_pixel, MandelbnSetup }, {FPMANDELZPOWER,1,JuliaZpowerbnFractal,mandelbn_per_pixel, MandelbnSetup}, /* The following is broken. Probably related to cplxdiv_bn() or div_bn(). JCO 09/28/2008 */ {DIVIDEBROT5,1,DivideBrot5bnFractal,dividebrot5bn_per_pixel, MandelbnSetup}, #endif {-1, 0,NULL, NULL, NULL } }; /* These are only needed for types with both integer and float variations */ char t_barnsleyj1[]= "*barnsleyj1"; char t_barnsleyj2[]= "*barnsleyj2"; char t_barnsleyj3[]= "*barnsleyj3"; char t_barnsleym1[]= "*barnsleym1"; char t_barnsleym2[]= "*barnsleym2"; char t_barnsleym3[]= "*barnsleym3"; char t_bifplussinpi[]= "*bif+sinpi"; char t_bifeqsinpi[]= "*bif=sinpi"; char t_biflambda[]= "*biflambda"; char t_bifmay[]= "*bifmay"; char t_bifstewart[]= "*bifstewart"; char t_bifurcation[]= "*bifurcation"; char t_fn_z_plusfn_pix_[]= "*fn(z)+fn(pix)"; char t_fn_zz_[]= "*fn(z*z)"; char t_fnfn[]= "*fn*fn"; char t_fnzplusz[]= "*fn*z+z"; char t_fnplusfn[]= "*fn+fn"; char t_formula[]= "*formula"; char t_henon[]= "*henon"; char t_ifs3d[]= "*ifs3d"; char t_julfnplusexp[]= "*julfn+exp"; char t_julfnpluszsqrd[]= "*julfn+zsqrd"; char t_julia[]= "*julia"; char t_julia_fnorfn_[]= "*julia(fn||fn)"; char t_julia4[]= "*julia4"; char t_julia_inverse[]= "*julia_inverse"; char t_julibrot[]= "*julibrot"; char t_julzpower[]= "*julzpower"; char t_kamtorus[]= "*kamtorus"; char t_kamtorus3d[]= "*kamtorus3d"; char t_lambda[]= "*lambda"; char t_lambda_fnorfn_[]= "*lambda(fn||fn)"; char t_lambdafn[]= "*lambdafn"; char t_lorenz[]= "*lorenz"; char t_lorenz3d[]= "*lorenz3d"; char t_mandel[]= "*mandel"; char t_mandel_fnorfn_[]= "*mandel(fn||fn)"; char t_mandel4[]= "*mandel4"; char t_mandelfn[]= "*mandelfn"; char t_mandellambda[]= "*mandellambda"; char t_mandphoenix[]= "*mandphoenix"; char t_mandphoenixcplx[]= "*mandphoenixclx"; char t_manfnplusexp[]= "*manfn+exp"; char t_manfnpluszsqrd[]= "*manfn+zsqrd"; char t_manlam_fnorfn_[]= "*manlam(fn||fn)"; char t_manowar[]= "*manowar"; char t_manowarj[]= "*manowarj"; char t_manzpower[]= "*manzpower"; char t_marksjulia[]= "*marksjulia"; char t_marksmandel[]= "*marksmandel"; char t_marksmandelpwr[]= "*marksmandelpwr"; char t_newtbasin[]= "*newtbasin"; char t_newton[]= "*newton"; char t_phoenix[]= "*phoenix"; char t_phoenixcplx[]= "*phoenixcplx"; char t_popcorn[]= "*popcorn"; char t_popcornjul[]= "*popcornjul"; char t_rossler3d[]= "*rossler3d"; char t_sierpinski[]= "*sierpinski"; char t_spider[]= "*spider"; char t_sqr_1divfn_[]= "*sqr(1/fn)"; char t_sqr_fn_[]= "*sqr(fn)"; char t_tims_error[]= "*tim's_error"; char t_unity[]= "*unity"; char t_frothybasin[]= "*frothybasin"; char t_halley[]= "*halley"; /* use next to cast orbitcalcs() that have arguments */ #define VF int(*)(void) struct fractalspecificstuff far fractalspecific[]= { /* { fractal name, {parameter text strings}, {parameter values}, helptext, helpformula, flags, xmin, xmax, ymin, ymax, int, tojulia, tomandel, tofloat, symmetry, orbit fnct, per_pixel fnct, per_image fnct, calctype fcnt, bailout } */ { t_mandel+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MANDEL, HF_MANDEL, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, JULIA, NOFRACTAL, MANDELFP, XAXIS_NOPARM, JuliaFractal, mandel_per_pixel,MandelSetup, StandardFractal, STDBAILOUT }, { t_julia+1, {realparm, imagparm, ES, ES}, {0.3, 0.6, 0, 0}, HT_JULIA, HF_JULIA, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, MANDEL, JULIAFP, ORIGIN, JuliaFractal, julia_per_pixel, JuliaSetup, StandardFractal, STDBAILOUT }, { t_newtbasin, {newtdegree, stripes, ES, ES}, {3, 0, 0, 0}, HT_NEWTBAS, HF_NEWTBAS, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, MPNEWTBASIN, NOSYM, NewtonFractal2, otherjuliafp_per_pixel, NewtonSetup, StandardFractal, NOBAILOUT }, { t_lambda+1, {realparm, imagparm, ES, ES}, {0.85, 0.6, 0, 0}, HT_LAMBDA, HF_LAMBDA, WINFRAC+OKJB+BAILTEST, (float)-1.5, (float)2.5, (float)-1.5, (float)1.5, 1, NOFRACTAL, MANDELLAMBDA, LAMBDAFP, NOSYM, LambdaFractal, julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_mandel, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MANDEL, HF_MANDEL, WINFRAC+BAILTEST+BF_MATH, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, JULIAFP, NOFRACTAL, MANDEL, XAXIS_NOPARM, JuliafpFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_newton, {newtdegree, ES, ES, ES}, {3, 0, 0, 0}, HT_NEWT, HF_NEWT, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, MPNEWTON, XAXIS, NewtonFractal2, otherjuliafp_per_pixel, NewtonSetup, StandardFractal, NOBAILOUT }, { t_julia, {realparm, imagparm, ES, ES}, {0.3, 0.6, 0, 0}, HT_JULIA, HF_JULIA, WINFRAC+OKJB+BAILTEST+BF_MATH, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDELFP, JULIA, ORIGIN, JuliafpFractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { "plasma", {"Graininess Factor (0 or 0.125 to 100, default is 2)", "+Algorithm (0 = original, 1 = new)", "+Random Seed Value (0 = Random, 1 = Reuse Last)", "+Save as Pot File? (0 = No, 1 = Yes)" }, {2, 0, 0, 0}, HT_PLASMA, HF_PLASMA, NOZOOM+NOGUESS+NOTRACE+NORESUME+WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, plasma, NOBAILOUT }, { t_mandelfn, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MANDFN, HF_MANDFN, TRIG1+WINFRAC, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 0, LAMBDATRIGFP, NOFRACTAL, MANDELTRIG, XYAXIS_NOPARM, LambdaTrigfpFractal,othermandelfp_per_pixel,MandelTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_manowar, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_MANOWAR, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, MANOWARJFP, NOFRACTAL, MANOWAR, XAXIS_NOPARM, ManOWarfpFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_manowar+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_MANOWAR, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, MANOWARJ, NOFRACTAL, MANOWARFP, XAXIS_NOPARM, ManOWarFractal, mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { "test", {"(testpt Param #1)", "(testpt param #2)", "(testpt param #3)", "(testpt param #4)" }, {0, 0, 0, 0}, HT_TEST, HF_TEST, 0, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, test, STDBAILOUT }, { t_sierpinski+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SIER, HF_SIER, WINFRAC, (float)-4/3, (float)96/45, (float)-0.9, (float)1.7, 1, NOFRACTAL, NOFRACTAL, SIERPINSKIFP, NOSYM, SierpinskiFractal, long_julia_per_pixel, SierpinskiSetup, StandardFractal, 127 }, { t_barnsleym1+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_BARNS, HF_BARNSM1, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, BARNSLEYJ1,NOFRACTAL, BARNSLEYM1FP, XYAXIS_NOPARM, Barnsley1Fractal, long_mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_barnsleyj1+1, {realparm, imagparm, ES, ES}, {0.6, 1.1, 0, 0}, HT_BARNS, HF_BARNSJ1, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, BARNSLEYM1, BARNSLEYJ1FP, ORIGIN, Barnsley1Fractal, long_julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_barnsleym2+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_BARNS, HF_BARNSM2, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, BARNSLEYJ2, NOFRACTAL, BARNSLEYM2FP, YAXIS_NOPARM, Barnsley2Fractal, long_mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_barnsleyj2+1, {realparm, imagparm, ES, ES}, {0.6, 1.1, 0, 0}, HT_BARNS, HF_BARNSJ2, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, BARNSLEYM2, BARNSLEYJ2FP, ORIGIN, Barnsley2Fractal, long_julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_sqr_fn_+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_SQRFN, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, NOFRACTAL, SQRTRIGFP, XAXIS, SqrTrigFractal, long_julia_per_pixel, SqrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_sqr_fn_, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_SQRFN, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, NOFRACTAL, SQRTRIG, XAXIS, SqrTrigfpFractal, otherjuliafp_per_pixel, SqrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_fnplusfn+1, {recoeftrg1, imcoeftrg1, recoeftrg2, imcoeftrg2}, {1, 0, 1, 0}, HT_SCOTSKIN, HF_FNPLUSFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, NOFRACTAL, TRIGPLUSTRIGFP, XAXIS, TrigPlusTrigFractal, long_julia_per_pixel, TrigPlusTriglongSetup, StandardFractal, LTRIGBAILOUT }, { t_mandellambda+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MLAMBDA, HF_MLAMBDA, WINFRAC+BAILTEST, (float)-3.0, (float)5.0, (float)-3.0, (float)3.0, 1, LAMBDA, NOFRACTAL, MANDELLAMBDAFP, XAXIS_NOPARM, LambdaFractal, mandel_per_pixel,MandellongSetup, StandardFractal, STDBAILOUT }, { t_marksmandel+1, {realz0, imagz0, exponent, ES}, {0, 0, 1, 0}, HT_MARKS, HF_MARKSMAND, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, MARKSJULIA, NOFRACTAL, MARKSMANDELFP, NOSYM, MarksLambdaFractal, marksmandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_marksjulia+1, {realparm, imagparm, exponent, ES}, {0.1, 0.9, 1, 0}, HT_MARKS, HF_MARKSJULIA, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, MARKSMANDEL, MARKSJULIAFP, ORIGIN, MarksLambdaFractal, julia_per_pixel, MarksJuliaSetup, StandardFractal, STDBAILOUT }, { t_unity+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_UNITY, HF_UNITY, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, NOFRACTAL, UNITYFP, XYAXIS, UnityFractal, long_julia_per_pixel, UnitySetup, StandardFractal, NOBAILOUT }, { t_mandel4+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MANDJUL4, HF_MANDEL4, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, JULIA4, NOFRACTAL, MANDEL4FP, XAXIS_NOPARM, Mandel4Fractal, mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_julia4+1, {realparm, imagparm, ES, ES}, {0.6, 0.55, 0, 0}, HT_MANDJUL4, HF_JULIA4, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, MANDEL4, JULIA4FP, ORIGIN, Mandel4Fractal, julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { "ifs", {color_method, ES, ES, ES}, {0, 0, 0, 0}, HT_IFS, -4, NOGUESS+NOTRACE+NORESUME+WINFRAC+INFCALC, (float)-8.0, (float)8.0, (float)-1.0, (float)11.0, 16, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, ifs, NOBAILOUT }, { t_ifs3d, {color_method, ES, ES, ES}, {0, 0, 0, 0}, HT_IFS, -4, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-11.0, (float)11.0, (float)-11.0, (float)11.0, 16, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, ifs, NOBAILOUT }, { t_barnsleym3+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_BARNS, HF_BARNSM3, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, BARNSLEYJ3,NOFRACTAL, BARNSLEYM3FP, XAXIS_NOPARM, Barnsley3Fractal, long_mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_barnsleyj3+1, {realparm, imagparm, ES, ES}, {0.1, 0.36, 0, 0}, HT_BARNS, HF_BARNSJ3, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, BARNSLEYM3, BARNSLEYJ3FP, NOSYM, Barnsley3Fractal, long_julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_fn_zz_+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_FNZTIMESZ, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, NOFRACTAL, TRIGSQRFP, XYAXIS, TrigZsqrdFractal, julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_fn_zz_, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_FNZTIMESZ, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, NOFRACTAL, TRIGSQR, XYAXIS, TrigZsqrdfpFractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_bifurcation, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFURCATION, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)1.9, (float)3.0, (float)0.0, (float)1.34, 0, NOFRACTAL, NOFRACTAL, LBIFURCATION, NOSYM, BifurcVerhulstTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_fnplusfn, {recoeftrg1, imcoeftrg1, recoeftrg2, imcoeftrg2}, {1, 0, 1, 0}, HT_SCOTSKIN, HF_FNPLUSFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, NOFRACTAL, TRIGPLUSTRIG, XAXIS, TrigPlusTrigfpFractal, otherjuliafp_per_pixel, TrigPlusTrigfpSetup, StandardFractal, LTRIGBAILOUT }, { t_fnfn+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_FNTIMESFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, NOFRACTAL, TRIGXTRIGFP, XAXIS, TrigXTrigFractal, long_julia_per_pixel, FnXFnSetup, StandardFractal, LTRIGBAILOUT }, { t_fnfn, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_FNTIMESFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, NOFRACTAL, TRIGXTRIG, XAXIS, TrigXTrigfpFractal, otherjuliafp_per_pixel, FnXFnSetup, StandardFractal, LTRIGBAILOUT }, { t_sqr_1divfn_+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_SQROVFN, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, NOFRACTAL, SQR1OVERTRIGFP, NOSYM, Sqr1overTrigFractal, long_julia_per_pixel, SqrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_sqr_1divfn_, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_SQROVFN, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, NOFRACTAL, SQR1OVERTRIG, NOSYM, Sqr1overTrigfpFractal, otherjuliafp_per_pixel, SqrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_fnzplusz+1, {recoeftrg1, imcoeftrg1, recoef2nd, imcoef2nd}, {1, 0, 1, 0}, HT_SCOTSKIN, HF_FNXZPLUSZ, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 1, NOFRACTAL, NOFRACTAL, ZXTRIGPLUSZFP, XAXIS, ZXTrigPlusZFractal, julia_per_pixel, ZXTrigPlusZSetup, StandardFractal, LTRIGBAILOUT }, { t_fnzplusz, {recoeftrg1, imcoeftrg1, recoef2nd, imcoef2nd}, {1, 0, 1, 0}, HT_SCOTSKIN, HF_FNXZPLUSZ, TRIG1+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, NOFRACTAL, ZXTRIGPLUSZ, XAXIS, ZXTrigPlusZfpFractal, juliafp_per_pixel, ZXTrigPlusZSetup, StandardFractal, LTRIGBAILOUT }, { t_kamtorus, {kamangle, kamstep, kamstop, pointsperorbit}, {1.3, .05, 1.5, 150}, HT_KAM, HF_KAM, NOGUESS+NOTRACE+WINFRAC, (float)-1.0, (float)1.0, (float)-.75, (float).75, 0, NOFRACTAL, NOFRACTAL, KAM, NOSYM, (VF)kamtorusfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { t_kamtorus+1, {kamangle, kamstep, kamstop, pointsperorbit}, {1.3, .05, 1.5, 150}, HT_KAM, HF_KAM, NOGUESS+NOTRACE+WINFRAC, (float)-1.0, (float)1.0, (float)-.75, (float).75, 16, NOFRACTAL, NOFRACTAL, KAMFP, NOSYM, (VF)kamtoruslongorbit, NULL, orbit3dlongsetup, orbit2dlong, NOBAILOUT }, { t_kamtorus3d, {kamangle, kamstep, kamstop, pointsperorbit}, {1.3, .05, 1.5, 150}, HT_KAM, HF_KAM, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D, (float)-3.0, (float)3.0, (float)-1.0, (float)3.5, 0, NOFRACTAL, NOFRACTAL, KAM3D, NOSYM, (VF)kamtorusfloatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { t_kamtorus3d+1, {kamangle, kamstep, kamstop, pointsperorbit}, {1.3, .05, 1.5, 150}, HT_KAM, HF_KAM, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D, (float)-3.0, (float)3.0, (float)-1.0, (float)3.5, 16, NOFRACTAL, NOFRACTAL, KAM3DFP, NOSYM, (VF)kamtoruslongorbit, NULL, orbit3dlongsetup, orbit3dlong, NOBAILOUT }, { t_lambdafn+1, {realparm, imagparm, ES, ES}, {1.0, 0.4, 0, 0}, HT_LAMBDAFN, HF_LAMBDAFN, TRIG1+WINFRAC+OKJB, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, MANDELTRIG, LAMBDATRIGFP, PI_SYM, (VF)LambdaTrigFractal, long_julia_per_pixel, LambdaTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_manfnpluszsqrd+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_PICKMJ, HF_MANDFNPLUSZSQRD, TRIG1+WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 16, LJULTRIGPLUSZSQRD, NOFRACTAL, FPMANTRIGPLUSZSQRD, XAXIS_NOPARM, TrigPlusZsquaredFractal, mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_julfnpluszsqrd+1, {realparm, imagparm, ES, ES}, {-0.5, 0.5, 0, 0}, HT_PICKMJ, HF_JULFNPLUSZSQRD, TRIG1+WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 16, NOFRACTAL, LMANTRIGPLUSZSQRD, FPJULTRIGPLUSZSQRD, NOSYM, TrigPlusZsquaredFractal, julia_per_pixel, JuliafnPlusZsqrdSetup, StandardFractal, STDBAILOUT }, { t_manfnpluszsqrd, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_PICKMJ, HF_MANDFNPLUSZSQRD, TRIG1+WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, FPJULTRIGPLUSZSQRD, NOFRACTAL, LMANTRIGPLUSZSQRD, XAXIS_NOPARM, TrigPlusZsquaredfpFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_julfnpluszsqrd, {realparm, imagparm, ES, ES}, {-0.5, 0.5, 0, 0}, HT_PICKMJ, HF_JULFNPLUSZSQRD, TRIG1+WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, FPMANTRIGPLUSZSQRD, LJULTRIGPLUSZSQRD, NOSYM, TrigPlusZsquaredfpFractal, juliafp_per_pixel, JuliafnPlusZsqrdSetup, StandardFractal, STDBAILOUT }, { t_lambdafn, {realparm, imagparm, ES, ES}, {1.0, 0.4, 0, 0}, HT_LAMBDAFN, HF_LAMBDAFN, TRIG1+WINFRAC+OKJB, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDELTRIGFP, LAMBDATRIG, PI_SYM, LambdaTrigfpFractal, otherjuliafp_per_pixel, LambdaTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_mandelfn+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MANDFN, HF_MANDFN, TRIG1+WINFRAC, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 16, LAMBDATRIG, NOFRACTAL, MANDELTRIGFP, XYAXIS_NOPARM, LambdaTrigFractal, long_mandel_per_pixel, MandelTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_manzpower+1, {realz0, imagz0, exponent, imexponent}, {0, 0, 2, 0}, HT_PICKMJ, HF_MANZPOWER, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, LJULIAZPOWER, NOFRACTAL, FPMANDELZPOWER, XAXIS_NOIMAG, longZpowerFractal, long_mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_julzpower+1, {realparm, imagparm, exponent, imexponent}, {0.3, 0.6, 2, 0}, HT_PICKMJ, HF_JULZPOWER, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, LMANDELZPOWER, FPJULIAZPOWER, ORIGIN, longZpowerFractal, long_julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_manzpower, {realz0, imagz0, exponent, imexponent}, {0, 0, 2, 0}, HT_PICKMJ, HF_MANZPOWER, WINFRAC+BAILTEST+BF_MATH, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, FPJULIAZPOWER, NOFRACTAL, LMANDELZPOWER, XAXIS_NOIMAG, floatZpowerFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_julzpower, {realparm, imagparm, exponent, imexponent}, {0.3, 0.6, 2, 0}, HT_PICKMJ, HF_JULZPOWER, WINFRAC+OKJB+BAILTEST+BF_MATH, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, FPMANDELZPOWER, LJULIAZPOWER, ORIGIN, floatZpowerFractal, otherjuliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { "manzzpwr", {realz0, imagz0, exponent, ES}, {0, 0, 2, 0}, HT_PICKMJ, HF_MANZZPWR, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, FPJULZTOZPLUSZPWR, NOFRACTAL, NOFRACTAL, XAXIS_NOPARM, floatZtozPluszpwrFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { "julzzpwr", {realparm, imagparm, exponent, ES}, {-0.3, 0.3, 2, 0}, HT_PICKMJ, HF_JULZZPWR, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, FPMANZTOZPLUSZPWR, NOFRACTAL, NOSYM, floatZtozPluszpwrFractal, otherjuliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_manfnplusexp+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_PICKMJ, HF_MANDFNPLUSEXP, TRIG1+WINFRAC+BAILTEST, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 16, LJULTRIGPLUSEXP, NOFRACTAL, FPMANTRIGPLUSEXP, XAXIS_NOPARM, LongTrigPlusExponentFractal, long_mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_julfnplusexp+1, {realparm, imagparm, ES, ES}, {0, 0, 0, 0}, HT_PICKMJ, HF_JULFNPLUSEXP, TRIG1+WINFRAC+OKJB+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, LMANTRIGPLUSEXP,FPJULTRIGPLUSEXP, NOSYM, LongTrigPlusExponentFractal, long_julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_manfnplusexp, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_PICKMJ, HF_MANDFNPLUSEXP, TRIG1+WINFRAC+BAILTEST, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 0, FPJULTRIGPLUSEXP, NOFRACTAL, LMANTRIGPLUSEXP, XAXIS_NOPARM, FloatTrigPlusExponentFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_julfnplusexp, {realparm, imagparm, ES, ES}, {0, 0, 0, 0}, HT_PICKMJ, HF_JULFNPLUSEXP, TRIG1+WINFRAC+OKJB+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, FPMANTRIGPLUSEXP, LJULTRIGPLUSEXP, NOSYM, FloatTrigPlusExponentFractal, otherjuliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_popcorn, {step_x, step_y, constant_x, constant_y}, {0.05, 0, 3.00, 0}, HT_POPCORN, HF_POPCORN, NOGUESS+NOTRACE+WINFRAC+TRIG4, (float)-3.0, (float)3.0, (float)-2.25, (float)2.25, 0, NOFRACTAL, NOFRACTAL, LPOPCORN, NOPLOT, PopcornFractalFn, otherjuliafp_per_pixel, JuliafpSetup, popcorn, STDBAILOUT }, { t_popcorn+1, {step_x, step_y, constant_x, constant_y}, {0.05, 0, 3.00, 0}, HT_POPCORN, HF_POPCORN, NOGUESS+NOTRACE+WINFRAC+TRIG4, (float)-3.0, (float)3.0, (float)-2.25, (float)2.25, 16, NOFRACTAL, NOFRACTAL, FPPOPCORN, NOPLOT, LPopcornFractalFn, long_julia_per_pixel, JulialongSetup, popcorn, STDBAILOUT }, { t_lorenz, {timestep, A, B, C}, {.02, 5, 15, 1}, HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-15.0, (float)15.0, (float)0.0, (float)30.0, 0, NOFRACTAL, NOFRACTAL, LLORENZ, NOSYM, (VF)lorenz3dfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { t_lorenz+1, {timestep, A, B, C}, {.02, 5, 15, 1}, HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-15.0, (float)15.0, (float)0.0, (float)30.0, 16, NOFRACTAL, NOFRACTAL, FPLORENZ, NOSYM, (VF)lorenz3dlongorbit, NULL, orbit3dlongsetup, orbit2dlong, NOBAILOUT }, { t_lorenz3d+1, {timestep, A, B, C}, {.02, 5, 15, 1}, HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-30.0, (float)30.0, 16, NOFRACTAL, NOFRACTAL, FPLORENZ3D, NOSYM, (VF)lorenz3dlongorbit, NULL, orbit3dlongsetup, orbit3dlong, NOBAILOUT }, { t_newton+1, {newtdegree, ES, ES, ES}, {3, 0, 0, 0}, HT_NEWT, HF_NEWT, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NEWTON, XAXIS, MPCNewtonFractal, MPCjulia_per_pixel, NewtonSetup, StandardFractal, NOBAILOUT }, { t_newtbasin+1, {newtdegree, stripes, ES, ES}, {3, 0, 0, 0}, HT_NEWTBAS, HF_NEWTBAS, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NEWTBASIN, NOSYM, MPCNewtonFractal, MPCjulia_per_pixel, NewtonSetup, StandardFractal, NOBAILOUT }, { "complexnewton", {realdegree, imagdegree, realroot, imagroot}, {3, 0, 1, 0}, HT_NEWTCMPLX, HF_COMPLEXNEWT, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, ComplexNewton, otherjuliafp_per_pixel, ComplexNewtonSetup, StandardFractal, NOBAILOUT }, { "complexbasin", {realdegree, imagdegree, realroot, imagroot}, {3, 0, 1, 0}, HT_NEWTCMPLX, HF_COMPLEXNEWT, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, ComplexBasin, otherjuliafp_per_pixel, ComplexNewtonSetup, StandardFractal, NOBAILOUT }, { "cmplxmarksmand", {realz0, imagz0, exponent, imexponent}, {0, 0, 1, 0}, HT_MARKS, HF_CMPLXMARKSMAND, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, COMPLEXMARKSJUL, NOFRACTAL, NOFRACTAL, NOSYM, MarksCplxMand, MarksCplxMandperp, MandelfpSetup, StandardFractal, STDBAILOUT }, { "cmplxmarksjul", {realparm, imagparm, exponent, imexponent}, {0.3, 0.6, 1, 0}, HT_MARKS, HF_CMPLXMARKSJUL, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, COMPLEXMARKSMAND, NOFRACTAL, NOSYM, MarksCplxMand, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_formula+1, {p1real, p1imag, p2real, p2imag}, {0, 0, 0, 0}, HT_FORMULA, -2, WINFRAC+MORE, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, NOFRACTAL, FFORMULA, SETUP_SYM, Formula, form_per_pixel, intFormulaSetup, StandardFractal, 0 }, { t_formula, {p1real, p1imag, p2real, p2imag}, {0, 0, 0, 0}, HT_FORMULA, -2, WINFRAC+MORE, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, FORMULA, SETUP_SYM, Formula, form_per_pixel, fpFormulaSetup, StandardFractal, 0 }, { t_sierpinski, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_SIER, HF_SIER, WINFRAC, (float)-4/3, (float)96/45, (float)-0.9, (float)1.7, 0, NOFRACTAL, NOFRACTAL, SIERPINSKI, NOSYM, SierpinskiFPFractal, otherjuliafp_per_pixel, SierpinskiFPSetup, StandardFractal, 127 }, { t_lambda, {realparm, imagparm, ES, ES}, {0.85, 0.6, 0, 0}, HT_LAMBDA, HF_LAMBDA, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDELLAMBDAFP, LAMBDA, NOSYM, LambdaFPFractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_barnsleym1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_BARNS, HF_BARNSM1, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, BARNSLEYJ1FP,NOFRACTAL, BARNSLEYM1, XYAXIS_NOPARM, Barnsley1FPFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_barnsleyj1, {realparm, imagparm, ES, ES}, {0.6, 1.1, 0, 0}, HT_BARNS, HF_BARNSJ1, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, BARNSLEYM1FP, BARNSLEYJ1, ORIGIN, Barnsley1FPFractal, otherjuliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_barnsleym2, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_BARNS, HF_BARNSM2, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, BARNSLEYJ2FP,NOFRACTAL, BARNSLEYM2, YAXIS_NOPARM, Barnsley2FPFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_barnsleyj2, {realparm, imagparm, ES, ES}, {0.6, 1.1, 0, 0}, HT_BARNS, HF_BARNSJ2, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, BARNSLEYM2FP, BARNSLEYJ2, ORIGIN, Barnsley2FPFractal, otherjuliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_barnsleym3, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_BARNS, HF_BARNSM3, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, BARNSLEYJ3FP, NOFRACTAL, BARNSLEYM3, XAXIS_NOPARM, Barnsley3FPFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_barnsleyj3, {realparm, imagparm, ES, ES}, {0.6, 1.1, 0, 0}, HT_BARNS, HF_BARNSJ3, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, BARNSLEYM3FP, BARNSLEYJ3, NOSYM, Barnsley3FPFractal, otherjuliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_mandellambda, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MLAMBDA, HF_MLAMBDA, WINFRAC+BAILTEST, (float)-3.0, (float)5.0, (float)-3.0, (float)3.0, 0, LAMBDAFP, NOFRACTAL, MANDELLAMBDA, XAXIS_NOPARM, LambdaFPFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_julibrot+1, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_JULIBROT, -1, NOGUESS+NOTRACE+NOROTATE+NORESUME+WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, NOFRACTAL, JULIBROTFP, NOSYM, JuliaFractal, jb_per_pixel, JulibrotSetup, Std4dFractal, STDBAILOUT }, { t_lorenz3d, {timestep, A, B, C}, {.02, 5, 15, 1}, HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-30.0, (float)30.0, 0, NOFRACTAL, NOFRACTAL, LLORENZ3D, NOSYM, (VF)lorenz3dfloatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { t_rossler3d+1, {timestep, A, B, C}, {.04, .2, .2, 5.7}, HT_ROSS, HF_ROSS, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-20.0, (float)40.0, 16, NOFRACTAL, NOFRACTAL, FPROSSLER, NOSYM, (VF)rosslerlongorbit, NULL, orbit3dlongsetup, orbit3dlong, NOBAILOUT }, { t_rossler3d, {timestep, A, B, C}, {.04, .2, .2, 5.7}, HT_ROSS, HF_ROSS, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-20.0, (float)40.0, 0, NOFRACTAL, NOFRACTAL, LROSSLER, NOSYM, (VF)rosslerfloatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { t_henon+1, {A, B, ES, ES}, {1.4, .3, 0, 0}, HT_HENON, HF_HENON, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-1.4, (float)1.4, (float)-.5, (float).5, 16, NOFRACTAL, NOFRACTAL, FPHENON, NOSYM, (VF)henonlongorbit, NULL, orbit3dlongsetup, orbit2dlong, NOBAILOUT }, { t_henon, {A, B, ES, ES}, {1.4, .3, 0, 0}, HT_HENON, HF_HENON, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-1.4, (float)1.4, (float)-.5, (float).5, 0, NOFRACTAL, NOFRACTAL, LHENON, NOSYM, (VF)henonfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "pickover", {A, B, C, D}, {2.24, .43, -.65, -2.43}, HT_PICK, HF_PICKOVER, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D, (float)-8/3, (float)8/3, (float)-2, (float)2, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)pickoverfloatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { "gingerbreadman", {initx, inity, ES, ES}, {-.1, 0, 0, 0}, HT_GINGER, HF_GINGER, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-4.5, (float)8.5, (float)-4.5, (float)8.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)gingerbreadfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "diffusion", {"+Border size", "+Type (0=Central,1=Falling,2=Square Cavity)", "+Color change rate (0=Random)", ES }, {10, 0, 0, 0}, HT_DIFFUS, HF_DIFFUS, NOZOOM+NOGUESS+NOTRACE+WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, diffusion, NOBAILOUT }, { t_unity, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_UNITY, HF_UNITY, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, UNITY, XYAXIS, UnityfpFractal, otherjuliafp_per_pixel, StandardSetup, StandardFractal, NOBAILOUT }, { t_spider, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_SPIDER, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, SPIDER, XAXIS_NOPARM, SpiderfpFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_spider+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_SPIDER, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, NOFRACTAL, NOFRACTAL, SPIDERFP, XAXIS_NOPARM, SpiderFractal, mandel_per_pixel, MandellongSetup,StandardFractal, STDBAILOUT }, { "tetrate", {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_TETRATE, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, XAXIS_NOIMAG, TetratefpFractal, othermandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { "magnet1m", {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MAGNET, HF_MAGM1, WINFRAC, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, MAGNET1J,NOFRACTAL,NOFRACTAL, XAXIS_NOPARM, Magnet1Fractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, 100 }, { "magnet1j", {realparm, imagparm, ES, ES}, {0, 0, 0, 0}, HT_MAGNET, HF_MAGJ1, WINFRAC, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 0, NOFRACTAL,MAGNET1M,NOFRACTAL, XAXIS_NOIMAG, Magnet1Fractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, 100 }, { "magnet2m", {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MAGNET, HF_MAGM2, WINFRAC, (float)-1.5, (float)3.7, (float)-1.95, (float)1.95, 0, MAGNET2J, NOFRACTAL, NOFRACTAL, XAXIS_NOPARM, Magnet2Fractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, 100 }, { "magnet2j", {realparm, imagparm, ES, ES}, {0, 0, 0, 0}, HT_MAGNET, HF_MAGJ2, WINFRAC, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 0, NOFRACTAL, MAGNET2M, NOFRACTAL, XAXIS_NOIMAG, Magnet2Fractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, 100 }, { t_bifurcation+1, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFURCATION, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)1.9, (float)3.0, (float)0.0, (float)1.34, 1, NOFRACTAL, NOFRACTAL, BIFURCATION, NOSYM, LongBifurcVerhulstTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_biflambda+1, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFLAMBDA, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)-2.0, (float)4.0, (float)-1.0, (float)2.0, 1, NOFRACTAL, NOFRACTAL, BIFLAMBDA, NOSYM, LongBifurcLambdaTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_biflambda, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFLAMBDA, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)-2.0, (float)4.0, (float)-1.0, (float)2.0, 0, NOFRACTAL, NOFRACTAL, LBIFLAMBDA, NOSYM, BifurcLambdaTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_bifplussinpi, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFPLUSSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)0.275, (float)1.45, (float)0.0, (float)2.0, 0, NOFRACTAL, NOFRACTAL, LBIFADSINPI, NOSYM, BifurcAddTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_bifeqsinpi, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFEQSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)-2.5, (float)2.5, (float)-3.5, (float)3.5, 0, NOFRACTAL, NOFRACTAL, LBIFEQSINPI, NOSYM, BifurcSetTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_popcornjul, {step_x, step_y, constant_x, constant_y}, {0.05, 0, 3.00, 0}, HT_POPCORN, HF_POPCJUL, WINFRAC+TRIG4, (float)-3.0, (float)3.0, (float)-2.25, (float)2.25, 0, NOFRACTAL, NOFRACTAL, LPOPCORNJUL, NOSYM, PopcornFractalFn, otherjuliafp_per_pixel, JuliafpSetup,StandardFractal, STDBAILOUT }, { t_popcornjul+1, {step_x, step_y, constant_x, constant_y}, {0.05, 0, 3.0, 0}, HT_POPCORN, HF_POPCJUL, WINFRAC+TRIG4, (float)-3.0, (float)3.0, (float)-2.25, (float)2.25, 16, NOFRACTAL, NOFRACTAL, FPPOPCORNJUL, NOSYM, LPopcornFractalFn, long_julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { "lsystem", {"+Order", ES, ES, ES}, {2, 0, 0, 0}, HT_LSYS, -3, NOZOOM+NORESUME+NOGUESS+NOTRACE+WINFRAC, (float)-1.0, (float)1.0, (float)-1.0, (float)1.0, 1, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, Lsystem, NOBAILOUT }, { t_manowarj, {realparm, imagparm, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_MANOWARJ, WINFRAC+OKJB+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANOWARFP, MANOWARJ, NOSYM, ManOWarfpFractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT }, { t_manowarj+1, {realparm, imagparm, ES, ES}, {0, 0, 0, 0}, HT_SCOTSKIN, HF_MANOWARJ, WINFRAC+OKJB+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, NOFRACTAL, MANOWAR, MANOWARJFP, NOSYM, ManOWarFractal, julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT }, { t_fn_z_plusfn_pix_, {realz0, imagz0, recoeftrg2, imcoeftrg2}, {0, 0, 1, 0}, HT_SCOTSKIN, HF_FNPLUSFNPIX, TRIG2+WINFRAC+BAILTEST, (float)-3.6, (float)3.6, (float)-2.7, (float)2.7, 0, NOFRACTAL, NOFRACTAL, FNPLUSFNPIXLONG, NOSYM, Richard8fpFractal, otherrichard8fp_per_pixel, MandelfpSetup, StandardFractal, LTRIGBAILOUT }, { t_fn_z_plusfn_pix_+1, {realz0, imagz0, recoeftrg2, imcoeftrg2}, {0, 0, 1, 0}, HT_SCOTSKIN, HF_FNPLUSFNPIX, TRIG2+WINFRAC+BAILTEST, (float)-3.6, (float)3.6, (float)-2.7, (float)2.7, 1, NOFRACTAL, NOFRACTAL, FNPLUSFNPIXFP, NOSYM, Richard8Fractal, long_richard8_per_pixel, MandellongSetup, StandardFractal, LTRIGBAILOUT }, { t_marksmandelpwr, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MARKS, HF_MARKSMANDPWR, TRIG1+WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, MARKSMANDELPWR, XAXIS_NOPARM, MarksMandelPwrfpFractal, marks_mandelpwrfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_marksmandelpwr+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MARKS, HF_MARKSMANDPWR, TRIG1+WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, NOFRACTAL, NOFRACTAL, MARKSMANDELPWRFP, XAXIS_NOPARM, MarksMandelPwrFractal, marks_mandelpwr_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_tims_error, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MARKS, HF_TIMSERR, WINFRAC+TRIG1+BAILTEST, (float)-2.9, (float)4.3, (float)-2.7, (float)2.7, 0, NOFRACTAL, NOFRACTAL, TIMSERROR, XAXIS_NOPARM, TimsErrorfpFractal, marks_mandelpwrfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_tims_error+1, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MARKS, HF_TIMSERR, WINFRAC+TRIG1+BAILTEST, (float)-2.9, (float)4.3, (float)-2.7, (float)2.7, 1, NOFRACTAL, NOFRACTAL, TIMSERRORFP, XAXIS_NOPARM, TimsErrorFractal, marks_mandelpwr_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT }, { t_bifeqsinpi+1, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFEQSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)-2.5, (float)2.5, (float)-3.5, (float)3.5, 1, NOFRACTAL, NOFRACTAL, BIFEQSINPI, NOSYM, LongBifurcSetTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_bifplussinpi+1, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFPLUSSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)0.275, (float)1.45, (float)0.0, (float)2.0, 1, NOFRACTAL, NOFRACTAL, BIFADSINPI, NOSYM, LongBifurcAddTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_bifstewart, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFSTEWART, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)0.7, (float)2.0, (float)-1.1, (float)1.1, 0, NOFRACTAL, NOFRACTAL, LBIFSTEWART, NOSYM, BifurcStewartTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { t_bifstewart+1, {filt, seed, ES, ES}, {1000.0, 0.66, 0, 0}, HT_BIF, HF_BIFSTEWART, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)0.7, (float)2.0, (float)-1.1, (float)1.1, 1, NOFRACTAL, NOFRACTAL, BIFSTEWART, NOSYM, LongBifurcStewartTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT }, { "hopalong", {A, B, C, ES}, {.4, 1, 0, 0}, HT_MARTIN, HF_HOPALONG, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-2.0, (float)3.0, (float)-1.625, (float)2.625, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)hopalong2dfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "circle", {"magnification", ES, ES, ES}, {200000L, 0, 0, 0}, HT_CIRCLE, HF_CIRCLE, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, XYAXIS, CirclefpFractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, NOBAILOUT }, { "martin", {A, ES, ES, ES}, {3.14, 0, 0, 0}, HT_MARTIN, HF_MARTIN, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-32, (float)32, (float)-24, (float)24, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)martin2dfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "lyapunov", {"+Order (integer)", "Population Seed", "+Filter Cycles", ES}, {0, 0.5, 0, 0}, HT_LYAPUNOV, HT_LYAPUNOV, WINFRAC, (float)-8.0, (float)8.0, (float)-6.0, (float)6.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, BifurcLambda, NULL, lya_setup, lyapunov, NOBAILOUT }, { "lorenz3d1", {timestep, A, B, C}, {.02, 5, 15, 1}, HT_LORENZ, HF_LORENZ3D1, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-30.0, (float)30.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)lorenz3d1floatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { "lorenz3d3", {timestep, A, B, C}, {.02, 10, 28, 2.66}, HT_LORENZ, HF_LORENZ3D3, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-30.0, (float)30.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)lorenz3d3floatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { "lorenz3d4", {timestep, A, B, C}, {.02, 10, 28, 2.66}, HT_LORENZ, HF_LORENZ3D4, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D+INFCALC, (float)-30.0, (float)30.0, (float)-30.0, (float)30.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)lorenz3d4floatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { t_lambda_fnorfn_+1, {realparm, imagparm, shiftval, ES}, {1, 0.1, 1, 0}, HT_FNORFN, HF_LAMBDAFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, LMANLAMFNFN, FPLAMBDAFNFN, ORIGIN, LambdaTrigOrTrigFractal, long_julia_per_pixel, LambdaTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_lambda_fnorfn_, {realparm, imagparm, shiftval, ES}, {1, 0.1, 1, 0}, HT_FNORFN, HF_LAMBDAFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, FPMANLAMFNFN, LLAMBDAFNFN, ORIGIN, LambdaTrigOrTrigfpFractal, otherjuliafp_per_pixel, LambdaTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_julia_fnorfn_+1, {realparm, imagparm, shiftval, ES}, {0, 0, 8, 0}, HT_FNORFN, HF_JULIAFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, NOFRACTAL, LMANFNFN, FPJULFNFN, XAXIS, JuliaTrigOrTrigFractal, long_julia_per_pixel, JuliaTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_julia_fnorfn_, {realparm, imagparm, shiftval, ES}, {0, 0, 8, 0}, HT_FNORFN, HF_JULIAFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, NOFRACTAL, FPMANFNFN, LJULFNFN, XAXIS, JuliaTrigOrTrigfpFractal, otherjuliafp_per_pixel, JuliaTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_manlam_fnorfn_+1, {realz0, imagz0, shiftval, ES}, {0, 0, 10, 0}, HT_FNORFN, HF_MANLAMFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, LLAMBDAFNFN, NOFRACTAL, FPMANLAMFNFN, XAXIS_NOPARM, LambdaTrigOrTrigFractal, long_mandel_per_pixel, ManlamTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_manlam_fnorfn_, {realz0, imagz0, shiftval, ES}, {0, 0, 10, 0}, HT_FNORFN, HF_MANLAMFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, FPLAMBDAFNFN, NOFRACTAL, LMANLAMFNFN, XAXIS_NOPARM, LambdaTrigOrTrigfpFractal, othermandelfp_per_pixel, ManlamTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_mandel_fnorfn_+1, {realz0, imagz0, shiftval, ES}, {0, 0, 0.5, 0}, HT_FNORFN, HF_MANDELFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 16, LJULFNFN, NOFRACTAL, FPMANFNFN,XAXIS_NOPARM, JuliaTrigOrTrigFractal, long_mandel_per_pixel, MandelTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_mandel_fnorfn_, {realz0, imagz0, shiftval, ES}, {0, 0, 0.5, 0}, HT_FNORFN, HF_MANDELFNFN, TRIG2+WINFRAC+BAILTEST, (float)-4.0, (float)4.0, (float)-3.0, (float)3.0, 0, FPJULFNFN, NOFRACTAL, LMANFNFN,XAXIS_NOPARM, JuliaTrigOrTrigfpFractal, othermandelfp_per_pixel, MandelTrigOrTrigSetup, StandardFractal, LTRIGBAILOUT }, { t_bifmay+1, {filt, seed, "Beta >= 2", ES}, {300.0, 0.9, 5, 0}, HT_BIF, HF_BIFMAY, NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)-3.5, (float)-0.9, (float)-0.5, (float)3.2, 16, NOFRACTAL, NOFRACTAL, BIFMAY, NOSYM, LongBifurcMay, NULL, BifurcMaySetup, Bifurcation, NOBAILOUT }, { t_bifmay, {filt, seed, "Beta >= 2", ES}, {300.0, 0.9, 5, 0}, HT_BIF, HF_BIFMAY, NOGUESS+NOTRACE+NOROTATE+WINFRAC, (float)-3.5, (float)-0.9, (float)-0.5, (float)3.2, 0, NOFRACTAL, NOFRACTAL, LBIFMAY, NOSYM, BifurcMay, NULL, BifurcMaySetup, Bifurcation, NOBAILOUT }, { t_halley+1, {order, real_relax, epsilon, imag_relax}, {6, 1.0, 0.0001, 0}, HT_HALLEY, HF_HALLEY, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, HALLEY, XYAXIS, MPCHalleyFractal, MPCHalley_per_pixel, HalleySetup, StandardFractal, NOBAILOUT }, { t_halley, {order, real_relax, epsilon, imag_relax}, {6, 1.0, 0.0001, 0}, HT_HALLEY, HF_HALLEY, WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, MPHALLEY, XYAXIS, HalleyFractal, Halley_per_pixel, HalleySetup, StandardFractal, NOBAILOUT }, { "dynamic", {"+# of intervals (<0 = connect)", "time step (<0 = Euler)", A, B}, {50, .1, 1, 3}, HT_DYNAM, HF_DYNAM, NOGUESS+NOTRACE+WINFRAC+TRIG1, (float)-20.0, (float)20.0, (float)-20.0, (float)20.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)dynamfloat, NULL, dynam2dfloatsetup, dynam2dfloat, NOBAILOUT }, { "quat", {notused, notused, CJ, CK}, {0, 0, 0, 0}, HT_QUAT, HF_QUAT, WINFRAC+OKJB, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, QUATJULFP, NOFRACTAL, NOFRACTAL, XAXIS, QuaternionFPFractal, quaternionfp_per_pixel, MandelfpSetup, StandardFractal, LTRIGBAILOUT }, { "quatjul", {C1, CI, CJ, CK}, {-.745, 0, .113, .05}, HT_QUAT, HF_QUATJ, WINFRAC+OKJB+MORE, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, QUATFP, NOFRACTAL, ORIGIN, QuaternionFPFractal, quaternionjulfp_per_pixel, JuliafpSetup, StandardFractal, LTRIGBAILOUT }, { "cellular", {cell_init, cell_rule, cell_type, cell_strt}, {11.0, 3311100320.0, 41.0, 0}, HT_CELLULAR, HF_CELLULAR, NOGUESS+NOTRACE+NOZOOM+WINFRAC, (float)-1.0, (float)1.0, (float)-1.0, (float)1.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, CellularSetup, cellular, NOBAILOUT }, { t_julibrot, {ES, ES, ES, ES}, {0, 0, 0, 0}, HT_JULIBROT, -1, NOGUESS+NOTRACE+NOROTATE+NORESUME+WINFRAC, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, JULIBROT, NOSYM, JuliafpFractal, jbfp_per_pixel, JulibrotSetup, Std4dfpFractal, STDBAILOUT }, #ifdef RANDOM_RUN { t_julia_inverse+1, {realparm, imagparm, s_maxhits, randomruninterval}, {-0.11, 0.6557, 4, 1024}, HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+NORESUME, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 24, NOFRACTAL, MANDEL, INVERSEJULIAFP, NOSYM, Linverse_julia_orbit, NULL, orbit3dlongsetup, inverse_julia_per_image, NOBAILOUT }, { t_julia_inverse, {realparm, imagparm, s_maxhits, randomruninterval}, {-0.11, 0.6557, 4, 1024}, HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+NORESUME, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDEL, INVERSEJULIA, NOSYM, Minverse_julia_orbit, NULL, orbit3dfloatsetup, inverse_julia_per_image, NOBAILOUT }, #else { t_julia_inverse+1, {realparm, imagparm, s_maxhits, ES}, {-0.11, 0.6557, 4, 1024}, HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+NORESUME, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 24, NOFRACTAL, MANDEL, INVERSEJULIAFP, NOSYM, Linverse_julia_orbit, NULL, orbit3dlongsetup, inverse_julia_per_image, NOBAILOUT }, { t_julia_inverse, {realparm, imagparm, s_maxhits, ES}, {-0.11, 0.6557, 4, 1024}, HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+NORESUME, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDEL, INVERSEJULIA, NOSYM, Minverse_julia_orbit, NULL, orbit3dfloatsetup, inverse_julia_per_image, NOBAILOUT }, #endif { "mandelcloud", {"+# of intervals (<0 = connect)", ES, ES, ES}, {50, 0, 0, 0}, HT_MANDELCLOUD, HF_MANDELCLOUD, NOGUESS+NOTRACE+WINFRAC, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)mandelcloudfloat, NULL, dynam2dfloatsetup, dynam2dfloat, NOBAILOUT }, { t_phoenix+1, {p1real, p2real, degreeZ, ES}, {0.56667, -0.5, 0, 0}, HT_PHOENIX, HF_PHOENIX, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, MANDPHOENIX, PHOENIXFP, XAXIS, LongPhoenixFractal, long_phoenix_per_pixel, PhoenixSetup, StandardFractal, STDBAILOUT }, { t_phoenix, {p1real, p2real, degreeZ, ES}, {0.56667, -0.5, 0, 0}, HT_PHOENIX, HF_PHOENIX, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDPHOENIXFP, PHOENIX, XAXIS, PhoenixFractal, phoenix_per_pixel, PhoenixSetup, StandardFractal, STDBAILOUT }, { t_mandphoenix+1, {realz0, imagz0, degreeZ, ES}, {0.0, 0.0, 0, 0}, HT_PHOENIX, HF_MANDPHOENIX, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, PHOENIX, NOFRACTAL, MANDPHOENIXFP, NOSYM, LongPhoenixFractal, long_mandphoenix_per_pixel, MandPhoenixSetup, StandardFractal, STDBAILOUT }, { t_mandphoenix, {realz0, imagz0, degreeZ, ES}, {0.0, 0.0, 0, 0}, HT_PHOENIX, HF_MANDPHOENIX, WINFRAC+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, PHOENIXFP, NOFRACTAL, MANDPHOENIX, NOSYM, PhoenixFractal, mandphoenix_per_pixel, MandPhoenixSetup, StandardFractal, STDBAILOUT }, { "hypercomplex", {notused, notused, CJ, CK}, {0, 0, 0, 0}, HT_HYPERC, HF_HYPERC, WINFRAC+OKJB+TRIG1, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, HYPERCMPLXJFP, NOFRACTAL, NOFRACTAL, XAXIS, HyperComplexFPFractal, quaternionfp_per_pixel, MandelfpSetup, StandardFractal, LTRIGBAILOUT }, { "hypercomplexj", {C1, CI, CJ, CK}, {-.745, 0, .113, .05}, HT_HYPERC, HF_HYPERCJ, WINFRAC+OKJB+TRIG1+MORE, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, HYPERCMPLXFP, NOFRACTAL, ORIGIN, HyperComplexFPFractal, quaternionjulfp_per_pixel, JuliafpSetup, StandardFractal, LTRIGBAILOUT }, { t_frothybasin+1, {frothmapping, frothshade, frothavalue, ES}, {1, 0, 1.028713768218725, 0}, HT_FROTH, HF_FROTH, NOTRACE+WINFRAC, (float)-2.8, (float)2.8, (float)-2.355, (float)1.845, 28, NOFRACTAL, NOFRACTAL, FROTHFP, NOSYM, froth_per_orbit, froth_per_pixel, froth_setup, calcfroth, FROTHBAILOUT }, { t_frothybasin, {frothmapping, frothshade, frothavalue, ES}, {1, 0, 1.028713768218725, 0}, HT_FROTH, HF_FROTH, NOTRACE+WINFRAC, (float)-2.8, (float)2.8, (float)-2.355, (float)1.845, 0, NOFRACTAL, NOFRACTAL, FROTH, NOSYM, froth_per_orbit, froth_per_pixel, froth_setup, calcfroth, FROTHBAILOUT }, { t_mandel4, {realz0, imagz0, ES, ES}, {0, 0, 0, 0}, HT_MANDJUL4, HF_MANDEL4, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, JULIA4FP, NOFRACTAL, MANDEL4, XAXIS_NOPARM, Mandel4fpFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_julia4, {realparm, imagparm, ES, ES}, {0.6, 0.55, 0, 0}, HT_MANDJUL4, HF_JULIA4, WINFRAC+OKJB+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDEL4FP, JULIA4, ORIGIN, Mandel4fpFractal, juliafp_per_pixel, JuliafpSetup,StandardFractal, STDBAILOUT }, { t_marksmandel, {realz0, imagz0, exponent, ES}, {0, 0, 1, 0}, HT_MARKS, HF_MARKSMAND, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, MARKSJULIAFP, NOFRACTAL, MARKSMANDEL, NOSYM, MarksLambdafpFractal, marksmandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT }, { t_marksjulia, {realparm, imagparm, exponent, ES}, {0.1, 0.9, 1, 0}, HT_MARKS, HF_MARKSJULIA, WINFRAC+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MARKSMANDELFP, MARKSJULIA, ORIGIN, MarksLambdafpFractal, juliafp_per_pixel, MarksJuliafpSetup, StandardFractal, STDBAILOUT }, /* dmf */ { "icons", {s_lambda, s_alpha, s_beta, s_gamma}, {-2.34, 2.0, 0.2, 0.1}, HT_ICON, HF_ICON, NOGUESS+NOTRACE+WINFRAC+INFCALC+MORE, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)iconfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, /* dmf */ { "icons3d", {s_lambda, s_alpha, s_beta, s_gamma}, {-2.34, 2.0, 0.2, 0.1}, HT_ICON, HF_ICON, NOGUESS+NOTRACE+WINFRAC+INFCALC+PARMS3D+MORE, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)iconfloatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT }, { t_phoenixcplx+1, {p1real, p1imag, p2real, p2imag}, {0.2, 0, 0.3, 0}, HT_PHOENIX, HF_PHOENIXCPLX, WINFRAC+MORE+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 1, NOFRACTAL, MANDPHOENIXCPLX,PHOENIXFPCPLX, ORIGIN, LongPhoenixFractalcplx, long_phoenix_per_pixel, PhoenixCplxSetup, StandardFractal, STDBAILOUT }, { t_phoenixcplx, {p1real, p1imag, p2real, p2imag}, {0.2, 0, 0.3, 0}, HT_PHOENIX, HF_PHOENIXCPLX, WINFRAC+MORE+BAILTEST, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, MANDPHOENIXFPCPLX, PHOENIXCPLX, ORIGIN, PhoenixFractalcplx, phoenix_per_pixel, PhoenixCplxSetup, StandardFractal, STDBAILOUT }, { t_mandphoenixcplx+1, {realz0, imagz0, p2real, p2imag}, {0, 0, 0.5, 0}, HT_PHOENIX, HF_MANDPHOENIXCPLX, WINFRAC+MORE+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 1, PHOENIXCPLX, NOFRACTAL, MANDPHOENIXFPCPLX, XAXIS, LongPhoenixFractalcplx, long_mandphoenix_per_pixel, MandPhoenixCplxSetup, StandardFractal, STDBAILOUT }, { t_mandphoenixcplx, {realz0, imagz0, p2real, p2imag}, {0, 0, 0.5, 0}, HT_PHOENIX, HF_MANDPHOENIXCPLX, WINFRAC+MORE+BAILTEST, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, PHOENIXFPCPLX, NOFRACTAL, MANDPHOENIXCPLX, XAXIS, PhoenixFractalcplx, mandphoenix_per_pixel, MandPhoenixCplxSetup, StandardFractal, STDBAILOUT }, { "ant", {"#Rule String (1's and non-1's, 0 rand)", "#Maxpts", "+Numants (max 256)", "+Ant type (1 or 2)" }, {1100, 1.0E9, 1, 1}, HT_ANT, HF_ANT, WINFRAC+NOZOOM+NOGUESS+NOTRACE+NORESUME+MORE, (float)-1.0, (float)1.0, (float)-1.0, (float)1.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, StandaloneSetup, ant, NOBAILOUT }, { "chip", {A, B, C, ES}, {-15,-19,1,0}, HT_MARTIN, HF_CHIP, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-760.0, (float)760.0, (float)-570.0, (float)570.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)chip2dfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "quadruptwo", {A, B, C, ES}, {34, 1, 5, 0}, HT_MARTIN, HF_QUADRUPTWO, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-82.93367, (float)112.2749, (float)-55.76383, (float)90.64257, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)quadruptwo2dfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "threeply", {A, B, C, ES}, {-55, -1, -42, 0}, HT_MARTIN, HF_THREEPLY, NOGUESS+NOTRACE+INFCALC+WINFRAC, (float)-8000.0, (float)8000.0, (float)-6000.0, (float)6000.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)threeply2dfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, { "volterra-lotka", {H, P, ES, ES}, {0.739, 0.739, 0, 0}, HT_VL, HF_VL, WINFRAC, (float)0.0, (float)6.0, (float)0.0, (float)4.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, VLfpFractal, otherjuliafp_per_pixel, VLSetup, StandardFractal, 256 }, { "escher_julia", {realparm, imagparm, ES, ES}, {0.32, 0.043, 0, 0}, HT_ESCHER, HF_ESCHER, WINFRAC, (float)-1.6, (float)1.6, (float)-1.2, (float)1.2, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, ORIGIN, EscherfpFractal, juliafp_per_pixel, StandardSetup, StandardFractal, STDBAILOUT }, /* From Pickovers' "Chaos in Wonderland" */ /* included by Humberto R. Baptista */ /* code adapted from king.cpp bt James Rankin */ { "latoocarfian", {A, B, C, D}, {-0.966918, 2.879879, 0.765145, 0.744728}, HT_LATOO, HF_LATOO, NOGUESS+NOTRACE+WINFRAC+INFCALC+MORE+TRIG4, (float)-2.0, (float)2.0, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, (VF)latoofloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT }, #if 0 { "mandelbrotmix4", {p1real, p1imag, p2real, p2imag}, {0.05, 3, -1.5, -2}, HT_MANDELBROTMIX4, HF_MANDELBROTMIX4, WINFRAC+BAILTEST+TRIG1+MORE, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, MandelbrotMix4fpFractal, MandelbrotMix4fp_per_pixel, MandelbrotMix4Setup, StandardFractal, STDBAILOUT }, #endif /* From Jim Muth */ { "dividebrot5", {A, B, ES, ES}, {2, 0, 0, 0}, HT_DIVIDEBROT5, HF_DIVIDEBROT5, WINFRAC+BAILTEST+BF_MATH, (float)-2.5, (float)1.5, (float)-1.5, (float)1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, DivideBrot5fpFractal, DivideBrot5fp_per_pixel, DivideBrot5Setup, StandardFractal, 16 }, { NULL, /* marks the END of the list */ {NULL, NULL, NULL, NULL}, {0, 0, 0, 0}, -1, -1, 0, (float)0.0, (float)0.0, (float)0.0, (float)0.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM, NULL, NULL, NULL, NULL, 0 } }; int num_fractal_types = (sizeof(fractalspecific)/ sizeof(struct fractalspecificstuff)) -1; /* * Returns 1 if the formula parameter is not used in the current * formula. If the parameter is used, or not a formula fractal, * a 0 is returned. Note: this routine only works for formula types. */ int paramnotused(int parm) { int ret = 0; /* sanity check */ if (fractype != FORMULA && fractype != FFORMULA) return (0); switch (parm/2) { case 0: if (!uses_p1) ret = 1; break; case 1: if (!uses_p2) ret = 1; break; case 2: if (!uses_p3) ret = 1; break; case 3: if (!uses_p4) ret = 1; break; case 4: if (!uses_p5) ret = 1; break; default: ret = 0; break; } return (ret); } /* * Returns 1 if parameter number parm exists for type. If the * parameter exists, the parameter prompt string is copied to buf. * Pass in NULL for buf if only the existence of the parameter is * needed, and not the prompt string. */ int typehasparm(int type,int parm,char *buf) { int extra; char far *ret = NULL; if(0 <= parm && parm < 4) ret=fractalspecific[type].param[parm]; else if(parm >= 4 && parm < MAXPARAMS) if((extra=find_extra_param(type)) > -1) ret=moreparams[extra].param[parm-4]; if(ret) if(*ret == 0) ret = NULL; if(type == FORMULA || type == FFORMULA) if(paramnotused(parm)) ret = NULL; if(ret && buf != NULL) far_strcpy(buf,ret); return(ret?1:0); } xfractint-20.4.10.orig/dos_help/0000755000000000000000000000000011456314752013312 5ustar xfractint-20.4.10.orig/dos_help/frachelp.mak0000644000000000000000000000070410405667107015567 0ustar HFD = ..\headers HELP = help.src help2.src help3.src help4.src help5.src # Next is a pseudo-target for nmake/nmk. It just generates harmless # warnings with make. all : hc.exe fractint.hlp # commented out remake of hc.c since it hasn't changed for many moons. hc.obj : hc.c $(HFD)\helpcom.h $(HFD)\port.h $(CC) /AL /W1 /FPi /c /I$(HFD) $(OptT) hc.c hc.exe : hc.obj $(LINKER) /ST:4096 /CP:1 /EXEPACK hc; fractint.hlp : hc.exe $(HELP) hc /c xfractint-20.4.10.orig/dos_help/hc.c0000644000000000000000000030471711257714555014070 0ustar /* * hc.c * * Stand-alone FRACTINT help compiler. Compile in the COMPACT memory model. * * See HC.DOC for source file syntax. * * * Revision History: * * 02-26-91 EAN Initial version. * * 03-21-91 EAN Modified for automatic paragraph formatting. * Added several new commands: * Format[+/-] Enable/disable paragraph formatting * Doc[+/-] Enable/disable output to document. * Online[+/-] Enable/disable output to online help. * Label= Defines a label. Replaces ~(...) * FF Forces a form-feed. Replaces ~~ * FormatExclude=val Exclude lines past val from * formatting. If before any topic sets * global default, otherwise set local. * FormatExclude= Set to global default. * FormatExclude=n Disable exclusion. (global or local) * FormatExclude[+/-] Enable/disable format exclusion. * Center[+/-] Enable/disable centering of text. * \ before nl Forces the end of a paragraph * Support for commands embedded in text with new * ~(...) format. * Support for multiple commands on a line separated by * commas. * Support for implict links; explicit links must now * start with an equal sign. * 04-03-91 EAN Added "include" command (works like #include) * 04-10-91 EAN Added support for "data" topics. * Added Comment/EndComment commands for multi-line * comments. * Added CompressSpaces[+/-] command. * Added DocContents command for document printing. * Added BinInc command which includes a binary file * in a data topic. * Fixed tables to flow down instead of across the page. * Makes no allowances for page breaks within tables. * 11-03-94 TIW Increased buffer size. * */ #define HC_C #define INCLUDE_COMMON /* tell helpcom.h to include common code */ #ifdef XFRACT #define strupr strlwr #else #include #endif #ifndef USE_VARARGS #include #else #include #endif #include #include #include #ifdef __TURBOC__ # include # define FNSPLIT fnsplit #else # define MAXFILE FILE_MAX_FNAME # define MAXEXT FILE_MAX_EXT # define FNSPLIT _splitpath #endif #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "helpcom.h" #ifdef XFRACT #ifndef HAVESTRI extern int stricmp(char *, char *); extern int strnicmp(char *, char *, int); #endif extern int filelength(int); extern int _splitpath(char *,char *,char *,char *,char *); #endif /* * When defined, SHOW_ERROR_LINE will cause the line number in HC.C where * errors/warnings/messages are generated to be displayed at the start of * the line. * * Used when debugging HC. Also useful for finding the line (in HC.C) that * generated a error or warning. */ #ifndef XFRACT #define SHOW_ERROR_LINE #endif #define DEFAULT_SRC_FNAME "help.src" #define DEFAULT_HLP_FNAME "fractint.hlp" #define DEFAULT_EXE_FNAME "fractint.exe" #define DEFAULT_DOC_FNAME "fractint.doc" #define TEMP_FNAME "HC.$$$" #define SWAP_FNAME "HCSWAP.$$$" #define MAX_ERRORS (25) /* stop after this many errors */ #define MAX_WARNINGS (25) /* stop after this many warnings */ /* 0 = never stop */ #define INDEX_LABEL "HELP_INDEX" #define DOCCONTENTS_TITLE "DocContent" /* #define BUFFER_SIZE (24*1024) */ #define BUFFER_SIZE (30*1024) typedef struct { int type; /* 0 = name is topic title, 1 = name is label, */ /* 2 = "special topic"; name is NULL and */ /* topic_num/topic_off is valid */ int topic_num; /* topic number to link to */ unsigned topic_off; /* offset into topic to link to */ int doc_page; /* document page # to link to */ char *name; /* name of label or title of topic to link to */ char *srcfile; /* .SRC file link appears in */ int srcline; /* .SRC file line # link appears in */ } LINK; typedef struct { unsigned offset; /* offset from start of topic text */ unsigned length; /* length of page (in chars) */ int margin; /* if > 0 then page starts in_para and text */ /* should be indented by this much */ } PAGE; /* values for TOPIC.flags */ #define TF_IN_DOC (1) /* 1 if topic is part of the printed document */ #define TF_DATA (2) /* 1 if it is a "data" topic */ typedef struct { unsigned flags; /* see #defines for TF_??? */ int doc_page; /* page number in document where topic starts */ unsigned title_len; /* length of title */ char *title; /* title for this topic */ int num_page; /* number of pages */ PAGE *page; /* list of pages */ unsigned text_len; /* lenth of topic text */ long text; /* topic text (all pages) */ long offset; /* offset to topic from start of file */ } TOPIC; typedef struct { char *name; /* its name */ int topic_num; /* topic number */ unsigned topic_off; /* offset of label in the topic's text */ int doc_page; } LABEL; /* values for CONTENT.flags */ #define CF_NEW_PAGE (1) /* true if section starts on a new page */ #define MAX_CONTENT_TOPIC (10) typedef struct { unsigned flags; char *id; char *name; int doc_page; unsigned page_num_pos; int num_topic; char is_label[MAX_CONTENT_TOPIC]; char *topic_name[MAX_CONTENT_TOPIC]; int topic_num[MAX_CONTENT_TOPIC]; char *srcfile; int srcline; } CONTENT; struct help_sig_info { unsigned long sig; int version; unsigned long base; } ; int num_topic = 0; /* topics */ TOPIC *topic; int num_label = 0; /* labels */ LABEL *label; int num_plabel = 0; /* private labels */ LABEL *plabel; int num_link = 0; /* all links */ LINK *a_link = 0; int num_contents = 0; /* the table-of-contents */ CONTENT *contents; int quiet_mode = 0; /* true if "/Q" option used */ int max_pages = 0; /* max. pages in any topic */ int max_links = 0; /* max. links on any page */ int num_doc_pages = 0; /* total number of pages in document */ FILE *srcfile; /* .SRC file */ int srcline = 0; /* .SRC line number (used for errors) */ int srccol = 0; /* .SRC column. */ int version = -1; /* help file version */ int errors = 0, /* number of errors reported */ warnings = 0; /* number of warnings reported */ char src_fname[81] = ""; /* command-line .SRC filename */ char hdr_fname[81] = ""; /* .H filename */ char hlp_fname[81] = ""; /* .HLP filename */ char *src_cfname = NULL; /* current .SRC filename */ int format_exclude = 0; /* disable formatting at this col, 0 to */ /* never disable formatting */ FILE *swapfile; long swappos; char *buffer; /* alloc'ed as BUFFER_SIZE bytes */ char *curr; /* current position in the buffer */ char cmd[128]; /* holds the current command */ int compress_spaces; int xonline; int xdoc; #define MAX_INCLUDE_STACK (5) /* allow 5 nested includes */ struct { char *fname; FILE *file; int line; int col; } include_stack[MAX_INCLUDE_STACK]; int include_stack_top = -1; #define CHK_BUFFER(off) { if ((long)(curr+(off)) - (long)buffer >= (BUFFER_SIZE-1024)) fatal(0,"Buffer overflowed -- Help topic too large."); } #ifdef __WATCOMC__ #define putw( x1, x2 ) fprintf( x2, "%c%c", x1&0xFF, x1>>8 ); #endif #ifdef XFRACT #define putw( x1, x2 ) fwrite( &(x1), 1, sizeof(int), x2); #endif /* * error/warning/message reporting functions. */ void report_errors(void) { printf("\n"); printf("Compiler Status:\n"); printf("%8d Error%c\n", errors, (errors==1) ? ' ' : 's'); printf("%8d Warning%c\n", warnings, (warnings==1) ? ' ' : 's'); } void print_msg(char *type, int lnum, char *format, va_list arg) { if (type != NULL) { printf(" %s", type); if (lnum>0) printf(" %s %d", src_cfname, lnum); printf(": "); } vprintf(format, arg); printf("\n"); } #ifndef USE_VARARGS void fatal(int diff, char *format, ...) #else void fatal(va_alist) va_dcl #endif { va_list arg; #ifndef USE_VARARGS va_start(arg, format); #else int diff; char *format; va_start(arg); diff = va_arg(arg,int); format = va_arg(arg,char *); #endif print_msg("Fatal", srcline-diff, format, arg); va_end(arg); if ( errors || warnings ) report_errors(); exit( errors + 1 ); } #ifndef USE_VARARGS void error(int diff, char *format, ...) #else void error(va_alist) va_dcl #endif { va_list arg; #ifndef USE_VARARGS va_start(arg, format); #else int diff; char *format; va_start(arg); diff = va_arg(arg,int); format = va_arg(arg,char *); #endif print_msg("Error", srcline-diff, format, arg); va_end(arg); if (++errors >= MAX_ERRORS && MAX_ERRORS > 0) fatal(0,"Too many errors!"); } #ifndef USE_VARARGS void warn(int diff, char *format, ...) #else void warn(va_alist) va_dcl #endif { va_list arg; #ifndef USE_VARARGS va_start(arg, format); #else int diff; char *format; va_start(arg); diff = va_arg(arg, int); format = va_arg(arg, char *); #endif print_msg("Warning", srcline-diff, format, arg); va_end(arg); if (++warnings >= MAX_WARNINGS && MAX_WARNINGS > 0) fatal(0,"Too many warnings!"); } #ifndef USE_VARARGS void notice(char *format, ...) #else void notice(va_alist) va_dcl #endif { va_list arg; #ifndef USE_VARARGS va_start(arg, format); #else char *format; va_start(arg); format = va_arg(arg,char *); #endif print_msg("Note", srcline, format, arg); va_end(arg); } #ifndef USE_VARARGS void msg(char *format, ...) #else void msg(va_alist) va_dcl #endif { va_list arg; #ifdef USE_VARARGS char *format; #endif if (quiet_mode) return; #ifndef USE_VARARGS va_start(arg, format); #else va_start(arg); format = va_arg(arg,char *); #endif print_msg(NULL, 0, format, arg); va_end(arg); } #ifdef SHOW_ERROR_LINE # define fatal (printf("[%04d] ", __LINE__), fatal) # define error (printf("[%04d] ", __LINE__), error) # define warn (printf("[%04d] ", __LINE__), warn) # define notice (printf("[%04d] ", __LINE__), notice) # define msg (printf((quiet_mode)?"":"[%04d] ", __LINE__), msg) #endif /* * store-topic-text-to-disk stuff. */ void alloc_topic_text(TOPIC *t, unsigned size) { t->text_len = size; t->text = swappos; swappos += size; fseek(swapfile, t->text, SEEK_SET); fwrite(buffer, 1, t->text_len, swapfile); } char *get_topic_text(TOPIC *t) { fseek(swapfile, t->text, SEEK_SET); fread(buffer, 1, t->text_len, swapfile); return (buffer); } void release_topic_text(TOPIC *t, int save) { if ( save ) { fseek(swapfile, t->text, SEEK_SET); fwrite(buffer, 1, t->text_len, swapfile); } } /* * memory-allocation functions. */ #define new(item) (item *)newx(sizeof(item)) #define delete(item) free(item) VOIDPTR newx(unsigned size) { VOIDPTR ptr; ptr = malloc(size); if (ptr == NULL) fatal(0,"Out of memory!"); return (ptr); } VOIDPTR renewx(VOIDPTR ptr, unsigned size) { ptr = realloc(ptr, size); if (ptr == NULL) fatal(0,"Out of memory!"); return (ptr); } char *dupstr(char *s, unsigned len) { char *ptr; if (len == 0) len = strlen(s) + 1; ptr = newx(len); memcpy(ptr, s, len); return (ptr); } #define LINK_ALLOC_SIZE (16) int add_link(LINK *l) { if (num_link == 0) a_link = newx( sizeof(LINK)*LINK_ALLOC_SIZE ); else if (num_link%LINK_ALLOC_SIZE == 0) a_link = renewx(a_link, sizeof(LINK) * (num_link+LINK_ALLOC_SIZE) ); a_link[num_link] = *l; return( num_link++ ); } #define PAGE_ALLOC_SIZE (4) int add_page(TOPIC *t, PAGE *p) { if (t->num_page == 0) t->page = newx( sizeof(PAGE)*PAGE_ALLOC_SIZE ); else if (t->num_page%PAGE_ALLOC_SIZE == 0) t->page = renewx(t->page, sizeof(PAGE) * (t->num_page+PAGE_ALLOC_SIZE) ); t->page[t->num_page] = *p; return ( t->num_page++ ); } #define TOPIC_ALLOC_SIZE (16) int add_topic(TOPIC *t) { if (num_topic == 0) topic = newx( sizeof(TOPIC)*TOPIC_ALLOC_SIZE ); else if (num_topic%TOPIC_ALLOC_SIZE == 0) topic = renewx(topic, sizeof(TOPIC) * (num_topic+TOPIC_ALLOC_SIZE) ); topic[num_topic] = *t; return ( num_topic++ ); } #define LABEL_ALLOC_SIZE (16) int add_label(LABEL *l) { if (l->name[0] == '@') /* if it's a private label... */ { if (num_plabel == 0) plabel = newx( sizeof(LABEL)*LABEL_ALLOC_SIZE ); else if (num_plabel%LABEL_ALLOC_SIZE == 0) plabel = renewx(plabel, sizeof(LABEL) * (num_plabel+LABEL_ALLOC_SIZE) ); plabel[num_plabel] = *l; return ( num_plabel++ ); } else { if (num_label == 0) label = newx( sizeof(LABEL)*LABEL_ALLOC_SIZE ); else if (num_label%LABEL_ALLOC_SIZE == 0) label = renewx(label, sizeof(LABEL) * (num_label+LABEL_ALLOC_SIZE) ); label[num_label] = *l; return ( num_label++ ); } } #define CONTENTS_ALLOC_SIZE (16) int add_content(CONTENT *c) { if (num_contents == 0) contents = newx( sizeof(CONTENT)*CONTENTS_ALLOC_SIZE ); else if (num_contents%CONTENTS_ALLOC_SIZE == 0) contents = renewx(contents, sizeof(CONTENT) * (num_contents+CONTENTS_ALLOC_SIZE) ); contents[num_contents] = *c; return ( num_contents++ ); } /* * read_char() stuff */ #define READ_CHAR_BUFF_SIZE (32) int read_char_buff[READ_CHAR_BUFF_SIZE]; int read_char_buff_pos = -1; int read_char_sp = 0; void unread_char(int ch) /* * Will not handle new-lines or tabs correctly! */ { if (read_char_buff_pos+1 >= READ_CHAR_BUFF_SIZE) fatal(0,"Compiler Error -- Read char buffer overflow!"); read_char_buff[++read_char_buff_pos] = ch; --srccol; } void unread_string(char *s) { int p = strlen(s); while (p-- > 0) unread_char(s[p]); } int eos(void) /* end-of-source ? */ { return ( !((read_char_sp==0) && (read_char_buff_pos==0) && feof(srcfile)) ); } int _read_char(void) { int ch; if (srcline <= 0) { srcline = 1; srccol = 0; } if (read_char_buff_pos >= 0) { ++srccol; return ( read_char_buff[read_char_buff_pos--] ); } if (read_char_sp > 0) { --read_char_sp; return (' '); } if ( feof(srcfile) ) return (-1); while (1) { ch = getc(srcfile); switch (ch) { case '\t': /* expand a tab */ { int diff = ( ( (srccol/8) + 1 ) * 8 ) - srccol; srccol += diff; read_char_sp += diff; break; } case ' ': ++srccol; ++read_char_sp; break; case '\n': read_char_sp = 0; /* delete spaces before a \n */ srccol = 0; ++srcline; return ('\n'); case -1: /* EOF */ if (read_char_sp > 0) { --read_char_sp; return (' '); } return (-1); default: if (read_char_sp > 0) { ungetc(ch, srcfile); --read_char_sp; return (' '); } ++srccol; return (ch); } /* switch */ } } int read_char(void) { int ch; ch = _read_char(); while (ch == ';' && srccol==1) /* skip over comments */ { ch = _read_char(); while (ch!='\n' && ch!=-1 ) ch = _read_char(); ch = _read_char(); } if (ch == '\\') /* process an escape code */ { ch = _read_char(); if (ch >= '0' && ch <= '9') { char buff[4]; int ctr; for (ctr=0; ; ctr++) { if ( ch<'0' || ch>'9' || ch==-1 || ctr>=3 ) { unread_char(ch); break; } buff[ctr] = ch; ch = _read_char(); } buff[ctr] = '\0'; ch = atoi(buff); } #ifdef XFRACT /* Convert graphics arrows into keyboard chars */ if (ch>=24 && ch<=27) { ch = "KJHL"[ch-24]; } #endif ch |= 0x100; } if ( (ch & 0xFF) == 0 ) { error(0,"Null character (\'\\0\') not allowed!"); ch = 0x1FF; /* since we've had an error the file will not be written; */ /* the value we return doesn't really matter */ } return(ch); } /* * misc. search functions. */ LABEL *find_label(char *name) { int l; LABEL *lp; if (*name == '@') { for (l=0, lp=plabel; lname) == 0 ) return (lp); } else { for (l=0, lp=label; lname) == 0 ) return (lp); } return (NULL); } int find_topic_title(char *title) { int t; int len; while (*title == ' ') ++title; len = strlen(title) - 1; while ( title[len] == ' ' && len > 0 ) --len; ++len; if ( len > 2 && title[0] == '\"' && title[len-1] == '\"' ) { ++title; len -= 2; } for (t=0; t 0 ) { ch = read_char(); if ( ch == -1 ) { *buff++ = '\0'; break; } if ( (ch&0xFF) <= MAX_CMD ) *buff++ = CMD_LITERAL; *buff++ = ch; if ( (ch&0x100)==0 && strchr(stop_chars, ch) != NULL ) break; } return ( buff-1 ); } void skip_over(char *skip) { int ch; while (1) { ch = read_char(); if ( ch == -1 ) break; else if ( (ch&0x100) == 0 && strchr(skip, ch) == NULL ) { unread_char(ch); break; } } } char *pchar(int ch) { static char buff[16]; if ( ch >= 0x20 && ch <= 0x7E ) sprintf(buff, "\'%c\'", ch); else sprintf(buff, "\'\\x%02X\'", ch&0xFF); return (buff); } void put_spaces(int how_many) { if (how_many > 2 && compress_spaces) { if (how_many > 255) { error(0,"Too many spaces (over 255)."); how_many = 255; } *curr++ = CMD_SPACE; *curr++ = (BYTE)how_many; } else { while (how_many-- > 0) *curr++ = ' '; } } int get_next_item(void) /* used by parse_contents() */ { int last; char *ptr; skip_over(" \t\n"); ptr = read_until(cmd, 128, ",}"); last = (*ptr == '}'); --ptr; while ( ptr >= cmd && strchr(" \t\n",*ptr) ) /* strip trailing spaces */ --ptr; *(++ptr) = '\0'; return (last); } void process_contents(void) { CONTENT c; char *ptr; int indent; int ch; TOPIC t; t.flags = 0; t.title_len = strlen(DOCCONTENTS_TITLE)+1; t.title = dupstr(DOCCONTENTS_TITLE, t.title_len); t.doc_page = -1; t.num_page = 0; curr = buffer; c.flags = 0; c.id = dupstr("",1); c.name = dupstr("",1); c.doc_page = -1; c.page_num_pos = 0; c.num_topic = 1; c.is_label[0] = 0; c.topic_name[0] = dupstr(DOCCONTENTS_TITLE,0); c.srcline = -1; add_content(&c); while (1) { ch = read_char(); if (ch == '{') /* process a CONTENT entry */ { int last; c.flags = 0; c.num_topic = 0; c.doc_page = -1; c.srcfile = src_cfname; c.srcline = srcline; if ( get_next_item() ) { error(0,"Unexpected end of DocContent entry."); continue; } c.id = dupstr(cmd,0); if ( get_next_item() ) { error(0,"Unexpected end of DocContent entry."); continue; } indent = atoi(cmd); last = get_next_item(); if ( cmd[0] == '\"' ) { ptr = cmd+1; if (ptr[strlen(ptr)-1] == '\"') ptr[strlen(ptr)-1] = '\0'; else warn(0,"Missing ending quote."); c.is_label[c.num_topic] = 0; c.topic_name[c.num_topic] = dupstr(ptr,0); ++c.num_topic; c.name = dupstr(ptr,0); } else c.name = dupstr(cmd,0); /* now, make the entry in the buffer */ sprintf(curr, "%-5s %*.0s%s", c.id, indent*2, "", c.name); ptr = curr + strlen(curr); while ( (ptr-curr) < PAGE_WIDTH-10 ) *ptr++ = '.'; c.page_num_pos = (unsigned) ( (ptr-3) - buffer ); curr = ptr; while (!last) { last = get_next_item(); if ( stricmp(cmd, "FF") == 0 ) { if ( c.flags & CF_NEW_PAGE ) warn(0,"FF already present in this entry."); c.flags |= CF_NEW_PAGE; continue; } if (cmd[0] == '\"') { ptr = cmd+1; if (ptr[strlen(ptr)-1] == '\"') ptr[strlen(ptr)-1] = '\0'; else warn(0,"Missing ending quote."); c.is_label[c.num_topic] = 0; c.topic_name[c.num_topic] = dupstr(ptr,0); } else { c.is_label[c.num_topic] = 1; c.topic_name[c.num_topic] = dupstr(cmd,0); } if ( ++c.num_topic >= MAX_CONTENT_TOPIC ) { error(0,"Too many topics in DocContent entry."); break; } } add_content(&c); } else if (ch == '~') /* end at any command */ { unread_char(ch); break; } else *curr++ = ch; CHK_BUFFER(0); } alloc_topic_text(&t, (unsigned) (curr - buffer) ); add_topic(&t); } int parse_link(void) /* returns length of link or 0 on error */ { char *ptr; char *end; int bad = 0; int len; LINK l; int lnum; int err_off; l.srcfile = src_cfname; l.srcline = srcline; l.doc_page = -1; end = read_until(cmd, 128, "}\n"); /* get the entire hot-link */ if (*end == '\0') { error(0,"Unexpected EOF in hot-link."); return (0); } if (*end == '\n') { err_off = 1; warn(1,"Hot-link has no closing curly-brace (\'}\')."); } else err_off = 0; *end = '\0'; if (cmd[0] == '=') /* it's an "explicit" link to a label or "special" */ { ptr = strchr(cmd, ' '); if (ptr == NULL) ptr = end; else *ptr++ = '\0'; len = (int) (end - ptr); if ( cmd[1] == '-' ) { l.type = 2; /* type 2 = "special" */ l.topic_num = atoi(cmd+1); l.topic_off = 0; l.name = NULL; } else { l.type = 1; /* type 1 = to a label */ if ((int)strlen(cmd) > 32) warn(err_off, "Label is long."); if (cmd[1] == '\0') { error(err_off, "Explicit hot-link has no Label."); bad = 1; } else l.name = dupstr(cmd+1,0); } if (len == 0) warn(err_off, "Explicit hot-link has no title."); } else { ptr = cmd; l.type = 0; /* type 0 = topic title */ len = (int) (end - ptr); if (len == 0) { error(err_off, "Implicit hot-link has no title."); bad = 1; } l.name = dupstr(ptr,len+1); l.name[len] = '\0'; } if ( !bad ) { CHK_BUFFER(1+3*sizeof(int)+len+1) lnum = add_link(&l); *curr++ = CMD_LINK; setint(curr,lnum); curr += 3*sizeof(int); memcpy(curr, ptr, len); curr += len; *curr++ = CMD_LINK; return (len); } else return (0); } #define MAX_TABLE_SIZE (100) int create_table(void) { char *ptr; int width; int cols; int start_off; int first_link; int rows; int r, c; int ch; int done; int len; int lnum; int count; char *title[MAX_TABLE_SIZE]; char *table_start; ptr = strchr(cmd, '='); if (ptr == NULL) return (0); /* should never happen! */ ptr++; len = sscanf(ptr, " %d %d %d", &width, &cols, &start_off); if (len < 3) { error(1,"Too few arguments to Table."); return (0); } if (width<=0 || width > 78 || cols<=0 || start_off<0 || start_off > 78) { error(1,"Argument out of range."); return (0); } done = 0; first_link = num_link; table_start = curr; count = 0; /* first, read all the links in the table */ do { do ch = read_char(); while ( ch=='\n' || ch == ' ' ); if (done) break; switch (ch) { case -1: error(0,"Unexpected EOF in a Table."); return(0); case '{': if (count >= MAX_TABLE_SIZE) fatal(0,"Table is too large."); len = parse_link(); curr = table_start; /* reset to the start... */ title[count] = dupstr(curr+3*sizeof(int)+1, len+1); if (len >= width) { warn(1,"Link is too long; truncating."); len = width-1; } title[count][len] = '\0'; ++count; break; case '~': { int imbedded; ch = read_char(); if (ch=='(') imbedded = 1; else { imbedded = 0; unread_char(ch); } ptr = read_until(cmd, 128, ")\n,"); ch = *ptr; *ptr = '\0'; if ( stricmp(cmd, "EndTable") == 0 ) done = 1; else { error(1,"Unexpected command in table \"%s\"", cmd); warn(1,"Command will be ignored."); } if (ch == ',') { if (imbedded) unread_char('('); unread_char('~'); } } break; default: error(0,"Unexpected character %s.", pchar(ch)); break; } } while (!done); /* now, put all the links into the buffer... */ rows = 1 + ( count / cols ); for (r=0; r= num_link ) break; len = strlen(title[lnum]); *curr++ = CMD_LINK; setint(curr,first_link+lnum); curr += 3*sizeof(int); memcpy(curr, title[lnum], len); curr += len; *curr++ = CMD_LINK; delete(title[lnum]); if ( c < cols-1 ) put_spaces( width-len ); } *curr++ = '\n'; } return (1); } void process_comment(void) { int ch; while ( 1 ) { ch = read_char(); if (ch == '~') { int imbedded; char *ptr; ch = read_char(); if (ch=='(') imbedded = 1; else { imbedded = 0; unread_char(ch); } ptr = read_until(cmd, 128, ")\n,"); ch = *ptr; *ptr = '\0'; if ( stricmp(cmd, "EndComment") == 0 ) { if (ch == ',') { if (imbedded) unread_char('('); unread_char('~'); } break; } } else if ( ch == -1 ) { error(0,"Unexpected EOF in Comment"); break; } } } void process_bininc(void) { int handle; long len; if ( (handle=open(cmd+7, O_RDONLY|O_BINARY)) == -1 ) { error(0,"Unable to open \"%s\"", cmd+7); return ; } len = filelength(handle); if ( len >= BUFFER_SIZE ) { error(0,"File \"%s\" is too large to BinInc (%dK).", cmd+7, (int)(len>>10)); close(handle); return ; } /* * Since we know len is less than BUFFER_SIZE (and therefore less then * 64K) we can treat it as an unsigned. */ CHK_BUFFER((unsigned)len); read(handle, curr, (unsigned)len); curr += (unsigned)len; close(handle); } void start_topic(TOPIC *t, char *title, int title_len) { t->flags = 0; t->title_len = title_len; t->title = dupstr(title, title_len+1); t->title[title_len] = '\0'; t->doc_page = -1; t->num_page = 0; curr = buffer; } void end_topic(TOPIC *t) { alloc_topic_text(t, (unsigned) (curr - buffer) ); add_topic(t); } int end_of_sentence(char *ptr) /* true if ptr is at the end of a sentence */ { if ( *ptr == ')') --ptr; if ( *ptr == '\"') --ptr; return ( *ptr=='.' || *ptr=='?' || *ptr=='!' ); } void add_blank_for_split(void) /* add space at curr for merging two lines */ { if ( !is_hyphen(curr-1) ) /* no spaces if it's a hyphen */ { if ( end_of_sentence(curr-1) ) *curr++ = ' '; /* two spaces at end of a sentence */ *curr++ = ' '; } } void put_a_char(int ch, TOPIC *t) { if (ch == '{' && !(t->flags & TF_DATA) ) /* is it a hot-link? */ parse_link(); else { if ( (ch&0xFF) <= MAX_CMD) *curr++ = CMD_LITERAL; *curr++ = ch; } } enum STATES /* states for FSM's */ { S_Start, /* initial state, between paragraphs */ S_StartFirstLine, /* spaces at start of first line */ S_FirstLine, /* text on the first line */ S_FirstLineSpaces, /* spaces on the first line */ S_StartSecondLine, /* spaces at start of second line */ S_Line, /* text on lines after the first */ S_LineSpaces, /* spaces on lines after the first */ S_StartLine, /* spaces at start of lines after second */ S_FormatDisabled, /* format automatically disabled for this line */ S_FormatDisabledSpaces, /* spaces in line which format is disabled */ S_Spaces } ; void check_command_length(int eoff, int len) { if (strlen(cmd) != len) error(eoff, "Invalid text after a command \"%s\"", cmd+len); } void read_src(char *fname) { int ch; char *ptr; TOPIC t; LABEL lbl; char *margin_pos = NULL; int in_topic = 0, formatting = 1, state = S_Start, num_spaces = 0, margin = 0, in_para = 0, centering = 0, lformat_exclude = format_exclude, again; xonline = xdoc = 0; src_cfname = fname; if ( (srcfile = fopen(fname, "rt")) == NULL ) fatal(0,"Unable to open \"%s\"", fname); msg("Compiling: %s", fname); in_topic = 0; curr = buffer; while ( 1 ) { ch = read_char(); if ( ch == -1 ) /* EOF? */ { if ( include_stack_top >= 0) { fclose(srcfile); src_cfname = include_stack[include_stack_top].fname; srcfile = include_stack[include_stack_top].file; srcline = include_stack[include_stack_top].line; srccol = include_stack[include_stack_top].col; --include_stack_top; continue; } else { if (in_topic) /* if we're in a topic, finish it */ end_topic(&t); if (num_topic == 0) warn(0,".SRC file has no topics."); break; } } if (ch == '~') /* is is a command? */ { int imbedded; int eoff; int done; ch = read_char(); if (ch == '(') { imbedded = 1; eoff = 0; } else { imbedded = 0; eoff=0; unread_char(ch); } done = 0; while ( !done ) { do ch = read_char(); while (ch == ' '); unread_char(ch); if (imbedded) ptr = read_until(cmd, 128, ")\n,"); else ptr = read_until(cmd, 128, "\n,"); done = 1; if ( *ptr == '\0' ) { error(0,"Unexpected EOF in command."); break; } if (*ptr == '\n') ++eoff; if ( imbedded && *ptr == '\n' ) error(eoff,"Imbedded command has no closing parend (\')\')"); done = (*ptr != ','); /* we done if it's not a comma */ if ( *ptr != '\n' && *ptr != ')' && *ptr != ',' ) { error(0,"Command line too long."); break; } *ptr = '\0'; /* commands allowed anytime... */ if ( strnicmp(cmd, "Topic=", 6) == 0 ) { if (in_topic) /* if we're in a topic, finish it */ end_topic(&t); else in_topic = 1; if (cmd[6] == '\0') warn(eoff,"Topic has no title."); else if ((int)strlen(cmd+6) > 70) error(eoff,"Topic title is too long."); else if ((int)strlen(cmd+6) > 60) warn(eoff,"Topic title is long."); if ( find_topic_title(cmd+6) != -1 ) error(eoff,"Topic title already exists."); start_topic(&t, cmd+6, (unsigned)(ptr-(cmd+6))); formatting = 1; centering = 0; state = S_Start; in_para = 0; num_spaces = 0; xonline = xdoc = 0; lformat_exclude = format_exclude; compress_spaces = 1; continue; } else if ( strnicmp(cmd, "Data=", 5) == 0 ) { if (in_topic) /* if we're in a topic, finish it */ end_topic(&t); else in_topic = 1; if (cmd[5] == '\0') warn(eoff,"Data topic has no label."); if ( !validate_label_name(cmd+5) ) { error(eoff,"Label \"%s\" contains illegal characters.", cmd+5); continue; } if ( find_label(cmd+5) != NULL ) { error(eoff,"Label \"%s\" already exists", cmd+5); continue; } if ( cmd[5] == '@' ) warn(eoff, "Data topic has a local label."); start_topic(&t, "", 0); t.flags |= TF_DATA; if ((int)strlen(cmd+5) > 32) warn(eoff,"Label name is long."); lbl.name = dupstr(cmd+5, 0); lbl.topic_num = num_topic; lbl.topic_off = 0; lbl.doc_page = -1; add_label(&lbl); formatting = 0; centering = 0; state = S_Start; in_para = 0; num_spaces = 0; xonline = xdoc = 0; lformat_exclude = format_exclude; compress_spaces = 0; continue; } else if ( strnicmp(cmd, "DocContents", 11) == 0 ) { check_command_length(eoff, 11); if (in_topic) /* if we're in a topic, finish it */ end_topic(&t); if (!done) { if (imbedded) unread_char('('); unread_char('~'); done = 1; } compress_spaces = 1; process_contents(); in_topic = 0; continue; } else if ( stricmp(cmd, "Comment") == 0 ) { process_comment(); continue; } else if ( strnicmp(cmd, "FormatExclude", 13) == 0 ) { if (cmd[13] == '-') { check_command_length(eoff, 14); if ( in_topic ) { if (lformat_exclude > 0) lformat_exclude = -lformat_exclude; else warn(eoff,"\"FormatExclude-\" is already in effect."); } else { if (format_exclude > 0) format_exclude = -format_exclude; else warn(eoff,"\"FormatExclude-\" is already in effect."); } } else if (cmd[13] == '+') { check_command_length(eoff,14); if ( in_topic ) { if (lformat_exclude < 0) lformat_exclude = -lformat_exclude; else warn(eoff,"\"FormatExclude+\" is already in effect."); } else { if (format_exclude < 0) format_exclude = -format_exclude; else warn(eoff,"\"FormatExclude+\" is already in effect."); } } else if (cmd[13] == '=') { if (cmd[14] == 'n' || cmd[14] == 'N') { check_command_length(eoff,15); if (in_topic) lformat_exclude = 0; else format_exclude = 0; } else if (cmd[14] == '\0') lformat_exclude = format_exclude; else { int n = ( ( (in_topic) ? lformat_exclude : format_exclude) < 0 ) ? -1 : 1; lformat_exclude = atoi(cmd+14); if ( lformat_exclude <= 0 ) { error(eoff,"Invalid argument to FormatExclude="); lformat_exclude = 0; } lformat_exclude *= n; if ( !in_topic ) format_exclude = lformat_exclude; } } else error(eoff,"Invalid format for FormatExclude"); continue; } else if ( strnicmp(cmd, "Include ", 8) == 0 ) { if (include_stack_top >= MAX_INCLUDE_STACK-1) error(eoff, "Too many nested Includes."); else { ++include_stack_top; include_stack[include_stack_top].fname = src_cfname; include_stack[include_stack_top].file = srcfile; include_stack[include_stack_top].line = srcline; include_stack[include_stack_top].col = srccol; strupr(cmd+8); if ( (srcfile = fopen(cmd+8, "rt")) == NULL ) { error(eoff, "Unable to open \"%s\"", cmd+8); srcfile = include_stack[include_stack_top--].file; } src_cfname = dupstr(cmd+8,0); /* never deallocate! */ srcline = 1; srccol = 0; } continue; } /* commands allowed only before all topics... */ if ( !in_topic ) { if ( strnicmp(cmd, "HdrFile=", 8) == 0 ) { if (hdr_fname[0] != '\0') warn(eoff,"Header Filename has already been defined."); strcpy(hdr_fname, cmd+8); strupr(hdr_fname); } else if ( strnicmp(cmd, "HlpFile=", 8) == 0 ) { if (hlp_fname[0] != '\0') warn(eoff,"Help Filename has already been defined."); strcpy(hlp_fname, cmd+8); strupr(hlp_fname); } else if ( strnicmp(cmd, "Version=", 8) == 0 ) { if (version != -1) /* an unlikely value */ warn(eoff,"Help version has already been defined"); version = atoi(cmd+8); } else error(eoff,"Bad or unexpected command \"%s\"", cmd); continue; } /* commands allowed only in a topic... */ else { if (strnicmp(cmd, "FF", 2) == 0 ) { check_command_length(eoff,2); if ( in_para ) *curr++ = '\n'; /* finish off current paragraph */ *curr++ = CMD_FF; state = S_Start; in_para = 0; num_spaces = 0; } else if (strnicmp(cmd, "DocFF", 5) == 0 ) { check_command_length(eoff,5); if ( in_para ) *curr++ = '\n'; /* finish off current paragraph */ if (!xonline) *curr++ = CMD_XONLINE; *curr++ = CMD_FF; if (!xonline) *curr++ = CMD_XONLINE; state = S_Start; in_para = 0; num_spaces = 0; } else if (strnicmp(cmd, "OnlineFF", 8) == 0 ) { check_command_length(eoff,8); if ( in_para ) *curr++ = '\n'; /* finish off current paragraph */ if (!xdoc) *curr++ = CMD_XDOC; *curr++ = CMD_FF; if (!xdoc) *curr++ = CMD_XDOC; state = S_Start; in_para = 0; num_spaces = 0; } else if ( strnicmp(cmd, "Label=", 6) == 0 ) { if ((int)strlen(cmd+6) <= 0) error(eoff,"Label has no name."); else if ( !validate_label_name(cmd+6) ) error(eoff,"Label \"%s\" contains illegal characters.", cmd+6); else if ( find_label(cmd+6) != NULL ) error(eoff,"Label \"%s\" already exists", cmd+6); else { if ((int)strlen(cmd+6) > 32) warn(eoff,"Label name is long."); if ( (t.flags & TF_DATA) && cmd[6] == '@' ) warn(eoff, "Data topic has a local label."); lbl.name = dupstr(cmd+6, 0); lbl.topic_num = num_topic; lbl.topic_off = (unsigned)(curr - buffer); lbl.doc_page = -1; add_label(&lbl); } } else if ( strnicmp(cmd, "Table=", 6) == 0 ) { if ( in_para ) { *curr++ = '\n'; /* finish off current paragraph */ in_para = 0; num_spaces = 0; state = S_Start; } if (!done) { if (imbedded) unread_char('('); unread_char('~'); done = 1; } create_table(); } else if ( strnicmp(cmd, "FormatExclude", 12) == 0 ) { if (cmd[13] == '-') { check_command_length(eoff,14); if (lformat_exclude > 0) lformat_exclude = -lformat_exclude; else warn(0,"\"FormatExclude-\" is already in effect."); } else if (cmd[13] == '+') { check_command_length(eoff,14); if (lformat_exclude < 0) lformat_exclude = -lformat_exclude; else warn(0,"\"FormatExclude+\" is already in effect."); } else error(eoff,"Unexpected or invalid argument to FormatExclude."); } else if ( strnicmp(cmd, "Format", 6) == 0 ) { if (cmd[6] == '+') { check_command_length(eoff,7); if ( !formatting ) { formatting = 1; in_para = 0; num_spaces = 0; state = S_Start; } else warn(eoff,"\"Format+\" is already in effect."); } else if (cmd[6] == '-') { check_command_length(eoff,7); if ( formatting ) { if ( in_para ) *curr++ = '\n'; /* finish off current paragraph */ state = S_Start; in_para = 0; formatting = 0; num_spaces = 0; state = S_Start; } else warn(eoff,"\"Format-\" is already in effect."); } else error(eoff,"Invalid argument to Format."); } else if ( strnicmp(cmd, "Online", 6) == 0 ) { if (cmd[6] == '+') { check_command_length(eoff,7); if ( xonline ) { *curr++ = CMD_XONLINE; xonline = 0; } else warn(eoff,"\"Online+\" already in effect."); } else if (cmd[6] == '-') { check_command_length(eoff,7); if ( !xonline ) { *curr++ = CMD_XONLINE; xonline = 1; } else warn(eoff,"\"Online-\" already in effect."); } else error(eoff,"Invalid argument to Online."); } else if ( strnicmp(cmd, "Doc", 3) == 0 ) { if (cmd[3] == '+') { check_command_length(eoff,4); if ( xdoc ) { *curr++ = CMD_XDOC; xdoc = 0; } else warn(eoff,"\"Doc+\" already in effect."); } else if (cmd[3] == '-') { check_command_length(eoff,4); if ( !xdoc ) { *curr++ = CMD_XDOC; xdoc = 1; } else warn(eoff,"\"Doc-\" already in effect."); } else error(eoff,"Invalid argument to Doc."); } else if ( strnicmp(cmd, "Center", 6) == 0 ) { if (cmd[6] == '+') { check_command_length(eoff,7); if ( !centering ) { centering = 1; if ( in_para ) { *curr++ = '\n'; in_para = 0; } state = S_Start; /* for centering FSM */ } else warn(eoff,"\"Center+\" already in effect."); } else if (cmd[6] == '-') { check_command_length(eoff,7); if ( centering ) { centering = 0; state = S_Start; /* for centering FSM */ } else warn(eoff,"\"Center-\" already in effect."); } else error(eoff,"Invalid argument to Center."); } else if ( strnicmp(cmd, "CompressSpaces", 14) == 0 ) { check_command_length(eoff,15); if ( cmd[14] == '+' ) { if ( compress_spaces ) warn(eoff,"\"CompressSpaces+\" is already in effect."); else compress_spaces = 1; } else if ( cmd[14] == '-' ) { if ( !compress_spaces ) warn(eoff,"\"CompressSpaces-\" is already in effect."); else compress_spaces = 0; } else error(eoff,"Invalid argument to CompressSpaces."); } else if ( strnicmp("BinInc ", cmd, 7) == 0 ) { if ( !(t.flags & TF_DATA) ) error(eoff,"BinInc allowed only in Data topics."); else process_bininc(); } else error(eoff,"Bad or unexpected command \"%s\".", cmd); } /* else */ } /* while (!done) */ continue; } if ( !in_topic ) { cmd[0] = ch; ptr = read_until(cmd+1, 127, "\n~"); if (*ptr == '~') unread_char('~'); *ptr = '\0'; error(0,"Text outside of any topic \"%s\".", cmd); continue; } if ( centering ) { do { again = 0; /* default */ switch (state) { case S_Start: if (ch == ' ') ; /* do nothing */ else if ( (ch&0xFF) == '\n' ) *curr++ = ch; /* no need to center blank lines. */ else { *curr++ = CMD_CENTER; state = S_Line; again = 1; } break; case S_Line: put_a_char(ch, &t); if ( (ch&0xFF) == '\n') state = S_Start; break; } /* switch */ } while (again); } else if ( formatting ) { int again; do { again = 0; /* default */ switch (state) { case S_Start: if ( (ch&0xFF) == '\n' ) *curr++ = ch; else { state = S_StartFirstLine; num_spaces = 0; again = 1; } break; case S_StartFirstLine: if ( ch == ' ') ++num_spaces; else { if (lformat_exclude > 0 && num_spaces >= lformat_exclude ) { put_spaces(num_spaces); num_spaces = 0; state = S_FormatDisabled; again = 1; } else { *curr++ = CMD_PARA; *curr++ = (char)num_spaces; *curr++ = (char)num_spaces; margin_pos = curr - 1; state = S_FirstLine; again = 1; in_para = 1; } } break; case S_FirstLine: if (ch == '\n') { state = S_StartSecondLine; num_spaces = 0; } else if (ch == ('\n'|0x100) ) /* force end of para ? */ { *curr++ = '\n'; in_para = 0; state = S_Start; } else if ( ch == ' ' ) { state = S_FirstLineSpaces; num_spaces = 1; } else put_a_char(ch, &t); break; case S_FirstLineSpaces: if (ch == ' ') ++num_spaces; else { put_spaces(num_spaces); state = S_FirstLine; again = 1; } break; case S_StartSecondLine: if ( ch == ' ') ++num_spaces; else if ((ch&0xFF) == '\n') /* a blank line means end of a para */ { *curr++ = '\n'; /* end the para */ *curr++ = '\n'; /* for the blank line */ in_para = 0; state = S_Start; } else { if (lformat_exclude > 0 && num_spaces >= lformat_exclude ) { *curr++ = '\n'; in_para = 0; put_spaces(num_spaces); num_spaces = 0; state = S_FormatDisabled; again = 1; } else { add_blank_for_split(); margin = num_spaces; *margin_pos = (char)num_spaces; state = S_Line; again = 1; } } break; case S_Line: /* all lines after the first */ if (ch == '\n') { state = S_StartLine; num_spaces = 0; } else if (ch == ('\n' | 0x100) ) /* force end of para ? */ { *curr++ = '\n'; in_para = 0; state = S_Start; } else if ( ch == ' ' ) { state = S_LineSpaces; num_spaces = 1; } else put_a_char(ch, &t); break; case S_LineSpaces: if (ch == ' ') ++num_spaces; else { put_spaces(num_spaces); state = S_Line; again = 1; } break; case S_StartLine: /* for all lines after the second */ if ( ch == ' ') ++num_spaces; else if ((ch&0xFF) == '\n') /* a blank line means end of a para */ { *curr++ = '\n'; /* end the para */ *curr++ = '\n'; /* for the blank line */ in_para = 0; state = S_Start; } else { if ( num_spaces != margin ) { *curr++ = '\n'; in_para = 0; state = S_StartFirstLine; /* with current num_spaces */ again = 1; } else { add_blank_for_split(); state = S_Line; again = 1; } } break; case S_FormatDisabled: if ( ch == ' ' ) { state = S_FormatDisabledSpaces; num_spaces = 1; } else { if ( (ch&0xFF) == '\n' ) state = S_Start; put_a_char(ch, &t); } break; case S_FormatDisabledSpaces: if ( ch == ' ' ) ++num_spaces; else { put_spaces(num_spaces); num_spaces = 0; /* is this needed? */ state = S_FormatDisabled; again = 1; } break; } /* switch (state) */ } while (again); } else { do { again = 0; /* default */ switch (state) { case S_Start: if ( ch == ' ' ) { state = S_Spaces; num_spaces = 1; } else put_a_char(ch, &t); break; case S_Spaces: if (ch == ' ') ++num_spaces; else { put_spaces(num_spaces); num_spaces = 0; /* is this needed? */ state = S_Start; again = 1; } break; } /* switch */ } while (again); } CHK_BUFFER(0) } /* while ( 1 ) */ fclose(srcfile); srcline = -1; } /* * stuff to resolve hot-link references. */ void make_hot_links(void) /* * calculate topic_num/topic_off for each link. */ { LINK *l; LABEL *lbl; int lctr; int t; CONTENT *c; int ctr; msg("Making hot-links."); /* * Calculate topic_num for all entries in DocContents. Also set * "TF_IN_DOC" flag for all topics included in the document. */ for (lctr=0, c=contents; lctrnum_topic; ctr++) { if ( c->is_label[ctr] ) { lbl = find_label(c->topic_name[ctr]); if (lbl == NULL) { src_cfname = c->srcfile; srcline = c->srcline; error(0,"Cannot find DocContent label \"%s\".", c->topic_name[ctr]); srcline = -1; } else { if ( topic[lbl->topic_num].flags & TF_DATA ) { src_cfname = c->srcfile; srcline = c->srcline; error(0,"Label \"%s\" is a data-only topic.", c->topic_name[ctr]); srcline = -1; } else { c->topic_num[ctr] = lbl->topic_num; if ( topic[lbl->topic_num].flags & TF_IN_DOC ) warn(0,"Topic \"%s\" appears in document more than once.", topic[lbl->topic_num].title); else topic[lbl->topic_num].flags |= TF_IN_DOC; } } } else { t = find_topic_title(c->topic_name[ctr]); if (t == -1) { src_cfname = c->srcfile; srcline = c->srcline; error(0,"Cannot find DocContent topic \"%s\".", c->topic_name[ctr]); srcline = -1; /* back to reality */ } else { c->topic_num[ctr] = t; if ( topic[t].flags & TF_IN_DOC ) warn(0,"Topic \"%s\" appears in document more than once.", topic[t].title); else topic[t].flags |= TF_IN_DOC; } } } } /* * Find topic_num and topic_off for all hot-links. Also flag all hot- * links which will (probably) appear in the document. */ for (lctr=0, l=a_link; lctrtype ) { case 0: /* name is the title of the topic */ t = find_topic_title(l->name); if (t == -1) { src_cfname = l->srcfile; srcline = l->srcline; /* pretend we are still in the source... */ error(0,"Cannot find implicit hot-link \"%s\".", l->name); srcline = -1; /* back to reality */ } else { l->topic_num = t; l->topic_off = 0; l->doc_page = (topic[t].flags & TF_IN_DOC) ? 0 : -1; } break; case 1: /* name is the name of a label */ lbl = find_label(l->name); if (lbl == NULL) { src_cfname = l->srcfile; srcline = l->srcline; /* pretend again */ error(0,"Cannot find explicit hot-link \"%s\".", l->name); srcline = -1; } else { if ( topic[lbl->topic_num].flags & TF_DATA ) { src_cfname = l->srcfile; srcline = l->srcline; error(0,"Label \"%s\" is a data-only topic.", l->name); srcline = -1; } else { l->topic_num = lbl->topic_num; l->topic_off = lbl->topic_off; l->doc_page = (topic[lbl->topic_num].flags & TF_IN_DOC) ? 0 : -1; } } break; case 2: /* it's a "special" link; topic_off already has the value */ break; } } } /* * online help pagination stuff */ void add_page_break(TOPIC *t, int margin, char *text, char *start, char *curr, int num_links) { PAGE p; p.offset = (unsigned) (start - text); p.length = (unsigned) (curr - start); p.margin = margin; add_page(t, &p); if (max_links < num_links) max_links = num_links; } void paginate_online(void) /* paginate the text for on-line help */ { /* also calculates max_pages and max_links */ int lnum; char *start; char *curr; char *text; TOPIC *t; int tctr; unsigned len; int skip_blanks; int num_links; int col; int tok; int size, width; int start_margin; msg("Paginating online help."); for (t=topic, tctr=0; tctrflags & TF_DATA ) continue; /* don't paginate data topics */ text = get_topic_text(t); curr = text; len = t->text_len; start = curr; skip_blanks = 0; lnum = 0; num_links = 0; col = 0; start_margin = -1; while (len > 0) { tok = find_token_length(ONLINE, curr, len, &size, &width); switch ( tok ) { case TOK_PARA: { int indent, margin; ++curr; indent = *curr++; margin = *curr++; len -= 3; col = indent; while (1) { tok = find_token_length(ONLINE, curr, len, &size, &width); if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF ) break; if ( tok == TOK_PARA ) { col = 0; /* fake a nl */ ++lnum; break; } if (tok == TOK_XONLINE || tok == TOK_XDOC ) { curr += size; len -= size; continue; } /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */ if (col+width > SCREEN_WIDTH) { /* go to next line... */ if ( ++lnum >= SCREEN_DEPTH ) { /* go to next page... */ add_page_break(t, start_margin, text, start, curr, num_links); start = curr + ( (tok == TOK_SPACE) ? size : 0 ); start_margin = margin; lnum = 0; num_links = 0; } if ( tok == TOK_SPACE ) width = 0; /* skip spaces at start of a line */ col = margin; } col += width; curr += size; len -= size; } skip_blanks = 0; width = size = 0; break; } case TOK_NL: if (skip_blanks && col == 0) { start += size; break; } ++lnum; if ( lnum >= SCREEN_DEPTH || (col == 0 && lnum==SCREEN_DEPTH-1) ) { add_page_break(t, start_margin, text, start, curr, num_links); start = curr + size; start_margin = -1; lnum = 0; num_links = 0; skip_blanks = 1; } col = 0; break; case TOK_FF: col = 0; if (skip_blanks) { start += size; break; } add_page_break(t, start_margin, text, start, curr, num_links); start_margin = -1; start = curr + size; lnum = 0; num_links = 0; break; case TOK_DONE: case TOK_XONLINE: /* skip */ case TOK_XDOC: /* ignore */ case TOK_CENTER: /* ignore */ break; case TOK_LINK: ++num_links; /* fall-through */ default: /* TOK_SPACE, TOK_LINK, TOK_WORD */ skip_blanks = 0; break; } /* switch */ curr += size; len -= size; col += width; } /* while */ if (!skip_blanks) add_page_break(t, start_margin, text, start, curr, num_links); if (max_pages < t->num_page) max_pages = t->num_page; release_topic_text(t, 0); } /* for */ } /* * paginate document stuff */ #define CNUM 0 #define TNUM 1 #define LINK_DEST_WARN 2 typedef struct { int cnum, /* must match above #defines so pd_get_info() will work */ tnum, link_dest_warn; char far *start; CONTENT *c; LABEL *lbl; } PAGINATE_DOC_INFO; LABEL *find_next_label_by_topic(int t) { LABEL *temp, *g, *p; int ctr; g = p = NULL; for (temp=label, ctr=0; ctrtopic_num == t && temp->doc_page == -1 ) { g = temp; break; } else if (temp->topic_num > t) break; for (temp=plabel, ctr=0; ctrtopic_num == t && temp->doc_page == -1 ) { p = temp; break; } else if (temp->topic_num > t) break; if ( p == NULL ) return (g); else if ( g == NULL ) return (p); else return ( (g->topic_off < p->topic_off) ? g : p ); } void set_hot_link_doc_page(void) /* * Find doc_page for all hot-links. */ { LINK *l; LABEL *lbl; int lctr; int t; for (lctr=0, l=a_link; lctrtype ) { case 0: /* name is the title of the topic */ t = find_topic_title(l->name); if (t == -1) { src_cfname = l->srcfile; srcline = l->srcline; /* pretend we are still in the source... */ error(0,"Cannot find implicit hot-link \"%s\".", l->name); srcline = -1; /* back to reality */ } else l->doc_page = topic[t].doc_page; break; case 1: /* name is the name of a label */ lbl = find_label(l->name); if (lbl == NULL) { src_cfname = l->srcfile; srcline = l->srcline; /* pretend again */ error(0,"Cannot find explicit hot-link \"%s\".", l->name); srcline = -1; } else l->doc_page = lbl->doc_page; break; case 2: /* special topics don't appear in the document */ break; } } } void set_content_doc_page(void) /* * insert page #'s in the DocContents */ { CONTENT *c; TOPIC *t; char *base; int tnum; int ctr; char buf[4]; int len; tnum = find_topic_title(DOCCONTENTS_TITLE); assert(tnum>=0); t = &topic[tnum]; base = get_topic_text(t); for (ctr=1, c=contents+1; ctrdoc_page>=1); sprintf(buf, "%d", c->doc_page); len = strlen(buf); assert(len<=3); memcpy(base+c->page_num_pos+(3-len), buf, len); } release_topic_text(t, 1); } int pd_get_info(int cmd, PD_INFO *pd, int *info) { /* this funtion also used by print_document() */ CONTENT *c; switch (cmd) { case PD_GET_CONTENT: if ( ++info[CNUM] >= num_contents ) return (0); c = &contents[info[CNUM]]; info[TNUM] = -1; pd->id = c->id; pd->title = c->name; pd->new_page = (c->flags & CF_NEW_PAGE) ? 1 : 0; return (1); case PD_GET_TOPIC: c = &contents[info[CNUM]]; if ( ++info[TNUM] >= c->num_topic ) return (0); pd->curr = get_topic_text( &topic[c->topic_num[info[TNUM]]] ); pd->len = topic[c->topic_num[info[TNUM]]].text_len; return (1); case PD_GET_LINK_PAGE: if ( a_link[getint(pd->s)].doc_page == -1 ) { if ( info[LINK_DEST_WARN] ) { src_cfname = a_link[getint(pd->s)].srcfile; srcline = a_link[getint(pd->s)].srcline; warn(0,"Hot-link destination is not in the document."); srcline = -1; } return (0); } pd->i = a_link[getint(pd->s)].doc_page; return (1); case PD_RELEASE_TOPIC: c = &contents[info[CNUM]]; release_topic_text(&topic[c->topic_num[info[TNUM]]], 0); return (1); default: return (0); } } int paginate_doc_output(int cmd, PD_INFO *pd, PAGINATE_DOC_INFO *info) { switch (cmd) { case PD_FOOTING: case PD_PRINT: case PD_PRINTN: case PD_PRINT_SEC: return (1); case PD_HEADING: ++num_doc_pages; return (1); case PD_START_SECTION: info->c = &contents[info->cnum]; return (1); case PD_START_TOPIC: info->start = pd->curr; info->lbl = find_next_label_by_topic(info->c->topic_num[info->tnum]); return (1); case PD_SET_SECTION_PAGE: info->c->doc_page = pd->pnum; return (1); case PD_SET_TOPIC_PAGE: topic[info->c->topic_num[info->tnum]].doc_page = pd->pnum; return (1); case PD_PERIODIC: while ( info->lbl != NULL && (unsigned)(pd->curr - info->start) >= info->lbl->topic_off) { info->lbl->doc_page = pd->pnum; info->lbl = find_next_label_by_topic(info->c->topic_num[info->tnum]); } return (1); default: return (0); } } void paginate_document(void) { PAGINATE_DOC_INFO info; if (num_contents == 0) return ; msg("Paginating document."); info.cnum = info.tnum = -1; info.link_dest_warn = 1; process_document((PD_FUNC)pd_get_info, (PD_FUNC)paginate_doc_output, &info); set_hot_link_doc_page(); set_content_doc_page(); } /* * label sorting stuff */ int fcmp_LABEL(VOIDCONSTPTR a, VOIDCONSTPTR b) { char *an = ((LABEL *)a)->name, *bn = ((LABEL *)b)->name; int diff; /* compare the names, making sure that the index goes first */ if ( (diff=strcmp(an,bn)) == 0 ) return (0); if ( strcmp(an, INDEX_LABEL) == 0 ) return (-1); if ( strcmp(bn, INDEX_LABEL) == 0 ) return (1); return ( diff ); } void sort_labels(void) { qsort(label, num_label, sizeof(LABEL), fcmp_LABEL); qsort(plabel, num_plabel, sizeof(LABEL), fcmp_LABEL); } /* * file write stuff. */ int compare_files(FILE *f1, FILE *f2) /* returns TRUE if different */ { if ( filelength(fileno(f1)) != filelength(fileno(f2)) ) return (1); /* different if sizes are not the same */ while ( !feof(f1) && !feof(f2) ) if ( getc(f1) != getc(f2) ) return (1); return ( ( feof(f1) && feof(f2) ) ? 0 : 1); } void _write_hdr(char *fname, FILE *file) { int ctr; char nfile[MAXFILE], next[MAXEXT]; FNSPLIT(fname, NULL, NULL, nfile, next); fprintf(file, "\n/*\n * %s%s\n", nfile, next); FNSPLIT(src_fname, NULL, NULL, nfile, next); fprintf(file, " *\n * Contains #defines for help.\n *\n"); fprintf(file, " * Generated by HC from: %s%s\n *\n */\n\n\n", nfile, next); fprintf(file, "/* current help file version */\n"); fprintf(file, "\n"); fprintf(file, "#define %-32s %3d\n", "HELP_VERSION", version); fprintf(file, "\n\n"); fprintf(file, "/* labels */\n\n"); for (ctr=0; ctrid) + /* id text */ 1 + /* name length */ strlen(cp->name) + /* name text */ 1 + /* number of topics */ cp->num_topic*sizeof(int); /* topic numbers */ for (t=0, tp=topic; toffset = offset; offset += (long)sizeof(int) + /* topic flags */ sizeof(int) + /* number of pages */ tp->num_page*3*sizeof(int) + /* page offset, length & starting margin */ 1 + /* length of title */ tp->title_len + /* title */ sizeof(int) + /* length of text */ tp->text_len; /* text */ } } void insert_real_link_info(char *curr, unsigned len) /* * Replaces link indexes in the help text with topic_num, topic_off and * doc_page info. */ { int size; int tok; LINK *l; while (len > 0) { tok = find_token_length(0, curr, len, &size, NULL); if ( tok == TOK_LINK ) { l = &a_link[ getint(curr+1) ]; setint(curr+1,l->topic_num); setint(curr+1+sizeof(int),l->topic_off); setint(curr+1+2*sizeof(int),l->doc_page); } len -= size; curr += size; } } void _write_help(FILE *file) { int t, p, l, c; char *text; TOPIC *tp; CONTENT *cp; struct help_sig_info hs; /* write the signature and version */ hs.sig = HELP_SIG; /* Edit line 17 of helpcom.h if this is a syntax error */ hs.version = version; fwrite(&hs, sizeof(long)+sizeof(int), 1, file); /* write max_pages & max_links */ putw(max_pages, file); putw(max_links, file); /* write num_topic, num_label and num_contents */ putw(num_topic, file); putw(num_label, file); putw(num_contents, file); /* write num_doc_page */ putw(num_doc_pages, file); /* write the offsets to each topic */ for (t=0; tflags, file); t = strlen(cp->id); putc((BYTE)t, file); fwrite(cp->id, 1, t, file); t = strlen(cp->name); putc((BYTE)t, file); fwrite(cp->name, 1, t, file); putc((BYTE)cp->num_topic, file); fwrite(cp->topic_num, sizeof(int), cp->num_topic, file); } /* write topics */ for (t=0, tp=topic; tflags, file); /* write offset, length and starting margin for each page */ putw(tp->num_page, file); for (p=0; pnum_page; p++) { putw(tp->page[p].offset, file); putw(tp->page[p].length, file); putw(tp->page[p].margin, file); } /* write the help title */ putc((BYTE)tp->title_len, file); fwrite(tp->title, 1, tp->title_len, file); /* insert hot-link info & write the help text */ text = get_topic_text(tp); if ( !(tp->flags & TF_DATA) ) /* don't process data topics... */ insert_real_link_info(text, tp->text_len); putw(tp->text_len, file); fwrite(text, 1, tp->text_len, file); release_topic_text(tp, 0); /* don't save the text even though */ /* insert_real_link_info() modified it */ /* because we don't access the info after */ /* this. */ } } void write_help(char *fname) { FILE *hlp; hlp = fopen(fname, "wb"); if (hlp == NULL) fatal(0,"Cannot create .HLP file: \"%s\".", fname); msg("Writing: %s", fname); _write_help(hlp); fclose(hlp); } /* * print document stuff. */ typedef struct { /* * Note: Don't move these first three or pd_get_info will work not * correctly. */ int cnum; int tnum; int link_dest_warn; /* = 0 */ FILE *file; int margin; int start_of_line; int spaces; } PRINT_DOC_INFO; void printerc(PRINT_DOC_INFO *info, int c, int n) { while ( n-- > 0 ) { if (c==' ') ++info->spaces; else if (c=='\n' || c=='\f') { info->start_of_line = 1; info->spaces = 0; /* strip spaces before a new-line */ putc(c, info->file); } else { if (info->start_of_line) { info->spaces += info->margin; info->start_of_line = 0; } while (info->spaces > 0) { fputc(' ', info->file); --info->spaces; } fputc(c, info->file); } } } void printers(PRINT_DOC_INFO *info, char far *s, int n) { if (n > 0) { while ( n-- > 0 ) printerc(info, *s++, 1); } else { while ( *s != '\0' ) printerc(info, *s++, 1); } } int print_doc_output(int cmd, PD_INFO *pd, PRINT_DOC_INFO *info) { switch (cmd) { case PD_HEADING: { char buff[20]; info->margin = 0; printers(info, "\n Fractint Version xx.xx Page ", 0); sprintf(buff, "%d\n\n", pd->pnum); printers(info, buff, 0); info->margin = PAGE_INDENT; return (1); } case PD_FOOTING: info->margin = 0; printerc(info, '\f', 1); info->margin = PAGE_INDENT; return (1); case PD_PRINT: printers(info, pd->s, pd->i); return (1); case PD_PRINTN: printerc(info, *pd->s, pd->i); return (1); case PD_PRINT_SEC: info->margin = TITLE_INDENT; if (pd->id[0] != '\0') { printers(info, pd->id, 0); printerc(info, ' ', 1); } printers(info, pd->title, 0); printerc(info, '\n', 1); info->margin = PAGE_INDENT; return (1); case PD_START_SECTION: case PD_START_TOPIC: case PD_SET_SECTION_PAGE: case PD_SET_TOPIC_PAGE: case PD_PERIODIC: return (1); default: return (0); } } void print_document(char *fname) { PRINT_DOC_INFO info; if (num_contents == 0) fatal(0,".SRC has no DocContents."); msg("Printing to: %s", fname); info.cnum = info.tnum = -1; info.link_dest_warn = 0; if ( (info.file = fopen(fname, "wt")) == NULL ) fatal(0,"Couldn't create \"%s\"", fname); info.margin = PAGE_INDENT; info.start_of_line = 1; info.spaces = 0; process_document((PD_FUNC)pd_get_info, (PD_FUNC)print_doc_output, &info); fclose(info.file); } /* * compiler status and memory usage report stuff. */ void report_memory(void) { long string = 0, /* bytes in strings */ text = 0, /* bytes in topic text (stored on disk) */ data = 0, /* bytes in active data structure */ dead = 0; /* bytes in unused data structure */ int ctr, ctr2; for (ctr=0; ctr 0) dead += (LINK_ALLOC_SIZE-(num_link%LINK_ALLOC_SIZE)) * sizeof(LINK); for (ctr=0; ctr 0) dead += (LABEL_ALLOC_SIZE-(num_label%LABEL_ALLOC_SIZE)) * sizeof(LABEL); for (ctr=0; ctr 0) dead += (LABEL_ALLOC_SIZE-(num_plabel%LABEL_ALLOC_SIZE)) * sizeof(LABEL); for (ctr=0; ctr1; argc--, arg++) { switch ( (*arg)[0] ) { case '/': case '-': switch ( (*arg)[1] ) { case 'c': if (mode == 0) mode = MODE_COMPILE; else fatal(0,"Cannot have /c with /a, /d or /p"); break; case 'a': if (mode == 0) mode = MODE_APPEND; else fatal(0,"Cannot have /a with /c, /d or /p"); break; case 'd': if (mode == 0) mode = MODE_DELETE; else fatal(0,"Cannot have /d with /c, /a or /p"); break; case 'p': if (mode == 0) mode = MODE_PRINT; else fatal(0,"Cannot have /p with /c, /a or /d"); break; case 'm': if (mode == MODE_COMPILE) show_mem = 1; else fatal(0,"/m switch allowed only when compiling (/c)"); break; case 's': if (mode == MODE_COMPILE) show_stats = 1; else fatal(0,"/s switch allowed only when compiling (/c)"); break; case 'r': if (mode == MODE_COMPILE || mode == MODE_PRINT) strcpy(swappath, (*arg)+2); else fatal(0,"/r switch allowed when compiling (/c) or printing (/p)"); break; case 'q': quiet_mode = 1; break; default: fatal(0,"Bad command-line switch /%c", (*arg)[1]); break; } break; default: /* assume it is a fname */ if (fname1[0] == '\0') strcpy(fname1, *arg); else if (fname2[0] == '\0') strcpy(fname2, *arg); else fatal(0,"Unexpected command-line argument \"%s\"", *arg); break; } /* switch */ } /* for */ strupr(fname1); strupr(fname2); strupr(swappath); switch (mode) { case 0: printf( "To compile a .SRC file:\n"); printf( " HC /c [/s] [/m] [/r[path]] [src_file]\n"); printf( " /s = report statistics.\n"); printf( " /m = report memory usage.\n"); printf( " /r[path] = set swap file path.\n"); printf( " src_file = .SRC file. Default is \"%s\"\n", DEFAULT_SRC_FNAME); printf( "To print a .SRC file:\n"); printf( " HC /p [/r[path]] [src_file] [out_file]\n"); printf( " /r[path] = set swap file path.\n"); printf( " src_file = .SRC file. Default is \"%s\"\n", DEFAULT_SRC_FNAME); printf( " out_file = Filename to print to. Default is \"%s\"\n", DEFAULT_DOC_FNAME); printf( "To append a .HLP file to an .EXE file:\n"); printf( " HC /a [hlp_file] [exe_file]\n"); printf( " hlp_file = .HLP file. Default is \"%s\"\n", DEFAULT_HLP_FNAME); printf( " exe_file = .EXE file. Default is \"%s\"\n", DEFAULT_EXE_FNAME); printf( "To delete help info from an .EXE file:\n"); printf( " HC /d [exe_file]\n"); printf( " exe_file = .EXE file. Default is \"%s\"\n", DEFAULT_EXE_FNAME); printf( "\n"); printf( "Use \"/q\" for quiet mode. (No status messages.)\n"); break; case MODE_COMPILE: if (fname2[0] != '\0') fatal(0,"Unexpected command-line argument \"%s\"", fname2); strcpy(src_fname, (fname1[0]=='\0') ? DEFAULT_SRC_FNAME : fname1); strcat(swappath, SWAP_FNAME); if ( (swapfile=fopen(swappath, "w+b")) == NULL ) fatal(0,"Cannot create swap file \"%s\"", swappath); swappos = 0; read_src(src_fname); if (hdr_fname[0] == '\0') error(0,"No .H file defined. (Use \"~HdrFile=\")"); if (hlp_fname[0] == '\0') error(0,"No .HLP file defined. (Use \"~HlpFile=\")"); if (version == -1) warn(0,"No help version has been defined. (Use \"~Version=\")"); /* order of these is very important... */ make_hot_links(); /* do even if errors since it may report */ /* more... */ if ( !errors ) paginate_online(); if ( !errors ) paginate_document(); if ( !errors ) calc_offsets(); if ( !errors ) sort_labels(); if ( !errors ) write_hdr(hdr_fname); if ( !errors ) write_help(hlp_fname); if ( show_stats ) report_stats(); if ( show_mem ) report_memory(); if ( errors || warnings ) report_errors(); fclose(swapfile); remove(swappath); break; case MODE_PRINT: strcpy(src_fname, (fname1[0]=='\0') ? DEFAULT_SRC_FNAME : fname1); strcat(swappath, SWAP_FNAME); if ( (swapfile=fopen(swappath, "w+b")) == NULL ) fatal(0,"Cannot create swap file \"%s\"", swappath); swappos = 0; read_src(src_fname); make_hot_links(); if ( !errors ) paginate_document(); if ( !errors ) print_document( (fname2[0]=='\0') ? DEFAULT_DOC_FNAME : fname2 ); if ( errors || warnings ) report_errors(); fclose(swapfile); remove(swappath); break; case MODE_APPEND: add_hlp_to_exe( (fname1[0]=='\0') ? DEFAULT_HLP_FNAME : fname1, (fname2[0]=='\0') ? DEFAULT_EXE_FNAME : fname2); break; case MODE_DELETE: if (fname2[0] != '\0') fatal(0,"Unexpected argument \"%s\"", fname2); delete_hlp_from_exe((fname1[0]=='\0') ? DEFAULT_EXE_FNAME : fname1); break; } free(buffer); return ( errors ); /* return the number of errors */ } xfractint-20.4.10.orig/dos_help/help3.src0000644000000000000000000022653210405667107015046 0ustar ~Topic=Doodads\, Bells\, and Whistles ~Format- { Drawing Method } { Autokey Mode } { Distance Estimator Method } { Inversion } { Decomposition } { Logarithmic Palettes and Color Ranges } { Biomorphs } { Continuous Potential } { Starfields } { Bailout Test } { Random Dot Stereograms (RDS) } ~Format+ ; ; ; ~Topic=Drawing Method The "passes option" ( options screen or "passes=" parameter) selects one of the single-pass, dual-pass, triple-pass, solid-guessing (default), solid-guessing after pass n, boundary tracing, tesseral, synchronous orbits, or orbits modes. This option applies to most fractal types. Single-pass mode ("1") draws the screen pixel by pixel. Dual-pass ("2") generates a half-resolution screen first as a preview using 2x2-pixel boxes, and then generates the rest of the dots with a second pass. Dual-pass uses no more time than single-pass. Triple-pass ("3") generates the coarse first pass of the solidguessing mode (see "g" below), then switches to either "1" (with low resolution video modes) or "2" (with higher resolution video modes). The advantage of '3' vs '2' is that when using high resolution modes, the first pass has a much lower resolution (about 160x120) and is therefore much quicker than the first pass of the passes=2 mode. However, with the '2' mode, the first pass does not represent wasted time. The '3' mode wastes the effort of generating the coarse first screen. The single, dual, and triple pass modes all result in identical images. These modes are for those who desire the highest possible accuracy. Most people will want to use the guessing mode, described next. Solid-guessing ("g") is the default. It performs from two to four visible passes - more in higher resolution video modes. Its first visible pass is actually two passes - one pixel per 4x4, 8x8, or 16x16 pixel box is generated, and the guessing logic is applied to fill in the blocks at the next level (2x2, 4x4, or 8x8). Subsequent passes fill in the display at the next finer resolution, skipping blocks which are surrounded by the same color. Solid-guessing can guess wrong, but it sure guesses quickly! Solid-guessing stop after pass n ("g1" through "g6") are a variation on the guessing mode in which the algorithm stops after the nth pass. This facility is for exploring in low resolution when you'd rather see a low resolution image with large blocky pixels filling the whole screen than a small low resolution image such as you get with the (View Windows) command. Note that on the screen you can't directly type g1 or g2. Press g repeatedly until you get the option you want, or else use the left or right cursor keys. Boundary Tracing ("b"), which only works accurately with fractal types (such as the Mandelbrot set, but not the Newton type) that do not contain "islands" of colors, finds a color boundary, traces it around the screen, and then "blits" in the color over the enclosed area. Tesseral ("t") is a sort of "super-solid-guessing" option that successively divides the image into subsections and colors in rectangles that have a boundary of a solid color. It's actually slower than the solid-guessing algorithm, but it looks neat, so we left it in. This mode is also subject to errors when islands of color appear inside the rectangles.\ Diffusion Scan ("d") is a drawing type based on dithering techniques. It scans the image spreading the points evenly and to each point it paints a square of the appropriate size so that the image will be incrementally enhanced. This method calculates ALL the points in the image being a good substitute for Single/Dual/Triple pass and presents a quick visualization even in the slowest fractals. With "fillcolor=0" (below) the squares are not painted and the points are spread over the image until all have being calculated (sort of a "Fade In"). The "fillcolor=" option in the screen or on the command line sets a fixed color to be used by the Boundary Tracing and Tesseral calculations for filling in defined regions. The effect of this is to show off the boundaries of the areas delimited by these two methods. Orbits ("o") draws an image by plotting the orbits of the escape time fractals. This technique uses the same coordinates to draw an image as the other passes options, sets "passes=1" and no symmetry, and then plots the orbits for each pixel. Zooming into a "passes=o" image is in fact zooming into the "passes=1" image, and the resulting image may not be what is expected. To find interesting places to investigate, press after an image has completed and watch the behaviour of the orbits as the cursor is moved around the screen. See {Orbits Window}. The "outside=summ" option causes Orbits to increment a pixel's color number every time an orbit touchs it; the resulting display is a 2-d histogram. If "outside=" is some other value, then the "inside=" color determines the color of the plotted orbits. If "inside=0", then the color number is incremented at the start of each pixel of the passes=1 image. The "orbitdelay=" option controls how many orbits are computed before the orbits are displayed on the screen. This allows the orbits to settle down. The "orbitinterval=" option causes Orbits to plot every nth orbit point. A non-zero value of the "periodicity=" option causes Orbits to not plot orbits that have reached the bailout conditions or where an orbit goes off the visible area of the image. A zero value of periodicity will plot all orbits except as modified by orbitdelay and orbitinterval. Synchronous orbits ("s") is an experimental mode using the "fractal witchcraft" algorithm based on the Almondbread implementation by Michael Ganss. This algorithm optimizes deep zooms by calculating parallel orbits starting at different points, and subdividing when the orbits break formation. Michael's implementation had to be extensively modified to work with Fractint's DOS medium memory model environment. Synchronous orbits (also known as SOI) has some limitations. SOI is loosely coupled with fractint and most options don't work with it. Only types mandel and julia are implemented. SOI is only useful for very deep zooms, but only up to the limit of double precision. Within this narrow magnification range, SOI can result in tremndous speedups. If you invoke fractint with "debug=3444" on the command line, a long double (rather than double) version will be used, which allows zooming about 1000 times deeper. SOI really needs to be ported to fractint's arbitary precision. This will likely happen only after Fractint is moved to a better programming environment. ; ; ~Topic=Autokey Mode The autokey feature allows you to set up beautiful self-running demo "loops". You can set up hypnotic sequences to attract people to a booth, to generate sequences for special effects, to teach how Fractal exploring is done, etc. A sample autokey file (DEMO.KEY) and a batch to run it (DEMO.BAT) are included with Fractint. Type "demo" at the DOS prompt to run it. Autokey record mode is enabled with the command line parameter "AUTOKEY=RECORD". Keystrokes are saved in an intelligible text format in a file called AUTO.KEY. You can change the file name with the "AUTOKEYNAME=" parameter. Playback is enabled with the parameter "AUTOKEY=PLAY". Playback can be terminated by pressing the key. After using record mode to capture an autokey file, you'll probably want to touch it up using your editor before playing it back. Separate lines are not necessary but you'll probably find it easier to understand an autokey file if you put each command on a separate line. Autokey files can contain the following: Quoted strings. Fractint reads whatever is between the quotes just as if you had typed it. For example, "t" "ifs" issues the "t" (type) command and then enters the letters i", "f", and "s" to select the ifs type. Symbols for function keys used to select a video mode. Examples:\ F3 -- Function key 3\ SF3 -- and together\ Special keys: ENTER ESC F1 PAGEUP PAGEDOWN HOME END LEFT RIGHT UP DOWN\ INSERT DELETE TAB CTRL_RIGHT CTRL_LEFT CTRL_DOWN CTRL_UP CTRL_HOME\ CTRL_END\ WAIT -- wait nnn.n seconds before continuing CALCWAIT -- pause until the current fractal calculation or file save or restore is finished. This command makes demo files more robust since calculation times depend on the speed of the machine running the demo - a "WAIT 10" command may allow enough time to complete a fractal on one machine, but not on another. The record mode does not generate this command - it should be added by hand to the autokey file whenever there is a process that should be allowed to run to completion. GOTO target -- The autokey file continues to be read from the label "target". The label can be any word that does not duplicate a key word. It must be present somewhere in the autokey file with a colon after it. Example:\ MESSAGE 2 This is executed once\ start:\ MESSAGE 2 This is executed repeatedly\ GOTO start\ GOTO is mainly useful for writing continuous loop demonstrations. It can also be useful when debugging an autokey file, to skip sections of it. ; -- A semi-colon indicates that the rest of the line containing it is a comment. MESSAGE nn -- Places a message on the top of the screen for nn seconds Making Fractint demos can be tricky. Here are some suggestions which may help: Start Fractint with "fractint autokeyname=mydemo.key autokey=record". Use a unique name each time you run so that you don't overwrite prior files. When in record mode, avoid using the cursor keys to select filenames, fractal types, formula names, etc. Instead, try to type in names. This will ensure that the exact item you want gets chosen during playback even if the list is different then. Beware of video mode assumptions. It is safest to build a separate demo for different resolution monitors. When in the record mode, try to type names quickly, then pause. If you pause partway through a name Fractint will break up the string in the .KEY file. E.g. if you paused in the middle of typing fract001, you might get:\ "fract"\ WAIT 2.2\ "001"\ No harm done, but messy to clean up. Fractint ignores pauses less than about 1/2 second. DO pause when you want the viewer to see what is happening during playback. When done recording, clean up your mydemo.key file. Insert a CALCWAIT after each keystroke which triggers something that takes a variable amount of time (calculating a fractal, restoring a file, saving a file). Add comments with ";" to the file so you know what is going on in future. It is a good idea to use INSERT before a GOTO which restarts the demo. The key resets Fractint as if you exited the program and restarted it. Warning: an autokey file built for this version of Fractint will probably require some retouching before it works with future releases of Fractint. We have no intention of making sure that the same sequence of keystrokes will have exactly the same effect from one version of Fractint to the next. That would require pretty much freezing Fractint development, and we just love to keep enhancing it! ; ; ; ~Topic=Distance Estimator Method This is Phil Wilson's implementation of an alternate method for the M and J sets, based on work by mathematician John Milnor and described in "The Science of Fractal Images", p. 198. While it can take full advantage of your color palette, one of the best uses is in preparing monochrome images for a printer. Using the 1600x1200x2 disk-video mode and an HP LaserJet, we have produced pictures of quality equivalent to the black and white illustrations of the M-set in "The Beauty of Fractals." The distance estimator method widens very thin "strands" which are part of the "inside" of the set. Instead of hiding invisibly between pixels, these strands are made one pixel wide. Though this option is available with any escape time fractal type, the formula used is specific to the mandel and julia types - for most other types it doesn't do a great job. To turn on the distance estimator method with any escape time fractal type, set the "Distance Estimator" value on the options screen (or use the "distest=" command line parameter). Setting the distance estimator option to a negative value -nnn enables edge-tracing mode. The edge of the set is display as color number nnn. This option works best when the "inside" and "outside" color values are also set to some other value(s). In a 2 color (monochrome) mode, setting to any positive value results in the inside of the set being expanded to include edge points, and the outside points being displayed in the other color. In color modes, setting to value 1 causes the edge points to be displayed using the inside color and the outside points to be displayed in their usual colors. Setting to a value greater than one causes the outside points to be displayed as contours, colored according to their distance from the inside of the set. Use a higher value for narrower color bands, a lower value for wider ones. 1000 is a good value to start with. The second distance estimator parameter ("width factor") sets the distance from the inside of the set which is to be considered as part of the inside. This value is expressed as a percentage of a pixel width, the default is 71. Negative values are now allowed and give a fraction of a percent of the pixel width. For example: -71 gives 1/71 % of the pixel width. You should use 1 or 2 pass mode with the distance estimator method, to avoid missing some of the thin strands made visible by it. For the highest quality, "maxiter" should also be set to a high value, say 1000 or so. You'll probably also want "inside" set to zero, to get a black interior. Enabling the distance estimator method automatically toggles to floating point mode. When you reset distest back to zero, remember to also turn off floating point mode if you want it off. Unfortunately, images using the distance estimator method can take many hours to calculate even on a fast machine with a coprocessor, especially if a high "maxiter" value is used. One way of dealing with this is to leave it turned off while you find and frame an image. Then hit to save the current image information in a parameter file (see {Parameter Save/Restore Commands}). Use an editor to change the parameter file entry, adding "distest=1", "video=something" to select a high- resolution monochrome disk-video mode, "maxiter=1000", and "inside=0". Run the parameter file entry with the <@> command when you won't be needing your machine for a while (over the weekend?) To reproduce images made prior to version 16.0, it is necessary to set several parameters from the command line or using . First, set "release=1510", then set "olddemmcolors=y". To obtain the fine strands it is necessary to set the "width factor" to a large negative value, such as -32000. ; ; ; ~Topic=Inversion Many years ago there was a brief craze for "anamorphic art": images painted and viewed with the use of a cylindrical mirror, so that they looked weirdly distorted on the canvas but correct in the distorted reflection. (This byway of art history may be a useful defense when your friends and family give you odd looks for staring at fractal images color- cycling on a CRT.) The Inversion option performs a related transformation on most of the fractal types. You define the center point and radius of a circle; Fractint maps each point inside the circle to a corresponding point outside, and vice-versa. This is known to mathematicians as inverting (or if you want to get precise, "everting") the plane, and is something they can contemplate without getting a headache. John Milnor (also mentioned in connection with the {Distance Estimator Method}), made his name in the 1950s with a method for everting a seven-dimensional sphere, so we have a lot of catching up to do. For example, if a point inside the circle is 1/3 of the way from the center to the radius, it is mapped to a point along the same radial line, but at a distance of (3 * radius) from the origin. An outside point at 4 times the radius is mapped inside at 1/4 the radius. The inversion parameters on the options screen allow entry of the radius and center coordinates of the inversion circle. A default choice of -1 sets the radius at 1/6 the smaller dimension of the image currently on the screen. The default values for Xcenter and Ycenter use the coordinates currently mapped to the center of the screen. Try this one out with a {=HT_NEWT Newton} plot, so its radial "spokes" will give you something to hang on to. Plot a Newton-method image, then set the inversion radius to 1, with default center coordinates. The center "explodes" to the periphery. Inverting through a circle not centered on the origin produces bizarre effects that we're not even going to try to describe. Aren't computers wonderful? ; ; ; ~Topic=Decomposition You'll remember that most fractal types are calculated by iterating a simple function of a complex number, producing another complex number, until either the number exceeds some pre-defined "bailout" value, or the iteration limit is reached. The pixel corresponding to the starting point is then colored based on the result of that calculation. The decomposition option ("decomp=", on the screen) toggles to another coloring protocol. Here the points are colored according to which quadrant of the complex plane (negative real/positive imaginary, positive real/positive imaginary, etc.) the final value is in. If you use 4 as the parameter, points ending up in each quadrant are given their own color; if 2 (binary decomposition), points in alternating quadrants are given 2 alternating colors. The result is a kind of warped checkerboard coloring, even in areas that would ordinarily be part of a single contour. Remember, for the M-set all points whose final values exceed 2 (by any amount) after, say, 80 iterations are normally the same color; under decomposition, Fractint runs [bailout-value] iterations and then colors according to where the actual final value falls on the complex plane. When using decomposition, a higher bailout value will give a more accurate plot, at some expense in speed. You might want to set the bailout value (in the parameters prompt following selection of a new fractal type; present for most but not all types) to a higher value than the default. A value of about 50 is a good compromise for M/J sets. ; ; ; ~Topic=Logarithmic Palettes and Color Ranges By default, Fractint maps iterations to colors 1:1. I.e. if the calculation for a fractal "escapes" (exceeds the bailout value) after N iterations, the pixel is colored as color number N. If N is greater than the number of colors available, it wraps around. So, if you are using a 16-color video mode, and you are using the default maximum iteration count of 150, your image will run through the 16-color palette 150/16 = 9.375 times. When you use Logarithmic palettes, the entire range of iteration values is compressed to map to one span of the color range. This results in spectacularly different images if you are using a high iteration limit and are zooming in on an area near a "lakelet". When using a compressed palette in a 256 color mode, we suggest changing your colors from the usual defaults. The last few colors in the default IBM VGA color map are black. This results in points nearest the "lake" smearing into a single dark band, with little contrast from the blue (by default) lake. Fractint has a number of types of compressed palette, selected by the "Log Palette" line on the screen, or by the "logmap=" command line parameter: logmap=1: for standard logarithmic palette. logmap=-1: "old" logarithmic palette. This variant was the only one used before Fractint 14.0. It differs from logmap=1 in that some colors are not used - logmap=1 "spreads" low color numbers which are unused by logmap=-1's pure logarithmic mapping so that all colors are assigned. logmap=N (>1): Same as logmap=1, but starting from iteration count N. Pixels with iteration counts less than N are mapped to color 1. This is useful when zooming in an area near the lake where no points in the image have low iteration counts - it makes use of the low colors which would otherwise be unused. logmap=-N (<-1): Similar to logmap=N, but uses a square root distribution of the colors instead of a logarithmic one. logmap=2 or -2: Auto calculates the logmap value for maximum effect. Another way to change the 1:1 mapping of iteration counts to colors is to use the "RANGES=" parameter. It has the format:\ RANGES=aa/bb/cc/dd/... Iteration counts up to and including the first value are mapped to color number 0, up to and including the second value to color number 1, and so on. The values must be in ascending order. A negative value can be specified for "striping". The negative value specifies a stripe width, the value following it specifies the limit of the striped range. Two alternating colors are used within the striped range. Example: RANGES=0/10/30/-5/65/79/32000\ This example maps iteration counts to colors as follows: ~Format- color iterations ------------------- 0 unused (formula always iterates at least once) 1 1 to 10 2 11 to 30 3 31 to 35, 41 to 45, 51 to 55, and 61 to 65 4 36 to 40, 46 to 50, and 56 to 60 5 66 to 79 6 80 and greater ~Format+ Note that the maximum value in a RANGES parameter is 32767 and the maximum value for the number of iterations is also 32767 when using RANGES. ; ; ; ~Topic=Biomorphs, Label=@Biomorphs Related to {Decomposition} are the "biomorphs" invented by Clifford Pickover, and discussed by A. K. Dewdney in the July 1989 "Scientific American", page 110. These are so-named because this coloring scheme makes many fractals look like one-celled animals. The idea is simple. The escape-time algorithm terminates an iterating formula when the size of the orbit value exceeds a predetermined bailout value. Normally the pixel corresponding to that orbit is colored according to the iteration when bailout happened. To create biomorphs, this is modified so that if EITHER the real OR the imaginary component is LESS than the bailout, then the pixel is set to the "biomorph" color. The effect is a bit better with higher bailout values: the bailout is automatically set to 100 when this option is in effect. You can try other values with the "bailout=" option. The biomorph option is turned on via the "biomorph=nnn" command-line option (where "nnn" is the color to use on the affected pixels). When toggling to Julia sets, the default corners are three times bigger than normal to allow seeing the biomorph appendages. Does not work with all types - in particular it fails with any of the mandelsine family. However, if you are stuck with monochrome graphics, try it - works great in two- color modes. Try it with the marksmandel and marksjulia types. ; ; ; ~Topic=Continuous Potential Note: This option can only be used with 256 color modes. Fractint's images are usually calculated by the "level set" method, producing bands of color corresponding to regions where the calculation gives the same value. When "3D" transformed (see {\"3D\" Images}), most images other than plasma clouds are like terraced landscapes: most of the surface is either horizontal or vertical. To get the best results with the "illuminated" 3D fill options 5 and 6, there is an alternative approach that yields continuous changes in colors. Continuous potential is approximated by calculating potential = log(modulus)/2^iterations where "modulus" is the orbit value (magnitude of the complex number) when the modulus bailout was exceeded, at the "iterations" iteration. Clear as mud, right? Fortunately, you don't have to understand all the details. However, there ARE a few points to understand. First, Fractint's criterion for halting a fractal calculation, the "modulus bailout value", is generally set to 4. Continuous potential is inaccurate at such a low value. The bad news is that the integer math which makes the "mandel" and "julia" types so fast imposes a hard-wired maximum value of 127. You can still make interesting images from those types, though, so don't avoid them. You will see "ridges" in the "hillsides." Some folks like the effect. The good news is that the other fractal types, particularly the (generally slower) floating point algorithms, have no such limitation. The even better news is that there is a floating-point algorithm for the "mandel" and "julia" types. To force the use of a floating-point algorithm, use Fractint with the "FLOAT=YES" command-line toggle. Only a few fractal types like plasma clouds, the Barnsley IFS type, and "test" are unaffected by this toggle. The parameters for continuous potential are:\ potential=maxcolor[/slope[/modulus[/16bit]]]\ These parameters are present on the options screen. "Maxcolor" is the color corresponding to zero potential, which plots as the TOP of the mountain. Generally this should be set to one less than the number of colors, i.e. usually 255. Remember that the last few colors of the default IBM VGA palette are BLACK, so you won't see what you are really getting unless you change to a different palette. "Slope" affects how rapidly the colors change -- the slope of the "mountains" created in 3D. If this is too low, the palette will not cover all the potential values and large areas will be black. If it is too high, the range of colors in the picture will be much less than those available. There is no easy way to predict in advance what this value should be. "Modulus" is the bailout value used to determine when an orbit has "escaped". Larger values give more accurate and smoother potential. A value of 500 gives excellent results. As noted, this value must be <128 for the integer fractal types (if you select a higher number, they will use 127). "16bit": If you transform a continuous potential image to 3D, the illumination modes 5 and 6 will work fine, but the colors will look a bit granular. This is because even with 256 colors, the continuous potential is being truncated to integers. The "16bit" option can be used to add an extra 8 bits of goodness to each stored pixel, for a much smoother result when transforming to 3D. Fractint's visible behavior is unchanged when 16bit is enabled, except that solid guessing and boundary tracing are not used. But when you save an image generated with 16bit continuous potential:\ o The saved file is a fair bit larger.\ o Fractint names the file with a .POT extension instead of .GIF, if you didn't specify an extension in "savename". o The image can be used as input to a subsequent <3> command to get the promised smoother effect. o If you happen to view the saved image with a GIF viewer other than Fractint, you'll find that it is twice as wide as it is supposed to be. (Guess where the extra goodness was stored!) Though these files are structurally legal GIF files the double-width business made us think they should perhaps not be called GIF - hence the .POT filename extension. A 16bit (.POT) file can be converted to an ordinary 8 bit GIF by estoring it, changing "16bit" to "no" on the options screen, and aving. You might find with 16bit continuous potential that there's a long delay at the start of an image, and disk activity during calculation. Fractint uses its disk-video cache area to store the extra 8 bits per pixel - if there isn't sufficient memory available, the cache will page to disk. The following commands can be used to recreate the image that Mark Peterson first prototyped for us, and named "MtMand": TYPE=mandel\ CORNERS=-0.19920/-0.11/1.0/1.06707\ INSIDE=255\ MAXITER=255\ POTENTIAL=255/2000/1000/16bit\ PASSES=1\ FLOAT=yes\ Note that prior to version 15.0, Fractint:\ o Produced "16 bit TGA potfiles" This format is no longer generated, but you can still (for a release or two) use and <3> with those files. o Assumed "inside=maxit" for continuous potential. It now uses the current "inside=" value - to recreate prior results you must be explicit about this parameter. ; ; ; ~Topic=Starfields, Label=HELPSTARFLD Once you have generated your favorite fractal image, you can convert it into a fractal starfield with the 'a' transformation (for 'astronomy'? - once again, all of the good letters were gone already). Stars are generated on a pixel-by-pixel basis - the odds that a particular pixel will coalesce into a star are based (partially) on the color index of that pixel. (The following was supplied by Mark Peterson, the starfield author). If the screen were entirely black and the 'Star Density per Pixel' were set to 30 then a starfield transformation would create an evenly distributed starfield with an average of one star for every 30 pixels. If you're on a 320x200 screen then you have 64000 pixels and would end up with about 2100 stars. By introducing the variable of 'Clumpiness' we can create more stars in areas that have higher color values. At 100% Clumpiness a color value of 255 will change the average of finding a star at that location to 50:50. A lower clumpiness values will lower the amount of probability weighting. To create a spiral galaxy draw your favorite spiral fractal (IFS, Julia, or Mandelbrot) and perform a starfield transformation. For general starfields I'd recommend transforming a plasma fractal. Real starfields have many more dim stars than bright ones because very few stars are close enough to appear bright. To achieve this effect the program will create a bell curve based on the value of ratio of Dim stars to bright stars. After calculating the bell curve the curve is folded in half and the peak used to represent the number of dim stars. Starfields can only be shown in 256 colors. Fractint will automatically try to load ALTERN.MAP and abort if the map file cannot be found. ; ; ; ~Topic=Random Dot Stereograms (RDS), Label=HELPRDS Random Dot Stereograms (RDS) are a way of encoding stereo images on a flat screen. Fractint can convert any image to a RDS using either the color number in the current palette or the grayscale value as depth. Try these steps. Generate a plasma fractal using the 640x480x256 video mode. When the image on the screen is complete, press ("s" for "Stereo"), and press at the "RDS Parameters" screen prompt to accept the defaults. (More on the parameters in a moment.) The screen will be converted into a seemingly random collection of colored dots. Relax your eyes, looking through the screen rather than at the screen surface. The image will (hopefully) resolve itself into the hills and valleys of the 3D Plasma fractal. Because pressing the two-keyed gets tiresome after a while, we have made key a synonym for for convenience. Don't get too attached to though; we reserve the right to reuse it for another purpose later. The RDS feature has five and sometimes six parameters. Pressing always takes you to the parameter screen. The first parameter allows you to control the depth effect. A larger value (positive or negative) exaggerates the sense of depth. If you make the depth negative, the high and low areas of the image are reversed. If your RDS image is streaky try either a lower depth factor or a higher resolution. The second parameter indicates the overall width in inches of the image on your monitor or printout. The default value of 10 inches is roughly the width of an image on a standard 14" to 16" monitor. This value does not normally need to be changed for viewing images on standard monitors. However, if your monitor or image hardcopy is much wider or narrower than 10 inches (25 cm), and you have trouble seeing the image, enter the image width in inches. The issue here is that if the widest separation of left and right pixels is greater than the physical separation of your eyes, you will not be able to fuse the images. Conversely, a too-small separation may cause your eyes to hyper-converge (fuse the wrong pixels together). A larger width value reduces the width between left and right pixels. You can use the calibration feature to help set the width parameter - see below. Once you have found a good width setting, you can place the value in your SSTOOLS.INI file with the command monitorwidth=. The third parameter allows you to control the method use to extract depth information from the original image. If your answer "no" at the "Use Grayscale value for Depth" prompt, then the color number of each pixel will be used. This value is independent of active color palette. If you answer "yes" and the prompt, then the depth values are keyed to the brightness of the color, which will change if you change palettes. The fourth parameter allows you to set the position of vertical stereo calibration bars to the middle or the top of the image, or have the bars initially turned off. Use this feature to help you adjust your eye's convergence to see the image. You will see two vertical bars on the screen. You can turn off and on these bars with the or keys after generating the RDS image. If you save an RDS image by pressing , if the bars are turned on at the time, they become a permanent part of the image. As you relax your eyes and look past the screen, these bars will appear as four bars. When you adjust your eyes so that the two middle bars merge into one bar, the 3D image should appear. The bars are set for the average depth in the area near the bars. They should always be closer together than the physical separation of your eyes, but not much less than about 1.5 inches. About 1.75 inches is ideal for many images. The depth and screen width controls affect the width of the bars. At the RDS Parameters screen, you can select bars at the middle of the screen or the top. If you select "none", the bars will initially be off, but immediately after generation of the image you can still turn on the bars with or before you press any other keys. If the initial setting of the calibration bars is "none", then if the bars are turned on later they will appear in the middle. Hint: if you cycle the colors and find you can't see the calibration bar, press or twice, and the bars will turn to a more visible color. The fifth parameter asks if you want to use an image map GIF file instead of using random dots. An image map can give your RDS image a more interesting background texture than the random dots. If you answer "yes" at the Use image map? prompt, Fractint will present you with a file selection list of GIF images. Fractint will then go ahead and transform your original image to RDS using the selected image map to provide the "random" dots. After you have selected an image map file, the next time you reach the RDS Parameters screen you will see an additional prompt asking if you want to use the same image map file again. Answering "yes" avoids the file selection menu. The best images to use as image maps are detailed textures with no solid spots. The default type=circle fractal works well, as do the barnsley fractals if you zoom in a little way. If the image map is smaller than your RDS image, the image map will repeated to fill the space. If the image map is larger, just the upper left corner of the image map will be used. The original image you are using for your stereogram is saved, so if you want to modify the stereogram parameters and try again, just press (or ) to get the parameter screen, changes the parameters, and press . The original image is restored and an RDS transform with the revised parameters is performed. If you press when viewing an RDS image, after the RDS image is saved, the original is restored. Try the RDS feature with continuous potential Mandelbrots as well as plasma fractals. For a summary of keystrokes in RDS mode, see {RDS Commands} ; ; ; ~Topic=Palette Maps, Label=HELPCOLORMAP If you have a VGA, MCGA, Super-VGA, 8514/A, XGA, TARGA, or TARGA+ video adapter, you can save and restore color palettes for use with any image. To load a palette onto an existing image, use the command in color-cycling or palette-editing mode. To save a palette, use the command in those modes. To change the default palette for an entire run, use the command line "map=" parameter. The default filetype for color-map files is ".MAP". These color-maps are ASCII text files set up as a series of RGB triplet values (one triplet per line, encoded as the red, green, and blue [RGB] components of the color). Note that .MAP file color values are in GIF format - values go from 0 (low) to 255 (high), so for a VGA adapter they get divided by 4 before being stuffed into the VGA's Video-DAC registers (so '6' and '7' end up referring to the same color value). ~OnlineFF ~Format- Fractint is distributed with some sample .MAP files: ALTERN.MAP the famous "Peterson-Vigneau Pseudo-Grey Scale" BLUES.MAP for rainy days, by Daniel Egnor CHROMA.MAP general purpose, chromatic DEFAULT.MAP the VGA start-up values FIRESTRM.MAP general purpose, muted fire colors GAMMA1.MAP and GAMMA2.MAP Lee Crocker's response to ALTERN.MAP GLASSES1.MAP used with 3d glasses modes GLASSES2.MAP used with 3d glasses modes GOODEGA.MAP for EGA users GREEN.MAP shaded green GREY.MAP another grey variant GRID.MAP for stereo surface grid images HEADACHE.MAP major stripes, by D. Egnor (try cycling and hitting <2>) LANDSCAP.MAP Guruka Singh Khalsa's favorite map for plasma "landscapes" NEON.MAP a flashy map, by Daniel Egnor PAINTJET.MAP high resolution mode PaintJet colors ROYAL.MAP the royal purple, by Daniel Egnor TOPO.MAP Monte Davis's contribution to full color terrain VOLCANO.MAP an explosion of lava, by Daniel Egnor ~Format+ ; ; ~Topic=Bailout Test The bailout test is used to determine if we should stop iterating before the maximum iteration count is reached. This test compares the value determined by the test to the "bailout" value set via the screen. The default bailout test compares the magnitude or modulus of a complex variable to some bailout value:\ ~Format- bailout test = |z| = sqrt(x^2 + y^2) >= 2 As a computational speedup, we square both sides of this equation and the bailout test used by Fractint is: bailout test = |z|^2 = x^2 + y^2 >= 4 Using a "bailout" other than 4 allows us to change when the bailout will occur. ~OnlineFF The following bailout tests have been implemented on the screen: mod: x^2 + y^2 >= bailout real: x^2 >= bailout imag: y^2 >= bailout or: x^2 >= bailout or y^2 >= bailout and: x^2 >= bailout and y^2 >= bailout manh: (abs(x) + abs(y))^2 >= bailout (based on Manhattan metric) manr: (x + y)^2 >= bailout ~Format+ The bailout test feature has not been implemented for all applicable fractal types. This is due to the speedups used for these types. Some of these bailout tests show the limitations of the integer math routines by clipping the spiked ends off of the protrusions. ; ; ; ~Topic=\"3D\" Images, Label=HELP3D ; Empty in docs, just to have the hotlink defined at chapter level. ~Format-,Doc- { 3D Overview } { 3D Mode Selection } { Select Fill Type Screen } { Stereo 3D Viewing } { Rectangular Coordinate Transformation } { 3D Color Parameters } { Light Source Parameters } { Spherical Projection } { 3D Overlay Mode } { Special Note for CGA or Hercules Users } { Making Terrains } { Making 3D Slides } { Interfacing with Ray Tracing Programs } ~Format+,Doc+ ; ; ; ~Topic=3D Overview Fractint can restore images in "3D". Important: we use quotation marks because it does not CREATE images of 3D fractal objects (there are such, but we're not there yet.) Instead, it restores .GIF images as a 3D PROJECTION or STEREO IMAGE PAIR. The iteration values you've come to know and love, the ones that determine pixel colors, are translated into "height" so that your saved screen becomes a landscape viewed in perspective. You can even wrap the landscape onto a sphere for realistic- looking planets and moons that never existed outside your PC! We suggest starting with a saved plasma-cloud screen. Hit <3> in main command mode to begin the process. Next, select the file to be transformed, and the video mode. (Usually you want the same video mode the file was generated in; other choices may or may not work.) After hitting <3>, you'll be bombarded with a long series of options. Not to worry: all of them have defaults chosen to yield an acceptable starting image, so the first time out just pump your way through with the key. When you enter a different value for any option, that becomes the default value the next time you hit <3>, so you can change one option at a time until you get what you want. Generally will take you back to the previous screen. Once you're familiar with the effects of the 3D option values you have a variety of options on how to specify them. You can specify them all on the command line (there ARE a lot of them so they may not all fit within the DOS command line limits), with an SSTOOLS.INI file, or with a parameter file. Here's an example for you power FRACTINTers, the command FRACTINT MYFILE SAVENAME=MY3D 3D=YES BATCH=YES would make Fractint load MYFILE.GIF, re-plot it as a 3D landscape (taking all of the defaults), save the result as MY3D.GIF, and exit to DOS. By the time you've come back with that cup of coffee, you'll have a new world to view, if not conquer. Note that the image created by 3D transformation is treated as if it were a plasma cloud - We have NO idea how to retain the ability to zoom and pan around a 3D image that has been twisted, stretched, perspective-ized, and water-leveled. Actually, we do, but it involves the kind of hardware that Industrial Light & Magic, Pixar et al. use for feature films. So if you'd like to send us a check equivalent to George Lucas' net from the "Star Wars" series... ; ; ; ~Topic=3D Mode Selection, Label=HELP3DMODE After hitting <3> and getting past the filename prompt and video mode selection, you're presented with a "3d Mode Selection" screen. If you wish to change the default for any of the following parameters, use the cursor keys to move through the menu. When you're satisfied press . Preview Mode: Preview mode provides a rapid look at your transformed image using by skipping a lot of rows and filling the image in. Good for quickly discovering the best parameters. Let's face it, the Fractint authors most famous for "blazingly fast" code *DIDN'T* write the 3D routines! [Pieter: "But they *are* picking away it and making some progress in each release."] Show Box: If you have selected Preview Mode you have another option to worry about. This is the option to show the image box in scaled and rotated coordinates x, y, and z. The box only appears in rectangular transformations and shows how the final image will be oriented. If you select light source in the next screen, it will also show you the light source vector so you can tell where the light is coming from in relation to your image. Sorry no head or tail on the vector yet. ~OnlineFF Coarseness: This sets how many divisions the image will be divided into in the y direction, if you select preview mode, ray tracing output, or grid fill in the "Select Fill Type" screen. Spherical Projection: The next question asks if you want a sphere projection. This will take your image and map it onto a plane if you answer "no" or a sphere if you answer "yes" as described above. Try it and you'll see what we mean. See {Spherical Projection}. Stereo: Stereo sound in Fractint? Well, not yet. Fractint now allows you to create 3D images for use with red/blue glasses like 3D comics you may have seen, or images like Captain EO. Option 0 is normal old 3D you can look at with just your eyes. Options 1 and 2 require the special red/blue-green glasses. They are meant to be viewed right on the screen or on a color print off of the screen. The image can be made to hover entirely or partially in front of the screen. Great fun! These two options give a gray scale image when viewed. Option 1 gives 64 shades of gray but with half the spatial resolution you have selected. It works by writing the red and blue images on adjacent pixels, which is why it eats half your resolution. In general, we recommend you use this only with resolutions above 640x350. Use this mode for continuous potential landscapes where you *NEED* all those shades. Option "2" gives you full spatial resolution but with only 16 shades of gray. If the red and blue images overlap, the colors are mixed. Good for wire-frame images (we call them surface grids), lorenz3d and 3D IFS. Works fine in 16 color modes. Option 3 is for creating stereo pair images for view later with more specialized equipment. It allows full color images to be presented in glorious stereo. The left image presented on the screen first. You may photograph it or save it. Then the second image is presented, you may do the same as the first image. You can then take the two images and convert them to a stereo image pair as outlined by Bruce Goren (see below). Option 4 places left and right images on the screen simultaneously as a stereo pair. Also see {Stereo 3D Viewing}. ~OnlineFF Ray Tracing Output: Fractint can create files of its 3d transformations which are compatible with many ray tracing programs. Currently four are supported directly: DKB (now obsolete), VIVID, MTV, and RAYSHADE. In addition a "RAW" output is supported which can be relatively easily transformed to be usable by many other products. One other option is supported: ACROSPIN. This is not a ray tracer, but the same Fractint options apply - see {=@ACROSPIN Acrospin}. Option values:\ 0 disables the creation of ray tracing output\ 1 DKB format (obsolete-see below)\ 2 VIVID format\ 3 generic format (must be massaged externally)\ 4 MTV format\ 5 RAYSHADE format\ 6 ACROSPIN format\ Users of POV-Ray can use the DKB output and convert to POV-Ray with the DKB2POV utility that comes with POV-Ray. A better (faster) approach is to create a RAW output file and convert to POV-Ray with RAW2POV. A still better approach is to use POV-Ray's height field feature to directly read the fractal .GIF or .POT file and do the 3D transformation inside POV-Ray. All ray tracing files consist of triangles which follow the surface created by Fractint during the 3d transform. Triangles which lie below the "water line" are not created in order to avoid causing unnecessary work for the poor ray tracers which are already overworked. A simple plane can be substituted by the user at the waterline if needed. The size (and therefore the number) of triangles created is determined by the "coarse" parameter setting. While generating the ray tracing file, you will view the image from above and watch it partitioned into triangles. The color of each triangle is the average of the color of its verticies in the original image, unless BRIEF is selected. If BRIEF is selected, a default color is assigned at the begining of the file and is used for all triangles. Also see {Interfacing with Ray Tracing Programs}. Brief output: This is a ray tracing sub-option. When it is set to yes, Fractint creates a considerably smaller and somewhat faster file. In this mode, all triangles use the default color specified at the begining of the file. This color should be edited to supply the color of your choice. Targa Output: If you want any of the 3d transforms you select to be saved as a Targa-24 file or overlayed onto one, select yes for this option. The overlay option in the final screen determines whether you will create a new file or overlay an existing one. MAP File name: Imediately after selecting the previous options, you will be given the chance to select an alternate color MAP file. The default is to use the current MAP. If you want another MAP used, then enter your selection at this point. Output File Name: This is a ray tracing sub-option, used to specify the name of the file to be written. The default name is FRACT001.RAY. The name is incremented by one each time a file is written. If you have not set "overwrite=yes" then the file name will also be automatically incremented to avoid over-writing previous files. ~Online- When you are satisfied with your selections press enter to go to the next parameter screen. ~Online+ ; ; ; ~Topic=Select Fill Type Screen, Label=HELP3DFILL This option exists because in the course of the 3D projection, portions of the original image may be stretched to fit the new surface. Points of an image that formerly were right next to each other, now may have a space between them. This option generally determines what to do with the space between the mapped dots. It is not used if you have selected a value for RAY other than 0. For an illustration, pick the second option "just draw the points", which just maps points to corresponding points. Generally this will leave empty space between many of the points. Therefore you can choose various algorithms that "fill in" the space between the points in various ways. Later, try the first option "make a surface grid." This option will make a grid of the surface which is as many divisions in the original "y" direction as was set in "coarse" in the first screen. It is very fast, and can give you a good idea what the final relationship of parts of your picture will look like. Later, try the second option "connect the dots (wire frame)", then "surface fills" - "colors interpolated" and "colors not interpolated", the general favorites of the authors. Solid fill, while it reveals the pseudo-geology under your pseudo-landscape, inevitably takes longer. Later, try the light source fill types. These two algorithms allow you to position the "sun" over your "landscape." Each pixel is colored according to the angle the surface makes with an imaginary light source. You will be asked to enter the three coordinates of the vector pointing toward the light in a following parameter screen - see {Light Source Parameters}. "Light source before transformation" uses the illumination direction without transforming it. The light source is fixed relative to your computer screen. If you generate a sequence of images with progressive rotation, the effect is as if you and the light source are fixed and the object is rotating. Therefore as the object rotates features of the object move in and out of the light. This fill option was incorrect prior to version 16.1, and has been changed. "Light source after transformation" applies the same transformation to both the light direction and the object. Since both the light direction and the object are transformed, if you generate a sequence of images with the rotation progressively changed, the effect is as if the image and the light source are fixed in relation to each other and you orbit around the image. The illumination of features on the object is constant, but you see the object from different angles. This fill option was correct in earlier Fractint versions and has not been changed. For ease of discussion we will refer to the following fill types by these numbers: 1 - surface grid\ 2 - (default) - no fill at all - just draw the dots\ 3 - wire frame - joins points with lines\ 4 - surface fill - (colors interpolated)\ 5 - surface fill - (interpolation turned off)\ 6 - solid fill - draws lines from the "ground" up to the point\ 7 - surface fill with light model - calculated before 3D transforms\ 8 - surface fill with light model - calculated after 3D transforms\ Types 4, 7, and 8 interpolate colors when filling, making a very smooth fill if the palette is continuous. This may not be desirable if the palette is not continuous. Type 5 is the same as type 4 with interpolation turned off. You might want to use fill type 5, for example, to project a .GIF photograph onto a sphere. With type 4, you might see the filled-in points, since chances are the palette is not continuous; type 5 fills those same points in with the colors of adjacent pixels. However, for most fractal images, fill type 4 works better. This screen is not available if you have selected a ray tracing option. ; ; ; ~Topic=Stereo 3D Viewing, Label=HELP3DGLASSES The "Funny Glasses" (stereo 3D) parameter screen is presented only if you select a non-zero stereo option in the prior 3D parameters. (See {3D Mode Selection}.) We suggest you definitely use defaults at first on this screen. When you look at an image with both eyes, each eye sees the image in slightly different perspective because they see it from different places. The first selection you must make is ocular separation, the distance the between the viewers eyes. This is measured as a % of screen and is an important factor in setting the position of the final stereo image in front of or behind the CRT Screen. The second selection is convergence, also as a % of screen. This tends to move the image forward and back to set where it floats. More positive values move the image towards the viewer. The value of this parameter needs to be set in conjunction with the setting of ocular separation and the perspective distance. It directly adjusts the overall separation of the two stereo images. Beginning anaglyphers love to create images floating mystically in front of the screen, but grizzled old 3D veterans look upon such antics with disdain, and believe the image should be safely inside the monitor where it belongs! Left and Right Red and Blue image crop (% of screen also) help keep the visible part of the right image the same as the visible part of the left by cropping them. If there is too much in the field of either eye that the other doesn't see, the stereo effect can be ruined. Red and Blue brightness factor. The generally available red/blue-green glasses, made for viewing on ink on paper and not the light from a CRT, let in more red light in the blue-green lens than we would like. This leaves a ghost of the red image on the blue-green image (definitely not desired in stereo images). We have countered this by adjusting the intensity of the red and blue values on the CRT. In general you should not have to adjust this. The final entry is Map file name (present only if stereo=1 or stereo=2 was selected). If you have a special map file you want to use for Stereo 3D this is the place to enter its name. Generally glasses1.map is for type 1 (alternating pixels), and glasses2.map is for type 2 (superimposed pixels). Grid.map is great for wire-frame images using 16 color modes. This screen is not available if you have selected a ray tracing option. ; ; ; ~Topic=3D Fractal Parameters, Label=HELP3DFRACT ; This topic is online only. The parameters on this screen are a subset of the zillions of options available for Fractint's 3D image transformations. This screen's parameters are those which also affect 3D fractal types like lorenz3d and kamtorus3d. Since they are documented elsewhere, we won't repeat ourselves: For a description of rotation, perspective, and shift parameters, please see {Rectangular Coordinate Transformation}. Ignore the paragraphs about "scaling" and "water level" - those parts apply only to 3D Transforms. For a description of the stereo option, please see the "stereo" subheading in {3D Mode Selection}. ; ; ; ~Topic=Rectangular Coordinate Transformation, Label=HELP3DPARMS The first entries are rotation values around the X, Y, and Z axes. Think of your starting image as a flat map: the X value tilts the bottom of your monitor towards you by X degrees, the Y value pulls the left side of the monitor towards you, and the Z value spins it counter-clockwise. Note that these are NOT independent rotations: the image is rotated first along the X-axis, then along the Y-axis, and finally along the Z-axis. Those are YOUR axes, not those of your (by now hopelessly skewed) monitor. All rotations actually occur through the center of the original image. Rotation parameters are not used when a ray tracing option has been selected. Then there are three scaling factors in percent. Initially, leave the X and Y axes alone and play with Z, now the vertical axis, which translates into surface "roughness." High values of Z make spiky, on-beyond-Alpine mountains and improbably deep valleys; low values make gentle, rolling terrain. Negative roughness is legal: if you're doing an M-set image and want Mandelbrot Lake to be below the ground, instead of eerily floating above, try a roughness of about -30%. Next we need a water level -- really a minimum-color value that performs the function "if (color < waterlevel) color = waterlevel". So it plots all colors "below" the one you choose at the level of that color, with the effect of filling in "valleys" and converting them to "lakes." Now we enter a perspective distance, which you can think of as the "distance" from your eye to the image. A zero value (the default) means no perspective calculations, which allows use of a faster algorithm. Perspective distance is not available if you have selected a ray tracing option. For non-zero values, picture a box with the original X-Y plane of your flat fractal on the bottom, and your 3D fractal inside. A perspective value of 100% places your eye right at the edge of the box and yields fairly severe distortion, like a close view through a wide-angle lens. 200% puts your eye as far from the front of the box as the back is behind. 300% puts your eye twice as far from the front of the box as the back is, etc. Try about 150% for reasonable results. Much larger values put you far away for even less distortion, while values smaller than 100% put you "inside" the box. Try larger values first, and work your way in. Next, you are prompted for two types of X and Y shifts (now back in the plane of your screen) that let you move the final image around if you'd like to re-center it. The first set, x and y shift with perspective, move the image and the effect changes the perspective you see. The second set, "x and y adjust without perspective", move the image but do not change perspective. They are used just for positioning the final image on the screen. Shifting of any type is not available if you have selected a ray tracing option. ~Doc- {3D Color Parameters} are also requested on the same input screen.\ If you are doing a {Spherical Projection}, special parameters for it are requested at the start of this screen. ~Doc+ ; ; ; ~Topic=3D Color Parameters You are asked for a range of "transparent" colors, if any. This option is most useful when using the {3D Overlay Mode}. Enter the color range (minimum and maximum value) for which you do not want to overwrite whatever may already be on the screen. The default is no transparency (overwrite everything). Now, for the final option. This one will smooth the transition between colors by randomizing them and reduce the banding that occurs with some maps. Select the value of randomize to between 0 (for no effect) and 7 (to randomize your colors almost beyond use). 3 is a good starting point. That's all for this screen. Press enter for these parameters and the next and final screen will appear (honestly!). ; ; ; ~Topic=Light Source Parameters, Label=HELP3DLIGHT This one deals with all the aspects of light source and Targa files. You must choose the direction of the light from the light source. This will be scaled in the x, y, and z directions the same as the image. For example, 1,1,3 positions the light to come from the lower right front of the screen in relation to the untransformed image. It is important to remember that these coordinates are scaled the same as your image. Thus, "1,1,1" positions the light to come from a direction of equal distances to the right, below and in front of each pixel on the original image. However, if the x,y,z scale is set to 90,90,30 the result will be from equal distances to the right and below each pixel but from only 1/3 the distance in front of the screen i.e.. it will be low in the sky, say, afternoon or morning. Then you are asked for a smoothing factor. Unless you used {Continuous Potential} when generating the starting image, the illumination when using light source fills may appear "sparkly", like a sandy beach in bright sun. A smoothing factor of 2 or 3 will allow you to see the large-scale shapes better. Smoothing is primarily useful when doing light source fill types with plasma clouds. If your fractal is not a plasma cloud and has features with sharply defined boundaries (e.g. Mandelbrot Lake), smoothing may cause the colors to run. This is a feature, not a bug. (A copyrighted response of [your favorite commercial software company here], used by permission.) The ambient option sets the minimum light value a surface has if it has no direct lighting at all. All light values are scaled from this value to white. This effectively adjusts the depth of the shadows and sets the overall contrast of the image. If you selected the full color option, you have a few more choices. The next is the haze factor. Set this to make distant objects more hazy. Close up objects will have little effect, distant objects will have most. 0 disables the function. 100 is the maximum effect, the farthest objects will be lost in the mist. Currently, this does not really use distance from the viewer, we cheat and use the y value of the original image. So the effect really only works if the y-rotation (set earlier) is between +/- 30. Next, you can choose the name under which to save your Targa file. If you have a RAM disk handy, you might want to create the file on it, for speed. So include its full path name in this option. If you have not set "overwrite=yes" then the file name will be incremented to avoid over-writing previous files. If you are going to overlay an existing Targa file, enter its name here. Next, you may select the background color for the Targa file. The default background on the Targa file is sky blue. Enter the Red, Green, and Blue component for the background color you wish. Finally, absolutely the last option (this time we mean it): you can now choose to overlay an existing Targa-24, type 2, non mapped, top-to-bottom file, such as created by Fractint or PVRay. The Targa file specified above will be overlayed with new info just as a GIF is overlayed on screen. Note: it is not necessary to use the "O" overlay command to overlay Targa files. The Targa_Overlay option must be set to yes, however. You'll probably want to adjust the final colors for monochrome fill types using light source via {=@ColorCycling color cycling}. Try one of the more continuous palettes ( through ), or load the GRAY palette with the lternate-map command. ~Online- Now, lie down for a while in a quiet room with a damp washcloth on your forehead. Feeling better? Good -- because it's time to go back almost to the top of the 3D options and just say yes to: ~Online+ ; ; ; ~Topic=Spherical Projection Picture a globe lying on its side, "north" pole to the right. (It's our planet, and we'll position it the way we like.) You will be mapping the X and Y axes of the starting image to latitude and longitude on the globe, so that what was a horizontal row of pixels follows a line of longitude. The defaults exactly cover the hemisphere facing you, from longitude 180 degrees (top) to 0 degrees (bottom) and latitude -90 (left) to latitude 90 (right). By changing them you can map the image to a piece of the hemisphere or wrap it clear around the globe. The next entry is for a radius factor that controls the over-all size of the globe. All the rest of the entries are the same as in the landscape projection. You may want less surface roughness for a plausible look, unless you prefer small worlds with big topography, a la "The Little Prince." WARNING: When the "construction" process begins at the edge of the globe (default) or behind it, it's plotting points that will be hidden by subsequent points as the process sweeps around the sphere toward you. Our nifty hidden-point algorithms "know" this, and the first few dozen lines may be invisible unless a high mountain happens to poke over the horizon. If you start a spherical projection and the screen stays black, wait for a while (a longer while for higher resolution or fill type 6) to see if points start to appear. Would we lie to you? If you're still waiting hours later, first check that the power's still on, then consider a faster system. ; ; ; ~Topic=3D Overlay Mode, Label=HELP3DOVLY While the <3> command (see {\"3D\" Images}) creates its image on a blank screen, the <#> (or on some keyboards) command draws a second image over an existing displayed image. This image can be any restored image from a command or the result of a just executed <3> command. So you can do a landscape, then press <#> and choose spherical projection to re-plot that image or another as a moon in the sky above the landscape. <#> can be repeated as many times as you like. It's worth noting that not all that many years ago, one of us watched Benoit Mandelbrot and fractal-graphics wizard Dick Voss creating just such a moon-over-landscape image at IBM's research center in Yorktown Heights, NY. The system was a large and impressive mainframe with floating-point facilities bigger than the average minicomputer, running LBLGRAPH -- what Mandelbrot calls "an independent-minded and often very ill-mannered heap of graphics programs that originated in work by Alex Hurwitz and Jack Wright of IBM Los Angeles." We'd like to salute LBLGRAPH, its successors, and their creators, because it was their graphic output (like "Planetrise over Labelgraph Hill," plate C9 in Mandelbrot's "Fractal Geometry of Nature") that helped turn fractal geometry from a mathematical curiosity into a phenomenon. We'd also like to point out that it wasn't as fast, flexible or pretty as Fractint on a 386/16 PC with S-VGA graphics. Now, a lot of the difference has to do with the incredible progress of micro-processor power since then, so a lot of the credit should go to Intel rather than to our highly tuned code. OK, twist our arms -- it IS awfully good code. ; ; ; ~Topic=Special Note for CGA or Hercules Users If you are one of those unfortunates with a CGA or Hercules 2-color monochrome graphics, it is now possible for you to make 3D projection images. Try the following unfortunately circuitous approach. Invoke Fractint, making sure you have set askvideo=yes. Use a disk-video mode to create a 256 color fractal. You might want to edit the fractint.cfg file to make a disk-video mode with the same pixel dimensions as your normal video. Using the "3" command, enter the file name of the saved 256 color file, then select your 2 or 4 color mode, and answer the other 3D prompts. You will then see a 3D projection of the fractal. Another example of Stone Soup responsiveness to our fan mail! ; ; ; ~Topic=Making Terrains If you enjoy using Fractint for making landscapes, we have several new features for you to work with. When doing 3d transformations banding tends to occur because all pixels of a given height end up the same color. Now, colors can be randomized to make the transitions between different colors at different altitudes smoother. Use the new "RANDOMIZE= " variable to accomplish this. If your light source images all look like lunar landscapes since they are all monochrome and have very dark shadows, we now allow you to set the ambient light for adjusting the contrast of the final image. Use the "Ambient= " variable. In addition to being able to create scenes with light sources in monochrome, you can now do it in full color as well. Setting fullcolor=1 will generate a Targa-24 file with a full color image which will be a combination of the original colors of the source image (or map file if you select map=something) and the amount of light which reflects off a given point on the surface. Since there can be 256 different colors in the original image and 256 levels of light, you can now generate an image with *lots* of colors. To convert it to a GIF if you can't view Targa files directly, you can use PICLAB (see {Other Programs}), and the following commands: SET PALETTE 256\ SET CREZ 8\ TLOAD yourfile.tga\ MAKEPAL\ MAP\ GSAVE yourfile.gif\ EXIT\ Using the full color option allows you to also set a haze factor with the "haze= " variable to make more distant objects more hazy. As a default, full color files also have the background set to sky blue. Warning, the files which are created with the full color option are very large, 3 bytes per pixel. So be sure to use a disk with enough space. The file is created using Fractint's disk-video caching, but is always created on real disk (expanded or extended memory is not used.) Try the following settings of the new variables in sequence to get a feel for the effect of each one:\ ;use this with any filltype\ map=topo\ randomize=3; adjusting this smooths color transitions\ ;now add this using filltype 5 or 6\ ambient=20; adjusting this changes the contrast\ filltype=6\ smoothing=2; makes the light not quite as granular as the terrain\ ;now add the following, and this is where it gets slow\ fullcolor=1; use PICLAB to reduce resulting lightfile to a GIF\ ;and finally this\ haze=20; sets the amount of haze for distant objects\ When full color is being used, the image you see on the screen will represent the amount of light being reflected, not the colors in the final image. Don't be disturbed if the colors look weird, they are an artifact of the process being used. The image being created in the lightfile won't look like the screen. However, if you are worried, hit ESC several times and when Fractint gets to the end of the current line it will abort. Your partial image will be there as LIGHT001.TGA or with whatever file name you selected with the lightname option. Convert it as described above and adjust any parameters you are not happy with. Its a little awkward, but we haven't figured out a better way yet. ; ; ; ~Topic=Making 3D Slides Bruce Goren, CIS's resident stereoscopic maven, contributed these tips on what to do with your 3D images (Bruce inspired and prodded us so much we automated much of what follows, allowing both this and actual on screen stereo viewing, but we included it here for reference and a brief tutorial.) "I use a Targa 32 video card and TOPAS graphic software, moving the viewport or imaginary camera left and right to create two separate views of the stationary object in x,y,z, space. The distance between the two views, known as the inter-ocular distance, toe-in or convergence angle, is critical. It makes the difference between good 3-D and headache-generating bad 3-D. "For a 3D fractal landscape, I created and photographed the left and right eye views as if flying by in an imaginary airplane and mounted the film chips for stereo viewing. To make my image, first I generated a plasma cloud based on a color map I calculated to resemble a geological survey map (available on CIS as TARGA.MAP). In the 3D reconstruction, I used a perspective value of 150 and shifted the camera -15 and +15 on the X-axis for the left and right views. All other values were left to the defaults. "The images are captured on a Matrix 3000 film recorder -- basically a box with a high-resolution (1400 lines) black and white TV and a 35mm camera (Konica FS-1) looking at the TV screen through a filter wheel. The Matrix 3000 can be calibrated for 8 different film types, but so far I have only used Kodak Ektachrome 64 daylight for slides and a few print films. I glass mount the film chips myself. "Each frame is exposed three times, once through each of the red, blue, and green filters to create a color image from computer video without the scan-lines which normally result from photographing television screens. The aspect ratio of the resulting images led me to mount the chips using the 7-sprocket Busch-European Emde masks. The best source of Stereo mounting and viewing supplies I know of is an outfit called Reel 3-D Enterprises, Inc. at P.O. Box 2368, Culver City, CA 90231, tel. 213-837- 2368. "My platform is an IBM PC/AT crystal-swapped up to 9 MHz. The math co-processor runs on a separate 8-MHz accessory sub-board. The system currently has 6.5 MB of RAM." ; ; ; ~Topic=Interfacing with Ray Tracing Programs (Also see "Ray Tracing Output", "Brief", and "Output File Name" in {"3D Mode Selection"}.) Fractint allows you to save your 3d transforms in files which may be fed to a ray tracer (or to "Acrospin"). However, they are not ready to be traced by themselves. For one thing, no light source is included. They are actually meant to be included within other ray tracing files. Since the intent is to produce an object which may be included in a larger ray tracing scene, it is expected that all rotations, shifts, and final scaling will be done by the ray tracer. Thus, in creating the images, no facilities for rotations or shifting is provided. Scaling is provided to achieve the correct aspect ratio. WARNING! The files created using the RAY option can be huge. Setting COARSE to 40 will result in over 2000 triangles. Each triangle can utilize from 50 to 200 bytes each to describe, so your ray tracing files can rapidly approach or exceed 1Meg. Make sure you have enough disk space before you start. Each file starts with a comment identifying the version of Fractint by which it was created. The file ends with a comment giving the number of triangles in the file. The files consist of long strips of adjacent triangles. Triangles are clockwise or counter clockwise depending on the target ray tracer. Currently, MTV and Rayshade are the only ones which use counter clockwise triangles. The size of the triangles is set by the COARSE setting in the main 3d menu. Color information about each individual triangle is included for all files unless in the brief mode. To keep the poor ray tracer from working too hard, if WATERLINE is set to a non zero value, no triangle which lies entirely at or below the current setting of WATERLINE is written to the ray tracing file. These may be replaced by a simple plane in the syntax of the ray tracer you are using. Fractint's coordinate system has the origin of the x-y plane at the upper left hand corner of the screen, with positive x to the right and positive y down. The ray tracing files have the origin of the x-y plane moved to the center of the screen with positive x to the right and positive y up. Increasing values of the color index are out of the screen and in the +z direction. The color index 0 will be found in the xy plane at z=-1. When x- y- and zscale are set to 100, the surface created by the triangles will fall within a box of +/- 1.0 in all 3 directions. Changing scale will change the size and/or aspect ratio of the enclosed object. We will only describe the structure of the RAW format here. If you want to understand any of the ray tracing file formats besides RAW, please see your favorite ray tracer docs. The RAW format simply consists of a series of clockwise triangles. If BRIEF=yes, Each line is a vertex with coordinates x, y, and z. Each triangle is separated by a couple of CR's from the next. If BRIEF=no, the first line in each triangle description if the r,g,b value of the triangle. Setting BRIEF=yes produces shorter files with the color of each triangle removed - all triangles will be the same color. These files are otherwise identical to normal files but will run faster than the non BRIEF files. Also, with BRIEF=yes, you may be able to get files with more triangles to run than with BRIEF=no. The DKB format is now obsolete. POV-Ray users should use the RAW output and convert to POV-Ray using the POV Group's RAW2POV utility. POV-Ray users can also do all 3D transformations within POV-Ray using height fields. ; ; ; xfractint-20.4.10.orig/dos_help/help4.src0000644000000000000000000032132710756016765015054 0ustar ~Topic=Startup Parameters\, Parameter Files ; This topic is online only. ~Format- { Summary of all Parameters } { Introduction to Parameters } { Using the DOS Command Line } { Setting Defaults (SSTOOLS.INI File) } { Parameter Files and the <@> Command } { General Parameter Syntax } { Startup Parameters } { Calculation Mode Parameters } { Fractal Type Parameters } { Image Calculation Parameters } { Passes Parameters } { Color Parameters } { Doodad Parameters } { File Parameters } { Sound Parameters } { Video Parameters } { Printer Parameters } { 3D Parameters } ; ; ~Topic=Summary of all Parameters, Label=HELPCOMMANDS ; This topic is online only. ~Format- {Startup Parameters} @filename[/setname] Process commands from a file [filename=]filename Start with this saved file (one saved by FRACTINT or a generic GIF file [treated as a plasma cloud]) makepar=parfile[/entry] Invokes batch facility to copy a GIF to PAR format with colors. maxlinelength=nnn Sets maximum width of lines written to PAR files. batch=yes Batch mode run (display image, save-to-disk, exit) autokey=play|record Playback or record keystrokes autokeyname=\\filename File for autokey mode, default AUTO.KEY fpu=387 Assume 387 fpu is present makedoc=filename Create Fractint documentation file maxhistory= Set image capacity of history feature. A higher number stores more images but uses more memory. tempdir=directory Place temporary files here workdir=directory Directory for miscellaneous written files curdir=yes|no When set to yes, Fractint checks current directory before default directory when opening files. Use this command when testing temporary .FRM, .L, etc. files in the current directory. comment=comment1/comment2/comment3/comment4 Inserts comments into PAR files. ~FF {Calculation Mode Parameters} passes=1|2|3|g|b|d|t|g1..g6|s|o Select Single-Pass, Dual-Pass, Triple-Pass Solid-Guessing, Solid-Guessing stop after pass n, Boundary-Tracing, Diffusion, Tesseral, Synchronous Orbits, or Orbits drawing algorithms fillcolor=normal| Sets a block fill color for use with Boundary Tracing and Tesseral options float=yes For most functions changes from integer math to fp symmetry=xxxx Force symmetry to None, Xaxis, Yaxis, XYaxis, Origin, or Pi symmetry. Useful as a speedup. Only use this feature if the fractal actually *has* the stated symmetry, otherwise may not work as expected. bfdigits= Force nnn digits if arbitrary precision used (not recommended - this is a developer feature.) mathtolerance=/ This commands controls the logic that automatically selects one of integer/float/arbitrary precision based on precision requirements of the current zoom depth. The first number controls the integer/float transition, and the second number controls the float/arbitrary precision transition. minstack= For SOI (passes=s). This controls the minimum number stack memory reserved during synchronous orbits. ~FF {Fractal Type Parameters} type=fractaltype Perform this Fractal Type (Default = mandel) See {Fractal Types} for a full list params=xxx[/xxx[/... Begin with these extra Parameter values (Examples: params=4 params=-0.480/0.626) function=fn1/.../fn4 Allows specification of transcendental functions with types using variable functions. Values are sin, cos, tan, cotan, sinh, cosh, tanh, cotanh, exp, log, sqr, recip (1/z), ident (identity), conj, flip, zero, one, cosxx (cos with bug), asin, asinh, acos, acosh, atan, atanh, sqrt, abs, cabs, floor, ceil, trunc, round formulaname=name Formula name for 'type=formula' fractals lname=name Lsystem name for 'type=lsystem' fractals ifs=name IFS name for 'type=ifs' fractals 3dmode=monocular|left|right|red-blue Sets the 3D mode used with Julibrot julibrot3d=nn[/nn[/nn[/nn[/nn[/nn]]]]]") Sets Julibrot 3D parameters zdots, origin, depth, height, width, and distance julibroteyes=nn Distance between the virtual eyes for Julibrot julibrotfromto=nn/nn[/nn/nn] "From-to" parameters used for Julibrot miim=depth|breadth|walk[/left|right] Parameters for MIIM julias. ~FF {Image Calculation Parameters} corners=[xmin/xmax/ymin/ymax[/x3rd/y3rd]] Begin with these Coordinates (Example: corners=-0.739/-0.736/0.288/0.291) With no parameters causes command to output 'corners=' instead of center-mag. center-mag=[Xctr/Yctr/Mag[/Xmagfactor/Rotation/Skew]] An alternative method of entering corners. (Example: center-mag=-0.7375/0.2895/300) With no parameters causes command to output 'center-mag=' (default) instead of corners. maxiter=nnn Maximum number of iterations (default = 150) bailout=nnnn Use this as the iteration bailout value (instead of the default (4.0 for most fractal types) bailoutest=mod|real|imag|or|and|manh|manr Sets bailout test (default=mod) initorbit=nnn/nnn Sets the value used to initialize Mandelbrot orbits to the given complex number (real and imag parts) initorbit=pixel Sets the value used to initialize Mandelbrot orbits to the complex number corresponding to the screen pixel. This is the default for most types. rseed=nnnnn Random number seed, for reproducable Plasma Clouds ~OnLineFF showdot=[auto|bright|medium|dark|nn]/size Colors the current dot being calculated color nn or an automatically calculated color (-1 disables). The second parameter is the size of the traveling pointer. aspectdrift=nn How much the aspect ratio can vary from normal due to zooming. (default is 0.02) {Passes Parameters} periodicity=[no|show|nnn] Controls periodicity checking. 'no' turns checking off; entering a number nnn controls the tightness of checking (default 1, higher is more stringent) 'show' or a neg value colors 'caught' points white. orbitdelay=nn Starts plotting orbits after the nth orbit. orbitinterval=nn Plots every nth orbit point with passes=o. screencoords=yes|no Maintain screen coordinates constant. orbitdrawmode=rect|line Use rectangular mode or line mode for orbits. ~OnLineFF {Color Parameters} inside=nnn|maxiter|zmag|bof60|bof61|epscr|star|per|atan|fmod Fractal interior color (inside=0 for black) outside=nnn|iter|real|imag|mult|summ|atan|fmod|tdis Fractal exterior color options map=\\filename Use 'filename' as the default color map (vga/targa) colors=@filename|colorspec Sets current image color map from file or spec, vga or higher only recordcolors=auto|comment|yes Sets method of writing colors in PAR files. Auto causes colors=@mapfile to be written if colors came from loading a color map. Yes and comment force compressed colors always. Comment also writes map name in a comment if colors came from a map file. Default is auto. cyclerange=nnn/nnn Range of colors to cycle (default 1/255) cyclelimit=nnn Color-cycler speed-limit (1 to 256, default = 55) olddemmcolors=yes|no Use old coloring scheme with distance estimator textcolors=aa/bb/cc/... Set text screen colors textcolors=mono Set text screen colors to simple black and white truecolor=yes Writes truecolor information to Targa file. truemode=def|iter Writes default color scheme or escape iteration to Targa file. nobof=yes|no Causes inside=bof60 & bof61 to NOT duplicate the bof images, but function like the other inside= options. Default is no. {Doodad Parameters} logmap=yes|old|nn Yes maps logarithm of iteration to color. Old uses pre vsn 14 logic. >1 compresses, <-1 for quadratic. logmode=fly|table|auto Fly forces on-the-fly calculation of logmap. Table forces the use of the logmap array. Auto causes logmap to be recalculated automatically when zooming. ranges=nn/nn/nn/... Ranges of iteration values to map to colors distest=nnn/nnn Distance Estimator Method decomp=nn 'Decomposition' toggle, value 2 to 256. biomorph=nnn Biomorph Coloring potential=nn[/nn[/nn[/16bit]]] Continuous Potential invert=nn/nn/nn Turns on inversion - turns images 'inside out' finattract=yes Look for finite attractor in julia types exitnoask=yes bypasses the final "are you sure?" exit screen ~OnLineFF {Sound Parameters} sound=off|beep|x|y|z Nobody ever plays with fractals at work, do they? /pc|fm/quant x|y|z can be used to add sound to attractor fractals, the orbits command, and reading GIFs. The PC speaker and/or an OPL-3 FM synth card can now be used for sound. See {Sound Controls}. The note frequency can be quantized, or rounded to the next 'proper' note. hertz=nnn Base frequency for sound effects orbitdelay=nn Slows up the display of orbits (by nn/10000 sec) showorbit=yes|no Causes orbits to be toggled on at start of image generation. orbitsave=sound Causes sound values of orbits of escape-time fractals and orbit fractals to be saved in a file suitable for post-processing to midi. {Advanced Sound Controls} polyphony=nn The number of voices audible at one time. wavetype=nn Selects the waveform used by the voices. attack=nn Time for note to reach full volume. decay=nn Time for note to reach zero volume. sustain=nn Level at which note is maintained 'on'. srelease=nn Time note takes to release. Note the leading 's'. volume=nn Volume adjustment for FM synth card, but NOT the PC speaker. attenuate=none|low|mid|high Attenuation of high pitched notes. scalemap=nn/nn/nn/... Combined with quantization this allows selecting notes on the musical scale. ~OnLineFF {File Parameters} filename=.suffix Sets the default file extension for the command formulafile=\\filename File for type=formula, default FRACTINT.FRM ifsfile=\\filename File for type=ifs, default FRACTINT.IFS lfile=\\filename File for type=lsystem, default FRACTINT.L map=\\filename Use 'filename' as the default color map (vga/targa) orgfrmdir= Path to OrgForm directory parmfile=\\filename File for <@> and commands, default FRACTINT.PAR savename=\\filename Save files using this name (instead of FRACT001) dither=yes Dither color GIFs read into a b/w display. gif87a=yes Save GIF files in the older GIF87a format (with no FRACTINT extension blocks) orbitsave=yes Causes IFS and orbit fractals orbit points to be saved in the file ORBITS.RAW overwrite=no|yes Don't over-write existing files savetime=nnn Autosave image every nnn minutes of calculation ~FF {Video Parameters} video=xxx Begin with this video mode (Example: Video=F2) askvideo=no Skip the prompt for video mode when restoring files adapter=hgc|cga|ega|egamono|mcga|vga Assume this (standard) video adapter is present adapter=ATI|Everex|Trident|NCR|Video7|Genoa|Paradise|Chipstech| Tseng3000|Tseng4000|AheadA|AheadB|Oaktech Assume the named SuperVGA Chip set is present and enable its non-standard SuperVGA modes. afi=yes Disables the register-compatible 8514/A logic and forces the use of the 8514/A API (HDILOAD) textsafe=yes|no|bios|save For use when images are not restored correctly on return from a text display exitmode=nn Sets the bios-supported videomode to use upon exit (if not mode 3) - nn is the mode in hexadecimal viewwindows=xx[/xx[/yes|no[/nn[/nn]]]] Set the reduction factor, final media aspect ratio, crop starting coordinates (y/n), explicit x size, and explicit y size ~OnLineFF fastrestore=yes|no If yes, resets viewwindow to NO prior to restoring a gif file, and bypasses the warning when restoring a gif in a video mode other than the one in which the gif was saved. Default is no. Feature will be useful when cycling through a group of gifs in autokey mode. virtual=yes|no If no, disables the check for and the ability to use virtual screen sizes. Default is yes. ~FF {Printer Parameters} printer=type[/res[/lpt#[/-1]]] Set the printer type, dots/inch, and port# types: IBM, EPSON, CO (Star Micronix), HP (LaserJet), PA (Paintjet), PS (PostScript portrait), PSL (landscape) port# 1-3 LPTn, 11-14 COMn, 21-22 direct parallel, 31-32 direct serial linefeed=crlf|lf|cr Control characters to emit at end of each line title=yes Print a title with the output printfile=\\filename Print to specified file epsf=1|2|3|... Forces print to file; default filename fract001.eps, forces PostScript mode translate=yes|nnn PostScript only; yes prints negative image; >0 reduces image colors; <0 color reduce+negative halftone=frq/angl/styl PostScript: defines halftone screen halftone=r/g/b PaintJet: contrast adjustment comport=port/baud/opts COM port initialization. Port=1,2,3,etc. baud=115,150,300,600,1200,2400,4800,9600 options 7,8 | 1,2 | e,n,o (any order) Example: comport=1/9600/n71 colorps=yes|no Enable or Disable the color postscript extensions rleps=yes|no Enable or Disable the postscript rle encoding ~FF {3D Parameters} 3d=yes|overlay Resets 3D to defaults, starts 3D mode. If overlay specified, does not clear existing graphics screen preview=yes Turns on 3D 'preview' default mode showbox=yes Turns on 3D 'showbox' default mode sphere=yes Turns on 3D sphere mode coarse=nnn Sets Preview 'coarseness' default value stereo=nnn Sets Stereo (R/B 3D) option: 0 = none, 1 = alternate, 2 = superimpose, 3 = photo, 4 = stereo pair ray=nnn selects raytrace output file format brief=yes selects brief or verbose file for DKB output usegrayscale=yes use grayscale as depth instead of color number interocular=nnn Sets 3D Interocular distance default value converge=nnn Sets 3D Convergence default value crop=nnn/nnn/nnn/nnn Sets 3D red-left, red-right, blue-left, and blue-right cropping default valuess bright=nnn/nnn Sets 3D red and blue brightness defaults, longitude=nn/nn Longitude minumim and maximum latitude=nn/nn Latitude minimum and maximum radius=nn Radius scale factor rotation=nn[/nn[/nn]] Rotation abount x,y, and z axes scalexyz=nn/nn/nn X, Y, and Z scale factors roughness=nn Same as Z scale factor waterline=nn Colors this number and below will be 'inside' color filltype=nn 3D filltype perspective=nn Perspective viewer distance (100 is at the edge) xyshift=nn/nn Shift image in x & y directions (alters viewpoint) lightsource=nn/nn/nn The coordinates of the light source vector smoothing=nn Smooths rough images in light source mode transparent=mm/nn Sets colors 'mm' to 'nn as transparent xyadjust=nnn/nnn Sets 3D X and Y adjustment defaults, randomize=nnn smoothes 3d color transitions between elevations fullcolor=yes allows creation of full color .TGA image with light source fill types ambient=nnn sets depth of shadows and contrast when using light source fill types haze=nnn sets haze for distant objects if fullcolor=1 background=nn/nn/nn sets the TGA background color as rr/gg/bb lightname=filename fullcolor output file name, default FRACT001.TGA monitorwidth=nnn monitor width in inches (for RDS only so far) ; ; ~Topic=Introduction to Parameters Fractint accepts command-line parameters that allow you to start it with a particular video mode, fractal type, starting coordinates, and just about every other parameter and option. These parameters can also be specified in a SSTOOLS.INI file, to set them every time you run Fractint. They can also be specified as named groups in a .PAR (parameter) file which you can then call up while running Fractint by using the <@> command. In all three cases (DOS command line, SSTOOLS.INI, and parameter file) the parameters use the same syntax, usually a series of keyword=value commands like SOUND=OFF. Each parameter is described in detail in subsequent sections. ; ; ~Topic=Using the DOS Command Line You can specify parameters when you start Fractint from DOS by using a command like: FRACTINT SOUND=OFF FILENAME=MYIMAGE.GIF The individual parameters are separated by one or more spaces (an parameter itself may not include spaces). Upper or lower case may be used, and parameters can be in any order. Since DOS commands are limited to 128 characters, Fractint has a special command you can use when you have a lot of startup parameters (or have a set of parameters you use frequently): FRACTINT @MYFILE When @filename is specified on the command line, Fractint reads parameters from the specified file as if they were keyed on the command line. You can create the file with a text editor, putting one "keyword=value" parameter on each line. ; ; ~Topic=Setting Defaults (SSTOOLS.INI File) Every time Fractint runs, it searches the current directory, and then the directories in your DOS PATH, for a file named SSTOOLS.INI. If it finds this file, it begins by reading parameters from it. This file is useful for setting parameters you always want, such as those defining your printer setup. SSTOOLS.INI is divided into sections belonging to particular programs. Each section begins with a label in brackets. Fractint looks for the label [fractint], and ignores any lines it finds in the file belonging to any other label. If an SSTOOLS.INI file looks like this: [fractint]\ sound=off ; (for home use only)\ printer=hp ; my printer is a LaserJet\ inside=0 ; using "traditional" black\ [startrek]\ warp=9.5 ; Captain, I dinna think the engines can take it!\ Fractint will use only the second, third, and fourth lines of the file. (Why use a convention like that when Fractint is the only program you know of that uses an SSTOOLS.INI file? Because there are other programs (such as Lee Crocker's PICLAB) that now use the same file, and there may one day be other, sister programs to Fractint using that file.) ; ; ~Topic=Parameter Files and the <@> Command You can change parameters on-the-fly while running Fractint by using the <@> or <2> command and a parameter file. Parameter files contain named groups of parameters, looking something like this: quickdraw \{ ; a set of parameters named quickdraw\ maxiter=150\ float=no\ }\ slowdraw \{ ; another set of parameters\ maxiter=2000\ float=yes\ }\ If you use the <@> or <2> command and select a parameter file containing the above example, Fractint will show two choices: quickdraw and slowdraw. You move the cursor to highlight one of the choices and press to set the parameters specified in the file by that choice. The default parameter file name is FRACTINT.PAR. A different file can be selected with the "parmfile=" option, or by using <@> or <2> and then hitting . You can create parameter files with a text editor, or for some uses, by using the command. Parameter files can be used in a number of ways, some examples: o To save the parameters for a favorite image. Fractint can do this for you with the command. o To save favorite sets of 3D transformation parameters. Fractint can do this for you with the command. o To set up different sets of parameters you use occasionally. For instance, if you have two printers, you might want to set up a group of parameters describing each. o To save image parameters for later use in batch mode - see {Batch Mode}. Formulas, ifs, and lsystem entries referred to in a parameter entry can\ be included in a .par file by adding the prefix frm:, ifs:, or lsys:\ respectively, for example frm:myformula \{rest of that formula}.\ Note that the prefix is a label, not part of the formula name, so the\ reference in the image entry would be formulaname=myformula. The\ formula, ifs, and lsystem entries added to a parfile are accessed only\ when the image entry in the parfile is run. To make these formulas generally\ accessible, they must be added to a .frm, .ifs or .l file (without the\ identifier prefix, of course). See {"Parameter Save/Restore Commands"} for details about the <@> and commands. ; ; ~Topic=General Parameter Syntax Parameters must be separated by one or more spaces. Upper and lower case can be used in keywords and values. Anything on a line following a ; (semi-colon) is ignored, i.e. is a comment. In parameter files and SSTOOLS.INI:\ o Individual parameters can be entered on separate lines.\ o Long values can be split onto multiple lines by ending a line with a \\ (backslash) - leading spaces on the following line are ignored, the information on the next line from the first non-blank character onward is appended to the prior line. Some terminology:\ KEYWORD=nnn enter a number in place of "nnn"\ KEYWORD=[filename] you supply filename\ KEYWORD=yes|no|whatever choose one of "yes", "no", or "whatever"\ KEYWORD=1st[/2nd[/3rd]] the slash-separated parameters "2nd" and "3rd" are optional ; ; ~Topic=Startup Parameters @FILENAME\ Causes Fractint to read "filename" for parameters. When it finishes, it resumes reading its own command line -- i.e., "FRACTINT MAXITER=250 @MYFILE PASSES=1" is legal. This option is only valid on the DOS command line, as Fractint is not clever enough to deal with multiple indirection. @FILENAME/GROUPNAME\ Like @FILENAME, but reads a named group of parameters from a parameter file. See {"Parameter Files and the <@> Command"}. TEMPDIR=[directory]\ This command allows to specify the directory where Fractint writes temporary files. WORKDIR=[directory]\ This command sets the directory where miscellaneous Fractint files get written, including MAKEMIG.BAT and debugging files. ~ONLINEFF FILENAME=[name]\ Causes Fractint to read the named file, which must either have been saved from an earlier Fractint session or be a generic GIF file, and use that as the starting point, bypassing the initial information screens. The filetype is optional and defaults to .GIF. Non-Fractint GIF files are restored as fractal type "plasma".\ On the DOS command line you may omit FILENAME= and just give the file name. CURDIR=yes\ Fractint uses directories set by various commands, possibly in the SSTOOLS.INI file. If you want to try out some files in the current directory, such as a modified copy of FRACTINT.FRM, you won't Fractint to read the copy in your official FRM directory. Setting curdir=yes at the command line will cause Fractint to look in the current directory for requested files first before looking in the default directory set by the other commands. Warning: screen may not reflect actual file opened in cases where the file was opened in the DOS current directory. ~ONLINEFF MAKEPAR=parfile/entryname\ This command invokes a batch facility to copy fractal and color information stored in GIF files to PAR format. The syntax is:\ fractint filename.gif makepar=parfile.par/entryname >> makepar.log\ The entryname is optional and defaults to the name of the gif filename if absent. Other parameters can appear before the makepar= command, but anything after will ignored. If the parfile and entryname exist, the entry will replace the previous entry. If the entry doesn't exist, it will be added. If the parfile doesn't exist it will be created. Redirection of output to a log file is possible in the DOS version because all screen output is written to the standard output. If you leave the GIF filename out of the command lime but add a map= command, then the makepar command will write a PAR named for the color map with only the colors in the PAR entry. This is a handy tool for converting maps into compressed PAR colors entry. For example, you could type:\ fractint map=lyapunov.map makepar=mycolors >> makepar.log\ This adds a colors-only PAR entry called lyapunov.map to mycolors.par. MAXLINELENGTH=nnn\ This command sets the maximum width of lines in a PAR entry. ~ONLINEFF ~Label=@COMMENTS COMMENT=[comment1]/[comment2]/[comment3]/[comment4]\ Inserts comments into PAR files. These comments can include variables that are expanded at the time the PAR file is created. Variables are indicated by $varname$. Underscore characters are expanded to blanks. If you want to include the special characters '$', '_', or '\\' in a comment, precede the character with '\\'. Supported variables are:\ Variable Expands to Example Variable Expands to Example =============================== ===============================\ $year$ time:year 1996 $date$ mo. day, yr Aug 17, 1996\ $month$ time:month Aug $calctime$ h:m:s 4:34:45.3\ $day$ time:day 12 $version$ version 1940\ $hour$ time:hour 21 $patch$ patch number 2\ $min$ time:minute 34 $xdots$ horiz rez 640\ $sec$ time:sec 14 $ydots$ vertical rez 480\ $time$ time:h:m:s 21:34:14 $vidkey$ video key SF4\ You can leave any of the four comment fields unchanged by leaving that position blank. For example, the command comment=//Created_$date$ inserts the text "Created Aug 17, 1996" into the third comment. BATCH=yes\ See {Batch Mode}. AUTOKEY=play|record\ Specifying "play" runs Fractint in playback mode - keystrokes are read from the autokey file (see next parameter) and interpreted as if they're being entered from the keyboard.\ Specifying "record" runs in recording mode - all keystrokes are recorded in the autokey file.\ See also {Autokey Mode}. AUTOKEYNAME=[filename]\ Specifies the file name to be used in autokey mode. The default file name is AUTO.KEY. MAKEDOC[=filename]\ Create Fractint documentation file (for printing or viewing with a text editor) and then return to DOS. Filename defaults to FRACTINT.DOC. There's also a function in Fractint's online help which can be used to produce the documentation file - ~Doc- see {Printing Fractint Documentation}. ~Doc+,Online- use "Printing Fractint Documentation" from the main help index. ~Online+ MAXHISTORY=\ Fractint maintains a list of parameters of the past 10 images that you generated in the current Fractint session. You can revisit these images using the and commands. The maxhistory command allows you to set the number of image parameter sets stored in memory. The tradeoff is between the convenience of storing more images and memory use. Each image in the circular history buffer takes up over 1200 bytes, so the default value of ten images uses up 12,000 bytes of memory. If your memory is very tight, and some memory-intensive Fractint operations are giving "out of memory" messages, you can reduce maxistory to 2 or even zero. Keep in mind that every time you color cycle or change from integer to float or back, another image parameter set is saved, so the default ten images are used up quickly. FPU=387\ This parameter is useful if you have an unusual coprocessor chip. If you have a 80287 replacement chip with full 80387 functionality use "FPU=387" to inform Fractint to take advantage of those extra 387 instructions. ; ; ~Topic=Calculation Mode Parameters PASSES=1|2|3|g|g1|g2|g3|g4|g5|g6|b|t|s|o\ Selects single-pass, dual-pass, triple-pass, solid-Guessing mode, solid-Guessing stop after pass n, Boundary Tracing, Tesseral, Synchronous Orbits, or the Orbits algorithm. See {Drawing Method} and {Passes Parameters}. FILLCOLOR=normal|\ Sets a color to be used for block fill by Boundary Tracing and Tesseral algorithms. See {Drawing Method}. FLOAT=yes\ Most fractal types have both a fast integer math and a floating point version. The faster, but possibly less accurate, integer version is the default. The default is to use integer math, but in this age of pentium (amd later) CPUS we now recommend your making float=yes the default by adding this line to your SSTOOLS.INI file. Also see {"Limitations of Integer Math (And How We Cope)"}. SYMMETRY=xxx\ Forces symmetry to None, Xaxis, Yaxis, XYaxis, Origin, or Pi symmetry. Useful as a speedup for symmetrical fractals. This is not a kaleidoscope feature for imposing symmetry where it doesn't exist. Use only when the fractal actual exhibits the symmetry, or else results may not be satisfactory. BFDIGITS=\ Forces nnn digits if arbitrary precision used. You can use this if fractint's precision detection changes to arbitrary precision too late and regular double precision is used with poor results. MATHTOLERANCE=/\ This commands controls the logic that automatically selects one of integer/float/arbitrary precision based on precision requirements of the current zoom depth. The first number controls the integer/float transition, and the second number controls the float/arbitrary precision transition. The default value of .05 for both means that the ratio between the exact and calculated width and height is between .95 and 1.05. A larger value than .05 (say .10) makes the test looser so that the lower precision math is used longer. A value <= 0 means the test is always failed and the higher precision math type is used. A value >= 1 means that the test is always passed and the lower precision math type is used. MINSTACK=\ This sets the minimum number of stack bytes required for passes=s in order to do another SOI recursion. If you get bad results, try setting this to a value above the default value of 1100. If the value is too large, the image will be OK but generation will be slower. ; ; ~Topic=Fractal Type Parameters TYPE=[name]\ Selects the fractal type to calculate. The default is type "mandel". PARAMS=n/n/n/n...\ Set optional (required, for some fractal types) values used in the calculations. These numbers typically represent the real and imaginary portions of some startup value, and are described in detail as needed in {Fractal Types}.\ (Example: FRACTINT TYPE=julia PARAMS=-0.48/0.626 would wait at the opening screen for you to select a video mode, but then proceed straight to the Julia set for the stated x (real) and y (imaginary) coordinates.) FUNCTION=[fn1[/fn2[/fn3[/fn4]]]]\ Allows setting variable functions found in some fractal type formulae. Possible values are sin, cos, tan, cotan, sinh, cosh, tanh, cotanh, exp, log, sqr, recip (i.e. 1/z), ident (i.e. identity), cosxx (cos with a pre version 16 bug), flip, zero, one, asin, asinh, acos, acosh, atan, atanh, sqrt, abs (abs(x)+i*abs(y)), cabs (sqrt(x*x+y*y)). New additions are the various rounding-to-integer functions: floor (round down), ceil (round up), trunc (round toward zero), and round (round to nearest). FORMULANAME=[formulaname]\ Specifies the default formula name for type=formula fractals. (I.e. the name of a formula defined in the FORMULAFILE.) Required if you want to generate one of these fractal types in batch mode, as this is the only way to specify a formula name in that case. LNAME=[lsystemname]\ Specifies the default L-System name. (I.e. the name of an entry in the LFILE.) Required if you want to generate one of these fractal types in batch mode, as this is the only way to specify an L-System name in that case. IFS=[ifsname]\ Specifies the default IFS name. (I.e. the name of an entry in the IFSFILE.) Required if you want to generate one of these fractal types in batch mode, as this is the only way to specify an IFS name in that case. ; ; ~Topic=Image Calculation Parameters MAXITER=nnn\ Reset the iteration maximum (the number of iterations at which the program gives up and says 'OK, this point seems to be part of the set in question and should be colored [insidecolor]') from the default 150. Values range from 2 to 2,147,483,647 (super-high iteration limits like 200000000 are useful when using logarithmic palettes). See {The Mandelbrot Set} for a description of the iteration method of calculating fractals.\ "maxiter=" can also be used to adjust the number of orbits plotted for 3D "attractor" fractal types such as lorenz3d and kamtorus. CORNERS=[xmin/xmax/ymin/ymax[/x3rd/y3rd]]\ Example: corners=-0.739/-0.736/0.288/0.291\ Begin with these coordinates as the range of x and y coordinates, rather than the default values of (for type=mandel) -2.0/2.0/-1.5/1.5. When you specify four values (the usual case), this defines a rectangle: x- coordinates are mapped to the screen, left to right, from xmin to xmax, y- coordinates are mapped to the screen, bottom to top, from ymin to ymax. Six parameters can be used to describe any rotated or stretched parallelogram: (xmin,ymax) are the coordinates used for the top-left corner of the screen, (xmax,ymin) for the bottom-right corner, and (x3rd,y3rd) for the bottom-left. Entering just "CORNERS=" tells Fractint to use this form rather than CENTER-MAG (see below) when saving parameters with the command. ~Label=@CENTERMAG CENTER-MAG=[Xctr/Yctr/Mag[/Xmagfactor/Rotation/Skew]]\ This is an alternative way to enter corners as a center point and a magnification that is popular with some fractal programs and publications. Entering just "CENTER-MAG=" tells Fractint to use this form (the default mode) rather than CORNERS (see above) when saving parameters with the command. The status display shows the "corners" in both forms. When you specify three values (the usual case), this defines a rectangle: (Xctr, Yctr) specifies the coordinates of the center of the image while Mag indicates the amount of magnification to use. Six parameters can be used to describe any rotated or stretched parallelogram: Xmagfactor tells how many times bigger the x-magnification is than the y-magnification, Rotation indicates how many degrees the image has been turned, and Skew tells how many degrees the image is leaning over. Positive angles will rotate and skew the image counter-clockwise. BAILOUT=nnn\ Over-rides the default bailout criterion for escape-time fractals. Can also be set from the parameters screen after selecting a fractal type. See description of bailout in {The Mandelbrot Set}. BAILOUTEST=mod|real|imag|or|and|manh|manr\ Specifies the {Bailout Test} used to determine when the fractal calculation has exceeded the bailout value. The default is mod and not all fractal types can utilize the additional tests. RESET\ Causes Fractint to reset all calculation related parameters to their default values. Non-calculation parameters such as "printer=", "sound=", and "savename=" are not affected. RESET should be specified at the start of each parameter file entry (used with the <@> command) which defines an image, so that the entry need not describe every possible parameter - when invoked, all parameters not specifically set by the entry will have predictable values (the defaults). INITORBIT=pixel\ INITORBIT=nnn/nnn\ Allows control over the value used to begin each Mandelbrot-type orbit. "initorbit=pixel" is the default for most types; this command initializes the orbit to the complex number corresponding to the screen pixel. The command "initorbit=nnn/nnn" uses the entered value as the initializer. See the discussion of the {Mandellambda Sets} for more on this topic. RSEED=nnnn\ The initial random-number "seed" for plasma clouds is taken from your PC's internal clock-timer. This argument forces a value (which you can see in the display), and allows you to reproduce plasma clouds. A detailed discussion of why a TRULY random number may be impossible to define, let alone generate, will have to wait for "FRACTINT: The 3-MB Doc File." SHOWDOT=[auto|bright|medium|dark|[/]]\ Colors the current dot being calculated color or an automatically calculated color taken from the current palette. The second parameter is the size of the traveling pointer in units of pixels of 1/1024th of a screen. The travelling pointer strobes with fast fractals because of interaction with the monitor's vertical refresh. The orbitdelay parameter can be used to introduce a per-pixel delay when showdot is turned on. Try orbitdelay=1000 with showdot=b/20 to get a feel for how the showdot triangle works. ASPECTDRIFT=\ When zooming in or out, the aspect ratio (the width to height ratio) can change slightly due to rounding and the noncontinuous nature of pixels. If the aspect changes by a factor less than , then the aspect is set to it's normal value, making the center-mag Xmagfactor parameter equal to 1. (see CENTER-MAG above.) The default is 0.01. A larger value adjusts more often. A value of 0 does no adjustment at all. ; ; ~Topic=Passes Parameters PERIODICITY=no|show|nnn\ Controls periodicity checking (see {Periodicity Logic}). "no" turns it off, "show" lets you see which pixels were painted as "inside" due to being caught by periodicity. Specifying a number causes a more conservative periodicity test (each increase of 1 divides test tolerance by 2). Entering a negative number lets you turn on "show" with that number. Type lambdafn function=exp needs periodicity turned off to be accurate -- there may be other cases. A non-zero value of the "periodicity=" option causes "passes=o" to not plot orbits that have reached the bailout conditions or where an orbit goes off the visible area of the image. A zero value of periodicity will plot all orbits except as modified by orbitdelay and orbitinterval. ORBITDELAY=\ This option controls how many orbits are computed before the orbits are displayed on the screen when using the "passes=o" option, or the fractal types mandelcloud and dynamic. This allows the orbits to settle down before plotting starts. This option also slows down the display of orbits using the command for folks with hot new computers. Units are in 1/10000 seconds per orbit point. ORBITDELAY=10 therefore allows you to see each pixel's orbit point for about one millisecond. For best display of orbits, try passes=1 and a moderate resolution such as 320x200. Note that the first time you press the 'O' key with the 'orbitdelay' function active, your computer will pause for a half-second or so to calibrate a high-resolution timer. ORBITINTERVAL=\ This parameter causes "passes=o" to plot every nth orbit point ranging from 1, which plots every orbit, to 255, which plots every 255th orbit. This value must be lower than the value of maxit to make any sense. SCREENCOORDS=yes|no\ This parameter maintains the screen coordinates and lets you zoom into an image changing the coordinates of the line or rectangle used to generate the image, but keeps the display coordinates the same. The screen coordinates can be zoomed, rotated, and skewed using the {Screen Coordinates Screen}. If set to no, the screen and image coordinates are maintained the same when an image is zoomed. ~ONLINEFF ORBITDRAWMODE=rect|line\ The rect(angle) method plots the orbits in a rectangle that can be zoomed, rotated, and skewed using the {Image Coordinates Screen}, and the straight line method plots the orbits between two points specified on the image coordinates screen. ; ; ~Topic=Color Parameters INSIDE=nnn|maxiter|bof60|bof61|zmag|epscross|startrail|period|atan|fmod\ Set the color of the interior: for example, "inside=0" makes the M-set "lake" a stylish basic black. A setting of inside=maxiter makes the inside color the same as the value of maxiter. Eight more options reveal hidden structure inside the lake. Inside=bof60 and inside=bof61, are named after the figures on pages 60 and 61 of "Beauty of Fractals". Inside=zmag is a method of coloring based on the magnitude of Z after the maximum iterations have been reached. The affect along the edges of the Mandelbrot is like thin-metal welded sculpture. Inside=fmod is a method of coloring based on the magnitude of the last orbit within a set distance from the origin. Inside=period colors pixels according to the period of their eventual orbit. Inside=atan colors by determining the angle in degrees the last iterated value has with respect to the real axis, and using the absolute value. See {Inside=bof60|bof61|zmag|fmod|period|atan} for a brilliant explanation of what these do! Inside=epscross colors pixels green or yellow according to whether their orbits swing close to the Y-axis or X-axis, respectively. Inside=startrail has a coloring scheme based on clusters of points in the orbits. Best with outside=. For more information, see {Inside=epscross|startrail}. Note that the "Look for finite attractor" option on the options screen will override the selected inside option if an attractor is found - see {Finite Attractors}. OUTSIDE=nnn|iter|real|imag|summ|mult|atan|fmod|tdis\ The classic method of coloring outside the fractal is to color according to how many iterations were required before Z reached the bailout value, usually 4. This is the method used when OUTSIDE=iter. However, when Z reaches bailout the real and imaginary components can be at very diferent values. OUTSIDE=real and OUTSIDE=imag color using the iteration value plus the real or imaginary values. OUTSIDE=summ uses the sum of all these values. These options can give a startling 3d quality to otherwise flat images and can change some boring images to wonderful ones. OUTSIDE=mult colors by multiplying the iteration by real divided by imaginary. There was no mathematical reason for this, it just seemed like a good idea. OUTSIDE=atan colors by determining the angle in degrees the last iterated value has with respect to the real axis, and using the absolute value. OUTSIDE=fmod colors pixels according to the magnitude of the last orbit point which is within a set distance from the origin. Then:\ color = magnitude * colors / closeprox\ The magnitude used for the comparison is now based on the same calculation as is used for the bailout test. The value of closeprox can be varied interactively. This feature was contributed by Iain Stirling. There is a problem with the mandel fractal type when outside=fmod is used with inside=bof6x and bailoutest=real, imag, or manr. This is likely due to changes made in the code so that bof images could be reproduced. Select a different fractal type that produces the default mandel image to explore using these parameters. OUTSIDE=tdis colors the pixels according to the total distance traveled by the orbit. This feature was suggested by Steve Robinson. Outside=nnn sets the color of the exterior to some number of your choosing: for example, "OUTSIDE=1" makes all points not INSIDE the fractal set to color 1 (blue). Note that defining an OUTSIDE color forces any image to be a two-color one: either a point is INSIDE the set, or it's OUTSIDE it. MAP=[filename]\ Reads in a replacement color map from [filename]. This map replaces the default color map of your video adapter. Requires a VGA or higher adapter. The difference between this argument and an alternate map read in via in color- command mode is that this one applies to the entire run. See {Palette Maps}. COLORS=@filename|colorspecification\ Sets colors for the current image, like the function in color cycling and palette editing modes. Unlike the MAP= parameter, colors set with COLORS= do not replace the default - when you next select a new fractal type, colors will revert to their defaults.\ COLORS=@filename tells Fractint to use a color map file named "filename". See {Palette Maps}.\ COLORS=colorspecification specifies the colors directly. The value of "colorspecification" is rather long (768 characters for 256 color modes), and its syntax is not documented here. This form of the COLORS= command is not intended for manual use - it exists for use by the command when saving the description of a nice image. ~Label=@RECORDCOLORS RECORDCOLORS=auto|comment|yes\ Controls the method of writing colors in PAR files. Auto causes the colors to be written in the colors=@mapfile form if the colors were loaded from a map. Use this mode if you manage your colors using map files. If you share PAR files with others, and have trouble remembering to send them the map file, use RECORDCOLORS=comment or yes. These modes force the writing of compressed color maps in the PAR file in all cases. The only difference is that the 'comment' option also writes the mapfile name in a comment so you can remember where the colors came from. ~Doc- See {Color Specification}. ~Doc+ CYCLERANGE=nnn/nnn\ Sets the range of color numbers to be animated during color cycling. The default is 1/255, i.e. just color number 0 (usually black) is not cycled. CYCLELIMIT=nnn\ Sets the speed of color cycling. Technically, the number of DAC registers updated during a single vertical refresh cycle. Legal values are 1 - 256, default is 55. TEXTCOLORS=mono\ Set text screen colors to simple black and white. TEXTCOLORS=aa/bb/cc/...\ Set text screen colors. Omit any value to use the default (e.g. textcolors=////50 to set just the 5th value). Each value is a 2 digit hexadecimal value; 1st digit is background color (from 0 to 7), 2nd digit is foreground color (from 0 to F).\ ~Format- Color values are: 0 black 8 gray 1 blue 9 light blue 2 green A light green 3 cyan B light cyan 4 red C light red 5 magenta D light magenta 6 brown E yellow 7 white F bright white 31 colors can be specified, their meanings are as follows: heading: 1 Fractint version info 2 heading line development info (not used in released version) help: 3 sub-heading 4 main text 5 instructions at bottom of screen 6 hotlink field 7 highlighted (current) hotlink menu, selection boxes, parameter input boxes: 8 background around box and instructions at bottom 9 emphasized text outside box 10 low intensity information in box 11 medium intensity information in box 12 high intensity information in box (e.g. heading) 13 current keyin field 14 current keyin field when it is limited to one of n values 15 current choice in multiple choice list 16 speed key prompt in multiple choice list 17 speed key keyin in multiple choice list general (tab key display, IFS parameters, "thinking" display): 18 high intensity information 19 medium intensity information 20 low intensity information 21 current keyin field disk video: 22 background around box 23 high intensity information 24 low intensity information diagnostic messages: 25 error 26 information credits screen: 27 bottom lines 28 high intensity divider line 29 low intensity divider line 30 primary authors 31 contributing authors The default is textcolors=1F/1A/2E/70/28/71/31/78/70/17/1F/1E/2F/3F/5F/07/ 0D/71/70/78/0F/70/0E/0F/4F/20/17/20/28/0F/07 (In a real command file, all values must be on one line.) ~Format+ OLDDEMMCOLORS=yes|no\ Sets the coloring scheme used with the distance estimator method to the pre-version 16 scheme. TRUECOLOR=yes\ You can save either the default color scheme or the iteration escape value to a file called FRACTxxx.TGA. This will allow experimentation with truecolor algorithms. A C language source file that reads the file when iterates are used, is provided. Someday we'll have REAL truecolor support ... TRUEMODE=def|iter\ Determines whether the FRACTxxx.TGA file produced when TRUECOLOR=yes contains the iteration value or the default coloring scheme. NOBOF=yes|no\ Setting this parameter to yes causes the bof60 and bof61 inside options to function the same as the other inside options by making the per pixel initialization the same. The per pixel initialization is normally different for the bof60 and bof61 options to reproduce the images in the book, "The Beauty of Fractals". The default is no. ; ; ~Topic=Color Specification ~Format-,Online- COLOR SPECIFICATION ~Format+,Online+ The colors= parameter in a PAR entry is a set of triplets. Each triplet represents a color in the saved palette. The triplet is made from the red green and blue components of the color in the palette entry. The current limitations of fractint's palette handling capabilities restrict the palette to 256 colors. Each triplet rgb component is a 6 bit value from 0 to 63. These values are encoded using the following scheme:\ rgb value => encoded value\ 0 - 9 => 0 - 9\ 10 - 35 => A - Z\ 36 - 37 => _ - `\ 38 - 63 => a - z\ In addition, Pieter Branderhorst has incorporated a way to compress the encoding when the image has smooth-shaded ranges. These ranges are written as with the nn representing the number of entries between the preceeding triplet and the following triplet. The routine for finding the smooth-shaded range works something like this. The current triplet's color values are compared to the current-1 triplet's color values. The difference is saved and then the current triplet's color values are compared to the current-2 triplet's color values. The difference is saved and then this difference is compared to the first one. If the differences are the same, a shaded range has been found. If the differences are off by one, this is saved as the one exceptable alternative difference. Up to four previous triplets will be looked at for the current triplet. If the color "slope" of the range is not sharp, meaning the colors change slowly, the current range is broken into more ranges to stop "drift" when loading and storing the PAR. ; ; ~Topic=Doodad Parameters LOGMAP=yes|old|n\ Selects a compressed relationship between escape-time iterations and palette colors. See {"Logarithmic Palettes and Color Ranges"} for details. LOGMODE=fly/table|auto\ Forces the use of the on-the-fly routine or the logarithm table for the calculation of log palettes. Not normally needed. The auto option cannot be used at the same time as the other two. Auto causes the logmap value to be automatically recalculated when zooming. Changing almost anything will turn this feature off. Set logmode=auto from the screen prompt. RANGES=nn/nn/nn/...\ Specifies ranges of escape-time iteration counts to be mapped to each color number. See {"Logarithmic Palettes and Color Ranges"} for details. DISTEST=nnn/nnn\ A nonzero value in the first parameter enables the distance estimator method. The second parameter specifies the "width factor", defaults to 71. See {"Distance Estimator Method"} for details. DECOMP=2|4|8|16|32|64|128|256\ Invokes the corresponding decomposition coloring scheme. See {Decomposition} for details. BIOMORPH=nnn\ Turn on biomorph option; set affected pixels to color nnn. See {Biomorphs} for details. POTENTIAL=maxcolor[/slope[/modulus[/16bit]]]\ Enables the "continuous potential" coloring mode for all fractal types except plasma clouds, attractor types such as lorenz, and IFS. The four arguments define the maximum color value, the slope of the potential curve, the modulus "bailout" value, and whether 16 bit values are to be calculated. Example: "POTENTIAL=240/2000/40/16bit". The Mandelbrot and Julia types ignore the modulus bailout value and use their own hardwired value of 4.0 instead. See {Continuous Potential} for details. INVERT=nn/nn/nn\ Turns on inversion. The parameters are radius of inversion, x-coordinate of center, and y-coordinate of center. -1 as the first parameter sets the radius to 1/6 the smaller screen dimension; no x/y parameters defaults to center of screen. The values are displayed with the command. See {Inversion} for details. FINATTRACT=no|yes\ Another option to show coloring inside some Julia "lakes" to show escape time to finite attractors. Works with lambda, magnet types, and possibly others. See {Finite Attractors} for more information. EXITNOASK=yes\ This option forces Fractint to bypass the final "are you sure?" exit screen when the ESCAPE key is pressed from the main image-generation screen. Added at the request of Ward Christensen. It's his funeral . ; ; ~Topic=File Parameters In Fractint you can use various filename variables to specify files, set default directories, or both. For example, in the SAVENAME description below, [name] can be a filename, a directory name, or a fully qualified pathname plus filename. You can specify default directories using these variables in your SSTOOLS.INI file. SAVENAME=[\\][name]\ Set the path and/or filename to use when you ave a screen. The default filename is FRACT001. The .GIF extension is optional (Example: SAVENAME=myfile) FILENAME=[.suffix]\ Sets the default file extension used for the command. When this parameter is omitted, the default file mask shows .GIF and .POT files. You might want to specify this parameter and the SAVENAME= parameter in your SSTOOLS.INI file if you keep your fractal images separate from other .GIF files by using a different suffix for them. FORMULAFILE=[\\][formulafilename]\ Specifies the formula path and/or file for type=formula fractals (default is FRACTINT.FRM). Handy if you want to generate one of these fractal types in batch mode. ~ONLINEFF IFSFILE=[\\][ifsfilename]\ Specifies the default path and/or file for type=ifs fractals (default is FRACTINT.IFS). LFILE=[\\][lsystemfile]\ Specifies the default L-System path and/or file for type=lsystem fractals (default is FRACTINT.L). MAP=[filename]\ Reads in a replacement color map from [filename]. This map replaces the default color map of your video adapter. Requires a VGA or higher adapter. The difference between this argument and an alternate map read in via in color- command mode is that this one applies to the entire run. See {Palette Maps}. ORGFRMDIR=[]\ When used, Fractint's search for formulas will make a final check of the appropriate Orgform compilation file ( see { Other Fractal Products }) in the specified directory (e.g. for a formula with the name "abc", the only file searched in the specified directory will be _a.frm). This feature will significantly reduce the time taken to find a formula for users of the Orgform compilation. ~ONLINEFF PARMFILE=[\\][parmfilename]\ Specifies the default parameter path and/or file to be used by the <@> (or <2>) and commands. If not specified, the default is FRACTINT.PAR. OVERWRITE=no|yes\ Sets the savename overwrite flag (default is 'no'). If 'yes', saved files will over-write existing files from previous sessions; otherwise the automatic incrementing of FRACTnnn.GIF will find the first unused filename. SAVETIME=nnn\ Tells Fractint to automatically do a save every nnn minutes while a calculation is in progress. This is mainly useful with long batches - see {Batch Mode}. GIF87a=yes\ Backward-compatibility switch to force creation of GIF files in the GIF87a format. As of version 14, Fractint defaults to the new GIF89a format which permits storage of fractal information within the format. GIF87a=YES is only needed if you wish to view Fractint images with a GIF decoder that cannot accept the newer format. See {GIF Save File Format}. ~ONLINEFF DITHER=yes\ Dither a color file into two colors for display on a b/w display. This give a poor-quality display of gray levels. Note that if you have a 2-color display, you can create a 256-color gif with disk video and then read it back in dithered. ORBITSAVE=yes\ Causes the file ORBITS.RAW to be opened and the points generated by orbit fractals or IFS fractals to be saved in a raw format. This file can be read by the Acrospin program which can rotate and scale the image rapidly in response to cursor-key commands. The filename ORBITS.RAW is fixed and will be overwritten each time a new fractal is generated with this option.\ (see {Barnsley IFS Fractals} {Orbit Fractals} {=@ACROSPIN Acrospin}). ; ~Topic=Video Parameters VIDEO=xxx\ Set the initial video mode (and bypass the informational screens). Handy for batch runs. (Example: VIDEO=F4 for IBM 16-color VGA.) You can obtain the current VIDEO= values (key assignments) from the "select video mode" screens inside Fractint. If you want to do a batch run with a video mode which isn't currently assigned to a key, you'll have to modify the key assignments - see {"Video Mode Function Keys"}. ASKVIDEO=yes|no\ If "no," this eliminates the prompt asking you if a file to be restored is OK for your current video hardware.\ WARNING: every version of Fractint so far has had a bigger, better, but shuffled-around video table. Since calling for a mode your hardware doesn't support can leave your system in limbo, be careful about leaving the above two parameters in a command file to be used with future versions of Fractint, particularly for the super-VGA modes. ADAPTER=hgc|cga|ega|egamono|mcga|vga|ATI|Everex|Trident|NCR|Video7|Genoa| Paradise|Chipstech|Tseng3000|Tseng4000|AheadA|AheadB|Oaktech\ Bypasses Fractint's internal video autodetect logic and assumes that the specified kind of adapter is present. Use this parameter only if you encounter video problems without it. Specifying adapter=vga with an SVGA adapter will make its extended modes unusable with Fractint. All of the options after the "VGA" option specify specific SuperVGA chipsets which are capable of video resolutions higher than that of a "vanilla" VGA adapter. Note that Fractint cares about the Chipset your adapter uses internally, not the name of the company that sold it to you. VESADETECT=yes|no\ Specify no to bypass VESA video detection logic. Try this if you encounter video problems with a VESA compliant video adapter or driver. AFI=yes|8514|no\ Normally, when you attempt to use an 8514/A-specific video mode, Fractint first attempts to detect the presence of an 8514/A register-compatible adapter. If it fails to find one, it then attempts to detect the presence of an 8514/A-compatible API (IE, IBM's HDILOAD or its equivalent). Fractint then uses either its register-compatible or its API-compatible video logic based on the results of those tests. If you have an "8514/A-compatible" video adapter that passes Fractint's register-compatible detection logic but doesn't work correctly with Fractint's register-compatible video logic, setting "afi=yes" will force Fractint to bypass the register-compatible code and look only for the API interface. TEXTSAFE=yes|no|bios|save\ When you switch from a graphics image to text mode (e.g. when you use while a fractal is on display), Fractint remembers the graphics image, and restores it when you return from the text mode. This should be no big deal - there are a number of well-defined ways Fractint could do this which *should* work on any video adapter. They don't - every fast approach we've tried runs into a bug on one video adapter or another. So, we've implemented a fast way which works on most adapters in most modes as the default, and added this parameter for use when the default approach doesn't work.\ If you experience the following problems, please fool around with this parameter to try to fix the problem:\ o Garbled image, or lines or dashes on image, when returning to image after going to menu, display, or help.\ o Blank screen when starting Fractint.\ The problems most often occur in higher resolution modes. We have not encountered them at all in modes under 320x200x256 - for those modes Fractint always uses a fast image save/restore approach.\ Textsafe options:\ yes: This is the default. When switching to/from graphics, Fractint saves just that part of video memory which EGA/VGA adapters are supposed to modify during the mode changes. no: This forces use of monochrome 640x200x2 mode for text displays (when there is a high resolution graphics image to be saved.) This choice is fast but uses chunky and colorless characters. If it turns out to be the best choice for you, you might want to also specify "textcolors=mono" for a more consistent appearance in text screens. bios: This saves memory in the same way as textsafe=yes, but uses the adapter's BIOS routines to save/restore the graphics state. This approach is fast and ought to work on all adapters. Sadly, we've found that very few adapters implement this function perfectly. save: It should work on all adapters in all modes but it can be slow. It tells Fractint to save/restore the entire image. Expanded or extended memory is used for the save if you have enough available; otherwise a temporary disk file is used. The speed of textsafe=save will be acceptable on some machines but not others. If this method is too slow, try the other textsafe modes. The speed depends on:\ o Cpu and video adapter speed.\ o Whether enough expanded or extended memory is available.\ o Video mode of image being remembered. A few special modes are *very* slow compared to the rest. The slow ones are: 2 and 4 color modes with resolution higher than 640x480; custom modes for ATI EGA Wonder, Paradise EGA-480, STB, Compaq portable 386, AT&T 6300, and roll your own video modes implemented with customized YOURVID.C code. If you want to tune Fractint to use different "textsafe" options for different video modes, see {"Customized Video Modes\, FRACTINT.CFG"}. (E.g. you might want to use the slower textsafe=save approach just for a few high-resolution modes which have problems with textsafe=yes.) EXITMODE=nn\ Sets the bios-supported videomode to use upon exit to the specified value. nn is in hexadecimal. The default is 3, which resets to 80x25 color text mode on exit. With Hercules Graphics Cards, and with monochrome EGA systems, the exit mode is always 7 and is unaffected by this parameter. TPLUS=yes|no\ For TARGA+ adapters. Setting this to 'no' pretends a TARGA+ is NOT installed. NONINTERLACED=yes|no\ For TARGA+ adapters. Setting this to 'yes' will configure the adapter to a non-interlaced mode whenever possible. It should only be used with a multisynch monitor. The default is no, i.e. interlaced. MAXCOLORRES=8|16|24\ For TARGA+ adapters. This determines the number of bits to use for color resolution. 8 bit color is equivalent to VGA color resolution. The 16 and 24 bit color resolutions are true color video modes. PIXELZOOM=0|1|2|3\ For TARGA+ adapters. Lowers the video mode resolution by powers of 2. For example, the 320x200 video resolution on the TARGA+ is actually the 640x400 video mode with a pixel zoom of 1. Using the 640x400 video mode with a zoom of 3 would lower the resolution by 8, which is 2 raised to the 3rd power, for a full screen resolution of 80x50 pixels. VIEWWINDOWS=xx[/xx[/yes|no[/nn[/nn]]]]\ Set the reduction factor, final media aspect ratio, crop starting coordinates (y/n), explicit x size, and explicit y size, see {"View Window"}. ~Label=@FASTRESTORE FASTRESTORE=yes|no\ If YES, resets viewwindow to "no" prior to restoring a gif file. Otherwise, images saved in full view will be drawn in reduced view if viewwindows has been set to "yes" previously. Also, when YES, bypasses the warning when restoring a gif in a video mode other than the one in which the gif was saved. Default is NO. Feature will be useful when cycling through a group of gifs in autokey mode. When combined with askvideo=no, allows loading images with the last successfully used video mode. This is handy when viewing 1600x1200 images when you only have 1024x768 available. VIRTUAL=yes|no\ With a suitable video adapter it is possible to set virtual screen modes using the {"View Window"} options. With certain video adapters it may be necessary to disable the check for virtual screen modes if this check prevents Fractint from loading correctly. The default is "yes". Setting this to "no" disables the check for and the ability to use virtual screen sizes. ; ; ~Topic=Sound Parameters SOUND=off|beep|x|y|z/pc|fm/quant\ We're all MUCH too busy to waste time with Fractint at work, and no doubt you are too, so "sound=off" is included only for use at home, to avoid waking the kids or your Significant Other, late at night. (By the way, didn't you tell yourself "just one more zoom on LambdaSine" an hour ago?) Suggestions for a "boss" hot-key will be cheerfully ignored, as this sucker is getting big enough without including a spreadsheet screen too. The "sound=x|y|x" options are for the "attractor" fractals, like the Lorenz fractals - they play with the sound on your PC speaker as they are generating an image, based on the X or Y or Z co-ordinate they are displaying at the moment. The scope of the sound command has been extended. You can now hear the sound of fractal orbits--just turn on sound from the command line, the menu, or the menu, fire up a fractal, and try the rbits command (or set showorbit=yes). Use the orbitdelay= command (also on the menu) to dramatically alter the effect, which ranges from an unearthly scream to a series of discrete tones. Not recommended when people you have to live with are nearby! Remember, we don't promise that it will sound beautiful! The sound output can now be directed to the PC speaker, a sound card with OPL-3 support, or both at the same time. There is also an option to quantize the notes generated by Fractint. See {Sound Controls}. You can also "hear" any image that Fractint can decode; turn on sound before using to read in a GIF file. We have no idea if this feature is useful. It was inspired by the comments of an on-line friend who is blind. We solicit feedback and suggestions from anyone who finds these sound features interesting or useful. The orbitdelay command also affects the sound of decoding images. HERTZ=\ Adjusts the sound produced by the "sound=x|y|z" option. Limits on legal values have been removed in version 19.3. The actual sounds produced are limited to the range of 20-5000 Hz. Setting a negative Hertz value allows shifting the range of sounds produced down into the bass range. This also eliminates some of the notes since anything under 20 Hz or over 5000 Hz will not be played. ORBITDELAY=\ Slows up the display of orbits using the command for folks with hot new computers. Units are in 1/10000 seconds per orbit point. ORBITDELAY=10 therefore allows you to see each pixel's orbit point for about one millisecond. For best display of orbits, try passes=1 and a moderate resolution such as 320x200. Note that the first time you press the 'O' key with the 'orbitdelay' function active, your computer will pause for a half-second or so to calibrate a high-resolution timer. SHOWORBIT=yes|no\ Causes the during-generation orbits feature, toggled by the command, to start off in the "on" position each time a new fractal calculation starts. ORBITSAVE=sound\ This option causes the hertz value played through the PC speaker with sound=x|y|z option to be written to a file "sound.txt" in the current directory. Bill Jemison has made some intriguing music with this option. ; ; ~Topic=Printer Parameters ~Doc- General printer parameters are described below.\ Additional parameters for specific types of printers are described in:\ {PostScript Parameters}\ {PaintJet Parameters}\ {Plotter Parameters}\ ~Doc+ PRINTER=type[/resolution[/port#]]\ Defines your printer setup. The SSTOOLS.INI file is a REAL handy place to put this option, so that it's available whenever you have that sudden, irresistible urge for hard copy. ~Format- Printer types: IB IBM-compatible (default) EP Epson-compatible HP LaserJet CO Star Micronics Color printer, supposedly Epson-color-compatible PA Paintjet PS PostScript PSL Postscript, landscape mode PL Plotter using HP-GL Resolution: In dots per inch. Epson/IBM: 60, 120, 240 LaserJet: 75, 150, 300 PaintJet: 90, 180 PostScript: 10 through 600, or special value 0 to print full page to within about .4" of the edges (in portrait mode, width is full page and height is adjusted to 3:4 aspect ratio) Plotter: 1 to 10 for 1/Nth of page (e.g. 2 for 1/2 page) Port: 1, 2, 3 for LPT1-3 via BIOS 11, 12, 13, 14 for COM1-4 via BIOS 21, 22 for LPT1 or LPT2 using direct port access (faster when it works) 31, 32 for COM1 or COM2 using direct port access ~Format+ COMPORT=port/baud/options\ Serial printer port initialization.\ Port=1,2,3,etc.\ Baud=115,150,300,600,1200,2400,4800,9600\ Options: 7,8 | 1,2 | e,n,o (any order).\ Example: comport=1/9600/n81 for COM1 set to 9600, no parity, 8 bits per character, 1 stop bit. LINEFEED=crlf|lf|cr\ Specifies the control characters to emit at end of each line: carriage return and linefeed, just linefeed, or just carriage return. The default is crlf. TITLE=yes\ If specified, title information is added to printouts. PRINTFILE=[\\]filename\ Causes output data for the printer to be written to the named file on disk instead of to a printer port. The filename is incremented by 1 each time an image is printed - e.g. if the name is FRAC01.PRN, the second print operation writes to FRAC02.PRN, etc. Existing files are not overwritten - if the file exists, the filename is incremented to a new name. ; ; ~Topic=PostScript Parameters EPSF=1|2|3\ Forces print-to-file and PostScript. If PRINTFILE is not specified, the default filename is FRACT001.EPS. The number determines how 'well-behaved' a .EPS file is. 1 means by-the-book. 2 allows some EPS 'no-nos' like settransfer and setscreen - BUT includes code that should make the code still work without affecting the rest of the non-EPS document. 3 is a free-for-all. COLORPS=yes|no - Enable or disable the color extensions. RLEPS=yes|no\ Enable or disable run length encoding of the PostScript file. Run length encoding will make the PostScript file much smaller, but it may take longer to print. The run length encoding code is based on pnmtops, which is copyright (C) 1989 by Jef Poskanzer, and carries the following notice: "Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. This software is provided "as is" without express or implied warranty." TRANSLATE=yes|-n|n\ Translate=yes prints the negative image of the fractal. Translate=n reduces the image to that many colors. A negative value causes a color reduction as well as a negative image. HALFTONE=frq/ang/sty[/f/a/s/f/a/s/f/a/s]\ Tells the PostScript printer how to define its halftone screen. The first value, frequency, defines the number of halftone lines per inch. The second chooses the angle (in degrees) that the screen lies at. The third option chooses the halftone 'spot' style. Good default frequencies are between 60 and 80; Good default angles are 45 and 0; the default style is 0. If the halftone= option is not specified, Fractint will print using the printer's default halftone screen, which should have been already set to do a fine job on the printer. These are the only three used when colorps=no. When color PS printing is being used, the other nine options specify the red, green, then blue screens. A negative number in any of these places will cause it to use the previous (or default) value for that parameter. NOTE: Especially when using color, the built-in screens in the printer's ROM may be the best choice for printing. ~OnlineFF The default values are as follows: halftone=45/45/1/45/75/1/45/15/1/45/0/1 and these will be used if Fractint's halftone is chosen over the printer's built-in screen. ~Format- Current halftone styles: 0 Dot 1 Dot (Smoother) 2 Dot (Inverted) 3 Ring (Black) 4 Ring (White) 5 Triangle (Right) 6 Triangle (Isosceles) 7 Grid 8 Diamond 9 Line 10 Microwaves 11 Ellipse 12 Rounded Box 13 Custom 14 Star 15 Random 16 Line (slightly different) ~Format+ ~OnlineFF A note on device-resolution black and white printing\ ----------------------------------------------------\ This mode of printing can now be done much more quickly, and takes a lot less file space. Just set EPSF=0 PRINTER=PSx/nnn COLORPS=NO RLEPS=YES TRANSLATE=m, where x is P or L for portrait/landscape, nnn is your printer's resolution, m is 2 or -2 for positive or negative printing respectively. This combination of parameters will print exactly one printer pixel per each image pixel and it will keep the proportions of the picture, if both your screen and printer have square pixels (or the same pixel-aspect). Choose a proper (read large) window size to fill as much of the paper as possible for the most spectacular results. 2048 by 2048 is barely enough to fill the width of a letter size page with 300 dpi printer resolution. For higher resolution printers, you can use fractint's new larger disk video sizes, up to 32k x 32k. ~OnlineFF A word from the author (Scott Taylor)\ -------------------------------------\ Color PostScript printing is new to me. I don't even have a color printer to test it on. (Don't want money. Want a Color PostScript printer!) The initial tests seem to have worked. I am still testing and don't know whether or not some sort of gamma correction will be needed. I'll have to wait and see about that one. ; ; ~Topic=PaintJet Parameters Note that the pixels printed by the PaintJet are square. Thus, a printout of an image created in a video mode with a 4:3 pixel ratio (such as 640x480 or 800x600) will come out matching the screen; other modes (such as 320x200) will come out stretched. Black and white images, or images using the 8 high resolution PaintJet colors, come out very nicely. Some images using the full spectrum of PaintJet colors are very nice, some are disappointing. When 180 dots per inch is selected (in PRINTER= command), high resolution 8 color printing is done. When 90 dpi is selected, low resolution printing using the full 330 dithered color palette is done. In both cases, Fractint starts by finding the nearest color supported by the PaintJet for each color in your image. The translation is then displayed (unless the current display mode is disk video). This display *should* be a fairly good match to what will be printed - it won't be perfect most of the time but should give some idea of how the output will look. At this point you can to go ahead and print, to cancel, or to cancel and keep the adjusted colors. Note that you can use the color map PAINTJET.MAP to create images which use the 8 high resolution colors available on the PaintJet. Also, two high-resolution disk video modes are available for creating full page images. If you find that the preview image seems very wrong (doesn't match what actually gets printed) or think that Fractint could be doing a better job of picking PaintJet colors to match your image's colors, you can try playing with the following parameter. Fair warning: this is a very tricky business and you may find it a very frustrating business trying to get it right. HALFTONE=r/g/b\ (The parameter name is not appropriate - we appropriated a PostScript parameter for double duty here.)\ This separately sets the "gamma" adjustment for each of the red, green, and blue color components. Think of "gamma" as being like the contrast adjustment on your screen. Higher gamma values for all three components results in colors with more contrast being produced on the printer. Since each color component can have its gamma separately adjusted, you can change the resulting color mix subtly (or drastically!)\ Each gamma value entered has one implied decimal digit.\ The default is "halftone=21/19/16", for red 2.1, green 1.9, and blue 1.6. (A note from Pieter Branderhorst: I wrote this stuff to come out reasonably on my monitor/printer. I'm a bit suspicious of the guns on my monitor; if the colors seem ridiculously wrong on your system you might start by trying halftone=17/17/17.) ; ; ~Topic=Plotter Parameters Plotters which understand HP-GL commands are supported. To use a plotter, draw a SMALL image (32x20 or 64x40) using the iew screen options. Put a red pen in the first holder in the plotter, green in the second, blue in the third. Now press

to start plotting. Now get a cup of coffee... or two... or three. It'll take a while to plot. Experiment with different resolutions, plot areas, plotstyles, and even change pens to create weird-colored images. PLOTSTYLE=0|1|2\ 0: 3 parallel lines (red/green/blue) are drawn for each pixel, arranged like "///". Each bar is scaled according to the intensity of the corresponding color in the pixel. Using different pen colors (e.g. blue, green, violet) can come out nicely. The trick is to not tell anyone what color the bars are supposed to represent and they will accept these plotted colors because they do look nice... 1: Same as 0, but the lines are also twisted. This removes some of the 'order' of the image which is a nice effect. It also leaves more whitespace making the image much lighter, but colors such as yellow are actually visible. 2: Color lines are at the same angle and overlap each other. This type has the most whitespace. Quality improves as you increase the number of pixels squeezed into the same size on the plotter. ; ; ~Topic=3D Parameters To stay out of trouble, specify all the 3D parameters, even if you want to use what you think are the default values. It takes a little practice to learn what the default values really are. The best way to create a set of parameters is to use the command on an image you like and then use an editor to modify the resulting parameter file. 3D=Yes\ 3D=Overlay\ Resets all 3d parameters to default values. If FILENAME= is given, forces a restore to be performed in 3D mode (handy when used with 'batch=yes' for batch-mode 3D images). If specified, 3D=Yes should come before any other 3d parameters on the command line or in a parameter file entry. The form 3D=Overlay is identical except that the previous graphics screen is not cleared, as with the <#> ( on some keyboards) overlay command. Useful for building parameter files that use the 3D overlay feature.\ The options below override the 3D defaults: ~Format- PREVIEW=yes Turns on 3D 'preview' default mode SHOWBOX=yes Turns on 3D 'showbox' default mode COARSE=nn Sets Preview 'coarseness' default value SPHERE=yes Turns on spherical projection mode STEREO=n Selects the type of stereo image creation RAY=nnn selects raytrace output file format BRIEF=yes selects brief or verbose file for DKB output USEGRAYSCALE=yes use grayscale as depth instead of color number INTEROCULAR=nn Sets the interocular distance for stereo CONVERGE=nn Determines the overall image separation CROP=nn/nn/nn/nn Trims the edges off stereo pairs BRIGHT=nn/nn Compensates funny glasses filter parameters LONGITUDE=nn/nn Longitude minimum and maximum LATITUDE=nn/nn Latitude minimum and maximum RADIUS=nn Radius scale factor ROTATION=nn[/nn[/nn]] Rotation about x,y, and z axes SCALEZYZ=nn/nn/nn X,y,and z scale factors ROUGHNESS=nn Same as z scale factor WATERLINE=nn Colors nn and below will be "inside" color FILLTYPE=nn 3D filltype PERSPECTIVE=nn Perspective distance XYSHIFT=nn/nn Shift image in x and y directions with perspective LIGHTSOURCE=nn/nn/nn Coordinates for light-source vector SMOOTHING=nn Smooths images in light-source fill modes TRANSPARENT=min/max Defines a range of colors to be treated as "transparent" when <#>Overlaying 3D images. XYADJUST=nn/nn This shifts the image in the x/y dir without perspective ~Format+ Below are new commands as of version 14 that support Marc Reinig's terrain features. RANDOMIZE=nnn (0 - 100)\ This feature randomly varies the color of a pixel to near by colors. Useful to minimize map banding in 3d transformations. Usable with all FILLTYPES. 0 disables, max values is 7. Try 3 - 5. AMBIENT=nnn (0 - 100)\ Set the depth of the shadows when using full color and light source filltypes. "0" disables the function, higher values lower the contrast. FULLCOLOR=yes\ Valid with any light source FILLTYPE. Allows you to create a Targa-24 file which uses the color of the image being transformed or the map you select and shades it as you would see it in real life. Well, its better than B&W. A good map file to use is topo HAZE=nnn (0 - 100)\ Gives more realistic terrains by setting the amount of haze for distant objects when using full color in light source FILLTYPES. Works only in the "y" direction currently, so don't use it with much y rotation. Try "rotation=85/0/0". 0 disables. BACKGROUND=nn/nn/nn\ Sets the background color of the Targa-24 file by setting the red, green, and blue values (rr/gg/bb). LIGHTNAME=\ The name of the Targa-24 file to be created when using full color with light source. Default is light001.tga. If overwrite=no (the default), the file name will be incremented until an unused filename is found. Background in this file will be the color set by background=r/g/b, the default is sky blue. MONITORWIDTH=\ This parameter allows you to specify the width in inches of the image on your monitor for the purpose of getting the correct stereo effect when viewing RDS images. See {Random Dot Stereograms (RDS)}. ; ; ; ~Topic=Batch Mode It IS possible, believe it or not, to become so jaded with the screen drawing process, so familiar with the types and options, that you just want to hit a key and do something else until the final images are safe on disk. To do this, start Fractint with the BATCH=yes parameter. To set up a batch run with the parameters required for a particular image you might: o Find an interesting area. Note the parameters from the display. Then use an editor to write a batch file. o Find an interesting area. Set all the options you'll want in the batch run. Use the command to store the parameters in a file. Then use an editor to add the additional required batch mode parameters (such as VIDEO=) to the generated parameter file entry. Then run the batch using "fractint @myname.par/myentry" (if you told the command to use file "myname" and to name the entry "myentry"). Another approach to batch mode calculations, using "FILENAME=" and resume, is described later. When modifying a parameter file entry generated by the command, the only parameters you must add for a batch mode run are "BATCH=yes", and "VIDEO=xxx" to select a video mode. You might want to also add "SAVENAME=[name]" to name the result as something other than the default FRACT001.GIF. Or, you might find it easier to leave the generated parameter file unchanged and add these parameters by using a command like: fractint @myname.par/myentry batch=y video=AF3 savename=mygif "BATCH=yes" tells Fractint to run in batch mode -- that is, Fractint draws the image using whatever other parameters you specified, then acts as if you had hit to save the image, then exits to DOS. "FILENAME=" can be used with "BATCH=yes" to resume calculation of an incomplete image. For instance, you might interactively find an image you like; then select some slow options (a high resolution disk video mode, distance estimator method, high maxiter, or whatever); start the calculation; then interrupt immediately with a ave. Rename the save file (fract001.gif if it is the first in the session and you didn't name it with the options or "savename=") to xxx.gif. Later you can run Fractint in batch mode to finish the job:\ fractint batch=yes filename=xxx savename=xxx "SAVETIME=nnn" is useful with long batch calculations, to store a checkpoint every nnn minutes. If you start a many hour calculation with say "savetime=60", and a power failure occurs during the calculation, you'll have lost at most an hour of work on the image. You can resume calculation from the save file as above. Automatic saves triggered by SAVETIME do not increment the save file name. The same file is overwritten by each auto save until the image completes. But note that Fractint does not directly over-write save files. Instead, each save operation writes a temporary file FRACTINT.TMP, then deletes the prior save file, then renames FRACTINT.TMP to be the new save file. This protects against power failures which occur during a save operation - if such a power failure occurs, the prior save file is intact and there's a harmless incomplete FRACTINT.TMP on your disk. If you want to spread a many-hour image over multiple bits of free machine time you could use a command like:\ fractint batch=yes filename=xxx savename=xxx savetime=60 video=F3\ While this batch is running, hit (almost any key actually) to tell fractint to save what it has done so far and give your machine back. A status code of 2 is returned by fractint to the batch file. Kick off the batch again when you have another time slice for it. When the savetime parameter is negative, Fractint will save the image after the requested time and exit. This is useful in batch files where you want to generate several images with a time limit on each image. While running a batch file, pressing any key will cause Fractint to exit with an errorlevel = 2. Any error that interrupts an image save to disk will cause an exit with errorlevel = 2. Any error that prevents an image from being generated will cause an exit with errorlevel = 1. The SAVETIME= parameter, and batch resumes of partial calculations, only work with fractal types which can be resumed. See {"Interrupting and Resuming"} for information about non-resumable types. ; ; ; ~Topic=Video Adapter Notes Alas, in this day of Windows, video adapter manufacturers do not have much incentive to support DOS video modes. Fractint can support any video modes included in your board's VESA video bios. Many otherwise good boards do not include the higher resolution modes in their bios even though those modes are supported in the manufacturer's Windows driver. Fractint users are particularly fond of the 1600x1200 mode. If you want to use this mode, make sure your video board supports it. Some boards that have given good results are boards from STB, various versions of Matrox Millennium, and boards from several manufacturers using Nvidia Riva chip sets. Using high resolution video modes poses a second challenge for fractint users. That is that the VESA standard does not have standard settings for this mode, so you will have to edit the fractint.cfg file to support your board. You can run the program makefcfg.exe that comes with fractint to generate entries for your fractint.cfg file. Finally, even if your video board VESA Bios supports high resolution video modes, it probably doesn't come with a utility that allows you to set the vertical refresh. If the vertical refresh is set for 60 Hz or less, you may see flicker and be subject to headaches. Fortunately, there is a wonderful freeware utility by Rob Muller that allows you to control the vertical refresh for any VESA video mode. Of course your monitor still needs to be able to support higher rates -- software can't help that. To get Rob's unirefresh program, email Rob at r.muller@student.utwente.nl or check out http://home.student.utwente.nl/r.muller/unirefresh True to the spirit of public-domain programming, Fractint makes only a limited attempt to verify that your video adapter can run in the mode you specify, or even that an adapter is present, before writing to it. So if you use the "video=" command line parameter, check it before using a new version of Fractint - the old key combo may now call an ultraviolet holographic mode. ~Doc- Comments about some particular video adapters:\ { EGA } { Tweaked VGA } { Super-VGA }\ { 8514/A } { XGA }\ { Targa } { Targa+ }\ Also see {Customized Video Modes\, FRACTINT.CFG}. ~Doc+ ; ; ~Topic=EGA ~Format-,Online- EGA ~Format+,Online+ Fractint assumes that every EGA adapter has a full 256K of memory (and can therefore display 640 x 350 x 16 colors), but does nothing to verify that fact before slinging pixels. ; ; ~Topic=Tweaked VGA ~Format-,Online- "TWEAKED" VGA MODES ~Format+,Online+ The IBM VGA adapter is a highly programmable device, and can be set up to display many video-mode combinations beyond those "officially" supported by the IBM BIOS. E.g. 320x400x256 and 360x480x256 (the latter is one of our favorites). These video modes are perfectly legal, but temporarily reprogram the adapter (IBM or fully register-compatible) in a non-standard manner that the BIOS does not recognize. Fractint also contains code that sets up the IBM (or any truly register- compatible) VGA adapter for several extended modes such as 704x528, 736x552, 768x576, and 800x600. It does this by programming the VGA controller to use the fastest dot-clock on the IBM adapter (28.322 MHz), throwing more pixels, and reducing the refresh rate to make up for it. These modes push many monitors beyond their rated specs, in terms of both resolution and refresh rate. Signs that your monitor is having problems with a particular "tweaked" mode include: o vertical or horizontal overscan (displaying dots beyond the edges of your visible CRT area) o flickering (caused by a too-slow refresh rate)\ o vertical roll or total garbage on the screen (your monitor simply can't keep up, or is attempting to "force" the image into a pre-set mode that doesn't fit). We have successfully tested the modes up to 768x576 on an IBM PS/2 Model 80 connected to IBM 8513, IBM 8514, NEC Multisync II, and Zenith 1490 monitors (all of which exhibit some overscan and flicker at the highest rates), and have tested 800x600 mode on the NEC Multisync II (although it took some twiddling of the vertical-size control). ; ; ~Topic=Super-VGA ~Format-,Online- SUPER-EGA AND SUPER-VGA MODES ~Format+,Online+ Since version 12.0, we've used both John Bridges' SuperVGA Autodetecting logic *and* VESA adapter detection, so that many brand-specific SuperVGA modes have been combined into single video mode selection entries. There is now exactly one entry for SuperVGA 640x480x256 mode, for instance. If Fractint's automatic SuperVGA/VESA detection logic guesses wrong, and you know which SuperVGA chipset your video adapter uses, you can use the "adapter=" command-line option to force Fractint to assume the presence of a specific SuperVGA Chipset - see {Video Parameters} for details. ; ; ~Topic=8514/A ~Format-,Online- 8514/A MODES ~Format+,Online+ The IBM 8514/A modes (640x480 and 1024x768) default to using the hardware registers. If an error occurs when trying to open the adapter, an attempt will be made to use IBM's software interface, and requires the preloading of IBM's HDILOAD TSR utility. The Adex 1280x1024 modes were written for and tested on an Adex Corporation 8514/A using a Brooktree DAC. The ATI GU 800x600x256 and 1280x1024x16 modes require a ROM bios version of 1.3 or higher for 800x600 and 1.4 or higher for 1280x1024. There are two sets of 8514/A modes: full sets (640x480, 800x600, 1024x768, 1280x1024) which cover the entire screen and do NOT have a border color (so that you cannot tell when you are "paused" in a color-cycling mode), and partial sets (632x474, 792x594, 1016x762, 1272x1018) with small border areas which do turn white when you are paused in color-cycling mode. Also, while these modes are declared to be 256-color, if you do not have your 8514/A adapter loaded with its full complement of memory you will actually be in 16-color mode. The hardware register 16-color modes have not been tested. If your 8514/A adapter is not truly register compatible and Fractint does not detect this, use of the adapter interface can be forced by using afi=y or afi=8514 in your SSTOOLS.INI file. Finally, because IBM's adapter interface does not handle drawing single pixels very well (we have to draw a 1x1 pixel "box"), generating the zoom box when using the interface is excruciatingly slow. Still, it works! ; ; ~Topic=XGA ~Format-,Online- XGA MODES ~Format+,Online+ The XGA adapter is supported using the VESA/SuperVGA Autodetect modes - the XGA looks like just another SuperVGA adapter to Fractint. The supported XGA modes are 640x480x256, 1024x768x16, 1024x768x256, 800x600x16, and 800x600x256. Note that the 1024x768x256 mode requires a full 1MB of adapter memory, the 1024x768 modes require a high-rez monitor, and the 800x600 modes require a multisynching monitor such as the NEC 2A. ; ; ~Topic=Targa ~Format-,Online- TARGA MODES ~Format+,Online+ TARGA support for Fractint is provided courtesy of Joe McLain and has been enhanced with the help of Bruce Goren and Richard Biddle. To use a TARGA board with Fractint, you must define two DOS environment variables, "TARGA" and "TARGASET". The definition of these variables is standardized by Truevision; if you have a TARGA board you probably already have added "SET" statements for these variables to your AUTOEXEC.BAT file. Be aware that there are a LOT of possible TARGA configurations, and a LOT of opportunities for a TARGA board and a VGA or EGA board to interfere with each other, and we may not have all of them smoothed away yet. Also, the TARGA boards have an entirely different color-map scheme than the VGA cards, and at the moment they cannot be run through the color-cycling menu. The "MAP=" argument (see {Color Parameters}), however, works with both TARGA and VGA boards and enables you to redefine the default color maps with either board. ; ; ~Topic=Targa+ ~Format-,Online- TARGA+ MODES ~Format+,Online+ To use the special modes supported for TARGA+ adapters, the TARGAP.SYS device driver has to be loaded, and the TPLUS.DAT file (included with Fractint) must be in the same directory as Fractint. The video modes with names containing "True Color Autodetect" can be used with the Targa+. You might want to use the command line parameters "tplus=", "noninterlaced=", "maxcolorres=", and "pixelzoom=" (see {Video Parameters}) in your SSTOOLS.INI file to modify Fractint's use of the adapter. ; ; ~Topic="Disk-Video" Modes These "video modes" do not involve a video adapter at all. They use (in order or preference) your expanded memory, your extended memory, or your disk drive (as file FRACTINT.$$$) to store the fractal image. These modes are useful for creating images beyond the capacity of your video adapter right up to the current internal limit of 32767 x 32767 x 256, e.g. for subsequent printing. They're also useful for background processing under multi-tasking DOS managers - create an image in a disk-video mode, save it, then restore it in a real video mode. While you are using a disk-video mode, your screen will display text information indicating whether memory or your disk drive is being used, and what portion of the "screen" is being read from or written to. A "Cache size" figure is also displayed. 64K is the maximum cache size. If you see a number less than this, it means that you don't have a lot of memory free, and that performance will be less than optimum. With a very low cache size such as 4 or 6k, performance gets considerably worse in cases using solid guessing, boundary tracing, plasma, or anything else which paints the screen non-linearly. If you have this problem, all we can suggest is having fewer TSR utilities loaded before starting Fractint, or changing in your config.sys file, such as reducing a very high BUFFERS value. The zoom box is disabled during disk-video modes (you couldn't see where it is anyway). So is the orbit display feature. {=@ColorCycling Color Cycling} can be used during disk-video modes, but only to load or save a color palette. When using real disk for your disk-video, Fractint previously would not generate some "attractor" types (e.g. Lorenz) nor "IFS" images. These stress disk drives with intensive reads and writes, but with the caching algorithm performance may be acceptable. Currently Fractint gives you a warning message but lets you proceed. You can end the calculation with if you think your hard disk is getting too strenuous a workout. When using a real disk, and you are not directing the file to a RAM disk, and you aren't using a disk caching program on your machine, specifying BUFFERS=10 (or more) in your config.sys file is best for performance. BUFFERS=10,2 or even BUFFERS=10,4 is also good. It is also best to keep your disk relatively "compressed" (or "defragmented") if you have a utility to do this. In order to use extended memory, you must have HIMEM.SYS or an equivalent that supports the XMS 2.0 standard or higher. Also, you can't have a VDISK installed in extended memory. Himem.sys is distributed with Microsoft Windows 286/386 and 3.0. If you have problems using the extended memory, try rebooting with just himem.sys loaded and see if that clears up the problem. If you are running background disk-video fractals under Windows 3, and you don't have a lot of real memory (over 2Mb), you might find it best to force Fractint to use real disk for disk-video modes. (Force this by using a .pif file with extended memory and expanded memory set to zero.) Try this if your disk goes crazy when generating background images, which are supposedly using extended or expanded memory. This problem can occur because, to multi-task, sometimes Windows must page an application's expanded or extended memory to disk, in big chunks. Fractint's own cached disk access may be faster in such cases. ; ; ; ~Topic=Customized Video Modes\, FRACTINT.CFG If you have a favorite adapter/video mode that you would like to add to Fractint... if you want some new sizes of disk-video modes... if you want to remove table entries that do not apply to your system... if you want to specify different "textsafe=" options for different video modes... relief is here, and without even learning "C"! You can do these things by modifying the FRACTINT.CFG file with your text editor. Saving a backup copy of FRACTINT.CFG first is of course highly recommended! Fractint uses a video adapter table for most of what it needs to know about any particular adapter/mode combination. The table is loaded from FRACTINT.CFG each time Fractint is run. It can contain information for up to 300 adapter/mode combinations. The table entries, and the function keys they are tied to, are displayed in the "select video mode" screen. This table makes adding support for various third-party video cards and their modes much easier, at least for the ones that pretend to be standard with extra dots and/or colors. There is even a special "roll-your-own" video mode (mode 19) enabling those of you with "C" compilers and a copy of the Fractint source to generate video modes supporting whatever adapter you may have. The table as currently distributed begins with nine standard and several non-standard IBM video modes that have been exercised successfully with a PS/2 model 80. These entries, coupled with the descriptive comments in the table definition and the information supplied (or that should have been supplied!) with your video adapter, should be all you need to add your own entries. After the IBM and quasi-pseudo-demi-IBM modes, the table contains an ever- increasing number of entries for other adapters. Almost all of these entries have been added because someone like you sent us spec sheets, or modified Fractint to support them and then informed us about it. Lines in FRACTINT.CFG which begin with a semi-colon are treated as comments. The rest of the lines must have eleven fields separated by commas. The fields are defined as: ~Format- 1. Key assignment. F2 to F10, SF1 to SF10, CF1 to CF10, or AF1 to AF10. Blank if no key is assigned to the mode. 2. The name of the adapter/video mode (25 chars max, no leading blanks). The adapter is set up for that mode via INT 10H, with: 3. AX = this, 4. BX = this, 5. CX = this, and 6. DX = this (hey, having all these registers wasn't OUR idea!) 7. An encoded value describing how to write to your video memory in that mode. Currently available codes are: 1) Use the BIOS (INT 10H, AH=12/13, AL=color) (last resort - SLOW!) 2) Pretend it's a (perhaps super-res) EGA/VGA 3) Pretend it's an MCGA 4) SuperVGA 256-Color mode using the Tseng Labs chipset 5) SuperVGA 256-Color mode using the Paradise chipset 6) SuperVGA 256-Color mode using the Video-7 chipset 7) Non-Standard IBM VGA 360 x 480 x 256-Color mode 8) SuperVGA 1024x768x16 mode for the Everex chipset 9) TARGA video modes 10) HERCULES video mode 11) Non-Video, i.e. "disk-video" 12) 8514/A video modes 13) CGA 320x200x4-color and 640x200x2-color modes 14) Reserved for Tandy 1000 video modes 15) SuperVGA 256-Color mode using the Trident chipset 16) SuperVGA 256-Color mode using the Chips & Tech chipset 17) SuperVGA 256-Color mode using the ATI VGA Wonder chipset 18) SuperVGA 256-Color mode using the EVEREX chipset 19) Roll-your-own video mode (as you've defined it in YOURVID.C) 20) SuperVGA 1024x768x16 mode for the ATI VGA Wonder chipset 21) SuperVGA 1024x768x16 mode for the Tseng Labs chipset 22) SuperVGA 1024x768x16 mode for the Trident chipset 23) SuperVGA 1024x768x16 mode for the Video 7 chipset 24) SuperVGA 1024x768x16 mode for the Paradise chipset 25) SuperVGA 1024x768x16 mode for the Chips & Tech chipset 26) SuperVGA 1024x768x16 mode for the Everex Chipset 27) SuperVGA Auto-Detect mode (we poke around looking for your adapter) 28) VESA modes 29) True Color Auto-Detect (currently only Targa+ supported) Add 100, 200, 300, or 400 to this code to specify an over-ride "textsafe=" option to be used with the mode. 100=yes, 200=no, 300=bios, 400=save. E.g. 428 for a VESA mode with textsafe=save forced. 8. The number of pixels across the screen (X - 2 to 2048) 9. The number of pixels down the screen (Y - 2 to 2048) 10. The number of available colors (2, 4, 16, or 256) 11. A comment describing the mode (25 chars max, leading blanks are OK) ~Format+ NOTE that the AX, BX, CX, and DX fields use hexadecimal notation (fifteen ==> 'f', sixteen ==> '10'), because that's the way most adapter documentation describes it. The other fields use standard decimal notation. If you look closely at the default entries, you will notice that the IBM VGA entries labeled "tweaked" and "non standard" have entries in the table with AX = BX = CX = 0, and DX = some other number. Those are special flags that we used to tell the program to custom-program the VGA adapter, and are NOT undocumented BIOS calls. Maybe they should be, but they aren't. If you have a fancy adapter and a new video mode that works on it, and it is not currently supported, PLEASE GET THAT INFORMATION TO US! We will add the video mode to the list on our next release, and give you credit for it. Which brings up another point: If you can confirm that a particular video adapter/mode works (or that it doesn't), and the program says it is UNTESTED, please get that information to us also. Thanks in advance! ; ; ; xfractint-20.4.10.orig/dos_help/help5.src0000644000000000000000000050247611133513272015044 0ustar ~Topic=Common Problems Of course, Fractint would never stoop to having a "common" problem. These notes describe some, ahem, "special situations" which come up occasionally and which even we haven't the gall to label as "features". Fractint (alas!) is still a DOS program. It runs well under windows, but there can be problems. Here are some tips from some expert users. Jay Hill's Windows tips:\ For starters, make sure the DOS window properties are set to 'Misc | Always suspend' = off." Unless you want the task to stop when it does not have focus. Also, you can put the Idle Sensitivity to high. Make settings on any other DOS windows you have open according to what they should be (or what you prefer). If your DOS window is full screen, press Alt-Enter to make it a Window window. Then click on the MSDOS icon in the upper left. WARNING, don't do this in a high res graphics mode or in text mode (sometimes). The safest is F3 320x200 graphics mode. Windows likes that mode. If you have a high res image, hit 'X' to get the text screen and then Alt-ENTER to get the DOS Windows window... POW...your task will likely die. So ... don't do that: Some DOS programs eat up to 50% or 80% CPU time just sitting watching for key strokes. Clearly, these should be suspended when they don't have the focus. A simple DOS prompt, I have found, eats little time. Some web pages eat lots of time (watching prompt boxes) while others eat little (plain text or graphics with no links). It has been noted here before, you can make a shortcut to Fractint.exe and tailor its properties. I use in the program tab: command line: FRACTINT.EXE textsafe=save sound=off\ Under the screen tab: Usage: Full screen. Under Misc: Allow screen saver=off. You should coordinate your DOS windows according to what you are doing. I often change the settings for a short time, just to do some other task. Damien M. Jones Windows tips:\ This is what works for me. Your mileage may vary. Create a shortcut to FRACTINT.EXE, right-click it, choose Properties. On the Memory tab: set all five drop-downs to "Auto". On the Screen tab: choose Full-screen and Fast ROM emulation, leave Dynamic memory allocation OFF. Under the Misc tab: turn OFF Allow screen saver. Turn ON Always suspend. Set the Idle sensitivity to about 1/4, closest to Low. In the SSTOOLS.INI file, put textsafe=save on a line by itself in the [fractint] section. (This helps preserve your screen when you switch away from FractInt, but only works if Always suspend is turned ON.) Having more than 8M of RAM helps too, that way Windows and FractInt aren't fighting over the same memory. Hang during startup:\ There might be a problem with Fractint's video detection logic and your particular video adapter. Try running with "fractint adapter=xxx" where xxx is cga, ega, egamono, mcga, or vga. If "adapter=vga" works, and you really have a SuperVGA adapter capable of higher video modes, there are other "adapter=" options for a number of SuperVGA chipsets - please see the full selection in {Video Parameters} for details. If this solves the problem, create an SSTOOLS.INI file with the "adapter=xxx" command in it so that the fix will apply to every run.\ Another possible cause: If you install the latest Fractint in say directory "newfrac", then run it from another directory with the command "\\newfrac\\fractint", *and* you have an older version of fractint.exe somewhere in your DOS PATH, a silent hang is all you'll get. See the notes under the "Cannot find FRACTINT.EXE message" problem for the reason.\ Another possibility: try one of the "textsafe" parameter choices described in {Video Parameters}. Scrambled image when returning from a text mode display:\ If an image which has been partly or completely generated gets partly destroyed when you return to it from the menu, help, or the information display, please try the various "textsafe" parameter options - see {Video Parameters} for details. If this cures the problem, create an SSTOOLS.INI file with the "textsafe=xxx" command so that the fix will apply to every run. "Holes" in an image while it is being drawn:\ Little squares colored in your "inside" color, in a pattern of every second square of that size, in solid guessing mode, both across and down (i.e., 1 out of 4), are a symptom of an image which should be calculated with more conservative periodicity checking than the default. See the Periodicity parameter under {Image Calculation Parameters}. Black bar at top of screen during color cycling on 8086/8088 machines:\ (This might happen intermittently, not every run.)\ "fractint cyclelimit=10" might cure the problem. If so, increase the cyclelimit value (try increasing by 5 or 10 each time) until the problem reappears, then back off one step and add that cyclelimit value to your SSTOOLS.INI file. Other video problems: If you are using a VESA driver with your video adapter, the first thing to try is the "vesadetect=no" parameter. If that fixes the problem, add it to your SSTOOLS.INI file to make the fix permanent. It may help to explicitly specify your type of adapter - see the "adapter=" parameter in {Video Parameters}. We've had one case where a video driver for Windows does not work properly with Fractint. If running under Windows, DesqView, or some other layered environment, try running Fractint directly from DOS to see if that avoids the problem.\ We've also had one case of a problem co-existing with "386 to the Max". We've had one report of an EGA adapter which got scrambled images in all modes until "textsafe=no" was used (see {Video Parameters}). Also, see {Video Adapter Notes} for information about enhanced video modes - Fractint makes only limited attempts to verify that a video mode you request is actually supported by your adapter. ~OnlineFF Other Hangs and Strange Behavior:\ We've had some problems (hangs and solid beeps) on an FPU equipped machine when running under Windows 3's enhanced mode. The only ways around the problem we can find are to either run the Fractint image involved outside Windows, or to use the DOS command "SET NO87=nofpu" before running Fractint. (This SET command makes Fractint ignore your fpu, so things might be a lot slower as a result.) Insufficient memory:\ Fractint requires a fair bit of memory to run. Most machines with at least 640k (ok sticklers, make that "PC-compatible machines") will have no problem. Machines with 512k and machines with many TSR utilities and/or a LAN interface may have problems. Some Fractint features allocate memory when required during a run. If you get a message about insufficient memory, or suspect that some problem is due to a memory shortage, you could try commenting out some TSR utilities in your AUTOEXEC.BAT file, some non-critical drivers in your CONFIG.SYS file, or reducing the BUFFERS parameter in your CONFIG.SYS. ~OnlineFF "Cannot find FRACTINT.EXE" message:\ Fractint is an overlayed program - some parts of it are brought from disk into memory only when used. The overlay manager needs to know where to find the program. It must be named FRACTINT.EXE (which it is unless somebody renamed it), and you should either be in the directory containing it when you start Fractint, or that directory should be in your DOS PATH. "File FRACTINT.CFG is missing or invalid" message:\ You should either start Fractint while you are in the directory containing it, or should have that directory in your DOS PATH variable. If that isn't the problem, maybe you have a FRACTINT.CFG file from an older release of Fractint lying around? If so, best rename or delete it. If that isn't the problem either, then the FRACTINT.CFG included in the FRAINT.EXE release file has probably been changed or deleted. Best reinstall Fractint to get a fresh copy. ~OnlineFF Some other program doesn't like GIF files created by Fractint:\ Fractint generates nice clean GIF89A spec files, honest! But telling this to the other program isn't likely to change its mind. Instead, try an option which might get around the problem: run Fractint with the command line option "gif87a=yes" and then save an image. Fractint will store the image in the older GIF87A format, without any fractal parameters in it (so you won't be able to load the image back into Fractint and zoom into it - the fractal type, coordinates, etc. are not stored in this older format), and without an "aspect ratio" in the GIF header (we've seen one utility which doesn't like that field.) Disk video mode performance:\ This won't be blindingly fast at the best of times, but there are things which can slow it down and can be tuned. See {"Disk-Video" Modes} for details. Sound card output isn't working:\ If you get the message "FM hardware not present" when trying to switch on output from your sound card then check that the drivers you installed with the card have set the BLASTER environment variable. To do this go to a DOS prompt and type SET, this command will list a bunch of lines like this:\ VARIABLE=VALUE\ ANOTHERVARIABLE=ANOTHER VALUE\ \ one of these should look like:\ BLASTER=A:220 I:5 D:3\ or similar, it's the A: entry that's important. If you don't have the variable set then try putting the line:\ SET BLASTER=A:220\ in your autoexec.bat file, though be warned that if your sound hardware isn't compatable or has its base i/o address set differently to the 220H, then unexpected things may happen as fractint tries to write to hardware that isn't there. If you get no warning message but still can't hear anything then try to alter the volume of your card's output using whatever utility came with the card. For windows 95 doubleclick on the small loudspeaker icon on your task bar and play with the sliders, you may have to go to the mixer properties menu and enable the control for the FM output to appear, this may be called 'synthesizer', 'FM', 'midi', or 'legacy' depending on your hardware. Also fractint is unlikely to be able to continue sounding notes when running in the background under windows 95, so you'll need to keep switching back and forth until things are set right. ; ; ; ~Topic=Fractals and the PC ; ; empty for document, present just so we can reference the subject ~Format-,Doc- A Little History: { Before Mandelbrot } { Who Is This Guy, Anyway? } A Little Code: { Periodicity Logic } { Limitations of Integer Math (And How We Cope) } { Arbitrary Precision and Deep Zooming } { The Fractint "Fractal Engine" Architecture } A Little Math: { Summary of Fractal Types } { Inside=bof60|bof61|zmag|fmod|period|atan } { Inside=epscross|startrail } { Finite Attractors } { Trig Identities } { Quaternion and Hypercomplex Algebra } ~Format+,Doc+ ; ; ~Topic=Before Mandelbrot Like new forms of life, new branches of mathematics and science don't appear from nowhere. The ideas of fractal geometry can be traced to the late nineteenth century, when mathematicians created shapes -- sets of points -- that seemed to have no counterpart in nature. By a wonderful irony, the "abstract" mathematics descended from that work has now turned out to be MORE appropriate than any other for describing many natural shapes and processes. Perhaps we shouldn't be surprised. The Greek geometers worked out the mathematics of the conic sections for its formal beauty; it was two thousand years before Copernicus and Brahe, Kepler and Newton overcame the preconception that all heavenly motions must be circular, and found the ellipse, parabola, and hyperbola in the paths of planets, comets, and projectiles. In the 17th century Newton and Leibniz created calculus, with its techniques for "differentiating" or finding the derivative of functions -- in geometric terms, finding the tangent of a curve at any given point. True, some functions were discontinuous, with no tangent at a gap or an isolated point. Some had singularities: abrupt changes in direction at which the idea of a tangent becomes meaningless. But these were seen as exceptional, and attention was focused on the "well-behaved" functions that worked well in modeling nature. Beginning in the early 1870s, though, a 50-year crisis transformed mathematical thinking. Weierstrass described a function that was continuous but nondifferentiable -- no tangent could be described at any point. Cantor showed how a simple, repeated procedure could turn a line into a dust of scattered points, and Peano generated a convoluted curve that eventually touches every point on a plane. These shapes seemed to fall "between" the usual categories of one-dimensional lines, two- dimensional planes and three-dimensional volumes. Most still saw them as "pathological" cases, but here and there they began to find applications. In other areas of mathematics, too, strange shapes began to crop up. Poincare attempted to analyze the stability of the solar system in the 1880s and found that the many-body dynamical problem resisted traditional methods. Instead, he developed a qualitative approach, a "state space" in which each point represented a different planetary orbit, and studied what we would now call the topology -- the "connectedness" -- of whole families of orbits. This approach revealed that while many initial motions quickly settled into the familiar curves, there were also strange, "chaotic" orbits that never became periodic and predictable. Other investigators trying to understand fluctuating, "noisy" phenomena -- the flooding of the Nile, price series in economics, the jiggling of molecules in Brownian motion in fluids -- found that traditional models could not match the data. They had to introduce apparently arbitrary scaling features, with spikes in the data becoming rarer as they grew larger, but never disappearing entirely. For many years these developments seemed unrelated, but there were tantalizing hints of a common thread. Like the pure mathematicians' curves and the chaotic orbital motions, the graphs of irregular time series often had the property of self-similarity: a magnified small section looked very similar to a large one over a wide range of scales. ; ; ~Topic=Who Is This Guy\, Anyway? While many pure and applied mathematicians advanced these trends, it is Benoit Mandelbrot above all who saw what they had in common and pulled the threads together into the new discipline. He was born in Warsaw in 1924, and moved to France in 1935. In a time when French mathematical training was strongly analytic, he visualized problems whenever possible, so that he could attack them in geometric terms. He attended the Ecole Polytechnique, then Caltech, where he encountered the tangled motions of fluid turbulence. In 1958 he joined IBM, where he began a mathematical analysis of electronic "noise" -- and began to perceive a structure in it, a hierarchy of fluctuations of all sizes, that could not be explained by existing statistical methods. Through the years that followed, one seemingly unrelated problem after another was drawn into the growing body of ideas he would come to call fractal geometry. As computers gained more graphic capabilities, the skills of his mind's eye were reinforced by visualization on display screens and plotters. Again and again, fractal models produced results -- series of flood heights, or cotton prices -- that experts said looked like "the real thing." Visualization was extended to the physical world as well. In a provocative essay titled "How Long Is the Coast of Britain?" Mandelbrot noted that the answer depends on the scale at which one measures: it grows longer and longer as one takes into account every bay and inlet, every stone, every grain of sand. And he codified the "self-similarity" characteristic of many fractal shapes -- the reappearance of geometrically similar features at all scales. First in isolated papers and lectures, then in two editions of his seminal book, he argued that many of science's traditional mathematical models are ill-suited to natural forms and processes: in fact, that many of the "pathological" shapes mathematicians had discovered generations before are useful approximations of tree bark and lung tissue, clouds and galaxies. Mandelbrot was named an IBM Fellow in 1974, and continues to work at the IBM Watson Research Center. He has also been a visiting professor and guest lecturer at many universities. ; ; ~Topic=Periodicity Logic The "Mandelbrot Lake" in the center of the M-set images is the traditional bane of plotting programs. It sucks up the most computer time because it always reaches the iteration limit -- and yet the most interesting areas are invariably right at the edge the lake. (See {The Mandelbrot Set} for a description of the iteration process.) Thanks to Mark Peterson for pointing out (well, he more like beat us over the head until we paid attention) that the iteration values in the middle of Mandelbrot Lake tend to decay to periodic loops (i.e., Z(n+m) == Z(n), a fact that is pointed out on pages 58-61 of "The Beauty of Fractals"). An intelligent program (like the one he wrote) would check for this periodicity once in a while, recognize that iterations caught in a loop are going to max out, and bail out early. For speed purposes, the current version of the program turns this checking algorithm on only if the last pixel generated was in the lake. (The checking itself takes a small amount of time, and the pixels on the very edge of the lake tend to decay to periodic loops very slowly, so this compromise turned out to be the fastest generic answer). Try a full M-set plot with a 1000-iteration maximum with any other program, and then try it on this one for a pretty dramatic proof of the value of periodicity checking. You can get a visual display of the periodicity effects if you press rbits while plotting. This toggles display of the intermediate iterations during the generation process. It also gives you an idea of how much work your poor little PC is going through for you! If you use this toggle, it's best to disable solid-guessing first using <1> or <2> because in its second pass, solid-guessing bypasses many of the pixel calculations precisely where the orbits are most interesting. Mark was also responsible for pointing out that 16-bit integer math was good enough for the first few levels of M/J images, where the round-off errors stay well within the area covered by a single pixel. Fractint now uses 16-bit math where applicable, which makes a big difference on non-32- bit PCs. Failure of the periodicity checking logic appears as horizontal stripes that start at the left edge of the lake. If this happens, the best solution is to turn periodicity checking off. If the image has a high iteration count and many pixels in the lake, so that you really do need periodicity turned on, try increasing the periodicity value until the stripes disappear. ; ; ~Topic=Limitations of Integer Math (And How We Cope) By default, Fractint uses 16-bit and/or 32-bit integer math to generate nearly all its fractal types. The advantage of integer math is speed: this is by far the fastest such plotter that we have ever seen on any PC. The disadvantage is an accuracy limit. Integer math represents numbers like 1.00 as 32-bit integers of the form [1.00 * (2^29)] (approximately a range of 500,000,000) for the Mandelbrot and Julia sets. Other integer fractal types use a bitshift of 24 rather than 29, so 1.0 is stored internally as [1.00 * (2^24)]. This yields accuracy of better than 8 significant digits, and works fine... until the initial values of the calculations on consecutive pixels differ only in the ninth decimal place. At that point, if Fractint has a floating-point algorithm handy for that particular fractal type (and virtually all of the fractal types have one these days), it will silently switch over to the floating-point algorithm and keep right on going. Fair warning - if you don't have an FPU, the effect is that of a rocket sled hitting a wall of jello, and even if you do, the slowdown is noticeable. If it has no floating-point algorithm, Fractint does the best it can: it switches to its minimal drawing mode, with adjacent pixels having initial values differing by 1 (really 0.000000002). Attempts to zoom further may result in moving the image around a bit, but won't actually zoom. If you are stuck with an integer algorithm, you can reach minimal mode with your fifth consecutive "maximum zoom", each of which covers about 0.25% of the previous screen. By then your full-screen image is an area less than 1/(10^13)th [\~0.0000000000001] the area of the initial screen. (If your image is rotated or stretched very slightly, you can run into the wall of jello as early as the fourth consecutive maximum zoom. Rotating or stretching by larger amounts has less impact on how soon you run into it.) Think of it this way: at minimal drawing mode, your VGA display would have to have a surface area of over one million square miles just to be able to display the entire M-set using the integer algorithms. Using the floating-point algorithms, your display would have to be big enough to fit the entire solar system out to the orbit of Saturn inside it. So there's a considerable saving on hardware, electricity and desk space involved here. Also, you don't have to take out asteroid insurance. 32 bit integers also limit the largest number which can be stored. This doesn't matter much since numbers outside the supported range (which is between -4 and +4) produce a boring single color. If you try to zoom-out to reduce the entire Mandelbrot set to a speck, or to squeeze it to a pancake, you'll find you can't do so in integer math mode. ; ; ~Topic=Arbitrary Precision and Deep Zooming The zoom limit of Fractint is approximately 10^15 (10 to the fifteenth power). This limit is due to the precision possible with the computer representation of numbers as 64 bit double precision data. To give you an idea of just how big a magnification 10^15 is, consider this. At the scale of your computer screen while displaying a tiny part of the Mandelbrot set at the deepest possible zoom, the entire Mandelbrot set would be many millions of miles wide, as big as the orbit of Jupiter. Big as this zoom magnification is, your PC can do better using something called arbitrary precision math. Instead of using 64 bit double precision to represent numbers, your computer software allocates as much memory as needed to create a data type supporting as many decimals of precision as you want. Incorporation of this feature in Fractint was inspired by Jay Hill and his DEEPZOOM program which uses the shareware MFLOAT programming library. Several of the Stone Soup programmers noticed Jay's posts in the Internet sci.fractals newsgroup and began to investigate adding arbitrary precision to Fractint. High school math and physics teacher Wes Loewer wrote an arbitrary precision library in both 80x86 assembler and C, and the Stone Soup team incorporated Wes's library into Fractint. Initially, support was added for fractal types mandel, julia, manzpower, and julzpower. Later, support for the fractal type dividebrot5 was added. Normally, when you reach Fractint's zoom limit, Fractint simply refuses to let you zoom any more. When using the fractal types that support arbitrary precision, you will not reach this limit, but can keep on zooming. When you pass the threshold between double precision and arbitrary precision, Fractint will dramatically slow down. The status screen can be used to verify that Fractint is indeed using arbitrary precision. Fractals with arbitrary precision are SLOW, as much as ten times slower than if the math were done with your math coprocessor, and even slower simply because the zoom depth is greater. The good news, if you want to call it that, is that your math coprocessor is not needed; coprocessorless machines can produce deep zooms with the same glacial slowness as machines with coprocessors! Maybe the real point of arbitrary precision math is to prolong the "olden" days when men were men, women were women, and real fractal programmers spent weeks generating fractals. One of your Stone Soup authors has a large monitor that blinks a bit when changing video modes--PCs have gotten so fast that Fractint finishes the default 320x200 Mandelbrot before the monitor can even complete its blinking transition to graphics mode! Computers are getting faster every day, and soon a new generation of fractal lovers might forget that fractal generation is *supposed* to be slow, just as it was in Grandpa's day when they only had Pentium chips. The solution to this educational dilemma is Fractint's arbitrary precision feature. Even the newest sexium and septium machines are going to have to chug for days or weeks at the extreme zoom depths now possible ... So how far can you zoom? How does 10^1600 sound--roughly 1600 decimal digits of precision. To put *this* magnification in perspective, the "tiny" ratio of 10^61 is the ratio of the entire visible universe to the smallest quantum effects. With 1600 digits to work with, you can expand an electron-sized image up to the size of the visible universe, not once but more than twenty times. So you can examine screen-sized portions of a Mandelbrot set so large all but a tiny part of it would be vastly farther away than the billion or so light year limit of our best telescopes. Lest anyone suppose that we Stone Soupers suffer from an inflated pride over having thus spanned the Universe, current inflationary cosmological theories estimate the size of the universe to be unimaginably larger than the "tiny" part we can see. Note: many of Fractint's options do not work with arbitrary precision. To experiment with arbitrary precision at the speedier ordinary magnifications, start Fractint with the debug=3200 command-line option. With the exception of mandel, manzpower, and dividebrot5 perturbations, values that would normally be entered in the Parameters and Coordinates screens need to be entered using the command-line interface or .par files. Other known things that do not yet work with arbitrary precision are: biomorph, decomp, distance estimator, inversion, Julia-Mandel switch, history, orbit-in-window, and the browse feature. ; ; ~Topic=The Fractint "Fractal Engine" Architecture Several of the authors would never ADMIT this, but Fractint has evolved a powerful and flexible architecture that makes adding new fractals very easy. (They would never admit this because they pride themselves on being the sort that mindlessly but happily hacks away at code and "sees if it works and doesn't hang the machine".) Many fractal calculations work by taking a rectangle in the complex plane, and, point by point, calculating a color corresponding to that point. Furthermore, the color calculation is often done by iterating a function over and over until some bailout condition is met. (See {The Mandelbrot Set} for a description of the iteration process.) In implementing such a scheme, there are three fractal-specific calculations that take place within a framework that is pretty much the same for them all. Rather than copy the same code over and over, we created a standard fractal engine that calls three functions that may be bolted in temporarily to the engine. The "bolting in" process uses the C language mechanism of variable function pointers. These three functions are: 1) a setup function that is run once per image, to do any required initialization of variables, 2) a once-per-pixel function that does whatever initialization has to be done to calculate a color for one pixel, and 3) a once-per-orbit-iteration function, which is the fundamental fractal algorithm that is repeatedly iterated in the fractal calculation. The common framework that calls these functions can contain all sorts of speedups, tricks, and options that the fractal implementor need not worry about. All that is necessary is to write the three functions in the correct way, and BINGO! - all options automatically apply. What makes it even easier is that usually one can re-use functions 1) and 2) written for other fractals, and therefore only need to write function 3). Then it occurred to us that there might be more than one sort of fractal engine, so we even allowed THAT to be bolted in. And we created a data structure for each fractal that includes pointers to these four functions, various prompts, a default region of the complex plane, and various miscellaneous bits of information that allow toggling between Julia and Mandelbrot or toggling between the various kinds of math used in implementation. That sounds pretty flexible, but there is one drawback - you have to be a C programmer and have a C compiler to make use of it! So we took it a step further, and designed a built-in high level compiler, so that you can enter the formulas for the various functions in a formula file in a straightforward algebra-like language, and Fractint will compile them and bolt them in for you! There is a terrible down side to this flexibility. Fractint users everywhere are going berserk. Fractal-inventing creativity is running rampant. Proposals for new fractal types are clogging the mail and the telephones. All we can say is that non-productivity software has never been so potent, and we're sorry, it's our fault! Fractint was compiled using Microsoft C 7.0 and Microsoft Assembler 6.0, using the "Medium" model. Note that the assembler code uses the "C" model option added to version 5.1, and must be assembled with the /MX or /ML switch to link with the "C" code. Because it has become too large to distribute comfortably as a single compressed file, and because many downloaders have no intention of ever modifying it, Fractint is now distributed as two files: one containing FRACTINT.EXE, auxiliary files and this document, and another containing complete source code (including a .MAK file and MAKEFRAC.BAT). See {Distribution of Fractint}. ; ; ; ~Topic=Inside=bof60|bof61|zmag|fmod|period|atan ~Format-,Online- INSIDE=BOF60|BOF61|ZMAG|FMOD|PERIOD|ATAN ~Format+,Online+ Here is an *ATTEMPTED* explanation of what the inside=bof60 and inside=bof61 options do. This explanation is hereby dedicated to Adrian Mariano, who badgered it out of us! For the *REAL* explanation, see "Beauty of Fractals", page 62. Let p(z) be the function that is repeatedly iterated to generate a fractal using the escape-time algorithm. For example, p(z) = z^2+c in the case of a Julia set. Then let pk(z) be the result of iterating the function p for k iterations. (The "k" should be shown as a superscript.) We could also use the notation pkc(z) when the function p has a parameter c, as it does in our example. Now hold your breath and get your thinking cap on. Define a(c) = inf\{|pkc(0)|:k=1,2,3,...}. In English - a(c) is the greatest lower bound of the images of zero of as many iterations as you like. Put another way, a(c) is the closest to the origin any point in the orbit starting with 0 gets. Then the index (c) is the value of k (the iteration) when that closest point was achieved. Since there may be more than one, index(c) is the least such. Got it? Good, because the "Beauty of Fractals" explanation of this, is, ahhhh, *TERSE* ! Now for the punch line. Inside=bof60 colors the lake alternating shades according to the level sets of a(c). Each band represents solid areas of the fractal where the closest value of the orbit to the origin is the same. Inside=bof61 show domains where index(c) is constant. That is, areas where the iteration when the orbit swooped closest to the origin has the same value. Well, folks, that's the best we can do! Improved explanations will be accepted for the next edition! In response to this request for lucidity, Herb Savage offers this explanation the bof60 and bof61 options: \ The picture on page 60 of The Beauty of Fractals shows the distance to\ origin of the closest point to the origin in the sequence of points\ generated from a given X,Y coordinate. The picture on page 61 shows\ the index (or number) in the sequence of the closest point.\ \ inside=zmag is similar. This option colors inside pixels according to the magnitude of the orbit point when maxiter was reached, using the formula color = (x^2 + y^2) * maxiter/2 + 1. inside=fmod colors inside pixels according to the magnitude of the last orbit point which is within a set distance from the origin. Then:\ color = magnitude * colors / closeprox\ The magnitude used for the comparison is now based on the same calculation as is used for the bailout test. The value of closeprox can be varied interactively. This feature was contributed by Iain Stirling. inside=period colors pixels according to the length of their eventual cycle. For example, points that approach a fixed point have color=1. Points that approach a 2-cycle have color=2. Points that do not approach a cycle during the iterations performed have color=maxit. This option works best with a fairly large number of iterations. inside=atan colors by determining the angle in degrees the last iterated value has with respect to the real axis, and using the absolute value. This feature should be used with periodicity=0, and this is automatically set. ; ; ; ~Topic=Inside=epscross|startrail ~Format-,Online- INSIDE=EPSCROSS|STARTRAIL ~Format+,Online+ Kenneth Hooper has written a paper entitled "A Note On Some Internal Structures Of The Mandelbrot Set" published in "Computers and Graphics", Vol 15, No.2, pp. 295-297. In that article he describes Clifford Pickover's "epsilon cross" method which creates some mysterious plant-like tendrils in the Mandelbrot set. The algorithm is this. In the escape-time calculation of a fractal, if the orbit comes within .01 of the Y-axis, the orbit is terminated and the pixel is colored green. Similarly, the pixel is colored yellow if it approaches the X-axis. Strictly speaking, this is not an "inside" option because a point destined to escape could be caught by this bailout criterion. The test distance, 0.01, can now be changed interactively on the screen and via the proximity= command line parameter. A negative value of the test distance triggers an alternative variation of epsilon cross that colors the epsilon bands with the iteration; otherwise they are colored normally to maintain compatibility. Hooper has another coloring scheme called "star trails" that involves detecting clusters of points being traversed by the orbit. A table of tangents of each orbit point is built, and the pixel colored according to how many orbit points are near the first one before the orbit flies out of the cluster. This option looks fine with maxiter=16, which greatly speeds the calculation. Both of these options should be tried with the outside color fixed (outside=) so that the "lake" structure revealed by the algorithms can be more clearly seen. Epsilon Cross is fun to watch with boundary tracing turned on - even though the result is incorrect it is interesting! Shucks - what does "incorrect" mean in chaos theory anyway?! ; ; ; ~Topic=Finite Attractors ~Format-,Online- FINITE ATTRACTORS ~Format+,Online+ Many of Fractint's fractals involve the iteration of functions of complex numbers until some "bailout" value is exceeded, then coloring the associated pixel according to the number of iterations performed. This process identifies which values tend to infinity when iterated, and gives us a rough measure of how "quickly" they get there. In dynamical terms, we say that "Infinity is an Attractor", as many initial values get "attracted" to it when iterated. The set of all points that are attracted to infinity is termed The Basin of Attraction of Infinity. The coloring algorithm used divides this Basin of Attraction into many distinct sets, each a single band of one color, representing all the points that are "attracted" to Infinity at the same "rate". These sets (bands of color) are termed "Level Sets" - all points in such a set are at the same "Level" away from the attractor, in terms of numbers of iterations required to exceed the bailout value. Thus, Fractint produces colored images of the Level Sets of the Basin of Attraction of Infinity, for all fractals that iterate functions of Complex numbers, at least. Now we have a sound mathematical definition of what Fractint's "bailout" processing generates, and we have formally introduced the terms Attractor, Basin of Attraction, and Level Set, so you should have little trouble following the rest of this section! For certain Julia-type fractals, Fractint can also display the Level Sets of Basins of Attraction of Finite Attractors. This capability is a by- product of the implementation of the MAGNETic fractal types, which always have at least one Finite Attractor. This option can be invoked by setting the "Look for finite attractor" option on the options screen, or by giving the "finattract=yes" command-line option. Most Julia-types that have a "lake" (normally colored blue by default) have a Finite Attractor within this lake, and the lake turns out to be, quite appropriately, the Basin of Attraction of this Attractor. The "finattract=yes" option (command-line or options screen) instructs Fractint to seek out and identify a possible Finite Attractor and, if found, to display the Level Sets of its Basin of Attraction, in addition to those of the Basin of Attraction of Infinity. In many cases this results in a "lake" with colored "waves" in it; in other cases there may be little change in the lake's appearance. For a quick demonstration, select a fractal type of LAMBDA, with a parameter of 0.5 + 0.5i. You will obtain an image with a large blue lake. Now set "Look for finite attractor" to 1 with the "Y" menu. The image will be re-drawn with a much more colorful lake. A Finite Attractor lives in the center of one of the resulting "ripple" patterns in the lake - turn the rbits display on to see where it is - the orbits of all initial points that are in the lake converge there. Fractint tests for the presence of a Finite Attractor by iterating a Critical Value of the fractal's function. If the iteration doesn't bail out before exceeding twice the iteration limit, it is almost certain that we have a Finite Attractor - we assume that we have. Next we define a small circle around it and, after each iteration, as well as testing for the usual bailout value being exceeded, we test to see if we've hit the circle. If so, we bail out and color our pixels according to the number of iterations performed. Result - a nicely colored-in lake that displays the Level Sets of the Basin of Attraction of the Finite Attractor. Sometimes ! First exception: This does not work for the lakes of Mandel-types. Every point in a Mandel-type is, in effect, a single point plucked from one of its related Julia-types. A Mandel-type's lake has an infinite number of points, and thus an infinite number of related Julia-type sets, and consequently an infinite number of finite attractors too. It *MAY* be possible to color in such a lake, by determining the attractor for EVERY pixel, but this would probably treble (at least) the number of iterations needed to draw the image. Due to this overhead, Finite Attractor logic has not been implemented for Mandel-types. Secondly, certain Julia-types with lakes may not respond to this treatment, depending on the parameter value used. E.g., the Lambda Set for 0.5 + 0.5i responds well; the Lambda Set for 0.0 + 1.0i does not - its lake stays blue. Attractors that consist of single points, or a cycle of a finite number of points are ok. Others are not. If you're into fractal technospeak, the implemented approach fails if the Julia-type is a Parabolic case, or has Siegel Disks, or has Herman Rings. However, all the difficult cases have one thing in common - they all have a parameter value that falls exactly on the edge of the related Mandel- type's lake. You can avoid them by intelligent use of the Mandel-Julia Space-Bar toggle: Pick a view of the related Mandel-type where the center of the screen is inside the lake, but not too close to its edge, then use the space-bar toggle. You should obtain a usable Julia-type with a lake, if you follow this guideline. Thirdly, the initial implementation only works for Julia-types that use the "Standard" fractal engine in Fractint. Fractals with their own special algorithms are not affected by Finite Attractor logic, as yet. Finally, the finite attractor code will not work if it fails to detect a finite attractor. If the number of iterations is set too low, the finite attractor may be missed. Despite these restrictions, the Finite Attractor logic can produce interesting results. Just bear in mind that it is principally a bonus off-shoot from the development of the MAGNETic fractal types, and is not specifically tuned for optimal performance for other Julia types. (Thanks to Kevin Allen for the above). There is a second type of finite attractor coloring, which is selected by setting "Look for Finite Attractor" to a negative value. This colors points by the phase of the convergence to the finite attractor, instead of by the speed of convergence. For example, consider the Julia set for -0.1 + 0.7i, which is the three-lobed "rabbit" set. The Finite Attractor is an orbit of length three; call these values a, b, and c. Then, the Julia set iteration can converge to one of three sequences: a,b,c,a,b,c,..., or b,c,a,b,c,..., or c,a,b,c,a,b,... The Finite Attractor phase option colors the interior of the Julia set with three colors, depending on which of the three sequences the orbit converges to. Internally, the code determines one point of the orbit, say "a", and the length of the orbit cycle, say 3. It then iterates until the sequence converges to a, and then uses the iteration number modulo 3 to determine the color. ; ; ~Topic=Trig Identities ~Online- TRIG IDENTITIES ~Online+ The following trig identities are invaluable for coding fractals that use complex-valued transcendental functions of a complex variable in terms of real-valued functions of a real variable, which are usually found in compiler math libraries. In what follows, we sometimes use "*" for multiplication, but leave it out when clarity is not lost. We use "^" for exponentiation; x^y is x to the y power. ~Format- (u+iv) + (x+iy) = (u+x) + i(v+y) (u+iv) - (x+iy) = (u-x) + i(v-y) (u+iv) * (x+iy) = (ux - vy) + i(vx + uy) (u+iv) / (x+iy) = ((ux + vy) + i(vx - uy)) / (x^2 + y^2) e^(x+iy) = (e^x) (cos(y) + i sin(y)) log(x+iy) = (1/2)log(x^2 + y^2) + i(atan(y/x) + 2kPi) for k = 0, -1, 1, -2, 2, ... (The log function refers to log base e, or ln. The expression atan(y/x) is an angle between -pi and pi in the quadrant containing (x,y) implemented in C as the atan2() function.) z^w = e^(w*log(z)) sin(x+iy) = sin(x)cosh(y) + i cos(x)sinh(y) cos(x+iy) = cos(x)cosh(y) - i sin(x)sinh(y) tan(x+iy) = sin(x+iy) / cos(x+iy) sinh(x+iy) = sinh(x)cos(y) + i cosh(x)sin(y) cosh(x+iy) = cosh(x)cos(y) + i sinh(x)sin(y) tanh(x+iy) = sinh(x+iy) / cosh(x+iy) cosxx(x+iy) = cos(x)cosh(y) + i sin(x)sinh(y) (cosxx is present in Fractint to provide compatibility with a bug which was in its cos calculation before version 16) sin(2x) sinh(2y) tan(x+iy) = ------------------ + i------------------ cos(2x) + cosh(2y) cos(2x) + cosh(2y) sin(2x) - i*sinh(2y) cotan(x+iy) = -------------------- cosh(2y) - cos(2x) sinh(2x) sin(2y) tanh(x+iy) = ------------------ + i------------------ cosh(2x) + cos(2y) cosh(2x) + cos(2y) sinh(2x) - i*sin(2y) cotanh(x+iy) = -------------------- cosh(2x) - cos(2y) asin(z) = -i * log(i*z+sqrt(1-z*z)) acos(z) = -i * log(z+sqrt(z*z-1)) atan(z) = i/2* log((1-i*z)/(1+i*z)) asinh(z) = log(z+sqrt(z*z+1)) acosh(z) = log(z+sqrt(z*z-1)) atanh(z) = 1/2 * log((1+z)/(1-z)) sqr(x+iy) = (x^2-y^2) + i*2xy sqrt(x+iy) = sqrt(sqrt(x^2+y^2)) * (cos(atan(y/x)/2) + i sin(atan(y/x)/2)) ident(x+iy) = x + iy conj(x+iy) = x - iy recip(x+iy) = (x-iy) / (x^2+y^2) flip(x+iy) = y + ix zero(x+iy) = 0 one(x+iy) = 1 cabs(x+iy) = sqrt(x^2 + y^2) floor(x+iy) = floor(x) + i*floor(y) ceil(x+iy) = ceil(x) + i*ceil(y) trunc(x+iy) = trunc(x) + i*trunc(y) round(x+iy) = round(x) + i*round(y) ~Format+ Fractint's definitions of abs(x+iy) and |x+iy| below are non-standard. Math texts define both absolute value and modulus of a complex number to be the same thing. They are both equal to cabs(x+iy) as defined above. ~Format- |x+iy| = x^2 + y^2 abs(x+iy) = sqrt(x^2) + i sqrt(y^2) ; ; ; ~Topic=Quaternion and Hypercomplex Algebra Quaternions are four dimensional generalizations of complex numbers. They almost obey the familiar field properties of real numbers, but fail the commutative law of multiplication, since x*y is not generally equal to y*x. Quaternion algebra is most compactly described by specifying the rules for multiplying the basis vectors 1, i, j, and k. Quaternions form a superset of the complex numbers, and the basis vectors 1 and i are the familiar basis vectors for the complex algebra. Any quaternion q can be represented as a linear combination q = x + yi + zj + wk of the basis vectors just as any complex number can be written in the form z = a + bi. ~Format- Multiplication rules for quaternion basis vectors: ij = k jk = i ki = j ji = -k kj = -i ik = -j ii = jj = kk = -1 ijk = -1 Note that ij = k but ji = -k, showing the failure of the commutative law. The rules for multiplying any two quaternions follow from the behavior of the basis vectors just described. However, for your convenience, the following formula works out the details. Let q1 = x1 + y1i + z1j + w1k and q2 = x2 + y2i + z2j + w2k. Then q1q2 = 1(x1x2 - y1y2 - z1z2 - w1w2) + i(y1x2 + x1y2 - w1z2 + z1w2) + j(z1x2 + w1y2 + x1z2 - y1w2) + k(w1x2 + z1y2 - y1z2 + x1w2) ~Format+ Quaternions are not the only possible four dimensional supersets of the complex numbers. William Rowan Hamilton, who discovered quaternions in 1843, considered the alternative called the hypercomplex number system. Unlike quaternions, the hypercomplex numbers satisfy the commutative law of multiplication. The law which fails is the field property that states that all non-zero elements of a field have a multiplicative inverse. For a non-zero hypercomplex number h, the multiplicative inverse 1/h does not always exist. As with quaternions, we will define multiplication in terms of the basis vectors 1, i, j, and k, but with subtly different rules. ~Format- Multiplication rules for hypercomplex basis vectors: ij = k jk = -i ki = -j ji = k kj = -i ik = -j ii = jj = -kk = -1 ijk = 1 Note that now ij = k and ji = k, and similarly for other products of pairs of basis vectors, so the commutative law holds. Hypercomplex multiplication formula: Let h1 = x1 + y1i + z1j + w1k and h2 = x2 + y2i + z2j + w2k. Then h1h2 = 1(x1x2 - y1y2 - z1z2 + w1w2) + i(y1x2 + x1y2 - w1z2 - z1w2) + j(z1x2 - w1y2 + x1z2 - y1w2) + k(w1x2 + z1y2 + y1z2 + x1w2) As an added bonus, we'll give you the formula for the reciprocal. Let det = [((x-w)^2+(y+z)^2)((x+w)^2+(y-z)^2)] Then 1/h = 1[ x(x^2+y^2+z^2+w^2)-2w(xw-yz)]/det + i[-y(x^2+y^2+z^2+w^2)-2z(xw-yz)]/det + j[-z(x^2+y^2+z^2+w^2)-2y(xw-yz)]/det + k[ w(x^2+y^2+z^2+w^2)-2x(xw-yz)]/det ~Format+ A look at this formula shows the difficulty with hypercomplex numbers. In order to calculate 1/h, you have to divide by the quantity det = [((x-w)^2+(y+z)^2)((x+w)^2+(y-z)^2)]. So when this quantity is zero, the multiplicative inverse will not exist. Hypercomplex numbers have an elegant generalization of any unary complex valued function defined on the complex numbers. First, note that hypercomplex numbers can be represented as a pair of complex numbers in the following way. ~Format- Let h = x + yi + zj + wk. a = (x-w) + i(y+z) b = (x+w) + i(y-z) ~Format+ The numbers a and b are complex numbers. We can represent h as the pair of complex numbers (a,b). Conversely, if we have a hypercomplex number given to us in the form (a,b), we can solve for x, y, z, and w. The solution to ~Format- c = (x-w) + i(y+z) d = (x+w) + i(y-z) is x = (real(c) + real(d))/2 y = (imag(c) + imag(d))/2 z = (imag(c) - imag(d))/2 w = (real(d) - real(c))/2 ~Format+ We can now, for example, compute sin(h). First compute the two complex numbers a and b as above, then set c = sin(a) and d = sin(b) where sin() is the complex version of the sin function. Now use the equations above to solve for x, y, z, and w in terms of c and d. The hypercomplex number (x,y,z,w) thus obtained is sin(h). The beauty of this is that it really doesn't make any difference what function we use. Instead of sin, we could have used cos, sinh, ln, or z^2. Using this technique, Fractint can create 3-D fractals using the formula h' = fn(h) + c, where "fn" is any of the built-in functions. Where fn is sqr(), this is the famous mandelbrot formula, generalized to four dimensions. For more information, see _Fractal Creations, Second Edition_ by Tim Wegner and Bert Tyler, Waite Group Press, 1993. ; ; ; ~Topic=GIF Save File Format Since version 5.0, Fractint has had the ave-to-disk command, which stores screen images in the extremely compact, flexible .GIF (Graphics Interchange Format) widely supported on CompuServe. Version 7.0 added the estore-from-disk capability. Until version 14, Fractint saved images as .FRA files, which were a non-standard extension of the then-current GIF87a specification. The reason was that GIF87a did not offer a place to store the extra information needed by Fractint to implement the feature -- i.e., the parameters that let you keep zooming, etc. as if the restored file had just been created in this session. The .FRA format worked with all of the popular GIF decoders that we tested, but these were not true GIF files. For one thing, information after the GIF terminator (which is where we put the extra info) has the potential to confuse the online GIF viewers used on CompuServe. For another, it is the opinion of some GIF developers that the addition of this extra information violates the GIF87a spec. That's why we used the default filetype .FRA instead. Since version 14, Fractint has used a genuine .GIF format, using the GIF89a spec - an upwardly compatible extension of GIF87a, released by CompuServe on August 1 1990. This new spec allows the placement of application data within "extension blocks". In version 14 we changed our default savename extension from .FRA to .GIF. There is one significant advantage to the new GIF89a format compared to the old GIF87a-based .FRA format for Fractint purposes: the new .GIF files may be uploaded to the CompuServe graphics forums fractal information intact. Therefore anyone downloading a Fractint image from CompuServe will also be downloading all the information needed to regenerate the image. Fractint can still read .FRA files generated by earlier versions. If for some reason you wish to save files in the older GIF87a format, for example because your favorite GIF decoder has not yet been upgraded to GIF89a, use the command-line parameter "GIF87a=yes". Then any saved files will use the original GIF87a format without any application-specific information. An easy way to convert an older .FRA file into true .GIF format suitable for uploading is something like this at the DOS prompt:\ FRACTINT MYFILE.FRA SAVENAME=MYFILE.GIF BATCH=YES\ Fractint will load MYFILE.FRA, save it in true .GIF format as MYFILE.GIF, and return to DOS. GIF and "Graphics Interchange Format" are trademarks of CompuServe Incorporated, an H&R Block Company. ; ; ; ~Topic=Using Fractint With a Mouse ; This topic is online only. ~FormatExclude- Left Button: Brings up and sizes the Zoom Box. While holding down the left button, push the mouse forward to shrink the Zoom Box, and pull it back to expand it. Double-clicking the left button performs the Zoom. Right Button: While holding the right button held down, move the mouse from side to side to 'rotate' the Zoom Box. Move the mouse forward or back to change the Zoom Box color. Double-clicking the right button performs a 'Zoom-Out'. Both Buttons: (or the middle button, if you have three of them) While holding down both buttons, move the mouse up and down to stretch/shrink the height of the Zoom Box, or side to side to 'squish' the Zoom Box into a non-rectangular shape. Zoom and Pan using the mouse typically consists of pushing in the left button, sizing the zoom box, letting go of the button, panning to the general area, then double-clicking the left button to perform the Zoom. For details of a special mode that takes advantage of the mouse when palette editing see {Freestyle mode tutorial} ; ; ; ~Topic=Selecting a video mode when loading a file, Label=HELPLOADFILE ; This topic is only online, context-sensitive. ~Format- The most suitable video modes for the file are listed first. The 'err' column in the video mode information indicates: blank mode seems perfect for this image v image smaller than screen, will be loaded in a iew window c mode has more colors than image needs * a major problem, one or more of the following is also shown: C mode has too few colors R image larger than screen, Fractint will reduce the image, possibly into a iew window, and maybe with aspect ratio a bit wrong A mode has the wrong shape of pixels for this image ; ; ; ~Topic=Distribution of Fractint ~Format-,Online- DISTRIBUTION OF FRACTINT ~Format+,Online+ New versions of FRACTINT are uploaded to the Fractint developer's web site at www.fractint.org, and make their way to other systems from that point. FRACTINT is available as two self-extracting archive files - FRAINT.EXE (executable & documentation) and FRASRC.EXE (source code). The latest developer's version can also be found at www.fractint.org. Many other sites tend to carry these files shortly after their initial release (although sometimes using different naming conventions). Look for frainnn.zip (executable package) and frasrnnn.zip (source), where nnn is the release number. Major releases with two digit numbers have names such as fraintnn.zip and frasrcnn.zip. On the Internet, try the Noel Giffin's Spanky Fractal Database. Using a Web browser, go to: \ http://spanky.triumf.ca/pub/fractals/programs/ibmpc/frainxxx.zip\ where xxx is the release number. Via FTP, login to spanky.triumf.ca as ANONYMOUS, and change directories to [pub.fractals.programs.ibmpc], then download frainxxx.zip. (The directory syntax is in VAX format.) The X Windows port of Fractint was written by Ken Shirriff and is available via FTP from http://spanky.triumf.ca/pub/fractals/programs/unix/XFRACTxxx.zip\ where xxx is the Xfractint release number. Developer's versions of Xfractint are available at the Fractint developer's web site. ; ; ~Topic=Contacting the Authors ~Format-,Online- CONTACTING THE AUTHORS ~Format+,Online+ Communication between the authors for development of the next version of Fractint takes place in the fractint mailing list. The following authors have agreed to the distribution of their addresses. Usenet/Internet/Bitnet/Whatevernet users can reach CIS users directly if they know the user ID. Postal addresses are listed below so that you have a way to send bug reports and ideas to the Stone Soup team. Please understand that we receive a lot of mail, and because of the demands of volunteer work on Fractint as well as our professional responsibilities, we are generally unable to answer it all. Several of us have reached the point where we can't answer any conventional mail. We *do* read and enjoy all the mail we receive, however. If you need a reply, the best thing to do is use email, which we are generally able to answer, or better yet, leave a message on the fractint list. Tim Wegner now runs a mailing list for fractint users to swap ideas and par data, you can subscribe by emailing mailman@mailman.xmission.com with the line:\ subscribe fractint\ as the sole content of the message, you'll receive further instructions by return of email. (This address list has been pruned of names of folks we haven't heard from in a while. If your name has been removed, and you'd like to be listed, just let us know and we'll add it back.) ~FF Current main authors: ~Format- Timothy Wegner twegner@fractint.org 4714 Rockwood Houston, TX 77004 (713) 747-7543 Jonathan Osuch josuch@fractint.org 2110 Northview Drive Marion, IA 52302 Contributing authors' addresses (in alphabetic order). Prof Jm Collard-Richard jmc@math.ethz.ch Paul de Leeuw 16 Sunset Street Wyoming NSW 2250 Australia +61-2-8293-3055 (Work) +61-2-4329-0870 (Home) ~OnlineFF Sylvie Gallet sylvie.gallet1@libertysurf.fr Lee H. Skinner skinner@thuntek.net P.O. Box 14944 Albuquerque, NM 87191 (505) 293-5723 Bert Tyler bert.tyler@oef.com Tyler Software 124 Wooded Lane Villanova, PA 19085 (610) 525-5478 ~Format+ ; ; ~Topic=The Stone Soup Story ~Format-,Online- THE STONE SOUP STORY ~Format+,Online+ Once upon a time, somewhere in Eastern Europe, there was a great famine. People jealously hoarded whatever food they could find, hiding it even from their friends and neighbors. One day a peddler drove his wagon into a village, sold a few of his wares, and began asking questions as if he planned to stay for the night. [No! No! It was three Russian Soldiers! - Lee Crocker]\ [Wait! I heard it was a Wandering Confessor! - Doug Quinn]\ [Well *my* kids have a book that uses Russian Soldiers! - Bert]\ [Look, who's writing this documentation, anyway? - Monte]\ [Ah, but who gets it *last* and gets to upload it? - Bert]\ "There's not a bite to eat in the whole province," he was told. "Better keep moving on." "Oh, I have everything I need," he said. "In fact, I was thinking of making some stone soup to share with all of you." He pulled an iron cauldron from his wagon, filled it with water, and built a fire under it. Then, with great ceremony, he drew an ordinary-looking stone from a velvet bag and dropped it into the water. By now, hearing the rumor of food, most of the villagers had come to the square or watched from their windows. As the peddler sniffed the "broth" and licked his lips in anticipation, hunger began to overcome their skepticism. "Ahh," the peddler said to himself rather loudly, "I do like a tasty stone soup. Of course, stone soup with CABBAGE -- that's hard to beat." Soon a villager approached hesitantly, holding a cabbage he'd retrieved from its hiding place, and added it to the pot. "Capital!" cried the peddler. "You know, I once had stone soup with cabbage and a bit of salt beef as well, and it was fit for a king." The village butcher managed to find some salt beef...and so it went, through potatoes, onions, carrots, mushrooms, and so on, until there was indeed a delicious meal for all. The villagers offered the peddler a great deal of money for the magic stone, but he refused to sell and traveled on the next day. And from that time on, long after the famine had ended, they reminisced about the finest soup they'd ever had. *** That's the way Fractint has grown, with quite a bit of magic, although without the element of deception. (You don't have to deceive programmers to make them think that hours of painstaking, often frustrating work is fun... they do it to themselves.) It wouldn't have happened, of course, without Benoit Mandelbrot and the explosion of interest in fractal graphics that has grown from his work at IBM. Or without the example of other Mandelplotters for the PC. Or without those wizards who first realized you could perform Mandelbrot calculations using integer math (it wasn't us - we just recognize good algorithms when we steal--uhh--see them). Or those graphics experts who hang around the CompuServe PICS forum and keep adding video modes to the program. Or... ~Doc- (continued in {A Word About the Authors}) ~Doc+ ; ; ~Topic=A Word About the Authors ~Format-,Online- A WORD ABOUT THE AUTHORS ~Format+,Online+ Fractint is the result of a synergy between the main authors, many contributors, and published sources. All of the main authors have had a hand in many aspects of the code. However, each author has certain areas of greater contribution and creativity. Since there is not room in the credits screen for the contributions of the main authors, we list these here to facilitate those who would like to communicate with us on particular subjects. Main Authors of Version 19 and later. BERT TYLER is the original author of Fractint. He wrote the "blindingly fast" 386-specific 32 bit integer math code and the original video mode logic. Bert made Stone Soup possible, and provides a sense of direction when we need it. His forte is writing fast 80x86 assembler, his knowledge of a variety of video hardware, and his skill at hacking up the code we send him! Bert has a BA in mathematics from Cornell University. He has been in programming since he got a job at the computer center in his sophomore year at college - in other words, he hasn't done an honest day's work in his life. He has been known to pass himself off as a PC expert, a UNIX expert, a statistician, and even a financial modeling expert. He is currently masquerading as an independent PC consultant, supporting the PC- to-Mainframe communications environment at NIH. If you sent mail from the Internet to an NIH staffer on his 3+Mail system, it was probably Bert's code that mangled it during the Internet-to-3+Mail conversion. He also claims to support the MS-Kermit environment at NIH. Fractint is Bert's first effort at building a graphics program. TIM WEGNER contributed the original implementation of palette animation, and is responsible for most of the 3D mechanisms. He provided the main outlines of the "StandardFractal" engine and data structures, and is accused by his cohorts of being "obsessed with options". One of Tim's main interests is the use of four dimensional algebras to produce fractals. Tim served as team coordinator for version 19, and integrated Wes Loewer's arbitrary precision library into Fractint. Tim has BA and MA degrees in mathematics from Carleton College and the University of California Berkeley. He worked for 7 years overseas as a volunteer, doing things like working with Egyptian villagers building water systems. Since returning to the US in 1982, he has written shuttle navigation software, a software support environment prototype, and supported strategic information planning, all at NASA's Johnson Space Center. After a two-year stint at full-time writing, he's back at NASA developing shuttle navigation software. JONATHAN OSUCH started throwing pebbles into the soup around version 15.0 with a method for simulating an if-then-else structure using the formula parser. He has contributed the fn||fn fractal types, the built-in bailout tests, the increase in both the maximum iteration count and bailout value, and bug fixes too numerous to count. Jonathan worked closely with Robin Bussell to implement Robin's browser mechanism in Fractint. Jonathan has a B.S. in Physics from the University of Dubuque and a B.S. in Computer Science from Mount Mercy College, both in Iowa. He is currently working as a consultant in the nuclear power industry. WES LOEWER first got his foot in the Stone Soup door by writing fast floating point assembler routines for Mandelbrot, Julia, and Lyapunov fractals. He also rewrote the boundary trace algorithms and added the frothybasin fractal. His most significant contribution is the addition of the arbitrary precision library which allows Fractint to perform incredibly deep zooms. Wes has a B.S. in Physics from Wheaton College in Illinois. He also holds an M.S. in Physics and an M.Ed. in Education from Texas A&M University. Wes teaches physics and math at McCullough High School in The Woodlands, Texas where his pupils inspire him to keep that sense of amazement that students get when they understand a physical or mathematical principle for the first time. Since he uses Fractint to help teach certain mathematical principles, he's one of the few folks who actually gets to use Fractint on the job. Besides his involvement with Fractint, Wes is the author of WL-Plot, an equation graphing program, and MatCalc, a matrix calculator program. GEORGE MARTIN first became known to Fractint users when he brought a modicum of order to the chaotic world of formula postings with his release of the Orgform program and formula compilation. George added IF..ELSE to the formula parser language for version 19.6. Among his other contributions are the ability to include formula, ifs, and lsystem entries in .par files, the scrolling of text in the and F2 screens, and new autokey commands. George received an A.B. in Economics from Dartmouth College and a J.D from the University of Michigan. When not playing with Fractint, he practices law in a small village about 40 miles northwest of Detroit. ROBIN BUSSELL began contributing to fractint in rudimentary fashion with the autologmap routine and has been producing more and more complex interface enhancements as he gets better at what he refers to as 'this C programming lark' He is always grateful for the help the rest of the team have given in smoothing the rough edges of the ingredients he adds to the soup and regards the evolver feature as his greatest achievement to date. Robin had far too much fun at college in London to actually get any qualifications there and has since worked his way up from a workshop job fixing computers back in the final days of CPM, via some interesting work with Transputers ( an innovative British cpu that was designed to run in massively parallel configurations, and made a very good Mandlebrot set calculating machine when a few dozen or more were set to the task) , through to his current position of senior engineer for a third party suppport company where he spends his time travelling the south west of Britain sorting out peoples IT problems. Anyone wishing to offer him interesting work in anything to do with computers can find a CV at: http://web.ukonline.co.uk/robin.b2/rbcv.htm When not playing with computers Robin likes to relax by experimenting with kite powered traction and can often be found hurtling around the local beaches on the end of a few square metres of fabric and carbon fibre in various configurations. ; ; ~Topic=Other Fractal Products (Forgive us, but we just *have* to begin this section with a plug for *our* fractal products even though the books are now out of print and hard to find ...) Several of Fractint's programmers have written books about fractals, Fractint, and Winfract (the Windows version of Fractint). The book about Fractint is Fractal Creations Second Edition (1994 Waite Group Press, ISBN # 1-878739-34-4). The book about Winfract is The Waite Group's Fractals for Windows (1992 Waite Group Press, ISBN # 1-878739-25-5). These books are now very hard to find, so if you see one, better get it! ~Format- Fractal Creations Second Edition includes: o A guided tour of Fractint. o A detailed manual and reference section of commands. o A tutorial on fractals. o A reference containing tips, explanations, and examples of parameters for all the Fractals generated by Fractint/Winfract. o Secrets on how the programs work internally. o Spectacular color plate section. o A CD containing Fractint and Xfract source and executable, and over a thousand spectacular fractal images. o A complete copy of the source code with a chapter explaining how the program works. ~Format+ ; ; ~OnlineFF Several Fractint enthusiasts are selling Fractal CDs. One of the best are called "Fractal Dimensions" by Lee Skinner. Highly recommended original artwork in a variety of graphics formats. You can receive the "Fractal Dimensions CD" by sending $19.95US + $5.00 S&H (or $10.00 S&H outside USA) to Lee H. Skinner P. O. Box 14944 Albuquerque, NM 87191-4944 USA ~OnlineFF Michael Peters and Randall Scott have written a fractal program called HOP based on the Martin orbit fractals. This program is much narrower than Fractint in the kind of thing that it does, but has many more animation effects and makes a great screen saver. Michael sent us the algorithms for the chip, quadruptwo, and threeply fractal types to give us a taste. The file is called HOPZIP.EXE in LIB 9 of CompuServe's DIGART forum. Michael has also written a handy utility called PARTOBAT which creates a batch file for generating all the images in a Fractint PAR file. George Martin has written a useful formula file organizing program, distributed as ORGFRM.ZIP, which also includes a comprehensive collection of formulas. More than 15,000 formulas written by Fractint users are included in the compilation, arranged alphabetically by name, and with the original source file shown in each formula by comment, making the compilation an encyclopedia of formulas written for Fractint. The most recent version of ORGFRM.ZIP is available at the CompuServe site, and at Noel Giffin's web page described in the next paragraph. The package includes a utility program, orgform.exe, which copies the formulas of ".frm" files into the compilation, skipping those formulas which are already included in the compilation. Formula writers are urged to consult this compilation in order to avoid giving a new formula an existing formula name. George can be reached at [76440,1143], or ggmartin@compuserve.com. Robin Bussell has knocked together a windows front end for fractint that makes rendering images from par information recieved in email a simple operation. Download it for free from http://web.ukonline.co.uk/robin.b2/pastengo.htm or check compuserve for pastengo.zip Noel Giffin (noel@triumf.ca), maintains a terrific web page for Fractint and fractals in general at spanky.triumf.ca. Highly recommended. His pages on arbitrary precision gleaned from sci.fractals and corresponence are required reading. ; ; ; ~Topic=Bibliography BARNSLEY, Michael: "Fractals Everywhere," Academic Press, 1988. DAVENPORT, Clyde: "A Hypercomplex Calculus with Applications to Relativity", ISBN 0-9623837-0-8. This self-published expansion of Mr. Davenport's Master's thesis makes the case for using hypercomplex numbers rather than quaternions. This book provided the background for Fractint's implementation of hypercomplex fractals. DEWDNEY, A. K., "Computer Recreations" columns in "Scientific American" -- 8/85, 7/87, 11/87, 12/88, 7/89. FEDER, Jens: "Fractals," Plenum, 1988.\ Quite technical, with good coverage of applications in fluid percolation, game theory, and other areas. GLEICK, James: "Chaos: Making a New Science," Viking Press, 1987.\ The best non-technical account of the revolution in our understanding of dynamical systems and its connections with fractal geometry. ~OnlineFF MANDELBROT, Benoit: "The Fractal Geometry of Nature," W. H. Freeman & Co., 1982.\ An even more revised and expanded version of the 1977 work. A rich and sometimes confusing stew of formal and informal mathematics, the prehistory of fractal geometry, and everything else. Best taken in small doses. MANDELBROT, Benoit: "Fractals: Form, Chance, and Dimension," W. H. Freeman & Co., 1977.\ A much revised translation of "Les objets fractals: forme, hasard, et dimension," Flammarion, 1975. PEITGEN, Heinz-Otto & RICHTER, Peter: "The Beauty of Fractals," Springer- Verlag, 1986.\ THE coffee-table book of fractal images, knowledgeable on computer graphics as well as the mathematics they portray. PEITGEN, Heinz-Otto & SAUPE, Ditmar: "The Science of Fractal Images," Springer-Verlag, 1988.\ A fantastic work, with a few nice pictures, but mostly filled with *equations*!!! PICKOVER, Clifford: "Computers, Pattern, Chaos, and Beauty," St. Martin's Press, 1990.\ SCHROEDER, Manfred: "Fractals, Chaos, Power Laws," W. H. Freeman & Co., 1991.\ WEGNER, Timothy: "Image Lab, Second Edition", Waite Group Press, 1995.\ Learn how to create fractal animations, fractal RDS stereo images, and how to use Fractint with other image creation and processing tools such as Piclab, POV-Ray and Polyray ray tracers. WEGNER, Timothy & TYLER, Bert: "Fractal Creations, Second Edition" Waite Group Press, 1993\ This is the definitive Fractint book. Spectacular color plate section, totally new and expanded fractal type descriptions, annotated PAR files, source code secrets, and a CD filled to the brim with spectacular fractals. WEGNER, Timothy, TYLER, Bert, PETERSON, Mark, and Branderhorst, Pieter: "Fractals for Windows," Waite Group Press, 1992.\ This book is to Winfract (the Windows version of Fractint) what "Fractal Creations" is to Fractint. ; ; ~Topic=Other Programs ~Label=@FDESIGN FDESIGN, by Doug Nelson (CIS ID 70431,3374) - a freeware IFS fractal generator available from CompuServe in DIGART LIB 9, and probably on your local BBS. This program requires a VGA adapter and a Microsoft-compatible mouse, and a floating point coprocessor is highly recommended. It generates IFS fractals in a *much* more intuitive fashion than Fractint. It can also (beginning with version 3.0) save its IFS formulas in Fractint-style .IFS files. BRAZIL Fractal Generator by David CHARDONNET - A freeware IFS fractal generator and animator for Windows 95 and Win/NT 4.0 shares common fractal description language for sharing fractals between fractint and this program. It can be downloaded from his website:\ http://www.geocities.com/CapeCanaveral/Lab/1837/index_a.html FRACTINT SCREEN SAVER by Thore Berntsen. This freeware screen saver works with Fractint. Check this out at:\ http://home.sol.no/\~thbernt/fintsave.htm\ ~OnlineFF The following pieces of software are pretty old now, but for now these references are still here. Winfract is based on on old version of Fractint and is no longer maintained. WINFRACT. Bert Tyler has ported Fractint to run under Windows 3. The same underlying code is used, with a Windows user interface. Winfract has almost all the functionality of Fractint - the biggest difference is the absence of a zillion weird video modes. Fractint for DOS will continue to be the definitive version. Winfract is available from CompuServe in DIGART LIB 9, as WINFRA.ZIP (executable) and WINSRC.ZIP (source). PICLAB, by Lee Crocker - a freeware image manipulation utility available from CompuServe in PICS Lib 10, as PICLAB.EXE. PICLAB can do very sophisticated resizing and color manipulation of GIF and TGA files. It can be used to reduce 24 bit TGA files generated with the Fractint "lightname" option to GIF files. ~OnlineFF ~Label=@ACROSPIN ACROSPIN, by David Parker - An inexpensive commercial program that reads an object definition file and creates images that can be rapidly rotated in three dimensions. The Fractint "orbitsave=yes" option creates files that this program can read for orbit-type fractals and IFS fractals. Contact: David Parker 801-966-2580\ P O Box 26871 800-227-6248\ Salt Lake City, UT 84126-0871 ; ; ~Topic=Sound Controls, label=HELPSOUND On this screen, accessed by hitting ctrl-F, you'll find a few parameters that you recognise from the 'x' menu handily gathered together, plus a few new ones. You can find the descriptions for the basic parms over at the {Sound Parameters} help. The newer parameters now control whether fractint uses the PC speaker for sound, as in previous versions, or the output of a sound card, or both. Your present Sound card may boast all manner of gizmos and wotnots but fractint may well not be able to take advantage of them, this is simply due to our not including umpteen different drivers for all the different cards. Instead it just uses a simple approach that at least allows you to use multimedia speakers for the various noises of which fractint is capable. This DOS version of fractint uses the current lowest common denominator hardware among the variety of sound cards available, the yamaha OPL-3 FM synthesizer chipset which is found in most sound cards from the original AdLib, through the various soundblasters from creative labs, to the numerous cards that emulate them. The OPL-3 chipset has within it several 'voices', each capable of generating sound independently of the others, and with a variety of controllable parameters. See {Advanced Sound Controls} for details. The sound card volume control given here will be overridden by any volume control applications that come with your OS, such as the windows 95 mixer control panel. Also, depending on your sound card and software, the output of the OPL-3 chipset may be controlled by a slider named 'synth', 'midi', or possibly 'legacy'... if in doubt, experiment :-) The other parameter that needs explaining here is note pitch quantisation. When this is enabled, tones that are to be played are first rounded to the nearest note on the western even tempered scale (i.e. the notes that you find on a piano) as opposed to the full spectrum of frequencies. The {Advanced Sound Controls} screen also has a facility to restrict the notes played further so that you can produce tunes in a particular key, if you're so inclined. ; ; ~Topic=Advanced Sound Controls, Label=HELPMUSIC The soundcard output from fractint is a tad more versatile than the simple tones of the PC speaker. This comes into its own when playing sounds based on fractal orbits, producing results from haunting chordal pulses through to unearthly arpeggios. The voices used to generate notes on the sound card have variable {Envelopes} and can be played polyphonically so we have three parameters to vary the sounds produced: POLYPHONY=nn\ This controls how many different note are allowed to sound at once, voices are assigned cyclically as notes are played: i.e. after the first orbit is calculated a frequency is assigned to the first voice and that note is triggered on. Fractint then waits for one orbitdelay period, calculates the next orbit, assigns a frequency to the second voice, and triggers it on. This continues until the number of voices sounding is equal to the polyphony value whereupon the first selected voice is triggered off and the note allowed to decay. That probably all sounds horrendously complex but just think of it as playing the organ, holding down each new note for as long as possible but with the polyphony value controlling how many fingers you have. WAVETYPE=nn\ ~Format- WaveForm 0: Sine WaveForm 1: Half-Sine | /^\\ | /^\\ /^\\ |/ \\ / |/ \\ / \\ /\\/ |----- | \\ / | | \\_/ | WaveForm 2: Abs-Sine WaveForm 3: Pulse-Sine | /^\\ /^\\ | /^| /^| |/ \\ / \\ / |/ | / | | |------- | | WaveForm 4: Sine - even periods only | /^\\ /^\\ |/ \\ / \\ |\\-----------\\ | \\ / \\ / | \\_/ \\_/ WaveForm 5: Abs-Sine - even periods only | /^\\ /^\\ /^\\ /^\\ |/ \\ / \\ / \\ / \\ |----------- | WaveForm 6: Square |----- ----- ----- - | | | | | | | ||||||| | | | | | | | | ----- ----- ----- WaveForm 7: Derived Square | |\\ |\\ | | \\ | \\ |--__|\\------__|\\------ | \\ | \\ | | \\| \\| ~Format+ ATTACK=nn\ This controls the time taken for a note to hit full volume after being triggered on. Low values give a punchy percussive sound while long values give a softer bowed sound. If attack time is set too long and orbitdelay is low then notes are played too fast to ever achieve any volume and the net result is low or non existent output. To put it another way, if orbitdelay is low then this value should be low also. DECAY=nn\ This controls the time taken for a note to die down to the sustain level. Setting this time too low may produce a rhythmic click between notes. The attack and decay values don't allow much fine control. SUSTAIN=nn\ This controls the volume level at which a note is held. SRELEASE=nn\ This controls the delay in time for releasing a note. A release value of 15 seems to equate to 'never let the note release' on the machine used to develop the sound card drivers. But, as ever, with other manufacturer's emulations your mileage may vary. VOLUME=nn\ It is possible to adjust the volume of an FM synth card. This has no effect on the PC speaker. ATTENUATE=none|low|mid|high\ On an FM synth card it is possible to attenuate the high pitched notes. The default is none. The low value attenuates at 1.5 dB/octave, the mid at 3.0 dB/octave, and the high at 6.0 dB/octave. SCALEMAP=nn/nn/nn/...\ The scale map list is a way of controlling which notes are played by fractint and only has any effect if note quantisation is switched on in the basic sound parameters screen. It can be very useful when the polyphony is up and the chords you're getting are more like dischords. :-) The way it works is this: When a sound is played with frequency quantisation on its frequency is rounded to the nearest 'proper' note on the musical scale, this note number is then looked up in the scale map table and substituted by the note indicated in that entry of the table. The end result of this is that, for instance, using this sequence of numbers as a scale map: \ 2,2,4,4,4,7,7,9,9,11,11,11 \ Will ensure that fractint uses only the black notes on the keyboard, just the sharps and flats for a vaguely oriental feel (to my western ears anyway :-) ). The above probably appears to be sheer gobbledegook at first reading, sorry, but if you keep at it you'll unlock this powerful feature for keeping your fractals melodic. (Unless you're totally turned on by microtonal frequencies in which case forget all this quantisation nonsense and tune in to the true sound of chaos!) The passes=1 setting ({Drawing Method}) almost always works best with sound. ~Topic=Envelopes Here's some more information about the concept of a note envelope for those unfamiliar with sound synthesis terminology, it's all about how the dynamics of a note are defined (i.e the way in which the loudness changes during the life of a note) Graph of a note's volume during it's life cycle: /\\______ /\\_______ \ __/ \\_____ ... _______/ \\_________ \ 0011111111110000000 ... 0000000111111111110000000000 \ A D S R AAADSSSSSSSR \ The string of 0's and 1's represents the keyon/off state of the voice, 1's indicate the key being held down. The attack, decay, sustain, and release portions of the envelope are represented by ADSR, this is what happens: When the note is first triggered on the volume rises to peak volume at a rate determined by the attack value. Once at the full level the decay period starts and the volume dies down (at a rate set by the decay value) to a level that is set by the sustain value. The note continues to sound at this volume until triggered off (the 'key' is released) whereupon it dies down to zero volume at the release rate. And so on. Now, with the current voice assignment method, while orbits are being generated continuously, timing looks like this (with four note polyphony in this example) Voice:\ 1 *111.....*111....\ 2 .*111.....*111...\ 3 ..*111.....*111..\ 4 ...*111.....*111.\ 5 ....*111.....*111\ 6 .....*111.....*11\ 7 ......*111.....*1\ 8 .......*111.....*\ 9 ........*111.....\ orbit: 12345678901234567\ Where:\ . = key off (silent or releasing note)\ * = note assigned a value and triggered on, attack, decay, sustain phase begins\ 1 = note held on, you'll notice that above there are only ever four notes held on at any one time, though more than four may be sounding if there is a long release value.\ ; ; ~Topic=Revision History Please select one of: {Version 20} {Version 19} {Version 18} {Version 17} {Version 16} {Version 15} {Versions 12 through 14} {Versions 1 through 11} ; ~Topic=Version 20 Version 20 (9/99) New features include: The new Fractal Evolver by Robin Bussell. This feature randomly perturbs fractal parameters in a user-controlled way, letting you see a screen full of postage-stamp variations of a fractal. See {=HELPEVOL Parameter explorer/evolver} New sound routines from Robin Bussell. Now brings up a menu for changing the sounds made by Fractint. The sound= prompt can now look like this: sound=off|beep|x|y|z/pc|fm/quant. See {Sound Parameters} New 32767 x 32767 (32K) pixel limit. Removed the 2048 pixel limit for the size of fractals. You can now define disk video modes larger than 2048 x 2048. Added the experimental synchronous orbits (a.k.a. SOI) "fractal witchcraft" algorithm invoked using passes=s. This algorithm optimizes the computation of very deeply zoomed fractals by calculating parallel orbits, and subdividing when the orbits break formation. See {Drawing Method} Other new features and changes include: When resuming in pass=1, the calculation is now restarted at the last X value, instead of at the beginning of the row. Fixed browser so browsing images won't make the current image non-resumable. During an image save to disk, the 's' key is now ignored. Added Humberto Baptista's Epsilon Cross variation. It is triggered with a negative proximity. With a positive proximity value, the result should be backwards compatable. This assumes no one has made images with a negative proximity. Changed the internal orbitdelay timer to use a new microsecond timer. Changed the logic for controlling sound and orbit speed to make it less machine dependent. Use debug=4020 to invoke the old timing logic. Modified autologmap so that it ignores symmetry. Made the sound= prompts and batch output match the docs. Made the colors= information put into PARs the last item in the PAR. Added capability for makepar command to detect viewwindows and add to PAR file. Turned off view windows when the window is either too large or too small. Added an auto calc feature for the final aspect ratio if it is set to zero and the x and y sizes are specified. Fixed corners drift of integer fractals by disabling the logic that attempts to keep the aspect fixed when zooming. The command no longer runs the backwards() routines unless debug=98. Added tangent domain protection to integer version of popcorn that prevents the "PI box" artifact. Brutal but works. ~OnlineFF Generalized popcorn and popcornjul. There's a lot of possibility in these new variations. The function variables are remembered as long as you stay within the popcorn family, otherwise they are set to defaults. The integer version has an artifact in the F3 mode, probably due to tan() being undefined. Included contributions from Humberto Baptista. These include Pickover's Latoocarfian fractal type, as well as a passes=d[iffusion] option. The parser colors variable is now initialized to 256. Fixed problem with the floating point Unity fractal type. Added Chuck Ebbert's parser speedup. Added checks for inside, outside, biomorph, and fillcolor entries larger than the number of colors. Added fix so that showorbit= can be turned off by restarting Fractint with . Adapted the browser so it would work with arbitrary precision images. Added cpu/fpu detection for 486 and up. Fixed the slow down of palette reset caused by slowing down color cycling. Fixed inside=zmag and =fmod for arbitrary precision. More mandel/julia FPU speedup by assembling the > 8087 code without the emulator fixups. This was also used to speedup the FPU parser code. The mandel/julia optimizations are a combination of contributions from Rees Acheson (author of MANDELB), Damien Jones, Agner Fog, Terje Mathisen, Thomas Jentzsch, and Daniele Paccaloni. Although it would be hard to identify any one person's contribution, they all played a great part in the pentium optimizations. Added inside=fmod and inside=atan. The inside=atan option should only be used with periodicity=0. Fixed a bug in loaddac() routine caused because bios doesn't zero top 8 entries when resetting the dac. Added two new features to command. You can now specify "only" at the "Record colors?", and added a maxlinelen field to specify how wide the parameter file can be. Added support for maps to makepar command. Try something like:\ fractint map=lyapunov makepar=mymaps Improved color map compression in PAR files. Debug=910 uses old method, otherwise uses Sylvie Gallet's fix. Debug=920 uses lossless compression for critical use. Removed a longstanding but unintended row limit of the encoder which resulted in an "interrupted" message when saving long (> 5000 rows) files. Fixed bug with LodRealPwr in formula parser. Speedkey now works with unsorted lists. Numbers in sound001.txt file names now increment. Added new based data type PFCODE which is a pointer to FCODE. This saves memory with the array of parser error messages. Fixed bug that caused lockup when extended memory is used without any expanded memory. Fixed a bug in the spacing of file names in the file selection menu. Added Rich Thomson's Xfractint fixes for Silicon Graphics. Fixed Julia pointer bug. Fixed a bug that caused the zoom box coordinates to be used if a doodad was changed with a zoom box on the screen. Formula type and inversion now work with large images. Fractint now does everything simplgifd does - make an appropriate diskvideo mode, then load and save a MIG!! Fixed a long standing bug in the popcorn fractal type and added backwards compatibility. Revised the popcorn type docs to clarify that when the view window is used, it is possible to see orbits outside the "box". Fixed a bug that was causing garbage to be read when a non-Fractint GIF image was read. Replaced the lzw logic with code based on the UNIX compress. This should eliminate very rare but very frustrating encoder problems. Added a function one() to formula parser, to complement ident() and zero(). The new function returns (1,0), and, like ident() and zero(), is only available as a choice for fn1, fn2, fn3 or fn4. Disabled symmetry for synchronous orbits. Moved encoder default color palettes from near memory to overlayed data. Changed the grid lookups to a function. Fixed diskvideo viewwindows bug. Moved zoom box function out of assembler to c. Changed the direction of single color cycling when in color cycling mode. Added command line option orgfrmdir=[directory path]. When used, Fractint's search for formulas will make a final check of the appropriate Orgform compilation file in the specified directory (e.g. for a formula with the name "abc", the only file searched in the specified directory will be _a.frm). This feature will significantly reduce the time taken to find a formula for users of the compilation. For more about the Orgform compilation, see { Other Fractal Products }. Added a new minstack= command. Default value is 1100. This is the minimum number of bytes returned by the stackavail() function required in order to do another SOI recursion. People who get bad SOI results at high resolutions should increase this value until the symptoms go away. Fixed the FPUatan bug that has been in the code in calmanfp.asm since it was written. It turns out that the major problem was that the FPU stack was being overrun. Rewrote the Mandelbrot FPU code. Fixed the FPU versions of inside= real, imag, mult, and summ. Incremented the version number so the fix could be backwards compatible. Added symmetry to Escher-Julia type. Editpal changes from Andrew McCarthy. Removed IIT coprocessor support. Parser changes: New code is only used to determine which functions and variables will appear at top of "z" screen for a formula. Variable names in formulas must now start with a letter or "_". Error checking of formulas expanded. Formulas in Orgform compilation caught by the new error checking have been rewritten. Fixed bug which appeared when an image entry and a formula in a .par file had the same name. Added support for formula type to SPACE Mandelbrot/Julia toggle. Implemented using new ismand parser constant. Added incremental redraw of images when maxiter is increased. This works on completed images that use inside=color. None of the other inside= options are supported. ~Topic=Version 19 Version 19.6 (5/97) new features include: Added new fractal types {=HT_ESCHER escher_julia} and {=HT_VL volterra-lotka} courtesy Michael Sargent. Expanded formula parser capability to recognize "if..else" flow control instructions. The format of an "if block" of instructions is: IF(boolean) statements ELSEIF(boolean) [any number of these are permitted in a block] statements ELSE [if used, only one is permitted in a block] statements ENDIF Note that ELSEIF() does not require a separate ENDIF. Each branching instruction must be a separate formula statement, separated from other statements by a comma or an end of line. There is a limit of 200 branching instructions per formula (ELSEIF counts as two branching instructions). Unlimited nesting is permitted; each ELSEIF, ELSE, and ENDIF relates to the immediately preceding "non endif'ed" IF. An IF() and its ENDIF cannot traverse the end of the initialization section of the formula. Added tutorials to the distribution package: Bradley Beacham's basic formula tutorial, Sylvie Gallet's PHC and PTC formula tutorial, and George Martin's tutorial on the new if..else feature of the formula parser. Required reading for formula writers. Added text scrolling capability in and F2 screens. Scroll keys for the screen: CTRL+DOWN_ARROW Move screen down one line CTRL+UP_ARROW Move screen up one line CTRL+RIGHT_ARROW Move screen right one column CTRL+LEFT_ARROW Move screen left one column CTRL+PAGE_DOWN Move screen down one view screen CTRL+PAGE_UP Move screen up one view screen CTRL+HOME Go to beginning of entry CTRL+END Go to end of entry Direction keys without the CONTROL key depressed maintain their current roles in moving the cursor in the entry prompt boxes. In the F2 screen, the same scrolling is available; the CONTROL key does not need to be depressed. Added capability to place ifs, formula, and lsys entries in PAR files. If not found in the file named in the parameter entry, formulas, ifs, and lsystem entries called for in entries are looked for in the .par file itself. The referenced entry must have the appropriate prefix in the PAR file as follows:\ formulas frm:\ lsystem lsys:\ ifs ifs:\ for example:\ frm:mandel \{\ z=c=pixel:\ z = z*z + c\ |z| < 4\ \}\ The prefix is an identifier, not part of the name itself. Thus, the parameter in the image entry would read "formulaname=mandel". The formulafile= parameter need not, and probably should not, name the PAR file itself - the search of the PAR file is automatic. Formulas, ifs, and lsys entries in a PAR file will not be shown on the menu screen for the PAR file, and are accessible only in connection with running the parameter entry which calls for the formula. Also, PAR files are not searched when looking for a formula, ifs, or lsystem entry in connection with restoring a .gif file. You will need to copy these entries from the PAR file into .frm, .ifs, and .l files as applicable (taking care, of course, to delete the identifier prefixes) in order to make general use of them. Added command line option fastrestore=yes|no. Default is NO. When YES, causes viewwindows to be set to NO before each restore, so that otherwise normal gifs will not be drawn at the reduced aspect when viewwindows was previously set to YES; and bypasses the warning which is displayed when a restore is to be viewed in a video mode other than the one at which the gif was saved. Combined with askvideo=no, all restores will automatically be made at the user's default video mode. This feature will be helpful when cycling through a group of gifs in autokey mode. Ctrl-Right used in file selection screens now skips over directory listings, and if the cursor is on the last file, moves the cursor to the first file. This makes possible uninterrupted cycling in autokey mode. The keyword for this keystroke in a .key file is CTRL_RIGHT.\ ~OnlineFF The following additional keystrokes were also implemented:\ Ctrl-Left (autokey symbol "CTRL_LEFT")\ Ctrl-Down ("CTRL_DOWN")\ Ctrl-Up ("CTRL_UP")\ Ctrl-Home ("CTRL_HOME")\ Ctrl-End ("CTRL_END")\ Run the following .key file with command line parameters fastrestore=yes and askvideo=no (and, if you don't set your video mode in sstools.ini, video=[your standard video mode]) and your coworkers will get a continuous display of the .gif files in your default .gif directory when you go to lunch (come on, we know you have Fractint on your hard drive at work): "r" MORE: ENTER CALCWAIT WAIT 30 "R" CTRL_RIGHT GOTO MORE Added four new lsystem types to fractint.l. When palette editing mode is entered, the original palette is now stored in the area associated with F2. Reduced the fractint.cfg resolution limit to 2x2 pixels. Fixed bug which caused a lockup when ranges= was used with maxit >= 32767. Fixed arbitrary precision and decoder crashes. Fixed an entry display scrolling bug. Fixed the integer mode frothy basin "censored" bug. Added backwards compatibility for inside=startrails. Fixed the 16-color color cycling inside the palette editor. Fixed color cycling when used with a maxit > 32767. Pixels with iterations > 32767 now cycle in the same direction as those with iterations <= 32767. Fixed bug which caused an apparent lockup when find finite attractor was used with maxit > 32767. Fixed viewwindows bug that caused extra points to be written when ydots was not divisible by 4. Fixed Ant type so that it works with 16 digits. Old pars will need to be re-entered or have a decimal point added to the first two parameters. Changed MAXSTRING in the decoder from 64000 to 60000. This change eliminates all the encoder bug examples we have, but we don't understand why it works and we may not have fixed the problem. Fixed the logmap routine when used with a par/gif release <= 1920 and memory for the LogTable is insufficient. Fixed the complexnewton type when used with a par/gif release <= 1920. Changed the keystroke behavior of the passes= field on the screen. New logic autocenters all input screen menu titles. Changed the automatic resolution switching logic between float and arbitrary precision. If user aborts before selecting a file in a file menu screen, the program now remembers the last file name selected even if the directory has been changed. Fixed writing 3d smooth factor to PAR. Fixed writing potential to PAR in makepar mode. Fixed redundant "Regenerate before to get correct symmetry" messages in divide and conquer mode. Fixed hi rez type 2 diffusion bug and parser error bug. Fixed crashing in disk video with too long a savename path. Added Adrian Mariano's diffusion fixes - a new color option, several bug fixes, and improved documentation. Removed integer support which wasn't being used anyway. Finally, we've added two undocumented commands to give expert users workarounds for math type precision and GIF encoder problems. Added the mathtolerance=.05/.05 command. The first number controls the integer/float transition, and the second number controls the float/arbitrary precision transition. The default value of .05 means that the ratio between the exact and calculated width and height is between .95 and 1.05. A larger value than .05 (say .10) makes the test looser so that the lower precision math is used longer. A value <= 0 means the test is always failed and the higher precision math type is used. A value >= 1 means that the test is always passed and the lower precision math type is used. The automatic precision toggle is resolution dependent. The same image may use float at 320x200 and arbitrary precision at 640x480. This is not a bug; it has to work this way. At a given magnification more pixels require more precision. There are other tests so even with mathtolerance=1/.05, eventually Fractint will have to use float. The same is not true for mathtolerance=.05/1. If you keep zooming Fractint will not rescue you; eventually you'll get a nasty error message and the corners will be lost. Added the tweaklzw=nnn/nnn command. Fractint's GIF encoder occasionally fails and produces bad GIF files. Tweaking encoder parameters might allow saving in such a situation. The parameters reduce the maximum size of the current string and maximum total length of the string table, respectively. The default values are 0, which gives the old encoder performance. Version 19.5 is a bug-fix release for version 19.4 based on the developer's version 19.40 patch 11. As always, we added a few new features along with the bug fixes. New {=@COMMENTS Comment= command}. You can automatically set any of the four PAR comments, and can include variables in the comments such as the much-requested $calctime$ and $date$. Fractint now writes ';;' for empty comments above the last comment from the comment= command. This prevents comments from moving positions when the PAR is reloaded. New {=@RECORDCOLORS recordcolors= command}. If you place recordcolors=y in your SSTOOLS.INI, compressed colors will always be written in your PARS. If you want to remember what the map file was (assuming the colors were loaded from one), try recordcolors=c. This is exactly like recordcolors=y except that the map file (if any) is written to a parfile comment. Added new parser constants:\ 1. whitesq parser constant = (row+col)&1\ 2. scrnpix parser constant = (col,row)\ 3. scrnmax parser constant = (xdots, ydots)\ 4. maxit parser constant = (maxit,0)\ Added "\\" linewrap for formula files. Made the round function consistent in all modes. Now round(z) is always (floor(x+.5)+i*floor(y+.5)). In version 19.4, in floating point mode with type=formula, round() used the coprocessor "nearest or even" rounding. Version 19.5 always rounds xxx.5 up. Fixed a bug that caused a crash when zooming out with certain functions in integer mode. Fixed a bug that caused a crash when attempting 3d=overlay without a filename in batch mode. Fixed a bug that caused part of the video table to not show when compiled by Borland. Fixed a bug that kept the last image browsed from showing up when you regenerate an image and then start the browser again. Fixed a bug that loaded images with the wrong aspect ratio when using the browser with the view window turned on, and the file image size was not the same as the screen image size. ~ONLINEFF Version 19.4 is a bug-fix release for version 19.3 based on the developer's version 19.30 patch 18. But a few new features did slip in when we weren't looking. New functions are now available for type=formula and general function variable use. They are the rounding functions: floor(), ceil(), trunc(), and round() New larger showdot "turtle" to enable better seeing which pixel is currently being calculated. The syntax is showdot=/, but the color parameter can now be one of auto, bright, medium, and dark in addition to the previously-supported color number value. The command now remembers the last command. Added the ability to load images into a view window. This can be used with the browser to browse images larger than the current image. Added George Martin's new integrated entry-finding code. Fractint is now more tolerant of text between entries, and the internal code is much cleaner than before. Added Bert Tyler's new VESA truecolor video drivers. These don't do anything yet; we've just added the video drivers for testing. Work goes on ...\ To test out the new modes, try fractint debug=500 type=test and select a new truecolor mode. They only work with video boards having VESA truecolor support. Some "non-standard VESA" modes (an unfortunate oxymoron if there ever was one) can also be supported by editing FRACTINT.CFG. These vendor-specific "VESA" modes tend to make Bert, our video expert, real grumpy ... Now for the squashed bugs report: Ranges is working again. Fixed a browser bug that caused a crash when the browser cross-hairs become too small. Fixed a bug which put the browser into an infinite loop if the history feature was used to try and access a deleted or renamed image that was still in the history stack. Fixed bug that caused any command with greater than 16 parameters to fail, most notably textcolors and ranges. Fixed a center-mag<->corners conversion bug that occurred with rotated images. arbitrary precision also (test with debug=3200). Fixed bug that allowed the matherr debugging file to grow arbitrarily large. Matherr file is limited to 100 messages for each fractal. Fixed bug that affected some Icons3d types, which were broken due to a very subtle bug in apparently good code caused by the compiler optimizer. Version 19.3 is a bug-fix release for version 19.2 based on the developer's version 19.21 patch 30. The biggest changes from 19.2 to 19.3 are the fixing of the color logmap function for maximum iterations greater than 32K, and a large increase in the maximum size of an individual formula and the maximum number of entries in formula, parameter, ifs, and lsystem files. Changes from 19.2 to 19.3 include: Added better math function error trapping for the formula parser. This can change the rendering of some PAR files using type=formula. If reset=1920 is included in the PAR file, the new error trapping is disabled. Fixed an old, rare, but nasty bug that stripped trailing zeros from the exponents of floating point numbers written to PAR files. Ctrl-ins and Ctrl-Del now change the browser frame colors. Fixed bug that occurred when writing PAR files containing a video= line with a four character video mode. Added batch facility to copy fractal information and color in GIFs to PAR format. Added current column to the screen. Removed support for reading Targa files. Added backwards compatibility for the fractal type fn(z*z). Added support for expanded and extended memory to the browser. Use expanded memory if you don't have at least 4 MB of extended memory. Added pi and e to constants that the formula parser recognizes. Fixed parser so that constants are recognized correctly. Added docs for freestyle mode in the colour editor. Fixed bug involving comments between formula entries. Allow renaming Fractint.exe without losing access to fractint's help files. Center-mag is now the default method for storing coordinates in PAR files. Increased limit on number of operations in a formula entry from 250 to over 2000. In most cases memory use is actually less than before because of use of existing memory arrays. Fixed a bug that caused the image to regenerate when the screen was accessed, but nothing was changed (or color cycle range was changed). Fixed a bug that caused saved partial images that used logmap to use the incorrect logmap routine when restored (GIFs & PARs). Made the solid guessing stop pass parameter save to GIFs and PARS. Added truecolor=yes command. This causes the iterations for each point to be written to a 24-bit Targa truecolor file called iterates.tga. Maxiter is also written to the file. This allows a simple outboard program to assign truecolors to iterations. Passes=1 is forced, but symmetry works. (This function may go away in the future when real truecolor support is implemented.) Fixed bug that caused PARs to have incorrect number of parameters when a formula based GIF was loaded and a PAR made immediately. Added additional bailout tests manh and manr. See {Bailout Test}. Fixed screen so bailout test can be changed when potential is being used. Fixed bug that caused large filename numbers to increment incorrectly. Added new guessing options g1, g2, etc. that cause guessing to terminate before the last pass. Added new orbitsave=sound option that causes orbits with sound on to write to a file sound.txt. The values written are the Hertz values for each orbit point. The time is written out in milliseconds once per pixel. Added documentation for making demm images to match ones made prior to version 16. Added key pressed check to autologmap so it is possible to bailout with a high maxit value. Made all floating point types capable of zooming out past (32,32). Added the formula parameters p1, p2, and p3 to the screen. Added stereo pair feature to stereo options menu. Fixed a bug that caused julia_inverse to continue after completed. Bignumber library rearranged. DOS midnight bug fix, so total time of images run overnight is now correct. Added logmap backwards compatibility for pre-version 19.2 images. Browser problem with flipped images fixed. Changed default corners to 4:3 aspect for types sierpinski, popcorn, pickover, popcornjul, tim's_error, martin, and halley. Added a range check for type=ants numants parameter. RDS save command is no longer case sensitive. Added the color number to the status area in the palette editor. Changed logmap and distest to a long variable to accomodate the version 19.0 change to long maxit. Added a pixel-at-a-time routine to calculate the logmap values on the fly when memory is low or maxit > 32767. Use logmode=fly to use with maxit < 32767. Note: ranges still doesn't work with maxit > 32767. Extended error checking to set the overflow variable when a zero denominator is found. Added checking of overflow in a few places where it is needed. Added backwards compatibility for the old "broken" integer parser mod function. Fixed the maximum zoom out of the integer type fn(z*z) (and others) so the user doesn't get thrown out to DOS. Fixed writing of olddemmcolors variable to PAR file. Version 19.2 changes start on the next page. ~FF Version 19.2 is a bug-fix release for version 19.1. Changes from 19.1 to 19.2 include: Fixed the 3D function, which was broken in 19.1 due to a side-effect of a repair of a minor bug in 19.0. Arrgghh! This is the main reason for the release of this version so quickly. Fixed a bug that caused the Julia inverse window and the orbits window to lose their place after loading a color map. Fixed a bug that causes corners to be lost when too many digits are entered. Added an enhanced ants automaton by Luciano Genero and Fulvio Cappelli. New showorbit command allows orbits-during-generation feature to be turned on by default. Expanded limits of Hertz command to 20 to 15000. Targa 3D files are now correctly written to workdir rather than tempdir. Uncommented garbage between file entries is now ignored. (But note that "\{" must be on same line as entry name.) Fixed savename update logic. Version 19.1 is a bug-fix release for version 19.0. Changes from 19.0 to 19.1 include: Disabled the F6 (corners) key when in the parameters screen () for arbitrary precision. IFS formulas now show in screen. Allow RDS image maps of arbitrary dimensions. Touched up Mandelbrot/Julia toggle logic. Fractint now remembers map name, and uses the mapfile path correctly, and now allows periods in directory names. Fixed tab bug that caused problems when interrupting a restore of an arbitrary precision image. Repaired savename logic. No longer show (usually truncated) full path of the saved file in the screen. Fixed double to arbitrary precision transition with 90 degree images. (This only failed before when the image was rotated exactly 90 degrees.) Corrected docs directory errors that reported several commands such as PARDIR= that were not implemented. Documented the color cycling HOME function. Fixed Mandelbrot/Julia types with bailout less than 4 (try it, results are interesting!) Fixed browser delete feature which left a box on the screen after deleting and exiting browser feature. More changes in filename processing logic. ".\\" is now recognized as the current directory and is expanded to its full path name. It is now possible, although not recommended, to designate the root directory of a disk as the desired search directory. Fixed integer math Mandelbrot bug for 286 or lower machines. Fixed problem of reading some Lsys files incorrectly (distribution PENROSE.L file was broken unless first line was commented.) Fixed problem that caused endless loop in RDS with bad input values. Made reading the current directory first optional, added the new curdir=yes command for times when you want to use current directory files. Fixed problem with complexpower() function ("x^y" formula operator) in the case where x == 0. (Note that formulas where 0^0 appears for every every pixel are considered broken and no promises made.) Prevented aspect ratio drift as you zoom. If you want to make tiny adjustments, use new ASPECTDRIFT=0 command. Inside=bof60 and bof61 options now work correctly with the formula parser. We discovered the calculation time is no good after 24 days, so instead of the time you will now get the message "A Really Long Time!!! (> 24.855 days)". We thought you'd like to know ... A prize for the first person who actually *sees* this message! A summary of features new with 19.0 begins on next page. ~FF New arbitrary precision math allows types mandelbrot, julia, manzpower, and julzpower to zoom to 10^1600. See {Arbitrary Precision and Deep Zooming} New Random Dot Stereogram feature using -. Thanks to Paul De Leeuw for contributing this feature. For more, see {Random Dot Stereograms (RDS)}. New browser invoked by the command allows you to see the relationships of a family of images within the current corners values. See {Browse Commands} and {Browser Parameters}. Thanks to Robin Bussell for contributing this feature. Added four bailout tests: real, imag, or, and. These are set on the screen of the fractal types for which they work. The default is still mod. See {Bailout Test}. New asin, asinh, acos, acosh, atan, atanh, sqrt, abs (abs(x)+i*abs(y)), and cabs (sqrt(x*x + y*y)) functions added to function variables and parser. New fractal types types chip, quadruptwo, threeply, phoenixcplx, mandphoenixclx, and ant automaton. Increased maximum iterations to 2,147,483,647 and maximum bailout to 2,100,000,000 when using floating point math. New path/directory management. Fractint now remembers the pathname of command-line filenames. This means that you can specifiy directories where your files reside in SSTOOLS.INI. In what follows, can be a directory, a filename, or a full path. File SSTOOLS.INI Command Comments\ ==========================================================================\ PAR directory parmfile=\ GIF files for reading filename=\ MAP files map=\ Autokey files autokeyname=\ GIF files for saving savename=\ Print file printfile=\ Formula files formulafile=\ Lsystem file lfile=\ IFS file ifsfile=\ Miscellaneous files workdir=\ new command\ Temporary files tempdir=\ new command\ If the directories do not exist, Fractint gives an error message on runup with the option to continue. Fractint now searches all FRM, IFS, LSYS, and PAR files in the designated directory for entries. The number of entries in files has been greatly increased from 200 to 2000. Comment support in these files is improved. Parameters shown in screen now match those used in a formula. Distance estimator logic has been overhauled, with the variable olddemmcolors added for backward compatibility. New floating point code for Lsystems from Nick Wilt greatly speeds up image generation. Enhanced fast parser from Chuck Ebbert makes floating point formula fractals faster than built-in types. Enhanced the history command to include all parameters, colors, and even .frm, .l, and .ifs file names and entries. Number of history sets remembered can be set with the maxhistory= command to save memory. Enhanced center-mag coordinates to support rotated/stretched/skewed zoom boxes. Added new parameter to built-in Halley for comparison with formula type, also added new parameter to Frothybasin type. Added color number to orbits numbers display. Added two new parameters to distest= to allow specifying resolution. This allows making resolution-independent distance estimator images. Fixed bug that caused the "big red switch" bug if '(' appeared in random uncommented formula file text, but fair warning, we don't officially support uncommented text in FRM files. Symmetry now works for the Marksjulia type and Marksmandel types. Full path no longer written in PAR files with command. Fixed fractal type fn(z*z) so that zooming out will no longer dump you out to DOS, affecting zoomed out integer images made with this type. Fixed a float to fudged integer conversion that affects integer fractal types fn(z*z) and fn*fn. This has only a minor impact on integer images made with these types. Default drive and directory restored after dropping to DOS, in case you changed it while under DOS. Added support for inversion to the formula parser (type=formula). Increased maximum number of files listed by command to 2977 from 300. Added outside=atan option. Added faster auto logmap logic. ; ; ; ~Topic=Version 18 Versions 18.1 and 18.2 are bug-fix releases for version 18.0. Changes from 18.1 to 18.2 include: The command now causes filenames only to be written in PAR files. Fractint will now search directories in the PATH for files not found in the requested the requested directory or the current directory. If you place .MAP, .FRM, etc. in directories in your PATH, then Fractint will find them. Fixed bug that caused fractals using PI symmetry to fail at high resolution. Fractals interrupted with <3> or can now resume. The palette editor's (undo) now works. The command in orbit/Julia window mode is no longer case sensitive. Added warnings that the POV-Ray output is obsolete (but has been left in). Use POV-Ray's height field facility instead or create and convert RAW files. Fixed several IFS bugs. Changes from 18.0 to 18.1 include: Overlay tuning - the Mandelbrot/Julia Set fractals are now back up to 17.x speeds Disk Video modes now work correctly with VESA video adapters (they used to use the same array for different purposes, confusing each other) 1024x768x256 and 2048x2048x256 disk video modes work again Parameter-file processing no longer crashes Fractint if it attempts to run a formula requiring access to a non-existent FRM file IFS arrays no longer overrun their array space type=cellular fixes "autologmap=2" now correctly picks up the minimum color The use of disk-video mode with random-access fractal types is now legal (it generates a warning message but lets you proceed if you really want to) The Lsystems "spinning-wheel" now spins slower (removing needless overhead) Changes to contributors' addresses in the Help screens (The remainder of this "new features" section is from version 18.0) New fractal types: 19 new fractal types, including: New fractal types - 'lambda(fn||fn)', 'julia(fn||fn)', 'manlam(fn||fn)', 'mandel(fn||fn)', 'halley', 'phoenix', 'mandphoenix', 'cellular', generalized bifurcation, and 'bifmay' - from Jonathan Osuch. New Mandelcloud, Quaternion, Dynamic System, Cellular Automata fractal types from Ken Shirriff. New HyperComplex fractal types from Timothy Wegner New ICON type from Dan Farmer, including a PAR file of examples. New Frothy Basin fractal types (and PAR entries) by Wesley Loewer MIIM (Modified Inverse Iteration Method) implementation of Inverse Julia from Michael Snyder. New Inverse Julia fractal type from Juan Buhler. New floating-point versions of Markslambda, Marksmandel, Mandel4, and Julia4 types (chosen automatically if the floating-point option is enabled). New options/features: New assembler-based parser logic from Chuck Ebbert - significantly faster than the C-based code it replaces! New assembler-based Lyapunov logic from Nicholas Wilt and Wes Loewer. Roughly six times faster than the old version! New Orbits-on-a-window / Julia-in-a-window options:\ 1) The old Overlay option is now '#' (Shift-3).\ 2) During generation, 'O' brings up orbits (as before) - after\ generation, 'O' brings up new orbits Windows mode.\ 3) Control-O brings up new orbits Windows mode at any time.\ 4) Spacebar toggles between Inverse Julia mode and the Julia set and\ back to the Mandelbrot set.\ These new "in-a-window" modes are really neat! See {Orbits Window} and {Julia Toggle Spacebar Commands} for details. New multi-image GIF support in the command. You can now generate 65535x65535x256 fractal images using Fractint (if you have the disk space, of course). This option builds special PAR entries and a MAKEMIG.BAT file that you later use to invoke Fractint multiple times to generate individual sections of the image and (in a final step) stitch them all together. If your other software can't handle Multiple-image GIFs, a SIMPLGIF program is also supplied that converts MIGS into simgle-image GIFs. Press F1 at the prompts screen for details. Fractint's decoder now handles Multi-Image Gifs. New SuperVGA/VESA Autodetect logic from the latest version of VGAKIT. Sure hope we didn't break anything. New register-compatible 8514/A code from Jonathan Osuch. By default, Fractint now looks first for the presence of an 8514/A register-compatible adapter and then (and only if it doesn't find one) the presence of the 8514/A API (IE, HDILOAD is no longer necessary for register-compatible "8514/a" adapters). Fractint can be forced to use the 8514/A API by using a new command-line option, "afi=yes". Jonathan also added ATI's "8514/a-style" 800x600x256 and 1280x1024x16 modes. New XGA-detection logic for ISA-based XGA-2 systems. The palette editor now has a "freestyle" editing option. See {Palette Editing Commands} for details. Fractint is now more "batch file" friendly. When running Fractint from a batch file, pressing any key will cause Fractint to exit with an errorlevel = 2. Any error that interrupts an image save to disk will cause an exit with errorlevel = 2. Any error that prevents an image from being generated will cause an exit with errorlevel = 1. New Control-X, Control-Y, and Control-Z options flip a fractal image along the X-axis, Y-axis, and Origin, respectively. New area calculation mode in TAB screen from Ken Shirriff (for accuracy use inside=0). The TAB screen now indicates when the Integer Math algorithms are in use. The palette must now be explicitly changed, it will not reset to the default unexpectedly when doing things like switching video modes. The Julibrot type has been generalized. Julibrot fractals can now be generated from PAR files. Added command support for viewwindows. Added room for two additional PAR comments in the command New coloring method for IFS shows which parts of fractal came from which transform. Added attractor basin phase plotting for Julia sets from Ken Shirriff. Improved finite attractor code to find more attractors from Ken Shirriff. New zero function, to be used in PAR files to replace old integer tan, tanh Debugflag=10000 now reports video chipset in use as well as CPU/FPU type and available memory Added 6 additional parameters for params= for those fractal types that need them. New 'matherr()' logic lets Fractint get more aggressive when these errors happen. New autologmap option (log=+-2) from Robin Bussell that ensures that all palette values are used by searching the screen border for the lowest value and then setting log= to +- that color. Two new diffusion options - falling and square cavity. Three new Editpal commands: '!', '@' and '#' commands (that's , , and ) to swap R<->G, G<->B, R<->B. Parameter files now use a slightly shorter maximum line length, making them a bit more readable when stuffed into messages on CompuServe. Plasma now has 16-bit .POT output for use with Ray tracers. The "old" algorithm has been modified so that the plasma effect is independent of resolution. Slight modification to the Raytrace code to make it compatible with Rayshade 4.0 patch level 6. Improved boundary-tracing logic from Wesley Loewer. Command-line parameters can now be entered on-the-fly using the key thanks to Ken Shirriff. Dithered gif images can now be loaded onto a b/w display. Thanks to Ken Shirriff. Pictures can now be output as compressed PostScript. Thanks to Ken Shirriff. Periodicity is a new inside coloring option. Thanks to Ken Shirriff. Fixes: symmetry values for the SQR functions, bailout for the floating-pt versions of 'lambdafn' and 'mandelfn' fractals from Jonathan Osuch. "Flip", "conj" operators are now selectable in the parser New DXF Raytracing option from Dennis Bragg. Improved boundary-tracing logic from Wesley Loewer. New MSC7-style overlay structure is used if MAKEFRAC.BAT specifies MSC7. (with new FRACTINT.DEF and FRACTINT.LNK files for MSC7 users). Several modules have been re-organized to take advantage of this new overlay capability if compiled under MSC7. Fractint now looks first any embedded help inside FRACTINT.EXE, and then for an external FRACTINT.HLP file before giving up. Previous releases required that the help text be embedded inside FRACTINT.EXE. Bug fixes: Corrected formulas displayed for Marksmandel, Cmplxmarksmandel, and associated julia types. BTM and precision fixes. Symmetry logic changed for various "outside=" options Symmetry value for EXP function in lambdafn and lambda(fn||fn) fixed. Fixed bug where math errors prevented save in batch mode. The <3> and commands no longer destroy image -- user can back out with ESC and image is still there. Fixed display of correct number of Julibrot parameters, and Julibrot relaxes and doesn't constantly force ALTERN.MAP. Fixed tesseral type for condition when border is all one color but center contains image. Fixed integer mandel and julia when used with parameters > +1.99 and < -1.99 Eliminated recalculation when generating a julia type from a mandelbrot type when the 'z' screen is viewed for the first time. Minor logic change to prevent double-clutching into and out of graphics mode when pressing, say, the 'x' key from a menu screen. Changed non-US phone number for the Houston Public (Software) Library The "Y" screen is now "Extended Options" instead of "Extended Doodads" ...and probably a lot more bux-fixes that we've since forgotten that we've implemented. ; ~Topic=Version 17 Version 17.2, 3/92 - Fixed a bug which caused Fractint to hang when a Continuous Potential\ Bailout value was set (using the 'Y') screen and then the 'Z' screen\ was activated.\ - fixed a bug which caused "batch=yes" runs to abort whenever any\ key was pressed.\ - bug-fixes in the Stereo3D/Targa logic from Marc Reinig.\ - Fractint now works correctly again on FPU-less 8088s when\ zoomed deeply into the Mandelbrot/Julia sets\ - The current image is no longer marked as "not resumable" on a\ Shell-To-Dos ("D") command.\ - fixed a bug which prevented the "help" functions from working\ properly during fractal-type selection for some fractal types.\ Version 17.1, 3/92 - fixed a bug which caused PCs with no FPU to lock up when they attempted\ to use some fractal types.\ - fixed a color-cycling bug which caused the palette to single-step \ when you pressed ESCAPE to exit color-cycling.\ - fixed the action of the '<' and '>' keys during color-cycling.\ Version 17.0, 2/92 - New fractal types (but of course!): Lyapunov Fractals from Roy Murphy (see {Lyapunov Fractals} for details) 'BifStewart' (Stewart Map bifurcation) fractal type and new bifurcation parameters (filter cycles, seed population) from Kevin Allen. Lorenz3d1, Lorenz3d3, and Lorenz3d4 fractal types from Scott Taylor. Note that a bug in the Lorenz3d1 fractal prevents zooming-out from working with it at the moment. Martin, Circle, and Hopalong (culled from Dewdney's Scientific American Article) Lots of new entries in fractint.par. New ".L" files (TILING.L, PENROSE.L) New 'rand()' function added to the 'type=formula' parser - New fractal generation options: New 'Tesseral' calculation algorithm (use the 'X' option list to select it) from Chris Lusby Taylor. New 'Fillcolor=' option shows off Boundary Tracing and Tesseral structure inside=epscross and inside=startrail options taken from a paper by Kenneth Hooper, with credit also to Clifford Pickover New Color Postscript Printer support from Scott Taylor. Sound= command now works with rbits and ead commands. New 'orbitdelay' option in X-screen and command-line interface New "showdot=nn" command-line option that displays the pixel currently being worked on using the specified color value (useful for those lloooonngg images being calculated using solid guessing - "where is it now?"). New 'exitnoask=yes' commandline/SSTOOLS.INI option to avoid the final "are you sure?" screen New plasma-cloud options. The interface at the moment (documented here and here only because it might change later) lets you:\ - use an alternate drawing algorithm that gives you an earlier preview\ of the finished image. - re-generate your favorite plasma cloud (say, at a higher resolution) by forcing a re-select of the random seed.\ New 'N' (negative palette) option from Scott Taylor - the documentation at this point is: Pressing 'N' while in the palette editor will invert each color. It will convert only the current color if it is in 'x' mode, a range if in 'y' mode, and every color if not in either the 'x' or 'y' mode. - Speedups: New, faster floating-point Mandelbrot/Julia set code from Wesley Loewer, Frank Fussenegger and Chris Lusby Taylor (in separate contributions). Faster non-386 integer Mandelbrot code from Chris Lusby Taylor, Mike Gelvin and Bill Townsend (in separate contributions) New integer Lsystems logic from Nicholas Wilt Finite-Attractor fixups and Lambda/mandellambda speedups from Kevin Allen. GIF Decoder speedups from Mike Gelvin - Bug-fixes and other enhancements: Fractint now works with 8088-based AMSTRAD computers. The video logic is improved so that (we think) fewer video boards will need "textsafe=save" for correct operation. Fixed a bug in the VESA interface which effectively messed up adapters with unusual VESA-style access, such as STB's S3 chipset. Fixed a color-cycling bug that would at times restore the wrong colors to your image if you exited out of color-cycling, displayed a 'help' screen, and then returned to the image. Fixed the XGA video logic so that its 256-color modes use the same default 256 colors as the VGA adapter's 320x200x256 mode. Fixed the 3D bug that caused bright spots on surfaces to show as black blotches of color 0 when using a light source. Fixed an image-generation bug that sometimes caused image regeneration to restart even if not required if the image had been zoomed in to the point that floating-point had been automatically activated. Added autodetection and 640x480x256 support for the Compaq Advanced VGA Systems board - I wonder if it works? Added VGA register-compatible 320x240x256 video mode. Fixed the "logmap=yes" option to (again) take effect for continuous potential images. This was broken in version 15.x. The colors for the floating-point algorithm of the Julia fractal now match the colors for the integer algorithm. If the GIF Encoder (the "Save" command) runs out of disk space, it now tells you about it. If you select both the boundary-tracing algorithm and either "inside=0" or "outside=0", the algorithm will now give you an error message instead of silently failing. Updated 3D logic from Marc Reinig. Minor changes to permit IFS3D fractal types to be handled properly using the "B" command. Minor changes to the "Obtaining the latest Source" section to refer to BBS access (Peter Longo's) and mailed diskettes (the Public (Software) Library). ~Topic=Version 16 Version 16.12, 8/91 Fix to cure some video problems reported with Amstrad 8088/8086-based PCs. Version 16.11, 7/91 SuperVGA Autodetect fixed for older Tseng 3000 adapters.\ New "adapter=" options to force the selection of specific SuperVGA adapter types. See {Video Parameters} for details.\ Integer/Floating-Point math toggle is changed only temporarily if floating-point math is forced due to deep zooming.\ Fractint now survives being modified by McAfee's "SCAN /AV" option.\ Bug Fixes for Acrospin interface, 3D "Light Source Before Transformation" fill type, and GIF decoder.\ New options in the parameters screen allow you to directly enter image coordinates.\ New "inside=zmag" and "outside=real|imag|mult|summ" options.\ The GIF Decoder now survives reading GIF files with a local color map.\ Improved IIT Math Coprocessor support.\ New color-cycling single-step options, '<' and '>'.\ Version 16.0, 6/91 Integrated online help / fractint.doc system from Ethan Nagel. To create a printable fractint.doc file see {Startup Parameters}. Over 350 screens of online help! Try pressing just about anywhere!\ New "autokey" feature. Type "demo" to run the included demo.bat and demo.key files for a great demonstration of Fractint. See {Autokey Mode} for details. New <@> command executes a saved set of commands. The command has changed to write the current image's parameters as a named set of commands in a structured file. Saved sets of commands can subsequently be executed with the <@> command. See {Parameter Save/Restore Commands}. A default "fractint.par" file is included with the release. New command allows changing fractal type-specific parameters without going back through the (fractal type selection) screen. Ray tracer interface from Marc Reinig, generates 3d transform output for a number of ray tracers; see {"Interfacing with Ray Tracing Programs"} Selection of video modes and structure of "fractint.cfg" have changed. If you have a customized fractint.cfg file, you'll have to rebuild it based on this release's version. You can customize the assignment of your favorite video modes to function keys; see {Video Mode Function Keys}. is a new command key which goes directly to video mode selection. New "cyclerange" option (command line and options screen) from Hugh Steele. Limits color cycling to a specified range of colors. Improved {Distance Estimator Method} algorithm from Phil Wilson.\ New "ranges=" option from Norman Hills. See {Logarithmic Palettes and Color Ranges} for details. type=formula definitions can use "variable functions" to select sin, cos, sinh, cosh, exp, log, etc at run time; new built-ins tan, tanh, cotan, cotanh, and flip are available with type=formula; see Type {Formula} New command in palette editing mode to convert image to greyscale\ All "fn" fractal types (e.g. fn*fn) can now use new functions tan, tanh, cotan, cotanh, recip, and ident; bug in prior cos function fixed, new function cosxx (conjugate of cos) is the old erroneous cos calculation New L-Systems from Herb Savage\ New IFS types from Alex Matulich\ Many new formulas in fractint.frm, including a large group from JM Collard-Richard Generalized type manzpwr with complex exponent per Lee Skinner's request\ Initial orbit parameter added to Gingerbreadman fractal type\ New color maps (neon, royal, volcano, blues, headache) from Daniel Egnor\ IFS type has changed to use a single file containing named entries (instead of a separate xxx.ifs file per type); the command brings up IFS editor (used to be command). See {=HT_IFS Barnsley IFS Fractals}. Much improved support for PaintJet printers; see {PaintJet Parameters}\ From Scott Taylor:\ Support for plotters using HP-GL; see {Plotter Parameters}\ Lots of new PostScript halftones; see {PostScript Parameters}\ "printer=PS[L]/0/..." for full page PostScript; see {PostScript Parameters}\ Option to drive printer ports directly (faster); see {Printer Parameters}\ Option to change printer end of line control chars; see {Printer Parameters} Support for XGA video adapter\ Support for Targa+ video adapter\ 16 color VGA mode enhancements:\ Now use the first 16 colors of .map files to be more predictable\ Palette editor now works with these modes\ Color cycling now works properly with these modes Targa video adapter fixes; Fractint now uses (and requires) the "targa" and "targaset" environment variables for Targa systems "vesadetect=no" parameter to bypass use of VESA video driver; try this if you encounter video problems with a VESA driver Upgraded video adapter detect and handling from John Bridges; autodetect added for NCR, Trident 8900, Tseng 4000, Genoa (this code is from a beta release of VGAKIT, we're not sure it all works yet) Zoom box is included in saved/printed images (but, is not recognized as anything special when such an image is restored) The colors numbers reserved by the palette editor are now selectable with the new palette editing mode command Option to use IIT floating point chip's special matrix arithmetic for faster 3D transforms; see "fpu=" in {Startup Parameters} Disk video cache increased to 64k; disk video does less seeking when running to real disk Faster floating point code for 287 and higher fpus, for types mandel, julia, barnsleyj1/m1/j2/m2, lambda, manowar, from Chuck Ebbert "filename=.xxx" can be used to set default function file mask\ Selection of type formula or lsys now goes directly to entry selection (file selection step is now skipped); to change to a different file, use from the entry selection screen Three new values have been added to the textcolors= parameter; if you use this parameter you should update it by inserting values for the new 6th, 7th, 9th, and 13th positions; see "textcolors=" in {Color Parameters} The formula type's imag() function has changed to return the result as a real number Fractal type-specific parameters (entered after selecting a new fractal type with ) now restart at their default values each time you select a new fractal type Floating point input fields can now be entered in scientific notation (e.g. 11.234e-20). Entering the letters "e" and "p" in the first column causes the numbers e=2.71828... and pi=3.14159... to be entered. New option "orbitsave=yes" to create files for Acrospin for some types (see {Barnsley IFS Fractals}, {Orbit Fractals}, {=@ACROSPIN Acrospin}) Bug fixes:\ Problem with Hercules adapter auto-detection repaired.\ Problems with VESA video adapters repaired (we're not sure we've got them all yet...)\ 3D transforms fixed to work at high resolutions (> 1000 dots).\ 3D parameters no longer clobbered when restoring non-3D images.\ L-Systems fixed to not crash when order too high for available memory.\ PostScript EPS file fixes.\ Bad leftmost pixels with floating point at 2048 dot resolution fixed.\ 3D transforms fixed to use current screen float/integer setting.\ Restore of images using inversion fixed.\ Error in "cos" function (used with "fn" type fractals) fixed; prior incorrect function still available as "cosxx" for compatibility Old 3D=nn/nn/nn/... form of 3D transform parameters no longer supported\ Fractint source code now Microsoft C6.00A compatible. ; ; ~Topic=Version 15 Version 15.11, 3/91, companion to Fractal Creations, not for general release Autokey feature, IIT fpu support, and some bug fixes publicly released in version 16. Version 15 and 15.1, 12/90 New user interface! Enjoy! Some key assignments have changed and some have been removed. New palette editing from Ethan Nagel.\ Reduced memory requirements - Fractint now uses overlays and will run on a 512K machine. New iew command: use to get small window for fast preview, or to setup an image which will eventually be rendered on hard copy with different aspect ratio L-System fractal type from Adrian Mariano\ Postscript printer support from Scott Taylor\ Better Tandy video support and faster CGA video from Joseph A Albrecht\ 16 bit continuous potential files have changed considerably; see the Continuous Potential section for details. Continuous potential is now resumable. Mandelbrot calculation is faster again (thanks to Mike Gelvin) - double speed in 8086 32 bit case Compressed log palette and sqrt palette from Chuck Ebbert\ Calculation automatically resumes whenever current image is resumable and is not paused for a visible reason. Auto increment of savename changed to be more predictable\ New video modes:\ trident 1024x768x256 mode\ 320x480x256 tweak mode (good for reduced 640x480 viewing)\ changed NEC GB-1, hopefully it works now\ Integer mandelbrot and julia now work with periodicitycheck\ Initial zoombox color auto-picked for better contrast (usually)\ New adapter=cga|ega|mcga|vga for systems having trouble with auto-detect\ New textsafe=no|yes for systems having trouble with garbled text mode\ and <3> commands now present list of video modes to pick from; can reduce a non-standard or unviewable image size. Diffusion fractal type is now resumable after interrupt/save\ Exitmode=n parameter, sets video mode to n when exiting from fractint\ When savetime is used with 1 and 2 pass and solid guessing, saves are deferred till the beginning of a new row, so that no calculation time is lost. 3d photographer's mode now allows the first image to be saved to disk\ textcolors=mono|12/34/56/... -- allows setting user interface colors\ Code (again!) compilable under TC++ (we think!)\ .TIW files (from v9.3) are no longer supported as input to 3D transformations bug fixes:\ multiple restores (msc 6.0, fixed in 14.0r)\ repeating 3d loads problem; slow 3d loads of images with float=yes\ map= is now a real substitute for default colors\ starfield and julibrot no longer cause permanent color map replacement\ starfield parameters bug fix - if you couldn't get the starfield parameters to do anything interesting before, try again with this\ release\ Newton and newtbasin orbit display fixed Fixed startup and text screen problems on systems with VESA compliant video adapters. New textsafe=save|bios options.\ Fixes for EGA with monochrome monitor, and for Hercules Graphics Card. Both should now be auto-detected and operate correctly in text modes. Options adapter=egamono and adapter=hgc added. Fixed color L-Systems to not use color 0 (black).\ PostScript printing fix. ; ~Topic=Versions 12 through 14 Version 14, 8/90 LAST MINUTE NEWS FLASH!\ CompuServe announces the GIF89a on August 1, 1990, and Fractint supports it on August 2! GIF files can now contain fractal information! Fractint now saves its files in the new GIF89a format by default, and uses .GIF rather than .FRA as a default filetype. Note that Fractint still *looks* for a .FRA file on file restores if it can't find a .GIF file, and can be coerced into using the old GIF87a format with the new 'gif87a=yes' command-line option. Pieter Branderhorst mounted a major campaign to get his name in lights:\ Mouse interface: Diagonals, faster movement, improved feel. Mouse button assignments have changed - see the online help. Zoom box enhancements: The zoom box can be rotated, stretched, skewed, and panned partially offscreen. See "More Zoom Box Commands". FINALLY!! You asked for it and we (eventually, by talking Pieter into it [actually he grabbed it]) did it! Images can be saved before completion, for a subsequent restore and continue. See "Interrupting and Resuming" and "Batch Mode". Off-center symmetry: Fractint now takes advantage of x or y axis symmetry anywhere on the screen to reduce drawing time. Panning: If you move an image up, down, left, or right, and don't change anything else, only the new edges are calculated. Disk-video caching - it is now possible, reasonable even, to do most things with disk video, including solid guessing, 3d, and plasma. Logarithmic palette changed to use all colors. It now matches regular palette except near the "lake". "logmap=old" gets the old way. New "savetime=nnn" parameter to save checkpoints during long calculations.\ Calculation time is shown in display. Kevin C Allen Finite Attractor, Bifurcation Engine, Magnetic fractals...\ Made Bifurcation/Verhulst into a generalized Fractal Engine (like StandardFractal, but for Bifurcation types), and implemented periodicity checking for Bifurcation types to speed them up. Added Integer version of Verhulst Bifurcation (lots faster now). Integer is the default. The Floating-Point toggle works, too. Added NEW Fractal types BIFLAMBDA, BIF+SINPI, and BIF=SINPI. These are Bifurcation types that make use of the new Engine. Floating- point/Integer toggle is available for BIFLAMBDA. The SINPI types are Floating-Point only, at this time. Corrected the generation of the MandelLambda Set. Sorry, but it's always been wrong (up to v 12, at least). Ask Mandelbrot ! Added NEW Fractal types MAGNET1M, MAGNET1J, MAGNET2M, MAGNET2J from "The Beauty of Fractals". Floating-Point only, so far, but what do you expect with THESE formulae ?! Added new symmetry types XAXIS NOIMAG and XAXIS NOREAL, required by the new MAGNETic Fractal types. Added Finite Attractor Bailout (FAB) logic to detect when iterations are approaching a known finite attractor. This is required by the new MAGNETic Fractal types. Added Finite Attractor Detection (FAD) logic which can be used by *SOME* Julia types prior to generating an image, to test for finite attractors, and find their values, for use by FAB logic. Can be used by the new MAGNETic Fractal Types, Lambda Sets, and some other Julia types too. Mike Burkey sent us new tweaked video modes:\ VGA - 400x600x256 376x564x256 400x564x256\ ATI VGA - 832x612x256 New HP Paintjet support from Chris Martin\ New "FUNCTION=" command to allow substition of different transcendental functions for variables in types (allows one type with four of these variables to represent 7*7*7*7 different types! ALL KINDS of new fractal types, some using "FUNCTION=": fn(z*z), fn*fn, fn*z+z, fn+fn, sqr(1/fn), sqr(fn), spider, tetrate, and Manowar. Most of these are generalizations of formula fractal types contributed by Scott Taylor and Lee Skinner. Distance Estimator logic can now be applied to many fractal types using distest= option. The types "demm" and "demj" have been replaced by "type=mandel distest=nnn" and "type=julia distest=nnn" Added extended memory support for diskvideo thanks to Paul Varner\ Added support for "center and magnification" format for corners.\ Color 0 is no longer generated except when specifically requested with inside= or outside=. Formula name is now included in display and in aved images.\ Bug fixes - formula type and diskvideo, batch file outside=-1 problem.\ Now you can produce your favorite fractal terrains in full color instead of boring old monochrome! Use the fullcolor option in 3d! Along with a few new 3D options. New "INITORBIT=" command to allow alternate Mandelbrot set orbit initialization. Version 13.0, 5/90 F1 was made the help key.\ Use F1 for help\ Use F9 for EGA 320x200x16 video mode\ Use CF4 for EGA 640x200x16 mode (if anybody uses that mode)\ Super-Solid-guessing (three or more passes) from Pieter Branderhorst (replaces the old solid-guessing mode) Boundary Tracing option from David Guenther ("fractint passes=btm", or use the new 'x' options screen) "outside=nnn" option sets all points not "inside" the fractal to color "nnn" (and generates a two-color image). 'x' option from the main menu brings up a full-screen menu of many popular options and toggle switches "Speed Key" feature for fractal type selection (either use the cursor keys for point-and-shoot, or just start typing the name of your favorite fractal type) "Attractor" fractals (Henon, Rossler, Pickover, Gingerbread)\ Diffusion fractal type by Adrian Mariano\ "type=formula" formulas from Scott Taylor and Lee H. Skinner.\ "sound=" options for attractor fractals. Sound=x plays speaker tones according to the 'x' attractor value Sound=y plays speaker tones according to the 'y' attractor value. Sound=z plays speaker tones according to the 'z' attractor value (These options are best invoked with the floating-point algorithm flag set.) "hertz=" option for adjusting the "sound=x/y/z" output.\ Printer support for color printers (printer=color) from Kurt Sowa\ Trident 4000 and Oak Technologies SuperVGA support from John Bridges\ Improved 8514/A support (the zoom-box keeps up with the cursor keys now!)\ Tandy 1000 640x200x16 mode from Brian Corbino (which does not, as yet, work with the F1(help) and TAB functions) The Julibrot fractal type and the Starmap option now automatically verify that they have been selected with a 256-color palette, and search for, and use, the appropriate GLASSESn.MAP or ALTERN.MAP palette map when invoked. *You* were supposed to be doing that manually all along, but *you* probably never read the docs, huh? Bug Fixes:\ TAB key now works after R(estore) commands\ PS/2 Model 30 (MCGA) adapters should be able to select 320x200x256 mode again (we think)\ Everex video adapters should work with the Autodetect modes again (we think) Version 12.0, 3/90 New SuperVGA Autodetecting and VESA Video modes (you tell us the resolution you want, and we'll figure out how to do it) New Full-Screen Entry for most prompting\ New Fractal formula interpreter ('type=formula') - roll your own fractals without using a "C" compiler! New 'Julibrot' fractal type\ Added floating point option to all remaining fractal types.\ Real (funny glasses) 3D - Now with "real-time" lorenz3D!!\ Non-Destructive - Check out what your fractal parameters are without stopping the generation of a fractal image New Cross-Hair mode for changing individual palette colors (VGA only)\ Zooming beyond the limits of Integer algorithms (with automatic switchover to a floating-point algorithm when you zoom in "too far") New 'inside=bof60', 'inside=bof61' ("Beauty of Fractals, Page nn") options\ New starmap ('a' - for astrology? astronomy?) transformation option\ Restrictions on the options available when using Expanded Memory "Disk/RAM" video mode have been removed And a lot of other nice little clean-up features that we've already forgotten that we've added... Added capability to create 3D projection images (just barely) for people with 2 or 4 color video boards. ; ~Topic=Versions 1 through 11 Version 11.0, 1/90 More fractal types\ mandelsinh/lambdasinh mandelcosh/lambdacosh\ mansinzsqrd/julsinzsqrd mansinexp/julsinexp\ manzzprw/julzzpwr manzpower/julzpower\ lorenz (from Rob Beyer) lorenz3d\ complexnewton complexbasin\ dynamic popcorn\ Most fractal types given an integer and a floating point algorithm. "Float=yes" option now determines whether integer or floating-point algorithms are used for most fractal types. "F" command toggles the use of floating-point algorithms, flagged in the status display 8/16/32/../256-Way decomposition option (from Richard Finegold)\ "Biomorph=", "bailout=", "symmetry=" and "askvideo=" options\ "T(ransform)" option in the IFS editor lets you select 3D options (used with the Lorenz3D fractal type) The "T(ype)" command uses a new "Point-and-Shoot" method of selecting fractal types rather than prompting you for a type name Bug fixes to continuous-potential algorithm on integer fractals, GIF encoder, and IFS editor Version 10.0, 11/89 Barnsley IFS type (Rob Beyer)\ Barnsley IFS3D type\ MandelSine/Cos/Exp type\ MandelLambda/MarksLambda/Unity type\ BarnsleyM1/J1/M2/J2/M3/J3 type\ Mandel4/Julia4 type\ Sierpinski gasket type\ Demm/Demj and bifurcation types (Phil Wilson), "test" is "mandel" again\ nversion command for most fractal types\ uaternary decomposition toggle and "DECOMP=" argument\ ditor for Barnsley IFS parameters\ Command-line options for 3D parameters\ Spherical 3D calculations 5x faster\ 3D now clips properly to screen edges and works at extreme perspective\ "RSEED=" argument for reproducible plasma clouds\ Faster plasma clouds (by 40% on a 386)\ Sensitivity to "continuous potential" algorithm for all types except plasma and IFS Palette-map ave and Restore () commands\ ogarithmic and ormal palette-mapping commands and arguments\ Maxiter increased to 32,000 to support log palette maps\ .MAP and .IFS files can now reside anywhere along the DOS path\ Direct-video support for Hercules adapters (Dean Souleles)\ Tandy 1000 160x200x16 mode (Tom Price)\ 320x400x256 register-compatible-VGA "tweaked" mode\ ATI VGA Wonder 1024x768x16 direct-video mode (Mark Peterson)\ 1024x768x16 direct-video mode for all supported chipsets\ Tseng 640x400x256 mode\ "Roll-your-own" video mode 19\ New video-table "hot-keys" eliminate need for enhanced keyboard to access later entries Version 9.3, 8/89

rint command and "PRINTER=" argument (Matt Saucier)\ 8514/A video modes (Kyle Powell)\ SSTOOLS.INI sensitivity and '@THISFILE' argument\ Continuous-potential algorithm for Mandelbrot/Julia sets\ Light source 3D option for all fractal types\ "Distance estimator" M/J method (Phil Wilson) implemented as "test" type\ LambdaCosine and LambdaExponent types\ Color cycling mode for 640x350x16 EGA adapters\ Plasma clouds for 16-color and 4-color video modes\ Improved TARGA support (Joe McLain)\ CGA modes now use direct-video read/writes\ Tandy 1000 320x200x16 and 640x200x4 modes (Tom Price)\ TRIDENT chip-set super-VGA video modes (Lew Ramsey)\ Direct-access video modes for TRIDENT, Chips & Technologies, and ATI VGA WONDER adapters (John Bridges). and, unlike version 9.1, they WORK in version 9.3!) "zoom-out" () command\ os command for shelling out\ 2/4/16-color Disk/RAM video mode capability and 2-color video modes supporting full-page printer graphics "INSIDE=-1" option (treated dynamically as "INSIDE=maxiter")\ Improved elp and sound routines (even a "SOUND=off" argument)\ Turbo-C and TASM compatibility (really! Would we lie to you?) Version 8.1, 6/89 <3>D restore-from-disk and 3D verlay commands, "3D=" argument\ Fast Newton algorithm including inversion option (Lee Crocker)\ 16-bit Mandelbrot/Julia logic for 386-class speed with non-386 PCs on "large" images (Mark Peterson) Restore now loads .GIF files (as plasma clouds)\ TARGA video modes and color-map file options (Joe McLain)\ 30 new color-cycling palette options ( to )\ "Disk-video, RAM-video, EMS-video" modes\ Lambda sets now use integer math (with 80386 speedups)\ "WARN=yes" argument to prevent over-writing old .GIF files Version 7.0, 4/89 Restore from disk (from prior save-to-disk using v. 7.0 or later)\ New types: Newton, Lambda, Mandelfp, Juliafp, Plasma, Lambdasine\ Many new color-cycling options (for VGA adapters only)\ New periodicity logic (Mark Peterson)\ Initial displays recognize (and use) symmetry\ Solid-guessing option (now the default)\ Context-sensitive elp\ Customizable video mode configuration file (FRACTINT.CFG)\ "Batch mode" option\ Improved super-VGA support (with direct video read/writes)\ Non-standard 360 x 480 x 256 color mode on a STANDARD IBM VGA! Version 6.0, 2/89 32-bit integer math emulated for non-386 processors; FRACT386 renamed FRACTINT More video modes Version 5.1, 1/89 Save to disk\ New! Improved! (and Incompatible!) optional arguments format\ "Correct" initial image aspect ratio\ More video modes Version 4.0, 12/88 Mouse support (Mike Kaufman)\ Dynamic iteration limits\ Color cycling\ Dual-pass mode\ More video modes, including "tweaked" modes for IBM VGA and register- compatible adapters Version 3.1, 11/88 Julia sets Version 2.1, 10/23/88 (the "debut" on CIS) Video table\ CPU type detector Version 2.0, 10/10/88 Zoom and pan Version 1.0, 9/88 The original, blindingly fast, 386-specific 32-bit integer algorithm ; ; ; ~Data=INTRO_AUTHORS ; ; FRACTINT intro screen primary authors ; Primary Authors (current version) Timothy Wegner twegner AT fractint.org Jonathan Osuch josuch AT fractint.org Contributing Authors ; room for 15 authors at a time here SPACEBAR toggles scrolling off/on Copyright (C) 1990-2009 The Stone Soup Group. Fractint may be freely copied and distributed but may not be sold. See help for more information. ; ; ; ~Data=INTRO_CREDITS ; ; FRACTINT intro screen contributing authors. ; ... Michael Abrash 360x480x256, 320x400x256 VGA video modes Rees Acheson (Author of MandelB) pentium speedups Joseph Albrecht Tandy video, CGA video speedup Kevin Allen Finite attractor, bifurcation engine Humberto Baptista passes=d, latoocarfian type Steve Bennett restore-from-disk logic Rob Beyer Barnsley IFS, Lorenz fractals Francois Blais Lyapunov Fractals, LYAPUNOV.MAP Scott D. Boyd Xfractint user interface cleanup Dennis Bragg DXF Raytracing output option Juan J. Buhler Diffusion options, inverse Julia type Mike Burkey 376x564x256, 400x564x256, and 832x612x256 VGA video modes Robin Bussell Fractal browser and evolver, past primary author John Bridges superVGA support, 360x480x256 mode Fulvio Cappelli ants options and speedup Charlie Chernohorsky Virtual VESA screen sizes & speedup Brian Corbino Tandy 1000 640x200x16 video mode Lee Crocker Fast Newton, Inversion, Decomposition.. Monte Davis Documentation Paul De Leeuw RDS (Random Dot Stereogram) Feature Jean-Pierre Demailly Xfractint truecolor support and pure X11 port Chuck Ebbert cmprsd & sqrt logmap, fpu speedups, fast parser Dan Farmer orbits enhancements Richard Finegold 8/16/../256-Way Decomposition option Frank Fussenegger Mandelbrot speedups Sylvie Gallet Formula and math wizard Mike Gelvin Mandelbrot speedups Luciano Genero ants options and speedup Lawrence Gozum Tseng 640x400x256 Video Mode David Guenther Boundary Tracing algorithm Jay Hill Windows notes Mike Kaufman mouse support, other features Norman Hills Ranges option Richard Hughes "inside=", "outside=" coloring options Bill Jemison orbitsave=sound option Damien M. Jones Windows notes, web hosting Wesley Loewer Arbitrary precision, past primary author Adrian Mariano Diffusion & L-Systems Charles Marslett VESA video and IIT math chip support George Martin Formula parser, past primary author Andrew McCarthy European keyboard support Joe McLain TARGA Support, color-map files Bob Montgomery (Author of VPIC) Fast text I/O routines Bret Mulvey plasma clouds Roy Murphy Lyapunov Fractals Ethan Nagel Palette editor, integrated help/doc system Yavuz Onder Postscript printer driver Kyle Powell 8514/A Support Mark Peterson Parser, julibrot, past primary author Marc Reinig Lots of 3D options Pieter Branderhorst Solid guessing, menus, past primary author Michael Sargent Volterra-Lotka, escher_julia fractals Matt Saucier Printer Support Herb Savage 'inside=bof60', 'inside=bof61' options Ken Shirriff Quaternions, CA, Xfractint port Lee Skinner Tetrate fractal types and more Michael Snyder julia inverse and Julia-In-A-Window using MIIM Dean Souleles Hercules Support Kurt Sowa Color Printer Support Hugh Steele cyclerange feature Iain Stirling Inside=fmod and outside=fmod John Swenson Postscript printer features Chris Taylor Floating&Fixed-point algorithm speedups, Tesseral Option Scott Taylor PostScript, Kam Torus, many fn types. Rich Thomson Xfractint truecolor support, mailing list Bill Townsend Mandelbrot Speedups Bert Tyler Original Fractint/Fract386 Author Paul Varner Extended Memory support for Disk Video Dave Warker Integer Mandelbrot Fractals concept Aaron Williams Register-compatible 8514/A code Phil Wilson Distance Estimator, Bifurcation fractals Nicholas Wilt Lsystem speedups Richard Wilton Tweaked VGA Video modes ; ; xfractint-20.4.10.orig/dos_help/help2.src0000644000000000000000000042454111071025125015031 0ustar ~Topic=Summary of Fractal Types, Label=HELPFRACTALS ~Format- ~Doc- For detailed descriptions, select a hot-link below, see {Fractal Types}, or use from the fractal type selection screen. ~Doc+,Online- SUMMARY OF FRACTAL TYPES ~Online+ ~CompressSpaces- ; ; Note that prompts.c pulls formulas out of the following for screen, ; using the HF_xxx labels. It assumes a rigid formatting structure for ; the formulas: ; 4 leading blanks (which get stripped on screen) ; lines no wider than 76 characters (not counting initial 4 spaces) ; formula ends at any of: ; blank line ; line which begins in column 1 ; format ctl char (~xxx, {xxx}, \x) ; {=HT_ANT ant} ~Label=HF_ANT Generalized Ant Automaton as described in the July 1994 Scientific American. Some ants wander around the screen. A rule string (the first parameter) determines the ant's direction. When the type 1 ant leaves a cell of color k, it turns right if the kth symbol in the first parameter is a 1, or left otherwise. Then the color in the old cell is incremented. The 2nd parameter is a maximum iteration to guarantee that the fractal will terminate. The 3rd parameter is the number of ants. The 4th is the ant type 1 or 2. The 5th parameter determines if the ants wrap the screen or stop at the edge. The 6th parameter is a random seed. You can slow down the ants to see them better using the

screen Orbit Delay. {=HT_BARNS barnsleyj1} ~Label=HF_BARNSJ1 z(0) = pixel; if real(z) >= 0 z(n+1) = (z-1)*c else z(n+1) = (z+1)*c Two parameters: real and imaginary parts of c {=HT_BARNS barnsleyj2} ~Label=HF_BARNSJ2 z(0) = pixel; if real(z(n)) * imag(c) + real(c) * imag(z(n)) >= 0 z(n+1) = (z(n)-1)*c else z(n+1) = (z(n)+1)*c Two parameters: real and imaginary parts of c {=HT_BARNS barnsleyj3} ~Label=HF_BARNSJ3 z(0) = pixel; if real(z(n)) > 0 then z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1) + i * (2*real(z(n)) * imag(z(n))) else z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1 + real(c) * real(z(n)) + i * (2*real(z(n)) * imag(z(n)) + imag(c) * real(z(n))) Two parameters: real and imaginary parts of c. {=HT_BARNS barnsleym1} ~Label=HF_BARNSM1 z(0) = c = pixel; if real(z) >= 0 then z(n+1) = (z-1)*c else z(n+1) = (z+1)*c. Parameters are perturbations of z(0) {=HT_BARNS barnsleym2} ~Label=HF_BARNSM2 z(0) = c = pixel; if real(z)*imag(c) + real(c)*imag(z) >= 0 z(n+1) = (z-1)*c else z(n+1) = (z+1)*c Parameters are perturbations of z(0) {=HT_BARNS barnsleym3} ~Label=HF_BARNSM3 z(0) = c = pixel; if real(z(n)) > 0 then z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1) + i * (2*real(z(n)) * imag(z(n))) else z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1 + real(c) * real(z(n)) + i * (2*real(z(n)) * imag(z(n)) + imag(c) * real(z(n))) Parameters are perturbations of z(0) {=HT_BIF bifurcation} ~Label=HF_BIFURCATION Pictorial representation of a population growth model. Let P = new population, p = oldpopulation, r = growth rate The model is: P = p + r*fn(p)*(1-fn(p)). Three parameters: Filter Cycles, Seed Population, and Function. {=HT_BIF bif+sinpi} ~Label=HF_BIFPLUSSINPI Bifurcation variation: model is: P = p + r*fn(PI*p). Three parameters: Filter Cycles, Seed Population, and Function. {=HT_BIF bif=sinpi} ~Label=HF_BIFEQSINPI Bifurcation variation: model is: P = r*fn(PI*p). Three parameters: Filter Cycles, Seed Population, and Function. {=HT_BIF biflambda} ~Label=HF_BIFLAMBDA Bifurcation variation: model is: P = r*fn(p)*(1-fn(p)). Three parameters: Filter Cycles, Seed Population, and Function. {=HT_BIF bifstewart} ~Label=HF_BIFSTEWART Bifurcation variation: model is: P = (r*fn(p)*fn(p)) - 1. Three parameters: Filter Cycles, Seed Population, and Function. {=HT_BIF bifmay} ~Label=HF_BIFMAY Bifurcation variation: model is: P = r*p / ((1+p)^beta). Three parameters: Filter Cycles, Seed Population, and Beta. ~OnlineFF {=HT_CELLULAR cellular} ~Label=HF_CELLULAR One-dimensional cellular automata or line automata. The type of CA is given by kr, where k is the number of different states of the automata and r is the radius of the neighborhood. The next generation is determined by the sum of the neighborhood and the specified rule. Four parameters: Initial String, Rule, Type, and Starting Row Number. For Type = 21, 31, 41, 51, 61, 22, 32, 42, 23, 33, 24, 25, 26, 27 Rule = 4, 7, 10, 13, 16, 6, 11, 16, 8, 15, 10, 12, 14, 16 digits {=HT_MARTIN chip} ~Label=HF_CHIP Chip attractor from Michael Peters - orbit in two dimensions. z(0) = y(0) = 0; x(n+1) = y(n) - sign(x(n)) * cos(sqr(ln(abs(b*x(n)-c)))) * arctan(sqr(ln(abs(c*x(n)-b)))) y(n+1) = a - x(n) Parameters are a, b, and c. ~OnlineFF {=HT_CIRCLE circle} ~Label=HF_CIRCLE Circle pattern by John Connett x + iy = pixel z = a*(x^2 + y^2) c = integer part of z color = c modulo(number of colors) {=HT_MARKS cmplxmarksjul} ~Label=HF_CMPLXMARKSJUL A generalization of the marksjulia fractal. z(0) = pixel; z(n+1) = c^(exp-1)*z(n)^2 + c. Four parameters: real and imaginary parts of c, and real and imaginary parts of exponent. {=HT_MARKS cmplxmarksmand} ~Label=HF_CMPLXMARKSMAND A generalization of the marksmandel fractal. z(0) = c = pixel; z(n+1) = c^(exp-1)*z(n)^2 + c. Four parameters: real and imaginary parts of perturbation of z(0), and real and imaginary parts of exponent. ~OnlineFF {=HT_NEWTCMPLX complexnewton\, complexbasin} ~Label=HF_COMPLEXNEWT Newton fractal types extended to complex degrees. Complexnewton colors pixels according to the number of iterations required to escape to a root. Complexbasin colors pixels according to which root captures the orbit. The equation is based on the newton formula for solving the equation z^p = r z(0) = pixel; z(n+1) = ((p - 1) * z(n)^p + r)/(p * z(n)^(p - 1)). Four parameters: real & imaginary parts of degree p and root r. {=HT_DIFFUS diffusion} ~Label=HF_DIFFUS Diffusion Limited Aggregation. Randomly moving points accumulate. Three parameters: border width (default 10), type, and color change rate. {=HT_DIVIDEBROT5 dividebrot5} ~Label=HF_DIVIDEBROT5 DivideBrot5 formula by Jim Muth. z(0) = 0; z(n+1) = sqr(z(n)) / (z(n)^(-(a-2)) + (b+10^(-20))) + pixel Two parameters: a and b ~OnlineFF {=HT_DYNAM dynamic} ~Label=HF_DYNAM Time-discrete dynamic system. x(0) = y(0) = start position. y(n+1) = y(n) + f( x(n) ) x(n+1) = x(n) - f( y(n) ) f(k) = sin(k + a*fn1(b*k)) For implicit Euler approximation: x(n+1) = x(n) - f( y(n+1) ) Five parameters: start position step, dt, a, b, and the function fn1. {=HT_ESCHER escher_julia} ~Label=HF_ESCHER Escher-like tiling of Julia sets from The Science of Fractal Images z(0) = pixel z(n+1) = z(n)^2 + (0, 0i) The target set is a second, scaled, Julia set: T = [ z: | (z * 15.0)^2 + c | < BAILOUT ] Two parameters: real and imaginary parts of c Iteration count and bailout size apply to both Julia sets. ~OnlineFF {=HT_SCOTSKIN fn(z)+fn(pix)} ~Label=HF_FNPLUSFNPIX c = z(0) = pixel; z(n+1) = fn1(z) + p*fn2(c) Six parameters: real and imaginary parts of the perturbation of z(0) and factor p, and the functions fn1, and fn2. {=HT_SCOTSKIN fn(z*z)} ~Label=HF_FNZTIMESZ z(0) = pixel; z(n+1) = fn(z(n)*z(n)) One parameter: the function fn. {=HT_SCOTSKIN fn*fn} ~Label=HF_FNTIMESFN z(0) = pixel; z(n+1) = fn1(n)*fn2(n) Two parameters: the functions fn1 and fn2. ~OnlineFF {=HT_SCOTSKIN fn*z+z} ~Label=HF_FNXZPLUSZ z(0) = pixel; z(n+1) = p1*fn(z(n))*z(n) + p2*z(n) Five parameters: the real and imaginary components of p1 and p2, and the function fn. {=HT_SCOTSKIN fn+fn} ~Label=HF_FNPLUSFN z(0) = pixel; z(n+1) = p1*fn1(z(n))+p2*fn2(z(n)) Six parameters: The real and imaginary components of p1 and p2, and the functions fn1 and fn2. {=HT_FORMULA formula} Formula interpreter - write your own formulas as text files! ~OnlineFF {=HT_FROTH frothybasin} ~Label=HF_FROTH Pixel color is determined by which attractor captures the orbit. The shade of color is determined by the number of iterations required to capture the orbit. Z(0) = pixel; Z(n+1) = Z(n)^2 - C*conj(Z(n)) where C = 1 + A*i, critical value of A = 1.028713768218725... {=HT_GINGER gingerbread} ~Label=HF_GINGER Orbit in two dimensions defined by: x(n+1) = 1 - y(n) + |x(n)| y(n+1) = x(n) Two parameters: initial values of x(0) and y(0). {=HT_HALLEY halley} ~Label=HF_HALLEY Halley map for the function: F = z(z^a - 1) = 0 z(0) = pixel; z(n+1) = z(n) - R * F / [F' - (F" * F / 2 * F')] bailout when: abs(mod(z(n+1)) - mod(z(n)) < epsilon Four parameters: order a, real part of R, epsilon, and imaginary part of R. ~OnlineFF {=HT_HENON henon} ~Label=HF_HENON Orbit in two dimensions defined by: x(n+1) = 1 + y(n) - a*x(n)*x(n) y(n+1) = b*x(n) Two parameters: a and b {=HT_MARTIN hopalong} ~Label=HF_HOPALONG Hopalong attractor by Barry Martin - orbit in two dimensions. z(0) = y(0) = 0; x(n+1) = y(n) - sign(x(n))*sqrt(abs(b*x(n)-c)) y(n+1) = a - x(n) Parameters are a, b, and c. ~FF {=HT_HYPERC hypercomplex} ~Label=HF_HYPERC HyperComplex Mandelbrot set. h(0) = (0,0,0,0) h(n+1) = fn(h(n)) + C. where "fn" is sin, cos, log, sqr etc. Two parameters: cj, ck C = (xpixel,ypixel,cj,ck) {=HT_HYPERC hypercomplexj} ~Label=HF_HYPERCJ HyperComplex Julia set. h(0) = (xpixel,ypixel,zj,zk) h(n+1) = fn(h(n)) + C. where "fn" is sin, cos, log, sqr etc. Six parameters: c1, ci, cj, ck C = (c1,ci,cj,ck) ~OnlineFF {=HT_ICON icon, icon3d} ~Label=HF_ICON Orbit in three dimensions defined by: p = lambda + alpha * magnitude + beta * (x(n)*zreal - y(n)*zimag) x(n+1) = p * x(n) + gamma * zreal - omega * y(n) y(n+1) = p * y(n) - gamma * zimag + omega * x(n) (3D version uses magnitude for z) Parameters: Lambda, Alpha, Beta, Gamma, Omega, and Degree {=HT_IFS IFS} Barnsley IFS (Iterated Function System) fractals. Apply contractive affine mappings. {=HT_PICKMJ julfn+exp} ~Label=HF_JULFNPLUSEXP A generalized Clifford Pickover fractal. z(0) = pixel; z(n+1) = fn(z(n)) + e^z(n) + c. Three parameters: real & imaginary parts of c, and fn {=HT_PICKMJ julfn+zsqrd} ~Label=HF_JULFNPLUSZSQRD z(0) = pixel; z(n+1) = fn(z(n)) + z(n)^2 + c Three parameters: real & imaginary parts of c, and fn {=HT_JULIA julia} ~Label=HF_JULIA Classic Julia set fractal. z(0) = pixel; z(n+1) = z(n)^2 + c. Two parameters: real and imaginary parts of c. {=HT_INVERSE julia_inverse} ~Label=HF_INVERSE Inverse Julia function - "orbit" traces Julia set in two dimensions. z(0) = a point on the Julia Set boundary; z(n+1) = +- sqrt(z(n) - c) Parameters: Real and Imaginary parts of c Maximum Hits per Pixel (similar to max iters) Breadth First, Depth First or Random Walk Tree Traversal Left or Right First Branching (in Depth First mode only) Try each traversal method, keeping everything else the same. Notice the differences in the way the image evolves. Start with a fairly low Maximum Hit limit, then increase it. The hit limit cannot be higher than the maximum colors in your video mode. ~OnlineFF {=HT_FNORFN julia(fn||fn)} ~Label=HF_JULIAFNFN z(0) = pixel; if modulus(z(n)) < shift value, then z(n+1) = fn1(z(n)) + c, else z(n+1) = fn2(z(n)) + c. Five parameters: real, imag portions of c, shift value, fn1, fn2. {=HT_MANDJUL4 julia4} ~Label=HF_JULIA4 Fourth-power Julia set fractals, a special case of julzpower kept for speed. z(0) = pixel; z(n+1) = z(n)^4 + c. Two parameters: real and imaginary parts of c. {=HT_JULIBROT julibrot} 'Julibrot' 4-dimensional fractals. {=HT_PICKMJ julzpower} ~Label=HF_JULZPOWER z(0) = pixel; z(n+1) = z(n)^m + c. Three parameters: real & imaginary parts of c, exponent m {=HT_PICKMJ julzzpwr} ~Label=HF_JULZZPWR z(0) = pixel; z(n+1) = z(n)^z(n) + z(n)^m + c. Three parameters: real & imaginary parts of c, exponent m {=HT_KAM kamtorus, kamtorus3d} ~Label=HF_KAM Series of orbits superimposed. 3d version has 'orbit' the z dimension. x(0) = y(0) = orbit/3; x(n+1) = x(n)*cos(a) + (x(n)*x(n)-y(n))*sin(a) y(n+1) = x(n)*sin(a) - (x(n)*x(n)-y(n))*cos(a) After each orbit, 'orbit' is incremented by a step size. Parameters: a, step size, stop value for 'orbit', and points per orbit. {=HT_LAMBDA lambda} ~Label=HF_LAMBDA Classic Lambda fractal. 'Julia' variant of Mandellambda. z(0) = pixel; z(n+1) = lambda*z(n)*(1 - z(n)). Two parameters: real and imaginary parts of lambda. {=HT_LAMBDAFN lambdafn} ~Label=HF_LAMBDAFN z(0) = pixel; z(n+1) = lambda * fn(z(n)). Three parameters: real, imag portions of lambda, and fn {=HT_FNORFN lambda(fn||fn)} ~Label=HF_LAMBDAFNFN z(0) = pixel; if modulus(z(n)) < shift value, then z(n+1) = lambda * fn1(z(n)), else z(n+1) = lambda * fn2(z(n)). Five parameters: real, imag portions of lambda, shift value, fn1, fn2 {=HT_LATOO latoocarfian} ~Label=HF_LATOO Orbit in two dimensions defined by: x(n+1) = fn1 (y(n) * b) + c * fn2(x(n) * b) y(n+1) = fn3 (x(n) * a) + d * fn4(y(n) * a) Parameters: a, b, c, d fn1..4 (all sin=original) ~OnlineFF {=HT_LORENZ lorenz, lorenz3d} ~Label=HF_LORENZ Lorenz two lobe attractor - orbit in three dimensions. In 2d the x and y components are projected to form the image. z(0) = y(0) = z(0) = 1; x(n+1) = x(n) + (-a*x(n)*dt) + ( a*y(n)*dt) y(n+1) = y(n) + ( b*x(n)*dt) - ( y(n)*dt) - (z(n)*x(n)*dt) z(n+1) = z(n) + (-c*z(n)*dt) + (x(n)*y(n)*dt) Parameters are dt, a, b, and c. {=HT_LORENZ lorenz3d1} ~Label=HF_LORENZ3D1 Lorenz one lobe attractor, 3D orbit (Rick Miranda and Emily Stone) z(0) = y(0) = z(0) = 1; norm = sqrt(x(n)^2 + y(n)^2) x(n+1) = x(n) + (-a*dt-dt)*x(n) + (a*dt-b*dt)*y(n) + (dt-a*dt)*norm + y(n)*dt*z(n) y(n+1) = y(n) + (b*dt-a*dt)*x(n) - (a*dt+dt)*y(n) + (b*dt+a*dt)*norm - x(n)*dt*z(n) - norm*z(n)*dt z(n+1) = z(n) +(y(n)*dt/2) - c*dt*z(n) Parameters are dt, a, b, and c. ~OnlineFF {=HT_LORENZ lorenz3d3} ~Label=HF_LORENZ3D3 Lorenz three lobe attractor, 3D orbit (Rick Miranda and Emily Stone) z(0) = y(0) = z(0) = 1; norm = sqrt(x(n)^2 + y(n)^2) x(n+1) = x(n) +(-(a*dt+dt)*x(n) + (a*dt-b*dt+z(n)*dt)*y(n))/3 + ((dt-a*dt)*(x(n)^2-y(n)^2) + 2*(b*dt+a*dt-z(n)*dt)*x(n)*y(n))/(3*norm) y(n+1) = y(n) +((b*dt-a*dt-z(n)*dt)*x(n) - (a*dt+dt)*y(n))/3 + (2*(a*dt-dt)*x(n)*y(n) + (b*dt+a*dt-z(n)*dt)*(x(n)^2-y(n)^2))/(3*norm) z(n+1) = z(n) +(3*x(n)*dt*x(n)*y(n)-y(n)*dt*y(n)^2)/2 - c*dt*z(n) Parameters are dt, a, b, and c. ~OnlineFF {=HT_LORENZ lorenz3d4} ~Label=HF_LORENZ3D4 Lorenz four lobe attractor, 3D orbit (Rick Miranda and Emily Stone) z(0) = y(0) = z(0) = 1; x(n+1) = x(n) +(-a*dt*x(n)^3 + (2*a*dt+b*dt-z(n)*dt)*x(n)^2*y(n) + (a*dt-2*dt)*x(n)*y(n)^2 + (z(n)*dt-b*dt)*y(n)^3) / (2 * (x(n)^2+y(n)^2)) y(n+1) = y(n) +((b*dt-z(n)*dt)*x(n)^3 + (a*dt-2*dt)*x(n)^2*y(n) + (-2*a*dt-b*dt+z(n)*dt)*x(n)*y(n)^2 - a*dt*y(n)^3) / (2 * (x(n)^2+y(n)^2)) z(n+1) = z(n) +(2*x(n)*dt*x(n)^2*y(n) - 2*x(n)*dt*y(n)^3 - c*dt*z(n)) Parameters are dt, a, b, and c. {=HT_LSYS lsystem} Using a turtle-graphics control language and starting with an initial axiom string, carries out string substitutions the specified number of times (the order), and plots the result. {=HT_LYAPUNOV lyapunov} Derived from the Bifurcation fractal, the Lyapunov plots the Lyapunov Exponent for a population model where the Growth parameter varies between two values in a periodic manner. {=HT_MAGNET magnet1j} ~Label=HF_MAGJ1 z(0) = pixel; [ z(n)^2 + (c-1) ] 2 z(n+1) = | ---------------- | [ 2*z(n) + (c-2) ] Parameters: the real and imaginary parts of c {=HT_MAGNET magnet1m} ~Label=HF_MAGM1 z(0) = 0; c = pixel; [ z(n)^2 + (c-1) ] 2 z(n+1) = | ---------------- | [ 2*z(n) + (c-2) ] Parameters: the real & imaginary parts of perturbation of z(0) {=HT_MAGNET magnet2j} ~Label=HF_MAGJ2 z(0) = pixel; [ z(n)^3 + 3*(C-1)*z(n) + (C-1)*(C-2) ] 2 z(n+1) = | -------------------------------------------- | [ 3*(z(n)^2) + 3*(C-2)*z(n) + (C-1)*(C-2) + 1 ] Parameters: the real and imaginary parts of c ~OnlineFF {=HT_MAGNET magnet2m} ~Label=HF_MAGM2 z(0) = 0; c = pixel; [ z(n)^3 + 3*(C-1)*z(n) + (C-1)*(C-2) ] 2 z(n+1) = | -------------------------------------------- | [ 3*(z(n)^2) + 3*(C-2)*z(n) + (C-1)*(C-2) + 1 ] Parameters: the real and imaginary parts of perturbation of z(0) {=HT_MANDEL mandel} ~Label=HF_MANDEL Classic Mandelbrot set fractal. z(0) = c = pixel; z(n+1) = z(n)^2 + c. Two parameters: real & imaginary perturbations of z(0) {=HT_FNORFN mandel(fn||fn)} ~Label=HF_MANDELFNFN c = pixel; z(0) = p1 if modulus(z(n)) < shift value, then z(n+1) = fn1(z(n)) + c, else z(n+1) = fn2(z(n)) + c. Five parameters: real, imaginary portions of p1, shift value, fn1 and fn2. ;{=HT_MANDELBROTMIX4 mandelbrotmix4} ;~Label=HF_MANDELBROTMIX4 ; From a Jim Muth favorite FOTD formula ; a=real(p1), b=imag(p1), d=real(p2), f=imag(p2), ; g=1/f, h=1/d, j=1/(f-b), z=(-a*b*g*h)^j, ; k=real(p3)+1, l=imag(p3)+100, c=fn1(pixel): ; z=k*((a*(z^b))+(d*(z^f)))+c ; Parameters: see above, sixth parameter used for bailout ; {=HT_MANDELCLOUD mandelcloud} ~Label=HF_MANDELCLOUD Displays orbits of Mandelbrot set: z(0) = c = pixel; z(n+1) = z(n)^2 + c. One parameter: number of intervals {=HT_MANDJUL4 mandel4} ~Label=HF_MANDEL4 Special case of mandelzpower kept for speed. z(0) = c = pixel; z(n+1) = z(n)^4 + c. Parameters: real & imaginary perturbations of z(0) ~OnlineFF {=HT_MANDFN mandelfn} ~Label=HF_MANDFN z(0) = c = pixel; z(n+1) = c*fn(z(n)). Parameters: real & imaginary perturbations of z(0), and fn {=HT_FNORFN manlam(fn||fn)} ~Label=HF_MANLAMFNFN c = pixel; z(0) = p1 if modulus(z(n)) < shift value, then z(n+1) = fn1(z(n)) * c, else z(n+1) = fn2(z(n)) * c. Five parameters: real, imaginary parts of p1, shift value, fn1, fn2. {=HT_MARTIN Martin} ~Label=HF_MARTIN Attractor fractal by Barry Martin - orbit in two dimensions. z(0) = y(0) = 0; x(n+1) = y(n) - sin(x(n)) y(n+1) = a - x(n) Parameter is a (try a value near pi) ~OnlineFF {=HT_MLAMBDA mandellambda} ~Label=HF_MLAMBDA z(0) = .5; lambda = pixel; z(n+1) = lambda*z(n)*(1 - z(n)). Parameters: real & imaginary perturbations of z(0) {=HT_PHOENIX mandphoenix} ~Label=HF_MANDPHOENIX z(0) = c = pixel, y(0) = 0; For degree = 0: z(n+1) = z(n)^2 + c.x + c.y*y(n), y(n+1) = z(n) For degree >= 2: z(n+1) = z(n)^degree + c.x*z(n)^(degree-1) + c.y*y(n) y(n+1) = z(n) For degree <= -3: z(n+1) = z(n)^|degree| + c.x*z(n)^(|degree|-2) + c.y*y(n) y(n+1) = z(n) Three parameters: real & imaginary perturbations of z(0), and degree. ~OnlineFF {=HT_PHOENIX mandphoenixclx} ~Label=HF_MANDPHOENIXCPLX z(0) = c = pixel, y(0) = 0; For degree = 0: z(n+1) = z(n)^2 + c + p2*y(n), y(n+1) = z(n) For degree >= 2: z(n+1) = z(n)^degree + c*z(n)^(degree-1) + p2*y(n), y(n+1) = z(n) For degree <= -3: z(n+1) = z(n)^|degree| + c*z(n)^(|degree|-2) + p2*y(n), y(n+1) = z(n) Five parameters: real & imaginary perturbations of z(0), real & imaginary parts of p2, and degree. {=HT_PICKMJ manfn+exp} ~Label=HF_MANDFNPLUSEXP 'Mandelbrot-Equivalent' for the julfn+exp fractal. z(0) = c = pixel; z(n+1) = fn(z(n)) + e^z(n) + C. Parameters: real & imaginary perturbations of z(0), and fn {=HT_PICKMJ manfn+zsqrd} ~Label=HF_MANDFNPLUSZSQRD 'Mandelbrot-Equivalent' for the Julfn+zsqrd fractal. z(0) = c = pixel; z(n+1) = fn(z(n)) + z(n)^2 + c. Parameters: real & imaginary perturbations of z(0), and fn {=HT_SCOTSKIN manowar} ~Label=HF_MANOWAR c = z1(0) = z(0) = pixel; z(n+1) = z(n)^2 + z1(n) + c; z1(n+1) = z(n); Parameters: real & imaginary perturbations of z(0) {=HT_SCOTSKIN manowarj} ~Label=HF_MANOWARJ z1(0) = z(0) = pixel; z(n+1) = z(n)^2 + z1(n) + c; z1(n+1) = z(n); Parameters: real & imaginary parts of c ~OnlineFF {=HT_PICKMJ manzpower} ~Label=HF_MANZPOWER 'Mandelbrot-Equivalent' for julzpower. z(0) = c = pixel; z(n+1) = z(n)^exp + c; try exp = e = 2.71828... Parameters: real & imaginary perturbations of z(0), real & imaginary parts of exponent exp. {=HT_PICKMJ manzzpwr} ~Label=HF_MANZZPWR 'Mandelbrot-Equivalent' for the julzzpwr fractal. z(0) = c = pixel z(n+1) = z(n)^z(n) + z(n)^exp + C. Parameters: real & imaginary perturbations of z(0), and exponent ~OnlineFF {=HT_MARKS marksjulia} ~Label=HF_MARKSJULIA A variant of the julia-lambda fractal. z(0) = pixel; z(n+1) = c^(exp-1)*z(n)^2 + c. Parameters: real & imaginary parts of c, and exponent {=HT_MARKS marksmandel} ~Label=HF_MARKSMAND A variant of the mandel-lambda fractal. z(0) = c = pixel; z(n+1) = c^(exp-1)*z(n)^2 + c. Parameters: real & imaginary parts of perturbations of z(0), and exponent {=HT_MARKS marksmandelpwr} ~Label=HF_MARKSMANDPWR The marksmandelpwr formula type generalized (it previously had fn=sqr hard coded). z(0) = pixel, c = z(0) ^ (z(0) - 1): z(n+1) = c * fn(z(n)) + pixel, Parameters: real and imaginary perturbations of z(0), and fn ~OnlineFF {=HT_NEWTBAS newtbasin} ~Label=HF_NEWTBAS Based on the Newton formula for finding the roots of z^p - 1. Pixels are colored according to which root captures the orbit. z(0) = pixel; z(n+1) = ((p-1)*z(n)^p + 1)/(p*z(n)^(p - 1)). Two parameters: the polynomial degree p, and a flag to turn on color stripes to show alternate iterations. {=HT_NEWT newton} ~Label=HF_NEWT Based on the Newton formula for finding the roots of z^p - 1. Pixels are colored according to the iteration when the orbit is captured by a root. z(0) = pixel; z(n+1) = ((p-1)*z(n)^p + 1)/(p*z(n)^(p - 1)). One parameter: the polynomial degree p. ~OnlineFF {=HT_PHOENIX phoenix} ~Label=HF_PHOENIX z(0) = pixel, y(0) = 0; For degree = 0: z(n+1) = z(n)^2 + p1.x + p2.x*y(n), y(n+1) = z(n) For degree >= 2: z(n+1) = z(n)^degree + p1.x*z(n)^(degree-1) + p2.x*y(n), y(n+1) = z(n) For degree <= -3: z(n+1) = z(n)^|degree| + p1.x*z(n)^(|degree|-2) + p2.x*y(n), y(n+1) = z(n) Three parameters: real parts of p1 & p2, and degree. {=HT_PHOENIX phoenixcplx} ~Label=HF_PHOENIXCPLX z(0) = pixel, y(0) = 0; For degree = 0: z(n+1) = z(n)^2 + p1 + p2*y(n), y(n+1) = z(n) For degree >= 2: z(n+1) = z(n)^degree + p1*z(n)^(degree-1) + p2*y(n), y(n+1) = z(n) For degree <= -3: z(n+1) = z(n)^|degree| + p1*z(n)^(|degree|-2) + p2*y(n), y(n+1) = z(n) Five parameters: real & imaginary parts of p1 & p2, and degree. ~OnlineFF {=HT_PICK pickover} ~Label=HF_PICKOVER Orbit in three dimensions defined by: x(n+1) = sin(a*y(n)) - z(n)*cos(b*x(n)) y(n+1) = z(n)*sin(c*x(n)) - cos(d*y(n)) z(n+1) = sin(x(n)) Parameters: a, b, c, and d. {=HT_PLASMA plasma} ~Label=HF_PLASMA Random, cloud-like formations. Requires 4 or more colors. A recursive algorithm repeatedly subdivides the screen and colors pixels according to an average of surrounding pixels and a random color, less random as the grid size decreases. Four parameters: 'graininess' (0, 0.125 to 100, default = 2), old/new algorithm, seed value used, 16-bit out output selection. ~OnlineFF {=HT_POPCORN popcorn} ~Label=HF_POPCORN The orbits in 2D are plotted superimposed: x(0) = xpixel, y(0) = ypixel; x(n+1) = x(n) - real(h * fn1( y(n) + fn2(C * y(n) )) - imag(h * fn3( x(n) + fn4(C * x(n) )) y(n+1) = y(n) - real(h * fn3( x(n) + fn4(C * x(n) )) - imag(h * fn1( y(n) + fn2(C * y(n) )) Parameters: step size h, C, functions fn1..4 (original: sin,tan,sin,tan). {=HT_POPCORN popcornjul} ~Label=HF_POPCJUL Julia using the generalized Pickover Popcorn formula: x(0) = xpixel, y(0) = ypixel; x(n+1) = x(n) - real(h * fn1( y(n) + fn2(C * y(n) )) - imag(h * fn3( x(n) + fn4(C * x(n) )) y(n+1) = y(n) - real(h * fn3( x(n) + fn4(C * x(n) )) - imag(h * fn1( y(n) + fn2(C * y(n) )) Parameters: step size h, C, functions fn1..4 (original: sin,tan,sin,tan). ~OnlineFF {=HT_MARTIN quadruptwo} ~Label=HF_QUADRUPTWO Quadruptwo attractor from Michael Peters - orbit in two dimensions. z(0) = y(0) = 0; x(n+1) = y(n) - sign(x(n)) * sin(ln(abs(b*x(n)-c))) * arctan(sqr(ln(abs(c*x(n)-b)))) y(n+1) = a - x(n) Parameters are a, b, and c. {=HT_QUAT quatjul} ~Label=HF_QUATJ Quaternion Julia set. q(0) = (xpixel,ypixel,zj,zk) q(n+1) = q(n)*q(n) + c. Four parameters: c, ci, cj, ck c = (c1,ci,cj,ck) {=HT_QUAT quat} ~Label=HF_QUAT Quaternion Mandelbrot set. q(0) = (0,0,0,0) q(n+1) = q(n)*q(n) + c. Two parameters: cj,ck c = (xpixel,ypixel,cj,ck) {=HT_ROSS rossler3D} ~Label=HF_ROSS Orbit in three dimensions defined by: x(0) = y(0) = z(0) = 1; x(n+1) = x(n) - y(n)*dt - z(n)*dt y(n+1) = y(n) + x(n)*dt + a*y(n)*dt z(n+1) = z(n) + b*dt + x(n)*z(n)*dt - c*z(n)*dt Parameters are dt, a, b, and c. {=HT_SIER sierpinski} ~Label=HF_SIER Sierpinski gasket - Julia set producing a 'Swiss cheese triangle' z(n+1) = (2*x,2*y-1) if y > .5; else (2*x-1,2*y) if x > .5; else (2*x,2*y) No parameters. {=HT_SCOTSKIN spider} ~Label=HF_SPIDER c(0) = z(0) = pixel; z(n+1) = z(n)^2 + c(n); c(n+1) = c(n)/2 + z(n+1) Parameters: real & imaginary perturbation of z(0) {=HT_SCOTSKIN sqr(1/fn)} ~Label=HF_SQROVFN z(0) = pixel; z(n+1) = (1/fn(z(n))^2 One parameter: the function fn. {=HT_SCOTSKIN sqr(fn)} ~Label=HF_SQRFN z(0) = pixel; z(n+1) = fn(z(n))^2 One parameter: the function fn. {=HT_TEST test} ~Label=HF_TEST 'test' point letting us (and you!) easily add fractal types via the c module testpt.c. Default set up is a mandelbrot fractal. Four parameters: user hooks (not used by default testpt.c). {=HT_SCOTSKIN tetrate} ~Label=HF_TETRATE z(0) = c = pixel; z(n+1) = c^z(n) Parameters: real & imaginary perturbation of z(0) ~OnlineFF {=HT_MARTIN threeply} ~Label=HF_THREEPLY Threeply attractor by Michael Peters - orbit in two dimensions. z(0) = y(0) = 0; x(n+1) = y(n) - sign(x(n)) * (abs(sin(x(n))*cos(b) +c-x(n)*sin(a+b+c))) y(n+1) = a - x(n) Parameters are a, b, and c. {=HT_MARKS tim's_error} ~Label=HF_TIMSERR A serendipitous coding error in marksmandelpwr brings to life an ancient pterodactyl! (Try setting fn to sqr.) z(0) = pixel, c = z(0) ^ (z(0) - 1): tmp = fn(z(n)) real(tmp) = real(tmp) * real(c) - imag(tmp) * imag(c); imag(tmp) = real(tmp) * imag(c) - imag(tmp) * real(c); z(n+1) = tmp + pixel; Parameters: real & imaginary perturbations of z(0) and function fn ~OnlineFF {=HT_UNITY unity} ~Label=HF_UNITY z(0) = pixel; x = real(z(n)), y = imag(z(n)) One = x^2 + y^2; y = (2 - One) * x; x = (2 - One) * y; z(n+1) = x + i*y No parameters. {=HT_VL volterra-lotka} ~Label=HF_VL Volterra-Lotka fractal from The Beauty of Fractals x(0) = xpixel, y(0) = ypixel; dx/dt = x - xy = f(x,y) dy/dt = -y + xy = g(x,y) x(new) = x + h/2 * [ f(x,y) + f[x + pf(x,y), y + pg(x,y)] ] y(new) = y + h/2 * [ g(x,y) + g[x + pf(x,y), y + pg(x,y)] ] Two parameters: h and p Recommended: zmag or bof60 inside coloring options ~CompressSpaces+ ; ; ; ~Topic=Fractal Types A list of the fractal types and their mathematics can be found in the {Summary of Fractal Types}. Some notes about how Fractint calculates them are in "A Little Code" in {"Fractals and the PC"}. Fractint starts by default with the Mandelbrot set. You can change that by using the command-line argument "TYPE=" followed by one of the fractal type names, or by using the command and selecting the type - if parameters are needed, you will be prompted for them. In the text that follows, due to the limitations of the ASCII character set, "a*b" means "a times b", and "a^b" means "a to the power b". ~Doc- Press for type selection list. ~FF Select a fractal type: ~Table=40 2 0 { The Mandelbrot Set } { Julia Sets } { Inverse Julias } { Newton domains of attraction } { Newton } { Complex Newton } { Lambda Sets } { Mandellambda Sets } { Plasma Clouds } { Lambdafn } { Mandelfn } { Barnsley Mandelbrot/Julia Sets } { Barnsley IFS Fractals } { Sierpinski Gasket } { Quartic Mandelbrot/Julia } ;{ Mandelbrot Mix 4 } { DivideBrot5 } { Distance Estimator } { Pickover Mandelbrot/Julia Types } { Pickover Popcorn } { Dynamic System } { Quaternion } { Peterson Variations } { Unity } { Circle } { Scott Taylor / Lee Skinner Variations } { Kam Torus } { Bifurcation } { Orbit Fractals } { Lorenz Attractors } { Rossler Attractors } { Henon Attractors } { Pickover Attractors } { Martin Attractors } { Gingerbreadman } { Test } { Formula } { Julibrots } { Diffusion Limited Aggregation } { Magnetic Fractals } { L-Systems } { Escher-Like Julia Sets } { Lyapunov Fractals } { fn||fn Fractals } { Halley } { Cellular Automata } { Phoenix } { Frothy Basins } { Icon } { Latoocarfian } { Hypercomplex } ~EndTable ~Doc+ ; ; ~Topic=The Mandelbrot Set, Label=HT_MANDEL (type=mandel) This set is the classic: the only one implemented in many plotting programs, and the source of most of the printed fractal images published in recent years. Like most of the other types in Fractint, it is simply a graph: the x (horizontal) and y (vertical) coordinate axes represent ranges of two independent quantities, with various colors used to symbolize levels of a third quantity which depends on the first two. So far, so good: basic analytic geometry. Now things get a bit hairier. The x axis is ordinary, vanilla real numbers. The y axis is an imaginary number, i.e. a real number times i, where i is the square root of -1. Every point on the plane -- in this case, your PC's display screen -- represents a complex number of the form: x-coordinate + i * y-coordinate If your math training stopped before you got to imaginary and complex numbers, this is not the place to catch up. Suffice it to say that they are just as "real" as the numbers you count fingers with (they're used every day by electrical engineers) and they can undergo the same kinds of algebraic operations. OK, now pick any complex number -- any point on the complex plane -- and call it C, a constant. Pick another, this time one which can vary, and call it Z. Starting with Z=0 (i.e., at the origin, where the real and imaginary axes cross), calculate the value of the expression Z^2 + C Take the result, make it the new value of the variable Z, and calculate again. Take that result, make it Z, and do it again, and so on: in mathematical terms, iterate the function Z(n+1) = Z(n)^2 + C. For certain values of C, the result "levels off" after a while. For all others, it grows without limit. The Mandelbrot set you see at the start -- the solid- colored lake (blue by default), the blue circles sprouting from it, and indeed every point of that color -- is the set of all points C for which the magnitude of Z is less than 2 after 150 iterations (150 is the default setting, changeable via the options screen or "maxiter=" parameter). All the surrounding "contours" of other colors represent points for which the magnitude of Z exceeds 2 after 149 iterations (the contour closest to the M-set itself), 148 iterations, (the next one out), and so on. We actually don't test for the magnitude of Z exceeding 2 - we test the magnitude of Z squared against 4 instead because it is easier. This value (FOUR usually) is known as the "bailout" value for the calculation, because we stop iterating for the point when it is reached. The bailout value can be changed on the options screen but the default is usually best. See also {Bailout Test}. Some features of interest: 1. Use the options screen to increase the maximum number of iterations. Notice that the boundary of the M-set becomes more and more convoluted (the technical terms are "wiggly," "squiggly," and "utterly bizarre") as the Z- magnitudes for points that were still within the set after 150 iterations turn out to exceed 2 after 200, 500, or 1200. In fact, it can be proven that the true boundary is infinitely long: detail without limit. 2. Although there appear to be isolated "islands" of blue, zoom in -- that is, plot for a smaller range of coordinates to show more detail -- and you'll see that there are fine "causeways" of blue connecting them to the main set. As you zoomed, smaller islands became visible; the same is true for them. In fact, there are no isolated points in the M-set: it is "connected" in a strict mathematical sense. 3. The upper and lower halves of the first image are symmetric (a fact that Fractint makes use of here and in some other fractal types to speed plotting). But notice that the same general features -- lobed discs, spirals, starbursts -- tend to repeat themselves (although never exactly) at smaller and smaller scales, so that it can be impossible to judge by eye the scale of a given image. 4. In a sense, the contour colors are window-dressing: mathematically, it is the properties of the M-set itself that are interesting, and no information about it would be lost if all points outside the set were assigned the same color. If you're a serious, no-nonsense type, you may want to cycle the colors just once to see the kind of silliness that other people enjoy, and then never do it again. Go ahead. Just once, now. We trust you. ; ; ~Topic=Julia Sets, Label=HT_JULIA (type=julia) These sets were named for mathematician Gaston Julia, and can be generated by a simple change in the iteration process described for the {=HT_MANDEL Mandelbrot Set}. Start with a specified value of C, "C-real + i * C-imaginary"; use as the initial value of Z "x-coordinate + i * y-coordinate"; and repeat the same iteration, Z(n+1) = Z(n)^2 + C. There is a Julia set corresponding to every point on the complex plane -- an infinite number of Julia sets. But the most visually interesting tend to be found for the same C values where the M-set image is busiest, i.e. points just outside the boundary. Go too far inside, and the corresponding Julia set is a circle; go too far outside, and it breaks up into scattered points. In fact, all Julia sets for C within the M-set share the "connected" property of the M-set, and all those for C outside lack it. Fractint's spacebar toggle lets you "flip" between any view of the M-set and the Julia set for the point C at the center of that screen. You can then toggle back, or zoom your way into the Julia set for a while and then return to the M-set. So if the infinite complexity of the M-set palls, remember: each of its infinite points opens up a whole new Julia set. Historically, the Julia sets came first: it was while looking at the M-set as an "index" of all the Julia sets' origins that Mandelbrot noticed its properties. The relationship between the {=HT_MANDEL Mandelbrot} set and Julia set can hold between other sets as well. Many of Fractint's types are "Mandelbrot/Julia" pairs (sometimes called "M-sets" or "J-sets". All these are generated by equations that are of the form z(k+1) = f(z(k),c), where the function orbit is the sequence z(0), z(1), ..., and the variable c is a complex parameter of the equation. The value c is fixed for "Julia" sets and is equal to the first two parameters entered with the "params=Creal/Cimag" command. The initial orbit value z(0) is the complex number corresponding to the screen pixel. For Mandelbrot sets, the parameter c is the complex number corresponding to the screen pixel. The value z(0) is c plus a perturbation equal to the values of the first two parameters. See the discussion of {=HT_MLAMBDA Mandellambda Sets}. This approach may or may not be the "standard" way to create "Mandelbrot" sets out of "Julia" sets. Some equations have additional parameters. These values are entered as the third or fourth params= value for both Julia and Mandelbrot sets. The variables x and y refer to the real and imaginary parts of z; similarly, cx and cy are the real and imaginary parts of the parameter c and fx(z) and fy(z) are the real and imaginary parts of f(z). The variable c is sometimes called lambda for historical reasons. NOTE: if you use the "PARAMS=" argument to warp the M-set by starting with an initial value of Z other than 0, the M-set/J-sets correspondence breaks down and the spacebar toggle no longer works. ; ; ~Topic=Julia Toggle Spacebar Commands, Label=HELP_JIIM The spacebar toggle has been enhanced for the classic Mandelbrot and Julia types. When viewing the Mandelbrot, the spacebar turns on a window mode that displays the Inverse Julia corresponding to the cursor position in a window. Pressing the spacebar then causes the regular Julia escape time fractal corresponding to the cursor position to be generated. The following keys take effect in Inverse Julia mode. Generate the escape-time Julia Set corresponding to the cursor\ position. Only works if fractal is a "Mandelbrot" type.\ Numbers toggle - shows coordinates of the cursor on the\ screen. Press again to turn off numbers.\

Enter new pixel coordinates directly\ Hide fractal toggle. Works only if View Windows is turned on\ and set for a small window (such as the default size.) Hides \ the fractal, allowing the orbit to take up the whole screen. \ Press again to uncover the fractal.\ Saves the fractal, cursor, orbits, and numbers.\ <<> or <,> Zoom inverse julia image smaller.\ <>> or <.> Zoom inverse julia image larger.\ Restore default zoom.\ The Julia Inverse window is only implemented for the classic Mandelbrot (type=mandel). For other "Mandelbrot" types turns on the cursor without the Julia window, and allows you to select coordinates of the matching Julia set in a way similar to the use of the zoom box with the Mandelbrot/Julia toggle in previous Fractint versions. ; ; ~Topic=Inverse Julias, Label=HT_INVERSE (type=julia_inverse) Pick a function, such as the familiar Z(n) = Z(n-1) squared plus C (the defining function of the Mandelbrot Set). If you pick a point Z(0) at random from the complex plane, and repeatedly apply the function to it, you get a sequence of new points called an orbit, which usually either zips out toward infinity or zooms in toward one or more "attractor" points near the middle of the plane. The set of all points that are "attracted" to infinity is called the "Basin of Attraction" of infinity. Each of the other attractors also has its own Basin of Attraction. Why is it called a Basin? Imagine a lake, and all the water in it "draining" into the attractor. The boundary between these basins is called the Julia Set of the function. The boundary between the basins of attraction is sort of like a repeller; all orbits move away from it, toward one of the attractors. But if we define a new function as the inverse of the old one, as for instance Z(n) = sqrt(Z(n-1) minus C), then the old attractors become repellers, and the former boundary itself becomes the attractor! Now, starting from any point, all orbits are drawn irresistibly to the Julia Set! In fact, once an orbit reaches the boundary, it will continue to hop about until it traces the entire Julia Set! This method for drawing Julia Sets is called the Inverse Iteration Method, or IIM for short. Unfortunately, some parts of each Julia Set boundary are far more attractive to inverse orbits than others are, so that as an orbit traces out the set, it keeps coming back to these attractive parts again and again, only occasionally visiting the less attractive parts. Thus it may take an infinite length of time to draw the entire set. To hasten the process, we can keep track of how many times each pixel on our computer screen is visited by an orbit, and whenever an orbit reaches a pixel that has already been visited more than a certain number of times, we can consider that orbit finished and move on to another one. This "hit limit" thus becomes similar to the iteration limit used in the traditional escape-time fractal algorithm. This is called the Modified Inverse Iteration Method, or MIIM, and is much faster than the IIM. Now, the inverse of Mandelbrot's classic function is a square root, and the square root actually has two solutions; one positive, one negative. Therefore at each step of each orbit of the inverse function there is a decision; whether to use the positive or the negative square root. Each one gives rise to a new point on the Julia Set, so each is a good choice. This series of choices defines a binary decision tree, each point on the Julia Set giving rise to two potential child points. There are many interesting ways to traverse a binary tree, among them Breadth first, Depth first (left or negative first), Depth first (right or positive first), and completely at random. It turns out that most traversal methods lead to the same or similar pictures, but that how the image evolves as the orbits trace it out differs wildly depending on the traversal method chosen. As far as we know, this fact is an original discovery by Michael Snyder, and version 18.2 of FRACTINT was its first publication. Pick a Julia constant such as Z(0) = (-.74543, .11301), the popular Seahorse Julia, and try drawing it first Breadth first, then Depth first (right first), Depth first (left first), and finally with Random Walk. Caveats: the video memory is used in the algorithm, to keep track of how many times each pixel has been visited (by changing it's color). Therefore the algorithm will not work well if you zoom in far enough that part of the Julia Set is off the screen. Bugs: Not working with Disk Video. Not resumeable. The key toggles between the Inverse Julia orbit and the corresponding Julia escape time fractal. ; ; ~Topic=Newton domains of attraction, Label=HT_NEWTBAS (type=newtbasin) The Newton formula is an algorithm used to find the roots of polynomial equations by successive "guesses" that converge on the correct value as you feed the results of each approximation back into the formula. It works very well -- unless you are unlucky enough to pick a value that is on a line BETWEEN two actual roots. In that case, the sequence explodes into chaos, with results that diverge more and more wildly as you continue the iteration. This fractal type shows the results for the polynomial Z^n - 1, which has n roots in the complex plane. Use the ype command and enter "newtbasin" in response to the prompt. You will be asked for a parameter, the "order" of the equation (an integer from 3 through 10 -- 3 for x^3-1, 7 for x^7-1, etc.). A second parameter is a flag to turn on alternating shades showing changes in the number of iterations needed to attract an orbit. Some people like stripes and some don't, as always, Fractint gives you a choice! The coloring of the plot shows the "basins of attraction" for each root of the polynomial -- i.e., an initial guess within any area of a given color would lead you to one of the roots. As you can see, things get a bit weird along certain radial lines or "spokes," those being the lines between actual roots. By "weird," we mean infinitely complex in the good old fractal sense. Zoom in and see for yourself. This fractal type is symmetric about the origin, with the number of "spokes" depending on the order you select. It uses floating-point math if you have an FPU, or a somewhat slower integer algorithm if you don't have one. ~Doc- See also: {Newton} ~Doc+ ; ; ~Topic=Newton, Label=HT_NEWT (type=newton) The generating formula here is identical to that for {=HT_NEWTBAS newtbasin}, but the coloring scheme is different. Pixels are colored not according to the root that would be "converged on" if you started using Newton's formula from that point, but according to the iteration when the value is close to a root. For example, if the calculations for a particular pixel converge to the 7th root on the 23rd iteration, NEWTBASIN will color that pixel using color #7, but NEWTON will color it using color #23. If you have a 256-color mode, use it: the effects can be much livelier than those you get with type=newtbasin, and color cycling becomes, like, downright cosmic. If your "corners" choice is symmetrical, Fractint exploits the symmetry for faster display. The applicable "params=" values are the same as newtbasin. Try "params=4." Other values are 3 through 10. 8 has twice the symmetry and is faster. As with newtbasin, an FPU helps. ; ; ~Topic=Complex Newton, Label=HT_NEWTCMPLX (type=complexnewton/complexbasin) Well, hey, "Z^n - 1" is so boring when you can use "Z^a - b" where "a" and "b" are complex numbers! The new "complexnewton" and "complexbasin" fractal types are just the old {=HT_NEWT "newton"} and {=HT_NEWTBAS "newtbasin"} fractal types with this little added twist. When you select these fractal types, you are prompted for four values (the real and imaginary portions of "a" and "b"). If "a" has a complex portion, the fractal has a discontinuity along the negative axis - relax, we finally figured out that it's *supposed* to be there! ; ; ~Topic=Lambda Sets, Label=HT_LAMBDA (type=lambda) This type calculates the Julia set of the formula lambda*Z*(1-Z). That is, the value Z[0] is initialized with the value corresponding to each pixel position, and the formula iterated. The pixel is colored according to the iteration when the sum of the squares of the real and imaginary parts exceeds 4. Two parameters, the real and imaginary parts of lambda, are required. Try 0 and 1 to see the classical fractal "dragon". Then try 0.2 and 1 for a lot more detail to zoom in on. It turns out that all quadratic Julia-type sets can be calculated using just the formula z^2+c (the "classic" Julia"), so that this type is redundant, but we include it for reason of it's prominence in the history of fractals. ; ; ~Topic=Mandellambda Sets, Label=HT_MLAMBDA (type=mandellambda) This type is the "Mandelbrot equivalent" of the {=HT_LAMBDA lambda} set. A comment is in order here. Almost all the Fractint "Mandelbrot" sets are created from orbits generated using formulas like z(n+1) = f(z(n),C), with z(0) and C initialized to the complex value corresponding to the current pixel. Our reasoning was that "Mandelbrots" are maps of the corresponding "Julias". Using this scheme each pixel of a "Mandelbrot" is colored the same as the Julia set corresponding to that pixel. However, Kevin Allen informs us that the MANDELLAMBDA set appears in the literature with z(0) initialized to a critical point (a point where the derivative of the formula is zero), which in this case happens to be the point (.5,0). Since Kevin knows more about Dr. Mandelbrot than we do, and Dr. Mandelbrot knows more about fractals than we do, we defer! Starting with version 14 Fractint calculates MANDELAMBDA Dr. Mandelbrot's way instead of our way. But ALL THE OTHER "Mandelbrot" sets in Fractint are still calculated OUR way! (Fortunately for us, for the classic Mandelbrot Set these two methods are the same!) Well now, folks, apart from questions of faithfulness to fractals named in the literature (which we DO take seriously!), if a formula makes a beautiful fractal, it is not wrong. In fact some of the best fractals in Fractint are the results of mistakes! Nevertheless, thanks to Kevin for keeping us accurate! (See description of "initorbit=" command in {Image Calculation Parameters} for a way to experiment with different orbit intializations). ; ; ~Topic=Circle, Label=HT_CIRCLE (type=circle) This fractal types is from A. K. Dewdney's "Computer Recreations" column in "Scientific American". It is attributed to John Connett of the University of Minnesota. (Don't tell anyone, but this fractal type is not really a fractal!) Fascinating Moire patterns can be formed by calculating x^2 + y^2 for each pixel in a piece of the complex plane. After multiplication by a magnification factor (the parameter), the number is truncated to an integer and mapped to a color via color = value modulo (number of colors). That is, the integer is divided by the number of colors, and the remainder is the color index value used. The resulting image is not a fractal because all detail is lost after zooming in too far. Try it with different resolution video modes - the results may surprise you! If inside=startrail is used, it will automatically be set to inside=norm by Fractint. This is because type circle and inside=startrail locks up Fractint. ; ; ~Topic=Plasma Clouds, Label=HT_PLASMA (type=plasma) Plasma clouds ARE real live fractals, even though we didn't know it at first. They are generated by a recursive algorithm that randomly picks colors of the corner of a rectangle, and then continues recursively quartering previous rectangles. Random colors are averaged with those of the outer rectangles so that small neighborhoods do not show much change, for a smoothed-out, cloud-like effect. The more colors your video mode supports, the better. The result, believe it or not, is a fractal landscape viewed as a contour map, with colors indicating constant elevation. To see this, save and view with the <3> command (see {\"3D\" Images}) and your "cloud" will be converted to a mountain! You've GOT to try {=@ColorCycling color cycling} on these (hit "+" or "-"). If you haven't been hypnotized by the drawing process, the writhing colors will do it for sure. We have now implemented subliminal messages to exploit the user's vulnerable state; their content varies with your bank balance, politics, gender, accessibility to a Fractint programmer, and so on. A free copy of Microsoft C to the first person who spots them. This type accepts four parameters. The first determines how abruptly the colors change. A value of .5 yields bland clouds, while 50 yields very grainy ones. The default value is 2. The second determines whether to use the original algorithm (0) or a modified one (1). The new one gives the same type of images but draws the dots in a different order. It will let you see what the final image will look like much sooner than the old one. The third determines whether to use a new seed for generating the next plasma cloud (0) or to use the previous seed (1). The fourth parameter turns on 16-bit .POT output which provides much smoother height gradations. This is especially useful for creating mountain landscapes when using the plasma output with a ray tracer such as POV-Ray. With parameter three set to 1, the next plasma cloud generated will be identical to the previous but at whatever new resolution is desired. Zooming is ignored, as each plasma-cloud screen is generated randomly. The random number seed used for each plasma image is displayed on the information screen, and can be entered with the command line parameter "rseed=" to recreate a particular image. The algorithm is based on the Pascal program distributed by Bret Mulvey as PLASMA.ARC. We have ported it to C and integrated it with Fractint's graphics and animation facilities. This implementation does not use floating-point math. The algorithm was modified starting with version 18 so that the plasma effect is independent of screen resolution. Saved plasma-cloud screens are EXCELLENT starting images for fractal "landscapes" created with the {\"3D\" commands}. ; ; ~Topic=Lambdafn, Label=HT_LAMBDAFN (type=lambdafn) Function=[sin|cos|sinh|cosh|exp|log|sqr|...]) is specified with this type. Prior to version 14, these types were lambdasine, lambdacos, lambdasinh, lambdacos, and lambdaexp. Where we say "lambdasine" or some such below, the good reader knows we mean "lambdafn with function=sin".) These types calculate the Julia set of the formula lambda*fn(Z), for various values of the function "fn", where lambda and Z are both complex. Two values, the real and imaginary parts of lambda, should be given in the "params=" option. For the feathery, nested spirals of LambdaSines and the frost-on-glass patterns of LambdaCosines, make the real part = 1, and try values for the imaginary part ranging from 0.1 to 0.4 (hint: values near 0.4 have the best patterns). In these ranges the Julia set "explodes". For the tongues and blobs of LambdaExponents, try a real part of 0.379 and an imaginary part of 0.479. A coprocessor used to be almost mandatory: each LambdaSine/Cosine iteration calculates a hyperbolic sine, hyperbolic cosine, a sine, and a cosine (the LambdaExponent iteration "only" requires an exponent, sine, and cosine operation)! However, Fractint now computes these transcendental functions with fast integer math. In a few cases the fast math is less accurate, so we have kept the old slow floating point code. To use the old code, invoke with the float=yes option, and, if you DON'T have a coprocessor, go on a LONG vacation! ; ; ~Topic=Halley, Label=HT_HALLEY (type=halley) The Halley map is an algorithm used to find the roots of polynomial equations by successive "guesses" that converge on the correct value as you feed the results of each approximation back into the formula. It works very well -- unless you are unlucky enough to pick a value that is on a line BETWEEN two actual roots. In that case, the sequence explodes into chaos, with results that diverge more and more wildly as you continue the iteration. This fractal type shows the results for the polynomial Z(Z^a - 1), which has a+1 roots in the complex plane. Use the ype command and enter "halley" in response to the prompt. You will be asked for a parameter, the "order" of the equation (an integer from 2 through 10 -- 2 for Z(Z^2 - 1), 7 for Z(Z^7 - 1), etc.). A second parameter is the relaxation coefficient, and is used to control the convergence stability. A number greater than one increases the chaotic behavior and a number less than one decreases the chaotic behavior. The third parameter is the value used to determine when the formula has converged. The test for convergence is ||Z(n+1)|^2 - |Z(n)|^2| < epsilon. This convergence test produces the whisker-like projections which generally point to a root. ; ; ~Topic=Phoenix, Label=HT_PHOENIX (type=phoenix, mandphoenix, phoenixcplx, mandphoenixclx) The phoenix type defaults to the original phoenix curve discovered by Shigehiro Ushiki, "Phoenix", IEEE Transactions on Circuits and Systems, Vol. 35, No. 7, July 1988, pp. 788-789. These images do not have the X and Y axis swapped as is normal for this type. The mandphoenix type is the corresponding Mandelbrot set image of the phoenix type. The spacebar toggles between the two as long as the mandphoenix type has an initial z(0) of (0,0). The mandphoenix is not an effective index to the phoenix type, so explore the wild blue yonder. To reproduce the Mandelbrot set image of the phoenix type as shown in Stevens' book, "Fractal Programming in C", set initorbit=0/0 on the command line or with the key. The colors need to be rotated one position because Stevens uses the values from the previous calculation instead of the current calculation to determine when to bailout. The phoenixcplx type is implemented using complex constants instead of the real constants that Stevens used. This recreates the mapping as originally presented by Ushiki. The mandphoenixclx type is the corresponding Mandelbrot set image of the phoenixcplx type. The spacebar toggles between the two as long as the mandphoenixclx type has a perturbation of z(0) = (0,0). The mandphoenixclx is an effective index to the phoenixcplx type. ; ; ~Topic=fn||fn Fractals, Label=HT_FNORFN (type=lambda(fn||fn), manlam(fn||fn), julia(fn||fn), mandel(fn||fn)) Two functions=[sin|cos|sinh|cosh|exp|log|sqr|...]) are specified with these types. The two functions are alternately used in the calculation based on a comparison between the modulus of the current Z and the shift value. The first function is used if the modulus of Z is less than the shift value and the second function is used otherwise. The lambda(fn||fn) type calculates the Julia set of the formula lambda*fn(Z), for various values of the function "fn", where lambda and Z are both complex. Two values, the real and imaginary parts of lambda, should be given in the "params=" option. The third value is the shift value. The space bar will generate the corresponding "pseudo Mandelbrot" set, manlam(fn||fn). The manlam(fn||fn) type calculates the "pseudo Mandelbrot" set of the formula fn(Z)*C, for various values of the function "fn", where C and Z are both complex. Two values, the real and imaginary parts of Z(0), should be given in the "params=" option. The third value is the shift value. The space bar will generate the corresponding julia set, lamda(fn||fn). The julia(fn||fn) type calculates the Julia set of the formula fn(Z)+C, for various values of the function "fn", where C and Z are both complex. Two values, the real and imaginary parts of C, should be given in the "params=" option. The third value is the shift value. The space bar will generate the corresponding mandelbrot set, mandel(fn||fn). The mandel(fn||fn) type calculates the Mandelbrot set of the formula fn(Z)+C, for various values of the function "fn", where C and Z are both complex. Two values, the real and imaginary parts of Z(0), should be given in the "params=" option. The third value is the shift value. The space bar will generate the corresponding julia set, julia(fn||fn). ; ; ~Topic=Mandelfn, Label=HT_MANDFN (type=mandelfn) Function=[sin|cos|sinh|cosh|exp|log|sqr|...]) is specified with this type. Prior to version 14, these types were mandelsine, mandelcos, mandelsinh, mandelcos, and mandelexp. Same comment about our lapses into the old terminology as above! These are "pseudo-Mandelbrot" mappings for the {=HT_LAMBDAFN LambdaFn} Julia functions. They map to their corresponding Julia sets via the spacebar command in exactly the same fashion as the original M/J sets. In general, they are interesting mainly because of that property (the function=exp set in particular is rather boring). Generate the appropriate "Mandelfn" set, zoom on a likely spot where the colors are changing rapidly, and hit the spacebar key to plot the Julia set for that particular point. Try "FRACTINT TYPE=MANDELFN CORNERS=4.68/4.76/-.03/.03 FUNCTION=COS" for a graphic demonstration that we're not taking Mandelbrot's name in vain here. We didn't even know these little buggers were here until Mark Peterson found this a few hours before the version incorporating Mandelfns was released. Note: If you created images using the lambda or mandel "fn" types prior to version 14, and you wish to update the fractal information in the "*.fra" file, simply read the files and save again. You can do this in batch mode via a command line such as: "fractint oldfile.fra savename=newfile.gif batch=yes" For example, this procedure can convert a version 13 "type=lambdasine" image to a version 14 "type=lambdafn function=sin" GIF89a image. We do not promise to keep this "backward compatibility" past version 14 - if you want to keep the fractal information in your *.fra files accurate, we recommend conversion. See {GIF Save File Format}. ; ; ~Topic=Barnsley Mandelbrot/Julia Sets, Label=HT_BARNS (type=barnsleym1/.../j3) Michael Barnsley has written a fascinating college-level text, "Fractals Everywhere," on fractal geometry and its graphic applications. (See {Bibliography}.) In it, he applies the principle of the M and J sets to more general functions of two complex variables. We have incorporated three of Barnsley's examples in Fractint. Their appearance suggests polarized-light microphotographs of minerals, with patterns that are less organic and more crystalline than those of the M/J sets. Each example has both a "Mandelbrot" and a "Julia" type. Toggle between them using the spacebar. The parameters have the same meaning as they do for the "regular" Mandelbrot and Julia. For types M1, M2, and M3, they are used to "warp" the image by setting the initial value of Z. For the types J1 through J3, they are the values of C in the generating formulas. Be sure to try the rbit function while plotting these types. ; ; ~Topic=Barnsley IFS Fractals, Label=HT_IFS (type=ifs) One of the most remarkable spin-offs of fractal geometry is the ability to "encode" realistic images in very small sets of numbers -- parameters for a set of functions that map a region of two-dimensional space onto itself. In principle (and increasingly in practice), a scene of any level of complexity and detail can be stored as a handful of numbers, achieving amazing "compression" ratios... how about a super-VGA image of a forest, more than 300,000 pixels at eight bits apiece, from a 1-KB "seed" file? Again, Michael Barnsley and his co-workers at the Georgia Institute of Technology are to be thanked for pushing the development of these iterated function systems (IFS). When you select this fractal type, Fractint scans the current IFS file (default is FRACTINT.IFS, a set of definitions supplied with Fractint) for IFS definitions, then prompts you for the IFS name you wish to run. Fern and 3dfern are good ones to start with. You can press at the selection screen if you want to select a different .IFS file you've written. Note that some Barnsley IFS values generate images quite a bit smaller than the initial (default) screen. Just bring up the zoom box, center it on the small image, and hit to get a full-screen image. To change the number of dots Fractint generates for an IFS image before stopping, you can change the "maximum iterations" parameter on the options screen. Fractint supports two types of IFS images: 2D and 3D. In order to fully appreciate 3D IFS images, since your monitor is presumably 2D, we have added rotation, translation, and perspective capabilities. These share values with the same variables used in Fractint's other 3D facilities; for their meaning see {"Rectangular Coordinate Transformation"}. You can enter these values from the command line using: rotation=xrot/yrot/zrot (try 30/30/30)\ shift=xshift/yshift (shifts BEFORE applying perspective!)\ perspective=viewerposition (try 200)\ Alternatively, entering from main screen will allow you to modify these values. The defaults are the same as for regular 3D, and are not always optimum for 3D IFS. With the 3dfern IFS type, try rotation=30/30/30. Note that applying shift when using perspective changes the picture -- your "point of view" is moved. A truly wild variation of 3D may be seen by entering "2" for the stereo mode (see {"Stereo 3D Viewing"}), putting on red/blue "funny glasses", and watching the fern develop with full depth perception right there before your eyes! This feature USED to be dedicated to Bruce Goren, as a bribe to get him to send us MORE knockout stereo slides of 3D ferns, now that we have made it so easy! Bruce, what have you done for us *LATELY* ?? (Just kidding, really!) Each line in an IFS definition (look at FRACTINT.IFS with your editor for examples) contains the parameters for one of the generating functions, e.g. in FERN: ~Format- a b c d e f p ___________________________________ 0 0 0 .16 0 0 .01 .85 .04 -.04 .85 0 1.6 .85 .2 -.26 .23 .22 0 1.6 .07 -.15 .28 .26 .24 0 .44 .07 The values on each line define a matrix, vector, and probability: matrix vector prob |a b| |e| p |c d| |f| ~Format+ The "p" values are the probabilities assigned to each function (how often it is used), which add up to one. Fractint supports up to 32 functions, although usually three or four are enough. 3D IFS definitions are a bit different. The name is followed by (3D) in the definition file, and each line of the definition contains 13 numbers: a b c d e f g h i j k l p, defining: matrix vector prob\ |a b c| |j| p\ |d e f| |k|\ |g h i| |l|\ ;You can experiment with changes to IFS definitions interactively by using ;Fractint's command. After selecting an IFS definition, hit to ;bring up the IFS editor. This editor displays the current IFS values, lets ;you modify them, and lets you save your modified values as a text file ;which you can then merge into an XXX.IFS file for future use with ;Fractint. ; The program FDESIGN can be used to design IFS fractals - see {=@FDESIGN FDESIGN}. You can save the points in your IFS fractal in the file ORBITS.RAW which is overwritten each time a fractal is generated. The program Acrospin can read this file and will let you view the fractal from any angle using the cursor keys. See {=@ACROSPIN Acrospin}. ; ; ~Topic=Sierpinski Gasket, Label=HT_SIER (type=sierpinski) Another pre-Mandelbrot classic, this one found by W. Sierpinski around World War I. It is generated by dividing a triangle into four congruent smaller triangles, doing the same to each of them, and so on, yea, even unto infinity. (Notice how hard we try to avoid reiterating "iterating"?) If you think of the interior triangles as "holes", they occupy more and more of the total area, while the "solid" portion becomes as hopelessly fragile as that gasket you HAD to remove without damaging it -- you remember, that Sunday afternoon when all the parts stores were closed? There's a three-dimensional equivalent using nested tetrahedrons instead of triangles, but it generates too much pyramid power to be safely unleashed yet. There are no parameters for this type. We were able to implement it with integer math routines, so it runs fairly quickly even without an FPU. ; ; ~Topic=Quartic Mandelbrot/Julia, Label=HT_MANDJUL4 (type=mandel4/julia4) These fractal types are the moral equivalent of the original M and J sets, except that they use the formula Z(n+1) = Z(n)^4 + C, which adds additional pseudo-symmetries to the plots. The "Mandel4" set maps to the "Julia4" set via -- surprise! -- the spacebar toggle. The M4 set is kind of boring at first (the area between the "inside" and the "outside" of the set is pretty thin, and it tends to take a few zooms to get to any interesting sections), but it looks nice once you get there. The Julia sets look nice right from the start. Other powers, like Z(n)^3 or Z(n)^7, work in exactly the same fashion. We used this one only because we're lazy, and Z(n)^4 = (Z(n)^2)^2. ; ; ;~Topic=Mandelbrot Mix 4, Label=HT_MANDELBROTMIX4 ;(type=mandelbrotmix4) ; ;Jim Muth has been publishing a "Fractal of the Day" on the fractint mailing ;list for many years now. As often as not Jim picks the formula ;Mandelbrotmix4 as the fractal continent to explore. To honor Jim, the ;fractint authors have provided this fractal as a built-in type. ; ;The formula is: ; ;MandelbrotMix4 \{\; Jim Muth ;a=real(p1), b=imag(p1), d=real(p2), f=imag(p2), ;g=1/f, h=1/d, j=1/(f-b), z=(-a*b*g*h)^j, ;k=real(p3)+1, l=imag(p3)+100, c=fn1(pixel): ;z=k*((a*(z^b))+(d*(z^f)))+c, ;|z| < l \} ; ;Note that Jim uses l=imag(p3)+100, which is to say, the sixth scalar parameter, ;as the bailout. Our implementation follows Jim if the user requests ;the default bailout. ; ; ~Topic=DivideBrot5, Label=HT_DIVIDEBROT5 (type=dividebrot5) This is Jim Muth's fifth version of the DivideBrot formula. The formula is: DivideBrot5 \{\; Jim Muth\ z = 0, c = pixel, a = real(p1) - 2,\ b = imag(p1) + 10^(-20):\ z = sqr(z) / (z^(-a) + b) + c\ |z| < 16\} ; ; ~Topic=Distance Estimator (distest=nnn/nnn) This used to be type=demm and type=demj. These types have not died, but are only hiding! They are equivalent to the mandel and julia types with the "distest=" option selected with a predetermined value. The {Distance Estimator Method} can be used to produce higher quality images of M and J sets, especially suitable for printing in black and white. If you have some *.fra files made with the old types demm/demj, you may want to convert them to the new form. See the {=HT_MANDFN Mandelfn} section for directions to carry out the conversion. ; ; ~Topic=Pickover Mandelbrot/Julia Types, Label=HT_PICKMJ (type=manfn+zsqrd/julfn+zsqrd, manzpowr/julzpowr, manzzpwr/julzzpwr, manfn+exp/julfn+exp - formerly included man/julsinzsqrd and man/julsinexp which have now been generalized) These types have been explored by Clifford A. Pickover, of the IBM Thomas J. Watson Research center. As implemented in Fractint, they are regular Mandelbrot/Julia set pairs that may be plotted with or without the {=@Biomorphs "biomorph"} option Pickover used to create organic-looking beasties (see below). These types are produced with formulas built from the functions z^z, z^n, sin(z), and e^z for complex z. Types with "power" or "pwr" in their name have an exponent value as a third parameter. For example, type=manzpower params=0/0/2 is our old friend the classical Mandelbrot, and type=manzpower params=0/0/4 is the Quartic Mandelbrot. Other values of the exponent give still other fractals. Since these WERE the original "biomorph" types, we should give an example. Try: FRACTINT type=manfn+zsqrd biomorph=0 corners=-8/8/-6/6 function=sin to see a big biomorph digesting little biomorphs! ; ; ~Topic=Pickover Popcorn, Label=HT_POPCORN (type=popcorn/popcornjul) Here is another Pickover idea. This one computes and plots the orbits of the dynamic system defined by: x(n+1) = x(n) - real(h * fn1( y(n) + fn2(C * y(n) )) - imag(h * fn3( x(n) + fn4(C * x(n) )) y(n+1) = y(n) - real(h * fn3( x(n) + fn4(C * x(n) )) - imag(h * fn1( y(n) + fn2(C * y(n) )) In the original the functions were: sin, tan, sin, tan, and C was 3. The initializers x(0) and y(0) equal to ALL the complex values within the "corners" values, and h=.01. ALL these orbits are superimposed, resulting in "popcorn" effect. You may want to use a maxiter value less than normal - Pickover recommends a value of 50. Although you can zoom and rotate popcorn, the results may not be what you'd expect, due to the superimposing of orbits and arbitrary use of color. The orbits frequently occur outside of the screen boundaries. To view the fractal in its entirety, set the preview display to "yes" using the "V" command. As a bonus, type=popcornjul shows the Julia set generated by these same equations with the usual escape-time coloring. Turn on orbit viewing with the "O" command, and as you watch the orbit pattern you may get some insight as to where the popcorn comes from. ; ; ~Topic=Dynamic System, Label=HT_DYNAM (type=dynamic, dynamic2) These fractals are based on a cyclic system of differential equations: x'(t) = -f(y(t))\ y'(t) = f(x(t))\ These equations are approximated by using a small time step dt, forming a time-discrete dynamic system: x(n+1) = x(n) - dt*f(y(n))\ y(n+1) = y(n) + dt*f(x(n))\ The initial values x(0) and y(0) are set to various points in the plane, the dynamic system is iterated, and the resulting orbit points are plotted. In fractint, the function f is restricted to: f(k) = sin(k + a*fn1(b*k)) The parameters are the spacing of the initial points, the time step dt, and the parameters (a,b,fn1) that affect the function f. Normally the orbit points are plotted individually, but for a negative spacing the points are connected. This fractal is similar to the {=HT_POPCORN Pickover Popcorn}. ~OnlineFF A variant is the implicit Euler approximation: y(n+1) = y(n) + dt*f(x(n))\ x(n+1) = x(n) - dt*f(y(n+1))\ This variant results in complex orbits. The implicit Euler approximation is selected by entering dt<0. There are two options that have unusual effects on these fractals. The Orbit Delay value controls how many initial points are computed before the orbits are displayed on the screen. This allows the orbit to settle down. The outside=summ option causes each pixel to increment color every time an orbit touches it; the resulting display is a 2-d histogram. These fractals are discussed in Chapter 14 of Pickover's "Computers, Pattern, Chaos, and Beauty". ; ; ~Topic=Mandelcloud, Label=HT_MANDELCLOUD (type=mandelcloud) This fractal computes the Mandelbrot function, but displays it differently. It starts with regularly spaced initial pixels and displays the resulting orbits. This idea is somewhat similar to the {=HT_DYNAM Dynamic System}. There are two options that have unusual effects on this fractal. The Orbit Delay value controls how many initial points are computed before the orbits are displayed on the screen. This allows the orbit to settle down. The outside=summ option causes each pixel to increment color every time an orbit touches it; the resulting display is a 2-d histogram. This fractal was invented by Noel Giffin. ; ; ~Topic=Peterson Variations, Label=HT_MARKS (type=marksmandel, marksjulia, cmplxmarksmand, cmplxmarksjul, marksmandelpwr, tim's_error) These fractal types are contributions of Mark Peterson. MarksMandel and MarksJulia are two families of fractal types that are linked in the same manner as the classic Mandelbrot/Julia sets: each MarksMandel set can be considered as a mapping into the MarksJulia sets, and is linked with the spacebar toggle. The basic equation for these sets is: Z(n+1) = (lambda^(exp-1) * Z(n)^2) + lambda\ where Z(0) = 0.0 and lambda is (x + iy) for MarksMandel. For MarksJulia, Z(0) = (x + iy) and lambda is a constant (taken from the MarksMandel spacebar toggle, if that method is used). The exponent is a positive integer or a complex number. We call these "families" because each value of the exponent yields a different MarksMandel set, which turns out to be a kinda-polygon with (exponent) sides. The exponent value is the third parameter, after the "initialization warping" values. Typically one would use null warping values, and specify the exponent with something like "PARAMS=0/0/5", which creates an unwarped, pentagonal MarksMandel set. In the process of coding MarksMandelPwr formula type, Tim Wegner created the type "tim's_error" after making an interesting coding mistake. ; ; ~Topic=Unity, Label=HT_UNITY (type=unity) This Peterson variation began with curiosity about other "Newton-style" approximation processes. A simple one, One = (x * x) + (y * y); y = (2 - One) * x; x = (2 - One) * y; produces the fractal called Unity. One of its interesting features is the "ghost lines." The iteration loop bails out when it reaches the number 1 to within the resolution of a screen pixel. When you zoom a section of the image, the bailout criterion is adjusted, causing some lines to become thinner and others thicker. Only one line in Unity that forms a perfect circle: the one at a radius of 1 from the origin. This line is actually infinitely thin. Zooming on it reveals only a thinner line, up (down?) to the limit of accuracy for the algorithm. The same thing happens with other lines in the fractal, such as those around |x| = |y| = (1/2)^(1/2) = .7071 Try some other tortuous approximations using the {=HT_TEST TEST stub} and let us know what you come up with! ; ; ~Topic=Scott Taylor / Lee Skinner Variations, Label=HT_SCOTSKIN (type=fn(z*z), fn*fn, fn*z+z, fn+fn, fn+fn(pix), sqr(1/fn), sqr(fn), spider, tetrate, manowar) Two of Fractint's faithful users went bonkers when we introduced the "formula" type, and came up with all kinds of variations on escape-time fractals using trig functions. We decided to put them in as regular types, but there were just too many! So we defined the types with variable functions and let you, the overwhelmed user, specify what the functions should be! Thus Scott Taylor's "z = sin(z) + z^2" formula type is now the "fn+fn" regular type, and EITHER function can be one of sin, cos, tan, cotan, sinh, cosh, tanh, cotanh, exp, log, sqr, recip, ident, zero, one, conj, flip, cosxx, asin, asinh, acos, acosh, atan, atanh, sqrt, abs, or cabs. Plus we give you 4 parameters to set, the complex coefficients of the two functions! Thus the innocent-looking "fn+fn" type is really 729 different types in disguise, not counting the damage done by the parameters! Lee informs us that you should not judge fractals by their "outer" appearance. For example, the images produced by z = sin(z) + z^2 and z = sin(z) - z^2 look very similar, but are different when you zoom in. ; ; ~Topic=Kam Torus, Label=HT_KAM (type=kamtorus, kamtorus3d) This type is created by superimposing orbits generated by a set of equations, with a variable incremented each time. x(0) = y(0) = orbit/3;\ x(n+1) = x(n)*cos(a) + (x(n)*x(n)-y(n))*sin(a)\ y(n+1) = x(n)*sin(a) - (x(n)*x(n)-y(n))*cos(a)\ After each orbit, 'orbit' is incremented by a step size. The parameters are angle "a", step size for incrementing 'orbit', stop value for 'orbit', and points per orbit. Try this with a stop value of 5 with sound=x for some weird fractal music (ok, ok, fractal noise)! You will also see the KAM Torus head into some chaotic territory that Scott Taylor wanted to hide from you by setting the defaults the way he did, but now we have revealed all! The 3D variant is created by treating 'orbit' as the z coordinate. With both variants, you can adjust the "maxiter" value ( options screen or parameter maxiter=) to change the number of orbits plotted. ; ; ~Topic=Bifurcation, Label=HT_BIF (type=bifxxx) The wonder of fractal geometry is that such complex forms can arise from such simple generating processes. A parallel surprise has emerged in the study of dynamical systems: that simple, deterministic equations can yield chaotic behavior, in which the system never settles down to a steady state or even a periodic loop. Often such systems behave normally up to a certain level of some controlling parameter, then go through a transition in which there are two possible solutions, then four, and finally a chaotic array of possibilities. This emerged many years ago in biological models of population growth. Consider a (highly over-simplified) model in which the rate of growth is partly a function of the size of the current population: New Population = Growth Rate * Old Population * (1 - Old Population) where population is normalized to be between 0 and 1. At growth rates less than 200 percent, this model is stable: for any starting value, after several generations the population settles down to a stable level. But for rates over 200 percent, the equation's curve splits or "bifurcates" into two discrete solutions, then four, and soon becomes chaotic. Type=bifurcation illustrates this model. (Although it's now considered a poor one for real populations, it helped get people thinking about chaotic systems.) The horizontal axis represents growth rates, from 190 percent (far left) to 400 percent; the vertical axis normalized population values, from 0 to 4/3. Notice that within the chaotic region, there are narrow bands where there is a small, odd number of stable values. It turns out that the geometry of this branching is fractal; zoom in where changing pixel colors look suspicious, and see for yourself. Three parameters apply to bifurcations: Filter Cycles, Seed Population, and Function or Beta. Filter Cycles (default 1000) is the number of iterations to be done before plotting maxiter population values. This gives the iteration time to settle into the characteristic patterns that constitute the bifurcation diagram, and results in a clean-looking plot. However, using lower values produces interesting results too. Set Filter Cycles to 1 for an unfiltered map. Seed Population (default 0.66) is the initial population value from which all others are calculated. For filtered maps the final image is independent of Seed Population value in the valid range (0.0 < Seed Population < 1.0). ~OnlineFF Seed Population becomes effective in unfiltered maps - try setting Filter Cycles to 1 (unfiltered) and Seed Population to 0.001 ("PARAMS=1/.001" on the command line). This results in a map overlaid with nice curves. Each Seed Population value results in a different set of curves. Function (default "ident") is the function applied to the old population before the new population is determined. The "ident" function calculates the same bifurcation fractal that was generated before these formulae were generalized. Beta is used in the bifmay bifurcations and is the power to which the denominator is raised. Note that fractint normally uses periodicity checking to speed up bifurcation computation. However, in some cases a better quality image will be obtained if you turn off periodicity checking with "periodicity=no"; for instance, if you use a high number of iterations and a smooth colormap. Many formulae can be used to produce bifurcations. Mitchel Feigenbaum studied lots of bifurcations in the mid-70's, using a HP-65 calculator (IBM PCs, Fractals, and Fractint, were all Sci-Fi then !). He studied where bifurcations occurred, for the formula r*p*(1-p), the one described above. He found that the ratios of lengths of adjacent areas of bifurcation were four and a bit. These ratios vary, but, as the growth rate increases, they tend to a limit of 4.669+. This helped him guess where bifurcation points would be, and saved lots of time. When he studied bifurcations of r*sin(PI*p) he found a similar pattern, which is not surprising in itself. However, 4.669+ popped out, again. Different formulae, same number ? Now, THAT's surprising ! He tried many other formulae and ALWAYS got 4.669+ - Hot Damn !!! So hot, in fact, that he phoned home and told his Mom it would make him Famous ! He also went on to tell other scientists. The rest is History... (It has been conjectured that if Feigenbaum had a copy of Fractint, and used it to study bifurcations, he may never have found his Number, as it only became obvious from long perusal of hand-written lists of values, without the distraction of wild color-cycling effects !). ~OnlineFF We now know that this number is as universal as PI or E. It appears in situations ranging from fluid-flow turbulence, electronic oscillators, chemical reactions, and even the Mandelbrot Set - yup, fraid so: "budding" of the Mandelbrot Set along the negative real axis occurs at intervals determined by Feigenbaum's Number, 4.669201660910..... Fractint does not make direct use of the Feigenbaum Number (YET !). However, it does now reflect the fact that there is a whole sub-species of Bifurcation-type fractals. Those implemented to date, and the related formulae, (writing P for pop[n+1] and p for pop[n]) are : ~Format- bifurcation P = p + r*fn(p)*(1-fn(p)) Verhulst Bifurcations. biflambda P = r*fn(p)*(1-fn(p)) Real equivalent of Lambda Sets. bif+sinpi P = p + r*fn(PI*p) Population scenario based on... bif=sinpi P = r*fn(PI*p) ...Feigenbaum's second formula. bifstewart P = r*fn(p)*fn(p) - 1 Stewart Map. bifmay P = r*p / ((1+p)^b) May Map. ~Format+ It took a while for bifurcations to appear here, despite them being over a century old, and intimately related to chaotic systems. However, they are now truly alive and well in Fractint! ; ; ~Topic=Orbit Fractals Orbit Fractals are generated by plotting an orbit path in two or three dimensional space. See {Lorenz Attractors}, {Rossler Attractors}, {Henon Attractors}, {Pickover Attractors}, {Gingerbreadman}, and {Martin Attractors}. The orbit trajectory for these types can be saved in the file ORBITS.RAW by invoking Fractint with the "orbitsave=yes" command-line option. This file will be overwritten each time you generate a new fractal, so rename it if you want to save it. A nifty program called Acrospin can read these files and rapidly rotate them in 3-D - see {=@ACROSPIN Acrospin}. ; ; ~Topic=Lorenz Attractors, Label=HT_LORENZ (type=lorenz/lorenz3d) The "Lorenz Attractor" is a "simple" set of three deterministic equations developed by Edward Lorenz while studying the non- repeatability of weather patterns. The weather forecaster's basic problem is that even very tiny changes in initial patterns ("the beating of a butterfly's wings" - the official term is "sensitive dependence on initial conditions") eventually reduces the best weather forecast to rubble. The lorenz attractor is the plot of the orbit of a dynamic system consisting of three first order non-linear differential equations. The solution to the differential equation is vector-valued function of one variable. If you think of the variable as time, the solution traces an orbit. The orbit is made up of two spirals at an angle to each other in three dimensions. We change the orbit color as time goes on to add a little dazzle to the image. The equations are: dx/dt = -a*x + a*y\ dy/dt = b*x - y -z*x\ dz/dt = -c*z + x*y\ We solve these differential equations approximately using a method known as the first order taylor series. Calculus teachers everywhere will kill us for saying this, but you treat the notation for the derivative dx/dt as though it really is a fraction, with "dx" the small change in x that happens when the time changes "dt". So multiply through the above equations by dt, and you will have the change in the orbit for a small time step. We add these changes to the old vector to get the new vector after one step. This gives us: xnew = x + (-a*x*dt) + (a*y*dt)\ ynew = y + (b*x*dt) - (y*dt) - (z*x*dt)\ znew = z + (-c*z*dt) + (x*y*dt)\ (default values: dt = .02, a = 5, b = 15, c = 1)\ We connect the successive points with a line, project the resulting 3D orbit onto the screen, and voila! The Lorenz Attractor! We have added two versions of the Lorenz Attractor. "Type=lorenz" is the Lorenz attractor as seen in everyday 2D. "Type=lorenz3d" is the same set of equations with the added twist that the results are run through our perspective 3D routines, so that you get to view it from different angles (you can modify your perspective "on the fly" by using the command.) If you set the "stereo" option to "2", and have red/blue funny glasses on, you will see the attractor orbit with depth perception. Hint: the default perspective values (x = 60, y = 30, z = 0) aren't the best ones to use for fun Lorenz Attractor viewing. Experiment a bit - start with rotation values of 0/0/0 and then change to 20/0/0 and 40/0/0 to see the attractor from different angles.- and while you're at it, use a non-zero perspective point Try 100 and see what happens when you get *inside* the Lorenz orbits. Here comes one - Duck! While you are at it, turn on the sound with the "X". This way you'll at least hear it coming! Different Lorenz attractors can be created using different parameters. Four parameters are used. The first is the time-step (dt). The default value is .02. A smaller value makes the plotting go slower; a larger value is faster but rougher. A line is drawn to connect successive orbit values. The 2nd, third, and fourth parameters are coefficients used in the differential equation (a, b, and c). The default values are 5, 15, and 1. Try changing these a little at a time to see the result. ; ; ~Topic=Rossler Attractors, Label=HT_ROSS (type=rossler3D) This fractal is named after the German Otto Rossler, a non-practicing medical doctor who approached chaos with a bemusedly philosophical attitude. He would see strange attractors as philosophical objects. His fractal namesake looks like a band of ribbon with a fold in it. All we can say is we used the same calculus-teacher-defeating trick of multiplying the equations by "dt" to solve the differential equation and generate the orbit. This time we will skip straight to the orbit generator - if you followed what we did above with type {=HT_LORENZ Lorenz} you can easily reverse engineer the differential equations. xnew = x - y*dt - z*dt\ ynew = y + x*dt + a*y*dt\ znew = z + b*dt + x*z*dt - c*z*dt\ Default parameters are dt = .04, a = .2, b = .2, c = 5.7 ; ; ~Topic=Henon Attractors, Label=HT_HENON (type=henon) Michel Henon was an astronomer at Nice observatory in southern France. He came to the subject of fractals via investigations of the orbits of astronomical objects. The strange attractor most often linked with Henon's name comes not from a differential equation, but from the world of discrete mathematics - difference equations. The Henon map is an example of a very simple dynamic system that exhibits strange behavior. The orbit traces out a characteristic banana shape, but on close inspection, the shape is made up of thicker and thinner parts. Upon magnification, the thicker bands resolve to still other thick and thin components. And so it goes forever! The equations that generate this strange pattern perform the mathematical equivalent of repeated stretching and folding, over and over again. xnew = 1 + y - a*x*x\ ynew = b*x\ The default parameters are a=1.4 and b=.3. ; ; ~Topic=Pickover Attractors, Label=HT_PICK (type=pickover) Clifford A. Pickover of the IBM Thomas J. Watson Research center is such a creative source for fractals that we attach his name to this one only with great trepidation. Probably tomorrow he'll come up with another one and we'll be back to square one trying to figure out a name! This one is the three dimensional orbit defined by: xnew = sin(a*y) - z*cos(b*x)\ ynew = z*sin(c*x) - cos(d*y)\ znew = sin(x)\ Default parameters are: a = 2.24, b = .43, c = -.65, d = -2.43 ; ; ~Topic=Gingerbreadman, Label=HT_GINGER (type=gingerbreadman) This simple fractal is a charming example stolen from "Science of Fractal Images", p. 149. xnew = 1 - y + |x|\ ynew = x The initial x and y values are set by parameters, defaults x=-.1, y = 0. ; ; ~Topic=Martin Attractors, Label=HT_MARTIN (type=hopalong/martin) These fractal types are from A. K. Dewdney's "Computer Recreations" column in "Scientific American". They are attributed to Barry Martin of Aston University in Birmingham, England. Hopalong is an "orbit" type fractal like lorenz. The image is obtained by iterating this formula after setting z(0) = y(0) = 0:\ x(n+1) = y(n) - sign(x(n))*sqrt(abs(b*x(n)-c))\ y(n+1) = a - x(n)\ Parameters are a, b, and c. The function "sign()" returns 1 if the argument is positive, -1 if argument is negative. This fractal continues to develop in surprising ways after many iterations. Another Martin fractal is simpler. The iterated formula is:\ x(n+1) = y(n) - sin(x(n))\ y(n+1) = a - x(n)\ The parameter is "a". Try values near the number pi. Michael Peters has based the HOP program on variations of these Martin types. You will find three of these here: chip, quadruptwo, and threeply. ; ; ; ~Topic=Icon, Label=HT_ICON (type=icon/icon3d) This fractal type was inspired by the book "Symmetry in Chaos" by Michael Field and Martin Golubitsky (ISBN 0-19-853689-5, Oxford Press) To quote from the book's jacket, "Field and Golubitsky describe how a chaotic process eventually can lead to symmetric patterns (in a river, for instance, photographs of the turbulent movement of eddies, taken over time, often reveal patterns on the average." The Icon type implemented here maps the classic population logistic map of bifurcation fractals onto the complex plane in Dn symmetry. The initial points plotted are the more chaotic initial orbits, but as you wait, delicate webs will begin to form as the orbits settle into a more periodic pattern. Since pixels are colored by the number of times they are hit, the more periodic paths will become clarified with time. These fractals run continuously. There are 6 parameters: Lambda, Alpha, Beta, Gamma, Omega, and Degree Omega 0 = Dn, or dihedral (rotation + reflectional) symmetry !0 = Zn, or cyclic (rotational) symmetry Degree = n, or Degree of symmetry ; ; ; ; ; New type include by Humberto R. Baptista, based on the ; Pickover book: Chaos In Wonderland ; ~Topic=Latoocarfian, Label=HT_LATOO (type=latoocarfian) This fractal type first appeared in the book "Chaos in Wonderland" by Clifford Pickover (ISBN 0-312-10743-9 St. Martin's Press) The Latoocarfians are beings that inhabit the moon Ganymede (of Jupiter) and have their forms generated by these formulas. The initial points plotted are the more chaotic initial orbits, but as you wait, delicate webs will begin to form as the orbits settle into a more periodic pattern. Since pixels are colored by the number of times they are hit, the more periodic paths will become clarified with time. There are 4 parameters: a, b, c, d and we recomend: a > -3, b < 3, c > 0.5, d < 1.5 ; ; ~Topic=Quaternion, Label=HT_QUAT (type=quat,quatjul) These fractals are based on quaternions. Quaternions are an extension of complex numbers, with 4 parts instead of 2. That is, a quaternion Q equals a+ib+jc+kd, where a,b,c,d are reals. Quaternions have rules for addition and multiplication. The normal Mandelbrot and Julia formulas can be generalized to use quaternions instead of complex numbers. There is one complication. Complex numbers have 2 parts, so they can be displayed on a plane. Quaternions have 4 parts, so they require 4 dimensions to view. That is, the quaternion Mandelbrot set is actually a 4-dimensional object. Each quaternion C generates a 4-dimensional Julia set. One method of displaying the 4-dimensional object is to take a 3-dimensional slice and render the resulting object in 3-dimensional perspective. Fractint isn't that sophisticated, so it merely displays a 2-dimensional slice of the resulting object. (Note: Now Fractint is that sophisticated! See the Julibrot type!) In fractint, for the Julia set, you can specify the four parameters of the quaternion constant: c=(c1,ci,cj,ck), but the 2-dimensional slice of the z-plane Julia set is fixed to (xpixel,ypixel,0,0). For the Mandelbrot set, you can specify the position of the c-plane slice: (xpixel,ypixel,cj,ck). These fractals are discussed in Chapter 10 of Pickover's "Computers, Pattern, Chaos, and Beauty". See also {HyperComplex} and { Quaternion and Hypercomplex Algebra } ; ; ~Topic=HyperComplex, Label=HT_HYPERC (type=hypercomplex,hypercomplexj) These fractals are based on hypercomplex numbers, which like quaternions are a four dimensional generalization of complex numbers. It is not possible to fully generalize the complex numbers to four dimensions without sacrificing some of the algebraic properties shared by real and complex numbers. Quaternions violate the commutative law of multiplication, which says z1*z2 = z2*z1. Hypercomplex numbers fail the rule that says all non-zero elements have multiplicative inverses - that is, if z is not 0, there should be a number 1/z such that (1/z)*(z) = 1. This law holds most of the time but not all the time for hypercomplex numbers. However hypercomplex numbers have a wonderful property for fractal purposes. Every function defined for complex numbers has a simple generalization to hypercomplex numbers. Fractint's implementation takes advantage of this by using "fn" variables - the iteration formula is\ h(n+1) = fn(h(n)) + C.\ where "fn" is the hypercomplex generalization of sin, cos, log, sqr etc. ~OnlineFF You can see 3D versions of these fractals using fractal type Julibrot. Hypercomplex numbers were brought to our attention by Clyde Davenport, author of "A Hypercomplex Calculus with Applications to Relativity", ISBN 0-9623837-0-8. See also {Quaternion} and { Quaternion and Hypercomplex Algebra } ; ; ~Topic=Cellular Automata, Label=HT_CELLULAR (type=cellular) These fractals are generated by 1-dimensional cellular automata. Consider a 1-dimensional line of cells, where each cell can have the value 0 or 1. In each time step, the new value of a cell is computed from the old value of the cell and the values of its neighbors. On the screen, each horizontal row shows the value of the cells at any one time. The time axis proceeds down the screen, with each row computed from the row above. Different classes of cellular automata can be described by how many different states a cell can have (k), and how many neighbors on each side are examined (r). Fractint implements the binary nearest neighbor cellular automata (k=2,r=1), the binary next-nearest neighbor cellular automata (k=2,r=2), and the ternary nearest neighbor cellular automata (k=3,r=1) and several others. The rules used here determine the next state of a given cell by using the sum of the states in the cell's neighborhood. The sum of the cells in the neighborhood are mapped by rule to the new value of the cell. For the binary nearest neighbor cellular automata, only the closest neighbor on each side is used. This results in a 4 digit rule controlling the generation of each new line: if each of the cells in the neighborhood is 1, the maximum sum is 1+1+1 = 3 and the sum can range from 0 to 3, or 4 values. This results in a 4 digit rule. For instance, in the rule 1010, starting from the right we have 0->0, 1->1, 2->0, 3->1. If the cell's neighborhood sums to 2, the new cell value would be 0. For the next-nearest cellular automata (kr = 22), each pixel is determined from the pixel value and the two neighbors on each side. This results in a 6 digit rule. For the ternary nearest neighbor cellular automata (kr = 31), each cell can have the value 0, 1, or 2. A single neighbor on each side is examined, resulting in a 7 digit rule. kr #'s in rule example rule | kr #'s in rule example rule\ 21 4 1010 | 42 16 2300331230331001\ 31 7 1211001 | 23 8 10011001\ 41 10 3311100320 | 33 15 021110101210010\ 51 13 2114220444030 | 24 10 0101001110\ 61 16 3452355321541340 | 25 12 110101011001\ 22 6 011010 | 26 14 00001100000110\ 32 11 21212002010 | 27 16 0010000000000110\ The starting row of cells can be set to a pattern of up to 16 digits or to a random pattern. The borders are set to zeros if a pattern is entered or are set randomly if the starting row is set randomly. A zero rule will randomly generate the rule to use. Hitting the space bar toggles between continuously generating the cellular automata and stopping at the end of the current screen. Recommended reading: "Computer Software in Science and Mathematics", Stephen Wolfram, Scientific American, September, 1984. "Abstract Mathematical Art", Kenneth E. Perry, BYTE, December, 1986. "The Armchair Universe", A. K. Dewdney, W. H. Freeman and Company, 1988. "Complex Patterns Generated by Next Nearest Neighbors Cellular Automata", Wentian Li, Computers & Graphics, Volume 13, Number 4. ; ; ~Topic=Ant Automaton, Label=HT_ANT (type=ant) This fractal type is the generalized Ant Automaton described in the "Computer Recreations" column of the July 1994 Scientific American. The article attributes this automaton to Greg Turk of Stanford University, Leonid A. Bunivomitch of the Georgia Institute of Technology, and S. E. Troubetzkoy of the University of Bielefeld. The ant wanders around the screen, starting at the middle. A rule string, which the user can input as Fractint's first parameter, determines the ant's direction. This rule string is stored as a double precision number in our implementation. Only the digit 1 is significant -- all other digits are treated as 0. When the type 1 ant leaves a cell (a pixel on the screen) of color k, it turns right if the kth symbol in the rule string is a 1, or left otherwise. Then the color in the abandoned cell is incremented. The type 2 ant uses only the rule string to move around. If the digit of the rule string is a 1, the ant turns right and puts a zero in current cell, otherwise it turns left and put a number in the current cell. An empty rule string causes the rule to be generated randomly. Fractint's 2nd parameter is a maximum iteration to guarantee that the fractal will terminate. The 3rd parameter is the number of ants (up to 256). If you select 0 ants, then the number oif ants is random. The 4th paramter allows you to select ant type 1 (the original), or type 2. The 5th parameter determines whether the ant's progress stops when the edge of the screen is reaches (as in the original implementation), or whether the ant's path wraps to the opposite side of the screen. You can slow down the ant to see her better using the

screen Orbit Delay - try 10. The 6th parameter accepts a random seed, allowing you to duplicate images using random values (empty rule string or 0 maximum ants. Try rule string 10. In this case, the ant moves in a seemingly random pattern, then suddenly marches off in a straight line. This happens for many other rule strings. The default 1100 produces symmetrical images. If the screen initially contains an image, the path of the ant changes. To try this, generate a fractal, and press . Note that images seeded with an image are not (yet) reproducible in PAR files. When started using the keys, after the ant is finished the default fractal type reverts to that of the underlying fractal. ~Label=ANTCOMMANDS Special keystrokes are in effect during the ant's march. The key toggles a step-by-step mode. When in this mode, press to see each step of the ant's progress. When orbit delay (on

screen) is set to 1, the step mode is the default. If you press the right or left arrow during the ant's journey, you can adjust the orbit delay factor with the arrow keys (increment by 10) or ctrl-arrow keys (increment by 100). Press any other key to get out of the orbit delay adjustment mode. Higher values cause slower motion. Changed values are not saved after the ant is finished, but you can set the orbit delay value in advance from the

screen. ; ; ; ~Topic=Test, Label=HT_TEST (type=test) This is a stub that we (and you!) use for trying out new fractal types. "Type=test" fractals make use of Fractint's structure and features for whatever code is in the routine 'testpt()' (located in the small source file TESTPT.C) to determine the color of a particular pixel. If you have a favorite fractal type that you believe would fit nicely into Fractint, just rewrite the C function in TESTPT.C (or use the prototype function there, which is a simple M-set implementation) with an algorithm that computes a color based on a point in the complex plane. After you get it working, send your code to one of the authors and we might just add it to the next release of Fractint, with full credit to you. Our criteria are: 1) an interesting image and 2) a formula significantly different from types already supported. (Bribery may also work. THIS author is completely honest, but I don't trust those other guys.) Be sure to include an explanation of your algorithm and the parameters supported, preferably formatted as you see here to simplify folding it into the documentation. ; ; ~Topic=Formula, Label=HT_FORMULA (type=formula) This is a "roll-your-own" fractal interpreter - you don't even need a compiler! To run a "type=formula" fractal, you first need a text file containing formulas (there's a sample file - FRACTINT.FRM - included with this distribution). When you select the "formula" fractal type, Fractint scans the current formula file (default is FRACTINT.FRM) for formulas, then prompts you for the formula name you wish to run. After prompting for any parameters, the formula is parsed for syntax errors and then the fractal is generated. If you want to use a different formula file, press when you are prompted to select a formula name. There are two command-line options that work with type=formula ("formulafile=" and "formulaname="), useful when you are using this fractal type in batch mode. A formula may also be included in a PAR file by preceeding the formulaname with frm:, for example: frm:Mandelbrot \{...\}. The PAR file will always be searched first for any required formula. ~OnlineFF The general format is: Name Symmetry Per Image Settings\ | | |\ Mandelbrot(XAXIS)[periodicity=0 float=y] \{ <= single line required\ z = Pixel: z = sqr(z) + pixel, |z| <= 4 \}\ | | |\ Initial Iteration Bailout\ Condition Criteria\ When initially selected from the fractal type formula screen, the Symmetry and any Per Image Settings are enforced. The Per Image Settings will be saved to PARs and GIFs, and can be changed from the appropriate screen. For every pixel, Initial Conditions are set, then the Iterations performed while the Bailout Criteria remains true or until 'z' turns into a periodic loop. All variables are created automatically by their usage and treated as complex. If you declare 'v = 2' then the variable 'v' is treated as a complex with an imaginary value of zero. Variables must start with a letter or an underscore. NOTE: For periodicity checking, inside options, outside options, and the passes=o option to work correctly it is necessary to leave the result of the orbit calculation in the variable z. ~OnlineFF The possible values for Symmetry are:\ XAXIS, XAXIS_NOPARM, XAXIS_NOREAL, XAXIS_NOIMAG\ YAXIS, YAXIS_NOPARM\ XYAXIS, XYAXIS_NOPARM\ ORIGIN, ORIGIN_NOPARM\ PI_SYM, PI_SYM_NOPARM\ These will force the symmetry even if no symmetry is actually present, so try your formulas without symmetry before you use these. For the NOPARM variants, p1 through p5 are checked to make sure that the paramaters are equal to zero (0,0). If they are all zero, the symmetry is applied. For the XAXIS_NOREAL (or XAXIS_NOIMAG) variant, p1 through p5 are checked to make sure that the real (or imaginary) part of each parameter is equal to zero (0,?)(or (?,0)). If the real (or imaginary) part of p1 through p5 is zero, the XAXIS symmetry is applied. ~OnlineFF The possible uses for Per Image Settings are:\ setting float=y\ setting periodicity=0\ Certain values cannot be set with the Per Image Settings. These include 'params=', 'corners=', and 'center-mag='. There may be others. These values get reset after the formula is parsed and before the iteration starts. Sequential processing of the formula can be altered with the flow control\ instructions IF(expr1)\ statements\ ELSEIF(expr2) [any number of these are permitted in a block]\ statements\ .\ .\ ELSEIF(exprn)\ statements\ ELSE [if used, only one is permitted in a block]\ statements\ ENDIF\ where the expressions are evaluated and the statements executed are those immediately following the first "true" expression (the real part of the complex variable being nonzero). Nesting of IF..ENDIF blocks is permitted. Note that ELSEIF() does not require a separate ENDIF. Each branching instruction must be a separate formula statement, separated from other statements by a comma or an end of line. There is a limit of 200 branching instructions per formula (ELSEIF counts as two branching instructions). Unlimited nesting is permitted; each ELSEIF, ELSE, and ENDIF relates to the immediately preceding "non endif'ed" IF. An IF() and its ENDIF cannot traverse the end of the initialization section of the formula. ~OnlineFF ~Format- Predefined Variables (x, y) -------------------------------------------- z used for periodicity checking p1 parameters 1 and 2 p2 parameters 3 and 4 p3 parameters 5 and 6 p4 parameters 7 and 8 p5 parameters 9 and 10 pixel complex coordinates LastSqr Modulus from the last sqr() function rand Complex random number pi (3.14159..., 0.0) e (2.71828..., 0.0) maxit (maxit, 0) maximum iterations scrnmax (xdots, ydots) max horizontal/vertical resolution. e.g. for SF7 scrnmax = (1024,768) scrnpix (col, row) pixel screen coordinates. (col, row) ranges from (0,0) to (xdots-1, ydots-1) whitesq ((col+row) modulo 2, 0) i.e. thinking of the screen coordinates as a large checker board, whitesq is (1,0) for the white squares and (0,0) for the black ones. ~OnlineFF Predefined Variables (Continued) -------------------------------------------- ismand 1 (true) by default, changes to 0 when the Mandelbrot/ Julia SPACE toggle is pressed. This allows writing formulas that have both "Mandelbrot" and "Julia" behavior. ~LABEL=@PREDEFCENTERMAG center Zoom box (Xcenter, Ycenter) (see {=@CENTERMAG center-mag}) magxmag Zoom box (Mag, Xmagnitude) (see {=@CENTERMAG center-mag}) rotskew Zoom box (Rotation, Skew) (see {=@CENTERMAG center-mag}) Precedence -------------------------------------------- 1 sin(), cos(), sinh(), cosh(), cosxx(), tan(), cotan(), tanh(), cotanh(), sqr(), log(), exp(), abs(), conj(), real(), imag(), flip(), fn1(), fn2(), fn3(), fn4(), srand(), asin(), asinh(), acos(), acosh(), atan(), atanh(), sqrt(), cabs(), floor(), ceil(), trunc(), round() 2 - (negation), ^ (power) 3 * (multiplication), / (division) 4 + (addition), - (subtraction) 5 = (assignment) ~OnlineFF Precedence (Continued) -------------------------------------------- 6 < (less than), <= (less than or equal to) > (greater than), >= (greater than or equal to) == (equal to), != (not equal to) 7 && (logical AND), || (logical OR) ~Format+ Precedence may be overridden by use of parenthesis. Note the modulus squared operator |z| is also parenthetic and always sets the imaginary component to zero. This means 'c * |z - 4|' first subtracts 4 from z, calculates the modulus squared then multiplies times 'c'. Nested modulus squared operators require overriding parenthesis: c * |z + (|pixel|)|\ The functions fn1(...) to fn4(...) are variable functions - when used, the user is prompted at run time (on the screen) to specify one of sin, cos, sinh, cosh, exp, log, sqr, etc. for each required variable function. Most of the functions have their conventional meaning, here are a few notes on others that are not conventional. ~Format- abs() - returns abs(x)+i*abs(y) |x+iy| - returns x*x+y*y cabs() - returns sqrt(x*x+y*y) conj() - returns the complex conjugate of the argument. That is, changes sign of the imaginary component of argument: (x,y) becomes (x,-y) cosxx() - duplicates a bug in the version 16 cos() function flip() - Swap the real and imaginary components of the complex number. e.g. (4,5) would become (5,4) ident() - identity function. Leaves the value of the argument unchanged, acting like a "z" term in a formula. zero() - returns 0. one() - returns 1. floor() - largest integer not greater than the argument floor(x+iy) = floor(x) + i*floor(y) ceil() - smallest integer not less than the argument trunc() - truncate fraction part toward zero round() - round to nearest integer or up. e.g. round(2.5,3.4) = (3,3) ~Format+ The formulas are performed using either integer or floating point mathematics depending on the floating point toggle. If you do not have an FPU then type MPC math is performed in lieu of traditional floating point. The 'rand' predefined variable is changed with each iteration to a new random number with the real and imaginary components containing a value between zero and 1. Use the srand() function to initialize the random numbers to a consistent random number sequence. If a formula does not contain the srand() function, then the formula compiler will use the system time to initialize the sequence. This could cause a different fractal to be generated each time the formula is used depending on how the formula is written. A formula containing one of the predefined variables "maxit", "scrnpix" or "scrnmax" will be automatically run in floating point mode. The rounding functions must be used cautiously; formulas that depend on exact values of numbers will not work reliably in all cases. For example, in floating point mode, trunc(6/3) returns 1 while trunc(6/real(3)) returns 2.\ Note that if x is an integer, floor(x) = ceil(x) = trunc(x) = round(x) = x. Remember that when using integer math there is a limited dynamic range, so what you think may be a fractal could really be just a limitation of the integer math range. God may work with integers, but God's dynamic range is many orders of magnitude greater than our puny 32 bit mathematics! Always verify with the floating point toggle. For mathematical formulas of functions used in the parser language, see\ { Trig Identities} ; ; ~Topic=Frothy Basins, Label=HT_FROTH (type=frothybasin) Frothy Basins, or Riddled Basins, were discovered by James C. Alexander of the University of Maryland. The discussion below is derived from a two page article entitled "Basins of Froth" in Science News, November 14, 1992 and from correspondence with others, including Dr. Alexander. The equations that generate this fractal are not very different from those that generate many other orbit fractals. ~Format- Z(0) = pixel; Z(n+1) = Z(n)^2 - C*conj(Z(n)) where C = 1 + A*i ~Format+ One of the things that makes this fractal so interesting is the shape of the dynamical system's attractors. It is not at all uncommon for a dynamical system to have non-point attractors. Shapes such as circles are very common. Strange attractors are attractors which are themselves fractal. What is unusual about this system, however, is that the attractors intersect. This is the first case in which such a phenomenon has been observed. The attractors for this system are made up of line segments which overlap to form an equilateral triangle. This attractor triangle can be seen by using the "show orbits" option (the 'o' key) or the "orbits window" option (the ctrl-'o' key). The number of attractors present is dependant on the value of A, the imaginary part of C. For values where A <= 1.028713768218725..., there are three attractors. When A is larger than this critical value, two of attractors merge into one, leaving only two attractors. An interesting variation on this fractal can be generated by applying the above mapping twice per each iteration. The result is that some of the attractors are split into two parts, giving the system either six or three attractors, depending on whether A is less than or greater than the critical value. These are also called "Riddled Basins" because each basin is riddled with holes. Which attractor a point is eventually pulled into is extremely sensitive to its initial position. A very slight change in any direction may cause it to end up on a different attractor. As a result, the basins are thoroughly intermingled. The effect appears to be a frothy mixture that has been subjected to lots of stirring and folding. Pixel color is determined by which attractor captures the orbit. The shade of color is determined by the number of iterations required to capture the orbit. In Fractint, the actual shade of color used depends on how many colors are available in the video mode being used. If 256 colors are available, the default coloring scheme is determined by the number of iterations that were required to capture the orbit. An alternative coloring scheme can be used where the shade is determined by the iterations required divided by the maximum iterations. This method is especially useful on deeply zoomed images. If only 16 colors are available, then only the alternative coloring scheme is used. If fewer than 16 colors are available, then Fractint just colors the basins without any shading. ; ; ~Topic=Julibrots, Label=HT_JULIBROT (type=julibrot) The Julibrot fractal type uses a general-purpose renderer for visualizing three dimensional solid fractals. Originally Mark Peterson developed this rendering mechanism to view a 3-D sections of a 4-D structure he called a "Julibrot". This structure, also called "layered Julia set" in the fractal literature, hinges on the relationship between the Mandelbrot and Julia sets. Each Julia set is created using a fixed value c in the iterated formula z^2 + c. The Julibrot is created by layering Julia sets in the x-y plane and continuously varying c, creating new Julia sets as z is incremented. The solid shape thus created is rendered by shading the surface using a brightness inversely proportional to the virtual viewer's eye. Starting with Fractint version 18, the Julibrot engine can be used with other Julia formulas besides the classic z^2 + c. The first field on the Julibrot parameter screen lets you select which orbit formula to use. You can also use the Julibrot renderer to visualize 3D cross sections of true four dimensional Quaternion and Hypercomplex fractals. The Julibrot Parameter Screens Orbit Algorithm - select the orbit algorithm to use. The available possibilities include 2-D Julia and both mandelbrot and Julia variants of the 4-D Quaternion and Hypercomplex fractals. Orbit parameters - the next screen lets you fill in any parameters belonging to the orbit algorithm. This list of parameters is not necessarily the same as the list normally presented for the orbit algorithm, because some of these parameters are used in the Julibrot layering process. From/To Parameters These parameters allow you to specify the "Mandelbrot" values used to generate the layered Julias. The parameter c in the Julia formulas will be incremented in steps ranging from the "from" x and y values to the "to" x and y values. If the orbit formula is one of the "true" four dimensional fractal types quat, quatj, hypercomplex, or hypercomplexj, then these numbers are used with the 3rd and 4th dimensional values. The "from/to" variables are different for the different kinds of orbit algorithm. ~Format- 2D Julia sets - complex number formula z' = f(z) + c The "from/to" parameters change the values of c. 4D Julia sets - Quaternion or Hypercomplex formula z' = f(z) + c The four dimensions of c are set by the orbit parameters. The first two dimensions of z are determined by the corners values. The third and fourth dimensions of z are the "to/from" variables. 4D Mandelbrot sets - Quaternion or Hypercomplex formula z' = f(z) + c The first two dimensions of c are determined by the corners values. The third and fourth dimensions of c are the "to/from" variables. ~Format+ Distance between the eyes - set this to 2.5 if you want a red/blue anaglyph image, 0 for a normal greyscale image. Number of z pixels - this sets how many layers are rendered in the screen z-axis. Use a higher value with higher resolution video modes. The remainder of the parameters are needed to construct the red/blue picture so that the fractal appears with the desired depth and proper 'z' location. With the origin set to 8 inches beyond the screen plane and the depth of the fractal at 8 inches the default fractal will appear to start at 4 inches beyond the screen and extend to 12 inches if your eyeballs are 2.5 inches apart and located at a distance of 24 inches from the screen. The screen dimensions provide the reference frame. ; ; ~Topic=Diffusion Limited Aggregation, Label=HT_DIFFUS (type=diffusion) Standard diffusion begins with a single point in the center of the screen. Subsequent points move around randomly until coming into contact with a point already on the screen, at which time their locations are fixed and they are drawn. This process repeats until the fractals reaches the edge of the screen. Use the show orbits function to see the points' random motion. One unfortunate problem is that on a large screen, this process will tend to take eons. To speed things up, the points are restricted to a box around the initial point. The first parameter to diffusion contains the size of the border between the fractal and the edge of the box. If you make this number small, the fractal will look more solid and will be generated more quickly. The second parameter to diffusion changes the type of growth. If you set it to 1, then the diffusion will start with a line along the bottom of the screen. Points will appear above this line and the fractal will grow upward. For this fractal, the points are restricted to a box which is as wide as the screen but whose distance from the fractal is given by the border size (the first parameter). Initial points are released from a centered segment along the top of this box which has a width equal to twice the border size. If the second parameter is set to 2, then diffusion begins with a square box on the screen. Points appear on a circle inside the box whose distance from the box is equal to the border size. This fractal grows very slowly since the points are not restricted to a small box. The third and last parameter for diffusion controls the color of the fractal. If it is set to zero then points are colored randomly. Otherwise, it tells how often to shift the color of the points being deposited. If you set it to 150, for example, then the color of the points will shift every 150 points leading to a radial color pattern if you are using the standards diffusion type. Diffusion was inspired by a Scientific American article a couple of years back which includes actual pictures of real physical phenomena that behave like this. Thanks to Adrian Mariano for providing the diffusion code and documentation. Juan J. Buhler added additional options. ; ; ~Topic=Lyapunov Fractals, Label=HT_LYAPUNOV (type=lyapunov) The Bifurcation fractal illustrates what happens in a simple population model as the growth rate increases. The Lyapunov fractal expands that model into two dimensions by letting the growth rate vary in a periodic fashion between two values. Each pair of growth rates is run through a logistic population model and a value called the Lyapunov Exponent is calculated for each pair and is plotted. The Lyapunov Exponent is calculated by adding up log | r - 2*r*x| over many cycles of the population model and dividing by the number of cycles. Negative Lyapunov exponents indicate a stable, periodic behavior and are plotted in color. Positive Lyapunov exponents indicate chaos (or a diverging model) and are colored black. Order parameter. Each possible periodic sequence yields a two dimensional space to explore. The Order parameter selects a sequence. The default value 0 represents the sequence ab which alternates between the two values of the growth parameter. On the screen, the a values run vertically and the b values run horizontally. Here is how to calculate the space parameter for any desired sequence. Take your sequence of a's and b's and arrange it so that it starts with at least 2 a's and ends with a b. It may be necessary to rotate the sequence or swap a's and b's. Strike the first a and the last b off the list and replace each remaining a with a 1 and each remaining b with a zero. Interpret this as a binary number and convert it into decimal. An Example. I like sonnets. A sonnet is a poem with fourteen lines that has the following rhyming sequence: abba abba abab cc. Ignoring the rhyming couplet at the end, let's calculate the Order parameter for this pattern. abbaabbaabab doesn't start with at least 2 a's \ aabbaabababb rotate it \ 1001101010 drop the first and last, replace with 0's and 1's \ 512+64+32+8+2 = 618 An Order parameter of 618 gives the Lyapunov equivalent of a sonnet. "How do I make thee? Let me count the ways..." Population Seed. When two parts of a Lyapunov overlap, which spike overlaps which is strongly dependent on the initial value of the population model. Any changes from using a different starting value between 0 and 1 may be subtle. The values 0 and 1 are interpreted in a special manner. A Seed of 1 will choose a random number between 0 and 1 at the start of each pixel. A Seed of 0 will suppress resetting the seed value between pixels unless the population model diverges in which case a random seed will be used on the next pixel. Filter Cycles. Like the Bifurcation model, the Lyapunov allow you to set the number of cycles that will be run to allow the model to approach equilibrium before the lyapunov exponent calculation is begun. The default value of 0 uses one half of the iterations before beginning the calculation of the exponent. Reference. A.K. Dewdney, Mathematical Recreations, Scientific American, Sept. 1991 ; ; ~Topic=Magnetic Fractals, Label=HT_MAGNET (type=magnet1m/.../magnet2j) These fractals use formulae derived from the study of hierarchical lattices, in the context of magnetic renormalisation transformations. This kinda stuff is useful in an area of theoretical physics that deals with magnetic phase-transitions (predicting at which temperatures a given substance will be magnetic, or non-magnetic). In an attempt to clarify the results obtained for Real temperatures (the kind that you and I can feel), the study moved into the realm of Complex Numbers, aiming to spot Real phase-transitions by finding the intersections of lines representing Complex phase-transitions with the Real Axis. The first people to try this were two physicists called Yang and Lee, who found the situation a bit more complex than first expected, as the phase boundaries for Complex temperatures are (surprise!) fractals. And that's all the technical (?) background you're getting here! For more details (are you SERIOUS ?!) read "The Beauty of Fractals". When you understand it all, you might like to rewrite this section, before you start your new job as a professor of theoretical physics... In Fractint terms, the important bits of the above are "Fractals", "Complex Numbers", "Formulae", and "The Beauty of Fractals". Lifting the Formulae straight out of the Book and iterating them over the Complex plane (just like the Mandelbrot set) produces Fractals. The formulae are a bit more complicated than the Z^2+C used for the Mandelbrot Set, that's all. They are : ~Format- [ ] 2 | Z^2 + (C-1) | MAGNET1 : | ------------- | | 2*Z + (C-2) | [ ] [ ] 2 | Z^3 + 3*(C-1)*Z + (C-1)*(C-2) | MAGNET2 : | --------------------------------------- | | 3*(Z^2) + 3*(C-2)*Z + (C-1)*(C-2) + 1 | [ ] ~Format+ These aren't quite as horrific as they look (oh yeah ?!) as they only involve two variables (Z and C), but cubing things, doing division, and eventually squaring the result (all in Complex Numbers) don't exactly spell S-p-e-e-d ! These are NOT the fastest fractals in Fractint ! As you might expect, for both formulae there is a single related Mandelbrot-type set (magnet1m, magnet2m) and an infinite number of related Julia-type sets (magnet1j, magnet2j), with the usual toggle between the corresponding Ms and Js via the spacebar. If you fancy delving into the Julia-types by hand, you will be prompted for the Real and Imaginary parts of the parameter denoted by C. The result is symmetrical about the Real axis (and therefore the initial image gets drawn in half the usual time) if you specify a value of Zero for the Imaginary part of C. Fractint Historical Note: Another complication (besides the formulae) in implementing these fractal types was that they all have a finite attractor (1.0 + 0.0i), as well as the usual one (Infinity). This fact spurred the development of Finite Attractor logic in Fractint. Without this code you can still generate these fractals, but you usually end up with a pretty boring image that is mostly deep blue "lake", courtesy of Fractint's standard {Periodicity Logic}. See {Finite Attractors} for more information on this aspect of Fractint internals. (Thanks to Kevin Allen for Magnetic type documentation above). ; ; ~Topic=Volterra-Lotka Fractals, Label=HT_VL (type=volterra-lotka) In The Beauty of Fractals, these images are offered as an example of "how an apparently innocent system of differential equations gives rise to unimaginably rich and complex behavior after discretization." The Volterra-Lotka equations are a refinement of attempts to model predator- prey systems. If x represents the prey population and y represents the predator population, their relationship can be expressed as: ~Format- dx/dt = Ax - Bxy = f(x,y) dy/dt = -Cy + Dxy = g(x,y) ~Format+ According to Peitgen and Richter, "Hence, x grows at a constant rate in the absence of y, and y decays at a constant rate in the absence of x. The prey is consumed in proportion to y, and the predators expand in proportion to x." They proceed to "discretize" this system, by "mating" the Euler and Heun methods. For purposes of image computation, their formula (Equation 8.3 on page 125) can be interpreted as: ~Format- x(new) = x + h/2 * [ f(x,y) + f[x + pf(x,y), y + pg(x,y)] ] y(new) = y + h/2 * [ g(x,y) + g[x + pf(x,y), y + pg(x,y)] ] ~Format+ This formula can be used to plot or connect single points, starting with arbitrary values of x(0) and y(0), to produce typical "strange attractor" images such as the ones commonly derived from the Henon or Lorenz formulae. But to produce an escape-time fractal, we iterate this formula for all (x, y) pairs that we can associate with pixels on our monitor screen. The standard window is: 0.0 < x < 6.0; 0.0 < y < 4.5. Since the "unimaginably rich and complex behavior" occurs with the points that do NOT escape, the inside coloring method assumes considerable importance. The parameters h and p can be selected between 0.0 and 1.0, and this determines the types of attractors that will result. Infinity and (1, 1) are predictable attractors. For certain combinations, an "invariant circle" (which is not strictly circular) and/or an orbit of period 9 also are attractive. The invariant circle and periodic orbit change with each (h, p) pair, and they must be determined empirically. That process would be thoroughly impractical to implement through any kind of fixed formula. This is especially true because even when these attractors are chosen, the threshold for determining when a point is "close enough" is quite arbitrary, and yet it affects the image considerably. The best compromise in the context of a generalized formula is to use either the "zmag" or "bof60" inside coloring options. See {Inside=bof60|bof61|zmag|fmod|period|atan} for details. This formula performs best with a relatively high bailout value; the default is set at 256, rather than the standard default of 4. ~Format- Reference: Peitgen, H.-O. and Richter, P.H. The Beauty of Fractals, Springer-Verlag, 1986; Section 8, pp. 125-7. ~Format+ ; ; ~Topic=Escher-Like Julia Sets, Label=HT_ESCHER (type=escher_julia) These unique variations on the Julia set theme, presented in The Science of Fractal Images, challenge us to expand our pre-conceived notions of how fractals should be iterated. We start with a very basic Julia formula: ~Format- z(n+1) = z(n)^2 + (0, 0i) ~Format+ The standard algorithm would test each iterated point to see if it "escapes to infinity". If its size or "modulus" (its distance from the origin) exceeds a preselected {Bailout Test} value, it is outside the Julia set, and it is banished to the world of multicolored level sets which color-cycle spectacularly. But another way of describing an escaped point is to say that it is "attracted" to infinity. We make this decision by calculating whether the point falls within the "target set" of all points closer to infinity than the boundary created by the bailout value. In this way, the "disk around infinity" is conceptually no different from the disks around {Finite Attractors} such as those used for Newton fractals. In the above formula, with c = (0, 0i), this standard algorithm yields a rather unexciting circle. But along comes Peitgen to tell us that "since T [the target set] can essentially be anything, this method has tremendous artistic potential. For example, T could be a so-called p-norm disk ... or a scaled filled-in Julia set or something designed by hand. This method opens a simple [beware when he uses words like that] and systematic approach to Escher-like tilings." So, what we do is iterate the above formula, scale each iteration, and plug it into a second Julia formula. This formula has a value of c selected by the user. If the point converges to this non-circular target set: ~Format- T = [ z: | (z * 15.0)^2 + c | < BAILOUT ] ~Format+ we color it in proportion to the overall iteration count. If not, it will be attracted to infinity and can be colored with the usual outside coloring options. This formula uses a new Fractint programming feature which allows the use of a customized coloring option for the points which converge to the target Julia set, yet allows the other points to be handled by the standard fractal engine with all of its options. With the proper palette and parameters for c, and using the {Inversion} option and a solid outside color from the {Color Parameters}, you can create a solar eclipse, with the corona composed of Julia-shaped flames radiating from the sun's surface. If you question the relevance of these images to Escher, check out his Circle Limit series (especially III and IV). In his own words: "It is to be doubted whether there exist today many ... artists of any kind, to whom the desire has come to penetrate to the depths of infinity.... There is only one possible way of ... obtaining an "infinity" entirely enclosed within a logical boundary line.... The largest ... shapes are now found in the center and the limit of infinite number and infinite smallness is reached at the circumference.... Not one single component ever reaches the edge. For beyond that there is "absolute nothingness." And yet this round world cannot exist without the emptiness around it, not simply because "within" presupposes "without", but also because it is out there in the "nothingness" that the center points of the arcs that go to build up the framework are fixed with such geometric exactitude." ~Format- References: Ernst, B. The Magic Mirror of M. C. Escher, Barnes & Noble, 1994, pp. 102-11. Peitgen, H.-O. and Saupe, D. The Science of Fractal Images, Springer-Verlag, 1988; pp. 185, 187. ~Format+ ; ; ~Topic=L-Systems, Label=HT_LSYS (type=lsystem) These fractals are constructed from line segments using rules specified in drawing commands. Starting with an initial string, the axiom, transformation rules are applied a specified number of times, to produce the final command string which is used to draw the image. Like the type=formula fractals, this type requires a separate data file. A sample file, FRACTINT.L, is included with this distribution. When you select type lsystem, the current lsystem file is read and you are asked for the lsystem name you wish to run. Press at this point if you wish to use a different lsystem file. After selecting an lsystem, you are asked for one parameter - the "order", or number of times to execute all the transformation rules. It is wise to start with small orders, because the size of the substituted command string grows exponentially and it is very easy to exceed your resolution. (Higher orders take longer to generate too.) The command line options "lname=" and "lfile=" can be used to over- ride the default file name and lsystem name. Each L-System entry in the file contains a specification of the angle, the axiom, and the transformation rules. Each item must appear on its own line and each line must be less than 160 characters long. The statement "angle n" sets the angle to 360/n degrees; n must be an integer greater than two and less than fifty. "Axiom string" defines the axiom. Transformation rules are specified as "a=string" and convert the single character 'a' into "string." If more than one rule is specified for a single character all of the strings will be added together. This allows specifying transformations longer than the 160 character limit. Transformation rules may operate on any characters except space, tab or '}'. Any information after a ; (semi-colon) on a line is treated as a comment. Here is a sample lsystem: ~Format- Dragon \{ ; Name of lsystem, \{ indicates start Angle 8 ; Specify the angle increment to 45 degrees Axiom FX ; Starting character string F= ; First rule: Delete 'F' y=+FX--FY+ ; Change 'y' into "+fx--fy+" x=-FX++FY- ; Similar transformation on 'x' } ; final } indicates end The standard drawing commands are: F Draw forward G Move forward (without drawing) + Increase angle - Decrease angle | Try to turn 180 degrees. (If angle is odd, the turn will be the largest possible turn less than 180 degrees.) ~Format+ These commands increment angle by the user specified angle value. They should be used when possible because they are fast. If greater flexibility is needed, use the following commands which keep a completely separate angle pointer which is specified in degrees. ~Format- D Draw forward M Move forward \\nn Increase angle nn degrees /nn Decrease angle nn degrees Color control: Cnn Select color nn nn decrement color by nn Advanced commands: ! Reverse directions (Switch meanings of +, - and \, /) @nnn Multiply line segment size by nnn nnn may be a plain number, or may be preceded by I for inverse, or Q for square root. (e.g. @IQ2 divides size by the square root of 2) [ Push. Stores current angle and position on a stack ] Pop. Return to location of last push ~Format+ Other characters are perfectly legal in command strings. They are ignored for drawing purposes, but can be used to achieve complex translations. The characters '+', '-', '<', '>', '[', ']', '|', '!', '@', '/', '\\', and 'c' are reserved symbols and cannot be redefined. For example, c=f+f and <= , are syntax errors. The integer code produces incorrect results in five known instances, Peano2 with order >= 7, SnowFlake1 with order >=6, and SnowFlake2, SnowFlake3, and SnowflakeColor with order >= 5. If you see strange results, switch to the floating point code. ; ; ; xfractint-20.4.10.orig/dos_help/help.src0000644000000000000000000036104511456055227014763 0ustar ; ; HELP.SRC ; ; ~HdrFile=HELPDEFS.H ~HlpFile=FRACTINT.HLP ~Version=100 ~FormatExclude=8 ; ; ; ~Topic=Main Help Index, Label=HELPMENU ~Label=HELP_INDEX ~Format- { Using Help } { Fractals and the PC } { Introduction } { Distribution of Fractint } { Conditions on Use } { Contacting the Authors } { Getting Started } { The Stone Soup Story } { New Features in 20.4.X } { A Word About the Authors } { Other Fractal Products } { Display Mode Commands } { Color Cycling Commands } { Fractint on Unix } { Palette Editing Commands } { Using Fractint With a Mouse } { Video Adapter Notes } { Summary of Fractal Types } { GIF Save File Format } { Doodads\, Bells\, and Whistles } { Common Problems } { "3D" Images } { Palette Maps } { Bibliography } { Other Programs } { Startup Parameters\, Parameter Files } { Revision History } { Batch Mode } { "Disk-Video" Modes } { Printing Fractint Documentation } ~Format+ ; ; ; ~DocContents { , 0, "New Features in 20.4.X", FF} { , 0, "Introduction", "Conditions on Use", FF} {1. , 0, Fractint Commands, FF} {1.1 , 1, "Getting Started"} {1.2 , 1, "Plotting Commands"} {1.3 , 1, "Zoom box Commands"} {1.4 , 1, "Color Cycling Commands"} {1.5 , 1, "Palette Editing Commands"} {1.6 , 1, "Image Save/Restore Commands"} {1.7 , 1, "Print Command"} {1.8 , 1, "Parameter Save/Restore Commands"} {1.9 , 1, "\"3D\" Commands"} {1.10 , 1, "Interrupting and Resuming"} {1.11 , 1, "Orbits Window"} {1.12 , 1, "View Window"} {1.13 , 1, "Video Mode Function Keys"} {1.14 , 1, "Browse Commands"} {1.15 , 1, "Evolver Commands"} {1.16 , 1, "RDS Commands"} {1.17 , 1, "Hints"} {1.18 , 1, "Fractint on Unix"} {2. , 0, "Fractal Types", FF} {2.1 , 1, "The Mandelbrot Set"} {2.2 , 1, "Julia Sets"} {2.3 , 1, "Julia Toggle Spacebar Commands"} {2.4 , 1, "Inverse Julias"} {2.5 , 1, "Newton domains of attraction"} {2.6 , 1, "Newton"} {2.7 , 1, "Complex Newton"} {2.8 , 1, "Lambda Sets"} {2.9 , 1, "Mandellambda Sets"} {2.10 , 1, "Circle"} {2.11 , 1, "Plasma Clouds"} {2.12 , 1, "Lambdafn"} {2.13 , 1, "Mandelfn"} {2.14 , 1, "Barnsley Mandelbrot/Julia Sets"} {2.15 , 1, "Barnsley IFS Fractals"} {2.16 , 1, "Sierpinski Gasket"} {2.17 , 1, "Quartic Mandelbrot/Julia"} {2.18 , 1, "Distance Estimator"} {2.19 , 1, "Pickover Mandelbrot/Julia Types"} {2.20 , 1, "Pickover Popcorn"} {2.21 , 1, "Peterson Variations"} {2.22 , 1, "Unity"} {2.23 , 1, "Scott Taylor / Lee Skinner Variations"} {2.24 , 1, "Kam Torus"} {2.25 , 1, "Bifurcation"} {2.26 , 1, "Orbit Fractals"} {2.27 , 1, "Lorenz Attractors"} {2.28 , 1, "Rossler Attractors"} {2.29 , 1, "Henon Attractors"} {2.30 , 1, "Pickover Attractors"} {2.31 , 1, "Gingerbreadman"} {2.32 , 1, "Martin Attractors"} {2.33 , 1, "Icon"} {2.34 , 1, "Test"} {2.35 , 1, "Formula"} {2.36 , 1, "Julibrots"} {2.37 , 1, "Diffusion Limited Aggregation"} {2.38 , 1, "Magnetic Fractals"} {2.39 , 1, "L-Systems"} {2.40 , 1, "Lyapunov Fractals"} {2.41 , 1, "fn||fn Fractals"} {2.42 , 1, "Halley"} {2.43 , 1, "Dynamic System"} {2.44 , 1, "Mandelcloud"} {2.45 , 1, "Quaternion"} {2.46 , 1, "HyperComplex"} {2.47 , 1, "Cellular Automata"} {2.48 , 1, "Ant Automaton"} {2.49 , 1, "Phoenix"} {2.50 , 1, "Frothy Basins"} {2.51 , 1, "Volterra-Lotka Fractals"} {2.52 , 1, "Escher-Like Julia Sets"} {2.53 , 1, "Latoocarfian"} ;{2.54 , 1, "Mandelbrot Mix 4"} {2.54 , 1, "DivideBrot5"} {3. , 0, Doodads\, Bells\, and Whistles, FF} {3.1 , 1, "Drawing Method"} {3.2 , 1, "Palette Maps"} {3.3 , 1, "Autokey Mode"} {3.4 , 1, "Distance Estimator Method"} {3.5 , 1, "Inversion"} {3.6 , 1, "Decomposition"} {3.7 , 1, "Logarithmic Palettes and Color Ranges"} {3.8 , 1, "Biomorphs"} {3.9 , 1, "Continuous Potential"} {3.10 , 1, "Starfields"} {3.11 , 1, "Bailout Test"} {3.12 , 1, "Parameter Explorer/Evolver"} {3.13 , 1, "Random Dot Stereograms (RDS)"} {3.14 , 1, "Freestyle mode tutorial"} {4. , 0, "\"3D\" Images", "3D Overview", FF} {4.1 , 1, "3D Mode Selection"} {4.2 , 1, "Select Fill Type Screen"} {4.3 , 1, "Stereo 3D Viewing"} {4.4 , 1, "Rectangular Coordinate Transformation"} {4.5 , 1, "3D Color Parameters"} {4.6 , 1, "Light Source Parameters"} {4.7 , 1, "Spherical Projection"} {4.8 , 1, "3D Overlay Mode"} {4.9 , 1, "Special Note for CGA or Hercules Users"} {4.10 , 1, "Making Terrains"} {4.11 , 1, "Making 3D Slides"} {4.12 , 1, "Interfacing with Ray Tracing Programs"} {5. , 0, Command Line Parameters\, Parameter Files\, Batch Mode, "Introduction to Parameters", FF} {5.1 , 1, "Using the DOS Command Line"} {5.2 , 1, "Setting Defaults (SSTOOLS.INI File)"} {5.3 , 1, "Parameter Files and the <@> Command"} {5.4 , 1, "General Parameter Syntax"} {5.5 , 1, "Startup Parameters"} {5.6 , 1, "Calculation Mode Parameters"} {5.7 , 1, "Fractal Type Parameters"} {5.8 , 1, "Image Calculation Parameters"} {5.9 , 1, "Color Parameters"} {5.10 , 1, "Doodad Parameters"} {5.11 , 1, "File Parameters"} {5.12 , 1, "Video Parameters"} {5.13 , 1, "Sound Parameters"} {5.13.1,2, "Sound Controls"} {5.13.2,2, "Advanced Sound Controls"} {5.13.3,2, "Envelopes"} {5.14 , 1, "Printer Parameters"} {5.15 , 1, "PostScript Parameters"} {5.16 , 1, "PaintJet Parameters"} {5.17 , 1, "Plotter Parameters"} {5.18 , 1, "3D Parameters"} {5.19 , 1, "Batch Mode"} {5.20 , 1, "Browser Parameters"} {5.21 , 1, "Passes Parameters"} {5.22 , 1, "Screen Coordinates Screen"} {5.23 , 1, "Image Coordinates Screen"} {6. , 0, Hardware Support, FF} {6.1 , 1, Notes on Video Modes\, \"Standard\" and Otherwise, "Video Adapter Notes", "EGA", "Tweaked VGA", "Super-VGA", "8514/A", "XGA", "Targa", "Targa+"} {6.2 , 1, "\"Disk-Video\" Modes"} {6.3 , 1, "Customized Video Modes\, FRACTINT.CFG"} {7. , 0, "Common Problems", FF} {8. , 0, "Fractals and the PC", FF} {8.1 , 1, A Little History} {8.1.1, 2, "Before Mandelbrot"} {8.1.2, 2, "Who Is This Guy\, Anyway?"} {8.2 , 1, A Little Code} {8.2.1, 2, "Periodicity Logic"} {8.2.2, 2, "Limitations of Integer Math (And How We Cope)"} {8.2.3, 2, "Arbitrary Precision and Deep Zooming"} {8.2.4, 2, "The Fractint \"Fractal Engine\" Architecture"} {Appendix A, 0, Mathematics of the Fractal Types, "Summary of Fractal Types", "Inside=bof60|bof61|zmag|fmod|period|atan", "Inside=epscross|startrail", "Finite Attractors", "Trig Identities", "Quaternion and Hypercomplex Algebra",FF} {Appendix B, 0, Stone Soup With Pixels: The Authors, "The Stone Soup Story", "A Word About the Authors", "Distribution of Fractint", "Contacting the Authors", FF} {Appendix C, 0, "GIF Save File Format", FF} {Appendix D, 0, "Other Fractal Products", FF} {Appendix E, 0, "Bibliography", FF} {Appendix F, 0, "Other Programs", FF} {Appendix G, 0, "Revision History", "Version 20", "Version 19", "Version 18", "Version 17", "Version 16", "Version 15", "Versions 12 through 14", "Versions 1 through 11", FF} ; ; End of DoContents ; ; ; ~Topic=Using Help ; This topic is online only. Use the following keys in help mode: F1 Go to the main help index. PgDn/PgUp Go to the next/previous page. Backspace Go to the previous topic. Escape Exit help mode. Enter Select (go to) highlighted hot-link. Tab/Shift-Tab Move to the next/previous hot-link. \24 \25 \27 \26 Move to a hot-link. Home/End Move to the first/last hot-link. ; ; ; ~Topic=Printing Fractint Documentation You can generate a text file containing full Fractint documentation by selecting the "Generate FRACTINT.DOC now" hot-link below and pressing Enter, or by using the DOS command "fractint makedoc=filename" ("filename" is the name of the file to be written; it defaults to FRACTINT.DOC.) All information in the documentation file is also available in the online help, so extracting it is a matter of preference - you can print the file (e.g. DOS command "print fractint.doc" or "copy fractint.doc prn") or read it with a text editor. It contains over 200 pages of information, has a table of contents, and is cross-referenced by page number. {=-101 Exit without generating FRACTINT.DOC} {=-100 Generate FRACTINT.DOC now} Fractint's great (and pioneering but no longer unique) online help and integrated documentation file software was written by Ethan Nagel. ; ; ; ~Topic=New Features in 20.4.X This is a developer's "incremental" release. These incremental releases typically have a short life and are updated frequently. They may have bug fixes, and thus be more stable, but they may also have new features which very likely have new bugs. Version 20.4.10 is an update of Fractint 20.0 based on the developer's version 20.4.9. New features include: Patch 10 to Version 20.4.0\ Fixed WinFract resetting palette when parameters are changed with the , , , or screens. Fixed usage of shift and control keys in Xfractint. Added sanity checks in Xfractint parser functions. Fixed long standing bug in Xfractint that occurred when a PAR was invoked from the command line. Increased the WinFract maximum image size to 4096x4096 pixels. Your mileage may vary depending upon how much memory Windows can allocate. But remember that above 2048x2048 passes=1 is forced. Fixed bug in the cvtcentermagbf() routine that was introduced some time prior to version 19.6. This fixes the problem that was occurring when rotating ap math images by 90 degrees. Fixed buffer overflow in Xfractint that occurred when changing directories. Patch 9 to Version 20.4.0\ Added new Fractal type {DivideBrot5} by Jim Muth. This Fractal type has AP math support. Note that image skewing and inversion are not supported by the AP math routines. See {Arbitrary Precision and Deep Zooming} for other features not supported. Fixed several obscure bugs in the AP math. Added MakeFile changes from Michal Januszewski (xfractint maintainer in Gentoo Linux) to increase distribution compatibility. Patch 8 to Version 20.4.0\ Fixed a bug in the virtual video code where the screen width was being reduced when going from a text screen back to the graphics screen. Revised logic that calculates the maximum X and Y resolutions possible with a given initial virtual screen size. Because of the variable type being used, the maximum size is 32767 even if sufficient video memory is available to support higher resolutions. Added back in code that forces passes=1 when either the X or Y resolution is greater than 2048. This was inadvertently removed with patch 5, and is needed because other passes= options are hard coded to use arrays of this size. Xfractint changes:\ Jean-Pierre Demailly provided extensive changes to eliminate the use of ncurses with Xfractint and also updated the MakeFile. Included a patch from Andrew Church and the people at Gentoo that fixes a filename buffer overflow that affected the help compiler. Also included their xioerror patch. Fixed a seg fault in Xfractint caused by not unstacking all the screens before exiting. Removed the shell-to-DOS option in Xfractint. Patch 7 to Version 20.4.0\ Added feature to write the base map name to the first line of the file when a map file is saved and the only change has been a rotation of the palette. The base map name is then read in and used as the current map name when the new map file is restored. The recordcolors=comment command line option has been modified to not create a comment line in PARs. Two colors= entries are now created with the first one in the format colors=@fname.map and the second in the format colors=000<24>0n0...010. When a PAR entry is read, the first colors= sets the map name, and the second colors= effectively rotates the colors. Updated the Xfractint Makefile to install using sudo instead of as root. Patch 6 to Version 20.4.0\ Added Per Image Settings to the {formula} parser. When initially selected from the fractal type formula screen, the symmetry and any per image settings are enforced. The per image settings will be saved to PARs and GIFs, and can be changed from the appropriate screen. The possible values for per image settings are the same as the parameters that appear in PAR files, with the exception of 'params='. Params can't be set in the per image settings section, because they get set to zero when the formula is parsed. Patch 5 to Version 20.4.0\ Tim's changes (5/29/2006)\ Moved version 20.0 change history to revision history to make room in help.src. Changed help screen to show just two main authors - decided better not to show inactive authors. Removed commented out complex macros in fractals.c. Added commented out bf version of Mandelbrot in fractalp.c. Giving thought to offerring bfmath as an option to bnmath, but if we fix the current bignum problems, this may be moot. Added interation to screen. Jonathan's changes\ Fixed the logic for calculating when to switch from using a grid to using the on-the-fly calculation of an image's pixels. The logic was not handling disk video images sized above 2048x2048 with floating point enabled. Added the savename to the disk video status screen. Fixed bug in the compare routine of bn_math that fixes long standing problem with periodicity checking in deep zoomed images. Resurrected the documentation for ap_math that was at the beginning of bignum.c. Added code to force periodicity=0 when the inside=atan feature is used. Patch 4 to Version 20.4.0\ Added minor changes so that Xfractint would compile under Cygwin. Added lines to the Xfractint makefile (commented out) for compiling in a 64-bit environment. Fixed Xfractint so that built in calls to a different map file would work. Modified the logic for calculating when to switch from using a grid to using the on-the-fly calculation of an image's pixels. This affects how large an image can be made when using integer math. The switch is now made when (xdots + ydots) * sizeof(long) > 32768. Pulled the WinFract version 18.21 source into the CVS repository source tree. This code now runs but still has many many bugs. Patch 3 to Version 20.4.0\ Started the cleanup of the docs. Cleaned up the map directory. Fixed the Xfractint Makefile so that install would run. Added an uninstall. Fixed Xfractint so that it can be run from an arbitrary directory and still use the directory settings in sstools.ini. Patch 2 to Version 20.4.0\ Fixed the display coordinates so they won't change, after an image had been zoomed, when the maintain screen coordinates parameter is set to yes. Fixed the corner parameter screen and image parameter screen so that rotating and/or skewing now doesn't get reset when changes are made. Patch 1 to Version 20.4.0\ Added the mathtolerance and orbit_delay parameters to values written to PARs and GIFs. Fixed how a mathtolerance parameter with a slash and a second number, but no first number is read in. The slash was being interpreted as a double. Stole the

key for use by passes options. If you are brave enough to try it, printing is still available using . Put periodicity and orbit delay on the new

screen. There are currently two drawing modes available for the passes=orbits option. The rect(angle) method plots the orbits in a rectangle that can be zoomed, rotated, and skewed using the corner parameter screen, and the straight line method plots the orbits between two points specified on the corner parameter screen. The orbit interval parameter plots every nth orbit. The maintain screen coordinates parameter lets you zoom into an image changing the coordinates of the line or rectangle used to generate the image, but keeps the display coordinates, set on the screen, the same. Updated the docs for center-mag and corners because center-mag is now the default. Restructured the source to make it easier to maintain. Version 20.4.0\ Incremented the version number to accommodate backwards compatibility for the mandel based per-pixel routines that were not setting the Y variable. Added a passes=o option that draws an image by plotting the orbits of the escape time fractals and leaving them on the screen. This technique uses the same coordinates to draw an image as the other passes options, sets "passes=1" and no symmetry, and then plots the orbits for each pixel. See {Drawing Method}. Xfractint fixes: Fixed the newton and newtbasin types in Xfractint so they would work without using the FPU=387 option. Fixed the Xfractint mandelbrot code in calmanfp.c so that the image generated matched the one produced by the StandardFractal() routine. Fixed the outside=sum option when used with the mandel fractal type. Fixed the command line option -geometry, which broke at 20.2.05. Patch 2 to Version 20.3.0\ Fixed the inability to reload a PAR created from an arbitrary precision fractal with a large magnification. Fixed the problem with a left mouse click not bringing up the zoom box after an image is completed. Incorporated Gerald Dobiasovsky's fix for the julibrot type when used with quat and hypercomplex. Fixed the display of subdirectories in Xfractint. Replaced control characters in realdos.c with the equivalent ascii values to quiet complaints by CVS. Patch 1\ Fixed the float bailout for the lambdafn fractal type when the EXP function is used so the float and integer images match. Jan Andres contributed Xfractint fixes that allow compiling with newer versions of gcc because varargs.h is no longer supported. Enabled the use of the long double type on Solaris. Moved the getwd() macro definition in prompts1.c after the #include lines, to avoid the mess that happens when the prototype for getwd() is included but it's already defined as a macro. Added some Solaris-specific comments to the Makefile. Fixed the sound in Xfractint so the beep turns off now. Changed lsys.c to use inline1 instead of the reserved word inline. Version 20.3.0\ Incremented the version number to accommodate backwards compatibility for the inside=atan and outside=atan options. Fixed inside=atan and outside=atan to use the full color palette instead of limiting to 180 colors. Added Charlie Chernohorsky's virtual screen zoombox fix. See {View Window}. Added Gerald Dobiasovsky's fixes for the demo key files needed because of menu prompt changes and pan/zoom size changes. Fixed evolver parameter entry. Fixed hypercomplex fractal type to turn off symmetry when a cj parameter is used. Fixed the plasma type to show the value of the parameter that is actually used in the image generation. Fixed the plasma type so that a parameter file uses the colors included in the parameter entry instead of the default colors. Revised the plasma type prompt to reflect the values that can actually be used. Increased the Lsystem line length from 160 characters to 255 characters. Fixed the browser so that it recognized the fractal type stored in images. Fixed the Xfractint FPUcplxdiv and FPUcplxlog routines in fpu087.c to match the Fractint assembler code. Modified the Xfractint resume code to remove the Xfractint specific sections since they are no longer needed (gcc macros match MSC macros). Patch 5\ Made changes to allow Xfractint to find files that use upper case letters. Fixed a problem with the Cellular type that prevented entering an initial row of greater than 32767 from working. Added a message about not being able to resume after interrupting prior to rows being displayed on screen. Fixed an evolver bug which caused setting evolver parameters to turn evolving on, even though evolving was actually turned off. Added Charlie Chernohorsky's truecolor speed up and his implementation of virtual screen sizes for the VESA modes (dotmode=28). This feature does not work consistently between different video cards, so it may be turned off by using the startup command "virtual=n". Use the screen to set the desired virtual screen size. See {View Window}. Please remember that if either X or Y is greater than 2048, solid guessing is turned off. This is for multiple reasons, so it is likely it will NOT get fixed soon. There is also a problem with the colorbars that appear when saving an image leaving bits of corruption on the screen. This occurs in all the VESA truecolor modes. Added Charlie to the scrolling list of contributors. Added Charlie's fix for the l-system type which occurred when a push-pop combination was on two different lines. Fixed the PAGE-UP/PAGE-DN zoombox in Xfractint so that it now appears on the screen. Fixed ranges= in Xfractint so GIFs save correctly and program doesn't end abruptly. Patch 4\ Modified the Xfractint makefile and source files to allow compiling without an assembler. Patch 3\ This patch ran the Xfractint code through -Wall to clear up most of the warnings. Updated the Xfractint man page. Turned on compiler optimizations. Fixed the documentation for the Latoocarfian fractal type thanks to comments by Pierre Desjardins on the Fractint Bug List. Patch 2\ This patch adds the assembly language version of the mandelbrot code to Xfractint. To use it, it is necessary to place the command line switch fpu=387 in your sstools.ini file. The NASM assembler was used, but if you don't have it available, not to worry, the object file is included. Modified the Xfractint C mandelbrot code to match the assembly version. Patch 1\ Made a small change to the quickcalc logic used to recalculate the inside pixels only when the iteration count is increased with a completed image. Interrupting and resuming the calculation was leaving extra pixels on the screen. Patched the Xfractint fractint.h file to match the DOS version. Fixed an Xfractint problem with color depths greater than 16 bits per pixel. Version 20.2.0\ Incremented the version number to accommodate backwards compatibility for the logmap option. Modified the logmap routine so that the color with index # 2 would be displayed. Added a logmode=auto command line option that causes the logmap to adjust automatically when zooming. Changing almost anything will turn this feature off. It is best set using the screen prompt. Edited the help docs to document the move of the development area from Compuserve to the web. Patch 13\ Added parameters p4 and p5 to the evolver. This required splitting the tweak central screen into two pages. Fixed an evolver bug that was causing the evolver to not exit cleanly. Changed the compile options on evolve.c to eliminate aliasing, which started to cause problems with this patch. Patch 12\ Fixed a problem with a finished image not redrawing if the maxiter was increased and another parameter was changed. Added checks for p3, p4, and p5 to the browser for determining similar images. Xfractint fixes: Fixed the command line -disk segmentation fault. Fixed the Shell to Linux/Unix segmentation fault and the displayed prompt. Fixed the bug causing colors= data to be incorrect when in a truecolor mode. Removed or commented out extra lines of code and some experimental routines. Some of this code was stealing key strokes. Changed the prompt for getting to the second screen. Patch 11\ Fixed a bug that caused a panned image to miss part of a line when the image was panned while the first row was being generated. Adjusted the time for keyboard checks when the showdot feature is used. Now the iterations stop much quicker when a key is pressed. Fixed a problem with the float-only version that appeared when an incomplete image was saved and restarted in the standard version. Fixed a problem in Xfractint pointed out by Ken on the Fractint bug list. Patch 10\ Took out a sanity check in the VESA detection routines that certain graphics cards don't pass, but work fine anyway. Patch 9\ Fixed evolver bug that occurred when some formula functions were evolved and others were not being evolved. Fixed a bug in the float-only version which truncated the image coordinates when saved to a PAR. Patch 8\ Added truecolor support to Fractint thanks to Bert Tyler. While in a truecolor mode, the following features are disabled/changed:\ Color Cycling\ Palette Editor brings up the contents of the MAP directory\ Saving the image still only produces a 256 color GIF\ Removed Bert's truecolor test code used with the test fractal type. Patch 7\ Fixed a bug which caused the float only version to omit the name of the formula/lsystem/ifs in saved GIFs. Fixed the julia_inverse fractal type broken with the first patch to version 20.0. Incorporated Gerald Dobiasovsky's fix to make the background= command work. Added truecolor support to Xfractint thanks to Rich Thomson and Jean-Pierre Demailly. Additional Xfractint fixes include the mandelcloud type and outside=atan when used with type=mandel. Patch 6\ Once again fixed the assignment of hotkeys to video modes so that the fractint.cfg file is no longer corrupted. This problem was caused by the section of code dealing with the true-color video modes. Patch 5\ Updated the disk video help docs. The limit of disk video has been 32767x32767 since version 20.0. Fixed the tab and evolver screens so that not using formula parameters consecutively starting with p1 now displays the parameters properly. The p4 and p5 parameters have still not been added to the evolver. Setting directories in sstools.ini can now be done relative to the current directory. For example: .\\frm\\fract200.frm Patch 4\ Modified the per image startup code for the circle type to turn off the inside= option if startrail is used. Since the inside=startrail option was locking up Fractint, no backwards compatibility is available. Made changes to the code for how sizeof() was being used. This fixes a long standing problem with the cellular type in Xfractint. Modified the hard coded reading of GIF files in Xfractint to eliminate the error message received after patch 3 changed the fractal_info structure. Fixed a problem with the Xfractint parameter, formula, and lsystem screens. Patch 3\ Fixed the incremental redraw so that interrupting the redraw no longer sets passes=1. Added a command line option, nobof=yes, which allows the inside=bof60 and bof61 options to function like the rest of the inside options. With nobof=yes the images in "The Beauty of Fractals" are no longer reproduced. Increased the usable bailout values when using arbitrary precision math. This is the best I can do with my minimal understanding of the ap-math routines. If you are seeing extraneous pixels on your ap-math images when you use a high bailout, lower the bailout until they go away. Made a change to the tab display routine to correct a problem with displaying parameters when returning from the F6 and control-tab screens. Patch 2\ Backed out the changes to the savegraphics() and restoregraphics() routines. Patch 1\ Fixed the display screen so the video memory doesn't get overwritten. This clears up the problem with extraneous dots with some fractal types. It should be possible to remove the textsafe=save from your sstools.ini file. Added Iain Stirling to the scrolling credits screen for his contribution of the inside=fmod and outside=fmod options. Reworded the error message received when more memory is requested than is available on your disk drive. The background= parameter, for 3D TGA files, is now saved to a PAR entry. Fixed the error message that appears when a parsing error occurs on startup. Cleaned up the savegraphics() and restoregraphics() routines. This should make them faster. Version 20.1.0\ Incremented the version number to accommodate backwards compatibility for the inside=fmod option. Fixed the assignment of hotkeys to video modes so that the fractint.cfg file is no longer corrupted. Made the showdot= feature reset with if it is entered using the screen. Added a check for the video size before invoking the palette editor. Too small a size would crash Fractint. Fixed an extraseg conflict which occurred with arbitrary precision when the key was used with various screens open (x,y,b). This conflict also occurred when loading an ap math image at the video selection screen. Cleaned up some of the ap math initialization code. Fixed an obscure bug that left memory allocated when an unfinished image was being reloaded, but a video mode was not selected (escape was pressed). Added outside=fmod option. This is an extension of the inside=fmod option. The magnitude used for the comparison is now based on the same calculation as is used for the bailout test. This feature was contributed by Iain Stirling. There is a problem with the mandel fractal type when outside=fmod is used with inside=bof6x and bailoutest=real, imag, or manr. This is likely due to changes made in the code so that bof images could be reproduced. Select a different fractal type that produces the default mandel image to explore using these parameters. Added outside=tdis option. This colors the pixels according to the total distance traveled by the orbit. This feature was suggested by Steve Robinson on the Fractint Wish List. Modified the inside and outside prompts on the screen. They are now split into two separate prompts. One for entering a color number and the other for changing the option. The left and right arrow keys can now be used to change the inside and outside options. Fixed a bug that was causing a crash when mathtolerance= was used and fractal types ifs, ifs3d, or lsystem were selected. Increased the minimum stack requirement for passes=s (SOI) to eliminate crashes when the tab key was pressed. Patch 15\ Added a prompt for the periodicity= option to the Extended Options screen. Fixed another prompt problem with the stereogram prompt screen. Put back in the evolver grid size limit based on screen resolution. Fixed an evolver save problem when a zoom box was present just prior to the save. Note that the center image cannot be recreated once the zoom box has been activated. This is not a problem if you are working from a saved image, just restore it. Modified the routine that reports a view window that is too large so that along with the full screen being used, the X and Y dimensions on the screen reflect the full screen dimensions. The screen can now be used to set the resolution of disk video modes. The limit is 32767x32767. First select a disk video mode using . Then on the screen enter both an X and a Y value. If you go back to the screen to see if the entry has been modified (it hasn't), you will get strange results if you don't select a video mode. Patch 14\ Fixed the generation of random numbers used by the evolver subimages. Fixed the bug causing completed evolver images to regenerate when restored. Patch 13\ Added parameters p4 and p5 to the formula parser. Fixed the symmetry for cases where XAXIS_NOREAL and XAXIS_NOIMAG are used with the formula parser and multiple parameters are used. Each parameter is now checked. Patch 12\ Fixed a 3D error introduced with patch 11. Fixed the stereogram screen prompts to prevent out of bounds array accesses. Patch 11\ Fixed an off by one error in the Xfractint type=julia code. Fixed the case where the second image would not finish generating when the 3D parameter Stereo=photo or stereo pair was used with an orbit type such as Lorenz. Patch 10\ Fixed some user interface prompts that were wrong in Xfractint. Merged the Xfractint version system with Fractint's. Thanks to Scott Boyd for these changes. Patch 9\ Fixed a bug that occurred when maxhistory=0 was used. Fixed a bug that occurred when ismand was used in a formula and ctrl was pressed. Patch 8\ Fixed a bug causing a lock up with lsystem and ifs fractal types when using a disk video mode with an X or Y resolution greater than 2048. Patch 7\ Updated Xfractint, copyright notice. Patch 6\ Fixed fractint.cfg problems with extra commas or long lines. This allows the output of makefcfg from certain video boards to be used without editing. Added center, magxmag, and rotskew constants to parser. See {=@PREDEFCENTERMAG Center-Mag Predefined Variables} Patch 5\ Added new command truemode=iter, which is used to switch the ouput to the truecolor Targa file to the number of iterates for each pixel. Made selecting the evolver feature turn off truecolor=yes. Each subimage was being generated as a separate blank Targa file. Patch 4\ Fixed the type=test bug. Patch 3\ Fixed a bug in the pentium mandelbrot code that affected periodicity checking. Fixed a problem with skewed zoom boxes leaving dots on the screen. This also fixed browser boxes with the same problem. Fixed the zoom box so it is visible in 2-color modes. Patch 2\ Fixed a bug in the formula parser. Patch 1\ Fixed the 2 and 16 color disk-video modes. Using truecolor=yes now results in writing a fractxxx.tga file instead of iterates.tga. This is not the same thing, so if somebody wants the output of the iterates.tga file, let us know. Fixed the 3D targa modes. ~OnlineFF For information on previous versions, see { Revision History }. ; ; ; ~Topic=Introduction FRACTINT plots and manipulates images of "objects" -- actually, sets of mathematical points -- that have fractal dimension. See {"Fractals and the PC"} for some historical and mathematical background on fractal geometry, a discipline named and popularized by mathematician Benoit Mandelbrot. For now, these sets of points have three important properties: 1) They are generated by relatively simple calculations repeated over and over, feeding the results of each step back into the next -- something computers can do very rapidly. 2) They are, quite literally, infinitely complex: they reveal more and more detail without limit as you plot smaller and smaller areas. Fractint lets you "zoom in" by positioning a small box and hitting to redraw the boxed area at full-screen size; its maximum linear "magnification" is over a trillionfold. 3) They can be astonishingly beautiful, especially using PC color displays' ability to assign colors to selected points, and (with VGA displays or EGA in 640x350x16 mode) to "animate" the images by quickly shifting those color assignments. ~OnlineFF For a demonstration of some of Fractint's features, run the demonstration file included with this release (DEMO.BAT) by typing "demo" at the DOS prompt. You can stop the demonstration at any time by pressing . The name FRACTINT was chosen because the program generates many of its images using INTeger math, rather than the floating point calculations used by most such programs. That means that you don't need a math co- processor chip (aka floating point unit or FPU), although for a few fractal types where floating point math is faster, the program recognizes and automatically uses an 80x87 chip if it's present. It's even faster on systems using Intel's 80386 and 80486 microprocessors, where the integer math can be executed in their native 32-bit mode. Fractint works with many adapters and graphics modes from CGA to the 1024x768, 256-color XGA mode. Even "larger" images, up to 32767x32767x256, can be plotted to expanded memory, extended memory, or disk: this bypasses the screen and allows you to create images with higher resolution than your current display can handle, and to run in "background" under multi- tasking control programs such as DESQview and Windows 3. ~OnlineFF Fractint is an experiment in collaboration. Many volunteers have joined Bert Tyler, the program's first author, in improving successive versions. Through electronic mail messages, CompuServe's GO GRAPHICS forums, new versions are hacked out and debugged a little at a time. Fractint was born fast, and none of us has seen any other fractal plotter close to the present version for speed, versatility, and all-around wonderfulness. (If you have, tell us so we can steal somebody else's ideas instead of each other's.) See {The Stone Soup Story} and {A Word About the Authors} for information about the authors, and see {Contacting the Authors} for how to contribute your own ideas and code. ; ; ; ~Topic=Conditions on Use Fractint is freeware. The copyright is retained by the Stone Soup Group. Fractint may be freely copied and distributed in unmodified form but may not be sold. (A nominal distribution fee may be charged for media and handling by freeware and shareware distributors.) Fractint may be used personally or in a business - if you can do your job better by using Fractint, or using images from it, that's great! It may not be given away with commercial products without explicit permission from the Stone Soup Group. There is no warranty of Fractint's suitability for any purpose, nor any acceptance of liability, express or implied. **********************************************************************\ * Contribution policy: Don't want money. Got money. Want admiration. *\ ********************************************************************** ~OnlineFF Source code for Fractint is also freely available - see {Distribution of Fractint}. See the FRACTSRC.DOC file included with the source for conditions on use. (In most cases we just want credit.) ; ; ; ~Topic=Getting Started To start the program, enter FRACTINT at the DOS prompt. The program displays an initial "credits" screen. If Fractint doesn't start properly, please see {Common Problems}. Hitting gets you from the initial screen to the main menu. You can select options from the menu by moving the highlight with the cursor arrow keys ~Doc- (\24 \25 \27 \26) ~Doc+ and pressing , or you can enter commands directly. As soon as you select a video mode, Fractint begins drawing an image - the "full" Mandelbrot set if you haven't selected another fractal type. For a quick start, after starting Fractint try one of the following:\ If you have MCGA, VGA, or better: \ If you have EGA: \ If you have CGA: \ Otherwise, monochrome: After the initial Mandelbrot image has been displayed, try zooming into it (see {Zoom Box Commands}) and color cycling (see {Color Cycling Commands}). Once you're comfortable with these basics, start exploring other functions from the main menu. Help is available from the menu and at most other points in Fractint by pressing the key. AT ANY TIME, you can hit ~Doc- one of the keys described in {Display Mode Commands} ~Doc+,Online- a command key ~Online+ to select a function. You do not need to wait for a calculation to finish, nor do you have to return to the main menu. When entering commands, note that for the "typewriter" keys, upper and lower case are equivalent, e.g. and have the same result. Many commands and parameters can be passed to FRACTINT as command-line arguments or read from a configuration file; ~Doc- see {Startup Parameters\, Parameter Files} for details. ~Doc+,Online- see "Command Line Parameters, Parameter Files, Batch Mode" for details. ~Online+ ; ; ; ~Topic=Display Mode Commands ; ; This topic is online only ~Format- { Summary of Commands } { Plotting Commands} { Zoom Box Commands } { Image Save/Restore Commands } { Print Command } { Parameter Save/Restore Commands } { Interrupting and Resuming } { Orbits Window } { View Window } { \"3D\" Commands } { Video Mode Function Keys } { Browse Commands } { Evolver Commands } { RDS Commands } { Hints } ; ; ; ~Topic=Summary of Commands, Label=HELPMAIN ; This topic is online only ~Doc- Hit any of these keys at the menu or while drawing or viewing a fractal. Commands marked with an '*' are also available at the credits screen. ~Format- {Plotting Commands} * Delete,F2,F3,.. Select a Video Mode and draw (or redraw) current fractal * F1 HELP! (Enter help mode) Esc or m Go to main menu h Redraw previous screen (you can 'back out' recursively) Ctrl-H Redraw next screen in history circular buffer Tab Display information about the current fractal image * t Select a new fractal type and parameters * x Set a number of options and doodads * y Set extended options and doodads * z Set fractal type-specific parameters p Set passes options c or + or - Enter Color-Cycling Mode (see {=HELPCYCLING Color Cycling Commands}) e Enter Palette-Editing Mode (see {=HELPXHAIR Palette Editing Commands}) Spacebar Mandelbrot/Julia Set toggle. Enter Continue an interrupted calculation (e.g. after a save) * f toggle the floating-point algorithm option ON or OFF * i Set parameters for 3D fractal types * Insert Restart Fractint * u List of contributors a Convert the current image into a fractal 'starfield' Ctrl-A Turn on screen-eating ant automaton Ctrl-S Convert current image to a Random Dot Stereogram (RDS) o toggles 'orbits' option on and off during image generation * d Shell to DOS (type 'exit' at the DOS prompt to return) Ctrl-X Flip the current image along the screen's X-axis Ctrl-Y Flip the current image along the screen's Y-axis Ctrl-Z Flip the current image along the screen's Origin {Image Save/Restore Commands} s Save the current screen image to disk * r Restore a saved (or .GIF) image ('3' or 'o' for 3-D) {Orbits Window} o Turns on Orbits Window mode after image generation ctrl-o Turns on Orbits Window mode {View Window} * v Set view window parameters (reduction, aspect ratio) {Print Command} ctrl-p Print the screen (command-line options set printer type) {Parameter Save/Restore Commands} b Save commands describing the current image in a file (writes an entry to be used with @ command) * @ or 2 Run a set of commands (in command line format) from a file g Give a startup parameter: {Summary of all Parameters} {\"3D\" Commands} * 3 3D transform a saved (or .GIF) image # (shift-3) same as 3, but overlay the current image {Zoom Box Commands} PageUp When no Zoom Box is active, bring one up When active already, shrink it PageDown Expand the Zoom Box Expanding past the screen size cancels the Zoom Box \24 \25 \27 \26 Pan (Move) the Zoom Box Ctrl- \24 \25 \27 \26 Fast-Pan the Zoom Box (may require an enhanced keyboard) Enter Redraw the Screen or area inside the Zoom Box Ctrl-Enter 'Zoom-out' - expands the image so that your current image is positioned inside the current zoom-box location. Ctrl-Pad+/Pad- Rotate the Zoom Box Ctrl-PgUp/PgDn Change Zoom Box vertical size (change its aspect ratio) Ctrl-Home/End Change Zoom Box shape Ctrl-Ins/Del Change Zoom Box color {Interrupting and Resuming} {Video Mode Function Keys} {Browse Commands} L(ook) Enter Browsing Mode {Evolver Commands} Ctrl-E Bring up {=HELPEVOL explorer/evolver} control screen Alt-1 ... Alt-7 Enter evolver mode with selected level of mutation: Alt-1 = low level, Alt-7 = maximum. (dont use the keypad, just the 'top row' numbers) When in evolve mode then just plain 1..7 also work {RDS Commands} Ctrl-S Access RDS parameter screen ~Doc+ ; ; ; ~Topic=Plotting Commands Function keys & various combinations are used to select a video mode and redraw the screen. For a quick start try one of the following:\ If you have MCGA, VGA, or better: \ If you have EGA: \ If you have CGA: \ Otherwise, monochrome: \ \ Display a help screen. The function keys available in help mode are displayed at the bottom of the help screen. or \ Return from a displayed image to the main menu. \ From the main menu, is used to exit from Fractint. \ Same as choosing "select video mode" from the main menu. Goes to the "select video mode" screen. See {Video Mode Function Keys}. \ Redraw the previous image in the circular history buffer, revisiting fractals you previously generated this session in reverse order. Fractint saves the last ten images worth of information including fractal type, coordinates, colors, and all options. Image information is saved only when some item changes. After ten images the circular buffer wraps around and earlier information is overwritten. You can set image capacity of the history feature using the maxhistory= command. About 1200 bytes of memory is required for each image slot. \ Redraw the next image in the circular history buffer. Use this to return to images you passed by when using . \ Display the current fractal type, parameters, video mode, screen or (if displayed) zoom-box coordinates, maximum iteration count, and other information useful in keeping track of where you are. The Tab function is non-destructive - if you press it while in the midst of generating an image, you will continue generating it when you return. The Tab function tells you if your image is still being generated or has finished - a handy feature for those overnight, 1024x768 resolution fractal images. If the image is incomplete, it also tells you whether it can be interrupted and resumed. (Any function other than and counts as an "interrupt".) The Tab screen also includes a pixel-counting function, which will count the number of pixels colored in the inside color. This gives an estimate of the area of the fractal. Note that the inside color must be different from the outside color(s) for this to work; inside=0 is a good choice. \ Select a fractal type. Move the cursor to your choice (or type the first few letters of its name) and hit . Next you will be prompted for any parameters used by the selected type - hit for the defaults. See {Fractal Types} for a list of supported types. \ Toggles the use of floating-point algorithms (see {"Limitations of Integer Math (And How We Cope)"}). Whether floating point is in use is shown on the status screen. The floating point option can also be turned on and off using the "X" options screen. If you have a non-Intel floating point chip which supports the full 387 instruction set, see the "FPU=" command in {Startup Parameters} to get the most out of your chip. \ Select a number of eXtended options. Brings up a full-screen menu of options, any of which you can change at will. These options are:\ "passes=" - see {Drawing Method}\ Floating point toggle - see key description above\ "maxiter=" - see {Image Calculation Parameters}\ "inside=" and "outside=" - see {Color Parameters}\ "savename=" filename - see {File Parameters}\ "overwrite=" option - see {File Parameters}\ "sound=" option - see {Sound Parameters}\ "logmap=" - see {Logarithmic Palettes and Color Ranges}\ "biomorph=" - see {Biomorphs}\ "decomp=" - see {Decomposition}\ "fillcolor=" - see {Drawing Method}\ \ More options which we couldn't fit under the command:\ "finattract=" - see {Finite Attractors}\ "potential=" parameters - see {Continuous Potential}\ "invert=" parameters - see {Inversion}\ "distest=" parameters - see {Distance Estimator Method}\ "cyclerange=" - see {Color Cycling Commands}\

\ Options that apply to the Passes feature:\ "periodicity=" - see {Periodicity Logic}\ "orbitdelay=" - see {Passes Parameters}\ "orbitinterval=" - see {Passes Parameters}\ "screencoords=" - see {Passes Parameters}\ "orbitdrawmode=" - see {Passes Parameters}\ \ Modify the parameters specific to the currently selected fractal type. This command lets you modify the parameters which are requested when you select a new fractal type with the command, without having to repeat that selection. You can enter "e" or "p" in column one of the input fields to get the numbers e and pi (2.71828... and 3.14159...).\ From the fractal parameters screen, you can press to bring up a sub parameter screen for the coordinates of the image's corners. With selected fractal types, allows you to change the {Bailout Test}. ; With the IFS fractal type, brings up the IFS editor (see ; {=HT_IFS Barnsley IFS Fractals}). <+> or <->\ Switch to color-cycling mode and begin cycling the palette by shifting each color to the next "contour." See {Color Cycling Commands}.\ \ Switch to color-cycling mode but do not start cycling. The normally black "overscan" border of the screen changes to white. See {Color Cycling Commands}. \ Enter Palette-Editing Mode. See {Palette Editing Commands}. \ Toggle between Mandelbrot set images and their corresponding Julia-set images. Read the notes in {=HT_JULIA Fractal Types, Julia Sets} before trying this option if you want to see anything interesting. \ Toggle between Julia escape time fractal and the Inverse Julia orbit fractal. See {=HT_INVERSE Inverse Julias} \ Enter is used to resume calculation after a pause. It is only necessary to do this when there is a message on the screen waiting to be acknowledged, such as the message shown after you save an image to disk. \ Modify 3D transformation parameters used with 3D fractal types such as "Lorenz3D" and 3D "IFS" definitions, including the selection of {=HELP3DGLASSES "funny glasses"} red/blue 3D. \ Convert the current image into a fractal 'starfield'. See {Starfields}. \ Unleash an image-eating ant automaton on current image. See {Ant Automaton}. (or )\ Convert the current image into a Random Dot Stereogram (RDS). See {Random Dot Stereograms (RDS)}. (the letter, not the number)\ If pressed while an image is being generated, toggles the display of intermediate results -- the "orbits" Fractint uses as it calculates values for each point. Slows the display a bit, but shows you how clever the program is behind the scenes. (See "A Little Code" in {"Fractals and the PC"}.) \ Shell to DOS. Return to Fractint by entering "exit" at a DOS prompt. (Not Xfractint) \ Restart at the "credits" screen and reset most variables to their initial state. Variables which are not reset are: savename, lightname, video, startup filename. \ Display the "credits" screen. \ Enter Browsing Mode. See {Browse Commands}. \ Enter Explorer/Evolver Mode. See {Evolver Commands}. ; ; ; ~Topic=Zoom Box Commands, Label=HELPZOOM Zoom Box functions can be invoked while an image is being generated or when it has been completely drawn. Zooming is supported for most fractal types, but not all. The general approach to using the zoom box is: Frame an area using the keys described below, then to expand what's in the frame to fill the whole screen (zoom in); or to shrink the current image into the framed area (zoom out). With a mouse, double-click the left button to zoom in, double click the right button to zoom out. , \ Use to initially bring up the zoom box. It starts at full screen size. Subsequent use of these keys makes the zoom box smaller or larger. Using to enlarge the zoom box when it is already at maximum size removes the zoom box from the display. Moving the mouse away from you or toward you while holding the left button down performs the same functions as these keys. Using the cursor "arrow" keys ~Doc- (\24 \25 \27 \26) ~Doc+ or moving the mouse without holding any buttons down, moves the zoom box. Holding while pressing cursor "arrow" keys moves the box 5 times faster. (This only works with enhanced keyboards.) Panning: If you move a fullsize zoombox and don't change anything else before performing the zoom, Fractint just moves what's already on the screen and then fills in the new edges, to reduce drawing time. This feature applies to most fractal types but not all. A side effect is that while an image is incomplete, a full size zoom box moves in steps larger than one pixel. Fractint keeps the box on multiple pixel boundaries, to make panning possible. As a multi-pass (e.g. solid guessing) image approaches completion, the zoom box can move in smaller increments. In addition to resizing the zoom box and moving it around, you can do some rather warped things with it. If you're a new Fractint user, we recommend skipping the rest of the zoom box functions for now and coming back to them when you're comfortable with the basic zoom box functions. , \ Holding and pressing the numeric keypad's + or - keys rotates the zoom box. Moving the mouse left or right while holding the right button down performs the same function. , \ These commands change the zoom box's "aspect ratio", stretching or shrinking it vertically. Moving the mouse away from you or toward you while holding both buttons (or the middle button on a 3-button mouse) down performs the same function. There are no commands to directly stretch or shrink the zoom box horizontally - the same effect can be achieved by combining vertical stretching and resizing. , \ These commands "skew" the zoom box, moving the top and bottom edges in opposite directions. Moving the mouse left or right while holding both buttons (or the middle button on a 3-button mouse) down performs the same function. There are no commands to directly skew the left and right edges - the same effect can be achieved by using these functions combined with rotation. , \ These commands change the zoom box color. This is useful when you're having trouble seeing the zoom box against the colors around it. Moving the mouse away from you or toward you while holding the right button down performs the same function. You may find it difficult to figure out what combination of size, position rotation, stretch, and skew to use to get a particular result. (We do.)\ A good way to get a feel for all these functions is to play with the Gingerbreadman fractal type. Gingerbreadman's shape makes it easy to see what you're doing to him. A warning though: Gingerbreadman will run forever, he's never quite done! So, pre-empt with your next zoom when he's baked enough. If you accidentally change your zoom box shape or rotate and forget which way is up, just use to make it bigger until it disappears, then to get a fresh one. With a mouse, after removing the old zoom box from the display release and re-press the left button for a fresh one. If your screen does not have a 4:3 "aspect ratio" (i.e. if the visible display area on it is not 1.333 times as wide as it is high), rotating and zooming will have some odd effects - angles will change, including the zoom box's shape itself, circles (if you are so lucky as to see any with a non-standard aspect ratio) become non-circular, and so on. The vast majority of PC screens *do* have a 4:3 aspect ratio. Zooming is not implemented for the plasma and diffusion fractal types, nor for overlayed and 3D images. A few fractal types support zooming but do not support rotation and skewing - nothing happens when you try it. ; ; ; ~Topic=Image Save/Restore Commands, Label=HELPSAVEREST saves the current image to disk. All parameters required to recreate the image are saved with it. Progress is marked by colored lines moving down the screen's edges. The default filename for the first image saved after starting Fractint is FRACT001.GIF; subsequent saves in the same session are automatically incremented 002, 003... Use the "savename=" parameter or options screen to change the name. By default, files left over from previous sessions are not overwritten - the first unused FRACTnnn name is used. Use the "overwrite=yes" parameter or options screen) to overwrite existing files. A save operation can be interrupted by pressing any key. If you interrupt, you'll be asked whether to keep or discard the partial file. restores an image previously saved with , or an ordinary GIF file. After pressing you are shown the file names in the current directory which match the current file mask. To select a file to restore, move the cursor to it (or type the first few letters of its name) and press . Directories are shown in the file list with a \"\\\" at the end of the name. When you select a directory, the contents of that directory are shown. Or, you can type the name of a different directory (and optionally a different drive) and press for a new display. You can also type a mask such as "*.XYZ" and press to display files whose name ends with the matching suffix (XYZ). You can use to switch directories to the default fractint directory or to your own directory which is specified through the DOS environment variable "FRACTDIR". Once you have selected a file to restore, a summary description of the file is shown, with a video mode selection list. Usually you can just press to go past this screen and load the image. Other choices available at this point are:\ Cursor keys: select a different video mode\ : display more information about the fractal\ : for help about the "err" column in displayed video modes\ If you restore a file into a video mode which does not have the same pixel dimensions as the file, Fractint will make some adjustments: The view window parameters (see command) will automatically be set to an appropriate size, and if the image is larger than the screen dimensions, it will be reduced by using only every Nth pixel during the restore. ; ; ; ~Topic=Print Command

\ Print the current fractal image on your (Laserjet, Paintjet, Epson- compatible, PostScript, or HP-GL) printer. See {"Setting Defaults (SSTOOLS.INI File)"} and {"Printer Parameters"} for how to let Fractint know about your printer setup. {"Disk-Video" Modes} can be used to generate images for printing at higher resolutions than your screen supports. ; ; ; ~Topic=Parameter Save/Restore Commands, Label=HELPPARMFILE Parameter files can be used to save/restore all options and settings required to recreate particular images. The parameters required to describe an image require very little disk space, especially compared with saving the image itself. <@> or <2> The <@> or <2> command loads a set of parameters describing an image. (Actually, it can also be used to set non-image parameters such as SOUND, but at this point we're interested in images. Other uses of parameter files are discussed in {"Parameter Files and the <@> Command"}.) When you hit <@> or <2>, Fractint displays the names of the entries in the currently selected parameter file. The default parameter file, FRACTINT.PAR, is included with the Fractint release and contains parameters for some sample images. After pressing <@> or <2>, highlight an entry and press to load it, or press to change to another parameter file. Note that parameter file entries specify all calculation related parameters, but do not specify things like the video mode - the image will be plotted in your currently selected mode. The command saves the parameters required to describe the currently displayed image, which can subsequently be used with the <@> or <2> command to recreate it. After you press , Fractint prompts for: Parameter file: The name of the file to store the parameters in. You should use some name like "myimages" instead of fractint.par, so that your images are kept separate from the ones released with new versions of Fractint. You can use the PARMFILE= command in SSTOOLS.INI to set the default parameter file name to "myimages" or whatever. (See {"Setting Defaults (SSTOOLS.INI File)"} and "parmfile=" in {"File Parameters"}.) Name: The name you want to assign to the entry, to be displayed when the <@> or <2> command is used. Main comment: A comment to be shown beside the entry in the <@> command display. Second, Third, and Fourth comment: Additional comments to store in the file with the entry. These comments go in the file only, and are not displayed by the <@> command. You can set these comments from the command line - see {=@COMMENTS Comment= Command}. Record colors?: Whether color information should be included in the entry. Usually the default value displayed by Fractint is what you want. Allowed values are:\ "no" - Don't record colors.\ "@mapfilename" - When these parameters are used, load colors from the named color map file. This is the default if you are currently using colors from a color map file.\ "yes" - Record the colors in detail. This is the default when you've changed the display colors by using the palette editor or by color cycling. The only reason that this isn't what Fractint always does for the command is that color information can be bulky - up to nearly 3K of disk space per map - which adds up to a lot for many images. Smooth-shaded ranges of colors are compressed, so if that's used a lot in an image the color information won't be as bulky.\ "only" - Record only the colors in the PAR file, without any other parameters. This is useful for converting color maps to PAR entries. # of colors: This only matters if "Record colors?" is set to "yes". It specifies the number of colors to record. Recording less colors will take less space. Usually the default value displayed by Fractint is what you want. You might want to increase it in some cases, e.g. if you are using a 256 color mode with maxiter 150, and have used the palette editor to set all 256 possible colors for use with color cycling, then you'll want to set the "# of colors" to 256. See the {=@RECORDCOLORS Recordcolors} command, which controls when mapfiles are used and when compressed colors are written to PAR files. maxlinelength: This number controls the maximum width of a parameter entry in a PAR file. The default is 72 characters. At the bottom of the input screen are inputs for Fractint's "pieces" divide-and-conquer feature. You can create multiple PAR entries that break an image up into pieces so that you can generate the image pieces one by one. There are two reasons for doing this. The first is in case the fractal is very slow, and you want to generate parts of the image at the same time on several computers. The second is that you might want to make an image greater than 2048 x 2048, the old pixel limit for Fractint. The parameters for this feature are: X Multiples - How many divisions of final image in the x direction\ Y Multiples - How many divisions of final image in the y direction\ Video mode - Fractint video mode for each piece (e.g. "F3")\ The last item defaults to the current video mode. If either X Multiples or Y Multiples are greater than 1, then multiple numbered PAR entries for the pieces are added to the PAR file, and a MAKEMIG.BAT file is created that builds all of the component pieces and then stitches them together into a "multi-image" GIF. The current limitations of the "divide and conquer" algorithm are 36 or fewer X and Y multiples (so you are limited to "only" 36x36=1296 component images), and a final resolution limit in both the X and Y directions of 65,535 (a limitation of "only" four billion pixels or so). The final image generated by MAKEMIG is a "multi-image" GIF file called FRACTMIG.GIF. In case you have other software that can't handle multi-image GIF files, MAKEMIG includes a final (but commented out) call to SIMPLGIF, a companion program that reads a GIF file that may contain little tricks like multiple images and creates a simple GIF from it. Fair warning: SIMPLGIF needs room to build a composite image while it works, and it does that using a temporary disk file equal to the size of the final image - and a 64Kx64K GIF image requires a 4GB temporary disk file! The command lets you give a startup parameter interactively. ; ; ; ~Topic= Options Screen, Label=HELPXOPTS ; This topic is online context-sensitive only. Passes - see {Drawing Method}\ Fillcolor - see {Drawing Method}\ Floating Point Algorithm - see notes below\ Maximum Iterations - see {Image Calculation Parameters}\ Inside and Outside colors - see {Color Parameters}\ Savename and File Overwrite - see {File Parameters}\ Sound option - see {Sound Parameters}\ Log Palette - see {Logarithmic Palettes and Color Ranges}\ Biomorph Color - see {Biomorphs}\ Decomp Option - see {Decomposition}\ You can toggle the use of floating-point algorithms on this screen (see {"Limitations of Integer Math (And How We Cope)"}). Whether floating point is in use is shown on the status screen. If you have a non-Intel floating point chip which supports the full 387 instruction set, see the "FPU=" command in {Startup Parameters} to get the most out of your chip. ; ; ~Topic= Options Screen, Label=HELPYOPTS ; This topic is online context-sensitive only. Finite attractor - see{ Finite Attractors }\ Potential parameters - see{ Continuous Potential }\ Distance Estimator parameters - see{ Distance Estimator Method }\ Inversion parameters - see{ Inversion }\ Color cycling range - see{ Color Cycling Commands }\ ; ; ~Topic=

Options Screen, Label=HELPPOPTS ; This topic is online context-sensitive only. Periodicity - see{ Passes Parameters }\ Orbit Delay - see{ Passes Parameters }\ Orbit Interval - see{ Passes Parameters }\ Maintain Screen Coordinates - see{ Passes Parameters }\ Orbit Draw Mode - see{ Passes Parameters }\ ; ; ~Topic=Image Coordinates Screen, Label=HELPCOORDS ; This topic is online context-sensitive only. You can directly enter corner coordinates on this screen instead of using the zoom box to move around. You can also use to reset the coordinates to the defaults for the current fractal type. There are two formats for the display: corners or center-mag. You can toggle between the two by using . In corners mode, corner coordinate values are entered directly. Usually only the top-left and bottom-right corners need be specified - the bottom left corner can be entered as zeros to default to an ordinary unrotated rectangular area. For rotated or skewed images, the bottom left corner must also be specified. In center-mag mode the image area is described by entering the coordinates for the center of the rectangle, and its magnification factor. Usually only these three values are needed, but the user can also specify the amount that the image is stretched, rotated and skewed. ; ; ~Topic=Screen Coordinates Screen, Label=HELPSCRNCOORDS ; This topic is online context-sensitive only. You can directly enter corner coordinates on this screen for use with the passes='o' option. You can also use to reset the coordinates to the defaults for the current fractal type. There are two formats for the display: corners or center-mag. You can toggle between the two by using . In corners mode, corner coordinate values are entered directly. Usually only the top-left and bottom-right corners need be specified - the bottom left corner can be entered as zeros to default to an ordinary unrotated rectangular area. For rotated or skewed images, the bottom left corner must also be specified. In center-mag mode the screen area is described by entering the coordinates for the center of the rectangle, and its magnification factor. Usually only these three values are needed, but the user can also specify the amount that the image is stretched, rotated and skewed. ; ; ; ~Topic=Interrupting and Resuming Fractint command keys can be loosely grouped as: o Keys which suspend calculation of the current image (if one is being calculated) and automatically resume after the function. (display status information) and (display help), are the only keys in this group. o Keys which automatically trigger calculation of a new image. Examples: selecting a video mode (e.g. ); selecting a fractal type using ; using the screen to change an option such as maximum iterations. o Keys which do something, then wait for you to indicate what to do next. Examples: to go to main menu; to enter color cycling mode; to bring up a zoom box. After using a command in this group, calculation automatically resumes when you return from the function (e.g. from color cycling, to clear zoom box). There are a few fractal types which cannot resume calculation, they are noted below. Note that after saving an image with , you must press to clear the "saved" message from the screen and resume. An image which is aved before it completes can later be estored and continued. The calculation is automatically resumed when you restore such an image. When a slow fractal type resumes after an interruption in the third category above, there may be a lag while nothing visible happens. This is because most cases of resume restart at the beginning of a screen line. If unsure, you can check whether calculation has resumed with the key. The following fractal types cannot (currently) be resumed: plasma, 3d transformations, julibrot, and 3d orbital types like lorenz3d. To check whether resuming an image is possible, use the key while it is calculating. It is resumable unless there is a note under the fractal type saying it is not. The {Batch Mode} section discusses how to resume in batch mode. To estore and resume a "formula", "lsystem", or "ifs" type fractal your "formulafile", "lfile", or "ifsfile" must contain the required name. ; ; ; ~Topic=Orbits Window, Label=HELP_ORBITS The key turns on the Orbit mode. In this mode a cursor appears over the fractal. A window appears showing the orbit used in the calculation of the color at the point where the cursor is. Move the cursor around the fractal using the arrow keys or the mouse and watch the orbits change. Try entering the Orbits mode with View Windows () turned on. The following keys take effect in Orbits mode.\ Circle toggle - makes little circles with radii inversely\ proportional to the iteration. Press again to toggle\ back to point-by-point display of orbits.\ Line toggle - connects orbits with lines (can use with )\ Numbers toggle - shows complex coordinates & color number of\ the cursor on the screen. Press again to turn off numbers.\

Enter pixel coordinates directly\ Hide fractal toggle. Works only if View Windows is turned on\ and set for a small window (such as the default size.) Hides the\ fractal, allowing the orbit to take up the whole screen. Press\ again to uncover the fractal.\ Saves the fractal, cursor, orbits, and numbers as they\ appear on the screen.\ <<> or <,> Zoom orbits image smaller\ <>> or <.> Zoom orbits image larger\ Restore default zoom.\ ; ; ; ~Topic=View Window, Label=HELPVIEW The command is used to set the view window parameters described below. These parameters can be used to:\ o Define a small window on the screen which is to contain the generated images. Using a small window speeds up calculation time (there are fewer pixels to generate). You can use a small window to explore quickly, then turn the view window off to recalculate the image at full screen size. o Generate an image with a different "aspect ratio"; e.g. in a square window or in a tall skinny rectangle. o View saved GIF images which have pixel dimensions different from any mode supported by your hardware. This use of view windows occurs automatically when you restore such an image. o Define a disk video mode up to 32767x32767. First select a disk video mode using . Then on the screen enter both an X and a Y value at the Virtual Screen Total Pixels prompts. o Define a virtual video mode up to the size that fits in video memory. First select a VESA video mode (dotmode=28) using . Then on the screen enter both an X and a Y value at the Virtual Screen Total Pixels prompts. The Keep Aspect prompt is used if the asked for virtual screen is larger than video memory. If set, the X and Y values will both be reduced such that the ratio between them is maintained. If not set, just the Y value will be reduced. "Preview display"\ Set this to "yes" to turn on view window, "no" for full screen display. While this is "no", the only view parameter which has any affect is "final media aspect ratio". When a view window is being used, all other Fractint functions continue to operate normally - you can zoom, color-cycle, and all the rest. "Reduction factor"\ When an explicit size is not given, this determines the view window size, as a factor of the screen size. E.g. a reduction factor of 2 makes the window 1/2 as big as the screen in both dimensions. "Final media aspect ratio"\ This is the height of the final image you want, divided by the width. The default is 0.75 because standard PC monitors have a height:width ratio of 3:4. E.g. set this to 2.0 for an image twice as high as it is wide. The effect of this parameter is visible only when "preview display" is enabled. If the explicit size of both x and y are set, setting this value to 0 will cause the appropriate value to be calculated based on x and y. "Crop starting coordinates"\ This parameter affects what happens when you change the aspect ratio. If set to "no", then when you change aspect ratio, the prior image will be squeezed or stretched to fit into the new shape. If set to "yes", the prior image is "cropped" to avoid squeezing or stretching. "Explicit size"\ Setting these to non-zero values over-rides the "reduction factor" with explicit sizes in pixels. If only the "x pixels" size is specified, the "y pixels" size is calculated automatically based on x and the aspect ratio. The following option is available when using disk video or virtual screen modes: "Virtual screen"\ Setting these allow defining a virtual screen as large as the available video memory will permit. The following options are available when using virtual screen modes: "Keep aspect"\ If this is set, when the asked for virtual screen is larger than video memory the X and Y values will both be reduced such that the ratio between them is maintained. If not set, just the Y value will be reduced. "Zoombox scrolling"\ The fixed setting tries to maintain the zoombox in the center of the screen by moving the virtual image. The relaxed setting moves the virtual image when the zoombox reached the edges of the screen. More about final aspect ratio: If you want to produce a high quality hard-copy image which is say 8" high by 5" down, based on a vertical "slice" of an existing image, you could use a procedure like the following. You'll need some method of converting a GIF image to your final media (slide or whatever) - Fractint can only do the whole job with a PostScript printer, it does not preserve aspect ratio with other printers. o restore the existing image\ o set view parameters: preview to yes, reduction to anything (say 2), aspect ratio to 1.6, and crop to yes o zoom, rotate, whatever, till you get the desired final image\ o set preview display back to no\ o trigger final calculation in some high res disk video mode, using the appropriate video mode function key o print directly to a PostScript printer, or save the result as a GIF file and use external utilities to convert to hard copy. ; ; ; ~Topic=\"3D\" Commands See {\"3D\" Images} for details of these commands. <3>\ Restore a saved image as a 3D "landscape", translating its color information into "height". You will be prompted for all KINDS of options. <#>\ Restore in 3D and overlay the result on the current screen. ; ; ; ~Topic=Video Mode Function Keys, Label=HELPVIDSEL Fractint supports *so* many video modes that we've given up trying to reserve a keyboard combination for each of them. Any supported video mode can be selected by going to the "Select Video Mode" screen (from main menu or by using ), then using the cursor up and down arrow keys and/or and keys to highlight the desired mode, then pressing . Up to 39 modes can be assigned to the keys F2-F10, SF1-SF10 +), CF1-CF10 (+), and AF1-AF10 (+). The modes assigned to function keys can be invoked directly by pressing the assigned key, without going to the video mode selection screen. 30 key combinations can be reassigned: to combined with any of , , or . The video modes assigned to through can not be changed - these are assigned to the most common video modes, which might be used in demonstration files or batches. To reassign a function key to a mode you often use, go to the "select video mode" screen, highlight the video mode, press the keypad (gray) <+> key, then press the desired function key or key combination. The new key assignment will be remembered for future runs. To unassign a key (so that it doesn't invoke any video mode), highlight the mode currently selected by the key and press the keypad (gray) <-> key. A note about the "select video modes" screen: the video modes which are displayed with a 'B' suffix in the number of colors are modes which have no custom programming - they use the BIOS and are S-L-O-W ones. See {"Video Adapter Notes"} for comments about particular adapters. See {"Disk-Video" Modes} for a description of these non-display modes. See {"Customized Video Modes\, FRACTINT.CFG"} for information about adding your own video modes. ; ; ; ~Topic=Browse Commands, Label=HELPBROWSE The following keystrokes function while browsing an image:\ Step through the outlines on the screen.\ Selects the image to display.\ <\\>, Recalls the last image selected.\ Deletes the selected file.\ Renames the selected file.\ Saves the current image with the browser boxes\ displayed.\ , Toggles the browse mode off.\ Brings up the {Browser Parameters} screen.\ Change the browser boxes color.\ This is a "visual directory", here is how it works...\ When 'L' or 'l' is pressed from a fractal display the current directory is searched for any saved files that are deeper zooms of the current image and their position shown on screen by a box (or crosshairs if the box would be too small). See also {Browser Parameters} for more on how this is done. One outline flashes, the selected outline can be changed by using the cursor keys. At the moment the outlines are selected in the order that they appear in your directory, so don't worry if the flashing window jumps all over the place! When enter is pressed, the selected image is loaded. In this mode a stack of the last sixteen selected filenames is maintained and the '\\' or 'h' key pops and loads the last image you were looking at. Using this it is possible to set up sequences of images that allow easy exploration of your favorite fractal without having to wait for recalc once the level of zoom gets too high, great for demos! (also useful for keeping track of just exactly where fract532.gif came from :-) ) You can also use this facility to tidy up your disk: by typing UPPER CASE 'D' when a file is selected the browser will delete the file for you, after making sure that you really mean it, you must reply to the "are you sure" prompts with an UPPER CASE 'Y' and nothing else, otherwise the command is ignored. Just to make absolutely sure you don't accidentally wipe out the fruits of many hours of cpu time the default setting is to have the browser prompt you twice, you can disable the second prompt within the parameters screen, however, if you're feeling overconfident :-). To complement the Delete function there is a rename function, use the UPPER CASE 'R' key for this. You need to enter the FULL new file name, no .GIF is implied. It is possible to save the current image along with all of the displayed boxes indicating subimages by pressing the 's' key. This exits the browse mode to save the image and the boxes become a permanent part of the image. Currently, the screen image ends up with stray dots colored after it is saved. Esc backs out of image selecting mode.\ The browser can now use expanded memory or extended memory. If you have more than 4 MB of expanded/extended memory available, you can use either. If you don't have 4 MB of expanded/extended memory available, use expanded memory as it will allocate as much as possible. The extended memory support will silently fail and default to the use of far memory if 4 MB of extended memory is not available. Here's a tip on how to zoom out beyond your starting point when browsing: Suppose you restore a fractal deeply-zoomed down in a directory of related zoomed images, and then bring up the browser. How do you zoom out? You can't use "\\" because you started with the zoomed image, and there is no browser command to detect the next outer image. What you can do is exit the browser, press PgUp until the zoom box won't get any smaller, zoom out with Ctrl-Enter, and before any image starts to develop, call up the browser again, locate your zoomed image that you started with, and see if there is another image that contains it - if so, restore it with the browser. You can also use a view window to load the first image, and then use the browser. POSSIBLE ERRORS: "Sorry..I can't find anything"\ The browser can't locate any files which match the file name mask. See {Browser Parameters} This is also displayed if you have less than 10K of far memory free when you run Fractint. "Sorry.... no more space"\ At the moment the browser can only cope with 450 sub images at one time. Any subsequent images are ignored. Make sure that the minimum image size isn't set too small on the parameters screen. ~OnlineFF "Sorry .... out of memory"\ The browser has run out of far, expanded, or extended memory in which to store the pixels covered by the sub image boxes. Try again with the main image at lower resolution, and/or reduce the number of TSRs resident in memory when you start Fractint. Make sure you have expanded or extended memory available. "Sorry...it's a read only file, can't del "\ "Sorry....can't rename"\ The file which you were trying to delete or rename has the read only attribute set, you'll need to reset this with your operating system before you can get rid of it. ; ; ; ~Topic=Browser Parameters, Label=HELPBRWSPARMS This Screen enables you to control Fractint's built in file browsing utility. If you don't know what that is see {Browse Commands}. This screen is selected with from just about anywhere. "Autobrowsing"\ Select yes if you want the loaded image to be scanned for sub images immediately without pressing 'L' every time. "Ask about GIF video mode"\ Allows turning on and off the display of the video mode table when loading GIFs. This has the same effect as the askvideo= command. "Type/Parm check"\ Select whether the browser tests for fractal type or parms when deciding whether a file is a sub image of the current screen or not. DISABLE WITH CAUTION! or things could get confusing. These tests can be switched off to allow such situations as wishing to display old images that were generated using a formula type which is now implemented as a built in fractal type. ~OnlineFF "Confirm deletes"\ Set this to No if you get fed up with the double prompting that the browser gives when deleting a file. It won't get rid of the first prompt however. "Smallest window"\ This parameter determines how small the image would have to be onscreen before the browser decides not to include it in the selection of files. The size is entered in decimal pixels so, for instance, this could be set to 0.2 to allow images that are up to around three maximum zooms away (depending on the current video resolution) to be loaded instantly. Set this to 0 to enable all sub images to be detected. This can lead to a very cluttered screen! The primary use is in conjunction with the search file mask (see below) to allow location of high magnification images within an overall view (like the whole Mset). "Smallest box"\ This determines when the image location is shown as crosshairs rather than a rather small box. Set this according to how good your eyesight is (probably worse than before you started staring at fractals all the time :-)) or the resolution of your screen. WARNING the crosshairs routine centers the cursor on one corner of the image box at the moment so this looks misleading if set too large. ~OnlineFF "Search Mask"\ Sets the file name pattern which the browser searches, this can be used to search out the location of a file by setting this to the filename and setting smallest image to 0 (see above). ; ; ; ~Topic=RDS Commands, Label=RDSKEYS The following keystrokes function while viewing an RDS image:\ or -- Toggle calibration bars on and off.\ or -- Return to RDS Parameters Screen.\ -- Save RDS image, then restore original.\ , <+>, <-> -- Color cycle RDS image.\ Other keys -- Exit RDS mode, restore original image, and pass\ keystroke on to main menu.\ For more about RDS, see {Random Dot Stereograms (RDS)} ; ; ; ~Topic=Hints Remember, you do NOT have to wait for the program to finish a full screen display before entering a command. If you see an interesting spot you want to zoom in on while the screen is half-done, don't wait -- do it! If you think after seeing the first few lines that another video mode would look better, go ahead -- Fractint will shift modes and start the redraw at once. When it finishes a display, it beeps and waits for your next command. In general, the most interesting areas are the "border" areas where the colors are changing rapidly. Zoom in on them for the best results. The first Mandelbrot-set (default) fractal image has a large, solid-colored interior that is the slowest to display; there's nothing to be seen by zooming there. Plotting time is directly proportional to the number of pixels in a screen, and hence increases with the resolution of the video mode. You may want to start in a low-resolution mode for quick progress while zooming in, and switch to a higher-resolution mode when things get interesting. Or use the solid guessing mode and pre-empt with a zoom before it finishes. Plotting time also varies with the maximum iteration setting, the fractal type, and your choice of drawing mode. Solid-guessing (the default) is fastest, but it can be wrong: perfectionists will want to use dual-pass mode (its first-pass preview is handy if you might zoom pre-emptively) or single-pass mode. When you start systematically exploring, you can save time (and hey, every little bit helps -- these "objects" are INFINITE, remember!) by aving your last screen in a session to a file, and then going straight to it the next time by using the command FRACTINT FRACTxxx (the .GIF extension is assumed), or by starting Fractint normally and then using the command to reload the saved file. Or you could hit to create a parameter file entry with the "recipe" for a given image, and next time use the <@> command to re-plot it. ; ; ; ~Topic=Fractint on Unix Fractint has been ported to Unix to run under X Windows. This version is called "Xfractint". Xfractint may be obtained by anonymous ftp, see {Distribution of Fractint}. Xfractint is still under development and is not as reliable as the IBM PC version. Contact xfractint@fractint.org for more information on Xfractint. ~FF Xfractint is a straight port of the IBM PC version. Thus, it uses the IBM user interface. If you do not have function keys, or Xfractint does not accept them from your keyboard, use the following key mappings: IBM Unix\ F1 to F10 Shift-1 to Shift-0\ INSERT I\ DELETE D\ PAGE_UP U\ PAGE_DOWN N\ LEFT_ARROW H\ RIGHT_ARROW L\ UP_ARROW K\ DOWN_ARROW J\ HOME O\ END E\ CTL_PLUS \}\ CTL_MINUS \{ Xfractint takes the following options: -onroot\ Puts the image on the root window. -fast\ Uses a faster drawing technique. -disk\ Uses disk video. -geometry WxH[\{+-X}\{+-Y}]\ Changes the geometry of the image window. -display displayname\ Specifies the X11 display to use. -private\ Allocates the entire colormap (i.e. more colors). -share\ Shares the current colormap. -fixcolors n\ Uses only n colors. -slowdisplay\ Prevents Xfractint from hanging on the title page with slow displays. -simple\ Uses simpler keyboard handling, which makes debugging easier. Common problems: If you get the message "Couldn't find fractint.hlp", you can\ a) Do "setenv FRACTDIR /foo", replacing /foo with the directory containing fractint.hlp.\ b) Run Xfractint from the directory containing fractint.hlp, or\ c) Copy fractint.hlp to /usr/local/bin/X11/fractint If you get the message "Invalid help signature", the problem is due to byteorder. You are probably using a Sun help file on a Dec machine or vice versa. If Xfractint doesn't accept input, try typing into both the graphics window and the text window. On some systems, only one of these works. If you are using Openwindows and can't get Xfractint to accept input, add to your .Xdefaults file:\ OpenWindows.FocusLenience: True If you cannot view the GIFs that Xfractint creates, the problem is that Xfractint creates GIF89a format and your viewer probably only handles GIF87a format. Run "xfractint gif87a=y" to produce GIF87a format. Because many shifted characters are used to simulate IBM keys, you can't enter capitalized filenames. ; ; ; ~Topic=Color Cycling Commands, Label=@ColorCycling ~Doc- See {=HELPCYCLING Color Cycling Command Summary} for a summary of commands. ~Doc+ Color-cycling mode is entered with the 'c', '+', or '-' keys from an image, or with the 'c' key from Palette-Editing mode. The color-cycling commands are available ONLY for VGA adapters and EGA adapters in 640x350x16 mode. You can also enter color-cycling while using a disk-video mode, to load or save a palette - other functions are not supported in disk-video. Note that the colors available on an EGA adapter (16 colors at a time out of a palette of 64) are limited compared to those of VGA, super- VGA, and MCGA (16 or 256 colors at a time out of a palette of 262,144). So color-cycling in general looks a LOT better in the latter modes. Also, because of the EGA palette restrictions, some commands are not available with EGA adapters. Color cycling applies to the color numbers selected by the "cyclerange=" command line parameter (also changeable via the options screen and via the palette editor). By default, color numbers 1 to 255 inclusive are cycled. On some images you might want to set "inside=0" ( options or command line parameter) to exclude the "lake" from color cycling. When you are in color-cycling mode, you will either see the screen colors cycling, or will see a white "overscan" border when paused, as a reminder that you are still in this mode. The keyboard commands available once you've entered color-cycling. are described below. \ Bring up a HELP screen with commands specific to color cycling mode. \ Leave color-cycling mode. \ Restore original palette. <+> or <->\ Begin cycling the palette by shifting each color to the next "contour." <+> cycles the colors in one direction, <-> in the other. '<' or '>'\ Force a color-cycling pause, disable random colorizing, and single-step through a one color-cycle. For "fine-tuning" your image colors. Cursor up/down\ Increase/decrease the cycling speed. High speeds may cause a harmless flicker at the top of the screen. through \ Switches from simple rotation to color selection using randomly generated color bands of short (F2) to long (F10) duration. <1> through <9>\ Causes the screen to be updated every 'n' color cycles (the default is 1). Handy for slower computers. \ Randomly selects a function key (F2 through F10) and then updates ALL the screen colors prior to displaying them for instant, random colors. Hit this over and over again (we do). \ Pause cycling with white overscan area. Cycling restarts with any command key (including another spacebar). -\ Pause cycling and reset the palette to a preset two color "straight" assignment, such as a spread from black to white. (Not for EGA) -\ Pause & set a 2-color cyclical assignment, e.g. red->yellow->red (not EGA). -\ Pause & set a 3-color cyclical assignment, e.g. green->white->blue (not EGA). , , \ Pause and increase the red, green, or blue component of all colors by a small amount (not for EGA). Note the case distinction of this vs: , , \ Pause and decrease the red, green, or blue component of all colors by a small amount (not for EGA). or \ Pause and load an external color map from the files DEFAULT.MAP or ALTERN.MAP, supplied with the program. \ Pause and load an external color map (.MAP file). Several .MAP files are supplied with Fractint. See {Palette Maps}. \ Pause, prompt for a filename, and save the current palette to the named file (.MAP assumed). See {Palette Maps}. ; ; ; ~Topic=Color Cycling Command Summary, Label=HELPCYCLING ; This topic is online only ~Format- See {Color Cycling Commands} for full documentation. F1 HELP! (Enter help mode and display this screen) Esc Exit from color-cycling mode + or - (re)-set the direction of the color-cycling Home Restore original palette ~Doc- \27 \26 (re)-set the direction of the color-cycling (just like +/-) \24 \25 SpeedUp/SlowDown the color cycling process ~Doc+,Online- Right/Left Arrow (re)-set the direction of the color-cycling (just like +/-) Up/Down Arrow SpeedUp/SlowDown the color cycling process ~Online+ F2 thru F10 Select Short--Medium--Long (randomly-generated) color bands 1 thru 9 Cycle through 'nn' colors between screen updates (default=1) Enter Randomly (re)-select all new colors [TRY THIS ONE!] Spacebar Pause until another key is hit < or > Pause and single-step through one color-cycle * SF1 thru AF10 Pause and reset the Palette to one of 30 fixed sequences d or a pause and load the palette from DEFAULT.MAP or ALTERN.MAP l load palette from a map file s save palette to a map file * r or g or b or force a pause and Lower (lower case) or Raise (upper case) * R or G or B the Red, Green, or Blue component of the fractal image ; ; ; ~Topic=Palette Editing Commands ~Doc- See {=HELPXHAIR Palette Editing Command Summary} for a summary of commands. ~Doc+ Palette-editing mode provides a number of tools for modifying the colors in an image. It can be used only with MCGA or higher adapters, and only with 16 or 256 color video modes. Many thanks to Ethan Nagel for creating the palette editor. Use the key to enter palette-editing mode from a displayed image or from the main menu. When this mode is entered, an empty palette frame is displayed. You can use the cursor keys to position the frame outline, and and to change its size. (The upper and lower limits on the size depend on the current video mode.) When the frame is positioned where you want it, hit Enter to display the current palette in the frame. Note that the palette frame shows R(ed) G(reen) and B(lue) values for two color registers at the top. The active color register has a solid frame, the inactive register's frame is dotted. Within the active register, the active color component is framed. With a video mode of 640x400 or higher, a status area appears between the two color registers. This status area shows: nnn = color number at the cursor location\ A = Auto mode\ X, Y = exclusion modes\ F = freesyle mode\ T = stripe mode is waiting for #\ Using the commands described below, you can assign particular colors to the registers and manipulate them. Note that at any given time there are two colors "X"d - these are pre-empted by the editor to display the palette frame. They can be edited but the results won't be visible. You can change which two colors are borrowed ("X"d out) by using the command. Once the palette frame is displayed and filled in, the following commands are available: \ Bring up a HELP screen with commands specific to palette-editing mode. \ Leave palette-editing mode \ Hide the palette frame to see full image; the cross-hair remains visible and all functions remain enabled; hit again to restore the palette display. Cursor keys\ Move the cross-hair cursor around. In 'auto' mode (the default) the color under the center of the cross-hair is automatically assigned to the active color register. Control-Cursor keys move the cross-hair faster. A mouse can also be used to move around. \ Select the Red, Green, or Blue component of the active color register for subsequent commands \ Select previous or next color component in active register ~onlineFF <+> <->\ Increase or decrease the active color component value by 1 Numeric keypad (gray) + and - keys do the same. \ Increase or decrease the active color component value by 5; Moving the mouse up/down with left button held is the same <0> <1> <2> <3> <4> <5> <6>\ Set the active color component's value to 0 10 20 ... 60 \ Select the other color register as the active one. In the default 'auto' mode this results in the now-inactive register being set to remember the color under the cursor, and the now-active register changing from whatever it had previously remembered to now follow the color. <,> <.>\ Rotate the palette one step. By default colors 1 through 255 inclusive are rotated. This range can be over-ridden with the "cyclerange" parameter, the options screen, or the command described below. "<" ">"\ Rotate the palette continuously (until next keystroke) \ Set the color cycling range to the range of colors currently defined by the color registers. \ Enter Color-Cycling Mode. When you invoke color-cycling from here, it will subsequently return to palette-editing when you from it. See {Color Cycling Commands}. <=>\ Create a smoothly shaded range of colors between the colors selected by the two color registers. \ Specify a gamma value for the shading created by <=>. \ Duplicate the inactive color register's values to the active color register. \ Stripe-shade - create a smoothly shaded range of colors between the two color registers, setting only every Nth register. After hitting , hit a numeric key from 2 to 9 to specify N. For example, if you press <3>, smooth shading is done between the two color registers, affecting only every 3rd color between them. The other colors between them remain unchanged. \ Convert current palette to gray-scale. (If the or exclude ranges described later are in force, only the active range of colors is converted to gray-scale.) ... \ Store the current palette in a temporary save area associated with the function key. The temporary save palettes are useful for quickly comparing different palettes or the effect of some changes - see next command. The temporary palettes are only remembered until you exit from palette-editing mode.\ Starting with version 19.6, when palette editing mode is entered, the original palette is stored in the area associated with F2. ... \ Restore the palette from a temporary save area. If you haven't previously saved a palette for the function key, you'll get a simple grey scale. \ Pause and load an external color map (.MAP file). See {Palette Maps}. \ Pause, prompt for a filename, and save the current palette to the named file (.MAP assumed). See {Palette Maps}. \ Invert frame colors. With some colors the palette is easier to see when the frame colors are interchanged. <\\>\ Move or resize the palette frame. The frame outline is drawn - it can then be repositioned and sized with the cursor keys, and , just as was done when first entering palette-editing mode. Hit Enter when done moving/sizing. \ Use the colors currently selected by the two color registers for the palette editor's frame. When palette editing mode is entered, the last two colors are "X"d out for use by the palette editor; this command can be used to replace the default with two other color numbers. \ Toggle 'auto' mode on or off. When on (the default), the active color register follows the cursor; when off, must be pressed to set the active register to the color under the cursor. \ Only useful when 'auto' is off, as described above; double clicking the left mouse button is the same as Enter. \ Toggle 'exclude' mode on or off - when toggled on, only those image pixels which match the active color are displayed. \ Toggle 'exclude' range on or off - similar to , but all pixels matching colors in the range of the two color registers are displayed. \ Make a negative color palette - will convert only current color if in 'x' mode or range between editors in 'y' mode or entire palette if in "normal" mode. \ <@> <\"> (English keyboard) (French keyboard)\ <#> (English keyboard) <$> (French keyboard)\ Swap R<->G, G<->B, and R<->B columns. , <@>, and <#> are shifted 1, 2, and 3, which you may find easier to remember. \ Undoes the last palette editor command. Will undo all the way to the beginning of the current session. \ Redoes the undone palette editor commands. \ Toggles "Freestyle mode" on and off (Freestyle mode changes a range of palette values smoothly from a center value outward). With your cursor inside the palette box, press the key to enter Freestyle mode. A default range of colors will be selected for you centered at the cursor (the ends of the color range are noted by putting dashed lines around the corresponding palette values). While in Freestyle mode: Moving the mouse changes the location of the range of colors that are affected. Control-Insert/Delete or the shifted-right-mouse-button changes the size of the affected palette range. The normal color editing keys (R,G,B,1-6, etc) set the central color of the affected palette range. Pressing ENTER or double-clicking the left mouse button makes the palette changes permanent (if you don't perform this step, any palette changes disappear when you press the key again to exit freestyle mode). For more details see {Freestyle mode tutorial} ; ; ~Topic=Freestyle mode tutorial It can be confusing working out what's going on in freestyle mode so here's a quick walk through...\ Freestyle palette editing is intended to be a way of colouring an image in an intuitive fashion with the minimum of keyboard usage. In fact everything is controllable with the mouse, as the following shows: To start with, generate a plasma type fractal as it has all 256 colours on screen at once. Now bring up the palette editor and press 'w' to set up a greyscale palette as a blank canvas on which to splash some colour. Pressing 'f' puts us in freestyle mode... crosshairs appear on the screen and a colour band is applied, centred on the cursor. Although, at the moment, the colour of this band is grey and you won't see much! In order to change the colour of the band, hold down the left mouse button and drag up and down. This changes the amount of red in the band. You'll see the values change in the status box above the palette grid. Double clicking the right mouse button changes the colour component that's varied in an r-g-b-r- cycle.... try it out and conjure up any shade you like! To vary the width of the band, drag up and down with the right button held down. Slower machines may show some 'lag' during this operation, especially if they have no math co-processor, so watch out as the mouse movements get buffered. Once you've got the band in a satisfactory position then double click the left button to fix it in place. Continue like this for as long as you like, adding different colours to the grey palette. You'll notice how the band relates to the existing colour, the RGB values give the middle colour which are then smoothly shaded out to the colours at the ends of the band. This can lead to some sudden jumps in the shading as the band is moved about the screen and the edges come to overlap different areas of colour. For really violent jumps in shading try starting with an image that has areas that change chaotically, such as a Mandlbrot set. You'll see what I mean when you move the cross hairs into an area close to the 'lake' where the change in value from one pixel to the next is sudden, chaotic and large. Watch out! the strobing effect can be somewhat disturbing. This is nothing to worry about but just a consequence of the manipulation of the palette and the way in which the colour bands are calculated. I hope that you'll find this a useful tool in colouring an image. Remember that the 'h' key can be used to hide the palette box and expose the whole image. ; ~Topic=Palette Editing Command Summary, Label=HELPXHAIR ; This topic is online only. ~Format- See {Palette Editing Commands} for full documentation. F1 HELP! (Enter help mode and display this screen) Esc Exit from palette editing mode h Hide/unhide the palette frame \24 \25 \27 \26 Move the cross-hair cursor around. Control-Cursor keys move faster. A mouse can also be used to move around. r or g or b Select the the Red, Green, or Blue component of the active color register for subsequent commands Insert or Delete Select previous or next color component in active register + or - Increase or decrease the active color component by 1 Pageup or Pagedn Increase or decrease the active color component by 5; Moving the mouse up/down with left button held is the same 0 1 2 3 4 5 6 Set active color component to 0 10 20 ... 60 Space Select the other color register as the active one , or . Rotate the palette one step < or > Rotate the palette continuously (until next keystroke) c Enter Color-Cycling Mode (see {=HELPCYCLING Color Cycling Commands}) = Create a smoothly shaded range of colors m Set the gamma value for '='. ~FF d Duplicate the inactive color register in active color t Stripe-shade; after hitting 't', hit a number from 2 to 9 which is used as stripe width Shift-F2,F3,..F9 Store the current palette in a temporary save area associated with the function key F2,F3,...,F9 Restore the palette from a temporary save area w Convert palette (or current exclude range) to gray-scale \\ Move or resize the palette frame i Invert frame colors, useful with dark colors a Toggle 'auto' mode on or off - when on, the active color register follows the cursor; when off, Enter must be hit to set the register to the color under the cursor Enter Only useful when 'auto' is off, as described above; double clicking the left mouse button is the same as Enter x Toggle 'exclude' mode on or off y Toggle 'exclude' range on or off o Set the 'cyclerange' (range affected by color cycling commands) to the range of the two registers n Make a negative color palette u Undoes the last command e Redoes the last undone command ~FF ! Swap red and green columns @ \" or u-grave Swap green and blue columns # pound or $ Swap red and blue columns f Toggle Freestyle Palette-Editing Mode. See {Palette Editing Commands} for details. ; ; ~Topic=Parameter Explorer/Evolver, Label=HELPEVOL Since fractint is such a wonderfully complex program it has more than a few parameters to tweak and options to select. To the inexperienced user the choice is bewildering. Even for the experts the chaotic nature of the mathematical processes involved make it difficult to know what to change in order to achieve the desired effect. In order to help with this situation the Fractint parameter evolver has been developed. It varies those parameters for you and puts the results on screen as a grid of small images. You can then choose the one which you like best and regenerate it full screen, or if you don't like any of the variations, you can try again to see if anything better turns up! Enough explanations for now, lets see how easy it is to use: With the default Mandlebrot set on the screen simply hold down the 'Alt' key and press the '1' key on the top row (DON'T use the numeric keypad to the right, it won't work). You'll see a screen full of images generated starting from the middle and spiraling outwards. The perfect Mandlebrot set will be in the middle and the others will be warped and distorted by having had the initial value of Z perturbed at random... but you don't need to know that (which is the whole point really!). 'Alt-1' produces a low level of mutation of the fractal, only 'mild' parameters are changed, those which have a more subtle effect. For much wilder variations try pressing 'Alt-7' now. This give the maximum available mutation with just about everything being twiddled and fiddled to rather dramatic effect as you should now be seeing. To select an image for full screen display simply bring up a zoombox by pressing 'Page-up' once. The center image will now have a white box around it. Hold down the 'Ctrl' key and use the arrow keys to move this box around until it's outlining an image you like. Pressing 'B' will now exit from evolver mode and redraw the selected image full size. If, rather than exiting from evolver mode, you just press 'enter', then a whole new set of images is generated, all based around the one you selected (which is now the middle image of the new set). From a basic point of view that's it! Just press alt-number to scramble things when you're out of inspiration, it works for any of the fractal types in fractint including formulae... easy! (chaotic, but easy :-) ) As this is a Fractint feature, there is, of course, a lot more to it than the basics described above... For a start, there are some handy hotkeys to use, 'F2' and 'F3' are used to alter the amount of mutation or the amount by which the selected parameters can be varied. 'F2' halves the amount of mutation, 'F3' doubles it. So if things on-screen are looking a bit samey just press 'F3' a few times to crank up the mutation level. Using 'F2' to decrease mutation levels is a way of moving towards a goal image. Say that a set of images contained one that looked a little like, maybe, a cats face and you wished to try and get something more cat like. To achieve this simply select the desired image and press 'F2'. The newly generated images should be more alike, though probably still quite widely varied. With luck, one of the new images will be even more cat like. Select this one and press 'F2' again. Continue like this, selecting the center image again if there are no improvements in the current generation, until eventually all the images are alike and you've arrived at your goal (or at least you're probably as close as it's possible to get with that fractal type). As you look for more details in the images it is useful to reduce the number of images per generation, thus producing larger sub images. Pressing 'F4' will reduce the number of images per side on the grid by two and pressing 'F5' increments the gridsize similarly. 'F6' will switch between normal random mutation and 'spread' random mutation. In 'spread' mode the amount of mutation allowed in an image is varied according to each images position in the grid. Those images near the center are allowed a lesser degree of freedom of mutation than those around the outside. This produces a sea of images, stable at the center with wilder variations around the edges. This mode is best used with larger gridsizes and becomes completely silly at a gridsize of three! 'Ctrl-e' brings up the evolver control screen on which you have manual access to the evolution parameters varied by the hotkeys described above.\ These are: Gridsize. The number of sub images per side of the screen. Use odd numbers only. Max Mutation The maximum amount by which a parameter may be varied Mutation Reduction The Max mutation value is multiplied by this between generations. This can be used to automatically goal seek without having to use the 'F2' key. Grouting Turns on or off the gap between sub images, at large values of gridsize this can reclaim valuable screen area for display use. Pressing 'F6' brings up a screen from which you can control what parameters get varied and in what manner. You'll notice that as well as the mutation modes 'random' and 'spread' there are other ways of stirring things around, read on...... As well as randomly mutating parameter values (referred to as 'evolver mode' or just 'evolving') a chosen set of parameters can be varied steadily across the screen thus allowing the user to explore what happens as a parameter is slowly changed ('explorer mode' or 'exploring'). For example, to get acquainted with parameter exploring and produce a map of the Julia sets, try this:\ Start Fractint and set the type to Julia and the resolution higher than 320x200, once the default Julia set has been generated, press 'Ctrl-e' to bring up the evolver/explorer control panel. Set evolve mode to yes and then press 'F6' to bring up the screen that allows you to choose what gets varied. Now set the first entry (param1) to 'x' and the second (param2) to 'y'. This tells Fractint to vary param1 (the real part of c) across the screen and param2 (the imaginary part of c) down the screen. Make sure all the other parameters are set to 'no' so that nothing else gets changed to confuse things. Press 'Return' to go back to the main evolver control screen and you'll see that a few more items have appeared. These control just how much the parameters are varied across the screen and what their starting values should be, leave them as they are but increase gridsz to 15. Also switch on the parameter zoom box option. When you exit this control screen with the 'Return' key, you'll see a grid of Julia sets generated all mapped out onto the imaginary plane, squint and you'll be able to spot the underlying Mset! When you press 'Pageup' this time you'll notice that there are two boxes on screen with a larger box centered around the normal selection box. 'Ctrl-pageup' or 'Ctrl-pagedown' varies the size of this box which represents the 'parameter' zoom box. The parameter zoombox allows you to look at smaller areas of the parameter space in more detail. To explain this further look at how the Julia sets change across the screen, around the area of 'seahorse valley' on the underlying Mset, the Julia sets undergo a sharp change in character. This area of change can be examined in more detail using parameter zooming. Make the outer zoombox a few grids across and select an image in the area of this change with the outer box straddling it. Look at the images right in the corners of the parm zoombox, when you press 'Enter' and a new generation of images is generated the same images will be in the corners of the screen with more sub images between them, allowing a finer look at how the change progresses. In this way, you can observe the chaotic areas in parameter space with the unique pseudo four dimensional view offered by the explorer. In the example shown above, you were just exploring the variation in two 'real' parameters, i.e. they can take fractional values, and the idea of being able to create an image half way between two others is valid. However, many of the parameters in fractint are discrete, i.e. can be only one of a set of specific values. Examples of discrete parameters are inside colouring method or decomposition values and the way in which these are explored is different in that parameter zooming has no meaning for discrete parameters. When a discrete parameter is set to vary with x or y it is simply cycled through all possible values and round again. Words are getting clumsy so it's time for another example methinks! First press 'Insert' to restart Fractint and get everything back to its default values for a fresh start. Set the fractal type to 'fn*fn' this type requires the user to choose two trig functions and this choice is made on the 'Z' screen. There are around thirty different functions to choose from and checking out all the different combinations is a not inconsiderable task manually. With the explorer, however, it's a piece of cake! Set the screen resolution to the highest you can view and press 'Ctrl-e' to bring up the control panel and enable evolving mode. Set the gridsize to 29 and leave the parameters at their defaults. Now, press 'F6' to enter 'variable tweak central' and set trig function 1 to 'x' and trig function 2 to 'y', and all the others to 'no'. Exit the two screens and you'll see generated all of the different combinations possible even if they are rather small examples! To find out what particular combination of trig functions an image is using, just select the image using the zoombox and bring up the 'z' screen. You don't have to press 'Enter', simply highlighting the appropriate image with the ctrl-arrow keys will do. And that just about sums up the evolver! Much more could be written but it's better experienced, try writing your formulae with more variable parameters and trig functions so that their behavior can be investigated. Try using it with any fractal type, if in doubt just see what happens! It should be noted here that some of the fractal types such as the IFS do not terminate, they run on forever and as such aren't usable with the evolver as the first sub image would never finish to allow the next one to generate. These fractal types are detected and you won't be allowed to start the evolver with these. There now only remains to mention that you can save image sets and restore them later to carry on exploring from a different seed image: 's' saves and 'r' restores as in normal fractint operation and the screenfull is saved as a single gif file. Have fun! See {Evolver Commands}. ; ; ~Topic=Evolver Commands ~Format- PageUp When no Zoom Box is active, brings one up. When Zoom Box is active already, shrinks it. PageDown Expands the Zoom Box. Expanding past the screen size cancels the Zoom Box. ~Doc- \24 \25 \27 \26 Pans (Moves) the Zoom Box. Ctrl- \24 \25 \27 \26 Moves the Zoom Box to the next subimage. ~Doc+,Online- Arrow key Pans (Moves) the Zoom Box. Ctrl-Arrow key Moves the Zoom Box to the next subimage. ~Online+ Enter Redraws the Screen or area inside the Zoom Box. Ctrl-Enter 'Zoom-out' - expands the image so that your current image is positioned inside the current zoom-box location. Ctrl-Pad+/Pad- Rotates the inner Zoom Box. Ctrl-PgUp/PgDn Changes inner Zoom Box vertical size. Ctrl-Home/End Changes inner Zoom Box shape. Ctrl-Ins/Del Changes inner Zoom Box color. Ctrl-E Brings up the evolver screen. Space Brings up the evolver screen once in evolver mode. B Turns off evolver if in evolver mode. F2 Halves the amount of mutation. F3 Doubles the amount of mutation. F4 Generates fewer, bigger images. F5 Generates more, smaller images. F6 Switches to/from 'spread' mode with fewer mutations around the middle. ~Format+ ; Fractal Types: ~Include help2.src ; ; Doodads, 3D: ~Include help3.src ; ; Parameters, Video Adapters & Modes: ~Include help4.src ; ; The rest: ~Include help5.src ; ;

"); choicekey[nextleft+=2] = 'v'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"view window options... "); if(showjuliatoggle == 0) { choicekey[nextleft+=2] = 'i'; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"fractal 3D parms... "); } choicekey[nextleft+=2] = 2; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"browse parms... "); if (fullmenu) { choicekey[nextleft+=2] = 5; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"evolver parms... "); } #ifndef XFRACT if (fullmenu) { choicekey[nextleft+=2] = 6; attributes[nextleft] = MENU_ITEM; LOADPROMPTSCHOICES(nextleft,"sound parms... "); } #endif LOADPROMPTSCHOICES(nextright+=2," FILE "); attributes[nextright] = 256+MENU_HDG; choicekey[nextright+=2] = '@'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"run saved command set... <@> "); if (fullmenu) { choicekey[nextright+=2] = 's'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"save image to file "); } choicekey[nextright+=2] = 'r'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"load image from file... "); choicekey[nextright+=2] = '3'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"3d transform from file...<3> "); if (fullmenu) { choicekey[nextright+=2] = '#'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"3d overlay from file.....<#> "); choicekey[nextright+=2] = 'b'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"save current parameters.. "); choicekey[nextright+=2] = 16; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"print image "); } #ifndef XFRACT choicekey[nextright+=2] = 'd'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"shell to dos "); #endif choicekey[nextright+=2] = 'g'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"give command string "); #ifdef XFRACT choicekey[nextright+=2] = 'u'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"list of contributors "); #endif choicekey[nextright+=2] = INSERT; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"restart "FRACTINT" "); choicekey[nextright+=2] = ESC; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"quit "FRACTINT" "); #ifdef XFRACT if (fullmenu && (gotrealdac || fake_lut) && colors >= 16) { #else if (fullmenu && gotrealdac && colors >= 16) { #endif /* nextright += 2; */ LOADPROMPTSCHOICES(nextright+=2," COLORS "); attributes[nextright] = 256+MENU_HDG; choicekey[nextright+=2] = 'c'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"color cycling mode "); choicekey[nextright+=2] = '+'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"rotate palette <+>,<-> "); if (colors > 16) { if (!reallyega) { choicekey[nextright+=2] = 'e'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"palette editing mode "); } choicekey[nextright+=2] = 'a'; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright,"make starfield "); } } choicekey[nextright+=2] = 1; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright, "ant automaton "); choicekey[nextright+=2] = 19; attributes[nextright] = MENU_ITEM; LOADPROMPTSCHOICES(nextright, "stereogram "); i = (keypressed()) ? getakey() : 0; if (menu_checkkey(i,1) == 0) { helpmode = HELPMAIN; /* switch help modes */ if ((nextleft += 2) < nextright) nextleft = nextright + 1; i = fullscreen_choice(CHOICEMENU+CHOICESCRUNCH, MAIN_MENU, NULL,NULL,nextleft,(char far * far *)choices,attributes, 2,nextleft/2,29,0,NULL,NULL,NULL,menu_checkkey); if (i == -1) /* escape */ i = ESC; else if (i < 0) i = 0 - i; else { /* user selected a choice */ i = choicekey[i]; switch (i) { /* check for special cases */ case -10: /* zoombox functions */ helpmode = HELPZOOM; help(0); i = 0; break; } } } if (i == ESC) { /* escape from menu exits Fractint */ if (!check_exit()) goto top; } if (i == TAB) { tab_display(); i = 0; } if (i == ENTER || i == ENTER_2) { i = 0; /* don't trigger new calc */ } tabmode = oldtabmode; return(i); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif int menu_checkkey(int curkey,int choice) { /* choice is dummy used by other routines called by fullscreen_choice() */ int testkey; menutype = choice; /* for intro screen only */ testkey = (curkey>='A' && curkey<='Z') ? curkey+('a'-'A') : curkey; #ifdef XFRACT /* We use F2 for shift-@, annoyingly enough */ if (testkey == F2) return(0-testkey); #endif if(testkey == '2') testkey = '@'; if (strchr("#@2txyzgvir3jdu",testkey) || testkey == INSERT || testkey == 2 || testkey == ESC || testkey == DELETE || testkey == 6) /*RB 6== ctrl-F for sound menu */ return(0-testkey); if (menutype) { if (strchr("\\sobpkha",testkey) || testkey == TAB || testkey == 1 || testkey == 5 || testkey == 8 || testkey == 16 || testkey == 19 || testkey == 21) /* ctrl-A, E, H, P, S, U */ return(0-testkey); if (testkey == ' ') if ((curfractalspecific->tojulia != NOFRACTAL && param[0] == 0.0 && param[1] == 0.0) || curfractalspecific->tomandel != NOFRACTAL) return(0-testkey); if (gotrealdac && colors >= 16) { if (strchr("c+-",testkey)) return(0-testkey); if (colors > 16 && (testkey == 'a' || (!reallyega && testkey == 'e'))) return(0-testkey); } /* Alt-A and Alt-S */ if (testkey == 1030 || testkey == 1031 ) return(0-testkey); } if (check_vidmode_key(0,testkey) >= 0) return(0-testkey); return(0); } int input_field( int options, /* &1 numeric, &2 integer, &4 double */ int attr, /* display attribute */ char *fld, /* the field itself */ int len, /* field length (declare as 1 larger for \0) */ int row, /* display row */ int col, /* display column */ int (*checkkey)(int) /* routine to check non data keys, or NULL */ ) { char savefld[81]; char buf[81]; int insert, started, offset, curkey, display; int i, j; int ret,savelookatmouse; savelookatmouse = lookatmouse; lookatmouse = 0; ret = -1; strcpy(savefld,fld); insert = started = offset = 0; display = 1; for(;;) { strcpy(buf,fld); i = strlen(buf); while (i < len) buf[i++] = ' '; buf[len] = 0; if (display) { /* display current value */ putstring(row,col,attr,buf); display = 0; } curkey = keycursor(row+insert,col+offset); /* get a keystroke */ if(curkey == 1047) curkey = 47; /* numeric slash */ switch (curkey) { case ENTER: case ENTER_2: ret = 0; goto inpfld_end; case ESC: goto inpfld_end; case RIGHT_ARROW: if (offset < len-1) ++offset; started = 1; break; case LEFT_ARROW: if (offset > 0) --offset; started = 1; break; case HOME: offset = 0; started = 1; break; case END: offset = strlen(fld); started = 1; break; case 8: case 127: /* backspace */ if (offset > 0) { j = strlen(fld); for (i = offset-1; i < j; ++i) fld[i] = fld[i+1]; --offset; } started = display = 1; break; case DELETE: /* delete */ j = strlen(fld); for (i = offset; i < j; ++i) fld[i] = fld[i+1]; started = display = 1; break; case INSERT: /* insert */ insert ^= 0x8000; started = 1; break; case F5: strcpy(fld,savefld); insert = started = offset = 0; display = 1; break; default: if (nonalpha(curkey)) { if (checkkey && (ret = (*checkkey)(curkey)) != 0) goto inpfld_end; break; /* non alphanum char */ } if (offset >= len) break; /* at end of field */ if (insert && started && strlen(fld) >= (size_t)len) break; /* insert & full */ if ((options & 1) && (curkey < '0' || curkey > '9') && curkey != '+' && curkey != '-') { if ((options & 2)) break; /* allow scientific notation, and specials "e" and "p" */ if ( ((curkey != 'e' && curkey != 'E') || offset >= 18) && ((curkey != 'p' && curkey != 'P') || offset != 0 ) && curkey != '.') break; } if (started == 0) /* first char is data, zap field */ fld[0] = 0; if (insert) { j = strlen(fld); while (j >= offset) { fld[j+1] = fld[j]; --j; } } if ((size_t)offset >= strlen(fld)) fld[offset+1] = 0; fld[offset++] = (char)curkey; /* if "e" or "p" in first col make number e or pi */ if ((options & 3) == 1) { /* floating point */ double tmpd; int specialv; char tmpfld[30]; specialv = 0; if (*fld == 'e' || *fld == 'E') { tmpd = exp(1.0); specialv = 1; } if (*fld == 'p' || *fld == 'P') { tmpd = atan(1.0) * 4; specialv = 1; } if (specialv) { if ((options & 4) == 0) roundfloatd(&tmpd); sprintf(tmpfld,"%.15g",tmpd); tmpfld[len-1] = 0; /* safety, field should be long enough */ strcpy(fld,tmpfld); offset = 0; } } started = display = 1; } } inpfld_end: lookatmouse = savelookatmouse; return(ret); } int field_prompt( int options, /* &1 numeric value, &2 integer */ char far *hdg, /* heading, \n delimited lines */ char far *instr, /* additional instructions or NULL */ char *fld, /* the field itself */ int len, /* field length (declare as 1 larger for \0) */ int (*checkkey)(int) /* routine to check non data keys, or NULL */ ) { char far *charptr; int boxwidth,titlelines,titlecol,titlerow; int promptcol; int i,j; char buf[81]; static char far DEFLT_INST[] = {"Press ENTER when finished (or ESCAPE to back out)"}; helptitle(); /* clear screen, display title */ setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest to background */ charptr = hdg; /* count title lines, find widest */ i = boxwidth = 0; titlelines = 1; while (*charptr) { if (*(charptr++) == '\n') { ++titlelines; i = -1; } if (++i > boxwidth) boxwidth = i; } if (len > boxwidth) boxwidth = len; i = titlelines + 4; /* total rows in box */ titlerow = (25 - i) / 2; /* top row of it all when centered */ titlerow -= titlerow / 4; /* higher is better if lots extra */ titlecol = (80 - boxwidth) / 2; /* center the box */ titlecol -= (90 - boxwidth) / 20; promptcol = titlecol - (boxwidth-len)/2; j = titlecol; /* add margin at each side of box */ if ((i = (82-boxwidth)/4) > 3) i = 3; j -= i; boxwidth += i * 2; for (i = -1; i < titlelines+3; ++i) /* draw empty box */ setattr(titlerow+i,j,C_PROMPT_LO,boxwidth); textcbase = titlecol; /* set left margin for putstring */ putstring(titlerow,0,C_PROMPT_HI,hdg); /* display heading */ textcbase = 0; i = titlerow + titlelines + 4; if (instr) { /* display caller's instructions */ charptr = instr; j = -1; while ((buf[++j] = *(charptr++)) != 0) if (buf[j] == '\n') { buf[j] = 0; putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf); j = -1; } putstringcenter(i,0,80,C_PROMPT_BKGRD,buf); } else /* default instructions */ putstringcenter(i,0,80,C_PROMPT_BKGRD,DEFLT_INST); return(input_field(options,C_PROMPT_INPUT,fld,len, titlerow+titlelines+1,promptcol,checkkey)); } /* thinking(1,message): if thinking message not yet on display, it is displayed; otherwise the wheel is updated returns 0 to keep going, -1 if keystroke pending thinking(0,NULL): call this when thinking phase is done */ int thinking(int options,char far *msg) { static int thinkstate = -1; char *wheel[] = {"-","\\","|","/"}; static int thinkcol; static int count = 0; char buf[81]; if (options == 0) { if (thinkstate >= 0) { thinkstate = -1; unstackscreen(); } return(0); } if (thinkstate < 0) { stackscreen(); thinkstate = 0; helptitle(); strcpy(buf," "); far_strcat(buf,msg); strcat(buf," "); putstring(4,10,C_GENERAL_HI,buf); thinkcol = textcol - 3; count = 0; } if ((count++)<100) { return 0; } count = 0; putstring(4,thinkcol,C_GENERAL_HI,wheel[thinkstate]); movecursor(25,80); /* turn off cursor */ thinkstate = (thinkstate + 1) & 3; return (keypressed()); } void clear_screen(int dummy) /* a stub for a windows only subroutine */ { dummy=0; /* quite the warning */ } /* savegraphics/restoregraphics: video.asm subroutines */ unsigned long swaptotlen; unsigned long swapoffset; BYTE far *swapvidbuf; int swaplength; #define SWAPBLKLEN 4096 /* must be a power of 2 */ U16 memhandle = 0; #ifdef XFRACT BYTE suffix[10000]; #endif #ifndef XFRACT int savegraphics() { int i; long count; unsigned long swaptmpoff; swaptotlen = (long)(vxdots > sxdots ? vxdots : sxdots) * (long)sydots; i = colors; while (i <= 16) { swaptotlen >>= 1; i = i * i; } count = (long)((swaptotlen / SWAPBLKLEN) + 1); swapoffset = 0; if (memhandle != 0) discardgraphics(); /* if any emm/xmm in use from prior call, release it */ memhandle = MemoryAlloc((U16)SWAPBLKLEN, count, EXPANDED); while (swapoffset < swaptotlen) { swaplength = SWAPBLKLEN; if ((swapoffset & (SWAPBLKLEN-1)) != 0) swaplength = (int)(SWAPBLKLEN - (swapoffset & (SWAPBLKLEN-1))); if ((unsigned long)swaplength > (swaptotlen - swapoffset)) swaplength = (int)(swaptotlen - swapoffset); if (swapoffset == 0) swaptmpoff = 0; else swaptmpoff = swapoffset/swaplength; (*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */ MoveToMemory(swapvidbuf,(U16)swaplength,1L,swaptmpoff,memhandle); swapoffset += swaplength; } return 0; } int restoregraphics() { unsigned long swaptmpoff; swapoffset = 0; swapvidbuf = MK_FP(extraseg+0x1000,0); /* for swapnormwrite case */ while (swapoffset < swaptotlen) { swaplength = SWAPBLKLEN; if ((swapoffset & (SWAPBLKLEN-1)) != 0) swaplength = (int)(SWAPBLKLEN - (swapoffset & (SWAPBLKLEN-1))); if ((unsigned long)swaplength > (swaptotlen - swapoffset)) swaplength = (int)(swaptotlen - swapoffset); if (swapoffset == 0) swaptmpoff = 0; else swaptmpoff = swapoffset/swaplength; if (swapsetup != swapnormread) (*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */ MoveFromMemory(swapvidbuf,(U16)swaplength,1L,swaptmpoff,memhandle); if (swapsetup == swapnormread) swapnormwrite(); swapoffset += swaplength; } discardgraphics(); return(0); } #else int savegraphics() {return 0;} int restoregraphics() {return 0;} #endif void discardgraphics() /* release expanded/extended memory if any in use */ { #ifndef XFRACT MemoryRelease(memhandle); memhandle = 0; #endif } #if (_MSC_VER >= 700) #pragma code_seg ("realdos1_text") /* place following in an overlay */ #endif VIDEOINFO *vidtbl; /* temporarily loaded fractint.cfg info */ int vidtbllen; /* number of entries in above */ int showvidlength() { int sz; sz = (sizeof(VIDEOINFO)+sizeof(int))*MAXVIDEOMODES; return(sz); } int load_fractint_cfg(int options) { /* Reads fractint.cfg, loading videoinfo entries into extraseg. */ /* Sets vidtbl pointing to the loaded table, and returns the */ /* number of entries (also sets vidtbllen to this). */ /* Past vidtbl, cfglinenums are stored for update_fractint_cfg. */ /* If fractint.cfg is not found or invalid, issues a message */ /* (first time the problem occurs only, and only if options is */ /* zero) and uses the hard-coded table. */ FILE *cfgfile; VIDEOINFO *vident; int far *cfglinenums; int linenum; long xdots, ydots; int i, j, keynum, ax, bx, cx, dx, dotmode, colors; int commas[10]; int textsafe2; char tempstring[150]; int truecolorbits; vidtbl = MK_FP(extraseg,0); cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]); #ifdef XFRACT badconfig = -1; #endif if (badconfig) /* fractint.cfg already known to be missing or bad */ goto use_resident_table; findpath("fractint.cfg",tempstring); if (tempstring[0] == 0 /* can't find the file */ || (cfgfile = fopen(tempstring,"r")) == NULL) /* can't open it */ goto bad_fractint_cfg; vidtbllen = 0; linenum = 0; vident = vidtbl; while (vidtbllen < MAXVIDEOMODES && fgets(tempstring, 120, cfgfile)) { if(strchr(tempstring,'\n') == NULL) /* finish reading the line */ while(fgetc(cfgfile) != '\n' && !feof(cfgfile)); ++linenum; if (tempstring[0] == ';') continue; /* comment line */ tempstring[120] = 0; tempstring[strlen(tempstring)-1] = 0; /* zap trailing \n */ memset(commas,0,20); i = j = -1; for(;;) { if (tempstring[++i] < ' ') { if (tempstring[i] == 0) break; tempstring[i] = ' '; /* convert tab (or whatever) to blank */ } else if (tempstring[i] == ',' && ++j < 10) { commas[j] = i + 1; /* remember start of next field */ tempstring[i] = 0; /* make field a separate string */ } } keynum = check_vidmode_keyname(tempstring); sscanf(&tempstring[commas[1]],"%x",&ax); sscanf(&tempstring[commas[2]],"%x",&bx); sscanf(&tempstring[commas[3]],"%x",&cx); sscanf(&tempstring[commas[4]],"%x",&dx); dotmode = atoi(&tempstring[commas[5]]); xdots = atol(&tempstring[commas[6]]); ydots = atol(&tempstring[commas[7]]); colors = atoi(&tempstring[commas[8]]); if(colors == 4 && strchr(strlwr(&tempstring[commas[8]]),'g')) { colors = 256; truecolorbits = 4; /* 32 bits */ } else if(colors == 16 && strchr(&tempstring[commas[8]],'m')) { colors = 256; truecolorbits = 3; /* 24 bits */ } else if(colors == 64 && strchr(&tempstring[commas[8]],'k')) { colors = 256; truecolorbits = 2; /* 16 bits */ } else if(colors == 32 && strchr(&tempstring[commas[8]],'k')) { colors = 256; truecolorbits = 1; /* 15 bits */ } else truecolorbits = 0; textsafe2 = dotmode / 100; dotmode %= 100; if (j < 9 || keynum < 0 || dotmode < 0 || dotmode > 30 || textsafe2 < 0 || textsafe2 > 4 || xdots < MINPIXELS || xdots > MAXPIXELS || ydots < MINPIXELS || ydots > MAXPIXELS || (colors != 0 && colors != 2 && colors != 4 && colors != 16 && colors != 256) ) goto bad_fractint_cfg; cfglinenums[vidtbllen] = linenum; /* for update_fractint_cfg */ far_memcpy(vident->name, (char far *)&tempstring[commas[0]],25); far_memcpy(vident->comment,(char far *)&tempstring[commas[9]],25); vident->name[25] = vident->comment[25] = 0; vident->keynum = keynum; vident->videomodeax = ax; vident->videomodebx = bx; vident->videomodecx = cx; vident->videomodedx = dx; vident->dotmode = truecolorbits * 1000 + textsafe2 * 100 + dotmode; vident->xdots = (short)xdots; vident->ydots = (short)ydots; vident->colors = colors; ++vident; ++vidtbllen; } fclose(cfgfile); return (vidtbllen); bad_fractint_cfg: badconfig = -1; /* bad, no message issued yet */ if (options == 0) bad_fractint_cfg_msg(); use_resident_table: vidtbllen = 0; vident = vidtbl; for (i = 0; i < MAXVIDEOTABLE; ++i) { if (videotable[i].xdots) { far_memcpy((char far *)vident,(char far *)&videotable[i], sizeof(*vident)); ++vident; ++vidtbllen; } } return (vidtbllen); } void bad_fractint_cfg_msg() { static char far badcfgmsg[]={"\ File FRACTINT.CFG is missing or invalid.\n\ See Hardware Support and Video Modes in the full documentation for help.\n\ I will continue with only the built-in video modes available."}; stopmsg(0,badcfgmsg); badconfig = 1; /* bad, message issued */ } void load_videotable(int options) { /* Loads fractint.cfg and copies the video modes which are */ /* assigned to function keys into videotable. */ int keyents,i; load_fractint_cfg(options); /* load fractint.cfg to extraseg */ keyents = 0; far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE); for (i = 0; i < vidtbllen; ++i) { if (vidtbl[i].keynum > 0) { far_memcpy((char far *)&videotable[keyents],(char far *)&vidtbl[i], sizeof(*vidtbl)); if (++keyents >= MAXVIDEOTABLE) break; } } } int check_vidmode_key(int option,int k) { int i; /* returns videotable entry number if the passed keystroke is a */ /* function key currently assigned to a video mode, -1 otherwise */ if (k == 1400) /* special value from select_vid_mode */ return(MAXVIDEOTABLE-1); /* for last entry with no key assigned */ if (k != 0) { if (option == 0) { /* check resident video mode table */ for (i = 0; i < MAXVIDEOTABLE; ++i) { if (videotable[i].keynum == k) return(i); } } else { /* check full vidtbl */ for (i = 0; i < vidtbllen; ++i) { if (vidtbl[i].keynum == k) return(i); } } } return(-1); } int check_vidmode_keyname(char *kname) { /* returns key number for the passed keyname, 0 if not a keyname */ int i,keyset; keyset = 1058; if (*kname == 'S' || *kname == 's') { keyset = 1083; ++kname; } else if (*kname == 'C' || *kname == 'c') { keyset = 1093; ++kname; } else if (*kname == 'A' || *kname == 'a') { keyset = 1103; ++kname; } if (*kname != 'F' && *kname != 'f') return(0); if (*++kname < '1' || *kname > '9') return(0); i = *kname - '0'; if (*++kname != 0 && *kname != ' ') { if (*kname != '0' || i != 1) return(0); i = 10; ++kname; } while (*kname) if (*(kname++) != ' ') return(0); if ((i += keyset) < 2) i = 0; return(i); } void vidmode_keyname(int k,char *buf) { /* set buffer to name of passed key number */ *buf = 0; if (k > 0) { if (k > 1103) { *(buf++) = 'A'; k -= 1103; } else if (k > 1093) { *(buf++) = 'C'; k -= 1093; } else if (k > 1083) { *(buf++) = 'S'; k -= 1083; } else k -= 1058; sprintf(buf,"F%d",k); } } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif xfractint-20.4.10.orig/common/fractals.c0000644000000000000000000026136711064332143014754 0ustar /* FRACTALS.C, FRACTALP.C and CALCFRAC.C actually calculate the fractal images (well, SOMEBODY had to do it!). The modules are set up so that all logic that is independent of any fractal-specific code is in CALCFRAC.C, the code that IS fractal-specific is in FRACTALS.C, and the structure that ties (we hope!) everything together is in FRACTALP.C. Original author Tim Wegner, but just about ALL the authors have contributed SOME code to this routine at one time or another, or contributed to one of the many massive restructurings. The Fractal-specific routines are divided into three categories: 1. Routines that are called once-per-orbit to calculate the orbit value. These have names like "XxxxFractal", and their function pointers are stored in fractalspecific[fractype].orbitcalc. EVERY new fractal type needs one of these. Return 0 to continue iterations, 1 if we're done. Results for integer fractals are left in 'lnew.x' and 'lnew.y', for floating point fractals in 'new.x' and 'new.y'. 2. Routines that are called once per pixel to set various variables prior to the orbit calculation. These have names like xxx_per_pixel and are fairly generic - chances are one is right for your new type. They are stored in fractalspecific[fractype].per_pixel. 3. Routines that are called once per screen to set various variables. These have names like XxxxSetup, and are stored in fractalspecific[fractype].per_image. 4. The main fractal routine. Usually this will be StandardFractal(), but if you have written a stand-alone fractal routine independent of the StandardFractal mechanisms, your routine name goes here, stored in fractalspecific[fractype].calctype.per_image. Adding a new fractal type should be simply a matter of adding an item to the 'fractalspecific' structure, writing (or re-using one of the existing) an appropriate setup, per_image, per_pixel, and orbit routines. -------------------------------------------------------------------- */ #include #include #ifdef __TURBOC__ #include #elif !defined(__386BSD__) #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #include "fractype.h" #include "externs.h" #define NEWTONDEGREELIMIT 100 _LCMPLX lcoefficient,lold,lnew,lparm, linit,ltmp,ltmp2,lparm2; long ltempsqrx,ltempsqry; int maxcolor; int root, degree,basin; double floatmin,floatmax; double roverd, d1overd, threshold; _CMPLX tmp2; _CMPLX coefficient; _CMPLX staticroots[16]; /* roots array for degree 16 or less */ _CMPLX *roots = staticroots; struct MPC *MPCroots; long FgHalf; _CMPLX pwr; int bitshiftless1; /* bit shift less 1 */ #ifndef sqr #define sqr(x) ((x)*(x)) #endif #ifndef lsqr #define lsqr(x) (multiply((x),(x),bitshift)) #endif #define modulus(z) (sqr((z).x)+sqr((z).y)) #define conjugate(pz) ((pz)->y = 0.0 - (pz)->y) #define distance(z1,z2) (sqr((z1).x-(z2).x)+sqr((z1).y-(z2).y)) #define pMPsqr(z) (*pMPmul((z),(z))) #define MPdistance(z1,z2) (*pMPadd(pMPsqr(*pMPsub((z1).x,(z2).x)),pMPsqr(*pMPsub((z1).y,(z2).y)))) double twopi = PI*2.0; int c_exp; /* These are local but I don't want to pass them as parameters */ _CMPLX parm,parm2; _CMPLX *floatparm; _LCMPLX *longparm; /* used here and in jb.c */ /* -------------------------------------------------------------------- */ /* These variables are external for speed's sake only */ /* -------------------------------------------------------------------- */ double sinx,cosx; double siny,cosy; double tmpexp; double tempsqrx,tempsqry; double foldxinitx,foldyinity,foldxinity,foldyinitx; long oldxinitx,oldyinity,oldxinity,oldyinitx; long longtmp; /* These are for quaternions */ double qc,qci,qcj,qck; /* temporary variables for trig use */ long lcosx, lsinx; long lcosy, lsiny; /* ** details of finite attractors (required for Magnet Fractals) ** (can also be used in "coloring in" the lakes of Julia types) */ /* ** pre-calculated values for fractal types Magnet2M & Magnet2J */ _CMPLX T_Cm1; /* 3 * (floatparm - 1) */ _CMPLX T_Cm2; /* 3 * (floatparm - 2) */ _CMPLX T_Cm1Cm2; /* (floatparm - 1) * (floatparm - 2) */ void FloatPreCalcMagnet2(void) /* precalculation for Magnet2 (M & J) for speed */ { T_Cm1.x = floatparm->x - 1.0; T_Cm1.y = floatparm->y; T_Cm2.x = floatparm->x - 2.0; T_Cm2.y = floatparm->y; T_Cm1Cm2.x = (T_Cm1.x * T_Cm2.x) - (T_Cm1.y * T_Cm2.y); T_Cm1Cm2.y = (T_Cm1.x * T_Cm2.y) + (T_Cm1.y * T_Cm2.x); T_Cm1.x += T_Cm1.x + T_Cm1.x; T_Cm1.y += T_Cm1.y + T_Cm1.y; T_Cm2.x += T_Cm2.x + T_Cm2.x; T_Cm2.y += T_Cm2.y + T_Cm2.y; } /* -------------------------------------------------------------------- */ /* Bailout Routines Macros */ /* -------------------------------------------------------------------- */ int (near *floatbailout)(void); int (near *longbailout)(void); int (near *bignumbailout)(void); int (near *bigfltbailout)(void); #if 0 int near fpMODbailout(void) { if ( ( magnitude = ( tempsqrx=sqr(new.x) ) + ( tempsqry=sqr(new.y) ) ) >= rqlim ) return(1); old = new; return(0); } #endif int near fpMODbailout(void) { tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; if(magnitude >= rqlim) return(1); old = new; return(0); } int near fpREALbailout(void) { tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; if(tempsqrx >= rqlim) return(1); old = new; return(0); } int near fpIMAGbailout(void) { tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; if(tempsqry >= rqlim) return(1); old = new; return(0); } int near fpORbailout(void) { tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; if(tempsqrx >= rqlim || tempsqry >= rqlim) return(1); old = new; return(0); } int near fpANDbailout(void) { tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; if(tempsqrx >= rqlim && tempsqry >= rqlim) return(1); old = new; return(0); } int near fpMANHbailout(void) { double manhmag; tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; manhmag = fabs(new.x) + fabs(new.y); if((manhmag * manhmag) >= rqlim) return(1); old = new; return(0); } int near fpMANRbailout(void) { double manrmag; tempsqrx=sqr(new.x); tempsqry=sqr(new.y); magnitude = tempsqrx + tempsqry; manrmag = new.x + new.y; /* don't need abs() since we square it next */ if((manrmag * manrmag) >= rqlim) return(1); old = new; return(0); } #define FLOATTRIGBAILOUT() \ if (fabs(old.y) >= rqlim2) return(1); #define LONGTRIGBAILOUT() \ if(labs(lold.y) >= llimit2) { return(1);} #define LONGXYTRIGBAILOUT() \ if(labs(lold.x) >= llimit2 || labs(lold.y) >= llimit2)\ { return(1);} #define FLOATXYTRIGBAILOUT() \ if (fabs(old.x) >= rqlim2 || fabs(old.y) >= rqlim2) return(1); #define FLOATHTRIGBAILOUT() \ if (fabs(old.x) >= rqlim2) return(1); #define LONGHTRIGBAILOUT() \ if(labs(lold.x) >= llimit2) { return(1);} #define TRIG16CHECK(X) \ if(labs((X)) > l16triglim) { return(1);} #define OLD_FLOATEXPBAILOUT() \ if (fabs(old.y) >= 1.0e8) return(1);\ if (fabs(old.x) >= 6.4e2) return(1); #define FLOATEXPBAILOUT() \ if (fabs(old.y) >= 1.0e3) return(1);\ if (fabs(old.x) >= 8) return(1); #define LONGEXPBAILOUT() \ if (labs(lold.y) >= (1000L<= (8L< l16triglim)\ {\ double tmp;\ tmp = (X);\ tmp /= fudge;\ tmp = fmod(tmp,twopi);\ tmp *= fudge;\ (X) = (long)tmp;\ }\ static int near Halleybailout(void) { if ( fabs(modulus(new)-modulus(old)) < parm2.x) return(1); old = new; return(0); } #ifndef XFRACT #define MPCmod(m) (*pMPadd(*pMPmul((m).x, (m).x), *pMPmul((m).y, (m).y))) struct MPC mpcold, mpcnew, mpctmp, mpctmp1; struct MP mptmpparm2x; #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif static int near MPCHalleybailout(void) { static struct MP mptmpbailout; mptmpbailout = *MPabs(*pMPsub(MPCmod(mpcnew), MPCmod(mpcold))); if (pMPcmp(mptmpbailout, mptmpparm2x) < 0) return(1); mpcold = mpcnew; return(0); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif #endif #ifdef XFRACT int asmlMODbailout(void) { return 0;} int asmlREALbailout(void) { return 0;} int asmlIMAGbailout(void) { return 0;} int asmlORbailout(void) { return 0;} int asmlANDbailout(void) { return 0;} int asmlMANHbailout(void) { return 0;} int asmlMANRbailout(void) { return 0;} int asm386lMODbailout(void) { return 0;} int asm386lREALbailout(void) { return 0;} int asm386lIMAGbailout(void) { return 0;} int asm386lORbailout(void) { return 0;} int asm386lANDbailout(void) { return 0;} int asm386lMANHbailout(void) { return 0;} int asm386lMANRbailout(void) { return 0;} int asmfpMODbailout(void) { return 0;} int asmfpREALbailout(void) { return 0;} int asmfpIMAGbailout(void) { return 0;} int asmfpORbailout(void) { return 0;} int asmfpANDbailout(void) { return 0;} int asmfpMANHbailout(void) { return 0;} int asmfpMANRbailout(void) { return 0;} #endif /* -------------------------------------------------------------------- */ /* Fractal (once per iteration) routines */ /* -------------------------------------------------------------------- */ static double xt, yt, t2; /* Raise complex number (base) to the (exp) power, storing the result ** in complex (result). */ void cpower(_CMPLX *base, int exp, _CMPLX *result) { if (exp<0) { cpower(base,-exp,result); CMPLXrecip(*result,*result); return; } xt = base->x; yt = base->y; if (exp & 1) { result->x = xt; result->y = yt; } else { result->x = 1.0; result->y = 0.0; } exp >>= 1; while (exp) { t2 = xt * xt - yt * yt; yt = 2 * xt * yt; xt = t2; if (exp & 1) { t2 = xt * result->x - yt * result->y; result->y = result->y * xt + yt * result->x; result->x = t2; } exp >>= 1; } } #ifndef XFRACT /* long version */ static long lxt, lyt, lt2; int lcpower(_LCMPLX *base, int exp, _LCMPLX *result, int bitshift) { static long maxarg; maxarg = 64L<x; lyt = base->y; if (exp & 1) { result->x = lxt; result->y = lyt; } else { result->x = 1L<y = 0L; } exp >>= 1; while (exp) { /* if(labs(lxt) >= maxarg || labs(lyt) >= maxarg) return(-1); */ lt2 = multiply(lxt, lxt, bitshift) - multiply(lyt,lyt,bitshift); lyt = multiply(lxt,lyt,bitshiftless1); if(overflow) return(overflow); lxt = lt2; if (exp & 1) { lt2 = multiply(lxt,result->x, bitshift) - multiply(lyt,result->y,bitshift); result->y = multiply(result->y,lxt,bitshift) + multiply(lyt,result->x,bitshift); result->x = lt2; } exp >>= 1; } if(result->x == 0 && result->y == 0) overflow = 1; return(overflow); } #if 0 int z_to_the_z(_CMPLX *z, _CMPLX *out) { static _CMPLX tmp1,tmp2; /* raises complex z to the z power */ int errno_xxx; errno_xxx = 0; if(fabs(z->x) < DBL_EPSILON) return(-1); /* log(x + iy) = 1/2(log(x*x + y*y) + i(arc_tan(y/x)) */ tmp1.x = .5*log(sqr(z->x)+sqr(z->y)); /* the fabs in next line added to prevent discontinuity in image */ tmp1.y = atan(fabs(z->y/z->x)); /* log(z)*z */ tmp2.x = tmp1.x * z->x - tmp1.y * z->y; tmp2.y = tmp1.x * z->y + tmp1.y * z->x; /* z*z = e**(log(z)*z) */ /* e**(x + iy) = e**x * (cos(y) + isin(y)) */ tmpexp = exp(tmp2.x); FPUsincos(&tmp2.y,&siny,&cosy); out->x = tmpexp*cosy; out->y = tmpexp*siny; return(errno_xxx); } #endif #endif #ifdef XFRACT /* fractint uses the NewtonFractal2 code in newton.asm */ int complex_div(_CMPLX arg1,_CMPLX arg2,_CMPLX *pz); int complex_mult(_CMPLX arg1,_CMPLX arg2,_CMPLX *pz); /* Distance of complex z from unit circle */ #define DIST1(z) (((z).x-1.0)*((z).x-1.0)+((z).y)*((z).y)) #define LDIST1(z) (lsqr((((z).x)-fudge)) + lsqr(((z).y))) int NewtonFractal2(void) { static char start=1; if(start) { start = 0; } cpower(&old, degree-1, &tmp); complex_mult(tmp, old, &new); if (DIST1(new) < threshold) { if(fractype==NEWTBASIN || fractype==MPNEWTBASIN) { long tmpcolor; int i; tmpcolor = -1; /* this code determines which degree-th root of root the Newton formula converges to. The roots of a 1 are distributed on a circle of radius 1 about the origin. */ for(i=0;ix = arg1.x*arg2.x - arg1.y*arg2.y; pz->y = arg1.x*arg2.y+arg1.y*arg2.x; return(0); } int complex_div(_CMPLX numerator,_CMPLX denominator,_CMPLX *pout) { double mod; if((mod = modulus(denominator)) < FLT_MIN) return(1); conjugate(&denominator); complex_mult(numerator,denominator,pout); pout->x = pout->x/mod; pout->y = pout->y/mod; return(0); } #endif /* newton code only used by xfractint */ #ifndef XFRACT struct MP mproverd, mpd1overd, mpthreshold; struct MP mpt2; struct MP mpone; #endif #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif int MPCNewtonFractal(void) { #ifndef XFRACT MPOverflow = 0; mpctmp = MPCpow(mpcold,degree-1); mpcnew.x = *pMPsub(*pMPmul(mpctmp.x,mpcold.x),*pMPmul(mpctmp.y,mpcold.y)); mpcnew.y = *pMPadd(*pMPmul(mpctmp.x,mpcold.y),*pMPmul(mpctmp.y,mpcold.x)); mpctmp1.x = *pMPsub(mpcnew.x, MPCone.x); mpctmp1.y = *pMPsub(mpcnew.y, MPCone.y); if(pMPcmp(MPCmod(mpctmp1),mpthreshold)< 0) { if(fractype==MPNEWTBASIN) { long tmpcolor; int i; tmpcolor = -1; for(i=0;i= 700) #pragma code_seg () /* back to normal segment */ #endif int Barnsley1Fractal(void) { #ifndef XFRACT /* Barnsley's Mandelbrot type M1 from "Fractals Everywhere" by Michael Barnsley, p. 322 */ /* calculate intermediate products */ oldxinitx = multiply(lold.x, longparm->x, bitshift); oldyinity = multiply(lold.y, longparm->y, bitshift); oldxinity = multiply(lold.x, longparm->y, bitshift); oldyinitx = multiply(lold.y, longparm->x, bitshift); /* orbit calculation */ if(lold.x >= 0) { lnew.x = (oldxinitx - longparm->x - oldyinity); lnew.y = (oldyinitx - longparm->y + oldxinity); } else { lnew.x = (oldxinitx + longparm->x - oldyinity); lnew.y = (oldyinitx + longparm->y + oldxinity); } return(longbailout()); #else return(0); #endif } int Barnsley1FPFractal(void) { /* Barnsley's Mandelbrot type M1 from "Fractals Everywhere" by Michael Barnsley, p. 322 */ /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */ /* calculate intermediate products */ foldxinitx = old.x * floatparm->x; foldyinity = old.y * floatparm->y; foldxinity = old.x * floatparm->y; foldyinitx = old.y * floatparm->x; /* orbit calculation */ if(old.x >= 0) { new.x = (foldxinitx - floatparm->x - foldyinity); new.y = (foldyinitx - floatparm->y + foldxinity); } else { new.x = (foldxinitx + floatparm->x - foldyinity); new.y = (foldyinitx + floatparm->y + foldxinity); } return(floatbailout()); } int Barnsley2Fractal(void) { #ifndef XFRACT /* An unnamed Mandelbrot/Julia function from "Fractals Everywhere" by Michael Barnsley, p. 331, example 4.2 */ /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */ /* calculate intermediate products */ oldxinitx = multiply(lold.x, longparm->x, bitshift); oldyinity = multiply(lold.y, longparm->y, bitshift); oldxinity = multiply(lold.x, longparm->y, bitshift); oldyinitx = multiply(lold.y, longparm->x, bitshift); /* orbit calculation */ if(oldxinity + oldyinitx >= 0) { lnew.x = oldxinitx - longparm->x - oldyinity; lnew.y = oldyinitx - longparm->y + oldxinity; } else { lnew.x = oldxinitx + longparm->x - oldyinity; lnew.y = oldyinitx + longparm->y + oldxinity; } return(longbailout()); #else return(0); #endif } int Barnsley2FPFractal(void) { /* An unnamed Mandelbrot/Julia function from "Fractals Everywhere" by Michael Barnsley, p. 331, example 4.2 */ /* calculate intermediate products */ foldxinitx = old.x * floatparm->x; foldyinity = old.y * floatparm->y; foldxinity = old.x * floatparm->y; foldyinitx = old.y * floatparm->x; /* orbit calculation */ if(foldxinity + foldyinitx >= 0) { new.x = foldxinitx - floatparm->x - foldyinity; new.y = foldyinitx - floatparm->y + foldxinity; } else { new.x = foldxinitx + floatparm->x - foldyinity; new.y = foldyinitx + floatparm->y + foldxinity; } return(floatbailout()); } int JuliaFractal(void) { #ifndef XFRACT /* used for C prototype of fast integer math routines for classic Mandelbrot and Julia */ lnew.x = ltempsqrx - ltempsqry + longparm->x; lnew.y = multiply(lold.x, lold.y, bitshiftless1) + longparm->y; return(longbailout()); #elif !defined(__386BSD__) fprintf(stderr,"JuliaFractal called\n"); exit(-1); #endif } int JuliafpFractal(void) { /* floating point version of classical Mandelbrot/Julia */ /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */ new.x = tempsqrx - tempsqry + floatparm->x; new.y = 2.0 * old.x * old.y + floatparm->y; return(floatbailout()); } int LambdaFPFractal(void) { /* variation of classical Mandelbrot/Julia */ /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */ tempsqrx = old.x - tempsqrx + tempsqry; tempsqry = -(old.y * old.x); tempsqry += tempsqry + old.y; new.x = floatparm->x * tempsqrx - floatparm->y * tempsqry; new.y = floatparm->x * tempsqry + floatparm->y * tempsqrx; return(floatbailout()); } int LambdaFractal(void) { #ifndef XFRACT /* variation of classical Mandelbrot/Julia */ /* in complex math) temp = Z * (1-Z) */ ltempsqrx = lold.x - ltempsqrx + ltempsqry; ltempsqry = lold.y - multiply(lold.y, lold.x, bitshiftless1); /* (in complex math) Z = Lambda * Z */ lnew.x = multiply(longparm->x, ltempsqrx, bitshift) - multiply(longparm->y, ltempsqry, bitshift); lnew.y = multiply(longparm->x, ltempsqry, bitshift) + multiply(longparm->y, ltempsqrx, bitshift); return(longbailout()); #else return(0); #endif } int SierpinskiFractal(void) { #ifndef XFRACT /* following code translated from basic - see "Fractals Everywhere" by Michael Barnsley, p. 251, Program 7.1.1 */ lnew.x = (lold.x << 1); /* new.x = 2 * old.x */ lnew.y = (lold.y << 1); /* new.y = 2 * old.y */ if(lold.y > ltmp.y) /* if old.y > .5 */ lnew.y = lnew.y - ltmp.x; /* new.y = 2 * old.y - 1 */ else if(lold.x > ltmp.y) /* if old.x > .5 */ lnew.x = lnew.x - ltmp.x; /* new.x = 2 * old.x - 1 */ /* end barnsley code */ return(longbailout()); #else return(0); #endif } int SierpinskiFPFractal(void) { /* following code translated from basic - see "Fractals Everywhere" by Michael Barnsley, p. 251, Program 7.1.1 */ new.x = old.x + old.x; new.y = old.y + old.y; if(old.y > .5) new.y = new.y - 1; else if (old.x > .5) new.x = new.x - 1; /* end barnsley code */ return(floatbailout()); } int LambdaexponentFractal(void) { /* found this in "Science of Fractal Images" */ if (save_release > 2002) { /* need braces since these are macros */ FLOATEXPBAILOUT(); } else { OLD_FLOATEXPBAILOUT(); } FPUsincos (&old.y,&siny,&cosy); if (old.x >= rqlim && cosy >= 0.0) return(1); tmpexp = exp(old.x); tmp.x = tmpexp*cosy; tmp.y = tmpexp*siny; /*multiply by lamda */ new.x = floatparm->x*tmp.x - floatparm->y*tmp.y; new.y = floatparm->y*tmp.x + floatparm->x*tmp.y; old = new; return(0); } int LongLambdaexponentFractal(void) { #ifndef XFRACT /* found this in "Science of Fractal Images" */ LONGEXPBAILOUT(); SinCos086 (lold.y, &lsiny, &lcosy); if (lold.x >= llimit && lcosy >= 0L) return(1); longtmp = Exp086(lold.x); ltmp.x = multiply(longtmp, lcosy, bitshift); ltmp.y = multiply(longtmp, lsiny, bitshift); lnew.x = multiply(longparm->x, ltmp.x, bitshift) - multiply(longparm->y, ltmp.y, bitshift); lnew.y = multiply(longparm->x, ltmp.y, bitshift) + multiply(longparm->y, ltmp.x, bitshift); lold = lnew; return(0); #else return(0); #endif } int FloatTrigPlusExponentFractal(void) { /* another Scientific American biomorph type */ /* z(n+1) = e**z(n) + trig(z(n)) + C */ if (fabs(old.x) >= 6.4e2) return(1); /* DOMAIN errors */ tmpexp = exp(old.x); FPUsincos (&old.y,&siny,&cosy); CMPLXtrig0(old,new); /*new = trig(old) + e**old + C */ new.x += tmpexp*cosy + floatparm->x; new.y += tmpexp*siny + floatparm->y; return(floatbailout()); } int LongTrigPlusExponentFractal(void) { #ifndef XFRACT /* calculate exp(z) */ /* domain check for fast transcendental functions */ TRIG16CHECK(lold.x); TRIG16CHECK(lold.y); longtmp = Exp086(lold.x); SinCos086 (lold.y, &lsiny, &lcosy); LCMPLXtrig0(lold,lnew); lnew.x += multiply(longtmp, lcosy, bitshift) + longparm->x; lnew.y += multiply(longtmp, lsiny, bitshift) + longparm->y; return(longbailout()); #else return(0); #endif } int MarksLambdaFractal(void) { /* Mark Peterson's variation of "lambda" function */ /* Z1 = (C^(exp-1) * Z**2) + C */ #ifndef XFRACT ltmp.x = ltempsqrx - ltempsqry; ltmp.y = multiply(lold.x ,lold.y ,bitshiftless1); lnew.x = multiply(lcoefficient.x, ltmp.x, bitshift) - multiply(lcoefficient.y, ltmp.y, bitshift) + longparm->x; lnew.y = multiply(lcoefficient.x, ltmp.y, bitshift) + multiply(lcoefficient.y, ltmp.x, bitshift) + longparm->y; return(longbailout()); #else return(0); #endif } int MarksLambdafpFractal(void) { /* Mark Peterson's variation of "lambda" function */ /* Z1 = (C^(exp-1) * Z**2) + C */ tmp.x = tempsqrx - tempsqry; tmp.y = old.x * old.y *2; new.x = coefficient.x * tmp.x - coefficient.y * tmp.y + floatparm->x; new.y = coefficient.x * tmp.y + coefficient.y * tmp.x + floatparm->y; return(floatbailout()); } long XXOne, FgOne, FgTwo; int UnityFractal(void) { #ifndef XFRACT /* brought to you by Mark Peterson - you won't find this in any fractal books unless they saw it here first - Mark invented it! */ XXOne = multiply(lold.x, lold.x, bitshift) + multiply(lold.y, lold.y, bitshift); if((XXOne > FgTwo) || (labs(XXOne - FgOne) < delmin)) return(1); lold.y = multiply(FgTwo - XXOne, lold.x, bitshift); lold.x = multiply(FgTwo - XXOne, lold.y, bitshift); lnew=lold; /* TW added this line */ return(0); #else return(0); #endif } int UnityfpFractal(void) { double XXOne; /* brought to you by Mark Peterson - you won't find this in any fractal books unless they saw it here first - Mark invented it! */ XXOne = sqr(old.x) + sqr(old.y); if((XXOne > 2.0) || (fabs(XXOne - 1.0) < ddelmin)) return(1); old.y = (2.0 - XXOne)* old.x; old.x = (2.0 - XXOne)* old.y; new=old; /* TW added this line */ return(0); } int Mandel4Fractal(void) { /* By writing this code, Bert has left behind the excuse "don't know what a fractal is, just know how to make'em go fast". Bert is hereby declared a bonafide fractal expert! Supposedly this routine calculates the Mandelbrot/Julia set based on the polynomial z**4 + lambda, but I wouldn't know -- can't follow all that integer math speedup stuff - Tim */ /* first, compute (x + iy)**2 */ #ifndef XFRACT lnew.x = ltempsqrx - ltempsqry; lnew.y = multiply(lold.x, lold.y, bitshiftless1); if (longbailout()) return(1); /* then, compute ((x + iy)**2)**2 + lambda */ lnew.x = ltempsqrx - ltempsqry + longparm->x; lnew.y = multiply(lold.x, lold.y, bitshiftless1) + longparm->y; return(longbailout()); #else return(0); #endif } int Mandel4fpFractal(void) { /* first, compute (x + iy)**2 */ new.x = tempsqrx - tempsqry; new.y = old.x*old.y*2; if (floatbailout()) return(1); /* then, compute ((x + iy)**2)**2 + lambda */ new.x = tempsqrx - tempsqry + floatparm->x; new.y = old.x*old.y*2 + floatparm->y; return(floatbailout()); } int floatZtozPluszpwrFractal(void) { cpower(&old,(int)param[2],&new); old = ComplexPower(old,old); new.x = new.x + old.x +floatparm->x; new.y = new.y + old.y +floatparm->y; return(floatbailout()); } int longZpowerFractal(void) { #ifndef XFRACT if(lcpower(&lold,c_exp,&lnew,bitshift)) lnew.x = lnew.y = 8L<x; lnew.y += longparm->y; return(longbailout()); #else return(0); #endif } int longCmplxZpowerFractal(void) { #ifndef XFRACT _CMPLX x, y; x.x = (double)lold.x / fudge; x.y = (double)lold.y / fudge; y.x = (double)lparm2.x / fudge; y.y = (double)lparm2.y / fudge; x = ComplexPower(x, y); if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) { lnew.x = (long)(x.x * fudge); lnew.y = (long)(x.y * fudge); } else overflow = 1; lnew.x += longparm->x; lnew.y += longparm->y; return(longbailout()); #else return(0); #endif } int floatZpowerFractal(void) { cpower(&old,c_exp,&new); new.x += floatparm->x; new.y += floatparm->y; return(floatbailout()); } int floatCmplxZpowerFractal(void) { new = ComplexPower(old, parm2); new.x += floatparm->x; new.y += floatparm->y; return(floatbailout()); } int Barnsley3Fractal(void) { /* An unnamed Mandelbrot/Julia function from "Fractals Everywhere" by Michael Barnsley, p. 292, example 4.1 */ /* calculate intermediate products */ #ifndef XFRACT oldxinitx = multiply(lold.x, lold.x, bitshift); oldyinity = multiply(lold.y, lold.y, bitshift); oldxinity = multiply(lold.x, lold.y, bitshift); /* orbit calculation */ if(lold.x > 0) { lnew.x = oldxinitx - oldyinity - fudge; lnew.y = oldxinity << 1; } else { lnew.x = oldxinitx - oldyinity - fudge + multiply(longparm->x,lold.x,bitshift); lnew.y = oldxinity <<1; /* This term added by Tim Wegner to make dependent on the imaginary part of the parameter. (Otherwise Mandelbrot is uninteresting. */ lnew.y += multiply(longparm->y,lold.x,bitshift); } return(longbailout()); #else return(0); #endif } int Barnsley3FPFractal(void) { /* An unnamed Mandelbrot/Julia function from "Fractals Everywhere" by Michael Barnsley, p. 292, example 4.1 */ /* calculate intermediate products */ foldxinitx = old.x * old.x; foldyinity = old.y * old.y; foldxinity = old.x * old.y; /* orbit calculation */ if(old.x > 0) { new.x = foldxinitx - foldyinity - 1.0; new.y = foldxinity * 2; } else { new.x = foldxinitx - foldyinity -1.0 + floatparm->x * old.x; new.y = foldxinity * 2; /* This term added by Tim Wegner to make dependent on the imaginary part of the parameter. (Otherwise Mandelbrot is uninteresting. */ new.y += floatparm->y * old.x; } return(floatbailout()); } int TrigPlusZsquaredFractal(void) { #ifndef XFRACT /* From Scientific American, July 1989 */ /* A Biomorph */ /* z(n+1) = trig(z(n))+z(n)**2+C */ LCMPLXtrig0(lold,lnew); lnew.x += ltempsqrx - ltempsqry + longparm->x; lnew.y += multiply(lold.x, lold.y, bitshiftless1) + longparm->y; return(longbailout()); #else return(0); #endif } int TrigPlusZsquaredfpFractal(void) { /* From Scientific American, July 1989 */ /* A Biomorph */ /* z(n+1) = trig(z(n))+z(n)**2+C */ CMPLXtrig0(old,new); new.x += tempsqrx - tempsqry + floatparm->x; new.y += 2.0 * old.x * old.y + floatparm->y; return(floatbailout()); } int Richard8fpFractal(void) { /* Richard8 {c = z = pixel: z=sin(z)+sin(pixel),|z|<=50} */ CMPLXtrig0(old,new); /* CMPLXtrig1(*floatparm,tmp); */ new.x += tmp.x; new.y += tmp.y; return(floatbailout()); } int Richard8Fractal(void) { #ifndef XFRACT /* Richard8 {c = z = pixel: z=sin(z)+sin(pixel),|z|<=50} */ LCMPLXtrig0(lold,lnew); /* LCMPLXtrig1(*longparm,ltmp); */ lnew.x += ltmp.x; lnew.y += ltmp.y; return(longbailout()); #else return(0); #endif } int PopcornFractal_Old(void) { tmp = old; tmp.x *= 3.0; tmp.y *= 3.0; FPUsincos(&tmp.x,&sinx,&cosx); FPUsincos(&tmp.y,&siny,&cosy); tmp.x = sinx/cosx + old.x; tmp.y = siny/cosy + old.y; FPUsincos(&tmp.x,&sinx,&cosx); FPUsincos(&tmp.y,&siny,&cosy); new.x = old.x - parm.x*siny; new.y = old.y - parm.x*sinx; /* new.x = old.x - parm.x*sin(old.y+tan(3*old.y)); new.y = old.y - parm.x*sin(old.x+tan(3*old.x)); */ if(plot == noplot) { plot_orbit(new.x,new.y,1+row%colors); old = new; } else /* FLOATBAILOUT(); */ /* PB The above line was weird, not what it seems to be! But, bracketing it or always doing it (either of which seem more likely to be what was intended) changes the image for the worse, so I'm not touching it. Same applies to int form in next routine. */ /* PB later: recoded inline, still leaving it weird */ tempsqrx = sqr(new.x); tempsqry = sqr(new.y); if((magnitude = tempsqrx + tempsqry) >= rqlim) return(1); old = new; return(0); } int PopcornFractal(void) { tmp = old; tmp.x *= 3.0; tmp.y *= 3.0; FPUsincos(&tmp.x,&sinx,&cosx); FPUsincos(&tmp.y,&siny,&cosy); tmp.x = sinx/cosx + old.x; tmp.y = siny/cosy + old.y; FPUsincos(&tmp.x,&sinx,&cosx); FPUsincos(&tmp.y,&siny,&cosy); new.x = old.x - parm.x*siny; new.y = old.y - parm.x*sinx; /* new.x = old.x - parm.x*sin(old.y+tan(3*old.y)); new.y = old.y - parm.x*sin(old.x+tan(3*old.x)); */ if(plot == noplot) { plot_orbit(new.x,new.y,1+row%colors); old = new; } /* else */ /* FLOATBAILOUT(); */ /* PB The above line was weird, not what it seems to be! But, bracketing it or always doing it (either of which seem more likely to be what was intended) changes the image for the worse, so I'm not touching it. Same applies to int form in next routine. */ /* PB later: recoded inline, still leaving it weird */ /* JCO: sqr's should always be done, else magnitude could be wrong */ tempsqrx = sqr(new.x); tempsqry = sqr(new.y); if((magnitude = tempsqrx + tempsqry) >= rqlim || fabs(new.x) > rqlim2 || fabs(new.y) > rqlim2 ) return(1); old = new; return(0); } int LPopcornFractal_Old(void) { #ifndef XFRACT ltmp = lold; ltmp.x *= 3L; ltmp.y *= 3L; LTRIGARG(ltmp.x); LTRIGARG(ltmp.y); SinCos086(ltmp.x,&lsinx,&lcosx); SinCos086(ltmp.y,&lsiny,&lcosy); ltmp.x = divide(lsinx,lcosx,bitshift) + lold.x; ltmp.y = divide(lsiny,lcosy,bitshift) + lold.y; LTRIGARG(ltmp.x); LTRIGARG(ltmp.y); SinCos086(ltmp.x,&lsinx,&lcosx); SinCos086(ltmp.y,&lsiny,&lcosy); lnew.x = lold.x - multiply(lparm.x,lsiny,bitshift); lnew.y = lold.y - multiply(lparm.x,lsinx,bitshift); if(plot == noplot) { iplot_orbit(lnew.x,lnew.y,1+row%colors); lold = lnew; } else /* LONGBAILOUT(); */ /* PB above still the old way, is weird, see notes in FP popcorn case */ { ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y); } lmagnitud = ltempsqrx + ltempsqry; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2 || labs(lnew.y) > llimit2) return(1); lold = lnew; return(0); #else return(0); #endif } int LPopcornFractal(void) { #ifndef XFRACT ltmp = lold; ltmp.x *= 3L; ltmp.y *= 3L; LTRIGARG(ltmp.x); LTRIGARG(ltmp.y); SinCos086(ltmp.x,&lsinx,&lcosx); SinCos086(ltmp.y,&lsiny,&lcosy); ltmp.x = divide(lsinx,lcosx,bitshift) + lold.x; ltmp.y = divide(lsiny,lcosy,bitshift) + lold.y; LTRIGARG(ltmp.x); LTRIGARG(ltmp.y); SinCos086(ltmp.x,&lsinx,&lcosx); SinCos086(ltmp.y,&lsiny,&lcosy); lnew.x = lold.x - multiply(lparm.x,lsiny,bitshift); lnew.y = lold.y - multiply(lparm.x,lsinx,bitshift); if(plot == noplot) { iplot_orbit(lnew.x,lnew.y,1+row%colors); lold = lnew; } /* else */ /* JCO: sqr's should always be done, else magnitude could be wrong */ ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y); lmagnitud = ltempsqrx + ltempsqry; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2 || labs(lnew.y) > llimit2) return(1); lold = lnew; return(0); #else return(0); #endif } /* Popcorn generalization proposed by HB */ int PopcornFractalFn(void) { _CMPLX tmpx; _CMPLX tmpy; /* tmpx contains the generalized value of the old real "x" equation */ CMPLXtimesreal(parm2,old.y,tmp); /* tmp = (C * old.y) */ CMPLXtrig1(tmp,tmpx); /* tmpx = trig1(tmp) */ tmpx.x += old.y; /* tmpx = old.y + trig1(tmp) */ CMPLXtrig0(tmpx,tmp); /* tmp = trig0(tmpx) */ CMPLXmult(tmp,parm,tmpx); /* tmpx = tmp * h */ /* tmpy contains the generalized value of the old real "y" equation */ CMPLXtimesreal(parm2,old.x,tmp); /* tmp = (C * old.x) */ CMPLXtrig3(tmp,tmpy); /* tmpy = trig3(tmp) */ tmpy.x += old.x; /* tmpy = old.x + trig1(tmp) */ CMPLXtrig2(tmpy,tmp); /* tmp = trig2(tmpy) */ CMPLXmult(tmp,parm,tmpy); /* tmpy = tmp * h */ new.x = old.x - tmpx.x - tmpy.y; new.y = old.y - tmpy.x - tmpx.y; if(plot == noplot) { plot_orbit(new.x,new.y,1+row%colors); old = new; } tempsqrx = sqr(new.x); tempsqry = sqr(new.y); if((magnitude = tempsqrx + tempsqry) >= rqlim || fabs(new.x) > rqlim2 || fabs(new.y) > rqlim2 ) return(1); old = new; return(0); } #define FIX_OVERFLOW(arg) if(overflow) \ { \ (arg).x = fudge;\ (arg).y = 0;\ overflow = 0;\ } int LPopcornFractalFn(void) { #ifndef XFRACT _LCMPLX ltmpx, ltmpy; overflow = 0; /* ltmpx contains the generalized value of the old real "x" equation */ LCMPLXtimesreal(lparm2,lold.y,ltmp); /* tmp = (C * old.y) */ LCMPLXtrig1(ltmp,ltmpx); /* tmpx = trig1(tmp) */ FIX_OVERFLOW(ltmpx); ltmpx.x += lold.y; /* tmpx = old.y + trig1(tmp) */ LCMPLXtrig0(ltmpx,ltmp); /* tmp = trig0(tmpx) */ FIX_OVERFLOW(ltmp); LCMPLXmult(ltmp,lparm,ltmpx); /* tmpx = tmp * h */ /* ltmpy contains the generalized value of the old real "y" equation */ LCMPLXtimesreal(lparm2,lold.x,ltmp); /* tmp = (C * old.x) */ LCMPLXtrig3(ltmp,ltmpy); /* tmpy = trig3(tmp) */ FIX_OVERFLOW(ltmpy); ltmpy.x += lold.x; /* tmpy = old.x + trig1(tmp) */ LCMPLXtrig2(ltmpy,ltmp); /* tmp = trig2(tmpy) */ FIX_OVERFLOW(ltmp); LCMPLXmult(ltmp,lparm,ltmpy); /* tmpy = tmp * h */ lnew.x = lold.x - ltmpx.x - ltmpy.y; lnew.y = lold.y - ltmpy.x - ltmpx.y; if(plot == noplot) { iplot_orbit(lnew.x,lnew.y,1+row%colors); lold = lnew; } ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y); lmagnitud = ltempsqrx + ltempsqry; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2 || labs(lnew.y) > llimit2) return(1); lold = lnew; return(0); #else return(0); #endif } int MarksCplxMand(void) { tmp.x = tempsqrx - tempsqry; tmp.y = 2*old.x*old.y; FPUcplxmul(&tmp, &coefficient, &new); new.x += floatparm->x; new.y += floatparm->y; return(floatbailout()); } int SpiderfpFractal(void) { /* Spider(XAXIS) { c=z=pixel: z=z*z+c; c=c/2+z, |z|<=4 } */ new.x = tempsqrx - tempsqry + tmp.x; new.y = 2 * old.x * old.y + tmp.y; tmp.x = tmp.x/2 + new.x; tmp.y = tmp.y/2 + new.y; return(floatbailout()); } int SpiderFractal(void) { #ifndef XFRACT /* Spider(XAXIS) { c=z=pixel: z=z*z+c; c=c/2+z, |z|<=4 } */ lnew.x = ltempsqrx - ltempsqry + ltmp.x; lnew.y = multiply(lold.x, lold.y, bitshiftless1) + ltmp.y; ltmp.x = (ltmp.x >> 1) + lnew.x; ltmp.y = (ltmp.y >> 1) + lnew.y; return(longbailout()); #else return(0); #endif } int TetratefpFractal(void) { /* Tetrate(XAXIS) { c=z=pixel: z=c^z, |z|<=(P1+3) } */ new = ComplexPower(*floatparm,old); return(floatbailout()); } int ZXTrigPlusZFractal(void) { #ifndef XFRACT /* z = (p1*z*trig(z))+p2*z */ LCMPLXtrig0(lold,ltmp); /* ltmp = trig(old) */ LCMPLXmult(lparm,ltmp,ltmp); /* ltmp = p1*trig(old) */ LCMPLXmult(lold,ltmp,ltmp2); /* ltmp2 = p1*old*trig(old) */ LCMPLXmult(lparm2,lold,ltmp); /* ltmp = p2*old */ LCMPLXadd(ltmp2,ltmp,lnew); /* lnew = p1*trig(old) + p2*old */ return(longbailout()); #else return(0); #endif } int ScottZXTrigPlusZFractal(void) { #ifndef XFRACT /* z = (z*trig(z))+z */ LCMPLXtrig0(lold,ltmp); /* ltmp = trig(old) */ LCMPLXmult(lold,ltmp,lnew); /* lnew = old*trig(old) */ LCMPLXadd(lnew,lold,lnew); /* lnew = trig(old) + old */ return(longbailout()); #else return(0); #endif } int SkinnerZXTrigSubZFractal(void) { #ifndef XFRACT /* z = (z*trig(z))-z */ LCMPLXtrig0(lold,ltmp); /* ltmp = trig(old) */ LCMPLXmult(lold,ltmp,lnew); /* lnew = old*trig(old) */ LCMPLXsub(lnew,lold,lnew); /* lnew = trig(old) - old */ return(longbailout()); #else return(0); #endif } int ZXTrigPlusZfpFractal(void) { /* z = (p1*z*trig(z))+p2*z */ CMPLXtrig0(old,tmp); /* tmp = trig(old) */ CMPLXmult(parm,tmp,tmp); /* tmp = p1*trig(old) */ CMPLXmult(old,tmp,tmp2); /* tmp2 = p1*old*trig(old) */ CMPLXmult(parm2,old,tmp); /* tmp = p2*old */ CMPLXadd(tmp2,tmp,new); /* new = p1*trig(old) + p2*old */ return(floatbailout()); } int ScottZXTrigPlusZfpFractal(void) { /* z = (z*trig(z))+z */ CMPLXtrig0(old,tmp); /* tmp = trig(old) */ CMPLXmult(old,tmp,new); /* new = old*trig(old) */ CMPLXadd(new,old,new); /* new = trig(old) + old */ return(floatbailout()); } int SkinnerZXTrigSubZfpFractal(void) { /* z = (z*trig(z))-z */ CMPLXtrig0(old,tmp); /* tmp = trig(old) */ CMPLXmult(old,tmp,new); /* new = old*trig(old) */ CMPLXsub(new,old,new); /* new = trig(old) - old */ return(floatbailout()); } int Sqr1overTrigFractal(void) { #ifndef XFRACT /* z = sqr(1/trig(z)) */ LCMPLXtrig0(lold,lold); LCMPLXrecip(lold,lold); LCMPLXsqr(lold,lnew); return(longbailout()); #else return(0); #endif } int Sqr1overTrigfpFractal(void) { /* z = sqr(1/trig(z)) */ CMPLXtrig0(old,old); CMPLXrecip(old,old); CMPLXsqr(old,new); return(floatbailout()); } int TrigPlusTrigFractal(void) { #ifndef XFRACT /* z = trig(0,z)*p1+trig1(z)*p2 */ LCMPLXtrig0(lold,ltmp); LCMPLXmult(lparm,ltmp,ltmp); LCMPLXtrig1(lold,ltmp2); LCMPLXmult(lparm2,ltmp2,lold); LCMPLXadd(ltmp,lold,lnew); return(longbailout()); #else return(0); #endif } int TrigPlusTrigfpFractal(void) { /* z = trig0(z)*p1+trig1(z)*p2 */ CMPLXtrig0(old,tmp); CMPLXmult(parm,tmp,tmp); CMPLXtrig1(old,old); CMPLXmult(parm2,old,old); CMPLXadd(tmp,old,new); return(floatbailout()); } /* The following four fractals are based on the idea of parallel or alternate calculations. The shift is made when the mod reaches a given value. JCO 5/6/92 */ int LambdaTrigOrTrigFractal(void) { #ifndef XFRACT /* z = trig0(z)*p1 if mod(old) < p2.x and trig1(z)*p1 if mod(old) >= p2.x */ if ((LCMPLXmod(lold)) < lparm2.x){ LCMPLXtrig0(lold,ltmp); LCMPLXmult(*longparm,ltmp,lnew);} else{ LCMPLXtrig1(lold,ltmp); LCMPLXmult(*longparm,ltmp,lnew);} return(longbailout()); #else return(0); #endif } int LambdaTrigOrTrigfpFractal(void) { /* z = trig0(z)*p1 if mod(old) < p2.x and trig1(z)*p1 if mod(old) >= p2.x */ if (CMPLXmod(old) < parm2.x){ CMPLXtrig0(old,old); FPUcplxmul(floatparm,&old,&new);} else{ CMPLXtrig1(old,old); FPUcplxmul(floatparm,&old,&new);} return(floatbailout()); } int JuliaTrigOrTrigFractal(void) { #ifndef XFRACT /* z = trig0(z)+p1 if mod(old) < p2.x and trig1(z)+p1 if mod(old) >= p2.x */ if (LCMPLXmod(lold) < lparm2.x){ LCMPLXtrig0(lold,ltmp); LCMPLXadd(*longparm,ltmp,lnew);} else{ LCMPLXtrig1(lold,ltmp); LCMPLXadd(*longparm,ltmp,lnew);} return(longbailout()); #else return(0); #endif } int JuliaTrigOrTrigfpFractal(void) { /* z = trig0(z)+p1 if mod(old) < p2.x and trig1(z)+p1 if mod(old) >= p2.x */ if (CMPLXmod(old) < parm2.x){ CMPLXtrig0(old,old); CMPLXadd(*floatparm,old,new);} else{ CMPLXtrig1(old,old); CMPLXadd(*floatparm,old,new);} return(floatbailout()); } int AplusOne, Ap1deg; struct MP mpAplusOne, mpAp1deg; struct MPC mpctmpparm; #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif int MPCHalleyFractal(void) { #ifndef XFRACT /* X(X^a - 1) = 0, Halley Map */ /* a = parm.x, relaxation coeff. = parm.y, epsilon = parm2.x */ int ihal; struct MPC mpcXtoAlessOne, mpcXtoA; struct MPC mpcXtoAplusOne; /* a-1, a, a+1 */ struct MPC mpcFX, mpcF1prime, mpcF2prime, mpcHalnumer1; struct MPC mpcHalnumer2, mpcHaldenom, mpctmp; MPOverflow = 0; mpcXtoAlessOne.x = mpcold.x; mpcXtoAlessOne.y = mpcold.y; for(ihal=2; ihal= 700) #pragma code_seg () /* back to normal segment */ #endif int HalleyFractal(void) { /* X(X^a - 1) = 0, Halley Map */ /* a = parm.x = degree, relaxation coeff. = parm.y, epsilon = parm2.x */ int ihal; _CMPLX XtoAlessOne, XtoA, XtoAplusOne; /* a-1, a, a+1 */ _CMPLX FX, F1prime, F2prime, Halnumer1, Halnumer2, Haldenom; _CMPLX relax; XtoAlessOne = old; for(ihal=2; ihalx+multiply(longparm->y,ltmp2.x,bitshift); lnew.y = (ltmp.x + ltmp.x) + multiply(longparm->y,ltmp2.y,bitshift); ltmp2 = lold; /* set ltmp2 to Y value */ return(longbailout()); #else return(0); #endif } int PhoenixFractal(void) { /* z(n+1) = z(n)^2 + p + qy(n), y(n+1) = z(n) */ tmp.x = old.x * old.y; new.x = tempsqrx - tempsqry + floatparm->x + (floatparm->y * tmp2.x); new.y = (tmp.x + tmp.x) + (floatparm->y * tmp2.y); tmp2 = old; /* set tmp2 to Y value */ return(floatbailout()); } int LongPhoenixFractalcplx(void) { #ifndef XFRACT /* z(n+1) = z(n)^2 + p + qy(n), y(n+1) = z(n) */ ltmp.x = multiply(lold.x, lold.y, bitshift); lnew.x = ltempsqrx-ltempsqry+longparm->x+multiply(lparm2.x,ltmp2.x,bitshift)-multiply(lparm2.y,ltmp2.y,bitshift); lnew.y = (ltmp.x + ltmp.x)+longparm->y+multiply(lparm2.x,ltmp2.y,bitshift)+multiply(lparm2.y,ltmp2.x,bitshift); ltmp2 = lold; /* set ltmp2 to Y value */ return(longbailout()); #else return(0); #endif } int PhoenixFractalcplx(void) { /* z(n+1) = z(n)^2 + p1 + p2*y(n), y(n+1) = z(n) */ tmp.x = old.x * old.y; new.x = tempsqrx - tempsqry + floatparm->x + (parm2.x * tmp2.x) - (parm2.y * tmp2.y); new.y = (tmp.x + tmp.x) + floatparm->y + (parm2.x * tmp2.y) + (parm2.y * tmp2.x); tmp2 = old; /* set tmp2 to Y value */ return(floatbailout()); } int LongPhoenixPlusFractal(void) { #ifndef XFRACT /* z(n+1) = z(n)^(degree-1) * (z(n) + p) + qy(n), y(n+1) = z(n) */ int i; _LCMPLX loldplus, lnewminus; loldplus = lold; ltmp = lold; for(i=1; i= 2, degree=degree-1 in setup */ LCMPLXmult(lold,ltmp,ltmp); /* = old^(degree-1) */ } loldplus.x += longparm->x; LCMPLXmult(ltmp, loldplus, lnewminus); lnew.x = lnewminus.x + multiply(longparm->y,ltmp2.x,bitshift); lnew.y = lnewminus.y + multiply(longparm->y,ltmp2.y,bitshift); ltmp2 = lold; /* set ltmp2 to Y value */ return(longbailout()); #else return(0); #endif } int PhoenixPlusFractal(void) { /* z(n+1) = z(n)^(degree-1) * (z(n) + p) + qy(n), y(n+1) = z(n) */ int i; _CMPLX oldplus, newminus; oldplus = old; tmp = old; for(i=1; i= 2, degree=degree-1 in setup */ FPUcplxmul(&old, &tmp, &tmp); /* = old^(degree-1) */ } oldplus.x += floatparm->x; FPUcplxmul(&tmp, &oldplus, &newminus); new.x = newminus.x + (floatparm->y * tmp2.x); new.y = newminus.y + (floatparm->y * tmp2.y); tmp2 = old; /* set tmp2 to Y value */ return(floatbailout()); } int LongPhoenixMinusFractal(void) { #ifndef XFRACT /* z(n+1) = z(n)^(degree-2) * (z(n)^2 + p) + qy(n), y(n+1) = z(n) */ int i; _LCMPLX loldsqr, lnewminus; LCMPLXmult(lold,lold,loldsqr); ltmp = lold; for(i=1; i= 3, degree=degree-2 in setup */ LCMPLXmult(lold,ltmp,ltmp); /* = old^(degree-2) */ } loldsqr.x += longparm->x; LCMPLXmult(ltmp, loldsqr, lnewminus); lnew.x = lnewminus.x + multiply(longparm->y,ltmp2.x,bitshift); lnew.y = lnewminus.y + multiply(longparm->y,ltmp2.y,bitshift); ltmp2 = lold; /* set ltmp2 to Y value */ return(longbailout()); #else return(0); #endif } int PhoenixMinusFractal(void) { /* z(n+1) = z(n)^(degree-2) * (z(n)^2 + p) + qy(n), y(n+1) = z(n) */ int i; _CMPLX oldsqr, newminus; FPUcplxmul(&old, &old, &oldsqr); tmp = old; for(i=1; i= 3, degree=degree-2 in setup */ FPUcplxmul(&old, &tmp, &tmp); /* = old^(degree-2) */ } oldsqr.x += floatparm->x; FPUcplxmul(&tmp, &oldsqr, &newminus); new.x = newminus.x + (floatparm->y * tmp2.x); new.y = newminus.y + (floatparm->y * tmp2.y); tmp2 = old; /* set tmp2 to Y value */ return(floatbailout()); } int LongPhoenixCplxPlusFractal(void) { #ifndef XFRACT /* z(n+1) = z(n)^(degree-1) * (z(n) + p) + qy(n), y(n+1) = z(n) */ int i; _LCMPLX loldplus, lnewminus; loldplus = lold; ltmp = lold; for(i=1; i= 2, degree=degree-1 in setup */ LCMPLXmult(lold,ltmp,ltmp); /* = old^(degree-1) */ } loldplus.x += longparm->x; loldplus.y += longparm->y; LCMPLXmult(ltmp, loldplus, lnewminus); LCMPLXmult(lparm2, ltmp2, ltmp); lnew.x = lnewminus.x + ltmp.x; lnew.y = lnewminus.y + ltmp.y; ltmp2 = lold; /* set ltmp2 to Y value */ return(longbailout()); #else return(0); #endif } int PhoenixCplxPlusFractal(void) { /* z(n+1) = z(n)^(degree-1) * (z(n) + p) + qy(n), y(n+1) = z(n) */ int i; _CMPLX oldplus, newminus; oldplus = old; tmp = old; for(i=1; i= 2, degree=degree-1 in setup */ FPUcplxmul(&old, &tmp, &tmp); /* = old^(degree-1) */ } oldplus.x += floatparm->x; oldplus.y += floatparm->y; FPUcplxmul(&tmp, &oldplus, &newminus); FPUcplxmul(&parm2, &tmp2, &tmp); new.x = newminus.x + tmp.x; new.y = newminus.y + tmp.y; tmp2 = old; /* set tmp2 to Y value */ return(floatbailout()); } int LongPhoenixCplxMinusFractal(void) { #ifndef XFRACT /* z(n+1) = z(n)^(degree-2) * (z(n)^2 + p) + qy(n), y(n+1) = z(n) */ int i; _LCMPLX loldsqr, lnewminus; LCMPLXmult(lold,lold,loldsqr); ltmp = lold; for(i=1; i= 3, degree=degree-2 in setup */ LCMPLXmult(lold,ltmp,ltmp); /* = old^(degree-2) */ } loldsqr.x += longparm->x; loldsqr.y += longparm->y; LCMPLXmult(ltmp, loldsqr, lnewminus); LCMPLXmult(lparm2, ltmp2, ltmp); lnew.x = lnewminus.x + ltmp.x; lnew.y = lnewminus.y + ltmp.y; ltmp2 = lold; /* set ltmp2 to Y value */ return(longbailout()); #else return(0); #endif } int PhoenixCplxMinusFractal(void) { /* z(n+1) = z(n)^(degree-2) * (z(n)^2 + p) + qy(n), y(n+1) = z(n) */ int i; _CMPLX oldsqr, newminus; FPUcplxmul(&old, &old, &oldsqr); tmp = old; for(i=1; i= 3, degree=degree-2 in setup */ FPUcplxmul(&old, &tmp, &tmp); /* = old^(degree-2) */ } oldsqr.x += floatparm->x; oldsqr.y += floatparm->y; FPUcplxmul(&tmp, &oldsqr, &newminus); FPUcplxmul(&parm2, &tmp2, &tmp); new.x = newminus.x + tmp.x; new.y = newminus.y + tmp.y; tmp2 = old; /* set tmp2 to Y value */ return(floatbailout()); } int ScottTrigPlusTrigFractal(void) { #ifndef XFRACT /* z = trig0(z)+trig1(z) */ LCMPLXtrig0(lold,ltmp); LCMPLXtrig1(lold,lold); LCMPLXadd(ltmp,lold,lnew); return(longbailout()); #else return(0); #endif } int ScottTrigPlusTrigfpFractal(void) { /* z = trig0(z)+trig1(z) */ CMPLXtrig0(old,tmp); CMPLXtrig1(old,tmp2); CMPLXadd(tmp,tmp2,new); return(floatbailout()); } int SkinnerTrigSubTrigFractal(void) { #ifndef XFRACT /* z = trig(0,z)-trig1(z) */ LCMPLXtrig0(lold,ltmp); LCMPLXtrig1(lold,ltmp2); LCMPLXsub(ltmp,ltmp2,lnew); return(longbailout()); #else return(0); #endif } int SkinnerTrigSubTrigfpFractal(void) { /* z = trig0(z)-trig1(z) */ CMPLXtrig0(old,tmp); CMPLXtrig1(old,tmp2); CMPLXsub(tmp,tmp2,new); return(floatbailout()); } int TrigXTrigfpFractal(void) { /* z = trig0(z)*trig1(z) */ CMPLXtrig0(old,tmp); CMPLXtrig1(old,old); CMPLXmult(tmp,old,new); return(floatbailout()); } #ifndef XFRACT /* call float version of fractal if integer math overflow */ static int TryFloatFractal(int (*fpFractal)(void)) { overflow=0; /* lold had better not be changed! */ old.x = lold.x; old.x /= fudge; old.y = lold.y; old.y /= fudge; tempsqrx = sqr(old.x); tempsqry = sqr(old.y); fpFractal(); if (save_release < 1900) { /* for backwards compatibility */ lnew.x = (long)(new.x/fudge); /* this error has been here a long time */ lnew.y = (long)(new.y/fudge); } else { lnew.x = (long)(new.x*fudge); lnew.y = (long)(new.y*fudge); } return(0); } #endif int TrigXTrigFractal(void) { #ifndef XFRACT _LCMPLX ltmp2; /* z = trig0(z)*trig1(z) */ LCMPLXtrig0(lold,ltmp); LCMPLXtrig1(lold,ltmp2); LCMPLXmult(ltmp,ltmp2,lnew); if(overflow) TryFloatFractal(TrigXTrigfpFractal); return(longbailout()); #else return(0); #endif } /********************************************************************/ /* Next six orbit functions are one type - extra functions are */ /* special cases written for speed. */ /********************************************************************/ int TrigPlusSqrFractal(void) /* generalization of Scott and Skinner types */ { #ifndef XFRACT /* { z=pixel: z=(p1,p2)*trig(z)+(p3,p4)*sqr(z), |z| l16triglim_2 || labs(ltmp.y) > l16triglim_2) && save_release > 1900) overflow = 1; else { LCMPLXtrig0(ltmp,lnew); } if(overflow) TryFloatFractal(TrigZsqrdfpFractal); return(longbailout()); #else return(0); #endif } int SqrTrigFractal(void) { #ifndef XFRACT /* { z=pixel: z=sqr(trig(z)), |z|x - 1; /* top = Z**2+C-1 */ top.y = old.x * old.y; top.y = top.y + top.y + floatparm->y; bot.x = old.x + old.x + floatparm->x - 2; /* bot = 2*Z+C-2 */ bot.y = old.y + old.y + floatparm->y; div = bot.x*bot.x + bot.y*bot.y; /* tmp = top/bot */ if (div < FLT_MIN) return(1); tmp.x = (top.x*bot.x + top.y*bot.y)/div; tmp.y = (top.y*bot.x - top.x*bot.y)/div; new.x = (tmp.x + tmp.y) * (tmp.x - tmp.y); /* Z = tmp**2 */ new.y = tmp.x * tmp.y; new.y += new.y; return(floatbailout()); } int Magnet2Fractal(void) /* Z = ((Z**3 + 3(C-1)Z + (C-1)(C-2) ) / */ /* (3Z**2 + 3(C-2)Z + (C-1)(C-2)+1) )**2 */ { /* In "Beauty of Fractals", code by Kev Allen. */ _CMPLX top, bot, tmp; double div; top.x = old.x * (tempsqrx-tempsqry-tempsqry-tempsqry + T_Cm1.x) - old.y * T_Cm1.y + T_Cm1Cm2.x; top.y = old.y * (tempsqrx+tempsqrx+tempsqrx-tempsqry + T_Cm1.x) + old.x * T_Cm1.y + T_Cm1Cm2.y; bot.x = tempsqrx - tempsqry; bot.x = bot.x + bot.x + bot.x + old.x * T_Cm2.x - old.y * T_Cm2.y + T_Cm1Cm2.x + 1.0; bot.y = old.x * old.y; bot.y += bot.y; bot.y = bot.y + bot.y + bot.y + old.x * T_Cm2.y + old.y * T_Cm2.x + T_Cm1Cm2.y; div = bot.x*bot.x + bot.y*bot.y; /* tmp = top/bot */ if (div < FLT_MIN) return(1); tmp.x = (top.x*bot.x + top.y*bot.y)/div; tmp.y = (top.y*bot.x - top.x*bot.y)/div; new.x = (tmp.x + tmp.y) * (tmp.x - tmp.y); /* Z = tmp**2 */ new.y = tmp.x * tmp.y; new.y += new.y; return(floatbailout()); } int LambdaTrigFractal(void) { #ifndef XFRACT LONGXYTRIGBAILOUT(); LCMPLXtrig0(lold,ltmp); /* ltmp = trig(lold) */ LCMPLXmult(*longparm,ltmp,lnew); /* lnew = longparm*trig(lold) */ lold = lnew; return(0); #else return(0); #endif } int LambdaTrigfpFractal(void) { FLOATXYTRIGBAILOUT(); CMPLXtrig0(old,tmp); /* tmp = trig(old) */ CMPLXmult(*floatparm,tmp,new); /* new = longparm*trig(old) */ old = new; return(0); } /* bailouts are different for different trig functions */ int LambdaTrigFractal1(void) { #ifndef XFRACT LONGTRIGBAILOUT(); /* sin,cos */ LCMPLXtrig0(lold,ltmp); /* ltmp = trig(lold) */ LCMPLXmult(*longparm,ltmp,lnew); /* lnew = longparm*trig(lold) */ lold = lnew; return(0); #else return(0); #endif } int LambdaTrigfpFractal1(void) { FLOATTRIGBAILOUT(); /* sin,cos */ CMPLXtrig0(old,tmp); /* tmp = trig(old) */ CMPLXmult(*floatparm,tmp,new); /* new = longparm*trig(old) */ old = new; return(0); } int LambdaTrigFractal2(void) { #ifndef XFRACT LONGHTRIGBAILOUT(); /* sinh,cosh */ LCMPLXtrig0(lold,ltmp); /* ltmp = trig(lold) */ LCMPLXmult(*longparm,ltmp,lnew); /* lnew = longparm*trig(lold) */ lold = lnew; return(0); #else return(0); #endif } int LambdaTrigfpFractal2(void) { #ifndef XFRACT FLOATHTRIGBAILOUT(); /* sinh,cosh */ CMPLXtrig0(old,tmp); /* tmp = trig(old) */ CMPLXmult(*floatparm,tmp,new); /* new = longparm*trig(old) */ old = new; return(0); #else return(0); #endif } int ManOWarFractal(void) { #ifndef XFRACT /* From Art Matrix via Lee Skinner */ lnew.x = ltempsqrx - ltempsqry + ltmp.x + longparm->x; lnew.y = multiply(lold.x, lold.y, bitshiftless1) + ltmp.y + longparm->y; ltmp = lold; return(longbailout()); #else return(0); #endif } int ManOWarfpFractal(void) { /* From Art Matrix via Lee Skinner */ /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */ new.x = tempsqrx - tempsqry + tmp.x + floatparm->x; new.y = 2.0 * old.x * old.y + tmp.y + floatparm->y; tmp = old; return(floatbailout()); } /* MarksMandelPwr (XAXIS) { z = pixel, c = z ^ (z - 1): z = c * sqr(z) + pixel, |z| <= 4 } */ int MarksMandelPwrfpFractal(void) { CMPLXtrig0(old,new); CMPLXmult(tmp,new,new); new.x += floatparm->x; new.y += floatparm->y; return(floatbailout()); } int MarksMandelPwrFractal(void) { #ifndef XFRACT LCMPLXtrig0(lold,lnew); LCMPLXmult(ltmp,lnew,lnew); lnew.x += longparm->x; lnew.y += longparm->y; return(longbailout()); #else return(0); #endif } /* I was coding Marksmandelpower and failed to use some temporary variables. The result was nice, and since my name is not on any fractal, I thought I would immortalize myself with this error! Tim Wegner */ int TimsErrorfpFractal(void) { CMPLXtrig0(old,new); new.x = new.x * tmp.x - new.y * tmp.y; new.y = new.x * tmp.y - new.y * tmp.x; new.x += floatparm->x; new.y += floatparm->y; return(floatbailout()); } int TimsErrorFractal(void) { #ifndef XFRACT LCMPLXtrig0(lold,lnew); lnew.x = multiply(lnew.x,ltmp.x,bitshift)-multiply(lnew.y,ltmp.y,bitshift); lnew.y = multiply(lnew.x,ltmp.y,bitshift)-multiply(lnew.y,ltmp.x,bitshift); lnew.x += longparm->x; lnew.y += longparm->y; return(longbailout()); #else return(0); #endif } int CirclefpFractal(void) { long i; i = (long)(param[0]*(tempsqrx+tempsqry)); coloriter = i%colors; return(1); } /* CirclelongFractal() { long i; i = multiply(lparm.x,(ltempsqrx+ltempsqry),bitshift); i = i >> bitshift; coloriter = i%colors); return(1); } */ /* -------------------------------------------------------------------- */ /* Initialization (once per pixel) routines */ /* -------------------------------------------------------------------- */ #ifdef XFRACT /* this code translated to asm - lives in newton.asm */ /* transform points with reciprocal function */ void invertz2(_CMPLX *z) { z->x = dxpixel(); z->y = dypixel(); z->x -= f_xcenter; z->y -= f_ycenter; /* Normalize values to center of circle */ tempsqrx = sqr(z->x) + sqr(z->y); /* Get old radius */ if(fabs(tempsqrx) > FLT_MIN) tempsqrx = f_radius / tempsqrx; else tempsqrx = FLT_MAX; /* a big number, but not TOO big */ z->x *= tempsqrx; z->y *= tempsqrx; /* Perform inversion */ z->x += f_xcenter; z->y += f_ycenter; /* Renormalize */ } #endif int long_julia_per_pixel(void) { #ifndef XFRACT /* integer julia types */ /* lambda */ /* barnsleyj1 */ /* barnsleyj2 */ /* sierpinski */ if(invert) { /* invert */ invertz2(&old); /* watch out for overflow */ if(sqr(old.x)+sqr(old.y) >= 127) { old.x = 8; /* value to bail out in one iteration */ old.y = 8; } /* convert to fudged longs */ lold.x = (long)(old.x*fudge); lold.y = (long)(old.y*fudge); } else { lold.x = lxpixel(); lold.y = lypixel(); } return(0); #else printf("Called long_julia_per_pixel\n"); return(0); #endif } int long_richard8_per_pixel(void) { #ifndef XFRACT long_mandel_per_pixel(); LCMPLXtrig1(*longparm,ltmp); LCMPLXmult(ltmp,lparm2,ltmp); return(1); #else return(0); #endif } int long_mandel_per_pixel(void) { #ifndef XFRACT /* integer mandel types */ /* barnsleym1 */ /* barnsleym2 */ linit.x = lxpixel(); if(save_release >= 2004) linit.y = lypixel(); if(invert) { /* invert */ invertz2(&init); /* watch out for overflow */ if(sqr(init.x)+sqr(init.y) >= 127) { init.x = 8; /* value to bail out in one iteration */ init.y = 8; } /* convert to fudged longs */ linit.x = (long)(init.x*fudge); linit.y = (long)(init.y*fudge); } if(useinitorbit == 1) lold = linitorbit; else lold = linit; lold.x += lparm.x; /* initial pertubation of parameters set */ lold.y += lparm.y; return(1); /* 1st iteration has been done */ #else printf("Called long_mandel_per_pixel\n"); return(0); #endif } int julia_per_pixel(void) { /* julia */ if(invert) { /* invert */ invertz2(&old); /* watch out for overflow */ if(bitshift <= 24) if (sqr(old.x)+sqr(old.y) >= 127) { old.x = 8; /* value to bail out in one iteration */ old.y = 8; } if(bitshift > 24) if (sqr(old.x)+sqr(old.y) >= 4.0) { old.x = 2; /* value to bail out in one iteration */ old.y = 2; } /* convert to fudged longs */ lold.x = (long)(old.x*fudge); lold.y = (long)(old.y*fudge); } else { lold.x = lxpixel(); lold.y = lypixel(); } ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); ltmp = lold; return(0); } int marks_mandelpwr_per_pixel(void) { #ifndef XFRACT mandel_per_pixel(); ltmp = lold; ltmp.x -= fudge; LCMPLXpwr(lold,ltmp,ltmp); return(1); #else return(0); #endif } int mandel_per_pixel(void) { /* mandel */ if(invert) { invertz2(&init); /* watch out for overflow */ if(bitshift <= 24) if (sqr(init.x)+sqr(init.y) >= 127) { init.x = 8; /* value to bail out in one iteration */ init.y = 8; } if(bitshift > 24) if (sqr(init.x)+sqr(init.y) >= 4) { init.x = 2; /* value to bail out in one iteration */ init.y = 2; } /* convert to fudged longs */ linit.x = (long)(init.x*fudge); linit.y = (long)(init.y*fudge); } else { linit.x = lxpixel(); if(save_release >= 2004) linit.y = lypixel(); } switch (fractype) { case MANDELLAMBDA: /* Critical Value 0.5 + 0.0i */ lold.x = FgHalf; lold.y = 0; break; default: lold = linit; break; } /* alter init value */ if(useinitorbit == 1) lold = linitorbit; else if(useinitorbit == 2) lold = linit; if((inside == BOF60 || inside == BOF61) && !nobof) { /* kludge to match "Beauty of Fractals" picture since we start Mandelbrot iteration with init rather than 0 */ lold.x = lparm.x; /* initial pertubation of parameters set */ lold.y = lparm.y; coloriter = -1; } else { lold.x += lparm.x; /* initial pertubation of parameters set */ lold.y += lparm.y; } ltmp = linit; /* for spider */ ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); return(1); /* 1st iteration has been done */ } int marksmandel_per_pixel() { #ifndef XFRACT /* marksmandel */ if(invert) { invertz2(&init); /* watch out for overflow */ if(sqr(init.x)+sqr(init.y) >= 127) { init.x = 8; /* value to bail out in one iteration */ init.y = 8; } /* convert to fudged longs */ linit.x = (long)(init.x*fudge); linit.y = (long)(init.y*fudge); } else { linit.x = lxpixel(); if(save_release >= 2004) linit.y = lypixel(); } if(useinitorbit == 1) lold = linitorbit; else lold = linit; lold.x += lparm.x; /* initial pertubation of parameters set */ lold.y += lparm.y; if(c_exp > 3) lcpower(&lold,c_exp-1,&lcoefficient,bitshift); else if(c_exp == 3) { lcoefficient.x = multiply(lold.x, lold.x, bitshift) - multiply(lold.y, lold.y, bitshift); lcoefficient.y = multiply(lold.x, lold.y, bitshiftless1); } else if(c_exp == 2) lcoefficient = lold; else if(c_exp < 2) { lcoefficient.x = 1L << bitshift; lcoefficient.y = 0L; } ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); #endif return(1); /* 1st iteration has been done */ } int marksmandelfp_per_pixel() { /* marksmandel */ if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } if(useinitorbit == 1) old = initorbit; else old = init; old.x += parm.x; /* initial pertubation of parameters set */ old.y += parm.y; tempsqrx = sqr(old.x); tempsqry = sqr(old.y); if(c_exp > 3) cpower(&old,c_exp-1,&coefficient); else if(c_exp == 3) { coefficient.x = tempsqrx - tempsqry; coefficient.y = old.x * old.y * 2; } else if(c_exp == 2) coefficient = old; else if(c_exp < 2) { coefficient.x = 1.0; coefficient.y = 0.0; } return(1); /* 1st iteration has been done */ } int marks_mandelpwrfp_per_pixel(void) { mandelfp_per_pixel(); tmp = old; tmp.x -= 1; CMPLXpwr(old,tmp,tmp); return(1); } int mandelfp_per_pixel(void) { /* floating point mandelbrot */ /* mandelfp */ if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } switch (fractype) { case MAGNET2M: FloatPreCalcMagnet2(); case MAGNET1M: /* Crit Val Zero both, but neither */ old.x = old.y = 0.0; /* is of the form f(Z,C) = Z*g(Z)+C */ break; case MANDELLAMBDAFP: /* Critical Value 0.5 + 0.0i */ old.x = 0.5; old.y = 0.0; break; default: old = init; break; } /* alter init value */ if(useinitorbit == 1) old = initorbit; else if(useinitorbit == 2) old = init; if((inside == BOF60 || inside == BOF61) && !nobof) { /* kludge to match "Beauty of Fractals" picture since we start Mandelbrot iteration with init rather than 0 */ old.x = parm.x; /* initial pertubation of parameters set */ old.y = parm.y; coloriter = -1; } else { old.x += parm.x; old.y += parm.y; } tmp = init; /* for spider */ tempsqrx = sqr(old.x); /* precalculated value for regular Mandelbrot */ tempsqry = sqr(old.y); return(1); /* 1st iteration has been done */ } int juliafp_per_pixel(void) { /* floating point julia */ /* juliafp */ if(invert) invertz2(&old); else { old.x = dxpixel(); old.y = dypixel(); } tempsqrx = sqr(old.x); /* precalculated value for regular Julia */ tempsqry = sqr(old.y); tmp = old; return(0); } #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif int MPCjulia_per_pixel(void) { #ifndef XFRACT /* floating point julia */ /* juliafp */ if(invert) invertz2(&old); else { old.x = dxpixel(); old.y = dypixel(); } mpcold.x = *pd2MP(old.x); mpcold.y = *pd2MP(old.y); return(0); #else return(0); #endif } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif int otherrichard8fp_per_pixel(void) { othermandelfp_per_pixel(); CMPLXtrig1(*floatparm,tmp); CMPLXmult(tmp,parm2,tmp); return(1); } int othermandelfp_per_pixel(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } if(useinitorbit == 1) old = initorbit; else old = init; old.x += parm.x; /* initial pertubation of parameters set */ old.y += parm.y; return(1); /* 1st iteration has been done */ } #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif int MPCHalley_per_pixel(void) { #ifndef XFRACT /* MPC halley */ if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } mpcold.x = *pd2MP(init.x); mpcold.y = *pd2MP(init.y); return(0); #else return(0); #endif } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif int Halley_per_pixel(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } old = init; return(0); /* 1st iteration is not done */ } int otherjuliafp_per_pixel(void) { if(invert) invertz2(&old); else { old.x = dxpixel(); old.y = dypixel(); } return(0); } #if 0 #define Q0 .113 #define Q1 .01 #else #define Q0 0 #define Q1 0 #endif int quaternionjulfp_per_pixel(void) { old.x = dxpixel(); old.y = dypixel(); floatparm->x = param[4]; floatparm->y = param[5]; qc = param[0]; qci = param[1]; qcj = param[2]; qck = param[3]; return(0); } int quaternionfp_per_pixel(void) { old.x = 0; old.y = 0; floatparm->x = 0; floatparm->y = 0; qc = dxpixel(); qci = dypixel(); qcj = param[2]; qck = param[3]; return(0); } int MarksCplxMandperp(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } old.x = init.x + parm.x; /* initial pertubation of parameters set */ old.y = init.y + parm.y; tempsqrx = sqr(old.x); /* precalculated value */ tempsqry = sqr(old.y); coefficient = ComplexPower(init, pwr); return(1); } int long_phoenix_per_pixel(void) { #ifndef XFRACT if(invert) { /* invert */ invertz2(&old); /* watch out for overflow */ if(sqr(old.x)+sqr(old.y) >= 127) { old.x = 8; /* value to bail out in one iteration */ old.y = 8; } /* convert to fudged longs */ lold.x = (long)(old.x*fudge); lold.y = (long)(old.y*fudge); } else { lold.x = lxpixel(); lold.y = lypixel(); } ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); ltmp2.x = 0; /* use ltmp2 as the complex Y value */ ltmp2.y = 0; return(0); #else printf("Called long_phoenix_per_pixel\n"); return(0); #endif } int phoenix_per_pixel(void) { if(invert) invertz2(&old); else { old.x = dxpixel(); old.y = dypixel(); } tempsqrx = sqr(old.x); /* precalculated value */ tempsqry = sqr(old.y); tmp2.x = 0; /* use tmp2 as the complex Y value */ tmp2.y = 0; return(0); } int long_mandphoenix_per_pixel(void) { #ifndef XFRACT linit.x = lxpixel(); if(save_release >= 2004) linit.y = lypixel(); if(invert) { /* invert */ invertz2(&init); /* watch out for overflow */ if(sqr(init.x)+sqr(init.y) >= 127) { init.x = 8; /* value to bail out in one iteration */ init.y = 8; } /* convert to fudged longs */ linit.x = (long)(init.x*fudge); linit.y = (long)(init.y*fudge); } if(useinitorbit == 1) lold = linitorbit; else lold = linit; lold.x += lparm.x; /* initial pertubation of parameters set */ lold.y += lparm.y; ltempsqrx = multiply(lold.x, lold.x, bitshift); ltempsqry = multiply(lold.y, lold.y, bitshift); ltmp2.x = 0; ltmp2.y = 0; return(1); /* 1st iteration has been done */ #else printf("Called long_mandphoenix_per_pixel\n"); return(0); #endif } int mandphoenix_per_pixel(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); if(save_release >= 2004) init.y = dypixel(); } if(useinitorbit == 1) old = initorbit; else old = init; old.x += parm.x; /* initial pertubation of parameters set */ old.y += parm.y; tempsqrx = sqr(old.x); /* precalculated value */ tempsqry = sqr(old.y); tmp2.x = 0; tmp2.y = 0; return(1); /* 1st iteration has been done */ } int QuaternionFPFractal(void) { double a0,a1,a2,a3,n0,n1,n2,n3; a0 = old.x; a1 = old.y; a2 = floatparm->x; a3 = floatparm->y; n0 = a0*a0-a1*a1-a2*a2-a3*a3 + qc; n1 = 2*a0*a1 + qci; n2 = 2*a0*a2 + qcj; n3 = 2*a0*a3 + qck; /* Check bailout */ magnitude = a0*a0+a1*a1+a2*a2+a3*a3; if (magnitude>rqlim) { return 1; } old.x = new.x = n0; old.y = new.y = n1; floatparm->x = n2; floatparm->y = n3; return(0); } int HyperComplexFPFractal(void) { _HCMPLX hold, hnew; hold.x = old.x; hold.y = old.y; hold.z = floatparm->x; hold.t = floatparm->y; /* HComplexSqr(&hold,&hnew); */ HComplexTrig0(&hold,&hnew); hnew.x += qc; hnew.y += qci; hnew.z += qcj; hnew.t += qck; old.x = new.x = hnew.x; old.y = new.y = hnew.y; floatparm->x = hnew.z; floatparm->y = hnew.t; /* Check bailout */ magnitude = sqr(old.x)+sqr(old.y)+sqr(floatparm->x)+sqr(floatparm->y); if (magnitude>rqlim) { return 1; } return(0); } int VLfpFractal(void) /* Beauty of Fractals pp. 125 - 127 */ { double a, b, ab, half, u, w, xy; half = param[0] / 2.0; xy = old.x * old.y; u = old.x - xy; w = -old.y + xy; a = old.x + param[1] * u; b = old.y + param[1] * w; ab = a * b; new.x = old.x + half * (u + (a - ab)); new.y = old.y + half * (w + (-b + ab)); return(floatbailout()); } int EscherfpFractal(void) /* Science of Fractal Images pp. 185, 187 */ { _CMPLX oldtest, newtest, testsqr; double testsize = 0.0; long testiter = 0; new.x = tempsqrx - tempsqry; /* standard Julia with C == (0.0, 0.0i) */ new.y = 2.0 * old.x * old.y; oldtest.x = new.x * 15.0; /* scale it */ oldtest.y = new.y * 15.0; testsqr.x = sqr(oldtest.x); /* set up to test with user-specified ... */ testsqr.y = sqr(oldtest.y); /* ... Julia as the target set */ while (testsize <= rqlim && testiter < maxit) /* nested Julia loop */ { newtest.x = testsqr.x - testsqr.y + param[0]; newtest.y = 2.0 * oldtest.x * oldtest.y + param[1]; testsize = (testsqr.x = sqr(newtest.x)) + (testsqr.y = sqr(newtest.y)); oldtest = newtest; testiter++; } if (testsize > rqlim) return(floatbailout()); /* point not in target set */ else /* make distinct level sets if point stayed in target set */ { coloriter = ((3L * coloriter) % 255L) + 1L; return 1; } } /* re-use static roots variable memory for mandelmix4 */ #define A staticroots[ 0] #define B staticroots[ 1] #define C staticroots[ 2] #define D staticroots[ 3] #define F staticroots[ 4] #define G staticroots[ 5] #define H staticroots[ 6] #define J staticroots[ 7] #define K staticroots[ 8] #define L staticroots[ 9] #define Z staticroots[10] int MandelbrotMix4Setup(void) { int sign_array = 0; A.x=param[0]; A.y=0.0; /* a=real(p1), */ B.x=param[1]; B.y=0.0; /* b=imag(p1), */ D.x=param[2]; D.y=0.0; /* d=real(p2), */ F.x=param[3]; F.y=0.0; /* f=imag(p2), */ K.x=param[4]+1.0; K.y=0.0; /* k=real(p3)+1, */ L.x=param[5]+100.0; L.y=0.0; /* l=imag(p3)+100, */ CMPLXrecip(F,G); /* g=1/f, */ CMPLXrecip(D,H); /* h=1/d, */ CMPLXsub(F,B,tmp); /* tmp = f-b */ CMPLXrecip(tmp,J); /* j = 1/(f-b) */ CMPLXneg(A,tmp); CMPLXmult(tmp,B,tmp); /* z=(-a*b*g*h)^j, */ CMPLXmult(tmp,G,tmp); CMPLXmult(tmp,H,tmp); /* This code kludge attempts to duplicate the behavior of the parser in determining the sign of zero of the imaginary part of the argument of the power function. The reason this is important is that the complex arctangent returns PI in one case and -PI in the other, depending on the sign bit of zero, and we wish the results to be compatible with Jim Muth's mix4 formula using the parser. First create a number encoding the signs of a, b, g , h. Our kludge assumes that those signs determine the behavior. */ if(A.x < 0.0) sign_array += 8; if(B.x < 0.0) sign_array += 4; if(G.x < 0.0) sign_array += 2; if(H.x < 0.0) sign_array += 1; if(tmp.y == 0.0) /* we know tmp.y IS zero but ... */ { switch(sign_array) { /* Add to this list the magic numbers of any cases in which the fractal does not match the formula version */ case 15: /* 1111 */ case 10: /* 1010 */ case 6: /* 0110 */ case 5: /* 0101 */ case 3: /* 0011 */ case 0: /* 0000 */ tmp.y = -tmp.y; /* swap sign bit */ default: /* do nothing - remaining cases already OK */ ; } /* in case our kludge failed, let the user fix it */ if(debugflag == 1012) tmp.y = -tmp.y; } CMPLXpwr(tmp,J,tmp); /* note: z is old */ /* in case our kludge failed, let the user fix it */ if(param[6] < 0.0) tmp.y = -tmp.y; if(bailout == 0) { rqlim = L.x; rqlim2 = rqlim*rqlim; } return(1); } int MandelbrotMix4fp_per_pixel(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); init.y = dypixel(); } old = tmp; CMPLXtrig0(init,C); /* c=fn1(pixel): */ return(0); /* 1st iteration has been NOT been done */ } int MandelbrotMix4fpFractal(void) /* from formula by Jim Muth */ { /* z=k*((a*(z^b))+(d*(z^f)))+c, */ _CMPLX z_b, z_f; CMPLXpwr(old,B,z_b); /* (z^b) */ CMPLXpwr(old,F,z_f); /* (z^f) */ new.x = K.x*A.x*z_b.x + K.x*D.x*z_f.x + C.x; new.y = K.x*A.x*z_b.y + K.x*D.x*z_f.y + C.y; return(floatbailout()); } #undef A #undef B #undef C #undef D #undef F #undef G #undef H #undef J #undef K #undef L double b_const; int DivideBrot5Setup(void) { c_exp = -((int)param[0] - 2); /* use negative here so only need it once */ b_const = param[1] + 0.00000000000000000001; return(1); } int DivideBrot5fp_per_pixel(void) { if(invert) invertz2(&init); else { init.x = dxpixel(); init.y = dypixel(); } tempsqrx = 0.0; /* precalculated value */ tempsqry = 0.0; old.x = 0.0; old.y = 0.0; return(0); /* 1st iteration has NOT been done */ } int DivideBrot5fpFractal(void) /* from formula by Jim Muth */ { /* z=sqr(z)/(z^(-a)+b)+c */ /* we'll set a to -a in setup, so don't need it here */ /* z=sqr(z)/(z^(a)+b)+c */ _CMPLX tmp_sqr, tmp1, tmp2; /* sqr(z) */ tmp_sqr.x = tempsqrx - tempsqry; tmp_sqr.y = old.x * old.y * 2.0; /* z^(a) = e^(a * log(z))*/ FPUcplxlog(&old, &tmp1); tmp1.x *= c_exp; tmp1.y *= c_exp; FPUcplxexp(&tmp1, &tmp2); /* then add b */ tmp2.x += b_const; /* sqr(z)/(z^(a)+b) */ FPUcplxdiv(&tmp_sqr, &tmp2, &new); /* then add c = init = pixel */ new.x += init.x; new.y += init.y; return(floatbailout()); } /* * The following functions calculate the real and imaginary complex * coordinates of the point in the complex plane corresponding to * the screen coordinates (col,row) at the current zoom corners * settings. The functions come in two flavors. One looks up the pixel * values using the precalculated grid arrays dx0, dx1, dy0, and dy1, * which has a speed advantage but is limited to MAXPIXELS image * dimensions. The other calculates the complex coordinates at a * cost of two additions and two multiplications for each component, * but works at any resolution. * * With Microsoft C's _fastcall keyword, the function call overhead * appears to be negligible. It also appears that the speed advantage * of the lookup vs the calculation is negligible on machines with * coprocessors. Bert Tyler's original implementation was designed for * machines with no coprocessor; on those machines the saving was * significant. For the time being, the table lookup capability will * be maintained. */ /* Real component, grid lookup version - requires dx0/dx1 arrays */ static double _fastcall dxpixel_grid(void) { return(dx0[col]+dx1[row]); } /* Real component, calculation version - does not require arrays */ static double _fastcall dxpixel_calc(void) { return((double)(xxmin + col*delxx + row*delxx2)); } /* Imaginary component, grid lookup version - requires dy0/dy1 arrays */ static double _fastcall dypixel_grid(void) { return(dy0[row]+dy1[col]); } /* Imaginary component, calculation version - does not require arrays */ static double _fastcall dypixel_calc(void) { return((double)(yymax - row*delyy - col*delyy2)); } /* Real component, grid lookup version - requires lx0/lx1 arrays */ static long _fastcall lxpixel_grid(void) { return(lx0[col]+lx1[row]); } /* Real component, calculation version - does not require arrays */ static long _fastcall lxpixel_calc(void) { return(xmin + col*delx + row*delx2); } /* Imaginary component, grid lookup version - requires ly0/ly1 arrays */ static long _fastcall lypixel_grid(void) { return(ly0[row]+ly1[col]); } /* Imaginary component, calculation version - does not require arrays */ static long _fastcall lypixel_calc(void) { return(ymax - row*dely - col*dely2); } double (_fastcall *dxpixel)(void) = dxpixel_calc; double (_fastcall *dypixel)(void) = dypixel_calc; long (_fastcall *lxpixel)(void) = lxpixel_calc; long (_fastcall *lypixel)(void) = lypixel_calc; void set_pixel_calc_functions(void) { if(use_grid) { dxpixel = dxpixel_grid; dypixel = dypixel_grid; lxpixel = lxpixel_grid; lypixel = lypixel_grid; } else { dxpixel = dxpixel_calc; dypixel = dypixel_calc; lxpixel = lxpixel_calc; lypixel = lypixel_calc; } } xfractint-20.4.10.orig/common/lsys.c0000644000000000000000000006650610352406114014144 0ustar #include #ifdef __TURBOC__ #include #else #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "lsys.h" struct lsys_cmd { void (*f)(struct lsys_turtlestatei *); long n; char ch; }; static int _fastcall readLSystemFile(char *); static void _fastcall free_rules_mem(void); static int _fastcall rule_present(char symbol); static int _fastcall save_rule(char *,char far **); static int _fastcall append_rule(char *rule, int index); static void free_lcmds(void); static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_turtlestatei *, struct lsys_cmd far **,int); static struct lsys_cmd far * drawLSysI(struct lsys_cmd far *command,struct lsys_turtlestatei *ts, struct lsys_cmd far **rules,int depth); static int lsysi_findscale(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth); static struct lsys_cmd far *LSysISizeTransform(char far *s, struct lsys_turtlestatei *ts); static struct lsys_cmd far *LSysIDrawTransform(char far *s, struct lsys_turtlestatei *ts); static void _fastcall lsysi_dosincos(void); static void lsysi_doslash(struct lsys_turtlestatei *cmd); static void lsysi_dobslash(struct lsys_turtlestatei *cmd); static void lsysi_doat(struct lsys_turtlestatei *cmd); static void lsysi_dopipe(struct lsys_turtlestatei *cmd); static void lsysi_dosizedm(struct lsys_turtlestatei *cmd); static void lsysi_dosizegf(struct lsys_turtlestatei *cmd); static void lsysi_dodrawd(struct lsys_turtlestatei *cmd); static void lsysi_dodrawm(struct lsys_turtlestatei *cmd); static void lsysi_dodrawg(struct lsys_turtlestatei *cmd); static void lsysi_dodrawf(struct lsys_turtlestatei *cmd); static void lsysi_dodrawc(struct lsys_turtlestatei *cmd); static void lsysi_dodrawgt(struct lsys_turtlestatei *cmd); static void lsysi_dodrawlt(struct lsys_turtlestatei *cmd); /* Some notes to Adrian from PB, made when I integrated with v15: printfs changed to work with new user interface bug at end of readLSystemFile, the line which said rulind=0 fixed to say *rulind=0 the calloc was not worthwhile, it was just for a 54 byte area, cheaper to keep it as a static; but there was a static 201 char buffer I changed to not be static use of strdup was a nono, caused problems running out of space cause the memory allocated each time was never freed; I've changed to use far memory and to free when done */ #define sins ((long *)(boxy)) #define coss (((long *)(boxy)+50)) /* 50 after the start of sins */ static char far *ruleptrs[MAXRULES]; static struct lsys_cmd far *rules2[MAXRULES]; char maxangle; static char loaded=0; int _fastcall ispow2(int n) { return (n == (n & -n)); } LDBL _fastcall getnumber(char far **str) { char numstr[30]; LDBL ret; int i,root,inverse; root=0; inverse=0; strcpy(numstr,""); (*str)++; switch (**str) { case 'q': root=1; (*str)++; break; case 'i': inverse=1; (*str)++; break; } switch (**str) { case 'q': root=1; (*str)++; break; case 'i': inverse=1; (*str)++; break; } i=0; while ((**str<='9' && **str>='0') || **str=='.') { numstr[i++]= **str; (*str)++; } (*str)--; numstr[i]=0; ret=atof(numstr); if (ret <= 0.0) /* this is a sanity check, JCO 8/31/94 */ return 0; if (root) ret=sqrtl(ret); if (inverse) ret = 1.0/ret; return ret; } static int _fastcall readLSystemFile(char *str) { int c; char far **rulind; int err=0; int linenum,check=0; char inline1[MAX_LSYS_LINE_LEN+1],fixed[MAX_LSYS_LINE_LEN+1],*word; FILE *infile; char msgbuf[481]; /* enough for 6 full lines */ if (find_file_item(LFileName,str,&infile, 2) < 0) return -1; while ((c = fgetc(infile)) != '{') if (c == EOF) return -1; maxangle=0; for(linenum=0;linenum -1) /* Max line length chars */ { static FCODE out_of_mem[] = {"Error: out of memory\n"}; linenum++; if ((word = strchr(inline1,';')) != NULL) /* strip comment */ *word = 0; strlwr(inline1); if ((int)strspn(inline1," \t\n") < (int)strlen(inline1)) /* not a blank line */ { word=strtok(inline1," =\t\n"); if (!strcmp(word,"axiom")) { if (save_rule(strtok(NULL," \t\n"),&ruleptrs[0])) { far_strcat(msgbuf,out_of_mem); ++err; break; } check=1; } else if (!strcmp(word,"angle")) { maxangle=(char)atoi(strtok(NULL," \t\n")); check=1; } else if (!strcmp(word,"}")) break; else if (!word[1]) { char *temp; int index, memerr = 0; if (strchr("+-/\\@|!c<>][", *word)) { sprintf(&msgbuf[strlen(msgbuf)], "Syntax error line %d: Redefined reserved symbol %s\n",linenum,word); ++err; break; } temp = strtok(NULL," =\t\n"); index = rule_present(*word); if (!index) { strcpy(fixed,word); if (temp) strcat(fixed,temp); memerr = save_rule(fixed,rulind++); } else if (temp) { strcpy(fixed,temp); memerr = append_rule(fixed,index); } if (memerr) { far_strcat(msgbuf, out_of_mem); ++err; break; } check=1; } else if (err<6) { sprintf(&msgbuf[strlen(msgbuf)], "Syntax error line %d: %s\n",linenum,word); ++err; } if (check) { check=0; if((word=strtok(NULL," \t\n"))!=NULL) if (err<6) { sprintf(&msgbuf[strlen(msgbuf)], "Extra text after command line %d: %s\n",linenum,word); ++err; } } } } fclose(infile); if (!ruleptrs[0] && err<6) { static FCODE no_axiom[] = {"Error: no axiom\n"}; far_strcat(msgbuf,no_axiom); ++err; } if ((maxangle<3||maxangle>50) && err<6) { static FCODE missing_angle[] = {"Error: illegal or missing angle\n"}; far_strcat(msgbuf,missing_angle); ++err; } if (err) { msgbuf[strlen(msgbuf)-1]=0; /* strip trailing \n */ stopmsg(0,msgbuf); return -1; } *rulind=NULL; return 0; } int Lsystem(void) { int order; char far **rulesc; struct lsys_cmd far **sc; int stackoflow = 0; if ( (!loaded) && LLoad()) return -1; overflow = 0; /* reset integer math overflow flag */ order=(int)param[0]; if (order<=0) order=0; if (usr_floatflag) overflow = 1; else { struct lsys_turtlestatei ts; ts.stackoflow = 0; ts.maxangle = maxangle; ts.dmaxangle = (char)(maxangle - 1); sc = rules2; for (rulesc = ruleptrs; *rulesc; rulesc++) *sc++ = LSysISizeTransform(*rulesc, &ts); *sc = NULL; lsysi_dosincos(); if (lsysi_findscale(rules2[0], &ts, &rules2[1], order)) { ts.realangle = ts.angle = ts.reverse = 0; free_lcmds(); sc = rules2; for (rulesc = ruleptrs; *rulesc; rulesc++) *sc++ = LSysIDrawTransform(*rulesc, &ts); *sc = NULL; /* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */ if ((ts.curcolor=15) > colors) ts.curcolor=(char)(colors-1); drawLSysI(rules2[0], &ts, &rules2[1], order); } stackoflow = ts.stackoflow; } if (stackoflow) { static FCODE msg[]={"insufficient memory, try a lower order"}; stopmsg(0,msg); } else if (overflow) { struct lsys_turtlestatef ts; overflow = 0; ts.stackoflow = 0; ts.maxangle = maxangle; ts.dmaxangle = (char)(maxangle - 1); sc = rules2; for (rulesc = ruleptrs; *rulesc; rulesc++) *sc++ = LSysFSizeTransform(*rulesc, &ts); *sc = NULL; lsysf_dosincos(); if (lsysf_findscale(rules2[0], &ts, &rules2[1], order)) { ts.realangle = ts.angle = ts.reverse = 0; free_lcmds(); sc = rules2; for (rulesc = ruleptrs; *rulesc; rulesc++) *sc++ = LSysFDrawTransform(*rulesc, &ts); *sc = NULL; /* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */ if ((ts.curcolor=15) > colors) ts.curcolor=(char)(colors-1); lsys_prepfpu(&ts); drawLSysF(rules2[0], &ts, &rules2[1], order); lsys_donefpu(&ts); } overflow = 0; } free_rules_mem(); free_lcmds(); loaded=0; return 0; } int LLoad(void) { if (readLSystemFile(LName)) { /* error occurred */ free_rules_mem(); loaded=0; return -1; } loaded=1; return 0; } static void _fastcall free_rules_mem(void) { int i; for(i=0;i=0) *(tmpfar++)= *(rule++); return 0; } static int _fastcall append_rule(char *rule, int index) { char far *dst, far *old, far *sav; int i, j; old = sav = ruleptrs[index]; for (i = 0; *(old++); i++) ; j = strlen(rule) + 1; if ((dst = (char far *)farmemalloc((long)(i + j))) == NULL) return -1; old = sav; ruleptrs[index] = dst; while (i-- > 0) *(dst++) = *(old++); while (j-- > 0) *(dst++) = *(rule++); farmemfree(sav); return 0; } static void free_lcmds(void) { struct lsys_cmd far **sc = rules2; while (*sc) farmemfree(*sc++); } #ifdef XFRACT #define lsysi_doslash_386 lsysi_doslash #define lsysi_dobslash_386 lsysi_dobslash #define lsys_doat lsysi_doat #define lsys_dosizegf lsysi_dosizegf #define lsys_dodrawg lsysi_dodrawg void lsys_prepfpu(struct lsys_turtlestatef *x) { } void lsys_donefpu(struct lsys_turtlestatef *x) { } #endif /* integer specific routines */ #ifdef XFRACT static void lsysi_doplus(struct lsys_turtlestatei *cmd) { if (cmd->reverse) { if (++cmd->angle == cmd->maxangle) cmd->angle = 0; } else { if (cmd->angle) cmd->angle--; else cmd->angle = cmd->dmaxangle; } } #else extern void lsysi_doplus(struct lsys_turtlestatei *cmd); #endif #ifdef XFRACT /* This is the same as lsys_doplus, except maxangle is a power of 2. */ static void lsysi_doplus_pow2(struct lsys_turtlestatei *cmd) { if (cmd->reverse) { cmd->angle++; cmd->angle &= cmd->dmaxangle; } else { cmd->angle--; cmd->angle &= cmd->dmaxangle; } } #else extern void lsysi_doplus_pow2(struct lsys_turtlestatei *cmd); #endif #ifdef XFRACT static void lsysi_dominus(struct lsys_turtlestatei *cmd) { if (cmd->reverse) { if (cmd->angle) cmd->angle--; else cmd->angle = cmd->dmaxangle; } else { if (++cmd->angle == cmd->maxangle) cmd->angle = 0; } } #else extern void lsysi_dominus(struct lsys_turtlestatei *cmd); #endif #ifdef XFRACT static void lsysi_dominus_pow2(struct lsys_turtlestatei *cmd) { if (cmd->reverse) { cmd->angle--; cmd->angle &= cmd->dmaxangle; } else { cmd->angle++; cmd->angle &= cmd->dmaxangle; } } #else extern void lsysi_dominus_pow2(struct lsys_turtlestatei *cmd); #endif static void lsysi_doslash(struct lsys_turtlestatei *cmd) { if (cmd->reverse) cmd->realangle -= cmd->num; else cmd->realangle += cmd->num; } #ifndef XFRACT extern void lsysi_doslash_386(struct lsys_turtlestatei *cmd); #endif static void lsysi_dobslash(struct lsys_turtlestatei *cmd) { if (cmd->reverse) cmd->realangle += cmd->num; else cmd->realangle -= cmd->num; } #ifndef XFRACT extern void lsysi_dobslash_386(struct lsys_turtlestatei *cmd); #endif static void lsysi_doat(struct lsys_turtlestatei *cmd) { cmd->size = multiply(cmd->size, cmd->num, 19); } static void lsysi_dopipe(struct lsys_turtlestatei *cmd) { cmd->angle = (char)(cmd->angle + (char)(cmd->maxangle / 2)); cmd->angle %= cmd->maxangle; } #ifdef XFRACT static void lsysi_dopipe_pow2(struct lsys_turtlestatei *cmd) { cmd->angle += cmd->maxangle >> 1; cmd->angle &= cmd->dmaxangle; } #else extern void lsysi_dopipe_pow2(struct lsys_turtlestatei *cmd); #endif #ifdef XFRACT static void lsysi_dobang(struct lsys_turtlestatei *cmd) { cmd->reverse = ! cmd->reverse; } #else extern void lsysi_dobang(struct lsys_turtlestatei *cmd); #endif static void lsysi_dosizedm(struct lsys_turtlestatei *cmd) { double angle = (double) cmd->realangle * ANGLE2DOUBLE; double s, c; long fixedsin, fixedcos; FPUsincos(&angle, &s, &c); fixedsin = (long) (s * FIXEDLT1); fixedcos = (long) (c * FIXEDLT1); cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29)); cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29)); /* xpos+=size*aspect*cos(realangle*PI/180); */ /* ypos+=size*sin(realangle*PI/180); */ if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos; if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos; if (cmd->xposxmin) cmd->xmin=cmd->xpos; if (cmd->yposymin) cmd->ymin=cmd->ypos; } static void lsysi_dosizegf(struct lsys_turtlestatei *cmd) { cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[(int)cmd->angle], 29)); cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[(int)cmd->angle], 29)); /* xpos+=size*coss[angle]; */ /* ypos+=size*sins[angle]; */ if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos; if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos; if (cmd->xposxmin) cmd->xmin=cmd->xpos; if (cmd->yposymin) cmd->ymin=cmd->ypos; } static void lsysi_dodrawd(struct lsys_turtlestatei *cmd) { double angle = (double) cmd->realangle * ANGLE2DOUBLE; double s, c; long fixedsin, fixedcos; int lastx, lasty; FPUsincos(&angle, &s, &c); fixedsin = (long) (s * FIXEDLT1); fixedcos = (long) (c * FIXEDLT1); lastx=(int) (cmd->xpos >> 19); lasty=(int) (cmd->ypos >> 19); cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29)); cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29)); /* xpos+=size*aspect*cos(realangle*PI/180); */ /* ypos+=size*sin(realangle*PI/180); */ draw_line(lastx,lasty,(int)(cmd->xpos >> 19),(int)(cmd->ypos >> 19),cmd->curcolor); } static void lsysi_dodrawm(struct lsys_turtlestatei *cmd) { double angle = (double) cmd->realangle * ANGLE2DOUBLE; double s, c; long fixedsin, fixedcos; FPUsincos(&angle, &s, &c); fixedsin = (long) (s * FIXEDLT1); fixedcos = (long) (c * FIXEDLT1); /* xpos+=size*aspect*cos(realangle*PI/180); */ /* ypos+=size*sin(realangle*PI/180); */ cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29)); cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29)); } static void lsysi_dodrawg(struct lsys_turtlestatei *cmd) { cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[(int)cmd->angle], 29)); cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[(int)cmd->angle], 29)); /* xpos+=size*coss[angle]; */ /* ypos+=size*sins[angle]; */ } static void lsysi_dodrawf(struct lsys_turtlestatei *cmd) { int lastx = (int) (cmd->xpos >> 19); int lasty = (int) (cmd->ypos >> 19); cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[(int)cmd->angle], 29)); cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[(int)cmd->angle], 29)); /* xpos+=size*coss[angle]; */ /* ypos+=size*sins[angle]; */ draw_line(lastx,lasty,(int)(cmd->xpos >> 19),(int)(cmd->ypos >> 19),cmd->curcolor); } static void lsysi_dodrawc(struct lsys_turtlestatei *cmd) { cmd->curcolor = (char)(((int) cmd->num) % colors); } static void lsysi_dodrawgt(struct lsys_turtlestatei *cmd) { cmd->curcolor = (char)(cmd->curcolor - (char)cmd->num); if ((cmd->curcolor %= colors) == 0) cmd->curcolor = (char)(colors-1); } static void lsysi_dodrawlt(struct lsys_turtlestatei *cmd) { cmd->curcolor = (char)(cmd->curcolor + (char)cmd->num); if ((cmd->curcolor %= colors) == 0) cmd->curcolor = 1; } static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth) { struct lsys_cmd far **rulind; int tran; if (overflow) /* integer math routines overflowed */ return NULL; if (stackavail() < 400) { /* leave some margin for calling subrtns */ ts->stackoflow = 1; return NULL; } while (command->ch && command->ch !=']') { static FCODE thinking_msg[] = {"L-System thinking (higher orders take longer)"}; if (! (ts->counter++)) { /* let user know we're not dead */ if (thinking(1,thinking_msg)) { ts->counter--; return NULL; } } tran=0; if (depth) { for(rulind=rules;*rulind;rulind++) if ((*rulind)->ch==command->ch) { tran=1; if (findsize((*rulind)+1,ts,rules,depth-1) == NULL) return(NULL); } } if (!depth || !tran) { if (command->f) { ts->num = command->n; (*command->f)(ts); } else if (command->ch == '[') { char saveang,saverev; long savesize,savex,savey; unsigned long saverang; saveang=ts->angle; saverev=ts->reverse; savesize=ts->size; saverang=ts->realangle; savex=ts->xpos; savey=ts->ypos; if ((command=findsize(command+1,ts,rules,depth)) == NULL) return(NULL); ts->angle=saveang; ts->reverse=saverev; ts->size=savesize; ts->realangle=saverang; ts->xpos=savex; ts->ypos=savey; } } command++; } return command; } static int lsysi_findscale(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth) { float horiz,vert; double xmin, xmax, ymin, ymax; double locsize; double locaspect; struct lsys_cmd far *fsret; locaspect=screenaspect*xdots/ydots; ts->aspect = FIXEDPT(locaspect); ts->xpos = ts->ypos = ts->xmin = ts->xmax = ts->ymax = ts->ymin = ts->realangle = ts->angle = ts->reverse = ts->counter = 0; ts->size=FIXEDPT(1L); fsret = findsize(command,ts,rules,depth); thinking(0, NULL); /* erase thinking message if any */ xmin = (double) ts->xmin / FIXEDMUL; xmax = (double) ts->xmax / FIXEDMUL; ymin = (double) ts->ymin / FIXEDMUL; ymax = (double) ts->ymax / FIXEDMUL; if (fsret == NULL) return 0; if (xmax == xmin) horiz = (float)1E37; else horiz = (float)((xdots-10)/(xmax-xmin)); if (ymax == ymin) vert = (float)1E37; else vert = (float)((ydots-6) /(ymax-ymin)); locsize = (vertxpos = FIXEDPT(xdots/2); else /* ts->xpos = FIXEDPT(-xmin*(locsize)+5+((xdots-10)-(locsize)*(xmax-xmin))/2); */ ts->xpos = FIXEDPT((xdots-locsize*(xmax+xmin))/2); if (vert == 1E37) ts->ypos = FIXEDPT(ydots/2); else /* ts->ypos = FIXEDPT(-ymin*(locsize)+3+((ydots-6)-(locsize)*(ymax-ymin))/2); */ ts->ypos = FIXEDPT((ydots-locsize*(ymax+ymin))/2); ts->size = FIXEDPT(locsize); return 1; } static struct lsys_cmd far * drawLSysI(struct lsys_cmd far *command,struct lsys_turtlestatei *ts, struct lsys_cmd far **rules,int depth) { struct lsys_cmd far **rulind; int tran; if (overflow) /* integer math routines overflowed */ return NULL; if (stackavail() < 400) { /* leave some margin for calling subrtns */ ts->stackoflow = 1; return NULL; } while (command->ch && command->ch !=']') { if (!(ts->counter++)) { if (keypressed()) { ts->counter--; return NULL; } } tran=0; if (depth) { for(rulind=rules;*rulind;rulind++) if ((*rulind)->ch == command->ch) { tran=1; if (drawLSysI((*rulind)+1,ts,rules,depth-1) == NULL) return NULL; } } if (!depth||!tran) { if (command->f) { ts->num = command->n; (*command->f)(ts); } else if (command->ch == '[') { char saveang,saverev,savecolor; long savesize,savex,savey; unsigned long saverang; saveang=ts->angle; saverev=ts->reverse; savesize=ts->size; saverang=ts->realangle; savex=ts->xpos; savey=ts->ypos; savecolor=ts->curcolor; if ((command=drawLSysI(command+1,ts,rules,depth)) == NULL) return(NULL); ts->angle=saveang; ts->reverse=saverev; ts->size=savesize; ts->realangle=saverang; ts->xpos=savex; ts->ypos=savey; ts->curcolor=savecolor; } } command++; } return command; } static struct lsys_cmd far * LSysISizeTransform(char far *s, struct lsys_turtlestatei *ts) { struct lsys_cmd far *ret; struct lsys_cmd far *doub; int maxval = 10; int n = 0; void (*f)(); long num; void (*plus)() = (ispow2(ts->maxangle)) ? lsysi_doplus_pow2 : lsysi_doplus; void (*minus)() = (ispow2(ts->maxangle)) ? lsysi_dominus_pow2 : lsysi_dominus; void (*pipe)() = (ispow2(ts->maxangle)) ? lsysi_dopipe_pow2 : lsysi_dopipe; void (*slash)() = (cpu >= 386) ? lsysi_doslash_386 : lsysi_doslash; void (*bslash)() = (cpu >= 386) ? lsysi_dobslash_386 : lsysi_dobslash; void (*at)() = (cpu >= 386) ? lsysi_doat_386 : lsysi_doat; void (*dogf)() = (cpu >= 386) ? lsysi_dosizegf_386 : lsysi_dosizegf; ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd)); if (ret == NULL) { ts->stackoflow = 1; return NULL; } while (*s) { f = NULL; num = 0; ret[n].ch = *s; switch (*s) { case '+': f = plus; break; case '-': f = minus; break; case '/': f = slash; num = (long) (getnumber(&s) * 11930465L); break; case '\\': f = bslash; num = (long) (getnumber(&s) * 11930465L); break; case '@': f = at; num = FIXEDPT(getnumber(&s)); break; case '|': f = pipe; break; case '!': f = lsysi_dobang; break; case 'd': case 'm': f = lsysi_dosizedm; break; case 'g': case 'f': f = dogf; break; case '[': num = 1; break; case ']': num = 2; break; default: num = 3; break; } #ifdef XFRACT ret[n].f = (void (*)())f; #else ret[n].f = (void (*)(struct lsys_turtlestatei *))f; #endif ret[n].n = num; if (++n == maxval) { doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd)); farmemfree(ret); ret = doub; maxval <<= 1; } s++; } ret[n].ch = 0; ret[n].f = NULL; ret[n].n = 0; n++; doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, n*sizeof(struct lsys_cmd)); farmemfree(ret); return doub; } static struct lsys_cmd far * LSysIDrawTransform(char far *s, struct lsys_turtlestatei *ts) { struct lsys_cmd far *ret; struct lsys_cmd far *doub; int maxval = 10; int n = 0; void (*f)(); long num; void (*plus)() = (ispow2(ts->maxangle)) ? lsysi_doplus_pow2 : lsysi_doplus; void (*minus)() = (ispow2(ts->maxangle)) ? lsysi_dominus_pow2 : lsysi_dominus; void (*pipe)() = (ispow2(ts->maxangle)) ? lsysi_dopipe_pow2 : lsysi_dopipe; void (*slash)() = (cpu >= 386) ? lsysi_doslash_386 : lsysi_doslash; void (*bslash)() = (cpu >= 386) ? lsysi_dobslash_386 : lsysi_dobslash; void (*at)() = (cpu >= 386) ? lsysi_doat_386 : lsysi_doat; void (*drawg)() = (cpu >= 386) ? lsysi_dodrawg_386 : lsysi_dodrawg; ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd)); if (ret == NULL) { ts->stackoflow = 1; return NULL; } while (*s) { f = NULL; num = 0; ret[n].ch = *s; switch (*s) { case '+': f = plus; break; case '-': f = minus; break; case '/': f = slash; num = (long) (getnumber(&s) * 11930465L); break; case '\\': f = bslash; num = (long) (getnumber(&s) * 11930465L); break; case '@': f = at; num = FIXEDPT(getnumber(&s)); break; case '|': f = pipe; break; case '!': f = lsysi_dobang; break; case 'd': f = lsysi_dodrawd; break; case 'm': f = lsysi_dodrawm; break; case 'g': f = drawg; break; case 'f': f = lsysi_dodrawf; break; case 'c': f = lsysi_dodrawc; num = (long) getnumber(&s); break; case '<': f = lsysi_dodrawlt; num = (long) getnumber(&s); break; case '>': f = lsysi_dodrawgt; num = (long) getnumber(&s); break; case '[': num = 1; break; case ']': num = 2; break; default: num = 3; break; } #ifdef XFRACT ret[n].f = (void (*)())f; #else ret[n].f = (void (*)(struct lsys_turtlestatei *))f; #endif ret[n].n = num; if (++n == maxval) { doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd)); farmemfree(ret); ret = doub; maxval <<= 1; } s++; } ret[n].ch = 0; ret[n].f = NULL; ret[n].n = 0; n++; doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd)); if (doub == NULL) { farmemfree(ret); ts->stackoflow = 1; return NULL; } far_memcpy(doub, ret, n*sizeof(struct lsys_cmd)); farmemfree(ret); return doub; } static void _fastcall lsysi_dosincos(void) { double locaspect; double TWOPI = 2.0 * PI; double twopimax; double twopimaxi; double s, c; int i; locaspect=screenaspect*xdots/ydots; twopimax = TWOPI / maxangle; for(i=0;i. * */ #include #include #include #include "port.h" #include "prototyp.h" #define DBLS double #define FABS(x) fabs(x) #define FREXP(x,y) frexp(x,y) #define TRUE 1 #define FALSE 0 #define EVERY 15 #define BASIN_COLOR 0 extern int rhombus_stack[10]; extern int rhombus_depth; extern int max_rhombus_depth; extern int minstackavail; extern int minstack; /* need this much stack to recurse */ static DBLS twidth; static DBLS equal; #if 0 static long iteration1(register DBLS cr, register DBLS ci, register DBLS re, register DBLS im, long start) { DBLS oldreal, oldimag, newreal, newimag, magnitude; long color; magnitude = 0.0; color = start; oldreal = re; oldimag = im; while ((magnitude < 16.0) && (color < maxit)) { newreal = oldreal * oldreal - oldimag * oldimag + cr; newimag = 2 * oldreal * oldimag + ci; color++; oldreal = newreal; oldimag = newimag; magnitude = newreal * newreal + newimag * newimag; } if (color >= maxit) color = BASIN_COLOR; return((int)color); } #endif static long iteration(register DBLS cr, register DBLS ci, register DBLS re, register DBLS im, long start) { old.x = re; old.y = im; tempsqrx = sqr(old.x); tempsqry = sqr(old.y); floatparm = &init; floatparm->x = cr; floatparm->y = ci; while(ORBITCALC()==0 && start < maxit) start++; if (start >= maxit) start = BASIN_COLOR; return(start); } #if 0 JuliafpFractal() { /* floating point version of classical Mandelbrot/Julia */ new.x = tempsqrx - tempsqry + floatparm->x; new.y = 2.0 * old.x * old.y + floatparm->y; return(floatbailout()); } #endif static void puthline(int x1,int y1,int x2,int color) { int x; for(x=x1;x<=x2;x++) (*plot)(x,y1,color); } static void putbox(int x1, int y1, int x2, int y2, int color) { for(; y1<=y2; y1++) puthline(x1,y1,x2,color); } /* maximum side length beyond which we start regular scanning instead of subdividing */ #define SCAN 16 /* pixel interleave used in scanning */ #define INTERLEAVE 4 /* compute the value of the interpolation polynomial at (x,y) */ #define GET_REAL(x,y) \ interpolate(cim1,midi,cim2,\ interpolate(cre1,midr,cre2,zre1,zre5,zre2,x),\ interpolate(cre1,midr,cre2,zre6,zre9,zre7,x),\ interpolate(cre1,midr,cre2,zre3,zre8,zre4,x),y) #define GET_IMAG(x,y) \ interpolate(cre1,midr,cre2,\ interpolate(cim1,midi,cim2,zim1,zim6,zim3,y),\ interpolate(cim1,midi,cim2,zim5,zim9,zim8,y),\ interpolate(cim1,midi,cim2,zim2,zim7,zim4,y),x) /* compute the value of the interpolation polynomial at (x,y) from saved values before interpolation failed to stay within tolerance */ #define GET_SAVED_REAL(x,y) \ interpolate(cim1,midi,cim2,\ interpolate(cre1,midr,cre2,sr1,sr5,sr2,x),\ interpolate(cre1,midr,cre2,sr6,sr9,sr7,x),\ interpolate(cre1,midr,cre2,sr3,sr8,sr4,x),y) #define GET_SAVED_IMAG(x,y) \ interpolate(cre1,midr,cre2,\ interpolate(cim1,midi,cim2,si1,si6,si3,y),\ interpolate(cim1,midi,cim2,si5,si9,si8,y),\ interpolate(cim1,midi,cim2,si2,si7,si4,y),x) /* compute the value of the interpolation polynomial at (x,y) during scanning. Here, key values do not change, so we can precompute coefficients in one direction and simply evaluate the polynomial during scanning. */ #define GET_SCAN_REAL(x,y) \ interpolate(cim1,midi,cim2,\ EVALUATE(cre1,midr,br10,br11,br12,x),\ EVALUATE(cre1,midr,br20,br21,br22,x),\ EVALUATE(cre1,midr,br30,br31,br32,x),y) #define GET_SCAN_IMAG(x,y) \ interpolate(cre1,midr,cre2,\ EVALUATE(cim1,midi,bi10,bi11,bi12,y),\ EVALUATE(cim1,midi,bi20,bi21,bi22,y),\ EVALUATE(cim1,midi,bi30,bi31,bi32,y),x) /* compute coefficients of Newton polynomial (b0,..,b2) from (x0,w0),..,(x2,w2). */ #define INTERPOLATE(x0,x1,x2,w0,w1,w2,b0,b1,b2) \ b0=w0;\ b1=(w1-w0)/(x1-x0);\ b2=((w2-w1)/(x2-x1)-b1)/(x2-x0) /* evaluate Newton polynomial given by (x0,b0),(x1,b1) at x:=t */ #define EVALUATE(x0,x1,b0,b1,b2,t) \ ((b2*(t-x1)+b1)*(t-x0)+b0) /* Newton Interpolation. It computes the value of the interpolation polynomial given by (x0,w0)..(x2,w2) at x:=t */ static DBLS interpolate(DBLS x0, DBLS x1, DBLS x2, DBLS w0, DBLS w1, DBLS w2, DBLS t) { register DBLS b0=w0,b1=w1,b2=w2,b; /*b0=(r0*b1-r1*b0)/(x1-x0); b1=(r1*b2-r2*b1)/(x2-x1); b0=(r0*b1-r2*b0)/(x2-x0); return (DBLS)b0;*/ b=(b1-b0)/(x1-x0); return (DBLS)((((b2-b1)/(x2-x1)-b)/(x2-x0))*(t-x1)+b)*(t-x0)+b0; /* if(t= 700) #pragma code_seg ("soi3_text") /* place following in an overlay */ #endif /* SOICompute - Perform simultaneous orbit iteration for a given rectangle Input: cre1..cim2 : values defining the four corners of the rectangle x1..y2 : corresponding pixel values zre1..zim9 : intermediate iterated values of the key points (key values) (cre1,cim1) (cre2,cim1) (zre1,zim1) (zre5,zim5) (zre2,zim2) +------------+------------+ | | | | | | (zre6,zim6) (zre9,zim9) (zre7,zim7) | | | | | | +------------+------------+ (zre3,zim3) (zre8,zim8) (zre4,zim4) (cre1,cim2) (cre2,cim2) iter : current number of iterations */ static DBLS zre1, zim1, zre2, zim2, zre3, zim3, zre4, zim4, zre5, zim5, zre6, zim6, zre7, zim7, zre8, zim8, zre9, zim9; /* The purpose of this macro is to reduce the number of parameters of the function rhombus(), since this is a recursive function, and stack space under DOS is extremely limited. */ #define RHOMBUS(CRE1,CRE2,CIM1,CIM2,X1,X2,Y1,Y2,ZRE1,ZIM1,ZRE2,ZIM2,ZRE3,ZIM3,\ ZRE4, ZIM4, ZRE5, ZIM5,ZRE6, ZIM6, ZRE7, ZIM7, ZRE8, ZIM8, ZRE9, ZIM9,ITER) \ zre1=(ZRE1);zim1=(ZIM1);\ zre2=(ZRE2);zim2=(ZIM2);\ zre3=(ZRE3);zim3=(ZIM3);\ zre4=(ZRE4);zim4=(ZIM4);\ zre5=(ZRE5);zim5=(ZIM5);\ zre6=(ZRE6);zim6=(ZIM6);\ zre7=(ZRE7);zim7=(ZIM7);\ zre8=(ZRE8);zim8=(ZIM8);\ zre9=(ZRE9);zim9=(ZIM9);\ status=rhombus((CRE1),(CRE2),(CIM1),(CIM2),(X1),(X2),(Y1),(Y2),(ITER)) static int rhombus(DBLS cre1, DBLS cre2, DBLS cim1, DBLS cim2, int x1, int x2, int y1, int y2, long iter) { /* The following variables do not need their values saved */ /* used in scanning */ static long far savecolor, color, helpcolor; static int far x,y,z,savex; #if 0 static DBLS far re,im,restep,imstep,interstep,helpre; static DBLS far zre,zim; /* interpolation coefficients */ static DBLS far br10,br11,br12,br20,br21,br22,br30,br31,br32; static DBLS far bi10,bi11,bi12,bi20,bi21,bi22,bi30,bi31,bi32; /* ratio of interpolated test point to iterated one */ static DBLS far l1,l2; /* squares of key values */ static DBLS far rq1,iq1; static DBLS far rq2,iq2; static DBLS far rq3,iq3; static DBLS far rq4,iq4; static DBLS far rq5,iq5; static DBLS far rq6,iq6; static DBLS far rq7,iq7; static DBLS far rq8,iq8; static DBLS far rq9,iq9; /* test points */ static DBLS far cr1,cr2; static DBLS far ci1,ci2; static DBLS far tzr1,tzi1,tzr2,tzi2,tzr3,tzi3,tzr4,tzi4; static DBLS far trq1,tiq1,trq2,tiq2,trq3,tiq3,trq4,tiq4; #else #define re mem_static[ 0] #define im mem_static[ 1] #define restep mem_static[ 2] #define imstep mem_static[ 3] #define interstep mem_static[ 4] #define helpre mem_static[ 5] #define zre mem_static[ 6] #define zim mem_static[ 7] #define br10 mem_static[ 8] #define br11 mem_static[ 9] #define br12 mem_static[10] #define br20 mem_static[11] #define br21 mem_static[12] #define br22 mem_static[13] #define br30 mem_static[14] #define br31 mem_static[15] #define br32 mem_static[16] #define bi10 mem_static[17] #define bi11 mem_static[18] #define bi12 mem_static[19] #define bi20 mem_static[20] #define bi21 mem_static[21] #define bi22 mem_static[22] #define bi30 mem_static[23] #define bi31 mem_static[24] #define bi32 mem_static[25] #define l1 mem_static[26] #define l2 mem_static[27] #define rq1 mem_static[28] #define iq1 mem_static[29] #define rq2 mem_static[30] #define iq2 mem_static[31] #define rq3 mem_static[32] #define iq3 mem_static[33] #define rq4 mem_static[34] #define iq4 mem_static[35] #define rq5 mem_static[36] #define iq5 mem_static[37] #define rq6 mem_static[38] #define iq6 mem_static[39] #define rq7 mem_static[40] #define iq7 mem_static[41] #define rq8 mem_static[42] #define iq8 mem_static[43] #define rq9 mem_static[44] #define iq9 mem_static[45] #define cr1 mem_static[46] #define cr2 mem_static[47] #define ci1 mem_static[48] #define ci2 mem_static[49] #define tzr1 mem_static[50] #define tzi1 mem_static[51] #define tzr2 mem_static[52] #define tzi2 mem_static[53] #define tzr3 mem_static[54] #define tzi3 mem_static[55] #define tzr4 mem_static[56] #define tzi4 mem_static[57] #define trq1 mem_static[58] #define tiq1 mem_static[59] #define trq2 mem_static[60] #define tiq2 mem_static[61] #define trq3 mem_static[62] #define tiq3 mem_static[63] #define trq4 mem_static[64] #define tiq4 mem_static[65] #endif /* number of iterations before SOI iteration cycle */ static long far before; static int far avail; /* the variables below need to have local copies for recursive calls */ int far *mem_int; DBLS far *mem; DBLS far *mem_static; /* center of rectangle */ DBLS midr=(cre1+cre2)/2,midi=(cim1+cim2)/2; #if 0 /* saved values of key values */ DBLS sr1,si1,sr2,si2,sr3,si3,sr4,si4; DBLS sr5,si5,sr6,si6,sr7,si7,sr8,si8,sr9,si9; /* key values for subsequent rectangles */ DBLS re10,re11,re12,re13,re14,re15,re16,re17,re18,re19,re20,re21; DBLS im10,im11,im12,im13,im14,im15,im16,im17,im18,im19,im20,im21; DBLS re91,re92,re93,re94,im91,im92,im93,im94; #else #define esc1 mem_int[0] #define esc2 mem_int[1] #define esc3 mem_int[2] #define esc4 mem_int[3] #define esc5 mem_int[4] #define esc6 mem_int[5] #define esc7 mem_int[6] #define esc8 mem_int[7] #define esc9 mem_int[8] #define tesc1 mem_int[9] #define tesc2 mem_int[10] #define tesc3 mem_int[11] #define tesc4 mem_int[12] #define sr1 mem[ 0] #define si1 mem[ 1] #define sr2 mem[ 2] #define si2 mem[ 3] #define sr3 mem[ 4] #define si3 mem[ 5] #define sr4 mem[ 6] #define si4 mem[ 7] #define sr5 mem[ 8] #define si5 mem[ 9] #define sr6 mem[10] #define si6 mem[11] #define sr7 mem[12] #define si7 mem[13] #define sr8 mem[14] #define si8 mem[15] #define sr9 mem[16] #define si9 mem[17] #define re10 mem[18] #define re11 mem[19] #define re12 mem[20] #define re13 mem[21] #define re14 mem[22] #define re15 mem[23] #define re16 mem[24] #define re17 mem[25] #define re18 mem[26] #define re19 mem[27] #define re20 mem[28] #define re21 mem[29] #define im10 mem[30] #define im11 mem[31] #define im12 mem[32] #define im13 mem[33] #define im14 mem[34] #define im15 mem[35] #define im16 mem[36] #define im17 mem[37] #define im18 mem[38] #define im19 mem[39] #define im20 mem[40] #define im21 mem[41] #define re91 mem[42] #define re92 mem[43] #define re93 mem[44] #define re94 mem[45] #define im91 mem[46] #define im92 mem[47] #define im93 mem[48] #define im94 mem[49] #endif int status = 0; rhombus_depth++; #if 1 /* what we go through under DOS to deal with memory! We re-use the sizeofstring array (8k). The first 660 bytes is for static variables, then we make our own "stack" with copies for each recursive call of rhombus() for the rest. */ mem_int = (int far *)sizeofstring; mem_static = (DBLS far *)(mem_int + 13); mem = mem_static+ 66 + 50*rhombus_depth; #endif if((avail = stackavail()) < minstackavail) minstackavail = avail; if(rhombus_depth > max_rhombus_depth) max_rhombus_depth = rhombus_depth; rhombus_stack[rhombus_depth] = avail; if(keypressed()) { status = 1; goto rhombus_done; } if(iter>maxit) { putbox(x1,y1,x2,y2,0); status = 0; goto rhombus_done; } if((y2-y1<=SCAN) || (avail < minstack)) { /* finish up the image by scanning the rectangle */ scan: INTERPOLATE(cre1,midr,cre2,zre1,zre5,zre2,br10,br11,br12); INTERPOLATE(cre1,midr,cre2,zre6,zre9,zre7,br20,br21,br22); INTERPOLATE(cre1,midr,cre2,zre3,zre8,zre4,br30,br31,br32); INTERPOLATE(cim1,midi,cim2,zim1,zim6,zim3,bi10,bi11,bi12); INTERPOLATE(cim1,midi,cim2,zim5,zim9,zim8,bi20,bi21,bi22); INTERPOLATE(cim1,midi,cim2,zim2,zim7,zim4,bi30,bi31,bi32); restep=(cre2-cre1)/(x2-x1); imstep=(cim2-cim1)/(y2-y1); interstep=INTERLEAVE*restep; for(y=y1, im=cim1; yx-INTERLEAVE; z--,helpre-=restep) { zre=GET_SCAN_REAL(helpre,im); zim=GET_SCAN_IMAG(helpre,im); helpcolor=iteration(helpre,im,zre,zim,iter); if(helpcolor < 0) { status = 1; goto rhombus_done; } else if(helpcolor==savecolor) break; (*plot)(z,y,(int)(helpcolor&255)); } if(savexsavex; z--,helpre-=restep) { zre=GET_SCAN_REAL(helpre,im); zim=GET_SCAN_IMAG(helpre,im); helpcolor=iteration(helpre,im,zre,zim,iter); if(helpcolor < 0) { status = 1; goto rhombus_done; } else if(helpcolor==savecolor) break; (*plot)(z,y,(int)(helpcolor&255)); } if(savexx = cr;\ floatparm->y = ci;\ esc = ORBITCALC();\ rq = tempsqrx;\ iq = tempsqry;\ zr = new.x;\ zi = new.y #define SOI_ORBIT(zr,rq,zi,iq,cr,ci,esc) \ zi=(zi+zi)*zr+ci;\ zr=rq-iq+cr;\ rq=zr*zr;\ iq=zi*zi;\ esc = ((rq+iq)>16.0)?1:0 /* iterate key values */ SOI_ORBIT(zre1,rq1,zim1,iq1,cre1,cim1,esc1); /* zim1=(zim1+zim1)*zre1+cim1; zre1=rq1-iq1+cre1; rq1=zre1*zre1; iq1=zim1*zim1; */ SOI_ORBIT(zre2,rq2,zim2,iq2,cre2,cim1,esc2); /* zim2=(zim2+zim2)*zre2+cim1; zre2=rq2-iq2+cre2; rq2=zre2*zre2; iq2=zim2*zim2; */ SOI_ORBIT(zre3,rq3,zim3,iq3,cre1,cim2,esc3); /* zim3=(zim3+zim3)*zre3+cim2; zre3=rq3-iq3+cre1; rq3=zre3*zre3; iq3=zim3*zim3; */ SOI_ORBIT(zre4,rq4,zim4,iq4,cre2,cim2,esc4); /* zim4=(zim4+zim4)*zre4+cim2; zre4=rq4-iq4+cre2; rq4=zre4*zre4; iq4=zim4*zim4; */ SOI_ORBIT(zre5,rq5,zim5,iq5,midr,cim1,esc5); /* zim5=(zim5+zim5)*zre5+cim1; zre5=rq5-iq5+midr; rq5=zre5*zre5; iq5=zim5*zim5; */ SOI_ORBIT(zre6,rq6,zim6,iq6,cre1,midi,esc6); /* zim6=(zim6+zim6)*zre6+midi; zre6=rq6-iq6+cre1; rq6=zre6*zre6; iq6=zim6*zim6; */ SOI_ORBIT(zre7,rq7,zim7,iq7,cre2,midi,esc7); /* zim7=(zim7+zim7)*zre7+midi; zre7=rq7-iq7+cre2; rq7=zre7*zre7; iq7=zim7*zim7; */ SOI_ORBIT(zre8,rq8,zim8,iq8,midr,cim2,esc8); /* zim8=(zim8+zim8)*zre8+cim2; zre8=rq8-iq8+midr; rq8=zre8*zre8; iq8=zim8*zim8; */ SOI_ORBIT(zre9,rq9,zim9,iq9,midr,midi,esc9); /* zim9=(zim9+zim9)*zre9+midi; zre9=rq9-iq9+midr; rq9=zre9*zre9; iq9=zim9*zim9; */ /* iterate test point */ SOI_ORBIT(tzr1,trq1,tzi1,tiq1,cr1,ci1,tesc1); /* tzi1=(tzi1+tzi1)*tzr1+ci1; tzr1=trq1-tiq1+cr1; trq1=tzr1*tzr1; tiq1=tzi1*tzi1; */ SOI_ORBIT(tzr2,trq2,tzi2,tiq2,cr2,ci1,tesc2); /* tzi2=(tzi2+tzi2)*tzr2+ci1; tzr2=trq2-tiq2+cr2; trq2=tzr2*tzr2; tiq2=tzi2*tzi2; */ SOI_ORBIT(tzr3,trq3,tzi3,tiq3,cr1,ci2,tesc3); /* tzi3=(tzi3+tzi3)*tzr3+ci2; tzr3=trq3-tiq3+cr1; trq3=tzr3*tzr3; tiq3=tzi3*tzi3; */ SOI_ORBIT(tzr4,trq4,tzi4,tiq4,cr2,ci2,tesc4); /* tzi4=(tzi4+tzi4)*tzr4+ci2; tzr4=trq4-tiq4+cr2; trq4=tzr4*tzr4; tiq4=tzi4*tzi4; */ iter++; /* if one of the iterated values bails out, subdivide */ /* if((rq1+iq1)>16.0|| (rq2+iq2)>16.0|| (rq3+iq3)>16.0|| (rq4+iq4)>16.0|| (rq5+iq5)>16.0|| (rq6+iq6)>16.0|| (rq7+iq7)>16.0|| (rq8+iq8)>16.0|| (rq9+iq9)>16.0|| (trq1+tiq1)>16.0|| (trq2+tiq2)>16.0|| (trq3+tiq3)>16.0|| (trq4+tiq4)>16.0) break; */ if(esc1||esc2||esc3||esc4||esc5||esc6||esc7||esc8||esc9|| tesc1||tesc2||tesc3||tesc4) break; /* if maximum number of iterations is reached, the whole rectangle can be assumed part of M. This is of course best case behavior of SOI, we seldomly get there */ if(iter>maxit) { putbox(x1,y1,x2,y2,0); status = 0; goto rhombus_done; } /* now for all test points, check whether they exceed the allowed tolerance. if so, subdivide */ l1=GET_REAL(cr1,ci1); l1=(tzr1==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr1; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr1,ci1); l2=(tzi1==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi1; if(FABS(1.0-l2)>twidth) break; l1=GET_REAL(cr2,ci1); l1=(tzr2==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr2; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr2,ci1); l2=(tzi2==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi2; if(FABS(1.0-l2)>twidth) break; l1=GET_REAL(cr1,ci2); l1=(tzr3==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr3; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr1,ci2); l2=(tzi3==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi3; if(FABS(1.0-l2)>twidth) break; l1=GET_REAL(cr2,ci2); l1=(tzr4==0.0)? (l1==0.0)?1.0:1000.0: l1/tzr4; if(FABS(1.0-l1)>twidth) break; l2=GET_IMAG(cr2,ci2); l2=(tzi4==0.0)? (l2==0.0)?1.0:1000.0: l2/tzi4; if(FABS(1.0-l2)>twidth) break; } iter--; /* this is a little heuristic I tried to improve performance. */ if(iter-before<10) { zre1=sr1; zim1=si1; zre2=sr2; zim2=si2; zre3=sr3; zim3=si3; zre4=sr4; zim4=si4; zre5=sr5; zim5=si5; zre6=sr6; zim6=si6; zre7=sr7; zim7=si7; zre8=sr8; zim8=si8; zre9=sr9; zim9=si9; goto scan; } /* compute key values for subsequent rectangles */ re10=interpolate(cre1,midr,cre2,sr1,sr5,sr2,cr1); im10=interpolate(cre1,midr,cre2,si1,si5,si2,cr1); re11=interpolate(cre1,midr,cre2,sr1,sr5,sr2,cr2); im11=interpolate(cre1,midr,cre2,si1,si5,si2,cr2); re20=interpolate(cre1,midr,cre2,sr3,sr8,sr4,cr1); im20=interpolate(cre1,midr,cre2,si3,si8,si4,cr1); re21=interpolate(cre1,midr,cre2,sr3,sr8,sr4,cr2); im21=interpolate(cre1,midr,cre2,si3,si8,si4,cr2); re15=interpolate(cre1,midr,cre2,sr6,sr9,sr7,cr1); im15=interpolate(cre1,midr,cre2,si6,si9,si7,cr1); re16=interpolate(cre1,midr,cre2,sr6,sr9,sr7,cr2); im16=interpolate(cre1,midr,cre2,si6,si9,si7,cr2); re12=interpolate(cim1,midi,cim2,sr1,sr6,sr3,ci1); im12=interpolate(cim1,midi,cim2,si1,si6,si3,ci1); re14=interpolate(cim1,midi,cim2,sr2,sr7,sr4,ci1); im14=interpolate(cim1,midi,cim2,si2,si7,si4,ci1); re17=interpolate(cim1,midi,cim2,sr1,sr6,sr3,ci2); im17=interpolate(cim1,midi,cim2,si1,si6,si3,ci2); re19=interpolate(cim1,midi,cim2,sr2,sr7,sr4,ci2); im19=interpolate(cim1,midi,cim2,si2,si7,si4,ci2); re13=interpolate(cim1,midi,cim2,sr5,sr9,sr8,ci1); im13=interpolate(cim1,midi,cim2,si5,si9,si8,ci1); re18=interpolate(cim1,midi,cim2,sr5,sr9,sr8,ci2); im18=interpolate(cim1,midi,cim2,si5,si9,si8,ci2); re91=GET_SAVED_REAL(cr1,ci1); re92=GET_SAVED_REAL(cr2,ci1); re93=GET_SAVED_REAL(cr1,ci2); re94=GET_SAVED_REAL(cr2,ci2); im91=GET_SAVED_IMAG(cr1,ci1); im92=GET_SAVED_IMAG(cr2,ci1); im93=GET_SAVED_IMAG(cr1,ci2); im94=GET_SAVED_IMAG(cr2,ci2); RHOMBUS(cre1,midr,cim1,midi,x1,((x1+x2)>>1),y1,((y1+y2)>>1), sr1,si1, sr5,si5, sr6,si6, sr9,si9, re10,im10, re12,im12, re13,im13, re15,im15, re91,im91, iter); RHOMBUS(midr,cre2,cim1,midi,(x1+x2)>>1,x2,y1,(y1+y2)>>1, sr5,si5, sr2,si2, sr9,si9, sr7,si7, re11,im11, re13,im13, re14,im14, re16,im16, re92,im92, iter); RHOMBUS(cre1,midr,midi,cim2,x1,(x1+x2)>>1,(y1+y2)>>1,y2, sr6,si6, sr9,si9, sr3,si3, sr8,si8, re15,im15, re17,im17, re18,im18, re20,im20, re93,im93, iter); RHOMBUS(midr,cre2,midi,cim2,(x1+x2)>>1,x2,(y1+y2)>>1,y2, sr9,si9, sr7,si7, sr8,si8, sr4,si4, re16,im16, re18,im18, re19,im19, re21,im21, re94,im94, iter); rhombus_done: rhombus_depth--; return(status); } #if (_MSC_VER >= 700) #pragma code_seg () #endif void soi(void) { int status; DBLS tolerance=0.1; DBLS stepx, stepy; DBLS xxminl, xxmaxl, yyminl, yymaxl; minstackavail = 30000; rhombus_depth = -1; max_rhombus_depth = 0; if(bf_math) { xxminl = (DBLS)bftofloat(bfxmin); yyminl = (DBLS)bftofloat(bfymin); xxmaxl = (DBLS)bftofloat(bfxmax); yymaxl = (DBLS)bftofloat(bfymax); } else { xxminl = xxmin; yyminl = yymin; xxmaxl = xxmax; yymaxl = yymax; } twidth=tolerance/(xdots-1); stepx = (xxmaxl - xxminl) / xdots; stepy = (yyminl - yymaxl) / ydots; equal = (stepx < stepy ? stepx : stepy); RHOMBUS(xxminl,xxmaxl,yymaxl,yyminl, 0,xdots,0,ydots, xxminl,yymaxl, xxmaxl,yymaxl, xxminl,yyminl, xxmaxl,yyminl, (xxmaxl+xxminl)/2,yymaxl, xxminl,(yymaxl+yyminl)/2, xxmaxl,(yymaxl+yyminl)/2, (xxmaxl+xxminl)/2,yyminl, (xxminl+xxmaxl)/2,(yymaxl+yyminl)/2, 1); } xfractint-20.4.10.orig/common/evolve.c0000644000000000000000000010304610150633601014440 0ustar #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" #define PARMBOX 128 U16 gene_handle = 0; /* px and py are coordinates in the parameter grid (small images on screen) */ /* evolving = flag, gridsz = dimensions of image grid (gridsz x gridsz) */ int px,py,evolving,gridsz; #define MAXGRIDSZ 51 /* This is arbitrary, = 1024/20 */ static int far ecountbox[MAXGRIDSZ][MAXGRIDSZ]; unsigned int this_gen_rseed; /* used to replay random sequences to obtain correct values when selecting a seed image for next generation */ double opx,opy,newopx,newopy,paramrangex,paramrangey,dpx,dpy,fiddlefactor; double fiddle_reduction; double parmzoom; char odpx,odpy,newodpx,newodpy; /* offset for discrete parameters x and y..*/ /* used for things like inside or outside types, bailout tests, trig fn etc */ /* variation factors, opx,opy, paramrangex/y dpx, dpy.. used in field mapping for smooth variation across screen. opx =offset param x, dpx = delta param per image, paramrangex = variation across grid of param ...likewise for py */ /* fiddlefactor is amount of random mutation used in random modes , fiddle_reduction is used to decrease fiddlefactor from one generation to the next to eventually produce a stable population */ U16 prmboxhandle = 0; U16 imgboxhandle = 0; int prmboxcount,imgboxcount; U16 oldhistory_handle = 0; char s_random[] = "random"; char s_spread[] = "spread"; char s_xplusy[] = "x+y"; char s_xminusy[] = "x-y"; struct phistory_info /* for saving evolution data of center image */ { double param0; double param1; double param2; double param3; double param4; double param5; double param6; double param7; double param8; double param9; int inside; int outside; int decomp0; double invert0; double invert1; double invert2; BYTE trigndx0; BYTE trigndx1; BYTE trigndx2; BYTE trigndx3; int bailoutest; }; typedef struct phistory_info PARAMHIST; void param_history(int mode); void varydbl(GENEBASE gene[],int randval,int i); int varyint( int randvalue, int limit, int mode); int wrapped_positive_varyint( int randvalue, int limit, int mode ); void varyinside(GENEBASE gene[], int randval, int i); void varyoutside(GENEBASE gene[], int randval, int i); void varypwr2(GENEBASE gene[], int randval, int i); void varytrig(GENEBASE gene[], int randval, int i); void varybotest(GENEBASE gene[], int randval, int i); void varyinv(GENEBASE gene[], int randval, int i); int explore_check(void); void spiralmap(int); static void set_random(int); void set_mutation_level(int); void SetupParamBox(void); void ReleaseParamBox(void); void initgene(void) /* set up pointers and mutation params for all usable image control variables in fractint... revise as necessary when new vars come along... dont forget to increment NUMGENES (in fractint.h ) as well */ { int i = 0; /* 0 = dont vary, 1= with x axis, 2 = with y */ /* 3 = with x+y, 4 = with x-y, 5 = random, 6 = weighted random */ /* Use only 15 letters below: 123456789012345 */ static FCODE s_Param0[] = {"Param 1 real"}; static FCODE s_Param1[] = {"Param 1 imag"}; static FCODE s_Param2[] = {"Param 2 real"}; static FCODE s_Param3[] = {"Param 2 imag"}; static FCODE s_Param4[] = {"Param 3 real"}; static FCODE s_Param5[] = {"Param 3 imag"}; static FCODE s_Param6[] = {"Param 4 real"}; static FCODE s_Param7[] = {"Param 4 imag"}; static FCODE s_Param8[] = {"Param 5 real"}; static FCODE s_Param9[] = {"Param 5 imag"}; static FCODE s_inside[] = {"inside colour"}; static FCODE s_outside[] = {"outside colour"}; static FCODE s_decomp[] = {"decomposition"}; static FCODE s_trigfn1[] = {"trig function 1"}; static FCODE s_trigfn2[] = {"trig fn 2"}; static FCODE s_trigfn3[] = {"trig fn 3"}; static FCODE s_trigfn4[] = {"trig fn 4"}; static FCODE s_botest[] = {"bailout test"}; static FCODE s_invertr[] = {"invert radius"}; static FCODE s_invertx[] = {"invert center x"}; static FCODE s_inverty[] = {"invert center y"}; GENEBASE gene[NUMGENES] = { { ¶m[0], varydbl, 5, "",1 }, { ¶m[1], varydbl, 5, "",1 }, { ¶m[2], varydbl, 0, "",1 }, { ¶m[3], varydbl, 0, "",1 }, { ¶m[4], varydbl, 0, "",1 }, { ¶m[5], varydbl, 0, "",1 }, { ¶m[6], varydbl, 0, "",1 }, { ¶m[7], varydbl, 0, "",1 }, { ¶m[8], varydbl, 0, "",1 }, { ¶m[9], varydbl, 0, "",1 }, { &inside, varyinside, 0, "",2 }, { &outside, varyoutside, 0, "",3 }, { &decomp[0], varypwr2, 0, "",4 }, { &inversion[0],varyinv, 0, "",7 }, { &inversion[1],varyinv, 0, "",7 }, { &inversion[2],varyinv, 0, "",7 }, { &trigndx[0], varytrig, 0, "",5 }, { &trigndx[1], varytrig, 0, "",5 }, { &trigndx[2], varytrig, 0, "",5 }, { &trigndx[3], varytrig, 0, "",5 }, { &bailoutest, varybotest, 0, "",6 } }; i = -1; far_strcpy(gene[++i].name, s_Param0); /* name of var for menus */ far_strcpy(gene[++i].name, s_Param1); far_strcpy(gene[++i].name, s_Param2); far_strcpy(gene[++i].name, s_Param3); far_strcpy(gene[++i].name, s_Param4); far_strcpy(gene[++i].name, s_Param5); far_strcpy(gene[++i].name, s_Param6); far_strcpy(gene[++i].name, s_Param7); far_strcpy(gene[++i].name, s_Param8); far_strcpy(gene[++i].name, s_Param9); far_strcpy(gene[++i].name, s_inside); far_strcpy(gene[++i].name, s_outside); far_strcpy(gene[++i].name, s_decomp); far_strcpy(gene[++i].name, s_invertr); far_strcpy(gene[++i].name, s_invertx); far_strcpy(gene[++i].name, s_inverty); far_strcpy(gene[++i].name, s_trigfn1); far_strcpy(gene[++i].name, s_trigfn2); far_strcpy(gene[++i].name, s_trigfn3); far_strcpy(gene[++i].name, s_trigfn4); far_strcpy(gene[++i].name, s_botest); if (gene_handle == 0) gene_handle = MemoryAlloc((U16)sizeof(gene),1L,FARMEM); MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); } void param_history(int mode) { /* mode = 0 for save old history, mode = 1 for restore old history */ PARAMHIST oldhistory; if (oldhistory_handle == 0) oldhistory_handle = MemoryAlloc((U16)sizeof(oldhistory),1L,FARMEM); if (mode == 0) { /* save the old parameter history */ oldhistory.param0 = param[0]; oldhistory.param1 = param[1]; oldhistory.param2 = param[2]; oldhistory.param3 = param[3]; oldhistory.param4 = param[4]; oldhistory.param5 = param[5]; oldhistory.param6 = param[6]; oldhistory.param7 = param[7]; oldhistory.param8 = param[8]; oldhistory.param9 = param[9]; oldhistory.inside = inside; oldhistory.outside = outside; oldhistory.decomp0 = decomp[0]; oldhistory.invert0 = inversion[0]; oldhistory.invert1 = inversion[1]; oldhistory.invert2 = inversion[2]; oldhistory.trigndx0 = trigndx[0]; oldhistory.trigndx1 = trigndx[1]; oldhistory.trigndx2 = trigndx[2]; oldhistory.trigndx3 = trigndx[3]; oldhistory.bailoutest = bailoutest; MoveToMemory((BYTE *)&oldhistory, (U16)sizeof(oldhistory), 1L, 0L, oldhistory_handle); } if (mode == 1) { /* restore the old parameter history */ MoveFromMemory((BYTE *)&oldhistory, (U16)sizeof(oldhistory), 1L, 0L, oldhistory_handle); param[0] = oldhistory.param0; param[1] = oldhistory.param1; param[2] = oldhistory.param2; param[3] = oldhistory.param3; param[4] = oldhistory.param4; param[5] = oldhistory.param5; param[6] = oldhistory.param6; param[7] = oldhistory.param7; param[8] = oldhistory.param8; param[9] = oldhistory.param9; inside = oldhistory.inside; outside = oldhistory.outside; decomp[0] = oldhistory.decomp0; inversion[0] = oldhistory.invert0; inversion[1] = oldhistory.invert1; inversion[2] = oldhistory.invert2; invert = (inversion[0] == 0.0) ? 0 : 3 ; trigndx[0] = oldhistory.trigndx0; trigndx[1] = oldhistory.trigndx1; trigndx[2] = oldhistory.trigndx2; trigndx[3] = oldhistory.trigndx3; bailoutest = oldhistory.bailoutest; } } void varydbl(GENEBASE gene[],int randval,int i) /* routine to vary doubles */ { int lclpy = gridsz - py - 1; switch(gene[i].mutate) { default: case 0: break; case 1: *(double *)gene[i].addr = px * dpx + opx; /*paramspace x coord * per view delta px + offset */ break; case 2: *(double *)gene[i].addr = lclpy * dpy + opy; /*same for y */ break; case 3: *(double *)gene[i].addr = px*dpx+opx +(lclpy*dpy)+opy; /*and x+y */ break; case 4: *(double *)gene[i].addr = (px*dpx+opx)-(lclpy*dpy+opy); /*and x-y*/ break; case 5: *(double *)gene[i].addr += (((double)randval / RAND_MAX) * 2 * fiddlefactor) - fiddlefactor; break; case 6: /* weighted random mutation, further out = further change */ { int mid = gridsz /2; double radius = sqrt( sqr(px - mid) + sqr(lclpy - mid) ); *(double *)gene[i].addr += ((((double)randval / RAND_MAX) * 2 * fiddlefactor) - fiddlefactor) * radius; } break; } return; } int varyint( int randvalue, int limit, int mode) { int ret = 0; int lclpy = gridsz - py - 1; switch(mode) { default: case 0: break; case 1: /* vary with x */ ret = (odpx+px)%limit; break; case 2: /* vary with y */ ret = (odpy+lclpy)%limit; break; case 3: /* vary with x+y */ ret = (odpx+px+odpy+lclpy)%limit; break; case 4: /* vary with x-y */ ret = (odpx+px)-(odpy+lclpy)%limit; break; case 5: /* random mutation */ ret = randvalue % limit; break; case 6: /* weighted random mutation, further out = further change */ { int mid = gridsz /2; double radius = sqrt( sqr(px - mid) + sqr(lclpy - mid) ); ret = (int)((((randvalue / RAND_MAX) * 2 * fiddlefactor) - fiddlefactor) * radius); ret %= limit; } break; } return(ret); } int wrapped_positive_varyint( int randvalue, int limit, int mode ) { int i; i = varyint(randvalue,limit,mode); if (i < 0) return(limit + i); else return(i); } void varyinside(GENEBASE gene[], int randval, int i) { int choices[9]={-59,-60,-61,-100,-101,-102,-103,-104,-1}; if (gene[i].mutate) *(int*)gene[i].addr=choices[wrapped_positive_varyint(randval,9,gene[i].mutate)]; return; } void varyoutside(GENEBASE gene[], int randval, int i) { int choices[8]={-1,-2,-3,-4,-5,-6,-7,-8}; if (gene[i].mutate) *(int*)gene[i].addr=choices[wrapped_positive_varyint(randval,8,gene[i].mutate)]; return; } void varybotest(GENEBASE gene[], int randval, int i) { int choices[7]={Mod, Real, Imag, Or, And, Manh, Manr}; if (gene[i].mutate) { *(int*)gene[i].addr=choices[wrapped_positive_varyint(randval,7,gene[i].mutate)]; /* move this next bit to varybot where it belongs */ setbailoutformula(bailoutest); } return; } void varypwr2(GENEBASE gene[], int randval, int i) { int choices[9]={0,2,4,8,16,32,64,128,256}; if (gene[i].mutate) *(int*)gene[i].addr=choices[wrapped_positive_varyint(randval,9,gene[i].mutate)]; return; } void varytrig(GENEBASE gene[], int randval, int i) { if (gene[i].mutate) /* Changed following to BYTE since trigfn is an array of BYTEs and if one */ /* of the functions isn't varied, it's value was being zeroed by the high */ /* BYTE of the preceeding function. JCO 2 MAY 2001 */ *(BYTE*)gene[i].addr=(BYTE)wrapped_positive_varyint(randval,numtrigfn,gene[i].mutate); /* replaced '30' with numtrigfn, set in prompts1.c */ set_trig_pointers(5); /*set all trig ptrs up*/ return; } void varyinv(GENEBASE gene[], int randval, int i) { if (gene[i].mutate) varydbl(gene,randval,i); invert = (inversion[0] == 0.0) ? 0 : 3 ; } #define LOADCHOICES(X) {\ static FCODE tmp[] = { X };\ far_strcpy(ptr,(char far *)tmp);\ choices[++k]= ptr;\ ptr += sizeof(tmp);\ } /* --------------------------------------------------------------------- */ /* get_evolve_params() is called from FRACTINT.C whenever the 'ctrl_e' key is pressed. Return codes are: -1 routine was ESCAPEd - no need to re-generate the images 0 minor variable changed. No need to re-generate the image. 1 major parms changed. Re-generate the images. */ int get_the_rest(void) { char *evolvmodes[]={s_no,s_x,s_y,s_xplusy,s_xminusy,s_random,s_spread}; static FCODE o_hdg[]={"Variable tweak central 2 of 2"}; int i,k,num, numtrig; char hdg[sizeof(o_hdg)]; char far *choices[20]; char far *ptr; struct fullscreenvalues uvalues[20]; GENEBASE gene[NUMGENES]; far_strcpy(hdg,o_hdg); ptr = (char far *)MK_FP(extraseg,0); MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); numtrig = (curfractalspecific->flags >> 6) & 7; if(fractype==FORMULA || fractype==FFORMULA ) { numtrig = maxfn; } choose_vars_restart: k = -1; for (num = MAXPARAMS; num < (NUMGENES - 5); num++) { choices[++k]=gene[num].name; uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 7; uvalues[k].uval.ch.llen = 7; uvalues[k].uval.ch.list = evolvmodes; uvalues[k].uval.ch.val = gene[num].mutate; } for (num = (NUMGENES - 5); num < (NUMGENES - 5 + numtrig); num++) { choices[++k]=gene[num].name; uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 7; uvalues[k].uval.ch.llen = 7; uvalues[k].uval.ch.list = evolvmodes; uvalues[k].uval.ch.val = gene[num].mutate; } if (curfractalspecific->calctype == StandardFractal && (curfractalspecific->flags & BAILTEST) ) { choices[++k]=gene[NUMGENES - 1].name; uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 7; uvalues[k].uval.ch.llen = 7; uvalues[k].uval.ch.list = evolvmodes; uvalues[k].uval.ch.val = gene[NUMGENES - 1].mutate; } LOADCHOICES(""); uvalues[k].type = '*'; LOADCHOICES("Press F2 to set all to off"); uvalues[k].type ='*'; LOADCHOICES("Press F3 to set all on"); uvalues[k].type = '*'; LOADCHOICES("Press F4 to randomize all"); uvalues[k].type = '*'; i = fullscreen_prompt(hdg,k+1,choices,uvalues,28,NULL); switch(i) { case F2: /* set all off */ for (num = MAXPARAMS; num < NUMGENES; num++) gene[num].mutate = 0; goto choose_vars_restart; case F3: /* set all on..alternate x and y for field map */ for (num = MAXPARAMS; num < NUMGENES; num ++ ) gene[num].mutate = (char)((num % 2) + 1); goto choose_vars_restart; case F4: /* Randomize all */ for (num =MAXPARAMS; num < NUMGENES; num ++ ) gene[num].mutate = (char)(rand() % 6); goto choose_vars_restart; case -1: return(-1); default: break; } /* read out values */ k = -1; for ( num = MAXPARAMS; num < (NUMGENES - 5); num++) gene[num].mutate = (char)(uvalues[++k].uval.ch.val); for (num = (NUMGENES - 5); num < (NUMGENES - 5 + numtrig); num++) gene[num].mutate = (char)(uvalues[++k].uval.ch.val); if (curfractalspecific->calctype == StandardFractal && (curfractalspecific->flags & BAILTEST) ) gene[NUMGENES - 1].mutate = (char)(uvalues[++k].uval.ch.val); MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); return(1); /* if you were here, you want to regenerate */ } int get_variations(void) { char *evolvmodes[]={s_no,s_x,s_y,s_xplusy,s_xminusy,s_random,s_spread}; static FCODE o_hdg[]={"Variable tweak central 1 of 2"}; int i,k,num, numparams; char hdg[sizeof(o_hdg)]; char far *choices[20]; char far *ptr; struct fullscreenvalues uvalues[20]; GENEBASE gene[NUMGENES]; int firstparm = 0; int lastparm = MAXPARAMS; int chngd = -1; far_strcpy(hdg,o_hdg); ptr = (char far *)MK_FP(extraseg,0); MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); if(fractype == FORMULA || fractype == FFORMULA) { if(uses_p1) /* set first parameter */ firstparm = 0; else if(uses_p2) firstparm = 2; else if(uses_p3) firstparm = 4; else if(uses_p4) firstparm = 6; else firstparm = 8; /* uses_p5 or no parameter */ if(uses_p5) /* set last parameter */ lastparm = 10; else if(uses_p4) lastparm = 8; else if(uses_p3) lastparm = 6; else if(uses_p2) lastparm = 4; else lastparm = 2; /* uses_p1 or no parameter */ } numparams = 0; for (i = firstparm; i < lastparm; i++) { if (typehasparm(julibrot?neworbittype:fractype,i,NULL)==0) { if(fractype == FORMULA || fractype == FFORMULA) if(paramnotused(i)) continue; break; } numparams++; } if (fractype != FORMULA && fractype != FFORMULA) lastparm = numparams; choose_vars_restart: k = -1; for (num = firstparm; num < lastparm; num++) { if(fractype == FORMULA || fractype == FFORMULA) if(paramnotused(num)) continue; choices[++k]=gene[num].name; uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 7; uvalues[k].uval.ch.llen = 7; uvalues[k].uval.ch.list = evolvmodes; uvalues[k].uval.ch.val = gene[num].mutate; } LOADCHOICES(""); uvalues[k].type = '*'; LOADCHOICES("Press F2 to set all to off"); uvalues[k].type ='*'; LOADCHOICES("Press F3 to set all on"); uvalues[k].type = '*'; LOADCHOICES("Press F4 to randomize all"); uvalues[k].type = '*'; LOADCHOICES("Press F6 for second page"); /* F5 gets eaten */ uvalues[k].type = '*'; i = fullscreen_prompt(hdg,k+1,choices,uvalues,92,NULL); switch(i) { case F2: /* set all off */ for (num = 0; num < MAXPARAMS; num++) gene[num].mutate = 0; goto choose_vars_restart; case F3: /* set all on..alternate x and y for field map */ for (num = 0; num < MAXPARAMS; num ++ ) gene[num].mutate = (char)((num % 2) + 1); goto choose_vars_restart; case F4: /* Randomize all */ for (num =0; num < MAXPARAMS; num ++ ) gene[num].mutate = (char)(rand() % 6); goto choose_vars_restart; case F6: /* go to second screen, put array away first */ MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); chngd = get_the_rest(); MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); goto choose_vars_restart; case -1: return(chngd); default: break; } /* read out values */ k = -1; for (num = firstparm; num < lastparm; num++) { if(fractype == FORMULA || fractype == FFORMULA) if(paramnotused(num)) continue; gene[num].mutate = (char)(uvalues[++k].uval.ch.val); } MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); return(1); /* if you were here, you want to regenerate */ } void set_mutation_level(int strength) { /* scan through the gene array turning on random variation for all parms that */ /* are suitable for this level of mutation */ int i; GENEBASE gene[NUMGENES]; /* get the gene array from far memory */ MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); for (i=0;i) */ k = -1; viewwindow = evolving = uvalues[++k].uval.ch.val; if (!evolving && i != F6) /* don't need any of the other parameters JCO 12JUL2002 */ return(1); /* the following code can set evolving even if it's off */ gridsz = uvalues[++k].uval.ival; tmp = sxdots / (MINPIXELS<<1); /* (sxdots / 20), max # of subimages @ 20 pixels per subimage */ /* MAXGRIDSZ == 1024 / 20 == 51 */ if (gridsz > MAXGRIDSZ) gridsz = MAXGRIDSZ; if (gridsz > tmp) gridsz = tmp; if (gridsz < 3) gridsz = 3; gridsz |= 1; /* make sure gridsz is odd */ if (explore_check()) { tmp = (PARMBOX * uvalues[++k].uval.ch.val); if (evolving) evolving += tmp; paramrangex = uvalues[++k].uval.dval; newopx = opx = uvalues[++k].uval.dval; paramrangey = uvalues[++k].uval.dval; newopy = opy = uvalues[++k].uval.dval; } fiddlefactor = uvalues[++k].uval.dval; fiddle_reduction = uvalues[++k].uval.dval; if (!(uvalues[++k].uval.ch.val)) evolving = evolving + NOGROUT; viewxdots = (sxdots / gridsz)-2; viewydots = (sydots / gridsz)-2; if (!viewwindow) viewxdots=viewydots=0; i = 0; if ( evolving != old_evolving || (gridsz != old_gridsz) ||(paramrangex!= old_paramrangex) || (opx != old_opx ) || (paramrangey != old_paramrangey) || (opy != old_opy) || (fiddlefactor != old_fiddlefactor) || (old_variations > 0) ) i = 1; if (evolving && !old_evolving) param_history(0); /* save old history */ if (!evolving && (evolving == old_evolving)) i = 0; if (j==F6) { old_variations = get_variations(); set_current_params(); if (old_variations > 0) { viewwindow = 1; evolving |= 1; /* leave other settings alone */ } fiddlefactor = 1; fiddle_reduction = 1.0; goto get_evol_restart; } return(i); } void SetupParamBox(void) { int vidsize; prmboxcount = 0; parmzoom=((double)gridsz-1.0)/2.0; /* need to allocate 2 int arrays for boxx and boxy plus 1 byte array for values */ vidsize = (xdots+ydots) * 4 * sizeof(int) ; vidsize = vidsize + xdots + ydots + 2 ; if (prmboxhandle == 0) prmboxhandle = MemoryAlloc((U16)(vidsize),1L,FARMEM); if (prmboxhandle == 0 ) { static FCODE msg[] = {"Sorry...can't allocate mem for parmbox"}; texttempmsg(msg); evolving=0; } prmboxcount=0; /* vidsize = (vidsize / gridsz)+3 ; */ /* allocate less mem for smaller box */ /* taken out above as *all* pixels get plotted in small boxes */ if (imgboxhandle == 0) imgboxhandle = MemoryAlloc((U16)(vidsize),1L,FARMEM); if (!imgboxhandle) { static FCODE msg[] = {"Sorry...can't allocate mem for imagebox"}; texttempmsg(msg); } } void ReleaseParamBox(void) { MemoryRelease(prmboxhandle); MemoryRelease(imgboxhandle); prmboxhandle = 0; imgboxhandle = 0; } void set_current_params(void) { paramrangex = curfractalspecific->xmax - curfractalspecific->xmin; opx = newopx = - (paramrangex / 2); paramrangey = curfractalspecific->ymax - curfractalspecific->ymin; opy = newopy = - (paramrangey / 2); return; } void fiddleparms(GENEBASE gene[], int ecount) { /* call with px,py ... parameter set co-ords*/ /* set random seed then call rnd enough times to get to px,py */ /* 5/2/96 adding in indirection */ /* 26/2/96 adding in multiple methods and field map */ /* 29/4/96 going for proper handling of the whole gene array */ /* bung in a pile of switches to allow for expansion to any future variable types */ /* 11/6/96 scrapped most of switches above and used function pointers instead */ /* 4/1/97 picking it up again after the last step broke it all horribly! */ int i; /* when writing routines to vary param types make sure that rand() gets called the same number of times whether gene[].mutate is set or not to allow user to change it between generations without screwing up the duplicability of the sequence and starting from the wrong point */ /* this function has got simpler and simpler throughout the construction of the evolver feature and now consists of just these few lines to loop through all the variables referenced in the gene array and call the functions required to vary them, aren't pointers marvellous! */ if ((px == gridsz / 2) && (py == gridsz / 2)) /* return if middle image */ return; set_random(ecount); /* generate the right number of pseudo randoms */ for (i=0;i 0) && (gene[i].mutate < 5)) nonrandom = TRUE; return(nonrandom); } void drawparmbox(int mode) { /* draws parameter zoom box in evolver mode */ /* clears boxes off screen if mode=1, otherwise, redraws boxes */ struct coords tl,tr,bl,br; int grout; if (!(evolving & PARMBOX)) return; /* don't draw if not asked to! */ grout = !((evolving & NOGROUT)/NOGROUT) ; imgboxcount = boxcount; if (boxcount) { /* stash normal zoombox pixels */ MoveToMemory((BYTE *)boxx,(U16)(boxcount*2),1L,0L,imgboxhandle); MoveToMemory((BYTE *)boxy,(U16)(boxcount*2),1L,1L,imgboxhandle); MoveToMemory((BYTE *)boxvalues,(U16)boxcount,1L,4L,imgboxhandle); clearbox(); /* to avoid probs when one box overlaps the other */ } if (prmboxcount!=0) { /* clear last parmbox */ boxcount=prmboxcount; MoveFromMemory((BYTE *)boxx,(U16)(boxcount*2),1L,0L,prmboxhandle); MoveFromMemory((BYTE *)boxy,(U16)(boxcount*2),1L,1L,prmboxhandle); MoveFromMemory((BYTE *)boxvalues,(U16)boxcount,1L,4L,prmboxhandle); clearbox(); } if (mode == 1) { boxcount = imgboxcount; prmboxcount = 0; return; } boxcount =0; /*draw larger box to show parm zooming range */ tl.x = bl.x = ((px -(int)parmzoom) * (int)(dxsize+1+grout))-sxoffs-1; tl.y = tr.y = ((py -(int)parmzoom) * (int)(dysize+1+grout))-syoffs-1; br.x = tr.x = ((px +1+(int)parmzoom) * (int)(dxsize+1+grout))-sxoffs; br.y = bl.y = ((py +1+(int)parmzoom) * (int)(dysize+1+grout))-syoffs; #ifndef XFRACT addbox(br);addbox(tr);addbox(bl);addbox(tl); drawlines(tl,tr,bl.x-tl.x,bl.y-tl.y); drawlines(tl,bl,tr.x-tl.x,tr.y-tl.y); #else boxx[0] = tl.x + sxoffs; boxy[0] = tl.y + syoffs; boxx[1] = tr.x + sxoffs; boxy[1] = tr.y + syoffs; boxx[2] = br.x + sxoffs; boxy[2] = br.y + syoffs; boxx[3] = bl.x + sxoffs; boxy[3] = bl.y + syoffs; boxcount = 8; #endif if(boxcount) { dispbox(); /* stash pixel values for later */ MoveToMemory((BYTE *)boxx,(U16)(boxcount*2),1L,0L,prmboxhandle); MoveToMemory((BYTE *)boxy,(U16)(boxcount*2),1L,1L,prmboxhandle); MoveToMemory((BYTE *)boxvalues,(U16)boxcount,1L,4L,prmboxhandle); } prmboxcount = boxcount; boxcount = imgboxcount; if(imgboxcount) { /* and move back old values so that everything can proceed as normal */ MoveFromMemory((BYTE *)boxx,(U16)(boxcount*2),1L,0L,imgboxhandle); MoveFromMemory((BYTE *)boxy,(U16)(boxcount*2),1L,1L,imgboxhandle); MoveFromMemory((BYTE *)boxvalues,(U16)boxcount,1L,4L,imgboxhandle); dispbox(); } return; } void set_evolve_ranges(void) { int lclpy = gridsz - py - 1; /* set up ranges and offsets for parameter explorer/evolver */ paramrangex=dpx*(parmzoom*2.0); paramrangey=dpy*(parmzoom*2.0); newopx=opx+(((double)px-parmzoom)*dpx); newopy=opy+(((double)lclpy-parmzoom)*dpy); newodpx=(char)(odpx+(px-gridsz/2)); newodpy=(char)(odpy+(lclpy-gridsz/2)); return; } void spiralmap(int count) { /* maps out a clockwise spiral for a prettier and possibly */ /* more intuitively useful order of drawing the sub images. */ /* All the malarky with count is to allow resuming */ int i,mid,offset; i = 0; mid = gridsz / 2; if (count == 0) { /* start in the middle */ px = py = mid; return; } for(offset = 1; offset <= mid; offset ++) { /* first do the top row */ py = (mid - offset); for(px = (mid - offset)+1; px mid - offset;px--) { i++; if (i == count) return; } /* then up the left to finish */ for (; py >= mid - offset; py-- ) { i++; if (i== count ) return; } } } int unspiralmap(void) { /* unmaps the clockwise spiral */ /* All this malarky is to allow selecting different subimages */ /* Returns the count from the center subimage to the current px & py */ int mid; static int oldgridsz = 0; mid = gridsz / 2; if ((px == mid && py == mid) || (oldgridsz != gridsz)) { int i, gridsqr; /* set up array and return */ gridsqr = gridsz * gridsz; ecountbox[px][py] = 0; /* we know the first one, do the rest */ for (i = 1; i < gridsqr; i++) { spiralmap(i); ecountbox[px][py] = i; } oldgridsz = gridsz; px = py = mid; return(0); } return(ecountbox[px][py]); } /* points to ponder..... watch out for near mem..... (TW) It's better now. try and keep gene array in overlay? (TW) No, but try dynamic alloc. how to preserve 'what to mutate ' choices through overlay swaps in prompts... (TW) Needs checking, seems OK. LOADCHOICES copies, so is safe. */ xfractint-20.4.10.orig/common/decoder.c0000644000000000000000000003631510150633601014551 0ustar /* DECODE.C - An LZW decoder for GIF * Copyright (C) 1987, by Steven A. Bennett * * Permission is given by the author to freely redistribute and include * this code in any program as long as this credit is given where due. * * In accordance with the above, I want to credit Steve Wilhite who wrote * the code which this is heavily inspired by... * * GIF and 'Graphics Interchange Format' are trademarks (tm) of * Compuserve, Incorporated, an H&R Block Company. * * Release Notes: This file contains a decoder routine for GIF images * which is similar, structurally, to the original routine by Steve Wilhite. * It is, however, somewhat noticably faster in most cases. * == This routine was modified for use in FRACTINT in two ways. == == 1) The original #includes were folded into the routine strictly to hold == down the number of files we were dealing with. == == 2) The 'stack', 'suffix', 'prefix', and 'decoderline' arrays were == changed from static and 'malloc()'ed to external only so that == the assembler program could use the same array space for several == independent chunks of code. Also, 'stack' was renamed to 'dstack' == for TASM compatibility. == == 3) The 'out_line()' external function has been changed to reference == '*outln()' for flexibility (in particular, 3D transformations) == == 4) A call to 'keypressed()' has been added after the 'outln()' calls == to check for the presenc of a key-press as a bail-out signal == == (Bert Tyler and Timothy Wegner) */ /* Rev 01/02/91 - Revised by Mike Gelvin * altered logic to allow newcode to input a line at a time * altered logic to allow decoder to place characters * directly into the output buffer if they fit */ /***** Application Includes *********************************************/ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" /***** Application Function Prototypes **********************************/ static short get_next_code(void); /* extern short out_line(pixels, linelen) * UBYTE pixels[]; * short linelen; * * - This function takes a full line of pixels (one byte per pixel) and * displays them (or does whatever your program wants with them...). It * should return zero, or negative if an error or some other event occurs * which would require aborting the decode process... Note that the length * passed will almost always be equal to the line length passed to the * decoder function, with the sole exception occurring when an ending code * occurs in an odd place in the GIF file... In any case, linelen will be * equal to the number of pixels passed... */ int (*outln) (BYTE *, int) = out_line; /***** Local Static Variables *******************************************/ /* Various error codes used by decoder * and my own routines... It's okay * for you to define whatever you want, * as long as it's negative... It will be * returned intact up the various subroutine * levels... */ #define OUT_OF_MEMORY -10 #define BAD_CODE_SIZE -20 #define READ_ERROR -1 #define WRITE_ERROR -2 #define OPEN_ERROR -3 #define CREATE_ERROR -4 #define MAX_CODES 4095 #define NOPE 0 #define YUP -1 static short curr_size; /* The current code size */ /* The following static variables are used * for seperating out codes */ static short navail_bytes; /* # bytes left in block */ static short nbits_left; /* # bits left in current byte */ static BYTE *byte_buff; /* Current block, reuse shared mem */ static BYTE *pbytes; /* Pointer to next byte in block */ static short code_mask[13] = { 0, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF }; /***** External Variables ***********************************************/ /* extern short bad_code_count; * * This value is the only other global required by the using program, and * is incremented each time an out of range code is read by the decoder. * When this value is non-zero after a decode, your GIF file is probably * corrupt in some way... * * whups, here are more globals, added by PB: * extern short skipxdots; 0 to get every dot, 1 for every 2nd, 2 every 3rd, ... * extern short skipydots; * * All external declarations now in PROTOTYPE.H */ /* I removed the LOCAL identifiers in the arrays below and replaced them with 'extern's so as to declare (and re-use) the space elsewhere. The arrays are actually declared in the assembler source. Bert Tyler */ #if 0 /* declarations moved to PROTOTYPE.H - these left for documentation */ BYTE dstack[MAX_CODES + 1]; /* Stack for storing pixels */ BYTE suffix[MAX_CODES + 1]; /* Suffix table */ unsigned short prefix[MAX_CODES + 1]; /* Prefix linked list */ BYTE decoderline[2]; /* decoded line goes here */ #endif /* avoid using fixed near arrays by enabling next */ #if 0 BYTE far dstack1[MAX_CODES + 1]; /* Stack for storing pixels */ #define dstack dstack1 #endif #if 0 /* remove this when suffix no longer used in diskvid.c */ BYTE far suffix1[MAX_CODES + 1]; /* Suffix table */ #define suffix suffix1 #endif #if 0 unsigned short far prefix1[MAX_CODES + 1]; /* Prefix linked list */ #define prefix prefix1 #endif /* for the time being, use a pointer to a buffer in the gifview stack */ extern BYTE *decoderline1; #define decoderline decoderline1 /* The reason we have these separated like this instead of using * a structure like the original Wilhite code did, is because this * stuff generally produces significantly faster code when compiled... * This code is full of similar speedups... (For a good book on writing * C for speed or for space optimization, see Efficient C by Tom Plum, * published by Plum-Hall Associates...) */ /***** Program **********************************************************/ /* short decoder(linewidth) * short linewidth; * Pixels per line of image * * * - This function decodes an LZW image, according to the method used * in the GIF spec. Every *linewidth* "characters" (ie. pixels) decoded * will generate a call to out_line(), which is a user specific function * to display a line of pixels. The function gets its codes from * get_next_code() which is responsible for reading blocks of data and * seperating them into the proper size codes. Finally, get_byte() is * the global routine to read the next byte from the GIF file. * * It is generally a good idea to have linewidth correspond to the actual * width of a line (as specified in the Image header) to make your own * code a bit simpler, but it isn't absolutely necessary. * * Returns: 0 if successful, else negative. (See ERRS.H) * */ /* moved sizeofstring here for possible re-use elsewhere */ short far sizeofstring[MAX_CODES + 1]; /* size of string list */ short decoder(short linewidth) { #ifdef XFRACT U16 prefix[MAX_CODES+1]; /* Prefix linked list */ #endif BYTE far *sp; short code; short old_code; short ret; short c; short size; short i; short j; short fastloop; short bufcnt; /* how many empty spaces left in buffer */ short xskip; short slot; /* Last read code */ short newcodes; /* First available code */ BYTE *bufptr; short yskip; short top_slot; /* Highest code for current size */ short clear; /* Value for a clear code */ short ending; /* Value for a ending code */ BYTE out_value; /* Initialize for decoding a new image... */ if ((size = (short) get_byte()) < 0) return (size); if (size < 2 || 9 < size) return (BAD_CODE_SIZE); curr_size = (short) (size + 1); top_slot = (short) (1 << curr_size); clear = (short) (1 << size); ending = (short) (clear + 1); slot = newcodes = (short) (ending + 1); navail_bytes = nbits_left = sizeofstring[slot] = xskip = yskip = old_code = 0; out_value = 0; for (i = 0; i < slot; i++) { sizeofstring[i] = 0; } /* Initialize in case they forgot to put in a clear code. (This shouldn't * happen, but we'll try and decode it anyway...) */ /* Set up the stack pointer and decode buffer pointer */ sp = dstack; bufptr = decoderline; bufcnt = linewidth; /* This is the main loop. For each code we get we pass through the linked * list of prefix codes, pushing the corresponding "character" for each * code onto the stack. When the list reaches a single "character" we * push that on the stack too, and then start unstacking each character * for output in the correct order. Special handling is included for the * clear code, and the whole thing ends when we get an ending code. */ while ((c = get_next_code()) != ending) { /* If we had a file error, return without completing the decode */ if (c < 0) return (0); /* If the code is a clear code, reinitialize all necessary items. */ if (c == clear) { curr_size = (short) (size + 1); slot = newcodes; sizeofstring[slot] = 0; top_slot = (short) (1 << curr_size); /* Continue reading codes until we get a non-clear code (Another * unlikely, but possible case...) */ while ((c = get_next_code()) == clear) ; /* If we get an ending code immediately after a clear code (Yet * another unlikely case), then break out of the loop. */ if (c == ending) break; /* Finally, if the code is beyond the range of already set codes, * (This one had better NOT happen... I have no idea what will * result from this, but I doubt it will look good...) then set it * to color zero. */ if (c >= slot) c = 0; out_value = (BYTE) (old_code = c); /* And let us not forget to put the char into the buffer... */ *sp++ = (BYTE) c; } else { /* In this case, it's not a clear code or an ending code, so it must * be a code code... So we can now decode the code into a stack of * character codes. (Clear as mud, right?) */ code = c; /* Here we go again with one of those off chances... If, on the off * chance, the code we got is beyond the range of those already set * up (Another thing which had better NOT happen...) we trick the * decoder into thinking it actually got the next slot avail. */ if (code >= slot) { if (code > slot) { ++bad_code_count; c = slot; } code = old_code; *sp++ = out_value; } /* Here we scan back along the linked list of prefixes. If they can * fit into the output buffer then transfer them direct. ELSE push * them into the stack until we are down to enough characters that * they do fit. Output the line then fall through to unstack the * ones that would not fit. */ fastloop = NOPE; while (code >= newcodes) { j = i = sizeofstring[code]; if (i > 0 && bufcnt - i > 0 && skipxdots == 0) { fastloop = YUP; do { *(bufptr + j) = suffix[code]; code = prefix[code]; } while (--j > 0); *bufptr = (BYTE) code; bufptr += ++i; bufcnt -= i; if (bufcnt == 0) /* finished an input row? */ { if (--yskip < 0) { if ((ret = (short) ((*outln) (decoderline, bufptr - decoderline))) < 0) return (ret); yskip = skipydots; } if (keypressed()) return (-1); bufptr = decoderline; bufcnt = linewidth; xskip = 0; } } else { *sp++ = suffix[code]; code = prefix[code]; } } /* Push the last character on the stack, and set up the new prefix * and suffix, and if the required slot number is greater than that * allowed by the current bit size, increase the bit size. (NOTE - * If we are all full, we *don't* save the new suffix and prefix... * I'm not certain if this is correct... it might be more proper to * overwrite the last code... */ if (fastloop == NOPE) *sp++ = (BYTE) code; if (slot < top_slot) { sizeofstring[slot] = (short) (sizeofstring[old_code] + 1); suffix[slot] = out_value = (BYTE) code; prefix[slot++] = old_code; old_code = c; } if (slot >= top_slot) if (curr_size < 12) { top_slot <<= 1; ++curr_size; } } while (sp > dstack) { --sp; if (--xskip < 0) { xskip = skipxdots; *bufptr++ = *sp; } if (--bufcnt == 0) /* finished an input row? */ { if (--yskip < 0) { if ((ret = (short) ((*outln) (decoderline, bufptr - decoderline))) < 0) return (ret); yskip = skipydots; } if (keypressed()) return (-1); bufptr = decoderline; bufcnt = linewidth; xskip = 0; } } } /* PB note that if last line is incomplete, we're not going to try to emit * it; original code did, but did so via out_line and therefore couldn't * have worked well in all cases... */ return (0); } /***** Program **********************************************************/ /* get_next_code() * - gets the next code from the GIF file. Returns the code, or else * a negative number in case of file errors... */ static short get_next_code() { static BYTE b1; /* Current byte */ static unsigned short ret_code; if (nbits_left == 0) { if (navail_bytes <= 0) { /* Out of bytes in current block, so read next block */ pbytes = byte_buff; if ((navail_bytes = (short) get_byte()) < 0) return (navail_bytes); else if (navail_bytes) get_bytes(byte_buff, navail_bytes); } b1 = *pbytes++; nbits_left = 8; --navail_bytes; } ret_code = (short) (b1 >> (8 - nbits_left)); while (curr_size > nbits_left) { if (navail_bytes <= 0) { /* Out of bytes in current block, so read next block */ pbytes = byte_buff; if ((navail_bytes = (short) get_byte()) < 0) return (navail_bytes); else if (navail_bytes) get_bytes(byte_buff, navail_bytes); } b1 = *pbytes++; ret_code |= b1 << nbits_left; nbits_left += 8; --navail_bytes; } nbits_left -= curr_size; return ((short) (ret_code & code_mask[curr_size])); } /* called in parent reoutine to set byte_buff */ void set_byte_buff(BYTE * ptr) { byte_buff = ptr; } xfractint-20.4.10.orig/common/parser.c0000644000000000000000000044307510627420161014451 0ustar /* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353] All rights reserved. Code may be used in any program provided the author is credited either during program execution or in the documentation. Source code may be distributed only in combination with public domain or shareware source code. Source code may be modified provided the copyright notice and this message is left unchanged and all modifications are clearly documented. I would appreciate a copy of any work which incorporates this code, however this is optional. Mark C. Peterson 405-C Queen St. Suite #181 Southington, CT 06489 (203) 276-9721 */ /* Chuck Ebbert (CompuServe [76306,1226] ) changed code marked 'CAE fp' */ /* for fast 387 floating-point math. See PARSERA.ASM and PARSERFP.C */ /* (13 Dec 1992.) */ /* */ /* Modified 12 July 1993 by CAE to fix crash when formula not found. */ #include #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #ifdef WATCH_MP double x1, y1, x2, y2; #endif enum MATH_TYPE MathType = D_MATH; /* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */ #define MAX_OPS 250 #define MAX_ARGS 100 #define MAX_BOXX 8192 /* max size of boxx array */ unsigned Max_Ops = MAX_OPS; unsigned Max_Args = MAX_ARGS; unsigned long number_of_ops, number_of_loads, number_of_stores, number_of_jumps; struct PEND_OP { void (far *f)(void); int p; }; #ifndef XFRACT /* reuse an array in the decoder */ JUMP_CONTROL_ST far *jump_control = (JUMP_CONTROL_ST far *) sizeofstring; #else JUMP_CONTROL_ST jump_control[MAX_JUMPS]; #endif int jump_index, InitJumpIndex; static int frm_prescan (FILE * open_file); #define CASE_TERMINATOR case',':\ case '\n':\ case '(':\ case ')':\ case '!':\ case '=':\ case '<':\ case '>':\ case '|':\ case '&':\ case '}':\ case ':':\ case '+':\ case '-':\ case '*':\ case '/':\ case '^' #define CASE_ALPHA case 'a':\ case 'b':\ case 'c':\ case 'd':\ case 'e':\ case 'f':\ case 'g':\ case 'h':\ case 'i':\ case 'j':\ case 'k':\ case 'l':\ case 'm':\ case 'n':\ case 'o':\ case 'p':\ case 'q':\ case 'r':\ case 's':\ case 't':\ case 'u':\ case 'v':\ case 'w':\ case 'x':\ case 'y':\ case 'z' #define CASE_NUM case '0':\ case '1':\ case '2':\ case '3':\ case '4':\ case '5':\ case '6':\ case '7':\ case '8':\ case '9' /* token_type definitions */ #define NOT_A_TOKEN 0 #define PARENS 1 #define PARAM_VARIABLE 2 #define USER_NAMED_VARIABLE 3 #define PREDEFINED_VARIABLE 4 #define REAL_CONSTANT 5 #define COMPLEX_CONSTANT 6 #define FUNCTION 7 #define PARAM_FUNCTION 8 #define FLOW_CONTROL 9 #define OPERATOR 10 #define END_OF_FORMULA 11 /* token IDs */ #define END_OF_FILE 1 #define ILLEGAL_CHARACTER 2 #define ILLEGAL_VARIABLE_NAME 3 #define TOKEN_TOO_LONG 4 #define FUNC_USED_AS_VAR 5 #define JUMP_MISSING_BOOLEAN 6 #define JUMP_WITH_ILLEGAL_CHAR 7 #define UNDEFINED_FUNCTION 8 #define ILLEGAL_OPERATOR 9 #define ILL_FORMED_CONSTANT 10 #define OPEN_PARENS 1 #define CLOSE_PARENS -1 struct token_st { char token_str[80]; int token_type; int token_id; _CMPLX token_const; }; /* CAE fp added MAX_STORES and LOADS */ /* MAX_STORES must be even to make Unix alignment work */ /* TW made dependent on Max_Ops */ #define MAX_STORES ((Max_Ops/4)*2) /* at most only half the ops can be stores */ #define MAX_LOADS ((unsigned)(Max_Ops*.8)) /* and 80% can be loads */ /* PB 901103 made some of the following static for safety */ static struct PEND_OP far *o; #if 0 static void ops_allocate(void); static void vars_allocate(void); #endif struct var_list_st { char name[34]; struct var_list_st far * next_item; } far * var_list; struct const_list_st { _CMPLX complex_const; struct const_list_st far * next_item; } far * complx_list, far * real_list; static void parser_allocate(void); union Arg *Arg1, *Arg2; /* PB 910417 removed unused "a" array */ /* CAE fp made some of the following non-static for PARSERA.ASM */ /* Some of these variables should be renamed for safety */ union Arg s[20], far * far *Store, far * far *Load; /* static CAE fp */ int StoPtr, LodPtr, OpPtr; /* static CAE fp */ int var_count; int complx_count; int real_count; void (far * far *f)(void) = (void(far * far *)(void))0; /* static CAE fp */ short int ismand = 1; unsigned int posp, vsp, LastOp; /* CAE fp made non-static */ static unsigned int n, NextOp, InitN; static int paren, ExpectingArg; struct ConstArg far *v = (struct ConstArg far *)0; /* was static CAE fp */ int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp; /* was static CAE fp */ static int Delta16; double fgLimit; /* TIW 05-04-91 */ static double fg; static int ShiftBack; /* TIW 06-18-90 */ static int SetRandom; /* MCP 11-21-91 */ static int Randomized; static unsigned long RandNum; short uses_p1, uses_p2, uses_p3, uses_p4, uses_p5, uses_jump; short uses_ismand; unsigned int chars_in_formula; #ifndef XFRACT #define ChkLongDenom(denom)\ if ((denom == 0 || overflow) && save_release > 1920) {\ overflow = 1;\ return;\ }\ else if (denom == 0)\ return #endif #define ChkFloatDenom(denom)\ if (fabs(denom) <= DBL_MIN) {\ if (save_release > 1920) overflow = 1;\ return;\ } #define LastSqr v[4].a #if (_MSC_VER >= 700) #pragma code_seg ("parser1_text") /* place following in an overlay */ #endif /* ParseErrs() defines; all calls to ParseErrs(), or any variable which will be used as the argument in a call to ParseErrs(), should use one of these defines. */ #define PE_NO_ERRORS_FOUND -1 #define PE_SHOULD_BE_ARGUMENT 0 #define PE_SHOULD_BE_OPERATOR 1 #define PE_NEED_A_MATCHING_OPEN_PARENS 2 #define PE_NEED_MORE_CLOSE_PARENS 3 #define PE_UNDEFINED_OPERATOR 4 #define PE_UNDEFINED_FUNCTION 5 #define PE_TABLE_OVERFLOW 6 #define PE_NO_MATCH_RIGHT_PAREN 7 #define PE_NO_LEFT_BRACKET_FIRST_LINE 8 #define PE_UNEXPECTED_EOF 9 #define PE_INVALID_SYM_USING_NOSYM 10 #define PE_FORMULA_TOO_LARGE 11 #define PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA 12 #define PE_COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED 13 #define PE_JUMP_NOT_FIRST 14 #define PE_NO_CHAR_AFTER_THIS_JUMP 15 #define PE_JUMP_NEEDS_BOOLEAN 16 #define PE_ENDIF_REQUIRED_AFTER_ELSE 17 #define PE_ENDIF_WITH_NO_IF 18 #define PE_MISPLACED_ELSE_OR_ELSEIF 19 #define PE_UNMATCHED_IF_IN_INIT_SECTION 20 #define PE_IF_WITH_NO_ENDIF 21 #define PE_ERROR_IN_PARSING_JUMP_STATEMENTS 22 #define PE_TOO_MANY_JUMPS 23 #define PE_FORMULA_NAME_TOO_LARGE 24 #define PE_ILLEGAL_ASSIGNMENT 25 #define PE_ILLEGAL_VAR_NAME 26 #define PE_INVALID_CONST 27 #define PE_ILLEGAL_CHAR 28 #define PE_NESTING_TO_DEEP 29 #define PE_UNMATCHED_MODULUS 30 #define PE_FUNC_USED_AS_VAR 31 #define PE_NO_NEG_AFTER_EXPONENT 32 #define PE_TOKEN_TOO_LONG 33 #define PE_SECOND_COLON 34 #define PE_INVALID_CALL_TO_PARSEERRS 35 static char far *ParseErrs(int which) { int lasterr; static FCODE e0[] = {"Should be an Argument"}; static FCODE e1[] = {"Should be an Operator"}; static FCODE e2[] = {"')' needs a matching '('"}; static FCODE e3[] = {"Need more ')'"}; static FCODE e4[] = {"Undefined Operator"}; static FCODE e5[] = {"Undefined Function"}; static FCODE e6[] = {"Table overflow"}; static FCODE e7[] = {"Didn't find matching ')' in symmetry declaration"}; static FCODE e8[] = {"No '{' found on first line"}; static FCODE e9[] = {"Unexpected EOF!"}; static FCODE e10[] = {"Symmetry below is invalid, will use NOSYM"}; static FCODE e11[] = {"Formula is too large"}; static FCODE e12[] = {"Insufficient memory to run fractal type 'formula'"}; static FCODE e13[] = {"Could not open file where formula located"}; static FCODE e14[] = {"No characters may precede jump instruction"}; static FCODE e15[] = {"No characters may follow this jump instruction"}; static FCODE e16[] = {"Jump instruction missing required (boolean argument)"}; static FCODE e17[] = {"Next jump after \"else\" must be \"endif\""}; static FCODE e18[] = {"\"endif\" has no matching \"if\""}; static FCODE e19[] = {"Misplaced \"else\" or \"elseif()\""}; static FCODE e20[] = {"\"if()\" in initialization has no matching \"endif\""}; static FCODE e21[] = {"\"if()\" has no matching \"endif\""}; static FCODE e22[] = {"Error in parsing jump statements"}; static FCODE e23[] = {"Formula has too many jump commands"}; static FCODE e24[] = {"Formula name has too many characters"}; static FCODE e25[] = {"Only variables are allowed to left of assignment"}; static FCODE e26[] = {"Illegal variable name"}; static FCODE e27[] = {"Invalid constant expression"}; static FCODE e28[] = {"This character not supported by parser"}; static FCODE e29[] = {"Nesting of parentheses exceeds maximum depth"}; static FCODE e30[] = {"Unmatched modulus operator \"|\" in this expression"}; /*last one */ static FCODE e31[] = {"Can't use function name as variable"}; static FCODE e32[] = {"Negative exponent must be enclosed in parens"}; static FCODE e33[] = {"Variable or constant exceeds 32 character limit"}; static FCODE e34[] = {"Only one \":\" permitted in a formula"}; static FCODE e35[] = {"Invalid ParseErrs code"}; static PFCODE ErrStrings[] = { e0,e1,e2,e3,e4,e5, e6,e7,e8,e9,e10, e11,e12,e13,e14,e15, e16,e17,e18,e19,e20, e21,e22,e23,e24,e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35 }; lasterr = sizeof(ErrStrings)/sizeof(ErrStrings[0]) - 1; if(which > lasterr) which = lasterr; return((char far *)ErrStrings[which]); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif /* use the following when only float functions are implemented to get MP math and Integer math */ #ifndef XFRACT #define FUNCT #ifdef FUNCT /* use function form save space - isn't really slower */ #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif static void mStkFunct(void (*fct)(void)) /* call lStk via dStk */ { Arg1->d = MPC2cmplx(Arg1->m); (*fct)(); Arg1->m = cmplx2MPC(Arg1->d); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif static void lStkFunct(void (*fct)(void)) /* call lStk via dStk */ { double y; /* intermediate variable needed for safety because of different size of double and long in Arg union */ y = (double)Arg1->l.y / fg; Arg1->d.x = (double)Arg1->l.x / fg; Arg1->d.y = y; (*fct)(); if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) { Arg1->l.x = (long)(Arg1->d.x * fg); Arg1->l.y = (long)(Arg1->d.y * fg); } else overflow = 1; } #else /* use Macro form for (?) greater speed */ /* call lStk via dStk */ #define mStkFunct(fct) \ Arg1->d = MPC2cmplx(Arg1->m);\ (*fct)();\ Arg1->m = cmplx2MPC(Arg1->d); /* call lStk via dStk */ #define lStkFunct(fct) {\ double y;\ y = (double)Arg1->l.y / fg;\ Arg1->d.x = (double)Arg1->l.x / fg;\ Arg1->d.y = y;\ (*fct)();\ if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) {\ Arg1->l.x = (long)(Arg1->d.x * fg);\ Arg1->l.y = (long)(Arg1->d.y * fg);\ }\ else\ overflow = 1;\ } #endif #endif /* Random number code, MCP 11-21-91 */ unsigned long NewRandNum(void) { return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum); } void lRandom(void) { v[7].a.l.x = NewRandNum() >> (32 - bitshift); v[7].a.l.y = NewRandNum() >> (32 - bitshift); } void dRandom(void) { long x, y; /* Use the same algorithm as for fixed math so that they will generate the same fractals when the srand() function is used. */ x = NewRandNum() >> (32 - bitshift); y = NewRandNum() >> (32 - bitshift); v[7].a.d.x = ((double)x / (1L << bitshift)); v[7].a.d.y = ((double)y / (1L << bitshift)); } #ifndef XFRACT void mRandom(void) { long x, y; /* Use the same algorithm as for fixed math so that they will generate the same fractals when the srand() function is used. */ x = NewRandNum() >> (32 - bitshift); y = NewRandNum() >> (32 - bitshift); v[7].a.m.x = *fg2MP(x, bitshift); v[7].a.m.y = *fg2MP(y, bitshift); } #endif void SetRandFnct(void) { unsigned Seed; if(!SetRandom) RandNum = Arg1->l.x ^ Arg1->l.y; Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16); srand(Seed); SetRandom = 1; /* Clear out the seed */ NewRandNum(); NewRandNum(); NewRandNum(); } void RandomSeed(void) { time_t ltime; /* Use the current time to randomize the random number sequence. */ time(<ime); srand((unsigned int)ltime); NewRandNum(); NewRandNum(); NewRandNum(); Randomized = 1; } #ifndef XFRACT void lStkSRand(void) { SetRandFnct(); lRandom(); Arg1->l = v[7].a.l; } #endif #ifndef XFRACT void mStkSRand(void) { Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp; Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp; SetRandFnct(); mRandom(); Arg1->m = v[7].a.m; } #endif void dStkSRand(void) { Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift)); Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift)); SetRandFnct(); dRandom(); Arg1->d = v[7].a.d; } void (*StkSRand)(void) = dStkSRand; void dStkLodDup() { Arg1+=2; Arg2+=2; *Arg2 = *Arg1 = *Load[LodPtr]; LodPtr+=2; } void dStkLodSqr() { Arg1++; Arg2++; Arg1->d.y = Load[LodPtr]->d.x * Load[LodPtr]->d.y * 2.0; Arg1->d.x = (Load[LodPtr]->d.x * Load[LodPtr]->d.x) - (Load[LodPtr]->d.y * Load[LodPtr]->d.y); LodPtr++; } void dStkLodSqr2() { Arg1++; Arg2++; LastSqr.d.x = Load[LodPtr]->d.x * Load[LodPtr]->d.x; LastSqr.d.y = Load[LodPtr]->d.y * Load[LodPtr]->d.y; Arg1->d.y = Load[LodPtr]->d.x * Load[LodPtr]->d.y * 2.0; Arg1->d.x = LastSqr.d.x - LastSqr.d.y; LastSqr.d.x += LastSqr.d.y; LastSqr.d.y = 0; LodPtr++; } void dStkStoDup(){} void dStkStoSqr(){} void dStkStoSqr0(){} void dStkLodDbl() { Arg1++; Arg2++; Arg1->d.x = Load[LodPtr]->d.x * 2.0; Arg1->d.y = Load[LodPtr]->d.y * 2.0; LodPtr++; } void dStkStoDbl(){} void dStkReal2(){} void dStkSqr0() { LastSqr.d.y = Arg1->d.y * Arg1->d.y; /* use LastSqr as temp storage */ Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0; Arg1->d.x = Arg1->d.x * Arg1->d.x - LastSqr.d.y; } void dStkSqr3() { Arg1->d.x = Arg1->d.x * Arg1->d.x; } void dStkAbs(void) { Arg1->d.x = fabs(Arg1->d.x); Arg1->d.y = fabs(Arg1->d.y); } #ifndef XFRACT void mStkAbs(void) { if(Arg1->m.x.Exp < 0) Arg1->m.x.Exp = -Arg1->m.x.Exp; if(Arg1->m.y.Exp < 0) Arg1->m.y.Exp = -Arg1->m.y.Exp; } void lStkAbs(void) { Arg1->l.x = labs(Arg1->l.x); Arg1->l.y = labs(Arg1->l.y); } #endif void (*StkAbs)(void) = dStkAbs; void dStkSqr(void) { LastSqr.d.x = Arg1->d.x * Arg1->d.x; LastSqr.d.y = Arg1->d.y * Arg1->d.y; Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0; Arg1->d.x = LastSqr.d.x - LastSqr.d.y; LastSqr.d.x += LastSqr.d.y; LastSqr.d.y = 0; } #ifndef XFRACT void mStkSqr(void) { LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x); LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y); Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y); Arg1->m.y.Exp++; Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y); LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y); LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0); } void lStkSqr(void) { LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift); LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift); Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1; Arg1->l.x = LastSqr.l.x - LastSqr.l.y; LastSqr.l.x += LastSqr.l.y; LastSqr.l.y = 0L; } #endif void (*StkSqr)(void) = dStkSqr; void dStkAdd(void) { Arg2->d.x += Arg1->d.x; Arg2->d.y += Arg1->d.y; Arg1--; Arg2--; } #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif void mStkAdd(void) { Arg2->m = MPCadd(Arg2->m, Arg1->m); Arg1--; Arg2--; } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif void lStkAdd(void) { Arg2->l.x += Arg1->l.x; Arg2->l.y += Arg1->l.y; Arg1--; Arg2--; } #endif void (*StkAdd)(void) = dStkAdd; void dStkSub(void) { Arg2->d.x -= Arg1->d.x; Arg2->d.y -= Arg1->d.y; Arg1--; Arg2--; } #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif void mStkSub(void) { Arg2->m = MPCsub(Arg2->m, Arg1->m); Arg1--; Arg2--; } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif void lStkSub(void) { Arg2->l.x -= Arg1->l.x; Arg2->l.y -= Arg1->l.y; Arg1--; Arg2--; } #endif void (*StkSub)(void) = dStkSub; void dStkConj(void) { Arg1->d.y = -Arg1->d.y; } #ifndef XFRACT void mStkConj(void) { Arg1->m.y.Exp ^= 0x8000; } void lStkConj(void) { Arg1->l.y = -Arg1->l.y; } #endif void (*StkConj)(void) = dStkConj; void dStkFloor(void) { Arg1->d.x = floor(Arg1->d.x); Arg1->d.y = floor(Arg1->d.y); } #ifndef XFRACT void mStkFloor(void) { mStkFunct(dStkFloor); /* call lStk via dStk */ } void lStkFloor(void) { /* * Kill fractional part. This operation truncates negative numbers * toward negative infinity as desired. */ Arg1->l.x = (Arg1->l.x) >> bitshift; Arg1->l.y = (Arg1->l.y) >> bitshift; Arg1->l.x = (Arg1->l.x) << bitshift; Arg1->l.y = (Arg1->l.y) << bitshift; } #endif void (*StkFloor)(void) = dStkFloor; void dStkCeil(void) { Arg1->d.x = ceil(Arg1->d.x); Arg1->d.y = ceil(Arg1->d.y); } #ifndef XFRACT void mStkCeil(void) { mStkFunct(dStkCeil); /* call lStk via dStk */ } void lStkCeil(void) { /* the shift operation does the "floor" operation, so we negate everything before the operation */ Arg1->l.x = (-Arg1->l.x) >> bitshift; Arg1->l.y = (-Arg1->l.y) >> bitshift; Arg1->l.x = -((Arg1->l.x) << bitshift); Arg1->l.y = -((Arg1->l.y) << bitshift); } #endif void (*StkCeil)(void) = dStkCeil; void dStkTrunc(void) { Arg1->d.x = (int)(Arg1->d.x); Arg1->d.y = (int)(Arg1->d.y); } #ifndef XFRACT void mStkTrunc(void) { mStkFunct(dStkTrunc); /* call lStk via dStk */ } void lStkTrunc(void) { /* shifting and shifting back truncates positive numbers, so we make the numbers positive */ int signx, signy; signx = sign(Arg1->l.x); signy = sign(Arg1->l.y); Arg1->l.x = labs(Arg1->l.x); Arg1->l.y = labs(Arg1->l.y); Arg1->l.x = (Arg1->l.x) >> bitshift; Arg1->l.y = (Arg1->l.y) >> bitshift; Arg1->l.x = (Arg1->l.x) << bitshift; Arg1->l.y = (Arg1->l.y) << bitshift; Arg1->l.x = signx*Arg1->l.x; Arg1->l.y = signy*Arg1->l.y; } #endif void (*StkTrunc)(void) = dStkTrunc; void dStkRound(void) { Arg1->d.x = floor(Arg1->d.x+.5); Arg1->d.y = floor(Arg1->d.y+.5); } #ifndef XFRACT void mStkRound(void) { mStkFunct(dStkRound); /* call lStk via dStk */ } void lStkRound(void) { /* Add .5 then truncate */ Arg1->l.x += (1L<l.y += (1L<d.y = Arg1->d.x = 0.0; } #ifndef XFRACT void mStkZero(void) { Arg1->m.x.Mant = Arg1->m.x.Exp = 0; Arg1->m.y.Mant = Arg1->m.y.Exp = 0; } void lStkZero(void) { Arg1->l.y = Arg1->l.x = 0; } #endif void (*StkZero)(void) = dStkZero; void dStkOne(void) { Arg1->d.x = 1.0; Arg1->d.y = 0.0; } #ifndef XFRACT void mStkOne(void) { Arg1->m = MPCone; } void lStkOne(void) { Arg1->l.x = (long) fg; Arg1->l.y = 0L; } #endif void (*StkOne)(void) = dStkOne; void dStkReal(void) { Arg1->d.y = 0.0; } #ifndef XFRACT void mStkReal(void) { Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0); } void lStkReal(void) { Arg1->l.y = 0l; } #endif void (*StkReal)(void) = dStkReal; void dStkImag(void) { Arg1->d.x = Arg1->d.y; Arg1->d.y = 0.0; } #ifndef XFRACT void mStkImag(void) { Arg1->m.x = Arg1->m.y; Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0); } void lStkImag(void) { Arg1->l.x = Arg1->l.y; Arg1->l.y = 0l; } #endif void (*StkImag)(void) = dStkImag; void dStkNeg(void) { Arg1->d.x = -Arg1->d.x; Arg1->d.y = -Arg1->d.y; } #ifndef XFRACT void mStkNeg(void) { Arg1->m.x.Exp ^= 0x8000; Arg1->m.y.Exp ^= 0x8000; } void lStkNeg(void) { Arg1->l.x = -Arg1->l.x; Arg1->l.y = -Arg1->l.y; } #endif void (*StkNeg)(void) = dStkNeg; void dStkMul(void) { FPUcplxmul(&Arg2->d, &Arg1->d, &Arg2->d); Arg1--; Arg2--; } #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif void mStkMul(void) { Arg2->m = MPCmul(Arg2->m, Arg1->m); Arg1--; Arg2--; } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif void lStkMul(void) { long x, y; x = multiply(Arg2->l.x, Arg1->l.x, bitshift) - multiply(Arg2->l.y, Arg1->l.y, bitshift); y = multiply(Arg2->l.y, Arg1->l.x, bitshift) + multiply(Arg2->l.x, Arg1->l.y, bitshift); Arg2->l.x = x; Arg2->l.y = y; Arg1--; Arg2--; } #endif void (*StkMul)(void) = dStkMul; void dStkDiv(void) { FPUcplxdiv(&Arg2->d, &Arg1->d, &Arg2->d); Arg1--; Arg2--; } #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif void mStkDiv(void) { Arg2->m = MPCdiv(Arg2->m, Arg1->m); Arg1--; Arg2--; } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif void lStkDiv(void) { long x, y, mod, x2, y2; mod = multiply(Arg1->l.x, Arg1->l.x, bitshift) + multiply(Arg1->l.y, Arg1->l.y, bitshift); x = divide(Arg1->l.x, mod, bitshift); y = -divide(Arg1->l.y, mod, bitshift); /* pb 900617 changed next 4 lines to use x2,y2 instead of x,y */ x2 = multiply(Arg2->l.x, x, bitshift) - multiply(Arg2->l.y, y, bitshift); y2 = multiply(Arg2->l.y, x, bitshift) + multiply(Arg2->l.x, y, bitshift); Arg2->l.x = x2; Arg2->l.y = y2; Arg1--; Arg2--; } #endif void (*StkDiv)(void) = dStkDiv; void dStkMod(void) { Arg1->d.x = (Arg1->d.x * Arg1->d.x) + (Arg1->d.y * Arg1->d.y); Arg1->d.y = 0.0; } #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif void mStkMod(void) { Arg1->m.x = MPCmod(Arg1->m); Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif void lStkMod(void) { /* Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) + */ /* multiply(Arg2->l.y, Arg1->l.y, bitshift); */ /*** I don't understand how this ever worked correctly! JCO 12/31/94 ***/ Arg1->l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift) + multiply(Arg1->l.y, Arg1->l.y, bitshift); if(Arg1->l.x < 0) overflow = 1; Arg1->l.y = 0L; } void lStkModOld(void) { Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) + multiply(Arg2->l.y, Arg1->l.y, bitshift); if(Arg1->l.x < 0) overflow = 1; Arg1->l.y = 0L; } #endif void (*StkMod)(void) = dStkMod; void StkSto(void) { *Store[StoPtr++] = *Arg1; } void (*PtrStkSto)(void) = StkSto; void StkLod(void) { Arg1++; Arg2++; *Arg1 = *Load[LodPtr++]; } void (*PtrStkLod)(void) = StkLod; void StkClr(void) { s[0] = *Arg1; Arg1 = &s[0]; Arg2 = Arg1; Arg2--; } void (*PtrStkClr)(void) = StkClr; /* MCP 4-9-91, Added Flip() */ void dStkFlip(void) { double t; t = Arg1->d.x; Arg1->d.x = Arg1->d.y; Arg1->d.y = t; } #ifndef XFRACT void mStkFlip(void) { struct MP t; t = Arg1->m.x; Arg1->m.x = Arg1->m.y; Arg1->m.y = t; } void lStkFlip(void) { long t; t = Arg1->l.x; Arg1->l.x = Arg1->l.y; Arg1->l.y = t; } #endif void (*StkFlip)(void) = dStkFlip; void dStkSin(void) { double sinx, cosx, sinhy, coshy; FPUsincos(&Arg1->d.x, &sinx, &cosx); FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); Arg1->d.x = sinx*coshy; Arg1->d.y = cosx*sinhy; } #ifndef XFRACT void mStkSin(void) { mStkFunct(dStkSin); /* call lStk via dStk */ } void lStkSin(void) { long x, y, sinx, cosx, sinhy, coshy; x = Arg1->l.x >> Delta16; y = Arg1->l.y >> Delta16; SinCos086(x, &sinx, &cosx); SinhCosh086(y, &sinhy, &coshy); Arg1->l.x = multiply(sinx, coshy, ShiftBack); /* TIW 06-18-90 */ Arg1->l.y = multiply(cosx, sinhy, ShiftBack); /* TIW 06-18-90 */ } #endif void (*StkSin)(void) = dStkSin; /* The following functions are supported by both the parser and for fn variable replacement. TIW 04-22-91 */ void dStkTan(void) { double sinx, cosx, sinhy, coshy, denom; Arg1->d.x *= 2; Arg1->d.y *= 2; FPUsincos(&Arg1->d.x, &sinx, &cosx); FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); denom = cosx + coshy; ChkFloatDenom(denom); Arg1->d.x = sinx/denom; Arg1->d.y = sinhy/denom; } #ifndef XFRACT void mStkTan(void) { mStkFunct(dStkTan); /* call lStk via dStk */ } void lStkTan(void) { long x, y, sinx, cosx, sinhy, coshy, denom; x = Arg1->l.x >> Delta16; x = x << 1; y = Arg1->l.y >> Delta16; y = y << 1; SinCos086(x, &sinx, &cosx); SinhCosh086(y, &sinhy, &coshy); denom = cosx + coshy; ChkLongDenom(denom); Arg1->l.x = divide(sinx,denom,bitshift); Arg1->l.y = divide(sinhy,denom,bitshift); } #endif void (*StkTan)(void) = dStkTan; void dStkTanh(void) { double siny, cosy, sinhx, coshx, denom; Arg1->d.x *= 2; Arg1->d.y *= 2; FPUsincos(&Arg1->d.y, &siny, &cosy); FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); denom = coshx + cosy; ChkFloatDenom(denom); Arg1->d.x = sinhx/denom; Arg1->d.y = siny/denom; } #ifndef XFRACT void mStkTanh(void) { mStkFunct(dStkTanh); /* call lStk via dStk */ } void lStkTanh(void) { long x, y, siny, cosy, sinhx, coshx, denom; x = Arg1->l.x >> Delta16; x = x << 1; y = Arg1->l.y >> Delta16; y = y << 1; SinCos086(y, &siny, &cosy); SinhCosh086(x, &sinhx, &coshx); denom = coshx + cosy; ChkLongDenom(denom); Arg1->l.x = divide(sinhx,denom,bitshift); Arg1->l.y = divide(siny,denom,bitshift); } #endif void (*StkTanh)(void) = dStkTanh; void dStkCoTan(void) { double sinx, cosx, sinhy, coshy, denom; Arg1->d.x *= 2; Arg1->d.y *= 2; FPUsincos(&Arg1->d.x, &sinx, &cosx); FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); denom = coshy - cosx; ChkFloatDenom(denom); Arg1->d.x = sinx/denom; Arg1->d.y = -sinhy/denom; } #ifndef XFRACT void mStkCoTan(void) { mStkFunct(dStkCoTan); /* call lStk via dStk */ } void lStkCoTan(void) { long x, y, sinx, cosx, sinhy, coshy, denom; x = Arg1->l.x >> Delta16; x = x << 1; y = Arg1->l.y >> Delta16; y = y << 1; SinCos086(x, &sinx, &cosx); SinhCosh086(y, &sinhy, &coshy); denom = coshy - cosx; ChkLongDenom(denom); Arg1->l.x = divide(sinx,denom,bitshift); Arg1->l.y = -divide(sinhy,denom,bitshift); } #endif void (*StkCoTan)(void) = dStkCoTan; void dStkCoTanh(void) { double siny, cosy, sinhx, coshx, denom; Arg1->d.x *= 2; Arg1->d.y *= 2; FPUsincos(&Arg1->d.y, &siny, &cosy); FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); denom = coshx - cosy; ChkFloatDenom(denom); Arg1->d.x = sinhx/denom; Arg1->d.y = -siny/denom; } #ifndef XFRACT void mStkCoTanh(void) { mStkFunct(dStkCoTanh); /* call lStk via dStk */ } void lStkCoTanh(void) { long x, y, siny, cosy, sinhx, coshx, denom; x = Arg1->l.x >> Delta16; x = x << 1; y = Arg1->l.y >> Delta16; y = y << 1; SinCos086(y, &siny, &cosy); SinhCosh086(x, &sinhx, &coshx); denom = coshx - cosy; ChkLongDenom(denom); Arg1->l.x = divide(sinhx,denom,bitshift); Arg1->l.y = -divide(siny,denom,bitshift); } #endif void (*StkCoTanh)(void) = dStkCoTanh; /* The following functions are not directly used by the parser - support for the parser was not provided because the existing parser language represents these quite easily. They are used for fn variable support in miscres.c but are placed here because they follow the pattern of the other parser functions. TIW 04-22-91 */ void dStkRecip(void) { double mod; mod =Arg1->d.x * Arg1->d.x + Arg1->d.y * Arg1->d.y; ChkFloatDenom(mod); Arg1->d.x = Arg1->d.x/mod; Arg1->d.y = -Arg1->d.y/mod; } #ifndef XFRACT void mStkRecip(void) { struct MP mod; mod = *MPadd(*MPmul(Arg1->m.x, Arg1->m.x),*MPmul(Arg1->m.y, Arg1->m.y)); if(mod.Mant == 0L) { overflow = 1; return; } Arg1->m.x = *MPdiv(Arg1->m.x,mod); Arg1->m.y = *MPdiv(Arg1->m.y,mod); Arg1->m.y.Exp ^= 0x8000; } void lStkRecip(void) { long mod; mod = multiply(Arg1->l.x,Arg1->l.x,bitshift) + multiply(Arg1->l.y,Arg1->l.y,bitshift); if(save_release > 1920) { ChkLongDenom(mod); } else if(mod<=0L) return; Arg1->l.x = divide(Arg1->l.x,mod,bitshift); Arg1->l.y = -divide(Arg1->l.y,mod,bitshift); } #endif void StkIdent(void) { /* do nothing - the function Z */ } /* End TIW 04-22-91 */ void dStkSinh(void) { double siny, cosy, sinhx, coshx; FPUsincos(&Arg1->d.y, &siny, &cosy); FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); Arg1->d.x = sinhx*cosy; Arg1->d.y = coshx*siny; } #ifndef XFRACT void mStkSinh(void) { mStkFunct(dStkSinh); /* call lStk via dStk */ } void lStkSinh(void) { long x, y, sinhx, coshx, siny, cosy; x = Arg1->l.x >> Delta16; y = Arg1->l.y >> Delta16; SinCos086(y, &siny, &cosy); SinhCosh086(x, &sinhx, &coshx); Arg1->l.x = multiply(cosy, sinhx, ShiftBack); /* TIW 06-18-90 */ Arg1->l.y = multiply(siny, coshx, ShiftBack); /* TIW 06-18-90 */ } #endif void (*StkSinh)(void) = dStkSinh; void dStkCos(void) { double sinx, cosx, sinhy, coshy; FPUsincos(&Arg1->d.x, &sinx, &cosx); FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); Arg1->d.x = cosx*coshy; Arg1->d.y = -sinx*sinhy; /* TIW 04-25-91 sign */ } #ifndef XFRACT void mStkCos(void) { mStkFunct(dStkCos); /* call lStk via dStk */ } void lStkCos(void) { long x, y, sinx, cosx, sinhy, coshy; x = Arg1->l.x >> Delta16; y = Arg1->l.y >> Delta16; SinCos086(x, &sinx, &cosx); SinhCosh086(y, &sinhy, &coshy); Arg1->l.x = multiply(cosx, coshy, ShiftBack); /* TIW 06-18-90 */ Arg1->l.y = -multiply(sinx, sinhy, ShiftBack); /* TIW 04-25-91 sign */ } #endif void (*StkCos)(void) = dStkCos; /* Bogus version of cos, to replicate bug which was in regular cos till v16: */ void dStkCosXX(void) { dStkCos(); Arg1->d.y = -Arg1->d.y; } #ifndef XFRACT void mStkCosXX(void) { mStkFunct(dStkCosXX); /* call lStk via dStk */ } void lStkCosXX(void) { lStkCos(); Arg1->l.y = -Arg1->l.y; } #endif void (*StkCosXX)(void) = dStkCosXX; void dStkCosh(void) { double siny, cosy, sinhx, coshx; FPUsincos(&Arg1->d.y, &siny, &cosy); FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); Arg1->d.x = coshx*cosy; Arg1->d.y = sinhx*siny; } #ifndef XFRACT void mStkCosh(void) { mStkFunct(dStkCosh); /* call lStk via dStk */ } void lStkCosh(void) { long x, y, sinhx, coshx, siny, cosy; x = Arg1->l.x >> Delta16; y = Arg1->l.y >> Delta16; SinCos086(y, &siny, &cosy); SinhCosh086(x, &sinhx, &coshx); Arg1->l.x = multiply(cosy, coshx, ShiftBack); /* TIW 06-18-90 */ Arg1->l.y = multiply(siny, sinhx, ShiftBack); /* TIW 06-18-90 */ } #endif void (*StkCosh)(void) = dStkCosh; /* TIW added arc functions here 11-25-94 */ void dStkASin(void) { Arcsinz(Arg1->d, &(Arg1->d)); } #ifndef XFRACT void mStkASin(void) { mStkFunct(dStkASin); } void lStkASin(void) { lStkFunct(dStkASin); } #endif void (*StkASin)(void) = dStkASin; void dStkASinh(void) { Arcsinhz(Arg1->d, &(Arg1->d)); } #ifndef XFRACT void mStkASinh(void) { mStkFunct(dStkASinh); } void lStkASinh(void) { lStkFunct(dStkASinh); } #endif void (*StkASinh)(void) = dStkASinh; void dStkACos(void) { Arccosz(Arg1->d, &(Arg1->d)); } #ifndef XFRACT void mStkACos(void) { mStkFunct(dStkACos); } void lStkACos(void) { lStkFunct(dStkACos); } #endif void (*StkACos)(void) = dStkACos; void dStkACosh(void) { Arccoshz(Arg1->d, &(Arg1->d)); } #ifndef XFRACT void mStkACosh(void) { mStkFunct(dStkACosh); } void lStkACosh(void) { lStkFunct(dStkACosh); } #endif void (*StkACosh)(void) = dStkACosh; void dStkATan(void) { Arctanz(Arg1->d, &(Arg1->d)); } #ifndef XFRACT void mStkATan(void) { mStkFunct(dStkATan); } void lStkATan(void) { lStkFunct(dStkATan); } #endif void (*StkATan)(void) = dStkATan; void dStkATanh(void) { Arctanhz(Arg1->d, &(Arg1->d)); } #ifndef XFRACT void mStkATanh(void) { mStkFunct(dStkATanh); } void lStkATanh(void) { lStkFunct(dStkATanh); } #endif void (*StkATanh)(void) = dStkATanh; void dStkSqrt(void) { Arg1->d = ComplexSqrtFloat(Arg1->d.x, Arg1->d.y); } #ifndef XFRACT void mStkSqrt(void) { mStkFunct(dStkSqrt); } void lStkSqrt(void) { /* lStkFunct(dStkSqrt); */ Arg1->l = ComplexSqrtLong(Arg1->l.x, Arg1->l.y); } #endif void (*StkSqrt)(void) = dStkSqrt; void dStkCAbs(void) { Arg1->d.x = sqrt(sqr(Arg1->d.x)+sqr(Arg1->d.y)); Arg1->d.y = 0.0; } #ifndef XFRACT void mStkCAbs(void) { mStkFunct(dStkCAbs); } void lStkCAbs(void) { lStkFunct(dStkCAbs); } #endif void (*StkCAbs)(void) = dStkCAbs; /* TIW end arc functions 11-25-94 */ void dStkLT(void) { Arg2->d.x = (double)(Arg2->d.x < Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkLT(void) { Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == -1), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkLT(void) { Arg2->l.x = (long)(Arg2->l.x < Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkLT)(void) = dStkLT; void dStkGT(void) { Arg2->d.x = (double)(Arg2->d.x > Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkGT(void) { Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == 1), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkGT(void) { Arg2->l.x = (long)(Arg2->l.x > Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkGT)(void) = dStkGT; void dStkLTE(void) { Arg2->d.x = (double)(Arg2->d.x <= Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkLTE(void) { int comp; comp = MPcmp(Arg2->m.x, Arg1->m.x); Arg2->m.x = *fg2MP((long)(comp == -1 || comp == 0), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkLTE(void) { Arg2->l.x = (long)(Arg2->l.x <= Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkLTE)(void) = dStkLTE; void dStkGTE(void) { Arg2->d.x = (double)(Arg2->d.x >= Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkGTE(void) { int comp; comp = MPcmp(Arg2->m.x, Arg1->m.x); Arg2->m.x = *fg2MP((long)(comp == 1 || comp == 0), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkGTE(void) { Arg2->l.x = (long)(Arg2->l.x >= Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkGTE)(void) = dStkGTE; void dStkEQ(void) { Arg2->d.x = (double)(Arg2->d.x == Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkEQ(void) { int comp; comp = MPcmp(Arg2->m.x, Arg1->m.x); Arg2->m.x = *fg2MP((long)(comp == 0), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkEQ(void) { Arg2->l.x = (long)(Arg2->l.x == Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkEQ)(void) = dStkEQ; void dStkNE(void) { Arg2->d.x = (double)(Arg2->d.x != Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkNE(void) { int comp; comp = MPcmp(Arg2->m.x, Arg1->m.x); Arg2->m.x = *fg2MP((long)(comp != 0), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkNE(void) { Arg2->l.x = (long)(Arg2->l.x != Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkNE)(void) = dStkNE; void dStkOR(void) { Arg2->d.x = (double)(Arg2->d.x || Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkOR(void) { Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant || Arg1->m.x.Mant), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkOR(void) { Arg2->l.x = (long)(Arg2->l.x || Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkOR)(void) = dStkOR; void dStkAND(void) { Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x); Arg2->d.y = 0.0; Arg1--; Arg2--; } #ifndef XFRACT void mStkAND(void) { Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant && Arg1->m.x.Mant), 0); Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); Arg1--; Arg2--; } void lStkAND(void) { Arg2->l.x = (long)(Arg2->l.x && Arg1->l.x) << bitshift; /* JCO 12/26/94 */ Arg2->l.y = 0l; Arg1--; Arg2--; } #endif void (*StkAND)(void) = dStkAND; void dStkLog(void) { FPUcplxlog(&Arg1->d, &Arg1->d); } #ifndef XFRACT void mStkLog(void) { mStkFunct(dStkLog); /* call lStk via dStk */ } void lStkLog(void) { lStkFunct(dStkLog); } #endif void (*StkLog)(void) = dStkLog; void FPUcplxexp(_CMPLX *x, _CMPLX *z) { double e2x, siny, cosy; if(fpu >= 387) FPUcplxexp387(x, z); else { e2x = exp(x->x); FPUsincos(&x->y, &siny, &cosy); z->x = e2x * cosy; z->y = e2x * siny; } } void dStkExp(void) { FPUcplxexp(&Arg1->d, &Arg1->d); } #ifndef XFRACT void mStkExp(void) { mStkFunct(dStkExp); /* call lStk via dStk */ } void lStkExp(void) { lStkFunct(dStkExp); } #endif void (*StkExp)(void) = dStkExp; void dStkPwr(void) { Arg2->d = ComplexPower(Arg2->d, Arg1->d); Arg1--; Arg2--; } #ifndef XFRACT #if (_MSC_VER >= 700) #pragma code_seg ("mpmath1_text") /* place following in an overlay */ #endif void mStkPwr(void) { _CMPLX x, y; x = MPC2cmplx(Arg2->m); y = MPC2cmplx(Arg1->m); x = ComplexPower(x, y); Arg2->m = cmplx2MPC(x); Arg1--; Arg2--; } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif void lStkPwr(void) { _CMPLX x, y; x.x = (double)Arg2->l.x / fg; x.y = (double)Arg2->l.y / fg; y.x = (double)Arg1->l.x / fg; y.y = (double)Arg1->l.y / fg; x = ComplexPower(x, y); if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) { Arg2->l.x = (long)(x.x * fg); Arg2->l.y = (long)(x.y * fg); } else overflow = 1; Arg1--; Arg2--; } #endif void (*StkPwr)(void) = dStkPwr; void EndInit(void) { LastInitOp = OpPtr; InitJumpIndex = jump_index; } void (*PtrEndInit)(void) = EndInit; void StkJump (void) { OpPtr = jump_control[jump_index].ptrs.JumpOpPtr; LodPtr = jump_control[jump_index].ptrs.JumpLodPtr; StoPtr = jump_control[jump_index].ptrs.JumpStoPtr; jump_index = jump_control[jump_index].DestJumpIndex; } void dStkJumpOnFalse (void) { if(Arg1->d.x == 0) StkJump(); else jump_index++; } void mStkJumpOnFalse (void) { #ifndef XFRACT if(Arg1->m.x.Mant == 0) StkJump(); else jump_index++; #endif } void lStkJumpOnFalse (void) { if(Arg1->l.x == 0) StkJump(); else jump_index++; } void (*StkJumpOnFalse)(void) = dStkJumpOnFalse; void dStkJumpOnTrue (void) { if(Arg1->d.x) StkJump(); else jump_index++; } void mStkJumpOnTrue (void) { #ifndef XFRACT if(Arg1->m.x.Mant) StkJump(); else jump_index++; #endif } void lStkJumpOnTrue (void) { if(Arg1->l.x) StkJump(); else jump_index++; } void (*StkJumpOnTrue)(void) = dStkJumpOnTrue; void StkJumpLabel (void) { jump_index++; } #if (_MSC_VER >= 700) #pragma code_seg ("parser1_text") /* place following in an overlay */ #endif unsigned SkipWhiteSpace(char *Str) { unsigned n, Done; for(Done = n = 0; !Done; n++) { switch(Str[n]) { case ' ': case '\t': case '\n': case '\r': break; default: Done = 1; } } return(n - 1); } /* detect if constant is part of a (a,b) construct */ static int isconst_pair(char *Str) { int n,j; int answer = 0; /* skip past first number */ for(n = 0; isdigit(Str[n]) || Str[n] == '.'; n++); if(Str[n] == ',') { j = n + SkipWhiteSpace(&Str[n+1]) + 1; if(isdigit(Str[j]) || (Str[j] == '-' && (isdigit(Str[j+1]) || Str[j+1] == '.')) || Str[j] == '.') { answer = 1; } } return(answer); } struct ConstArg far *isconst(char *Str, int Len) { _CMPLX z; unsigned n, j; /* next line enforces variable vs constant naming convention */ for(n = 0; n < vsp; n++) { if(v[n].len == Len) { if(!strnicmp(v[n].s, Str, Len)) { if(n == 1) /* The formula uses 'p1'. */ uses_p1 = 1; if(n == 2) /* The formula uses 'p2'. */ uses_p2 = 1; if(n == 7) /* The formula uses 'rand'. */ RandomSeed(); if(n == 8) /* The formula uses 'p3'. */ uses_p3 = 1; if(n == 13) /* The formula uses 'ismand'. */ uses_ismand = 1; if(n == 17) /* The formula uses 'p4'. */ uses_p4 = 1; if(n == 18) /* The formula uses 'p5'. */ uses_p5 = 1; #ifndef XFRACT if(n == 10 || n == 11 || n == 12) if(MathType == L_MATH) keybuffer = 'f'; #endif if(!isconst_pair(Str)) return(&v[n]); } } } v[vsp].s = Str; v[vsp].len = Len; v[vsp].a.d.x = v[vsp].a.d.y = 0.0; #ifndef XFRACT /* v[vsp].a should already be zeroed out */ switch(MathType) { case M_MATH: v[vsp].a.m.x.Mant = v[vsp].a.m.x.Exp = 0; v[vsp].a.m.y.Mant = v[vsp].a.m.y.Exp = 0; break; case L_MATH: v[vsp].a.l.x = v[vsp].a.l.y = 0; break; } #endif if(isdigit(Str[0]) || (Str[0] == '-' && (isdigit(Str[1]) || Str[1] == '.')) || Str[0] == '.') { if(o[posp-1].f == StkNeg) { posp--; Str = Str - 1; InitN--; v[vsp].len++; } for(n = 1; isdigit(Str[n]) || Str[n] == '.'; n++); if(Str[n] == ',') { j = n + SkipWhiteSpace(&Str[n+1]) + 1; if(isdigit(Str[j]) || (Str[j] == '-' && (isdigit(Str[j+1]) || Str[j+1] == '.')) || Str[j] == '.') { z.y = atof(&Str[j]); for(; isdigit(Str[j]) || Str[j] == '.' || Str[j] == '-'; j++); v[vsp].len = j; } else z.y = 0.0; } else z.y = 0.0; z.x = atof(Str); switch(MathType) { case D_MATH: v[vsp].a.d = z; break; #ifndef XFRACT case M_MATH: v[vsp].a.m = cmplx2MPC(z); break; case L_MATH: v[vsp].a.l.x = (long)(z.x * fg); v[vsp].a.l.y = (long)(z.y * fg); break; #endif } v[vsp].s = Str; } return(&v[vsp++]); } struct FNCT_LIST { char far *s; /* TIW 03-31-91 added far */ void (**ptr)(void); }; /* TIW 03-30-91 START */ void (*StkTrig0)(void) = dStkSin; void (*StkTrig1)(void) = dStkSqr; void (*StkTrig2)(void) = dStkSinh; void (*StkTrig3)(void) = dStkCosh; char far * JumpList[] = { "if", "elseif", "else", "endif", "" }; int isjump(char *Str, int Len) { /* return values 0 - Not a jump 1 - if 2 - elseif 3 - else 4 - endif */ int i; for(i = 0; *JumpList[i]; i++) if(far_strlen(JumpList[i]) == Len) if(!far_strnicmp(JumpList[i], Str, Len)) return i + 1; return 0; } char maxfn = 0; /* TIW 03-30-91 STOP */ struct FNCT_LIST far FnctList[] = { /* TIW 03-31-91 added far */ {s_sin, &StkSin}, {s_sinh, &StkSinh}, {s_cos, &StkCos}, {s_cosh, &StkCosh}, {s_sqr, &StkSqr}, {s_log, &StkLog}, {s_exp, &StkExp}, {s_abs, &StkAbs}, {s_conj, &StkConj}, {s_real, &StkReal}, {s_imag, &StkImag}, {s_fn1, &StkTrig0}, /* TIW 03-30-91 */ {s_fn2, &StkTrig1}, /* TIW 03-30-91 */ {s_fn3, &StkTrig2}, /* TIW 03-30-91 */ {s_fn4, &StkTrig3}, /* TIW 03-30-91 */ {s_flip, &StkFlip}, /* MCP 4-9-91 */ {s_tan, &StkTan}, /* TIW 04-22-91 */ {s_tanh, &StkTanh}, /* TIW 04-22-91 */ {s_cotan, &StkCoTan}, /* TIW 04-24-91 */ {s_cotanh,&StkCoTanh}, /* TIW 04-24-91 */ {s_cosxx, &StkCosXX}, /* PB 04-28-91 */ {s_srand, &StkSRand}, /* MCP 11-21-91 */ {s_asin, &StkASin}, /* TIW 11-26-94 */ {s_asinh, &StkASinh}, /* TIW 11-26-94 */ {s_acos, &StkACos}, /* TIW 11-26-94 */ {s_acosh, &StkACosh}, /* TIW 11-26-94 */ {s_atan, &StkATan}, /* TIW 11-26-94 */ {s_atanh, &StkATanh}, /* TIW 11-26-94 */ {s_sqrt, &StkSqrt}, /* TIW 11-26-94 */ {s_cabs, &StkCAbs}, /* TIW 11-26-94 */ {s_floor, &StkFloor}, /* TIW 06-30-96 */ {s_ceil, &StkCeil}, /* TIW 06-30-96 */ {s_trunc, &StkTrunc}, /* TIW 06-30-96 */ {s_round, &StkRound}, /* TIW 06-30-96 */ }; struct OP_LIST { char *s; void (**ptr)(void); }; struct OP_LIST far OPList[] = { {"," , &PtrStkClr }, /* 0 */ {"!=" , &StkNE }, /* 1 */ {"=" , &PtrStkSto }, /* 2 */ {"==" , &StkEQ }, /* 3 */ {"<" , &StkLT }, /* 4 */ {"<=" , &StkLTE }, /* 5 */ {">" , &StkGT }, /* 6 */ {">=" , &StkGTE }, /* 7 */ {"|" , &StkMod }, /* 8 */ {"||" , &StkOR }, /* 9 */ {"&&" , &StkAND }, /* 10 */ {":" , &PtrEndInit }, /* 11 */ {"+" , &StkAdd }, /* 12 */ {"-" , &StkSub }, /* 13 */ {"*" , &StkMul }, /* 14 */ {"/" , &StkDiv }, /* 15 */ {"^" , &StkPwr }, /* 16 */ }; void NotAFnct(void) { } void FnctNotFound(void) { } /* determine if s names a function and if so which one */ /* TIW 04-22-91 */ int whichfn(char *s, int len) { int out; if(len != 3) out = 0; else if(strnicmp(s,"fn",2)) out = 0; else out = atoi(s+2); if(out < 1 || out > 4) out = 0; return(out); } #ifndef XFRACT void (far *isfunct(char *Str, int Len))(void) #else void (*isfunct(Str, Len))() char *Str; int Len; #endif { unsigned n; int functnum; /* TIW 04-22-91 */ n = SkipWhiteSpace(&Str[Len]); if(Str[Len+n] == '(') { for(n = 0; n < sizeof(FnctList) / sizeof(struct FNCT_LIST); n++) { if(far_strlen(FnctList[n].s) == Len) { /* TIW 03-31-91 added far */ if(!far_strnicmp(FnctList[n].s, Str, Len)) { /* TIW 03-31-91 added far */ /* count function variables */ if((functnum = whichfn(Str, Len)) != 0) /* TIW 04-22-91 */ if(functnum > maxfn) /* TIW 04-22-91 */ maxfn = (char)functnum; /* TIW 04-22-91 */ return(*FnctList[n].ptr); } } } return(FnctNotFound); } return(NotAFnct); } void RecSortPrec(void) { int ThisOp = NextOp++; while(o[ThisOp].p > o[NextOp].p && NextOp < posp) RecSortPrec(); f[OpPtr++] = o[ThisOp].f; } static char *Constants[] = { "pixel", /* v[0] */ "p1", /* v[1] */ "p2", /* v[2] */ "z", /* v[3] */ "LastSqr", /* v[4] */ "pi", /* v[5] */ "e", /* v[6] */ "rand", /* v[7] */ "p3", /* v[8] */ "whitesq", /* v[9] */ "scrnpix", /* v[10] */ "scrnmax", /* v[11] */ "maxit", /* v[12] */ s_ismand, /* v[13] */ "center", /* v[14] */ "magxmag", /* v[15] */ "rotskew", /* v[16] */ "p4", /* v[17] */ "p5" /* v[18] */ }; struct SYMETRY { char *s; int n; } SymStr[] = { {"NOSYM", 0}, {"XAXIS_NOPARM", -1}, {"XAXIS", 1}, {"YAXIS_NOPARM", -2}, {"YAXIS", 2}, {"XYAXIS_NOPARM",-3}, {"XYAXIS", 3}, {"ORIGIN_NOPARM",-4}, {"ORIGIN", 4}, {"PI_SYM_NOPARM",-5}, {"PI_SYM", 5}, {"XAXIS_NOIMAG", -6}, {"XAXIS_NOREAL", 6}, {"NOPLOT", 99}, {"", 0} }; static int ParseStr(char *Str, int pass) { struct ConstArg far *c; int ModFlag = 999, Len, Equals = 0, Mod[20], mdstk = 0; int jumptype; double const_pi, const_e; double Xctr, Yctr, Xmagfactor, Rotation, Skew; LDBL Magnification; SetRandom = Randomized = 0; uses_jump = 0; jump_index = 0; if(pass == 0) o = (struct PEND_OP far *) ((char far *)typespecific_workarea + total_formula_mem-sizeof(struct PEND_OP) * Max_Ops); else if(used_extra == 1) o = (struct PEND_OP far *) ((char far *)typespecific_workarea + total_formula_mem-sizeof(struct PEND_OP) * Max_Ops); else o = (struct PEND_OP far *)farmemalloc(sizeof(struct PEND_OP) * (long)Max_Ops); if( !o || !typespecific_workarea) { stopmsg(0,ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); return(1); } switch(MathType) { case D_MATH: StkAdd = dStkAdd; StkSub = dStkSub; StkNeg = dStkNeg; StkMul = dStkMul; StkSin = dStkSin; StkSinh = dStkSinh; StkLT = dStkLT; StkLTE = dStkLTE; StkMod = dStkMod; StkSqr = dStkSqr; StkCos = dStkCos; StkCosh = dStkCosh; StkLog = dStkLog; StkExp = dStkExp; StkPwr = dStkPwr; StkDiv = dStkDiv; StkAbs = dStkAbs; StkReal = dStkReal; StkImag = dStkImag; StkConj = dStkConj; StkTrig0 = dtrig0; /* TIW 03-30-91 */ StkTrig1 = dtrig1; /* TIW 03-30-91 */ StkTrig2 = dtrig2; /* TIW 03-30-91 */ StkTrig3 = dtrig3; /* TIW 03-30-91 */ StkFlip = dStkFlip; StkTan = dStkTan; /* TIW 04-22-91 */ StkTanh = dStkTanh; /* TIW 04-22-91 */ StkCoTan = dStkCoTan; /* TIW 04-24-91 */ StkCoTanh = dStkCoTanh; /* TIW 04-24-91 */ StkCosXX = dStkCosXX; /* PB 04-28-91 */ StkGT = dStkGT; /* MCP 11-3-91 */ StkGTE = dStkGTE; /* MCP 11-3-91 */ StkEQ = dStkEQ; /* MCP 11-3-91 */ StkNE = dStkNE; /* MCP 11-3-91 */ StkAND = dStkAND; /* MCP 11-3-91 */ StkOR = dStkOR ; /* MCP 11-3-91 */ StkSRand = dStkSRand; /* MCP 11-21-91 */ StkASin = dStkASin; /* TIW 11-25-94 */ StkASinh = dStkASinh; /* TIW 11-25-94 */ StkACos = dStkACos; /* TIW 11-25-94 */ StkACosh = dStkACosh; /* TIW 11-25-94 */ StkATan = dStkATan; /* TIW 11-25-94 */ StkATanh = dStkATanh; /* TIW 11-25-94 */ StkCAbs = dStkCAbs; /* TIW 11-25-94 */ StkSqrt = dStkSqrt; /* TIW 11-25-94 */ StkZero = dStkZero; /* JCO 12-31-94 */ StkFloor = dStkFloor; /* TIW 06-30-96 */ StkCeil = dStkCeil; /* TIW 06-30-96 */ StkTrunc = dStkTrunc; /* TIW 06-30-96 */ StkRound = dStkRound; /* TIW 06-30-96 */ StkJumpOnTrue = dStkJumpOnTrue; /* GGM 02-10-97 */ StkJumpOnFalse = dStkJumpOnFalse; /* GGM 02-10-97 */ StkOne = dStkOne; /* GGM 10-08-97 */ break; #ifndef XFRACT case M_MATH: StkAdd = mStkAdd; StkSub = mStkSub; StkNeg = mStkNeg; StkMul = mStkMul; StkSin = mStkSin; StkSinh = mStkSinh; StkLT = mStkLT; StkLTE = mStkLTE; StkMod = mStkMod; StkSqr = mStkSqr; StkCos = mStkCos; StkCosh = mStkCosh; StkLog = mStkLog; StkExp = mStkExp; StkPwr = mStkPwr; StkDiv = mStkDiv; StkAbs = mStkAbs; StkReal = mStkReal; StkImag = mStkImag; StkConj = mStkConj; StkTrig0 = mtrig0; /* TIW 03-30-91 */ StkTrig1 = mtrig1; /* TIW 03-30-91 */ StkTrig2 = mtrig2; /* TIW 03-30-91 */ StkTrig3 = mtrig3; /* TIW 03-30-91 */ StkFlip = mStkFlip; StkTan = mStkTan; /* TIW 04-22-91 */ StkTanh = mStkTanh;/* TIW 04-22-91 */ StkCoTan = mStkCoTan; /* TIW 04-24-91 */ StkCoTanh = mStkCoTanh;/* TIW 04-24-91 */ StkCosXX = mStkCosXX; /* PB 04-28-91 */ StkGT = mStkGT; /* MCP 11-3-91 */ StkGTE = mStkGTE; /* MCP 11-3-91 */ StkEQ = mStkEQ; /* MCP 11-3-91 */ StkNE = mStkNE; /* MCP 11-3-91 */ StkAND = mStkAND; /* MCP 11-3-91 */ StkOR = mStkOR ; /* MCP 11-3-91 */ StkSRand = mStkSRand; /* MCP 11-21-91 */ StkASin = mStkASin; /* TIW 11-25-94 */ StkACos = mStkACos; /* TIW 11-25-94 */ StkACosh = mStkACosh; /* TIW 11-25-94 */ StkATan = mStkATan; /* TIW 11-25-94 */ StkATanh = mStkATanh; /* TIW 11-25-94 */ StkCAbs = mStkCAbs; /* TIW 11-25-94 */ StkSqrt = mStkSqrt; /* TIW 11-25-94 */ StkZero = mStkZero; /* JCO 12-31-94 */ StkFloor = mStkFloor; /* TIW 06-30-96 */ StkCeil = mStkCeil; /* TIW 06-30-96 */ StkTrunc = mStkTrunc; /* TIW 06-30-96 */ StkRound = mStkRound; /* TIW 06-30-96 */ StkJumpOnTrue = mStkJumpOnTrue; /* GGM 02-10-97 */ StkJumpOnFalse = mStkJumpOnFalse; /* GGM 02-10-97 */ StkOne = mStkOne; /* GGM 10-08-97 */ break; case L_MATH: Delta16 = bitshift - 16; ShiftBack = 32 - bitshift; /* TW 06-18-90 */ StkAdd = lStkAdd; StkSub = lStkSub; StkNeg = lStkNeg; StkMul = lStkMul; StkSin = lStkSin; StkSinh = lStkSinh; StkLT = lStkLT; StkLTE = lStkLTE; if (save_release > 1826) StkMod = lStkMod; else StkMod = lStkModOld; StkSqr = lStkSqr; StkCos = lStkCos; StkCosh = lStkCosh; StkLog = lStkLog; StkExp = lStkExp; StkPwr = lStkPwr; StkDiv = lStkDiv; StkAbs = lStkAbs; StkReal = lStkReal; StkImag = lStkImag; StkConj = lStkConj; StkTrig0 = ltrig0; /* TIW 03-30-91 */ StkTrig1 = ltrig1; /* TIW 03-30-91 */ StkTrig2 = ltrig2; /* TIW 03-30-91 */ StkTrig3 = ltrig3; /* TIW 03-30-91 */ StkFlip = lStkFlip; StkTan = lStkTan; /* TIW 04-22-91 */ StkTanh = lStkTanh; /* TIW 04-22-91 */ StkCoTan = lStkCoTan; /* TIW 04-24-91 */ StkCoTanh = lStkCoTanh; /* TIW 04-24-91 */ StkCosXX = lStkCosXX; /* PB 04-28-91 */ StkGT = lStkGT; /* MCP 11-3-91 */ StkGTE = lStkGTE; /* MCP 11-3-91 */ StkEQ = lStkEQ; /* MCP 11-3-91 */ StkNE = lStkNE; /* MCP 11-3-91 */ StkAND = lStkAND; /* MCP 11-3-91 */ StkOR = lStkOR ; /* MCP 11-3-91 */ StkSRand = lStkSRand; /* MCP 11-21-91 */ StkASin = lStkASin; /* TIW 11-25-94 */ StkACos = lStkACos; /* TIW 11-25-94 */ StkACosh = lStkACosh; /* TIW 11-25-94 */ StkATan = lStkATan; /* TIW 11-25-94 */ StkATanh = lStkATanh; /* TIW 11-25-94 */ StkCAbs = lStkCAbs; /* TIW 11-25-94 */ StkSqrt = lStkSqrt; /* TIW 11-25-94 */ StkZero = lStkZero; /* JCO 12-31-94 */ StkFloor = lStkFloor; /* TIW 06-30-96 */ StkCeil = lStkCeil; /* TIW 06-30-96 */ StkTrunc = lStkTrunc; /* TIW 06-30-96 */ StkRound = lStkRound; /* TIW 06-30-96 */ StkJumpOnTrue = lStkJumpOnTrue; /* GGM 02-10-97 */ StkJumpOnFalse = lStkJumpOnFalse; /* GGM 02-10-97 */ StkOne = lStkOne; /* GGM 10-08-97 */ break; #endif } maxfn = 0; /* TIW 03-30-91 */ for(vsp = 0; vsp < sizeof(Constants) / sizeof(char*); vsp++) { v[vsp].s = Constants[vsp]; v[vsp].len = strlen(Constants[vsp]); } cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); const_pi = atan(1.0) * 4; const_e = exp(1.0); v[7].a.d.x = v[7].a.d.y = 0.0; v[11].a.d.x = (double)xdots; v[11].a.d.y = (double)ydots; v[12].a.d.x = (double)maxit; v[12].a.d.y = 0; v[13].a.d.x = (double)ismand; v[13].a.d.y = 0; v[14].a.d.x = Xctr; v[14].a.d.y = Yctr; v[15].a.d.x = (double)Magnification; v[15].a.d.y = Xmagfactor; v[16].a.d.x = Rotation; v[16].a.d.y = Skew; switch(MathType) { case D_MATH: v[1].a.d.x = param[0]; v[1].a.d.y = param[1]; v[2].a.d.x = param[2]; v[2].a.d.y = param[3]; v[5].a.d.x = const_pi; v[5].a.d.y = 0.0; v[6].a.d.x = const_e; v[6].a.d.y = 0.0; v[8].a.d.x = param[4]; v[8].a.d.y = param[5]; v[17].a.d.x = param[6]; v[17].a.d.y = param[7]; v[18].a.d.x = param[8]; v[18].a.d.y = param[9]; break; #ifndef XFRACT case M_MATH: v[1].a.m.x = *d2MP(param[0]); v[1].a.m.y = *d2MP(param[1]); v[2].a.m.x = *d2MP(param[2]); v[2].a.m.y = *d2MP(param[3]); v[5].a.m.x = *d2MP(const_pi); v[5].a.m.y = *d2MP(0.0); v[6].a.m.x = *d2MP(const_e); v[6].a.m.y = *d2MP(0.0); v[8].a.m.x = *d2MP(param[4]); v[8].a.m.y = *d2MP(param[5]); v[11].a.m = cmplx2MPC(v[11].a.d); v[12].a.m = cmplx2MPC(v[12].a.d); v[13].a.m = cmplx2MPC(v[13].a.d); v[14].a.m = cmplx2MPC(v[14].a.d); v[15].a.m = cmplx2MPC(v[15].a.d); v[16].a.m = cmplx2MPC(v[16].a.d); v[17].a.m.x = *d2MP(param[6]); v[17].a.m.y = *d2MP(param[7]); v[18].a.m.x = *d2MP(param[8]); v[18].a.m.y = *d2MP(param[9]); break; case L_MATH: v[1].a.l.x = (long)(param[0] * fg); v[1].a.l.y = (long)(param[1] * fg); v[2].a.l.x = (long)(param[2] * fg); v[2].a.l.y = (long)(param[3] * fg); v[5].a.l.x = (long)(const_pi * fg); v[5].a.l.y = 0L; v[6].a.l.x = (long)(const_e * fg); v[6].a.l.y = 0L; v[8].a.l.x = (long)(param[4] * fg); v[8].a.l.y = (long)(param[5] * fg); v[11].a.l.x = xdots; v[11].a.l.x <<= bitshift; v[11].a.l.y = ydots; v[11].a.l.y <<= bitshift; v[12].a.l.x = maxit; v[12].a.l.x <<= bitshift; v[12].a.l.y = 0L; v[13].a.l.x = ismand; v[13].a.l.x <<= bitshift; v[13].a.l.y = 0L; v[14].a.l.x = (long)(v[14].a.d.x * fg); v[14].a.l.y = (long)(v[14].a.d.y * fg); v[15].a.l.x = (long)(v[15].a.d.x * fg); v[15].a.l.y = (long)(v[15].a.d.y * fg); v[16].a.l.x = (long)(v[16].a.d.x * fg); v[16].a.l.y = (long)(v[16].a.d.y * fg); v[17].a.l.x = (long)(param[6] * fg); v[17].a.l.y = (long)(param[7] * fg); v[18].a.l.x = (long)(param[8] * fg); v[18].a.l.y = (long)(param[9] * fg); break; #endif } LastInitOp = paren = OpPtr = LodPtr = StoPtr = posp = 0; ExpectingArg = 1; for(n = 0; Str[n]; n++) { if(!Str[n]) break; InitN = n; switch(Str[n]) { case ' ': case '\t': case '\r': case '\n': break; case '(': paren++; break; case ')': paren--; break; case '|': if(Str[n+1] == '|') { ExpectingArg = 1; n++; o[posp].f = StkOR; o[posp++].p = 7 - (paren + Equals)*15; } else if(ModFlag == paren-1) { paren--; ModFlag = Mod[--mdstk]; } else { Mod[mdstk++] = ModFlag; o[posp].f = StkMod; o[posp++].p = 2 - (paren + Equals)*15; ModFlag = paren++; } break; case ',': case ';': if(!ExpectingArg) { ExpectingArg = 1; o[posp].f = (void(far*)(void))0; o[posp++].p = 15; o[posp].f = StkClr; o[posp++].p = -30000; Equals = paren = 0; } break; case ':': ExpectingArg = 1; o[posp].f = (void(far*)(void))0; o[posp++].p = 15; o[posp].f = EndInit; o[posp++].p = -30000; Equals = paren = 0; LastInitOp = 10000; break; case '+': ExpectingArg = 1; o[posp].f = StkAdd; o[posp++].p = 4 - (paren + Equals)*15; break; case '-': if(ExpectingArg) { o[posp].f = StkNeg; o[posp++].p = 2 - (paren + Equals)*15; } else { o[posp].f = StkSub; o[posp++].p = 4 - (paren + Equals)*15; ExpectingArg = 1; } break; case '&': ExpectingArg = 1; n++; o[posp].f = StkAND; o[posp++].p = 7 - (paren + Equals)*15; break; case '!': ExpectingArg = 1; n++; o[posp].f = StkNE; o[posp++].p = 6 - (paren + Equals)*15; break; case '<': ExpectingArg = 1; if(Str[n+1] == '=') { n++; o[posp].f = StkLTE; } else o[posp].f = StkLT; o[posp++].p = 6 - (paren + Equals)*15; break; case '>': ExpectingArg = 1; if(Str[n+1] == '=') { n++; o[posp].f = StkGTE; } else o[posp].f = StkGT; o[posp++].p = 6 - (paren + Equals)*15; break; case '*': ExpectingArg = 1; o[posp].f = StkMul; o[posp++].p = 3 - (paren + Equals)*15; break; case '/': ExpectingArg = 1; o[posp].f = StkDiv; o[posp++].p = 3 - (paren + Equals)*15; break; case '^': ExpectingArg = 1; o[posp].f = StkPwr; o[posp++].p = 2 - (paren + Equals)*15; break; case '=': ExpectingArg = 1; if(Str[n+1] == '=') { n++; o[posp].f = StkEQ; o[posp++].p = 6 - (paren + Equals)*15; } else { o[posp-1].f = StkSto; o[posp-1].p = 5 - (paren + Equals)*15; Store[StoPtr++] = Load[--LodPtr]; Equals++; } break; default: while(isalnum(Str[n+1]) || Str[n+1] == '.' || Str[n+1] == '_') n++; Len = (n+1)-InitN; ExpectingArg = 0; if((jumptype = isjump(&Str[InitN], Len)) != 0) { uses_jump = 1; switch (jumptype) { case 1: /* if */ ExpectingArg = 1; jump_control[jump_index++].type = 1; o[posp].f = StkJumpOnFalse; o[posp++].p = 1; break; case 2: /* elseif */ ExpectingArg = 1; jump_control[jump_index++].type = 2; jump_control[jump_index++].type = 2; o[posp].f = StkJump; o[posp++].p = 1; o[posp].f = (void(far*)(void))0; o[posp++].p = 15; o[posp].f = StkClr; o[posp++].p = -30000; o[posp].f = StkJumpOnFalse; o[posp++].p = 1; break; case 3: /* else */ jump_control[jump_index++].type = 3; o[posp].f = StkJump; o[posp++].p = 1; break; case 4: /* endif */ jump_control[jump_index++].type = 4; o[posp].f = StkJumpLabel; o[posp++].p = 1; break; default: break; } } else { o[posp].f = isfunct(&Str[InitN], Len); if(o[posp].f != NotAFnct) { o[posp++].p = 1 - (paren + Equals)*15; ExpectingArg = 1; } else { c = isconst(&Str[InitN], Len); Load[LodPtr++] = &(c->a); o[posp].f = StkLod; o[posp++].p = 1 - (paren + Equals)*15; n = InitN + c->len - 1; } } break; } } o[posp].f = (void(far*)(void))0; o[posp++].p = 16; NextOp = 0; LastOp = posp; while(NextOp < posp) { if(o[NextOp].f) RecSortPrec(); else { NextOp++; LastOp--; } } if(pass > 0 && used_extra == 0) farmemfree(o); return(0); } #if (_MSC_VER >= 700) #pragma code_seg () /* back to normal segment */ #endif int Formula(void) { if(FormName[0] == 0 || overflow) return(1); LodPtr = InitLodPtr; StoPtr = InitStoPtr; OpPtr = InitOpPtr; jump_index=InitJumpIndex; /* Set the random number, MCP 11-21-91 */ if(SetRandom || Randomized) { switch(MathType) { case D_MATH: dRandom(); break; #ifndef XFRACT case L_MATH: lRandom(); break; case M_MATH: mRandom(); #endif } } Arg1 = &s[0]; Arg2 = Arg1-1; while(OpPtr < (int)LastOp) { f[OpPtr](); OpPtr++; #ifdef WATCH_MP x1 = *MP2d(Arg1->m.x); y1 = *MP2d(Arg1->m.y); x2 = *MP2d(Arg2->m.x); y2 = *MP2d(Arg2->m.y); #endif } switch(MathType) { case D_MATH: old = new = v[3].a.d; return(Arg1->d.x == 0.0); #ifndef XFRACT case M_MATH: old = new = MPC2cmplx(v[3].a.m); return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0); case L_MATH: lold = lnew = v[3].a.l; if(overflow) return(1); return(Arg1->l.x == 0L); #endif } return(1); } int form_per_pixel(void) { if (FormName[0] == 0) return(1); overflow = LodPtr = StoPtr = OpPtr = jump_index = 0; Arg1 = &s[0]; Arg2 = Arg1; Arg2--; v[10].a.d.x = (double)col; v[10].a.d.y = (double)row; switch(MathType) { case D_MATH: if((row+col)&1) v[9].a.d.x = 1.0; else v[9].a.d.x = 0.0; v[9].a.d.y = 0.0; break; #ifndef XFRACT case M_MATH: if((row+col)&1) v[9].a.m = MPCone; else { v[9].a.m.x.Mant = v[9].a.m.x.Exp = 0; v[9].a.m.y.Mant = v[9].a.m.y.Exp = 0; } v[10].a.m = cmplx2MPC(v[10].a.d); break; case L_MATH: v[9].a.l.x = (long) (((row+col)&1) * fg); v[9].a.l.y = 0L; v[10].a.l.x = col; v[10].a.l.x <<= bitshift; v[10].a.l.y = row; v[10].a.l.y <<= bitshift; break; #endif } /* TW started additions for inversion support here 4/17/94 */ { if(invert) { invertz2(&old); switch(MathType) { case D_MATH: v[0].a.d.x = old.x; v[0].a.d.y = old.y; break; #ifndef XFRACT case M_MATH: v[0].a.m.x = *d2MP(old.x); v[0].a.m.y = *d2MP(old.y); break; case L_MATH: /* watch out for overflow */ if(sqr(old.x)+sqr(old.y) >= 127) { old.x = 8; /* value to bail out in one iteration */ old.y = 8; } /* convert to fudged longs */ v[0].a.l.x = (long)(old.x*fg); v[0].a.l.y = (long)(old.y*fg); break; #endif } } else /* TW end of inversion support changes here 4/17/94 */ switch(MathType) { case D_MATH: v[0].a.d.x = dxpixel(); v[0].a.d.y = dypixel(); break; #ifndef XFRACT case M_MATH: v[0].a.m.x = *d2MP(dxpixel()); v[0].a.m.y = *d2MP(dypixel()); break; case L_MATH: v[0].a.l.x = lxpixel(); v[0].a.l.y = lypixel(); break; #endif } } if(LastInitOp) LastInitOp = LastOp; while(OpPtr < LastInitOp) { f[OpPtr](); OpPtr++; } InitLodPtr = LodPtr; InitStoPtr = StoPtr; InitOpPtr = OpPtr; /* Set old variable for orbits TIW 12-18-93 */ switch(MathType) { case D_MATH: old = v[3].a.d; break; #ifndef XFRACT case M_MATH: old = MPC2cmplx(v[3].a.m); break; case L_MATH: lold = v[3].a.l; break; #endif } if(overflow) return(0); else return(1); } int fill_if_group(int endif_index, JUMP_PTRS_ST* jump_data) { int i = endif_index; int ljp = endif_index; /* ljp means "last jump processed" */ while(i > 0) { i--; switch (jump_control[i].type) { case 1: /*if(); this concludes processing of this group*/ jump_control[i].ptrs = jump_data[ljp]; jump_control[i].DestJumpIndex = ljp + 1; return i; case 2: /*elseif* ( 2 jumps, the else and the if*/ /* first, the "if" part */ jump_control[i].ptrs = jump_data[ljp]; jump_control[i].DestJumpIndex = ljp + 1; /* then, the else part */ i--; /*fall through to "else" is intentional*/ case 3: jump_control[i].ptrs = jump_data[endif_index]; jump_control[i].DestJumpIndex = endif_index + 1; ljp = i; break; case 4: /*endif*/ i = fill_if_group(i, jump_data); break; default: break; } } return -1; /* should never get here */ } int fill_jump_struct(void) { /* Completes all entries in jump structure. Returns 1 on error) */ /* On entry, jump_index is the number of jump functions in the formula*/ int i = 0; int loadcount = 0; int storecount = 0; int checkforelse = 0; void (*JumpFunc)(void) = NULL; int find_new_func = 1; JUMP_PTRS_ST jump_data[MAX_JUMPS]; for (OpPtr = 0; OpPtr < (int) LastOp; OpPtr++) { if(find_new_func) { switch (jump_control[i].type) { case 1: JumpFunc = StkJumpOnFalse; break; case 2: checkforelse = !checkforelse; if(checkforelse) JumpFunc = StkJump; else JumpFunc = StkJumpOnFalse; break; case 3: JumpFunc = StkJump; break; case 4: JumpFunc = StkJumpLabel; break; default: break; } find_new_func = 0; } if(*(f[OpPtr]) == StkLod) loadcount++; else if(*(f[OpPtr]) == StkSto) storecount++; else if(*(f[OpPtr]) == JumpFunc) { jump_data[i].JumpOpPtr = OpPtr; jump_data[i].JumpLodPtr = loadcount; jump_data[i].JumpStoPtr = storecount; i++; find_new_func = 1; } } /* Following for safety only; all should always be false */ if(i != jump_index || jump_control[i - 1].type != 4 || jump_control[0].type != 1) { return 1; } while(i > 0) { i--; i = fill_if_group(i, jump_data); } return i < 0 ? 1 : 0; } static char *FormStr; #if (_MSC_VER >= 700) #pragma code_seg ("parser1_text") /* place following in an overlay */ #endif int frmgetchar (FILE * openfile) { int c; int done = 0; int linewrap = 0; while (!done) { c = getc(openfile); switch (c) { case '\r': case ' ' : case '\t' : break; case '\\': linewrap = 1; break; case ';' : while ((c = getc(openfile)) != '\n' && c != EOF && c != '\032') {} if(c == EOF || c == '\032') done = 1; case '\n' : if(!linewrap) done = 1; linewrap = 0; break; default: done = 1; break; } } return tolower(c); } /* This function also gets flow control info */ void getfuncinfo(struct token_st * tok) { int i; for(i=0; i < sizeof(FnctList)/ sizeof(struct FNCT_LIST); i++) { if(!far_strcmp(FnctList[i].s, tok->token_str)) { tok->token_id = i; if(i >= 11 && i <= 14) tok->token_type = PARAM_FUNCTION; else tok->token_type = FUNCTION; return; } } for (i=0; i < 4; i++) { /*pick up flow control*/ if(!far_strcmp(JumpList[i], tok->token_str)) { tok->token_type = FLOW_CONTROL; tok->token_id = i + 1; return; } } tok->token_type = NOT_A_TOKEN; tok->token_id = UNDEFINED_FUNCTION; return; } void getvarinfo(struct token_st * tok) { int i; for(i=0; i < sizeof(Constants) / sizeof(char*); i++) { if(!far_strcmp(Constants[i], tok->token_str)) { tok->token_id = i; switch(i) { case 1: case 2: case 8: case 13: case 17: case 18: tok->token_type = PARAM_VARIABLE; break; default: tok->token_type = PREDEFINED_VARIABLE; break; } return; } } tok->token_type = USER_NAMED_VARIABLE; tok->token_id = 0; } /* fills in token structure where numeric constant is indicated */ /* Note - this function will be called twice to fill in the components of a complex constant. See is_complex_constant() below. */ /* returns 1 on success, 0 on NOT_A_TOKEN */ int frmgetconstant(FILE * openfile, struct token_st * tok) { int c; int i = 1; int getting_base = 1; long filepos = ftell(openfile); int got_decimal_already = 0; int done = 0; tok->token_const.x = 0.0; /*initialize values to 0*/ tok->token_const.y = 0.0; if(tok->token_str[0] == '.') got_decimal_already = 1; while (!done) { switch (c=frmgetchar(openfile)) { case EOF: case '\032': tok->token_str[i] = (char) 0; tok->token_type = NOT_A_TOKEN; tok->token_id = END_OF_FILE; return 0; CASE_NUM: tok->token_str[i++] = (char) c; filepos=ftell(openfile); break; case '.': if (got_decimal_already || !getting_base) { tok->token_str[i++] = (char) c; tok->token_str[i++] = (char) 0; tok->token_type = NOT_A_TOKEN; tok->token_id = ILL_FORMED_CONSTANT; return 0; } else { tok->token_str[i++] = (char) c; got_decimal_already = 1; filepos=ftell(openfile); } break; default : if(c == 'e' && getting_base && (isdigit(tok->token_str[i-1]) || (tok->token_str[i-1] == '.' && i > 1))) { tok->token_str[i++] = (char) c; getting_base = 0; got_decimal_already = 0; filepos=ftell(openfile); if((c = frmgetchar(openfile)) == '-' || c == '+') { tok->token_str[i++] = (char) c; filepos = ftell(openfile); } else { fseek(openfile, filepos, SEEK_SET); } } else if(isalpha(c) || c == '_') { tok->token_str[i++] = (char) c; tok->token_str[i++] = (char) 0; tok->token_type = NOT_A_TOKEN; tok->token_id = ILL_FORMED_CONSTANT; return 0; } else if (tok->token_str[i-1] == 'e' || (tok->token_str[i-1] == '.' && i == 1)) { tok->token_str[i++] = (char) c; tok->token_str[i++] = (char) 0; tok->token_type = NOT_A_TOKEN; tok->token_id = ILL_FORMED_CONSTANT; return 0; } else { fseek(openfile, filepos, SEEK_SET); tok->token_str[i++] = (char) 0; done = 1; } break; } if (i == 33 && tok->token_str[32]) { tok->token_str[33] = (char) 0; tok->token_type = NOT_A_TOKEN; tok->token_id = TOKEN_TOO_LONG; return 0; } } /* end of while loop. Now fill in the value */ tok->token_const.x = atof(tok->token_str); tok->token_type = REAL_CONSTANT; tok->token_id = 0; return 1; } void is_complex_constant(FILE * openfile, struct token_st * tok) { /* should test to make sure tok->token_str[0] == '(' */ struct token_st temp_tok; long filepos; int c; int sign_value = 1; int done = 0; int getting_real = 1; FILE * debug_token = NULL; tok->token_str[1] = (char) 0; /* so we can concatenate later */ filepos = ftell(openfile); if (debugflag == 96) { debug_token = fopen("frmconst.txt","at"); } while (!done) { switch (c = frmgetchar(openfile)) { CASE_NUM : case '.': if (debug_token != NULL) { fprintf(debug_token, "Set temp_tok.token_str[0] to %c\n", c); } temp_tok.token_str[0] = (char) c; break; case '-' : if (debug_token != NULL) { fprintf(debug_token, "First char is a minus\n"); } sign_value = -1; if ((c = frmgetchar(openfile)) == '.' || isdigit(c)) { if (debug_token != NULL) { fprintf(debug_token, "Set temp_tok.token_str[0] to %c\n", c); } temp_tok.token_str[0] = (char) c; } else { if (debug_token != NULL) { fprintf(debug_token, "First char not a . or NUM\n"); } done = 1; } break; default: if (debug_token != NULL) { fprintf(debug_token, "First char not a . or NUM\n"); } done = 1; break; } if (debug_token != NULL) { fprintf(debug_token, "Calling frmgetconstant unless done is 1; done is %d\n", done); } if (!done && frmgetconstant (openfile, &temp_tok)) { c = frmgetchar(openfile); if (debug_token != NULL) { fprintf(debug_token, "frmgetconstant returned 1; next token is %c\n", c); } if (getting_real && c == ',') { /*we have the real part now*/ if (sign_value == -1) { strcat(tok->token_str, "-"); } strcat(tok->token_str, temp_tok.token_str); strcat(tok->token_str, ","); tok->token_const.x = temp_tok.token_const.x * sign_value; getting_real = 0; sign_value = 1; } else if (!getting_real && c == ')') { /* we have the complex part */ if (sign_value == -1) { strcat(tok->token_str, "-"); } strcat(tok->token_str, temp_tok.token_str); strcat(tok->token_str, ")"); tok->token_const.y = temp_tok.token_const.x * sign_value; tok->token_type = tok->token_const.y ? COMPLEX_CONSTANT : REAL_CONSTANT; tok->token_id = 0; if (debug_token != NULL) { fprintf(debug_token, "Exiting with type set to %d\n", tok->token_const.y ? COMPLEX_CONSTANT : REAL_CONSTANT); fclose (debug_token); } return; } else done = 1; } else done = 1; } fseek (openfile, filepos, SEEK_SET); tok->token_str[1] = (char) 0; tok->token_const.y = tok->token_const.x = 0.0; tok->token_type = PARENS; tok->token_id = OPEN_PARENS; if (debug_token != NULL) { fprintf(debug_token, "Exiting with ID set to OPEN_PARENS\n"); fclose (debug_token); } return; } int frmgetalpha(FILE * openfile, struct token_st * tok) { int c; int i = 1; int var_name_too_long = 0; long filepos; long last_filepos = ftell(openfile); while ((c=frmgetchar(openfile)) != EOF && c != '\032') { filepos = ftell(openfile); switch (c) { CASE_ALPHA: CASE_NUM: case '_': if (i<79) tok->token_str[i++] = (char) c; else { tok->token_str[i] = (char) 0; } if(i == 33) { var_name_too_long=1; } last_filepos = filepos; break; default: if (c == '.') { /*illegal character in variable or func name*/ tok->token_type = NOT_A_TOKEN; tok->token_id = ILLEGAL_VARIABLE_NAME; tok->token_str[i++] = '.'; tok->token_str[i] = (char) 0; return 0; } else if (var_name_too_long) { tok->token_type = NOT_A_TOKEN; tok->token_id = TOKEN_TOO_LONG; tok->token_str[i] = (char) 0; fseek(openfile, last_filepos, SEEK_SET); return 0; } tok->token_str[i] = (char) 0; fseek(openfile, last_filepos, SEEK_SET); getfuncinfo(tok); if(c=='(') { /*getfuncinfo() correctly filled structure*/ if (tok->token_type == NOT_A_TOKEN) return 0; else if (tok->token_type == FLOW_CONTROL && (tok->token_id == 3 || tok->token_id == 4)) { tok->token_type = NOT_A_TOKEN; tok->token_id = JUMP_WITH_ILLEGAL_CHAR; return 0; } else return 1; } /*can't use function names as variables*/ else if(tok->token_type == FUNCTION || tok->token_type == PARAM_FUNCTION) { tok->token_type = NOT_A_TOKEN; tok->token_id = FUNC_USED_AS_VAR; return 0; } else if(tok->token_type == FLOW_CONTROL && (tok->token_id == 1 || tok->token_id == 2)) { tok->token_type = NOT_A_TOKEN; tok->token_id = JUMP_MISSING_BOOLEAN; return 0; } else if (tok->token_type == FLOW_CONTROL && (tok->token_id == 3 || tok->token_id == 4)) { if (c == ',' || c == '\n' || c == ':') return 1; else { tok->token_type = NOT_A_TOKEN; tok->token_id = JUMP_WITH_ILLEGAL_CHAR; return 0; } } else { getvarinfo(tok); return 1; } } } tok->token_str[0] = (char) 0; tok->token_type = NOT_A_TOKEN; tok->token_id = END_OF_FILE; return 0; } void frm_get_eos (FILE * openfile, struct token_st * this_token) { long last_filepos = ftell(openfile); int c; while ((c = frmgetchar(openfile)) == '\n' || c == ',' || c == ':') { if (c == ':') { this_token->token_str[0] = ':'; } last_filepos = ftell(openfile); } if (c == '}') { this_token->token_str[0] = '}'; this_token->token_type = END_OF_FORMULA; this_token->token_id = 0; } else { fseek (openfile, last_filepos, SEEK_SET); if (this_token->token_str[0] == '\n') { this_token->token_str[0] = ','; } } } /*frmgettoken fills token structure; returns 1 on success and 0 on NOT_A_TOKEN and END_OF_FORMULA */ int frmgettoken(FILE * openfile, struct token_st * this_token) { int c; int i=1; long filepos; switch (c = frmgetchar(openfile)) { CASE_NUM: case '.': this_token->token_str[0] = (char) c; return frmgetconstant(openfile, this_token); CASE_ALPHA: case '_': this_token->token_str[0] = (char) c; return frmgetalpha(openfile, this_token); CASE_TERMINATOR: this_token->token_type = OPERATOR; /* this may be changed below */ this_token->token_str[0] = (char) c; filepos = ftell(openfile); if(c=='<' || c=='>' || c=='=') { if((c=frmgetchar(openfile)) == '=') this_token->token_str[i++] = (char) c; else { fseek(openfile, filepos, SEEK_SET); } } else if(c=='!') { if((c=frmgetchar(openfile)) == '=') this_token->token_str[i++] = (char) c; else { fseek(openfile, filepos, SEEK_SET); this_token->token_str[1] = (char) 0; this_token->token_type = NOT_A_TOKEN; this_token->token_id = ILLEGAL_OPERATOR; return 0; } } else if(c=='|') { if((c=frmgetchar(openfile)) == '|') this_token->token_str[i++] = (char) c; else fseek(openfile, filepos, SEEK_SET); } else if (c=='&') { if((c=frmgetchar(openfile)) == '&') this_token->token_str[i++] = (char) c; else { fseek(openfile, filepos, SEEK_SET); this_token->token_str[1] = (char) 0; this_token->token_type = NOT_A_TOKEN; this_token->token_id = ILLEGAL_OPERATOR; return 0; } } else if(this_token->token_str[0] == '}') { this_token->token_type = END_OF_FORMULA; this_token->token_id = 0; } else if (this_token->token_str[0] == '\n' || this_token->token_str[0] == ',' || this_token->token_str[0] == ':' ) { frm_get_eos(openfile, this_token); } else if (this_token->token_str[0] == ')') { this_token->token_type = PARENS; this_token->token_id = CLOSE_PARENS; } else if (this_token->token_str[0] == '(') { /* the following function will set token_type to PARENS and token_id to OPEN_PARENS if this is not the start of a complex constant */ is_complex_constant(openfile, this_token); return 1; } this_token->token_str[i] = (char) 0; if(this_token->token_type == OPERATOR) { for(i=0; i < sizeof(OPList)/sizeof(struct OP_LIST); i++) { if(!far_strcmp(OPList[i].s, this_token->token_str)) { this_token->token_id = i; } } } return this_token->token_str[0] == '}' ? 0 : 1; case EOF: case '\032': this_token->token_str[0] = (char) 0; this_token->token_type = NOT_A_TOKEN; this_token->token_id = END_OF_FILE; return 0; default: this_token->token_str[0] = (char) c; this_token->token_str[1] = (char) 0; this_token->token_type = NOT_A_TOKEN; this_token->token_id = ILLEGAL_CHARACTER; return 0; } } int frm_get_param_stuff (char * Name) { FILE *debug_token = NULL; int c; struct token_st current_token; FILE * entry_file = NULL; uses_p1 = uses_p2 = uses_p3 = uses_ismand = maxfn = 0; uses_p4 = uses_p5 = 0; if (FormName[0] == 0 ) { return 0; /* and don't reset the pointers */ } if (find_file_item(FormFileName,Name,&entry_file, 1)) { stopmsg(0, ParseErrs(PE_COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED)); return 0; } while((c=frmgetchar(entry_file)) != '{' && c != EOF && c != '\032') {} if (c != '{') { stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); fclose(entry_file); return 0; } if(debugflag == 96) { if((debug_token = fopen("frmtokens.txt","at")) != NULL) fprintf(debug_token,"%s\n", Name); } while(frmgettoken(entry_file, ¤t_token)) { if (debug_token != NULL) { fprintf(debug_token,"%s\n", current_token.token_str); fprintf(debug_token,"token_type is %d\n", current_token.token_type); fprintf(debug_token,"token_id is %d\n", current_token.token_id); if (current_token.token_type == REAL_CONSTANT || current_token.token_type == COMPLEX_CONSTANT) { fprintf(debug_token,"Real value is %f\n", current_token.token_const.x); fprintf(debug_token,"Imag value is %f\n", current_token.token_const.y); } fprintf(debug_token,"\n"); } switch (current_token.token_type) { case PARAM_VARIABLE: if(current_token.token_id == 1) uses_p1 = 1; else if(current_token.token_id == 2) uses_p2 = 1; else if(current_token.token_id == 8) uses_p3 = 1; else if(current_token.token_id == 13) uses_ismand = 1; else if(current_token.token_id == 17) uses_p4 = 1; else if(current_token.token_id == 18) uses_p5 = 1; break; case PARAM_FUNCTION: if((current_token.token_id - 10) > maxfn) maxfn = (char) (current_token.token_id - 10); break; } } fclose(entry_file); if(debug_token) fclose(debug_token); if (current_token.token_type != END_OF_FORMULA) { uses_p1 = uses_p2 = uses_p3 = uses_ismand = maxfn = 0; uses_p4 = uses_p5 = 0; return 0; } return 1; } /* frm_check_name_and_sym(): error checking to the open brace on the first line; return 1 on success, 2 if an invalid symmetry is found, and 0 if errors are found which should cause the formula not to be executed */ int frm_check_name_and_sym (FILE * open_file, int from_prompts1c) { long filepos = ftell(open_file); int c, i, done, at_end_of_name; /* first, test name */ done = at_end_of_name = i = 0; while(!done) { switch (c = getc(open_file)) { case EOF: case '\032': stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); return 0; case '\r': case '\n': stopmsg(0,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); return 0; case ' ': case '\t': at_end_of_name = 1; break; case '(': case '[': case '{': done = 1; break; default : if (!at_end_of_name) i++; break; } } if(i > ITEMNAMELEN) { int j; int k = far_strlen(ParseErrs(PE_FORMULA_NAME_TOO_LARGE)); char msgbuf[100]; far_strcpy(msgbuf, ParseErrs(PE_FORMULA_NAME_TOO_LARGE)); strcat(msgbuf, ":\n "); fseek(open_file, filepos, SEEK_SET); for(j = 0; j < i && j < 25; j++) msgbuf[j+k+2] = (char) getc(open_file); msgbuf[j+k+2] = (char) 0; stopmsg(8, msgbuf); return 0; } /* get symmetry */ symmetry = 0; if (c == '(') { char sym_buf[20]; done = i = 0; while(!done) { switch (c = getc(open_file)) { case EOF: case '\032': stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); return 0; case '\r': case '\n': stopmsg(8,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); return 0; case '{': case '[': stopmsg(8,ParseErrs(PE_NO_MATCH_RIGHT_PAREN)); return 0; case ' ': case '\t': break; case ')': c = getc(open_file); /* get next character */ done = 1; break; default : if(i < 19) sym_buf[i++] = (char) toupper(c); break; } } sym_buf[i] = (char) 0; for(i = 0; SymStr[i].s[0]; i++) { if(!stricmp(SymStr[i].s, sym_buf)) { symmetry = SymStr[i].n; break; } } if(SymStr[i].s[0] == (char) 0 && from_prompts1c) { char far * msgbuf = (char far*) farmemalloc(far_strlen(ParseErrs(PE_INVALID_SYM_USING_NOSYM)) + strlen(sym_buf) + 6); far_strcpy(msgbuf, ParseErrs(PE_INVALID_SYM_USING_NOSYM)); far_strcat(msgbuf, ":\n "); far_strcat(msgbuf, sym_buf); stopmsg(8, msgbuf); farmemfree(msgbuf); } } if (from_prompts1c) { while(c == ' ') c = getc(open_file); /* eat spaces */ /* get preset per-image parameters */ if (c == '[') { char par_buf[30]; done = i = 0; while(!done) { switch (c = getc(open_file)) { case EOF: case '\032': stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); return 0; case '\r': case '\n': stopmsg(8,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); return 0; case '{': stopmsg(8,ParseErrs(PE_NO_MATCH_RIGHT_PAREN)); return 0; case ']': done = 1; /*fall through and set last parameter */ case ' ': case '\t': par_buf[i] = (char) 0; cmdarg(par_buf, 2); i = 0; break; default : if(i < 29) par_buf[i++] = (char) (c); break; } /* switch */ } /* while(!done) */ } /* if (c == '[') */ } /* if (from_prompts1c) */ if (c != '{') { done = 0; while(!done) { switch (c = getc(open_file)) { case EOF: case '\032': stopmsg(8,ParseErrs(PE_UNEXPECTED_EOF)); return 0; case '\r': case '\n': stopmsg(8,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); return 0; case '{': done = 1; break; default : break; } } } return 1; } static char *PrepareFormula(FILE * File, int from_prompts1c) { /* GGM 5-23-96: replaces FindFormula(). This function sets the symmetry and converts a formula into a string with no spaces, and one comma after each expression except where the ':' is placed and except the final expression in the formula. The open file passed as an argument is open in "rb" mode and is positioned at the first letter of the name of the formula to be prepared. This function is called from RunForm() below. */ FILE *debug_fp = NULL; char *FormulaStr; struct token_st temp_tok; int Done; long filepos = ftell(File); /* char debugmsg[500]; */ /*Test for a repeat*/ if (frm_check_name_and_sym(File, from_prompts1c) == 0) { fseek(File, filepos, SEEK_SET); return NULL; } if(!frm_prescan(File)) { fseek(File, filepos, SEEK_SET); return NULL; } if(chars_in_formula > 8190) { fseek(File, filepos, SEEK_SET); return NULL; } if(debugflag == 96) { if((debug_fp = fopen("debugfrm.txt","at")) != NULL) { fprintf(debug_fp,"%s\n",FormName); if(symmetry != 0) fprintf(debug_fp,"%s\n", SymStr[symmetry].s); } } FormulaStr = (char *)boxx; FormulaStr[0] = (char) 0; /* To permit concantenation later */ Done = 0; /*skip opening end-of-lines */ while(!Done) { frmgettoken(File, &temp_tok); if (temp_tok.token_type == NOT_A_TOKEN) { stopmsg(8, "Unexpected token error in PrepareFormula\n"); fseek(File, filepos, SEEK_SET); return NULL; } else if (temp_tok.token_type == END_OF_FORMULA) { stopmsg(8, "Formula has no executable instructions\n"); fseek(File, filepos, SEEK_SET); return NULL; } if (temp_tok.token_str[0] == ',') ; else { strcat(FormulaStr, temp_tok.token_str); Done = 1; } } Done = 0; while(!Done) { frmgettoken(File, &temp_tok); switch (temp_tok.token_type) { case NOT_A_TOKEN: stopmsg(8, "Unexpected token error in PrepareFormula\n"); fseek(File, filepos, SEEK_SET); return NULL; case END_OF_FORMULA: Done = 1; fseek(File, filepos, SEEK_SET); break; default: strcat(FormulaStr, temp_tok.token_str); break; } } if(debug_fp != NULL && FormulaStr != NULL) fprintf(debug_fp," %s\n",FormulaStr); if(debug_fp != NULL) fclose(debug_fp); /* sprintf(debugmsg, "Chars in formula per boxx is %u.\n", strlen(FormulaStr)); stopmsg(0, debugmsg); */ return FormulaStr; } int BadFormula(void) { /* moved from Parsera.Asm by CAE 12 July 1993 */ /* this is called when a formula is bad, instead of calling */ /* the normal functions which will produce undefined results */ return 1; } int RunForm(char *Name, int from_prompts1c) { /* returns 1 if an error occurred */ FILE * entry_file = NULL; /* CAE changed fn 12 July 1993 to fix problem when formula not found */ /* first set the pointers so they point to a fn which always returns 1 */ curfractalspecific->per_pixel = BadFormula; curfractalspecific->orbitcalc = BadFormula; if (FormName[0] == 0 ){ return 1; /* and don't reset the pointers */ } /* TW 5-31-94 add search for FRM files in directory */ if (find_file_item(FormFileName,Name,&entry_file, 1)) { stopmsg(0, ParseErrs(PE_COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED)); return 1; } FormStr = PrepareFormula(entry_file, from_prompts1c ); fclose(entry_file); if(FormStr) /* No errors while making string */ { parser_allocate(); /* ParseStr() will test if this alloc worked */ if (ParseStr(FormStr,1)) return 1; /* parse failed, don't change fn pointers */ else { if(uses_jump == 1 && fill_jump_struct() == 1) { stopmsg(0, ParseErrs(PE_ERROR_IN_PARSING_JUMP_STATEMENTS)); return 1; } /* all parses succeeded so set the pointers back to good functions*/ curfractalspecific->per_pixel = form_per_pixel; curfractalspecific->orbitcalc = Formula; return 0; } } else return 1; /* error in making string*/ } int fpFormulaSetup(void) { int RunFormRes; /* CAE fp */ #ifndef XFRACT if (fpu > 0) { MathType = D_MATH; /* CAE changed below for fp */ RunFormRes = !RunForm(FormName, 0); /* RunForm() returns 1 for failure */ if (RunFormRes && fpu >=387 && debugflag != 90 && (orbitsave&2) == 0 && !Randomized) return CvtStk(); /* run fast assembler code in parsera.asm */ return RunFormRes; } else { MathType = M_MATH; return !RunForm(FormName, 0); } #else MathType = D_MATH; RunFormRes = !RunForm(FormName, 0); /* RunForm() returns 1 for failure */ #if 0 if (RunFormRes && fpu == -1 && debugflag != 90 && (orbitsave&2) == 0 && !Randomized) return CvtStk(); /* run fast assembler code in parsera.asm */ #endif return RunFormRes; #endif } int intFormulaSetup(void) { #ifdef XFRACT printf("intFormulaSetup called!!!\n"); exit(-1); #else MathType = L_MATH; fg = (double)(1L << bitshift); fgLimit = (double)0x7fffffffL / fg; ShiftBack = 32 - bitshift; #endif return(!RunForm(FormName, 0)); } /* TIW added 06-20-90 so functions can be called from fractals.c */ void init_misc() { static struct ConstArg far vv[5]; static union Arg argfirst,argsecond; if(!v) v = vv; Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */ fg = (double)(1L << bitshift); fgLimit = (double)0x7fffffffL / fg; ShiftBack = 32 - bitshift; Delta16 = bitshift - 16; bitshiftless1 = bitshift-1; uses_p1 = uses_p2 = uses_p3 = uses_jump = uses_ismand = 0; uses_p4 = uses_p5 = 0; } /* PB 910417 here to end changed. Allocate sub-arrays from one main farmemalloc, using global variable typespecific_workarea; calcfrac.c releases this area when calculation ends or is terminated. Moved the "f" array to be allocated as part of this. */ long total_formula_mem; BYTE used_extra = 0; static void parser_allocate(void) { /* CAE fp changed below for v18 */ /* Note that XFRACT will waste about 6k here for pfls */ /* Somewhat more memory is now allocated than in v17 here */ /* however Store and Load were reduced in size to help make up for it */ long f_size,Store_size,Load_size,v_size, p_size; int pass, is_bad_form=0; long end_dx_array; /* TW Jan 1 1996 Made two passes to determine actual values of Max_Ops and Max_Args. Now use the end of extraseg if possible, so if less than 2048x2048 resolution is used, usually no farmemalloc calls are needed */ for(pass = 0; pass < 2; pass++) { free_workarea(); if(pass == 0) { Max_Ops = 2300; /* this value uses up about 64K memory */ Max_Args = (unsigned)(Max_Ops/2.5); } f_size = sizeof(void(far * far *)(void)) * Max_Ops; Store_size = sizeof(union Arg far *) * MAX_STORES; Load_size = sizeof(union Arg far *) * MAX_LOADS; v_size = sizeof(struct ConstArg) * Max_Args; p_size = sizeof(struct fls far *) * Max_Ops; total_formula_mem = f_size+Load_size+Store_size+v_size+p_size /*+ jump_size*/ + sizeof(struct PEND_OP) * Max_Ops; used_extra = 0; if(use_grid) end_dx_array = 2L*(long)(xdots+ydots)*sizeof(double); else end_dx_array = 0; if(pass == 0 || is_bad_form) { typespecific_workarea = (char far *)MK_FP(extraseg,0); used_extra = 1; } else if(1L<<16 > end_dx_array + total_formula_mem) { typespecific_workarea = (char far *)MK_FP(extraseg,0) + end_dx_array; used_extra = 1; } else if(is_bad_form == 0) { typespecific_workarea = (char far *)farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size)); used_extra = 0; } f = (void(far * far *)(void))typespecific_workarea; Store = (union Arg far * far *)(f + Max_Ops); Load = (union Arg far * far *)(Store + MAX_STORES); v = (struct ConstArg far *)(Load + MAX_LOADS); pfls = (struct fls far *)(v + Max_Args); if(pass == 0) { if((is_bad_form = ParseStr(FormStr,pass)) == 0) { /* per Chuck Ebbert, fudge these up a little */ Max_Ops = posp+4; Max_Args = vsp+4; } typespecific_workarea = NULL; } } uses_p1 = uses_p2 = uses_p3 = uses_p4 = uses_p5 = 0; } void free_workarea() { if(typespecific_workarea && used_extra == 0) { farmemfree(typespecific_workarea); } typespecific_workarea = NULL; Store = (union Arg far * far *)0; Load = (union Arg far * far *)0; v = (struct ConstArg far *)0; f = (void(far * far *)(void))0; /* CAE fp */ pfls = (struct fls far * )0; /* CAE fp */ total_formula_mem = 0; /* restore extraseg */ if(integerfractal && !invert) fill_lx_array(); else fill_dx_array(); } struct error_data_st { long start_pos; long error_pos; int error_number; } errors[3]; void frm_error(FILE * open_file, long begin_frm) { struct token_st tok; /* char debugmsg[500]; */ int i, chars_to_error=0, chars_in_error=0, token_count; int statement_len, line_number; int done; char msgbuf[900]; long filepos; int j; int initialization_error; strcpy (msgbuf, "\n"); for(j=0; j < 3 && errors[j].start_pos; j++) { initialization_error = errors[j].error_number == PE_SECOND_COLON ? 1 : 0; fseek(open_file, begin_frm, SEEK_SET); line_number = 1; while (ftell(open_file) != errors[j].error_pos) { if((i = fgetc(open_file)) == '\n') { line_number++; } else if (i == EOF || i == '}') { stopmsg(0, "Unexpected EOF or end-of-formula in error function.\n"); fseek (open_file, errors[j].error_pos, SEEK_SET); frmgettoken(open_file, &tok); /*reset file to end of error token */ return; } } #ifndef XFRACT sprintf(&msgbuf[strlen(msgbuf)], "Error(%d) at line %d: %Fs\n ", errors[j].error_number, line_number, ParseErrs(errors[j].error_number)); #else sprintf(&msgbuf[strlen(msgbuf)], "Error(%d) at line %d: %s\n ", errors[j].error_number, line_number, ParseErrs(errors[j].error_number)); #endif i = strlen(msgbuf); /* sprintf(debugmsg, "msgbuf is: %s\n and i is %d\n", msgbuf, i); stopmsg (0, debugmsg); */ fseek(open_file, errors[j].start_pos, SEEK_SET); statement_len = token_count = 0; done = 0; while(!done) { filepos = ftell (open_file); if(filepos == errors[j].error_pos) { /* stopmsg(0, "About to get error token\n"); */ chars_to_error = statement_len; frmgettoken(open_file, &tok); chars_in_error = strlen(tok.token_str); statement_len += chars_in_error; token_count++; /* sprintf(debugmsg, "Error is %s\nChars in error is %d\nChars to error is %d\n", tok.token_str, chars_in_error, chars_to_error); stopmsg (0, debugmsg); */ } else { frmgettoken(open_file, &tok); /* sprintf(debugmsg, "Just got %s\n", tok.token_str); stopmsg (0, debugmsg); */ statement_len += strlen(tok.token_str); token_count++; } if ((tok.token_type == END_OF_FORMULA) || (tok.token_type == OPERATOR && (tok.token_id == 0 || tok.token_id == 11)) || (tok.token_type == NOT_A_TOKEN && tok.token_id == END_OF_FILE)){ done = 1; if (token_count > 1 && !initialization_error) { token_count--; } } } fseek(open_file, errors[j].start_pos, SEEK_SET); if(chars_in_error < 74) { while (chars_to_error + chars_in_error > 74) { /* stopmsg(0, "chars in error less than 74, but late in line"); */ frmgettoken(open_file, &tok); chars_to_error -= strlen(tok.token_str); token_count--; } } else { fseek(open_file, errors[j].error_pos, SEEK_SET); chars_to_error = 0; token_count = 1; } /* stopmsg(0, "Back to beginning of statement to build msgbuf"); */ while (strlen(&msgbuf[i]) <=74 && token_count--) { frmgettoken (open_file, &tok); strcat (msgbuf, tok.token_str); /* stopmsg(0, &msgbuf[i]); */ } fseek (open_file, errors[j].error_pos, SEEK_SET); frmgettoken (open_file, &tok); if (strlen(&msgbuf[i]) > 74) msgbuf[i + 74] = (char) 0; strcat(msgbuf, "\n"); i = strlen(msgbuf); while (chars_to_error-- > -2) strcat (msgbuf, " "); /* sprintf(debugmsg, "Going into final line, chars in error is %d", chars_in_error); stopmsg(0, debugmsg); */ if(errors[j].error_number == PE_TOKEN_TOO_LONG) { chars_in_error = 33; } while (chars_in_error-- && strlen(&msgbuf[i]) <=74) strcat (msgbuf, "^"); strcat (msgbuf, "\n"); } stopmsg (8, msgbuf); return; } void display_var_list() { struct var_list_st far * p; stopmsg(0, "List of user defined variables:\n"); for (p = var_list; p; p=p->next_item) { stopmsg(0, p->name); } } void display_const_lists() { struct const_list_st far * p; char msgbuf[800]; stopmsg (0, "Complex constants are:"); for (p = complx_list; p; p=p->next_item) { sprintf(msgbuf, "%f, %f\n", p->complex_const.x, p->complex_const.y); stopmsg(0, msgbuf); } stopmsg (0, "Real constants are:"); for (p = real_list; p; p=p->next_item) { sprintf(msgbuf, "%f, %f\n", p->complex_const.x, p->complex_const.y); stopmsg(0, msgbuf); } } struct var_list_st far *var_list_alloc() { return (struct var_list_st far*) farmemalloc(sizeof(struct var_list_st)); } struct const_list_st far *const_list_alloc() { return (struct const_list_st far *) farmemalloc(sizeof(struct const_list_st)); } void init_var_list() { struct var_list_st far * temp, far * p; for (p = var_list; p; p=temp) { temp = p->next_item; farmemfree(p); } var_list = NULL; } void init_const_lists() { struct const_list_st far * temp, far * p; for (p = complx_list; p; p=temp) { temp = p->next_item; farmemfree(p); } complx_list = NULL; for (p = real_list; p; p=temp) { temp = p->next_item; farmemfree(p); } real_list = NULL; } struct var_list_st far * add_var_to_list (struct var_list_st far * p, struct token_st tok) { if (p == NULL) { if ((p = var_list_alloc()) == NULL) return NULL; far_strcpy(p->name, tok.token_str); p->next_item = NULL; } else if (far_strcmp(p->name, tok.token_str) == 0) { } else { if ((p->next_item = add_var_to_list(p->next_item, tok)) == NULL) return NULL; } return p; } struct const_list_st far * add_const_to_list (struct const_list_st far * p, struct token_st tok) { if (p == NULL) { if ((p = const_list_alloc()) == NULL) return NULL; p->complex_const.x = tok.token_const.x; p->complex_const.y = tok.token_const.y; p->next_item = NULL; } else if (p->complex_const.x == tok.token_const.x && p->complex_const.y == tok.token_const.y) { } else if ((p->next_item = add_const_to_list(p->next_item, tok)) == NULL) return NULL; return p; } void count_lists() { /* char msgbuf[800]; */ struct var_list_st far * p; struct const_list_st far * q; var_count = 0; complx_count = 0; real_count = 0; for (p = var_list; p; p=p->next_item) { var_count++; } for (q = complx_list; q; q=q->next_item) { complx_count++; } for (q = real_list; q; q=q->next_item) { real_count++; } /* sprintf(msgbuf, "Number of vars is %d\nNumber of complx is %d\nNumber of real is %d\n", var_count, complx_count, real_count); stopmsg(0, msgbuf); */ } /*frm_prescan() takes an open file with the file pointer positioned at the beginning of the relevant formula, and parses the formula, token by token, for syntax errors. The function also accumulates data for memory allocation to be done later. The function returns 1 if success, and 0 if errors are found. */ int disable_fastparser; int must_use_float; int frm_prescan (FILE * open_file) { long filepos; int i; long statement_pos, orig_pos; int done = 0; struct token_st this_token; int errors_found = 0; int ExpectingArg = 1; int NewStatement = 1; int assignment_ok = 1; int already_got_colon = 0; unsigned long else_has_been_used = 0; unsigned long waiting_for_mod = 0; int waiting_for_endif = 0; int max_parens = sizeof(long) * 8; /* char debugmsg[800]; stopmsg (0, "Entering prescan"); */ disable_fastparser = 0; must_use_float = 0; number_of_ops = number_of_loads = number_of_stores = number_of_jumps = (unsigned) 0L; chars_in_formula = (unsigned) 0; uses_jump = (short) 0; paren = 0; init_var_list(); init_const_lists(); orig_pos = statement_pos = ftell(open_file); for (i = 0; i < 3; i++) { errors[i].start_pos = 0L; errors[i].error_pos = 0L; errors[i].error_number = 0; } while (!done) { /* char msgbuf[80] = "Just got "; */ filepos = ftell (open_file); frmgettoken (open_file, &this_token); /* strcat(msgbuf, this_token.token_str); stopmsg (0, msgbuf); sprintf (debugmsg, "Errors structure\n0: %ld, %ld, %d\n1: %ld, %ld, %d\n2: %ld, %ld, %d\n\n", errors[0].start_pos, errors[0].error_pos, errors[0].error_number, errors[1].start_pos, errors[1].error_pos, errors[1].error_number, errors[2].start_pos, errors[2].error_pos, errors[2].error_number); stopmsg (0, debugmsg); */ chars_in_formula += strlen(this_token.token_str); switch (this_token.token_type) { case NOT_A_TOKEN: assignment_ok = 0; switch (this_token.token_id) { case END_OF_FILE: stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); fseek(open_file, orig_pos, SEEK_SET); return 0; case ILLEGAL_CHARACTER: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_ILLEGAL_CHAR; } break; case ILLEGAL_VARIABLE_NAME: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_ILLEGAL_VAR_NAME; } break; case TOKEN_TOO_LONG: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_TOKEN_TOO_LONG; } break; case FUNC_USED_AS_VAR: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_FUNC_USED_AS_VAR; } break; case JUMP_MISSING_BOOLEAN: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_JUMP_NEEDS_BOOLEAN; } break; case JUMP_WITH_ILLEGAL_CHAR: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_NO_CHAR_AFTER_THIS_JUMP; } break; case UNDEFINED_FUNCTION: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_UNDEFINED_FUNCTION; } break; case ILLEGAL_OPERATOR: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_UNDEFINED_OPERATOR; } break; case ILL_FORMED_CONSTANT: if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_INVALID_CONST; } break; default: stopmsg(0, "Unexpected arrival at default case in prescan()"); fseek(open_file, orig_pos, SEEK_SET); return 0; } break; case PARENS: assignment_ok = 0; NewStatement = 0; switch (this_token.token_id) { case OPEN_PARENS: if(++paren > max_parens) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_NESTING_TO_DEEP; } } else if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } waiting_for_mod = waiting_for_mod << 1; break; case CLOSE_PARENS: if(paren) { paren--; } else { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_NEED_A_MATCHING_OPEN_PARENS; } paren = 0; } if (waiting_for_mod & 1L) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_UNMATCHED_MODULUS; } } else { waiting_for_mod = waiting_for_mod >> 1; } if (ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } break; default: break; } break; case PARAM_VARIABLE: /*i.e. p1, p2, p3, p4 or p5*/ number_of_ops++; number_of_loads++; NewStatement = 0; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } switch (this_token.token_id) { case 1: break; case 2: break; case 8: break; case 17: break; case 18: break; default: break; } ExpectingArg = 0; break; case USER_NAMED_VARIABLE: /* i.e. c, iter, etc. */ number_of_ops++; number_of_loads++; NewStatement = 0; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } ExpectingArg = 0; /* if ((var_list = add_var_to_list (var_list, this_token)) == NULL) { stopmsg(0, ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); fseek(open_file, orig_pos, SEEK_SET); init_var_list(); init_const_lists(); return 0; } */ break; case PREDEFINED_VARIABLE: /* i.e. z, pixel, whitesq, etc. */ number_of_ops++; number_of_loads++; NewStatement = 0; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } switch (this_token.token_id) { case 0: /* pixel */ break; case 3: /* z */ break; case 4: /* LastSqr */ break; case 5: /* pi */ break; case 6: /* e */ break; case 7: /* rand */ break; case 9: /* whitesq */ break; case 10: /* scrnpix */ break; case 11: /* scrnmax */ break; case 12: /* maxit */ break; case 13: /* ismand */ break; default: break; } ExpectingArg = 0; break; case REAL_CONSTANT: /* i.e. 4, (4,0), etc.) */ assignment_ok = 0; number_of_ops++; number_of_loads++; NewStatement = 0; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } ExpectingArg = 0; /* if ((real_list = add_const_to_list (real_list, this_token)) == NULL) { stopmsg(0, ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); fseek(open_file, orig_pos, SEEK_SET); init_var_list(); init_const_lists(); return 0; } */ break; case COMPLEX_CONSTANT: /* i.e. (1,2) etc. */ assignment_ok = 0; number_of_ops++; number_of_loads++; NewStatement = 0; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } ExpectingArg = 0; /* if ((complx_list = add_const_to_list (complx_list, this_token)) == NULL) { stopmsg(0, ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); fseek(open_file, orig_pos, SEEK_SET); init_var_list(); init_const_lists(); return 0; } */ break; case FUNCTION: assignment_ok = 0; NewStatement = 0; number_of_ops++; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } switch (this_token.token_id) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break; case 10: break; case 15: break; case 16: break; case 17: break; case 18: break; case 19: break; case 20: break; case 21: break; case 22: break; case 23: break; case 24: break; case 25: break; case 26: break; case 27: break; case 28: break; case 29: break; case 30: break; case 31: break; case 32: break; case 33: break; case 34: break; default: break; } break; case PARAM_FUNCTION: assignment_ok = 0; NewStatement = 0; number_of_ops++; if(!ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } switch (this_token.token_id) { case 11: break; case 12: break; case 13: break; case 14: break; default: break; } NewStatement = 0; break; case FLOW_CONTROL: assignment_ok = 0; number_of_ops++; number_of_jumps++; if(!NewStatement) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_JUMP_NOT_FIRST; } } else { uses_jump = 1; switch (this_token.token_id) { case 1: /* if */ else_has_been_used = else_has_been_used << 1; waiting_for_endif++; break; case 2: /*ELSEIF*/ number_of_ops += 3; /*else + two clear statements*/ number_of_jumps++; /* this involves two jumps */ if (else_has_been_used % 2) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_ENDIF_REQUIRED_AFTER_ELSE; } } else if (!waiting_for_endif) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_MISPLACED_ELSE_OR_ELSEIF; } } break; case 3: /*ELSE*/ if (else_has_been_used % 2) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_ENDIF_REQUIRED_AFTER_ELSE; } } else if (!waiting_for_endif) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_MISPLACED_ELSE_OR_ELSEIF; } } else_has_been_used = else_has_been_used | 1; break; case 4: /*ENDIF*/ else_has_been_used = else_has_been_used >> 1; waiting_for_endif--; if(waiting_for_endif < 0) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_ENDIF_WITH_NO_IF; } waiting_for_endif = 0; } break; default: break; } } break; case OPERATOR: number_of_ops++; /*This will be corrected below in certain cases*/ switch (this_token.token_id) { case 0: case 11: /* end of statement and : */ number_of_ops++; /* ParseStr inserts a dummy op*/ if (paren) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_NEED_MORE_CLOSE_PARENS; } paren = 0; } if (waiting_for_mod) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_UNMATCHED_MODULUS; } waiting_for_mod = 0; } if (!ExpectingArg) { if (this_token.token_id == 11) number_of_ops += 2; else number_of_ops++; } else if (!NewStatement) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } if (this_token.token_id == 11 && waiting_for_endif) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_UNMATCHED_IF_IN_INIT_SECTION; } waiting_for_endif = 0; } if (this_token.token_id == 11 && already_got_colon) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SECOND_COLON; } } if (this_token.token_id == 11) already_got_colon = 1; NewStatement = ExpectingArg = assignment_ok = 1; statement_pos = ftell(open_file); break; case 1: /* != */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 2: /* = */ number_of_ops--; /*this just converts a load to a store*/ number_of_loads--; number_of_stores++; if(!assignment_ok) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_ILLEGAL_ASSIGNMENT; } } ExpectingArg = 1; break; case 3: /* == */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 4: /* < */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 5: /* <= */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 6: /* > */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 7: /* >= */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 8: /* | */ /* (half of the modulus operator */ assignment_ok = 0; if(!waiting_for_mod & 1L) { number_of_ops--; } if(!(waiting_for_mod & 1L) && !ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; } } else if ((waiting_for_mod & 1L) && ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } waiting_for_mod = waiting_for_mod ^ 1L; /*switch right bit*/ break; case 9: /* || */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 10: /* && */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 12: /* + */ /* case 11 (":") is up with case 0 */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 13: /* - */ assignment_ok = 0; ExpectingArg = 1; break; case 14: /* * */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 15: /* / */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } ExpectingArg = 1; break; case 16: /* ^ */ assignment_ok = 0; if(ExpectingArg) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } } filepos = ftell(open_file); frmgettoken (open_file, &this_token); if (this_token.token_str[0] == '-') { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_NO_NEG_AFTER_EXPONENT; } } else fseek(open_file, filepos, SEEK_SET); ExpectingArg = 1; break; default: break; } break; case END_OF_FORMULA: number_of_ops+= 3; /* Just need one, but a couple of extra just for the heck of it */ if (paren) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_NEED_MORE_CLOSE_PARENS; } paren = 0; } if (waiting_for_mod) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_UNMATCHED_MODULUS; } waiting_for_mod = 0; } if (waiting_for_endif) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_IF_WITH_NO_ENDIF; } waiting_for_endif = 0; } if (ExpectingArg && !NewStatement) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; } statement_pos = ftell(open_file); } if (number_of_jumps >= MAX_JUMPS) { if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { errors[errors_found].start_pos = statement_pos; errors[errors_found].error_pos = filepos; errors[errors_found++].error_number = PE_TOO_MANY_JUMPS; } } done = 1; break; default: break; } if (errors_found == 3) done = 1; } if(errors[0].start_pos) { /* sprintf (debugmsg, "Errors structure on entering frm_error\n 0: %ld, %ld, %d\n1: %ld, %ld, %d\n2: %ld, %ld, %d\n\n", errors[0].start_pos, errors[0].error_pos, errors[0].error_number, errors[1].start_pos, errors[1].error_pos, errors[1].error_number, errors[2].start_pos, errors[2].error_pos, errors[2].error_number); stopmsg (0, debugmsg); */ frm_error(open_file, orig_pos); fseek(open_file, orig_pos, SEEK_SET); return 0; } fseek(open_file, orig_pos, SEEK_SET); /* display_var_list(); display_const_lists(); */ count_lists(); /* sprintf(debugmsg, "Chars in formula per prescan() is %u.\n", chars_in_formula); stopmsg(0, debugmsg); */ return 1; } xfractint-20.4.10.orig/common/zoom.c0000644000000000000000000006656310150633601014140 0ustar /* zoom.c - routines for zoombox manipulation and for panning */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #define PIXELROUND 0.00001 static void _fastcall zmo_calc(double, double, double *, double *, double); static void _fastcall zmo_calcbf(bf_t,bf_t,bf_t,bf_t,bf_t,bf_t,bf_t,bf_t,bf_t); static int check_pan(void); static void fix_worklist(void); static void _fastcall move_row(int fromrow,int torow,int col); /* big number declarations */ void calc_corner(bf_t target,bf_t p1,double p2,bf_t p3,double p4,bf_t p5) { bf_t btmp1, btmp2 ,btmp3; int saved; saved = save_stack(); btmp1 = alloc_stack(rbflength+2); btmp2 = alloc_stack(rbflength+2); btmp3 = alloc_stack(rbflength+2); /* use target as temporary variable */ floattobf(btmp3, p2); mult_bf(btmp1,btmp3,p3); mult_bf(btmp2,floattobf(target, p4),p5); add_bf(target,btmp1,btmp2); add_a_bf(target,p1); restore_stack(saved); } int boxcolor; #ifndef XFRACT void dispbox(void) { int i; int boxc = (colors-1)&boxcolor; unsigned char *values = (unsigned char *)boxvalues; int rgb[3]; xorTARGA = 1; for(i=0;i abs(to.y-fr.y)) { /* delta.x > delta.y */ if (fr.x>to.x) { /* swap so from.x is < to.x */ tmpp = fr; fr = to; to = tmpp; } xincr = (to.x-fr.x)*4/sxdots+1; /* do every 1st, 2nd, 3rd, or 4th dot */ ctr = (to.x-fr.x-1)/xincr; altdec = abs(to.y-fr.y)*xincr; altinc = to.x-fr.x; altctr = altinc/2; yincr = (to.y>fr.y)?1:-1; line2.x = (line1.x = fr.x) + dx; line2.y = (line1.y = fr.y) + dy; while (--ctr>=0) { line1.x += xincr; line2.x += xincr; altctr -= altdec; while (altctr<0) { altctr += altinc; line1.y += yincr; line2.y += yincr; } addbox(line1); addbox(line2); } } else { /* delta.y > delta.x */ if (fr.y>to.y) { /* swap so from.y is < to.y */ tmpp = fr; fr = to; to = tmpp; } yincr = (to.y-fr.y)*4/sydots+1; /* do every 1st, 2nd, 3rd, or 4th dot */ ctr = (to.y-fr.y-1)/yincr; altdec = abs(to.x-fr.x)*yincr; altinc = to.y-fr.y; altctr = altinc/2; xincr = (to.x>fr.x) ? 1 : -1; line2.x = (line1.x = fr.x) + dx; line2.y = (line1.y = fr.y) + dy; while (--ctr>=0) { line1.y += yincr; line2.y += yincr; altctr -= altdec; while (altctr<0) { altctr += altinc; line1.x += xincr; line2.x += xincr; } addbox(line1); addbox(line2); } } } void _fastcall addbox(struct coords point) { point.x += sxoffs; point.y += syoffs; if (point.x >= 0 && point.x < sxdots && point.y >= 0 && point.y < sydots) { boxx[boxcount] = point.x; boxy[boxcount] = point.y; ++boxcount; } } void moveboxf(double dx, double dy) { int align,row,col; align = check_pan(); if (dx!=0.0) { if ((zbx += dx) + zwidth/2 < 0) /* center must stay onscreen */ zbx = zwidth/-2; if (zbx + zwidth/2 > 1) zbx = 1.0 - zwidth/2; if (align != 0 && ((col = (int)(zbx*(dxsize+PIXELROUND))) & (align-1)) != 0) { if (dx > 0) col += align; col -= col & (align-1); /* adjust col to pass alignment */ zbx = (double)col/dxsize; } } if (dy!=0.0) { if ((zby += dy) + zdepth/2 < 0) zby = zdepth/-2; if (zby + zdepth/2 > 1) zby = 1.0 - zdepth/2; if (align != 0 && ((row = (int)(zby*(dysize+PIXELROUND))) & (align-1)) != 0) { if (dy > 0) row += align; row -= row & (align-1); zby = (double)row/dysize; } } #ifndef XFRACT if (video_scroll != 0) { /* scroll screen center to the box center */ col = (int)((zbx + zwidth/2)*(dxsize + PIXELROUND)) + sxoffs; row = (int)((zby + zdepth/2)*(dysize + PIXELROUND)) + syoffs; switch (zscroll) { case 0: /* fixed - screen center fixed to the zoombox center */ scroll_center(col,row); break; case 1: /* relaxed - as the zoombox center leaves the screen */ if ((col -= video_startx) > 0 && (col -= vesa_xres - 1) < 0) col = 0; if ((row -= video_starty) > 0 && (row -= vesa_yres - 1) < 0) row = 0; if (col != 0 || row != 0) scroll_relative(col, row); break; } } #endif } static void _fastcall chgboxf(double dwidth, double ddepth) { if (zwidth+dwidth > 1) dwidth = 1.0-zwidth; if (zwidth+dwidth < 0.05) dwidth = 0.05-zwidth; zwidth += dwidth; if (zdepth+ddepth > 1) ddepth = 1.0-zdepth; if (zdepth+ddepth < 0.05) ddepth = 0.05-zdepth; zdepth += ddepth; moveboxf(dwidth/-2,ddepth/-2); /* keep it centered & check limits */ } void resizebox(int steps) { double deltax,deltay; if (zdepth*screenaspect > zwidth) { /* box larger on y axis */ deltay = steps * 0.036 / screenaspect; deltax = zwidth * deltay / zdepth; } else { /* box larger on x axis */ deltax = steps * 0.036; deltay = zdepth * deltax / zwidth; } chgboxf(deltax,deltay); } void chgboxi(int dw, int dd) { /* change size by pixels */ chgboxf( (double)dw/dxsize, (double)dd/dysize ); } #ifdef C6 #pragma optimize("e",off) /* MSC 6.00A messes up next rtn with "e" on */ #endif extern void show_three_bf(); static void _fastcall zmo_calcbf(bf_t bfdx, bf_t bfdy, bf_t bfnewx, bf_t bfnewy,bf_t bfplotmx1, bf_t bfplotmx2, bf_t bfplotmy1, bf_t bfplotmy2, bf_t bfftemp) { bf_t btmp1, btmp2, btmp3, btmp4, btempx, btempy ; bf_t btmp2a, btmp4a; int saved; saved = save_stack(); btmp1 = alloc_stack(rbflength+2); btmp2 = alloc_stack(rbflength+2); btmp3 = alloc_stack(rbflength+2); btmp4 = alloc_stack(rbflength+2); btmp2a = alloc_stack(rbflength+2); btmp4a = alloc_stack(rbflength+2); btempx = alloc_stack(rbflength+2); btempy = alloc_stack(rbflength+2); /* calc cur screen corner relative to zoombox, when zoombox co-ords are taken as (0,0) topleft thru (1,1) bottom right */ /* tempx = dy * plotmx1 - dx * plotmx2; */ mult_bf(btmp1,bfdy,bfplotmx1); mult_bf(btmp2,bfdx,bfplotmx2); sub_bf(btempx,btmp1,btmp2); /* tempy = dx * plotmy1 - dy * plotmy2; */ mult_bf(btmp1,bfdx,bfplotmy1); mult_bf(btmp2,bfdy,bfplotmy2); sub_bf(btempy,btmp1,btmp2); /* calc new corner by extending from current screen corners */ /* *newx = sxmin + tempx*(sxmax-sx3rd)/ftemp + tempy*(sx3rd-sxmin)/ftemp; */ sub_bf(btmp1,bfsxmax,bfsx3rd); mult_bf(btmp2,btempx,btmp1); /* show_three_bf("fact1",btempx,"fact2",btmp1,"prod ",btmp2,70); */ div_bf(btmp2a,btmp2,bfftemp); /* show_three_bf("num ",btmp2,"denom",bfftemp,"quot ",btmp2a,70); */ sub_bf(btmp3,bfsx3rd,bfsxmin); mult_bf(btmp4,btempy,btmp3); div_bf(btmp4a,btmp4,bfftemp); add_bf(bfnewx,bfsxmin,btmp2a); add_a_bf(bfnewx,btmp4a); /* *newy = symax + tempy*(sy3rd-symax)/ftemp + tempx*(symin-sy3rd)/ftemp; */ sub_bf(btmp1,bfsy3rd,bfsymax); mult_bf(btmp2,btempy,btmp1); div_bf(btmp2a,btmp2,bfftemp); sub_bf(btmp3,bfsymin,bfsy3rd); mult_bf(btmp4,btempx,btmp3); div_bf(btmp4a,btmp4,bfftemp); add_bf(bfnewy,bfsymax,btmp2a); add_a_bf(bfnewy,btmp4a); restore_stack(saved); } static void _fastcall zmo_calc(double dx, double dy, double *newx, double *newy, double ftemp) { double tempx,tempy; /* calc cur screen corner relative to zoombox, when zoombox co-ords are taken as (0,0) topleft thru (1,1) bottom right */ tempx = dy * plotmx1 - dx * plotmx2; tempy = dx * plotmy1 - dy * plotmy2; /* calc new corner by extending from current screen corners */ *newx = sxmin + tempx*(sxmax-sx3rd)/ftemp + tempy*(sx3rd-sxmin)/ftemp; *newy = symax + tempy*(sy3rd-symax)/ftemp + tempx*(symin-sy3rd)/ftemp; } void zoomoutbf(void) /* for ctl-enter, calc corners for zooming out */ { /* (xxmin,yymax), etc, are already set to zoombox corners; (sxmin,symax), etc, are still the screen's corners; use the same logic as plot_orbit stuff to first calculate current screen corners relative to the zoombox, as if the zoombox were a square with upper left (0,0) and width/depth 1; ie calc the current screen corners as if plotting them from the zoombox; then extend these co-ords from current real screen corners to get new actual corners */ bf_t savbfxmin,savbfymax,bfftemp; bf_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6,bfplotmx1,bfplotmx2,bfplotmy1,bfplotmy2; int saved; saved = save_stack(); savbfxmin = alloc_stack(rbflength+2); savbfymax = alloc_stack(rbflength+2); bfftemp = alloc_stack(rbflength+2); tmp1 = alloc_stack(rbflength+2); tmp2 = alloc_stack(rbflength+2); tmp3 = alloc_stack(rbflength+2); tmp4 = alloc_stack(rbflength+2); tmp5 = alloc_stack(rbflength+2); tmp6 = alloc_stack(rbflength+2); bfplotmx1 = alloc_stack(rbflength+2); bfplotmx2 = alloc_stack(rbflength+2); bfplotmy1 = alloc_stack(rbflength+2); bfplotmy2 = alloc_stack(rbflength+2); /* ftemp = (yymin-yy3rd)*(xx3rd-xxmin) - (xxmax-xx3rd)*(yy3rd-yymax); */ sub_bf(tmp1,bfymin,bfy3rd); sub_bf(tmp2,bfx3rd,bfxmin); sub_bf(tmp3,bfxmax,bfx3rd); sub_bf(tmp4,bfy3rd,bfymax); mult_bf(tmp5,tmp1,tmp2); mult_bf(tmp6,tmp3,tmp4); sub_bf(bfftemp,tmp5,tmp6); /* plotmx1 = (xx3rd-xxmin); */ ; /* reuse the plotxxx vars is safe */ copy_bf(bfplotmx1,tmp2); /* plotmx2 = (yy3rd-yymax); */ copy_bf(bfplotmx2,tmp4); /* plotmy1 = (yymin-yy3rd); */ copy_bf(bfplotmy1,tmp1); /* plotmy2 = (xxmax-xx3rd); */; copy_bf(bfplotmy2,tmp3); /* savxxmin = xxmin; savyymax = yymax; */ copy_bf(savbfxmin,bfxmin); copy_bf(savbfymax,bfymax); sub_bf(tmp1,bfsxmin,savbfxmin); sub_bf(tmp2,bfsymax,savbfymax); zmo_calcbf(tmp1,tmp2,bfxmin,bfymax,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); sub_bf(tmp1,bfsxmax,savbfxmin); sub_bf(tmp2,bfsymin,savbfymax); zmo_calcbf(tmp1,tmp2,bfxmax,bfymin,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); sub_bf(tmp1,bfsx3rd,savbfxmin); sub_bf(tmp2,bfsy3rd,savbfymax); zmo_calcbf(tmp1,tmp2,bfx3rd,bfy3rd,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); restore_stack(saved); } void zoomoutdbl(void) /* for ctl-enter, calc corners for zooming out */ { /* (xxmin,yymax), etc, are already set to zoombox corners; (sxmin,symax), etc, are still the screen's corners; use the same logic as plot_orbit stuff to first calculate current screen corners relative to the zoombox, as if the zoombox were a square with upper left (0,0) and width/depth 1; ie calc the current screen corners as if plotting them from the zoombox; then extend these co-ords from current real screen corners to get new actual corners */ double savxxmin,savyymax,ftemp; ftemp = (yymin-yy3rd)*(xx3rd-xxmin) - (xxmax-xx3rd)*(yy3rd-yymax); plotmx1 = (xx3rd-xxmin); /* reuse the plotxxx vars is safe */ plotmx2 = (yy3rd-yymax); plotmy1 = (yymin-yy3rd); plotmy2 = (xxmax-xx3rd); savxxmin = xxmin; savyymax = yymax; zmo_calc(sxmin-savxxmin,symax-savyymax,&xxmin,&yymax,ftemp); zmo_calc(sxmax-savxxmin,symin-savyymax,&xxmax,&yymin,ftemp); zmo_calc(sx3rd-savxxmin,sy3rd-savyymax,&xx3rd,&yy3rd,ftemp); } void zoomout(void) /* for ctl-enter, calc corners for zooming out */ { if(bf_math) { zoomoutbf(); } else zoomoutdbl(); } #ifdef C6 #pragma optimize("e",on) /* back to normal */ #endif void aspectratio_crop(float oldaspect,float newaspect) { double ftemp,xmargin,ymargin; if (newaspect > oldaspect) { /* new ratio is taller, crop x */ ftemp = (1.0 - oldaspect / newaspect) / 2; xmargin = (xxmax - xx3rd) * ftemp; ymargin = (yymin - yy3rd) * ftemp; xx3rd += xmargin; yy3rd += ymargin; } else { /* new ratio is wider, crop y */ ftemp = (1.0 - newaspect / oldaspect) / 2; xmargin = (xx3rd - xxmin) * ftemp; ymargin = (yy3rd - yymax) * ftemp; xx3rd -= xmargin; yy3rd -= ymargin; } xxmin += xmargin; yymax += ymargin; xxmax -= xmargin; yymin -= ymargin; } static int check_pan(void) /* return 0 if can't, alignment requirement if can */ { int i,j; if ((calc_status != 2 && calc_status != 4) || evolving) return(0); /* not resumable, not complete */ if ( curfractalspecific->calctype != StandardFractal && curfractalspecific->calctype != calcmand && curfractalspecific->calctype != calcmandfp && curfractalspecific->calctype != lyapunov && curfractalspecific->calctype != calcfroth) return(0); /* not a worklist-driven type */ if (zwidth != 1.0 || zdepth != 1.0 || zskew != 0.0 || zrotate != 0.0) return(0); /* not a full size unrotated unskewed zoombox */ if (stdcalcmode == 't') return(0); /* tesselate, can't do it */ if (stdcalcmode == 'd') return(0); /* diffusion scan: can't do it either */ if (stdcalcmode == 'o') return(0); /* orbits, can't do it */ /* can pan if we get this far */ if (calc_status == 4) return(1); /* image completed, align on any pixel */ if (potflag && pot16bit) return(1); /* 1 pass forced so align on any pixel */ if (stdcalcmode == 'b') return(1); /* btm, align on any pixel */ if (stdcalcmode != 'g' || (curfractalspecific->flags&NOGUESS)) { if (stdcalcmode == '2' || stdcalcmode == '3') /* align on even pixel for 2pass */ return(2); return(1); /* assume 1pass */ } /* solid guessing */ start_resume(); get_resume(sizeof(num_worklist),&num_worklist,sizeof(worklist),worklist,0); /* don't do end_resume! we're just looking */ i = 9; for (j=0; j= 0) j = j>>1; /* reduce requirement */ return(j); } static void _fastcall move_row(int fromrow,int torow,int col) /* move a row on the screen */ { int startcol,endcol,tocol; memset(dstack,0,xdots); /* use dstack as a temp for the row; clear it */ if (fromrow >= 0 && fromrow < ydots) { tocol = startcol = 0; endcol = xdots-1; if (col < 0) { tocol -= col; endcol += col; } if (col > 0) startcol += col; get_line(fromrow,startcol,endcol,(BYTE *)&dstack[tocol]); } put_line(torow,0,xdots-1,(BYTE *)dstack); } int init_pan_or_recalc(int do_zoomout) /* decide to recalc, or to chg worklist & pan */ { int i,j,row,col,y,alignmask,listfull; if (zwidth == 0.0) return(0); /* no zoombox, leave calc_status as is */ /* got a zoombox */ if ((alignmask=check_pan()-1) < 0 || evolving) { calc_status = 0; /* can't pan, trigger recalc */ return(0); } if (zbx == 0.0 && zby == 0.0) { clearbox(); return(0); } /* box is full screen, leave calc_status as is */ col = (int)(zbx*(dxsize+PIXELROUND)); /* calc dest col,row of topleft pixel */ row = (int)(zby*(dysize+PIXELROUND)); if (do_zoomout) { /* invert row and col */ row = 0-row; col = 0-col; } if ((row&alignmask) != 0 || (col&alignmask) != 0) { calc_status = 0; /* not on useable pixel alignment, trigger recalc */ return(0); } /* pan */ num_worklist = 0; if (calc_status == 2) { start_resume(); get_resume(sizeof(num_worklist),&num_worklist,sizeof(worklist),worklist,0); } /* don't do end_resume! we might still change our mind */ /* adjust existing worklist entries */ for (i=0; i 0) { listfull |= add_worklist(0,xdots-1,0,ydots-row,ydots-1,ydots-row,0,0); j = ydots - row - 1; } if (col < 0) listfull |= add_worklist(0,0-col-1,0,i,j,i,0,0); if (col > 0) listfull |= add_worklist(xdots-col,xdots-1,xdots-col,i,j,i,0,0); if (listfull != 0) { static FCODE msg[] = {"\ Tables full, can't pan current image.\n\ Cancel resumes old image, continue pans and calculates a new one."}; if (stopmsg(2,msg)) { zwidth = 0; /* cancel the zoombox */ drawbox(1); } else calc_status = 0; /* trigger recalc */ return(0); } /* now we're committed */ calc_status = 2; clearbox(); if (row > 0) /* move image up */ for (y=0; y=0;) move_row(y+row,y,col); fix_worklist(); /* fixup any out of bounds worklist entries */ alloc_resume(sizeof(worklist)+20,2); /* post the new worklist */ put_resume(sizeof(num_worklist),&num_worklist,sizeof(worklist),worklist,0); return(0); } static void _fastcall restart_window(int wknum) /* force a worklist entry to restart */ { int yfrom,yto,xfrom,xto; if ((yfrom = worklist[wknum].yystart) < 0) yfrom = 0; if ((xfrom = worklist[wknum].xxstart) < 0) xfrom = 0; if ((yto = worklist[wknum].yystop) >= ydots) yto = ydots - 1; if ((xto = worklist[wknum].xxstop) >= xdots) xto = xdots - 1; memset(dstack,0,xdots); /* use dstack as a temp for the row; clear it */ while (yfrom <= yto) put_line(yfrom++,xfrom,xto,(BYTE *)dstack); worklist[wknum].sym = worklist[wknum].pass = 0; worklist[wknum].yybegin = worklist[wknum].yystart; worklist[wknum].xxbegin = worklist[wknum].xxstart; } static void fix_worklist(void) /* fix out of bounds and symmetry related stuff */ { int i,j,k; WORKLIST *wk; for (i=0; iyystart >= ydots || wk->yystop < 0 || wk->xxstart >= xdots || wk->xxstop < 0) { /* offscreen, delete */ for (j=i+1; jyystart < 0) { /* partly off top edge */ if ((wk->sym&1) == 0) { /* no sym, easy */ wk->yystart = 0; wk->xxbegin = 0; } else { /* xaxis symmetry */ if ((j = wk->yystop + wk->yystart) > 0 && num_worklist < MAXCALCWORK) { /* split the sym part */ worklist[num_worklist] = worklist[i]; worklist[num_worklist].yystart = 0; worklist[num_worklist++].yystop = j; wk->yystart = j+1; } else wk->yystart = 0; restart_window(i); /* restart the no-longer sym part */ } } if (wk->yystop >= ydots) { /* partly off bottom edge */ j = ydots-1; if ((wk->sym&1) != 0) { /* uses xaxis symmetry */ if ((k = wk->yystart + (wk->yystop - j)) < j) { if (num_worklist >= MAXCALCWORK) /* no room to split */ restart_window(i); else { /* split it */ worklist[num_worklist] = worklist[i]; worklist[num_worklist].yystart = k; worklist[num_worklist++].yystop = j; j = k-1; } } wk->sym &= -1 - 1; } wk->yystop = j; } if (wk->xxstart < 0) { /* partly off left edge */ if ((wk->sym&2) == 0) /* no sym, easy */ wk->xxstart = 0; else { /* yaxis symmetry */ if ((j = wk->xxstop + wk->xxstart) > 0 && num_worklist < MAXCALCWORK) { /* split the sym part */ worklist[num_worklist] = worklist[i]; worklist[num_worklist].xxstart = 0; worklist[num_worklist++].xxstop = j; wk->xxstart = j+1; } else wk->xxstart = 0; restart_window(i); /* restart the no-longer sym part */ } } if (wk->xxstop >= xdots) { /* partly off right edge */ j = xdots-1; if ((wk->sym&2) != 0) { /* uses xaxis symmetry */ if ((k = wk->xxstart + (wk->xxstop - j)) < j) { if (num_worklist >= MAXCALCWORK) /* no room to split */ restart_window(i); else { /* split it */ worklist[num_worklist] = worklist[i]; worklist[num_worklist].xxstart = k; worklist[num_worklist++].xxstop = j; j = k-1; } } wk->sym &= -1 - 2; } wk->xxstop = j; } if (wk->yybegin < wk->yystart) wk->yybegin = wk->yystart; if (wk->yybegin > wk->yystop) wk->yybegin = wk->yystop; if (wk->xxbegin < wk->xxstart) wk->xxbegin = wk->xxstart; if (wk->xxbegin > wk->xxstop) wk->xxbegin = wk->xxstop; } tidy_worklist(); /* combine where possible, re-sort */ } xfractint-20.4.10.orig/common/prompts1.c0000644000000000000000000027703711253454200014742 0ustar /* Various routines that prompt for things. */ #include #include #ifdef XFRACT #ifndef __386BSD__ #include #include #endif #endif #ifdef __TURBOC__ #include #elif !defined(__386BSD__) #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" #ifdef __hpux #include #define getwd(a) getcwd(a,MAXPATHLEN) #endif #ifdef __SVR4 #include #define getwd(a) getcwd(a,MAXPATHLEN) #endif /* Routines used in prompts2.c */ int prompt_checkkey(int curkey); int prompt_checkkey_scroll(int curkey); long get_file_entry(int,char *,char *,char *,char *); /* Routines in this module */ int prompt_valuestring(char *buf,struct fullscreenvalues *val); static int input_field_list(int attr,char *fld,int vlen,char **list,int llen, int row,int col,int (*checkkey)(int)); static int select_fracttype(int t); static int sel_fractype_help(int curkey, int choice); int select_type_params(int newfractype,int oldfractype); void set_default_parms(void); static long gfe_choose_entry(int,char *,char *,char *); static int check_gfe_key(int curkey,int choice); static void load_entry_text(FILE *entfile,char far *buf,int maxlines, int startrow, int startcol); static void format_parmfile_line(int,char *); static int get_light_params(void ); static int check_mapfile(void ); static int get_funny_glasses_params(void ); /* fullscreen_choice options */ #define CHOICEHELP 4 #define GETFORMULA 0 #define GETLSYS 1 #define GETIFS 2 #define GETPARM 3 static char funnyglasses_map_name[MAX_NAME]; char ifsmask[MAX_NAME] = {"*.ifs"}; char formmask[MAX_NAME] = {"*.frm"}; char lsysmask[MAX_NAME] = {"*.l"}; char Glasses1Map[MAX_NAME] = "glasses1.map"; char MAP_name[FILE_MAX_DIR] = ""; int mapset = 0; int julibrot; /* flag for julibrot */ /* --------------------------------------------------------------------- */ int promptfkeys; /* These need to be global because F6 exits fullscreen_prompt() */ int scroll_row_status; /* will be set to first line of extra info to be displayed ( 0 = top line) */ int scroll_column_status; /* will be set to first column of extra info to be displayed ( 0 = leftmost column )*/ int fullscreen_prompt( /* full-screen prompting routine */ char far *hdg, /* heading, lines separated by \n */ int numprompts, /* there are this many prompts (max) */ char far **prompts, /* array of prompting pointers */ struct fullscreenvalues *values, /* array of values */ int fkeymask, /* bit n on if Fn to cause return */ char far *extrainfo /* extra info box to display, \n separated */ ) { char far *hdgscan; int titlelines,titlewidth,titlerow; int maxpromptwidth,maxfldwidth,maxcomment; int boxrow,boxlines; int boxcol,boxwidth; int extralines,extrawidth,extrarow; int instrrow; int promptrow,promptcol,valuecol; int curchoice = 0; int done, i, j; int anyinput; int savelookatmouse; int curtype, curlen; char buf[81]; /* scrolling related variables */ FILE * scroll_file = NULL; /* file with extrainfo entry to scroll */ long scroll_file_start = 0; /* where entry starts in scroll_file */ int in_scrolling_mode = 0; /* will be 1 if need to scroll extrainfo */ int lines_in_entry = 0; /* total lines in entry to be scrolled */ int vertical_scroll_limit = 0; /* don't scroll down if this is top line */ int widest_entry_line = 0; /* length of longest line in entry */ int rewrite_extrainfo = 0; /* if 1: rewrite extrainfo to text box */ char blanks[78]; /* used to clear text box */ static FCODE instr1[] = {"Use " UPARR1 " and " DNARR1 " to select values to change"}; static FCODE instr2a[] = {"Type in replacement value for selected field"}; static FCODE instr2b[] = {"Use " LTARR1 " or " RTARR1 " to change value of selected field"}; static FCODE instr3a[] = {"Press ENTER when finished (or ESCAPE to back out)"}; static FCODE instr3b[] = {"Press ENTER when finished, ESCAPE to back out, or "FK_F1" for help"}; static FCODE instr0[] = {"No changeable parameters;"}; static FCODE instr0a[] = {"Press ENTER to exit"}; static FCODE instr0b[] = {"Press ENTER to exit, ESC to back out, "FK_F1" for help"}; savelookatmouse = lookatmouse; lookatmouse = 0; promptfkeys = fkeymask; memset(blanks,' ',77); /* initialize string of blanks */ blanks[77] = (char) 0; /* If applicable, open file for scrolling extrainfo. The function find_file_item() opens the file and sets the file pointer to the beginning of the entry. */ if((fractype == FORMULA || fractype == FFORMULA) && extrainfo && *extrainfo) { find_file_item(FormFileName, FormName, &scroll_file, 1); in_scrolling_mode = 1; scroll_file_start = ftell(scroll_file); } else if(fractype == LSYSTEM && extrainfo && *extrainfo) { find_file_item(LFileName, LName, &scroll_file, 2); in_scrolling_mode = 1; scroll_file_start = ftell(scroll_file); } else if((fractype == IFS || fractype == IFS3D) && extrainfo && *extrainfo) { find_file_item(IFSFileName, IFSName, &scroll_file, 3); in_scrolling_mode = 1; scroll_file_start = ftell(scroll_file); } /* initialize widest_entry_line and lines_in_entry */ if(in_scrolling_mode && scroll_file != NULL) { int comment = 0; int c = 0; int widthct = 0; while((c = fgetc(scroll_file)) != EOF && c != '\032') { if(c == ';') comment = 1; else if(c == '\n') { comment = 0; lines_in_entry++; widthct = -1; } else if (c == '\t') widthct += 7 - widthct % 8; else if ( c == '\r') continue; if(++widthct > widest_entry_line) widest_entry_line = widthct; if (c == '}' && !comment) { lines_in_entry++; break; } } if(c == EOF || c == '\032') { /* should never happen */ fclose(scroll_file); in_scrolling_mode = 0; } } helptitle(); /* clear screen, display title line */ setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest of screen to background */ hdgscan = hdg; /* count title lines, find widest */ i = titlewidth = 0; titlelines = 1; while (*hdgscan) { if (*(hdgscan++) == '\n') { ++titlelines; i = -1; } if (++i > titlewidth) titlewidth = i; } extralines = extrawidth = i = 0; if ((hdgscan = extrainfo) != 0) { if (*hdgscan == 0) extrainfo = NULL; else { /* count extra lines, find widest */ extralines = 3; while (*hdgscan) { if (*(hdgscan++) == '\n') { if (extralines + numprompts + titlelines >= 20) { *hdgscan = 0; /* full screen, cut off here */ break; } ++extralines; i = -1; } if (++i > extrawidth) extrawidth = i; } } } /* if entry fits in available space, shut off scrolling */ if(in_scrolling_mode && scroll_row_status == 0 && lines_in_entry == extralines - 2 && scroll_column_status == 0 && far_strchr(extrainfo, '\021') == NULL) { in_scrolling_mode = 0; fclose(scroll_file); scroll_file = NULL; } /*initialize vertical scroll limit. When the top line of the text box is the vertical scroll limit, the bottom line is the end of the entry, and no further down scrolling is necessary. */ if (in_scrolling_mode) vertical_scroll_limit = lines_in_entry - (extralines - 2); /* work out vertical positioning */ i = numprompts + titlelines + extralines + 3; /* total rows required */ j = (25 - i) / 2; /* top row of it all when centered */ j -= j / 4; /* higher is better if lots extra */ boxlines = numprompts; titlerow = 1 + j; promptrow = boxrow = titlerow + titlelines; if (titlerow > 2) { /* room for blank between title & box? */ --titlerow; --boxrow; ++boxlines; } instrrow = boxrow+boxlines; if (instrrow + 3 + extralines < 25) { ++boxlines; /* blank at bottom of box */ ++instrrow; if (instrrow + 3 + extralines < 25) ++instrrow; /* blank before instructions */ } extrarow = instrrow + 2; if (numprompts > 1) /* 3 instructions lines */ ++extrarow; if (extrarow + extralines < 25) ++extrarow; if(in_scrolling_mode) /* set box to max width if in scrolling mode */ extrawidth = 76; /* work out horizontal positioning */ maxfldwidth = maxpromptwidth = maxcomment = anyinput = 0; for (i = 0; i < numprompts; i++) { if (values[i].type == 'y') { static char *noyes[2] = {s_no,s_yes}; values[i].type = 'l'; values[i].uval.ch.vlen = 3; values[i].uval.ch.list = noyes; values[i].uval.ch.llen = 2; } j = far_strlen(prompts[i]); if (values[i].type == '*') { if (j > maxcomment) maxcomment = j; } else { anyinput = 1; if (j > maxpromptwidth) maxpromptwidth = j; j = prompt_valuestring(buf,&values[i]); if (j > maxfldwidth) maxfldwidth = j; } } boxwidth = maxpromptwidth + maxfldwidth + 2; if (maxcomment > boxwidth) boxwidth = maxcomment; if ((boxwidth += 4) > 80) boxwidth = 80; boxcol = (80 - boxwidth) / 2; /* center the box */ promptcol = boxcol + 2; valuecol = boxcol + boxwidth - maxfldwidth - 2; if (boxwidth <= 76) { /* make margin a bit wider if we can */ boxwidth += 2; --boxcol; } if ((j = titlewidth) < extrawidth) j = extrawidth; if ((i = j + 4 - boxwidth) > 0) { /* expand box for title/extra */ if (boxwidth + i > 80) i = 80 - boxwidth; boxwidth += i; boxcol -= i / 2; } i = (90 - boxwidth) / 20; boxcol -= i; promptcol -= i; valuecol -= i; /* display box heading */ for (i = titlerow; i < boxrow; ++i) setattr(i,boxcol,C_PROMPT_HI,boxwidth); { char far *hdgline = hdg; /* center each line of heading independently */ int i; for(i=0;i 0) ? instr0b : instr0a); movecursor(25,80); textcbase = 2; for(;;) { if(rewrite_extrainfo) { rewrite_extrainfo = 0; fseek(scroll_file, scroll_file_start, SEEK_SET); load_entry_text(scroll_file, extrainfo, extralines - 2, scroll_row_status, scroll_column_status); for(i=1; i <= extralines - 2; i++) putstring(extrarow+i,0,C_PROMPT_TEXT,blanks); putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo); } while (!keypressed()) { } done = getakey(); switch(done) { case ESC: done = -1; case ENTER: case ENTER_2: goto fullscreen_exit; case DOWN_ARROW_2: /* scrolling key - down one row */ if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) { scroll_row_status++; rewrite_extrainfo = 1; } break; case UP_ARROW_2: /* scrolling key - up one row */ if(in_scrolling_mode && scroll_row_status > 0) { scroll_row_status--; rewrite_extrainfo = 1; } break; case LEFT_ARROW_2: /* scrolling key - left one column */ if(in_scrolling_mode && scroll_column_status > 0) { scroll_column_status--; rewrite_extrainfo = 1; } break; case RIGHT_ARROW_2: /* scrolling key - right one column */ if(in_scrolling_mode && far_strchr(extrainfo, '\021') != NULL) { scroll_column_status++; rewrite_extrainfo = 1; } break; case CTL_PAGE_DOWN: /* scrolling key - down one screen */ if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) { scroll_row_status += extralines - 2; if(scroll_row_status > vertical_scroll_limit) scroll_row_status = vertical_scroll_limit; rewrite_extrainfo = 1; } break; case CTL_PAGE_UP: /* scrolling key - up one screen */ if(in_scrolling_mode && scroll_row_status > 0) { scroll_row_status -= extralines - 2; if(scroll_row_status < 0) scroll_row_status = 0; rewrite_extrainfo = 1; } break; case CTL_END: /* scrolling key - to end of entry */ if(in_scrolling_mode) { scroll_row_status = vertical_scroll_limit; scroll_column_status = 0; rewrite_extrainfo = 1; } break; case CTL_HOME: /* scrolling key - to beginning of entry */ if(in_scrolling_mode) { scroll_row_status = scroll_column_status = 0; rewrite_extrainfo = 1; } break; case F2: case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: if (promptfkeys & (1<<(done+1-F1)) ) goto fullscreen_exit; } } } /* display footing */ if (numprompts > 1) putstringcenter(instrrow++,0,80,C_PROMPT_BKGRD,instr1); putstringcenter(instrrow+1,0,80,C_PROMPT_BKGRD, (helpmode > 0) ? instr3b : instr3a); done = 0; while (values[curchoice].type == '*') ++curchoice; while (!done) { if(rewrite_extrainfo) { j = textcbase; textcbase = 2; fseek(scroll_file, scroll_file_start, SEEK_SET); load_entry_text(scroll_file, extrainfo, extralines - 2, scroll_row_status, scroll_column_status); for(i=1; i <= extralines - 2; i++) putstring(extrarow+i,0,C_PROMPT_TEXT,blanks); putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo); textcbase = j; } curtype = values[curchoice].type; curlen = prompt_valuestring(buf,&values[curchoice]); if(!rewrite_extrainfo) putstringcenter(instrrow,0,80,C_PROMPT_BKGRD, (curtype == 'l') ? instr2b : instr2a); else rewrite_extrainfo = 0; putstring(promptrow+curchoice,promptcol,C_PROMPT_HI,prompts[curchoice]); if (curtype == 'l') { i = input_field_list( C_PROMPT_CHOOSE, buf, curlen, values[curchoice].uval.ch.list, values[curchoice].uval.ch.llen, promptrow+curchoice,valuecol, in_scrolling_mode ? prompt_checkkey_scroll : prompt_checkkey); for (j = 0; j < values[curchoice].uval.ch.llen; ++j) if (strcmp(buf,values[curchoice].uval.ch.list[j]) == 0) break; values[curchoice].uval.ch.val = j; } else { j = 0; if (curtype == 'i') j = 3; if (curtype == 'L') j = 3; if (curtype == 'd') j = 5; if (curtype == 'D') j = 7; if (curtype == 'f') j = 1; i = input_field(j, C_PROMPT_INPUT, buf, curlen, promptrow+curchoice,valuecol, in_scrolling_mode ? prompt_checkkey_scroll : prompt_checkkey); switch (values[curchoice].type) { case 'd': case 'D': values[curchoice].uval.dval = atof(buf); break; case 'f': values[curchoice].uval.dval = atof(buf); roundfloatd(&values[curchoice].uval.dval); break; case 'i': values[curchoice].uval.ival = atoi(buf); break; case 'L': values[curchoice].uval.Lval = atol(buf); break; case 's': strncpy(values[curchoice].uval.sval,buf,16); break; default: /* assume 0x100+n */ far_strcpy(values[curchoice].uval.sbuf,buf); } } putstring(promptrow+curchoice,promptcol,C_PROMPT_LO,prompts[curchoice]); j = strlen(buf); memset(&buf[j],' ',80-j); buf[curlen] = 0; putstring(promptrow+curchoice, valuecol, C_PROMPT_LO, buf); switch(i) { case 0: /* enter */ done = 13; break; case -1: /* escape */ case F2: case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: done = i; break; case PAGE_UP: curchoice = -1; case DOWN_ARROW: do { if (++curchoice >= numprompts) curchoice = 0; } while (values[curchoice].type == '*'); break; case PAGE_DOWN: curchoice = numprompts; case UP_ARROW: do { if (--curchoice < 0) curchoice = numprompts - 1; } while (values[curchoice].type == '*'); break; case DOWN_ARROW_2: /* scrolling key - down one row */ if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) { scroll_row_status++; rewrite_extrainfo = 1; } break; case UP_ARROW_2: /* scrolling key - up one row */ if(in_scrolling_mode && scroll_row_status > 0) { scroll_row_status--; rewrite_extrainfo = 1; } break; case LEFT_ARROW_2: /*scrolling key - left one column */ if(in_scrolling_mode && scroll_column_status > 0) { scroll_column_status--; rewrite_extrainfo = 1; } break; case RIGHT_ARROW_2: /* scrolling key - right one column */ if(in_scrolling_mode && far_strchr(extrainfo, '\021') != NULL) { scroll_column_status++; rewrite_extrainfo = 1; } break; case CTL_PAGE_DOWN: /* scrolling key - down on screen */ if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) { scroll_row_status += extralines - 2; if(scroll_row_status > vertical_scroll_limit) scroll_row_status = vertical_scroll_limit; rewrite_extrainfo = 1; } break; case CTL_PAGE_UP: /* scrolling key - up one screen */ if(in_scrolling_mode && scroll_row_status > 0) { scroll_row_status -= extralines - 2; if(scroll_row_status < 0) scroll_row_status = 0; rewrite_extrainfo = 1; } break; case CTL_END: /* scrolling key - go to end of entry */ if(in_scrolling_mode) { scroll_row_status = vertical_scroll_limit; scroll_column_status = 0; rewrite_extrainfo = 1; } break; case CTL_HOME: /* scrolling key - go to beginning of entry */ if(in_scrolling_mode) { scroll_row_status = scroll_column_status = 0; rewrite_extrainfo = 1; } break; } } fullscreen_exit: movecursor(25,80); lookatmouse = savelookatmouse; if(scroll_file) { fclose(scroll_file); scroll_file = NULL; } return(done); } int prompt_valuestring(char *buf,struct fullscreenvalues *val) { /* format value into buf, return field width */ int i,ret; switch (val->type) { case 'd': ret = 20; i = 16; /* cellular needs 16 (was 15)*/ for(;;) { sprintf(buf,"%.*g",i,val->uval.dval); if ((int)strlen(buf) <= ret) break; --i; } break; case 'D': if (val->uval.dval<0) { /* We have to round the right way */ sprintf(buf,"%ld",(long)(val->uval.dval-.5)); } else { sprintf(buf,"%ld",(long)(val->uval.dval+.5)); } ret = 20; break; case 'f': sprintf(buf,"%.7g",val->uval.dval); ret = 14; break; case 'i': sprintf(buf,"%d",val->uval.ival); ret = 6; break; case 'L': sprintf(buf,"%ld",val->uval.Lval); ret = 10; break; case '*': *buf = (char)(ret = 0); break; case 's': strncpy(buf,val->uval.sval,16); buf[15] = 0; ret = 15; break; case 'l': strcpy(buf,val->uval.ch.list[val->uval.ch.val]); ret = val->uval.ch.vlen; break; default: /* assume 0x100+n */ far_strcpy(buf,val->uval.sbuf); ret = val->type & 0xff; } return ret; } int prompt_checkkey(int curkey) { switch(curkey) { case PAGE_UP: case DOWN_ARROW: case PAGE_DOWN: case UP_ARROW: return(curkey); case F2: case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: if (promptfkeys & (1<<(curkey+1-F1)) ) return(curkey); } return(0); } int prompt_checkkey_scroll(int curkey) { switch(curkey) { case PAGE_UP: case DOWN_ARROW: case DOWN_ARROW_2: case PAGE_DOWN: case UP_ARROW: case UP_ARROW_2: case LEFT_ARROW_2: case RIGHT_ARROW_2: case CTL_PAGE_DOWN: case CTL_PAGE_UP: case CTL_END: case CTL_HOME: return(curkey); case F2: case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: if (promptfkeys & (1<<(curkey+1-F1)) ) return(curkey); } return(0); } static int input_field_list( int attr, /* display attribute */ char *fld, /* display form field value */ int vlen, /* field length */ char **list, /* list of values */ int llen, /* number of entries in list */ int row, /* display row */ int col, /* display column */ int (*checkkey)(int) /* routine to check non data keys, or NULL */ ) { int initval,curval; char buf[81]; int curkey; int i, j; int ret,savelookatmouse; savelookatmouse = lookatmouse; lookatmouse = 0; for (initval = 0; initval < llen; ++initval) if (strcmp(fld,list[initval]) == 0) break; if (initval >= llen) initval = 0; curval = initval; ret = -1; for(;;) { strcpy(buf,list[curval]); i = strlen(buf); while (i < vlen) buf[i++] = ' '; buf[vlen] = 0; putstring(row,col,attr,buf); curkey = keycursor(row,col); /* get a keystroke */ switch (curkey) { case ENTER: case ENTER_2: ret = 0; goto inpfldl_end; case ESC: goto inpfldl_end; case RIGHT_ARROW: if (++curval >= llen) curval = 0; break; case LEFT_ARROW: if (--curval < 0) curval = llen - 1; break; case F5: curval = initval; break; default: if (nonalpha(curkey)) { if (checkkey && (ret = (*checkkey)(curkey)) != 0) goto inpfldl_end; break; /* non alphanum char */ } j = curval; for (i = 0; i < llen; ++i) { if (++j >= llen) j = 0; if ( (*list[j] & 0xdf) == (curkey & 0xdf)) { curval = j; break; } } } } inpfldl_end: strcpy(fld,list[curval]); lookatmouse = savelookatmouse; return(ret); } /* --------------------------------------------------------------------- */ /* MCP 7-7-91, This is static code, but not called anywhere */ #ifdef DELETE_UNUSED_CODE /* compare for sort of type table */ static int compare(const VOIDPTR i, const VOIDPTR j) { return(strcmp(fractalspecific[(int)*((BYTE*)i)].name, fractalspecific[(int)*((BYTE*)j)].name)); } /* --------------------------------------------------------------------- */ static void clear_line(int row, int start, int stop, int color) /* clear part of a line */ { int col; for(col=start;col<= stop;col++) putstring(row,col,color," "); } #endif /* --------------------------------------------------------------------- */ int get_fracttype() /* prompt for and select fractal type */ { int done,i,oldfractype,t; done = -1; oldfractype = fractype; for(;;) { if ((t = select_fracttype(fractype)) < 0) break; if ((i = select_type_params(t, fractype)) == 0) { /* ok, all done */ done = 0; break; } if (i > 0) /* can't return to prior image anymore */ done = 1; } if (done < 0) fractype = oldfractype; curfractalspecific = &fractalspecific[fractype]; return(done); } struct FT_CHOICE { char name[15]; int num; }; static struct FT_CHOICE far **ft_choices; /* for sel_fractype_help subrtn */ static int select_fracttype(int t) /* subrtn of get_fracttype, separated */ /* so that storage gets freed up */ { static FCODE head1[] = {"Select a Fractal Type"}; static FCODE head2[] = {"Select Orbit Algorithm for Julibrot"}; static FCODE o_instr[] = {"Press "FK_F2" for a description of the highlighted type"}; char instr[sizeof(o_instr)]; char head[40]; int oldhelpmode; int numtypes, done; int i, j; #define MAXFTYPES 200 char tname[40]; struct FT_CHOICE far *choices[MAXFTYPES]; int attributes[MAXFTYPES]; /* steal existing array for "choices" */ choices[0] = (struct FT_CHOICE far *)boxy; attributes[0] = 1; for (i = 1; i < MAXFTYPES; ++i) { choices[i] = choices[i-1] + 1; attributes[i] = 1; } ft_choices = &choices[0]; /* setup context sensitive help */ oldhelpmode = helpmode; helpmode = HELPFRACTALS; far_strcpy(instr,o_instr); if(julibrot) far_strcpy(head,head2); else far_strcpy(head,head1); if (t == IFS3D) t = IFS; i = j = -1; while(fractalspecific[++i].name) { if(julibrot) if (!((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*')) continue; if (fractalspecific[i].name[0] == '*') continue; far_strcpy(choices[++j]->name,fractalspecific[i].name); choices[j]->name[14] = 0; /* safety */ choices[j]->num = i; /* remember where the real item is */ } numtypes = j + 1; shell_sort(choices,numtypes,sizeof(char far *),lccompare); /* sort list */ j = 0; for (i = 0; i < numtypes; ++i) /* find starting choice in sorted list */ if (choices[i]->num == t || choices[i]->num == fractalspecific[t].tofloat) j = i; tname[0] = 0; done = fullscreen_choice(CHOICEHELP+8,head,NULL,instr,numtypes, (char far *far*)choices,attributes,0,0,0,j,NULL,tname,NULL,sel_fractype_help); if (done >= 0) { done = choices[done]->num; if((done == FORMULA || done == FFORMULA) && !strcmp(FormFileName, CommandFile)) strcpy(FormFileName, searchfor.frm); if(done == LSYSTEM && !strcmp(LFileName, CommandFile)) strcpy(LFileName, searchfor.lsys); if((done == IFS || done == IFS3D) && !strcmp(IFSFileName, CommandFile)) strcpy(IFSFileName, searchfor.ifs); } helpmode = oldhelpmode; return(done); } static int sel_fractype_help(int curkey,int choice) { int oldhelpmode; if (curkey == F2) { oldhelpmode = helpmode; helpmode = fractalspecific[(*(ft_choices+choice))->num].helptext; help(0); helpmode = oldhelpmode; } return(0); } int select_type_params( /* prompt for new fractal type parameters */ int newfractype, /* new fractal type */ int oldfractype /* previous fractal type */ ) { int ret,oldhelpmode; oldhelpmode = helpmode; sel_type_restart: ret = 0; fractype = newfractype; curfractalspecific = &fractalspecific[fractype]; if (fractype == LSYSTEM) { helpmode = HT_LSYS; if (get_file_entry(GETLSYS,"L-System",lsysmask,LFileName,LName) < 0) { ret = 1; goto sel_type_exit; } } if (fractype == FORMULA || fractype == FFORMULA) { helpmode = HT_FORMULA; if (get_file_entry(GETFORMULA,"Formula",formmask,FormFileName,FormName) < 0) { ret = 1; goto sel_type_exit; } } if (fractype == IFS || fractype == IFS3D) { helpmode = HT_IFS; if (get_file_entry(GETIFS,"IFS",ifsmask,IFSFileName,IFSName) < 0) { ret = 1; goto sel_type_exit; } } /* Added the following to accommodate fn bifurcations. JCO 7/2/92 */ if(((fractype == BIFURCATION) || (fractype == LBIFURCATION)) && !((oldfractype == BIFURCATION) || (oldfractype == LBIFURCATION))) set_trig_array(0,s_ident); if(((fractype == BIFSTEWART) || (fractype == LBIFSTEWART)) && !((oldfractype == BIFSTEWART) || (oldfractype == LBIFSTEWART))) set_trig_array(0,s_ident); if(((fractype == BIFLAMBDA) || (fractype == LBIFLAMBDA)) && !((oldfractype == BIFLAMBDA) || (oldfractype == LBIFLAMBDA))) set_trig_array(0,s_ident); if(((fractype == BIFEQSINPI) || (fractype == LBIFEQSINPI)) && !((oldfractype == BIFEQSINPI) || (oldfractype == LBIFEQSINPI))) set_trig_array(0,s_sin); if(((fractype == BIFADSINPI) || (fractype == LBIFADSINPI)) && !((oldfractype == BIFADSINPI) || (oldfractype == LBIFADSINPI))) set_trig_array(0,s_sin); /* * Next assumes that user going between popcorn and popcornjul * might not want to change function variables */ if(((fractype == FPPOPCORN ) || (fractype == LPOPCORN ) || (fractype == FPPOPCORNJUL) || (fractype == LPOPCORNJUL)) && !((oldfractype == FPPOPCORN ) || (oldfractype == LPOPCORN ) || (oldfractype == FPPOPCORNJUL) || (oldfractype == LPOPCORNJUL))) set_function_parm_defaults(); /* set LATOO function defaults */ if(fractype == LATOO && oldfractype != LATOO) { set_function_parm_defaults(); } set_default_parms(); if (get_fract_params(0) < 0) if (fractype == FORMULA || fractype == FFORMULA || fractype == IFS || fractype == IFS3D || fractype == LSYSTEM) goto sel_type_restart; else ret = 1; else { if (newfractype != oldfractype) { invert = 0; inversion[0] = inversion[1] = inversion[2] = 0; } } sel_type_exit: helpmode = oldhelpmode; return(ret); } void set_default_parms() { int i,extra; xxmin = curfractalspecific->xmin; xxmax = curfractalspecific->xmax; yymin = curfractalspecific->ymin; yymax = curfractalspecific->ymax; xx3rd = xxmin; yy3rd = yymin; if (viewcrop && finalaspectratio != screenaspect) aspectratio_crop(screenaspect,finalaspectratio); for (i = 0; i < 4; i++) { param[i] = curfractalspecific->paramvalue[i]; if (fractype != CELLULAR && fractype != FROTH && fractype != FROTHFP && fractype != ANT) roundfloatd(¶m[i]); /* don't round cellular, frothybasin or ant */ } if((extra=find_extra_param(fractype)) > -1) for(i=0;i= MAXFRACTALS) break; } } return (numfractals); } static FCODE v0a[] = {"From cx (real part)"}; static FCODE v1a[] = {"From cy (imaginary part)"}; static FCODE v2a[] = {"To cx (real part)"}; static FCODE v3a[] = {"To cy (imaginary part)"}; /* 4D Mandelbrot */ static FCODE v0b[] = {"From cj (3rd dim)"}; static FCODE v1b[] = {"From ck (4th dim)"}; static FCODE v2b[] = {"To cj (3rd dim)"}; static FCODE v3b[] = {"To ck (4th dim)"}; /* 4D Julia */ static FCODE v0c[] = {"From zj (3rd dim)"}; static FCODE v1c[] = {"From zk (4th dim)"}; static FCODE v2c[] = {"To zj (3rd dim)"}; static FCODE v3c[] = {"To zk (4th dim)"}; static FCODE v4[] = {"Number of z pixels"}; static FCODE v5[] = {"Location of z origin"}; static FCODE v6[] = {"Depth of z"}; static FCODE v7[] = {"Screen height"}; static FCODE v8[] = {"Screen width"}; static FCODE v9[] = {"Distance to Screen"}; static FCODE v10[] = {"Distance between eyes"}; static FCODE v11[] = {"3D Mode"}; char *juli3Doptions[] = {"monocular","lefteye","righteye","red-blue"}; /* JIIM */ #ifdef RANDOM_RUN static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk, Random Run?"; char *JIIMmethod[] = {"breadth", "depth", "walk", "run"}; #else static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk"; char *JIIMmethod[] = {"breadth", "depth", "walk"}; #endif static FCODE JIIMstr2[] = "Left first or Right first?"; char *JIIMleftright[] = {"left", "right"}; /* moved from miscres.c so sizeof structure can be accessed here */ struct trig_funct_lst trigfn[] = /* changing the order of these alters meaning of *.fra file */ /* maximum 6 characters in function names or recheck all related code */ { #ifndef XFRACT {s_sin, lStkSin, dStkSin, mStkSin }, {s_cosxx, lStkCosXX, dStkCosXX, mStkCosXX }, {s_sinh, lStkSinh, dStkSinh, mStkSinh }, {s_cosh, lStkCosh, dStkCosh, mStkCosh }, {s_exp, lStkExp, dStkExp, mStkExp }, {s_log, lStkLog, dStkLog, mStkLog }, {s_sqr, lStkSqr, dStkSqr, mStkSqr }, {s_recip, lStkRecip, dStkRecip, mStkRecip }, /* from recip on new in v16 */ {s_ident, StkIdent, StkIdent, StkIdent }, {s_cos, lStkCos, dStkCos, mStkCos }, {s_tan, lStkTan, dStkTan, mStkTan }, {s_tanh, lStkTanh, dStkTanh, mStkTanh }, {s_cotan, lStkCoTan, dStkCoTan, mStkCoTan }, {s_cotanh,lStkCoTanh,dStkCoTanh,mStkCoTanh}, {s_flip, lStkFlip, dStkFlip, mStkFlip }, {s_conj, lStkConj, dStkConj, mStkConj }, {s_zero, lStkZero, dStkZero, mStkZero }, {s_asin, lStkASin, dStkASin, mStkASin }, {s_asinh, lStkASinh, dStkASinh, mStkASinh }, {s_acos, lStkACos, dStkACos, mStkACos }, {s_acosh, lStkACosh, dStkACosh, mStkACosh }, {s_atan, lStkATan, dStkATan, mStkATan }, {s_atanh, lStkATanh, dStkATanh, mStkATanh }, {s_cabs, lStkCAbs, dStkCAbs, mStkCAbs }, {s_abs, lStkAbs, dStkAbs, mStkAbs }, {s_sqrt, lStkSqrt, dStkSqrt, mStkSqrt }, {s_floor, lStkFloor, dStkFloor, mStkFloor }, {s_ceil, lStkCeil, dStkCeil, mStkCeil }, {s_trunc, lStkTrunc, dStkTrunc, mStkTrunc }, {s_round, lStkRound, dStkRound, mStkRound }, {s_one, lStkOne, dStkOne, mStkOne }, #else {s_sin, dStkSin, dStkSin, dStkSin }, {s_cosxx, dStkCosXX, dStkCosXX, dStkCosXX }, {s_sinh, dStkSinh, dStkSinh, dStkSinh }, {s_cosh, dStkCosh, dStkCosh, dStkCosh }, {s_exp, dStkExp, dStkExp, dStkExp }, {s_log, dStkLog, dStkLog, dStkLog }, {s_sqr, dStkSqr, dStkSqr, dStkSqr }, {s_recip, dStkRecip, dStkRecip, dStkRecip }, /* from recip on new in v16 */ {s_ident, StkIdent, StkIdent, StkIdent }, {s_cos, dStkCos, dStkCos, dStkCos }, {s_tan, dStkTan, dStkTan, dStkTan }, {s_tanh, dStkTanh, dStkTanh, dStkTanh }, {s_cotan, dStkCoTan, dStkCoTan, dStkCoTan }, {s_cotanh,dStkCoTanh,dStkCoTanh,dStkCoTanh}, {s_flip, dStkFlip, dStkFlip, dStkFlip }, {s_conj, dStkConj, dStkConj, dStkConj }, {s_zero, dStkZero, dStkZero, dStkZero }, {s_asin, dStkASin, dStkASin, dStkASin }, {s_asinh, dStkASinh, dStkASinh, dStkASinh }, {s_acos, dStkACos, dStkACos, dStkACos }, {s_acosh, dStkACosh, dStkACosh, dStkACosh }, {s_atan, dStkATan, dStkATan, dStkATan }, {s_atanh, dStkATanh, dStkATanh, dStkATanh }, {s_cabs, dStkCAbs, dStkCAbs, dStkCAbs }, {s_abs, dStkAbs, dStkAbs, dStkAbs }, {s_sqrt, dStkSqrt, dStkSqrt, dStkSqrt }, {s_floor, dStkFloor, dStkFloor, dStkFloor }, {s_ceil, dStkCeil, dStkCeil, dStkCeil }, {s_trunc, dStkTrunc, dStkTrunc, dStkTrunc }, {s_round, dStkRound, dStkRound, dStkRound }, {s_one, dStkOne, dStkOne, dStkOne }, #endif }; #define NUMTRIGFN sizeof(trigfn)/sizeof(struct trig_funct_lst) const int numtrigfn = NUMTRIGFN; /* --------------------------------------------------------------------- */ int get_fract_params(int caller) /* prompt for type-specific parms */ { char far *v0 = v0a; char far *v1 = v1a; char far *v2 = v2a; char far *v3 = v3a; char *juliorbitname = NULL; int i,j,k; int curtype,numparams,numtrig; struct fullscreenvalues paramvalues[30]; char far *choices[30]; long oldbailout = 0L, long_i; int promptnum; char msg[120]; char *typename, *tmpptr; char bailoutmsg[50]; int ret = 0; int oldhelpmode; char parmprompt[MAXPARAMS][55]; static FCODE t1[] = {"First Function"}; static FCODE t2[] = {"Second Function"}; static FCODE t3[] = {"Third Function"}; static FCODE t4[] = {"Fourth Function"}; static FCODE *trg[] = {t1, t2, t3, t4}; char *filename,*entryname; FILE *entryfile; char *trignameptr[NUMTRIGFN]; #ifdef XFRACT static /* Can't initialize aggregates on the stack */ #endif char *bailnameptr[] = {s_mod,s_real,s_imag,s_or,s_and,s_manh,s_manr}; struct fractalspecificstuff far *jborbit = NULL; struct fractalspecificstuff far *savespecific; int firstparm = 0; int lastparm = MAXPARAMS; double oldparam[MAXPARAMS]; int fkeymask = 0x40; oldbailout = bailout; if(fractype==JULIBROT || fractype==JULIBROTFP) julibrot = 1; else julibrot = 0; curtype = fractype; if (curfractalspecific->name[0] == '*' && (i = curfractalspecific->tofloat) != NOFRACTAL /* FIXED BUG HERE!! */ && fractalspecific[i].name[0] != '*') curtype = i; curfractalspecific = &fractalspecific[curtype]; tstack[0] = 0; if ((i = curfractalspecific->helpformula) < -1) { if (i == -2) { /* special for formula */ filename = FormFileName; entryname = FormName; } else if (i == -3) { /* special for lsystem */ filename = LFileName; entryname = LName; } else if (i == -4) { /* special for ifs */ filename = IFSFileName; entryname = IFSName; } else { /* this shouldn't happen */ filename = NULL; entryname = NULL; } if (find_file_item(filename,entryname,&entryfile, -1-i) == 0) { load_entry_text(entryfile,tstack,17, 0, 0); fclose(entryfile); if(fractype == FORMULA || fractype == FFORMULA) frm_get_param_stuff(entryname); /* no error check, should be okay, from above */ } } else if (i >= 0) { int c,lines; read_help_topic(i,0,2000,tstack); /* need error handling here ?? */ tstack[2000-i] = 0; i = j = lines = 0; k = 1; while ((c = tstack[i++]) != 0) { /* stop at ctl, blank, or line with col 1 nonblank, max 16 lines */ if (k && c == ' ' && ++k <= 5) { } /* skip 4 blanks at start of line */ else { if (c == '\n') { if (k) break; /* blank line */ if (++lines >= 16) break; k = 1; } else if (c < 16) /* a special help format control char */ break; else { if (k == 1) /* line starts in column 1 */ break; k = 0; } tstack[j++] = (char)c; } } while (--j >= 0 && tstack[j] == '\n') { } tstack[j+1] = 0; } gfp_top: promptnum = 0; if (julibrot) { i = select_fracttype(neworbittype); if (i < 0) { if (ret == 0) ret = -1; julibrot = 0; goto gfp_exit; } else neworbittype = i; jborbit = &fractalspecific[neworbittype]; juliorbitname = jborbit->name; } if(fractype == FORMULA || fractype == FFORMULA) { if(uses_p1) /* set first parameter */ firstparm = 0; else if(uses_p2) firstparm = 2; else if(uses_p3) firstparm = 4; else if(uses_p4) firstparm = 6; else firstparm = 8; /* uses_p5 or no parameter */ if(uses_p5) /* set last parameter */ lastparm = 10; else if(uses_p4) lastparm = 8; else if(uses_p3) lastparm = 6; else if(uses_p2) lastparm = 4; else lastparm = 2; /* uses_p1 or no parameter */ } savespecific = curfractalspecific; if(julibrot) { curfractalspecific = jborbit; firstparm = 2; /* in most case Julibrot does not need first two parms */ if(neworbittype == QUATJULFP || /* all parameters needed */ neworbittype == HYPERCMPLXJFP) { firstparm = 0; lastparm = 4; } if(neworbittype == QUATFP || /* no parameters needed */ neworbittype == HYPERCMPLXFP) firstparm = 4; } numparams = 0; j = 0; for (i = firstparm; i < lastparm; i++) { char tmpbuf[30]; if (!typehasparm(julibrot?neworbittype:fractype,i,parmprompt[j])) { if(curtype == FORMULA || curtype == FFORMULA) if(paramnotused(i)) continue; break; } numparams++; choices[promptnum] = parmprompt[j++]; paramvalues[promptnum].type = 'd'; if (choices[promptnum][0] == '+') { choices[promptnum]++; paramvalues[promptnum].type = 'D'; } else if (choices[promptnum][0] == '#') choices[promptnum]++; sprintf(tmpbuf,"%.17g",param[i]); paramvalues[promptnum].uval.dval = atof(tmpbuf); oldparam[i] = paramvalues[promptnum++].uval.dval; } /* The following is a goofy kludge to make reading in the formula * parameters work. */ if(curtype == FORMULA || curtype == FFORMULA) numparams = lastparm - firstparm; numtrig = (curfractalspecific->flags >> 6) & 7; if(curtype==FORMULA || curtype==FFORMULA ) { numtrig = maxfn; } i = NUMTRIGFN; while (--i >= 0) trignameptr[i] = trigfn[i].name; for (i = 0; i < numtrig; i++) { paramvalues[promptnum].type = 'l'; paramvalues[promptnum].uval.ch.val = trigndx[i]; paramvalues[promptnum].uval.ch.llen = NUMTRIGFN; paramvalues[promptnum].uval.ch.vlen = 6; paramvalues[promptnum].uval.ch.list = trignameptr; choices[promptnum++] = (char far *)trg[i]; } if (*(typename = curfractalspecific->name) == '*') ++typename; long_i = curfractalspecific->orbit_bailout; if( long_i != 0 && curfractalspecific->calctype == StandardFractal && (curfractalspecific->flags & BAILTEST) ) { static FCODE bailteststr[] = {"Bailout Test (mod, real, imag, or, and, manh, manr)"}; paramvalues[promptnum].type = 'l'; paramvalues[promptnum].uval.ch.val = (int)bailoutest; paramvalues[promptnum].uval.ch.llen = 7; paramvalues[promptnum].uval.ch.vlen = 6; paramvalues[promptnum].uval.ch.list = bailnameptr; choices[promptnum++] = bailteststr; } if (long_i) { if (potparam[0] != 0.0 && potparam[2] != 0.0) { static FCODE bailpotstr[] = {"Bailout: continuous potential (Y screen) value in use"}; paramvalues[promptnum].type = '*'; choices[promptnum++] = bailpotstr; } else { static FCODE bailoutstr[] = {"Bailout value (0 means use default)"}; choices[promptnum] = bailoutstr; paramvalues[promptnum].type = 'L'; paramvalues[promptnum++].uval.Lval = (oldbailout = bailout); paramvalues[promptnum].type = '*'; tmpptr = typename; if (usr_biomorph != -1) { i = 100; tmpptr = "biomorph"; } sprintf(bailoutmsg," (%s default is %ld)",tmpptr,long_i); choices[promptnum++] = bailoutmsg; } } if (julibrot) { switch(neworbittype) { case QUATFP: case HYPERCMPLXFP: v0 = v0b; v1 = v1b; v2 = v2b; v3 = v3b; break; case QUATJULFP: case HYPERCMPLXJFP: v0 = v0c; v1 = v1c; v2 = v2c; v3 = v3c; break; default: v0 = v0a; v1 = v1a; v2 = v2a; v3 = v3a; break; } curfractalspecific = savespecific; paramvalues[promptnum].uval.dval = mxmaxfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v0; paramvalues[promptnum].uval.dval = mymaxfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v1; paramvalues[promptnum].uval.dval = mxminfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v2; paramvalues[promptnum].uval.dval = myminfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v3; paramvalues[promptnum].uval.ival = zdots; paramvalues[promptnum].type = 'i'; choices[promptnum++] = v4; paramvalues[promptnum].type = 'l'; paramvalues[promptnum].uval.ch.val = juli3Dmode; paramvalues[promptnum].uval.ch.llen = 4; paramvalues[promptnum].uval.ch.vlen = 9; paramvalues[promptnum].uval.ch.list = juli3Doptions; choices[promptnum++] = v11; paramvalues[promptnum].uval.dval = eyesfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v10; paramvalues[promptnum].uval.dval = originfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v5; paramvalues[promptnum].uval.dval = depthfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v6; paramvalues[promptnum].uval.dval = heightfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v7; paramvalues[promptnum].uval.dval = widthfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v8; paramvalues[promptnum].uval.dval = distfp; paramvalues[promptnum].type = 'f'; choices[promptnum++] = v9; } if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP) { choices[promptnum] = JIIMstr1; paramvalues[promptnum].type = 'l'; paramvalues[promptnum].uval.ch.list = JIIMmethod; paramvalues[promptnum].uval.ch.vlen = 7; #ifdef RANDOM_RUN paramvalues[promptnum].uval.ch.llen = 4; #else paramvalues[promptnum].uval.ch.llen = 3; /* disable random run */ #endif paramvalues[promptnum++].uval.ch.val = major_method; choices[promptnum] = JIIMstr2; paramvalues[promptnum].type = 'l'; paramvalues[promptnum].uval.ch.list = JIIMleftright; paramvalues[promptnum].uval.ch.vlen = 5; paramvalues[promptnum].uval.ch.llen = 2; paramvalues[promptnum++].uval.ch.val = minor_method; } if((curtype==FORMULA || curtype==FFORMULA) && uses_ismand) { choices[promptnum] = (char far *)s_ismand; paramvalues[promptnum].type = 'y'; paramvalues[promptnum++].uval.ch.val = ismand?1:0; } if (caller /* command ? */ /* && (display3d > 0 || promptnum == 0)) */ && (display3d > 0)) { static FCODE msg[]={"Current type has no type-specific parameters"}; stopmsg(20,msg); goto gfp_exit; } if(julibrot) sprintf(msg,"Julibrot Parameters (orbit= %s)",juliorbitname); else sprintf(msg,"Parameters for fractal type %s",typename); if(bf_math == 0) { static FCODE pressf6[] = {"\n(Press "FK_F6" for corner parameters)"}; far_strcat(msg,pressf6); } else fkeymask = 0; scroll_row_status = 0; /* make sure we start at beginning of entry */ scroll_column_status = 0; for(;;) { oldhelpmode = helpmode; helpmode = curfractalspecific->helptext; i = fullscreen_prompt(msg,promptnum,choices,paramvalues,fkeymask,tstack); helpmode = oldhelpmode; if (i < 0) { if(julibrot) goto gfp_top; if (ret == 0) ret = -1; goto gfp_exit; } if (i != F6) break; if(bf_math == 0) if (get_corners() > 0) ret = 1; } promptnum = 0; for ( i = firstparm; i < numparams+firstparm; i++) { if(curtype == FORMULA || curtype == FFORMULA) if(paramnotused(i)) continue; if (oldparam[i] != paramvalues[promptnum].uval.dval) { param[i] = paramvalues[promptnum].uval.dval; ret = 1; } ++promptnum; } for ( i = 0; i < numtrig; i++) { if (paramvalues[promptnum].uval.ch.val != (int)trigndx[i]) { set_trig_array(i,trigfn[paramvalues[promptnum].uval.ch.val].name); ret = 1; } ++promptnum; } if(julibrot) { savespecific = curfractalspecific; curfractalspecific = jborbit; } long_i = curfractalspecific->orbit_bailout; if( long_i != 0 && curfractalspecific->calctype == StandardFractal && (curfractalspecific->flags & BAILTEST) ) { if (paramvalues[promptnum].uval.ch.val != (int)bailoutest) { bailoutest = (enum bailouts)paramvalues[promptnum].uval.ch.val; ret = 1; } promptnum++; } else bailoutest = Mod; setbailoutformula(bailoutest); if (long_i) { if (potparam[0] != 0.0 && potparam[2] != 0.0) promptnum++; else { bailout = paramvalues[promptnum++].uval.Lval; if (bailout != 0 && (bailout < 1 || bailout > 2100000000L)) bailout = oldbailout; if (bailout != oldbailout) ret = 1; promptnum++; } } if (julibrot) { mxmaxfp = paramvalues[promptnum++].uval.dval; mymaxfp = paramvalues[promptnum++].uval.dval; mxminfp = paramvalues[promptnum++].uval.dval; myminfp = paramvalues[promptnum++].uval.dval; zdots = paramvalues[promptnum++].uval.ival; juli3Dmode = paramvalues[promptnum++].uval.ch.val; eyesfp = (float)paramvalues[promptnum++].uval.dval; originfp = (float)paramvalues[promptnum++].uval.dval; depthfp = (float)paramvalues[promptnum++].uval.dval; heightfp = (float)paramvalues[promptnum++].uval.dval; widthfp = (float)paramvalues[promptnum++].uval.dval; distfp = (float)paramvalues[promptnum++].uval.dval; ret = 1; /* force new calc since not resumable anyway */ } if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP) { if (paramvalues[promptnum].uval.ch.val != major_method || paramvalues[promptnum+1].uval.ch.val != minor_method) ret = 1; major_method = (enum Major)paramvalues[promptnum++].uval.ch.val; minor_method = (enum Minor)paramvalues[promptnum++].uval.ch.val; } if((curtype==FORMULA || curtype==FFORMULA) && uses_ismand) { if (ismand != (short int)paramvalues[promptnum].uval.ch.val) { ismand = (short int)paramvalues[promptnum].uval.ch.val; ret = 1; } ++promptnum; } gfp_exit: curfractalspecific = &fractalspecific[fractype]; return(ret); } int find_extra_param(int type) { int i,ret,curtyp; ret = -1; i= -1; if(fractalspecific[type].flags&MORE) { while((curtyp=moreparams[++i].type) != type && curtyp != -1); if(curtyp == type) ret = i; } return(ret); } void load_params(int fractype) { int i, extra; for (i = 0; i < 4; ++i) { param[i] = fractalspecific[fractype].paramvalue[i]; if(fractype != CELLULAR && fractype != ANT) roundfloatd(¶m[i]); /* don't round cellular or ant */ } if((extra=find_extra_param(fractype)) > -1) for(i=0;iname, buf); choices[numentries]->point = name_offset; if (++numentries >= MAXENTRIES) { sprintf(buf, "Too many entries in file, first %ld used", MAXENTRIES); stopmsg(0, buf); break; } } } } else if (c == EOF || c == '\032') break; } return (numentries); } static long gfe_choose_entry(int type,char *title,char *filename,char *entryname) /* subrtn of get_file_entry, separated so that storage gets freed up */ { #ifdef XFRACT static FCODE o_instr[]={"Press "FK_F6" to select file, "FK_F2" for details, "FK_F4" to toggle sort "}; /* keep the above line length < 80 characters */ #else static FCODE o_instr[]={"Press "FK_F6" to select different file, "FK_F2" for details, "FK_F4" to toggle sort "}; #endif int numentries, i; char buf[101]; struct entryinfo far * far *choices; int far *attributes; void (*formatitem)(int, char *); int boxwidth,boxdepth,colwidth; static int dosort = 1; int options = 8; char far *instr; /* steal existing array for "choices" */ choices = (struct entryinfo far *far*)MK_FP(extraseg,0); /* leave room for details F2 */ choices = choices + (2048/sizeof(struct entryinfo far *far*)); choices[0] = (struct entryinfo far *)(choices + MAXENTRIES+1); attributes = (int far *)(choices[0] + MAXENTRIES+1); instr = (char far *)(attributes + MAXENTRIES +1); gfe_choices = &choices[0]; gfe_title = title; retry: attributes[0] = 1; for(i=1;iname); return(choices[i]->point); } static int check_gfe_key(int curkey,int choice) { char infhdg[60]; char far *infbuf; int in_scrolling_mode = 0; /* 1 if entry doesn't fit available space */ int top_line = 0; int left_column = 0; int i; int done = 0; int rewrite_infbuf = 0; /* if 1: rewrite the entry portion of screen */ char blanks[79]; /* used to clear the entry portion of screen */ memset(blanks, ' ', 78); blanks[78] = (char) 0; if (curkey == F6) return 0-F6; if (curkey == F4) return 0-F4; if (curkey == F2) { int widest_entry_line = 0; int lines_in_entry = 0; int comment = 0; int c = 0; int widthct = 0; infbuf = MK_FP(extraseg,0); fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET); while((c = fgetc(gfe_file)) != EOF && c != '\032') { if(c == ';') comment = 1; else if(c == '\n') { comment = 0; lines_in_entry++; widthct = -1; } else if (c == '\t') widthct += 7 - widthct % 8; else if ( c == '\r') continue; if(++widthct > widest_entry_line) widest_entry_line = widthct; if (c == '}' && !comment) { lines_in_entry++; break; } } if(c == EOF || c == '\032') { /* should never happen */ fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET); in_scrolling_mode = 0; } fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET); load_entry_text(gfe_file,infbuf, 17, 0, 0); if(lines_in_entry > 17 || widest_entry_line > 74) in_scrolling_mode = 1; strcpy(infhdg,gfe_title); strcat(infhdg," file entry:\n\n"); /* ... instead, call help with buffer? heading added */ stackscreen(); helptitle(); setattr(1,0,C_GENERAL_MED,24*80); textcbase = 0; putstring(2,1,C_GENERAL_HI,infhdg); textcbase = 2; /* left margin is 2 */ putstring(4,0,C_GENERAL_MED,infbuf); { static FCODE msg[] = {"\n\n Use "UPARR1", "DNARR1", "RTARR1", "LTARR1", PgUp, PgDown, Home, and End to scroll text\nAny other key to return to selection list"}; putstring(-1,0,C_GENERAL_LO,msg); } while(!done) { if(rewrite_infbuf) { rewrite_infbuf = 0; fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET); load_entry_text(gfe_file, infbuf, 17, top_line, left_column); for(i = 4; i < (lines_in_entry < 17 ? lines_in_entry + 4 : 21); i++) putstring(i,0,C_GENERAL_MED,blanks); putstring(4,0,C_GENERAL_MED,infbuf); } if((i = getakeynohelp()) == DOWN_ARROW || i == DOWN_ARROW_2 || i == UP_ARROW || i == UP_ARROW_2 || i == LEFT_ARROW || i == LEFT_ARROW_2 || i == RIGHT_ARROW || i == RIGHT_ARROW_2 || i == HOME || i == CTL_HOME || i == END || i == CTL_END || i == PAGE_UP || i == CTL_PAGE_UP || i == PAGE_DOWN || i == CTL_PAGE_DOWN) { switch(i) { case DOWN_ARROW: case DOWN_ARROW_2: /* down one line */ if(in_scrolling_mode && top_line < lines_in_entry - 17) { top_line++; rewrite_infbuf = 1; } break; case UP_ARROW: case UP_ARROW_2: /* up one line */ if(in_scrolling_mode && top_line > 0) { top_line--; rewrite_infbuf = 1; } break; case LEFT_ARROW: case LEFT_ARROW_2: /* left one column */ if(in_scrolling_mode && left_column > 0) { left_column--; rewrite_infbuf = 1; } break; case RIGHT_ARROW: case RIGHT_ARROW_2: /* right one column */ if(in_scrolling_mode && far_strchr(infbuf, '\021') != NULL) { left_column++; rewrite_infbuf = 1; } break; case PAGE_DOWN: case CTL_PAGE_DOWN: /* down 17 lines */ if(in_scrolling_mode && top_line < lines_in_entry - 17) { top_line += 17; if(top_line > lines_in_entry - 17) top_line = lines_in_entry - 17; rewrite_infbuf = 1; } break; case PAGE_UP: case CTL_PAGE_UP: /* up 17 lines */ if(in_scrolling_mode && top_line > 0) { top_line -= 17; if(top_line < 0) top_line = 0; rewrite_infbuf = 1; } break; case END: case CTL_END: /* to end of entry */ if(in_scrolling_mode) { top_line = lines_in_entry - 17; left_column = 0; rewrite_infbuf = 1; } break; case HOME: case CTL_HOME: /* to beginning of entry */ if(in_scrolling_mode) { top_line = left_column = 0; rewrite_infbuf = 1; } break; default: break; } } else done = 1; /* a key other than scrolling key was pressed */ } textcbase = 0; movecursor(25,80); unstackscreen(); } return 0; } static void load_entry_text( FILE *entfile, char far *buf, int maxlines, int startrow, int startcol) { /* Revised 12/14/96 by George Martin. Up to maxlines of an entry is copied to *buf starting from row "startrow", and skipping characters in each line up to "startcol". The terminating '\n' is deleted if maxlines is reached before the end of the entry. */ int linelen, i; int comment=0; int c = 0; int tabpos = 7 - (startcol % 8); if(maxlines <= 0) { /* no lines to get! */ *buf = (char) 0; return; } /*move down to starting row*/ for(i = 0; i < startrow; i++) { while((c=fgetc(entfile)) != '\n' && c != EOF && c != '\032') { if(c == ';') comment = 1; if(c == '}' && !comment) /* end of entry before start line */ break; /* this should never happen */ } if(c == '\n') comment = 0; else { /* reached end of file or end of entry */ *buf = (char) 0; return; } } /* write maxlines of entry */ while(maxlines-- > 0) { comment = linelen = i = c = 0; /* skip line up to startcol */ while (i++ < startcol && (c = fgetc(entfile)) != EOF && c != '\032') { if(c == ';') comment = 1; if(c == '}' && !comment) { /*reached end of entry*/ *buf = (char) 0; return; } if ( c == '\r') { i--; continue; } if(c == '\t') i += 7 - (i % 8); if(c == '\n') { /*need to insert '\n', even for short lines*/ *(buf++) = (char)c; break; } } if(c == EOF || c == '\032') { /* unexpected end of file */ *buf = (char) 0; return; } if(c == '\n') /* line is already completed */ continue; if(i > startcol) { /* can happen because of character */ while(i-- > startcol) { *(buf++) = ' '; linelen++; } } /*process rest of line into buf */ while ((c = fgetc(entfile)) != EOF && c != '\032') { if (c == ';') comment = 1; else if (c == '\n' || c == '\r') comment = 0; if (c != '\r') { if (c == '\t') { while ((linelen % 8) != tabpos && linelen < 75) { /* 76 wide max */ *(buf++) = ' '; ++linelen; } c = ' '; } if (c == '\n') { *(buf++) = '\n'; break; } if (++linelen > 75) { if (linelen == 76) *(buf++) = '\021'; } else *(buf++) = (char)c; if (c == '}' && !comment) { /*reached end of entry*/ *(buf) = (char) 0; return; } } } if(c == EOF || c == '\032') { /* unexpected end of file */ *buf = (char) 0; return; } } if(*(buf-1) == '\n') /* specified that buf will not end with a '\n' */ buf--; *buf = (char) 0; } static void format_parmfile_line(int choice,char *buf) { int c,i; char line[80]; fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET); while (getc(gfe_file) != '{') { } while ((c = getc(gfe_file)) == ' ' || c == '\t' || c == ';') { } i = 0; while (i < 56 && c != '\n' && c != '\r' && c != EOF && c != '\032') { line[i++] = (char)((c == '\t') ? ' ' : c); c = getc(gfe_file); } line[i] = 0; #ifndef XFRACT sprintf(buf,"%-20Fs%-56s",gfe_choices[choice]->name,line); #else sprintf(buf,"%-20s%-56s",gfe_choices[choice]->name,line); #endif } /* --------------------------------------------------------------------- */ int get_fract3d_params() /* prompt for 3D fractal parameters */ { int i,k,ret,oldhelpmode; static FCODE hdg[] = {"3D Parameters"}; static FCODE p1[] = {"X-axis rotation in degrees"}; static FCODE p2[] = {"Y-axis rotation in degrees"}; static FCODE p3[] = {"Z-axis rotation in degrees"}; static FCODE p4[] = {"Perspective distance [1 - 999, 0 for no persp]"}; static FCODE p5[] = {"X shift with perspective (positive = right)"}; static FCODE p6[] = {"Y shift with perspective (positive = up )"}; static FCODE p7[] = {"Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo,4=stereo pair)"}; struct fullscreenvalues uvalues[20]; char far *ifs3d_prompts[8]; stackscreen(); ifs3d_prompts[0] = p1; ifs3d_prompts[1] = p2; ifs3d_prompts[2] = p3; ifs3d_prompts[3] = p4; ifs3d_prompts[4] = p5; ifs3d_prompts[5] = p6; ifs3d_prompts[6] = p7; k = 0; uvalues[k].type = 'i'; uvalues[k++].uval.ival = XROT; uvalues[k].type = 'i'; uvalues[k++].uval.ival = YROT; uvalues[k].type = 'i'; uvalues[k++].uval.ival = ZROT; uvalues[k].type = 'i'; uvalues[k++].uval.ival = ZVIEWER; uvalues[k].type = 'i'; uvalues[k++].uval.ival = XSHIFT; uvalues[k].type = 'i'; uvalues[k++].uval.ival = YSHIFT; uvalues[k].type = 'i'; uvalues[k++].uval.ival = glassestype; oldhelpmode = helpmode; helpmode = HELP3DFRACT; i = fullscreen_prompt(hdg,k,ifs3d_prompts,uvalues,0,NULL); helpmode = oldhelpmode; if (i < 0) { ret = -1; goto get_f3d_exit; } ret = k = 0; XROT = uvalues[k++].uval.ival; YROT = uvalues[k++].uval.ival; ZROT = uvalues[k++].uval.ival; ZVIEWER = uvalues[k++].uval.ival; XSHIFT = uvalues[k++].uval.ival; YSHIFT = uvalues[k++].uval.ival; glassestype = uvalues[k++].uval.ival; if (glassestype < 0 || glassestype > 4) glassestype = 0; if (glassestype) if (get_funny_glasses_params() || check_mapfile()) ret = -1; get_f3d_exit: unstackscreen(); return(ret); } /* --------------------------------------------------------------------- */ /* These macros streamline the "save near space" campaign */ #define LOADPROMPTS3D(X) {\ static FCODE tmp[] = { X };\ prompts3d[++k]= tmp;\ } #define LOADPROMPTSCHOICES(X) {\ static FCODE tmp[] = { X };\ choices[k++]= tmp;\ } int get_3d_params() /* prompt for 3D parameters */ { static FCODE hdg[]={"3D Mode Selection"}; static FCODE hdg1[]={"Select 3D Fill Type"}; char far *choices[11]; int attributes[21]; int sphere; char far *s; static FCODE s1[] = {"Sphere 3D Parameters\n\ Sphere is on its side; North pole to right\n\ Long. 180 is top, 0 is bottom; Lat. -90 is left, 90 is right"}; static FCODE s2[]={"Planar 3D Parameters\n\ Pre-rotation X axis is screen top; Y axis is left side\n\ Pre-rotation Z axis is coming at you out of the screen!"}; char far *prompts3d[21]; struct fullscreenvalues uvalues[21]; int i, k; int oldhelpmode; #ifdef WINFRACT { extern int far wintext_textmode; if (wintext_textmode != 2) /* are we in textmode? */ return(0); /* no - prompts are already handled */ } #endif #ifdef XFRACT stackscreen(); #endif restart_1: if (Targa_Out && overlay3d) Targa_Overlay = 1; k= -1; LOADPROMPTS3D("Preview Mode?"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = preview; LOADPROMPTS3D(" Show Box?"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = showbox; LOADPROMPTS3D("Coarseness, preview/grid/ray (in y dir)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = previewfactor; LOADPROMPTS3D("Spherical Projection?"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = sphere = SPHERE; LOADPROMPTS3D("Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,"); uvalues[k].type = 'i'; uvalues[k].uval.ival = glassestype; LOADPROMPTS3D(" 3=photo,4=stereo pair)"); uvalues[k].type = '*'; LOADPROMPTS3D("Ray trace out? (0=No, 1=DKB/POVRay, 2=VIVID, 3=RAW,"); uvalues[k].type = 'i'; uvalues[k].uval.ival = RAY; LOADPROMPTS3D(" 4=MTV, 5=RAYSHADE, 6=ACROSPIN, 7=DXF)"); uvalues[k].type = '*'; LOADPROMPTS3D(" Brief output?"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = BRIEF; check_writefile(ray_name,".ray"); LOADPROMPTS3D(" Output File Name"); uvalues[k].type = 's'; strcpy(uvalues[k].uval.sval,ray_name); LOADPROMPTS3D("Targa output?"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = Targa_Out; LOADPROMPTS3D("Use grayscale value for depth? (if \"no\" uses color number)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = grayflag; oldhelpmode = helpmode; helpmode = HELP3DMODE; k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL); helpmode = oldhelpmode; if (k < 0) { #ifdef XFRACT unstackscreen(); #endif return(-1); } k=0; preview = (char)uvalues[k++].uval.ch.val; showbox = (char)uvalues[k++].uval.ch.val; previewfactor = uvalues[k++].uval.ival; sphere = uvalues[k++].uval.ch.val; glassestype = uvalues[k++].uval.ival; k++; RAY = uvalues[k++].uval.ival; k++; { static FCODE msg[] = { "DKB/POV-Ray output is obsolete but still works. See \"Ray Tracing Output\" in\n\ the online documentation."}; if(RAY == 1) stopmsg(0,msg); } BRIEF = uvalues[k++].uval.ch.val; strcpy(ray_name,uvalues[k++].uval.sval); Targa_Out = uvalues[k++].uval.ch.val; grayflag = (char)uvalues[k++].uval.ch.val; /* check ranges */ if(previewfactor < 2) previewfactor = 2; if(previewfactor > 2000) previewfactor = 2000; if(sphere && !SPHERE) { SPHERE = TRUE; set_3d_defaults(); } else if(!sphere && SPHERE) { SPHERE = FALSE; set_3d_defaults(); } if(glassestype < 0) glassestype = 0; if(glassestype > 4) glassestype = 4; if(glassestype) whichimage = 1; if (RAY < 0) RAY = 0; if (RAY > 7) RAY = 7; if (!RAY) { k = 0; LOADPROMPTSCHOICES("make a surface grid"); LOADPROMPTSCHOICES("just draw the points"); LOADPROMPTSCHOICES("connect the dots (wire frame)"); LOADPROMPTSCHOICES("surface fill (colors interpolated)"); LOADPROMPTSCHOICES("surface fill (colors not interpolated)"); LOADPROMPTSCHOICES("solid fill (bars up from \"ground\")"); if(SPHERE) { LOADPROMPTSCHOICES("light source"); } else { LOADPROMPTSCHOICES("light source before transformation"); LOADPROMPTSCHOICES("light source after transformation"); } for (i = 0; i < k; ++i) attributes[i] = 1; helpmode = HELP3DFILL; i = fullscreen_choice(CHOICEHELP,hdg1,NULL,NULL,k,(char far * far *)choices,attributes, 0,0,0,FILLTYPE+1,NULL,NULL,NULL,NULL); helpmode = oldhelpmode; if (i < 0) goto restart_1; FILLTYPE = i-1; if(glassestype) { if(get_funny_glasses_params()) goto restart_1; } if (check_mapfile()) goto restart_1; } restart_3: if(SPHERE) { k = -1; LOADPROMPTS3D("Longitude start (degrees)"); LOADPROMPTS3D("Longitude stop (degrees)"); LOADPROMPTS3D("Latitude start (degrees)"); LOADPROMPTS3D("Latitude stop (degrees)"); LOADPROMPTS3D("Radius scaling factor in pct"); } else { k = -1; if (!RAY) { LOADPROMPTS3D("X-axis rotation in degrees"); LOADPROMPTS3D("Y-axis rotation in degrees"); LOADPROMPTS3D("Z-axis rotation in degrees"); } LOADPROMPTS3D("X-axis scaling factor in pct"); LOADPROMPTS3D("Y-axis scaling factor in pct"); } k = -1; if (!(RAY && !SPHERE)) { uvalues[++k].uval.ival = XROT ; uvalues[k].type = 'i'; uvalues[++k].uval.ival = YROT ; uvalues[k].type = 'i'; uvalues[++k].uval.ival = ZROT ; uvalues[k].type = 'i'; } uvalues[++k].uval.ival = XSCALE ; uvalues[k].type = 'i'; uvalues[++k].uval.ival = YSCALE ; uvalues[k].type = 'i'; LOADPROMPTS3D("Surface Roughness scaling factor in pct"); uvalues[k].type = 'i'; uvalues[k].uval.ival = ROUGH ; LOADPROMPTS3D("'Water Level' (minimum color value)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = WATERLINE ; if(!RAY) { LOADPROMPTS3D("Perspective distance [1 - 999, 0 for no persp])"); uvalues[k].type = 'i'; uvalues[k].uval.ival = ZVIEWER ; LOADPROMPTS3D("X shift with perspective (positive = right)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = XSHIFT ; LOADPROMPTS3D("Y shift with perspective (positive = up )"); uvalues[k].type = 'i'; uvalues[k].uval.ival = YSHIFT ; LOADPROMPTS3D("Image non-perspective X adjust (positive = right)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = xtrans ; LOADPROMPTS3D("Image non-perspective Y adjust (positive = up)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = ytrans ; LOADPROMPTS3D("First transparent color"); uvalues[k].type = 'i'; uvalues[k].uval.ival = transparent[0]; LOADPROMPTS3D("Last transparent color"); uvalues[k].type = 'i'; uvalues[k].uval.ival = transparent[1]; } LOADPROMPTS3D("Randomize Colors (0 - 7, '0' disables)"); uvalues[k].type = 'i'; uvalues[k++].uval.ival = RANDOMIZE; if (SPHERE) s = s1; else s = s2; helpmode = HELP3DPARMS; k = fullscreen_prompt(s,k,prompts3d,uvalues,0,NULL); helpmode = oldhelpmode; if (k < 0) goto restart_1; k = 0; if (!(RAY && !SPHERE)) { XROT = uvalues[k++].uval.ival; YROT = uvalues[k++].uval.ival; ZROT = uvalues[k++].uval.ival; } XSCALE = uvalues[k++].uval.ival; YSCALE = uvalues[k++].uval.ival; ROUGH = uvalues[k++].uval.ival; WATERLINE = uvalues[k++].uval.ival; if (!RAY) { ZVIEWER = uvalues[k++].uval.ival; XSHIFT = uvalues[k++].uval.ival; YSHIFT = uvalues[k++].uval.ival; xtrans = uvalues[k++].uval.ival; ytrans = uvalues[k++].uval.ival; transparent[0] = uvalues[k++].uval.ival; transparent[1] = uvalues[k++].uval.ival; } RANDOMIZE = uvalues[k++].uval.ival; if (RANDOMIZE >= 7) RANDOMIZE = 7; if (RANDOMIZE <= 0) RANDOMIZE = 0; if ((Targa_Out || ILLUMINE || RAY)) if(get_light_params()) goto restart_3; #ifdef XFRACT unstackscreen(); #endif return(0); } /* --------------------------------------------------------------------- */ static int get_light_params() { static FCODE hdg[]={"Light Source Parameters"}; char far *prompts3d[13]; struct fullscreenvalues uvalues[13]; int k; int oldhelpmode; /* defaults go here */ k = -1; if (ILLUMINE || RAY) { LOADPROMPTS3D("X value light vector"); uvalues[k].type = 'i'; uvalues[k].uval.ival = XLIGHT ; LOADPROMPTS3D("Y value light vector"); uvalues[k].type = 'i'; uvalues[k].uval.ival = YLIGHT ; LOADPROMPTS3D("Z value light vector"); uvalues[k].type = 'i'; uvalues[k].uval.ival = ZLIGHT ; if (!RAY) { LOADPROMPTS3D("Light Source Smoothing Factor"); uvalues[k].type = 'i'; uvalues[k].uval.ival = LIGHTAVG ; LOADPROMPTS3D("Ambient"); uvalues[k].type = 'i'; uvalues[k].uval.ival = Ambient; } } if (Targa_Out && !RAY) { LOADPROMPTS3D("Haze Factor (0 - 100, '0' disables)"); uvalues[k].type = 'i'; uvalues[k].uval.ival= haze; if (!Targa_Overlay) check_writefile(light_name,".tga"); LOADPROMPTS3D("Targa File Name (Assume .tga)"); uvalues[k].type = 's'; strcpy(uvalues[k].uval.sval,light_name); LOADPROMPTS3D("Back Ground Color (0 - 255)"); uvalues[k].type = '*'; LOADPROMPTS3D(" Red"); uvalues[k].type = 'i'; uvalues[k].uval.ival = (int)back_color[0]; LOADPROMPTS3D(" Green"); uvalues[k].type = 'i'; uvalues[k].uval.ival = (int)back_color[1]; LOADPROMPTS3D(" Blue"); uvalues[k].type = 'i'; uvalues[k].uval.ival = (int)back_color[2]; LOADPROMPTS3D("Overlay Targa File? (Y/N)"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = Targa_Overlay; } LOADPROMPTS3D(""); oldhelpmode = helpmode; helpmode = HELP3DLIGHT; k = fullscreen_prompt(hdg,k,prompts3d,uvalues,0,NULL); helpmode = oldhelpmode; if (k < 0) return(-1); k = 0; if (ILLUMINE) { XLIGHT = uvalues[k++].uval.ival; YLIGHT = uvalues[k++].uval.ival; ZLIGHT = uvalues[k++].uval.ival; if (!RAY) { LIGHTAVG = uvalues[k++].uval.ival; Ambient = uvalues[k++].uval.ival; if (Ambient >= 100) Ambient = 100; if (Ambient <= 0) Ambient = 0; } } if (Targa_Out && !RAY) { haze = uvalues[k++].uval.ival; if (haze >= 100) haze = 100; if (haze <= 0) haze = 0; strcpy(light_name,uvalues[k++].uval.sval); /* In case light_name conflicts with an existing name it is checked again in line3d */ k++; back_color[0] = (char)(uvalues[k++].uval.ival % 255); back_color[1] = (char)(uvalues[k++].uval.ival % 255); back_color[2] = (char)(uvalues[k++].uval.ival % 255); Targa_Overlay = uvalues[k].uval.ch.val; } return(0); } /* --------------------------------------------------------------------- */ static int check_mapfile() { int askflag = 0; int i,oldhelpmode; if(dontreadcolor) return(0); strcpy(temp1,"*"); if (mapset) strcpy(temp1,MAP_name); if (!(glassestype == 1 || glassestype == 2)) askflag = 1; else merge_pathnames(temp1,funnyglasses_map_name,0); for(;;) { if (askflag) { static FCODE msg[] = {"\ Enter name of .MAP file to use,\n\ or '*' to use palette from the image to be loaded."}; oldhelpmode = helpmode; helpmode = -1; i = field_prompt(0,msg,NULL,temp1,60,NULL); helpmode = oldhelpmode; if (i < 0) return(-1); if (temp1[0] == '*') { mapset = 0; break; } } memcpy(olddacbox,dacbox,256*3); /* save the DAC */ i = ValidateLuts(temp1); memcpy(dacbox,olddacbox,256*3); /* restore the DAC */ if (i != 0) { /* Oops, somethings wrong */ askflag = 1; continue; } mapset = 1; merge_pathnames(MAP_name,temp1,0); break; } return(0); } static int get_funny_glasses_params() { static FCODE hdg[]={"Funny Glasses Parameters"}; char far *prompts3d[10]; struct fullscreenvalues uvalues[10]; int k; int oldhelpmode; /* defaults */ if(ZVIEWER == 0) ZVIEWER = 150; if(eyeseparation == 0) { if(fractype==IFS3D || fractype==LLORENZ3D || fractype==FPLORENZ3D) { eyeseparation = 2; xadjust = -2; } else { eyeseparation = 3; xadjust = 0; } } if(glassestype == 1) strcpy(funnyglasses_map_name,Glasses1Map); else if(glassestype == 2) { if(FILLTYPE == -1) strcpy(funnyglasses_map_name,"grid.map"); else { strcpy(funnyglasses_map_name,Glasses1Map); funnyglasses_map_name[7] = '2'; } } k = -1; LOADPROMPTS3D("Interocular distance (as % of screen)"); uvalues[k].type = 'i'; uvalues[k].uval.ival= eyeseparation; LOADPROMPTS3D("Convergence adjust (positive = spread greater)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = xadjust; LOADPROMPTS3D("Left red image crop (% of screen)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = red_crop_left; LOADPROMPTS3D("Right red image crop (% of screen)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = red_crop_right; LOADPROMPTS3D("Left blue image crop (% of screen)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = blue_crop_left; LOADPROMPTS3D("Right blue image crop (% of screen)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = blue_crop_right; LOADPROMPTS3D("Red brightness factor (%)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = red_bright; LOADPROMPTS3D("Blue brightness factor (%)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = blue_bright; if(glassestype == 1 || glassestype == 2) { LOADPROMPTS3D("Map File name"); uvalues[k].type = 's'; strcpy(uvalues[k].uval.sval,funnyglasses_map_name); } oldhelpmode = helpmode; helpmode = HELP3DGLASSES; k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL); helpmode = oldhelpmode; if (k < 0) return(-1); k = 0; eyeseparation = uvalues[k++].uval.ival; xadjust = uvalues[k++].uval.ival; red_crop_left = uvalues[k++].uval.ival; red_crop_right = uvalues[k++].uval.ival; blue_crop_left = uvalues[k++].uval.ival; blue_crop_right = uvalues[k++].uval.ival; red_bright = uvalues[k++].uval.ival; blue_bright = uvalues[k++].uval.ival; if(glassestype == 1 || glassestype == 2) strcpy(funnyglasses_map_name,uvalues[k].uval.sval); return(0); } void setbailoutformula(enum bailouts test) { switch(test) { case Mod: default:{ if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpMODbailout; else floatbailout = (int (near *)(void))fpMODbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lMODbailout; else longbailout = (int (near *)(void))asmlMODbailout; bignumbailout = (int (near *)(void))bnMODbailout; bigfltbailout = (int (near *)(void))bfMODbailout; break;} case Real: { if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpREALbailout; else floatbailout = (int (near *)(void))fpREALbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lREALbailout; else longbailout = (int (near *)(void))asmlREALbailout; bignumbailout = (int (near *)(void))bnREALbailout; bigfltbailout = (int (near *)(void))bfREALbailout; break;} case Imag:{ if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpIMAGbailout; else floatbailout = (int (near *)(void))fpIMAGbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lIMAGbailout; else longbailout = (int (near *)(void))asmlIMAGbailout; bignumbailout = (int (near *)(void))bnIMAGbailout; bigfltbailout = (int (near *)(void))bfIMAGbailout; break;} case Or:{ if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpORbailout; else floatbailout = (int (near *)(void))fpORbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lORbailout; else longbailout = (int (near *)(void))asmlORbailout; bignumbailout = (int (near *)(void))bnORbailout; bigfltbailout = (int (near *)(void))bfORbailout; break;} case And:{ if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpANDbailout; else floatbailout = (int (near *)(void))fpANDbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lANDbailout; else longbailout = (int (near *)(void))asmlANDbailout; bignumbailout = (int (near *)(void))bnANDbailout; bigfltbailout = (int (near *)(void))bfANDbailout; break;} case Manh:{ if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpMANHbailout; else floatbailout = (int (near *)(void))fpMANHbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lMANHbailout; else longbailout = (int (near *)(void))asmlMANHbailout; bignumbailout = (int (near *)(void))bnMANHbailout; bigfltbailout = (int (near *)(void))bfMANHbailout; break;} case Manr:{ if (fpu >= 287 && debugflag != 72) /* Fast 287 math */ floatbailout = (int (near *)(void))asmfpMANRbailout; else floatbailout = (int (near *)(void))fpMANRbailout; if (cpu >=386 && debugflag != 8088) /* Fast 386 math */ longbailout = (int (near *)(void))asm386lMANRbailout; else longbailout = (int (near *)(void))asmlMANRbailout; bignumbailout = (int (near *)(void))bnMANRbailout; bigfltbailout = (int (near *)(void))bfMANRbailout; break;} } } xfractint-20.4.10.orig/common/encoder.c0000644000000000000000000011071310762306640014567 0ustar /* encoder.c - GIF Encoder and associated routines */ #include #include #ifndef XFRACT #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" static int compress(int rowlimit); static int _fastcall shftwrite(BYTE far * color, int numcolors); static int _fastcall extend_blk_len(int datalen); static int _fastcall put_extend_blk(int block_id, int block_len, char far * block_data); static int _fastcall store_item_name(char *); static void _fastcall setup_save_info(struct fractal_info far * save_info); /* Save-To-Disk Routines (GIF) The following routines perform the GIF encoding when the 's' key is pressed. The compression logic in this file has been replaced by the classic UNIX compress code. We have extensively modified the sources to fit Fractint's needs, but have left the original credits where they appear. Thanks to the original authors for making available these classic and reliable sources. Of course, they are not responsible for all the changes we have made to integrate their sources into Fractint. MEMORY ALLOCATION There are two large arrays: long htab[HSIZE] (5003*4 = 20012 bytes) unsigned short codetab[HSIZE] (5003*2 = 10006 bytes) At the moment these arrays reuse extraseg and strlocn, respectively. */ static int numsaves = 0; /* For adjusting 'save-to-disk' filenames */ static FILE *g_outfile; static int last_colorbar; static int save16bit; static int outcolor1s, outcolor2s; static int startbits; static BFCODE paletteBW[] = { /* B&W palette */ 0, 0, 0, 63, 63, 63, }; #ifndef XFRACT static BFCODE paletteCGA[] = { /* 4-color (CGA) palette */ 0, 0, 0, 21, 63, 63, 63, 21, 63, 63, 63, 63, }; #endif static BFCODE paletteEGA[] = { /* 16-color (EGA/CGA) pal */ 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42, 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42, 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63, 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63, }; int savetodisk(char *filename) /* save-to-disk routine */ { char tmpmsg[41]; /* before openfile in case of overrun */ char openfile[FILE_MAX_PATH], openfiletype[10]; char tmpfile[FILE_MAX_PATH]; char *period; int newfile; int i, j, interrupted, outcolor1, outcolor2; restart: save16bit = disk16bit; if (gif87a_flag) /* not storing non-standard fractal info */ save16bit = 0; strcpy(openfile, filename); /* decode and open the filename */ strcpy(openfiletype, DEFAULTFRACTALTYPE); /* determine the file * extension */ if (save16bit) strcpy(openfiletype, ".pot"); if ((period = has_ext(openfile)) != NULL) { strcpy(openfiletype, period); *period = 0; } if (resave_flag != 1) updatesavename(filename); /* for next time */ strcat(openfile, openfiletype); strcpy(tmpfile, openfile); if (access(openfile, 0) != 0)/* file doesn't exist */ newfile = 1; else { /* file already exists */ static FCODE fractint_tmp[] = {"fractint.tmp"}; if (overwrite == 0) { if (resave_flag == 0) goto restart; if (started_resaves == 0) { /* first save of a savetime set */ updatesavename(filename); goto restart; } } if (access(openfile, 2) != 0) { sprintf(tmpmsg, s_cantwrite, openfile); stopmsg(0, tmpmsg); return -1; } newfile = 0; i = strlen(tmpfile); while (--i >= 0 && tmpfile[i] != SLASHC) tmpfile[i] = 0; far_strcat(tmpfile, fractint_tmp); } started_resaves = (resave_flag == 1) ? 1 : 0; if (resave_flag == 2) /* final save of savetime set? */ resave_flag = 0; if ((g_outfile = fopen(tmpfile, "wb")) == NULL) { sprintf(tmpmsg, s_cantcreate, tmpfile); stopmsg(0, tmpmsg); return -1; } if (dotmode == 11) { /* disk-video */ char buf[61]; extract_filename(tmpmsg, openfile); sprintf(buf, "Saving %s", tmpmsg); dvid_status(1, buf); } #ifdef XFRACT else #ifdef NCURSES { putstring(3, 0, 0, "Saving to:"); putstring(4, 0, 0, openfile); putstring(5, 0, 0, " "); } #else { char cmd[256]; sprintf(cmd, "Saving to: %s", openfile); xpopup(cmd); usleep(300000); } #endif #endif busy = 1; if (debugflag != 200) interrupted = encoder(); else interrupted = timer(2, NULL); /* invoke encoder() via timer */ busy = 0; fclose(g_outfile); if (interrupted) { static FCODE s_delete[] = {"delete the file,\ncontinue to keep the partial image."}; static FCODE s_retain[] = {"retain the original file,\ncontinue to replace original with new partial image."}; char buf[200]; sprintf(buf, "Save of %s interrupted.\nCancel to ", openfile); if (newfile) far_strcat(buf,s_delete); else far_strcat(buf,s_retain); interrupted = 1; if (stopmsg(2, buf) < 0) { interrupted = -1; unlink(tmpfile); } } if (newfile == 0 && interrupted >= 0) { /* replace the real file */ unlink(openfile); /* success assumed since we checked */ rename(tmpfile, openfile);/* earlier with access */ } if (dotmode != 11) { /* suppress this on disk-video */ if (active_system == 0) { /* no bars in Windows/X11 (most) versions */ outcolor1 = outcolor1s; outcolor2 = outcolor2s; for (j = 0; j <= last_colorbar; j++) { if ((j & 4) == 0) { if (++outcolor1 >= colors) outcolor1 = 0; if (++outcolor2 >= colors) outcolor2 = 0; } for (i = 0; 250 * i < xdots; i++) { /* clear vert status bars */ putcolor(i, j, getcolor(i, j) ^ outcolor1); putcolor(xdots - 1 - i, j, getcolor(xdots - 1 - i, j) ^ outcolor2); } } } #ifdef NCURSES putstring(5, 0, 0, "Saving done\n"); #endif } else /* disk-video */ dvid_status(1, ""); if (interrupted) { static FCODE msg[] = {" *interrupted* save "}; texttempmsg(msg); if (initbatch >= 1) initbatch = 3; /* if batch mode, set error level */ return -1; } if (timedsave == 0) { buzzer(0); if (initbatch == 0) { extract_filename(tmpfile, openfile); sprintf(tmpmsg, " File saved as %s ", tmpfile); texttempmsg(tmpmsg); } } if (initsavetime < 0) goodbye(); return 0; } int encoder() { int i, width, rowlimit, interrupted; BYTE bitsperpixel, x; struct fractal_info save_info; if (initbatch) /* flush any impending keystrokes */ while (keypressed()) getakey(); setup_save_info(&save_info); #ifndef XFRACT bitsperpixel = 0; /* calculate bits / pixel */ for (i = colors; i >= 2; i /= 2) bitsperpixel++; startbits = bitsperpixel + 1;/* start coding with this many bits */ if (colors == 2) startbits++; /* B&W Klooge */ #else if (colors == 2) { bitsperpixel = 1; startbits = 3; } else { bitsperpixel = 8; startbits = 9; } #endif if (gif87a_flag == 1) { if (fwrite("GIF87a", 6, 1, g_outfile) != 1) goto oops; /* old GIF Signature */ } else { if (fwrite("GIF89a", 6, 1, g_outfile) != 1) goto oops; /* new GIF Signature */ } width = xdots; rowlimit = ydots; if (save16bit) { /* pot16bit info is stored as: file: double width rows, right side * of row is low 8 bits diskvid: ydots rows of colors followed by ydots * rows of low 8 bits decoder: returns (row of color info then row of * low 8 bits) * ydots */ rowlimit <<= 1; width <<= 1; } if (write2(&width, 2, 1, g_outfile) != 1) goto oops; /* screen descriptor */ if (write2(&ydots, 2, 1, g_outfile) != 1) goto oops; x = (BYTE) (128 + ((6 - 1) << 4) + (bitsperpixel - 1)); /* color resolution == 6 * bits worth */ if (write1(&x, 1, 1, g_outfile) != 1) goto oops; if (fputc(0, g_outfile) != 0) goto oops; /* background color */ i = 0; if (viewwindow /* less than full screen? */ && (viewxdots == 0 || viewydots == 0)) /* and we picked the dots? */ i = (int) (((double) sydots / (double) sxdots) * 64.0 / screenaspect - 14.5); else /* must risk loss of precision if numbers low */ i = (int) ((((double) ydots / (double) xdots) / finalaspectratio) * 64 - 14.5); if (i < 1) i = 1; if (i > 255) i = 255; if (gif87a_flag) i = 0; /* for some decoders which can't handle * aspect */ if (fputc(i, g_outfile) != i) goto oops; /* pixel aspect ratio */ #ifndef XFRACT if (colors == 256) { /* write out the 256-color palette */ if (gotrealdac) { /* got a DAC - must be a VGA */ if (!shftwrite((BYTE far *) dacbox, colors)) goto oops; #else if (colors > 2) { if (gotrealdac || fake_lut) { /* got a DAC - must be a VGA */ if (!shftwrite((BYTE far *) dacbox, 256)) goto oops; #endif } else { /* uh oh - better fake it */ for (i = 0; i < 256; i += 16) if (!shftwrite((BYTE far *)paletteEGA, 16)) goto oops; } } if (colors == 2) { /* write out the B&W palette */ if (!shftwrite((BYTE far *)paletteBW, colors)) goto oops; } #ifndef XFRACT if (colors == 4) { /* write out the CGA palette */ if (!shftwrite((BYTE far *)paletteCGA, colors)) goto oops; } if (colors == 16) { /* Either EGA or VGA */ if (gotrealdac) { if (!shftwrite((BYTE *) dacbox, colors)) goto oops; } else { /* no DAC - must be an EGA */ if (!shftwrite((BYTE far *)paletteEGA, colors)) goto oops; } } #endif if (fwrite(",", 1, 1, g_outfile) != 1) goto oops; /* Image Descriptor */ i = 0; if (write2(&i, 2, 1, g_outfile) != 1) goto oops; if (write2(&i, 2, 1, g_outfile) != 1) goto oops; if (write2(&width, 2, 1, g_outfile) != 1) goto oops; if (write2(&ydots, 2, 1, g_outfile) != 1) goto oops; if (write1(&i, 1, 1, g_outfile) != 1) goto oops; bitsperpixel = (BYTE) (startbits - 1); if (write1(&bitsperpixel, 1, 1, g_outfile) != 1) goto oops; interrupted = compress(rowlimit); if(ferror(g_outfile)) goto oops; if (fputc(0, g_outfile) != 0) goto oops; if (gif87a_flag == 0) { /* store non-standard fractal info */ /* loadfile.c has notes about extension block structure */ if (interrupted) save_info.calc_status = 0; /* partial save is not resumable */ save_info.tot_extend_len = 0; if (resume_info != 0 && save_info.calc_status == 2) { /* resume info block, 002 */ save_info.tot_extend_len += extend_blk_len(resume_len); MoveFromMemory((BYTE *)block,(U16)1,(long)resume_len,0,resume_info); if (!put_extend_blk(2, resume_len, (char far *)block)) goto oops; } /* save_info.fractal_type gets modified in setup_save_info() in float only version, so we need to use fractype. JCO 06JAN01 */ /* if (save_info.fractal_type == FORMULA || save_info.fractal_type == FFORMULA) */ if (fractype == FORMULA || fractype == FFORMULA) save_info.tot_extend_len += store_item_name(FormName); /* if (save_info.fractal_type == LSYSTEM) */ if (fractype == LSYSTEM) save_info.tot_extend_len += store_item_name(LName); /* if (save_info.fractal_type == IFS || save_info.fractal_type == IFS3D) */ if (fractype == IFS || fractype == IFS3D) save_info.tot_extend_len += store_item_name(IFSName); if (display3d <= 0 && rangeslen) { /* ranges block, 004 */ save_info.tot_extend_len += extend_blk_len(rangeslen * 2); #ifdef XFRACT fix_ranges(ranges, rangeslen, 0); #endif if (!put_extend_blk(4, rangeslen * 2, (char far *) ranges)) goto oops; } /* Extended parameters block 005 */ if (bf_math) { save_info.tot_extend_len += extend_blk_len(22 * (bflength + 2)); /* note: this assumes variables allocated in order starting with * bfxmin in init_bf2() in BIGNUM.C */ if (!put_extend_blk(5, 22 * (bflength + 2), (char far *) bfxmin)) goto oops; } /* Extended parameters block 006 */ if (evolving&1) { struct evolution_info esave_info; int i; struct evolution_info resume_e_info; GENEBASE gene[NUMGENES]; MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); if (evolve_handle == 0 || calc_status == 4) { esave_info.paramrangex = paramrangex; esave_info.paramrangey = paramrangey; esave_info.opx = opx; esave_info.opy = opy; esave_info.odpx = (short)odpx; esave_info.odpy = (short)odpy; esave_info.px = (short)px; esave_info.py = (short)py; esave_info.sxoffs = (short)sxoffs; esave_info.syoffs = (short)syoffs; esave_info.xdots = (short)xdots; esave_info.ydots = (short)ydots; esave_info.gridsz = (short)gridsz; esave_info.evolving = (short)evolving; esave_info.this_gen_rseed = (unsigned short)this_gen_rseed; esave_info.fiddlefactor = fiddlefactor; esave_info.ecount = (short) (gridsz * gridsz); /* flag for done */ } else { /* we will need the resuming information */ MoveFromMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle); esave_info.paramrangex = resume_e_info.paramrangex; esave_info.paramrangey = resume_e_info.paramrangey; esave_info.opx = resume_e_info.opx; esave_info.opy = resume_e_info.opy; esave_info.odpx = (short)resume_e_info.odpx; esave_info.odpy = (short)resume_e_info.odpy; esave_info.px = (short)resume_e_info.px; esave_info.py = (short)resume_e_info.py; esave_info.sxoffs = (short)resume_e_info.sxoffs; esave_info.syoffs = (short)resume_e_info.syoffs; esave_info.xdots = (short)resume_e_info.xdots; esave_info.ydots = (short)resume_e_info.ydots; esave_info.gridsz = (short)resume_e_info.gridsz; esave_info.evolving = (short)resume_e_info.evolving; esave_info.this_gen_rseed = (unsigned short)resume_e_info.this_gen_rseed; esave_info.fiddlefactor = resume_e_info.fiddlefactor; esave_info.ecount = resume_e_info.ecount; } for (i = 0; i < NUMGENES; i++) esave_info.mutate[i] = (short)gene[i].mutate; for (i = 0; i < sizeof(esave_info.future) / sizeof(short); i++) esave_info.future[i] = 0; /* some XFRACT logic for the doubles needed here */ #ifdef XFRACT decode_evolver_info(&esave_info, 0); #endif /* evolution info block, 006 */ save_info.tot_extend_len += extend_blk_len(sizeof(esave_info)); if (!put_extend_blk(6, sizeof(esave_info), (char far *) &esave_info)) goto oops; } /* Extended parameters block 007 */ if (stdcalcmode == 'o') { struct orbits_info osave_info; int i; osave_info.oxmin = oxmin; osave_info.oxmax = oxmax; osave_info.oymin = oymin; osave_info.oymax = oymax; osave_info.ox3rd = ox3rd; osave_info.oy3rd = oy3rd; osave_info.keep_scrn_coords= (short)keep_scrn_coords; osave_info.drawmode = drawmode; for (i = 0; i < sizeof(osave_info.future) / sizeof(short); i++) osave_info.future[i] = 0; /* some XFRACT logic for the doubles needed here */ #ifdef XFRACT decode_orbits_info(&osave_info, 0); #endif /* orbits info block, 007 */ save_info.tot_extend_len += extend_blk_len(sizeof(osave_info)); if (!put_extend_blk(7, sizeof(osave_info), (char far *) &osave_info)) goto oops; } /* main and last block, 001 */ save_info.tot_extend_len += extend_blk_len(FRACTAL_INFO_SIZE); #ifdef XFRACT decode_fractal_info(&save_info, 0); #endif if (!put_extend_blk(1, FRACTAL_INFO_SIZE, (char far *) &save_info)) { goto oops; } } if (fwrite(";", 1, 1, g_outfile) != 1) goto oops; /* GIF Terminator */ return (interrupted); oops: { static FCODE msg[] = {"Error Writing to disk (Disk full?)"}; fflush(g_outfile); stopmsg(0,msg); return 1; } } /* shift IBM colors to GIF */ static int _fastcall shftwrite(BYTE far * color, int numcolors) { BYTE thiscolor; int i, j; for (i = 0; i < numcolors; i++) for (j = 0; j < 3; j++) { thiscolor = color[3 * i + j]; thiscolor = (BYTE) (thiscolor << 2); thiscolor = (BYTE) (thiscolor + (BYTE) (thiscolor >> 6)); if (fputc(thiscolor, g_outfile) != (int) thiscolor) return (0); } return (1); } static int _fastcall extend_blk_len(int datalen) { return (datalen + (datalen + 254) / 255 + 15); /* data + 1.per.block + 14 for id + 1 for null at end */ } static int _fastcall put_extend_blk(int block_id, int block_len, char far * block_data) { int i, j; char header[15]; strcpy(header, "!\377\013fractint"); sprintf(&header[11], "%03u", block_id); if (fwrite(header, 14, 1, g_outfile) != 1) return (0); i = (block_len + 254) / 255; while (--i >= 0) { block_len -= (j = min(block_len, 255)); if (fputc(j, g_outfile) != j) return (0); while (--j >= 0) fputc(*(block_data++), g_outfile); } if (fputc(0, g_outfile) != 0) return (0); return (1); } static int _fastcall store_item_name(char *nameptr) { struct formula_info fsave_info; int i; for (i = 0; i < 40; i++) fsave_info.form_name[i] = 0; /* initialize string */ strcpy(fsave_info.form_name, nameptr); if (fractype == FORMULA || fractype == FFORMULA) { fsave_info.uses_p1 = (short) uses_p1; fsave_info.uses_p2 = (short) uses_p2; fsave_info.uses_p3 = (short) uses_p3; fsave_info.uses_ismand = (short) uses_ismand; fsave_info.ismand = (short) ismand; fsave_info.uses_p4 = (short) uses_p4; fsave_info.uses_p5 = (short) uses_p5; } else { fsave_info.uses_p1 = 0; fsave_info.uses_p2 = 0; fsave_info.uses_p3 = 0; fsave_info.uses_ismand = 0; fsave_info.ismand = 0; fsave_info.uses_p4 = 0; fsave_info.uses_p5 = 0; } for (i = 0; i < sizeof(fsave_info.future) / sizeof(short); i++) fsave_info.future[i] = 0; /* formula/lsys/ifs info block, 003 */ put_extend_blk(3, sizeof(fsave_info), (char far *) &fsave_info); return (extend_blk_len(sizeof(fsave_info))); } static void _fastcall setup_save_info(struct fractal_info far * save_info) { int i; if (fractype != FORMULA && fractype != FFORMULA) maxfn = 0; /* set save parameters in save structure */ far_strcpy(save_info->info_id, INFO_ID); save_info->version = VERSION; if (maxit <= SHRT_MAX) save_info->iterationsold = (short) maxit; else save_info->iterationsold = (short) SHRT_MAX; save_info->fractal_type = (short) fractype; save_info->xmin = xxmin; save_info->xmax = xxmax; save_info->ymin = yymin; save_info->ymax = yymax; save_info->creal = param[0]; save_info->cimag = param[1]; save_info->videomodeax = (short) videoentry.videomodeax; save_info->videomodebx = (short) videoentry.videomodebx; save_info->videomodecx = (short) videoentry.videomodecx; save_info->videomodedx = (short) videoentry.videomodedx; save_info->dotmode = (short) (videoentry.dotmode % 100); save_info->xdots = (short) videoentry.xdots; save_info->ydots = (short) videoentry.ydots; save_info->colors = (short) videoentry.colors; save_info->parm3 = 0; /* pre version==7 fields */ save_info->parm4 = 0; save_info->dparm3 = param[2]; save_info->dparm4 = param[3]; save_info->dparm5 = param[4]; save_info->dparm6 = param[5]; save_info->dparm7 = param[6]; save_info->dparm8 = param[7]; save_info->dparm9 = param[8]; save_info->dparm10 = param[9]; save_info->fillcolor = (short) fillcolor; save_info->potential[0] = (float) potparam[0]; save_info->potential[1] = (float) potparam[1]; save_info->potential[2] = (float) potparam[2]; save_info->rflag = (short) rflag; save_info->rseed = (short) rseed; save_info->inside = (short) inside; if (LogFlag <= SHRT_MAX) save_info->logmapold = (short) LogFlag; else save_info->logmapold = (short) SHRT_MAX; save_info->invert[0] = (float) inversion[0]; save_info->invert[1] = (float) inversion[1]; save_info->invert[2] = (float) inversion[2]; save_info->decomp[0] = (short) decomp[0]; save_info->biomorph = (short) usr_biomorph; save_info->symmetry = (short) forcesymmetry; for (i = 0; i < 16; i++) save_info->init3d[i] = (short) init3d[i]; save_info->previewfactor = (short) previewfactor; save_info->xtrans = (short) xtrans; save_info->ytrans = (short) ytrans; save_info->red_crop_left = (short) red_crop_left; save_info->red_crop_right = (short) red_crop_right; save_info->blue_crop_left = (short) blue_crop_left; save_info->blue_crop_right = (short) blue_crop_right; save_info->red_bright = (short) red_bright; save_info->blue_bright = (short) blue_bright; save_info->xadjust = (short) xadjust; save_info->yadjust = (short) yadjust; save_info->eyeseparation = (short) eyeseparation; save_info->glassestype = (short) glassestype; save_info->outside = (short) outside; save_info->x3rd = xx3rd; save_info->y3rd = yy3rd; save_info->calc_status = (short) calc_status; save_info->stdcalcmode = (char) ((three_pass && stdcalcmode == '3') ? 127 : stdcalcmode); if (distest <= 32000) save_info->distestold = (short) distest; else save_info->distestold = 32000; save_info->floatflag = floatflag; if (bailout >= 4 && bailout <= 32000) save_info->bailoutold = (short) bailout; else save_info->bailoutold = 0; save_info->calctime = calctime; save_info->trigndx[0] = trigndx[0]; save_info->trigndx[1] = trigndx[1]; save_info->trigndx[2] = trigndx[2]; save_info->trigndx[3] = trigndx[3]; save_info->finattract = (short) finattract; save_info->initorbit[0] = initorbit.x; save_info->initorbit[1] = initorbit.y; save_info->useinitorbit = useinitorbit; save_info->periodicity = (short) periodicitycheck; save_info->pot16bit = (short) disk16bit; save_info->faspectratio = finalaspectratio; save_info->system = (short) save_system; if (check_back()) save_info->release = (short) min(save_release, release); else save_info->release = (short) release; save_info->flag3d = (short) display3d; save_info->ambient = (short) Ambient; save_info->randomize = (short) RANDOMIZE; save_info->haze = (short) haze; save_info->transparent[0] = (short) transparent[0]; save_info->transparent[1] = (short) transparent[1]; save_info->rotate_lo = (short) rotate_lo; save_info->rotate_hi = (short) rotate_hi; save_info->distestwidth = (short) distestwidth; save_info->mxmaxfp = mxmaxfp; save_info->mxminfp = mxminfp; save_info->mymaxfp = mymaxfp; save_info->myminfp = myminfp; save_info->zdots = (short) zdots; save_info->originfp = originfp; save_info->depthfp = depthfp; save_info->heightfp = heightfp; save_info->widthfp = widthfp; save_info->distfp = distfp; save_info->eyesfp = eyesfp; save_info->orbittype = (short) neworbittype; save_info->juli3Dmode = (short) juli3Dmode; save_info->maxfn = maxfn; save_info->inversejulia = (short) ((major_method << 8) + minor_method); /* MVS */ save_info->bailout = bailout; save_info->bailoutest = (short) bailoutest; save_info->iterations = maxit; save_info->bflength = (short) bnlength; save_info->bf_math = (short) bf_math; save_info->old_demm_colors = (short) old_demm_colors; save_info->logmap = LogFlag; save_info->distest = distest; save_info->dinvert[0] = inversion[0]; save_info->dinvert[1] = inversion[1]; save_info->dinvert[2] = inversion[2]; save_info->logcalc = (short) Log_Fly_Calc; save_info->stoppass = (short) stoppass; save_info->quick_calc = (short) quick_calc; save_info->closeprox = closeprox; save_info->nobof = (short) nobof; save_info->orbit_interval = orbit_interval; save_info->orbit_delay = (short) orbit_delay; save_info->math_tol[0] = math_tol[0]; save_info->math_tol[1] = math_tol[1]; for (i = 0; i < sizeof(save_info->future) / sizeof(short); i++) save_info->future[i] = 0; } /*************************************************************************** * * GIFENCOD.C - GIF Image compression routines * * Lempel-Ziv compression based on 'compress'. GIF modifications by * David Rowley (mgardi@watdcsu.waterloo.edu). * Thoroughly massaged by the Stone Soup team for Fractint's purposes. * ***************************************************************************/ #define BITSF 12 #define HSIZE 5003 /* 80% occupancy */ /* * * GIF Image compression - modified 'compress' * * Based on: compress.c - File compression ala IEEE Computer, June 1984. * * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) * Jim McKie (decvax!mcvax!jim) * Steve Davies (decvax!vax135!petsd!peora!srd) * Ken Turkowski (decvax!decwrl!turtlevax!ken) * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * */ /* prototypes */ static void _fastcall output(int code); static void _fastcall char_out(int c); static void _fastcall flush_char(void); static void _fastcall cl_block(void); static int n_bits; /* number of bits/code */ static int maxbits = BITSF; /* user settable max # bits/code */ static int maxcode; /* maximum code, given n_bits */ static int maxmaxcode = (int)1 << BITSF; /* should NEVER generate this code */ # define MAXCODE(n_bits) (((int) 1 << (n_bits)) - 1) #ifdef XFRACT unsigned int strlocn[10240]; BYTE block[4096]; #endif static long far *htab; static unsigned short *codetab = (unsigned short *)strlocn; /* * To save much memory, we overlay the table used by compress() with those * used by decompress(). The tab_prefix table is the same size and type * as the codetab. The tab_suffix table needs 2**BITSF characters. We * get this from the beginning of htab. The output stack uses the rest * of htab, and contains characters. There is plenty of room for any * possible stack (stack used to be 8000 characters). */ #define tab_prefixof(i) codetab[i] #define tab_suffixof(i) ((char_type far *)(htab))[i] #define de_stack ((char_type far *)&tab_suffixof((int)1< 2) { outcolor1 = 2; outcolor2 = 3; } if (((++numsaves) & 1) == 0) { /* reverse the colors on alt saves */ i = outcolor1; outcolor1 = outcolor2; outcolor2 = i; } outcolor1s = outcolor1; outcolor2s = outcolor2; /* * Set up the necessary values */ cur_accum = 0; cur_bits = 0; clear_flg = 0; ydot = 0; ent = 0; maxcode = MAXCODE(n_bits = startbits); ClearCode = (1 << (startbits - 1)); EOFCode = ClearCode + 1; free_ent = ClearCode + 2; a_count = 0; hshift = 0; for (fcode = (long) HSIZE; fcode < 65536L; fcode *= 2L) hshift++; hshift = 8 - hshift; /* set hash code range bound */ far_memset(htab,0xff,(unsigned)HSIZE*sizeof(long)); hsize_reg = HSIZE; output((int)ClearCode); for (rownum = 0; rownum < ydots; rownum++) { /* scan through the dots */ for (ydot = rownum; ydot < rowlimit; ydot += ydots) { for (xdot = 0; xdot < xdots; xdot++) { if (save16bit == 0 || ydot < ydots) color = getcolor(xdot, ydot); else color = readdisk(xdot + sxoffs, ydot + syoffs); if(in_count == 0) { in_count = 1; ent = color; continue; } fcode = (long) (((long) color << maxbits) + ent); i = (((int)color << hshift) ^ ent); /* xor hashing */ if (htab[i] == fcode) { ent = codetab[i]; continue; } else if ((long)htab[i] < 0) /* empty slot */ goto nomatch; disp = hsize_reg - i; /* secondary hash (after G. Knott) */ if (i == 0) disp = 1; probe: if ((i -= disp) < 0) i += hsize_reg; if (htab[i] == fcode) { ent = codetab[i]; continue; } if ((long)htab[i] > 0) goto probe; nomatch: output ((int) ent); ent = color; if (free_ent < maxmaxcode) { /* code -> hashtable */ codetab[i] = (unsigned short)free_ent++; htab[i] = fcode; } else cl_block(); } /* end for xdot */ if (dotmode != 11 /* suppress this on disk-video */ && active_system == 0 /* and in Windows/X11 (most) versions */ && ydot == rownum) { if ((ydot & 4) == 0) { if (++outcolor1 >= colors) outcolor1 = 0; if (++outcolor2 >= colors) outcolor2 = 0; } for (i = 0; 250 * i < xdots; i++) { /* display vert status bars */ /* (this is NOT GIF-related) */ putcolor(i, ydot, getcolor(i, ydot) ^ outcolor1); putcolor(xdots - 1 - i, ydot, getcolor(xdots - 1 - i, ydot) ^ outcolor2); } last_colorbar = ydot; } /* end if dotmode != 11 */ tempkey = keypressed(); if (tempkey && (tempkey != (int)'s')) /* keyboard hit - bail out */ { interrupted = 1; rownum = ydots; break; } if (tempkey == (int)'s') getakey(); /* eat the keystroke */ } /* end for ydot */ } /* end for rownum */ /* * Put out the final code. */ output((int)ent); output((int) EOFCode); return (interrupted); } /***************************************************************** * TAG(output) * * Output the given code. * Inputs: * code: A n_bits-bit integer. If == -1, then EOF. This assumes * that n_bits =< (long)wordsize - 1. * Outputs: * Outputs code to the file. * Assumptions: * Chars are 8 bits long. * Algorithm: * Maintain a BITSF character long buffer (so that 8 codes will * fit in it exactly). Use the VAX insv instruction to insert each * code in turn. When the buffer fills up empty it and start over. */ static void _fastcall output(int code) { static ULFCODE masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; cur_accum &= masks[ cur_bits ]; if(cur_bits > 0) cur_accum |= ((long)code << cur_bits); else cur_accum = code; cur_bits += n_bits; while(cur_bits >= 8) { char_out((unsigned int)(cur_accum & 0xff)); cur_accum >>= 8; cur_bits -= 8; } /* * If the next entry is going to be too big for the code size, * then increase it, if possible. */ if (free_ent > maxcode || clear_flg) { if(clear_flg) { maxcode = MAXCODE (n_bits = startbits); clear_flg = 0; } else { n_bits++; if (n_bits == maxbits) maxcode = maxmaxcode; else maxcode = MAXCODE(n_bits); } } if(code == EOFCode) { /* * At EOF, write the rest of the buffer. */ while(cur_bits > 0) { char_out((unsigned int)(cur_accum & 0xff)); cur_accum >>= 8; cur_bits -= 8; } flush_char(); fflush(g_outfile); } } /* * Clear out the hash table */ static void _fastcall cl_block(void) /* table clear for block compress */ { far_memset(htab,0xff,(unsigned)HSIZE*sizeof(long)); free_ent = ClearCode + 2; clear_flg = 1; output((int)ClearCode); } /* * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */ static void _fastcall char_out(int c) { accum[ a_count++ ] = (char)c; if(a_count >= 254) flush_char(); } /* * Flush the packet to disk, and reset the accumulator */ static void _fastcall flush_char(void) { if(a_count > 0) { fputc(a_count, g_outfile); fwrite(accum, 1, a_count, g_outfile); a_count = 0; } } xfractint-20.4.10.orig/common/lorenz.c0000644000000000000000000022643510552477553014503 0ustar /* This file contains two 3 dimensional orbit-type fractal generators - IFS and LORENZ3D, along with code to generate red/blue 3D images. Tim Wegner */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /* orbitcalc is declared with no arguments so jump through hoops here */ #define LORBIT(x,y,z) \ (*(int(*)(long *,long *,long *))curfractalspecific->orbitcalc)(x,y,z) #define FORBIT(x,y,z) \ (*(int(*)(double*,double*,double*))curfractalspecific->orbitcalc)(x,y,z) #define RANDOM(x) (rand()%(x)) /* BAD_PIXEL is used to cutoff orbits that are diverging. It might be better to test the actual floating point orbit values, but this seems safe for now. A higher value cannot be used - to test, turn off math coprocessor and use +2.24 for type ICONS. If BAD_PIXEL is set to 20000, this will abort Fractint with a math error. Note that this approach precludes zooming in very far to an orbit type. */ #define BAD_PIXEL 10000L /* pixels can't get this big */ struct l_affine { /* weird order so a,b,e and c,d,f are vectors */ long a; long b; long e; long c; long d; long f; }; struct long3dvtinf /* data used by 3d view transform subroutine */ { long orbit[3]; /* interated function orbit value */ long iview[3]; /* perspective viewer's coordinates */ long viewvect[3]; /* orbit transformed for viewing */ long viewvect1[3]; /* orbit transformed for viewing */ long maxvals[3]; long minvals[3]; MATRIX doublemat; /* transformation matrix */ MATRIX doublemat1; /* transformation matrix */ long longmat[4][4]; /* long version of matrix */ long longmat1[4][4]; /* long version of matrix */ int row,col; /* results */ int row1,col1; struct l_affine cvt; }; struct float3dvtinf /* data used by 3d view transform subroutine */ { double orbit[3]; /* interated function orbit value */ double viewvect[3]; /* orbit transformed for viewing */ double viewvect1[3]; /* orbit transformed for viewing */ double maxvals[3]; double minvals[3]; MATRIX doublemat; /* transformation matrix */ MATRIX doublemat1; /* transformation matrix */ int row,col; /* results */ int row1,col1; struct affine cvt; }; /* Routines in this module */ static int ifs2d(void); static int ifs3d(void); static int ifs3dlong(void); static int ifs3dfloat(void); static int l_setup_convert_to_screen(struct l_affine *); static void setupmatrix(MATRIX); static int long3dviewtransf(struct long3dvtinf *inf); static int float3dviewtransf(struct float3dvtinf *inf); static FILE *open_orbitsave(void); static void _fastcall plothist(int x, int y, int color); static int realtime; static char orbitsavename[] = {"orbits.raw"}; static char orbitsave_format[] = {"%g %g %g 15\n"}; S32 maxct; static int t; static long l_dx,l_dy,l_dz,l_dt,l_a,l_b,l_c,l_d; static long l_adt,l_bdt,l_cdt,l_xdt,l_ydt; static long initorbitlong[3]; static double dx,dy,dz,dt,a,b,c,d; static double adt,bdt,cdt,xdt,ydt,zdt; static double initorbitfp[3]; /* * The following declarations used for Inverse Julia. MVS */ static FCODE NoQueue[] = "Not enough memory: switching to random walk.\n"; static int mxhits; int run_length; /* enum {breadth_first, depth_first, random_walk, random_run} major_method; enum {left_first, right_first} minor_method; */ enum Major major_method; enum Minor minor_method; struct affine cvt; struct l_affine lcvt; double Cx, Cy; long CxLong, CyLong; /* * end of Inverse Julia declarations; */ /* these are potential user parameters */ int connect = 1; /* flag to connect points with a line */ int euler = 0; /* use implicit euler approximation for dynamic system */ int waste = 100; /* waste this many points before plotting */ int projection = 2; /* projection plane - default is to plot x-y */ /******************************************************************/ /* zoom box conversion functions */ /******************************************************************/ /* Conversion of complex plane to screen coordinates for rotating zoom box. Assume there is an affine transformation mapping complex zoom parallelogram to rectangular screen. We know this map must map parallelogram corners to screen corners, so we have following equations: a*xxmin+b*yymax+e == 0 (upper left) c*xxmin+d*yymax+f == 0 a*xx3rd+b*yy3rd+e == 0 (lower left) c*xx3rd+d*yy3rd+f == ydots-1 a*xxmax+b*yymin+e == xdots-1 (lower right) c*xxmax+d*yymin+f == ydots-1 First we must solve for a,b,c,d,e,f - (which we do once per image), then we just apply the transformation to each orbit value. */ /* Thanks to Sylvie Gallet for the following. The original code for setup_convert_to_screen() solved for coefficients of the complex-plane-to-screen transformation using a very straight-forward application of determinants to solve a set of simulataneous equations. The procedure was simple and general, but inefficient. The inefficiecy wasn't hurting anything because the routine was called only once per image, but it seemed positively sinful to use it because the code that follows is SO much more compact, at the expense of being less general. Here are Sylvie's notes. I have further optimized the code a slight bit. Tim Wegner July, 1996 Sylvie's notes, slightly edited follow: You don't need 3x3 determinants to solve these sets of equations because the unknowns e and f have the same coefficient: 1. First set of 3 equations: a*xxmin+b*yymax+e == 0 a*xx3rd+b*yy3rd+e == 0 a*xxmax+b*yymin+e == xdots-1 To make things easy to read, I just replace xxmin, xxmax, xx3rd by x1, x2, x3 (ditto for yy...) and xdots-1 by xd. a*x1 + b*y2 + e == 0 (1) a*x3 + b*y3 + e == 0 (2) a*x2 + b*y1 + e == xd (3) I subtract (1) to (2) and (3): a*x1 + b*y2 + e == 0 (1) a*(x3-x1) + b*(y3-y2) == 0 (2)-(1) a*(x2-x1) + b*(y1-y2) == xd (3)-(1) I just have to calculate a 2x2 determinant: det == (x3-x1)*(y1-y2) - (y3-y2)*(x2-x1) And the solution is: a = -xd*(y3-y2)/det b = xd*(x3-x1)/det e = - a*x1 - b*y2 The same technique can be applied to the second set of equations: c*xxmin+d*yymax+f == 0 c*xx3rd+d*yy3rd+f == ydots-1 c*xxmax+d*yymin+f == ydots-1 c*x1 + d*y2 + f == 0 (1) c*x3 + d*y3 + f == yd (2) c*x2 + d*y1 + f == yd (3) c*x1 + d*y2 + f == 0 (1) c*(x3-x2) + d*(y3-y1) == 0 (2)-(3) c*(x2-x1) + d*(y1-y2) == yd (3)-(1) det == (x3-x2)*(y1-y2) - (y3-y1)*(x2-x1) c = -yd*(y3-y1)/det d = yd*(x3-x2))det f = - c*x1 - d*y2 - Sylvie */ int setup_convert_to_screen(struct affine *scrn_cnvt) { double det, xd, yd; if((det = (xx3rd-xxmin)*(yymin-yymax) + (yymax-yy3rd)*(xxmax-xxmin))==0) return(-1); xd = dxsize/det; scrn_cnvt->a = xd*(yymax-yy3rd); scrn_cnvt->b = xd*(xx3rd-xxmin); scrn_cnvt->e = -scrn_cnvt->a*xxmin - scrn_cnvt->b*yymax; if((det = (xx3rd-xxmax)*(yymin-yymax) + (yymin-yy3rd)*(xxmax-xxmin))==0) return(-1); yd = dysize/det; scrn_cnvt->c = yd*(yymin-yy3rd); scrn_cnvt->d = yd*(xx3rd-xxmax); scrn_cnvt->f = -scrn_cnvt->c*xxmin - scrn_cnvt->d*yymax; return(0); } static int l_setup_convert_to_screen(struct l_affine *l_cvt) { struct affine cvt; /* MCP 7-7-91, This function should return a something! */ if(setup_convert_to_screen(&cvt)) return(-1); l_cvt->a = (long)(cvt.a*fudge); l_cvt->b = (long)(cvt.b*fudge); l_cvt->c = (long)(cvt.c*fudge); l_cvt->d = (long)(cvt.d*fudge); l_cvt->e = (long)(cvt.e*fudge); l_cvt->f = (long)(cvt.f*fudge); /* MCP 7-7-91 */ return(0); } /******************************************************************/ /* setup functions - put in fractalspecific[fractype].per_image */ /******************************************************************/ static double orbit; static long l_orbit; static long l_sinx,l_cosx; int orbit3dlongsetup() { maxct = 0L; connect = 1; waste = 100; projection = 2; if (fractype==LHENON || fractype==KAM || fractype==KAM3D || fractype==INVERSEJULIA) connect=0; if(fractype==LROSSLER) waste = 500; if(fractype==LLORENZ) projection = 1; initorbitlong[0] = fudge; /* initial conditions */ initorbitlong[1] = fudge; initorbitlong[2] = fudge; if(fractype==LHENON) { l_a = (long)(param[0]*fudge); l_b = (long)(param[1]*fudge); l_c = (long)(param[2]*fudge); l_d = (long)(param[3]*fudge); } else if(fractype==KAM || fractype==KAM3D) { maxct = 1L; a = param[0]; /* angle */ if(param[1] <= 0.0) param[1] = .01; l_b = (long)(param[1]*fudge); /* stepsize */ l_c = (long)(param[2]*fudge); /* stop */ t = (int)(l_d = (long)(param[3])); /* points per orbit */ l_sinx = (long)(sin(a)*fudge); l_cosx = (long)(cos(a)*fudge); l_orbit = 0; initorbitlong[0] = initorbitlong[1] = initorbitlong[2] = 0; } else if (fractype == INVERSEJULIA) { LCMPLX Sqrt; CxLong = (long)(param[0] * fudge); CyLong = (long)(param[1] * fudge); mxhits = (int) param[2]; run_length = (int) param[3]; if (mxhits <= 0) mxhits = 1; else if (mxhits >= colors) mxhits = colors - 1; param[2] = mxhits; setup_convert_to_screen(&cvt); /* Note: using bitshift of 21 for affine, 24 otherwise */ lcvt.a = (long)(cvt.a * (1L << 21)); lcvt.b = (long)(cvt.b * (1L << 21)); lcvt.c = (long)(cvt.c * (1L << 21)); lcvt.d = (long)(cvt.d * (1L << 21)); lcvt.e = (long)(cvt.e * (1L << 21)); lcvt.f = (long)(cvt.f * (1L << 21)); Sqrt = ComplexSqrtLong(fudge - 4 * CxLong, -4 * CyLong); switch (major_method) { case breadth_first: if (Init_Queue((long)32*1024) == 0) { /* can't get queue memory: fall back to random walk */ stopmsg(20, NoQueue); major_method = random_walk; goto lrwalk; } EnQueueLong((fudge + Sqrt.x) / 2, Sqrt.y / 2); EnQueueLong((fudge - Sqrt.x) / 2, -Sqrt.y / 2); break; case depth_first: if (Init_Queue((long)32*1024) == 0) { /* can't get queue memory: fall back to random walk */ stopmsg(20, NoQueue); major_method = random_walk; goto lrwalk; } switch (minor_method) { case left_first: PushLong((fudge + Sqrt.x) / 2, Sqrt.y / 2); PushLong((fudge - Sqrt.x) / 2, -Sqrt.y / 2); break; case right_first: PushLong((fudge - Sqrt.x) / 2, -Sqrt.y / 2); PushLong((fudge + Sqrt.x) / 2, Sqrt.y / 2); break; } break; case random_walk: lrwalk: lnew.x = initorbitlong[0] = fudge + Sqrt.x / 2; lnew.y = initorbitlong[1] = Sqrt.y / 2; break; case random_run: lnew.x = initorbitlong[0] = fudge + Sqrt.x / 2; lnew.y = initorbitlong[1] = Sqrt.y / 2; break; } } else { l_dt = (long)(param[0]*fudge); l_a = (long)(param[1]*fudge); l_b = (long)(param[2]*fudge); l_c = (long)(param[3]*fudge); } /* precalculations for speed */ l_adt = multiply(l_a,l_dt,bitshift); l_bdt = multiply(l_b,l_dt,bitshift); l_cdt = multiply(l_c,l_dt,bitshift); return(1); } #define COSB dx #define SINABC dy int orbit3dfloatsetup() { maxct = 0L; connect = 1; waste = 100; projection = 2; if(fractype==FPHENON || fractype==FPPICKOVER || fractype==FPGINGERBREAD || fractype == KAMFP || fractype == KAM3DFP || fractype == FPHOPALONG || fractype == INVERSEJULIAFP) connect=0; if(fractype==FPLORENZ3D1 || fractype==FPLORENZ3D3 || fractype==FPLORENZ3D4) waste = 750; if(fractype==FPROSSLER) waste = 500; if(fractype==FPLORENZ) projection = 1; /* plot x and z */ initorbitfp[0] = 1; /* initial conditions */ initorbitfp[1] = 1; initorbitfp[2] = 1; if(fractype==FPGINGERBREAD) { initorbitfp[0] = param[0]; /* initial conditions */ initorbitfp[1] = param[1]; } if(fractype==ICON || fractype==ICON3D) /* DMF */ { initorbitfp[0] = 0.01; /* initial conditions */ initorbitfp[1] = 0.003; connect = 0; waste = 2000; } if(fractype==LATOO) /* HB */ { connect = 0; } if(fractype==FPHENON || fractype==FPPICKOVER) { a = param[0]; b = param[1]; c = param[2]; d = param[3]; } else if(fractype==ICON || fractype==ICON3D) /* DMF */ { initorbitfp[0] = 0.01; /* initial conditions */ initorbitfp[1] = 0.003; connect = 0; waste = 2000; /* Initialize parameters */ a = param[0]; b = param[1]; c = param[2]; d = param[3]; } else if(fractype==KAMFP || fractype==KAM3DFP) { maxct = 1L; a = param[0]; /* angle */ if(param[1] <= 0.0) param[1] = .01; b = param[1]; /* stepsize */ c = param[2]; /* stop */ t = (int)(l_d = (long)(param[3])); /* points per orbit */ sinx = sin(a); cosx = cos(a); orbit = 0; initorbitfp[0] = initorbitfp[1] = initorbitfp[2] = 0; } else if(fractype==FPHOPALONG || fractype==FPMARTIN || fractype==CHIP || fractype==QUADRUPTWO || fractype==THREEPLY) { initorbitfp[0] = 0; /* initial conditions */ initorbitfp[1] = 0; initorbitfp[2] = 0; connect = 0; a = param[0]; b = param[1]; c = param[2]; d = param[3]; if(fractype==THREEPLY) { COSB = cos(b); SINABC = sin(a+b+c); } } else if (fractype == INVERSEJULIAFP) { _CMPLX Sqrt; Cx = param[0]; Cy = param[1]; mxhits = (int) param[2]; run_length = (int) param[3]; if (mxhits <= 0) mxhits = 1; else if (mxhits >= colors) mxhits = colors - 1; param[2] = mxhits; setup_convert_to_screen(&cvt); /* find fixed points: guaranteed to be in the set */ Sqrt = ComplexSqrtFloat(1 - 4 * Cx, -4 * Cy); switch ((int) major_method) { case breadth_first: if (Init_Queue((long)32*1024) == 0) { /* can't get queue memory: fall back to random walk */ stopmsg(20, NoQueue); major_method = random_walk; goto rwalk; } EnQueueFloat((float)((1 + Sqrt.x) / 2), (float)(Sqrt.y / 2)); EnQueueFloat((float)((1 - Sqrt.x) / 2), (float)(-Sqrt.y / 2)); break; case depth_first: /* depth first (choose direction) */ if (Init_Queue((long)32*1024) == 0) { /* can't get queue memory: fall back to random walk */ stopmsg(20, NoQueue); major_method = random_walk; goto rwalk; } switch (minor_method) { case left_first: PushFloat((float)((1 + Sqrt.x) / 2), (float)(Sqrt.y / 2)); PushFloat((float)((1 - Sqrt.x) / 2), (float)(-Sqrt.y / 2)); break; case right_first: PushFloat((float)((1 - Sqrt.x) / 2), (float)(-Sqrt.y / 2)); PushFloat((float)((1 + Sqrt.x) / 2), (float)(Sqrt.y / 2)); break; } break; case random_walk: rwalk: new.x = initorbitfp[0] = 1 + Sqrt.x / 2; new.y = initorbitfp[1] = Sqrt.y / 2; break; case random_run: /* random run, choose intervals */ major_method = random_run; new.x = initorbitfp[0] = 1 + Sqrt.x / 2; new.y = initorbitfp[1] = Sqrt.y / 2; break; } } else { dt = param[0]; a = param[1]; b = param[2]; c = param[3]; } /* precalculations for speed */ adt = a*dt; bdt = b*dt; cdt = c*dt; return(1); } /******************************************************************/ /* orbit functions - put in fractalspecific[fractype].orbitcalc */ /******************************************************************/ /* Julia sets by inverse iterations added by Juan J. Buhler 4/3/92 */ /* Integrated with Lorenz by Tim Wegner 7/20/92 */ /* Add Modified Inverse Iteration Method, 11/92 by Michael Snyder */ int Minverse_julia_orbit() { static int random_dir = 0, random_len = 0; int newrow, newcol; int color, leftright; /* * First, compute new point */ switch (major_method) { case breadth_first: if (QueueEmpty()) return -1; new = DeQueueFloat(); break; case depth_first: if (QueueEmpty()) return -1; new = PopFloat(); break; case random_walk: #if 0 new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); if (RANDOM(2)) { new.x = -new.x; new.y = -new.y; } #endif break; case random_run: #if 0 new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); if (random_len == 0) { random_len = RANDOM(run_length); random_dir = RANDOM(3); } switch (random_dir) { case 0: /* left */ break; case 1: /* right */ new.x = -new.x; new.y = -new.y; break; case 2: /* random direction */ if (RANDOM(2)) { new.x = -new.x; new.y = -new.y; } break; } #endif break; } /* * Next, find its pixel position */ newcol = (int)(cvt.a * new.x + cvt.b * new.y + cvt.e); newrow = (int)(cvt.c * new.x + cvt.d * new.y + cvt.f); /* * Now find the next point(s), and flip a coin to choose one. */ new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); leftright = (RANDOM(2)) ? 1 : -1; if (newcol < 1 || newcol >= xdots || newrow < 1 || newrow >= ydots) { /* * MIIM must skip points that are off the screen boundary, * since it cannot read their color. */ switch (major_method) { case breadth_first: EnQueueFloat((float)(leftright * new.x), (float)(leftright * new.y)); return 1; case depth_first: PushFloat ((float)(leftright * new.x), (float)(leftright * new.y)); return 1; case random_run: case random_walk: break; } } /* * Read the pixel's color: * For MIIM, if color >= mxhits, discard the point * else put the point's children onto the queue */ color = getcolor(newcol, newrow); switch (major_method) { case breadth_first: if (color < mxhits) { putcolor(newcol, newrow, color+1); /* new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); */ EnQueueFloat( (float)new.x, (float)new.y); EnQueueFloat((float)-new.x, (float)-new.y); } break; case depth_first: if (color < mxhits) { putcolor(newcol, newrow, color+1); /* new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); */ if (minor_method == left_first) { if (QueueFullAlmost()) PushFloat((float)-new.x, (float)-new.y); else { PushFloat( (float)new.x, (float)new.y); PushFloat((float)-new.x, (float)-new.y); } } else { if (QueueFullAlmost()) PushFloat( (float)new.x, (float)new.y); else { PushFloat((float)-new.x, (float)-new.y); PushFloat( (float)new.x, (float)new.y); } } } break; case random_run: if (random_len-- == 0) { random_len = RANDOM(run_length); random_dir = RANDOM(3); } switch (random_dir) { case 0: /* left */ break; case 1: /* right */ new.x = -new.x; new.y = -new.y; break; case 2: /* random direction */ new.x = leftright * new.x; new.y = leftright * new.y; break; } if (color < colors-1) putcolor(newcol, newrow, color+1); break; case random_walk: if (color < colors-1) putcolor(newcol, newrow, color+1); new.x = leftright * new.x; new.y = leftright * new.y; break; } return 1; } int Linverse_julia_orbit() { static int random_dir = 0, random_len = 0; int newrow, newcol; int color; /* * First, compute new point */ switch (major_method) { case breadth_first: if (QueueEmpty()) return -1; lnew = DeQueueLong(); break; case depth_first: if (QueueEmpty()) return -1; lnew = PopLong(); break; case random_walk: lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong); if (RANDOM(2)) { lnew.x = -lnew.x; lnew.y = -lnew.y; } break; case random_run: lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong); if (random_len == 0) { random_len = RANDOM(run_length); random_dir = RANDOM(3); } switch (random_dir) { case 0: /* left */ break; case 1: /* right */ lnew.x = -lnew.x; lnew.y = -lnew.y; break; case 2: /* random direction */ if (RANDOM(2)) { lnew.x = -lnew.x; lnew.y = -lnew.y; } break; } } /* * Next, find its pixel position * * Note: had to use a bitshift of 21 for this operation because * otherwise the values of lcvt were truncated. Used bitshift * of 24 otherwise, for increased precision. */ newcol = (int)((multiply(lcvt.a, lnew.x >> (bitshift - 21), 21) + multiply(lcvt.b, lnew.y >> (bitshift - 21), 21) + lcvt.e) >> 21); newrow = (int)((multiply(lcvt.c, lnew.x >> (bitshift - 21), 21) + multiply(lcvt.d, lnew.y >> (bitshift - 21), 21) + lcvt.f) >> 21); if (newcol < 1 || newcol >= xdots || newrow < 1 || newrow >= ydots) { /* * MIIM must skip points that are off the screen boundary, * since it cannot read their color. */ if (RANDOM(2)) color = 1; else color = -1; switch (major_method) { case breadth_first: lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong); EnQueueLong(color * lnew.x, color * lnew.y); break; case depth_first: lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong); PushLong(color * lnew.x, color * lnew.y); break; case random_run: random_len--; case random_walk: break; } return 1; } /* * Read the pixel's color: * For MIIM, if color >= mxhits, discard the point * else put the point's children onto the queue */ color = getcolor(newcol, newrow); switch (major_method) { case breadth_first: if (color < mxhits) { putcolor(newcol, newrow, color+1); lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong); EnQueueLong( lnew.x, lnew.y); EnQueueLong(-lnew.x, -lnew.y); } break; case depth_first: if (color < mxhits) { putcolor(newcol, newrow, color+1); lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong); if (minor_method == left_first) { if (QueueFullAlmost()) PushLong(-lnew.x, -lnew.y); else { PushLong( lnew.x, lnew.y); PushLong(-lnew.x, -lnew.y); } } else { if (QueueFullAlmost()) PushLong( lnew.x, lnew.y); else { PushLong(-lnew.x, -lnew.y); PushLong( lnew.x, lnew.y); } } } break; case random_run: random_len--; /* fall through */ case random_walk: if (color < colors-1) putcolor(newcol, newrow, color+1); break; } return 1; } #if 0 int inverse_julia_orbit(double *x, double *y, double *z) { double r, xo, yo; int waste; if(*z >= 1.0) /* this assumes intial value is 1.0!!! */ { waste = 20; /* skip these points at first */ *z = 0; } else waste = 1; while(waste--) { xo = *x - param[0]; yo = *y - param[1]; r = sqrt(xo*xo + yo*yo); *x = sqrt((r + xo)/2); if (yo < 0) *x = - *x; *y = sqrt((r - xo)/2); if(RANDOM(10) > 4) { *x = -(*x); *y = -(*y); } } return(0); } #endif int lorenz3dlongorbit(long *l_x, long *l_y, long *l_z) { l_xdt = multiply(*l_x,l_dt,bitshift); l_ydt = multiply(*l_y,l_dt,bitshift); l_dx = -multiply(l_adt,*l_x,bitshift) + multiply(l_adt,*l_y,bitshift); l_dy = multiply(l_bdt,*l_x,bitshift) -l_ydt -multiply(*l_z,l_xdt,bitshift); l_dz = -multiply(l_cdt,*l_z,bitshift) + multiply(*l_x,l_ydt,bitshift); *l_x += l_dx; *l_y += l_dy; *l_z += l_dz; return(0); } int lorenz3d1floatorbit(double *x, double *y, double *z) { double norm; xdt = (*x)*dt; ydt = (*y)*dt; zdt = (*z)*dt; /* 1-lobe Lorenz */ norm = sqrt((*x)*(*x)+(*y)*(*y)); dx = (-adt-dt)*(*x) + (adt-bdt)*(*y) + (dt-adt)*norm + ydt*(*z); dy = (bdt-adt)*(*x) - (adt+dt)*(*y) + (bdt+adt)*norm - xdt*(*z) - norm*zdt; dz = (ydt/2) - cdt*(*z); *x += dx; *y += dy; *z += dz; return(0); } int lorenz3dfloatorbit(double *x, double *y, double *z) { xdt = (*x)*dt; ydt = (*y)*dt; zdt = (*z)*dt; /* 2-lobe Lorenz (the original) */ dx = -adt*(*x) + adt*(*y); dy = bdt*(*x) - ydt - (*z)*xdt; dz = -cdt*(*z) + (*x)*ydt; *x += dx; *y += dy; *z += dz; return(0); } int lorenz3d3floatorbit(double *x, double *y, double *z) { double norm; xdt = (*x)*dt; ydt = (*y)*dt; zdt = (*z)*dt; /* 3-lobe Lorenz */ norm = sqrt((*x)*(*x)+(*y)*(*y)); dx = (-(adt+dt)*(*x) + (adt-bdt+zdt)*(*y)) / 3 + ((dt-adt)*((*x)*(*x)-(*y)*(*y)) + 2*(bdt+adt-zdt)*(*x)*(*y))/(3*norm); dy = ((bdt-adt-zdt)*(*x) - (adt+dt)*(*y)) / 3 + (2*(adt-dt)*(*x)*(*y) + (bdt+adt-zdt)*((*x)*(*x)-(*y)*(*y)))/(3*norm); dz = (3*xdt*(*x)*(*y)-ydt*(*y)*(*y))/2 - cdt*(*z); *x += dx; *y += dy; *z += dz; return(0); } int lorenz3d4floatorbit(double *x, double *y, double *z) { xdt = (*x)*dt; ydt = (*y)*dt; zdt = (*z)*dt; /* 4-lobe Lorenz */ dx = (-adt*(*x)*(*x)*(*x) + (2*adt+bdt-zdt)*(*x)*(*x)*(*y) + (adt-2*dt)*(*x)*(*y)*(*y) + (zdt-bdt)*(*y)*(*y)*(*y)) / (2 * ((*x)*(*x)+(*y)*(*y))); dy = ((bdt-zdt)*(*x)*(*x)*(*x) + (adt-2*dt)*(*x)*(*x)*(*y) + (-2*adt-bdt+zdt)*(*x)*(*y)*(*y) - adt*(*y)*(*y)*(*y)) / (2 * ((*x)*(*x)+(*y)*(*y))); dz = (2*xdt*(*x)*(*x)*(*y) - 2*xdt*(*y)*(*y)*(*y) - cdt*(*z)); *x += dx; *y += dy; *z += dz; return(0); } int henonfloatorbit(double *x, double *y, double *z) { double newx,newy; *z = *x; /* for warning only */ newx = 1 + *y - a*(*x)*(*x); newy = b*(*x); *x = newx; *y = newy; return(0); } int henonlongorbit(long *l_x, long *l_y, long *l_z) { long newx,newy; *l_z = *l_x; /* for warning only */ newx = multiply(*l_x,*l_x,bitshift); newx = multiply(newx,l_a,bitshift); newx = fudge + *l_y - newx; newy = multiply(l_b,*l_x,bitshift); *l_x = newx; *l_y = newy; return(0); } int rosslerfloatorbit(double *x, double *y, double *z) { xdt = (*x)*dt; ydt = (*y)*dt; dx = -ydt - (*z)*dt; dy = xdt + (*y)*adt; dz = bdt + (*z)*xdt - (*z)*cdt; *x += dx; *y += dy; *z += dz; return(0); } int pickoverfloatorbit(double *x, double *y, double *z) { double newx,newy,newz; newx = sin(a*(*y)) - (*z)*cos(b*(*x)); newy = (*z)*sin(c*(*x)) - cos(d*(*y)); newz = sin(*x); *x = newx; *y = newy; *z = newz; return(0); } /* page 149 "Science of Fractal Images" */ int gingerbreadfloatorbit(double *x, double *y, double *z) { double newx; *z = *x; /* for warning only */ newx = 1 - (*y) + fabs(*x); *y = *x; *x = newx; return(0); } int rosslerlongorbit(long *l_x, long *l_y, long *l_z) { l_xdt = multiply(*l_x,l_dt,bitshift); l_ydt = multiply(*l_y,l_dt,bitshift); l_dx = -l_ydt - multiply(*l_z,l_dt,bitshift); l_dy = l_xdt + multiply(*l_y,l_adt,bitshift); l_dz = l_bdt + multiply(*l_z,l_xdt,bitshift) - multiply(*l_z,l_cdt,bitshift); *l_x += l_dx; *l_y += l_dy; *l_z += l_dz; return(0); } /* OSTEP = Orbit Step (and inner orbit value) */ /* NTURNS = Outside Orbit */ /* TURN2 = Points per orbit */ /* a = Angle */ int kamtorusfloatorbit(double *r, double *s, double *z) { double srr; if(t++ >= l_d) { orbit += b; (*r) = (*s) = orbit/3; t = 0; *z = orbit; if(orbit > c) return(1); } srr = (*s)-(*r)*(*r); (*s)=(*r)*sinx+srr*cosx; (*r)=(*r)*cosx-srr*sinx; return(0); } int kamtoruslongorbit(long *r, long *s, long *z) { long srr; if(t++ >= l_d) { l_orbit += l_b; (*r) = (*s) = l_orbit/3; t = 0; *z = l_orbit; if(l_orbit > l_c) return(1); } srr = (*s)-multiply((*r),(*r),bitshift); (*s)=multiply((*r),l_sinx,bitshift)+multiply(srr,l_cosx,bitshift); (*r)=multiply((*r),l_cosx,bitshift)-multiply(srr,l_sinx,bitshift); return(0); } int hopalong2dfloatorbit(double *x, double *y, double *z) { double tmp; *z = *x; /* for warning only */ tmp = *y - sign(*x)*sqrt(fabs(b*(*x)-c)); *y = a - *x; *x = tmp; return(0); } /* from Michael Peters and HOP */ int chip2dfloatorbit(double *x, double *y, double *z) { double tmp; *z = *x; /* for warning only */ tmp = *y - sign(*x) * cos(sqr(log(fabs(b*(*x)-c)))) * atan(sqr(log(fabs(c*(*x)-b)))); *y = a - *x; *x = tmp; return(0); } /* from Michael Peters and HOP */ int quadruptwo2dfloatorbit(double *x, double *y, double *z) { double tmp; *z = *x; /* for warning only */ tmp = *y - sign(*x) * sin(log(fabs(b*(*x)-c))) * atan(sqr(log(fabs(c*(*x)-b)))); *y = a - *x; *x = tmp; return(0); } /* from Michael Peters and HOP */ int threeply2dfloatorbit(double *x, double *y, double *z) { double tmp; *z = *x; /* for warning only */ tmp = *y - sign(*x)*(fabs(sin(*x)*COSB+c-(*x)*SINABC)); *y = a - *x; *x = tmp; return(0); } int martin2dfloatorbit(double *x, double *y, double *z) { double tmp; *z = *x; /* for warning only */ tmp = *y - sin(*x); *y = a - *x; *x = tmp; return(0); } int mandelcloudfloat(double *x, double *y, double *z) { double newx,newy,x2,y2; #ifndef XFRACT newx = *z; /* for warning only */ #endif x2 = (*x)*(*x); y2 = (*y)*(*y); if (x2+y2>2) return 1; newx = x2-y2+a; newy = 2*(*x)*(*y)+b; *x = newx; *y = newy; return(0); } int dynamfloat(double *x, double *y, double *z) { _CMPLX cp,tmp; double newx,newy; #ifndef XFRACT newx = *z; /* for warning only */ #endif cp.x = b* *x; cp.y = 0; CMPLXtrig0(cp, tmp); newy = *y + dt*sin(*x + a*tmp.x); if (euler) { *y = newy; } cp.x = b* *y; cp.y = 0; CMPLXtrig0(cp, tmp); newx = *x - dt*sin(*y + a*tmp.x); *x = newx; *y = newy; return(0); } /* dmf */ #undef LAMBDA #define LAMBDA param[0] #define ALPHA param[1] #define BETA param[2] #define GAMMA param[3] #define OMEGA param[4] #define DEGREE param[5] int iconfloatorbit(double *x, double *y, double *z) { double oldx, oldy, zzbar, zreal, zimag, za, zb, zn, p; int i; oldx = *x; oldy = *y; zzbar = oldx * oldx + oldy * oldy; zreal = oldx; zimag = oldy; for(i=1; i <= DEGREE-2; i++) { za = zreal * oldx - zimag * oldy; zb = zimag * oldx + zreal * oldy; zreal = za; zimag = zb; } zn = oldx * zreal - oldy * zimag; p = LAMBDA + ALPHA * zzbar + BETA * zn; *x = p * oldx + GAMMA * zreal - OMEGA * oldy; *y = p * oldy - GAMMA * zimag + OMEGA * oldx; *z = zzbar; return(0); } #ifdef LAMBDA /* Tim says this will make me a "good citizen" */ #undef LAMBDA /* Yeah, but you were bad, Dan - LAMBDA was already */ #undef ALPHA /* defined! TW */ #undef BETA #undef GAMMA #endif /* hb */ #define PAR_A param[0] #define PAR_B param[1] #define PAR_C param[2] #define PAR_D param[3] int latoofloatorbit(double *x, double *y, double *z) { double xold, yold, tmp; xold = *z; /* for warning only */ xold = *x; yold = *y; /* *x = sin(yold * PAR_B) + PAR_C * sin(xold * PAR_B); */ old.x = yold * PAR_B; old.y = 0; /* old = (y * B) + 0i (in the complex)*/ CMPLXtrig0(old,new); tmp = (double) new.x; old.x = xold * PAR_B; old.y = 0; /* old = (x * B) + 0i */ CMPLXtrig1(old,new); *x = PAR_C * new.x + tmp; /* *y = sin(xold * PAR_A) + PAR_D * sin(yold * PAR_A); */ old.x = xold * PAR_A; old.y = 0; /* old = (y * A) + 0i (in the complex)*/ CMPLXtrig2(old,new); tmp = (double) new.x; old.x = yold * PAR_A; old.y = 0; /* old = (x * B) + 0i */ CMPLXtrig3(old,new); *y = PAR_D * new.x + tmp; return(0); } #undef PAR_A #undef PAR_B #undef PAR_C #undef PAR_D /**********************************************************************/ /* Main fractal engines - put in fractalspecific[fractype].calctype */ /**********************************************************************/ int inverse_julia_per_image() { int color = 0; if (resuming) /* can't resume */ return -1; while (color >= 0) /* generate points */ { if (check_key()) { Free_Queue(); return -1; } color = curfractalspecific->orbitcalc(); old = new; } Free_Queue(); return 0; } int orbit2dfloat() { FILE *fp; double *soundvar; double x,y,z; int color,col,row; int count; int oldrow, oldcol; double *p0,*p1,*p2; struct affine cvt; int ret; soundvar = p0 = p1 = p2 = NULL; fp = open_orbitsave(); /* setup affine screen coord conversion */ setup_convert_to_screen(&cvt); /* set up projection scheme */ if(projection==0) { p0 = &z; p1 = &x; p2 = &y; } else if(projection==1) { p0 = &x; p1 = &z; p2 = &y; } else if(projection==2) { p0 = &x; p1 = &y; p2 = &z; } if((soundflag&7) == 2) soundvar = &x; else if((soundflag&7) == 3) soundvar = &y; else if((soundflag&7) == 4) soundvar = &z; if(inside > 0) color = inside; else color = 2; if(color >= colors) color = 1; oldcol = oldrow = -1; x = initorbitfp[0]; y = initorbitfp[1]; z = initorbitfp[2]; coloriter = 0L; count = ret = 0; if(maxit > 0x1fffffL || maxct) maxct = 0x7fffffffL; else maxct = maxit*1024L; if (resuming) { start_resume(); get_resume(sizeof(count),&count,sizeof(color),&color, sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol, sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,sizeof(t),&t, sizeof(orbit),&orbit,sizeof(coloriter),&coloriter, 0); end_resume(); } while(coloriter++ <= maxct) /* loop until keypress or maxit */ { if(keypressed()) { mute(); alloc_resume(100,1); put_resume(sizeof(count),&count,sizeof(color),&color, sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol, sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,sizeof(t),&t, sizeof(orbit),&orbit,sizeof(coloriter),&coloriter, 0); ret = -1; break; } if (++count > 1000) { /* time to switch colors? */ count = 0; if (++color >= colors) /* another color to switch to? */ color = 1; /* (don't use the background color) */ } col = (int)(cvt.a*x + cvt.b*y + cvt.e); row = (int)(cvt.c*x + cvt.d*y + cvt.f); if ( col >= 0 && col < xdots && row >= 0 && row < ydots ) { if ((soundflag&7) > 1) w_snd((int)(*soundvar*100+basehertz)); if((fractype!=ICON) && (fractype!=LATOO)) { if(oldcol != -1 && connect) draw_line(col,row,oldcol,oldrow,color%colors); else (*plot)(col,row,color%colors); } else { /* should this be using plothist()? */ color = getcolor(col,row)+1; if( color < colors ) /* color sticks on last value */ (*plot)(col,row,color); } oldcol = col; oldrow = row; } else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */ return(ret); else oldrow = oldcol = -1; if(FORBIT(p0, p1, p2)) break; if(fp) fprintf(fp,orbitsave_format,*p0,*p1,0.0); } if(fp) fclose(fp); return(ret); } int orbit2dlong() { FILE *fp; long *soundvar; long x,y,z; int color,col,row; int count; int oldrow, oldcol; long *p0,*p1,*p2; struct l_affine cvt; int ret,start; start = 1; soundvar = p0 = p1 = p2 = NULL; fp = open_orbitsave(); /* setup affine screen coord conversion */ l_setup_convert_to_screen(&cvt); /* set up projection scheme */ if(projection==0) { p0 = &z; p1 = &x; p2 = &y; } else if(projection==1) { p0 = &x; p1 = &z; p2 = &y; } else if(projection==2) { p0 = &x; p1 = &y; p2 = &z; } if((soundflag&7)==2) soundvar = &x; else if((soundflag&7)==3) soundvar = &y; else if((soundflag&7)==4) soundvar = &z; if(inside > 0) color = inside; else color = 2; if(color >= colors) color = 1; oldcol = oldrow = -1; x = initorbitlong[0]; y = initorbitlong[1]; z = initorbitlong[2]; count = ret = 0; if(maxit > 0x1fffffL || maxct) maxct = 0x7fffffffL; else maxct = maxit*1024L; coloriter = 0L; if (resuming) { start_resume(); get_resume(sizeof(count),&count,sizeof(color),&color, sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol, sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,sizeof(t),&t, sizeof(l_orbit),&l_orbit,sizeof(coloriter),&coloriter, 0); end_resume(); } while(coloriter++ <= maxct) /* loop until keypress or maxit */ { if(keypressed()) { mute(); alloc_resume(100,1); put_resume(sizeof(count),&count,sizeof(color),&color, sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol, sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,sizeof(t),&t, sizeof(l_orbit),&l_orbit,sizeof(coloriter),&coloriter, 0); ret = -1; break; } if (++count > 1000) { /* time to switch colors? */ count = 0; if (++color >= colors) /* another color to switch to? */ color = 1; /* (don't use the background color) */ } col = (int)((multiply(cvt.a,x,bitshift) + multiply(cvt.b,y,bitshift) + cvt.e) >> bitshift); row = (int)((multiply(cvt.c,x,bitshift) + multiply(cvt.d,y,bitshift) + cvt.f) >> bitshift); if(overflow) { overflow = 0; return(ret); } if ( col >= 0 && col < xdots && row >= 0 && row < ydots ) { if ((soundflag&7) > 1) { double yy; yy = *soundvar; yy = yy/fudge; w_snd((int)(yy*100+basehertz)); } if(oldcol != -1 && connect) draw_line(col,row,oldcol,oldrow,color%colors); else if(!start) (*plot)(col,row,color%colors); oldcol = col; oldrow = row; start = 0; } else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */ return(ret); else oldrow = oldcol = -1; /* Calculate the next point */ if(LORBIT(p0, p1, p2)) break; if(fp) fprintf(fp,orbitsave_format,(double)*p0/fudge,(double)*p1/fudge,0.0); } if(fp) fclose(fp); return(ret); } static int orbit3dlongcalc(void) { FILE *fp; unsigned long count; int oldcol,oldrow; int oldcol1,oldrow1; struct long3dvtinf inf; int color; int ret; /* setup affine screen coord conversion */ l_setup_convert_to_screen(&inf.cvt); oldcol1 = oldrow1 = oldcol = oldrow = -1; color = 2; if(color >= colors) color = 1; inf.orbit[0] = initorbitlong[0]; inf.orbit[1] = initorbitlong[1]; inf.orbit[2] = initorbitlong[2]; if(diskvideo) /* this would KILL a disk drive! */ notdiskmsg(); fp = open_orbitsave(); count = ret = 0; if(maxit > 0x1fffffL || maxct) maxct = 0x7fffffffL; else maxct = maxit*1024L; coloriter = 0L; while(coloriter++ <= maxct) /* loop until keypress or maxit */ { /* calc goes here */ if (++count > 1000) { /* time to switch colors? */ count = 0; if (++color >= colors) /* another color to switch to? */ color = 1; /* (don't use the background color) */ } if(keypressed()) { mute(); ret = -1; break; } LORBIT(&inf.orbit[0],&inf.orbit[1],&inf.orbit[2]); if(fp) fprintf(fp,orbitsave_format,(double)inf.orbit[0]/fudge,(double)inf.orbit[1]/fudge,(double)inf.orbit[2]/fudge); if (long3dviewtransf(&inf)) { /* plot if inside window */ if (inf.col >= 0) { if(realtime) whichimage=1; if ((soundflag&7) > 1) { double yy; yy = inf.viewvect[((soundflag&7) - 2)]; yy = yy/fudge; w_snd((int)(yy*100+basehertz)); } if(oldcol != -1 && connect) draw_line(inf.col,inf.row,oldcol,oldrow,color%colors); else (*plot)(inf.col,inf.row,color%colors); } else if (inf.col == -2) return(ret); oldcol = inf.col; oldrow = inf.row; if(realtime) { whichimage=2; /* plot if inside window */ if (inf.col1 >= 0) { if(oldcol1 != -1 && connect) draw_line(inf.col1,inf.row1,oldcol1,oldrow1,color%colors); else (*plot)(inf.col1,inf.row1,color%colors); } else if (inf.col1 == -2) return(ret); oldcol1 = inf.col1; oldrow1 = inf.row1; } } } if(fp) fclose(fp); return(ret); } static int orbit3dfloatcalc(void) { FILE *fp; unsigned long count; int oldcol,oldrow; int oldcol1,oldrow1; int color; int ret; struct float3dvtinf inf; /* setup affine screen coord conversion */ setup_convert_to_screen(&inf.cvt); oldcol = oldrow = -1; oldcol1 = oldrow1 = -1; color = 2; if(color >= colors) color = 1; inf.orbit[0] = initorbitfp[0]; inf.orbit[1] = initorbitfp[1]; inf.orbit[2] = initorbitfp[2]; if(diskvideo) /* this would KILL a disk drive! */ notdiskmsg(); fp = open_orbitsave(); ret = 0; if(maxit > 0x1fffffL || maxct) maxct = 0x7fffffffL; else maxct = maxit*1024L; count = coloriter = 0L; while(coloriter++ <= maxct) /* loop until keypress or maxit */ { /* calc goes here */ if (++count > 1000) { /* time to switch colors? */ count = 0; if (++color >= colors) /* another color to switch to? */ color = 1; /* (don't use the background color) */ } if(keypressed()) { mute(); ret = -1; break; } FORBIT(&inf.orbit[0],&inf.orbit[1],&inf.orbit[2]); if(fp) fprintf(fp,orbitsave_format,inf.orbit[0],inf.orbit[1],inf.orbit[2]); if (float3dviewtransf(&inf)) { /* plot if inside window */ if (inf.col >= 0) { if(realtime) whichimage=1; if ((soundflag&7) > 1) { w_snd((int)(inf.viewvect[((soundflag&7) - 2)]*100+basehertz)); } if(oldcol != -1 && connect) draw_line(inf.col,inf.row,oldcol,oldrow,color%colors); else (*plot)(inf.col,inf.row,color%colors); } else if (inf.col == -2) return(ret); oldcol = inf.col; oldrow = inf.row; if(realtime) { whichimage=2; /* plot if inside window */ if (inf.col1 >= 0) { if(oldcol1 != -1 && connect) draw_line(inf.col1,inf.row1,oldcol1,oldrow1,color%colors); else (*plot)(inf.col1,inf.row1,color%colors); } else if (inf.col1 == -2) return(ret); oldcol1 = inf.col1; oldrow1 = inf.row1; } } } if(fp) fclose(fp); return(ret); } int dynam2dfloatsetup() { connect = 0; euler = 0; d = param[0]; /* number of intervals */ if (d<0) { d = -d; connect = 1; } else if (d==0) { d = 1; } if (fractype==DYNAMICFP) { a = param[2]; /* parameter */ b = param[3]; /* parameter */ dt = param[1]; /* step size */ if (dt<0) { dt = -dt; euler = 1; } if (dt==0) dt = 0.01; } if (outside == SUM) { plot = plothist; } return(1); } /* * This is the routine called to perform a time-discrete dynamical * system image. * The starting positions are taken by stepping across the image in steps * of parameter1 pixels. maxit differential equation steps are taken, with * a step size of parameter2. */ int dynam2dfloat() { FILE *fp; double *soundvar = NULL; double x,y,z; int color,col,row; long count; int oldrow, oldcol; double *p0,*p1; struct affine cvt; int ret; int xstep, ystep; /* The starting position step number */ double xpixel, ypixel; /* Our pixel position on the screen */ fp = open_orbitsave(); /* setup affine screen coord conversion */ setup_convert_to_screen(&cvt); p0 = &x; p1 = &y; if((soundflag&7)==2) soundvar = &x; else if((soundflag&7)==3) soundvar = &y; else if((soundflag&7)==4) soundvar = &z; count = 0; if(inside > 0) color = inside; if(color >= colors) color = 1; oldcol = oldrow = -1; xstep = -1; ystep = 0; if (resuming) { start_resume(); get_resume(sizeof(count),&count, sizeof(color),&color, sizeof(oldrow),&oldrow, sizeof(oldcol),&oldcol, sizeof(x),&x, sizeof(y), &y, sizeof(xstep), &xstep, sizeof(ystep), &ystep, 0); end_resume(); } ret = 0; for(;;) { if(keypressed()) { mute(); alloc_resume(100,1); put_resume(sizeof(count),&count, sizeof(color),&color, sizeof(oldrow),&oldrow, sizeof(oldcol),&oldcol, sizeof(x),&x, sizeof(y), &y, sizeof(xstep), &xstep, sizeof(ystep), &ystep, 0); ret = -1; break; } xstep ++; if (xstep>=d) { xstep = 0; ystep ++; if (ystep>d) { mute(); ret = -1; break; } } xpixel = dxsize*(xstep+.5)/d; ypixel = dysize*(ystep+.5)/d; x = (double)((xxmin+delxx*xpixel) + (delxx2*ypixel)); y = (double)((yymax-delyy*ypixel) + (-delyy2*xpixel)); if (fractype==MANDELCLOUD) { a = x; b = y; } oldcol = -1; if (++color >= colors) /* another color to switch to? */ color = 1; /* (don't use the background color) */ for (count=0;count= 0 && col < xdots && row >= 0 && row < ydots ) { if ((soundflag&7) > 1) w_snd((int)(*soundvar*100+basehertz)); if (count>=orbit_delay) { if(oldcol != -1 && connect) draw_line(col,row,oldcol,oldrow,color%colors); else if(count > 0 || fractype != MANDELCLOUD) (*plot)(col,row,color%colors); } oldcol = col; oldrow = row; } else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */ return(ret); else oldrow = oldcol = -1; if(FORBIT(p0, p1, NULL)) break; if(fp) fprintf(fp,orbitsave_format,*p0,*p1,0.0); } } if(fp) fclose(fp); return(ret); } int keep_scrn_coords = 0; int set_orbit_corners = 0; long orbit_interval; double oxmin, oymin, oxmax, oymax, ox3rd, oy3rd; struct affine o_cvt; static int o_color; int setup_orbits_to_screen(struct affine *scrn_cnvt) { double det, xd, yd; if((det = (ox3rd-oxmin)*(oymin-oymax) + (oymax-oy3rd)*(oxmax-oxmin))==0) return(-1); xd = dxsize/det; scrn_cnvt->a = xd*(oymax-oy3rd); scrn_cnvt->b = xd*(ox3rd-oxmin); scrn_cnvt->e = -scrn_cnvt->a*oxmin - scrn_cnvt->b*oymax; if((det = (ox3rd-oxmax)*(oymin-oymax) + (oymin-oy3rd)*(oxmax-oxmin))==0) return(-1); yd = dysize/det; scrn_cnvt->c = yd*(oymin-oy3rd); scrn_cnvt->d = yd*(ox3rd-oxmax); scrn_cnvt->f = -scrn_cnvt->c*oxmin - scrn_cnvt->d*oymax; return(0); } int plotorbits2dsetup(void) { #ifndef XFRACT if (curfractalspecific->isinteger != 0) { int tofloat; if ((tofloat = curfractalspecific->tofloat) == NOFRACTAL) return(-1); floatflag = usr_floatflag = 1; /* force floating point */ curfractalspecific = &fractalspecific[tofloat]; fractype = tofloat; } #endif PER_IMAGE(); /* setup affine screen coord conversion */ if (keep_scrn_coords) { if(setup_orbits_to_screen(&o_cvt)) return(-1); } else { if(setup_convert_to_screen(&o_cvt)) return(-1); } /* set so truncation to int rounds to nearest */ o_cvt.e += 0.5; o_cvt.f += 0.5; if (orbit_delay >= maxit) /* make sure we get an image */ orbit_delay = (int)(maxit - 1); o_color = 1; if (outside == SUM) { plot = plothist; } return(1); } int plotorbits2dfloat(void) { double *soundvar = NULL; double x,y,z; int col,row; long count; if(keypressed()) { mute(); alloc_resume(100,1); put_resume(sizeof(o_color),&o_color, 0); return(-1); } #if 0 col = (int)(o_cvt.a*new.x + o_cvt.b*new.y + o_cvt.e); row = (int)(o_cvt.c*new.x + o_cvt.d*new.y + o_cvt.f); if ( col >= 0 && col < xdots && row >= 0 && row < ydots ) (*plot)(col,row,1); return(0); #endif if((soundflag&7)==2) soundvar = &x; else if((soundflag&7)==3) soundvar = &y; else if((soundflag&7)==4) soundvar = &z; if (resuming) { start_resume(); get_resume(sizeof(o_color),&o_color, 0); end_resume(); } if(inside > 0) o_color = inside; else { /* inside <= 0 */ o_color++; if (o_color >= colors) /* another color to switch to? */ o_color = 1; /* (don't use the background color) */ } PER_PIXEL(); /* initialize the calculations */ for (count = 0; count < maxit; count++) { if (ORBITCALC() == 1 && periodicitycheck) continue; /* bailed out, don't plot */ if (count < orbit_delay || count%orbit_interval) continue; /* don't plot it */ /* else count >= orbit_delay and we want to plot it */ col = (int)(o_cvt.a*new.x + o_cvt.b*new.y + o_cvt.e); row = (int)(o_cvt.c*new.x + o_cvt.d*new.y + o_cvt.f); #ifdef XFRACT if ( col >= 0 && col < xdots && row >= 0 && row < ydots ) #else /* don't know why the next line is necessary, the one above should work */ if ( col > 0 && col < xdots && row > 0 && row < ydots ) #endif { /* plot if on the screen */ if ((soundflag&7) > 1) w_snd((int)(*soundvar*100+basehertz)); (*plot)(col,row,o_color%colors); } else { /* off screen, don't continue unless periodicity=0 */ if (periodicitycheck) return(0); /* skip to next pixel */ } } return(0); } /* this function's only purpose is to manage funnyglasses related */ /* stuff so the code is not duplicated for ifs3d() and lorenz3d() */ int funny_glasses_call(int (*calc)(void)) { int status; status = 0; if(glassestype) whichimage = 1; else whichimage = 0; plot_setup(); plot = standardplot; status = calc(); if(realtime && glassestype < 3) { realtime = 0; goto done; } if(glassestype && status == 0 && display3d) { if(glassestype==3) { /* photographer's mode */ if(active_system == 0) { /* dos version */ int i; static FCODE firstready[]={"\ First image (left eye) is ready. Hit any key to see it,\n\ then hit to save, hit any other key to create second image."}; stopmsg(16,firstready); while ((i = getakey()) == 's' || i == 'S') { diskisactive = 1; savetodisk(savename); diskisactive = 0; } /* is there a better way to clear the screen in graphics mode? */ setvideomode(videoentry.videomodeax, videoentry.videomodebx, videoentry.videomodecx, videoentry.videomodedx); } else { /* Windows version */ static FCODE firstready2[]={"First (Left Eye) image is complete"}; stopmsg(0,firstready2); clear_screen(0); } } whichimage = 2; if(curfractalspecific->flags & INFCALC) curfractalspecific->per_image(); /* reset for 2nd image */ plot_setup(); plot = standardplot; /* is there a better way to clear the graphics screen ? */ if((status = calc()) != 0) goto done; if(glassestype==3) /* photographer's mode */ if(active_system == 0) { /* dos version */ static FCODE secondready[]={"Second image (right eye) is ready"}; stopmsg(16,secondready); } } done: if(glassestype == 4 && sxdots >= 2*xdots) { /* turn off view windows so will save properly */ sxoffs = syoffs = 0; xdots = sxdots; ydots = sydots; viewwindow = 0; } return(status); } /* double version - mainly for testing */ static int ifs3dfloat(void) { int color_method; FILE *fp; int color; double newx,newy,newz,r,sum; int k; int ret; struct float3dvtinf inf; float far *ffptr; /* setup affine screen coord conversion */ setup_convert_to_screen(&inf.cvt); srand(1); color_method = (int)param[0]; if(diskvideo) /* this would KILL a disk drive! */ notdiskmsg(); inf.orbit[0] = 0; inf.orbit[1] = 0; inf.orbit[2] = 0; fp = open_orbitsave(); ret = 0; if(maxit > 0x1fffffL) maxct = 0x7fffffffL; else maxct = maxit*1024; coloriter = 0L; while(coloriter++ <= maxct) /* loop until keypress or maxit */ { if( keypressed() ) /* keypress bails out */ { ret = -1; break; } r = rand(); /* generate a random number between 0 and 1 */ r /= RAND_MAX; /* pick which iterated function to execute, weighted by probability */ sum = ifs_defn[12]; /* [0][12] */ k = 0; while ( sum < r && ++k < numaffine*IFS3DPARM) { sum += ifs_defn[k*IFS3DPARM+12]; if (ifs_defn[(k+1)*IFS3DPARM+12] == 0) break; /* for safety */ } /* calculate image of last point under selected iterated function */ ffptr = ifs_defn + k*IFS3DPARM; /* point to first parm in row */ newx = *ffptr * inf.orbit[0] + *(ffptr+1) * inf.orbit[1] + *(ffptr+2) * inf.orbit[2] + *(ffptr+9); newy = *(ffptr+3) * inf.orbit[0] + *(ffptr+4) * inf.orbit[1] + *(ffptr+5) * inf.orbit[2] + *(ffptr+10); newz = *(ffptr+6) * inf.orbit[0] + *(ffptr+7) * inf.orbit[1] + *(ffptr+8) * inf.orbit[2] + *(ffptr+11); inf.orbit[0] = newx; inf.orbit[1] = newy; inf.orbit[2] = newz; if(fp) fprintf(fp,orbitsave_format,newx,newy,newz); if (float3dviewtransf(&inf)) { /* plot if inside window */ if (inf.col >= 0) { if(realtime) whichimage=1; if(color_method) color = (k%colors)+1; else color = getcolor(inf.col,inf.row)+1; if( color < colors ) /* color sticks on last value */ (*plot)(inf.col,inf.row,color); } else if (inf.col == -2) return(ret); if(realtime) { whichimage=2; /* plot if inside window */ if (inf.col1 >= 0) { if(color_method) color = (k%colors)+1; else color = getcolor(inf.col1,inf.row1)+1; if( color < colors ) /* color sticks on last value */ (*plot)(inf.col1,inf.row1,color); } else if (inf.col1 == -2) return(ret); } } } /* end while */ if(fp) fclose(fp); return(ret); } int ifs() /* front-end for ifs2d and ifs3d */ { if (ifs_defn == NULL && ifsload() < 0) return(-1); if(diskvideo) /* this would KILL a disk drive! */ notdiskmsg(); return((ifs_type == 0) ? ifs2d() : ifs3d()); } /* IFS logic shamelessly converted to integer math */ static int ifs2d(void) { int color_method; FILE *fp; int col; int row; int color; int ret; long far *localifs; long far *lfptr; long x,y,newx,newy,r,sum, tempr; int i,j,k; struct l_affine cvt; /* setup affine screen coord conversion */ l_setup_convert_to_screen(&cvt); srand(1); color_method = (int)param[0]; if((localifs=(long far *)farmemalloc((long)numaffine*IFSPARM*sizeof(long)))==NULL) { stopmsg(0,insufficient_ifs_mem); return(-1); } for (i = 0; i < numaffine; i++) /* fill in the local IFS array */ for (j = 0; j < IFSPARM; j++) localifs[i*IFSPARM+j] = (long)(ifs_defn[i*IFSPARM+j] * fudge); tempr = fudge / 32767; /* find the proper rand() fudge */ fp = open_orbitsave(); x = y = 0; ret = 0; if(maxit > 0x1fffffL) maxct = 0x7fffffffL; else maxct = maxit*1024L; coloriter = 0L; while(coloriter++ <= maxct) /* loop until keypress or maxit */ { if( keypressed() ) /* keypress bails out */ { ret = -1; break; } r = rand15(); /* generate fudged random number between 0 and 1 */ r *= tempr; /* pick which iterated function to execute, weighted by probability */ sum = localifs[6]; /* [0][6] */ k = 0; while ( sum < r && k < numaffine-1) /* fixed bug of error if sum < 1 */ sum += localifs[++k*IFSPARM+6]; /* calculate image of last point under selected iterated function */ lfptr = localifs + k*IFSPARM; /* point to first parm in row */ newx = multiply(lfptr[0],x,bitshift) + multiply(lfptr[1],y,bitshift) + lfptr[4]; newy = multiply(lfptr[2],x,bitshift) + multiply(lfptr[3],y,bitshift) + lfptr[5]; x = newx; y = newy; if(fp) fprintf(fp,orbitsave_format,(double)newx/fudge,(double)newy/fudge,0.0); /* plot if inside window */ col = (int)((multiply(cvt.a,x,bitshift) + multiply(cvt.b,y,bitshift) + cvt.e) >> bitshift); row = (int)((multiply(cvt.c,x,bitshift) + multiply(cvt.d,y,bitshift) + cvt.f) >> bitshift); if ( col >= 0 && col < xdots && row >= 0 && row < ydots ) { /* color is count of hits on this pixel */ if(color_method) color = (k%colors)+1; else color = getcolor(col,row)+1; if( color < colors ) /* color sticks on last value */ (*plot)(col,row,color); } else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */ return(ret); } if(fp) fclose(fp); farmemfree(localifs); return(ret); } static int ifs3dlong(void) { int color_method; FILE *fp; int color; int ret; long far *localifs; long far *lfptr; long newx,newy,newz,r,sum, tempr; int i,j,k; struct long3dvtinf inf; srand(1); color_method = (int)param[0]; if((localifs=(long far *)farmemalloc((long)numaffine*IFS3DPARM*sizeof(long)))==NULL) { stopmsg(0,insufficient_ifs_mem); return(-1); } /* setup affine screen coord conversion */ l_setup_convert_to_screen(&inf.cvt); for (i = 0; i < numaffine; i++) /* fill in the local IFS array */ for (j = 0; j < IFS3DPARM; j++) localifs[i*IFS3DPARM+j] = (long)(ifs_defn[i*IFS3DPARM+j] * fudge); tempr = fudge / 32767; /* find the proper rand() fudge */ inf.orbit[0] = 0; inf.orbit[1] = 0; inf.orbit[2] = 0; fp = open_orbitsave(); ret = 0; if(maxit > 0x1fffffL) maxct = 0x7fffffffL; else maxct = maxit*1024L; coloriter = 0L; while(coloriter++ <= maxct) /* loop until keypress or maxit */ { if( keypressed() ) /* keypress bails out */ { ret = -1; break; } r = rand15(); /* generate fudged random number between 0 and 1 */ r *= tempr; /* pick which iterated function to execute, weighted by probability */ sum = localifs[12]; /* [0][12] */ k = 0; while ( sum < r && ++k < numaffine*IFS3DPARM) { sum += localifs[k*IFS3DPARM+12]; if (ifs_defn[(k+1)*IFS3DPARM+12] == 0) break; /* for safety */ } /* calculate image of last point under selected iterated function */ lfptr = localifs + k*IFS3DPARM; /* point to first parm in row */ /* calculate image of last point under selected iterated function */ newx = multiply(lfptr[0], inf.orbit[0], bitshift) + multiply(lfptr[1], inf.orbit[1], bitshift) + multiply(lfptr[2], inf.orbit[2], bitshift) + lfptr[9]; newy = multiply(lfptr[3], inf.orbit[0], bitshift) + multiply(lfptr[4], inf.orbit[1], bitshift) + multiply(lfptr[5], inf.orbit[2], bitshift) + lfptr[10]; newz = multiply(lfptr[6], inf.orbit[0], bitshift) + multiply(lfptr[7], inf.orbit[1], bitshift) + multiply(lfptr[8], inf.orbit[2], bitshift) + lfptr[11]; inf.orbit[0] = newx; inf.orbit[1] = newy; inf.orbit[2] = newz; if(fp) fprintf(fp,orbitsave_format,(double)newx/fudge,(double)newy/fudge,(double)newz/fudge); if (long3dviewtransf(&inf)) { if((long)abs(inf.row) + (long)abs(inf.col) > BAD_PIXEL) /* sanity check */ return(ret); /* plot if inside window */ if (inf.col >= 0) { if(realtime) whichimage=1; if(color_method) color = (k%colors)+1; else color = getcolor(inf.col,inf.row)+1; if( color < colors ) /* color sticks on last value */ (*plot)(inf.col,inf.row,color); } if(realtime) { whichimage=2; /* plot if inside window */ if (inf.col1 >= 0) { if(color_method) color = (k%colors)+1; else color = getcolor(inf.col1,inf.row1)+1; if( color < colors ) /* color sticks on last value */ (*plot)(inf.col1,inf.row1,color); } } } } if(fp) fclose(fp); farmemfree(localifs); return(ret); } static void setupmatrix(MATRIX doublemat) { /* build transformation matrix */ identity (doublemat); /* apply rotations - uses the same rotation variables as line3d.c */ xrot ((double)XROT / 57.29577,doublemat); yrot ((double)YROT / 57.29577,doublemat); zrot ((double)ZROT / 57.29577,doublemat); /* apply scale */ /* scale((double)XSCALE/100.0,(double)YSCALE/100.0,(double)ROUGH/100.0,doublemat);*/ } int orbit3dfloat() { display3d = -1; if(0 < glassestype && glassestype < 3) realtime = 1; else realtime = 0; return(funny_glasses_call(orbit3dfloatcalc)); } int orbit3dlong() { display3d = -1; if(0 < glassestype && glassestype < 3) realtime = 1; else realtime = 0; return(funny_glasses_call(orbit3dlongcalc)); } static int ifs3d(void) { display3d = -1; if(0 < glassestype && glassestype < 3) realtime = 1; else realtime = 0; if(floatflag) return(funny_glasses_call(ifs3dfloat)); /* double version of ifs3d */ else return(funny_glasses_call(ifs3dlong)); /* long version of ifs3d */ } static int long3dviewtransf(struct long3dvtinf *inf) { int i,j; double tmpx, tmpy, tmpz; long tmp; if (coloriter == 1) /* initialize on first call */ { for(i=0;i<3;i++) { inf->minvals[i] = 1L << 30; inf->maxvals[i] = -inf->minvals[i]; } setupmatrix(inf->doublemat); if(realtime) setupmatrix(inf->doublemat1); /* copy xform matrix to long for for fixed point math */ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { inf->longmat[i][j] = (long)(inf->doublemat[i][j] * fudge); if(realtime) inf->longmat1[i][j] = (long)(inf->doublemat1[i][j] * fudge); } } /* 3D VIEWING TRANSFORM */ longvmult(inf->orbit,inf->longmat,inf->viewvect,bitshift); if(realtime) longvmult(inf->orbit,inf->longmat1,inf->viewvect1,bitshift); if(coloriter <= waste) /* waste this many points to find minz and maxz */ { /* find minz and maxz */ for(i=0;i<3;i++) if ((tmp = inf->viewvect[i]) < inf->minvals[i]) inf->minvals[i] = tmp; else if (tmp > inf->maxvals[i]) inf->maxvals[i] = tmp; if(coloriter == waste) /* time to work it out */ { inf->iview[0] = inf->iview[1] = 0L; /* center viewer on origin */ /* z value of user's eye - should be more negative than extreme negative part of image */ inf->iview[2] = (long)((inf->minvals[2]-inf->maxvals[2])*(double)ZVIEWER/100.0); /* center image on origin */ tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0*fudge); /* center x */ tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0*fudge); /* center y */ /* apply perspective shift */ tmpx += ((double)xshift*(xxmax-xxmin))/(xdots); tmpy += ((double)yshift*(yymax-yymin))/(ydots); tmpz = -((double)inf->maxvals[2]) / fudge; trans(tmpx,tmpy,tmpz,inf->doublemat); if(realtime) { /* center image on origin */ tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0*fudge); /* center x */ tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0*fudge); /* center y */ tmpx += ((double)xshift1*(xxmax-xxmin))/(xdots); tmpy += ((double)yshift1*(yymax-yymin))/(ydots); tmpz = -((double)inf->maxvals[2]) / fudge; trans(tmpx,tmpy,tmpz,inf->doublemat1); } for(i=0;i<3;i++) view[i] = (double)inf->iview[i] / fudge; /* copy xform matrix to long for for fixed point math */ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { inf->longmat[i][j] = (long)(inf->doublemat[i][j] * fudge); if(realtime) inf->longmat1[i][j] = (long)(inf->doublemat1[i][j] * fudge); } } return(0); } /* apply perspective if requested */ if(ZVIEWER) { if(debugflag==22 || ZVIEWER < 100) /* use float for small persp */ { /* use float perspective calc */ VECTOR tmpv; for(i=0;i<3;i++) tmpv[i] = (double)inf->viewvect[i] / fudge; perspective(tmpv); for(i=0;i<3;i++) inf->viewvect[i] = (long)(tmpv[i]*fudge); if(realtime) { for(i=0;i<3;i++) tmpv[i] = (double)inf->viewvect1[i] / fudge; perspective(tmpv); for(i=0;i<3;i++) inf->viewvect1[i] = (long)(tmpv[i]*fudge); } } else { longpersp(inf->viewvect,inf->iview,bitshift); if(realtime) longpersp(inf->viewvect1,inf->iview,bitshift); } } /* work out the screen positions */ inf->row = (int)(((multiply(inf->cvt.c,inf->viewvect[0],bitshift) + multiply(inf->cvt.d,inf->viewvect[1],bitshift) + inf->cvt.f) >> bitshift) + yyadjust); inf->col = (int)(((multiply(inf->cvt.a,inf->viewvect[0],bitshift) + multiply(inf->cvt.b,inf->viewvect[1],bitshift) + inf->cvt.e) >> bitshift) + xxadjust); if (inf->col < 0 || inf->col >= xdots || inf->row < 0 || inf->row >= ydots) { if((long)abs(inf->col)+(long)abs(inf->row) > BAD_PIXEL) inf->col= inf->row = -2; else inf->col= inf->row = -1; } if(realtime) { inf->row1 = (int)(((multiply(inf->cvt.c,inf->viewvect1[0],bitshift) + multiply(inf->cvt.d,inf->viewvect1[1],bitshift) + inf->cvt.f) >> bitshift) + yyadjust1); inf->col1 = (int)(((multiply(inf->cvt.a,inf->viewvect1[0],bitshift) + multiply(inf->cvt.b,inf->viewvect1[1],bitshift) + inf->cvt.e) >> bitshift) + xxadjust1); if (inf->col1 < 0 || inf->col1 >= xdots || inf->row1 < 0 || inf->row1 >= ydots) { if((long)abs(inf->col1)+(long)abs(inf->row1) > BAD_PIXEL) inf->col1= inf->row1 = -2; else inf->col1= inf->row1 = -1; } } return(1); } static int float3dviewtransf(struct float3dvtinf *inf) { int i; double tmpx, tmpy, tmpz; double tmp; if (coloriter == 1) /* initialize on first call */ { for(i=0;i<3;i++) { inf->minvals[i] = 100000.0; /* impossible value */ inf->maxvals[i] = -100000.0; } setupmatrix(inf->doublemat); if(realtime) setupmatrix(inf->doublemat1); } /* 3D VIEWING TRANSFORM */ vmult(inf->orbit,inf->doublemat,inf->viewvect ); if(realtime) vmult(inf->orbit,inf->doublemat1,inf->viewvect1); if(coloriter <= waste) /* waste this many points to find minz and maxz */ { /* find minz and maxz */ for(i=0;i<3;i++) if ((tmp = inf->viewvect[i]) < inf->minvals[i]) inf->minvals[i] = tmp; else if (tmp > inf->maxvals[i]) inf->maxvals[i] = tmp; if(coloriter == waste) /* time to work it out */ { view[0] = view[1] = 0; /* center on origin */ /* z value of user's eye - should be more negative than extreme negative part of image */ view[2] = (inf->minvals[2]-inf->maxvals[2])*(double)ZVIEWER/100.0; /* center image on origin */ tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0); /* center x */ tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0); /* center y */ /* apply perspective shift */ tmpx += ((double)xshift*(xxmax-xxmin))/(xdots); tmpy += ((double)yshift*(yymax-yymin))/(ydots); tmpz = -(inf->maxvals[2]); trans(tmpx,tmpy,tmpz,inf->doublemat); if(realtime) { /* center image on origin */ tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0); /* center x */ tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0); /* center y */ tmpx += ((double)xshift1*(xxmax-xxmin))/(xdots); tmpy += ((double)yshift1*(yymax-yymin))/(ydots); tmpz = -(inf->maxvals[2]); trans(tmpx,tmpy,tmpz,inf->doublemat1); } } return(0); } /* apply perspective if requested */ if(ZVIEWER) { perspective(inf->viewvect); if(realtime) perspective(inf->viewvect1); } inf->row = (int)(inf->cvt.c*inf->viewvect[0] + inf->cvt.d*inf->viewvect[1] + inf->cvt.f + yyadjust); inf->col = (int)(inf->cvt.a*inf->viewvect[0] + inf->cvt.b*inf->viewvect[1] + inf->cvt.e + xxadjust); if (inf->col < 0 || inf->col >= xdots || inf->row < 0 || inf->row >= ydots) { if((long)abs(inf->col)+(long)abs(inf->row) > BAD_PIXEL) inf->col= inf->row = -2; else inf->col= inf->row = -1; } if(realtime) { inf->row1 = (int)(inf->cvt.c*inf->viewvect1[0] + inf->cvt.d*inf->viewvect1[1] + inf->cvt.f + yyadjust1); inf->col1 = (int)(inf->cvt.a*inf->viewvect1[0] + inf->cvt.b*inf->viewvect1[1] + inf->cvt.e + xxadjust1); if (inf->col1 < 0 || inf->col1 >= xdots || inf->row1 < 0 || inf->row1 >= ydots) { if((long)abs(inf->col1)+(long)abs(inf->row1) > BAD_PIXEL) inf->col1= inf->row1 = -2; else inf->col1= inf->row1 = -1; } } return(1); } static FILE *open_orbitsave(void) { FILE *fp; if ((orbitsave&1) && (fp = fopen(orbitsavename,"w")) != NULL) { fprintf(fp,"pointlist x y z color\n"); return fp; } return NULL; } /* Plot a histogram by incrementing the pixel each time it it touched */ static void _fastcall plothist(int x, int y, int color) { color = getcolor(x,y)+1; if (color >= colors) color = 1; putcolor(x,y,color); } xfractint-20.4.10.orig/common/comwin.mak0000755000000000000000000000726410541650033014774 0ustar # Note that frachelp.mak and fractint.mak can't be combined into a single # make file because with MSC6 we need to use "NMK", to have enough memory # available for the compiler. NMK would not trigger subsequent recompiles # due to a rebuild of helpdefs.h file if we used a single step. OBJ = 3d.obj ant.obj bigflt.obj biginit.obj bignum.obj calcfrac.obj \ cmdfiles.obj decoder.obj editpal.obj encoder.obj evolve.obj \ f16.obj fracsubr.obj fractals.obj fractalp.obj fractalb.obj \ frasetup.obj gifview.obj hcmplx.obj help.obj history.obj \ jb.obj jiim.obj line3d.obj loadfile.obj loadmap.obj \ lorenz.obj lsys.obj lsysf.obj memory.obj miscfrac.obj miscovl.obj \ miscres.obj mpmath_c.obj parser.obj parserfp.obj plot3d.obj \ prompts1.obj prompts2.obj soi.obj \ soi1.obj stereo.obj testpt.obj tgaview.obj HFD = ..\headers # Next is a pseudo-target for nmake/nmk. It just generates harmless # warnings with make. all : $(OBJ) .c.obj: $(CC) /I$(HFD) $(OptT) $*.c >> f_errs.txt Optsize = $(CC) /I$(HFD) $(OptS) $*.c >> f_errs.txt Optnoalias = $(CC) /I$(HFD) $(OptN) $*.c >> f_errs.txt 3d.obj : 3d.c $(HFD)\fractint.h ant.obj : ant.c $(HFD)\helpdefs.h bigflt.obj : bigflt.c $(HFD)\big.h $(Optnoalias) biginit.obj : biginit.c $(HFD)\big.h $(Optnoalias) bignum.obj : bignum.c $(HFD)\big.h $(Optnoalias) # only used for non ASM version #bignumc.obj : bignumc.c $(HFD)\big.h # $(Optnoalias) calcfrac.obj : calcfrac.c $(HFD)\fractint.h $(HFD)\mpmath.h cmdfiles.obj : cmdfiles.c $(HFD)\fractint.h $(Optsize) decoder.obj : decoder.c $(HFD)\fractint.h editpal.obj : editpal.c $(HFD)\fractint.h $(Optsize) encoder.obj : encoder.c $(HFD)\fractint.h $(HFD)\fractype.h evolve.obj : evolve.c $(HFD)\fractint.h $(Optnoalias) f16.obj : f16.c $(HFD)\targa_lc.h fracsubr.obj : fracsubr.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(Optnoalias) fractals.obj : fractals.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\mpmath.h $(HFD)\helpdefs.h fractalp.obj : fractalp.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\mpmath.h $(HFD)\helpdefs.h fractalb.obj : fractalb.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\big.h $(HFD)\helpdefs.h frasetup.obj : frasetup.c gifview.obj : gifview.c $(HFD)\fractint.h hcmplx.obj : hcmplx.c $(HFD)\fractint.h help.obj : help.c $(HFD)\fractint.h $(HFD)\helpdefs.h $(HFD)\helpcom.h $(Optsize) history.obj : history.c $(HFD)\fractint.h $(HFD)\fractype.h $(Optsize) jb.obj : jb.c $(HFD)\fractint.h $(HFD)\helpdefs.h jiim.obj : jiim.c $(HFD)\helpdefs.h line3d.obj : line3d.c $(HFD)\fractint.h loadfile.obj : loadfile.c $(HFD)\fractint.h $(HFD)\fractype.h $(Optsize) loadmap.obj : loadmap.c $(HFD)\targa.h $(HFD)\fractint.h $(Optsize) lorenz.obj : lorenz.c $(HFD)\fractint.h $(HFD)\fractype.h lsys.obj : lsys.c $(HFD)\fractint.h $(HFD)\lsys.h lsysf.obj : lsysf.c $(HFD)\fractint.h $(HFD)\lsys.h memory.obj : memory.c miscfrac.obj : miscfrac.c $(HFD)\fractint.h $(HFD)\mpmath.h miscovl.obj : miscovl.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) miscres.obj : miscres.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) mpmath_c.obj : mpmath_c.c $(HFD)\mpmath.h parser.obj : parser.c $(HFD)\fractint.h $(HFD)\mpmath.h $(Optnoalias) parserfp.obj : parserfp.c $(HFD)\fractint.h $(HFD)\mpmath.h $(Optnoalias) plot3d.obj : plot3d.c $(HFD)\fractint.h $(HFD)\fractype.h $(Optnoalias) prompts1.obj : prompts1.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) prompts2.obj : prompts2.c $(HFD)\fractint.h $(HFD)\fractype.h $(HFD)\helpdefs.h $(Optsize) soi.obj : soi.c soi1.obj : soi1.c stereo.obj : stereo.c $(HFD)\helpdefs.h testpt.obj: testpt.c $(HFD)\fractint.h tgaview.obj : tgaview.c $(HFD)\fractint.h $(HFD)\targa_lc.h $(HFD)\port.h xfractint-20.4.10.orig/common/slideshw.c0000644000000000000000000002443411257714555015006 0ustar /***********************************************************************/ /* These routines are called by getakey to allow keystrokes to control */ /* Fractint to be read from a file. */ /***********************************************************************/ #include #include #include #ifndef XFRACT #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" static void sleep_secs(int); static int showtempmsg_txt(int,int,int,int,char *); static void message(int secs, char far *buf); static void slideshowerr(char far *msg); static int get_scancode(char *mn); static void get_mnemonic(int code, char *mnemonic); static FCODE s_ENTER [] = "ENTER" ; static FCODE s_INSERT [] = "INSERT" ; static FCODE s_DELETE [] = "DELETE" ; static FCODE s_ESC [] = "ESC" ; static FCODE s_TAB [] = "TAB" ; static FCODE s_PAGEUP [] = "PAGEUP" ; static FCODE s_PAGEDOWN [] = "PAGEDOWN" ; static FCODE s_HOME [] = "HOME" ; static FCODE s_END [] = "END" ; static FCODE s_LEFT [] = "LEFT" ; static FCODE s_RIGHT [] = "RIGHT" ; static FCODE s_UP [] = "UP" ; static FCODE s_DOWN [] = "DOWN" ; static FCODE s_F1 [] = "F1" ; static FCODE s_CTRL_RIGHT[] = "CTRL_RIGHT"; static FCODE s_CTRL_LEFT [] = "CTRL_LEFT" ; static FCODE s_CTRL_DOWN [] = "CTRL_DOWN" ; static FCODE s_CTRL_UP [] = "CTRL_UP" ; static FCODE s_CTRL_END [] = "CTRL_END" ; static FCODE s_CTRL_HOME [] = "CTRL_HOME" ; #define MAX_MNEMONIC 20 /* max size of any mnemonic string */ struct scancodes { int code; FCODE *mnemonic; }; static struct scancodes far scancodes[] = { { ENTER, s_ENTER }, { INSERT, s_INSERT }, { DELETE, s_DELETE }, { ESC, s_ESC }, { TAB, s_TAB }, { PAGE_UP, s_PAGEUP }, { PAGE_DOWN, s_PAGEDOWN }, { HOME, s_HOME }, { END, s_END }, { LEFT_ARROW, s_LEFT }, { RIGHT_ARROW, s_RIGHT }, { UP_ARROW, s_UP }, { DOWN_ARROW, s_DOWN }, { F1, s_F1 }, { RIGHT_ARROW_2, s_CTRL_RIGHT}, { LEFT_ARROW_2, s_CTRL_LEFT }, { DOWN_ARROW_2, s_CTRL_DOWN }, { UP_ARROW_2, s_CTRL_UP }, { CTL_END, s_CTRL_END }, { CTL_HOME, s_CTRL_HOME }, { -1, NULL } }; #define stop sizeof(scancodes)/sizeof(struct scancodes)-1 static int get_scancode(char *mn) { int i; i = 0; for(i=0;i< stop;i++) if(far_strcmp((char far *)mn,scancodes[i].mnemonic)==0) break; return(scancodes[i].code); } static void get_mnemonic(int code,char *mnemonic) { int i; i = 0; *mnemonic = 0; for(i=0;i< stop;i++) if(code == scancodes[i].code) { far_strcpy(mnemonic,scancodes[i].mnemonic); break; } } #undef stop char busy = 0; static FILE *fpss = NULL; static long starttick; static long ticks; static int slowcount; static unsigned int quotes; static char calcwait = 0; static int repeats = 0; static int last1 = 0; static FCODE smsg[] = "MESSAGE"; static FCODE sgoto[] = "GOTO"; static FCODE scalcwait[] = "CALCWAIT"; static FCODE swait[] = "WAIT"; /* places a temporary message on the screen in text mode */ static int showtempmsg_txt(int row, int col, int attr,int secs,char *txt) { int savescrn[80]; int i; if(text_type > 1) return(1); for(i=0;i<80;i++) { movecursor(row,i); savescrn[i] = get_a_char(); } putstring(row,col,attr,txt); movecursor(25,80); sleep_secs(secs); for(i=0;i<80;i++) { movecursor(row,i); put_a_char(savescrn[i]); } return(0); } static void message(int secs, char far *buf) { int i; char nearbuf[41]; i = -1; while(buf[++i] && i< 40) nearbuf[i] = buf[i]; nearbuf[i] = 0; if(text_type < 2) showtempmsg_txt(0,0,7,secs,nearbuf); else if (showtempmsg(nearbuf) == 0) { sleep_secs(secs); cleartempmsg(); } } /* this routine reads the file autoname and returns keystrokes */ int slideshw() { int out,err,i; char buffer[81]; if(calcwait) { if(calc_status == 1 || busy) /* restart timer - process not done */ return(0); /* wait for calc to finish before reading more keystrokes */ calcwait = 0; } if(fpss==NULL) /* open files first time through */ if(startslideshow()==0) { stopslideshow(); return (0); } if(ticks) /* if waiting, see if waited long enough */ { if(clock_ticks() - starttick < ticks) /* haven't waited long enough */ return(0); ticks = 0; } if (++slowcount <= 18) { starttick = clock_ticks(); ticks = CLK_TCK/5; /* a slight delay so keystrokes are visible */ if (slowcount > 10) ticks /= 2; } if(repeats>0) { repeats--; return(last1); } start: if(quotes) /* reading a quoted string */ { if((out=fgetc(fpss)) != '\"' && out != EOF) return(last1 = out); quotes = 0; } /* skip white space: */ while ((out=fgetc(fpss)) == ' ' || out == '\t' || out == '\n') { } switch(out) { case EOF: stopslideshow(); return(0); case '\"': /* begin quoted string */ quotes = 1; goto start; case ';': /* comment from here to end of line, skip it */ while((out=fgetc(fpss)) != '\n' && out != EOF) { } goto start; case '*': if (fscanf(fpss,"%d",&repeats) != 1 || repeats <= 1 || repeats >= 256 || feof(fpss)) { static FCODE msg[] = "error in * argument"; slideshowerr(msg); last1 = repeats = 0; } repeats -= 2; return(out = last1); } i = 0; for(;;) /* get a token */ { if(i < 80) buffer[i++] = (char)out; if((out=fgetc(fpss)) == ' ' || out == '\t' || out == '\n' || out == EOF) break; } buffer[i] = 0; if(buffer[i-1] == ':') goto start; out = -12345; if(isdigit(buffer[0])) /* an arbitrary scan code number - use it */ out=atoi(buffer); else if(far_strcmp((char far *)buffer,smsg)==0) { int secs; out = 0; if (fscanf(fpss,"%d",&secs) != 1) { static FCODE msg[] = "MESSAGE needs argument"; slideshowerr(msg); } else { int len; char buf[41]; char *dummy; /* to quiet compiler */ buf[40] = 0; dummy = fgets(buf,40,fpss); len = strlen(buf); buf[len-1]=0; /* zap newline */ message(secs,(char far *)buf); } out = 0; } else if(far_strcmp((char far *)buffer,sgoto)==0) { if (fscanf(fpss,"%s",buffer) != 1) { static FCODE msg[] = "GOTO needs target"; slideshowerr(msg); out = 0; } else { char buffer1[80]; rewind(fpss); strcat(buffer,":"); do { err = fscanf(fpss,"%s",buffer1); } while( err == 1 && strcmp(buffer1,buffer) != 0); if(feof(fpss)) { static FCODE msg[] = "GOTO target not found"; slideshowerr(msg); return(0); } goto start; } } else if((i = get_scancode(buffer)) > 0) out = i; else if(far_strcmp(swait,(char far *)buffer)==0) { float fticks; err = fscanf(fpss,"%f",&fticks); /* how many ticks to wait */ fticks *= CLK_TCK; /* convert from seconds to ticks */ if(err==1) { ticks = (long)fticks; starttick = clock_ticks(); /* start timing */ } else { static FCODE msg[] = "WAIT needs argument"; slideshowerr(msg); } slowcount = out = 0; } else if(far_strcmp(scalcwait,(char far *)buffer)==0) /* wait for calc to finish */ { calcwait = 1; slowcount = out = 0; } else if((i=check_vidmode_keyname(buffer)) != 0) out = i; if(out == -12345) { char msg[MSGLEN]; sprintf(msg,s_cantunderstand,buffer); slideshowerr(msg); out = 0; } return(last1 = out); } int startslideshow() { if((fpss=fopen(autoname,"r"))==NULL) slides = 0; ticks = 0; quotes = 0; calcwait = 0; slowcount = 0; return(slides); } void stopslideshow() { if(fpss) fclose(fpss); fpss = NULL; slides = 0; } void recordshw(int key) { char mn[MAX_MNEMONIC]; float dt; dt = (float)ticks; /* save time of last call */ ticks=clock_ticks(); /* current time */ if(fpss==NULL) if((fpss=fopen(autoname,"w"))==NULL) return; dt = ticks-dt; dt /= CLK_TCK; /* dt now in seconds */ if(dt > .5) /* don't bother with less than half a second */ { if(quotes) /* close quotes first */ { quotes=0; fprintf(fpss,"\"\n"); } fprintf(fpss,"WAIT %4.1f\n",dt); } if(key >= 32 && key < 128) { if(!quotes) { quotes=1; fputc('\"',fpss); } fputc(key,fpss); } else { if(quotes) /* not an ASCII character - turn off quotes */ { fprintf(fpss,"\"\n"); quotes=0; } get_mnemonic(key,mn); if(*mn) fprintf(fpss,"%s",mn); else if (check_vidmode_key(0,key) >= 0) { char buf[10]; vidmode_keyname(key,buf); fprintf(fpss,buf); } else /* not ASCII and not FN key */ fprintf(fpss,"%4d",key); fputc('\n',fpss); } } /* suspend process # of seconds */ static void sleep_secs(int secs) { long stop; stop = clock_ticks() + (long)secs*CLK_TCK; while(clock_ticks() < stop && kbhit() == 0) { } /* bailout if key hit */ } static void slideshowerr(char far *msg) { char msgbuf[300]; static FCODE errhdg[] = "Slideshow error:\n"; stopslideshow(); far_strcpy(msgbuf,errhdg); far_strcat(msgbuf,msg); stopmsg(0,msgbuf); } xfractint-20.4.10.orig/common/miscovl.c0000644000000000000000000023426011253454200014620 0ustar /* Overlayed odds and ends that don't fit anywhere else. */ #include #include #include #ifndef XFRACT #include #include #include #endif #ifndef USE_VARARGS #include #else #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" /* routines in this module */ void write_batch_parms(char *colorinf,int colorsonly, int maxcolor,int i, int j); void expand_comments(char far *target, char far *source); #ifndef USE_VARARGS static void put_parm(char *parm,...); #else static void put_parm(); #endif static void put_parm_line(void); static int getprec(double,double,double); int getprecbf(int); static void put_float(int,double,int); static void put_bf(int slash,bf_t r, int prec); static void put_filename(char *keyword,char *fname); #ifndef XFRACT static int check_modekey(int curkey,int choice); #endif static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2); static void update_fractint_cfg(void); static void strip_zeros(char *buf); /* fullscreen_choice options */ #define CHOICERETURNKEY 1 #define CHOICEMENU 2 #define CHOICEHELP 4 char far par_comment[4][MAXCMT]; char s_yes[] = "yes"; char s_no[] = "no"; char s_seqs[] = " %s=%s"; char s_seqd[] = " %s=%d"; char s_seqdd[] = " %s=%d/%d"; char s_seqddd[] = " %s=%d/%d/%d"; char s_seqldddd[] = " %s=%ld/%d/%d/%d"; char s_seqd12[] = " %s=%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d"; char s_seqy[] = " %s=y"; char s_x[] = "x"; char s_y[] = "y"; char s_z[] = "z"; /* JIIM */ FILE *parmfile; #define PAR_KEY(x) ( x < 10 ? '0' + x : 'a' - 10 + x) #ifdef _MSC_VER #pragma optimize("e",off) /* MSC 6.00A messes up next rtn with "e" on */ #endif #define LOADBATCHPROMPTS(X) {\ static FCODE tmp[] = { X };\ far_strcpy(ptr,tmp);\ choices[promptnum]= ptr;\ ptr += sizeof(tmp);\ } void make_batch_file() { #define MAXPROMPTS 18 int colorsonly = 0; static char far hdg[]={"Save Current Parameters"}; /** added for pieces feature **/ double pdelx = 0.0; double pdely = 0.0; double pdelx2 = 0.0; double pdely2 = 0.0; unsigned int pxdots, pydots, xm, ym; double pxxmin = 0.0, pyymax = 0.0; char vidmde[5]; int promptnum; int piecespromts; int have3rd = 0; /****/ int i,j; char far *inpcommandfile, far *inpcommandname; char far *inpcomment[4]; struct fullscreenvalues paramvalues[18]; char far * choices[MAXPROMPTS]; char far *ptr; int gotinfile; char outname[FILE_MAX_PATH+1], buf[256], buf2[128]; FILE *infile = NULL; FILE *fpbat = NULL; char colorspec[MAX_NAME+1]; int maxcolor; int maxcolorindex = 0; char *sptr = NULL, *sptr2; int oldhelpmode; if(s_makepar[1] == 0) /* makepar map case */ colorsonly = 1; /* put comment storage in extraseg */ inpcommandfile = MK_FP(extraseg,0); inpcommandname = inpcommandfile+80; inpcomment[0] = inpcommandname+(ITEMNAMELEN + 1); inpcomment[1] = inpcomment[0] + MAXCMT; inpcomment[2] = inpcomment[1] + MAXCMT; inpcomment[3] = inpcomment[2] + MAXCMT; /* steal existing array for "choices" */ ptr = (char far *)(inpcomment[3] + MAXCMT); stackscreen(); oldhelpmode = helpmode; helpmode = HELPPARMFILE; maxcolor = colors; strcpy(colorspec,"y"); #ifndef XFRACT if ((gotrealdac && !reallyega) || (istruecolor && !truemode)) #else if ((gotrealdac && !reallyega) || (istruecolor && !truemode) || fake_lut) #endif { --maxcolor; /* if (maxit < maxcolor) remove 2 lines */ /* maxcolor = maxit; so that whole palette is always saved */ if (inside > 0 && inside > maxcolor) maxcolor = inside; if (outside > 0 && outside > maxcolor) maxcolor = outside; if (distest < 0 && 0 - distest > maxcolor) maxcolor = (int)(0 - distest); if (decomp[0] > maxcolor) maxcolor = decomp[0] - 1; if (potflag && potparam[0] >= maxcolor) maxcolor = (int)potparam[0]; if (++maxcolor > 256) maxcolor = 256; if (colorstate == 0) { /* default colors */ if (mapdacbox) { colorspec[0] = '@'; sptr = MAP_name; } } else if (colorstate == 2 || (colorstate == 3 && recordcolors == 'c')) { /* colors match colorfile or only rotated and we want map name */ colorspec[0] = '@'; sptr = colorfile; } else /* colors match no .map that we know of */ strcpy (colorspec,"y"); if (colorspec[0] == '@') { if ((sptr2 = strrchr(sptr, SLASHC)) != NULL) sptr = sptr2 + 1; if ((sptr2 = strrchr(sptr, ':')) != NULL) sptr = sptr2 + 1; strncpy(&colorspec[1], sptr, MAX_NAME-1); colorspec[MAX_NAME] = 0; } } far_strcpy(inpcommandfile, CommandFile); far_strcpy(inpcommandname, CommandName); for(i=0;i<4;i++) { expand_comments(CommandComment[i], par_comment[i]); far_strcpy(inpcomment[i], CommandComment[i]); } if (CommandName[0] == 0) far_strcpy(inpcommandname, "test"); /* TW added these - and Bert moved them */ pxdots = xdots; pydots = ydots; xm = ym = 1; if(*s_makepar == 0) goto skip_UI; vidmode_keyname(videoentry.keynum, vidmde); for(;;) { prompt_user: promptnum = 0; LOADBATCHPROMPTS("Parameter file"); paramvalues[promptnum].type = 0x100 + MAXCMT - 1; paramvalues[promptnum++].uval.sbuf = inpcommandfile; LOADBATCHPROMPTS("Name"); paramvalues[promptnum].type = 0x100 + ITEMNAMELEN; paramvalues[promptnum++].uval.sbuf = inpcommandname; LOADBATCHPROMPTS("Main comment"); paramvalues[promptnum].type = 0x100 + MAXCMT - 1; paramvalues[promptnum++].uval.sbuf = inpcomment[0]; LOADBATCHPROMPTS("Second comment"); paramvalues[promptnum].type = 0x100 + MAXCMT - 1; paramvalues[promptnum++].uval.sbuf = inpcomment[1]; LOADBATCHPROMPTS("Third comment"); paramvalues[promptnum].type = 0x100 + MAXCMT - 1; paramvalues[promptnum++].uval.sbuf = inpcomment[2]; LOADBATCHPROMPTS("Fourth comment"); paramvalues[promptnum].type = 0x100 + MAXCMT - 1; paramvalues[promptnum++].uval.sbuf = inpcomment[3]; #ifndef XFRACT if ((gotrealdac && !reallyega) || (istruecolor && !truemode)) #else if ((gotrealdac && !reallyega) || (istruecolor && !truemode) || fake_lut) #endif { LOADBATCHPROMPTS("Record colors?"); paramvalues[promptnum].type = 0x100 + 13; paramvalues[promptnum++].uval.sbuf = colorspec; LOADBATCHPROMPTS(" (no | yes | only for full info | @filename to point to a map file)"); paramvalues[promptnum++].type = '*'; LOADBATCHPROMPTS("# of colors"); maxcolorindex = promptnum; paramvalues[promptnum].type = 'i'; paramvalues[promptnum++].uval.ival = maxcolor; LOADBATCHPROMPTS(" (if recording full color info)"); paramvalues[promptnum++].type = '*'; } LOADBATCHPROMPTS("Maximum line length"); paramvalues[promptnum].type = 'i'; paramvalues[promptnum++].uval.ival = maxlinelength; LOADBATCHPROMPTS(""); paramvalues[promptnum++].type = '*'; LOADBATCHPROMPTS(" **** The following is for generating images in pieces ****"); paramvalues[promptnum++].type = '*'; LOADBATCHPROMPTS("X Multiples"); piecespromts = promptnum; paramvalues[promptnum].type = 'i'; paramvalues[promptnum++].uval.ival = xm; LOADBATCHPROMPTS("Y Multiples"); paramvalues[promptnum].type = 'i'; paramvalues[promptnum++].uval.ival = ym; #ifndef XFRACT LOADBATCHPROMPTS("Video mode"); paramvalues[promptnum].type = 0x100 + 4; paramvalues[promptnum++].uval.sbuf = vidmde; #endif if (fullscreen_prompt(hdg,promptnum, choices, paramvalues, 0, NULL) < 0) break; if(*colorspec == 'o' || s_makepar[1] == 0) { strcpy(colorspec,"y"); colorsonly = 1; } far_strcpy(CommandFile, inpcommandfile); if (has_ext(CommandFile) == NULL) strcat(CommandFile, ".par"); /* default extension .par */ far_strcpy(CommandName, inpcommandname); for(i=0;i<4;i++) far_strncpy(CommandComment[i], inpcomment[i], MAXCMT); #ifndef XFRACT if ((gotrealdac && !reallyega) || (istruecolor && !truemode)) #else if ((gotrealdac && !reallyega) || (istruecolor && !truemode) || fake_lut) #endif if (paramvalues[maxcolorindex].uval.ival > 0 && paramvalues[maxcolorindex].uval.ival <= 256) maxcolor = paramvalues[maxcolorindex].uval.ival; promptnum = piecespromts; { int newmaxlinelength; newmaxlinelength = paramvalues[promptnum-3].uval.ival; if(maxlinelength != newmaxlinelength && newmaxlinelength >= MINMAXLINELENGTH && newmaxlinelength <= MAXMAXLINELENGTH) maxlinelength = newmaxlinelength; } xm = paramvalues[promptnum++].uval.ival; ym = paramvalues[promptnum++].uval.ival; /* sanity checks */ { long xtotal, ytotal; #ifndef XFRACT int i; /* get resolution from the video name (which must be valid) */ pxdots = pydots = 0; if ((i = check_vidmode_keyname(vidmde)) > 0) if ((i = check_vidmode_key(0, i)) >= 0) { /* get the resolution of this video mode */ pxdots = videotable[i].xdots; pydots = videotable[i].ydots; } if (pxdots == 0 && (xm > 1 || ym > 1)) { /* no corresponding video mode! */ static FCODE msg[] = {"Invalid video mode entry!"}; stopmsg(0,msg); goto prompt_user; } #endif /* bounds range on xm, ym */ if (xm < 1 || xm > 36 || ym < 1 || ym > 36) { static FCODE msg[] = {"X and Y components must be 1 to 36"}; stopmsg(0,msg); goto prompt_user; } /* another sanity check: total resolution cannot exceed 65535 */ xtotal = xm; ytotal = ym; xtotal *= pxdots; ytotal *= pydots; if (xtotal > 65535L || ytotal > 65535L) { static FCODE msg[] = {"Total resolution (X or Y) cannot exceed 65535"}; stopmsg(0,msg); goto prompt_user; } } skip_UI: if(*s_makepar == 0) { if(filecolors > 0) strcpy(colorspec, "y"); else strcpy(colorspec, "n"); if(s_makepar[1] == 0) maxcolor = 256; else maxcolor = filecolors; } strcpy(outname, CommandFile); gotinfile = 0; if (access(CommandFile, 0) == 0) { /* file exists */ gotinfile = 1; if (access(CommandFile, 6)) { sprintf(buf, s_cantwrite, CommandFile); stopmsg(0, buf); continue; } i = strlen(outname); while (--i >= 0 && outname[i] != SLASHC) outname[i] = 0; strcat(outname, "fractint.tmp"); infile = fopen(CommandFile, "rt"); #ifndef XFRACT setvbuf(infile, tstack, _IOFBF, 4096); /* improves speed */ #endif } if ((parmfile = fopen(outname, "wt")) == NULL) { sprintf(buf, s_cantcreate, outname); stopmsg(0, buf); if (gotinfile) fclose(infile); continue; } if (gotinfile) { while (file_gets(buf, 255, infile) >= 0) { if (strchr(buf, '{')/* entry heading? */ && sscanf(buf, " %40[^ \t({]", buf2) && stricmp(buf2, CommandName) == 0) { /* entry with same name */ static FCODE s1[] = {"File already has an entry named "}; static FCODE s2[] = {"\n\ Continue to replace it, Cancel to back out"}; static FCODE s2a[] = {"... Replacing ..."}; far_strcpy(buf2,s1); far_strcat(buf2,CommandName); if(*s_makepar == 0) far_strcat(buf2,s2a); else far_strcat(buf2,s2); if (stopmsg(18, buf2) < 0) { /* cancel */ fclose(infile); fclose(parmfile); unlink(outname); goto prompt_user; } while (strchr(buf, '}') == NULL && file_gets(buf, 255, infile) > 0) ; /* skip to end of set */ break; } fputs(buf, parmfile); fputc('\n', parmfile); } } /***** start here*/ if (xm > 1 || ym > 1) { if (xxmin != xx3rd || yymin != yy3rd) have3rd = 1; else have3rd = 0; if ((fpbat = dir_fopen(workdir,"makemig.bat", "w")) == NULL) xm = ym = 0; pdelx = (xxmax - xx3rd) / (xm * pxdots - 1); /* calculate stepsizes */ pdely = (yymax - yy3rd) / (ym * pydots - 1); pdelx2 = (xx3rd - xxmin) / (ym * pydots - 1); pdely2 = (yy3rd - yymin) / (xm * pxdots - 1); /* save corners */ pxxmin = xxmin; pyymax = yymax; } for (i = 0; i < (int)xm; i++) /* columns */ for (j = 0; j < (int)ym; j++) /* rows */ { if (xm > 1 || ym > 1) { int w; char c; char PCommandName[80]; w=0; while(w < (int)strlen(CommandName)) { c = CommandName[w]; if(isspace(c) || c == 0) break; PCommandName[w] = c; w++; } PCommandName[w] = 0; { char buf[20]; sprintf(buf,"_%c%c",PAR_KEY(i),PAR_KEY(j)); strcat(PCommandName,buf); } fprintf(parmfile, "%-19s{",PCommandName); xxmin = pxxmin + pdelx*(i*pxdots) + pdelx2*(j*pydots); xxmax = pxxmin + pdelx*((i+1)*pxdots - 1) + pdelx2*((j+1)*pydots - 1); yymin = pyymax - pdely*((j+1)*pydots - 1) - pdely2*((i+1)*pxdots - 1); yymax = pyymax - pdely*(j*pydots) - pdely2*(i*pxdots); if (have3rd) { xx3rd = pxxmin + pdelx*(i*pxdots) + pdelx2*((j+1)*pydots - 1); yy3rd = pyymax - pdely*((j+1)*pydots - 1) - pdely2*(i*pxdots); } else { xx3rd = xxmin; yy3rd = yymin; } fprintf(fpbat,"Fractint batch=yes overwrite=yes @%s/%s\n",CommandFile,PCommandName); fprintf(fpbat,"If Errorlevel 2 goto oops\n"); } else fprintf(parmfile, "%-19s{", CommandName); { /* guarantee that there are no blank comments above the last non-blank par_comment */ int i, last; for(last=-1,i=0;i<4;i++) if(*par_comment[i]) last=i; for(i=0;i 1 || ym > 1) { fprintf(parmfile," video=%s", vidmde); fprintf(parmfile," savename=frmig_%c%c\n", PAR_KEY(i), PAR_KEY(j)); } fprintf(parmfile, " }\n\n"); } if(xm > 1 || ym > 1) { fprintf(fpbat,"Fractint makemig=%d/%d\n",xm,ym); fprintf(fpbat,"Rem Simplgif fractmig.gif simplgif.gif in case you need it\n"); fprintf(fpbat,":oops\n"); fclose(fpbat); } /*******end here */ if (gotinfile) { /* copy the rest of the file */ while ((i = file_gets(buf, 255, infile)) == 0) ; /* skip blanks */ while (i >= 0) { fputs(buf, parmfile); fputc('\n', parmfile); i = file_gets(buf, 255, infile); } fclose(infile); } fclose(parmfile); if (gotinfile) { /* replace the original file with the new */ unlink(CommandFile); /* success assumed on these lines */ rename(outname, CommandFile); /* since we checked earlier with * access */ } break; } helpmode = oldhelpmode; unstackscreen(); } #ifdef C6 #pragma optimize("e",on) /* back to normal */ #endif static struct write_batch_data { /* buffer for parms to break lines nicely */ int len; char *buf; } *wbdata; void write_batch_parms(char *colorinf, int colorsonly, int maxcolor, int ii, int jj) { char far *saveshared; int i,j,k; double Xctr, Yctr; LDBL Magnification; double Xmagfactor, Rotation, Skew; struct write_batch_data wb_data; char *sptr; char buf[81]; bf_t bfXctr=NULL, bfYctr=NULL; int saved; saved = save_stack(); if(bf_math) { bfXctr = alloc_stack(bflength+2); bfYctr = alloc_stack(bflength+2); } wbdata = &wb_data; wb_data.len = 0; /* force first parm to start on new line */ /* Using near string boxx for buffer after saving to extraseg */ saveshared = MK_FP(extraseg,0); far_memcpy(saveshared,boxx,10000); far_memset(boxx,0,10000); wb_data.buf = (char *)boxx; if(colorsonly) goto docolors; if (display3d <= 0) { /* a fractal was generated */ /****** fractal only parameters in this section *******/ put_parm(" reset"); if (check_back()) put_parm("=%d",min(save_release,release)); else put_parm("=%d",release); if (*(sptr = curfractalspecific->name) == '*') ++sptr; put_parm( s_seqs,s_type,sptr); if (fractype == JULIBROT || fractype == JULIBROTFP) { put_parm(" %s=%.15g/%.15g/%.15g/%.15g", s_julibrotfromto,mxmaxfp,mxminfp,mymaxfp,myminfp); /* these rarely change */ if(originfp != 8 || heightfp != 7 || widthfp != 10 || distfp != 24 || depthfp != 8 || zdots != 128) put_parm(" %s=%d/%g/%g/%g/%g/%g",s_julibrot3d, zdots, originfp, depthfp, heightfp, widthfp,distfp); if(eyesfp != 0) put_parm(" %s=%g",s_julibroteyes,eyesfp); if(neworbittype != JULIA) { char *name; name = fractalspecific[neworbittype].name; if(*name=='*') name++; put_parm(s_seqs,s_orbitname,name); } if(juli3Dmode != 0) put_parm(s_seqs,s_3dmode,juli3Doptions[juli3Dmode]); } if (fractype == FORMULA || fractype == FFORMULA) { put_filename(s_formulafile,FormFileName); put_parm( s_seqs,s_formulaname,FormName); if (uses_ismand) put_parm(" %s=%c",s_ismand,ismand?'y':'n'); } if (fractype == LSYSTEM) { put_filename(s_lfile,LFileName); put_parm( s_seqs,s_lname,LName); } if (fractype == IFS || fractype == IFS3D) { put_filename(s_ifsfile,IFSFileName); put_parm( s_seqs,s_ifs,IFSName); } if (fractype == INVERSEJULIA || fractype == INVERSEJULIAFP) put_parm( " %s=%s/%s",s_miim,JIIMmethod[major_method], JIIMleftright[minor_method]); showtrig(buf); /* this function is in miscres.c */ if (buf[0]) put_parm(buf); if (usr_stdcalcmode != 'g') put_parm(" %s=%c",s_passes,usr_stdcalcmode); if (stoppass != 0) put_parm(" %s=%c%c",s_passes,usr_stdcalcmode,(char)stoppass + '0'); if (usemag) { if (bf_math) { int digits; cvtcentermagbf(bfXctr, bfYctr, &Magnification, &Xmagfactor, &Rotation, &Skew); digits = getprecbf(MAXREZ); put_parm(" %s=",s_centermag); put_bf(0,bfXctr,digits); put_bf(1,bfYctr,digits); } else /* !bf_math */ { cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); put_parm(" %s=",s_centermag); /* convert 1000 fudged long to double, 1000/1<<24 = 6e-5 */ put_parm(ddelmin > 6e-5 ? "%g/%g" : "%+20.17lf/%+20.17lf", Xctr, Yctr); } #ifdef USE_LONG_DOUBLE put_parm("/%.7Lg",Magnification); /* precision of magnification not critical, but magnitude is */ #else put_parm("/%.7lg",Magnification); /* precision of magnification not critical, but magnitude is */ #endif /* Round to avoid ugly decimals, precision here is not critical */ /* Don't round Xmagfactor if it's small */ if (fabs(Xmagfactor) > 0.5) /* or so, exact value isn't important */ Xmagfactor = (sign(Xmagfactor) * (long)(fabs(Xmagfactor) * 1e4 + 0.5)) / 1e4; /* Just truncate these angles. Who cares about 1/1000 of a degree */ /* Somebody does. Some rotated and/or skewed images are slightly */ /* off when recreated from a PAR using 1/1000. */ /* JCO 08052001 */ #if 0 Rotation = (long)(Rotation * 1e3)/1e3; Skew = (long)(Skew * 1e3)/1e3; #endif if (Xmagfactor != 1 || Rotation != 0 || Skew != 0) { /* Only put what is necessary */ /* The difference with Xmagfactor is that it is normally */ /* near 1 while the others are normally near 0 */ if (fabs(Xmagfactor) >= 1) put_float(1,Xmagfactor,5); /* put_float() uses %g */ else /* abs(Xmagfactor) is < 1 */ put_float(1,Xmagfactor,4); /* put_float() uses %g */ if (Rotation != 0 || Skew != 0) { /* Use precision=6 here. These angle have already been rounded */ /* to 3 decimal places, but angles like 123.456 degrees need 6 */ /* sig figs to get 3 decimal places. Trailing 0's are dropped anyway. */ /* Changed to 18 to address rotated and skewed problem w/ PARs */ /* JCO 08052001 */ put_float(1,Rotation,18); if (Skew != 0) { put_float(1,Skew,18); } } } } else /* not usemag */ { put_parm( " %s=",s_corners); if(bf_math) { int digits; digits = getprecbf(MAXREZ); put_bf(0,bfxmin,digits); put_bf(1,bfxmax,digits); put_bf(1,bfymin,digits); put_bf(1,bfymax,digits); if (cmp_bf(bfx3rd,bfxmin) || cmp_bf(bfy3rd,bfymin)) { put_bf(1,bfx3rd,digits); put_bf(1,bfy3rd,digits); } } else { int xdigits,ydigits; xdigits = getprec(xxmin,xxmax,xx3rd); ydigits = getprec(yymin,yymax,yy3rd); put_float(0,xxmin,xdigits); put_float(1,xxmax,xdigits); put_float(1,yymin,ydigits); put_float(1,yymax,ydigits); if (xx3rd != xxmin || yy3rd != yymin) { put_float(1,xx3rd,xdigits); put_float(1,yy3rd,ydigits); } } } for(i = (MAXPARAMS-1); i >= 0; --i) if(typehasparm((fractype==JULIBROT || fractype==JULIBROTFP) ?neworbittype:fractype,i,NULL)) break; if (i >= 0) { if (fractype == CELLULAR || fractype == ANT) put_parm(" %s=%.1f",s_params,param[0]); else { #ifdef USE_LONG_DOUBLE if(debugflag == 750) put_parm(" %s=%.17Lg",s_params,(long double)param[0]); else #endif put_parm(" %s=%.17g",s_params,param[0]); } for (j = 1; j <= i; ++j) if (fractype == CELLULAR || fractype == ANT) put_parm("/%.1f",param[j]); else { #ifdef USE_LONG_DOUBLE if(debugflag == 750) put_parm("/%.17Lg",(long double)param[j]); else #endif put_parm("/%.17g",param[j]); } } if(useinitorbit == 2) put_parm( " %s=pixel",s_initorbit); else if(useinitorbit == 1) put_parm( " %s=%.15g/%.15g",s_initorbit,initorbit.x,initorbit.y); if (floatflag) put_parm( s_seqy,s_float); if (maxit != 150) put_parm(" %s=%ld",s_maxiter,maxit); if(bailout && (potflag == 0 || potparam[2] == 0.0)) put_parm(" %s=%ld",s_bailout,bailout); if(bailoutest != Mod) { put_parm(" %s=",s_bailoutest); if (bailoutest == Real) put_parm( s_real); else if (bailoutest == Imag) put_parm(s_imag); else if (bailoutest == Or) put_parm(s_or); else if (bailoutest == And) put_parm(s_and); else if (bailoutest == Manh) put_parm(s_manh); else if (bailoutest == Manr) put_parm(s_manr); else put_parm(s_mod); /* default, just in case */ } if(fillcolor != -1) { put_parm(" %s=",s_fillcolor); put_parm( "%d",fillcolor); } if (inside != 1) { put_parm(" %s=",s_inside); if (inside == -1) put_parm( s_maxiter); else if (inside == ZMAG) put_parm(s_zmag); else if (inside == BOF60) put_parm(s_bof60); else if (inside == BOF61) put_parm(s_bof61); else if (inside == EPSCROSS) put_parm(s_epscross); else if (inside == STARTRAIL) put_parm(s_startrail); else if (inside == PERIOD) put_parm(s_period); else if (inside == FMODI) put_parm(s_fmod); else if (inside == ATANI) put_parm(s_atan); else put_parm( "%d",inside); } if (closeprox != 0.01 && (inside == EPSCROSS || inside == FMODI || outside==FMOD) ) { put_parm(" %s=%.15g",s_prox,closeprox); } if (outside != -1) { put_parm(" %s=",s_outside); if (outside == REAL) put_parm(s_real); else if (outside == IMAG) put_parm(s_imag); else if (outside == MULT) put_parm(s_mult); else if (outside == SUM) put_parm(s_sum); else if (outside == ATAN) put_parm(s_atan); else if (outside == FMOD) put_parm(s_fmod); else if (outside == TDIS) put_parm(s_tdis); else put_parm( "%d",outside); } if(LogFlag && !rangeslen) { put_parm( " %s=",s_logmap); if(LogFlag == -1) put_parm( "old"); else if(LogFlag == 1) put_parm( s_yes); else put_parm( "%ld", LogFlag); } if(Log_Fly_Calc && LogFlag && !rangeslen) { put_parm( " %s=",s_logmode); if(Log_Fly_Calc == 1) put_parm( "fly"); else if(Log_Fly_Calc == 2) put_parm( "table"); } if (potflag) { put_parm( " %s=%d/%g/%d",s_potential, (int)potparam[0],potparam[1],(int)potparam[2]); if(pot16bit) put_parm( "/%s",s_16bit); } if (invert) put_parm( " %s=%-1.15lg/%-1.15lg/%-1.15lg",s_invert, inversion[0], inversion[1], inversion[2]); if (decomp[0]) put_parm( s_seqd,s_decomp, decomp[0]); if (distest) { put_parm( s_seqldddd,s_distest, distest, distestwidth, pseudox?pseudox:xdots,pseudoy?pseudoy:ydots); } if (old_demm_colors) put_parm( s_seqy,s_olddemmcolors); if (usr_biomorph != -1) put_parm( s_seqd,s_biomorph, usr_biomorph); if (finattract) put_parm(s_seqy,s_finattract); if (forcesymmetry != 999) { static FCODE msg[] = {"Regenerate before to get correct symmetry"}; if(forcesymmetry == 1000 && ii == 1 && jj == 1) stopmsg(0,msg); put_parm( " %s=",s_symmetry); if (forcesymmetry==XAXIS) put_parm(s_xaxis); else if(forcesymmetry==YAXIS) put_parm(s_yaxis); else if(forcesymmetry==XYAXIS) put_parm(s_xyaxis); else if(forcesymmetry==ORIGIN) put_parm(s_origin); else if(forcesymmetry==PI_SYM) put_parm(s_pi); else put_parm(s_none); } if (periodicitycheck != 1) put_parm( s_seqd,s_periodicity,periodicitycheck); if (rflag) put_parm( s_seqd,s_rseed,rseed); if (rangeslen) { put_parm(" %s=",s_ranges); i = 0; while (i < rangeslen) { if (i) put_parm("/"); if (ranges[i] == -1) { put_parm("-%d/",ranges[++i]); ++i; } put_parm("%d",ranges[i++]); } } } if (display3d >= 1) { /***** 3d transform only parameters in this section *****/ if(display3d == 2) put_parm( s_seqs,s_3d,s_overlay); else put_parm( s_seqs,s_3d,s_yes); if (loaded3d == 0) put_filename(s_filename,readname); if (SPHERE) { put_parm( s_seqy,s_sphere); put_parm( s_seqdd,s_latitude, THETA1, THETA2); put_parm( s_seqdd,s_longitude, PHI1, PHI2); put_parm( s_seqd,s_radius, RADIUS); } put_parm( s_seqdd,s_scalexyz, XSCALE, YSCALE); put_parm( s_seqd,s_roughness, ROUGH); put_parm( s_seqd,s_waterline, WATERLINE); if (FILLTYPE) put_parm( s_seqd,s_filltype, FILLTYPE); if (transparent[0] || transparent[1]) put_parm( s_seqdd,s_transparent, transparent[0],transparent[1]); if (preview) { put_parm( s_seqs,s_preview,s_yes); if (showbox) put_parm( s_seqs,s_showbox,s_yes); put_parm( s_seqd,s_coarse,previewfactor); } if (RAY) { put_parm( s_seqd,s_ray,RAY); if (BRIEF) put_parm(s_seqy,s_brief); } if (FILLTYPE > 4) { put_parm( s_seqddd,s_lightsource, XLIGHT, YLIGHT, ZLIGHT); if (LIGHTAVG) put_parm(s_seqd,s_smoothing, LIGHTAVG); } if (RANDOMIZE) put_parm( s_seqd,s_randomize,RANDOMIZE); if (Targa_Out) put_parm( s_seqy,s_fullcolor); if (grayflag) put_parm( s_seqy,s_usegrayscale); if (Ambient) put_parm( s_seqd,s_ambient,Ambient); if (haze) put_parm( s_seqd,s_haze,haze); if (back_color[0] != 51 || back_color[1] != 153 || back_color[2] != 200) put_parm( s_seqddd,s_background,back_color[0],back_color[1], back_color[2]); } if (display3d) { /* universal 3d */ /***** common (fractal & transform) 3d parameters in this section *****/ if (!SPHERE || display3d < 0) put_parm( s_seqddd,s_rotation, XROT, YROT, ZROT); put_parm( s_seqd,s_perspective, ZVIEWER); put_parm( s_seqdd,s_xyshift, XSHIFT, YSHIFT); if(xtrans || ytrans) put_parm( s_seqdd,s_xyadjust,xtrans,ytrans); if(glassestype) { put_parm( s_seqd,s_stereo,glassestype); put_parm( s_seqd,s_interocular,eyeseparation); put_parm( s_seqd,s_converge,xadjust); put_parm( " %s=%d/%d/%d/%d",s_crop, red_crop_left,red_crop_right,blue_crop_left,blue_crop_right); put_parm( s_seqdd,s_bright, red_bright,blue_bright); } } /***** universal parameters in this section *****/ if(viewwindow == 1) { put_parm(" %s=%g/%g",s_viewwindows,viewreduction,finalaspectratio); if(viewcrop) put_parm("/%s",s_yes); else put_parm("/%s",s_no); put_parm("/%d/%d",viewxdots,viewydots); } if(colorsonly == 0) { if (rotate_lo != 1 || rotate_hi != 255) put_parm( s_seqdd,s_cyclerange,rotate_lo,rotate_hi); if(basehertz != 440) put_parm(s_seqd,s_hertz,basehertz); if(soundflag != 9) { if((soundflag&7) == 0) put_parm(s_seqs,s_sound,s_off); else if((soundflag&7) == 1) put_parm(s_seqs,s_sound,s_beep); else if((soundflag&7) == 2) put_parm(s_seqs,s_sound,s_x); else if((soundflag&7) == 3) put_parm(s_seqs,s_sound,s_y); else if((soundflag&7) == 4) put_parm(s_seqs,s_sound,s_z); #ifndef XFRACT if((soundflag&7) && (soundflag&7) <=4) { if(soundflag&8) put_parm("/pc"); if(soundflag&16) put_parm("/fm"); if(soundflag&32) put_parm("/midi"); if(soundflag&64) put_parm("/quant"); } #endif } #ifndef XFRACT if(fm_vol != 63) put_parm(s_seqd,s_volume,fm_vol); if(hi_atten != 0) { if(hi_atten == 1) put_parm(s_seqs,s_atten,s_low); else if(hi_atten == 2) put_parm(s_seqs,s_atten,s_mid); else if(hi_atten == 3) put_parm(s_seqs,s_atten,s_high); else /* just in case */ put_parm(s_seqs,s_atten,s_none); } if(polyphony != 0) put_parm(s_seqd,s_polyphony,polyphony+1); if(fm_wavetype !=0) put_parm(s_seqd,s_wavetype,fm_wavetype); if(fm_attack != 5) put_parm(s_seqd,s_attack,fm_attack); if(fm_decay != 10) put_parm(s_seqd,s_decay,fm_decay); if(fm_sustain != 13) put_parm(s_seqd,s_sustain,fm_sustain); if(fm_release != 5) put_parm(s_seqd,s_srelease,fm_release); if(soundflag&64) { /* quantize turned on */ for(i=0;i<=11;i++) if(scale_map[i] != i+1) i=15; if(i>12) put_parm(s_seqd12,s_scalemap,scale_map[0],scale_map[1],scale_map[2],scale_map[3] ,scale_map[4],scale_map[5],scale_map[6],scale_map[7],scale_map[8] ,scale_map[9],scale_map[10],scale_map[11]); } #endif if(nobof > 0) put_parm(s_seqs,s_nobof,s_yes); if(orbit_delay > 0) put_parm(s_seqd,s_orbitdelay,orbit_delay); if(orbit_interval != 1) put_parm(s_seqd,s_orbitinterval,orbit_interval); if(start_showorbit > 0) put_parm(s_seqs,s_showorbit,s_yes); if (keep_scrn_coords) put_parm(s_seqs,s_screencoords,s_yes); if (usr_stdcalcmode == 'o' && set_orbit_corners && keep_scrn_coords) { int xdigits,ydigits; put_parm( " %s=",s_orbitcorners); xdigits = getprec(oxmin,oxmax,ox3rd); ydigits = getprec(oymin,oymax,oy3rd); put_float(0,oxmin,xdigits); put_float(1,oxmax,xdigits); put_float(1,oymin,ydigits); put_float(1,oymax,ydigits); if (ox3rd != oxmin || oy3rd != oymin) { put_float(1,ox3rd,xdigits); put_float(1,oy3rd,ydigits); } } if (drawmode != 'r') put_parm(" %s=%c",s_orbitdrawmode, drawmode); if (math_tol[0] != 0.05 || math_tol[1] != 0.05) put_parm(" %s=%g/%g",s_mathtolerance,math_tol[0],math_tol[1]); } if (*colorinf != 'n') { if(recordcolors=='c' && *colorinf == '@') { put_parm_line(); put_parm(" %s=",s_colors); put_parm(colorinf); put_parm_line(); } docolors: put_parm(" %s=",s_colors); if (recordcolors !='c' && recordcolors != 'y' && *colorinf == '@') put_parm(colorinf); else { int curc,scanc,force,diffmag = -1; int delta,diff1[4][3],diff2[4][3]; curc = force = 0; #ifdef XFRACT if (fake_lut && !truemode) loaddac(); /* stupid kludge JCO 6/23/2001 */ #endif for(;;) { /* emit color in rgb 3 char encoded form */ for (j = 0; j < 3; ++j) { if ((k = dacbox[curc][j]) < 10) k += '0'; else if (k < 36) k += ('A' - 10); else k += ('_' - 36); buf[j] = (char)k; } buf[3] = 0; put_parm(buf); if (++curc >= maxcolor) /* quit if done last color */ break; if(debugflag == 920) /* lossless compression */ continue; /* Next a P Branderhorst special, a tricky scan for smooth-shaded ranges which can be written as to compress .par file entry. Method used is to check net change in each color value over spans of 2 to 5 color numbers. First time for each span size the value change is noted. After first time the change is checked against noted change. First time it differs, a a difference of 1 is tolerated and noted as an alternate acceptable change. When change is not one of the tolerated values, loop exits. */ if (force) { --force; continue; } scanc = curc; while (scanc < maxcolor) { /* scan while same diff to next */ if ((i = scanc - curc) > 3) /* check spans up to 4 steps */ i = 3; for (k = 0; k <= i; ++k) { for (j = 0; j < 3; ++j) { /* check pattern of chg per color */ /* Sylvie Gallet's fix */ if (debugflag != 910 && scanc > (curc+4) && scanc < maxcolor-5) if (abs(2*dacbox[scanc][j] - dacbox[scanc-5][j] - dacbox[scanc+5][j]) >= 2) break; /* end Sylvie's fix */ delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j]; if (k == scanc - curc) diff1[k][j] = diff2[k][j] = delta; else if (delta != diff1[k][j] && delta != diff2[k][j]) { diffmag = abs(delta - diff1[k][j]); if (diff1[k][j] != diff2[k][j] || diffmag != 1) break; diff2[k][j] = delta; } } if (j < 3) break; /* must've exited from inner loop above */ } if (k <= i) break; /* must've exited from inner loop above */ ++scanc; } /* now scanc-1 is next color which must be written explicitly */ if (scanc - curc > 2) { /* good, we have a shaded range */ if (scanc != maxcolor) { if (diffmag < 3) { /* not a sharp slope change? */ force = 2; /* force more between ranges, to stop */ --scanc; /* "drift" when load/store/load/store/ */ } if (k) { /* more of the same */ force += k; --scanc; } } if (--scanc - curc > 1) { put_parm("<%d>",scanc-curc); curc = scanc; } else /* changed our mind */ force = 0; } } } } while (wbdata->len) /* flush the buffer */ put_parm_line(); /* restore previous boxx data from extraseg */ far_memcpy(boxx, saveshared, 10000); restore_stack(saved); } static void put_filename(char *keyword,char *fname) { char *p; if (*fname && !endswithslash(fname)) { if ((p = strrchr(fname, SLASHC)) != NULL) if (*(fname = p+1) == 0) return; put_parm(s_seqs,keyword,fname); } } #ifndef USE_VARARGS static void put_parm(char *parm,...) #else static void put_parm(va_alist) va_dcl #endif { char *bufptr; va_list args; #ifndef USE_VARARGS va_start(args,parm); #else char * parm; va_start(args); parm = va_arg(args,char *); #endif if (*parm == ' ' /* starting a new parm */ && wbdata->len == 0) /* skip leading space */ ++parm; bufptr = wbdata->buf + wbdata->len; vsprintf(bufptr,parm,args); while (*(bufptr++)) ++wbdata->len; while (wbdata->len > 200) put_parm_line(); } int maxlinelength=72; #define MAXLINELEN maxlinelength #define NICELINELEN (MAXLINELEN-4) static void put_parm_line() { int len,c; if ((len = wbdata->len) > NICELINELEN) { len = NICELINELEN+1; while (--len != 0 && wbdata->buf[len] != ' ') { } if (len == 0) { len = NICELINELEN-1; while (++len < MAXLINELEN && wbdata->buf[len] && wbdata->buf[len] != ' ') { } } } c = wbdata->buf[len]; wbdata->buf[len] = 0; fputs(" ",parmfile); fputs(wbdata->buf,parmfile); if (c && c != ' ') fputc('\\',parmfile); fputc('\n',parmfile); if ((wbdata->buf[len] = (char)c) == ' ') ++len; wbdata->len -= len; strcpy(wbdata->buf,wbdata->buf+len); } int getprecbf_mag() { double Xmagfactor, Rotation, Skew; LDBL Magnification; bf_t bXctr, bYctr; int saved,dec; saved = save_stack(); bXctr = alloc_stack(bflength+2); bYctr = alloc_stack(bflength+2); /* this is just to find Magnification */ cvtcentermagbf(bXctr, bYctr, &Magnification, &Xmagfactor, &Rotation, &Skew); restore_stack(saved); /* I don't know if this is portable, but something needs to */ /* be used in case compiler's LDBL_MAX is not big enough */ if (Magnification > LDBL_MAX || Magnification < -LDBL_MAX) return(-1); dec = getpower10(Magnification) + 4; /* 4 digits of padding sounds good */ return(dec); } static int getprec(double a,double b,double c) { double diff,temp; int digits; double highv = 1.0E20; if ((diff = fabs(a - b)) == 0.0) diff = highv; if ((temp = fabs(a - c)) == 0.0) temp = highv; if (temp < diff) diff = temp; if ((temp = fabs(b - c)) == 0.0) temp = highv; if (temp < diff) diff = temp; digits = 7; if(debugflag >= 700 && debugflag < 720 ) digits = debugflag - 700; while (diff < 1.0 && digits <= DBL_DIG+1) { diff *= 10; ++digits; } return(digits); } /* This function calculates the precision needed to distiguish adjacent pixels at Fractint's maximum resolution of MAXPIXELS by MAXPIXELS (if rez==MAXREZ) or at current resolution (if rez==CURRENTREZ) */ int getprecbf(int rezflag) { bf_t del1,del2, one, bfxxdel, bfxxdel2, bfyydel, bfyydel2; int digits,dec; int saved; int rez; saved = save_stack(); del1 = alloc_stack(bflength+2); del2 = alloc_stack(bflength+2); one = alloc_stack(bflength+2); bfxxdel = alloc_stack(bflength+2); bfxxdel2 = alloc_stack(bflength+2); bfyydel = alloc_stack(bflength+2); bfyydel2 = alloc_stack(bflength+2); floattobf(one,1.0); if(rezflag == MAXREZ) rez = OLDMAXPIXELS -1; else rez = xdots-1; /* bfxxdel = (bfxmax - bfx3rd)/(xdots-1) */ sub_bf(bfxxdel, bfxmax, bfx3rd); div_a_bf_int(bfxxdel, (U16)rez); /* bfyydel2 = (bfy3rd - bfymin)/(xdots-1) */ sub_bf(bfyydel2, bfy3rd, bfymin); div_a_bf_int(bfyydel2, (U16)rez); if(rezflag == CURRENTREZ) rez = ydots-1; /* bfyydel = (bfymax - bfy3rd)/(ydots-1) */ sub_bf(bfyydel, bfymax, bfy3rd); div_a_bf_int(bfyydel, (U16)rez); /* bfxxdel2 = (bfx3rd - bfxmin)/(ydots-1) */ sub_bf(bfxxdel2, bfx3rd, bfxmin); div_a_bf_int(bfxxdel2, (U16)rez); abs_a_bf(add_bf(del1,bfxxdel,bfxxdel2)); abs_a_bf(add_bf(del2,bfyydel,bfyydel2)); if(cmp_bf(del2,del1) < 0) copy_bf(del1, del2); if(cmp_bf(del1,clear_bf(del2)) == 0) { restore_stack(saved); return(-1); } digits = 1; while(cmp_bf(del1,one) < 0) { digits++; mult_a_bf_int(del1,10); } digits = max(digits,3); restore_stack(saved); dec = getprecbf_mag(); return(max(digits,dec)); } #ifdef _MSC_VER #pragma optimize("e",off) /* MSC 7.00 messes up next with "e" on */ #endif /* This function calculates the precision needed to distiguish adjacent pixels at Fractint's maximum resolution of MAXPIXELS by MAXPIXELS (if rez==MAXREZ) or at current resolution (if rez==CURRENTREZ) */ int getprecdbl(int rezflag) { LDBL del1,del2, xdel, xdel2, ydel, ydel2; int digits; LDBL rez; if(rezflag == MAXREZ) rez = OLDMAXPIXELS -1; else rez = xdots-1; xdel = ((LDBL)xxmax - (LDBL)xx3rd)/rez; ydel2 = ((LDBL)yy3rd - (LDBL)yymin)/rez; if(rezflag == CURRENTREZ) rez = ydots-1; ydel = ((LDBL)yymax - (LDBL)yy3rd)/rez; xdel2 = ((LDBL)xx3rd - (LDBL)xxmin)/rez; del1 = fabsl(xdel) + fabsl(xdel2); del2 = fabsl(ydel) + fabsl(ydel2); if(del2 < del1) del1 = del2; if(del1 == 0) { #ifdef DEBUG showcornersdbl("getprecdbl"); #endif return(-1); } digits = 1; while(del1 < 1.0) { digits++; del1 *= 10; } digits = max(digits,3); return(digits); } #ifdef _MSC_VER #pragma optimize("e",on) #endif /* Strips zeros from the non-exponent part of a number. This logic was originally in put_bf(), but is split into this routine so it can be shared with put_float(), which had a bug in Fractint 19.2 (used to strip zeros from the exponent as well.) */ static void strip_zeros(char *buf) { char *dptr, *bptr, *exptr; strlwr(buf); if ((dptr = strchr(buf,'.')) != 0) { ++dptr; if ((exptr = strchr(buf,'e')) !=0) /* scientific notation with 'e'? */ bptr = exptr; else bptr = buf + strlen(buf); while (--bptr > dptr && *bptr == '0') *bptr = 0; if(exptr && bptr < exptr -1) strcat(buf,exptr); } } static void put_float(int slash,double fnum,int prec) { char buf[40]; char *bptr; bptr = buf; if (slash) *(bptr++) = '/'; /* sprintf(bptr,"%1.*f",prec,fnum); */ #ifdef USE_LONG_DOUBLE /* Idea of long double cast is to squeeze out another digit or two which might be needed (we have found cases where this digit makes a difference.) But lets not do this at lower precision */ if(prec > 15) sprintf(bptr,"%1.*Lg",prec,(long double)fnum); else #endif sprintf(bptr,"%1.*g",prec,(double)fnum); strip_zeros(bptr); put_parm(buf); } static void put_bf(int slash,bf_t r, int prec) { char *buf; /* "/-1.xxxxxxE-1234" */ char *bptr; /* buf = malloc(decimals+11); */ buf = wbdata->buf+5000; /* end of use suffix buffer, 5000 bytes safe */ bptr = buf; if (slash) *(bptr++) = '/'; bftostr(bptr, prec, r); strip_zeros(bptr); put_parm(buf); } #ifndef XFRACT #include void shell_to_dos() { int drv; char *comspec; char curdir[FILE_MAX_DIR],*s; if ((comspec = getenv("COMSPEC")) == NULL) printf("Cannot find COMMAND.COM.\n"); else { putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g"); s = getcwd(curdir,100); drv = _getdrive(); spawnl(P_WAIT, comspec, NULL); if(drv) _chdrive(drv); if(s) chdir(s); } } size_t showstack(void) { return(stackavail()); } long fr_farfree(void) { long j,j2; BYTE huge *fartempptr; j = 0; j2 = 0x80000L; while ((j2 >>= 1) != 0) if ((fartempptr = (BYTE huge *)farmemalloc(j+j2)) != NULL) { farmemfree((void far*)fartempptr); j += j2; } return(j); } void showfreemem(void) { char *tempptr; unsigned i,i2; char adapter_name[8]; /* entry lenth from VIDEO.ASM */ char *adapter_ptr; printf("\n CPU type: %d FPU type: %d Video: %d", cpu, fpu, video_type); adapter_ptr = &supervga_list; for(i = 0 ; ; i++) { /* find the SuperVGA entry */ int j; memcpy(adapter_name , adapter_ptr, 8); adapter_ptr += 8; if (adapter_name[0] == ' ') break; /* end-of-the-list */ if (adapter_name[6] == 0) continue; /* not our adapter */ adapter_name[6] = ' '; for (j = 0; j < 8; j++) if(adapter_name[j] == ' ') adapter_name[j] = 0; printf(" Video chip: %d (%s)",i+1,adapter_name); } printf("\n\n"); i = 0; i2 = 0x8000; while ((i2 >>= 1) != 0) if ((tempptr = malloc(i+i2)) != NULL) { free(tempptr); i += i2; } printf(" %d NEAR bytes free \n", i); printf(" %ld FAR bytes free ", fr_farfree()); { size_t stack; stack = showstack(); /* if(stack >= 0) */ /* stack is unsigned */ printf("\n %u STACK bytes free",stack); } printf("\n %ld used by HISTORY structure", sizeof(HISTORY)*(unsigned long)maxhistory); printf("\n %d video table used",showvidlength()); printf("\n\n %Fs...\n",s_pressanykeytocontinue); getakey(); } #endif int edit_text_colors() { int save_debugflag,save_lookatmouse; int row,col,bkgrd; int rowf,colf,rowt,colt; char far *vidmem; char far *savescreen; char far *farp1; char far *farp2; int i,j,k; save_debugflag = debugflag; save_lookatmouse = lookatmouse; debugflag = 0; /* don't get called recursively */ lookatmouse = 2; /* text mouse sensitivity */ row = col = bkgrd = rowt = rowf = colt = colf = 0; vidmem = MK_FP(0xB800,0); for(;;) { if (row < 0) row = 0; if (row > 24) row = 24; if (col < 0) col = 0; if (col > 79) col = 79; movecursor(row,col); i = getakey(); if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */ switch (i) { case 27: /* esc */ debugflag = save_debugflag; lookatmouse = save_lookatmouse; movecursor(25,80); return 0; case '/': farp1 = savescreen = (char far *)farmemalloc(4000L); farp2 = vidmem; for (i = 0; i < 4000; ++i) { /* save and blank */ *(farp1++) = *farp2; *(farp2++) = 0; } for (i = 0; i < 8; ++i) /* 8 bkgrd attrs */ for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */ k = i*16 + j; farp1 = vidmem + i*320 + j*10; *(farp1++) = ' '; *(farp1++) = (char)k; *(farp1++) = (char)(i+'0'); *(farp1++) = (char)k; *(farp1++) = (char)((j < 10) ? j+'0' : j+'A'-10); *(farp1++) = (char)k; *(farp1++) = ' '; *(farp1++) = (char)k; } getakey(); farp1 = vidmem; farp2 = savescreen; for (i = 0; i < 4000; ++i) /* restore */ *(farp1++) = *(farp2++); farmemfree(savescreen); break; case ',': rowf = row; colf = col; break; case '.': rowt = row; colt = col; break; case ' ': /* next color is background */ bkgrd = 1; break; case 1075: /* cursor left */ --col; break; case 1077: /* cursor right */ ++col; break; case 1072: /* cursor up */ --row; break; case 1080: /* cursor down */ ++row; break; case 13: /* enter */ *(vidmem + row*160 + col*2) = (char)getakey(); break; default: if (i >= '0' && i <= '9') i -= '0'; else if (i >= 'A' && i <= 'F') i -= 'A'-10; else break; for (j = rowf; j <= rowt; ++j) for (k = colf; k <= colt; ++k) { farp1 = vidmem + j*160 + k*2 + 1; if (bkgrd) *farp1 = (char)((*farp1 & 15) + i * 16); else *farp1 = (char)((*farp1 & 0xf0) + i); } bkgrd = 0; } } } static int *entsptr; static int modes_changed; int select_video_mode(int curmode) { static FCODE o_hdg2[]={"key...name.......................xdot..ydot.colr.comment.................."}; static FCODE o_hdg1[]={"Select Video Mode"}; char hdg2[sizeof(o_hdg2)]; char hdg1[sizeof(o_hdg1)]; int entnums[MAXVIDEOMODES]; int attributes[MAXVIDEOMODES]; int i,k,ret; #ifndef XFRACT int j; int oldtabmode,oldhelpmode; #endif load_fractint_cfg(0); /* load fractint.cfg to extraseg */ far_strcpy(hdg1,o_hdg1); far_strcpy(hdg2,o_hdg2); for (i = 0; i < vidtbllen; ++i) { /* init tables */ entnums[i] = i; attributes[i] = 1; } entsptr = entnums; /* for indirectly called subroutines */ qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */ /* pick default mode */ if (curmode < 0) { switch (video_type) { /* set up a reasonable default (we hope) */ case 1: videoentry.videomodeax = 8; /* hgc */ videoentry.colors = 2; break; case 2: videoentry.videomodeax = 4; /* cga */ videoentry.colors = 4; break; case 3: videoentry.videomodeax = 16; /* ega */ videoentry.colors = 16; if (mode7text) { /* egamono */ videoentry.videomodeax = 15; videoentry.colors = 2; } break; default: videoentry.videomodeax = 19; /* mcga/vga? */ videoentry.colors = 256; break; } } else far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode], sizeof(videoentry)); #ifndef XFRACT for (i = 0; i < vidtbllen; ++i) { /* find default mode */ if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax && videoentry.colors == vidtbl[entnums[i]].colors && (curmode < 0 || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]], sizeof(videoentry)) == 0)) break; } if (i >= vidtbllen) /* no match, default to first entry */ i = 0; oldtabmode = tabmode; oldhelpmode = helpmode; modes_changed = 0; tabmode = 0; helpmode = HELPVIDSEL; i = fullscreen_choice(CHOICEHELP,hdg1,hdg2,NULL,vidtbllen,NULL,attributes, 1,16,74,i,format_vid_table,NULL,NULL,check_modekey); tabmode = oldtabmode; helpmode = oldhelpmode; if (i == -1) { static FCODE msg[]={"Save new function key assignments or cancel changes?"}; if (modes_changed /* update fractint.cfg for new key assignments */ && badconfig == 0 && stopmsg(22,msg) == 0) update_fractint_cfg(); return(-1); } if (i < 0) /* picked by function key */ i = -1 - i; else /* picked by Enter key */ i = entnums[i]; #endif far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i], sizeof(videoentry)); /* the selected entry now in videoentry */ #ifndef XFRACT /* copy fractint.cfg table to resident table, note selected entry */ j = k = 0; far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE); for (i = 0; i < vidtbllen; ++i) { if (vidtbl[i].keynum > 0) { far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i], sizeof(*vidtbl)); if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i], sizeof(videoentry)) == 0) k = vidtbl[i].keynum; if (++j >= MAXVIDEOTABLE-1) break; } } #else k = vidtbl[0].keynum; #endif if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */ far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1], (char far *)&videoentry,sizeof(*vidtbl)); ret = 1400; /* special value for check_vidmode_key */ } if (modes_changed /* update fractint.cfg for new key assignments */ && badconfig == 0) update_fractint_cfg(); return(ret); } void format_vid_table(int choice,char *buf) { char local_buf[81]; char kname[5]; char biosflag; int truecolorbits; far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]], sizeof(videoentry)); vidmode_keyname(videoentry.keynum,kname); biosflag = (char)((videoentry.dotmode % 100 == 1) ? 'B' : ' '); sprintf(buf,"%-5s %-25s %5d %5d ", /* 44 chars */ kname, videoentry.name, videoentry.xdots, videoentry.ydots); if((truecolorbits = videoentry.dotmode/1000) == 0) sprintf(local_buf,"%s%3d", /* 47 chars */ buf, videoentry.colors); else sprintf(local_buf,"%s%3s", /* 47 chars */ buf, (truecolorbits == 4)?" 4g": (truecolorbits == 3)?"16m": (truecolorbits == 2)?"64k": (truecolorbits == 1)?"32k":"???"); sprintf(buf,"%s%c %-25s", /* 74 chars */ local_buf, biosflag, videoentry.comment); } #ifndef XFRACT static int check_modekey(int curkey,int choice) { int i,j,k,ret; if ((i = check_vidmode_key(1,curkey)) >= 0) return(-1-i); i = entsptr[choice]; ret = 0; if ( (curkey == '-' || curkey == '+') && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) { static FCODE msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."}; if (badconfig) stopmsg(0,msg); else { if (curkey == '-') { /* deassign key? */ if (vidtbl[i].keynum >= 1084) { vidtbl[i].keynum = 0; modes_changed = 1; } } else { /* assign key? */ j = getakeynohelp(); if (j >= 1084 && j <= 1113) { for (k = 0; k < vidtbllen; ++k) { if (vidtbl[k].keynum == j) { vidtbl[k].keynum = 0; ret = -1; /* force redisplay */ } } vidtbl[i].keynum = j; modes_changed = 1; } } } } return(ret); } #endif static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2) { int i,j; if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999; if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999; if (i < j || (i == j && *((int *)p1) < *((int *)p2))) return(-1); return(1); } static void update_fractint_cfg() { #ifndef XFRACT char cfgname[100],outname[100],buf[121],kname[5]; FILE *cfgfile,*outfile; int far *cfglinenums; int i,j,linenum,nextlinenum,nextmode; struct videoinfo vident; findpath("fractint.cfg",cfgname); if (access(cfgname,6)) { sprintf(buf,s_cantwrite,cfgname); stopmsg(0,buf); return; } strcpy(outname,cfgname); i = strlen(outname); while (--i >= 0 && outname[i] != SLASHC) outname[i] = 0; strcat(outname,"fractint.tmp"); if ((outfile = fopen(outname,"w")) == NULL) { sprintf(buf,s_cantcreate,outname); stopmsg(0,buf); return; } cfgfile = fopen(cfgname,"r"); cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]); linenum = nextmode = 0; nextlinenum = cfglinenums[0]; while (fgets(buf,120,cfgfile)) { int truecolorbits; char colorsbuf[10]; ++linenum; if (linenum == nextlinenum) { /* replace this line */ far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode], sizeof(videoentry)); vidmode_keyname(vident.keynum,kname); strcpy(buf,vident.name); i = strlen(buf); while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */ --i; j = i + 5; while (j < 32) { /* tab to column 33 */ buf[i++] = '\t'; j += 8; } buf[i] = 0; if((truecolorbits = vident.dotmode/1000) == 0) sprintf(colorsbuf,"%3d",vident.colors); else sprintf(colorsbuf,"%3s", (truecolorbits == 4)?" 4g": (truecolorbits == 3)?"16m": (truecolorbits == 2)?"64k": (truecolorbits == 1)?"32k":"???"); fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%5d,%5d,%s,%s\n", kname, buf, vident.videomodeax, vident.videomodebx, vident.videomodecx, vident.videomodedx, vident.dotmode%1000, /* remove true-color flag, keep textsafe */ vident.xdots, vident.ydots, colorsbuf, vident.comment); if (++nextmode >= vidtbllen) nextlinenum = 32767; else nextlinenum = cfglinenums[nextmode]; } else fputs(buf,outfile); } fclose(cfgfile); fclose(outfile); unlink(cfgname); /* success assumed on these lines */ rename(outname,cfgname); /* since we checked earlier with access */ #endif } /* make_mig() takes a collection of individual GIF images (all presumably the same resolution and all presumably generated by Fractint and its "divide and conquer" algorithm) and builds a single multiple-image GIF out of them. This routine is invoked by the "batch=stitchmode/x/y" option, and is called with the 'x' and 'y' parameters */ void make_mig(unsigned int xmult, unsigned int ymult) { unsigned int xstep, ystep; unsigned int xres, yres; unsigned int allxres, allyres, xtot, ytot; unsigned int xloc, yloc; unsigned char ichar; unsigned int allitbl, itbl; unsigned int i; char gifin[15], gifout[15]; int errorflag, inputerrorflag; unsigned char *temp; FILE *out, *in; char msgbuf[81]; errorflag = 0; /* no errors so far */ inputerrorflag = 0; allxres = allyres = allitbl = 0; out = in = NULL; strcpy(gifout,"fractmig.gif"); temp= &olddacbox[0][0]; /* a safe place for our temp data */ gif87a_flag = 1; /* for now, force this */ /* process each input image, one at a time */ for (ystep = 0; ystep < ymult; ystep++) { for (xstep = 0; xstep < xmult; xstep++) { if (xstep == 0 && ystep == 0) { /* first time through? */ static FCODE msg1[] = "Cannot create output file %s!\n"; static FCODE msg2[] = " \n Generating multi-image GIF file %s using"; static FCODE msg3[] = " %d X and %d Y components\n\n"; far_strcpy(msgbuf, msg2); printf(msgbuf, gifout); far_strcpy(msgbuf, msg3); printf(msgbuf, xmult, ymult); /* attempt to create the output file */ if ((out = fopen(gifout,"wb")) == NULL) { far_strcpy(msgbuf, msg1); printf(msgbuf, gifout); exit(1); } } sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep)); if ((in = fopen(gifin,"rb")) == NULL) { static FCODE msg1[] = "Can't open file %s!\n"; far_strcpy(msgbuf, msg1); printf(msgbuf, gifin); exit(1); } /* (read, but only copy this if it's the first time through) */ if (fread(temp,13,1,in) != 1) /* read the header and LDS */ inputerrorflag = 1; memcpy(&xres, &temp[6], 2); /* X-resolution */ memcpy(&yres, &temp[8], 2); /* Y-resolution */ if (xstep == 0 && ystep == 0) { /* first time through? */ allxres = xres; /* save the "master" resolution */ allyres = yres; xtot = xres * xmult; /* adjust the image size */ ytot = yres * ymult; memcpy(&temp[6], &xtot, 2); memcpy(&temp[8], &ytot, 2); if (gif87a_flag) { temp[3] = '8'; temp[4] = '7'; temp[5] = 'a'; } temp[12] = 0; /* reserved */ if (fwrite(temp,13,1,out) != 1) /* write out the header */ errorflag = 1; } /* end of first-time-through */ ichar = (char)(temp[10] & 0x07); /* find the color table size */ itbl = 1 << (++ichar); ichar = (char)(temp[10] & 0x80); /* is there a global color table? */ if (xstep == 0 && ystep == 0) /* first time through? */ allitbl = itbl; /* save the color table size */ if (ichar != 0) { /* yup */ /* (read, but only copy this if it's the first time through) */ if(fread(temp,3*itbl,1,in) != 1) /* read the global color table */ inputerrorflag = 2; if (xstep == 0 && ystep == 0) /* first time through? */ if (fwrite(temp,3*itbl,1,out) != 1) /* write out the GCT */ errorflag = 2; } if (xres != allxres || yres != allyres || itbl != allitbl) { /* Oops - our pieces don't match */ static FCODE msg1[] = "File %s doesn't have the same resolution as its predecessors!\n"; far_strcpy(msgbuf, msg1); printf(msgbuf, gifin); exit(1); } for (;;) { /* process each information block */ memset(temp,0,10); if (fread(temp,1,1,in) != 1) /* read the block identifier */ inputerrorflag = 3; if (temp[0] == 0x2c) { /* image descriptor block */ if (fread(&temp[1],9,1,in) != 1) /* read the Image Descriptor */ inputerrorflag = 4; memcpy(&xloc, &temp[1], 2); /* X-location */ memcpy(&yloc, &temp[3], 2); /* Y-location */ xloc += (xstep * xres); /* adjust the locations */ yloc += (ystep * yres); memcpy(&temp[1], &xloc, 2); memcpy(&temp[3], &yloc, 2); if (fwrite(temp,10,1,out) != 1) /* write out the Image Descriptor */ errorflag = 4; ichar = (char)(temp[9] & 0x80); /* is there a local color table? */ if (ichar != 0) { /* yup */ if (fread(temp,3*itbl,1,in) != 1) /* read the local color table */ inputerrorflag = 5; if (fwrite(temp,3*itbl,1,out) != 1) /* write out the LCT */ errorflag = 5; } if (fread(temp,1,1,in) != 1) /* LZH table size */ inputerrorflag = 6; if (fwrite(temp,1,1,out) != 1) errorflag = 6; for(;;) { if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ break; if (fread(temp,1,1,in) != 1) /* block size */ inputerrorflag = 7; if (fwrite(temp,1,1,out) != 1) errorflag = 7; if ((i = temp[0]) == 0) break; if (fread(temp,i,1,in) != 1) /* LZH data block */ inputerrorflag = 8; if (fwrite(temp,i,1,out) != 1) errorflag = 8; } } if (temp[0] == 0x21) { /* extension block */ /* (read, but only copy this if it's the last time through) */ if (fread(&temp[2],1,1,in) != 1) /* read the block type */ inputerrorflag = 9; if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1) if (fwrite(temp,2,1,out) != 1) errorflag = 9; for(;;) { if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ break; if (fread(temp,1,1,in) != 1) /* block size */ inputerrorflag = 10; if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1) if (fwrite(temp,1,1,out) != 1) errorflag = 10; if ((i = temp[0]) == 0) break; if (fread(temp,i,1,in) != 1) /* data block */ inputerrorflag = 11; if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1) if (fwrite(temp,i,1,out) != 1) errorflag = 11; } } if (temp[0] == 0x3b) { /* end-of-stream indicator */ break; /* done with this file */ } if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ break; } fclose(in); /* done with an input GIF */ if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ break; } if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ break; } temp[0] = 0x3b; /* end-of-stream indicator */ if (fwrite(temp,1,1,out) != 1) errorflag = 12; fclose(out); /* done with the output GIF */ if (inputerrorflag != 0) { /* uh-oh - something failed */ static FCODE msg1[] = "\007 Process failed = early EOF on input file %s\n"; far_strcpy(msgbuf, msg1); printf(msgbuf, gifin); /* following line was for debugging printf("inputerrorflag = %d\n", inputerrorflag); */ } if (errorflag != 0) { /* uh-oh - something failed */ static FCODE msg1[] = "\007 Process failed = out of disk space?\n"; far_strcpy(msgbuf, msg1); printf(msgbuf); /* following line was for debugging printf("errorflag = %d\n", errorflag); */ } /* now delete each input image, one at a time */ if (errorflag == 0 && inputerrorflag == 0) for (ystep = 0; ystep < ymult; ystep++) { for (xstep = 0; xstep < xmult; xstep++) { sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep)); remove(gifin); } } /* tell the world we're done */ if (errorflag == 0 && inputerrorflag == 0) { static FCODE msg1[] = "File %s has been created (and its component files deleted)\n"; far_strcpy(msgbuf, msg1); printf(msgbuf, gifout); } } /* This routine copies the current screen to by flipping x-axis, y-axis, or both. Refuses to work if calculation in progress or if fractal non-resumable. Clears zoombox if any. Resets corners so resulting fractal is still valid. */ void flip_image(int key) { int i, j, ixhalf, iyhalf, tempdot; /* fractal must be rotate-able and be finished */ if ((curfractalspecific->flags&NOROTATE) != 0 || calc_status == 1 || calc_status == 2) return; if(bf_math) clear_zoombox(); /* clear, don't copy, the zoombox */ ixhalf = xdots / 2; iyhalf = ydots / 2; switch(key) { case 24: /* control-X - reverse X-axis */ for (i = 0; i < ixhalf; i++) { if(keypressed()) break; for (j = 0; j < ydots; j++) { tempdot=getcolor(i,j); putcolor(i, j, getcolor(xdots-1-i,j)); putcolor(xdots-1-i, j, tempdot); } } sxmin = xxmax + xxmin - xx3rd; symax = yymax + yymin - yy3rd; sxmax = xx3rd; symin = yy3rd; sx3rd = xxmax; sy3rd = yymin; if(bf_math) { add_bf(bfsxmin, bfxmax, bfxmin); /* sxmin = xxmax + xxmin - xx3rd; */ sub_a_bf(bfsxmin, bfx3rd); add_bf(bfsymax, bfymax, bfymin); /* symax = yymax + yymin - yy3rd; */ sub_a_bf(bfsymax, bfy3rd); copy_bf(bfsxmax, bfx3rd); /* sxmax = xx3rd; */ copy_bf(bfsymin, bfy3rd); /* symin = yy3rd; */ copy_bf(bfsx3rd, bfxmax); /* sx3rd = xxmax; */ copy_bf(bfsy3rd, bfymin); /* sy3rd = yymin; */ } break; case 25: /* control-Y - reverse Y-aXis */ for (j = 0; j < iyhalf; j++) { if(keypressed()) break; for (i = 0; i < xdots; i++) { tempdot=getcolor(i,j); putcolor(i, j, getcolor(i,ydots-1-j)); putcolor(i,ydots-1-j, tempdot); } } sxmin = xx3rd; symax = yy3rd; sxmax = xxmax + xxmin - xx3rd; symin = yymax + yymin - yy3rd; sx3rd = xxmin; sy3rd = yymax; if(bf_math) { copy_bf(bfsxmin, bfx3rd); /* sxmin = xx3rd; */ copy_bf(bfsymax, bfy3rd); /* symax = yy3rd; */ add_bf(bfsxmax, bfxmax, bfxmin); /* sxmax = xxmax + xxmin - xx3rd; */ sub_a_bf(bfsxmax, bfx3rd); add_bf(bfsymin, bfymax, bfymin); /* symin = yymax + yymin - yy3rd; */ sub_a_bf(bfsymin, bfy3rd); copy_bf(bfsx3rd, bfxmin); /* sx3rd = xxmin; */ copy_bf(bfsy3rd, bfymax); /* sy3rd = yymax; */ } break; case 26: /* control-Z - reverse X and Y aXis */ for (i = 0; i < ixhalf; i++) { if(keypressed()) break; for (j = 0; j < ydots; j++) { tempdot=getcolor(i,j); putcolor(i, j, getcolor(xdots-1-i,ydots-1-j)); putcolor(xdots-1-i, ydots-1-j, tempdot); } } sxmin = xxmax; symax = yymin; sxmax = xxmin; symin = yymax; sx3rd = xxmax + xxmin - xx3rd; sy3rd = yymax + yymin - yy3rd; if(bf_math) { copy_bf(bfsxmin, bfxmax); /* sxmin = xxmax; */ copy_bf(bfsymax, bfymin); /* symax = yymin; */ copy_bf(bfsxmax, bfxmin); /* sxmax = xxmin; */ copy_bf(bfsymin, bfymax); /* symin = yymax; */ add_bf(bfsx3rd, bfxmax, bfxmin); /* sx3rd = xxmax + xxmin - xx3rd; */ sub_a_bf(bfsx3rd, bfx3rd); add_bf(bfsy3rd, bfymax, bfymin); /* sy3rd = yymax + yymin - yy3rd; */ sub_a_bf(bfsy3rd, bfy3rd); } break; } reset_zoom_corners(); calc_status = 0; } static char *expand_var(char *var, char *buf) { static FCODE s_year [] = {"year" }; static FCODE s_month [] = {"month" }; static FCODE s_day [] = {"day" }; static FCODE s_hour [] = {"hour" }; static FCODE s_min [] = {"min" }; static FCODE s_sec [] = {"sec" }; static FCODE s_time [] = {"time" }; static FCODE s_date [] = {"date" }; static FCODE s_calctime[] = {"calctime"}; static FCODE s_version [] = {"version" }; static FCODE s_patch [] = {"patch" }; static FCODE s_xdots [] = {"xdots" }; static FCODE s_ydots [] = {"ydots" }; static FCODE s_vidkey [] = {"vidkey" }; time_t ltime; char *str, *out; time( <ime ); str = ctime(<ime); /* ctime format */ /* Sat Aug 17 21:34:14 1996 */ /* 012345678901234567890123 */ /* 1 2 */ if(far_strcmp(var,s_year) == 0) /* 4 chars */ { str[24] = '\0'; out = &str[20]; } else if(far_strcmp(var,s_month) == 0) /* 3 chars */ { str[7] = '\0'; out = &str[4]; } else if(far_strcmp(var,s_day) == 0) /* 2 chars */ { str[10] = '\0'; out = &str[8]; } else if(far_strcmp(var,s_hour) == 0) /* 2 chars */ { str[13] = '\0'; out = &str[11]; } else if(far_strcmp(var,s_min) == 0) /* 2 chars */ { str[16] = '\0'; out = &str[14]; } else if(far_strcmp(var,s_sec) == 0) /* 2 chars */ { str[19] = '\0'; out = &str[17]; } else if(far_strcmp(var,s_time) == 0) /* 8 chars */ { str[19] = '\0'; out = &str[11]; } else if(far_strcmp(var,s_date) == 0) { str[10] = '\0'; str[24] = '\0'; out = &str[4]; strcat(out,", "); strcat(out,&str[20]); } else if(far_strcmp(var,s_calctime) == 0) { get_calculation_time(buf,calctime); out = buf; } else if(far_strcmp(var,s_version) == 0) /* 4 chars */ { sprintf(buf,"%d",release); out = buf; } else if(far_strcmp(var,s_patch) == 0) /* 1 or 2 chars */ { sprintf(buf,"%d",patchlevel); out = buf; } else if(far_strcmp(var,s_xdots) == 0) /* 2 to 4 chars */ { sprintf(buf,"%d",xdots); out = buf; } else if(far_strcmp(var,s_ydots) == 0) /* 2 to 4 chars */ { sprintf(buf,"%d",ydots); out = buf; } else if(far_strcmp(var,s_vidkey) == 0) /* 2 to 3 chars */ { char vidmde[5]; vidmode_keyname(videoentry.keynum, vidmde); sprintf(buf,"%s",vidmde); out = buf; } else { static char far msg[] = {"Unknown comment variable xxxxxxxxxxxxxxx"}; msg[25] = '\0'; far_strcat(msg,var); stopmsg(0,msg); out = ""; } return(out); } #define MAXVNAME 13 static const char esc_char = '$'; /* extract comments from the comments= command */ void expand_comments(char far *target, char far *source) { int i,j, k, escape = 0; char c, oldc, varname[MAXVNAME]; i=j=k=0; c = oldc = 0; while(i < MAXCMT && j < MAXCMT && (c = *(source+i++)) != '\0') { if(c == '\\' && oldc != '\\') { oldc = c; continue; } /* expand underscores to blanks */ if(c == '_' && oldc != '\\') c = ' '; /* esc_char marks start and end of variable names */ if(c == esc_char && oldc != '\\') escape = 1 - escape; if(c != esc_char && escape != 0) /* if true, building variable name */ { if(k < MAXVNAME-1) varname[k++] = c; } /* got variable name */ else if(c == esc_char && escape == 0 && oldc != '\\') { char buf[100]; char *varstr; varname[k] = 0; varstr = expand_var(varname,buf); far_strncpy(target+j,varstr,MAXCMT-j-1); j += strlen(varstr); } else if (c == esc_char && escape != 0 && oldc != '\\') k = 0; else if ((c != esc_char || oldc == '\\') && escape == 0) *(target+j++) = c; oldc = c; } if(*source != '\0') *(target+min(j,MAXCMT-1)) = '\0'; } /* extract comments from the comments= command */ void parse_comments(char *value) { int i; char *next,save; for(i=0;i<4;i++) { save = '\0'; if (*value == 0) break; next = strchr(value,'/'); if (*value != '/') { if(next != NULL) { save = *next; *next = '\0'; } far_strncpy(par_comment[i],value, MAXCMT); } if(next == NULL) break; if(save != '\0') *next = save; value = next+1; } } void init_comments() { int i; for(i=0;i<4;i++) par_comment[i][0] = '\0'; } xfractint-20.4.10.orig/common/loadfile.c0000644000000000000000000020464511257714555014747 0ustar /* loadfile.c - load an existing fractal image, control level */ #include #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" #include "targa_lc.h" /* routines in this module */ static int find_fractal_info(char *,struct fractal_info *, struct ext_blk_2 *, struct ext_blk_3 *, struct ext_blk_4 *, struct ext_blk_5 *, struct ext_blk_6 *, struct ext_blk_7 *); static void load_ext_blk(char far *loadptr,int loadlen); static void skip_ext_blk(int *,int *); static void backwardscompat(struct fractal_info *info); static int fix_bof(void); static int fix_period_bof(void); int filetype; int loaded3d; static FILE *fp; int fileydots, filexdots, filecolors; float fileaspectratio; short skipxdots,skipydots; /* for decoder, when reducing image */ int bad_outside = 0; int ldcheck = 0; int read_overlay() /* read overlay/3D files, if reqr'd */ { struct fractal_info read_info; char oldfloatflag; char msg[110]; struct ext_blk_2 blk_2_info; struct ext_blk_3 blk_3_info; struct ext_blk_4 blk_4_info; struct ext_blk_5 blk_5_info; struct ext_blk_6 blk_6_info; struct ext_blk_7 blk_7_info; showfile = 1; /* for any abort exit, pretend done */ initmode = -1; /* no viewing mode set yet */ oldfloatflag = usr_floatflag; loaded3d = 0; if(fastrestore) viewwindow=0; if(has_ext(readname) == NULL) strcat(readname,".gif"); if(find_fractal_info(readname,&read_info,&blk_2_info,&blk_3_info, &blk_4_info,&blk_5_info,&blk_6_info,&blk_7_info)) { /* didn't find a useable file */ sprintf(msg,"Sorry, %s isn't a file I can decode.",readname); stopmsg(0,msg); return(-1); } maxit = read_info.iterationsold; fractype = read_info.fractal_type; if (fractype < 0 || fractype >= num_fractal_types) { sprintf(msg,"Warning: %s has a bad fractal type; using 0",readname); fractype = 0; } curfractalspecific = &fractalspecific[fractype]; xxmin = read_info.xmin; xxmax = read_info.xmax; yymin = read_info.ymin; yymax = read_info.ymax; param[0] = read_info.creal; param[1] = read_info.cimag; save_release = 1100; /* unless we find out better later on */ invert = 0; if(read_info.version > 0) { param[2] = read_info.parm3; roundfloatd(¶m[2]); param[3] = read_info.parm4; roundfloatd(¶m[3]); potparam[0] = read_info.potential[0]; potparam[1] = read_info.potential[1]; potparam[2] = read_info.potential[2]; if(*s_makepar == '\0') colors = read_info.colors; potflag = (potparam[0] != 0.0); rflag = read_info.rflag; rseed = read_info.rseed; inside = read_info.inside; LogFlag = read_info.logmapold; inversion[0] = read_info.invert[0]; inversion[1] = read_info.invert[1]; inversion[2] = read_info.invert[2]; if (inversion[0] != 0.0) invert = 3; decomp[0] = read_info.decomp[0]; decomp[1] = read_info.decomp[1]; usr_biomorph = read_info.biomorph; forcesymmetry = read_info.symmetry; } if(read_info.version > 1) { save_release = 1200; if (!display3d && (read_info.version <= 4 || read_info.flag3d > 0 || (curfractalspecific->flags&PARMS3D) )) { int i; for (i = 0; i < 16; i++) init3d[i] = read_info.init3d[i]; previewfactor = read_info.previewfactor; xtrans = read_info.xtrans; ytrans = read_info.ytrans; red_crop_left = read_info.red_crop_left; red_crop_right = read_info.red_crop_right; blue_crop_left = read_info.blue_crop_left; blue_crop_right = read_info.blue_crop_right; red_bright = read_info.red_bright; blue_bright = read_info.blue_bright; xadjust = read_info.xadjust; eyeseparation = read_info.eyeseparation; glassestype = read_info.glassestype; } } if(read_info.version > 2) { save_release = 1300; outside = read_info.outside; } calc_status = 0; /* defaults if version < 4 */ xx3rd = xxmin; yy3rd = yymin; usr_distest = 0; calctime = 0; if(read_info.version > 3) { save_release = 1400; xx3rd = read_info.x3rd; yy3rd = read_info.y3rd; calc_status = read_info.calc_status; usr_stdcalcmode = read_info.stdcalcmode; three_pass = 0; if(usr_stdcalcmode == 127) { three_pass = 1; usr_stdcalcmode = '3'; } usr_distest = read_info.distestold; usr_floatflag = (char)read_info.floatflag; bailout = read_info.bailoutold; calctime = read_info.calctime; trigndx[0] = read_info.trigndx[0]; trigndx[1] = read_info.trigndx[1]; trigndx[2] = read_info.trigndx[2]; trigndx[3] = read_info.trigndx[3]; finattract = read_info.finattract; initorbit.x = read_info.initorbit[0]; initorbit.y = read_info.initorbit[1]; useinitorbit = read_info.useinitorbit; usr_periodicitycheck = read_info.periodicity; } pot16bit = 0; save_system = 0; if(read_info.version > 4) { pot16bit = read_info.pot16bit; if (pot16bit) filexdots >>= 1; fileaspectratio = read_info.faspectratio; if (fileaspectratio < 0.01) /* fix files produced in early v14.1 */ fileaspectratio = screenaspect; save_system = read_info.system; save_release = read_info.release; /* from fmt 5 on we know real number */ if (read_info.version == 5 /* except a few early fmt 5 cases: */ && (save_release <= 0 || save_release >= 4000)) { save_release = 1410; save_system = 0; } if (!display3d && read_info.flag3d > 0) { loaded3d = 1; Ambient = read_info.ambient; RANDOMIZE = read_info.randomize; haze = read_info.haze; transparent[0] = read_info.transparent[0]; transparent[1] = read_info.transparent[1]; } } rotate_lo = 1; rotate_hi = 255; distestwidth = 71; if(read_info.version > 5) { rotate_lo = read_info.rotate_lo; rotate_hi = read_info.rotate_hi; distestwidth = read_info.distestwidth; } if(read_info.version > 6) { param[2] = read_info.dparm3; param[3] = read_info.dparm4; } if(read_info.version > 7) { fillcolor = read_info.fillcolor; } if(read_info.version > 8) { mxmaxfp = read_info.mxmaxfp ; mxminfp = read_info.mxminfp ; mymaxfp = read_info.mymaxfp ; myminfp = read_info.myminfp ; zdots = read_info.zdots ; originfp = read_info.originfp ; depthfp = read_info.depthfp ; heightfp = read_info.heightfp ; widthfp = read_info.widthfp ; distfp = read_info.distfp ; eyesfp = read_info.eyesfp ; neworbittype = read_info.orbittype ; juli3Dmode = read_info.juli3Dmode ; maxfn = (char)read_info.maxfn ; major_method = (enum Major)read_info.inversejulia >> 8; minor_method = (enum Minor)read_info.inversejulia & 255; param[4] = read_info.dparm5; param[5] = read_info.dparm6; param[6] = read_info.dparm7; param[7] = read_info.dparm8; param[8] = read_info.dparm9; param[9] = read_info.dparm10; } if(read_info.version < 4 && read_info.version != 0) { /* pre-version 14.0? */ backwardscompat(&read_info); /* translate obsolete types */ if(LogFlag) LogFlag = 2; usr_floatflag = (char)((curfractalspecific->isinteger) ? 0 : 1); } if (read_info.version < 5 && read_info.version != 0) { /* pre-version 15.0? */ if (LogFlag == 2) /* logmap=old changed again in format 5! */ LogFlag = -1; if (decomp[0] > 0 && decomp[1] > 0) bailout = decomp[1]; } if(potflag) /* in version 15.x and 16.x logmap didn't work with pot */ if(read_info.version == 6 || read_info.version == 7) LogFlag = 0; set_trig_pointers(-1); if(read_info.version < 9 && read_info.version != 0) { /* pre-version 18.0? */ /* forcesymmetry==1000 means we want to force symmetry but don't know which symmetry yet, will find out in setsymmetry() */ if(outside==REAL || outside==IMAG || outside==MULT || outside==SUM || outside==ATAN) if(forcesymmetry == 999) forcesymmetry = 1000; } if(save_release < 1725 && read_info.version != 0) { /* pre-version 17.25 */ set_if_old_bif(); /* translate bifurcation types */ functionpreloaded = 1; } if(read_info.version > 9) { /* post-version 18.22 */ bailout = read_info.bailout; /* use long bailout */ bailoutest = (enum bailouts)read_info.bailoutest; } else bailoutest = Mod; setbailoutformula(bailoutest); if(read_info.version > 9) { /* post-version 18.23 */ maxit = read_info.iterations; /* use long maxit */ /* post-version 18.27 */ old_demm_colors = read_info.old_demm_colors; } if (read_info.version > 10) { /* post-version 19.20 */ LogFlag = read_info.logmap; usr_distest= read_info.distest; } if (read_info.version > 11) { /* post-version 19.20, inversion fix */ inversion[0] = read_info.dinvert[0]; inversion[1] = read_info.dinvert[1]; inversion[2] = read_info.dinvert[2]; Log_Fly_Calc = read_info.logcalc; stoppass = read_info.stoppass; } if (read_info.version > 12) { /* post-version 19.60 */ quick_calc = read_info.quick_calc; closeprox = read_info.closeprox; if (fractype == FPPOPCORN || fractype == LPOPCORN || fractype == FPPOPCORNJUL || fractype == LPOPCORNJUL || fractype == LATOO) functionpreloaded = 1; } nobof=0; if (read_info.version > 13) { /* post-version 20.1.2 */ nobof = read_info.nobof; } /* if (read_info.version > 14) post-version 20.1.12 */ /* modified saved evolver structure JCO 12JUL01 */ Log_Auto_Calc = 0; /* make sure it's turned off */ orbit_interval = 1; if (read_info.version > 15) { /* post-version 20.3.2 */ orbit_interval = read_info.orbit_interval; } orbit_delay = 0; math_tol[0] = 0.05; math_tol[1] = 0.05; if (read_info.version > 16) { /* post-version 20.4.0 */ orbit_delay = read_info.orbit_delay; math_tol[0] = read_info.math_tol[0]; math_tol[1] = read_info.math_tol[1]; } backwards_v18(); backwards_v19(); backwards_v20(); if (display3d) /* PB - a klooge till the meaning of */ usr_floatflag = oldfloatflag; /* floatflag in line3d is clarified */ if (overlay3d) { initmode = adapter; /* use previous adapter mode for overlays */ if (filexdots > xdots || fileydots > ydots) { static FCODE msg[]={"Can't overlay with a larger image"}; stopmsg(0,msg); initmode = -1; return(-1); } } else { int olddisplay3d,i; char oldfloatflag; olddisplay3d = display3d; oldfloatflag = floatflag; display3d = loaded3d; /* for display during next */ floatflag = usr_floatflag; /* ditto */ i = get_video_mode(&read_info,&blk_3_info); display3d = olddisplay3d; floatflag = oldfloatflag; if (i) { if(blk_2_info.got_data == 1) { MemoryRelease((U16)blk_2_info.resume_data); blk_2_info.length = 0; } initmode = -1; return(-1); } } if (display3d) { calc_status = 0; fractype = PLASMA; curfractalspecific = &fractalspecific[PLASMA]; param[0] = 0; if (!initbatch) if (get_3d_params() < 0) { initmode = -1; return(-1); } } if (resume_info != 0) { /* free the prior area if there is one */ MemoryRelease(resume_info); resume_info = 0; } if(blk_2_info.got_data == 1) { resume_info = (U16)blk_2_info.resume_data; resume_len = blk_2_info.length; } if(blk_3_info.got_data == 1) { char *nameptr; switch (read_info.fractal_type) { case LSYSTEM: nameptr = LName; break; case IFS: case IFS3D: nameptr = IFSName; break; default: nameptr = FormName; uses_p1 = blk_3_info.uses_p1; uses_p2 = blk_3_info.uses_p2; uses_p3 = blk_3_info.uses_p3; uses_ismand = blk_3_info.uses_ismand; ismand = blk_3_info.ismand; uses_p4 = blk_3_info.uses_p4; uses_p5 = blk_3_info.uses_p5; break; } blk_3_info.form_name[ITEMNAMELEN] = 0; strcpy(nameptr,blk_3_info.form_name); /* perhaps in future add more here, check block_len for backward compatibility */ } if (rangeslen) { /* free prior ranges */ farmemfree((char far *)ranges); rangeslen = 0; } if(blk_4_info.got_data == 1) { ranges = (int far *)blk_4_info.range_data; rangeslen = blk_4_info.length; #ifdef XFRACT fix_ranges(ranges,rangeslen,1); #endif } if(blk_5_info.got_data == 1) { bf_math = 1; init_bf_length(read_info.bflength); far_memcpy((char far *)bfxmin,blk_5_info.apm_data,blk_5_info.length); farmemfree(blk_5_info.apm_data); } else bf_math = 0; if(blk_6_info.got_data == 1) { struct evolution_info resume_e_info; GENEBASE gene[NUMGENES]; int i; if (gene_handle == 0) gene_handle = MemoryAlloc((U16)sizeof(gene),1L,FARMEM); MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); if (read_info.version < 15) /* This is VERY Ugly! JCO 14JUL01 */ /* Increasing NUMGENES moves ecount in the data structure */ /* We added 4 to NUMGENES, so ecount is at NUMGENES-4 */ blk_6_info.ecount = blk_6_info.mutate[NUMGENES-4]; if (blk_6_info.ecount != blk_6_info.gridsz * blk_6_info.gridsz && calc_status != 4) { calc_status = 2; if (evolve_handle == 0) evolve_handle = MemoryAlloc((U16)sizeof(resume_e_info),1L,FARMEM); resume_e_info.paramrangex = blk_6_info.paramrangex; resume_e_info.paramrangey = blk_6_info.paramrangey; resume_e_info.opx = blk_6_info.opx; resume_e_info.opy = blk_6_info.opy; resume_e_info.odpx = blk_6_info.odpx; resume_e_info.odpy = blk_6_info.odpy; resume_e_info.px = blk_6_info.px; resume_e_info.py = blk_6_info.py; resume_e_info.sxoffs = blk_6_info.sxoffs; resume_e_info.syoffs = blk_6_info.syoffs; resume_e_info.xdots = blk_6_info.xdots; resume_e_info.ydots = blk_6_info.ydots; resume_e_info.gridsz = blk_6_info.gridsz; resume_e_info.evolving = blk_6_info.evolving; resume_e_info.this_gen_rseed = blk_6_info.this_gen_rseed; resume_e_info.fiddlefactor = blk_6_info.fiddlefactor; resume_e_info.ecount = blk_6_info.ecount; MoveToMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle); } else { if (evolve_handle != 0) /* Image completed, release it. */ MemoryRelease(evolve_handle); evolve_handle = 0; calc_status = 4; } paramrangex = blk_6_info.paramrangex; paramrangey = blk_6_info.paramrangey; opx = newopx = blk_6_info.opx; opy = newopy = blk_6_info.opy; odpx = newodpx = (char)blk_6_info.odpx; odpy = newodpy = (char)blk_6_info.odpy; px = blk_6_info.px; py = blk_6_info.py; sxoffs = blk_6_info.sxoffs; syoffs = blk_6_info.syoffs; xdots = blk_6_info.xdots; ydots = blk_6_info.ydots; gridsz = blk_6_info.gridsz; this_gen_rseed = blk_6_info.this_gen_rseed; fiddlefactor = blk_6_info.fiddlefactor; evolving = viewwindow = (int)blk_6_info.evolving; dpx=paramrangex/(gridsz-1); dpy=paramrangey/(gridsz-1); if (read_info.version > 14) for (i = 0; i < NUMGENES; i++) gene[i].mutate = (int)blk_6_info.mutate[i]; else { for (i = 0; i < 6; i++) gene[i].mutate = (int)blk_6_info.mutate[i]; for (i = 6; i < 10; i++) gene[i].mutate = 0; for (i = 10; i < NUMGENES; i++) gene[i].mutate = (int)blk_6_info.mutate[i-4]; } MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); param_history(0); /* store history */ } else { evolving = FALSE; } if(blk_7_info.got_data == 1) { oxmin = blk_7_info.oxmin; oxmax = blk_7_info.oxmax; oymin = blk_7_info.oymin; oymax = blk_7_info.oymax; ox3rd = blk_7_info.ox3rd; oy3rd = blk_7_info.oy3rd; keep_scrn_coords = blk_7_info.keep_scrn_coords; drawmode = blk_7_info.drawmode; if(keep_scrn_coords) set_orbit_corners = 1; } showfile = 0; /* trigger the file load */ return(0); } static int find_fractal_info(char *gif_file,struct fractal_info *info, struct ext_blk_2 *blk_2_info, struct ext_blk_3 *blk_3_info, struct ext_blk_4 *blk_4_info, struct ext_blk_5 *blk_5_info, struct ext_blk_6 *blk_6_info, struct ext_blk_7 *blk_7_info) { BYTE gifstart[18]; char temp1[81]; int scan_extend, block_type, block_len, data_len; int fractinf_len; int hdr_offset; struct formula_info fload_info; struct evolution_info eload_info; struct orbits_info oload_info; int i, j, k = 0; int dummy; /* to quiet compiler */ blk_2_info->got_data = 0; /* initialize to no data */ blk_3_info->got_data = 0; /* initialize to no data */ blk_4_info->got_data = 0; /* initialize to no data */ blk_5_info->got_data = 0; /* initialize to no data */ blk_6_info->got_data = 0; /* initialize to no data */ blk_7_info->got_data = 0; /* initialize to no data */ if((fp = fopen(gif_file,"rb"))==NULL) return(-1); dummy = fread(gifstart,13,1,fp); if (strncmp((char *)gifstart,"GIF",3) != 0) { /* not GIF, maybe old .tga? */ fclose(fp); return(-1); } filetype = 0; /* GIF */ GET16(gifstart[6],filexdots); GET16(gifstart[8],fileydots); filecolors = 2 << (gifstart[10] & 7); fileaspectratio = 0; /* unknown */ if (gifstart[12]) { /* calc reasonably close value from gif header */ fileaspectratio = (float)((64.0 / ((double)(gifstart[12]) + 15.0)) * (double)fileydots / (double)filexdots); if ( fileaspectratio > screenaspect-0.03 && fileaspectratio < screenaspect+0.03) fileaspectratio = screenaspect; } else if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */ fileaspectratio = screenaspect; if(*s_makepar == 0 && (gifstart[10] & 0x80)!=0) { for (i = 0; i < filecolors; i++) { for (j = 0; j < 3; j++) { if ((k = getc(fp)) < 0) break; dacbox[i][j] = (BYTE)(k >> 2); } if(k < 0) break; } } /* Format of .gif extension blocks is: 1 byte '!', extension block identifier 1 byte extension block number, 255 1 byte length of id, 11 11 bytes alpha id, "fractintnnn" with fractint, nnn is secondary id n * { 1 byte length of block info in bytes x bytes block info } 1 byte 0, extension terminator To scan extension blocks, we first look in file at length of fractal_info (the main extension block) from end of file, looking for a literal known to be at start of our block info. Then we scan forward a bit, in case the file is from an earlier fractint vsn with shorter fractal_info. If fractal_info is found and is from vsn>=14, it includes the total length of all extension blocks; we then scan them all first to last to load any optional ones which are present. Defined extension blocks: fractint001 header, always present fractint002 resume info for interrupted resumable image fractint003 additional formula type info fractint004 ranges info fractint005 extended precision parameters fractint006 evolver params */ memset(info,0,FRACTAL_INFO_SIZE); fractinf_len = FRACTAL_INFO_SIZE + (FRACTAL_INFO_SIZE+254)/255; fseek(fp,(long)(-1-fractinf_len),SEEK_END); dummy = fread(info,1,FRACTAL_INFO_SIZE,fp); if (strcmp(INFO_ID,info->info_id) == 0) { #ifdef XFRACT decode_fractal_info(info,1); #endif hdr_offset = -1-fractinf_len; } else { /* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */ int offset,i; char tmpbuf[110]; hdr_offset = 0; offset = 80; /* don't even check last 80 bytes of file for id */ while (offset < fractinf_len+513) { /* allow 512 garbage at eof */ offset += 100; /* go back 100 bytes at a time */ fseek(fp,(long)(0-offset),SEEK_END); dummy = fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */ for (i = 0; i < 100; ++i) if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */ strcpy(info->info_id,INFO_ID); fseek(fp,(long)(hdr_offset=i-offset),SEEK_END); dummy = fread(info,1,FRACTAL_INFO_SIZE,fp); #ifdef XFRACT decode_fractal_info(info,1); #endif offset = 10000; /* force exit from outer loop */ break; } } } if (hdr_offset) { /* we found INFO_ID */ if (info->version >= 4) { /* first reload main extension block, reasons: might be over 255 chars, and thus earlier load might be bad find exact endpoint, so scan back to start of ext blks works */ fseek(fp,(long)(hdr_offset-15),SEEK_END); scan_extend = 1; while (scan_extend) { if (fgetc(fp) != '!' /* if not what we expect just give up */ || fread(temp1,1,13,fp) != 13 || strncmp(&temp1[2],"fractint",8)) break; temp1[13] = 0; block_type = atoi(&temp1[10]); /* e.g. "fractint002" */ switch (block_type) { case 1: /* "fractint001", the main extension block */ if (scan_extend == 2) { /* we've been here before, done now */ scan_extend = 0; break; } load_ext_blk((char far *)info,FRACTAL_INFO_SIZE); #ifdef XFRACT decode_fractal_info(info,1); #endif scan_extend = 2; /* now we know total extension len, back up to first block */ fseek(fp,0L-info->tot_extend_len,SEEK_CUR); break; case 2: /* resume info */ skip_ext_blk(&block_len,&data_len); /* once to get lengths */ if ((blk_2_info->resume_data = MemoryAlloc((U16)1,(long)data_len,FARMEM)) == 0) info->calc_status = 3; /* not resumable after all */ else { fseek(fp,(long)(0-block_len),SEEK_CUR); load_ext_blk((char far *)block,data_len); MoveToMemory((BYTE *)block,(U16)1,(long)data_len,0,(U16)blk_2_info->resume_data); blk_2_info->length = data_len; blk_2_info->got_data = 1; /* got data */ } break; case 3: /* formula info */ skip_ext_blk(&block_len,&data_len); /* once to get lengths */ /* check data_len for backward compatibility */ fseek(fp,(long)(0-block_len),SEEK_CUR); load_ext_blk((char far *)&fload_info,data_len); strcpy(blk_3_info->form_name,fload_info.form_name); blk_3_info->length = data_len; blk_3_info->got_data = 1; /* got data */ if (data_len < sizeof(fload_info)) { /* must be old GIF */ blk_3_info->uses_p1 = 1; blk_3_info->uses_p2 = 1; blk_3_info->uses_p3 = 1; blk_3_info->uses_ismand = 0; blk_3_info->ismand = 1; blk_3_info->uses_p4 = 0; blk_3_info->uses_p5 = 0; } else { blk_3_info->uses_p1 = fload_info.uses_p1; blk_3_info->uses_p2 = fload_info.uses_p2; blk_3_info->uses_p3 = fload_info.uses_p3; blk_3_info->uses_ismand = fload_info.uses_ismand; blk_3_info->ismand = fload_info.ismand; blk_3_info->uses_p4 = fload_info.uses_p4; blk_3_info->uses_p5 = fload_info.uses_p5; } break; case 4: /* ranges info */ skip_ext_blk(&block_len,&data_len); /* once to get lengths */ if ((blk_4_info->range_data = (int far *)farmemalloc((long)data_len)) != NULL) { fseek(fp,(long)(0-block_len),SEEK_CUR); load_ext_blk((char far *)blk_4_info->range_data,data_len); blk_4_info->length = data_len/2; blk_4_info->got_data = 1; /* got data */ } break; case 5: /* extended precision parameters */ skip_ext_blk(&block_len,&data_len); /* once to get lengths */ if ((blk_5_info->apm_data = (char far *)farmemalloc((long)data_len)) != NULL) { fseek(fp,(long)(0-block_len),SEEK_CUR); load_ext_blk(blk_5_info->apm_data,data_len); blk_5_info->length = data_len; blk_5_info->got_data = 1; /* got data */ } break; case 6: /* evolver params */ skip_ext_blk(&block_len,&data_len); /* once to get lengths */ fseek(fp,(long)(0-block_len),SEEK_CUR); load_ext_blk((char far *)&eload_info,data_len); /* XFRACT processing of doubles here */ #ifdef XFRACT decode_evolver_info(&eload_info,1); #endif blk_6_info->length = data_len; blk_6_info->got_data = 1; /* got data */ blk_6_info->paramrangex = eload_info.paramrangex; blk_6_info->paramrangey = eload_info.paramrangey; blk_6_info->opx = eload_info.opx; blk_6_info->opy = eload_info.opy; blk_6_info->odpx = (char)eload_info.odpx; blk_6_info->odpy = (char)eload_info.odpy; blk_6_info->px = eload_info.px; blk_6_info->py = eload_info.py; blk_6_info->sxoffs = eload_info.sxoffs; blk_6_info->syoffs = eload_info.syoffs; blk_6_info->xdots = eload_info.xdots; blk_6_info->ydots = eload_info.ydots; blk_6_info->gridsz = eload_info.gridsz; blk_6_info->evolving = eload_info.evolving; blk_6_info->this_gen_rseed = eload_info.this_gen_rseed; blk_6_info->fiddlefactor = eload_info.fiddlefactor; blk_6_info->ecount = eload_info.ecount; for (i = 0; i < NUMGENES; i++) blk_6_info->mutate[i] = eload_info.mutate[i]; break; case 7: /* orbits parameters */ skip_ext_blk(&block_len,&data_len); /* once to get lengths */ fseek(fp,(long)(0-block_len),SEEK_CUR); load_ext_blk((char far *)&oload_info,data_len); /* XFRACT processing of doubles here */ #ifdef XFRACT decode_orbits_info(&oload_info,1); #endif blk_7_info->length = data_len; blk_7_info->got_data = 1; /* got data */ blk_7_info->oxmin = oload_info.oxmin; blk_7_info->oxmax = oload_info.oxmax; blk_7_info->oymin = oload_info.oymin; blk_7_info->oymax = oload_info.oymax; blk_7_info->ox3rd = oload_info.ox3rd; blk_7_info->oy3rd = oload_info.oy3rd; blk_7_info->keep_scrn_coords= oload_info.keep_scrn_coords; blk_7_info->drawmode = oload_info.drawmode; break; default: skip_ext_blk(&block_len,&data_len); } } } fclose(fp); fileaspectratio = screenaspect; /* if not >= v15, this is correct */ return(0); } strcpy(info->info_id, "GIFFILE"); info->iterations = 150; info->iterationsold = 150; info->fractal_type = PLASMA; info->xmin = -1; info->xmax = 1; info->ymin = -1; info->ymax = 1; info->x3rd = -1; info->y3rd = -1; info->creal = 0; info->cimag = 0; info->videomodeax=255; info->videomodebx=255; info->videomodecx=255; info->videomodedx=255; info->dotmode = 0; info->xdots = (short)filexdots; info->ydots = (short)fileydots; info->colors = (short)filecolors; info->version = 0; /* this forces lots more init at calling end too */ /* zero means we won */ fclose(fp); return(0); } static void load_ext_blk(char far *loadptr,int loadlen) { int len; while ((len = fgetc(fp)) > 0) { while (--len >= 0) { if (--loadlen >= 0) *(loadptr++) = (char)fgetc(fp); else fgetc(fp); /* discard excess characters */ } } } static void skip_ext_blk(int *block_len, int *data_len) { int len; *data_len = 0; *block_len = 1; while ((len = fgetc(fp)) > 0) { fseek(fp,(long)len,SEEK_CUR); *data_len += len; *block_len += len + 1; } } /* switch obsolete fractal types to new generalizations */ static void backwardscompat(struct fractal_info *info) { switch(fractype) { case LAMBDASINE: fractype = LAMBDATRIGFP; trigndx[0] = SIN; break; case LAMBDACOS : fractype = LAMBDATRIGFP; trigndx[0] = COS; break; case LAMBDAEXP : fractype = LAMBDATRIGFP; trigndx[0] = EXP; break; case MANDELSINE : fractype = MANDELTRIGFP; trigndx[0] = SIN; break; case MANDELCOS : fractype = MANDELTRIGFP; trigndx[0] = COS; break; case MANDELEXP : fractype = MANDELTRIGFP; trigndx[0] = EXP; break; case MANDELSINH : fractype = MANDELTRIGFP; trigndx[0] = SINH; break; case LAMBDASINH : fractype = LAMBDATRIGFP; trigndx[0] = SINH; break; case MANDELCOSH : fractype = MANDELTRIGFP; trigndx[0] = COSH; break; case LAMBDACOSH : fractype = LAMBDATRIGFP; trigndx[0] = COSH; break; case LMANDELSINE : fractype = MANDELTRIG; trigndx[0] = SIN; break; case LLAMBDASINE : fractype = LAMBDATRIG; trigndx[0] = SIN; break; case LMANDELCOS : fractype = MANDELTRIG; trigndx[0] = COS; break; case LLAMBDACOS : fractype = LAMBDATRIG; trigndx[0] = COS; break; case LMANDELSINH : fractype = MANDELTRIG; trigndx[0] = SINH; break; case LLAMBDASINH : fractype = LAMBDATRIG; trigndx[0] = SINH; break; case LMANDELCOSH : fractype = MANDELTRIG; trigndx[0] = COSH; break; case LLAMBDACOSH : fractype = LAMBDATRIG; trigndx[0] = COSH; break; case LMANDELEXP : fractype = MANDELTRIG; trigndx[0] = EXP; break; case LLAMBDAEXP : fractype = LAMBDATRIG; trigndx[0] = EXP; break; case DEMM : fractype = MANDELFP; usr_distest = (info->ydots - 1) * 2; break; case DEMJ : fractype = JULIAFP; usr_distest = (info->ydots - 1) * 2; break; case MANDELLAMBDA : useinitorbit = 2; break; } curfractalspecific = &fractalspecific[fractype]; } /* switch old bifurcation fractal types to new generalizations */ void set_if_old_bif(void) { /* set functions if not set already, may need to check 'functionpreloaded' before calling this routine. JCO 7/5/92 */ switch(fractype) { case BIFURCATION: case LBIFURCATION: case BIFSTEWART: case LBIFSTEWART: case BIFLAMBDA: case LBIFLAMBDA: set_trig_array(0,s_ident); break; case BIFEQSINPI: case LBIFEQSINPI: case BIFADSINPI: case LBIFADSINPI: set_trig_array(0,s_sin); break; } } /* miscellaneous function variable defaults */ void set_function_parm_defaults(void) { switch(fractype) { case FPPOPCORN: case LPOPCORN: case FPPOPCORNJUL: case LPOPCORNJUL: set_trig_array(0,s_sin); set_trig_array(1,s_tan); set_trig_array(2,s_sin); set_trig_array(3,s_tan); break; case LATOO: set_trig_array(0,s_sin); set_trig_array(1,s_sin); set_trig_array(2,s_sin); set_trig_array(3,s_sin); break; } } void backwards_v18(void) { if(!functionpreloaded) set_if_old_bif(); /* old bifs need function set, JCO 7/5/92 */ if(fractype==MANDELTRIG && usr_floatflag==1 && save_release < 1800 && bailout == 0) bailout = 2500; if(fractype==LAMBDATRIG && usr_floatflag==1 && save_release < 1800 && bailout == 0) bailout = 2500; } void backwards_v19(void) { if(fractype==MARKSJULIA && save_release < 1825) { if(param[2] == 0) param[2] = 2; else param[2] += 1; } if(fractype==MARKSJULIAFP && save_release < 1825) { if(param[2] == 0) param[2] = 2; else param[2] += 1; } if((fractype==FORMULA || fractype==FFORMULA) && save_release < 1824) inversion[0] = inversion[1] = inversion[2] = invert = 0; if(fix_bof()) no_mag_calc = 1; /* fractal has old bof60/61 problem with magnitude */ else no_mag_calc = 0; if(fix_period_bof()) use_old_period = 1; /* fractal uses old periodicity method */ else use_old_period = 0; if(save_release < 1827 && distest) use_old_distest = 1; /* use old distest code */ else use_old_distest = 0; /* use new distest code */ } void backwards_v20(void) { /* Fractype == FP type is not seen from PAR file ????? */ if((fractype == MANDELFP || fractype == JULIAFP || fractype == MANDEL || fractype == JULIA) && (outside <= REAL && outside >= SUM) && save_release <= 1960) bad_outside = 1; else bad_outside = 0; if((fractype == FORMULA || fractype == FFORMULA) && (save_release < 1900 || debugflag == 94)) ldcheck = 1; else ldcheck = 0; if(inside == EPSCROSS && save_release < 1961) closeprox = 0.01; if(!functionpreloaded) set_function_parm_defaults(); } int check_back(void) { /* put the features that need to save the value in save_release for backwards compatibility in this routine */ int ret = 0; if (fractype == LYAPUNOV || fractype == FROTH || fractype == FROTHFP || fix_bof() || fix_period_bof() || use_old_distest || decomp[0] == 2 || (fractype == FORMULA && save_release <= 1920) || (fractype == FFORMULA && save_release <= 1920) || (LogFlag != 0 && save_release <= 2001) || (fractype == TRIGSQR && save_release < 1900) || (inside == STARTRAIL && save_release < 1825) || (maxit > 32767 && save_release <= 1950) || (distest && save_release <=1950) || ((outside <= REAL && outside >= ATAN) && save_release <= 1960) || (fractype == FPPOPCORN && save_release <= 1960) || (fractype == LPOPCORN && save_release <= 1960) || (fractype == FPPOPCORNJUL && save_release <= 1960) || (fractype == LPOPCORNJUL && save_release <= 1960) || (inside == FMODI && save_release <= 2000) || ((inside == ATANI || outside == ATAN) && save_release <= 2005) || (fractype == LAMBDATRIGFP && trigndx[0] == EXP && save_release <= 2002) || ((fractype == JULIBROT || fractype == JULIBROTFP) && (neworbittype == QUATFP || neworbittype == HYPERCMPLXFP) && save_release <= 2002) ) ret = 1; return(ret); } static int fix_bof(void) { int ret = 0; if (inside <= BOF60 && inside >= BOF61 && save_release < 1826) if ((curfractalspecific->calctype == StandardFractal && (curfractalspecific->flags & BAILTEST) == 0) || (fractype==FORMULA || fractype==FFORMULA)) ret = 1; return (ret); } static int fix_period_bof(void) { int ret = 0; if (inside <= BOF60 && inside >= BOF61 && save_release < 1826) ret = 1; return (ret); } /* browse code RB*/ #define MAX_WINDOWS_OPEN 450 struct window { /* for fgetwindow on screen browser */ struct coords itl; /* screen coordinates */ struct coords ibl; struct coords itr; struct coords ibr; double win_size; /* box size for drawindow() */ char name[MAX_NAME]; /* for filename */ int boxcount; /* bytes of saved screen info */ }; /* prototypes */ static void drawindow( int, struct window * ); static char is_visible_window ( struct window *, struct fractal_info *, struct ext_blk_5 * ); static void transform( struct dblcoords * ); static char paramsOK( struct fractal_info * ); static char typeOK( struct fractal_info *, struct ext_blk_3 * ); static char functionOK( struct fractal_info *, int ); static void check_history( char *, char * ); static void bfsetup_convert_to_screen( void ); static void bftransform( bf_t, bf_t, struct dblcoords * ); char browsename[MAX_NAME]; /* name for browse file */ U16 browsehandle; U16 boxxhandle; U16 boxyhandle; U16 boxvalueshandle; /* here because must be visible inside several routines */ static struct affine *cvt; static bf_t bt_a, bt_b, bt_c, bt_d, bt_e, bt_f; static bf_t n_a, n_b, n_c, n_d, n_e, n_f; int oldbf_math; /* fgetwindow reads all .GIF files and draws window outlines on the screen */ int fgetwindow(void) { struct affine stack_cvt; struct fractal_info read_info; struct ext_blk_2 blk_2_info; struct ext_blk_3 blk_3_info; struct ext_blk_4 blk_4_info; struct ext_blk_5 blk_5_info; struct ext_blk_6 blk_6_info; struct ext_blk_7 blk_7_info; time_t thistime,lastime; char mesg[40],newname[60],oldname[60]; int c,i,index,done,wincount,toggle,color_of_box; struct window winlist; char drive[FILE_MAX_DRIVE]; char dir[FILE_MAX_DIR]; char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char tmpmask[FILE_MAX_PATH]; int vid_too_big = 0; int no_memory = 0; U16 vidlength; BYTE *winlistptr = (BYTE *)&winlist; int saved; #ifdef XFRACT U32 blinks; #endif oldbf_math = bf_math; bf_math = BIGFLT; if (!oldbf_math) { int oldcalc_status = calc_status; /* kludge because next sets it = 0 */ fractal_floattobf(); calc_status = oldcalc_status; } saved = save_stack(); bt_a = alloc_stack(rbflength+2); bt_b = alloc_stack(rbflength+2); bt_c = alloc_stack(rbflength+2); bt_d = alloc_stack(rbflength+2); bt_e = alloc_stack(rbflength+2); bt_f = alloc_stack(rbflength+2); if ((vidlength = (U16)(sxdots + sydots)) > (U16)4096) vid_too_big = 2; /* 4096 based on 4096B in boxx... max 1/4 pixels plotted, and need words */ /* 4096 = 10240/2.5 based on size of boxx+boxy+boxvalues */ #ifdef XFRACT vidlength = 4; /* Xfractint only needs the 4 corners saved. */ #endif browsehandle = MemoryAlloc((U16)sizeof(struct window),(long)MAX_WINDOWS_OPEN,FARMEM); boxxhandle = MemoryAlloc((U16)(vidlength),(long)MAX_WINDOWS_OPEN,EXPANDED); boxyhandle = MemoryAlloc((U16)(vidlength),(long)MAX_WINDOWS_OPEN,EXPANDED); boxvalueshandle = MemoryAlloc((U16)(vidlength>>1),(long)MAX_WINDOWS_OPEN,EXPANDED); if(!browsehandle || !boxxhandle || !boxyhandle || !boxvalueshandle) no_memory = 1; /* set up complex-plane-to-screen transformation */ if (oldbf_math) { bfsetup_convert_to_screen(); } else { cvt = &stack_cvt; /* use stack */ setup_convert_to_screen(cvt); /* put in bf variables */ floattobf(bt_a, cvt->a); floattobf(bt_b, cvt->b); floattobf(bt_c, cvt->c); floattobf(bt_d, cvt->d); floattobf(bt_e, cvt->e); floattobf(bt_f, cvt->f); } find_special_colors(); color_of_box = color_medium; rescan: /* entry for changed browse parms */ time(&lastime); toggle = 0; wincount = 0; no_sub_images = FALSE; splitpath(readname,drive,dir,NULL,NULL); splitpath(browsemask,NULL,NULL,fname,ext); makepath(tmpmask,drive,dir,fname,ext); done=(vid_too_big==2) || no_memory || fr_findfirst(tmpmask); /* draw all visible windows */ while (!done) { if(keypressed()) { getakey(); break; } splitpath(DTA.filename,NULL,NULL,fname,ext); makepath(tmpmask,drive,dir,fname,ext); if( !find_fractal_info(tmpmask,&read_info,&blk_2_info,&blk_3_info, &blk_4_info,&blk_5_info,&blk_6_info, &blk_7_info) && (typeOK(&read_info,&blk_3_info) || !brwschecktype) && (paramsOK(&read_info) || !brwscheckparms) && stricmp(browsename,DTA.filename) && blk_6_info.got_data != 1 && is_visible_window(&winlist,&read_info,&blk_5_info) ) { far_strcpy(winlist.name,DTA.filename); drawindow(color_of_box,&winlist); boxcount <<= 1; /*boxcount*2;*/ /* double for byte count */ winlist.boxcount = boxcount; MoveToMemory(winlistptr,(U16)sizeof(struct window),1L,(long)wincount,browsehandle); MoveToMemory((BYTE *)boxx,vidlength,1L,(long)wincount,boxxhandle); MoveToMemory((BYTE *)boxy,vidlength,1L,(long)wincount,boxyhandle); MoveToMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)wincount,boxvalueshandle); wincount++; } if(blk_2_info.got_data == 1) /* Clean up any far memory allocated */ MemoryRelease((U16)blk_2_info.resume_data); if(blk_4_info.got_data == 1) /* Clean up any far memory allocated */ farmemfree(blk_4_info.range_data); if(blk_5_info.got_data == 1) /* Clean up any far memory allocated */ farmemfree(blk_5_info.apm_data); done=(fr_findnext() || wincount >= MAX_WINDOWS_OPEN); } if (no_memory) { static FCODE msg[] = {"Sorry...not enough memory to browse."}; texttempmsg(msg);/* doesn't work if NO far memory available, go figure */ } if (wincount >= MAX_WINDOWS_OPEN) { /* hard code message at MAX_WINDOWS_OPEN = 450 */ static FCODE msg[] = {"Sorry...no more space, 450 displayed."}; texttempmsg(msg); } if (vid_too_big==2) { static FCODE msg[] = {"Xdots + Ydots > 4096."}; texttempmsg(msg); } c=0; if (wincount) { buzzer(0); /*let user know we've finished */ index=0;done = 0; MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle); MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle); MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle); showtempmsg(winlist.name); while ( !done) /* on exit done = 1 for quick exit, done = 2 for erase boxes and exit done = 3 for rescan done = 4 for set boxes and exit to save image */ { #ifdef XFRACT blinks = 1; #endif while (!keypressed()) { time(&thistime); if (difftime(thistime,lastime) > .2 ) { lastime=thistime; toggle = 1- toggle; } if (toggle) drawindow(color_bright,&winlist); /* flash current window */ else drawindow(color_dark,&winlist); #ifdef XFRACT blinks++; #endif } #ifdef XFRACT if ((blinks & 1) == 1) /* Need an odd # of blinks, so next one leaves box turned off */ drawindow(color_bright,&winlist); #endif c=getakey(); switch (c) { case RIGHT_ARROW: case LEFT_ARROW: case DOWN_ARROW: case UP_ARROW: cleartempmsg(); drawindow(color_of_box,&winlist);/* dim last window */ if (c==RIGHT_ARROW || c== UP_ARROW) { index++; /* shift attention to next window */ if (index >= wincount) index=0; } else { index -- ; if ( index < 0 ) index = wincount -1 ; } MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle); MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle); MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle); showtempmsg(winlist.name); break; #ifndef XFRACT case CTL_INSERT: color_of_box += key_count(CTL_INSERT); for (i=0 ; i < wincount ; i++) { MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)i,browsehandle); drawindow(color_of_box,&winlist); } MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); drawindow(color_of_box,&winlist); break; case CTL_DEL: color_of_box -= key_count(CTL_DEL); for (i=0 ; i < wincount ; i++) { MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)i,browsehandle); drawindow(color_of_box,&winlist); } MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); drawindow(color_of_box,&winlist); break; #endif case ENTER: case ENTER_2: /* this file please */ far_strcpy(browsename,winlist.name); done = 1; break; case ESC: case 'l': case 'L': #ifdef XFRACT /* Need all boxes turned on, turn last one back on. */ drawindow(color_bright,&winlist); #endif autobrowse = FALSE; done = 2; break; case 'D': /* delete file */ cleartempmsg(); strcpy(mesg,""); strcat(mesg,"Delete "); far_strcat(mesg,winlist.name); strcat(mesg,"? (Y/N)"); showtempmsg(mesg); while (!keypressed()) ; cleartempmsg(); c = getakey(); if ( c == 'Y' && doublecaution ) { static FCODE msg[] = {"ARE YOU SURE???? (Y/N)"}; texttempmsg(msg); if ( getakey() != 'Y') c = 'N'; } if ( c == 'Y' ) { splitpath(readname,drive,dir,NULL,NULL); splitpath(winlist.name,NULL,NULL,fname,ext); makepath(tmpmask,drive,dir,fname,ext); if ( !unlink(tmpmask)) { /* do a rescan */ done = 3; far_strcpy(oldname,winlist.name); tmpmask[0] = '\0'; check_history(oldname,tmpmask); break; } else if( errno == EACCES ) { static FCODE msg[] = {"Sorry...it's a read only file, can't del"}; texttempmsg(msg); showtempmsg(winlist.name); break; } } { static FCODE msg[] = {"file not deleted (phew!)"}; texttempmsg(msg); } showtempmsg(winlist.name); break; case 'R': cleartempmsg(); stackscreen(); newname[0] = 0; strcpy(mesg,""); { static FCODE msg[] = {"Enter the new filename for "}; far_strcat((char far *)mesg,msg); } splitpath(readname,drive,dir,NULL,NULL); splitpath(winlist.name,NULL,NULL,fname,ext); makepath(tmpmask,drive,dir,fname,ext); strcpy(newname,tmpmask); strcat(mesg,tmpmask); i = field_prompt(0,mesg,NULL,newname,60,NULL); unstackscreen(); if( i != -1) if (!rename(tmpmask,newname)) { if (errno == EACCES) { static FCODE msg[] = {"sorry....can't rename"}; texttempmsg(msg); } else { splitpath(newname,NULL,NULL,fname,ext); makepath(tmpmask,NULL,NULL,fname,ext); far_strcpy(oldname,winlist.name); check_history(oldname,tmpmask); far_strcpy(winlist.name,tmpmask); } } MoveToMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); showtempmsg(winlist.name); break; case 2: /* ctrl B */ cleartempmsg(); stackscreen(); done = abs(get_browse_params()); unstackscreen(); showtempmsg(winlist.name); break; case 's': /* save image with boxes */ autobrowse = FALSE; drawindow(color_of_box,&winlist); /* current window white */ done = 4; break; case '\\': /*back out to last image */ done = 2; break; default: break; } /*switch */ } /*while*/ /* now clean up memory (and the screen if necessary) */ cleartempmsg(); if (done >= 1 && done < 4) { for (index=wincount-1;index>=0;index--){ /* don't need index, reuse it */ MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); boxcount = winlist.boxcount; MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle); MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle); MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle); boxcount >>= 1; if (boxcount > 0 ) #ifdef XFRACT /* Turn all boxes off */ drawindow(color_bright,&winlist); #else clearbox(); #endif } } if (done == 3) { goto rescan; /* hey everybody I just used the g word! */ } }/*if*/ else { static FCODE msg[] = {"sorry.. I can't find anything"}; buzzer(1); /*no suitable files in directory! */ texttempmsg(msg); no_sub_images = TRUE; } MemoryRelease(browsehandle); MemoryRelease(boxxhandle); MemoryRelease(boxyhandle); MemoryRelease(boxvalueshandle); restore_stack(saved); if (!oldbf_math) free_bf_vars(); bf_math = oldbf_math; floatflag = usr_floatflag; return(c); } static void drawindow(int colour,struct window *info) { #ifndef XFRACT int cross_size; struct coords ibl,itr; #endif boxcolor=colour; boxcount = 0; if (info->win_size >= minbox) { /* big enough on screen to show up as a box so draw it */ /* corner pixels */ #ifndef XFRACT addbox(info->itl); addbox(info->itr); addbox(info->ibl); addbox(info->ibr); drawlines(info->itl,info->itr,info->ibl.x-info->itl.x,info->ibl.y-info->itl.y); /* top & bottom lines */ drawlines(info->itl,info->ibl,info->itr.x-info->itl.x,info->itr.y-info->itl.y); /* left & right lines */ #else boxx[0] = info->itl.x + sxoffs; boxy[0] = info->itl.y + syoffs; boxx[1] = info->itr.x + sxoffs; boxy[1] = info->itr.y + syoffs; boxx[2] = info->ibr.x + sxoffs; boxy[2] = info->ibr.y + syoffs; boxx[3] = info->ibl.x + sxoffs; boxy[3] = info->ibl.y + syoffs; boxcount = 4; #endif dispbox(); } else { /* draw crosshairs */ #ifndef XFRACT cross_size = ydots / 45; if (cross_size < 2) cross_size = 2; itr.x = info->itl.x - cross_size; itr.y = info->itl.y; ibl.y = info->itl.y - cross_size; ibl.x = info->itl.x; drawlines(info->itl,itr,ibl.x-itr.x,0); /* top & bottom lines */ drawlines(info->itl,ibl,0,itr.y-ibl.y); /* left & right lines */ dispbox(); #endif } } /* maps points onto view screen*/ static void transform(struct dblcoords *point) { double tmp_pt_x; tmp_pt_x = cvt->a * point->x + cvt->b * point->y + cvt->e; point->y = cvt->c * point->x + cvt->d * point->y + cvt->f; point->x = tmp_pt_x; } static char is_visible_window ( struct window *list, struct fractal_info *info, struct ext_blk_5 *blk_5_info ) { struct dblcoords tl,tr,bl,br; bf_t bt_x, bt_y; bf_t bt_xmin, bt_xmax, bt_ymin, bt_ymax, bt_x3rd, bt_y3rd; int saved; int two_len; int cornercount, cant_see; int orig_bflength, orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor, orig_rbflength; double toobig, tmp_sqrt; toobig = sqrt(sqr((double)sxdots)+sqr((double)sydots)) * 1.5; /* arbitrary value... stops browser zooming out too far */ cornercount=0; cant_see = 0; saved = save_stack(); /* Save original values. */ orig_bflength = bflength; orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_rbflength = rbflength; /* if (oldbf_math && info->bf_math && (bnlength+4 < info->bflength)) { bnlength = info->bflength; calc_lengths(); } */ two_len = bflength + 2; bt_x = alloc_stack(two_len); bt_y = alloc_stack(two_len); bt_xmin = alloc_stack(two_len); bt_xmax = alloc_stack(two_len); bt_ymin = alloc_stack(two_len); bt_ymax = alloc_stack(two_len); bt_x3rd = alloc_stack(two_len); bt_y3rd = alloc_stack(two_len); if (info->bf_math) { bf_t bt_t1, bt_t2, bt_t3, bt_t4, bt_t5, bt_t6; int di_bflength, two_di_len, two_rbf; di_bflength = info->bflength + bnstep; two_di_len = di_bflength + 2; two_rbf = rbflength + 2; n_a = alloc_stack(two_rbf); n_b = alloc_stack(two_rbf); n_c = alloc_stack(two_rbf); n_d = alloc_stack(two_rbf); n_e = alloc_stack(two_rbf); n_f = alloc_stack(two_rbf); convert_bf(n_a, bt_a, rbflength, orig_rbflength); convert_bf(n_b, bt_b, rbflength, orig_rbflength); convert_bf(n_c, bt_c, rbflength, orig_rbflength); convert_bf(n_d, bt_d, rbflength, orig_rbflength); convert_bf(n_e, bt_e, rbflength, orig_rbflength); convert_bf(n_f, bt_f, rbflength, orig_rbflength); bt_t1 = alloc_stack(two_di_len); bt_t2 = alloc_stack(two_di_len); bt_t3 = alloc_stack(two_di_len); bt_t4 = alloc_stack(two_di_len); bt_t5 = alloc_stack(two_di_len); bt_t6 = alloc_stack(two_di_len); far_memcpy((char far *)bt_t1,blk_5_info->apm_data,(two_di_len)); far_memcpy((char far *)bt_t2,blk_5_info->apm_data+two_di_len,(two_di_len)); far_memcpy((char far *)bt_t3,blk_5_info->apm_data+2*two_di_len,(two_di_len)); far_memcpy((char far *)bt_t4,blk_5_info->apm_data+3*two_di_len,(two_di_len)); far_memcpy((char far *)bt_t5,blk_5_info->apm_data+4*two_di_len,(two_di_len)); far_memcpy((char far *)bt_t6,blk_5_info->apm_data+5*two_di_len,(two_di_len)); convert_bf(bt_xmin, bt_t1, two_len, two_di_len); convert_bf(bt_xmax, bt_t2, two_len, two_di_len); convert_bf(bt_ymin, bt_t3, two_len, two_di_len); convert_bf(bt_ymax, bt_t4, two_len, two_di_len); convert_bf(bt_x3rd, bt_t5, two_len, two_di_len); convert_bf(bt_y3rd, bt_t6, two_len, two_di_len); } /* tranform maps real plane co-ords onto the current screen view see above */ if (oldbf_math || info->bf_math) { if (!info->bf_math) { floattobf(bt_x, info->xmin); floattobf(bt_y, info->ymax); } else { copy_bf(bt_x, bt_xmin); copy_bf(bt_y, bt_ymax); } bftransform(bt_x, bt_y, &tl); } else { tl.x=info->xmin; tl.y=info->ymax; transform(&tl); } list->itl.x=(int)(tl.x + 0.5); list->itl.y=(int)(tl.y + 0.5); if (oldbf_math || info->bf_math) { if (!info->bf_math) { floattobf(bt_x, (info->xmax)-(info->x3rd-info->xmin)); floattobf(bt_y, (info->ymax)+(info->ymin-info->y3rd)); } else { neg_a_bf(sub_bf(bt_x, bt_x3rd, bt_xmin)); add_a_bf(bt_x, bt_xmax); sub_bf(bt_y, bt_ymin, bt_y3rd); add_a_bf(bt_y, bt_ymax); } bftransform(bt_x, bt_y, &tr); } else { tr.x=(info->xmax)-(info->x3rd-info->xmin); tr.y=(info->ymax)+(info->ymin-info->y3rd); transform(&tr); } list->itr.x=(int)(tr.x + 0.5); list->itr.y=(int)(tr.y + 0.5); if (oldbf_math || info->bf_math) { if (!info->bf_math) { floattobf(bt_x, info->x3rd); floattobf(bt_y, info->y3rd); } else { copy_bf(bt_x, bt_x3rd); copy_bf(bt_y, bt_y3rd); } bftransform(bt_x, bt_y, &bl); } else { bl.x=info->x3rd; bl.y=info->y3rd; transform(&bl); } list->ibl.x=(int)(bl.x + 0.5); list->ibl.y=(int)(bl.y + 0.5); if (oldbf_math || info->bf_math) { if (!info->bf_math) { floattobf(bt_x, info->xmax); floattobf(bt_y, info->ymin); } else { copy_bf(bt_x, bt_xmax); copy_bf(bt_y, bt_ymin); } bftransform(bt_x, bt_y, &br); } else { br.x=info->xmax; br.y=info->ymin; transform(&br); } list->ibr.x=(int)(br.x + 0.5); list->ibr.y=(int)(br.y + 0.5); tmp_sqrt = sqrt(sqr(tr.x-bl.x) + sqr(tr.y-bl.y)); list->win_size = tmp_sqrt; /* used for box vs crosshair in drawindow() */ if (tmp_sqrt < toosmall ) cant_see = 1; /* reject anything too small onscreen */ if (tmp_sqrt > toobig ) cant_see = 1; /* or too big... */ /* restore original values */ bflength = orig_bflength; bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; rbflength = orig_rbflength; restore_stack(saved); if (cant_see) /* do it this way so bignum stack is released */ return(FALSE); /* now see how many corners are on the screen, accept if one or more */ if ( tl.x >=(0-sxoffs) && tl.x <= (sxdots-sxoffs) && tl.y >=(0-syoffs) && tl.y<= (sydots-syoffs) ) cornercount ++; if ( bl.x >=(0-sxoffs) && bl.x <= (sxdots-sxoffs) && bl.y >=(0-syoffs) && bl.y<= (sydots-syoffs) ) cornercount ++; if ( tr.x >=(0-sxoffs) && tr.x <= (sxdots-sxoffs) && tr.y >=(0-syoffs) && tr.y<= (sydots-syoffs) ) cornercount ++; if ( br.x >=(0-sxoffs) && br.x <= (sxdots-sxoffs) && br.y >=(0-syoffs) && br.y<= (sydots-syoffs) ) cornercount ++; if (cornercount >=1 ) return( TRUE ); else return( FALSE ); } static char paramsOK( struct fractal_info *info ) { double tmpparm3, tmpparm4; double tmpparm5, tmpparm6; double tmpparm7, tmpparm8; double tmpparm9, tmpparm10; #define MINDIF 0.001 if( info->version > 6) { tmpparm3 = info->dparm3; tmpparm4 = info->dparm4; } else{ tmpparm3 = info->parm3; roundfloatd(&tmpparm3); tmpparm4 = info->parm4; roundfloatd(&tmpparm4); } if( info->version > 8) { tmpparm5 = info->dparm5; tmpparm6 = info->dparm6; tmpparm7 = info->dparm7; tmpparm8 = info->dparm8; tmpparm9 = info->dparm9; tmpparm10 = info->dparm10; } else{ tmpparm5 = 0.0; tmpparm6 = 0.0; tmpparm7 = 0.0; tmpparm8 = 0.0; tmpparm9 = 0.0; tmpparm10 = 0.0; } if( fabs(info->creal - param[0]) < MINDIF && fabs(info->cimag - param[1]) < MINDIF && fabs(tmpparm3 - param[2]) < MINDIF && fabs(tmpparm4 - param[3]) < MINDIF && fabs(tmpparm5 - param[4]) < MINDIF && fabs(tmpparm6 - param[5]) < MINDIF && fabs(tmpparm7 - param[6]) < MINDIF && fabs(tmpparm8 - param[7]) < MINDIF && fabs(tmpparm9 - param[8]) < MINDIF && fabs(tmpparm10 - param[9]) < MINDIF && info->invert[0] - inversion[0] < MINDIF) return(1); /* parameters are in range */ else return(0); } static char functionOK( struct fractal_info *info, int numfn) { int i, mzmatch; mzmatch = 0; for(i=0; itrigndx[i] != trigndx[i] ) mzmatch++; } if(mzmatch > 0) return(0); else return(1); /* they all match */ } static char typeOK( struct fractal_info *info, struct ext_blk_3 *blk_3_info ) { int numfn; if( (fractype == FORMULA || fractype == FFORMULA) && (info->fractal_type == FORMULA || info->fractal_type == FFORMULA) ) { if( !stricmp(blk_3_info->form_name,FormName) ) { numfn = maxfn; if (numfn>0) return(functionOK(info, numfn)); else return(1); /* match up formula names with no functions */ } else return(0); /* two formulas but names don't match */ } else if(info->fractal_type == fractype || info->fractal_type == curfractalspecific->tofloat) { numfn = (curfractalspecific->flags >> 6) & 7; if (numfn>0) return(functionOK(info, numfn)); else return(1); /* match types with no functions */ } else return(0); /* no match */ } static void check_history ( char *oldname, char *newname ) { int i; /* file_name_stack[] is maintained in framain2.c. It is the history */ /* file for the browser and holds a maximum of 16 images. The history */ /* file needs to be adjusted if the rename or delete functions of the */ /* browser are used. */ /* name_stack_ptr is also maintained in framain2.c. It is the index into */ /* file_name_stack[]. */ for (i=0;ix = cvt->a * point->x + cvt->b * point->y + cvt->e; */ mult_bf(bt_tmp1, n_a, bt_x); mult_bf(bt_tmp2, n_b, bt_y); add_a_bf(bt_tmp1, bt_tmp2); add_a_bf(bt_tmp1, n_e); point->x = (double)bftofloat(bt_tmp1); /* point->y = cvt->c * point->x + cvt->d * point->y + cvt->f; */ mult_bf(bt_tmp1, n_c, bt_x); mult_bf(bt_tmp2, n_d, bt_y); add_a_bf(bt_tmp1, bt_tmp2); add_a_bf(bt_tmp1, n_f); point->y = (double)bftofloat(bt_tmp1); restore_stack(saved); } xfractint-20.4.10.orig/common/cmdfiles.c0000644000000000000000000033217311257714555014754 0ustar /* Command-line / Command-File Parser Routines */ #include #include #include #include #ifndef XFRACT #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /*#ifdef __TURBOC__ #include #endif */ #ifdef XFRACT #define DEFAULT_PRINTER 5 /* Assume a Postscript printer */ #define PRT_RESOLUTION 100 /* Assume medium resolution */ #define INIT_GIF87 0 /* Turn on GIF 89a processing */ #else #define DEFAULT_PRINTER 2 /* Assume an IBM/Epson printer */ #define PRT_RESOLUTION 60 /* Assume low resolution */ #define INIT_GIF87 0 /* Turn on GIF 89a processing */ #endif #define far_strncmp far_strnicmp static int cmdfile(FILE *,int); static int next_command(char *,int,FILE *,char *,int *,int); static int next_line(FILE *,char *,int); int cmdarg(char *,int); static void argerror(char *); static void initvars_run(void); static void initvars_restart(void); static void initvars_fractal(void); static void initvars_3d(void); static void reset_ifs_defn(void); static void parse_textcolors(char *value); static int parse_colors(char *value); static int parse_printer(char *value); static int get_bf(bf_t, char *); static int isabigfloat(char *str); /* variables defined by the command line/files processor */ int stoppass=0; /* stop at this guessing pass early */ int pseudox=0; /* xdots to use for video independence */ int pseudoy=0; /* ydots to use for video independence */ int bfdigits=0; /* digits to use (force) for bf_math */ int showdot=-1; /* color to show crawling graphics cursor */ int sizedot; /* size of dot crawling cursor */ char recordcolors; /* default PAR color-writing method */ char autoshowdot=0; /* dark, medium, bright */ char start_showorbit=0; /* show orbits on at start of fractal */ char temp1[256]; /* temporary strings */ char readname[FILE_MAX_PATH];/* name of fractal input file */ char tempdir[FILE_MAX_DIR] = {""}; /* name of temporary directory */ char workdir[FILE_MAX_DIR] = {""}; /* name of directory for misc files */ char orgfrmdir[FILE_MAX_DIR] = {""};/*name of directory for orgfrm files*/ char gifmask[MAX_NAME] = {""}; char PrintName[FILE_MAX_PATH]={"fract001.ps"}; /* Name for print-to-file */ char savename[FILE_MAX_PATH]={"fract001"}; /* save files using this name */ char autoname[FILE_MAX_PATH]={"auto.key"}; /* record auto keystrokes here */ int potflag=0; /* continuous potential enabled? */ int pot16bit; /* store 16 bit continuous potential values */ int gif87a_flag; /* 1 if GIF87a format, 0 otherwise */ int dither_flag; /* 1 if want to dither GIFs */ int askvideo; /* flag for video prompting */ char floatflag; int biomorph; /* flag for biomorph */ int usr_biomorph; int forcesymmetry; /* force symmetry */ int showfile; /* zero if file display pending */ int rflag, rseed; /* Random number seeding flag and value */ int decomp[2]; /* Decomposition coloring */ long distest; int distestwidth; char overwrite = 0; /* 0 if file overwrite not allowed */ int soundflag; /* sound control bitfield... see sound.c for useage*/ int basehertz; /* sound=x/y/x hertz value */ int debugflag; /* internal use only - you didn't see this */ int timerflag; /* you didn't see this, either */ int cyclelimit; /* color-rotator upper limit */ int inside; /* inside color: 1=blue */ int fillcolor; /* fillcolor: -1=normal */ int outside; /* outside color */ int finattract; /* finite attractor logic */ int display3d; /* 3D display flag: 0 = OFF */ int overlay3d; /* 3D overlay flag: 0 = OFF */ int init3d[20]; /* '3d=nn/nn/nn/...' values */ int checkcurdir; /* flag to check current dir for files */ int initbatch; /* 1 if batch run (no kbd) */ int initsavetime; /* autosave minutes */ _CMPLX initorbit; /* initial orbitvalue */ char useinitorbit; /* flag for initorbit */ int initmode; /* initial video mode */ int initcyclelimit; /* initial cycle limit */ BYTE usemag; /* use center-mag corners */ long bailout; /* user input bailout value */ enum bailouts bailoutest; /* test used for determining bailout */ double inversion[3]; /* radius, xcenter, ycenter */ int rotate_lo,rotate_hi; /* cycling color range */ int far *ranges; /* iter->color ranges mapping */ int rangeslen = 0; /* size of ranges array */ BYTE far *mapdacbox = NULL; /* map= (default colors) */ int colorstate; /* 0, dacbox matches default (bios or map=) */ /* 1, dacbox matches no known defined map */ /* 2, dacbox matches the colorfile map */ /* 3, dacbox rotation of the colorfile map */ int colorpreloaded; /* if dacbox preloaded for next mode select */ int save_release; /* release creating PAR file*/ char dontreadcolor=0; /* flag for reading color from GIF */ double math_tol[2]={.05,.05}; /* For math transition */ int Targa_Out = 0; /* 3D fullcolor flag */ int truecolor = 0; /* escape time truecolor flag */ int truemode = 0; /* truecolor coloring scheme */ char colorfile[FILE_MAX_PATH];/* from last or colors=@filename */ int functionpreloaded; /* if function loaded for new bifs, JCO 7/5/92 */ float screenaspect = DEFAULTASPECT; /* aspect ratio of the screen */ float aspectdrift = DEFAULTASPECTDRIFT; /* how much drift is allowed and */ /* still forced to screenaspect */ int fastrestore = 0; /* 1 - reset viewwindows prior to a restore and do not display warnings when video mode changes during restore */ int orgfrmsearch = 0; /* 1 - user has specified a directory for Orgform formula compilation files */ /* TARGA+ variables */ int TPlusFlag; /* Use the TARGA+ if found */ int MaxColorRes; /* Default Color Resolution if available */ int PixelZoom; /* TPlus Zoom Level */ int NonInterlaced; /* Non-Interlaced video flag */ int orbitsave = 0; /* for IFS and LORENZ to output acrospin file */ int orbit_delay; /* clock ticks delating orbit release */ int transparent[2]; /* transparency min/max values */ long LogFlag; /* Logarithmic palette flag: 0 = no */ BYTE exitmode = 3; /* video mode on exit */ char ai_8514; /* Flag for using 8514a afi JCO 4/11/92 */ int Log_Fly_Calc = 0; /* calculate logmap on-the-fly */ int Log_Auto_Calc = 0; /* auto calculate logmap */ int nobof = 0; /* Flag to make inside=bof options not duplicate bof images */ int bios_palette; /* set to 1 to force BIOS palette updates */ int escape_exit; /* set to 1 to avoid the "are you sure?" screen */ int first_init=1; /* first time into cmdfiles? */ static int init_rseed; static char initcorners,initparams; struct fractalspecificstuff far *curfractalspecific; char FormFileName[FILE_MAX_PATH];/* file to find (type=)formulas in */ char FormName[ITEMNAMELEN+1]; /* Name of the Formula (if not null) */ char LFileName[FILE_MAX_PATH]; /* file to find (type=)L-System's in */ char LName[ITEMNAMELEN+1]; /* Name of L-System */ char CommandFile[FILE_MAX_PATH]; /* file to find command sets in */ char CommandName[ITEMNAMELEN+1]; /* Name of Command set */ char CommandComment[4][MAXCMT]; /* comments for command set */ char IFSFileName[FILE_MAX_PATH];/* file to find (type=)IFS in */ char IFSName[ITEMNAMELEN+1]; /* Name of the IFS def'n (if not null) */ struct SearchPath searchfor; float far *ifs_defn = NULL; /* ifs parameters */ int ifs_type; /* 0=2d, 1=3d */ int slides = 0; /* 1 autokey=play, 2 autokey=record */ BYTE txtcolor[]={ BLUE*16+L_WHITE, /* C_TITLE title background */ BLUE*16+L_GREEN, /* C_TITLE_DEV development vsn foreground */ GREEN*16+YELLOW, /* C_HELP_HDG help page title line */ WHITE*16+BLACK, /* C_HELP_BODY help page body */ GREEN*16+GRAY, /* C_HELP_INSTR help page instr at bottom */ WHITE*16+BLUE, /* C_HELP_LINK help page links */ CYAN*16+BLUE, /* C_HELP_CURLINK help page current link */ WHITE*16+GRAY, /* C_PROMPT_BKGRD prompt/choice background */ WHITE*16+BLACK, /* C_PROMPT_TEXT prompt/choice extra info */ BLUE*16+WHITE, /* C_PROMPT_LO prompt/choice text */ BLUE*16+L_WHITE, /* C_PROMPT_MED prompt/choice hdg2/... */ BLUE*16+YELLOW, /* C_PROMPT_HI prompt/choice hdg/cur/... */ GREEN*16+L_WHITE, /* C_PROMPT_INPUT fullscreen_prompt input */ CYAN*16+L_WHITE, /* C_PROMPT_CHOOSE fullscreen_prompt choice */ MAGENTA*16+L_WHITE, /* C_CHOICE_CURRENT fullscreen_choice input */ BLACK*16+WHITE, /* C_CHOICE_SP_INSTR speed key bar & instr */ BLACK*16+L_MAGENTA, /* C_CHOICE_SP_KEYIN speed key value */ WHITE*16+BLUE, /* C_GENERAL_HI tab, thinking, IFS */ WHITE*16+BLACK, /* C_GENERAL_MED */ WHITE*16+GRAY, /* C_GENERAL_LO */ BLACK*16+L_WHITE, /* C_GENERAL_INPUT */ WHITE*16+BLACK, /* C_DVID_BKGRD disk video */ BLACK*16+YELLOW, /* C_DVID_HI */ BLACK*16+L_WHITE, /* C_DVID_LO */ RED*16+L_WHITE, /* C_STOP_ERR stop message, error */ GREEN*16+BLACK, /* C_STOP_INFO stop message, info */ BLUE*16+WHITE, /* C_TITLE_LOW bottom lines of title screen */ GREEN*16+BLACK, /* C_AUTHDIV1 title screen dividers */ GREEN*16+GRAY, /* C_AUTHDIV2 title screen dividers */ BLACK*16+L_WHITE, /* C_PRIMARY primary authors */ BLACK*16+WHITE /* C_CONTRIB contributing authors */ }; /* start of string literals cleanup */ char s_atan[] = "atan"; char s_iter[] = "iter"; char s_real[] = "real"; char s_mult[] = "mult"; char s_sum[] = "summ"; char s_imag[] = "imag"; char s_zmag[] = "zmag"; char s_bof60[] = "bof60"; char s_bof61[] = "bof61"; char s_maxiter[] = "maxiter"; char s_epscross[] = "epsiloncross"; char s_startrail[] = "startrail"; char s_normal[] = "normal"; char s_period[] = "period"; char s_fmod[] = "fmod"; char s_tdis[] = "tdis"; char s_or[] = "or"; char s_and[] = "and"; char s_mod[] = "mod"; char s_16bit[] = "16bit"; char s_387[] = "387"; char s_3d[] = "3d"; char s_3dmode[] = "3dmode"; char s_adapter[] = "adapter"; char s_afi[] = "afi"; char s_ambient[] = "ambient"; char s_askvideo[] = "askvideo"; char s_aspectdrift[] = "aspectdrift"; char s_attack[] = "attack"; char s_atten[] = "attenuate"; char s_autokey[] = "autokey"; char s_autokeyname[] = "autokeyname"; char s_background[] = "background"; char s_bailout[] = "bailout"; char s_bailoutest[] = "bailoutest"; char s_batch[] = "batch"; char s_beep[] = "beep"; char s_biomorph[] = "biomorph"; char s_biospalette[] = "biospalette"; char s_brief[] = "brief"; char s_bright[] = "bright"; char s_centermag[] = "center-mag"; char s_cga[] = "cga"; char s_coarse[] = "coarse"; char s_colorps[] = "colorps"; char s_colors[] = "colors"; char s_comment[] = "comment"; char s_comport[] = "comport"; char s_converge[] = "converge"; char s_corners[] = "corners"; char s_cr[] = "cr"; char s_crlf[] = "crlf"; char s_crop[] = "crop"; char s_cyclelimit[] = "cyclelimit"; char s_cyclerange[] = "cyclerange"; char s_curdir[] = "curdir"; char s_debug[] = "debug"; char s_debugflag[] = "debugflag"; char s_decay[] = "decay"; char s_decomp[] = "decomp"; char s_distest[] = "distest"; char s_dither[] = "dither"; char s_ega[] = "ega"; char s_egamono[] = "egamono"; char s_epsf[] = "epsf"; char s_exitmode[] = "exitmode"; char s_exitnoask[] = "exitnoask"; char s_fastrestore[] = "fastrestore"; char s_filename[] = "filename"; char s_fillcolor[] = "fillcolor"; char s_filltype[] = "filltype"; char s_finattract[] = "finattract"; char s_float[] = "float"; char s_formulafile[] = "formulafile"; char s_formulaname[] = "formulaname"; char s_fpu[] = "fpu"; char s_fract001ps[] = "fract001.ps"; char s_fullcolor[] = "fullcolor"; char s_function[] = "function"; char s_gif87a[] = "gif87a"; char s_halftone[] = "halftone"; char s_haze[] = "haze"; char s_hertz[] = "hertz"; char s_hgc[] = "hgc"; char s_high[] = "high"; char s_ifs[] = "ifs"; char s_ifs3d[] = "ifs3d"; char s_ifsfile[] = "ifsfile"; char s_initorbit[] = "initorbit"; char s_inside[] = "inside"; char s_interocular[] = "interocular"; char s_invert[] = "invert"; char s_iterincr[] = "iterincr"; char s_julibrot3d[] = "julibrot3d"; char s_julibroteyes[] = "julibroteyes"; char s_julibrotfromto[] = "julibrotfromto"; char s_latitude[] = "latitude"; char s_lf[] = "lf"; char s_lfile[] = "lfile"; char s_lightname[] = "lightname"; char s_lightsource[] = "lightsource"; char s_linefeed[] = "linefeed"; char s_lname[] = "lname"; char s_logmap[] = "logmap"; char s_logmode[] = "logmode"; char s_longitude[] = "longitude"; char s_low[] = "low"; char s_makedoc[] = "makedoc"; char s_makemig[] = "makemig"; char s_makepar[] = "makepar"; char s_manh[] = "manh"; char s_manr[] = "manr"; char s_map[] = "map"; char s_maxcolorres[] = "maxcolorres"; char s_mcga[] = "mcga"; char s_mid[] = "mid"; char s_miim[] = "miim"; char s_nobof[] = "nobof"; char s_mono[] = "mono"; char s_none[] = "none"; char s_noninterlaced[] = "noninterlaced"; char s_off[] = "off"; char s_olddemmcolors[] = "olddemmcolors"; char s_orbitcorners[] = "orbitcorners"; char s_orbitdelay[] = "orbitdelay"; char s_orbitdrawmode[] = "orbitdrawmode"; char s_orbitinterval[] = "orbitinterval"; char s_orbitname[] = "orbitname"; char s_orbitsave[] = "orbitsave"; char s_orgfrmdir[] = "orgfrmdir"; char s_origin[] = "origin"; char s_outside[] = "outside"; char s_overlay[] = "overlay"; char s_overwrite[] = "overwrite"; char s_params[] = "params"; char s_parmfile[] = "parmfile"; char s_passes[] = "passes"; char s_periodicity[] = "periodicity"; char s_perspective[] = "perspective"; char s_pi[] = "pi"; char s_pixel[] = "pixel"; char s_pixelzoom[] = "pixelzoom"; char s_play[] = "play"; char s_plotstyle[] = "plotstyle"; char s_polyphony[] = "polyphony"; char s_potential[] = "potential"; char s_preview[] = "preview"; char s_printer[] = "printer"; char s_printfile[] = "printfile"; char s_prox[] = "proximity"; char s_radius[] = "radius"; char s_ramvideo[] = "ramvideo"; char s_randomize[] = "randomize"; char s_ranges[] = "ranges"; char s_ray[] = "ray"; char s_record[] = "record"; char s_release[] = "release"; char s_srelease[] = "srelease"; char s_reset[] = "reset"; char s_rleps[] = "rleps"; char s_rotation[] = "rotation"; char s_roughness[] = "roughness"; char s_rseed[] = "rseed"; char s_savename[] = "savename"; char s_savetime[] = "savetime"; char s_scalemap[] = "scalemap"; char s_scalexyz[] = "scalexyz"; char s_screencoords[] = "screencoords"; char s_showbox[] = "showbox"; char s_showdot[] = "showdot"; char s_showorbit[] = "showorbit"; char s_smoothing[] = "smoothing"; char s_sound[] = "sound"; char s_sphere[] = "sphere"; char s_stereo[] = "stereo"; char s_sustain[] = "sustain"; char s_symmetry[] = "symmetry"; char s_truecolor[] = "truecolor"; char s_truemode[] = "truemode"; char s_tempdir[] = "tempdir"; char s_workdir[] = "workdir"; char s_usegrayscale[] = "usegrayscale"; char s_monitorwidth[] = "monitorwidth"; char s_targa_overlay[] = "targa_overlay"; char s_textcolors[] = "textcolors"; char s_textsafe[] = "textsafe"; char s_title[] = "title"; char s_tplus[] = "tplus"; char s_translate[] = "translate"; char s_transparent[] = "transparent"; char s_type[] = "type"; char s_vesadetect[] = "vesadetect"; char s_vga[] = "vga"; char s_video[] = "video"; char s_viewwindows[] = "viewwindows"; char s_virtual[] = "virtual"; char s_volume[] = "volume"; char s_warn[] = "warn"; char s_waterline[] = "waterline"; char s_wavetype[]= "wavetype"; char s_xaxis[] = "xaxis"; char s_xyadjust[] = "xyadjust"; char s_xyaxis[] = "xyaxis"; char s_xyshift[] = "xyshift"; char s_yaxis [] = "yaxis"; char s_sin [] = "sin"; char s_sinh [] = "sinh"; char s_cos [] = "cos"; char s_cosh [] = "cosh"; char s_sqr [] = "sqr"; char s_log [] = "log"; char s_exp [] = "exp"; char s_abs [] = "abs"; char s_conj [] = "conj"; char s_fn1 [] = "fn1"; char s_fn2 [] = "fn2"; char s_fn3 [] = "fn3"; char s_fn4 [] = "fn4"; char s_flip [] = "flip"; char s_floor [] = "floor"; char s_ceil [] = "ceil"; char s_trunc [] = "trunc"; char s_round [] = "round"; char s_tan [] = "tan"; char s_tanh [] = "tanh"; char s_cotan [] = "cotan"; char s_cotanh [] = "cotanh"; char s_cosxx [] = "cosxx"; char s_srand [] = "srand"; char s_recip [] = "recip"; char s_ident [] = "ident"; char s_zero [] = "zero"; char s_one [] = "one"; char s_asin [] = "asin"; char s_asinh [] = "asinh"; char s_acos [] = "acos"; char s_acosh [] = "acosh"; char s_atanh [] = "atanh"; char s_cabs [] = "cabs"; char s_sqrt [] = "sqrt"; char s_ismand [] = "ismand"; char s_mathtolerance[] = "mathtolerance"; static FCODE s_bfdigits [] = "bfdigits"; static FCODE s_recordcolors [] = "recordcolors"; static FCODE s_maxlinelength []= "maxlinelength"; static FCODE s_minstack[] = "minstack"; static FCODE s_lzw [] = "tweaklzw"; static FCODE s_sstoolsini [] = "sstools.ini"; static FCODE s_fractintfrm [] = "fractint.frm"; static FCODE s_fractintl [] = "fractint.l"; static FCODE s_fractintpar [] = "fractint.par"; static FCODE s_fractintifs [] = "fractint.ifs"; static FCODE s_commandline [] = "command line"; static FCODE s_at_cmd [] = "PAR file"; int lzw[2]; static FCODE s_escapetoabort[] = "Press Escape to abort, any other key to continue"; char far s_pressanykeytocontinue[] = "press any key to continue"; /* cmdfiles(argc,argv) process the command-line arguments it also processes the 'sstools.ini' file and any indirect files ('fractint @myfile') */ /* This probably ought to go somewhere else, but it's used here. */ /* getpower10(x) returns the magnitude of x. This rounds */ /* a little so 9.95 rounds to 10, but we're using a binary base anyway, */ /* so there's nothing magic about changing to the next power of 10. */ int getpower10(LDBL x) { char string[11]; /* space for "+x.xe-xxxx" */ int p; #ifdef USE_LONG_DOUBLE sprintf(string,"%+.1Le", x); #else sprintf(string,"%+.1le", x); #endif p = atoi(string+5); return p; } int cmdfiles(int argc,char **argv) { int i; char curarg[141]; char tempstring[101]; char *sptr; FILE *initfile; if (first_init) initvars_run(); /* once per run initialization */ initvars_restart(); /* key initialization */ initvars_fractal(); /* image initialization */ far_strcpy(curarg,s_sstoolsini); findpath(curarg, tempstring); /* look for SSTOOLS.INI */ if (tempstring[0] != 0) /* found it! */ if ((initfile = fopen(tempstring,"r")) != NULL) cmdfile(initfile,1); /* process it */ for (i = 1; i < argc; i++) { /* cycle through args */ #ifdef XFRACT /* Let the xfract code take a look at the argument */ if (unixarg(argc,argv,&i)) continue; #endif strcpy(curarg,argv[i]); if (curarg[0] == ';') /* start of comments? */ break; if (curarg[0] != '@') { /* simple command? */ if (strchr(curarg,'=') == NULL) { /* not xxx=yyy, so check for gif */ strcpy(tempstring,curarg); if (has_ext(curarg) == NULL) strcat(tempstring,".gif"); if ((initfile = fopen(tempstring,"rb")) != NULL) { int dummy; /* to quiet compiler */ dummy = fread(tempstring,6,1,initfile); if ( tempstring[0] == 'G' && tempstring[1] == 'I' && tempstring[2] == 'F' && tempstring[3] >= '8' && tempstring[3] <= '9' && tempstring[4] >= '0' && tempstring[4] <= '9') { strcpy(readname,curarg); extract_filename(browsename,readname); curarg[0] = (char)(showfile = 0); } fclose(initfile); } } if (curarg[0]) cmdarg(curarg,0); /* process simple command */ } else if ((sptr = strrchr(curarg,'/')) != NULL) { /* @filename/setname? */ *sptr = 0; strcpy(CommandName,sptr+1); /* merge_pathnames modifies curarg, so get CommandName first */ if(merge_pathnames(CommandFile, &curarg[1], 3) < 0) init_msg(0,"",CommandFile,3); if(find_file_item(CommandFile,CommandName,&initfile, 0)<0 || initfile==NULL) argerror(curarg); cmdfile(initfile,3); } else { /* @filename */ if ((initfile = fopen(&curarg[1],"r")) == NULL) argerror(curarg); cmdfile(initfile,0); } } if (first_init == 0) { initmode = -1; /* don't set video when key used */ showfile = 1; /* nor startup image file */ } init_msg(0,"",NULL,0); /* this causes getakey if init_msg called on runup */ if(debugflag != 110) first_init = 0; /* { char msg[MSGLEN]; sprintf(msg,"cmdfiles colorpreloaded %d showfile %d savedac %d", colorpreloaded, showfile, savedac); stopmsg(0,msg); } */ if(colorpreloaded && showfile==0) /* PAR reads a file and sets color */ dontreadcolor = 1; /* don't read colors from GIF */ else dontreadcolor = 0; /* read colors from GIF */ /*set structure of search directories*/ strcpy(searchfor.par, CommandFile); strcpy(searchfor.frm, FormFileName); strcpy(searchfor.lsys, LFileName); strcpy(searchfor.ifs, IFSFileName); return(0); } int load_commands(FILE *infile) { /* when called, file is open in binary mode, positioned at the */ /* '(' or '{' following the desired parameter set's name */ int ret; initcorners = initparams = 0; /* reset flags for type= */ ret = cmdfile(infile,2); /* { char msg[MSGLEN]; sprintf(msg,"load commands colorpreloaded %d showfile %d savedac %d", colorpreloaded, showfile, savedac); stopmsg(0,msg); } */ if(colorpreloaded && showfile==0) /* PAR reads a file and sets color */ dontreadcolor = 1; /* don't read colors from GIF */ else dontreadcolor = 0; /* read colors from GIF */ return ret; } static void initvars_run() /* once per run init */ { char *p; init_rseed = (int)time(NULL); init_comments(); if((p = getenv("TMP")) == NULL) p = getenv("TEMP"); if(p != NULL) { if(isadirectory(p) != 0) { strcpy(tempdir,p); fix_dirname(tempdir); } } else *tempdir = 0; } static void initvars_restart() /* key init */ { int i; recordcolors = 'a'; /* don't use mapfiles in PARs */ save_release = release; /* this release number */ gif87a_flag = INIT_GIF87; /* turn on GIF89a processing */ dither_flag = 0; /* no dithering */ askvideo = 1; /* turn on video-prompt flag */ overwrite = 0; /* don't overwrite */ soundflag = 9; /* sound is on to PC speaker */ initbatch = 0; /* not in batch mode */ checkcurdir = 0; /* flag to check current dire for files */ initsavetime = 0; /* no auto-save */ initmode = -1; /* no initial video mode */ viewwindow = 0; /* no view window */ viewreduction = (float)4.2; viewcrop = 1; virtual = 1; /* virtual screen modes on */ ai_8514 = 0; /* no need for the 8514 API */ finalaspectratio = screenaspect; viewxdots = viewydots = 0; video_cutboth = 1; /* keep virtual aspect */ zscroll = 1; /* relaxed screen scrolling */ orbit_delay = 0; /* full speed orbits */ orbit_interval = 1; /* plot all orbits */ debugflag = 0; /* debugging flag(s) are off */ timerflag = 0; /* timer flags are off */ far_strcpy(FormFileName,s_fractintfrm); /* default formula file */ FormName[0] = 0; far_strcpy(LFileName,s_fractintl); LName[0] = 0; far_strcpy(CommandFile,s_fractintpar); CommandName[0] = 0; for(i=0;i<4; i++) CommandComment[i][0] = 0; far_strcpy(IFSFileName,s_fractintifs); IFSName[0] = 0; reset_ifs_defn(); rflag = 0; /* not a fixed srand() seed */ rseed = init_rseed; strcpy(readname,DOTSLASH); /* initially current directory */ showfile = 1; /* next should perhaps be fractal re-init, not just ? */ initcyclelimit=55; /* spin-DAC default speed limit */ mapset = 0; /* no map= name active */ if (mapdacbox) { farmemfree(mapdacbox); mapdacbox = NULL; } TPlusFlag = 1; MaxColorRes = 8; PixelZoom = 0; NonInterlaced = 0; Printer_Type = DEFAULT_PRINTER; /* assume an IBM/EPSON */ Printer_Resolution = PRT_RESOLUTION; /* assume low resolution */ Printer_Titleblock = 0; /* assume no title block */ Printer_ColorXlat = 0; /* assume positive image */ Printer_SetScreen = 0; /* assume default screen */ Printer_SFrequency = 45; /* New screen frequency K */ Printer_SAngle = 45; /* New screen angle K */ Printer_SStyle = 1; /* New screen style K */ Printer_RFrequency = 45; /* New screen frequency R */ Printer_RAngle = 75; /* New screen angle R */ Printer_RStyle = 1; /* New screen style R */ Printer_GFrequency = 45; /* New screen frequency G */ Printer_GAngle = 15; /* New screen angle G */ Printer_GStyle = 1; /* New screen style G */ Printer_BFrequency = 45; /* New screen frequency B */ Printer_BAngle = 0; /* New screen angle B */ Printer_BStyle = 1; /* New screen style B */ #ifndef XFRACT Print_To_File = 0; /* No print-to-file */ Printer_CRLF = 0; /* Assume CR+LF */ #else Print_To_File = 1; /* Print-to-file */ Printer_CRLF = 2; /* Assume LF */ Printer_Compress = 0; /* Assume NO PostScript compression */ #endif EPSFileType = 0; /* Assume no save to .EPS */ LPTNumber = 1; /* assume LPT1 */ ColorPS = 1; /* Assume Color PostScript ...*/ major_method = breadth_first; /* default inverse julia methods */ minor_method = left_first; /* default inverse julia methods */ truecolor = 0; /* truecolor output flag */ truemode = 0; /* set to default color scheme */ } static void initvars_fractal() /* init vars affecting calculation */ { int i; bios_palette = 0; /* don't force use of a BIOS palette */ escape_exit = 0; /* don't disable the "are you sure?" screen */ usr_periodicitycheck = 1; /* turn on periodicity */ inside = 1; /* inside color = blue */ fillcolor = -1; /* no special fill color */ usr_biomorph = -1; /* turn off biomorph flag */ outside = -1; /* outside color = -1 (not used) */ maxit = 150; /* initial maxiter */ usr_stdcalcmode = 'g'; /* initial solid-guessing */ stoppass = 0; /* initial guessing stoppass */ quick_calc = 0; closeprox = 0.01; ismand = 1; /* default formula mand/jul toggle */ #ifndef XFRACT usr_floatflag = 0; /* turn off the float flag */ #else usr_floatflag = 1; /* turn on the float flag */ #endif finattract = 0; /* disable finite attractor logic */ fractype = 0; /* initial type Set flag */ curfractalspecific = &fractalspecific[0]; initcorners = initparams = 0; bailout = 0; /* no user-entered bailout */ nobof = 0; /* use normal bof initialization to make bof images */ useinitorbit = 0; for (i = 0; i < MAXPARAMS; i++) param[i] = 0.0; /* initial parameter values */ for (i = 0; i < 3; i++) potparam[i] = 0.0; /* initial potential values */ for (i = 0; i < 3; i++) inversion[i] = 0.0; /* initial invert values */ initorbit.x = initorbit.y = 0.0; /* initial orbit values */ invert = 0; decomp[0] = decomp[1] = 0; usr_distest = 0; pseudox = 0; pseudoy = 0; distestwidth = 71; forcesymmetry = 999; /* symmetry not forced */ xx3rd = xxmin = -2.5; xxmax = 1.5; /* initial corner values */ yy3rd = yymin = -1.5; yymax = 1.5; /* initial corner values */ bf_math = 0; pot16bit = potflag = 0; LogFlag = 0; /* no logarithmic palette */ set_trig_array(0,s_sin); /* trigfn defaults */ set_trig_array(1,s_sqr); set_trig_array(2,s_sinh); set_trig_array(3,s_cosh); if (rangeslen) { farmemfree((char far *)ranges); rangeslen = 0; } usemag = 1; /* use center-mag, not corners */ colorstate = colorpreloaded = 0; rotate_lo = 1; rotate_hi = 255; /* color cycling default range */ orbit_delay = 0; /* full speed orbits */ orbit_interval = 1; /* plot all orbits */ keep_scrn_coords = 0; drawmode = 'r'; /* passes=orbits draw mode */ set_orbit_corners = 0; oxmin = curfractalspecific->xmin; oxmax = curfractalspecific->xmax; ox3rd = curfractalspecific->xmin; oymin = curfractalspecific->ymin; oymax = curfractalspecific->ymax; oy3rd = curfractalspecific->ymin; math_tol[0] = 0.05; math_tol[1] = 0.05; display3d = 0; /* 3D display is off */ overlay3d = 0; /* 3D overlay is off */ old_demm_colors = 0; bailoutest = Mod; floatbailout = (int (near *)(void))fpMODbailout; longbailout = (int (near *)(void))asmlMODbailout; bignumbailout = (int (near *)(void))bnMODbailout; bigfltbailout = (int (near *)(void))bfMODbailout; functionpreloaded = 0; /* for old bifs JCO 7/5/92 */ mxminfp = -.83; myminfp = -.25; mxmaxfp = -.83; mymaxfp = .25; originfp = 8; heightfp = 7; widthfp = 10; distfp = 24; eyesfp = (float)2.5; depthfp = 8; neworbittype = JULIA; zdots = 128; initvars_3d(); basehertz = 440; /* basic hertz rate */ #ifndef XFRACT fm_vol = 63; /* full volume on soundcard o/p */ hi_atten = 0; /* no attenuation of hi notes */ fm_attack = 5; /* fast attack */ fm_decay = 10; /* long decay */ fm_sustain = 13; /* fairly high sustain level */ fm_release = 5; /* short release */ fm_wavetype = 0; /* sin wave */ polyphony = 0; /* no polyphony */ for(i=0;i<=11;i++) scale_map[i]=i+1; /* straight mapping of notes in octave */ #endif } static void initvars_3d() /* init vars affecting 3d */ { RAY = 0; BRIEF = 0; SPHERE = FALSE; preview = 0; showbox = 0; xadjust = 0; yadjust = 0; eyeseparation = 0; glassestype = 0; previewfactor = 20; red_crop_left = 4; red_crop_right = 0; blue_crop_left = 0; blue_crop_right = 4; red_bright = 80; blue_bright = 100; transparent[0] = transparent[1] = 0; /* no min/max transparency */ set_3d_defaults(); } static void reset_ifs_defn() { if (ifs_defn) { farmemfree((char far *)ifs_defn); ifs_defn = NULL; } } static int cmdfile(FILE *handle,int mode) /* mode = 0 command line @filename */ /* 1 sstools.ini */ /* 2 <@> command after startup */ /* 3 command line @filename/setname */ { /* note that cmdfile could be open as text OR as binary */ /* binary is used in @ command processing for reasonable speed note/point */ int i; int lineoffset = 0; int changeflag = 0; /* &1 fractal stuff chgd, &2 3d stuff chgd */ char linebuf[513],*cmdbuf; char far *savesuffix; /* use near array suffix for large argument buffer, but save existing contents to extraseg */ cmdbuf = (char *)suffix; savesuffix = MK_FP(extraseg,0); far_memcpy(savesuffix,suffix,10000); far_memset(suffix,0,10000); if (mode == 2 || mode == 3) { while ((i = getc(handle)) != '{' && i != EOF) { } for(i=0;i<4; i++) CommandComment[i][0] = 0; } linebuf[0] = 0; while (next_command(cmdbuf,10000,handle,linebuf,&lineoffset,mode) > 0) { if ((mode == 2 || mode == 3) && far_strcmp(cmdbuf,"}") == 0) break; if ((i = cmdarg(cmdbuf,mode)) < 0) break; changeflag |= i; } fclose(handle); #ifdef XFRACT initmode = 0; /* Skip credits if @file is used. */ #endif far_memcpy(suffix,savesuffix,10000); if(changeflag&1) { backwards_v18(); backwards_v19(); backwards_v20(); } return changeflag; } static int next_command(char *cmdbuf,int maxlen, FILE *handle,char *linebuf,int *lineoffset,int mode) { int i; int cmdlen = 0; char *lineptr; lineptr = linebuf + *lineoffset; for(;;) { while (*lineptr <= ' ' || *lineptr == ';') { if (cmdlen) { /* space or ; marks end of command */ cmdbuf[cmdlen] = 0; *lineoffset = lineptr - linebuf; return cmdlen; } while (*lineptr && *lineptr <= ' ') ++lineptr; /* skip spaces and tabs */ if (*lineptr == ';' || *lineptr == 0) { if (*lineptr == ';' && (mode == 2 || mode == 3) && (CommandComment[0][0] == 0 || CommandComment[1][0] == 0 || CommandComment[2][0] == 0 || CommandComment[3][0] == 0)) { /* save comment */ while (*(++lineptr) && (*lineptr == ' ' || *lineptr == '\t')) { } if (*lineptr) { if ((int)strlen(lineptr) >= MAXCMT) *(lineptr+MAXCMT-1) = 0; for(i=0;i<4; i++) if (CommandComment[i][0] == 0) { far_strcpy(CommandComment[i],lineptr); break; } } } if (next_line(handle,linebuf,mode) != 0) return(-1); /* eof */ lineptr = linebuf; /* start new line */ } } if (*lineptr == '\\' /* continuation onto next line? */ && *(lineptr+1) == 0) { if (next_line(handle,linebuf,mode) != 0) { argerror(cmdbuf); /* missing continuation */ return(-1); } lineptr = linebuf; while (*lineptr && *lineptr <= ' ') ++lineptr; /* skip white space @ start next line */ continue; /* loop to check end of line again */ } cmdbuf[cmdlen] = *(lineptr++); /* copy character to command buffer */ if (++cmdlen >= maxlen) { /* command too long? */ argerror(cmdbuf); return(-1); } } } static int next_line(FILE *handle,char *linebuf,int mode) { int toolssection; char tmpbuf[11]; toolssection = 0; while (file_gets(linebuf,512,handle) >= 0) { if (mode == 1 && linebuf[0] == '[') { /* check for [fractint] */ #ifndef XFRACT strncpy(tmpbuf,&linebuf[1],9); tmpbuf[9] = 0; strlwr(tmpbuf); toolssection = far_strncmp(tmpbuf,"fractint]",9); #else strncpy(tmpbuf,&linebuf[1],10); tmpbuf[10] = 0; strlwr(tmpbuf); toolssection = far_strncmp(tmpbuf,"xfractint]",10); #endif continue; /* skip tools section heading */ } if (toolssection == 0) return(0); } return(-1); } /* cmdarg(string,mode) processes a single command-line/command-file argument return: -1 error, >= 0 ok if ok, return value: | 1 means fractal parm has been set | 2 means 3d parm has been set | 4 means 3d=yes specified | 8 means reset specified */ /* following gets rid of "too big for optimization" warning */ #ifdef _MSC_VER #if (_MSC_VER >= 600) #pragma optimize( "el", off ) #endif #endif int cmdarg(char *curarg,int mode) /* process a single argument */ { char variable[21]; /* variable name goes here */ char *value; /* pointer to variable value */ int valuelen; /* length of value */ int numval; /* numeric value of arg */ #define NONNUMERIC -32767 char charval[16]; /* first character of arg */ int yesnoval[16]; /* 0 if 'n', 1 if 'y', -1 if not */ double ftemp; int i, j, k, l; char *argptr,*argptr2; int totparms; /* # of / delimited parms */ int intparms; /* # of / delimited ints */ int floatparms; /* # of / delimited floats */ int intval[64]; /* pre-parsed integer parms */ double floatval[16]; /* pre-parsed floating parms */ char *floatvalstr[16]; /* pointers to float vals */ char tmpc; int lastarg; double Xctr, Yctr, Xmagfactor, Rotation, Skew; LDBL Magnification; bf_t bXctr, bYctr; argptr = curarg; #ifndef XFRACT while (*argptr) { /* convert to lower case */ if (*argptr >= 'A' && *argptr <= 'Z') *argptr += 'a' - 'A'; if (*argptr == '=' && far_strncmp(curarg,"colors=",7) == 0) break; /* don't convert colors=value */ if (*argptr == '=' && far_strncmp(curarg,s_comment,7) == 0) break; /* don't convert comment=value */ ++argptr; } #endif if ((value = strchr(&curarg[1],'=')) != NULL) { if ((j = (value++) - curarg) > 1 && curarg[j-1] == ':') --j; /* treat := same as = */ } else value = curarg + (j = strlen(curarg)); if (j > 20) goto badarg; /* keyword too long */ strncpy(variable,curarg,j); /* get the variable name */ variable[j] = 0; /* truncate variable name */ valuelen = strlen(value); /* note value's length */ charval[0] = value[0]; /* first letter of value */ yesnoval[0] = -1; /* note yes|no value */ if (charval[0] == 'n') yesnoval[0] = 0; if (charval[0] == 'y') yesnoval[0] = 1; argptr = value; numval = totparms = intparms = floatparms = 0; while (*argptr) { /* count and pre-parse parms */ unsigned long ll; char firstchar; lastarg = 0; if ((argptr2 = strchr(argptr,'/')) == NULL) { /* find next '/' */ argptr2 = argptr + strlen(argptr); *argptr2 = '/'; lastarg = 1; } if (totparms == 0) numval = NONNUMERIC; i = -1; if(totparms < 16) { charval[totparms] = *argptr; /* first letter of value */ if (charval[totparms] == 'n') yesnoval[totparms] = 0; if (charval[totparms] == 'y') yesnoval[totparms] = 1; } j=0; if (sscanf(argptr,"%c%c",(char *)&j,&tmpc) > 0 /* NULL entry */ && ((char)j == '/' || (char)j == '=') && tmpc == '/') { j = 0; ++floatparms; ++intparms; if (totparms < 16) {floatval[totparms] = j; floatvalstr[totparms]="0";} if (totparms < 64) intval[totparms] = j; if (totparms == 0) numval = j; } else if (sscanf(argptr,"%c%ld%c",&firstchar,&ll,&tmpc) > 0 && firstchar == '-' && tmpc == '/') { /* got a negative integer */ ++floatparms; ++intparms; if (totparms < 16) {floatval[totparms] = 0.0 - ll; floatvalstr[totparms]=argptr;} if (totparms < 64) intval[totparms] = 0 - (int)ll; if (totparms == 0) numval = 0 - (int)ll; } else if (sscanf(argptr,"%ld%c",&ll,&tmpc) > 0 /* got an integer */ && tmpc == '/') { /* needs a long int, ll, here for lyapunov */ ++floatparms; ++intparms; if (totparms < 16) {floatval[totparms] = ll; floatvalstr[totparms]=argptr;} if (totparms < 64) intval[totparms] = (int)ll; if (totparms == 0) numval = (int)ll; } #ifndef XFRACT else if (sscanf(argptr,"%lg%c",&ftemp,&tmpc) > 0 /* got a float */ #else else if (sscanf(argptr,"%lf%c",&ftemp,&tmpc) > 0 /* got a float */ #endif && tmpc == '/') { ++floatparms; if (totparms < 16) {floatval[totparms] = ftemp;floatvalstr[totparms]=argptr;} } /* using arbitrary precision and above failed */ else if (((int)strlen(argptr) > 513) /* very long command */ || (totparms > 0 && floatval[totparms-1] == FLT_MAX && totparms < 6) || isabigfloat(argptr)) { ++floatparms; floatval[totparms] = FLT_MAX; floatvalstr[totparms]=argptr; } ++totparms; argptr = argptr2; /* on to the next */ if (lastarg) *argptr = 0; else ++argptr; } if (mode != 2 || debugflag==110) { /* these commands are allowed only at startup */ if (far_strcmp(variable,s_batch) == 0 ) { /* batch=? */ if (yesnoval[0] < 0) goto badarg; #ifdef XFRACT initmode = yesnoval[0]?0:-1; /* skip credits for batch mode */ #endif initbatch = yesnoval[0]; return 3; } if (far_strcmp(variable,"maxhistory") == 0) { /* maxhistory=? */ if(numval == NONNUMERIC) goto badarg; else if(numval < 0 /* || numval > 1000 */) goto badarg; else maxhistory = numval; return 3; } #ifndef XFRACT if (far_strcmp(variable,s_adapter) == 0 ) { /* adapter==? */ int i, j; char adapter_name[8]; /* entry lenth from VIDEO.ASM */ char *adapter_ptr; adapter_ptr = &supervga_list; for(i = 0 ; ; i++) { /* find the SuperVGA entry */ memcpy(adapter_name , adapter_ptr, 8); adapter_name[6] = ' '; for (j = 0; j < 8; j++) if(adapter_name[j] == ' ') adapter_name[j] = 0; if (adapter_name[0] == 0) break; /* end-of-the-list */ if (far_strncmp(value,adapter_name,strlen(adapter_name)) == 0) { svga_type = i+1; adapter_ptr[6] = 1; break; } adapter_ptr += 8; } if (svga_type != 0) return 3; video_type = 5; /* assume video=vga */ if (far_strcmp(value,s_egamono) == 0) { video_type = 3; mode7text = 1; } else if (far_strcmp(value,s_hgc) == 0) { /* video = hgc */ video_type = 1; mode7text = 1; } else if (far_strcmp(value,s_ega) == 0) /* video = ega */ video_type = 3; else if (far_strcmp(value,s_cga) == 0) /* video = cga */ video_type = 2; else if (far_strcmp(value,s_mcga) == 0) /* video = mcga */ video_type = 4; else if (far_strcmp(value,s_vga) == 0) /* video = vga */ video_type = 5; else goto badarg; return 3; } if (far_strcmp(variable,s_afi) == 0) { if (far_strncmp(value,"8514" ,4) == 0 || charval[0] == 'y') ai_8514 = 1; /* set afi flag JCO 4/11/92 */ return 3; } if (far_strcmp(variable,s_textsafe) == 0 ) { /* textsafe==? */ if (first_init) { if (charval[0] == 'n') /* no */ textsafe = 2; else if (charval[0] == 'y') /* yes */ textsafe = 1; else if (charval[0] == 'b') /* bios */ textsafe = 3; else if (charval[0] == 's') /* save */ textsafe = 4; else goto badarg; } return 3; } if (far_strcmp(variable,s_vesadetect) == 0) { if (yesnoval[0] < 0) goto badarg; vesa_detect = yesnoval[0]; return 3; } if (far_strcmp(variable,s_biospalette) == 0) { if (yesnoval[0] < 0) goto badarg; bios_palette = yesnoval[0]; return 3; } #endif if (far_strcmp(variable,s_fpu) == 0) { if (far_strcmp(value,s_387) == 0) { #ifndef XFRACT fpu = 387; #else fpu = -1; #endif return 0; } goto badarg; } if (far_strcmp(variable,s_exitnoask) == 0) { if (yesnoval[0] < 0) goto badarg; escape_exit = yesnoval[0]; return 3; } if (far_strcmp(variable,s_makedoc) == 0) { print_document(*value ? value : "fractint.doc", makedoc_msg_func, 0); #ifndef WINFRACT goodbye(); #endif } if (far_strcmp(variable,s_makepar) == 0) { char *slash, *next=NULL; if(totparms < 1 || totparms > 2) goto badarg; if((slash = strchr(value,'/')) != NULL) { *slash = 0; next = slash+1; } strcpy(CommandFile,value); if(strchr(CommandFile,'.') == NULL) strcat(CommandFile,".par"); if(strcmp(readname,DOTSLASH)==0) *readname = 0; if(next == NULL) { if(*readname != 0) extract_filename(CommandName,readname); else if(*MAP_name != 0) extract_filename(CommandName,MAP_name); else goto badarg; } else { strncpy(CommandName,next,ITEMNAMELEN); CommandName[ITEMNAMELEN] = 0; } *s_makepar = 0; /* used as a flag for makepar case */ if(*readname != 0) { if(read_overlay() != 0) goodbye(); } else if(*MAP_name != 0) { s_makepar[1] = 0; /* second char is flag for map */ } xdots = filexdots; ydots = fileydots; dxsize = xdots-1; dysize = ydots-1; calcfracinit(); make_batch_file(); #ifndef WINFRACT #ifndef XFRACT if(*readname != 0) printf("copying fractal info in GIF %s to PAR %s/%s\n", readname,CommandFile,CommandName); else if (*MAP_name != 0) printf("copying color info in map %s to PAR %s/%s\n", MAP_name,CommandFile,CommandName); #endif goodbye(); #endif } } /* end of commands allowed only at startup */ if (far_strcmp(variable,s_reset) == 0) { initvars_fractal(); /* PAR release unknown unless specified */ if (numval>=0) save_release = numval; else goto badarg; if (save_release == 0) save_release = 1730; /* before start of lyapunov wierdness */ return 9; } if (far_strcmp(variable,s_filename) == 0) { /* filename=? */ int existdir; if (charval[0] == '.' && value[1] != SLASHC) { if (valuelen > 4) goto badarg; gifmask[0] = '*'; gifmask[1] = 0; strcat(gifmask,value); return 0; } if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if (mode == 2 && display3d == 0) /* can't do this in @ command */ goto badarg; if((existdir=merge_pathnames(readname, value, mode))==0) showfile = 0; else if(existdir < 0) init_msg(0,variable,value,mode); else extract_filename(browsename,readname); return 3; } if (far_strcmp(variable,s_video) == 0) { /* video=? */ if (active_system == 0) { if ((k = check_vidmode_keyname(value)) == 0) goto badarg; initmode = -1; for (i = 0; i < MAXVIDEOTABLE; ++i) { if (videotable[i].keynum == k) { initmode = i; break; } } if (initmode == -1) goto badarg; } return 3; } if (far_strcmp(variable,s_map) == 0 ) { /* map=, set default colors */ int existdir; if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if((existdir=merge_pathnames(MAP_name,value,mode))>0) return 0; /* got a directory */ else if (existdir < 0) { init_msg(0,variable,value,mode); return (0); } SetColorPaletteName(MAP_name); return 0; } if (far_strcmp(variable,s_colors) == 0) { /* colors=, set current colors */ if (parse_colors(value) < 0) goto badarg; return 0; } if (far_strcmp(variable,s_recordcolors) == 0) { /* recordcolors= */ if(*value != 'y' && *value != 'c' && *value != 'a') goto badarg; recordcolors = *value; return 0; } if (far_strcmp(variable,s_maxlinelength) == 0) { /* maxlinelength= */ if(numval < MINMAXLINELENGTH || numval > MAXMAXLINELENGTH) goto badarg; maxlinelength = numval; return 0; } if (far_strcmp(variable,s_comment) == 0) { /* comment= */ parse_comments(value); return 0; } if (far_strcmp(variable,s_tplus) == 0) { /* Use the TARGA+ if found? */ if (yesnoval[0] < 0) goto badarg; TPlusFlag = yesnoval[0]; return 0; } if (far_strcmp(variable,s_noninterlaced) == 0) { if (yesnoval[0] < 0) goto badarg; NonInterlaced = yesnoval[0]; return 0; } if (far_strcmp(variable,s_maxcolorres) == 0) { /* Change default color resolution */ if (numval == 1 || numval == 4 || numval == 8 || numval == 16 || numval == 24) { MaxColorRes = numval; return 0; } goto badarg; } if (far_strcmp(variable,s_pixelzoom) == 0) { if (numval < 5) PixelZoom = numval; return 0; } /* keep this for backward compatibility */ if (far_strcmp(variable,s_warn) == 0 ) { /* warn=? */ if (yesnoval[0] < 0) goto badarg; overwrite = (char)(yesnoval[0] ^ 1); return 0; } if (far_strcmp(variable,s_overwrite) == 0 ) { /* overwrite=? */ if (yesnoval[0] < 0) goto badarg; overwrite = (char)yesnoval[0]; return 0; } if (far_strcmp(variable,s_gif87a) == 0 ) { /* gif87a=? */ if (yesnoval[0] < 0) goto badarg; gif87a_flag = yesnoval[0]; return 0; } if (far_strcmp(variable,s_dither) == 0 ) { /* dither=? */ if (yesnoval[0] < 0) goto badarg; dither_flag = yesnoval[0]; return 0; } if (far_strcmp(variable,s_savetime) == 0) { /* savetime=? */ initsavetime = numval; return 0; } if (far_strcmp(variable,s_autokey) == 0) { /* autokey=? */ if (far_strcmp(value,s_record)==0) slides=2; else if (far_strcmp(value,s_play)==0) slides=1; else goto badarg; return 0; } if (far_strcmp(variable,s_autokeyname) == 0) { /* autokeyname=? */ if(merge_pathnames(autoname, value,mode) < 0) init_msg(0,variable,value,mode); return 0; } if (far_strcmp(variable,s_type) == 0 ) { /* type=? */ if (value[valuelen-1] == '*') value[--valuelen] = 0; /* kludge because type ifs3d has an asterisk in front */ if(far_strcmp(value,s_ifs3d)==0) value[3]=0; for (k = 0; fractalspecific[k].name != NULL; k++) if (far_strcmp(value,fractalspecific[k].name) == 0) break; if (fractalspecific[k].name == NULL) goto badarg; curfractalspecific = &fractalspecific[fractype = k]; if (initcorners == 0) { xx3rd = xxmin = curfractalspecific->xmin; xxmax = curfractalspecific->xmax; yy3rd = yymin = curfractalspecific->ymin; yymax = curfractalspecific->ymax; } if (initparams == 0) load_params(fractype); return 1; } if (far_strcmp(variable,s_inside) == 0 ) { /* inside=? */ if(far_strcmp(value,s_zmag)==0) inside = ZMAG; else if(far_strcmp(value,s_bof60)==0) inside = BOF60; else if(far_strcmp(value,s_bof61)==0) inside = BOF61; else if(far_strncmp(value,s_epscross,3)==0) inside = EPSCROSS; else if(far_strncmp(value,s_startrail,4)==0) inside = STARTRAIL; else if(far_strncmp(value,s_period,3)==0) inside = PERIOD; else if(far_strncmp(value,s_fmod,3)==0) inside = FMODI; else if(far_strncmp(value,s_atan,3)==0) inside = ATANI; else if(far_strcmp(value,s_maxiter)==0) inside = -1; else if(numval == NONNUMERIC) goto badarg; else inside = numval; return 1; } if (far_strcmp(variable,s_prox) == 0 ) { /* proximity=? */ closeprox = floatval[0]; return 1; } if (far_strcmp(variable,s_fillcolor) == 0 ) { /* fillcolor */ if(far_strcmp(value,s_normal)==0) fillcolor = -1; else if(numval == NONNUMERIC) goto badarg; else fillcolor = numval; return 1; } if (far_strcmp(variable,s_finattract) == 0 ) { /* finattract=? */ if (yesnoval[0] < 0) goto badarg; finattract = yesnoval[0]; return 1; } if (far_strcmp(variable,s_nobof) == 0 ) { /* nobof=? */ if (yesnoval[0] < 0) goto badarg; nobof = yesnoval[0]; return 1; } if (far_strcmp(variable,s_function) == 0) { /* function=?,? */ k = 0; while (*value && k < 4) { if(set_trig_array(k++,value)) goto badarg; if ((value = strchr(value,'/')) == NULL) break; ++value; } functionpreloaded = 1; /* for old bifs JCO 7/5/92 */ return 1; } if (far_strcmp(variable,s_outside) == 0 ) { /* outside=? */ if(far_strcmp(value,s_iter)==0) outside = ITER; else if(far_strcmp(value,s_real)==0) outside = REAL; else if(far_strcmp(value,s_imag)==0) outside = IMAG; else if(far_strcmp(value,s_mult)==0) outside = MULT; else if(far_strcmp(value,s_sum)==0) outside = SUM; else if(far_strcmp(value,s_atan)==0) outside = ATAN; else if(far_strcmp(value,s_fmod)==0) outside = FMOD; else if(far_strcmp(value,s_tdis)==0) outside = TDIS; else if(numval == NONNUMERIC) goto badarg; else if(numval < TDIS || numval > 255) goto badarg; else outside = numval; return 1; } if (far_strcmp(variable,s_bfdigits) == 0 ) { /* bfdigits=? */ if(numval == NONNUMERIC) goto badarg; else if(numval < 0 || numval > 2000) goto badarg; else bfdigits = numval; return 1; } if (far_strcmp(variable,s_maxiter) == 0) { /* maxiter=? */ if (floatval[0] < 2) goto badarg; maxit = (long)floatval[0]; return 1; } if (far_strcmp(variable,s_iterincr) == 0) /* iterincr=? */ return 0; if (far_strcmp(variable,s_passes) == 0) { /* passes=? */ if ( charval[0] != '1' && charval[0] != '2' && charval[0] != '3' && charval[0] != 'g' && charval[0] != 'b' && charval[0] != 't' && charval[0] != 's' && charval[0] != 'd' && charval[0] != 'o') goto badarg; usr_stdcalcmode = charval[0]; if(charval[0] == 'g') { stoppass = ((int)value[1] - (int)'0'); if(stoppass < 0 || stoppass > 6) stoppass = 0; } return 1; } if (far_strcmp(variable,s_ismand) == 0 ) { /* ismand=? */ if (yesnoval[0] < 0) goto badarg; ismand = (short int)yesnoval[0]; return 1; } if (far_strcmp(variable,s_cyclelimit) == 0 ) { /* cyclelimit=? */ if (numval <= 1 || numval > 256) goto badarg; initcyclelimit = numval; return 0; } if (far_strcmp(variable,s_makemig) == 0) { int xmult, ymult; if (totparms < 2) goto badarg; xmult = intval[0]; ymult = intval[1]; make_mig(xmult, ymult); #ifndef WINFRACT exit(0); #endif } if (far_strcmp(variable,s_cyclerange) == 0) { if (totparms < 2) intval[1] = 255; if (totparms < 1) intval[0] = 1; if (totparms != intparms || intval[0] < 0 || intval[1] > 255 || intval[0] > intval[1]) goto badarg; rotate_lo = intval[0]; rotate_hi = intval[1]; return 0; } if (far_strcmp(variable,s_ranges) == 0) { int i,j,entries,prev; int tmpranges[128]; if (totparms != intparms) goto badarg; entries = prev = i = 0; LogFlag = 0; /* ranges overrides logmap */ while (i < totparms) { if ((j = intval[i++]) < 0) { /* striping */ if ((j = 0-j) < 1 || j >= 16384 || i >= totparms) goto badarg; tmpranges[entries++] = -1; /* {-1,width,limit} for striping */ tmpranges[entries++] = j; j = intval[i++]; } if (j < prev) goto badarg; tmpranges[entries++] = prev = j; } if (prev == 0) goto badarg; if ((ranges = (int far *)farmemalloc(sizeof(int)*entries)) == NULL) { static FCODE msg[] = {"Insufficient memory for ranges="}; stopmsg(1,msg); return(-1); } rangeslen = entries; for (i = 0; i < rangeslen; ++i) ranges[i] = tmpranges[i]; return 1; } if (far_strcmp(variable,s_savename) == 0) { /* savename=? */ if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if (first_init || mode == 2) { if(merge_pathnames(savename, value, mode) < 0) init_msg(0,variable,value,mode); } return 0; } if (far_strcmp(variable,s_lzw) == 0) { /* tweaklzw=? */ if (totparms >= 1) lzw[0] = intval[0]; if (totparms >= 2) lzw[1] = intval[1]; return 0; } if (far_strcmp(variable,s_minstack) == 0) { /* minstack=? */ if (totparms != 1) goto badarg; minstack = intval[0]; return 0; } if (far_strcmp(variable,s_mathtolerance) == 0) { /* mathtolerance=? */ if(charval[0] == '/') ; /* leave math_tol[0] at the default value */ else if (totparms >= 1) math_tol[0] = floatval[0]; if (totparms >= 2) math_tol[1] = floatval[1]; return 0; } if (far_strcmp(variable,s_tempdir) == 0) { /* tempdir=? */ if (valuelen > (FILE_MAX_DIR-1)) goto badarg; if(isadirectory(value) == 0) goto badarg; strcpy(tempdir,value); fix_dirname(tempdir); return 0; } if (far_strcmp(variable,s_workdir) == 0) { /* workdir=? */ if (valuelen > (FILE_MAX_DIR-1)) goto badarg; if(isadirectory(value) == 0) goto badarg; strcpy(workdir,value); fix_dirname(workdir); return 0; } if (far_strcmp(variable,s_exitmode) == 0) { /* exitmode=? */ sscanf(value,"%x",&numval); exitmode = (BYTE)numval; return 0; } if (far_strcmp(variable,s_textcolors) == 0) { parse_textcolors(value); return 0; } if (far_strcmp(variable,s_potential) == 0) { /* potential=? */ k = 0; while (k < 3 && *value) { if(k==1) potparam[k] = atof(value); else potparam[k] = atoi(value); k++; if ((value = strchr(value,'/')) == NULL) k = 99; ++value; } pot16bit = 0; if (k < 99) { if (far_strcmp(value,s_16bit)) goto badarg; pot16bit = 1; } return 1; } if (far_strcmp(variable,s_params) == 0) { /* params=?,? */ if (totparms != floatparms || totparms > MAXPARAMS) goto badarg; initparams = 1; for (k = 0; k < MAXPARAMS; ++k) param[k] = (k < totparms) ? floatval[k] : 0.0; if(bf_math) for (k = 0; k < MAXPARAMS; k++) floattobf(bfparms[k],param[k]); return 1; } if (far_strcmp(variable,s_miim) == 0) { /* miim=?[/?[/?[/?]]] */ if (totparms > 6) goto badarg; if (charval[0] == 'b') major_method = breadth_first; else if (charval[0] == 'd') major_method = depth_first; else if (charval[0] == 'w') major_method = random_walk; #ifdef RANDOM_RUN else if (charval[0] == 'r') major_method = random_run; #endif else goto badarg; if (charval[1] == 'l') minor_method = left_first; else if (charval[1] == 'r') minor_method = right_first; else goto badarg; /* keep this next part in for backwards compatibility with old PARs ??? */ if (totparms > 2) for (k = 2; k < 6; ++k) param[k-2] = (k < totparms) ? floatval[k] : 0.0; return 1; } if (far_strcmp(variable,s_initorbit) == 0) { /* initorbit=?,? */ if(far_strcmp(value,s_pixel)==0) useinitorbit = 2; else { if (totparms != 2 || floatparms != 2) goto badarg; initorbit.x = floatval[0]; initorbit.y = floatval[1]; useinitorbit = 1; } return 1; } if (far_strcmp(variable,s_orbitname) == 0 ) { /* orbitname=? */ if(check_orbit_name(value)) goto badarg; return 1; } if (far_strcmp(variable,s_3dmode) == 0 ) { /* orbitname=? */ int i,j; j = -1; for(i=0;i<4;i++) if(far_strcmp(value,juli3Doptions[i])==0) j = i; if(j < 0) goto badarg; else juli3Dmode = j; return 1; } if (far_strcmp(variable,s_julibrot3d) == 0) { /* julibrot3d=?,?,?,? */ if (floatparms != totparms) goto badarg; if(totparms > 0) zdots = (int)floatval[0]; if (totparms > 1) originfp = (float)floatval[1]; if (totparms > 2) depthfp = (float)floatval[2]; if (totparms > 3) heightfp = (float)floatval[3]; if (totparms > 4) widthfp = (float)floatval[4]; if (totparms > 5) distfp = (float)floatval[5]; return 1; } if (far_strcmp(variable,s_julibroteyes) == 0) { /* julibroteyes=?,?,?,? */ if (floatparms != totparms || totparms != 1) goto badarg; eyesfp = (float)floatval[0]; return 1; } if (far_strcmp(variable,s_julibrotfromto) == 0) { /* julibrotfromto=?,?,?,? */ if (floatparms != totparms || totparms != 4) goto badarg; mxmaxfp = floatval[0]; mxminfp = floatval[1]; mymaxfp = floatval[2]; myminfp = floatval[3]; return 1; } if (far_strcmp(variable,s_corners) == 0) { /* corners=?,?,?,? */ int dec; if (fractype == CELLULAR) return 1; /* skip setting the corners */ #if 0 printf("totparms %d floatparms %d\n",totparms, floatparms); getch(); #endif if ( floatparms != totparms || (totparms != 0 && totparms != 4 && totparms != 6)) goto badarg; usemag = 0; if (totparms == 0) return 0; /* turns corners mode on */ initcorners = 1; /* good first approx, but dec could be too big */ dec = get_max_curarg_len(floatvalstr,totparms) + 1; if((dec > DBL_DIG+1 || debugflag == 3200) && debugflag != 3400) { int old_bf_math; old_bf_math = bf_math; if(!bf_math || dec > decimals) init_bf_dec(dec); if(old_bf_math == 0) { int k; for (k = 0; k < MAXPARAMS; k++) floattobf(bfparms[k],param[k]); } /* xx3rd = xxmin = floatval[0]; */ get_bf(bfxmin,floatvalstr[0]); get_bf(bfx3rd,floatvalstr[0]); /* xxmax = floatval[1]; */ get_bf(bfxmax,floatvalstr[1]); /* yy3rd = yymin = floatval[2]; */ get_bf(bfymin,floatvalstr[2]); get_bf(bfy3rd,floatvalstr[2]); /* yymax = floatval[3]; */ get_bf(bfymax,floatvalstr[3]); if (totparms == 6) { /* xx3rd = floatval[4]; */ get_bf(bfx3rd,floatvalstr[4]); /* yy3rd = floatval[5]; */ get_bf(bfy3rd,floatvalstr[5]); } /* now that all the corners have been read in, get a more */ /* accurate value for dec and do it all again */ dec = getprecbf_mag(); if (dec < 0) goto badarg; /* ie: Magnification is +-1.#INF */ if(dec > decimals) /* get corners again if need more precision */ { init_bf_dec(dec); /* now get parameters and corners all over again at new decimal setting */ for (k = 0; k < MAXPARAMS; k++) floattobf(bfparms[k],param[k]); /* xx3rd = xxmin = floatval[0]; */ get_bf(bfxmin,floatvalstr[0]); get_bf(bfx3rd,floatvalstr[0]); /* xxmax = floatval[1]; */ get_bf(bfxmax,floatvalstr[1]); /* yy3rd = yymin = floatval[2]; */ get_bf(bfymin,floatvalstr[2]); get_bf(bfy3rd,floatvalstr[2]); /* yymax = floatval[3]; */ get_bf(bfymax,floatvalstr[3]); if (totparms == 6) { /* xx3rd = floatval[4]; */ get_bf(bfx3rd,floatvalstr[4]); /* yy3rd = floatval[5]; */ get_bf(bfy3rd,floatvalstr[5]); } } } xx3rd = xxmin = floatval[0]; xxmax = floatval[1]; yy3rd = yymin = floatval[2]; yymax = floatval[3]; if (totparms == 6) { xx3rd = floatval[4]; yy3rd = floatval[5]; } return 1; } if (far_strcmp(variable,s_orbitcorners) == 0) { /* orbit corners=?,?,?,? */ set_orbit_corners = 0; if ( floatparms != totparms || (totparms != 0 && totparms != 4 && totparms != 6)) goto badarg; ox3rd = oxmin = floatval[0]; oxmax = floatval[1]; oy3rd = oymin = floatval[2]; oymax = floatval[3]; if (totparms == 6) { ox3rd = floatval[4]; oy3rd = floatval[5]; } set_orbit_corners = 1; keep_scrn_coords = 1; return 1; } if (far_strcmp(variable,s_screencoords) == 0 ) { /* screencoords=? */ if (yesnoval[0] < 0) goto badarg; keep_scrn_coords = yesnoval[0]; return 1; } if (far_strcmp(variable,s_orbitdrawmode) == 0) { /* orbitdrawmode=? */ if ( charval[0] != 'l' && charval[0] != 'r' && charval[0] != 'f') goto badarg; drawmode = charval[0]; return 1; } if (far_strcmp(variable,s_viewwindows) == 0) { /* viewwindows=?,?,?,?,? */ if (totparms > 5 || floatparms-intparms > 2 || intparms > 4) goto badarg; viewwindow = 1; viewreduction = (float)4.2; /* reset default values */ finalaspectratio = screenaspect; viewcrop = 1; /* yes */ viewxdots = viewydots = 0; if((totparms > 0) && (floatval[0] > 0.001)) viewreduction = (float)floatval[0]; if((totparms > 1) && (floatval[1] > 0.001)) finalaspectratio = (float)floatval[1]; if((totparms > 2) && (yesnoval[2] == 0)) viewcrop = yesnoval[2]; if((totparms > 3) && (intval[3] > 0)) viewxdots = intval[3]; if((totparms == 5) && (intval[4] > 0)) viewydots = intval[4]; return 1; } if (far_strcmp(variable,s_centermag) == 0) { /* center-mag=?,?,?[,?,?,?] */ int dec; if ( (totparms != floatparms) || (totparms != 0 && totparms < 3) || (totparms >= 3 && floatval[2] == 0.0)) goto badarg; if (fractype == CELLULAR) return 1; /* skip setting the corners */ usemag = 1; if (totparms == 0) return 0; /* turns center-mag mode on */ initcorners = 1; /* dec = get_max_curarg_len(floatvalstr,totparms); */ #ifdef USE_LONG_DOUBLE sscanf(floatvalstr[2], "%Lf", &Magnification); #else sscanf(floatvalstr[2], "%lf", &Magnification); #endif /* I don't know if this is portable, but something needs to */ /* be used in case compiler's LDBL_MAX is not big enough */ if (Magnification > LDBL_MAX || Magnification < -LDBL_MAX) goto badarg; /* ie: Magnification is +-1.#INF */ dec = getpower10(Magnification) + 4; /* 4 digits of padding sounds good */ if((dec <= DBL_DIG+1 && debugflag != 3200) || debugflag == 3400) { /* rough estimate that double is OK */ Xctr = floatval[0]; Yctr = floatval[1]; /* Magnification = floatval[2]; */ /* already done above */ Xmagfactor = 1; Rotation = 0; Skew = 0; if (floatparms > 3) Xmagfactor = floatval[3]; if (Xmagfactor == 0) Xmagfactor = 1; if (floatparms > 4) Rotation = floatval[4]; if (floatparms > 5) Skew = floatval[5]; /* calculate bounds */ cvtcorners(Xctr, Yctr, Magnification, Xmagfactor, Rotation, Skew); return 1; } else { /* use arbitrary precision */ int old_bf_math; int saved; initcorners = 1; old_bf_math = bf_math; if(!bf_math || dec > decimals) init_bf_dec(dec); if(old_bf_math == 0) { int k; for (k = 0; k < MAXPARAMS; k++) floattobf(bfparms[k],param[k]); } usemag = 1; saved = save_stack(); bXctr = alloc_stack(bflength+2); bYctr = alloc_stack(bflength+2); /* Xctr = floatval[0]; */ get_bf(bXctr,floatvalstr[0]); /* Yctr = floatval[1]; */ get_bf(bYctr,floatvalstr[1]); /* Magnification = floatval[2]; */ /* already done above */ Xmagfactor = 1; Rotation = 0; Skew = 0; if (floatparms > 3) Xmagfactor = floatval[3]; if (Xmagfactor == 0) Xmagfactor = 1; if (floatparms > 4) Rotation = floatval[4]; if (floatparms > 5) Skew = floatval[5]; /* calculate bounds */ cvtcornersbf(bXctr, bYctr, Magnification, Xmagfactor, Rotation, Skew); bfcornerstofloat(); restore_stack(saved); return 1; } } if (far_strcmp(variable,s_aspectdrift) == 0 ) { /* aspectdrift=? */ if(floatparms != 1 || floatval[0] < 0) goto badarg; aspectdrift = (float)floatval[0]; return 1; } if (far_strcmp(variable,s_invert) == 0) { /* invert=?,?,? */ if (totparms != floatparms || (totparms != 1 && totparms != 3)) goto badarg; invert = ((inversion[0] = floatval[0]) != 0.0) ? totparms : 0; if (totparms == 3) { inversion[1] = floatval[1]; inversion[2] = floatval[2]; } return 1; } if (far_strcmp(variable,s_olddemmcolors) == 0 ) { /* olddemmcolors=? */ if (yesnoval[0] < 0) goto badarg; old_demm_colors = yesnoval[0]; return 0; } if (far_strcmp(variable,s_askvideo) == 0 ) { /* askvideo=? */ if (yesnoval[0] < 0) goto badarg; askvideo = yesnoval[0]; return 0; } if (far_strcmp(variable,s_ramvideo) == 0 ) /* ramvideo=? */ return 0; /* just ignore and return, for old time's sake */ if (far_strcmp(variable,s_float) == 0 ) { /* float=? */ if (yesnoval[0] < 0) goto badarg; #ifndef XFRACT usr_floatflag = (char)yesnoval[0]; #else usr_floatflag = 1; /* must use floating point */ #endif return 3; } if (far_strcmp(variable,s_fastrestore) == 0 ) { /* fastrestore=? */ if (yesnoval[0] < 0) goto badarg; fastrestore = (char)yesnoval[0]; return 0; } if (far_strcmp(variable,s_orgfrmdir) == 0 ) { /* orgfrmdir=? */ if (valuelen > (FILE_MAX_DIR-1)) goto badarg; if(isadirectory(value) == 0) goto badarg; orgfrmsearch = 1; strcpy(orgfrmdir,value); fix_dirname(orgfrmdir); return 0; } if (far_strcmp(variable,s_biomorph) == 0 ) { /* biomorph=? */ usr_biomorph = numval; return 1; } if (far_strcmp(variable,s_orbitsave) == 0 ) { /* orbitsave=? */ if(charval[0] == 's') orbitsave |= 2; else if (yesnoval[0] < 0) goto badarg; orbitsave |= yesnoval[0]; return 1; } if (far_strcmp(variable,s_bailout) == 0 ) { /* bailout=? */ if (floatval[0] < 1 || floatval[0] > 2100000000L) goto badarg; bailout = (long)floatval[0]; return 1; } if (far_strcmp(variable,s_bailoutest) == 0 ) { /* bailoutest=? */ if (far_strcmp(value,s_mod )==0) bailoutest = Mod; else if(far_strcmp(value,s_real)==0) bailoutest = Real; else if(far_strcmp(value,s_imag)==0) bailoutest = Imag; else if(far_strcmp(value,s_or )==0) bailoutest = Or; else if(far_strcmp(value,s_and )==0) bailoutest = And; else if(far_strcmp(value,s_manh)==0) bailoutest = Manh; else if(far_strcmp(value,s_manr)==0) bailoutest = Manr; else goto badarg; setbailoutformula(bailoutest); return 1; } if (far_strcmp(variable,s_symmetry) == 0 ) { /* symmetry=? */ if (far_strcmp(value,s_xaxis )==0) forcesymmetry = XAXIS; else if(far_strcmp(value,s_yaxis )==0) forcesymmetry = YAXIS; else if(far_strcmp(value,s_xyaxis)==0) forcesymmetry = XYAXIS; else if(far_strcmp(value,s_origin)==0) forcesymmetry = ORIGIN; else if(far_strcmp(value,s_pi )==0) forcesymmetry = PI_SYM; else if(far_strcmp(value,s_none )==0) forcesymmetry = NOSYM; else goto badarg; return 1; } if (far_strcmp(variable,s_printer) == 0 ) { /* printer=? */ if (parse_printer(value) < 0) goto badarg; return 0; } if (far_strcmp(variable,s_printfile) == 0) { /* printfile=? */ int existdir; if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if((existdir=merge_pathnames(PrintName, value, mode))==0) Print_To_File = 1; else if (existdir < 0) init_msg(0,variable,value,mode); return 0; } if(far_strcmp(variable,s_rleps) == 0) { Printer_Compress = yesnoval[0]; return(0); } if(far_strcmp(variable,s_colorps) == 0) { ColorPS = yesnoval[0]; return(0); } if (far_strcmp(variable,s_epsf) == 0) { /* EPS type? SWT */ Print_To_File = 1; EPSFileType = numval; Printer_Type = 5; if (far_strcmp(PrintName,s_fract001ps)==0) strcpy(PrintName,"fract001.ps"); return 0; } if (far_strcmp(variable,s_title) == 0) { /* Printer title block? SWT */ if (yesnoval[0] < 0) goto badarg; Printer_Titleblock = yesnoval[0]; return 0; } if (far_strcmp(variable,s_translate) == 0) { /* Translate color? SWT */ Printer_ColorXlat=0; if (charval[0] == 'y') Printer_ColorXlat=1; else if (numval > 1 || numval < -1) Printer_ColorXlat=numval; return 0; } if (far_strcmp(variable,s_plotstyle) == 0) { /* plot style? SWT */ Printer_SStyle = numval; return 0; } if (far_strcmp(variable,s_halftone) == 0) { /* New halftoning? SWT */ if (totparms != intparms) goto badarg; Printer_SetScreen=1; if ((totparms > 0) && ( intval[ 0] >= 0)) Printer_SFrequency = intval[ 0]; if ((totparms > 1) && ( intval[ 1] >= 0)) Printer_SAngle = intval[ 1]; if ((totparms > 2) && ( intval[ 2] >= 0)) Printer_SStyle = intval[ 2]; if ((totparms > 3) && ( intval[ 3] >= 0)) Printer_RFrequency = intval[ 3]; if ((totparms > 4) && ( intval[ 4] >= 0)) Printer_RAngle = intval[ 4]; if ((totparms > 5) && ( intval[ 5] >= 0)) Printer_RStyle = intval[ 5]; if ((totparms > 6) && ( intval[ 6] >= 0)) Printer_GFrequency = intval[ 6]; if ((totparms > 7) && ( intval[ 7] >= 0)) Printer_GAngle = intval[ 7]; if ((totparms > 8) && ( intval[ 8] >= 0)) Printer_GStyle = intval[ 8]; if ((totparms > 9) && ( intval[ 9] >= 0)) Printer_BFrequency = intval[ 9]; if ((totparms > 10) && ( intval[10] >= 0)) Printer_BAngle = intval[10]; if ((totparms > 11) && ( intval[11] >= 0)) Printer_BStyle = intval[11]; return 0; } if (far_strcmp(variable,s_linefeed) == 0) { /* Use LF for printer */ if (far_strcmp(value,s_cr) == 0) Printer_CRLF = 1; else if (far_strcmp(value,s_lf) == 0) Printer_CRLF = 2; else if (far_strcmp(value,s_crlf) == 0) Printer_CRLF = 0; else goto badarg; return 0; } if (far_strcmp(variable,s_comport) == 0 ) { /* Set the COM parameters */ if ((value=strchr(value,'/')) == NULL) goto badarg; switch (atoi(++value)) { case 110: l = 0; break; case 150: l = 32; break; case 300: l = 64; break; case 600: l = 96; break; case 1200: l = 128; break; case 2400: l = 160; break; case 4800: l = 192; break; case 9600: default: l = 224; break; } if ((value=strchr(value,'/')) == NULL) goto badarg; for (k=0; k < (int)strlen(value); k++) { switch (value[k]) { case '7': l |= 2; break; case '8': l |= 3; break; case 'o': l |= 8; break; case 'e': l |= 24; break; case '2': l |= 4; break; } } #ifndef XFRACT #ifndef WINFRACT _bios_serialcom(0,numval-1,l); #endif #endif return 0; } if (far_strcmp(variable,s_sound) == 0 ) { /* sound=?,?,? */ if (totparms > 5) goto badarg; soundflag = 0; /* start with a clean slate, add bits as we go */ if (totparms == 1) soundflag = 8; /* old command, default to PC speaker */ /* soundflag is used as a bitfield... bit 0,1,2 used for whether sound is modified by an orbits x,y,or z component. and also to turn it on or off (0==off, 1==beep (or yes), 2==x, 3==y, 4==z), Bit 3 is used for flagging the PC speaker sound, Bit 4 for OPL3 FM soundcard output, Bit 5 will be for midi output (not yet), Bit 6 for whether the tone is quantised to the nearest 'proper' note (according to the western, even tempered system anyway) */ if (charval[0] == 'n' || charval[0] == 'o') soundflag = soundflag & 0xF8; else if ((far_strncmp(value,"ye",2) == 0) || (charval[0] == 'b')) soundflag = soundflag | 1; else if (charval[0] == 'x') soundflag = soundflag | 2; else if (charval[0] == 'y' && far_strncmp(value,"ye",2) != 0) soundflag = soundflag | 3; else if (charval[0] == 'z') soundflag = soundflag | 4; else goto badarg; #ifndef XFRACT if (totparms > 1) { int i; soundflag = soundflag & 7; /* reset options */ for (i = 1; i < totparms; i++) { /* this is for 2 or more options at the same time */ if (charval[i] == 'f') { /* (try to)switch on opl3 fm synth */ if(initfm()) soundflag = soundflag | 16; else soundflag = (soundflag & 0xEF); } else if (charval[i] == 'p') soundflag = soundflag | 8; else if (charval[i] == 'm') soundflag = soundflag | 32; else if (charval[i] == 'q') soundflag = soundflag | 64; else goto badarg; } /* end for */ } /* end totparms > 1 */ return 0; } if (far_strcmp(variable,s_hertz) == 0) { /* Hertz=? */ basehertz = numval; return 0; } if (far_strcmp(variable,s_volume) == 0) { /* Volume =? */ fm_vol = numval & 0x3F; /* 63 */ return 0; } if (far_strcmp(variable,s_atten) == 0) { if (charval[0] == 'n') hi_atten = 0; else if (charval[0] == 'l') hi_atten = 1; else if (charval[0] == 'm') hi_atten = 2; else if (charval[0] == 'h') hi_atten = 3; else goto badarg; return 0; } if(far_strcmp(variable,s_polyphony) == 0) { if (numval > 9) goto badarg; polyphony = abs(numval-1); return(0); } if(far_strcmp(variable,s_wavetype) == 0) { /* wavetype = ? */ fm_wavetype = numval & 0x0F; return(0); } if(far_strcmp(variable,s_attack) == 0) { /* attack = ? */ fm_attack = numval & 0x0F; return(0); } if(far_strcmp(variable,s_decay) == 0) { /* decay = ? */ fm_decay = numval & 0x0F; return(0); } if(far_strcmp(variable,s_sustain) == 0) { /* sustain = ? */ fm_sustain = numval & 0x0F; return(0); } if(far_strcmp(variable,s_srelease) == 0) { /* release = ? */ fm_release = numval & 0x0F; return(0); } if (far_strcmp(variable,s_scalemap) == 0) { /* Scalemap=?,?,?,?,?,?,?,?,?,?,? */ int counter; if (totparms != intparms) goto badarg; for(counter=0;counter <=11;counter++) if ((totparms > counter) && (intval[counter] > 0) && (intval[counter] < 13)) scale_map[counter] = intval[counter]; #endif return(0); } if (far_strcmp(variable,s_periodicity) == 0 ) { /* periodicity=? */ usr_periodicitycheck=1; if ((charval[0] == 'n') || (numval == 0)) usr_periodicitycheck=0; else if (charval[0] == 'y') usr_periodicitycheck=1; else if (charval[0] == 's') /* 's' for 'show' */ usr_periodicitycheck= -1; else if(numval == NONNUMERIC) goto badarg; else if(numval != 0) usr_periodicitycheck=numval; if (usr_periodicitycheck > 255) usr_periodicitycheck = 255; if (usr_periodicitycheck < -255) usr_periodicitycheck = -255; return 1; } if (far_strcmp(variable,s_logmap) == 0 ) { /* logmap=? */ Log_Auto_Calc = 0; /* turn this off if loading a PAR */ if (charval[0] == 'y') LogFlag = 1; /* palette is logarithmic */ else if (charval[0] == 'n') LogFlag = 0; else if (charval[0] == 'o') LogFlag = -1; /* old log palette */ else LogFlag = (long)floatval[0]; return 1; } if (far_strcmp(variable,s_logmode) == 0 ) { /* logmode=? */ Log_Fly_Calc = 0; /* turn off if error */ Log_Auto_Calc = 0; if (charval[0] == 'f') Log_Fly_Calc = 1; /* calculate on the fly */ else if (charval[0] == 't') Log_Fly_Calc = 2; /* force use of LogTable */ else if (charval[0] == 'a') { Log_Auto_Calc = 1; /* force auto calc of logmap */ } else goto badarg; return 1; } if (far_strcmp(variable,s_debugflag) == 0 || far_strcmp(variable,s_debug) == 0) { /* internal use only */ debugflag = numval; timerflag = debugflag & 1; /* separate timer flag */ debugflag -= timerflag; return 0; } if (far_strcmp(variable,s_rseed) == 0) { rseed = numval; rflag = 1; return 1; } if (far_strcmp(variable,s_orbitdelay) == 0) { orbit_delay = numval; return 0; } if (far_strcmp(variable,s_orbitinterval) == 0) { orbit_interval = numval; if (orbit_interval < 1) orbit_interval = 1; if (orbit_interval > 255) orbit_interval = 255; return 0; } if (far_strcmp(variable,s_showdot) == 0) { showdot = 15; if(totparms > 0) { autoshowdot = (char)0; if(isalpha(charval[0])) { if(strchr("abdm",(int)charval[0]) != NULL) autoshowdot = charval[0]; else goto badarg; } else { showdot=numval; if(showdot<0) showdot=-1; } if(totparms > 1 && intparms > 0) sizedot = intval[1]; if(sizedot < 0) sizedot = 0; } return 0; } if (far_strcmp(variable,s_showorbit) == 0) { /* showorbit=yes|no */ start_showorbit=(char)yesnoval[0]; return 0; } if (far_strcmp(variable,s_decomp) == 0) { if (totparms != intparms || totparms < 1) goto badarg; decomp[0] = intval[0]; decomp[1] = 0; if (totparms > 1) /* backward compatibility */ bailout = decomp[1] = intval[1]; return 1; } if (far_strcmp(variable,s_distest) == 0) { if (totparms != intparms || totparms < 1) goto badarg; usr_distest = (long)floatval[0]; distestwidth = 71; if (totparms > 1) distestwidth = intval[1]; if(totparms > 3 && intval[2] > 0 && intval[3] > 0) { pseudox = intval[2]; pseudoy = intval[3]; } else pseudox = pseudoy = 0; return 1; } if (far_strcmp(variable,s_formulafile) == 0) { /* formulafile=? */ if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if(merge_pathnames(FormFileName, value, mode)<0) init_msg(0,variable,value,mode); return 1; } if (far_strcmp(variable,s_formulaname) == 0) { /* formulaname=? */ if (valuelen > ITEMNAMELEN) goto badarg; strcpy(FormName,value); return 1; } if (far_strcmp(variable,s_lfile) == 0) { /* lfile=? */ if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if(merge_pathnames(LFileName, value, mode)<0) init_msg(0,variable,value,mode); return 1; } if (far_strcmp(variable,s_lname) == 0) { if (valuelen > ITEMNAMELEN) goto badarg; strcpy(LName,value); return 1; } if (far_strcmp(variable,s_ifsfile) == 0) { /* ifsfile=?? */ int existdir; if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if((existdir=merge_pathnames(IFSFileName, value, mode))==0) reset_ifs_defn(); else if(existdir < 0) init_msg(0,variable,value,mode); return 1; } if (far_strcmp(variable,s_ifs) == 0 || far_strcmp(variable,s_ifs3d) == 0) { /* ifs3d for old time's sake */ if (valuelen > ITEMNAMELEN) goto badarg; strcpy(IFSName,value); reset_ifs_defn(); return 1; } if (far_strcmp(variable,s_parmfile) == 0) { /* parmfile=? */ if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if(merge_pathnames(CommandFile, value, mode)<0) init_msg(0,variable,value,mode); return 1; } if (far_strcmp(variable,s_stereo) == 0) { /* stereo=? */ if ((numval<0) || (numval>4)) goto badarg; glassestype = numval; return 3; } if (far_strcmp(variable,s_rotation) == 0) { /* rotation=?/?/? */ if (totparms != 3 || intparms != 3) goto badarg; XROT = intval[0]; YROT = intval[1]; ZROT = intval[2]; return 3; } if (far_strcmp(variable,s_perspective) == 0) { /* perspective=? */ if (numval == NONNUMERIC) goto badarg; ZVIEWER = numval; return 3; } if (far_strcmp(variable,s_xyshift) == 0) { /* xyshift=?/? */ if (totparms != 2 || intparms != 2) goto badarg; XSHIFT = intval[0]; YSHIFT = intval[1]; return 3; } if (far_strcmp(variable,s_interocular) == 0) { /* interocular=? */ eyeseparation = numval; return 3; } if (far_strcmp(variable,s_converge) == 0) { /* converg=? */ xadjust = numval; return 3; } if (far_strcmp(variable,s_crop) == 0) { /* crop=? */ if (totparms != 4 || intparms != 4 || intval[0] < 0 || intval[0] > 100 || intval[1] < 0 || intval[1] > 100 || intval[2] < 0 || intval[2] > 100 || intval[3] < 0 || intval[3] > 100) goto badarg; red_crop_left = intval[0]; red_crop_right = intval[1]; blue_crop_left = intval[2]; blue_crop_right = intval[3]; return 3; } if (far_strcmp(variable,s_bright) == 0) { /* bright=? */ if (totparms != 2 || intparms != 2) goto badarg; red_bright = intval[0]; blue_bright = intval[1]; return 3; } if (far_strcmp(variable,s_xyadjust) == 0) { /* trans=? */ if (totparms != 2 || intparms != 2) goto badarg; xtrans = intval[0]; ytrans = intval[1]; return 3; } if (far_strcmp(variable,s_3d) == 0) { /* 3d=?/?/.. */ if(far_strcmp(value,s_overlay)==0) { yesnoval[0]=1; if(calc_status > -1) /* if no image, treat same as 3D=yes */ overlay3d=1; } else if (yesnoval[0] < 0) goto badarg; display3d = yesnoval[0]; initvars_3d(); return (display3d) ? 6 : 2; } if (far_strcmp(variable,s_sphere) == 0 ) { /* sphere=? */ if (yesnoval[0] < 0) goto badarg; SPHERE = yesnoval[0]; return 2; } if (far_strcmp(variable,s_scalexyz) == 0) { /* scalexyz=?/?/? */ if (totparms < 2 || intparms != totparms) goto badarg; XSCALE = intval[0]; YSCALE = intval[1]; if (totparms > 2) ROUGH = intval[2]; return 2; } /* "rough" is really scale z, but we add it here for convenience */ if (far_strcmp(variable,s_roughness) == 0) { /* roughness=? */ ROUGH = numval; return 2; } if (far_strcmp(variable,s_waterline) == 0) { /* waterline=? */ if (numval<0) goto badarg; WATERLINE = numval; return 2; } if (far_strcmp(variable,s_filltype) == 0) { /* filltype=? */ if (numval < -1 || numval > 6) goto badarg; FILLTYPE = numval; return 2; } if (far_strcmp(variable,s_lightsource) == 0) { /* lightsource=?/?/? */ if (totparms != 3 || intparms != 3) goto badarg; XLIGHT = intval[0]; YLIGHT = intval[1]; ZLIGHT = intval[2]; return 2; } if (far_strcmp(variable,s_smoothing) == 0) { /* smoothing=? */ if (numval<0) goto badarg; LIGHTAVG = numval; return 2; } if (far_strcmp(variable,s_latitude) == 0) { /* latitude=?/? */ if (totparms != 2 || intparms != 2) goto badarg; THETA1 = intval[0]; THETA2 = intval[1]; return 2; } if (far_strcmp(variable,s_longitude) == 0) { /* longitude=?/? */ if (totparms != 2 || intparms != 2) goto badarg; PHI1 = intval[0]; PHI2 = intval[1]; return 2; } if (far_strcmp(variable,s_radius) == 0) { /* radius=? */ if (numval < 0) goto badarg; RADIUS = numval; return 2; } if (far_strcmp(variable,s_transparent) == 0) { /* transparent? */ if (totparms != intparms || totparms < 1) goto badarg; transparent[1] = transparent[0] = intval[0]; if (totparms > 1) transparent[1] = intval[1]; return 2; } if (far_strcmp(variable,s_preview) == 0) { /* preview? */ if (yesnoval[0] < 0) goto badarg; preview = (char)yesnoval[0]; return 2; } if (far_strcmp(variable,s_showbox) == 0) { /* showbox? */ if (yesnoval[0] < 0) goto badarg; showbox = (char)yesnoval[0]; return 2; } if (far_strcmp(variable,s_coarse) == 0) { /* coarse=? */ if (numval < 3 || numval > 2000) goto badarg; previewfactor = numval; return 2; } if (far_strcmp(variable,s_randomize) == 0) { /* RANDOMIZE=? */ if (numval<0 || numval>7) goto badarg; RANDOMIZE = numval; return 2; } if (far_strcmp(variable,s_ambient) == 0) { /* ambient=? */ if (numval<0||numval>100) goto badarg; Ambient = numval; return 2; } if (far_strcmp(variable,s_haze) == 0) { /* haze=? */ if (numval<0||numval>100) goto badarg; haze = numval; return 2; } if (far_strcmp(variable,s_fullcolor) == 0) { /* fullcolor=? */ if (yesnoval[0] < 0) goto badarg; Targa_Out = yesnoval[0]; return 2; } if (far_strcmp(variable,s_truecolor) == 0) { /* truecolor=? */ if (yesnoval[0] < 0) goto badarg; truecolor = yesnoval[0]; return 3; } if (far_strcmp(variable,s_truemode) == 0) { /* truemode=? */ truemode = 0; /* use default if error */ if (charval[0] == 'd') truemode = 0; /* use default color output */ if (charval[0] == 'i' || intval[0] == 1) truemode = 1; /* use iterates output */ if (intval[0] == 2) truemode = 2; if (intval[0] == 3) truemode = 3; return 3; } if (far_strcmp(variable,s_usegrayscale) == 0) { /* usegrayscale? */ if (yesnoval[0] < 0) goto badarg; grayflag = (char)yesnoval[0]; return 2; } if (far_strcmp(variable,s_monitorwidth) == 0) { /* monitorwidth=? */ if (totparms != 1 || floatparms != 1) goto badarg; AutoStereo_width = floatval[0]; return 2; } if (far_strcmp(variable,s_targa_overlay) == 0) { /* Targa Overlay? */ if (yesnoval[0] < 0) goto badarg; Targa_Overlay = yesnoval[0]; return 2; } if (far_strcmp(variable,s_background) == 0) { /* background=?/? */ if (totparms != 3 || intparms != 3) goto badarg; for (i=0;i<3;i++) if (intval[i] & ~0xff) goto badarg; back_color[0] = (BYTE)intval[0]; back_color[1] = (BYTE)intval[1]; back_color[2] = (BYTE)intval[2]; return 2; } if (far_strcmp(variable,s_lightname) == 0) { /* lightname=? */ if (valuelen > (FILE_MAX_PATH-1)) goto badarg; if (first_init || mode == 2) strcpy(light_name,value); return 0; } if (far_strcmp(variable,s_ray) == 0) { /* RAY=? */ if (numval < 0 || numval > 6) goto badarg; RAY = numval; return 2; } if (far_strcmp(variable,s_brief) == 0) { /* BRIEF? */ if (yesnoval[0] < 0) goto badarg; BRIEF = yesnoval[0]; return 2; } if (far_strcmp(variable,s_release) == 0) { /* release */ if (numval < 0) goto badarg; save_release = numval; return 2; } if (far_strcmp(variable,s_curdir) == 0) { /* curdir= */ if (yesnoval[0] < 0) goto badarg; checkcurdir = yesnoval[0]; return 0; } if (far_strcmp(variable,s_virtual) == 0) { /* virtual= */ if (yesnoval[0] < 0) goto badarg; virtual = yesnoval[0]; return 1; } badarg: argerror(curarg); return(-1); } #ifdef _MSC_VER #if (_MSC_VER >= 600) #pragma optimize( "el", on ) #endif #endif /* Some routines broken out of above so compiler doesn't run out of heap: */ static void parse_textcolors(char *value) { int i,j,k,hexval; if (far_strcmp(value,s_mono) == 0) { for (k = 0; k < sizeof(txtcolor); ++k) txtcolor[k] = BLACK*16+WHITE; /* C_HELP_CURLINK = C_PROMPT_INPUT = C_CHOICE_CURRENT = C_GENERAL_INPUT = C_AUTHDIV1 = C_AUTHDIV2 = WHITE*16+BLACK; */ txtcolor[6] = txtcolor[12] = txtcolor[13] = txtcolor[14] = txtcolor[20] = txtcolor[27] = txtcolor[28] = WHITE*16+BLACK; /* C_TITLE = C_HELP_HDG = C_HELP_LINK = C_PROMPT_HI = C_CHOICE_SP_KEYIN = C_GENERAL_HI = C_DVID_HI = C_STOP_ERR = C_STOP_INFO = BLACK*16+L_WHITE; */ txtcolor[0] = txtcolor[2] = txtcolor[5] = txtcolor[11] = txtcolor[16] = txtcolor[17] = txtcolor[22] = txtcolor[24] = txtcolor[25] = BLACK*16+L_WHITE; } else { k = 0; while ( k < sizeof(txtcolor)) { if (*value == 0) break; if (*value != '/') { sscanf(value,"%x",&hexval); i = (hexval / 16) & 7; j = hexval & 15; if (i == j || (i == 0 && j == 8)) /* force contrast */ j = 15; txtcolor[k] = (BYTE)(i * 16 + j); if ((value = strchr(value,'/')) == NULL) break; } ++value; ++k; } } } static int parse_colors(char *value) { int i,j,k; if (*value == '@') { char temp_name[MAX_NAME]; strncpy(temp_name,&value[1],MAX_NAME); temp_name[MAX_NAME-1] = 0; if(merge_pathnames(MAP_name,temp_name,3)<0) init_msg(0,"",temp_name,3); if ((int)strlen(value) > FILE_MAX_PATH || ValidateLuts(MAP_name) != 0) goto badcolor; if (display3d) { mapset = 1; } else { if(merge_pathnames(colorfile,temp_name,3)<0) init_msg(0,"",temp_name,3); colorstate = 2; } } else { int smooth; i = smooth = 0; while (*value) { if (i >= 256) goto badcolor; if (*value == '<') { if (i == 0 || smooth || (smooth = atoi(value+1)) < 2 || (value = strchr(value,'>')) == NULL) goto badcolor; i += smooth; ++value; } else { for (j = 0; j < 3; ++j) { if ((k = *(value++)) < '0') goto badcolor; else if (k <= '9') k -= '0'; else if (k < 'A') goto badcolor; else if (k <= 'Z') k -= ('A'-10); else if (k < '_' || k > 'z') goto badcolor; else k -= ('_'-36); dacbox[i][j] = (BYTE)k; if (smooth) { int start,spread,cnum; start = i - (spread = smooth + 1); cnum = 0; if ((k - (int)dacbox[start][j]) == 0) { while (++cnum < spread) dacbox[start+cnum][j] = (BYTE)k; } else { while (++cnum < spread) dacbox[start+cnum][j] = (BYTE)(( cnum *dacbox[i][j] + (i-(start+cnum))*dacbox[start][j] + spread/2 ) / (BYTE) spread); } } } smooth = 0; ++i; } } if (smooth) goto badcolor; while (i < 256) { /* zap unset entries */ dacbox[i][0] = dacbox[i][1] = dacbox[i][2] = 40; ++i; } if (colorstate == 2) /* read in map name, but it is rotated */ colorstate = 3; else colorstate = 1; } colorpreloaded = 1; memcpy(olddacbox,dacbox,256*3); return(0); badcolor: return(-1); } static int parse_printer(char *value) { int k; if (value[0]=='h' && value[1]=='p') Printer_Type=1; /* HP LaserJet */ if (value[0]=='i' && value[1]=='b') Printer_Type=2; /* IBM Graphics */ if (value[0]=='e' && value[1]=='p') Printer_Type=2; /* Epson (model?) */ if (value[0]=='c' && value[1]=='o') Printer_Type=3; /* Star (Epson-Comp?) color */ if (value[0]=='p') { if (value[1]=='a') Printer_Type=4; /* HP Paintjet (color) */ if ((value[1]=='o' || value[1]=='s')) { Printer_Type=5; /* PostScript SWT */ if (value[2]=='h' || value[2]=='l') Printer_Type=6; } if (value[1]=='l') Printer_Type=7; /* HP Plotter (semi-color) */ } if (Printer_Type == 1) /* assume low resolution */ Printer_Resolution = 75; else Printer_Resolution = 60; if (EPSFileType > 0) /* EPS save - force type 5 */ Printer_Type = 5; if ((Printer_Type == 5) || (Printer_Type == 6)) Printer_Resolution = 150; /* PostScript def. res. */ if ((value=strchr(value,'/')) != NULL) { if ((k=atoi(++value)) >= 0) Printer_Resolution=k; if ((value=strchr(value,'/')) != NULL) { if ((k=atoi(++value))> 0) LPTNumber = k; if (k < 0) { Print_To_File = 1; LPTNumber = 1; } } } return(0); } static void argerror(char *badarg) /* oops. couldn't decode this */ { static FCODE argerrmsg1[]={"\ Oops. I couldn't understand the argument:\n "}; static FCODE argerrmsg2[]={"\n\n\ (see the Startup Help screens or documentation for a complete\n\ argument list with descriptions)"}; char msg[300]; if ((int)strlen(badarg) > 70) badarg[70] = 0; if (active_system == 0 /* DOS */ && first_init) /* & this is 1st call to cmdfiles */ #ifndef XFRACT sprintf(msg,"%Fs%s%Fs",(char far *)argerrmsg1,badarg,(char far *)argerrmsg2); else sprintf(msg,"%Fs%s",(char far *)argerrmsg1,badarg); #else sprintf(msg,"%s%s%s",argerrmsg1,badarg,argerrmsg2); else sprintf(msg,"%s%s",argerrmsg1,badarg); #endif stopmsg(0,msg); if (initbatch) { initbatch = 4; goodbye(); } } void set_3d_defaults() { ROUGH = 30; WATERLINE = 0; ZVIEWER = 0; XSHIFT = 0; YSHIFT = 0; xtrans = 0; ytrans = 0; LIGHTAVG = 0; Ambient = 20; RANDOMIZE = 0; haze = 0; back_color[0] = 51; back_color[1] = 153; back_color[2] = 200; if(SPHERE) { PHI1 = 180; PHI2 = 0; THETA1 = -90; THETA2 = 90; RADIUS = 100; FILLTYPE = 2; XLIGHT = 1; YLIGHT = 1; ZLIGHT = 1; } else { XROT = 60; YROT = 30; ZROT = 0; XSCALE = 90; YSCALE = 90; FILLTYPE = 0; if (active_system != 0) FILLTYPE = 2; XLIGHT = 1; YLIGHT = -1; ZLIGHT = 1; } } /* copy a big number from a string, up to slash */ static int get_bf(bf_t bf, char *curarg) { char *s; s=strchr(curarg,'/'); if(s) *s = 0; strtobf(bf,curarg); if(s) *s = '/'; return(0); } /* Get length of current args */ int get_curarg_len(char *curarg) { int len; char *s; s=strchr(curarg,'/'); if(s) *s = 0; len = strlen(curarg); if(s) *s = '/'; return(len); } /* Get max length of current args */ int get_max_curarg_len(char *floatvalstr[], int totparms) { int i,tmp,max_str; max_str = 0; for(i=0;i max_str) max_str = tmp; return(max_str); } /* mode = 0 command line @filename */ /* 1 sstools.ini */ /* 2 <@> command after startup */ /* 3 command line @filename/setname */ /* this is like stopmsg() but can be used in cmdfiles() */ /* call with NULL for badfilename to get pause for getakey() */ int init_msg(int flags,char *cmdstr,char far *badfilename,int mode) { char far *modestr[4] = {s_commandline,s_sstoolsini,s_at_cmd,s_at_cmd}; static FCODE diags[] = {"Fractint found the following problems when parsing commands: "}; char msg[256]; char cmd[80]; static int row = 1; if (initbatch == 1) { /* in batch mode */ if(badfilename) /* uncomment next if wish to cause abort in batch mode for errors in CMDFILES.C such as parsing SSTOOLS.INI */ /* initbatch = 4; */ /* used to set errorlevel */ return (-1); } strncpy(cmd,cmdstr,30); cmd[29] = 0; if(*cmd) strcat(cmd,"="); if(badfilename) #ifndef XFRACT sprintf(msg,"Can't find %s%Fs, please check %Fs",cmd,badfilename,modestr[mode]); #else sprintf(msg,"Can't find %s%s, please check %s",cmd,badfilename,modestr[mode]); #endif if (active_system == 0 /* DOS */ && first_init) { /* & cmdfiles hasn't finished 1st try */ if(row == 1 && badfilename) { setvideotext(); putstring(0,0,15,diags); } if(badfilename) putstring(row++,0,7,msg); else if(row > 1){ putstring(++row,0,15,s_escapetoabort); movecursor(row+1,0); /* if(getakeynohelp()==27) goodbye(); */ dopause(2); /* defer getakeynohelp until after parseing */ } } else if(badfilename) stopmsg(flags,msg); return(0); } /* defer pause until after parsing so we know if in batch mode */ void dopause(int action) { static unsigned char needpause = 0; switch(action) { case 0: if(initbatch == 0) { if(needpause == 1) getakey(); else if (needpause == 2) if(getakeynohelp() == ESC) goodbye(); } needpause = 0; break; case 1: case 2: needpause = (char)action; break; default: break; } } /* Crude function to detect a floating point number. Intended for use with arbitrary precision. */ static int isabigfloat(char *str) { /* [+|-]numbers][.]numbers[+|-][e|g]numbers */ int result=1; char *s = str; int numdot=0; int nume=0; int numsign=0; while(*s != 0 && *s != '/' && *s != ' ') { if(*s == '-' || *s == '+') numsign++; else if(*s == '.') numdot++; else if(*s == 'e' || *s == 'E' || *s == 'g' || *s == 'G') nume++; else if(!isdigit(*s)) {result=0; break;} s++; } if(numdot > 1 || numsign > 2 || nume > 1) result=0; return(result); } xfractint-20.4.10.orig/common/frasetup.c0000644000000000000000000010744010150633601014773 0ustar #include #include #ifdef __TURBOC__ #include #elif !defined(__386BSD__) #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #include "fractype.h" #ifndef XFRACT #define MPCmod(m) (*pMPadd(*pMPmul((m).x, (m).x), *pMPmul((m).y, (m).y))) #endif /* -------------------------------------------------------------------- */ /* Setup (once per fractal image) routines */ /* -------------------------------------------------------------------- */ int MandelSetup(void) /* Mandelbrot Routine */ { if (debugflag != 90 && !invert && decomp[0] == 0 && rqlim == 4.0 && bitshift == 29 && potflag == 0 && biomorph == -1 && inside > -59 && outside >= -1 && useinitorbit != 1 && using_jiim == 0 && bailoutest == Mod && (orbitsave&2) == 0) calctype = calcmand; /* the normal case - use CALCMAND */ else { /* special case: use the main processing loop */ calctype = StandardFractal; longparm = &linit; } return(1); } int JuliaSetup(void) /* Julia Routine */ { if (debugflag != 90 && !invert && decomp[0] == 0 && rqlim == 4.0 && bitshift == 29 && potflag == 0 && biomorph == -1 && inside > -59 && outside >= -1 && !finattract && using_jiim == 0 && bailoutest == Mod && (orbitsave&2) == 0) calctype = calcmand; /* the normal case - use CALCMAND */ else { /* special case: use the main processing loop */ calctype = StandardFractal; longparm = &lparm; get_julia_attractor (0.0, 0.0); /* another attractor? */ } return(1); } int NewtonSetup(void) /* Newton/NewtBasin Routines */ { int i; #ifndef XFRACT if (debugflag != 1010) { if(fpu != 0) { if(fractype == MPNEWTON) fractype = NEWTON; else if(fractype == MPNEWTBASIN) fractype = NEWTBASIN; } else { if(fractype == NEWTON) fractype = MPNEWTON; else if(fractype == NEWTBASIN) fractype = MPNEWTBASIN; } curfractalspecific = &fractalspecific[fractype]; } #else if(fractype == MPNEWTON) fractype = NEWTON; else if(fractype == MPNEWTBASIN) fractype = NEWTBASIN; curfractalspecific = &fractalspecific[fractype]; #endif /* set up table of roots of 1 along unit circle */ degree = (int)parm.x; if(degree < 2) degree = 3; /* defaults to 3, but 2 is possible */ root = 1; /* precalculated values */ roverd = (double)root / (double)degree; d1overd = (double)(degree - 1) / (double)degree; maxcolor = 0; threshold = .3*PI/degree; /* less than half distance between roots */ #ifndef XFRACT if (fractype == MPNEWTON || fractype == MPNEWTBASIN) { mproverd = *pd2MP(roverd); mpd1overd = *pd2MP(d1overd); mpthreshold = *pd2MP(threshold); mpone = *pd2MP(1.0); } #endif floatmin = FLT_MIN; floatmax = FLT_MAX; basin = 0; if(roots != staticroots) { free(roots); roots = staticroots; } if (fractype==NEWTBASIN) { if(parm.y) basin = 2; /*stripes */ else basin = 1; if(degree > 16) { if((roots=(_CMPLX *)malloc(degree*sizeof(_CMPLX)))==NULL) { roots = staticroots; degree = 16; } } else roots = staticroots; /* list of roots to discover where we converged for newtbasin */ for(i=0;i 16) { if((MPCroots=(struct MPC *)malloc(degree*sizeof(struct MPC)))==NULL) { MPCroots = (struct MPC *)staticroots; degree = 16; } } else MPCroots = (struct MPC *)staticroots; /* list of roots to discover where we converged for newtbasin */ for(i=0;icalctype); return(0); /* effectively disable solid-guessing */ } int UnitySetup(void) { periodicitycheck = 0; FgOne = (1L << bitshift); FgTwo = FgOne + FgOne; return(1); } int MandelfpSetup(void) { bf_math = 0; c_exp = (int)param[2]; pwr.x = param[2] - 1.0; pwr.y = param[3]; floatparm = &init; switch (fractype) { case MARKSMANDELFP: if(c_exp < 1){ c_exp = 1; param[2] = 1; } if(!(c_exp & 1)) symmetry = XYAXIS_NOPARM; /* odd exponents */ if(c_exp & 1) symmetry = XAXIS_NOPARM; break; case MANDELFP: /* floating point code could probably be altered to handle many of the situations that otherwise are using StandardFractal(). calcmandfp() can currently handle invert, any rqlim, potflag zmag, epsilon cross, and all the current outside options Wes Loewer 11/03/91 Took out support for inside= options, for speed. 7/13/97 */ if (debugflag != 90 && !distest && decomp[0] == 0 && biomorph == -1 && (inside >= -1) /* uncomment this next line if more outside options are added */ && outside >= -6 && useinitorbit != 1 && (soundflag & 0x07) < 2 && using_jiim == 0 && bailoutest == Mod && (orbitsave&2) == 0) { calctype = calcmandfp; /* the normal case - use calcmandfp */ #ifndef XFRACT if (cpu >= 386 && fpu >= 387) { calcmandfpasmstart_p5(); calcmandfpasm = (long (*)(void))calcmandfpasm_p5; } else if (cpu == 286 && fpu >= 287) { calcmandfpasmstart(); calcmandfpasm = (long (*)(void))calcmandfpasm_287; } else { calcmandfpasmstart(); calcmandfpasm = (long (*)(void))calcmandfpasm_87; } #else { #ifdef NASM if (fpu == -1) { calcmandfpasmstart_p5(); calcmandfpasm = (long (*)(void))calcmandfpasm_p5; } else #endif { calcmandfpasmstart(); calcmandfpasm = (long (*)(void))calcmandfpasm_c; } } #endif } else { /* special case: use the main processing loop */ calctype = StandardFractal; } break; case FPMANDELZPOWER: if((double)c_exp == param[2] && (c_exp & 1)) /* odd exponents */ symmetry = XYAXIS_NOPARM; if(param[3] != 0) symmetry = NOSYM; if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2]) fractalspecific[fractype].orbitcalc = floatZpowerFractal; else fractalspecific[fractype].orbitcalc = floatCmplxZpowerFractal; break; case MAGNET1M: case MAGNET2M: attr[0].x = 1.0; /* 1.0 + 0.0i always attracts */ attr[0].y = 0.0; /* - both MAGNET1 and MAGNET2 */ attrperiod[0] = 1; attractors = 1; break; case SPIDERFP: if(periodicitycheck==1) /* if not user set */ periodicitycheck=4; break; case MANDELEXP: symmetry = XAXIS_NOPARM; break; /* Added to account for symmetry in manfn+exp and manfn+zsqrd */ /* JCO 2/29/92 */ case FPMANTRIGPLUSEXP: case FPMANTRIGPLUSZSQRD: if(parm.y == 0.0) symmetry = XAXIS; else symmetry = NOSYM; if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */ symmetry = NOSYM; break; case QUATFP: floatparm = &tmp; attractors = 0; periodicitycheck = 0; break; case HYPERCMPLXFP: floatparm = &tmp; attractors = 0; periodicitycheck = 0; if(param[2] != 0) symmetry = NOSYM; if(trigndx[0] == 14) /* FLIP */ symmetry = NOSYM; break; case TIMSERRORFP: if(trigndx[0] == 14) /* FLIP */ symmetry = NOSYM; break; case MARKSMANDELPWRFP: if(trigndx[0] == 14) /* FLIP */ symmetry = NOSYM; break; default: break; } return(1); } int JuliafpSetup(void) { c_exp = (int)param[2]; floatparm = &parm; if(fractype==COMPLEXMARKSJUL) { pwr.x = param[2] - 1.0; pwr.y = param[3]; coefficient = ComplexPower(*floatparm, pwr); } switch (fractype) { case JULIAFP: /* floating point code could probably be altered to handle many of the situations that otherwise are using StandardFractal(). calcmandfp() can currently handle invert, any rqlim, potflag zmag, epsilon cross, and all the current outside options Wes Loewer 11/03/91 Took out support for inside= options, for speed. 7/13/97 */ if (debugflag != 90 && !distest && decomp[0] == 0 && biomorph == -1 && (inside >= -1) /* uncomment this next line if more outside options are added */ && outside >= -6 && useinitorbit != 1 && (soundflag & 0x07) < 2 && !finattract && using_jiim == 0 && bailoutest == Mod && (orbitsave&2) == 0) { calctype = calcmandfp; /* the normal case - use calcmandfp */ #ifndef XFRACT if (cpu >= 386 && fpu >= 387) { calcmandfpasmstart_p5(); calcmandfpasm = (long (*)(void))calcmandfpasm_p5; } else if (cpu == 286 && fpu >= 287) { calcmandfpasmstart(); calcmandfpasm = (long (*)(void))calcmandfpasm_287; } else { calcmandfpasmstart(); calcmandfpasm = (long (*)(void))calcmandfpasm_87; } #else { #ifdef NASM if (fpu == -1) { calcmandfpasmstart_p5(); calcmandfpasm = (long (*)(void))calcmandfpasm_p5; } else #endif { calcmandfpasmstart(); calcmandfpasm = (long (*)(void))calcmandfpasm_c; } } #endif } else { /* special case: use the main processing loop */ calctype = StandardFractal; get_julia_attractor (0.0, 0.0); /* another attractor? */ } break; case FPJULIAZPOWER: if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] ) symmetry = NOSYM; if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2]) fractalspecific[fractype].orbitcalc = floatZpowerFractal; else fractalspecific[fractype].orbitcalc = floatCmplxZpowerFractal; get_julia_attractor (param[0], param[1]); /* another attractor? */ break; case MAGNET2J: FloatPreCalcMagnet2(); case MAGNET1J: attr[0].x = 1.0; /* 1.0 + 0.0i always attracts */ attr[0].y = 0.0; /* - both MAGNET1 and MAGNET2 */ attrperiod[0] = 1; attractors = 1; get_julia_attractor (0.0, 0.0); /* another attractor? */ break; case LAMBDAFP: get_julia_attractor (0.0, 0.0); /* another attractor? */ get_julia_attractor (0.5, 0.0); /* another attractor? */ break; case LAMBDAEXP: if(parm.y == 0.0) symmetry=XAXIS; get_julia_attractor (0.0, 0.0); /* another attractor? */ break; /* Added to account for symmetry in julfn+exp and julfn+zsqrd */ /* JCO 2/29/92 */ case FPJULTRIGPLUSEXP: case FPJULTRIGPLUSZSQRD: if(parm.y == 0.0) symmetry = XAXIS; else symmetry = NOSYM; if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */ symmetry = NOSYM; get_julia_attractor (0.0, 0.0); /* another attractor? */ break; case HYPERCMPLXJFP: if(param[2] != 0) symmetry = NOSYM; if(trigndx[0] != SQR) symmetry=NOSYM; case QUATJULFP: attractors = 0; /* attractors broken since code checks r,i not j,k */ periodicitycheck = 0; if(param[4] != 0.0 || param[5] != 0) symmetry = NOSYM; break; case FPPOPCORN: case FPPOPCORNJUL: { int default_functions = 0; if(trigndx[0] == SIN && trigndx[1] == TAN && trigndx[2] == SIN && trigndx[3] == TAN && fabs(parm2.x - 3.0) < .0001 && parm2.y == 0 && parm.y == 0) { default_functions = 1; if(fractype == FPPOPCORNJUL) symmetry = ORIGIN; } if(save_release <=1960) curfractalspecific->orbitcalc = PopcornFractal_Old; else if(default_functions && debugflag == 96) curfractalspecific->orbitcalc = PopcornFractal; else curfractalspecific->orbitcalc = PopcornFractalFn; get_julia_attractor (0.0, 0.0); /* another attractor? */ } break; case FPCIRCLE: if (inside == STARTRAIL) /* FPCIRCLE locks up when used with STARTRAIL */ inside = 0; /* arbitrarily set inside = NUMB */ get_julia_attractor (0.0, 0.0); /* another attractor? */ break; default: get_julia_attractor (0.0, 0.0); /* another attractor? */ break; } return(1); } int MandellongSetup(void) { FgHalf = fudge >> 1; c_exp = (int)param[2]; if(fractype==MARKSMANDEL && c_exp < 1){ c_exp = 1; param[2] = 1; } if((fractype==MARKSMANDEL && !(c_exp & 1)) || (fractype==LMANDELZPOWER && (c_exp & 1))) symmetry = XYAXIS_NOPARM; /* odd exponents */ if((fractype==MARKSMANDEL && (c_exp & 1)) || fractype==LMANDELEXP) symmetry = XAXIS_NOPARM; if(fractype==SPIDER && periodicitycheck==1) periodicitycheck=4; longparm = &linit; if(fractype==LMANDELZPOWER) { if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2]) fractalspecific[fractype].orbitcalc = longZpowerFractal; else fractalspecific[fractype].orbitcalc = longCmplxZpowerFractal; if(param[3] != 0 || (double)c_exp != param[2] ) symmetry = NOSYM; } /* Added to account for symmetry in manfn+exp and manfn+zsqrd */ /* JCO 2/29/92 */ if((fractype==LMANTRIGPLUSEXP)||(fractype==LMANTRIGPLUSZSQRD)) { if(parm.y == 0.0) symmetry = XAXIS; else symmetry = NOSYM; if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */ symmetry = NOSYM; } if(fractype == TIMSERROR) { if(trigndx[0] == 14) /* FLIP */ symmetry = NOSYM; } if(fractype == MARKSMANDELPWR) { if(trigndx[0] == 14) /* FLIP */ symmetry = NOSYM; } return(1); } int JulialongSetup(void) { c_exp = (int)param[2]; longparm = &lparm; switch (fractype) { case LJULIAZPOWER: if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2]) symmetry = NOSYM; if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2]) fractalspecific[fractype].orbitcalc = longZpowerFractal; else fractalspecific[fractype].orbitcalc = longCmplxZpowerFractal; break; case LAMBDA: get_julia_attractor (0.0, 0.0); /* another attractor? */ get_julia_attractor (0.5, 0.0); /* another attractor? */ break; case LLAMBDAEXP: if(lparm.y == 0) symmetry = XAXIS; break; /* Added to account for symmetry in julfn+exp and julfn+zsqrd */ /* JCO 2/29/92 */ case LJULTRIGPLUSEXP: case LJULTRIGPLUSZSQRD: if(parm.y == 0.0) symmetry = XAXIS; else symmetry = NOSYM; if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */ symmetry = NOSYM; get_julia_attractor (0.0, 0.0); /* another attractor? */ break; case LPOPCORN: case LPOPCORNJUL: { int default_functions = 0; if(trigndx[0] == SIN && trigndx[1] == TAN && trigndx[2] == SIN && trigndx[3] == TAN && fabs(parm2.x - 3.0) < .0001 && parm2.y == 0 && parm.y == 0) { default_functions = 1; if(fractype == LPOPCORNJUL) symmetry = ORIGIN; } if(save_release <=1960) curfractalspecific->orbitcalc = LPopcornFractal_Old; else if(default_functions && debugflag == 96) curfractalspecific->orbitcalc = LPopcornFractal; else curfractalspecific->orbitcalc = LPopcornFractalFn; get_julia_attractor (0.0, 0.0); /* another attractor? */ } break; default: get_julia_attractor (0.0, 0.0); /* another attractor? */ break; } return(1); } int TrigPlusSqrlongSetup(void) { curfractalspecific->per_pixel = julia_per_pixel; curfractalspecific->orbitcalc = TrigPlusSqrFractal; if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90) { if(lparm2.x == fudge) /* Scott variant */ curfractalspecific->orbitcalc = ScottTrigPlusSqrFractal; else if(lparm2.x == -fudge) /* Skinner variant */ curfractalspecific->orbitcalc = SkinnerTrigSubSqrFractal; } return(JulialongSetup()); } int TrigPlusSqrfpSetup(void) { curfractalspecific->per_pixel = juliafp_per_pixel; curfractalspecific->orbitcalc = TrigPlusSqrfpFractal; if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90) { if(parm2.x == 1.0) /* Scott variant */ curfractalspecific->orbitcalc = ScottTrigPlusSqrfpFractal; else if(parm2.x == -1.0) /* Skinner variant */ curfractalspecific->orbitcalc = SkinnerTrigSubSqrfpFractal; } return(JuliafpSetup()); } int TrigPlusTriglongSetup(void) { FnPlusFnSym(); if(trigndx[1] == SQR) return(TrigPlusSqrlongSetup()); curfractalspecific->per_pixel = long_julia_per_pixel; curfractalspecific->orbitcalc = TrigPlusTrigFractal; if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90) { if(lparm2.x == fudge) /* Scott variant */ curfractalspecific->orbitcalc = ScottTrigPlusTrigFractal; else if(lparm2.x == -fudge) /* Skinner variant */ curfractalspecific->orbitcalc = SkinnerTrigSubTrigFractal; } return(JulialongSetup()); } int TrigPlusTrigfpSetup(void) { FnPlusFnSym(); if(trigndx[1] == SQR) return(TrigPlusSqrfpSetup()); curfractalspecific->per_pixel = otherjuliafp_per_pixel; curfractalspecific->orbitcalc = TrigPlusTrigfpFractal; if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90) { if(parm2.x == 1.0) /* Scott variant */ curfractalspecific->orbitcalc = ScottTrigPlusTrigfpFractal; else if(parm2.x == -1.0) /* Skinner variant */ curfractalspecific->orbitcalc = SkinnerTrigSubTrigfpFractal; } return(JuliafpSetup()); } int FnPlusFnSym(void) /* set symmetry matrix for fn+fn type */ { static char far fnplusfn[7][7] = {/* fn2 ->sin cos sinh cosh exp log sqr */ /* fn1 */ /* sin */ {PI_SYM,XAXIS, XYAXIS, XAXIS, XAXIS, XAXIS, XAXIS}, /* cos */ {XAXIS, PI_SYM,XAXIS, XYAXIS,XAXIS, XAXIS, XAXIS}, /* sinh*/ {XYAXIS,XAXIS, XYAXIS, XAXIS, XAXIS, XAXIS, XAXIS}, /* cosh*/ {XAXIS, XYAXIS,XAXIS, XYAXIS,XAXIS, XAXIS, XAXIS}, /* exp */ {XAXIS, XYAXIS,XAXIS, XAXIS, XYAXIS,XAXIS, XAXIS}, /* log */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XAXIS}, /* sqr */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, XYAXIS} }; if(parm.y == 0.0 && parm2.y == 0.0) { if(trigndx[0] < 7 && trigndx[1] < 7) /* bounds of array JCO 5/6/92*/ symmetry = fnplusfn[trigndx[0]][trigndx[1]]; /* JCO 5/6/92 */ if(trigndx[0] == 14 || trigndx[1] == 14) /* FLIP */ symmetry = NOSYM; } /* defaults to XAXIS symmetry JCO 5/6/92 */ else symmetry = NOSYM; return(0); } int LambdaTrigOrTrigSetup(void) { /* default symmetry is ORIGIN JCO 2/29/92 (changed from PI_SYM) */ longparm = &lparm; /* added to consolidate code 10/1/92 JCO */ floatparm = &parm; if ((trigndx[0] == EXP) || (trigndx[1] == EXP)) symmetry = NOSYM; /* JCO 1/9/93 */ if ((trigndx[0] == LOG) || (trigndx[1] == LOG)) symmetry = XAXIS; get_julia_attractor (0.0, 0.0); /* an attractor? */ return(1); } int JuliaTrigOrTrigSetup(void) { /* default symmetry is XAXIS */ longparm = &lparm; /* added to consolidate code 10/1/92 JCO */ floatparm = &parm; if(parm.y != 0.0) symmetry = NOSYM; if(trigndx[0] == 14 || trigndx[1] == 14) /* FLIP */ symmetry = NOSYM; get_julia_attractor (0.0, 0.0); /* an attractor? */ return(1); } int ManlamTrigOrTrigSetup(void) { /* psuedo */ /* default symmetry is XAXIS */ longparm = &linit; /* added to consolidate code 10/1/92 JCO */ floatparm = &init; if (trigndx[0] == SQR) symmetry = NOSYM; if ((trigndx[0] == LOG) || (trigndx[1] == LOG)) symmetry = NOSYM; return(1); } int MandelTrigOrTrigSetup(void) { /* default symmetry is XAXIS_NOPARM */ longparm = &linit; /* added to consolidate code 10/1/92 JCO */ floatparm = &init; if ((trigndx[0] == 14) || (trigndx[1] == 14)) /* FLIP JCO 5/28/92 */ symmetry = NOSYM; return(1); } int ZXTrigPlusZSetup(void) { /* static char far ZXTrigPlusZSym1[] = */ /* fn1 -> sin cos sinh cosh exp log sqr */ /* {XAXIS,XYAXIS,XAXIS,XYAXIS,XAXIS,NOSYM,XYAXIS}; */ /* static char far ZXTrigPlusZSym2[] = */ /* fn1 -> sin cos sinh cosh exp log sqr */ /* {NOSYM,ORIGIN,NOSYM,ORIGIN,NOSYM,NOSYM,ORIGIN}; */ if(param[1] == 0.0 && param[3] == 0.0) /* symmetry = ZXTrigPlusZSym1[trigndx[0]]; */ switch(trigndx[0]) { case COS: /* changed to two case statments and made any added */ case COSH: /* functions default to XAXIS symmetry. JCO 5/25/92 */ case SQR: case 9: /* 'real' cos */ symmetry = XYAXIS; break; case 14: /* FLIP JCO 2/29/92 */ symmetry = YAXIS; break; case LOG: symmetry = NOSYM; break; default: symmetry = XAXIS; break; } else /* symmetry = ZXTrigPlusZSym2[trigndx[0]]; */ switch(trigndx[0]) { case COS: case COSH: case SQR: case 9: /* 'real' cos */ symmetry = ORIGIN; break; case 14: /* FLIP JCO 2/29/92 */ symmetry = NOSYM; break; default: symmetry = NOSYM; break; } if(curfractalspecific->isinteger) { curfractalspecific->orbitcalc = ZXTrigPlusZFractal; if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90) { if(lparm2.x == fudge) /* Scott variant */ curfractalspecific->orbitcalc = ScottZXTrigPlusZFractal; else if(lparm2.x == -fudge) /* Skinner variant */ curfractalspecific->orbitcalc = SkinnerZXTrigSubZFractal; } return(JulialongSetup()); } else { curfractalspecific->orbitcalc = ZXTrigPlusZfpFractal; if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90) { if(parm2.x == 1.0) /* Scott variant */ curfractalspecific->orbitcalc = ScottZXTrigPlusZfpFractal; else if(parm2.x == -1.0) /* Skinner variant */ curfractalspecific->orbitcalc = SkinnerZXTrigSubZfpFractal; } } return(JuliafpSetup()); } int LambdaTrigSetup(void) { int isinteger; if((isinteger = curfractalspecific->isinteger) != 0) curfractalspecific->orbitcalc = LambdaTrigFractal; else curfractalspecific->orbitcalc = LambdaTrigfpFractal; switch(trigndx[0]) { case SIN: case COS: case 9: /* 'real' cos, added this and default for additional functions */ symmetry = PI_SYM; if(isinteger) curfractalspecific->orbitcalc = LambdaTrigFractal1; else curfractalspecific->orbitcalc = LambdaTrigfpFractal1; break; case SINH: case COSH: symmetry = ORIGIN; if(isinteger) curfractalspecific->orbitcalc = LambdaTrigFractal2; else curfractalspecific->orbitcalc = LambdaTrigfpFractal2; break; case SQR: symmetry = ORIGIN; break; case EXP: if(isinteger) curfractalspecific->orbitcalc = LongLambdaexponentFractal; else curfractalspecific->orbitcalc = LambdaexponentFractal; symmetry = NOSYM; /* JCO 1/9/93 */ break; case LOG: symmetry = NOSYM; break; default: /* default for additional functions */ symmetry = ORIGIN; /* JCO 5/8/92 */ break; } get_julia_attractor (0.0, 0.0); /* an attractor? */ if(isinteger) return(JulialongSetup()); else return(JuliafpSetup()); } int JuliafnPlusZsqrdSetup(void) { /* static char far fnpluszsqrd[] = */ /* fn1 -> sin cos sinh cosh sqr exp log */ /* sin {NOSYM,ORIGIN,NOSYM,ORIGIN,ORIGIN,NOSYM,NOSYM}; */ /* symmetry = fnpluszsqrd[trigndx[0]]; JCO 5/8/92 */ switch(trigndx[0]) /* fix sqr symmetry & add additional functions */ { case COS: /* cosxx */ case COSH: case SQR: case 9: /* 'real' cos */ case 10: /* tan */ case 11: /* tanh */ symmetry = ORIGIN; /* default is for NOSYM symmetry */ } if(curfractalspecific->isinteger) return(JulialongSetup()); else return(JuliafpSetup()); } int SqrTrigSetup(void) { /* static char far SqrTrigSym[] = */ /* fn1 -> sin cos sinh cosh sqr exp log */ /* {PI_SYM,PI_SYM,XYAXIS,XYAXIS,XYAXIS,XAXIS,XAXIS}; */ /* symmetry = SqrTrigSym[trigndx[0]]; JCO 5/9/92 */ switch(trigndx[0]) /* fix sqr symmetry & add additional functions */ { case SIN: case COS: /* cosxx */ case 9: /* 'real' cos */ symmetry = PI_SYM; /* default is for XAXIS symmetry */ } if(curfractalspecific->isinteger) return(JulialongSetup()); else return(JuliafpSetup()); } int FnXFnSetup(void) { static char far fnxfn[7][7] = {/* fn2 ->sin cos sinh cosh exp log sqr */ /* fn1 */ /* sin */ {PI_SYM,YAXIS, XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS}, /* cos */ {YAXIS, PI_SYM,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS}, /* sinh*/ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS}, /* cosh*/ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS}, /* exp */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, NOSYM, XYAXIS}, /* log */ {NOSYM, NOSYM, NOSYM, NOSYM, NOSYM, XAXIS, NOSYM}, /* sqr */ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XYAXIS,NOSYM, XYAXIS}, }; /* if(trigndx[0]==EXP || trigndx[0]==LOG || trigndx[1]==EXP || trigndx[1]==LOG) symmetry = XAXIS; else if((trigndx[0]==SIN && trigndx[1]==SIN)||(trigndx[0]==COS && trigndx[1]==COS)) symmetry = PI_SYM; else if((trigndx[0]==SIN && trigndx[1]==COS)||(trigndx[0]==COS && trigndx[1]==SIN)) symmetry = YAXIS; else symmetry = XYAXIS; */ if(trigndx[0] < 7 && trigndx[1] < 7) /* bounds of array JCO 5/22/92*/ symmetry = fnxfn[trigndx[0]][trigndx[1]]; /* JCO 5/22/92 */ /* defaults to XAXIS symmetry JCO 5/22/92 */ else { /* added to complete the symmetry JCO 5/22/92 */ if (trigndx[0]==LOG || trigndx[1] ==LOG) symmetry = NOSYM; if (trigndx[0]==9 || trigndx[1] ==9) { /* 'real' cos */ if (trigndx[0]==SIN || trigndx[1] ==SIN) symmetry = PI_SYM; if (trigndx[0]==COS || trigndx[1] ==COS) symmetry = PI_SYM; } if (trigndx[0]==9 && trigndx[1] ==9) symmetry = PI_SYM; } if(curfractalspecific->isinteger) return(JulialongSetup()); else return(JuliafpSetup()); } int MandelTrigSetup(void) { int isinteger; if((isinteger = curfractalspecific->isinteger) != 0) curfractalspecific->orbitcalc = LambdaTrigFractal; else curfractalspecific->orbitcalc = LambdaTrigfpFractal; symmetry = XYAXIS_NOPARM; switch(trigndx[0]) { case SIN: case COS: if(isinteger) curfractalspecific->orbitcalc = LambdaTrigFractal1; else curfractalspecific->orbitcalc = LambdaTrigfpFractal1; break; case SINH: case COSH: if(isinteger) curfractalspecific->orbitcalc = LambdaTrigFractal2; else curfractalspecific->orbitcalc = LambdaTrigfpFractal2; break; case EXP: symmetry = XAXIS_NOPARM; if(isinteger) curfractalspecific->orbitcalc = LongLambdaexponentFractal; else curfractalspecific->orbitcalc = LambdaexponentFractal; break; case LOG: symmetry = XAXIS_NOPARM; break; default: /* added for additional functions, JCO 5/25/92 */ symmetry = XYAXIS_NOPARM; break; } if(isinteger) return(MandellongSetup()); else return(MandelfpSetup()); } int MarksJuliaSetup(void) { #ifndef XFRACT if(param[2] < 1) param[2] = 1; c_exp = (int)param[2]; longparm = &lparm; lold = *longparm; if(c_exp > 3) lcpower(&lold,c_exp-1,&lcoefficient,bitshift); else if(c_exp == 3) { lcoefficient.x = multiply(lold.x,lold.x,bitshift) - multiply(lold.y,lold.y,bitshift); lcoefficient.y = multiply(lold.x,lold.y,bitshiftless1); } else if(c_exp == 2) lcoefficient = lold; else if(c_exp < 2) { lcoefficient.x = 1L << bitshift; lcoefficient.y = 0L; } get_julia_attractor (0.0, 0.0); /* an attractor? */ #endif return(1); } int MarksJuliafpSetup(void) { if(param[2] < 1) param[2] = 1; c_exp = (int)param[2]; floatparm = &parm; old = *floatparm; if(c_exp > 3) cpower(&old,c_exp-1,&coefficient); else if(c_exp == 3) { coefficient.x = sqr(old.x) - sqr(old.y); coefficient.y = old.x * old.y * 2; } else if(c_exp == 2) coefficient = old; else if(c_exp < 2) { coefficient.x = 1.0; coefficient.y = 0.0; } get_julia_attractor (0.0, 0.0); /* an attractor? */ return(1); } int SierpinskiSetup(void) { /* sierpinski */ periodicitycheck = 0; /* disable periodicity checks */ ltmp.x = 1; ltmp.x = ltmp.x << bitshift; /* ltmp.x = 1 */ ltmp.y = ltmp.x >> 1; /* ltmp.y = .5 */ return(1); } int SierpinskiFPSetup(void) { /* sierpinski */ periodicitycheck = 0; /* disable periodicity checks */ tmp.x = 1; tmp.y = 0.5; return(1); } int HalleySetup(void) { /* Halley */ periodicitycheck=0; if(usr_floatflag) fractype = HALLEY; /* float on */ else fractype = MPHALLEY; curfractalspecific = &fractalspecific[fractype]; degree = (int)parm.x; if(degree < 2) degree = 2; param[0] = (double)degree; /* precalculated values */ AplusOne = degree + 1; /* a+1 */ Ap1deg = AplusOne * degree; #ifndef XFRACT if(fractype == MPHALLEY) { setMPfunctions(); mpAplusOne = *pd2MP((double)AplusOne); mpAp1deg = *pd2MP((double)Ap1deg); mpctmpparm.x = *pd2MP(parm.y); mpctmpparm.y = *pd2MP(parm2.y); mptmpparm2x = *pd2MP(parm2.x); mpone = *pd2MP(1.0); } #endif if(degree % 2) symmetry = XAXIS; /* odd */ else symmetry = XYAXIS; /* even */ return(1); } int PhoenixSetup(void) { longparm = &lparm; /* added to consolidate code 10/1/92 JCO */ floatparm = &parm; degree = (int)parm2.x; if(degree < 2 && degree > -3) degree = 0; param[2] = (double)degree; if(degree == 0){ if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixFractal; else curfractalspecific->orbitcalc = LongPhoenixFractal; } if(degree >= 2){ degree = degree - 1; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixPlusFractal; else curfractalspecific->orbitcalc = LongPhoenixPlusFractal; } if(degree <= -3){ degree = abs(degree) - 2; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixMinusFractal; else curfractalspecific->orbitcalc = LongPhoenixMinusFractal; } return(1); } int PhoenixCplxSetup(void) { longparm = &lparm; floatparm = &parm; degree = (int)param[4]; if(degree < 2 && degree > -3) degree = 0; param[4] = (double)degree; if(degree == 0){ if(parm2.x != 0 || parm2.y != 0) symmetry = NOSYM; else symmetry = ORIGIN; if(parm.y == 0 && parm2.y == 0) symmetry = XAXIS; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixFractalcplx; else curfractalspecific->orbitcalc = LongPhoenixFractalcplx; } if(degree >= 2){ degree = degree - 1; if(parm.y == 0 && parm2.y == 0) symmetry = XAXIS; else symmetry = NOSYM; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixCplxPlusFractal; else curfractalspecific->orbitcalc = LongPhoenixCplxPlusFractal; } if(degree <= -3){ degree = abs(degree) - 2; if(parm.y == 0 && parm2.y == 0) symmetry = XAXIS; else symmetry = NOSYM; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixCplxMinusFractal; else curfractalspecific->orbitcalc = LongPhoenixCplxMinusFractal; } return(1); } int MandPhoenixSetup(void) { longparm = &linit; /* added to consolidate code 10/1/92 JCO */ floatparm = &init; degree = (int)parm2.x; if(degree < 2 && degree > -3) degree = 0; param[2] = (double)degree; if(degree == 0){ if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixFractal; else curfractalspecific->orbitcalc = LongPhoenixFractal; } if(degree >= 2){ degree = degree - 1; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixPlusFractal; else curfractalspecific->orbitcalc = LongPhoenixPlusFractal; } if(degree <= -3){ degree = abs(degree) - 2; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixMinusFractal; else curfractalspecific->orbitcalc = LongPhoenixMinusFractal; } return(1); } int MandPhoenixCplxSetup(void) { longparm = &linit; /* added to consolidate code 10/1/92 JCO */ floatparm = &init; degree = (int)param[4]; if(degree < 2 && degree > -3) degree = 0; param[4] = (double)degree; if(parm.y != 0 || parm2.y != 0) symmetry = NOSYM; if(degree == 0){ if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixFractalcplx; else curfractalspecific->orbitcalc = LongPhoenixFractalcplx; } if(degree >= 2){ degree = degree - 1; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixCplxPlusFractal; else curfractalspecific->orbitcalc = LongPhoenixCplxPlusFractal; } if(degree <= -3){ degree = abs(degree) - 2; if(usr_floatflag) curfractalspecific->orbitcalc = PhoenixCplxMinusFractal; else curfractalspecific->orbitcalc = LongPhoenixCplxMinusFractal; } return(1); } int StandardSetup(void) { if(fractype==UNITYFP) periodicitycheck=0; return(1); } int VLSetup(void) { if (param[0] < 0.0) param[0] = 0.0; if (param[1] < 0.0) param[1] = 0.0; if (param[0] > 1.0) param[0] = 1.0; if (param[1] > 1.0) param[1] = 1.0; floatparm = &parm; return 1; } xfractint-20.4.10.orig/common/bignum.c0000644000000000000000000013061011064332143014420 0ustar /* bignum.c - C routines for bignumbers */ /* Wesley Loewer's Big Numbers. (C) 1994-95, Wesley B. Loewer The bignumber format is simply a signed integer of variable length. The bytes are stored in reverse order (least significant byte first, most significant byte last). The sign bit is the highest bit of the most significant byte. Negatives are stored in 2's complement form. The byte length of the bignumbers must be a multiple of 4 for 386+ operations, and a multiple of 2 for 8086/286 and non 80x86 machines. Some of the arithmetic operations coded here may alter some of the operands used. Therefore, take note of the SIDE-EFFECTS listed with each procedure. If the value of an operand needs to be retained, just use copy_bn() first. This was done for speed sake to avoid unnecessary copying. If space is at such a premium that copying it would be difficult, some of the operations only change the sign of the value. In this case, the original could be optained by calling neg_a_bn(). Most of the bignumber routines operate on true integers. Some of the procedures, however, are designed specifically for fixed decimal point operations. The results and how the results are interpreted depend on where the implied decimal point is located. The routines that depend on where the decimal is located are: strtobn(), bntostr(), bntoint(), inttobn(), bntofloat(), floattobn(), inv_bn(), div_bn(). The number of bytes designated for the integer part may be 1, 2, or 4. BIGNUMBER FORMAT: The following is a discription of the bignumber format and associated variables. The number is stored in reverse order (Least Significant Byte, LSB, stored first in memory, Most Significant Byte, MSB, stored last). Each '_' below represents a block of memory used for arithmetic (1 block = 4 bytes on 386+, 2 bytes on 286-). All lengths are given in bytes. LSB MSB _ _ _ _ _ _ _ _ _ _ _ _ n <----------- bnlength -----------> intlength ---> <--- bnlength = the length in bytes of the bignumber intlength = the number of bytes used to represent the integer part of the bignumber. Possible values are 1, 2, or 4. This determines the largest number that can be represented by the bignumber. intlength = 1, max value = 127.99... intlength = 2, max value = 32,767.99... intlength = 4, max value = 2,147,483,647.99... FULL DOUBLE PRECISION MULTIPLICATION: ( full_mult_bn(), full_square_bn() ) The product of two bignumbers, n1 and n2, will be a result, r, which is a double wide bignumber. The integer part will also be twice as wide, thereby eliminating the possiblity of overflowing the number. LSB MSB _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ r <--------------------------- 2*bnlength -----------------------------> 2*intlength ---> <--- If this double wide bignumber, r, needs to be converted to a normal, single width bignumber, this is easily done with pointer arithmetic. The converted value starts at r+shiftfactor (where shiftfactor = bnlength-intlength) and continues for bnlength bytes. The lower order bytes and the upper integer part of the double wide number can then be ignored. LSB MSB _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ r <--------------------------- 2*bnlength -----------------------------> 2*intlength ---> <--- LSB MSB r+shiftfactor <---------- bnlength ------------> intlength ---> <--- PARTIAL PRECISION MULTIPLICATION: ( mult_bn(), square_bn() ) In most cases, full double precision multiplication is not necessary. The lower order bytes are usually thrown away anyway. The non-"full" multiplication routines only calculate rlength bytes in the result. The value of rlength must be in the range: 2*bnlength <= rlength < bnlength. The amount by which rlength exceeds bnlength accounts for the extra bytes that must be multiplied so that the first bnlength bytes are correct. These extra bytes are refered to in the code as the "padding," that is: rlength=bnlength+padding. All three of the values, bnlength, rlength, and therefore padding, must be multiples of the size of memory blocks being used for arithmetic (2 on 8086/286 and 4 on 386+). Typically, the padding is 2*blocksize. In the case where bnlength=blocksize, padding can only be blocksize to keep rlength from being too big. The product of two bignumbers, n1 and n2, will then be a result, r, which is of length rlength. The integer part will be twice as wide, thereby eliminating the possiblity of overflowing the number. LSB MSB _ _ _ _ _ _ _ _ _ _ _ _ _ _ r <---- rlength = bnlength+padding ------> 2*intlength ---> <--- If r needs to be converted to a normal, single width bignumber, this is easily done with pointer arithmetic. The converted value starts at r+shiftfactor (where shiftfactor = padding-intlength) and continues for bnlength bytes. The lower order bytes and the upper integer part of the double wide number can then be ignored. LSB MSB _ _ _ _ _ _ _ _ _ _ _ _ _ _ r <---- rlength = bnlength+padding ------> 2*intlength ---> <--- LSB MSB r+shiftfactor <---------- bnlength ---------> intlength ---> <--- */ /************************************************************************/ /* There are three parts to the bignum library: */ /* */ /* 1) bignum.c - initialization, general routines, routines that would */ /* not be speeded up much with assembler. */ /* */ /* 2) bignuma.asm - hand coded assembler routines. */ /* */ /* 3) bignumc.c - portable C versions of routines in bignuma.asm */ /* */ /************************************************************************/ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "big.h" #ifndef BIG_ANSI_C #include #endif /************************************************************************* * The original bignumber code was written specifically for a Little Endian * system (80x86). The following is not particularly efficient, but was * simple to incorporate. If speed with a Big Endian machine is critical, * the bignumber format could be reversed. **************************************************************************/ #ifdef ACCESS_BY_BYTE U32 big_access32(BYTE BIGDIST *addr) { return addr[0] | ((U32)addr[1]<<8) | ((U32)addr[2]<<16) | ((U32)addr[3]<<24); } U16 big_access16(BYTE BIGDIST *addr) { return (U16)addr[0] | ((U16)addr[1]<<8); } S16 big_accessS16(S16 BIGDIST *addr) { return (S16)((BYTE *)addr)[0] | ((S16)((BYTE *)addr)[1]<<8); } U32 big_set32(BYTE BIGDIST *addr, U32 val) { addr[0] = (BYTE)(val&0xff); addr[1] = (BYTE)((val>>8)&0xff); addr[2] = (BYTE)((val>>16)&0xff); addr[3] = (BYTE)((val>>24)&0xff); return val; } U16 big_set16(BYTE BIGDIST *addr, U16 val) { addr[0] = (BYTE)(val&0xff); addr[1] = (BYTE)((val>>8)&0xff); return val; } S16 big_setS16(S16 BIGDIST *addr, S16 val) { ((BYTE *)addr)[0] = (BYTE)(val&0xff); ((BYTE *)addr)[1] = (BYTE)((val>>8)&0xff); return val; } #endif #if (_MSC_VER >= 700) #pragma code_seg ("bignum1_text") /* place following in an overlay */ #endif /************************************************************************/ /* convert_bn -- convert bignum numbers from old to new lengths */ int convert_bn(bn_t new, bn_t old, int newbnlength, int newintlength, int oldbnlength, int oldintlength) { int savebnlength, saveintlength; /* save lengths so not dependent on external environment */ saveintlength = intlength; savebnlength = bnlength; intlength = newintlength; bnlength = newbnlength; clear_bn(new); if(newbnlength - newintlength > oldbnlength - oldintlength) { /* This will keep the integer part from overflowing past the array. */ bnlength = oldbnlength - oldintlength + min(oldintlength, newintlength); _fmemcpy(new+newbnlength-newintlength-oldbnlength+oldintlength, old,bnlength); } else { bnlength = newbnlength - newintlength + min(oldintlength, newintlength); _fmemcpy(new,old+oldbnlength-oldintlength-newbnlength+newintlength, bnlength); } intlength = saveintlength; bnlength = savebnlength; return(0); } /********************************************************************/ /* bn_hexdump() - for debugging, dumps to stdout */ void bn_hexdump(bn_t r) { int i; for (i=0; i= '0' && s[l] <= '9') /* while a digit */ { *onesbyte = (BYTE)(s[l--] - '0'); div_a_bn_int(r, 10); } if (s[l] == '.') { longval = atol(s); switch (intlength) { /* only 1, 2, or 4 are allowed */ case 1: *onesbyte = (BYTE)longval; break; case 2: big_set16(onesbyte, (U16)longval); break; case 4: big_set32(onesbyte, longval); break; } } } else { longval = atol(s); switch (intlength) { /* only 1, 2, or 4 are allowed */ case 1: *onesbyte = (BYTE)longval; break; case 2: big_set16(onesbyte, (U16)longval); break; case 4: big_set32(onesbyte, longval); break; } } if (signflag) neg_a_bn(r); return r; } /********************************************************************/ /* strlen_needed() - returns string length needed to hold bignumber */ int strlen_needed() { int length = 3; /* first space for integer part */ switch(intlength) { case 1: length = 3; /* max 127 */ break; case 2: length = 5; /* max 32767 */ break; case 4: length = 10; /* max 2147483647 */ break; } length += decimals; /* decimal part */ length += 2; /* decimal point and sign */ length += 4; /* null and a little extra for safety */ return(length); } /********************************************************************/ /* bntostr() - converts a bignumber into a string */ /* s - string, must be large enough to hold the number. */ /* r - bignumber */ /* will covert to a floating point notation */ /* SIDE-EFFECT: the bignumber, r, is destroyed. */ /* Copy it first if necessary. */ char *unsafe_bntostr(char *s, int dec, bn_t r) { int l=0, d; bn_t onesbyte; long longval = 0; if (dec == 0) dec = decimals; onesbyte = r + bnlength - intlength; if (is_bn_neg(r)) { neg_a_bn(r); *(s++) = '-'; } switch (intlength) { /* only 1, 2, or 4 are allowed */ case 1: longval = *onesbyte; break; case 2: longval = big_access16(onesbyte); break; case 4: longval = big_access32(onesbyte); break; } ltoa(longval, s, 10); l = strlen(s); s[l++] = '.'; for (d=0; d < dec; d++) { *onesbyte = 0; /* clear out highest byte */ mult_a_bn_int(r, 10); if (is_bn_zero(r)) break; s[l++] = (BYTE)(*onesbyte + '0'); } s[l] = '\0'; /* don't forget nul char */ return s; } #if (_MSC_VER >= 700) #pragma code_seg ( ) /* back to normal segment */ #endif /*********************************************************************/ /* b = l */ /* Converts a long to a bignumber */ bn_t inttobn(bn_t r, long longval) { bn_t onesbyte; clear_bn(r); onesbyte = r + bnlength - intlength; switch (intlength) { /* only 1, 2, or 4 are allowed */ case 1: *onesbyte = (BYTE)longval; break; case 2: big_set16(onesbyte, (U16)longval); break; case 4: big_set32(onesbyte, longval); break; } return r; } /*********************************************************************/ /* l = floor(b), floor rounds down */ /* Converts the integer part a bignumber to a long */ long bntoint(bn_t n) { bn_t onesbyte; long longval = 0; onesbyte = n + bnlength - intlength; switch (intlength) { /* only 1, 2, or 4 are allowed */ case 1: longval = *onesbyte; break; case 2: longval = big_access16(onesbyte); break; case 4: longval = big_access32(onesbyte); break; } return longval; } /*********************************************************************/ /* b = f */ /* Converts a double to a bignumber */ bn_t floattobn(bn_t r, LDBL f) { #ifndef USE_BIGNUM_C_CODE /* Only use this when using the ASM code as the C version of */ /* floattobf() calls floattobn(), an infinite recursive loop. */ floattobf(bftmp1, f); return bftobn(r, bftmp1); #else bn_t onesbyte; int i; int signflag=0; clear_bn(r); onesbyte = r + bnlength - intlength; if (f < 0) { signflag = 1; f = -f; } switch (intlength) { /* only 1, 2, or 4 are allowed */ case 1: *onesbyte = (BYTE)f; break; case 2: big_set16(onesbyte, (U16)f); break; case 4: big_set32(onesbyte, (U32)f); break; } f -= (long)f; /* keep only the decimal part */ for (i = bnlength - intlength - 1; i >= 0 && f != 0.0; i--) { f *= 256; r[i] = (BYTE)f; /* keep use the integer part */ f -= (BYTE)f; /* now throw away the integer part */ } if (signflag) neg_a_bn(r); return r; #endif /* USE_BIGNUM_C_CODE */ } /********************************************************************/ /* sign(r) */ int sign_bn(bn_t n) { return is_bn_neg(n) ? -1 : is_bn_not_zero(n) ? 1 : 0; } /********************************************************************/ /* r = |n| */ bn_t abs_bn(bn_t r, bn_t n) { copy_bn(r,n); if (is_bn_neg(r)) neg_a_bn(r); return r; } /********************************************************************/ /* r = |r| */ bn_t abs_a_bn(bn_t r) { if (is_bn_neg(r)) neg_a_bn(r); return r; } /********************************************************************/ /* r = 1/n */ /* uses bntmp1 - bntmp3 - global temp bignumbers */ /* SIDE-EFFECTS: */ /* n ends up as |n| Make copy first if necessary. */ bn_t unsafe_inv_bn(bn_t r, bn_t n) { int signflag=0, i; long maxval; LDBL f; bn_t orig_r, orig_n; /* orig_bntmp1 not needed here */ int orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor; /* use Newton's recursive method for zeroing in on 1/n : r=r(2-rn) */ if (is_bn_neg(n)) { /* will be a lot easier to deal with just positives */ signflag = 1; neg_a_bn(n); } f = bntofloat(n); if (f == 0) /* division by zero */ { max_bn(r); return r; } f = 1/f; /* approximate inverse */ maxval = (1L << ((intlength<<3)-1)) - 1; if (f > maxval) /* check for overflow */ { max_bn(r); return r; } else if (f <= -maxval) { max_bn(r); neg_a_bn(r); return r; } /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_r = r; orig_n = n; /* orig_bntmp1 = bntmp1; */ /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; /* bntmp1 = orig_bntmp1 + orig_bnlength - bnlength; */ floattobn(r, f); /* start with approximate inverse */ clear_bn(bntmp2); /* will be used as 1.0 and 2.0 */ for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; /* bntmp1 = orig_bntmp1 + orig_bnlength - bnlength; */ unsafe_mult_bn(bntmp1, r, n); /* bntmp1=rn */ inttobn(bntmp2, 1); /* bntmp2 = 1.0 */ if (bnlength == orig_bnlength && cmp_bn(bntmp2, bntmp1+shiftfactor) == 0 ) /* if not different */ break; /* they must be the same */ inttobn(bntmp2, 2); /* bntmp2 = 2.0 */ sub_bn(bntmp3, bntmp2, bntmp1+shiftfactor); /* bntmp3=2-rn */ unsafe_mult_bn(bntmp1, r, bntmp3); /* bntmp1=r(2-rn) */ copy_bn(r, bntmp1+shiftfactor); /* r = bntmp1 */ } /* restore original values */ bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; r = orig_r; n = orig_n; /* bntmp1 = orig_bntmp1; */ if (signflag) { neg_a_bn(r); } return r; } /********************************************************************/ /* r = n1/n2 */ /* r - result of length bnlength */ /* uses bntmp1 - bntmp3 - global temp bignumbers */ /* SIDE-EFFECTS: */ /* n1, n2 can end up as GARBAGE */ /* Make copies first if necessary. */ bn_t unsafe_div_bn(bn_t r, bn_t n1, bn_t n2) { int scale1, scale2, scale, sign=0, i; long maxval; LDBL a, b, f; /* first, check for valid data */ a = bntofloat(n1); if (a == 0) /* division into zero */ { clear_bn(r); /* return 0 */ return r; } b = bntofloat(n2); if (b == 0) /* division by zero */ { max_bn(r); return r; } f = a/b; /* approximate quotient */ maxval = (1L << ((intlength<<3)-1)) - 1; if (f > maxval) /* check for overflow */ { max_bn(r); return r; } else if (f <= -maxval) { max_bn(r); neg_a_bn(r); return r; } /* appears to be ok, do division */ if (is_bn_neg(n1)) { neg_a_bn(n1); sign = !sign; } if (is_bn_neg(n2)) { neg_a_bn(n2); sign = !sign; } /* scale n1 and n2 so: |n| >= 1/256 */ /* scale = (int)(log(1/fabs(a))/LOG_256) = LOG_256(1/|a|) */ i = bnlength-1; while (i >= 0 && n1[i] == 0) i--; scale1 = bnlength - i - 2; if (scale1 < 0) scale1 = 0; i = bnlength-1; while (i >= 0 && n2[i] == 0) i--; scale2 = bnlength - i - 2; if (scale2 < 0) scale2 = 0; /* shift n1, n2 */ /* important!, use memmove(), not memcpy() */ _fmemmove(n1+scale1, n1, bnlength-scale1); /* shift bytes over */ _fmemset(n1, 0, scale1); /* zero out the rest */ _fmemmove(n2+scale2, n2, bnlength-scale2); /* shift bytes over */ _fmemset(n2, 0, scale2); /* zero out the rest */ unsafe_inv_bn(r, n2); unsafe_mult_bn(bntmp1, n1, r); copy_bn(r, bntmp1+shiftfactor); /* r = bntmp1 */ if (scale1 != scale2) { /* Rescale r back to what it should be. Overflow has already been checked */ if (scale1 > scale2) /* answer is too big, adjust it */ { scale = scale1-scale2; _fmemmove(r, r+scale, bnlength-scale); /* shift bytes over */ _fmemset(r+bnlength-scale, 0, scale); /* zero out the rest */ } else if (scale1 < scale2) /* answer is too small, adjust it */ { scale = scale2-scale1; _fmemmove(r+scale, r, bnlength-scale); /* shift bytes over */ _fmemset(r, 0, scale); /* zero out the rest */ } /* else scale1 == scale2 */ } if (sign) neg_a_bn(r); return r; } /********************************************************************/ /* sqrt(r) */ /* uses bntmp1 - bntmp6 - global temp bignumbers */ /* SIDE-EFFECTS: */ /* n ends up as |n| */ bn_t sqrt_bn(bn_t r, bn_t n) { int i, comp, almost_match=0; LDBL f; bn_t orig_r, orig_n; int orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor; /* use Newton's recursive method for zeroing in on sqrt(n): r=.5(r+n/r) */ if (is_bn_neg(n)) { /* sqrt of a neg, return 0 */ clear_bn(r); return r; } f = bntofloat(n); if (f == 0) /* division by zero will occur */ { clear_bn(r); /* sqrt(0) = 0 */ return r; } f = sqrtl(f); /* approximate square root */ /* no need to check overflow */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_r = r; orig_n = n; /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; floattobn(r, f); /* start with approximate sqrt */ copy_bn(bntmp4, r); for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; copy_bn(bntmp6, r); copy_bn(bntmp5, n); unsafe_div_bn(bntmp4, bntmp5, bntmp6); add_a_bn(r, bntmp4); half_a_bn(r); if (bnlength == orig_bnlength && (comp=abs(cmp_bn(r, bntmp4))) < 8 ) /* if match or almost match */ { if (comp < 4 /* perfect or near perfect match */ || almost_match == 1) /* close enough for 2nd time */ break; else /* this is the first time they almost matched */ almost_match++; } } /* restore original values */ bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; r = orig_r; n = orig_n; return r; } /********************************************************************/ /* exp(r) */ /* uses bntmp1, bntmp2, bntmp3 - global temp bignumbers */ bn_t exp_bn(bn_t r, bn_t n) { U16 fact=1; if (is_bn_zero(n)) { inttobn(r, 1); return r; } /* use Taylor Series (very slow convergence) */ inttobn(r, 1); /* start with r=1.0 */ copy_bn(bntmp2, r); for (;;) { /* copy n, if n is negative, mult_bn() alters n */ unsafe_mult_bn(bntmp3, bntmp2, copy_bn(bntmp1, n)); copy_bn(bntmp2, bntmp3+shiftfactor); div_a_bn_int(bntmp2, fact); if (!is_bn_not_zero(bntmp2)) break; /* too small to register */ add_a_bn(r, bntmp2); fact++; } return r; } /********************************************************************/ /* ln(r) */ /* uses bntmp1 - bntmp6 - global temp bignumbers */ /* SIDE-EFFECTS: */ /* n ends up as |n| */ bn_t unsafe_ln_bn(bn_t r, bn_t n) { int i, comp, almost_match=0; long maxval; LDBL f; bn_t orig_r, orig_n, orig_bntmp5, orig_bntmp4; int orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor; /* use Newton's recursive method for zeroing in on ln(n): r=r+n*exp(-r)-1 */ if (is_bn_neg(n) || is_bn_zero(n)) { /* error, return largest neg value */ max_bn(r); neg_a_bn(r); return r; } f = bntofloat(n); f = logl(f); /* approximate ln(x) */ maxval = (1L << ((intlength<<3)-1)) - 1; if (f > maxval) /* check for overflow */ { max_bn(r); return r; } else if (f <= -maxval) { max_bn(r); neg_a_bn(r); return r; } /* appears to be ok, do ln */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_r = r; orig_n = n; orig_bntmp5 = bntmp5; orig_bntmp4 = bntmp4; inttobn(bntmp4, 1); /* set before setting new values */ /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; bntmp5 = orig_bntmp5 + orig_bnlength - bnlength; bntmp4 = orig_bntmp4 + orig_bnlength - bnlength; floattobn(r, f); /* start with approximate ln */ neg_a_bn(r); /* -r */ copy_bn(bntmp5, r); /* -r */ for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; bntmp5 = orig_bntmp5 + orig_bnlength - bnlength; bntmp4 = orig_bntmp4 + orig_bnlength - bnlength; exp_bn(bntmp6, r); /* exp(-r) */ unsafe_mult_bn(bntmp2, bntmp6, n); /* n*exp(-r) */ sub_a_bn(bntmp2+shiftfactor, bntmp4); /* n*exp(-r) - 1 */ sub_a_bn(r, bntmp2+shiftfactor); /* -r - (n*exp(-r) - 1) */ if (bnlength == orig_bnlength && (comp=abs(cmp_bn(r, bntmp5))) < 8 ) /* if match or almost match */ { if (comp < 4 /* perfect or near perfect match */ || almost_match == 1) /* close enough for 2nd time */ break; else /* this is the first time they almost matched */ almost_match++; } copy_bn(bntmp5, r); /* -r */ } /* restore original values */ bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; r = orig_r; n = orig_n; bntmp5 = orig_bntmp5; bntmp4 = orig_bntmp4; neg_a_bn(r); /* -(-r) */ return r; } /********************************************************************/ /* sincos_bn(r) */ /* uses bntmp1 - bntmp2 - global temp bignumbers */ /* SIDE-EFFECTS: */ /* n ends up as |n| mod (pi/4) */ bn_t unsafe_sincos_bn(bn_t s, bn_t c, bn_t n) { U16 fact=2; int k=0, i, halves; int signcos=0, signsin=0, switch_sincos=0; #ifndef CALCULATING_BIG_PI /* assure range 0 <= x < pi/4 */ if (is_bn_zero(n)) { clear_bn(s); /* sin(0) = 0 */ inttobn(c, 1); /* cos(0) = 1 */ return s; } if (is_bn_neg(n)) { signsin = !signsin; /* sin(-x) = -sin(x), odd; cos(-x) = cos(x), even */ neg_a_bn(n); } /* n >= 0 */ double_bn(bntmp1, bn_pi); /* 2*pi */ /* this could be done with remainders, but it would probably be slower */ while (cmp_bn(n, bntmp1) >= 0) /* while n >= 2*pi */ sub_a_bn(n, bntmp1); /* 0 <= n < 2*pi */ copy_bn(bntmp1, bn_pi); /* pi */ if (cmp_bn(n, bntmp1) >= 0) /* if n >= pi */ { sub_a_bn(n, bntmp1); signsin = !signsin; signcos = !signcos; } /* 0 <= n < pi */ half_bn(bntmp1, bn_pi); /* pi/2 */ if (cmp_bn(n, bntmp1) > 0) /* if n > pi/2 */ { sub_bn(n, bn_pi, n); /* pi - n */ signcos = !signcos; } /* 0 <= n < pi/2 */ half_bn(bntmp1, bn_pi); /* pi/2 */ half_a_bn(bntmp1); /* pi/4 */ if (cmp_bn(n, bntmp1) > 0) /* if n > pi/4 */ { half_bn(bntmp1, bn_pi); /* pi/2 */ sub_bn(n, bntmp1, n); /* pi/2 - n */ switch_sincos = !switch_sincos; } /* 0 <= n < pi/4 */ /* this looks redundant, but n could now be zero when it wasn't before */ if (is_bn_zero(n)) { clear_bn(s); /* sin(0) = 0 */ inttobn(c, 1); /* cos(0) = 1 */ return s; } /* at this point, the double angle trig identities could be used as many */ /* times as desired to reduce the range to pi/8, pi/16, etc... Each time */ /* the range is cut in half, the number of iterations required is reduced */ /* by "quite a bit." It's just a matter of testing to see what gives the */ /* optimal results. */ /* halves = bnlength / 10; */ /* this is experimental */ halves = 1; for (i = 0; i < halves; i++) half_a_bn(n); #endif /* use Taylor Series (very slow convergence) */ copy_bn(s, n); /* start with s=n */ inttobn(c, 1); /* start with c=1 */ copy_bn(bntmp1, n); /* the current x^n/n! */ for (;;) { /* even terms for cosine */ unsafe_mult_bn(bntmp2, bntmp1, n); copy_bn(bntmp1, bntmp2+shiftfactor); div_a_bn_int(bntmp1, fact++); if (!is_bn_not_zero(bntmp1)) break; /* too small to register */ if (k) /* alternate between adding and subtracting */ add_a_bn(c, bntmp1); else sub_a_bn(c, bntmp1); /* odd terms for sine */ unsafe_mult_bn(bntmp2, bntmp1, n); copy_bn(bntmp1, bntmp2+shiftfactor); div_a_bn_int(bntmp1, fact++); if (!is_bn_not_zero(bntmp1)) break; /* too small to register */ if (k) /* alternate between adding and subtracting */ add_a_bn(s, bntmp1); else sub_a_bn(s, bntmp1); k = !k; /* toggle */ #ifdef CALCULATING_BIG_PI printf("."); /* lets you know it's doing something */ #endif } #ifndef CALCULATING_BIG_PI /* now need to undo what was done by cutting angles in half */ inttobn(bntmp1, 1); for (i = 0; i < halves; i++) { unsafe_mult_bn(bntmp2, s, c); /* no need for safe mult */ double_bn(s, bntmp2+shiftfactor); /* sin(2x) = 2*sin(x)*cos(x) */ unsafe_square_bn(bntmp2,c); double_a_bn(bntmp2+shiftfactor); sub_bn(c, bntmp2+shiftfactor, bntmp1); /* cos(2x) = 2*cos(x)*cos(x) - 1 */ } if (switch_sincos) { copy_bn(bntmp1, s); copy_bn(s, c); copy_bn(c, bntmp1); } if (signsin) neg_a_bn(s); if (signcos) neg_a_bn(c); #endif return s; /* return sine I guess */ } /********************************************************************/ /* atan(r) */ /* uses bntmp1 - bntmp5 - global temp bignumbers */ /* SIDE-EFFECTS: */ /* n ends up as |n| or 1/|n| */ bn_t unsafe_atan_bn(bn_t r, bn_t n) { int i, comp, almost_match=0, signflag=0; LDBL f; bn_t orig_r, orig_n, orig_bn_pi, orig_bntmp3; int orig_bnlength, orig_padding, orig_rlength, orig_shiftfactor; int large_arg; /* use Newton's recursive method for zeroing in on atan(n): r=r-cos(r)(sin(r)-n*cos(r)) */ if (is_bn_neg(n)) { signflag = 1; neg_a_bn(n); } /* If n is very large, atanl() won't give enough decimal places to be a */ /* good enough initial guess for Newton's Method. If it is larger than */ /* say, 1, atan(n) = pi/2 - acot(n) = pi/2 - atan(1/n). */ f = bntofloat(n); large_arg = f > 1.0; if (large_arg) { unsafe_inv_bn(bntmp4, n); /* need to use bntmp4 here since inv uses bntmp3 */ copy_bn(n, bntmp4); f = bntofloat(n); } clear_bn(bntmp3); /* not really necessary, but makes things more consistent */ /* With Newton's Method, there is no need to calculate all the digits */ /* every time. The precision approximately doubles each iteration. */ /* Save original values. */ orig_bnlength = bnlength; orig_padding = padding; orig_rlength = rlength; orig_shiftfactor = shiftfactor; orig_bn_pi = bn_pi; orig_r = r; orig_n = n; orig_bntmp3 = bntmp3; /* calculate new starting values */ bnlength = intlength + (int)(LDBL_DIG/LOG10_256) + 1; /* round up */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); /* adjust pointers */ r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; bn_pi = orig_bn_pi + orig_bnlength - bnlength; bntmp3 = orig_bntmp3 + orig_bnlength - bnlength; f = atanl(f); /* approximate arctangent */ /* no need to check overflow */ floattobn(r, f); /* start with approximate atan */ copy_bn(bntmp3, r); for (i=0; i<25; i++) /* safety net, this shouldn't ever be needed */ { /* adjust lengths */ bnlength <<= 1; /* double precision */ if (bnlength > orig_bnlength) bnlength = orig_bnlength; calc_lengths(); r = orig_r + orig_bnlength - bnlength; n = orig_n + orig_bnlength - bnlength; bn_pi = orig_bn_pi + orig_bnlength - bnlength; bntmp3 = orig_bntmp3 + orig_bnlength - bnlength; #ifdef CALCULATING_BIG_PI printf("\natan() loop #%i, bnlength=%i\nsincos() loops\n", i, bnlength); #endif unsafe_sincos_bn(bntmp4, bntmp5, bntmp3); /* sin(r), cos(r) */ copy_bn(bntmp3, r); /* restore bntmp3 from sincos_bn() */ copy_bn(bntmp1, bntmp5); unsafe_mult_bn(bntmp2, n, bntmp1); /* n*cos(r) */ sub_a_bn(bntmp4, bntmp2+shiftfactor); /* sin(r) - n*cos(r) */ unsafe_mult_bn(bntmp1, bntmp5, bntmp4); /* cos(r) * (sin(r) - n*cos(r)) */ sub_a_bn(r, bntmp1+shiftfactor); /* r - cos(r) * (sin(r) - n*cos(r)) */ #ifdef CALCULATING_BIG_PI putchar('\n'); bn_hexdump(r); #endif if (bnlength == orig_bnlength && (comp=abs(cmp_bn(r, bntmp3))) < 8 ) /* if match or almost match */ { #ifdef CALCULATING_BIG_PI printf("atan() loop comp=%i\n", comp); #endif if (comp < 4 /* perfect or near perfect match */ || almost_match == 1) /* close enough for 2nd time */ break; else /* this is the first time they almost matched */ almost_match++; } #ifdef CALCULATING_BIG_PI if (bnlength == orig_bnlength && comp >= 8) printf("atan() loop comp=%i\n", comp); #endif /* the following gets set above and not altered before we use it! */ /* copy_bn(bntmp3, r); */ /* make a copy for later comparison */ } /* restore original values */ bnlength = orig_bnlength; padding = orig_padding; rlength = orig_rlength; shiftfactor = orig_shiftfactor; bn_pi = orig_bn_pi; r = orig_r; n = orig_n; bntmp3 = orig_bntmp3; if (large_arg) { half_bn(bntmp3, bn_pi); /* pi/2 */ sub_a_bn(bntmp3, r); /* pi/2 - atan(1/n) */ copy_bn(r, bntmp3); } if (signflag) neg_a_bn(r); return r; } /********************************************************************/ /* atan2(r,ny,nx) */ /* uses bntmp1 - bntmp6 - global temp bigfloats */ bn_t unsafe_atan2_bn(bn_t r, bn_t ny, bn_t nx) { int signx, signy; signx = sign_bn(nx); signy = sign_bn(ny); if (signy == 0) { if (signx < 0) copy_bn(r, bn_pi); /* negative x axis, 180 deg */ else /* signx >= 0 positive x axis, 0 */ clear_bn(r); return(r); } if (signx == 0) { copy_bn(r, bn_pi); /* y axis */ half_a_bn(r); /* +90 deg */ if (signy < 0) neg_a_bn(r); /* -90 deg */ return(r); } if (signy < 0) neg_a_bn(ny); if (signx < 0) neg_a_bn(nx); unsafe_div_bn(bntmp6,ny,nx); unsafe_atan_bn(r, bntmp6); if (signx < 0) sub_bn(r,bn_pi,r); if(signy < 0) neg_a_bn(r); return(r); } /**********************************************************************/ /* The rest of the functions are "safe" versions of the routines that */ /* have side effects which alter the parameters */ /**********************************************************************/ /**********************************************************************/ bn_t full_mult_bn(bn_t r, bn_t n1, bn_t n2) { int sign1, sign2; sign1 = is_bn_neg(n1); sign2 = is_bn_neg(n2); unsafe_full_mult_bn(r, n1, n2); if (sign1) neg_a_bn(n1); if (sign2) neg_a_bn(n2); return r; } /**********************************************************************/ bn_t mult_bn(bn_t r, bn_t n1, bn_t n2) { int sign1, sign2; /* TW ENDFIX */ sign1 = is_bn_neg(n1); sign2 = is_bn_neg(n2); unsafe_mult_bn(r, n1, n2); if (sign1) neg_a_bn(n1); if (sign2) neg_a_bn(n2); return r; } /**********************************************************************/ bn_t full_square_bn(bn_t r, bn_t n) { int sign; sign = is_bn_neg(n); unsafe_full_square_bn(r, n); if (sign) neg_a_bn(n); return r; } /**********************************************************************/ bn_t square_bn(bn_t r, bn_t n) { int sign; sign = is_bn_neg(n); unsafe_square_bn(r, n); if (sign) neg_a_bn(n); return r; } /**********************************************************************/ bn_t div_bn_int(bn_t r, bn_t n, U16 u) { int sign; sign = is_bn_neg(n); unsafe_div_bn_int(r, n, u); if (sign) neg_a_bn(n); return r; } #if (_MSC_VER >= 700) #pragma code_seg ("bignum1_text") /* place following in an overlay */ #endif /**********************************************************************/ char *bntostr(char *s, int dec, bn_t r) { return unsafe_bntostr(s, dec, copy_bn(bntmpcpy2, r)); } #if (_MSC_VER >= 700) #pragma code_seg ( ) /* back to normal segment */ #endif /**********************************************************************/ bn_t inv_bn(bn_t r, bn_t n) { int sign; sign = is_bn_neg(n); unsafe_inv_bn(r, n); if (sign) neg_a_bn(n); return r; } /**********************************************************************/ bn_t div_bn(bn_t r, bn_t n1, bn_t n2) { copy_bn(bntmpcpy1, n1); copy_bn(bntmpcpy2, n2); return unsafe_div_bn(r, bntmpcpy1, bntmpcpy2); } /**********************************************************************/ bn_t ln_bn(bn_t r, bn_t n) { #if 0 int sign; sign = is_bn_neg(n); unsafe_ln_bn(r, n); if (sign) neg_a_bn(n); #endif copy_bn(bntmpcpy1, n); /* allows r and n to overlap memory */ unsafe_ln_bn(r, bntmpcpy1); return r; } /**********************************************************************/ bn_t sincos_bn(bn_t s, bn_t c, bn_t n) { return unsafe_sincos_bn(s, c, copy_bn(bntmpcpy1, n)); } /**********************************************************************/ bn_t atan_bn(bn_t r, bn_t n) { int sign; sign = is_bn_neg(n); unsafe_atan_bn(r, n); if (sign) neg_a_bn(n); return r; } /**********************************************************************/ bn_t atan2_bn(bn_t r, bn_t ny, bn_t nx) { copy_bn(bntmpcpy1, ny); copy_bn(bntmpcpy2, nx); unsafe_atan2_bn(r, bntmpcpy1, bntmpcpy2); return r; } /**********************************************************************/ /* Tim's miscellaneous stuff follows */ /**********************************************************************/ int is_bn_zero(bn_t n) { return !is_bn_not_zero(n); } xfractint-20.4.10.orig/common/jiim.c0000644000000000000000000010323510532116313014070 0ustar /* * JIIM.C * * Generates Inverse Julia in real time, lets move a cursor which determines * the J-set. * * The J-set is generated in a fixed-size window, a third of the screen. * * The routines used to set/move the cursor and to save/restore the * window were "borrowed" from editpal.c (TW - now we *use* the editpal code) * (if you don't know how to write good code, look for someone who does) * * JJB [jbuhler@gidef.edu.ar] * TIW Tim Wegner * MS Michael Snyder * KS Ken Shirriff * Revision History: * * 7-28-92 JJB Initial release out of editpal.c * 7-29-92 JJB Added SaveRect() & RestoreRect() - now the * screen is restored after leaving. * 7-30-92 JJB Now, if the cursor goes into the window, the * window is moved to the other side of the screen. * Worked from the first time! * 10-09-92 TIW A major rewrite that merged cut routines duplicated * in EDITPAL.C and added orbits feature. * 11-02-92 KS Made cursor blink * 11-18-92 MS Altered Inverse Julia to use MIIM method. * 11-25-92 MS Modified MIIM support routines to better be * shared with stand-alone inverse julia in * LORENZ.C, and to use DISKVID for swap space. * 05-05-93 TIW Boy this change file really got out of date. * Added orbits capability, various commands, some * of Dan Farmer's ideas like circles and lines * connecting orbits points. * 12-18-93 TIW Removed use of float only for orbits, fixed a * helpmode bug. * */ #include #ifndef USE_VARARGS #include #else #include #endif #ifdef __TURBOC__ # include /* to get mem...() declarations */ #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" #include "fractype.h" #define FAR_RESERVE 8192L /* amount of far mem we will leave avail. */ #define MAXRECT 1024 /* largest width of SaveRect/RestoreRect */ #define newx(size) mem_alloc(size) #define delete(block) block=NULL int show_numbers =0; /* toggle for display of coords */ U16 memory_handle = 0; FILE *file; int windows = 0; /* windows management system */ int xc, yc; /* corners of the window */ int xd, yd; /* dots in the window */ double xcjul = BIG; double ycjul = BIG; void displays(int x, int y, int fg, int bg, char *str, int len) { int i; for(i=0;i 1.0) yAspect = (unsigned int)(65536.0 / aspect); else xAspect = (unsigned int)(65536.0 * aspect); } } void _fastcall c_putcolor(int x, int y, int color) { /* avoid writing outside window */ if ( x < xc || y < yc || x >= xc + xd || y >= yc + yd ) return ; if(y >= sydots - show_numbers) /* avoid overwriting coords */ return; if(windows == 2) /* avoid overwriting fractal */ if (0 <= x && x < xdots && 0 <= y && y < ydots) return; putcolor(x, y, color); } int c_getcolor(int x, int y) { /* avoid reading outside window */ if ( x < xc || y < yc || x >= xc + xd || y >= yc + yd ) return 1000; if(y >= sydots - show_numbers) /* avoid overreading coords */ return 1000; if(windows == 2) /* avoid overreading fractal */ if (0 <= x && x < xdots && 0 <= y && y < ydots) return 1000; return getcolor(x, y); } void circleplot(int x, int y, int color) { if (xAspect == 0) if (yAspect == 0) c_putcolor(x+xbase, y+ybase,color); else c_putcolor(x+xbase, (short)(ybase + (((long) y * (long) yAspect) >> 16)),color); else c_putcolor((int)(xbase + (((long) x * (long) xAspect) >> 16)), y+ybase, color); } void plot8(int x, int y, int color) { circleplot(x,y,color); circleplot(-x,y,color); circleplot(x,-y,color); circleplot(-x,-y,color); circleplot(y,x,color); circleplot(-y,x,color); circleplot(y,-x,color); circleplot(-y,-x,color); } void circle(int radius, int color) { int x,y,sum; x = 0; y = radius << 1; sum = 0; while (x <= y) { if ( !(x & 1) ) /* plot if x is even */ plot8( x >> 1, (y+1) >> 1, color); sum += (x << 1) + 1; x++; if (sum > 0) { sum -= (y << 1) - 1; y--; } } } /* * MIIM section: * * Global variables and service functions used for computing * MIIM Julias will be grouped here (and shared by code in LORENZ.C) * */ long ListFront, ListBack, ListSize; /* head, tail, size of MIIM Queue */ long lsize, lmax; /* how many in queue (now, ever) */ int maxhits = 1; int OKtoMIIM; int SecretExperimentalMode; float luckyx = 0, luckyy = 0; static void fillrect(int x, int y, int width, int depth, int color) { /* fast version of fillrect */ if(hasinverse == 0) return; memset(dstack, color % colors, width); while (depth-- > 0) { if(keypressed()) /* we could do this less often when in fast modes */ return; putrow(x, y++, width, (char *)dstack); } } /* * Queue/Stack Section: * * Defines a buffer that can be used as a FIFO queue or LIFO stack. */ int QueueEmpty() /* True if NO points remain in queue */ { return (ListFront == ListBack); } #if 0 /* not used */ int QueueFull() /* True if room for NO more points in queue */ { return (((ListFront + 1) % ListSize) == ListBack); } #endif int QueueFullAlmost() /* True if room for ONE more point in queue */ { return (((ListFront + 2) % ListSize) == ListBack); } void ClearQueue() { ListFront = ListBack = lsize = lmax = 0; } /* * Queue functions for MIIM julia: * move to JIIM.C when done */ int Init_Queue(unsigned long request) { if (dotmode == 11) { static FCODE nono[] = "Don't try this in disk video mode, kids...\n"; stopmsg(0, nono); ListSize = 0; return 0; } #if 0 if (xmmquery() && debugflag != 420) /* use LARGEST extended mem */ if ((largest = xmmlongest()) > request / 128) request = (unsigned long) largest * 128L; #endif for (ListSize = request; ListSize > 1024; ListSize /= 2) switch (common_startdisk(ListSize * 8, 1, 256)) { case 0: /* success */ ListFront = ListBack = 0; lsize = lmax = 0; return 1; case -1: continue; /* try smaller queue size */ case -2: ListSize = 0; /* cancelled by user */ return 0; } /* failed to get memory for MIIM Queue */ ListSize = 0; return 0; } void Free_Queue() { enddisk(); ListFront = ListBack = ListSize = lsize = lmax = 0; } int PushLong(long x, long y) { if (((ListFront + 1) % ListSize) != ListBack) { if (ToMemDisk(8*ListFront, sizeof(x), &x) && ToMemDisk(8*ListFront +sizeof(x), sizeof(y), &y)) { ListFront = (ListFront + 1) % ListSize; if (++lsize > lmax) { lmax = lsize; luckyx = (float)x; luckyy = (float)y; } return 1; } } return 0; /* fail */ } int PushFloat(float x, float y) { if (((ListFront + 1) % ListSize) != ListBack) { if (ToMemDisk(8*ListFront, sizeof(x), &x) && ToMemDisk(8*ListFront +sizeof(x), sizeof(y), &y)) { ListFront = (ListFront + 1) % ListSize; if (++lsize > lmax) { lmax = lsize; luckyx = x; luckyy = y; } return 1; } } return 0; /* fail */ } _CMPLX PopFloat() { _CMPLX pop; float popx, popy; if (!QueueEmpty()) { ListFront--; if (ListFront < 0) ListFront = ListSize - 1; if (FromMemDisk(8*ListFront, sizeof(popx), &popx) && FromMemDisk(8*ListFront +sizeof(popx), sizeof(popy), &popy)) { pop.x = popx; pop.y = popy; --lsize; } return pop; } pop.x = 0; pop.y = 0; return pop; } LCMPLX PopLong() { LCMPLX pop; if (!QueueEmpty()) { ListFront--; if (ListFront < 0) ListFront = ListSize - 1; if (FromMemDisk(8*ListFront, sizeof(pop.x), &pop.x) && FromMemDisk(8*ListFront +sizeof(pop.x), sizeof(pop.y), &pop.y)) --lsize; return pop; } pop.x = 0; pop.y = 0; return pop; } int EnQueueFloat(float x, float y) { return PushFloat(x, y); } int EnQueueLong(long x, long y) { return PushLong(x, y); } _CMPLX DeQueueFloat() { _CMPLX out; float outx, outy; if (ListBack != ListFront) { if (FromMemDisk(8*ListBack, sizeof(outx), &outx) && FromMemDisk(8*ListBack +sizeof(outx), sizeof(outy), &outy)) { ListBack = (ListBack + 1) % ListSize; out.x = outx; out.y = outy; lsize--; } return out; } out.x = 0; out.y = 0; return out; } LCMPLX DeQueueLong() { LCMPLX out; out.x = 0; out.y = 0; if (ListBack != ListFront) { if (FromMemDisk(8*ListBack, sizeof(out.x), &out.x) && FromMemDisk(8*ListBack +sizeof(out.x), sizeof(out.y), &out.y)) { ListBack = (ListBack + 1) % ListSize; lsize--; } return out; } out.x = 0; out.y = 0; return out; } /* * End MIIM section; */ static void SaveRect(int x, int y, int width, int depth) { char buff[MAXRECT]; int yoff; if(hasinverse == 0) return; /* first, do any de-allocationg */ if (memory_handle != 0) MemoryRelease(memory_handle); /* allocate space and store the rect */ memset(dstack, color_dark, width); if ((memory_handle = MemoryAlloc( (U16)width, (long)depth, FARMEM)) != 0) { Cursor_Hide(); for (yoff=0; yoff= MAXRECT ) { /* this mode puts orbit/julia in an overlapping window 1/3 the size of the physical screen */ windows = 0; /* full screen or large view window */ xd = vesa_xres / 3; yd = vesa_yres / 3; xc = video_startx + xd * 2; yc = video_starty + yd * 2; xoff = video_startx + xd * 5 / 2; yoff = video_starty + yd * 5 / 2; } else if(xdots > vesa_xres/3 && ydots > vesa_yres/3) { /* Julia/orbit and fractal don't overlap */ windows = 1; xd = vesa_xres - xdots; yd = vesa_yres - ydots; xc = video_startx + xdots; yc = video_starty + ydots; xoff = xc + xd/2; yoff = yc + yd/2; } else { /* Julia/orbit takes whole screen */ windows = 2; xd = vesa_xres; yd = vesa_yres; xc = video_startx; yc = video_starty; xoff = video_startx + xd/2; yoff = video_starty + yd/2; } xfactor = (int)(xd/5.33); yfactor = (int)(-yd/4); if(windows == 0) SaveRect(xc,yc,xd,yd); else if(windows == 2) /* leave the fractal */ { fillrect(xdots, yc, xd-xdots, yd, color_dark); fillrect(xc , ydots, xdots, yd-ydots, color_dark); } else /* blank whole window */ fillrect(xc, yc, xd, yd, color_dark); setup_convert_to_screen(&cvt); /* reuse last location if inside window */ col = (int)(cvt.a*SaveC.x + cvt.b*SaveC.y + cvt.e + .5); row = (int)(cvt.c*SaveC.x + cvt.d*SaveC.y + cvt.f + .5); if(col < 0 || col >= xdots || row < 0 || row >= ydots) { cr = (xxmax + xxmin) / 2.0; ci = (yymax + yymin) / 2.0; } else { cr = SaveC.x; ci = SaveC.y; } old_x = old_y = -1; col = (int)(cvt.a*cr + cvt.b*ci + cvt.e + .5); row = (int)(cvt.c*cr + cvt.d*ci + cvt.f + .5); /* possible extraseg arrays have been trashed, so set up again */ if(integerfractal) fill_lx_array(); else fill_dx_array(); Cursor_SetPos(col, row); Cursor_Show(); color = color_bright; iter = 1; still = 1; zoom = 1; #ifdef XFRACT Cursor_StartMouseTracking(); #endif while (still) { int dcol, drow; if (actively_computing) { Cursor_CheckBlink(); } else { Cursor_WaitKey(); } if(keypressed() || first_time) /* prevent burning up UNIX CPU */ { first_time = 0; while(keypressed()) { Cursor_WaitKey(); kbdchar = getakey(); dcol = drow = 0; xcjul = BIG; ycjul = BIG; switch (kbdchar) { case 1143: /* ctrl - keypad 5 */ case 1076: /* keypad 5 */ break; /* do nothing */ case CTL_PAGE_UP: dcol = 4; drow = -4; break; case CTL_PAGE_DOWN: dcol = 4; drow = 4; break; case CTL_HOME: dcol = -4; drow = -4; break; case CTL_END: dcol = -4; drow = 4; break; case PAGE_UP: dcol = 1; drow = -1; break; case PAGE_DOWN: dcol = 1; drow = 1; break; case HOME: dcol = -1; drow = -1; break; case END: dcol = -1; drow = 1; break; case UP_ARROW: drow = -1; break; case DOWN_ARROW: drow = 1; break; case LEFT_ARROW: dcol = -1; break; case RIGHT_ARROW: dcol = 1; break; case UP_ARROW_2: drow = -4; break; case DOWN_ARROW_2: drow = 4; break; case LEFT_ARROW_2: dcol = -4; break; case RIGHT_ARROW_2: dcol = 4; break; case 'z': case 'Z': zoom = (float)1.0; break; case '<': case ',': zoom /= (float)1.15; break; case '>': case '.': zoom *= (float)1.15; break; case SPACE: xcjul = cr; ycjul = ci; goto finish; /* break; */ case 'c': /* circle toggle */ case 'C': /* circle toggle */ mode = mode ^ 1; break; case 'l': case 'L': mode = mode ^ 2; break; case 'n': case 'N': show_numbers = 8 - show_numbers; if(windows == 0 && show_numbers == 0) { Cursor_Hide(); cleartempmsg(); Cursor_Show(); } break; case 'p': case 'P': get_a_number(&cr,&ci); exact = 1; col = (int)(cvt.a*cr + cvt.b*ci + cvt.e + .5); row = (int)(cvt.c*cr + cvt.d*ci + cvt.f + .5); dcol = drow = 0; break; case 'h': /* hide fractal toggle */ case 'H': /* hide fractal toggle */ if(windows == 2) windows = 3; else if(windows == 3 && xd == vesa_xres) { RestoreRect(video_startx, video_starty, xdots, ydots); windows = 2; } break; #ifdef XFRACT case ENTER: break; #endif case '0': case '1': case '2': /* case '3': */ /* don't use '3', it's already meaningful */ case '4': case '5': case '6': case '7': case '8': case '9': if (which == JIIM) { SecretExperimentalMode = kbdchar - '0'; break; } default: still = 0; /* ismand = (short)(1 - ismand); */ } /* switch */ if(kbdchar == 's' || kbdchar == 'S') goto finish; if(dcol > 0 || drow > 0) exact = 0; col += dcol; row += drow; #ifdef XFRACT if (kbdchar == ENTER) { /* We want to use the position of the cursor */ exact=0; col = Cursor_GetX(); row = Cursor_GetY(); } #endif /* keep cursor in logical screen */ if(col >= xdots) { col = xdots -1; exact = 0; } if(row >= ydots) { row = ydots -1; exact = 0; } if(col < 0) { col = 0; exact = 0; } if(row < 0) { row = 0; exact = 0; } Cursor_SetPos(col,row); } /* end while (keypressed) */ if(exact == 0) { if(integerfractal) { cr = lxpixel(); ci = lypixel(); cr /= (1L<xc && col < xc+xd && row>yc && row < yc+yd) { RestoreRect(xc,yc,xd,yd); if (xc == video_startx + xd*2) xc = video_startx + 2; else xc = video_startx + xd*2; xoff = xc + xd / 2; SaveRect(xc,yc,xd,yd); } if(windows == 2) { fillrect(xdots, yc, xd-xdots, yd-show_numbers, color_dark); fillrect(xc , ydots, xdots, yd-ydots-show_numbers, color_dark); } else fillrect(xc, yc, xd, yd, color_dark); } /* end if (keypressed) */ if(which == JIIM) { if(hasinverse == 0) continue; /* * MIIM code: * If we have MIIM queue allocated, then use MIIM method. */ if (OKtoMIIM) { if (QueueEmpty()) { if (maxhits < colors - 1 && maxhits < 5 && (luckyx != 0.0 || luckyy != 0.0)) { int i; lsize = lmax = 0; old.x = new.x = luckyx; old.y = new.y = luckyy; luckyx = luckyy = (float)0.0; for (i=0; i<199; i++) { old = ComplexSqrtFloat(old.x - cr, old.y - ci); new = ComplexSqrtFloat(new.x - cr, new.y - ci); EnQueueFloat( (float)new.x, (float)new.y); EnQueueFloat((float)-old.x, (float)-old.y); } maxhits++; } else continue; /* loop while (still) */ } old = DeQueueFloat(); #if 0 /* try a different new method */ if (lsize < (lmax / 8) && maxhits < 5) /* NEW METHOD */ if (maxhits < colors - 1) maxhits++; #endif x = (int)(old.x * xfactor * zoom + xoff); y = (int)(old.y * yfactor * zoom + yoff); color = c_getcolor(x, y); if (color < maxhits) { c_putcolor(x, y, color + 1); new = ComplexSqrtFloat(old.x - cr, old.y - ci); EnQueueFloat( (float)new.x, (float)new.y); EnQueueFloat((float)-new.x, (float)-new.y); } } else { /* * end Msnyder code, commence if not MIIM code. */ old.x -= cr; old.y -= ci; r = old.x*old.x + old.y*old.y; if(r > 10.0) { old.x = old.y = 0.0; /* avoids math error */ iter = 1; r = 0; } iter++; color = ((count++)>>5)%colors; /* chg color every 32 pts */ if(color==0) color = 1; /* r = sqrt(old.x*old.x + old.y*old.y); calculated above */ r = sqrt(r); new.x = sqrt(fabs((r + old.x)/2)); if (old.y < 0) new.x = -new.x; new.y = sqrt(fabs((r - old.x)/2)); switch (SecretExperimentalMode) { case 0: /* unmodified random walk */ default: if (rand() % 2) { new.x = -new.x; new.y = -new.y; } x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); break; case 1: /* always go one direction */ if (SaveC.y < 0) { new.x = -new.x; new.y = -new.y; } x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); break; case 2: /* go one dir, draw the other */ if (SaveC.y < 0) { new.x = -new.x; new.y = -new.y; } x = (int)(-new.x * xfactor * zoom + xoff); y = (int)(-new.y * yfactor * zoom + yoff); break; case 4: /* go negative if max color */ x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); if (c_getcolor(x, y) == colors - 1) { new.x = -new.x; new.y = -new.y; x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); } break; case 5: /* go positive if max color */ new.x = -new.x; new.y = -new.y; x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); if (c_getcolor(x, y) == colors - 1) { x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); } break; case 7: if (SaveC.y < 0) { new.x = -new.x; new.y = -new.y; } x = (int)(-new.x * xfactor * zoom + xoff); y = (int)(-new.y * yfactor * zoom + yoff); if(iter > 10) { if(mode == 0) /* pixels */ c_putcolor(x, y, color); else if (mode & 1) /* circles */ { xbase = x; ybase = y; circle((int)(zoom*(xd >> 1)/iter),color); } if ((mode & 2) && x > 0 && y > 0 && old_x > 0 && old_y > 0) { draw_line(x, y, old_x, old_y, color); } old_x = x; old_y = y; } x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); break; case 8: /* go in long zig zags */ if (rancnt >= 300) rancnt = -300; if (rancnt < 0) { new.x = -new.x; new.y = -new.y; } x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); break; case 9: /* "random run" */ switch (randir) { case 0: /* go random direction for a while */ if (rand() % 2) { new.x = -new.x; new.y = -new.y; } if (++rancnt > 1024) { rancnt = 0; if (rand() % 2) randir = 1; else randir = -1; } break; case 1: /* now go negative dir for a while */ new.x = -new.x; new.y = -new.y; /* fall through */ case -1: /* now go positive dir for a while */ if (++rancnt > 512) randir = rancnt = 0; break; } x = (int)(new.x * xfactor * zoom + xoff); y = (int)(new.y * yfactor * zoom + yoff); break; } /* end switch SecretMode (sorry about the indentation) */ } /* end if not MIIM */ } else /* orbits */ { if(iter < maxit) { color = (int)iter%colors; if(integerfractal) { old.x = lold.x; old.x /= fudge; old.y = lold.y; old.y /= fudge; } x = (int)((old.x - init.x) * xfactor * 3 * zoom + xoff); y = (int)((old.y - init.y) * yfactor * 3 * zoom + yoff); if((*ORBITCALC)()) iter = maxit; else iter++; } else { x = y = -1; actively_computing = 0; } } if(which == ORBIT || iter > 10) { if(mode == 0) /* pixels */ c_putcolor(x, y, color); else if (mode & 1) /* circles */ { xbase = x; ybase = y; circle((int)(zoom*(xd >> 1)/iter),color); } if ((mode & 2) && x > 0 && y > 0 && old_x > 0 && old_y > 0) { draw_line(x, y, old_x, old_y, color); } old_x = x; old_y = y; } old = new; lold = lnew; } /* end while(still) */ finish: /* * Msnyder code: * free MIIM queue */ Free_Queue(); /* * end Msnyder code. */ if(kbdchar != 's'&& kbdchar != 'S') { Cursor_Hide(); if(windows == 0) RestoreRect(xc,yc,xd,yd); else if(windows >= 2 ) { if(windows == 2) { fillrect(xdots, yc, xd-xdots, yd, color_dark); fillrect(xc , ydots, xdots, yd-ydots, color_dark); } else fillrect(xc, yc, xd, yd, color_dark); if(windows == 3 && xd == vesa_xres) /* unhide */ { RestoreRect(0, 0, xdots, ydots); windows = 2; } Cursor_Hide(); savehasinverse = hasinverse; hasinverse = 1; SaveRect(0,0,xdots,ydots); sxoffs = oldsxoffs; syoffs = oldsyoffs; RestoreRect(0,0,xdots,ydots); hasinverse = savehasinverse; } } Cursor_Destroy(); #ifdef XFRACT Cursor_EndMouseTracking(); #endif delete(line_buff); if (memory_handle != 0) { MemoryRelease(memory_handle); memory_handle = 0; } #if 0 if (memory) /* done with memory, free it */ { farmemfree(memory); memory = NULL; } #endif lookatmouse = oldlookatmouse; using_jiim = 0; calctype = oldcalctype; debugflag = old_debugflag; /* yo Chuck! */ helpmode = oldhelpmode; if(kbdchar == 's' || kbdchar == 'S') { viewwindow = viewxdots = viewydots = 0; viewreduction = (float)4.2; viewcrop = 1; finalaspectratio = screenaspect; xdots = sxdots; ydots = sydots; dxsize = xdots - 1; dysize = ydots - 1; sxoffs = 0; syoffs = 0; freetempmsg(); } else cleartempmsg(); if (file != NULL) { fclose(file); file = NULL; dir_remove(tempdir,scrnfile); } show_numbers = 0; ungetakey(kbdchar); if (curfractalspecific->calctype == calcfroth) froth_cleanup(); } xfractint-20.4.10.orig/common/intro.c0000644000000000000000000000700311011103106014254 0ustar /* * intro.c * * FRACTINT intro screen (authors & credits) * * */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" /* stuff from fractint */ #ifdef XFRACT extern int slowdisplay; #endif void intro(void) { /* following overlayed data safe if "putstrings" are resident */ static FCODE PRESS_ENTER[] = {"Press ESC for main menu, F1 for help."}; int toprow, botrow, i, j, delaymax; char oldchar; int authors[100]; /* this should be enough for awhile */ char far *credits; char far *screen_text; int oldlookatmouse; int oldhelpmode; timer_start -= clock_ticks(); /* "time out" during help */ oldlookatmouse = lookatmouse; oldhelpmode = helpmode; lookatmouse = 0; /* de-activate full mouse checking */ screen_text = MK_FP(extraseg, 0); i = 32767 + read_help_topic(INTRO_AUTHORS, 0, 32767, screen_text); screen_text[i++] = '\0'; credits = screen_text + i; i = 32767 + read_help_topic(INTRO_CREDITS, 0, 32767, credits); credits[i++] = '\0'; j = 0; authors[j] = 0; /* find the start of each credit-line */ for (i = 0; credits[i] != 0; i++) if (credits[i] == 10) authors[++j] = i+1; authors[j+1] = i; helptitle(); #define END_MAIN_AUTHOR 5 toprow = END_MAIN_AUTHOR+1; #ifndef XFRACT botrow = 21; #else botrow = 20; putstringcenter(botrow+1,0,80,C_TITLE, "Unix/X port of fractint by Ken Shirriff"); #endif putstringcenter(1,0,80,C_TITLE, PRESS_ENTER); putstring(2,0,C_CONTRIB,screen_text); setattr(2,0,C_AUTHDIV1,80); setattr(END_MAIN_AUTHOR,0,C_AUTHDIV1,80); setattr(3,0,C_PRIMARY,80*(END_MAIN_AUTHOR-3)); for (i = 3; i < END_MAIN_AUTHOR; ++i) setattr(i,21,C_CONTRIB,58); setattr(toprow,0,C_CONTRIB,(botrow-END_MAIN_AUTHOR)*80); setattr(botrow+1,0,C_AUTHDIV2,80); setattr(botrow+2,0,C_PROMPT_BKGRD,80); setattr(botrow+3,0,C_TITLE_LOW,160); i = botrow - toprow; srand((unsigned int)clock_ticks()); j = rand()%(j-(botrow-toprow)); /* first to use */ i = j+botrow-toprow; /* last to use */ oldchar = credits[authors[i+1]]; credits[authors[i+1]] = 0; putstring(toprow,0,C_CONTRIB,credits+authors[j]); credits[authors[i+1]] = oldchar; delaymax = 10; movecursor(25,80); /* turn it off */ helpmode = HELPMENU; #ifdef XFRACT if (slowdisplay) delaymax *= 15; #endif loop_intro: for (j = 0; j < delaymax && !(keypressed()); j++) delay(100); if (j = keypressed()) /* set j to returned key */ getakey(); if (menu_checkkey(j,0) || j == 109) /* menu key or 'm' */ goto intro_end; if (j == 32) { /* spacebar pauses */ wait_again: #ifndef XFRACT while (!keypressed()) ; #else waitkeypressed(0); #endif if (j = keypressed()) /* set j to returned key */ getakey(); if (menu_checkkey(j,0) || j == 109) /* menu key or 'm' */ goto intro_end; if (j!= 32) /* spacebar */ goto wait_again; } scrollup(toprow, botrow); i++; if (credits[authors[i]] == 0) i = 0; oldchar = credits[authors[i+1]]; credits[authors[i+1]] = 0; putstring(botrow,0,C_CONTRIB,&credits[authors[i]]); credits[authors[i+1]] = oldchar; movecursor(25,80); /* turn it off */ goto loop_intro; intro_end: ungetakey(j); lookatmouse = oldlookatmouse; /* restore the mouse-checking */ helpmode = oldhelpmode; return ; } xfractint-20.4.10.orig/common/gifview.c0000644000000000000000000003154511253454200014605 0ustar /* * * This GIF decoder is designed for use with the FRACTINT program. * This decoder code lacks full generality in the following respects: * supports non-interlaced GIF files only, and calmly ignores any * local color maps and non-Fractint-specific extension blocks. * * GIF and 'Graphics Interchange Format' are trademarks (tm) of * Compuserve, Incorporated, an H&R Block Company. * * Tim Wegner */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" static void close_file(void); #define MAXCOLORS 256 static FILE *fpin = NULL; /* FILE pointer */ unsigned int height; unsigned numcolors; int bad_code_count = 0; /* needed by decoder module */ static int out_line_dither(BYTE *, int); static int out_line_migs(BYTE *, int); static int out_line_too_wide(BYTE *, int); static int colcount; /* keeps track of current column for wide images */ static unsigned int gifview_image_top; /* (for migs) */ static unsigned int gifview_image_left; /* (for migs) */ static unsigned int gifview_image_twidth; /* (for migs) */ int get_byte() { return (getc(fpin)); /* EOF is -1, as desired */ } int get_bytes(BYTE *where,int how_many) { return (fread((char *)where,1,how_many,fpin)); /* EOF is -1, as desired */ } /* * DECODERLINEWIDTH is the width of the pixel buffer used by the decoder. A * larger buffer gives better performance. However, this buffer does not * have to be a whole line width, although historically in Fractint it has * been: images were decoded line by line and a whole line written to the * screen at once. The requirement to have a whole line buffered at once * has now been relaxed in order to support larger images. The one exception * to this is in the case where the image is being decoded to a smaller size. * The skipxdots and skipydots logic assumes that the buffer holds one line. */ #ifdef XFRACT BYTE decoderline[MAXPIXELS+1]; /* write-line routines use this */ #define DECODERLINE_WIDTH MAXPIXELS #else #define DECODERLINE_WIDTH 2048 /* width of decoderline, can be smaller */ #endif BYTE *decoderline1; static char far *ditherbuf = NULL; /* Main entry decoder */ int gifview() { BYTE buffer[16]; unsigned top, left, width, finished; char temp1[FILE_MAX_DIR]; BYTE byte_buf[257]; /* for decoder */ int status; int i, j, k, planes; BYTE linebuf[DECODERLINE_WIDTH]; decoderline1 = linebuf; #if 0 { char msg[100]; sprintf(msg,"Stack free in gifview: %d",stackavail()); stopmsg(0,msg); } #endif /* using stack for decoder byte buf rather than static mem */ set_byte_buff(byte_buf); status = 0; /* initialize the col and row count for write-lines */ colcount = rowcount = 0; /* Open the file */ if(outln == outline_stereo) strcpy(temp1,stereomapname); else strcpy(temp1,readname); if (has_ext(temp1) == NULL) { strcat(temp1,DEFAULTFRACTALTYPE); if ((fpin = fopen(temp1,"rb")) != NULL) { fclose(fpin); } else { if(outln == outline_stereo) strcpy(temp1,stereomapname); else strcpy(temp1,readname); strcat(temp1,ALTERNATEFRACTALTYPE); } } if ((fpin = fopen(temp1, "rb")) == NULL) { return (-1); } /* Get the screen description */ for (i = 0; i < 13; i++) { int tmp; buffer[i] = (BYTE)(tmp = get_byte()); if (tmp < 0) { close_file(); return(-1); } } if(strncmp((char *)buffer,"GIF87a",3) || /* use updated GIF specs */ buffer[3] < '0' || buffer[3] > '9' || buffer[4] < '0' || buffer[4] > '9' || buffer[5] < 'A' || buffer[5] > 'z' ) { close_file(); return(-1); } width = buffer[6] | (buffer[7] << 8); height = buffer[8] | (buffer[9] << 8); planes = (buffer[10] & 0x0F) + 1; gifview_image_twidth = width; if((buffer[10] & 0x80)==0) /* color map (better be!) */ { close_file(); return(-1); } numcolors = 1 << planes; if (dither_flag && numcolors>2 && colors==2 && outln==out_line) { outln = out_line_dither; } for (i = 0; i < (int)numcolors; i++) { for (j = 0; j < 3; j++) { if ((k = get_byte()) < 0) { close_file(); return(-1); } if((!display3d || (glassestype != 1 && glassestype != 2)) && !dontreadcolor) dacbox[i][j] = (BYTE)(k >> 2); } } colorstate = 1; /* colors aren't default and not a known .map file */ /* don't read if glasses */ if (display3d && mapset && glassestype!=1 && glassestype != 2) { ValidateLuts(MAP_name); /* read the palette file */ spindac(0,1); /* load it, but don't spin */ } if (dacbox[0][0] != 255) spindac(0,1); /* update the DAC */ if (dotmode == 11){ /* disk-video */ char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; char tmpname[MAX_NAME]; char msg[40]; splitpath(temp1,NULL,NULL,fname,ext); makepath(tmpname,NULL,NULL,fname,ext); sprintf(msg,"restoring %s",tmpname); dvid_status(1,msg); } dontreadcolor = 0; /* Now display one or more GIF objects */ finished = 0; while (!finished) { switch (get_byte()) { case ';': /* End of the GIF dataset */ finished = 1; status = 0; break; case '!': /* GIF Extension Block */ get_byte(); /* read (and ignore) the ID */ while ((i = get_byte()) > 0) /* get the data length */ for (j = 0; j < i; j++) get_byte(); /* flush the data */ break; case ',': /* * Start of an image object. Read the image description. */ for (i = 0; i < 9; i++) { int tmp; buffer[i] = (BYTE)(tmp = get_byte()); if (tmp < 0) { status = -1; break; } } if(status < 0) { finished = 1; break; } left = buffer[0] | (buffer[1] << 8); top = buffer[2] | (buffer[3] << 8); width = buffer[4] | (buffer[5] << 8); height = buffer[6] | (buffer[7] << 8); /* adjustments for handling MIGs */ gifview_image_top = top; if (skipxdots > 0) gifview_image_top /= (skipydots+1); gifview_image_left = left; if (skipydots > 0) gifview_image_left /= (skipxdots+1); if (outln==out_line) { /* what about continuous potential???? */ if(width != gifview_image_twidth || top != 0) { /* we're using normal decoding and we have a MIG */ outln = out_line_migs; } else if(width > DECODERLINE_WIDTH && skipxdots == 0) { outln = out_line_too_wide; } } if (pot16bit) width >>= 1; /* Skip local color palette */ if((buffer[8] & 0x80)==0x80) { /* local map? */ int numcolors; /* make this local */ planes = (buffer[8] & 0x0F) + 1; numcolors = 1 << planes; /* skip local map */ for (i = 0; i < numcolors; i++) { for (j = 0; j < 3; j++) { if ((k = get_byte()) < 0) { close_file(); return(-1); } } } } /* initialize the row count for write-lines */ rowcount = 0; if (calc_status == 1) /* should never be so, but make sure */ calc_status = 0; busy = 1; /* for slideshow CALCWAIT */ /* * Call decoder(width) via timer. * Width is limited to DECODERLINE_WIDTH. */ if(skipxdots == 0) width = min(width,DECODERLINE_WIDTH); status = timer(1,NULL,width); busy = 0; /* for slideshow CALCWAIT */ if (calc_status == 1) /* e.g., set by line3d */ { calctime = timer_interval; /* note how long it took */ if (keypressed() != 0) { calc_status = 3; /* interrupted, not resumable */ finished = 1; } else calc_status = 4; /* complete */ } /* Hey! the decoder doesn't read the last (0-length) block!! */ if (get_byte() != 0) { status = -1; finished = 1; } break; default: status = -1; finished = 1; break; } } close_file(); if (dotmode == 11) { /* disk-video */ static FCODE o_msg[] = {"Restore completed"}; char msg[sizeof(o_msg)]; far_strcpy(msg,o_msg); dvid_status(0,msg); dvid_status(1,""); } if (ditherbuf != NULL) { /* we're done, free dither memory */ farmemfree(ditherbuf); ditherbuf = NULL; } return(status); } static void close_file() { fclose(fpin); fpin = NULL; } /* routine for MIGS that generates partial output lines */ static int out_line_migs(BYTE *pixels, int linelen) { int row, startcol, stopcol; row = gifview_image_top + rowcount; startcol = gifview_image_left; stopcol = startcol+linelen-1; put_line(row, startcol, stopcol, pixels); rowcount++; return(0); } static int out_line_dither(BYTE *pixels, int linelen) { int i,nexterr,brt,err; if(ditherbuf == NULL) ditherbuf = (char far *)farmemalloc(linelen+1); far_memset( ditherbuf, 0, linelen+1); nexterr = (rand()&0x1f)-16; for (i=0;i>4; /* brightness from 0 to 63 */ #else brt = (dacbox[pixels[i]][0]*5+dacbox[pixels[i]][1]*9 + dacbox[pixels[i]][2]*2)>>4; /* brightness from 0 to 63 */ #endif brt += nexterr; if (brt>32) { pixels[i] = 1; err = brt-63; } else { pixels[i] = 0; err = brt; } nexterr = ditherbuf[i+1]+err/3; ditherbuf[i] = (char)(err/3); ditherbuf[i+1] = (char)(err/3); } return out_line(pixels, linelen); } /* routine for images wider than the row buffer */ static int out_line_too_wide(BYTE *pixels, int linelen) { /* int twidth = gifview_image_twidth;*/ int twidth = xdots; int extra; while(linelen > 0) { extra = colcount+linelen-twidth; if(extra > 0) /* line wraps */ { put_line(rowcount, colcount, twidth-1, pixels); pixels += twidth-colcount; linelen -= twidth-colcount; colcount = twidth; } else { put_line(rowcount, colcount, colcount+linelen-1, pixels); colcount += linelen; linelen = 0; } if(colcount >= twidth) { colcount = 0; rowcount++; } } return(0); } static int put_sound_line(int row, int colstart, int colstop, BYTE *pixels) { int col; for(col=colstart;col<=colstop;col++) { putcolor(col,row,*pixels); if(orbit_delay > 0) sleepms(orbit_delay); w_snd((int)((int)(*pixels++)*3000/colors+basehertz)); if(keypressed()) { mute(); return(-1); } } return(0); } int sound_line(BYTE *pixels, int linelen) { /* int twidth = gifview_image_twidth;*/ int twidth = xdots; int extra; int ret=0; while(linelen > 0) { extra = colcount+linelen-twidth; if(extra > 0) /* line wraps */ { if(put_sound_line(rowcount, colcount, twidth-1, pixels)) break; pixels += twidth-colcount; linelen -= twidth-colcount; colcount = twidth; } else { if(put_sound_line(rowcount, colcount, colcount+linelen-1, pixels)) break; colcount += linelen; linelen = 0; } if(colcount >= twidth) { colcount = 0; rowcount++; } } mute(); if(keypressed()) ret = -1; return(ret); } int pot_line(BYTE *pixels, int linelen) { int row,col,saverowcount; if (rowcount == 0) if (pot_startdisk() < 0) return -1; saverowcount = rowcount; row = (rowcount >>= 1); if ((saverowcount & 1) != 0) /* odd line */ row += ydots; else if (dotmode != 11) /* even line - display the line too */ out_line(pixels,linelen); for (col = 0; col < xdots; ++col) writedisk(col+sxoffs,row+syoffs,*(pixels+col)); rowcount = saverowcount + 1; return(0); } xfractint-20.4.10.orig/common/stereo.c0000644000000000000000000002231610532116313014441 0ustar /* STEREO.C a module to view 3D images. Written in Borland 'C++' by Paul de Leeuw. From an idea in "New Scientist" 9 October 1993 pages 26 - 29. Change History: 11 June 94 - Modified to reuse existing Fractint arrays TW 11 July 94 - Added depth parameter PDL 14 July 94 - Added grayscale option and did general cleanup TW 19 July 94 - Fixed negative depth PDL 19 July 94 - Added calibration bars, get_min_max() TW 24 Sep 94 - Added image save/restore, color cycle, and save TW 28 Sep 94 - Added image map TW 20 Mar 95 - Fixed endless loop bug with bad depth values TW 23 Mar 95 - Allow arbitrary dimension image maps TW (TW is Tim Wegner, PDL is Paul de Leeuw) */ #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "helpdefs.h" char stereomapname[FILE_MAX_DIR+1] = {""}; int AutoStereo_depth = 100; double AutoStereo_width = 10; char grayflag = 0; /* flag to use gray value rather than color * number */ char calibrate = 1; /* add calibration bars to image */ char image_map = 0; /* this structure permits variables to be temporarily static and visible to routines in this file without permanently hogging memory */ static struct static_vars { long avg; long avgct; long depth; int barheight; int ground; int maxcc; int maxc; int minc; int reverse; int sep; double width; int x1; int x2; int xcen; int y; int y1; int y2; int ycen; BYTE *savedac; } *pv; #define AVG (pv->avg) #define AVGCT (pv->avgct) #define DEPTH (pv->depth) #define BARHEIGHT (pv->barheight) #define GROUND (pv->ground) #define MAXCC (pv->maxcc) #define MAXC (pv->maxc) #define MINC (pv->minc) #define REVERSE (pv->reverse) #define SEP (pv->sep) #define WIDTH (pv->width) #define X1 (pv->x1) #define X2 (pv->x2) #define Y (pv->y) #define Y1 (pv->y1) #define Y2 (pv->y2) #define XCEN (pv->xcen) #define YCEN (pv->ycen) /* The getdepth() function allows using the grayscale value of the color as DEPTH, rather than the color number. Maybe I got a little too sophisticated trying to avoid a divide, so the comment tells what all the multiplies and shifts are trying to do. The result should be from 0 to 255. */ typedef BYTE (*DACBOX)[256][3]; #define dac (*((DACBOX)(pv->savedac))) static int getdepth(int xd, int yd) { int pal; pal = getcolor(xd, yd); if (grayflag) { /* effectively (30*R + 59*G + 11*B)/100 scaled 0 to 255 */ pal = ((int) dac[pal][0] * 77 + (int) dac[pal][1] * 151 + (int) dac[pal][2] * 28); pal >>= 6; } return (pal); } /* Get min and max DEPTH value in picture */ static int get_min_max(void) { int xd, yd, ldepth; MINC = colors; MAXC = 0; for(yd = 0; yd < ydots; yd++) { if (keypressed()) return (1); if(yd == 20) showtempmsg("Getting min and max"); for(xd = 0; xd < xdots; xd++) { ldepth = getdepth(xd,yd); if ( ldepth < MINC) MINC = ldepth; if (ldepth > MAXC) MAXC = ldepth; } } cleartempmsg(); return(0); } void toggle_bars(int *bars, int barwidth, int far *colour) { int i, j, ct; find_special_colors(); ct = 0; for (i = XCEN; i < (XCEN) + barwidth; i++) for (j = YCEN; j < (YCEN) + BARHEIGHT; j++) { if(*bars) { putcolor(i + (int)(AVG), j , color_bright); putcolor(i - (int)(AVG), j , color_bright); } else { putcolor(i + (int)(AVG), j, colour[ct++]); putcolor(i - (int)(AVG), j, colour[ct++]); } } *bars = 1 - *bars; } int outline_stereo(BYTE * pixels, int linelen) { int i, j, x, s; int far *same; int far *colour; if((Y) >= ydots) return(1); same = (int far *)MK_FP(extraseg,0); colour = &same[ydots]; for (x = 0; x < xdots; ++x) same[x] = x; for (x = 0; x < xdots; ++x) { if(REVERSE) SEP = GROUND - (int) (DEPTH * (getdepth(x, Y) - MINC) / MAXCC); else SEP = GROUND - (int) (DEPTH * (MAXCC - (getdepth(x, Y) - MINC)) / MAXCC); SEP = (int)((SEP * 10.0) / WIDTH); /* adjust for media WIDTH */ /* get average value under calibration bars */ if(X1 <= x && x <= X2 && Y1 <= Y && Y <= Y2) { AVG += SEP; (AVGCT)++; } i = x - (SEP + (SEP & Y & 1)) / 2; j = i + SEP; if (0 <= i && j < xdots) { /* there are cases where next never terminates so we timeout */ int ct = 0; for (s = same[i]; s != i && s != j && ct++ < xdots; s = same[i]) { if (s > j) { same[i] = j; i = j; j = s; } else i = s; } same[i] = j; } } for (x = xdots - 1; x >= 0; x--) { if (same[x] == x) /* colour[x] = rand()%colors; */ colour[x] = (int)pixels[x%linelen]; else colour[x] = colour[same[x]]; putcolor(x, Y, colour[x]); } (Y)++; return(0); } /************************************************************************** Convert current image into Auto Stereo Picture **************************************************************************/ int do_AutoStereo(void) { struct static_vars v; BYTE savedacbox[256*3]; int oldhelpmode, ret=0; int i, j, done; int bars, ct, kbdchar, barwidth; time_t ltime; unsigned char *buf = (unsigned char *)decoderline; /* following two lines re-use existing arrays in Fractint */ int far *same; int far *colour; same = (int far *)MK_FP(extraseg,0); colour = &same[ydots]; pv = &v; /* set static vars to stack structure */ pv->savedac = savedacbox; /* Use the current time to randomize the random number sequence. */ time(<ime); srand((unsigned int)ltime); oldhelpmode = helpmode; helpmode = RDSKEYS; savegraphics(); /* save graphics image */ memcpy(savedacbox, dacbox, 256 * 3); /* save colors */ if(xdots > OLDMAXPIXELS) { static FCODE msg[] = {"Stereo not allowed with resolution > 2048 pixels wide"}; stopmsg(0,msg); buzzer(1); ret = 1; goto exit_stereo; } /* empircally determined adjustment to make WIDTH scale correctly */ WIDTH = AutoStereo_width*.67; if(WIDTH < 1) WIDTH = 1; GROUND = xdots / 8; if(AutoStereo_depth < 0) REVERSE = 1; else REVERSE = 0; DEPTH = ((long) xdots * (long) AutoStereo_depth) / 4000L; DEPTH = labs(DEPTH) + 1; if(get_min_max()) { buzzer(1); ret = 1; goto exit_stereo; } MAXCC = MAXC - MINC + 1; AVG = AVGCT = 0L; barwidth = 1 + xdots / 200; BARHEIGHT = 1 + ydots / 20; XCEN = xdots/2; if(calibrate > 1) YCEN = BARHEIGHT/2; else YCEN = ydots/2; /* box to average for calibration bars */ X1 = XCEN - xdots/16; X2 = XCEN + xdots/16; Y1 = YCEN - BARHEIGHT/2; Y2 = YCEN + BARHEIGHT/2; Y = 0; if(image_map) { outln = outline_stereo; while((Y) < ydots) if(gifview()) { ret = 1; goto exit_stereo; } } else { while(Y < ydots) { if(keypressed()) { ret = 1; goto exit_stereo; } for(i=0;i>8); rowcount++; return(0); } xfractint-20.4.10.orig/common/bignumc.c0000644000000000000000000010300710150633601014561 0ustar /* bignumc.c - C routines equivalent to ASM routines in bignuma.asm */ /* Wesley Loewer's Big Numbers. (C) 1994-95, Wesley B. Loewer */ #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "big.h" /******************************************************************** The following code contains the C versions of the routines from the file BIGNUMA.ASM. It is provided here for portibility and for clarity. *********************************************************************/ /******************************************************************** Note: The C code must be able to detect over/underflow. Therefore 32 bit integers must be used when doing 16 bit math. All we really need is one more bit, such as is provided in asm with the carry bit. Functions that don't need the test for over/underflow, such as cmp_bn() and is_bn_not_zero(), can use 32 bit integers as as long as bnstep is set to 4. The 16/32 bit compination of integer sizes could be increased to 32/64 bit to improve efficiency, but since many compilers don't offer 64 bit integers, this option was not included. *********************************************************************/ /********************************************************************/ /* r = 0 */ bn_t clear_bn(bn_t r) { #ifdef BIG_BASED _fmemset( r, 0, bnlength); /* set array to zero */ #else #ifdef BIG_FAR _fmemset( r, 0, bnlength); /* set array to zero */ #else memset( r, 0, bnlength); /* set array to zero */ #endif #endif return r; } /********************************************************************/ /* r = max positive value */ bn_t max_bn(bn_t r) { #ifdef BIG_BASED _fmemset( r, 0xFF, bnlength-1); /* set to max values */ #else #ifdef BIG_FAR _fmemset( r, 0xFF, bnlength-1); /* set to max values */ #else memset( r, 0xFF, bnlength-1); /* set to max values */ #endif #endif r[bnlength-1] = 0x7F; /* turn off the sign bit */ return r; } /********************************************************************/ /* r = n */ bn_t copy_bn(bn_t r, bn_t n) { #ifdef BIG_BASED _fmemcpy( r, n, bnlength); #else #ifdef BIG_FAR _fmemcpy( r, n, bnlength); #else memcpy( r, n, bnlength); #endif #endif return r; } /***************************************************************************/ /* n1 != n2 ? */ /* RETURNS: */ /* if n1 == n2 returns 0 */ /* if n1 > n2 returns a positive (bytes left to go when mismatch occured) */ /* if n1 < n2 returns a negative (bytes left to go when mismatch occured) */ int cmp_bn(bn_t n1, bn_t n2) { int i; S16 Svalue1, Svalue2; U16 value1, value2; /* two bytes at a time */ /* signed comparison for msb */ if ( (Svalue1=big_accessS16((S16 BIGDIST *)(n1+bnlength-2))) > (Svalue2=big_accessS16((S16 BIGDIST *)(n2+bnlength-2))) ) { /* now determine which of the two bytes was different */ if ( (S16)(Svalue1&0xFF00) > (S16)(Svalue2&0xFF00) ) /* compare just high bytes */ return (bnlength); /* high byte was different */ else return (bnlength-1); /* low byte was different */ } else if (Svalue1 < Svalue2) { /* now determine which of the two bytes was different */ if ( (S16)(Svalue1&0xFF00) < (S16)(Svalue2&0xFF00) ) /* compare just high bytes */ return -(bnlength); /* high byte was different */ else return -(bnlength-1); /* low byte was different */ } /* unsigned comparison for the rest */ for (i=bnlength-4; i>=0; i-=2) { if ( (value1=big_access16(n1+i)) > (value2=big_access16(n2+i)) ) { /* now determine which of the two bytes was different */ if ( (value1&0xFF00) > (value2&0xFF00) ) /* compare just high bytes */ return (i+2); /* high byte was different */ else return (i+1); /* low byte was different */ } else if (value1 < value2) { /* now determine which of the two bytes was different */ if ( (value1&0xFF00) < (value2&0xFF00) ) /* compare just high bytes */ return -(i+2); /* high byte was different */ else return -(i+1); /* low byte was different */ } } return 0; } /********************************************************************/ /* r < 0 ? */ /* returns 1 if negative, 0 if positive or zero */ int is_bn_neg(bn_t n) { return (S8)n[bnlength-1] < 0; } /********************************************************************/ /* n != 0 ? */ /* RETURNS: if n != 0 returns 1 */ /* else returns 0 */ int is_bn_not_zero(bn_t n) { int i; /* two bytes at a time */ for (i=0; i>= 16; /* shift the overflow for next time */ } return r; } /********************************************************************/ /* r += n */ bn_t add_a_bn(bn_t r, bn_t n) { int i; U32 sum=0; /* two bytes at a time */ for (i=0; i>= 16; /* shift the overflow for next time */ } return r; } /********************************************************************/ /* r = n1 - n2 */ bn_t sub_bn(bn_t r, bn_t n1, bn_t n2) { int i; U32 diff=0; /* two bytes at a time */ for (i=0; i>= 16; /* shift the underflow for next time */ } return r; } /********************************************************************/ /* r -= n */ bn_t sub_a_bn(bn_t r, bn_t n) { int i; U32 diff=0; /* two bytes at a time */ for (i=0; i>= 16; /* shift the underflow for next time */ } return r; } /********************************************************************/ /* r = -n */ bn_t neg_bn(bn_t r, bn_t n) { int i; U16 t_short; U32 neg=1; /* to get the 2's complement started */ /* two bytes at a time */ for (i=0; neg != 0 && i>= 16; /* shift the sign bit for next time */ } /* if neg was 0, then just "not" the rest */ for (; i>= 16; /* shift the sign bit for next time */ } /* if neg was 0, then just "not" the rest */ for (; i>= 16; /* shift the overflow for next time */ } return r; } /********************************************************************/ /* r *= 2 */ bn_t double_a_bn(bn_t r) { int i; U32 prod=0; /* two bytes at a time */ for (i=0; i>= 16; /* shift the overflow for next time */ } return r; } /********************************************************************/ /* r = n/2 */ bn_t half_bn(bn_t r, bn_t n) { int i; U32 quot=0; /* two bytes at a time */ /* start with an arithmetic shift */ i=bnlength-2; quot += (U32)(((S32)(S16)big_access16(n+i)<<16)>>1) ; /* shift to upper 2 bytes and half it */ big_set16(r+i, (U16)(quot>>16)); /* store the upper 2 bytes */ quot <<= 16; /* shift the underflow for next time */ for (i=bnlength-4; i>=0; i-=2) { /* looks wierd, but properly sign extends argument */ quot += (U32)(((U32)big_access16(n+i)<<16)>>1) ; /* shift to upper 2 bytes and half it */ big_set16(r+i, (U16)(quot>>16)); /* store the upper 2 bytes */ quot <<= 16; /* shift the underflow for next time */ } return r; } /********************************************************************/ /* r /= 2 */ bn_t half_a_bn(bn_t r) { int i; U32 quot=0; /* two bytes at a time */ /* start with an arithmetic shift */ i=bnlength-2; quot += (U32)(((S32)(S16)big_access16(r+i)<<16)>>1) ; /* shift to upper 2 bytes and half it */ big_set16(r+i, (U16)(quot>>16)); /* store the upper 2 bytes */ quot <<= 16; /* shift the underflow for next time */ for (i=bnlength-4; i>=0; i-=2) { /* looks wierd, but properly sign extends argument */ quot += (U32)(((U32)(U16)big_access16(r+i)<<16)>>1) ; /* shift to upper 2 bytes and half it */ big_set16(r+i, (U16)(quot>>16)); /* store the upper 2 bytes */ quot <<= 16; /* shift the underflow for next time */ } return r; } /************************************************************************/ /* r = n1 * n2 */ /* Note: r will be a double wide result, 2*bnlength */ /* n1 and n2 can be the same pointer */ /* SIDE-EFFECTS: n1 and n2 are changed to their absolute values */ bn_t unsafe_full_mult_bn(bn_t r, bn_t n1, bn_t n2) { int sign1, sign2 = 0, samevar; int i, j, k, steps, doublesteps, carry_steps; bn_t n1p, n2p; /* pointers for n1, n2 */ bn_t rp1, rp2, rp3; /* pointers for r */ U32 prod, sum; if ((sign1 = is_bn_neg(n1)) != 0) /* =, not == */ neg_a_bn(n1); samevar = (n1 == n2); if (!samevar) /* check to see if they're the same pointer */ if ((sign2 = is_bn_neg(n2)) != 0) /* =, not == */ neg_a_bn(n2); n1p = n1; steps = bnlength>>1; /* two bytes at a time */ carry_steps = doublesteps = (steps<<1) - 2; bnlength <<= 1; clear_bn(r); /* double width */ bnlength >>= 1; rp1 = rp2 = r; for (i = 0; i < steps; i++) { n2p = n2; for (j = 0; j < steps; j++) { prod = (U32)big_access16(n1p) * (U32)big_access16(n2p); /* U16*U16=U32 */ sum = (U32)big_access16(rp2) + prod; /* add to previous, including overflow */ big_set16(rp2, (U16)sum); /* save the lower 2 bytes */ sum >>= 16; /* keep just the upper 2 bytes */ rp3 = rp2 + 2; /* move over 2 bytes */ sum += big_access16(rp3); /* add what was the upper two bytes */ big_set16(rp3 ,(U16)sum); /* save what was the upper two bytes */ sum >>= 16; /* keep just the overflow */ for (k=0; sum != 0 && k>= 16; /* keep just the new overflow */ } n2p += 2; /* to next word */ rp2 += 2; carry_steps--; /* use one less step */ } n1p += 2; /* to next word */ rp2 = rp1 += 2; carry_steps = --doublesteps; /* decrease doubles steps and reset carry_steps */ } /* if they were the same or same sign, the product must be positive */ if (!samevar && sign1 != sign2) { bnlength <<= 1; /* for a double wide number */ neg_a_bn(r); bnlength >>= 1; /* restore bnlength */ } return r; } /************************************************************************/ /* r = n1 * n2 calculating only the top rlength bytes */ /* Note: r will be of length rlength */ /* 2*bnlength <= rlength < bnlength */ /* n1 and n2 can be the same pointer */ /* SIDE-EFFECTS: n1 and n2 are changed to their absolute values */ bn_t unsafe_mult_bn(bn_t r, bn_t n1, bn_t n2) { int sign1, sign2 = 0, samevar; int i, j, k, steps, doublesteps, carry_steps, skips; bn_t n1p, n2p; /* pointers for n1, n2 */ bn_t rp1, rp2, rp3; /* pointers for r */ U32 prod, sum; int bnl; /* temp bnlength holder */ bnl = bnlength; if ((sign1 = is_bn_neg(n1)) != 0) /* =, not == */ neg_a_bn(n1); samevar = (n1 == n2); if (!samevar) /* check to see if they're the same pointer */ if ((sign2 = is_bn_neg(n2)) != 0) /* =, not == */ neg_a_bn(n2); n1p = n1; n2 += (bnlength<<1) - rlength; /* shift n2 over to where it is needed */ bnlength = rlength; clear_bn(r); /* zero out r, rlength width */ bnlength = bnl; steps = (rlength-bnlength)>>1; skips = (bnlength>>1) - steps; carry_steps = doublesteps = (rlength>>1)-2; rp2 = rp1 = r; for (i=bnlength>>1; i>0; i--) { n2p = n2; for (j=0; j>= 16; /* keep just the upper 2 bytes */ rp3 = rp2 + 2; /* move over 2 bytes */ sum += big_access16(rp3); /* add what was the upper two bytes */ big_set16(rp3, (U16)sum); /* save what was the upper two bytes */ sum >>= 16; /* keep just the overflow */ for (k=0; sum != 0 && k>= 16; /* keep just the new overflow */ } n2p += 2; /* increase by two bytes */ rp2 += 2; carry_steps--; } n1p += 2; /* increase by two bytes */ if (skips != 0) { n2 -= 2; /* shift n2 back a word */ steps++; /* one more step this time */ skips--; /* keep track of how many times we've done this */ } else { rp1 += 2; /* shift forward a word */ doublesteps--; /* reduce the carry steps needed next time */ } rp2 = rp1; carry_steps = doublesteps; } /* if they were the same or same sign, the product must be positive */ if (!samevar && sign1 != sign2) { bnlength = rlength; neg_a_bn(r); /* wider bignumber */ bnlength = bnl; } return r; } /************************************************************************/ /* r = n^2 */ /* because of the symetry involved, n^2 is much faster than n*n */ /* for a bignumber of length l */ /* n*n takes l^2 multiplications */ /* n^2 takes (l^2+l)/2 multiplications */ /* which is about 1/2 n*n as l gets large */ /* uses the fact that (a+b+c+...)^2 = (a^2+b^2+c^2+...)+2(ab+ac+bc+...)*/ /* */ /* SIDE-EFFECTS: n is changed to its absolute value */ bn_t unsafe_full_square_bn(bn_t r, bn_t n) { int i, j, k, steps, doublesteps, carry_steps; bn_t n1p, n2p; bn_t rp1, rp2, rp3; U32 prod, sum; if (is_bn_neg(n)) /* don't need to keep track of sign since the */ neg_a_bn(n); /* answer must be positive. */ bnlength <<= 1; clear_bn(r); /* zero out r, double width */ bnlength >>= 1; steps = (bnlength>>1)-1; carry_steps = doublesteps = (steps<<1) - 1; rp2 = rp1 = r + 2; /* start with second two-byte word */ n1p = n; if (steps != 0) /* if zero, then skip all the middle term calculations */ { for (i=steps; i>0; i--) /* steps gets altered, count backwards */ { n2p = n1p + 2; /* set n2p pointer to 1 step beyond n1p */ for (j=0; j>= 16; /* keep just the upper 2 bytes */ rp3 = rp2 + 2; /* move over 2 bytes */ sum += big_access16(rp3); /* add what was the upper two bytes */ big_set16(rp3, (U16)sum); /* save what was the upper two bytes */ sum >>= 16; /* keep just the overflow */ for (k=0; sum != 0 && k>= 16; /* keep just the new overflow */ } n2p += 2; /* increase by two bytes */ rp2 += 2; carry_steps--; } n1p += 2; /* increase by two bytes */ rp2 = rp1 += 4; /* increase by 2 * two bytes */ carry_steps = doublesteps -= 2; /* reduce the carry steps needed */ steps--; } /* All the middle terms have been multiplied. Now double it. */ bnlength <<= 1; /* double wide bignumber */ double_a_bn(r); bnlength >>= 1; /* finished with middle terms */ } /* Now go back and add in the squared terms. */ n1p = n; steps = (bnlength>>1); carry_steps = doublesteps = (steps<<1) - 2; rp1 = r; for (i=0; i>= 16; /* keep just the upper 2 bytes */ rp3 = rp1 + 2; /* move over 2 bytes */ sum += big_access16(rp3); /* add what was the upper two bytes */ big_set16(rp3, (U16)sum); /* save what was the upper two bytes */ sum >>= 16; /* keep just the overflow */ for (k=0; sum != 0 && k>= 16; /* keep just the new overflow */ } n1p += 2; /* increase by 2 bytes */ rp1 += 4; /* increase by 4 bytes */ carry_steps = doublesteps -= 2; } return r; } /************************************************************************/ /* r = n^2 */ /* because of the symetry involved, n^2 is much faster than n*n */ /* for a bignumber of length l */ /* n*n takes l^2 multiplications */ /* n^2 takes (l^2+l)/2 multiplications */ /* which is about 1/2 n*n as l gets large */ /* uses the fact that (a+b+c+...)^2 = (a^2+b^2+c^2+...)+2(ab+ac+bc+...)*/ /* */ /* Note: r will be of length rlength */ /* 2*bnlength >= rlength > bnlength */ /* SIDE-EFFECTS: n is changed to its absolute value */ bn_t unsafe_square_bn(bn_t r, bn_t n) { int i, j, k, steps, doublesteps, carry_steps; int skips, rodd; bn_t n1p, n2p, n3p; bn_t rp1, rp2, rp3; U32 prod, sum; int bnl; /* This whole procedure would be a great deal simpler if we could assume that */ /* rlength < 2*bnlength (that is, not =). Therefore, we will take the */ /* easy way out and call full_square_bn() if it is. */ if (rlength == (bnlength<<1)) /* rlength == 2*bnlength */ return unsafe_full_square_bn(r, n); /* call full_square_bn() and quit */ if (is_bn_neg(n)) /* don't need to keep track of sign since the */ neg_a_bn(n); /* answer must be positive. */ bnl = bnlength; bnlength = rlength; clear_bn(r); /* zero out r, of width rlength */ bnlength = bnl; /* determine whether r is on an odd or even two-byte word in the number */ rodd = (U16)(((bnlength<<1)-rlength)>>1) & 0x0001; i = (bnlength>>1)-1; steps = (rlength-bnlength)>>1; carry_steps = doublesteps = (bnlength>>1)+steps-2; skips = (i - steps)>>1; /* how long to skip over pointer shifts */ rp2 = rp1 = r; n1p = n; n3p = n2p = n1p + (((bnlength>>1)-steps)<<1); /* n2p = n1p + 2*(bnlength/2 - steps) */ if (i != 0) /* if zero, skip middle term calculations */ { /* i is already set */ for (; i>0; i--) { for (j=0; j>= 16; /* keep just the upper 2 bytes */ rp3 = rp2 + 2; /* move over 2 bytes */ sum += big_access16(rp3); /* add what was the upper two bytes */ big_set16(rp3, (U16)sum); /* save what was the upper two bytes */ sum >>= 16; /* keep just the overflow */ for (k=0; sum != 0 && k>= 16; /* keep just the new overflow */ } n2p += 2; /* increase by 2-byte word size */ rp2 += 2; carry_steps--; } n1p += 2; /* increase by 2-byte word size */ if (skips > 0) { n2p = n3p -= 2; steps++; skips--; } else if (skips == 0) /* only gets executed once */ { steps -= rodd; /* rodd is 1 or 0 */ doublesteps -= rodd+1; rp1 += (rodd+1)<<1; n2p = n1p+2; skips--; } else /* skips < 0 */ { steps--; doublesteps -= 2; rp1 += 4; /* add two 2-byte words */ n2p = n1p + 2; } rp2 = rp1; carry_steps = doublesteps; } /* All the middle terms have been multiplied. Now double it. */ bnlength = rlength; double_a_bn(r); bnlength = bnl; } /* Now go back and add in the squared terms. */ /* be careful, the next dozen or so lines are confusing! */ /* determine whether r is on an odd or even word in the number */ /* using i as a temporary variable here */ i = (bnlength<<1)-rlength; rp1 = r + ((U16)i & (U16)0x0002); i = (U16)((i>>1)+1) & (U16)0xFFFE; n1p = n + i; /* i here is no longer a temp var., but will be used as a loop counter */ i = (bnlength - i)>>1; carry_steps = doublesteps = (i<<1)-2; /* i is already set */ for (; i>0; i--) { /* square it */ prod = (U32)big_access16(n1p) * (U32)big_access16(n1p); /* U16*U16=U32 */ sum = (U32)big_access16(rp1) + prod; /* add to previous, including overflow */ big_set16(rp1, (U16)sum); /* save the lower 2 bytes */ sum >>= 16; /* keep just the upper 2 bytes */ rp3 = rp1 + 2; /* move over 2 bytes */ sum += big_access16(rp3); /* add what was the upper two bytes */ big_set16(rp3, (U16)sum); /* save what was the upper two bytes */ sum >>= 16; /* keep just the overflow */ for (k=0; sum != 0 && k>= 16; /* keep just the new overflow */ } n1p += 2; rp1 += 4; carry_steps = doublesteps -= 2; } return r; } /********************************************************************/ /* r = n * u where u is an unsigned integer */ bn_t mult_bn_int(bn_t r, bn_t n, U16 u) { int i; U32 prod=0; /* two bytes at a time */ for (i=0; i>= 16; /* shift the overflow for next time */ } return r; } /********************************************************************/ /* r *= u where u is an unsigned integer */ bn_t mult_a_bn_int(bn_t r, U16 u) { int i; U32 prod=0; /* two bytes at a time */ for (i=0; i>= 16; /* shift the overflow for next time */ } return r; } /********************************************************************/ /* r = n / u where u is an unsigned integer */ bn_t unsafe_div_bn_int(bn_t r, bn_t n, U16 u) { int i, sign; U32 full_number; U16 quot, rem=0; sign = is_bn_neg(n); if (sign) neg_a_bn(n); if (u == 0) /* division by zero */ { max_bn(r); if (sign) neg_a_bn(r); return r; } /* two bytes at a time */ for (i=bnlength-2; i>=0; i-=2) { full_number = ((U32)rem<<16) + (U32)big_access16(n+i); quot = (U16)(full_number / u); rem = (U16)(full_number % u); big_set16(r+i, quot); } if (sign) neg_a_bn(r); return r; } /********************************************************************/ /* r /= u where u is an unsigned integer */ bn_t div_a_bn_int(bn_t r, U16 u) { int i, sign; U32 full_number; U16 quot, rem=0; sign = is_bn_neg(r); if (sign) neg_a_bn(r); if (u == 0) /* division by zero */ { max_bn(r); if (sign) neg_a_bn(r); return r; } /* two bytes at a time */ for (i=bnlength-2; i>=0; i-=2) { full_number = ((U32)rem<<16) + (U32)big_access16(r+i); quot = (U16)(full_number / u); rem = (U16)(full_number % u); big_set16(r+i, quot); } if (sign) neg_a_bn(r); return r; } /*********************************************************************/ /* f = b */ /* Converts a bignumber to a double */ LDBL bntofloat(bn_t n) { int i; int signflag=0; int expon; bn_t getbyte; LDBL f=0; if (is_bn_neg(n)) { signflag = 1; neg_a_bn(n); } expon = intlength - 1; getbyte = n + bnlength - 1; while (*getbyte == 0 && getbyte >= n) { getbyte--; expon--; } /* There is no need to use all bnlength bytes. To get the full */ /* precision of LDBL, all you need is LDBL_MANT_DIG/8+1. */ for (i = 0; i < (LDBL_MANT_DIG/8+1) && getbyte >= n; i++, getbyte--) { f += scale_256(*getbyte,-i); } f = scale_256(f,expon); if (signflag) { f = -f; neg_a_bn(n); } return f; } /*****************************************/ /* the following used to be in bigfltc.c */ /********************************************************************/ /* r = 0 */ bf_t clear_bf(bf_t r) { _fmemset( r, 0, bflength+2); /* set array to zero */ return r; } /********************************************************************/ /* r = n */ bf_t copy_bf(bf_t r, bf_t n) { _fmemcpy( r, n, bflength+2); return r; } /*********************************************************************/ /* b = f */ /* Converts a double to a bigfloat */ bf_t floattobf(bf_t r, LDBL f) { int power; int bnl, il; if (f == 0) { clear_bf(r); return r; } /* remove the exp part */ f = extract_256(f, &power); bnl = bnlength; bnlength = bflength; il = intlength; intlength = 2; floattobn(r, f); bnlength = bnl; intlength = il; big_set16(r + bflength, (S16)power); /* exp */ return r; } /*********************************************************************/ /* b = f */ /* Converts a double to a bigfloat */ bf_t floattobf1(bf_t r, LDBL f) { char msg[80]; #ifdef USE_LONG_DOUBLE sprintf(msg,"%-.22Le",f); #else sprintf(msg,"%-.22le",f); #endif strtobf(r,msg); return r; } /*********************************************************************/ /* f = b */ /* Converts a bigfloat to a double */ LDBL bftofloat(bf_t n) { int power; int bnl, il; LDBL f; bnl = bnlength; bnlength = bflength; il = intlength; intlength = 2; f = bntofloat(n); bnlength = bnl; intlength = il; power = (S16)big_access16(n + bflength); f = scale_256(f,power); return f; } /********************************************************************/ /* extracts the mantissa and exponent of f */ /* finds m and n such that 1<=|m|<256 and f = m*256^n */ /* n is stored in *exp_ptr and m is returned, sort of like frexp() */ LDBL extract_256(LDBL f, int *exp_ptr) { return extract_value(f, 256, exp_ptr); } /********************************************************************/ /* calculates and returns the value of f*256^n */ /* sort of like ldexp() */ /* */ /* n must be in the range -2^12 <= n < 2^12 (2^12=4096), */ /* which should not be a problem */ LDBL scale_256( LDBL f, int n ) { return scale_value( f, 256, n ); } xfractint-20.4.10.orig/common/Makefile0000755000000000000000000001574210541652036014453 0ustar SHELL=/bin/sh OBJS = \ 3d.o ant.o bigflt.o biginit.o bignum.o bignumc.o calcfrac.o \ cmdfiles.o decoder.o editpal.o encoder.o \ evolve.o f16.o fracsubr.o fractalb.o fractalp.o fractals.o \ fractint.o framain2.o frasetup.o gifview.o hcmplx.o help.o history.o\ intro.o jb.o jiim.o line3d.o loadfdos.o loadfile.o loadmap.o lorenz.o \ lsys.o lsysf.o memory.o miscfrac.o miscovl.o miscres.o mpmath_c.o parser.o \ parserfp.o plot3d.o printer.o prompts1.o prompts2.o \ realdos.o rotate.o slideshw.o soi.o soi1.o stereo.o targa.o testpt.o tgaview.o \ zoom.o #Need to prevent lex from doing fractint.l -> fractint.c .SUFFIXES: .SUFFIXES: .o .c .s .h .asm all: $(OBJS) tidy: rm -f $(OBJS) clean: rm -f $(OBJS) fractint.o: fractint.c $(CC) $(CFLAGS) -DSRCDIR=\"$(SRCDIR)\" -c fractint.c help.o: help.c $(CC) $(CFLAGS) -DSRCDIR=\"$(SRCDIR)\" -c help.c copy: $(FILES) mv $(FILES) backup # DO NOT DELETE THIS LINE -- make depend depends on it. 3d.o: 3d.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h ant.o: ant.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h ${HFD}/helpdefs.h bigflt.o: bigflt.c ${HFD}/big.h ${HFD}/biginit.h biginit.o: biginit.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h \ ${HFD}/big.h bignum.o: bignum.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h bignumc.o: bignumc.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h calcfrac.o: calcfrac.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/mpmath.h ${HFD}/targa_lc.h \ ${HFD}/prototyp.h ${HFD}/helpcom.h cmdfiles.o: cmdfiles.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/prototyp.h ${HFD}/mpmath.h \ ${HFD}/helpcom.h decoder.o: decoder.c ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/port.h ${HFD}/fractint.h ${HFD}/helpcom.h editpal.o: editpal.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h encoder.o: encoder.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h f16.o: f16.c ${HFD}/targa_lc.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/port.h ${HFD}/fractint.h ${HFD}/helpcom.h fracsubr.o: fracsubr.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/mpmath.h ${HFD}/prototyp.h \ ${HFD}/helpcom.h fractalb.o: fractalb.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h \ ${HFD}/helpdefs.h ${HFD}/fractype.h fractalp.o: fractalp.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/mpmath.h ${HFD}/helpdefs.h ${HFD}/fractype.h \ ${HFD}/prototyp.h ${HFD}/helpcom.h fractals.o: fractals.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/mpmath.h ${HFD}/helpdefs.h ${HFD}/fractype.h \ ${HFD}/prototyp.h ${HFD}/helpcom.h fractint.o: fractint.c ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/port.h ${HFD}/fractint.h ${HFD}/helpcom.h \ ${HFD}/fractype.h ${HFD}/helpdefs.h framain2.o: framain2.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h \ ${HFD}/fractype.h ${HFD}/helpdefs.h frasetup.o: frasetup.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h \ ${HFD}/mpmath.h ${HFD}/helpdefs.h ${HFD}/fractype.h gifview.o: gifview.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h hcmplx.o: hcmplx.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h ${HFD}/mpmath.h help.o: help.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/helpcom.h ${HFD}/helpdefs.h ${HFD}/prototyp.h ${HFD}/mpmath.h history.o: history.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h intro.o: intro.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/helpdefs.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h jb.o: jb.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/mpmath.h ${HFD}/helpdefs.h ${HFD}/prototyp.h ${HFD}/helpcom.h jiim.o: jiim.c ${HFD}/helpdefs.h ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/prototyp.h ${HFD}/mpmath.h \ ${HFD}/helpcom.h line3d.o: line3d.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h loadfdos.o: loadfdos.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/helpdefs.h ${HFD}/prototyp.h ${HFD}/mpmath.h \ ${HFD}/helpcom.h loadfile.o: loadfile.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/targa_lc.h ${HFD}/prototyp.h \ ${HFD}/mpmath.h ${HFD}/helpcom.h loadmap.o: loadmap.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h lorenz.o: lorenz.c ${HFD}/mpmath.h ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/prototyp.h ${HFD}/helpcom.h lsys.o: lsys.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h lsysf.o: lsysf.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h ${HFD}/lsys.h miscfrac.o: miscfrac.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h \ ${HFD}/fractype.h ${HFD}/targa_lc.h miscovl.o: miscovl.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/helpdefs.h ${HFD}/prototyp.h \ ${HFD}/mpmath.h ${HFD}/helpcom.h miscres.o: miscres.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/helpdefs.h ${HFD}/prototyp.h \ ${HFD}/mpmath.h ${HFD}/helpcom.h mpmath_c.o: mpmath_c.c ${HFD}/mpmath.h ${HFD}/prototyp.h ${HFD}/port.h ${HFD}/fractint.h ${HFD}/helpcom.h parser.o: parser.c ${HFD}/mpmath.h ${HFD}/prototyp.h ${HFD}/port.h ${HFD}/fractint.h ${HFD}/helpcom.h parserfp.o: parserfp.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h plot3d.o: plot3d.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h printer.o: printer.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h prompts1.o: prompts1.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/helpdefs.h ${HFD}/prototyp.h \ ${HFD}/mpmath.h ${HFD}/helpcom.h prompts2.o: prompts2.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/helpdefs.h ${HFD}/prototyp.h \ ${HFD}/mpmath.h ${HFD}/helpcom.h realdos.o: realdos.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/fractype.h ${HFD}/helpdefs.h ${HFD}/prototyp.h \ ${HFD}/mpmath.h ${HFD}/helpcom.h rotate.o: rotate.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/helpdefs.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h slideshw.o: slideshw.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h stereo.o: stereo.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h ${HFD}/helpdefs.h targa.o: targa.c ${HFD}/targa.h ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h testpt.o: testpt.c tgaview.o: tgaview.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/targa_lc.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h tp3d.o: tp3d.c ${HFD}/mpmath.h ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/helpcom.h zoom.o: zoom.c ${HFD}/fractint.h ${HFD}/port.h ${HFD}/prototyp.h ${HFD}/mpmath.h ${HFD}/helpcom.h xfractint-20.4.10.orig/common/framain2.c0000644000000000000000000021574111011103106014632 0ustar #include #include #ifndef XFRACT #include #endif #ifndef USE_VARARGS #include #else #include #endif #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" #if 0 /* makes a handly list of jul-man pairs, not for release */ static void julman() { FILE *fp; int i; fp = dir_fopen(workdir,"toggle.txt","w"); i = -1; while(fractalspecific[++i].name) { if(fractalspecific[i].tojulia != NOFRACTAL && fractalspecific[i].name[0] != '*') fprintf(fp,"%s %s\n",fractalspecific[i].name, fractalspecific[fractalspecific[i].tojulia].name); } fclose(fp); } #endif /* routines in this module */ int main_menu_switch(int*,int*,int*,char*,int); int evolver_menu_switch(int*,int*,int*,char*); int big_while_loop(int *kbdmore, char *stacked, int resumeflag); static void move_zoombox(int); char fromtext_flag = 0; /* = 1 if we're in graphics mode */ static int call_line3d(BYTE *pixels, int linelen); static void note_zoom(void); static void restore_zoom(void); static void move_zoombox(int keynum); static void cmp_line_cleanup(void); U16 evolve_handle = 0; char old_stdcalcmode; static char far *savezoom; void (*outln_cleanup) (void); int big_while_loop(int *kbdmore, char *stacked, int resumeflag) { int frommandel; /* if julia entered from mandel */ int axmode=0, bxmode, cxmode, dxmode; /* video mode (BIOS ##) */ double ftemp; /* fp temp */ int i=0; /* temporary loop counters */ int kbdchar; int mms_value; frommandel = 0; if(resumeflag) goto resumeloop; for(;;) { /* eternal loop */ if (calc_status != 2 || showfile == 0) { #ifdef XFRACT if (resizeWindow()) { calc_status = -1; } #endif far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter], sizeof(videoentry)); axmode = videoentry.videomodeax; /* video mode (BIOS call) */ bxmode = videoentry.videomodebx; /* video mode (BIOS call) */ cxmode = videoentry.videomodecx; /* video mode (BIOS call) */ dxmode = videoentry.videomodedx; /* video mode (BIOS call) */ dotmode = videoentry.dotmode; /* assembler dot read/write */ xdots = videoentry.xdots; /* # dots across the screen */ ydots = videoentry.ydots; /* # dots down the screen */ colors = videoentry.colors; /* # colors available */ dotmode %= 1000; textsafe2 = dotmode / 100; dotmode %= 100; sxdots = xdots; sydots = ydots; sxoffs = syoffs = 0; rotate_hi = (rotate_hi < colors) ? rotate_hi : colors - 1; diskvideo = 0; /* set diskvideo flag */ if (dotmode == 11) /* default assumption is disk */ diskvideo = 2; memcpy(olddacbox,dacbox,256*3); /* save the DAC */ diskisactive = 1; /* flag for disk-video routines */ if (overlay3d && !initbatch) { unstackscreen(); /* restore old graphics image */ overlay3d = 0; } else { setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */ if (goodmode == 0) { static FCODE msg[] = {"That video mode is not available with your adapter."}; #ifndef XFRACT static FCODE TPlusStr[] = "This video mode requires 'noninterlaced=yes'"; if(TPlusErr) { stopmsg(0, TPlusStr); TPlusErr = 0; } else #endif if(dotmode == 11) { askvideo = TRUE; } else { stopmsg(0,msg); askvideo = TRUE; } initmode = -1; setvideotext(); /* switch to text mode */ /* goto restorestart; */ return(RESTORESTART); } if (virtual && (xdots > sxdots || ydots > sydots)) { char buf[120]; static FCODE msgxy1[] = {"Can't set virtual line that long, width cut down."}; static FCODE msgxy2[] = {"Not enough video memory for that many lines, height cut down."}; if (xdots > sxdots && ydots > sydots) { #ifndef XFRACT sprintf(buf,"%Fs\n%Fs",(char far *)msgxy1,(char far *)msgxy2); #else sprintf(buf,"%s\n%s",(char far *)msgxy1,(char far *)msgxy2); #endif stopmsg(0,buf); } else if (ydots > sydots) { stopmsg(0,msgxy2); } else { stopmsg(0,msgxy1); } } xdots = sxdots; ydots = sydots; videoentry.xdots = xdots; videoentry.ydots = ydots; } diskisactive = 0; /* flag for disk-video routines */ if (savedac || colorpreloaded) { memcpy(dacbox,olddacbox,256*3); /* restore the DAC */ spindac(0,1); colorpreloaded = 0; } else { /* reset DAC to defaults, which setvideomode has done for us */ if (mapdacbox) { /* but there's a map=, so load that */ far_memcpy((char far *)dacbox,mapdacbox,768); spindac(0,1); } else if ((dotmode == 11 && colors == 256) || !colors) { /* disk video, setvideomode via bios didn't get it right, so: */ #ifndef XFRACT ValidateLuts("default"); /* read the default palette file */ #endif } colorstate = 0; } if (viewwindow) { ftemp = finalaspectratio /* bypass for VESA virtual screen */ * ((dotmode == 28 && ((vesa_xres && vesa_xres != sxdots) || (vesa_yres && vesa_yres != sydots))) ? 1 : (double)sydots / (double)sxdots / screenaspect); if ((xdots = viewxdots) != 0) { /* xdots specified */ if ((ydots = viewydots) == 0) /* calc ydots? */ ydots = (int)((double)xdots * ftemp + 0.5); } else if (finalaspectratio <= screenaspect) { xdots = (int)((double)sxdots / viewreduction + 0.5); ydots = (int)((double)xdots * ftemp + 0.5); } else { ydots = (int)((double)sydots / viewreduction + 0.5); xdots = (int)((double)ydots / ftemp + 0.5); } if (xdots > sxdots || ydots > sydots) { static FCODE msg[] = {"View window too large; using full screen."}; stopmsg(0,msg); viewwindow = 0; xdots = viewxdots = sxdots; ydots = viewydots = sydots; } else if (((xdots <= 1) /* changed test to 1, so a 2x2 window will */ || (ydots <= 1)) /* work with the sound feature */ && !(evolving&1)) { /* so ssg works */ /* but no check if in evolve mode to allow lots of small views*/ static FCODE msg[] = {"View window too small; using full screen."}; stopmsg(0,msg); viewwindow = 0; xdots = sxdots; ydots = sydots; } if ((evolving&1) && (curfractalspecific->flags&INFCALC)) { static FCODE msg[] = {"Fractal doesn't terminate! switching off evolution."}; stopmsg(0,msg); evolving = evolving -1; viewwindow = FALSE; xdots=sxdots; ydots=sydots; } if (evolving&1) { xdots = (sxdots / gridsz)-!((evolving & NOGROUT)/NOGROUT); xdots = xdots - (xdots % 4); /* trim to multiple of 4 for SSG */ ydots = (sydots / gridsz)-!((evolving & NOGROUT)/NOGROUT); ydots = ydots - (ydots % 4); } else { sxoffs = (sxdots - xdots) / 2; syoffs = (sydots - ydots) / 3; } } dxsize = xdots - 1; /* convert just once now */ dysize = ydots - 1; } if(savedac == 0) savedac = 2; /* assume we save next time (except jb) */ else savedac = 1; /* assume we save next time */ if (initbatch == 0) lookatmouse = -PAGE_UP; /* mouse left button == pgup */ if(showfile == 0) { /* loading an image */ outln_cleanup = NULL; /* outln routine can set this */ if (display3d) /* set up 3D decoding */ outln = call_line3d; else if(filetype >= 1) /* old .tga format input file */ outln = outlin16; else if(comparegif) /* debug 50 */ outln = cmp_line; else if(pot16bit) { /* .pot format input file */ if (pot_startdisk() < 0) { /* pot file failed? */ showfile = 1; potflag = 0; pot16bit = 0; initmode = -1; calc_status = 2; /* "resume" without 16-bit */ setvideotext(); get_fracttype(); /* goto imagestart; */ return(IMAGESTART); } outln = pot_line; } else if((soundflag&7) > 1 && !evolving) /* regular gif/fra input file */ outln = sound_line; /* sound decoding */ else outln = out_line; /* regular decoding */ if(filetype == 0) { if(debugflag==2224) { char msg[MSGLEN]; sprintf(msg,"floatflag=%d",usr_floatflag); stopmsg(4,(char far *)msg); } i = funny_glasses_call(gifview); } else i = funny_glasses_call(tgaview); if(outln_cleanup) /* cleanup routine defined? */ (*outln_cleanup)(); if(i == 0) buzzer(0); else { calc_status = -1; if (keypressed()) { static FCODE msg[] = {"*** load incomplete ***"}; buzzer(1); while (keypressed()) getakey(); texttempmsg(msg); } } } zoomoff = 1; /* zooming is enabled */ if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0) zoomoff = 0; /* for these cases disable zooming */ if (!evolving) calcfracinit(); #ifdef XFRACT schedulealarm(1); #endif sxmin = xxmin; /* save 3 corners for zoom.c ref points */ sxmax = xxmax; sx3rd = xx3rd; symin = yymin; symax = yymax; sy3rd = yy3rd; if(bf_math) { copy_bf(bfsxmin,bfxmin); copy_bf(bfsxmax,bfxmax); copy_bf(bfsymin,bfymin); copy_bf(bfsymax,bfymax); copy_bf(bfsx3rd,bfx3rd); copy_bf(bfsy3rd,bfy3rd); } save_history_info(); if (display3d || showfile) { /* paranoia: these vars don't get set */ save_system = active_system; /* unless really doing some work, */ } /* so simple + keeps number */ if(showfile == 0) { /* image has been loaded */ showfile = 1; if (initbatch == 1 && calc_status == 2) initbatch = -1; /* flag to finish calc before save */ if (loaded3d) /* 'r' of image created with '3' */ display3d = 1; /* so set flag for 'b' command */ } else { /* draw an image */ diskisactive = 1; /* flag for disk-video routines */ if (initsavetime != 0 /* autosave and resumable? */ && (curfractalspecific->flags&NORESUME) == 0) { savebase = readticker(); /* calc's start time */ saveticks = abs(initsavetime); saveticks *= 1092; /* bios ticks/minute */ if ((saveticks & 65535L) == 0) ++saveticks; /* make low word nonzero */ finishrow = -1; } browsing = FALSE; /* regenerate image, turn off browsing */ /*rb*/ name_stack_ptr = -1; /* reset pointer */ browsename[0] = '\0'; /* null */ if (viewwindow && (evolving&1) && (calc_status != 4)) /*generate a set of images with varied parameters on each one*/ { int grout,ecount,tmpxdots,tmpydots,gridsqr; struct evolution_info resume_e_info; GENEBASE gene[NUMGENES]; /* get the gene array from far memory */ MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); if ((evolve_handle != 0) && (calc_status == 2)) { MoveFromMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle); paramrangex = resume_e_info.paramrangex; paramrangey = resume_e_info.paramrangey; opx = newopx = resume_e_info.opx; opy = newopy = resume_e_info.opy; odpx = newodpx = (char)resume_e_info.odpx; odpy = newodpy = (char)resume_e_info.odpy; px = resume_e_info.px; py = resume_e_info.py; sxoffs = resume_e_info.sxoffs; syoffs = resume_e_info.syoffs; xdots = resume_e_info.xdots; ydots = resume_e_info.ydots; gridsz = resume_e_info.gridsz; this_gen_rseed = resume_e_info.this_gen_rseed; fiddlefactor = resume_e_info.fiddlefactor; evolving = viewwindow = resume_e_info.evolving; ecount = resume_e_info.ecount; MemoryRelease(evolve_handle); /* We're done with it, release it. */ evolve_handle = 0; } else { /* not resuming, start from the beginning */ int mid = gridsz / 2; if ((px != mid) || (py != mid)) { this_gen_rseed = (unsigned int)clock_ticks(); /* time for new set */ } param_history(0); /* save old history */ ecount = 0; fiddlefactor = fiddlefactor * fiddle_reduction; opx = newopx; opy = newopy; odpx = newodpx; odpy = newodpy; /*odpx used for discrete parms like inside, outside, trigfn etc */ } prmboxcount = 0; dpx=paramrangex/(gridsz-1); dpy=paramrangey/(gridsz-1); grout = !((evolving & NOGROUT)/NOGROUT); tmpxdots = xdots+grout; tmpydots = ydots+grout; gridsqr = gridsz * gridsz; while ( ecount < gridsqr ) { spiralmap(ecount); /* sets px & py */ sxoffs = tmpxdots * px; syoffs = tmpydots * py; param_history(1); /* restore old history */ fiddleparms(gene, ecount); calcfracinit(); if (calcfract() == -1) goto done; ecount ++; } done: if (ecount == gridsqr) { i = 0; buzzer(0); /* finished!! */ } else { /* interrupted screen generation, save info */ if (evolve_handle == 0) evolve_handle = MemoryAlloc((U16)sizeof(resume_e_info),1L,FARMEM); resume_e_info.paramrangex = paramrangex; resume_e_info.paramrangey = paramrangey; resume_e_info.opx = opx; resume_e_info.opy = opy; resume_e_info.odpx = (short)odpx; resume_e_info.odpy = (short)odpy; resume_e_info.px = (short)px; resume_e_info.py = (short)py; resume_e_info.sxoffs = (short)sxoffs; resume_e_info.syoffs = (short)syoffs; resume_e_info.xdots = (short)xdots; resume_e_info.ydots = (short)ydots; resume_e_info.gridsz = (short)gridsz; resume_e_info.this_gen_rseed = (short)this_gen_rseed; resume_e_info.fiddlefactor = fiddlefactor; resume_e_info.evolving = (short)evolving; resume_e_info.ecount = (short) ecount; MoveToMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle); } sxoffs = syoffs = 0; xdots = sxdots; ydots = sydots; /* otherwise save only saves a sub image and boxes get clipped */ /* set up for 1st selected image, this reuses px and py */ px = py = gridsz/2; unspiralmap(); /* first time called, w/above line sets up array */ param_history(1); /* restore old history */ fiddleparms(gene, 0); /* now put the gene array back in far memory */ MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); } /* end of evolution loop */ else { i = calcfract(); /* draw the fractal using "C" */ if (i == 0) buzzer(0); /* finished!! */ } saveticks = 0; /* turn off autosave timer */ if (dotmode == 11 && i == 0) /* disk-video */ { static FCODE o_msg[] = {"Image has been completed"}; char msg[sizeof(o_msg)]; far_strcpy(msg,o_msg); dvid_status(0,msg); } diskisactive = 0; /* flag for disk-video routines */ } #ifndef XFRACT boxcount = 0; /* no zoom box yet */ zwidth = 0; #else if (!XZoomWaiting) { boxcount = 0; /* no zoom box yet */ zwidth = 0; } #endif if (fractype == PLASMA && cpu > 88) { cyclelimit = 256; /* plasma clouds need quick spins */ daccount = 256; daclearn = 1; } resumeloop: /* return here on failed overlays */ *kbdmore = 1; while (*kbdmore == 1) { /* loop through command keys */ if (timedsave != 0) { if (timedsave == 1) { /* woke up for timed save */ getakey(); /* eat the dummy char */ kbdchar = 's'; /* do the save */ resave_flag = 1; timedsave = 2; } else { /* save done, resume */ timedsave = 0; resave_flag = 2; kbdchar = ENTER; } } else if (initbatch == 0) { /* not batch mode */ #ifndef XFRACT lookatmouse = (zwidth == 0 && !video_scroll) ? -PAGE_UP : 3; #else lookatmouse = (zwidth == 0) ? -PAGE_UP : 3; #endif if (calc_status == 2 && zwidth == 0 && !keypressed()) { kbdchar = ENTER ; /* no visible reason to stop, continue */ } else { /* wait for a real keystroke */ if (autobrowse && !no_sub_images) kbdchar = 'l'; else { #ifndef XFRACT while (!keypressed());/* { }*/ /* enables help */ #else waitkeypressed(0); #endif kbdchar = getakey(); } if (kbdchar == ESC || kbdchar == 'm' || kbdchar == 'M') { if (kbdchar == ESC && escape_exit != 0) /* don't ask, just get out */ goodbye(); stackscreen(); #ifndef XFRACT kbdchar = main_menu(1); #else if (XZoomWaiting) { kbdchar = ENTER; } else { kbdchar = main_menu(1); if (XZoomWaiting) { kbdchar = ENTER; } } #endif if (kbdchar == '\\' || kbdchar == CTL_BACKSLASH || kbdchar == 'h' || kbdchar == 8 || check_vidmode_key(0,kbdchar) >= 0) discardscreen(); else if (kbdchar == 'x' || kbdchar == 'y' || kbdchar == 'z' || kbdchar == 'g' || kbdchar == 'v' || kbdchar == 2 || kbdchar == 5 || kbdchar == 6) fromtext_flag = 1; else unstackscreen(); } } } else { /* batch mode, fake next keystroke */ /* initbatch == -1 flag to finish calc before save */ /* initbatch == 0 not in batch mode */ /* initbatch == 1 normal batch mode */ /* initbatch == 2 was 1, now do a save */ /* initbatch == 3 bailout with errorlevel == 2, error occurred, no save */ /* initbatch == 4 bailout with errorlevel == 1, interrupted, try to save */ /* initbatch == 5 was 4, now do a save */ if (initbatch == -1) { /* finish calc */ kbdchar = ENTER; initbatch = 1; } else if (initbatch == 1 || initbatch == 4 ) { /* save-to-disk */ /* while(keypressed()) getakey(); */ if (debugflag == 50) kbdchar = 'r'; else kbdchar = 's'; if(initbatch == 1) initbatch = 2; if(initbatch == 4) initbatch = 5; } else { if(calc_status != 4) initbatch = 3; /* bailout with error */ goodbye(); /* done, exit */ } } #ifndef XFRACT if ('A' <= kbdchar && kbdchar <= 'Z') kbdchar = tolower(kbdchar); #endif if (evolving) mms_value = evolver_menu_switch(&kbdchar,&frommandel,kbdmore,stacked); else mms_value = main_menu_switch(&kbdchar,&frommandel,kbdmore,stacked,axmode); if (quick_calc && (mms_value == IMAGESTART || mms_value == RESTORESTART || mms_value == RESTART)) { quick_calc = 0; usr_stdcalcmode = old_stdcalcmode; } if (quick_calc && calc_status != 4) usr_stdcalcmode = '1'; switch(mms_value) { case IMAGESTART: return(IMAGESTART); case RESTORESTART: return(RESTORESTART); case RESTART: return(RESTART); case CONTINUE: continue; default: break; } if (zoomoff == 1 && *kbdmore == 1) /* draw/clear a zoom box? */ drawbox(1); #ifdef XFRACT if (resizeWindow()) { calc_status = -1; } #endif } } /* return(0); */ } int main_menu_switch(int *kbdchar, int *frommandel, int *kbdmore, char *stacked, int axmode) { int i,k; static double jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */ static double jxx3rd, jyy3rd; long old_maxit; /* char drive[FILE_MAX_DRIVE]; char dir[FILE_MAX_DIR]; char fname[FILE_MAX_FNAME]; char ext[FILE_MAX_EXT]; */ if (quick_calc && calc_status == 4) { quick_calc = 0; usr_stdcalcmode = old_stdcalcmode; } if (quick_calc && calc_status != 4) usr_stdcalcmode = old_stdcalcmode; switch (*kbdchar) { case 't': /* new fractal type */ julibrot = 0; clear_zoombox(); stackscreen(); if ((i = get_fracttype()) >= 0) { discardscreen(); savedac = 0; save_release = release; no_mag_calc = 0; use_old_period = 0; bad_outside = 0; ldcheck = 0; set_current_params(); odpx=odpy=newodpx=newodpy=0; fiddlefactor = 1; /* reset param evolution stuff */ set_orbit_corners = 0; param_history(0); /* save history */ if (i == 0) { initmode = adapter; *frommandel = 0; } else if (initmode < 0) /* it is supposed to be... */ setvideotext(); /* reset to text mode */ return(IMAGESTART); } unstackscreen(); break; case 24: /* Ctl-X, Ctl-Y, CTL-Z do flipping */ case 25: case 26: flip_image(*kbdchar); break; case 'x': /* invoke options screen */ case 'y': case 'p': /* passes options */ case 'z': /* type specific parms */ case 'g': case 'v': case 2: case 5: case 6: old_maxit = maxit; clear_zoombox(); if (fromtext_flag == 1) fromtext_flag = 0; else stackscreen(); if (*kbdchar == 'x') i = get_toggles(); else if (*kbdchar == 'y') i = get_toggles2(); else if (*kbdchar == 'p') i = passes_options(); else if (*kbdchar == 'z') i = get_fract_params(1); else if (*kbdchar == 'v') i = get_view_params(); /* get the parameters */ else if (*kbdchar == 2) i = get_browse_params(); else if (*kbdchar == 5) { i = get_evolve_Parms(); if (i > 0) { start_showorbit = 0; soundflag &= 0xF9; /* turn off only x,y,z */ Log_Auto_Calc = 0; /* turn it off */ } } else if (*kbdchar == 6) i = get_sound_params(); else i = get_cmd_string(); unstackscreen(); if (evolving && truecolor) truecolor = 0; /* truecolor doesn't play well with the evolver */ if (maxit > old_maxit && inside >= 0 && calc_status == 4 && curfractalspecific->calctype == StandardFractal && !LogFlag && !truecolor && /* recalc not yet implemented with truecolor */ !(usr_stdcalcmode == 't' && fillcolor > -1) && /* tesseral with fill doesn't work */ !(usr_stdcalcmode == 'o') && i == 1 && /* nothing else changed */ outside != ATAN ) { quick_calc = 1; old_stdcalcmode = usr_stdcalcmode; usr_stdcalcmode = '1'; *kbdmore = 0; calc_status = 2; i = 0; } else if (i > 0) { /* time to redraw? */ quick_calc = 0; param_history(0); /* save history */ *kbdmore = calc_status = 0; } break; #ifndef XFRACT case '@': /* execute commands */ case '2': /* execute commands */ #else case F2: /* execute commands */ #endif stackscreen(); i = get_commands(); if (initmode != -1) { /* video= was specified */ adapter = initmode; initmode = -1; i |= 1; savedac = 0; } else if (colorpreloaded) { /* colors= was specified */ spindac(0, 1); colorpreloaded = 0; } else if ((i & 8)) /* reset was specified */ savedac = 0; if ((i & 4)) { /* 3d = was specified */ *kbdchar = '3'; unstackscreen(); goto do_3d_transform; /* pretend '3' was keyed */ } if ((i & 1)) { /* fractal parameter changed */ discardscreen(); /* backwards_v18();*/ /* moved this to cmdfiles.c */ /* backwards_v19();*/ *kbdmore = calc_status = 0; } else unstackscreen(); break; case 'f': /* floating pt toggle */ if (usr_floatflag == 0) usr_floatflag = 1; else if (stdcalcmode != 'o') /* don't go there */ usr_floatflag = 0; initmode = adapter; return(IMAGESTART); case 'i': /* 3d fractal parms */ if (get_fract3d_params() >= 0) /* get the parameters */ calc_status = *kbdmore = 0; /* time to redraw */ break; #if 0 case 'w': /*chk_keys();*/ /*julman();*/ break; #endif case 1: /* ^a Ant */ clear_zoombox(); { int oldtype, err, i; double oldparm[MAXPARAMS]; oldtype = fractype; for(i=0;i= 0) { unstackscreen(); if (ant() >= 0) calc_status = 0; } else unstackscreen(); fractype = oldtype; for(i=0;i= 0) return(CONTINUE); } break; case 'k': /* ^s is irritating, give user a single key */ case 19: /* ^s RDS */ clear_zoombox(); if (get_rds_params() >= 0) { if (do_AutoStereo() >= 0) calc_status = 0; return(CONTINUE); } break; case 'a': /* starfield parms */ clear_zoombox(); if (get_starfield_params() >= 0) { if (starfield() >= 0) calc_status = 0; return(CONTINUE); } break; case 15: /* ctrl-o */ case 'o': /* must use standard fractal and have a float variant */ if ((fractalspecific[fractype].calctype == StandardFractal || fractalspecific[fractype].calctype == calcfroth) && (fractalspecific[fractype].isinteger == 0 || fractalspecific[fractype].tofloat != NOFRACTAL) && !bf_math && /* for now no arbitrary precision support */ !(istruecolor && truemode) ) { clear_zoombox(); Jiim(ORBIT); } break; case SPACE: /* spacebar, toggle mand/julia */ if(bf_math || evolving) break; if (fractype == CELLULAR) { if (nxtscreenflag) nxtscreenflag = 0; /* toggle flag to stop generation */ else nxtscreenflag = 1; /* toggle flag to generate next screen */ calc_status = 2; *kbdmore = 0; } else { if(fractype == FORMULA || fractype == FFORMULA) { if(ismand) { fractalspecific[fractype].tojulia = fractype; fractalspecific[fractype].tomandel = NOFRACTAL; ismand = 0; } else { fractalspecific[fractype].tojulia = NOFRACTAL; fractalspecific[fractype].tomandel = fractype; ismand = 1; } } if (curfractalspecific->tojulia != NOFRACTAL && param[0] == 0.0 && param[1] == 0.0) { /* switch to corresponding Julia set */ int key; if ((fractype == MANDEL || fractype == MANDELFP) && bf_math == 0) hasinverse = 1; else hasinverse = 0; clear_zoombox(); Jiim(JIIM); key = getakey(); /* flush keyboard buffer */ if (key != SPACE) { ungetakey(key); break; } fractype = curfractalspecific->tojulia; curfractalspecific = &fractalspecific[fractype]; if (xcjul == BIG || ycjul == BIG) { param[0] = (xxmax + xxmin) / 2; param[1] = (yymax + yymin) / 2; } else { param[0] = xcjul; param[1] = ycjul; xcjul = ycjul = BIG; } jxxmin = sxmin; jxxmax = sxmax; jyymax = symax; jyymin = symin; jxx3rd = sx3rd; jyy3rd = sy3rd; *frommandel = 1; xxmin = curfractalspecific->xmin; xxmax = curfractalspecific->xmax; yymin = curfractalspecific->ymin; yymax = curfractalspecific->ymax; xx3rd = xxmin; yy3rd = yymin; if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29) { xxmin *= 3.0; xxmax *= 3.0; yymin *= 3.0; yymax *= 3.0; xx3rd *= 3.0; yy3rd *= 3.0; } zoomoff = 1; calc_status = 0; *kbdmore = 0; } else if (curfractalspecific->tomandel != NOFRACTAL) { /* switch to corresponding Mandel set */ fractype = curfractalspecific->tomandel; curfractalspecific = &fractalspecific[fractype]; if (*frommandel) { xxmin = jxxmin; xxmax = jxxmax; yymin = jyymin; yymax = jyymax; xx3rd = jxx3rd; yy3rd = jyy3rd; } else { xxmin = xx3rd = curfractalspecific->xmin; xxmax = curfractalspecific->xmax; yymin = yy3rd = curfractalspecific->ymin; yymax = curfractalspecific->ymax; } SaveC.x = param[0]; SaveC.y = param[1]; param[0] = 0; param[1] = 0; zoomoff = 1; calc_status = 0; *kbdmore = 0; } else buzzer(2); /* can't switch */ } /* end of else for if == cellular */ break; case 'j': /* inverse julia toggle */ /* if the inverse types proliferate, something more elegant will be * needed */ if (fractype == JULIA || fractype == JULIAFP || fractype == INVERSEJULIA) { static int oldtype = -1; if (fractype == JULIA || fractype == JULIAFP) { oldtype = fractype; fractype = INVERSEJULIA; } else if (fractype == INVERSEJULIA) { if (oldtype != -1) fractype = oldtype; else fractype = JULIA; } curfractalspecific = &fractalspecific[fractype]; zoomoff = 1; calc_status = 0; *kbdmore = 0; } #if 0 else if (fractype == MANDEL || fractype == MANDELFP) { clear_zoombox(); Jiim(JIIM); } #endif else buzzer(2); break; case '\\': /* return to prev image */ case CTL_BACKSLASH: case 'h': case 8: if (name_stack_ptr >= 1) { /* go back one file if somewhere to go (ie. browsing) */ name_stack_ptr--; while (file_name_stack[name_stack_ptr][0] == '\0' && name_stack_ptr >= 0) name_stack_ptr--; if (name_stack_ptr < 0) /* oops, must have deleted first one */ break; strcpy(browsename, file_name_stack[name_stack_ptr]); /* splitpath(browsename, NULL, NULL, fname, ext); splitpath(readname, drive, dir, NULL, NULL); makepath(readname, drive, dir, fname, ext); */ merge_pathnames(readname,browsename,2); browsing = TRUE; no_sub_images = FALSE; showfile = 0; if (askvideo) { stackscreen(); /* save graphics image */ *stacked = 1; } return(RESTORESTART); } else if(maxhistory > 0 && bf_math == 0) { if(*kbdchar == '\\' || *kbdchar == 'h') if (--historyptr < 0) historyptr = maxhistory - 1; if(*kbdchar == CTL_BACKSLASH || *kbdchar == 8) if (++historyptr >= maxhistory) historyptr = 0; restore_history_info(historyptr); zoomoff = 1; initmode = adapter; if (curfractalspecific->isinteger != 0 && curfractalspecific->tofloat != NOFRACTAL) usr_floatflag = 0; if (curfractalspecific->isinteger == 0 && curfractalspecific->tofloat != NOFRACTAL) usr_floatflag = 1; historyflag = 1; /* avoid re-store parms due to rounding errs */ return(IMAGESTART); } break; case 'd': /* shell to MS-DOS (redraw image in Xfractint) */ #ifndef XFRACT stackscreen(); if (75000L > fr_farfree()) { static FCODE dosmsg[] = {"Not enough memory to Shell-to-DOS"}; unstackscreen(); stopmsg(0, dosmsg); break; } if (axmode == 0 || axmode > 7) { static FCODE dosmsg[] = {"\ Note: Your graphics image is still squirreled away in your video\n\ adapter's memory. Switching video modes will clobber part of that\n\ image. Sorry - it's the best we could do."}; putstring(0, 0, 7, dosmsg); movecursor(6, 0); } shell_to_dos(); unstackscreen(); #else initmode = adapter; return(IMAGESTART); #endif /* calc_status = 0; */ break; case 'c': /* switch to color cycling */ case '+': /* rotate palette */ case '-': /* rotate palette */ clear_zoombox(); memcpy(olddacbox, dacbox, 256 * 3); rotate((*kbdchar == 'c') ? 0 : ((*kbdchar == '+') ? 1 : -1)); if (memcmp(olddacbox, dacbox, 256 * 3)) { /* colorstate = 1; Move to rotate.c to more precisely define when */ /* colorstate is changed. JCO 11/18/2007 */ save_history_info(); } return(CONTINUE); case 'e': /* switch to color editing */ if (istruecolor && !initbatch) { /* don't enter palette editor */ if (load_palette() >= 0) { *kbdmore = calc_status = 0; break; } else return(CONTINUE); } clear_zoombox(); if (dacbox[0][0] != 255 && !reallyega && colors >= 16 && dotmode != 11) { int oldhelpmode; oldhelpmode = helpmode; memcpy(olddacbox, dacbox, 256 * 3); helpmode = HELPXHAIR; EditPalette(); helpmode = oldhelpmode; if (memcmp(olddacbox, dacbox, 256 * 3)) { /* colorstate = 1; Move to editpal.c to more precisely define when */ /* colorstate is changed. JCO 11/18/2007 */ save_history_info(); } } return(CONTINUE); case 's': /* save-to-disk */ if (dotmode == 11 && disktarga == 1) return(CONTINUE); /* disk video and targa, nothing to save */ diskisactive = 1; /* flag for disk-video routines */ note_zoom(); savetodisk(savename); restore_zoom(); diskisactive = 0; /* flag for disk-video routines */ return(CONTINUE); case '#': /* 3D overlay */ #ifdef XFRACT case F3: /* 3D overlay */ #endif clear_zoombox(); overlay3d = 1; case '3': /* restore-from (3d) */ do_3d_transform: if (overlay3d) display3d = 2; /* for command */ else display3d = 1; case 'r': /* restore-from */ comparegif = 0; *frommandel = 0; if (browsing) { browsing = FALSE; } if (*kbdchar == 'r') { if (debugflag == 50) { comparegif = overlay3d = 1; if (initbatch == 2) { stackscreen(); /* save graphics image */ strcpy(readname, savename); showfile = 0; return(RESTORESTART); } } else comparegif = overlay3d = 0; display3d = 0; } stackscreen(); /* save graphics image */ if (overlay3d) *stacked = 0; else *stacked = 1; if (resave_flag) { updatesavename(savename); /* do the pending increment */ resave_flag = started_resaves = 0; } showfile = -1; return(RESTORESTART); case 'l': case 'L': /* Look for other files within this view */ if ((zwidth == 0) && (!diskvideo)) /* not zooming & no disk video */ { int oldhelpmode; oldhelpmode = helpmode; helpmode = HELPBROWSE; switch (fgetwindow()) { case ENTER: case ENTER_2: showfile = 0; /* trigger load */ browsing = TRUE; /* but don't ask for the file name as it's * just been selected */ if (name_stack_ptr == 15) { /* about to run off the end of the file * history stack so shift it all back one to * make room, lose the 1st one */ int tmp; for (tmp = 1; tmp < 16; tmp++) strcpy(file_name_stack[tmp - 1], file_name_stack[tmp]); name_stack_ptr = 14; } name_stack_ptr++; strcpy(file_name_stack[name_stack_ptr], browsename); /* splitpath(browsename, NULL, NULL, fname, ext); splitpath(readname, drive, dir, NULL, NULL); makepath(readname, drive, dir, fname, ext); */ merge_pathnames(readname,browsename,2); if (askvideo) { stackscreen(); /* save graphics image */ *stacked = 1; } return(RESTORESTART); /* hop off and do it!! */ case '\\': if (name_stack_ptr >= 1) { /* go back one file if somewhere to go (ie. browsing) */ name_stack_ptr--; while (file_name_stack[name_stack_ptr][0] == '\0' && name_stack_ptr >= 0) name_stack_ptr--; if (name_stack_ptr < 0) /* oops, must have deleted first one */ break; strcpy(browsename, file_name_stack[name_stack_ptr]); /* splitpath(browsename, NULL, NULL, fname, ext); splitpath(readname, drive, dir, NULL, NULL); makepath(readname, drive, dir, fname, ext); */ merge_pathnames(readname,browsename,2); browsing = TRUE; showfile = 0; if (askvideo) { stackscreen();/* save graphics image */ *stacked = 1; } return(RESTORESTART); } /* otherwise fall through and turn off * browsing */ case ESC: case 'l': /* turn it off */ case 'L': browsing = FALSE; helpmode = oldhelpmode; break; case 's': browsing = FALSE; helpmode = oldhelpmode; savetodisk(savename); break; default: /* or no files found, leave the state of * browsing */ break; /* alone */ } } else { browsing = FALSE; buzzer(2); /* can't browse if zooming or diskvideo */ } break; case 'b': /* make batch file */ make_batch_file(); break; case 'u': stackscreen();/* save graphics image */ intro(); unstackscreen(); break; case 16: /* print current image */ note_zoom(); Print_Screen(); restore_zoom(); if (!keypressed()) buzzer(0); else { buzzer(1); getakey(); } return(CONTINUE); case ENTER: /* Enter */ case ENTER_2: /* Numeric-Keypad Enter */ #ifdef XFRACT XZoomWaiting = 0; #endif if (zwidth != 0.0) { /* do a zoom */ init_pan_or_recalc(0); *kbdmore = 0; } if (calc_status != 4) /* don't restart if image complete */ *kbdmore = 0; break; case CTL_ENTER: /* control-Enter */ case CTL_ENTER_2: /* Control-Keypad Enter */ init_pan_or_recalc(1); *kbdmore = 0; zoomout(); /* calc corners for zooming out */ break; case INSERT: /* insert */ setvideotext(); /* force text mode */ return(RESTART); case LEFT_ARROW: /* cursor left */ case RIGHT_ARROW: /* cursor right */ case UP_ARROW: /* cursor up */ case DOWN_ARROW: /* cursor down */ move_zoombox(*kbdchar); break; case LEFT_ARROW_2: /* Ctrl-cursor left */ case RIGHT_ARROW_2: /* Ctrl-cursor right */ case UP_ARROW_2: /* Ctrl-cursor up */ case DOWN_ARROW_2: /* Ctrl-cursor down */ move_zoombox(*kbdchar); break; case CTL_HOME: /* Ctrl-home */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) { i = key_count(CTL_HOME); if ((zskew -= 0.02 * i) < -0.48) zskew = -0.48; } break; case CTL_END: /* Ctrl-end */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) { i = key_count(CTL_END); if ((zskew += 0.02 * i) > 0.48) zskew = 0.48; } break; case CTL_PAGE_UP: /* Ctrl-pgup */ if (boxcount) chgboxi(0, -2 * key_count(CTL_PAGE_UP)); break; case CTL_PAGE_DOWN: /* Ctrl-pgdn */ if (boxcount) chgboxi(0, 2 * key_count(CTL_PAGE_DOWN)); break; case PAGE_UP: /* page up */ if (zoomoff == 1) { if (zwidth == 0) { /* start zoombox */ zwidth = zdepth = 1; zskew = zrotate = 0; zbx = zby = 0; find_special_colors(); boxcolor = color_bright; px = py = gridsz/2; moveboxf(0.0,0.0); /* force scrolling */ } else resizebox(0 - key_count(PAGE_UP)); } break; case PAGE_DOWN: /* page down */ if (boxcount) { if (zwidth >= .999 && zdepth >= 0.999) /* end zoombox */ zwidth = 0; else resizebox(key_count(PAGE_DOWN)); } break; case CTL_MINUS: /* Ctrl-kpad- */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) zrotate += key_count(CTL_MINUS); break; case CTL_PLUS: /* Ctrl-kpad+ */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) zrotate -= key_count(CTL_PLUS); break; case CTL_INSERT: /* Ctrl-ins */ boxcolor += key_count(CTL_INSERT); break; case CTL_DEL: /* Ctrl-del */ boxcolor -= key_count(CTL_DEL); break; case 1120: /* alt + number keys set mutation level and start evolution engine */ case 1121: case 1122: case 1123: case 1124: case 1125: case 1126: /* case 1127: case 1128: */ viewwindow = evolving = 1; set_mutation_level(*kbdchar-1119); param_history(0); /* save parameter history */ *kbdmore = calc_status = 0; break; case DELETE: /* select video mode from list */ { stackscreen(); *kbdchar = select_video_mode(adapter); if (check_vidmode_key(0, *kbdchar) >= 0) /* picked a new mode? */ discardscreen(); else unstackscreen(); /* fall through */ } default: /* other (maybe a valid Fn key) */ if ((k = check_vidmode_key(0, *kbdchar)) >= 0) { adapter = k; /* if (videotable[adapter].dotmode != 11 Took out so that */ /* || videotable[adapter].colors != colors) DAC is not reset */ /* savedac = 0; when changing video modes */ if (videotable[adapter].colors != colors) savedac = 0; calc_status = 0; *kbdmore = 0; return(CONTINUE); } break; } /* end of the big switch */ return(0); } int evolver_menu_switch(int *kbdchar, int *frommandel, int *kbdmore, char *stacked) { int i,k; switch (*kbdchar) { case 't': /* new fractal type */ julibrot = 0; clear_zoombox(); stackscreen(); if ((i = get_fracttype()) >= 0) { discardscreen(); savedac = 0; save_release = release; no_mag_calc = 0; use_old_period = 0; bad_outside = 0; ldcheck = 0; set_current_params(); odpx=odpy=newodpx=newodpy=0; fiddlefactor = 1; /* reset param evolution stuff */ set_orbit_corners = 0; param_history(0); /* save history */ if (i == 0) { initmode = adapter; *frommandel = 0; } else if (initmode < 0) /* it is supposed to be... */ setvideotext(); /* reset to text mode */ return(IMAGESTART); } unstackscreen(); break; case 'x': /* invoke options screen */ case 'y': case 'p': /* passes options */ case 'z': /* type specific parms */ case 'g': case 5: case SPACE: clear_zoombox(); if (fromtext_flag == 1) fromtext_flag = 0; else stackscreen(); if (*kbdchar == 'x') i = get_toggles(); else if (*kbdchar == 'y') i = get_toggles2(); else if (*kbdchar == 'p') i = passes_options(); else if (*kbdchar == 'z') i = get_fract_params(1); else if (*kbdchar == 5 || *kbdchar == SPACE) i = get_evolve_Parms(); else i = get_cmd_string(); unstackscreen(); if (evolving && truecolor) truecolor = 0; /* truecolor doesn't play well with the evolver */ if (i > 0) { /* time to redraw? */ param_history(0); /* save history */ *kbdmore = calc_status = 0; } break; case 'b': /* quick exit from evolve mode */ evolving = viewwindow = 0; param_history(0); /* save history */ *kbdmore = calc_status = 0; break; case 'f': /* floating pt toggle */ if (usr_floatflag == 0) usr_floatflag = 1; else if (stdcalcmode != 'o') /* don't go there */ usr_floatflag = 0; initmode = adapter; return(IMAGESTART); case '\\': /* return to prev image */ case CTL_BACKSLASH: case 'h': case 8: if(maxhistory > 0 && bf_math == 0) { if(*kbdchar == '\\' || *kbdchar == 'h') if (--historyptr < 0) historyptr = maxhistory - 1; if(*kbdchar == CTL_BACKSLASH || *kbdchar == 8) if (++historyptr >= maxhistory) historyptr = 0; restore_history_info(historyptr); zoomoff = 1; initmode = adapter; if (curfractalspecific->isinteger != 0 && curfractalspecific->tofloat != NOFRACTAL) usr_floatflag = 0; if (curfractalspecific->isinteger == 0 && curfractalspecific->tofloat != NOFRACTAL) usr_floatflag = 1; historyflag = 1; /* avoid re-store parms due to rounding errs */ return(IMAGESTART); } break; case 'c': /* switch to color cycling */ case '+': /* rotate palette */ case '-': /* rotate palette */ clear_zoombox(); memcpy(olddacbox, dacbox, 256 * 3); rotate((*kbdchar == 'c') ? 0 : ((*kbdchar == '+') ? 1 : -1)); if (memcmp(olddacbox, dacbox, 256 * 3)) { colorstate = 1; save_history_info(); } return(CONTINUE); case 'e': /* switch to color editing */ if (istruecolor && !initbatch) { /* don't enter palette editor */ if (load_palette() >= 0) { *kbdmore = calc_status = 0; break; } else return(CONTINUE); } clear_zoombox(); if (dacbox[0][0] != 255 && !reallyega && colors >= 16 && dotmode != 11) { int oldhelpmode; oldhelpmode = helpmode; memcpy(olddacbox, dacbox, 256 * 3); helpmode = HELPXHAIR; EditPalette(); helpmode = oldhelpmode; if (memcmp(olddacbox, dacbox, 256 * 3)) { colorstate = 1; save_history_info(); } } return(CONTINUE); case 's': /* save-to-disk */ { int oldsxoffs, oldsyoffs, oldxdots, oldydots, oldpx, oldpy; GENEBASE gene[NUMGENES]; if (dotmode == 11 && disktarga == 1) return(CONTINUE); /* disk video and targa, nothing to save */ /* get the gene array from far memory */ MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); oldsxoffs = sxoffs; oldsyoffs = syoffs; oldxdots = xdots; oldydots = ydots; oldpx = px; oldpy = py; sxoffs = syoffs = 0; xdots = sxdots; ydots = sydots; /* for full screen save and pointer move stuff */ px = py = gridsz / 2; diskisactive = 1; /* flag for disk-video routines */ param_history(1); /* restore old history */ fiddleparms(gene, 0); drawparmbox(1); savetodisk(savename); px = oldpx; py = oldpy; param_history(1); /* restore old history */ fiddleparms(gene, unspiralmap()); diskisactive = 0; /* flag for disk-video routines */ sxoffs = oldsxoffs; syoffs = oldsyoffs; xdots = oldxdots; ydots = oldydots; MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); } return(CONTINUE); case 'r': /* restore-from */ comparegif = 0; *frommandel = 0; if (browsing) { browsing = FALSE; } if (*kbdchar == 'r') { if (debugflag == 50) { comparegif = overlay3d = 1; if (initbatch == 2) { stackscreen(); /* save graphics image */ strcpy(readname, savename); showfile = 0; return(RESTORESTART); } } else comparegif = overlay3d = 0; display3d = 0; } stackscreen(); /* save graphics image */ if (overlay3d) *stacked = 0; else *stacked = 1; if (resave_flag) { updatesavename(savename); /* do the pending increment */ resave_flag = started_resaves = 0; } showfile = -1; return(RESTORESTART); case 'u': stackscreen();/* save graphics image */ intro(); unstackscreen(); break; case ENTER: /* Enter */ case ENTER_2: /* Numeric-Keypad Enter */ #ifdef XFRACT XZoomWaiting = 0; #endif if (zwidth != 0.0) { /* do a zoom */ init_pan_or_recalc(0); *kbdmore = 0; } if (calc_status != 4) /* don't restart if image complete */ *kbdmore = 0; break; case CTL_ENTER: /* control-Enter */ case CTL_ENTER_2: /* Control-Keypad Enter */ init_pan_or_recalc(1); *kbdmore = 0; zoomout(); /* calc corners for zooming out */ break; case INSERT: /* insert */ setvideotext(); /* force text mode */ return(RESTART); case LEFT_ARROW: /* cursor left */ case RIGHT_ARROW: /* cursor right */ case UP_ARROW: /* cursor up */ case DOWN_ARROW: /* cursor down */ move_zoombox(*kbdchar); break; case LEFT_ARROW_2: /* Ctrl-cursor left */ case RIGHT_ARROW_2: /* Ctrl-cursor right */ case UP_ARROW_2: /* Ctrl-cursor up */ case DOWN_ARROW_2: /* Ctrl-cursor down */ /* borrow ctrl cursor keys for moving selection box */ /* in evolver mode */ if (boxcount) { int grout; GENEBASE gene[NUMGENES]; /* get the gene array from far memory */ MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); if (evolving&1) { if (*kbdchar == LEFT_ARROW_2) { px--; } if (*kbdchar == RIGHT_ARROW_2) { px++; } if (*kbdchar == UP_ARROW_2) { py--; } if (*kbdchar == DOWN_ARROW_2) { py++; } if (px <0 ) px = gridsz-1; if (px >(gridsz-1)) px = 0; if (py <0) py = gridsz-1; if (py > (gridsz-1)) py = 0; grout = !((evolving & NOGROUT)/NOGROUT) ; sxoffs = px * (int)(dxsize+1+grout); syoffs = py * (int)(dysize+1+grout); param_history(1); /* restore old history */ fiddleparms(gene, unspiralmap()); /* change all parameters */ /* to values appropriate to the image selected */ set_evolve_ranges(); chgboxi(0,0); drawparmbox(0); } /* now put the gene array back in far memory */ MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); } else /* if no zoombox, scroll by arrows */ move_zoombox(*kbdchar); break; case CTL_HOME: /* Ctrl-home */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) { i = key_count(CTL_HOME); if ((zskew -= 0.02 * i) < -0.48) zskew = -0.48; } break; case CTL_END: /* Ctrl-end */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) { i = key_count(CTL_END); if ((zskew += 0.02 * i) > 0.48) zskew = 0.48; } break; case CTL_PAGE_UP: if(prmboxcount) { parmzoom -= 1.0; if(parmzoom<1.0) parmzoom=1.0; drawparmbox(0); set_evolve_ranges(); } break; case CTL_PAGE_DOWN: if(prmboxcount) { parmzoom += 1.0; if(parmzoom>(double)gridsz/2.0) parmzoom=(double)gridsz/2.0; drawparmbox(0); set_evolve_ranges(); } break; case PAGE_UP: /* page up */ if (zoomoff == 1) { if (zwidth == 0) { /* start zoombox */ zwidth = zdepth = 1; zskew = zrotate = 0; zbx = zby = 0; find_special_colors(); boxcolor = color_bright; /*rb*/ if (evolving&1) { /* set screen view params back (previously changed to allow full screen saves in viewwindow mode) */ int grout = !((evolving & NOGROUT) / NOGROUT); sxoffs = px * (int)(dxsize+1+grout); syoffs = py * (int)(dysize+1+grout); SetupParamBox(); drawparmbox(0); } moveboxf(0.0,0.0); /* force scrolling */ } else resizebox(0 - key_count(PAGE_UP)); } break; case PAGE_DOWN: /* page down */ if (boxcount) { if (zwidth >= .999 && zdepth >= 0.999) { /* end zoombox */ zwidth = 0; if (evolving&1) { drawparmbox(1); /* clear boxes off screen */ ReleaseParamBox(); } } else resizebox(key_count(PAGE_DOWN)); } break; case CTL_MINUS: /* Ctrl-kpad- */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) zrotate += key_count(CTL_MINUS); break; case CTL_PLUS: /* Ctrl-kpad+ */ if (boxcount && (curfractalspecific->flags & NOROTATE) == 0) zrotate -= key_count(CTL_PLUS); break; case CTL_INSERT: /* Ctrl-ins */ boxcolor += key_count(CTL_INSERT); break; case CTL_DEL: /* Ctrl-del */ boxcolor -= key_count(CTL_DEL); break; /* grabbed a couple of video mode keys, user can change to these using delete and the menu if necessary */ case F2: /* halve mutation params and regen */ fiddlefactor = fiddlefactor / 2; paramrangex = paramrangex / 2; newopx = opx + paramrangex / 2; paramrangey = paramrangey / 2; newopy = opy + paramrangey / 2; *kbdmore = calc_status = 0; break; case F3: /*double mutation parameters and regenerate */ { double centerx, centery; fiddlefactor = fiddlefactor * 2; centerx = opx + paramrangex / 2; paramrangex = paramrangex * 2; newopx = centerx - paramrangex / 2; centery = opy + paramrangey / 2; paramrangey = paramrangey * 2; newopy = centery - paramrangey / 2; *kbdmore = calc_status = 0; break; } case F4: /*decrement gridsize and regen */ if (gridsz > 3) { gridsz = gridsz - 2; /* gridsz must have odd value only */ *kbdmore = calc_status = 0; } break; case F5: /* increment gridsize and regen */ if (gridsz < (sxdots / (MINPIXELS<<1))) { gridsz = gridsz + 2; *kbdmore = calc_status = 0; } break; case F6: /* toggle all variables selected for random variation to center weighted variation and vice versa */ { int i; GENEBASE gene[NUMGENES]; /* get the gene array from far memory */ MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); for (i =0;i < NUMGENES; i++) { if (gene[i].mutate == 5) { gene[i].mutate = 6; continue; } if (gene[i].mutate == 6) gene[i].mutate = 5; } /* now put the gene array back in far memory */ MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); } *kbdmore = calc_status = 0; break; case 1120: /* alt + number keys set mutation level */ case 1121: case 1122: case 1123: case 1124: case 1125: case 1126: /* case 1127: case 1128: */ set_mutation_level(*kbdchar-1119); param_history(1); /* restore old history */ *kbdmore = calc_status = 0; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': /* add these in when more parameters can be varied case '8': case '9': */ set_mutation_level(*kbdchar-(int)'0'); param_history(1); /* restore old history */ *kbdmore = calc_status = 0; break; case '0': /* mutation level 0 == turn off evolving */ evolving = viewwindow = 0; *kbdmore = calc_status = 0; break; case DELETE: /* select video mode from list */ stackscreen(); *kbdchar = select_video_mode(adapter); if (check_vidmode_key(0, *kbdchar) >= 0) /* picked a new mode? */ discardscreen(); else unstackscreen(); /* fall through */ default: /* other (maybe valid Fn key */ if ((k = check_vidmode_key(0, *kbdchar)) >= 0) { adapter = k; if (videotable[adapter].colors != colors) savedac = 0; calc_status = 0; *kbdmore = 0; return(CONTINUE); } break; } /* end of the big evolver switch */ return(0); } static int call_line3d(BYTE *pixels, int linelen) { /* this routine exists because line3d might be in an overlay */ return(line3d(pixels,linelen)); } static void note_zoom() { if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */ if ((savezoom = (char far *)farmemalloc((long)(5*boxcount))) == NULL) clear_zoombox(); /* not enuf mem so clear the box */ else { reset_zoom_corners(); /* reset these to overall image, not box */ far_memcpy(savezoom,boxx,boxcount*2); far_memcpy(savezoom+boxcount*2,boxy,boxcount*2); far_memcpy(savezoom+boxcount*4,boxvalues,boxcount); } } } static void restore_zoom() { if (boxcount) { /* restore zoombox arrays */ far_memcpy(boxx,savezoom,boxcount*2); far_memcpy(boxy,savezoom+boxcount*2,boxcount*2); far_memcpy(boxvalues,savezoom+boxcount*4,boxcount); farmemfree(savezoom); drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */ } } /* do all pending movement at once for smooth mouse diagonal moves */ static void move_zoombox(int keynum) { int vertical, horizontal, getmore; vertical = horizontal = 0; getmore = 1; while (getmore) { switch (keynum) { case LEFT_ARROW: /* cursor left */ --horizontal; break; case RIGHT_ARROW: /* cursor right */ ++horizontal; break; case UP_ARROW: /* cursor up */ --vertical; break; case DOWN_ARROW: /* cursor down */ ++vertical; break; case LEFT_ARROW_2: /* Ctrl-cursor left */ horizontal -= 8; break; case RIGHT_ARROW_2: /* Ctrl-cursor right */ horizontal += 8; break; case UP_ARROW_2: /* Ctrl-cursor up */ vertical -= 8; break; case DOWN_ARROW_2: /* Ctrl-cursor down */ vertical += 8; break; /* += 8 needed by VESA scrolling */ default: getmore = 0; } if (getmore) { if (getmore == 2) /* eat last key used */ getakey(); getmore = 2; keynum = keypressed(); /* next pending key */ } } if (boxcount) { /* if (horizontal != 0) moveboxf((double)horizontal/dxsize,0.0); if (vertical != 0) moveboxf(0.0,(double)vertical/dysize); */ moveboxf((double)horizontal/dxsize,(double)vertical/dysize); } #ifndef XFRACT else /* if no zoombox, scroll by arrows */ scroll_relative(horizontal,vertical); #endif } /* displays differences between current image file and new image */ static FILE *cmp_fp; static int errcount; int cmp_line(BYTE *pixels, int linelen) { int row,col; int oldcolor; if((row = rowcount++) == 0) { errcount = 0; cmp_fp = dir_fopen(workdir,"cmperr",(initbatch)?"a":"w"); outln_cleanup = cmp_line_cleanup; } if(pot16bit) { /* 16 bit info, ignore odd numbered rows */ if((row & 1) != 0) return(0); row >>= 1; } for(col=0;col 0) /* decrease history if necessary */ { history = MemoryAlloc((U16)sizeof(HISTORY),(long)maxhistory,EXPANDED); if(history) break; maxhistory--; } } if(extraseg == 0 || tmp == NULL) { buzzer(2); #ifndef XFRACT printf("%Fs",(char far *)msg); #else printf("%s",msg); #endif exit(1); } farmemfree(tmp); /* was just to check for min space */ if(secondpass && (maxhistory < oldmaxhistory || (history == 0 && oldmaxhistory != 0))) { #ifndef XFRACT printf("%Fs%d\n%Fs\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue); #else printf("%s%d\n%s\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue); #endif getakey(); } } xfractint-20.4.10.orig/common/biginit.c0000644000000000000000000005204111064603461014571 0ustar /* biginit.c - C routines for bignumbers */ /* Note: This is NOT the biginit.c file that come the standard BigNum library, but is a customized version specific to Fractint. The biggest difference is in the allocations of memory for the big numbers. */ #include #include /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /* appears to me that avoiding the start of extraseg is unnecessary. If correct, later we can eliminate ENDVID here. */ #ifdef ENDVID #undef ENDVID #endif #define ENDVID 0 /* globals */ #ifdef BIG_BASED _segment bignum_seg; #endif int bnstep, bnlength, intlength, rlength, padding, shiftfactor, decimals; int bflength, rbflength, bfdecimals; /* used internally by bignum.c routines */ static bn_t bnroot=BIG_NULL; static bn_t stack_ptr; /* memory allocator base after global variables */ bn_t bntmp1, bntmp2, bntmp3, bntmp4, bntmp5, bntmp6; /* rlength */ bn_t bntmpcpy1, bntmpcpy2; /* bnlength */ /* used by other routines */ bn_t bnxmin, bnxmax, bnymin, bnymax, bnx3rd, bny3rd; /* bnlength */ bn_t bnxdel, bnydel, bnxdel2, bnydel2, bnclosenuff; /* bnlength */ bn_t bntmpsqrx, bntmpsqry, bntmp; /* rlength */ _BNCMPLX /* bnold, bnnew, */ bnparm, bnsaved; /* bnlength */ _BNCMPLX bnold, bnnew; /* rlength */ bn_t bn_pi; /* TAKES NO SPACE */ bf_t bftmp1, bftmp2, bftmp3, bftmp4, bftmp5, bftmp6; /* rbflength+2 */ bf_t bftmpcpy1, bftmpcpy2; /* rbflength+2 */ bf_t bfxdel, bfydel, bfxdel2, bfydel2, bfclosenuff; /* rbflength+2 */ bf_t bftmpsqrx, bftmpsqry; /* rbflength+2 */ _BFCMPLX /* bfold, bfnew, */ bfparm, bfsaved; /* bflength+2 */ _BFCMPLX bfold, bfnew; /* rbflength+2 */ bf_t bf_pi; /* TAKES NO SPACE */ bf_t big_pi; /* bflength+2 */ /* for testing only */ /* used by other routines */ bf_t bfxmin, bfxmax, bfymin, bfymax, bfx3rd, bfy3rd; /* bflength+2 */ bf_t bfsxmin, bfsxmax, bfsymin, bfsymax, bfsx3rd, bfsy3rd;/* bflength+2 */ bf_t bfparms[10]; /* (bflength+2)*10 */ bf_t bftmp; bf_t bf10tmp; /* dec+4 */ #define LOG10_256 2.4082399653118 #define LOG_256 5.5451774444795 static int save_bf_vars(void); static int restore_bf_vars(void); /*********************************************************************/ /* given bnlength, calc_lengths will calculate all the other lengths */ void calc_lengths(void) { #if 0 #ifdef USE_BIGNUM_C_CODE bnstep = 2; #else /* use 80x86 asm code */ if (cpu >= 386) bnstep = 4; else /* cpu <= 286 */ bnstep = 2; #endif #else bnstep = 4; /* use 4 in all cases */ #endif if (bnlength % bnstep != 0) bnlength = (bnlength / bnstep + 1) * bnstep; if (bnlength == bnstep) padding = bnlength; else padding = 2*bnstep; rlength = bnlength + padding; /* This shiftfactor assumes non-full multiplications will be performed.*/ /* Change to bnlength-intlength for full multiplications. */ shiftfactor = padding - intlength; bflength = bnlength+bnstep; /* one extra step for added precision */ rbflength = bflength + padding; bfdecimals = (int)((bflength-2)*LOG10_256); } /************************************************************************/ /* intended only to be called from init_bf_dec() or init_bf_length(). */ /* initialize bignumber global variables */ long maxptr = 0; long startstack = 0; long maxstack = 0; int bf_save_len = 0; /* ??? for some strange reason, msc 7.0 hangs here without this pragma. ??? */ #ifndef XFRACT #pragma optimize( "", off ) #endif static void init_bf_2(void) { int i; long ptr; save_bf_vars(); /* copy corners values for conversion */ calc_lengths(); /* allocate all the memory at once within the same segment (DOS) */ #if defined(BIG_FAR) || defined(BIG_ANSI_C) bnroot = (bf_t)MK_FP(extraseg,ENDVID); /* ENDVID is to avoid videotable */ #else /* BASED or NEAR */ bnroot = (bf_t)ENDVID; /* ENDVID is to avoid videotable */ #endif #ifdef BIG_BASED bignum_seg = (_segment)extraseg; #endif /* at present time one call would suffice, but this logic allows multiple kinds of alternate math eg long double */ if((i = find_alternate_math(fractype, BIGNUM)) > -1) bf_math = alternatemath[i].math; else if((i = find_alternate_math(fractype, BIGFLT)) > -1) bf_math = alternatemath[i].math; else bf_math = 1; /* maybe called from cmdfiles.c and fractype not set */ floatflag=1; /* Now split up the memory among the pointers */ /* internal pointers */ ptr = 0; bntmp1 = bnroot+ptr; ptr += rlength; bntmp2 = bnroot+ptr; ptr += rlength; bntmp3 = bnroot+ptr; ptr += rlength; bntmp4 = bnroot+ptr; ptr += rlength; bntmp5 = bnroot+ptr; ptr += rlength; bntmp6 = bnroot+ptr; ptr += rlength; bftmp1 = bnroot+ptr; ptr += rbflength+2; bftmp2 = bnroot+ptr; ptr += rbflength+2; bftmp3 = bnroot+ptr; ptr += rbflength+2; bftmp4 = bnroot+ptr; ptr += rbflength+2; bftmp5 = bnroot+ptr; ptr += rbflength+2; bftmp6 = bnroot+ptr; ptr += rbflength+2; bftmpcpy1 = bnroot+ptr; ptr += (rbflength+2)*2; bftmpcpy2 = bnroot+ptr; ptr += (rbflength+2)*2; bntmpcpy1 = bnroot+ptr; ptr += (rlength*2); bntmpcpy2 = bnroot+ptr; ptr += (rlength*2); if (bf_math == BIGNUM) { bnxmin = bnroot+ptr; ptr += bnlength; bnxmax = bnroot+ptr; ptr += bnlength; bnymin = bnroot+ptr; ptr += bnlength; bnymax = bnroot+ptr; ptr += bnlength; bnx3rd = bnroot+ptr; ptr += bnlength; bny3rd = bnroot+ptr; ptr += bnlength; bnxdel = bnroot+ptr; ptr += bnlength; bnydel = bnroot+ptr; ptr += bnlength; bnxdel2 = bnroot+ptr; ptr += bnlength; bnydel2 = bnroot+ptr; ptr += bnlength; bnold.x = bnroot+ptr; ptr += rlength; bnold.y = bnroot+ptr; ptr += rlength; bnnew.x = bnroot+ptr; ptr += rlength; bnnew.y = bnroot+ptr; ptr += rlength; bnsaved.x = bnroot+ptr; ptr += bnlength; bnsaved.y = bnroot+ptr; ptr += bnlength; bnclosenuff= bnroot+ptr; ptr += bnlength; bnparm.x = bnroot+ptr; ptr += bnlength; bnparm.y = bnroot+ptr; ptr += bnlength; bntmpsqrx = bnroot+ptr; ptr += rlength; bntmpsqry = bnroot+ptr; ptr += rlength; bntmp = bnroot+ptr; ptr += rlength; } if (bf_math == BIGFLT) { bfxdel = bnroot+ptr; ptr += bflength+2; bfydel = bnroot+ptr; ptr += bflength+2; bfxdel2 = bnroot+ptr; ptr += bflength+2; bfydel2 = bnroot+ptr; ptr += bflength+2; bfold.x = bnroot+ptr; ptr += rbflength+2; bfold.y = bnroot+ptr; ptr += rbflength+2; bfnew.x = bnroot+ptr; ptr += rbflength+2; bfnew.y = bnroot+ptr; ptr += rbflength+2; bfsaved.x = bnroot+ptr; ptr += bflength+2; bfsaved.y = bnroot+ptr; ptr += bflength+2; bfclosenuff= bnroot+ptr; ptr += bflength+2; bfparm.x = bnroot+ptr; ptr += bflength+2; bfparm.y = bnroot+ptr; ptr += bflength+2; bftmpsqrx = bnroot+ptr; ptr += rbflength+2; bftmpsqry = bnroot+ptr; ptr += rbflength+2; bftmp = bnroot+ptr; ptr += rbflength+2; } big_pi = bnroot+ptr; ptr += bflength+2; /* needed by both BIGNUM & BIGFLT */ bf10tmp = bnroot+ptr; ptr += bfdecimals+4; /* ptr needs to be 16-bit aligned on some systems */ ptr = (ptr+1)&~1; stack_ptr = bnroot + ptr; startstack = ptr; /* max stack offset from bnroot */ maxstack = (long)0x10000l-(bflength+2)*22-ENDVID; /* sanity check */ /* leave room for NUMVARS variables allocated from stack */ /* also leave room for the safe area at top of segment */ if(ptr + NUMVARS*(bflength+2) > maxstack) { char msg[80]; char nmsg[80]; static FCODE fmsg[] = {"Requested precision of %d too high, aborting"}; far_strcpy(nmsg,fmsg); sprintf(msg,nmsg,decimals); stopmsg(0,msg); goodbye(); } /* room for 6 corners + 6 save corners + 10 params at top of extraseg */ /* this area is safe - use for variables that are used outside fractal*/ /* generation - e.g. zoom box variables */ ptr = maxstack; bfxmin = bnroot+ptr; ptr += bflength+2; bfxmax = bnroot+ptr; ptr += bflength+2; bfymin = bnroot+ptr; ptr += bflength+2; bfymax = bnroot+ptr; ptr += bflength+2; bfx3rd = bnroot+ptr; ptr += bflength+2; bfy3rd = bnroot+ptr; ptr += bflength+2; for(i=0;i<10;i++) { bfparms[i] = bnroot+ptr; ptr += bflength+2; } bfsxmin = bnroot+ptr; ptr += bflength+2; bfsxmax = bnroot+ptr; ptr += bflength+2; bfsymin = bnroot+ptr; ptr += bflength+2; bfsymax = bnroot+ptr; ptr += bflength+2; bfsx3rd = bnroot+ptr; ptr += bflength+2; bfsy3rd = bnroot+ptr; ptr += bflength+2; /* end safe vars */ /* good citizens initialize variables */ if(bf_save_len) /* leave save area */ far_memset(bnroot+(bf_save_len+2)*22,0,(unsigned)(startstack-(bf_save_len+2)*22)); else /* first time through - nothing saved */ { /* high variables */ far_memset(bnroot+maxstack,0,(bflength+2)*22); /* low variables */ far_memset(bnroot,0,(unsigned)startstack); } restore_bf_vars(); /* Initialize the value of pi. Needed for trig functions. */ /* init_big_pi(); */ /* call to init_big_pi() has been moved to fractal setup routine */ /* so as to use only when necessary. */ } /**********************************************************/ /* save current corners and parameters to start of bnroot */ /* to preserve values across calls to init_bf() */ static int save_bf_vars(void) { int ret; unsigned int mem; if(bnroot != BIG_NULL) { mem = (bflength+2)*22; /* 6 corners + 6 save corners + 10 params */ bf_save_len = bflength; far_memcpy(bnroot,bfxmin,mem); /* scrub old high area */ far_memset(bfxmin,0,mem); ret = 0; } else { bf_save_len = 0; ret = -1; } return(ret); } /************************************************************************/ /* copy current corners and parameters from save location */ static int restore_bf_vars(void) { bf_t ptr; int i; if(bf_save_len == 0) return(-1); ptr = bnroot; convert_bf(bfxmin,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfxmax,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfymin,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfymax,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfx3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfy3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2; for(i=0;i<10;i++) { convert_bf(bfparms[i],ptr,bflength,bf_save_len); ptr += bf_save_len+2; } convert_bf(bfsxmin,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfsxmax,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfsymin,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfsymax,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfsx3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2; convert_bf(bfsy3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2; /* scrub save area */ far_memset(bnroot,0,(bf_save_len+2)*22); return(0); } /*******************************************/ /* free corners and parameters save memory */ void free_bf_vars() { bf_save_len = bf_math = 0; bnstep=bnlength=intlength=rlength=padding=shiftfactor=decimals=0; bflength=rbflength=bfdecimals=0; } #ifndef XFRACT #pragma optimize( "", on ) #endif /************************************************************************/ /* Memory allocator routines start here. */ /************************************************************************/ /* Allocates a bn_t variable on stack */ bn_t alloc_stack(size_t size) { long stack_addr; if(bf_math == 0) { static FCODE msg[] = {"alloc_stack called with bf_math==0"}; stopmsg(0,msg); return(0); } stack_addr = (long)(stack_ptr-bnroot)+size; /* +ENDVID, part of bnroot */ if(stack_addr > maxstack) { static FCODE msg[] = {"Aborting, Out of Bignum Stack Space"}; stopmsg(0,msg); goodbye(); } /* keep track of max ptr */ if(stack_addr > maxptr) maxptr = stack_addr; stack_ptr += size; /* increment stack pointer */ return(stack_ptr - size); } /************************************************************************/ /* Returns stack pointer offset so it can be saved. */ int save_stack(void) { return(stack_ptr - bnroot); } /************************************************************************/ /* Restores stack pointer, effectively freeing local variables */ /* allocated since save_stack() */ void restore_stack(int old_offset) { stack_ptr = bnroot+old_offset; } /************************************************************************/ /* Memory allocator routines end here. */ /************************************************************************/ /************************************************************************/ /* initialize bignumber global variables */ /* dec = decimal places after decimal point */ /* intl = bytes for integer part (1, 2, or 4) */ void init_bf_dec(int dec) { if(bfdigits) decimals=bfdigits; /* blindly force */ else decimals = dec; if(bailout > 10) /* arbitrary value */ /* using 2 doesn't gain much and requires another test */ intlength = 4; else if (fractype == FPMANDELZPOWER || fractype == FPJULIAZPOWER || fractype == DIVIDEBROT5) intlength = 4; /* 2 leaves artifacts in the center of the lakes */ /* the bailout tests need greater dynamic range */ else if(bailoutest == Real || bailoutest == Imag || bailoutest == And || bailoutest == Manr) intlength = 2; else intlength = 1; /* conservative estimate */ bnlength = intlength + (int)(decimals/LOG10_256) + 1; /* round up */ init_bf_2(); } /************************************************************************/ /* initialize bignumber global variables */ /* bnl = bignumber length */ /* intl = bytes for integer part (1, 2, or 4) */ void init_bf_length(int bnl) { bnlength = bnl; if(bailout > 10) /* arbitrary value */ /* using 2 doesn't gain much and requires another test */ intlength = 4; else if (fractype == FPMANDELZPOWER || fractype == FPJULIAZPOWER || fractype == DIVIDEBROT5) intlength = 4; /* 2 leaves artifacts in the center of the lakes */ /* the bailout tests need greater dynamic range */ else if(bailoutest == Real || bailoutest == Imag || bailoutest == And || bailoutest == Manr) intlength = 2; else intlength = 1; /* conservative estimate */ decimals = (int)((bnlength-intlength)*LOG10_256); init_bf_2(); } void init_big_pi(void) { /* What, don't you recognize the first 700 digits of pi, */ /* in base 256, in reverse order? */ int length, pi_offset; static BFCODE pi_table[] = { 0x44, 0xD5, 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A, 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF, 0x00, 0x3E, 0x48, 0x7B, 0x31, 0x53, 0x60, 0x87, 0x23, 0xFD, 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E, 0x50, 0x2F, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C, 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0xCC, 0xA3, 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40, 0xC6, 0x00, 0xA1, 0xD6, 0x0A, 0x32, 0x60, 0x1A, 0xBD, 0xC0, 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2, 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, 0xB3, 0x4B, 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0xFD, 0x4A, 0x33, 0xDE, 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, 0x44, 0x45, 0x81, 0xCC, 0x2C, 0x95, 0x30, 0x9B, 0x1F, 0x51, 0xFC, 0x6D, 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, 0xB5, 0x53, 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, 0x63, 0x24, 0x6A, 0x19, 0xC2, 0x9E, 0x5C, 0x5E, 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F, 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, 0xBD, 0xE0, 0x6C, 0x97, 0x3B, 0x4C, 0x79, 0xB6, 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE, 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, 0x7B, 0x1B, 0x99, 0x80, 0xC9, 0x72, 0x53, 0x07, 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA, 0x0F, 0xDB, 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37, 0x3D, 0x02, 0x9B, 0x42, 0x72, 0xDF, 0xFE, 0x1B, 0x06, 0x77, 0x3F, 0x36, 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56, 0x9F, 0x44, 0x1A, 0x40, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75, 0x6F, 0xE0, 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D, 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E, 0x43, 0x82, 0x3E, 0x59, 0xCA, 0x66, 0x76, 0x01, 0xAF, 0x39, 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0, 0x3B, 0xBA, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E, 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x68, 0x2F, 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB, 0x61, 0x9C, 0x0C, 0x67, 0x9A, 0x6C, 0xE9, 0xF6, 0x42, 0x68, 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69, 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, 0x39, 0x42, 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0xC5, 0xAC, 0x96, 0xD3, 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, 0x02, 0x23, 0x26, 0xDC, 0xB1, 0x75, 0x85, 0xE9, 0x5D, 0x5D, 0x84, 0xEF, 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, 0x91, 0xA9, 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, 0x93, 0x21, 0x28, 0x66, 0x1B, 0xE8, 0xBF, 0xC4, 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48, 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, 0x81, 0x53, 0x32, 0x7A, 0x5C, 0xCF, 0x24, 0x6C, 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93, 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, 0xF6, 0x31, 0x18, 0x74, 0x5D, 0xC5, 0xA9, 0x2B, 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14, 0xEE, 0xB3, 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1, 0xCE, 0xE8, 0x41, 0x11, 0x34, 0x5C, 0xCC, 0xB4, 0xB6, 0x10, 0xAB, 0x2A, 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63, 0x62, 0x98, 0x48, 0x57, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25, 0x55, 0xE6, 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78, 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A, 0x1E, 0xB0, 0x8B, 0x0E, 0x9E, 0x6C, 0x0E, 0x18, 0x3A, 0x60, 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79, 0x41, 0xCA, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5, 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0xB5, 0x59, 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82, 0x58, 0xCD, 0x8B, 0x71, 0x58, 0xB6, 0x8E, 0x72, 0x8F, 0x74, 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4, 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, 0x16, 0xFC, 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0xF7, 0x6C, 0x91, 0xB3, 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, 0x45, 0x90, 0x7C, 0xBA, 0x96, 0x7E, 0x26, 0x6A, 0xED, 0xAF, 0xE1, 0xB8, 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, 0xAC, 0xB5, 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, 0x1B, 0xFB, 0x79, 0x89, 0xD9, 0xD5, 0x16, 0x92, 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5, 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, 0xB7, 0x29, 0xAC, 0xC0, 0x6C, 0x0C, 0xE9, 0x34, 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13, 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, 0x89, 0x6C, 0x4E, 0xEC, 0x98, 0xFA, 0x2E, 0x08, 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38, 0x09, 0xA4, 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13, 0xD3, 0x08, 0xA3, 0x85, 0x88, 0x6A, 0x3F, 0x24, /* . */ 0x03, 0x00, 0x00, 0x00 /* <- up to intlength 4 -> */ /* or bf_t int length of 2 + 2 byte exp */ }; length = bflength+2; /* 2 byte exp */ pi_offset = sizeof pi_table - length; _fmemcpy(big_pi, pi_table + pi_offset, length); /* notice that bf_pi and bn_pi can share the same memory space */ bf_pi = big_pi; bn_pi = big_pi + (bflength-2) - (bnlength-intlength); return; } xfractint-20.4.10.orig/common/history.c0000644000000000000000000004012110541650033014635 0ustar /* HISTORY.C History routines taken out of framain2.c to make them accessable to WinFract */ /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" /* routines in this module */ /* void _fastcall restore_history_info(int); void _fastcall save_history_info(void); */ int historyptr = -1; /* user pointer into history tbl */ static int saveptr = 0; /* save ptr into history tbl */ int historyflag; /* are we backing off in history? */ void _fastcall save_history_info() { HISTORY current,last; if(maxhistory <= 0 || bf_math || history == 0) return; MoveFromMemory((BYTE far *)&last,(U16)sizeof(HISTORY),1L,(long)saveptr,history); far_memset((void far *)¤t,0,sizeof(HISTORY)); current.fractal_type = (short)fractype ; current.xmin = xxmin ; current.xmax = xxmax ; current.ymin = yymin ; current.ymax = yymax ; current.creal = param[0] ; current.cimag = param[1] ; current.dparm3 = param[2] ; current.dparm4 = param[3] ; current.dparm5 = param[4] ; current.dparm6 = param[5] ; current.dparm7 = param[6] ; current.dparm8 = param[7] ; current.dparm9 = param[8] ; current.dparm10 = param[9] ; current.fillcolor = (short)fillcolor ; current.potential[0] = potparam[0] ; current.potential[1] = potparam[1] ; current.potential[2] = potparam[2] ; current.rflag = (short)rflag ; current.rseed = (short)rseed ; current.inside = (short)inside ; current.logmap = LogFlag ; current.invert[0] = inversion[0] ; current.invert[1] = inversion[1] ; current.invert[2] = inversion[2] ; current.decomp = (short)decomp[0]; ; current.biomorph = (short)biomorph ; current.symmetry = (short)forcesymmetry ; current.init3d[0] = (short)init3d[0] ; current.init3d[1] = (short)init3d[1] ; current.init3d[2] = (short)init3d[2] ; current.init3d[3] = (short)init3d[3] ; current.init3d[4] = (short)init3d[4] ; current.init3d[5] = (short)init3d[5] ; current.init3d[6] = (short)init3d[6] ; current.init3d[7] = (short)init3d[7] ; current.init3d[8] = (short)init3d[8] ; current.init3d[9] = (short)init3d[9] ; current.init3d[10] = (short)init3d[10] ; current.init3d[11] = (short)init3d[12] ; current.init3d[12] = (short)init3d[13] ; current.init3d[13] = (short)init3d[14] ; current.init3d[14] = (short)init3d[15] ; current.init3d[15] = (short)init3d[16] ; current.previewfactor = (short)previewfactor ; current.xtrans = (short)xtrans ; current.ytrans = (short)ytrans ; current.red_crop_left = (short)red_crop_left ; current.red_crop_right = (short)red_crop_right ; current.blue_crop_left = (short)blue_crop_left ; current.blue_crop_right = (short)blue_crop_right ; current.red_bright = (short)red_bright ; current.blue_bright = (short)blue_bright ; current.xadjust = (short)xadjust ; current.yadjust = (short)yadjust ; current.eyeseparation = (short)eyeseparation ; current.glassestype = (short)glassestype ; current.outside = (short)outside ; current.x3rd = xx3rd ; current.y3rd = yy3rd ; current.stdcalcmode = usr_stdcalcmode ; current.three_pass = three_pass ; current.stoppass = (short)stoppass; current.distest = distest ; current.trigndx[0] = trigndx[0] ; current.trigndx[1] = trigndx[1] ; current.trigndx[2] = trigndx[2] ; current.trigndx[3] = trigndx[3] ; current.finattract = (short)finattract ; current.initorbit[0] = initorbit.x ; current.initorbit[1] = initorbit.y ; current.useinitorbit = useinitorbit ; current.periodicity = (short)periodicitycheck ; current.pot16bit = (short)disk16bit ; current.release = (short)release ; current.save_release = (short)save_release ; current.flag3d = (short)display3d ; current.ambient = (short)Ambient ; current.randomize = (short)RANDOMIZE ; current.haze = (short)haze ; current.transparent[0] = (short)transparent[0] ; current.transparent[1] = (short)transparent[1] ; current.rotate_lo = (short)rotate_lo ; current.rotate_hi = (short)rotate_hi ; current.distestwidth = (short)distestwidth ; current.mxmaxfp = mxmaxfp ; current.mxminfp = mxminfp ; current.mymaxfp = mymaxfp ; current.myminfp = myminfp ; current.zdots = (short)zdots ; current.originfp = originfp ; current.depthfp = depthfp ; current.heightfp = heightfp ; current.widthfp = widthfp ; current.distfp = distfp ; current.eyesfp = eyesfp ; current.orbittype = (short)neworbittype ; current.juli3Dmode = (short)juli3Dmode ; current.maxfn = maxfn ; current.major_method = (short)major_method ; current.minor_method = (short)minor_method ; current.bailout = bailout ; current.bailoutest = (short)bailoutest ; current.iterations = maxit ; current.old_demm_colors = (short)old_demm_colors; current.logcalc = (short)Log_Fly_Calc; current.ismand = (short)ismand; current.closeprox = closeprox; current.nobof = (short)nobof; current.orbit_delay = (short)orbit_delay; current.orbit_interval = orbit_interval; current.oxmin = oxmin; current.oxmax = oxmax; current.oymin = oymin; current.oymax = oymax; current.ox3rd = ox3rd; current.oy3rd = oy3rd; current.keep_scrn_coords= (short)keep_scrn_coords; current.drawmode = drawmode; far_memcpy(current.dac,dacbox,256*3); switch(fractype) { case FORMULA: case FFORMULA: far_strncpy(current.filename,FormFileName,FILE_MAX_PATH); far_strncpy(current.itemname,FormName,ITEMNAMELEN+1); break; case IFS: case IFS3D: far_strncpy(current.filename,IFSFileName,FILE_MAX_PATH); far_strncpy(current.itemname,IFSName,ITEMNAMELEN+1); break; case LSYSTEM: far_strncpy(current.filename,LFileName,FILE_MAX_PATH); far_strncpy(current.itemname,LName,ITEMNAMELEN+1); break; default: *(current.filename) = 0; *(current.itemname) = 0; break; } if (historyptr == -1) /* initialize the history file */ { int i; for (i = 0; i < maxhistory; i++) MoveToMemory((BYTE far *)¤t,(U16)sizeof(HISTORY),1L,(long)i,history); historyflag = saveptr = historyptr = 0; /* initialize history ptr */ } else if(historyflag == 1) historyflag = 0; /* coming from user history command, don't save */ else if(far_memcmp(¤t,&last,sizeof(HISTORY))) { if(++saveptr >= maxhistory) /* back to beginning of circular buffer */ saveptr = 0; if(++historyptr >= maxhistory) /* move user pointer in parallel */ historyptr = 0; MoveToMemory((BYTE far *)¤t,(U16)sizeof(HISTORY),1L,(long)saveptr,history); } } void _fastcall restore_history_info(int i) { HISTORY last; if(maxhistory <= 0 || bf_math || history == 0) return; MoveFromMemory((BYTE far *)&last,(U16)sizeof(HISTORY),1L,(long)i,history); invert = 0; calc_status = 0; resuming = 0; fractype = last.fractal_type ; xxmin = last.xmin ; xxmax = last.xmax ; yymin = last.ymin ; yymax = last.ymax ; param[0] = last.creal ; param[1] = last.cimag ; param[2] = last.dparm3 ; param[3] = last.dparm4 ; param[4] = last.dparm5 ; param[5] = last.dparm6 ; param[6] = last.dparm7 ; param[7] = last.dparm8 ; param[8] = last.dparm9 ; param[9] = last.dparm10 ; fillcolor = last.fillcolor ; potparam[0] = last.potential[0] ; potparam[1] = last.potential[1] ; potparam[2] = last.potential[2] ; rflag = last.rflag ; rseed = last.rseed ; inside = last.inside ; LogFlag = last.logmap ; inversion[0] = last.invert[0] ; inversion[1] = last.invert[1] ; inversion[2] = last.invert[2] ; decomp[0] = last.decomp ; usr_biomorph = last.biomorph ; biomorph = last.biomorph ; forcesymmetry = last.symmetry ; init3d[0] = last.init3d[0] ; init3d[1] = last.init3d[1] ; init3d[2] = last.init3d[2] ; init3d[3] = last.init3d[3] ; init3d[4] = last.init3d[4] ; init3d[5] = last.init3d[5] ; init3d[6] = last.init3d[6] ; init3d[7] = last.init3d[7] ; init3d[8] = last.init3d[8] ; init3d[9] = last.init3d[9] ; init3d[10] = last.init3d[10] ; init3d[12] = last.init3d[11] ; init3d[13] = last.init3d[12] ; init3d[14] = last.init3d[13] ; init3d[15] = last.init3d[14] ; init3d[16] = last.init3d[15] ; previewfactor = last.previewfactor ; xtrans = last.xtrans ; ytrans = last.ytrans ; red_crop_left = last.red_crop_left ; red_crop_right = last.red_crop_right ; blue_crop_left = last.blue_crop_left ; blue_crop_right = last.blue_crop_right; red_bright = last.red_bright ; blue_bright = last.blue_bright ; xadjust = last.xadjust ; yadjust = last.yadjust ; eyeseparation = last.eyeseparation ; glassestype = last.glassestype ; outside = last.outside ; xx3rd = last.x3rd ; yy3rd = last.y3rd ; usr_stdcalcmode = last.stdcalcmode ; stdcalcmode = last.stdcalcmode ; three_pass = last.three_pass ; stoppass = last.stoppass ; distest = last.distest ; usr_distest = last.distest ; trigndx[0] = last.trigndx[0] ; trigndx[1] = last.trigndx[1] ; trigndx[2] = last.trigndx[2] ; trigndx[3] = last.trigndx[3] ; finattract = last.finattract ; initorbit.x = last.initorbit[0] ; initorbit.y = last.initorbit[1] ; useinitorbit = last.useinitorbit ; periodicitycheck = last.periodicity ; usr_periodicitycheck = last.periodicity ; disk16bit = last.pot16bit ; release = last.release ; save_release = last.save_release ; display3d = last.flag3d ; Ambient = last.ambient ; RANDOMIZE = last.randomize ; haze = last.haze ; transparent[0] = last.transparent[0] ; transparent[1] = last.transparent[1] ; rotate_lo = last.rotate_lo ; rotate_hi = last.rotate_hi ; distestwidth = last.distestwidth ; mxmaxfp = last.mxmaxfp ; mxminfp = last.mxminfp ; mymaxfp = last.mymaxfp ; myminfp = last.myminfp ; zdots = last.zdots ; originfp = last.originfp ; depthfp = last.depthfp ; heightfp = last.heightfp ; widthfp = last.widthfp ; distfp = last.distfp ; eyesfp = last.eyesfp ; neworbittype = last.orbittype ; juli3Dmode = last.juli3Dmode ; maxfn = last.maxfn ; major_method = (enum Major)last.major_method ; minor_method = (enum Minor)last.minor_method ; bailout = last.bailout ; bailoutest = (enum bailouts)last.bailoutest ; maxit = last.iterations ; old_demm_colors = last.old_demm_colors; curfractalspecific = &fractalspecific[fractype]; potflag = (potparam[0] != 0.0); if (inversion[0] != 0.0) invert = 3; Log_Fly_Calc = last.logcalc; ismand = last.ismand; closeprox = last.closeprox; nobof = last.nobof; orbit_delay = last.orbit_delay; orbit_interval = last.orbit_interval; oxmin = last.oxmin; oxmax = last.oxmax; oymin = last.oymin; oymax = last.oymax; ox3rd = last.ox3rd; oy3rd = last.oy3rd; keep_scrn_coords = last.keep_scrn_coords; if (keep_scrn_coords) set_orbit_corners = 1; drawmode = last.drawmode; usr_floatflag = (char)((curfractalspecific->isinteger) ? 0 : 1); far_memcpy(dacbox,last.dac,256*3); far_memcpy(olddacbox,last.dac,256*3); if(mapdacbox) far_memcpy(mapdacbox,last.dac,256*3); spindac(0,1); if(fractype == JULIBROT || fractype == JULIBROTFP) savedac = 0; else savedac = 1; switch(fractype) { case FORMULA: case FFORMULA: far_strncpy(FormFileName,last.filename,FILE_MAX_PATH); far_strncpy(FormName, last.itemname,ITEMNAMELEN+1); break; case IFS: case IFS3D: far_strncpy(IFSFileName,last.filename,FILE_MAX_PATH); far_strncpy(IFSName ,last.itemname,ITEMNAMELEN+1); break; case LSYSTEM: far_strncpy(LFileName,last.filename,FILE_MAX_PATH); far_strncpy(LName ,last.itemname,ITEMNAMELEN+1); break; default: break; } } xfractint-20.4.10.orig/common/prompts2.c0000644000000000000000000024211611257714555014751 0ustar /* Various routines that prompt for things. */ #include #include #ifndef XFRACT #include #elif !defined(__386BSD__) #include #include #ifdef DIRENT #include #elif !defined(__SVR4) #include #else #include #ifndef DIRENT #define DIRENT #endif #endif #endif #ifdef __TURBOC__ #include #elif !defined(__386BSD__) #include #endif #ifdef XFRACT #include #endif #ifdef __hpux #include #endif #ifdef __SVR4 #include #endif /* see Fractint.c for a description of the "include" hierarchy */ #include "port.h" #include "prototyp.h" #include "fractype.h" #include "helpdefs.h" /* Routines in this module */ static int check_f6_key(int curkey,int choice); static int expand_dirname(char *dirname,char *drive); static int filename_speedstr(int, int, int, char *, int); static int get_screen_corners(void); /* speed key state values */ #define MATCHING 0 /* string matches list - speed key mode */ #define TEMPLATE -2 /* wild cards present - buiding template */ #define SEARCHPATH -3 /* no match - building path search name */ #define FILEATTR 0x37 /* File attributes; select all but volume labels */ #define HIDDEN 2 #define SYSTEM 4 #define SUBDIR 16 #define MAXNUMFILES 2977L struct DIR_SEARCH DTA; /* Allocate DTA and define structure */ #define GETFORMULA 0 #define GETLSYS 1 #define GETIFS 2 #define GETPARM 3 char commandmask[MAX_NAME] = {"*.par"}; /* --------------------------------------------------------------------- */ /* get_toggles() is called from FRACTINT.C whenever the 'x' key is pressed. This routine prompts for several options, sets the appropriate variables, and returns the following code to the calling routine: -1 routine was ESCAPEd - no need to re-generate the image. 0 nothing changed, or minor variable such as "overwrite=". No need to re-generate the image. 1 major variable changed (such as "inside="). Re-generate the image. Finally, remember to insert variables in the list *and* check for them in the same order!!! */ #define LOADCHOICES(X) {\ static FCODE tmp[] = { X };\ far_strcpy(ptr,(char far *)tmp);\ choices[++k]= ptr;\ ptr += sizeof(tmp);\ } int get_toggles() { static FCODE o_hdg[]={"Basic Options\n(not all combinations make sense)"}; char hdg[sizeof(o_hdg)]; char far *choices[20]; char far *ptr; int oldhelpmode; char prevsavename[FILE_MAX_DIR+1]; char *savenameptr; struct fullscreenvalues uvalues[25]; int i, j, k; char old_usr_stdcalcmode; long old_maxit,old_logflag; int old_inside,old_outside,old_soundflag; int old_biomorph,old_decomp; int old_fillcolor; int old_stoppass; double old_closeprox; char *calcmodes[] ={"1","2","3","g","g1","g2","g3","g4","g5","g6","b","s","t","d","o"}; char *soundmodes[5]={s_off,s_beep,s_x,s_y,s_z}; char *insidemodes[]={"numb",s_maxiter,s_zmag,s_bof60,s_bof61,s_epscross, s_startrail,s_period,s_atan,s_fmod}; char *outsidemodes[]={"numb",s_iter,s_real,s_imag,s_mult,s_sum,s_atan, s_fmod,s_tdis}; far_strcpy(hdg,o_hdg); ptr = (char far *)MK_FP(extraseg,0); k = -1; LOADCHOICES("Passes (1,2,3, g[uess], b[ound], t[ess], d[iffu], o[rbit])"); uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 3; uvalues[k].uval.ch.llen = sizeof(calcmodes)/sizeof(*calcmodes); uvalues[k].uval.ch.list = calcmodes; uvalues[k].uval.ch.val = (usr_stdcalcmode == '1') ? 0 : (usr_stdcalcmode == '2') ? 1 : (usr_stdcalcmode == '3') ? 2 : (usr_stdcalcmode == 'g' && stoppass == 0) ? 3 : (usr_stdcalcmode == 'g' && stoppass == 1) ? 4 : (usr_stdcalcmode == 'g' && stoppass == 2) ? 5 : (usr_stdcalcmode == 'g' && stoppass == 3) ? 6 : (usr_stdcalcmode == 'g' && stoppass == 4) ? 7 : (usr_stdcalcmode == 'g' && stoppass == 5) ? 8 : (usr_stdcalcmode == 'g' && stoppass == 6) ? 9 : (usr_stdcalcmode == 'b') ? 10 : (usr_stdcalcmode == 's') ? 11 : (usr_stdcalcmode == 't') ? 12 : (usr_stdcalcmode == 'd') ? 13 : /* "o"rbits */ 14; old_usr_stdcalcmode = usr_stdcalcmode; old_stoppass = stoppass; #ifndef XFRACT LOADCHOICES("Floating Point Algorithm"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = usr_floatflag; #endif LOADCHOICES("Maximum Iterations (2 to 2,147,483,647)"); uvalues[k].type = 'L'; uvalues[k].uval.Lval = old_maxit = maxit; LOADCHOICES("Inside Color (0-# of colors, if Inside=numb)"); uvalues[k].type = 'i'; if (inside >= 0) uvalues[k].uval.ival = inside; else uvalues[k].uval.ival = 0; LOADCHOICES("Inside (numb,maxit,zmag,bof60,bof61,epscr,star,per,atan,fmod)"); uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 12; uvalues[k].uval.ch.llen = sizeof(insidemodes)/sizeof(*insidemodes); uvalues[k].uval.ch.list = insidemodes; if(inside >= 0) /* numb */ uvalues[k].uval.ch.val = 0; else if(inside == -1) /* maxiter */ uvalues[k].uval.ch.val = 1; else if(inside == ZMAG) uvalues[k].uval.ch.val = 2; else if(inside == BOF60) uvalues[k].uval.ch.val = 3; else if(inside == BOF61) uvalues[k].uval.ch.val = 4; else if(inside == EPSCROSS) uvalues[k].uval.ch.val = 5; else if(inside == STARTRAIL) uvalues[k].uval.ch.val = 6; else if(inside == PERIOD) uvalues[k].uval.ch.val = 7; else if(inside == ATANI) uvalues[k].uval.ch.val = 8; else if(inside == FMODI) uvalues[k].uval.ch.val = 9; old_inside = inside; LOADCHOICES("Outside Color (0-# of colors, if Outside=numb)"); uvalues[k].type = 'i'; if (outside >= 0) uvalues[k].uval.ival = outside; else uvalues[k].uval.ival = 0; LOADCHOICES("Outside (numb,iter,real,imag,mult,summ,atan,fmod,tdis)"); uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 4; uvalues[k].uval.ch.llen = sizeof(outsidemodes)/sizeof(*outsidemodes); uvalues[k].uval.ch.list = outsidemodes; if(outside >= 0) /* numb */ uvalues[k].uval.ch.val = 0; else uvalues[k].uval.ch.val = -outside; old_outside = outside; LOADCHOICES("Savename (.GIF implied)"); uvalues[k].type = 's'; strcpy(prevsavename,savename); savenameptr = strrchr(savename, SLASHC); if(savenameptr == NULL) savenameptr = savename; else savenameptr++; /* point past slash */ strcpy(uvalues[k].uval.sval,savenameptr); LOADCHOICES("File Overwrite ('overwrite=')"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = overwrite; LOADCHOICES("Sound (off, beep, x, y, z)"); uvalues[k].type = 'l'; uvalues[k].uval.ch.vlen = 4; uvalues[k].uval.ch.llen = 5; uvalues[k].uval.ch.list = soundmodes; uvalues[k].uval.ch.val = (old_soundflag = soundflag)&7; if (rangeslen == 0) { LOADCHOICES("Log Palette (0=no,1=yes,-1=old,+n=cmprsd,-n=sqrt, 2=auto)"); uvalues[k].type = 'L'; } else { LOADCHOICES("Log Palette (n/a, ranges= parameter is in effect)"); uvalues[k].type = '*'; } uvalues[k].uval.Lval = old_logflag = LogFlag; LOADCHOICES("Biomorph Color (-1 means OFF)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_biomorph = usr_biomorph; LOADCHOICES("Decomp Option (2,4,8,..,256, 0=OFF)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_decomp = decomp[0]; LOADCHOICES("Fill Color (normal,#) (works with passes=t, b and d)"); uvalues[k].type = 's'; if(fillcolor < 0) strcpy(uvalues[k].uval.sval,s_normal); else sprintf(uvalues[k].uval.sval,"%d",fillcolor); old_fillcolor = fillcolor; LOADCHOICES("Proximity value for inside=epscross and fmod"); uvalues[k].type = 'f'; /* should be 'd', but prompts get messed up JCO */ uvalues[k].uval.dval = old_closeprox = closeprox; oldhelpmode = helpmode; helpmode = HELPXOPTS; i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,NULL); helpmode = oldhelpmode; if (i < 0) { return(-1); } /* now check out the results (*hopefully* in the same order ) */ k = -1; j = 0; /* return code */ usr_stdcalcmode = calcmodes[uvalues[++k].uval.ch.val][0]; stoppass = (int)calcmodes[uvalues[k].uval.ch.val][1] - (int)'0'; if(stoppass < 0 || stoppass > 6 || usr_stdcalcmode != 'g') stoppass = 0; if(usr_stdcalcmode == 'o' && fractype == LYAPUNOV) /* Oops,lyapunov type */ /* doesn't use 'new' & breaks orbits */ usr_stdcalcmode = old_usr_stdcalcmode; if (old_usr_stdcalcmode != usr_stdcalcmode) j++; if (old_stoppass != stoppass) j++; #ifndef XFRACT if (uvalues[++k].uval.ch.val != usr_floatflag) { usr_floatflag = (char)uvalues[k].uval.ch.val; j++; } #endif ++k; maxit = uvalues[k].uval.Lval; if (maxit < 0) maxit = old_maxit; if (maxit < 2) maxit = 2; if (maxit != old_maxit) j++; inside = uvalues[++k].uval.ival; if (inside < 0) inside = -inside; if (inside >= colors) inside = (inside % colors) + (inside / colors); { int tmp; tmp = uvalues[++k].uval.ch.val; if (tmp > 0) switch (tmp) { case 1: inside = -1; /* maxiter */ break; case 2: inside = ZMAG; break; case 3: inside = BOF60; break; case 4: inside = BOF61; break; case 5: inside = EPSCROSS; break; case 6: inside = STARTRAIL; break; case 7: inside = PERIOD; break; case 8: inside = ATANI; break; case 9: inside = FMODI; break; } } if (inside != old_inside) j++; outside = uvalues[++k].uval.ival; if (outside < 0) outside = -outside; if (outside >= colors) outside = (outside % colors) + (outside / colors); { int tmp; tmp = uvalues[++k].uval.ch.val; if (tmp > 0) outside = -tmp; } if (outside != old_outside) j++; strcpy(savenameptr,uvalues[++k].uval.sval); if (strcmp(savename,prevsavename)) resave_flag = started_resaves = 0; /* forget pending increment */ overwrite = (char)uvalues[++k].uval.ch.val; soundflag = ((soundflag >> 3) << 3) | (uvalues[++k].uval.ch.val); if (soundflag != old_soundflag && ((soundflag&7) > 1 || (old_soundflag&7) > 1)) j++; LogFlag = uvalues[++k].uval.Lval; if (LogFlag != old_logflag) { j++; Log_Auto_Calc = 0; /* turn it off, use the supplied value */ } usr_biomorph = uvalues[++k].uval.ival; if (usr_biomorph >= colors) usr_biomorph = (usr_biomorph % colors) + (usr_biomorph / colors); if (usr_biomorph != old_biomorph) j++; decomp[0] = uvalues[++k].uval.ival; if (decomp[0] != old_decomp) j++; if(strncmp(strlwr(uvalues[++k].uval.sval),s_normal,4)==0) fillcolor = -1; else fillcolor = atoi(uvalues[k].uval.sval); if (fillcolor < 0) fillcolor = -1; if (fillcolor >= colors) fillcolor = (fillcolor % colors) + (fillcolor / colors); if (fillcolor != old_fillcolor) j++; ++k; closeprox = uvalues[k].uval.dval; if (closeprox != old_closeprox) j++; /* if (j >= 1) j = 1; need to know how many prompts changed for quick_calc JCO 6/23/2001 */ return(j); } /* get_toggles2() is similar to get_toggles, invoked by 'y' key */ int get_toggles2() { static FCODE o_hdg[]={"Extended Options\n\ (not all combinations make sense)"}; char hdg[sizeof(o_hdg)]; char far *ptr; char far *choices[18]; int oldhelpmode; struct fullscreenvalues uvalues[23]; int i, j, k; int old_rotate_lo,old_rotate_hi; int old_distestwidth; double old_potparam[3],old_inversion[3]; long old_usr_distest; far_strcpy(hdg,o_hdg); ptr = (char far *)MK_FP(extraseg,0); /* fill up the choices (and previous values) arrays */ k = -1; LOADCHOICES("Look for finite attractor (0=no,>0=yes,<0=phase)"); uvalues[k].type = 'i'; uvalues[k].uval.ch.val = finattract; LOADCHOICES("Potential Max Color (0 means off)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = (int)(old_potparam[0] = potparam[0]); LOADCHOICES(" Slope"); uvalues[k].type = 'd'; uvalues[k].uval.dval = old_potparam[1] = potparam[1]; LOADCHOICES(" Bailout"); uvalues[k].type = 'i'; uvalues[k].uval.ival = (int)(old_potparam[2] = potparam[2]); LOADCHOICES(" 16 bit values"); uvalues[k].type = 'y'; uvalues[k].uval.ch.val = pot16bit; LOADCHOICES("Distance Estimator (0=off, <0=edge, >0=on):"); uvalues[k].type = 'L'; uvalues[k].uval.Lval = old_usr_distest = usr_distest; LOADCHOICES(" width factor:"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_distestwidth = distestwidth; LOADCHOICES("Inversion radius or \"auto\" (0 means off)"); LOADCHOICES(" center X coordinate or \"auto\""); LOADCHOICES(" center Y coordinate or \"auto\""); k = k - 3; for (i= 0; i < 3; i++) { uvalues[++k].type = 's'; if ((old_inversion[i] = inversion[i]) == AUTOINVERT) sprintf(uvalues[k].uval.sval,"auto"); else sprintf(uvalues[k].uval.sval,"%-1.15lg",inversion[i]); } LOADCHOICES(" (use fixed radius & center when zooming)"); uvalues[k].type = '*'; LOADCHOICES("Color cycling from color (0 ... 254)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_rotate_lo = rotate_lo; LOADCHOICES(" to color (1 ... 255)"); uvalues[k].type = 'i'; uvalues[k].uval.ival = old_rotate_hi = rotate_hi; oldhelpmode = helpmode; helpmode = HELPYOPTS; i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,NULL); helpmode = oldhelpmode; if (i < 0) { return(-1); } /* now check out the results (*hopefully* in the same order ) */ k = -1; j = 0; /* return code */ if (uvalues[++k].uval.ch.val != finattract) { finattract = uvalues[k].uval.ch.val; j = 1; } potparam[0] = uvalues[++k].uval.ival; if (potparam[0] != old_potparam[0]) j = 1; potparam[1] = uvalues[++k].uval.dval; if (potparam[0] != 0.0 && potparam[1] != old_potparam[1]) j = 1; potparam[2] = uvalues[++k].uval.ival; if (potparam[0] != 0.0 && potparam[2] != old_potparam[2]) j = 1; if (uvalues[++k].uval.ch.val != pot16bit) { pot16bit = uvalues[k].uval.ch.val; if (pot16bit) { /* turned it on */ if (potparam[0] != 0.0) j = 1; } else /* turned it off */ if (dotmode != 11) /* ditch the disk video */ enddisk(); else /* keep disk video, but ditch the fraction part at end */ disk16bit = 0; } ++k; /* usr_distest = (uvalues[k].uval.ival > 32000) ? 32000 : uvalues[k].uval.ival; */ usr_distest = uvalues[k].uval.Lval; if (usr_distest != old_usr_distest) j = 1; ++k; distestwidth = uvalues[k].uval.ival; if (usr_distest && distestwidth != old_distestwidth) j = 1; for (i = 0; i < 3; i++) { if (uvalues[++k].uval.sval[0] == 'a' || uvalues[k].uval.sval[0] == 'A') inversion[i] = AUTOINVERT; else inversion[i] = atof(uvalues[k].uval.sval); if (old_inversion[i] != inversion[i] && (i == 0 || inversion[0] != 0.0)) j = 1; } invert = (inversion[0] == 0.0) ? 0 : 3; ++k; rotate_lo = uvalues[++k].uval.ival; rotate_hi = uvalues[++k].uval.ival; if (rotate_lo < 0 || rotate_hi > 255 || rotate_lo > rotate_hi) { rotate_lo = old_rotate_lo; rotate_hi = old_rotate_hi; } return(j); } /* passes_options invoked by