home *** CD-ROM | disk | FTP | other *** search
/ Fractal Creations (Second Edition) / FRACTALS_2E.iso / xfract / xfsrc < prev   
Text File  |  1993-10-28  |  2MB  |  75,096 lines

  1. #!/bin/sh
  2. # This is a shell archive (shar 3.24)
  3. # made 10/29/1993 06:19 UTC by shirriff@sprite.Berkeley.EDU
  4. # Source directory /user6/shirriff/rsrch/fractint
  5. #
  6. # existing files WILL be overwritten
  7. #
  8. # This shar contains:
  9. # length  mode       name
  10. # ------ ---------- ------------------------------------------
  11. #  10094 -rw-r--r-- 3d.c
  12. #  84436 -rw-r--r-- calcfrac.c
  13. #  67637 -rw-r--r-- cmdfiles.c
  14. #  13232 -rw-r--r-- decoder.c
  15. #  80381 -rw-r--r-- editpal.c
  16. #  28368 -rw-r--r-- encoder.c
  17. #   2503 -rw-r--r-- f16.c
  18. #  30883 -rw-r--r-- fracsubr.c
  19. #  48702 -rw-r--r-- fractalp.c
  20. # 101275 -rw-r--r-- fractals.c
  21. #  54603 -rw-r--r-- fractint.c
  22. #   8871 -rw-r--r-- gifview.c
  23. #  83237 -rw-r--r-- hc.c
  24. #   2946 -rw-r--r-- hcmplx.c
  25. #  36787 -rw-r--r-- help.c
  26. #   3156 -rw-r--r-- intro.c
  27. #  12009 -rw-r--r-- jb.c
  28. #  35541 -rw-r--r-- jiim.c
  29. #  77259 -rw-r--r-- line3d.c
  30. #  14560 -rw-r--r-- loadfdos.c
  31. #  22666 -rw-r--r-- loadfile.c
  32. #   2268 -rw-r--r-- loadmap.c
  33. #  66158 -rw-r--r-- lorenz.c
  34. #  21423 -rw-r--r-- lsys.c
  35. #  56787 -rw-r--r-- miscfrac.c
  36. #  56485 -rw-r--r-- miscovl.c
  37. #  27230 -rw-r--r-- miscres.c
  38. #  11132 -rw-r--r-- mpmath_c.c
  39. #  54067 -rw-r--r-- parser.c
  40. #  35051 -rw-r--r-- parserfp.c
  41. #  13679 -rw-r--r-- plot3d.c
  42. #  44938 -rw-r--r-- printer.c
  43. #  63669 -rw-r--r-- prompts1.c
  44. #  49042 -rw-r--r-- prompts2.c
  45. #  51622 -rw-r--r-- realdos.c
  46. #  14636 -rw-r--r-- rotate.c
  47. #   8468 -rw-r--r-- slideshw.c
  48. #  19635 -rw-r--r-- targa.c
  49. #   2048 -rw-r--r-- testpt.c
  50. #   1504 -rw-r--r-- tgaview.c
  51. #   7735 -rw-r--r-- tp3d.c
  52. #  11727 -rw-r--r-- tplus.c
  53. #  18354 -rw-r--r-- zoom.c
  54. #  19765 -rw-r--r-- fractint.h
  55. #   5675 -rw-r--r-- fractype.h
  56. #   6871 -rw-r--r-- fmath.h
  57. #   4549 -rw-r--r-- port.h
  58. #  15703 -rw-r--r-- helpcom.h
  59. #   7593 -rw-r--r-- helpdefs.h
  60. #   7413 -rw-r--r-- mpmath.h
  61. #   8664 -rw-r--r-- targa.h
  62. #    618 -rw-r--r-- targa_lc.h
  63. #   2388 -rw-r--r-- tplus.h
  64. #  33264 -rw-r--r-- prototyp.h
  65. #  17535 -rw-r--r-- fractsrc.doc
  66. #   2610 -rw-r--r-- debugfla.doc
  67. #  17114 -rw-r--r-- hc.doc
  68. #    381 -rw-r--r-- calcmand.c
  69. #   3910 -rw-r--r-- calmanfp.c
  70. #   5594 -rw-r--r-- diskvidu.c
  71. #   3671 -rw-r--r-- fpu087.c
  72. #    589 -rw-r--r-- fracsuba.c
  73. #  19394 -rw-r--r-- general.c
  74. #   8947 -rw-r--r-- printera.c
  75. #    295 -rw-r--r-- tplus_a.c
  76. #  15972 -rw-r--r-- video.c
  77. #   8340 -rw-r--r-- unix.c
  78. #  46415 -rw-r--r-- unixscr.c
  79. #   3507 -rw-r--r-- unix.h
  80. #  10830 -rw-r--r-- Makefile
  81. #   4195 -rw-r--r-- versions
  82. #  76566 -rw-r--r-- help.src
  83. # 116316 -rw-r--r-- help2.src
  84. #  64400 -rw-r--r-- help3.src
  85. #  79101 -rw-r--r-- help4.src
  86. #  93177 -rw-r--r-- help5.src
  87. #
  88. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  89.  then TOUCH=touch
  90.  else TOUCH=true
  91. fi
  92. # ============= 3d.c ==============
  93. echo "x - extracting 3d.c (Text)"
  94. sed 's/^X//' << 'SHAR_EOF' > 3d.c &&
  95. X/*
  96. XA word about the 3D library. Even though this library supports
  97. Xthree dimensions, the matrices are 4x4 for the following reason.
  98. XWith normal 3 dimensional vectors, translation is an ADDITION,
  99. Xand rotation is a MULTIPLICATION. A vector {x,y,z} is represented
  100. Xas a 4-tuple {x,y,z,1}. It is then possible to define a 4x4
  101. Xmatrix such that multiplying the vector by the matrix translates
  102. Xthe vector. This allows combinations of translation and rotation
  103. Xto be obtained in a single matrix by multiplying a translation
  104. Xmatrix and a rotation matrix together. Note that in the code,
  105. Xvectors have three components; since the fourth component is
  106. Xalways 1, that value is not included in the vector variable to
  107. Xsave space, but the routines make use of the fourth component
  108. X(see vec_mult()). Similarly, the fourth column of EVERY matrix is
  109. Xalways
  110. X     0
  111. X     0
  112. X     0
  113. X     1
  114. Xbut currently the C version of a matrix includes this even though
  115. Xit could be left out of the data structure and assumed in the
  116. Xroutines. Vectors are ROW vectors, and are always multiplied with
  117. Xmatrices FROM THE LEFT (e.g. vector*matrix). Also note the order
  118. Xof indices of a matrix is matrix[row][column], and in usual C
  119. Xfashion, numbering starts with 0.
  120. X
  121. XTRANSLATION MATRIX =  1     0      0    0
  122. X              0     1      0    0
  123. X              0     0      1    0
  124. X              Tx    Ty      Tz    1
  125. X
  126. XSCALE MATRIX =          Sx    0      0    0
  127. X              0     Sy      0    0
  128. X              0     0      Sz    0
  129. X              0     0      0    1
  130. X
  131. XRotation about x axis i degrees:
  132. XROTX(i) =        1     0     0      0
  133. X              0   cosi  sini    0
  134. X              0  -sini  cosi    0
  135. X              0     0      0    1
  136. X
  137. XRotation about y axis i degrees:
  138. XROTY(i) =          cosi    0  -sini    0
  139. X              0     1      0    0
  140. X            sini    0   cosi    0
  141. X              0     0      0    1
  142. X
  143. XRotation about z axis i degrees:
  144. XROTZ(i) =          cosi  sini    0     0
  145. X           -sini  cosi    0     0
  146. X              0     0      1    0
  147. X              0     0      0    1
  148. X
  149. X              --  Tim Wegner  April 22, 1989
  150. X*/
  151. X
  152. X#include <stdio.h>
  153. X#include <float.h>
  154. X#include <string.h>
  155. X#include "fractint.h"
  156. X#include "prototyp.h"
  157. Xextern int overflow;
  158. Xextern int bad_value;
  159. X
  160. X/* initialize a matrix and set to identity matrix
  161. X   (all 0's, 1's on diagonal) */
  162. Xvoid identity(MATRIX m)
  163. X{
  164. X   int i,j;
  165. X   for(i=0;i<CMAX;i++)
  166. X   for(j=0;j<RMAX;j++)
  167. X      if(i==j)
  168. X     m[j][i] = 1.0;
  169. X      else
  170. X      m[j][i] = 0.0;
  171. X}
  172. X
  173. X/* Multiply two matrices */
  174. Xvoid mat_mul(MATRIX mat1, MATRIX mat2, MATRIX mat3)
  175. X{
  176. X     /* result stored in MATRIX new to avoid problems
  177. X    in case parameter mat3 == mat2 or mat 1 */
  178. X     MATRIX new;
  179. X     int i,j;
  180. X     for(i=0;i<4;i++)
  181. X     for(j=0;j<4;j++)
  182. X    new[j][i] =  mat1[j][0]*mat2[0][i]+
  183. X             mat1[j][1]*mat2[1][i]+
  184. X             mat1[j][2]*mat2[2][i]+
  185. X             mat1[j][3]*mat2[3][i];
  186. X     memcpy(mat3,new,sizeof(new));
  187. X}
  188. X
  189. X/* multiply a matrix by a scalar */
  190. Xvoid scale (double sx, double sy, double sz, MATRIX m)
  191. X{
  192. X   MATRIX scale;
  193. X   identity(scale);
  194. X   scale[0][0] = sx;
  195. X   scale[1][1] = sy;
  196. X   scale[2][2] = sz;
  197. X   mat_mul(m,scale,m);
  198. X}
  199. X
  200. X/* rotate about X axis    */
  201. Xvoid xrot (double theta, MATRIX m)
  202. X{
  203. X   MATRIX rot;
  204. X   double sintheta,costheta;
  205. X   sintheta = sin(theta);
  206. X   costheta = cos(theta);
  207. X   identity(rot);
  208. X   rot[1][1] = costheta;
  209. X   rot[1][2] = -sintheta;
  210. X   rot[2][1] = sintheta;
  211. X   rot[2][2] = costheta;
  212. X   mat_mul(m,rot,m);
  213. X}
  214. X
  215. X/* rotate about Y axis    */
  216. Xvoid yrot (double theta, MATRIX m)
  217. X{
  218. X   MATRIX rot;
  219. X   double sintheta,costheta;
  220. X   sintheta = sin(theta);
  221. X   costheta = cos(theta);
  222. X   identity(rot);
  223. X   rot[0][0] = costheta;
  224. X   rot[0][2] = sintheta;
  225. X   rot[2][0] = -sintheta;
  226. X   rot[2][2] = costheta;
  227. X   mat_mul(m,rot,m);
  228. X}
  229. X
  230. X/* rotate about Z axis    */
  231. Xvoid zrot (double theta, MATRIX m)
  232. X{
  233. X   MATRIX rot;
  234. X   double sintheta,costheta;
  235. X   sintheta = sin(theta);
  236. X   costheta = cos(theta);
  237. X   identity(rot);
  238. X   rot[0][0] = costheta;
  239. X   rot[0][1] = -sintheta;
  240. X   rot[1][0] = sintheta;
  241. X   rot[1][1] = costheta;
  242. X   mat_mul(m,rot,m);
  243. X}
  244. X
  245. X/* translate  */
  246. Xvoid trans (double tx, double ty, double tz, MATRIX m)
  247. X{
  248. X   MATRIX trans;
  249. X   identity(trans);
  250. X   trans[3][0] = tx;
  251. X   trans[3][1] = ty;
  252. X   trans[3][2] = tz;
  253. X   mat_mul(m,trans,m);
  254. X}
  255. X
  256. X/* cross product  - useful because cross is perpendicular to v and w */
  257. Xint cross_product (VECTOR v, VECTOR w, VECTOR cross)
  258. X{
  259. X   VECTOR tmp;
  260. X   tmp[0] =  v[1]*w[2] - w[1]*v[2];
  261. X   tmp[1] =  w[0]*v[2] - v[0]*w[2];
  262. X   tmp[2] =  v[0]*w[1] - w[0]*v[1];
  263. X   cross[0] = tmp[0];
  264. X   cross[1] = tmp[1];
  265. X   cross[2] = tmp[2];
  266. X   return(0);
  267. X}
  268. X
  269. X/* cross product integer arguments (not fudged) */
  270. X/*** pb, unused
  271. Xint icross_product (IVECTOR v, IVECTOR w, IVECTOR cross)
  272. X{
  273. X   IVECTOR tmp;
  274. X   tmp[0] =  v[1]*w[2] - w[1]*v[2];
  275. X   tmp[1] =  w[0]*v[2] - v[0]*w[2];
  276. X   tmp[2] =  v[0]*w[1] - w[0]*v[1];
  277. X   cross[0] = tmp[0];
  278. X   cross[1] = tmp[1];
  279. X   cross[2] = tmp[2];
  280. X   return(0);
  281. X}
  282. X***/
  283. X
  284. X/* normalize a vector to length 1 */
  285. Xnormalize_vector(VECTOR v)
  286. X{
  287. X    double vlength;
  288. X    vlength = dot_product(v,v);
  289. X
  290. X    /* bailout if zero vlength */
  291. X    if(vlength < FLT_MIN || vlength > FLT_MAX)
  292. X       return(-1);
  293. X    vlength = sqrt(vlength);
  294. X    if(vlength < FLT_MIN)
  295. X       return(-1);
  296. X
  297. X    v[0] /= vlength;
  298. X    v[1] /= vlength;
  299. X    v[2] /= vlength;
  300. X    return(0);
  301. X}
  302. X
  303. X/* multiply source vector s by matrix m, result in target t */
  304. X/* used to apply transformations to a vector */
  305. Xint vmult(s,m,t)
  306. XVECTOR s,t;
  307. XMATRIX m;
  308. X{
  309. X   VECTOR tmp;
  310. X   int i,j;
  311. X   for(j=0;j<CMAX-1;j++)
  312. X   {
  313. X      tmp[j] = 0.0;
  314. X      for(i=0;i<RMAX-1;i++)
  315. X     tmp[j] += s[i]*m[i][j];
  316. X      /* vector is really four dimensional with last component always 1 */
  317. X      tmp[j] += m[3][j];
  318. X   }
  319. X   /* set target = tmp. Necessary to use tmp in case source = target */
  320. X   memcpy(t,tmp,sizeof(tmp));
  321. X   return(0);
  322. X}
  323. X
  324. X/* multiply vector s by matrix m, result in s */
  325. X/* use with a function pointer in line3d.c */
  326. X/* must coordinate calling conventions with */
  327. X/* mult_vec_iit in general.asm */
  328. Xvoid mult_vec_c(s)
  329. XVECTOR s;
  330. X{
  331. X   extern MATRIX m;
  332. X   VECTOR tmp;
  333. X   int i,j;
  334. X   for(j=0;j<CMAX-1;j++)
  335. X   {
  336. X      tmp[j] = 0.0;
  337. X      for(i=0;i<RMAX-1;i++)
  338. X     tmp[j] += s[i]*m[i][j];
  339. X      /* vector is really four dimensional with last component always 1 */
  340. X      tmp[j] += m[3][j];
  341. X   }
  342. X   /* set target = tmp. Necessary to use tmp in case source = target */
  343. X   memcpy(s,tmp,sizeof(tmp));
  344. X}
  345. X
  346. X/* perspective projection of vector v with respect to viewpont vector view */
  347. Xperspective(VECTOR v)
  348. X{
  349. X   extern VECTOR view;
  350. X   double denom;
  351. X   denom = view[2] - v[2];
  352. X
  353. X   if(denom >= 0.0)
  354. X   {
  355. X      v[0] = bad_value;   /* clipping will catch these values */
  356. X      v[1] = bad_value;   /* so they won't plot values BEHIND viewer */
  357. X      v[2] = bad_value;
  358. X      return(-1);
  359. X   }
  360. X   v[0] = (v[0]*view[2] - view[0]*v[2])/denom;
  361. X   v[1] = (v[1]*view[2] - view[1]*v[2])/denom;
  362. X
  363. X   /* calculation of z if needed later */
  364. X   /* v[2] =  v[2]/denom;*/
  365. X   return(0);
  366. X}
  367. X
  368. X/* long version of vmult and perspective combined for speed */
  369. Xlongvmultpersp(s, m, t0, t, lview, bitshift)
  370. XLVECTOR s;     /* source vector */
  371. XLMATRIX m;     /* transformation matrix */
  372. XLVECTOR t0;     /* after transformation, before persp */
  373. XLVECTOR t;     /* target vector */
  374. XLVECTOR lview;     /* perspective viewer coordinates */
  375. Xint bitshift;     /* fixed point conversion bitshift */
  376. X{
  377. X   LVECTOR tmp;
  378. X   int i,j, k;
  379. X   overflow = 0;
  380. X   k = CMAX-1;            /* shorten the math if non-perspective and non-illum */
  381. X   if (lview[2] == 0 && t0[0] == 0) k--;
  382. X
  383. X   for(j=0;j<k;j++)
  384. X   {
  385. X      tmp[j] = 0;
  386. X      for(i=0;i<RMAX-1;i++)
  387. X     tmp[j] += multiply(s[i],m[i][j],bitshift);
  388. X      /* vector is really four dimensional with last component always 1 */
  389. X      tmp[j] += m[3][j];
  390. X   }
  391. X   if(t0[0]) /* first component of  t0 used as flag */
  392. X   {
  393. X      /* faster than for loop, if less general */
  394. X      t0[0] = tmp[0];
  395. X      t0[1] = tmp[1];
  396. X      t0[2] = tmp[2];
  397. X   }
  398. X   if (lview[2] != 0)        /* perspective 3D */
  399. X   {
  400. X
  401. X      LVECTOR tmpview;
  402. X      long denom;
  403. X
  404. X      denom = lview[2] - tmp[2];
  405. X      if (denom >= 0)        /* bail out if point is "behind" us */
  406. X      {
  407. X       t[0] = bad_value;
  408. X       t[0] = t[0]<<bitshift;
  409. X       t[1] = t[0];
  410. X       t[2] = t[0];
  411. X       return(-1);
  412. X      }
  413. X
  414. X      /* doing math in this order helps prevent overflow */
  415. X      tmpview[0] = divide(lview[0],denom,bitshift);
  416. X      tmpview[1] = divide(lview[1],denom,bitshift);
  417. X      tmpview[2] = divide(lview[2],denom,bitshift);
  418. X
  419. X      tmp[0] = multiply(tmp[0], tmpview[2], bitshift) -
  420. X           multiply(tmpview[0], tmp[2], bitshift);
  421. X
  422. X      tmp[1] = multiply(tmp[1], tmpview[2], bitshift) -
  423. X           multiply(tmpview[1], tmp[2], bitshift);
  424. X
  425. X      /* z coordinate if needed       */
  426. X      /* tmp[2] = divide(lview[2],denom);  */
  427. X   }
  428. X
  429. X   /* set target = tmp. Necessary to use tmp in case source = target */
  430. X   /* faster than for loop, if less general */
  431. X   t[0] = tmp[0];
  432. X   t[1] = tmp[1];
  433. X   t[2] = tmp[2];
  434. X   return(overflow);
  435. X}
  436. X
  437. X/* Long version of perspective. Because of use of fixed point math, there
  438. X   is danger of overflow and underflow */
  439. Xlongpersp(LVECTOR lv, LVECTOR lview, int bitshift)
  440. X{
  441. X   LVECTOR tmpview;
  442. X   long denom;
  443. X   overflow = 0;
  444. X   denom = lview[2] - lv[2];
  445. X   if (denom >= 0)        /* bail out if point is "behind" us */
  446. X   {
  447. X    lv[0] = bad_value;
  448. X    lv[0] = lv[0]<<bitshift;
  449. X    lv[1] = lv[0];
  450. X    lv[2] = lv[0];
  451. X    return(-1);
  452. X   }
  453. X
  454. X   /* doing math in this order helps prevent overflow */
  455. X   tmpview[0] = divide(lview[0],denom,bitshift);
  456. X   tmpview[1] = divide(lview[1],denom,bitshift);
  457. X   tmpview[2] = divide(lview[2],denom,bitshift);
  458. X
  459. X   lv[0] = multiply(lv[0], tmpview[2], bitshift) -
  460. X       multiply(tmpview[0], lv[2], bitshift);
  461. X
  462. X   lv[1] = multiply(lv[1], tmpview[2], bitshift) -
  463. X       multiply(tmpview[1], lv[2], bitshift);
  464. X
  465. X   /* z coordinate if needed           */
  466. X   /* lv[2] = divide(lview[2],denom);  */
  467. X   return(overflow);
  468. X}
  469. X
  470. Xint longvmult(LVECTOR s,LMATRIX m,LVECTOR t,int bitshift)
  471. X{
  472. X   LVECTOR tmp;
  473. X   int i,j, k;
  474. X   overflow = 0;
  475. X   k = CMAX-1;
  476. X
  477. X   for(j=0;j<k;j++)
  478. X   {
  479. X      tmp[j] = 0;
  480. X      for(i=0;i<RMAX-1;i++)
  481. X     tmp[j] += multiply(s[i],m[i][j],bitshift);
  482. X      /* vector is really four dimensional with last component always 1 */
  483. X      tmp[j] += m[3][j];
  484. X   }
  485. X
  486. X   /* set target = tmp. Necessary to use tmp in case source = target */
  487. X   /* faster than for loop, if less general */
  488. X   t[0] = tmp[0];
  489. X   t[1] = tmp[1];
  490. X   t[2] = tmp[2];
  491. X   return(overflow);
  492. X}
  493. SHAR_EOF
  494. $TOUCH -am 1028230093 3d.c &&
  495. chmod 0644 3d.c ||
  496. echo "restore of 3d.c failed"
  497. set `wc -c 3d.c`;Wc_c=$1
  498. if test "$Wc_c" != "10094"; then
  499.     echo original size 10094, current size $Wc_c
  500. fi
  501. # ============= calcfrac.c ==============
  502. echo "x - extracting calcfrac.c (Text)"
  503. sed 's/^X//' << 'SHAR_EOF' > calcfrac.c &&
  504. X/*
  505. XCALCFRAC.C contains the high level ("engine") code for calculating the
  506. Xfractal images (well, SOMEBODY had to do it!).
  507. XOriginal author Tim Wegner, but just about ALL the authors have contributed
  508. XSOME code to this routine at one time or another, or contributed to one of
  509. Xthe many massive restructurings.
  510. XThis module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  511. XThe following modules work very closely with CALCFRAC.C:
  512. X  FRACTALS.C    the fractal-specific code for escape-time fractals.
  513. X  FRACSUBR.C    assorted subroutines belonging mainly to calcfrac.
  514. X  CALCMAND.ASM    fast Mandelbrot/Julia integer implementation
  515. XAdditional fractal-specific modules are also invoked from CALCFRAC:
  516. X  LORENZ.C    engine level and fractal specific code for attractors.
  517. X  JB.C        julibrot logic
  518. X  PARSER.C    formula fractals
  519. X  and more
  520. X -------------------------------------------------------------------- */
  521. X
  522. X#include <stdio.h>
  523. X#include <string.h>
  524. X#include <stdlib.h>
  525. X#include <float.h>
  526. X#include <limits.h>
  527. X#ifndef XFRACT
  528. X#include <dos.h>
  529. X#endif
  530. X#include <limits.h>
  531. X#include "fractint.h"
  532. X#include "fractype.h"
  533. X#include "mpmath.h"
  534. X#include "targa_lc.h"
  535. X#include "prototyp.h"
  536. X
  537. X/* routines in this module    */
  538. X
  539. Xstatic void perform_worklist(void);
  540. Xstatic int  OneOrTwoPass(void);
  541. Xstatic int  _fastcall StandardCalc(int);
  542. Xstatic int  _fastcall potential(double,int);
  543. Xstatic void decomposition(void);
  544. Xstatic int  bound_trace_main(void);
  545. Xstatic void step_col_row(void);
  546. Xstatic int  _fastcall boundary_trace(int,int);
  547. Xstatic int  _fastcall calc_xy(int,int);
  548. Xstatic int  _fastcall fillseg1(int,int,int,int);
  549. Xstatic int  _fastcall fillseg(int,int,int,int);
  550. Xstatic void _fastcall reverse_string(BYTE *,BYTE *,int);
  551. Xstatic int  solidguess(void);
  552. Xstatic int  _fastcall guessrow(int,int,int);
  553. Xstatic void _fastcall plotblock(int,int,int,int);
  554. Xstatic void _fastcall setsymmetry(int,int);
  555. Xstatic int  _fastcall xsym_split(int,int);
  556. Xstatic int  _fastcall ysym_split(int,int);
  557. Xstatic void set_Plasma_palette(void);
  558. Xstatic U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb);
  559. Xstatic void _fastcall subDivide(int x1,int y1,int x2,int y2);
  560. Xstatic int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur);
  561. Xstatic void verhulst(void);
  562. Xstatic void Bif_Period_Init(void);
  563. Xstatic int  _fastcall Bif_Periodic(int);
  564. Xstatic void set_Cellular_palette(void);
  565. X
  566. X/**CJLT new function prototypes: */
  567. Xstatic int tesseral(void);
  568. Xstatic int _fastcall tesschkcol(int,int,int);
  569. Xstatic int _fastcall tesschkrow(int,int,int);
  570. Xstatic int _fastcall tesscol(int,int,int);
  571. Xstatic int _fastcall tessrow(int,int,int);
  572. X/* added for testing autologmap() */
  573. Xstatic int autologmap(void);
  574. X
  575. Xextern _CMPLX initorbit;
  576. Xextern char useinitorbit;
  577. X_LCMPLX linitorbit;
  578. Xextern int showdot;
  579. Xextern unsigned int decoderline[];
  580. Xextern int overflow;
  581. Xlong lmagnitud, llimit, llimit2, lclosenuff, l16triglim;
  582. X_CMPLX init,tmp,old,new,saved;
  583. Xextern int biomorph,usr_biomorph;
  584. Xextern _LCMPLX linit;
  585. Xextern int basin;
  586. Xextern int cpu;
  587. Xextern char savename[80];   /* save files using this name */
  588. Xextern int resave_flag;
  589. Xextern int started_resaves;
  590. Xextern int dotmode;
  591. Xextern int save_release;    /* use this to maintain compatibility */
  592. X
  593. Xint color, oldcolor, row, col, passes;
  594. Xint realcolor;
  595. Xint iterations, invert;
  596. Xdouble f_radius,f_xcenter, f_ycenter; /* for inversion */
  597. Xextern double far *dx0, far *dy0;
  598. Xextern double far *dx1, far *dy1;
  599. X
  600. Xextern int LogFlag;
  601. Xextern BYTE far *LogTable;
  602. Xextern int rangeslen;
  603. Xextern int far *ranges;
  604. X
  605. Xvoid (_fastcall *plot)(int,int,int) = putcolor;
  606. Xtypedef void (_fastcall *PLOT)(int,int,int);
  607. X
  608. Xextern double inversion[];        /* inversion radius, f_xcenter, f_ycenter */
  609. Xextern int    xdots, ydots;        /* coordinates of dots on the screen  */
  610. Xextern int    sxdots,sydots;
  611. Xextern int    sxoffs,syoffs;
  612. Xextern int    colors;         /* maximum colors available */
  613. Xextern int    andcolor;        /* colors-1         */
  614. Xextern int    inside;         /* "inside" color to use    */
  615. Xextern int    fillcolor;         /* "fillcolor" color to use    */
  616. Xextern int    outside;        /* "outside" color to use   */
  617. Xextern int    finattract;
  618. Xdouble        min_orbit;        /* orbit value closest to origin */
  619. Xint        min_index;        /* iteration of min_orbit */
  620. Xextern int    maxit;            /* try this many iterations */
  621. Xextern int    fractype;        /* fractal type */
  622. Xextern char    stdcalcmode;        /* '1', '2', 'g', 'b' */
  623. Xextern int    debugflag;        /* for debugging purposes */
  624. Xextern    int    diskvideo;        /* for disk-video klooges */
  625. Xextern int    calc_status;        /* status of calculations */
  626. Xextern long    calctime;        /* total calc time for image */
  627. X
  628. Xextern int rflag, rseed;
  629. Xextern int decomp[];
  630. Xextern int distest,distestwidth;
  631. X
  632. Xextern double    param[];        /* parameters */
  633. Xextern int    potflag;        /* potential enabled? */
  634. Xextern double    potparam[];        /* potential parameters */
  635. Xextern int    pot16bit;        /* store 16bit continuous potential */
  636. Xextern long    far *lx0, far *ly0; /* X, Y points */
  637. Xextern long    far *lx1, far *ly1; /* X, Y points */
  638. Xextern long    fudge;            /* fudge factor (2**n) */
  639. Xextern int    bitshift;        /* bit shift for fudge */
  640. Xextern long    delmin;         /* for periodicity checking */
  641. X
  642. Xextern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* corners */
  643. Xextern long   xmin, xmax, ymin, ymax;           /* integer equivs */
  644. Xextern long   delx,dely;               /* X, Y increments */
  645. Xextern double delxx,delxx2,delyy,delyy2;
  646. Xdouble deltaX, deltaY;
  647. Xdouble magnitude, rqlim, rqlim2, rqlim_save;
  648. Xextern _CMPLX parm,parm2;
  649. Xint (*calctype)();
  650. Xdouble closenuff;
  651. Xint pixelpi; /* value of pi in pixels */
  652. Xunsigned long lm;        /* magnitude limit (CALCMAND) */
  653. Xextern long linitx,linity;    /* in calcmand */
  654. Xextern unsigned long savedmask; /* in calcmand */
  655. Xextern int TranspSymmetry;
  656. X
  657. X/* ORBIT variables */
  658. Xint    show_orbit;            /* flag to turn on and off */
  659. Xint    orbit_ptr;            /* pointer into save_orbit array */
  660. Xint far *save_orbit;            /* array to save orbit values */
  661. Xint    orbit_color=15;         /* XOR color */
  662. X
  663. Xint    ixstart, ixstop, iystart, iystop;    /* start, stop here */
  664. Xint    symmetry;       /* symmetry flag */
  665. Xint    reset_periodicity; /* nonzero if escape time pixel rtn to reset */
  666. Xint    kbdcount, max_kbdcount;    /* avoids checking keyboard too often */
  667. X
  668. Xextern    int    integerfractal;     /* TRUE if fractal uses integer math */
  669. X
  670. Xchar far *resume_info = NULL;        /* pointer to resume info if allocated */
  671. Xint resuming;                /* nonzero if resuming after interrupt */
  672. Xint num_worklist;            /* resume worklist for standard engine */
  673. Xstruct workliststuff worklist[MAXCALCWORK];
  674. Xint xxstart,xxstop;            /* these are same as worklist, */
  675. Xint yystart,yystop,yybegin;        /* declared as separate items  */
  676. Xint workpass,worksym;            /* for the sake of calcmand    */
  677. X
  678. Xextern long timer_interval;        /* timer(...) total */
  679. X
  680. XVOIDFARPTR typespecific_workarea = NULL;
  681. X
  682. Xstatic double dem_delta, dem_width;    /* distance estimator variables */
  683. Xstatic double dem_toobig;
  684. X#define DEM_BAILOUT 535.5  /* (pb: not sure if this is special or arbitrary) */
  685. X
  686. X/* variables which must be visible for tab_display */
  687. Xint got_status; /* -1 if not, 0 for 1or2pass, 1 for ssg, 2 for btm, 3 for 3d */
  688. Xint curpass,totpasses;
  689. Xint currow,curcol;
  690. X
  691. X/* static vars for solidguess & its subroutines */
  692. Xstatic int maxblock,halfblock;
  693. Xstatic int guessplot;            /* paint 1st pass row at a time?   */
  694. Xstatic int right_guess,bottom_guess;
  695. X#define maxyblk 7    /* maxxblk*maxyblk*2 <= 4096, the size of "prefix" */
  696. X#define maxxblk 202  /* each maxnblk is oversize by 2 for a "border" */
  697. X             /* maxxblk defn must match fracsubr.c */
  698. X/* next has a skip bit for each maxblock unit;
  699. X   1st pass sets bit  [1]... off only if block's contents guessed;
  700. X   at end of 1st pass [0]... bits are set if any surrounding block not guessed;
  701. X   bits are numbered [..][y/16+1][x+1]&(1<<(y&15)) */
  702. Xextern unsigned int prefix[2][maxyblk][maxxblk]; /* common temp */
  703. X/* size of next puts a limit of MAXPIXELS pixels across on solid guessing logic */
  704. X#ifndef XFRACT
  705. Xextern char dstack[4096];               /* common temp, two put_line calls */
  706. Xextern char suffix[4096];             /* cellular, put_line/get_line calls */
  707. Xextern unsigned int prefix[2][maxyblk][maxxblk]; /* common temp */
  708. X#else
  709. XBYTE dstack[4096];              /* common temp, two put_line calls */
  710. Xunsigned int prefix[2][maxyblk][maxxblk]; /* common temp */
  711. X#endif
  712. X
  713. Xint nxtscreenflag; /* for cellular next screen generation */
  714. Xint    attractors;            /* number of finite attractors  */
  715. X_CMPLX    attr[N_ATTR];        /* finite attractor vals (f.p)  */
  716. X_LCMPLX lattr[N_ATTR];        /* finite attractor vals (int)  */
  717. Xint    attrperiod[N_ATTR];        /* period of the finite attractor */
  718. X
  719. X/***** vars for new btm *****/
  720. Xenum direction {North,East,South,West};
  721. Xenum direction going_to;
  722. Xint trail_row, trail_col;
  723. X
  724. X#ifndef sqr
  725. X#define sqr(x) ((x)*(x))
  726. X#endif
  727. X
  728. X#ifndef lsqr
  729. X#define lsqr(x) (multiply((x),(x),bitshift))
  730. X#endif
  731. X
  732. X/* -------------------------------------------------------------------- */
  733. X/*        These variables are external for speed's sake only      */
  734. X/* -------------------------------------------------------------------- */
  735. Xextern _LCMPLX lold,lnew,lparm,lparm2;     /* added "lold" */
  736. X
  737. Xint periodicitycheck;
  738. Xextern long ltempsqrx,ltempsqry;
  739. Xextern double tempsqrx,tempsqry;
  740. Xextern _LCMPLX ltmp;
  741. Xextern int display3d;
  742. X
  743. X
  744. Xvoid calcfrac_overlay() { }    /* for restore_active_ovly */
  745. Xextern int first_err;   /* flag for math errors */
  746. X
  747. X/******* calcfract - the top level routine for generating an image *******/
  748. X
  749. Xint calcfract()
  750. X{
  751. X   ENTER_OVLY(OVLY_CALCFRAC);
  752. X
  753. X   first_err = 1;
  754. X   attractors = 0;        /* default to no known finite attractors  */
  755. X   display3d = 0;
  756. X   basin = 0;
  757. X
  758. X   init_misc();  /* set up some variables in parser.c */
  759. X
  760. X   /* following delta values useful only for types with rotation disabled */
  761. X   /* currently used only by bifurcation */
  762. X   if (integerfractal)
  763. X   {
  764. X      distest = 0;
  765. X      deltaX = (double)lx0[     1] / fudge - xxmin;
  766. X      deltaY = yymax - (double)ly0[     1] / fudge;
  767. X   }
  768. X   else
  769. X   {
  770. X      deltaX = dx0[     1] - xxmin;
  771. X      deltaY = yymax - dy0[     1];
  772. X   }
  773. X
  774. X   parm.x   = param[0];
  775. X   parm.y   = param[1];
  776. X   parm2.x  = param[2];
  777. X   parm2.y  = param[3];
  778. X
  779. X   if (LogFlag && colors < 16) {
  780. X      static char far msg[]={"Need at least 16 colors to use logmap"};
  781. X      stopmsg(0,msg);
  782. X      LogFlag = 0;
  783. X      }
  784. X   if (LogFlag || rangeslen)
  785. X      if (!(LogTable = farmemalloc((long)maxit + 1))) {
  786. X      static char far msg[]={"Insufficient memory for logmap/ranges with this maxiter"};
  787. X      stopmsg(0,msg);
  788. X      }
  789. X      else if (rangeslen) {
  790. X     int i,k,l,m,numval,flip,altern;
  791. X     i = k = l = 0;
  792. X     while (i < rangeslen) {
  793. X        m = flip = 0;
  794. X        altern = 32767;
  795. X        if ((numval = ranges[i++]) < 0) {
  796. X           altern = ranges[i++];    /* sub-range iterations */
  797. X           numval = ranges[i++];
  798. X           }
  799. X        if (numval > maxit || i >= rangeslen)
  800. X           numval = maxit;
  801. X        while (l <= numval)  {
  802. X           LogTable[l++] = k + flip;
  803. X           if (++m >= altern) {
  804. X          flip ^= 1;        /* Alternate colors */
  805. X          m = 0;
  806. X          }
  807. X           }
  808. X        ++k;
  809. X        if (altern != 32767) ++k;
  810. X        }
  811. X     }
  812. X      else
  813. X     SetupLogTable();
  814. X
  815. X   lm = 4L << bitshift;         /* CALCMAND magnitude limit */
  816. X
  817. X   /* ORBIT stuff */
  818. X   save_orbit = (int far *)((double huge *)dx0 + 4*MAXPIXELS);
  819. X   show_orbit = 0;
  820. X   orbit_ptr = 0;
  821. X   orbit_color = 15;
  822. X   if(colors < 16)
  823. X      orbit_color = 1;
  824. X
  825. X   if(inversion[0] != 0.0)
  826. X   {
  827. X      f_radius      = inversion[0];
  828. X      f_xcenter   = inversion[1];
  829. X      f_ycenter   = inversion[2];
  830. X
  831. X      if (inversion[0] == AUTOINVERT)  /*  auto calc radius 1/6 screen */
  832. X     inversion[0] = f_radius = min(fabs(xxmax - xxmin),
  833. X         fabs(yymax - yymin)) / 6.0;
  834. X
  835. X      if (invert < 2 || inversion[1] == AUTOINVERT)  /* xcenter not already set */
  836. X      {
  837. X     inversion[1] = f_xcenter = (xxmin + xxmax) / 2.0;
  838. X     if (fabs(f_xcenter) < fabs(xxmax-xxmin) / 100)
  839. X        inversion[1] = f_xcenter = 0.0;
  840. X      }
  841. X
  842. X      if (invert < 3 || inversion[2] == AUTOINVERT)  /* ycenter not already set */
  843. X      {
  844. X     inversion[2] = f_ycenter = (yymin + yymax) / 2.0;
  845. X     if (fabs(f_ycenter) < fabs(yymax-yymin) / 100)
  846. X        inversion[2] = f_ycenter = 0.0;
  847. X      }
  848. X
  849. X      invert = 3; /* so values will not be changed if we come back */
  850. X   }
  851. X
  852. X   closenuff = delmin >> abs(periodicitycheck); /* for periodicity checking */
  853. X   closenuff /= fudge;
  854. X   rqlim_save = rqlim;
  855. X   rqlim2 = sqrt(rqlim);
  856. X   if (integerfractal)        /* for integer routines (lambda) */
  857. X   {
  858. X      lparm.x = parm.x * fudge;    /* real portion of Lambda */
  859. X      lparm.y = parm.y * fudge;    /* imaginary portion of Lambda */
  860. X      lparm2.x = parm2.x * fudge;  /* real portion of Lambda2 */
  861. X      lparm2.y = parm2.y * fudge;  /* imaginary portion of Lambda2 */
  862. X      llimit = rqlim * fudge;       /* stop if magnitude exceeds this */
  863. X      if (llimit <= 0) llimit = 0x7fffffff; /* klooge for integer math */
  864. X      llimit2 = rqlim2 * fudge;    /* stop if magnitude exceeds this */
  865. X      lclosenuff = closenuff * fudge;    /* "close enough" value */
  866. X      l16triglim = 8L<<16;       /* domain limit of fast trig functions */
  867. X      linitorbit.x = initorbit.x * fudge;
  868. X      linitorbit.y = initorbit.y * fudge;
  869. X   }
  870. X   resuming = (calc_status == 2);
  871. X   if (!resuming) /* free resume_info memory if any is hanging around */
  872. X   {
  873. X      end_resume();
  874. X      if (resave_flag) {
  875. X     updatesavename(savename); /* do the pending increment */
  876. X     resave_flag = started_resaves = 0;
  877. X     }
  878. X      calctime = 0;
  879. X   }
  880. X
  881. X   if (curfractalspecific->calctype != StandardFractal
  882. X       && curfractalspecific->calctype != calcmand
  883. X       && curfractalspecific->calctype != calcmandfp
  884. X       && curfractalspecific->calctype != lyapunov
  885. X       && curfractalspecific->calctype != calcfroth)
  886. X   {
  887. X      calctype = curfractalspecific->calctype; /* per_image can override */
  888. X      symmetry = curfractalspecific->symmetry; /*   calctype & symmetry  */
  889. X      plot = putcolor; /* defaults when setsymmetry not called or does nothing */
  890. X      iystart = ixstart = yystart = xxstart = yybegin = 0;
  891. X      iystop = yystop = ydots -1;
  892. X      ixstop = xxstop = xdots -1;
  893. X      calc_status = 1; /* mark as in-progress */
  894. X      distest = 0; /* only standard escape time engine supports distest */
  895. X      /* per_image routine is run here */
  896. X      if (curfractalspecific->per_image())
  897. X      { /* not a stand-alone */
  898. X     /* next two lines in case periodicity changed */
  899. X     closenuff = delmin >> abs(periodicitycheck); /* for periodicity checking */
  900. X     closenuff /= fudge;
  901. X     lclosenuff = closenuff * fudge;    /* "close enough" value */
  902. X     setsymmetry(symmetry,0);
  903. X     timer(0,calctype); /* non-standard fractal engine */
  904. X      }
  905. X      if (check_key())
  906. X      {
  907. X     if (calc_status == 1) /* calctype didn't set this itself, */
  908. X        calc_status = 3;   /* so mark it interrupted, non-resumable */
  909. X      }
  910. X      else
  911. X     calc_status = 4; /* no key, so assume it completed */
  912. X   }
  913. X   else /* standard escape-time engine */
  914. X      timer(0,(int (*)())perform_worklist);
  915. X   calctime += timer_interval;
  916. X
  917. X   if(LogTable)
  918. X   {
  919. X      farmemfree(LogTable);
  920. X      LogTable = NULL;
  921. X   }
  922. X   if(typespecific_workarea)
  923. X   {
  924. X      free_workarea();
  925. X   }
  926. X
  927. X   EXIT_OVLY;
  928. X   return((calc_status == 4) ? 0 : -1);
  929. X}
  930. X
  931. X/**************** general escape-time engine routines *********************/
  932. X
  933. Xstatic void perform_worklist()
  934. X{
  935. X   int i;
  936. X   long tmplong; /* this temp must be signed */
  937. X
  938. X   if (potflag && pot16bit)
  939. X   {
  940. X      int tmpcalcmode = stdcalcmode;
  941. X
  942. X      stdcalcmode = '1'; /* force 1 pass */
  943. X      if (resuming == 0)
  944. X     if (pot_startdisk() < 0)
  945. X     {
  946. X        pot16bit = 0;    /* startdisk failed or cancelled */
  947. X        stdcalcmode = tmpcalcmode;    /* maybe we can carry on??? */
  948. X     }
  949. X   }
  950. X   if (stdcalcmode == 'b' && (curfractalspecific->flags & NOTRACE))
  951. X      stdcalcmode = '1';
  952. X   if (stdcalcmode == 'g' && (curfractalspecific->flags & NOGUESS))
  953. X      stdcalcmode = '1';
  954. X
  955. X   /* default setup a new worklist */
  956. X   num_worklist = 1;
  957. X   worklist[0].xxstart = 0;
  958. X   worklist[0].yystart = worklist[0].yybegin = 0;
  959. X   worklist[0].xxstop = xdots - 1;
  960. X   worklist[0].yystop = ydots - 1;
  961. X   worklist[0].pass = worklist[0].sym = 0;
  962. X   if (resuming) /* restore worklist, if we can't the above will stay in place */
  963. X   {
  964. X      start_resume();
  965. X      get_resume(sizeof(int),&num_worklist,sizeof(worklist),worklist,0);
  966. X      end_resume();
  967. X   }
  968. X
  969. X   if (distest) /* setup stuff for distance estimator */
  970. X   {
  971. X      double ftemp,ftemp2;
  972. X      dem_delta = sqr(delxx) + sqr(delyy2);
  973. X      if ((ftemp = sqr(delyy) + sqr(delxx2)) > dem_delta)
  974. X     dem_delta = ftemp;
  975. X      if (distestwidth == 0)
  976. X     distestwidth = 71;
  977. X      ftemp = distestwidth;
  978. X      dem_delta *= sqr(ftemp)/10000; /* multiply by thickness desired */
  979. X      dem_width = ( sqrt( sqr(xxmax-xxmin) + sqr(xx3rd-xxmin) ) * ydots/xdots
  980. X      + sqrt( sqr(yymax-yymin) + sqr(yy3rd-yymin) ) ) / distest;
  981. X      ftemp = (rqlim < DEM_BAILOUT) ? DEM_BAILOUT : rqlim;
  982. X      ftemp += 3; /* bailout plus just a bit */
  983. X      ftemp2 = log(ftemp);
  984. X      dem_toobig = sqr(ftemp) * sqr(ftemp2) * 4 / dem_delta;
  985. X   }
  986. X
  987. X   while (num_worklist > 0)
  988. X   {
  989. X      calctype = curfractalspecific->calctype; /* per_image can override */
  990. X      symmetry = curfractalspecific->symmetry; /*   calctype & symmetry  */
  991. X      plot = putcolor; /* defaults when setsymmetry not called or does nothing */
  992. X
  993. X      /* pull top entry off worklist */
  994. X      ixstart = xxstart = worklist[0].xxstart;
  995. X      ixstop  = xxstop    = worklist[0].xxstop;
  996. X      iystart = yystart = worklist[0].yystart;
  997. X      iystop  = yystop    = worklist[0].yystop;
  998. X      yybegin  = worklist[0].yybegin;
  999. X      workpass = worklist[0].pass;
  1000. X      worksym  = worklist[0].sym;
  1001. X      --num_worklist;
  1002. X      for (i=0; i<num_worklist; ++i)
  1003. X     worklist[i] = worklist[i+1];
  1004. X
  1005. X      calc_status = 1; /* mark as in-progress */
  1006. X
  1007. X      curfractalspecific->per_image();
  1008. X
  1009. X      /* some common initialization for escape-time pixel level routines */
  1010. X      closenuff = delmin >> abs(periodicitycheck); /* for periodicity checking */
  1011. X      closenuff /= fudge;
  1012. X      lclosenuff = closenuff * fudge;    /* "close enough" value */
  1013. X      kbdcount=max_kbdcount;
  1014. X      /* savedmask is for calcmand's periodicity checking */
  1015. X      savedmask = 0xC0000000; /* top 2 bits on */
  1016. X      tmplong = (delmin >> abs(periodicitycheck)) | 1;
  1017. X      while (tmplong > 0) /* while top bit not on */
  1018. X      {
  1019. X     tmplong <<= 1;
  1020. X     savedmask = (savedmask >> 1) | 0x80000000;
  1021. X      }
  1022. X
  1023. X      setsymmetry(symmetry,1);
  1024. X
  1025. X/* added for testing autologmap() */
  1026. X      if (!(resuming)&&(abs(LogFlag) ==2))
  1027. X       {  /* calculate round screen edges to work out best start for logmap */
  1028. X         LogFlag = ( autologmap() * (LogFlag / abs(LogFlag)));
  1029. X         SetupLogTable();
  1030. X       }
  1031. X
  1032. X      /* call the appropriate escape-time engine */
  1033. X      switch (stdcalcmode)
  1034. X      {
  1035. X      case 't':
  1036. X     tesseral();
  1037. X     break;
  1038. X      case 'b':
  1039. X     bound_trace_main();
  1040. X     break;
  1041. X      case 'g':
  1042. X     solidguess();
  1043. X     break;
  1044. X      default:
  1045. X     OneOrTwoPass();
  1046. X      }
  1047. X
  1048. X      if (check_key()) /* interrupted? */
  1049. X     break;
  1050. X   }
  1051. X
  1052. X   if (num_worklist > 0)
  1053. X   {  /* interrupted, resumable */
  1054. X      alloc_resume(sizeof(worklist)+10,1);
  1055. X      put_resume(sizeof(int),&num_worklist,sizeof(worklist),worklist,0);
  1056. X   }
  1057. X   else
  1058. X      calc_status = 4; /* completed */
  1059. X}
  1060. X
  1061. Xstatic int OneOrTwoPass()
  1062. X{
  1063. X   int i;
  1064. X   totpasses = 1;
  1065. X   if (stdcalcmode == '2') totpasses = 2;
  1066. X   if (stdcalcmode == '2' && workpass == 0) /* do 1st pass of two */
  1067. X   {
  1068. X      if (StandardCalc(1) == -1)
  1069. X      {
  1070. X     add_worklist(xxstart,xxstop,yystart,yystop,row,0,worksym);
  1071. X     return(-1);
  1072. X      }
  1073. X      if (num_worklist > 0) /* worklist not empty, defer 2nd pass */
  1074. X      {
  1075. X     add_worklist(xxstart,xxstop,yystart,yystop,yystart,1,worksym);
  1076. X     return(0);
  1077. X      }
  1078. X      workpass = 1;
  1079. X      yybegin = yystart;
  1080. X   }
  1081. X   /* second or only pass */
  1082. X   if (StandardCalc(2) == -1)
  1083. X   {
  1084. X      i = yystop;
  1085. X      if (iystop != yystop) /* must be due to symmetry */
  1086. X     i -= row - iystart;
  1087. X      add_worklist(xxstart,xxstop,row,i,row,workpass,worksym);
  1088. X      return(-1);
  1089. X   }
  1090. X   return(0);
  1091. X}
  1092. X
  1093. Xstatic int _fastcall StandardCalc(int passnum)
  1094. X{
  1095. X   got_status = 0;
  1096. X   curpass = passnum;
  1097. X   row = yybegin;
  1098. X   while (row <= iystop)
  1099. X   {
  1100. X      currow = row;
  1101. X      reset_periodicity = 1;
  1102. X      col = ixstart;
  1103. X      while (col <= ixstop)
  1104. X      {
  1105. X         if(showdot>0)
  1106. X            (*plot) (col, row, showdot&(colors-1));
  1107. X
  1108. X     /* on 2nd pass of two, skip even pts */
  1109. X     if (passnum == 1 || stdcalcmode == '1' || (row&1) != 0 || (col&1) != 0)
  1110. X     {
  1111. X        if ((*calctype)() == -1) /* StandardFractal(), calcmand() or calcmandfp() */
  1112. X           return(-1); /* interrupted */
  1113. X        reset_periodicity = 0;
  1114. X        if (passnum == 1) /* first pass, copy pixel and bump col */
  1115. X        {
  1116. X           if ((row&1) == 0 && row < iystop)
  1117. X           {
  1118. X          (*plot)(col,row+1,color);
  1119. X          if ((col&1) == 0 && col < ixstop)
  1120. X             (*plot)(col+1,row+1,color);
  1121. X           }
  1122. X           if ((col&1) == 0 && col < ixstop)
  1123. X          (*plot)(++col,row,color);
  1124. X        }
  1125. X     }
  1126. X     ++col;
  1127. X      }
  1128. X      if (passnum == 1 && (row&1) == 0)
  1129. X     ++row;
  1130. X      ++row;
  1131. X   }
  1132. X   return(0);
  1133. X}
  1134. X
  1135. Xint calcmand()        /* fast per pixel 1/2/b/g, called with row & col set */
  1136. X{
  1137. X   /* setup values from far array to avoid using es reg in calcmand.asm */
  1138. X   linitx = lx0[col] + lx1[row];
  1139. X   linity = ly0[row] + ly1[col];
  1140. X   if (calcmandasm() >= 0)
  1141. X   {
  1142. X      if (LogTable /* map color, but not if maxit & adjusted for inside,etc */
  1143. X      && (realcolor < maxit || (inside < 0 && color == maxit)))
  1144. X     color = LogTable[min(color, maxit)];
  1145. X      if (color >= colors) /* don't use color 0 unless from inside/outside */
  1146. X     if (colors < 16)
  1147. X        color &= andcolor;
  1148. X     else
  1149. X        color = ((color - 1) % andcolor) + 1;  /* skip color zero */
  1150. X      if(debugflag != 470)
  1151. X         if(color <= 0 && stdcalcmode == 'b' )   /* fix BTM bug */
  1152. X            color = 1;
  1153. X      (*plot) (col, row, color);
  1154. X   }
  1155. X   return (color);
  1156. X}
  1157. X
  1158. X/************************************************************************/
  1159. X/* added by Wes Loewer - sort of a floating point version of calcmand() */
  1160. X/* can also handle invert, any rqlim, potflag, zmag, epsilon cross,     */
  1161. X/* and all the current outside options    -Wes Loewer 11/03/91          */
  1162. X/************************************************************************/
  1163. Xint calcmandfp()
  1164. X{
  1165. X   if(invert)
  1166. X      invertz2(&init);
  1167. X   else
  1168. X   {
  1169. X      init.y = dy0[row]+dy1[col];
  1170. X      init.x = dx0[col]+dx1[row];
  1171. X   }
  1172. X   if (calcmandfpasm() >= 0)
  1173. X   {
  1174. X      if (potflag)
  1175. X     color = potential(magnitude, realcolor);
  1176. X      if (LogTable /* map color, but not if maxit & adjusted for inside,etc */
  1177. X          && (realcolor < maxit || (inside < 0 && color == maxit)))
  1178. X        color = LogTable[min(color, maxit)];
  1179. X     if (color >= colors) /* don't use color 0 unless from inside/outside */
  1180. X        if (colors < 16)
  1181. X           color &= andcolor;
  1182. X        else
  1183. X           color = ((color - 1) % andcolor) + 1;  /* skip color zero */
  1184. X         if(debugflag != 470)
  1185. X            if(color == 0 && stdcalcmode == 'b' )   /* fix BTM bug */
  1186. X               color = 1;
  1187. X      (*plot) (col, row, color);
  1188. X   }
  1189. X   return (color);
  1190. X}
  1191. X
  1192. X#define green 2
  1193. X#define yellow 6
  1194. Xint StandardFractal()    /* per pixel 1/2/b/g, called with row & col set */
  1195. X{
  1196. X   double tantable[16];
  1197. X   int hooper;
  1198. X   double close;
  1199. X   long lclose;
  1200. X   int cyclelen = -1;
  1201. X   int savedcolor;
  1202. X   int caught_a_cycle;
  1203. X   int savedand, savedincr;    /* for periodicity checking */
  1204. X   _LCMPLX lsaved;
  1205. X   int i, attracted;
  1206. X   _LCMPLX lat;
  1207. X   _CMPLX  at;
  1208. X   _CMPLX deriv;
  1209. X   int dem_color;
  1210. X   _CMPLX dem_new;
  1211. X   close = .01;
  1212. X   lclose = close*fudge;
  1213. X
  1214. X   if(inside == STARTRAIL)
  1215. X   {
  1216. X      int i;
  1217. X      for(i=0;i<16;i++)
  1218. X     tantable[i] = 0.0;
  1219. X   }
  1220. X   else if(inside == EPSCROSS)
  1221. X   {
  1222. X      close = .01;
  1223. X      lclose = close*fudge;
  1224. X   }
  1225. X   if (periodicitycheck == 0 || inside == ZMAG || inside == STARTRAIL)
  1226. X      oldcolor = 32767;     /* don't check periodicity at all */
  1227. X   else if (inside == PERIOD)    /* for display-periodicity */
  1228. X      oldcolor = maxit*4/5;    /* don't check until nearly done */
  1229. X   else if (reset_periodicity)
  1230. X      oldcolor = 250;        /* don't check periodicity 1st 250 iterations */
  1231. X
  1232. X   /* really fractal specific, but we'll leave it here */
  1233. X   if (!integerfractal)
  1234. X   {
  1235. X      if (useinitorbit == 1)
  1236. X     saved = initorbit;
  1237. X      else {
  1238. X     saved.x = 0;
  1239. X     saved.y = 0;
  1240. X      }
  1241. X      init.y = dy0[row] + dy1[col];
  1242. X      if (distest)
  1243. X      {
  1244. X     rqlim = rqlim_save;          /* start with regular bailout */
  1245. X     if (distest != 1 || colors == 2) /* not doing regular outside colors */
  1246. X        if (rqlim < DEM_BAILOUT)      /* so go straight for dem bailout */
  1247. X           rqlim = DEM_BAILOUT;
  1248. X     deriv.x = 1;
  1249. X     deriv.y = 0;
  1250. X     magnitude = 0;
  1251. X     dem_color = -1;
  1252. X      }
  1253. X   }
  1254. X   else
  1255. X   {
  1256. X      if (useinitorbit == 1)
  1257. X     lsaved = linitorbit;
  1258. X      else {
  1259. X     lsaved.x = 0;
  1260. X     lsaved.y = 0;
  1261. X      }
  1262. X      linit.y = ly0[row] + ly1[col];
  1263. X   }
  1264. X   orbit_ptr = 0;
  1265. X   color = 0;
  1266. X   if(fractype==JULIAFP || fractype==JULIA)
  1267. X      color = -1;
  1268. X   caught_a_cycle = 0;
  1269. X   if (inside == PERIOD) {
  1270. X       savedand = 16;        /* begin checking every 16th cycle */
  1271. X   } else {
  1272. X       savedand = 1;        /* begin checking every other cycle */
  1273. X   }
  1274. X   savedincr = 1;        /* start checking the very first time */
  1275. X
  1276. X   if (inside <= BOF60 && inside >= BOF61)
  1277. X   {
  1278. X      magnitude = lmagnitud = 0;
  1279. X      min_orbit = 100000.0;
  1280. X   }
  1281. X   overflow = 0;        /* reset integer math overflow flag */
  1282. X
  1283. X   curfractalspecific->per_pixel(); /* initialize the calculations */
  1284. X
  1285. X   attracted = FALSE;
  1286. X   while (++color < maxit)
  1287. X   {
  1288. X      if(showdot>0)
  1289. X         (*plot) (col, row, showdot&(colors-1));
  1290. X
  1291. X      /* calculation of one orbit goes here */
  1292. X      /* input in "old" -- output in "new" */
  1293. X
  1294. X      if (distest)
  1295. X      {
  1296. X     double ftemp;
  1297. X     /* Distance estimator for points near Mandelbrot set */
  1298. X     /* Original code by Phil Wilson, hacked around by PB */
  1299. X     /* Algorithms from Peitgen & Saupe, Science of Fractal Images, p.198 */
  1300. X     ftemp     = 2 * (old.x * deriv.x - old.y * deriv.y) + 1;
  1301. X     deriv.y = 2 * (old.y * deriv.x + old.x * deriv.y);
  1302. X     deriv.x = ftemp;
  1303. X     if (sqr(deriv.x)+sqr(deriv.y) > dem_toobig)
  1304. X        break;
  1305. X     /* if above exit taken, the later test vs dem_delta will place this
  1306. X            point on the boundary, because mag(old)<bailout just now */
  1307. X     if (curfractalspecific->orbitcalc())
  1308. X     {
  1309. X        if (dem_color < 0)          /* note "regular" color for later */
  1310. X        {
  1311. X           dem_color = color;
  1312. X           dem_new = new;
  1313. X        }
  1314. X        if (rqlim >= DEM_BAILOUT  /* exit if past real bailout */
  1315. X        || magnitude >= (rqlim = DEM_BAILOUT) /* reset to real bailout */
  1316. X        || magnitude == 0)     /* exit if type doesn't "floatbailout" */
  1317. X           break;
  1318. X        old = new;              /* carry on till past real bailout */
  1319. X     }
  1320. X      }
  1321. X      else /* the usual case */
  1322. X     if (curfractalspecific->orbitcalc() && inside != STARTRAIL)
  1323. X        break;
  1324. X      if (show_orbit)
  1325. X     if (!integerfractal)
  1326. X        plot_orbit(new.x, new.y, -1);
  1327. X     else
  1328. X        iplot_orbit(lnew.x, lnew.y, -1);
  1329. X      if(inside == STARTRAIL)
  1330. X      {
  1331. X     if(0 < color && color < 16)
  1332. X     {
  1333. X     if (integerfractal)
  1334. X     {
  1335. X           new.x = lnew.x;
  1336. X           new.x /= fudge;
  1337. X           new.y = lnew.y;
  1338. X           new.y /= fudge;
  1339. X        }
  1340. X        tantable[color-1] = new.y/(new.x+.000001);
  1341. X     }
  1342. X      }
  1343. X      else if(inside == EPSCROSS)
  1344. X      {
  1345. X     hooper = 0;
  1346. X     if(integerfractal)
  1347. X     {
  1348. X        if(labs(lnew.x) < lclose)
  1349. X        {
  1350. X           hooper = 1; /* close to y axis */
  1351. X           goto plot_inside;
  1352. X        }
  1353. X        else if(labs(lnew.y) < lclose)
  1354. X        {
  1355. X           hooper = 2; /* close to x axis */
  1356. X           goto plot_inside;
  1357. X        }
  1358. X     }
  1359. X     else
  1360. X     {
  1361. X        if(fabs(new.x) < close)
  1362. X        {
  1363. X           hooper = 1; /* close to y axis */
  1364. X           goto plot_inside;
  1365. X        }
  1366. X        else if(fabs(new.y) < close)
  1367. X        {
  1368. X           hooper = 2; /* close to x axis */
  1369. X           goto plot_inside;
  1370. X        }
  1371. X     }
  1372. X      }
  1373. X      else if (inside <= BOF60 && inside >= BOF61)
  1374. X      {
  1375. X     if (integerfractal)
  1376. X     {
  1377. X        if (lmagnitud == 0)
  1378. X           lmagnitud = lsqr(lnew.x) + lsqr(lnew.y);
  1379. X        magnitude = lmagnitud;
  1380. X        magnitude = magnitude / fudge;
  1381. X     }
  1382. X     else
  1383. X        if (magnitude == 0.0)
  1384. X           magnitude = sqr(new.x) + sqr(new.y);
  1385. X     if (magnitude < min_orbit)
  1386. X     {
  1387. X        min_orbit = magnitude;
  1388. X        min_index = color + 1;
  1389. X     }
  1390. X      }
  1391. X
  1392. X
  1393. X      if (attractors > 0)    /* finite attractor in the list   */
  1394. X      {             /* NOTE: Integer code is UNTESTED */
  1395. X     if (integerfractal)
  1396. X     {
  1397. X        for (i = 0; i < attractors; i++)
  1398. X        {
  1399. X        lat.x = lnew.x - lattr[i].x;
  1400. X        lat.x = lsqr(lat.x);
  1401. X        if (lat.x < l_at_rad)
  1402. X        {
  1403. X           lat.y = lnew.y - lattr[i].y;
  1404. X           lat.y = lsqr(lat.y);
  1405. X           if (lat.y < l_at_rad)
  1406. X           {
  1407. X              if ((lat.x + lat.y) < l_at_rad)
  1408. X              {
  1409. X             attracted = TRUE;
  1410. X             if (finattract<0) color = (color%attrperiod[i])+1;
  1411. X             break;
  1412. X              }
  1413. X           }
  1414. X        }
  1415. X        }
  1416. X     }
  1417. X     else
  1418. X     {
  1419. X        for (i = 0; i < attractors; i++)
  1420. X        {
  1421. X        at.x = new.x - attr[i].x;
  1422. X        at.x = sqr(at.x);
  1423. X        if (at.x < f_at_rad)
  1424. X        {
  1425. X           at.y = new.y - attr[i].y;
  1426. X           at.y = sqr(at.y);
  1427. X           if ( at.y < f_at_rad)
  1428. X           {
  1429. X              if ((at.x + at.y) < f_at_rad)
  1430. X              {
  1431. X             attracted = TRUE;
  1432. X             if (finattract<0) color = (color%attrperiod[i])+1;
  1433. X             break;
  1434. X              }
  1435. X           }
  1436. X        }
  1437. X        }
  1438. X     }
  1439. X     if (attracted)
  1440. X        break;        /* AHA! Eaten by an attractor */
  1441. X      }
  1442. X
  1443. X      if (color > oldcolor)    /* check periodicity */
  1444. X      {
  1445. X     if ((color & savedand) == 0)         /* time to save a new value */
  1446. X     {
  1447. X        savedcolor = color;
  1448. X        if (!integerfractal)
  1449. X           saved = new;  /* floating pt fractals */
  1450. X        else
  1451. X           lsaved = lnew;/* integer fractals */
  1452. X        if (--savedincr == 0)    /* time to lengthen the periodicity? */
  1453. X        {
  1454. X           savedand = (savedand << 1) + 1;         /* longer periodicity */
  1455. X           savedincr = 4;/* restart counter */
  1456. X        }
  1457. X     }
  1458. X     else             /* check against an old save */
  1459. X     {
  1460. X        if (!integerfractal)     /* floating-pt periodicity chk */
  1461. X        {
  1462. X           if (fabs(saved.x - new.x) < closenuff)
  1463. X          if (fabs(saved.y - new.y) < closenuff)
  1464. X          {
  1465. X             caught_a_cycle = 1;
  1466. X             cyclelen = color-savedcolor;
  1467. X             color = maxit - 1;
  1468. X          }
  1469. X        }
  1470. X        else         /* integer periodicity check */
  1471. X        {
  1472. X           if (labs(lsaved.x - lnew.x) < lclosenuff)
  1473. X          if (labs(lsaved.y - lnew.y) < lclosenuff)
  1474. X          {
  1475. X             caught_a_cycle = 1;
  1476. X             cyclelen = color-savedcolor;
  1477. X             color = maxit - 1;
  1478. X          }
  1479. X        }
  1480. X     }
  1481. X      }
  1482. X   }
  1483. X
  1484. X   if (show_orbit)
  1485. X      scrub_orbit();
  1486. X
  1487. X   realcolor = color;        /* save this before we start adjusting it */
  1488. X   if (color >= maxit)
  1489. X      oldcolor = 0;        /* check periodicity immediately next time */
  1490. X   else
  1491. X   {
  1492. X      oldcolor = color + 10;    /* check when past this + 10 next time */
  1493. X      if (color == 0)
  1494. X     color = 1;        /* needed to make same as calcmand */
  1495. X   }
  1496. X
  1497. X   if (potflag)
  1498. X   {
  1499. X      if (integerfractal)    /* adjust integer fractals */
  1500. X      {
  1501. X     new.x = ((double)lnew.x) / fudge;
  1502. X     new.y = ((double)lnew.y) / fudge;
  1503. X      }
  1504. X      magnitude = sqr(new.x) + sqr(new.y);
  1505. X      color = potential(magnitude, color);
  1506. X      if (LogTable)
  1507. X     color = LogTable[min(color, maxit)];
  1508. X      goto plot_pixel;        /* skip any other adjustments */
  1509. X   }
  1510. X
  1511. X   if (color >= maxit)        /* an "inside" point */
  1512. X      goto plot_inside;     /* distest, decomp, biomorph don't apply */
  1513. X
  1514. X
  1515. X   if (outside < -1)  /* these options by Richard Hughes modified by TW */
  1516. X   {
  1517. X      if (integerfractal)
  1518. X      {
  1519. X     new.x = ((double)lnew.x) / fudge;
  1520. X     new.y = ((double)lnew.y) / fudge;
  1521. X      }
  1522. X      /* Add 7 to overcome negative values on the MANDEL    */
  1523. X      if (outside == REAL)         /* "real" */
  1524. X     color += new.x + 7;
  1525. X      else if (outside == IMAG)         /* "imag" */
  1526. X     color += new.y + 7;
  1527. X      else if (outside == MULT  && new.y)  /* "mult" */
  1528. X      color *= (new.x/new.y);
  1529. X      else if (outside == SUM)         /* "sum" */
  1530. X      color += new.x + new.y;
  1531. X
  1532. X      /* eliminate negative colors & wrap arounds */
  1533. X      if (color < 0 || color > maxit)
  1534. X      color = 0;
  1535. X   }
  1536. X
  1537. X   if (distest)
  1538. X   {
  1539. X      double dist,temp;
  1540. X      dist = sqr(new.x) + sqr(new.y);
  1541. X      temp = log(dist);
  1542. X      dist = dist * sqr(temp) / ( sqr(deriv.x) + sqr(deriv.y) );
  1543. X      if (dist < dem_delta)    /* point is on the edge */
  1544. X      {
  1545. X     if (distest > 0)
  1546. X        goto plot_inside;    /* show it as an inside point */
  1547. X     color = 0 - distest;    /* show boundary as specified color */
  1548. X     goto plot_pixel;    /* no further adjustments apply */
  1549. X      }
  1550. X      if (colors == 2)
  1551. X      {
  1552. X     color = !inside;    /* the only useful distest 2 color use */
  1553. X     goto plot_pixel;    /* no further adjustments apply */
  1554. X      }
  1555. X      if (distest > 1)        /* pick color based on distance */
  1556. X      {
  1557. X     color = sqrt(dist / dem_width + 1);
  1558. X         color &= INT_MAX;     /* oops - color can be negative */
  1559. X     goto plot_pixel;    /* no further adjustments apply */
  1560. X      }
  1561. X      color = dem_color;    /* use pixel's "regular" color */
  1562. X      new = dem_new;
  1563. X   }
  1564. X
  1565. X   if (decomp[0] > 0)
  1566. X      decomposition();
  1567. X   else if (biomorph != -1)
  1568. X   {
  1569. X      if (integerfractal)
  1570. X      {
  1571. X     if (labs(lnew.x) < llimit2 || labs(lnew.y) < llimit2)
  1572. X        color = biomorph;
  1573. X      }
  1574. X      else
  1575. X     if (fabs(new.x) < rqlim2 || fabs(new.y) < rqlim2)
  1576. X        color = biomorph;
  1577. X   }
  1578. X
  1579. X   if (outside >= 0 && attracted == FALSE) /* merge escape-time stripes */
  1580. X      color = outside;
  1581. X   else if (LogTable)
  1582. X      color = LogTable[min(color, maxit)];
  1583. X   goto plot_pixel;
  1584. X
  1585. X   plot_inside: /* we're "inside" */
  1586. X   if (periodicitycheck < 0 && caught_a_cycle)
  1587. X      color = 7;           /* show periodicity */
  1588. X   else if (inside >= 0)
  1589. X      color = inside;           /* set to specified color, ignore logpal */
  1590. X   else
  1591. X   {
  1592. X      if(inside == STARTRAIL)
  1593. X      {
  1594. X     int i;
  1595. X     double diff;
  1596. X     color = 0;
  1597. X     for(i=1;i<16;i++)
  1598. X     {
  1599. X        diff = tantable[0] - tantable[i];
  1600. X        if(fabs(diff) < .05)
  1601. X        {
  1602. X           color = i;
  1603. X           break;
  1604. X        }
  1605. X     }
  1606. X      }
  1607. X      else if(inside== PERIOD) {
  1608. X      if (cyclelen>0) {
  1609. X          color = cyclelen;
  1610. X      } else {
  1611. X          color = maxit;
  1612. X      }
  1613. X      }
  1614. X      else if(inside == EPSCROSS)
  1615. X      {
  1616. X     if(hooper==1)
  1617. X        color = green;
  1618. X     else if(hooper==2)
  1619. X        color = yellow;
  1620. X     else
  1621. X        color = maxit;
  1622. X     if (show_orbit)
  1623. X        scrub_orbit();
  1624. X      }
  1625. X      else if (inside == BOF60)
  1626. X     color = sqrt(min_orbit) * 75;
  1627. X      else if (inside == BOF61)
  1628. X     color = min_index;
  1629. X      else if (inside == ZMAG)
  1630. X      {
  1631. X     if (integerfractal)
  1632. X     {
  1633. X        /*
  1634. X        new.x = ((double)lnew.x) / fudge;
  1635. X        new.y = ((double)lnew.y) / fudge;
  1636. X        */
  1637. X        color = (((double)lsqr(lnew.x))/fudge + ((double)lsqr(lnew.y))/fudge) * (maxit>>1) + 1;
  1638. X     }
  1639. X     else
  1640. X        color = (sqr(new.x) + sqr(new.y)) * (maxit>>1) + 1;
  1641. X      }
  1642. X      else /* inside == -1 */
  1643. X     color = maxit;
  1644. X      if (LogTable)
  1645. X     color = LogTable[min(color, maxit)];
  1646. X   }
  1647. X
  1648. X   plot_pixel:
  1649. X
  1650. X   if (color >= colors) /* don't use color 0 unless from inside/outside */
  1651. X      if (colors < 16)
  1652. X     color &= andcolor;
  1653. X      else
  1654. X     color = ((color - 1) % andcolor) + 1;    /* skip color zero */
  1655. X   if(debugflag != 470)
  1656. X      if(color <= 0 && stdcalcmode == 'b' )   /* fix BTM bug */
  1657. X         color = 1;
  1658. X   (*plot) (col, row, color);
  1659. X
  1660. X   if ((kbdcount -= realcolor) <= 0)
  1661. X   {
  1662. X      if (check_key())
  1663. X     return (-1);
  1664. X      kbdcount = max_kbdcount;
  1665. X   }
  1666. X
  1667. X   return (color);
  1668. X}
  1669. X#undef green
  1670. X#undef yellow
  1671. X
  1672. X
  1673. X
  1674. X/**************** standardfractal doodad subroutines *********************/
  1675. X
  1676. Xstatic void decomposition()
  1677. X{
  1678. X   static double far cos45       = 0.70710678118654750; /* cos 45    degrees */
  1679. X   static double far sin45       = 0.70710678118654750; /* sin 45    degrees */
  1680. X   static double far cos22_5   = 0.92387953251128670; /* cos 22.5    degrees */
  1681. X   static double far sin22_5   = 0.38268343236508980; /* sin 22.5    degrees */
  1682. X   static double far cos11_25  = 0.98078528040323040; /* cos 11.25    degrees */
  1683. X   static double far sin11_25  = 0.19509032201612820; /* sin 11.25    degrees */
  1684. X   static double far cos5_625  = 0.99518472667219690; /* cos 5.625    degrees */
  1685. X   static double far sin5_625  = 0.09801714032956060; /* sin 5.625    degrees */
  1686. X   static double far tan22_5   = 0.41421356237309500; /* tan 22.5    degrees */
  1687. X   static double far tan11_25  = 0.19891236737965800; /* tan 11.25    degrees */
  1688. X   static double far tan5_625  = 0.09849140335716425; /* tan 5.625    degrees */
  1689. X   static double far tan2_8125 = 0.04912684976946725; /* tan 2.8125 degrees */
  1690. X   static double far tan1_4063 = 0.02454862210892544; /* tan 1.4063 degrees */
  1691. X   static long far lcos45      ; /* cos 45      degrees */
  1692. X   static long far lsin45      ; /* sin 45      degrees */
  1693. X   static long far lcos22_5   ; /* cos 22.5   degrees */
  1694. X   static long far lsin22_5   ; /* sin 22.5   degrees */
  1695. X   static long far lcos11_25  ; /* cos 11.25  degrees */
  1696. X   static long far lsin11_25  ; /* sin 11.25  degrees */
  1697. X   static long far lcos5_625  ; /* cos 5.625  degrees */
  1698. X   static long far lsin5_625  ; /* sin 5.625  degrees */
  1699. X   static long far ltan22_5   ; /* tan 22.5   degrees */
  1700. X   static long far ltan11_25  ; /* tan 11.25  degrees */
  1701. X   static long far ltan5_625  ; /* tan 5.625  degrees */
  1702. X   static long far ltan2_8125 ; /* tan 2.8125 degrees */
  1703. X   static long far ltan1_4063 ; /* tan 1.4063 degrees */
  1704. X   static reset_fudge = -1;
  1705. X   int temp = 0;
  1706. X   int i;
  1707. X   _LCMPLX lalt;
  1708. X   _CMPLX alt;
  1709. X   color = 0;
  1710. X   if (integerfractal) /* the only case */
  1711. X   {
  1712. X      if (reset_fudge != fudge)
  1713. X      {
  1714. X     reset_fudge = fudge;
  1715. X     lcos45     = cos45     *fudge;
  1716. X     lsin45     = sin45     *fudge;
  1717. X     lcos22_5   = cos22_5     *fudge;
  1718. X     lsin22_5   = sin22_5     *fudge;
  1719. X     lcos11_25  = cos11_25     *fudge;
  1720. X     lsin11_25  = sin11_25     *fudge;
  1721. X     lcos5_625  = cos5_625     *fudge;
  1722. X     lsin5_625  = sin5_625     *fudge;
  1723. X     ltan22_5   = tan22_5     *fudge;
  1724. X     ltan11_25  = tan11_25     *fudge;
  1725. X     ltan5_625  = tan5_625     *fudge;
  1726. X     ltan2_8125 = tan2_8125  *fudge;
  1727. X     ltan1_4063 = tan1_4063  *fudge;
  1728. X      }
  1729. X      if (lnew.y < 0)
  1730. X      {
  1731. X     temp = 2;
  1732. X     lnew.y = -lnew.y;
  1733. X      }
  1734. X
  1735. X      if (lnew.x < 0)
  1736. X      {
  1737. X     ++temp;
  1738. X     lnew.x = -lnew.x;
  1739. X      }
  1740. X
  1741. X      if (decomp[0] >= 8)
  1742. X      {
  1743. X     temp <<= 1;
  1744. X     if (lnew.x < lnew.y)
  1745. X     {
  1746. X        ++temp;
  1747. X        lalt.x = lnew.x; /* just */
  1748. X        lnew.x = lnew.y; /* swap */
  1749. X        lnew.y = lalt.x; /* them */
  1750. X     }
  1751. X
  1752. X     if (decomp[0] >= 16)
  1753. X     {
  1754. X        temp <<= 1;
  1755. X        if (multiply(lnew.x,ltan22_5,bitshift) < lnew.y)
  1756. X        {
  1757. X           ++temp;
  1758. X           lalt = lnew;
  1759. X           lnew.x = multiply(lalt.x,lcos45,bitshift) +
  1760. X           multiply(lalt.y,lsin45,bitshift);
  1761. X           lnew.y = multiply(lalt.x,lsin45,bitshift) -
  1762. X           multiply(lalt.y,lcos45,bitshift);
  1763. X        }
  1764. X
  1765. X        if (decomp[0] >= 32)
  1766. X        {
  1767. X           temp <<= 1;
  1768. X           if (multiply(lnew.x,ltan11_25,bitshift) < lnew.y)
  1769. X           {
  1770. X          ++temp;
  1771. X          lalt = lnew;
  1772. X          lnew.x = multiply(lalt.x,lcos22_5,bitshift) +
  1773. X              multiply(lalt.y,lsin22_5,bitshift);
  1774. X          lnew.y = multiply(lalt.x,lsin22_5,bitshift) -
  1775. X              multiply(lalt.y,lcos22_5,bitshift);
  1776. X           }
  1777. X
  1778. X           if (decomp[0] >= 64)
  1779. X           {
  1780. X          temp <<= 1;
  1781. X          if (multiply(lnew.x,ltan5_625,bitshift) < lnew.y)
  1782. X          {
  1783. X             ++temp;
  1784. X             lalt = lnew;
  1785. X             lnew.x = multiply(lalt.x,lcos11_25,bitshift) +
  1786. X             multiply(lalt.y,lsin11_25,bitshift);
  1787. X             lnew.y = multiply(lalt.x,lsin11_25,bitshift) -
  1788. X             multiply(lalt.y,lcos11_25,bitshift);
  1789. X          }
  1790. X
  1791. X          if (decomp[0] >= 128)
  1792. X          {
  1793. X             temp <<= 1;
  1794. X             if (multiply(lnew.x,ltan2_8125,bitshift) < lnew.y)
  1795. X             {
  1796. X            ++temp;
  1797. X            lalt = lnew;
  1798. X            lnew.x = multiply(lalt.x,lcos5_625,bitshift) +
  1799. X                multiply(lalt.y,lsin5_625,bitshift);
  1800. X            lnew.y = multiply(lalt.x,lsin5_625,bitshift) -
  1801. X                multiply(lalt.y,lcos5_625,bitshift);
  1802. X             }
  1803. X
  1804. X             if (decomp[0] == 256)
  1805. X             {
  1806. X            temp <<= 1;
  1807. X            if (multiply(lnew.x,ltan1_4063,bitshift) < lnew.y)
  1808. X               if ((lnew.x*ltan1_4063 < lnew.y))
  1809. X                  ++temp;
  1810. X             }
  1811. X          }
  1812. X           }
  1813. X        }
  1814. X     }
  1815. X      }
  1816. X   }
  1817. X   else /* double case */
  1818. X   {
  1819. X      if (new.y < 0)
  1820. X      {
  1821. X     temp = 2;
  1822. X     new.y = -new.y;
  1823. X      }
  1824. X      if (new.x < 0)
  1825. X      {
  1826. X     ++temp;
  1827. X     new.x = -new.x;
  1828. X      }
  1829. X      if (decomp[0] >= 8)
  1830. X      {
  1831. X     temp <<= 1;
  1832. X     if (new.x < new.y)
  1833. X     {
  1834. X        ++temp;
  1835. X        alt.x = new.x; /* just */
  1836. X        new.x = new.y; /* swap */
  1837. X        new.y = alt.x; /* them */
  1838. X     }
  1839. X     if (decomp[0] >= 16)
  1840. X     {
  1841. X        temp <<= 1;
  1842. X        if (new.x*tan22_5 < new.y)
  1843. X        {
  1844. X           ++temp;
  1845. X           alt = new;
  1846. X           new.x = alt.x*cos45 + alt.y*sin45;
  1847. X           new.y = alt.x*sin45 - alt.y*cos45;
  1848. X        }
  1849. X
  1850. X        if (decomp[0] >= 32)
  1851. X        {
  1852. X           temp <<= 1;
  1853. X           if (new.x*tan11_25 < new.y)
  1854. X           {
  1855. X          ++temp;
  1856. X          alt = new;
  1857. X          new.x = alt.x*cos22_5 + alt.y*sin22_5;
  1858. X          new.y = alt.x*sin22_5 - alt.y*cos22_5;
  1859. X           }
  1860. X
  1861. X           if (decomp[0] >= 64)
  1862. X           {
  1863. X          temp <<= 1;
  1864. X          if (new.x*tan5_625 < new.y)
  1865. X          {
  1866. X             ++temp;
  1867. X             alt = new;
  1868. X             new.x = alt.x*cos11_25 + alt.y*sin11_25;
  1869. X             new.y = alt.x*sin11_25 - alt.y*cos11_25;
  1870. X          }
  1871. X
  1872. X          if (decomp[0] >= 128)
  1873. X          {
  1874. X             temp <<= 1;
  1875. X             if (new.x*tan2_8125 < new.y)
  1876. X             {
  1877. X            ++temp;
  1878. X            alt = new;
  1879. X            new.x = alt.x*cos5_625 + alt.y*sin5_625;
  1880. X            new.y = alt.x*sin5_625 - alt.y*cos5_625;
  1881. X             }
  1882. X
  1883. X             if (decomp[0] == 256)
  1884. X             {
  1885. X            temp <<= 1;
  1886. X            if ((new.x*tan1_4063 < new.y))
  1887. X               ++temp;
  1888. X             }
  1889. X          }
  1890. X           }
  1891. X        }
  1892. X     }
  1893. X      }
  1894. X   }
  1895. X   for (i = 1; temp > 0; ++i)
  1896. X   {
  1897. X      if (temp & 1)
  1898. X     color = (1 << i) - 1 - color;
  1899. X      temp >>= 1;
  1900. X   }
  1901. X   if (decomp[0] == 2)
  1902. X      color &= 1;
  1903. X   if (colors > decomp[0])
  1904. X      color++;
  1905. X}
  1906. X
  1907. X/******************************************************************/
  1908. X/* Continuous potential calculation for Mandelbrot and Julia      */
  1909. X/* Reference: Science of Fractal Images p. 190.           */
  1910. X/* Special thanks to Mark Peterson for his "MtMand" program that  */
  1911. X/* beautifully approximates plate 25 (same reference) and spurred */
  1912. X/* on the inclusion of similar capabilities in FRACTINT.      */
  1913. X/*                                  */
  1914. X/* The purpose of this function is to calculate a color value      */
  1915. X/* for a fractal that varies continuously with the screen pixels  */
  1916. X/* locations for better rendering in 3D.              */
  1917. X/*                                  */
  1918. X/* Here "magnitude" is the modulus of the orbit value at          */
  1919. X/* "iterations". The potparms[] are user-entered paramters        */
  1920. X/* controlling the level and slope of the continuous potential      */
  1921. X/* surface. Returns color.  - Tim Wegner 6/25/89          */
  1922. X/*                                  */
  1923. X/*               -- Change history --              */
  1924. X/*                                  */
  1925. X/* 09/12/89   - added floatflag support and fixed float underflow */
  1926. X/*                                  */
  1927. X/******************************************************************/
  1928. X
  1929. Xstatic int _fastcall potential(double mag, int iterations)
  1930. X{
  1931. X   float f_mag,f_tmp,pot;
  1932. X   double d_tmp;
  1933. X   int i_pot;
  1934. X   long l_pot;
  1935. X   extern char floatflag;
  1936. X
  1937. X   if(iterations < maxit)
  1938. X   {
  1939. X      pot = i_pot = iterations+2;
  1940. X      if(i_pot <= 0 || mag <= 1.0)
  1941. X     pot = 0.0;
  1942. X      else /* pot = log(mag) / pow(2.0, (double)pot); */
  1943. X      {
  1944. X     if(i_pot < 120 && !floatflag) /* empirically determined limit of fShift */
  1945. X     {
  1946. X        f_mag = mag;
  1947. X        fLog14(f_mag,f_tmp); /* this SHOULD be non-negative */
  1948. X        fShift(f_tmp,(char)-i_pot,pot);
  1949. X     }
  1950. X     else
  1951. X     {
  1952. X        d_tmp = log(mag)/(double)pow(2.0,(double)pot);
  1953. X        if(d_tmp > FLT_MIN) /* prevent float type underflow */
  1954. X           pot = d_tmp;
  1955. X        else
  1956. X           pot = 0.0;
  1957. X     }
  1958. X      }
  1959. X      /* following transformation strictly for aesthetic reasons */
  1960. X      /* meaning of parameters:
  1961. X        potparam[0] -- zero potential level - highest color -
  1962. X        potparam[1] -- slope multiplier -- higher is steeper
  1963. X        potparam[2] -- rqlim value if changeable (bailout for modulus) */
  1964. X
  1965. X      if(pot > 0.0)
  1966. X      {
  1967. X     if(floatflag)
  1968. X        pot = (float)sqrt((double)pot);
  1969. X     else
  1970. X     {
  1971. X        fSqrt14(pot,f_tmp);
  1972. X        pot = f_tmp;
  1973. X     }
  1974. X     pot = potparam[0] - pot*potparam[1] - 1.0;
  1975. X      }
  1976. X      else
  1977. X     pot = potparam[0] - 1.0;
  1978. X      if(pot < 1.0)
  1979. X     pot = 1.0; /* avoid color 0 */
  1980. X   }
  1981. X   else if(inside >= 0)
  1982. X      pot = inside;
  1983. X   else /* inside < 0 implies inside=maxit, so use 1st pot param instead */
  1984. X      pot = potparam[0];
  1985. X
  1986. X   i_pot = (l_pot = pot * 256) >> 8;
  1987. X   if(i_pot >= colors)
  1988. X   {
  1989. X      i_pot = colors - 1;
  1990. X      l_pot = 255;
  1991. X   }
  1992. X
  1993. X   if(pot16bit)
  1994. X   {
  1995. X      if (dotmode != 11) /* if putcolor won't be doing it for us */
  1996. X     writedisk(col+sxoffs,row+syoffs,i_pot);
  1997. X      writedisk(col+sxoffs,row+sydots+syoffs,(int)l_pot);
  1998. X   }
  1999. X
  2000. X   return(i_pot);
  2001. X}
  2002. X
  2003. X
  2004. X/******************* boundary trace method ***************************
  2005. XFractint's original btm was written by David Guenther.  There were a few
  2006. Xrare circumstances in which the original btm would not trace or fill
  2007. Xcorrectly, even on Mandelbrot Sets.  The code below was adapted from
  2008. X"Mandelbrot Sets by Wesley Loewer" (see calmanfp.asm) which was written
  2009. Xbefore I was introduced to Fractint.  It should be noted that without
  2010. XDavid Guenther's implimentation of a btm, I doubt that I would have been
  2011. Xable to impliment my own code into Fractint.  There are several things in
  2012. Xthe following code that are not original with me but came from David
  2013. XGuenther's code.  I've noted these places with the initials DG.
  2014. X
  2015. X                    Wesley Loewer 3/8/92
  2016. X*********************************************************************/
  2017. X#define bkcolor 0  /* I have some ideas for the future with this. -Wes */
  2018. X#define advance_match()     coming_from = ((going_to = (going_to - 1) & 0x03) - 1) & 0x03
  2019. X#define advance_no_match()  going_to = (going_to + 1) & 0x03
  2020. X
  2021. Xstatic
  2022. Xint  bound_trace_main()
  2023. X    {
  2024. X    enum direction coming_from;
  2025. X    unsigned int match_found, continue_loop;
  2026. X    int trail_color, fillcolor_used, last_fillcolor_used;
  2027. X    int max_putline_length;
  2028. X    int right, left, length;
  2029. X
  2030. X    if (inside == 0 || outside == 0)
  2031. X    {
  2032. X    static char far msg[]=
  2033. X        "Boundary tracing cannot be used with inside=0 or outside=0.";
  2034. X    stopmsg(0,msg);
  2035. X    return(-1);
  2036. X    }
  2037. X    if (colors < 16)
  2038. X    {
  2039. X    static char far msg[]=
  2040. X        "Boundary tracing cannot be used with < 16 colors.";
  2041. X    stopmsg(0,msg);
  2042. X    return(-1);
  2043. X    }
  2044. X
  2045. X    got_status = 2;
  2046. X    max_putline_length = 0; /* reset max_putline_length */
  2047. X    for (currow = iystart; currow <= iystop; currow++)
  2048. X    {
  2049. X    reset_periodicity = 1; /* reset for a new row */
  2050. X    color = bkcolor;
  2051. X    for (curcol = ixstart; curcol <= ixstop; curcol++)
  2052. X        {
  2053. X        if (getcolor(curcol, currow) != bkcolor)
  2054. X        continue;
  2055. X
  2056. X        trail_color = color;
  2057. X        row = currow;
  2058. X        col = curcol;
  2059. X        if ((*calctype)()== -1) /* color, row, col are global */
  2060. X        {
  2061. X        if (iystop != yystop)  /* DG */
  2062. X           iystop = yystop - (currow - yystart); /* allow for sym */
  2063. X        add_worklist(xxstart,xxstop,currow,iystop,currow,0,worksym);
  2064. X        return -1;
  2065. X        }
  2066. X        reset_periodicity = 0; /* normal periodicity checking */
  2067. X
  2068. X        /*
  2069. X        This next line may cause a few more pixels to be calculated,
  2070. X        but at the savings of quite a bit of overhead
  2071. X        */
  2072. X        if (color != trail_color)  /* DG */
  2073. X        continue;
  2074. X
  2075. X        /* sweep clockwise to trace outline */
  2076. X        trail_row = currow;
  2077. X        trail_col = curcol;
  2078. X        trail_color = color;
  2079. X        fillcolor_used = fillcolor > 0 ? fillcolor : trail_color;
  2080. X        coming_from = West;
  2081. X        going_to = East;
  2082. X        match_found = 0;
  2083. X        continue_loop = TRUE;
  2084. X        do
  2085. X        {
  2086. X        step_col_row();
  2087. X        if (row >= currow
  2088. X            && col >= ixstart
  2089. X            && col <= ixstop
  2090. X            && row <= iystop)
  2091. X            {
  2092. X            /* the order of operations in this next line is critical */
  2093. X            if ((color = getcolor(col, row)) == bkcolor && (*calctype)()== -1)
  2094. X                /* color, row, col are global for (*calctype)() */
  2095. X            {
  2096. X            if (iystop != yystop)  /* DG */
  2097. X               iystop = yystop - (currow - yystart); /* allow for sym */
  2098. X            add_worklist(xxstart,xxstop,currow,iystop,currow,0,worksym);
  2099. X            return -1;
  2100. X            }
  2101. X            else if (color == trail_color)
  2102. X            {
  2103. X            if (match_found < 4) /* to keep it from overflowing */
  2104. X                match_found++;
  2105. X            trail_row = row;
  2106. X            trail_col = col;
  2107. X            advance_match();
  2108. X            }
  2109. X            else
  2110. X            {
  2111. X            advance_no_match();
  2112. X            continue_loop = going_to != coming_from || match_found;
  2113. X            }
  2114. X            }
  2115. X        else
  2116. X            {
  2117. X            advance_no_match();
  2118. X            continue_loop = going_to != coming_from || match_found;
  2119. X            }
  2120. X        } while (continue_loop && (col != curcol || row != currow));
  2121. X
  2122. X        if (match_found <= 3)  /* DG */
  2123. X        { /* no hole */
  2124. X        color = bkcolor;
  2125. X        reset_periodicity = 1;
  2126. X        continue;
  2127. X        }
  2128. X
  2129. X/*
  2130. XFill in region by looping around again, filling lines to the left
  2131. Xwhenever going_to is South or West
  2132. X*/
  2133. X        trail_row = currow;
  2134. X        trail_col = curcol;
  2135. X        coming_from = West;
  2136. X        going_to = East;
  2137. X        do
  2138. X        {
  2139. X        match_found = FALSE;
  2140. X        do
  2141. X            {
  2142. X            step_col_row();
  2143. X            if (row >= currow
  2144. X                && col >= ixstart
  2145. X                && col <= ixstop
  2146. X                && row <= iystop
  2147. X                && getcolor(col,row) == trail_color)
  2148. X                  /* getcolor() must be last */
  2149. X            {
  2150. X            if (going_to == South
  2151. X                || (going_to == West && coming_from != East))
  2152. X                { /* fill a row, but only once */
  2153. X                right = col;
  2154. X                while (--right >= ixstart && (color = getcolor(right,row)) == trail_color)
  2155. X                ; /* do nothing */
  2156. X                if (color == bkcolor) /* check last color */
  2157. X                {
  2158. X                left = right;
  2159. X                while (getcolor(--left,row) == bkcolor)
  2160. X                      /* Should NOT be possible for left < ixstart */
  2161. X                    ; /* do nothing */
  2162. X                left++; /* one pixel too far */
  2163. X                if (right == left) /* only one hole */
  2164. X                    (*plot)(left,row,fillcolor_used);
  2165. X                else
  2166. X                    { /* fill the line to the left */
  2167. X                    length=right-left+1;
  2168. X                    if (fillcolor_used != last_fillcolor_used || length > max_putline_length)
  2169. X                    { /* only reset dstack if necessary */
  2170. X                    memset(dstack,fillcolor_used,length);
  2171. X                    last_fillcolor_used = fillcolor_used;
  2172. X                    max_putline_length = length;
  2173. X                    }
  2174. X                    put_line(row,left,right,dstack);
  2175. X                    /* here's where all the symmetry goes */
  2176. X                    if (plot == putcolor)
  2177. X                    kbdcount -= length >> 4; /* seems like a reasonable value */
  2178. X                    else if (plot == symplot2) /* X-axis symmetry */
  2179. X                    {
  2180. X                    put_line(yystop-(row-yystart),left,right,dstack);
  2181. X                    kbdcount -= length >> 3;
  2182. X                    }
  2183. X                    else if (plot == symplot2Y) /* Y-axis symmetry */
  2184. X                    {
  2185. X                    put_line(row,xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
  2186. X                    kbdcount -= length >> 3;
  2187. X                    }
  2188. X                    else if (plot == symplot2J)  /* Origin symmetry */
  2189. X                    {
  2190. X                    put_line(yystop-(row-yystart),xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
  2191. X                    kbdcount -= length >> 3;
  2192. X                    }
  2193. X                    else if (plot == symplot4) /* X-axis and Y-axis symmetry */
  2194. X                    {
  2195. X                    put_line(yystop-(row-yystart),left,right,dstack);
  2196. X                    put_line(row,xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
  2197. X                    put_line(yystop-(row-yystart),xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
  2198. X                    kbdcount -= length >> 2;
  2199. X                    }
  2200. X                    else    /* cheap and easy way out */
  2201. X                    {
  2202. X                    int c;
  2203. X                    for (c = left; c <= right; c++)  /* DG */
  2204. X                        (*plot)(c,row,fillcolor_used);
  2205. X                    kbdcount -= length >> 1;
  2206. X                    }
  2207. X                    }
  2208. X                } /* end of fill line */
  2209. X
  2210. X                if(--kbdcount<=0)
  2211. X                {
  2212. X                if(check_key())
  2213. X                    {
  2214. X                    if (iystop != yystop)
  2215. X                       iystop = yystop - (currow - yystart); /* allow for sym */
  2216. X                    add_worklist(xxstart,xxstop,currow,iystop,currow,0,worksym);
  2217. X                    return(-1);
  2218. X                    }
  2219. X                kbdcount=max_kbdcount;
  2220. X                }
  2221. X                }
  2222. X            trail_row = row;
  2223. X            trail_col = col;
  2224. X            advance_match();
  2225. X            match_found = TRUE;
  2226. X            }
  2227. X            else
  2228. X            advance_no_match();
  2229. X            } while (!match_found && going_to != coming_from);
  2230. X
  2231. X        if (!match_found)
  2232. X            { /* next one has to be a match */
  2233. X            step_col_row();
  2234. X            trail_row = row;
  2235. X            trail_col = col;
  2236. X            advance_match();
  2237. X            }
  2238. X        } while (trail_col != curcol || trail_row != currow);
  2239. X        reset_periodicity = 1; /* reset after a trace/fill */
  2240. X        color = bkcolor;
  2241. X        }
  2242. X    }
  2243. X    return 0;
  2244. X    }
  2245. X
  2246. X/*******************************************************************/
  2247. X/* take one step in the direction of going_to */
  2248. Xstatic void step_col_row()
  2249. X    {
  2250. X    switch (going_to)
  2251. X    {
  2252. X    case North:
  2253. X        col = trail_col;
  2254. X        row = trail_row - 1;
  2255. X        break;
  2256. X    case East:
  2257. X        col = trail_col + 1;
  2258. X        row = trail_row;
  2259. X        break;
  2260. X    case South:
  2261. X        col = trail_col;
  2262. X        row = trail_row + 1;
  2263. X        break;
  2264. X    case West:
  2265. X        col = trail_col - 1;
  2266. X        row = trail_row;
  2267. X        break;
  2268. X    }
  2269. X    }
  2270. X
  2271. X/******************* end of boundary trace method *******************/
  2272. X
  2273. X
  2274. X/************************ super solid guessing *****************************/
  2275. X
  2276. X/*
  2277. X   I, Timothy Wegner, invented this solidguessing idea and implemented it in
  2278. X   more or less the overall framework you see here.  I am adding this note
  2279. X   now in a possibly vain attempt to secure my place in history, because
  2280. X   Pieter Branderhorst has totally rewritten this routine, incorporating
  2281. X   a *MUCH* more sophisticated algorithm.  His revised code is not only
  2282. X   faster, but is also more accurate. Harrumph!
  2283. X*/
  2284. X
  2285. Xstatic int solidguess()
  2286. X{
  2287. X   int i,x,y,xlim,ylim,blocksize;
  2288. X   unsigned int *pfxp0,*pfxp1;
  2289. X   unsigned int u;
  2290. X
  2291. X   guessplot=(plot!=putcolor && plot!=symplot2 && plot!=symplot2J);
  2292. X   /* check if guessing at bottom & right edges is ok */
  2293. X   bottom_guess = (plot == symplot2 || (plot == putcolor && iystop+1 == ydots));
  2294. X   right_guess    = (plot == symplot2J
  2295. X       || ((plot == putcolor || plot == symplot2) && ixstop+1 == xdots));
  2296. X
  2297. X   i = maxblock = blocksize = ssg_blocksize();
  2298. X   totpasses = 1;
  2299. X   while ((i >>= 1) > 1) ++totpasses;
  2300. X
  2301. X   /* ensure window top and left are on required boundary, treat window
  2302. X     as larger than it really is if necessary (this is the reason symplot
  2303. X     routines must check for > xdots/ydots before plotting sym points) */
  2304. X   ixstart &= -1 - (maxblock-1);
  2305. X   iystart = yybegin;
  2306. X   iystart &= -1 - (maxblock-1);
  2307. X
  2308. X   got_status = 1;
  2309. X
  2310. X   if (workpass == 0) /* otherwise first pass already done */
  2311. X   {
  2312. X      /* first pass, calc every blocksize**2 pixel, quarter result & paint it */
  2313. X      curpass = 1;
  2314. X      if (iystart <= yystart) /* first time for this window, init it */
  2315. X      {
  2316. X     currow = 0;
  2317. X     memset(&prefix[1][0][0],0,maxxblk*maxyblk*2); /* noskip flags off */
  2318. X     reset_periodicity = 1;
  2319. X     row=iystart;
  2320. X     for(col=ixstart; col<=ixstop; col+=maxblock)
  2321. X     { /* calc top row */
  2322. X        if((*calctype)()== -1)
  2323. X        {
  2324. X           add_worklist(xxstart,xxstop,yystart,yystop,yybegin,0,worksym);
  2325. X           goto exit_solidguess;
  2326. X        }
  2327. X        reset_periodicity = 0;
  2328. X     }
  2329. X      }
  2330. X      else
  2331. X     memset(&prefix[1][0][0],-1,maxxblk*maxyblk*2); /* noskip flags on */
  2332. X      for(y=iystart; y<=iystop; y+=blocksize)
  2333. X      {
  2334. X     currow = y;
  2335. X     i = 0;
  2336. X     if(y+blocksize<=iystop)
  2337. X     { /* calc the row below */
  2338. X        row=y+blocksize;
  2339. X        reset_periodicity = 1;
  2340. X        for(col=ixstart; col<=ixstop; col+=maxblock)
  2341. X        {
  2342. X           if((i=(*calctype)()) == -1)
  2343. X          break;
  2344. X           reset_periodicity = 0;
  2345. X        }
  2346. X     }
  2347. X     reset_periodicity = 1;
  2348. X     if (i == -1 || guessrow(1,y,blocksize) != 0) /* interrupted? */
  2349. X     {
  2350. X        if (y < yystart)
  2351. X           y = yystart;
  2352. X        add_worklist(xxstart,xxstop,yystart,yystop,y,0,worksym);
  2353. X        goto exit_solidguess;
  2354. X     }
  2355. X      }
  2356. X
  2357. X      if (num_worklist) /* work list not empty, just do 1st pass */
  2358. X      {
  2359. X     add_worklist(xxstart,xxstop,yystart,yystop,yystart,1,worksym);
  2360. X     goto exit_solidguess;
  2361. X      }
  2362. X      ++workpass;
  2363. X      iystart = yystart & (-1 - (maxblock-1));
  2364. X
  2365. X      /* calculate skip flags for skippable blocks */
  2366. X      xlim=(ixstop+maxblock)/maxblock+1;
  2367. X      ylim=((iystop+maxblock)/maxblock+15)/16+1;
  2368. X      if(right_guess==0) /* no right edge guessing, zap border */
  2369. X     for(y=0;y<=ylim;++y)
  2370. X        prefix[1][y][xlim]= -1;
  2371. X      if(bottom_guess==0) /* no bottom edge guessing, zap border */
  2372. X      {
  2373. X     i=(iystop+maxblock)/maxblock+1;
  2374. X     y=i/16+1;
  2375. X     i=1<<(i&15);
  2376. X     for(x=0;x<=xlim;++x)
  2377. X        prefix[1][y][x]|=i;
  2378. X      }
  2379. X      /* set each bit in prefix[0] to OR of it & surrounding 8 in prefix[1] */
  2380. X      for(y=0;++y<ylim;)
  2381. X      {
  2382. X     pfxp0= &prefix[0][y][0];
  2383. X     pfxp1= &prefix[1][y][0];
  2384. X     for(x=0;++x<xlim;)
  2385. X     {
  2386. X        ++pfxp1;
  2387. X        u= *(pfxp1-1)|*pfxp1|*(pfxp1+1);
  2388. X        *(++pfxp0)=u|(u>>1)|(u<<1)
  2389. X           |((*(pfxp1-(maxxblk+1))|*(pfxp1-maxxblk)|*(pfxp1-(maxxblk-1)))>>15)
  2390. X          |((*(pfxp1+(maxxblk-1))|*(pfxp1+maxxblk)|*(pfxp1+(maxxblk+1)))<<15);
  2391. X     }
  2392. X      }
  2393. X   }
  2394. X   else /* first pass already done */
  2395. X      memset(&prefix[0][0][0],-1,maxxblk*maxyblk*2); /* noskip flags on */
  2396. X
  2397. X   /* remaining pass(es), halve blocksize & quarter each blocksize**2 */
  2398. X   i = workpass;
  2399. X   while (--i > 0) /* allow for already done passes */
  2400. X      blocksize = blocksize>>1;
  2401. X   reset_periodicity = 1;
  2402. X   while((blocksize=blocksize>>1)>=2)
  2403. X   {
  2404. X      curpass = workpass + 1;
  2405. X      for(y=iystart; y<=iystop; y+=blocksize)
  2406. X      {
  2407. X     currow = y;
  2408. X     if(guessrow(0,y,blocksize)!=0)
  2409. X     {
  2410. X        if (y < yystart)
  2411. X           y = yystart;
  2412. X        add_worklist(xxstart,xxstop,yystart,yystop,y,workpass,worksym);
  2413. X        goto exit_solidguess;
  2414. X     }
  2415. X      }
  2416. X      ++workpass;
  2417. X      if (num_worklist /* work list not empty, do one pass at a time */
  2418. X      && blocksize>2) /* if 2, we just did last pass */
  2419. X      {
  2420. X     add_worklist(xxstart,xxstop,yystart,yystop,yystart,workpass,worksym);
  2421. X     goto exit_solidguess;
  2422. X      }
  2423. X      iystart = yystart & (-1 - (maxblock-1));
  2424. X   }
  2425. X
  2426. X   exit_solidguess:
  2427. X   return(0);
  2428. X}
  2429. X
  2430. X#define calcadot(c,x,y) { col=x; row=y; if((c=(*calctype)())== -1) return -1; }
  2431. X
  2432. Xstatic int _fastcall guessrow(int firstpass,int y,int blocksize)
  2433. X{
  2434. X   int x,i,j,color;
  2435. X   int xplushalf,xplusblock;
  2436. X   int ylessblock,ylesshalf,yplushalf,yplusblock;
  2437. X   int       c21,c31,c41;     /* cxy is the color of pixel at (x,y) */
  2438. X   int c12,c22,c32,c42;     /* where c22 is the topleft corner of */
  2439. X   int c13,c23,c33;        /* the block being handled in current */
  2440. X   int       c24,    c44;     /* iteration                  */
  2441. X   int guessed23,guessed32,guessed33,guessed12,guessed13;
  2442. X   int prev11,fix21,fix31;
  2443. X   unsigned int *pfxptr,pfxmask;
  2444. X
  2445. X   halfblock=blocksize>>1;
  2446. X   i=y/maxblock;
  2447. X   pfxptr= &prefix[firstpass][(i>>4)+1][ixstart/maxblock];
  2448. X   pfxmask=1<<(i&15);
  2449. X   ylesshalf=y-halfblock;
  2450. X   ylessblock=y-blocksize; /* constants, for speed */
  2451. X   yplushalf=y+halfblock;
  2452. X   yplusblock=y+blocksize;
  2453. X   prev11= -1;
  2454. X   c24=c12=c13=c22=getcolor(ixstart,y);
  2455. X   c31=c21=getcolor(ixstart,(y>0)?ylesshalf:0);
  2456. X   if(yplusblock<=iystop)
  2457. X      c24=getcolor(ixstart,yplusblock);
  2458. X   else if(bottom_guess==0)
  2459. X      c24= -1;
  2460. X   guessed12=guessed13=0;
  2461. X
  2462. X   for(x=ixstart; x<=ixstop;)  /* increment at end, or when doing continue */
  2463. X   {
  2464. X      if((x&(maxblock-1))==0)  /* time for skip flag stuff */
  2465. X      {
  2466. X     ++pfxptr;
  2467. X     if(firstpass==0 && (*pfxptr&pfxmask)==0)  /* check for fast skip */
  2468. X     {
  2469. X        /* next useful in testing to make skips visible */
  2470. X        /*
  2471. X               if(halfblock==1)
  2472. X               {
  2473. X                  (*plot)(x+1,y,0); (*plot)(x,y+1,0); (*plot)(x+1,y+1,0);
  2474. X                  }
  2475. X             */
  2476. X        x+=maxblock;
  2477. X        prev11=c31=c21=c24=c12=c13=c22;
  2478. X        guessed12=guessed13=0;
  2479. X        continue;
  2480. X     }
  2481. X      }
  2482. X
  2483. X      if(firstpass)  /* 1st pass, paint topleft corner */
  2484. X     plotblock(0,x,y,c22);
  2485. X      /* setup variables */
  2486. X      xplusblock=(xplushalf=x+halfblock)+halfblock;
  2487. X      if(xplushalf>ixstop)
  2488. X      {
  2489. X     if(right_guess==0)
  2490. X        c31= -1;
  2491. X      }
  2492. X      else if(y>0)
  2493. X     c31=getcolor(xplushalf,ylesshalf);
  2494. X      if(xplusblock<=ixstop)
  2495. X      {
  2496. X     if(yplusblock<=iystop)
  2497. X        c44=getcolor(xplusblock,yplusblock);
  2498. X     c41=getcolor(xplusblock,(y>0)?ylesshalf:0);
  2499. X     c42=getcolor(xplusblock,y);
  2500. X      }
  2501. X      else if(right_guess==0)
  2502. X     c41=c42=c44= -1;
  2503. X      if(yplusblock>iystop)
  2504. X     c44=(bottom_guess)?c42:-1;
  2505. X
  2506. X      /* guess or calc the remaining 3 quarters of current block */
  2507. X      guessed23=guessed32=guessed33=1;
  2508. X      c23=c32=c33=c22;
  2509. X      if(yplushalf>iystop)
  2510. X      {
  2511. X     if(bottom_guess==0)
  2512. X        c23=c33= -1;
  2513. X     guessed23=guessed33= -1;
  2514. X      }
  2515. X      if(xplushalf>ixstop)
  2516. X      {
  2517. X     if(right_guess==0)
  2518. X        c32=c33= -1;
  2519. X     guessed32=guessed33= -1;
  2520. X      }
  2521. X      while(1) /* go around till none of 23,32,33 change anymore */
  2522. X      {
  2523. X     if(guessed33>0
  2524. X         && (c33!=c44 || c33!=c42 || c33!=c24 || c33!=c32 || c33!=c23))
  2525. X     {
  2526. X        calcadot(c33,xplushalf,yplushalf);
  2527. X        guessed33=0;
  2528. X     }
  2529. X     if(guessed32>0
  2530. X         && (c32!=c33 || c32!=c42 || c32!=c31 || c32!=c21
  2531. X         || c32!=c41 || c32!=c23))
  2532. X     {
  2533. X        calcadot(c32,xplushalf,y);
  2534. X        guessed32=0;
  2535. X        continue;
  2536. X     }
  2537. X     if(guessed23>0
  2538. X         && (c23!=c33 || c23!=c24 || c23!=c13 || c23!=c12 || c23!=c32))
  2539. X     {
  2540. X        calcadot(c23,x,yplushalf);
  2541. X        guessed23=0;
  2542. X        continue;
  2543. X     }
  2544. X     break;
  2545. X      }
  2546. X
  2547. X      if(firstpass) /* note whether any of block's contents were calculated */
  2548. X     if(guessed23==0 || guessed32==0 || guessed33==0)
  2549. X        *pfxptr|=pfxmask;
  2550. X
  2551. X      if(halfblock>1) /* not last pass, check if something to display */
  2552. X     if(firstpass)    /* display guessed corners, fill in block */
  2553. X     {
  2554. X        if(guessplot)
  2555. X        {
  2556. X           if(guessed23>0)
  2557. X          (*plot)(x,yplushalf,c23);
  2558. X           if(guessed32>0)
  2559. X          (*plot)(xplushalf,y,c32);
  2560. X           if(guessed33>0)
  2561. X          (*plot)(xplushalf,yplushalf,c33);
  2562. X        }
  2563. X        plotblock(1,x,yplushalf,c23);
  2564. X        plotblock(0,xplushalf,y,c32);
  2565. X        plotblock(1,xplushalf,yplushalf,c33);
  2566. X     }
  2567. X     else  /* repaint changed blocks */
  2568. X     {
  2569. X        if(c23!=c22)
  2570. X           plotblock(-1,x,yplushalf,c23);
  2571. X        if(c32!=c22)
  2572. X           plotblock(-1,xplushalf,y,c32);
  2573. X        if(c33!=c22)
  2574. X           plotblock(-1,xplushalf,yplushalf,c33);
  2575. X     }
  2576. X
  2577. X      /* check if some calcs in this block mean earlier guesses need fixing */
  2578. X      fix21=((c22!=c12 || c22!=c32)
  2579. X      && c21==c22 && c21==c31 && c21==prev11
  2580. X      && y>0
  2581. X      && (x==ixstart || c21==getcolor(x-halfblock,ylessblock))
  2582. X      && (xplushalf>ixstop || c21==getcolor(xplushalf,ylessblock))
  2583. X      && c21==getcolor(x,ylessblock));
  2584. X      fix31=(c22!=c32
  2585. X      && c31==c22 && c31==c42 && c31==c21 && c31==c41
  2586. X      && y>0 && xplushalf<=ixstop
  2587. X      && c31==getcolor(xplushalf,ylessblock)
  2588. X      && (xplusblock>ixstop || c31==getcolor(xplusblock,ylessblock))
  2589. X      && c31==getcolor(x,ylessblock));
  2590. X      prev11=c31; /* for next time around */
  2591. X      if(fix21)
  2592. X      {
  2593. X     calcadot(c21,x,ylesshalf);
  2594. X     if(halfblock>1 && c21!=c22)
  2595. X        plotblock(-1,x,ylesshalf,c21);
  2596. X      }
  2597. X      if(fix31)
  2598. X      {
  2599. X     calcadot(c31,xplushalf,ylesshalf);
  2600. X     if(halfblock>1 && c31!=c22)
  2601. X        plotblock(-1,xplushalf,ylesshalf,c31);
  2602. X      }
  2603. X      if(c23!=c22)
  2604. X      {
  2605. X     if(guessed12)
  2606. X     {
  2607. X        calcadot(c12,x-halfblock,y);
  2608. X        if(halfblock>1 && c12!=c22)
  2609. X           plotblock(-1,x-halfblock,y,c12);
  2610. X     }
  2611. X     if(guessed13)
  2612. X     {
  2613. X        calcadot(c13,x-halfblock,yplushalf);
  2614. X        if(halfblock>1 && c13!=c22)
  2615. X           plotblock(-1,x-halfblock,yplushalf,c13);
  2616. X     }
  2617. X      }
  2618. X      c22=c42;
  2619. X      c24=c44;
  2620. X      c13=c33;
  2621. X      c31=c21=c41;
  2622. X      c12=c32;
  2623. X      guessed12=guessed32;
  2624. X      guessed13=guessed33;
  2625. X      x+=blocksize;
  2626. X   } /* end x loop */
  2627. X
  2628. X   if(firstpass==0 || guessplot) return 0;
  2629. X
  2630. X   /* paint rows the fast way */
  2631. X   for(i=0;i<halfblock;++i)
  2632. X   {
  2633. X      if((j=y+i)<=iystop)
  2634. X     put_line(j,xxstart,ixstop,&dstack[xxstart]);
  2635. X      if((j=y+i+halfblock)<=iystop)
  2636. X     put_line(j,xxstart,ixstop,&dstack[xxstart+MAXPIXELS]);
  2637. X      if(keypressed()) return -1;
  2638. X   }
  2639. X   if(plot!=putcolor)  /* symmetry, just vertical & origin the fast way */
  2640. X   {
  2641. X      if(plot==symplot2J) /* origin sym, reverse lines */
  2642. X     for(i=(ixstop+xxstart+1)/2;--i>=xxstart;)
  2643. X     {
  2644. X        color=dstack[i];
  2645. X        dstack[i]=dstack[j=ixstop-(i-xxstart)];
  2646. X        dstack[j]=color;
  2647. X        j+=MAXPIXELS;
  2648. X        color=dstack[i+MAXPIXELS];
  2649. X        dstack[i+MAXPIXELS]=dstack[j];
  2650. X        dstack[j]=color;
  2651. X     }
  2652. X      for(i=0;i<halfblock;++i)
  2653. X      {
  2654. X     if((j=yystop-(y+i-yystart))>iystop && j<ydots)
  2655. X        put_line(j,xxstart,ixstop,&dstack[xxstart]);
  2656. X     if((j=yystop-(y+i+halfblock-yystart))>iystop && j<ydots)
  2657. X        put_line(j,xxstart,ixstop,&dstack[xxstart+MAXPIXELS]);
  2658. X     if(keypressed()) return -1;
  2659. X      }
  2660. X   }
  2661. X   return 0;
  2662. X}
  2663. X
  2664. Xstatic void _fastcall plotblock(int buildrow,int x,int y,int color)
  2665. X{
  2666. X   int i,xlim,ylim;
  2667. X   if((xlim=x+halfblock)>ixstop)
  2668. X      xlim=ixstop+1;
  2669. X   if(buildrow>=0 && guessplot==0) /* save it for later put_line */
  2670. X   {
  2671. X      if(buildrow==0)
  2672. X     for(i=x;i<xlim;++i)
  2673. X        dstack[i]=color;
  2674. X      else
  2675. X     for(i=x;i<xlim;++i)
  2676. X        dstack[i+MAXPIXELS]=color;
  2677. X      if (x>=xxstart) /* when x reduced for alignment, paint those dots too */
  2678. X     return; /* the usual case */
  2679. X   }
  2680. X   /* paint it */
  2681. X   if((ylim=y+halfblock)>iystop)
  2682. X   {
  2683. X      if(y>iystop)
  2684. X     return;
  2685. X      ylim=iystop+1;
  2686. X   }
  2687. X   for(i=x;++i<xlim;)
  2688. X      (*plot)(i,y,color); /* skip 1st dot on 1st row */
  2689. X   while(++y<ylim)
  2690. X      for(i=x;i<xlim;++i)
  2691. X     (*plot)(i,y,color);
  2692. X}
  2693. X
  2694. X
  2695. X/************************* symmetry plot setup ************************/
  2696. X
  2697. Xstatic int _fastcall xsym_split(int xaxis_row,int xaxis_between)
  2698. X{
  2699. X   int i;
  2700. X   if ((worksym&0x11) == 0x10) /* already decided not sym */
  2701. X      return(1);
  2702. X   if ((worksym&1) != 0) /* already decided on sym */
  2703. X      iystop = (yystart+yystop)/2;
  2704. X   else /* new window, decide */
  2705. X   {
  2706. X      worksym |= 0x10;
  2707. X      if (xaxis_row <= yystart || xaxis_row >= yystop)
  2708. X     return(1); /* axis not in window */
  2709. X      i = xaxis_row + (xaxis_row - yystart);
  2710. X      if (xaxis_between)
  2711. X     ++i;
  2712. X      if (i > yystop) /* split into 2 pieces, bottom has the symmetry */
  2713. X      {
  2714. X     if (num_worklist >= MAXCALCWORK-1) /* no room to split */
  2715. X        return(1);
  2716. X     iystop = xaxis_row - (yystop - xaxis_row);
  2717. X     if (!xaxis_between)
  2718. X        --iystop;
  2719. X     add_worklist(xxstart,xxstop,iystop+1,yystop,iystop+1,workpass,0);
  2720. X     yystop = iystop;
  2721. X     return(1); /* tell set_symmetry no sym for current window */
  2722. X      }
  2723. X      if (i < yystop) /* split into 2 pieces, top has the symmetry */
  2724. X      {
  2725. X     if (num_worklist >= MAXCALCWORK-1) /* no room to split */
  2726. X        return(1);
  2727. X     add_worklist(xxstart,xxstop,i+1,yystop,i+1,workpass,0);
  2728. X     yystop = i;
  2729. X      }
  2730. X      iystop = xaxis_row;
  2731. X      worksym |= 1;
  2732. X   }
  2733. X   symmetry = 0;
  2734. X   return(0); /* tell set_symmetry its a go */
  2735. X}
  2736. X
  2737. Xstatic int _fastcall ysym_split(int yaxis_col,int yaxis_between)
  2738. X{
  2739. X   int i;
  2740. X   if ((worksym&0x22) == 0x20) /* already decided not sym */
  2741. X      return(1);
  2742. X   if ((worksym&2) != 0) /* already decided on sym */
  2743. X      ixstop = (xxstart+xxstop)/2;
  2744. X   else /* new window, decide */
  2745. X   {
  2746. X      worksym |= 0x20;
  2747. X      if (yaxis_col <= xxstart || yaxis_col >= xxstop)
  2748. X     return(1); /* axis not in window */
  2749. X      i = yaxis_col + (yaxis_col - xxstart);
  2750. X      if (yaxis_between)
  2751. X     ++i;
  2752. X      if (i > xxstop) /* split into 2 pieces, right has the symmetry */
  2753. X      {
  2754. X     if (num_worklist >= MAXCALCWORK-1) /* no room to split */
  2755. X        return(1);
  2756. X     ixstop = yaxis_col - (xxstop - yaxis_col);
  2757. X     if (!yaxis_between)
  2758. X        --ixstop;
  2759. X     add_worklist(ixstop+1,xxstop,yystart,yystop,yystart,workpass,0);
  2760. X     xxstop = ixstop;
  2761. X     return(1); /* tell set_symmetry no sym for current window */
  2762. X      }
  2763. X      if (i < xxstop) /* split into 2 pieces, left has the symmetry */
  2764. X      {
  2765. X     if (num_worklist >= MAXCALCWORK-1) /* no room to split */
  2766. X        return(1);
  2767. X     add_worklist(i+1,xxstop,yystart,yystop,yystart,workpass,0);
  2768. X     xxstop = i;
  2769. X      }
  2770. X      ixstop = yaxis_col;
  2771. X      worksym |= 2;
  2772. X   }
  2773. X   symmetry = 0;
  2774. X   return(0); /* tell set_symmetry its a go */
  2775. X}
  2776. X
  2777. X#ifdef _MSC_VER
  2778. X#pragma optimize ("ea", off)
  2779. X#endif
  2780. X
  2781. Xstatic void _fastcall setsymmetry(int sym, int uselist) /* set up proper symmetrical plot functions */
  2782. X{
  2783. X   extern int forcesymmetry;
  2784. X   int i;
  2785. X   int parmszero;
  2786. X   int xaxis_row, yaxis_col;         /* pixel number for origin */
  2787. X   int xaxis_between, yaxis_between; /* if axis between 2 pixels, not on one */
  2788. X   double ftemp;
  2789. X   symmetry = 1;
  2790. X   TranspSymmetry = sym;         /* for tp3d.c, MCP 6-1-90 */
  2791. X   if(sym == NOPLOT && forcesymmetry == 999)
  2792. X   {
  2793. X      plot = noplot;
  2794. X      return;
  2795. X   }
  2796. X   /* NOTE: 16-bit potential disables symmetry */
  2797. X   /* also any decomp= option and any inversion not about the origin */
  2798. X   /* also any rotation other than 180deg and any off-axis stretch */
  2799. X   if ((potflag && pot16bit) || (invert && inversion[2] != 0.0)
  2800. X       || decomp[0] != 0
  2801. X       || xxmin!=xx3rd || yymin!=yy3rd)
  2802. X      return;
  2803. X   if(sym != XAXIS && sym != XAXIS_NOPARM && inversion[1] != 0.0 && forcesymmetry == 999)
  2804. X      return;
  2805. X   if(forcesymmetry < 999)
  2806. X      sym = forcesymmetry;
  2807. X   else if(forcesymmetry == 1000)
  2808. X      forcesymmetry = sym;  /* for backwards compatibility */
  2809. X   else if(outside==REAL || outside==IMAG || outside==MULT || outside==SUM)
  2810. X      return;
  2811. X   parmszero = (parm.x == 0.0 && parm.y == 0.0 && useinitorbit != 1);
  2812. X   switch (fractype)
  2813. X   { case LMANLAMFNFN:      /* These need only P1 checked. */
  2814. X     case FPMANLAMFNFN:     /* P2 is used for a switch value */
  2815. X     case LMANFNFN:         /* These have NOPARM set in fractalp.c, */
  2816. X     case FPMANFNFN:        /* but it only applies to P1. */
  2817. X     case FPMANDELZPOWER:   /* or P2 is an exponent */
  2818. X     case LMANDELZPOWER:
  2819. X     case FPMANZTOZPLUSZPWR:
  2820. X       break;
  2821. X     default:   /* Check P2 for the rest */
  2822. X       parmszero = (parmszero && parm2.x == 0.0 && parm2.y == 0.0);
  2823. X   }
  2824. X   xaxis_row = yaxis_col = -1;
  2825. X   if (fabs(yymin+yymax) < fabs(yymin)+fabs(yymax)) /* axis is on screen */
  2826. X   {
  2827. X      ftemp = (0.0-yymax) / (yymin-yymax) * (ydots-1) + 0.25;
  2828. X      xaxis_row = ftemp;
  2829. X      xaxis_between = (ftemp - xaxis_row >= 0.5);
  2830. X      if (uselist == 0 && (!xaxis_between || (xaxis_row+1)*2 != ydots))
  2831. X     xaxis_row = -1; /* can't split screen, so dead center or not at all */
  2832. X   }
  2833. X   if (fabs(xxmin+xxmax) < fabs(xxmin)+fabs(xxmax)) /* axis is on screen */
  2834. X   {
  2835. X      ftemp = (0.0-xxmin) / (xxmax-xxmin) * (xdots-1) + 0.25;
  2836. X      yaxis_col = ftemp;
  2837. X      yaxis_between = (ftemp - yaxis_col >= 0.5);
  2838. X      if (uselist == 0 && (!yaxis_between || (yaxis_col+1)*2 != xdots))
  2839. X     yaxis_col = -1; /* can't split screen, so dead center or not at all */
  2840. X   }
  2841. X   switch(sym)         /* symmetry switch */
  2842. X   {
  2843. X   case XAXIS_NOREAL:     /* X-axis Symmetry (no real param) */
  2844. X      if (parm.x != 0.0) break;
  2845. X      goto xsym;
  2846. X   case XAXIS_NOIMAG:     /* X-axis Symmetry (no imag param) */
  2847. X      if (parm.y != 0.0) break;
  2848. X      goto xsym;
  2849. X   case XAXIS_NOPARM:                 /* X-axis Symmetry  (no params)*/
  2850. X      if (!parmszero)
  2851. X     break;
  2852. X      xsym:
  2853. X   case XAXIS:                 /* X-axis Symmetry */
  2854. X      if (xsym_split(xaxis_row,xaxis_between) == 0)
  2855. X     if(basin)
  2856. X        plot = symplot2basin;
  2857. X     else
  2858. X        plot = symplot2;
  2859. X      break;
  2860. X   case YAXIS_NOPARM:                 /* Y-axis Symmetry (No Parms)*/
  2861. X      if (!parmszero)
  2862. X     break;
  2863. X   case YAXIS:                 /* Y-axis Symmetry */
  2864. X      if (ysym_split(yaxis_col,yaxis_between) == 0)
  2865. X     plot = symplot2Y;
  2866. X      break;
  2867. X   case XYAXIS_NOPARM:                 /* X-axis AND Y-axis Symmetry (no parms)*/
  2868. X      if(!parmszero)
  2869. X     break;
  2870. X   case XYAXIS:              /* X-axis AND Y-axis Symmetry */
  2871. X      xsym_split(xaxis_row,xaxis_between);
  2872. X      ysym_split(yaxis_col,yaxis_between);
  2873. X      switch (worksym & 3)
  2874. X      {
  2875. X      case 1: /* just xaxis symmetry */
  2876. X     if(basin)
  2877. X        plot = symplot2basin;
  2878. X     else
  2879. X        plot = symplot2 ;
  2880. X     break;
  2881. X      case 2: /* just yaxis symmetry */
  2882. X     if (basin) /* got no routine for this case */
  2883. X     {
  2884. X        ixstop = xxstop; /* fix what split should not have done */
  2885. X        symmetry = 1;
  2886. X     }
  2887. X     else
  2888. X        plot = symplot2Y;
  2889. X     break;
  2890. X      case 3: /* both axes */
  2891. X     if(basin)
  2892. X        plot = symplot4basin;
  2893. X     else
  2894. X        plot = symplot4 ;
  2895. X      }
  2896. X      break;
  2897. X   case ORIGIN_NOPARM:                 /* Origin Symmetry (no parms)*/
  2898. X      if (!parmszero)
  2899. X     break;
  2900. X   case ORIGIN:              /* Origin Symmetry */
  2901. X      originsym:
  2902. X      if ( xsym_split(xaxis_row,xaxis_between) == 0
  2903. X      && ysym_split(yaxis_col,yaxis_between) == 0)
  2904. X      {
  2905. X     plot = symplot2J;
  2906. X     ixstop = xxstop; /* didn't want this changed */
  2907. X      }
  2908. X      else
  2909. X      {
  2910. X     iystop = yystop; /* in case first split worked */
  2911. X     symmetry = 1;
  2912. X     worksym = 0x30; /* let it recombine with others like it */
  2913. X      }
  2914. X      break;
  2915. X   case PI_SYM_NOPARM:
  2916. X      if (!parmszero)
  2917. X     break;
  2918. X   case PI_SYM:              /* PI symmetry */
  2919. X      if(fabs(xxmax - xxmin) < PI/4)   
  2920. X         break; /* no point in pi symmetry if values too close */
  2921. X      if(invert && forcesymmetry == 999)
  2922. X     goto originsym;
  2923. X      plot = symPIplot ;
  2924. X      symmetry = 0;
  2925. X      if ( xsym_split(xaxis_row,xaxis_between) == 0
  2926. X      && ysym_split(yaxis_col,yaxis_between) == 0)
  2927. X     if(parm.y == 0.0)
  2928. X        plot = symPIplot4J; /* both axes */
  2929. X     else
  2930. X        plot = symPIplot2J; /* origin */
  2931. X      else
  2932. X      {
  2933. X     iystop = yystop; /* in case first split worked */
  2934. X     worksym = 0x30;  /* don't mark pisym as ysym, just do it unmarked */
  2935. X      }
  2936. X      pixelpi = (PI/fabs(xxmax-xxmin))*xdots; /* PI in pixels */
  2937. X      if ( (ixstop = xxstart+pixelpi-1 ) > xxstop)
  2938. X     ixstop = xxstop;
  2939. X      if (plot == symPIplot4J && ixstop > (i = (xxstart+xxstop)/2))
  2940. X     ixstop = i;
  2941. X      break;
  2942. X   default:             /* no symmetry */
  2943. X      break;
  2944. X   }
  2945. X}
  2946. X
  2947. X#ifdef _MSC_VER
  2948. X#pragma optimize ("ea", on)
  2949. X#endif
  2950. X
  2951. X/**************** tesseral method by CJLT begins here*********************/
  2952. X/*  reworked by PB for speed and resumeability */
  2953. X
  2954. Xstruct tess { /* one of these per box to be done gets stacked */
  2955. X   int x1,x2,y1,y2;     /* left/right top/bottom x/y coords  */
  2956. X   int top,bot,lft,rgt;  /* edge colors, -1 mixed, -2 unknown */
  2957. X};
  2958. X
  2959. Xstatic int tesseral()
  2960. X{
  2961. X   register struct tess *tp;
  2962. X
  2963. X   guessplot = (plot != putcolor && plot != symplot2);
  2964. X   tp = (struct tess *)&dstack[0];
  2965. X   tp->x1 = ixstart;                  /* set up initial box */
  2966. X   tp->x2 = ixstop;
  2967. X   tp->y1 = iystart;
  2968. X   tp->y2 = iystop;
  2969. X
  2970. X   if (workpass == 0) { /* not resuming */
  2971. X      tp->top = tessrow(ixstart,ixstop,iystart);     /* Do top row */
  2972. X      tp->bot = tessrow(ixstart,ixstop,iystop);      /* Do bottom row */
  2973. X      tp->lft = tesscol(ixstart,iystart+1,iystop-1); /* Do left column */
  2974. X      tp->rgt = tesscol(ixstop,iystart+1,iystop-1);  /* Do right column */
  2975. X      if (check_key()) { /* interrupt before we got properly rolling */
  2976. X         add_worklist(xxstart,xxstop,yystart,yystop,yystart,0,worksym);
  2977. X         return(-1);
  2978. X      }
  2979. X   }
  2980. X
  2981. X   else { /* resuming, rebuild work stack */
  2982. X      int i,mid,curx,cury,xsize,ysize;
  2983. X      struct tess *tp2;
  2984. X      tp->top = tp->bot = tp->lft = tp->rgt = -2;
  2985. X      cury = yybegin & 0xfff;
  2986. X      ysize = 1;
  2987. X      i = (unsigned)yybegin >> 12;
  2988. X      while (--i >= 0) ysize <<= 1;
  2989. X      curx = workpass & 0xfff;
  2990. X      xsize = 1;
  2991. X      i = (unsigned)workpass >> 12;
  2992. X      while (--i >= 0) xsize <<= 1;
  2993. X      while (1) {
  2994. X         tp2 = tp;
  2995. X         if (tp->x2 - tp->x1 > tp->y2 - tp->y1) { /* next divide down middle */
  2996. X            if (tp->x1 == curx && (tp->x2 - tp->x1 - 2) < xsize)
  2997. X               break;
  2998. X            mid = (tp->x1 + tp->x2) >> 1;         /* Find mid point */
  2999. X            if (mid > curx) { /* stack right part */
  3000. X               memcpy(++tp,tp2,sizeof(*tp));
  3001. X               tp->x2 = mid;
  3002. X            }
  3003. X            tp2->x1 = mid;
  3004. X         }
  3005. X         else {                   /* next divide across */
  3006. X            if (tp->y1 == cury && (tp->y2 - tp->y1 - 2) < ysize) break;
  3007. X            mid = (tp->y1 + tp->y2) >> 1;         /* Find mid point */
  3008. X            if (mid > cury) { /* stack bottom part */
  3009. X               memcpy(++tp,tp2,sizeof(*tp));
  3010. X               tp->y2 = mid;
  3011. X            }
  3012. X            tp2->y1 = mid;
  3013. X         }
  3014. X      }
  3015. X   }
  3016. X
  3017. X   got_status = 4; /* for tab_display */
  3018. X
  3019. X   while (tp >= (struct tess *)&dstack[0]) { /* do next box */
  3020. X      curcol = tp->x1; /* for tab_display */
  3021. X      currow = tp->y1;
  3022. X
  3023. X      if (tp->top == -1 || tp->bot == -1 || tp->lft == -1 || tp->rgt == -1)
  3024. X         goto tess_split;
  3025. X      /* for any edge whose color is unknown, set it */
  3026. X      if (tp->top == -2)
  3027. X         tp->top = tesschkrow(tp->x1,tp->x2,tp->y1);
  3028. X      if (tp->top == -1)
  3029. X         goto tess_split;
  3030. X      if (tp->bot == -2)
  3031. X         tp->bot = tesschkrow(tp->x1,tp->x2,tp->y2);
  3032. X      if (tp->bot != tp->top)
  3033. X         goto tess_split;
  3034. X      if (tp->lft == -2)
  3035. X         tp->lft = tesschkcol(tp->x1,tp->y1,tp->y2);
  3036. X      if (tp->lft != tp->top)
  3037. X         goto tess_split;
  3038. X      if (tp->rgt == -2)
  3039. X         tp->rgt = tesschkcol(tp->x2,tp->y1,tp->y2);
  3040. X      if (tp->rgt != tp->top)
  3041. X         goto tess_split;
  3042. X
  3043. X      {
  3044. X      int mid,midcolor;
  3045. X      if (tp->x2 - tp->x1 > tp->y2 - tp->y1) { /* divide down the middle */
  3046. X         mid = (tp->x1 + tp->x2) >> 1;         /* Find mid point */
  3047. X         midcolor = tesscol(mid, tp->y1+1, tp->y2-1); /* Do mid column */
  3048. X         if (midcolor != tp->top) goto tess_split;
  3049. X         }
  3050. X      else {                   /* divide across the middle */
  3051. X         mid = (tp->y1 + tp->y2) >> 1;         /* Find mid point */
  3052. X         midcolor = tessrow(tp->x1+1, tp->x2-1, mid); /* Do mid row */
  3053. X         if (midcolor != tp->top) goto tess_split;
  3054. X         }
  3055. X      }
  3056. X
  3057. X      {  /* all 4 edges are the same color, fill in */
  3058. X         int i,j;
  3059. X         i = 0;
  3060. X         if(fillcolor != 0)
  3061. X         {
  3062. X         if(fillcolor > 0)
  3063. X            tp->top = fillcolor & (colors-1);
  3064. X         if (guessplot || (j = tp->x2 - tp->x1 - 1) < 2) { /* paint dots */
  3065. X            for (col = tp->x1 + 1; col < tp->x2; col++)
  3066. X               for (row = tp->y1 + 1; row < tp->y2; row++) {
  3067. X                  (*plot)(col,row,tp->top);
  3068. X                  if (++i > 500) {
  3069. X                     if (check_key()) goto tess_end;
  3070. X                     i = 0;
  3071. X                  }
  3072. X               }
  3073. X         }
  3074. X         else { /* use put_line for speed */
  3075. X            memset(&dstack[MAXPIXELS],tp->top,j);
  3076. X            for (row = tp->y1 + 1; row < tp->y2; row++) {
  3077. X               put_line(row,tp->x1+1,tp->x2-1,&dstack[MAXPIXELS]);
  3078. X               if (plot != putcolor) /* symmetry */
  3079. X                  if ((j = yystop-(row-yystart)) > iystop && j < ydots)
  3080. X                     put_line(j,tp->x1+1,tp->x2-1,&dstack[MAXPIXELS]);
  3081. X               if (++i > 25) {
  3082. X                  if (check_key()) goto tess_end;
  3083. X                  i = 0;
  3084. X               }
  3085. X            }
  3086. X         }
  3087. X         }
  3088. X         --tp;
  3089. X      }
  3090. X      continue;
  3091. X
  3092. X      tess_split:
  3093. X      {  /* box not surrounded by same color, sub-divide */
  3094. X         int mid,midcolor;
  3095. X         struct tess *tp2;
  3096. X         if (tp->x2 - tp->x1 > tp->y2 - tp->y1) { /* divide down the middle */
  3097. X            mid = (tp->x1 + tp->x2) >> 1;         /* Find mid point */
  3098. X            midcolor = tesscol(mid, tp->y1+1, tp->y2-1); /* Do mid column */
  3099. X            if (midcolor == -3) goto tess_end;
  3100. X            if (tp->x2 - mid > 1) {    /* right part >= 1 column */
  3101. X               if (tp->top == -1) tp->top = -2;
  3102. X               if (tp->bot == -1) tp->bot = -2;
  3103. X               tp2 = tp;
  3104. X               if (mid - tp->x1 > 1) { /* left part >= 1 col, stack right */
  3105. X                  memcpy(++tp,tp2,sizeof(*tp));
  3106. X                  tp->x2 = mid;
  3107. X                  tp->rgt = midcolor;
  3108. X               }
  3109. X               tp2->x1 = mid;
  3110. X               tp2->lft = midcolor;
  3111. X            }
  3112. X            else
  3113. X               --tp;
  3114. X         }
  3115. X         else {                   /* divide across the middle */
  3116. X            mid = (tp->y1 + tp->y2) >> 1;         /* Find mid point */
  3117. X            midcolor = tessrow(tp->x1+1, tp->x2-1, mid); /* Do mid row */
  3118. X            if (midcolor == -3) goto tess_end;
  3119. X            if (tp->y2 - mid > 1) {    /* bottom part >= 1 column */
  3120. X               if (tp->lft == -1) tp->lft = -2;
  3121. X               if (tp->rgt == -1) tp->rgt = -2;
  3122. X               tp2 = tp;
  3123. X               if (mid - tp->y1 > 1) { /* top also >= 1 col, stack bottom */
  3124. X                  memcpy(++tp,tp2,sizeof(*tp));
  3125. X                  tp->y2 = mid;
  3126. X                  tp->bot = midcolor;
  3127. X               }
  3128. X               tp2->y1 = mid;
  3129. X               tp2->top = midcolor;
  3130. X            }
  3131. X            else
  3132. X               --tp;
  3133. X         }
  3134. X      }
  3135. X
  3136. X   }
  3137. X
  3138. X   tess_end:
  3139. X   if (tp >= (struct tess *)&dstack[0]) { /* didn't complete */
  3140. X      int i,xsize,ysize;
  3141. X      xsize = ysize = 1;
  3142. X      i = 2;
  3143. X      while (tp->x2 - tp->x1 - 2 >= i) {
  3144. X         i <<= 1;
  3145. X         ++xsize;
  3146. X      }
  3147. X      i = 2;
  3148. X      while (tp->y2 - tp->y1 - 2 >= i) {
  3149. X         i <<= 1;
  3150. X         ++ysize;
  3151. X      }
  3152. X      add_worklist(xxstart,xxstop,yystart,yystop,
  3153. X          (ysize<<12)+tp->y1,(xsize<<12)+tp->x1,worksym);
  3154. X      return(-1);
  3155. X   }
  3156. X   return(0);
  3157. X
  3158. X} /* tesseral */
  3159. X
  3160. Xstatic int _fastcall tesschkcol(int x,int y1,int y2)
  3161. X{
  3162. X   int i;
  3163. X   i = getcolor(x,++y1);
  3164. X   while (--y2 > y1)
  3165. X      if (getcolor(x,y2) != i) return -1;
  3166. X   return i;
  3167. X}
  3168. X
  3169. Xstatic int _fastcall tesschkrow(int x1,int x2,int y)
  3170. X{
  3171. X   int i;
  3172. X   i = getcolor(x1,y);
  3173. X   while (x2 > x1) {
  3174. X      if (getcolor(x2,y) != i) return -1;
  3175. X      --x2;
  3176. X   }
  3177. X   return i;
  3178. X}
  3179. X
  3180. Xstatic int _fastcall tesscol(int x,int y1,int y2)
  3181. X{
  3182. X   int colcolor,i;
  3183. X   col = x;
  3184. X   row = y1;
  3185. X   reset_periodicity = 1;
  3186. X   colcolor = (*calctype)();
  3187. X   reset_periodicity = 0;
  3188. X   while (++row <= y2) { /* generate the column */
  3189. X      if ((i = (*calctype)()) < 0) return -3;
  3190. X      if (i != colcolor) colcolor = -1;
  3191. X   }
  3192. X   return colcolor;
  3193. X}
  3194. X
  3195. Xstatic int _fastcall tessrow(int x1,int x2,int y)
  3196. X{
  3197. X   int rowcolor,i;
  3198. X   row = y;
  3199. X   col = x1;
  3200. X   reset_periodicity = 1;
  3201. X   rowcolor = (*calctype)();
  3202. X   reset_periodicity = 0;
  3203. X   while (++col <= x2) { /* generate the row */
  3204. X      if ((i = (*calctype)()) < 0) return -3;
  3205. X      if (i != rowcolor) rowcolor = -1;
  3206. X   }
  3207. X   return rowcolor;
  3208. X}
  3209. X
  3210. X/* added for testing autologmap() */ /* CAE 9211 fixed missing comment */
  3211. X/* insert at end of CALCFRAC.C */
  3212. X
  3213. Xstatic int autologmap()   /*RB*/
  3214. X{  /* calculate round screen edges to avoid wasted colours in logmap */
  3215. X int mincolour,lag;
  3216. X mincolour=32767;
  3217. X row=iystart;
  3218. X reset_periodicity = 0;
  3219. X for (col=ixstart;col<ixstop;col++) /* top row */
  3220. X    {
  3221. X      color=(*calctype)();
  3222. X      if (realcolor < mincolour) mincolour=realcolor ;
  3223. X      if ( col >=32 ) (*plot)(col-32,row,0);
  3224. X    }                                    /* these lines tidy up for BTM etc */
  3225. X    for (lag=32;lag>0;lag--) (*plot)(col-lag,row,0);
  3226. X
  3227. X col=ixstop;
  3228. X for (row=iystart;row<iystop;row++) /* right  side */
  3229. X    {
  3230. X      color=(*calctype)();
  3231. X      if (realcolor < mincolour) mincolour=realcolor ;
  3232. X      if ( row >=32 ) (*plot)(col,row-32,0);
  3233. X    }
  3234. X    for (lag=32;lag>0;lag--) (*plot)(col,row-lag,0);
  3235. X
  3236. X col=ixstart;
  3237. X for (row=iystart;row<iystop;row++) /* left  side */
  3238. X    {
  3239. X      color=(*calctype)();
  3240. X      if (realcolor < mincolour) mincolour=realcolor ;
  3241. X      if ( row >=32 ) (*plot)(col,row-32,0);
  3242. X    }
  3243. X    for (lag=32;lag>0;lag--) (*plot)(col,row-lag,0);
  3244. X
  3245. X row=iystop ;
  3246. X for (col=ixstart;col<ixstop;col++) /* bottom row */
  3247. X    {
  3248. X      color=(*calctype)();
  3249. X      if (realcolor < mincolour) mincolour=realcolor ;
  3250. X      if ( col >=32 ) (*plot)(col-32,row,0);
  3251. X    }
  3252. X    for (lag=32;lag>0;lag--) (*plot)(col-lag,row,0);
  3253. X
  3254. X if (mincolour==2) resuming=1; /* insure autologmap not called again */
  3255. X
  3256. X return mincolour;
  3257. X}
  3258. X
  3259. X/* Symmetry plot for period PI */
  3260. Xvoid _fastcall symPIplot(x, y, color)
  3261. Xint x, y, color ;
  3262. X{
  3263. X   while(x <= xxstop)
  3264. X   {
  3265. X      putcolor(x, y, color) ;
  3266. X      x += pixelpi;
  3267. X   }
  3268. X}
  3269. X/* Symmetry plot for period PI plus Origin Symmetry */
  3270. Xvoid _fastcall symPIplot2J(x, y, color)
  3271. Xint x, y, color ;
  3272. X{
  3273. X   int i,j;
  3274. X   while(x <= xxstop)
  3275. X   {
  3276. X      putcolor(x, y, color) ;
  3277. X      if ((i=yystop-(y-yystart)) > iystop && i < ydots
  3278. X      && (j=xxstop-(x-xxstart)) < xdots)
  3279. X     putcolor(j, i, color) ;
  3280. X      x += pixelpi;
  3281. X   }
  3282. X}
  3283. X/* Symmetry plot for period PI plus Both Axis Symmetry */
  3284. Xvoid _fastcall symPIplot4J(x, y, color)
  3285. Xint x, y, color ;
  3286. X{
  3287. X   int i,j;
  3288. X   while(x <= (xxstart+xxstop)/2)
  3289. X   {
  3290. X      j = xxstop-(x-xxstart);
  3291. X      putcolor(       x , y , color) ;
  3292. X      if (j < xdots)
  3293. X     putcolor(j , y , color) ;
  3294. X      if ((i=yystop-(y-yystart)) > iystop && i < ydots)
  3295. X      {
  3296. X     putcolor(x , i , color) ;
  3297. X     if (j < xdots)
  3298. X        putcolor(j , i , color) ;
  3299. X      }
  3300. X      x += pixelpi;
  3301. X   }
  3302. X}
  3303. X
  3304. X/* Symmetry plot for X Axis Symmetry */
  3305. Xvoid _fastcall symplot2(x, y, color)
  3306. Xint x, y, color ;
  3307. X{
  3308. X   int i;
  3309. X   putcolor(x, y, color) ;
  3310. X   if ((i=yystop-(y-yystart)) > iystop && i < ydots)
  3311. X      putcolor(x, i, color) ;
  3312. X}
  3313. X
  3314. X/* Symmetry plot for Y Axis Symmetry */
  3315. Xvoid _fastcall symplot2Y(x, y, color)
  3316. Xint x, y, color ;
  3317. X{
  3318. X   int i;
  3319. X   putcolor(x, y, color) ;
  3320. X   if ((i=xxstop-(x-xxstart)) < xdots)
  3321. X      putcolor(i, y, color) ;
  3322. X}
  3323. X
  3324. X/* Symmetry plot for Origin Symmetry */
  3325. Xvoid _fastcall symplot2J(x, y, color)
  3326. Xint x, y, color ;
  3327. X{
  3328. X   int i,j;
  3329. X   putcolor(x, y, color) ;
  3330. X   if ((i=yystop-(y-yystart)) > iystop && i < ydots
  3331. X       && (j=xxstop-(x-xxstart)) < xdots)
  3332. X      putcolor(j, i, color) ;
  3333. X}
  3334. X
  3335. X/* Symmetry plot for Both Axis Symmetry */
  3336. Xvoid _fastcall symplot4(x, y, color)
  3337. Xint x, y, color ;
  3338. X{
  3339. X   int i,j;
  3340. X   j = xxstop-(x-xxstart);
  3341. X   putcolor(       x , y, color) ;
  3342. X   if (j < xdots)
  3343. X      putcolor(    j , y, color) ;
  3344. X   if ((i=yystop-(y-yystart)) > iystop && i < ydots)
  3345. X   {
  3346. X      putcolor(    x , i, color) ;
  3347. X      if (j < xdots)
  3348. X     putcolor(j , i, color) ;
  3349. X   }
  3350. X}
  3351. X
  3352. X/* Symmetry plot for X Axis Symmetry - Striped Newtbasin version */
  3353. Xvoid _fastcall symplot2basin(x, y, color)
  3354. Xint x, y, color ;
  3355. X{
  3356. X   int i,stripe;
  3357. X   extern int degree;
  3358. X   putcolor(x, y, color) ;
  3359. X   if(basin==2 && color > 8)
  3360. X      stripe=8;
  3361. X   else
  3362. X      stripe = 0;
  3363. X   if ((i=yystop-(y-yystart)) > iystop && i < ydots)
  3364. X   {
  3365. X      color -= stripe;              /* reconstruct unstriped color */
  3366. X      color = (degree+1-color)%degree+1;  /* symmetrical color */
  3367. X      color += stripe;              /* add stripe */
  3368. X      putcolor(x, i,color)  ;
  3369. X   }
  3370. X}
  3371. X
  3372. X/* Symmetry plot for Both Axis Symmetry  - Newtbasin version */
  3373. Xvoid _fastcall symplot4basin(x, y, color)
  3374. Xint x, y, color ;
  3375. X{
  3376. X   extern int degree;
  3377. X   int i,j,color1,stripe;
  3378. X   if(color == 0) /* assumed to be "inside" color */
  3379. X   {
  3380. X      symplot4(x, y, color);
  3381. X      return;
  3382. X   }
  3383. X   if(basin==2 && color > 8)
  3384. X      stripe = 8;
  3385. X   else
  3386. X      stripe = 0;
  3387. X   color -= stripe;          /* reconstruct unstriped color */
  3388. X   color1 = degree/2+degree+2 - color;
  3389. X   if(color < degree/2+2)
  3390. X      color1 = degree/2+2 - color;
  3391. X   else
  3392. X      color1 = degree/2+degree+2 - color;
  3393. X   j = xxstop-(x-xxstart);
  3394. X   putcolor(       x, y, color+stripe) ;
  3395. X   if (j < xdots)
  3396. X      putcolor(    j, y, color1+stripe) ;
  3397. X   if ((i=yystop-(y-yystart)) > iystop && i < ydots)
  3398. X   {
  3399. X      putcolor(    x, i, stripe + (degree+1 - color)%degree+1) ;
  3400. X      if (j < xdots)
  3401. X     putcolor(j, i, stripe + (degree+1 - color1)%degree+1) ;
  3402. X   }
  3403. X}
  3404. X
  3405. X/* Do nothing plot!!! */
  3406. Xvoid _fastcall noplot(int x,int y,int color)
  3407. X{
  3408. X}
  3409. SHAR_EOF
  3410. $TOUCH -am 1028230093 calcfrac.c &&
  3411. chmod 0644 calcfrac.c ||
  3412. echo "restore of calcfrac.c failed"
  3413. set `wc -c calcfrac.c`;Wc_c=$1
  3414. if test "$Wc_c" != "84436"; then
  3415.     echo original size 84436, current size $Wc_c
  3416. fi
  3417. # ============= cmdfiles.c ==============
  3418. echo "x - extracting cmdfiles.c (Text)"
  3419. sed 's/^X//' << 'SHAR_EOF' > cmdfiles.c &&
  3420. X/*
  3421. X    Command-line / Command-File Parser Routines
  3422. X    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  3423. X*/
  3424. X
  3425. X#include <stdlib.h>
  3426. X#include <stdio.h>
  3427. X#include <string.h>
  3428. X#include <float.h>
  3429. X#include <ctype.h>
  3430. X#include <time.h>
  3431. X#ifndef XFRACT
  3432. X#include <bios.h>
  3433. X#endif
  3434. X#include "fractint.h"
  3435. X#include "fractype.h"
  3436. X#ifdef __TURBOC__
  3437. X#include <dir.h>
  3438. X#endif
  3439. X#include "prototyp.h"
  3440. X
  3441. X#ifdef XFRACT
  3442. X#define DEFAULT_PRINTER 5    /* Assume a Postscript printer */
  3443. X#define PRT_RESOLUTION  100    /* Assume medium resolution    */
  3444. X#define INIT_GIF87      0    /* Turn on GIF 89a processing  */
  3445. X#else
  3446. X#define DEFAULT_PRINTER 2    /* Assume an IBM/Epson printer */
  3447. X#define PRT_RESOLUTION  60    /* Assume low resolution       */
  3448. X#define INIT_GIF87      0    /* Turn on GIF 89a processing  */
  3449. X#endif
  3450. X
  3451. Xstatic int  cmdfile(FILE *,int);
  3452. Xstatic int  next_command(char *,int,FILE *,char *,int *,int);
  3453. Xstatic int  next_line(FILE *,char *,int);
  3454. Xint  cmdarg(char *,int);
  3455. Xstatic void argerror(char *);
  3456. Xstatic void initvars_run(void);
  3457. Xstatic void initvars_restart(void);
  3458. Xstatic void initvars_fractal(void);
  3459. Xstatic void initvars_3d(void);
  3460. Xstatic void reset_ifs_defn(void);
  3461. Xstatic void parse_textcolors(char *value);
  3462. Xstatic int  parse_colors(char *value);
  3463. Xstatic int  parse_printer(char *value);
  3464. X
  3465. X/* variables defined by the command line/files processor */
  3466. Xint        showdot;    /* color to show crawling graphics cursor */
  3467. Xchar    temp1[256];        /* temporary strings        */
  3468. Xchar    readname[80];        /* name of fractal input file */
  3469. Xchar    gifmask[13] = {""};
  3470. Xchar    PrintName[80]={"fract001.prn"}; /* Name for print-to-file */
  3471. Xchar    savename[80]={"fract001"};      /* save files using this name */
  3472. Xchar    autoname[80]={"auto.key"};      /* record auto keystrokes here */
  3473. Xint    potflag=0;        /* continuous potential enabled? */
  3474. Xint    pot16bit;        /* store 16 bit continuous potential values */
  3475. Xint    gif87a_flag;        /* 1 if GIF87a format, 0 otherwise */
  3476. Xint     dither_flag;        /* 1 if want to dither GIFs */
  3477. Xint    askvideo;        /* flag for video prompting */
  3478. Xchar    floatflag;
  3479. Xint    biomorph;        /* flag for biomorph */
  3480. Xint    usr_biomorph;
  3481. Xint    forcesymmetry;        /* force symmetry */
  3482. Xint    showfile;        /* zero if file display pending */
  3483. Xint    rflag, rseed;        /* Random number seeding flag and value */
  3484. Xint    decomp[2];        /* Decomposition coloring */
  3485. Xint    distest;
  3486. Xint    distestwidth;
  3487. Xchar overwrite = 0;    /* 0 if file overwrite not allowed */
  3488. Xint    soundflag;        /* 0 if sound is off, 1 if on */
  3489. Xint    basehertz;        /* sound=x/y/x hertz value */
  3490. Xint    debugflag;        /* internal use only - you didn't see this */
  3491. Xint    timerflag;        /* you didn't see this, either */
  3492. Xint    cyclelimit;        /* color-rotator upper limit */
  3493. Xint    inside;         /* inside color: 1=blue     */
  3494. Xint    fillcolor;         /* fillcolor: -1=normal     */
  3495. Xint    outside;        /* outside color    */
  3496. Xint    finattract;        /* finite attractor logic */
  3497. Xint    display3d;        /* 3D display flag: 0 = OFF */
  3498. Xint    overlay3d;        /* 3D overlay flag: 0 = OFF */
  3499. Xint    init3d[20];        /* '3d=nn/nn/nn/...' values */
  3500. Xint    initbatch;        /* 1 if batch run (no kbd)  */
  3501. Xunsigned initsavetime;        /* autosave minutes        */
  3502. Xdouble    initorbit[2];        /* initial orbitvalue */
  3503. Xchar    useinitorbit;        /* flag for initorbit */
  3504. Xint    initmode;        /* initial video mode        */
  3505. Xint    initcyclelimit;     /* initial cycle limit        */
  3506. XBYTE usemag;        /* use center-mag corners   */
  3507. Xint    bailout;        /* user input bailout value */
  3508. Xdouble    inversion[3];        /* radius, xcenter, ycenter */
  3509. Xint    rotate_lo,rotate_hi;    /* cycling color range        */
  3510. Xint far *ranges;        /* iter->color ranges mapping */
  3511. Xint    rangeslen = 0;        /* size of ranges array     */
  3512. Xchar far *mapdacbox = NULL;    /* map= (default colors)    */
  3513. Xint    colorstate;        /* 0, dacbox matches default (bios or map=) */
  3514. X                /* 1, dacbox matches no known defined map   */
  3515. X                /* 2, dacbox matches the colorfile map        */
  3516. Xint    colorpreloaded;     /* if dacbox preloaded for next mode select */
  3517. Xint     save_release;        /* release creating PAR file*/
  3518. X
  3519. Xextern int calc_status;
  3520. Xextern int Targa_Overlay;
  3521. Xint Targa_Out = 0;
  3522. Xchar    colorfile[80];        /* from last <l> <s> or colors=@filename    */
  3523. Xint functionpreloaded; /* if function loaded for new bifs, JCO 7/5/92 */
  3524. Xfloat    screenaspect = DEFAULTASPECT;    /* aspect ratio of the screen */
  3525. X
  3526. X/* TARGA+ variables */
  3527. Xint    TPlusFlag;        /* Use the TARGA+ if found  */
  3528. Xint    MaxColorRes;        /* Default Color Resolution if available */
  3529. Xint    PixelZoom;        /* TPlus Zoom Level */
  3530. Xint    NonInterlaced;        /* Non-Interlaced video flag */
  3531. X
  3532. X/* 3D Transparency Variables, MCP 5-30-91 */
  3533. Xdouble xcoord, ycoord, zcoord, tcoord;
  3534. Xdouble zzmin, zzmax;        /* initial depth corner values */
  3535. Xdouble ttmin, ttmax;        /* initial time coordinates */
  3536. Xint Transparent3D, SolidCore, MultiDrawing;
  3537. Xint tpdepth, tptime;
  3538. Xunsigned CoreRed, CoreGreen, CoreBlue, NumFrames;
  3539. X
  3540. X/* AntiAliasing variables, MCP 6-6-91 */
  3541. Xint AntiAliasing, Shadowing;
  3542. X
  3543. X/* Julibrot variables TIW 1/24/93 */
  3544. Xextern double mxmaxfp, mxminfp, mymaxfp, myminfp, originfp;
  3545. Xextern double depthfp, heightfp, widthfp, distfp, eyesfp;
  3546. Xextern int zdots; 
  3547. X
  3548. Xextern int lastorbittype, neworbittype;
  3549. Xextern char *juli3Doptions[];
  3550. Xextern int juli3Dmode;
  3551. Xextern struct moreparams far moreparams[];
  3552. X
  3553. X/* inverse julia methods. MVS 3/15/93 */
  3554. Xextern int major_method;
  3555. Xextern int minor_method;
  3556. X
  3557. Xint    orbitsave = 0;        /* for IFS and LORENZ to output acrospin file */
  3558. Xint orbit_delay;                /* clock ticks delating orbit release */
  3559. Xextern    int invert;
  3560. Xextern int fractype;        /* fractal type         */
  3561. Xextern double param[];         /* initial parameters        */
  3562. Xextern double xxmin,xxmax;    /* initial corner values    */
  3563. Xextern double yymin,yymax;    /* initial corner values    */
  3564. Xextern double xx3rd,yy3rd;    /* initial corner values    */
  3565. Xextern char usr_stdcalcmode;    /* '1', '2', 'g', 'b'       */
  3566. Xextern int maxit;        /* max iterations        */
  3567. Xextern int usr_periodicitycheck; /* periodicity checking  1=on,0=off */
  3568. Xextern char usr_floatflag;    /* flag for float calcs */
  3569. Xextern int usr_distest;     /* nonzero if distance estimator option */
  3570. Xextern char color_lakes;    /* finite attractor flag */
  3571. Xextern int haze;
  3572. Xextern int RANDOMIZE;
  3573. Xextern int Ambient;
  3574. Xextern char light_name[];
  3575. Xextern int BRIEF;
  3576. Xextern int RAY;
  3577. Xextern int release;
  3578. X
  3579. Xextern BYTE back_color[];
  3580. Xextern BYTE dacbox[256][3];
  3581. Xextern struct videoinfo far videotable[];
  3582. Xextern int fpu;
  3583. Xextern int iit;
  3584. X
  3585. Xextern double potparam[];    /* potential parameters  */
  3586. Xextern int Printer_Resolution, LPTNumber,
  3587. X       Printer_Type, Printer_Titleblock,
  3588. X       Printer_ColorXlat, Printer_SetScreen,
  3589. X       Printer_SFrequency, Printer_SAngle, Printer_SStyle,
  3590. X       Printer_RFrequency, Printer_RAngle, Printer_RStyle,
  3591. X       Printer_GFrequency, Printer_GAngle, Printer_GStyle,
  3592. X       Printer_BFrequency, Printer_BAngle, Printer_BStyle,
  3593. X       Printer_Compress,
  3594. X       EPSFileType, ColorPS,
  3595. X       Print_To_File,Printer_CRLF;        /* for printer functions */
  3596. X
  3597. Xint    transparent[2];     /* transparency min/max values */
  3598. Xint    LogFlag;        /* Logarithmic palette flag: 0 = no */
  3599. X
  3600. XBYTE exitmode = 3;    /* video mode on exit */
  3601. X
  3602. Xextern int video_type;
  3603. Xextern int svga_type;           /* for forcing a specific SVGA adapter */
  3604. Xextern int mode7text;
  3605. Xextern int textsafe;
  3606. Xextern int vesa_detect;
  3607. Xchar    ai_8514;    /* Flag for using 8514a afi JCO 4/11/92 */
  3608. X
  3609. Xint        bios_palette;        /* set to 1 to force BIOS palette updates */
  3610. Xint        escape_exit;         /* set to 1 to avoid the "are you sure?" screen */
  3611. X
  3612. Xextern int   viewwindow;
  3613. Xextern float viewreduction;
  3614. Xextern int   viewcrop;
  3615. Xextern float finalaspectratio;
  3616. Xextern int   viewxdots,viewydots;
  3617. X
  3618. Xextern char MAP_name[];
  3619. Xextern int mapset;
  3620. X
  3621. Xextern int eyeseparation; /* Occular Separation */
  3622. Xextern int glassestype;
  3623. Xextern int xadjust; /* Convergence */
  3624. Xextern int yadjust;
  3625. Xextern int xtrans, ytrans; /* X,Y shift with no perspective */
  3626. Xextern int red_crop_left, red_crop_right;
  3627. Xextern int blue_crop_left, blue_crop_right;
  3628. Xextern int red_bright, blue_bright;
  3629. Xextern char showbox; /* flag to show box and vector in preview */
  3630. Xextern char preview;        /* 3D preview mode flag */
  3631. Xextern int previewfactor; /* Coarsness */
  3632. X
  3633. Xint first_init=1;        /* first time into cmdfiles? */
  3634. Xstatic int init_rseed;
  3635. Xstatic char initcorners,initparams;
  3636. Xstruct fractalspecificstuff far *curfractalspecific;
  3637. X
  3638. Xchar FormFileName[80];        /* file to find (type=)formulas in */
  3639. Xchar FormName[ITEMNAMELEN+1];    /* Name of the Formula (if not null) */
  3640. Xchar LFileName[80];        /* file to find (type=)L-System's in */
  3641. Xchar LName[ITEMNAMELEN+1];    /* Name of L-System */
  3642. Xchar CommandFile[80];        /* file to find command sets in */
  3643. Xchar CommandName[ITEMNAMELEN+1];/* Name of Command set */
  3644. Xchar far CommandComment1[57];    /* comments for command set */
  3645. Xchar far CommandComment2[57];
  3646. Xchar far CommandComment3[57];
  3647. Xchar far CommandComment4[57];
  3648. Xchar IFSFileName[80];        /* file to find (type=)IFS in */
  3649. Xchar IFSName[ITEMNAMELEN+1];    /* Name of the IFS def'n (if not null) */
  3650. Xfloat far *ifs_defn = NULL;    /* ifs parameters */
  3651. Xint  ifs_changed;        /* nonzero if parameters have been edited */
  3652. Xint  ifs_type;            /* 0=2d, 1=3d */
  3653. Xint  slides = 0;        /* 1 autokey=play, 2 autokey=record */
  3654. X
  3655. XBYTE txtcolor[]={
  3656. X      BLUE*16+L_WHITE,      /* C_TITLE           title background */
  3657. X      BLUE*16+L_GREEN,      /* C_TITLE_DEV       development vsn foreground */
  3658. X      GREEN*16+YELLOW,      /* C_HELP_HDG        help page title line */
  3659. X      WHITE*16+BLACK,      /* C_HELP_BODY       help page body */
  3660. X      GREEN*16+GRAY,      /* C_HELP_INSTR      help page instr at bottom */
  3661. X      WHITE*16+BLUE,      /* C_HELP_LINK       help page links */
  3662. X      CYAN*16+BLUE,      /* C_HELP_CURLINK    help page current link */
  3663. X      WHITE*16+GRAY,      /* C_PROMPT_BKGRD    prompt/choice background */
  3664. X      WHITE*16+BLACK,      /* C_PROMPT_TEXT     prompt/choice extra info */
  3665. X      BLUE*16+WHITE,      /* C_PROMPT_LO       prompt/choice text */
  3666. X      BLUE*16+L_WHITE,      /* C_PROMPT_MED      prompt/choice hdg2/... */
  3667. X      BLUE*16+YELLOW,      /* C_PROMPT_HI       prompt/choice hdg/cur/... */
  3668. X      GREEN*16+L_WHITE,   /* C_PROMPT_INPUT    fullscreen_prompt input */
  3669. X      CYAN*16+L_WHITE,      /* C_PROMPT_CHOOSE   fullscreen_prompt choice */
  3670. X      MAGENTA*16+L_WHITE, /* C_CHOICE_CURRENT  fullscreen_choice input */
  3671. X      BLACK*16+WHITE,      /* C_CHOICE_SP_INSTR speed key bar & instr */
  3672. X      BLACK*16+L_MAGENTA, /* C_CHOICE_SP_KEYIN speed key value */
  3673. X      WHITE*16+BLUE,      /* C_GENERAL_HI      tab, thinking, IFS */
  3674. X      WHITE*16+BLACK,      /* C_GENERAL_MED */
  3675. X      WHITE*16+GRAY,      /* C_GENERAL_LO */
  3676. X      BLACK*16+L_WHITE,   /* C_GENERAL_INPUT */
  3677. X      WHITE*16+BLACK,      /* C_DVID_BKGRD      disk video */
  3678. X      BLACK*16+YELLOW,      /* C_DVID_HI */
  3679. X      BLACK*16+L_WHITE,   /* C_DVID_LO */
  3680. X      RED*16+L_WHITE,      /* C_STOP_ERR        stop message, error */
  3681. X      GREEN*16+BLACK,      /* C_STOP_INFO       stop message, info */
  3682. X      BLUE*16+WHITE,      /* C_TITLE_LOW       bottom lines of title screen */
  3683. X      GREEN*16+BLACK,      /* C_AUTHDIV1        title screen dividers */
  3684. X      GREEN*16+GRAY,      /* C_AUTHDIV2        title screen dividers */
  3685. X      BLACK*16+L_WHITE,   /* C_PRIMARY           primary authors */
  3686. X      BLACK*16+WHITE      /* C_CONTRIB           contributing authors */
  3687. X      };
  3688. X
  3689. Xextern int active_system;
  3690. X/* start of string literals cleanup */
  3691. Xchar s_iter[]    = "iter";
  3692. Xchar s_real[]    = "real";
  3693. Xchar s_mult[]     = "mult";
  3694. Xchar s_sum[]     = "summ";
  3695. Xchar s_imag[]    = "imag";
  3696. Xchar s_zmag[]    = "zmag";
  3697. Xchar s_bof60[]   = "bof60";
  3698. Xchar s_bof61[]   = "bof61";
  3699. Xchar s_maxiter[] =  "maxiter";
  3700. Xchar s_epscross[] =  "epsiloncross";
  3701. Xchar s_startrail[] =  "startrail";
  3702. Xchar s_normal[] =  "normal";
  3703. Xchar s_period[] = "period";
  3704. X
  3705. X
  3706. Xvoid cmdfiles_overlay() { }    /* for restore_active_ovly */
  3707. X
  3708. X/*
  3709. X    cmdfiles(argc,argv) process the command-line arguments
  3710. X        it also processes the 'sstools.ini' file and any
  3711. X        indirect files ('fractint @myfile')
  3712. X*/
  3713. X
  3714. Xint cmdfiles(int argc,char **argv)
  3715. X{
  3716. X   int       i;
  3717. X   char    curarg[141];
  3718. X   char    tempstring[101];
  3719. X   char    *sptr;
  3720. X   FILE    *initfile;
  3721. X
  3722. X   ENTER_OVLY(OVLY_CMDFILES);
  3723. X
  3724. X   if (first_init) initvars_run();    /* once per run initialization */
  3725. X   initvars_restart();            /* <ins> key initialization */
  3726. X   initvars_fractal();            /* image initialization */
  3727. X
  3728. X   findpath("sstools.ini", tempstring); /* look for SSTOOLS.INI */
  3729. X   if (tempstring[0] != 0)        /* found it! */
  3730. X      if ((initfile = fopen(tempstring,"r")) != NULL)
  3731. X     cmdfile(initfile,1);        /* process it */
  3732. X
  3733. X   for (i = 1; i < argc; i++) {     /* cycle through args */
  3734. X#ifdef XFRACT
  3735. X      /* Let the xfract code take a look at the argument */
  3736. X      if (unixarg(argc,argv,&i)) continue;
  3737. X#endif
  3738. X      strcpy(curarg,argv[i]);
  3739. X      if (curarg[0] == ';')             /* start of comments? */
  3740. X     break;
  3741. X      if (curarg[0] != '@') {           /* simple command? */
  3742. X     if (strchr(curarg,'=') == NULL) { /* not xxx=yyy, so check for gif */
  3743. X        strcpy(tempstring,curarg);
  3744. X        if (strchr(curarg,'.') == NULL)
  3745. X           strcat(tempstring,".gif");
  3746. X        if ((initfile = fopen(tempstring,"rb"))) {
  3747. X           fread(tempstring,6,1,initfile);
  3748. X           if ( tempstring[0] == 'G'
  3749. X         && tempstring[1] == 'I'
  3750. X         && tempstring[2] == 'F'
  3751. X         && tempstring[3] >= '8' && tempstring[3] <= '9'
  3752. X         && tempstring[4] >= '0' && tempstring[4] <= '9') {
  3753. X          strcpy(readname,curarg);
  3754. X          curarg[0] = showfile = 0;
  3755. X          }
  3756. X           fclose(initfile);
  3757. X           }
  3758. X        }
  3759. X     if (curarg[0])
  3760. X        cmdarg(curarg,0);        /* process simple command */
  3761. X     }
  3762. X      else if ((sptr = strchr(curarg,'/'))) { /* @filename/setname? */
  3763. X     *sptr = 0;
  3764. X     strcpy(CommandFile,&curarg[1]);
  3765. X     strcpy(CommandName,sptr+1);
  3766. X     find_file_item(CommandFile,CommandName,&initfile);
  3767. X     cmdfile(initfile,3);
  3768. X     }
  3769. X      else {                /* @filename */
  3770. X     if ((initfile = fopen(&curarg[1],"r")) == NULL)
  3771. X        argerror(curarg);
  3772. X     cmdfile(initfile,0);
  3773. X     }
  3774. X      }
  3775. X
  3776. X   if (first_init == 0) {
  3777. X      initmode = -1; /* don't set video when <ins> key used */
  3778. X      showfile = 1;  /* nor startup image file            */
  3779. X      }
  3780. X
  3781. X   if(debugflag != 110)
  3782. X       first_init = 0;
  3783. X   EXIT_OVLY;
  3784. X   return(0);
  3785. X}
  3786. X
  3787. X
  3788. Xint load_commands(FILE *infile)
  3789. X{
  3790. X   /* when called, file is open in binary mode, positioned at the */
  3791. X   /* '(' or '{' following the desired parameter set's name       */
  3792. X   int ret;
  3793. X   ENTER_OVLY(OVLY_CMDFILES);
  3794. X   initcorners = initparams = 0; /* reset flags for type= */
  3795. X   ret = cmdfile(infile,2);
  3796. X   EXIT_OVLY;
  3797. X   return ret;
  3798. X}
  3799. X
  3800. X
  3801. Xstatic void initvars_run()        /* once per run init */
  3802. X{
  3803. X   init_rseed = (int)time(NULL);
  3804. X}
  3805. X
  3806. Xstatic void initvars_restart()        /* <ins> key init */
  3807. X{
  3808. X   save_release = release;              /* this release number */
  3809. X   gif87a_flag = INIT_GIF87;            /* turn on GIF89a processing */
  3810. X   dither_flag = 0;            /* no dithering */
  3811. X   askvideo = 1;            /* turn on video-prompt flag */
  3812. X   overwrite = 0;            /* don't overwrite           */
  3813. X   soundflag = -1;            /* sound is on             */
  3814. X   basehertz = 440;            /* basic hertz rate         */
  3815. X   initbatch = 0;            /* not in batch mode         */
  3816. X   initsavetime = 0;            /* no auto-save          */
  3817. X   initmode = -1;            /* no initial video mode     */
  3818. X   viewwindow = 0;            /* no view window         */
  3819. X   viewreduction = 4.2;
  3820. X   viewcrop = 1;
  3821. X   ai_8514 = 0;                         /* no need for the 8514 API  */
  3822. X   finalaspectratio = screenaspect;
  3823. X   viewxdots = viewydots = 0;
  3824. X   orbit_delay = 0;                     /* full speed orbits */
  3825. X   debugflag = 0;            /* debugging flag(s) are off */
  3826. X   timerflag = 0;            /* timer flags are off         */
  3827. X   strcpy(FormFileName,"fractint.frm"); /* default formula file      */
  3828. X   FormName[0] = 0;
  3829. X   strcpy(LFileName,"fractint.l");
  3830. X   LName[0] = 0;
  3831. X   strcpy(CommandFile,"fractint.par");
  3832. X   CommandName[0] = CommandComment1[0] = CommandComment2[0] = 0;
  3833. X   CommandComment3[0] = CommandComment4[0] = 0;
  3834. X   strcpy(IFSFileName,"fractint.ifs");
  3835. X   IFSName[0] = 0;
  3836. X   reset_ifs_defn();
  3837. X   rflag = 0;                /* not a fixed srand() seed */
  3838. X   rseed = init_rseed;
  3839. X   strcpy(readname,DOTSLASH);           /* initially current directory */
  3840. X   showfile = 1;
  3841. X   /* next should perhaps be fractal re-init, not just <ins> ? */
  3842. X   initcyclelimit=55;            /* spin-DAC default speed limit */
  3843. X   mapset = 0;                /* no map= name active */
  3844. X   if (mapdacbox) {
  3845. X      farmemfree(mapdacbox);
  3846. X      mapdacbox = NULL;
  3847. X      }
  3848. X   TPlusFlag = 1;
  3849. X   MaxColorRes = 8;
  3850. X   PixelZoom = 0;
  3851. X   NonInterlaced = 0;
  3852. X
  3853. X   Transparent3D = 0;
  3854. X   SolidCore = 1;
  3855. X   CoreRed   = 128;
  3856. X   CoreGreen = 128;
  3857. X   CoreBlue  = 128;
  3858. X   zzmin = -1.5;
  3859. X   zzmax = 1.5;
  3860. X   ttmin = 0.0;
  3861. X   ttmax = 0.0;
  3862. X   NumFrames = 1;
  3863. X   tpdepth = tptime = 0;
  3864. X
  3865. X   AntiAliasing = 0;
  3866. X   Shadowing = 0;
  3867. X
  3868. X   Printer_Type = DEFAULT_PRINTER;      /* assume an IBM/EPSON    */
  3869. X   Printer_Resolution = PRT_RESOLUTION; /* assume low resolution  */
  3870. X   Printer_Titleblock = 0;        /* assume no title block  */
  3871. X   Printer_ColorXlat = 0;        /* assume positive image  */
  3872. X   Printer_SetScreen = 0;               /* assume default screen  */
  3873. X   Printer_SFrequency = 45;             /* New screen frequency K */
  3874. X   Printer_SAngle = 45;                 /* New screen angle     K */
  3875. X   Printer_SStyle = 1;                  /* New screen style     K */
  3876. X   Printer_RFrequency = 45;             /* New screen frequency R */
  3877. X   Printer_RAngle = 75;                 /* New screen angle     R */
  3878. X   Printer_RStyle = 1;                  /* New screen style     R */
  3879. X   Printer_GFrequency = 45;             /* New screen frequency G */
  3880. X   Printer_GAngle = 15;                 /* New screen angle     G */
  3881. X   Printer_GStyle = 1;                  /* New screen style     G */
  3882. X   Printer_BFrequency = 45;             /* New screen frequency B */
  3883. X   Printer_BAngle = 0;                  /* New screen angle     B */
  3884. X   Printer_BStyle = 1;                  /* New screen style     B */
  3885. X#ifndef XFRACT
  3886. X   Print_To_File = 0;                   /* No print-to-file       */
  3887. X   Printer_CRLF = 0;                    /* Assume CR+LF           */
  3888. X#else
  3889. X   Print_To_File = 1;                   /* Print-to-file          */
  3890. X   Printer_CRLF = 2;                    /* Assume LF              */
  3891. X   Printer_Compress = 0;                /* Assume NO PostScript compression */
  3892. X#endif
  3893. X   EPSFileType = 0;            /* Assume no save to .EPS */
  3894. X   LPTNumber = 1;            /* assume LPT1 */
  3895. X   ColorPS = 0;                         /* Assume NO Color PostScr*/
  3896. X   major_method = minor_method = 0;    /* default inverse julia methods */
  3897. X}
  3898. X
  3899. Xstatic void initvars_fractal()        /* init vars affecting calculation */
  3900. X{
  3901. X   int i;
  3902. X   bios_palette = 0;                    /* don't force use of a BIOS palette */
  3903. X   escape_exit = 0;                     /* don't disable the "are you sure?" screen */
  3904. X   usr_periodicitycheck = 1;        /* turn on periodicity      */
  3905. X   inside = 1;                /* inside color = blue      */
  3906. X   fillcolor = -1;            /* no special fill color */
  3907. X   usr_biomorph = -1;            /* turn off biomorph flag */
  3908. X   outside = -1;            /* outside color = -1 (not used) */
  3909. X   maxit = 150;             /* initial maxiter      */
  3910. X   usr_stdcalcmode = 'g';               /* initial solid-guessing */
  3911. X#ifndef XFRACT
  3912. X   usr_floatflag = 0;            /* turn off the float flag */
  3913. X#else
  3914. X   usr_floatflag = 1;            /* turn on the float flag */
  3915. X#endif
  3916. X   finattract = 0;            /* disable finite attractor logic */
  3917. X   fractype = 0;            /* initial type Set flag  */
  3918. X   curfractalspecific = &fractalspecific[0];
  3919. X   initcorners = initparams = 0;
  3920. X   bailout = 0;             /* no user-entered bailout */
  3921. X   useinitorbit = 0;
  3922. X   for (i = 0; i < MAXPARAMS; i++) param[i] = 0.0;     /* initial parameter values */
  3923. X   for (i = 0; i < 3; i++) potparam[i]    = 0.0; /* initial potential values */
  3924. X   for (i = 0; i < 3; i++) inversion[i] = 0.0;    /* initial invert values */
  3925. X   initorbit[0] = initorbit[1] = 0.0;    /* initial orbit values */
  3926. X   invert = 0;
  3927. X   decomp[0] = decomp[1] = 0;
  3928. X   usr_distest = 0;
  3929. X   distestwidth = 71;
  3930. X   forcesymmetry = 999;         /* symmetry not forced */
  3931. X   xx3rd = xxmin = -2.5; xxmax = 1.5;    /* initial corner values  */
  3932. X   yy3rd = yymin = -1.5; yymax = 1.5;    /* initial corner values  */
  3933. X   pot16bit = potflag = 0;
  3934. X   LogFlag = 0;             /* no logarithmic palette */
  3935. X   set_trig_array(0,"sin");             /* trigfn defaults */
  3936. X   set_trig_array(1,"sqr");
  3937. X   set_trig_array(2,"sinh");
  3938. X   set_trig_array(3,"cosh");
  3939. X   if (rangeslen) {
  3940. X      farmemfree((char far *)ranges);
  3941. X      rangeslen = 0;
  3942. X      }
  3943. X   usemag = 0;                /* use corners, not center-mag */
  3944. X
  3945. X   colorstate = colorpreloaded = 0;
  3946. X   rotate_lo = 1; rotate_hi = 255;    /* color cycling default range */
  3947. X
  3948. X   display3d = 0;            /* 3D display is off        */
  3949. X   overlay3d = 0;            /* 3D overlay is off        */
  3950. X
  3951. X   functionpreloaded = 0; /* for old bifs  JCO 7/5/92 */
  3952. X   mxminfp = -.83;
  3953. X   myminfp = -.25;
  3954. X   mxmaxfp = -.83;
  3955. X   mymaxfp =  .25;
  3956. X   originfp = 8;
  3957. X   heightfp = 7;
  3958. X   widthfp = 10;
  3959. X   distfp = 24;
  3960. X   eyesfp = 2.5;
  3961. X   depthfp = 8;
  3962. X   lastorbittype = -1;
  3963. X   neworbittype = JULIA;
  3964. X   zdots = 128;
  3965. X   initvars_3d();
  3966. X}
  3967. X
  3968. Xstatic void initvars_3d()        /* init vars affecting 3d */
  3969. X{
  3970. X   RAY     = 0;
  3971. X   BRIEF   = 0;
  3972. X   SPHERE = FALSE;
  3973. X   preview = 0;
  3974. X   showbox = 0;
  3975. X   xadjust = 0;
  3976. X   yadjust = 0;
  3977. X   eyeseparation = 0;
  3978. X   glassestype = 0;
  3979. X   previewfactor = 20;
  3980. X   red_crop_left   = 4;
  3981. X   red_crop_right  = 0;
  3982. X   blue_crop_left  = 0;
  3983. X   blue_crop_right = 4;
  3984. X   red_bright      = 80;
  3985. X   blue_bright     = 100;
  3986. X   transparent[0] = transparent[1] = 0; /* no min/max transparency */
  3987. X   set_3d_defaults();
  3988. X}
  3989. X
  3990. Xstatic void reset_ifs_defn()
  3991. X{
  3992. X   if (ifs_defn) {
  3993. X      farmemfree((char far *)ifs_defn);
  3994. X      ifs_defn = NULL;
  3995. X      }
  3996. X}
  3997. X
  3998. X
  3999. Xstatic int cmdfile(FILE *handle,int mode)
  4000. X   /* mode = 0 command line @filename          */
  4001. X   /*         1 sstools.ini              */
  4002. X   /*         2 <@> command after startup      */
  4003. X   /*         3 command line @filename/setname */
  4004. X{
  4005. X   /* note that cmdfile could be open as text OR as binary */
  4006. X   /* binary is used in @ command processing for reasonable speed note/point */
  4007. X   int i;
  4008. X   int lineoffset = 0;
  4009. X   int changeflag = 0; /* &1 fractal stuff chgd, &2 3d stuff chgd */
  4010. X   char linebuf[513],cmdbuf[1001];
  4011. X   if (mode == 2 || mode == 3) {
  4012. X      while ((i = getc(handle)) != '{' && i != EOF) { }
  4013. X      CommandComment1[0] = CommandComment2[0] = 0;
  4014. X      CommandComment3[0] = CommandComment4[0] = 0;
  4015. X      }
  4016. X   linebuf[0] = 0;
  4017. X   while (next_command(cmdbuf,1000,handle,linebuf,&lineoffset,mode) > 0) {
  4018. X      if ((mode == 2 || mode == 3) && strcmp(cmdbuf,"}") == 0) break;
  4019. X      if ((i = cmdarg(cmdbuf,mode)) < 0) break;
  4020. X      changeflag |= i;
  4021. X      }
  4022. X   fclose(handle);
  4023. X#ifdef XFRACT
  4024. X   initmode = 0;        /* Skip credits if @file is used. */
  4025. X#endif
  4026. X   return changeflag;
  4027. X}
  4028. X
  4029. Xstatic int next_command(char *cmdbuf,int maxlen,
  4030. X              FILE *handle,char *linebuf,int *lineoffset,int mode)
  4031. X{
  4032. X   int cmdlen = 0;
  4033. X   char *lineptr;
  4034. X   lineptr = linebuf + *lineoffset;
  4035. X   while(1) {
  4036. X      while (*lineptr <= ' ' || *lineptr == ';') {
  4037. X     if (cmdlen) {            /* space or ; marks end of command */
  4038. X        cmdbuf[cmdlen] = 0;
  4039. X        *lineoffset = lineptr - linebuf;
  4040. X        return cmdlen;
  4041. X        }
  4042. X     while (*lineptr && *lineptr <= ' ')
  4043. X        ++lineptr;            /* skip spaces and tabs */
  4044. X     if (*lineptr == ';' || *lineptr == 0) {
  4045. X        if (*lineptr == ';'
  4046. X          && (mode == 2 || mode == 3)
  4047. X          && (CommandComment1[0] == 0 || CommandComment2[0] == 0 ||
  4048. X              CommandComment3[0] == 0 || CommandComment4[0] == 0)) {
  4049. X           /* save comment */
  4050. X           while (*(++lineptr)
  4051. X         && (*lineptr == ' ' || *lineptr == '\t')) { }
  4052. X           if (*lineptr) {
  4053. X          if (strlen(lineptr) > 56)
  4054. X             *(lineptr+56) = 0;
  4055. X          if (CommandComment1[0] == 0)
  4056. X             far_strcpy(CommandComment1,lineptr);
  4057. X          else if (CommandComment2[0] == 0)
  4058. X             far_strcpy(CommandComment2,lineptr);
  4059. X          else if (CommandComment3[0] == 0)
  4060. X             far_strcpy(CommandComment3,lineptr);
  4061. X          else
  4062. X             far_strcpy(CommandComment4,lineptr);
  4063. X          }
  4064. X           }
  4065. X        if (next_line(handle,linebuf,mode) != 0)
  4066. X           return(-1); /* eof */
  4067. X        lineptr = linebuf; /* start new line */
  4068. X        }
  4069. X     }
  4070. X      if (*lineptr == '\\'              /* continuation onto next line? */
  4071. X    && *(lineptr+1) == 0) {
  4072. X     if (next_line(handle,linebuf,mode) != 0) {
  4073. X        argerror(cmdbuf);        /* missing continuation */
  4074. X        return(-1);
  4075. X        }
  4076. X     lineptr = linebuf;
  4077. X     while (*lineptr && *lineptr <= ' ')
  4078. X        ++lineptr;            /* skip white space @ start next line */
  4079. X     continue;            /* loop to check end of line again */
  4080. X     }
  4081. X      cmdbuf[cmdlen] = *(lineptr++);    /* copy character to command buffer */
  4082. X      if (++cmdlen >= maxlen) {     /* command too long? */
  4083. X     argerror(cmdbuf);
  4084. X     return(-1);
  4085. X     }
  4086. X      }
  4087. X}
  4088. X
  4089. Xstatic int next_line(FILE *handle,char *linebuf,int mode)
  4090. X{
  4091. X   int toolssection;
  4092. X   char tmpbuf[10];
  4093. X   toolssection = 0;
  4094. X   while (file_gets(linebuf,512,handle) >= 0) {
  4095. X      if (mode == 1 && linebuf[0] == '[') {     /* check for [fractint] */
  4096. X     strncpy(tmpbuf,&linebuf[1],9);
  4097. X     tmpbuf[9] = 0;
  4098. X     strlwr(tmpbuf);
  4099. X     toolssection = strncmp(tmpbuf,"fractint]",9);
  4100. X     continue;                /* skip tools section heading */
  4101. X     }
  4102. X      if (toolssection == 0) return(0);
  4103. X      }
  4104. X   return(-1);
  4105. X}
  4106. X
  4107. X/*
  4108. X  cmdarg(string,mode) processes a single command-line/command-file argument
  4109. X    return:
  4110. X      -1 error, >= 0 ok
  4111. X      if ok, return value:
  4112. X    | 1 means fractal parm has been set
  4113. X    | 2 means 3d parm has been set
  4114. X    | 4 means 3d=yes specified
  4115. X    | 8 means reset specified
  4116. X*/
  4117. X
  4118. Xint cmdarg(char *curarg,int mode) /* process a single argument */
  4119. X{
  4120. X   char    variable[21];        /* variable name goes here   */
  4121. X   char    *value;            /* pointer to variable value */
  4122. X   int       valuelen;            /* length of value         */
  4123. X   int       numval;            /* numeric value of arg      */
  4124. X#define NONNUMERIC -32767
  4125. X   char    charval;            /* first character of arg    */
  4126. X   int       yesnoval;            /* 0 if 'n', 1 if 'y', -1 if not */
  4127. X   double  ftemp;
  4128. X   int       i, j, k, l;
  4129. X   char    *argptr,*argptr2;
  4130. X   int       totparms;            /* # of / delimited parms    */
  4131. X   int       intparms;            /* # of / delimited ints     */
  4132. X   int       floatparms;            /* # of / delimited floats   */
  4133. X   int       intval[64];            /* pre-parsed integer parms  */
  4134. X   double  floatval[16];        /* pre-parsed floating parms */
  4135. X   char    tmpc;
  4136. X   int       lastarg;
  4137. X
  4138. X   argptr = curarg;
  4139. X   while (*argptr) {            /* convert to lower case */
  4140. X      if (*argptr >= 'A' && *argptr <= 'Z')
  4141. X     *argptr += 'a' - 'A';
  4142. X      if (*argptr == '=' && strncmp(curarg,"colors=",7) == 0)
  4143. X     break;             /* don't convert colors=value */
  4144. X      ++argptr;
  4145. X      }
  4146. X
  4147. X   if ((value = strchr(&curarg[1],'='))) {
  4148. X      if ((j = (value++) - curarg) > 1 && curarg[j-1] == ':')
  4149. X     --j;                /* treat := same as =      */
  4150. X      }
  4151. X   else
  4152. X      value = curarg + (j = strlen(curarg));
  4153. X   if (j > 20) goto badarg;        /* keyword too long */
  4154. X   strncpy(variable,curarg,j);        /* get the variable name  */
  4155. X   variable[j] = 0;            /* truncate variable name */
  4156. X   valuelen = strlen(value);        /* note value's length    */
  4157. X   charval = value[0];            /* first letter of value  */
  4158. X   yesnoval = -1;            /* note yes|no value      */
  4159. X   if (charval == 'n') yesnoval = 0;
  4160. X   if (charval == 'y') yesnoval = 1;
  4161. X
  4162. X   argptr = value;
  4163. X   numval = totparms = intparms = floatparms = 0;
  4164. X   while (*argptr) {            /* count and pre-parse parms */
  4165. X      long ll;
  4166. X      lastarg = 0;
  4167. X      if ((argptr2 = strchr(argptr,'/')) == NULL) {     /* find next '/' */
  4168. X     argptr2 = argptr + strlen(argptr);
  4169. X     *argptr2 = '/';
  4170. X     lastarg = 1;
  4171. X     }
  4172. X      if (totparms == 0) numval = NONNUMERIC;
  4173. X      i = -1;
  4174. X      charval = *argptr;            /* first letter of value  */
  4175. X      if (charval == 'n') yesnoval = 0;    /* allows only ONE y/n param */
  4176. X      if (charval == 'y') yesnoval = 1;
  4177. X      if (sscanf(argptr,"%c%c",&j,&tmpc) > 0    /* NULL entry */
  4178. X      && (j == '/' || j == '=') && tmpc == '/') {
  4179. X     j = 0;
  4180. X     ++floatparms; ++intparms;
  4181. X     if (totparms < 16) floatval[totparms] = j;
  4182. X     if (totparms < 64) intval[totparms] = j;
  4183. X     if (totparms == 0) numval = j;
  4184. X     }
  4185. X      else if (sscanf(argptr,"%ld%c",&ll,&tmpc) > 0       /* got an integer */
  4186. X    && tmpc == '/') {        /* needs a long int, ll, here for lyapunov */
  4187. X     ++floatparms; ++intparms;
  4188. X     if (totparms < 16) floatval[totparms] = ll;
  4189. X     if (totparms < 64) intval[totparms] = (int)ll;
  4190. X     if (totparms == 0) numval = (int)ll;
  4191. X     }
  4192. X#ifndef XFRACT
  4193. X      else if (sscanf(argptr,"%lg%c",&ftemp,&tmpc) > 0  /* got a float */
  4194. X#else
  4195. X      else if (sscanf(argptr,"%lf%c",&ftemp,&tmpc) > 0  /* got a float */
  4196. X#endif
  4197. X         && tmpc == '/') {
  4198. X     ++floatparms;
  4199. X     if (totparms < 16) floatval[totparms] = ftemp;
  4200. X     }
  4201. X      ++totparms;
  4202. X      argptr = argptr2;                 /* on to the next */
  4203. X      if (lastarg)
  4204. X     *argptr = 0;
  4205. X      else
  4206. X     ++argptr;
  4207. X      }
  4208. X
  4209. X   if (mode != 2 || debugflag==110) {
  4210. X      /* these commands are allowed only at startup */
  4211. X
  4212. X      if (strcmp(variable,"batch") == 0 ) {     /* batch=?      */
  4213. X     if (yesnoval < 0) goto badarg;
  4214. X#ifdef XFRACT
  4215. X         initmode = yesnoval?0:-1; /* skip credits for batch mode */
  4216. X#endif
  4217. X     initbatch = yesnoval;
  4218. X     return 3;
  4219. X     }
  4220. X
  4221. X#ifndef XFRACT
  4222. X      if (strcmp(variable,"adapter") == 0 ) {   /* adapter==?     */
  4223. X         int i, j;
  4224. X         extern char supervga_list;    /* from the list in VIDEO.ASM */
  4225. X         char adapter_name[8];      /* entry lenth from VIDEO.ASM */
  4226. X         char *adapter_ptr;
  4227. X         
  4228. X         adapter_ptr = &supervga_list;
  4229. X         
  4230. X         for(i = 0 ; ; i++) {        /* find the SuperVGA entry */
  4231. X             memcpy(adapter_name , adapter_ptr, 8);
  4232. X             adapter_name[6] = ' ';
  4233. X             for (j = 0; j < 8; j++)
  4234. X                 if(adapter_name[j] == ' ')
  4235. X                     adapter_name[j] = 0;
  4236. X             if (adapter_name[0] == 0) break;  /* end-of-the-list */
  4237. X             if (strncmp(value,adapter_name,strlen(adapter_name)) == 0) {
  4238. X                svga_type = i+1;
  4239. X                adapter_ptr[6] = 1;
  4240. X                break;
  4241. X                }
  4242. X             adapter_ptr += 8;
  4243. X             }
  4244. X         if (svga_type != 0) return 3;
  4245. X
  4246. X     video_type = 5;            /* assume video=vga */
  4247. X     if (strcmp(value,"egamono") == 0) {
  4248. X        video_type = 3;
  4249. X        mode7text = 1;
  4250. X        }
  4251. X     else if (strcmp(value,"hgc") == 0) {   /* video = hgc */
  4252. X        video_type = 1;
  4253. X        mode7text = 1;
  4254. X        }
  4255. X     else if (strcmp(value,"ega") == 0)     /* video = ega */
  4256. X        video_type = 3;
  4257. X     else if (strcmp(value,"cga") == 0)     /* video = cga */
  4258. X        video_type = 2;
  4259. X     else if (strcmp(value,"mcga") == 0)    /* video = mcga */
  4260. X        video_type = 4;
  4261. X     else if (strcmp(value,"vga") == 0)     /* video = vga */
  4262. X        video_type = 5;
  4263. X     else
  4264. X        goto badarg;
  4265. X     return 3;
  4266. X     }
  4267. X
  4268. X      if (strcmp(variable,"afi") == 0) {
  4269. X       if (strncmp(value,"8514"  ,4) == 0
  4270. X           || charval == 'y') ai_8514 = 1; /* set afi flag JCO 4/11/92 */
  4271. X       return 3;
  4272. X    }
  4273. X
  4274. X      if (strcmp(variable,"textsafe") == 0 ) {  /* textsafe==? */
  4275. X     if (first_init) {
  4276. X        if (charval == 'n') /* no */
  4277. X           textsafe = 2;
  4278. X        else if (charval == 'y') /* yes */
  4279. X           textsafe = 1;
  4280. X        else if (charval == 'b') /* bios */
  4281. X           textsafe = 3;
  4282. X        else if (charval == 's') /* save */
  4283. X           textsafe = 4;
  4284. X        else
  4285. X           goto badarg;
  4286. X        }   
  4287. X     return 3;
  4288. X     }
  4289. X
  4290. X      if (strcmp(variable, "vesadetect") == 0) {
  4291. X     if (yesnoval < 0) goto badarg;
  4292. X     vesa_detect = yesnoval;
  4293. X     return 3;
  4294. X     }
  4295. X
  4296. X      if (strcmp(variable, "biospalette") == 0) {
  4297. X         if (yesnoval < 0) goto badarg;
  4298. X         bios_palette = yesnoval;
  4299. X         return 3;
  4300. X         }
  4301. X
  4302. X      if (strcmp(variable,"fpu") == 0) {
  4303. X     if (strcmp(value,"iit") == 0) {
  4304. X        fpu = 387;
  4305. X        iit = 1;
  4306. X        return 0;
  4307. X        }
  4308. X     if (strcmp(value,"noiit") == 0) {
  4309. X        iit = -2;
  4310. X        return 0;
  4311. X        }
  4312. X     if (strcmp(value,"387") == 0) {
  4313. X        fpu = 387;
  4314. X        iit = -2;
  4315. X        return 0;
  4316. X        }
  4317. X     goto badarg;
  4318. X     }
  4319. X#endif
  4320. X
  4321. X      if (strcmp(variable, "exitnoask") == 0) {
  4322. X         if (yesnoval < 0) goto badarg;
  4323. X         escape_exit = yesnoval;
  4324. X         return 3;
  4325. X         }
  4326. X
  4327. X      if (strcmp(variable,"makedoc") == 0) {
  4328. X     print_document(*value ? value : "fractint.doc", makedoc_msg_func, 0);
  4329. X#ifndef WINFRACT
  4330. X     goodbye();
  4331. X#endif
  4332. X     }
  4333. X
  4334. X      } /* end of commands allowed only at startup */
  4335. X
  4336. X   if (strcmp(variable,"reset") == 0) {
  4337. X      initvars_fractal();
  4338. X
  4339. X      /* PAR release unknown unless specified */
  4340. X      if (numval>=0) save_release = numval;
  4341. X      else goto badarg;
  4342. X      return 9;
  4343. X      }
  4344. X
  4345. X   if (strcmp(variable,"filename") == 0) {      /* filename=?     */
  4346. X      if (charval == '.') {
  4347. X     if (valuelen > 4) goto badarg;
  4348. X     gifmask[0] = '*';
  4349. X     gifmask[1] = 0;
  4350. X     strcat(gifmask,value);
  4351. X     return 0;
  4352. X     }
  4353. X      if (valuelen > 79) goto badarg;
  4354. X      if (mode == 2 && display3d == 0) /* can't do this in @ command */
  4355. X     goto badarg;
  4356. X      strcpy(readname,value);
  4357. X      showfile = 0;
  4358. X      return 3;
  4359. X      }
  4360. X
  4361. X   if (strcmp(variable,"video") == 0) {         /* video=? */
  4362. X      if (active_system == 0) {
  4363. X     if ((k = check_vidmode_keyname(value)) == 0) goto badarg;
  4364. X     initmode = -1;
  4365. X     for (i = 0; i < MAXVIDEOTABLE; ++i) {
  4366. X        if (videotable[i].keynum == k) {
  4367. X           initmode = i;
  4368. X           break;
  4369. X           }
  4370. X        }
  4371. X     if (initmode == -1) goto badarg;
  4372. X     }
  4373. X      return 3;
  4374. X      }
  4375. X
  4376. X   if (strcmp(variable,"map") == 0 ) {         /* map=, set default colors */
  4377. X      if (valuelen > 79 || SetColorPaletteName(value) != 0) goto badarg;
  4378. X      mapset = 1;
  4379. X      strcpy(MAP_name,value);
  4380. X      return 0;
  4381. X      }
  4382. X
  4383. X   if (strcmp(variable,"colors") == 0) {       /* colors=, set current colors */
  4384. X      if (parse_colors(value) < 0) goto badarg;
  4385. X      return 0;
  4386. X      }
  4387. X
  4388. X   if (strcmp(variable, "tplus") == 0) {       /* Use the TARGA+ if found? */
  4389. X      if (yesnoval < 0) goto badarg;
  4390. X      TPlusFlag = yesnoval;
  4391. X      return 0;
  4392. X      }
  4393. X
  4394. X   if (strcmp(variable, "noninterlaced") == 0) {
  4395. X      if (yesnoval < 0) goto badarg;
  4396. X      NonInterlaced = yesnoval;
  4397. X      return 0;
  4398. X      }
  4399. X
  4400. X   if (strcmp(variable, "maxcolorres") == 0) { /* Change default color resolution */
  4401. X      if (numval == 1 || numval == 4 || numval == 8 ||
  4402. X            numval == 16 || numval == 24) {
  4403. X     MaxColorRes = numval;
  4404. X     return 0;
  4405. X     }
  4406. X      goto badarg;
  4407. X      }
  4408. X
  4409. X   if (strcmp(variable, "pixelzoom") == 0) {
  4410. X      if (numval < 5)
  4411. X     PixelZoom = numval;
  4412. X      return 0;
  4413. X      }
  4414. X
  4415. X   /* keep this for backward compatibility */
  4416. X   if (strcmp(variable,"warn") == 0 ) {         /* warn=? */
  4417. X      if (yesnoval < 0) goto badarg;
  4418. X      overwrite = yesnoval ^ 1;
  4419. X      return 0;
  4420. X      }
  4421. X   if (strcmp(variable,"overwrite") == 0 ) {    /* overwrite=? */
  4422. X      if (yesnoval < 0) goto badarg;
  4423. X      overwrite = yesnoval;
  4424. X      return 0;
  4425. X      }
  4426. X
  4427. X   if (strcmp(variable,"gif87a") == 0 ) {       /* gif87a=? */
  4428. X      if (yesnoval < 0) goto badarg;
  4429. X      gif87a_flag = yesnoval;
  4430. X      return 0;
  4431. X      }
  4432. X
  4433. X   if (strcmp(variable,"dither") == 0 ) {       /* dither=? */
  4434. X      if (yesnoval < 0) goto badarg;
  4435. X      dither_flag = yesnoval;
  4436. X      return 0;
  4437. X      }
  4438. X
  4439. X   if (strcmp(variable,"savetime") == 0) {      /* savetime=? */
  4440. X      initsavetime = numval;
  4441. X      return 0;
  4442. X      }
  4443. X
  4444. X   if (strcmp(variable,"autokey") == 0) {       /* autokey=? */
  4445. X      if (strcmp(value,"record")==0)
  4446. X     slides=2;
  4447. X      else if (strcmp(value,"play")==0)
  4448. X     slides=1;
  4449. X      else
  4450. X     goto badarg;
  4451. X      return 0;
  4452. X      }
  4453. X
  4454. X   if(strcmp(variable, "solidcore") == 0) {
  4455. X      SolidCore = yesnoval;
  4456. X      return(0);
  4457. X      }
  4458. X/* (nuked until antialiasing become an option)
  4459. X   if(strcmp(variable, "antialias") == 0) {
  4460. X      if(numval < 0 || numval > 8)
  4461. X     goto badarg;
  4462. X      AntiAliasing = numval;
  4463. X      return(0);
  4464. X      }
  4465. X*/
  4466. X   if(strcmp(variable, "transparent3d") == 0) {
  4467. X      Transparent3D = yesnoval;
  4468. X      return(0);
  4469. X      }
  4470. X
  4471. X   if(strcmp(variable, "corecolor") == 0) {
  4472. X      if(floatparms != totparms || totparms != 3)
  4473. X     goto badarg;
  4474. X      CoreRed    = (int)floatval[0];
  4475. X      CoreGreen = (int)floatval[1];
  4476. X      CoreBlue    = (int)floatval[2];
  4477. X      return(0);
  4478. X      }
  4479. X
  4480. X   if(strcmp(variable, "mdcorners") == 0) {
  4481. X      if(floatparms != totparms || totparms < 2 || totparms > 4)
  4482. X     goto badarg;
  4483. X      zzmin = floatval[0];
  4484. X      zzmax = floatval[1];
  4485. X      if(totparms >= 3)
  4486. X     ttmin = floatval[2];
  4487. X      if(totparms == 4)
  4488. X     ttmax = floatval[3];
  4489. X      return(0);
  4490. X      }
  4491. X
  4492. X   if(strcmp(variable, "numframes") == 0) {
  4493. X      NumFrames = numval;
  4494. X      return(0);
  4495. X      }
  4496. X
  4497. X   if (strcmp(variable,"autokeyname") == 0) {   /* autokeyname=? */
  4498. X      strcpy(autoname,value);
  4499. X      return 0;
  4500. X      }
  4501. X
  4502. X   if (strcmp(variable,"type") == 0 ) {         /* type=? */
  4503. X      if (value[valuelen-1] == '*')
  4504. X     value[--valuelen] = 0;
  4505. X      /* kludge because type ifs3d has an asterisk in front */
  4506. X      if(strcmp(value,"ifs3d")==0)
  4507. X         value[3]=0;
  4508. X      for (k = 0; fractalspecific[k].name != NULL; k++)
  4509. X     if (strcmp(value,fractalspecific[k].name) == 0)
  4510. X        break;
  4511. X      if (fractalspecific[k].name == NULL) goto badarg;
  4512. X      curfractalspecific = &fractalspecific[fractype = k];
  4513. X      if (initcorners == 0) {
  4514. X     xx3rd = xxmin = curfractalspecific->xmin;
  4515. X     xxmax           = curfractalspecific->xmax;
  4516. X     yy3rd = yymin = curfractalspecific->ymin;
  4517. X     yymax           = curfractalspecific->ymax;
  4518. X     }
  4519. X      if (initparams == 0) {
  4520. X     for (k = 0; k < 4; ++k) {
  4521. X        param[k] = curfractalspecific->paramvalue[k];
  4522. X        if(fractype != CELLULAR) /* don't round cellular */
  4523. X           roundfloatd(¶m[k]);
  4524. X      }
  4525. X         if(curfractalspecific->flags&MORE) {
  4526. X            int extra;
  4527. X            if((extra=find_extra_param(fractype)) > -1)
  4528. X            for(i=0;i<MAXPARAMS-4;i++) {
  4529. X               param[i+4] = moreparams[extra].paramvalue[i];
  4530. X           }
  4531. X         }
  4532. X      }   
  4533. X      return 1;
  4534. X      }
  4535. X   if (strcmp(variable,"inside") == 0 ) {       /* inside=? */
  4536. X      if(strcmp(value,s_zmag)==0)
  4537. X     inside = -59;
  4538. X      else if(strcmp(value,s_bof60)==0)
  4539. X     inside = -60;
  4540. X      else if(strcmp(value,s_bof61)==0)
  4541. X     inside = -61;
  4542. X      else if(strncmp(value,s_epscross,3)==0)
  4543. X     inside = -100;
  4544. X      else if(strncmp(value,s_startrail,4)==0)
  4545. X     inside = -101;
  4546. X      else if(strncmp(value,s_period,3)==0)
  4547. X     inside = -102;
  4548. X      else if(strcmp(value,s_maxiter)==0)
  4549. X     inside = -1;
  4550. X      else if(numval == NONNUMERIC)
  4551. X     goto badarg;
  4552. X      else
  4553. X     inside = numval;
  4554. X      return 1;
  4555. X      }
  4556. X   if (strcmp(variable,"fillcolor") == 0 ) {       /* fillcolor */
  4557. X      if(strcmp(value,s_normal)==0)
  4558. X     fillcolor = -1;
  4559. X      else if(numval == NONNUMERIC)
  4560. X     goto badarg;
  4561. X      else
  4562. X     fillcolor = numval;
  4563. X      return 1;
  4564. X      }
  4565. X
  4566. X   if (strcmp(variable,"finattract") == 0 ) {   /* finattract=? */
  4567. X      if (yesnoval < 0) goto badarg;
  4568. X      finattract = yesnoval;
  4569. X      return 1;
  4570. X      }
  4571. X
  4572. X   if (strcmp(variable,"function") == 0) {      /* function=?,? */
  4573. X      k = 0;
  4574. X      while (*value && k < 4) {
  4575. X     if(set_trig_array(k++,value)) goto badarg;
  4576. X     if ((value = strchr(value,'/')) == NULL) break;
  4577. X     ++value;
  4578. X     }
  4579. X       functionpreloaded = 1; /* for old bifs  JCO 7/5/92 */
  4580. X      return 1;
  4581. X      }
  4582. X
  4583. X   if (strcmp(variable,"outside") == 0 ) {      /* outside=? */
  4584. X      if(strcmp(value,s_iter)==0)
  4585. X     outside = -1;
  4586. X      else if(strcmp(value,s_real)==0)
  4587. X     outside = -2;
  4588. X      else if(strcmp(value,s_imag)==0)
  4589. X     outside = -3;
  4590. X      else if(strcmp(value,s_mult)==0)
  4591. X     outside = -4;
  4592. X      else if(strcmp(value,s_sum)==0)
  4593. X     outside = -5;
  4594. X
  4595. X      else if(numval == NONNUMERIC)
  4596. X     goto badarg;
  4597. X      else if(numval < -5 || numval > 255) goto badarg;
  4598. X      else outside = numval;
  4599. X      return 1;
  4600. X      }
  4601. X
  4602. X   if (strcmp(variable,s_maxiter) == 0) {       /* maxiter=? */
  4603. X      if (numval < 2) goto badarg;
  4604. X      maxit = numval;
  4605. X      return 1;
  4606. X      }
  4607. X
  4608. X   if (strcmp(variable,"iterincr") == 0)        /* iterincr=? */
  4609. X      return 0;
  4610. X
  4611. X   if (strcmp(variable,"passes") == 0) {        /* passes=? */
  4612. X      if ( charval != '1' && charval != '2'
  4613. X    && charval != 'g' && charval != 'b'
  4614. X    && charval != 't')
  4615. X     goto badarg;
  4616. X      usr_stdcalcmode = charval;
  4617. X      return 1;
  4618. X      }
  4619. X
  4620. X   if (strcmp(variable,"cyclelimit") == 0 ) {   /* cyclelimit=? */
  4621. X      if (numval <= 1 || numval > 256) goto badarg;
  4622. X      initcyclelimit = numval;
  4623. X      return 0;
  4624. X      }
  4625. X
  4626. X   if (strcmp(variable,"makemig") == 0) {
  4627. X       int xmult, ymult;
  4628. X       if (totparms < 2) goto badarg;
  4629. X       xmult = intval[0];
  4630. X       ymult = intval[1];
  4631. X       make_mig(xmult, ymult);
  4632. X#ifndef WINFRACT
  4633. X       exit(0);
  4634. X#endif
  4635. X       }
  4636. X
  4637. X   if (strcmp(variable,"cyclerange") == 0) {
  4638. X      if (totparms < 2) intval[1] = 255;
  4639. X      if (totparms < 1) intval[0] = 1;
  4640. X      if (totparms != intparms
  4641. X    || intval[0] < 0 || intval[1] > 255 || intval[0] > intval[1])
  4642. X     goto badarg;
  4643. X      rotate_lo = intval[0];
  4644. X      rotate_hi = intval[1];
  4645. X      return 0;
  4646. X      }
  4647. X
  4648. X   if (strcmp(variable,"ranges") == 0) {
  4649. X      int i,j,entries,prev;
  4650. X      int tmpranges[128];
  4651. X      if (totparms != intparms) goto badarg;
  4652. X      entries = prev = i = 0;
  4653. X      while (i < totparms) {
  4654. X     if ((j = intval[i++]) < 0) { /* striping */
  4655. X        if ((j = 0-j) < 1 || j >= 16384 || i >= totparms) goto badarg;
  4656. X        tmpranges[entries++] = -1; /* {-1,width,limit} for striping */
  4657. X        tmpranges[entries++] = j;
  4658. X        j = intval[i++];
  4659. X        }
  4660. X     if (j < prev) goto badarg;
  4661. X     tmpranges[entries++] = prev = j;
  4662. X     }
  4663. X      if (prev == 0) goto badarg;
  4664. X      if ((ranges = (int far *)farmemalloc(2L*entries)) == NULL) {
  4665. X     static char far msg[] = {"Insufficient memory for ranges="};
  4666. X     stopmsg(0,msg);
  4667. X     return(-1);
  4668. X     }
  4669. X      rangeslen = entries;
  4670. X      for (i = 0; i < rangeslen; ++i)
  4671. X     ranges[i] = tmpranges[i];
  4672. X      return 1;
  4673. X      }
  4674. X
  4675. X   if (strcmp(variable,"savename") == 0) {      /* savename=? */
  4676. X      if (valuelen > 79) goto badarg;
  4677. X      if (first_init || mode == 2)
  4678. X     strcpy(savename,value);
  4679. X      return 0;
  4680. X      }
  4681. X
  4682. X   if (strcmp(variable,"exitmode") == 0) {      /* exitmode=? */
  4683. X      sscanf(value,"%x",&numval);
  4684. X      exitmode = numval;
  4685. X      return 0;
  4686. X      }
  4687. X
  4688. X   if (strcmp(variable,"textcolors") == 0) {
  4689. X      parse_textcolors(value);
  4690. X      return 0;
  4691. X      }
  4692. X
  4693. X   if (strcmp(variable,"potential") == 0) {     /* potential=? */
  4694. X      k = 0;
  4695. X      while (k < 3 && *value) {
  4696. X         if(k==1)
  4697. X        potparam[k] = atof(value);
  4698. X     else
  4699. X        potparam[k] = atoi(value);
  4700. X     k++;
  4701. X       if ((value = strchr(value,'/')) == NULL) k = 99;
  4702. X     ++value;
  4703. X     }
  4704. X      pot16bit = 0;
  4705. X      if (k < 99) {
  4706. X     if (strcmp(value,"16bit")) goto badarg;
  4707. X     pot16bit = 1;
  4708. X     }
  4709. X      return 1;
  4710. X      }
  4711. X
  4712. X   if (strcmp(variable,"params") == 0) {        /* params=?,? */
  4713. X      if (totparms != floatparms || totparms > MAXPARAMS)
  4714. X     goto badarg;
  4715. X      for (k = 0; k < MAXPARAMS; ++k)
  4716. X     param[k] = (k < totparms) ? floatval[k] : 0.0;
  4717. X      initparams = 1;
  4718. X      return 1;
  4719. X      }
  4720. X
  4721. X   if (strcmp(variable, "miim") == 0) {        /* miim=?[/?[/?[/?]]] */
  4722. X      k = 0;
  4723. X      do {
  4724. X     if (isdigit(*value) ||
  4725. X         *value == '.' || *value == '-' || *value == '+') {
  4726. X        if (k >= 4)
  4727. X           goto badarg;
  4728. X        param[k++] = atof(value);
  4729. X     }
  4730. X     else if (strncmp(value, "breadth", 7) == 0)
  4731. X        major_method = 0;
  4732. X     else if (strncmp(value, "depth",   5) == 0)
  4733. X        major_method = 1;
  4734. X     else if (strncmp(value, "walk",    4) == 0)
  4735. X        major_method = 2;
  4736. X     else if (strncmp(value, "run",     3) == 0)
  4737. X        major_method = 3;
  4738. X     else if (strncmp(value, "left",    4) == 0)
  4739. X        minor_method = 0;
  4740. X     else if (strncmp(value, "right",   5) == 0)
  4741. X        minor_method = 1;
  4742. X     else goto badarg;
  4743. X     value = strchr(value, '/');
  4744. X      } while (value++);
  4745. X      return 1;
  4746. X   }
  4747. X
  4748. X   if (strcmp(variable,"initorbit") == 0) {     /* initorbit=?,? */
  4749. X      if(strcmp(value,"pixel")==0)
  4750. X     useinitorbit = 2;
  4751. X      else {
  4752. X     if (totparms != 2 || floatparms != 2) goto badarg;
  4753. X     initorbit[0] = floatval[0];
  4754. X     initorbit[1] = floatval[1];
  4755. X     useinitorbit = 1;
  4756. X     }
  4757. X      return 1;
  4758. X      }
  4759. X
  4760. X   if (strcmp(variable,"orbitname") == 0 ) {         /* orbitname=? */
  4761. X      if(check_orbit_name(value))
  4762. X         goto badarg;
  4763. X      return 1;
  4764. X      }
  4765. X   if (strcmp(variable,"3dmode") == 0 ) {         /* orbitname=? */
  4766. X      int i,j;
  4767. X      j = -1;
  4768. X      for(i=0;i<4;i++)
  4769. X         if(strcmp(value,juli3Doptions[i])==0)
  4770. X            j = i; 
  4771. X      if(j < 0)
  4772. X         goto badarg;
  4773. X      else
  4774. X         juli3Dmode = j;
  4775. X      return 1;
  4776. X      }
  4777. X
  4778. X   if (strcmp(variable,"julibrot3d") == 0) {       /* julibrot3d=?,?,?,? */
  4779. X      if (floatparms != totparms)
  4780. X     goto badarg;
  4781. X      if(totparms > 0)
  4782. X         zdots = floatval[0];
  4783. X      if (totparms > 1)
  4784. X         originfp = floatval[1];
  4785. X      if (totparms > 2)
  4786. X         depthfp = floatval[2];
  4787. X      if (totparms > 3)
  4788. X         heightfp = floatval[3];
  4789. X      if (totparms > 4)
  4790. X         widthfp = floatval[4];
  4791. X      if (totparms > 5)
  4792. X         distfp = floatval[5];
  4793. X      return 1;
  4794. X      }
  4795. X
  4796. X   if (strcmp(variable,"julibroteyes") == 0) {       /* julibroteyes=?,?,?,? */
  4797. X      if (floatparms != totparms || totparms != 1)
  4798. X     goto badarg;
  4799. X      eyesfp =  floatval[0];
  4800. X      return 1;
  4801. X      }
  4802. X
  4803. X   if (strcmp(variable,"julibrotfromto") == 0) {       /* julibrotfromto=?,?,?,? */
  4804. X      if (floatparms != totparms || totparms != 4)
  4805. X     goto badarg;
  4806. X      mxmaxfp = floatval[0];
  4807. X      mxminfp = floatval[1];
  4808. X      mymaxfp = floatval[2];
  4809. X      myminfp = floatval[3];
  4810. X      return 1;
  4811. X      }
  4812. X
  4813. X   if (strcmp(variable,"corners") == 0) {       /* corners=?,?,?,? */
  4814. X      if (fractype == CELLULAR)
  4815. X          return 1; /* skip setting the corners */
  4816. X      if (floatparms != totparms || (totparms != 4 && totparms != 6))
  4817. X     goto badarg;
  4818. X      usemag = 0;
  4819. X      initcorners = 1;
  4820. X      xx3rd = xxmin = floatval[0];
  4821. X      xxmax =          floatval[1];
  4822. X      yy3rd = yymin = floatval[2];
  4823. X      yymax =          floatval[3];
  4824. X      if (totparms == 6) {
  4825. X     xx3rd =      floatval[4];
  4826. X     yy3rd =      floatval[5];
  4827. X     }
  4828. X      return 1;
  4829. X      }
  4830. X
  4831. X   if (strcmp(variable,"viewwindows") == 0) {  /* viewwindows=?,?,?,?,? */
  4832. X      if (totparms > 5 || floatparms-intparms > 2 || intparms > 4)
  4833. X     goto badarg;
  4834. X      viewwindow = 1;
  4835. X      viewreduction = 4.2;  /* reset default values */
  4836. X      finalaspectratio = screenaspect;
  4837. X      viewcrop = 1; /* yes */
  4838. X      viewxdots = viewydots = 0;
  4839. X
  4840. X      if((totparms > 0) && (floatval[0] > 0.001))
  4841. X        viewreduction = floatval[0];
  4842. X      if((totparms > 1) && (floatval[1] > 0.001))
  4843. X        finalaspectratio = floatval[1];
  4844. X      if((totparms > 2) && (yesnoval == 0))
  4845. X        viewcrop = yesnoval;
  4846. X      if((totparms > 3) && (intval[3] > 0))
  4847. X        viewxdots = intval[3];
  4848. X      if((totparms == 5) && (intval[4] > 0))
  4849. X        viewydots = intval[4];
  4850. X      return 1;
  4851. X      }
  4852. X
  4853. X   if (strcmp(variable,"center-mag") == 0) {    /* center-mag=?,?,? */
  4854. X      double Xctr, Yctr,Magnification,Ratio,Height, Width,Radius;
  4855. X      if (totparms != floatparms
  4856. X    || (totparms != 0 && totparms != 3)
  4857. X    || (totparms == 3 && floatval[2] <= 0.0))
  4858. X     goto badarg;
  4859. X      usemag = 1;
  4860. X      if (totparms == 0) return 0;
  4861. X      initcorners = 1;
  4862. X      Xctr = floatval[0];
  4863. X      Yctr = floatval[1];
  4864. X      Magnification = floatval[2];
  4865. X      Radius = 1.0 / Magnification;
  4866. X      Ratio = .75;    /* inverse aspect ratio of screen  */
  4867. X      /* calculate bounds */
  4868. X      Height = 2.0 * Radius;
  4869. X      Width = Height / Ratio;
  4870. X      yymax = Yctr + Radius;
  4871. X      yy3rd = yymin = Yctr - Radius;
  4872. X      xxmax = Xctr + Width / 2.0;
  4873. X      xx3rd = xxmin = Xctr - Width / 2.0;
  4874. X      return 1;
  4875. X      }
  4876. X
  4877. X   if (strcmp(variable,"invert") == 0) {        /* invert=?,?,? */
  4878. X      if (totparms != floatparms || (totparms != 1 && totparms != 3))
  4879. X     goto badarg;
  4880. X      invert = ((inversion[0] = floatval[0]) != 0.0) ? totparms : 0;
  4881. X      if (totparms == 3) {
  4882. X     inversion[1] = floatval[1];
  4883. X     inversion[2] = floatval[2];
  4884. X     }
  4885. X      return 1;
  4886. X      }
  4887. X
  4888. X   if (strcmp(variable,"askvideo") == 0 ) {     /* askvideo=?   */
  4889. X      if (yesnoval < 0) goto badarg;
  4890. X      askvideo = yesnoval;
  4891. X      return 0;
  4892. X      }
  4893. X
  4894. X   if (strcmp(variable,"ramvideo") == 0 )       /* ramvideo=?   */
  4895. X      return 0; /* just ignore and return, for old time's sake */
  4896. X
  4897. X   if (strcmp(variable,"float") == 0 ) {        /* float=? */
  4898. X      if (yesnoval < 0) goto badarg;
  4899. X      usr_floatflag = yesnoval;
  4900. X      return 3;
  4901. X      }
  4902. X
  4903. X   if (strcmp(variable,"biomorph") == 0 ) {     /* biomorph=? */
  4904. X      usr_biomorph = numval;
  4905. X      return 1;
  4906. X      }
  4907. X
  4908. X   if (strcmp(variable,"orbitsave") == 0 ) {     /* orbitsave=? */
  4909. X      if (yesnoval < 0) goto badarg;
  4910. X      orbitsave = yesnoval;
  4911. X      return 1;
  4912. X      }
  4913. X
  4914. X   if (strcmp(variable,"bailout") == 0 ) {      /* bailout=? */
  4915. X      if (numval < 4 || numval > 32000) goto badarg;
  4916. X      bailout = numval;
  4917. X      return 1;
  4918. X      }
  4919. X
  4920. X   if (strcmp(variable,"symmetry") == 0 ) {     /* symmetry=? */
  4921. X      if     (strcmp(value,"xaxis" )==0) forcesymmetry = XAXIS;
  4922. X      else if(strcmp(value,"yaxis" )==0) forcesymmetry = YAXIS;
  4923. X      else if(strcmp(value,"xyaxis")==0) forcesymmetry = XYAXIS;
  4924. X      else if(strcmp(value,"origin")==0) forcesymmetry = ORIGIN;
  4925. X      else if(strcmp(value,"pi"    )==0) forcesymmetry = PI_SYM;
  4926. X      else if(strcmp(value,"none"  )==0) forcesymmetry = NOSYM;
  4927. X      else goto badarg;
  4928. X      return 1;
  4929. X      }
  4930. X
  4931. X   if (strcmp(variable,"printer") == 0 ) {      /* printer=? */
  4932. X      if (parse_printer(value) < 0) goto badarg;
  4933. X      return 0;
  4934. X      }
  4935. X
  4936. X   if (strcmp(variable,"printfile") == 0) {     /* print-to-file? SWT */
  4937. X      if (valuelen > 79) goto badarg;
  4938. X      Print_To_File = 1;
  4939. X      strcpy(PrintName,value);
  4940. X      return 0;
  4941. X      }
  4942. X   if(strcmp(variable, "rleps") == 0) {
  4943. X      Printer_Compress = yesnoval;
  4944. X      return(0);
  4945. X      }
  4946. X   if(strcmp(variable, "colorps") == 0) {
  4947. X      ColorPS = yesnoval;
  4948. X      return(0);
  4949. X      }
  4950. X
  4951. X   if (strcmp(variable,"epsf") == 0) {          /* EPS type? SWT */
  4952. X      Print_To_File = 1;
  4953. X      EPSFileType = numval;
  4954. X      Printer_Type = 5;
  4955. X      if (strcmp(PrintName,"fract001.prn")==0)
  4956. X     strcpy(PrintName,"fract001.eps");
  4957. X      return 0;
  4958. X      }
  4959. X
  4960. X   if (strcmp(variable,"title") == 0) {         /* Printer title block? SWT */
  4961. X      if (yesnoval < 0) goto badarg;
  4962. X      Printer_Titleblock = yesnoval;
  4963. X      return 0;
  4964. X      }
  4965. X
  4966. X   if (strcmp(variable,"translate") == 0) {     /* Translate color? SWT */
  4967. X      Printer_ColorXlat=0;
  4968. X      if (charval == 'y')
  4969. X     Printer_ColorXlat=1;
  4970. X      else if (numval > 1 || numval < -1)
  4971. X     Printer_ColorXlat=numval;
  4972. X      return 0;
  4973. X      }
  4974. X
  4975. X   if (strcmp(variable,"plotstyle") == 0) {     /* plot style? SWT */
  4976. X      Printer_SStyle = numval;
  4977. X      return 0;
  4978. X      }
  4979. X
  4980. X   if (strcmp(variable,"halftone") == 0) {      /* New halftoning? SWT */
  4981. X      if (totparms != intparms) goto badarg;
  4982. X      Printer_SetScreen=1;
  4983. X      if ((totparms >  0) && ( intval[ 0] >= 0))
  4984. X                      Printer_SFrequency = intval[ 0];
  4985. X      if ((totparms >  1) && ( intval[ 1] >= 0))
  4986. X                      Printer_SAngle     = intval[ 1];
  4987. X      if ((totparms >  2) && ( intval[ 2] >= 0))
  4988. X                      Printer_SStyle     = intval[ 2];
  4989. X      if ((totparms >  3) && ( intval[ 3] >= 0))
  4990. X                      Printer_RFrequency = intval[ 3];
  4991. X      if ((totparms >  4) && ( intval[ 4] >= 0))
  4992. X                      Printer_RAngle     = intval[ 4];
  4993. X      if ((totparms >  5) && ( intval[ 5] >= 0))
  4994. X                      Printer_RStyle     = intval[ 5];
  4995. X      if ((totparms >  6) && ( intval[ 6] >= 0))
  4996. X                      Printer_GFrequency = intval[ 6];
  4997. X      if ((totparms >  7) && ( intval[ 7] >= 0))
  4998. X                      Printer_GAngle     = intval[ 7];
  4999. X      if ((totparms >  8) && ( intval[ 8] >= 0))
  5000. X                      Printer_GStyle     = intval[ 8];
  5001. X      if ((totparms >  9) && ( intval[ 9] >= 0))
  5002. X                      Printer_BFrequency = intval[ 9];
  5003. X      if ((totparms > 10) && ( intval[10] >= 0))
  5004. X                      Printer_BAngle     = intval[10];
  5005. X      if ((totparms > 11) && ( intval[11] >= 0))
  5006. X                      Printer_BStyle     = intval[11];
  5007. X      return 0;
  5008. X      }
  5009. X
  5010. X   if (strcmp(variable,"linefeed") == 0) {      /* Use LF for printer */
  5011. X      if      (strcmp(value,"cr")   == 0) Printer_CRLF = 1;
  5012. X      else if (strcmp(value,"lf")   == 0) Printer_CRLF = 2;
  5013. X      else if (strcmp(value,"crlf") == 0) Printer_CRLF = 0;
  5014. X      else goto badarg;
  5015. X      return 0;
  5016. X      }
  5017. X
  5018. X   if (strcmp(variable,"comport") == 0 ) {      /* Set the COM parameters */
  5019. X      if ((value=strchr(value,'/')) == NULL) goto badarg;
  5020. X      switch (atoi(++value)) {
  5021. X     case 110:  l = 0;   break;
  5022. X     case 150:  l = 32;  break;
  5023. X     case 300:  l = 64;  break;
  5024. X     case 600:  l = 96;  break;
  5025. X     case 1200: l = 128; break;
  5026. X     case 2400: l = 160; break;
  5027. X     case 4800: l = 192; break;
  5028. X     case 9600:
  5029. X     default:   l = 224; break;
  5030. X     }
  5031. X      if ((value=strchr(value,'/')) == NULL) goto badarg;
  5032. X      for (k=0; k < strlen(value); k++) {
  5033. X     switch (value[k]) {
  5034. X        case '7':  l |= 2;  break;
  5035. X        case '8':  l |= 3;  break;
  5036. X        case 'o':  l |= 8;  break;
  5037. X        case 'e':  l |= 24; break;
  5038. X        case '2':  l |= 4;  break;
  5039. X        }
  5040. X     }
  5041. X#ifndef XFRACT
  5042. X#ifndef WINFRACT
  5043. X      _bios_serialcom(0,numval-1,l);
  5044. X#endif
  5045. X#endif
  5046. X      return 0;
  5047. X      }
  5048. X
  5049. X   if (strcmp(variable,"sound") == 0 ) {        /* sound=? */
  5050. X      soundflag = 0;
  5051. X      if (strncmp(value,"ye",2) == 0) {
  5052. X     soundflag = -1;
  5053. X     return(0);
  5054. X     }
  5055. X      if (charval == 'x')
  5056. X     soundflag = 1;
  5057. X      if (charval == 'y')
  5058. X     soundflag = 2;
  5059. X      if (charval == 'z')
  5060. X     soundflag = 3;
  5061. X      return 0;
  5062. X      }
  5063. X
  5064. X   if (strcmp(variable,"hertz") == 0) {         /* Hertz=? */
  5065. X      if (numval < 200 || numval > 10000) goto badarg;
  5066. X      basehertz = numval;
  5067. X      return 0;
  5068. X      }
  5069. X
  5070. X   if (strcmp(variable,"periodicity") == 0 ) {  /* periodicity=? */
  5071. X      usr_periodicitycheck=1;
  5072. X      if ((charval == 'n') || (numval == 0))
  5073. X     usr_periodicitycheck=0;
  5074. X      else if (charval == 'y')
  5075. X     usr_periodicitycheck=1;
  5076. X      else if (charval == 's')   /* 's' for 'show' */
  5077. X     usr_periodicitycheck= -1;
  5078. X      else if(numval == NONNUMERIC)
  5079. X     goto badarg;
  5080. X      else if(numval != 0)
  5081. X     usr_periodicitycheck=numval;
  5082. X      return 1;
  5083. X      }
  5084. X
  5085. X   if (strcmp(variable,"logmap") == 0 ) {       /* logmap=? */
  5086. X      if (charval == 'y')
  5087. X     LogFlag = 1;                /* palette is logarithmic */
  5088. X      else if (charval == 'n')
  5089. X     LogFlag = 0;
  5090. X      else if (charval == 'o')
  5091. X     LogFlag = -1;                /* old log palette */
  5092. X      else
  5093. X     LogFlag = numval;
  5094. X      return 1;
  5095. X      }
  5096. X
  5097. X   if (strcmp(variable,"debugflag") == 0
  5098. X     || strcmp(variable,"debug") == 0) {        /* internal use only */
  5099. X      debugflag = numval;
  5100. X      timerflag = debugflag & 1;        /* separate timer flag */
  5101. X      debugflag -= timerflag;
  5102. X      return 0;
  5103. X      }
  5104. X
  5105. X   if (strcmp(variable, "rseed") == 0) {
  5106. X      rseed = numval;
  5107. X      rflag = 1;
  5108. X      return 1;
  5109. X      }
  5110. X
  5111. X   if (strcmp(variable, "orbitdelay") == 0) {
  5112. X      orbit_delay = numval;
  5113. X      return 0;
  5114. X      }
  5115. X
  5116. X   if (strcmp(variable, "showdot") == 0) {
  5117. X      showdot=numval;
  5118. X      if(showdot<0)
  5119. X         showdot=0;
  5120. X      return 0;
  5121. X      }
  5122. X
  5123. X   if (strcmp(variable, "decomp") == 0) {
  5124. X      if (totparms != intparms || totparms < 1) goto badarg;
  5125. X      decomp[0] = intval[0];
  5126. X      decomp[1] = 0;
  5127. X      if (totparms > 1) /* backward compatibility */
  5128. X     bailout = decomp[1] = intval[1];
  5129. X      return 1;
  5130. X      }
  5131. X
  5132. X   if (strcmp(variable, "distest") == 0) {
  5133. X      if (totparms != intparms || totparms < 1) goto badarg;
  5134. X      usr_distest = intval[0];
  5135. X      distestwidth = 71;
  5136. X      if (totparms > 1)
  5137. X     distestwidth = intval[1];
  5138. X      return 1;
  5139. X      }
  5140. X
  5141. X   if (strcmp(variable,"formulafile") == 0) {   /* formulafile=? */
  5142. X      if (valuelen > 79) goto badarg;
  5143. X      strcpy(FormFileName,value);
  5144. X      return 1;
  5145. X      }
  5146. X
  5147. X   if (strcmp(variable,"formulaname") == 0) {   /* formulaname=? */
  5148. X      if (valuelen > ITEMNAMELEN) goto badarg;
  5149. X      strcpy(FormName,value);
  5150. X      return 1;
  5151. X      }
  5152. X
  5153. X   if (strcmp(variable,"lfile") == 0) {
  5154. X      if (valuelen > 79) goto badarg;
  5155. X      strcpy(LFileName,value);
  5156. X      return 1;
  5157. X      }
  5158. X
  5159. X   if (strcmp(variable,"lname") == 0) {
  5160. X      if (valuelen > ITEMNAMELEN) goto badarg;
  5161. X      strcpy(LName,value);
  5162. X      return 1;
  5163. X      }
  5164. X
  5165. X   if (strcmp(variable,"ifsfile") == 0) {
  5166. X      if (valuelen > 79) goto badarg;
  5167. X      strcpy(IFSFileName,value);
  5168. X      reset_ifs_defn();
  5169. X      return 1;
  5170. X      }
  5171. X
  5172. X   if (strcmp(variable,"ifs") == 0
  5173. X     || strcmp(variable,"ifs3d") == 0) {        /* ifs3d for old time's sake */
  5174. X      if (valuelen > ITEMNAMELEN) goto badarg;
  5175. X      strcpy(IFSName,value);
  5176. X      reset_ifs_defn();
  5177. X      return 1;
  5178. X      }
  5179. X
  5180. X   if (strcmp(variable,"parmfile") == 0) {
  5181. X      if (valuelen > 79) goto badarg;
  5182. X      strcpy(CommandFile,value);
  5183. X      return 0;
  5184. X      }
  5185. X
  5186. X   if (strcmp(variable,"stereo") == 0) {        /* stereo=? */
  5187. X      if ((numval<0) || (numval>3)) goto badarg;
  5188. X      glassestype = numval;
  5189. X      return 3;
  5190. X      }
  5191. X
  5192. X   if (strcmp(variable,"rotation") == 0) {      /* rotation=?/?/? */
  5193. X      if (totparms != 3 || intparms != 3) goto badarg;
  5194. X      XROT = intval[0];
  5195. X      YROT = intval[1];
  5196. X      ZROT = intval[2];
  5197. X      return 3;
  5198. X      }
  5199. X
  5200. X   if (strcmp(variable,"perspective") == 0) {   /* perspective=? */
  5201. X      if (numval == NONNUMERIC) goto badarg;
  5202. X      ZVIEWER = numval;
  5203. X      return 3;
  5204. X      }
  5205. X
  5206. X   if (strcmp(variable,"xyshift") == 0) {       /* xyshift=?/?  */
  5207. X      if (totparms != 2 || intparms != 2) goto badarg;
  5208. X      XSHIFT = intval[0];
  5209. X      YSHIFT = intval[1];
  5210. X      return 3;
  5211. X      }
  5212. X
  5213. X   if (strcmp(variable,"interocular") == 0) {   /* interocular=? */
  5214. X      eyeseparation = numval;
  5215. X      return 3;
  5216. X      }
  5217. X
  5218. X   if (strcmp(variable,"converge") == 0) {      /* converg=? */
  5219. X      xadjust = numval;
  5220. X      return 3;
  5221. X      }
  5222. X
  5223. X   if (strcmp(variable,"crop") == 0) {          /* crop=? */
  5224. X      if (totparms != 4 || intparms != 4
  5225. X    || intval[0] < 0 || intval[0] > 100
  5226. X    || intval[1] < 0 || intval[1] > 100
  5227. X    || intval[2] < 0 || intval[2] > 100
  5228. X    || intval[3] < 0 || intval[3] > 100)
  5229. X      goto badarg;
  5230. X      red_crop_left   = intval[0];
  5231. X      red_crop_right  = intval[1];
  5232. X      blue_crop_left  = intval[2];
  5233. X      blue_crop_right = intval[3];
  5234. X      return 3;
  5235. X      }
  5236. X
  5237. X   if (strcmp(variable,"bright") == 0) {        /* bright=? */
  5238. X      if (totparms != 2 || intparms != 2) goto badarg;
  5239. X      red_bright  = intval[0];
  5240. X      blue_bright = intval[1];
  5241. X      return 3;
  5242. X      }
  5243. X
  5244. X   if (strcmp(variable,"xyadjust") == 0) {      /* trans=? */
  5245. X      if (totparms != 2 || intparms != 2) goto badarg;
  5246. X      xtrans = intval[0];
  5247. X      ytrans = intval[1];
  5248. X      return 3;
  5249. X      }
  5250. X
  5251. X   if (strcmp(variable,"3d") == 0) {            /* 3d=?/?/..    */
  5252. X      if(strcmp(value,"overlay")==0) {
  5253. X         yesnoval=1;
  5254. X         if(calc_status > -1) /* if no image, treat same as 3D=yes */
  5255. X            overlay3d=1;
  5256. X      }      
  5257. X      else if (yesnoval < 0) goto badarg;
  5258. X      display3d = yesnoval;
  5259. X      initvars_3d();
  5260. X      return (display3d) ? 6 : 2;
  5261. X      }
  5262. X
  5263. X   if (strcmp(variable,"sphere") == 0 ) {       /* sphere=? */
  5264. X      if (yesnoval < 0) goto badarg;
  5265. X      SPHERE = yesnoval;
  5266. X      return 2;
  5267. X      }
  5268. X
  5269. X   if (strcmp(variable,"scalexyz") == 0) {      /* scalexyz=?/?/? */
  5270. X      if (totparms < 2 || intparms != totparms) goto badarg;
  5271. X      XSCALE = intval[0];
  5272. X      YSCALE = intval[1];
  5273. X      if (totparms > 2) ROUGH = intval[2];
  5274. X      return 2;
  5275. X      }
  5276. X
  5277. X   /* "rough" is really scale z, but we add it here for convenience */
  5278. X   if (strcmp(variable,"roughness") == 0) {     /* roughness=?  */
  5279. X      ROUGH = numval;
  5280. X      return 2;
  5281. X      }
  5282. X
  5283. X   if (strcmp(variable,"waterline") == 0) {     /* waterline=?  */
  5284. X      if (numval<0) goto badarg;
  5285. X      WATERLINE = numval;
  5286. X      return 2;
  5287. X      }
  5288. X
  5289. X   if (strcmp(variable,"filltype") == 0) {      /* filltype=?   */
  5290. X      if (numval < -1 || numval > 6) goto badarg;
  5291. X      FILLTYPE = numval;
  5292. X      return 2;
  5293. X      }
  5294. X
  5295. X   if (strcmp(variable,"lightsource") == 0) {   /* lightsource=?/?/? */
  5296. X      if (totparms != 3 || intparms != 3) goto badarg;
  5297. X      XLIGHT = intval[0];
  5298. X      YLIGHT = intval[1];
  5299. X      ZLIGHT = intval[2];
  5300. X      return 2;
  5301. X      }
  5302. X
  5303. X   if (strcmp(variable,"smoothing") == 0) {     /* smoothing=?  */
  5304. X      if (numval<0) goto badarg;
  5305. X      LIGHTAVG = numval;
  5306. X      return 2;
  5307. X      }
  5308. X
  5309. X   if (strcmp(variable,"latitude") == 0) {      /* latitude=?/? */
  5310. X      if (totparms != 2 || intparms != 2) goto badarg;
  5311. X      THETA1 = intval[0];
  5312. X      THETA2 = intval[1];
  5313. X      return 2;
  5314. X      }
  5315. X
  5316. X   if (strcmp(variable,"longitude") == 0) {     /* longitude=?/? */
  5317. X      if (totparms != 2 || intparms != 2) goto badarg;
  5318. X      PHI1 = intval[0];
  5319. X      PHI2 = intval[1];
  5320. X      return 2;
  5321. X      }
  5322. X
  5323. X   if (strcmp(variable,"radius") == 0) {        /* radius=? */
  5324. X      if (numval < 0) goto badarg;
  5325. X      RADIUS = numval;
  5326. X      return 2;
  5327. X      }
  5328. X
  5329. X   if (strcmp(variable,"transparent") == 0) {   /* transparent? */
  5330. X      if (totparms != intparms || totparms < 1) goto badarg;
  5331. X      transparent[1] = transparent[0] = intval[0];
  5332. X      if (totparms > 1) transparent[1] = intval[1];
  5333. X      return 2;
  5334. X      }
  5335. X
  5336. X   if (strcmp(variable,"preview") == 0) {       /* preview? */
  5337. X      if (yesnoval < 0) goto badarg;
  5338. X      preview = yesnoval;
  5339. X      return 2;
  5340. X      }
  5341. X
  5342. X   if (strcmp(variable,"showbox") == 0) {       /* showbox? */
  5343. X      if (yesnoval < 0) goto badarg;
  5344. X      showbox = yesnoval;
  5345. X      return 2;
  5346. X      }
  5347. X
  5348. X   if (strcmp(variable,"coarse") == 0) {        /* coarse=? */
  5349. X      if (numval < 3 || numval > 2000) goto badarg;
  5350. X      previewfactor = numval;
  5351. X      return 2;
  5352. X      }
  5353. X
  5354. X   if (strcmp(variable,"randomize") == 0) {     /* RANDOMIZE=? */
  5355. X      if (numval<0 || numval>7) goto badarg;
  5356. X      RANDOMIZE = numval;
  5357. X      return 2;
  5358. X      }
  5359. X
  5360. X   if (strcmp(variable,"ambient") == 0) {       /* ambient=? */
  5361. X      if (numval<0||numval>100) goto badarg;
  5362. X      Ambient = numval;
  5363. X      return 2;
  5364. X      }
  5365. X
  5366. X   if (strcmp(variable,"haze") == 0) {          /* haze=? */
  5367. X      if (numval<0||numval>100) goto badarg;
  5368. X      haze = numval;
  5369. X      return 2;
  5370. X      }
  5371. X
  5372. X   if (strcmp(variable,"fullcolor") == 0) {     /* fullcolor=? */
  5373. X      if (yesnoval < 0) goto badarg;
  5374. X      Targa_Out = yesnoval;
  5375. X      return 2;
  5376. X      }
  5377. X   if (strcmp(variable,"targa_out") == 0) {     /* Targa Out? */
  5378. X      if (yesnoval < 0) goto badarg;
  5379. X      Targa_Out = yesnoval;
  5380. X      return 2;
  5381. X      }
  5382. X
  5383. X   if (strcmp(variable,"targa_overlay") == 0) {         /* Targa Overlay? */
  5384. X      if (yesnoval < 0) goto badarg;
  5385. X      Targa_Overlay = yesnoval;
  5386. X      return 2;
  5387. X      }
  5388. X
  5389. X   if (strcmp(variable,"background") == 0) {     /* background=?/? */
  5390. X      if (totparms != 3 || intparms != 3) goto badarg;
  5391. X                for (i=0;i<3;i++)
  5392. X                        if (intval[i] & 0xff)
  5393. X                                goto badarg;
  5394. X      back_color[0] = intval[0];
  5395. X      back_color[1] = intval[1];
  5396. X      back_color[2] = intval[2];
  5397. X      return 2;
  5398. X      }
  5399. X
  5400. X   if (strcmp(variable,"lightname") == 0) {     /* lightname=?   */
  5401. X      if (valuelen > 79) goto badarg;
  5402. X      if (first_init || mode == 2)
  5403. X     strcpy(light_name,value);
  5404. X      return 0;
  5405. X      }
  5406. X
  5407. X   if (strcmp(variable,"ray") == 0) {           /* RAY=? */
  5408. X      if (numval < 0 || numval > 6) goto badarg;
  5409. X      RAY = numval;
  5410. X      return 2;
  5411. X      }
  5412. X
  5413. X   if (strcmp(variable,"brief") == 0) {         /* BRIEF? */
  5414. X      if (yesnoval < 0) goto badarg;
  5415. X      BRIEF = yesnoval;
  5416. X      return 2;
  5417. X      }
  5418. X
  5419. X   if (strcmp(variable,"release") == 0) {       /* release */
  5420. X      if (numval < 0) goto badarg;
  5421. X
  5422. X      save_release = numval;
  5423. X      return 2;
  5424. X      }
  5425. X
  5426. X
  5427. Xbadarg:
  5428. X   argerror(curarg);
  5429. X   return(-1);
  5430. X
  5431. X}
  5432. X
  5433. X/* Some routines broken out of above so compiler doesn't run out of heap: */
  5434. X
  5435. Xstatic void parse_textcolors(char *value)
  5436. X{
  5437. X   int i,j,k,hexval;
  5438. X   if (strcmp(value,"mono") == 0) {
  5439. X      for (k = 0; k < sizeof(txtcolor); ++k)
  5440. X     txtcolor[k] = BLACK*16+WHITE;
  5441. X   /* C_HELP_CURLINK = C_PROMPT_INPUT = C_CHOICE_CURRENT = C_GENERAL_INPUT
  5442. X             = C_AUTHDIV1 = C_AUTHDIV2 = WHITE*16+BLACK; */
  5443. X      txtcolor[6] = txtcolor[12] = txtcolor[13] = txtcolor[14] = txtcolor[20]
  5444. X          = txtcolor[27] = txtcolor[28] = WHITE*16+BLACK;
  5445. X      /* C_TITLE = C_HELP_HDG = C_HELP_LINK = C_PROMPT_HI = C_CHOICE_SP_KEYIN
  5446. X         = C_GENERAL_HI = C_DVID_HI = C_STOP_ERR
  5447. X         = C_STOP_INFO = BLACK*16+L_WHITE; */
  5448. X      txtcolor[0] = txtcolor[2] = txtcolor[5] = txtcolor[11] = txtcolor[16]
  5449. X          = txtcolor[17] = txtcolor[22] = txtcolor[24]
  5450. X          = txtcolor[25] = BLACK*16+L_WHITE;
  5451. X      }
  5452. X   else {
  5453. X      k = 0;
  5454. X      while ( k < sizeof(txtcolor)) {
  5455. X     if (*value == 0) break;
  5456. X     if (*value != '/') {
  5457. X        sscanf(value,"%x",&hexval);
  5458. X        i = (hexval / 16) & 7;
  5459. X        j = hexval & 15;
  5460. X        if (i == j || (i == 0 && j == 8)) /* force contrast */
  5461. X           j = 15;
  5462. X        txtcolor[k] = i * 16 + j;
  5463. X        if ((value = strchr(value,'/')) == NULL) break;
  5464. X        }
  5465. X     ++value;
  5466. X     ++k;
  5467. X     }
  5468. X      }
  5469. X}
  5470. X
  5471. Xstatic int parse_colors(char *value)
  5472. X{
  5473. X   int i,j,k;
  5474. X   if (*value == '@') {
  5475. X      if (strlen(value) > 80 || ValidateLuts(&value[1]) != 0) goto badcolor;
  5476. X      if (display3d) {
  5477. X        mapset = 1;
  5478. X        strcpy(MAP_name,&value[1]);
  5479. X        }
  5480. X      else {
  5481. X        strcpy(colorfile,&value[1]);
  5482. X        colorstate = 2;
  5483. X        }
  5484. X      }
  5485. X   else {
  5486. X      int smooth;
  5487. X      i = smooth = 0;
  5488. X      while (*value) {
  5489. X     if (i >= 256) goto badcolor;
  5490. X     if (*value == '<') {
  5491. X        if (i == 0 || smooth
  5492. X          || (smooth = atoi(value+1)) < 2
  5493. X          || (value = strchr(value,'>')) == NULL)
  5494. X           goto badcolor;
  5495. X        i += smooth;
  5496. X        ++value;
  5497. X        }
  5498. X     else {
  5499. X        for (j = 0; j < 3; ++j) {
  5500. X           if ((k = *(value++)) < '0')  goto badcolor;
  5501. X           else if (k <= '9')       k -= '0';
  5502. X           else if (k < 'A')            goto badcolor;
  5503. X           else if (k <= 'Z')       k -= ('A'-10);
  5504. X           else if (k < '_' || k > 'z') goto badcolor;
  5505. X           else            k -= ('_'-36);
  5506. X           dacbox[i][j] = k;
  5507. X           if (smooth) {
  5508. X          int start,spread,cnum;
  5509. X          start = i - (spread = smooth + 1);
  5510. X          cnum = 0;
  5511. X          if ((k - (int)dacbox[start][j]) == 0) {
  5512. X             while (++cnum < spread)
  5513. X            dacbox[start+cnum][j] = k;
  5514. X             }
  5515. X          else {
  5516. X             while (++cnum < spread)
  5517. X            dacbox[start+cnum][j] =
  5518. X               ( cnum         *dacbox[i][j]
  5519. X               + (i-(start+cnum))*dacbox[start][j]
  5520. X               + spread/2 )
  5521. X               / spread;
  5522. X             }
  5523. X          }
  5524. X           }
  5525. X        smooth = 0;
  5526. X        ++i;
  5527. X        }
  5528. X     }
  5529. X      if (smooth) goto badcolor;
  5530. X      while (i < 256)  { /* zap unset entries */
  5531. X     dacbox[i][0] = dacbox[i][1] = dacbox[i][2] = 40;
  5532. X     ++i;
  5533. X     }
  5534. X      colorstate = 1;
  5535. X      }
  5536. X   colorpreloaded = 1;
  5537. X   return(0);
  5538. Xbadcolor:
  5539. X   return(-1);
  5540. X}
  5541. X
  5542. Xstatic int parse_printer(char *value)
  5543. X{
  5544. X   int k;
  5545. X   if (value[0]=='h' && value[1]=='p')
  5546. X      Printer_Type=1;                 /* HP LaserJet           */
  5547. X   if (value[0]=='i' && value[1]=='b')
  5548. X      Printer_Type=2;                 /* IBM Graphics           */
  5549. X   if (value[0]=='e' && value[1]=='p')
  5550. X      Printer_Type=2;                 /* Epson (model?)           */
  5551. X   if (value[0]=='c' && value[1]=='o')
  5552. X      Printer_Type=3;                 /* Star (Epson-Comp?) color */
  5553. X   if (value[0]=='p') {
  5554. X      if (value[1]=='a')
  5555. X     Printer_Type=4;             /* HP Paintjet (color)    */
  5556. X      if ((value[1]=='o' || value[1]=='s')) {
  5557. X     Printer_Type=5;             /* PostScript  SWT */
  5558. X     if (value[2]=='h' || value[2]=='l')
  5559. X        Printer_Type=6;
  5560. X     }
  5561. X      if (value[1]=='l')
  5562. X     Printer_Type=7;             /* HP Plotter (semi-color) */
  5563. X      }
  5564. X   if (Printer_Type == 1)             /* assume low resolution */
  5565. X      Printer_Resolution = 75;
  5566. X   else
  5567. X      Printer_Resolution = 60;
  5568. X   if (EPSFileType > 0)              /* EPS save - force type 5 */
  5569. X      Printer_Type = 5;
  5570. X   if ((Printer_Type == 5) || (Printer_Type == 6))
  5571. X      Printer_Resolution = 150;          /* PostScript def. res. */
  5572. X   if ((value=strchr(value,'/'))) {
  5573. X      if ((k=atoi(++value)) >= 0) Printer_Resolution=k;
  5574. X      if ((value=strchr(value,'/'))) {
  5575. X     if ((k=atoi(++value))> 0) LPTNumber = k;
  5576. X     if (k < 0) {
  5577. X        Print_To_File = 1;
  5578. X        LPTNumber = 1;
  5579. X        }
  5580. X     }
  5581. X      }
  5582. X   return(0);
  5583. X}
  5584. X
  5585. X
  5586. X
  5587. Xstatic void argerror(char *badarg)    /* oops. couldn't decode this */
  5588. X{
  5589. X   static char far argerrmsg1[]={"\
  5590. XOops. I couldn't understand the argument:\n  "};
  5591. X   static char far argerrmsg2[]={"\n\n\
  5592. X(see the Startup Help screens or documentation for a complete\n\
  5593. X argument list with descriptions)"};
  5594. X   char msg[300];
  5595. X   if (strlen(badarg) > 70) badarg[70] = 0;
  5596. X   if (active_system == 0 /* DOS */
  5597. X     && first_init)      /* & this is 1st call to cmdfiles */
  5598. X#ifndef XFRACT
  5599. X      sprintf(msg,"%Fs%s%Fs",argerrmsg1,badarg,argerrmsg2);
  5600. X   else
  5601. X      sprintf(msg,"%Fs%s",argerrmsg1,badarg);
  5602. X#else
  5603. X      sprintf(msg,"%s%s%s",argerrmsg1,badarg,argerrmsg2);
  5604. X   else
  5605. X      sprintf(msg,"%s%s",argerrmsg1,badarg);
  5606. X#endif
  5607. X   stopmsg(0,msg);
  5608. X}
  5609. X
  5610. Xvoid set_3d_defaults()
  5611. X{
  5612. X   ENTER_OVLY(OVLY_CMDFILES);
  5613. X   ROUGH     = 30;
  5614. X   WATERLINE = 0;
  5615. X   ZVIEWER   = 0;
  5616. X   XSHIFT    = 0;
  5617. X   YSHIFT    = 0;
  5618. X   xtrans    = 0;
  5619. X   ytrans    = 0;
  5620. X   LIGHTAVG  = 0;
  5621. X   Ambient   = 20;
  5622. X   RANDOMIZE = 0;
  5623. X   haze      = 0;
  5624. X   back_color[0] = 51; back_color[1] = 153; back_color[2] = 200;
  5625. X   if(SPHERE) {
  5626. X      PHI1    =  180;
  5627. X      PHI2    =  0;
  5628. X      THETA1    =  -90;
  5629. X      THETA2    =  90;
  5630. X      RADIUS    =  100;
  5631. X      FILLTYPE    = 2;
  5632. X      XLIGHT    = 1;
  5633. X      YLIGHT    = 1;
  5634. X      ZLIGHT    = 1;
  5635. X      }
  5636. X   else {
  5637. X      XROT    = 60;
  5638. X      YROT    = 30;
  5639. X      ZROT    = 0;
  5640. X      XSCALE    = 90;
  5641. X      YSCALE    = 90;
  5642. X      FILLTYPE    = 0;
  5643. X      if (active_system != 0)
  5644. X     FILLTYPE = 2;
  5645. X      XLIGHT    = 1;
  5646. X      YLIGHT    = -1;
  5647. X      ZLIGHT    = 1;
  5648. X      }
  5649. X    EXIT_OVLY;
  5650. X}
  5651. SHAR_EOF
  5652. $TOUCH -am 1028230093 cmdfiles.c &&
  5653. chmod 0644 cmdfiles.c ||
  5654. echo "restore of cmdfiles.c failed"
  5655. set `wc -c cmdfiles.c`;Wc_c=$1
  5656. if test "$Wc_c" != "67637"; then
  5657.     echo original size 67637, current size $Wc_c
  5658. fi
  5659. # ============= decoder.c ==============
  5660. echo "x - extracting decoder.c (Text)"
  5661. sed 's/^X//' << 'SHAR_EOF' > decoder.c &&
  5662. X/* DECODE.C - An LZW decoder for GIF
  5663. X * Copyright (C) 1987, by Steven A. Bennett
  5664. X *
  5665. X * Permission is given by the author to freely redistribute and include
  5666. X * this code in any program as long as this credit is given where due.
  5667. X *
  5668. X * In accordance with the above, I want to credit Steve Wilhite who wrote
  5669. X * the code which this is heavily inspired by...
  5670. X *
  5671. X * GIF and 'Graphics Interchange Format' are trademarks (tm) of
  5672. X * Compuserve, Incorporated, an H&R Block Company.
  5673. X *
  5674. X * Release Notes: This file contains a decoder routine for GIF images
  5675. X * which is similar, structurally, to the original routine by Steve Wilhite.
  5676. X * It is, however, somewhat noticably faster in most cases.
  5677. X *
  5678. X == This routine was modified for use in FRACTINT in two ways.
  5679. X ==
  5680. X == 1) The original #includes were folded into the routine strictly to hold
  5681. X ==    down the number of files we were dealing with.
  5682. X ==
  5683. X == 2) The 'stack', 'suffix', 'prefix', and 'decoderline' arrays were changed from
  5684. X ==    static and 'malloc()'ed to external only so that the assembler
  5685. X ==    program could use the same array space for several independent
  5686. X ==    chunks of code.    Also, 'stack' was renamed to 'dstack' for TASM
  5687. X ==    compatibility.
  5688. X ==
  5689. X == 3) The 'out_line()' external function has been changed to reference
  5690. X ==    '*outln()' for flexibility (in particular, 3D transformations)
  5691. X ==
  5692. X == 4) A call to 'keypressed()' has been added after the 'outln()' calls
  5693. X ==    to check for the presenc of a key-press as a bail-out signal
  5694. X ==
  5695. X == (Bert Tyler and Timothy Wegner)
  5696. X */
  5697. X
  5698. X/* Rev ??/??/?? - Initial Release
  5699. X * Rev 01/02/91 - Revised by Mike Gelvin
  5700. X *                    altered logic to allow newcode to input a line at a time
  5701. X *                    altered logic to allow decoder to place characters
  5702. X *                        directly into the output buffer if they fit
  5703. X*/
  5704. X
  5705. X/***** C Library Includes ***********************************************/
  5706. X#include <stdio.h>
  5707. X
  5708. X/***** Application Includes *********************************************/
  5709. X#include "prototyp.h"
  5710. X
  5711. X/***** Application Function Prototypes **********************************/
  5712. Xstatic short get_next_code(void);
  5713. X
  5714. X/* extern short out_line(pixels, linelen)
  5715. X *     UBYTE pixels[];
  5716. X *     short linelen;
  5717. X *
  5718. X *   - This function takes a full line of pixels (one byte per pixel) and
  5719. X * displays them (or does whatever your program wants with them...).  It
  5720. X * should return zero, or negative if an error or some other event occurs
  5721. X * which would require aborting the decode process...  Note that the length
  5722. X * passed will almost always be equal to the line length passed to the
  5723. X * decoder function, with the sole exception occurring when an ending code
  5724. X * occurs in an odd place in the GIF file...  In any case, linelen will be
  5725. X * equal to the number of pixels passed...
  5726. X */
  5727. Xint (*outln)(BYTE *,int) = out_line;
  5728. X
  5729. X/***** Local Static Variables *******************************************/
  5730. X/* Various error codes used by decoder
  5731. X * and my own routines...   It's okay
  5732. X * for you to define whatever you want,
  5733. X * as long as it's negative...  It will be
  5734. X * returned intact up the various subroutine
  5735. X * levels...
  5736. X */
  5737. X#define OUT_OF_MEMORY -10
  5738. X#define BAD_CODE_SIZE -20
  5739. X#define READ_ERROR -1
  5740. X#define WRITE_ERROR -2
  5741. X#define OPEN_ERROR -3
  5742. X#define CREATE_ERROR -4
  5743. X
  5744. X#define MAX_CODES   4095
  5745. X
  5746. X#define NOPE 0
  5747. X#define YUP -1
  5748. X
  5749. Xstatic short curr_size;            /* The current code size */
  5750. X
  5751. X#ifndef XFRACT
  5752. Xstatic short far sizeofstring[MAX_CODES+1];
  5753. X#else
  5754. Xstatic short sizeofstring[MAX_CODES+1];    /* size of string list */
  5755. X#endif
  5756. X
  5757. X/* The following static variables are used
  5758. X * for seperating out codes
  5759. X */
  5760. Xstatic short navail_bytes;        /* # bytes left in block */
  5761. Xstatic short nbits_left;        /* # bits left in current byte */
  5762. Xstatic BYTE byte_buff[257];    /* Current block, reuse shared mem */
  5763. Xstatic BYTE *pbytes;        /* Pointer to next byte in block */
  5764. Xstatic unsigned short ret_code;
  5765. X
  5766. Xstatic short code_mask[13] = {
  5767. X     0,
  5768. X     0x0001, 0x0003,
  5769. X     0x0007, 0x000F,
  5770. X     0x001F, 0x003F,
  5771. X     0x007F, 0x00FF,
  5772. X     0x01FF, 0x03FF,
  5773. X     0x07FF, 0x0FFF
  5774. X     };
  5775. X
  5776. X/***** External Variables ***********************************************/
  5777. X/* extern short bad_code_count;
  5778. X *
  5779. X * This value is the only other global required by the using program, and
  5780. X * is incremented each time an out of range code is read by the decoder.
  5781. X * When this value is non-zero after a decode, your GIF file is probably
  5782. X * corrupt in some way...
  5783. X */
  5784. Xextern short bad_code_count;
  5785. X
  5786. X/* whups, here are more globals, added by PB: */
  5787. Xextern short skipxdots; /* 0 to get every dot, 1 for every 2nd, 2 every 3rd, ... */
  5788. Xextern short skipydots; /* ditto for rows */
  5789. X
  5790. X/*
  5791. XI removed the LOCAL identifiers in the arrays below and replaced them
  5792. Xwith 'extern's so as to declare (and re-use) the space elsewhere.
  5793. XThe arrays are actually declared in the assembler source.
  5794. X                        Bert Tyler
  5795. X*/
  5796. Xextern BYTE dstack[MAX_CODES + 1];            /* Stack for storing pixels */
  5797. Xextern BYTE suffix[MAX_CODES + 1];            /* Suffix table */
  5798. Xextern unsigned short prefix[MAX_CODES + 1];        /* Prefix linked list */
  5799. Xextern BYTE decoderline[2];                /* decoded line goes here */
  5800. X
  5801. X
  5802. X/* The reason we have these separated like this instead of using
  5803. X * a structure like the original Wilhite code did, is because this
  5804. X * stuff generally produces significantly faster code when compiled...
  5805. X * This code is full of similar speedups...  (For a good book on writing
  5806. X * C for speed or for space optimization, see Efficient C by Tom Plum,
  5807. X * published by Plum-Hall Associates...)
  5808. X */
  5809. X
  5810. X
  5811. X/***** Program **********************************************************/
  5812. X/* short decoder(linewidth)
  5813. X *    short linewidth;            * Pixels per line of image *
  5814. X *
  5815. X * - This function decodes an LZW image, according to the method used
  5816. X * in the GIF spec.  Every *linewidth* "characters" (ie. pixels) decoded
  5817. X * will generate a call to out_line(), which is a user specific function
  5818. X * to display a line of pixels.  The function gets its codes from
  5819. X * get_next_code() which is responsible for reading blocks of data and
  5820. X * seperating them into the proper size codes.    Finally, get_byte() is
  5821. X * the global routine to read the next byte from the GIF file.
  5822. X *
  5823. X * It is generally a good idea to have linewidth correspond to the actual
  5824. X * width of a line (as specified in the Image header) to make your own
  5825. X * code a bit simpler, but it isn't absolutely necessary.
  5826. X *
  5827. X * Returns: 0 if successful, else negative.  (See ERRS.H)
  5828. X *
  5829. X */
  5830. Xshort decoder( short linewidth)
  5831. X{
  5832. X    BYTE *sp;
  5833. X    short code;
  5834. X    short old_code;
  5835. X    short ret;
  5836. X    short c;
  5837. X    short size;
  5838. X    short i;
  5839. X    short j;
  5840. X    short fastloop;
  5841. X    short bufcnt;                    /* how many empty spaces left in buffer */
  5842. X    short xskip;
  5843. X    short slot;                        /* Last read code */
  5844. X    short newcodes;                    /* First available code */
  5845. X    BYTE *bufptr;
  5846. X    short yskip;
  5847. X    short top_slot;                    /* Highest code for current size */
  5848. X    short clear;                    /* Value for a clear code */
  5849. X    short ending;                    /* Value for a ending code */
  5850. X    BYTE out_value;
  5851. X
  5852. X
  5853. X    /* Initialize for decoding a new image...
  5854. X    */
  5855. X
  5856. X    if ((size = get_byte()) < 0)
  5857. X        return(size);
  5858. X    if (size < 2 || 9 < size)
  5859. X        return(BAD_CODE_SIZE);
  5860. X
  5861. X    curr_size = size + 1;
  5862. X    top_slot = 1 << curr_size;
  5863. X    clear = 1 << size;
  5864. X    ending = clear + 1;
  5865. X    slot = newcodes = ending + 1;
  5866. X    navail_bytes = nbits_left = sizeofstring[slot] = xskip = yskip
  5867. X        = old_code = 0;
  5868. X    out_value = 0;
  5869. Xfor (i = 0; i < slot; i++)
  5870. X{    sizeofstring[i] = 0;
  5871. X}
  5872. X    
  5873. X    /* Initialize in case they forgot to put in a clear code.
  5874. X     * (This shouldn't happen, but we'll try and decode it anyway...)
  5875. X    */
  5876. X
  5877. X    /* Set up the stack pointer and decode buffer pointer
  5878. X    */
  5879. X    sp = dstack;
  5880. X    bufptr = decoderline;
  5881. X    bufcnt = linewidth;
  5882. X
  5883. X    /* This is the main loop.  For each code we get we pass through the
  5884. X     * linked list of prefix codes, pushing the corresponding "character" for
  5885. X     * each code onto the stack.  When the list reaches a single "character"
  5886. X     * we push that on the stack too, and then start unstacking each
  5887. X     * character for output in the correct order.  Special handling is
  5888. X     * included for the clear code, and the whole thing ends when we get
  5889. X     * an ending code.
  5890. X    */
  5891. X    while ((c = get_next_code()) != ending)
  5892. X    {
  5893. X
  5894. X        /* If we had a file error, return without completing the decode
  5895. X        */
  5896. X        if (c < 0)
  5897. X            return(0);
  5898. X
  5899. X        /* If the code is a clear code, reinitialize all necessary items.
  5900. X        */
  5901. X        if (c == clear)
  5902. X        {
  5903. X            curr_size = size + 1;
  5904. X            slot = newcodes;
  5905. X            sizeofstring[slot] = 0;
  5906. X            top_slot = 1 << curr_size;
  5907. X
  5908. X            /* Continue reading codes until we get a non-clear code
  5909. X             * (Another unlikely, but possible case...)
  5910. X            */
  5911. X            while ((c = get_next_code()) == clear)
  5912. X            ;
  5913. X
  5914. X            /* If we get an ending code immediately after a clear code
  5915. X             * (Yet another unlikely case), then break out of the loop.
  5916. X            */
  5917. X            if (c == ending)
  5918. X                break;
  5919. X
  5920. X            /* Finally, if the code is beyond the range of already set codes,
  5921. X             * (This one had better NOT happen...    I have no idea what will
  5922. X             * result from this, but I doubt it will look good...) then set it
  5923. X             * to color zero.
  5924. X            */
  5925. X            if (c >= slot)
  5926. X                c = 0;
  5927. X
  5928. X            old_code = out_value = c;
  5929. X
  5930. X            /* And let us not forget to put the char into the buffer... */
  5931. X            *sp++ = c;
  5932. X        }
  5933. X        else
  5934. X        {
  5935. X
  5936. X            /* In this case, it's not a clear code or an ending code, so
  5937. X             * it must be a code code...  So we can now decode the code into
  5938. X             * a stack of character codes. (Clear as mud, right?)
  5939. X            */
  5940. X            code = c;
  5941. X
  5942. X            /* Here we go again with one of those off chances...  If, on the
  5943. X             * off chance, the code we got is beyond the range of those already
  5944. X             * set up (Another thing which had better NOT happen...) we trick
  5945. X             * the decoder into thinking it actually got the next slot avail.
  5946. X            */
  5947. X
  5948. X            if (code >= slot)
  5949. X            {
  5950. X                if (code > slot)
  5951. X                {
  5952. X                    ++bad_code_count;
  5953. X                    c = slot;
  5954. X                }
  5955. X                code = old_code;
  5956. X                *sp++ = out_value;
  5957. X            }
  5958. X
  5959. X            /* Here we scan back along the linked list of prefixes.  If they can
  5960. X             * fit into the output buffer then transfer them direct.  ELSE push
  5961. X             * them into the stack until we are down to enough characters that
  5962. X             * they do fit.  Output the line then fall through to unstack the ones
  5963. X             * that would not fit.
  5964. X            */
  5965. X            fastloop = NOPE;
  5966. X            while (code >= newcodes)
  5967. X            {    j = i = sizeofstring[code];
  5968. X                if (i > 0 && bufcnt - i > 0 && skipxdots == 0)
  5969. X                {
  5970. X                    fastloop = YUP;
  5971. X
  5972. X                    do
  5973. X                    {    *(bufptr + j) = suffix[code];
  5974. X                        code = prefix[code];
  5975. X                    } while(--j > 0);
  5976. X                    *bufptr = (BYTE)code;
  5977. X                    bufptr += ++i;
  5978. X                    bufcnt -= i;
  5979. X                    if (bufcnt == 0) /* finished an input row? */
  5980. X                    {    if (--yskip < 0)
  5981. X                        {
  5982. X                            if ((ret = (*outln)(decoderline, bufptr - decoderline)) < 0)
  5983. X                                return(ret);
  5984. X                            yskip = skipydots;
  5985. X                        }
  5986. X                        if (keypressed())
  5987. X                            return(-1);
  5988. X                        bufptr = decoderline;
  5989. X                        bufcnt = linewidth;
  5990. X                        xskip = 0;
  5991. X                    }
  5992. X                }
  5993. X                else
  5994. X                {
  5995. X                    *sp++ = suffix[code];
  5996. X                    code = prefix[code];
  5997. X                }
  5998. X            }
  5999. X
  6000. X            /* Push the last character on the stack, and set up the new
  6001. X             * prefix and suffix, and if the required slot number is greater
  6002. X             * than that allowed by the current bit size, increase the bit
  6003. X             * size.  (NOTE - If we are all full, we *don't* save the new
  6004. X             * suffix and prefix...  I'm not certain if this is correct...
  6005. X             * it might be more proper to overwrite the last code...
  6006. X            */
  6007. X            if (fastloop == NOPE)
  6008. X                *sp++ = (BYTE)code;
  6009. X
  6010. X            if (slot < top_slot)
  6011. X            {
  6012. X                sizeofstring[slot] = sizeofstring[old_code]+1;
  6013. X                suffix[slot] = out_value = (BYTE)code;
  6014. X                prefix[slot++] = old_code;
  6015. X                old_code = c;
  6016. X            }
  6017. X            if (slot >= top_slot)
  6018. X                if (curr_size < 12)
  6019. X                {
  6020. X                    top_slot <<= 1;
  6021. X                    ++curr_size;
  6022. X                }
  6023. X        }
  6024. X        while (sp > dstack)
  6025. X        {
  6026. X            --sp;
  6027. X            if (--xskip < 0)
  6028. X            {
  6029. X                xskip = skipxdots;
  6030. X                *bufptr++ = *sp;
  6031. X            }
  6032. X            if (--bufcnt == 0) /* finished an input row? */
  6033. X            {    if (--yskip < 0)
  6034. X                {
  6035. X                    if ((ret = (*outln)(decoderline, bufptr - decoderline)) < 0)
  6036. X                        return(ret);
  6037. X                    yskip = skipydots;
  6038. X                }
  6039. X                if (keypressed())
  6040. X                    return(-1);
  6041. X                bufptr = decoderline;
  6042. X                bufcnt = linewidth;
  6043. X                xskip = 0;
  6044. X            }
  6045. X        }
  6046. X
  6047. X    }
  6048. X    /* PB note that if last line is incomplete, we're not going to try
  6049. X     * to emit it;  original code did, but did so via out_line and therefore
  6050. X     * couldn't have worked well in all cases...
  6051. X    */
  6052. X    return(0);
  6053. X}
  6054. X
  6055. X
  6056. X
  6057. X
  6058. X/***** Program **********************************************************/
  6059. X/* get_next_code()
  6060. X * - gets the next code from the GIF file.  Returns the code, or else
  6061. X * a negative number in case of file errors...
  6062. X */
  6063. Xstatic short get_next_code()
  6064. X{
  6065. X    static BYTE b1;                /* Current byte */
  6066. X    static unsigned short ret_code;
  6067. X
  6068. X    if (nbits_left == 0)
  6069. X    {
  6070. X        if (navail_bytes <= 0)
  6071. X        {
  6072. X
  6073. X            /* Out of bytes in current block, so read next block
  6074. X            */
  6075. X            pbytes = byte_buff;
  6076. X            if ((navail_bytes = get_byte()) < 0)
  6077. X                return(navail_bytes);
  6078. X            else
  6079. X                if (navail_bytes)
  6080. X                    get_bytes(byte_buff,navail_bytes);
  6081. X        }
  6082. X        b1 = *pbytes++;
  6083. X        nbits_left = 8;
  6084. X        --navail_bytes;
  6085. X    }
  6086. X
  6087. X    ret_code = b1 >> (8 - nbits_left);
  6088. X    while (curr_size > nbits_left)
  6089. X    {
  6090. X        if (navail_bytes <= 0)
  6091. X        {
  6092. X
  6093. X            /* Out of bytes in current block, so read next block
  6094. X            */
  6095. X            pbytes = byte_buff;
  6096. X            if ((navail_bytes = get_byte()) < 0)
  6097. X                return(navail_bytes);
  6098. X            else
  6099. X                if (navail_bytes)
  6100. X                    get_bytes(byte_buff,navail_bytes);
  6101. X        }
  6102. X        b1 = *pbytes++;
  6103. X        ret_code |= b1 << nbits_left;
  6104. X        nbits_left += 8;
  6105. X        --navail_bytes;
  6106. X    }
  6107. X    nbits_left -= curr_size;
  6108. X    return(ret_code & code_mask[curr_size]);
  6109. X}
  6110. SHAR_EOF
  6111. $TOUCH -am 1028230093 decoder.c &&
  6112. chmod 0644 decoder.c ||
  6113. echo "restore of decoder.c failed"
  6114. set `wc -c decoder.c`;Wc_c=$1
  6115. if test "$Wc_c" != "13232"; then
  6116.     echo original size 13232, current size $Wc_c
  6117. fi
  6118. # ============= editpal.c ==============
  6119. echo "x - extracting editpal.c (Text)"
  6120. sed 's/^X//' << 'SHAR_EOF' > editpal.c &&
  6121. X/*
  6122. X * editpal.c
  6123. X *
  6124. X * Edits VGA 256-color palettes.
  6125. X *
  6126. X * This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  6127. X *
  6128. X *
  6129. X * Key to initials:
  6130. X *
  6131. X *    EAN - Ethan Nagel [70022,2552]
  6132. X *
  6133. X *    JJB - Juan J. Buhler [jbuhler@gidef.edu.ar]
  6134. X *
  6135. X *    TIW - Tim Wegner
  6136. X *
  6137. X * Revision History:
  6138. X *
  6139. X *   10-22-90 EAN     Initial release.
  6140. X *
  6141. X *   10-23-90 EAN     "Discovered" get_line/put_line functions, integrated
  6142. X *                them in (instead of only getcolor/putcolor). Much
  6143. X *                faster!
  6144. X *              Redesigned color editors (now at top of palette) and
  6145. X *                re-assigned some keys.
  6146. X *              Added (A)uto option.
  6147. X *              Fixed memory allocation problem.  Now uses shared
  6148. X *                FRACTINT data area (strlocn).  Uses 6 bytes DS.
  6149. X *
  6150. X *   10-27-90 EAN     Added save to memory option - will save screen image to
  6151. X *                memory, if enough mem avail.  (disk otherwise).
  6152. X *              Added s(T)ripe mode - works like (S)hade except only
  6153. X *                changes every n'th entry.
  6154. X *              Added temporary palette save/restore.  (Can work like
  6155. X *                an undo feature.)  Thanks to Pieter Branderhorst for
  6156. X *                idea.
  6157. X *
  6158. X *   10-28-90 EAN     The (H)ide function now makes the palette invisible,
  6159. X *                while allowing any other operations (except '\\' -
  6160. X *                move/resize) to continue.
  6161. X *
  6162. X *   10-29-90 PB (in EAN's absence, <grin>)
  6163. X *              Change 'c' to 'd' and 's' to '=' for below.
  6164. X *              Add 'l' to load palette from .map, 's' to store .map.
  6165. X *              Add 'c' to invoke color cycling.
  6166. X *              Change cursor to use whatever colors it can from
  6167. X *              the palette (not fixed 0 and 255).
  6168. X *              Restore colors 0 and 255 to real values whenever
  6169. X *              palette is not on display.
  6170. X *              Rotate 255 colors instead of 254.
  6171. X *              Reduce cursor blink rate.
  6172. X *
  6173. X *   11-15-90 EAN     Minor "bug" fixes.  Continuous rotation now at a fixed
  6174. X *                rate - once every timer tick (18.2 sec);  Blanks out
  6175. X *                color samples when rotating; Editors no longer rotate
  6176. X *                with the colors in color rotation mode;  Eliminated
  6177. X *                (Z)oom mode; other minor fixes.
  6178. X *
  6179. X *   01-05-91 PB      Add 'w' function to convert to greyscale.
  6180. X *
  6181. X *   01-16-91 PB      Change rotate function to use new cyclerange stuff.
  6182. X *
  6183. X *   01-29-91 EAN     Made all colors editable.  The two reserved colors are
  6184. X *             X'ed out.  They can be edited but the color is not
  6185. X *             visible.  (There is an X over the sample instead.)
  6186. X *              Changed default reserved colors to 254 & 255.
  6187. X *              Added 'v' command to set the reserved colors to those
  6188. X *             under the editors.
  6189. X *              Added 'o' command to set the rotate range to between
  6190. X *                the two editors.
  6191. X *              Modified 'w' function:
  6192. X *                uses internal function to do conversion (not BIOS)
  6193. X *                will convert only current color if in 'x' mode or
  6194. X *              range between editors in 'y' mode or entire palette
  6195. X *              if in "normal" mode.
  6196. X *
  6197. X *   02-08-91 EAN     Improved 16 color support.  In 16 color mode, colors
  6198. X *                16-255 have a dot over them and are editable but not
  6199. X *                visible (like the two reserved colors).
  6200. X *
  6201. X *   09-08-91 SWT     Added 'n' command to make a negative color palette:
  6202. X *                      will convert only current color if in 'x' mode or
  6203. X *                      range between editors in 'y' mode or entire palette
  6204. X *                      if in "normal" mode.
  6205. X *
  6206. X *   03-03-92 JJB     Added '!', '@' and '#' commands to swap RG, GB and
  6207. X *                      RB columns (sorry, I didn't find better keys)
  6208. X *
  6209. X *  10-03-92 TIW      Minor changes for Jiim support, primarily changing
  6210. X *                    variables from static to global.
  6211. X *
  6212. X *   2-11-93 EAN      Added full Undo ('U' key) and Redo ('E' key)
  6213. X *                      capability.  Works pretty much as you'd expect
  6214. X *                      it to.
  6215. X *
  6216. X *    3-6-93 EAN      Modified "freestyle" mode, written by RB, to integrate
  6217. X *                      into palette editor more completely and work with
  6218. X *                      undo logic.
  6219. X *                    Added status area under the "fractint" message to
  6220. X *                      display current state of editor.  A = Auto mode,
  6221. X *                      X, Y = exclusion modes, F = freesyle mode, T = stripe
  6222. X *                      mode is waiting for #.
  6223. X *
  6224. X */
  6225. X
  6226. X
  6227. X
  6228. X#ifdef DEBUG_UNDO
  6229. X#include "mdisp.h"   /* EAN 930211 *** Debug Only *** */
  6230. X#endif
  6231. X
  6232. X
  6233. X#include <stdio.h>
  6234. X#include <stdlib.h>
  6235. X#include <string.h>
  6236. X#ifndef XFRACT
  6237. X#include <stdarg.h>
  6238. X#include <dos.h>     /* for FP_SEG & FP_OFF */
  6239. X#else
  6240. X#include <varargs.h>
  6241. X#endif
  6242. X#include <math.h>
  6243. X
  6244. X#ifdef __TURBOC__
  6245. X#   include <mem.h>   /* to get mem...() declarations */
  6246. X#endif
  6247. X
  6248. X#include "fractint.h" /* for overlay stuff */
  6249. X#include "prototyp.h"
  6250. X
  6251. X
  6252. X/*
  6253. X * misc. #defines
  6254. X */
  6255. X
  6256. X#define FONT_DEPTH        8      /* font size */
  6257. X
  6258. X#define CSIZE_MIN        8      /* csize cannot be smaller than this */
  6259. X
  6260. X#define CURSOR_SIZE        5      /* length of one side of the x-hair cursor */
  6261. X
  6262. X#ifndef XFRACT
  6263. X#define CURSOR_BLINK_RATE   3      /* timer ticks between cursor blinks */
  6264. X#else
  6265. X#define CURSOR_BLINK_RATE   300      /* timer ticks between cursor blinks */
  6266. X#endif
  6267. X
  6268. X#define FAR_RESERVE     8192L      /* amount of far mem we will leave avail. */
  6269. X
  6270. X#define MAX_WIDTH     1024      /* palette editor cannot be wider than this */
  6271. X
  6272. Xchar scrnfile[] = "FRACTINT.$$1";  /* file where screen portion is */
  6273. X                   /* stored */
  6274. Xchar undofile[] = "FRACTINT.$$2";  /* file where undo list is stored */
  6275. X#define TITLE   "FRACTINT"
  6276. X
  6277. X#define TITLE_LEN (8)
  6278. X
  6279. X
  6280. X#define newx(size)     mem_alloc(size)
  6281. X#define new(class)     (class *)(mem_alloc(sizeof(class)))
  6282. X#define delete(block)
  6283. X
  6284. X#ifdef XFRACT
  6285. Xint editpal_cursor = 0;
  6286. X#endif
  6287. X
  6288. X
  6289. X/*
  6290. X * Stuff from fractint
  6291. X */
  6292. X
  6293. Xextern BYTE dacbox[256][3];     /* DAC spindac() will use         */
  6294. Xextern int         sxdots;         /* width of physical screen         */
  6295. Xextern int         sydots;         /* depth of physical screen         */
  6296. Xextern int         sxoffs;         /* start of logical screen         */
  6297. Xextern int         syoffs;         /* start of logical screen         */
  6298. Xextern int         lookatmouse;     /* mouse mode for getakey(), etc    */
  6299. Xextern int         strlocn[];      /* 10K buffer to store classes in   */
  6300. Xextern int         colors;         /* # colors avail.             */
  6301. Xextern int         color_bright;     /* brightest color in palette         */
  6302. Xextern int         color_dark;     /* darkest color in palette         */
  6303. Xextern int         color_medium;     /* nearest to medbright gray color  */
  6304. Xextern int         rotate_lo, rotate_hi;
  6305. Xextern int         debugflag;
  6306. Xint using_jiim = 0;
  6307. X
  6308. X/*
  6309. X * basic data types
  6310. X */
  6311. X
  6312. X
  6313. Xtypedef struct
  6314. X   {
  6315. X   BYTE red,
  6316. X         green,
  6317. X         blue;
  6318. X   } PALENTRY;
  6319. X
  6320. X
  6321. X
  6322. X/*
  6323. X * static data
  6324. X */
  6325. X
  6326. X
  6327. Xstatic BYTE far *font8x8 = NULL;
  6328. XBYTE     *line_buff;   /* must be alloced!!! */
  6329. Xstatic BYTE      fg_color,
  6330. X              bg_color;
  6331. Xstatic BOOLEAN          reserve_colors;
  6332. Xstatic BOOLEAN          inverse;
  6333. X
  6334. Xstatic float    gamma_val = 1.0;
  6335. X
  6336. X
  6337. X/*
  6338. X * Interface to FRACTINT's graphics stuff
  6339. X */
  6340. X
  6341. X
  6342. Xstatic void setpal(int pal, int r, int g, int b)
  6343. X   {
  6344. X   dacbox[pal][0] = r;
  6345. X   dacbox[pal][1] = g;
  6346. X   dacbox[pal][2] = b;
  6347. X   spindac(0,1);
  6348. X   }
  6349. X
  6350. X
  6351. Xstatic void setpalrange(int first, int how_many, PALENTRY *pal)
  6352. X   {
  6353. X   memmove(dacbox+first, pal, how_many*3);
  6354. X   spindac(0,1);
  6355. X   }
  6356. X
  6357. X
  6358. Xstatic void getpalrange(int first, int how_many, PALENTRY *pal)
  6359. X   {
  6360. X   memmove(pal, dacbox+first, how_many*3);
  6361. X   }
  6362. X
  6363. X
  6364. Xstatic void rotatepal(PALENTRY *pal, int dir, int lo, int hi)
  6365. X   {             /* rotate in either direction */
  6366. X   PALENTRY hold;
  6367. X   int        size;
  6368. X
  6369. X   size  = 1 + (hi-lo);
  6370. X
  6371. X   if ( dir > 0 )
  6372. X      {
  6373. X      while ( dir-- > 0 )
  6374. X         {
  6375. X         memmove(&hold, &pal[hi],  3);
  6376. X         memmove(&pal[lo+1], &pal[lo], 3*(size-1));
  6377. X         memmove(&pal[lo], &hold, 3);
  6378. X         }
  6379. X      }
  6380. X
  6381. X   else if ( dir < 0 )
  6382. X      {
  6383. X      while ( dir++ < 0 )
  6384. X         {
  6385. X         memmove(&hold, &pal[lo], 3);
  6386. X         memmove(&pal[lo], &pal[lo+1], 3*(size-1));
  6387. X         memmove(&pal[hi], &hold,  3);
  6388. X         }
  6389. X      }
  6390. X   }
  6391. X
  6392. X
  6393. Xstatic void clip_put_line(int row, int start, int stop, BYTE *pixels)
  6394. X   {
  6395. X   if ( row < 0 || row >= sydots || start > sxdots || stop < 0 )
  6396. X      return ;
  6397. X
  6398. X   if ( start < 0 )
  6399. X      {
  6400. X      pixels += -start;
  6401. X      start = 0;
  6402. X      }
  6403. X
  6404. X   if ( stop >= sxdots )
  6405. X      stop = sxdots - 1;
  6406. X
  6407. X   if ( start > stop )
  6408. X      return ;
  6409. X
  6410. X   put_line(row, start, stop, pixels);
  6411. X   }
  6412. X
  6413. X
  6414. Xstatic void clip_get_line(int row, int start, int stop, BYTE *pixels)
  6415. X   {
  6416. X   if ( row < 0 || row >= sydots || start > sxdots || stop < 0 )
  6417. X      return ;
  6418. X
  6419. X   if ( start < 0 )
  6420. X      {
  6421. X      pixels += -start;
  6422. X      start = 0;
  6423. X      }
  6424. X
  6425. X   if ( stop >= sxdots )
  6426. X      stop = sxdots - 1;
  6427. X
  6428. X   if ( start > stop )
  6429. X      return ;
  6430. X
  6431. X   get_line(row, start, stop, pixels);
  6432. X   }
  6433. X
  6434. X
  6435. Xvoid clip_putcolor(int x, int y, int color)
  6436. X   {
  6437. X   if ( x < 0 || y < 0 || x >= sxdots || y >= sydots )
  6438. X      return ;
  6439. X
  6440. X   putcolor(x, y, color);
  6441. X   }
  6442. X
  6443. X
  6444. Xint clip_getcolor(int x, int y)
  6445. X   {
  6446. X   if ( x < 0 || y < 0 || x >= sxdots || y >= sydots )
  6447. X      return (0);
  6448. X
  6449. X   return ( getcolor(x, y) );
  6450. X   }
  6451. X
  6452. X
  6453. Xvoid hline(int x, int y, int width, int color)
  6454. X   {
  6455. X   memset(line_buff, color, width);
  6456. X   clip_put_line(y, x, x+width-1, line_buff);
  6457. X   }
  6458. X
  6459. X
  6460. Xvoid vline(int x, int y, int depth, int color)
  6461. X   {
  6462. X   while (depth-- > 0)
  6463. X      clip_putcolor(x, y++, color);
  6464. X   }
  6465. X
  6466. X
  6467. Xvoid getrow(int x, int y, int width, char *buff)
  6468. X   {
  6469. X   clip_get_line(y, x, x+width-1, (BYTE *)buff);
  6470. X   }
  6471. X
  6472. X
  6473. Xvoid putrow(int x, int y, int width, char *buff)
  6474. X   {
  6475. X   clip_put_line(y, x, x+width-1, (BYTE *)buff);
  6476. X   }
  6477. X
  6478. X
  6479. Xstatic void vgetrow(int x, int y, int depth, char *buff)
  6480. X   {
  6481. X   while (depth-- > 0)
  6482. X      *buff++ = clip_getcolor(x, y++);
  6483. X   }
  6484. X
  6485. X
  6486. Xstatic void vputrow(int x, int y, int depth, char *buff)
  6487. X   {
  6488. X   while (depth-- > 0)
  6489. X      clip_putcolor(x, y++, (BYTE)(*buff++));
  6490. X   }
  6491. X
  6492. X
  6493. Xstatic void fillrect(int x, int y, int width, int depth, int color)
  6494. X   {
  6495. X   while (depth-- > 0)
  6496. X      hline(x, y++, width, color);
  6497. X   }
  6498. X
  6499. X
  6500. Xstatic void rect(int x, int y, int width, int depth, int color)
  6501. X   {
  6502. X   hline(x, y, width, color);
  6503. X   hline(x, y+depth-1, width, color);
  6504. X
  6505. X   vline(x, y, depth, color);
  6506. X   vline(x+width-1, y, depth, color);
  6507. X   }
  6508. X
  6509. X
  6510. Xvoid displayc(int x, int y, int fg, int bg, int ch)
  6511. X   {
  6512. X   int              xc, yc;
  6513. X   BYTE      t;
  6514. X   BYTE far *ptr;
  6515. X
  6516. X   if( font8x8 == NULL)
  6517. X      if ( (font8x8 = findfont(0)) == NULL )
  6518. X         return ;
  6519. X
  6520. X   ptr = ((BYTE far *)font8x8) + ch*FONT_DEPTH;
  6521. X
  6522. X   for (yc=0; yc<FONT_DEPTH; yc++, y++, ++ptr)
  6523. X      {
  6524. X      for (xc=0, t= *ptr; xc<8; xc++, t<<=1)
  6525. X     line_buff[xc] = (t&0x80) ? (unsigned)fg : (unsigned)bg;
  6526. X      putrow(x, y, 8, (char *)line_buff);
  6527. X      }
  6528. X   }
  6529. X
  6530. X
  6531. X#ifndef XFRACT
  6532. Xstatic void displayf(int x, int y, int fg, int bg, char *format, ...)
  6533. X#else
  6534. Xstatic void displayf(va_alist)
  6535. Xva_dcl
  6536. X#endif
  6537. X   {
  6538. X   char buff[81];
  6539. X   int  ctr;
  6540. X
  6541. X   va_list arg_list;
  6542. X
  6543. X#ifndef XFRACT
  6544. X   va_start(arg_list, format);
  6545. X#else
  6546. X   int x,y,fg,bg;
  6547. X   char *format;
  6548. X
  6549. X   va_start(arg_list);
  6550. X   x = va_arg(arg_list,int);
  6551. X   y = va_arg(arg_list,int);
  6552. X   fg = va_arg(arg_list,int);
  6553. X   bg = va_arg(arg_list,int);
  6554. X   format = va_arg(arg_list,char *);
  6555. X#endif
  6556. X   vsprintf(buff, format, arg_list);
  6557. X   va_end(arg_list);
  6558. X
  6559. X   for(ctr=0; buff[ctr]!='\0'; ctr++, x+=8)
  6560. X      displayc(x, y, fg, bg, buff[ctr]);
  6561. X   }
  6562. X
  6563. X
  6564. X/*
  6565. X * create smooth shades between two colors
  6566. X */
  6567. X
  6568. X
  6569. Xstatic void mkpalrange(PALENTRY *p1, PALENTRY *p2, PALENTRY pal[], int num, int skip)
  6570. X   {
  6571. X   int      curr;
  6572. X   double rm = (double)((int) p2->red   - (int) p1->red  ) / num,
  6573. X      gm = (double)((int) p2->green - (int) p1->green) / num,
  6574. X      bm = (double)((int) p2->blue  - (int) p1->blue ) / num;
  6575. X
  6576. X   for (curr=0; curr<num; curr+=skip)
  6577. X      {
  6578. X      if (gamma_val == 1)
  6579. X          {
  6580. X      pal[curr].red   = (p1->red   == p2->red  ) ? p1->red   :
  6581. X          (int) p1->red   + (int) ( rm * curr );
  6582. X      pal[curr].green = (p1->green == p2->green) ? p1->green :
  6583. X          (int) p1->green + (int) ( gm * curr );
  6584. X      pal[curr].blue  = (p1->blue  == p2->blue ) ? p1->blue  :
  6585. X          (int) p1->blue  + (int) ( bm * curr );
  6586. X      }
  6587. X      else
  6588. X      {
  6589. X      pal[curr].red   = (p1->red   == p2->red  ) ? p1->red   :
  6590. X          (int) p1->red   + pow(curr/(double)(num-1),gamma_val)*num*rm;
  6591. X      pal[curr].green = (p1->green == p2->green) ? p1->green :
  6592. X          (int) p1->green + pow(curr/(double)(num-1),gamma_val)*num*gm;
  6593. X      pal[curr].blue  = (p1->blue  == p2->blue ) ? p1->blue  :
  6594. X          (int) p1->blue  + pow(curr/(double)(num-1),gamma_val)*num*bm;
  6595. X      }
  6596. X      }
  6597. X   }
  6598. X
  6599. X
  6600. X
  6601. X/*  Swap RG GB & RB columns */
  6602. X
  6603. Xstatic void rotcolrg(PALENTRY pal[], int num)
  6604. X   {
  6605. X   int      curr;
  6606. X   int    dummy;
  6607. X
  6608. X    for (curr=0; curr<=num; curr++)
  6609. X      {
  6610. X      dummy = pal[curr].red;
  6611. X      pal[curr].red = pal[curr].green;
  6612. X      pal[curr].green = dummy;
  6613. X      }
  6614. X   }
  6615. X
  6616. X
  6617. Xstatic void rotcolgb(PALENTRY pal[], int num)
  6618. X   {
  6619. X   int      curr;
  6620. X   int    dummy;
  6621. X
  6622. X    for (curr=0; curr<=num; curr++)
  6623. X      {
  6624. X      dummy = pal[curr].green;
  6625. X      pal[curr].green = pal[curr].blue;
  6626. X      pal[curr].blue = dummy;
  6627. X      }
  6628. X   }
  6629. X
  6630. Xstatic void rotcolbr(PALENTRY pal[], int num)
  6631. X   {
  6632. X   int      curr;
  6633. X   int    dummy;
  6634. X
  6635. X    for (curr=0; curr<=num; curr++)
  6636. X      {
  6637. X      dummy = pal[curr].red;
  6638. X      pal[curr].red = pal[curr].blue;
  6639. X      pal[curr].blue = dummy;
  6640. X      }
  6641. X   }
  6642. X
  6643. X
  6644. X/*
  6645. X * convert a range of colors to grey scale
  6646. X */
  6647. X
  6648. X
  6649. Xstatic void palrangetogrey(PALENTRY pal[], int first, int how_many)
  6650. X   {
  6651. X   PALENTRY      *curr;
  6652. X   BYTE  val;
  6653. X
  6654. X
  6655. X   for (curr = &pal[first]; how_many>0; how_many--, curr++)
  6656. X      {
  6657. X      val = (BYTE) ( ((int)curr->red*30 + (int)curr->green*59 + (int)curr->blue*11) / 100 );
  6658. X      curr->red = curr->green = curr->blue = (BYTE)val;
  6659. X      }
  6660. X   }
  6661. X
  6662. X/*
  6663. X * convert a range of colors to their inverse
  6664. X */
  6665. X
  6666. X
  6667. Xstatic void palrangetonegative(PALENTRY pal[], int first, int how_many)
  6668. X   {
  6669. X   PALENTRY      *curr;
  6670. X
  6671. X   for (curr = &pal[first]; how_many>0; how_many--, curr++)
  6672. X      {
  6673. X      curr->red   = 63 - curr->red;
  6674. X      curr->green = 63 - curr->green;
  6675. X      curr->blue  = 63 - curr->blue;
  6676. X      }
  6677. X   }
  6678. X
  6679. X
  6680. X/*
  6681. X * draw and horizontal/vertical dotted lines
  6682. X */
  6683. X
  6684. X
  6685. Xstatic void hdline(int x, int y, int width)
  6686. X   {
  6687. X   int ctr;
  6688. X   BYTE *ptr;
  6689. X
  6690. X   for (ctr=0, ptr=line_buff; ctr<width; ctr++, ptr++)
  6691. X      *ptr = (ctr&2) ? bg_color : fg_color;
  6692. X
  6693. X   putrow(x, y, width, (char *)line_buff);
  6694. X   }
  6695. X
  6696. X
  6697. Xstatic void vdline(int x, int y, int depth)
  6698. X   {
  6699. X   int ctr;
  6700. X
  6701. X   for (ctr=0; ctr<depth; ctr++, y++)
  6702. X      clip_putcolor(x, y, (ctr&2) ? bg_color : fg_color);
  6703. X   }
  6704. X
  6705. X
  6706. Xstatic void drect(int x, int y, int width, int depth)
  6707. X   {
  6708. X   hdline(x, y, width);
  6709. X   hdline(x, y+depth-1, width);
  6710. X
  6711. X   vdline(x, y, depth);
  6712. X   vdline(x+width-1, y, depth);
  6713. X   }
  6714. X
  6715. X
  6716. X/*
  6717. X * A very simple memory "allocator".
  6718. X *
  6719. X * Each call to mem_alloc() returns size bytes from the array mem_block.
  6720. X *
  6721. X * Be sure to call mem_init() before using mem_alloc()!
  6722. X *
  6723. X */
  6724. X
  6725. Xstatic char     *mem_block;
  6726. Xstatic unsigned  mem_avail;
  6727. X
  6728. X
  6729. Xvoid mem_init(VOIDPTR block, unsigned size)
  6730. X   {
  6731. X   mem_block = (char *)block;
  6732. X   mem_avail = size;
  6733. X   }
  6734. X
  6735. X
  6736. XVOIDPTR mem_alloc(unsigned size)
  6737. X   {
  6738. X   VOIDPTR block;
  6739. X
  6740. X#ifndef XFRACT
  6741. X   if (size & 1)
  6742. X      ++size;   /* allocate even sizes */
  6743. X#else
  6744. X   size = (size+3)&~3; /* allocate word-aligned memory */
  6745. X#endif
  6746. X
  6747. X   if (mem_avail < size)   /* don't let this happen! */
  6748. X      {
  6749. X      static char far msg[] = "editpal.c: Out of memory!\n";
  6750. X
  6751. X      stopmsg(0, msg);
  6752. X      exit(1);
  6753. X      }
  6754. X
  6755. X   block = mem_block;
  6756. X   mem_avail -= size;
  6757. X   mem_block += size;
  6758. X
  6759. X   return(block);
  6760. X   }
  6761. X
  6762. X
  6763. X
  6764. X/*
  6765. X * misc. routines
  6766. X *
  6767. X */
  6768. X
  6769. X
  6770. Xstatic BOOLEAN is_reserved(int color)
  6771. X   {
  6772. X   return ( (reserve_colors && (color==fg_color || color==bg_color) ) ? TRUE : FALSE );
  6773. X   }
  6774. X
  6775. X
  6776. X
  6777. Xstatic BOOLEAN is_in_box(int x, int y, int bx, int by, int bw, int bd)
  6778. X   {
  6779. X   return ( (x >= bx) && (y >= by) && (x < bx+bw) && (y < by+bd) );
  6780. X   }
  6781. X
  6782. X
  6783. X
  6784. Xstatic void draw_diamond(int x, int y, int color)
  6785. X   {
  6786. X   putcolor (x+2, y+0,      color);
  6787. X   hline    (x+1, y+1, 3, color);
  6788. X   hline    (x+0, y+2, 5, color);
  6789. X   hline    (x+1, y+3, 3, color);
  6790. X   putcolor (x+2, y+4,      color);
  6791. X   }
  6792. X
  6793. X
  6794. X
  6795. X/*
  6796. X * Class:     Cursor
  6797. X *
  6798. X * Purpose:   Draw the blinking cross-hair cursor.
  6799. X *
  6800. X * Note:      Only one Cursor can exist (referenced through the_cursor).
  6801. X *          IMPORTANT: Call Cursor_Construct before you use any other
  6802. X *          Cursor_ function!  Call Cursor_Destroy before exiting to
  6803. X *          deallocate memory.
  6804. X */
  6805. X
  6806. Xstruct _Cursor
  6807. X   {
  6808. X
  6809. X   int       x, y;
  6810. X   int       hidden;     /* >0 if mouse hidden */
  6811. X   long    last_blink;
  6812. X   BOOLEAN blink;
  6813. X   char    t[CURSOR_SIZE],      /* save line segments here */
  6814. X       b[CURSOR_SIZE],
  6815. X       l[CURSOR_SIZE],
  6816. X       r[CURSOR_SIZE];
  6817. X   } ;
  6818. X
  6819. X#define Cursor struct _Cursor
  6820. X
  6821. X/* private: */
  6822. X
  6823. X   static  void    Cursor__Draw      (void);
  6824. X   static  void    Cursor__Save      (void);
  6825. X   static  void    Cursor__Restore   (void);
  6826. X
  6827. X/* public: */
  6828. X#ifdef NOT_USED
  6829. X   static  BOOLEAN Cursor_IsHidden  (void);
  6830. X#endif
  6831. X
  6832. X
  6833. X
  6834. Xstatic Cursor *the_cursor = NULL;
  6835. X
  6836. X
  6837. XBOOLEAN Cursor_Construct(void)
  6838. X   {
  6839. X   if (the_cursor != NULL)
  6840. X      return(FALSE);
  6841. X
  6842. X   the_cursor = new(Cursor);
  6843. X
  6844. X   the_cursor->x      = sxdots/2;
  6845. X   the_cursor->y      = sydots/2;
  6846. X   the_cursor->hidden      = 1;
  6847. X   the_cursor->blink      = FALSE;
  6848. X   the_cursor->last_blink = 0;
  6849. X
  6850. X   return (TRUE);
  6851. X   }
  6852. X
  6853. X
  6854. Xvoid Cursor_Destroy(void)
  6855. X   {
  6856. X   if (the_cursor != NULL)
  6857. X      delete(the_cursor);
  6858. X
  6859. X   the_cursor = NULL;
  6860. X   }
  6861. X
  6862. X
  6863. X
  6864. Xstatic void Cursor__Draw(void)
  6865. X   {
  6866. X   int color;
  6867. X
  6868. X   find_special_colors();
  6869. X   color = (the_cursor->blink) ? color_medium : color_dark;
  6870. X
  6871. X   vline(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, color);
  6872. X   vline(the_cursor->x, the_cursor->y+2,         CURSOR_SIZE, color);
  6873. X
  6874. X   hline(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, color);
  6875. X   hline(the_cursor->x+2,          the_cursor->y, CURSOR_SIZE, color);
  6876. X   }
  6877. X
  6878. X
  6879. Xstatic void Cursor__Save(void)
  6880. X   {
  6881. X   vgetrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t);
  6882. X   vgetrow(the_cursor->x, the_cursor->y+2,           CURSOR_SIZE, the_cursor->b);
  6883. X
  6884. X   getrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y,  CURSOR_SIZE, the_cursor->l);
  6885. X   getrow(the_cursor->x+2,           the_cursor->y,  CURSOR_SIZE, the_cursor->r);
  6886. X   }
  6887. X
  6888. X
  6889. Xstatic void Cursor__Restore(void)
  6890. X   {
  6891. X   vputrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t);
  6892. X   vputrow(the_cursor->x, the_cursor->y+2,           CURSOR_SIZE, the_cursor->b);
  6893. X
  6894. X   putrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y,  CURSOR_SIZE, the_cursor->l);
  6895. X   putrow(the_cursor->x+2,           the_cursor->y,  CURSOR_SIZE, the_cursor->r);
  6896. X   }
  6897. X
  6898. X
  6899. X
  6900. Xvoid Cursor_SetPos(int x, int y)
  6901. X   {
  6902. X   if (!the_cursor->hidden)
  6903. X      Cursor__Restore();
  6904. X
  6905. X   the_cursor->x = x;
  6906. X   the_cursor->y = y;
  6907. X
  6908. X   if (!the_cursor->hidden)
  6909. X      {
  6910. X      Cursor__Save();
  6911. X      Cursor__Draw();
  6912. X      }
  6913. X   }
  6914. X
  6915. X#ifdef NOT_USED
  6916. X
  6917. Xstatic int Cursor_IsHidden(void)
  6918. X   {
  6919. X   return ( the_cursor->hidden );
  6920. X   }
  6921. X
  6922. X
  6923. X#endif
  6924. X
  6925. X
  6926. Xvoid Cursor_Move(int xoff, int yoff)
  6927. X   {
  6928. X   if ( !the_cursor->hidden )
  6929. X      Cursor__Restore();
  6930. X
  6931. X   the_cursor->x += xoff;
  6932. X   the_cursor->y += yoff;
  6933. X
  6934. X   if (the_cursor->x < 0)       the_cursor->x = 0;
  6935. X   if (the_cursor->y < 0)       the_cursor->y = 0;
  6936. X   if (the_cursor->x >= sxdots) the_cursor->x = sxdots-1;
  6937. X   if (the_cursor->y >= sydots) the_cursor->y = sydots-1;
  6938. X
  6939. X   if ( !the_cursor->hidden )
  6940. X      {
  6941. X      Cursor__Save();
  6942. X      Cursor__Draw();
  6943. X      }
  6944. X   }
  6945. X
  6946. X
  6947. Xint Cursor_GetX(void)   { return(the_cursor->x); }
  6948. X
  6949. Xint Cursor_GetY(void)   { return(the_cursor->y); }
  6950. X
  6951. X
  6952. Xvoid Cursor_Hide(void)
  6953. X   {
  6954. X   if ( the_cursor->hidden++ == 0 )
  6955. X      Cursor__Restore();
  6956. X   }
  6957. X
  6958. X
  6959. Xvoid Cursor_Show(void)
  6960. X   {
  6961. X   if ( --the_cursor->hidden == 0)
  6962. X      {
  6963. X      Cursor__Save();
  6964. X      Cursor__Draw();
  6965. X      }
  6966. X   }
  6967. X
  6968. X#ifdef XFRACT
  6969. Xvoid Cursor_StartMouseTracking()
  6970. X{
  6971. X    editpal_cursor = 1;
  6972. X}
  6973. X
  6974. Xvoid Cursor_EndMouseTracking()
  6975. X{
  6976. X    editpal_cursor = 0;
  6977. X}
  6978. X#endif
  6979. X
  6980. X/* See if the cursor should blink yet, and blink it if so */
  6981. Xvoid Cursor_CheckBlink(void)
  6982. X{
  6983. X   long tick;
  6984. X   tick = readticker();
  6985. X
  6986. X   if ( (tick - the_cursor->last_blink) > CURSOR_BLINK_RATE )
  6987. X      {
  6988. X      the_cursor->blink = (the_cursor->blink) ? FALSE : TRUE;
  6989. X      the_cursor->last_blink = tick;
  6990. X      if ( !the_cursor->hidden )
  6991. X     Cursor__Draw();
  6992. X      }
  6993. X   else if ( tick < the_cursor->last_blink )
  6994. X      the_cursor->last_blink = tick;
  6995. X}
  6996. X
  6997. Xint Cursor_WaitKey(void)   /* blink cursor while waiting for a key */
  6998. X   {
  6999. X
  7000. X#ifndef XFRACT
  7001. X   while ( !keypressed() ) {
  7002. X       Cursor_CheckBlink();
  7003. X   }
  7004. X#else
  7005. X   while ( !waitkeypressed(1) ) {
  7006. X       Cursor_CheckBlink();
  7007. X   }
  7008. X#endif
  7009. X
  7010. X   return( keypressed() );
  7011. X   }
  7012. X
  7013. X
  7014. X
  7015. X/*
  7016. X * Class:     MoveBox
  7017. X *
  7018. X * Purpose:   Handles the rectangular move/resize box.
  7019. X */
  7020. X
  7021. Xstruct _MoveBox
  7022. X   {
  7023. X   int        x, y;
  7024. X   int        base_width,
  7025. X        base_depth;
  7026. X   int        csize;
  7027. X   BOOLEAN  moved;
  7028. X   BOOLEAN  should_hide;
  7029. X   char    *t, *b,
  7030. X       *l, *r;
  7031. X   } ;
  7032. X
  7033. X#define MoveBox struct _MoveBox
  7034. X
  7035. X/* private: */
  7036. X
  7037. X   static void       MoveBox__Draw     (MoveBox *this);
  7038. X   static void       MoveBox__Erase    (MoveBox *this);
  7039. X   static void       MoveBox__Move     (MoveBox *this, int key);
  7040. X
  7041. X/* public: */
  7042. X
  7043. X   static MoveBox *MoveBox_Construct  (int x, int y, int csize, int base_width,
  7044. X                      int base_depth);
  7045. X   static void       MoveBox_Destroy    (MoveBox *this);
  7046. X   static BOOLEAN  MoveBox_Process    (MoveBox *this); /* returns FALSE if ESCAPED */
  7047. X   static BOOLEAN  MoveBox_Moved      (MoveBox *this);
  7048. X   static BOOLEAN  MoveBox_ShouldHide (MoveBox *this);
  7049. X   static int       MoveBox_X          (MoveBox *this);
  7050. X   static int       MoveBox_Y          (MoveBox *this);
  7051. X   static int       MoveBox_CSize      (MoveBox *this);
  7052. X
  7053. X   static void       MoveBox_SetPos     (MoveBox *this, int x, int y);
  7054. X   static void       MoveBox_SetCSize   (MoveBox *this, int csize);
  7055. X
  7056. X
  7057. X
  7058. Xstatic MoveBox *MoveBox_Construct(int x, int y, int csize, int base_width, int base_depth)
  7059. X   {
  7060. X   MoveBox *this = new(MoveBox);
  7061. X
  7062. X   this->x         = x;
  7063. X   this->y         = y;
  7064. X   this->csize         = csize;
  7065. X   this->base_width  = base_width;
  7066. X   this->base_depth  = base_depth;
  7067. X   this->moved         = FALSE;
  7068. X   this->should_hide = FALSE;
  7069. X   this->t         = newx(sxdots);
  7070. X   this->b         = newx(sxdots);
  7071. X   this->l         = newx(sydots);
  7072. X   this->r         = newx(sydots);
  7073. X
  7074. X   return(this);
  7075. X   }
  7076. X
  7077. X
  7078. Xstatic void MoveBox_Destroy(MoveBox *this)
  7079. X   {
  7080. X   delete(this->t);
  7081. X   delete(this->b);
  7082. X   delete(this->l);
  7083. X   delete(this->r);
  7084. X   delete(this);
  7085. X   }
  7086. X
  7087. X
  7088. Xstatic BOOLEAN MoveBox_Moved(MoveBox *this) { return(this->moved); }
  7089. X
  7090. Xstatic BOOLEAN MoveBox_ShouldHide(MoveBox *this) { return(this->should_hide); }
  7091. X
  7092. Xstatic int MoveBox_X(MoveBox *this)     { return(this->x); }
  7093. X
  7094. Xstatic int MoveBox_Y(MoveBox *this)     { return(this->y); }
  7095. X
  7096. Xstatic int MoveBox_CSize(MoveBox *this)  { return(this->csize); }
  7097. X
  7098. X
  7099. Xstatic void MoveBox_SetPos(MoveBox *this, int x, int y)
  7100. X   {
  7101. X   this->x = x;
  7102. X   this->y = y;
  7103. X   }
  7104. X
  7105. X
  7106. Xstatic void MoveBox_SetCSize(MoveBox *this, int csize)
  7107. X   {
  7108. X   this->csize = csize;
  7109. X   }
  7110. X
  7111. X
  7112. Xstatic void MoveBox__Draw(MoveBox *this)  /* private */
  7113. X   {
  7114. X   int width = this->base_width + this->csize*16+1,
  7115. X       depth = this->base_depth + this->csize*16+1;
  7116. X   int x     = this->x,
  7117. X       y     = this->y;
  7118. X
  7119. X
  7120. X   getrow (x, y,     width, this->t);
  7121. X   getrow (x, y+depth-1, width, this->b);
  7122. X
  7123. X   vgetrow(x,          y, depth, this->l);
  7124. X   vgetrow(x+width-1, y, depth, this->r);
  7125. X
  7126. X   hdline(x, y,         width);
  7127. X   hdline(x, y+depth-1, width);
  7128. X
  7129. X   vdline(x,         y, depth);
  7130. X   vdline(x+width-1, y, depth);
  7131. X   }
  7132. X
  7133. X
  7134. Xstatic void MoveBox__Erase(MoveBox *this)   /* private */
  7135. X   {
  7136. X   int width = this->base_width + this->csize*16+1,
  7137. X       depth = this->base_depth + this->csize*16+1;
  7138. X
  7139. X   vputrow(this->x,        this->y, depth, this->l);
  7140. X   vputrow(this->x+width-1, this->y, depth, this->r);
  7141. X
  7142. X   putrow(this->x, this->y,        width, this->t);
  7143. X   putrow(this->x, this->y+depth-1, width, this->b);
  7144. X   }
  7145. X
  7146. X
  7147. X#define BOX_INC     1
  7148. X#define CSIZE_INC   2
  7149. X
  7150. Xstatic void MoveBox__Move(MoveBox *this, int key)
  7151. X   {
  7152. X   BOOLEAN done  = FALSE;
  7153. X   BOOLEAN first = TRUE;
  7154. X   int       xoff  = 0,
  7155. X       yoff  = 0;
  7156. X
  7157. X   while ( !done )
  7158. X      {
  7159. X      switch(key)
  7160. X     {
  7161. X     case RIGHT_ARROW_2:     xoff += BOX_INC*4;   break;
  7162. X     case RIGHT_ARROW:     xoff += BOX_INC;     break;
  7163. X     case LEFT_ARROW_2:     xoff -= BOX_INC*4;   break;
  7164. X     case LEFT_ARROW:     xoff -= BOX_INC;     break;
  7165. X     case DOWN_ARROW_2:     yoff += BOX_INC*4;   break;
  7166. X     case DOWN_ARROW:     yoff += BOX_INC;     break;
  7167. X     case UP_ARROW_2:     yoff -= BOX_INC*4;   break;
  7168. X     case UP_ARROW:      yoff -= BOX_INC;     break;
  7169. X
  7170. X     default:
  7171. X        done = TRUE;
  7172. X     }
  7173. X
  7174. X      if (!done)
  7175. X     {
  7176. X     if (!first)
  7177. X        getakey();         /* delete key from buffer */
  7178. X     else
  7179. X        first = FALSE;
  7180. X     key = keypressed();   /* peek at the next one... */
  7181. X     }
  7182. X      }
  7183. X
  7184. X   xoff += this->x;
  7185. X   yoff += this->y;   /* (xoff,yoff) = new position */
  7186. X
  7187. X   if (xoff < 0) xoff = 0;
  7188. X   if (yoff < 0) yoff = 0;
  7189. X
  7190. X   if (xoff+this->base_width+this->csize*16+1 > sxdots)
  7191. X       xoff = sxdots - (this->base_width+this->csize*16+1);
  7192. X
  7193. X   if (yoff+this->base_depth+this->csize*16+1 > sydots)
  7194. X      yoff = sydots - (this->base_depth+this->csize*16+1);
  7195. X
  7196. X   if ( xoff!=this->x || yoff!=this->y )
  7197. X      {
  7198. X      MoveBox__Erase(this);
  7199. X      this->y = yoff;
  7200. X      this->x = xoff;
  7201. X      MoveBox__Draw(this);
  7202. X      }
  7203. X   }
  7204. X
  7205. X
  7206. Xstatic BOOLEAN MoveBox_Process(MoveBox *this)
  7207. X   {
  7208. X   int       key;
  7209. X   int       orig_x     = this->x,
  7210. X       orig_y     = this->y,
  7211. X       orig_csize = this->csize;
  7212. X
  7213. X   MoveBox__Draw(this);
  7214. X
  7215. X#ifdef XFRACT
  7216. X   Cursor_StartMouseTracking();
  7217. X#endif
  7218. X   while (1)
  7219. X      {
  7220. X      Cursor_WaitKey();
  7221. X      key = getakey();
  7222. X
  7223. X      if (key==ENTER || key==ENTER_2 || key==ESC || key=='H' || key=='h')
  7224. X     {
  7225. X     if (this->x != orig_x || this->y != orig_y || this->csize != orig_csize)
  7226. X        this->moved = TRUE;
  7227. X     else
  7228. X       this->moved = FALSE;
  7229. X     break;
  7230. X     }
  7231. X
  7232. X      switch(key)
  7233. X     {
  7234. X     case UP_ARROW:
  7235. X     case DOWN_ARROW:
  7236. X     case LEFT_ARROW:
  7237. X     case RIGHT_ARROW:
  7238. X     case UP_ARROW_2:
  7239. X     case DOWN_ARROW_2:
  7240. X     case LEFT_ARROW_2:
  7241. X     case RIGHT_ARROW_2:
  7242. X        MoveBox__Move(this, key);
  7243. X        break;
  7244. X
  7245. X     case PAGE_UP:     /* shrink */
  7246. X        if (this->csize > CSIZE_MIN)
  7247. X           {
  7248. X           int t = this->csize - CSIZE_INC;
  7249. X           int change;
  7250. X
  7251. X           if (t < CSIZE_MIN)
  7252. X          t = CSIZE_MIN;
  7253. X
  7254. X           MoveBox__Erase(this);
  7255. X
  7256. X           change = this->csize - t;
  7257. X           this->csize = t;
  7258. X           this->x += (change*16) / 2;
  7259. X           this->y += (change*16) / 2;
  7260. X           MoveBox__Draw(this);
  7261. X           }
  7262. X        break;
  7263. X
  7264. X     case PAGE_DOWN:   /* grow */
  7265. X        {
  7266. X        int max_width = min(sxdots, MAX_WIDTH);
  7267. X
  7268. X        if (this->base_depth+(this->csize+CSIZE_INC)*16+1 < sydots  &&
  7269. X            this->base_width+(this->csize+CSIZE_INC)*16+1 < max_width )
  7270. X           {
  7271. X           MoveBox__Erase(this);
  7272. X           this->x -= (CSIZE_INC*16) / 2;
  7273. X           this->y -= (CSIZE_INC*16) / 2;
  7274. X           this->csize += CSIZE_INC;
  7275. X           if (this->y+this->base_depth+this->csize*16+1 > sydots)
  7276. X          this->y = sydots - (this->base_depth+this->csize*16+1);
  7277. X           if (this->x+this->base_width+this->csize*16+1 > max_width)
  7278. X          this->x = max_width - (this->base_width+this->csize*16+1);
  7279. X           if (this->y < 0)
  7280. X          this->y = 0;
  7281. X           if (this->x < 0)
  7282. X          this->x = 0;
  7283. X           MoveBox__Draw(this);
  7284. X           }
  7285. X        }
  7286. X        break;
  7287. X     }
  7288. X      }
  7289. X
  7290. X#ifdef XFRACT
  7291. X   Cursor_EndMouseTracking();
  7292. X#endif
  7293. X
  7294. X   MoveBox__Erase(this);
  7295. X
  7296. X   this->should_hide = (key == 'H' || key == 'h') ? TRUE : FALSE;
  7297. X
  7298. X   return( (key==ESC) ? FALSE : TRUE );
  7299. X   }
  7300. X
  7301. X
  7302. X
  7303. X/*
  7304. X * Class:     CEditor
  7305. X *
  7306. X * Purpose:   Edits a single color component (R, G or B)
  7307. X *
  7308. X * Note:      Calls the "other_key" function to process keys it doesn't use.
  7309. X *          The "change" function is called whenever the value is changed
  7310. X *          by the CEditor.
  7311. X */
  7312. X
  7313. Xstruct _CEditor
  7314. X   {
  7315. X   int         x, y;
  7316. X   char      letter;
  7317. X   int         val;
  7318. X   BOOLEAN   done;
  7319. X   BOOLEAN   hidden;
  7320. X#ifndef XFRACT
  7321. X   void    (*other_key)(int key, struct _CEditor *ce, VOIDPTR info);
  7322. X   void    (*change)(struct _CEditor *ce, VOIDPTR info);
  7323. X#else
  7324. X   void    (*other_key)();
  7325. X   void    (*change)();
  7326. X#endif
  7327. X   void     *info;
  7328. X
  7329. X   } ;
  7330. X
  7331. X#define CEditor struct _CEditor
  7332. X
  7333. X/* public: */
  7334. X
  7335. X#ifndef XFRACT
  7336. X   static CEditor *CEditor_Construct( int x, int y, char letter,
  7337. X                      void (*other_key)(int,CEditor*,void*),
  7338. X                                      void (*change)(CEditor*,void*), VOIDPTR info);
  7339. X   static void CEditor_Destroy     (CEditor *this);
  7340. X   static void CEditor_Draw     (CEditor *this);
  7341. X   static void CEditor_SetPos     (CEditor *this, int x, int y);
  7342. X   static void CEditor_SetVal     (CEditor *this, int val);
  7343. X   static int  CEditor_GetVal     (CEditor *this);
  7344. X   static void CEditor_SetDone     (CEditor *this, BOOLEAN done);
  7345. X   static void CEditor_SetHidden (CEditor *this, BOOLEAN hidden);
  7346. X   static int  CEditor_Edit     (CEditor *this);
  7347. X#else
  7348. X   static CEditor *CEditor_Construct( int , int , char ,
  7349. X                                    void (*other_key)(),
  7350. X                                    void (*change)(), VOIDPTR );
  7351. X   static void CEditor_Destroy         (CEditor *);
  7352. X   static void CEditor_Draw    (CEditor *);
  7353. X   static void CEditor_SetPos  (CEditor *, int , int );
  7354. X   static void CEditor_SetVal  (CEditor *, int );
  7355. X   static int  CEditor_GetVal  (CEditor *);
  7356. X   static void CEditor_SetDone         (CEditor *, BOOLEAN );
  7357. X   static void CEditor_SetHidden (CEditor *, BOOLEAN );
  7358. X   static int  CEditor_Edit    (CEditor *);
  7359. X#endif
  7360. X
  7361. X#define CEditor_WIDTH (8*3+4)
  7362. X#define CEditor_DEPTH (8+4)
  7363. X
  7364. X
  7365. X
  7366. X#ifndef XFRACT
  7367. Xstatic CEditor *CEditor_Construct( int x, int y, char letter,
  7368. X                   void (*other_key)(int,CEditor*,VOIDPTR),
  7369. X                   void (*change)(CEditor*, VOIDPTR), VOIDPTR info)
  7370. X#else
  7371. Xstatic CEditor *CEditor_Construct( int x, int y, char letter,
  7372. X                                   void (*other_key)(),
  7373. X                                   void (*change)(), VOIDPTR info)
  7374. X#endif
  7375. X   {
  7376. X   CEditor *this = new(CEditor);
  7377. X
  7378. X   this->x       = x;
  7379. X   this->y       = y;
  7380. X   this->letter    = letter;
  7381. X   this->val       = 0;
  7382. X   this->other_key = other_key;
  7383. X   this->hidden    = FALSE;
  7384. X   this->change    = change;
  7385. X   this->info       = info;
  7386. X
  7387. X   return(this);
  7388. X   }
  7389. X
  7390. X
  7391. Xstatic void CEditor_Destroy(CEditor *this)
  7392. X   {
  7393. X   delete(this);
  7394. X   }
  7395. X
  7396. X
  7397. Xstatic void CEditor_Draw(CEditor *this)
  7398. X   {
  7399. X   if (this->hidden)
  7400. X      return;
  7401. X
  7402. X   Cursor_Hide();
  7403. X   displayf(this->x+2, this->y+2, fg_color, bg_color, "%c%02d", this->letter, this->val);
  7404. X   Cursor_Show();
  7405. X   }
  7406. X
  7407. X
  7408. Xstatic void CEditor_SetPos(CEditor *this, int x, int y)
  7409. X   {
  7410. X   this->x = x;
  7411. X   this->y = y;
  7412. X   }
  7413. X
  7414. X
  7415. Xstatic void CEditor_SetVal(CEditor *this, int val)
  7416. X   {
  7417. X   this->val = val;
  7418. X   }
  7419. X
  7420. X
  7421. Xstatic int CEditor_GetVal(CEditor *this)
  7422. X   {
  7423. X   return(this->val);
  7424. X   }
  7425. X
  7426. X
  7427. Xstatic void CEditor_SetDone(CEditor *this, BOOLEAN done)
  7428. X   {
  7429. X   this->done = done;
  7430. X   }
  7431. X
  7432. X
  7433. Xstatic void CEditor_SetHidden(CEditor *this, BOOLEAN hidden)
  7434. X   {
  7435. X   this->hidden = hidden;
  7436. X   }
  7437. X
  7438. X
  7439. Xstatic int CEditor_Edit(CEditor *this)
  7440. X   {
  7441. X   int key;
  7442. X   int diff;
  7443. X
  7444. X   this->done = FALSE;
  7445. X
  7446. X   if (!this->hidden)
  7447. X      {
  7448. X      Cursor_Hide();
  7449. X      rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, fg_color);
  7450. X      Cursor_Show();
  7451. X      }
  7452. X
  7453. X#ifdef XFRACT
  7454. X   Cursor_StartMouseTracking();
  7455. X#endif
  7456. X   while ( !this->done )
  7457. X      {
  7458. X      Cursor_WaitKey();
  7459. X      key = getakey();
  7460. X
  7461. X      switch( key )
  7462. X     {
  7463. X     case PAGE_UP:
  7464. X        if (this->val < 63)
  7465. X           {
  7466. X           this->val += 5;
  7467. X           if (this->val > 63)
  7468. X          this->val = 63;
  7469. X           CEditor_Draw(this);
  7470. X           this->change(this, this->info);
  7471. X           }
  7472. X        break;
  7473. X
  7474. X     case '+':
  7475. X        diff = 1;
  7476. X        while ( keypressed() == key )
  7477. X           {
  7478. X           getakey();
  7479. X           ++diff;
  7480. X           }
  7481. X        if (this->val < 63)
  7482. X           {
  7483. X           this->val += diff;
  7484. X           if (this->val > 63)
  7485. X          this->val = 63;
  7486. X           CEditor_Draw(this);
  7487. X           this->change(this, this->info);
  7488. X           }
  7489. X        break;
  7490. X
  7491. X     case PAGE_DOWN:
  7492. X        if (this->val > 0)
  7493. X           {
  7494. X           this->val -= 5;
  7495. X           if (this->val < 0)
  7496. X          this->val = 0;
  7497. X           CEditor_Draw(this);
  7498. X           this->change(this, this->info);
  7499. X           } break;
  7500. X
  7501. X     case '-':
  7502. X        diff = 1;
  7503. X        while ( keypressed() == key )
  7504. X           {
  7505. X           getakey();
  7506. X           ++diff;
  7507. X           }
  7508. X        if (this->val > 0)
  7509. X           {
  7510. X           this->val -= diff;
  7511. X           if (this->val < 0)
  7512. X          this->val = 0;
  7513. X           CEditor_Draw(this);
  7514. X           this->change(this, this->info);
  7515. X           }
  7516. X        break;
  7517. X
  7518. X     case '0':
  7519. X     case '1':
  7520. X     case '2':
  7521. X     case '3':
  7522. X     case '4':
  7523. X     case '5':
  7524. X     case '6':
  7525. X     case '7':
  7526. X     case '8':
  7527. X     case '9':
  7528. X        this->val = (key - '0') * 10;
  7529. X        if (this->val > 63)
  7530. X           this->val = 63;
  7531. X        CEditor_Draw(this);
  7532. X        this->change(this, this->info);
  7533. X        break;
  7534. X
  7535. X     default:
  7536. X        this->other_key(key, this, this->info);
  7537. X        break;
  7538. X     } /* switch */
  7539. X      } /* while */
  7540. X#ifdef XFRACT
  7541. X   Cursor_EndMouseTracking();
  7542. X#endif
  7543. X
  7544. X   if (!this->hidden)
  7545. X      {
  7546. X      Cursor_Hide();
  7547. X      rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, bg_color);
  7548. X      Cursor_Show();
  7549. X      }
  7550. X
  7551. X   return(key);
  7552. X   }
  7553. X
  7554. X
  7555. X
  7556. X/*
  7557. X * Class:     RGBEditor
  7558. X *
  7559. X * Purpose:   Edits a complete color using three CEditors for R, G and B
  7560. X */
  7561. X
  7562. Xstruct _RGBEditor
  7563. X   {
  7564. X   int         x, y;          /* position */
  7565. X   int         curr;          /* 0=r, 1=g, 2=b */
  7566. X   int         pal;          /* palette number */
  7567. X   BOOLEAN   done;
  7568. X   BOOLEAN   hidden;
  7569. X   CEditor  *color[3];          /* color editors 0=r, 1=g, 2=b */
  7570. X#ifndef XFRACT
  7571. X   void    (*other_key)(int key, struct _RGBEditor *e, VOIDPTR info);
  7572. X   void    (*change)(struct _RGBEditor *e, VOIDPTR info);
  7573. X#else
  7574. X   void    (*other_key)();
  7575. X   void    (*change)();
  7576. X#endif
  7577. X   void     *info;
  7578. X   } ;
  7579. X
  7580. X#define RGBEditor struct _RGBEditor
  7581. X
  7582. X/* private: */
  7583. X
  7584. X   static void      RGBEditor__other_key (int key, CEditor *ceditor, VOIDPTR info);
  7585. X   static void      RGBEditor__change    (CEditor *ceditor, VOIDPTR info);
  7586. X
  7587. X/* public: */
  7588. X
  7589. X#ifndef XFRACT
  7590. X   static RGBEditor *RGBEditor_Construct(int x, int y,
  7591. X             void (*other_key)(int,RGBEditor*,void*),
  7592. X             void (*change)(RGBEditor*,void*), VOIDPTR info);
  7593. X#else
  7594. X   static RGBEditor *RGBEditor_Construct(int x, int y,
  7595. X                     void (*other_key)(),
  7596. X                     void (*change)(), VOIDPTR info);
  7597. X#endif
  7598. X
  7599. X   static void       RGBEditor_Destroy  (RGBEditor *this);
  7600. X   static void       RGBEditor_SetPos   (RGBEditor *this, int x, int y);
  7601. X   static void       RGBEditor_SetDone  (RGBEditor *this, BOOLEAN done);
  7602. X   static void       RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden);
  7603. X   static void       RGBEditor_BlankSampleBox(RGBEditor *this);
  7604. X   static void       RGBEditor_Update   (RGBEditor *this);
  7605. X   static void       RGBEditor_Draw     (RGBEditor *this);
  7606. X   static int       RGBEditor_Edit     (RGBEditor *this);
  7607. X   static void       RGBEditor_SetRGB   (RGBEditor *this, int pal, PALENTRY *rgb);
  7608. X   static PALENTRY RGBEditor_GetRGB   (RGBEditor *this);
  7609. X
  7610. X#define RGBEditor_WIDTH 62
  7611. X#define RGBEditor_DEPTH (1+1+CEditor_DEPTH*3-2+2)
  7612. X
  7613. X#define RGBEditor_BWIDTH ( RGBEditor_WIDTH - (2+CEditor_WIDTH+1 + 2) )
  7614. X#define RGBEditor_BDEPTH ( RGBEditor_DEPTH - 4 )
  7615. X
  7616. X
  7617. X
  7618. X#ifndef XFRACT
  7619. Xstatic RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(int,RGBEditor*,void*),
  7620. X                      void (*change)(RGBEditor*,void*), VOIDPTR info)
  7621. X#else
  7622. Xstatic RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(),
  7623. X                                      void (*change)(), VOIDPTR info)
  7624. X#endif
  7625. X   {
  7626. X   RGBEditor      *this     = new(RGBEditor);
  7627. X   static char far letter[] = "RGB";
  7628. X   int           ctr;
  7629. X
  7630. X   for (ctr=0; ctr<3; ctr++)
  7631. X      this->color[ctr] = CEditor_Construct(0, 0, letter[ctr], RGBEditor__other_key,
  7632. X                       RGBEditor__change, this);
  7633. X
  7634. X   RGBEditor_SetPos(this, x, y);
  7635. X   this->curr       = 0;
  7636. X   this->pal       = 1;
  7637. X   this->hidden    = FALSE;
  7638. X   this->other_key = other_key;
  7639. X   this->change    = change;
  7640. X   this->info       = info;
  7641. X
  7642. X   return(this);
  7643. X   }
  7644. X
  7645. X
  7646. Xstatic void RGBEditor_Destroy(RGBEditor *this)
  7647. X   {
  7648. X   CEditor_Destroy(this->color[0]);
  7649. X   CEditor_Destroy(this->color[1]);
  7650. X   CEditor_Destroy(this->color[2]);
  7651. X   delete(this);
  7652. X   }
  7653. X
  7654. X
  7655. Xstatic void RGBEditor_SetDone(RGBEditor *this, BOOLEAN done)
  7656. X   {
  7657. X   this->done = done;
  7658. X   }
  7659. X
  7660. X
  7661. Xstatic void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden)
  7662. X   {
  7663. X   this->hidden = hidden;
  7664. X   CEditor_SetHidden(this->color[0], hidden);
  7665. X   CEditor_SetHidden(this->color[1], hidden);
  7666. X   CEditor_SetHidden(this->color[2], hidden);
  7667. X   }
  7668. X
  7669. X
  7670. Xstatic void RGBEditor__other_key(int key, CEditor *ceditor, VOIDPTR info) /* private */
  7671. X   {
  7672. X   RGBEditor *this = (RGBEditor *)info;
  7673. X
  7674. X   switch( key )
  7675. X      {
  7676. X      case 'R':
  7677. X      case 'r':
  7678. X     if (this->curr != 0)
  7679. X        {
  7680. X        this->curr = 0;
  7681. X        CEditor_SetDone(ceditor, TRUE);
  7682. X        }
  7683. X     break;
  7684. X
  7685. X      case 'G':
  7686. X      case 'g':
  7687. X     if (this->curr != 1)
  7688. X        {
  7689. X        this->curr = 1;
  7690. X        CEditor_SetDone(ceditor, TRUE);
  7691. X        }
  7692. X     break;
  7693. X
  7694. X      case 'B':
  7695. X      case 'b':
  7696. X     if (this->curr != 2)
  7697. X        {
  7698. X        this->curr = 2;
  7699. X        CEditor_SetDone(ceditor, TRUE);
  7700. X        }
  7701. X     break;
  7702. X
  7703. X      case DELETE:   /* move to next CEditor */
  7704. X     if ( ++this->curr > 2)
  7705. X        this->curr = 0;
  7706. X     CEditor_SetDone(ceditor, TRUE);
  7707. X     break;
  7708. X
  7709. X      case INSERT:   /* move to prev CEditor */
  7710. X     if ( --this->curr < 0)
  7711. X        this->curr = 2;
  7712. X     CEditor_SetDone(ceditor, TRUE);
  7713. X     break;
  7714. X
  7715. X      default:
  7716. X     this->other_key(key, this, this->info);
  7717. X     if (this->done)
  7718. X        CEditor_SetDone(ceditor, TRUE);
  7719. X     break;
  7720. X      }
  7721. X   }
  7722. X
  7723. X
  7724. X
  7725. X#ifdef __TURBOC__
  7726. X#   pragma argsused   /* kills "arg not used" warning */
  7727. X#endif
  7728. X
  7729. Xstatic void RGBEditor__change(CEditor *ceditor, VOIDPTR info) /* private */
  7730. X   {
  7731. X   RGBEditor *this = (RGBEditor *)info;
  7732. X
  7733. X   if ( this->pal < colors && !is_reserved(this->pal) )
  7734. X      setpal(this->pal, CEditor_GetVal(this->color[0]),
  7735. X      CEditor_GetVal(this->color[1]), CEditor_GetVal(this->color[2]));
  7736. X
  7737. X   this->change(this, this->info);
  7738. X   }
  7739. X
  7740. X
  7741. Xstatic void RGBEditor_SetPos(RGBEditor *this, int x, int y)
  7742. X   {
  7743. X   this->x = x;
  7744. X   this->y = y;
  7745. X
  7746. X   CEditor_SetPos(this->color[0], x+2, y+2);
  7747. X   CEditor_SetPos(this->color[1], x+2, y+2+CEditor_DEPTH-1);
  7748. X   CEditor_SetPos(this->color[2], x+2, y+2+CEditor_DEPTH-1+CEditor_DEPTH-1);
  7749. X   }
  7750. X
  7751. X
  7752. Xstatic void RGBEditor_BlankSampleBox(RGBEditor *this)
  7753. X   {
  7754. X   if (this->hidden)
  7755. X      return ;
  7756. X
  7757. X   Cursor_Hide();
  7758. X   fillrect(this->x+2+CEditor_WIDTH+1+1, this->y+2+1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color);
  7759. X   Cursor_Show();
  7760. X   }
  7761. X
  7762. X
  7763. Xstatic void RGBEditor_Update(RGBEditor *this)
  7764. X   {
  7765. X   int x1 = this->x+2+CEditor_WIDTH+1+1,
  7766. X       y1 = this->y+2+1;
  7767. X
  7768. X   if (this->hidden)
  7769. X      return ;
  7770. X
  7771. X   Cursor_Hide();
  7772. X
  7773. X   if ( this->pal >= colors )
  7774. X      {
  7775. X      fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color);
  7776. X      draw_diamond(x1+(RGBEditor_BWIDTH-5)/2, y1+(RGBEditor_BDEPTH-5)/2, fg_color);
  7777. X      }
  7778. X
  7779. X   else if ( is_reserved(this->pal) )
  7780. X      {
  7781. X      int x2 = x1+RGBEditor_BWIDTH-3,
  7782. X      y2 = y1+RGBEditor_BDEPTH-3;
  7783. X
  7784. X      fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color);
  7785. X      draw_line(x1, y1, x2, y2, fg_color);
  7786. X      draw_line(x1, y2, x2, y1, fg_color);
  7787. X      }
  7788. X   else
  7789. X      fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, this->pal);
  7790. X
  7791. X   CEditor_Draw(this->color[0]);
  7792. X   CEditor_Draw(this->color[1]);
  7793. X   CEditor_Draw(this->color[2]);
  7794. X   Cursor_Show();
  7795. X   }
  7796. X
  7797. X
  7798. Xstatic void RGBEditor_Draw(RGBEditor *this)
  7799. X   {
  7800. X   if (this->hidden)
  7801. X      return ;
  7802. X
  7803. X   Cursor_Hide();
  7804. X   drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH);
  7805. X   fillrect(this->x+1, this->y+1, RGBEditor_WIDTH-2, RGBEditor_DEPTH-2, bg_color);
  7806. X   rect(this->x+1+CEditor_WIDTH+2, this->y+2, RGBEditor_BWIDTH, RGBEditor_BDEPTH, fg_color);
  7807. X   RGBEditor_Update(this);
  7808. X   Cursor_Show();
  7809. X   }
  7810. X
  7811. X
  7812. Xstatic int RGBEditor_Edit(RGBEditor *this)
  7813. X   {
  7814. X   int key;
  7815. X
  7816. X   this->done = FALSE;
  7817. X
  7818. X   if (!this->hidden)
  7819. X      {
  7820. X      Cursor_Hide();
  7821. X      rect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH, fg_color);
  7822. X      Cursor_Show();
  7823. X      }
  7824. X
  7825. X   while ( !this->done )
  7826. X      key = CEditor_Edit( this->color[this->curr] );
  7827. X
  7828. X   if (!this->hidden)
  7829. X      {
  7830. X      Cursor_Hide();
  7831. X      drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH);
  7832. X      Cursor_Show();
  7833. X      }
  7834. X
  7835. X   return (key);
  7836. X   }
  7837. X
  7838. X
  7839. Xstatic void RGBEditor_SetRGB(RGBEditor *this, int pal, PALENTRY *rgb)
  7840. X   {
  7841. X   this->pal = pal;
  7842. X   CEditor_SetVal(this->color[0], rgb->red);
  7843. X   CEditor_SetVal(this->color[1], rgb->green);
  7844. X   CEditor_SetVal(this->color[2], rgb->blue);
  7845. X   }
  7846. X
  7847. X
  7848. Xstatic PALENTRY RGBEditor_GetRGB(RGBEditor *this)
  7849. X   {
  7850. X   PALENTRY pal;
  7851. X
  7852. X   pal.red   = CEditor_GetVal(this->color[0]);
  7853. X   pal.green = CEditor_GetVal(this->color[1]);
  7854. X   pal.blue  = CEditor_GetVal(this->color[2]);
  7855. X
  7856. X   return(pal);
  7857. X   }
  7858. X
  7859. X
  7860. X
  7861. X/*
  7862. X * Class:     PalTable
  7863. X *
  7864. X * Purpose:   This is where it all comes together.  Creates the two RGBEditors
  7865. X *          and the palette. Moves the cursor, hides/restores the screen,
  7866. X *          handles (S)hading, (C)opying, e(X)clude mode, the "Y" exclusion
  7867. X *          mode, (Z)oom option, (H)ide palette, rotation, etc.
  7868. X *
  7869. X */
  7870. X
  7871. Xenum stored_at_values
  7872. X   {
  7873. X   NOWHERE,
  7874. X   DISK,
  7875. X   MEMORY
  7876. X   } ;
  7877. X
  7878. X/*
  7879. X
  7880. XModes:
  7881. X   Auto:          "A", " "
  7882. X   Exclusion:     "X", "Y", " "
  7883. X   Freestyle:     "F", " "
  7884. X   S(t)ripe mode: "T", " "
  7885. X
  7886. X*/
  7887. X
  7888. X
  7889. X
  7890. Xstruct  _PalTable
  7891. X   {
  7892. X   int         x, y;
  7893. X   int         csize;
  7894. X   int         active;   /* which RGBEditor is active (0,1) */
  7895. X   int         curr[2];
  7896. X   RGBEditor    *rgb[2];
  7897. X   MoveBox      *movebox;
  7898. X   BOOLEAN     done;
  7899. X   BOOLEAN     exclude;
  7900. X   BOOLEAN     auto_select;
  7901. X   PALENTRY     pal[256];
  7902. X   FILE         *undo_file;
  7903. X   BOOLEAN       curr_changed;
  7904. X   int           num_redo;
  7905. X   int         hidden;
  7906. X   int         stored_at;
  7907. X   FILE         *file;
  7908. X   char far     *memory;
  7909. X
  7910. X   PALENTRY far *save_pal[8];
  7911. X
  7912. X   PALENTRY      fs_color;
  7913. X   int           top,bottom; /* top and bottom colours of freestyle band */
  7914. X   int           bandwidth; /*size of freestyle colour band */
  7915. X   BOOLEAN       freestyle;
  7916. X   } ;
  7917. X
  7918. X#define PalTable struct _PalTable
  7919. X
  7920. X/* private: */
  7921. X
  7922. X   static void    PalTable__DrawStatus  (PalTable *this, BOOLEAN stripe_mode);
  7923. X   static void      PalTable__HlPal       (PalTable *this, int pnum, int color);
  7924. X   static void      PalTable__Draw        (PalTable *this);
  7925. X   static BOOLEAN PalTable__SetCurr     (PalTable *this, int which, int curr);
  7926. X   static BOOLEAN PalTable__MemoryAlloc (PalTable *this, long size);
  7927. X   static void      PalTable__SaveRect    (PalTable *this);
  7928. X   static void      PalTable__RestoreRect (PalTable *this);
  7929. X   static void      PalTable__SetPos      (PalTable *this, int x, int y);
  7930. X   static void      PalTable__SetCSize    (PalTable *this, int csize);
  7931. X   static int      PalTable__GetCursorColor(PalTable *this);
  7932. X   static void      PalTable__DoCurs      (PalTable *this, int key);
  7933. X   static void      PalTable__Rotate      (PalTable *this, int dir, int lo, int hi);
  7934. X   static void      PalTable__UpdateDAC   (PalTable *this);
  7935. X   static void    PalTable__other_key   (int key, RGBEditor *rgb, VOIDPTR info);
  7936. X   static void    PalTable__SaveUndoData(PalTable *this, int first, int last);
  7937. X   static void    PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last);
  7938. X   static void    PalTable__UndoProcess (PalTable *this, int delta);
  7939. X   static void    PalTable__Undo        (PalTable *this);
  7940. X   static void    PalTable__Redo        (PalTable *this);
  7941. X   static void    PalTable__change      (RGBEditor *rgb, VOIDPTR info);
  7942. X
  7943. X/* public: */
  7944. X
  7945. X   static PalTable *PalTable_Construct (void);
  7946. X   static void        PalTable_Destroy   (PalTable *this);
  7947. X   static void        PalTable_Process   (PalTable *this);
  7948. X   static void        PalTable_SetHidden (PalTable *this, BOOLEAN hidden);
  7949. X   static void        PalTable_Hide      (PalTable *this, RGBEditor *rgb, BOOLEAN hidden);
  7950. X
  7951. X
  7952. X#define PalTable_PALX (1)
  7953. X#define PalTable_PALY (2+RGBEditor_DEPTH+2)
  7954. X
  7955. X#define UNDO_DATA        (1)
  7956. X#define UNDO_DATA_SINGLE (2)
  7957. X#define UNDO_ROTATE      (3)
  7958. X
  7959. X
  7960. X
  7961. X/*  - Freestyle code - */
  7962. X
  7963. X
  7964. Xvoid PalTable__CalcTopBottom(PalTable *this)
  7965. X   {
  7966. X   if (this->curr[this->active] < this->bandwidth )
  7967. X      this->bottom = 0;
  7968. X   else
  7969. X      this->bottom = (this->curr[this->active]) - this->bandwidth;
  7970. X
  7971. X   if (this->curr[this->active] > (255-this->bandwidth) )
  7972. X      this->top = 255;
  7973. X   else
  7974. X      this->top = (this->curr[this->active]) + this->bandwidth;
  7975. X   }
  7976. X
  7977. X
  7978. Xvoid PalTable__PutBand(PalTable *this, PALENTRY *pal)
  7979. X   {
  7980. X   int r,b,a;
  7981. X
  7982. X  /* clip top and bottom values to stop them running off the end of the DAC */
  7983. X
  7984. X   PalTable__CalcTopBottom(this);
  7985. X
  7986. X  /* put bands either side of current colour */
  7987. X
  7988. X   a = this->curr[this->active];
  7989. X   b = this->bottom;
  7990. X   r = this->top;
  7991. X
  7992. X   pal[a] = this->fs_color;
  7993. X
  7994. X   if (r != a && a != b)
  7995. X      {
  7996. X      mkpalrange(&pal[a], &pal[r], &pal[a], r-a, 1);
  7997. X      mkpalrange(&pal[b], &pal[a], &pal[b], a-b, 1);
  7998. X      }
  7999. X
  8000. X   }
  8001. X
  8002. X
  8003. X/* - Undo.Redo code - */
  8004. X
  8005. X
  8006. Xstatic void PalTable__SaveUndoData(PalTable *this, int first, int last)
  8007. X   {
  8008. X   int num;
  8009. X
  8010. X   if ( this->undo_file == NULL )
  8011. X      return ;
  8012. X
  8013. X   num = (last - first) + 1;
  8014. X
  8015. X#ifdef DEBUG_UNDO
  8016. X   mprintf("%6ld Writing Undo DATA from %d to %d (%d)", ftell(this->undo_file), first, last, num);
  8017. X#endif
  8018. X
  8019. X   fseek(this->undo_file, 0, SEEK_CUR);
  8020. X   if ( num == 1 )
  8021. X      {
  8022. X      putc(UNDO_DATA_SINGLE, this->undo_file);
  8023. X      putc(first, this->undo_file);
  8024. X      fwrite(this->pal+first, 3, 1, this->undo_file);
  8025. X      putw( 1 + 1 + 3 + sizeof(int), this->undo_file);
  8026. X      }
  8027. X   else
  8028. X      {
  8029. X      putc(UNDO_DATA, this->undo_file);
  8030. X      putc(first, this->undo_file);
  8031. X      putc(last,  this->undo_file);
  8032. X      fwrite(this->pal+first, 3, num, this->undo_file);
  8033. X      putw(1 + 2 + (num*3) + sizeof(int), this->undo_file);
  8034. X      }
  8035. X
  8036. X   this->num_redo = 0;
  8037. X   }
  8038. X
  8039. X
  8040. Xstatic void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last)
  8041. X   {
  8042. X   if ( this->undo_file == NULL )
  8043. X      return ;
  8044. X
  8045. X#ifdef DEBUG_UNDO
  8046. X   mprintf("%6ld Writing Undo ROTATE of %d from %d to %d", ftell(this->undo_file), dir, first, last);
  8047. X#endif
  8048. X
  8049. X   fseek(this->undo_file, 0, SEEK_CUR);
  8050. X   putc(UNDO_ROTATE, this->undo_file);
  8051. X   putc(first, this->undo_file);
  8052. X   putc(last,  this->undo_file);
  8053. X   putw(dir, this->undo_file);
  8054. X   putw(1 + 2 + sizeof(int), this->undo_file);
  8055. X
  8056. X   this->num_redo = 0;
  8057. X   }
  8058. X
  8059. X
  8060. Xstatic void PalTable__UndoProcess(PalTable *this, int delta)   /* undo/redo common code */
  8061. X   {              /* delta = -1 for undo, +1 for redo */
  8062. X   int cmd = getc(this->undo_file);
  8063. X
  8064. X   switch( cmd )
  8065. X      {
  8066. X      case UNDO_DATA:
  8067. X      case UNDO_DATA_SINGLE:
  8068. X         {
  8069. X         int      first, last, num;
  8070. X         PALENTRY temp[256];
  8071. X
  8072. X         if ( cmd == UNDO_DATA )
  8073. X            {
  8074. X            first = (unsigned char)getc(this->undo_file);
  8075. X            last  = (unsigned char)getc(this->undo_file);
  8076. X            }
  8077. X         else  /* UNDO_DATA_SINGLE */
  8078. X            first = last = (unsigned char)getc(this->undo_file);
  8079. X
  8080. X         num = (last - first) + 1;
  8081. X
  8082. X#ifdef DEBUG_UNDO
  8083. X         mprintf("          Reading DATA from %d to %d", first, last);
  8084. X#endif
  8085. X
  8086. X         fread(temp, 3, num, this->undo_file);
  8087. X
  8088. X         fseek(this->undo_file, -(num*3), SEEK_CUR);  /* go to start of undo/redo data */
  8089. X         fwrite(this->pal+first, 3, num, this->undo_file);  /* write redo/undo data */
  8090. X
  8091. X         memmove(this->pal+first, temp, num*3);
  8092. X
  8093. X         PalTable__UpdateDAC(this);
  8094. X
  8095. X         RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
  8096. X         RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
  8097. X         RGBEditor_Update(this->rgb[0]);
  8098. X         RGBEditor_Update(this->rgb[1]);
  8099. X         break;
  8100. X         }
  8101. X
  8102. X      case UNDO_ROTATE:
  8103. X         {
  8104. X         int first = (unsigned char)getc(this->undo_file);
  8105. X         int last  = (unsigned char)getc(this->undo_file);
  8106. X         int dir   = getw(this->undo_file);
  8107. X
  8108. X#ifdef DEBUG_UNDO
  8109. X         mprintf("          Reading ROTATE of %d from %d to %d", dir, first, last);
  8110. X#endif
  8111. X         PalTable__Rotate(this, delta*dir, first, last);
  8112. X         break;
  8113. X         }
  8114. X
  8115. X      default:
  8116. X#ifdef DEBUG_UNDO
  8117. X         mprintf("          Unknown command: %d", cmd);
  8118. X#endif
  8119. X         break;
  8120. X      }
  8121. X
  8122. X   fseek(this->undo_file, 0, SEEK_CUR);  /* to put us in read mode */
  8123. X   getw(this->undo_file);  /* read size */
  8124. X   }
  8125. X
  8126. X
  8127. Xstatic void PalTable__Undo(PalTable *this)
  8128. X   {
  8129. X   int  size;
  8130. X   long pos;
  8131. X
  8132. X   if ( ftell(this->undo_file) <= 0  )   /* at beginning of file? */
  8133. X      {                                  /*   nothing to undo -- exit */
  8134. X      return ;
  8135. X      }
  8136. X
  8137. X   fseek(this->undo_file, -(int)sizeof(int), SEEK_CUR);  /* go back to get size */
  8138. X
  8139. X   size = getw(this->undo_file);
  8140. X   fseek(this->undo_file, -size, SEEK_CUR);   /* go to start of undo */
  8141. X
  8142. X#ifdef DEBUG_UNDO
  8143. X   mprintf("%6ld Undo:", ftell(this->undo_file));
  8144. X#endif
  8145. X
  8146. X   pos = ftell(this->undo_file);
  8147. X
  8148. X   PalTable__UndoProcess(this, -1);
  8149. X
  8150. X   fseek(this->undo_file, pos, SEEK_SET);   /* go to start of this block */
  8151. X
  8152. X   ++this->num_redo;
  8153. X   }
  8154. X
  8155. X
  8156. Xstatic void PalTable__Redo(PalTable *this)
  8157. X   {
  8158. X   if ( this->num_redo <= 0 )
  8159. X      return ;
  8160. X
  8161. X#ifdef DEBUG_UNDO
  8162. X   mprintf("%6ld Redo:", ftell(this->undo_file));
  8163. X#endif
  8164. X
  8165. X   fseek(this->undo_file, 0, SEEK_CUR);  /* to make sure we are in "read" mode */
  8166. X   PalTable__UndoProcess(this, 1);
  8167. X
  8168. X   --this->num_redo;
  8169. X   }
  8170. X
  8171. X
  8172. X/* - everything else - */
  8173. X
  8174. X
  8175. X#define STATUS_LEN (4)
  8176. X
  8177. Xstatic void PalTable__DrawStatus(PalTable *this, BOOLEAN stripe_mode)
  8178. X   {
  8179. X   int width = 1+(this->csize*16)+1+1;
  8180. X
  8181. X   if ( !this->hidden && ( width - (RGBEditor_WIDTH*2+4) >= STATUS_LEN*8 ) )
  8182. X      {
  8183. X      int x = this->x + 2 + RGBEditor_WIDTH,
  8184. X          y = this->y + PalTable_PALY - 10;
  8185. X
  8186. X      Cursor_Hide();
  8187. X
  8188. X      displayc(x+(0*8), y, fg_color, bg_color, (this->auto_select) ? 'A' : 254);
  8189. X      displayc(x+(1*8), y, fg_color, bg_color, (this->exclude==1)  ? 'X' :
  8190. X                                               (this->exclude==2)  ? 'Y' : 254);
  8191. X      displayc(x+(2*8), y, fg_color, bg_color, (this->freestyle)   ? 'F' : 254);
  8192. X      displayc(x+(3*8), y, fg_color, bg_color, (stripe_mode)       ? 'T' : 254);
  8193. X
  8194. X      Cursor_Show();
  8195. X      }
  8196. X   }
  8197. X
  8198. X
  8199. Xstatic void PalTable__HlPal(PalTable *this, int pnum, int color)
  8200. X   {
  8201. X   int x    = this->x + PalTable_PALX + (pnum%16)*this->csize,
  8202. X       y    = this->y + PalTable_PALY + (pnum/16)*this->csize,
  8203. X       size = this->csize;
  8204. X
  8205. X   if (this->hidden)
  8206. X      return ;
  8207. X
  8208. X   Cursor_Hide();
  8209. X
  8210. X   if (color < 0)
  8211. X      drect(x, y, size+1, size+1);
  8212. X   else
  8213. X      rect(x, y, size+1, size+1, color);
  8214. X
  8215. X   Cursor_Show();
  8216. X   }
  8217. X
  8218. X
  8219. Xstatic void PalTable__Draw(PalTable *this)
  8220. X   {
  8221. X   int pal;
  8222. X   int xoff, yoff;
  8223. X   int width;
  8224. X
  8225. X   if (this->hidden)
  8226. X      return ;
  8227. X
  8228. X   Cursor_Hide();
  8229. X
  8230. X   width = 1+(this->csize*16)+1+1;
  8231. X
  8232. X   rect(this->x, this->y, width, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1, fg_color);
  8233. X
  8234. X   fillrect(this->x+1, this->y+1, width-2, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1-2, bg_color);
  8235. X
  8236. X   hline(this->x, this->y+PalTable_PALY-1, width, fg_color);
  8237. X
  8238. X   if ( width - (RGBEditor_WIDTH*2+4) >= TITLE_LEN*8 )
  8239. X      {
  8240. X      int center = (width - TITLE_LEN*8) / 2;
  8241. X
  8242. X      displayf(this->x+center, this->y+2+RGBEditor_DEPTH/2-4, fg_color, bg_color, TITLE);
  8243. X      }
  8244. X
  8245. X   RGBEditor_Draw(this->rgb[0]);
  8246. X   RGBEditor_Draw(this->rgb[1]);
  8247. X
  8248. X   for (pal=0; pal<256; pal++)
  8249. X      {
  8250. X      xoff = PalTable_PALX + (pal%16) * this->csize;
  8251. X      yoff = PalTable_PALY + (pal/16) * this->csize;
  8252. X
  8253. X      if ( pal >= colors )
  8254. X     {
  8255. X     fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color);
  8256. X     draw_diamond(this->x + xoff + this->csize/2 - 1, this->y + yoff + this->csize/2 - 1, fg_color);
  8257. X     }
  8258. X
  8259. X      else if ( is_reserved(pal) )
  8260. X     {
  8261. X     int x1 = this->x + xoff + 1,
  8262. X         y1 = this->y + yoff + 1,
  8263. X         x2 = x1 + this->csize - 2,
  8264. X         y2 = y1 + this->csize - 2;
  8265. X     fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color);
  8266. X     draw_line(x1, y1, x2, y2, fg_color);
  8267. X     draw_line(x1, y2, x2, y1, fg_color);
  8268. X     }
  8269. X      else
  8270. X     fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, pal);
  8271. X
  8272. X      }
  8273. X
  8274. X   if (this->active == 0)
  8275. X      {
  8276. X      PalTable__HlPal(this, this->curr[1], -1);
  8277. X      PalTable__HlPal(this, this->curr[0], fg_color);
  8278. X      }
  8279. X   else
  8280. X      {
  8281. X      PalTable__HlPal(this, this->curr[0], -1);
  8282. X      PalTable__HlPal(this, this->curr[1], fg_color);
  8283. X      }
  8284. X
  8285. X   PalTable__DrawStatus(this, FALSE);
  8286. X
  8287. X   Cursor_Show();
  8288. X   }
  8289. X
  8290. X
  8291. X
  8292. Xstatic BOOLEAN PalTable__SetCurr(PalTable *this, int which, int curr)
  8293. X   {
  8294. X   BOOLEAN redraw = (which < 0) ? TRUE : FALSE;
  8295. X
  8296. X   if ( redraw )
  8297. X      {
  8298. X      which = this->active;
  8299. X      curr = this->curr[which];
  8300. X      }
  8301. X   else
  8302. X      if ( curr == this->curr[which] || curr < 0 )
  8303. X     return (FALSE);
  8304. X
  8305. X   Cursor_Hide();
  8306. X
  8307. X   PalTable__HlPal(this, this->curr[0], bg_color);
  8308. X   PalTable__HlPal(this, this->curr[1], bg_color);
  8309. X   PalTable__HlPal(this, this->top,     bg_color);
  8310. X   PalTable__HlPal(this, this->bottom,  bg_color);
  8311. X
  8312. X   if ( this->freestyle )
  8313. X      {
  8314. X      this->curr[which] = curr;
  8315. X
  8316. X      PalTable__CalcTopBottom(this);
  8317. X
  8318. X      PalTable__HlPal(this, this->top,    -1);
  8319. X      PalTable__HlPal(this, this->bottom, -1);
  8320. X      PalTable__HlPal(this, this->curr[this->active], fg_color);
  8321. X
  8322. X      RGBEditor_SetRGB(this->rgb[which], this->curr[which], &this->fs_color);
  8323. X      RGBEditor_Update(this->rgb[which]);
  8324. X
  8325. X      PalTable__UpdateDAC(this);
  8326. X
  8327. X      Cursor_Show();
  8328. X
  8329. X      return (TRUE);
  8330. X      }
  8331. X
  8332. X   this->curr[which] = curr;
  8333. X
  8334. X   if (this->curr[0] != this->curr[1])
  8335. X      PalTable__HlPal(this, this->curr[this->active==0?1:0], -1);
  8336. X   PalTable__HlPal(this, this->curr[this->active], fg_color);
  8337. X
  8338. X   RGBEditor_SetRGB(this->rgb[which], this->curr[which], &(this->pal[this->curr[which]]));
  8339. X
  8340. X   if (redraw)
  8341. X      {
  8342. X      int other = (which==0) ? 1 : 0;
  8343. X      RGBEditor_SetRGB(this->rgb[other], this->curr[other], &(this->pal[this->curr[other]]));
  8344. X      RGBEditor_Update(this->rgb[0]);
  8345. X      RGBEditor_Update(this->rgb[1]);
  8346. X      }
  8347. X   else
  8348. X      RGBEditor_Update(this->rgb[which]);
  8349. X
  8350. X   if (this->exclude)
  8351. X      PalTable__UpdateDAC(this);
  8352. X
  8353. X   Cursor_Show();
  8354. X
  8355. X   this->curr_changed = FALSE;
  8356. X
  8357. X   return(TRUE);
  8358. X   }
  8359. X
  8360. X
  8361. Xstatic BOOLEAN PalTable__MemoryAlloc(PalTable *this, long size)
  8362. X   {
  8363. X   char far *temp;
  8364. X
  8365. X   if (debugflag = 420)
  8366. X      {
  8367. X      this->stored_at = NOWHERE;
  8368. X      return (FALSE);   /* can't do it */
  8369. X      }
  8370. X   temp = farmemalloc(FAR_RESERVE);   /* minimum free space */
  8371. X
  8372. X   if (temp == NULL)
  8373. X      {
  8374. X      this->stored_at = NOWHERE;
  8375. X      return (FALSE);   /* can't do it */
  8376. X      }
  8377. X
  8378. X   this->memory = farmemalloc( size );
  8379. X
  8380. X   farmemfree(temp);
  8381. X
  8382. X   if ( this->memory == NULL )
  8383. X      {
  8384. X      this->stored_at = NOWHERE;
  8385. X      return (FALSE);
  8386. X      }
  8387. X   else
  8388. X      {
  8389. X      this->stored_at = MEMORY;
  8390. X      return (TRUE);
  8391. X      }
  8392. X   }
  8393. X
  8394. X
  8395. Xstatic void PalTable__SaveRect(PalTable *this)
  8396. X   {
  8397. X   char buff[MAX_WIDTH];
  8398. X   int  width = PalTable_PALX + this->csize*16 + 1 + 1,
  8399. X        depth = PalTable_PALY + this->csize*16 + 1 + 1;
  8400. X   int  yoff;
  8401. X
  8402. X
  8403. X   /* first, do any de-allocationg */
  8404. X
  8405. X   switch( this->stored_at )
  8406. X      {
  8407. X      case NOWHERE:
  8408. X     break;
  8409. X
  8410. X      case DISK:
  8411. X     break;
  8412. X
  8413. X      case MEMORY:
  8414. X     if (this->memory != NULL)
  8415. X        farmemfree(this->memory);
  8416. X     this->memory = NULL;
  8417. X     break;
  8418. X      } ;
  8419. X
  8420. X   /* allocate space and store the rect */
  8421. X
  8422. X   if ( PalTable__MemoryAlloc(this, (long)width*depth) )
  8423. X      {
  8424. X      char far  *ptr = this->memory;
  8425. X      char far  *bufptr = buff; /* MSC needs this indirection to get it right */
  8426. X
  8427. X      Cursor_Hide();
  8428. X      for (yoff=0; yoff<depth; yoff++)
  8429. X     {
  8430. X     getrow(this->x, this->y+yoff, width, buff);
  8431. X     hline (this->x, this->y+yoff, width, bg_color);
  8432. X     movedata(FP_SEG(bufptr), FP_OFF(bufptr), FP_SEG(ptr), FP_OFF(ptr), width);
  8433. X     ptr = (char far *)normalize(ptr+width);
  8434. X     }
  8435. X      Cursor_Show();
  8436. X      }
  8437. X
  8438. X   else /* to disk */
  8439. X      {
  8440. X      this->stored_at = DISK;
  8441. X
  8442. X      if ( this->file == NULL )
  8443. X     {
  8444. X     this->file = fopen(scrnfile, "w+b");
  8445. X     if (this->file == NULL)
  8446. X        {
  8447. X        this->stored_at = NOWHERE;
  8448. X        buzzer(3);
  8449. X        return ;
  8450. X        }
  8451. X     }
  8452. X
  8453. X      rewind(this->file);
  8454. X      Cursor_Hide();
  8455. X      for (yoff=0; yoff<depth; yoff++)
  8456. X     {
  8457. X     getrow(this->x, this->y+yoff, width, buff);
  8458. X     hline (this->x, this->y+yoff, width, bg_color);
  8459. X     if ( fwrite(buff, width, 1, this->file) != 1 )
  8460. X        {
  8461. X        buzzer(3);
  8462. X        break;
  8463. X        }
  8464. X     }
  8465. X      Cursor_Show();
  8466. X      }
  8467. X
  8468. X   }
  8469. X
  8470. X
  8471. Xstatic void PalTable__RestoreRect(PalTable *this)
  8472. X   {
  8473. X   char buff[MAX_WIDTH];
  8474. X   int  width = PalTable_PALX + this->csize*16 + 1 + 1,
  8475. X        depth = PalTable_PALY + this->csize*16 + 1 + 1;
  8476. X   int  yoff;
  8477. X
  8478. X   if (this->hidden)
  8479. X      return;
  8480. X
  8481. X   switch ( this->stored_at )
  8482. X      {
  8483. X      case DISK:
  8484. X     rewind(this->file);
  8485. X     Cursor_Hide();
  8486. X     for (yoff=0; yoff<depth; yoff++)
  8487. X        {
  8488. X        if ( fread(buff, width, 1, this->file) != 1 )
  8489. X           {
  8490. X           buzzer(3);
  8491. X           break;
  8492. X           }
  8493. X        putrow(this->x, this->y+yoff, width, buff);
  8494. X        }
  8495. X     Cursor_Show();
  8496. X     break;
  8497. X
  8498. X      case MEMORY:
  8499. X     {
  8500. X     char far  *ptr = this->memory;
  8501. X     char far  *bufptr = buff; /* MSC needs this indirection to get it right */
  8502. X
  8503. X     Cursor_Hide();
  8504. X     for (yoff=0; yoff<depth; yoff++)
  8505. X        {
  8506. X        movedata(FP_SEG(ptr), FP_OFF(ptr), FP_SEG(bufptr), FP_OFF(bufptr), width);
  8507. X        putrow(this->x, this->y+yoff, width, buff);
  8508. X        ptr = (char far *)normalize(ptr+width);
  8509. X        }
  8510. X     Cursor_Show();
  8511. X     break;
  8512. X     }
  8513. X
  8514. X      case NOWHERE:
  8515. X     break;
  8516. X      } /* switch */
  8517. X   }
  8518. X
  8519. X
  8520. Xstatic void PalTable__SetPos(PalTable *this, int x, int y)
  8521. X   {
  8522. X   int width = PalTable_PALX + this->csize*16 + 1 + 1;
  8523. X
  8524. X   this->x = x;
  8525. X   this->y = y;
  8526. X
  8527. X   RGBEditor_SetPos(this->rgb[0], x+2, y+2);
  8528. X   RGBEditor_SetPos(this->rgb[1], x+width-2-RGBEditor_WIDTH, y+2);
  8529. X   }
  8530. X
  8531. X
  8532. Xstatic void PalTable__SetCSize(PalTable *this, int csize)
  8533. X   {
  8534. X   this->csize = csize;
  8535. X   PalTable__SetPos(this, this->x, this->y);
  8536. X   }
  8537. X
  8538. X
  8539. Xstatic int PalTable__GetCursorColor(PalTable *this)
  8540. X   {
  8541. X   int x     = Cursor_GetX(),
  8542. X       y     = Cursor_GetY(),
  8543. X       size;
  8544. X   int color = getcolor(x, y);
  8545. X
  8546. X   if ( is_reserved(color) )
  8547. X      {
  8548. X      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) )
  8549. X     {  /* is the cursor over the editor? */
  8550. X     x -= this->x + PalTable_PALX;
  8551. X     y -= this->y + PalTable_PALY;
  8552. X     size = this->csize;
  8553. X
  8554. X     if (x < 0 || y < 0 || x > size*16 || y > size*16)
  8555. X        return (-1);
  8556. X
  8557. X     if ( x == size*16 )
  8558. X        --x;
  8559. X     if ( y == size*16 )
  8560. X        --y;
  8561. X
  8562. X     return ( (y/size)*16 + x/size );
  8563. X     }
  8564. X      else
  8565. X     return (color);
  8566. X      }
  8567. X
  8568. X   return (color);
  8569. X   }
  8570. X
  8571. X
  8572. X
  8573. X#define CURS_INC 1
  8574. X
  8575. Xstatic void PalTable__DoCurs(PalTable *this, int key)
  8576. X   {
  8577. X   BOOLEAN done  = FALSE;
  8578. X   BOOLEAN first = TRUE;
  8579. X   int       xoff  = 0,
  8580. X       yoff  = 0;
  8581. X
  8582. X   while ( !done )
  8583. X      {
  8584. X      switch(key)
  8585. X     {
  8586. X     case RIGHT_ARROW_2:     xoff += CURS_INC*4;   break;
  8587. X     case RIGHT_ARROW:     xoff += CURS_INC;     break;
  8588. X     case LEFT_ARROW_2:     xoff -= CURS_INC*4;   break;
  8589. X     case LEFT_ARROW:     xoff -= CURS_INC;     break;
  8590. X     case DOWN_ARROW_2:     yoff += CURS_INC*4;   break;
  8591. X     case DOWN_ARROW:     yoff += CURS_INC;     break;
  8592. X     case UP_ARROW_2:     yoff -= CURS_INC*4;   break;
  8593. X     case UP_ARROW:      yoff -= CURS_INC;     break;
  8594. X
  8595. X     default:
  8596. X        done = TRUE;
  8597. X     }
  8598. X
  8599. X      if (!done)
  8600. X     {
  8601. X     if (!first)
  8602. X        getakey();         /* delete key from buffer */
  8603. X     else
  8604. X        first = FALSE;
  8605. X     key = keypressed();   /* peek at the next one... */
  8606. X     }
  8607. X      }
  8608. X
  8609. X   Cursor_Move(xoff, yoff);
  8610. X
  8611. X   if (this->auto_select)
  8612. X      PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  8613. X   }
  8614. X
  8615. X
  8616. X#ifdef __TURBOC__
  8617. X#   pragma argsused
  8618. X#endif
  8619. X
  8620. Xstatic void PalTable__change(RGBEditor *rgb, VOIDPTR info)
  8621. X   {
  8622. X   PalTable *this = (PalTable *)info;
  8623. X   int       pnum = this->curr[this->active];
  8624. X
  8625. X   if ( this->freestyle )
  8626. X      {
  8627. X      this->fs_color = RGBEditor_GetRGB(rgb);
  8628. X      PalTable__UpdateDAC(this);
  8629. X      return ;
  8630. X      }
  8631. X
  8632. X   if ( !this->curr_changed )
  8633. X      {
  8634. X      PalTable__SaveUndoData(this, pnum, pnum);
  8635. X      this->curr_changed = TRUE;
  8636. X      }
  8637. X
  8638. X   this->pal[pnum] = RGBEditor_GetRGB(rgb);
  8639. X
  8640. X   if (this->curr[0] == this->curr[1])
  8641. X      {
  8642. X      int      other = this->active==0 ? 1 : 0;
  8643. X      PALENTRY color;
  8644. X
  8645. X      color = RGBEditor_GetRGB(this->rgb[this->active]);
  8646. X      RGBEditor_SetRGB(this->rgb[other], this->curr[other], &color);
  8647. X
  8648. X      Cursor_Hide();
  8649. X      RGBEditor_Update(this->rgb[other]);
  8650. X      Cursor_Show();
  8651. X      }
  8652. X
  8653. X   }
  8654. X
  8655. X
  8656. Xstatic void PalTable__UpdateDAC(PalTable *this)
  8657. X   {
  8658. X   if ( this->exclude )
  8659. X      {
  8660. X      memset(dacbox, 0, 256*3);
  8661. X      if (this->exclude == 1)
  8662. X     {
  8663. X     int a = this->curr[this->active];
  8664. X     memmove(dacbox[a], &this->pal[a], 3);
  8665. X     }
  8666. X      else
  8667. X     {
  8668. X     int a = this->curr[0],
  8669. X         b = this->curr[1];
  8670. X
  8671. X     if (a>b)
  8672. X        {
  8673. X        int t=a;
  8674. X        a=b;
  8675. X        b=t;
  8676. X        }
  8677. X
  8678. X     memmove(dacbox[a], &this->pal[a], 3*(1+(b-a)));
  8679. X     }
  8680. X      }
  8681. X   else
  8682. X      {
  8683. X      memmove(dacbox[0], this->pal, 3*colors);
  8684. X
  8685. X      if ( this->freestyle )
  8686. X         PalTable__PutBand(this, (PALENTRY *)dacbox);   /* apply band to dacbox */
  8687. X      }
  8688. X
  8689. X   if ( !this->hidden )
  8690. X      {
  8691. X      if (inverse)
  8692. X     {
  8693. X     memset(dacbox[fg_color], 0, 3);     /* dacbox[fg] = (0,0,0) */
  8694. X     memset(dacbox[bg_color], 48, 3);     /* dacbox[bg] = (48,48,48) */
  8695. X     }
  8696. X      else
  8697. X     {
  8698. X     memset(dacbox[bg_color], 0, 3);     /* dacbox[bg] = (0,0,0) */
  8699. X     memset(dacbox[fg_color], 48, 3);     /* dacbox[fg] = (48,48,48) */
  8700. X     }
  8701. X      }
  8702. X
  8703. X   spindac(0,1);
  8704. X   }
  8705. X
  8706. X
  8707. Xstatic void PalTable__Rotate(PalTable *this, int dir, int lo, int hi)
  8708. X   {
  8709. X
  8710. X   rotatepal(this->pal, dir, lo, hi);
  8711. X
  8712. X   Cursor_Hide();
  8713. X
  8714. X   /* update the DAC.  */
  8715. X
  8716. X   PalTable__UpdateDAC(this);
  8717. X
  8718. X   /* update the editors. */
  8719. X
  8720. X   RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
  8721. X   RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
  8722. X   RGBEditor_Update(this->rgb[0]);
  8723. X   RGBEditor_Update(this->rgb[1]);
  8724. X
  8725. X   Cursor_Show();
  8726. X   }
  8727. X
  8728. X
  8729. Xstatic void PalTable__other_key(int key, RGBEditor *rgb, VOIDPTR info)
  8730. X   {
  8731. X   PalTable *this = (PalTable *)info;
  8732. X
  8733. X   switch(key)
  8734. X      {
  8735. X      case '\\':    /* move/resize */
  8736. X     {
  8737. X     if (this->hidden)
  8738. X        break;         /* cannot move a hidden pal */
  8739. X     Cursor_Hide();
  8740. X     PalTable__RestoreRect(this);
  8741. X     MoveBox_SetPos(this->movebox, this->x, this->y);
  8742. X     MoveBox_SetCSize(this->movebox, this->csize);
  8743. X     if ( MoveBox_Process(this->movebox) )
  8744. X        {
  8745. X        if ( MoveBox_ShouldHide(this->movebox) )
  8746. X           PalTable_SetHidden(this, TRUE);
  8747. X        else if ( MoveBox_Moved(this->movebox) )
  8748. X           {
  8749. X           PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox));
  8750. X           PalTable__SetCSize(this, MoveBox_CSize(this->movebox));
  8751. X           PalTable__SaveRect(this);
  8752. X           }
  8753. X        }
  8754. X     PalTable__Draw(this);
  8755. X     Cursor_Show();
  8756. X
  8757. X     RGBEditor_SetDone(this->rgb[this->active], TRUE);
  8758. X
  8759. X     if (this->auto_select)
  8760. X        PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  8761. X     break;
  8762. X     }
  8763. X
  8764. X      case 'Y':    /* exclude range */
  8765. X      case 'y':
  8766. X     if ( this->exclude==2 )
  8767. X        this->exclude = 0;
  8768. X     else
  8769. X        this->exclude = 2;
  8770. X     PalTable__UpdateDAC(this);
  8771. X         PalTable__DrawStatus(this, FALSE);
  8772. X     break;
  8773. X
  8774. X      case 'X':
  8775. X      case 'x':     /* exclude current entry */
  8776. X     if ( this->exclude==1 )
  8777. X        this->exclude = 0;
  8778. X     else
  8779. X        this->exclude = 1;
  8780. X     PalTable__UpdateDAC(this);
  8781. X         PalTable__DrawStatus(this, FALSE);
  8782. X     break;
  8783. X
  8784. X      case RIGHT_ARROW:
  8785. X      case LEFT_ARROW:
  8786. X      case UP_ARROW:
  8787. X      case DOWN_ARROW:
  8788. X      case RIGHT_ARROW_2:
  8789. X      case LEFT_ARROW_2:
  8790. X      case UP_ARROW_2:
  8791. X      case DOWN_ARROW_2:
  8792. X     PalTable__DoCurs(this, key);
  8793. X     break;
  8794. X
  8795. X      case ESC:
  8796. X     this->done = TRUE;
  8797. X     RGBEditor_SetDone(rgb, TRUE);
  8798. X     break;
  8799. X
  8800. X      case ' ':     /* select the other palette register */
  8801. X     this->active = (this->active==0) ? 1 : 0;
  8802. X     if (this->auto_select)
  8803. X        PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  8804. X      else
  8805. X        PalTable__SetCurr(this, -1, 0);
  8806. X
  8807. X     if (this->exclude || this->freestyle)
  8808. X        PalTable__UpdateDAC(this);
  8809. X
  8810. X     RGBEditor_SetDone(rgb, TRUE);
  8811. X     break;
  8812. X
  8813. X      case ENTER:    /* set register to color under cursor.  useful when not */
  8814. X      case ENTER_2:  /* in auto_select mode */
  8815. X
  8816. X         if ( this->freestyle )
  8817. X            {
  8818. X            PalTable__SaveUndoData(this, this->bottom, this->top);
  8819. X            PalTable__PutBand(this, this->pal);
  8820. X            }
  8821. X
  8822. X     PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  8823. X
  8824. X     if (this->exclude || this->freestyle )
  8825. X        PalTable__UpdateDAC(this);
  8826. X
  8827. X     RGBEditor_SetDone(rgb, TRUE);
  8828. X     break;
  8829. X
  8830. X      case 'D':    /* copy (Duplicate?) color in inactive to color in active */
  8831. X      case 'd':
  8832. X     {
  8833. X     int   a = this->active,
  8834. X          b = (a==0) ? 1 : 0;
  8835. X     PALENTRY t;
  8836. X
  8837. X     t = RGBEditor_GetRGB(this->rgb[b]);
  8838. X     Cursor_Hide();
  8839. X
  8840. X     RGBEditor_SetRGB(this->rgb[a], this->curr[a], &t);
  8841. X     RGBEditor_Update(this->rgb[a]);
  8842. X     PalTable__change(this->rgb[a], this);
  8843. X     PalTable__UpdateDAC(this);
  8844. X
  8845. X     Cursor_Show();
  8846. X     break;
  8847. X     }
  8848. X
  8849. X      case '=':    /* create a shade range between the two entries */
  8850. X     {
  8851. X     int a = this->curr[0],
  8852. X         b = this->curr[1];
  8853. X
  8854. X     if (a > b)
  8855. X        {
  8856. X        int t = a;
  8857. X        a = b;
  8858. X        b = t;
  8859. X        }
  8860. X
  8861. X         PalTable__SaveUndoData(this, a, b);
  8862. X
  8863. X     if (a != b)
  8864. X        {
  8865. X        mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, 1);
  8866. X        PalTable__UpdateDAC(this);
  8867. X        }
  8868. X
  8869. X     break;
  8870. X     }
  8871. X
  8872. X      case '!':    /* swap r<->g */
  8873. X     {
  8874. X     int a = this->curr[0],
  8875. X         b = this->curr[1];
  8876. X
  8877. X     if (a > b)
  8878. X        {
  8879. X        int t = a;
  8880. X        a = b;
  8881. X        b = t;
  8882. X        }
  8883. X
  8884. X         PalTable__SaveUndoData(this, a, b);
  8885. X
  8886. X     if (a != b)
  8887. X        {
  8888. X        rotcolrg(&this->pal[a], b-a);
  8889. X        PalTable__UpdateDAC(this);
  8890. X        }
  8891. X
  8892. X
  8893. X     break;
  8894. X     }
  8895. X
  8896. X      case '@':    /* swap g<->b */
  8897. X     {
  8898. X     int a = this->curr[0],
  8899. X         b = this->curr[1];
  8900. X
  8901. X     if (a > b)
  8902. X        {
  8903. X        int t = a;
  8904. X        a = b;
  8905. X        b = t;
  8906. X        }
  8907. X
  8908. X         PalTable__SaveUndoData(this, a, b);
  8909. X
  8910. X     if (a != b)
  8911. X        {
  8912. X        rotcolgb(&this->pal[a], b-a);
  8913. X        PalTable__UpdateDAC(this);
  8914. X        }
  8915. X
  8916. X     break;
  8917. X     }
  8918. X
  8919. X      case '#':    /* swap r<->b */
  8920. X     {
  8921. X     int a = this->curr[0],
  8922. X         b = this->curr[1];
  8923. X
  8924. X     if (a > b)
  8925. X        {
  8926. X        int t = a;
  8927. X        a = b;
  8928. X        b = t;
  8929. X        }
  8930. X
  8931. X         PalTable__SaveUndoData(this, a, b);
  8932. X
  8933. X     if (a != b)
  8934. X        {
  8935. X        rotcolbr(&this->pal[a], b-a);
  8936. X        PalTable__UpdateDAC(this);
  8937. X        }
  8938. X
  8939. X     break;
  8940. X     }
  8941. X
  8942. X
  8943. X      case 'T':
  8944. X      case 't':   /* s(T)ripe mode */
  8945. X     {
  8946. X     int key;
  8947. X
  8948. X     Cursor_Hide();
  8949. X         PalTable__DrawStatus(this, TRUE);
  8950. X     key = getakeynohelp();
  8951. X         PalTable__DrawStatus(this, FALSE);
  8952. X     Cursor_Show();
  8953. X
  8954. X     if (key >= '1' && key <= '9')
  8955. X        {
  8956. X        int a = this->curr[0],
  8957. X        b = this->curr[1];
  8958. X
  8959. X        if (a > b)
  8960. X           {
  8961. X           int t = a;
  8962. X           a = b;
  8963. X           b = t;
  8964. X           }
  8965. X
  8966. X            PalTable__SaveUndoData(this, a, b);
  8967. X
  8968. X        if (a != b)
  8969. X           {
  8970. X           mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, key-'0');
  8971. X           PalTable__UpdateDAC(this);
  8972. X           }
  8973. X        }
  8974. X
  8975. X     break;
  8976. X     }
  8977. X
  8978. X      case 'M':   /* set gamma */
  8979. X      case 'm':
  8980. X      {
  8981. X          int i;
  8982. X          char buf[20];
  8983. X          sprintf(buf,"%.3f",1./gamma_val);
  8984. X          stackscreen();
  8985. X          i = field_prompt(0,"Enter gamma value",NULL,buf,20,NULL);
  8986. X          unstackscreen();
  8987. X          if (i != -1) {
  8988. X          sscanf(buf,"%f",&gamma_val);
  8989. X          if (gamma_val==0) {
  8990. X              gamma_val = 0.0000000001;
  8991. X          }
  8992. X          gamma_val = 1./gamma_val;
  8993. X          }
  8994. X      }
  8995. X      break;
  8996. X      case 'A':   /* toggle auto-select mode */
  8997. X      case 'a':
  8998. X     this->auto_select = (this->auto_select) ? FALSE : TRUE;
  8999. X     if (this->auto_select)
  9000. X        {
  9001. X        PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  9002. X        if (this->exclude)
  9003. X           PalTable__UpdateDAC(this);
  9004. X        }
  9005. X         PalTable__DrawStatus(this, FALSE);
  9006. X     break;
  9007. X
  9008. X      case 'H':
  9009. X      case 'h': /* toggle hide/display of palette editor */
  9010. X     Cursor_Hide();
  9011. X     PalTable_Hide(this, rgb, (BOOLEAN)((this->hidden) ? FALSE : TRUE));
  9012. X     Cursor_Show();
  9013. X     break;
  9014. X
  9015. X      case '.':   /* rotate once */
  9016. X      case ',':
  9017. X     {
  9018. X         int dir = (key=='.') ? 1 : -1;
  9019. X
  9020. X         PalTable__SaveUndoRotate(this, dir, rotate_lo, rotate_hi);
  9021. X     PalTable__Rotate(this, dir, rotate_lo, rotate_hi);
  9022. X     break;
  9023. X     }
  9024. X
  9025. X      case '>':   /* continuous rotation (until a key is pressed) */
  9026. X      case '<':
  9027. X     {
  9028. X         int  dir;
  9029. X     long tick;
  9030. X         int  diff = 0;
  9031. X
  9032. X     Cursor_Hide();
  9033. X
  9034. X     if ( !this->hidden )
  9035. X        {
  9036. X        RGBEditor_BlankSampleBox(this->rgb[0]);
  9037. X        RGBEditor_BlankSampleBox(this->rgb[1]);
  9038. X        RGBEditor_SetHidden(this->rgb[0], TRUE);
  9039. X        RGBEditor_SetHidden(this->rgb[1], TRUE);
  9040. X        }
  9041. X
  9042. X         do
  9043. X            {
  9044. X            dir = (key=='>') ? 1 : -1;
  9045. X
  9046. X           while ( !keypressed() )
  9047. X           {
  9048. X           tick = readticker();
  9049. X           PalTable__Rotate(this, dir, rotate_lo, rotate_hi);
  9050. X               diff += dir;
  9051. X           while (readticker() == tick) ;   /* wait until a tick passes */
  9052. X           }
  9053. X
  9054. X          key = getakey();
  9055. X            }
  9056. X         while (key=='<' || key=='>');
  9057. X
  9058. X     if ( !this->hidden )
  9059. X        {
  9060. X        RGBEditor_SetHidden(this->rgb[0], FALSE);
  9061. X        RGBEditor_SetHidden(this->rgb[1], FALSE);
  9062. X        RGBEditor_Update(this->rgb[0]);
  9063. X        RGBEditor_Update(this->rgb[1]);
  9064. X        }
  9065. X
  9066. X         if ( diff != 0 )
  9067. X            PalTable__SaveUndoRotate(this, diff, rotate_lo, rotate_hi);
  9068. X
  9069. X     Cursor_Show();
  9070. X     break;
  9071. X     }
  9072. X
  9073. X      case 'I':     /* invert the fg & bg colors */
  9074. X      case 'i':
  9075. X    inverse = !inverse;
  9076. X    PalTable__UpdateDAC(this);
  9077. X    break;
  9078. X
  9079. X      case 'V':
  9080. X      case 'v':     /* set the reserved colors to the editor colors */
  9081. X     if ( this->curr[0] >= colors || this->curr[1] >= colors ||
  9082. X          this->curr[0] == this->curr[1] )
  9083. X        {
  9084. X        buzzer(2);
  9085. X        break;
  9086. X        }
  9087. X
  9088. X     fg_color = this->curr[0];
  9089. X     bg_color = this->curr[1];
  9090. X
  9091. X     if ( !this->hidden )
  9092. X        {
  9093. X        Cursor_Hide();
  9094. X        PalTable__UpdateDAC(this);
  9095. X        PalTable__Draw(this);
  9096. X        Cursor_Show();
  9097. X        }
  9098. X
  9099. X     RGBEditor_SetDone(this->rgb[this->active], TRUE);
  9100. X     break;
  9101. X
  9102. X      case 'O':    /* set rotate_lo and rotate_hi to editors */
  9103. X      case 'o':
  9104. X     if (this->curr[0] > this->curr[1])
  9105. X        {
  9106. X        rotate_lo = this->curr[1];
  9107. X        rotate_hi = this->curr[0];
  9108. X        }
  9109. X     else
  9110. X        {
  9111. X        rotate_lo = this->curr[0];
  9112. X        rotate_hi = this->curr[1];
  9113. X        }
  9114. X     break;
  9115. X
  9116. X      case F2:      /* restore a palette */
  9117. X      case F3:
  9118. X      case F4:
  9119. X      case F5:
  9120. X      case F6:
  9121. X      case F7:
  9122. X      case F8:
  9123. X      case F9:
  9124. X     {
  9125. X     int which = key - F2;
  9126. X
  9127. X     if ( this->save_pal[which] != NULL )
  9128. X        {
  9129. X        struct SREGS seg;
  9130. X
  9131. X        Cursor_Hide();
  9132. X
  9133. X            PalTable__SaveUndoData(this, 0, 255);
  9134. X
  9135. X        segread(&seg);
  9136. X        movedata(FP_SEG(this->save_pal[which]), FP_OFF(this->save_pal[which]),
  9137. X             seg.ds, (USEGTYPE)(this->pal), 256*3);
  9138. X
  9139. X        PalTable__UpdateDAC(this);
  9140. X
  9141. X        PalTable__SetCurr(this, -1, 0);
  9142. X        Cursor_Show();
  9143. X        RGBEditor_SetDone(this->rgb[this->active], TRUE);
  9144. X        }
  9145. X     else
  9146. X        buzzer(3);     /* error buzz */
  9147. X     break;
  9148. X     }
  9149. X
  9150. X      case SF2:   /* save a palette */
  9151. X      case SF3:
  9152. X      case SF4:
  9153. X      case SF5:
  9154. X      case SF6:
  9155. X      case SF7:
  9156. X      case SF8:
  9157. X      case SF9:
  9158. X     {
  9159. X     int which = key - SF2;
  9160. X
  9161. X     if ( this->save_pal[which] != NULL )
  9162. X        {
  9163. X        struct SREGS seg;
  9164. X
  9165. X        segread(&seg);
  9166. X        movedata(seg.ds, (USEGTYPE)(this->pal), FP_SEG(this->save_pal[which]),
  9167. X            FP_OFF(this->save_pal[which]), 256*3);
  9168. X        }
  9169. X     else
  9170. X        buzzer(3); /* oops! short on memory! */
  9171. X     break;
  9172. X     }
  9173. X
  9174. X      case 'L':     /* load a .map palette */
  9175. X      case 'l':
  9176. X     {
  9177. X         PalTable__SaveUndoData(this, 0, 255);
  9178. X
  9179. X     load_palette();
  9180. X#ifndef XFRACT
  9181. X     getpalrange(0, colors, this->pal);
  9182. X#else
  9183. X     getpalrange(0, 256, this->pal);
  9184. X#endif
  9185. X     PalTable__UpdateDAC(this);
  9186. X     RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
  9187. X     RGBEditor_Update(this->rgb[0]);
  9188. X     RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
  9189. X     RGBEditor_Update(this->rgb[1]);
  9190. X     break;
  9191. X     }
  9192. X
  9193. X      case 'S':     /* save a .map palette */
  9194. X      case 's':
  9195. X     {
  9196. X#ifndef XFRACT
  9197. X     setpalrange(0, colors, this->pal);
  9198. X#else
  9199. X     setpalrange(0, 256, this->pal);
  9200. X#endif
  9201. X     save_palette();
  9202. X     PalTable__UpdateDAC(this);
  9203. X     break;
  9204. X     }
  9205. X
  9206. X      case 'C':     /* color cycling sub-mode */
  9207. X      case 'c':
  9208. X     {
  9209. X     BOOLEAN oldhidden = this->hidden;
  9210. X
  9211. X         PalTable__SaveUndoData(this, 0, 255);
  9212. X
  9213. X     Cursor_Hide();
  9214. X     if ( !oldhidden )
  9215. X        PalTable_Hide(this, rgb, TRUE);
  9216. X     setpalrange(0, colors, this->pal);
  9217. X     rotate(0);
  9218. X     getpalrange(0, colors, this->pal);
  9219. X     PalTable__UpdateDAC(this);
  9220. X     if ( !oldhidden )
  9221. X        {
  9222. X        RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
  9223. X        RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
  9224. X        PalTable_Hide(this, rgb, FALSE);
  9225. X        }
  9226. X     Cursor_Show();
  9227. X     break;
  9228. X     }
  9229. X
  9230. X      case 'F':
  9231. X      case 'f':    /* toggle freestyle palette edit mode */
  9232. X         this->freestyle= (this->freestyle) ? FALSE :TRUE;
  9233. X
  9234. X         PalTable__SetCurr(this, -1, 0);
  9235. X
  9236. X         if ( !this->freestyle )   /* if turning off... */
  9237. X            PalTable__UpdateDAC(this);
  9238. X
  9239. X         PalTable__DrawStatus(this, FALSE);
  9240. X         break;
  9241. X
  9242. X      case CTL_DEL:  /* rt plus down */
  9243. X         if (this->bandwidth >0 )
  9244. X            this->bandwidth  --;
  9245. X         else
  9246. X            this->bandwidth=0;
  9247. X         PalTable__SetCurr(this, -1, 0);
  9248. X         break;
  9249. X
  9250. X      case CTL_INSERT: /* rt plus up */
  9251. X         if (this->bandwidth <255 )
  9252. X           this->bandwidth ++;
  9253. X         else
  9254. X            this->bandwidth = 255;
  9255. X         PalTable__SetCurr(this, -1, 0);
  9256. X         break;
  9257. X
  9258. X      case 'W':   /* convert to greyscale */
  9259. X      case 'w':
  9260. X     {
  9261. X     switch ( this->exclude )
  9262. X        {
  9263. X        case 0:   /* normal mode.  convert all colors to grey scale */
  9264. X               PalTable__SaveUndoData(this, 0, 255);
  9265. X           palrangetogrey(this->pal, 0, 256);
  9266. X           break;
  9267. X
  9268. X        case 1:   /* 'x' mode. convert current color to grey scale.  */
  9269. X               PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]);
  9270. X           palrangetogrey(this->pal, this->curr[this->active], 1);
  9271. X           break;
  9272. X
  9273. X        case 2:  /* 'y' mode.  convert range between editors to grey. */
  9274. X           {
  9275. X           int a = this->curr[0],
  9276. X           b = this->curr[1];
  9277. X
  9278. X           if (a > b)
  9279. X          {
  9280. X          int t = a;
  9281. X          a = b;
  9282. X          b = t;
  9283. X          }
  9284. X
  9285. X               PalTable__SaveUndoData(this, a, b);
  9286. X           palrangetogrey(this->pal, a, 1+(b-a));
  9287. X           break;
  9288. X           }
  9289. X        }
  9290. X
  9291. X     PalTable__UpdateDAC(this);
  9292. X     RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
  9293. X     RGBEditor_Update(this->rgb[0]);
  9294. X     RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
  9295. X     RGBEditor_Update(this->rgb[1]);
  9296. X     break;
  9297. X     }
  9298. X
  9299. X      case 'N':   /* convert to negative color */
  9300. X      case 'n':
  9301. X     {
  9302. X     switch ( this->exclude )
  9303. X        {
  9304. X        case 0:     /* normal mode.  convert all colors to grey scale */
  9305. X               PalTable__SaveUndoData(this, 0, 255);
  9306. X           palrangetonegative(this->pal, 0, 256);
  9307. X           break;
  9308. X
  9309. X        case 1:     /* 'x' mode. convert current color to grey scale.  */
  9310. X               PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]);
  9311. X           palrangetonegative(this->pal, this->curr[this->active], 1);
  9312. X           break;
  9313. X
  9314. X        case 2:  /* 'y' mode.  convert range between editors to grey. */
  9315. X           {
  9316. X           int a = this->curr[0],
  9317. X           b = this->curr[1];
  9318. X
  9319. X           if (a > b)
  9320. X          {
  9321. X          int t = a;
  9322. X          a = b;
  9323. X          b = t;
  9324. X          }
  9325. X
  9326. X               PalTable__SaveUndoData(this, a, b);
  9327. X           palrangetonegative(this->pal, a, 1+(b-a));
  9328. X           break;
  9329. X           }
  9330. X        }
  9331. X
  9332. X     PalTable__UpdateDAC(this);
  9333. X     RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
  9334. X     RGBEditor_Update(this->rgb[0]);
  9335. X     RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
  9336. X     RGBEditor_Update(this->rgb[1]);
  9337. X     break;
  9338. X     }
  9339. X
  9340. X      case 'U':     /* Undo */
  9341. X      case 'u':
  9342. X         PalTable__Undo(this);
  9343. X         break;
  9344. X
  9345. X      case 'e':    /* Redo */
  9346. X      case 'E':
  9347. X         PalTable__Redo(this);
  9348. X         break;
  9349. X
  9350. X      } /* switch */
  9351. X   }
  9352. X
  9353. X
  9354. Xstatic void PalTable__MkDefaultPalettes(PalTable *this)  /* creates default Fkey palettes */
  9355. X   {
  9356. X   PALENTRY     black,
  9357. X            white;
  9358. X   PALENTRY     temp[256];
  9359. X   int            ctr;
  9360. X   struct SREGS seg;
  9361. X
  9362. X   black.red = black.green = black.blue = 0;
  9363. X   white.red = white.green = white.blue = 63;
  9364. X   mkpalrange(&black, &white, temp, 256, 1); /* boring! */
  9365. X
  9366. X   segread(&seg);
  9367. X
  9368. X   for (ctr=0; ctr<8; ctr++)   /* copy temp into all fkey saves */
  9369. X      movedata(seg.ss, (USEGTYPE)(temp), FP_SEG(this->save_pal[ctr]),
  9370. X           FP_OFF(this->save_pal[ctr]), 256*3);
  9371. X   }
  9372. X
  9373. X
  9374. X
  9375. Xstatic PalTable *PalTable_Construct(void)
  9376. X   {
  9377. X   PalTable     *this = new(PalTable);
  9378. X   int         csize;
  9379. X   int         ctr;
  9380. X   PALENTRY far *mem_block;
  9381. X   void far     *temp;
  9382. X
  9383. X   temp = farmemalloc(FAR_RESERVE);
  9384. X
  9385. X   if ( temp != NULL )
  9386. X      {
  9387. X      mem_block = (PALENTRY far *)farmemalloc(256L*3 * 8);
  9388. X
  9389. X      if ( mem_block == NULL )
  9390. X     {
  9391. X     for (ctr=0; ctr<8; ctr++)
  9392. X        this->save_pal[ctr] = NULL;
  9393. X     }
  9394. X      else
  9395. X     {
  9396. X     for (ctr=0; ctr<8; ctr++)
  9397. X        this->save_pal[ctr] = mem_block + (256*ctr);
  9398. X
  9399. X     PalTable__MkDefaultPalettes(this);
  9400. X     }
  9401. X      farmemfree(temp);
  9402. X      }
  9403. X
  9404. X   this->rgb[0] = RGBEditor_Construct(0, 0, PalTable__other_key,
  9405. X          PalTable__change, this);
  9406. X   this->rgb[1] = RGBEditor_Construct(0, 0, PalTable__other_key,
  9407. X          PalTable__change, this);
  9408. X
  9409. X   this->movebox = MoveBox_Construct(0,0,0, PalTable_PALX+1, PalTable_PALY+1);
  9410. X
  9411. X   this->active      = 0;
  9412. X   this->curr[0]     = 1;
  9413. X   this->curr[1]     = 1;
  9414. X   this->auto_select = TRUE;
  9415. X   this->exclude     = FALSE;
  9416. X   this->hidden      = FALSE;
  9417. X   this->stored_at   = NOWHERE;
  9418. X   this->file         = NULL;
  9419. X   this->memory      = NULL;
  9420. X
  9421. X   this->fs_color.red   = 42;
  9422. X   this->fs_color.green = 42;
  9423. X   this->fs_color.blue  = 42;
  9424. X   this->freestyle      = FALSE;
  9425. X   this->bandwidth      = 15;
  9426. X   this->top            = 255;
  9427. X   this->bottom         = 0 ;
  9428. X
  9429. X   this->undo_file    = fopen(undofile, "w+b");
  9430. X   this->curr_changed = FALSE;
  9431. X   this->num_redo     = 0;
  9432. X
  9433. X   RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]);
  9434. X   RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]);
  9435. X
  9436. X   PalTable__SetPos(this, 0, 0);
  9437. X
  9438. X   csize = ( (sydots-(PalTable_PALY+1+1)) / 2 ) / 16;
  9439. X   if (csize<CSIZE_MIN)
  9440. X      csize = CSIZE_MIN;
  9441. X   PalTable__SetCSize(this, csize);
  9442. X
  9443. X   return(this);
  9444. X   }
  9445. X
  9446. X
  9447. Xstatic void PalTable_SetHidden(PalTable *this, BOOLEAN hidden)
  9448. X   {
  9449. X   this->hidden = hidden;
  9450. X   RGBEditor_SetHidden(this->rgb[0], hidden);
  9451. X   RGBEditor_SetHidden(this->rgb[1], hidden);
  9452. X   PalTable__UpdateDAC(this);
  9453. X   }
  9454. X
  9455. X
  9456. X
  9457. Xstatic void PalTable_Hide(PalTable *this, RGBEditor *rgb, BOOLEAN hidden)
  9458. X   {
  9459. X   if (hidden)
  9460. X      {
  9461. X      PalTable__RestoreRect(this);
  9462. X      PalTable_SetHidden(this, TRUE);
  9463. X      reserve_colors = FALSE;
  9464. X      if (this->auto_select)
  9465. X     PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  9466. X      }
  9467. X   else
  9468. X      {
  9469. X      PalTable_SetHidden(this, FALSE);
  9470. X      reserve_colors = TRUE;
  9471. X      if (this->stored_at == NOWHERE)  /* do we need to save screen? */
  9472. X     PalTable__SaveRect(this);
  9473. X      PalTable__Draw(this);
  9474. X      if (this->auto_select)
  9475. X     PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
  9476. X      RGBEditor_SetDone(rgb, TRUE);
  9477. X      }
  9478. X   }
  9479. X
  9480. X
  9481. Xstatic void PalTable_Destroy(PalTable *this)
  9482. X   {
  9483. X
  9484. X   if (this->file != NULL)
  9485. X      {
  9486. X      fclose(this->file);
  9487. X      remove(scrnfile);
  9488. X      }
  9489. X
  9490. X   if (this->undo_file != NULL)
  9491. X      {
  9492. X      fclose(this->undo_file);
  9493. X      remove(undofile);
  9494. X      }
  9495. X
  9496. X   if (this->memory != NULL)
  9497. X      farmemfree(this->memory);
  9498. X
  9499. X   if (this->save_pal[0] != NULL)
  9500. X      farmemfree((BYTE far *)this->save_pal[0]);
  9501. X
  9502. X   RGBEditor_Destroy(this->rgb[0]);
  9503. X   RGBEditor_Destroy(this->rgb[1]);
  9504. X   MoveBox_Destroy(this->movebox);
  9505. X   delete(this);
  9506. X   }
  9507. X
  9508. X
  9509. Xstatic void PalTable_Process(PalTable *this)
  9510. X   {
  9511. X   int ctr;
  9512. X
  9513. X   getpalrange(0, colors, this->pal);
  9514. X
  9515. X   /* Make sure all palette entries are 0-63 */
  9516. X
  9517. X   for(ctr=0; ctr<768; ctr++)
  9518. X      ((char *)this->pal)[ctr] &= 63;
  9519. X
  9520. X   PalTable__UpdateDAC(this);
  9521. X
  9522. X   RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]);
  9523. X   RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]);
  9524. X
  9525. X   if (!this->hidden)
  9526. X      {
  9527. X      MoveBox_SetPos(this->movebox, this->x, this->y);
  9528. X      MoveBox_SetCSize(this->movebox, this->csize);
  9529. X      if ( !MoveBox_Process(this->movebox) )
  9530. X     {
  9531. X     setpalrange(0, colors, this->pal);
  9532. X     return ;
  9533. X     }
  9534. X
  9535. X      PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox));
  9536. X      PalTable__SetCSize(this, MoveBox_CSize(this->movebox));
  9537. X
  9538. X      if ( MoveBox_ShouldHide(this->movebox) )
  9539. X     {
  9540. X     PalTable_SetHidden(this, TRUE);
  9541. X     reserve_colors = FALSE;   /* <EAN> */
  9542. X     }
  9543. X      else
  9544. X     {
  9545. X     reserve_colors = TRUE;    /* <EAN> */
  9546. X     PalTable__SaveRect(this);
  9547. X     PalTable__Draw(this);
  9548. X     }
  9549. X      }
  9550. X
  9551. X   PalTable__SetCurr(this, this->active,      PalTable__GetCursorColor(this));
  9552. X   PalTable__SetCurr(this, (this->active==1)?0:1, PalTable__GetCursorColor(this));
  9553. X   Cursor_Show();
  9554. X
  9555. X   this->done = FALSE;
  9556. X
  9557. X   while ( !this->done )
  9558. X      RGBEditor_Edit(this->rgb[this->active]);
  9559. X
  9560. X   Cursor_Hide();
  9561. X   PalTable__RestoreRect(this);
  9562. X   setpalrange(0, colors, this->pal);
  9563. X   }
  9564. X
  9565. X
  9566. X/*
  9567. X * interface to FRACTINT
  9568. X */
  9569. X
  9570. X
  9571. X
  9572. Xvoid EditPalette(void)         /* called by fractint */
  9573. X   {
  9574. X   int         oldlookatmouse = lookatmouse;
  9575. X   int         oldsxoffs        = sxoffs;
  9576. X   int         oldsyoffs        = syoffs;
  9577. X   PalTable *pt;
  9578. X
  9579. X   ENTER_OVLY(OVLY_ROTATE);
  9580. X
  9581. X   mem_init(strlocn, 10*1024);
  9582. X
  9583. X   if ( (font8x8 = findfont(0)) == NULL )
  9584. X      return ;
  9585. X
  9586. X   plot = putcolor;
  9587. X
  9588. X   line_buff = newx(max(sxdots,sydots));
  9589. X
  9590. X   lookatmouse = 3;
  9591. X   sxoffs = syoffs = 0;
  9592. X
  9593. X   reserve_colors = TRUE;
  9594. X   inverse = FALSE;
  9595. X   fg_color = 255%colors;
  9596. X   bg_color = fg_color-1;
  9597. X
  9598. X   Cursor_Construct();
  9599. X   pt = PalTable_Construct();
  9600. X   PalTable_Process(pt);
  9601. X   PalTable_Destroy(pt);
  9602. X   Cursor_Destroy();
  9603. X
  9604. X   lookatmouse = oldlookatmouse;
  9605. X   sxoffs = oldsxoffs;
  9606. X   syoffs = oldsyoffs;
  9607. X   delete(line_buff);
  9608. X   EXIT_OVLY;
  9609. X   }
  9610. X
  9611. SHAR_EOF
  9612. $TOUCH -am 1028230093 editpal.c &&
  9613. chmod 0644 editpal.c ||
  9614. echo "restore of editpal.c failed"
  9615. set `wc -c editpal.c`;Wc_c=$1
  9616. if test "$Wc_c" != "80381"; then
  9617.     echo original size 80381, current size $Wc_c
  9618. fi
  9619. # ============= encoder.c ==============
  9620. echo "x - extracting encoder.c (Text)"
  9621. sed 's/^X//' << 'SHAR_EOF' > encoder.c &&
  9622. X/*
  9623. X    encoder.c - GIF Encoder and associated routines
  9624. X    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  9625. X*/
  9626. X
  9627. X#include <stdlib.h>
  9628. X#include <stdio.h>
  9629. X#include <string.h>
  9630. X#ifndef XFRACT
  9631. X#include <io.h>
  9632. X#endif
  9633. X#include "fractint.h"
  9634. X#include "fractype.h"
  9635. X#include "prototyp.h"
  9636. X
  9637. X/* MCP 10-27-91 */
  9638. X#ifdef WINFRACT
  9639. X   extern int OperCancelled;
  9640. X   void OpenStatusBox(void);
  9641. X   void UpdateStatusBox(unsigned long Partial, unsigned long Total);
  9642. X   void CloseStatusBox(void);
  9643. X#endif
  9644. X
  9645. Xextern char s_cantopen[];
  9646. Xextern char s_cantwrite[];
  9647. Xextern char s_cantcreate[];
  9648. Xextern char s_cantunderstand[];
  9649. Xextern char s_cantfind[];
  9650. Xextern char maxfn;
  9651. Xstatic void _fastcall setup_save_info(struct fractal_info *);
  9652. Xstatic int inittable(void);
  9653. Xstatic int _fastcall shftwrite(BYTE *color,int numcolors);
  9654. Xstatic int _fastcall raster(unsigned int);
  9655. Xstatic int  _fastcall extend_blk_len(int datalen);
  9656. Xstatic int _fastcall put_extend_blk(int block_id,int block_len,char far *block_data);
  9657. Xstatic int  _fastcall store_item_name(char *);
  9658. X
  9659. Xextern int initbatch;
  9660. Xextern char far *resume_info;        /* pointer to resume info if allocated */
  9661. Xextern int  resume_len;         /* length of resume info */
  9662. Xextern char LName[];
  9663. Xextern char FormName[];         /* formula name */
  9664. Xextern char IFSName[];
  9665. Xextern int  active_system;        /* 0=dos, 1=windows */
  9666. Xextern int  far *ranges;
  9667. Xextern int  rangeslen;
  9668. X
  9669. Xextern    int    sxdots,sydots;        /* # of dots on the physical screen    */
  9670. Xextern    int    sxoffs,syoffs;        /* physical top left of logical screen */
  9671. Xextern    int    xdots, ydots;        /* # of dots on the logical screen     */
  9672. Xextern    int    viewwindow;        /* 0 for full screen, 1 for window */
  9673. Xextern    float    finalaspectratio;    /* for view shape and rotation */
  9674. Xextern    int    viewxdots,viewydots;    /* explicit view sizing */
  9675. Xextern    int    colors;         /* maximum colors available */
  9676. Xextern    int    dotmode;        /* so we can detect disk-video */
  9677. Xextern    char overwrite;         /* overwrite on/off */
  9678. Xextern    int    resave_flag;        /* resaving after a timed save */
  9679. Xextern    int    started_resaves;
  9680. Xextern    int    timedsave;        /* if doing an auto save */
  9681. Xextern    int    disk16bit;        /* 16 bit continuous potential */
  9682. X
  9683. Xextern BYTE dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  9684. Xextern    int    gotrealdac;        /* DAC valid? */
  9685. Xextern int    daclearn, daccount;    /* used by the color-cyclers */
  9686. Xextern SEGTYPE    extraseg;        /* used by Save-to-GIF routines */
  9687. Xextern int    debugflag;
  9688. X
  9689. Xextern int    gif87a_flag;        /* if 1, supress GIF extension blocks */
  9690. X
  9691. Xextern int    calc_status;
  9692. Xextern long   calctime;
  9693. Xextern char   stdcalcmode;
  9694. Xextern int    fractype;
  9695. Xextern double xxmin,xxmax;
  9696. Xextern double yymin,yymax;
  9697. Xextern double xx3rd,yy3rd;
  9698. Xextern double param[];
  9699. Xextern int    major_method;        /* inverse julia parms */
  9700. Xextern int    minor_method;
  9701. Xextern int    maxit;            /* try this many iterations */
  9702. Xextern int    fillcolor;        /* fill color: -1 = normal  */
  9703. Xextern int    inside;            /* inside color: 1=blue     */
  9704. Xextern int    outside;            /* outside color, if set    */
  9705. Xextern int    finattract;        /* finite attractor option  */
  9706. Xextern int    forcesymmetry;
  9707. Xextern int    LogFlag;            /* non-zero if logarithmic palettes */
  9708. Xextern int    rflag, rseed;
  9709. Xextern int    periodicitycheck;
  9710. Xextern char   useinitorbit;
  9711. Xextern _CMPLX initorbit;
  9712. Xextern int    pot16bit;
  9713. Xextern float  finalaspectratio;
  9714. Xextern double potparam[3];        /* three potential parameters*/
  9715. Xextern double inversion[];
  9716. Xextern int    decomp[];
  9717. Xextern int    distest;            /* non-zero if distance estimator   */
  9718. Xextern int    distestwidth;
  9719. Xextern int    init3d[20];        /* '3d=nn/nn/nn/...' values */
  9720. Xextern char   floatflag;        /* floating-point fractals? */
  9721. Xextern int    usr_biomorph;
  9722. Xextern int    bailout;            /* user input bailout value */
  9723. Xextern int    previewfactor;
  9724. Xextern int    xtrans;
  9725. Xextern int    ytrans;
  9726. Xextern int    red_crop_left;
  9727. Xextern int    red_crop_right;
  9728. Xextern int    blue_crop_left;
  9729. Xextern int    blue_crop_right;
  9730. Xextern int    red_bright;
  9731. Xextern int    blue_bright;
  9732. Xextern int    xadjust;
  9733. Xextern int    eyeseparation;
  9734. Xextern int    glassestype;
  9735. Xextern int    save_system;
  9736. Xextern int    save_release;
  9737. Xextern int    display3d;        /* 3D display flag: 0 = OFF */
  9738. Xextern int    Ambient;
  9739. Xextern int    RANDOMIZE;
  9740. Xextern int    haze;
  9741. Xextern int    transparent[2];
  9742. Xextern int    rotate_lo,rotate_hi;
  9743. Xextern char   busy;
  9744. Xextern float  screenaspect;
  9745. Xextern     double mxmaxfp;
  9746. Xextern     double mxminfp;
  9747. Xextern     double mymaxfp;
  9748. Xextern     double myminfp;
  9749. Xextern     int zdots;        
  9750. Xextern     float originfp;
  9751. Xextern     float depthfp;    
  9752. Xextern     float heightfp;
  9753. Xextern     float widthfp;    
  9754. Xextern     float distfp;    
  9755. Xextern     float eyesfp;    
  9756. Xextern     int neworbittype;
  9757. Xextern     short juli3Dmode;
  9758. X    
  9759. X#ifdef XFRACT
  9760. Xextern int decode_fractal_info();
  9761. X#endif
  9762. X
  9763. X/*
  9764. X            Save-To-Disk Routines (GIF)
  9765. X
  9766. XGIF and 'Graphics Interchange Format' are trademarks (tm) of Compuserve
  9767. XIncorporated, an H&R Block Company.
  9768. X
  9769. X
  9770. XThe following routines perform the GIF encoding when the 's' key is pressed.
  9771. XThe routines refer to several variables that are declared elsewhere
  9772. X[colors, xdots, ydots, and 'dacbox'], and rely on external routines to
  9773. Xactually read and write screen pixels [getcolor(x,y) and putcolor(x,y,color)].
  9774. X(Writing pixels is just stuffed in here as a sort of visual status report,
  9775. Xand has nothing to do with any GIF function.)    They also rely on the
  9776. Xexistence of an externally-defined 64K dataspace and they use the routines
  9777. X'toextra()' and 'cmpextra()' to deal with that dataspace (in the same manner
  9778. Xas 'memcpy()' and 'memcmp()' would).   Otherwise, they perform a generic
  9779. XGIF-encoder function.
  9780. X
  9781. XNote that these routines use small string- and hash-tables, and "flush"
  9782. Xthe GIF entries whenever the hash-table gets two-thirds full or the string
  9783. Xtable gets full.   They also use the GIF encoding technique of limiting the
  9784. Xencoded string length to a specific size, "adding" a string to the hash table
  9785. Xat that point even if a matching string exists ("adding" is in quotes, because
  9786. Xif a matching string exists we can increment the code counter but safely throw
  9787. Xthe duplicate string away, saving both string space and a hash table entry).
  9788. X
  9789. X   This results in relatively good speed and small data space, but at the
  9790. Xexpense of compression efficiency (filesize).    These trade-offs could be
  9791. Xadjusted by modifying the #DEFINEd variables below.
  9792. X
  9793. XNote that the 'strlocn' and 'teststring' routines are declared
  9794. Xto be external just so that they can be defined (and the space re-used)
  9795. Xelsewhere.  The actual declarations are in the assembler code.
  9796. X
  9797. X*/
  9798. X
  9799. X#define MAXTEST   100        /* maximum single string length */
  9800. X#define MAXSTRING 64000     /* total space reserved for strings */
  9801. X                /* maximum number of strings available */
  9802. X#define MAXENTRY  5003        /* (a prime number is best for hashing) */
  9803. X
  9804. X#ifndef XFRACT
  9805. Xextern unsigned int strlocn[MAXENTRY];
  9806. Xextern BYTE teststring[MAXTEST];
  9807. Xextern BYTE block[266];   /* GIF-encoded blocks go here */
  9808. X#else
  9809. Xunsigned int strlocn[10240];
  9810. XBYTE teststring[MAXTEST];
  9811. XBYTE block[266];   /* GIF-encoded blocks go here */
  9812. X#endif
  9813. X
  9814. Xstatic int numsaves = 0;    /* For adjusting 'save-to-disk' filenames */
  9815. X
  9816. Xstatic FILE *out;
  9817. Xstatic int last_colorbar;
  9818. Xstatic int save16bit;
  9819. Xstatic int outcolor1s, outcolor2s;
  9820. X
  9821. Xstatic int lentest, lastentry, numentries, numrealentries;
  9822. Xstatic unsigned int nextentry;
  9823. Xstatic int clearcode, endcode;
  9824. Xstatic unsigned int hashcode;
  9825. X
  9826. Xstatic BYTE blockcount;
  9827. Xstatic int startbits, codebits, bytecount, bitcount;
  9828. X
  9829. Xstatic char paletteBW[] = {            /* B&W palette */
  9830. X      0,  0,  0, 63, 63, 63,
  9831. X    };
  9832. Xstatic char paletteCGA[] = {            /* 4-color (CGA) palette  */
  9833. X      0,  0,  0, 21, 63, 63, 63, 21, 63, 63, 63, 63,
  9834. X    };
  9835. Xstatic char paletteEGA[] = {            /* 16-color (EGA/CGA) pal */
  9836. X      0,  0,  0,  0,  0, 42,  0, 42,  0,  0, 42, 42,
  9837. X     42,  0,  0, 42,  0, 42, 42, 21,  0, 42, 42, 42,
  9838. X     21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
  9839. X     63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
  9840. X    };
  9841. X
  9842. Xvoid encoder_overlay() { }    /* for restore_active_ovly */
  9843. X
  9844. Xint savetodisk(filename)    /* save-to-disk routine */
  9845. X   char *filename;
  9846. X   {
  9847. X   char tmpmsg[41]; /* before openfile in case of overrun */
  9848. X   char openfile[80], openfiletype[10];
  9849. X   char tmpfile[80];
  9850. X   int newfile;
  9851. X   int i, j, outcolor1, outcolor2, interrupted;
  9852. X
  9853. X   ENTER_OVLY(OVLY_ENCODER);
  9854. X
  9855. Xrestart:
  9856. X
  9857. X   save16bit = disk16bit;
  9858. X   if (gif87a_flag) /* not storing non-standard fractal info */
  9859. X      save16bit = 0;
  9860. X
  9861. X   strcpy(openfile,filename);        /* decode and open the filename */
  9862. X   strcpy(openfiletype,DEFAULTFRACTALTYPE);/* determine the file extension */
  9863. X   if (save16bit)
  9864. X      strcpy(openfiletype,".pot");
  9865. X   for (i = 0; i < strlen(openfile); i++)
  9866. X      if (openfile[i] == '.') {
  9867. X         strcpy(openfiletype,&openfile[i]);
  9868. X         openfile[i] = 0;
  9869. X         }
  9870. X   if (resave_flag != 1)
  9871. X      updatesavename(filename); /* for next time */
  9872. X
  9873. X   strcat(openfile,openfiletype);
  9874. X
  9875. X   strcpy(tmpfile,openfile);
  9876. X   if (access(openfile,0) != 0) /* file doesn't exist */
  9877. X      newfile = 1;
  9878. X   else { /* file already exists */
  9879. X      if (overwrite == 0) {
  9880. X         if (resave_flag == 0)
  9881. X            goto restart;
  9882. X         if (started_resaves == 0) { /* first save of a savetime set */
  9883. X            updatesavename(filename);
  9884. X            goto restart;
  9885. X            }
  9886. X         }
  9887. X      if (access(openfile,2) != 0) {
  9888. X         sprintf(tmpmsg,s_cantwrite,openfile);
  9889. X         stopmsg(0,tmpmsg);
  9890. X         EXIT_OVLY;
  9891. X         return -1;
  9892. X         }
  9893. X      newfile = 0;
  9894. X      i = strlen(tmpfile);
  9895. X      while (--i >= 0 && tmpfile[i] != SLASHC)
  9896. X         tmpfile[i] = 0;
  9897. X      strcat(tmpfile,"fractint.tmp");
  9898. X      }
  9899. X
  9900. X   started_resaves = (resave_flag == 1) ? 1 : 0;
  9901. X   if (resave_flag == 2) /* final save of savetime set? */
  9902. X      resave_flag = 0;
  9903. X
  9904. X   if ((out=fopen(tmpfile,"wb")) == NULL) {
  9905. X      sprintf(tmpmsg,s_cantcreate,tmpfile);
  9906. X      stopmsg(0,tmpmsg);
  9907. X      EXIT_OVLY;
  9908. X      return -1;
  9909. X      }
  9910. X
  9911. X   if (dotmode == 11) {            /* disk-video */
  9912. X      char buf[60];
  9913. X      sprintf(buf,"Saving %s",openfile);
  9914. X      dvid_status(1,buf);
  9915. X      }
  9916. X#ifdef XFRACT
  9917. X      else {
  9918. X      putstring(3,0,0,"Saving to:");
  9919. X      putstring(4,0,0,openfile);
  9920. X      putstring(5,0,0,"               ");
  9921. X      }
  9922. X#endif
  9923. X
  9924. X   busy = 1;
  9925. X
  9926. X   if (debugflag != 200)
  9927. X      interrupted = encoder();
  9928. X   else
  9929. X      interrupted = timer(2,NULL);    /* invoke encoder() via timer */
  9930. X
  9931. X   busy = 0;
  9932. X
  9933. X   fclose(out);
  9934. X
  9935. X   if (interrupted) {
  9936. X      char buf[200];
  9937. X      sprintf(buf,"Save of %s interrupted.\nCancel to ",openfile);
  9938. X      if (newfile)
  9939. X         strcat(buf,"delete the file,\ncontinue to keep the partial image.");
  9940. X      else
  9941. X         strcat(buf,"retain the original file,\ncontinue to replace original with new partial image.");
  9942. X      interrupted = 1;
  9943. X      if (stopmsg(2,buf) < 0) {
  9944. X         interrupted = -1;
  9945. X         unlink(tmpfile);
  9946. X         }
  9947. X      }
  9948. X
  9949. X   if (newfile == 0 && interrupted >= 0) { /* replace the real file */
  9950. X      unlink(openfile);        /* success assumed since we checked */
  9951. X      rename(tmpfile,openfile);    /* earlier with access            */
  9952. X      }
  9953. X
  9954. X   if (dotmode != 11) {            /* supress this on disk-video */
  9955. X      if (active_system == 0) {        /* no bars in Windows version */
  9956. X         outcolor1 = outcolor1s;
  9957. X         outcolor2 = outcolor2s;
  9958. X         for (j = 0; j <= last_colorbar; j++) {
  9959. X            if ((j & 4) == 0) {
  9960. X               if (++outcolor1 >= colors) outcolor1 = 0;
  9961. X               if (++outcolor2 >= colors) outcolor2 = 0;
  9962. X               }
  9963. X            for (i = 0; 250*i < xdots; i++) { /* clear vert status bars */
  9964. X               putcolor(i,j,getcolor(i,j)^outcolor1);
  9965. X               putcolor(xdots-1-i,j,getcolor(xdots-1-i,j)^outcolor2);
  9966. X               }
  9967. X            }
  9968. X         }
  9969. X#ifdef XFRACT
  9970. X         putstring(5,0,0,"Saving done\n");
  9971. X#endif
  9972. X      }
  9973. X   else                    /* disk-video */
  9974. X      dvid_status(1,"");
  9975. X
  9976. X   if (interrupted) {
  9977. X      texttempmsg(" *interrupted* save ");
  9978. X      if (initbatch == 2 || initbatch == 5) initbatch = 3; /* if batch mode, set error level */
  9979. X      EXIT_OVLY;
  9980. X      return -1;
  9981. X      }
  9982. X   if (timedsave == 0) {
  9983. X      buzzer(0);
  9984. X      if (initbatch == 0) {
  9985. X         sprintf(tmpmsg," File saved as %s ",openfile);
  9986. X         texttempmsg(tmpmsg);
  9987. X         }
  9988. X      }
  9989. X   EXIT_OVLY;
  9990. X   return 0;
  9991. X   }
  9992. X
  9993. X
  9994. Xint encoder()
  9995. X{
  9996. Xint i, ydot, xdot, color, outcolor1, outcolor2;
  9997. Xint width;
  9998. Xint rownum, rowlimit;
  9999. Xunsigned int hashentry;
  10000. XBYTE bitsperpixel, x;
  10001. Xint entrynum;
  10002. Xstruct fractal_info save_info;
  10003. X
  10004. Xif(initbatch)            /* flush any impending keystrokes */
  10005. X   while(keypressed())
  10006. X      getakey();
  10007. X
  10008. Xsetup_save_info(&save_info);
  10009. X
  10010. X#ifndef XFRACT
  10011. Xbitsperpixel = 0;            /* calculate bits / pixel */
  10012. Xfor (i = colors; i >= 2; i /= 2 )
  10013. X    bitsperpixel++;
  10014. X
  10015. Xstartbits = bitsperpixel+1;        /* start coding with this many bits */
  10016. Xif (colors == 2)
  10017. X    startbits++;            /* B&W Klooge */
  10018. X#else
  10019. X    if (colors==2) {
  10020. X        bitsperpixel = 1;
  10021. X        startbits = 3;
  10022. X    } else {
  10023. X        bitsperpixel = 8;
  10024. X        startbits = 9;
  10025. X    }
  10026. X#endif
  10027. X
  10028. Xclearcode = 1 << (startbits - 1);    /* set clear and end codes */
  10029. Xendcode = clearcode+1;
  10030. X
  10031. Xoutcolor1 = 0;                /* use these colors to show progress */
  10032. Xoutcolor2 = 1;                /* (this has nothing to do with GIF) */
  10033. Xif (colors > 2) {
  10034. X    outcolor1 = 2;
  10035. X    outcolor2 = 3;
  10036. X    }
  10037. Xif (((++numsaves) & 1) == 0) {            /* reverse the colors on alt saves */
  10038. X    i = outcolor1;
  10039. X    outcolor1 = outcolor2;
  10040. X    outcolor2 = i;
  10041. X    }
  10042. Xoutcolor1s = outcolor1;
  10043. Xoutcolor2s = outcolor2;
  10044. X
  10045. Xif (gif87a_flag == 1) {
  10046. X    if (fwrite("GIF87a",6,1,out) != 1) goto oops;  /* old GIF Signature */
  10047. X} else {
  10048. X    if (fwrite("GIF89a",6,1,out) != 1) goto oops;  /* new GIF Signature */
  10049. X}
  10050. X
  10051. Xwidth = xdots;
  10052. Xrowlimit = ydots;
  10053. Xif (save16bit) {
  10054. X    /* pot16bit info is stored as:
  10055. X       file:    double width rows, right side of row is low 8 bits
  10056. X       diskvid: ydots rows of colors followed by ydots rows of low 8 bits
  10057. X       decoder: returns (row of color info then row of low 8 bits) * ydots
  10058. X       */
  10059. X    rowlimit <<= 1;
  10060. X    width <<= 1;
  10061. X    }
  10062. Xif (write2(&width,2,1,out) != 1) goto oops;  /* screen descriptor */
  10063. Xif (write2(&ydots,2,1,out) != 1) goto oops;
  10064. Xx = 128 + ((6-1)<<4) + (bitsperpixel-1); /* color resolution == 6 bits worth */
  10065. Xif (write1(&x,1,1,out) != 1) goto oops;
  10066. Xif (fputc(0,out) != 0) goto oops;    /* background color */
  10067. Xi = 0;
  10068. X/** PB, changed to always store pixel aspect ratio, some utilities
  10069. X    have been reported to like it **/
  10070. X/**
  10071. Xif ( finalaspectratio < screenaspect-0.01
  10072. X  || finalaspectratio > screenaspect+0.01) {
  10073. X **/
  10074. Xif (viewwindow                    /* less than full screen?  */
  10075. X  && (viewxdots == 0 || viewydots == 0))    /* and we picked the dots? */
  10076. X   i = ((double)sydots / (double)sxdots) * 64.0/screenaspect - 14.5;
  10077. Xelse /* must risk loss of precision if numbers low */
  10078. X   i = (((double)ydots / (double)xdots) / finalaspectratio) * 64 - 14.5;
  10079. Xif (i < 1)   i = 1;
  10080. Xif (i > 255) i = 255;
  10081. Xif (gif87a_flag) i = 0;    /* for some decoders which can't handle aspect */
  10082. Xif (fputc(i,out) != i) goto oops;    /* pixel aspect ratio */
  10083. X
  10084. X#ifndef XFRACT
  10085. Xif (colors == 256) {            /* write out the 256-color palette */
  10086. X    if (gotrealdac) {         /* got a DAC - must be a VGA */
  10087. X        if (!shftwrite((BYTE *)dacbox,colors)) goto oops;
  10088. X#else
  10089. Xif (colors > 2) {
  10090. X        if (gotrealdac) {               /* got a DAC - must be a VGA */
  10091. X                if (!shftwrite((BYTE *)dacbox,256)) goto oops;
  10092. X#endif
  10093. X     } else {            /* uh oh - better fake it */
  10094. X        for (i = 0; i < 256; i += 16)
  10095. X            if (!shftwrite((BYTE *)paletteEGA,16)) goto oops;
  10096. X        }
  10097. X    }
  10098. Xif (colors == 2) {            /* write out the B&W palette */
  10099. X    if (!shftwrite((BYTE *)paletteBW,colors)) goto oops;
  10100. X    }
  10101. X#ifndef XFRACT
  10102. Xif (colors == 4) {            /* write out the CGA palette */
  10103. X    if (!shftwrite(paletteCGA,colors))goto oops;
  10104. X    }
  10105. Xif (colors == 16) {            /* Either EGA or VGA */
  10106. X    if (gotrealdac) {
  10107. X        if (!shftwrite((BYTE *)dacbox,colors))goto oops;
  10108. X        }
  10109. X     else    {            /* no DAC - must be an EGA */
  10110. X        if (!shftwrite(paletteEGA,colors))goto oops;
  10111. X        }
  10112. X    }
  10113. X#endif
  10114. X
  10115. Xif (fwrite(",",1,1,out) != 1) goto oops;  /* Image Descriptor */
  10116. Xi = 0;
  10117. Xif (write2(&i,2,1,out) != 1) goto oops;
  10118. Xif (write2(&i,2,1,out) != 1) goto oops;
  10119. Xif (write2(&width,2,1,out) != 1) goto oops;
  10120. Xif (write2(&ydots,2,1,out) != 1) goto oops;
  10121. Xif (write1(&i,1,1,out) != 1) goto oops;
  10122. X
  10123. Xbitsperpixel = startbits - 1;        /* raster data starts here */
  10124. Xif (write1(&bitsperpixel,1,1,out) != 1) goto oops;
  10125. X
  10126. Xcodebits = startbits;            /* start encoding */
  10127. X
  10128. Xif (!raster(9999)) goto oops;        /* initialize the raster routine */
  10129. X
  10130. Xif (!inittable()) goto oops;        /* initialize the LZW tables */
  10131. X
  10132. Xfor ( rownum = 0; rownum < ydots; rownum++
  10133. X#ifdef WINFRACT
  10134. X      , UpdateStatusBox(rownum, ydots)
  10135. X#endif
  10136. X) {  /* scan through the dots */
  10137. X    for (ydot = rownum; ydot < rowlimit; ydot += ydots) {
  10138. X    for (xdot = 0; xdot < xdots; xdot++) {
  10139. X        if (save16bit == 0 || ydot < ydots)
  10140. X            color = getcolor(xdot,ydot);
  10141. X        else
  10142. X            color = readdisk(xdot+sxoffs,ydot+syoffs);
  10143. X        teststring[0] = ++lentest;
  10144. X        teststring[lentest] = color;
  10145. X        if (lentest == 1) {        /* root entry? */
  10146. X            lastentry = color;
  10147. X            continue;
  10148. X            }
  10149. X        if (lentest == 2)        /* init   the hash code */
  10150. X            hashcode = 301 * (teststring[1]+1);
  10151. X        hashcode *= (color + lentest);    /* update the hash code */
  10152. X        hashentry = ++hashcode % MAXENTRY;
  10153. X        for( i = 0; i < MAXENTRY; i++) {
  10154. X            if (++hashentry >= MAXENTRY) hashentry = 0;
  10155. X            if (cmpextra(strlocn[hashentry]+sizeof(int),
  10156. X                (char *)teststring,lentest+1) == 0)
  10157. X                    break;
  10158. X            if (strlocn[hashentry] == 0) i = MAXENTRY;
  10159. X            }
  10160. X        /* found an entry and string length isn't too bad */
  10161. X        if (strlocn[hashentry] != 0 && lentest < MAXTEST-1-sizeof(int)) {
  10162. X            fromextra(strlocn[hashentry],(char *)&entrynum,sizeof(int));
  10163. X            lastentry = entrynum;
  10164. X            continue;
  10165. X            }
  10166. X        if (!raster(lastentry)) goto oops;    /* write entry */
  10167. X        numentries++;        /* act like you added one, anyway */
  10168. X        if (strlocn[hashentry] == 0) {    /* add new string, if any */
  10169. X            entrynum = numentries+endcode;
  10170. X            strlocn[hashentry] = nextentry;
  10171. X            toextra(nextentry, (char *)&entrynum,sizeof(int));
  10172. X            toextra(nextentry+sizeof(int),
  10173. X                (char *)teststring,lentest+1);
  10174. X            nextentry += lentest+1+sizeof(int);
  10175. X            numrealentries++;
  10176. X            }
  10177. X        teststring[0] = 1;        /* reset current entry */
  10178. X        teststring[1] = color;
  10179. X        lentest = 1;
  10180. X        lastentry = color;
  10181. X
  10182. X        if ((numentries+endcode) == (1<<codebits))
  10183. X            codebits++;         /* use longer encoding */
  10184. X
  10185. X        if ( numentries + endcode > 4093 ||    /* out of room? */
  10186. X            numrealentries > (MAXENTRY*2)/3 ||
  10187. X            nextentry > MAXSTRING-MAXTEST-1-2*sizeof(int)) {
  10188. X            if (!raster(lastentry)) goto oops;    /* flush & restart */
  10189. X            if (!inittable()) goto oops;
  10190. X            }
  10191. X        }
  10192. X    if (dotmode != 11            /* supress this on disk-video */
  10193. X        && active_system == 0        /* and in Windows version     */
  10194. X        && ydot == rownum) {
  10195. X        if ((ydot & 4) == 0) {
  10196. X            if (++outcolor1 >= colors) outcolor1 = 0;
  10197. X            if (++outcolor2 >= colors) outcolor2 = 0;
  10198. X            }
  10199. X        for (i = 0; 250*i < xdots; i++) {    /* display vert status bars */
  10200. X                            /*   (this is NOT GIF-related)    */
  10201. X            /* PB Changed following code to xor color, so that
  10202. X               image can be restored at end and resumed
  10203. X               putcolor(      i,ydot,outcolor1);
  10204. X               putcolor(xdots-1-i,ydot,outcolor2);
  10205. X            */
  10206. X            putcolor(i,ydot,getcolor(i,ydot)^outcolor1);
  10207. X            putcolor(xdots-1-i,ydot,getcolor(xdots-1-i,ydot)^outcolor2);
  10208. X            }
  10209. X        last_colorbar = ydot;
  10210. X        }
  10211. X#ifdef WINFRACT
  10212. X        keypressed();
  10213. X        if (OperCancelled)
  10214. X#else
  10215. X        if (keypressed())                     /* keyboard hit - bail out */
  10216. X#endif
  10217. X        ydot = rownum = 9999;
  10218. X    }
  10219. X    }
  10220. X
  10221. Xif (!raster(lastentry)) goto oops;    /* tidy up - dump the last code */
  10222. X
  10223. Xif (!raster(endcode)) goto oops;    /* finish the map */
  10224. X
  10225. Xif (fputc(0,out) != 0) goto oops;    /* raster data ends here */
  10226. X
  10227. Xif (gif87a_flag == 0) { /* store non-standard fractal info */
  10228. X    /* loadfile.c has notes about extension block structure */
  10229. X    if (ydot >= 9999)
  10230. X        save_info.calc_status = 0; /* partial save is not resumable */
  10231. X    save_info.tot_extend_len = 0;
  10232. X    if (resume_info != NULL && save_info.calc_status == 2) {
  10233. X        /* resume info block, 002 */
  10234. X        save_info.tot_extend_len += extend_blk_len(resume_len);
  10235. X        if (!put_extend_blk(2,resume_len,resume_info))goto oops;
  10236. X        }
  10237. X    if (save_info.fractal_type == FORMULA || save_info.fractal_type == FFORMULA)
  10238. X        save_info.tot_extend_len += store_item_name(FormName);
  10239. X    if (save_info.fractal_type == LSYSTEM)
  10240. X        save_info.tot_extend_len += store_item_name(LName);
  10241. X    if (save_info.fractal_type == IFS || save_info.fractal_type == IFS3D)
  10242. X        save_info.tot_extend_len += store_item_name(IFSName);
  10243. X    if (display3d <= 0 && rangeslen) {
  10244. X        /* ranges block, 004 */
  10245. X        save_info.tot_extend_len += extend_blk_len(rangeslen*2);
  10246. X#ifdef XFRACT
  10247. X        fix_ranges(ranges,rangeslen,0);
  10248. X        put_extend_blk(4,rangeslen*2,(char far *)ranges);
  10249. X        fix_ranges(ranges,rangeslen,0);
  10250. X#else
  10251. X        if (!put_extend_blk(4,rangeslen*2,(char far *)ranges))
  10252. X            goto oops;
  10253. X#endif
  10254. X        }
  10255. X
  10256. X    /* main and last block, 001 */
  10257. X    save_info.tot_extend_len += extend_blk_len(FRACTAL_INFO_SIZE);
  10258. X#ifdef XFRACT
  10259. X        decode_fractal_info(&save_info,0);
  10260. X#endif
  10261. X    if (!put_extend_blk(1,FRACTAL_INFO_SIZE,(char far *)&save_info)) {
  10262. X        goto oops;
  10263. X    }
  10264. X    }
  10265. X
  10266. Xif (fwrite(";",1,1,out) != 1) goto oops;          /* GIF Terminator */
  10267. X
  10268. Xreturn ((ydot < 9999) ? 0 : 1);
  10269. X
  10270. Xoops:
  10271. X    {
  10272. X    fflush(out);
  10273. X    stopmsg(0,"Error Writing to disk (Disk full?)");
  10274. X    return 1;
  10275. X    }
  10276. X}
  10277. X
  10278. Xstatic int _fastcall shftwrite(BYTE *color,int numcolors)
  10279. X/* shift IBM colors to GIF */
  10280. X{
  10281. XBYTE thiscolor;
  10282. Xint i,j;
  10283. Xfor (i = 0; i < numcolors; i++)
  10284. X    for (j = 0; j < 3; j++) {
  10285. X        thiscolor = color[3*i+j];
  10286. X        thiscolor = thiscolor << 2;
  10287. X        thiscolor += (thiscolor >> 6);
  10288. X        if (fputc(thiscolor,out) != thiscolor) return(0);
  10289. X        }
  10290. Xreturn(1);
  10291. X}
  10292. X
  10293. Xstatic int inittable()         /* routine to init tables */
  10294. X{
  10295. Xint i;
  10296. X
  10297. Xif (!raster(clearcode)) return(0);    /* signal that table is initialized */
  10298. X
  10299. Xnumentries = 0;             /* initialize the table */
  10300. Xnumrealentries = 0;
  10301. Xnextentry = 1;
  10302. Xlentest = 0;
  10303. Xcodebits = startbits;
  10304. X
  10305. Xtoextra(0,"\0",1);                      /* clear the hash entries */
  10306. Xfor (i = 0; i < MAXENTRY; i++)
  10307. X    strlocn[i] = 0;
  10308. X
  10309. Xreturn(1);
  10310. X}
  10311. X
  10312. Xstatic int _fastcall raster(code)    /* routine to block and output codes */
  10313. Xunsigned int code;
  10314. X{
  10315. Xunsigned int icode, i, j;
  10316. X
  10317. Xif (code == 9999) {            /* special start-up signal */
  10318. X    bytecount = 0;
  10319. X    bitcount = 0;
  10320. X    for (i = 0; i < 266; i++)
  10321. X        block[i] = 0;
  10322. X    return(1);
  10323. X    }
  10324. X
  10325. Xicode = code << bitcount;        /* update the bit string */
  10326. Xblock[bytecount  ] |= (icode & 255);
  10327. Xblock[bytecount+1] |= ((icode>>8) & 255);
  10328. Xicode = (code>>8) << bitcount;
  10329. Xblock[bytecount+2] |= ((icode>>8) & 255);
  10330. Xbitcount += codebits;
  10331. Xwhile (bitcount >= 8) {         /* locate next starting point */
  10332. X    bitcount -= 8;
  10333. X    bytecount++;
  10334. X    }
  10335. X
  10336. Xif (bytecount > 250 || code == endcode) {    /* time to write a block */
  10337. X    if (code == endcode)
  10338. X        while (bitcount > 0) {        /* if EOF, find the real end */
  10339. X            bitcount -= 8;
  10340. X            bytecount++;
  10341. X            }
  10342. X    i = bytecount;
  10343. X    blockcount = i;
  10344. X        if (write1(&blockcount,1,1,out) != 1) return(0); /* write the block */
  10345. X    if (fwrite(block,i,1,out) != 1) return(0);
  10346. X    bytecount = 0;                /* now re-start the block */
  10347. X    for (j = 0; j < 5; j++)         /* (may have leftover bits) */
  10348. X        block[j] = block[j+i];
  10349. X    for (j = 5; j < 266; j++)
  10350. X        block[j] = 0;
  10351. X    }
  10352. Xreturn(1);
  10353. X}
  10354. X
  10355. X
  10356. Xstatic int _fastcall extend_blk_len(int datalen)
  10357. X{
  10358. X   return(datalen + (datalen+254)/255 + 15);
  10359. X   /*       data   +    1.per.block   + 14 for id + 1 for null at end  */
  10360. X}
  10361. X
  10362. Xstatic int _fastcall put_extend_blk(int block_id,int block_len,char far *block_data)
  10363. X{
  10364. X   int i,j;
  10365. X   char header[15];
  10366. X   strcpy(header,"!\377\013fractint");
  10367. X   sprintf(&header[11],"%03u",block_id);
  10368. X   if (fwrite(header,14,1,out) != 1) return(0);
  10369. X   i = (block_len + 254) / 255;
  10370. X   while (--i >= 0) {
  10371. X      block_len -= (j = min(block_len,255));
  10372. X      if (fputc(j,out) != j) return(0);
  10373. X      while (--j >= 0)
  10374. X     fputc(*(block_data++),out);
  10375. X      }
  10376. X   if (fputc(0,out) != 0) return(0);
  10377. X   return(1);
  10378. X}
  10379. X
  10380. Xstatic int _fastcall store_item_name(char *nameptr)
  10381. X{
  10382. X   char tmpname[40];
  10383. X   strcpy(tmpname,nameptr);
  10384. X   /* formula/lsys/ifs info block, 003 */
  10385. X   put_extend_blk(3,40,tmpname);
  10386. X   return(extend_blk_len(40));
  10387. X}
  10388. X
  10389. Xstatic void _fastcall setup_save_info(struct fractal_info *save_info)
  10390. X{
  10391. X   int i;
  10392. X
  10393. X   if(fractype != FORMULA && fractype != FFORMULA)
  10394. X      maxfn = 0;     
  10395. X   /* set save parameters in save structure */
  10396. X   strcpy(save_info->info_id, INFO_ID);
  10397. X   save_info->version          = 9; /* file version, independant of system */
  10398. X   save_info->iterations      = maxit;
  10399. X   save_info->fractal_type    = fractype;
  10400. X   save_info->xmin          = xxmin;
  10401. X   save_info->xmax          = xxmax;
  10402. X   save_info->ymin          = yymin;
  10403. X   save_info->ymax          = yymax;
  10404. X   save_info->creal          = param[0];
  10405. X   save_info->cimag          = param[1];
  10406. X   save_info->videomodeax     = videoentry.videomodeax;
  10407. X   save_info->videomodebx     = videoentry.videomodebx;
  10408. X   save_info->videomodecx     = videoentry.videomodecx;
  10409. X   save_info->videomodedx     = videoentry.videomodedx;
  10410. X   save_info->dotmode          = videoentry.dotmode % 100;
  10411. X   save_info->xdots          = videoentry.xdots;
  10412. X   save_info->ydots          = videoentry.ydots;
  10413. X   save_info->colors          = videoentry.colors;
  10414. X   save_info->parm3          = 0; /* pre version==7 fields */
  10415. X   save_info->parm4          = 0;
  10416. X   save_info->dparm3          = param[2];
  10417. X   save_info->dparm4          = param[3];
  10418. X   save_info->dparm5          = param[4];
  10419. X   save_info->dparm6          = param[5];
  10420. X   save_info->dparm7          = param[6];
  10421. X   save_info->dparm8          = param[7];
  10422. X   save_info->dparm9          = param[8];
  10423. X   save_info->dparm10         = param[9];
  10424. X   save_info->fillcolor          = fillcolor;
  10425. X   save_info->potential[0]    = potparam[0];
  10426. X   save_info->potential[1]    = potparam[1];
  10427. X   save_info->potential[2]    = potparam[2];
  10428. X   save_info->rflag          = rflag;
  10429. X   save_info->rseed          = rseed;
  10430. X   save_info->inside          = inside;
  10431. X   save_info->logmap          = LogFlag;
  10432. X   save_info->invert[0]       = inversion[0];
  10433. X   save_info->invert[1]       = inversion[1];
  10434. X   save_info->invert[2]       = inversion[2];
  10435. X   save_info->decomp[0]       = decomp[0];
  10436. X   save_info->biomorph          = usr_biomorph;
  10437. X   save_info->symmetry          = forcesymmetry;
  10438. X   for (i = 0; i < 16; i++)
  10439. X      save_info->init3d[i] = init3d[i];
  10440. X   save_info->previewfactor   = previewfactor;
  10441. X   save_info->xtrans          = xtrans;
  10442. X   save_info->ytrans          = ytrans;
  10443. X   save_info->red_crop_left   = red_crop_left;
  10444. X   save_info->red_crop_right  = red_crop_right;
  10445. X   save_info->blue_crop_left  = blue_crop_left;
  10446. X   save_info->blue_crop_right = blue_crop_right;
  10447. X   save_info->red_bright      = red_bright;
  10448. X   save_info->blue_bright     = blue_bright;
  10449. X   save_info->xadjust          = xadjust;
  10450. X   save_info->eyeseparation   = eyeseparation;
  10451. X   save_info->glassestype     = glassestype;
  10452. X   save_info->outside          = outside;
  10453. X   save_info->x3rd          = xx3rd;
  10454. X   save_info->y3rd          = yy3rd;
  10455. X   save_info->calc_status     = calc_status;
  10456. X   save_info->stdcalcmode     = stdcalcmode;
  10457. X   save_info->distest          = distest;
  10458. X   save_info->floatflag       = floatflag;
  10459. X   save_info->bailout          = bailout;
  10460. X   save_info->calctime          = calctime;
  10461. X   save_info->trigndx[0]      = trigndx[0];
  10462. X   save_info->trigndx[1]      = trigndx[1];
  10463. X   save_info->trigndx[2]      = trigndx[2];
  10464. X   save_info->trigndx[3]      = trigndx[3];
  10465. X   save_info->finattract      = finattract;
  10466. X   save_info->initorbit[0]    = initorbit.x;
  10467. X   save_info->initorbit[1]    = initorbit.y;
  10468. X   save_info->useinitorbit    = useinitorbit;
  10469. X   save_info->periodicity     = periodicitycheck;
  10470. X   save_info->pot16bit          = disk16bit;
  10471. X   save_info->faspectratio    = finalaspectratio;
  10472. X   save_info->system          = save_system;
  10473. X   save_info->release          = save_release;
  10474. X   save_info->flag3d          = display3d;
  10475. X   save_info->ambient          = Ambient;
  10476. X   save_info->randomize       = RANDOMIZE;
  10477. X   save_info->haze          = haze;
  10478. X   save_info->transparent[0]  = transparent[0];
  10479. X   save_info->transparent[1]  = transparent[1];
  10480. X   save_info->rotate_lo       = rotate_lo;
  10481. X   save_info->rotate_hi       = rotate_hi;
  10482. X   save_info->distestwidth    = distestwidth;
  10483. X   save_info->mxmaxfp         = mxmaxfp;
  10484. X   save_info->mxminfp         = mxminfp;
  10485. X   save_info->mymaxfp         = mymaxfp;
  10486. X   save_info->myminfp         = myminfp;
  10487. X   save_info->zdots           = zdots;        
  10488. X   save_info->originfp        = originfp;
  10489. X   save_info->depthfp         = depthfp;    
  10490. X   save_info->heightfp        = heightfp;
  10491. X   save_info->widthfp         = widthfp;    
  10492. X   save_info->distfp          = distfp;    
  10493. X   save_info->eyesfp          = eyesfp;    
  10494. X   save_info->orbittype       = neworbittype;
  10495. X   save_info->juli3Dmode      = juli3Dmode;
  10496. X   save_info->maxfn           = maxfn;
  10497. X   save_info->inversejulia    = (major_method << 8) + minor_method; /* MVS */
  10498. X   for (i = 0; i < sizeof(save_info->future)/sizeof(short); i++)
  10499. X      save_info->future[i] = 0;
  10500. X}
  10501. SHAR_EOF
  10502. $TOUCH -am 1028230093 encoder.c &&
  10503. chmod 0644 encoder.c ||
  10504. echo "restore of encoder.c failed"
  10505. set `wc -c encoder.c`;Wc_c=$1
  10506. if test "$Wc_c" != "28368"; then
  10507.     echo original size 28368, current size $Wc_c
  10508. fi
  10509. # ============= f16.c ==============
  10510. echo "x - extracting f16.c (Text)"
  10511. sed 's/^X//' << 'SHAR_EOF' > f16.c &&
  10512. X/**************************************
  10513. X**
  10514. X** F16.C : Code to read 16-bit fractal data sets.  Uses
  10515. X** strictly Targa16 type 10 files (run-length encoded 16-bit RGB).
  10516. X*/
  10517. X
  10518. X/* Lee Daniel Crocker       CompuServe: 73407,2030   <== Preferred
  10519. X** 1380 Jewett Ave.          BIX: lcrocker
  10520. X** Pittsburg, CA  94565        Usenet: ...!ames!pacbell!sactoh0!siva!lee
  10521. X**
  10522. X** This code is hereby placed in the public domain.  You are free to
  10523. X** use, modify, usurp, laugh at, destroy, or otherwise abuse it in any
  10524. X** way you see fit.
  10525. X**
  10526. X** "If you steal from one author it's plagiarism; if you steal from
  10527. X** many it's research."  --Wilson Mizner
  10528. X*/
  10529. X
  10530. X/* 16 bit .tga files were generated for continuous potential "potfile"s
  10531. X   from version 9.? thru version 14.  Replaced by double row gif type
  10532. X   file (.pot) in version 15.  Delete this code after a few more revs.
  10533. X   The part which wrote 16 bit .tga files has already been deleted.
  10534. X*/
  10535. X
  10536. X#include <stdio.h>
  10537. X#include <string.h>
  10538. X#include <ctype.h>
  10539. X#include "targa_lc.h"
  10540. X#include "prototyp.h"
  10541. X
  10542. X#ifndef XFRACT
  10543. Xextern char rlebuf[258];    /* RLE-state variables */
  10544. X#else
  10545. Xchar rlebuf[258];    /* RLE-state variables */
  10546. X#endif
  10547. Xstatic int state, count, bufp;
  10548. X
  10549. X/**************************************
  10550. X**
  10551. X** Open previously saved Targa16 type 10 file filling in hs, vs, and
  10552. X** csize with values in the header.  If *csize is not zero, the block
  10553. X** pointed to by cp is filled with the comment block.  The caller
  10554. X** _must_ allocate 256 bytes for this purpose before calling.
  10555. X*/
  10556. X
  10557. XFILE *t16_open(char *fname, int *hs, int *vs, int *csize, U8 *cp)
  10558. X{
  10559. X    char filename[64];
  10560. X    U8 header[HEADERSIZE];
  10561. X    FILE *fp;
  10562. X
  10563. X    strcpy(filename, fname);
  10564. X    if (strchr(filename, '.') == NULL) strcat(filename, ".TGA");
  10565. X    if ((fp = fopen(filename, READMODE)) == NULL) return NULL;
  10566. X
  10567. X    fread(header, HEADERSIZE, 1, fp);
  10568. X    if ((header[O_FILETYPE] != T_RLERGB) || (header[O_ESIZE] != 16)) {
  10569. X    fclose(fp);
  10570. X    return NULL;
  10571. X    }
  10572. X    GET16(header[O_HSIZE], *hs);
  10573. X    GET16(header[O_VSIZE], *vs);
  10574. X    if (*csize = header[O_COMMENTLEN]) fread(cp, *csize, 1, fp);
  10575. X
  10576. X    state = count = bufp = 0;
  10577. X    return fp;
  10578. X}
  10579. X
  10580. Xint t16_getline(FILE *fp, int hs, U16 *data)
  10581. X{
  10582. X    int i;
  10583. X
  10584. X    for (i=0; i<hs; ++i) {
  10585. X    if (state == 0) {
  10586. X        bufp = 0;
  10587. X        if ((count = getc(fp)) > 127) {
  10588. X        state = 1;
  10589. X        count -= 127;
  10590. X        fread(rlebuf, 2, 1, fp);
  10591. X        } else {
  10592. X        state = 2;
  10593. X        ++count;
  10594. X        fread(rlebuf, 2, count, fp);
  10595. X        }
  10596. X    }
  10597. X    GET16(rlebuf[bufp], data[i]);
  10598. X    if (--count == 0) state = 0;
  10599. X    if (state == 2) bufp += 2;
  10600. X    }
  10601. X    return 0;
  10602. X}
  10603. X
  10604. SHAR_EOF
  10605. $TOUCH -am 1028230093 f16.c &&
  10606. chmod 0644 f16.c ||
  10607. echo "restore of f16.c failed"
  10608. set `wc -c f16.c`;Wc_c=$1
  10609. if test "$Wc_c" != "2503"; then
  10610.     echo original size 2503, current size $Wc_c
  10611. fi
  10612. # ============= fracsubr.c ==============
  10613. echo "x - extracting fracsubr.c (Text)"
  10614. sed 's/^X//' << 'SHAR_EOF' > fracsubr.c &&
  10615. X/*
  10616. XFRACSUBR.C contains subroutines which belong primarily to CALCFRAC.C and
  10617. XFRACTALS.C, i.e. which are non-fractal-specific fractal engine subroutines.
  10618. X*/
  10619. X
  10620. X#include <stdio.h>
  10621. X#ifndef XFRACT
  10622. X#include <stdarg.h>
  10623. X#else
  10624. X#include <varargs.h>
  10625. X#endif
  10626. X#include <float.h>
  10627. X#include <sys/types.h>
  10628. X#include <sys/timeb.h>
  10629. X#include <stdlib.h>
  10630. X#include "fractint.h"
  10631. X#include "fractype.h"
  10632. X#include "mpmath.h"
  10633. X#include "prototyp.h"
  10634. X
  10635. X/* routines in this module    */
  10636. X
  10637. Xstatic long   _fastcall fudgetolong(double d);
  10638. Xstatic double _fastcall fudgetodouble(long l);
  10639. Xstatic void   _fastcall adjust_to_limits(double);
  10640. Xstatic void   _fastcall smallest_add(double *);
  10641. Xstatic int    _fastcall ratio_bad(double,double);
  10642. Xstatic void   _fastcall plotdorbit(double,double,int);
  10643. Xstatic int    _fastcall combine_worklist(void);
  10644. X
  10645. X
  10646. Xextern int    calc_status;        /* status of calculations */
  10647. Xextern char far *resume_info;        /* pointer to resume info if allocated */
  10648. X       int    resume_len;        /* length of resume info */
  10649. Xstatic int    resume_offset;        /* offset in resume info gets */
  10650. Xextern double plotmx1,plotmx2,plotmy1,plotmy2; /* real->screen conversion */
  10651. Xextern int    orbit_ptr;        /* pointer into save_orbit array */
  10652. Xextern int orbit_delay;         /* orbit delay value */
  10653. Xextern int far *save_orbit;        /* array to save orbit values */
  10654. Xextern int    orbit_color;        /* XOR color */
  10655. Xextern int    num_worklist;        /* resume worklist for standard engine */
  10656. Xextern int    fractype;         /* fractal type */
  10657. Xextern char   stdcalcmode;        /* '1', '2', 'g', 'b'       */
  10658. Xextern char   floatflag;        /* floating-point fractals? */
  10659. Xextern int    integerfractal;        /* TRUE if fractal uses integer math */
  10660. Xextern struct workliststuff worklist[MAXCALCWORK];
  10661. Xextern int    sxdots,sydots;        /* # of dots on the physical screen    */
  10662. Xextern int    sxoffs,syoffs;        /* physical top left of logical screen */
  10663. Xextern int    xdots, ydots;        /* # of dots on the logical screen     */
  10664. Xextern int    colors;            /* maximum colors available */
  10665. Xextern long   fudge;            /* fudge factor (2**n) */
  10666. Xextern int    bitshift;         /* bit shift for fudge */
  10667. Xextern int    inside;            /* inside color: 1=blue     */
  10668. Xextern int    outside;            /* outside color    */
  10669. Xextern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* corners */
  10670. Xextern long   xmin, xmax, ymin, ymax, x3rd, y3rd;  /* integer equivs */
  10671. Xextern int    maxit;            /* try this many iterations */
  10672. Xextern int    attractors;        /* number of finite attractors    */
  10673. Xextern _CMPLX  attr[];        /* finite attractor vals (f.p)    */
  10674. Xextern _LCMPLX lattr[];     /* finite attractor vals (int)    */
  10675. Xextern int    attrperiod[];         /* finite attractor period    */
  10676. Xextern _CMPLX  old,new;
  10677. Xextern _LCMPLX lold,lnew;
  10678. Xextern double tempsqrx,tempsqry;
  10679. Xextern long   ltempsqrx,ltempsqry;
  10680. Xextern int    xxstart,xxstop;        /* these are same as worklist, */
  10681. Xextern int    yystart,yystop,yybegin;    /* declared as separate items  */
  10682. Xextern int    periodicitycheck;
  10683. Xextern int    basin;
  10684. Xextern int    finattract;
  10685. Xextern int    pixelpi;            /* value of pi in pixels */
  10686. Xextern double closenuff;
  10687. Xextern long   lclosenuff;
  10688. Xextern int    ixstart, ixstop, iystart, iystop;
  10689. Xextern int    color;
  10690. Xextern int    decomp[];
  10691. Xextern double potparam[3];        /* three potential parameters*/
  10692. Xextern int    distest;            /* non-zero if distance estimator */
  10693. Xextern double param[];          /* parameters */
  10694. Xextern int    invert;            /* non-zero if inversion active */
  10695. Xextern int    biomorph,usr_biomorph;
  10696. Xextern int    debugflag; /* internal use only - you didn't see this */
  10697. Xextern long   creal, cimag;        /* for calcmand */
  10698. Xextern long   delx, dely;        /* screen pixel increments  */
  10699. Xextern long   delx2, dely2;        /* screen pixel increments  */
  10700. Xextern double delxx, delyy;        /* screen pixel increments  */
  10701. Xextern double delxx2, delyy2;        /* screen pixel increments  */
  10702. Xextern long   delmin;            /* for calcfrac/calcmand    */
  10703. Xextern double ddelmin;            /* same as a double        */
  10704. Xextern int    potflag;            /* continuous potential flag */
  10705. Xextern int    bailout;
  10706. Xextern double rqlim;
  10707. Xextern double  dxsize, dysize;        /* xdots-1, ydots-1        */
  10708. Xextern int soundflag;
  10709. Xextern int basehertz;
  10710. X
  10711. Xextern long   far *lx0, far *ly0;    /* x, y grid            */
  10712. Xextern long   far *lx1, far *ly1;    /* adjustment for rotate    */
  10713. X/* note that lx1 & ly1 values can overflow into sign bit; since     */
  10714. X/* they're used only to add to lx0/ly0, 2s comp straightens it out  */
  10715. Xextern double far *dx0, far *dy0;    /* floating pt equivs */
  10716. Xextern double far *dx1, far *dy1;
  10717. X
  10718. Xextern char   usr_floatflag;
  10719. Xextern char   usr_stdcalcmode;
  10720. Xextern int    usr_periodicitycheck;
  10721. Xextern int    usr_distest;
  10722. Xextern double zwidth;
  10723. X
  10724. Xextern int neworbittype;
  10725. X
  10726. X#define FUDGEFACTOR    29    /* fudge all values up by 2**this */
  10727. X#define FUDGEFACTOR2    24    /* (or maybe this)          */
  10728. X
  10729. X
  10730. Xvoid calcfracinit() /* initialize a *pile* of stuff for fractal calculation */
  10731. X{
  10732. X   int i;
  10733. X   double ftemp;
  10734. X
  10735. X   floatflag = usr_floatflag;
  10736. X   if (calc_status == 2) /* on resume, ensure floatflag correct */
  10737. X      if (curfractalspecific->isinteger)
  10738. X     floatflag = 0;
  10739. X      else
  10740. X     floatflag = 1;
  10741. X   /* if floating pt only, set floatflag for TAB screen */
  10742. X   if (!curfractalspecific->isinteger && curfractalspecific->tofloat == NOFRACTAL)
  10743. X      floatflag = 1;
  10744. X
  10745. Xinit_restart:
  10746. X
  10747. X   /* the following variables may be forced to a different setting due to
  10748. X      calc routine constraints;  usr_xxx is what the user last said is wanted,
  10749. X      xxx is what we actually do in the current situation */
  10750. X   stdcalcmode        = usr_stdcalcmode;
  10751. X   periodicitycheck = usr_periodicitycheck;
  10752. X   distest        = usr_distest;
  10753. X   biomorph        = usr_biomorph;
  10754. X
  10755. X   potflag = 0;
  10756. X   if (potparam[0] != 0.0
  10757. X     && colors >= 64
  10758. X     && (curfractalspecific->calctype == StandardFractal
  10759. X     || curfractalspecific->calctype == calcmand
  10760. X     || curfractalspecific->calctype == calcmandfp)) {
  10761. X      potflag = 1;
  10762. X      distest = 0;    /* can't do distest too */
  10763. X      }
  10764. X
  10765. X   if (distest)
  10766. X      floatflag = 1;  /* force floating point for dist est */
  10767. X
  10768. X   if (floatflag) { /* ensure type matches floatflag */
  10769. X      if (curfractalspecific->isinteger != 0
  10770. X    && curfractalspecific->tofloat != NOFRACTAL)
  10771. X     fractype = curfractalspecific->tofloat;
  10772. X      }
  10773. X   else {
  10774. X      if (curfractalspecific->isinteger == 0
  10775. X    && curfractalspecific->tofloat != NOFRACTAL)
  10776. X     fractype = curfractalspecific->tofloat;
  10777. X      }
  10778. X   /* match Julibrot with integer mode of orbit */   
  10779. X   if(fractype == JULIBROTFP && fractalspecific[neworbittype].isinteger)
  10780. X   {
  10781. X      int i;
  10782. X      if((i=fractalspecific[neworbittype].tofloat) != NOFRACTAL)
  10783. X         neworbittype = i;
  10784. X      else
  10785. X         fractype = JULIBROT;   
  10786. X   }
  10787. X   else if(fractype == JULIBROT && fractalspecific[neworbittype].isinteger==0)
  10788. X   {
  10789. X      int i;
  10790. X      if((i=fractalspecific[neworbittype].tofloat) != NOFRACTAL)
  10791. X         neworbittype = i;
  10792. X      else
  10793. X         fractype = JULIBROTFP;   
  10794. X   }
  10795. X      
  10796. X   curfractalspecific = &fractalspecific[fractype];
  10797. X
  10798. X   integerfractal = curfractalspecific->isinteger;
  10799. X
  10800. X/*   if (fractype == JULIBROT)
  10801. X      rqlim = 4;
  10802. X   else */ if (potflag && potparam[2] != 0.0)
  10803. X      rqlim = potparam[2];
  10804. X/* else if (decomp[0] > 0 && decomp[1] > 0)
  10805. X      rqlim = (double)decomp[1]; */
  10806. X   else if (bailout) /* user input bailout */
  10807. X      rqlim = bailout;
  10808. X   else if (biomorph != -1) /* biomorph benefits from larger bailout */
  10809. X      rqlim = 100;
  10810. X   else
  10811. X      rqlim = curfractalspecific->orbit_bailout;
  10812. X   if (integerfractal) /* the bailout limit mustn't be too high here */
  10813. X      if (rqlim > 127.0) rqlim = 127.0;
  10814. X
  10815. X   if ((curfractalspecific->flags&NOROTATE) != 0) {
  10816. X      /* ensure min<max and unrotated rectangle */
  10817. X      if (xxmin > xxmax) { ftemp = xxmax; xxmax = xxmin; xxmin = ftemp; }
  10818. X      if (yymin > yymax) { ftemp = yymax; yymax = yymin; yymin = ftemp; }
  10819. X      xx3rd = xxmin; yy3rd = yymin;
  10820. X      }
  10821. X
  10822. X   /* set up bitshift for integer math */
  10823. X   bitshift = FUDGEFACTOR2; /* by default, the smaller shift */
  10824. X   if (integerfractal > 1)  /* use specific override from table */
  10825. X      bitshift = integerfractal;
  10826. X   if (integerfractal == 0) /* float? */
  10827. X      if ((i = curfractalspecific->tofloat) != NOFRACTAL) /* -> int? */
  10828. X     if (fractalspecific[i].isinteger > 1) /* specific shift? */
  10829. X        bitshift = fractalspecific[i].isinteger;
  10830. X
  10831. X/* We want this code if we're using the assembler calcmand */
  10832. X   if (fractype == MANDEL || fractype == JULIA) { /* adust shift bits if.. */
  10833. X      if (potflag == 0                  /* not using potential */
  10834. X    && (param[0] > -2.0 && param[0] < 2.0)  /* parameters not too large */
  10835. X    && (param[1] > -2.0 && param[1] < 2.0)
  10836. X    && !invert                  /* and not inverting */
  10837. X    && biomorph == -1              /* and not biomorphing */
  10838. X    && rqlim <= 4.0               /* and bailout not too high */
  10839. X    && (outside > -2 || outside < -5)      /* and no funny outside stuff */
  10840. X    && debugflag != 1234)              /* and not debugging */
  10841. X     bitshift = FUDGEFACTOR;          /* use the larger bitshift */
  10842. X      }
  10843. X
  10844. X   fudge = 1L << bitshift;
  10845. X
  10846. X   l_at_rad = fudge/32768L;
  10847. X   f_at_rad = 1.0/32768L;
  10848. X
  10849. X   /* now setup arrays of real coordinates corresponding to each pixel */
  10850. X
  10851. X   adjust_to_limits(1.0); /* make sure all corners in valid range */
  10852. X
  10853. X   delxx  = (xxmax - xx3rd) / dxsize; /* calculate stepsizes */
  10854. X   delyy  = (yymax - yy3rd) / dysize;
  10855. X   delxx2 = (xx3rd - xxmin) / dysize;
  10856. X   delyy2 = (yy3rd - yymin) / dxsize;
  10857. X
  10858. X  if(fractype != CELLULAR) { /* fudgetolong fails w >10 digits in double */
  10859. X   creal = fudgetolong(param[0]); /* integer equivs for it all */
  10860. X   cimag = fudgetolong(param[1]);
  10861. X   xmin  = fudgetolong(xxmin);
  10862. X   xmax  = fudgetolong(xxmax);
  10863. X   x3rd  = fudgetolong(xx3rd);
  10864. X   ymin  = fudgetolong(yymin);
  10865. X   ymax  = fudgetolong(yymax);
  10866. X   y3rd  = fudgetolong(yy3rd);
  10867. X   delx  = fudgetolong(delxx);
  10868. X   dely  = fudgetolong(delyy);
  10869. X   delx2 = fudgetolong(delxx2);
  10870. X   dely2 = fudgetolong(delyy2);
  10871. X  }
  10872. X
  10873. X   if (fractype != PLASMA) { /* skip this if plasma to avoid 3d problems */
  10874. X      if (integerfractal && !invert) {
  10875. X     if (    (delx  == 0 && delxx  != 0.0)
  10876. X         || (delx2 == 0 && delxx2 != 0.0)
  10877. X         || (dely  == 0 && delyy  != 0.0)
  10878. X         || (dely2 == 0 && delyy2 != 0.0) )
  10879. X        goto expand_retry;
  10880. X     lx0[0] = xmin;         /* fill up the x, y grids */
  10881. X     ly0[0] = ymax;
  10882. X     lx1[0] = ly1[0] = 0;
  10883. X     for (i = 1; i < xdots; i++ ) {
  10884. X        lx0[i] = lx0[i-1] + delx;
  10885. X        ly1[i] = ly1[i-1] - dely2;
  10886. X        }
  10887. X     for (i = 1; i < ydots; i++ ) {
  10888. X        ly0[i] = ly0[i-1] - dely;
  10889. X        lx1[i] = lx1[i-1] + delx2;
  10890. X        }
  10891. X     /* past max res?  check corners within 10% of expected */
  10892. X     if (    ratio_bad((double)lx0[xdots-1]-xmin,(double)xmax-x3rd)
  10893. X         || ratio_bad((double)ly0[ydots-1]-ymax,(double)y3rd-ymax)
  10894. X         || ratio_bad((double)lx1[(ydots>>1)-1],((double)x3rd-xmin)/2)
  10895. X         || ratio_bad((double)ly1[(xdots>>1)-1],((double)ymin-y3rd)/2) ) {
  10896. Xexpand_retry:
  10897. X        if (integerfractal        /* integer fractal type? */
  10898. X          && curfractalspecific->tofloat != NOFRACTAL)
  10899. X           floatflag = 1;        /* switch to floating pt */
  10900. X        else
  10901. X           adjust_to_limits(2.0);    /* double the size */
  10902. X        if (calc_status == 2)    /* due to restore of an old file? */
  10903. X           calc_status = 0;     /*   whatever, it isn't resumable */
  10904. X        goto init_restart;
  10905. X        }
  10906. X     /* re-set corners to match reality */
  10907. X     xmax = lx0[xdots-1] + lx1[ydots-1];
  10908. X     ymin = ly0[ydots-1] + ly1[xdots-1];
  10909. X     x3rd = xmin + lx1[ydots-1];
  10910. X     y3rd = ly0[ydots-1];
  10911. X     xxmin = fudgetodouble(xmin);
  10912. X     xxmax = fudgetodouble(xmax);
  10913. X     xx3rd = fudgetodouble(x3rd);
  10914. X     yymin = fudgetodouble(ymin);
  10915. X     yymax = fudgetodouble(ymax);
  10916. X     yy3rd = fudgetodouble(y3rd);
  10917. X     }
  10918. X      else {
  10919. X     /* set up dx0 and dy0 analogs of lx0 and ly0 */
  10920. X     /* put fractal parameters in doubles */
  10921. X     dx0[0] = xxmin;        /* fill up the x, y grids */
  10922. X     dy0[0] = yymax;
  10923. X     dx1[0] = dy1[0] = 0;
  10924. X     for (i = 1; i < xdots; i++ ) {
  10925. X        dx0[i] = dx0[i-1] + delxx;
  10926. X        dy1[i] = dy1[i-1] - delyy2;
  10927. X        }
  10928. X     for (i = 1; i < ydots; i++ ) {
  10929. X        dy0[i] = dy0[i-1] - delyy;
  10930. X        dx1[i] = dx1[i-1] + delxx2;
  10931. X        }
  10932. X     if (    ratio_bad(dx0[xdots-1]-xxmin,xxmax-xx3rd)
  10933. X         || ratio_bad(dy0[ydots-1]-yymax,yy3rd-yymax)
  10934. X         || ratio_bad(dx1[ydots-1],xx3rd-xxmin)
  10935. X         || ratio_bad(dy1[xdots-1],yymin-yy3rd))
  10936. X        goto expand_retry;
  10937. X     /* re-set corners to match reality */
  10938. X     xxmax = dx0[xdots-1] + dx1[ydots-1];
  10939. X     yymin = dy0[ydots-1] + dy1[xdots-1];
  10940. X     xx3rd = xxmin + dx1[ydots-1];
  10941. X     yy3rd = dy0[ydots-1];
  10942. X     }
  10943. X      }
  10944. X
  10945. X   /* for periodicity close-enough, and for unity: */
  10946. X   /*      min(max(delx,delx2),max(dely,dely2)       */
  10947. X   ddelmin = fabs(delxx);
  10948. X   if (fabs(delxx2) > ddelmin)
  10949. X      ddelmin = fabs(delxx2);
  10950. X   if (fabs(delyy) > fabs(delyy2)) {
  10951. X      if (fabs(delyy) < ddelmin)
  10952. X     ddelmin = fabs(delyy);
  10953. X      }
  10954. X   else
  10955. X      if (fabs(delyy2) < ddelmin)
  10956. X     ddelmin = fabs(delyy2);
  10957. X   delmin = fudgetolong(ddelmin);
  10958. X
  10959. X   /* calculate factors which plot real values to screen co-ords */
  10960. X   /* calcfrac.c plot_orbit routines have comments about this     */
  10961. X   ftemp = (0.0-delyy2) * delxx2 * dxsize * dysize
  10962. X       - (xxmax-xx3rd) * (yy3rd-yymax);
  10963. X   plotmx1 = delxx2 * dxsize * dysize / ftemp;
  10964. X   plotmx2 = (yy3rd-yymax) * dxsize / ftemp;
  10965. X   plotmy1 = (0.0-delyy2) * dxsize * dysize / ftemp;
  10966. X   plotmy2 = (xxmax-xx3rd) * dysize / ftemp;
  10967. X
  10968. X}
  10969. X
  10970. Xstatic long _fastcall fudgetolong(double d)
  10971. X{
  10972. X   if ((d *= fudge) > 0) d += 0.5;
  10973. X   else          d -= 0.5;
  10974. X   return (long)d;
  10975. X}
  10976. X
  10977. Xstatic double _fastcall fudgetodouble(long l)
  10978. X{
  10979. X   char buf[30];
  10980. X   double d;
  10981. X   sprintf(buf,"%.9g",(double)l / fudge);
  10982. X#ifndef XFRACT
  10983. X   sscanf(buf,"%lg",&d);
  10984. X#else
  10985. X   sscanf(buf,"%lf",&d);
  10986. X#endif
  10987. X   return d;
  10988. X}
  10989. X
  10990. X
  10991. Xvoid adjust_corner()
  10992. X{
  10993. X   /* make edges very near vert/horiz exact, to ditch rounding errs and */
  10994. X   /* to avoid problems when delta per axis makes too large a ratio    */
  10995. X   double ftemp,ftemp2;
  10996. X   if( (ftemp=fabs(xx3rd-xxmin)) < (ftemp2=fabs(xxmax-xx3rd)) ) {
  10997. X      if (ftemp*10000 < ftemp2 && yy3rd != yymax)
  10998. X     xx3rd = xxmin;
  10999. X      }
  11000. X   else if (ftemp2*10000 < ftemp && yy3rd != yymin)
  11001. X      xx3rd = xxmax;
  11002. X   if( (ftemp=fabs(yy3rd-yymin)) < (ftemp2=fabs(yymax-yy3rd)) ) {
  11003. X      if (ftemp*10000 < ftemp2 && xx3rd != xxmax)
  11004. X     yy3rd = yymin;
  11005. X      }
  11006. X   else if (ftemp2*10000 < ftemp && xx3rd != xxmin)
  11007. X      yy3rd = yymax;
  11008. X}
  11009. X
  11010. Xstatic void _fastcall adjust_to_limits(double expand)
  11011. X{  double cornerx[4],cornery[4];
  11012. X   double lowx,highx,lowy,highy,limit,ftemp;
  11013. X   double centerx,centery,adjx,adjy;
  11014. X   int i;
  11015. X   limit = 32767.99;
  11016. X   if (bitshift >= 24) limit = 31.99;
  11017. X   if (bitshift >= 29) limit = 3.99;
  11018. X   centerx = (xxmin+xxmax)/2;
  11019. X   centery = (yymin+yymax)/2;
  11020. X   if (xxmin == centerx) { /* ohoh, infinitely thin, fix it */
  11021. X      smallest_add(&xxmax);
  11022. X      xxmin -= xxmax-centerx;
  11023. X      }
  11024. X   if (yymin == centery) {
  11025. X      smallest_add(&yymax);
  11026. X      yymin -= yymax-centery;
  11027. X      }
  11028. X   if (xx3rd == centerx)
  11029. X      smallest_add(&xx3rd);
  11030. X   if (yy3rd == centery)
  11031. X      smallest_add(&yy3rd);
  11032. X   /* setup array for easier manipulation */
  11033. X   cornerx[0] = xxmin; cornerx[1] = xxmax;
  11034. X   cornerx[2] = xx3rd; cornerx[3] = xxmin+(xxmax-xx3rd);
  11035. X   cornery[0] = yymax; cornery[1] = yymin;
  11036. X   cornery[2] = yy3rd; cornery[3] = yymin+(yymax-yy3rd);
  11037. X   /* if caller wants image size adjusted, do that first */
  11038. X   if (expand != 1.0)
  11039. X      for (i=0; i<4; ++i) {
  11040. X     cornerx[i] = centerx + (cornerx[i]-centerx)*expand;
  11041. X     cornery[i] = centery + (cornery[i]-centery)*expand;
  11042. X      }
  11043. X   /* get min/max x/y values */
  11044. X   lowx = highx = cornerx[0];
  11045. X   lowy = highy = cornery[0];
  11046. X   for (i=1; i<4; ++i) {
  11047. X      if (cornerx[i] < lowx)  lowx  = cornerx[i];
  11048. X      if (cornerx[i] > highx) highx = cornerx[i];
  11049. X      if (cornery[i] < lowy)  lowy  = cornery[i];
  11050. X      if (cornery[i] > highy) highy = cornery[i];
  11051. X      }
  11052. X   /* if image is too large, downsize it maintaining center */
  11053. X   ftemp = highx-lowx;
  11054. X   if (highy-lowy > ftemp) ftemp = highy-lowy;
  11055. X   if ((ftemp = limit*2/ftemp) < 1.0)
  11056. X      for (i=0; i<4; ++i) {
  11057. X     cornerx[i] = centerx + (cornerx[i]-centerx)*ftemp;
  11058. X     cornery[i] = centery + (cornery[i]-centery)*ftemp;
  11059. X     }
  11060. X   /* if any corner has x or y past limit, move the image */
  11061. X   adjx = adjy = 0;
  11062. X   for (i=0; i<4; ++i) {
  11063. X      if (cornerx[i] > limit     && (ftemp = cornerx[i] - limit) > adjx)
  11064. X     adjx = ftemp;
  11065. X      if (cornerx[i] < 0.0-limit && (ftemp = cornerx[i] + limit) < adjx)
  11066. X     adjx = ftemp;
  11067. X      if (cornery[i] > limit     && (ftemp = cornery[i] - limit) > adjy)
  11068. X     adjy = ftemp;
  11069. X      if (cornery[i] < 0.0-limit && (ftemp = cornery[i] + limit) < adjy)
  11070. X     adjy = ftemp;
  11071. X      }
  11072. X   if (calc_status == 2 && (adjx != 0 || adjy != 0) && (zwidth == 1.0))
  11073. X      calc_status = 0;
  11074. X   xxmin = cornerx[0] - adjx;
  11075. X   xxmax = cornerx[1] - adjx;
  11076. X   xx3rd = cornerx[2] - adjx;
  11077. X   yymax = cornery[0] - adjy;
  11078. X   yymin = cornery[1] - adjy;
  11079. X   yy3rd = cornery[2] - adjy;
  11080. X   adjust_corner(); /* make 3rd corner exact if very near other co-ords */
  11081. X}
  11082. X
  11083. Xstatic void _fastcall smallest_add(double *num)
  11084. X{
  11085. X   *num += *num * 5.0e-16;
  11086. X}
  11087. X
  11088. Xstatic int _fastcall ratio_bad(double actual, double desired)
  11089. X{  double ftemp;
  11090. X   if (desired != 0)
  11091. X      if ((ftemp = actual / desired) < 0.95 || ftemp > 1.05)
  11092. X     return(1);
  11093. X   return(0);
  11094. X}
  11095. X
  11096. X
  11097. X/* Save/resume stuff:
  11098. X
  11099. X   Engines which aren't resumable can simply ignore all this.
  11100. X
  11101. X   Before calling the (per_image,calctype) routines (engine), calcfract sets:
  11102. X      "resuming" to 0 if new image, nonzero if resuming a partially done image
  11103. X      "calc_status" to 1
  11104. X   If an engine is interrupted and wants to be able to resume it must:
  11105. X      store whatever status info it needs to be able to resume later
  11106. X      set calc_status to 2 and return
  11107. X   If subsequently called with resuming!=0, the engine must restore status
  11108. X   info and continue from where it left off.
  11109. X
  11110. X   Since the info required for resume can get rather large for some types,
  11111. X   it is not stored directly in save_info.  Instead, memory is dynamically
  11112. X   allocated as required, and stored in .fra files as a separate block.
  11113. X   To save info for later resume, an engine routine can use:
  11114. X      alloc_resume(maxsize,version)
  11115. X     Maxsize must be >= max bytes subsequently saved + 2; over-allocation
  11116. X     is harmless except for possibility of insufficient mem available;
  11117. X     undersize is not checked and probably causes serious misbehaviour.
  11118. X     Version is an arbitrary number so that subsequent revisions of the
  11119. X     engine can be made backward compatible.
  11120. X     Alloc_resume sets calc_status to 2 (resumable) if it succeeds; to 3
  11121. X     if it cannot allocate memory (and issues warning to user).
  11122. X      put_resume({bytes,&argument,} ... 0)
  11123. X     Can be called as often as required to store the info.
  11124. X     Arguments must not be far addresses.
  11125. X     Is not protected against calls which use more space than allocated.
  11126. X   To reload info when resuming, use:
  11127. X      start_resume()
  11128. X     initializes and returns version number
  11129. X      get_resume({bytes,&argument,} ... 0)
  11130. X     inverse of store_resume
  11131. X      end_resume()
  11132. X     optional, frees the memory area sooner than would happen otherwise
  11133. X
  11134. X   Example, save info:
  11135. X      alloc_resume(sizeof(parmarray)+100,2);
  11136. X      put_resume(sizeof(int),&row, sizeof(int),&col,
  11137. X         sizeof(parmarray),parmarray, 0);
  11138. X    restore info:
  11139. X      vsn = start_resume();
  11140. X      get_resume(sizeof(int),&row, sizeof(int),&col, 0);
  11141. X      if (vsn >= 2)
  11142. X     get_resume(sizeof(parmarray),parmarray,0);
  11143. X      end_resume();
  11144. X
  11145. X   Engines which allocate a large far memory chunk of their own might
  11146. X   directly set resume_info, resume_len, calc_status to avoid doubling
  11147. X   transient memory needs by using these routines.
  11148. X
  11149. X   StandardFractal, calcmand, solidguess, and bound_trace_main are a related
  11150. X   set of engines for escape-time fractals.  They use a common worklist
  11151. X   structure for save/resume.  Fractals using these must specify calcmand
  11152. X   or StandardFractal as the engine in fractalspecificinfo.
  11153. X   Other engines don't get btm nor ssg, don't get off-axis symmetry nor
  11154. X   panning (the worklist stuff), and are on their own for save/resume.
  11155. X
  11156. X   */
  11157. X
  11158. X#ifndef XFRACT
  11159. Xint put_resume(int len, ...)
  11160. X#else
  11161. Xint put_resume(va_alist)
  11162. Xva_dcl
  11163. X#endif
  11164. X{
  11165. X   va_list arg_marker;    /* variable arg list */
  11166. X   char *source_ptr;
  11167. X#ifdef XFRACT
  11168. X   int len;
  11169. X#endif
  11170. X
  11171. X   if (resume_info == NULL)
  11172. X      return(-1);
  11173. X#ifndef XFRACT
  11174. X   va_start(arg_marker,len);
  11175. X#else
  11176. X   va_start(arg_marker);
  11177. X   len = va_arg(arg_marker,int);
  11178. X#endif
  11179. X   while (len)
  11180. X   {
  11181. X      source_ptr = va_arg(arg_marker,char *);
  11182. X      far_memcpy(resume_info+resume_len,source_ptr,len);
  11183. X      resume_len += len;
  11184. X      len = va_arg(arg_marker,int);
  11185. X   }
  11186. X   return(0);
  11187. X}
  11188. X
  11189. Xint alloc_resume(int alloclen, int version)
  11190. X{
  11191. X   if (resume_info != NULL) /* free the prior area if there is one */
  11192. X      farmemfree(resume_info);
  11193. X   if ((resume_info = farmemalloc((long)alloclen))== NULL)
  11194. X   {
  11195. X      static char msg[] = {"\
  11196. XWarning - insufficient free memory to save status.\n\
  11197. XYou will not be able to resume calculating this image."};
  11198. X      stopmsg(0,msg);
  11199. X      calc_status = 3;
  11200. X      return(-1);
  11201. X   }
  11202. X   resume_len = 0;
  11203. X   put_resume(sizeof(int),&version,0);
  11204. X   calc_status = 2;
  11205. X   return(0);
  11206. X}
  11207. X
  11208. X#ifndef XFRACT
  11209. Xint get_resume(int len, ...)
  11210. X#else
  11211. Xint get_resume(va_alist)
  11212. Xva_dcl
  11213. X#endif
  11214. X{
  11215. X   va_list arg_marker;    /* variable arg list */
  11216. X   char *dest_ptr;
  11217. X#ifdef XFRACT
  11218. X   int len;
  11219. X#endif
  11220. X
  11221. X   if (resume_info == NULL)
  11222. X      return(-1);
  11223. X#ifndef XFRACT
  11224. X   va_start(arg_marker,len);
  11225. X#else
  11226. X   va_start(arg_marker);
  11227. X   len = va_arg(arg_marker,int);
  11228. X#endif
  11229. X   while (len)
  11230. X   {
  11231. X      dest_ptr = va_arg(arg_marker,char *);
  11232. X      far_memcpy(dest_ptr,resume_info+resume_offset,len);
  11233. X      resume_offset += len;
  11234. X      len = va_arg(arg_marker,int);
  11235. X   }
  11236. X   return(0);
  11237. X}
  11238. X
  11239. Xint start_resume()
  11240. X{
  11241. X   int version;
  11242. X   if (resume_info == NULL)
  11243. X      return(-1);
  11244. X   resume_offset = 0;
  11245. X   get_resume(sizeof(int),&version,0);
  11246. X   return(version);
  11247. X}
  11248. X
  11249. Xvoid end_resume()
  11250. X{
  11251. X   if (resume_info != NULL) /* free the prior area if there is one */
  11252. X   {
  11253. X      farmemfree(resume_info);
  11254. X      resume_info = NULL;
  11255. X   }
  11256. X}
  11257. X
  11258. X
  11259. X/* Showing orbit requires converting real co-ords to screen co-ords.
  11260. X   Define:
  11261. X       Xs == xxmax-xx3rd           Ys == yy3rd-yymax
  11262. X       W  == xdots-1               D  == ydots-1
  11263. X   We know that:
  11264. X       realx == lx0[col] + lx1[row]
  11265. X       realy == ly0[row] + ly1[col]
  11266. X       lx0[col] == (col/width) * Xs + xxmin
  11267. X       lx1[row] == row * delxx
  11268. X       ly0[row] == (row/D) * Ys + yymax
  11269. X       ly1[col] == col * (0-delyy)
  11270. X  so:
  11271. X       realx == (col/W) * Xs + xxmin + row * delxx
  11272. X       realy == (row/D) * Ys + yymax + col * (0-delyy)
  11273. X  and therefore:
  11274. X       row == (realx-xxmin - (col/W)*Xs) / Xv     (1)
  11275. X       col == (realy-yymax - (row/D)*Ys) / Yv     (2)
  11276. X  substitute (2) into (1) and solve for row:
  11277. X       row == ((realx-xxmin)*(0-delyy2)*W*D - (realy-yymax)*Xs*D)
  11278. X              / ((0-delyy2)*W*delxx2*D-Ys*Xs)
  11279. X  */
  11280. X
  11281. X/* sleep N * a tenth of a millisecond */
  11282. X
  11283. Xvoid sleepms(long ms)
  11284. X{
  11285. X    extern int tabmode;
  11286. X    static long scalems=0L;
  11287. X    int savehelpmode,savetabmode;
  11288. X    struct timeb t1,t2;
  11289. X#define SLEEPINIT 250 /* milliseconds for calibration */
  11290. X    savetabmode  = tabmode;
  11291. X    savehelpmode = helpmode;
  11292. X    tabmode  = 0;
  11293. X    helpmode = -1;
  11294. X    if(scalems==0L) /* calibrate */
  11295. X    {
  11296. X    /* selects a value of scalems that makes the units
  11297. X       10000 per sec independent of CPU speed */
  11298. X    char msg[80];
  11299. X    long millisecs;
  11300. X    int i,elapsed;
  11301. X
  11302. X    scalems = 1L;
  11303. X    if(keypressed()) /* check at start, hope to get start of timeslice */
  11304. X       goto sleepexit;
  11305. X    /* calibrate, assume slow computer first */
  11306. X    do
  11307. X    {
  11308. X       scalems *= 2;
  11309. X       ftime(&t2);
  11310. X       do { /* wait for the start of a new tick */
  11311. X          ftime(&t1);
  11312. X        }
  11313. X        while (t2.time == t1.time && t2.millitm == t1.millitm);
  11314. X       sleepms(10L * SLEEPINIT); /* about 1/4 sec */
  11315. X       ftime(&t2);
  11316. X       if(keypressed()) {
  11317. X          scalems = 0L;
  11318. X          goto sleepexit;
  11319. X       }
  11320. X     }
  11321. X     while ((elapsed = (int)(t2.time-t1.time)*1000 + t2.millitm-t1.millitm)
  11322. X        < SLEEPINIT);
  11323. X    /* once more to see if faster (eg multi-tasking) */
  11324. X    do { /* wait for the start of a new tick */
  11325. X       ftime(&t1);
  11326. X       }
  11327. X     while (t2.time == t1.time && t2.millitm == t1.millitm);
  11328. X    sleepms(10L * SLEEPINIT);
  11329. X    ftime(&t2);
  11330. X    if ((i = (int)(t2.time-t1.time)*1000 + t2.millitm-t1.millitm) < elapsed)
  11331. X       elapsed = (i == 0) ? 1 : i;
  11332. X    scalems = (float)SLEEPINIT/(float)(elapsed) * scalems;
  11333. X    if (debugflag == 700) {
  11334. X       sprintf(msg,"scale factor=%ld",scalems);
  11335. X       stopmsg(0,msg);
  11336. X    }
  11337. X    }
  11338. X    if(ms > 10L * SLEEPINIT) { /* using ftime is probably more accurate */
  11339. X    ms /= 10;
  11340. X    ftime(&t1);
  11341. X    while(1) {
  11342. X       if(keypressed()) break;
  11343. X       ftime(&t2);
  11344. X       if ((t2.time-t1.time)*1000 + t2.millitm-t1.millitm >= ms) break;
  11345. X    }
  11346. X    }
  11347. X    else
  11348. X    if(!keypressed()) {
  11349. X       ms *= scalems;
  11350. X       while(ms-- >= 0);
  11351. X    }
  11352. Xsleepexit:
  11353. X    tabmode  = savetabmode;
  11354. X    helpmode = savehelpmode;
  11355. X}
  11356. X
  11357. X
  11358. Xstatic void _fastcall plotdorbit(double dx, double dy, int color)
  11359. X{
  11360. X   int i, j, c;
  11361. X   int save_sxoffs,save_syoffs;
  11362. X   if (orbit_ptr >= 1500) return;
  11363. X   i = dy * plotmx1 - dx * plotmx2; i += sxoffs;
  11364. X   if (i < 0 || i >= sxdots) return;
  11365. X   j = dx * plotmy1 - dy * plotmy2; j += syoffs;
  11366. X   if (j < 0 || j >= sydots) return;
  11367. X   save_sxoffs = sxoffs;
  11368. X   save_syoffs = syoffs;
  11369. X   sxoffs = syoffs = 0;
  11370. X   /* save orbit value */
  11371. X   if(color == -1)
  11372. X   {
  11373. X      *(save_orbit + orbit_ptr++) = i;
  11374. X      *(save_orbit + orbit_ptr++) = j;
  11375. X      *(save_orbit + orbit_ptr++) = c = getcolor(i,j);
  11376. X      putcolor(i,j,c^orbit_color);
  11377. X   }
  11378. X   else
  11379. X      putcolor(i,j,color);
  11380. X   sxoffs = save_sxoffs;
  11381. X   syoffs = save_syoffs;
  11382. X   if(orbit_delay > 0)
  11383. X      sleepms(orbit_delay);
  11384. X   if(soundflag==1)
  11385. X       snd((int)(i*1000/xdots+basehertz));
  11386. X   else if(soundflag > 1)
  11387. X       snd((int)(j*1000/ydots+basehertz));
  11388. X   /* placing sleepms here delays each dot */
  11389. X}
  11390. X
  11391. Xvoid iplot_orbit(ix, iy, color)
  11392. Xlong ix, iy;
  11393. Xint color;
  11394. X{
  11395. X   plotdorbit((double)ix/fudge-xxmin,(double)iy/fudge-yymax,color);
  11396. X}
  11397. X
  11398. Xvoid plot_orbit(real,imag,color)
  11399. Xdouble real,imag;
  11400. Xint color;
  11401. X{
  11402. X   plotdorbit(real-xxmin,imag-yymax,color);
  11403. X}
  11404. X
  11405. Xvoid scrub_orbit()
  11406. X{
  11407. X   static long oldtime = 0;
  11408. X   int i,j,c;
  11409. X   int save_sxoffs,save_syoffs;
  11410. X   save_sxoffs = sxoffs;
  11411. X   save_syoffs = syoffs;
  11412. X   sxoffs = syoffs = 0;
  11413. X   while(orbit_ptr > 0)
  11414. X   {
  11415. X      c = *(save_orbit + --orbit_ptr);
  11416. X      j = *(save_orbit + --orbit_ptr);
  11417. X      i = *(save_orbit + --orbit_ptr);
  11418. X      putcolor(i,j,c);
  11419. X   }
  11420. X   sxoffs = save_sxoffs;
  11421. X   syoffs = save_syoffs;
  11422. X   nosnd();
  11423. X}
  11424. X
  11425. X
  11426. Xint add_worklist(int xfrom, int xto, int yfrom, int yto, int ybegin,
  11427. Xint pass, int sym)
  11428. X{
  11429. X   if (num_worklist >= MAXCALCWORK)
  11430. X      return(-1);
  11431. X   worklist[num_worklist].xxstart = xfrom;
  11432. X   worklist[num_worklist].xxstop  = xto;
  11433. X   worklist[num_worklist].yystart = yfrom;
  11434. X   worklist[num_worklist].yystop  = yto;
  11435. X   worklist[num_worklist].yybegin = ybegin;
  11436. X   worklist[num_worklist].pass      = pass;
  11437. X   worklist[num_worklist].sym      = sym;
  11438. X   ++num_worklist;
  11439. X   tidy_worklist();
  11440. X   return(0);
  11441. X}
  11442. X
  11443. Xstatic int _fastcall combine_worklist() /* look for 2 entries which can freely merge */
  11444. X{
  11445. X   int i,j;
  11446. X   for (i=0; i<num_worklist; ++i)
  11447. X      if (worklist[i].yystart == worklist[i].yybegin)
  11448. X     for (j=i+1; j<num_worklist; ++j)
  11449. X        if (worklist[j].sym == worklist[i].sym
  11450. X        && worklist[j].yystart == worklist[j].yybegin
  11451. X        && worklist[i].pass == worklist[j].pass)
  11452. X        {
  11453. X           if ( worklist[i].xxstart == worklist[j].xxstart
  11454. X           && worklist[i].xxstop  == worklist[j].xxstop)
  11455. X           {
  11456. X          if (worklist[i].yystop+1 == worklist[j].yystart)
  11457. X          {
  11458. X             worklist[i].yystop = worklist[j].yystop;
  11459. X             return(j);
  11460. X          }
  11461. X          if (worklist[j].yystop+1 == worklist[i].yystart)
  11462. X          {
  11463. X             worklist[i].yystart = worklist[j].yystart;
  11464. X             worklist[i].yybegin = worklist[j].yybegin;
  11465. X             return(j);
  11466. X          }
  11467. X           }
  11468. X           if ( worklist[i].yystart == worklist[j].yystart
  11469. X           && worklist[i].yystop  == worklist[j].yystop)
  11470. X           {
  11471. X          if (worklist[i].xxstop+1 == worklist[j].xxstart)
  11472. X          {
  11473. X             worklist[i].xxstop = worklist[j].xxstop;
  11474. X             return(j);
  11475. X          }
  11476. X          if (worklist[j].xxstop+1 == worklist[i].xxstart)
  11477. X          {
  11478. X             worklist[i].xxstart = worklist[j].xxstart;
  11479. X             return(j);
  11480. X          }
  11481. X           }
  11482. X        }
  11483. X   return(0); /* nothing combined */
  11484. X}
  11485. X
  11486. Xvoid tidy_worklist() /* combine mergeable entries, resort */
  11487. X{
  11488. X   int i,j;
  11489. X   struct workliststuff tempwork;
  11490. X   while (i=combine_worklist())
  11491. X   { /* merged two, delete the gone one */
  11492. X      while (++i < num_worklist)
  11493. X     worklist[i-1] = worklist[i];
  11494. X      --num_worklist;
  11495. X   }
  11496. X   for (i=0; i<num_worklist; ++i)
  11497. X      for (j=i+1; j<num_worklist; ++j)
  11498. X     if (worklist[j].pass < worklist[i].pass
  11499. X         || (worklist[j].pass == worklist[i].pass
  11500. X         && (worklist[j].yystart < worklist[i].yystart
  11501. X         || (   worklist[j].yystart == worklist[i].yystart
  11502. X         && worklist[j].xxstart <  worklist[i].xxstart))))
  11503. X     { /* dumb sort, swap 2 entries to correct order */
  11504. X        tempwork = worklist[i];
  11505. X        worklist[i] = worklist[j];
  11506. X        worklist[j] = tempwork;
  11507. X     }
  11508. X}
  11509. X
  11510. X
  11511. Xvoid get_julia_attractor (double real, double imag)
  11512. X{
  11513. X   _LCMPLX lresult;
  11514. X   _CMPLX result;
  11515. X   int savper,savmaxit;
  11516. X   int i;
  11517. X
  11518. X   if (attractors == 0 && finattract == 0) /* not magnet & not requested */
  11519. X      return;
  11520. X
  11521. X   if (attractors >= N_ATTR)     /* space for more attractors ?  */
  11522. X      return;               /* Bad luck - no room left !    */
  11523. X
  11524. X   savper = periodicitycheck;
  11525. X   savmaxit = maxit;
  11526. X   periodicitycheck = 0;
  11527. X   old.x = real;            /* prepare for f.p orbit calc */
  11528. X   old.y = imag;
  11529. X   tempsqrx = sqr(old.x);
  11530. X   tempsqry = sqr(old.y);
  11531. X
  11532. X   lold.x = real;        /* prepare for int orbit calc */
  11533. X   lold.y = imag;
  11534. X   ltempsqrx = tempsqrx;
  11535. X   ltempsqry = tempsqry;
  11536. X
  11537. X   lold.x = lold.x << bitshift;
  11538. X   lold.y = lold.y << bitshift;
  11539. X   ltempsqrx = ltempsqrx << bitshift;
  11540. X   ltempsqry = ltempsqry << bitshift;
  11541. X
  11542. X   if (maxit < 500)        /* we're going to try at least this hard */
  11543. X      maxit = 500;
  11544. X   color = 0;
  11545. X   while (++color < maxit)
  11546. X      if(curfractalspecific->orbitcalc())
  11547. X     break;
  11548. X   if (color >= maxit)        /* if orbit stays in the lake */
  11549. X   {
  11550. X      if (integerfractal)   /* remember where it went to */
  11551. X     lresult = lnew;
  11552. X      else
  11553. X     result =  new;
  11554. X     for (i=0;i<10;i++) {
  11555. X      if(!curfractalspecific->orbitcalc()) /* if it stays in the lake */
  11556. X      {                /* and doen't move far, probably */
  11557. X     if (integerfractal)   /*   found a finite attractor    */
  11558. X     {
  11559. X        if(labs(lresult.x-lnew.x) < lclosenuff
  11560. X        && labs(lresult.y-lnew.y) < lclosenuff)
  11561. X        {
  11562. X           lattr[attractors] = lnew;
  11563. X           attrperiod[attractors] = i+1;
  11564. X           attractors++;   /* another attractor - coloured lakes ! */
  11565. X           break;
  11566. X        }
  11567. X     }
  11568. X     else
  11569. X     {
  11570. X        if(fabs(result.x-new.x) < closenuff
  11571. X        && fabs(result.y-new.y) < closenuff)
  11572. X        {
  11573. X           attr[attractors] = new;
  11574. X           attrperiod[attractors] = i+1;
  11575. X           attractors++;   /* another attractor - coloured lakes ! */
  11576. X           break;
  11577. X        }
  11578. X     }
  11579. X      } else {
  11580. X      break;
  11581. X      }
  11582. X     }
  11583. X   }
  11584. X   if(attractors==0)
  11585. X      periodicitycheck = savper;
  11586. X   maxit = savmaxit;
  11587. X}
  11588. X
  11589. X
  11590. X#define maxyblk 7    /* must match calcfrac.c */
  11591. X#define maxxblk 202  /* must match calcfrac.c */
  11592. Xint ssg_blocksize() /* used by solidguessing and by zoom panning */
  11593. X{
  11594. X   int blocksize,i;
  11595. X   /* blocksize 4 if <300 rows, 8 if 300-599, 16 if 600-1199, 32 if >=1200 */
  11596. X   blocksize=4;
  11597. X   i=300;
  11598. X   while(i<=ydots)
  11599. X   {
  11600. X      blocksize+=blocksize;
  11601. X      i+=i;
  11602. X   }
  11603. X   /* increase blocksize if prefix array not big enough */
  11604. X   while(blocksize*(maxxblk-2)<xdots || blocksize*(maxyblk-2)*16<ydots)
  11605. X      blocksize+=blocksize;
  11606. X   return(blocksize);
  11607. X}
  11608. X
  11609. SHAR_EOF
  11610. $TOUCH -am 1028230093 fracsubr.c &&
  11611. chmod 0644 fracsubr.c ||
  11612. echo "restore of fracsubr.c failed"
  11613. set `wc -c fracsubr.c`;Wc_c=$1
  11614. if test "$Wc_c" != "30883"; then
  11615.     echo original size 30883, current size $Wc_c
  11616. fi
  11617. # ============= fractalp.c ==============
  11618. echo "x - extracting fractalp.c (Text)"
  11619. sed 's/^X//' << 'SHAR_EOF' > fractalp.c &&
  11620. X/*
  11621. X    This module consists only of the fractalspecific structure
  11622. X    and a *slew* of defines needed to get it to compile
  11623. X*/
  11624. X
  11625. X/* includes needed for fractalspecific */
  11626. X
  11627. X#include <stdio.h>
  11628. X#include <stdlib.h>
  11629. X#include "fractint.h"
  11630. X#include "mpmath.h"
  11631. X#include "helpdefs.h"
  11632. X#include "fractype.h"
  11633. X#include "prototyp.h"
  11634. X
  11635. X/* functions defined elswhere needed for fractalspecific */
  11636. X/* moved to prototyp.h */
  11637. X
  11638. X/* parameter descriptions */
  11639. X/* Note: parameters preceded by + are integer parameters */
  11640. X
  11641. X/* for Mandelbrots */
  11642. Xstatic char realz0[] = "Real Perturbation of Z(0)";
  11643. Xstatic char imagz0[] = "Imaginary Perturbation of Z(0)";
  11644. X
  11645. X/* for Julias */
  11646. Xstatic char realparm[] = "Real Part of Parameter";
  11647. Xstatic char imagparm[] = "Imaginary Part of Parameter";
  11648. X
  11649. X/* for Newtons */
  11650. Xstatic char newtdegree[] = "+Polynomial Degree (>= 2)";
  11651. X
  11652. X/* for MarksMandel/Julia */
  11653. Xstatic char exponent[]   = "Real part of Exponent";
  11654. Xstatic char imexponent[] = "Imag part of Exponent";
  11655. X
  11656. X/* for Complex Newton */
  11657. Xstatic char realroot[]     = "Real part of Root";
  11658. Xstatic char imagroot[]     = "Imag part of Root";
  11659. Xstatic char realdegree[] = "Real part of Degree";
  11660. Xstatic char imagdegree[] = "Imag part of Degree";
  11661. X
  11662. X/* for Lorenz */
  11663. Xstatic char timestep[]       = "Time Step";
  11664. X
  11665. X/* for formula */
  11666. Xstatic char p1real[] = "Real portion of p1";
  11667. Xstatic char p2real[] = "Real portion of p2";
  11668. Xstatic char p1imag[] = "Imaginary portion of p1";
  11669. Xstatic char p2imag[] = "Imaginary portion of p2";
  11670. X
  11671. X/* trig functions */
  11672. Xstatic char recoeftrg1[] = "Real Coefficient First Function";
  11673. Xstatic char imcoeftrg1[] = "Imag Coefficient First Function";
  11674. Xstatic char recoeftrg2[] = "Real Coefficient Second Function";
  11675. Xstatic char imcoeftrg2[] = "Imag Coefficient Second Function";
  11676. X
  11677. X/* MCP 7-7-91
  11678. Xstatic char recoefsqr[] = "Real Coefficient Square Term";
  11679. Xstatic char imcoefsqr[] = "Imag Coefficient Square Term";
  11680. X*/
  11681. X
  11682. Xstatic char recoef2nd[] = "Real Coefficient Second Term";
  11683. Xstatic char imcoef2nd[] = "Imag Coefficient Second Term";
  11684. X
  11685. X/* KAM Torus */
  11686. Xstatic char kamangle[] = "Angle (radians)";
  11687. Xstatic char kamstep[] =  "Step size";
  11688. Xstatic char kamstop[] =  "Stop value";
  11689. Xstatic char pointsperorbit[] = "+Points per orbit";
  11690. X
  11691. X/* Newtbasin */
  11692. Xstatic char stripes[] = "Enter non-zero value for stripes";
  11693. X
  11694. X/* Gingerbreadman */
  11695. Xstatic char initx[] = "Initial x";
  11696. Xstatic char inity[] = "Initial y";
  11697. X
  11698. X/* popcorn */
  11699. Xstatic char step[] = "Step size";
  11700. X
  11701. X/* bifurcations */
  11702. Xstatic char filt[] = "+Filter Cycles";
  11703. Xstatic char seed[] = "Seed Population";
  11704. X
  11705. X/* frothy basins */
  11706. Xstatic char frothattractor[] = "+3 or 6 attractor system";
  11707. Xstatic char frothshade[] =  "+Enter non-zero value for alternate color shading";
  11708. X
  11709. X/* symmetrical icon fractals */
  11710. Xstatic char lambda[] = "Lambda";
  11711. Xstatic char alpha[]  = "Alpha";
  11712. Xstatic char beta[]   = "Beta";
  11713. Xstatic char gamma2[]  = "Gamma";
  11714. Xstatic char omega[]  = "Omega";
  11715. Xstatic char symdegree[] = "+Degree of symmetry";
  11716. X
  11717. Xstatic char shiftval[] = "Function Shift Value";
  11718. X
  11719. X/* ifs */
  11720. Xstatic char color_method[] = "+Coloring method (0,1)";
  11721. X
  11722. X/* orbit fractals */
  11723. Xstatic char A[] = "a";
  11724. Xstatic char B[] = "b";
  11725. Xstatic char D[] = "d";
  11726. X
  11727. X/* 4D fractals */
  11728. Xstatic char C[] = "c";
  11729. Xstatic char C1[] = "c1";
  11730. Xstatic char CI[] = "ci";
  11731. Xstatic char CJ[] = "cj";
  11732. Xstatic char CK[] = "ck";
  11733. Xstatic char ZJ[] = "zj";
  11734. Xstatic char ZK[] = "zk";
  11735. X
  11736. X/* empty string */
  11737. Xstatic char ES[] = "";
  11738. X/* bailout defines */
  11739. X#define FTRIGBAILOUT 2500.0
  11740. X#define LTRIGBAILOUT   64.0
  11741. X#define FROTHBAILOUT    6.0
  11742. X#define STDBAILOUT    4.0
  11743. X#define NOBAILOUT    0.0
  11744. X
  11745. Xstruct moreparams far moreparams[] = 
  11746. X{
  11747. X    ICON,  omega,symdegree,ES,ES,ES,ES,0,3,0,0,0,0,
  11748. X    ICON3D,omega,symdegree,ES,ES,ES,ES,0,3,0,0,0,0,
  11749. X    HYPERCMPLXJFP,ZJ,ZK,   ES,ES,ES,ES,0,0,0,0,0,0,
  11750. X    QUATJULFP    ,ZJ,ZK,   ES,ES,ES,ES,0,0,0,0,0,0,   
  11751. X    -1,      NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,0,0
  11752. X};         
  11753. X
  11754. X
  11755. Xstruct fractalspecificstuff far fractalspecific[] =
  11756. X{
  11757. X   /*
  11758. X     fractal name, parameter text strings, parameter values,
  11759. X     helptext, helpformula, flags,
  11760. X     xmin  xmax  ymin  ymax int tojulia   tomandel tofloat  symmetry
  11761. X   |------|-----|-----|-----|--|--------|---------|--------|---------|
  11762. X     orbit fnct     per_pixel fnct  per_image fnct  calctype fcnt    bailout
  11763. X   |---------------|---------------|---------------|----------------|-------|
  11764. X   */
  11765. X
  11766. X   "mandel", realz0, imagz0,ES,ES,0,0,0,0,
  11767. X   HT_MANDEL, HF_MANDEL, WINFRAC,
  11768. X   -2.5,  1.5, -1.5,  1.5, 1, JULIA, NOFRACTAL, MANDELFP, XAXIS_NOPARM,
  11769. X   JuliaFractal, mandel_per_pixel,MandelSetup, StandardFractal, STDBAILOUT,
  11770. X
  11771. X   "julia", realparm, imagparm,ES,ES,0.3,0.6,0,0,
  11772. X   HT_JULIA, HF_JULIA, WINFRAC+OKJB,
  11773. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, MANDEL, JULIAFP,  ORIGIN,
  11774. X   JuliaFractal, julia_per_pixel, JuliaSetup, StandardFractal, STDBAILOUT,
  11775. X
  11776. X   "*newtbasin", newtdegree,stripes, ES,ES,3,0,0,0,
  11777. X   HT_NEWTBAS, HF_NEWTBAS, WINFRAC,
  11778. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, MPNEWTBASIN,   NOSYM,
  11779. X   NewtonFractal2, otherjuliafp_per_pixel,  NewtonSetup, StandardFractal,NOBAILOUT,
  11780. X
  11781. X   "lambda",      realparm, imagparm,ES,ES,0.85,0.6,0,0,
  11782. X   HT_LAMBDA, HF_LAMBDA, WINFRAC+OKJB,
  11783. X   -1.5,  2.5, -1.5,  1.5, 1, NOFRACTAL, MANDELLAMBDA, LAMBDAFP,  NOSYM,
  11784. X   LambdaFractal,   julia_per_pixel, JulialongSetup,  StandardFractal,STDBAILOUT,
  11785. X
  11786. X   "*mandel",    realz0, imagz0,ES,ES,0,0,0,0,
  11787. X   HT_MANDEL, HF_MANDEL, WINFRAC,
  11788. X   -2.5,  1.5, -1.5,  1.5, 0, JULIAFP,   NOFRACTAL, MANDEL,  XAXIS_NOPARM,
  11789. X   JuliafpFractal,mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT,
  11790. X
  11791. X   "*newton", newtdegree, ES, ES,ES,3,0,0,0,
  11792. X   HT_NEWT, HF_NEWT, WINFRAC,
  11793. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, MPNEWTON,    XAXIS,
  11794. X   NewtonFractal2, otherjuliafp_per_pixel,  NewtonSetup, StandardFractal,NOBAILOUT,
  11795. X
  11796. X   "*julia",     realparm, imagparm,ES,ES,0.3,0.6,0,0,
  11797. X   HT_JULIA, HF_JULIA, WINFRAC+OKJB,
  11798. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, MANDELFP, JULIA,  ORIGIN,
  11799. X   JuliafpFractal, juliafp_per_pixel,  JuliafpSetup, StandardFractal,STDBAILOUT,
  11800. X
  11801. X   "plasma",      "Graininess Factor (.1 to 50, default is 2)",
  11802. X                  "+Algorithm (0 = original, 1 = new)",
  11803. X                  "+Random Seed Value (0 = Random, 1 = Reuse Last)",
  11804. X                  "+Save as Pot File? (0 = No,     1 = Yes)",
  11805. X                  2,0,0,0,
  11806. X   HT_PLASMA, HF_PLASMA, NOZOOM+NOGUESS+NOTRACE+NORESUME+WINFRAC,
  11807. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  11808. X   NULL,       NULL,   StandaloneSetup,     plasma,      NOBAILOUT,
  11809. X
  11810. X   "*mandelfn",  realz0, imagz0,ES,ES,0,0,0,0,
  11811. X   HT_MANDFN, HF_MANDFN, TRIG1+WINFRAC,
  11812. X   -8.0,  8.0, -6.0,  6.0, 0, LAMBDATRIGFP,NOFRACTAL, MANDELTRIG, XYAXIS_NOPARM,
  11813. X   LambdaTrigfpFractal,othermandelfp_per_pixel,MandelTrigSetup,StandardFractal,LTRIGBAILOUT,
  11814. X
  11815. X   "*manowar",    realz0, imagz0,ES,ES,0,0,0,0,
  11816. X   HT_SCOTSKIN, HF_MANOWAR, WINFRAC,
  11817. X   -2.5,  1.5, -1.5,  1.5, 0, MANOWARJFP, NOFRACTAL, MANOWAR,  XAXIS_NOPARM,
  11818. X   ManOWarfpFractal,mandelfp_per_pixel, MandelfpSetup,StandardFractal,STDBAILOUT,
  11819. X
  11820. X   "manowar",    realz0, imagz0,ES,ES,0,0,0,0,
  11821. X   HT_SCOTSKIN, HF_MANOWAR, WINFRAC,
  11822. X   -2.5,  1.5, -1.5,  1.5, 1, MANOWARJ, NOFRACTAL, MANOWARFP, XAXIS_NOPARM,
  11823. X   ManOWarFractal,mandel_per_pixel, MandellongSetup,StandardFractal,STDBAILOUT,
  11824. X
  11825. X   "test","(testpt Param #1)","(testpt param #2)","(testpt param #3)","(testpt param #4)",0,0,0,0,
  11826. X   HT_TEST, HF_TEST, 0,
  11827. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  11828. X   NULL,      NULL,         StandaloneSetup, test,    STDBAILOUT,
  11829. X
  11830. X   "sierpinski",  ES,ES,ES,ES,0,0,0,0,
  11831. X   HT_SIER, HF_SIER, WINFRAC,
  11832. X   -0.9,  1.7, -0.9,  1.7, 1, NOFRACTAL, NOFRACTAL, SIERPINSKIFP,   NOSYM,
  11833. X   SierpinskiFractal,long_julia_per_pixel, SierpinskiSetup,StandardFractal,127.0,
  11834. X
  11835. X   "barnsleym1",  realz0, imagz0,ES,ES,0,0,0,0,
  11836. X   HT_BARNS, HF_BARNSM1, WINFRAC,
  11837. X   -2.0,  2.0, -1.5,  1.5, 1, BARNSLEYJ1,NOFRACTAL, BARNSLEYM1FP,  XYAXIS_NOPARM,
  11838. X   Barnsley1Fractal,long_mandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  11839. X
  11840. X   "barnsleyj1",  realparm, imagparm,ES,ES,0.6,1.1,0,0,
  11841. X   HT_BARNS, HF_BARNSJ1, WINFRAC+OKJB,
  11842. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, BARNSLEYM1, BARNSLEYJ1FP,  ORIGIN,
  11843. X   Barnsley1Fractal,long_julia_per_pixel,JulialongSetup,StandardFractal,STDBAILOUT,
  11844. X
  11845. X   "barnsleym2",  realz0, imagz0,ES,ES,0,0,0,0,
  11846. X   HT_BARNS, HF_BARNSM2, WINFRAC,
  11847. X   -2.0,  2.0, -1.5,  1.5, 1, BARNSLEYJ2,NOFRACTAL, BARNSLEYM2FP,  YAXIS_NOPARM,
  11848. X   Barnsley2Fractal,long_mandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  11849. X
  11850. X   "barnsleyj2",  realparm, imagparm,ES,ES,0.6,1.1,0,0,
  11851. X   HT_BARNS, HF_BARNSJ2, WINFRAC+OKJB,
  11852. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, BARNSLEYM2, BARNSLEYJ2FP,  ORIGIN,
  11853. X   Barnsley2Fractal,long_julia_per_pixel,JulialongSetup,StandardFractal,STDBAILOUT,
  11854. X
  11855. X   "sqr(fn)", ES,ES,ES,ES,0,0,0,0,
  11856. X   HT_SCOTSKIN, HF_SQRFN, TRIG1+WINFRAC,
  11857. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, NOFRACTAL, SQRTRIGFP,XAXIS,
  11858. X   SqrTrigFractal,   long_julia_per_pixel, SqrTrigSetup,  StandardFractal,LTRIGBAILOUT,
  11859. X
  11860. X   "*sqr(fn)", ES,ES,ES,ES,0,0,0,0,
  11861. X   HT_SCOTSKIN, HF_SQRFN, TRIG1+WINFRAC,
  11862. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, NOFRACTAL, SQRTRIG,XAXIS,
  11863. X   SqrTrigfpFractal,   otherjuliafp_per_pixel, SqrTrigSetup,  StandardFractal,LTRIGBAILOUT,
  11864. X
  11865. X   "fn+fn", recoeftrg1, imcoeftrg1,recoeftrg2, imcoeftrg2,1,0,1,0,
  11866. X   HT_SCOTSKIN, HF_FNPLUSFN, TRIG2+WINFRAC,
  11867. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, NOFRACTAL, TRIGPLUSTRIGFP,XAXIS,
  11868. X   TrigPlusTrigFractal,   long_julia_per_pixel, TrigPlusTriglongSetup,    StandardFractal,LTRIGBAILOUT,
  11869. X
  11870. X   "mandellambda",realz0, imagz0,ES,ES,0,0,0,0,
  11871. X   HT_MLAMBDA, HF_MLAMBDA, WINFRAC,
  11872. X   -3.0,  5.0, -3.0,  3.0, 1, LAMBDA,     NOFRACTAL, MANDELLAMBDAFP,  XAXIS_NOPARM,
  11873. X   LambdaFractal,mandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  11874. X
  11875. X   "marksmandel", realz0, imagz0, exponent,ES,0,0,1,0,
  11876. X   HT_MARKS, HF_MARKSMAND, WINFRAC,
  11877. X   -2.0,  2.0, -1.5,  1.5, 1, MARKSJULIA, NOFRACTAL, MARKSMANDELFP,  NOSYM,
  11878. X   MarksLambdaFractal,marksmandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  11879. X
  11880. X   "marksjulia", realparm, imagparm, exponent,ES,0.1,0.9,0,0,
  11881. X   HT_MARKS, HF_MARKSJULIA, WINFRAC,
  11882. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, MARKSMANDEL, MARKSJULIAFP,   ORIGIN,
  11883. X   MarksLambdaFractal,julia_per_pixel,MarksJuliaSetup,StandardFractal,STDBAILOUT,
  11884. X
  11885. X   "unity", ES,ES,ES,ES,0,0,0,0,
  11886. X   HT_UNITY, HF_UNITY, WINFRAC,
  11887. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, NOFRACTAL, UNITYFP,   XYAXIS,
  11888. X   UnityFractal, long_julia_per_pixel,UnitySetup,StandardFractal,NOBAILOUT,
  11889. X
  11890. X   "mandel4", realz0, imagz0,ES,ES,0,0,0,0,
  11891. X   HT_MANDJUL4, HF_MANDEL4, WINFRAC,
  11892. X   -2.0,  2.0, -1.5,  1.5, 1, JULIA4,      NOFRACTAL, MANDEL4FP,  XAXIS_NOPARM,
  11893. X   Mandel4Fractal,  mandel_per_pixel, MandellongSetup, StandardFractal,  STDBAILOUT,
  11894. X
  11895. X   "julia4", realparm, imagparm,ES,ES,0.6,0.55,0,0,
  11896. X   HT_MANDJUL4, HF_JULIA4, WINFRAC+OKJB,
  11897. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, MANDEL4, JULIA4FP, ORIGIN,
  11898. X   Mandel4Fractal,   julia_per_pixel, JulialongSetup,StandardFractal,     STDBAILOUT,
  11899. X
  11900. X   "ifs",color_method,ES,ES,ES,0,0,0,0,
  11901. X   HT_IFS, -1, NOGUESS+NOTRACE+NORESUME+WINFRAC,
  11902. X   -8.0,  8.0, -1.0, 11.0, 16, NOFRACTAL, NOFRACTAL, NOFRACTAL,  NOSYM,
  11903. X   NULL,      NULL,      StandaloneSetup, ifs,    NOBAILOUT,
  11904. X
  11905. X   "*ifs3d",color_method,ES,ES,ES,0,0,0,0,
  11906. X   HT_IFS, -1, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  11907. X   -11.0,  11.0, -11.0, 11.0, 16, NOFRACTAL, NOFRACTAL, NOFRACTAL,   NOSYM,
  11908. X   NULL,      NULL,      StandaloneSetup, ifs,    NOBAILOUT,
  11909. X
  11910. X   "barnsleym3",  realz0, imagz0,ES,ES,0,0,0,0,
  11911. X   HT_BARNS, HF_BARNSM3, WINFRAC,
  11912. X   -2.0,  2.0, -1.5,  1.5, 1, BARNSLEYJ3,NOFRACTAL, BARNSLEYM3FP,  XAXIS_NOPARM,
  11913. X   Barnsley3Fractal,long_mandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  11914. X
  11915. X   "barnsleyj3",  realparm, imagparm,ES,ES,0.1,0.36,0,0,
  11916. X   HT_BARNS, HF_BARNSJ3, WINFRAC+OKJB,
  11917. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, BARNSLEYM3, BARNSLEYJ3FP,  NOSYM,
  11918. X   Barnsley3Fractal,long_julia_per_pixel,JulialongSetup,StandardFractal,STDBAILOUT,
  11919. X
  11920. X   "fn(z*z)", ES,ES,ES,ES,0,0,0,0,
  11921. X   HT_SCOTSKIN, HF_FNZTIMESZ, TRIG1+WINFRAC,
  11922. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, NOFRACTAL, TRIGSQRFP,XYAXIS,
  11923. X   TrigZsqrdFractal,   julia_per_pixel, JulialongSetup,  StandardFractal,STDBAILOUT,
  11924. X
  11925. X   "*fn(z*z)", ES,ES,ES,ES,0,0,0,0,
  11926. X   HT_SCOTSKIN, HF_FNZTIMESZ, TRIG1+WINFRAC,
  11927. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, NOFRACTAL, TRIGSQR,XYAXIS,
  11928. X   TrigZsqrdfpFractal,     juliafp_per_pixel, JuliafpSetup,  StandardFractal,STDBAILOUT,
  11929. X
  11930. X   "*bifurcation",filt,seed,ES,ES,1000.0,0.66,0,0,
  11931. X   HT_BIF, HF_BIFURCATION, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  11932. X   1.9,  3.0, 0,  1.34, 0, NOFRACTAL, NOFRACTAL, LBIFURCATION, NOSYM,
  11933. X   BifurcVerhulstTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  11934. X
  11935. X   "*fn+fn",recoeftrg1,imcoeftrg1,recoeftrg2,imcoeftrg2,1,0,1,0,
  11936. X   HT_SCOTSKIN, HF_FNPLUSFN, TRIG2+WINFRAC,
  11937. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, NOFRACTAL, TRIGPLUSTRIG,XAXIS,
  11938. X   TrigPlusTrigfpFractal, otherjuliafp_per_pixel, TrigPlusTrigfpSetup,    StandardFractal,LTRIGBAILOUT,
  11939. X
  11940. X   "fn*fn", ES,ES,ES,ES,0,0,0,0,
  11941. X   HT_SCOTSKIN, HF_FNTIMESFN, TRIG2+WINFRAC,
  11942. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, NOFRACTAL, TRIGXTRIGFP,XAXIS,
  11943. X   TrigXTrigFractal, long_julia_per_pixel, FnXFnSetup,    StandardFractal,LTRIGBAILOUT,
  11944. X
  11945. X   "*fn*fn", ES,ES,ES,ES,0,0,0,0,
  11946. X   HT_SCOTSKIN, HF_FNTIMESFN, TRIG2+WINFRAC,
  11947. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, NOFRACTAL, TRIGXTRIG,XAXIS,
  11948. X   TrigXTrigfpFractal, otherjuliafp_per_pixel, FnXFnSetup,  StandardFractal,LTRIGBAILOUT,
  11949. X
  11950. X   "sqr(1/fn)",ES,ES,ES,ES,0,0,0,0,
  11951. X   HT_SCOTSKIN, HF_SQROVFN, TRIG1+WINFRAC,
  11952. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, NOFRACTAL, SQR1OVERTRIGFP,NOSYM,
  11953. X   Sqr1overTrigFractal, long_julia_per_pixel, SqrTrigSetup,  StandardFractal,LTRIGBAILOUT,
  11954. X
  11955. X   "*sqr(1/fn)",ES,ES,ES,ES,0,0,0,0,
  11956. X   HT_SCOTSKIN, HF_SQROVFN, TRIG1+WINFRAC,
  11957. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, NOFRACTAL, SQR1OVERTRIG,NOSYM,
  11958. X   Sqr1overTrigfpFractal, otherjuliafp_per_pixel, SqrTrigSetup,  StandardFractal,LTRIGBAILOUT,
  11959. X
  11960. X   "fn*z+z",recoeftrg1, imcoeftrg1, recoef2nd,imcoef2nd,1,0,1,0,
  11961. X   HT_SCOTSKIN, HF_FNXZPLUSZ, TRIG1+WINFRAC,
  11962. X   -4.0,  4.0, -3.0,  3.0, 1, NOFRACTAL, NOFRACTAL, ZXTRIGPLUSZFP,XAXIS,
  11963. X   ZXTrigPlusZFractal,julia_per_pixel,ZXTrigPlusZSetup,  StandardFractal,LTRIGBAILOUT,
  11964. X
  11965. X   "*fn*z+z",recoeftrg1, imcoeftrg2, recoef2nd,imcoef2nd,1,0,1,0,
  11966. X   HT_SCOTSKIN, HF_FNXZPLUSZ, TRIG1+WINFRAC,
  11967. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, NOFRACTAL, ZXTRIGPLUSZ,XAXIS,
  11968. X   ZXTrigPlusZfpFractal,   juliafp_per_pixel, ZXTrigPlusZSetup,  StandardFractal,LTRIGBAILOUT,
  11969. X
  11970. X   "*kamtorus",kamangle,kamstep,kamstop,pointsperorbit,1.3,.05,1.5,150,
  11971. X   HT_KAM, HF_KAM, NOGUESS+NOTRACE+WINFRAC,
  11972. X   -1.0,  1.0, -.75, .75, 0, NOFRACTAL, NOFRACTAL, KAM,   NOSYM,
  11973. X   kamtorusfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat, NOBAILOUT,
  11974. X
  11975. X   "kamtorus",kamangle,kamstep,kamstop,pointsperorbit,1.3,.05,1.5,150,
  11976. X   HT_KAM, HF_KAM, NOGUESS+NOTRACE+WINFRAC,
  11977. X   -1.0,  1.0, -.75, .75,16, NOFRACTAL, NOFRACTAL, KAMFP, NOSYM,
  11978. X   kamtoruslongorbit,  NULL, orbit3dlongsetup, orbit2dlong,   NOBAILOUT,
  11979. X
  11980. X   "*kamtorus3d",kamangle,kamstep,kamstop,pointsperorbit,1.3,.05,1.5,150,
  11981. X   HT_KAM, HF_KAM, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  11982. X   -3.0,  3.0, -1, 3.5, 0, NOFRACTAL, NOFRACTAL, KAM3D,   NOSYM,
  11983. X   kamtorusfloatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT,
  11984. X
  11985. X   "kamtorus3d",kamangle,kamstep,kamstop,pointsperorbit,1.3,.05,1.5,150,
  11986. X   HT_KAM, HF_KAM, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  11987. X   -3.0,  3.0, -1, 3.5,16, NOFRACTAL, NOFRACTAL, KAM3DFP, NOSYM,
  11988. X   kamtoruslongorbit,  NULL, orbit3dlongsetup, orbit3dlong,   NOBAILOUT,
  11989. X
  11990. X   "lambdafn",     realparm, imagparm,ES,ES,1.0,0.4,0,0,
  11991. X   HT_LAMBDAFN, HF_LAMBDAFN, TRIG1+WINFRAC+OKJB,
  11992. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, MANDELTRIG, LAMBDATRIGFP,PI_SYM,
  11993. X   LambdaTrigFractal,long_julia_per_pixel, LambdaTrigSetup,    StandardFractal,LTRIGBAILOUT,
  11994. X
  11995. X   "manfn+zsqrd",  realz0, imagz0,ES,ES,0,0,0,0,
  11996. X   HT_PICKMJ, HF_MANDFNPLUSZSQRD, TRIG1+WINFRAC,
  11997. X   -2.5,  1.5, -1.5,  1.5, 16, LJULTRIGPLUSZSQRD,  NOFRACTAL, FPMANTRIGPLUSZSQRD, XAXIS_NOPARM,
  11998. X   TrigPlusZsquaredFractal,mandel_per_pixel,MandellongSetup,StandardFractal, STDBAILOUT,
  11999. X
  12000. X   "julfn+zsqrd",  realparm, imagparm,ES,ES,-0.5,0.5,0,0,
  12001. X   HT_PICKMJ, HF_JULFNPLUSZSQRD, TRIG1+WINFRAC+OKJB,
  12002. X   -2.0,  2.0, -1.5,  1.5, 16, NOFRACTAL, LMANTRIGPLUSZSQRD, FPJULTRIGPLUSZSQRD,    NOSYM,
  12003. X   TrigPlusZsquaredFractal,julia_per_pixel, JuliafnPlusZsqrdSetup,StandardFractal, STDBAILOUT,
  12004. X
  12005. X   "*manfn+zsqrd", realz0, imagz0,ES,ES,0,0,0,0,
  12006. X   HT_PICKMJ, HF_MANDFNPLUSZSQRD, TRIG1+WINFRAC,
  12007. X   -2.5,  1.5, -1.5,  1.5, 0, FPJULTRIGPLUSZSQRD,   NOFRACTAL, LMANTRIGPLUSZSQRD, XAXIS_NOPARM,
  12008. X   TrigPlusZsquaredfpFractal,mandelfp_per_pixel, MandelfpSetup,StandardFractal, STDBAILOUT,
  12009. X
  12010. X   "*julfn+zsqrd", realparm, imagparm,ES,ES,-0.5,0.5,0,0,
  12011. X   HT_PICKMJ, HF_JULFNPLUSZSQRD, TRIG1+WINFRAC+OKJB,
  12012. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, FPMANTRIGPLUSZSQRD, LJULTRIGPLUSZSQRD, NOSYM,
  12013. X   TrigPlusZsquaredfpFractal, juliafp_per_pixel,  JuliafnPlusZsqrdSetup,StandardFractal, STDBAILOUT,
  12014. X
  12015. X   "*lambdafn",  realparm, imagparm,ES,ES,1.0,0.4,0,0,
  12016. X   HT_LAMBDAFN, HF_LAMBDAFN, TRIG1+WINFRAC+OKJB,
  12017. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, MANDELTRIGFP, LAMBDATRIG, PI_SYM,
  12018. X   LambdaTrigfpFractal,otherjuliafp_per_pixel,LambdaTrigSetup,StandardFractal,LTRIGBAILOUT,
  12019. X
  12020. X   "mandelfn",realz0, imagz0,ES,ES, 0,0,0,0,
  12021. X   HT_MANDFN, HF_MANDFN, TRIG1+WINFRAC,
  12022. X   -8.0,  8.0, -6.0,  6.0, 16, LAMBDATRIG, NOFRACTAL, MANDELTRIGFP, XYAXIS_NOPARM,
  12023. X   LambdaTrigFractal,long_mandel_per_pixel,MandelTrigSetup,StandardFractal,LTRIGBAILOUT,
  12024. X
  12025. X   "manzpower", realz0, imagz0, exponent,imexponent,0,0,2,0,
  12026. X   HT_PICKMJ, HF_MANZPOWER, WINFRAC,
  12027. X   -2.0,  2.0, -1.5,  1.5, 1, LJULIAZPOWER, NOFRACTAL, FPMANDELZPOWER,    XAXIS_NOIMAG,
  12028. X   longZpowerFractal,long_mandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  12029. X
  12030. X   "julzpower", realparm, imagparm, exponent,imexponent,0.3,0.6,2,0,
  12031. X   HT_PICKMJ, HF_JULZPOWER, WINFRAC+OKJB,
  12032. X   -2.0,  2.0, -1.5,  1.5, 1, NOFRACTAL, LMANDELZPOWER, FPJULIAZPOWER,     ORIGIN,
  12033. X   longZpowerFractal,long_julia_per_pixel,JulialongSetup,StandardFractal,STDBAILOUT,
  12034. X
  12035. X   "*manzpower", realz0, imagz0, exponent,imexponent,0,0,2,0,
  12036. X   HT_PICKMJ, HF_MANZPOWER, WINFRAC,
  12037. X   -2.5,  1.5, -1.5,  1.5, 0, FPJULIAZPOWER,   NOFRACTAL, LMANDELZPOWER,  XAXIS_NOIMAG,
  12038. X   floatZpowerFractal,othermandelfp_per_pixel, MandelfpSetup,StandardFractal,STDBAILOUT,
  12039. X
  12040. X   "*julzpower", realparm, imagparm, exponent,imexponent,0.3,0.6,2,0,
  12041. X   HT_PICKMJ, HF_JULZPOWER, WINFRAC+OKJB,
  12042. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, FPMANDELZPOWER, LJULIAZPOWER,    ORIGIN,
  12043. X   floatZpowerFractal, otherjuliafp_per_pixel,    JuliafpSetup,StandardFractal,STDBAILOUT,
  12044. X
  12045. X   "manzzpwr", realz0, imagz0, exponent,ES,0,0,2,0,
  12046. X   HT_PICKMJ, HF_MANZZPWR, WINFRAC,
  12047. X   -2.5,  1.5, -1.5,  1.5, 0, FPJULZTOZPLUSZPWR,   NOFRACTAL, NOFRACTAL,  XAXIS_NOPARM,
  12048. X   floatZtozPluszpwrFractal,othermandelfp_per_pixel, MandelfpSetup,StandardFractal,STDBAILOUT,
  12049. X
  12050. X   "julzzpwr", realparm, imagparm, exponent,ES,-0.3,0.3,2,0,
  12051. X   HT_PICKMJ, HF_JULZZPWR, WINFRAC+OKJB,
  12052. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, FPMANZTOZPLUSZPWR, NOFRACTAL,    NOSYM,
  12053. X   floatZtozPluszpwrFractal, otherjuliafp_per_pixel,  JuliafpSetup,StandardFractal,STDBAILOUT,
  12054. X
  12055. X   "manfn+exp",realz0, imagz0,ES,ES,0,0,0,0,
  12056. X   HT_PICKMJ, HF_MANDFNPLUSEXP, TRIG1+WINFRAC,
  12057. X   -8.0,  8.0, -6.0,  6.0, 16, LJULTRIGPLUSEXP,    NOFRACTAL,  FPMANTRIGPLUSEXP, XAXIS_NOPARM,
  12058. X   LongTrigPlusExponentFractal,long_mandel_per_pixel,MandellongSetup,StandardFractal,STDBAILOUT,
  12059. X
  12060. X   "julfn+exp", realparm, imagparm,ES,ES,0,0,0,0,
  12061. X   HT_PICKMJ, HF_JULFNPLUSEXP, TRIG1+WINFRAC+OKJB,
  12062. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, LMANTRIGPLUSEXP,FPJULTRIGPLUSEXP, NOSYM,
  12063. X   LongTrigPlusExponentFractal,   long_julia_per_pixel, JulialongSetup,  StandardFractal,STDBAILOUT,
  12064. X
  12065. X   "*manfn+exp", realz0, imagz0,ES,ES,0,0,0,0,
  12066. X   HT_PICKMJ, HF_MANDFNPLUSEXP, TRIG1+WINFRAC,
  12067. X   -8.0,  8.0, -6.0,  6.0, 0, FPJULTRIGPLUSEXP, NOFRACTAL, LMANTRIGPLUSEXP,   XAXIS_NOPARM,
  12068. X   FloatTrigPlusExponentFractal,othermandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12069. X
  12070. X   "*julfn+exp", realparm, imagparm,ES,ES,0,0,0,0,
  12071. X   HT_PICKMJ, HF_JULFNPLUSEXP, TRIG1+WINFRAC+OKJB,
  12072. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, FPMANTRIGPLUSEXP, LJULTRIGPLUSEXP,   NOSYM,
  12073. X   FloatTrigPlusExponentFractal,otherjuliafp_per_pixel,JuliafpSetup,StandardFractal,STDBAILOUT,
  12074. X
  12075. X   "*popcorn", step, ES, ES,ES,0.05,0,0,0,
  12076. X   HT_POPCORN, HF_POPCORN, NOGUESS+NOTRACE+WINFRAC,
  12077. X   -3.0,  3.0, -2.2,  2.2, 0, NOFRACTAL, NOFRACTAL, LPOPCORN,  NOPLOT,
  12078. X   PopcornFractal, otherjuliafp_per_pixel,  JuliafpSetup,  popcorn,STDBAILOUT,
  12079. X
  12080. X   "popcorn", step, ES, ES,ES,0.05,0,0,0,
  12081. X   HT_POPCORN, HF_POPCORN, NOGUESS+NOTRACE+WINFRAC,
  12082. X   -3.0,  3.0, -2.2,  2.2, 16, NOFRACTAL, NOFRACTAL, FPPOPCORN,  NOPLOT,
  12083. X   LPopcornFractal,   long_julia_per_pixel, JulialongSetup,popcorn,STDBAILOUT,
  12084. X
  12085. X   "*lorenz",timestep,A,B, C,.02,5,15,1,
  12086. X   HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12087. X   -15,  15, 0, 30, 0, NOFRACTAL, NOFRACTAL, LLORENZ,   NOSYM,
  12088. X   lorenz3dfloatorbit, NULL,         orbit3dfloatsetup, orbit2dfloat,     NOBAILOUT,
  12089. X
  12090. X   "lorenz",timestep,A,B, C,.02,5,15,1,
  12091. X   HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12092. X   -15,  15, 0, 30, 16, NOFRACTAL, NOFRACTAL, FPLORENZ,   NOSYM,
  12093. X   lorenz3dlongorbit, NULL,        orbit3dlongsetup, orbit2dlong,    NOBAILOUT,
  12094. X
  12095. X   "lorenz3d",timestep,A,B, C,.02,5,15,1,
  12096. X   HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12097. X   -30.0,  30.0,  -30.0,   30.0, 16, NOFRACTAL, NOFRACTAL, FPLORENZ3D,   NOSYM,
  12098. X   lorenz3dlongorbit, NULL,        orbit3dlongsetup, orbit3dlong,    NOBAILOUT,
  12099. X
  12100. X   "newton", newtdegree,ES, ES,ES,3,0,0,0,
  12101. X   HT_NEWT, HF_NEWT, WINFRAC,
  12102. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NEWTON,   XAXIS,
  12103. X   MPCNewtonFractal, MPCjulia_per_pixel,  NewtonSetup, StandardFractal,NOBAILOUT,
  12104. X
  12105. X   "newtbasin", newtdegree,stripes, ES,ES,3,0,0,0,
  12106. X   HT_NEWTBAS, HF_NEWTBAS, WINFRAC,
  12107. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NEWTBASIN,     NOSYM,
  12108. X   MPCNewtonFractal, MPCjulia_per_pixel,  NewtonSetup, StandardFractal,NOBAILOUT,
  12109. X
  12110. X   "complexnewton", realdegree,imagdegree,realroot,imagroot,3,0,1,0,
  12111. X   HT_NEWTCMPLX, HF_COMPLEXNEWT, WINFRAC,
  12112. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  12113. X   ComplexNewton, otherjuliafp_per_pixel,  ComplexNewtonSetup, StandardFractal,NOBAILOUT,
  12114. X
  12115. X   "complexbasin", realdegree,imagdegree,realroot,imagroot,3,0,1,0,
  12116. X   HT_NEWTCMPLX, HF_COMPLEXNEWT, WINFRAC,
  12117. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  12118. X   ComplexBasin, otherjuliafp_per_pixel,  ComplexNewtonSetup,  StandardFractal, NOBAILOUT,
  12119. X
  12120. X   "cmplxmarksmand", realz0, imagz0, realdegree, imagdegree,0,0,1,0,
  12121. X   HT_MARKS, HF_CMPLXMARKSMAND, WINFRAC,
  12122. X   -2.0,  2.0, -1.5,  1.5, 0, COMPLEXMARKSJUL, NOFRACTAL, NOFRACTAL,   NOSYM,
  12123. X   MarksCplxMand, MarksCplxMandperp, MandelfpSetup, StandardFractal, STDBAILOUT,
  12124. X
  12125. X   "cmplxmarksjul", realparm, imagparm, realdegree, imagdegree,0.3,0.6,1,0,
  12126. X   HT_MARKS, HF_CMPLXMARKSJUL, WINFRAC,
  12127. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, COMPLEXMARKSMAND, NOFRACTAL,    NOSYM,
  12128. X   MarksCplxMand, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT,
  12129. X
  12130. X   "formula", p1real, p1imag, p2real, p2imag, 0,0,0,0,
  12131. X   HT_FORMULA, -2, WINFRAC,
  12132. X   -2.0, 2.0, -1.5, 1.5, 1, NOFRACTAL, NOFRACTAL, FFORMULA, SETUP_SYM,
  12133. X   Formula, form_per_pixel, intFormulaSetup, StandardFractal, 0,
  12134. X
  12135. X   "*formula", p1real, p1imag, p2real, p2imag, 0,0,0,0,
  12136. X   HT_FORMULA, -2, WINFRAC,
  12137. X   -2.0, 2.0, -1.5, 1.5, 0, NOFRACTAL, NOFRACTAL, FORMULA, SETUP_SYM,
  12138. X   Formula, form_per_pixel, fpFormulaSetup, StandardFractal, 0,
  12139. X
  12140. X   "*sierpinski",  ES,ES,ES,ES,0,0,0,0,
  12141. X   HT_SIER, HF_SIER, WINFRAC,
  12142. X   -0.9,  1.7, -0.9,  1.7, 0, NOFRACTAL, NOFRACTAL, SIERPINSKI,   NOSYM,
  12143. X   SierpinskiFPFractal, otherjuliafp_per_pixel, SierpinskiFPSetup,StandardFractal,127.0,
  12144. X
  12145. X   "*lambda", realparm, imagparm,ES,ES,0.85,0.6,0,0,
  12146. X   HT_LAMBDA, HF_LAMBDA, WINFRAC+OKJB,
  12147. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, MANDELLAMBDAFP, LAMBDA,  NOSYM,
  12148. X   LambdaFPFractal,   juliafp_per_pixel, JuliafpSetup,    StandardFractal,STDBAILOUT,
  12149. X
  12150. X   "*barnsleym1", realz0, imagz0,ES,ES,0,0,0,0,
  12151. X   HT_BARNS, HF_BARNSM1, WINFRAC,
  12152. X   -2.0,  2.0, -1.5,  1.5, 0, BARNSLEYJ1FP,NOFRACTAL, BARNSLEYM1,  XYAXIS_NOPARM,
  12153. X   Barnsley1FPFractal, othermandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12154. X
  12155. X   "*barnsleyj1", realparm, imagparm,ES,ES,0.6,1.1,0,0,
  12156. X   HT_BARNS, HF_BARNSJ1, WINFRAC+OKJB,
  12157. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, BARNSLEYM1FP, BARNSLEYJ1,  ORIGIN,
  12158. X   Barnsley1FPFractal, otherjuliafp_per_pixel,JuliafpSetup,StandardFractal,STDBAILOUT,
  12159. X
  12160. X   "*barnsleym2", realz0, imagz0,ES,ES,0,0,0,0,
  12161. X   HT_BARNS, HF_BARNSM2, WINFRAC,
  12162. X   -2.0,  2.0, -1.5,  1.5, 0, BARNSLEYJ2FP,NOFRACTAL, BARNSLEYM2,  YAXIS_NOPARM,
  12163. X   Barnsley2FPFractal,othermandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12164. X
  12165. X   "*barnsleyj2", realparm, imagparm,ES,ES,0.6,1.1,0,0,
  12166. X   HT_BARNS, HF_BARNSJ2, WINFRAC+OKJB,
  12167. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, BARNSLEYM2FP, BARNSLEYJ2,  ORIGIN,
  12168. X   Barnsley2FPFractal,otherjuliafp_per_pixel,JuliafpSetup,StandardFractal,STDBAILOUT,
  12169. X
  12170. X   "*barnsleym3", realz0, imagz0,ES,ES,0,0,0,0,
  12171. X   HT_BARNS, HF_BARNSM3, WINFRAC,
  12172. X   -2.0,  2.0, -1.5,  1.5, 0, BARNSLEYJ3FP, NOFRACTAL, BARNSLEYM3,  XAXIS_NOPARM,
  12173. X   Barnsley3FPFractal,othermandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12174. X
  12175. X   "*barnsleyj3", realparm, imagparm,ES,ES,0.6,1.1,0,0,
  12176. X   HT_BARNS, HF_BARNSJ3, WINFRAC+OKJB,
  12177. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, BARNSLEYM3FP, BARNSLEYJ3,  XAXIS,
  12178. X   Barnsley3FPFractal,otherjuliafp_per_pixel,JuliafpSetup,StandardFractal,STDBAILOUT,
  12179. X
  12180. X   "*mandellambda",realz0, imagz0,ES,ES,0,0,0,0,
  12181. X   HT_MLAMBDA, HF_MLAMBDA, WINFRAC,
  12182. X   -3.0,  5.0, -3.0,  3.0, 0, LAMBDAFP, NOFRACTAL, MANDELLAMBDA,  XAXIS_NOPARM,
  12183. X   LambdaFPFractal,mandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12184. X
  12185. X   "julibrot", ES,ES,ES,ES,0,0,0,0,
  12186. X   HT_JULIBROT, -1, NOGUESS+NOTRACE+NOROTATE+NORESUME+WINFRAC,
  12187. X   -2.0, 2.0, -1.5, 1.5, 1, NOFRACTAL, NOFRACTAL, JULIBROTFP, NOSYM,
  12188. X   JuliaFractal, jb_per_pixel, JulibrotSetup, Std4dFractal, STDBAILOUT,
  12189. X
  12190. X   "*lorenz3d",timestep,A,B,C,.02,5,15,1,
  12191. X   HT_LORENZ, HF_LORENZ, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12192. X   -30.0,  30.0,  -30.0,   30.0, 0, NOFRACTAL, NOFRACTAL, LLORENZ3D,   NOSYM,
  12193. X   lorenz3dfloatorbit, NULL,         orbit3dfloatsetup, orbit3dfloat,     NOBAILOUT,
  12194. X
  12195. X   "rossler3d",timestep,A,B,C,.04,.2,.2,5.7,
  12196. X   HT_ROSS, HF_ROSS, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12197. X   -30.0,  30.0,  -20.0,   40.0, 16, NOFRACTAL, NOFRACTAL, FPROSSLER,    NOSYM,
  12198. X   rosslerlongorbit, NULL,       orbit3dlongsetup, orbit3dlong,    NOBAILOUT,
  12199. X
  12200. X   "*rossler3d",timestep,A,B,C,.04,.2,.2,5.7,
  12201. X   HT_ROSS, HF_ROSS, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12202. X   -30.0,  30.0,  -20.0,   40.0, 0, NOFRACTAL, NOFRACTAL, LROSSLER,   NOSYM,
  12203. X   rosslerfloatorbit, NULL,        orbit3dfloatsetup, orbit3dfloat,    NOBAILOUT,
  12204. X
  12205. X   "henon",A,B,ES,ES,1.4,.3,0,0,
  12206. X   HT_HENON, HF_HENON, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12207. X   -1.4,  1.4,    -.5,   .5, 16, NOFRACTAL, NOFRACTAL, FPHENON,    NOSYM,
  12208. X   henonlongorbit, NULL,     orbit3dlongsetup, orbit2dlong,    NOBAILOUT,
  12209. X
  12210. X   "*henon",A,B,ES,ES,1.4,.3,0,0,
  12211. X   HT_HENON, HF_HENON, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12212. X   -1.4,  1.4,    -.5,   .5, 0, NOFRACTAL, NOFRACTAL, LHENON,   NOSYM,
  12213. X   henonfloatorbit, NULL,      orbit3dfloatsetup, orbit2dfloat,    NOBAILOUT,
  12214. X
  12215. X   "pickover",A,B,C,D,2.24,.43,-.65,-2.43,
  12216. X   HT_PICK, HF_PICKOVER, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12217. X   -2.8,  2.8,    -2.0, 2.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  12218. X   pickoverfloatorbit, NULL,         orbit3dfloatsetup, orbit3dfloat,     NOBAILOUT,
  12219. X
  12220. X   "gingerbreadman",initx,inity,ES,ES,-.1,0,0,0,
  12221. X   HT_GINGER, HF_GINGER, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12222. X   -4.5,  8.5,    -4.5, 8.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  12223. X   gingerbreadfloatorbit, NULL, orbit3dfloatsetup, orbit2dfloat,    NOBAILOUT,
  12224. X
  12225. X   "diffusion", "+Border size","+Type (0=Central,1=Falling,2=Square Cavity)",ES, ES,10,0,0,0,
  12226. X   HT_DIFFUS, HF_DIFFUS, NOZOOM+NOGUESS+NOTRACE+WINFRAC,
  12227. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,     NOSYM,
  12228. X   NULL,   NULL,     StandaloneSetup, diffusion,    NOBAILOUT,
  12229. X
  12230. X   "*unity", ES,ES,ES,ES,0,0,0,0,
  12231. X   HT_UNITY, HF_UNITY, WINFRAC,
  12232. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, UNITY,   XYAXIS,
  12233. X   UnityfpFractal, otherjuliafp_per_pixel,StandardSetup,StandardFractal,NOBAILOUT,
  12234. X
  12235. X   "*spider", realz0, imagz0,ES,ES,0,0,0,0,
  12236. X   HT_SCOTSKIN, HF_SPIDER, WINFRAC,
  12237. X   -2.5,  1.5, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, SPIDER,  XAXIS_NOPARM,
  12238. X   SpiderfpFractal,mandelfp_per_pixel, MandelfpSetup,StandardFractal,STDBAILOUT,
  12239. X
  12240. X   "spider",  realz0, imagz0,ES,ES,0,0,0,0,
  12241. X   HT_SCOTSKIN, HF_SPIDER, WINFRAC,
  12242. X   -2.5,  1.5, -1.5,  1.5, 1, NOFRACTAL, NOFRACTAL, SPIDERFP,  XAXIS_NOPARM,
  12243. X   SpiderFractal,mandel_per_pixel, MandellongSetup,StandardFractal,STDBAILOUT,
  12244. X
  12245. X   "tetrate", realz0, imagz0,ES,ES,0,0,0,0,
  12246. X   HT_SCOTSKIN, HF_TETRATE, WINFRAC,
  12247. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,    XAXIS,
  12248. X   TetratefpFractal,othermandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12249. X
  12250. X   "magnet1m", realz0, imagz0,ES,ES,0,0,0,0,
  12251. X   HT_MAGNET, HF_MAGM1, WINFRAC,
  12252. X   -4.0, 4.0, -3.0, 3.0, 0, MAGNET1J,NOFRACTAL,NOFRACTAL, XAXIS_NOPARM,
  12253. X   Magnet1Fractal,mandelfp_per_pixel,MandelfpSetup,StandardFractal,100.0,
  12254. X
  12255. X   "magnet1j", realparm, imagparm,ES,ES,0,0,0,0,
  12256. X   HT_MAGNET, HF_MAGJ1, WINFRAC,
  12257. X   -8.0,  8.0, -6.0,  6.0, 0, NOFRACTAL,MAGNET1M,NOFRACTAL, XAXIS_NOIMAG,
  12258. X   Magnet1Fractal,juliafp_per_pixel,JuliafpSetup,StandardFractal,100.0,
  12259. X
  12260. X   "magnet2m", realz0, imagz0,ES,ES,0,0,0,0,
  12261. X   HT_MAGNET, HF_MAGM2, WINFRAC,
  12262. X   -1.5,3.7, -1.95,1.95,   0, MAGNET2J,NOFRACTAL,NOFRACTAL, XAXIS_NOPARM,
  12263. X   Magnet2Fractal,mandelfp_per_pixel,MandelfpSetup,StandardFractal,100.0,
  12264. X
  12265. X   "magnet2j", realparm, imagparm,ES,ES,0,0,0,0,
  12266. X   HT_MAGNET, HF_MAGJ2, WINFRAC,
  12267. X   -8.0,  8.0, -6.0,  6.0, 0, NOFRACTAL,MAGNET2M,NOFRACTAL, XAXIS_NOIMAG,
  12268. X   Magnet2Fractal,juliafp_per_pixel,JuliafpSetup,StandardFractal,100.0,
  12269. X
  12270. X   "bifurcation",filt,seed,ES,ES,1000.0,0.66,0,0,
  12271. X   HT_BIF, HF_BIFURCATION, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12272. X   1.9,  3.0, 0,  1.34, 1, NOFRACTAL, NOFRACTAL, BIFURCATION, NOSYM,
  12273. X   LongBifurcVerhulstTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12274. X
  12275. X   "biflambda",filt,seed,ES,ES,1000.0,0.66,0,0,
  12276. X   HT_BIF, HF_BIFLAMBDA, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12277. X   -2.0, 4.0, -1.0, 2.0, 1, NOFRACTAL, NOFRACTAL, BIFLAMBDA,   NOSYM,
  12278. X   LongBifurcLambdaTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12279. X
  12280. X   "*biflambda",filt,seed,ES,ES,1000.0,0.66,0,0,
  12281. X   HT_BIF, HF_BIFLAMBDA, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12282. X   -2.0, 4.0, -1.0, 2.0, 0, NOFRACTAL, NOFRACTAL, LBIFLAMBDA,  NOSYM,
  12283. X   BifurcLambdaTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12284. X
  12285. X   "*bif+sinpi",filt,seed,ES,ES,1000.0,0.66,0,0,
  12286. X   HT_BIF, HF_BIFPLUSSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12287. X   0.275,1.45, 0.0, 2.0, 0, NOFRACTAL, NOFRACTAL, LBIFADSINPI,     NOSYM,
  12288. X   BifurcAddTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12289. X
  12290. X   "*bif=sinpi",filt,seed,ES,ES,1000.0,0.66,0,0,
  12291. X   HT_BIF, HF_BIFEQSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12292. X   -2.5, 2.5, -3.5, 3.5, 0, NOFRACTAL, NOFRACTAL, LBIFEQSINPI,     NOSYM,
  12293. X   BifurcSetTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12294. X
  12295. X   "*popcornjul", step, ES, ES,ES,0.05,0,0,0,
  12296. X   HT_POPCORN, HF_POPCJUL, WINFRAC,
  12297. X   -3.0,  3.0, -2.2,  2.2, 0, NOFRACTAL, NOFRACTAL, LPOPCORNJUL,  ORIGIN,
  12298. X   PopcornFractal, otherjuliafp_per_pixel,  JuliafpSetup,StandardFractal,STDBAILOUT,
  12299. X
  12300. X   "popcornjul", step, ES, ES,ES,0.05,0,0,0,
  12301. X   HT_POPCORN, HF_POPCJUL, WINFRAC,
  12302. X   -3.0,  3.0, -2.2,  2.2, 16, NOFRACTAL, NOFRACTAL, FPPOPCORNJUL,  ORIGIN,
  12303. X   LPopcornFractal,   long_julia_per_pixel, JulialongSetup,  StandardFractal,STDBAILOUT,
  12304. X
  12305. X   "lsystem", "+Order",ES,ES,ES,2,0,0,0,
  12306. X   HT_LSYS, -3, NOZOOM+NORESUME+NOGUESS+NOTRACE+WINFRAC,
  12307. X   -1, 1, -1, 1, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12308. X   NULL, NULL, StandaloneSetup, Lsystem, NOBAILOUT,
  12309. X
  12310. X   "*manowarj", realparm, imagparm,ES,ES,0,0,0,0,
  12311. X   HT_SCOTSKIN, HF_MANOWARJ, WINFRAC+OKJB,
  12312. X   -2.5,  1.5, -1.5, 1.5, 0, NOFRACTAL, MANOWARFP, MANOWARJ,   NOSYM,
  12313. X   ManOWarfpFractal,juliafp_per_pixel, JuliafpSetup,StandardFractal,STDBAILOUT,
  12314. X
  12315. X   "manowarj",  realparm, imagparm,ES,ES,0,0,0,0,
  12316. X   HT_SCOTSKIN, HF_MANOWARJ, WINFRAC+OKJB,
  12317. X   -2.5,  1.5, -1.5, 1.5, 1, NOFRACTAL, MANOWAR,   MANOWARJFP, NOSYM,
  12318. X   ManOWarFractal,julia_per_pixel, JulialongSetup,StandardFractal,STDBAILOUT,
  12319. X
  12320. X   "*fn(z)+fn(pix)", realz0,imagz0,recoeftrg2,imcoeftrg2,0,0,1,0,
  12321. X   HT_SCOTSKIN, HF_FNPLUSFNPIX, TRIG2,
  12322. X   -2.5,  1.5, -1.5, 1.5, 0, NOFRACTAL, NOFRACTAL, FNPLUSFNPIXLONG, NOSYM,
  12323. X   Richard8fpFractal,otherrichard8fp_per_pixel, MandelfpSetup,StandardFractal,LTRIGBAILOUT,
  12324. X
  12325. X   "fn(z)+fn(pix)",  realz0,imagz0,recoeftrg2,imcoeftrg2,0,0,1,0,
  12326. X   HT_SCOTSKIN, HF_FNPLUSFNPIX, TRIG2,
  12327. X   -2.5,  1.5, -1.5, 1.5, 1, NOFRACTAL, NOFRACTAL, FNPLUSFNPIXFP, NOSYM,
  12328. X   Richard8Fractal,long_richard8_per_pixel, MandellongSetup,StandardFractal,LTRIGBAILOUT,
  12329. X
  12330. X   "*marksmandelpwr", realz0, imagz0,ES,ES,0,0,0,0,
  12331. X   HT_MARKS, HF_MARKSMANDPWR, TRIG1+WINFRAC,
  12332. X   -2.5,  1.5, -1.5, 1.5, 0, NOFRACTAL, NOFRACTAL, MARKSMANDELPWR, XAXIS_NOPARM,
  12333. X   MarksMandelPwrfpFractal,marks_mandelpwrfp_per_pixel, MandelfpSetup,StandardFractal,STDBAILOUT,
  12334. X
  12335. X   "marksmandelpwr",  realz0, imagz0,ES,ES,0,0,0,0,
  12336. X   HT_MARKS, HF_MARKSMANDPWR, TRIG1+WINFRAC,
  12337. X   -2.5,  1.5, -1.5,  1.5, 1, NOFRACTAL,     NOFRACTAL, MARKSMANDELPWRFP,  XAXIS_NOPARM,
  12338. X   MarksMandelPwrFractal,marks_mandelpwr_per_pixel, MandelSetup,StandardFractal,STDBAILOUT,
  12339. X
  12340. X   "*tim's_error",    realz0, imagz0,ES,ES,0,0,0,0,
  12341. X   HT_MARKS, HF_TIMSERR, WINFRAC+TRIG1,
  12342. X   -2.5,  3.0, -2.0,  2.0, 0, NOFRACTAL,     NOFRACTAL, TIMSERROR,    XAXIS_NOPARM,
  12343. X   TimsErrorfpFractal,marks_mandelpwrfp_per_pixel, MandelfpSetup,StandardFractal,STDBAILOUT,
  12344. X
  12345. X   "tim's_error",    realz0, imagz0,ES,ES,0,0,0,0,
  12346. X   HT_MARKS, HF_TIMSERR, WINFRAC+TRIG1,
  12347. X   -2.5,  3.0, -2.0,  2.0, 1, NOFRACTAL,     NOFRACTAL, TIMSERRORFP,  XAXIS_NOPARM,
  12348. X   TimsErrorFractal,marks_mandelpwr_per_pixel, MandelSetup,StandardFractal,STDBAILOUT,
  12349. X
  12350. X   "bif=sinpi",filt,seed,ES,ES,1000.0,0.66,0,0,
  12351. X   HT_BIF, HF_BIFEQSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12352. X   -2.5, 2.5, -3.5, 3.5, 1, NOFRACTAL, NOFRACTAL, BIFEQSINPI,     NOSYM,
  12353. X   LongBifurcSetTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12354. X
  12355. X   "bif+sinpi",filt,seed,ES,ES,1000.0,0.66,0,0,
  12356. X   HT_BIF, HF_BIFPLUSSINPI, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12357. X   0.275,1.45, 0.0, 2.0, 1, NOFRACTAL, NOFRACTAL, BIFADSINPI,     NOSYM,
  12358. X   LongBifurcAddTrigPi, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12359. X
  12360. X   "*bifstewart",filt,seed,ES,ES,1000.0,0.66,0,0,
  12361. X   HT_BIF, HF_BIFSTEWART, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12362. X   0.7,2.0, -1.1,1.1, 0, NOFRACTAL, NOFRACTAL, LBIFSTEWART, NOSYM,
  12363. X   BifurcStewartTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12364. X
  12365. X   "bifstewart", filt,seed,ES,ES,1000.0,0.66,0,0,
  12366. X   HT_BIF, HF_BIFSTEWART, TRIG1+NOGUESS+NOTRACE+NOROTATE+WINFRAC,
  12367. X   0.7,2.0, -1.1,1.1, 1, NOFRACTAL, NOFRACTAL, BIFSTEWART, NOSYM,
  12368. X   LongBifurcStewartTrig, NULL, StandaloneSetup, Bifurcation, NOBAILOUT,
  12369. X
  12370. X   "hopalong",A,B,C,ES,.4,1,0,0,
  12371. X   HT_MARTIN, HF_HOPALONG, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12372. X   -2.0, 3.0, -1.625, 2.625, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,    NOSYM,
  12373. X   hopalong2dfloatorbit, NULL,         orbit3dfloatsetup, orbit2dfloat,     NOBAILOUT,
  12374. X
  12375. X   "circle", "magnification",ES,ES,ES,200000,0,0,0,
  12376. X   HT_CIRCLE, HF_CIRCLE, WINFRAC,
  12377. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,  XYAXIS,
  12378. X   CirclefpFractal, juliafp_per_pixel,  JuliafpSetup,StandardFractal,NOBAILOUT,
  12379. X
  12380. X   "martin",A,ES,ES,ES,3.14,0,0,0,
  12381. X   HT_MARTIN, HF_MARTIN, NOGUESS+NOTRACE+INFCALC+WINFRAC,
  12382. X   -32,  32, -32, 32, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,    NOSYM,
  12383. X   martin2dfloatorbit, NULL,         orbit3dfloatsetup, orbit2dfloat,     NOBAILOUT,
  12384. X
  12385. X  "lyapunov", "+Order (integer)", "Population Seed", "+Filter Cycles", ES, 0, 0.5, 0, 0,
  12386. X   HT_LYAPUNOV, HT_LYAPUNOV, WINFRAC,
  12387. X   -8.0, 8.0, -6.0, 6.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12388. X   BifurcLambda, NULL, lya_setup, lyapunov, NOBAILOUT,
  12389. X
  12390. X   "lorenz3d1",timestep,A,B,C,.02,5,15,1,
  12391. X   HT_LORENZ, HF_LORENZ3D1, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12392. X   -30.0,  30.0,  -30.0,   30.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12393. X   lorenz3d1floatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT,
  12394. X
  12395. X   "lorenz3d3",timestep,A,B,C,.02,10,28,2.66,
  12396. X   HT_LORENZ, HF_LORENZ3D3, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12397. X   -30.0,  30.0,  -30.0,   30.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12398. X   lorenz3d3floatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT,
  12399. X
  12400. X   "lorenz3d4",timestep,A,B,C,.02,10,28,2.66,
  12401. X   HT_LORENZ, HF_LORENZ3D4, NOGUESS+NOTRACE+NORESUME+WINFRAC+PARMS3D,
  12402. X   -30.0,  30.0,  -30.0,   30.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12403. X   lorenz3d4floatorbit, NULL, orbit3dfloatsetup, orbit3dfloat, NOBAILOUT,
  12404. X
  12405. X   "lambda(fn||fn)", realparm, imagparm, shiftval, ES,1,0.1,1,0,
  12406. X   HT_FNORFN, HF_LAMBDAFNFN, TRIG2,
  12407. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, LMANLAMFNFN, FPLAMBDAFNFN, ORIGIN,
  12408. X   LambdaTrigOrTrigFractal, long_julia_per_pixel, LambdaTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12409. X
  12410. X   "*lambda(fn||fn)", realparm, imagparm, shiftval,ES,1,0.1,1,0,
  12411. X   HT_FNORFN, HF_LAMBDAFNFN, TRIG2,
  12412. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, FPMANLAMFNFN, LLAMBDAFNFN,ORIGIN,
  12413. X   LambdaTrigOrTrigfpFractal, otherjuliafp_per_pixel, LambdaTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12414. X
  12415. X   "julia(fn||fn)", realparm, imagparm, shiftval, ES,0,0,8,0,
  12416. X   HT_FNORFN, HF_JULIAFNFN, TRIG2,
  12417. X   -4.0,  4.0, -3.0,  3.0, 16, NOFRACTAL, LMANFNFN, FPJULFNFN,XAXIS,
  12418. X   JuliaTrigOrTrigFractal, long_julia_per_pixel, JuliaTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12419. X
  12420. X   "*julia(fn||fn)", realparm, imagparm, shiftval,ES,0,0,8,0,
  12421. X   HT_FNORFN, HF_JULIAFNFN, TRIG2,
  12422. X   -4.0,  4.0, -3.0,  3.0, 0, NOFRACTAL, FPMANFNFN, LJULFNFN,XAXIS,
  12423. X   JuliaTrigOrTrigfpFractal, otherjuliafp_per_pixel, JuliaTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12424. X
  12425. X   "manlam(fn||fn)", realz0, imagz0, shiftval,ES,0,0,10,0,
  12426. X   HT_FNORFN, HF_MANLAMFNFN, TRIG2,
  12427. X   -4.0,  4.0, -3.0,  3.0, 16, LLAMBDAFNFN, NOFRACTAL, FPMANLAMFNFN,XAXIS_NOPARM,
  12428. X   LambdaTrigOrTrigFractal, long_mandel_per_pixel, ManlamTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12429. X
  12430. X   "*manlam(fn||fn)", realz0, imagz0, shiftval,ES,0,0,10,0,
  12431. X   HT_FNORFN, HF_MANLAMFNFN, TRIG2,
  12432. X   -4.0,  4.0, -3.0,  3.0, 0, FPLAMBDAFNFN, NOFRACTAL, LMANLAMFNFN,XAXIS_NOPARM,
  12433. X   LambdaTrigOrTrigfpFractal, othermandelfp_per_pixel, ManlamTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12434. X
  12435. X   "mandel(fn||fn)", realz0, imagz0, shiftval,ES,0,0,0.5,0,
  12436. X   HT_FNORFN, HF_MANDELFNFN, TRIG2,
  12437. X   -4.0,  4.0, -3.0,  3.0, 16, LJULFNFN, NOFRACTAL, FPMANFNFN,XAXIS_NOPARM,
  12438. X   JuliaTrigOrTrigFractal, long_mandel_per_pixel, MandelTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12439. X
  12440. X   "*mandel(fn||fn)", realz0, imagz0, shiftval,ES,0,0,0.5,0,
  12441. X   HT_FNORFN, HF_MANDELFNFN, TRIG2,
  12442. X   -4.0,  4.0, -3.0,  3.0, 0, FPJULFNFN, NOFRACTAL, LMANFNFN,XAXIS_NOPARM,
  12443. X   JuliaTrigOrTrigfpFractal, othermandelfp_per_pixel, MandelTrigOrTrigSetup, StandardFractal,LTRIGBAILOUT,
  12444. X
  12445. X   "bifmay",filt,seed,"Beta >= 2",ES,300.0,0.9,5,0,
  12446. X   HT_BIF, HF_BIFMAY, NOGUESS+NOTRACE+NOROTATE,
  12447. X   -3.5, -0.9, -0.5, 3.2, 16, NOFRACTAL, NOFRACTAL, BIFMAY,     NOSYM,
  12448. X   LongBifurcMay, NULL, BifurcMaySetup, Bifurcation, NOBAILOUT,
  12449. X
  12450. X   "*bifmay",filt,seed,"Beta >= 2",ES,300.0,0.9,5,0,
  12451. X   HT_BIF, HF_BIFMAY, NOGUESS+NOTRACE+NOROTATE,
  12452. X   -3.5, -0.9, -0.5, 3.2, 0, NOFRACTAL, NOFRACTAL, LBIFMAY,     NOSYM,
  12453. X   BifurcMay, NULL, BifurcMaySetup, Bifurcation, NOBAILOUT,
  12454. X
  12455. X  "halley", "+Order (integer > 1)", "Relaxation coefficient", "Epsilon", ES, 6, 1.0, 0.0001, 0,
  12456. X   HT_HALLEY, HF_HALLEY, 0,
  12457. X   -2.0, 2.0, -1.3, 1.3, 0, NOFRACTAL, NOFRACTAL, HALLEY, XYAXIS,
  12458. X   MPCHalleyFractal, MPCHalley_per_pixel, HalleySetup, StandardFractal, NOBAILOUT,
  12459. X
  12460. X  "*halley", "+Order (integer > 1)", "Relaxation coefficient", "Epsilon", ES, 6, 1.0, 0.0001, 0,
  12461. X   HT_HALLEY, HF_HALLEY, 0,
  12462. X   -2.0, 2.0, -1.3, 1.3, 0, NOFRACTAL, NOFRACTAL, MPHALLEY, XYAXIS,
  12463. X   HalleyFractal, Halley_per_pixel, HalleySetup, StandardFractal, NOBAILOUT,
  12464. X
  12465. X   "dynamic","+# of intervals (<0 = connect)","time step (<0 = Euler",A,B,
  12466. X   50,.1,1,3,
  12467. X   HT_DYNAM, HF_DYNAM, NOGUESS+NOTRACE+NORESUME+WINFRAC+TRIG1,
  12468. X   -20.0,  20.0,  -20.0,   20.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12469. X   dynamfloat, NULL, dynam2dfloatsetup, dynam2dfloat, NOBAILOUT,
  12470. X
  12471. X   "quat", "notused", "notused",CJ,CK,0,0,0,0,
  12472. X   HT_QUAT, HF_QUAT, WINFRAC+OKJB,
  12473. X   -2.0,  2.0, -1.5,  1.5, 0, QUATJULFP, NOFRACTAL, NOFRACTAL,  XAXIS,
  12474. X   QuaternionFPFractal, quaternionfp_per_pixel,MandelfpSetup,StandardFractal,
  12475. X   LTRIGBAILOUT,
  12476. X
  12477. X   "quatjul", C1, CI, CJ,CK,-.745,0,.113,.05,
  12478. X   HT_QUAT, HF_QUATJ, WINFRAC+OKJB+MORE,
  12479. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, QUATFP, NOFRACTAL,  ORIGIN,
  12480. X   QuaternionFPFractal, quaternionjulfp_per_pixel,JuliafpSetup,StandardFractal,
  12481. X   LTRIGBAILOUT,
  12482. X
  12483. X   "cellular", "Initial String | 0 = Random | -1 = Reuse Last Random",
  12484. X   "Rule = # of digits (see below) | 0 = Random",
  12485. X   "Type (see below)",
  12486. X   "Starting Row Number",
  12487. X   11.0, 3311100320.0, 41.0, 0,
  12488. X   HT_CELLULAR, HF_CELLULAR, NOGUESS+NOTRACE+NOZOOM,
  12489. X   -1.0,  1.0, -1.0,  1.0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,  NOSYM,
  12490. X   NULL,       NULL,   CellularSetup,     cellular,      NOBAILOUT,
  12491. X
  12492. X   "*julibrot", ES,ES,ES,ES,0, 0, 0, 0,
  12493. X   HT_JULIBROT, -1, NOGUESS+NOTRACE+NOROTATE+NORESUME+WINFRAC,
  12494. X   -2.0, 2.0, -1.5, 1.5, 0, NOFRACTAL, NOFRACTAL, JULIBROT, NOSYM,
  12495. X   JuliafpFractal, jbfp_per_pixel, JulibrotSetup, Std4dfpFractal, STDBAILOUT,
  12496. X
  12497. X#ifdef RANDOM_RUN
  12498. X   "julia_inverse", realparm, imagparm,
  12499. X   "Max Hits per Pixel", "Random Run Interval", -0.11, 0.6557, 4, 1024,
  12500. X   HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+WINFRAC+NORESUME,
  12501. X   -2.0,  2.0, -1.5, 1.5, 24, NOFRACTAL, MANDEL, INVERSEJULIAFP,  NOSYM,
  12502. X   Linverse_julia_orbit, NULL, orbit3dlongsetup, inverse_julia_per_image, NOBAILOUT,
  12503. X
  12504. X   "*julia_inverse", realparm, imagparm,
  12505. X   "Max Hits per Pixel", "Random Run Interval", -0.11, 0.6557, 4, 1024,
  12506. X   HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+WINFRAC+NORESUME,
  12507. X   -2.0,  2.0, -1.5, 1.5,  0, NOFRACTAL, MANDEL, INVERSEJULIA,  NOSYM,
  12508. X   Minverse_julia_orbit, NULL, orbit3dfloatsetup, inverse_julia_per_image, NOBAILOUT,
  12509. X#else
  12510. X   "julia_inverse", realparm, imagparm,
  12511. X   "Max Hits per Pixel", ES, -0.11, 0.6557, 4, 1024,
  12512. X   HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+WINFRAC+NORESUME,
  12513. X   -2.0,  2.0, -1.5, 1.5, 24, NOFRACTAL, MANDEL, INVERSEJULIAFP,  NOSYM,
  12514. X   Linverse_julia_orbit, NULL, orbit3dlongsetup, inverse_julia_per_image, NOBAILOUT,
  12515. X
  12516. X   "*julia_inverse", realparm, imagparm,
  12517. X   "Max Hits per Pixel", ES, -0.11, 0.6557, 4, 1024,
  12518. X   HT_INVERSE, HF_INVERSE, NOGUESS+NOTRACE+INFCALC+WINFRAC+NORESUME,
  12519. X   -2.0,  2.0, -1.5, 1.5,  0, NOFRACTAL, MANDEL, INVERSEJULIA,  NOSYM,
  12520. X   Minverse_julia_orbit, NULL, orbit3dfloatsetup, inverse_julia_per_image, NOBAILOUT,
  12521. X
  12522. X#endif
  12523. X
  12524. X   "mandelcloud","+# of intervals (<0 = connect)",ES,ES,ES,
  12525. X   50,0,0,0,
  12526. X   HT_MANDELCLOUD, HF_MANDELCLOUD, NOGUESS+NOTRACE+NORESUME+WINFRAC,
  12527. X   -2.5,  1.5,  -1.5,   1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12528. X   mandelcloudfloat, NULL, dynam2dfloatsetup, dynam2dfloat, NOBAILOUT,
  12529. X
  12530. X   "phoenix",p1real,p2real,"Degree of Z = 0 | >= 2 | <= -3",ES,0.56667,-0.5,0,0,
  12531. X   HT_PHOENIX, HF_PHOENIX, 0,
  12532. X   -2.0, 2.0, -1.5, 1.5, 1, NOFRACTAL, MANDPHOENIX, PHOENIXFP, XAXIS,
  12533. X   LongPhoenixFractal, long_phoenix_per_pixel, PhoenixSetup, StandardFractal, STDBAILOUT,
  12534. X
  12535. X   "*phoenix",p1real,p2real,"Degree of Z = 0 | >= 2 | <= -3",ES,0.56667,-0.5,0,0,
  12536. X   HT_PHOENIX, HF_PHOENIX, 0,
  12537. X   -2.0, 2.0, -1.5, 1.5, 0, NOFRACTAL, MANDPHOENIXFP, PHOENIX, XAXIS,
  12538. X   PhoenixFractal, phoenix_per_pixel, PhoenixSetup, StandardFractal, STDBAILOUT,
  12539. X
  12540. X   "mandphoenix",realz0,imagz0,"Degree of Z = 0 | >= 2 | <= -3",ES,0.0,0.0,0,0,
  12541. X   HT_PHOENIX, HF_MANDPHOENIX, 0,
  12542. X   -2.5, 1.5, -1.5, 1.5, 1, PHOENIX, NOFRACTAL, MANDPHOENIXFP, NOSYM,
  12543. X   LongPhoenixFractal, long_mandphoenix_per_pixel, MandPhoenixSetup, StandardFractal, STDBAILOUT,
  12544. X
  12545. X   "*mandphoenix",realz0,imagz0,"Degree of Z = 0 | >= 2 | <= -3",ES,0.0,0.0,0,0,
  12546. X   HT_PHOENIX, HF_MANDPHOENIX, 0,
  12547. X   -2.5, 1.5, -1.5, 1.5, 0, PHOENIXFP, NOFRACTAL, MANDPHOENIX, NOSYM,
  12548. X   PhoenixFractal, mandphoenix_per_pixel, MandPhoenixSetup, StandardFractal, STDBAILOUT,
  12549. X
  12550. X   "hypercomplex", "notused", "notused",CJ,CK,0,0,0,0,
  12551. X   HT_HYPERC, HF_HYPERC, WINFRAC+OKJB+TRIG1,
  12552. X   -2.0,  2.0, -1.5,  1.5, 0, HYPERCMPLXJFP, NOFRACTAL, NOFRACTAL,  XAXIS,
  12553. X   HyperComplexFPFractal, quaternionfp_per_pixel,MandelfpSetup,StandardFractal,
  12554. X   LTRIGBAILOUT,
  12555. X
  12556. X   "hypercomplexj", C1, CI, CJ,CK,-.745,0,.113,.05,
  12557. X   HT_HYPERC, HF_HYPERCJ, WINFRAC+OKJB+TRIG1+MORE,
  12558. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, HYPERCMPLXFP, NOFRACTAL,  ORIGIN,
  12559. X   HyperComplexFPFractal, quaternionjulfp_per_pixel,JuliafpSetup,StandardFractal,
  12560. X   LTRIGBAILOUT,
  12561. X
  12562. X  "frothybasin", frothattractor, frothshade, ES, ES, 3, 0, 0, 0,
  12563. X   HT_FROTH, HF_FROTH, NOTRACE+WINFRAC,
  12564. X   -3, 3, -2.5, 2, 28, NOFRACTAL, NOFRACTAL, FROTHFP, NOSYM,
  12565. X   NULL, NULL, froth_setup, calcfroth, FROTHBAILOUT,
  12566. X
  12567. X  "*frothybasin", frothattractor, frothshade, ES, ES, 3, 0, 0, 0,
  12568. X   HT_FROTH, HF_FROTH, NOTRACE+WINFRAC,
  12569. X   -3, 3, -2.5, 2, 0, NOFRACTAL, NOFRACTAL, FROTH, NOSYM,
  12570. X   NULL, NULL, froth_setup, calcfroth, FROTHBAILOUT,
  12571. X
  12572. X   "*mandel4",realz0, imagz0,ES,ES,0,0,0,0,
  12573. X   HT_MANDJUL4, HF_MANDEL4, WINFRAC,
  12574. X   -2.0,  2.0, -1.5,  1.5, 0, JULIA4FP, NOFRACTAL, MANDEL4,  XAXIS_NOPARM,
  12575. X   Mandel4fpFractal,mandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12576. X
  12577. X   "*julia4", realparm, imagparm,ES,ES,0.6,0.55,0,0,
  12578. X   HT_MANDJUL4, HF_JULIA4, WINFRAC+OKJB,
  12579. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, MANDEL4FP, JULIA4, ORIGIN,
  12580. X   Mandel4fpFractal, juliafp_per_pixel, JuliafpSetup,StandardFractal,     STDBAILOUT,
  12581. X
  12582. X   "*marksmandel", realz0, imagz0, exponent,ES,0,0,1,0,
  12583. X   HT_MARKS, HF_MARKSMAND, WINFRAC,
  12584. X   -2.0,  2.0, -1.5,  1.5, 0, MARKSJULIAFP, NOFRACTAL, MARKSMANDEL,  NOSYM,
  12585. X   MarksLambdafpFractal,marksmandelfp_per_pixel,MandelfpSetup,StandardFractal,STDBAILOUT,
  12586. X
  12587. X   "*marksjulia", realparm, imagparm, exponent,ES,0.1,0.9,0,0,
  12588. X   HT_MARKS, HF_MARKSJULIA, WINFRAC,
  12589. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, MARKSMANDELFP, MARKSJULIA,   ORIGIN,
  12590. X   MarksLambdafpFractal,juliafp_per_pixel,MarksJuliafpSetup,StandardFractal,STDBAILOUT,
  12591. X
  12592. X   /* dmf */
  12593. X   "icons", lambda, alpha,beta,gamma2, -2.34, 2.0, 0.2, 0.1,
  12594. X   HT_ICON, HF_ICON, NOGUESS+NOTRACE+WINFRAC+INFCALC+MORE,
  12595. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL,  NOFRACTAL, NOSYM,
  12596. X   iconfloatorbit, NULL, orbit3dfloatsetup,  orbit2dfloat, NOBAILOUT,
  12597. X
  12598. X   /* dmf */
  12599. X   "icons3d", lambda, alpha,beta,gamma2, -2.34, 2.0, 0.2, 0.1,
  12600. X   HT_ICON, HF_ICON, NOGUESS+NOTRACE+WINFRAC+INFCALC+PARMS3D+MORE,
  12601. X   -2.0,  2.0, -1.5,  1.5, 0, NOFRACTAL, NOFRACTAL,  NOFRACTAL, NOSYM,
  12602. X   iconfloatorbit, NULL, orbit3dfloatsetup,  orbit3dfloat, NOBAILOUT,
  12603. X
  12604. X/*  the following demonstration drunkard's walk fractal requires
  12605. X    only the demowalk() routine in FRACTALS.C to be functional
  12606. X    (the definition of the positional value DEMOWALK in FRACTYPE.H
  12607. X    is not really required, but is good practice).
  12608. X*/
  12609. X/*
  12610. X   "demowalk", "Average Stepsize (% of image)",
  12611. X               "Color (0 means rotate colors)",ES,ES,5,0.0,0,0,
  12612. X   -1, -1, NORESUME+WINFRAC,
  12613. X   -2.5,  1.5,  -1.5,   1.5, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL, NOSYM,
  12614. X   NULL,  NULL,  StandaloneSetup,  demowalk,  NOBAILOUT,
  12615. X*/
  12616. X
  12617. X/*  the following demonstration Mandelbrot/Julia fractals require
  12618. X    only the definition of the four positional values DEMOMANDEL,
  12619. X    DEMOJULIA, DEMOMANDELFP, and DEMOJULIAFP in FRACTYPE.H to be
  12620. X    functional - and we only need *them* for the integer/floatingpoint
  12621. X    and Mandelbrot/Julia toggle items in their structure items.
  12622. X*/
  12623. X/*
  12624. X   "demomandel", realz0, imagz0,ES,ES,0,0,0,0,
  12625. X   -1, -1, WINFRAC,
  12626. X   -2.5, 1.5, -1.5, 1.5, 1, DEMOJULIA,  NOFRACTAL, DEMOMANDELFP, XAXIS_NOPARM,
  12627. X   JuliaFractal, mandel_per_pixel, MandellongSetup, StandardFractal, STDBAILOUT,
  12628. X
  12629. X   "demojulia", realparm, imagparm,ES,ES,0.3,0.6,0,0,
  12630. X   -1, -1, WINFRAC,
  12631. X   -2.0, 2.0, -1.5, 1.5, 1, NOFRACTAL, DEMOMANDEL, DEMOJULIAFP, ORIGIN,
  12632. X   JuliaFractal, julia_per_pixel, JulialongSetup, StandardFractal, STDBAILOUT,
  12633. X
  12634. X   "*demomandel", realz0, imagz0,ES,ES,0,0,0,0,
  12635. X   -1, -1, WINFRAC,
  12636. X   -2.5, 1.5, -1.5, 1.5, 0, DEMOJULIAFP,  NOFRACTAL, DEMOJULIA, XAXIS_NOPARM,
  12637. X   JuliafpFractal, mandelfp_per_pixel, MandelfpSetup, StandardFractal, STDBAILOUT,
  12638. X
  12639. X   "*demojulia", realparm, imagparm,ES,ES,0.3,0.6,0,0,
  12640. X   -1, -1, WINFRAC,
  12641. X   -2.0, 2.0, -1.5, 1.5, 0, NOFRACTAL, DEMOMANDELFP, DEMOMANDEL, ORIGIN,
  12642. X   JuliafpFractal, juliafp_per_pixel, JuliafpSetup, StandardFractal, STDBAILOUT,
  12643. X*/
  12644. X
  12645. X
  12646. X   NULL, NULL, NULL, NULL, NULL,0,0,0,0,    /* marks the END of the list */
  12647. X   -1, -1, 0,
  12648. X   0,  0, 0,  0, 0, NOFRACTAL, NOFRACTAL, NOFRACTAL,   NOSYM,
  12649. X   NULL, NULL, NULL, NULL,0
  12650. X
  12651. X};
  12652. X
  12653. Xint num_fractal_types = (sizeof(fractalspecific)/
  12654. X    sizeof(struct fractalspecificstuff)) -1;
  12655. X
  12656. SHAR_EOF
  12657. $TOUCH -am 1028230093 fractalp.c &&
  12658. chmod 0644 fractalp.c ||
  12659. echo "restore of fractalp.c failed"
  12660. set `wc -c fractalp.c`;Wc_c=$1
  12661. if test "$Wc_c" != "48702"; then
  12662.     echo original size 48702, current size $Wc_c
  12663. fi
  12664. # ============= fractals.c ==============
  12665. echo "x - extracting fractals.c (Text)"
  12666. sed 's/^X//' << 'SHAR_EOF' > fractals.c &&
  12667. X/*
  12668. XFRACTALS.C, FRACTALP.C and CALCFRAC.C actually calculate the fractal
  12669. Ximages (well, SOMEBODY had to do it!).  The modules are set up so that
  12670. Xall logic that is independent of any fractal-specific code is in
  12671. XCALCFRAC.C, the code that IS fractal-specific is in FRACTALS.C, and the
  12672. Xstruscture that ties (we hope!) everything together is in FRACTALP.C.
  12673. XOriginal author Tim Wegner, but just about ALL the authors have
  12674. Xcontributed SOME code to this routine at one time or another, or
  12675. Xcontributed to one of the many massive restructurings.
  12676. X
  12677. XThe Fractal-specific routines are divided into three categories:
  12678. X
  12679. X1. Routines that are called once-per-orbit to calculate the orbit
  12680. X   value. These have names like "XxxxFractal", and their function
  12681. X   pointers are stored in fractalspecific[fractype].orbitcalc. EVERY
  12682. X   new fractal type needs one of these. Return 0 to continue iterations,
  12683. X   1 if we're done. Results for integer fractals are left in 'lnew.x' and
  12684. X   'lnew.y', for floating point fractals in 'new.x' and 'new.y'.
  12685. X
  12686. X2. Routines that are called once per pixel to set various variables
  12687. X   prior to the orbit calculation. These have names like xxx_per_pixel
  12688. X   and are fairly generic - chances are one is right for your new type.
  12689. X   They are stored in fractalspecific[fractype].per_pixel.
  12690. X
  12691. X3. Routines that are called once per screen to set various variables.
  12692. X   These have names like XxxxSetup, and are stored in
  12693. X   fractalspecific[fractype].per_image.
  12694. X
  12695. X4. The main fractal routine. Usually this will be StandardFractal(),
  12696. X   but if you have written a stand-alone fractal routine independent
  12697. X   of the StandardFractal mechanisms, your routine name goes here,
  12698. X   stored in fractalspecific[fractype].calctype.per_image.
  12699. X
  12700. XAdding a new fractal type should be simply a matter of adding an item
  12701. Xto the 'fractalspecific' structure, writing (or re-using one of the existing)
  12702. Xan appropriate setup, per_image, per_pixel, and orbit routines.
  12703. X
  12704. X--------------------------------------------------------------------   */
  12705. X
  12706. X
  12707. X#include <stdio.h>
  12708. X#include <stdlib.h>
  12709. X#include <float.h>
  12710. X#include <limits.h>
  12711. X#include <string.h>
  12712. X#ifdef __TURBOC__
  12713. X#include <alloc.h>
  12714. X#elif !defined(__386BSD__)
  12715. X#include <malloc.h>
  12716. X#endif
  12717. X#include "fractint.h"
  12718. X#include "mpmath.h"
  12719. X#include "helpdefs.h"
  12720. X#include "fractype.h"
  12721. X#include "prototyp.h"
  12722. X
  12723. X#define NEWTONDEGREELIMIT  100
  12724. X
  12725. Xextern int using_jiim;
  12726. Xextern _CMPLX  initorbit;
  12727. Xextern _LCMPLX linitorbit;
  12728. Xextern char useinitorbit;
  12729. Xextern double fgLimit;
  12730. Xextern int distest;
  12731. X
  12732. X#define CMPLXsqr_old(out)    \
  12733. X   (out).y = (old.x+old.x) * old.y;\
  12734. X   (out).x = tempsqrx - tempsqry
  12735. X
  12736. X#define CMPLXpwr(arg1,arg2,out)   (out)= ComplexPower((arg1), (arg2))
  12737. X#define CMPLXmult1(arg1,arg2,out)    Arg2->d = (arg1); Arg1->d = (arg2);\
  12738. X     dStkMul(); Arg1++; Arg2++; (out) = Arg2->d
  12739. X
  12740. X#define CMPLXmult(arg1,arg2,out)  \
  12741. X    {\
  12742. X       _CMPLX TmP;\
  12743. X       TmP.x = (arg1).x*(arg2).x - (arg1).y*(arg2).y;\
  12744. X       TmP.y = (arg1).x*(arg2).y + (arg1).y*(arg2).x;\
  12745. X       (out) = TmP;\
  12746. X     }
  12747. X#if 0
  12748. X#define CMPLXmult(arg1,arg2,out)  {CMPLXmult2(arg1,arg2,&out);}
  12749. X#endif
  12750. X
  12751. Xvoid CMPLXmult2(_CMPLX arg1,_CMPLX arg2, _CMPLX *out)
  12752. X{
  12753. X    _CMPLX TmP;
  12754. X    TmP.x = (arg1).x*(arg2).x - (arg1).y*(arg2).y;
  12755. X    TmP.y = (arg1).x*(arg2).y + (arg1).y*(arg2).x;
  12756. X    *out = TmP;
  12757. X}
  12758. X
  12759. X#define CMPLXadd(arg1,arg2,out)    \
  12760. X    (out).x = (arg1).x + (arg2).x; (out).y = (arg1).y + (arg2).y
  12761. X#define CMPLXsub(arg1,arg2,out)    \
  12762. X    (out).x = (arg1).x - (arg2).x; (out).y = (arg1).y - (arg2).y
  12763. X#define CMPLXtimesreal(arg,real,out)   \
  12764. X    (out).x = (arg).x*(real);\
  12765. X    (out).y = (arg).y*(real)
  12766. X
  12767. X#define CMPLXrecip(arg,out)    \
  12768. X   { double denom; denom = sqr((arg).x) + sqr((arg).y);\
  12769. X     if(denom==0.0) {(out).x = 1.0e10;(out).y = 1.0e10;}else\
  12770. X    { (out).x =  (arg).x/denom;\
  12771. X     (out).y = -(arg).y/denom;}}
  12772. X
  12773. Xextern int xshift, yshift;
  12774. Xextern int biomorph;
  12775. Xextern int forcesymmetry;
  12776. Xextern int symmetry;
  12777. X_LCMPLX lcoefficient,lold,lnew,lparm, linit,ltmp,ltmp2,lparm2;
  12778. Xlong ltempsqrx,ltempsqry;
  12779. Xextern int decomp[];
  12780. Xextern double param[];
  12781. Xextern int potflag;                   /* potential enabled? */
  12782. Xextern double f_radius,f_xcenter,f_ycenter;    /* inversion radius, center */
  12783. Xextern double xxmin,xxmax,yymin,yymax;           /* corners */
  12784. Xextern int overflow;
  12785. Xextern int integerfractal;    /* TRUE if fractal uses integer math */
  12786. X
  12787. Xint maxcolor;
  12788. Xint root, degree,basin;
  12789. Xdouble floatmin,floatmax;
  12790. Xdouble roverd, d1overd, threshold;
  12791. X_CMPLX tmp2;
  12792. Xextern _CMPLX init,tmp,old,new,saved,jbcfp;
  12793. X_CMPLX coefficient;
  12794. X_CMPLX    staticroots[16]; /* roots array for degree 16 or less */
  12795. X_CMPLX    *roots = staticroots;
  12796. Xstruct MPC    *MPCroots;
  12797. Xextern int color, row, col;
  12798. Xextern int invert;
  12799. Xextern double far *dx0, far *dy0;
  12800. Xextern double far *dx1, far *dy1;
  12801. Xlong FgHalf;
  12802. X
  12803. X_CMPLX one;
  12804. X_CMPLX pwr;
  12805. X_CMPLX Coefficient;
  12806. X
  12807. Xextern int    colors;             /* maximum colors available */
  12808. Xextern int    inside;             /* "inside" color to use    */
  12809. Xextern int    outside;            /* "outside" color to use   */
  12810. Xextern int    finattract;
  12811. Xextern int    fractype;            /* fractal type */
  12812. Xextern int    debugflag;            /* for debugging purposes */
  12813. X
  12814. Xextern double    param[];        /* parameters */
  12815. Xextern long    far *lx0, far *ly0;        /* X, Y points */
  12816. Xextern long    far *lx1, far *ly1;        /* X, Y points */
  12817. Xextern long    delx,dely;            /* X, Y increments */
  12818. Xextern long    delmin;             /* min(max(dx),max(dy) */
  12819. Xextern double    ddelmin;            /* min(max(dx),max(dy) */
  12820. Xextern long    fudge;                /* fudge factor (2**n) */
  12821. Xextern int    bitshift;            /* bit shift for fudge */
  12822. Xint    bitshiftless1;            /* bit shift less 1 */
  12823. X
  12824. X#ifndef sqr
  12825. X#define sqr(x) ((x)*(x))
  12826. X#endif
  12827. X
  12828. X#ifndef lsqr
  12829. X#define lsqr(x) (multiply((x),(x),bitshift))
  12830. X#endif
  12831. X
  12832. X#define modulus(z)     (sqr((z).x)+sqr((z).y))
  12833. X#define conjugate(pz)    ((pz)->y = 0.0 - (pz)->y)
  12834. X#define distance(z1,z2)  (sqr((z1).x-(z2).x)+sqr((z1).y-(z2).y))
  12835. X#define pMPsqr(z) (*pMPmul((z),(z)))
  12836. X#define MPdistance(z1,z2)  (*pMPadd(pMPsqr(*pMPsub((z1).x,(z2).x)),pMPsqr(*pMPsub((z1).y,(z2).y))))
  12837. X
  12838. Xdouble twopi = PI*2.0;
  12839. Xint c_exp;
  12840. X
  12841. X
  12842. X/* These are local but I don't want to pass them as parameters */
  12843. X_CMPLX lambda;
  12844. Xextern double magnitude, rqlim, rqlim2;
  12845. X_CMPLX parm,parm2;
  12846. X_CMPLX *floatparm;
  12847. X_LCMPLX *longparm; /* used here and in jb.c */
  12848. Xextern int (*calctype)();
  12849. Xextern unsigned long lm;        /* magnitude limit (CALCMAND) */
  12850. X
  12851. X/* -------------------------------------------------------------------- */
  12852. X/*        These variables are external for speed's sake only      */
  12853. X/* -------------------------------------------------------------------- */
  12854. X
  12855. Xdouble sinx,cosx,sinhx,coshx;
  12856. Xdouble siny,cosy,sinhy,coshy;
  12857. Xdouble tmpexp;
  12858. Xdouble tempsqrx,tempsqry,tempsqrz,tempsqrt;
  12859. X
  12860. Xdouble foldxinitx,foldyinity,foldxinity,foldyinitx;
  12861. Xlong oldxinitx,oldyinity,oldxinity,oldyinitx;
  12862. Xlong longtmp;
  12863. Xextern long lmagnitud, llimit, llimit2, l16triglim;
  12864. Xextern periodicitycheck;
  12865. Xextern char floatflag;
  12866. X
  12867. X/* These are for quaternions */
  12868. Xdouble qc,qci,qcj,qck;
  12869. X
  12870. X/* temporary variables for trig use */
  12871. Xlong lcosx, lcoshx, lsinx, lsinhx;
  12872. Xlong lcosy, lcoshy, lsiny, lsinhy;
  12873. X
  12874. X/*
  12875. X**  details of finite attractors (required for Magnet Fractals)
  12876. X**  (can also be used in "coloring in" the lakes of Julia types)
  12877. X*/
  12878. Xextern          int      attractors; /* number of finite attractors   */
  12879. Xextern _CMPLX  attr[];       /* finite attractor values (f.p) */
  12880. Xextern _LCMPLX lattr[];      /* finite attractor values (int) */
  12881. Xextern int    attrperiod[]; /* finite attractor period */
  12882. X
  12883. X/*
  12884. X**  pre-calculated values for fractal types Magnet2M & Magnet2J
  12885. X*/
  12886. X_CMPLX    T_Cm1;          /* 3 * (floatparm - 1)            */
  12887. X_CMPLX    T_Cm2;          /* 3 * (floatparm - 2)            */
  12888. X_CMPLX    T_Cm1Cm2;     /* (floatparm - 1) * (floatparm - 2) */
  12889. X
  12890. Xvoid FloatPreCalcMagnet2() /* precalculation for Magnet2 (M & J) for speed */
  12891. X  {
  12892. X    T_Cm1.x = floatparm->x - 1.0;   T_Cm1.y = floatparm->y;
  12893. X    T_Cm2.x = floatparm->x - 2.0;   T_Cm2.y = floatparm->y;
  12894. X    T_Cm1Cm2.x = (T_Cm1.x * T_Cm2.x) - (T_Cm1.y * T_Cm2.y);
  12895. X    T_Cm1Cm2.y = (T_Cm1.x * T_Cm2.y) + (T_Cm1.y * T_Cm2.x);
  12896. X    T_Cm1.x += T_Cm1.x + T_Cm1.x;   T_Cm1.y += T_Cm1.y + T_Cm1.y;
  12897. X    T_Cm2.x += T_Cm2.x + T_Cm2.x;   T_Cm2.y += T_Cm2.y + T_Cm2.y;
  12898. X  }
  12899. X
  12900. X
  12901. X/* -------------------------------------------------------------------- */
  12902. X/*        Bailout Routines Macros                                                 */
  12903. X/* -------------------------------------------------------------------- */
  12904. X
  12905. Xstatic int near floatbailout()
  12906. X{
  12907. X   if ( ( magnitude = ( tempsqrx=sqr(new.x) )
  12908. X            + ( tempsqry=sqr(new.y) ) ) >= rqlim ) return(1);
  12909. X   old = new;
  12910. X   return(0);
  12911. X}
  12912. X
  12913. X/* longbailout() is equivalent to next */
  12914. X#define LONGBAILOUT()    \
  12915. X   ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);\
  12916. X   lmagnitud = ltempsqrx + ltempsqry;\
  12917. X   if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2\
  12918. X     || labs(lnew.y) > llimit2 || overflow) \
  12919. X           { overflow=0;return(1);}\
  12920. X   lold = lnew;
  12921. X
  12922. X#define FLOATTRIGBAILOUT()  \
  12923. X   if (fabs(old.y) >= rqlim2) return(1);
  12924. X
  12925. X#define LONGTRIGBAILOUT()  \
  12926. X   if(labs(lold.y) >= llimit2 || overflow) { overflow=0;return(1);}
  12927. X
  12928. X#define LONGXYTRIGBAILOUT()  \
  12929. X   if(labs(lold.x) >= llimit2 || labs(lold.y) >= llimit2 || overflow)\
  12930. X    { overflow=0;return(1);}
  12931. X
  12932. X#define FLOATXYTRIGBAILOUT()  \
  12933. X   if (fabs(old.x) >= rqlim2 || fabs(old.y) >= rqlim2) return(1);
  12934. X
  12935. X#define FLOATHTRIGBAILOUT()  \
  12936. X   if (fabs(old.x) >= rqlim2) return(1);
  12937. X
  12938. X#define LONGHTRIGBAILOUT()  \
  12939. X   if(labs(lold.x) >= llimit2 || overflow) { overflow=0;return(1);}
  12940. X
  12941. X#define TRIG16CHECK(X)    \
  12942. X      if(labs((X)) > l16triglim || overflow) { overflow=0;return(1);}
  12943. X
  12944. X#define FLOATEXPBAILOUT()  \
  12945. X   if (fabs(old.y) >= 1.0e8) return(1);\
  12946. X   if (fabs(old.x) >= 6.4e2) return(1);
  12947. X
  12948. X#define LONGEXPBAILOUT()  \
  12949. X   if (labs(lold.y) >= (1000L<<bitshift)) return(1);\
  12950. X   if (labs(lold.x) >=      (8L<<bitshift)) return(1);
  12951. X
  12952. X#if 0
  12953. X/* this define uses usual trig instead of fast trig */
  12954. X#define FPUsincos(px,psinx,pcosx) \
  12955. X   *(psinx) = sin(*(px));\
  12956. X   *(pcosx) = cos(*(px));
  12957. X
  12958. X#define FPUsinhcosh(px,psinhx,pcoshx) \
  12959. X   *(psinhx) = sinh(*(px));\
  12960. X   *(pcoshx) = cosh(*(px));
  12961. X#endif
  12962. X
  12963. X#define LTRIGARG(X)    \
  12964. X   if(labs((X)) > l16triglim)\
  12965. X   {\
  12966. X      double tmp;\
  12967. X      tmp = (X);\
  12968. X      tmp /= fudge;\
  12969. X      tmp = fmod(tmp,twopi);\
  12970. X      tmp *= fudge;\
  12971. X      (X) = tmp;\
  12972. X   }\
  12973. X
  12974. Xstatic int near Halleybailout()
  12975. X{
  12976. X   if ( fabs(modulus(new)-modulus(old)) < parm2.x)
  12977. X      return(1);
  12978. X   old = new;
  12979. X   return(0);
  12980. X}
  12981. X
  12982. X#ifndef XFRACT
  12983. X#define MPCmod(m) (*pMPadd(*pMPmul((m).x, (m).x), *pMPmul((m).y, (m).y)))
  12984. Xstruct MPC mpcold, mpcnew, mpctmp, mpctmp1;
  12985. Xstruct MP mptmpparm2x;
  12986. X
  12987. Xstatic int near MPCHalleybailout()
  12988. X{
  12989. Xstatic struct MP mptmpbailout;
  12990. X   mptmpbailout = *MPabs(*pMPsub(MPCmod(mpcnew), MPCmod(mpcold)));
  12991. X   if (pMPcmp(mptmpbailout, mptmpparm2x) < 0)
  12992. X      return(1);
  12993. X   mpcold = mpcnew;
  12994. X   return(0);
  12995. X}
  12996. X#endif
  12997. X
  12998. X/* -------------------------------------------------------------------- */
  12999. X/*        Fractal (once per iteration) routines            */
  13000. X/* -------------------------------------------------------------------- */
  13001. Xstatic double xt, yt, t2;
  13002. X
  13003. X/* Raise complex number (base) to the (exp) power, storing the result
  13004. X** in complex (result).
  13005. X*/
  13006. Xvoid cpower(_CMPLX *base, int exp, _CMPLX *result)
  13007. X{
  13008. X    if (exp<0) {
  13009. X    cpower(base,-exp,result);
  13010. X    CMPLXrecip(*result,*result);
  13011. X    return;
  13012. X    }
  13013. X
  13014. X    xt = base->x;   yt = base->y;
  13015. X
  13016. X    if (exp & 1)
  13017. X    {
  13018. X       result->x = xt;
  13019. X       result->y = yt;
  13020. X    }
  13021. X    else
  13022. X    {
  13023. X       result->x = 1.0;
  13024. X       result->y = 0.0;
  13025. X    }
  13026. X
  13027. X    exp >>= 1;
  13028. X    while (exp)
  13029. X    {
  13030. X    t2 = xt * xt - yt * yt;
  13031. X    yt = 2 * xt * yt;
  13032. X    xt = t2;
  13033. X
  13034. X    if (exp & 1)
  13035. X    {
  13036. X        t2 = xt * result->x - yt * result->y;
  13037. X        result->y = result->y * xt + yt * result->x;
  13038. X        result->x = t2;
  13039. X    }
  13040. X    exp >>= 1;
  13041. X    }
  13042. X}
  13043. X/* long version */
  13044. Xstatic long lxt, lyt, lt2;
  13045. X
  13046. Xlcpower(_LCMPLX *base, int exp, _LCMPLX *result, int bitshift)
  13047. X{
  13048. X    static long maxarg;
  13049. X    maxarg = 64L<<bitshift;
  13050. X
  13051. X    overflow = 0;
  13052. X    lxt = base->x;   lyt = base->y;
  13053. X
  13054. X    if (exp & 1)
  13055. X    {
  13056. X       result->x = lxt;
  13057. X       result->y = lyt;
  13058. X    }
  13059. X    else
  13060. X    {
  13061. X       result->x = 1L<<bitshift;
  13062. X       result->y = 0L;
  13063. X    }
  13064. X
  13065. X    exp >>= 1;
  13066. X    while (exp)
  13067. X    {
  13068. X    /*
  13069. X    if(labs(lxt) >= maxarg || labs(lyt) >= maxarg)
  13070. X       return(-1);
  13071. X    */
  13072. X    lt2 = multiply(lxt, lxt, bitshift) - multiply(lyt,lyt,bitshift);
  13073. X    lyt = multiply(lxt,lyt,bitshiftless1);
  13074. X    if(overflow)
  13075. X       return(overflow);
  13076. X    lxt = lt2;
  13077. X
  13078. X    if (exp & 1)
  13079. X    {
  13080. X        lt2 = multiply(lxt,result->x, bitshift) - multiply(lyt,result->y,bitshift);
  13081. X        result->y = multiply(result->y,lxt,bitshift) + multiply(lyt,result->x,bitshift);
  13082. X        result->x = lt2;
  13083. X    }
  13084. X    exp >>= 1;
  13085. X    }
  13086. X    if(result->x == 0 && result->y == 0)
  13087. X       overflow = 1;
  13088. X    return(overflow);
  13089. X}
  13090. X#if 0
  13091. Xz_to_the_z(_CMPLX *z, _CMPLX *out)
  13092. X{
  13093. X    static _CMPLX tmp1,tmp2;
  13094. X    /* raises complex z to the z power */
  13095. X    int errno_xxx;
  13096. X    errno_xxx = 0;
  13097. X
  13098. X    if(fabs(z->x) < DBL_EPSILON) return(-1);
  13099. X
  13100. X    /* log(x + iy) = 1/2(log(x*x + y*y) + i(arc_tan(y/x)) */
  13101. X    tmp1.x = .5*log(sqr(z->x)+sqr(z->y));
  13102. X
  13103. X    /* the fabs in next line added to prevent discontinuity in image */
  13104. X    tmp1.y = atan(fabs(z->y/z->x));
  13105. X
  13106. X    /* log(z)*z */
  13107. X    tmp2.x = tmp1.x * z->x - tmp1.y * z->y;
  13108. X    tmp2.y = tmp1.x * z->y + tmp1.y * z->x;
  13109. X
  13110. X    /* z*z = e**(log(z)*z) */
  13111. X    /* e**(x + iy) =  e**x * (cos(y) + isin(y)) */
  13112. X
  13113. X    tmpexp = exp(tmp2.x);
  13114. X
  13115. X    FPUsincos(&tmp2.y,&siny,&cosy);
  13116. X    out->x = tmpexp*cosy;
  13117. X    out->y = tmpexp*siny;
  13118. X    return(errno_xxx);
  13119. X}
  13120. X#endif
  13121. X
  13122. Xint complex_div(_CMPLX arg1,_CMPLX arg2,_CMPLX *pz);
  13123. Xint complex_mult(_CMPLX arg1,_CMPLX arg2,_CMPLX *pz);
  13124. X
  13125. X#ifdef XFRACT /* fractint uses the NewtonFractal2 code in newton.asm */
  13126. X
  13127. X/* Distance of complex z from unit circle */
  13128. X#define DIST1(z) (((z).x-1.0)*((z).x-1.0)+((z).y)*((z).y))
  13129. X#define LDIST1(z) (lsqr((((z).x)-fudge)) + lsqr(((z).y)))
  13130. X
  13131. X
  13132. Xint NewtonFractal2()
  13133. X{
  13134. X    static char start=1;
  13135. X    if(start)
  13136. X    {
  13137. X       start = 0;
  13138. X    }
  13139. X    cpower(&old, degree-1, &tmp);
  13140. X    complex_mult(tmp, old, &new);
  13141. X
  13142. X    if (DIST1(new) < threshold)
  13143. X    {
  13144. X       if(fractype==NEWTBASIN || fractype==MPNEWTBASIN)
  13145. X       {
  13146. X      int tmpcolor;
  13147. X      int i;
  13148. X      tmpcolor = -1;
  13149. X      /* this code determines which degree-th root of root the
  13150. X         Newton formula converges to. The roots of a 1 are
  13151. X         distributed on a circle of radius 1 about the origin. */
  13152. X      for(i=0;i<degree;i++)
  13153. X         /* color in alternating shades with iteration according to
  13154. X        which root of 1 it converged to */
  13155. X          if(distance(roots[i],old) < threshold)
  13156. X          {
  13157. X          if (basin==2) {
  13158. X                  tmpcolor = 1+(i&7)+((color&1)<<3);
  13159. X          } else {
  13160. X              tmpcolor = 1+i;
  13161. X          }
  13162. X          break;
  13163. X          }
  13164. X       if(tmpcolor == -1)
  13165. X          color = maxcolor;
  13166. X       else
  13167. X          color = tmpcolor;
  13168. X       }
  13169. X       return(1);
  13170. X    }
  13171. X    new.x = d1overd * new.x + roverd;
  13172. X    new.y *= d1overd;
  13173. X
  13174. X    /* Watch for divide underflow */
  13175. X    if ((t2 = tmp.x * tmp.x + tmp.y * tmp.y) < FLT_MIN)
  13176. X      return(1);
  13177. X    else
  13178. X    {
  13179. X    t2 = 1.0 / t2;
  13180. X    old.x = t2 * (new.x * tmp.x + new.y * tmp.y);
  13181. X    old.y = t2 * (new.y * tmp.x - new.x * tmp.y);
  13182. X    }
  13183. X    return(0);
  13184. X}
  13185. X
  13186. X
  13187. X
  13188. X#endif /* newton code only used by xfractint */
  13189. X
  13190. Xcomplex_mult(arg1,arg2,pz)
  13191. X_CMPLX arg1,arg2,*pz;
  13192. X{
  13193. X   pz->x = arg1.x*arg2.x - arg1.y*arg2.y;
  13194. X   pz->y = arg1.x*arg2.y+arg1.y*arg2.x;
  13195. X   return(0);
  13196. X}
  13197. X
  13198. X
  13199. Xcomplex_div(numerator,denominator,pout)
  13200. X_CMPLX numerator,denominator,*pout;
  13201. X{
  13202. X   double mod;
  13203. X   if((mod = modulus(denominator)) < FLT_MIN)
  13204. X      return(1);
  13205. X   conjugate(&denominator);
  13206. X   complex_mult(numerator,denominator,pout);
  13207. X   pout->x = pout->x/mod;
  13208. X   pout->y = pout->y/mod;
  13209. X   return(0);
  13210. X}
  13211. X
  13212. X#ifndef XFRACT
  13213. Xstruct MP mproverd, mpd1overd, mpthreshold,sqrmpthreshold;
  13214. Xstruct MP mpt2;
  13215. Xstruct MP mpone;
  13216. Xextern struct MPC MPCone;
  13217. Xextern int MPOverflow;
  13218. X#endif
  13219. X
  13220. Xint MPCNewtonFractal()
  13221. X{
  13222. X#ifndef XFRACT
  13223. X    MPOverflow = 0;
  13224. X    mpctmp   = MPCpow(mpcold,degree-1);
  13225. X
  13226. X    mpcnew.x = *pMPsub(*pMPmul(mpctmp.x,mpcold.x),*pMPmul(mpctmp.y,mpcold.y));
  13227. X    mpcnew.y = *pMPadd(*pMPmul(mpctmp.x,mpcold.y),*pMPmul(mpctmp.y,mpcold.x));
  13228. X    mpctmp1.x = *pMPsub(mpcnew.x, MPCone.x);
  13229. X    mpctmp1.y = *pMPsub(mpcnew.y, MPCone.y);
  13230. X    if(pMPcmp(MPCmod(mpctmp1),mpthreshold)< 0)
  13231. X    {
  13232. X      if(fractype==MPNEWTBASIN)
  13233. X      {
  13234. X     int tmpcolor;
  13235. X     int i;
  13236. X     tmpcolor = -1;
  13237. X     for(i=0;i<degree;i++)
  13238. X         if(pMPcmp(MPdistance(MPCroots[i],mpcold),mpthreshold) < 0)
  13239. X         {
  13240. X        if(basin==2)
  13241. X           tmpcolor = 1+(i&7) + ((color&1)<<3);
  13242. X        else
  13243. X           tmpcolor = 1+i;
  13244. X            break;
  13245. X         }
  13246. X      if(tmpcolor == -1)
  13247. X         color = maxcolor;
  13248. X      else
  13249. X         color = tmpcolor;
  13250. X      }
  13251. X       return(1);
  13252. X    }
  13253. X
  13254. X    mpcnew.x = *pMPadd(*pMPmul(mpd1overd,mpcnew.x),mproverd);
  13255. X    mpcnew.y = *pMPmul(mpcnew.y,mpd1overd);
  13256. X    mpt2 = MPCmod(mpctmp);
  13257. X    mpt2 = *pMPdiv(mpone,mpt2);
  13258. X    mpcold.x = *pMPmul(mpt2,(*pMPadd(*pMPmul(mpcnew.x,mpctmp.x),*pMPmul(mpcnew.y,mpctmp.y))));
  13259. X    mpcold.y = *pMPmul(mpt2,(*pMPsub(*pMPmul(mpcnew.y,mpctmp.x),*pMPmul(mpcnew.x,mpctmp.y))));
  13260. X    new.x = *pMP2d(mpcold.x);
  13261. X    new.y = *pMP2d(mpcold.y);
  13262. X    return(MPOverflow);
  13263. X#endif
  13264. X}
  13265. X
  13266. X
  13267. XBarnsley1Fractal()
  13268. X{
  13269. X#ifndef XFRACT
  13270. X   /* Barnsley's Mandelbrot type M1 from "Fractals
  13271. X   Everywhere" by Michael Barnsley, p. 322 */
  13272. X
  13273. X   /* calculate intermediate products */
  13274. X   oldxinitx   = multiply(lold.x, longparm->x, bitshift);
  13275. X   oldyinity   = multiply(lold.y, longparm->y, bitshift);
  13276. X   oldxinity   = multiply(lold.x, longparm->y, bitshift);
  13277. X   oldyinitx   = multiply(lold.y, longparm->x, bitshift);
  13278. X   /* orbit calculation */
  13279. X   if(lold.x >= 0)
  13280. X   {
  13281. X      lnew.x = (oldxinitx - longparm->x - oldyinity);
  13282. X      lnew.y = (oldyinitx - longparm->y + oldxinity);
  13283. X   }
  13284. X   else
  13285. X   {
  13286. X      lnew.x = (oldxinitx + longparm->x - oldyinity);
  13287. X      lnew.y = (oldyinitx + longparm->y + oldxinity);
  13288. X   }
  13289. X   return(longbailout());
  13290. X#endif
  13291. X}
  13292. X
  13293. XBarnsley1FPFractal()
  13294. X{
  13295. X   /* Barnsley's Mandelbrot type M1 from "Fractals
  13296. X   Everywhere" by Michael Barnsley, p. 322 */
  13297. X   /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */
  13298. X
  13299. X   /* calculate intermediate products */
  13300. X   foldxinitx = old.x * floatparm->x;
  13301. X   foldyinity = old.y * floatparm->y;
  13302. X   foldxinity = old.x * floatparm->y;
  13303. X   foldyinitx = old.y * floatparm->x;
  13304. X   /* orbit calculation */
  13305. X   if(old.x >= 0)
  13306. X   {
  13307. X      new.x = (foldxinitx - floatparm->x - foldyinity);
  13308. X      new.y = (foldyinitx - floatparm->y + foldxinity);
  13309. X   }
  13310. X   else
  13311. X   {
  13312. X      new.x = (foldxinitx + floatparm->x - foldyinity);
  13313. X      new.y = (foldyinitx + floatparm->y + foldxinity);
  13314. X   }
  13315. X   return(floatbailout());
  13316. X}
  13317. X
  13318. XBarnsley2Fractal()
  13319. X{
  13320. X#ifndef XFRACT
  13321. X   /* An unnamed Mandelbrot/Julia function from "Fractals
  13322. X   Everywhere" by Michael Barnsley, p. 331, example 4.2 */
  13323. X   /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */
  13324. X
  13325. X   /* calculate intermediate products */
  13326. X   oldxinitx   = multiply(lold.x, longparm->x, bitshift);
  13327. X   oldyinity   = multiply(lold.y, longparm->y, bitshift);
  13328. X   oldxinity   = multiply(lold.x, longparm->y, bitshift);
  13329. X   oldyinitx   = multiply(lold.y, longparm->x, bitshift);
  13330. X
  13331. X   /* orbit calculation */
  13332. X   if(oldxinity + oldyinitx >= 0)
  13333. X   {
  13334. X      lnew.x = oldxinitx - longparm->x - oldyinity;
  13335. X      lnew.y = oldyinitx - longparm->y + oldxinity;
  13336. X   }
  13337. X   else
  13338. X   {
  13339. X      lnew.x = oldxinitx + longparm->x - oldyinity;
  13340. X      lnew.y = oldyinitx + longparm->y + oldxinity;
  13341. X   }
  13342. X   return(longbailout());
  13343. X#endif
  13344. X}
  13345. X
  13346. XBarnsley2FPFractal()
  13347. X{
  13348. X   /* An unnamed Mandelbrot/Julia function from "Fractals
  13349. X   Everywhere" by Michael Barnsley, p. 331, example 4.2 */
  13350. X
  13351. X   /* calculate intermediate products */
  13352. X   foldxinitx = old.x * floatparm->x;
  13353. X   foldyinity = old.y * floatparm->y;
  13354. X   foldxinity = old.x * floatparm->y;
  13355. X   foldyinitx = old.y * floatparm->x;
  13356. X
  13357. X   /* orbit calculation */
  13358. X   if(foldxinity + foldyinitx >= 0)
  13359. X   {
  13360. X      new.x = foldxinitx - floatparm->x - foldyinity;
  13361. X      new.y = foldyinitx - floatparm->y + foldxinity;
  13362. X   }
  13363. X   else
  13364. X   {
  13365. X      new.x = foldxinitx + floatparm->x - foldyinity;
  13366. X      new.y = foldyinitx + floatparm->y + foldxinity;
  13367. X   }
  13368. X   return(floatbailout());
  13369. X}
  13370. X
  13371. XJuliaFractal()
  13372. X{
  13373. X#ifndef XFRACT
  13374. X   /* used for C prototype of fast integer math routines for classic
  13375. X      Mandelbrot and Julia */
  13376. X   lnew.x  = ltempsqrx - ltempsqry + longparm->x;
  13377. X   lnew.y = multiply(lold.x, lold.y, bitshiftless1) + longparm->y;
  13378. X   return(longbailout());
  13379. X#elif !defined(__386BSD__)
  13380. X   fprintf(stderr,"JuliaFractal called\n");
  13381. X   exit(-1);
  13382. X#endif
  13383. X}
  13384. X
  13385. XJuliafpFractal()
  13386. X{
  13387. X   /* floating point version of classical Mandelbrot/Julia */
  13388. X   /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */
  13389. X   new.x = tempsqrx - tempsqry + floatparm->x;
  13390. X   new.y = 2.0 * old.x * old.y + floatparm->y;
  13391. X   return(floatbailout());
  13392. X}
  13393. X
  13394. Xstatic double f(double x, double y)
  13395. X{
  13396. X   return(x - x*y);
  13397. X}
  13398. X
  13399. Xstatic double g(double x, double y)
  13400. X{
  13401. X   return(-y + x*y);
  13402. X}
  13403. X
  13404. XLambdaFPFractal()
  13405. X{
  13406. X   /* variation of classical Mandelbrot/Julia */
  13407. X   /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */
  13408. X
  13409. X   tempsqrx = old.x - tempsqrx + tempsqry;
  13410. X   tempsqry = -(old.y * old.x);
  13411. X   tempsqry += tempsqry + old.y;
  13412. X
  13413. X   new.x = floatparm->x * tempsqrx - floatparm->y * tempsqry;
  13414. X   new.y = floatparm->x * tempsqry + floatparm->y * tempsqrx;
  13415. X   return(floatbailout());
  13416. X}
  13417. X
  13418. XLambdaFractal()
  13419. X{
  13420. X#ifndef XFRACT
  13421. X   /* variation of classical Mandelbrot/Julia */
  13422. X
  13423. X   /* in complex math) temp = Z * (1-Z) */
  13424. X   ltempsqrx = lold.x - ltempsqrx + ltempsqry;
  13425. X   ltempsqry = lold.y
  13426. X         - multiply(lold.y, lold.x, bitshiftless1);
  13427. X   /* (in complex math) Z = Lambda * Z */
  13428. X   lnew.x = multiply(longparm->x, ltempsqrx, bitshift)
  13429. X    - multiply(longparm->y, ltempsqry, bitshift);
  13430. X   lnew.y = multiply(longparm->x, ltempsqry, bitshift)
  13431. X    + multiply(longparm->y, ltempsqrx, bitshift);
  13432. X   return(longbailout());
  13433. X#endif
  13434. X}
  13435. X
  13436. XSierpinskiFractal()
  13437. X{
  13438. X#ifndef XFRACT
  13439. X   /* following code translated from basic - see "Fractals
  13440. X   Everywhere" by Michael Barnsley, p. 251, Program 7.1.1 */
  13441. X   lnew.x = (lold.x << 1);        /* new.x = 2 * old.x  */
  13442. X   lnew.y = (lold.y << 1);        /* new.y = 2 * old.y  */
  13443. X   if(lold.y > ltmp.y)    /* if old.y > .5 */
  13444. X      lnew.y = lnew.y - ltmp.x; /* new.y = 2 * old.y - 1 */
  13445. X   else if(lold.x > ltmp.y)    /* if old.x > .5 */
  13446. X      lnew.x = lnew.x - ltmp.x; /* new.x = 2 * old.x - 1 */
  13447. X   /* end barnsley code */
  13448. X   return(longbailout());
  13449. X#endif
  13450. X}
  13451. X
  13452. XSierpinskiFPFractal()
  13453. X{
  13454. X   /* following code translated from basic - see "Fractals
  13455. X   Everywhere" by Michael Barnsley, p. 251, Program 7.1.1 */
  13456. X
  13457. X   new.x = old.x + old.x;
  13458. X   new.y = old.y + old.y;
  13459. X   if(old.y > .5)
  13460. X      new.y = new.y - 1;
  13461. X   else if (old.x > .5)
  13462. X      new.x = new.x - 1;
  13463. X
  13464. X   /* end barnsley code */
  13465. X   return(floatbailout());
  13466. X}
  13467. X
  13468. XLambdaexponentFractal()
  13469. X{
  13470. X   /* found this in  "Science of Fractal Images" */
  13471. X   FLOATEXPBAILOUT();
  13472. X   FPUsincos  (&old.y,&siny,&cosy);
  13473. X
  13474. X   if (old.x >= rqlim && cosy >= 0.0) return(1);
  13475. X   tmpexp = exp(old.x);
  13476. X   tmp.x = tmpexp*cosy;
  13477. X   tmp.y = tmpexp*siny;
  13478. X
  13479. X   /*multiply by lamda */
  13480. X   new.x = floatparm->x*tmp.x - floatparm->y*tmp.y;
  13481. X   new.y = floatparm->y*tmp.x + floatparm->x*tmp.y;
  13482. X   old = new;
  13483. X   return(0);
  13484. X}
  13485. X
  13486. XLongLambdaexponentFractal()
  13487. X{
  13488. X#ifndef XFRACT
  13489. X   /* found this in  "Science of Fractal Images" */
  13490. X   LONGEXPBAILOUT();
  13491. X
  13492. X   SinCos086  (lold.y, &lsiny,    &lcosy);
  13493. X
  13494. X   if (lold.x >= llimit && lcosy >= 0L) return(1);
  13495. X   longtmp = Exp086(lold.x);
  13496. X
  13497. X   ltmp.x = multiply(longtmp,       lcosy,   bitshift);
  13498. X   ltmp.y = multiply(longtmp,       lsiny,   bitshift);
  13499. X
  13500. X   lnew.x  = multiply(longparm->x, ltmp.x, bitshift)
  13501. X       - multiply(longparm->y, ltmp.y, bitshift);
  13502. X   lnew.y  = multiply(longparm->x, ltmp.y, bitshift)
  13503. X       + multiply(longparm->y, ltmp.x, bitshift);
  13504. X   lold = lnew;
  13505. X   return(0);
  13506. X#endif
  13507. X}
  13508. X
  13509. XFloatTrigPlusExponentFractal()
  13510. X{
  13511. X   /* another Scientific American biomorph type */
  13512. X   /* z(n+1) = e**z(n) + trig(z(n)) + C */
  13513. X
  13514. X   if (fabs(old.x) >= 6.4e2) return(1); /* DOMAIN errors */
  13515. X   tmpexp = exp(old.x);
  13516. X   FPUsincos  (&old.y,&siny,&cosy);
  13517. X   CMPLXtrig0(old,new);
  13518. X
  13519. X   /*new =   trig(old) + e**old + C  */
  13520. X   new.x += tmpexp*cosy + floatparm->x;
  13521. X   new.y += tmpexp*siny + floatparm->y;
  13522. X   return(floatbailout());
  13523. X}
  13524. X
  13525. X
  13526. XLongTrigPlusExponentFractal()
  13527. X{
  13528. X#ifndef XFRACT
  13529. X   /* calculate exp(z) */
  13530. X
  13531. X   /* domain check for fast transcendental functions */
  13532. X   TRIG16CHECK(lold.x);
  13533. X   TRIG16CHECK(lold.y);
  13534. X
  13535. X   longtmp = Exp086(lold.x);
  13536. X   SinCos086  (lold.y, &lsiny,    &lcosy);
  13537. X   LCMPLXtrig0(lold,lnew);
  13538. X   lnew.x += multiply(longtmp,      lcosy,   bitshift) + longparm->x;
  13539. X   lnew.y += multiply(longtmp,      lsiny,   bitshift) + longparm->y;
  13540. X   return(longbailout());
  13541. X#endif
  13542. X}
  13543. X
  13544. XMarksLambdaFractal()
  13545. X{
  13546. X   /* Mark Peterson's variation of "lambda" function */
  13547. X
  13548. X   /* Z1 = (C^(exp-1) * Z**2) + C */
  13549. X   ltmp.x = ltempsqrx - ltempsqry;
  13550. X   ltmp.y = multiply(lold.x ,lold.y ,bitshiftless1);
  13551. X
  13552. X   lnew.x = multiply(lcoefficient.x, ltmp.x, bitshift)
  13553. X    - multiply(lcoefficient.y, ltmp.y, bitshift) + longparm->x;
  13554. X   lnew.y = multiply(lcoefficient.x, ltmp.y, bitshift)
  13555. X    + multiply(lcoefficient.y, ltmp.x, bitshift) + longparm->y;
  13556. X
  13557. X   return(longbailout());
  13558. X}
  13559. X
  13560. XMarksLambdafpFractal()
  13561. X{
  13562. X   /* Mark Peterson's variation of "lambda" function */
  13563. X
  13564. X   /* Z1 = (C^(exp-1) * Z**2) + C */
  13565. X   tmp.x = tempsqrx - tempsqry;
  13566. X   tmp.y = old.x * old.y *2;
  13567. X
  13568. X   new.x = coefficient.x * tmp.x - coefficient.y * tmp.y + floatparm->x;
  13569. X   new.y = coefficient.x * tmp.y + coefficient.y * tmp.x + floatparm->y;
  13570. X
  13571. X   return(floatbailout());
  13572. X}
  13573. X
  13574. X
  13575. Xlong XXOne, FgOne, FgTwo;
  13576. X
  13577. XUnityFractal()
  13578. X{
  13579. X#ifndef XFRACT
  13580. X   /* brought to you by Mark Peterson - you won't find this in any fractal
  13581. X      books unless they saw it here first - Mark invented it! */
  13582. X   XXOne = multiply(lold.x, lold.x, bitshift) + multiply(lold.y, lold.y, bitshift);
  13583. X   if((XXOne > FgTwo) || (labs(XXOne - FgOne) < delmin))
  13584. X      return(1);
  13585. X   lold.y = multiply(FgTwo - XXOne, lold.x, bitshift);
  13586. X   lold.x = multiply(FgTwo - XXOne, lold.y, bitshift);
  13587. X   lnew=lold;  /* TW added this line */
  13588. X   return(0);
  13589. X#endif
  13590. X}
  13591. X
  13592. X#define XXOne new.x
  13593. X
  13594. XUnityfpFractal()
  13595. X{
  13596. X   /* brought to you by Mark Peterson - you won't find this in any fractal
  13597. X      books unless they saw it here first - Mark invented it! */
  13598. X
  13599. X   XXOne = sqr(old.x) + sqr(old.y);
  13600. X   if((XXOne > 2.0) || (fabs(XXOne - 1.0) < ddelmin))
  13601. X      return(1);
  13602. X   old.y = (2.0 - XXOne)* old.x;
  13603. X   old.x = (2.0 - XXOne)* old.y;
  13604. X   new=old;  /* TW added this line */
  13605. X   return(0);
  13606. X}
  13607. X
  13608. X#undef XXOne
  13609. X
  13610. XMandel4Fractal()
  13611. X{
  13612. X   /* By writing this code, Bert has left behind the excuse "don't
  13613. X      know what a fractal is, just know how to make'em go fast".
  13614. X      Bert is hereby declared a bonafide fractal expert! Supposedly
  13615. X      this routine calculates the Mandelbrot/Julia set based on the
  13616. X      polynomial z**4 + lambda, but I wouldn't know -- can't follow
  13617. X      all that integer math speedup stuff - Tim */
  13618. X
  13619. X   /* first, compute (x + iy)**2 */
  13620. X   lnew.x  = ltempsqrx - ltempsqry;
  13621. X   lnew.y = multiply(lold.x, lold.y, bitshiftless1);
  13622. X   if (longbailout()) return(1);
  13623. X
  13624. X   /* then, compute ((x + iy)**2)**2 + lambda */
  13625. X   lnew.x  = ltempsqrx - ltempsqry + longparm->x;
  13626. X   lnew.y = multiply(lold.x, lold.y, bitshiftless1) + longparm->y;
  13627. X   return(longbailout());
  13628. X}
  13629. X
  13630. XMandel4fpFractal()
  13631. X{
  13632. X   /* first, compute (x + iy)**2 */
  13633. X   new.x  = tempsqrx - tempsqry;
  13634. X   new.y = old.x*old.y*2;
  13635. X   if (floatbailout()) return(1);
  13636. X
  13637. X   /* then, compute ((x + iy)**2)**2 + lambda */
  13638. X   new.x  = tempsqrx - tempsqry + floatparm->x;
  13639. X   new.y =  old.x*old.y*2 + floatparm->y;
  13640. X   return(floatbailout());
  13641. X}
  13642. X
  13643. XfloatZtozPluszpwrFractal()
  13644. X{
  13645. X   cpower(&old,(int)param[2],&new);
  13646. X   old = ComplexPower(old,old);
  13647. X   new.x = new.x + old.x +floatparm->x;
  13648. X   new.y = new.y + old.y +floatparm->y;
  13649. X   return(floatbailout());
  13650. X}
  13651. X
  13652. XlongZpowerFractal()
  13653. X{
  13654. X#ifndef XFRACT
  13655. X   if(lcpower(&lold,c_exp,&lnew,bitshift))
  13656. X      lnew.x = lnew.y = 8L<<bitshift;
  13657. X   lnew.x += longparm->x;
  13658. X   lnew.y += longparm->y;
  13659. X   return(longbailout());
  13660. X#endif
  13661. X}
  13662. X
  13663. XlongCmplxZpowerFractal()
  13664. X{
  13665. X#ifndef XFRACT
  13666. X   _CMPLX x, y;
  13667. X
  13668. X   x.x = (double)lold.x / fudge;
  13669. X   x.y = (double)lold.y / fudge;
  13670. X   y.x = (double)lparm2.x / fudge;
  13671. X   y.y = (double)lparm2.y / fudge;
  13672. X   x = ComplexPower(x, y);
  13673. X   if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  13674. X      lnew.x = (long)(x.x * fudge);
  13675. X      lnew.y = (long)(x.y * fudge);
  13676. X   }
  13677. X   else
  13678. X      overflow = 1;
  13679. X   lnew.x += longparm->x;
  13680. X   lnew.y += longparm->y;
  13681. X   return(longbailout());
  13682. X#endif
  13683. X}
  13684. X
  13685. XfloatZpowerFractal()
  13686. X{
  13687. X   cpower(&old,c_exp,&new);
  13688. X   new.x += floatparm->x;
  13689. X   new.y += floatparm->y;
  13690. X   return(floatbailout());
  13691. X}
  13692. X
  13693. XfloatCmplxZpowerFractal()
  13694. X{
  13695. X   new = ComplexPower(old, parm2);
  13696. X   new.x += floatparm->x;
  13697. X   new.y += floatparm->y;
  13698. X   return(floatbailout());
  13699. X}
  13700. X
  13701. XBarnsley3Fractal()
  13702. X{
  13703. X   /* An unnamed Mandelbrot/Julia function from "Fractals
  13704. X   Everywhere" by Michael Barnsley, p. 292, example 4.1 */
  13705. X
  13706. X   /* calculate intermediate products */
  13707. X   oldxinitx   = multiply(lold.x, lold.x, bitshift);
  13708. X   oldyinity   = multiply(lold.y, lold.y, bitshift);
  13709. X   oldxinity   = multiply(lold.x, lold.y, bitshift);
  13710. X
  13711. X   /* orbit calculation */
  13712. X   if(lold.x > 0)
  13713. X   {
  13714. X      lnew.x = oldxinitx   - oldyinity - fudge;
  13715. X      lnew.y = oldxinity << 1;
  13716. X   }
  13717. X   else
  13718. X   {
  13719. X      lnew.x = oldxinitx - oldyinity - fudge
  13720. X       + multiply(longparm->x,lold.x,bitshift);
  13721. X      lnew.y = oldxinity <<1;
  13722. X
  13723. X      /* This term added by Tim Wegner to make dependent on the
  13724. X     imaginary part of the parameter. (Otherwise Mandelbrot
  13725. X     is uninteresting. */
  13726. X      lnew.y += multiply(longparm->y,lold.x,bitshift);
  13727. X   }
  13728. X   return(longbailout());
  13729. X}
  13730. X
  13731. XBarnsley3FPFractal()
  13732. X{
  13733. X   /* An unnamed Mandelbrot/Julia function from "Fractals
  13734. X   Everywhere" by Michael Barnsley, p. 292, example 4.1 */
  13735. X
  13736. X
  13737. X   /* calculate intermediate products */
  13738. X   foldxinitx  = old.x * old.x;
  13739. X   foldyinity  = old.y * old.y;
  13740. X   foldxinity  = old.x * old.y;
  13741. X
  13742. X   /* orbit calculation */
  13743. X   if(old.x > 0)
  13744. X   {
  13745. X      new.x = foldxinitx - foldyinity - 1.0;
  13746. X      new.y = foldxinity * 2;
  13747. X   }
  13748. X   else
  13749. X   {
  13750. X      new.x = foldxinitx - foldyinity -1.0 + floatparm->x * old.x;
  13751. X      new.y = foldxinity * 2;
  13752. X
  13753. X      /* This term added by Tim Wegner to make dependent on the
  13754. X     imaginary part of the parameter. (Otherwise Mandelbrot
  13755. X     is uninteresting. */
  13756. X      new.y += floatparm->y * old.x;
  13757. X   }
  13758. X   return(floatbailout());
  13759. X}
  13760. X
  13761. XTrigPlusZsquaredFractal()
  13762. X{
  13763. X#ifndef XFRACT
  13764. X   /* From Scientific American, July 1989 */
  13765. X   /* A Biomorph              */
  13766. X   /* z(n+1) = trig(z(n))+z(n)**2+C      */
  13767. X   LCMPLXtrig0(lold,lnew);
  13768. X   lnew.x += ltempsqrx - ltempsqry + longparm->x;
  13769. X   lnew.y += multiply(lold.x, lold.y, bitshiftless1) + longparm->y;
  13770. X   return(longbailout());
  13771. X#endif
  13772. X}
  13773. X
  13774. XTrigPlusZsquaredfpFractal()
  13775. X{
  13776. X   /* From Scientific American, July 1989 */
  13777. X   /* A Biomorph              */
  13778. X   /* z(n+1) = trig(z(n))+z(n)**2+C      */
  13779. X
  13780. X   CMPLXtrig0(old,new);
  13781. X   new.x += tempsqrx - tempsqry + floatparm->x;
  13782. X   new.y += 2.0 * old.x * old.y + floatparm->y;
  13783. X   return(floatbailout());
  13784. X}
  13785. X
  13786. XRichard8fpFractal()
  13787. X{
  13788. X   /*  Richard8 {c = z = pixel: z=sin(z)+sin(pixel),|z|<=50} */
  13789. X   CMPLXtrig0(old,new);
  13790. X/*   CMPLXtrig1(*floatparm,tmp); */
  13791. X   new.x += tmp.x;
  13792. X   new.y += tmp.y;
  13793. X   return(floatbailout());
  13794. X}
  13795. X
  13796. XRichard8Fractal()
  13797. X{
  13798. X#ifndef XFRACT
  13799. X   /*  Richard8 {c = z = pixel: z=sin(z)+sin(pixel),|z|<=50} */
  13800. X   LCMPLXtrig0(lold,lnew);
  13801. X/*   LCMPLXtrig1(*longparm,ltmp); */
  13802. X   lnew.x += ltmp.x;
  13803. X   lnew.y += ltmp.y;
  13804. X   return(longbailout());
  13805. X#endif
  13806. X}
  13807. X
  13808. XPopcornFractal()
  13809. X{
  13810. X   extern int row;
  13811. X   tmp = old;
  13812. X   tmp.x *= 3.0;
  13813. X   tmp.y *= 3.0;
  13814. X   FPUsincos(&tmp.x,&sinx,&cosx);
  13815. X   FPUsincos(&tmp.y,&siny,&cosy);
  13816. X   tmp.x = sinx/cosx + old.x;
  13817. X   tmp.y = siny/cosy + old.y;
  13818. X   FPUsincos(&tmp.x,&sinx,&cosx);
  13819. X   FPUsincos(&tmp.y,&siny,&cosy);
  13820. X   new.x = old.x - parm.x*siny;
  13821. X   new.y = old.y - parm.x*sinx;
  13822. X   /*
  13823. X   new.x = old.x - parm.x*sin(old.y+tan(3*old.y));
  13824. X   new.y = old.y - parm.x*sin(old.x+tan(3*old.x));
  13825. X   */
  13826. X   if(plot == noplot)
  13827. X   {
  13828. X      plot_orbit(new.x,new.y,1+row%colors);
  13829. X      old = new;
  13830. X   }
  13831. X   else
  13832. X   /* FLOATBAILOUT(); */
  13833. X   /* PB The above line was weird, not what it seems to be!  But, bracketing
  13834. X     it or always doing it (either of which seem more likely to be what
  13835. X     was intended) changes the image for the worse, so I'm not touching it.
  13836. X     Same applies to int form in next routine. */
  13837. X   /* PB later: recoded inline, still leaving it weird */
  13838. X      tempsqrx = sqr(new.x);
  13839. X   tempsqry = sqr(new.y);
  13840. X   if((magnitude = tempsqrx + tempsqry) >= rqlim) return(1);
  13841. X   old = new;
  13842. X   return(0);
  13843. X}
  13844. X
  13845. XLPopcornFractal()
  13846. X{
  13847. X#ifndef XFRACT
  13848. X   extern int row;
  13849. X   ltmp = lold;
  13850. X   ltmp.x *= 3L;
  13851. X   ltmp.y *= 3L;
  13852. X   LTRIGARG(ltmp.x);
  13853. X   LTRIGARG(ltmp.y);
  13854. X   SinCos086(ltmp.x,&lsinx,&lcosx);
  13855. X   SinCos086(ltmp.y,&lsiny,&lcosy);
  13856. X   ltmp.x = divide(lsinx,lcosx,bitshift) + lold.x;
  13857. X   ltmp.y = divide(lsiny,lcosy,bitshift) + lold.y;
  13858. X   LTRIGARG(ltmp.x);
  13859. X   LTRIGARG(ltmp.y);
  13860. X   SinCos086(ltmp.x,&lsinx,&lcosx);
  13861. X   SinCos086(ltmp.y,&lsiny,&lcosy);
  13862. X   lnew.x = lold.x - multiply(lparm.x,lsiny,bitshift);
  13863. X   lnew.y = lold.y - multiply(lparm.x,lsinx,bitshift);
  13864. X   if(plot == noplot)
  13865. X   {
  13866. X      iplot_orbit(lnew.x,lnew.y,1+row%colors);
  13867. X      lold = lnew;
  13868. X   }
  13869. X   else
  13870. X      LONGBAILOUT();
  13871. X   /* PB above still the old way, is weird, see notes in FP popcorn case */
  13872. X   return(0);
  13873. X#endif
  13874. X}
  13875. X
  13876. Xint MarksCplxMand(void)
  13877. X{
  13878. X   tmp.x = tempsqrx - tempsqry;
  13879. X   tmp.y = 2*old.x*old.y;
  13880. X   FPUcplxmul(&tmp, &Coefficient, &new);
  13881. X   new.x += floatparm->x;
  13882. X   new.y += floatparm->y;
  13883. X   return(floatbailout());
  13884. X}
  13885. X
  13886. Xint SpiderfpFractal(void)
  13887. X{
  13888. X   /* Spider(XAXIS) { c=z=pixel: z=z*z+c; c=c/2+z, |z|<=4 } */
  13889. X   new.x = tempsqrx - tempsqry + tmp.x;
  13890. X   new.y = 2 * old.x * old.y + tmp.y;
  13891. X   tmp.x = tmp.x/2 + new.x;
  13892. X   tmp.y = tmp.y/2 + new.y;
  13893. X   return(floatbailout());
  13894. X}
  13895. X
  13896. XSpiderFractal(void)
  13897. X{
  13898. X#ifndef XFRACT
  13899. X   /* Spider(XAXIS) { c=z=pixel: z=z*z+c; c=c/2+z, |z|<=4 } */
  13900. X   lnew.x  = ltempsqrx - ltempsqry + ltmp.x;
  13901. X   lnew.y = multiply(lold.x, lold.y, bitshiftless1) + ltmp.y;
  13902. X   ltmp.x = (ltmp.x >> 1) + lnew.x;
  13903. X   ltmp.y = (ltmp.y >> 1) + lnew.y;
  13904. X   return(longbailout());
  13905. X#endif
  13906. X}
  13907. X
  13908. XTetratefpFractal()
  13909. X{
  13910. X   /* Tetrate(XAXIS) { c=z=pixel: z=c^z, |z|<=(P1+3) } */
  13911. X   new = ComplexPower(*floatparm,old);
  13912. X   return(floatbailout());
  13913. X}
  13914. X
  13915. XZXTrigPlusZFractal()
  13916. X{
  13917. X#ifndef XFRACT
  13918. X   /* z = (p1*z*trig(z))+p2*z */
  13919. X   LCMPLXtrig0(lold,ltmp);        /* ltmp  = trig(old)         */
  13920. X   LCMPLXmult(lparm,ltmp,ltmp);      /* ltmp  = p1*trig(old)          */
  13921. X   LCMPLXmult(lold,ltmp,ltmp2);      /* ltmp2 = p1*old*trig(old)      */
  13922. X   LCMPLXmult(lparm2,lold,ltmp);     /* ltmp  = p2*old              */
  13923. X   LCMPLXadd(ltmp2,ltmp,lnew);         /* lnew  = p1*trig(old) + p2*old */
  13924. X   return(longbailout());
  13925. X#endif
  13926. X}
  13927. X
  13928. XScottZXTrigPlusZFractal()
  13929. X{
  13930. X#ifndef XFRACT
  13931. X   /* z = (z*trig(z))+z */
  13932. X   LCMPLXtrig0(lold,ltmp);        /* ltmp  = trig(old)       */
  13933. X   LCMPLXmult(lold,ltmp,lnew);         /* lnew  = old*trig(old)    */
  13934. X   LCMPLXadd(lnew,lold,lnew);         /* lnew  = trig(old) + old */
  13935. X   return(longbailout());
  13936. X#endif
  13937. X}
  13938. X
  13939. XSkinnerZXTrigSubZFractal()
  13940. X{
  13941. X#ifndef XFRACT
  13942. X   /* z = (z*trig(z))-z */
  13943. X   LCMPLXtrig0(lold,ltmp);        /* ltmp  = trig(old)       */
  13944. X   LCMPLXmult(lold,ltmp,lnew);         /* lnew  = old*trig(old)    */
  13945. X   LCMPLXsub(lnew,lold,lnew);         /* lnew  = trig(old) - old */
  13946. X   return(longbailout());
  13947. X#endif
  13948. X}
  13949. X
  13950. XZXTrigPlusZfpFractal()
  13951. X{
  13952. X   /* z = (p1*z*trig(z))+p2*z */
  13953. X   CMPLXtrig0(old,tmp);      /* tmp  = trig(old)         */
  13954. X   CMPLXmult(parm,tmp,tmp);     /* tmp  = p1*trig(old)      */
  13955. X   CMPLXmult(old,tmp,tmp2);     /* tmp2 = p1*old*trig(old)     */
  13956. X   CMPLXmult(parm2,old,tmp);     /* tmp  = p2*old         */
  13957. X   CMPLXadd(tmp2,tmp,new);     /* new  = p1*trig(old) + p2*old */
  13958. X   return(floatbailout());
  13959. X}
  13960. X
  13961. XScottZXTrigPlusZfpFractal()
  13962. X{
  13963. X   /* z = (z*trig(z))+z */
  13964. X   CMPLXtrig0(old,tmp);     /* tmp    = trig(old)      */
  13965. X   CMPLXmult(old,tmp,new);     /* new  = old*trig(old)   */
  13966. X   CMPLXadd(new,old,new);     /* new  = trig(old) + old */
  13967. X   return(floatbailout());
  13968. X}
  13969. X
  13970. XSkinnerZXTrigSubZfpFractal()
  13971. X{
  13972. X   /* z = (z*trig(z))-z */
  13973. X   CMPLXtrig0(old,tmp);     /* tmp    = trig(old)      */
  13974. X   CMPLXmult(old,tmp,new);     /* new  = old*trig(old)   */
  13975. X   CMPLXsub(new,old,new);     /* new  = trig(old) - old */
  13976. X   return(floatbailout());
  13977. X}
  13978. X
  13979. XSqr1overTrigFractal()
  13980. X{
  13981. X#ifndef XFRACT
  13982. X   /* z = sqr(1/trig(z)) */
  13983. X   LCMPLXtrig0(lold,lold);
  13984. X   LCMPLXrecip(lold,lold);
  13985. X   LCMPLXsqr(lold,lnew);
  13986. X   return(longbailout());
  13987. X#endif
  13988. X}
  13989. X
  13990. XSqr1overTrigfpFractal()
  13991. X{
  13992. X   /* z = sqr(1/trig(z)) */
  13993. X   CMPLXtrig0(old,old);
  13994. X   CMPLXrecip(old,old);
  13995. X   CMPLXsqr(old,new);
  13996. X   return(floatbailout());
  13997. X}
  13998. X
  13999. XTrigPlusTrigFractal()
  14000. X{
  14001. X#ifndef XFRACT
  14002. X   /* z = trig(0,z)*p1+trig1(z)*p2 */
  14003. X   LCMPLXtrig0(lold,ltmp);
  14004. X   LCMPLXmult(lparm,ltmp,ltmp);
  14005. X   LCMPLXtrig1(lold,ltmp2);
  14006. X   LCMPLXmult(lparm2,ltmp2,lold);
  14007. X   LCMPLXadd(ltmp,lold,lnew);
  14008. X   return(longbailout());
  14009. X#endif
  14010. X}
  14011. X
  14012. XTrigPlusTrigfpFractal()
  14013. X{
  14014. X   /* z = trig0(z)*p1+trig1(z)*p2 */
  14015. X   CMPLXtrig0(old,tmp);
  14016. X   CMPLXmult(parm,tmp,tmp);
  14017. X   CMPLXtrig1(old,old);
  14018. X   CMPLXmult(parm2,old,old);
  14019. X   CMPLXadd(tmp,old,new);
  14020. X   return(floatbailout());
  14021. X}
  14022. X
  14023. X/* The following four fractals are based on the idea of parallel
  14024. X   or alternate calculations.  The shift is made when the mod
  14025. X   reaches a given value.  JCO  5/6/92 */
  14026. X
  14027. XLambdaTrigOrTrigFractal()
  14028. X{
  14029. X#ifndef XFRACT
  14030. X   /* z = trig0(z)*p1 if mod(old) < p2.x and
  14031. X          trig1(z)*p1 if mod(old) >= p2.x */
  14032. X   if ((LCMPLXmod(lold)) < lparm2.x){
  14033. X     LCMPLXtrig0(lold,ltmp);
  14034. X     LCMPLXmult(*longparm,ltmp,lnew);}
  14035. X   else{
  14036. X     LCMPLXtrig1(lold,ltmp);
  14037. X     LCMPLXmult(*longparm,ltmp,lnew);}
  14038. X   return(longbailout());
  14039. X#endif
  14040. X}
  14041. X
  14042. XLambdaTrigOrTrigfpFractal()
  14043. X{
  14044. X   /* z = trig0(z)*p1 if mod(old) < p2.x and
  14045. X          trig1(z)*p1 if mod(old) >= p2.x */
  14046. X   if (CMPLXmod(old) < parm2.x){
  14047. X     CMPLXtrig0(old,old);
  14048. X     FPUcplxmul(floatparm,&old,&new);}
  14049. X   else{
  14050. X     CMPLXtrig1(old,old);
  14051. X     FPUcplxmul(floatparm,&old,&new);}
  14052. X   return(floatbailout());
  14053. X}
  14054. X
  14055. XJuliaTrigOrTrigFractal()
  14056. X{
  14057. X#ifndef XFRACT
  14058. X   /* z = trig0(z)+p1 if mod(old) < p2.x and
  14059. X          trig1(z)+p1 if mod(old) >= p2.x */
  14060. X   if (LCMPLXmod(lold) < lparm2.x){
  14061. X     LCMPLXtrig0(lold,ltmp);
  14062. X     LCMPLXadd(*longparm,ltmp,lnew);}
  14063. X   else{
  14064. X     LCMPLXtrig1(lold,ltmp);
  14065. X     LCMPLXadd(*longparm,ltmp,lnew);}
  14066. X   return(longbailout());
  14067. X#endif
  14068. X}
  14069. X
  14070. XJuliaTrigOrTrigfpFractal()
  14071. X{
  14072. X   /* z = trig0(z)+p1 if mod(old) < p2.x and
  14073. X          trig1(z)+p1 if mod(old) >= p2.x */
  14074. X   if (CMPLXmod(old) < parm2.x){
  14075. X     CMPLXtrig0(old,old);
  14076. X     CMPLXadd(*floatparm,old,new);}
  14077. X   else{
  14078. X     CMPLXtrig1(old,old);
  14079. X     CMPLXadd(*floatparm,old,new);}
  14080. X   return(floatbailout());
  14081. X}
  14082. X
  14083. Xstatic int AplusOne, Ap1deg;
  14084. Xstatic struct MP mpAplusOne, mpAp1deg, mptmpparmy;
  14085. X
  14086. Xint MPCHalleyFractal()
  14087. X{
  14088. X#ifndef XFRACT
  14089. X   /*  X(X^a - 1) = 0, Halley Map */
  14090. X   /*  a = parm.x,  relaxation coeff. = parm.y,  epsilon = parm2.x  */
  14091. X
  14092. Xint ihal;
  14093. Xstruct MPC mpcXtoAlessOne, mpcXtoA;
  14094. Xstruct MPC mpcXtoAplusOne; /* a-1, a, a+1 */
  14095. Xstruct MPC mpcFX, mpcF1prime, mpcF2prime, mpcHalnumer1;
  14096. Xstruct MPC mpcHalnumer2, mpcHaldenom, mpctmp;
  14097. X
  14098. X   MPOverflow = 0;
  14099. X   mpcXtoAlessOne.x = mpcold.x;
  14100. X   mpcXtoAlessOne.y = mpcold.y;
  14101. X   for(ihal=2; ihal<degree; ihal++) {
  14102. X     mpctmp.x = *pMPsub(*pMPmul(mpcXtoAlessOne.x,mpcold.x),*pMPmul(mpcXtoAlessOne.y,mpcold.y));
  14103. X     mpctmp.y = *pMPadd(*pMPmul(mpcXtoAlessOne.x,mpcold.y),*pMPmul(mpcXtoAlessOne.y,mpcold.x));
  14104. X     mpcXtoAlessOne.x = mpctmp.x;
  14105. X     mpcXtoAlessOne.y = mpctmp.y;
  14106. X   }
  14107. X   mpcXtoA.x = *pMPsub(*pMPmul(mpcXtoAlessOne.x,mpcold.x),*pMPmul(mpcXtoAlessOne.y,mpcold.y));
  14108. X   mpcXtoA.y = *pMPadd(*pMPmul(mpcXtoAlessOne.x,mpcold.y),*pMPmul(mpcXtoAlessOne.y,mpcold.x));
  14109. X   mpcXtoAplusOne.x = *pMPsub(*pMPmul(mpcXtoA.x,mpcold.x),*pMPmul(mpcXtoA.y,mpcold.y));
  14110. X   mpcXtoAplusOne.y = *pMPadd(*pMPmul(mpcXtoA.x,mpcold.y),*pMPmul(mpcXtoA.y,mpcold.x));
  14111. X
  14112. X   mpcFX.x = *pMPsub(mpcXtoAplusOne.x, mpcold.x);
  14113. X   mpcFX.y = *pMPsub(mpcXtoAplusOne.y, mpcold.y); /* FX = X^(a+1) - X  = F */
  14114. X
  14115. X   mpcF2prime.x = *pMPmul(mpAp1deg, mpcXtoAlessOne.x); /* mpAp1deg in setup */
  14116. X   mpcF2prime.y = *pMPmul(mpAp1deg, mpcXtoAlessOne.y);        /* F" */
  14117. X
  14118. X   mpcF1prime.x = *pMPsub(*pMPmul(mpAplusOne, mpcXtoA.x), mpone);
  14119. X   mpcF1prime.y = *pMPmul(mpAplusOne, mpcXtoA.y);                   /*  F'  */
  14120. X
  14121. X   mpctmp.x = *pMPsub(*pMPmul(mpcF2prime.x,mpcFX.x),*pMPmul(mpcF2prime.y,mpcFX.y));
  14122. X   mpctmp.y = *pMPadd(*pMPmul(mpcF2prime.x,mpcFX.y),*pMPmul(mpcF2prime.y,mpcFX.x));
  14123. X   /*  F * F"  */
  14124. X
  14125. X   mpcHaldenom.x = *pMPadd(mpcF1prime.x, mpcF1prime.x);
  14126. X   mpcHaldenom.y = *pMPadd(mpcF1prime.y, mpcF1prime.y);      /*  2 * F'  */
  14127. X
  14128. X   mpcHalnumer1 = MPCdiv(mpctmp, mpcHaldenom);        /*  F"F/2F'  */
  14129. X   mpctmp.x = *pMPsub(mpcF1prime.x, mpcHalnumer1.x);
  14130. X   mpctmp.y = *pMPsub(mpcF1prime.y, mpcHalnumer1.y); /*  F' - F"F/2F'  */
  14131. X   mpcHalnumer2 = MPCdiv(mpcFX, mpctmp);
  14132. X
  14133. X   mpctmp.x = *pMPmul(mptmpparmy,mpcHalnumer2.x); /* mptmpparmy is */
  14134. X   mpctmp.y = *pMPmul(mptmpparmy,mpcHalnumer2.y); /* relaxation coef. */
  14135. X   mpcnew.x = *pMPsub(mpcold.x, mpctmp.x);
  14136. X   mpcnew.y = *pMPsub(mpcold.y, mpctmp.y);
  14137. X
  14138. X   new.x = *pMP2d(mpcnew.x);
  14139. X   new.y = *pMP2d(mpcnew.y);
  14140. X
  14141. X   return(MPCHalleybailout()||MPOverflow);
  14142. X#endif
  14143. X}
  14144. X
  14145. XHalleyFractal()
  14146. X{
  14147. X   /*  X(X^a - 1) = 0, Halley Map */
  14148. X   /*  a = parm.x = degree, relaxation coeff. = parm.y, epsilon = parm2.x  */
  14149. X
  14150. Xint ihal;
  14151. X_CMPLX XtoAlessOne, XtoA, XtoAplusOne; /* a-1, a, a+1 */
  14152. X_CMPLX FX, F1prime, F2prime, Halnumer1, Halnumer2, Haldenom;
  14153. X
  14154. X   XtoAlessOne = old;
  14155. X   for(ihal=2; ihal<degree; ihal++) {
  14156. X     FPUcplxmul(&old, &XtoAlessOne, &XtoAlessOne);
  14157. X   }
  14158. X   FPUcplxmul(&old, &XtoAlessOne, &XtoA);
  14159. X   FPUcplxmul(&old, &XtoA, &XtoAplusOne);
  14160. X
  14161. X   CMPLXsub(XtoAplusOne, old, FX);        /* FX = X^(a+1) - X  = F */
  14162. X   F2prime.x = Ap1deg * XtoAlessOne.x; /* Ap1deg in setup */
  14163. X   F2prime.y = Ap1deg * XtoAlessOne.y;        /* F" */
  14164. X
  14165. X   F1prime.x = AplusOne * XtoA.x - 1.0;
  14166. X   F1prime.y = AplusOne * XtoA.y;                             /*  F'  */
  14167. X
  14168. X   FPUcplxmul(&F2prime, &FX, &Halnumer1);                  /*  F * F"  */
  14169. X   Haldenom.x = F1prime.x + F1prime.x;
  14170. X   Haldenom.y = F1prime.y + F1prime.y;                     /*  2 * F'  */
  14171. X
  14172. X   FPUcplxdiv(&Halnumer1, &Haldenom, &Halnumer1);         /*  F"F/2F'  */
  14173. X   CMPLXsub(F1prime, Halnumer1, Halnumer2);          /*  F' - F"F/2F'  */
  14174. X   FPUcplxdiv(&FX, &Halnumer2, &Halnumer2);
  14175. X   new.x = old.x - (parm.y * Halnumer2.x); /* parm.y is relaxation coef. */
  14176. X   new.y = old.y - (parm.y * Halnumer2.y);
  14177. X
  14178. X   return(Halleybailout());
  14179. X}
  14180. X
  14181. XLongPhoenixFractal()
  14182. X{
  14183. X#ifndef XFRACT
  14184. X/* z(n+1) = z(n)^2 + p + qy(n),  y(n+1) = z(n) */
  14185. X   ltmp.x = multiply(lold.x, lold.y, bitshift);
  14186. X   lnew.x = ltempsqrx-ltempsqry+longparm->x+multiply(longparm->y,ltmp2.x,bitshift);
  14187. X   lnew.y = (ltmp.x + ltmp.x) + multiply(longparm->y,ltmp2.y,bitshift);
  14188. X   ltmp2 = lold; /* set ltmp2 to Y value */
  14189. X   return(longbailout());
  14190. X#endif
  14191. X}
  14192. X
  14193. XPhoenixFractal()
  14194. X{
  14195. X/* z(n+1) = z(n)^2 + p + qy(n),  y(n+1) = z(n) */
  14196. X   tmp.x = old.x * old.y;
  14197. X   new.x = tempsqrx - tempsqry + floatparm->x + (floatparm->y * tmp2.x);
  14198. X   new.y = (tmp.x + tmp.x) + (floatparm->y * tmp2.y);
  14199. X   tmp2 = old; /* set tmp2 to Y value */
  14200. X   return(floatbailout());
  14201. X}
  14202. X
  14203. XLongPhoenixPlusFractal()
  14204. X{
  14205. X#ifndef XFRACT
  14206. X/* z(n+1) = z(n)^(degree-1) * (z(n) + p) + qy(n),  y(n+1) = z(n) */
  14207. Xint i;
  14208. X_LCMPLX loldplus, lnewminus;
  14209. X   loldplus = lold;
  14210. X   ltmp = lold;
  14211. X   for(i=1; i<degree; i++) { /* degree >= 2, degree=degree-1 in setup */
  14212. X      LCMPLXmult(lold,ltmp,ltmp); /* = old^(degree-1) */
  14213. X   }
  14214. X   loldplus.x += longparm->x;
  14215. X   LCMPLXmult(ltmp, loldplus, lnewminus);
  14216. X   lnew.x = lnewminus.x + multiply(longparm->y,ltmp2.x,bitshift);
  14217. X   lnew.y = lnewminus.y + multiply(longparm->y,ltmp2.y,bitshift);
  14218. X   ltmp2 = lold; /* set ltmp2 to Y value */
  14219. X   return(longbailout());
  14220. X#endif
  14221. X}
  14222. X
  14223. XPhoenixPlusFractal()
  14224. X{
  14225. X/* z(n+1) = z(n)^(degree-1) * (z(n) + p) + qy(n),  y(n+1) = z(n) */
  14226. Xint i;
  14227. X_CMPLX oldplus, newminus;
  14228. X   oldplus = old;
  14229. X   tmp = old;
  14230. X   for(i=1; i<degree; i++) { /* degree >= 2, degree=degree-1 in setup */
  14231. X     FPUcplxmul(&old, &tmp, &tmp); /* = old^(degree-1) */
  14232. X   }
  14233. X   oldplus.x += floatparm->x;
  14234. X   FPUcplxmul(&tmp, &oldplus, &newminus);
  14235. X   new.x = newminus.x + (floatparm->y * tmp2.x);
  14236. X   new.y = newminus.y + (floatparm->y * tmp2.y);
  14237. X   tmp2 = old; /* set tmp2 to Y value */
  14238. X   return(floatbailout());
  14239. X}
  14240. X
  14241. XLongPhoenixMinusFractal()
  14242. X{
  14243. X#ifndef XFRACT
  14244. X/* z(n+1) = z(n)^(degree-2) * (z(n)^2 + p) + qy(n),  y(n+1) = z(n) */
  14245. Xint i;
  14246. X_LCMPLX loldsqr, lnewminus;
  14247. X   LCMPLXmult(lold,lold,loldsqr);
  14248. X   ltmp = lold;
  14249. X   for(i=1; i<degree; i++) { /* degree >= 3, degree=degree-2 in setup */
  14250. X      LCMPLXmult(lold,ltmp,ltmp); /* = old^(degree-2) */
  14251. X   }
  14252. X   loldsqr.x += longparm->x;
  14253. X   LCMPLXmult(ltmp, loldsqr, lnewminus);
  14254. X   lnew.x = lnewminus.x + multiply(longparm->y,ltmp2.x,bitshift);
  14255. X   lnew.y = lnewminus.y + multiply(longparm->y,ltmp2.y,bitshift);
  14256. X   ltmp2 = lold; /* set ltmp2 to Y value */
  14257. X   return(longbailout());
  14258. X#endif
  14259. X}
  14260. X
  14261. XPhoenixMinusFractal()
  14262. X{
  14263. X/* z(n+1) = z(n)^(degree-2) * (z(n)^2 + p) + qy(n),  y(n+1) = z(n) */
  14264. Xint i;
  14265. X_CMPLX oldsqr, newminus;
  14266. X   FPUcplxmul(&old, &old, &oldsqr);
  14267. X   tmp = old;
  14268. X   for(i=1; i<degree; i++) { /* degree >= 3, degree=degree-2 in setup */
  14269. X     FPUcplxmul(&old, &tmp, &tmp); /* = old^(degree-2) */
  14270. X   }
  14271. X   oldsqr.x += floatparm->x;
  14272. X   FPUcplxmul(&tmp, &oldsqr, &newminus);
  14273. X   new.x = newminus.x + (floatparm->y * tmp2.x);
  14274. X   new.y = newminus.y + (floatparm->y * tmp2.y);
  14275. X   tmp2 = old; /* set tmp2 to Y value */
  14276. X   return(floatbailout());
  14277. X}
  14278. X
  14279. XScottTrigPlusTrigFractal()
  14280. X{
  14281. X#ifndef XFRACT
  14282. X   /* z = trig0(z)+trig1(z) */
  14283. X   LCMPLXtrig0(lold,ltmp);
  14284. X   LCMPLXtrig1(lold,lold);
  14285. X   LCMPLXadd(ltmp,lold,lnew);
  14286. X   return(longbailout());
  14287. X#endif
  14288. X}
  14289. X
  14290. XScottTrigPlusTrigfpFractal()
  14291. X{
  14292. X   /* z = trig0(z)+trig1(z) */
  14293. X   CMPLXtrig0(old,tmp);
  14294. X   CMPLXtrig1(old,tmp2);
  14295. X   CMPLXadd(tmp,tmp2,new);
  14296. X   return(floatbailout());
  14297. X}
  14298. X
  14299. XSkinnerTrigSubTrigFractal()
  14300. X{
  14301. X#ifndef XFRACT
  14302. X   /* z = trig(0,z)-trig1(z) */
  14303. X   LCMPLXtrig0(lold,ltmp);
  14304. X   LCMPLXtrig1(lold,ltmp2);
  14305. X   LCMPLXsub(ltmp,ltmp2,lnew);
  14306. X   return(longbailout());
  14307. X#endif
  14308. X}
  14309. X
  14310. XSkinnerTrigSubTrigfpFractal()
  14311. X{
  14312. X   /* z = trig0(z)-trig1(z) */
  14313. X   CMPLXtrig0(old,tmp);
  14314. X   CMPLXtrig1(old,tmp2);
  14315. X   CMPLXsub(tmp,tmp2,new);
  14316. X   return(floatbailout());
  14317. X}
  14318. X
  14319. X
  14320. XTrigXTrigfpFractal()
  14321. X{
  14322. X   /* z = trig0(z)*trig1(z) */
  14323. X   CMPLXtrig0(old,tmp);
  14324. X   CMPLXtrig1(old,old);
  14325. X   CMPLXmult(tmp,old,new);
  14326. X   return(floatbailout());
  14327. X}
  14328. X
  14329. XTrigXTrigFractal()
  14330. X{
  14331. X#ifndef XFRACT
  14332. X   _LCMPLX ltmp2;
  14333. X   /* z = trig0(z)*trig1(z) */
  14334. X   LCMPLXtrig0(lold,ltmp);
  14335. X   LCMPLXtrig1(lold,ltmp2);
  14336. X   LCMPLXmult(ltmp,ltmp2,lnew);
  14337. X   if(overflow)
  14338. X      TryFloatFractal(TrigXTrigfpFractal);
  14339. X   return(longbailout());
  14340. X#endif
  14341. X}
  14342. X
  14343. X /* call float version of fractal if integer math overflow */
  14344. XTryFloatFractal(int (*fpFractal)())
  14345. X{
  14346. X   overflow=0;
  14347. X   /* lold had better not be changed! */
  14348. X   old.x = lold.x; old.x /= fudge;
  14349. X   old.y = lold.y; old.y /= fudge;
  14350. X   tempsqrx = sqr(old.x);
  14351. X   tempsqry = sqr(old.y);
  14352. X   fpFractal();
  14353. X   lnew.x = new.x/fudge;
  14354. X   lnew.y = new.y/fudge;
  14355. X   return(0);
  14356. X}
  14357. X
  14358. X/********************************************************************/
  14359. X/*  Next six orbit functions are one type - extra functions are     */
  14360. X/*    special cases written for speed.                    */
  14361. X/********************************************************************/
  14362. X
  14363. XTrigPlusSqrFractal() /* generalization of Scott and Skinner types */
  14364. X{
  14365. X#ifndef XFRACT
  14366. X   /* { z=pixel: z=(p1,p2)*trig(z)+(p3,p4)*sqr(z), |z|<BAILOUT } */
  14367. X   LCMPLXtrig0(lold,ltmp);     /* ltmp = trig(lold)               */
  14368. X   LCMPLXmult(lparm,ltmp,lnew); /* lnew = lparm*trig(lold)            */
  14369. X   LCMPLXsqr_old(ltmp);     /* ltmp = sqr(lold)                */
  14370. X   LCMPLXmult(lparm2,ltmp,ltmp);/* ltmp = lparm2*sqr(lold)            */
  14371. X   LCMPLXadd(lnew,ltmp,lnew);    /* lnew = lparm*trig(lold)+lparm2*sqr(lold) */
  14372. X   return(longbailout());
  14373. X#endif
  14374. X}
  14375. X
  14376. XTrigPlusSqrfpFractal() /* generalization of Scott and Skinner types */
  14377. X{
  14378. X   /* { z=pixel: z=(p1,p2)*trig(z)+(p3,p4)*sqr(z), |z|<BAILOUT } */
  14379. X   CMPLXtrig0(old,tmp);     /* tmp = trig(old)               */
  14380. X   CMPLXmult(parm,tmp,new); /* new = parm*trig(old)           */
  14381. X   CMPLXsqr_old(tmp);         /* tmp = sqr(old)                */
  14382. X   CMPLXmult(parm2,tmp,tmp2); /* tmp = parm2*sqr(old)             */
  14383. X   CMPLXadd(new,tmp2,new);    /* new = parm*trig(old)+parm2*sqr(old) */
  14384. X   return(floatbailout());
  14385. X}
  14386. X
  14387. XScottTrigPlusSqrFractal()
  14388. X{
  14389. X#ifndef XFRACT
  14390. X   /*  { z=pixel: z=trig(z)+sqr(z), |z|<BAILOUT } */
  14391. X   LCMPLXtrig0(lold,lnew);    /* lnew = trig(lold)         */
  14392. X   LCMPLXsqr_old(ltmp);        /* lold = sqr(lold)          */
  14393. X   LCMPLXadd(ltmp,lnew,lnew);  /* lnew = trig(lold)+sqr(lold) */
  14394. X   return(longbailout());
  14395. X#endif
  14396. X}
  14397. X
  14398. XScottTrigPlusSqrfpFractal() /* float version */
  14399. X{
  14400. X   /* { z=pixel: z=sin(z)+sqr(z), |z|<BAILOUT } */
  14401. X   CMPLXtrig0(old,new);       /* new = trig(old)      */
  14402. X   CMPLXsqr_old(tmp);           /* tmp = sqr(old)       */
  14403. X   CMPLXadd(new,tmp,new);      /* new = trig(old)+sqr(old) */
  14404. X   return(floatbailout());
  14405. X}
  14406. X
  14407. XSkinnerTrigSubSqrFractal()
  14408. X{
  14409. X#ifndef XFRACT
  14410. X   /* { z=pixel: z=sin(z)-sqr(z), |z|<BAILOUT }           */
  14411. X   LCMPLXtrig0(lold,lnew);    /* lnew = trig(lold)         */
  14412. X   LCMPLXsqr_old(ltmp);        /* lold = sqr(lold)          */
  14413. X   LCMPLXsub(lnew,ltmp,lnew);  /* lnew = trig(lold)-sqr(lold) */
  14414. X   return(longbailout());
  14415. X#endif
  14416. X}
  14417. X
  14418. XSkinnerTrigSubSqrfpFractal()
  14419. X{
  14420. X   /* { z=pixel: z=sin(z)-sqr(z), |z|<BAILOUT } */
  14421. X   CMPLXtrig0(old,new);       /* new = trig(old) */
  14422. X   CMPLXsqr_old(tmp);           /* old = sqr(old)  */
  14423. X   CMPLXsub(new,tmp,new);      /* new = trig(old)-sqr(old) */
  14424. X   return(floatbailout());
  14425. X}
  14426. X
  14427. XTrigZsqrdfpFractal()
  14428. X{
  14429. X   /* { z=pixel: z=trig(z*z), |z|<TEST } */
  14430. X   CMPLXsqr_old(tmp);
  14431. X   CMPLXtrig0(tmp,new);
  14432. X   return(floatbailout());
  14433. X}
  14434. X
  14435. XTrigZsqrdFractal() /* this doesn't work very well */
  14436. X{
  14437. X#ifndef XFRACT
  14438. X   /* { z=pixel: z=trig(z*z), |z|<TEST } */
  14439. X   LCMPLXsqr_old(ltmp);
  14440. X   LCMPLXtrig0(ltmp,lnew);
  14441. X   if(overflow)
  14442. X      TryFloatFractal(TrigZsqrdfpFractal);
  14443. X   return(longbailout());
  14444. X#endif
  14445. X}
  14446. X
  14447. XSqrTrigFractal()
  14448. X{
  14449. X#ifndef XFRACT
  14450. X   /* { z=pixel: z=sqr(trig(z)), |z|<TEST} */
  14451. X   LCMPLXtrig0(lold,ltmp);
  14452. X   LCMPLXsqr(ltmp,lnew);
  14453. X   return(longbailout());
  14454. X#endif
  14455. X}
  14456. X
  14457. XSqrTrigfpFractal()
  14458. X{
  14459. X   /* SZSB(XYAXIS) { z=pixel, TEST=(p1+3): z=sin(z)*sin(z), |z|<TEST} */
  14460. X   CMPLXtrig0(old,tmp);
  14461. X   CMPLXsqr(tmp,new);
  14462. X   return(floatbailout());
  14463. X}
  14464. X
  14465. X
  14466. XMagnet1Fractal()    /*      Z = ((Z**2 + C - 1)/(2Z + C - 2))**2      */
  14467. X  {              /*  In "Beauty of Fractals", code by Kev Allen. */
  14468. X    _CMPLX top, bot, tmp;
  14469. X    double div;
  14470. X
  14471. X    top.x = tempsqrx - tempsqry + floatparm->x - 1; /* top = Z**2+C-1 */
  14472. X    top.y = old.x * old.y;
  14473. X    top.y = top.y + top.y + floatparm->y;
  14474. X
  14475. X    bot.x = old.x + old.x + floatparm->x - 2;        /* bot = 2*Z+C-2  */
  14476. X    bot.y = old.y + old.y + floatparm->y;
  14477. X
  14478. X    div = bot.x*bot.x + bot.y*bot.y;            /* tmp = top/bot  */
  14479. X    if (div < FLT_MIN) return(1);
  14480. X    tmp.x = (top.x*bot.x + top.y*bot.y)/div;
  14481. X    tmp.y = (top.y*bot.x - top.x*bot.y)/div;
  14482. X
  14483. X    new.x = (tmp.x + tmp.y) * (tmp.x - tmp.y);        /* Z = tmp**2     */
  14484. X    new.y = tmp.x * tmp.y;
  14485. X    new.y += new.y;
  14486. X
  14487. X    return(floatbailout());
  14488. X  }
  14489. X
  14490. XMagnet2Fractal()  /* Z = ((Z**3 + 3(C-1)Z + (C-1)(C-2)    ) /     */
  14491. X            /*         (3Z**2 + 3(C-2)Z + (C-1)(C-2)+1) )**2  */
  14492. X  {            /*     In "Beauty of Fractals", code by Kev Allen.  */
  14493. X    _CMPLX top, bot, tmp;
  14494. X    double div;
  14495. X
  14496. X    top.x = old.x * (tempsqrx-tempsqry-tempsqry-tempsqry + T_Cm1.x)
  14497. X      - old.y * T_Cm1.y + T_Cm1Cm2.x;
  14498. X    top.y = old.y * (tempsqrx+tempsqrx+tempsqrx-tempsqry + T_Cm1.x)
  14499. X      + old.x * T_Cm1.y + T_Cm1Cm2.y;
  14500. X
  14501. X    bot.x = tempsqrx - tempsqry;
  14502. X    bot.x = bot.x + bot.x + bot.x
  14503. X      + old.x * T_Cm2.x - old.y * T_Cm2.y
  14504. X      + T_Cm1Cm2.x + 1.0;
  14505. X    bot.y = old.x * old.y;
  14506. X    bot.y += bot.y;
  14507. X    bot.y = bot.y + bot.y + bot.y
  14508. X      + old.x * T_Cm2.y + old.y * T_Cm2.x
  14509. X      + T_Cm1Cm2.y;
  14510. X
  14511. X    div = bot.x*bot.x + bot.y*bot.y;            /* tmp = top/bot  */
  14512. X    if (div < FLT_MIN) return(1);
  14513. X    tmp.x = (top.x*bot.x + top.y*bot.y)/div;
  14514. X    tmp.y = (top.y*bot.x - top.x*bot.y)/div;
  14515. X
  14516. X    new.x = (tmp.x + tmp.y) * (tmp.x - tmp.y);        /* Z = tmp**2     */
  14517. X    new.y = tmp.x * tmp.y;
  14518. X    new.y += new.y;
  14519. X
  14520. X    return(floatbailout());
  14521. X  }
  14522. X
  14523. XLambdaTrigFractal()
  14524. X{
  14525. X#ifndef XFRACT
  14526. X   LONGXYTRIGBAILOUT();
  14527. X   LCMPLXtrig0(lold,ltmp);         /* ltmp = trig(lold)        */
  14528. X   LCMPLXmult(*longparm,ltmp,lnew);   /* lnew = longparm*trig(lold)  */
  14529. X   lold = lnew;
  14530. X   return(0);
  14531. X#endif
  14532. X}
  14533. X
  14534. XLambdaTrigfpFractal()
  14535. X{
  14536. X   FLOATXYTRIGBAILOUT();
  14537. X   CMPLXtrig0(old,tmp);          /* tmp = trig(old)       */
  14538. X   CMPLXmult(*floatparm,tmp,new);   /* new = longparm*trig(old)  */
  14539. X   old = new;
  14540. X   return(0);
  14541. X}
  14542. X
  14543. X/* bailouts are different for different trig functions */
  14544. XLambdaTrigFractal1()
  14545. X{
  14546. X#ifndef XFRACT
  14547. X   LONGTRIGBAILOUT(); /* sin,cos */
  14548. X   LCMPLXtrig0(lold,ltmp);         /* ltmp = trig(lold)        */
  14549. X   LCMPLXmult(*longparm,ltmp,lnew);   /* lnew = longparm*trig(lold)  */
  14550. X   lold = lnew;
  14551. X   return(0);
  14552. X#endif
  14553. X}
  14554. X
  14555. XLambdaTrigfpFractal1()
  14556. X{
  14557. X   FLOATTRIGBAILOUT(); /* sin,cos */
  14558. X   CMPLXtrig0(old,tmp);          /* tmp = trig(old)       */
  14559. X   CMPLXmult(*floatparm,tmp,new);   /* new = longparm*trig(old)  */
  14560. X   old = new;
  14561. X   return(0);
  14562. X}
  14563. X
  14564. XLambdaTrigFractal2()
  14565. X{
  14566. X#ifndef XFRACT
  14567. X   LONGHTRIGBAILOUT(); /* sinh,cosh */
  14568. X   LCMPLXtrig0(lold,ltmp);         /* ltmp = trig(lold)        */
  14569. X   LCMPLXmult(*longparm,ltmp,lnew);   /* lnew = longparm*trig(lold)  */
  14570. X   lold = lnew;
  14571. X   return(0);
  14572. X#endif
  14573. X}
  14574. X
  14575. XLambdaTrigfpFractal2()
  14576. X{
  14577. X#ifndef XFRACT
  14578. X   FLOATHTRIGBAILOUT(); /* sinh,cosh */
  14579. X   CMPLXtrig0(old,tmp);          /* tmp = trig(old)       */
  14580. X   CMPLXmult(*floatparm,tmp,new);   /* new = longparm*trig(old)  */
  14581. X   old = new;
  14582. X   return(0);
  14583. X#endif
  14584. X}
  14585. X
  14586. XManOWarFractal()
  14587. X{
  14588. X#ifndef XFRACT
  14589. X   /* From Art Matrix via Lee Skinner */
  14590. X   lnew.x  = ltempsqrx - ltempsqry + ltmp.x + longparm->x;
  14591. X   lnew.y = multiply(lold.x, lold.y, bitshiftless1) + ltmp.y + longparm->y;
  14592. X   ltmp = lold;
  14593. X   return(longbailout());
  14594. X#endif
  14595. X}
  14596. X
  14597. XManOWarfpFractal()
  14598. X{
  14599. X   /* From Art Matrix via Lee Skinner */
  14600. X   /* note that fast >= 287 equiv in fracsuba.asm must be kept in step */
  14601. X   new.x = tempsqrx - tempsqry + tmp.x + floatparm->x;
  14602. X   new.y = 2.0 * old.x * old.y + tmp.y + floatparm->y;
  14603. X   tmp = old;
  14604. X   return(floatbailout());
  14605. X}
  14606. X
  14607. X/*
  14608. X   MarksMandelPwr (XAXIS) {
  14609. X      z = pixel, c = z ^ (z - 1):
  14610. X     z = c * sqr(z) + pixel,
  14611. X      |z| <= 4
  14612. X   }
  14613. X*/
  14614. X
  14615. XMarksMandelPwrfpFractal()
  14616. X{
  14617. X   CMPLXtrig0(old,new);
  14618. X   CMPLXmult(tmp,new,new);
  14619. X   new.x += floatparm->x;
  14620. X   new.y += floatparm->y;
  14621. X   return(floatbailout());
  14622. X}
  14623. X
  14624. XMarksMandelPwrFractal()
  14625. X{
  14626. X#ifndef XFRACT
  14627. X   LCMPLXtrig0(lold,lnew);
  14628. X   LCMPLXmult(ltmp,lnew,lnew);
  14629. X   lnew.x += longparm->x;
  14630. X   lnew.y += longparm->y;
  14631. X   return(longbailout());
  14632. X#endif
  14633. X}
  14634. X
  14635. X/* I was coding Marksmandelpower and failed to use some temporary
  14636. X   variables. The result was nice, and since my name is not on any fractal,
  14637. X   I thought I would immortalize myself with this error!
  14638. X        Tim Wegner */
  14639. X
  14640. X
  14641. XTimsErrorfpFractal()
  14642. X{
  14643. X   CMPLXtrig0(old,new);
  14644. X   new.x = new.x * tmp.x - new.y * tmp.y;
  14645. X   new.y = new.x * tmp.y - new.y * tmp.x;
  14646. X   new.x += floatparm->x;
  14647. X   new.y += floatparm->y;
  14648. X   return(floatbailout());
  14649. X}
  14650. XTimsErrorFractal()
  14651. X{
  14652. X#ifndef XFRACT
  14653. X   LCMPLXtrig0(lold,lnew);
  14654. X   lnew.x = multiply(lnew.x,ltmp.x,bitshift)-multiply(lnew.y,ltmp.y,bitshift);
  14655. X   lnew.y = multiply(lnew.x,ltmp.y,bitshift)-multiply(lnew.y,ltmp.x,bitshift);
  14656. X   lnew.x += longparm->x;
  14657. X   lnew.y += longparm->y;
  14658. X   return(longbailout());
  14659. X#endif
  14660. X}
  14661. X
  14662. XCirclefpFractal()
  14663. X{
  14664. X   extern int colors;
  14665. X   extern int color;
  14666. X   int i;
  14667. X   i = param[0]*(tempsqrx+tempsqry);
  14668. X   color = i&(colors-1);
  14669. X   return(1);
  14670. X}
  14671. X/*
  14672. XCirclelongFractal()
  14673. X{
  14674. X   extern int colors;
  14675. X   extern int color;
  14676. X   long i;
  14677. X   i = multiply(lparm.x,(ltempsqrx+ltempsqry),bitshift);
  14678. X   i = i >> bitshift;
  14679. X   color = i&(colors-1);
  14680. X   return(1);
  14681. X}
  14682. X*/
  14683. X
  14684. X/* -------------------------------------------------------------------- */
  14685. X/*        Initialization (once per pixel) routines                        */
  14686. X/* -------------------------------------------------------------------- */
  14687. X
  14688. X#ifdef XFRACT
  14689. X/* this code translated to asm - lives in newton.asm */
  14690. X/* transform points with reciprocal function */
  14691. Xvoid invertz2(_CMPLX *z)
  14692. X{
  14693. X   z->x = dx0[col]+dx1[row];
  14694. X   z->y = dy0[row]+dy1[col];
  14695. X   z->x -= f_xcenter; z->y -= f_ycenter;  /* Normalize values to center of circle */
  14696. X
  14697. X   tempsqrx = sqr(z->x) + sqr(z->y);  /* Get old radius */
  14698. X   if(fabs(tempsqrx) > FLT_MIN)
  14699. X      tempsqrx = f_radius / tempsqrx;
  14700. X   else
  14701. X      tempsqrx = FLT_MAX;   /* a big number, but not TOO big */
  14702. X   z->x *= tempsqrx;      z->y *= tempsqrx;     /* Perform inversion */
  14703. X   z->x += f_xcenter; z->y += f_ycenter; /* Renormalize */
  14704. X}
  14705. X#endif
  14706. X
  14707. Xint long_julia_per_pixel()
  14708. X{
  14709. X#ifndef XFRACT
  14710. X   /* integer julia types */
  14711. X   /* lambda */
  14712. X   /* barnsleyj1 */
  14713. X   /* barnsleyj2 */
  14714. X   /* sierpinski */
  14715. X   if(invert)
  14716. X   {
  14717. X      /* invert */
  14718. X      invertz2(&old);
  14719. X
  14720. X      /* watch out for overflow */
  14721. X      if(sqr(old.x)+sqr(old.y) >= 127)
  14722. X      {
  14723. X     old.x = 8;  /* value to bail out in one iteration */
  14724. X     old.y = 8;
  14725. X      }
  14726. X
  14727. X      /* convert to fudged longs */
  14728. X      lold.x = old.x*fudge;
  14729. X      lold.y = old.y*fudge;
  14730. X   }
  14731. X   else
  14732. X   {
  14733. X      lold.x = lx0[col]+lx1[row];
  14734. X      lold.y = ly0[row]+ly1[col];
  14735. X   }
  14736. X   return(0);
  14737. X#else
  14738. X   printf("Called long_julia_per_pixel\n");
  14739. X   exit(0);
  14740. X#endif
  14741. X}
  14742. X
  14743. Xint long_richard8_per_pixel()
  14744. X{
  14745. X#ifndef XFRACT
  14746. X    long_mandel_per_pixel();
  14747. X    LCMPLXtrig1(*longparm,ltmp);
  14748. X    LCMPLXmult(ltmp,lparm2,ltmp);
  14749. X    return(1);
  14750. X#endif
  14751. X}
  14752. X
  14753. Xint long_mandel_per_pixel()
  14754. X{
  14755. X#ifndef XFRACT
  14756. X   /* integer mandel types */
  14757. X   /* barnsleym1 */
  14758. X   /* barnsleym2 */
  14759. X   linit.x = lx0[col]+lx1[row];
  14760. X
  14761. X   if(invert)
  14762. X   {
  14763. X      /* invert */
  14764. X      invertz2(&init);
  14765. X
  14766. X      /* watch out for overflow */
  14767. X      if(sqr(init.x)+sqr(init.y) >= 127)
  14768. X      {
  14769. X     init.x = 8;  /* value to bail out in one iteration */
  14770. X     init.y = 8;
  14771. X      }
  14772. X
  14773. X      /* convert to fudged longs */
  14774. X      linit.x = init.x*fudge;
  14775. X      linit.y = init.y*fudge;
  14776. X   }
  14777. X
  14778. X   if(useinitorbit == 1)
  14779. X      lold = linitorbit;
  14780. X   else
  14781. X      lold = linit;
  14782. X
  14783. X   lold.x += lparm.x;     /* initial pertubation of parameters set */
  14784. X   lold.y += lparm.y;
  14785. X   return(1); /* 1st iteration has been done */
  14786. X#else
  14787. X   printf("Called long_mandel_per_pixel\n");
  14788. X   exit(0);
  14789. X#endif
  14790. X}
  14791. X
  14792. Xint julia_per_pixel()
  14793. X{
  14794. X   /* julia */
  14795. X
  14796. X   if(invert)
  14797. X   {
  14798. X      /* invert */
  14799. X      invertz2(&old);
  14800. X
  14801. X      /* watch out for overflow */
  14802. X      if(bitshift <= 24)
  14803. X     if (sqr(old.x)+sqr(old.y) >= 127)
  14804. X     {
  14805. X        old.x = 8;    /* value to bail out in one iteration */
  14806. X        old.y = 8;
  14807. X     }
  14808. X      if(bitshift >  24)
  14809. X     if (sqr(old.x)+sqr(old.y) >= 4.0)
  14810. X     {
  14811. X        old.x = 2;    /* value to bail out in one iteration */
  14812. X        old.y = 2;
  14813. X     }
  14814. X
  14815. X      /* convert to fudged longs */
  14816. X      lold.x = old.x*fudge;
  14817. X      lold.y = old.y*fudge;
  14818. X   }
  14819. X   else
  14820. X   {
  14821. X      lold.x = lx0[col]+lx1[row];
  14822. X      lold.y = ly0[row]+ly1[col];
  14823. X   }
  14824. X
  14825. X   ltempsqrx = multiply(lold.x, lold.x, bitshift);
  14826. X   ltempsqry = multiply(lold.y, lold.y, bitshift);
  14827. X   ltmp = lold;
  14828. X   return(0);
  14829. X}
  14830. X
  14831. Xmarks_mandelpwr_per_pixel()
  14832. X{
  14833. X#ifndef XFRACT
  14834. X   mandel_per_pixel();
  14835. X   ltmp = lold;
  14836. X   ltmp.x -= fudge;
  14837. X   LCMPLXpwr(lold,ltmp,ltmp);
  14838. X   return(1);
  14839. X#endif
  14840. X}
  14841. X
  14842. Xint mandel_per_pixel()
  14843. X{
  14844. X   /* mandel */
  14845. X
  14846. X   if(invert)
  14847. X   {
  14848. X      invertz2(&init);
  14849. X
  14850. X      /* watch out for overflow */
  14851. X      if(bitshift <= 24)
  14852. X     if (sqr(init.x)+sqr(init.y) >= 127)
  14853. X     {
  14854. X        init.x = 8;  /* value to bail out in one iteration */
  14855. X        init.y = 8;
  14856. X     }
  14857. X      if(bitshift >  24)
  14858. X     if (sqr(init.x)+sqr(init.y) >= 4)
  14859. X     {
  14860. X        init.x = 2;  /* value to bail out in one iteration */
  14861. X        init.y = 2;
  14862. X     }
  14863. X
  14864. X      /* convert to fudged longs */
  14865. X      linit.x = init.x*fudge;
  14866. X      linit.y = init.y*fudge;
  14867. X   }
  14868. X   else
  14869. X      linit.x = lx0[col]+lx1[row];
  14870. X   switch (fractype)
  14871. X     {
  14872. X    case MANDELLAMBDA:        /* Critical Value 0.5 + 0.0i  */
  14873. X        lold.x = FgHalf;
  14874. X        lold.y = 0;
  14875. X        break;
  14876. X    default:
  14877. X        lold = linit;
  14878. X        break;
  14879. X      }
  14880. X
  14881. X   /* alter init value */
  14882. X   if(useinitorbit == 1)
  14883. X      lold = linitorbit;
  14884. X   else if(useinitorbit == 2)
  14885. X      lold = linit;
  14886. X
  14887. X   if(inside == -60 || inside == -61)
  14888. X   {
  14889. X      /* kludge to match "Beauty of Fractals" picture since we start
  14890. X     Mandelbrot iteration with init rather than 0 */
  14891. X      lold.x = lparm.x; /* initial pertubation of parameters set */
  14892. X      lold.y = lparm.y;
  14893. X      color = -1;
  14894. X   }
  14895. X   else
  14896. X   {
  14897. X      lold.x += lparm.x; /* initial pertubation of parameters set */
  14898. X      lold.y += lparm.y;
  14899. X   }
  14900. X   ltmp = linit; /* for spider */
  14901. X   ltempsqrx = multiply(lold.x, lold.x, bitshift);
  14902. X   ltempsqry = multiply(lold.y, lold.y, bitshift);
  14903. X   return(1); /* 1st iteration has been done */
  14904. X}
  14905. X
  14906. X
  14907. Xint marksmandel_per_pixel()
  14908. X{
  14909. X   /* marksmandel */
  14910. X
  14911. X   if(invert)
  14912. X   {
  14913. X      invertz2(&init);
  14914. X
  14915. X      /* watch out for overflow */
  14916. X      if(sqr(init.x)+sqr(init.y) >= 127)
  14917. X      {
  14918. X     init.x = 8;  /* value to bail out in one iteration */
  14919. X     init.y = 8;
  14920. X      }
  14921. X
  14922. X      /* convert to fudged longs */
  14923. X      linit.x = init.x*fudge;
  14924. X      linit.y = init.y*fudge;
  14925. X   }
  14926. X   else
  14927. X      linit.x = lx0[col]+lx1[row];
  14928. X
  14929. X   if(useinitorbit == 1)
  14930. X      lold = linitorbit;
  14931. X   else
  14932. X      lold = linit;
  14933. X
  14934. X   lold.x += lparm.x;     /* initial pertubation of parameters set */
  14935. X   lold.y += lparm.y;
  14936. X
  14937. X   if(c_exp > 3)
  14938. X      lcpower(&lold,c_exp-1,&lcoefficient,bitshift);
  14939. X   else if(c_exp == 3) {
  14940. X      lcoefficient.x = multiply(lold.x, lold.x, bitshift)
  14941. X     - multiply(lold.y, lold.y, bitshift);
  14942. X      lcoefficient.y = multiply(lold.x, lold.y, bitshiftless1);
  14943. X   }
  14944. X   else if(c_exp == 2)
  14945. X      lcoefficient = lold;
  14946. X   else if(c_exp < 2) {
  14947. X      lcoefficient.x = 1L << bitshift;
  14948. X      lcoefficient.y = 0L;
  14949. X   }
  14950. X
  14951. X   ltempsqrx = multiply(lold.x, lold.x, bitshift);
  14952. X   ltempsqry = multiply(lold.y, lold.y, bitshift);
  14953. X   return(1); /* 1st iteration has been done */
  14954. X}
  14955. X
  14956. Xint marksmandelfp_per_pixel()
  14957. X{
  14958. X   /* marksmandel */
  14959. X
  14960. X   if(invert)
  14961. X      invertz2(&init);
  14962. X   else
  14963. X      init.x = dx0[col]+dx1[row];
  14964. X
  14965. X   if(useinitorbit == 1)
  14966. X      old = initorbit;
  14967. X   else
  14968. X      old = init;
  14969. X
  14970. X   old.x += parm.x;     /* initial pertubation of parameters set */
  14971. X   old.y += parm.y;
  14972. X
  14973. X   tempsqrx = sqr(old.x);
  14974. X   tempsqry = sqr(old.y);
  14975. X
  14976. X   if(c_exp > 3)
  14977. X      cpower(&old,c_exp-1,&coefficient);
  14978. X   else if(c_exp == 3) {
  14979. X      coefficient.x = tempsqrx - tempsqry;
  14980. X      coefficient.y = old.x * old.y * 2;
  14981. X   }
  14982. X   else if(c_exp == 2)
  14983. X      coefficient = old;
  14984. X   else if(c_exp < 2) {
  14985. X      coefficient.x = 1.0;
  14986. X      coefficient.y = 0.0;
  14987. X   }
  14988. X
  14989. X   return(1); /* 1st iteration has been done */
  14990. X}
  14991. X
  14992. Xmarks_mandelpwrfp_per_pixel()
  14993. X{
  14994. X   mandelfp_per_pixel();
  14995. X   tmp = old;
  14996. X   tmp.x -= 1;
  14997. X   CMPLXpwr(old,tmp,tmp);
  14998. X   return(1);
  14999. X}
  15000. X
  15001. Xint mandelfp_per_pixel()
  15002. X{
  15003. X   /* floating point mandelbrot */
  15004. X   /* mandelfp */
  15005. X
  15006. X   if(invert)
  15007. X      invertz2(&init);
  15008. X   else
  15009. X      init.x = dx0[col]+dx1[row];
  15010. X    switch (fractype)
  15011. X      {
  15012. X    case MAGNET2M:
  15013. X        FloatPreCalcMagnet2();
  15014. X    case MAGNET1M:         /* Crit Val Zero both, but neither   */
  15015. X        old.x = old.y = 0.0; /* is of the form f(Z,C) = Z*g(Z)+C  */
  15016. X        break;
  15017. X    case MANDELLAMBDAFP:        /* Critical Value 0.5 + 0.0i  */
  15018. X        old.x = 0.5;
  15019. X        old.y = 0.0;
  15020. X        break;
  15021. X    default:
  15022. X        old = init;
  15023. X        break;
  15024. X      }
  15025. X
  15026. X   /* alter init value */
  15027. X   if(useinitorbit == 1)
  15028. X      old = initorbit;
  15029. X   else if(useinitorbit == 2)
  15030. X      old = init;
  15031. X
  15032. X   if(inside == -60 || inside == -61)
  15033. X   {
  15034. X      /* kludge to match "Beauty of Fractals" picture since we start
  15035. X     Mandelbrot iteration with init rather than 0 */
  15036. X      old.x = parm.x; /* initial pertubation of parameters set */
  15037. X      old.y = parm.y;
  15038. X      color = -1;
  15039. X   }
  15040. X   else
  15041. X   {
  15042. X     old.x += parm.x;
  15043. X     old.y += parm.y;
  15044. X   }
  15045. X   tmp = init; /* for spider */
  15046. X   tempsqrx = sqr(old.x);  /* precalculated value for regular Mandelbrot */
  15047. X   tempsqry = sqr(old.y);
  15048. X   return(1); /* 1st iteration has been done */
  15049. X}
  15050. X
  15051. Xint juliafp_per_pixel()
  15052. X{
  15053. X   /* floating point julia */
  15054. X   /* juliafp */
  15055. X   if(invert)
  15056. X      invertz2(&old);
  15057. X   else
  15058. X   {
  15059. X     old.x = dx0[col]+dx1[row];
  15060. X     old.y = dy0[row]+dy1[col];
  15061. X   }
  15062. X   tempsqrx = sqr(old.x);  /* precalculated value for regular Julia */
  15063. X   tempsqry = sqr(old.y);
  15064. X   tmp = old;
  15065. X   return(0);
  15066. X}
  15067. X
  15068. Xint MPCjulia_per_pixel()
  15069. X{
  15070. X#ifndef XFRACT
  15071. X   /* floating point julia */
  15072. X   /* juliafp */
  15073. X   if(invert)
  15074. X      invertz2(&old);
  15075. X   else
  15076. X   {
  15077. X     old.x = dx0[col]+dx1[row];
  15078. X     old.y = dy0[row]+dy1[col];
  15079. X   }
  15080. X   mpcold.x = *pd2MP(old.x);
  15081. X   mpcold.y = *pd2MP(old.y);
  15082. X   return(0);
  15083. X#endif
  15084. X}
  15085. X
  15086. Xotherrichard8fp_per_pixel()
  15087. X{
  15088. X    othermandelfp_per_pixel();
  15089. X    CMPLXtrig1(*floatparm,tmp);
  15090. X    CMPLXmult(tmp,parm2,tmp);
  15091. X    return(1);
  15092. X}
  15093. X
  15094. Xint othermandelfp_per_pixel()
  15095. X{
  15096. X   if(invert)
  15097. X      invertz2(&init);
  15098. X   else
  15099. X      init.x = dx0[col]+dx1[row];
  15100. X
  15101. X   if(useinitorbit == 1)
  15102. X      old = initorbit;
  15103. X   else
  15104. X      old = init;
  15105. X
  15106. X   old.x += parm.x;     /* initial pertubation of parameters set */
  15107. X   old.y += parm.y;
  15108. X
  15109. X   return(1); /* 1st iteration has been done */
  15110. X}
  15111. X
  15112. Xint MPCHalley_per_pixel()
  15113. X{
  15114. X#ifndef XFRACT
  15115. X   /* MPC halley */
  15116. X   if(invert)
  15117. X      invertz2(&init);
  15118. X   else
  15119. X     init.x = dx0[col]+dx1[row];
  15120. X
  15121. X   mpcold.x = *pd2MP(init.x);
  15122. X   mpcold.y = *pd2MP(init.y);
  15123. X
  15124. X   return(0);
  15125. X#endif
  15126. X}
  15127. X
  15128. Xint Halley_per_pixel()
  15129. X{
  15130. X   if(invert)
  15131. X      invertz2(&init);
  15132. X   else
  15133. X      init.x = dx0[col]+dx1[row];
  15134. X
  15135. X   old = init;
  15136. X
  15137. X   return(0); /* 1st iteration is not done */
  15138. X}
  15139. X
  15140. Xint otherjuliafp_per_pixel()
  15141. X{
  15142. X   if(invert)
  15143. X      invertz2(&old);
  15144. X   else
  15145. X   {
  15146. X      old.x = dx0[col]+dx1[row];
  15147. X      old.y = dy0[row]+dy1[col];
  15148. X   }
  15149. X   return(0);
  15150. X}
  15151. X
  15152. X#if 0
  15153. X#define Q0 .113
  15154. X#define Q1 .01
  15155. X#else
  15156. X#define Q0 0
  15157. X#define Q1 0
  15158. X#endif
  15159. X
  15160. Xint quaternionjulfp_per_pixel()
  15161. X{
  15162. X   old.x = dx0[col]+dx1[row];
  15163. X   old.y = dy0[row]+dy1[col];
  15164. X   floatparm->x = param[4];
  15165. X   floatparm->y = param[5];
  15166. X   qc  = param[0];
  15167. X   qci = param[1];
  15168. X   qcj = param[2];
  15169. X   qck = param[3];
  15170. X   return(0);
  15171. X}
  15172. X
  15173. Xint quaternionfp_per_pixel()
  15174. X{
  15175. X   old.x = 0;
  15176. X   old.y = 0;
  15177. X   floatparm->x = 0;
  15178. X   floatparm->y = 0;
  15179. X   qc  = dx0[col]+dx1[row];
  15180. X   qci = dy0[row]+dy1[col];
  15181. X   qcj = param[2];
  15182. X   qck = param[3];
  15183. X   return(0);
  15184. X}
  15185. X
  15186. Xint trigmandelfp_per_pixel()
  15187. X{
  15188. X   if(invert)
  15189. X      invertz2(&init);
  15190. X   else
  15191. X      init.x = dx0[col]+dx1[row];
  15192. X
  15193. X   if(useinitorbit == 1)
  15194. X      old = initorbit;
  15195. X   else
  15196. X      old = init;
  15197. X
  15198. X   old.x += parm.x;     /* initial pertubation of parameters set */
  15199. X   old.y += parm.y;
  15200. X   CMPLXtrig0(old,old);
  15201. X   return(1); /* 1st iteration has been done */
  15202. X}
  15203. X
  15204. Xint trigjuliafp_per_pixel()
  15205. X{
  15206. X   /* for tetrated types */
  15207. X   if(invert)
  15208. X      invertz2(&old);
  15209. X   else
  15210. X   {
  15211. X      old.x = dx0[col]+dx1[row];
  15212. X      old.y = dy0[row]+dy1[col];
  15213. X   }
  15214. X   CMPLXtrig0(old,old);
  15215. X   return(0);
  15216. X}
  15217. X
  15218. Xint trigXtrigmandelfp_per_pixel()
  15219. X{
  15220. X   if(invert)
  15221. X      invertz2(&init);
  15222. X   else
  15223. X      init.x = dx0[col]+dx1[row];
  15224. X
  15225. X   if(useinitorbit == 1)
  15226. X      old = initorbit;
  15227. X   else
  15228. X      old = init;
  15229. X
  15230. X   old.x += parm.x;     /* initial pertubation of parameters set */
  15231. X   old.y += parm.y;
  15232. X   CMPLXtrig0(old,tmp);
  15233. X   CMPLXtrig1(old,tmp2);
  15234. X   CMPLXmult(tmp,tmp2,old);
  15235. X   return(1); /* 1st iteration has been done */
  15236. X}
  15237. X
  15238. Xint trigXtrigjuliafp_per_pixel()
  15239. X{
  15240. X   if(invert)
  15241. X      invertz2(&old);
  15242. X   else
  15243. X   {
  15244. X      old.x = dx0[col]+dx1[row];
  15245. X      old.y = dy0[row]+dy1[col];
  15246. X   }
  15247. X   CMPLXtrig0(old,tmp);
  15248. X   CMPLXtrig1(old,tmp2);
  15249. X   CMPLXmult(tmp,tmp2,old);
  15250. X   return(0);
  15251. X}
  15252. X
  15253. Xint MarksCplxMandperp(void)
  15254. X{
  15255. X   if(invert)
  15256. X      invertz2(&init);
  15257. X   else
  15258. X      init.x = dx0[col]+dx1[row];
  15259. X   old.x = init.x + parm.x; /* initial pertubation of parameters set */
  15260. X   old.y = init.y + parm.y;
  15261. X   tempsqrx = sqr(old.x);  /* precalculated value */
  15262. X   tempsqry = sqr(old.y);
  15263. X   Coefficient = ComplexPower(init, pwr);
  15264. X   return(1);
  15265. X}
  15266. X
  15267. Xint long_phoenix_per_pixel()
  15268. X{
  15269. X#ifndef XFRACT
  15270. X   if(invert)
  15271. X   {
  15272. X      /* invert */
  15273. X      invertz2(&old);
  15274. X
  15275. X      /* watch out for overflow */
  15276. X      if(sqr(old.x)+sqr(old.y) >= 127)
  15277. X      {
  15278. X     old.x = 8;  /* value to bail out in one iteration */
  15279. X     old.y = 8;
  15280. X      }
  15281. X
  15282. X      /* convert to fudged longs */
  15283. X      lold.x = old.x*fudge;
  15284. X      lold.y = old.y*fudge;
  15285. X   }
  15286. X   else
  15287. X   {
  15288. X      lold.x = lx0[col]+lx1[row];
  15289. X      lold.y = ly0[row]+ly1[col];
  15290. X   }
  15291. X   ltempsqrx = multiply(lold.x, lold.x, bitshift);
  15292. X   ltempsqry = multiply(lold.y, lold.y, bitshift);
  15293. X   ltmp2.x = 0; /* use ltmp2 as the complex Y value */
  15294. X   ltmp2.y = 0;
  15295. X   return(0);
  15296. X#else
  15297. X   printf("Called long_phoenix_per_pixel\n");
  15298. X   exit(0);
  15299. X#endif
  15300. X}
  15301. X
  15302. Xint phoenix_per_pixel()
  15303. X{
  15304. X   if(invert)
  15305. X      invertz2(&old);
  15306. X   else
  15307. X   {
  15308. X      old.x = dx0[col]+dx1[row];
  15309. X      old.y = dy0[row]+dy1[col];
  15310. X   }
  15311. X   tempsqrx = sqr(old.x);  /* precalculated value */
  15312. X   tempsqry = sqr(old.y);
  15313. X   tmp2.x = 0; /* use tmp2 as the complex Y value */
  15314. X   tmp2.y = 0;
  15315. X   return(0);
  15316. X}
  15317. Xint long_mandphoenix_per_pixel()
  15318. X{
  15319. X#ifndef XFRACT
  15320. X   linit.x = lx0[col]+lx1[row];
  15321. X
  15322. X   if(invert)
  15323. X   {
  15324. X      /* invert */
  15325. X      invertz2(&init);
  15326. X
  15327. X      /* watch out for overflow */
  15328. X      if(sqr(init.x)+sqr(init.y) >= 127)
  15329. X      {
  15330. X     init.x = 8;  /* value to bail out in one iteration */
  15331. X     init.y = 8;
  15332. X      }
  15333. X
  15334. X      /* convert to fudged longs */
  15335. X      linit.x = init.x*fudge;
  15336. X      linit.y = init.y*fudge;
  15337. X   }
  15338. X
  15339. X   if(useinitorbit == 1)
  15340. X      lold = linitorbit;
  15341. X   else
  15342. X      lold = linit;
  15343. X
  15344. X   lold.x += lparm.x;     /* initial pertubation of parameters set */
  15345. X   lold.y += lparm.y;
  15346. X   ltempsqrx = multiply(lold.x, lold.x, bitshift);
  15347. X   ltempsqry = multiply(lold.y, lold.y, bitshift);
  15348. X   ltmp2.x = 0;
  15349. X   ltmp2.y = 0;
  15350. X   return(1); /* 1st iteration has been done */
  15351. X#else
  15352. X   printf("Called long_mandphoenix_per_pixel\n");
  15353. X   exit(0);
  15354. X#endif
  15355. X}
  15356. Xint mandphoenix_per_pixel()
  15357. X{
  15358. X   if(invert)
  15359. X      invertz2(&init);
  15360. X   else
  15361. X      init.x = dx0[col]+dx1[row];
  15362. X
  15363. X   if(useinitorbit == 1)
  15364. X      old = initorbit;
  15365. X   else
  15366. X      old = init;
  15367. X
  15368. X   old.x += parm.x;     /* initial pertubation of parameters set */
  15369. X   old.y += parm.y;
  15370. X   tempsqrx = sqr(old.x);  /* precalculated value */
  15371. X   tempsqry = sqr(old.y);
  15372. X   tmp2.x = 0;
  15373. X   tmp2.y = 0;
  15374. X   return(1); /* 1st iteration has been done */
  15375. X}
  15376. X
  15377. XQuaternionFPFractal()
  15378. X{
  15379. X   double a0,a1,a2,a3,n0,n1,n2,n3;
  15380. X   a0 = old.x;
  15381. X   a1 = old.y;
  15382. X   a2 = floatparm->x;
  15383. X   a3 = floatparm->y;
  15384. X
  15385. X   n0 = a0*a0-a1*a1-a2*a2-a3*a3 + qc;
  15386. X   n1 = 2*a0*a1 + qci;
  15387. X   n2 = 2*a0*a2 + qcj;
  15388. X   n3 = 2*a0*a3 + qck;
  15389. X   /* Check bailout */
  15390. X   magnitude = a0*a0+a1*a1+a2*a2+a3*a3;
  15391. X   if (magnitude>rqlim) {
  15392. X       return 1;
  15393. X   }
  15394. X   old.x = n0;
  15395. X   old.y = n1;
  15396. X   floatparm->x = n2;
  15397. X   floatparm->y = n3;
  15398. X   return(0);
  15399. X}
  15400. X
  15401. XHyperComplex1FPFractal()
  15402. X{
  15403. X   double n0,n1,n2,n3;
  15404. X
  15405. X   n0 = sqr(old.x)-sqr(old.y)-sqr(floatparm->x)+sqr(floatparm->y) + qc;
  15406. X   n1 = 2*old.x*old.y - 2*floatparm->x*floatparm->y + qci;
  15407. X   n2 = 2*old.x*floatparm->x - 2*old.y*floatparm->y + qcj;
  15408. X   n3 = 2*old.x*floatparm->y + 2*old.y*floatparm->x + qck;
  15409. X   
  15410. X   old.x = n0;
  15411. X   old.y = n1;
  15412. X   floatparm->x = n2;
  15413. X   floatparm->y = n3;
  15414. X
  15415. X   /* Check bailout */
  15416. X   magnitude = sqr(old.x)+sqr(old.y)+sqr(floatparm->x)+sqr(floatparm->y);
  15417. X   if (magnitude>rqlim) {
  15418. X       return 1;
  15419. X   }
  15420. X   return(0);
  15421. X}
  15422. X
  15423. XHyperComplexFPFractal()
  15424. X{
  15425. X   double n0,n1,n2,n3;
  15426. X   _HCMPLX hold, hnew;
  15427. X   hold.x = old.x;
  15428. X   hold.y = old.y;
  15429. X   hold.z = floatparm->x;
  15430. X   hold.t = floatparm->y;
  15431. X
  15432. X/*   HComplexSqr(&hold,&hnew); */
  15433. X   HComplexTrig0(&hold,&hnew);
  15434. X   
  15435. X   hnew.x += qc;
  15436. X   hnew.y += qci;
  15437. X   hnew.z += qcj;
  15438. X   hnew.t += qck;
  15439. X   
  15440. X   old.x = hnew.x;
  15441. X   old.y = hnew.y;
  15442. X   floatparm->x = hnew.z;
  15443. X   floatparm->y = hnew.t;
  15444. X
  15445. X   /* Check bailout */
  15446. X   magnitude = sqr(old.x)+sqr(old.y)+sqr(floatparm->x)+sqr(floatparm->y);
  15447. X   if (magnitude>rqlim) {
  15448. X       return 1;
  15449. X   }
  15450. X   return(0);
  15451. X}
  15452. X
  15453. X/* -------------------------------------------------------------------- */
  15454. X/*        Setup (once per fractal image) routines         */
  15455. X/* -------------------------------------------------------------------- */
  15456. X
  15457. XMandelSetup()        /* Mandelbrot Routine */
  15458. X{
  15459. X   if (debugflag != 90 && ! invert && decomp[0] == 0 && rqlim <= 4.0
  15460. X       && bitshift == 29 && potflag == 0
  15461. X       && biomorph == -1 && inside > -59 && outside >= -1
  15462. X       && useinitorbit != 1 && using_jiim == 0)
  15463. X      calctype = calcmand; /* the normal case - use CALCMAND */
  15464. X   else
  15465. X   {
  15466. X      /* special case: use the main processing loop */
  15467. X      calctype = StandardFractal;
  15468. X      longparm = &linit;
  15469. X   }
  15470. X   return(1);
  15471. X}
  15472. X
  15473. XJuliaSetup()        /* Julia Routine */
  15474. X{
  15475. X   if (debugflag != 90 && ! invert && decomp[0] == 0 && rqlim <= 4.0
  15476. X       && bitshift == 29 && potflag == 0
  15477. X       && biomorph == -1 && inside > -59 && outside >= -1
  15478. X       && !finattract && using_jiim == 0)
  15479. X      calctype = calcmand; /* the normal case - use CALCMAND */
  15480. X   else
  15481. X   {
  15482. X      /* special case: use the main processing loop */
  15483. X      calctype = StandardFractal;
  15484. X      longparm = &lparm;
  15485. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15486. X   }
  15487. X   return(1);
  15488. X}
  15489. X
  15490. XNewtonSetup()        /* Newton/NewtBasin Routines */
  15491. X{
  15492. X   int i;
  15493. X   extern int basin;
  15494. X   extern int fpu;
  15495. X   if (debugflag != 1010)
  15496. X   {
  15497. X      if(fpu != 0)
  15498. X      {
  15499. X     if(fractype == MPNEWTON)
  15500. X        fractype = NEWTON;
  15501. X     else if(fractype == MPNEWTBASIN)
  15502. X        fractype = NEWTBASIN;
  15503. X      }
  15504. X      else
  15505. X      {
  15506. X     if(fractype == NEWTON)
  15507. X           fractype = MPNEWTON;
  15508. X     else if(fractype == NEWTBASIN)
  15509. X           fractype = MPNEWTBASIN;
  15510. X      }
  15511. X      curfractalspecific = &fractalspecific[fractype];
  15512. X   }
  15513. X
  15514. X   /* set up table of roots of 1 along unit circle */
  15515. X   degree = (int)parm.x;
  15516. X   if(degree < 2)
  15517. X      degree = 3;   /* defaults to 3, but 2 is possible */
  15518. X   root = 1;
  15519. X
  15520. X   /* precalculated values */
  15521. X   roverd    = (double)root / (double)degree;
  15522. X   d1overd    = (double)(degree - 1) / (double)degree;
  15523. X   maxcolor    = 0;
  15524. X   threshold    = .3*PI/degree; /* less than half distance between roots */
  15525. X#ifndef XFRACT
  15526. X   if (fractype == MPNEWTON || fractype == MPNEWTBASIN) {
  15527. X      mproverd       = *pd2MP(roverd);
  15528. X      mpd1overd    = *pd2MP(d1overd);
  15529. X      mpthreshold  = *pd2MP(threshold);
  15530. X      mpone       = *pd2MP(1.0);
  15531. X   }
  15532. X#endif
  15533. X
  15534. X   floatmin = FLT_MIN;
  15535. X   floatmax = FLT_MAX;
  15536. X
  15537. X   basin = 0;
  15538. X   if(roots != staticroots) {
  15539. X      free(roots);
  15540. X      roots = staticroots;
  15541. X   }
  15542. X
  15543. X   if (fractype==NEWTBASIN)
  15544. X   {
  15545. X      if(parm.y)
  15546. X     basin = 2; /*stripes */
  15547. X      else
  15548. X     basin = 1;
  15549. X      if(degree > 16)
  15550. X      {
  15551. X     if((roots=(_CMPLX *)malloc(degree*sizeof(_CMPLX)))==NULL)
  15552. X     {
  15553. X        roots = staticroots;
  15554. X        degree = 16;
  15555. X     }
  15556. X      }
  15557. X      else
  15558. X     roots = staticroots;
  15559. X
  15560. X      /* list of roots to discover where we converged for newtbasin */
  15561. X      for(i=0;i<degree;i++)
  15562. X      {
  15563. X     roots[i].x = cos(i*twopi/(double)degree);
  15564. X     roots[i].y = sin(i*twopi/(double)degree);
  15565. X      }
  15566. X   }
  15567. X#ifndef XFRACT
  15568. X   else if (fractype==MPNEWTBASIN)
  15569. X   {
  15570. X     if(parm.y)
  15571. X     basin = 2; /*stripes */
  15572. X      else
  15573. X     basin = 1;
  15574. X
  15575. X      if(degree > 16)
  15576. X      {
  15577. X     if((MPCroots=(struct MPC *)malloc(degree*sizeof(struct MPC)))==NULL)
  15578. X     {
  15579. X        MPCroots = (struct MPC *)staticroots;
  15580. X        degree = 16;
  15581. X     }
  15582. X      }
  15583. X      else
  15584. X     MPCroots = (struct MPC *)staticroots;
  15585. X
  15586. X      /* list of roots to discover where we converged for newtbasin */
  15587. X      for(i=0;i<degree;i++)
  15588. X      {
  15589. X     MPCroots[i].x = *pd2MP(cos(i*twopi/(double)degree));
  15590. X     MPCroots[i].y = *pd2MP(sin(i*twopi/(double)degree));
  15591. X      }
  15592. X   }
  15593. X#endif
  15594. X
  15595. X   param[0] = (double)degree; /* JCO 7/1/92 */
  15596. X   if (degree%4 == 0)
  15597. X      symmetry = XYAXIS;
  15598. X   else
  15599. X      symmetry = XAXIS;
  15600. X
  15601. X   calctype=StandardFractal;
  15602. X#ifndef XFRACT
  15603. X   if (fractype == MPNEWTON || fractype == MPNEWTBASIN)
  15604. X      setMPfunctions();
  15605. X#endif
  15606. X   return(1);
  15607. X}
  15608. X
  15609. X
  15610. XStandaloneSetup()
  15611. X{
  15612. X   timer(0,curfractalspecific->calctype);
  15613. X   return(0);        /* effectively disable solid-guessing */
  15614. X}
  15615. X
  15616. XUnitySetup()
  15617. X{
  15618. X   periodicitycheck = 0;
  15619. X   FgOne = (1L << bitshift);
  15620. X   FgTwo = FgOne + FgOne;
  15621. X   return(1);
  15622. X}
  15623. X
  15624. XMandelfpSetup()
  15625. X{
  15626. X   c_exp = param[2];
  15627. X   pwr.x = param[2] - 1.0;
  15628. X   pwr.y = param[3];
  15629. X   floatparm = &init;
  15630. X   switch (fractype)
  15631. X   {
  15632. X   case MARKSMANDELFP:
  15633. X      if(c_exp < 1)
  15634. X         c_exp = 1;
  15635. X      if(!(c_exp & 1))
  15636. X         symmetry = XYAXIS_NOPARM;    /* odd exponents */
  15637. X      if(c_exp & 1)
  15638. X         symmetry = XAXIS_NOPARM;
  15639. X      break;
  15640. X   case MANDELFP:
  15641. X    /*
  15642. X       floating point code could probably be altered to handle many of
  15643. X       the situations that otherwise are using StandardFractal().
  15644. X       calcmandfp() can currently handle invert, any rqlim, potflag
  15645. X       zmag, epsilon cross, and all the current outside options
  15646. X                             Wes Loewer 11/03/91
  15647. X    */
  15648. X    if (debugflag != 90
  15649. X        && !distest
  15650. X        && decomp[0] == 0
  15651. X        && biomorph == -1
  15652. X        && (inside >= -1 || inside == -59 || inside == -100)
  15653. X        /* uncomment this next line if more outside options are added */
  15654. X        /* && outside >= -5 */
  15655. X        && useinitorbit != 1
  15656. X        && using_jiim == 0)
  15657. X    {
  15658. X       calctype = calcmandfp; /* the normal case - use calcmandfp */
  15659. X       calcmandfpasmstart();
  15660. X    }
  15661. X    else
  15662. X    {
  15663. X       /* special case: use the main processing loop */
  15664. X       calctype = StandardFractal;
  15665. X    }
  15666. X    break;
  15667. X   case FPMANDELZPOWER:
  15668. X      if((double)c_exp == param[2] && c_exp & 1) /* odd exponents */
  15669. X         symmetry = XYAXIS_NOPARM;
  15670. X      if(param[3] != 0)
  15671. X         symmetry = NOSYM;
  15672. X      if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
  15673. X          fractalspecific[fractype].orbitcalc = floatZpowerFractal;
  15674. X      else
  15675. X          fractalspecific[fractype].orbitcalc = floatCmplxZpowerFractal;
  15676. X      break;
  15677. X   case MAGNET1M:
  15678. X   case MAGNET2M:
  15679. X      attr[0].x = 1.0;        /* 1.0 + 0.0i always attracts */
  15680. X      attr[0].y = 0.0;        /* - both MAGNET1 and MAGNET2 */
  15681. X      attrperiod[0] = 1;
  15682. X      attractors = 1;
  15683. X      break;
  15684. X   case SPIDERFP:
  15685. X      if(periodicitycheck==1) /* if not user set */
  15686. X     periodicitycheck=4;
  15687. X      break;
  15688. X   case MANDELEXP:
  15689. X      symmetry = XAXIS_NOPARM;
  15690. X      break;
  15691. X/* Added to account for symmetry in manfn+exp and manfn+zsqrd */
  15692. X/*     JCO 2/29/92 */
  15693. X   case FPMANTRIGPLUSEXP:
  15694. X   case FPMANTRIGPLUSZSQRD:
  15695. X     if(parm.y == 0.0)
  15696. X        symmetry = XAXIS;
  15697. X     else
  15698. X        symmetry = NOSYM;
  15699. X     if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
  15700. X        symmetry = NOSYM;
  15701. X      break;
  15702. X   case QUATFP:
  15703. X   case HYPERCMPLXFP:
  15704. X      floatparm = &tmp;
  15705. X      attractors = 0;
  15706. X      periodicitycheck = 0;
  15707. X      break;
  15708. X   default:
  15709. X      break;
  15710. X   }
  15711. X   return(1);
  15712. X}
  15713. X
  15714. XJuliafpSetup()
  15715. X{
  15716. X   c_exp = param[2];
  15717. X   floatparm = &parm;
  15718. X   if(fractype==COMPLEXMARKSJUL)
  15719. X   {
  15720. X      pwr.x = param[2] - 1.0;
  15721. X      pwr.y = param[3];
  15722. X      Coefficient = ComplexPower(*floatparm, pwr);
  15723. X   }
  15724. X   switch (fractype)
  15725. X   {
  15726. X   case JULIAFP:
  15727. X    /*
  15728. X       floating point code could probably be altered to handle many of
  15729. X       the situations that otherwise are using StandardFractal().
  15730. X       calcmandfp() can currently handle invert, any rqlim, potflag
  15731. X       zmag, epsilon cross, and all the current outside options
  15732. X                             Wes Loewer 11/03/91
  15733. X    */
  15734. X    if (debugflag != 90
  15735. X        && !distest
  15736. X        && decomp[0] == 0
  15737. X        && biomorph == -1
  15738. X        && (inside >= -1 || inside == -59 || inside == -100)
  15739. X        /* uncomment this next line if more outside options are added */
  15740. X        /* && outside >= -5 */
  15741. X        && useinitorbit != 1
  15742. X        && !finattract
  15743. X        && using_jiim == 0)
  15744. X    {
  15745. X       calctype = calcmandfp; /* the normal case - use calcmandfp */
  15746. X       calcmandfpasmstart();
  15747. X    }
  15748. X    else
  15749. X    {
  15750. X       /* special case: use the main processing loop */
  15751. X       calctype = StandardFractal;
  15752. X       get_julia_attractor (0.0, 0.0);   /* another attractor? */
  15753. X    }
  15754. X    break;
  15755. X   case FPJULIAZPOWER:
  15756. X      if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] )
  15757. X         symmetry = NOSYM;
  15758. X      if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
  15759. X          fractalspecific[fractype].orbitcalc = floatZpowerFractal;
  15760. X      else
  15761. X          fractalspecific[fractype].orbitcalc = floatCmplxZpowerFractal;
  15762. X      get_julia_attractor (param[0], param[1]);    /* another attractor? */
  15763. X      break;
  15764. X   case MAGNET2J:
  15765. X      FloatPreCalcMagnet2();
  15766. X   case MAGNET1J:
  15767. X      attr[0].x = 1.0;        /* 1.0 + 0.0i always attracts */
  15768. X      attr[0].y = 0.0;        /* - both MAGNET1 and MAGNET2 */
  15769. X      attrperiod[0] = 1;
  15770. X      attractors = 1;
  15771. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15772. X      break;
  15773. X   case LAMBDAFP:
  15774. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15775. X      get_julia_attractor (0.5, 0.0);    /* another attractor? */
  15776. X      break;
  15777. X   case LAMBDAEXP:
  15778. X      if(parm.y == 0.0)
  15779. X     symmetry=XAXIS;
  15780. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15781. X      break;
  15782. X/* Added to account for symmetry in julfn+exp and julfn+zsqrd */
  15783. X/*     JCO 2/29/92 */
  15784. X   case FPJULTRIGPLUSEXP:
  15785. X   case FPJULTRIGPLUSZSQRD:
  15786. X     if(parm.y == 0.0)
  15787. X        symmetry = XAXIS;
  15788. X     else
  15789. X        symmetry = NOSYM;
  15790. X     if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
  15791. X        symmetry = NOSYM;
  15792. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15793. X      break;
  15794. X   case HYPERCMPLXJFP:
  15795. X      if(trigndx[0] != SQR)
  15796. X         symmetry=NOSYM;
  15797. X   case QUATJULFP:
  15798. X      attractors = 0;    /* attractors broken since code checks r,i not j,k */
  15799. X      periodicitycheck = 0;
  15800. X      if(param[4] != 0.0 || param[5] != 0)
  15801. X         symmetry = NOSYM;
  15802. X      break;
  15803. X   default:
  15804. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15805. X      break;
  15806. X   }
  15807. X   return(1);
  15808. X}
  15809. X
  15810. XMandellongSetup()
  15811. X{
  15812. X   FgHalf = fudge >> 1;
  15813. X   c_exp = param[2];
  15814. X   if(fractype==MARKSMANDEL && c_exp < 1)
  15815. X      c_exp = 1;
  15816. X   if(fractype==LMANDELZPOWER && c_exp < 1)
  15817. X      c_exp = 1;
  15818. X   if((fractype==MARKSMANDEL   && !(c_exp & 1)) ||
  15819. X       (fractype==LMANDELZPOWER && c_exp & 1))
  15820. X      symmetry = XYAXIS_NOPARM;    /* odd exponents */
  15821. X   if((fractype==MARKSMANDEL && (c_exp & 1)) || fractype==LMANDELEXP)
  15822. X      symmetry = XAXIS_NOPARM;
  15823. X   if(fractype==SPIDER && periodicitycheck==1)
  15824. X      periodicitycheck=4;
  15825. X   longparm = &linit;
  15826. X   if(fractype==LMANDELZPOWER)
  15827. X   {
  15828. X      if(param[3] == 0.0 && debugflag != 6000  && (double)c_exp == param[2])
  15829. X          fractalspecific[fractype].orbitcalc = longZpowerFractal;
  15830. X      else
  15831. X          fractalspecific[fractype].orbitcalc = longCmplxZpowerFractal;
  15832. X      if(param[3] != 0 || (double)c_exp != param[2] )
  15833. X         symmetry = NOSYM;
  15834. X    }
  15835. X/* Added to account for symmetry in manfn+exp and manfn+zsqrd */
  15836. X/*     JCO 2/29/92 */
  15837. X   if((fractype==LMANTRIGPLUSEXP)||(fractype==LMANTRIGPLUSZSQRD))
  15838. X   {
  15839. X     if(parm.y == 0.0)
  15840. X        symmetry = XAXIS;
  15841. X     else
  15842. X        symmetry = NOSYM;
  15843. X     if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
  15844. X        symmetry = NOSYM;
  15845. X   }
  15846. X   return(1);
  15847. X}
  15848. X
  15849. XJulialongSetup()
  15850. X{
  15851. X   c_exp = param[2];
  15852. X   longparm = &lparm;
  15853. X   switch (fractype)
  15854. X   {
  15855. X   case LJULIAZPOWER:
  15856. X      if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2])
  15857. X         symmetry = NOSYM;
  15858. X      else if(c_exp < 1)
  15859. X         c_exp = 1;
  15860. X      if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
  15861. X          fractalspecific[fractype].orbitcalc = longZpowerFractal;
  15862. X      else
  15863. X          fractalspecific[fractype].orbitcalc = longCmplxZpowerFractal;
  15864. X      break;
  15865. X   case LAMBDA:
  15866. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15867. X      get_julia_attractor (0.5, 0.0);    /* another attractor? */
  15868. X      break;
  15869. X   case LLAMBDAEXP:
  15870. X      if(lparm.y == 0)
  15871. X     symmetry = XAXIS;
  15872. X      break;
  15873. X/* Added to account for symmetry in julfn+exp and julfn+zsqrd */
  15874. X/*     JCO 2/29/92 */
  15875. X   case LJULTRIGPLUSEXP:
  15876. X   case LJULTRIGPLUSZSQRD:
  15877. X     if(parm.y == 0.0)
  15878. X        symmetry = XAXIS;
  15879. X     else
  15880. X        symmetry = NOSYM;
  15881. X     if ((trigndx[0] == LOG) || (trigndx[0] == 14)) /* LOG or FLIP */
  15882. X        symmetry = NOSYM;
  15883. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15884. X      break;
  15885. X   default:
  15886. X      get_julia_attractor (0.0, 0.0);    /* another attractor? */
  15887. X      break;
  15888. X   }
  15889. X   return(1);
  15890. X}
  15891. X
  15892. XTrigPlusSqrlongSetup()
  15893. X{
  15894. X   curfractalspecific->per_pixel =  julia_per_pixel;
  15895. X   curfractalspecific->orbitcalc =  TrigPlusSqrFractal;
  15896. X   if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90)
  15897. X   {
  15898. X      if(lparm2.x == fudge)       /* Scott variant */
  15899. X     curfractalspecific->orbitcalc =  ScottTrigPlusSqrFractal;
  15900. X      else if(lparm2.x == -fudge)  /* Skinner variant */
  15901. X     curfractalspecific->orbitcalc =  SkinnerTrigSubSqrFractal;
  15902. X   }
  15903. X   return(JulialongSetup());
  15904. X}
  15905. X
  15906. XTrigPlusSqrfpSetup()
  15907. X{
  15908. X   curfractalspecific->per_pixel =  juliafp_per_pixel;
  15909. X   curfractalspecific->orbitcalc =  TrigPlusSqrfpFractal;
  15910. X   if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90)
  15911. X   {
  15912. X      if(parm2.x == 1.0)    /* Scott variant */
  15913. X     curfractalspecific->orbitcalc =  ScottTrigPlusSqrfpFractal;
  15914. X      else if(parm2.x == -1.0)    /* Skinner variant */
  15915. X     curfractalspecific->orbitcalc =  SkinnerTrigSubSqrfpFractal;
  15916. X   }
  15917. X   return(JuliafpSetup());
  15918. X}
  15919. X
  15920. XTrigPlusTriglongSetup()
  15921. X{
  15922. X   FnPlusFnSym();
  15923. X   if(trigndx[1] == SQR)
  15924. X      return(TrigPlusSqrlongSetup());
  15925. X   curfractalspecific->per_pixel =  long_julia_per_pixel;
  15926. X   curfractalspecific->orbitcalc =  TrigPlusTrigFractal;
  15927. X   if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90)
  15928. X   {
  15929. X      if(lparm2.x == fudge)       /* Scott variant */
  15930. X     curfractalspecific->orbitcalc =  ScottTrigPlusTrigFractal;
  15931. X      else if(lparm2.x == -fudge)  /* Skinner variant */
  15932. X     curfractalspecific->orbitcalc =  SkinnerTrigSubTrigFractal;
  15933. X   }
  15934. X   return(JulialongSetup());
  15935. X}
  15936. X
  15937. XTrigPlusTrigfpSetup()
  15938. X{
  15939. X   FnPlusFnSym();
  15940. X   if(trigndx[1] == SQR)
  15941. X      return(TrigPlusSqrfpSetup());
  15942. X   curfractalspecific->per_pixel =  otherjuliafp_per_pixel;
  15943. X   curfractalspecific->orbitcalc =  TrigPlusTrigfpFractal;
  15944. X   if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90)
  15945. X   {
  15946. X      if(parm2.x == 1.0)    /* Scott variant */
  15947. X     curfractalspecific->orbitcalc =  ScottTrigPlusTrigfpFractal;
  15948. X      else if(parm2.x == -1.0)    /* Skinner variant */
  15949. X     curfractalspecific->orbitcalc =  SkinnerTrigSubTrigfpFractal;
  15950. X   }
  15951. X   return(JuliafpSetup());
  15952. X}
  15953. X
  15954. XFnPlusFnSym() /* set symmetry matrix for fn+fn type */
  15955. X{
  15956. X   static char far fnplusfn[7][7] =
  15957. X   {/* fn2 ->sin     cos    sinh    cosh   exp    log    sqr  */
  15958. X   /* fn1 */
  15959. X   /* sin */ {PI_SYM,XAXIS, XYAXIS, XAXIS, XAXIS, XAXIS, XAXIS},
  15960. X   /* cos */ {XAXIS, PI_SYM,XAXIS,  XYAXIS,XAXIS, XAXIS, XAXIS},
  15961. X   /* sinh*/ {XYAXIS,XAXIS, XYAXIS, XAXIS, XAXIS, XAXIS, XAXIS},
  15962. X   /* cosh*/ {XAXIS, XYAXIS,XAXIS,  XYAXIS,XAXIS, XAXIS, XAXIS},
  15963. X   /* exp */ {XAXIS, XYAXIS,XAXIS,  XAXIS, XYAXIS,XAXIS, XAXIS},
  15964. X   /* log */ {XAXIS, XAXIS, XAXIS,  XAXIS, XAXIS, XAXIS, XAXIS},
  15965. X   /* sqr */ {XAXIS, XAXIS, XAXIS,  XAXIS, XAXIS, XAXIS, XYAXIS}
  15966. X   };
  15967. X   if(parm.y == 0.0 && parm2.y == 0.0)
  15968. X    { if(trigndx[0] < 7 && trigndx[1] < 7)  /* bounds of array JCO 5/6/92*/
  15969. X        symmetry = fnplusfn[trigndx[0]][trigndx[1]];  /* JCO 5/6/92 */
  15970. X    }                 /* defaults to XAXIS symmetry JCO 5/6/92 */
  15971. X   else
  15972. X      symmetry = NOSYM;
  15973. X   return(0);
  15974. X}
  15975. X
  15976. XLambdaTrigOrTrigSetup()
  15977. X{
  15978. X/* default symmetry is ORIGIN  JCO 2/29/92 (changed from PI_SYM) */
  15979. X   longparm = &lparm; /* added to consolidate code 10/1/92 JCO */
  15980. X   floatparm = &parm;
  15981. X   if ((trigndx[0] == EXP) || (trigndx[1] == EXP))
  15982. X      symmetry = NOSYM; /* JCO 1/9/93 */
  15983. X   if ((trigndx[0] == LOG) || (trigndx[1] == LOG))
  15984. X      symmetry = XAXIS;
  15985. X   get_julia_attractor (0.0, 0.0);    /* an attractor? */
  15986. X   return(1);
  15987. X}
  15988. X
  15989. XJuliaTrigOrTrigSetup()
  15990. X{
  15991. X/* default symmetry is XAXIS */
  15992. X   longparm = &lparm; /* added to consolidate code 10/1/92 JCO */
  15993. X   floatparm = &parm;
  15994. X   if(parm.y != 0.0)
  15995. X     symmetry = NOSYM;
  15996. X   get_julia_attractor (0.0, 0.0);    /* an attractor? */
  15997. X   return(1);
  15998. X}
  15999. X
  16000. XManlamTrigOrTrigSetup()
  16001. X{ /* psuedo */
  16002. X/* default symmetry is XAXIS */
  16003. X   longparm = &linit; /* added to consolidate code 10/1/92 JCO */
  16004. X   floatparm = &init;
  16005. X   if (trigndx[0] == SQR)
  16006. X      symmetry = NOSYM;
  16007. X   if ((trigndx[0] == LOG) || (trigndx[1] == LOG))
  16008. X      symmetry = NOSYM;
  16009. X   return(1);
  16010. X}
  16011. X
  16012. XMandelTrigOrTrigSetup()
  16013. X{
  16014. X/* default symmetry is XAXIS_NOPARM */
  16015. X   longparm = &linit; /* added to consolidate code 10/1/92 JCO */
  16016. X   floatparm = &init;
  16017. X   if ((trigndx[0] == 14) || (trigndx[1] == 14)) /* FLIP  JCO 5/28/92 */
  16018. X      symmetry = NOSYM;
  16019. X   return(1);
  16020. X}
  16021. X
  16022. X
  16023. XZXTrigPlusZSetup()
  16024. X{
  16025. X/*   static char far ZXTrigPlusZSym1[] = */
  16026. X   /* fn1 ->  sin   cos    sinh  cosh exp   log   sqr */
  16027. X/*         {XAXIS,XYAXIS,XAXIS,XYAXIS,XAXIS,NOSYM,XYAXIS}; */
  16028. X/*   static char far ZXTrigPlusZSym2[] = */
  16029. X   /* fn1 ->  sin   cos    sinh  cosh exp   log   sqr */
  16030. X/*         {NOSYM,ORIGIN,NOSYM,ORIGIN,NOSYM,NOSYM,ORIGIN}; */
  16031. X
  16032. X   if(param[1] == 0.0 && param[3] == 0.0)
  16033. X/*      symmetry = ZXTrigPlusZSym1[trigndx[0]]; */
  16034. X   switch(trigndx[0])
  16035. X   {
  16036. X      case COS:   /* changed to two case statments and made any added */
  16037. X      case COSH:  /* functions default to XAXIS symmetry. JCO 5/25/92 */
  16038. X      case SQR:
  16039. X      case 9:   /* 'real' cos */
  16040. X         symmetry = XYAXIS;
  16041. X         break;
  16042. X      case 14:   /* FLIP  JCO 2/29/92 */
  16043. X         symmetry = YAXIS;
  16044. X         break;
  16045. X      case LOG:
  16046. X         symmetry = NOSYM;
  16047. X         break;
  16048. X      default:
  16049. X         symmetry = XAXIS;
  16050. X         break;
  16051. X      }
  16052. X   else
  16053. X/*      symmetry = ZXTrigPlusZSym2[trigndx[0]]; */
  16054. X   switch(trigndx[0])
  16055. X   {
  16056. X      case COS:
  16057. X      case COSH:
  16058. X      case SQR:
  16059. X      case 9:   /* 'real' cos */
  16060. X         symmetry = ORIGIN;
  16061. X         break;
  16062. X      case 14:   /* FLIP  JCO 2/29/92 */
  16063. X         symmetry = NOSYM;
  16064. X         break;
  16065. X      default:
  16066. X         symmetry = XAXIS;
  16067. X         break;
  16068. X      }
  16069. X   if(curfractalspecific->isinteger)
  16070. X   {
  16071. X      curfractalspecific->orbitcalc =  ZXTrigPlusZFractal;
  16072. X      if(lparm.x == fudge && lparm.y == 0L && lparm2.y == 0L && debugflag != 90)
  16073. X      {
  16074. X     if(lparm2.x == fudge)       /* Scott variant */
  16075. X         curfractalspecific->orbitcalc =  ScottZXTrigPlusZFractal;
  16076. X     else if(lparm2.x == -fudge)  /* Skinner variant */
  16077. X         curfractalspecific->orbitcalc =  SkinnerZXTrigSubZFractal;
  16078. X      }
  16079. X      return(JulialongSetup());
  16080. X   }
  16081. X   else
  16082. X   {
  16083. X      curfractalspecific->orbitcalc =  ZXTrigPlusZfpFractal;
  16084. X      if(parm.x == 1.0 && parm.y == 0.0 && parm2.y == 0.0 && debugflag != 90)
  16085. X      {
  16086. X     if(parm2.x == 1.0)    /* Scott variant */
  16087. X         curfractalspecific->orbitcalc =  ScottZXTrigPlusZfpFractal;
  16088. X     else if(parm2.x == -1.0)    /* Skinner variant */
  16089. X         curfractalspecific->orbitcalc =  SkinnerZXTrigSubZfpFractal;
  16090. X      }
  16091. X   }
  16092. X   return(JuliafpSetup());
  16093. X}
  16094. X
  16095. XLambdaTrigSetup()
  16096. X{
  16097. X   int isinteger;
  16098. X   if((isinteger = curfractalspecific->isinteger))
  16099. X      curfractalspecific->orbitcalc =  LambdaTrigFractal;
  16100. X   else
  16101. X      curfractalspecific->orbitcalc =  LambdaTrigfpFractal;
  16102. X   switch(trigndx[0])
  16103. X   {
  16104. X   case SIN:
  16105. X   case COS:
  16106. X   case 9:   /* 'real' cos, added this and default for additional functions */
  16107. X      symmetry = PI_SYM;
  16108. X      if(isinteger)
  16109. X     curfractalspecific->orbitcalc =  LambdaTrigFractal1;
  16110. X      else
  16111. X     curfractalspecific->orbitcalc =  LambdaTrigfpFractal1;
  16112. X      break;
  16113. X   case SINH:
  16114. X   case COSH:
  16115. X      symmetry = ORIGIN;
  16116. X      if(isinteger)
  16117. X     curfractalspecific->orbitcalc =  LambdaTrigFractal2;
  16118. X      else
  16119. X     curfractalspecific->orbitcalc =  LambdaTrigfpFractal2;
  16120. X      break;
  16121. X   case SQR:
  16122. X      symmetry = ORIGIN;
  16123. X      break;
  16124. X   case EXP:
  16125. X      if(isinteger)
  16126. X     curfractalspecific->orbitcalc =  LongLambdaexponentFractal;
  16127. X      else
  16128. X     curfractalspecific->orbitcalc =  LambdaexponentFractal;
  16129. X      symmetry = NOSYM; /* JCO 1/9/93 */
  16130. X      break;
  16131. X   case LOG:
  16132. X      symmetry = NOSYM;
  16133. X      break;
  16134. X   default:   /* default for additional functions */
  16135. X      symmetry = ORIGIN;  /* JCO 5/8/92 */
  16136. X      break;
  16137. X   }
  16138. X   get_julia_attractor (0.0, 0.0);    /* an attractor? */
  16139. X   if(isinteger)
  16140. X      return(JulialongSetup());
  16141. X   else
  16142. X      return(JuliafpSetup());
  16143. X}
  16144. X
  16145. XJuliafnPlusZsqrdSetup()
  16146. X{
  16147. X/*   static char far fnpluszsqrd[] = */
  16148. X   /* fn1 ->  sin   cos    sinh  cosh    sqr    exp   log  */
  16149. X   /* sin    {NOSYM,ORIGIN,NOSYM,ORIGIN,ORIGIN,NOSYM,NOSYM}; */
  16150. X
  16151. X/*   symmetry = fnpluszsqrd[trigndx[0]];   JCO  5/8/92 */
  16152. X   switch(trigndx[0]) /* fix sqr symmetry & add additional functions */
  16153. X   {
  16154. X   case COS: /* cosxx */
  16155. X   case COSH:
  16156. X   case SQR:
  16157. X   case 9:   /* 'real' cos */
  16158. X   case 10:  /* tan */
  16159. X   case 11:  /* tanh */
  16160. X   symmetry = ORIGIN;
  16161. X    /* default is for NOSYM symmetry */
  16162. X   }
  16163. X   if(curfractalspecific->isinteger)
  16164. X      return(JulialongSetup());
  16165. X   else
  16166. X      return(JuliafpSetup());
  16167. X}
  16168. X
  16169. XSqrTrigSetup()
  16170. X{
  16171. X/*   static char far SqrTrigSym[] = */
  16172. X   /* fn1 ->  sin    cos    sinh   cosh   sqr     exp   log  */
  16173. X/*         {PI_SYM,PI_SYM,XYAXIS,XYAXIS,XYAXIS,XAXIS,XAXIS}; */
  16174. X/*   symmetry = SqrTrigSym[trigndx[0]];      JCO  5/9/92 */
  16175. X   switch(trigndx[0]) /* fix sqr symmetry & add additional functions */
  16176. X   {
  16177. X   case SIN:
  16178. X   case COS: /* cosxx */
  16179. X   case 9:   /* 'real' cos */
  16180. X   symmetry = PI_SYM;
  16181. X    /* default is for XAXIS symmetry */
  16182. X   }
  16183. X   if(curfractalspecific->isinteger)
  16184. X      return(JulialongSetup());
  16185. X   else
  16186. X      return(JuliafpSetup());
  16187. X}
  16188. X
  16189. XFnXFnSetup()
  16190. X{
  16191. X   static char far fnxfn[7][7] =
  16192. X   {/* fn2 ->sin     cos    sinh    cosh  exp    log    sqr */
  16193. X   /* fn1 */
  16194. X   /* sin */ {PI_SYM,YAXIS, XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
  16195. X   /* cos */ {YAXIS, PI_SYM,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
  16196. X   /* sinh*/ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
  16197. X   /* cosh*/ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XAXIS, NOSYM, XYAXIS},
  16198. X   /* exp */ {XAXIS, XAXIS, XAXIS, XAXIS, XAXIS, NOSYM, XYAXIS},
  16199. X   /* log */ {NOSYM, NOSYM, NOSYM, NOSYM, NOSYM, XAXIS, NOSYM},
  16200. X   /* sqr */ {XYAXIS,XYAXIS,XYAXIS,XYAXIS,XYAXIS,NOSYM, XYAXIS},
  16201. X   };
  16202. X   /*
  16203. X   if(trigndx[0]==EXP || trigndx[0]==LOG || trigndx[1]==EXP || trigndx[1]==LOG)
  16204. X      symmetry = XAXIS;
  16205. X   else if((trigndx[0]==SIN && trigndx[1]==SIN)||(trigndx[0]==COS && trigndx[1]==COS))
  16206. X      symmetry = PI_SYM;
  16207. X   else if((trigndx[0]==SIN && trigndx[1]==COS)||(trigndx[0]==COS && trigndx[1]==SIN))
  16208. X      symmetry = YAXIS;
  16209. X   else
  16210. X      symmetry = XYAXIS;
  16211. X   */
  16212. X   if(trigndx[0] < 7 && trigndx[1] < 7)  /* bounds of array JCO 5/22/92*/
  16213. X        symmetry = fnxfn[trigndx[0]][trigndx[1]];  /* JCO 5/22/92 */
  16214. X                    /* defaults to XAXIS symmetry JCO 5/22/92 */
  16215. X   else {  /* added to complete the symmetry JCO 5/22/92 */
  16216. X      if (trigndx[0]==LOG || trigndx[1] ==LOG) symmetry = NOSYM;
  16217. X      if (trigndx[0]==9 || trigndx[1] ==9) { /* 'real' cos */
  16218. X         if (trigndx[0]==SIN || trigndx[1] ==SIN) symmetry = PI_SYM;
  16219. X         if (trigndx[0]==COS || trigndx[1] ==COS) symmetry = PI_SYM;
  16220. X      }
  16221. X      if (trigndx[0]==9 && trigndx[1] ==9) symmetry = PI_SYM;
  16222. X   }
  16223. X   if(curfractalspecific->isinteger)
  16224. X      return(JulialongSetup());
  16225. X   else
  16226. X      return(JuliafpSetup());
  16227. X}
  16228. X
  16229. XMandelTrigSetup()
  16230. X{
  16231. X   int isinteger;
  16232. X   if((isinteger = curfractalspecific->isinteger))
  16233. X      curfractalspecific->orbitcalc =  LambdaTrigFractal;
  16234. X   else
  16235. X      curfractalspecific->orbitcalc =  LambdaTrigfpFractal;
  16236. X   symmetry = XYAXIS_NOPARM;
  16237. X   switch(trigndx[0])
  16238. X   {
  16239. X   case SIN:
  16240. X   case COS:
  16241. X      if(isinteger)
  16242. X     curfractalspecific->orbitcalc =  LambdaTrigFractal1;
  16243. X      else
  16244. X     curfractalspecific->orbitcalc =  LambdaTrigfpFractal1;
  16245. X      break;
  16246. X   case SINH:
  16247. X   case COSH:
  16248. X      if(isinteger)
  16249. X     curfractalspecific->orbitcalc =  LambdaTrigFractal2;
  16250. X      else
  16251. X     curfractalspecific->orbitcalc =  LambdaTrigfpFractal2;
  16252. X      break;
  16253. X   case EXP:
  16254. X      symmetry = XAXIS_NOPARM;
  16255. X      if(isinteger)
  16256. X     curfractalspecific->orbitcalc =  LongLambdaexponentFractal;
  16257. X      else
  16258. X     curfractalspecific->orbitcalc =  LambdaexponentFractal;
  16259. X      break;
  16260. X   case LOG:
  16261. X      symmetry = XAXIS_NOPARM;
  16262. X      break;
  16263. X   default:   /* added for additional functions, JCO 5/25/92 */
  16264. X      symmetry = XYAXIS_NOPARM;
  16265. X      break;
  16266. X   }
  16267. X   if(isinteger)
  16268. X      return(MandellongSetup());
  16269. X   else
  16270. X      return(MandelfpSetup());
  16271. X}
  16272. X
  16273. XMarksJuliaSetup()
  16274. X{
  16275. X   c_exp = param[2];
  16276. X   longparm = &lparm;
  16277. X   lold = *longparm;
  16278. X   if(c_exp > 2)
  16279. X      lcpower(&lold,c_exp,&lcoefficient,bitshift);
  16280. X   else if(c_exp == 2)
  16281. X   {
  16282. X      lcoefficient.x = multiply(lold.x,lold.x,bitshift) - multiply(lold.y,lold.y,bitshift);
  16283. X      lcoefficient.y = multiply(lold.x,lold.y,bitshiftless1);
  16284. X   }
  16285. X   else if(c_exp < 2)
  16286. X      lcoefficient = lold;
  16287. X   get_julia_attractor (0.0, 0.0);    /* an attractor? */
  16288. X   return(1);
  16289. X}
  16290. X
  16291. XMarksJuliafpSetup()
  16292. X{
  16293. X   c_exp = param[2];
  16294. X   floatparm = &parm;
  16295. X   old = *floatparm;
  16296. X   if(c_exp > 2)
  16297. X      cpower(&old,c_exp,&coefficient);
  16298. X   else if(c_exp == 2)
  16299. X   {
  16300. X      coefficient.x = sqr(old.x) - sqr(old.y);
  16301. X      coefficient.y = old.x * old.y * 2;
  16302. X   }
  16303. X   else if(c_exp < 2)
  16304. X      coefficient = old;
  16305. X   get_julia_attractor (0.0, 0.0);    /* an attractor? */
  16306. X   return(1);
  16307. X}
  16308. X
  16309. XSierpinskiSetup()
  16310. X{
  16311. X   /* sierpinski */
  16312. X   periodicitycheck = 0;        /* disable periodicity checks */
  16313. X   ltmp.x = 1;
  16314. X   ltmp.x = ltmp.x << bitshift; /* ltmp.x = 1 */
  16315. X   ltmp.y = ltmp.x >> 1;            /* ltmp.y = .5 */
  16316. X   return(1);
  16317. X}
  16318. X
  16319. XSierpinskiFPSetup()
  16320. X{
  16321. X   /* sierpinski */
  16322. X   periodicitycheck = 0;        /* disable periodicity checks */
  16323. X   tmp.x = 1;
  16324. X   tmp.y = 0.5;
  16325. X   return(1);
  16326. X}
  16327. X
  16328. Xextern char usr_floatflag;
  16329. X
  16330. XHalleySetup()
  16331. X{
  16332. X   /* Halley */
  16333. X   periodicitycheck=0;
  16334. X
  16335. X   if(usr_floatflag)
  16336. X     fractype = HALLEY; /* float on */
  16337. X   else
  16338. X     fractype = MPHALLEY;
  16339. X
  16340. X   curfractalspecific = &fractalspecific[fractype];
  16341. X
  16342. X   degree = (int)parm.x;
  16343. X   if(degree < 2)
  16344. X      degree = 2;
  16345. X   param[0] = (double)degree;
  16346. X
  16347. X/*  precalculated values */
  16348. X   AplusOne = degree + 1; /* a+1 */
  16349. X   Ap1deg = AplusOne * degree;
  16350. X
  16351. X#ifndef XFRACT
  16352. X   if(fractype == MPHALLEY) {
  16353. X      setMPfunctions();
  16354. X      mpAplusOne = *pd2MP((double)AplusOne);
  16355. X      mpAp1deg = *pd2MP((double)Ap1deg);
  16356. X      mptmpparmy = *pd2MP(parm.y);
  16357. X      mptmpparm2x = *pd2MP(parm2.x);
  16358. X      mpone       = *pd2MP(1.0);
  16359. X   }
  16360. X#endif
  16361. X
  16362. X   if(degree % 2)
  16363. X     symmetry = XAXIS;   /* odd */
  16364. X   else
  16365. X     symmetry = XYAXIS; /* even */
  16366. X   return(1);
  16367. X}
  16368. X
  16369. XPhoenixSetup()
  16370. X{
  16371. X   longparm = &lparm; /* added to consolidate code 10/1/92 JCO */
  16372. X   floatparm = &parm;
  16373. X   degree = (int)parm2.x;
  16374. X   if(degree < 2 && degree > -3) degree = 0;
  16375. X   param[2] = (double)degree;
  16376. X   if(degree == 0){
  16377. X     if(usr_floatflag)
  16378. X       curfractalspecific->orbitcalc =  PhoenixFractal;
  16379. X     else
  16380. X       curfractalspecific->orbitcalc =  LongPhoenixFractal;
  16381. X   }
  16382. X   if(degree >= 2){
  16383. X     degree = degree - 1;
  16384. X     if(usr_floatflag)
  16385. X       curfractalspecific->orbitcalc =  PhoenixPlusFractal;
  16386. X     else
  16387. X       curfractalspecific->orbitcalc =  LongPhoenixPlusFractal;
  16388. X   }
  16389. X   if(degree <= -3){
  16390. X     degree = abs(degree) - 2;
  16391. X     if(degree % 2)
  16392. X       symmetry = XYAXIS; /* odd */
  16393. X     else
  16394. X       symmetry = XAXIS; /* even */
  16395. X     if(usr_floatflag)
  16396. X       curfractalspecific->orbitcalc =  PhoenixMinusFractal;
  16397. X     else
  16398. X       curfractalspecific->orbitcalc =  LongPhoenixMinusFractal;
  16399. X   }
  16400. X
  16401. X   return(1);
  16402. X}
  16403. X
  16404. XMandPhoenixSetup()
  16405. X{
  16406. X   longparm = &linit; /* added to consolidate code 10/1/92 JCO */
  16407. X   floatparm = &init;
  16408. X   degree = (int)parm2.x;
  16409. X   if(degree < 2 && degree > -3) degree = 0;
  16410. X   param[2] = (double)degree;
  16411. X   if(degree == 0){
  16412. X     if(usr_floatflag)
  16413. X       curfractalspecific->orbitcalc =  PhoenixFractal;
  16414. X     else
  16415. X       curfractalspecific->orbitcalc =  LongPhoenixFractal;
  16416. X   }
  16417. X   if(degree >= 2){
  16418. X     degree = degree - 1;
  16419. X     if(usr_floatflag)
  16420. X       curfractalspecific->orbitcalc =  PhoenixPlusFractal;
  16421. X     else
  16422. X       curfractalspecific->orbitcalc =  LongPhoenixPlusFractal;
  16423. X   }
  16424. X   if(degree <= -3){
  16425. X     degree = abs(degree) - 2;
  16426. X     if(usr_floatflag)
  16427. X       curfractalspecific->orbitcalc =  PhoenixMinusFractal;
  16428. X     else
  16429. X       curfractalspecific->orbitcalc =  LongPhoenixMinusFractal;
  16430. X   }
  16431. X
  16432. X   return(1);
  16433. X}
  16434. X
  16435. XStandardSetup()
  16436. X{
  16437. X   if(fractype==UNITYFP)
  16438. X      periodicitycheck=0;
  16439. X   return(1);
  16440. X}
  16441. X
  16442. Xdemowalk()
  16443. X{
  16444. X    extern double param[];        /* optional user parameters */
  16445. X    extern int maxit;            /* maximum iterations (steps) */
  16446. X    extern int rflag, rseed;        /* random number seed */
  16447. X    extern int xdots, ydots;        /* image coordinates */
  16448. X    extern int colors;                  /* maximum colors available */
  16449. X    extern double far *dx0, far *dy0;    /* arrays of pixel coordinates */
  16450. X    extern double far *dx1, far *dy1;    /* (... for skewed zoom-boxes) */
  16451. X
  16452. X    float stepsize;            /* average stepsize */
  16453. X    int xwalk, ywalk;            /* current position */
  16454. X    int xstep, ystep;            /* current step */
  16455. X    int steps;                /* number of steps */
  16456. X    int color;                /* color to draw this step */
  16457. X    float temp, tempadjust;        /* temporary variables */
  16458. X
  16459. Xif (param[0] != 999) {            /* if 999, do a Mandelbrot instead */
  16460. X
  16461. X    srand(rseed);            /* seed the random number generator */
  16462. X    if (!rflag) ++rseed;
  16463. X    tempadjust = RAND_MAX >> 2;        /* adjustment factor */
  16464. X
  16465. X    xwalk = xdots / 2;            /* start in the center of the image */
  16466. X    ywalk = ydots / 2;
  16467. X
  16468. X    stepsize = min(xdots, ydots)     /* calculate average stepsize */
  16469. X               * (param[0]/100.0);    /* as a percentage of the image */
  16470. X
  16471. X    color = max(0, min(colors, param[1]));  /* set the initial color */  
  16472. X
  16473. X    for (steps = 0; steps < maxit; steps++) { /* take maxit steps */
  16474. X        if (keypressed())        /* abort if told to do so */
  16475. X            return(0);
  16476. X        temp = rand();            /* calculate the next xstep */
  16477. X        xstep = ((temp/tempadjust) - 2.0) * stepsize;
  16478. X        xstep = min(xwalk + xstep, xdots - 1);
  16479. X        xstep = max(0, xstep);
  16480. X        temp = rand();            /* calculate the next ystep */
  16481. X        ystep = ((temp/tempadjust) - 2.0) * stepsize;
  16482. X        ystep = min(ywalk + ystep, ydots - 1);
  16483. X        ystep = max(0, ystep);
  16484. X        if (param[1] == 0.0)        /* rotate the colors? */
  16485. X            if (++color >= colors)    /* rotate the colors, avoiding */
  16486. X                color = 1;        /* the background color 0 */
  16487. X        /* the draw_line function is borrowed from the 3D routines */
  16488. X        draw_line(xwalk, ywalk,xstep,ystep,color);
  16489. X        /* or, we could be on a pogo stick and just displaying
  16490. X           where we landed...
  16491. X        putcolor(xstep, ystep, color);
  16492. X        */
  16493. X
  16494. X        xwalk = xstep;            /* remember where we were */
  16495. X        ywalk = ystep;
  16496. X        }
  16497. X    return(1);                          /* we're done */
  16498. X
  16499. X} else {                /* a simple Mandelbrot routine */
  16500. X
  16501. X    /* the following routine determines the X and Y values of
  16502. X       each pixel coordinate and calculates a simple mandelbrot
  16503. X       fractal with them - slowly, but surely */
  16504. X    int ix, iy;
  16505. X    for (iy = 0; iy < ydots; iy++) {
  16506. X        for (ix = 0; ix < xdots; ix++) {
  16507. X            int iter;
  16508. X            double x, y, newx, newy, tempxx, tempxy, tempyy;
  16509. X            /* first, obtain the X and Y coordinate values of this pixel */
  16510. X            x = dx0[ix]+dx1[iy];
  16511. X            y = dy0[iy]+dy1[ix];
  16512. X            /* now initialize the temporary values */
  16513. X            tempxx = tempyy = tempxy = 0.0;
  16514. X            if (keypressed())        /* abort if told to do so */
  16515. X                return(0);
  16516. X            /* the inner iteration loop */
  16517. X            for (iter = 1; iter < maxit; iter++) {
  16518. X                /* calculate the X and Y values of Z(iter) */
  16519. X                newx = tempxx - tempyy + x;
  16520. X                newy = tempxy + tempxy + y;
  16521. X                /* calculate the temporary values */
  16522. X                tempxx = newx * newx;
  16523. X                tempyy = newy * newy;
  16524. X                tempxy = newx * newy;
  16525. X                /* are we done yet? */
  16526. X                if (tempxx + tempyy > 4.0) break;
  16527. X                }
  16528. X            /* color in the pixel */
  16529. X            putcolor(ix, iy, iter & (colors - 1));
  16530. X            }
  16531. X        }
  16532. X    return(1);                          /* we're done */
  16533. X    }
  16534. X
  16535. X}
  16536. SHAR_EOF
  16537. $TOUCH -am 1028230093 fractals.c &&
  16538. chmod 0644 fractals.c ||
  16539. echo "restore of fractals.c failed"
  16540. set `wc -c fractals.c`;Wc_c=$1
  16541. if test "$Wc_c" != "101275"; then
  16542.     echo original size 101275, current size $Wc_c
  16543. fi
  16544. # ============= fractint.c ==============
  16545. echo "x - extracting fractint.c (Text)"
  16546. sed 's/^X//' << 'SHAR_EOF' > fractint.c &&
  16547. X/*
  16548. X    FRACTINT - The Ultimate Fractal Generator
  16549. X            Main Routine
  16550. X*/
  16551. X
  16552. X#include <stdlib.h>
  16553. X#include <stdio.h>
  16554. X#include <string.h>
  16555. X#include <time.h>
  16556. X#ifndef XFRACT
  16557. X#include <dos.h>
  16558. X#include <stdarg.h>
  16559. X#else
  16560. X#include <varargs.h>
  16561. X#endif
  16562. X#include <ctype.h>
  16563. X#include "prototyp.h"
  16564. X/* routines in this module    */
  16565. X
  16566. Xstatic void cmp_line_cleanup();
  16567. Xstatic void move_zoombox(int);
  16568. Xstatic int call_line3d(BYTE *pixels, int linelen);
  16569. Xvoid clear_zoombox();
  16570. Xstatic void note_zoom();
  16571. Xstatic void restore_zoom();
  16572. Xstatic void setup287code();
  16573. X
  16574. X#ifndef XFRACT
  16575. Xextern    int timer(int timertype,int(*subrtn)(),...);
  16576. X#else
  16577. Xextern  int timer();
  16578. X#endif
  16579. X
  16580. X#define PUTTHEMHERE 1        /* stuff common external arrays here */
  16581. X
  16582. X#include "fractint.h"
  16583. X#include "mpmath.h"
  16584. X#include "fractype.h"
  16585. X#include "helpdefs.h"
  16586. X
  16587. Xlong timer_start,timer_interval;    /* timer(...) start & total */
  16588. Xextern int  timerflag;
  16589. X
  16590. Xint    adapter;        /* Video Adapter chosen from list in ...h */
  16591. X
  16592. Xextern double xcjul, ycjul;
  16593. Xextern int soundflag;
  16594. Xextern int julibrot;
  16595. X
  16596. Xextern char gifmask[];
  16597. Xextern int TPlusErr;
  16598. X
  16599. Xextern int save_release, bailout;
  16600. Xextern int Transparent3D, far NewTPFractal, tpdepth;
  16601. Xextern int AntiAliasing, Shadowing;
  16602. Xextern int pot16bit;        /* save 16 bit values for continuous potential */
  16603. Xextern int disk16bit;        /* disk video up & running with 16 bit values */
  16604. Xextern int video_type;        /* coded value indicating video adapter type */
  16605. Xextern int usr_biomorph;
  16606. Xextern int escape_exit;
  16607. Xextern int forcesymmetry;
  16608. Xextern float  screenaspect;
  16609. Xextern    char    readname[];    /* name of fractal input file */
  16610. Xextern    int    showfile;    /* zero if display of file is pending */
  16611. X#define MAXHISTORY    10    /* save this many historical rcds */
  16612. Xstruct historystruct {        /* history structure */
  16613. X    int fractype;        /* fractal type */
  16614. X    double param[MAXPARAMS];/* parameters   */
  16615. X    double xxmin;        /* top left    */
  16616. X    double yymax;        /* top left    */
  16617. X    double xxmax;        /* bottom right */
  16618. X    double yymin;        /* bottom right */
  16619. X    double xx3rd;        /* bottom left    */
  16620. X    double yy3rd;        /* bottom left    */
  16621. X    } far *history;
  16622. X
  16623. Xchar *fract_dir1="", *fract_dir2="";
  16624. X
  16625. X#ifdef __TURBOC__
  16626. X
  16627. X/* yes, I *know* it's supposed to be compatible with Microsoft C,
  16628. X   but some of the routines need to know if the "C" code
  16629. X   has been compiled with Turbo-C.  This flag is a 1 if FRACTINT.C
  16630. X   (and presumably the other routines as well) has been compiled
  16631. X   with Turbo-C. */
  16632. Xint compiled_by_turboc = 1;
  16633. X
  16634. X/* set size to be used for overlays, a bit bigger than largest (help) */
  16635. Xunsigned _ovrbuffer = 54 * 64; /* that's 54k for overlays, counted in paragraphs */
  16636. X
  16637. X#else
  16638. X
  16639. Xint compiled_by_turboc = 0;
  16640. X
  16641. X#endif
  16642. X
  16643. Xextern char savename[];     /* save files using this name */
  16644. Xextern char preview;        /* 3D preview mode flag */
  16645. Xextern char temp1[];        /* temporary strings        */
  16646. Xextern int  debugflag;        /* internal use only - you didn't see this */
  16647. X/*
  16648. X   the following variables are out here only so
  16649. X   that the calcfract() and assembler routines can get at them easily
  16650. X*/
  16651. X    int    active_system = 0;    /* 0 for DOS, WINFRAC for Windows */
  16652. X    int    dotmode;        /* video access method        */
  16653. X    int    textsafe2;        /* textsafe override from videotable */
  16654. X    int    oktoprint;        /* 0 if printf() won't work */
  16655. X    int    sxdots,sydots;        /* # of dots on the physical screen    */
  16656. X    int    sxoffs,syoffs;        /* physical top left of logical screen */
  16657. X    int    xdots, ydots;        /* # of dots on the logical screen     */
  16658. X    double    dxsize, dysize;     /* xdots-1, ydots-1        */
  16659. X    int    colors;         /* maximum colors available */
  16660. X    int    maxit;            /* try this many iterations */
  16661. X    int    boxcount;        /* 0 if no zoom-box yet     */
  16662. X    int    zrotate;        /* zoombox rotation        */
  16663. X    double    zbx,zby;        /* topleft of zoombox        */
  16664. X    double    zwidth,zdepth,zskew;    /* zoombox size & shape     */
  16665. X
  16666. X    int    fractype;        /* if == 0, use Mandelbrot  */
  16667. X    char    stdcalcmode;        /* '1', '2', 'g', 'b'       */
  16668. X    long    creal, cimag;        /* real, imag'ry parts of C */
  16669. X    long    delx, dely;        /* screen pixel increments  */
  16670. X    long    delx2, dely2;        /* screen pixel increments  */
  16671. X    double    delxx, delyy;        /* screen pixel increments  */
  16672. X    double    delxx2, delyy2;     /* screen pixel increments  */
  16673. X    long    delmin;         /* for calcfrac/calcmand    */
  16674. X    double    ddelmin;        /* same as a double        */
  16675. X    double    param[MAXPARAMS];    /* parameters               */
  16676. X    double    potparam[3];        /* three potential parameters*/
  16677. X    long    fudge;            /* 2**fudgefactor        */
  16678. X    long    l_at_rad;        /* finite attractor radius  */
  16679. X    double    f_at_rad;        /* finite attractor radius  */
  16680. X    int    bitshift;        /* fudgefactor            */
  16681. X
  16682. X    int    badconfig = 0;        /* 'fractint.cfg' ok?       */
  16683. X    int    diskisactive;        /* disk-video drivers flag  */
  16684. X    int    diskvideo;        /* disk-video access flag   */
  16685. X    int hasinverse = 0;
  16686. X    /* note that integer grid is set when integerfractal && !invert;    */
  16687. X    /* otherwise the floating point grid is set; never both at once     */
  16688. X    long    far *lx0, far *ly0;    /* x, y grid            */
  16689. X    long    far *lx1, far *ly1;    /* adjustment for rotate    */
  16690. X    /* note that lx1 & ly1 values can overflow into sign bit; since     */
  16691. X    /* they're used only to add to lx0/ly0, 2s comp straightens it out  */
  16692. X    double far *dx0, far *dy0;    /* floating pt equivs */
  16693. X    double far *dx1, far *dy1;
  16694. X    int    integerfractal;     /* TRUE if fractal uses integer math */
  16695. X
  16696. X    /* usr_xxx is what the user wants, vs what we may be forced to do */
  16697. X    char    usr_stdcalcmode;
  16698. X    int    usr_periodicitycheck;
  16699. X    int    usr_distest;
  16700. X    char    usr_floatflag;
  16701. X
  16702. X    int    viewwindow;        /* 0 for full screen, 1 for window */
  16703. X    float    viewreduction;        /* window auto-sizing */
  16704. X    int    viewcrop;        /* nonzero to crop default coords */
  16705. X    float    finalaspectratio;    /* for view shape and rotation */
  16706. X    int    viewxdots,viewydots;    /* explicit view sizing */
  16707. Xextern    int    inside;         /* inside color: 1=blue     */
  16708. Xextern    int    outside;        /* outside color, if set    */
  16709. Xextern    int    cyclelimit;        /* color-rotator upper limit */
  16710. Xextern    int    display3d;        /* 3D display flag: 0 = OFF */
  16711. Xextern    int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  16712. Xextern    int    boxcolor;        /* zoom box color */
  16713. Xextern    int    color_bright;        /* set by find_special_colors */
  16714. X
  16715. X#ifndef XFRACT
  16716. Xextern BYTE dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  16717. Xextern BYTE olddacbox[256][3]; /* backup copy of the Video-DAC */
  16718. X#else
  16719. XBYTE dacbox[256][3];   /* Video-DAC (filled in by SETVIDEO) */
  16720. XBYTE olddacbox[256][3]; /* backup copy of the Video-DAC */
  16721. X#endif
  16722. Xextern struct videoinfo far videotable[];
  16723. Xextern BYTE far *mapdacbox;    /* default dacbox when map= specified */
  16724. Xextern int    daclearn, daccount;    /* used by the color-cyclers */
  16725. Xextern SEGTYPE    extraseg;        /* used by Save-to-DISK routines */
  16726. Xextern int    cpu;            /* cpu type            */
  16727. Xextern int    fpu;            /* fpu type            */
  16728. Xextern int    iit;            /* iit fpu?            */
  16729. Xextern int    lookatmouse;        /* used to select mouse mode    */
  16730. Xextern int    (*outln)(BYTE *, int);    /* called in decoder */
  16731. X       void    (*outln_cleanup)();
  16732. Xextern int    filetype;        /* GIF or other */
  16733. X
  16734. X/* variables defined by the command line/files processor */
  16735. Xextern    double    inversion[];
  16736. Xextern    int    invert;     /* non-zero if inversion active */
  16737. Xextern    int    initbatch;    /* 1 if batch run (no kbd)  */
  16738. X                 /* 2 batch, no save */
  16739. X                 /* 3 user interrupt, errorlevel 2 */
  16740. X                 /* 4 program error errorlevel 1, save */
  16741. X                 /* 5 program error errorlevel 1, don't save */
  16742. X                /* -1 complete first, then set to 1 */
  16743. X
  16744. Xextern    int    initmode;        /* initial video mode        */
  16745. Xextern    int    goodmode;        /* video.asm sets nonzero if mode ok */
  16746. Xextern    int    initcyclelimit;     /* initial cycle limit        */
  16747. Xextern    int    LogFlag;        /* non-zero if logarithmic palettes */
  16748. Xextern    int    reallyega;        /* == 0 if it's really an EGA */
  16749. X
  16750. Xextern char showbox;        /* flag to show box and vector in preview */
  16751. Xextern unsigned initsavetime;    /* timed save interval */
  16752. X
  16753. Xint    comparegif=0;            /* compare two gif files flag */
  16754. Xint    timedsave=0;            /* when doing a timed save */
  16755. Xextern long saveticks, savebase;    /* timed save vars for general.asm */
  16756. Xextern int  finishrow;            /* for general.asm timed save */
  16757. Xint    resave_flag=0;            /* tells encoder not to incr filename */
  16758. Xint    started_resaves=0;        /* but incr on first resave */
  16759. Xint    save_system;            /* from and for save files */
  16760. Xint    tabmode = 1;            /* tab display enabled */
  16761. Xextern    int got_status;
  16762. Xextern    int loaded3d;
  16763. Xextern    int colorstate,colorpreloaded;    /* comments in cmdfiles */
  16764. Xextern int functionpreloaded; /* set in cmdfiles for old bifs JCO 7/5/92 */
  16765. X
  16766. Xextern int  show_orbit;
  16767. X
  16768. X#ifdef XFRACT
  16769. Xextern int XZoomWaiting;
  16770. X#endif
  16771. X
  16772. X/* for historical reasons (before rotation):         */
  16773. X/*    top    left  corner of screen is (xxmin,yymax) */
  16774. X/*    bottom left  corner of screen is (xx3rd,yy3rd) */
  16775. X/*    bottom right corner of screen is (xxmax,yymin) */
  16776. Xdouble    xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners  */
  16777. Xlong    xmin, xmax, ymin, ymax, x3rd, y3rd;  /* integer equivs         */
  16778. Xdouble    sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */
  16779. Xdouble    plotmx1,plotmx2,plotmy1,plotmy2;     /* real->screen multipliers */
  16780. X
  16781. Xint calc_status; /* -1 no fractal            */
  16782. X         /*  0 parms changed, recalc reqd   */
  16783. X         /*  1 actively calculating        */
  16784. X         /*  2 interrupted, resumable        */
  16785. X         /*  3 interrupted, not resumable   */
  16786. X         /*  4 completed            */
  16787. Xlong calctime;
  16788. X
  16789. Xint max_colors;                /* maximum palette size */
  16790. Xextern int max_kbdcount;        /* governs keyboard-check speed */
  16791. X
  16792. Xint       zoomoff;            /* = 0 when zoom is disabled    */
  16793. Xextern int nxtscreenflag; /* for cellular next screen generation */
  16794. X
  16795. Xstatic int far fromtext_flag = 0;    /* = 1 if we're in graphics mode */
  16796. Xint       savedac;            /* save-the-Video DAC flag    */
  16797. X
  16798. Xvoid main(int argc, char **argv)
  16799. X{
  16800. X   double  jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */
  16801. X   double  jxx3rd, jyy3rd;
  16802. X   int       frommandel;            /* if julia entered from mandel */
  16803. X   int       axmode, bxmode, cxmode, dxmode; /* video mode (BIOS ##)    */
  16804. X   int       historyptr;            /* pointer into history tbl    */
  16805. X   int       historyflag;         /* are we backing off in history? */
  16806. X   int       kbdchar;            /* keyboard key-hit value    */
  16807. X   int       kbdmore;            /* continuation variable    */
  16808. X   int       i, k;            /* temporary loop counters    */
  16809. X   double  ftemp;            /* fp temp            */
  16810. X   char stacked=0;            /* flag to indicate screen stacked */
  16811. X
  16812. X   initasmvars();            /* initialize ASM stuff */
  16813. X
  16814. X   if (extraseg == 0        /* oops.  not enough memory */
  16815. X     || (history = (struct historystruct far * ) farmemalloc((unsigned long)
  16816. X              (MAXHISTORY * sizeof(*history)))) == NULL
  16817. X     || (ly0 = (long far *) farmemalloc(4096L)) == NULL) {
  16818. X      buzzer(2);
  16819. X      printf(" I'm sorry, but you don't have enough free memory \n");
  16820. X      printf(" to run this program.\n\n");
  16821. X      exit(1);
  16822. X      }
  16823. X   farmemfree((BYTE far *)ly0); /* was just to check for min space */
  16824. X
  16825. X   dx0 = MK_FP(extraseg,0);
  16826. X   dy1 = (dx1 = (dy0 = dx0 + MAXPIXELS) + MAXPIXELS) + MAXPIXELS;
  16827. X   lx0 = (long far *) dx0;
  16828. X   ly1 = (lx1 = (ly0 = lx0 + MAXPIXELS) + MAXPIXELS) + MAXPIXELS;
  16829. X
  16830. X   historyptr = 0;            /* initialize history ptr */
  16831. X   historyflag = 0;
  16832. X   history[historyptr].fractype = -1;
  16833. X
  16834. X   load_videotable(1); /* load fractint.cfg, no message yet if bad */
  16835. X#ifdef XFRACT
  16836. X   UnixInit();
  16837. X#endif
  16838. X   init_help();
  16839. X
  16840. Xrestart:                /* insert key re-starts here */
  16841. X
  16842. X   cmdfiles(argc,argv);         /* process the command-line */
  16843. X   if(debugflag==450 && strcmp(savename,"fract001") != 0)
  16844. X   {
  16845. X      char name[80];
  16846. X      strcpy(name,savename);
  16847. X      strcat(name,".gif");
  16848. X      if(access(name,0)==0)
  16849. X         exit(0);
  16850. X   }   
  16851. X#ifdef XFRACT
  16852. X   initUnixWindow();
  16853. X#endif
  16854. X
  16855. X   memcpy(olddacbox,dacbox,256*3);    /* save in case colors= present */
  16856. X
  16857. X   if (debugflag == 8088)         cpu =    86; /* for testing purposes */
  16858. X   if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
  16859. X   if (debugflag ==  870 && fpu >=  87 ) fpu =    87; /* for testing purposes */
  16860. X   if (debugflag ==   70)         fpu =     0; /* for testing purposes */
  16861. X   if (getenv("NO87")) fpu = 0;
  16862. X   fract_dir1 = getenv("FRACTDIR");
  16863. X   if (fract_dir1==NULL) {
  16864. X       fract_dir1 = ".";
  16865. X   }
  16866. X#ifdef SRCDIR
  16867. X   fract_dir2 = SRCDIR;
  16868. X#else
  16869. X   fract_dir2 = ".";
  16870. X#endif
  16871. X   if (fpu == 0)       iit = 0;
  16872. X   if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  16873. X      setup287code();
  16874. X
  16875. X   /* IIT math coprocessor chip logic */
  16876. X   if(iit == 0 && fpu)
  16877. X      if(IITCoPro())
  16878. X         iit = 3;  /* detect iit chip */
  16879. X   if(iit < 0) iit = 0;  /* user wants chip turned off */
  16880. X   if(iit>0)
  16881. X   {
  16882. X      if(F4x4Check())
  16883. X         iit = 2;    /* semaphore TSR is installed */
  16884. X      else if(iit == 3)
  16885. X         iit = 0;    /* we detetct chip but no tsr - don't use */
  16886. X      /* else user forced iit == 1 */
  16887. X   }
  16888. X
  16889. X   adapter_detect();            /* check what video is really present */
  16890. X   if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */
  16891. X      if (video_type > (debugflag-9000)/2)     /* adjust the video value */
  16892. X     video_type = (debugflag-9000)/2;
  16893. X
  16894. X   diskisactive = 0;            /* disk-video is inactive */
  16895. X   diskvideo = 0;            /* disk driver is not in use */
  16896. X   setvideotext();            /* switch to text mode */
  16897. X   calc_status = -1;            /* no active fractal image */
  16898. X   savedac = 0;             /* don't save the VGA DAC */
  16899. X
  16900. X   if (debugflag == 10000)        /* check for free memory */
  16901. X      showfreemem();
  16902. X
  16903. X#ifndef XFRACT
  16904. X   if (badconfig < 0)            /* fractint.cfg bad, no msg yet */
  16905. X      bad_fractint_cfg_msg();
  16906. X#endif
  16907. X
  16908. X   max_colors = 256;                    /* the Windows version is lower */
  16909. X   max_kbdcount=(cpu==386) ? 80 : 30;   /* check the keyboard this often */
  16910. X
  16911. X   if (showfile && initmode < 0) {
  16912. X      intro();                /* display the credits screen */
  16913. X      if (keypressed() == ESC) {
  16914. X     getakey();
  16915. X     goodbye();
  16916. X     }
  16917. X      }
  16918. X
  16919. X   if (colorpreloaded)
  16920. X      memcpy(dacbox,olddacbox,256*3);    /* restore in case colors= present */
  16921. X   if (!functionpreloaded)
  16922. X      set_if_old_bif();
  16923. X   stacked = 0;
  16924. Xrestorestart:
  16925. X
  16926. X   lookatmouse = 0;            /* ignore mouse */
  16927. X
  16928. X   while (showfile <= 0) {        /* image is to be loaded */
  16929. X      char *hdg;
  16930. X      tabmode = 0;
  16931. X      if (overlay3d) {
  16932. X     hdg = "Select File for 3D Overlay";
  16933. X     helpmode = HELP3DOVLY;
  16934. X     }
  16935. X      else if (display3d) {
  16936. X     hdg = "Select File for 3D Transform";
  16937. X     helpmode = HELP3D;
  16938. X     }
  16939. X      else {
  16940. X     hdg = "Select File to Restore";
  16941. X     helpmode = HELPSAVEREST;
  16942. X     }
  16943. X      if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) {
  16944. X     showfile = 1;             /* cancelled */
  16945. X     initmode = -1;
  16946. X     break;
  16947. X     }
  16948. X      showfile = 0;
  16949. X      helpmode = -1;
  16950. X      tabmode = 1;
  16951. X      if(stacked)
  16952. X      {
  16953. X         discardscreen();
  16954. X         setvideotext();
  16955. X         stacked = 0;
  16956. X      }
  16957. X      if (read_overlay() == 0)         /* read hdr, get video mode */
  16958. X     break;              /* got it, exit */
  16959. X      showfile = -1;             /* retry */
  16960. X      }
  16961. X
  16962. X   helpmode = HELPMENU;         /* now use this help mode */
  16963. X   tabmode = 1;
  16964. X   lookatmouse = 0;            /* ignore mouse */
  16965. X
  16966. X   if ((overlay3d || stacked) && initmode < 0) {    /* overlay command failed */
  16967. X      unstackscreen();            /* restore the graphics screen */
  16968. X      stacked = 0;
  16969. X      overlay3d = 0;            /* forget overlays */
  16970. X      display3d = 0;            /* forget 3D */
  16971. X      if (calc_status > 0 && calc_status !=2)
  16972. X     calc_status = 0;
  16973. X      goto resumeloop;            /* ooh, this is ugly */
  16974. X      }
  16975. X
  16976. X   savedac = 0;             /* don't save the VGA DAC */
  16977. Ximagestart:                /* calc/display a new image */
  16978. X   if(stacked)
  16979. X   {
  16980. X      discardscreen();
  16981. X      stacked = 0;
  16982. X   }
  16983. X#ifdef XFRACT
  16984. X   usr_floatflag = 1;
  16985. X#endif
  16986. X   got_status = -1;            /* for tab_display */
  16987. X
  16988. X   if (showfile)
  16989. X      if (calc_status > 0)        /* goto imagestart implies re-calc */
  16990. X     calc_status = 0;
  16991. X
  16992. X   if (initbatch == 0)
  16993. X      lookatmouse = -PAGE_UP;        /* just mouse left button, == pgup */
  16994. X
  16995. X   cyclelimit = initcyclelimit;     /* default cycle limit     */
  16996. X
  16997. X   frommandel = 0;
  16998. X
  16999. X   adapter = initmode;            /* set the video adapter up */
  17000. X   initmode = -1;            /* (once)            */
  17001. X
  17002. X   while (adapter < 0) {        /* cycle through instructions */
  17003. X      if (initbatch) {                /* batch, nothing to do */
  17004. X         initbatch = 4;            /* exit with error condition set */
  17005. X         goodbye();
  17006. X      }
  17007. X      kbdchar = main_menu(0);
  17008. X      if (kbdchar == INSERT) goto restart;    /* restart pgm on Insert Key */
  17009. X      if (kbdchar == DELETE)            /* select video mode list */
  17010. X     kbdchar = select_video_mode(-1);
  17011. X      if ((adapter = check_vidmode_key(0,kbdchar)) >= 0)
  17012. X     break;                 /* got a video mode now */
  17013. X#ifndef XFRACT
  17014. X      if ('A' <= kbdchar && kbdchar <= 'Z')
  17015. X     kbdchar = tolower(kbdchar);
  17016. X#endif
  17017. X      if (kbdchar == 'd') {                     /* shell to DOS */
  17018. X     setclear();
  17019. X     printf("\n\nShelling to DOS - type 'exit' to return\n\n");
  17020. X     shell_to_dos();
  17021. X     goto imagestart;
  17022. X     }
  17023. X#ifndef XFRACT
  17024. X      if (kbdchar == '@') {                     /* execute commands */
  17025. X#else
  17026. X      if (kbdchar == F2 || kbdchar == '@') {     /* We mapped @ to F2 */
  17027. X#endif
  17028. X     if ((get_commands() & 4) == 0)
  17029. X        goto imagestart;
  17030. X     kbdchar = '3';                         /* 3d=y so fall thru '3' code */
  17031. X     }
  17032. X#ifndef XFRACT
  17033. X      if (kbdchar == 'r' || kbdchar == '3' || kbdchar == '#') {
  17034. X#else
  17035. X      if (kbdchar == 'r' || kbdchar == '3' || kbdchar == F3) {
  17036. X#endif
  17037. X     display3d = 0;
  17038. X     if (kbdchar == '3' || kbdchar == '#' || kbdchar == F3)
  17039. X        display3d = 1;
  17040. X     setvideotext(); /* switch to text mode */
  17041. X     showfile = -1;
  17042. X     goto restorestart;
  17043. X     }
  17044. X      if (kbdchar == 't') {                     /* set fractal type */
  17045. X         julibrot = 0;
  17046. X     get_fracttype();
  17047. X     goto imagestart;
  17048. X     }
  17049. X      if (kbdchar == 'x') {                     /* generic toggle switch */
  17050. X     get_toggles();
  17051. X     goto imagestart;
  17052. X     }
  17053. X      if (kbdchar == 'y') {                     /* generic toggle switch */
  17054. X     get_toggles2();
  17055. X     goto imagestart;
  17056. X     }
  17057. X      if (kbdchar == 'z') {                     /* type specific parms */
  17058. X     get_fract_params(1);
  17059. X     goto imagestart;
  17060. X     }
  17061. X      if (kbdchar == 'v') {                     /* view parameters */
  17062. X     get_view_params();
  17063. X     goto imagestart;
  17064. X     }
  17065. X      if (kbdchar == 'f') {                     /* floating pt toggle */
  17066. X     if (usr_floatflag == 0)
  17067. X        usr_floatflag = 1;
  17068. X     else
  17069. X        usr_floatflag = 0;
  17070. X     goto imagestart;
  17071. X     }
  17072. X      if (kbdchar == 'i') {                     /* set 3d fractal parms */
  17073. X     get_fract3d_params(); /* get the parameters */
  17074. X     goto imagestart;
  17075. X     }
  17076. X      if (kbdchar == 'g') {
  17077. X     get_cmd_string(); /* get command string */
  17078. X     goto imagestart;
  17079. X         }
  17080. X      /* buzzer(2); */                /* unrecognized key */
  17081. X      }
  17082. X
  17083. X   zoomoff = 1;         /* zooming is enabled */
  17084. X   helpmode = HELPMAIN;     /* now use this help mode */
  17085. X
  17086. X   while (1) {            /* eternal loop */
  17087. X
  17088. X      if (calc_status != 2 || showfile == 0) {
  17089. X#ifdef XFRACT
  17090. X         if (resizeWindow()) {
  17091. X         calc_status = -1;
  17092. X     }
  17093. X#endif
  17094. X     far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter],
  17095. X            sizeof(videoentry));
  17096. X     axmode  = videoentry.videomodeax; /* video mode (BIOS call)   */
  17097. X     bxmode  = videoentry.videomodebx; /* video mode (BIOS call)   */
  17098. X     cxmode  = videoentry.videomodecx; /* video mode (BIOS call)   */
  17099. X     dxmode  = videoentry.videomodedx; /* video mode (BIOS call)   */
  17100. X     dotmode = videoentry.dotmode;       /* assembler dot read/write */
  17101. X     xdots     = videoentry.xdots;       /* # dots across the screen */
  17102. X     ydots     = videoentry.ydots;       /* # dots down the screen   */
  17103. X     colors  = videoentry.colors;       /* # colors available */
  17104. X     textsafe2 = dotmode / 100;
  17105. X     dotmode  %= 100;
  17106. X     sxdots  = xdots;
  17107. X     sydots  = ydots;
  17108. X     sxoffs = syoffs = 0;
  17109. X
  17110. X     diskvideo = 0;         /* set diskvideo flag */
  17111. X     if (dotmode == 11)        /* default assumption is disk */
  17112. X        diskvideo = 2;
  17113. X
  17114. X     memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  17115. X     diskisactive = 1;        /* flag for disk-video routines */
  17116. X
  17117. X     if (overlay3d) {
  17118. X        unstackscreen();        /* restore old graphics image */
  17119. X        overlay3d = 0;
  17120. X        }
  17121. X
  17122. X     else {
  17123. X        setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
  17124. X        if (goodmode == 0) {
  17125. X           static char far msg[] = {"That video mode is not available with your adapter."};
  17126. X           static char far TPlusStr[] = "This video mode requires 'noninterlaced=yes'";
  17127. X
  17128. X           if(TPlusErr) {
  17129. X          stopmsg(0, TPlusStr);
  17130. X          TPlusErr = 0;
  17131. X          }
  17132. X           else
  17133. X          stopmsg(0,msg);
  17134. X           initmode = -1;
  17135. X           setvideotext(); /* switch to text mode */
  17136. X           goto restorestart;
  17137. X           }
  17138. X
  17139. X        if(Transparent3D && curfractalspecific->orbitcalc == Formula) {
  17140. X           char far *ErrMsg;
  17141. X           if((ErrMsg = TrueColorAutoDetect()) != ((char far*)0)) {
  17142. X          stopmsg(0, ErrMsg);
  17143. X          Transparent3D = 0;
  17144. X          }
  17145. X           else {
  17146. X          tpdepth = 0;
  17147. X          NewTPFractal = 1;
  17148. X          }
  17149. X           }
  17150. X        else if(AntiAliasing) {
  17151. X           if(dotmode != 11) {
  17152. X          static char far DiskVidError[] =
  17153. X            "Anti-aliasing resolution too high, try a lower value or lower\n\
  17154. Xscreen resolution.";
  17155. X          /* Ensure the absolute resolution is < MAXPIXELS */
  17156. X          if(AntiAliasing >= 8 ||
  17157. X             ((long)xdots << AntiAliasing) > MAXPIXELS)
  17158. X             goto AntiAliasError;
  17159. X          if(!colors)
  17160. X             TrueColorAutoDetect();
  17161. X          if(SetupShadowVideo() != 0) {
  17162. XAntiAliasError:
  17163. X             stopmsg(0, DiskVidError);
  17164. X             initmode = -1;
  17165. X             setvideotext(); /* switch to text mode */
  17166. X             goto restorestart;
  17167. X             }
  17168. X          }
  17169. X           }
  17170. X        }
  17171. X
  17172. X     diskisactive = 0;        /* flag for disk-video routines */
  17173. X     if (savedac || colorpreloaded) {
  17174. X        memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  17175. X        spindac(0,1);
  17176. X        colorpreloaded = 0;
  17177. X        }
  17178. X     else { /* reset DAC to defaults, which setvideomode has done for us */
  17179. X        if (mapdacbox) { /* but there's a map=, so load that */
  17180. X           far_memcpy((char far *)dacbox,mapdacbox,768);
  17181. X           spindac(0,1);
  17182. X           }
  17183. X        else if ((dotmode == 11 && colors == 256) || !colors) {
  17184. X           /* disk video, setvideomode via bios didn't get it right, so: */
  17185. X#ifndef XFRACT
  17186. X           ValidateLuts("default"); /* read the default palette file */
  17187. X#endif
  17188. X           }
  17189. X        colorstate = 0;
  17190. X        }
  17191. X     if (viewwindow) {
  17192. X        ftemp = finalaspectratio
  17193. X            * (double)sydots / (double)sxdots / screenaspect;
  17194. X        if ((xdots = viewxdots)) { /* xdots specified */
  17195. X           if ((ydots = viewydots) == 0) /* calc ydots? */
  17196. X          ydots = (double)xdots * ftemp + 0.5;
  17197. X           }
  17198. X        else
  17199. X           if (finalaspectratio <= screenaspect) {
  17200. X          xdots = (double)sxdots / viewreduction + 0.5;
  17201. X          ydots = (double)xdots * ftemp + 0.5;
  17202. X          }
  17203. X           else {
  17204. X          ydots = (double)sydots / viewreduction + 0.5;
  17205. X          xdots = (double)ydots / ftemp + 0.5;
  17206. X          }
  17207. X        if (xdots > sxdots || ydots > sydots) {
  17208. X           static char far msg[] = {"View window too large; using full screen."};
  17209. X           stopmsg(0,msg);
  17210. X           xdots = sxdots;
  17211. X           ydots = sydots;
  17212. X           }
  17213. X        else if (xdots <= sxdots/20 || ydots <= sydots/20) { /* so ssg works */
  17214. X           static char far msg[] = {"View window too small; using full screen."};
  17215. X           stopmsg(0,msg);
  17216. X           xdots = sxdots;
  17217. X           ydots = sydots;
  17218. X           }
  17219. X        sxoffs = (sxdots - xdots) / 2;
  17220. X        syoffs = (sydots - ydots) / 3;
  17221. X        }
  17222. X     dxsize = xdots - 1;        /* convert just once now */
  17223. X     dysize = ydots - 1;
  17224. X     }
  17225. X      if(savedac == 0)
  17226. X        savedac = 2;            /* assume we save next time (except jb) */
  17227. X      else
  17228. X      savedac = 1;            /* assume we save next time */
  17229. X      if (initbatch == 0)
  17230. X     lookatmouse = -PAGE_UP;    /* mouse left button == pgup */
  17231. X
  17232. X      if(showfile == 0) {        /* loading an image */
  17233. X     outln_cleanup = NULL;        /* outln routine can set this */
  17234. X     if (display3d)         /* set up 3D decoding */
  17235. X        outln = call_line3d;
  17236. X     else if(filetype >= 1)     /* old .tga format input file */
  17237. X        outln = outlin16;
  17238. X     else if(comparegif)        /* debug 50 */
  17239. X        outln = cmp_line;
  17240. X     else if(pot16bit) {        /* .pot format input file */
  17241. X        if (pot_startdisk() < 0)
  17242. X        {                /* pot file failed?  */
  17243. X           extern int potflag;
  17244. X
  17245. X           showfile = 1;
  17246. X           potflag  = 0;
  17247. X           pot16bit = 0;
  17248. X           initmode = -1;
  17249. X           calc_status = 2;        /* "resume" without 16-bit */
  17250. X           setvideotext();
  17251. X           get_fracttype();
  17252. X           goto imagestart;
  17253. X        }
  17254. X        outln = pot_line;
  17255. X     }
  17256. X     else                /* regular gif/fra input file */
  17257. X            if(soundflag > 0)
  17258. X               outln = sound_line;      /* sound decoding */
  17259. X            else
  17260. X               outln = out_line;        /* regular decoding */
  17261. X     if(filetype == 0)
  17262. X     {
  17263. X        if(iit == 2 && usr_floatflag != 0)
  17264. X           if(F4x4Lock()==0)
  17265. X              iit = -1;  /* semaphore not free - no iit */
  17266. X        if(debugflag==2224)
  17267. X         {
  17268. X            char buf[80];
  17269. X            sprintf(buf,"iit=%d floatflag=%d",iit,usr_floatflag);
  17270. X            stopmsg(4,(char far *)buf);
  17271. X         }
  17272. X
  17273. X        i = funny_glasses_call(gifview);
  17274. X        if(iit == 2)
  17275. X           F4x4Free();      /* unlock semaphore */
  17276. X        else if(iit == -1)
  17277. X           iit = 2;         /* semaphore operating */
  17278. X     }
  17279. X     else
  17280. X        i = funny_glasses_call(tgaview);
  17281. X     if(outln_cleanup)        /* cleanup routine defined? */
  17282. X        (*outln_cleanup)();
  17283. X     if(i == 0)
  17284. X        buzzer(0);
  17285. X     else {
  17286. X        calc_status = -1;
  17287. X        if (keypressed()) {
  17288. X           buzzer(1);
  17289. X           while (keypressed()) getakey();
  17290. X           texttempmsg("*** load incomplete ***");
  17291. X           }
  17292. X        }
  17293. X     }
  17294. X
  17295. X      zoomoff = 1;            /* zooming is enabled */
  17296. X      if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0)
  17297. X     zoomoff = 0;            /* for these cases disable zooming */
  17298. X
  17299. X      calcfracinit();
  17300. X#ifdef XFRACT
  17301. X      schedulealarm(1);
  17302. X#endif
  17303. X
  17304. X      sxmin = xxmin; /* save 3 corners for zoom.c ref points */
  17305. X      sxmax = xxmax;
  17306. X      sx3rd = xx3rd;
  17307. X      symin = yymin;
  17308. X      symax = yymax;
  17309. X      sy3rd = yy3rd;
  17310. X
  17311. X      if (history[0].fractype == -1)    /* initialize the history file */
  17312. X     for (i = 0; i < MAXHISTORY; i++) {
  17313. X        int j;
  17314. X        history[i].xxmax = xxmax;
  17315. X        history[i].xxmin = xxmin;
  17316. X        history[i].yymax = yymax;
  17317. X        history[i].yymin = yymin;
  17318. X        history[i].xx3rd = xx3rd;
  17319. X        history[i].yy3rd = yy3rd;
  17320. X        for(j=0;j<MAXPARAMS;j++)
  17321. X           history[i].param[j] = param[j];
  17322. X        history[i].fractype = fractype;
  17323. X        }
  17324. X
  17325. X      if ( history[historyptr].xxmax != xxmax  || /* save any (new) zoom data */
  17326. X       history[historyptr].xxmin != xxmin  ||
  17327. X       history[historyptr].yymax != yymax  ||
  17328. X       history[historyptr].yymin != yymin  ||
  17329. X       history[historyptr].xx3rd != xx3rd  ||
  17330. X       history[historyptr].yy3rd != yy3rd  ||
  17331. X       history[historyptr].param[0] != param[0] ||
  17332. X       history[historyptr].param[1] != param[1] ||
  17333. X       history[historyptr].param[2] != param[2] ||
  17334. X       history[historyptr].param[3] != param[3] ||
  17335. X       history[historyptr].param[4] != param[4] ||
  17336. X       history[historyptr].param[5] != param[5] ||
  17337. X       history[historyptr].param[6] != param[6] ||
  17338. X       history[historyptr].param[7] != param[7] ||
  17339. X       history[historyptr].param[8] != param[8] ||
  17340. X       history[historyptr].param[9] != param[9] ||
  17341. X       history[historyptr].fractype != fractype) {
  17342. X           int j;
  17343. X     if (historyflag == 0) /* if we're not backing off for <\> */
  17344. X        if (++historyptr == MAXHISTORY) historyptr = 0;
  17345. X     history[historyptr].xxmax = xxmax;
  17346. X     history[historyptr].xxmin = xxmin;
  17347. X     history[historyptr].yymax = yymax;
  17348. X     history[historyptr].yymin = yymin;
  17349. X     history[historyptr].xx3rd = xx3rd;
  17350. X     history[historyptr].yy3rd = yy3rd;
  17351. X         for(j=0;j<MAXPARAMS;j++)
  17352. X            history[historyptr].param[j] = param[j];
  17353. X     history[historyptr].fractype = fractype;
  17354. X     }
  17355. X      historyflag = 0;
  17356. X
  17357. X      if (display3d || showfile) {    /* paranoia: these vars don't get set */
  17358. X     save_system  = active_system;    /*   unless really doing some work,   */
  17359. X     }                /*   so simple <r> + <s> keeps number */
  17360. X
  17361. X      if(showfile == 0) {        /* image has been loaded */
  17362. X     showfile = 1;
  17363. X     if (initbatch == 1 && calc_status == 2)
  17364. X        initbatch = -1; /* flag to finish calc before save */
  17365. X     if (loaded3d)        /* 'r' of image created with '3' */
  17366. X        display3d = 1;  /* so set flag for 'b' command */
  17367. X     }
  17368. X      else {                /* draw an image */
  17369. X     diskisactive = 1;        /* flag for disk-video routines */
  17370. X     if (initsavetime != 0        /* autosave and resumable? */
  17371. X       && (curfractalspecific->flags&NORESUME) == 0) {
  17372. X        savebase = readticker(); /* calc's start time */
  17373. X        saveticks = (long)initsavetime * 1092; /* bios ticks/minute */
  17374. X        if ((saveticks & 65535L) == 0)
  17375. X           ++saveticks; /* make low word nonzero */
  17376. X        finishrow = -1;
  17377. X        }
  17378. X
  17379. X     if(Transparent3D && curfractalspecific->orbitcalc == Formula)
  17380. X        i = Transp3DFnct();
  17381. X     else {
  17382. X        i = calcfract();    /* draw the fractal using "C" */
  17383. X        if(AntiAliasing && i == 0)
  17384. X           AntiAliasPass();
  17385. X        }
  17386. X     if (i == 0)
  17387. X        buzzer(0); /* finished!! */
  17388. X
  17389. X     saveticks = 0;         /* turn off autosave timer */
  17390. X     if (dotmode == 11 && i == 0) /* disk-video */
  17391. X        dvid_status(0,"Image has been completed");
  17392. X     diskisactive = 0;        /* flag for disk-video routines */
  17393. X     }
  17394. X
  17395. X#ifndef XFRACT
  17396. X      boxcount = 0;            /* no zoom box yet  */
  17397. X      zwidth = 0;
  17398. X#else
  17399. X      if (!XZoomWaiting) {
  17400. X      boxcount = 0;            /* no zoom box yet  */
  17401. X      zwidth = 0;
  17402. X      }
  17403. X#endif
  17404. X
  17405. X      if (fractype == PLASMA && cpu > 88) {
  17406. X     cyclelimit = 256;        /* plasma clouds need quick spins */
  17407. X     daccount = 256;
  17408. X     daclearn = 1;
  17409. X     }
  17410. X
  17411. Xresumeloop:                /* return here on failed overlays */
  17412. X
  17413. X      kbdmore = 1;
  17414. X      while (kbdmore == 1) {        /* loop through command keys */
  17415. X
  17416. X     if (timedsave != 0) {
  17417. X        if (timedsave == 1) {    /* woke up for timed save */
  17418. X           getakey();     /* eat the dummy char */
  17419. X           kbdchar = 's'; /* do the save */
  17420. X           resave_flag = 1;
  17421. X           timedsave = 2;
  17422. X           }
  17423. X        else {            /* save done, resume */
  17424. X           timedsave = 0;
  17425. X           resave_flag = 2;
  17426. X           kbdchar = ENTER;
  17427. X           }
  17428. X        }
  17429. X     else if (initbatch == 0) {    /* not batch mode */
  17430. X        lookatmouse = (zwidth == 0) ? -PAGE_UP : 3;
  17431. X        if (calc_status == 2 && zwidth == 0 && !keypressed()) {
  17432. X           kbdchar = ENTER;        /* no visible reason to stop, continue */
  17433. X        } else {            /* wait for a real keystroke */
  17434. X#ifndef XFRACT
  17435. X               while (!keypressed()) { }  /* enables help */
  17436. X#else
  17437. X               waitkeypressed(0);
  17438. X#endif
  17439. X           kbdchar = getakey();
  17440. X           if (kbdchar == ESC || kbdchar == 'm' || kbdchar == 'M') {
  17441. X                  if (kbdchar == ESC && escape_exit != 0)
  17442. X                      /* don't ask, just get out */
  17443. X                      goodbye();
  17444. X          stackscreen();
  17445. X#ifndef XFRACT
  17446. X          kbdchar = main_menu(1);
  17447. X#else
  17448. X                  if (XZoomWaiting) {
  17449. X              kbdchar = ENTER;
  17450. X          } else {
  17451. X              kbdchar = main_menu(1);
  17452. X              if (XZoomWaiting) {
  17453. X              kbdchar = ENTER;
  17454. X              }
  17455. X          }
  17456. X#endif
  17457. X          if (kbdchar == '\\'
  17458. X            || check_vidmode_key(0,kbdchar) >= 0)
  17459. X             discardscreen();
  17460. X          else if (kbdchar == 'x' || kbdchar == 'y' ||
  17461. X                   kbdchar == 'z' || kbdchar == 'g' ) 
  17462. X             fromtext_flag = 1;
  17463. X          else
  17464. X             unstackscreen();
  17465. X          }
  17466. X           }
  17467. X        }
  17468. X     else {             /* batch mode, fake next keystroke */
  17469. X        if (initbatch == -1) {    /* finish calc */
  17470. X           kbdchar = ENTER;
  17471. X           initbatch = 1;
  17472. X           }
  17473. X        else if (initbatch == 1 || initbatch == 4 ) {    /* save-to-disk */
  17474. X/*
  17475. X           while(keypressed())
  17476. X         getakey();
  17477. X*/
  17478. X           if (debugflag == 50)
  17479. X          kbdchar = 'r';
  17480. X           else
  17481. X          kbdchar = 's';
  17482. X           if(initbatch == 1) initbatch = 2;
  17483. X           if(initbatch == 4) initbatch = 5;
  17484. X           }
  17485. X        else {
  17486. X           if(calc_status != 4) initbatch = 3; /* bailout with error */
  17487. X           goodbye();        /* done, exit */
  17488. X           }
  17489. X        }
  17490. X
  17491. X#ifndef XFRACT
  17492. X         if ('A' <= kbdchar && kbdchar <= 'Z')
  17493. X            kbdchar = tolower(kbdchar);
  17494. X#endif
  17495. X     switch (kbdchar) {
  17496. X        int x,y,v;
  17497. X        case 't':                   /* new fractal type             */
  17498. X           julibrot = 0;
  17499. X           clear_zoombox();
  17500. X           stackscreen();
  17501. X           if ((i = get_fracttype()) >= 0) {
  17502. X          discardscreen();
  17503. X          savedac = 0;
  17504. X          if (i == 0) {
  17505. X             initmode = adapter;
  17506. X             frommandel = 0;
  17507. X             }
  17508. X          else
  17509. X             if (initmode < 0)    /* it is supposed to be... */
  17510. X            setvideotext(); /* reset to text mode       */
  17511. X          goto imagestart;
  17512. X          }
  17513. X           unstackscreen();
  17514. X           break;
  17515. X        case 24:                    /* Ctl-X, Ctl-Y, CTL-Z do flipping */
  17516. X        case 25:
  17517. X        case 26:
  17518. X           flip_image(kbdchar);
  17519. X           break;
  17520. X        case 'x':                   /* invoke options screen        */
  17521. X        case 'y':
  17522. X        case 'z':                   /* type specific parms */
  17523. X        case 'g':
  17524. X           if (fromtext_flag == 1)
  17525. X               fromtext_flag = 0;
  17526. X           else
  17527. X               stackscreen();
  17528. X           if (kbdchar == 'x')
  17529. X          i = get_toggles();
  17530. X           else if (kbdchar == 'y')
  17531. X          i = get_toggles2();
  17532. X           else if (kbdchar =='z')
  17533. X          i = get_fract_params(1);
  17534. X               else
  17535. X                  i = get_cmd_string();
  17536. X           if (i > 0) {        /* time to redraw? */
  17537. X          discardscreen();
  17538. X          kbdmore = calc_status = 0;
  17539. X          }
  17540. X           else
  17541. X          unstackscreen();
  17542. X           break;
  17543. X#ifndef XFRACT
  17544. X        case '@':                   /* execute commands */
  17545. X#else
  17546. X        case F2:                   /* execute commands */
  17547. X#endif
  17548. X           stackscreen();
  17549. X           i = get_commands();
  17550. X           if (initmode != -1) {    /* video= was specified */
  17551. X          adapter = initmode;
  17552. X          initmode = -1;
  17553. X          i |= 1;
  17554. X          savedac = 0;
  17555. X          }
  17556. X           else if (colorpreloaded) { /* colors= was specified */
  17557. X          spindac(0,1);
  17558. X          colorpreloaded = 0;
  17559. X          }
  17560. X           else if ((i & 8))    /* reset was specified */
  17561. X          savedac = 0;
  17562. X           if ((i & 4)) {        /* 3d = was specified */
  17563. X          kbdchar = '3';
  17564. X          unstackscreen();
  17565. X          goto do_3d_transform; /* pretend '3' was keyed */
  17566. X          }
  17567. X           if ((i & 1)) {        /* fractal parameter changed */
  17568. X          discardscreen();
  17569. X          if(!functionpreloaded)
  17570. X            set_if_old_bif(); /* old bifs need function set, JCO 7/5/92 */
  17571. X          if(fractype==MANDELTRIG && usr_floatflag==1
  17572. X             && save_release < 1800 && bailout == 0)
  17573. X            bailout = 2500;
  17574. X          if(fractype==LAMBDATRIG && usr_floatflag==1
  17575. X             && save_release < 1800 && bailout == 0)
  17576. X            bailout = 2500;
  17577. X          kbdmore = calc_status = 0;
  17578. X          }
  17579. X           else
  17580. X          unstackscreen();
  17581. X           break;
  17582. X        case 'v':                   /* invoke options screen        */
  17583. X           i = get_view_params();    /* get the parameters */
  17584. X           if (i > 0)        /* time to redraw? */
  17585. X          kbdmore = calc_status = 0;
  17586. X           break;
  17587. X        case 'f':                   /* floating pt toggle           */
  17588. X           if (usr_floatflag == 0)
  17589. X          usr_floatflag = 1;
  17590. X           else
  17591. X          usr_floatflag = 0;
  17592. X           initmode = adapter;
  17593. X           goto imagestart;
  17594. X        case 'i':                   /* 3d fractal parms */
  17595. X           if (get_fract3d_params() >= 0) /* get the parameters */
  17596. X          calc_status = kbdmore = 0;  /* time to redraw */
  17597. X           break;
  17598. X        case 'a':                  /* starfield parms               */
  17599. X           clear_zoombox();
  17600. X           if (get_starfield_params() >= 0) {
  17601. X              if (starfield() >= 0)
  17602. X             calc_status = 0;
  17603. X          continue;
  17604. X          }
  17605. X           break;
  17606. X        case 15:   /* ctrl-o */
  17607. X        case 'o':
  17608. X            /* must use standard fractal and have a float variant */
  17609. X            if(fractalspecific[fractype].calctype == StandardFractal &&
  17610. X               (fractalspecific[fractype].isinteger == 0 ||
  17611. X                fractalspecific[fractype].tofloat != NOFRACTAL))
  17612. X            {
  17613. X               clear_zoombox();
  17614. X               Jiim(ORBIT);
  17615. X            }
  17616. X            break;
  17617. X        case SPACE:               /* spacebar, toggle mand/julia    */
  17618. X        if (fractype == CELLULAR) {
  17619. X            if(nxtscreenflag)
  17620. X              nxtscreenflag = 0; /* toggle flag to stop generation */
  17621. X            else
  17622. X              nxtscreenflag = 1; /* toggle flag to generate next screen */
  17623. X            calc_status = 2;
  17624. X            kbdmore = 0;
  17625. X        }
  17626. X        else {
  17627. X           if (curfractalspecific->tojulia != NOFRACTAL
  17628. X         && param[0] == 0.0 && param[1] == 0.0) {
  17629. X          /* switch to corresponding Julia set */
  17630. X         if(1)
  17631. X         {
  17632. X             int key;
  17633. X              if(fractype==MANDEL || fractype==MANDELFP)
  17634. X                 hasinverse=1;
  17635. X              else
  17636. X                 hasinverse=0;
  17637. X             clear_zoombox();
  17638. X             Jiim(JIIM);
  17639. X             key = getakey(); /* flush keyboard buffer */
  17640. X             if(key != SPACE)
  17641. X             {
  17642. X                ungetakey(key);
  17643. X                break;
  17644. X             }
  17645. X          }
  17646. X          fractype = curfractalspecific->tojulia;
  17647. X          curfractalspecific = &fractalspecific[fractype];
  17648. X          if(xcjul == BIG || ycjul == BIG)
  17649. X          {
  17650. X                param[0] = (xxmax + xxmin) / 2;
  17651. X             param[1] = (yymax + yymin) / 2;
  17652. X          }
  17653. X          else
  17654. X          {
  17655. X                param[0] = xcjul;
  17656. X             param[1] = ycjul;
  17657. X             xcjul = ycjul = BIG;
  17658. X          }
  17659. X          jxxmin = sxmin; jxxmax = sxmax;
  17660. X          jyymax = symax; jyymin = symin;
  17661. X          jxx3rd = sx3rd; jyy3rd = sy3rd;
  17662. X          frommandel = 1 ;
  17663. X          xxmin = curfractalspecific->xmin;
  17664. X          xxmax = curfractalspecific->xmax;
  17665. X          yymin = curfractalspecific->ymin;
  17666. X          yymax = curfractalspecific->ymax;
  17667. X          xx3rd = xxmin;
  17668. X          yy3rd = yymin;
  17669. X          if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29) {
  17670. X             xxmin *= 3.0;
  17671. X             xxmax *= 3.0;
  17672. X             yymin *= 3.0;
  17673. X             yymax *= 3.0;
  17674. X             xx3rd *= 3.0;
  17675. X             yy3rd *= 3.0;
  17676. X             }
  17677. X          zoomoff = 1;
  17678. X          calc_status = 0;
  17679. X          kbdmore = 0;
  17680. X          }
  17681. X           else if (curfractalspecific->tomandel != NOFRACTAL) {
  17682. X          /* switch to corresponding Mandel set */
  17683. X          fractype = curfractalspecific->tomandel;
  17684. X          curfractalspecific = &fractalspecific[fractype];
  17685. X          if (frommandel) {
  17686. X             xxmin = jxxmin;  xxmax = jxxmax;
  17687. X             yymin = jyymin;  yymax = jyymax;
  17688. X             xx3rd = jxx3rd;  yy3rd = jyy3rd;
  17689. X             }
  17690. X          else {
  17691. X             double ccreal,ccimag;
  17692. X             ccreal = (curfractalspecific->xmax - curfractalspecific->xmin) / 2;
  17693. X             ccimag = (curfractalspecific->ymax - curfractalspecific->ymin) / 2;
  17694. X             xxmin = xx3rd = param[0] - ccreal;
  17695. X             xxmax = param[0] + ccreal;
  17696. X             yymin = yy3rd = param[1] - ccimag;
  17697. X             yymax = param[1] + ccimag;
  17698. X             }
  17699. X          param[0] = 0;
  17700. X          param[1] = 0;
  17701. X          zoomoff = 1;
  17702. X          calc_status = 0;
  17703. X          kbdmore = 0;
  17704. X          }
  17705. X           else
  17706. X          buzzer(2); /* can't switch */
  17707. X           } /* end of else for if == cellular */
  17708. X           break;
  17709. X        case 'j':                 /* inverse julia toggle */
  17710. X           /* if the inverse types proliferate, something more elegant will
  17711. X              be needed */
  17712. X           if(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA)
  17713. X           {
  17714. X              static int oldtype = -1;
  17715. X              if(fractype==JULIA || fractype==JULIAFP)
  17716. X              {
  17717. X                 oldtype=fractype;
  17718. X                 fractype=INVERSEJULIA;
  17719. X              }
  17720. X              else if(fractype==INVERSEJULIA)
  17721. X              {
  17722. X                 if(oldtype != -1)
  17723. X                    fractype=oldtype;
  17724. X                 else
  17725. X                    fractype=JULIA;
  17726. X              }
  17727. X             curfractalspecific = &fractalspecific[fractype];
  17728. X             zoomoff = 1;
  17729. X             calc_status = 0;
  17730. X             kbdmore = 0;
  17731. X          }
  17732. X#if 0
  17733. X          else if(fractype==MANDEL || fractype==MANDELFP)
  17734. X          {
  17735. X            clear_zoombox();
  17736. X            Jiim(JIIM);
  17737. X            }
  17738. X#endif
  17739. X          else
  17740. X          buzzer(2);
  17741. X           break;
  17742. X        case '\\':                 /* return to prev image    */
  17743. X           if (--historyptr < 0)
  17744. X          historyptr = MAXHISTORY-1;
  17745. X           xxmax  = history[historyptr].xxmax;
  17746. X           xxmin  = history[historyptr].xxmin;
  17747. X           yymax  = history[historyptr].yymax;
  17748. X           yymin  = history[historyptr].yymin;
  17749. X           xx3rd  = history[historyptr].xx3rd;
  17750. X           yy3rd  = history[historyptr].yy3rd;
  17751. X           {
  17752. X              int j;
  17753. X              for(j=0;j<MAXPARAMS;j++)
  17754. X                    param[j] = history[historyptr].param[j];
  17755. X               }
  17756. X           fractype = history[historyptr].fractype;
  17757. X           curfractalspecific = &fractalspecific[fractype];
  17758. X           zoomoff = 1;
  17759. X           initmode = adapter;
  17760. X           if (curfractalspecific->isinteger != 0 &&
  17761. X           curfractalspecific->tofloat != NOFRACTAL)
  17762. X          usr_floatflag = 0;
  17763. X           if (curfractalspecific->isinteger == 0 &&
  17764. X           curfractalspecific->tofloat != NOFRACTAL)
  17765. X          usr_floatflag = 1;
  17766. X           historyflag = 1; /* avoid re-store parms due to rounding errs */
  17767. X           goto imagestart;
  17768. X        case 'd':                   /* shell to MS-DOS              */
  17769. X           stackscreen();
  17770. X#ifndef XFRACT
  17771. X           if (axmode == 0 || axmode > 7) {
  17772. Xstatic char far dosmsg[]={"\
  17773. XNote:  Your graphics image is still squirreled away in your video\n\
  17774. Xadapter's memory.  Switching video modes will clobber part of that\n\
  17775. Ximage.  Sorry - it's the best we could do."};
  17776. X          putstring(0,0,7,dosmsg);
  17777. X          movecursor(6,0);
  17778. X          }
  17779. X#endif
  17780. X           shell_to_dos();
  17781. X           unstackscreen();
  17782. X/*           calc_status = 0; */
  17783. X           break;
  17784. X        case 'c':                   /* switch to color cycling      */
  17785. X        case '+':                   /* rotate palette               */
  17786. X        case '-':                   /* rotate palette               */
  17787. X           clear_zoombox();
  17788. X           memcpy(olddacbox,dacbox,256*3);
  17789. X           rotate((kbdchar == 'c') ? 0 : ((kbdchar == '+') ? 1 : -1));
  17790. X           if (memcmp(olddacbox,dacbox,256*3))
  17791. X          colorstate = 1;
  17792. X           continue;
  17793. X        case 'e':                   /* switch to color editing      */
  17794. X           clear_zoombox();
  17795. X           if (dacbox[0][0] != 255 && !reallyega && colors >= 16
  17796. X         && dotmode != 11) {
  17797. X          int oldhelpmode;
  17798. X          oldhelpmode = helpmode;
  17799. X          memcpy(olddacbox,dacbox,256*3);
  17800. X          helpmode = HELPXHAIR;
  17801. X          EditPalette();
  17802. X          helpmode = oldhelpmode;
  17803. X          if (memcmp(olddacbox,dacbox,256*3))
  17804. X             colorstate = 1;
  17805. X          }
  17806. X           continue;
  17807. X        case 's':                   /* save-to-disk                 */
  17808. X           diskisactive = 1;    /* flag for disk-video routines */
  17809. X           note_zoom();
  17810. X           savetodisk(savename);
  17811. X           restore_zoom();
  17812. X           diskisactive = 0;    /* flag for disk-video routines */
  17813. X           continue;
  17814. X        case '#':                   /* 3D overlay                   */
  17815. X#ifdef XFRACT
  17816. X        case F3:                   /* 3D overlay                   */
  17817. X#endif
  17818. X           clear_zoombox();
  17819. X           overlay3d = 1;
  17820. X        case '3':                   /* restore-from (3d)            */
  17821. Xdo_3d_transform:
  17822. X           if(overlay3d)    
  17823. X              display3d = 2;    /* for <b> command         */
  17824. X           else   
  17825. X           display3d = 1;
  17826. X        case 'r':                   /* restore-from                 */
  17827. X           comparegif = 0;
  17828. X           frommandel = 0;
  17829. X           if(kbdchar == 'r')  {
  17830. X          if(debugflag == 50) {
  17831. X             comparegif = overlay3d = 1;
  17832. X             if (initbatch == 2) {
  17833. X            stackscreen(); /* save graphics image */
  17834. X            strcpy(readname,savename);
  17835. X            showfile = 0;
  17836. X            goto restorestart;
  17837. X            }
  17838. X             }
  17839. X          else
  17840. X             comparegif = overlay3d = 0;
  17841. X          display3d = 0;
  17842. X          }
  17843. X           stackscreen(); /* save graphics image */
  17844. X        if (overlay3d)
  17845. X              stacked = 0;
  17846. X            else
  17847. X              stacked = 1;
  17848. X           if (resave_flag) {
  17849. X          updatesavename(savename); /* do the pending increment */
  17850. X          resave_flag = started_resaves = 0;
  17851. X          }
  17852. X           showfile = -1;
  17853. X           goto restorestart;
  17854. X        case 'b':                   /* make batch file              */
  17855. X           make_batch_file();
  17856. X           break;
  17857. X        case 'p':                   /* print current image          */
  17858. X           note_zoom();
  17859. X           Print_Screen();
  17860. X           restore_zoom();
  17861. X           if (!keypressed())
  17862. X          buzzer(0);
  17863. X           else {
  17864. X          buzzer(1);
  17865. X          getakey();
  17866. X          }
  17867. X           continue;
  17868. X            case ENTER:                 /* Enter                        */
  17869. X            case ENTER_2:               /* Numeric-Keypad Enter         */
  17870. X#ifdef XFRACT
  17871. X               XZoomWaiting = 0;
  17872. X#endif
  17873. X           if (zwidth != 0.0) {    /* do a zoom */
  17874. X          init_pan_or_recalc(0);
  17875. X          kbdmore = 0;
  17876. X          }
  17877. X           if (calc_status != 4)    /* don't restart if image complete */
  17878. X          kbdmore = 0;
  17879. X           break;
  17880. X            case CTL_ENTER:             /* control-Enter                */
  17881. X            case CTL_ENTER_2:           /* Control-Keypad Enter         */
  17882. X           init_pan_or_recalc(1);
  17883. X           kbdmore = 0;
  17884. X           zoomout(); /* calc corners for zooming out */
  17885. X           break;
  17886. X            case INSERT:                /* insert                       */
  17887. X           setvideotext(); /* force text mode */
  17888. X           goto restart;
  17889. X            case LEFT_ARROW:            /* cursor left                  */
  17890. X            case RIGHT_ARROW:           /* cursor right                 */
  17891. X            case UP_ARROW:              /* cursor up                    */
  17892. X            case DOWN_ARROW:            /* cursor down                  */
  17893. X            case LEFT_ARROW_2:          /* Ctrl-cursor left             */
  17894. X            case RIGHT_ARROW_2:         /* Ctrl-cursor right            */
  17895. X            case UP_ARROW_2:            /* Ctrl-cursor up               */
  17896. X            case DOWN_ARROW_2:          /* Ctrl-cursor down             */
  17897. X           move_zoombox(kbdchar);
  17898. X           break;
  17899. X            case CTL_HOME:              /* Ctrl-home                    */
  17900. X           if (boxcount && (curfractalspecific->flags&NOROTATE) == 0) {
  17901. X                  i = key_count(CTL_HOME);
  17902. X          if ((zskew -= 0.02*i) < -0.48)
  17903. X             zskew = -0.48;
  17904. X          }
  17905. X           break;
  17906. X            case CTL_END:               /* Ctrl-end                     */
  17907. X               if (boxcount && (curfractalspecific->flags&NOROTATE) == 0) {
  17908. X                  i = key_count(CTL_END);
  17909. X          if ((zskew += 0.02*i) > 0.48)
  17910. X             zskew = 0.48;
  17911. X          }
  17912. X           break;
  17913. X            case CTL_PAGE_UP:           /* Ctrl-pgup                    */
  17914. X               if (boxcount)
  17915. X                  chgboxi(0,-2*key_count(CTL_PAGE_UP));
  17916. X               break;
  17917. X            case CTL_PAGE_DOWN:         /* Ctrl-pgdn                    */
  17918. X               if (boxcount)
  17919. X                  chgboxi(0,2*key_count(CTL_PAGE_DOWN));
  17920. X               break;
  17921. X            case PAGE_UP:               /* page up                      */
  17922. X           if (zoomoff == 1)
  17923. X          if (zwidth == 0) { /* start zoombox */
  17924. X             zwidth = zdepth = 1;
  17925. X             zrotate = zskew = 0;
  17926. X             zbx = zby = 0;
  17927. X             find_special_colors();
  17928. X             boxcolor = color_bright;
  17929. X             }
  17930. X          else
  17931. X                     resizebox(0-key_count(PAGE_UP));
  17932. X               break;
  17933. X            case PAGE_DOWN:             /* page down                    */
  17934. X           if (boxcount) {
  17935. X          if (zwidth >= .999 && zdepth >= 0.999) /* end zoombox */
  17936. X             zwidth = 0;
  17937. X          else
  17938. X                     resizebox(key_count(PAGE_DOWN));
  17939. X                  }
  17940. X               break;
  17941. X            case CTL_MINUS:             /* Ctrl-kpad-                  */
  17942. X               if (boxcount && (curfractalspecific->flags&NOROTATE) == 0)
  17943. X                  zrotate += key_count(CTL_MINUS);
  17944. X               break;
  17945. X            case CTL_PLUS:              /* Ctrl-kpad+               */
  17946. X               if (boxcount && (curfractalspecific->flags&NOROTATE) == 0)
  17947. X                  zrotate -= key_count(CTL_PLUS);
  17948. X               break;
  17949. X            case CTL_INSERT:            /* Ctrl-ins                 */
  17950. X               boxcolor += key_count(CTL_INSERT);
  17951. X               break;
  17952. X            case CTL_DEL:               /* Ctrl-del                 */
  17953. X               boxcolor -= key_count(CTL_DEL);
  17954. X           break;
  17955. X        case DELETE:        /* select video mode from list */
  17956. X           stackscreen();
  17957. X           kbdchar = select_video_mode(adapter);
  17958. X           if (check_vidmode_key(0,kbdchar) >= 0) /* picked a new mode? */
  17959. X          discardscreen();
  17960. X           else
  17961. X          unstackscreen();
  17962. X           /* fall through */
  17963. X        default:            /* other (maybe a valid Fn key) */
  17964. X           if ((k = check_vidmode_key(0,kbdchar)) >= 0) {
  17965. X          adapter = k;
  17966. X/*          if (videotable[adapter].dotmode != 11       Took out so that */
  17967. X/*            || videotable[adapter].colors != colors)  DAC is not reset */
  17968. X/*             savedac = 0;                    when changing video modes */
  17969. X          calc_status = 0;
  17970. X          kbdmore = 0;
  17971. X          continue;
  17972. X          }
  17973. X           break;
  17974. X
  17975. X        } /* end of the big switch */
  17976. X
  17977. X     if (zoomoff == 1 && kbdmore == 1) /* draw/clear a zoom box? */
  17978. X        drawbox(1);
  17979. X#ifdef XFRACT
  17980. X     if (resizeWindow()) {
  17981. X         calc_status = -1;
  17982. X     }
  17983. X#endif
  17984. X     }
  17985. X      }
  17986. X
  17987. X}
  17988. X
  17989. X/* read keystrokes while = specified key, return 1+count;    */
  17990. X/* used to catch up when moving zoombox is slower than keyboard */
  17991. Xint key_count(int keynum)
  17992. X{  int ctr;
  17993. X   ctr = 1;
  17994. X   while (keypressed() == keynum) {
  17995. X      getakey();
  17996. X      ++ctr;
  17997. X      }
  17998. X   return ctr;
  17999. X}
  18000. X
  18001. X/* do all pending movement at once for smooth mouse diagonal moves */
  18002. Xstatic void move_zoombox(int keynum)
  18003. X{  int vertical, horizontal, getmore;
  18004. X   if (boxcount == 0)
  18005. X      return;
  18006. X   vertical = horizontal = 0;
  18007. X   getmore = 1;
  18008. X   while (getmore) {
  18009. X      switch (keynum) {
  18010. X         case LEFT_ARROW:               /* cursor left */
  18011. X            --horizontal;
  18012. X            break;
  18013. X         case RIGHT_ARROW:              /* cursor right */
  18014. X            ++horizontal;
  18015. X            break;
  18016. X         case UP_ARROW:                 /* cursor up */
  18017. X            --vertical;
  18018. X            break;
  18019. X         case DOWN_ARROW:               /* cursor down */
  18020. X            ++vertical;
  18021. X            break;
  18022. X         case LEFT_ARROW_2:             /* Ctrl-cursor left */
  18023. X            horizontal -= 5;
  18024. X            break;
  18025. X         case RIGHT_ARROW_2:             /* Ctrl-cursor right */
  18026. X            horizontal += 5;
  18027. X            break;
  18028. X         case UP_ARROW_2:               /* Ctrl-cursor up */
  18029. X            vertical -= 5;
  18030. X            break;
  18031. X         case DOWN_ARROW_2:             /* Ctrl-cursor down */
  18032. X        vertical += 5;
  18033. X        break;
  18034. X     default:
  18035. X        getmore = 0;
  18036. X     }
  18037. X      if (getmore) {
  18038. X     if (getmore == 2)        /* eat last key used */
  18039. X        getakey();
  18040. X     getmore = 2;
  18041. X     keynum = keypressed();     /* next pending key */
  18042. X     }
  18043. X      }
  18044. X   if (horizontal!=0)
  18045. X      moveboxf((double)horizontal/dxsize,0.0);
  18046. X   if (vertical!=0)
  18047. X      moveboxf(0.0,(double)vertical/dysize);
  18048. X}
  18049. X
  18050. X/* displays differences between current image file and new image */
  18051. Xstatic FILE *cmp_fp;
  18052. Xstatic errcount;
  18053. Xint cmp_line(BYTE *pixels, int linelen)
  18054. X{
  18055. X   extern int rowcount;
  18056. X   int row,col;
  18057. X   int oldcolor;
  18058. X   if((row = rowcount++) == 0) {
  18059. X      errcount = 0;
  18060. X      cmp_fp = fopen("cmperr",(initbatch)?"a":"w");
  18061. X      outln_cleanup = cmp_line_cleanup;
  18062. X      }
  18063. X   if(pot16bit) { /* 16 bit info, ignore odd numbered rows */
  18064. X      if((row & 1) != 0) return(0);
  18065. X      row >>= 1;
  18066. X      }
  18067. X   for(col=0;col<linelen;col++) {
  18068. X      oldcolor=getcolor(col,row);
  18069. X      if(oldcolor==pixels[col])
  18070. X     putcolor(col,row,0);
  18071. X      else {
  18072. X     if(oldcolor==0)
  18073. X        putcolor(col,row,1);
  18074. X     ++errcount;
  18075. X     if(initbatch == 0)
  18076. X        fprintf(cmp_fp,"#%5d col %3d row %3d old %3d new %3d\n",
  18077. X           errcount,col,row,oldcolor,pixels[col]);
  18078. X     }
  18079. X      }
  18080. X   return(0);
  18081. X}
  18082. X
  18083. Xstatic void cmp_line_cleanup()
  18084. X{
  18085. X   char *timestring;
  18086. X   time_t ltime;
  18087. X   if(initbatch) {
  18088. X      time(<ime);
  18089. X      timestring = ctime(<ime);
  18090. X      timestring[24] = 0; /*clobber newline in time string */
  18091. X      fprintf(cmp_fp,"%s compare to %s has %5d errs\n",
  18092. X             timestring,readname,errcount);
  18093. X      }
  18094. X   fclose(cmp_fp);
  18095. X}
  18096. X
  18097. Xint pot_line(BYTE *pixels, int linelen)
  18098. X{
  18099. X   extern int rowcount;
  18100. X   int row,col,saverowcount;
  18101. X   if (rowcount == 0)
  18102. X      if (pot_startdisk() < 0)
  18103. X     return -1;
  18104. X   saverowcount = rowcount;
  18105. X   row = (rowcount >>= 1);
  18106. X   if ((saverowcount & 1) != 0) /* odd line */
  18107. X      row += ydots;
  18108. X   else             /* even line */
  18109. X      if (dotmode != 11) /* display the line too */
  18110. X     out_line(pixels,linelen);
  18111. X   for (col = 0; col < xdots; ++col)
  18112. X      writedisk(col+sxoffs,row+syoffs,*(pixels+col));
  18113. X   rowcount = saverowcount + 1;
  18114. X   return(0);
  18115. X}
  18116. X
  18117. Xstatic int call_line3d(BYTE *pixels, int linelen)
  18118. X{
  18119. X   /* this routine exists because line3d might be in an overlay */
  18120. X   return(line3d(pixels,linelen));
  18121. X}
  18122. X
  18123. X
  18124. Xvoid clear_zoombox()
  18125. X{
  18126. X   zwidth = 0;
  18127. X   drawbox(0);
  18128. X   reset_zoom_corners();
  18129. X}
  18130. X
  18131. Xvoid reset_zoom_corners()
  18132. X{
  18133. X   xxmin = sxmin;
  18134. X   xxmax = sxmax;
  18135. X   xx3rd = sx3rd;
  18136. X   yymax = symax;
  18137. X   yymin = symin;
  18138. X   yy3rd = sy3rd;
  18139. X}
  18140. X
  18141. Xstatic char far *savezoom;
  18142. Xextern int boxcount;
  18143. Xextern char boxx[],boxy[];
  18144. Xextern char boxvalues[];
  18145. X
  18146. Xstatic void note_zoom()
  18147. X{
  18148. X   if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */
  18149. X      if ((savezoom = farmemalloc((long)(5*boxcount))) == NULL)
  18150. X     clear_zoombox(); /* not enuf mem so clear the box */
  18151. X      else {
  18152. X     reset_zoom_corners(); /* reset these to overall image, not box */
  18153. X     far_memcpy(savezoom,boxx,boxcount*2);
  18154. X     far_memcpy(savezoom+boxcount*2,boxy,boxcount*2);
  18155. X     far_memcpy(savezoom+boxcount*4,boxvalues,boxcount);
  18156. X     }
  18157. X      }
  18158. X}
  18159. X
  18160. Xstatic void restore_zoom()
  18161. X{
  18162. X   if (boxcount) { /* restore zoombox arrays */
  18163. X      far_memcpy(boxx,savezoom,boxcount*2);
  18164. X      far_memcpy(boxy,savezoom+boxcount*2,boxcount*2);
  18165. X      far_memcpy(boxvalues,savezoom+boxcount*4,boxcount);
  18166. X      farmemfree(savezoom);
  18167. X      drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */
  18168. X      }
  18169. X}
  18170. X
  18171. X
  18172. X/*
  18173. X   Function setup287code is called by main() when a 287
  18174. X   or better fpu is detected.
  18175. X*/
  18176. X#define ORBPTR(x) fractalspecific[x].orbitcalc
  18177. Xstatic void setup287code()
  18178. X{
  18179. X   ORBPTR(MANDELFP)      = ORBPTR(JULIAFP)     = FJuliafpFractal;
  18180. X   ORBPTR(BARNSLEYM1FP)   = ORBPTR(BARNSLEYJ1FP) = FBarnsley1FPFractal;
  18181. X   ORBPTR(BARNSLEYM2FP)   = ORBPTR(BARNSLEYJ2FP) = FBarnsley2FPFractal;
  18182. X   ORBPTR(MANOWARFP)      = ORBPTR(MANOWARJFP)     = FManOWarfpFractal;
  18183. X   ORBPTR(MANDELLAMBDAFP) = ORBPTR(LAMBDAFP)     = FLambdaFPFractal;
  18184. X}
  18185. X
  18186. Xint sound_line(pixels, linelen)
  18187. XBYTE *pixels;
  18188. Xint linelen;
  18189. X{
  18190. X   extern int rowcount;
  18191. X   extern int basehertz;
  18192. X   extern int xdots;
  18193. X   extern int colors;
  18194. X   extern int orbit_delay;
  18195. X   int i;
  18196. X   for(i=0;i<linelen;i++)
  18197. X   {
  18198. X      putcolor(i,rowcount,pixels[i]);
  18199. X      if(orbit_delay > 0)
  18200. X         sleepms(orbit_delay);
  18201. X      snd((int)(pixels[i]*3000/colors+basehertz));
  18202. X      if(keypressed())
  18203. X      {
  18204. X        nosnd();
  18205. X        return(-1);
  18206. X      }
  18207. X   }
  18208. X   nosnd();
  18209. X   rowcount++;
  18210. X   return(0);
  18211. X}
  18212. X
  18213. Xint check_key()
  18214. X{
  18215. X   int key;
  18216. X   if((key = keypressed()) != 0) {
  18217. X      if(key != 'o' && key != 'O') {
  18218. X     fflush(stdout);
  18219. X     return(-1);
  18220. X      }
  18221. X      getakey();
  18222. X      if (dotmode != 11)
  18223. X     show_orbit = 1 - show_orbit;
  18224. X   }
  18225. X   return(0);
  18226. X}
  18227. X
  18228. X/* timer function:
  18229. X     timer(0,(*fractal)())        fractal engine
  18230. X     timer(1,NULL,int width)        decoder
  18231. X     timer(2)                encoder
  18232. X  */
  18233. X#ifndef XFRACT
  18234. Xint timer(int timertype,int(*subrtn)(),...)
  18235. X#else
  18236. Xint timer(va_alist)
  18237. Xva_dcl
  18238. X#endif
  18239. X{
  18240. X   va_list arg_marker;    /* variable arg list */
  18241. X   char *timestring;
  18242. X   time_t ltime;
  18243. X   FILE *fp;
  18244. X   int out;
  18245. X   int i;
  18246. X   int do_bench;
  18247. X
  18248. X#ifndef XFRACT
  18249. X   va_start(arg_marker,subrtn);
  18250. X#else
  18251. X   int timertype;
  18252. X   int (*subrtn)();
  18253. X   va_start(arg_marker);
  18254. X   timertype = va_arg(arg_marker, int);
  18255. X   subrtn = ( int (*)()) va_arg(arg_marker, int *);
  18256. X#endif
  18257. X
  18258. X   do_bench = timerflag; /* record time? */
  18259. X   if (timertype == 2)     /* encoder, record time only if debug=200 */
  18260. X      do_bench = (debugflag == 200);
  18261. X   if(do_bench)
  18262. X      fp=fopen("bench","a");
  18263. X   timer_start = clock_ticks();
  18264. X   switch(timertype) {
  18265. X      case 0:
  18266. X     out = (*subrtn)();
  18267. X     break;
  18268. X      case 1:
  18269. X     i = va_arg(arg_marker,int);
  18270. X     out = decoder(i);         /* not indirect, safer with overlays */
  18271. X     break;
  18272. X      case 2:
  18273. X     out = encoder();         /* not indirect, safer with overlays */
  18274. X     break;
  18275. X      }
  18276. X   /* next assumes CLK_TCK is 10^n, n>=2 */
  18277. X   timer_interval = (clock_ticks() - timer_start) / (CLK_TCK/100);
  18278. X
  18279. X   if(do_bench) {
  18280. X      time(<ime);
  18281. X      timestring = ctime(<ime);
  18282. X      timestring[24] = 0; /*clobber newline in time string */
  18283. X      switch(timertype) {
  18284. X     case 1:
  18285. X        fprintf(fp,"decode ");
  18286. X        break;
  18287. X     case 2:
  18288. X        fprintf(fp,"encode ");
  18289. X        break;
  18290. X     }
  18291. X      fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%d",
  18292. X      timestring,
  18293. X      curfractalspecific->name,
  18294. X      xdots,
  18295. X      ydots,
  18296. X      maxit);
  18297. X      fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100);
  18298. X      if(fp != NULL)
  18299. X     fclose(fp);
  18300. X      }
  18301. X   return(out);
  18302. X}
  18303. SHAR_EOF
  18304. $TOUCH -am 1028230093 fractint.c &&
  18305. chmod 0644 fractint.c ||
  18306. echo "restore of fractint.c failed"
  18307. set `wc -c fractint.c`;Wc_c=$1
  18308. if test "$Wc_c" != "54603"; then
  18309.     echo original size 54603, current size $Wc_c
  18310. fi
  18311. # ============= gifview.c ==============
  18312. echo "x - extracting gifview.c (Text)"
  18313. sed 's/^X//' << 'SHAR_EOF' > gifview.c &&
  18314. X/*
  18315. X *
  18316. X * This GIF decoder is designed for use with the FRACTINT program.
  18317. X * This decoder code lacks full generality in the following respects:
  18318. X * supports non-interlaced GIF files only, and calmly ignores any
  18319. X * local color maps and non-Fractint-specific extension blocks.
  18320. X *
  18321. X * GIF and 'Graphics Interchange Format' are trademarks (tm) of
  18322. X * Compuserve, Incorporated, an H&R Block Company.
  18323. X *
  18324. X *                                            Tim Wegner
  18325. X */
  18326. X
  18327. X#include <stdio.h>
  18328. X#include <string.h>
  18329. X#ifndef XFRACT
  18330. X#include <dos.h>
  18331. X#endif
  18332. X#include "fractint.h"
  18333. X#include "prototyp.h"
  18334. X
  18335. Xstatic void close_file(void);
  18336. X
  18337. X#define MAXCOLORS    256
  18338. X
  18339. Xextern int rowcount;        /* row counter for screen */
  18340. Xextern char readname[];     /* file name          */
  18341. Xstatic FILE *fpin = NULL;    /* FILE pointer       */
  18342. Xunsigned int height;
  18343. Xextern    char busy;
  18344. Xunsigned numcolors;
  18345. X
  18346. Xextern char MAP_name[];
  18347. Xextern int mapset;
  18348. Xextern int colorstate;        /* comments in cmdfiles */
  18349. X
  18350. Xextern int colors;
  18351. Xextern int glassestype;
  18352. Xextern int display3d;
  18353. Xextern int dotmode;        /* so we can detect disk-video */
  18354. Xextern int calc_status;
  18355. Xextern long calctime;
  18356. Xextern long timer_interval;
  18357. Xextern int pot16bit;        /* 16 bit values for continuous potential */
  18358. Xextern int dither_flag;
  18359. X
  18360. Xextern int (*outln)();
  18361. Xstatic int out_line_dither(BYTE *, int);
  18362. Xstatic int out_line_migs(BYTE *, int);
  18363. X
  18364. Xint bad_code_count = 0;     /* needed by decoder module */
  18365. X
  18366. Xextern short skipxdots; /* 0 to get every dot, 1 for every 2nd, 2 every 3rd, ... */
  18367. Xextern short skipydots; /* ditto for rows */
  18368. Xunsigned int far gifview_image_top;    /* (for migs) */
  18369. Xunsigned int far gifview_image_left;    /* (for migs) */
  18370. Xunsigned int far gifview_image_twidth;    /* (for migs) */
  18371. X
  18372. Xint get_byte()
  18373. X{
  18374. X   return (getc(fpin)); /* EOF is -1, as desired */
  18375. X}
  18376. X
  18377. Xint get_bytes(BYTE *where,int how_many)
  18378. X{
  18379. X   return (fread((char *)where,1,how_many,fpin)); /* EOF is -1, as desired */
  18380. X}
  18381. X
  18382. Xextern BYTE dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  18383. X#ifndef XFRACT
  18384. Xextern BYTE decoderline[MAXPIXELS+1]; /* write-line routines use this */
  18385. X#else
  18386. XBYTE decoderline[MAXPIXELS+1]; /* write-line routines use this */
  18387. X#endif
  18388. X
  18389. Xstatic int ditherlen = -1;
  18390. Xstatic char far *ditherbuf = NULL;
  18391. X
  18392. X/* Main entry decoder */
  18393. X
  18394. Xvoid decoder_overlay() { }    /* for restore_active_ovly */
  18395. X
  18396. Xint gifview1()
  18397. X{
  18398. X   BYTE buffer[16];
  18399. X   unsigned top, left, width, finished;
  18400. X   char temp1[81];
  18401. X
  18402. X   int status;
  18403. X   int i, j, k, planes;
  18404. X
  18405. X   ENTER_OVLY(OVLY_DECODER);
  18406. X
  18407. X   status = 0;
  18408. X
  18409. X   /* initialize the row count for write-lines */
  18410. X   rowcount = 0;
  18411. X
  18412. X   /* zero out the full write-line */
  18413. X   for (width = 0; width < MAXPIXELS+1; width++) decoderline[width] = 0;
  18414. X
  18415. X   /* Open the file */
  18416. X   strcpy(temp1,readname);
  18417. X   if (strchr(temp1,'.') == NULL) {
  18418. X      strcat(temp1,DEFAULTFRACTALTYPE);
  18419. X      if ((fpin = fopen(temp1,"rb")) != NULL) {
  18420. X     fclose(fpin);
  18421. X     }
  18422. X      else {
  18423. X     strcpy(temp1,readname);
  18424. X     strcat(temp1,ALTERNATEFRACTALTYPE);
  18425. X     }
  18426. X      }
  18427. X   if ((fpin = fopen(temp1, "rb")) == NULL) {
  18428. X      EXIT_OVLY;
  18429. X      return (-1);
  18430. X      }
  18431. X
  18432. X   /* Get the screen description */
  18433. X   for (i = 0; i < 13; i++)
  18434. X   {
  18435. X      int tmp;
  18436. X
  18437. X      buffer[i] = tmp = get_byte();
  18438. X      if (tmp < 0)
  18439. X      {
  18440. X     close_file();
  18441. X         EXIT_OVLY;
  18442. X     return(-1);
  18443. X      }
  18444. X   }
  18445. X
  18446. X   if(strncmp(buffer,"GIF87a",3) ||             /* use updated GIF specs */
  18447. X      buffer[3] < '0' || buffer[3] > '9' ||
  18448. X      buffer[4] < '0' || buffer[4] > '9' ||
  18449. X      buffer[5] < 'A' || buffer[5] > 'z' )
  18450. X   {
  18451. X      close_file();
  18452. X      EXIT_OVLY;
  18453. X      return(-1);
  18454. X   }
  18455. X
  18456. X   width  = buffer[6] | (buffer[7] << 8);
  18457. X   height = buffer[8] | (buffer[9] << 8);
  18458. X   planes = (buffer[10] & 0x0F) + 1;
  18459. X   gifview_image_twidth = width;
  18460. X
  18461. X   if((buffer[10] & 0x80)==0)     /* color map (better be!) */
  18462. X   {
  18463. X      close_file();
  18464. X      EXIT_OVLY;
  18465. X      return(-1);
  18466. X   }
  18467. X   numcolors = 1 << planes;
  18468. X
  18469. X   if (dither_flag && numcolors>2 && colors==2 && outln==out_line) {
  18470. X     outln = out_line_dither;
  18471. X   }
  18472. X
  18473. X
  18474. X   for (i = 0; i < numcolors; i++)
  18475. X   {
  18476. X      for (j = 0; j < 3; j++) {
  18477. X     if ((k = get_byte()) < 0)
  18478. X     {
  18479. X        close_file();
  18480. X            EXIT_OVLY;
  18481. X        return(-1);
  18482. X     }
  18483. X     if(!display3d || (glassestype != 1 && glassestype != 2))
  18484. X        dacbox[i][j] = k >> 2;
  18485. X      }
  18486. X   }
  18487. X   colorstate = 1; /* colors aren't default and not a known .map file */
  18488. X
  18489. X   /* don't read if glasses */
  18490. X   if (display3d && mapset && glassestype!=1 && glassestype != 2)
  18491. X   {
  18492. X       ValidateLuts(MAP_name);    /* read the palette file */
  18493. X       spindac(0,1); /* load it, but don't spin */
  18494. X   }
  18495. X   if (dacbox[0][0] != 255)
  18496. X      spindac(0,1);      /* update the DAC */
  18497. X
  18498. X   if (dotmode == 11) /* disk-video */
  18499. X       dvid_status(1,"...restoring...");
  18500. X
  18501. X   /* Now display one or more GIF objects */
  18502. X   finished = 0;
  18503. X   while (!finished)
  18504. X   {
  18505. X      switch (get_byte())
  18506. X      {
  18507. X      case ';':
  18508. X     /* End of the GIF dataset */
  18509. X
  18510. X     finished = 1;
  18511. X     status = 0;
  18512. X     break;
  18513. X
  18514. X      case '!':                               /* GIF Extension Block */
  18515. X     get_byte();             /* read (and ignore) the ID */
  18516. X     while ((i = get_byte()) > 0)     /* get the data length */
  18517. X        for (j = 0; j < i; j++)
  18518. X           get_byte();     /* flush the data */
  18519. X     break;
  18520. X      case ',':
  18521. X     /*
  18522. X      * Start of an image object. Read the image description.
  18523. X      */
  18524. X
  18525. X     for (i = 0; i < 9; i++)
  18526. X     {
  18527. X            int tmp;
  18528. X
  18529. X            buffer[i] = tmp = get_byte();
  18530. X        if (tmp < 0)
  18531. X        {
  18532. X           status = -1;
  18533. X           break;
  18534. X        }
  18535. X     }
  18536. X     if(status < 0)
  18537. X     {
  18538. X        finished = 1;
  18539. X        break;
  18540. X     }
  18541. X
  18542. X     left    = buffer[0] | (buffer[1] << 8);
  18543. X     top    = buffer[2] | (buffer[3] << 8);
  18544. X     width    = buffer[4] | (buffer[5] << 8);
  18545. X     if (pot16bit) width >>= 1;
  18546. X     height = buffer[6] | (buffer[7] << 8);
  18547. X
  18548. X         /* adjustments for handling MIGs */
  18549. X         gifview_image_top  = top;
  18550. X         if (skipxdots > 0)
  18551. X             gifview_image_top /= (skipydots+1);
  18552. X         gifview_image_left = left;
  18553. X         if (skipydots > 0)
  18554. X             gifview_image_left /= (skipxdots+1);
  18555. X         if (outln==out_line &&
  18556. X             (width != gifview_image_twidth || top != 0)) {
  18557. X              /* we're using normal decoding and we have a MIG */
  18558. X         outln = out_line_migs;
  18559. X             }
  18560. X
  18561. X         /* Skip local color palette */
  18562. X         if((buffer[8] & 0x80)==0x80) {      /* local map? */
  18563. X             int numcolors;    /* make this local */
  18564. X             planes = (buffer[8] & 0x0F) + 1;
  18565. X             numcolors = 1 << planes;
  18566. X             /* skip local map */
  18567. X             for (i = 0; i < numcolors; i++) {
  18568. X                for (j = 0; j < 3; j++) {
  18569. X                   if ((k = get_byte()) < 0) {
  18570. X                      close_file();
  18571. X                      return(-1);
  18572. X                      }
  18573. X                   }
  18574. X                }
  18575. X             }
  18576. X
  18577. X         /* initialize the row count for write-lines */
  18578. X         rowcount = 0;
  18579. X
  18580. X         /* zero out the full write-line */
  18581. X         {
  18582. X         int i;
  18583. X         for (i = 0; i < MAXPIXELS+1; i++) decoderline[i] = 0;
  18584. X         }
  18585. X
  18586. X     if (calc_status == 1) /* should never be so, but make sure */
  18587. X        calc_status = 0;
  18588. X     busy = 1;    /* for slideshow CALCWAIT */
  18589. X     status = timer(1,NULL,width); /* call decoder(width) via timer */
  18590. X     busy = 0;    /* for slideshow CALCWAIT */
  18591. X     if (calc_status == 1) /* e.g., set by line3d */
  18592. X     {
  18593. X        calctime = timer_interval; /* note how long it took */
  18594. X        if (keypressed() != 0) {
  18595. X           calc_status = 3; /* interrupted, not resumable */
  18596. X               finished = 1;
  18597. X           }
  18598. X        else
  18599. X           calc_status = 4; /* complete */
  18600. X     }
  18601. X         /* Hey! the decoder doesn't read the last (0-length) block!! */
  18602. X         if (get_byte() != 0) {
  18603. X             status = -1;
  18604. X             finished = 1;
  18605. X             }
  18606. X     break;
  18607. X      default:
  18608. X     status = -1;
  18609. X     finished = 1;
  18610. X     break;
  18611. X      }
  18612. X   }
  18613. X   close_file();
  18614. X   if (dotmode == 11) { /* disk-video */
  18615. X      dvid_status(0,"Restore completed");
  18616. X      dvid_status(1,"");
  18617. X      }
  18618. X      
  18619. X    if (ditherbuf != NULL) { /* we're done, free dither memory */
  18620. X        farmemfree(ditherbuf);
  18621. X        ditherbuf = NULL;
  18622. X    }
  18623. X
  18624. X   EXIT_OVLY;
  18625. X   return(status);
  18626. X}
  18627. X
  18628. Xstatic void close_file()
  18629. X{
  18630. X   fclose(fpin);
  18631. X   fpin = NULL;
  18632. X}
  18633. X
  18634. X/* routine for MIGS that generates partial output lines */
  18635. X
  18636. Xstatic out_line_migs(BYTE *pixels, int linelen)
  18637. X{
  18638. Xint row, startcol, stopcol;
  18639. X
  18640. Xrow = gifview_image_top + rowcount;
  18641. Xstartcol = gifview_image_left;
  18642. Xstopcol = startcol+linelen-1;
  18643. Xput_line(row, startcol, stopcol, pixels);
  18644. Xrowcount++;
  18645. X
  18646. X}
  18647. X
  18648. X
  18649. Xstatic int out_line_dither(pixels, linelen)
  18650. XBYTE *pixels;
  18651. Xint linelen;
  18652. X{
  18653. X    int i,nexterr,brt,err;
  18654. X    if(ditherbuf == NULL)
  18655. X        ditherbuf = (char far *)farmemalloc(linelen+1);
  18656. X    far_memset( ditherbuf, 0, linelen+1); 
  18657. X
  18658. X    nexterr = (rand15()&0x1f)-16;
  18659. X    for (i=0;i<linelen;i++) {
  18660. X    brt = (dacbox[pixels[i]][0]*5+dacbox[pixels[i]][1]*9 +
  18661. X        dacbox[pixels[i]][2]*2)>>4; /* brightness from 0 to 63 */
  18662. X    brt += nexterr;
  18663. X    if (brt>32) {
  18664. X        pixels[i] = 1;
  18665. X        err = brt-63;
  18666. X    } else {
  18667. X        pixels[i] = 0;
  18668. X        err = brt;
  18669. X    }
  18670. X    nexterr = ditherbuf[i+1]+err/3;
  18671. X    ditherbuf[i] = err/3;
  18672. X    ditherbuf[i+1] = err/3;
  18673. X    }
  18674. X    return out_line(pixels, linelen);
  18675. X}
  18676. SHAR_EOF
  18677. $TOUCH -am 1028230093 gifview.c &&
  18678. chmod 0644 gifview.c ||
  18679. echo "restore of gifview.c failed"
  18680. set `wc -c gifview.c`;Wc_c=$1
  18681. if test "$Wc_c" != "8871"; then
  18682.     echo original size 8871, current size $Wc_c
  18683. fi
  18684. # ============= hc.c ==============
  18685. echo "x - extracting hc.c (Text)"
  18686. sed 's/^X//' << 'SHAR_EOF' > hc.c &&
  18687. X
  18688. X/*
  18689. X * hc.c
  18690. X *
  18691. X * Stand-alone FRACTINT help compiler.  Compile in the COMPACT memory model.
  18692. X *
  18693. X * See HC.DOC for source file syntax.
  18694. X *
  18695. X *
  18696. X * Revision History:
  18697. X *
  18698. X *   02-26-91 EAN     Initial version.
  18699. X *
  18700. X *   03-21-91 EAN     Modified for automatic paragraph formatting.
  18701. X *              Added several new commands:
  18702. X *             Format[+/-]  Enable/disable paragraph formatting
  18703. X *             Doc[+/-]     Enable/disable output to document.
  18704. X *             Online[+/-]  Enable/disable output to online help.
  18705. X *             Label=       Defines a label. Replaces ~(...)
  18706. X *             FF          Forces a form-feed.  Replaces ~~
  18707. X *             FormatExclude=val Exclude lines past val from
  18708. X *                      formatting.  If before any topic sets
  18709. X *                      global default, otherwise set local.
  18710. X *             FormatExclude= Set to global default.
  18711. X *             FormatExclude=n Disable exclusion. (global or local)
  18712. X *             FormatExclude[+/-] Enable/disable format exclusion.
  18713. X *             Center[+/-]  Enable/disable centering of text.
  18714. X *             \ before nl  Forces the end of a paragraph
  18715. X *              Support for commands embedded in text with new
  18716. X *              ~(...) format.
  18717. X *              Support for multiple commands on a line separated by
  18718. X *              commas.
  18719. X *              Support for implict links; explicit links must now
  18720. X *              start with an equal sign.
  18721. X *   04-03-91 EAN     Added "include" command (works like #include)
  18722. X *   04-10-91 EAN     Added support for "data" topics.
  18723. X *              Added Comment/EndComment commands for multi-line
  18724. X *             comments.
  18725. X *              Added CompressSpaces[+/-] command.
  18726. X *              Added DocContents command for document printing.
  18727. X *              Added BinInc command which includes a binary file
  18728. X *             in a data topic.
  18729. X *              Fixed tables to flow down instead of across the page.
  18730. X *             Makes no allowances for page breaks within tables.
  18731. X *
  18732. X */
  18733. X
  18734. X
  18735. X#define HC_C
  18736. X
  18737. X#define INCLUDE_COMMON  /* tell helpcom.h to include common code */
  18738. X
  18739. X
  18740. X#include <stdio.h>
  18741. X#ifndef XFRACT
  18742. X#include <io.h>
  18743. X#include <stdarg.h>
  18744. X#else
  18745. X#include <varargs.h>
  18746. X#define strupr strlwr
  18747. X#endif
  18748. X#include <fcntl.h>
  18749. X#include <stdlib.h>
  18750. X#include <string.h>
  18751. X#include <ctype.h>
  18752. X
  18753. X#ifdef __TURBOC__
  18754. X#   include <dir.h>
  18755. X#   define FNSPLIT fnsplit
  18756. X#else
  18757. X#   define MAXFILE _MAX_FNAME
  18758. X#   define MAXEXT  _MAX_EXT
  18759. X#   define FNSPLIT _splitpath
  18760. X#endif
  18761. X
  18762. X
  18763. X#include <assert.h>
  18764. X#include "helpcom.h"
  18765. X
  18766. X
  18767. X/*
  18768. X * When defined, SHOW_ERROR_LINE will cause the line number in HC.C where
  18769. X * errors/warnings/messages are generated to be displayed at the start of
  18770. X * the line.
  18771. X *
  18772. X * Used when debugging HC.  Also useful for finding the line (in HC.C) that
  18773. X * generated a error or warning.
  18774. X */
  18775. X
  18776. X#ifndef XFRACT
  18777. X#define SHOW_ERROR_LINE
  18778. X#endif
  18779. X
  18780. X
  18781. X#define DEFAULT_SRC_FNAME "help.src"
  18782. X#define DEFAULT_HLP_FNAME "fractint.hlp"
  18783. X#define DEFAULT_EXE_FNAME "fractint.exe"
  18784. X#define DEFAULT_DOC_FNAME "fractint.doc"
  18785. X
  18786. X#define TEMP_FNAME      "HC.$$$"
  18787. X#define SWAP_FNAME      "HCSWAP.$$$"
  18788. X
  18789. X#define MAX_ERRORS      (25)     /* stop after this many errors */
  18790. X#define MAX_WARNINGS      (25)     /* stop after this many warnings */
  18791. X                 /* 0 = never stop */
  18792. X
  18793. X#define INDEX_LABEL      "HELP_INDEX"
  18794. X#define DOCCONTENTS_TITLE "DocContent"
  18795. X
  18796. X
  18797. X
  18798. X#define BUFFER_SIZE   (24*1024)
  18799. X
  18800. X
  18801. Xtypedef struct
  18802. X   {
  18803. X   int        type;         /* 0 = name is topic title, 1 = name is label, */
  18804. X                 /*   2 = "special topic"; name is NULL and */
  18805. X                 /*   topic_num/topic_off is valid */
  18806. X   int        topic_num;         /* topic number to link to */
  18807. X   unsigned topic_off;         /* offset into topic to link to */
  18808. X   int        doc_page;         /* document page # to link to */
  18809. X   char    *name;         /* name of label or title of topic to link to */
  18810. X   char    *srcfile;         /* .SRC file link appears in */
  18811. X   int        srcline;         /* .SRC file line # link appears in */
  18812. X   } LINK;
  18813. X
  18814. X
  18815. Xtypedef struct
  18816. X   {
  18817. X   unsigned offset;     /* offset from start of topic text */
  18818. X   unsigned length;     /* length of page (in chars) */
  18819. X   int        margin;     /* if > 0 then page starts in_para and text */
  18820. X                /* should be indented by this much */
  18821. X   } PAGE;
  18822. X
  18823. X
  18824. X/* values for TOPIC.flags */
  18825. X
  18826. X#define TF_IN_DOC  (1)         /* 1 if topic is part of the printed document */
  18827. X#define TF_DATA    (2)         /* 1 if it is a "data" topic */
  18828. X
  18829. X
  18830. Xtypedef struct
  18831. X   {
  18832. X   unsigned  flags;         /* see #defines for TF_??? */
  18833. X   int         doc_page;         /* page number in document where topic starts */
  18834. X   unsigned  title_len;      /* length of title */
  18835. X   char     *title;         /* title for this topic */
  18836. X   int         num_page;         /* number of pages */
  18837. X   PAGE     *page;         /* list of pages */
  18838. X   unsigned  text_len;         /* lenth of topic text */
  18839. X   long      text;         /* topic text (all pages) */
  18840. X   long      offset;         /* offset to topic from start of file */
  18841. X   } TOPIC;
  18842. X
  18843. X
  18844. Xtypedef struct
  18845. X   {
  18846. X   char    *name;         /* its name */
  18847. X   int        topic_num;         /* topic number */
  18848. X   unsigned topic_off;         /* offset of label in the topic's text */
  18849. X   int        doc_page;
  18850. X   } LABEL;
  18851. X
  18852. X
  18853. X/* values for CONTENT.flags */
  18854. X
  18855. X#define CF_NEW_PAGE  (1)     /* true if section starts on a new page */
  18856. X
  18857. X
  18858. X#define MAX_CONTENT_TOPIC (10)
  18859. X
  18860. X
  18861. Xtypedef struct
  18862. X   {
  18863. X   unsigned  flags;
  18864. X   char     *id;
  18865. X   char     *name;
  18866. X   int         doc_page;
  18867. X   unsigned  page_num_pos;
  18868. X   int         num_topic;
  18869. X   char      is_label[MAX_CONTENT_TOPIC];
  18870. X   char     *topic_name[MAX_CONTENT_TOPIC];
  18871. X   int         topic_num[MAX_CONTENT_TOPIC];
  18872. X   char     *srcfile;
  18873. X   int         srcline;
  18874. X   } CONTENT;
  18875. X
  18876. X
  18877. Xstruct help_sig_info
  18878. X   {
  18879. X   unsigned long sig;
  18880. X   int         version;
  18881. X   unsigned long base;
  18882. X   } ;
  18883. X
  18884. X
  18885. Xint     num_topic      = 0;      /* topics */
  18886. XTOPIC   *topic;
  18887. X
  18888. Xint     num_label      = 0;      /* labels */
  18889. XLABEL   *label;
  18890. X
  18891. Xint     num_plabel      = 0;      /* private labels */
  18892. XLABEL   *plabel;
  18893. X
  18894. Xint     num_link      = 0;      /* all links */
  18895. XLINK    *a_link          = 0;
  18896. X
  18897. Xint     num_contents      = 0;      /* the table-of-contents */
  18898. XCONTENT *contents;
  18899. X
  18900. Xint     quiet_mode      = 0;      /* true if "/Q" option used */
  18901. X
  18902. Xint     max_pages      = 0;      /* max. pages in any topic */
  18903. Xint     max_links      = 0;      /* max. links on any page */
  18904. Xint     num_doc_pages      = 0;      /* total number of pages in document */
  18905. X
  18906. XFILE    *srcfile;          /* .SRC file */
  18907. Xint     srcline      = 0;      /* .SRC line number (used for errors) */
  18908. Xint     srccol       = 0;      /* .SRC column. */
  18909. X
  18910. Xint     version      = -1;   /* help file version */
  18911. X
  18912. Xint     errors       = 0,      /* number of errors reported */
  18913. X     warnings      = 0;      /* number of warnings reported */
  18914. X
  18915. Xchar     src_fname[81]      = "";   /* command-line .SRC filename */
  18916. Xchar     hdr_fname[81]      = "";   /* .H filename */
  18917. Xchar     hlp_fname[81]      = "";   /* .HLP filename */
  18918. Xchar    *src_cfname      = NULL; /* current .SRC filename */
  18919. X
  18920. Xint     format_exclude   = 0;      /* disable formatting at this col, 0 to */
  18921. X                  /*    never disable formatting */
  18922. XFILE    *swapfile;
  18923. Xlong     swappos;
  18924. X
  18925. Xchar    *buffer;          /* alloc'ed as BUFFER_SIZE bytes */
  18926. Xchar    *curr;              /* current position in the buffer */
  18927. Xchar     cmd[128];          /* holds the current command */
  18928. Xint     compress_spaces;
  18929. Xint     xonline;
  18930. Xint     xdoc;
  18931. X
  18932. X#define  MAX_INCLUDE_STACK (5)      /* allow 5 nested includes */
  18933. X
  18934. Xstruct
  18935. X   {
  18936. X   char *fname;
  18937. X   FILE *file;
  18938. X   int     line;
  18939. X   int     col;
  18940. X   } include_stack[MAX_INCLUDE_STACK];
  18941. Xint include_stack_top = -1;
  18942. X
  18943. X
  18944. X#define CHK_BUFFER(off) { if ((unsigned)(curr+(off)) - (unsigned)buffer >= (BUFFER_SIZE-1024)) fatal(0,"Buffer overflowed -- Help topic too large."); }
  18945. X
  18946. X#ifdef __WATCOMC__
  18947. X#define putw( x1, x2 )  fprintf( x2, "%c%c", x1&0xFF, x1>>8 );
  18948. X#endif
  18949. X
  18950. X#ifdef XFRACT
  18951. X#define putw( x1, x2 )  fwrite( &(x1), 1, sizeof(int), x2);
  18952. X#endif
  18953. X
  18954. X/*
  18955. X * error/warning/message reporting functions.
  18956. X */
  18957. X
  18958. X
  18959. Xvoid report_errors(void)
  18960. X   {
  18961. X   printf("\n");
  18962. X   printf("Compiler Status:\n");
  18963. X   printf("%8d Error%c\n",     errors,   (errors==1)     ? ' ' : 's');
  18964. X   printf("%8d Warning%c\n",     warnings, (warnings==1) ? ' ' : 's');
  18965. X   }
  18966. X
  18967. X
  18968. Xvoid print_msg(char *type, int lnum, char *format, va_list arg)
  18969. X   {
  18970. X   if (type != NULL)
  18971. X      {
  18972. X      printf("   %s", type);
  18973. X      if (lnum>0)
  18974. X     printf(" %s %d", src_cfname, lnum);
  18975. X      printf(": ");
  18976. X      }
  18977. X   vprintf(format, arg);
  18978. X   printf("\n");
  18979. X   }
  18980. X
  18981. X
  18982. X#ifndef XFRACT
  18983. Xvoid fatal(int diff, char *format, ...)
  18984. X#else
  18985. Xvoid fatal(va_alist)
  18986. X    va_dcl
  18987. X#endif
  18988. X   {
  18989. X   va_list arg;
  18990. X
  18991. X#ifndef XFRACT
  18992. X   va_start(arg, format);
  18993. X#else
  18994. X   int diff;
  18995. X   char *format;
  18996. X   va_start(arg);
  18997. X   diff = va_arg(arg,int);
  18998. X   format = va_arg(arg,char *);
  18999. X#endif
  19000. X
  19001. X   print_msg("Fatal", srcline-diff, format, arg);
  19002. X   va_end(arg);
  19003. X
  19004. X   if ( errors || warnings )
  19005. X      report_errors();
  19006. X
  19007. X   exit( errors + 1 );
  19008. X   }
  19009. X
  19010. X
  19011. X#ifndef XFRACT
  19012. Xvoid error(int diff, char *format, ...)
  19013. X#else
  19014. Xvoid error(va_alist)
  19015. X    va_dcl
  19016. X#endif
  19017. X   {
  19018. X   va_list arg;
  19019. X
  19020. X#ifndef XFRACT
  19021. X   va_start(arg, format);
  19022. X#else
  19023. X   int diff;
  19024. X   char *format;
  19025. X   va_start(arg);
  19026. X   diff = va_arg(arg,int);
  19027. X   format = va_arg(arg,char *);
  19028. X#endif
  19029. X   print_msg("Error", srcline-diff, format, arg);
  19030. X   va_end(arg);
  19031. X
  19032. X   if (++errors >= MAX_ERRORS && MAX_ERRORS > 0)
  19033. X      fatal(0,"Too many errors!");
  19034. X   }
  19035. X
  19036. X
  19037. X#ifndef XFRACT
  19038. Xvoid warn(int diff, char *format, ...)
  19039. X#else
  19040. Xvoid warn(va_alist)
  19041. X   va_dcl
  19042. X#endif
  19043. X   {
  19044. X   va_list arg;
  19045. X#ifndef XFRACT
  19046. X   va_start(arg, format);
  19047. X#else
  19048. X   int diff;
  19049. X   char *format;
  19050. X   va_start(arg);
  19051. X   diff = va_arg(arg, int);
  19052. X   format = va_arg(arg, char *);
  19053. X#endif
  19054. X   print_msg("Warning", srcline-diff, format, arg);
  19055. X   va_end(arg);
  19056. X
  19057. X   if (++warnings >= MAX_WARNINGS && MAX_WARNINGS > 0)
  19058. X      fatal(0,"Too many warnings!");
  19059. X   }
  19060. X
  19061. X
  19062. X#ifndef XFRACT
  19063. Xvoid notice(char *format, ...)
  19064. X#else
  19065. Xvoid notice(va_alist)
  19066. X    va_dcl
  19067. X#endif
  19068. X   {
  19069. X   va_list arg;
  19070. X#ifndef XFRACT
  19071. X   va_start(arg, format);
  19072. X#else
  19073. X   char *format;
  19074. X
  19075. X   va_start(arg);
  19076. X   format = va_arg(arg,char *);
  19077. X#endif
  19078. X   print_msg("Note", srcline, format, arg);
  19079. X   va_end(arg);
  19080. X   }
  19081. X
  19082. X
  19083. X#ifndef XFRACT
  19084. Xvoid msg(char *format, ...)
  19085. X#else
  19086. Xvoid msg(va_alist)
  19087. Xva_dcl
  19088. X#endif
  19089. X   {
  19090. X   va_list arg;
  19091. X#ifdef XFRACT
  19092. X   char *format;
  19093. X#endif
  19094. X
  19095. X   if (quiet_mode)
  19096. X      return;
  19097. X#ifndef XFRACT
  19098. X   va_start(arg, format);
  19099. X#else
  19100. X   va_start(arg);
  19101. X   format = va_arg(arg,char *);
  19102. X#endif
  19103. X   print_msg(NULL, 0, format, arg);
  19104. X   va_end(arg);
  19105. X   }
  19106. X
  19107. X
  19108. X#ifdef SHOW_ERROR_LINE
  19109. X#   define fatal  (printf("[%04d] ", __LINE__), fatal)
  19110. X#   define error  (printf("[%04d] ", __LINE__), error)
  19111. X#   define warn   (printf("[%04d] ", __LINE__), warn)
  19112. X#   define notice (printf("[%04d] ", __LINE__), notice)
  19113. X#   define msg      (printf((quiet_mode)?"":"[%04d] ", __LINE__), msg)
  19114. X#endif
  19115. X
  19116. X
  19117. X/*
  19118. X * store-topic-text-to-disk stuff.
  19119. X */
  19120. X
  19121. X
  19122. Xvoid alloc_topic_text(TOPIC *t, unsigned size)
  19123. X   {
  19124. X   t->text_len = size;
  19125. X   t->text = swappos;
  19126. X   swappos += size;
  19127. X   fseek(swapfile, t->text, SEEK_SET);
  19128. X   fwrite(buffer, 1, t->text_len, swapfile);
  19129. X   }
  19130. X
  19131. X
  19132. Xchar *get_topic_text(TOPIC *t)
  19133. X   {
  19134. X   fseek(swapfile, t->text, SEEK_SET);
  19135. X   fread(buffer, 1, t->text_len, swapfile);
  19136. X   return (buffer);
  19137. X   }
  19138. X
  19139. X
  19140. Xvoid release_topic_text(TOPIC *t, int save)
  19141. X   {
  19142. X   if ( save )
  19143. X      {
  19144. X      fseek(swapfile, t->text, SEEK_SET);
  19145. X      fwrite(buffer, 1, t->text_len, swapfile);
  19146. X      }
  19147. X   }
  19148. X
  19149. X
  19150. X/*
  19151. X * memory-allocation functions.
  19152. X */
  19153. X
  19154. X
  19155. X#define new(item)    (item *)newx(sizeof(item))
  19156. X#define delete(item) free(item)
  19157. X
  19158. X
  19159. XVOIDPTR newx(unsigned size)
  19160. X   {
  19161. X   VOIDPTR ptr;
  19162. X
  19163. X   ptr = malloc(size);
  19164. X
  19165. X   if (ptr == NULL)
  19166. X      fatal(0,"Out of memory!");
  19167. X
  19168. X   return (ptr);
  19169. X   }
  19170. X
  19171. X
  19172. XVOIDPTR renewx(VOIDPTR ptr, unsigned size)
  19173. X   {
  19174. X   ptr = realloc(ptr, size);
  19175. X
  19176. X   if (ptr == NULL)
  19177. X      fatal(0,"Out of memory!");
  19178. X
  19179. X   return (ptr);
  19180. X   }
  19181. X
  19182. X
  19183. Xchar *dupstr(char *s, unsigned len)
  19184. X   {
  19185. X   char *ptr;
  19186. X
  19187. X   if (len == 0)
  19188. X      len = strlen(s) + 1;
  19189. X
  19190. X   ptr = newx(len);
  19191. X
  19192. X   memcpy(ptr, s, len);
  19193. X
  19194. X   return (ptr);
  19195. X   }
  19196. X
  19197. X
  19198. X#define LINK_ALLOC_SIZE (16)
  19199. X
  19200. X
  19201. Xint add_link(LINK *l)
  19202. X   {
  19203. X   if (num_link == 0)
  19204. X      a_link = newx( sizeof(LINK)*LINK_ALLOC_SIZE );
  19205. X
  19206. X   else if (num_link%LINK_ALLOC_SIZE == 0)
  19207. X      a_link = renewx(a_link, sizeof(LINK) * (num_link+LINK_ALLOC_SIZE) );
  19208. X
  19209. X   a_link[num_link] = *l;
  19210. X
  19211. X   return( num_link++ );
  19212. X   }
  19213. X
  19214. X
  19215. X#define PAGE_ALLOC_SIZE (4)
  19216. X
  19217. X
  19218. Xint add_page(TOPIC *t, PAGE *p)
  19219. X   {
  19220. X   if (t->num_page == 0)
  19221. X      t->page = newx( sizeof(PAGE)*PAGE_ALLOC_SIZE );
  19222. X
  19223. X   else if (t->num_page%PAGE_ALLOC_SIZE == 0)
  19224. X      t->page = renewx(t->page, sizeof(PAGE) * (t->num_page+PAGE_ALLOC_SIZE) );
  19225. X
  19226. X   t->page[t->num_page] = *p;
  19227. X
  19228. X   return ( t->num_page++ );
  19229. X   }
  19230. X
  19231. X
  19232. X#define TOPIC_ALLOC_SIZE (16)
  19233. X
  19234. X
  19235. Xint add_topic(TOPIC *t)
  19236. X   {
  19237. X   if (num_topic == 0)
  19238. X      topic = newx( sizeof(TOPIC)*TOPIC_ALLOC_SIZE );
  19239. X
  19240. X   else if (num_topic%TOPIC_ALLOC_SIZE == 0)
  19241. X      topic = renewx(topic, sizeof(TOPIC) * (num_topic+TOPIC_ALLOC_SIZE) );
  19242. X
  19243. X   topic[num_topic] = *t;
  19244. X
  19245. X   return ( num_topic++ );
  19246. X   }
  19247. X
  19248. X
  19249. X#define LABEL_ALLOC_SIZE (16)
  19250. X
  19251. X
  19252. Xint add_label(LABEL *l)
  19253. X   {
  19254. X   if (l->name[0] == '@')    /* if it's a private label... */
  19255. X      {
  19256. X      if (num_plabel == 0)
  19257. X     plabel = newx( sizeof(LABEL)*LABEL_ALLOC_SIZE );
  19258. X
  19259. X      else if (num_plabel%LABEL_ALLOC_SIZE == 0)
  19260. X     plabel = renewx(plabel, sizeof(LABEL) * (num_plabel+LABEL_ALLOC_SIZE) );
  19261. X
  19262. X      plabel[num_plabel] = *l;
  19263. X
  19264. X      return ( num_plabel++ );
  19265. X      }
  19266. X   else
  19267. X      {
  19268. X      if (num_label == 0)
  19269. X     label = newx( sizeof(LABEL)*LABEL_ALLOC_SIZE );
  19270. X
  19271. X      else if (num_label%LABEL_ALLOC_SIZE == 0)
  19272. X     label = renewx(label, sizeof(LABEL) * (num_label+LABEL_ALLOC_SIZE) );
  19273. X
  19274. X      label[num_label] = *l;
  19275. X
  19276. X      return ( num_label++ );
  19277. X      }
  19278. X   }
  19279. X
  19280. X
  19281. X#define CONTENTS_ALLOC_SIZE (16)
  19282. X
  19283. X
  19284. Xint add_content(CONTENT *c)
  19285. X   {
  19286. X   if (num_contents == 0)
  19287. X      contents = newx( sizeof(CONTENT)*CONTENTS_ALLOC_SIZE );
  19288. X
  19289. X   else if (num_contents%CONTENTS_ALLOC_SIZE == 0)
  19290. X      contents = renewx(contents, sizeof(CONTENT) * (num_contents+CONTENTS_ALLOC_SIZE) );
  19291. X
  19292. X   contents[num_contents] = *c;
  19293. X
  19294. X   return ( num_contents++ );
  19295. X   }
  19296. X
  19297. X
  19298. X/*
  19299. X * read_char() stuff
  19300. X */
  19301. X
  19302. X
  19303. X#define READ_CHAR_BUFF_SIZE (32)
  19304. X
  19305. X
  19306. Xint  read_char_buff[READ_CHAR_BUFF_SIZE];
  19307. Xint  read_char_buff_pos = -1;
  19308. Xint  read_char_sp       = 0;
  19309. X
  19310. X
  19311. Xvoid unread_char(int ch)
  19312. X   /*
  19313. X    * Will not handle new-lines or tabs correctly!
  19314. X    */
  19315. X   {
  19316. X   if (read_char_buff_pos+1 >= READ_CHAR_BUFF_SIZE)
  19317. X      fatal(0,"Compiler Error -- Read char buffer overflow!");
  19318. X
  19319. X   read_char_buff[++read_char_buff_pos] = ch;
  19320. X
  19321. X   --srccol;
  19322. X   }
  19323. X
  19324. X
  19325. Xvoid unread_string(char *s)
  19326. X   {
  19327. X   int p = strlen(s);
  19328. X
  19329. X   while (p-- > 0)
  19330. X      unread_char(s[p]);
  19331. X   }
  19332. X
  19333. X
  19334. Xint eos(void)     /* end-of-source ? */
  19335. X   {
  19336. X   return ( !((read_char_sp==0) && (read_char_buff_pos==0) && feof(srcfile)) );
  19337. X   }
  19338. X
  19339. X
  19340. Xint _read_char(void)
  19341. X   {
  19342. X   int ch;
  19343. X
  19344. X   if (srcline <= 0)
  19345. X      {
  19346. X      srcline = 1;
  19347. X      srccol = 0;
  19348. X      }
  19349. X
  19350. X   if (read_char_buff_pos >= 0)
  19351. X      {
  19352. X      ++srccol;
  19353. X      return ( read_char_buff[read_char_buff_pos--] );
  19354. X      }
  19355. X
  19356. X   if (read_char_sp > 0)
  19357. X      {
  19358. X      --read_char_sp;
  19359. X      return (' ');
  19360. X      }
  19361. X
  19362. X   if ( feof(srcfile) )
  19363. X      return (-1);
  19364. X
  19365. X   while (1)
  19366. X      {
  19367. X      ch = getc(srcfile);
  19368. X
  19369. X      switch (ch)
  19370. X     {
  19371. X     case '\t':    /* expand a tab */
  19372. X        {
  19373. X        int diff = ( ( (srccol/8) + 1 ) * 8 ) - srccol;
  19374. X
  19375. X        srccol += diff;
  19376. X        read_char_sp += diff;
  19377. X        break;
  19378. X        }
  19379. X
  19380. X     case ' ':
  19381. X        ++srccol;
  19382. X        ++read_char_sp;
  19383. X        break;
  19384. X
  19385. X     case '\n':
  19386. X        read_char_sp = 0;   /* delete spaces before a \n */
  19387. X        srccol = 0;
  19388. X        ++srcline;
  19389. X        return ('\n');
  19390. X
  19391. X     case -1:            /* EOF */
  19392. X        if (read_char_sp > 0)
  19393. X           {
  19394. X           --read_char_sp;
  19395. X           return (' ');
  19396. X           }
  19397. X        return (-1);
  19398. X
  19399. X     default:
  19400. X        if (read_char_sp > 0)
  19401. X           {
  19402. X           ungetc(ch, srcfile);
  19403. X           --read_char_sp;
  19404. X           return (' ');
  19405. X           }
  19406. X
  19407. X        ++srccol;
  19408. X        return (ch);
  19409. X
  19410. X     } /* switch */
  19411. X      }
  19412. X   }
  19413. X
  19414. X
  19415. Xint read_char(void)
  19416. X   {
  19417. X   int ch;
  19418. X
  19419. X   ch = _read_char();
  19420. X
  19421. X   while (ch == ';' && srccol==1)    /* skip over comments */
  19422. X      {
  19423. X      ch = _read_char();
  19424. X
  19425. X      while (ch!='\n' && ch!=-1 )
  19426. X     ch = _read_char();
  19427. X
  19428. X      ch = _read_char();
  19429. X      }
  19430. X
  19431. X   if (ch == '\\')   /* process an escape code */
  19432. X      {
  19433. X      ch = _read_char();
  19434. X
  19435. X      if (ch >= '0' && ch <= '9')
  19436. X     {
  19437. X     char buff[4];
  19438. X     int  ctr;
  19439. X
  19440. X     for (ctr=0; ; ctr++)
  19441. X        {
  19442. X        if ( ch<'0' || ch>'9' || ch==-1 || ctr>=3 )
  19443. X           {
  19444. X           unread_char(ch);
  19445. X           break;
  19446. X           }
  19447. X        buff[ctr] = ch;
  19448. X        ch = _read_char();
  19449. X        }
  19450. X     buff[ctr] = '\0';
  19451. X     ch = atoi(buff);
  19452. X     }
  19453. X
  19454. X#ifdef XFRACT
  19455. X   /* Convert graphics arrows into keyboard chars */
  19456. X       if (ch>=24 && ch<=27) {
  19457. X       ch = "KJHL"[ch-24];
  19458. X       }
  19459. X#endif
  19460. X      ch |= 0x100;
  19461. X      }
  19462. X
  19463. X   if ( (ch & 0xFF) == 0 )
  19464. X      {
  19465. X      error(0,"Null character (\'\\0\') not allowed!");
  19466. X      ch = 0x1FF; /* since we've had an error the file will not be written; */
  19467. X          /*   the value we return doesn't really matter */
  19468. X      }
  19469. X
  19470. X   return(ch);
  19471. X   }
  19472. X
  19473. X
  19474. X/*
  19475. X * misc. search functions.
  19476. X */
  19477. X
  19478. X
  19479. XLABEL *find_label(char *name)
  19480. X   {
  19481. X   int      l;
  19482. X   LABEL *lp;
  19483. X
  19484. X   if (*name == '@')
  19485. X      {
  19486. X      for (l=0, lp=plabel; l<num_plabel; l++, lp++)
  19487. X     if ( strcmp(name, lp->name) == 0 )
  19488. X        return (lp);
  19489. X      }
  19490. X   else
  19491. X      {
  19492. X      for (l=0, lp=label; l<num_label; l++, lp++)
  19493. X     if ( strcmp(name, lp->name) == 0 )
  19494. X        return (lp);
  19495. X      }
  19496. X
  19497. X   return (NULL);
  19498. X   }
  19499. X
  19500. X
  19501. Xint find_topic_title(char *title)
  19502. X   {
  19503. X   int t;
  19504. X   int len;
  19505. X
  19506. X   while (*title == ' ')
  19507. X      ++title;
  19508. X
  19509. X   len = strlen(title) - 1;
  19510. X   while ( title[len] == ' ' && len > 0 )
  19511. X      --len;
  19512. X
  19513. X   ++len;
  19514. X
  19515. X   if ( len > 2 && title[0] == '\"' && title[len-1] == '\"' )
  19516. X      {
  19517. X      ++title;
  19518. X      len -= 2;
  19519. X      }
  19520. X
  19521. X   for (t=0; t<num_topic; t++)
  19522. X      if ( strlen(topic[t].title) == len &&
  19523. X       strnicmp(title, topic[t].title, len) == 0 )
  19524. X     return (t);
  19525. X
  19526. X   return (-1);   /* not found */
  19527. X   }
  19528. X
  19529. X
  19530. X/*
  19531. X * .SRC file parser stuff
  19532. X */
  19533. X
  19534. X
  19535. Xint validate_label_name(char *name)
  19536. X   {
  19537. X   if ( !isalpha(*name) && *name!='@' && *name!='_' )
  19538. X      return (0);  /* invalid */
  19539. X
  19540. X   while (*(++name) != '\0')
  19541. X      if ( !isalpha(*name) && !isdigit(*name) && *name!='_' )
  19542. X     return(0);  /* invalid */
  19543. X
  19544. X   return (1);  /* valid */
  19545. X   }
  19546. X
  19547. X
  19548. Xchar *read_until(char *buff, int len, char *stop_chars)
  19549. X   {
  19550. X   int ch;
  19551. X
  19552. X   while ( --len > 0 )
  19553. X      {
  19554. X      ch = read_char();
  19555. X
  19556. X      if ( ch == -1 )
  19557. X     {
  19558. X     *buff++ = '\0';
  19559. X     break;
  19560. X     }
  19561. X
  19562. X      if ( (ch&0xFF) <= MAX_CMD )
  19563. X     *buff++ = CMD_LITERAL;
  19564. X
  19565. X      *buff++ = ch;
  19566. X
  19567. X      if ( (ch&0x100)==0 && strchr(stop_chars, ch) != NULL )
  19568. X     break;
  19569. X      }
  19570. X
  19571. X   return ( buff-1 );
  19572. X   }
  19573. X
  19574. X
  19575. Xvoid skip_over(char *skip)
  19576. X   {
  19577. X   int ch;
  19578. X
  19579. X   while (1)
  19580. X      {
  19581. X      ch = read_char();
  19582. X
  19583. X      if ( ch == -1 )
  19584. X     break;
  19585. X
  19586. X      else if ( (ch&0x100) == 0 && strchr(skip, ch) == NULL )
  19587. X     {
  19588. X     unread_char(ch);
  19589. X     break;
  19590. X     }
  19591. X      }
  19592. X   }
  19593. X
  19594. X
  19595. Xchar *pchar(int ch)
  19596. X   {
  19597. X   static char buff[16];
  19598. X
  19599. X   if ( ch >= 0x20 && ch <= 0x7E )
  19600. X      sprintf(buff, "\'%c\'", ch);
  19601. X   else
  19602. X      sprintf(buff, "\'\\x%02X\'", ch&0xFF);
  19603. X
  19604. X   return (buff);
  19605. X   }
  19606. X
  19607. X
  19608. Xvoid put_spaces(int how_many)
  19609. X   {
  19610. X   if (how_many > 2 && compress_spaces)
  19611. X      {
  19612. X      if (how_many > 255)
  19613. X     {
  19614. X     error(0,"Too many spaces (over 255).");
  19615. X     how_many = 255;
  19616. X     }
  19617. X
  19618. X      *curr++ = CMD_SPACE;
  19619. X      *curr++ = (BYTE)how_many;
  19620. X      }
  19621. X   else
  19622. X      {
  19623. X      while (how_many-- > 0)
  19624. X     *curr++ = ' ';
  19625. X      }
  19626. X   }
  19627. X
  19628. X
  19629. Xint get_next_item(void)   /* used by parse_contents() */
  19630. X   {
  19631. X   int     last;
  19632. X   char *ptr;
  19633. X
  19634. X   skip_over(" \t\n");
  19635. X   ptr = read_until(cmd, 128, ",}");
  19636. X   last = (*ptr == '}');
  19637. X   --ptr;
  19638. X   while ( ptr >= cmd && strchr(" \t\n",*ptr) )   /* strip trailing spaces */
  19639. X      --ptr;
  19640. X   *(++ptr) = '\0';
  19641. X
  19642. X   return (last);
  19643. X   }
  19644. X
  19645. X
  19646. Xvoid process_contents(void)
  19647. X   {
  19648. X   CONTENT c;
  19649. X   char   *ptr;
  19650. X   int       indent;
  19651. X   int       ch;
  19652. X   TOPIC   t;
  19653. X
  19654. X   t.flags     = 0;
  19655. X   t.title_len = strlen(DOCCONTENTS_TITLE)+1;
  19656. X   t.title     = dupstr(DOCCONTENTS_TITLE, t.title_len);
  19657. X   t.doc_page  = -1;
  19658. X   t.num_page  = 0;
  19659. X
  19660. X   curr = buffer;
  19661. X
  19662. X   c.flags = 0;
  19663. X   c.id = dupstr("",1);
  19664. X   c.name = dupstr("",1);
  19665. X   c.doc_page = -1;
  19666. X   c.page_num_pos = 0;
  19667. X   c.num_topic = 1;
  19668. X   c.is_label[0] = 0;
  19669. X   c.topic_name[0] = dupstr(DOCCONTENTS_TITLE,0);
  19670. X   c.srcline = -1;
  19671. X   add_content(&c);
  19672. X
  19673. X   while (1)
  19674. X      {
  19675. X      ch = read_char();
  19676. X
  19677. X      if (ch == '{')   /* process a CONTENT entry */
  19678. X     {
  19679. X     int last;
  19680. X
  19681. X     c.flags = 0;
  19682. X     c.num_topic = 0;
  19683. X     c.doc_page = -1;
  19684. X     c.srcfile = src_cfname;
  19685. X     c.srcline = srcline;
  19686. X
  19687. X     if ( get_next_item() )
  19688. X        {
  19689. X        error(0,"Unexpected end of DocContent entry.");
  19690. X        continue;
  19691. X        }
  19692. X     c.id = dupstr(cmd,0);
  19693. X
  19694. X     if ( get_next_item() )
  19695. X        {
  19696. X        error(0,"Unexpected end of DocContent entry.");
  19697. X        continue;
  19698. X        }
  19699. X     indent = atoi(cmd);
  19700. X
  19701. X     last = get_next_item();
  19702. X
  19703. X     if ( cmd[0] == '\"' )
  19704. X        {
  19705. X        ptr = cmd+1;
  19706. X        if (ptr[strlen(ptr)-1] == '\"')
  19707. X           ptr[strlen(ptr)-1] = '\0';
  19708. X        else
  19709. X           warn(0,"Missing ending quote.");
  19710. X
  19711. X        c.is_label[c.num_topic] = 0;
  19712. X        c.topic_name[c.num_topic] = dupstr(ptr,0);
  19713. X        ++c.num_topic;
  19714. X        c.name = dupstr(ptr,0);
  19715. X        }
  19716. X     else
  19717. X        c.name = dupstr(cmd,0);
  19718. X
  19719. X     /* now, make the entry in the buffer */
  19720. X
  19721. X     sprintf(curr, "%-5s %*.0s%s", c.id, indent*2, "", c.name);
  19722. X     ptr = curr + strlen(curr);
  19723. X     while ( (ptr-curr) < PAGE_WIDTH-10 )
  19724. X        *ptr++ = '.';
  19725. X     c.page_num_pos = (unsigned) ( (ptr-3) - buffer );
  19726. X     curr = ptr;
  19727. X
  19728. X     while (!last)
  19729. X        {
  19730. X        last = get_next_item();
  19731. X
  19732. X        if ( stricmp(cmd, "FF") == 0 )
  19733. X           {
  19734. X           if ( c.flags & CF_NEW_PAGE )
  19735. X          warn(0,"FF already present in this entry.");
  19736. X           c.flags |= CF_NEW_PAGE;
  19737. X           continue;
  19738. X           }
  19739. X
  19740. X        if (cmd[0] == '\"')
  19741. X           {
  19742. X           ptr = cmd+1;
  19743. X           if (ptr[strlen(ptr)-1] == '\"')
  19744. X          ptr[strlen(ptr)-1] = '\0';
  19745. X           else
  19746. X          warn(0,"Missing ending quote.");
  19747. X
  19748. X           c.is_label[c.num_topic] = 0;
  19749. X           c.topic_name[c.num_topic] = dupstr(ptr,0);
  19750. X           }
  19751. X        else
  19752. X           {
  19753. X           c.is_label[c.num_topic] = 1;
  19754. X           c.topic_name[c.num_topic] = dupstr(cmd,0);
  19755. X           }
  19756. X
  19757. X        if ( ++c.num_topic >= MAX_CONTENT_TOPIC )
  19758. X           {
  19759. X           error(0,"Too many topics in DocContent entry.");
  19760. X           break;
  19761. X           }
  19762. X        }
  19763. X
  19764. X     add_content(&c);
  19765. X     }
  19766. X
  19767. X      else if (ch == '~')   /* end at any command */
  19768. X     {
  19769. X     unread_char(ch);
  19770. X     break;
  19771. X     }
  19772. X
  19773. X      else
  19774. X     *curr++ = ch;
  19775. X
  19776. X      CHK_BUFFER(0);
  19777. X      }
  19778. X
  19779. X   alloc_topic_text(&t, (unsigned) (curr - buffer) );
  19780. X   add_topic(&t);
  19781. X   }
  19782. X
  19783. X
  19784. Xint parse_link(void)   /* returns length of link or 0 on error */
  19785. X   {
  19786. X   char *ptr;
  19787. X   char *end;
  19788. X   int     bad = 0;
  19789. X   int     len;
  19790. X   LINK  l;
  19791. X   int     lnum;
  19792. X   int     err_off;
  19793. X
  19794. X   l.srcfile  = src_cfname;
  19795. X   l.srcline  = srcline;
  19796. X   l.doc_page = -1;
  19797. X
  19798. X   end = read_until(cmd, 128, "}\n");   /* get the entire hot-link */
  19799. X
  19800. X   if (*end == '\0')
  19801. X      {
  19802. X      error(0,"Unexpected EOF in hot-link.");
  19803. X      return (0);
  19804. X      }
  19805. X
  19806. X   if (*end == '\n')
  19807. X      {
  19808. X      err_off = 1;
  19809. X      warn(1,"Hot-link has no closing curly-brace (\'}\').");
  19810. X      }
  19811. X   else
  19812. X      err_off = 0;
  19813. X
  19814. X   *end = '\0';
  19815. X
  19816. X   if (cmd[0] == '=')   /* it's an "explicit" link to a label or "special" */
  19817. X      {
  19818. X      ptr = strchr(cmd, ' ');
  19819. X
  19820. X      if (ptr == NULL)
  19821. X     ptr = end;
  19822. X      else
  19823. X     *ptr++ = '\0';
  19824. X
  19825. X      len = (int) (end - ptr);
  19826. X
  19827. X      if ( cmd[1] == '-' )
  19828. X     {
  19829. X     l.type      = 2;       /* type 2 = "special" */
  19830. X     l.topic_num = atoi(cmd+1);
  19831. X     l.topic_off = 0;
  19832. X     l.name      = NULL;
  19833. X     }
  19834. X      else
  19835. X     {
  19836. X     l.type = 1;           /* type 1 = to a label */
  19837. X     if (strlen(cmd) > 32)
  19838. X        warn(err_off, "Label is long.");
  19839. X     if (cmd[1] == '\0')
  19840. X        {
  19841. X        error(err_off, "Explicit hot-link has no Label.");
  19842. X        bad = 1;
  19843. X        }
  19844. X     else
  19845. X        l.name = dupstr(cmd+1,0);
  19846. X     }
  19847. X      if (len == 0)
  19848. X     warn(err_off, "Explicit hot-link has no title.");
  19849. X      }
  19850. X   else
  19851. X      {
  19852. X      ptr = cmd;
  19853. X      l.type = 0;   /* type 0 = topic title */
  19854. X      len = (int) (end - ptr);
  19855. X      if (len == 0)
  19856. X     {
  19857. X     error(err_off, "Implicit hot-link has no title.");
  19858. X     bad = 1;
  19859. X     }
  19860. X      l.name = dupstr(ptr,len+1);
  19861. X      l.name[len] = '\0';
  19862. X      }
  19863. X
  19864. X   if ( !bad )
  19865. X      {
  19866. X      CHK_BUFFER(1+3*sizeof(int)+len+1)
  19867. X      lnum = add_link(&l);
  19868. X      *curr++ = CMD_LINK;
  19869. X      setint(curr,lnum);
  19870. X      curr += 3*sizeof(int);
  19871. X      memcpy(curr, ptr, len);
  19872. X      curr += len;
  19873. X      *curr++ = CMD_LINK;
  19874. X      return (len);
  19875. X      }
  19876. X   else
  19877. X      return (0);
  19878. X   }
  19879. X
  19880. X
  19881. X#define MAX_TABLE_SIZE (100)
  19882. X
  19883. X
  19884. Xint create_table(void)
  19885. X   {
  19886. X   char  *ptr;
  19887. X   int      width;
  19888. X   int      cols;
  19889. X   int      start_off;
  19890. X   int      first_link;
  19891. X   int      rows;
  19892. X   int      r, c;
  19893. X   int      ch;
  19894. X   int      done;
  19895. X   int      len;
  19896. X   int      lnum;
  19897. X   int      count;
  19898. X   char  *title[MAX_TABLE_SIZE];
  19899. X   char  *table_start;
  19900. X
  19901. X   ptr = strchr(cmd, '=');
  19902. X
  19903. X   if (ptr == NULL)
  19904. X      return (0);   /* should never happen! */
  19905. X
  19906. X   ptr++;
  19907. X
  19908. X   len = sscanf(ptr, " %d %d %d", &width, &cols, &start_off);
  19909. X
  19910. X   if (len < 3)
  19911. X      {
  19912. X      error(1,"Too few arguments to Table.");
  19913. X      return (0);
  19914. X      }
  19915. X
  19916. X   if (width<=0 || width > 78 || cols<=0 || start_off<0 || start_off > 78)
  19917. X      {
  19918. X      error(1,"Argument out of range.");
  19919. X      return (0);
  19920. X      }
  19921. X
  19922. X   done = 0;
  19923. X
  19924. X   first_link = num_link;
  19925. X   table_start = curr;
  19926. X   count = 0;
  19927. X
  19928. X   /* first, read all the links in the table */
  19929. X
  19930. X   do
  19931. X      {
  19932. X
  19933. X      do
  19934. X     ch = read_char();
  19935. X      while ( ch=='\n' || ch == ' ' );
  19936. X
  19937. X      if (done)
  19938. X     break;
  19939. X
  19940. X      switch (ch)
  19941. X     {
  19942. X     case -1:
  19943. X        error(0,"Unexpected EOF in a Table.");
  19944. X        return(0);
  19945. X
  19946. X     case '{':
  19947. X        if (count >= MAX_TABLE_SIZE)
  19948. X           fatal(0,"Table is too large.");
  19949. X        len = parse_link();
  19950. X        curr = table_start;   /* reset to the start... */
  19951. X            title[count] = dupstr(curr+3*sizeof(int)+1, len+1);
  19952. X        if (len >= width)
  19953. X           {
  19954. X           warn(1,"Link is too long; truncating.");
  19955. X           len = width-1;
  19956. X           }
  19957. X        title[count][len] = '\0';
  19958. X        ++count;
  19959. X        break;
  19960. X
  19961. X     case '~':
  19962. X        {
  19963. X        int imbedded;
  19964. X
  19965. X        ch = read_char();
  19966. X
  19967. X        if (ch=='(')
  19968. X           imbedded = 1;
  19969. X        else
  19970. X           {
  19971. X           imbedded = 0;
  19972. X           unread_char(ch);
  19973. X           }
  19974. X
  19975. X        ptr = read_until(cmd, 128, ")\n,");
  19976. X
  19977. X        ch = *ptr;
  19978. X        *ptr = '\0';
  19979. X
  19980. X        if  ( stricmp(cmd, "EndTable") == 0 )
  19981. X           done = 1;
  19982. X        else
  19983. X           {
  19984. X           error(1,"Unexpected command in table \"%s\"", cmd);
  19985. X           warn(1,"Command will be ignored.");
  19986. X           }
  19987. X
  19988. X        if (ch == ',')
  19989. X           {
  19990. X           if (imbedded)
  19991. X          unread_char('(');
  19992. X           unread_char('~');
  19993. X           }
  19994. X        }
  19995. X        break;
  19996. X
  19997. X     default:
  19998. X        error(0,"Unexpected character %s.", pchar(ch));
  19999. X        break;
  20000. X     }
  20001. X      }
  20002. X   while (!done);
  20003. X
  20004. X   /* now, put all the links into the buffer... */
  20005. X
  20006. X   rows = 1 + ( count / cols );
  20007. X
  20008. X   for (r=0; r<rows; r++)
  20009. X      {
  20010. X      put_spaces(start_off);
  20011. X      for (c=0; c<cols; c++)
  20012. X     {
  20013. X     lnum = c*rows + r;
  20014. X
  20015. X     if ( first_link+lnum >= num_link )
  20016. X        break;
  20017. X
  20018. X     len = strlen(title[lnum]);
  20019. X     *curr++ = CMD_LINK;
  20020. X         setint(curr,first_link+lnum);
  20021. X         curr += 3*sizeof(int);
  20022. X     memcpy(curr, title[lnum], len);
  20023. X     curr += len;
  20024. X     *curr++ = CMD_LINK;
  20025. X
  20026. X     delete(title[lnum]);
  20027. X
  20028. X     if ( c < cols-1 )
  20029. X        put_spaces( width-len );
  20030. X     }
  20031. X      *curr++ = '\n';
  20032. X      }
  20033. X
  20034. X   return (1);
  20035. X   }
  20036. X
  20037. X
  20038. Xvoid process_comment(void)
  20039. X   {
  20040. X   int ch;
  20041. X
  20042. X   while ( 1 )
  20043. X      {
  20044. X      ch = read_char();
  20045. X
  20046. X      if (ch == '~')
  20047. X     {
  20048. X     int   imbedded;
  20049. X     char *ptr;
  20050. X
  20051. X     ch = read_char();
  20052. X
  20053. X     if (ch=='(')
  20054. X        imbedded = 1;
  20055. X     else
  20056. X        {
  20057. X        imbedded = 0;
  20058. X        unread_char(ch);
  20059. X        }
  20060. X
  20061. X     ptr = read_until(cmd, 128, ")\n,");
  20062. X
  20063. X     ch = *ptr;
  20064. X     *ptr = '\0';
  20065. X
  20066. X     if  ( stricmp(cmd, "EndComment") == 0 )
  20067. X        {
  20068. X        if (ch == ',')
  20069. X           {
  20070. X           if (imbedded)
  20071. X          unread_char('(');
  20072. X           unread_char('~');
  20073. X           }
  20074. X        break;
  20075. X        }
  20076. X     }
  20077. X
  20078. X      else if ( ch == -1 )
  20079. X     {
  20080. X     error(0,"Unexpected EOF in Comment");
  20081. X     break;
  20082. X     }
  20083. X      }
  20084. X   }
  20085. X
  20086. X
  20087. Xvoid process_bininc(void)
  20088. X   {
  20089. X   int  handle;
  20090. X   long len;
  20091. X
  20092. X   if ( (handle=open(cmd+7, O_RDONLY|O_BINARY)) == -1 )
  20093. X      {
  20094. X      error(0,"Unable to open \"%s\"", cmd+7);
  20095. X      return ;
  20096. X      }
  20097. X
  20098. X   len = filelength(handle);
  20099. X
  20100. X   if ( len >= BUFFER_SIZE )
  20101. X      {
  20102. X      error(0,"File \"%s\" is too large to BinInc (%dK).", cmd+7, (int)(len>>10));
  20103. X      close(handle);
  20104. X      return ;
  20105. X      }
  20106. X
  20107. X   /*
  20108. X    * Since we know len is less than BUFFER_SIZE (and therefore less then
  20109. X    * 64K) we can treat it as an unsigned.
  20110. X    */
  20111. X
  20112. X   CHK_BUFFER((unsigned)len);
  20113. X
  20114. X   read(handle, curr, (unsigned)len);
  20115. X
  20116. X   curr += (unsigned)len;
  20117. X
  20118. X   close(handle);
  20119. X   }
  20120. X
  20121. X
  20122. Xvoid start_topic(TOPIC *t, char *title, int title_len)
  20123. X   {
  20124. X   t->flags = 0;
  20125. X   t->title_len = title_len;
  20126. X   t->title = dupstr(title, title_len+1);
  20127. X   t->title[title_len] = '\0';
  20128. X   t->doc_page = -1;
  20129. X   t->num_page = 0;
  20130. X   curr = buffer;
  20131. X   }
  20132. X
  20133. X
  20134. Xvoid end_topic(TOPIC *t)
  20135. X   {
  20136. X   alloc_topic_text(t, (unsigned) (curr - buffer) );
  20137. X   add_topic(t);
  20138. X   }
  20139. X
  20140. X
  20141. Xint end_of_sentence(char *ptr)  /* true if ptr is at the end of a sentence */
  20142. X   {
  20143. X   if ( *ptr == ')')
  20144. X      --ptr;
  20145. X
  20146. X   if ( *ptr == '\"')
  20147. X      --ptr;
  20148. X
  20149. X   return ( *ptr=='.' || *ptr=='?' || *ptr=='!' );
  20150. X   }
  20151. X
  20152. X
  20153. Xvoid add_blank_for_split(void)     /* add space at curr for merging two lines */
  20154. X   {
  20155. X   if ( !is_hyphen(curr-1) )   /* no spaces if it's a hyphen */
  20156. X      {
  20157. X      if ( end_of_sentence(curr-1) )
  20158. X     *curr++ = ' ';  /* two spaces at end of a sentence */
  20159. X      *curr++ = ' ';
  20160. X      }
  20161. X   }
  20162. X
  20163. X
  20164. Xvoid put_a_char(int ch, TOPIC *t)
  20165. X   {
  20166. X   if (ch == '{' && !(t->flags & TF_DATA) )   /* is it a hot-link? */
  20167. X      parse_link();
  20168. X   else
  20169. X      {
  20170. X      if ( (ch&0xFF) <= MAX_CMD)
  20171. X     *curr++ = CMD_LITERAL;
  20172. X      *curr++ = ch;
  20173. X      }
  20174. X   }
  20175. X
  20176. X
  20177. Xenum STATES   /* states for FSM's */
  20178. X   {
  20179. X   S_Start,            /* initial state, between paragraphs       */
  20180. X   S_StartFirstLine,        /* spaces at start of first line           */
  20181. X   S_FirstLine,         /* text on the first line               */
  20182. X   S_FirstLineSpaces,        /* spaces on the first line            */
  20183. X   S_StartSecondLine,        /* spaces at start of second line           */
  20184. X   S_Line,            /* text on lines after the first           */
  20185. X   S_LineSpaces,        /* spaces on lines after the first           */
  20186. X   S_StartLine,         /* spaces at start of lines after second       */
  20187. X   S_FormatDisabled,        /* format automatically disabled for this line */
  20188. X   S_FormatDisabledSpaces,  /* spaces in line which format is disabled       */
  20189. X   S_Spaces
  20190. X   } ;
  20191. X
  20192. X
  20193. Xvoid check_command_length(int eoff, int len)
  20194. X   {
  20195. X   if (strlen(cmd) != len)
  20196. X      error(eoff, "Invalid text after a command \"%s\"", cmd+len);
  20197. X   }
  20198. X
  20199. X
  20200. Xvoid read_src(char *fname)
  20201. X   {
  20202. X   int      ch;
  20203. X   char  *ptr;
  20204. X   TOPIC  t;
  20205. X   LABEL  lbl;
  20206. X   char  *margin_pos = NULL;
  20207. X   int      in_topic   = 0,
  20208. X      formatting = 1,
  20209. X      state      = S_Start,
  20210. X      num_spaces = 0,
  20211. X      margin     = 0,
  20212. X      in_para    = 0,
  20213. X      centering  = 0,
  20214. X      lformat_exclude = format_exclude,
  20215. X      again;
  20216. X
  20217. X   xonline = xdoc = 0;
  20218. X
  20219. X   src_cfname = fname;
  20220. X
  20221. X   if ( (srcfile = fopen(fname, "rt")) == NULL )
  20222. X      fatal(0,"Unable to open \"%s\"", fname);
  20223. X
  20224. X   msg("Compiling: %s", fname);
  20225. X
  20226. X   in_topic = 0;
  20227. X
  20228. X   curr = buffer;
  20229. X
  20230. X   while ( 1 )
  20231. X      {
  20232. X
  20233. X      ch = read_char();
  20234. X
  20235. X      if ( ch == -1 )   /* EOF? */
  20236. X     {
  20237. X     if ( include_stack_top >= 0)
  20238. X        {
  20239. X        fclose(srcfile);
  20240. X        src_cfname = include_stack[include_stack_top].fname;
  20241. X        srcfile = include_stack[include_stack_top].file;
  20242. X        srcline = include_stack[include_stack_top].line;
  20243. X        srccol  = include_stack[include_stack_top].col;
  20244. X        --include_stack_top;
  20245. X        continue;
  20246. X        }
  20247. X     else
  20248. X        {
  20249. X        if (in_topic)  /* if we're in a topic, finish it */
  20250. X           end_topic(&t);
  20251. X        if (num_topic == 0)
  20252. X           warn(0,".SRC file has no topics.");
  20253. X        break;
  20254. X        }
  20255. X     }
  20256. X
  20257. X      if (ch == '~')   /* is is a command? */
  20258. X     {
  20259. X     int imbedded;
  20260. X     int eoff;
  20261. X     int done;
  20262. X
  20263. X     ch = read_char();
  20264. X     if (ch == '(')
  20265. X        {
  20266. X        imbedded = 1;
  20267. X        eoff = 0;
  20268. X        }
  20269. X     else
  20270. X        {
  20271. X        imbedded = 0;
  20272. X        eoff=0;
  20273. X        unread_char(ch);
  20274. X        }
  20275. X
  20276. X     done = 0;
  20277. X
  20278. X     while ( !done )
  20279. X        {
  20280. X        do
  20281. X           ch = read_char();
  20282. X        while (ch == ' ');
  20283. X        unread_char(ch);
  20284. X
  20285. X        if (imbedded)
  20286. X           ptr = read_until(cmd, 128, ")\n,");
  20287. X        else
  20288. X           ptr = read_until(cmd, 128, "\n,");
  20289. X
  20290. X        done = 1;
  20291. X
  20292. X        if ( *ptr == '\0' )
  20293. X           {
  20294. X           error(0,"Unexpected EOF in command.");
  20295. X           break;
  20296. X           }
  20297. X
  20298. X        if (*ptr == '\n')
  20299. X           ++eoff;
  20300. X
  20301. X        if ( imbedded && *ptr == '\n' )
  20302. X           error(eoff,"Imbedded command has no closing parend (\')\')");
  20303. X
  20304. X        done = (*ptr != ',');   /* we done if it's not a comma */
  20305. X
  20306. X        if ( *ptr != '\n' && *ptr != ')' && *ptr != ',' )
  20307. X           {
  20308. X           error(0,"Command line too long.");
  20309. X           break;
  20310. X           }
  20311. X
  20312. X        *ptr = '\0';
  20313. X
  20314. X
  20315. X        /* commands allowed anytime... */
  20316. X
  20317. X        if ( strnicmp(cmd, "Topic=", 6) == 0 )
  20318. X           {
  20319. X           if (in_topic)  /* if we're in a topic, finish it */
  20320. X          end_topic(&t);
  20321. X           else
  20322. X          in_topic = 1;
  20323. X
  20324. X           if (cmd[6] == '\0')
  20325. X          warn(eoff,"Topic has no title.");
  20326. X
  20327. X           else if (strlen(cmd+6) > 70)
  20328. X          error(eoff,"Topic title is too long.");
  20329. X
  20330. X           else if (strlen(cmd+6) > 60)
  20331. X          warn(eoff,"Topic title is long.");
  20332. X
  20333. X           if ( find_topic_title(cmd+6) != -1 )
  20334. X          error(eoff,"Topic title already exists.");
  20335. X
  20336. X           start_topic(&t, cmd+6, (unsigned)(ptr-(cmd+6)));
  20337. X           formatting = 1;
  20338. X           centering = 0;
  20339. X           state = S_Start;
  20340. X           in_para = 0;
  20341. X           num_spaces = 0;
  20342. X           xonline = xdoc = 0;
  20343. X           lformat_exclude = format_exclude;
  20344. X           compress_spaces = 1;
  20345. X           continue;
  20346. X           }
  20347. X
  20348. X        else if ( strnicmp(cmd, "Data=", 5) == 0 )
  20349. X           {
  20350. X           if (in_topic)  /* if we're in a topic, finish it */
  20351. X          end_topic(&t);
  20352. X           else
  20353. X          in_topic = 1;
  20354. X
  20355. X           if (cmd[5] == '\0')
  20356. X          warn(eoff,"Data topic has no label.");
  20357. X
  20358. X           if ( !validate_label_name(cmd+5) )
  20359. X          {
  20360. X          error(eoff,"Label \"%s\" contains illegal characters.", cmd+5);
  20361. X          continue;
  20362. X          }
  20363. X
  20364. X           if ( find_label(cmd+5) != NULL )
  20365. X          {
  20366. X          error(eoff,"Label \"%s\" already exists", cmd+5);
  20367. X          continue;
  20368. X          }
  20369. X
  20370. X           if ( cmd[5] == '@' )
  20371. X          warn(eoff, "Data topic has a local label.");
  20372. X
  20373. X           start_topic(&t, "", 0);
  20374. X           t.flags |= TF_DATA;
  20375. X
  20376. X           if (strlen(cmd+5) > 32)
  20377. X          warn(eoff,"Label name is long.");
  20378. X
  20379. X           lbl.name      = dupstr(cmd+5, 0);
  20380. X           lbl.topic_num = num_topic;
  20381. X           lbl.topic_off = 0;
  20382. X           lbl.doc_page  = -1;
  20383. X           add_label(&lbl);
  20384. X
  20385. X           formatting = 0;
  20386. X           centering = 0;
  20387. X           state = S_Start;
  20388. X           in_para = 0;
  20389. X           num_spaces = 0;
  20390. X           xonline = xdoc = 0;
  20391. X           lformat_exclude = format_exclude;
  20392. X           compress_spaces = 0;
  20393. X           continue;
  20394. X           }
  20395. X
  20396. X        else if ( strnicmp(cmd, "DocContents", 11) == 0 )
  20397. X           {
  20398. X           check_command_length(eoff, 11);
  20399. X           if (in_topic)  /* if we're in a topic, finish it */
  20400. X          end_topic(&t);
  20401. X           if (!done)
  20402. X          {
  20403. X          if (imbedded)
  20404. X             unread_char('(');
  20405. X          unread_char('~');
  20406. X          done = 1;
  20407. X          }
  20408. X           compress_spaces = 1;
  20409. X           process_contents();
  20410. X           in_topic = 0;
  20411. X           continue;
  20412. X           }
  20413. X
  20414. X        else if ( stricmp(cmd, "Comment") == 0 )
  20415. X           {
  20416. X           process_comment();
  20417. X           continue;
  20418. X           }
  20419. X
  20420. X        else if ( strnicmp(cmd, "FormatExclude", 13) == 0 )
  20421. X           {
  20422. X           if (cmd[13] == '-')
  20423. X          {
  20424. X          check_command_length(eoff, 14);
  20425. X          if ( in_topic )
  20426. X             {
  20427. X             if (lformat_exclude > 0)
  20428. X                lformat_exclude = -lformat_exclude;
  20429. X             else
  20430. X                warn(eoff,"\"FormatExclude-\" is already in effect.");
  20431. X             }
  20432. X          else
  20433. X             {
  20434. X             if (format_exclude > 0)
  20435. X                format_exclude = -format_exclude;
  20436. X             else
  20437. X                warn(eoff,"\"FormatExclude-\" is already in effect.");
  20438. X             }
  20439. X          }
  20440. X           else if (cmd[13] == '+')
  20441. X          {
  20442. X          check_command_length(eoff,14);
  20443. X          if ( in_topic )
  20444. X             {
  20445. X             if (lformat_exclude < 0)
  20446. X                lformat_exclude = -lformat_exclude;
  20447. X             else
  20448. X                warn(eoff,"\"FormatExclude+\" is already in effect.");
  20449. X             }
  20450. X          else
  20451. X             {
  20452. X             if (format_exclude < 0)
  20453. X                format_exclude = -format_exclude;
  20454. X             else
  20455. X                warn(eoff,"\"FormatExclude+\" is already in effect.");
  20456. X             }
  20457. X          }
  20458. X           else if (cmd[13] == '=')
  20459. X          {
  20460. X          if (cmd[14] == 'n' || cmd[14] == 'N')
  20461. X             {
  20462. X             check_command_length(eoff,15);
  20463. X             if (in_topic)
  20464. X                lformat_exclude = 0;
  20465. X             else
  20466. X               format_exclude = 0;
  20467. X             }
  20468. X          else if (cmd[14] == '\0')
  20469. X             lformat_exclude = format_exclude;
  20470. X          else
  20471. X             {
  20472. X             int n = ( ( (in_topic) ? lformat_exclude : format_exclude) < 0 ) ? -1 : 1;
  20473. X
  20474. X             lformat_exclude = atoi(cmd+14);
  20475. X
  20476. X             if ( lformat_exclude <= 0 )
  20477. X                {
  20478. X                error(eoff,"Invalid argument to FormatExclude=");
  20479. X                lformat_exclude = 0;
  20480. X                }
  20481. X
  20482. X             lformat_exclude *= n;
  20483. X
  20484. X             if ( !in_topic )
  20485. X                format_exclude = lformat_exclude;
  20486. X             }
  20487. X          }
  20488. X           else
  20489. X          error(eoff,"Invalid format for FormatExclude");
  20490. X
  20491. X           continue;
  20492. X           }
  20493. X
  20494. X        else if ( strnicmp(cmd, "Include ", 8) == 0 )
  20495. X           {
  20496. X           if (include_stack_top >= MAX_INCLUDE_STACK-1)
  20497. X          error(eoff, "Too many nested Includes.");
  20498. X           else
  20499. X          {
  20500. X          ++include_stack_top;
  20501. X          include_stack[include_stack_top].fname = src_cfname;
  20502. X          include_stack[include_stack_top].file = srcfile;
  20503. X          include_stack[include_stack_top].line = srcline;
  20504. X          include_stack[include_stack_top].col  = srccol;
  20505. X          strupr(cmd+8);
  20506. X          if ( (srcfile = fopen(cmd+8, "rt")) == NULL )
  20507. X             {
  20508. X             error(eoff, "Unable to open \"%s\"", cmd+8);
  20509. X             srcfile = include_stack[include_stack_top--].file;
  20510. X             }
  20511. X          src_cfname = dupstr(cmd+8,0);  /* never deallocate! */
  20512. X          srcline = 1;
  20513. X          srccol = 0;
  20514. X          }
  20515. X
  20516. X           continue;
  20517. X           }
  20518. X
  20519. X
  20520. X        /* commands allowed only before all topics... */
  20521. X
  20522. X        if ( !in_topic )
  20523. X           {
  20524. X           if ( strnicmp(cmd, "HdrFile=", 8) == 0 )
  20525. X          {
  20526. X          if (hdr_fname[0] != '\0')
  20527. X             warn(eoff,"Header Filename has already been defined.");
  20528. X          strcpy(hdr_fname, cmd+8);
  20529. X          strupr(hdr_fname);
  20530. X          }
  20531. X
  20532. X           else if ( strnicmp(cmd, "HlpFile=", 8) == 0 )
  20533. X          {
  20534. X          if (hlp_fname[0] != '\0')
  20535. X             warn(eoff,"Help Filename has already been defined.");
  20536. X          strcpy(hlp_fname, cmd+8);
  20537. X          strupr(hlp_fname);
  20538. X          }
  20539. X
  20540. X           else if ( strnicmp(cmd, "Version=", 8) == 0 )
  20541. X          {
  20542. X          if (version != -1)   /* an unlikely value */
  20543. X             warn(eoff,"Help version has already been defined");
  20544. X          version = atoi(cmd+8);
  20545. X          }
  20546. X
  20547. X           else
  20548. X          error(eoff,"Bad or unexpected command \"%s\"", cmd);
  20549. X
  20550. X           continue;
  20551. X           }
  20552. X
  20553. X
  20554. X        /* commands allowed only in a topic... */
  20555. X
  20556. X        else
  20557. X           {
  20558. X           if (strnicmp(cmd, "FF", 2) == 0 )
  20559. X          {
  20560. X          check_command_length(eoff,2);
  20561. X          if ( in_para )
  20562. X             *curr++ = '\n';  /* finish off current paragraph */
  20563. X          *curr++ = CMD_FF;
  20564. X          state = S_Start;
  20565. X          in_para = 0;
  20566. X          num_spaces = 0;
  20567. X          }
  20568. X
  20569. X           else if (strnicmp(cmd, "DocFF", 5) == 0 )
  20570. X          {
  20571. X          check_command_length(eoff,5);
  20572. X          if ( in_para )
  20573. X             *curr++ = '\n';  /* finish off current paragraph */
  20574. X          if (!xonline)
  20575. X             *curr++ = CMD_XONLINE;
  20576. X          *curr++ = CMD_FF;
  20577. X          if (!xonline)
  20578. X             *curr++ = CMD_XONLINE;
  20579. X          state = S_Start;
  20580. X          in_para = 0;
  20581. X          num_spaces = 0;
  20582. X          }
  20583. X
  20584. X           else if (strnicmp(cmd, "OnlineFF", 8) == 0 )
  20585. X          {
  20586. X          check_command_length(eoff,8);
  20587. X          if ( in_para )
  20588. X             *curr++ = '\n';  /* finish off current paragraph */
  20589. X          if (!xdoc)
  20590. X             *curr++ = CMD_XDOC;
  20591. X          *curr++ = CMD_FF;
  20592. X          if (!xdoc)
  20593. X             *curr++ = CMD_XDOC;
  20594. X          state = S_Start;
  20595. X          in_para = 0;
  20596. X          num_spaces = 0;
  20597. X          }
  20598. X
  20599. X           else if ( strnicmp(cmd, "Label=", 6) == 0 )
  20600. X          {
  20601. X          if (strlen(cmd+6) <= 0)
  20602. X             error(eoff,"Label has no name.");
  20603. X
  20604. X          else if ( !validate_label_name(cmd+6) )
  20605. X             error(eoff,"Label \"%s\" contains illegal characters.", cmd+6);
  20606. X
  20607. X          else if ( find_label(cmd+6) != NULL )
  20608. X             error(eoff,"Label \"%s\" already exists", cmd+6);
  20609. X
  20610. X          else
  20611. X             {
  20612. X             if (strlen(cmd+6) > 32)
  20613. X                warn(eoff,"Label name is long.");
  20614. X
  20615. X            if ( (t.flags & TF_DATA) && cmd[6] == '@' )
  20616. X               warn(eoff, "Data topic has a local label.");
  20617. X
  20618. X             lbl.name       = dupstr(cmd+6, 0);
  20619. X             lbl.topic_num = num_topic;
  20620. X             lbl.topic_off = (unsigned)(curr - buffer);
  20621. X             lbl.doc_page  = -1;
  20622. X             add_label(&lbl);
  20623. X             }
  20624. X          }
  20625. X
  20626. X           else if ( strnicmp(cmd, "Table=", 6) == 0 )
  20627. X          {
  20628. X          if ( in_para )
  20629. X             {
  20630. X             *curr++ = '\n';  /* finish off current paragraph */
  20631. X             in_para = 0;
  20632. X             num_spaces = 0;
  20633. X             state = S_Start;
  20634. X             }
  20635. X
  20636. X          if (!done)
  20637. X             {
  20638. X             if (imbedded)
  20639. X                unread_char('(');
  20640. X             unread_char('~');
  20641. X             done = 1;
  20642. X             }
  20643. X
  20644. X          create_table();
  20645. X          }
  20646. X
  20647. X           else if ( strnicmp(cmd, "FormatExclude", 12) == 0 )
  20648. X          {
  20649. X          if (cmd[13] == '-')
  20650. X             {
  20651. X             check_command_length(eoff,14);
  20652. X             if (lformat_exclude > 0)
  20653. X                lformat_exclude = -lformat_exclude;
  20654. X             else
  20655. X                warn(0,"\"FormatExclude-\" is already in effect.");
  20656. X             }
  20657. X          else if (cmd[13] == '+')
  20658. X             {
  20659. X             check_command_length(eoff,14);
  20660. X             if (lformat_exclude < 0)
  20661. X                lformat_exclude = -lformat_exclude;
  20662. X             else
  20663. X                warn(0,"\"FormatExclude+\" is already in effect.");
  20664. X             }
  20665. X          else
  20666. X             error(eoff,"Unexpected or invalid argument to FormatExclude.");
  20667. X          }
  20668. X
  20669. X           else if ( strnicmp(cmd, "Format", 6) == 0 )
  20670. X          {
  20671. X          if (cmd[6] == '+')
  20672. X             {
  20673. X             check_command_length(eoff,7);
  20674. X             if ( !formatting )
  20675. X                {
  20676. X                formatting = 1;
  20677. X                in_para = 0;
  20678. X                num_spaces = 0;
  20679. X                state = S_Start;
  20680. X                }
  20681. X             else
  20682. X                warn(eoff,"\"Format+\" is already in effect.");
  20683. X             }
  20684. X          else if (cmd[6] == '-')
  20685. X             {
  20686. X             check_command_length(eoff,7);
  20687. X             if ( formatting )
  20688. X                {
  20689. X                if ( in_para )
  20690. X               *curr++ = '\n';  /* finish off current paragraph */
  20691. X                state = S_Start;
  20692. X                in_para = 0;
  20693. X                formatting = 0;
  20694. X                num_spaces = 0;
  20695. X                state = S_Start;
  20696. X                }
  20697. X             else
  20698. X                warn(eoff,"\"Format-\" is already in effect.");
  20699. X             }
  20700. X          else
  20701. X             error(eoff,"Invalid argument to Format.");
  20702. X          }
  20703. X
  20704. X           else if ( strnicmp(cmd, "Online", 6) == 0 )
  20705. X          {
  20706. X          if (cmd[6] == '+')
  20707. X             {
  20708. X             check_command_length(eoff,7);
  20709. X
  20710. X             if ( xonline )
  20711. X                {
  20712. X                *curr++ = CMD_XONLINE;
  20713. X                xonline = 0;
  20714. X                }
  20715. X             else
  20716. X                warn(eoff,"\"Online+\" already in effect.");
  20717. X             }
  20718. X          else if (cmd[6] == '-')
  20719. X             {
  20720. X             check_command_length(eoff,7);
  20721. X             if ( !xonline )
  20722. X                {
  20723. X                *curr++ = CMD_XONLINE;
  20724. X                xonline = 1;
  20725. X                }
  20726. X             else
  20727. X                warn(eoff,"\"Online-\" already in effect.");
  20728. X             }
  20729. X          else
  20730. X             error(eoff,"Invalid argument to Online.");
  20731. X          }
  20732. X
  20733. X           else if ( strnicmp(cmd, "Doc", 3) == 0 )
  20734. X          {
  20735. X          if (cmd[3] == '+')
  20736. X             {
  20737. X             check_command_length(eoff,4);
  20738. X             if ( xdoc )
  20739. X                {
  20740. X                *curr++ = CMD_XDOC;
  20741. X                xdoc = 0;
  20742. X                }
  20743. X             else
  20744. X                warn(eoff,"\"Doc+\" already in effect.");
  20745. X             }
  20746. X          else if (cmd[3] == '-')
  20747. X             {
  20748. X             check_command_length(eoff,4);
  20749. X             if ( !xdoc )
  20750. X                {
  20751. X                *curr++ = CMD_XDOC;
  20752. X                xdoc = 1;
  20753. X                }
  20754. X             else
  20755. X                warn(eoff,"\"Doc-\" already in effect.");
  20756. X             }
  20757. X          else
  20758. X             error(eoff,"Invalid argument to Doc.");
  20759. X          }
  20760. X
  20761. X           else if ( strnicmp(cmd, "Center", 6) == 0 )
  20762. X          {
  20763. X          if (cmd[6] == '+')
  20764. X             {
  20765. X             check_command_length(eoff,7);
  20766. X             if ( !centering )
  20767. X                {
  20768. X                centering = 1;
  20769. X                if ( in_para )
  20770. X               {
  20771. X               *curr++ = '\n';
  20772. X               in_para = 0;
  20773. X               }
  20774. X                state = S_Start;  /* for centering FSM */
  20775. X                }
  20776. X             else
  20777. X                warn(eoff,"\"Center+\" already in effect.");
  20778. X             }
  20779. X          else if (cmd[6] == '-')
  20780. X             {
  20781. X             check_command_length(eoff,7);
  20782. X             if ( centering )
  20783. X                {
  20784. X                centering = 0;
  20785. X                state = S_Start;  /* for centering FSM */
  20786. X                }
  20787. X             else
  20788. X                warn(eoff,"\"Center-\" already in effect.");
  20789. X             }
  20790. X          else
  20791. X             error(eoff,"Invalid argument to Center.");
  20792. X          }
  20793. X
  20794. X           else if ( strnicmp(cmd, "CompressSpaces", 14) == 0 )
  20795. X          {
  20796. X          check_command_length(eoff,15);
  20797. X
  20798. X          if ( cmd[14] == '+' )
  20799. X             {
  20800. X             if ( compress_spaces )
  20801. X                warn(eoff,"\"CompressSpaces+\" is already in effect.");
  20802. X             else
  20803. X                compress_spaces = 1;
  20804. X             }
  20805. X          else if ( cmd[14] == '-' )
  20806. X             {
  20807. X             if ( !compress_spaces )
  20808. X                warn(eoff,"\"CompressSpaces-\" is already in effect.");
  20809. X             else
  20810. X                compress_spaces = 0;
  20811. X             }
  20812. X          else
  20813. X             error(eoff,"Invalid argument to CompressSpaces.");
  20814. X          }
  20815. X
  20816. X           else if ( strnicmp("BinInc ", cmd, 7) == 0 )
  20817. X          {
  20818. X          if ( !(t.flags & TF_DATA) )
  20819. X             error(eoff,"BinInc allowed only in Data topics.");
  20820. X          else
  20821. X             process_bininc();
  20822. X          }
  20823. X
  20824. X           else
  20825. X          error(eoff,"Bad or unexpected command \"%s\".", cmd);
  20826. X           } /* else */
  20827. X
  20828. X        } /* while (!done) */
  20829. X
  20830. X     continue;
  20831. X     }
  20832. X
  20833. X      if ( !in_topic )
  20834. X     {
  20835. X     cmd[0] = ch;
  20836. X     ptr = read_until(cmd+1, 127, "\n~");
  20837. X     if (*ptr == '~')
  20838. X        unread_char('~');
  20839. X     *ptr = '\0';
  20840. X     error(0,"Text outside of any topic \"%s\".", cmd);
  20841. X     continue;
  20842. X     }
  20843. X
  20844. X      if ( centering )
  20845. X     {
  20846. X     do
  20847. X        {
  20848. X        again = 0;     /* default */
  20849. X
  20850. X        switch (state)
  20851. X           {
  20852. X           case S_Start:
  20853. X          if (ch == ' ')
  20854. X             ; /* do nothing */
  20855. X          else if ( (ch&0xFF) == '\n' )
  20856. X             *curr++ = ch;  /* no need to center blank lines. */
  20857. X          else
  20858. X             {
  20859. X             *curr++ = CMD_CENTER;
  20860. X             state = S_Line;
  20861. X             again = 1;
  20862. X             }
  20863. X          break;
  20864. X
  20865. X           case S_Line:
  20866. X          put_a_char(ch, &t);
  20867. X          if ( (ch&0xFF) == '\n')
  20868. X             state = S_Start;
  20869. X          break;
  20870. X           } /* switch */
  20871. X        }
  20872. X     while (again);
  20873. X     }
  20874. X
  20875. X      else if ( formatting )
  20876. X     {
  20877. X     int again;
  20878. X
  20879. X     do
  20880. X        {
  20881. X        again = 0;     /* default */
  20882. X
  20883. X        switch (state)
  20884. X           {
  20885. X           case S_Start:
  20886. X          if ( (ch&0xFF) == '\n' )
  20887. X             *curr++ = ch;
  20888. X          else
  20889. X             {
  20890. X             state = S_StartFirstLine;
  20891. X             num_spaces = 0;
  20892. X             again = 1;
  20893. X             }
  20894. X          break;
  20895. X
  20896. X           case S_StartFirstLine:
  20897. X          if ( ch == ' ')
  20898. X             ++num_spaces;
  20899. X
  20900. X          else
  20901. X             {
  20902. X             if (lformat_exclude > 0 && num_spaces >= lformat_exclude )
  20903. X                {
  20904. X                put_spaces(num_spaces);
  20905. X                num_spaces = 0;
  20906. X                state = S_FormatDisabled;
  20907. X                again = 1;
  20908. X                }
  20909. X             else
  20910. X                {
  20911. X                *curr++ = CMD_PARA;
  20912. X                *curr++ = (char)num_spaces;
  20913. X                *curr++ = (char)num_spaces;
  20914. X                margin_pos = curr - 1;
  20915. X                state = S_FirstLine;
  20916. X                again = 1;
  20917. X                in_para = 1;
  20918. X                }
  20919. X             }
  20920. X          break;
  20921. X
  20922. X           case S_FirstLine:
  20923. X          if (ch == '\n')
  20924. X             {
  20925. X             state = S_StartSecondLine;
  20926. X             num_spaces = 0;
  20927. X             }
  20928. X          else if (ch == ('\n'|0x100) )   /* force end of para ? */
  20929. X             {
  20930. X             *curr++ = '\n';
  20931. X             in_para = 0;
  20932. X             state = S_Start;
  20933. X             }
  20934. X          else if ( ch == ' ' )
  20935. X             {
  20936. X             state = S_FirstLineSpaces;
  20937. X             num_spaces = 1;
  20938. X             }
  20939. X          else
  20940. X             put_a_char(ch, &t);
  20941. X          break;
  20942. X
  20943. X           case S_FirstLineSpaces:
  20944. X          if (ch == ' ')
  20945. X             ++num_spaces;
  20946. X          else
  20947. X             {
  20948. X             put_spaces(num_spaces);
  20949. X             state = S_FirstLine;
  20950. X             again = 1;
  20951. X             }
  20952. X          break;
  20953. X
  20954. X           case S_StartSecondLine:
  20955. X          if ( ch == ' ')
  20956. X             ++num_spaces;
  20957. X          else if ((ch&0xFF) == '\n') /* a blank line means end of a para */
  20958. X             {
  20959. X             *curr++ = '\n';   /* end the para */
  20960. X             *curr++ = '\n';   /* for the blank line */
  20961. X             in_para = 0;
  20962. X             state = S_Start;
  20963. X             }
  20964. X          else
  20965. X             {
  20966. X             if (lformat_exclude > 0 && num_spaces >= lformat_exclude )
  20967. X                {
  20968. X                *curr++ = '\n';
  20969. X                in_para = 0;
  20970. X                put_spaces(num_spaces);
  20971. X                num_spaces = 0;
  20972. X                state = S_FormatDisabled;
  20973. X                again = 1;
  20974. X                }
  20975. X             else
  20976. X                {
  20977. X                add_blank_for_split();
  20978. X                margin = num_spaces;
  20979. X                *margin_pos = (char)num_spaces;
  20980. X                state = S_Line;
  20981. X                again = 1;
  20982. X                }
  20983. X             }
  20984. X          break;
  20985. X
  20986. X           case S_Line:   /* all lines after the first */
  20987. X          if (ch == '\n')
  20988. X             {
  20989. X             state = S_StartLine;
  20990. X             num_spaces = 0;
  20991. X             }
  20992. X          else if (ch == ('\n' | 0x100) )   /* force end of para ? */
  20993. X             {
  20994. X             *curr++ = '\n';
  20995. X             in_para = 0;
  20996. X             state = S_Start;
  20997. X             }
  20998. X          else if ( ch == ' ' )
  20999. X             {
  21000. X             state = S_LineSpaces;
  21001. X             num_spaces = 1;
  21002. X             }
  21003. X          else
  21004. X             put_a_char(ch, &t);
  21005. X          break;
  21006. X
  21007. X           case S_LineSpaces:
  21008. X          if (ch == ' ')
  21009. X             ++num_spaces;
  21010. X          else
  21011. X             {
  21012. X             put_spaces(num_spaces);
  21013. X             state = S_Line;
  21014. X             again = 1;
  21015. X             }
  21016. X          break;
  21017. X
  21018. X           case S_StartLine:   /* for all lines after the second */
  21019. X          if ( ch == ' ')
  21020. X             ++num_spaces;
  21021. X          else if ((ch&0xFF) == '\n') /* a blank line means end of a para */
  21022. X             {
  21023. X             *curr++ = '\n';   /* end the para */
  21024. X             *curr++ = '\n';   /* for the blank line */
  21025. X             in_para = 0;
  21026. X             state = S_Start;
  21027. X             }
  21028. X          else
  21029. X             {
  21030. X             if ( num_spaces != margin )
  21031. X                {
  21032. X                *curr++ = '\n';
  21033. X                in_para = 0;
  21034. X                state = S_StartFirstLine;  /* with current num_spaces */
  21035. X                again = 1;
  21036. X                }
  21037. X             else
  21038. X                {
  21039. X                add_blank_for_split();
  21040. X                state = S_Line;
  21041. X                again = 1;
  21042. X                }
  21043. X             }
  21044. X          break;
  21045. X
  21046. X           case S_FormatDisabled:
  21047. X          if ( ch == ' ' )
  21048. X             {
  21049. X             state = S_FormatDisabledSpaces;
  21050. X             num_spaces = 1;
  21051. X             }
  21052. X          else
  21053. X             {
  21054. X             if ( (ch&0xFF) == '\n' )
  21055. X                state = S_Start;
  21056. X             put_a_char(ch, &t);
  21057. X             }
  21058. X          break;
  21059. X
  21060. X           case S_FormatDisabledSpaces:
  21061. X          if ( ch == ' ' )
  21062. X             ++num_spaces;
  21063. X          else
  21064. X             {
  21065. X             put_spaces(num_spaces);
  21066. X             num_spaces = 0;    /* is this needed? */
  21067. X             state = S_FormatDisabled;
  21068. X             again = 1;
  21069. X             }
  21070. X          break;
  21071. X
  21072. X           } /* switch (state) */
  21073. X        }
  21074. X     while (again);
  21075. X     }
  21076. X
  21077. X      else
  21078. X     {
  21079. X     do
  21080. X        {
  21081. X        again = 0;     /* default */
  21082. X
  21083. X        switch (state)
  21084. X           {
  21085. X           case S_Start:
  21086. X          if ( ch == ' ' )
  21087. X             {
  21088. X             state = S_Spaces;
  21089. X             num_spaces = 1;
  21090. X             }
  21091. X          else
  21092. X             put_a_char(ch, &t);
  21093. X          break;
  21094. X
  21095. X           case S_Spaces:
  21096. X          if (ch == ' ')
  21097. X             ++num_spaces;
  21098. X          else
  21099. X             {
  21100. X             put_spaces(num_spaces);
  21101. X             num_spaces = 0;     /* is this needed? */
  21102. X             state = S_Start;
  21103. X             again = 1;
  21104. X             }
  21105. X          break;
  21106. X           } /* switch */
  21107. X        }
  21108. X     while (again);
  21109. X     }
  21110. X
  21111. X      CHK_BUFFER(0)
  21112. X      } /* while ( 1 ) */
  21113. X
  21114. X   fclose(srcfile);
  21115. X
  21116. X   srcline = -1;
  21117. X   }
  21118. X
  21119. X
  21120. X/*
  21121. X * stuff to resolve hot-link references.
  21122. X */
  21123. X
  21124. X
  21125. Xvoid make_hot_links(void)
  21126. X   /*
  21127. X    * calculate topic_num/topic_off for each link.
  21128. X    */
  21129. X   {
  21130. X   LINK    *l;
  21131. X   LABEL   *lbl;
  21132. X   int        lctr;
  21133. X   int        t;
  21134. X   CONTENT *c;
  21135. X   int        ctr;
  21136. X
  21137. X   msg("Making hot-links.");
  21138. X
  21139. X   /*
  21140. X    * Calculate topic_num for all entries in DocContents.  Also set
  21141. X    * "TF_IN_DOC" flag for all topics included in the document.
  21142. X    */
  21143. X
  21144. X   for (lctr=0, c=contents; lctr<num_contents; lctr++, c++)
  21145. X      {
  21146. X      for (ctr=0; ctr<c->num_topic; ctr++)
  21147. X     {
  21148. X     if ( c->is_label[ctr] )
  21149. X        {
  21150. X        lbl = find_label(c->topic_name[ctr]);
  21151. X        if (lbl == NULL)
  21152. X           {
  21153. X           src_cfname = c->srcfile;
  21154. X           srcline = c->srcline;
  21155. X           error(0,"Cannot find DocContent label \"%s\".", c->topic_name[ctr]);
  21156. X           srcline = -1;
  21157. X           }
  21158. X        else
  21159. X           {
  21160. X           if ( topic[lbl->topic_num].flags & TF_DATA )
  21161. X          {
  21162. X          src_cfname = c->srcfile;
  21163. X          srcline = c->srcline;
  21164. X          error(0,"Label \"%s\" is a data-only topic.", c->topic_name[ctr]);
  21165. X          srcline = -1;
  21166. X          }
  21167. X           else
  21168. X          {
  21169. X          c->topic_num[ctr] = lbl->topic_num;
  21170. X          if ( topic[lbl->topic_num].flags & TF_IN_DOC )
  21171. X             warn(0,"Topic \"%s\" appears in document more than once.",
  21172. X              topic[lbl->topic_num].title);
  21173. X          else
  21174. X             topic[lbl->topic_num].flags |= TF_IN_DOC;
  21175. X          }
  21176. X           }
  21177. X
  21178. X        }
  21179. X     else
  21180. X        {
  21181. X        t = find_topic_title(c->topic_name[ctr]);
  21182. X
  21183. X        if (t == -1)
  21184. X           {
  21185. X           src_cfname = c->srcfile;
  21186. X           srcline = c->srcline;
  21187. X           error(0,"Cannot find DocContent topic \"%s\".", c->topic_name[ctr]);
  21188. X           srcline = -1;  /* back to reality */
  21189. X           }
  21190. X        else
  21191. X           {
  21192. X           c->topic_num[ctr] = t;
  21193. X           if ( topic[t].flags & TF_IN_DOC )
  21194. X          warn(0,"Topic \"%s\" appears in document more than once.",
  21195. X               topic[t].title);
  21196. X           else
  21197. X          topic[t].flags |= TF_IN_DOC;
  21198. X           }
  21199. X        }
  21200. X     }
  21201. X      }
  21202. X
  21203. X   /*
  21204. X    * Find topic_num and topic_off for all hot-links.  Also flag all hot-
  21205. X    * links which will (probably) appear in the document.
  21206. X    */
  21207. X
  21208. X   for (lctr=0, l=a_link; lctr<num_link; l++, lctr++)
  21209. X      {
  21210. X      switch ( l->type )
  21211. X     {
  21212. X     case 0:      /* name is the title of the topic */
  21213. X        t = find_topic_title(l->name);
  21214. X        if (t == -1)
  21215. X           {
  21216. X           src_cfname = l->srcfile;
  21217. X           srcline = l->srcline; /* pretend we are still in the source... */
  21218. X           error(0,"Cannot find implicit hot-link \"%s\".", l->name);
  21219. X           srcline = -1;  /* back to reality */
  21220. X           }
  21221. X        else
  21222. X           {
  21223. X           l->topic_num = t;
  21224. X           l->topic_off = 0;
  21225. X           l->doc_page = (topic[t].flags & TF_IN_DOC) ? 0 : -1;
  21226. X           }
  21227. X        break;
  21228. X
  21229. X     case 1:  /* name is the name of a label */
  21230. X        lbl = find_label(l->name);
  21231. X        if (lbl == NULL)
  21232. X           {
  21233. X           src_cfname = l->srcfile;
  21234. X           srcline = l->srcline; /* pretend again */
  21235. X           error(0,"Cannot find explicit hot-link \"%s\".", l->name);
  21236. X           srcline = -1;
  21237. X           }
  21238. X        else
  21239. X           {
  21240. X           if ( topic[lbl->topic_num].flags & TF_DATA )
  21241. X          {
  21242. X          src_cfname = l->srcfile;
  21243. X          srcline = l->srcline;
  21244. X          error(0,"Label \"%s\" is a data-only topic.", l->name);
  21245. X          srcline = -1;
  21246. X          }
  21247. X           else
  21248. X          {
  21249. X          l->topic_num = lbl->topic_num;
  21250. X          l->topic_off = lbl->topic_off;
  21251. X          l->doc_page  = (topic[lbl->topic_num].flags & TF_IN_DOC) ? 0 : -1;
  21252. X          }
  21253. X           }
  21254. X        break;
  21255. X
  21256. X     case 2:   /* it's a "special" link; topic_off already has the value */
  21257. X        break;
  21258. X     }
  21259. X      }
  21260. X
  21261. X   }
  21262. X
  21263. X
  21264. X/*
  21265. X * online help pagination stuff
  21266. X */
  21267. X
  21268. X
  21269. Xvoid add_page_break(TOPIC *t, int margin, char *text, char *start, char *curr, int num_links)
  21270. X   {
  21271. X   PAGE p;
  21272. X
  21273. X   p.offset = (unsigned) (start - text);
  21274. X   p.length = (unsigned) (curr - start);
  21275. X   p.margin = margin;
  21276. X   add_page(t, &p);
  21277. X
  21278. X   if (max_links < num_links)
  21279. X      max_links = num_links;
  21280. X   }
  21281. X
  21282. X
  21283. Xvoid paginate_online(void)    /* paginate the text for on-line help */
  21284. X   {               /* also calculates max_pages and max_links */
  21285. X   int         lnum;
  21286. X   char     *start;
  21287. X   char     *curr;
  21288. X   char     *text;
  21289. X   TOPIC    *t;
  21290. X   int         tctr;
  21291. X   unsigned  len;
  21292. X   int         skip_blanks;
  21293. X   int         num_links;
  21294. X   int         col;
  21295. X   int         tok;
  21296. X   int         size,
  21297. X         width;
  21298. X   int         start_margin;
  21299. X
  21300. X   msg("Paginating online help.");
  21301. X
  21302. X   for (t=topic, tctr=0; tctr<num_topic; t++, tctr++)
  21303. X      {
  21304. X      if ( t->flags & TF_DATA )
  21305. X     continue;    /* don't paginate data topics */
  21306. X
  21307. X      text = get_topic_text(t);
  21308. X      curr = text;
  21309. X      len  = t->text_len;
  21310. X
  21311. X      start = curr;
  21312. X      skip_blanks = 0;
  21313. X      lnum = 0;
  21314. X      num_links = 0;
  21315. X      col = 0;
  21316. X      start_margin = -1;
  21317. X
  21318. X      while (len > 0)
  21319. X     {
  21320. X     tok = find_token_length(ONLINE, curr, len, &size, &width);
  21321. X
  21322. X     switch ( tok )
  21323. X        {
  21324. X        case TOK_PARA:
  21325. X           {
  21326. X           int indent,
  21327. X           margin;
  21328. X
  21329. X           ++curr;
  21330. X
  21331. X           indent = *curr++;
  21332. X           margin = *curr++;
  21333. X
  21334. X           len -= 3;
  21335. X
  21336. X           col = indent;
  21337. X
  21338. X           while (1)
  21339. X          {
  21340. X          tok = find_token_length(ONLINE, curr, len, &size, &width);
  21341. X
  21342. X          if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF )
  21343. X             break;
  21344. X
  21345. X          if ( tok == TOK_PARA )
  21346. X             {
  21347. X             col = 0;   /* fake a nl */
  21348. X             ++lnum;
  21349. X             break;
  21350. X             }
  21351. X
  21352. X          if (tok == TOK_XONLINE || tok == TOK_XDOC )
  21353. X             {
  21354. X             curr += size;
  21355. X             len -= size;
  21356. X             continue;
  21357. X             }
  21358. X
  21359. X          /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */
  21360. X
  21361. X          if (col+width > SCREEN_WIDTH)
  21362. X             {            /* go to next line... */
  21363. X             if ( ++lnum >= SCREEN_DEPTH )
  21364. X                {        /* go to next page... */
  21365. X                add_page_break(t, start_margin, text, start, curr, num_links);
  21366. X                start = curr + ( (tok == TOK_SPACE) ? size : 0 );
  21367. X                start_margin = margin;
  21368. X                lnum = 0;
  21369. X                num_links = 0;
  21370. X                }
  21371. X             if ( tok == TOK_SPACE )
  21372. X                width = 0;   /* skip spaces at start of a line */
  21373. X
  21374. X             col = margin;
  21375. X             }
  21376. X
  21377. X          col += width;
  21378. X          curr += size;
  21379. X          len -= size;
  21380. X          }
  21381. X
  21382. X           skip_blanks = 0;
  21383. X           width = size = 0;
  21384. X           break;
  21385. X           }
  21386. X
  21387. X        case TOK_NL:
  21388. X           if (skip_blanks && col == 0)
  21389. X          {
  21390. X          start += size;
  21391. X          break;
  21392. X          }
  21393. X           ++lnum;
  21394. X           if ( lnum >= SCREEN_DEPTH || (col == 0 && lnum==SCREEN_DEPTH-1) )
  21395. X          {
  21396. X          add_page_break(t, start_margin, text, start, curr, num_links);
  21397. X          start = curr + size;
  21398. X          start_margin = -1;
  21399. X          lnum = 0;
  21400. X          num_links = 0;
  21401. X          skip_blanks = 1;
  21402. X          }
  21403. X           col = 0;
  21404. X           break;
  21405. X
  21406. X        case TOK_FF:
  21407. X           col = 0;
  21408. X           if (skip_blanks)
  21409. X          {
  21410. X          start += size;
  21411. X          break;
  21412. X          }
  21413. X           add_page_break(t, start_margin, text, start, curr, num_links);
  21414. X           start_margin = -1;
  21415. X           start = curr + size;
  21416. X           lnum = 0;
  21417. X           num_links = 0;
  21418. X           break;
  21419. X
  21420. X        case TOK_DONE:
  21421. X        case TOK_XONLINE:   /* skip */
  21422. X        case TOK_XDOC:      /* ignore */
  21423. X        case TOK_CENTER:    /* ignore */
  21424. X           break;
  21425. X
  21426. X        case TOK_LINK:
  21427. X           ++num_links;
  21428. X
  21429. X           /* fall-through */
  21430. X
  21431. X        default:    /* TOK_SPACE, TOK_LINK, TOK_WORD */
  21432. X           skip_blanks = 0;
  21433. X           break;
  21434. X
  21435. X        } /* switch */
  21436. X
  21437. X     curr += size;
  21438. X     len  -= size;
  21439. X     col  += width;
  21440. X     } /* while */
  21441. X
  21442. X      if (!skip_blanks)
  21443. X     add_page_break(t, start_margin, text, start, curr, num_links);
  21444. X
  21445. X      if (max_pages < t->num_page)
  21446. X     max_pages = t->num_page;
  21447. X
  21448. X      release_topic_text(t, 0);
  21449. X      } /* for */
  21450. X   }
  21451. X
  21452. X
  21453. X/*
  21454. X * paginate document stuff
  21455. X */
  21456. X
  21457. X
  21458. X#define CNUM           0
  21459. X#define TNUM           1
  21460. X#define LINK_DEST_WARN 2
  21461. X
  21462. X
  21463. Xtypedef struct
  21464. X   {
  21465. X   int        cnum,  /* must match above #defines so pd_get_info() will work */
  21466. X        tnum,
  21467. X        link_dest_warn;
  21468. X
  21469. X   char far *start;
  21470. X   CONTENT  *c;
  21471. X   LABEL    *lbl;
  21472. X
  21473. X   } PAGINATE_DOC_INFO;
  21474. X
  21475. X
  21476. XLABEL *find_next_label_by_topic(int t)
  21477. X   {
  21478. X   LABEL *temp, *g, *p;
  21479. X   int      ctr;
  21480. X
  21481. X   g = p = NULL;
  21482. X
  21483. X   for (temp=label, ctr=0; ctr<num_label; ctr++, temp++)
  21484. X      if ( temp->topic_num == t && temp->doc_page == -1 )
  21485. X     {
  21486. X     g = temp;
  21487. X     break;
  21488. X     }
  21489. X      else if (temp->topic_num > t)
  21490. X     break;
  21491. X
  21492. X   for (temp=plabel, ctr=0; ctr<num_plabel; ctr++, temp++)
  21493. X      if ( temp->topic_num == t && temp->doc_page == -1 )
  21494. X     {
  21495. X     p = temp;
  21496. X     break;
  21497. X     }
  21498. X      else if (temp->topic_num > t)
  21499. X     break;
  21500. X
  21501. X   if ( p == NULL )
  21502. X      return (g);
  21503. X
  21504. X   else if ( g == NULL )
  21505. X      return (p);
  21506. X
  21507. X   else
  21508. X      return ( (g->topic_off < p->topic_off) ? g : p );
  21509. X   }
  21510. X
  21511. X
  21512. Xvoid set_hot_link_doc_page(void)
  21513. X   /*
  21514. X    * Find doc_page for all hot-links.
  21515. X    */
  21516. X   {
  21517. X   LINK  *l;
  21518. X   LABEL *lbl;
  21519. X   int      lctr;
  21520. X   int      t;
  21521. X
  21522. X   for (lctr=0, l=a_link; lctr<num_link; l++, lctr++)
  21523. X      {
  21524. X      switch ( l->type )
  21525. X     {
  21526. X     case 0:      /* name is the title of the topic */
  21527. X        t = find_topic_title(l->name);
  21528. X        if (t == -1)
  21529. X           {
  21530. X           src_cfname = l->srcfile;
  21531. X           srcline = l->srcline; /* pretend we are still in the source... */
  21532. X           error(0,"Cannot find implicit hot-link \"%s\".", l->name);
  21533. X           srcline = -1;  /* back to reality */
  21534. X           }
  21535. X        else
  21536. X           l->doc_page = topic[t].doc_page;
  21537. X        break;
  21538. X
  21539. X     case 1:  /* name is the name of a label */
  21540. X        lbl = find_label(l->name);
  21541. X        if (lbl == NULL)
  21542. X           {
  21543. X           src_cfname = l->srcfile;
  21544. X           srcline = l->srcline; /* pretend again */
  21545. X           error(0,"Cannot find explicit hot-link \"%s\".", l->name);
  21546. X           srcline = -1;
  21547. X           }
  21548. X        else
  21549. X           l->doc_page = lbl->doc_page;
  21550. X        break;
  21551. X
  21552. X     case 2:   /* special topics don't appear in the document */
  21553. X        break;
  21554. X     }
  21555. X      }
  21556. X   }
  21557. X
  21558. X
  21559. Xvoid set_content_doc_page(void)
  21560. X   /*
  21561. X    * insert page #'s in the DocContents
  21562. X    */
  21563. X   {
  21564. X   CONTENT *c;
  21565. X   TOPIC   *t;
  21566. X   char    *base;
  21567. X   int        tnum;
  21568. X   int        ctr;
  21569. X   char     buf[4];
  21570. X   int        len;
  21571. X
  21572. X   tnum = find_topic_title(DOCCONTENTS_TITLE);
  21573. X   assert(tnum>=0);
  21574. X   t = &topic[tnum];
  21575. X
  21576. X   base = get_topic_text(t);
  21577. X
  21578. X   for (ctr=1, c=contents+1; ctr<num_contents; ctr++, c++)
  21579. X      {
  21580. X      assert(c->doc_page>=1);
  21581. X      sprintf(buf, "%d", c->doc_page);
  21582. X      len = strlen(buf);
  21583. X      assert(len<=3);
  21584. X      memcpy(base+c->page_num_pos+(3-len), buf, len);
  21585. X      }
  21586. X
  21587. X   release_topic_text(t, 1);
  21588. X   }
  21589. X
  21590. X
  21591. Xint pd_get_info(int cmd, PD_INFO *pd, int *info)
  21592. X   {         /* this funtion also used by print_document() */
  21593. X   CONTENT *c;
  21594. X
  21595. X   switch (cmd)
  21596. X      {
  21597. X      case PD_GET_CONTENT:
  21598. X     if ( ++info[CNUM] >= num_contents )
  21599. X        return (0);
  21600. X     c = &contents[info[CNUM]];
  21601. X     info[TNUM] = -1;
  21602. X     pd->id       = c->id;
  21603. X     pd->title    = c->name;
  21604. X     pd->new_page = (c->flags & CF_NEW_PAGE) ? 1 : 0;
  21605. X     return (1);
  21606. X
  21607. X      case PD_GET_TOPIC:
  21608. X     c = &contents[info[CNUM]];
  21609. X     if ( ++info[TNUM] >= c->num_topic )
  21610. X        return (0);
  21611. X     pd->curr = get_topic_text( &topic[c->topic_num[info[TNUM]]] );
  21612. X     pd->len = topic[c->topic_num[info[TNUM]]].text_len;
  21613. X     return (1);
  21614. X
  21615. X      case PD_GET_LINK_PAGE:
  21616. X         if ( a_link[getint(pd->s)].doc_page == -1 )
  21617. X        {
  21618. X        if ( info[LINK_DEST_WARN] )
  21619. X           {
  21620. X               src_cfname = a_link[getint(pd->s)].srcfile;
  21621. X               srcline    = a_link[getint(pd->s)].srcline;
  21622. X           warn(0,"Hot-link destination is not in the document.");
  21623. X           srcline = -1;
  21624. X           }
  21625. X        return (0);
  21626. X        }
  21627. X         pd->i = a_link[getint(pd->s)].doc_page;
  21628. X     return (1);
  21629. X
  21630. X      case PD_RELEASE_TOPIC:
  21631. X     c = &contents[info[CNUM]];
  21632. X     release_topic_text(&topic[c->topic_num[info[TNUM]]], 0);
  21633. X     return (1);
  21634. X
  21635. X      default:
  21636. X     return (0);
  21637. X      }
  21638. X   }
  21639. X
  21640. X
  21641. Xint paginate_doc_output(int cmd, PD_INFO *pd, PAGINATE_DOC_INFO *info)
  21642. X   {
  21643. X   switch (cmd)
  21644. X      {
  21645. X      case PD_FOOTING:
  21646. X      case PD_PRINT:
  21647. X      case PD_PRINTN:
  21648. X      case PD_PRINT_SEC:
  21649. X     return (1);
  21650. X
  21651. X      case PD_HEADING:
  21652. X     ++num_doc_pages;
  21653. X     return (1);
  21654. X
  21655. X      case PD_START_SECTION:
  21656. X     info->c = &contents[info->cnum];
  21657. X     return (1);
  21658. X
  21659. X      case PD_START_TOPIC:
  21660. X     info->start = pd->curr;
  21661. X     info->lbl = find_next_label_by_topic(info->c->topic_num[info->tnum]);
  21662. X     return (1);
  21663. X
  21664. X      case PD_SET_SECTION_PAGE:
  21665. X     info->c->doc_page = pd->pnum;
  21666. X     return (1);
  21667. X
  21668. X      case PD_SET_TOPIC_PAGE:
  21669. X     topic[info->c->topic_num[info->tnum]].doc_page = pd->pnum;
  21670. X     return (1);
  21671. X
  21672. X      case PD_PERIODIC:
  21673. X     while ( info->lbl != NULL && (unsigned)(pd->curr - info->start) >= info->lbl->topic_off)
  21674. X        {
  21675. X        info->lbl->doc_page = pd->pnum;
  21676. X        info->lbl = find_next_label_by_topic(info->c->topic_num[info->tnum]);
  21677. X        }
  21678. X     return (1);
  21679. X
  21680. X      default:
  21681. X     return (0);
  21682. X      }
  21683. X   }
  21684. X
  21685. X
  21686. Xvoid paginate_document(void)
  21687. X   {
  21688. X   PAGINATE_DOC_INFO info;
  21689. X
  21690. X   if (num_contents == 0)
  21691. X      return ;
  21692. X
  21693. X   msg("Paginating document.");
  21694. X
  21695. X   info.cnum = info.tnum = -1;
  21696. X   info.link_dest_warn = 1;
  21697. X
  21698. X   process_document((PD_FUNC)pd_get_info, (PD_FUNC)paginate_doc_output, &info);
  21699. X
  21700. X   set_hot_link_doc_page();
  21701. X   set_content_doc_page();
  21702. X   }
  21703. X
  21704. X
  21705. X/*
  21706. X * label sorting stuff
  21707. X */
  21708. X
  21709. X
  21710. Xint fcmp_LABEL(VOIDCONSTPTR a, VOIDCONSTPTR b)
  21711. X   {
  21712. X   char *an = ((LABEL *)a)->name,
  21713. X        *bn = ((LABEL *)b)->name;
  21714. X   int     diff;
  21715. X
  21716. X   /* compare the names, making sure that the index goes first */
  21717. X
  21718. X   if ( (diff=strcmp(an,bn)) == 0 )
  21719. X      return (0);
  21720. X
  21721. X   if ( strcmp(an, INDEX_LABEL) == 0 )
  21722. X      return (-1);
  21723. X
  21724. X   if ( strcmp(bn, INDEX_LABEL) == 0 )
  21725. X      return (1);
  21726. X
  21727. X   return ( diff );
  21728. X   }
  21729. X
  21730. X
  21731. Xvoid sort_labels(void)
  21732. X   {
  21733. X   qsort(label,  num_label,  sizeof(LABEL), fcmp_LABEL);
  21734. X   qsort(plabel, num_plabel, sizeof(LABEL), fcmp_LABEL);
  21735. X   }
  21736. X
  21737. X
  21738. X/*
  21739. X * file write stuff.
  21740. X */
  21741. X
  21742. X
  21743. Xint compare_files(FILE *f1, FILE *f2) /* returns TRUE if different */
  21744. X   {
  21745. X   if ( filelength(fileno(f1)) != filelength(fileno(f2)) )
  21746. X      return (1);   /* different if sizes are not the same */
  21747. X
  21748. X   while ( !feof(f1) && !feof(f2) )
  21749. X      if ( getc(f1) != getc(f2) )
  21750. X     return (1);
  21751. X
  21752. X   return ( ( feof(f1) && feof(f2) ) ? 0 : 1);
  21753. X   }
  21754. X
  21755. X
  21756. Xvoid _write_hdr(char *fname, FILE *file)
  21757. X   {
  21758. X   int ctr;
  21759. X   char nfile[MAXFILE],
  21760. X        next[MAXEXT];
  21761. X
  21762. X   FNSPLIT(fname, NULL, NULL, nfile, next);
  21763. X   fprintf(file, "\n/*\n * %s%s\n", nfile, next);
  21764. X   FNSPLIT(src_fname, NULL, NULL, nfile, next);
  21765. X   fprintf(file, " *\n * Contains #defines for help.\n *\n");
  21766. X   fprintf(file, " * Generated by HC from: %s%s\n *\n */\n\n\n", nfile, next);
  21767. X
  21768. X   fprintf(file, "/* current help file version */\n");
  21769. X   fprintf(file, "\n");
  21770. X   fprintf(file, "#define %-32s %3d\n", "HELP_VERSION", version);
  21771. X   fprintf(file, "\n\n");
  21772. X
  21773. X   fprintf(file, "/* labels */\n\n");
  21774. X
  21775. X   for (ctr=0; ctr<num_label; ctr++)
  21776. X      if (label[ctr].name[0] != '@')  /* if it's not a local label... */
  21777. X     {
  21778. X     fprintf(file, "#define %-32s %3d", label[ctr].name, ctr);
  21779. X     if ( strcmp(label[ctr].name, INDEX_LABEL) == 0 )
  21780. X        fprintf(file, "        /* index */");
  21781. X     fprintf(file, "\n");
  21782. X     }
  21783. X
  21784. X   fprintf(file, "\n\n");
  21785. X   }
  21786. X
  21787. X
  21788. Xvoid write_hdr(char *fname)
  21789. X   {
  21790. X   FILE *temp,
  21791. X        *hdr;
  21792. X
  21793. X   hdr = fopen(fname, "rt");
  21794. X
  21795. X   if (hdr == NULL)
  21796. X      {         /* if no prev. hdr file generate a new one */
  21797. X      hdr = fopen(fname, "wt");
  21798. X      if (hdr == NULL)
  21799. X     fatal(0,"Cannot create \"%s\".", fname);
  21800. X      msg("Writing: %s", fname);
  21801. X      _write_hdr(fname, hdr);
  21802. X      fclose(hdr);
  21803. X      notice("FRACTINT must be re-compiled.");
  21804. X      return ;
  21805. X      }
  21806. X
  21807. X   msg("Comparing: %s", fname);
  21808. X
  21809. X   temp = fopen(TEMP_FNAME, "wt");
  21810. X
  21811. X   if (temp == NULL)
  21812. X      fatal(0,"Cannot create temporary file: \"%s\".", TEMP_FNAME);
  21813. X
  21814. X   _write_hdr(fname, temp);
  21815. X
  21816. X   fclose(temp);
  21817. X   temp = fopen(TEMP_FNAME, "rt");
  21818. X
  21819. X   if (temp == NULL)
  21820. X      fatal(0,"Cannot open temporary file: \"%s\".", TEMP_FNAME);
  21821. X
  21822. X   if ( compare_files(temp, hdr) )   /* if they are different... */
  21823. X      {
  21824. X      msg("Updating: %s", fname);
  21825. X      fclose(temp);
  21826. X      fclose(hdr);
  21827. X      unlink(fname);           /* delete the old hdr file */
  21828. X      rename(TEMP_FNAME, fname);   /* rename the temp to the hdr file */
  21829. X      notice("FRACTINT must be re-compiled.");
  21830. X      }
  21831. X   else
  21832. X      {   /* if they are the same leave the original alone. */
  21833. X      fclose(temp);
  21834. X      fclose(hdr);
  21835. X      unlink(TEMP_FNAME);      /* delete the temp */
  21836. X      }
  21837. X   }
  21838. X
  21839. X
  21840. Xvoid calc_offsets(void)    /* calc file offset to each topic */
  21841. X   {
  21842. X   int        t;
  21843. X   TOPIC   *tp;
  21844. X   long     offset;
  21845. X   CONTENT *cp;
  21846. X   int        c;
  21847. X
  21848. X   /* NOTE: offsets do NOT include 6 bytes for signature & version! */
  21849. X
  21850. X   offset = sizeof(int) +           /* max_pages */
  21851. X            sizeof(int) +           /* max_links */
  21852. X            sizeof(int) +           /* num_topic */
  21853. X            sizeof(int) +           /* num_label */
  21854. X            sizeof(int) +           /* num_contents */
  21855. X            sizeof(int) +           /* num_doc_pages */
  21856. X            num_topic*sizeof(long) +/* offsets to each topic */
  21857. X            num_label*2*sizeof(int);/* topic_num/topic_off for all public labels */
  21858. X
  21859. X   for (c=0, cp=contents; c<num_contents; c++, cp++)
  21860. X      offset += sizeof(int) +       /* flags */
  21861. X            1 +            /* id length */
  21862. X            strlen(cp->id) +    /* id text */
  21863. X            1 +            /* name length */
  21864. X            strlen(cp->name) +  /* name text */
  21865. X            1 +            /* number of topics */
  21866. X                cp->num_topic*sizeof(int);    /* topic numbers */
  21867. X
  21868. X   for (t=0, tp=topic; t<num_topic; t++, tp++)
  21869. X      {
  21870. X      tp->offset = offset;
  21871. X      offset += (long)sizeof(int) + /* topic flags */
  21872. X                sizeof(int) +       /* number of pages */
  21873. X                tp->num_page*3*sizeof(int) +   /* page offset, length & starting margin */
  21874. X            1 +            /* length of title */
  21875. X            tp->title_len +     /* title */
  21876. X                sizeof(int) +       /* length of text */
  21877. X            tp->text_len;        /* text */
  21878. X      }
  21879. X
  21880. X   }
  21881. X
  21882. X
  21883. Xvoid insert_real_link_info(char *curr, unsigned len)
  21884. X   /*
  21885. X    * Replaces link indexes in the help text with topic_num, topic_off and
  21886. X    * doc_page info.
  21887. X    */
  21888. X   {
  21889. X   int         size;
  21890. X   int         tok;
  21891. X   LINK     *l;
  21892. X
  21893. X   while (len > 0)
  21894. X      {
  21895. X      tok = find_token_length(0, curr, len, &size, NULL);
  21896. X
  21897. X      if ( tok == TOK_LINK )
  21898. X     {
  21899. X         l = &a_link[ getint(curr+1) ];
  21900. X         setint(curr+1,l->topic_num);
  21901. X         setint(curr+1+sizeof(int),l->topic_off);
  21902. X         setint(curr+1+2*sizeof(int),l->doc_page);
  21903. X     }
  21904. X
  21905. X      len -= size;
  21906. X      curr += size;
  21907. X      }
  21908. X   }
  21909. X
  21910. X
  21911. Xvoid _write_help(FILE *file)
  21912. X   {
  21913. X   int             t, p, l, c;
  21914. X   char             *text;
  21915. X   TOPIC            *tp;
  21916. X   CONTENT            *cp;
  21917. X   struct help_sig_info  hs;
  21918. X
  21919. X   /* write the signature and version */
  21920. X
  21921. X   hs.sig = HELP_SIG; /* Edit line 17 of helpcom.h if this is a syntax error */
  21922. X   hs.version = version;
  21923. X
  21924. X   fwrite(&hs, sizeof(long)+sizeof(int), 1, file);
  21925. X
  21926. X   /* write max_pages & max_links */
  21927. X
  21928. X   putw(max_pages, file);
  21929. X   putw(max_links, file);
  21930. X
  21931. X   /* write num_topic, num_label and num_contents */
  21932. X
  21933. X   putw(num_topic, file);
  21934. X   putw(num_label, file);
  21935. X   putw(num_contents, file);
  21936. X
  21937. X   /* write num_doc_page */
  21938. X
  21939. X   putw(num_doc_pages, file);
  21940. X
  21941. X   /* write the offsets to each topic */
  21942. X
  21943. X   for (t=0; t<num_topic; t++) 
  21944. X      fwrite(&topic[t].offset, sizeof(long), 1, file);
  21945. X
  21946. X   /* write all public labels */
  21947. X
  21948. X   for (l=0; l<num_label; l++)
  21949. X      {
  21950. X      putw(label[l].topic_num, file);
  21951. X      putw(label[l].topic_off, file);
  21952. X      }
  21953. X
  21954. X   /* write contents */
  21955. X
  21956. X   for (c=0, cp=contents; c<num_contents; c++, cp++)
  21957. X      {
  21958. X      putw(cp->flags, file);
  21959. X
  21960. X      t = strlen(cp->id);
  21961. X      putc((BYTE)t, file);
  21962. X      fwrite(cp->id, 1, t, file);
  21963. X
  21964. X      t = strlen(cp->name);
  21965. X      putc((BYTE)t, file);
  21966. X      fwrite(cp->name, 1, t, file);
  21967. X
  21968. X      putc((BYTE)cp->num_topic, file);
  21969. X      fwrite(cp->topic_num, sizeof(int), cp->num_topic, file);
  21970. X      }
  21971. X
  21972. X   /* write topics */
  21973. X
  21974. X   for (t=0, tp=topic; t<num_topic; t++, tp++)
  21975. X      {
  21976. X      /* write the topics flags */
  21977. X
  21978. X      putw(tp->flags, file);
  21979. X
  21980. X      /* write offset, length and starting margin for each page */
  21981. X
  21982. X      putw(tp->num_page, file);
  21983. X      for (p=0; p<tp->num_page; p++)
  21984. X     {
  21985. X     putw(tp->page[p].offset, file);
  21986. X     putw(tp->page[p].length, file);
  21987. X     putw(tp->page[p].margin, file);
  21988. X     }
  21989. X
  21990. X      /* write the help title */
  21991. X
  21992. X      putc((BYTE)tp->title_len, file);
  21993. X      fwrite(tp->title, 1, tp->title_len, file);
  21994. X
  21995. X      /* insert hot-link info & write the help text */
  21996. X
  21997. X      text = get_topic_text(tp);
  21998. X
  21999. X      if ( !(tp->flags & TF_DATA) )   /* don't process data topics... */
  22000. X     insert_real_link_info(text, tp->text_len);
  22001. X
  22002. X      putw(tp->text_len, file);
  22003. X      fwrite(text, 1, tp->text_len, file);
  22004. X
  22005. X      release_topic_text(tp, 0);  /* don't save the text even though        */
  22006. X                  /* insert_real_link_info() modified it    */
  22007. X                  /* because we don't access the info after */
  22008. X                  /* this.                    */
  22009. X
  22010. X      }
  22011. X   }
  22012. X
  22013. X
  22014. Xvoid write_help(char *fname)
  22015. X   {
  22016. X   FILE *hlp;
  22017. X
  22018. X   hlp = fopen(fname, "wb");
  22019. X
  22020. X   if (hlp == NULL)
  22021. X      fatal(0,"Cannot create .HLP file: \"%s\".", fname);
  22022. X
  22023. X   msg("Writing: %s", fname);
  22024. X
  22025. X   _write_help(hlp);
  22026. X
  22027. X   fclose(hlp);
  22028. X   }
  22029. X
  22030. X
  22031. X/*
  22032. X * print document stuff.
  22033. X */
  22034. X
  22035. X
  22036. Xtypedef struct
  22037. X   {
  22038. X
  22039. X   /*
  22040. X    * Note: Don't move these first three or pd_get_info will work not
  22041. X    *        correctly.
  22042. X    */
  22043. X
  22044. X   int        cnum;
  22045. X   int        tnum;
  22046. X   int        link_dest_warn;   /* = 0 */
  22047. X
  22048. X   FILE    *file;
  22049. X   int        margin;
  22050. X   int        start_of_line;
  22051. X   int        spaces;
  22052. X   } PRINT_DOC_INFO;
  22053. X
  22054. X
  22055. Xvoid printerc(PRINT_DOC_INFO *info, int c, int n)
  22056. X   {
  22057. X   while ( n-- > 0 )
  22058. X      {
  22059. X      if (c==' ')
  22060. X     ++info->spaces;
  22061. X
  22062. X      else if (c=='\n' || c=='\f')
  22063. X     {
  22064. X     info->start_of_line = 1;
  22065. X     info->spaces = 0;   /* strip spaces before a new-line */
  22066. X     putc(c, info->file);
  22067. X     }
  22068. X
  22069. X      else
  22070. X     {
  22071. X     if (info->start_of_line)
  22072. X        {
  22073. X        info->spaces += info->margin;
  22074. X        info->start_of_line = 0;
  22075. X        }
  22076. X
  22077. X     while (info->spaces > 0)
  22078. X        {
  22079. X        fputc(' ', info->file);
  22080. X        --info->spaces;
  22081. X        }
  22082. X
  22083. X     fputc(c, info->file);
  22084. X     }
  22085. X      }
  22086. X   }
  22087. X
  22088. X
  22089. Xvoid printers(PRINT_DOC_INFO *info, char far *s, int n)
  22090. X   {
  22091. X   if (n > 0)
  22092. X      {
  22093. X      while ( n-- > 0 )
  22094. X     printerc(info, *s++, 1);
  22095. X      }
  22096. X   else
  22097. X      {
  22098. X      while ( *s != '\0' )
  22099. X     printerc(info, *s++, 1);
  22100. X      }
  22101. X   }
  22102. X
  22103. X
  22104. Xint print_doc_output(int cmd, PD_INFO *pd, PRINT_DOC_INFO *info)
  22105. X   {
  22106. X   switch (cmd)
  22107. X      {
  22108. X      case PD_HEADING:
  22109. X     {
  22110. X     char buff[20];
  22111. X
  22112. X     info->margin = 0;
  22113. X     printers(info, "\n                     Fractint Version xx.xx                     Page ", 0);
  22114. X     sprintf(buff, "%d\n\n", pd->pnum);
  22115. X     printers(info, buff, 0);
  22116. X     info->margin = PAGE_INDENT;
  22117. X     return (1);
  22118. X     }
  22119. X
  22120. X      case PD_FOOTING:
  22121. X     info->margin = 0;
  22122. X     printerc(info, '\f', 1);
  22123. X     info->margin = PAGE_INDENT;
  22124. X     return (1);
  22125. X
  22126. X      case PD_PRINT:
  22127. X     printers(info, pd->s, pd->i);
  22128. X     return (1);
  22129. X
  22130. X      case PD_PRINTN:
  22131. X     printerc(info, *pd->s, pd->i);
  22132. X     return (1);
  22133. X
  22134. X      case PD_PRINT_SEC:
  22135. X     info->margin = TITLE_INDENT;
  22136. X     if (pd->id[0] != '\0')
  22137. X        {
  22138. X        printers(info, pd->id, 0);
  22139. X        printerc(info, ' ', 1);
  22140. X        }
  22141. X     printers(info, pd->title, 0);
  22142. X     printerc(info, '\n', 1);
  22143. X     info->margin = PAGE_INDENT;
  22144. X     return (1);
  22145. X
  22146. X      case PD_START_SECTION:
  22147. X      case PD_START_TOPIC:
  22148. X      case PD_SET_SECTION_PAGE:
  22149. X      case PD_SET_TOPIC_PAGE:
  22150. X      case PD_PERIODIC:
  22151. X     return (1);
  22152. X
  22153. X      default:
  22154. X     return (0);
  22155. X      }
  22156. X   }
  22157. X
  22158. X
  22159. Xvoid print_document(char *fname)
  22160. X   {
  22161. X   PRINT_DOC_INFO info;
  22162. X
  22163. X   if (num_contents == 0)
  22164. X      fatal(0,".SRC has no DocContents.");
  22165. X
  22166. X   msg("Printing to: %s", fname);
  22167. X
  22168. X   info.cnum = info.tnum = -1;
  22169. X   info.link_dest_warn = 0;
  22170. X
  22171. X   if ( (info.file = fopen(fname, "wt")) == NULL )
  22172. X      fatal(0,"Couldn't create \"%s\"", fname);
  22173. X
  22174. X   info.margin = PAGE_INDENT;
  22175. X   info.start_of_line = 1;
  22176. X   info.spaces = 0;
  22177. X
  22178. X   process_document((PD_FUNC)pd_get_info, (PD_FUNC)print_doc_output, &info);
  22179. X
  22180. X   fclose(info.file);
  22181. X   }
  22182. X
  22183. X
  22184. X/*
  22185. X * compiler status and memory usage report stuff.
  22186. X */
  22187. X
  22188. X
  22189. Xvoid report_memory(void)
  22190. X   {
  22191. X   long string = 0,   /* bytes in strings */
  22192. X        text   = 0,   /* bytes in topic text (stored on disk) */
  22193. X        data   = 0,   /* bytes in active data structure */
  22194. X        dead   = 0;   /* bytes in unused data structure */
  22195. X   int  ctr, ctr2;
  22196. X
  22197. X   for (ctr=0; ctr<num_topic; ctr++)
  22198. X      {
  22199. X      data   += sizeof(TOPIC);
  22200. X      string += topic[ctr].title_len;
  22201. X      text   += topic[ctr].text_len;
  22202. X      data   += topic[ctr].num_page * sizeof(PAGE);
  22203. X
  22204. X      dead   += (PAGE_ALLOC_SIZE-(topic[ctr].num_page%PAGE_ALLOC_SIZE)) * sizeof(PAGE);
  22205. X      }
  22206. X
  22207. X   for (ctr=0; ctr<num_link; ctr++)
  22208. X      {
  22209. X      data += sizeof(LINK);
  22210. X      string += strlen(a_link[ctr].name);
  22211. X      }
  22212. X
  22213. X   if (num_link > 0)
  22214. X      dead += (LINK_ALLOC_SIZE-(num_link%LINK_ALLOC_SIZE)) * sizeof(LINK);
  22215. X
  22216. X   for (ctr=0; ctr<num_label; ctr++)
  22217. X      {
  22218. X      data   += sizeof(LABEL);
  22219. X      string += strlen(label[ctr].name) + 1;
  22220. X      }
  22221. X
  22222. X   if (num_label > 0)
  22223. X      dead += (LABEL_ALLOC_SIZE-(num_label%LABEL_ALLOC_SIZE)) * sizeof(LABEL);
  22224. X
  22225. X   for (ctr=0; ctr<num_plabel; ctr++)
  22226. X      {
  22227. X      data   += sizeof(LABEL);
  22228. X      string += strlen(plabel[ctr].name) + 1;
  22229. X      }
  22230. X
  22231. X   if (num_plabel > 0)
  22232. X      dead += (LABEL_ALLOC_SIZE-(num_plabel%LABEL_ALLOC_SIZE)) * sizeof(LABEL);
  22233. X
  22234. X   for (ctr=0; ctr<num_contents; ctr++)
  22235. X      {
  22236. X      int t;
  22237. X
  22238. X      t = ( MAX_CONTENT_TOPIC - contents[ctr].num_topic ) *
  22239. X      ( sizeof(contents[0].is_label[0])   +
  22240. X        sizeof(contents[0].topic_name[0]) +
  22241. X        sizeof(contents[0].topic_num[0])     );
  22242. X      data += sizeof(CONTENT) - t;
  22243. X      dead += t;
  22244. X      string += strlen(contents[ctr].id) + 1;
  22245. X      string += strlen(contents[ctr].name) + 1;
  22246. X      for (ctr2=0; ctr2<contents[ctr].num_topic; ctr2++)
  22247. X     string += strlen(contents[ctr].topic_name[ctr2]) + 1;
  22248. X      }
  22249. X
  22250. X   dead += (CONTENTS_ALLOC_SIZE-(num_contents%CONTENTS_ALLOC_SIZE)) * sizeof(CONTENT);
  22251. X
  22252. X   printf("\n");
  22253. X   printf("Memory Usage:\n");
  22254. X   printf("%8ld Bytes in buffers.\n", (long)BUFFER_SIZE);
  22255. X   printf("%8ld Bytes in strings.\n", string);
  22256. X   printf("%8ld Bytes in data.\n", data);
  22257. X   printf("%8ld Bytes in dead space.\n", dead);
  22258. X   printf("--------\n");
  22259. X   printf("%8ld Bytes total.\n", (long)BUFFER_SIZE+string+data+dead);
  22260. X   printf("\n");
  22261. X   printf("Disk Usage:\n");
  22262. X   printf("%8ld Bytes in topic text.\n", text);
  22263. X   }
  22264. X
  22265. X
  22266. Xvoid report_stats(void)
  22267. X   {
  22268. X   int  pages = 0;
  22269. X   int        t;
  22270. X
  22271. X   for (t=0; t<num_topic; t++)
  22272. X      pages += topic[t].num_page;
  22273. X
  22274. X   printf("\n");
  22275. X   printf("Statistics:\n");
  22276. X   printf("%8d Topics\n", num_topic);
  22277. X   printf("%8d Links\n", num_link);
  22278. X   printf("%8d Labels\n", num_label);
  22279. X   printf("%8d Private labels\n", num_plabel);
  22280. X   printf("%8d Table of contents (DocContent) entries\n", num_contents);
  22281. X   printf("%8d Online help pages\n", pages);
  22282. X   printf("%8d Document pages\n", num_doc_pages);
  22283. X   }
  22284. X
  22285. X
  22286. X/*
  22287. X * add/delete help from .EXE functions.
  22288. X */
  22289. X
  22290. X
  22291. Xvoid add_hlp_to_exe(char *hlp_fname, char *exe_fname)
  22292. X   {
  22293. X   int                exe,   /* handles */
  22294. X                hlp;
  22295. X   long             len,
  22296. X                count;
  22297. X   int                size;
  22298. X   struct help_sig_info hs;
  22299. X
  22300. X   if ( (exe=open(exe_fname, O_RDWR|O_BINARY)) == -1 )
  22301. X      fatal(0,"Unable to open \"%s\"", exe_fname);
  22302. X
  22303. X   if ( (hlp=open(hlp_fname, O_RDONLY|O_BINARY)) == -1 )
  22304. X      fatal(0,"Unable to open \"%s\"", hlp_fname);
  22305. X
  22306. X   msg("Appending %s to %s", hlp_fname, exe_fname);
  22307. X
  22308. X   /* first, check and see if any help is currently installed */
  22309. X
  22310. X   lseek(exe, filelength(exe) - sizeof(struct help_sig_info), SEEK_SET);
  22311. X
  22312. X   read(exe, (char *)&hs, 10);
  22313. X
  22314. X   if ( hs.sig == HELP_SIG )
  22315. X      warn(0,"Overwriting previous help. (Version=%d)", hs.version);
  22316. X   else
  22317. X      hs.base = filelength(exe);
  22318. X
  22319. X   /* now, let's see if their help file is for real (and get the version) */
  22320. X
  22321. X   read(hlp, (char *)&hs, sizeof(long)+sizeof(int));
  22322. X
  22323. X   if (hs.sig != HELP_SIG )
  22324. X      fatal(0,"Help signature not found in %s", hlp_fname);
  22325. X
  22326. X   msg("Help file %s Version=%d", hlp_fname, hs.version);
  22327. X
  22328. X   /* append the help stuff, overwriting old help (if any) */
  22329. X
  22330. X   lseek(exe, hs.base, SEEK_SET);
  22331. X
  22332. X   len = filelength(hlp) - sizeof(long) - sizeof(int); /* adjust for the file signature & version */
  22333. X
  22334. X   for (count=0; count<len; )
  22335. X      {
  22336. X      size = (int) min((long)BUFFER_SIZE, len-count);
  22337. X      read(hlp, buffer, size);
  22338. X      write(exe, buffer, size);
  22339. X      count += size;
  22340. X      }
  22341. X
  22342. X   /* add on the signature, version and offset */
  22343. X
  22344. X   write(exe, (char *)&hs, 10);
  22345. X
  22346. X   chsize(exe, lseek(exe,0L,SEEK_CUR));/* truncate if old help was longer */
  22347. X
  22348. X   close(exe);
  22349. X   close(hlp);
  22350. X   }
  22351. X
  22352. X
  22353. Xvoid delete_hlp_from_exe(char *exe_fname)
  22354. X   {
  22355. X   int     exe;   /* file handle */
  22356. X   struct help_sig_info hs;
  22357. X
  22358. X   if ( (exe=open(exe_fname, O_RDWR|O_BINARY)) == -1 )
  22359. X      fatal(0,"Unable to open \"%s\"", exe_fname);
  22360. X
  22361. X   msg("Deleting help from %s", exe_fname);
  22362. X
  22363. X   /* see if any help is currently installed */
  22364. X
  22365. X#ifndef XFRACT
  22366. X   lseek(exe, filelength(exe) - 10, SEEK_SET);
  22367. X   read(exe, (char *)&hs, 10);
  22368. X#else
  22369. X   lseek(exe, filelength(exe) - 12, SEEK_SET);
  22370. X   read(exe, (char *)&hs, 12);
  22371. X#endif
  22372. X
  22373. X   if ( hs.sig == HELP_SIG )
  22374. X      {
  22375. X      chsize(exe, hs.base);   /* truncate at the start of the help */
  22376. X      close(exe);
  22377. X      }
  22378. X   else
  22379. X      {
  22380. X      close(exe);
  22381. X      fatal(0,"No help found in %s", exe_fname);
  22382. X      }
  22383. X   }
  22384. X
  22385. X
  22386. X/*
  22387. X * command-line parser, etc.
  22388. X */
  22389. X
  22390. X
  22391. X#define MODE_COMPILE 1
  22392. X#define MODE_PRINT   2
  22393. X#define MODE_APPEND  3
  22394. X#define MODE_DELETE  4
  22395. X
  22396. X
  22397. Xint main(int argc, char *argv[])
  22398. X   {
  22399. X   int      show_stats = 0,
  22400. X      show_mem   = 0;
  22401. X   int      mode         = 0;
  22402. X
  22403. X   char **arg;
  22404. X   char   fname1[81],
  22405. X      fname2[81];
  22406. X   char   swappath[81];
  22407. X
  22408. X   fname1[0] = fname2[0] = swappath[0] = 0;
  22409. X
  22410. X   printf("HC - FRACTINT Help Compiler.\n\n");
  22411. X
  22412. X   buffer = malloc(BUFFER_SIZE);
  22413. X
  22414. X   if (buffer == NULL)
  22415. X      fatal(0,"Not enough memory to allocate buffer.");
  22416. X
  22417. X   for (arg= &argv[1]; argc>1; argc--, arg++)
  22418. X      {
  22419. X      switch ( (*arg)[0] )
  22420. X     {
  22421. X     case '/':
  22422. X     case '-':
  22423. X        switch ( (*arg)[1] )
  22424. X           {
  22425. X           case 'c':
  22426. X          if (mode == 0)
  22427. X             mode = MODE_COMPILE;
  22428. X          else
  22429. X             fatal(0,"Cannot have /c with /a, /d or /p");
  22430. X          break;
  22431. X
  22432. X           case 'a':
  22433. X          if (mode == 0)
  22434. X             mode = MODE_APPEND;
  22435. X          else
  22436. X             fatal(0,"Cannot have /a with /c, /d or /p");
  22437. X          break;
  22438. X
  22439. X           case 'd':
  22440. X          if (mode == 0)
  22441. X             mode = MODE_DELETE;
  22442. X          else
  22443. X             fatal(0,"Cannot have /d with /c, /a or /p");
  22444. X          break;
  22445. X
  22446. X           case 'p':
  22447. X          if (mode == 0)
  22448. X             mode = MODE_PRINT;
  22449. X          else
  22450. X             fatal(0,"Cannot have /p with /c, /a or /d");
  22451. X          break;
  22452. X
  22453. X           case 'm':
  22454. X          if (mode == MODE_COMPILE)
  22455. X             show_mem = 1;
  22456. X          else
  22457. X             fatal(0,"/m switch allowed only when compiling (/c)");
  22458. X          break;
  22459. X
  22460. X           case 's':
  22461. X          if (mode == MODE_COMPILE)
  22462. X             show_stats = 1;
  22463. X          else
  22464. X             fatal(0,"/s switch allowed only when compiling (/c)");
  22465. X          break;
  22466. X
  22467. X           case 'r':
  22468. X          if (mode == MODE_COMPILE || mode == MODE_PRINT)
  22469. X             strcpy(swappath, (*arg)+2);
  22470. X          else
  22471. X             fatal(0,"/r switch allowed when compiling (/c) or printing (/p)");
  22472. X          break;
  22473. X
  22474. X           case 'q':
  22475. X          quiet_mode = 1;
  22476. X          break;
  22477. X
  22478. X           default:
  22479. X          fatal(0,"Bad command-line switch /%c", (*arg)[1]);
  22480. X          break;
  22481. X           }
  22482. X        break;
  22483. X
  22484. X     default:   /* assume it is a fname */
  22485. X        if (fname1[0] == '\0')
  22486. X           strcpy(fname1, *arg);
  22487. X        else if (fname2[0] == '\0')
  22488. X           strcpy(fname2, *arg);
  22489. X        else
  22490. X           fatal(0,"Unexpected command-line argument \"%s\"", *arg);
  22491. X        break;
  22492. X     } /* switch */
  22493. X      } /* for */
  22494. X
  22495. X   strupr(fname1);
  22496. X   strupr(fname2);
  22497. X   strupr(swappath);
  22498. X
  22499. X   switch (mode)
  22500. X      {
  22501. X      case 0:
  22502. X         printf( "To compile a .SRC file:\n");
  22503. X         printf( "      HC /c [/s] [/m] [/r[path]] [src_file]\n");
  22504. X         printf( "         /s       = report statistics.\n");
  22505. X         printf( "         /m       = report memory usage.\n");
  22506. X         printf( "         /r[path] = set swap file path.\n");
  22507. X         printf( "         src_file = .SRC file.  Default is \"%s\"\n", DEFAULT_SRC_FNAME);
  22508. X         printf( "To print a .SRC file:\n");
  22509. X         printf( "      HC /p [/r[path]] [src_file] [out_file]\n");
  22510. X         printf( "         /r[path] = set swap file path.\n");
  22511. X         printf( "         src_file = .SRC file.  Default is \"%s\"\n", DEFAULT_SRC_FNAME);
  22512. X         printf( "         out_file = Filename to print to. Default is \"%s\"\n",
  22513. X         DEFAULT_DOC_FNAME);
  22514. X         printf( "To append a .HLP file to an .EXE file:\n");
  22515. X         printf( "      HC /a [hlp_file] [exe_file]\n");
  22516. X         printf( "         hlp_file = .HLP file.  Default is \"%s\"\n", DEFAULT_HLP_FNAME);
  22517. X         printf( "         exe_file = .EXE file.  Default is \"%s\"\n", DEFAULT_EXE_FNAME);
  22518. X         printf( "To delete help info from an .EXE file:\n");
  22519. X         printf( "      HC /d [exe_file]\n");
  22520. X         printf( "         exe_file = .EXE file.  Default is \"%s\"\n", DEFAULT_EXE_FNAME);
  22521. X         printf( "\n");
  22522. X         printf( "Use \"/q\" for quiet mode. (No status messages.)\n");
  22523. X     break;
  22524. X
  22525. X      case MODE_COMPILE:
  22526. X     if (fname2[0] != '\0')
  22527. X        fatal(0,"Unexpected command-line argument \"%s\"", fname2);
  22528. X
  22529. X     strcpy(src_fname, (fname1[0]=='\0') ? DEFAULT_SRC_FNAME : fname1);
  22530. X
  22531. X     strcat(swappath, SWAP_FNAME);
  22532. X
  22533. X     if ( (swapfile=fopen(swappath, "w+b")) == NULL )
  22534. X        fatal(0,"Cannot create swap file \"%s\"", swappath);
  22535. X     swappos = 0;
  22536. X
  22537. X     read_src(src_fname);
  22538. X
  22539. X     if (hdr_fname[0] == '\0')
  22540. X        error(0,"No .H file defined.  (Use \"~HdrFile=\")");
  22541. X     if (hlp_fname[0] == '\0')
  22542. X        error(0,"No .HLP file defined.  (Use \"~HlpFile=\")");
  22543. X     if (version == -1)
  22544. X        warn(0,"No help version has been defined.  (Use \"~Version=\")");
  22545. X
  22546. X     /* order of these is very important... */
  22547. X
  22548. X     make_hot_links();  /* do even if errors since it may report */
  22549. X                /* more... */
  22550. X
  22551. X     if ( !errors )     paginate_online();
  22552. X     if ( !errors )     paginate_document();
  22553. X     if ( !errors )     calc_offsets();
  22554. X     if ( !errors )     sort_labels();
  22555. X     if ( !errors )     write_hdr(hdr_fname);
  22556. X     if ( !errors )     write_help(hlp_fname);
  22557. X
  22558. X     if ( show_stats )
  22559. X        report_stats();
  22560. X
  22561. X     if ( show_mem )
  22562. X        report_memory();
  22563. X
  22564. X     if ( errors || warnings )
  22565. X        report_errors();
  22566. X
  22567. X     fclose(swapfile);
  22568. X     remove(swappath);
  22569. X
  22570. X     break;
  22571. X
  22572. X      case MODE_PRINT:
  22573. X     strcpy(src_fname, (fname1[0]=='\0') ? DEFAULT_SRC_FNAME : fname1);
  22574. X
  22575. X     strcat(swappath, SWAP_FNAME);
  22576. X
  22577. X     if ( (swapfile=fopen(swappath, "w+b")) == NULL )
  22578. X        fatal(0,"Cannot create swap file \"%s\"", swappath);
  22579. X     swappos = 0;
  22580. X
  22581. X     read_src(src_fname);
  22582. X
  22583. X     make_hot_links();
  22584. X
  22585. X     if ( !errors )     paginate_document();
  22586. X     if ( !errors )     print_document( (fname2[0]=='\0') ? DEFAULT_DOC_FNAME : fname2 );
  22587. X
  22588. X     if ( errors || warnings )
  22589. X        report_errors();
  22590. X
  22591. X     fclose(swapfile);
  22592. X     remove(swappath);
  22593. X
  22594. X     break;
  22595. X
  22596. X      case MODE_APPEND:
  22597. X     add_hlp_to_exe( (fname1[0]=='\0') ? DEFAULT_HLP_FNAME : fname1,
  22598. X             (fname2[0]=='\0') ? DEFAULT_EXE_FNAME : fname2);
  22599. X     break;
  22600. X
  22601. X      case MODE_DELETE:
  22602. X     if (fname2[0] != '\0')
  22603. X        fatal(0,"Unexpected argument \"%s\"", fname2);
  22604. X     delete_hlp_from_exe((fname1[0]=='\0') ? DEFAULT_EXE_FNAME : fname1);
  22605. X     break;
  22606. X      }
  22607. X
  22608. X   free(buffer);
  22609. X
  22610. X   return ( errors );   /* return the number of errors */
  22611. X   }
  22612. X
  22613. X
  22614. SHAR_EOF
  22615. $TOUCH -am 1028230093 hc.c &&
  22616. chmod 0644 hc.c ||
  22617. echo "restore of hc.c failed"
  22618. set `wc -c hc.c`;Wc_c=$1
  22619. if test "$Wc_c" != "83237"; then
  22620.     echo original size 83237, current size $Wc_c
  22621. fi
  22622. # ============= hcmplx.c ==============
  22623. echo "x - extracting hcmplx.c (Text)"
  22624. sed 's/^X//' << 'SHAR_EOF' > hcmplx.c &&
  22625. X/* some hyper complex functions */
  22626. X#include "fractint.h"
  22627. X#include "mpmath.h"
  22628. X
  22629. Xvoid HComplexMult(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out)
  22630. X{
  22631. X    /* it is possible to reoganize this code and reduce the multiplies
  22632. X        from 16 to 10, but on my 486 it is SLOWER !!! so I left it
  22633. X        like this - Tim Wegner */
  22634. X    out->x = arg1->x * arg2->x - arg1->y * arg2->y 
  22635. X           - arg1->z * arg2->z + arg1->t * arg2->t;
  22636. X    out->y = arg1->y * arg2->x + arg1->x * arg2->y 
  22637. X           - arg1->t * arg2->z - arg1->z * arg2->t;
  22638. X    out->z = arg1->z * arg2->x - arg1->t * arg2->y 
  22639. X           + arg1->x * arg2->z - arg1->y * arg2->t;
  22640. X    out->t = arg1->t * arg2->x + arg1->z * arg2->y 
  22641. X           + arg1->y * arg2->z + arg1->x * arg2->t;
  22642. X}
  22643. X
  22644. Xvoid HComplexSqr(_HCMPLX *arg, _HCMPLX *out)
  22645. X{
  22646. X    out->x = arg->x * arg->x - arg->y * arg->y 
  22647. X           - arg->z * arg->z + arg->t * arg->t;
  22648. X    out->y = 2 * arg->x * arg->y - 2 * arg->z * arg->t;
  22649. X    out->z = 2 * arg->z * arg->x - 2 * arg->t * arg->y; 
  22650. X    out->t = 2 * arg->t * arg->x + 2 * arg->z * arg->y;
  22651. X}
  22652. X
  22653. Xint HComplexInv(_HCMPLX *arg, _HCMPLX *out)
  22654. X{
  22655. X   double det, mod, xt_minus_yz;
  22656. X   
  22657. X   det = (sqr(arg->x - arg->t) + sqr(arg->y + arg->z))* 
  22658. X           (sqr(arg->x + arg->t) + sqr(arg->y - arg->z));
  22659. X
  22660. X   if(det == 0.0)
  22661. X      return(-1);
  22662. X   mod = sqr(arg->x) + sqr(arg->y) + sqr(arg->z) + sqr(arg->t);
  22663. X   xt_minus_yz = arg->x * arg->t - arg->y * arg->z;
  22664. X
  22665. X   out->x = ( arg->x * mod - 2 * arg->t * xt_minus_yz)/det;
  22666. X   out->y = (-arg->y * mod - 2 * arg->z * xt_minus_yz)/det;
  22667. X   out->z = (-arg->z * mod - 2 * arg->y * xt_minus_yz)/det;
  22668. X   out->t = ( arg->t * mod - 2 * arg->x * xt_minus_yz)/det;
  22669. X   return(0);
  22670. X}
  22671. X
  22672. Xvoid HComplexAdd(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out)
  22673. X{
  22674. X    out->x = arg1->x + arg2->x;
  22675. X    out->y = arg1->y + arg2->y;
  22676. X    out->z = arg1->z + arg2->z;
  22677. X    out->t = arg1->t + arg2->t;
  22678. X}
  22679. X
  22680. Xvoid HComplexSub(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out)
  22681. X{
  22682. X    out->x = arg1->x - arg2->x;
  22683. X    out->y = arg1->y - arg2->y;
  22684. X    out->z = arg1->z - arg2->z;
  22685. X    out->t = arg1->t - arg2->t;
  22686. X}
  22687. X
  22688. Xvoid HComplexMinus(_HCMPLX *arg1, _HCMPLX *out)
  22689. X{
  22690. X    out->x = -arg1->x;
  22691. X    out->y = -arg1->y;
  22692. X    out->z = -arg1->z;
  22693. X    out->t = -arg1->t;
  22694. X}
  22695. X
  22696. X/* extends the unary function f to *h1 */
  22697. Xvoid HComplexTrig0(_HCMPLX *h, _HCMPLX *out)
  22698. X{
  22699. X    /* This is the whole beauty of Hypercomplex numbers - *ANY* unary 
  22700. X       complex valued function of a complex variable can easily 
  22701. X       be generalized to hypercomplex numbers */
  22702. X    
  22703. X    _CMPLX a,b, resulta,resultb;
  22704. X    double t,s;
  22705. X    
  22706. X    /* convert to duplex form */
  22707. X    a.x = h->x - h->t;    
  22708. X    a.y = h->y + h->z;    
  22709. X    b.x = h->x + h->t;    
  22710. X    b.y = h->y - h->z;    
  22711. X
  22712. X    /* apply function to each part */
  22713. X    CMPLXtrig0(a,resulta);
  22714. X    CMPLXtrig0(b,resultb);
  22715. X    
  22716. X    /* convert back */    
  22717. X    out->x =  (resulta.x + resultb.x)/2;
  22718. X    out->y =  (resulta.y + resultb.y)/2;
  22719. X    out->z =  (resulta.y - resultb.y)/2;
  22720. X    out->t =  (resultb.x - resulta.x)/2;
  22721. X}
  22722. SHAR_EOF
  22723. $TOUCH -am 1028230093 hcmplx.c &&
  22724. chmod 0644 hcmplx.c ||
  22725. echo "restore of hcmplx.c failed"
  22726. set `wc -c hcmplx.c`;Wc_c=$1
  22727. if test "$Wc_c" != "2946"; then
  22728.     echo original size 2946, current size $Wc_c
  22729. fi
  22730. # ============= help.c ==============
  22731. echo "x - extracting help.c (Text)"
  22732. sed 's/^X//' << 'SHAR_EOF' > help.c &&
  22733. X/*
  22734. X * help.c
  22735. X *
  22736. X * This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  22737. X *
  22738. X *
  22739. X * Revision history:
  22740. X *
  22741. X *   2-26-90  EAN     Initial version.
  22742. X *
  22743. X *
  22744. X */
  22745. X
  22746. X
  22747. X#ifndef TEST /* kills all those assert macros in production version */
  22748. X#define NDEBUG
  22749. X#endif
  22750. X
  22751. X#define INCLUDE_COMMON    /* include common code in helpcom.h */
  22752. X
  22753. X
  22754. X#include <stdio.h>
  22755. X#include <stdlib.h>
  22756. X#ifndef XFRACT
  22757. X#include <io.h>
  22758. X#include <dos.h>
  22759. X#endif
  22760. X#include <fcntl.h>
  22761. X#include <string.h>
  22762. X#include <time.h>
  22763. X#include <assert.h>
  22764. X#include <sys/types.h>
  22765. X#include <sys/stat.h>
  22766. X#ifdef XFRACT
  22767. X#include <unistd.h>
  22768. X#endif
  22769. X#include "fractint.h"
  22770. X#include "helpcom.h"
  22771. X#include "helpdefs.h"
  22772. X#include "prototyp.h"
  22773. X
  22774. X
  22775. X#define MAX_HIST       16         /* number of pages we'll remember */
  22776. X
  22777. X#define ALT_F1         1104
  22778. X#define BACK_TAB     1015
  22779. X#define BACKSPACE        8
  22780. X
  22781. X#define ACTION_CALL        0         /* values returned by help_topic() */
  22782. X#define ACTION_PREV        1
  22783. X#define ACTION_PREV2        2         /* special - go back two topics */
  22784. X#define ACTION_INDEX        3
  22785. X#define ACTION_QUIT        4
  22786. X
  22787. X#define F_HIST            (1<<0)   /* flags for help_topic() */
  22788. X#define F_INDEX         (1<<1)
  22789. X
  22790. X#define MAX_PAGE_SIZE        (80*25)  /* no page of text may be larger */
  22791. X
  22792. X#define TEXT_START_ROW        2         /* start print the help text here */
  22793. X
  22794. X
  22795. Xtypedef struct
  22796. X   {
  22797. X   BYTE r, c;
  22798. X   int         width;
  22799. X   unsigned     offset;
  22800. X   int         topic_num;
  22801. X   unsigned     topic_off;
  22802. X   } LINK;
  22803. X
  22804. X
  22805. Xtypedef struct
  22806. X   {
  22807. X   int        topic_num;
  22808. X   unsigned topic_off;
  22809. X   } LABEL;
  22810. X
  22811. X
  22812. Xtypedef struct
  22813. X   {
  22814. X   unsigned     offset;
  22815. X   unsigned     len;
  22816. X   int         margin;
  22817. X   } PAGE;
  22818. X
  22819. X
  22820. Xtypedef struct
  22821. X   {
  22822. X   int        topic_num;
  22823. X   unsigned topic_off;
  22824. X   int        link;
  22825. X   } HIST;
  22826. X
  22827. X
  22828. Xstruct help_sig_info
  22829. X   {
  22830. X   unsigned long sig;
  22831. X   int         version;
  22832. X   unsigned long base;       /* only if added to fractint.exe */
  22833. X   } ;
  22834. X
  22835. X
  22836. Xvoid print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg );
  22837. Xstatic int print_doc_msg_func(int pnum, int num_pages);
  22838. X
  22839. X
  22840. X
  22841. Xvoid help_overlay(void) { }
  22842. X
  22843. X
  22844. X
  22845. X/* stuff from fractint */
  22846. X
  22847. Xextern int  lookatmouse;
  22848. Xextern long timer_start;
  22849. Xextern int  helpmode;
  22850. Xextern int  text_type;     /* 0=real color text, 1=640x200x2, 2=??mono?? */
  22851. Xextern int  textcbase;
  22852. Xextern int  textrbase;
  22853. Xextern SEGTYPE  extraseg;
  22854. Xextern int  release;
  22855. X
  22856. Xint  putstringcenter (int row, int col, int width, int attr, char far *msg);
  22857. Xvoid helptitle         (void);
  22858. Xvoid stackscreen     (void);
  22859. Xvoid unstackscreen   (void);
  22860. Xvoid findpath         (char *filename, char *path);
  22861. X
  22862. X
  22863. Xstatic int          help_file = -1; /* help file handle */
  22864. Xstatic long          base_off;       /* offset to help info in help file */
  22865. Xstatic int          max_links;      /* max # of links in any page */
  22866. Xstatic int          max_pages;      /* max # of pages in any topic */
  22867. Xstatic int          num_label;      /* number of labels */
  22868. Xstatic int          num_topic;      /* number of topics */
  22869. Xstatic int          curr_hist = 0;  /* current pos in history */
  22870. X
  22871. X/* these items alloc'ed in init_help... */
  22872. X
  22873. Xstatic long     far *topic_offset;       /* 4*num_topic */
  22874. Xstatic LABEL     far *label;           /* 4*num_label */
  22875. Xstatic HIST     far *hist;           /* 6*MAX_HIST (96 bytes) */
  22876. X
  22877. X/* these items alloc'ed only while help is active... */
  22878. X
  22879. Xstatic char      far *buffer;         /* MAX_PAGE_SIZE (2048 bytes) */
  22880. Xstatic LINK      far *link_table;     /* 10*max_links */
  22881. Xstatic PAGE      far *page_table;     /* 4*max_pages  */
  22882. X
  22883. X
  22884. Xstatic void help_seek(long pos)
  22885. X   {
  22886. X   lseek(help_file, base_off+pos, SEEK_SET);
  22887. X   }
  22888. X
  22889. X
  22890. Xstatic void displayc(int row, int col, int color, int ch)
  22891. X   {
  22892. X#ifndef XFRACT
  22893. X   static char *s = "?";
  22894. X#else
  22895. X   static char s[] = "?";
  22896. X#endif
  22897. X
  22898. X   if (text_type == 1)     /* if 640x200x2 mode */
  22899. X      {
  22900. X      /*
  22901. X       * This is REALLY ugly, but it works.  Non-current links (ones that
  22902. X       * would be bold if 640x200 supported it) are in upper-case and the
  22903. X       * current item is inversed.
  22904. X       *
  22905. X       */
  22906. X
  22907. X      if (color & INVERSE)
  22908. X     color = (signed int)INVERSE;
  22909. X      else if (color & BRIGHT)
  22910. X     {
  22911. X     color = 0;   /* normal */
  22912. X     if (ch>='a' && ch<='z')
  22913. X        ch += 'A' - 'a';
  22914. X     }
  22915. X      else
  22916. X     color = 0;   /* normal */
  22917. X      }
  22918. X
  22919. X   s[0] = ch;
  22920. X   putstring(row, col, color, s);
  22921. X   }
  22922. X
  22923. X
  22924. Xstatic void display_text(int row, int col, int color, char far *text, unsigned len)
  22925. X   {
  22926. X   while (len-- > 0)
  22927. X      {
  22928. X      if (*text == CMD_LITERAL)
  22929. X     {
  22930. X     ++text;
  22931. X     --len;
  22932. X     }
  22933. X      displayc(row, col++, color, *text++);
  22934. X      }
  22935. X   }
  22936. X
  22937. X
  22938. Xstatic void display_parse_text(char far *text, unsigned len, int start_margin, int *num_link, LINK far *link)
  22939. X   {
  22940. X   char far  *curr;
  22941. X   int          row, col;
  22942. X   int          tok;
  22943. X   int          size,
  22944. X          width;
  22945. X
  22946. X   textcbase = SCREEN_INDENT;
  22947. X   textrbase = TEXT_START_ROW;
  22948. X
  22949. X   curr = text;
  22950. X   row = 0;
  22951. X   col = 0;
  22952. X
  22953. X   size = width = 0;
  22954. X
  22955. X   if (start_margin >= 0)
  22956. X      tok = TOK_PARA;
  22957. X   else
  22958. X      tok = -1;
  22959. X
  22960. X   while ( 1 )
  22961. X      {
  22962. X      switch ( tok )
  22963. X     {
  22964. X     case TOK_PARA:
  22965. X        {
  22966. X        int indent,
  22967. X        margin;
  22968. X
  22969. X        if (size > 0)
  22970. X           {
  22971. X           ++curr;
  22972. X           indent = *curr++;
  22973. X           margin = *curr++;
  22974. X           len  -= 3;
  22975. X           }
  22976. X        else
  22977. X           {
  22978. X           indent = start_margin;
  22979. X           margin = start_margin;
  22980. X           }
  22981. X
  22982. X        col = indent;
  22983. X
  22984. X        while (1)
  22985. X           {
  22986. X           tok = find_token_length(ONLINE, curr, len, &size, &width);
  22987. X
  22988. X           if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF )
  22989. X          break;
  22990. X
  22991. X           if (tok == TOK_PARA)
  22992. X          {
  22993. X          col = 0;   /* fake a new-line */
  22994. X          row++;
  22995. X          break;
  22996. X          }
  22997. X
  22998. X           if (tok == TOK_XONLINE || tok == TOK_XDOC)
  22999. X          {
  23000. X          curr += size;
  23001. X          len  -= size;
  23002. X          continue;
  23003. X          }
  23004. X
  23005. X           /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */
  23006. X
  23007. X           if (col+width > SCREEN_WIDTH)
  23008. X          {         /* go to next line... */
  23009. X          col = margin;
  23010. X          ++row;
  23011. X
  23012. X          if ( tok == TOK_SPACE )
  23013. X             width = 0;   /* skip spaces at start of a line */
  23014. X          }
  23015. X
  23016. X           if (tok == TOK_LINK)
  23017. X          {
  23018. X          display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
  23019. X          if (num_link != NULL)
  23020. X             {
  23021. X             link[*num_link].r           = row;
  23022. X             link[*num_link].c           = col;
  23023. X                     link[*num_link].topic_num = getint(curr+1);
  23024. X                     link[*num_link].topic_off = getint(curr+1+sizeof(int));
  23025. X                     link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
  23026. X             link[*num_link].width     = width;
  23027. X             ++(*num_link);
  23028. X             }
  23029. X          }
  23030. X           else if (tok == TOK_WORD )
  23031. X          display_text(row, col, C_HELP_BODY, curr, width);
  23032. X
  23033. X           col += width;
  23034. X           curr += size;
  23035. X           len -= size;
  23036. X           }
  23037. X
  23038. X        width = size = 0;
  23039. X        break;
  23040. X        }
  23041. X
  23042. X     case TOK_CENTER:
  23043. X        col = find_line_width(ONLINE, curr, len);
  23044. X        col = (SCREEN_WIDTH-col)/2;
  23045. X        if (col < 0)
  23046. X           col = 0;
  23047. X        break;
  23048. X
  23049. X     case TOK_NL:
  23050. X        col = 0;
  23051. X        ++row;
  23052. X        break;
  23053. X
  23054. X     case TOK_LINK:
  23055. X            display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
  23056. X        if (num_link != NULL)
  23057. X           {
  23058. X           link[*num_link].r     = row;
  23059. X           link[*num_link].c     = col;
  23060. X               link[*num_link].topic_num = getint(curr+1);
  23061. X               link[*num_link].topic_off = getint(curr+1+sizeof(int));
  23062. X               link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
  23063. X           link[*num_link].width     = width;
  23064. X           ++(*num_link);
  23065. X           }
  23066. X        break;
  23067. X
  23068. X     case TOK_XONLINE:  /* skip */
  23069. X     case TOK_FF:        /* ignore */
  23070. X     case TOK_XDOC:     /* ignore */
  23071. X     case TOK_DONE:
  23072. X     case TOK_SPACE:
  23073. X        break;
  23074. X
  23075. X     case TOK_WORD:
  23076. X        display_text(row, col, C_HELP_BODY, curr, width);
  23077. X        break;
  23078. X     } /* switch */
  23079. X
  23080. X      curr += size;
  23081. X      len  -= size;
  23082. X      col  += width;
  23083. X
  23084. X      if (len == 0)
  23085. X     break;
  23086. X
  23087. X      tok = find_token_length(ONLINE, curr, len, &size, &width);
  23088. X      } /* while */
  23089. X
  23090. X   textcbase = 0;
  23091. X   textrbase = 0;
  23092. X   }
  23093. X
  23094. X
  23095. Xstatic void color_link(LINK far *link, int color)
  23096. X   {
  23097. X   textcbase = SCREEN_INDENT;
  23098. X   textrbase = TEXT_START_ROW;
  23099. X
  23100. X   if (text_type == 1)     /* if 640x200x2 mode */
  23101. X      display_text(link->r, link->c, color, buffer+link->offset, link->width);
  23102. X   else
  23103. X      setattr(link->r, link->c, color, link->width);
  23104. X
  23105. X   textcbase = 0;
  23106. X   textrbase = 0;
  23107. X   }
  23108. X
  23109. X
  23110. X
  23111. X/* #define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR_KEYS,name), putstring(-1,-1,C_HELP_INSTR," "descrip"  ") */
  23112. X#ifndef XFRACT
  23113. X#define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR,name); putstring(-1,-1,C_HELP_INSTR,":"descrip"  ")
  23114. X#else
  23115. X#define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR,name);\
  23116. Xputstring(-1,-1,C_HELP_INSTR,":");\
  23117. Xputstring(-1,-1,C_HELP_INSTR,descrip);\
  23118. Xputstring(-1,-1,C_HELP_INSTR,"  ")
  23119. X#endif
  23120. X
  23121. X
  23122. Xstatic void helpinstr(void)
  23123. X   {
  23124. X   int ctr;
  23125. X
  23126. X   for (ctr=0; ctr<80; ctr++)
  23127. X     putstring(24, ctr, C_HELP_INSTR, " ");
  23128. X
  23129. X   movecursor(24, 1);
  23130. X   PUT_KEY("F1",               "Index");
  23131. X#ifndef XFRACT
  23132. X   PUT_KEY("\030\031\033\032", "Select");
  23133. X#else
  23134. X   PUT_KEY("K J H L", "Select");
  23135. X#endif
  23136. X   PUT_KEY("Enter",            "Go to");
  23137. X   PUT_KEY("Backspace",        "Last topic");
  23138. X   PUT_KEY("Escape",           "Exit help");
  23139. X   }
  23140. X
  23141. X
  23142. Xstatic void printinstr(void)
  23143. X   {
  23144. X   int ctr;
  23145. X
  23146. X   for (ctr=0; ctr<80; ctr++)
  23147. X     putstring(24, ctr, C_HELP_INSTR, " ");
  23148. X
  23149. X   movecursor(24, 1);
  23150. X   PUT_KEY("Escape", "Abort");
  23151. X   }
  23152. X
  23153. X
  23154. X#undef PUT_KEY
  23155. X
  23156. X
  23157. Xstatic 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)
  23158. X   {
  23159. X   char temp[9];
  23160. X
  23161. X   helptitle();
  23162. X   helpinstr();
  23163. X   setattr(2, 0, C_HELP_BODY, 80*22);
  23164. X   putstringcenter(1, 0, 80, C_HELP_HDG, title);
  23165. X   sprintf(temp, "%2d of %d", page+1, num_pages);
  23166. X#ifndef XFRACT
  23167. X   putstring(1, 79-(6 + ((num_pages>=10)?2:1)), C_HELP_INSTR, temp);
  23168. X#else
  23169. X   /* Some systems (Ultrix) mess up if you write to column 80 */
  23170. X   putstring(1, 78-(6 + ((num_pages>=10)?2:1)), C_HELP_INSTR, temp);
  23171. X#endif
  23172. X
  23173. X   if (text != NULL)
  23174. X      display_parse_text(text, text_len, start_margin, num_link, link);
  23175. X
  23176. X   movecursor(25, 80);     /* hide cursor */
  23177. X   }
  23178. X
  23179. X
  23180. X
  23181. X/*
  23182. X * int overlap(int a, int a2, int b, int b2);
  23183. X *
  23184. X * If a, a2, b, and b2 are points on a line, this function returns the
  23185. X * distance of intersection between a-->a2 and b-->b2.    If there is no
  23186. X * intersection between the lines this function will return a negative number
  23187. X * representing the distance between the two lines.
  23188. X *
  23189. X * There are six possible cases of intersection between the lines:
  23190. X *
  23191. X *            a              a2
  23192. X *            |              |
  23193. X *     b     b2    |              |       b     b2
  23194. X *     |---(1)---|    |              |       |---(2)---|
  23195. X *            |              |
  23196. X *        b    |     b2      b       |      b2
  23197. X *        |------(3)----|       |------(4)-----|
  23198. X *            |              |
  23199. X *         b    |              |   b2
  23200. X *         |------+--------(5)----------+---|
  23201. X *            |              |
  23202. X *            |     b       b2      |
  23203. X *            |     |--(6)--|       |
  23204. X *            |              |
  23205. X *            |              |
  23206. X *
  23207. X */
  23208. X
  23209. X
  23210. Xstatic int overlap(int a, int a2, int b, int b2)
  23211. X   {
  23212. X   if ( b < a )
  23213. X      {
  23214. X      if ( b2 >= a2 )
  23215. X     return ( a2 - a );           /* case (5) */
  23216. X
  23217. X      return ( b2 - a );           /* case (1), case (3) */
  23218. X      }
  23219. X
  23220. X   if ( b2 <= a2 )
  23221. X      return ( b2 - b );           /* case (6) */
  23222. X
  23223. X   return ( a2 - b );               /* case (2), case (4) */
  23224. X   }
  23225. X
  23226. X
  23227. Xstatic int dist(int a, int b)
  23228. X   {
  23229. X   int t = a - b;
  23230. X
  23231. X   return (abs(t));
  23232. X   }
  23233. X
  23234. X
  23235. X#ifdef __TURBOC__
  23236. X#   pragma warn -def /* turn off "Possible use before definition" warning */
  23237. X#endif
  23238. X
  23239. X
  23240. X
  23241. X
  23242. Xstatic int find_link_updown(LINK far *link, int num_link, int curr_link, int up)
  23243. X   {
  23244. X   int         ctr,
  23245. X         curr_c2,
  23246. X         best_overlap,
  23247. X         temp_overlap;
  23248. X   LINK far *curr,
  23249. X    far *temp,
  23250. X    far *best;
  23251. X   int         temp_dist;
  23252. X
  23253. X   curr    = &link[curr_link];
  23254. X   best    = NULL;
  23255. X   curr_c2 = curr->c + curr->width - 1;
  23256. X
  23257. X   for (ctr=0, temp=link; ctr<num_link; ctr++, temp++)
  23258. X      {
  23259. X      if ( ctr != curr_link &&
  23260. X       ( (up && temp->r < curr->r) || (!up && temp->r > curr->r) ) )
  23261. X     {
  23262. X     temp_overlap = overlap(curr->c, curr_c2, temp->c, temp->c+temp->width-1);
  23263. X     /* if >= 3 lines between, prioritize on vertical distance: */
  23264. X     if ((temp_dist = dist(temp->r, curr->r)) >= 4)
  23265. X        temp_overlap -= temp_dist * 100;
  23266. X
  23267. X     if (best != NULL)
  23268. X        {
  23269. X        if ( best_overlap >= 0 && temp_overlap >= 0 )
  23270. X           {     /* if they're both under curr set to closest in y dir */
  23271. X           if ( dist(best->r, curr->r) > temp_dist )
  23272. X          best = NULL;
  23273. X           }
  23274. X        else
  23275. X           {
  23276. X           if ( best_overlap < temp_overlap )
  23277. X          best = NULL;
  23278. X           }
  23279. X        }
  23280. X
  23281. X     if (best == NULL)
  23282. X        {
  23283. X        best = temp;
  23284. X        best_overlap = temp_overlap;
  23285. X        }
  23286. X     }
  23287. X      }
  23288. X
  23289. X   return ( (best==NULL) ? -1 : (int)(best-link) );
  23290. X   }
  23291. X
  23292. X
  23293. Xstatic int find_link_leftright(LINK far *link, int num_link, int curr_link, int left)
  23294. X   {
  23295. X   int         ctr,
  23296. X         curr_c2,
  23297. X         best_c2,
  23298. X         temp_c2,
  23299. X         best_dist,
  23300. X         temp_dist;
  23301. X   LINK far *curr,
  23302. X    far *temp,
  23303. X    far *best;
  23304. X
  23305. X   curr    = &link[curr_link];
  23306. X   best    = NULL;
  23307. X   curr_c2 = curr->c + curr->width - 1;
  23308. X
  23309. X   for (ctr=0, temp=link; ctr<num_link; ctr++, temp++)
  23310. X      {
  23311. X      temp_c2 = temp->c + temp->width - 1;
  23312. X
  23313. X      if ( ctr != curr_link &&
  23314. X       ( (left && temp_c2 < curr->c) || (!left && temp->c > curr_c2) ) )
  23315. X     {
  23316. X     temp_dist = dist(curr->r, temp->r);
  23317. X
  23318. X     if (best != NULL)
  23319. X        {
  23320. X        if ( best_dist == 0 && temp_dist == 0 )  /* if both on curr's line... */
  23321. X           {
  23322. X           if ( (  left && dist(curr->c, best_c2) > dist(curr->c, temp_c2) ) ||
  23323. X            ( !left && dist(curr_c2, best->c) > dist(curr_c2, temp->c) ) )
  23324. X          best = NULL;
  23325. X           }
  23326. X        else
  23327. X           {
  23328. X           if ( best_dist >= temp_dist )   /* if temp is closer... */
  23329. X          best = NULL;
  23330. X           }
  23331. X        } /* if (best...) */
  23332. X
  23333. X     if (best == NULL)
  23334. X        {
  23335. X        best      = temp;
  23336. X        best_dist = temp_dist;
  23337. X        best_c2   = temp_c2;
  23338. X        }
  23339. X     }
  23340. X      } /* for */
  23341. X
  23342. X   return ( (best==NULL) ? -1 : (int)(best-link) );
  23343. X   }
  23344. X
  23345. X
  23346. X#ifdef __TURBOC__
  23347. X#   pragma warn .def   /* back to default */
  23348. X#   pragma warn -par   /* now turn off "Parameter not used" warning */
  23349. X#endif
  23350. X
  23351. X
  23352. Xstatic int find_link_key(LINK far *link, int num_link, int curr_link, int key)
  23353. X   {
  23354. X   switch (key)
  23355. X      {
  23356. X      case TAB:      return ( (curr_link>=num_link-1) ? -1 : curr_link+1 );
  23357. X      case BACK_TAB: return ( (curr_link<=0)          ? -1 : curr_link-1 );
  23358. X      default:         assert(0);  return (-1);
  23359. X      }
  23360. X   }
  23361. X
  23362. X
  23363. X#ifdef __TURBOC__
  23364. X#   pragma warn .par /* back to default */
  23365. X#endif
  23366. X
  23367. X
  23368. Xstatic int do_move_link(LINK far *link, int num_link, int *curr, int (*f)(LINK far *,int,int,int), int val)
  23369. X   {
  23370. X   int t;
  23371. X
  23372. X   if (num_link > 1)
  23373. X      {
  23374. X      if ( f == NULL )
  23375. X     t = val;
  23376. X      else
  23377. X     t = (*f)(link, num_link, *curr, val);
  23378. X
  23379. X      if ( t >= 0 && t != *curr )
  23380. X     {
  23381. X     color_link(&link[*curr], C_HELP_LINK);
  23382. X     *curr = t;
  23383. X     color_link(&link[*curr], C_HELP_CURLINK);
  23384. X     return (1);
  23385. X     }
  23386. X      }
  23387. X
  23388. X   return (0);
  23389. X   }
  23390. X
  23391. X
  23392. Xstatic int help_topic(HIST *curr, HIST *next, int flags)
  23393. X   {
  23394. X   int         len;
  23395. X   int         key;
  23396. X   int         num_pages;
  23397. X   int         num_link;
  23398. X   int         page;
  23399. X   int         curr_link;
  23400. X   char      title[81];
  23401. X   long      where;
  23402. X   int         draw_page;
  23403. X   int         action;
  23404. X   BYTE ch;
  23405. X
  23406. X   where     = topic_offset[curr->topic_num]+sizeof(int); /* to skip flags */
  23407. X   curr_link = curr->link;
  23408. X
  23409. X   help_seek(where);
  23410. X
  23411. X   read(help_file, (char *)&num_pages, sizeof(int));
  23412. X   assert(num_pages>0 && num_pages<=max_pages);
  23413. X
  23414. X   farread(help_file, (char far *)page_table, 3*sizeof(int)*num_pages);
  23415. X
  23416. X   read(help_file, &ch, 1);
  23417. X   len = ch;
  23418. X   assert(len<81);
  23419. X   read(help_file, (char *)title, len);
  23420. X   title[len] = '\0';
  23421. X
  23422. X   where += sizeof(int) + num_pages*3*sizeof(int) + 1 + len + sizeof(int);
  23423. X
  23424. X   for(page=0; page<num_pages; page++)
  23425. X      if (curr->topic_off >= page_table[page].offset &&
  23426. X      curr->topic_off <  page_table[page].offset+page_table[page].len )
  23427. X     break;
  23428. X
  23429. X   assert(page < num_pages);
  23430. X
  23431. X   action = -1;
  23432. X   draw_page = 2;
  23433. X
  23434. X   do
  23435. X      {
  23436. X      if (draw_page)
  23437. X     {
  23438. X     help_seek(where+page_table[page].offset);
  23439. X     farread(help_file, buffer, page_table[page].len);
  23440. X
  23441. X     num_link = 0;
  23442. X     display_page(title, buffer, page_table[page].len, page, num_pages,
  23443. X              page_table[page].margin, &num_link, link_table);
  23444. X
  23445. X     if (draw_page==2)
  23446. X        {
  23447. X        assert(num_link<=0 || (curr_link>=0 && curr_link<num_link));
  23448. X        }
  23449. X     else if (draw_page==3)
  23450. X        curr_link = num_link - 1;
  23451. X     else
  23452. X        curr_link = 0;
  23453. X
  23454. X     if (num_link > 0)
  23455. X        color_link(&link_table[curr_link], C_HELP_CURLINK);
  23456. X
  23457. X     draw_page = 0;
  23458. X     }
  23459. X
  23460. X      key = getakey();
  23461. X
  23462. X      switch(key)
  23463. X     {
  23464. X     case PAGE_DOWN:
  23465. X        if (page<num_pages-1)
  23466. X           {
  23467. X           page++;
  23468. X           draw_page = 1;
  23469. X           }
  23470. X        break;
  23471. X
  23472. X     case PAGE_UP:
  23473. X        if (page>0)
  23474. X           {
  23475. X           page--;
  23476. X           draw_page = 1;
  23477. X           }
  23478. X        break;
  23479. X
  23480. X     case HOME:
  23481. X        if ( page != 0 )
  23482. X           {
  23483. X           page = 0;
  23484. X           draw_page = 1;
  23485. X           }
  23486. X        else
  23487. X           do_move_link(link_table, num_link, &curr_link, NULL, 0);
  23488. X        break;
  23489. X
  23490. X     case END:
  23491. X        if ( page != num_pages-1 )
  23492. X           {
  23493. X           page = num_pages-1;
  23494. X           draw_page = 3;
  23495. X           }
  23496. X        else
  23497. X           do_move_link(link_table, num_link, &curr_link, NULL, num_link-1);
  23498. X        break;
  23499. X
  23500. X     case TAB:
  23501. X        if ( !do_move_link(link_table, num_link, &curr_link, find_link_key, key) &&
  23502. X         page<num_pages-1 )
  23503. X           {
  23504. X           ++page;
  23505. X           draw_page = 1;
  23506. X           }
  23507. X        break;
  23508. X
  23509. X     case BACK_TAB:
  23510. X        if ( !do_move_link(link_table, num_link, &curr_link, find_link_key, key) &&
  23511. X         page>0 )
  23512. X           {
  23513. X           --page;
  23514. X           draw_page = 3;
  23515. X           }
  23516. X        break;
  23517. X
  23518. X     case DOWN_ARROW:
  23519. X        if ( !do_move_link(link_table, num_link, &curr_link, find_link_updown, 0) &&
  23520. X         page<num_pages-1 )
  23521. X           {
  23522. X           ++page;
  23523. X           draw_page = 1;
  23524. X           }
  23525. X        break;
  23526. X
  23527. X     case UP_ARROW:
  23528. X        if ( !do_move_link(link_table, num_link, &curr_link, find_link_updown, 1) &&
  23529. X         page>0 )
  23530. X           {
  23531. X           --page;
  23532. X           draw_page = 3;
  23533. X           }
  23534. X        break;
  23535. X
  23536. X     case LEFT_ARROW:
  23537. X        do_move_link(link_table, num_link, &curr_link, find_link_leftright, 1);
  23538. X        break;
  23539. X
  23540. X     case RIGHT_ARROW:
  23541. X        do_move_link(link_table, num_link, &curr_link, find_link_leftright, 0);
  23542. X        break;
  23543. X
  23544. X     case ESC:       /* exit help */
  23545. X        action = ACTION_QUIT;
  23546. X        break;
  23547. X
  23548. X     case BACKSPACE:   /* prev topic */
  23549. X     case ALT_F1:
  23550. X        if (flags & F_HIST)
  23551. X           action = ACTION_PREV;
  23552. X        break;
  23553. X
  23554. X     case F1:    /* help index */
  23555. X        if (!(flags & F_INDEX))
  23556. X           action = ACTION_INDEX;
  23557. X        break;
  23558. X
  23559. X     case ENTER:
  23560. X     case ENTER_2:
  23561. X        if (num_link > 0)
  23562. X           {
  23563. X           next->topic_num = link_table[curr_link].topic_num;
  23564. X           next->topic_off = link_table[curr_link].topic_off;
  23565. X           action = ACTION_CALL;
  23566. X           }
  23567. X        break;
  23568. X     } /* switch */
  23569. X      }
  23570. X   while ( action == -1 );
  23571. X
  23572. X   curr->topic_off = page_table[page].offset;
  23573. X   curr->link       = curr_link;
  23574. X
  23575. X   return (action);
  23576. X   }
  23577. X
  23578. X
  23579. Xint help(int action)
  23580. X   {
  23581. X   static char far unknowntopic_msg[] = "Unknown Help Topic";
  23582. X   HIST      curr;
  23583. X   int         oldlookatmouse;
  23584. X   int         oldhelpmode;
  23585. X   int         flags;
  23586. X   HIST      next;
  23587. X
  23588. X   ENTER_OVLY(OVLY_HELP);
  23589. X
  23590. X   if (helpmode == -1)     /* is help disabled? */
  23591. X      {
  23592. X      EXIT_OVLY;
  23593. X      return (0);
  23594. X      }
  23595. X
  23596. X   if (help_file == -1)
  23597. X      {
  23598. X      buzzer(2);
  23599. X      EXIT_OVLY;
  23600. X      return (0);
  23601. X      }
  23602. X
  23603. X   buffer = farmemalloc((long)MAX_PAGE_SIZE + sizeof(LINK)*max_links +
  23604. X            sizeof(PAGE)*max_pages);
  23605. X
  23606. X   if (buffer == NULL)
  23607. X      {
  23608. X      buzzer(2);
  23609. X      EXIT_OVLY;
  23610. X      return (0);
  23611. X      }
  23612. X
  23613. X   link_table = (LINK far *)(&buffer[MAX_PAGE_SIZE]);
  23614. X   page_table = (PAGE far *)(&link_table[max_links]);
  23615. X
  23616. X   oldlookatmouse = lookatmouse;
  23617. X   lookatmouse = 0;
  23618. X   timer_start -= clock_ticks();
  23619. X   stackscreen();
  23620. X
  23621. X   if (helpmode >= 0)
  23622. X      {
  23623. X      next.topic_num = label[helpmode].topic_num;
  23624. X      next.topic_off = label[helpmode].topic_off;
  23625. X      }
  23626. X   else
  23627. X      {
  23628. X      next.topic_num = helpmode;
  23629. X      next.topic_off = 0;
  23630. X      }
  23631. X
  23632. X   oldhelpmode = helpmode;
  23633. X
  23634. X   if (curr_hist <= 0)
  23635. X      action = ACTION_CALL;  /* make sure it isn't ACTION_PREV! */
  23636. X
  23637. X   do
  23638. X      {
  23639. X      switch(action)
  23640. X     {
  23641. X     case ACTION_PREV2:
  23642. X        if (curr_hist > 0)
  23643. X           curr = hist[--curr_hist];
  23644. X
  23645. X        /* fall-through */
  23646. X
  23647. X     case ACTION_PREV:
  23648. X        if (curr_hist > 0)
  23649. X           curr = hist[--curr_hist];
  23650. X        break;
  23651. X
  23652. X     case ACTION_QUIT:
  23653. X        break;
  23654. X
  23655. X     case ACTION_INDEX:
  23656. X        next.topic_num = label[HELP_INDEX].topic_num;
  23657. X        next.topic_off = label[HELP_INDEX].topic_off;
  23658. X
  23659. X        /* fall-through */
  23660. X
  23661. X     case ACTION_CALL:
  23662. X        curr = next;
  23663. X        curr.link = 0;
  23664. X        break;
  23665. X     } /* switch */
  23666. X
  23667. X      flags = 0;
  23668. X      if (curr.topic_num == label[HELP_INDEX].topic_num)
  23669. X     flags |= F_INDEX;
  23670. X      if (curr_hist > 0)
  23671. X     flags |= F_HIST;
  23672. X
  23673. X      if ( curr.topic_num >= 0 )
  23674. X     action = help_topic(&curr, &next, flags);
  23675. X      else
  23676. X     {
  23677. X     if ( curr.topic_num == -100 )
  23678. X        {
  23679. X        print_document("FRACTINT.DOC", print_doc_msg_func, 1);
  23680. X        action = ACTION_PREV2;
  23681. X        }
  23682. X
  23683. X     else if ( curr.topic_num == -101 )
  23684. X        action = ACTION_PREV2;
  23685. X
  23686. X     else
  23687. X        {
  23688. X        display_page(unknowntopic_msg, NULL, 0, 0, 1, 0, NULL, NULL);
  23689. X        action = -1;
  23690. X        while (action == -1)
  23691. X           {
  23692. X           switch (getakey())
  23693. X          {
  23694. X          case ESC:     action = ACTION_QUIT;    break;
  23695. X          case ALT_F1:     action = ACTION_PREV;    break;
  23696. X          case F1:     action = ACTION_INDEX; break;
  23697. X          } /* switch */
  23698. X           } /* while */
  23699. X        }
  23700. X     } /* else */
  23701. X
  23702. X      if ( action != ACTION_PREV && action != ACTION_PREV2 )
  23703. X     {
  23704. X     if (curr_hist >= MAX_HIST)
  23705. X        {
  23706. X        int ctr;
  23707. X
  23708. X        for (ctr=0; ctr<MAX_HIST-1; ctr++)
  23709. X           hist[ctr] = hist[ctr+1];
  23710. X
  23711. X        curr_hist = MAX_HIST-1;
  23712. X        }
  23713. X     hist[curr_hist++] = curr;
  23714. X     }
  23715. X      }
  23716. X   while (action != ACTION_QUIT);
  23717. X
  23718. X   farmemfree((BYTE far *)buffer);
  23719. X
  23720. X   unstackscreen();
  23721. X   lookatmouse = oldlookatmouse;
  23722. X   helpmode = oldhelpmode;
  23723. X   timer_start += clock_ticks();
  23724. X
  23725. X   EXIT_OVLY;
  23726. X   return(0);
  23727. X   }
  23728. X
  23729. X
  23730. X
  23731. Xstatic int dos_version(void)
  23732. X   {
  23733. X#ifndef XFRACT
  23734. X   union REGS r;
  23735. X
  23736. X   r.x.ax = 0x3000;
  23737. X   intdos(&r, &r);
  23738. X
  23739. X   return (r.h.al*100 + r.h.ah);
  23740. X#else
  23741. X   return 0;
  23742. X#endif
  23743. X   }
  23744. X
  23745. X
  23746. Xstatic int exe_path(char *filename, char *path)
  23747. X   {
  23748. X#ifndef XFRACT
  23749. X   char *ptr;
  23750. X
  23751. X   if (dos_version() >= 300)  /* DOS version 3.00+ ? */
  23752. X      {
  23753. X#ifdef __TURBOC__
  23754. X      strcpy(path, _argv[0]);
  23755. X#else  /* assume MSC */
  23756. X      extern char **__argv;
  23757. X      strcpy(path, __argv[0]);     /* note: __argv may be undocumented in MSC */
  23758. X#endif
  23759. X
  23760. X      ptr = strrchr(path, SLASHC);
  23761. X      if (ptr == NULL)
  23762. X     ptr = path;
  23763. X      else
  23764. X     ++ptr;
  23765. X      strcpy(ptr, filename);
  23766. X      return (1);
  23767. X      }
  23768. X
  23769. X   return (0);
  23770. X#else
  23771. X   strcpy(path,SRCDIR);
  23772. X   strcat(path,"/");
  23773. X   strcat(path,filename);
  23774. X   return 1;
  23775. X#endif
  23776. X   }
  23777. X
  23778. X
  23779. Xstatic int find_file(char *filename, char *path)
  23780. X   {
  23781. X   int handle;
  23782. X
  23783. X   if ( exe_path(filename, path) )
  23784. X      if ( (handle=open(path, O_RDONLY)) != -1)
  23785. X     {
  23786. X     close(handle);
  23787. X     return (1);
  23788. X     }
  23789. X
  23790. X   findpath(filename,path);
  23791. X   return ( (path[0]) ? 1 : 0);
  23792. X   }
  23793. X
  23794. X
  23795. Xstatic int _read_help_topic(int topic, int off, int len, VOIDFARPTR buf)
  23796. X   {
  23797. X   static int  curr_topic = -1;
  23798. X   static long curr_base;
  23799. X   static int  curr_len;
  23800. X   int           read_len;
  23801. X
  23802. X   if ( topic != curr_topic )
  23803. X      {
  23804. X      int t;
  23805. X      char ch;
  23806. X
  23807. X      curr_topic = topic;
  23808. X
  23809. X      curr_base = topic_offset[topic];
  23810. X
  23811. X      curr_base += sizeof(int);            /* skip flags */
  23812. X
  23813. X      help_seek(curr_base);
  23814. X      read(help_file, (char *)&t, sizeof(int));    /* read num_pages */
  23815. X      curr_base += sizeof(int) + t*3*sizeof(int); /* skip page info */
  23816. X
  23817. X      if (t>0)
  23818. X     help_seek(curr_base);
  23819. X      read(help_file, &ch, 1);            /* read title_len */
  23820. X      t = ch;
  23821. X      curr_base += 1 + t;            /* skip title */
  23822. X
  23823. X      if (t>0)
  23824. X     help_seek(curr_base);
  23825. X      read(help_file, (char *)&curr_len, sizeof(int)); /* read topic len */
  23826. X      curr_base += sizeof(int);
  23827. X      }
  23828. X
  23829. X   read_len = (off+len > curr_len) ? curr_len - off : len;
  23830. X
  23831. X   if (read_len > 0)
  23832. X      {
  23833. X      help_seek(curr_base + off);
  23834. X      farread(help_file, (char far *)buf, read_len);
  23835. X      }
  23836. X
  23837. X   return ( curr_len - (off+len) );
  23838. X   }
  23839. X
  23840. X
  23841. Xint read_help_topic(int label_num, int off, int len, VOIDFARPTR buf)
  23842. X   /*
  23843. X    * reads text from a help topic.  Returns number of bytes from (off+len)
  23844. X    * to end of topic.    On "EOF" returns a negative number representing
  23845. X    * number of bytes not read.
  23846. X    */
  23847. X   {
  23848. X   int ret;
  23849. X
  23850. X   ENTER_OVLY(OVLY_HELP);
  23851. X
  23852. X   ret = _read_help_topic(label[label_num].topic_num,
  23853. X              label[label_num].topic_off + off, len, buf);
  23854. X
  23855. X   EXIT_OVLY;
  23856. X
  23857. X   return ( ret );
  23858. X   }
  23859. X
  23860. X
  23861. X#define PRINT_BUFFER_SIZE  (32767)     /* max. size of help topic in doc. */
  23862. X#define TEMP_FILE_NAME       "HELP.$$$"    /* temp file for storing extraseg  */
  23863. X                     /*    while printing document        */
  23864. X#define MAX_NUM_TOPIC_SEC  (10)      /* max. number of topics under any */
  23865. X                     /*    single section (CONTENT)     */
  23866. X
  23867. X
  23868. Xtypedef struct PRINT_DOC_INFO
  23869. X   {
  23870. X   int         cnum;        /* current CONTENT num */
  23871. X   int         tnum;        /* current topic num */
  23872. X
  23873. X   long      content_pos;   /* current CONTENT item offset in file */
  23874. X   int         num_page;        /* total number of pages in document */
  23875. X
  23876. X   int         num_contents,  /* total number of CONTENT entries */
  23877. X         num_topic;     /* number of topics in current CONTENT */
  23878. X
  23879. X   int         topic_num[MAX_NUM_TOPIC_SEC]; /* topic_num[] for current CONTENT entry */
  23880. X
  23881. X   char far *buffer;        /* text buffer */
  23882. X
  23883. X   char      id[81];        /* buffer to store id in */
  23884. X   char      title[81];     /* buffer to store title in */
  23885. X
  23886. X#ifndef XFRACT
  23887. X   int     (*msg_func)(int pnum, int num_page);
  23888. X#else
  23889. X   int     (*msg_func)();
  23890. X   int pnum;
  23891. X#endif
  23892. X
  23893. X   FILE     *file;        /* file to sent output to */
  23894. X   int         margin;        /* indent text by this much */
  23895. X   int         start_of_line; /* are we at the beginning of a line? */
  23896. X   int         spaces;        /* number of spaces in a row */
  23897. X   } PRINT_DOC_INFO;
  23898. X
  23899. X
  23900. Xvoid print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg );
  23901. X
  23902. X
  23903. Xstatic void printerc(PRINT_DOC_INFO *info, int c, int n)
  23904. X   {
  23905. X   while ( n-- > 0 )
  23906. X      {
  23907. X      if (c==' ')
  23908. X     ++info->spaces;
  23909. X
  23910. X      else if (c=='\n' || c=='\f')
  23911. X     {
  23912. X     info->start_of_line = 1;
  23913. X     info->spaces = 0;   /* strip spaces before a new-line */
  23914. X     putc(c, info->file);
  23915. X     }
  23916. X
  23917. X      else
  23918. X     {
  23919. X     if (info->start_of_line)
  23920. X        {
  23921. X        info->spaces += info->margin;
  23922. X        info->start_of_line = 0;
  23923. X        }
  23924. X
  23925. X     while (info->spaces > 0)
  23926. X        {
  23927. X        fputc(' ', info->file);
  23928. X        --info->spaces;
  23929. X        }
  23930. X
  23931. X     fputc(c, info->file);
  23932. X     }
  23933. X      }
  23934. X   }
  23935. X
  23936. X
  23937. Xstatic void printers(PRINT_DOC_INFO *info, char far *s, int n)
  23938. X   {
  23939. X   if (n > 0)
  23940. X      {
  23941. X      while ( n-- > 0 )
  23942. X     printerc(info, *s++, 1);
  23943. X      }
  23944. X   else
  23945. X      {
  23946. X      while ( *s != '\0' )
  23947. X     printerc(info, *s++, 1);
  23948. X      }
  23949. X   }
  23950. X
  23951. X
  23952. Xstatic int print_doc_get_info(int cmd, PD_INFO *pd, PRINT_DOC_INFO *info)
  23953. X   {
  23954. X   int t;
  23955. X   BYTE ch;
  23956. X
  23957. X   switch (cmd)
  23958. X      {
  23959. X      case PD_GET_CONTENT:
  23960. X     if ( ++info->cnum >= info->num_contents )
  23961. X        return (0);
  23962. X
  23963. X     help_seek( info->content_pos );
  23964. X
  23965. X         read(help_file, (char *)&t, sizeof(int));      /* read flags */
  23966. X         info->content_pos += sizeof(int);
  23967. X     pd->new_page = (t & 1) ? 1 : 0;
  23968. X
  23969. X         read(help_file, &ch, 1);       /* read id len */
  23970. X         t = ch;
  23971. X     assert(t<80);
  23972. X     read(help_file, (char *)info->id, t);    /* read the id */
  23973. X     info->content_pos += 1 + t;
  23974. X     info->id[t] = '\0';
  23975. X
  23976. X         read(help_file, (char *)&ch, 1);       /* read title len */
  23977. X         t = ch;
  23978. X     assert(t<80);
  23979. X     read(help_file, (char *)info->title, t); /* read the title */
  23980. X     info->content_pos += 1 + t;
  23981. X     info->title[t] = '\0';
  23982. X
  23983. X         read(help_file, (char *)&ch, 1);       /* read num_topic */
  23984. X         t = ch;
  23985. X     assert(t<MAX_NUM_TOPIC_SEC);
  23986. X         read(help_file, (char *)info->topic_num, t*sizeof(int));  /* read topic_num[] */
  23987. X     info->num_topic = t;
  23988. X         info->content_pos += 1 + t*sizeof(int);
  23989. X
  23990. X     info->tnum = -1;
  23991. X
  23992. X     pd->id = info->id;
  23993. X     pd->title = info->title;
  23994. X     return (1);
  23995. X
  23996. X      case PD_GET_TOPIC:
  23997. X     if ( ++info->tnum >= info->num_topic )
  23998. X        return (0);
  23999. X
  24000. X     t = _read_help_topic(info->topic_num[info->tnum], 0, PRINT_BUFFER_SIZE, info->buffer);
  24001. X
  24002. X     assert(t <= 0);
  24003. X
  24004. X     pd->curr = info->buffer;
  24005. X     pd->len  = PRINT_BUFFER_SIZE + t;   /* same as ...SIZE - abs(t) */
  24006. X     return (1);
  24007. X
  24008. X      case PD_GET_LINK_PAGE:
  24009. X         pd->i = getint(pd->s+sizeof(long));
  24010. X     return ( (pd->i == -1) ? 0 : 1 );
  24011. X
  24012. X      case PD_RELEASE_TOPIC:
  24013. X     return (1);
  24014. X
  24015. X      default:
  24016. X     return (0);
  24017. X      }
  24018. X   }
  24019. X
  24020. X
  24021. Xstatic int print_doc_output(int cmd, PD_INFO *pd, PRINT_DOC_INFO *info)
  24022. X   {
  24023. X   switch (cmd)
  24024. X      {
  24025. X      case PD_HEADING:
  24026. X     {
  24027. X     char line[81];
  24028. X     char buff[40];
  24029. X     int  width = PAGE_WIDTH + PAGE_INDENT;
  24030. X     int  keep_going;
  24031. X
  24032. X     if ( info->msg_func != NULL )
  24033. X        keep_going = (*info->msg_func)(pd->pnum, info->num_page);
  24034. X     else
  24035. X        keep_going = 1;
  24036. X
  24037. X     info->margin = 0;
  24038. X
  24039. X     memset(line, ' ', 81);
  24040. X     sprintf(buff, "Fractint Version %d.%01d%c",release/100, (release%100)/10,
  24041. X                ( (release%10) ? '0'+(release%10) : ' ') );
  24042. X     memmove(line + ( (width-strlen(buff)) / 2)-4, buff, strlen(buff));
  24043. X
  24044. X     sprintf(buff, "Page %d", pd->pnum);
  24045. X     memmove(line + (width - strlen(buff)), buff, strlen(buff));
  24046. X
  24047. X     printerc(info, '\n', 1);
  24048. X     printers(info, line, width);
  24049. X     printerc(info, '\n', 2);
  24050. X
  24051. X     info->margin = PAGE_INDENT;
  24052. X
  24053. X     return ( keep_going );
  24054. X     }
  24055. X
  24056. X      case PD_FOOTING:
  24057. X     info->margin = 0;
  24058. X     printerc(info, '\f', 1);
  24059. X     info->margin = PAGE_INDENT;
  24060. X     return (1);
  24061. X
  24062. X      case PD_PRINT:
  24063. X     printers(info, pd->s, pd->i);
  24064. X     return (1);
  24065. X
  24066. X      case PD_PRINTN:
  24067. X     printerc(info, *pd->s, pd->i);
  24068. X     return (1);
  24069. X
  24070. X      case PD_PRINT_SEC:
  24071. X     info->margin = TITLE_INDENT;
  24072. X     if (pd->id[0] != '\0')
  24073. X        {
  24074. X        printers(info, pd->id, 0);
  24075. X        printerc(info, ' ', 1);
  24076. X        }
  24077. X     printers(info, pd->title, 0);
  24078. X     printerc(info, '\n', 1);
  24079. X     info->margin = PAGE_INDENT;
  24080. X     return (1);
  24081. X
  24082. X      case PD_START_SECTION:
  24083. X      case PD_START_TOPIC:
  24084. X      case PD_SET_SECTION_PAGE:
  24085. X      case PD_SET_TOPIC_PAGE:
  24086. X      case PD_PERIODIC:
  24087. X     return (1);
  24088. X
  24089. X      default:
  24090. X     return (0);
  24091. X      }
  24092. X   }
  24093. X
  24094. X
  24095. Xstatic int print_doc_msg_func(int pnum, int num_pages)
  24096. X   {
  24097. X   char temp[10];
  24098. X   int    key;
  24099. X
  24100. X   if ( pnum == -1 )    /* successful completion */
  24101. X      {
  24102. X      buzzer(0);
  24103. X      putstringcenter(7, 0, 80, C_HELP_LINK, "Done -- Press any key");
  24104. X      getakey();
  24105. X      return (0);
  24106. X      }
  24107. X
  24108. X   if ( pnum == -2 )   /* aborted */
  24109. X      {
  24110. X      buzzer(1);
  24111. X      putstringcenter(7, 0, 80, C_HELP_LINK, "Aborted -- Press any key");
  24112. X      getakey();
  24113. X      return (0);
  24114. X      }
  24115. X
  24116. X   if (pnum == 0)   /* initialization */
  24117. X      {
  24118. X      helptitle();
  24119. X      printinstr();
  24120. X      setattr(2, 0, C_HELP_BODY, 80*22);
  24121. X      putstringcenter(1, 0, 80, C_HELP_HDG, "Generating FRACTINT.DOC");
  24122. X
  24123. X      putstring(7, 30, C_HELP_BODY, "Completed:");
  24124. X
  24125. X      movecursor(25,80);   /* hide cursor */
  24126. X      }
  24127. X
  24128. X
  24129. X   sprintf(temp, "%d%%", (int)( (100.0 / num_pages) * pnum ) );
  24130. X   putstring(7, 41, C_HELP_LINK, temp);
  24131. X
  24132. X   while ( keypressed() )
  24133. X      {
  24134. X      key = getakey();
  24135. X      if ( key == ESC )
  24136. X     return (0);    /* user abort */
  24137. X      }
  24138. X
  24139. X   return (1);     /* AOK -- continue */
  24140. X   }
  24141. X
  24142. Xint makedoc_msg_func(int pnum, int num_pages)
  24143. X   {
  24144. X   if (pnum >= 0)
  24145. X      {
  24146. X      printf("\rcompleted %d%%", (int)( (100.0 / num_pages) * pnum ) );
  24147. X      return (1);
  24148. X      }
  24149. X   if ( pnum == -2 )
  24150. X      printf("\n*** aborted");
  24151. X   printf("\n");
  24152. X   return (0);
  24153. X   }
  24154. X
  24155. X
  24156. X
  24157. Xvoid print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg )
  24158. X   {
  24159. X   static char far err_no_temp[]  = "Unable to create temporary file.\n";
  24160. X   static char far err_no_out[]   = "Unable to create output file.\n";
  24161. X   static char far err_badwrite[] = "Error writing temporary file.\n";
  24162. X   static char far err_badread[]  = "Error reading temporary file.\nSystem may be corrupt!\nSave your image and re-start FRACTINT!\n";
  24163. X
  24164. X   PRINT_DOC_INFO info;
  24165. X   int          success;
  24166. X   int          temp_file = -1;
  24167. X   char      far *msg = NULL;
  24168. X
  24169. X   ENTER_OVLY(OVLY_HELP);
  24170. X
  24171. X   info.buffer = MK_FP(extraseg, 0);
  24172. X
  24173. X/*   help_seek((long)sizeof(int)+sizeof(long));        Strange -- should be 8 -- CWM */
  24174. X   help_seek(8L);                /* indeed it should - Bert */
  24175. X   read(help_file, (char *)&info.num_contents, sizeof(int));
  24176. X   read(help_file, (char *)&info.num_page, sizeof(int));
  24177. X
  24178. X   info.cnum = info.tnum = -1;
  24179. X   info.content_pos = sizeof(long)+4*sizeof(int) + num_topic*sizeof(long) + num_label*2*sizeof(int);
  24180. X   info.msg_func = msg_func;
  24181. X
  24182. X   if ( msg_func != NULL )
  24183. X      msg_func(0, info.num_page);   /* initialize */
  24184. X
  24185. X   if ( save_extraseg )
  24186. X      {
  24187. X      if ( (temp_file=open(TEMP_FILE_NAME, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE)) == -1 )
  24188. X     {
  24189. X     msg = err_no_temp;
  24190. X     goto ErrorAbort;
  24191. X     }
  24192. X
  24193. X      if ( farwrite(temp_file, info.buffer, PRINT_BUFFER_SIZE) != PRINT_BUFFER_SIZE )
  24194. X     {
  24195. X     msg = err_badwrite;
  24196. X     goto ErrorAbort;
  24197. X     }
  24198. X      }
  24199. X
  24200. X   if ( (info.file = fopen(outfname, "wt")) == NULL )
  24201. X      {
  24202. X      msg = err_no_out;
  24203. X      goto ErrorAbort;
  24204. X      }
  24205. X
  24206. X   info.margin = PAGE_INDENT;
  24207. X   info.start_of_line = 1;
  24208. X   info.spaces = 0;
  24209. X
  24210. X   success = process_document((PD_FUNC)print_doc_get_info,
  24211. X                  (PD_FUNC)print_doc_output,   &info);
  24212. X   fclose(info.file);
  24213. X
  24214. X   if ( save_extraseg )
  24215. X      {
  24216. X      if ( lseek(temp_file, 0L, SEEK_SET) != 0L )
  24217. X     {
  24218. X     msg = err_badread;
  24219. X     goto ErrorAbort;
  24220. X     }
  24221. X
  24222. X      if ( farread(temp_file, info.buffer, PRINT_BUFFER_SIZE) != PRINT_BUFFER_SIZE )
  24223. X     {
  24224. X     msg = err_badread;
  24225. X     goto ErrorAbort;
  24226. X     }
  24227. X      }
  24228. X
  24229. XErrorAbort:
  24230. X   if (temp_file != -1)
  24231. X      {
  24232. X      close(temp_file);
  24233. X      remove(TEMP_FILE_NAME);
  24234. X      temp_file = -1;
  24235. X      }
  24236. X
  24237. X   if ( msg != NULL )
  24238. X      {
  24239. X      helptitle();
  24240. X      stopmsg(1, msg);
  24241. X      }
  24242. X
  24243. X   else if ( msg_func != NULL )
  24244. X      msg_func((success) ? -1 : -2, info.num_page );
  24245. X
  24246. X   EXIT_OVLY;
  24247. X   }
  24248. X
  24249. X
  24250. Xint init_help(void)
  24251. X   {
  24252. X   struct help_sig_info hs;
  24253. X   char         path[81];
  24254. X
  24255. X   ENTER_OVLY(OVLY_HELP);
  24256. X
  24257. X   help_file = -1;
  24258. X
  24259. X#ifndef XFRACT
  24260. X   if (help_file == -1)        /* now look for help files in FRACTINT.EXE */
  24261. X      {
  24262. X      static char far err_no_open[]    = "Help system was unable to open FRACTINT.EXE!\n";
  24263. X      static char far err_no_exe[]     = "Help system couldn't find FRACTINT.EXE!\n";
  24264. X      static char far err_wrong_ver[]  = "Wrong help version in FRACTINT.EXE!\n";
  24265. X/*
  24266. X      static char far err_not_in_exe[] = "Help not found in FRACTINT.EXE!\n";
  24267. X*/
  24268. X
  24269. X      if ( find_file("FRACTINT.EXE", path) )
  24270. X     {
  24271. X     if ( (help_file = open(path, O_RDONLY|O_BINARY)) != -1 )
  24272. X        {
  24273. X        long help_offset;
  24274. X
  24275. X        for (help_offset = -((long)sizeof(hs)); help_offset >= -128L; help_offset--)
  24276. X               {
  24277. X           lseek(help_file, help_offset, SEEK_END);
  24278. X           read(help_file, (char *)&hs, sizeof(hs));
  24279. X           if (hs.sig == HELP_SIG)  break;
  24280. X           }
  24281. X
  24282. X        if ( hs.sig != HELP_SIG )
  24283. X           {
  24284. X           close(help_file);
  24285. X           help_file = -1;
  24286. X           /* (leave out the error message)
  24287. X           stopmsg(1, err_not_in_exe);
  24288. X           */
  24289. X           }
  24290. X
  24291. X        else
  24292. X           {
  24293. X           if ( hs.version != HELP_VERSION )
  24294. X              {
  24295. X              close(help_file);
  24296. X              help_file = -1;
  24297. X              stopmsg(1, err_wrong_ver);
  24298. X              }
  24299. X             else
  24300. X              base_off = hs.base;
  24301. X
  24302. X               }
  24303. X        }
  24304. X     else
  24305. X        stopmsg(1, err_no_open);
  24306. X     }
  24307. X      else
  24308. X     stopmsg(1, err_no_exe);
  24309. X
  24310. X      }
  24311. X#endif
  24312. X
  24313. Xif (help_file == -1)        /* look for FRACTINT.HLP */
  24314. X   {
  24315. X   if ( find_file("fractint.hlp", path) )
  24316. X      {
  24317. X      if ( (help_file = open(path, O_RDONLY|O_BINARY)) != -1 )
  24318. X     {
  24319. X         read(help_file, (char *)&hs, sizeof(long)+sizeof(int));
  24320. X
  24321. X     if ( hs.sig != HELP_SIG )
  24322. X        {
  24323. X        static char far msg[] = {"Invalid help signature in FRACTINT.HLP!\n"};
  24324. X        close(help_file);
  24325. X        stopmsg(1, msg);
  24326. X        }
  24327. X
  24328. X     else if ( hs.version != HELP_VERSION )
  24329. X        {
  24330. X        static char far msg[] = {"Wrong help version in FRACTINT.HLP!\n"};
  24331. X        close(help_file);
  24332. X        stopmsg(1, msg);
  24333. X        }
  24334. X
  24335. X     else
  24336. X        base_off = sizeof(long)+sizeof(int);
  24337. X     }
  24338. X      }
  24339. X   }
  24340. X
  24341. X   if (help_file == -1)        /* Can't find the help files anywhere! */
  24342. X      {
  24343. X      static char far msg[] =
  24344. X#ifndef XFRACT
  24345. X     {"Help Files aren't in FRACTINT.EXE, and couldn't find FRACTINT.HLP!\n"};
  24346. X#else
  24347. X     {"Couldn't find fractint.hlp; set FRACTDIR to proper directory with setenv.\n"};
  24348. X#endif
  24349. X      stopmsg(1, msg);
  24350. X      }
  24351. X
  24352. X   help_seek(0L);
  24353. X
  24354. X   read(help_file, (char *)&max_pages, sizeof(int));
  24355. X   read(help_file, (char *)&max_links, sizeof(int));
  24356. X   read(help_file, (char *)&num_topic, sizeof(int));
  24357. X   read(help_file, (char *)&num_label, sizeof(int));
  24358. X   help_seek((long)6*sizeof(int));  /* skip num_contents and num_doc_pages */
  24359. X
  24360. X   assert(max_pages > 0);
  24361. X   assert(max_links >= 0);
  24362. X   assert(num_topic > 0);
  24363. X   assert(num_label > 0);
  24364. X
  24365. X   /* allocate one big chunk for all three arrays */
  24366. X
  24367. X   topic_offset = (long far *)farmemalloc(sizeof(long)*num_topic + 2L*sizeof(int)*num_label + sizeof(HIST)*MAX_HIST);
  24368. X
  24369. X   if (topic_offset == NULL)
  24370. X      {
  24371. X      static char far err_no_mem[] = "Not enough memory for help system!\n";
  24372. X      close(help_file);
  24373. X      help_file = -1;
  24374. X      stopmsg(1, err_no_mem);
  24375. X
  24376. X      EXIT_OVLY;      /* JIC stopmsg continues for some reason? */
  24377. X      return (-2);
  24378. X      }
  24379. X
  24380. X   /* split off the other arrays */
  24381. X
  24382. X   label = (LABEL far *)(&topic_offset[num_topic]);
  24383. X   hist  = (HIST far *)(&label[num_label]);
  24384. X
  24385. X   /* read in the tables... */
  24386. X
  24387. X   farread(help_file, topic_offset, num_topic*sizeof(long));
  24388. X   farread(help_file, label, num_label*2*sizeof(int));
  24389. X
  24390. X   /* finished! */
  24391. X
  24392. X   EXIT_OVLY;
  24393. X   return (0);    /* success */
  24394. X   }
  24395. X
  24396. X
  24397. Xvoid end_help(void)
  24398. X   {
  24399. X   ENTER_OVLY(OVLY_HELP);
  24400. X   if (help_file != -1)
  24401. X      {
  24402. X      close(help_file);
  24403. X      farmemfree((BYTE far *)topic_offset);
  24404. X      help_file = -1;
  24405. X      }
  24406. X   EXIT_OVLY;
  24407. X   }
  24408. X
  24409. X
  24410. SHAR_EOF
  24411. $TOUCH -am 1028230093 help.c &&
  24412. chmod 0644 help.c ||
  24413. echo "restore of help.c failed"
  24414. set `wc -c help.c`;Wc_c=$1
  24415. if test "$Wc_c" != "36787"; then
  24416.     echo original size 36787, current size $Wc_c
  24417. fi
  24418. # ============= intro.c ==============
  24419. echo "x - extracting intro.c (Text)"
  24420. sed 's/^X//' << 'SHAR_EOF' > intro.c &&
  24421. X
  24422. X/*
  24423. X * intro.c
  24424. X *
  24425. X * FRACTINT intro screen (authors & credits)
  24426. X *
  24427. X *
  24428. X */
  24429. X
  24430. X#include <stdio.h>
  24431. X#include <time.h>
  24432. X#ifndef XFRACT
  24433. X#include <dos.h>
  24434. X#endif
  24435. X
  24436. X#include "fractint.h"
  24437. X#include "helpdefs.h"
  24438. X#include "prototyp.h"
  24439. X
  24440. X/* stuff from fractint */
  24441. X
  24442. Xextern int  lookatmouse;
  24443. Xextern long timer_start;
  24444. Xextern int  helpmode;
  24445. Xextern SEGTYPE  extraseg;
  24446. X
  24447. X
  24448. X#ifdef XFRACT
  24449. Xextern int slowdisplay;
  24450. X#endif
  24451. X
  24452. X
  24453. Xvoid intro_overlay(void) { }
  24454. X
  24455. X
  24456. Xvoid intro(void)
  24457. X   {
  24458. X   int         toprow, botrow, i, j, delaymax;
  24459. X   char      oldchar;
  24460. X   int         authors[100];        /* this should be enough for awhile */
  24461. X   char far *credits;
  24462. X   char far *screen_text;
  24463. X   int         oldlookatmouse;
  24464. X   int         oldhelpmode;
  24465. X
  24466. X   ENTER_OVLY(OVLY_INTRO);
  24467. X
  24468. X   timer_start -= clock_ticks();        /* "time out" during help */
  24469. X   oldlookatmouse = lookatmouse;
  24470. X   oldhelpmode = helpmode;
  24471. X   lookatmouse = 0;            /* de-activate full mouse checking */
  24472. X
  24473. X   screen_text = MK_FP(extraseg, 0);
  24474. X
  24475. X   i = 32767 + read_help_topic(INTRO_AUTHORS, 0, 32767, screen_text);
  24476. X   screen_text[i++] = '\0';
  24477. X   credits = screen_text + i;
  24478. X   i = 32767 + read_help_topic(INTRO_CREDITS, 0, 32767, credits);
  24479. X   credits[i++] = '\0';
  24480. X
  24481. X   j = 0;
  24482. X   authors[j] = 0;        /* find the start of each credit-line */
  24483. X   for (i = 0; credits[i] != 0; i++)
  24484. X      if (credits[i] == 10)
  24485. X     authors[++j] = i+1;
  24486. X   authors[j+1] = i;
  24487. X
  24488. X   helptitle();
  24489. X   toprow = 8;
  24490. X#ifndef XFRACT
  24491. X   botrow = 21;
  24492. X#else
  24493. X   botrow = 20;
  24494. X   putstringcenter(21,0,80,C_TITLE,
  24495. X   "Unix/X port of fractint by Ken Shirriff [shirriff@sprite.Berkeley.EDU]");
  24496. X#endif
  24497. X   putstringcenter(1,0,80,C_TITLE, "Press ENTER for main menu, F1 for help.");
  24498. X   putstring(2,0,C_CONTRIB,screen_text);
  24499. X   setattr(2,0,C_AUTHDIV1,80);
  24500. X   setattr(7,0,C_AUTHDIV1,80);
  24501. X   setattr(22,0,C_AUTHDIV2,80);
  24502. X   setattr(3,0,C_PRIMARY,320);
  24503. X   setattr(23,0,C_TITLE_LOW,160);
  24504. X   for (i = 3; i < 7; ++i)
  24505. X      setattr(i,20,C_CONTRIB,60);
  24506. X   setattr(toprow,0,C_CONTRIB,14*80);
  24507. X   i = botrow - toprow;
  24508. X   srand(clock_ticks());
  24509. X   j = rand15()%(j-(botrow-toprow)); /* first to use */
  24510. X   i = j+botrow-toprow; /* last to use */
  24511. X   oldchar = credits[authors[i+1]];
  24512. X   credits[authors[i+1]] = 0;
  24513. X   putstring(toprow,0,C_CONTRIB,credits+authors[j]);
  24514. X   credits[authors[i+1]] = oldchar;
  24515. X   delaymax = 10;
  24516. X   movecursor(25,80); /* turn it off */
  24517. X   helpmode = HELPMENU;
  24518. X   while (! keypressed())
  24519. X      {
  24520. X#ifdef XFRACT
  24521. X      if (slowdisplay) delaymax *= 15;
  24522. X#endif
  24523. X      for (j = 0; j < delaymax && !(keypressed()); j++)
  24524. X     delay(100);
  24525. X      if (keypressed() == 32)
  24526. X     {    /* spacebar pauses */
  24527. X     getakey();
  24528. X#ifndef XFRACT
  24529. X         while (!keypressed()) ;
  24530. X#else
  24531. X         waitkeypressed(0);
  24532. X#endif
  24533. X     if (keypressed() == 32)
  24534. X        getakey();
  24535. X     }
  24536. X      delaymax = 15;
  24537. X      scrollup(toprow, botrow);
  24538. X      i++;
  24539. X      if (credits[authors[i]] == 0)
  24540. X     i = 0;
  24541. X      oldchar = credits[authors[i+1]];
  24542. X      credits[authors[i+1]] = 0;
  24543. X      putstring(botrow,0,C_CONTRIB,&credits[authors[i]]);
  24544. X      setattr(botrow,0,C_CONTRIB,80);
  24545. X      credits[authors[i+1]] = oldchar;
  24546. X      movecursor(25,80); /* turn it off */
  24547. X      }
  24548. X
  24549. X   lookatmouse = oldlookatmouse;        /* restore the mouse-checking */
  24550. X   helpmode = oldhelpmode;
  24551. X   EXIT_OVLY;
  24552. X   return ;
  24553. X   }
  24554. SHAR_EOF
  24555. $TOUCH -am 1028230093 intro.c &&
  24556. chmod 0644 intro.c ||
  24557. echo "restore of intro.c failed"
  24558. set `wc -c intro.c`;Wc_c=$1
  24559. if test "$Wc_c" != "3156"; then
  24560.     echo original size 3156, current size $Wc_c
  24561. fi
  24562. # ============= jb.c ==============
  24563. echo "x - extracting jb.c (Text)"
  24564. sed 's/^X//' << 'SHAR_EOF' > jb.c &&
  24565. X#include <stdio.h>
  24566. X#include <stdlib.h>
  24567. X#include "fractint.h"
  24568. X#include "mpmath.h"
  24569. X#include "helpdefs.h"
  24570. X#include "prototyp.h"
  24571. X#include "fractype.h"
  24572. X
  24573. Xextern int savedac;
  24574. Xextern int c_exp;
  24575. Xextern int debugflag;
  24576. Xextern int maxit;
  24577. Xextern int num_fractal_types;
  24578. Xextern struct fractalspecificstuff far fractalspecific[];
  24579. Xextern int row, col, xdots, ydots, bitshift, fractype;
  24580. Xextern int ixstart, ixstop, iystart, iystop, colors, helpmode;
  24581. Xextern double param[], xxmin, xxmax, yymin, yymax;
  24582. Xextern long delx, dely, ltempsqrx, ltempsqry, far * lx0, far * ly0;
  24583. Xextern double tempsqrx, tempsqry, qc, qci, qcj, qck;
  24584. Xextern _LCMPLX lold, lnew, *longparm;
  24585. Xextern _CMPLX old, new, *floatparm;
  24586. Xextern llimit2;
  24587. X
  24588. X/* these need to be accessed elsewhere for saving data */
  24589. Xdouble mxminfp = -.83;
  24590. Xdouble myminfp = -.25;
  24591. Xdouble mxmaxfp = -.83;
  24592. Xdouble mymaxfp =  .25;
  24593. X
  24594. Xstatic long mxmin, mymin;
  24595. Xstatic long x_per_inch, y_per_inch, inch_per_xdot, inch_per_ydot;
  24596. Xstatic double x_per_inchfp, y_per_inchfp, inch_per_xdotfp, inch_per_ydotfp;
  24597. Xstatic int bbase;
  24598. Xstatic long xpixel, ypixel;
  24599. Xstatic double xpixelfp, ypixelfp;
  24600. Xstatic long initz, djx, djy, dmx, dmy;
  24601. Xstatic double initzfp, djxfp, djyfp, dmxfp, dmyfp;
  24602. Xstatic long jx, jy, mx, my, xoffset, yoffset;
  24603. Xstatic double jxfp, jyfp, mxfp, myfp, xoffsetfp, yoffsetfp;
  24604. X
  24605. Xstruct Perspective
  24606. X{
  24607. X   long x, y, zx, zy;
  24608. X};
  24609. X
  24610. Xstruct Perspectivefp
  24611. X{
  24612. X   double x, y, zx, zy;
  24613. X};
  24614. X
  24615. Xstruct Perspective LeftEye, RightEye, *Per;
  24616. Xstruct Perspectivefp LeftEyefp, RightEyefp, *Perfp;
  24617. X
  24618. X_LCMPLX jbc;
  24619. X_CMPLX jbcfp;
  24620. X
  24621. Xextern char Glasses1Map[];
  24622. Xextern char GreyFile[];
  24623. X
  24624. Xstatic double fg, fg16;
  24625. Xint zdots = 128;
  24626. X
  24627. Xdouble originfp = 8, heightfp = 7, widthfp = 10, distfp = 24, eyesfp = 2.5, depthfp = 8, brratiofp = 1;
  24628. Xstatic long width, dist, eyes, depth, brratio;
  24629. X
  24630. Xint juli3Dmode = 0;
  24631. X
  24632. Xint lastorbittype = -1;
  24633. Xint neworbittype = JULIA;
  24634. X
  24635. Xint
  24636. XJulibrotSetup(void)
  24637. X{
  24638. X   long origin, height;
  24639. X   int numparams;
  24640. X   struct fractalspecificstuff far *oldcurfractalspecific;
  24641. X   int oldfractype;
  24642. X   int i;
  24643. X   int r;
  24644. X   int oldhelpmode;
  24645. X   char *mapname;
  24646. X
  24647. X#ifndef XFRACT
  24648. X   if (colors < 255)
  24649. X   {
  24650. X      static char far msg[] =
  24651. X      {"Sorry, but Julibrots require a 256-color video mode"};
  24652. X      stopmsg(0, msg);
  24653. X      return (0);
  24654. X   }
  24655. X#endif
  24656. X
  24657. X   stackscreen();
  24658. X   oldhelpmode = helpmode;
  24659. X   helpmode = HT_JULIBROT;
  24660. X   xoffsetfp = (xxmax + xxmin) / 2;     /* Calculate average */
  24661. X   yoffsetfp = (yymax + yymin) / 2;     /* Calculate average */
  24662. X   dmxfp = (mxmaxfp - mxminfp) / zdots;
  24663. X   dmyfp = (mymaxfp - myminfp) / zdots;
  24664. X   floatparm = &jbcfp;
  24665. X
  24666. X
  24667. X   x_per_inchfp = (xxmin - xxmax) / widthfp;
  24668. X   y_per_inchfp = (yymax - yymin) / heightfp;
  24669. X   inch_per_xdotfp = widthfp / xdots;
  24670. X   inch_per_ydotfp = heightfp / ydots;
  24671. X
  24672. X   initzfp = originfp - (depthfp / 2);
  24673. X   if(juli3Dmode == 0)
  24674. X      RightEyefp.x = 0.0;
  24675. X   else
  24676. X      RightEyefp.x = eyesfp / 2;
  24677. X   LeftEyefp.x = -RightEyefp.x;
  24678. X   LeftEyefp.y = RightEyefp.y = 0;
  24679. X   LeftEyefp.zx = RightEyefp.zx = distfp;
  24680. X   LeftEyefp.zy = RightEyefp.zy = distfp;
  24681. X   bbase = 128;
  24682. X   oldcurfractalspecific = curfractalspecific;
  24683. X   oldfractype = fractype;
  24684. X   fractype = neworbittype;
  24685. X   curfractalspecific = &fractalspecific[fractype];
  24686. X   lastorbittype = neworbittype;
  24687. X   curfractalspecific = oldcurfractalspecific;
  24688. X   fractype = oldfractype;
  24689. X#ifndef XFRACT
  24690. X   if (fractalspecific[fractype].isinteger > 0)
  24691. X   {
  24692. X      long jxmin, jxmax, jymin, jymax, mxmax, mymax;
  24693. X      if (fractalspecific[neworbittype].isinteger == 0)
  24694. X      {
  24695. X         char msg[80];
  24696. X         sprintf(msg, "Julibrot orbit type isinteger mismatch");
  24697. X         stopmsg(0, msg);
  24698. X      }
  24699. X      if (fractalspecific[neworbittype].isinteger > 1)
  24700. X         bitshift = fractalspecific[neworbittype].isinteger;
  24701. X      fg = (double) (1L << bitshift);
  24702. X      fg16 = (double) (1L << 16);
  24703. X      jxmin = (long) (xxmin * fg);
  24704. X      jxmax = (long) (xxmax * fg);
  24705. X      xoffset = (jxmax + jxmin) / 2;    /* Calculate average */
  24706. X      jymin = (long) (yymin * fg);
  24707. X      jymax = (long) (yymax * fg);
  24708. X      yoffset = (jymax + jymin) / 2;    /* Calculate average */
  24709. X      mxmin = (long) (mxminfp * fg);
  24710. X      mxmax = (long) (mxmaxfp * fg);
  24711. X      mymin = (long) (myminfp * fg);
  24712. X      mymax = (long) (mymaxfp * fg);
  24713. X      origin = (long) (originfp * fg16);
  24714. X      depth = (long) (depthfp * fg16);
  24715. X      height = (long) (heightfp * fg16);
  24716. X      width = (long) (widthfp * fg16);
  24717. X      dist = (long) (distfp * fg16);
  24718. X      eyes = (long) (eyesfp * fg16);
  24719. X      brratio = (long) (brratiofp * fg16);
  24720. X      dmx = (mxmax - mxmin) / zdots;
  24721. X      dmy = (mymax - mymin) / zdots;
  24722. X      longparm = &jbc;
  24723. X
  24724. X      x_per_inch = (long) ((xxmin - xxmax) / widthfp * fg);
  24725. X      y_per_inch = (long) ((yymax - yymin) / heightfp * fg);
  24726. X      inch_per_xdot = (long) ((widthfp / xdots) * fg16);
  24727. X      inch_per_ydot = (long) ((heightfp / ydots) * fg16);
  24728. X      initz = origin - (depth / 2);
  24729. X      if(juli3Dmode == 0)
  24730. X         RightEye.x = 0l;
  24731. X      else
  24732. X         RightEye.x = eyes / 2;
  24733. X      LeftEye.x = -RightEye.x;
  24734. X      LeftEye.y = RightEye.y = 0l;
  24735. X      LeftEye.zx = RightEye.zx = dist;
  24736. X      LeftEye.zy = RightEye.zy = dist;
  24737. X      bbase = (int) (128.0 * brratiofp);
  24738. X   }
  24739. X#endif
  24740. X
  24741. X   helpmode = oldhelpmode;
  24742. X   unstackscreen();
  24743. X   if (juli3Dmode == 3)
  24744. X   {
  24745. X      savedac = 0;
  24746. X      mapname = Glasses1Map;
  24747. X   }
  24748. X   else
  24749. X      mapname = GreyFile;
  24750. X   if(savedac != 1)
  24751. X   {
  24752. X   if (ValidateLuts(mapname) != 0)
  24753. X      return (0);
  24754. X   spindac(0, 1);               /* load it, but don't spin */
  24755. X      if(savedac == 2)
  24756. X        savedac = 1;
  24757. X   }
  24758. X   return (r >= 0);
  24759. X}
  24760. X
  24761. X
  24762. Xint
  24763. Xjb_per_pixel(void)
  24764. X{
  24765. X   jx = multiply(Per->x - xpixel, initz, 16);
  24766. X   jx = divide(jx, dist, 16) - xpixel;
  24767. X   jx = multiply(jx << (bitshift - 16), x_per_inch, bitshift);
  24768. X   jx += xoffset;
  24769. X   djx = divide(depth, dist, 16);
  24770. X   djx = multiply(djx, Per->x - xpixel, 16) << (bitshift - 16);
  24771. X   djx = multiply(djx, x_per_inch, bitshift) / zdots;
  24772. X
  24773. X   jy = multiply(Per->y - ypixel, initz, 16);
  24774. X   jy = divide(jy, dist, 16) - ypixel;
  24775. X   jy = multiply(jy << (bitshift - 16), y_per_inch, bitshift);
  24776. X   jy += yoffset;
  24777. X   djy = divide(depth, dist, 16);
  24778. X   djy = multiply(djy, Per->y - ypixel, 16) << (bitshift - 16);
  24779. X   djy = multiply(djy, y_per_inch, bitshift) / zdots;
  24780. X
  24781. X   return (1);
  24782. X}
  24783. X
  24784. Xint
  24785. Xjbfp_per_pixel(void)
  24786. X{
  24787. X   jxfp = ((Perfp->x - xpixelfp) * initzfp / distfp - xpixelfp) * x_per_inchfp;
  24788. X   jxfp += xoffsetfp;
  24789. X   djxfp = (depthfp / distfp) * (Perfp->x - xpixelfp) * x_per_inchfp / zdots;
  24790. X
  24791. X   jyfp = ((Perfp->y - ypixelfp) * initzfp / distfp - ypixelfp) * y_per_inchfp;
  24792. X   jyfp += yoffsetfp;
  24793. X   djyfp = depthfp / distfp * (Perfp->y - ypixelfp) * y_per_inchfp / zdots;
  24794. X
  24795. X   return (1);
  24796. X}
  24797. X
  24798. Xstatic int n, zpixel, plotted, color;
  24799. X
  24800. Xint
  24801. Xzline(long x, long y)
  24802. X{
  24803. X   xpixel = x;
  24804. X   ypixel = y;
  24805. X   mx = mxmin;
  24806. X   my = mymin;
  24807. X   switch(juli3Dmode)
  24808. X   {
  24809. X   case 0:
  24810. X   case 1:
  24811. X      Per = &LeftEye;
  24812. X      break;
  24813. X   case 2:
  24814. X      Per = &RightEye;
  24815. X      break;
  24816. X   case 3:
  24817. X      if ((row + col) & 1)
  24818. X         Per = &LeftEye;
  24819. X      else
  24820. X         Per = &RightEye;
  24821. X      break;
  24822. X   }
  24823. X   jb_per_pixel();
  24824. X   for (zpixel = 0; zpixel < zdots; zpixel++)
  24825. X   {
  24826. X      lold.x = jx;
  24827. X      lold.y = jy;
  24828. X      jbc.x = mx;
  24829. X      jbc.y = my;
  24830. X      if (check_key())
  24831. X         return (-1);
  24832. X      ltempsqrx = multiply(lold.x, lold.x, bitshift);
  24833. X      ltempsqry = multiply(lold.y, lold.y, bitshift);
  24834. X      for (n = 0; n < maxit; n++)
  24835. X         if (fractalspecific[neworbittype].orbitcalc())
  24836. X            break;
  24837. X      if (n == maxit)
  24838. X      {
  24839. X         if (juli3Dmode==3)
  24840. X         {
  24841. X            color = (int) (128l * zpixel / zdots);
  24842. X            if ((row + col) & 1)
  24843. X            {
  24844. X
  24845. X               (*plot) (col, row, 127 - color);
  24846. X            }
  24847. X            else
  24848. X            {
  24849. X               color = (int) (multiply((long) color << 16, brratio, 16) >> 16);
  24850. X               if (color < 1)
  24851. X                  color = 1;
  24852. X               if (color > 127)
  24853. X                  color = 127;
  24854. X               (*plot) (col, row, 127 + bbase - color);
  24855. X            }
  24856. X         }
  24857. X         else
  24858. X         {
  24859. X            color = (int) (254l * zpixel / zdots);
  24860. X            (*plot) (col, row, color + 1);
  24861. X         }
  24862. X         plotted = 1;
  24863. X         break;
  24864. X      }
  24865. X      mx += dmx;
  24866. X      my += dmy;
  24867. X      jx += djx;
  24868. X      jy += djy;
  24869. X   }
  24870. X   return (0);
  24871. X}
  24872. X
  24873. Xint
  24874. Xzlinefp(double x, double y)
  24875. X{
  24876. X   static int keychk = 0;
  24877. X   xpixelfp = x;
  24878. X   ypixelfp = y;
  24879. X   mxfp = mxminfp;
  24880. X   myfp = myminfp;
  24881. X   switch(juli3Dmode)
  24882. X   {
  24883. X   case 0:
  24884. X   case 1:
  24885. X      Perfp = &LeftEyefp;
  24886. X      break;
  24887. X   case 2:
  24888. X      Perfp = &RightEyefp;
  24889. X      break;
  24890. X   case 3:
  24891. X      if ((row + col) & 1)
  24892. X         Perfp = &LeftEyefp;
  24893. X      else
  24894. X         Perfp = &RightEyefp;
  24895. X      break;
  24896. X   }
  24897. X   jbfp_per_pixel();
  24898. X   for (zpixel = 0; zpixel < zdots; zpixel++)
  24899. X   {
  24900. X      old.x = jxfp;
  24901. X      old.y = jyfp;
  24902. X      jbcfp.x = mxfp;
  24903. X      jbcfp.y = myfp;
  24904. X      qc = param[0];
  24905. X      qci = param[1];
  24906. X      qcj = param[2];
  24907. X      qck = param[3];
  24908. X#ifdef XFRACT      
  24909. X      if (keychk++ > 500)
  24910. X      {
  24911. X         keychk = 0;
  24912. X         if (check_key())
  24913. X            return (-1);
  24914. X      }
  24915. X#else
  24916. X      if (check_key())
  24917. X         return (-1);
  24918. X#endif      
  24919. X      tempsqrx = sqr(old.x);
  24920. X      tempsqry = sqr(old.y);
  24921. X
  24922. X      for (n = 0; n < maxit; n++)
  24923. X         if (fractalspecific[neworbittype].orbitcalc())
  24924. X            break;
  24925. X      if (n == maxit)
  24926. X      {
  24927. X         if (juli3Dmode == 3)
  24928. X         {
  24929. X            color = (int) (128l * zpixel / zdots);
  24930. X            if ((row + col) & 1)
  24931. X               (*plot) (col, row, 127 - color);
  24932. X            else
  24933. X            {
  24934. X               color = color * brratiofp;
  24935. X               if (color < 1)
  24936. X                  color = 1;
  24937. X               if (color > 127)
  24938. X                  color = 127;
  24939. X               (*plot) (col, row, 127 + bbase - color);
  24940. X            }
  24941. X         }
  24942. X         else
  24943. X         {
  24944. X            color = (int) (254l * zpixel / zdots);
  24945. X            (*plot) (col, row, color + 1);
  24946. X         }
  24947. X         plotted = 1;
  24948. X         break;
  24949. X      }
  24950. X      mxfp += dmxfp;
  24951. X      myfp += dmyfp;
  24952. X      jxfp += djxfp;
  24953. X      jyfp += djyfp;
  24954. X   }
  24955. X   return (0);
  24956. X}
  24957. X
  24958. Xint
  24959. XStd4dFractal(void)
  24960. X{
  24961. X   long x, y;
  24962. X   int xdot, ydot;
  24963. X   c_exp = param[2];
  24964. X   if(neworbittype == LJULIAZPOWER)
  24965. X   {
  24966. X      if(c_exp < 1)
  24967. X         c_exp = 1;
  24968. X      if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
  24969. X          fractalspecific[neworbittype].orbitcalc = longZpowerFractal;
  24970. X      else
  24971. X          fractalspecific[neworbittype].orbitcalc = longCmplxZpowerFractal;
  24972. X   }
  24973. X
  24974. X   for (y = 0, ydot = (ydots >> 1) - 1; ydot >= 0; ydot--, y -= inch_per_ydot)
  24975. X   {
  24976. X      plotted = 0;
  24977. X      x = -(width >> 1);
  24978. X      for (xdot = 0; xdot < xdots; xdot++, x += inch_per_xdot)
  24979. X      {
  24980. X         col = xdot;
  24981. X         row = ydot;
  24982. X         if (zline(x, y) < 0)
  24983. X            return (-1);
  24984. X         col = xdots - col - 1;
  24985. X         row = ydots - row - 1;
  24986. X         if (zline(-x, -y) < 0)
  24987. X            return (-1);
  24988. X      }
  24989. X      if (plotted == 0)
  24990. X      {
  24991. X         if (y == 0)
  24992. X           plotted = -1;  /* no points first pass; don't give up */
  24993. X         else  
  24994. X           break;
  24995. X      }     
  24996. X   }
  24997. X   return (0);
  24998. X}
  24999. Xint
  25000. XStd4dfpFractal(void)
  25001. X{
  25002. X   double x, y;
  25003. X   int xdot, ydot;
  25004. X   c_exp = param[2];
  25005. X
  25006. X   if(neworbittype == FPJULIAZPOWER)
  25007. X   {
  25008. X      if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
  25009. X          fractalspecific[neworbittype].orbitcalc = floatZpowerFractal;
  25010. X      else
  25011. X          fractalspecific[neworbittype].orbitcalc = floatCmplxZpowerFractal;
  25012. X      get_julia_attractor (param[0], param[1]);    /* another attractor? */
  25013. X   }
  25014. X
  25015. X   for (y = 0, ydot = (ydots >> 1) - 1; ydot >= 0; ydot--, y -= inch_per_ydotfp)
  25016. X   {
  25017. X      plotted = 0;
  25018. X      x = -widthfp / 2;
  25019. X      for (xdot = 0; xdot < xdots; xdot++, x += inch_per_xdotfp)
  25020. X      {
  25021. X         col = xdot;
  25022. X         row = ydot;
  25023. X         if (zlinefp(x, y) < 0)
  25024. X            return (-1);
  25025. X         col = xdots - col - 1;
  25026. X         row = ydots - row - 1;
  25027. X         if (zlinefp(-x, -y) < 0)
  25028. X            return (-1);
  25029. X      }
  25030. X      if (plotted == 0)
  25031. X      {
  25032. X         if (y == 0)
  25033. X           plotted = -1;  /* no points first pass; don't give up */
  25034. X         else  
  25035. X           break;
  25036. X      }     
  25037. X   }
  25038. X   return (0);
  25039. X}
  25040. SHAR_EOF
  25041. $TOUCH -am 1028230093 jb.c &&
  25042. chmod 0644 jb.c ||
  25043. echo "restore of jb.c failed"
  25044. set `wc -c jb.c`;Wc_c=$1
  25045. if test "$Wc_c" != "12009"; then
  25046.     echo original size 12009, current size $Wc_c
  25047. fi
  25048. # ============= jiim.c ==============
  25049. echo "x - extracting jiim.c (Text)"
  25050. sed 's/^X//' << 'SHAR_EOF' > jiim.c &&
  25051. X/*
  25052. X * JIIM.C
  25053. X *
  25054. X * Generates Inverse Julia in real time, lets move a cursor which determines
  25055. X * the J-set.
  25056. X *
  25057. X *  The J-set is generated in a fixed-size window, a third of the screen.
  25058. X *
  25059. X * This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  25060. X *
  25061. X *
  25062. X * The routines used to set/move the cursor and to save/restore the
  25063. X * window were "borrowed" from editpal.c (TW - now we *use* the editpal code)
  25064. X *     (if you don't know how to write good code, look for someone who does)
  25065. X *
  25066. X *    JJB  [jbuhler@gidef.edu.ar]
  25067. X *    TIW  Tim Wegner
  25068. X *    MS   Michael Snyder
  25069. X *    KS   Ken Shirriff
  25070. X * Revision History:
  25071. X *
  25072. X *        7-28-92       JJB  Initial release out of editpal.c
  25073. X *        7-29-92       JJB  Added SaveRect() & RestoreRect() - now the
  25074. X *                           screen is restored after leaving.
  25075. X *        7-30-92       JJB  Now, if the cursor goes into the window, the
  25076. X *                           window is moved to the other side of the screen.
  25077. X *                           Worked from the first time!
  25078. X *        10-09-92      TIW  A major rewrite that merged cut routines duplicated
  25079. X *                           in EDITPAL.C and added orbits feature.
  25080. X *        11-02-92      KS   Made cursor blink
  25081. X *        11-18-92      MS   Altered Inverse Julia to use MIIM method.
  25082. X *      11-25-92    MS   Modified MIIM support routines to better be
  25083. X *                 shared with stand-alone inverse julia in
  25084. X *                 LORENZ.C, and to use DISKVID for swap space.
  25085. X *        05-05-93      TIW  Boy this change file really got out of date.
  25086. X *                 Added orbits capability, various commands, some 
  25087. X *                  of Dan Farmer's ideas like circles and lines 
  25088. X *                 connecting orbits points.
  25089. X */
  25090. X
  25091. X#include <stdio.h>
  25092. X#include <stdlib.h>
  25093. X#include <string.h>
  25094. X
  25095. X#ifndef XFRACT
  25096. X#include <stdarg.h>
  25097. X#include <dos.h>     /* for FP_SEG & FP_OFF */
  25098. X#else
  25099. X#include <varargs.h>
  25100. X#endif
  25101. X
  25102. X#include <math.h>
  25103. X
  25104. X#ifdef __TURBOC__
  25105. X#   include <mem.h>   /* to get mem...() declarations */
  25106. X#endif
  25107. X
  25108. X#include "helpdefs.h"
  25109. X#include "fractint.h" /* for overlay stuff */
  25110. X#include "fractype.h"
  25111. X#include "prototyp.h"
  25112. X
  25113. X#define FAR_RESERVE     8192L     /* amount of far mem we will leave avail. */
  25114. X#define MAXRECT         1024      /* largest width of SaveRect/RestoreRect */
  25115. X
  25116. X#define newx(size)     mem_alloc(size)
  25117. X#define delete(block)
  25118. X
  25119. Xenum stored_at_values
  25120. X   {
  25121. X   NOWHERE,
  25122. X   DISK,
  25123. X   MEMORY
  25124. X   } ;
  25125. X
  25126. X/* borrowed from LORENZ.C */
  25127. Xstruct affine
  25128. X{
  25129. X   /* weird order so a,b,e and c,d,f are vectors */
  25130. X   double a;
  25131. X   double b;
  25132. X   double e;
  25133. X   double c;
  25134. X   double d;
  25135. X   double f;
  25136. X};
  25137. X
  25138. Xextern int  setup_convert_to_screen(struct affine *);
  25139. X
  25140. Xint show_numbers =0;              /* toggle for display of coords */
  25141. Xint stored_at;
  25142. Xchar far *memory = NULL;            /* pointer to saved rectangle */
  25143. XFILE *file;
  25144. Xint windows = 0;               /* windows management system */
  25145. X
  25146. Xextern char scrnfile[];   /* file where screen portion is */
  25147. X                  /* stored */
  25148. Xextern BYTE      *line_buff;   /* must be alloced!!! */
  25149. Xextern int           sxdots;             /* width of physical screen         */
  25150. Xextern int           sydots;             /* depth of physical screen         */
  25151. Xextern int           sxoffs;             /* start of logical screen          */
  25152. Xextern int           syoffs;             /* start of logical screen          */
  25153. Xextern int           strlocn[];          /* 10K buffer to store classes in   */
  25154. Xextern int           colors;             /* # colors avail.                  */
  25155. Xextern int       using_jiim;
  25156. Xextern int       viewwindow;     /* 0 for full screen, 1 for window */
  25157. Xextern float     viewreduction;  /* window auto-sizing */
  25158. Xextern int       viewcrop;               /* nonzero to crop default coords */
  25159. Xextern float     finalaspectratio;              /* for view shape and rotation */
  25160. Xextern int       viewxdots,viewydots;   /* explicit view sizing */
  25161. Xextern double    dxsize, dysize;
  25162. Xextern int       xdots;                  /* width of logical screen          */
  25163. Xextern int       ydots;                  /* depth of logical screen          */
  25164. Xextern double    xxmax,xxmin;    /* limits of the "window"       */
  25165. Xextern double    yymax,yymin;    /* on the z-plane               */
  25166. Xextern int           color_bright;       /* brightest color in palette       */
  25167. Xextern int           color_dark;         /* darkest color in palette         */
  25168. Xextern int           color_medium;       /* nearest to medbright gray color  */
  25169. Xextern int           lookatmouse;        /* mouse mode for getakey(), etc    */
  25170. Xextern int           maxit;                  /* try this many iterations */
  25171. Xextern int           fractype;       /* fractal type */
  25172. Xextern _CMPLX     old,new,init;
  25173. Xextern double tempsqrx,tempsqry;
  25174. Xstatic int xc, yc;                       /* corners of the window */
  25175. Xstatic int xd, yd;                       /* dots in the window    */
  25176. Xextern void displayc(int x, int y, int fg, int bg, int ch);
  25177. Xextern float screenaspect;
  25178. Xdouble xcjul = BIG;
  25179. Xdouble ycjul = BIG;
  25180. Xextern int hasinverse;
  25181. X
  25182. Xvoid displays(int x, int y, int fg, int bg, char *str, int len)
  25183. X{
  25184. X   int i;
  25185. X   for(i=0;i<len; i++)
  25186. X      displayc(x+i*8, y, fg, bg, str[i]);
  25187. X}
  25188. X
  25189. X/* circle routines from Dr. Dobbs June 1990 */
  25190. Xint xbase, ybase;
  25191. Xunsigned xAspect, yAspect;
  25192. X
  25193. Xvoid SetAspect(double aspect)
  25194. X{
  25195. X   xAspect = 0;
  25196. X   yAspect = 0;
  25197. X   aspect = fabs(aspect);
  25198. X   if (aspect != 1.0)
  25199. X      if (aspect > 1.0)
  25200. X     yAspect = 65536.0 / aspect;
  25201. X      else
  25202. X     xAspect = 65536.0 * aspect;
  25203. X}
  25204. X
  25205. Xvoid _fastcall c_putcolor(int x, int y, int color)
  25206. X   {
  25207. X   /* avoid writing outside window */
  25208. X   if ( x < xc || y < yc || x >= xc + xd || y >= yc + yd )
  25209. X      return ;
  25210. X   if(y >= sydots - show_numbers) /* avoid overwriting coords */
  25211. X      return;
  25212. X   if(windows == 2) /* avoid overwriting fractal */
  25213. X      if (0 <= x && x < xdots && 0 <= y && y < ydots)
  25214. X     return;
  25215. X   putcolor(x, y, color);
  25216. X   }
  25217. X
  25218. X
  25219. Xint  c_getcolor(int x, int y)
  25220. X   {
  25221. X   /* avoid reading outside window */
  25222. X   if ( x < xc || y < yc || x >= xc + xd || y >= yc + yd )
  25223. X      return 1000;
  25224. X   if(y >= sydots - show_numbers) /* avoid overreading coords */
  25225. X      return 1000;
  25226. X   if(windows == 2) /* avoid overreading fractal */
  25227. X      if (0 <= x && x < xdots && 0 <= y && y < ydots)
  25228. X     return 1000;
  25229. X   return getcolor(x, y);
  25230. X   }
  25231. X
  25232. Xvoid circleplot(int x, int y, int color)
  25233. X{
  25234. X   if (xAspect == 0)
  25235. X      if (yAspect == 0)
  25236. X     c_putcolor(x+xbase, y+ybase,color);
  25237. X      else
  25238. X     c_putcolor(x+xbase, (short)(ybase + (((long) y * (long) yAspect) >> 16)),color);
  25239. X   else
  25240. X      c_putcolor((int)(xbase + (((long) x * (long) xAspect) >> 16)), y+ybase, color);
  25241. X}
  25242. X
  25243. Xvoid plot8(int x, int y, int color)
  25244. X{
  25245. X   circleplot(x,y,color);
  25246. X   circleplot(-x,y,color);
  25247. X   circleplot(x,-y,color);
  25248. X   circleplot(-x,-y,color);
  25249. X   circleplot(y,x,color);
  25250. X   circleplot(-y,x,color);
  25251. X   circleplot(y,-x,color);
  25252. X   circleplot(-y,-x,color);
  25253. X}
  25254. X
  25255. Xvoid circle(int radius, int color)
  25256. X{
  25257. X   int x,y,sum;
  25258. X
  25259. X   x = 0;
  25260. X   y = radius << 1;
  25261. X   sum = 0;
  25262. X
  25263. X   while (x <= y)
  25264. X   {
  25265. X      if ( !(x & 1) )   /* plot if x is even */
  25266. X     plot8( x >> 1, (y+1) >> 1, color);
  25267. X      sum += (x << 1) + 1;
  25268. X      x++;
  25269. X      if (sum > 0)
  25270. X      {
  25271. X     sum -= (y << 1) - 1;
  25272. X     y--;
  25273. X      }
  25274. X   }
  25275. X}
  25276. X
  25277. X
  25278. X/*
  25279. X * MIIM section:
  25280. X *
  25281. X * Global variables and service functions used for computing
  25282. X * MIIM Julias will be grouped here (and shared by code in LORENZ.C)
  25283. X *
  25284. X */
  25285. X
  25286. X
  25287. X long   ListFront, ListBack, ListSize;  /* head, tail, size of MIIM Queue */
  25288. X long   lsize, lmax;            /* how many in queue (now, ever) */
  25289. X int    maxhits = 1;
  25290. X int    OKtoMIIM;
  25291. X int    SecretExperimentalMode;
  25292. X float  luckyx = 0, luckyy = 0;
  25293. X extern int debugflag;
  25294. X extern int           bitshift;         /* bit shift for fudge */
  25295. X extern long          fudge;            /* fudge factor (2**n) */
  25296. X
  25297. X
  25298. Xlong lsqrt(long f)
  25299. X{
  25300. X    int N;
  25301. X    unsigned long y0, z;
  25302. X    static long a=0, b=0, c=0;                  /* constant factors */
  25303. X
  25304. X    if (f == 0)
  25305. X    return f;
  25306. X    if (f <  0)
  25307. X    return 0;
  25308. X
  25309. X    if (a==0)                                   /* one-time compute consts */
  25310. X    {
  25311. X    a = fudge * .41731;
  25312. X    b = fudge * .59016;
  25313. X    c = fudge * .7071067811;
  25314. X    }
  25315. X
  25316. X    N  = 0;
  25317. X    while (f & 0xff000000L)                     /* shift arg f into the */
  25318. X    {                                           /* range: 0.5 <= f < 1  */
  25319. X    N++;
  25320. X    f /= 2;
  25321. X    }
  25322. X    while (!(f & 0xff800000L))
  25323. X    {
  25324. X    N--;
  25325. X    f *= 2;
  25326. X    }
  25327. X
  25328. X    y0 = a + multiply(b, f,  bitshift);         /* Newton's approximation */
  25329. X
  25330. X    z  = y0 + divide (f, y0, bitshift);
  25331. X    y0 = (z>>2) + divide(f, z,  bitshift);
  25332. X
  25333. X    if (N % 2)
  25334. X    {
  25335. X    N++;
  25336. X    y0 = multiply(c,y0, bitshift);
  25337. X    }
  25338. X    N /= 2;
  25339. X    if (N >= 0)
  25340. X    return y0 <<  N;                        /* correct for shift above */
  25341. X    else
  25342. X    return y0 >> -N;
  25343. X}
  25344. X
  25345. X#define SinCosFudge 0x10000L
  25346. X
  25347. X
  25348. XLCMPLX
  25349. XComplexSqrtLong(long x, long y)
  25350. X{
  25351. X   double    mag, theta;
  25352. X   long      maglong, thetalong;
  25353. X   LCMPLX    result;
  25354. X
  25355. X#if 1
  25356. X   mag       = sqrt(sqrt(((double) multiply(x,x,bitshift))/fudge +
  25357. X             ((double) multiply(y,y,bitshift))/ fudge));
  25358. X   maglong   = mag * fudge;
  25359. X#else
  25360. X   maglong   = lsqrt(lsqrt(multiply(x,x,bitshift)+multiply(y,y,bitshift)));
  25361. X#endif
  25362. X   theta     = atan2((double) y/fudge, (double) x/fudge)/2;
  25363. X   thetalong = theta * SinCosFudge;
  25364. X   SinCos086(thetalong, &result.y, &result.x);
  25365. X   result.x  = multiply(result.x << (bitshift - 16), maglong, bitshift);
  25366. X   result.y  = multiply(result.y << (bitshift - 16), maglong, bitshift);
  25367. X   return result;
  25368. X}
  25369. X
  25370. X_CMPLX
  25371. XComplexSqrtFloat(double x, double y)
  25372. X{
  25373. X   double mag   = sqrt(sqrt(x*x + y*y));
  25374. X   double theta = atan2(y, x) / 2;
  25375. X   _CMPLX  result;
  25376. X
  25377. X   FPUsincos(&theta, &result.y, &result.x);
  25378. X   result.x *= mag;
  25379. X   result.y *= mag;
  25380. X   return result;
  25381. X}
  25382. X
  25383. X
  25384. Xextern char dstack[];
  25385. X
  25386. Xstatic void fillrect(int x, int y, int width, int depth, int color)
  25387. X{
  25388. X   /* fast version of fillrect */
  25389. X   if(hasinverse == 0)
  25390. X      return;
  25391. X   memset(dstack, color % colors, width);
  25392. X   while (depth-- > 0)
  25393. X   {
  25394. X      if(keypressed()) /* we could do this less often when in fast modes */
  25395. X         return;
  25396. X      putrow(x, y++, width, dstack);
  25397. X   }
  25398. X}
  25399. X
  25400. X/*
  25401. X * Queue/Stack Section:
  25402. X *
  25403. X * Defines a buffer that can be used as a FIFO queue or LIFO stack.
  25404. X */
  25405. X
  25406. Xint
  25407. XQueueEmpty()        /* True if NO points remain in queue */
  25408. X{
  25409. X   return (ListFront == ListBack);
  25410. X}
  25411. X
  25412. Xint
  25413. XQueueFull()        /* True if room for NO more points in queue */
  25414. X{
  25415. X   return (((ListFront + 1) % ListSize) == ListBack);
  25416. X}
  25417. X
  25418. Xint
  25419. XQueueFullAlmost()    /* True if room for ONE more point in queue */
  25420. X{
  25421. X   return (((ListFront + 2) % ListSize) == ListBack);
  25422. X}
  25423. X
  25424. Xvoid
  25425. XClearQueue()
  25426. X{
  25427. X   ListFront = ListBack = lsize = lmax = 0;
  25428. X}
  25429. X
  25430. X
  25431. X/*
  25432. X * Queue functions for MIIM julia:
  25433. X * move to JIIM.C when done
  25434. X */
  25435. X
  25436. Xextern long  ListSize, ListFront, ListBack, lsize, lmax;
  25437. Xextern float luckyx, luckyy;
  25438. X
  25439. Xint Init_Queue(unsigned long request)
  25440. X{
  25441. X   extern int _fastcall common_startdisk(long, long, int);
  25442. X   extern unsigned int xmmlongest();
  25443. X   extern unsigned int xmmreallocate(unsigned int, unsigned int);
  25444. X   extern int dotmode;
  25445. X   unsigned int        largest;
  25446. X
  25447. X
  25448. X   if (dotmode == 11)
  25449. X   {
  25450. X      static char far *nono = "Don't try this in disk video mode, kids...\n";
  25451. X      stopmsg(0, nono);
  25452. X      ListSize = 0;
  25453. X      return 0;
  25454. X   }
  25455. X
  25456. X#if 0
  25457. X   if (xmmquery() && debugflag != 420)    /* use LARGEST extended mem */
  25458. X      if ((largest = xmmlongest()) > request / 128)
  25459. X     request   = (unsigned long) largest * 128L;
  25460. X#endif
  25461. X
  25462. X   for (ListSize = request; ListSize > 1024; ListSize -= 512)
  25463. X      switch (common_startdisk(ListSize * 8, 1, 256))
  25464. X      {
  25465. X     case 0:                        /* success */
  25466. X        ListFront = ListBack = 0;
  25467. X        lsize = lmax = 0;
  25468. X        return 1;
  25469. X     case -1:
  25470. X        continue;            /* try smaller queue size */
  25471. X     case -2:
  25472. X        ListSize = 0;               /* cancelled by user      */
  25473. X        return 0;
  25474. X      }
  25475. X
  25476. X   /* failed to get memory for MIIM Queue */
  25477. X   ListSize = 0;
  25478. X   return 0;
  25479. X}
  25480. X
  25481. Xvoid
  25482. XFree_Queue()
  25483. X{
  25484. X   enddisk();
  25485. X   ListFront = ListBack = ListSize = lsize = lmax = 0;
  25486. X}
  25487. X
  25488. Xextern int ToMemDisk  (long, int, void far *);
  25489. Xextern int FromMemDisk(long, int, void far *);
  25490. X
  25491. Xint
  25492. XPushLong(long x, long y)
  25493. X{
  25494. X   if (((ListFront + 1) % ListSize) != ListBack)
  25495. X   {
  25496. X      if (ToMemDisk(8*ListFront, sizeof(x), &x) &&
  25497. X      ToMemDisk(8*ListFront +sizeof(x), sizeof(y), &y))
  25498. X      {
  25499. X     ListFront = (ListFront + 1) % ListSize;
  25500. X     if (++lsize > lmax)
  25501. X     {
  25502. X        lmax   = lsize;
  25503. X        luckyx = x;
  25504. X        luckyy = y;
  25505. X     }
  25506. X     return 1;
  25507. X      }
  25508. X   }
  25509. X   return 0;            /* fail */
  25510. X}
  25511. X
  25512. Xint
  25513. XPushFloat(float x, float y)
  25514. X{
  25515. X   if (((ListFront + 1) % ListSize) != ListBack)
  25516. X   {
  25517. X      if (ToMemDisk(8*ListFront, sizeof(x), &x) &&
  25518. X      ToMemDisk(8*ListFront +sizeof(x), sizeof(y), &y))
  25519. X      {
  25520. X     ListFront = (ListFront + 1) % ListSize;
  25521. X     if (++lsize > lmax)
  25522. X     {
  25523. X        lmax   = lsize;
  25524. X        luckyx = x;
  25525. X        luckyy = y;
  25526. X     }
  25527. X     return 1;
  25528. X      }
  25529. X   }
  25530. X   return 0;            /* fail */
  25531. X}
  25532. X
  25533. X_CMPLX
  25534. XPopFloat()
  25535. X{
  25536. X   _CMPLX pop;
  25537. X   float  popx, popy;
  25538. X
  25539. X   if (!QueueEmpty())
  25540. X   {
  25541. X      ListFront--;
  25542. X      if (ListFront < 0)
  25543. X      ListFront = ListSize - 1;
  25544. X      if (FromMemDisk(8*ListFront, sizeof(popx), &popx) &&
  25545. X      FromMemDisk(8*ListFront +sizeof(popx), sizeof(popy), &popy))
  25546. X      {
  25547. X     pop.x = popx;
  25548. X     pop.y = popy;
  25549. X     --lsize;
  25550. X      }
  25551. X      return pop;
  25552. X   }
  25553. X   pop.x = 0;
  25554. X   pop.y = 0;
  25555. X   return pop;
  25556. X}
  25557. X
  25558. XLCMPLX
  25559. XPopLong()
  25560. X{
  25561. X   LCMPLX pop;
  25562. X
  25563. X   if (!QueueEmpty())
  25564. X   {
  25565. X      ListFront--;
  25566. X      if (ListFront < 0)
  25567. X      ListFront = ListSize - 1;
  25568. X      if (FromMemDisk(8*ListFront, sizeof(pop.x), &pop.x) &&
  25569. X      FromMemDisk(8*ListFront +sizeof(pop.x), sizeof(pop.y), &pop.y))
  25570. X     --lsize;
  25571. X      return pop;
  25572. X   }
  25573. X   pop.x = 0;
  25574. X   pop.y = 0;
  25575. X   return pop;
  25576. X}
  25577. X
  25578. Xint
  25579. XEnQueueFloat(float x, float y)
  25580. X{
  25581. X   return PushFloat(x, y);
  25582. X}
  25583. X
  25584. Xint
  25585. XEnQueueLong(long x, long y)
  25586. X{
  25587. X   return PushLong(x, y);
  25588. X}
  25589. X
  25590. X_CMPLX
  25591. XDeQueueFloat()
  25592. X{
  25593. X   _CMPLX out;
  25594. X   float outx, outy;
  25595. X
  25596. X   if (ListBack != ListFront)
  25597. X   {
  25598. X      if (FromMemDisk(8*ListBack, sizeof(outx), &outx) &&
  25599. X      FromMemDisk(8*ListBack +sizeof(outx), sizeof(outy), &outy))
  25600. X      {
  25601. X     ListBack = (ListBack + 1) % ListSize;
  25602. X     out.x = outx;
  25603. X     out.y = outy;
  25604. X     lsize--;
  25605. X      }
  25606. X      return out;
  25607. X   }
  25608. X   out.x = 0;
  25609. X   out.y = 0;
  25610. X   return out;
  25611. X}
  25612. X
  25613. XLCMPLX
  25614. XDeQueueLong()
  25615. X{
  25616. X   LCMPLX out;
  25617. X   out.x = 0;
  25618. X   out.y = 0;
  25619. X
  25620. X   if (ListBack != ListFront)
  25621. X   {
  25622. X      if (FromMemDisk(8*ListBack, sizeof(out.x), &out.x) &&
  25623. X      FromMemDisk(8*ListBack +sizeof(out.x), sizeof(out.y), &out.y))
  25624. X      {
  25625. X     ListBack = (ListBack + 1) % ListSize;
  25626. X     lsize--;
  25627. X      }
  25628. X      return out;
  25629. X   }
  25630. X   out.x = 0;
  25631. X   out.y = 0;
  25632. X   return out;
  25633. X}
  25634. X
  25635. X
  25636. X
  25637. X/*
  25638. X * End MIIM section;
  25639. X */
  25640. X
  25641. X
  25642. X
  25643. Xstatic BOOLEAN MemoryAlloc(long size)
  25644. X{
  25645. X   char far *temp;
  25646. X   
  25647. X   if (debugflag == 420)
  25648. X      return(FALSE);
  25649. X   temp = (char far *)farmemalloc(FAR_RESERVE);   /* minimum free space */
  25650. X
  25651. X   if (temp == NULL)
  25652. X   {
  25653. X      stored_at = NOWHERE;
  25654. X      return (FALSE);   /* can't do it */
  25655. X   }
  25656. X
  25657. X   memory = (char far *)farmemalloc( size );
  25658. X   farmemfree(temp);
  25659. X
  25660. X   if ( memory == NULL )
  25661. X   {
  25662. X      stored_at = NOWHERE;
  25663. X      return (FALSE);
  25664. X   }
  25665. X   else
  25666. X   {
  25667. X      stored_at = MEMORY;
  25668. X      return (TRUE);
  25669. X   }
  25670. X}
  25671. X
  25672. X
  25673. Xstatic void SaveRect(int x, int y, int width, int depth)
  25674. X{
  25675. X   char buff[MAXRECT];
  25676. X   int  yoff;
  25677. X   if(hasinverse == 0)
  25678. X      return;
  25679. X   /* first, do any de-allocationg */
  25680. X
  25681. X   switch( stored_at )
  25682. X   {
  25683. X   case NOWHERE:
  25684. X      break;
  25685. X
  25686. X   case DISK:
  25687. X      break;
  25688. X
  25689. X   case MEMORY:
  25690. X      if (memory != NULL)
  25691. X      {
  25692. X     farmemfree(memory);
  25693. X      }
  25694. X      memory = NULL;
  25695. X      break;
  25696. X   }
  25697. X
  25698. X   /* allocate space and store the rect */
  25699. X
  25700. X   memset(dstack, color_dark, width);
  25701. X   if ( MemoryAlloc( (long)width*(long)depth) )
  25702. X   {
  25703. X      char far  *ptr = memory;
  25704. X      char far  *bufptr = buff; /* MSC needs this indirection to get it right */
  25705. X
  25706. X      Cursor_Hide();
  25707. X      for (yoff=0; yoff<depth; yoff++)
  25708. X      {
  25709. X     getrow(x, y+yoff, width, buff);
  25710. X     putrow(x, y+yoff, width, dstack);
  25711. X     movedata(FP_SEG(bufptr), FP_OFF(bufptr), FP_SEG(ptr), FP_OFF(ptr), width);
  25712. X     ptr = (char far *)normalize(ptr+width);
  25713. X      }
  25714. X      Cursor_Show();
  25715. X   }
  25716. X
  25717. X   else /* to disk */
  25718. X   {
  25719. X      stored_at = DISK;
  25720. X
  25721. X      if ( file == NULL )
  25722. X      {
  25723. X     file = fopen(scrnfile, "w+b");
  25724. X     if (file == NULL)
  25725. X     {
  25726. X        stored_at = NOWHERE;
  25727. X        buzzer(3);
  25728. X        return ;
  25729. X     }
  25730. X      }
  25731. X
  25732. X      rewind(file);
  25733. X      Cursor_Hide();
  25734. X      for (yoff=0; yoff<depth; yoff++)
  25735. X      {
  25736. X     getrow(x, y+yoff, width, buff);
  25737. X     putrow(x, y+yoff, width, dstack);
  25738. X     if ( fwrite(buff, width, 1, file) != 1 )
  25739. X     {
  25740. X        buzzer(3);
  25741. X        break;
  25742. X     }
  25743. X      }
  25744. X      Cursor_Show();
  25745. X   }
  25746. X}
  25747. X
  25748. X
  25749. Xstatic void RestoreRect(x, y, width, depth)
  25750. X{
  25751. X   char buff[MAXRECT];
  25752. X   int  yoff;
  25753. X   if(hasinverse == 0)
  25754. X      return;
  25755. X
  25756. X   switch ( stored_at )
  25757. X   {
  25758. X   case DISK:
  25759. X      rewind(file);
  25760. X      Cursor_Hide();
  25761. X      for (yoff=0; yoff<depth; yoff++)
  25762. X      {
  25763. X     if ( fread(buff, width, 1, file) != 1 )
  25764. X     {
  25765. X        buzzer(3);
  25766. X        break;
  25767. X     }
  25768. X     putrow(x, y+yoff, width, buff);
  25769. X      }
  25770. X      Cursor_Show();
  25771. X      break;
  25772. X
  25773. X   case MEMORY:
  25774. X      {
  25775. X     char far  *ptr = memory;
  25776. X     char far  *bufptr = buff; /* MSC needs this indirection to get it right */
  25777. X
  25778. X     Cursor_Hide();
  25779. X     for (yoff=0; yoff<depth; yoff++)
  25780. X     {
  25781. X        movedata(FP_SEG(ptr), FP_OFF(ptr), FP_SEG(bufptr), FP_OFF(bufptr), width);
  25782. X        putrow(x, y+yoff, width, buff);
  25783. X        ptr = (char far *)normalize(ptr+width);
  25784. X     }
  25785. X     Cursor_Show();
  25786. X     break;
  25787. X      }
  25788. X
  25789. X   case NOWHERE:
  25790. X      break;
  25791. X   } /* switch */
  25792. X}
  25793. X
  25794. X/*
  25795. X * interface to FRACTINT
  25796. X */
  25797. Xint jfractype;
  25798. X
  25799. Xextern int row, col;
  25800. Xextern double far *dx0, far *dy0;
  25801. Xextern double far *dx1, far *dy1;
  25802. Xextern int integerfractal;
  25803. Xextern long far *lx0, far *ly0;
  25804. Xextern long far *lx1, far *ly1;
  25805. Xextern int bitshift;
  25806. Xextern int helpmode;
  25807. X
  25808. X/* the following macros and function call the setup, per_pixel, and orbit
  25809. X   routines and calculate an orbit at row 0 column 0. Have to save and 
  25810. X   restore the first elements of dx0 ... dy1 as well as row and col */
  25811. X
  25812. X#define PER_IMAGE fractalspecific[o_fractype].per_image
  25813. X#define PER_PIXEL fractalspecific[o_fractype].per_pixel
  25814. X#define ORBITCALC   fractalspecific[o_fractype].orbitcalc
  25815. X
  25816. Xint do_fractal_routines(double cr, double ci, int (*func)())
  25817. X{
  25818. X   int ret;
  25819. X   int old_row, old_col;
  25820. X   double old_dx0, old_dx1, old_dy0, old_dy1;
  25821. X   old_dx0 = *dx0; old_dx1 = *dx1;
  25822. X   old_dy0 = *dy0; old_dy1 = *dy1;
  25823. X   old_row = row;  old_col = col;
  25824. X   row = col = 0;
  25825. X   *dx0 = cr; *dy0 = ci; *dx1 = *dy1 = 0.0;
  25826. X   ret = func();
  25827. X   *dx0 = old_dx0; *dx1 = old_dx1;
  25828. X   *dy0 = old_dy0; *dy1 = old_dy1;
  25829. X   row = old_row;  col = old_col;
  25830. X   return(ret);
  25831. X}
  25832. X
  25833. X
  25834. Xvoid Jiim(int which)         /* called by fractint */
  25835. X{
  25836. X   struct affine cvt;
  25837. X   int exact = 0;
  25838. X   int oldhelpmode;
  25839. X   int count = 0;            /* coloring julia */
  25840. X   static int mode = 0;      /* point, circle, ... */
  25841. X   int       oldlookatmouse = lookatmouse;
  25842. X   double cr, ci, r;
  25843. X   int xfactor, yfactor;             /* aspect ratio          */
  25844. X
  25845. X   int xoff, yoff;                   /* center of the window  */
  25846. X   int x, y;
  25847. X   int still, kbdchar;
  25848. X   int xcrsr,ycrsr;     /* coords of the cursor / offsets to move it  */
  25849. X   int iter;
  25850. X   int color;
  25851. X   float zoom;
  25852. X   int oldsxoffs, oldsyoffs;
  25853. X   int savehasinverse;
  25854. X   int (*oldcalctype)();
  25855. X   extern int (*calctype)();
  25856. X   int o_fractype;
  25857. X   int old_x, old_y;
  25858. X   double aspect;
  25859. X   static int randir = 0;
  25860. X   static int rancnt = 0;
  25861. X   static _CMPLX SaveC = {-3000.0, -3000.0};
  25862. X   int actively_computing = 1;
  25863. X   int first_time = 1;
  25864. X
  25865. X   ENTER_OVLY(OVLY_ROTATE);
  25866. X   /* must use standard fractal and have a float variant */
  25867. X   if(fractalspecific[fractype].calctype != StandardFractal ||
  25868. X     (fractalspecific[fractype].isinteger &&
  25869. X     fractalspecific[fractype].tofloat == NOFRACTAL))
  25870. X   {
  25871. X       EXIT_OVLY;
  25872. X       return;
  25873. X   }
  25874. X   oldhelpmode = helpmode;
  25875. X   if(which == JIIM)
  25876. X      helpmode = HELP_JIIM;
  25877. X   else
  25878. X   {
  25879. X      helpmode = HELP_ORBITS;
  25880. X      hasinverse = 1;
  25881. X   }
  25882. X   if(fractalspecific[fractype].isinteger)
  25883. X      o_fractype = fractalspecific[fractype].tofloat;
  25884. X   else
  25885. X      o_fractype = fractype;
  25886. X   oldsxoffs = sxoffs;
  25887. X   oldsyoffs = syoffs;
  25888. X   oldcalctype = calctype;
  25889. X   show_numbers = 0;
  25890. X   using_jiim = 1;
  25891. X   mem_init(strlocn, 10*1024);
  25892. X   line_buff = newx(max(sxdots,sydots));
  25893. X   aspect = ((double)xdots*3)/((double)ydots*4);  /* assumes 4:3 */
  25894. X     actively_computing = 1;
  25895. X   SetAspect(aspect);
  25896. X   lookatmouse = 3;
  25897. X   Cursor_Construct();
  25898. X
  25899. X/*
  25900. X * MIIM code:
  25901. X * Grab far memory for Queue/Stack before SaveRect gets it.
  25902. X */
  25903. X   OKtoMIIM  = 0;
  25904. X   if (which == JIIM && debugflag != 300)
  25905. X      OKtoMIIM = Init_Queue((long)8*1024); /* Queue Set-up Successful? */
  25906. X
  25907. X   maxhits = 1;
  25908. X   if (which == ORBIT)
  25909. X      plot = c_putcolor;             /* for line with clipping */
  25910. X
  25911. X/*
  25912. X * end MIIM code.
  25913. X */
  25914. X
  25915. X
  25916. X   if(sxoffs != 0 || syoffs != 0) /* we're in view windows */
  25917. X   {
  25918. X      savehasinverse = hasinverse;
  25919. X      hasinverse = 1;
  25920. X      SaveRect(0,0,xdots,ydots);
  25921. X      sxoffs = 0;
  25922. X      syoffs = 0;
  25923. X      RestoreRect(0,0,xdots,ydots);
  25924. X      hasinverse = savehasinverse;
  25925. X   }
  25926. X
  25927. X   if(which == ORBIT)
  25928. X      do_fractal_routines(cr, ci,PER_IMAGE);
  25929. X   else
  25930. X      color = color_bright;
  25931. X
  25932. X   oldhelpmode = helpmode;
  25933. X   if(which == JIIM)
  25934. X      helpmode = HELP_JIIM;
  25935. X   else
  25936. X      helpmode = HELP_ORBITS;
  25937. X
  25938. X   if(xdots == sxdots || ydots == sydots ||
  25939. X       sxdots-xdots < sxdots/3 ||
  25940. X       sydots-ydots < sydots/3 ||
  25941. X       xdots >= MAXRECT )
  25942. X   {
  25943. X      /* this mode puts orbit/julia in an overlapping window 1/3 the size of
  25944. X     the physical screen */
  25945. X      windows = 0; /* full screen or large view window */
  25946. X      xd = sxdots / 3;
  25947. X      yd = sydots / 3;
  25948. X      xc = xd * 2;
  25949. X      yc = yd * 2;
  25950. X      xoff = xd * 5 / 2;
  25951. X      yoff = yd * 5 / 2;
  25952. X   }
  25953. X   else if(xdots > sxdots/3 && ydots > sydots/3)
  25954. X   {
  25955. X      /* Julia/orbit and fractal don't overlap */
  25956. X      windows = 1;
  25957. X      xd = sxdots-xdots;
  25958. X      yd = sydots-ydots;
  25959. X      xc = xdots;
  25960. X      yc = ydots;
  25961. X      xoff = xc + xd/2;
  25962. X      yoff = yc + yd/2;
  25963. X
  25964. X   }
  25965. X   else
  25966. X   {
  25967. X      /* Julia/orbit takes whole screen */
  25968. X      windows = 2;
  25969. X      xd = sxdots;
  25970. X      yd = sydots;
  25971. X      xc = 0;
  25972. X      yc = 0;
  25973. X      xoff = xd/2;
  25974. X      yoff = yd/2;
  25975. X   }
  25976. X
  25977. X   xfactor = xd/5.33;
  25978. X   yfactor = -yd/4;
  25979. X
  25980. X   if(windows == 0)
  25981. X      SaveRect(xc,yc,xd,yd);
  25982. X   else if(windows == 2)  /* leave the fractal */
  25983. X   {
  25984. X      fillrect(xdots, yc, xd-xdots, yd, color_dark);
  25985. X      fillrect(xc   , ydots, xdots, yd-ydots, color_dark);
  25986. X   }
  25987. X   else  /* blank whole window */
  25988. X      fillrect(xc, yc, xd, yd, color_dark);
  25989. X
  25990. X   setup_convert_to_screen(&cvt);
  25991. X
  25992. X   /* reuse last location if inside window */
  25993. X   xcrsr = cvt.a*SaveC.x + cvt.b*SaveC.y + cvt.e + .5;
  25994. X   ycrsr = cvt.c*SaveC.x + cvt.d*SaveC.y + cvt.f + .5;
  25995. X   if(xcrsr < 0 || xcrsr >= xdots ||
  25996. X      ycrsr < 0 || ycrsr >= ydots)
  25997. X   {
  25998. X      cr = (xxmax + xxmin) / 2.0;
  25999. X      ci = (yymax + yymin) / 2.0;
  26000. X   }
  26001. X   else
  26002. X   {
  26003. X      cr = SaveC.x;
  26004. X      ci = SaveC.y;
  26005. X   }
  26006. X
  26007. X   old_x = old_y = -1;
  26008. X
  26009. X   xcrsr = cvt.a*cr + cvt.b*ci + cvt.e + .5;
  26010. X   ycrsr = cvt.c*cr + cvt.d*ci + cvt.f + .5;
  26011. X
  26012. X   Cursor_SetPos(xcrsr, ycrsr);
  26013. X   Cursor_Show();
  26014. X   color = color_bright;
  26015. X
  26016. X   iter = 1;
  26017. X   still = 1;
  26018. X   zoom = 1;
  26019. X
  26020. X#ifdef XFRACT
  26021. X   Cursor_StartMouseTracking();
  26022. X#endif
  26023. X
  26024. X   while (still)
  26025. X   {
  26026. X      int dxcrsr, dycrsr;
  26027. X      if (actively_computing) {
  26028. X      Cursor_CheckBlink();
  26029. X      } else {
  26030. X      Cursor_WaitKey();
  26031. X      }
  26032. X      if(keypressed() || first_time) /* prevent burning up UNIX CPU */
  26033. X      {
  26034. X     first_time = 0;
  26035. X     while(keypressed())
  26036. X     {
  26037. X        Cursor_WaitKey();
  26038. X        kbdchar = getakey();
  26039. X
  26040. X        dxcrsr = dycrsr = 0;
  26041. X        xcjul = BIG;
  26042. X        ycjul = BIG;
  26043. X        switch (kbdchar)
  26044. X        {
  26045. X            case 1143:    /* ctrl - keypad 5 */
  26046. X        case 1076:    /* keypad 5        */
  26047. X           break;     /* do nothing */
  26048. X        case CTL_PAGE_UP:
  26049. X           dxcrsr = 4;
  26050. X           dycrsr = -4;
  26051. X           break;
  26052. X        case CTL_PAGE_DOWN:
  26053. X           dxcrsr = 4;
  26054. X           dycrsr = 4;
  26055. X           break;
  26056. X        case CTL_HOME:
  26057. X           dxcrsr = -4;
  26058. X           dycrsr = -4;
  26059. X           break;
  26060. X        case CTL_END:
  26061. X           dxcrsr = -4;
  26062. X           dycrsr = 4;
  26063. X           break;
  26064. X        case PAGE_UP:
  26065. X           dxcrsr = 1;
  26066. X           dycrsr = -1;
  26067. X           break;
  26068. X        case PAGE_DOWN:
  26069. X           dxcrsr = 1;
  26070. X           dycrsr = 1;
  26071. X           break;
  26072. X        case HOME:
  26073. X           dxcrsr = -1;
  26074. X           dycrsr = -1;
  26075. X           break;
  26076. X        case END:
  26077. X           dxcrsr = -1;
  26078. X           dycrsr = 1;
  26079. X           break;
  26080. X        case UP_ARROW:
  26081. X           dycrsr = -1;
  26082. X           break;
  26083. X        case DOWN_ARROW:
  26084. X           dycrsr = 1;
  26085. X           break;
  26086. X        case LEFT_ARROW:
  26087. X           dxcrsr = -1;
  26088. X           break;
  26089. X        case RIGHT_ARROW:
  26090. X           dxcrsr = 1;
  26091. X           break;
  26092. X        case UP_ARROW_2:
  26093. X           dycrsr = -4;
  26094. X           break;
  26095. X        case DOWN_ARROW_2:
  26096. X           dycrsr = 4;
  26097. X           break;
  26098. X        case LEFT_ARROW_2:
  26099. X           dxcrsr = -4;
  26100. X           break;
  26101. X        case RIGHT_ARROW_2:
  26102. X           dxcrsr = 4;
  26103. X           break;
  26104. X        case 'z':
  26105. X        case 'Z':
  26106. X           zoom = 1.0;
  26107. X           break;
  26108. X        case '<':
  26109. X        case ',':
  26110. X           zoom /= 1.15;
  26111. X           break;
  26112. X        case '>':
  26113. X        case '.':
  26114. X           zoom *= 1.15;
  26115. X           break;
  26116. X        case SPACE:
  26117. X           xcjul = cr;
  26118. X           ycjul = ci;
  26119. X           goto finish;
  26120. X           break;
  26121. X        case 'c':   /* circle toggle */
  26122. X        case 'C':   /* circle toggle */
  26123. X           mode = mode ^ 1;
  26124. X           break;
  26125. X        case 'l':
  26126. X        case 'L':
  26127. X           mode = mode ^ 2;
  26128. X           break;
  26129. X        case 'n':
  26130. X        case 'N':
  26131. X           show_numbers = 8 - show_numbers;
  26132. X           if(windows == 0 && show_numbers == 0)
  26133. X           {
  26134. X          Cursor_Hide();
  26135. X          cleartempmsg();
  26136. X          Cursor_Show();
  26137. X           }
  26138. X           break;
  26139. X        case 'p':
  26140. X        case 'P':
  26141. X           get_a_number(&cr,&ci);
  26142. X               exact = 1;
  26143. X               xcrsr = cvt.a*cr + cvt.b*ci + cvt.e + .5;
  26144. X               ycrsr = cvt.c*cr + cvt.d*ci + cvt.f + .5;
  26145. X               dxcrsr = dycrsr = 0;
  26146. X           break;
  26147. X        case 'h':   /* hide fractal toggle */
  26148. X        case 'H':   /* hide fractal toggle */
  26149. X           if(windows == 2)
  26150. X          windows = 3;
  26151. X           else if(windows == 3 && xd == sxdots)
  26152. X           {
  26153. X          RestoreRect(0, 0, xdots, ydots);
  26154. X          windows = 2;
  26155. X           }
  26156. X           break;
  26157. X#ifdef XFRACT
  26158. X        case ENTER:
  26159. X        break;
  26160. X#endif
  26161. X        case '0':
  26162. X        case '1':
  26163. X        case '2':
  26164. X/*        case '3': */  /* don't use '3', it's already meaningful */
  26165. X        case '4':
  26166. X        case '5':
  26167. X        case '6':
  26168. X        case '7':
  26169. X        case '8':
  26170. X        case '9':
  26171. X           if (which == JIIM)
  26172. X           {
  26173. X          SecretExperimentalMode = kbdchar - '0';
  26174. X          break;
  26175. X           }
  26176. X        default:
  26177. X           still = 0;
  26178. X        }  /* switch */
  26179. X        if(kbdchar == 's' || kbdchar == 'S')
  26180. X           goto finish;
  26181. X            if(dxcrsr > 0 || dycrsr > 0)
  26182. X               exact = 0;
  26183. X            xcrsr += dxcrsr;
  26184. X            ycrsr += dycrsr;
  26185. X#ifdef XFRACT
  26186. X        if (kbdchar == ENTER) {
  26187. X        /* We want to use the position of the cursor */
  26188. X        exact=0;
  26189. X        xcrsr = Cursor_GetX();
  26190. X        ycrsr = Cursor_GetY();
  26191. X        }
  26192. X#endif
  26193. X            
  26194. X        /* keep cursor in logical screen */
  26195. X       if(xcrsr >= xdots)
  26196. X          xcrsr = xdots -1, exact = 0;
  26197. X       if(ycrsr >= ydots)
  26198. X          ycrsr = ydots -1, exact = 0;
  26199. X       if(xcrsr < 0)
  26200. X          xcrsr = 0, exact = 0;
  26201. X       if(ycrsr < 0)
  26202. X          ycrsr = 0, exact = 0;
  26203. X        
  26204. X            Cursor_SetPos(xcrsr,ycrsr);
  26205. X     }  /* end while (keypressed) */
  26206. X
  26207. X         if(exact == 0)
  26208. X         {
  26209. X        if(integerfractal)
  26210. X        {
  26211. X           cr = lx0[xcrsr]+lx1[ycrsr];  /* supports rotated zoom boxes! */
  26212. X           ci = ly0[ycrsr]+ly1[xcrsr];
  26213. X           cr /= (1L<<bitshift);
  26214. X           ci /= (1L<<bitshift);
  26215. X        }
  26216. X        else
  26217. X        {
  26218. X           cr = dx0[xcrsr]+dx1[ycrsr];
  26219. X           ci = dy0[ycrsr]+dy1[xcrsr];
  26220. X        }
  26221. X     }
  26222. X     actively_computing = 1;
  26223. X     if(show_numbers) /* write coordinates on screen */
  26224. X     {
  26225. X        char str[80];
  26226. X        sprintf(str,"x=%16.14f y=%16.14f   ",cr,ci);
  26227. X        str[40] = 0;
  26228. X        if(windows == 0)
  26229. X        {
  26230. X           Cursor_Hide();
  26231. X           actively_computing = 1;
  26232. X           showtempmsg(str);
  26233. X           Cursor_Show();
  26234. X        }
  26235. X        else
  26236. X           displays(5, sydots-show_numbers, WHITE, BLACK, str,strlen(str));
  26237. X     }
  26238. X     iter = 1;
  26239. X     old.x = old.y = 0;
  26240. X     SaveC.x = init.x =  cr;
  26241. X     SaveC.y = init.y =  ci;
  26242. X     old_x = old_y = -1;
  26243. X/*
  26244. X * MIIM code:
  26245. X * compute fixed points and use them as starting points of JIIM
  26246. X */
  26247. X     if (which == JIIM && OKtoMIIM)
  26248. X     {
  26249. X        _CMPLX f1, f2, Sqrt;    /* Fixed points of Julia */
  26250. X
  26251. X        Sqrt = ComplexSqrtFloat(1 - 4 * cr, -4 * ci);
  26252. X        f1.x = (1 + Sqrt.x) / 2;
  26253. X        f2.x = (1 - Sqrt.x) / 2;
  26254. X        f1.y =  Sqrt.y / 2;
  26255. X        f2.y = -Sqrt.y / 2;
  26256. X
  26257. X        ClearQueue();
  26258. X        maxhits = 1;
  26259. X        EnQueueFloat(f1.x, f1.y);
  26260. X        EnQueueFloat(f2.x, f2.y);
  26261. X     }
  26262. X/*
  26263. X * End MIIM code.
  26264. X */
  26265. X     if(which == ORBIT)
  26266. X           do_fractal_routines(cr, ci,PER_PIXEL);
  26267. X     /* move window if bumped */
  26268. X     if(windows==0 && xcrsr>xc && xcrsr < xc+xd && ycrsr>yc && ycrsr < yc+yd)
  26269. X     {
  26270. X        RestoreRect(xc,yc,xd,yd);
  26271. X        if (xc == xd*2)
  26272. X           xc = 2;
  26273. X        else
  26274. X           xc = xd*2;
  26275. X        xoff = xc + xd /  2;
  26276. X        SaveRect(xc,yc,xd,yd);
  26277. X     }
  26278. X     if(windows == 2)
  26279. X     {
  26280. X        fillrect(xdots, yc, xd-xdots, yd-show_numbers, color_dark);
  26281. X        fillrect(xc   , ydots, xdots, yd-ydots-show_numbers, color_dark);
  26282. X     }
  26283. X     else
  26284. X        fillrect(xc, yc, xd, yd, color_dark);
  26285. X
  26286. X      } /* end if (keypressed) */
  26287. X
  26288. X      if(which == JIIM)
  26289. X      {
  26290. X         if(hasinverse == 0)
  26291. X            continue;
  26292. X/*
  26293. X * MIIM code:
  26294. X * If we have MIIM queue allocated, then use MIIM method.
  26295. X */
  26296. X     if (OKtoMIIM)
  26297. X     {
  26298. X        if (QueueEmpty())
  26299. X        {
  26300. X           if (maxhits < colors - 1 && maxhits < 5 &&
  26301. X          (luckyx != 0.0 || luckyy != 0.0))
  26302. X           {
  26303. X          int i;
  26304. X
  26305. X          lsize  = lmax   = 0;
  26306. X          old.x  = new.x  = luckyx;
  26307. X          old.y  = new.y  = luckyy;
  26308. X          luckyx = luckyy = 0.0;
  26309. X          for (i=0; i<199; i++)
  26310. X          {
  26311. X             old = ComplexSqrtFloat(old.x - cr, old.y - ci);
  26312. X             new = ComplexSqrtFloat(new.x - cr, new.y - ci);
  26313. X             EnQueueFloat( new.x,  new.y);
  26314. X             EnQueueFloat(-old.x, -old.y);
  26315. X          }
  26316. X          maxhits++;
  26317. X           }
  26318. X           else
  26319. X          continue;        /* loop while (still) */
  26320. X        }
  26321. X
  26322. X        old = DeQueueFloat();
  26323. X
  26324. X#if 0 /* try a different new method */
  26325. X        if (lsize < (lmax / 8) && maxhits < 5)    /* NEW METHOD */
  26326. X           if (maxhits < colors - 1)
  26327. X           maxhits++;
  26328. X#endif
  26329. X        x = old.x * xfactor * zoom + xoff;
  26330. X        y = old.y * yfactor * zoom + yoff;
  26331. X        color = c_getcolor(x, y);
  26332. X        if (color < maxhits)
  26333. X        {
  26334. X           c_putcolor(x, y, color + 1);
  26335. X           new = ComplexSqrtFloat(old.x - cr, old.y - ci);
  26336. X           EnQueueFloat( new.x,  new.y);
  26337. X           EnQueueFloat(-new.x, -new.y);
  26338. X        }
  26339. X     }
  26340. X     else
  26341. X     {
  26342. X/*
  26343. X * end Msnyder code, commence if not MIIM code.
  26344. X */
  26345. X     old.x -= cr;
  26346. X     old.y -= ci;
  26347. X     r = old.x*old.x + old.y*old.y;
  26348. X     if(r > 10.0)
  26349. X     {
  26350. X         old.x = old.y = 0.0; /* avoids math error */
  26351. X         iter = 1;
  26352. X     }
  26353. X     iter++;
  26354. X     color = ((count++)>>5)&(colors-1); /* chg color every 32 pts */
  26355. X     if(color==0)
  26356. X      color = 1;
  26357. X
  26358. X     r = sqrt(old.x*old.x + old.y*old.y);
  26359. X     new.x = sqrt(fabs((r + old.x)/2));
  26360. X     if (old.y < 0)
  26361. X        new.x = -new.x;
  26362. X
  26363. X     new.y = sqrt(fabs((r - old.x)/2));
  26364. X
  26365. X
  26366. X     switch (SecretExperimentalMode) {
  26367. X        case 0:            /* unmodified random walk */
  26368. X        default:
  26369. X        if (rand() % 2)
  26370. X        {
  26371. X           new.x = -new.x;
  26372. X           new.y = -new.y;
  26373. X        }
  26374. X        x = new.x * xfactor * zoom + xoff;
  26375. X        y = new.y * yfactor * zoom + yoff;
  26376. X        break;
  26377. X        case 1:              /* always go one direction */
  26378. X        if (SaveC.y < 0)
  26379. X        {
  26380. X           new.x = -new.x;
  26381. X           new.y = -new.y;
  26382. X        }
  26383. X        x = new.x * xfactor * zoom + xoff;
  26384. X        y = new.y * yfactor * zoom + yoff;
  26385. X        break;
  26386. X        case 2:            /* go one dir, draw the other */
  26387. X        if (SaveC.y < 0)
  26388. X        {
  26389. X           new.x = -new.x;
  26390. X           new.y = -new.y;
  26391. X        }
  26392. X        x = -new.x * xfactor * zoom + xoff;
  26393. X        y = -new.y * yfactor * zoom + yoff;
  26394. X        break;
  26395. X        case 4:            /* go negative if max color */
  26396. X        x = new.x * xfactor * zoom + xoff;
  26397. X        y = new.y * yfactor * zoom + yoff;
  26398. X        if (c_getcolor(x, y) == colors - 1)
  26399. X        {
  26400. X           new.x = -new.x;
  26401. X           new.y = -new.y;
  26402. X           x = new.x * xfactor * zoom + xoff;
  26403. X           y = new.y * yfactor * zoom + yoff;
  26404. X        }
  26405. X        break;
  26406. X        case 5:            /* go positive if max color */
  26407. X        new.x = -new.x;
  26408. X        new.y = -new.y;
  26409. X        x = new.x * xfactor * zoom + xoff;
  26410. X        y = new.y * yfactor * zoom + yoff;
  26411. X        if (c_getcolor(x, y) == colors - 1)
  26412. X        {
  26413. X           x = new.x * xfactor * zoom + xoff;
  26414. X           y = new.y * yfactor * zoom + yoff;
  26415. X        }
  26416. X        break;
  26417. X        case 7:
  26418. X        if (SaveC.y < 0)
  26419. X        {
  26420. X           new.x = -new.x;
  26421. X           new.y = -new.y;
  26422. X        }
  26423. X        x = -new.x * xfactor * zoom + xoff;
  26424. X        y = -new.y * yfactor * zoom + yoff;
  26425. X        if(iter > 10)
  26426. X        {
  26427. X           if(mode == 0)            /* pixels  */
  26428. X              c_putcolor(x, y, color);
  26429. X           else if (mode & 1)            /* circles */
  26430. X           {
  26431. X              xbase = x;
  26432. X              ybase = y;
  26433. X              circle((int)(zoom*(xd >> 1)/iter),color);
  26434. X           }
  26435. X           if ((mode & 2) && x > 0 && y > 0 && old_x > 0 && old_y > 0)
  26436. X           {
  26437. X              draw_line(x, y, old_x, old_y, color);
  26438. X           }
  26439. X           old_x = x;
  26440. X           old_y = y;
  26441. X        }
  26442. X        x = new.x * xfactor * zoom + xoff;
  26443. X        y = new.y * yfactor * zoom + yoff;
  26444. X        break;
  26445. X        case 8:            /* go in long zig zags */
  26446. X        if (rancnt >= 300)
  26447. X            rancnt = -300;
  26448. X        if (rancnt < 0)
  26449. X        {
  26450. X            new.x = -new.x;
  26451. X            new.y = -new.y;
  26452. X        }
  26453. X        x = new.x * xfactor * zoom + xoff;
  26454. X        y = new.y * yfactor * zoom + yoff;
  26455. X        break;
  26456. X        case 9:            /* "random run" */
  26457. X        switch (randir) {
  26458. X            case 0:             /* go random direction for a while */
  26459. X            if (rand() % 2)
  26460. X            {
  26461. X                new.x = -new.x;
  26462. X                new.y = -new.y;
  26463. X            }
  26464. X            if (++rancnt > 1024)
  26465. X            {
  26466. X                rancnt = 0;
  26467. X                if (rand() % 2)
  26468. X                randir =  1;
  26469. X                else
  26470. X                randir = -1;
  26471. X            }
  26472. X            break;
  26473. X            case 1:             /* now go negative dir for a while */
  26474. X            new.x = -new.x;
  26475. X            new.y = -new.y;
  26476. X            /* fall through */
  26477. X            case -1:            /* now go positive dir for a while */
  26478. X            if (++rancnt > 512)
  26479. X                randir = rancnt = 0;
  26480. X            break;
  26481. X        }
  26482. X        x = new.x * xfactor * zoom + xoff;
  26483. X        y = new.y * yfactor * zoom + yoff;
  26484. X        break;
  26485. X     } /* end switch SecretMode (sorry about the indentation) */
  26486. X     } /* end if not MIIM */
  26487. X      }
  26488. X      else /* orbits */
  26489. X      {
  26490. X     if(iter < maxit)
  26491. X     {
  26492. X        color = iter&(colors-1);
  26493. X        x = (old.x - init.x) * xfactor * 3 * zoom + xoff;
  26494. X        y = (old.y - init.y) * yfactor * 3 * zoom + yoff;
  26495. X        if(do_fractal_routines(cr, ci,ORBITCALC))
  26496. X           iter = maxit;
  26497. X        else
  26498. X           iter++;
  26499. X     }
  26500. X     else
  26501. X     {
  26502. X        x = y = -1;
  26503. X        actively_computing = 0;
  26504. X     }
  26505. X      }
  26506. X      if(which == ORBIT || iter > 10)
  26507. X      {
  26508. X     if(mode == 0)            /* pixels  */
  26509. X        c_putcolor(x, y, color);
  26510. X     else if (mode & 1)            /* circles */
  26511. X     {
  26512. X        xbase = x;
  26513. X        ybase = y;
  26514. X        circle((int)(zoom*(xd >> 1)/iter),color);
  26515. X     }
  26516. X     if ((mode & 2) && x > 0 && y > 0 && old_x > 0 && old_y > 0)
  26517. X     {
  26518. X        draw_line(x, y, old_x, old_y, color);
  26519. X     }
  26520. X     old_x = x;
  26521. X     old_y = y;
  26522. X      }
  26523. X      old = new;
  26524. X   } /* end while(still) */
  26525. Xfinish:
  26526. X
  26527. X/*
  26528. X * Msnyder code:
  26529. X * free MIIM queue
  26530. X */
  26531. X
  26532. X   Free_Queue();
  26533. X/*
  26534. X * end Msnyder code.
  26535. X */
  26536. X
  26537. X   if(kbdchar != 's'&& kbdchar != 'S')
  26538. X   {
  26539. X      Cursor_Hide();
  26540. X      if(windows == 0)
  26541. X     RestoreRect(xc,yc,xd,yd);
  26542. X      else if(windows >= 2 )
  26543. X      {
  26544. X     if(windows == 2)
  26545. X     {
  26546. X        fillrect(xdots, yc, xd-xdots, yd, color_dark);
  26547. X        fillrect(xc   , ydots, xdots, yd-ydots, color_dark);
  26548. X     }
  26549. X     else
  26550. X        fillrect(xc, yc, xd, yd, color_dark);
  26551. X         if(windows == 3 && xd == sxdots) /* unhide */
  26552. X         {
  26553. X            RestoreRect(0, 0, xdots, ydots);
  26554. X            windows = 2;
  26555. X         }
  26556. X     Cursor_Hide();
  26557. X     savehasinverse = hasinverse;
  26558. X     hasinverse = 1;
  26559. X     SaveRect(0,0,xdots,ydots);
  26560. X     sxoffs = oldsxoffs;
  26561. X     syoffs = oldsyoffs;
  26562. X     RestoreRect(0,0,xdots,ydots);
  26563. X     hasinverse = savehasinverse;
  26564. X      }
  26565. X   }
  26566. X   Cursor_Destroy();
  26567. X#ifdef XFRACT
  26568. X   Cursor_EndMouseTracking();
  26569. X#endif
  26570. X   delete(line_buff);
  26571. X   if (memory)            /* done with memory, free it */
  26572. X   {
  26573. X      farmemfree(memory);
  26574. X      memory = NULL;
  26575. X   }
  26576. X
  26577. X   lookatmouse = oldlookatmouse;
  26578. X   using_jiim = 0;
  26579. X   calctype = oldcalctype;
  26580. X
  26581. X   helpmode = oldhelpmode;
  26582. X   if(kbdchar == 's' || kbdchar == 'S')
  26583. X   {
  26584. X      viewwindow = viewxdots = viewydots = 0;
  26585. X      viewreduction = 4.2;
  26586. X      viewcrop = 1;
  26587. X      finalaspectratio = screenaspect;
  26588. X      xdots = sxdots;
  26589. X      ydots = sydots;
  26590. X      dxsize = xdots - 1;
  26591. X      dysize = ydots - 1;
  26592. X      sxoffs = 0;
  26593. X      syoffs = 0;
  26594. X      freetempmsg();
  26595. X   }
  26596. X   else
  26597. X      cleartempmsg();
  26598. X   if (file != NULL)
  26599. X      {
  26600. X      fclose(file);
  26601. X      file = NULL;
  26602. X      remove(scrnfile);
  26603. X      }
  26604. X   show_numbers = 0;
  26605. X   ungetakey(kbdchar);
  26606. X   EXIT_OVLY;
  26607. X}
  26608. X  
  26609. SHAR_EOF
  26610. $TOUCH -am 1028230093 jiim.c &&
  26611. chmod 0644 jiim.c ||
  26612. echo "restore of jiim.c failed"
  26613. set `wc -c jiim.c`;Wc_c=$1
  26614. if test "$Wc_c" != "35541"; then
  26615.     echo original size 35541, current size $Wc_c
  26616. fi
  26617. # ============= line3d.c ==============
  26618. echo "x - extracting line3d.c (Text)"
  26619. sed 's/^X//' << 'SHAR_EOF' > line3d.c &&
  26620. X/******************************************************************************/
  26621. X/* This file contains a 3D replacement for the out_line function called            */
  26622. X/* by the decoder. The purpose is to apply various 3D transformations            */
  26623. X/* before displaying points. Called once per line of the input file.                */
  26624. X/*                                                                                                        */
  26625. X/* This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.            */
  26626. X/*                                                                                                        */
  26627. X/* Original Author Tim Wegner, with extensive help from Marc Reinig.                */
  26628. X/*****************************************************************************/
  26629. X
  26630. X#include <stdio.h>
  26631. X#include <stdlib.h>
  26632. X#include <limits.h>
  26633. X#ifndef XFRACT
  26634. X#include <dos.h>
  26635. X#endif
  26636. X#include "fractint.h"
  26637. X#include "prototyp.h"
  26638. X
  26639. Xstruct point
  26640. X{
  26641. X    int x;
  26642. X    int y;
  26643. X    int color;
  26644. X};
  26645. X
  26646. X/* routines in this module    */
  26647. X
  26648. Xstatic void _fastcall vdraw_line(double *,double *,int);
  26649. Xstatic void (_fastcall *fillplot)(int,int,int);
  26650. Xstatic void (_fastcall *normalplot)(int,int,int);
  26651. Xstatic void _fastcall putminmax(int x,int y,int color);
  26652. Xstatic void _fastcall clipcolor(int x,int y,int color);
  26653. Xstatic void _fastcall T_clipcolor(int x,int y,int color);
  26654. Xstatic void _fastcall interpcolor(int x,int y,int color);
  26655. Xstatic void corners(),draw_light_box();
  26656. Xstatic void _fastcall putatriangle(struct point pt1,struct point pt2,
  26657. X                    struct point pt3,int color);
  26658. Xstatic int _fastcall offscreen(struct point pt);
  26659. Xstatic int  H_R(),R_H();
  26660. Xstatic int  startdisk1(char *File_Name2, FILE *Source, int overlay);
  26661. Xstatic int  set_pixel_buff();
  26662. Xstatic void line3d_cleanup();
  26663. Xextern int glassestype, whichimage;
  26664. Xvoid (_fastcall *standardplot)(int,int,int);
  26665. X
  26666. Xstatic    int line_length1;
  26667. Xstatic    int T_header_24 = 18; /* Size of current Targa-24 header */
  26668. Xextern    BYTE dacbox[256][3];
  26669. XMATRIX m;                /* transformation matrix */
  26670. Xvoid (*mult_vec)(VECTOR) = mult_vec_c;
  26671. Xextern int iit;                 /* iit flag */
  26672. Xstatic    FILE *File_Ptr1 = NULL;
  26673. Xint Ambient;
  26674. Xstatic unsigned int IAmbient;
  26675. Xint RANDOMIZE;
  26676. Xstatic int rand_factor;
  26677. Xint haze;
  26678. Xstatic int HAZE_MULT;
  26679. Xint Real_V = 0; /* mrr Actual value of V for fillytpe>4 monochrome images */
  26680. X
  26681. Xchar light_name[80] = "fract001";
  26682. Xint Targa_Overlay, error;
  26683. Xextern int Targa_Out;
  26684. Xchar targa_temp[14] = "fractemp.tga";
  26685. Xstatic void File_Error (char *File_Name1, int ERROR);
  26686. Xstatic BYTE T24=24;
  26687. Xstatic BYTE T32=32;
  26688. Xstatic BYTE upr_lwr[4];
  26689. Xstatic int T_Safe; /* Original Targa Image successfully copied to targa_temp */
  26690. Xint P = 250; /* Perspective dist used when viewing light vector */
  26691. Xstatic void draw_rect (VECTOR V0, VECTOR V1, VECTOR V2, VECTOR V3, int color,
  26692. X                            int rect);
  26693. Xstatic VECTOR light_direction;
  26694. X
  26695. XBYTE back_color[3];
  26696. Xstatic BYTE Real_Color; /* Actual color of cur pixel */
  26697. Xextern int dotmode; /* video access method, 11 if really disk video */
  26698. Xextern int calc_status;
  26699. Xextern long calctime;
  26700. Xextern int got_status,currow;
  26701. X
  26702. X
  26703. Xstatic int RO, CO, CO_MAX; /*  For use in Acrospin support */
  26704. Xstatic char far acro_s1[] =
  26705. X    {"Set Layer 1\nSet Color 2\nEndpointList X Y Z Name\n"};
  26706. Xstatic char far acro_s2[] = {"LineList From To\n"};
  26707. Xstatic char far s3[] = {"{ Created by FRACTINT Ver. "};
  26708. Xstatic char far s3a[] = {" }\n\n"};
  26709. X#ifndef XFRACT
  26710. Xstatic char banner[] ="%Fs%#4.2f%Fs";
  26711. X#else
  26712. Xstatic char banner[] ="%s%#4.2f%s";
  26713. X#endif
  26714. Xchar ray_name[80] = "fract001";
  26715. X
  26716. Xchar preview = 0;
  26717. Xchar showbox = 0;
  26718. Xstatic int localpreviewfactor;
  26719. Xint previewfactor = 20;
  26720. Xint xadjust = 0;
  26721. Xint yadjust = 0;
  26722. Xint xxadjust;
  26723. Xint yyadjust;
  26724. Xint xshift;
  26725. Xint yshift;
  26726. Xextern int overflow;
  26727. Xextern int filetype;
  26728. Xextern char usr_floatflag;
  26729. Xextern int xdots, ydots, colors, sxoffs, syoffs;
  26730. Xextern int debugflag;
  26731. Xextern SEGTYPE extraseg;
  26732. Xextern unsigned height;
  26733. Xextern int rowcount;        /* in general.asm */
  26734. Xextern int init3d[];        /* 3D arguments (FRACTINT.C) */
  26735. Xextern long far *lx0;
  26736. Xextern int transparent[2];    /* transparency min/max */
  26737. Xextern int pot16bit;
  26738. Xextern int filecolors;
  26739. Xextern void (*outln_cleanup)();
  26740. X
  26741. Xstatic int zcoord = 256;
  26742. Xstatic double aspect;            /* aspect ratio */
  26743. Xstatic int evenoddrow;
  26744. X
  26745. Xstatic float far *sinthetaarray;    /* all sine        thetas go here  */
  26746. Xstatic float far *costhetaarray;    /* all cosine thetas go here */
  26747. X
  26748. Xstatic double rXrscale;         /* precalculation factor */
  26749. X
  26750. Xstatic int persp;    /* flag for indicating perspective transformations */
  26751. Xint bad_value = -10000; /* set bad values to this */
  26752. Xint bad_check = -3000;    /* check values against this to determine if good */
  26753. X
  26754. X/* this array remembers the previous line */
  26755. Xstruct point far *lastrow;
  26756. X
  26757. Xstatic struct point p1,p2,p3;
  26758. X
  26759. Xstruct f_point
  26760. X{
  26761. X    float x;
  26762. X    float y;
  26763. X    float color;
  26764. X}
  26765. Xfar *f_lastrow;
  26766. X
  26767. X
  26768. Xint RAY = 0; /* Flag to generate Ray trace compatible files in 3d */
  26769. Xint BRIEF = 0; /* 1 = short ray trace files */
  26770. Xextern int release; /* Current release level of Fractint */
  26771. Xstatic int _fastcall RAY_Header(void);
  26772. Xstatic void _fastcall triangle_bounds(float pt_t[3][3]);
  26773. Xstatic int _fastcall out_triangle(struct f_point pt1, struct f_point pt2,
  26774. X            struct f_point pt3, int c1, int c2, int c3);
  26775. Xstatic float min_xyz[3], max_xyz[3]; /* For Raytrace output */
  26776. Xstatic int _fastcall start_object(void);
  26777. Xstatic int _fastcall end_object(int triout);
  26778. Xextern unsigned numcolors; /* number of colors in original GIF */
  26779. Xstatic long num_tris; /* number of triangles output to ray trace file */
  26780. X
  26781. X/* array of min and max x values used in triangle fill */
  26782. Xstruct minmax
  26783. X{
  26784. X    int minx;
  26785. X    int maxx;
  26786. X}
  26787. Xfar *minmax_x;
  26788. X
  26789. XVECTOR view;    /* position of observer for perspective */
  26790. XVECTOR cross;
  26791. XVECTOR tmpcross;
  26792. X
  26793. Xstruct point oldlast =
  26794. X{
  26795. X    0, 0, 0
  26796. X};    /* old pixels */
  26797. X
  26798. Xvoid line3d_overlay() {
  26799. X}    /* for restore_active_ovly */
  26800. X
  26801. Xint line3d(BYTE *pixels, unsigned linelen)
  26802. X{
  26803. X    int tout; /*  triangle has been sent to ray trace file */
  26804. X    int RND;
  26805. X    float f_water; /* transformed WATERLINE for ray trace files */
  26806. X
  26807. X    /* these values come from FRACTINT.C */
  26808. X
  26809. X    /* These variables must preserve their values across calls */
  26810. X    static float    deltaphi;  /* increment of latitude, longitude */
  26811. X    static double rscale;            /* surface roughness factor */
  26812. X    static long xcenter,ycenter;            /* circle center */
  26813. X    double r0;
  26814. X    int xcenter0,ycenter0; /* Unfudged versions */
  26815. X
  26816. X    static double sclx,scly,sclz;        /* scale factors */
  26817. X    static double R;                /* radius values */
  26818. X    static double Rfactor;            /* for intermediate calculation */
  26819. X    MATRIX lightm;                /* m w/no trans, keeps obj. on screen */
  26820. X    static LMATRIX lm;                /* "" */
  26821. X    static LVECTOR lview;            /* for perspective views */
  26822. X    static double zcutoff;            /* perspective backside cutoff value */
  26823. X    static float twocosdeltaphi;
  26824. X    static float cosphi,sinphi;            /* precalculated sin/cos of longitude */
  26825. X    static float oldcosphi1,oldsinphi1;
  26826. X    static float oldcosphi2,oldsinphi2;
  26827. X    double r;                    /* sphere radius */
  26828. X    double xval,yval,zval;            /* rotation values */
  26829. X    float costheta,sintheta;            /* precalculated sin/cos of latitude */
  26830. X    float twocosdeltatheta;
  26831. X
  26832. X    int next; /* used by preview and grid */
  26833. X    int col;                    /* current column (original GIF) */
  26834. X    struct point cur;                /* current pixels */
  26835. X    struct point old;                /* old pixels */
  26836. X
  26837. X    static struct point bad;            /* out of range value */
  26838. X
  26839. X    struct f_point f_cur;
  26840. X    struct f_point f_old;
  26841. X    static struct f_point f_bad;            /* out of range value */
  26842. X
  26843. X    static BYTE far *fraction;/* float version of pixels array */
  26844. X
  26845. X    VECTOR v;                    /* double vector */
  26846. X    VECTOR v1,v2;
  26847. X    VECTOR crossavg;
  26848. X    char crossnotinit;                /* flag for crossavg init indication */
  26849. X
  26850. X    double v_length;
  26851. X    VECTOR origin, direct, tmp;
  26852. X    LVECTOR lv;                    /* long equivalent of v */
  26853. X    LVECTOR lv0;                 /* long equivalent of v */
  26854. X
  26855. X    /* corners of transformed xdotx by ydots x colors box */
  26856. X    double xmin, ymin, zmin, xmax, ymax, zmax;
  26857. X    int i,j;
  26858. X    int lastdot;
  26859. X
  26860. X    long fudge;
  26861. X
  26862. X    ENTER_OVLY(OVLY_LINE3D);
  26863. X
  26864. X    fudge = 1L<<16;
  26865. X
  26866. X
  26867. X    if(transparent[0] || transparent[1])
  26868. X        plot = normalplot = T_clipcolor;    /*  Use transparent plot function */
  26869. X    else            /* Use the usual FRACTINT plot function with clipping */
  26870. X        plot = normalplot = clipcolor;
  26871. X
  26872. X    currow = rowcount; /* use separate variable to allow for pot16bit files */
  26873. X    if (pot16bit)
  26874. X        currow >>= 1;
  26875. X
  26876. X    /************************************************************************/
  26877. X    /* This IF clause is executed ONCE per image. All precalculations are    */
  26878. X    /* done here, with out any special concern about speed. DANGER -            */
  26879. X    /* communication with the rest of the program is generally via static    */
  26880. X    /* or global variables.                                                                    */
  26881. X    /************************************************************************/
  26882. X    if(rowcount++ == 0)
  26883. X    {
  26884. X        long check_extra;
  26885. X        float theta,theta1,theta2;    /* current,start,stop latitude */
  26886. X        float phi1,phi2;            /* current start,stop longitude */
  26887. X        float    deltatheta;        /* increment of latitude */
  26888. X        outln_cleanup = line3d_cleanup;
  26889. X
  26890. X        calctime = evenoddrow = 0;
  26891. X        /* mark as in-progress, and enable <tab> timer display */
  26892. X        calc_status = 1;
  26893. X
  26894. X        IAmbient = (unsigned int) (255 * (float)(100 - Ambient) / 100.0);
  26895. X        if (IAmbient < 1)        IAmbient = 1;
  26896. X
  26897. X        tout = 0;
  26898. X        num_tris = 0;
  26899. X
  26900. X        /* Open file for RAY trace output and write header */
  26901. X        if (RAY)
  26902. X        {
  26903. X            RAY_Header();
  26904. X            xxadjust = yyadjust = 0; /* Disable shifting in ray tracing */
  26905. X            xshift = yshift = 0;
  26906. X        }
  26907. X
  26908. X        CO_MAX=CO=RO=0;
  26909. X
  26910. X        upr_lwr[0] = xdots & 0xff;
  26911. X        upr_lwr[1] = xdots >> 8;
  26912. X        upr_lwr[2] = ydots &  0xff;
  26913. X        upr_lwr[3] = ydots >> 8;
  26914. X        line_length1 = 3 * xdots;        /*  line length @ 3 bytes per pixel  */
  26915. X        error = 0;
  26916. X
  26917. X        if (whichimage < 2)
  26918. X            T_Safe = 0; /* Not safe yet to mess with the source image */
  26919. X
  26920. X        if (Targa_Out && !((glassestype==1 || glassestype==2) && whichimage==2))
  26921. X        {
  26922. X            if (Targa_Overlay)    
  26923. X            {        
  26924. X                /* Make sure target file is a supportable Targa File */    
  26925. X                if(targa_validate (light_name))        
  26926. X                    return(-1);
  26927. X            }        
  26928. X            else
  26929. X            {
  26930. X                check_writefile(light_name,".tga");
  26931. X                if (startdisk1(light_name, NULL, 0))    /* Open new file */
  26932. X                    return(-1);
  26933. X            }
  26934. X        }
  26935. X
  26936. X        rand_factor = 14 - RANDOMIZE;
  26937. X
  26938. X        zcoord = filecolors;
  26939. X
  26940. X        crossavg[0] = 0;
  26941. X        crossavg[1] = 0;
  26942. X        crossavg[2] = 0;
  26943. X
  26944. X        /*********************************************************************/
  26945. X        /*  Memory allocation - assumptions - a 64K segment starting at        */
  26946. X        /*  extraseg has been grabbed. It may have other purposes elsewhere, */
  26947. X        /*  but it is assumed that it is totally free for use here. Our        */
  26948. X        /*  strategy is to assign all the far pointers needed here to various*/
  26949. X        /*  spots in the extra segment, depending on the pixel dimensions of */
  26950. X        /*  the video mode, and check whether we have run out. There is        */
  26951. X        /*  basically one case where the extra segment is not big enough        */
  26952. X        /*  -- SPHERE mode with a fill type that uses putatriangle() (array    */
  26953. X        /*  minmax_x) at the largest legal resolution of MAXPIXELSxMAXPIXELS or            */
  26954. X        /*  thereabouts. In that case we use farmemalloc to grab    memory        */
  26955. X        /*  for minmax_x. This memory is never freed.                                */
  26956. X        /*********************************************************************/
  26957. X
  26958. X        /* lastrow stores the previous row of the original GIF image for
  26959. X            the purpose of filling in gaps with triangle procedure */
  26960. X        lastrow = MK_FP(extraseg,0);
  26961. X
  26962. X        check_extra = sizeof(*lastrow)*xdots;
  26963. X        if(SPHERE)
  26964. X        {
  26965. X            sinthetaarray = (float far *)(lastrow+xdots);
  26966. X            check_extra += sizeof(*sinthetaarray)*xdots;
  26967. X
  26968. X            costhetaarray = (float far *)(sinthetaarray+xdots);
  26969. X            check_extra += sizeof(*costhetaarray)*xdots;
  26970. X
  26971. X            f_lastrow = (struct f_point far *)(costhetaarray+xdots);
  26972. X        }
  26973. X        else
  26974. X            f_lastrow = (struct f_point far *)(lastrow+xdots);
  26975. X        check_extra += sizeof(*f_lastrow)*(xdots);
  26976. X
  26977. X        if(pot16bit)
  26978. X        {
  26979. X            fraction = (BYTE far *)(f_lastrow+xdots);
  26980. X            check_extra += sizeof(*fraction)*xdots;
  26981. X        }
  26982. X        minmax_x = (struct minmax *)NULL;
  26983. X
  26984. X        /* these fill types call putatriangle which uses minmax_x */
  26985. X        if( FILLTYPE == 2 || FILLTYPE == 3 || FILLTYPE == 5 || FILLTYPE == 6)
  26986. X        {
  26987. X            /* end of arrays if we use extra segement */
  26988. X            check_extra += sizeof(struct minmax)*ydots;
  26989. X            if(check_extra > (1L<<16)) /* run out of extra segment? */
  26990. X            {
  26991. X                static struct minmax far *got_mem = NULL;
  26992. X                /* not using extra segment so decrement check_extra */
  26993. X                check_extra -= sizeof(struct minmax)*ydots;
  26994. X                if(got_mem == NULL)
  26995. X                    got_mem = (struct minmax far *)(farmemalloc(MAXPIXELS *
  26996. X                sizeof(struct minmax)));
  26997. X
  26998. X                if(got_mem)
  26999. X                    minmax_x = got_mem;
  27000. X                else
  27001. X                {
  27002. X                    EXIT_OVLY;
  27003. X                    return(-1);
  27004. X                }
  27005. X            }
  27006. X            else /* ok to use extra segment */
  27007. X            {
  27008. X                if(pot16bit)
  27009. X                    minmax_x = (struct minmax far *)(fraction+xdots);
  27010. X                else
  27011. X                    minmax_x = (struct minmax far *)(f_lastrow+xdots);
  27012. X
  27013. X            }
  27014. X        }
  27015. X
  27016. X        if(debugflag == 2222 || check_extra > (1L<<16))
  27017. X        {
  27018. X            char tmpmsg[70];
  27019. X            static char far extramsg[] = {" of extra segment"};
  27020. X#ifndef XFRACT
  27021. X            sprintf(tmpmsg,"used %ld%Fs", check_extra, extramsg);
  27022. X#else
  27023. X            sprintf(tmpmsg,"used %ld%s", check_extra, extramsg);
  27024. X#endif
  27025. X            stopmsg(4,tmpmsg);
  27026. X        }
  27027. X
  27028. X        /* get scale factors */
  27029. X        sclx =    XSCALE/100.0;
  27030. X        scly =    YSCALE/100.0;
  27031. X        if (ROUGH)
  27032. X            sclz = -ROUGH/100.0;
  27033. X        else
  27034. X            rscale = sclz = -0.0001; /* if rough=0 make it very flat but plot something */
  27035. X
  27036. X        /* aspect ratio calculation - assume screen is 4 x 3 */
  27037. X        aspect = (double)xdots*.75/(double)ydots;
  27038. X
  27039. X        if(SPHERE==FALSE)  /* skip this slow stuff in sphere case */
  27040. X        {
  27041. X        /*********************************************************************/
  27042. X        /* What is done here is to create a single matrix, m, which has        */
  27043. X        /* scale, rotation, and shift all combined. This allows us to use        */
  27044. X        /* a single matrix to transform any point. Additionally, we create      */
  27045. X        /* two perspective vectors.                                                        */
  27046. X        /*                                                                                            */
  27047. X        /* Start with a unit matrix. Add scale and rotation. Then calculate     */
  27048. X        /* the perspective vectors. Finally add enough translation to center    */
  27049. X        /* the final image plus whatever shift the user has set.                    */
  27050. X        /*********************************************************************/
  27051. X
  27052. X            /* start with identity */
  27053. X            identity (m);
  27054. X            identity (lightm);
  27055. X
  27056. X            /* translate so origin is in center of box, so that when we rotate */
  27057. X            /* it, we do so through the center */
  27058. X            trans ( (double)xdots/(-2.0),(double)ydots/(-2.0),
  27059. X                    (double)zcoord/(-2.0),m);
  27060. X            trans ( (double)xdots/(-2.0),(double)ydots/(-2.0),
  27061. X                    (double)zcoord/(-2.0),lightm);
  27062. X
  27063. X            /* apply scale factors */
  27064. X            scale(sclx,scly,sclz,m);
  27065. X            scale(sclx,scly,sclz,lightm);
  27066. X
  27067. X            /* rotation values - converting from degrees to radians */
  27068. X            xval = XROT / 57.29577;
  27069. X            yval = YROT / 57.29577;
  27070. X            zval = ZROT / 57.29577;
  27071. X
  27072. X            if (RAY)    {xval = yval = zval = 0;}
  27073. X
  27074. X            xrot (xval,m);
  27075. X            xrot (xval,lightm);
  27076. X            yrot (yval,m);
  27077. X            yrot (yval,lightm);
  27078. X            zrot (zval,m);
  27079. X            zrot (zval,lightm);
  27080. X
  27081. X            /* Find values of translation that make all x,y,z negative */
  27082. X            /* m current matrix */
  27083. X            /* 0 means don't show box */
  27084. X            /* returns minimum and maximum values of x,y,z in fractal */
  27085. X            corners(m,0,&xmin,&ymin,&zmin,&xmax,&ymax,&zmax);
  27086. X        }
  27087. X
  27088. X        /* perspective 3D vector - lview[2] == 0 means no perspective */
  27089. X
  27090. X        /* set perspective flag */
  27091. X        persp = 0;
  27092. X        if (ZVIEWER != 0)
  27093. X        {
  27094. X            persp = 1;
  27095. X            if(ZVIEWER < 80) /* force float */
  27096. X                usr_floatflag |= 2; /* turn on second bit */
  27097. X        }
  27098. X
  27099. X        /* set up view vector, and put viewer in center of screen */
  27100. X        lview[0] = xdots >> 1;
  27101. X        lview[1] = ydots >> 1;
  27102. X
  27103. X        /* z value of user's eye - should be more negative than extreme
  27104. X                                negative part of image */
  27105. X        if(SPHERE) /* sphere case */
  27106. X            lview[2] = -(long)((double)ydots*(double)ZVIEWER/100.0);
  27107. X        else    /* non-sphere case */
  27108. X            lview[2] = (long)((zmin-zmax)*(double)ZVIEWER/100.0);
  27109. X
  27110. X        view[0] = lview[0];
  27111. X        view[1] = lview[1];
  27112. X        view[2] = lview[2];
  27113. X        lview[0] = lview[0] << 16;
  27114. X        lview[1] = lview[1] << 16;
  27115. X        lview[2] = lview[2] << 16;
  27116. X
  27117. X        if(SPHERE==FALSE) /* sphere skips this */
  27118. X        {
  27119. X            /* translate back exactly amount we translated earlier plus enough
  27120. X                to center image so maximum values are non-positive */
  27121. X            trans(((double)xdots-xmax-xmin)/2,((double)ydots-ymax-ymin) / 2,
  27122. X                -zmax,m);
  27123. X
  27124. X            /* Keep the box centered and on screen regardless of shifts */
  27125. X            trans(((double)xdots-xmax-xmin)/2,((double)ydots-ymax-ymin)/2,
  27126. X                -zmax,lightm);
  27127. X
  27128. X            trans((double)(xshift),(double)(-yshift),0.0,m);
  27129. X
  27130. X            /* matrix m now contains ALL those transforms composed together !!
  27131. X                convert m to long integers shifted 16 bits */
  27132. X            for (i = 0; i < 4; i++)
  27133. X                for (j = 0; j < 4; j++)
  27134. X                    lm[i][j] = m[i][j] * 65536.0;
  27135. X
  27136. X        }
  27137. X        else /* sphere stuff goes here */
  27138. X        {
  27139. X            /* Sphere is on side - north pole on right. Top is -90 degrees
  27140. X                latitude; bottom 90 degrees */
  27141. X
  27142. X            /* Map X to this LATITUDE range */
  27143. X            theta1 = THETA1*PI/180.0;
  27144. X            theta2 = THETA2*PI/180.0;
  27145. X
  27146. X            /* Map Y to this LONGITUDE range */
  27147. X            phi1    = PHI1*PI/180.0;
  27148. X            phi2    = PHI2*PI/180.0;
  27149. X
  27150. X            theta = theta1;
  27151. X
  27152. X        /*********************************************************************/
  27153. X        /* Thanks to Hugh Bray for the following idea: when calculating        */
  27154. X        /* a table of evenly spaced sines or cosines, only a few initial        */
  27155. X        /* values need be calculated, and the remaining values can be            */
  27156. X        /* gotten from a derivative of the sine/cosine angle sum formula        */
  27157. X        /* at the cost of one multiplication and one addition per value!        */
  27158. X        /*                                                                                            */
  27159. X        /* This idea is applied once here to get a complete table for            */
  27160. X        /* latitude, and near the bottom of this routine to incrementally        */
  27161. X        /* calculate longitude.                                                                */
  27162. X        /*                                                                                            */
  27163. X        /* Precalculate 2*cos(deltaangle), sin(start) and sin(start+delta).    */
  27164. X        /* Then apply recursively:                                                            */
  27165. X        /*    sin(angle+2*delta) = sin(angle+delta) * 2cosdelta - sin(angle)        */
  27166. X        /*                                                                                            */
  27167. X        /* Similarly for cosine. Neat!                                                     */
  27168. X        /*********************************************************************/
  27169. X
  27170. X            deltatheta = (float)(theta2 - theta1)/(float)linelen;
  27171. X
  27172. X            /* initial sin,cos theta */
  27173. X            sinthetaarray[0] = sin((double)theta);
  27174. X            costhetaarray[0] = cos((double)theta);
  27175. X            sinthetaarray[1] = sin((double)(theta + deltatheta));
  27176. X            costhetaarray[1] = cos((double)(theta + deltatheta));
  27177. X
  27178. X            /* sin,cos delta theta */
  27179. X            twocosdeltatheta = 2.0*cos((double)deltatheta);
  27180. X
  27181. X            /* build table of other sin,cos with trig identity */
  27182. X            for(i=2;i<linelen;i++)
  27183. X            {
  27184. X                sinthetaarray[i] = sinthetaarray[i-1]*twocosdeltatheta-
  27185. X                    sinthetaarray[i-2];
  27186. X                costhetaarray[i] = costhetaarray[i-1]*twocosdeltatheta-
  27187. X                    costhetaarray[i-2];
  27188. X            }
  27189. X
  27190. X            /* now phi - these calculated as we go - get started here */
  27191. X            deltaphi    = (float)(phi2    - phi1  )/(float)height;
  27192. X
  27193. X            /* initial sin,cos phi */
  27194. X
  27195. X            sinphi = oldsinphi1 = sin((double)phi1);
  27196. X            cosphi = oldcosphi1 = cos((double)phi1);
  27197. X            oldsinphi2 = sin((double)(phi1+deltaphi));
  27198. X            oldcosphi2 = cos((double)(phi1+deltaphi));
  27199. X
  27200. X            /* sin,cos delta phi */
  27201. X            twocosdeltaphi = 2*cos((double)deltaphi);
  27202. X
  27203. X            xcenter0 = xcenter = xdots/2 + xshift;
  27204. X            ycenter0 = ycenter = ydots/2 - yshift;
  27205. X
  27206. X            /* affects how rough planet terrain is */
  27207. X            if (ROUGH)
  27208. X                rscale = .3*ROUGH/100.0;
  27209. X
  27210. X            /* radius of planet */
  27211. X            R = (double)(ydots)/2;
  27212. X
  27213. X            /* precalculate factor */
  27214. X            rXrscale = R*rscale;
  27215. X
  27216. X            sclz = sclx = scly = RADIUS/100.0; /* Need x,y,z for RAY */
  27217. X
  27218. X            /* adjust x scale factor for aspect */
  27219. X            sclx *= aspect;
  27220. X
  27221. X            /* precalculation factor used in sphere calc */
  27222. X            Rfactor = rscale*R/(double)zcoord;
  27223. X
  27224. X            if(persp) /* precalculate fudge factor */
  27225. X            {
  27226. X                double radius;
  27227. X                double zview;
  27228. X                double angle;
  27229. X
  27230. X                xcenter  = xcenter << 16;
  27231. X                ycenter  = ycenter << 16;
  27232. X
  27233. X                Rfactor *= 65536.0;
  27234. X                R            *= 65536.0;
  27235. X
  27236. X                /* calculate z cutoff factor
  27237. X                    attempt to prevent out-of-view surfaces from being written */
  27238. X                zview = -(long)((double)ydots*(double)ZVIEWER/100.0);
  27239. X                radius = (double)(ydots)/2;
  27240. X                angle = atan(-radius/(zview+radius));
  27241. X                zcutoff = -radius - sin(angle)*radius;
  27242. X                zcutoff *= 1.1; /* for safety */
  27243. X                zcutoff *= 65536;
  27244. X            }
  27245. X        }
  27246. X
  27247. X        /* set fill plot function */
  27248. X        if(FILLTYPE != 3)
  27249. X            fillplot = interpcolor;
  27250. X        else
  27251. X        {
  27252. X            fillplot = clipcolor;
  27253. X
  27254. X            if(transparent[0] || transparent[1])
  27255. X                /*    If transparent colors are set */
  27256. X                fillplot = T_clipcolor;  /*  Use the transparent plot function  */
  27257. X        }
  27258. X
  27259. X        /* Both Sphere and Normal 3D */
  27260. X        direct[0] = light_direction[0] = XLIGHT;
  27261. X        direct[1] = light_direction[1] = -YLIGHT;
  27262. X        direct[2] = light_direction[2] = ZLIGHT;
  27263. X
  27264. X        /* Needed because sclz = -ROUGH/100 and light_direction is transformed
  27265. X            in FILLTYPE 6 but not in 5. */
  27266. X        if (FILLTYPE == 5)
  27267. X            direct[2] = light_direction[2] = -ZLIGHT;
  27268. X
  27269. X        if(FILLTYPE==6) /* transform light direction */
  27270. X        {
  27271. X            /* Think of light direction  as a vector with tail at (0,0,0) and
  27272. X                head at (light_direction). We apply the transformation to
  27273. X                BOTH head and tail and take the difference */
  27274. X
  27275. X            v[0] = 0.0;
  27276. X            v[1] = 0.0;
  27277. X            v[2] = 0.0;
  27278. X            vmult(v,m,v);
  27279. X            vmult(light_direction,m,light_direction);
  27280. X
  27281. X            for (i=0;i<3;i++)        light_direction[i] -= v[i];
  27282. X        }
  27283. X        normalize_vector(light_direction);
  27284. X
  27285. X        if(preview && showbox)
  27286. X        {
  27287. X            normalize_vector(direct);
  27288. X
  27289. X            /* move light vector to be more clear with grey scale maps */
  27290. X            origin[0] = (3 * xdots) / 16;
  27291. X            origin[1] = (3 * ydots) / 4;
  27292. X            if (FILLTYPE == 6)
  27293. X                origin[1] = (11 * ydots) / 16;
  27294. X
  27295. X            origin[2] = 0.0;
  27296. X
  27297. X            v_length = min (xdots, ydots) / 2;
  27298. X            if (persp && ZVIEWER <= P)
  27299. X                v_length *= (long)(P + 600) /((long)(ZVIEWER+600) * 2);
  27300. X
  27301. X            /* Set direct[] to point from origin[] in direction of
  27302. X                untransformed light_direction (direct[]). */
  27303. X            for (i=0;i<3;i++)
  27304. X                direct[i] = origin[i] + direct[i] * v_length;
  27305. X
  27306. X            /* center light box */
  27307. X            for (i=0;i<2;i++)
  27308. X            {
  27309. X                tmp[i] = (direct[i] - origin[i]) / 2;
  27310. X                origin[i] -= tmp[i];
  27311. X                direct[i] -= tmp[i];
  27312. X            }
  27313. X
  27314. X            /* Draw light source vector and box containing it, draw_light_box
  27315. X                will transform them if necessary. */
  27316. X            draw_light_box (origin,direct,lightm);
  27317. X            /* draw box around original field of view to help visualize effect
  27318. X                of rotations 1 means show box - xmin etc. do nothing here */
  27319. X            if (!SPHERE)
  27320. X                corners(m,1,&xmin,&ymin,&zmin,&xmax,&ymax,&zmax);
  27321. X        }
  27322. X
  27323. X        /* bad has values caught by clipping */
  27324. X        f_bad.x            = bad.x            = bad_value;
  27325. X        f_bad.y            = bad.y            = bad_value;
  27326. X        f_bad.color = bad.color = bad_value;
  27327. X        for(i=0;i<linelen;i++)
  27328. X        {
  27329. X            lastrow[i]    = bad;
  27330. X            f_lastrow[i] = f_bad;
  27331. X        }
  27332. X        got_status = 3;
  27333. X        if(iit>0)
  27334. X        {
  27335. X            load_mat(m); /* load matrix into iit registers */
  27336. X            mult_vec = mult_vec_iit;
  27337. X        }
  27338. X        else
  27339. X            mult_vec = mult_vec_c;
  27340. X    } /* end of once-per-image intializations */
  27341. X
  27342. X    crossnotinit = 1;
  27343. X    col = 0;
  27344. X
  27345. X    CO = 0;
  27346. X
  27347. X    /* make sure these pixel coordinates are out of range */
  27348. X    old        = bad;
  27349. X    f_old = f_bad;
  27350. X
  27351. X    /* copies pixels buffer to float type fraction buffer for fill purposes */
  27352. X    if(pot16bit)
  27353. X        if (set_pixel_buff(pixels,fraction,linelen))
  27354. X        {
  27355. X            EXIT_OVLY;
  27356. X            return(0);
  27357. X        }
  27358. X
  27359. X  /*************************************************************************/
  27360. X  /* This section of code allows the operation of a preview mode when the    */
  27361. X  /* preview flag is set. Enabled, it allows the drawing of only the first */
  27362. X  /* line of the source image, then every 10th line, until and including    */
  27363. X  /* the last line. For the undrawn lines, only necessary calculations are */
  27364. X  /* made. As a bonus, in non-sphere mode a box is drawn to help visualize */
  27365. X  /* the effects of 3D transformations. Thanks to Marc Reinig for this idea*/
  27366. X  /* and code -- BTW, Marc did NOT put the goto in, but WE did, to avoid    */
  27367. X  /* copying code here, and to avoid a HUGE "if-then" construct. Besides,    */
  27368. X  /* we have ALREADY sinned, so why not sin some more?                            */
  27369. X  /*************************************************************************/
  27370. X
  27371. X
  27372. X    lastdot = min(xdots-1, linelen-1);
  27373. X    if (FILLTYPE >= 5)
  27374. X        if (haze && Targa_Out)
  27375. X        {
  27376. X            HAZE_MULT = haze * (
  27377. X                (float)((long)(ydots - 1 - currow) *
  27378. X                (long)(ydots - 1 - currow)) /
  27379. X                (float)((long)(ydots - 1) * (long)(ydots - 1)));
  27380. X            HAZE_MULT = 100 - HAZE_MULT;
  27381. X        }
  27382. X
  27383. X    if (previewfactor >= ydots || previewfactor > lastdot)
  27384. X        previewfactor = min ( ydots - 1, lastdot);
  27385. X
  27386. X    localpreviewfactor = ydots/previewfactor;
  27387. X
  27388. X    tout = 0;
  27389. X    /* Insure last line is drawn in preview and filltypes <0  */
  27390. X    if ((RAY || preview || FILLTYPE < 0) && (currow != ydots-1) &&
  27391. X        (currow % localpreviewfactor) && /* Draw mod preview lines */
  27392. X        !(!RAY && (FILLTYPE > 4) && (currow == 1)))
  27393. X            /* Get init geometry in lightsource modes */
  27394. X            goto reallythebottom; /* skip over most of the line3d calcs */
  27395. X    if (dotmode == 11)
  27396. X    {
  27397. X        char s[40];
  27398. X        sprintf(s,"mapping to 3d, reading line %d", currow);
  27399. X        dvid_status(1,s);
  27400. X    }
  27401. X
  27402. X    if(!col && RAY && currow != 0)        start_object();
  27403. X
  27404. X    if(FILLTYPE==0 && !SPHERE && !pot16bit && !RAY && debugflag != 2224 )
  27405. X        /* This while loop contains just a limited non-sphere case for speed */
  27406. X        /* Other while loop still has the old logic. Use debugflag to compare*/
  27407. X        while(col < linelen)
  27408. X        {
  27409. X            Real_Color = cur.color = pixels[col];
  27410. X            if (cur.color > 0 && cur.color < WATERLINE)
  27411. X                Real_Color = cur.color = WATERLINE;  /* "lake" */
  27412. X            if(!usr_floatflag)
  27413. X            {
  27414. X                lv0[0] = 0; /* don't save vector before perspective */
  27415. X
  27416. X                /* use 32-bit multiply math to snap this out */
  27417. X                lv[0] = col;
  27418. X                lv[0] = lv[0] << 16;
  27419. X                lv[1] = currow;
  27420. X                lv[1] = lv[1] << 16;
  27421. X                lv[2] = cur.color;
  27422. X                lv[2] = lv[2] << 16;
  27423. X
  27424. X                if(longvmultpersp(lv,lm,lv0,lv,lview,16) == -1)
  27425. X                {
  27426. X                    cur    = bad;
  27427. X                    goto loopbottom;
  27428. X                }
  27429. X                cur.x = ((lv[0]/* +32768L */) >> 16) + xxadjust;
  27430. X                cur.y = ((lv[1]/* +32768L */) >> 16) + yyadjust;
  27431. X            }
  27432. X            /* do in float if integer math overflowed */
  27433. X            if(usr_floatflag || overflow)
  27434. X            {
  27435. X                /* slow float version for comparison */
  27436. X                v[0] = col;
  27437. X                v[1] = currow;
  27438. X                v[2] = cur.color;
  27439. X                mult_vec(v); /* matrix*vector routine */
  27440. X                if(persp)
  27441. X                    perspective(v);
  27442. X                cur.x = v[0] + xxadjust /* + .5 */;
  27443. X                cur.y = v[1] + yyadjust /* + .5 */;
  27444. X            }
  27445. X            (*plot)(cur.x,cur.y,cur.color);
  27446. X            col++;
  27447. X        }  /*  End of while statement for plotting line  */
  27448. X    else
  27449. X
  27450. X        /* PROCESS ROW LOOP BEGINS HERE */
  27451. X        while(col < linelen)
  27452. X        {
  27453. X            if ((RAY || preview || FILLTYPE < 0) &&
  27454. X                (col != lastdot) &&        /* if this is not the last col */
  27455. X                /* if not the 1st or mod factor col*/
  27456. X                (col % (int)(aspect * localpreviewfactor)) &&
  27457. X                (!(!RAY && FILLTYPE > 4 && col == 1)))
  27458. X                    goto loopbottom;
  27459. X
  27460. X            f_cur.color = Real_Color = cur.color = pixels[col];
  27461. X
  27462. X            if (RAY || preview || FILLTYPE < 0)
  27463. X            {
  27464. X                next = col + aspect * localpreviewfactor;
  27465. X                if (next == col)        next = col + 1;
  27466. X            }
  27467. X            else
  27468. X                next = col + 1;
  27469. X            if (next >= lastdot)
  27470. X                next = lastdot;
  27471. X
  27472. X            if (cur.color > 0 && cur.color < WATERLINE)
  27473. X                f_cur.color = Real_Color = cur.color = WATERLINE;        /* "lake" */
  27474. X            else if(pot16bit)
  27475. X                f_cur.color += ((float)fraction[col])/(float)(1<<8);
  27476. X
  27477. X            if(SPHERE) /* sphere case */
  27478. X            {
  27479. X                sintheta = sinthetaarray[col];
  27480. X                costheta = costhetaarray[col];
  27481. X
  27482. X                if(sinphi < 0 && !(RAY || FILLTYPE < 0))
  27483. X                {
  27484. X                    cur    = bad;
  27485. X                    f_cur = f_bad;
  27486. X                    goto loopbottom;    /* another goto ! */
  27487. X                }
  27488. X            /******************************************************************/
  27489. X            /* KEEP THIS FOR DOCS - original formula --                                */
  27490. X            /* if(rscale < 0.0)                                                                 */
  27491. X            /*            r = 1.0+((double)cur.color/(double)zcoord)*rscale;            */
  27492. X            /* else                                                                                */
  27493. X            /*            r = 1.0-rscale+((double)cur.color/(double)zcoord)*rscale;*/
  27494. X            /* R = (double)ydots/2;                                                            */
  27495. X            /* r = r*R;                                                                         */
  27496. X            /* cur.x = xdots/2 + sclx*r*sintheta*aspect + xup ;                    */
  27497. X            /* cur.y = ydots/2 + scly*r*costheta*cosphi - yup ;                    */
  27498. X            /******************************************************************/
  27499. X
  27500. X                if(rscale < 0.0)
  27501. X                    r = R + Rfactor*(double)f_cur.color*costheta;
  27502. X                else if(rscale > 0.0)
  27503. X                    r = R -rXrscale + Rfactor*(double)f_cur.color*costheta;
  27504. X                else
  27505. X                    r = R;
  27506. X                if(persp || RAY) /* Allow Ray trace to go through so display is ok */
  27507. X                {    /* mrr how do lv[] and cur and f_cur all relate */
  27508. X                    /* NOTE: fudge was pre-calculated above in r and R */
  27509. X                    /* (almost) guarantee negative */
  27510. X                    lv[2] = -R - r*costheta*sinphi;    /* z */
  27511. X                    if((lv[2] > zcutoff) && !FILLTYPE < 0)
  27512. X                    {
  27513. X                        cur = bad;
  27514. X                        f_cur = f_bad;
  27515. X                        goto loopbottom;    /* another goto ! */
  27516. X                    }
  27517. X                    lv[0] = xcenter + sintheta*sclx*r;    /* x */
  27518. X                    lv[1] = ycenter + costheta*cosphi*scly*r;        /* y */
  27519. X
  27520. X                    if((FILLTYPE >= 5) || RAY)
  27521. X                    {  /* calculate illumination normal before persp */
  27522. X
  27523. X                        r0        = r/65536;
  27524. X                        f_cur.x        = xcenter0 + sintheta*sclx*r0;
  27525. X                        f_cur.y        = ycenter0 + costheta*cosphi*scly*r0;
  27526. X                        f_cur.color = -r0*costheta*sinphi;
  27527. X                    }
  27528. X                    if(!(usr_floatflag || RAY))
  27529. X                    {
  27530. X                        if(longpersp(lv,lview,16) == -1)
  27531. X                        {
  27532. X                            cur = bad;
  27533. X                            f_cur = f_bad;
  27534. X                            goto loopbottom;    /* another goto ! */
  27535. X                        }
  27536. X                        cur.x = ((lv[0]+32768L) >> 16) + xxadjust;
  27537. X                        cur.y = ((lv[1]+32768L) >> 16) + yyadjust;
  27538. X                    }
  27539. X                    if(usr_floatflag || overflow || RAY)
  27540. X                    {
  27541. X                        v[0] = lv[0];
  27542. X                        v[1] = lv[1];
  27543. X                        v[2] = lv[2];
  27544. X                        v[0] /= fudge;
  27545. X                        v[1] /= fudge;
  27546. X                        v[2] /= fudge;
  27547. X                        perspective(v);
  27548. X                        cur.x = v[0]+.5 + xxadjust;
  27549. X                        cur.y = v[1]+.5 + yyadjust;
  27550. X                    }
  27551. X                }
  27552. X                else if (!(persp && RAY)) /* mrr Not sure how this and 3rd if
  27553. X                                                    above relate */
  27554. X                {    /* mrr Why the xx- and yyadjust here and not above? */
  27555. X                    cur.x = f_cur.x = xcenter + sintheta*sclx*r + xxadjust;
  27556. X                    cur.y = f_cur.y = ycenter + costheta*cosphi*scly*r + yyadjust;
  27557. X                    if(FILLTYPE >= 5 || RAY) /* mrr why do we do this for filltype>5? */
  27558. X                        f_cur.color = -r * costheta * sinphi * sclz;
  27559. X                    v[0]=v[1]=v[2]=0;    /* MRR Why do we do this? */
  27560. X                }
  27561. X            }
  27562. X            else /* non-sphere 3D */
  27563. X            {
  27564. X                if(!usr_floatflag && !RAY)
  27565. X                {
  27566. X                    if(FILLTYPE >= 5) /* flag to save vector before perspective */
  27567. X                        lv0[0] = 1;        /* in longvmultpersp calculation */
  27568. X                    else
  27569. X                        lv0[0] = 0;
  27570. X
  27571. X                    /* use 32-bit multiply math to snap this out */
  27572. X                    lv[0] = col;
  27573. X                    lv[0] = lv[0] << 16;
  27574. X                    lv[1] = currow;
  27575. X                    lv[1] = lv[1] << 16;
  27576. X                    if(filetype || pot16bit) /* don't truncate fractional part */
  27577. X                        lv[2] = f_cur.color*65536.0;
  27578. X                    else    /* there IS no fractaional part here! */
  27579. X                    {
  27580. X                        lv[2] = f_cur.color;
  27581. X                        lv[2] = lv[2] << 16;
  27582. X                    }
  27583. X
  27584. X                    if(longvmultpersp(lv,lm,lv0,lv,lview,16) == -1)
  27585. X                    {
  27586. X                        cur    = bad;
  27587. X                        f_cur = f_bad;
  27588. X                        goto loopbottom;
  27589. X                    }
  27590. X
  27591. X                    cur.x = ((lv[0]+32768L) >> 16) + xxadjust;
  27592. X                    cur.y = ((lv[1]+32768L) >> 16) + yyadjust;
  27593. X                    if(FILLTYPE >= 5 && !overflow)
  27594. X                    {
  27595. X                        f_cur.x        = lv0[0];
  27596. X                        f_cur.x            /= 65536.0;
  27597. X                        f_cur.y        = lv0[1];
  27598. X                        f_cur.y            /= 65536.0;
  27599. X                        f_cur.color  = lv0[2];
  27600. X                        f_cur.color /= 65536.0;
  27601. X                    }
  27602. X                }
  27603. X
  27604. X                if(usr_floatflag || overflow || RAY)
  27605. X                /* do in float if integer math overflowed or doing Ray trace */
  27606. X                {
  27607. X                    /* slow float version for comparison */
  27608. X                    v[0] = col;
  27609. X                    v[1] = currow;
  27610. X                    v[2] = f_cur.color; /* Actually the z value */
  27611. X
  27612. X                    mult_vec(v); /* matrix*vector routine */
  27613. X
  27614. X                    if (FILLTYPE > 4 || RAY)
  27615. X                    {
  27616. X                        f_cur.x    = v[0];
  27617. X                        f_cur.y    = v[1];
  27618. X                        f_cur.color = v[2];
  27619. X
  27620. X                        if(RAY == 6)
  27621. X                        {
  27622. X                            f_cur.x = f_cur.x * (2.0 / xdots) - 1;
  27623. X                            f_cur.y = f_cur.y * (2.0 / ydots) - 1;
  27624. X                            f_cur.color = -f_cur.color * (2.0 / numcolors) - 1;
  27625. X                        }
  27626. X                    }
  27627. X
  27628. X                    if(persp && !RAY)
  27629. X                        perspective(v);
  27630. X                    cur.x = v[0] + xxadjust + .5;
  27631. X                    cur.y = v[1] + yyadjust + .5;
  27632. X
  27633. X                    v[0] = 0;
  27634. X                    v[1] = 0;
  27635. X                    v[2] = WATERLINE;
  27636. X                    mult_vec(v);
  27637. X                    f_water = v[2];
  27638. X                }
  27639. X            }
  27640. X
  27641. X            if (RANDOMIZE)
  27642. X                if (cur.color > WATERLINE)
  27643. X                {
  27644. X                    RND = rand15() >> 8;    /* 7-bit number */
  27645. X                    RND = RND * RND >> rand_factor;    /* n-bit number */
  27646. X
  27647. X                    if (rand() & 1)
  27648. X                        RND = -RND; /* Make +/- n-bit number */
  27649. X
  27650. X                    if ((int)(cur.color) + RND >= colors)
  27651. X                        cur.color = colors-2;
  27652. X                    else if ((int)(cur.color) + RND <= WATERLINE)
  27653. X                        cur.color = WATERLINE + 1;
  27654. X                    else
  27655. X                        cur.color = cur.color + RND;
  27656. X                    Real_Color = cur.color;
  27657. X                }
  27658. X
  27659. X            if (RAY)
  27660. X            {
  27661. X                if (col && currow &&
  27662. X                    old.x > bad_check &&
  27663. X                    old.x < (xdots - bad_check) &&
  27664. X                    lastrow[col].x > bad_check &&
  27665. X                    lastrow[col].y > bad_check &&
  27666. X                    lastrow[col].x < (xdots - bad_check) &&
  27667. X                    lastrow[col].y < (ydots - bad_check))
  27668. X                {
  27669. X                    /* Get rid of all the triangles in the plane
  27670. X                        at the base of the object */
  27671. X
  27672. X                    if (f_cur.color == f_water &&
  27673. X                        f_lastrow[col].color == f_water &&
  27674. X                        f_lastrow[next].color == f_water)
  27675. X                            goto loopbottom;
  27676. X
  27677. X                    if (RAY != 6) /* Output the vertex info */
  27678. X                        out_triangle(f_cur, f_old, f_lastrow[col],
  27679. X                            cur.color, old.color, lastrow[col].color);
  27680. X
  27681. X                    tout = 1;
  27682. X
  27683. X                    draw_line (old.x, old.y, cur.x, cur.y, old.color);
  27684. X                    draw_line (old.x, old.y, lastrow[col].x,
  27685. X                        lastrow[col].y, old.color);
  27686. X                    draw_line (lastrow[col].x, lastrow[col].y,
  27687. X                        cur.x, cur.y, cur.color);
  27688. X                    num_tris++;
  27689. X                }
  27690. X
  27691. X                if (col < lastdot && currow &&
  27692. X                    lastrow[col].x > bad_check &&
  27693. X                    lastrow[col].y > bad_check &&
  27694. X                    lastrow[col].x < (xdots - bad_check) &&
  27695. X                    lastrow[col].y < (ydots - bad_check) &&
  27696. X                    lastrow[next].x > bad_check &&
  27697. X                    lastrow[next].y > bad_check &&
  27698. X                    lastrow[next].x < (xdots - bad_check) &&
  27699. X                    lastrow[next].y < (ydots - bad_check))
  27700. X                {
  27701. X                    /* Get rid of all the triangles in the plane
  27702. X                    at the base of the object */
  27703. X
  27704. X                    if (f_cur.color == f_water &&
  27705. X                        f_lastrow[col].color == f_water &&
  27706. X                        f_lastrow[next].color == f_water)
  27707. X                            goto loopbottom;
  27708. X
  27709. X                    if (RAY != 6) /* Output the vertex info */
  27710. X                        out_triangle(f_cur, f_lastrow[col], f_lastrow[next],
  27711. X                            cur.color, lastrow[col].color, lastrow[next].color);
  27712. X
  27713. X                    tout = 1;
  27714. X
  27715. X                    draw_line (lastrow[col].x, lastrow[col].y, cur.x, cur.y,
  27716. X                        cur.color);
  27717. X                    draw_line (lastrow[next].x, lastrow[next].y, cur.x, cur.y,
  27718. X                        cur.color);
  27719. X                    draw_line (lastrow[next].x, lastrow[next].y, lastrow[col].x,
  27720. X                        lastrow[col].y, lastrow[col].color);
  27721. X                    num_tris++;
  27722. X                }
  27723. X
  27724. X                if (RAY == 6)  /* Output vertex info for Acrospin */
  27725. X                {
  27726. X                    fprintf (File_Ptr1, "% #4.4f % #4.4f % #4.4f R%dC%d\n",
  27727. X                        f_cur.x, f_cur.y, f_cur.color, RO, CO);
  27728. X                    if (CO > CO_MAX)
  27729. X                        CO_MAX = CO;
  27730. X                    CO++;
  27731. X                }
  27732. X                goto loopbottom;
  27733. X
  27734. X            }
  27735. X
  27736. X            switch(FILLTYPE)
  27737. X            {
  27738. X                case -1:
  27739. X                    if (col &&
  27740. X                    old.x > bad_check &&
  27741. X                    old.x < (xdots - bad_check))
  27742. X                        draw_line (old.x, old.y, cur.x, cur.y, cur.color);
  27743. X                    if (currow &&
  27744. X                    lastrow[col].x > bad_check &&
  27745. X                    lastrow[col].y > bad_check &&
  27746. X                    lastrow[col].x < (xdots - bad_check) &&
  27747. X                    lastrow[col].y < (ydots - bad_check))
  27748. X                        draw_line (lastrow[col].x,lastrow[col].y,cur.x,
  27749. X                            cur.y,cur.color);
  27750. X                    break;
  27751. X        
  27752. X                case 0:
  27753. X                    (*plot)(cur.x,cur.y,cur.color);
  27754. X                    break;
  27755. X        
  27756. X                case 1:            /* connect-a-dot */
  27757. X                    if ((old.x < xdots) && (col) &&
  27758. X                        old.x > bad_check &&
  27759. X                        old.y > bad_check) /* Don't draw from old to cur on col 0 */
  27760. X                            draw_line(old.x,old.y,cur.x,cur.y,cur.color);
  27761. X                    break;
  27762. X        
  27763. X                case 2: /* with interpolation */
  27764. X                case 3: /* no interpolation */
  27765. X                    /***************************************************************/
  27766. X                    /*  "triangle fill" - consider four points: current point,        */
  27767. X                    /*  previous point same row, point opposite current point in    */
  27768. X                    /*  previous row, point after current point in previous row.    */
  27769. X                    /*  The object is to fill all points inside the two triangles.    */
  27770. X                    /*                                                                                    */
  27771. X                    /*    lastrow[col].x/y___ lastrow[next]                                    */
  27772. X                    /*              /    1         /                                                        */
  27773. X                    /*            /        1       /                                                        */
  27774. X                    /*            /        1     /                                                         */
  27775. X                    /*  oldrow/col _____ trow/col                                                */
  27776. X                    /***************************************************************/
  27777. X        
  27778. X                    if(currow && !col)
  27779. X                        putatriangle(lastrow[next],lastrow[col],cur,cur.color);
  27780. X                    if(currow && col)        /* skip first row and first column */
  27781. X                    {
  27782. X                        if(col == 1)
  27783. X                            putatriangle(lastrow[col],oldlast,old,old.color);
  27784. X        
  27785. X                        if(col < lastdot)
  27786. X                            putatriangle(lastrow[next],lastrow[col], cur, cur.color);
  27787. X                        putatriangle(old, lastrow[col], cur, cur.color);
  27788. X                    }
  27789. X                    break;
  27790. X        
  27791. X                case 4: /* "solid fill" */
  27792. X                    if (SPHERE)
  27793. X                    {
  27794. X                        if (persp)
  27795. X                        {
  27796. X                            old.x = xcenter>>16;
  27797. X                            old.y = ycenter>>16;
  27798. X                        }
  27799. X                        else
  27800. X                        {
  27801. X                            old.x = xcenter;
  27802. X                            old.y = ycenter;
  27803. X                        }
  27804. X                    }
  27805. X                    else
  27806. X                    {
  27807. X                        lv[0] = col;
  27808. X                        lv[1] = currow;
  27809. X                        lv[2] = 0;
  27810. X        
  27811. X                        /* apply fudge bit shift for integer math */
  27812. X                        lv[0] = lv[0] << 16;
  27813. X                        lv[1] = lv[1] << 16;
  27814. X                        /* Since 0, unnecessary lv[2] = lv[2] << 16;*/
  27815. X        
  27816. X                        if(longvmultpersp(lv,lm,lv0,lv,lview,16))
  27817. X                        {
  27818. X                            cur    = bad;
  27819. X                            f_cur = f_bad;
  27820. X                            goto loopbottom;    /* another goto ! */
  27821. X                        }
  27822. X        
  27823. X                        /*    Round and fudge back to original  */
  27824. X                        old.x = (lv[0]+32768L) >> 16;
  27825. X                        old.y = (lv[1]+32768L) >> 16;
  27826. X                    }
  27827. X                    if (old.x < 0)
  27828. X                        old.x = 0;
  27829. X                    if (old.x >= xdots)
  27830. X                        old.x = xdots-1;
  27831. X                    if (old.y < 0)
  27832. X                        old.y = 0;
  27833. X                    if (old.y >= ydots)
  27834. X                        old.y = ydots-1;
  27835. X                    draw_line(old.x,old.y,cur.x,cur.y,cur.color);
  27836. X                    break;
  27837. X        
  27838. X                case 5:
  27839. X                case 6:
  27840. X                    /* light-source modulated fill */
  27841. X                    if(currow && col)        /* skip first row and first column */
  27842. X                    {
  27843. X                        if(f_cur.color < bad_check || f_old.color < bad_check ||
  27844. X                            f_lastrow[col].color < bad_check)
  27845. X                                break;
  27846. X        
  27847. X                        v1[0] = f_cur.x        - f_old.x;
  27848. X                        v1[1] = f_cur.y        - f_old.y;
  27849. X                        v1[2] = f_cur.color - f_old.color;
  27850. X        
  27851. X                        v2[0] = f_lastrow[col].x            - f_cur.x;
  27852. X                        v2[1] = f_lastrow[col].y            - f_cur.y;
  27853. X                        v2[2] = f_lastrow[col].color - f_cur.color;
  27854. X        
  27855. X                        cross_product (v1, v2, cross);
  27856. X        
  27857. X                        /* normalize cross - and check if non-zero */
  27858. X                        if(normalize_vector(cross))
  27859. X                        {
  27860. X                            if(debugflag)
  27861. X                            {
  27862. X                                static char far msg[] = {"debug, cur.color=bad"};
  27863. X                                stopmsg(0,msg);
  27864. X                            }
  27865. X                            cur.color = f_cur.color = bad.color;
  27866. X                        }
  27867. X                        else
  27868. X                        {
  27869. X                            /* line-wise averaging scheme */
  27870. X                            if(LIGHTAVG>0)
  27871. X                            {
  27872. X                                if(crossnotinit)
  27873. X                                {
  27874. X                                    /* initialize array of old normal vectors */
  27875. X                                    crossavg[0] = cross[0];
  27876. X                                    crossavg[1] = cross[1];
  27877. X                                    crossavg[2] = cross[2];
  27878. X                                    crossnotinit = 0;
  27879. X                                }
  27880. X                                tmpcross[0] = (crossavg[0]*LIGHTAVG+cross[0]) /
  27881. X                                   (LIGHTAVG+1);
  27882. X                                tmpcross[1] = (crossavg[1]*LIGHTAVG+cross[1]) /
  27883. X                                   (LIGHTAVG+1);
  27884. X                                tmpcross[2] = (crossavg[2]*LIGHTAVG+cross[2]) /
  27885. X                                   (LIGHTAVG+1);
  27886. X            
  27887. X                                cross[0] = tmpcross[0];
  27888. X                                cross[1] = tmpcross[1];
  27889. X                                cross[2] = tmpcross[2];
  27890. X
  27891. X                                if(normalize_vector(cross))
  27892. X                                {
  27893. X                                    /* this shouldn't happen */
  27894. X                                    if(debugflag)
  27895. X                                    {
  27896. X                                        static char far msg[] =
  27897. X                                        {"debug, normal vector err2"};
  27898. X                                        stopmsg(0,msg);
  27899. X                                        /* use next instead if you ever need details:
  27900. X                                        static char far tmp[] = {"debug, vector err"};
  27901. X                                        char msg[200];
  27902. X#ifndef XFRACT
  27903. X                                        sprintf(msg,"%Fs\n%f %f %f\n%f %f %f\n%f %f %f",
  27904. X#else
  27905. X                                        sprintf(msg,"%s\n%f %f %f\n%f %f %f\n%f %f %f",
  27906. X#endif
  27907. X                                        tmp, f_cur.x, f_cur.y, f_cur.color,
  27908. X                                        f_lastrow[col].x, f_lastrow[col].y,
  27909. X                                        f_lastrow[col].color, f_lastrow[col-1].x,
  27910. X                                        f_lastrow[col-1].y,f_lastrow[col-1].color);
  27911. X                                        stopmsg(0,msg);
  27912. X                                        */
  27913. X                                    }
  27914. X                                    cur.color = f_cur.color = colors;
  27915. X                                }
  27916. X                            }
  27917. X                            crossavg[0] = tmpcross[0];
  27918. X                            crossavg[1] = tmpcross[1];
  27919. X                            crossavg[2] = tmpcross[2];
  27920. X
  27921. X                            /* dot product of unit vectors is cos of angle between */
  27922. X                            /* we will use this value to shade surface */
  27923. X        
  27924. X                            cur.color = 1 + (colors-2) *
  27925. X                                (1.0-dot_product(cross,light_direction));
  27926. X                        }
  27927. X                        /* if colors out of range, set them to min or max color 
  27928. X                            index but avoid background index. This makes colors
  27929. X                            "opaque" so SOMETHING plots. These conditions shouldn't 
  27930. X                            happen but just in case                    */
  27931. X                        if(cur.color < 1)            /* prevent transparent colors */
  27932. X                            cur.color = 1;        /* avoid background */
  27933. X                        if(cur.color > colors-1)
  27934. X                            cur.color = colors-1;
  27935. X        
  27936. X                    /* why "col < 2"? So we have sufficient geometry for the fill */
  27937. X                    /* algorithm, which needs previous point in same row to have  */
  27938. X                    /* already been calculated (variable old)        */
  27939. X                    /* fix ragged left margin in preview */
  27940. X                        if (col == 1 && currow > 1)
  27941. X                            putatriangle(lastrow[next],lastrow[col],cur,cur.color);
  27942. X        
  27943. X                        if(col < 2 || currow < 2) /* don't have valid colors yet */
  27944. X                            break;
  27945. X        
  27946. X                        if(col < lastdot)
  27947. X                            putatriangle(lastrow[next],lastrow[col],cur,cur.color);
  27948. X                        putatriangle(old,lastrow[col],cur,cur.color);
  27949. X        
  27950. X                        plot=standardplot;
  27951. X                    }
  27952. X                    break;
  27953. X            }  /*    End of CASE statement for fill type  */
  27954. X        
  27955. Xloopbottom:
  27956. X
  27957. X            if (RAY || (FILLTYPE != 0 && FILLTYPE != 4))
  27958. X            {
  27959. X                /* for triangle and grid fill purposes */
  27960. X                oldlast = lastrow[col];
  27961. X                old = lastrow[col] = cur;
  27962. X        
  27963. X                /* for illumination model purposes */
  27964. X                f_old    = f_lastrow[col] = f_cur;
  27965. X                if (currow && RAY && col >= lastdot)
  27966. X                /* if we're at the end of a row, close the object */
  27967. X                {
  27968. X                    end_object(tout);
  27969. X                    tout=0;
  27970. X                    if (ferror (File_Ptr1))
  27971. X                    {
  27972. X                        fclose (File_Ptr1);
  27973. X                        remove (light_name);
  27974. X                        File_Error(ray_name, 2);
  27975. X                        EXIT_OVLY;
  27976. X                        return(-1);
  27977. X                    }
  27978. X                }
  27979. X            }
  27980. X        
  27981. X            col++;
  27982. X
  27983. X        }  /*  End of while statement for plotting line  */
  27984. X
  27985. X    RO++;
  27986. X
  27987. Xreallythebottom:
  27988. X        
  27989. X    /* stuff that HAS to be done, even in preview mode, goes here */    
  27990. X    if(SPHERE)    
  27991. X    {    
  27992. X        /* incremental sin/cos phi calc */    
  27993. X        if(currow == 0)    
  27994. X        {    
  27995. X            sinphi = oldsinphi2;    
  27996. X            cosphi = oldcosphi2;    
  27997. X        }    
  27998. X        else    
  27999. X        {    
  28000. X            sinphi = twocosdeltaphi*oldsinphi2 - oldsinphi1;    
  28001. X            cosphi = twocosdeltaphi*oldcosphi2 - oldcosphi1;    
  28002. X            oldsinphi1 = oldsinphi2;    
  28003. X            oldsinphi2 = sinphi;    
  28004. X            oldcosphi1 = oldcosphi2;    
  28005. X            oldcosphi2 = cosphi;    
  28006. X        }    
  28007. X    }
  28008. X    EXIT_OVLY;
  28009. X    return(0); /* decoder needs to know all is well !!! */
  28010. X}
  28011. X
  28012. X
  28013. X/* vector version of line draw */
  28014. Xstatic void _fastcall vdraw_line(v1,v2,color)
  28015. Xdouble *v1,*v2;
  28016. Xint color;
  28017. X{
  28018. X    int x1,y1,x2,y2;
  28019. X    x1 = (int)v1[0];
  28020. X    y1 = (int)v1[1];
  28021. X    x2 = (int)v2[0];
  28022. X    y2 = (int)v2[1];
  28023. X    draw_line(x1,y1,x2,y2,color);
  28024. X}
  28025. X
  28026. X
  28027. X
  28028. Xstatic void corners(m,show,pxmin,pymin,pzmin,pxmax,pymax,pzmax)
  28029. X
  28030. XMATRIX m;
  28031. Xint show; /* turns on box-showing feature */
  28032. Xdouble *pxmin,*pymin,*pzmin,*pxmax,*pymax,*pzmax;
  28033. X
  28034. X{
  28035. X    int i,j;
  28036. X    VECTOR S[2][4]; /* Holds the top an bottom points, S[0][]=bottom */
  28037. X
  28038. X    /*
  28039. X    define corners of box fractal is in in x,y,z plane
  28040. X    "b" stands for "bottom" - these points are the corners of the screen
  28041. X    in the x-y plane. The "t"'s stand for Top - they are the top of
  28042. X    the cube where 255 color points hit.
  28043. X    */
  28044. X
  28045. X    *pxmin = *pymin = *pzmin = (int)INT_MAX;
  28046. X    *pxmax = *pymax = *pzmax = (int)INT_MIN; 
  28047. X
  28048. X    for (j = 0; j < 4; ++j)
  28049. X        for (i=0;i<3;i++)
  28050. X            S[0][j][i]=S[1][j][i]=0;
  28051. X
  28052. X    S[0][1][0] = S[0][2][0] = S[1][1][0] = S[1][2][0] = xdots-1;
  28053. X    S[0][2][1] = S[0][3][1] = S[1][2][1] = S[1][3][1] = ydots-1;
  28054. X    S[1][0][2] = S[1][1][2] = S[1][2][2] = S[1][3][2] = zcoord-1;
  28055. X
  28056. X    for (i = 0; i < 4; ++i)
  28057. X    {
  28058. X        /* transform points */
  28059. X        vmult(S[0][i],m,S[0][i]);
  28060. X        vmult(S[1][i],m,S[1][i]);
  28061. X
  28062. X        /* update minimums and maximums */
  28063. X        if (S[0][i][0] <= *pxmin) *pxmin = S[0][i][0];
  28064. X        if (S[0][i][0] >= *pxmax) *pxmax = S[0][i][0];
  28065. X        if (S[1][i][0] <= *pxmin) *pxmin = S[1][i][0];
  28066. X        if (S[1][i][0] >= *pxmax) *pxmax = S[1][i][0];
  28067. X        if (S[0][i][1] <= *pymin) *pymin = S[0][i][1];
  28068. X        if (S[0][i][1] >= *pymax) *pymax = S[0][i][1];
  28069. X        if (S[1][i][1] <= *pymin) *pymin = S[1][i][1];
  28070. X        if (S[1][i][1] >= *pymax) *pymax = S[1][i][1];
  28071. X        if (S[0][i][2] <= *pzmin) *pzmin = S[0][i][2];
  28072. X        if (S[0][i][2] >= *pzmax) *pzmax = S[0][i][2];
  28073. X        if (S[1][i][2] <= *pzmin) *pzmin = S[1][i][2];
  28074. X        if (S[1][i][2] >= *pzmax) *pzmax = S[1][i][2];
  28075. X    }
  28076. X
  28077. X    if(show)
  28078. X    {
  28079. X        if(persp)
  28080. X        {
  28081. X            for (i=0;i<4;i++)
  28082. X            {
  28083. X                perspective(S[0][i]);
  28084. X                perspective(S[1][i]);
  28085. X            }
  28086. X        }
  28087. X
  28088. X        /* Keep the box surrounding the fractal */
  28089. X        for (j=0;j<2;j++)
  28090. X            for (i = 0; i < 4; ++i)
  28091. X            {
  28092. X                S[j][i][0] += xxadjust;
  28093. X                S[j][i][1] += yyadjust;
  28094. X            }
  28095. X
  28096. X        draw_rect(S[0][0],S[0][1],S[0][2],S[0][3],2,1);/* Bottom */
  28097. X
  28098. X        draw_rect(S[0][0],S[1][0],S[0][1],S[1][1], 5, 0); /* Sides */
  28099. X        draw_rect(S[0][2],S[1][2],S[0][3],S[1][3], 6, 0);
  28100. X
  28101. X        draw_rect(S[1][0],S[1][1],S[1][2],S[1][3],8,1); /* Top */
  28102. X    }
  28103. X}
  28104. X
  28105. X
  28106. X
  28107. X/* This function draws a vector from origin[] to direct[] and a box
  28108. X    around it. The vector and box are transformed or not depending on
  28109. X    FILLTYPE.
  28110. X
  28111. X*/
  28112. X
  28113. Xstatic void draw_light_box (origin, direct, light_m)
  28114. Xdouble *origin, *direct;
  28115. XMATRIX light_m;
  28116. X
  28117. X
  28118. X{
  28119. X    VECTOR S[2][4];
  28120. X    int i,j;
  28121. X    double temp;
  28122. X
  28123. X    S[1][0][0] = S[0][0][0] = origin[0];
  28124. X    S[1][0][1] = S[0][0][1] = origin[1];
  28125. X
  28126. X    S[1][0][2] = direct[2];
  28127. X
  28128. X    for (i=0;i<2;i++)
  28129. X    {
  28130. X        S[i][1][0] = S[i][0][0];
  28131. X        S[i][1][1] = direct[1];
  28132. X        S[i][1][2] = S[i][0][2];
  28133. X        S[i][2][0] = direct[0];
  28134. X        S[i][2][1] = S[i][1][1];
  28135. X        S[i][2][2] = S[i][0][2];
  28136. X        S[i][3][0] = S[i][2][0];
  28137. X        S[i][3][1] = S[i][0][1];
  28138. X        S[i][3][2] = S[i][0][2];
  28139. X    }
  28140. X
  28141. X    /* transform the corners if necessary */
  28142. X    if (FILLTYPE == 6)
  28143. X        for (i=0;i<4;i++)
  28144. X        {
  28145. X            vmult (S[0][i],light_m,S[0][i]);
  28146. X            vmult (S[1][i],light_m,S[1][i]);
  28147. X        }
  28148. X
  28149. X    /* always use perspective to aid viewing */
  28150. X    temp = view[2]; /* save perspective distance for a later restore */
  28151. X    view[2] = - P * 300.0 / 100.0;
  28152. X
  28153. X    for (i=0;i<4;i++)
  28154. X    {
  28155. X        perspective(S[0][i]);
  28156. X        perspective(S[1][i]);
  28157. X    }
  28158. X    view[2] = temp; /* Restore perspective distance*/
  28159. X
  28160. X    /* Adjust for aspect */
  28161. X    for (i=0;i<4;i++)
  28162. X    {
  28163. X        S[0][i][0] = S[0][i][0] * aspect;
  28164. X        S[1][i][0] = S[1][i][0] * aspect;
  28165. X    }
  28166. X
  28167. X    /* draw box connecting transformed points. NOTE order and COLORS */
  28168. X    draw_rect(S[0][0],S[0][1],S[0][2],S[0][3],2,1);
  28169. X
  28170. X    vdraw_line (S[0][0],S[1][2],8);
  28171. X
  28172. X    /* sides */
  28173. X    draw_rect(S[0][0],S[1][0],S[0][1],S[1][1], 4, 0);
  28174. X    draw_rect(S[0][2],S[1][2],S[0][3],S[1][3], 5, 0);
  28175. X
  28176. X    draw_rect(S[1][0],S[1][1],S[1][2],S[1][3],3,1);
  28177. X
  28178. X    /* Draw the "arrow head" */
  28179. X    for (i= -3;i<4;i++)
  28180. X        for (j= -3;j<4;j++)
  28181. X            if (abs(i) + abs(j) < 6)
  28182. X                plot((int)(S[1][2][0]+i),(int)(S[1][2][1]+j),10);
  28183. X}
  28184. X
  28185. X
  28186. X
  28187. Xstatic void draw_rect (V0, V1, V2, V3, color, rect)
  28188. X
  28189. XVECTOR V0, V1, V2, V3;
  28190. Xint color, rect;
  28191. X
  28192. X{
  28193. XVECTOR V[4];
  28194. Xint i;
  28195. X
  28196. X    for (i=0;i<2;i++) 
  28197. X    { /* Since V[2] is not used by vdraw_line don't bother setting it */    
  28198. X        V[0][i] = V0[i];    
  28199. X        V[1][i] = V1[i];    
  28200. X        V[2][i] = V2[i];    
  28201. X        V[3][i] = V3[i];    
  28202. X    }    
  28203. X    if (rect) /* Draw a rectangle */
  28204. X    {
  28205. X        for (i=0;i<4;i++)
  28206. X            if (fabs(V[i][0]-V[(i+1)%4][0]) < -2*bad_check &&
  28207. X                fabs(V[i][1]-V[(i+1)%4][1]) < -2*bad_check)
  28208. X                    vdraw_line (V[i],V[(i+1)%4],color);
  28209. X    }
  28210. X    else /* Draw 2 lines instead */
  28211. X    {
  28212. X        for(i=0;i<3;i+=2)
  28213. X            if (fabs(V[i][0]-V[i+1][0]) < -2*bad_check &&
  28214. X                fabs(V[i][1]-V[i+1][1]) < -2*bad_check)
  28215. X                    vdraw_line (V[i],V[i+1],color);
  28216. X    }
  28217. X    return;
  28218. X}
  28219. X
  28220. X
  28221. X
  28222. X/* replacement for plot - builds a table of min and max x's instead of plot */
  28223. X/* called by draw_line as part of triangle fill routine */
  28224. Xstatic void _fastcall putminmax(int x,int y,int color)
  28225. X{
  28226. X    if(y >= 0 && y < ydots)
  28227. X    {
  28228. X        if(x < minmax_x[y].minx) minmax_x[y].minx = x;
  28229. X        if(x > minmax_x[y].maxx) minmax_x[y].maxx = x;
  28230. X    }
  28231. X}
  28232. X
  28233. X/*
  28234. X    This routine fills in a triangle. Extreme left and right values for
  28235. X    each row are calculated by calling the line function for the sides.
  28236. X    Then rows are filled in with horizontal lines
  28237. X*/
  28238. X#define MAXOFFSCREEN  2 /* allow two of three points to be off screen */
  28239. X
  28240. Xstatic void _fastcall putatriangle(struct point pt1,struct point pt2,
  28241. X                    struct point pt3,int color)
  28242. X{
  28243. X    extern struct point p1,p2,p3;
  28244. X    int miny,maxy;
  28245. X    int x,y,xlim;
  28246. X
  28247. X    /* Too many points off the screen? */
  28248. X    if(offscreen(pt1) + offscreen(pt2) + offscreen(pt3) > MAXOFFSCREEN)
  28249. X        return;
  28250. X
  28251. X    p1 = pt1; /* needed by interpcolor */
  28252. X    p2 = pt2;
  28253. X    p3 = pt3;
  28254. X
  28255. X    /* fast way if single point or single line */
  28256. X    if (p1.y == p2.y && p1.x == p2.x)
  28257. X    {
  28258. X        plot = fillplot;
  28259. X        if (p1.y == p3.y && p1.x == p3.x)
  28260. X            (*plot)(p1.x, p1.y, color);
  28261. X        else
  28262. X            draw_line(p1.x,p1.y,p3.x,p3.y,color);
  28263. X        plot = normalplot;
  28264. X        return;
  28265. X    }
  28266. X    else if ( (p3.y == p1.y && p3.x == p1.x) || (p3.y == p2.y && p3.x == p2.x) )
  28267. X    {
  28268. X        plot = fillplot;
  28269. X        draw_line(p1.x,p1.y,p2.x,p2.y,color);
  28270. X        plot = normalplot;
  28271. X        return;
  28272. X    }
  28273. X
  28274. X    /* find min max y */
  28275. X    miny = maxy = p1.y;
  28276. X    if(p2.y < miny) miny = p2.y;
  28277. X    else         maxy = p2.y;
  28278. X    if(p3.y < miny) miny = p3.y;
  28279. X    else if(p3.y > maxy) maxy = p3.y;
  28280. X
  28281. X    /* only worried about values on screen */
  28282. X    if(miny < 0)        miny = 0;
  28283. X    if(maxy >= ydots) maxy = ydots-1;
  28284. X
  28285. X    for(y=miny;y<=maxy;y++)
  28286. X    {
  28287. X        minmax_x[y].minx = (int)INT_MAX;
  28288. X        minmax_x[y].maxx = (int)INT_MIN;
  28289. X    }
  28290. X
  28291. X    /* set plot to "fake" plot function */
  28292. X    plot = putminmax;
  28293. X
  28294. X    /* build table of extreme x's of triangle */
  28295. X    draw_line(p1.x,p1.y,p2.x,p2.y,0);
  28296. X    draw_line(p2.x,p2.y,p3.x,p3.y,0);
  28297. X    draw_line(p3.x,p3.y,p1.x,p1.y,0);
  28298. X
  28299. X    for(y=miny;y<=maxy;y++)
  28300. X    {
  28301. X        xlim = minmax_x[y].maxx;
  28302. X        for(x=minmax_x[y].minx;x<=xlim;x++)
  28303. X        (*fillplot)(x,y,color);
  28304. X    }
  28305. X    plot = normalplot;
  28306. X}
  28307. X
  28308. X
  28309. Xstatic int _fastcall offscreen(struct point pt)
  28310. X{
  28311. X    if(pt.x >= 0)
  28312. X        if(pt.x < xdots)
  28313. X            if(pt.y >= 0)
  28314. X                if(pt.y < ydots)
  28315. X                    return(0); /* point is ok */
  28316. X    if (abs(pt.x) > 0-bad_check || abs(pt.y) > 0-bad_check)
  28317. X        return(99); /* point is bad */
  28318. X    return(1); /* point is off the screen */
  28319. X}
  28320. X
  28321. Xstatic void _fastcall clipcolor(int x,int y,int color)
  28322. X{
  28323. X    if(0 <= x    && x < xdots    &&
  28324. X        0 <= y    && y < ydots    &&
  28325. X        0 <= color && color < filecolors)
  28326. X    {
  28327. X        standardplot(x,y,color);
  28328. X
  28329. X        if (Targa_Out)
  28330. X            if (!(glassestype==1 || glassestype==2)) /* standardplot modifies color in these types */
  28331. X                targa_color(x, y, color);
  28332. X    }
  28333. X}
  28334. X
  28335. X/*********************************************************************/
  28336. X/* This function is the same as clipcolor but checks for color being */
  28337. X/* in transparent range. Intended to be called only if transparency  */
  28338. X/* has been enabled.                                                 */
  28339. X/*********************************************************************/
  28340. X
  28341. Xstatic void _fastcall T_clipcolor(int x,int y,int color)
  28342. X{
  28343. X    if (0 <= x        && x < xdots            && /*  is the point on screen?  */
  28344. X        0 <= y    && y < ydots            && /*  Yes?  */
  28345. X        0 <= color && color < colors    && /*  Colors in valid range?  */
  28346. X        /*  Lets make sure its not a transparent color  */
  28347. X        (transparent[0] > color || color > transparent[1]))
  28348. X    {
  28349. X        standardplot(x,y,color); /* I guess we can plot then  */
  28350. X
  28351. X        if (Targa_Out)
  28352. X            if (!(glassestype==1 || glassestype==2)) /* standardplot modifies color in these types */
  28353. X                targa_color(x, y, color);
  28354. X    }
  28355. X}
  28356. X
  28357. X/************************************************************************/
  28358. X/* A substitute for plotcolor that interpolates the colors according    */
  28359. X/* to the x and y values of three points (p1,p2,p3) which are static in    */
  28360. X/* this routine                                                            */
  28361. X/*                                                                        */
  28362. X/*    In Light source modes, color is light value, not actual color        */
  28363. X/*    Real_Color always contains the actual color                            */
  28364. X/************************************************************************/
  28365. X
  28366. Xstatic void _fastcall interpcolor(int x,int y,int color)
  28367. X{
  28368. X    int D,d1,d2,d3;
  28369. X
  28370. X  /* this distance formula is not the usual one - but it has the virtue
  28371. X        that it uses ONLY additions (almost) and it DOES go to zero as the
  28372. X        points get close.
  28373. X        */
  28374. X
  28375. X    d1 = abs(p1.x-x)+abs(p1.y-y);
  28376. X    d2 = abs(p2.x-x)+abs(p2.y-y);
  28377. X    d3 = abs(p3.x-x)+abs(p3.y-y);
  28378. X
  28379. X    D = (d1 + d2 + d3) << 1;
  28380. X    if(D)
  28381. X    {  /* calculate a weighted average of colors -
  28382. X        long casts prevent integer overflow. This can evaluate to zero */
  28383. X        color = ((long)(d2+d3)*(long)p1.color +
  28384. X            (long)(d1+d3)*(long)p2.color +
  28385. X            (long)(d1+d2)*(long)p3.color) / D;
  28386. X    }
  28387. X    
  28388. X    if(0 <= x        && x < xdots    &&
  28389. X        0 <= y        && y < ydots    &&
  28390. X        0 <= color && color < colors &&
  28391. X        (transparent[1] == 0 || Real_Color > transparent[1] ||
  28392. X        transparent[0] > Real_Color))
  28393. X    {
  28394. X        if (Targa_Out)
  28395. X            if (!(glassestype==1 || glassestype==2)) /* standardplot modifies color in these types */
  28396. X                D = targa_color(x, y, color);
  28397. X        if (FILLTYPE >= 5)
  28398. X            if (Real_V && Targa_Out)
  28399. X                color = D;
  28400. X            else
  28401. X                        {
  28402. X                            color =  (1 + (unsigned)color * IAmbient)/256;
  28403. X                            if (color == 0)
  28404. X                                color = 1;
  28405. X                        }
  28406. X        standardplot(x,y,color);
  28407. X    }
  28408. X}
  28409. X
  28410. X
  28411. X
  28412. X/*
  28413. X    In non light source modes, both color and Real_Color contain the
  28414. X    actual pixel color. In light source modes, color contains the
  28415. X    light value, and Real_Color contains the origninal color
  28416. X
  28417. X    This routine takes a pixel modifies it for lightshading if appropriate
  28418. X    and plots it in a Targa file. Used in plot3d.c
  28419. X*/
  28420. X
  28421. Xint _fastcall targa_color(int x,int y,int color)
  28422. X{
  28423. X    unsigned long H, S, V;
  28424. X    BYTE RGB[3];
  28425. X
  28426. X    if (FILLTYPE == 2 || glassestype==1 || glassestype==2)  
  28427. X        Real_Color = color; /* So Targa gets interpolated color */
  28428. X
  28429. X    RGB[0]  =  dacbox [Real_Color] [0] << 2; /* Move color space to */
  28430. X    RGB[1]  =  dacbox [Real_Color] [1] << 2; /* 256 color primaries */
  28431. X    RGB[2]  =  dacbox [Real_Color] [2] << 2; /* from 64 colors */
  28432. X
  28433. X    /* Now lets convert it to HSV */
  28434. X    R_H(RGB[0], RGB[1], RGB[2], &H, &S, &V);
  28435. X
  28436. X    /* Modify original S and V components */
  28437. X    if (FILLTYPE > 4 && !(glassestype==1 || glassestype==2)) /* Adjust for Ambient */
  28438. X        V = (V * (65535 - (unsigned)(color * IAmbient))) / 65535;
  28439. X
  28440. X    if (haze)
  28441. X    {
  28442. X        S = (unsigned long)(S * HAZE_MULT) / 100; /* Haze lowers sat of colors */
  28443. X        if (V >= 32640) /* Haze reduces contrast */
  28444. X        {
  28445. X            V = V - 32640;
  28446. X            V = (unsigned long)((V * HAZE_MULT) / 100);
  28447. X            V = V + 32640;
  28448. X        }
  28449. X        else
  28450. X        {
  28451. X            V = 32640 - V;
  28452. X            V = (unsigned long)((V * HAZE_MULT) / 100);
  28453. X            V = 32640 - V;
  28454. X        }
  28455. X    }
  28456. X    /* Now lets convert it back to RGB. Original Hue, modified Sat and Val */
  28457. X    H_R(&RGB[0], &RGB[1], &RGB[2], H, S, V);
  28458. X
  28459. X    if (Real_V)
  28460. X        V = (35 * (int)RGB[0] + 45 * (int)RGB[1] + 20 * (int)RGB[2]) / 100;
  28461. X
  28462. X    /* Now write the color triple to its transformed location */
  28463. X    /* on the disk. */
  28464. X    targa_writedisk (x+sxoffs, y+syoffs, RGB[0], RGB[1], RGB[2]);
  28465. X
  28466. X    return(255-V);
  28467. X}
  28468. X
  28469. X
  28470. X
  28471. Xstatic int set_pixel_buff(BYTE *pixels,BYTE far *fraction,unsigned linelen)
  28472. X{
  28473. X    int i;
  28474. X    if ((evenoddrow++ & 1) == 0) /* even rows are color value */
  28475. X    {
  28476. X        for(i=0;i<linelen;i++) /* add the fractional part in odd row */
  28477. X            fraction[i] = pixels[i];
  28478. X        return(1);
  28479. X    }
  28480. X    else /* swap */
  28481. X    {
  28482. X        BYTE tmp;
  28483. X        for(i=0;i<linelen;i++) /* swap so pixel has color */
  28484. X        {
  28485. X            tmp = pixels[i];
  28486. X            pixels[i]=fraction[i];
  28487. X            fraction[i]=tmp;
  28488. X        }
  28489. X    }
  28490. X    return(0);
  28491. X}
  28492. X
  28493. X
  28494. X/* cross product  - useful because cross is perpendicular to v and w */
  28495. X/**** PB commented this out - it is unused
  28496. Xstatic int chk_cross_product (int col, int row,VECTOR v, VECTOR w, VECTOR cross, VECTOR crossavg)
  28497. X{
  28498. X    static start = 1;
  28499. X    static FILE *fp;
  28500. X
  28501. X    if(start)
  28502. X    {
  28503. X        fp = fopen("blob","w");
  28504. X        start = 0;
  28505. X    }
  28506. X
  28507. X    fprintf(fp,"row %+4d col %+4d v1 %+8.3e %+8.3e %+8.3e v2 %+8.3e %+8.3e %+8.3e cross %+8.3e %+8.3e %+8.3e crossavg %+8.3e %+8.3e %+8.3e \n",
  28508. X    row,col,v[0],v[1],v[2],w[0],w[1],w[2],cross[0],cross[1],cross[2],crossavg[0],crossavg[1],crossavg[2]);
  28509. X    return(0);
  28510. X}
  28511. X***/
  28512. X
  28513. X/**************************************************************************
  28514. X
  28515. X        Common routine for printing error messages to the screen for Targa
  28516. X        and other files
  28517. X
  28518. X**************************************************************************/
  28519. X
  28520. X
  28521. X#ifndef XFRACT
  28522. Xstatic char f[]                 = "%Fs%Fs";
  28523. Xstatic char fff[]               = "%Fs%Fs%Fs";
  28524. X#else
  28525. Xstatic char f[]                 = "%s%s";
  28526. Xstatic char fff[]               = "%s%s%s";
  28527. X#endif
  28528. Xstatic char far OOPS[]  = {"OOPS, "};
  28529. Xstatic char far E1[]        = {"can't handle this type of file.\n"};
  28530. Xstatic char far str1[]  = {"couldn't open  < "};
  28531. Xstatic char far str3[]  = {"image wrong size\n"};
  28532. Xstatic char far temp1[] = {"ran out of disk space. < "};
  28533. X
  28534. Xstatic void File_Error (char *File_Name1, int ERROR)
  28535. X{
  28536. X   char msgbuf[200];
  28537. X
  28538. X    error = ERROR;
  28539. X    switch(ERROR)
  28540. X    {
  28541. X    case 1: /* Can't Open */
  28542. X#ifndef XFRACT
  28543. X                sprintf(msgbuf,"%Fs%Fs%s >", OOPS, str1, File_Name1);
  28544. X#else
  28545. X                sprintf(msgbuf,"%s%s%s >", OOPS, str1, File_Name1);
  28546. X#endif
  28547. X        break;
  28548. X    case 2: /* Not enough room */
  28549. X#ifndef XFRACT
  28550. X        sprintf(msgbuf,"%Fs%Fs%s >", OOPS, temp1, File_Name1);
  28551. X#else
  28552. X                sprintf(msgbuf,"%s%s%s >", OOPS, temp1, File_Name1);
  28553. X#endif
  28554. X        break;
  28555. X    case 3: /* Image wrong size */
  28556. X        sprintf(msgbuf, f, OOPS, str3);
  28557. X        break;
  28558. X    case 4: /* Wrong file type */
  28559. X        sprintf(msgbuf, f, OOPS, E1);
  28560. X        break;
  28561. X    }
  28562. X    stopmsg(0,msgbuf);
  28563. X    return;
  28564. X}
  28565. X
  28566. X
  28567. X/************************************************************************/
  28568. X/*                                                                        */
  28569. X/*        This function opens a TARGA_24 file for reading and writing. If    */
  28570. X/*        its a new file, (overlay == 0) it writes a header. If it is to    */
  28571. X/*        overlay an existing file (overlay == 1) it copies the original    */
  28572. X/*        header whose lenght and validity was determined in                */
  28573. X/*        Targa_validate.                                                    */
  28574. X/*                                                                        */
  28575. X/*        It Verifies there is enough disk space, and leaves the file     */
  28576. X/*        at the start of the display data area.                            */
  28577. X/*                                                                        */
  28578. X/*        If this is an overlay, closes source and copies to "targa_temp"    */
  28579. X/*        If there is an error close the file.                             */
  28580. X/*                                                                        */
  28581. X/* **********************************************************************/
  28582. X
  28583. X
  28584. Xstatic int startdisk1 (char *File_Name2, FILE *Source, int overlay)
  28585. X{
  28586. X    int i,j,k, inc;
  28587. X    FILE *fps;
  28588. X
  28589. X    /* Open File for both reading and writing */
  28590. X    if ((fps=fopen(File_Name2,"w+b"))==NULL)
  28591. X    {
  28592. X        File_Error(File_Name2, 1);
  28593. X        return(-1); /* Oops, somethings wrong! */
  28594. X    }
  28595. X
  28596. X    inc = 1; /* Assume we are overlaying a file */
  28597. X
  28598. X    /* Write the header */
  28599. X    if (overlay) /* We are overlaying a file */
  28600. X        for (i=0;i<T_header_24;i++) /* Copy the header from the Source */
  28601. X            fputc(fgetc(Source),fps);
  28602. X    else
  28603. X    {    /* Write header for a new file */
  28604. X        /* ID field size = 0, No color map, Targa type 2 file */
  28605. X        for (i=0;i<12;i++)
  28606. X        {
  28607. X            if (i == 2)
  28608. X                fputc(i,fps);
  28609. X            else
  28610. X                fputc(0,fps);
  28611. X        }
  28612. X        /*  Write image size  */
  28613. X        for (i=0;i<4;i++)
  28614. X            fputc(upr_lwr[i],fps);
  28615. X        fputc(T24,fps); /* Targa 24 file */
  28616. X        fputc(T32,fps); /* Image at upper left */
  28617. X        inc = 3;
  28618. X    }
  28619. X
  28620. X    /*  Finished with the header, now lets work on the display area  */
  28621. X    for (i=0;i<ydots;i++)    /* "clear the screen" (write to the disk) */
  28622. X    {
  28623. X        for (j=0;j<line_length1;j=j+inc)
  28624. X        {
  28625. X            if (overlay)
  28626. X                fputc(fgetc(Source), fps);
  28627. X            else
  28628. X                for (k=2;k>-1;k--)
  28629. X                    fputc(back_color[k], fps);            /* Targa order (B, G, R) */
  28630. X        }
  28631. X        if (ferror (fps))        
  28632. X        {        
  28633. X            /*  Almost certainly not enough disk space  */        
  28634. X            fclose (fps);
  28635. X            fclose (Source);
  28636. X            remove (File_Name2);        
  28637. X            File_Error(File_Name2, 2);        
  28638. X            return(-2);        
  28639. X        }
  28640. X        if (check_key())        return(-3);
  28641. X    }
  28642. X
  28643. X    if (targa_startdisk(fps, T_header_24) != 0)
  28644. X    {
  28645. X        enddisk();
  28646. X        remove (File_Name2);
  28647. X        return(-4);
  28648. X    }
  28649. X    return(0);
  28650. X}
  28651. X
  28652. X/**************************************************************************
  28653. X
  28654. X
  28655. X**************************************************************************/
  28656. X
  28657. Xint targa_validate(char *File_Name)
  28658. X{
  28659. X    FILE *fp;
  28660. X    int i, j = 0;
  28661. X
  28662. X    /* Attempt to open source file for reading */
  28663. X    if ((fp=fopen(File_Name,"rb"))==NULL)
  28664. X    {
  28665. X        File_Error(File_Name, 1);
  28666. X        return(-1); /* Oops, file does not exist */
  28667. X    }
  28668. X
  28669. X    T_header_24 += fgetc(fp); /* Check ID field and adjust header size */
  28670. X
  28671. X    if (fgetc(fp)) /* Make sure this is an unmapped file */
  28672. X    {
  28673. X        File_Error(File_Name, 4);
  28674. X        return(-1);
  28675. X    }
  28676. X
  28677. X    if (fgetc(fp)!=2) /* Make sure it is a type 2 file */
  28678. X    {
  28679. X        File_Error(File_Name, 4);
  28680. X        return(-1);
  28681. X    }
  28682. X
  28683. X    /* Skip color map specification */
  28684. X    for (i=0;i<5;i++)
  28685. X            fgetc(fp);
  28686. X
  28687. X    for (i=0;i<4;i++)
  28688. X    {
  28689. X        /* Check image origin */
  28690. X        fgetc(fp);
  28691. X        if(j != 0)
  28692. X        {
  28693. X            File_Error(File_Name, 4);
  28694. X            return(-1);
  28695. X        }
  28696. X    }
  28697. X    /* Check Image specs */
  28698. X    for (i=0;i<4;i++)
  28699. X        if(fgetc(fp) != upr_lwr[i])
  28700. X        {
  28701. X            File_Error(File_Name,3);
  28702. X            return(-1);
  28703. X        }
  28704. X
  28705. X    if(fgetc(fp) != T24) error=4; /* Is it a targa 24 file? */
  28706. X    if(fgetc(fp) != T32) error=4; /* Is the origin at the upper left? */
  28707. X    if (error == 4)
  28708. X    {
  28709. X        File_Error(File_Name,4);
  28710. X        return(-1);
  28711. X    }
  28712. X    rewind(fp);
  28713. X
  28714. X    /* Now that we know its a good file, create a working copy */
  28715. X    if (startdisk1(targa_temp, fp, 1))
  28716. X        return(-1);
  28717. X    
  28718. X    fclose(fp);    /* Close the source */
  28719. X
  28720. X    T_Safe=1; /* Original file successfully copied to targa_temp */
  28721. X    return(0);
  28722. X}
  28723. X
  28724. Xstatic int R_H (R, G, B, H, S, V)
  28725. XBYTE R,G,B;
  28726. Xunsigned long *H, *S, *V;
  28727. X{
  28728. X    unsigned long    R1, G1, B1, DENOM;
  28729. X    BYTE MIN;
  28730. X
  28731. X    *V = R;
  28732. X    MIN = G;
  28733. X    if (R < G)
  28734. X    {
  28735. X        *V = G;
  28736. X        MIN = R;
  28737. X        if (G < B)            *V = B;
  28738. X        if (B < R)            MIN = B;
  28739. X    }
  28740. X    else
  28741. X    {
  28742. X        if (B < G)            MIN = B;
  28743. X        if (R < B)            *V = B;
  28744. X    }
  28745. X    DENOM = *V - MIN;
  28746. X    if (*V != 0 && DENOM !=0)
  28747. X    {
  28748. X        *S = ((DENOM << 16) / *V) - 1;
  28749. X    }
  28750. X    else  *S = 0;/* Color is black! and Sat has no meaning */
  28751. X    if(*S == 0) /*  R=G=B => shade of grey and Hue has no meaning */
  28752. X    {
  28753. X        *H = 0;
  28754. X        *V = *V << 8;
  28755. X        return(1);  /* v or s or both are 0 */
  28756. X    }
  28757. X    if (*V == MIN)
  28758. X    {
  28759. X        *H = 0;
  28760. X        *V = *V << 8;
  28761. X        return(0);
  28762. X    }
  28763. X    R1 = (((*V - R) * 60) << 6) / DENOM;        /* distance of color from red    */
  28764. X    G1 = (((*V - G) * 60) << 6) / DENOM;        /* distance of color from green */
  28765. X    B1 = (((*V - B) * 60) << 6) / DENOM;        /* distance of color from blue  */
  28766. X    if(*V == R)
  28767. X        if (MIN == G)        *H = (300 << 6) + B1;
  28768. X        else            *H = (60 << 6) - G1;
  28769. X    if(*V == G)
  28770. X        if (MIN == B)        *H = (60 << 6) + R1;
  28771. X        else            *H = (180 << 6) - B1;
  28772. X    if(*V == B)
  28773. X        if(MIN == R)        *H = (180 << 6) + G1;
  28774. X        else            *H = (300 << 6) - R1;
  28775. X
  28776. X    *V = *V << 8;
  28777. X    return(0);
  28778. X}
  28779. X
  28780. Xstatic int H_R (R, G, B, H, S, V)
  28781. XBYTE *R, *G, *B;
  28782. Xunsigned long  H, S, V;
  28783. X{
  28784. X    unsigned long        P1, P2, P3;
  28785. X    int    RMD, I;
  28786. X
  28787. X    if(H >= 23040)            H = H % 23040; /*  Makes h circular  */
  28788. X    I = H / 3840;
  28789. X    RMD = H % 3840;            /*  RMD = fractional part of H    */
  28790. X
  28791. X    P1 = ((V * (65535 - S)) / 65280) >> 8;
  28792. X    P2 = (((V * (65535 - (S * RMD) / 3840)) / 65280) - 1) >> 8;
  28793. X    P3 = (((V * (65535 - (S * (3840 - RMD)) / 3840)) / 65280)) >> 8;
  28794. X    V = V >> 8;
  28795. X    switch (I)
  28796. X    {
  28797. X    case 0:
  28798. X        *R = V;
  28799. X        *G = P3;
  28800. X        *B = P1;
  28801. X        break;
  28802. X    case 1:
  28803. X        *R = P2;
  28804. X        *G = V;
  28805. X        *B = P1;
  28806. X        break;
  28807. X    case 2:
  28808. X        *R = P1;
  28809. X        *G = V;
  28810. X        *B = P3;
  28811. X        break;
  28812. X    case 3:
  28813. X        *R = P1;
  28814. X        *G = P2;
  28815. X        *B = V;
  28816. X        break;
  28817. X    case 4:
  28818. X        *R = P3;
  28819. X        *G = P1;
  28820. X        *B = V;
  28821. X        break;
  28822. X    case 5:
  28823. X        *R = V ;
  28824. X        *G = P1;
  28825. X        *B = P2;
  28826. X        break;
  28827. X    }
  28828. X    return(0);
  28829. X}
  28830. X
  28831. X
  28832. X/***************************************************************************/
  28833. X/*                                        */
  28834. X/* EB & DG fiddled with outputs for Rayshade so they work. with v4.x.      */
  28835. X/* EB == eli brandt.     ebrandt@jarthur.claremont.edu                                          */
  28836. X/* DG == dan goldwater.  daniel_goldwater@brown.edu & dgold@math.umass.edu */
  28837. X/*    (NOTE: all the stuff we fiddled with is commented with "EB & DG" (plus even some extra bonus comments!) */
  28838. X/* general raytracing code info/notes:                         */
  28839. X/*                                            */
  28840. X/*  ray == 0 means no raytracer output    ray == 7 is for dxf                    */
  28841. X/*  ray == 1 is for dkb/pov        ray == 4 is for mtv            */
  28842. X/*  ray == 2 is for vivid        ray == 5 is for rayshade        */
  28843. X/*  ray == 3 is for raw            ray == 6 is for acrospin        */
  28844. X/*                                          */
  28845. X/*  rayshade needs counterclockwise triangles.  raytracers that support     */
  28846. X/*  the 'heightfield' primitive include rayshade and pov.  anyone want to write */
  28847. X/*  code to make heightfields?  they are *MUCH* faster to trace than triangles  */
  28848. X/*  when doing landscapes...                            */
  28849. X/*  */
  28850. X/*  stuff EB & DG changed:  */
  28851. X/*  made the rayshade output create a "grid" aggregate object (one of rayshade's primitives), instead */
  28852. X/*  of a global grid.  as a result, the grid can be optimized based on the number of triangles.  */
  28853. X/*  the z component of the grid can always be 1 since the surface formed by the triangles is flat */
  28854. X/*  (ie, it doesnt curve over itself).  this is a major optimization.  the x and y grid size is */
  28855. X/*  also optimized for a 4:3 aspect ratio image, to get the fewest possible traingles in each grid square. */
  28856. X/*  also, we fixed the rayshade code so it actually produces output that works with rayshade. */
  28857. X/*  (maybe the old code was for a really old version of rayshade?).  */
  28858. X/*  */
  28859. X/*  */
  28860. X/***************************************************************************/
  28861. X
  28862. X/********************************************************************/
  28863. X/*                                                                    */
  28864. X/*  This routine writes a header to a ray tracer data file. It        */
  28865. X/*  Identifies the version of FRACTINT which created it an the        */
  28866. X/*  key 3D parameters in effect at the time.                        */
  28867. X/*                                                                    */
  28868. X/********************************************************************/
  28869. X
  28870. X
  28871. Xstatic char far declare[] = {"DECLARE    "};
  28872. Xstatic char far frac_default[] = {"F_Dflt"};
  28873. Xstatic char far color[] = {"COLOR  "};
  28874. Xstatic char far dflt[] = {"RED 0.8 GREEN 0.4 BLUE 0.1\n"};
  28875. Xstatic char far d_color[] = {"0.8 0.4 0.1"};
  28876. Xstatic char far r_surf[] = {"0.95 0.05 5 0 0\n"};
  28877. Xstatic char far surf[] = {"surf={diff="};
  28878. Xstatic char far rs_surf[] = {"applysurf diffuse "};   /* EB & DG: changed "surface T" to "applysurf" and "diff" to "diffuse" */
  28879. Xstatic char far end[] = {"END_"};
  28880. Xstatic char far plane[] = {"PLANE"};
  28881. Xstatic char far m1[] = {"-1.0 "};
  28882. Xstatic char far one[] = {" 1.0 "};
  28883. Xstatic char far z[]  = {" 0.0 "};
  28884. Xstatic char far bnd_by[]  = {" BOUNDED_BY\n"};
  28885. Xstatic char far end_bnd[]  = {" END_BOUND\n"};
  28886. Xstatic char far inter[]  = {"INTERSECTION\n"};
  28887. X#ifndef XFRACT
  28888. Xstatic char fmt[] = "   %Fs <%Fs%Fs%Fs> % #4.3f %Fs%Fs\n";
  28889. X#else
  28890. Xstatic char fmt[] = "   %s <%s%s%s> % #4.3f %s%s\n";
  28891. X#endif
  28892. Xstatic char dxf_begin[] = {"  0\nSECTION\n  2\nTABLES\n  0\nTABLE\n  2\nLAYER\n\
  28893. X 70\n     2\n  0\nLAYER\n  2\n0\n 70\n     0\n 62\n     7\n  6\nCONTINUOUS\n\
  28894. X  0\nLAYER\n  2\nFRACTAL\n 70\n    64\n 62\n     1\n  6\nCONTINUOUS\n  0\n\
  28895. XENDTAB\n  0\nENDSEC\n  0\nSECTION\n  2\nENTITIES\n"};
  28896. Xstatic char dxf_3dface[] = {"  0\n3DFACE\n  8\nFRACTAL\n 62\n%3d\n"};
  28897. Xstatic char dxf_vertex[] = {"%3d\n%g\n"};
  28898. Xstatic char dxf_end[] = {"  0\nENDSEC\n  0\nEOF\n"};
  28899. X
  28900. Xstatic char far composite[] = {"COMPOSITE"};
  28901. Xstatic char far object[]  = {"OBJECT"};
  28902. Xstatic char far triangle[] = {"TRIANGLE "};
  28903. Xstatic char far l_tri[] = {"triangle"};
  28904. Xstatic char far texture[] = {"TEXTURE\n"};
  28905. X/* static char far end_texture[] = {" END_TEXTURE\n"}; */
  28906. Xstatic char far red[] = {"RED"};
  28907. Xstatic char far green[] = {"GREEN"};
  28908. Xstatic char far blue[] = {"BLUE"};
  28909. X
  28910. Xstatic char far frac_texture[] = {"    AMBIENT 0.25 DIFFUSE 0.75"};
  28911. X
  28912. Xstatic char far polygon[] = {"polygon={points=3;"};
  28913. Xstatic char far vertex[] = {" vertex =  "};
  28914. Xstatic char far d_vert[] = {"    <"};
  28915. Xstatic char f1[] = "% #4.4f ";
  28916. X/* EB & DG: changed this to much better values. now it actually makes a good trace */
  28917. Xstatic char far grid[] = {"screen 640 480\neyep 0 2.1 0.8\nlookp 0 0 -0.95\nlight 1 point -2 1 1.5\n"};
  28918. Xstatic char far grid2[] = {"background .3 0 0\nreport verbose\n"};
  28919. X
  28920. Xstatic char n[] = "\n";
  28921. Xstatic char f2[] = "R%dC%d R%dC%d\n";
  28922. Xstatic char far ray_comment1[] = {"/* make a gridded aggregate. this size grid is fast for landscapes. */\n"};
  28923. Xstatic char far ray_comment2[] = {"/* make z grid = 1 always for landscapes. */\n\n"};
  28924. Xstatic char far grid3[] = {"grid 33 25 1\n"};
  28925. X
  28926. Xstatic int _fastcall RAY_Header(void)
  28927. X
  28928. X
  28929. X{  /* Open the ray tracing output file */
  28930. X    check_writefile(ray_name,".ray");
  28931. X    if ((File_Ptr1=fopen(ray_name,"w"))==NULL)
  28932. X        return(-1); /* Oops, somethings wrong! */
  28933. X
  28934. X    if (RAY == 2)
  28935. X        fprintf(File_Ptr1, "//");
  28936. X    if (RAY == 4)
  28937. X        fprintf(File_Ptr1, "#");
  28938. X    if (RAY == 5)
  28939. X        fprintf(File_Ptr1, "/*\n");
  28940. X    if (RAY == 6)
  28941. X        fprintf(File_Ptr1, "--");
  28942. X      if (RAY == 7)
  28943. X          fprintf(File_Ptr1, dxf_begin);
  28944. X  
  28945. X      if (RAY != 7)
  28946. X         fprintf(File_Ptr1, banner, s3, release/100., s3a);
  28947. X
  28948. X    if (RAY == 5)
  28949. X        fprintf(File_Ptr1, "*/\n");
  28950. X
  28951. X
  28952. X    /* Set the default color */
  28953. X    if (RAY == 1)
  28954. X    {
  28955. X        fprintf (File_Ptr1, f, declare, frac_default);
  28956. X        fprintf (File_Ptr1, " = ");
  28957. X        fprintf (File_Ptr1, f, color, dflt);
  28958. X    }
  28959. X    if (BRIEF)
  28960. X    {
  28961. X        if (RAY == 2)
  28962. X        {
  28963. X            fprintf (File_Ptr1, f, surf, d_color);
  28964. X            fprintf (File_Ptr1, ";}\n");
  28965. X        }
  28966. X        if (RAY == 4)
  28967. X        {
  28968. X            fprintf (File_Ptr1, "f ");
  28969. X            fprintf (File_Ptr1, f, d_color, r_surf);
  28970. X        }
  28971. X        if (RAY == 5)
  28972. X            fprintf (File_Ptr1, f, rs_surf, d_color);
  28973. X    }
  28974. X      if (RAY != 7)
  28975. X        fprintf (File_Ptr1, n);
  28976. X
  28977. X    if (RAY == 5)             /* EB & DG: open "grid" opject, a speedy way to do aggregates in rayshade */
  28978. X        fprintf (File_Ptr1, fff, ray_comment1,ray_comment2,grid3);
  28979. X
  28980. X    if (RAY == 6)
  28981. X#ifndef XFRACT
  28982. X                fprintf (File_Ptr1, "%Fs", acro_s1);
  28983. X#else
  28984. X        fprintf (File_Ptr1, "%s", acro_s1);
  28985. X#endif
  28986. X
  28987. X    return(0);
  28988. X}
  28989. X
  28990. X
  28991. X/********************************************************************/
  28992. X/*                                                                    */
  28993. X/*  This routine describes the triangle to the ray tracer, it        */
  28994. X/*  sets the color of the triangle to the average of the color        */
  28995. X/*  of its verticies and sets the light parameters to arbitrary        */
  28996. X/*  values.                                                            */
  28997. X/*                                                                    */
  28998. X/*  Note: numcolors (number of colors in the source                    */
  28999. X/*  file) is used instead of colors (number of colors avail. with    */
  29000. X/*  display) so you can generate ray trace files with your LCD        */
  29001. X/*  or monochrome display                                            */
  29002. X/*                                                                    */
  29003. X/********************************************************************/
  29004. X
  29005. Xstatic int _fastcall out_triangle(struct f_point pt1, struct f_point pt2,
  29006. X            struct f_point pt3, int c1, int c2, int c3)
  29007. X
  29008. X{
  29009. Xint i, j;
  29010. Xfloat c[3];
  29011. Xfloat pt_t[3][3];
  29012. X
  29013. X    /* Normalize each vertex to screen size and adjust coordinate system */
  29014. X    pt_t[0][0]            =    2 * pt1.x            / xdots  - 1;
  29015. X    pt_t[0][1]            =  (2 * pt1.y            / ydots  - 1);
  29016. X    pt_t[0][2]            =  -2 * pt1.color / numcolors - 1;
  29017. X    pt_t[1][0]            =    2 * pt2.x            / xdots  - 1;
  29018. X    pt_t[1][1]            =  (2 * pt2.y            / ydots  - 1);
  29019. X    pt_t[1][2]            =  -2 * pt2.color / numcolors - 1;
  29020. X    pt_t[2][0]            =    2 * pt3.x            / xdots  - 1;
  29021. X    pt_t[2][1]            =  (2 * pt3.y            / ydots  - 1);
  29022. X    pt_t[2][2]            =  -2 * pt3.color / numcolors - 1;
  29023. X
  29024. X    /* Color of triangle is average of colors of its verticies */
  29025. X    if (!BRIEF)
  29026. X        for (i=0;i<=2;i++)
  29027. X        c[i] = (float)(dacbox[c1][i] + dacbox[c2][i] + dacbox[c3][i])
  29028. X                / (3 * 63);
  29029. X
  29030. X        /* get rid of degenerate triangles: any two points equal */
  29031. X        if (pt_t[0][0] == pt_t[1][0] &&
  29032. X                pt_t[0][1] == pt_t[1][1] &&
  29033. X                pt_t[0][2] == pt_t[1][2] ||
  29034. X
  29035. X                pt_t[0][0] == pt_t[2][0] &&
  29036. X                pt_t[0][1] == pt_t[2][1] &&
  29037. X                pt_t[0][2] == pt_t[2][2] ||
  29038. X
  29039. X                pt_t[2][0] == pt_t[1][0] &&
  29040. X                pt_t[2][1] == pt_t[1][1] &&
  29041. X                pt_t[2][2] == pt_t[1][2])
  29042. X            return(0);
  29043. X
  29044. X    /* Describe the triangle */
  29045. X#ifndef XFRACT
  29046. X    if (RAY == 1)
  29047. X        fprintf (File_Ptr1, " %Fs\n  %Fs", object, triangle);
  29048. X        if (RAY == 2 && !BRIEF)
  29049. X        fprintf (File_Ptr1, "%Fs", surf);
  29050. X#else
  29051. X    if (RAY == 1)
  29052. X        fprintf (File_Ptr1, " %s\n  %s", object, triangle);
  29053. X        if (RAY == 2 && !BRIEF)
  29054. X        fprintf (File_Ptr1, "%s", surf);
  29055. X#endif
  29056. X    if (RAY == 4 && !BRIEF)
  29057. X        fprintf (File_Ptr1, "f");
  29058. X    if (RAY == 5 && !BRIEF)
  29059. X#ifndef XFRACT
  29060. X        fprintf (File_Ptr1, "%Fs", rs_surf);
  29061. X#else
  29062. X        fprintf (File_Ptr1, "%s", rs_surf);
  29063. X#endif
  29064. X
  29065. X    if (!BRIEF && RAY != 1 && RAY != 7)
  29066. X        for (i=0;i<=2;i++)
  29067. X        fprintf (File_Ptr1, f1, c[i]);
  29068. X
  29069. X    if (RAY == 2)
  29070. X    {
  29071. X        if (!BRIEF)
  29072. X        fprintf (File_Ptr1, ";}\n");
  29073. X#ifndef XFRACT
  29074. X        fprintf (File_Ptr1, "%Fs", polygon);
  29075. X#else
  29076. X        fprintf (File_Ptr1, "%s", polygon);
  29077. X#endif
  29078. X    }
  29079. X    if (RAY == 4)
  29080. X    {
  29081. X        if (!BRIEF)
  29082. X#ifndef XFRACT
  29083. X            fprintf (File_Ptr1, "%Fs", r_surf);
  29084. X#else
  29085. X            fprintf (File_Ptr1, "%s", r_surf);
  29086. X#endif
  29087. X        fprintf (File_Ptr1, "p 3");
  29088. X    }
  29089. X    if (RAY == 5)
  29090. X    {
  29091. X        if (!BRIEF)
  29092. X            fprintf (File_Ptr1, n);
  29093. X#ifndef XFRACT
  29094. X        fprintf (File_Ptr1, "%Fs", l_tri);   /* EB & DG: removed "T" after "triangle" */
  29095. X#else
  29096. X        fprintf (File_Ptr1, "%s", l_tri);    /* EB & DG: removed "T" after "triangle" */
  29097. X#endif
  29098. X    }
  29099. X
  29100. X      if (RAY == 7)
  29101. X          fprintf (File_Ptr1, dxf_3dface, min(255, max(1, c1)));
  29102. X
  29103. X    for(i=0;i<=2;i++)  /*  Describe each  Vertex  */
  29104. X    {
  29105. X          if (RAY != 7)
  29106. X        fprintf (File_Ptr1, n);
  29107. X
  29108. X#ifndef XFRACT
  29109. X        if (RAY == 1)
  29110. X            fprintf (File_Ptr1, "%Fs", d_vert);
  29111. X        if (RAY == 2)
  29112. X            fprintf (File_Ptr1, "%Fs", vertex);
  29113. X#else
  29114. X        if (RAY == 1)
  29115. X            fprintf (File_Ptr1, "%s", d_vert);
  29116. X        if (RAY == 2)
  29117. X            fprintf (File_Ptr1, "%s", vertex);
  29118. X#endif
  29119. X        if (RAY > 3 && RAY != 7)
  29120. X            fprintf (File_Ptr1, " ");
  29121. X
  29122. X        for(j=0;j<=2;j++)
  29123. X               {
  29124. X              if (RAY == 7)
  29125. X                  {
  29126. X                  /* write 3dface entity to dxf file */
  29127. X                  fprintf (File_Ptr1, dxf_vertex, 10*(j+1)+i, pt_t[i][j]);
  29128. X                  if (i == 2)                /* 3dface needs 4 vertecies */
  29129. X                      fprintf (File_Ptr1, dxf_vertex, 10*(j+1)+i+1, pt_t[i][j]);
  29130. X                  }
  29131. X              else if (!(RAY == 4 || RAY == 5))
  29132. X                  fprintf (File_Ptr1, f1, pt_t[i][j]); /* Right handed */
  29133. X              else
  29134. X                  fprintf (File_Ptr1, f1, pt_t[2-i][j]); /* Left handed */
  29135. X              }
  29136. X
  29137. X        if (RAY == 1)
  29138. X        fprintf (File_Ptr1, ">");
  29139. X        if (RAY == 2)
  29140. X        fprintf (File_Ptr1, ";");
  29141. X    }
  29142. X
  29143. X    if (RAY == 1)
  29144. X    {
  29145. X#ifndef XFRACT
  29146. X        fprintf (File_Ptr1, " %Fs%Fs\n", end, triangle);
  29147. X#else
  29148. X        fprintf (File_Ptr1, " %s%s\n", end, triangle);
  29149. X#endif
  29150. X        if (!BRIEF)
  29151. X        {
  29152. X#ifndef XFRACT
  29153. X        fprintf (File_Ptr1, "  %Fs"
  29154. X            "    %Fs%Fs% #4.4f %Fs% #4.4f %Fs% #4.4f\n"
  29155. X            "%Fs"
  29156. X            " %Fs%Fs",
  29157. X#else
  29158. X        fprintf (File_Ptr1,
  29159. X            "  %s   %s%s% #4.4f %s% #4.4f %s% #4.4f\n%s %s%s",
  29160. X#endif
  29161. X            texture,
  29162. X            color, red, c[0], green, c[1], blue, c[2],
  29163. X            frac_texture,
  29164. X            end, texture);
  29165. X        }
  29166. X#ifndef XFRACT
  29167. X        fprintf (File_Ptr1, "  %Fs%Fs  %Fs%Fs",
  29168. X#else
  29169. X        fprintf (File_Ptr1, "  %s%s  %s%s",
  29170. X#endif
  29171. X        color, frac_default,
  29172. X        end, object);
  29173. X        triangle_bounds(pt_t); /* update bounding info */
  29174. X    }
  29175. X    if (RAY == 2)
  29176. X        fprintf (File_Ptr1, "}");
  29177. X    if (RAY == 3 && !BRIEF)
  29178. X        fprintf (File_Ptr1, n);
  29179. X
  29180. X      if (RAY != 7)
  29181. X        fprintf (File_Ptr1, n);
  29182. X
  29183. X    return(0);
  29184. X}
  29185. X
  29186. X
  29187. X/********************************************************************/
  29188. X/*                                                                    */
  29189. X/*  This routine calculates the min and max values of a triangle    */
  29190. X/*  for use in creating ray tracer data files. The values of min    */
  29191. X/*  and max x, y, and z are assumed to be global.                    */
  29192. X/*                                                                    */
  29193. X/********************************************************************/
  29194. X
  29195. Xstatic void _fastcall triangle_bounds(float pt_t[3][3])
  29196. X
  29197. X{
  29198. Xint i,j;
  29199. X
  29200. X    for (i=0;i<=2;i++)
  29201. X    for (j=0;j<=2;j++)
  29202. X    {
  29203. X        if(pt_t[i][j] < min_xyz[j]) min_xyz[j] = pt_t[i][j];
  29204. X        if(pt_t[i][j] > max_xyz[j]) max_xyz[j] = pt_t[i][j];
  29205. X    }
  29206. X    return;
  29207. X}
  29208. X
  29209. X/********************************************************************/
  29210. X/*                                                                    */
  29211. X/*  This routine starts a composite object for ray trace data files.*/
  29212. X/*                                                                    */
  29213. X/********************************************************************/
  29214. X
  29215. Xstatic int _fastcall start_object(void)
  29216. X
  29217. X{
  29218. X    if (RAY != 1)            return(0);
  29219. X
  29220. X    /*    Reset the min/max values, for bounding box  */
  29221. X    min_xyz[0] = min_xyz[1] = min_xyz[2] =  999999;
  29222. X    max_xyz[0] = max_xyz[1] = max_xyz[2] = -999999;
  29223. X
  29224. X#ifndef XFRACT
  29225. X    fprintf (File_Ptr1, "%Fs\n", composite);
  29226. X#else
  29227. X    fprintf (File_Ptr1, "%s\n", composite);
  29228. X#endif
  29229. X    return(0);
  29230. X}
  29231. X
  29232. X/********************************************************************/
  29233. X/*                                                                    */
  29234. X/*  This routine adds a bounding box for the triangles drawn        */
  29235. X/*  in the last block and completes the composite object created.    */
  29236. X/*  It uses the globals min and max x,y and z calculated in            */
  29237. X/*  z calculated in Triangle_Bounds().                                */
  29238. X/*                                                                    */
  29239. X/********************************************************************/
  29240. X
  29241. Xstatic int _fastcall end_object(int triout)
  29242. X{
  29243. X      if (RAY == 7)
  29244. X          return(0);
  29245. X    if (RAY == 1)
  29246. X    {
  29247. X    if (triout)
  29248. X        {
  29249. X        /* Make sure the bounding box is slightly larger than the object */
  29250. X        int i;
  29251. X        for (i=0;i<=2;i++)
  29252. X        {
  29253. X            if (min_xyz[i] == max_xyz[i])
  29254. X            {
  29255. X                min_xyz[i] -= 0.01;
  29256. X            max_xyz[i] += 0.01;
  29257. X            }
  29258. X            else
  29259. X            {
  29260. X                min_xyz[i] -= (max_xyz[i] - min_xyz[i]) * 0.01;
  29261. X                max_xyz[i] += (max_xyz[i] - min_xyz[i]) * 0.01;
  29262. X            }
  29263. X        }
  29264. X
  29265. X        /* Add the bounding box info */
  29266. X#ifndef XFRACT
  29267. X        fprintf (File_Ptr1, "%Fs  %Fs", bnd_by, inter);
  29268. X#else
  29269. X        fprintf (File_Ptr1, "%s  %s", bnd_by, inter);
  29270. X#endif
  29271. X        fprintf (File_Ptr1, fmt, plane,m1,z,z,-min_xyz[0],end,plane);
  29272. X        fprintf (File_Ptr1, fmt, plane,one,z,z,max_xyz[0],end,plane);
  29273. X        fprintf (File_Ptr1, fmt, plane,z,m1,z,-min_xyz[1],end,plane);
  29274. X        fprintf (File_Ptr1, fmt, plane,z,one,z,max_xyz[1],end,plane);
  29275. X        fprintf (File_Ptr1, fmt, plane,z,z,m1,-min_xyz[2],end,plane);
  29276. X        fprintf (File_Ptr1, fmt, plane,z,z,one,max_xyz[2],end,plane);
  29277. X#ifndef XFRACT
  29278. X        fprintf (File_Ptr1, "  %Fs%Fs%Fs", end, inter, end_bnd);
  29279. X#else
  29280. X        fprintf (File_Ptr1, "  %s%s%s", end, inter, end_bnd);
  29281. X#endif
  29282. X        }
  29283. X
  29284. X        /* Complete the composite object statement */
  29285. X#ifndef XFRACT
  29286. X        fprintf (File_Ptr1, "%Fs%Fs\n", end, composite);
  29287. X#else
  29288. X        fprintf (File_Ptr1, "%s%s\n", end, composite);
  29289. X#endif
  29290. X    }
  29291. X
  29292. X    if (RAY!=6 && RAY!=5)
  29293. X        fprintf (File_Ptr1, n);  /* EB & DG: too many newlines */
  29294. X
  29295. X    return(0);
  29296. X}
  29297. X
  29298. X
  29299. Xstatic void line3d_cleanup()
  29300. X{
  29301. X int i,j;
  29302. X    if(RAY && File_Ptr1)
  29303. X    {  /*  Finish up the ray tracing files */
  29304. X        static char far n_ta[] ={"{ No. Of Triangles = "};
  29305. X        if (RAY != 5 && RAY != 7)
  29306. X            fprintf (File_Ptr1, n);  /* EB & DG: too many newlines */
  29307. X        if (RAY == 2)
  29308. X            fprintf(File_Ptr1, "\n\n//");
  29309. X        if (RAY == 4)
  29310. X            fprintf(File_Ptr1, "\n\n#");
  29311. X
  29312. X        if (RAY == 5)
  29313. X#ifndef XFRACT
  29314. X            fprintf (File_Ptr1, "end\n\n/*good landscape:*/\n%Fs%Fs\n/*", grid,grid2); /* EB & DG: end grid aggregate */
  29315. X#else
  29316. X            fprintf (File_Ptr1, "end\n\n/*good landscape:*/\n%s%s\n/*", grid,grid2);  /* EB & DG: end grid aggregate */
  29317. X#endif
  29318. X        if (RAY == 6)
  29319. X        {
  29320. X#ifndef XFRACT
  29321. X            fprintf (File_Ptr1, "%Fs", acro_s2);
  29322. X#else
  29323. X            fprintf (File_Ptr1, "%s", acro_s2);
  29324. X#endif
  29325. X            for (i=0;i<RO;i++)
  29326. X                for (j=0;j<=CO_MAX;j++)
  29327. X                {
  29328. X                    if (j < CO_MAX)
  29329. X                        fprintf (File_Ptr1, f2, i, j, i, j+1);
  29330. X                    if (i < RO - 1)
  29331. X                        fprintf (File_Ptr1, f2, i, j, i+1, j);
  29332. X                    if (i && i < RO && j < CO_MAX)
  29333. X                        fprintf (File_Ptr1, f2, i, j, i-1, j+1);
  29334. X                }
  29335. X            fprintf (File_Ptr1, "\n\n--");
  29336. X        }
  29337. X            if (RAY != 7)
  29338. X#ifndef XFRACT
  29339. X            fprintf(File_Ptr1, "%Fs%d }*/\n\n",n_ta, num_tris); /* EB & DG: this is what s3a should be */
  29340. X/* see note        fprintf(File_Ptr1, "%Fs%d%Fs",n_ta, num_tris, s3a);   BUG! s3a=null here! why?! */
  29341. X#else
  29342. X            fprintf(File_Ptr1, "%s%d }*/\n\n",n_ta, num_tris);  /* EB & DG: this is what s3a should be */
  29343. X/* see note        fprintf(File_Ptr1, "%s%d%s",n_ta, num_tris, s3a);     BUG! s3a=null here! why?! */
  29344. X#endif
  29345. X          if (RAY == 7)
  29346. X               fprintf (File_Ptr1, dxf_end);
  29347. X        fclose(File_Ptr1);
  29348. X        File_Ptr1 = NULL;
  29349. X    }
  29350. X    if (Targa_Out)
  29351. X    {    /*  Finish up targa files */
  29352. X        T_header_24 = 18; /* Reset Targa header size */
  29353. X        enddisk();
  29354. X        if (!debugflag && T_Safe && !error && Targa_Overlay)
  29355. X        {
  29356. X            remove(light_name);
  29357. X            rename(targa_temp,light_name);
  29358. X        }
  29359. X        if (!debugflag && Targa_Overlay)
  29360. X            remove (targa_temp);
  29361. X    }
  29362. X    usr_floatflag &= 1; /* strip second bit */
  29363. X    error = T_Safe = 0;
  29364. X}
  29365. X
  29366. SHAR_EOF
  29367. $TOUCH -am 1028230093 line3d.c &&
  29368. chmod 0644 line3d.c ||
  29369. echo "restore of line3d.c failed"
  29370. set `wc -c line3d.c`;Wc_c=$1
  29371. if test "$Wc_c" != "77259"; then
  29372.     echo original size 77259, current size $Wc_c
  29373. fi
  29374. # ============= loadfdos.c ==============
  29375. echo "x - extracting loadfdos.c (Text)"
  29376. sed 's/^X//' << 'SHAR_EOF' > loadfdos.c &&
  29377. X/*
  29378. X    loadfdos.c - subroutine of loadfile.c (read_overlay) which sets
  29379. X         up video (mode, screen size).
  29380. X    This module is linked as an overlay, should only be called from loadfile.c
  29381. X
  29382. X    This code was split to a separate module to isolate the DOS only aspects
  29383. X    of loading an image.  get_video_mode should return with:
  29384. X      return code 0 for ok, -1 for error or cancelled by user
  29385. X      video parameters setup for the mainline, in the dos case this means
  29386. X    setting initmode to video mode, based on this fractint.c will set up
  29387. X    for and call setvideomode
  29388. X      set viewwindow on if file going to be loaded into a view smaller than
  29389. X    physical screen, in this case also set viewreduction, viewxdots,
  29390. X    viewydots, and finalaspectratio
  29391. X      set skipxdots and skipydots, to 0 if all pixels are to be loaded,
  29392. X    to 1 for every 2nd pixel, 2 for every 3rd, etc
  29393. X
  29394. X    In WinFract, at least initially, get_video_mode can do just the
  29395. X    following:
  29396. X      set overall image x & y dimensions (sxdots and sydots) to filexdots
  29397. X    and fileydots (note that filecolors is the number of colors in the
  29398. X    gif, not sure if that is of any use...)
  29399. X      if current window smaller than new sxdots and sydots, use scroll bars,
  29400. X    if larger perhaps reduce the window size? whatever
  29401. X      set viewwindow to 0 (no need? it always is for now in windows vsn?)
  29402. X      set finalaspectratio to .75 (ditto?)
  29403. X      set skipxdots and skipydots to 0
  29404. X      return 0
  29405. X
  29406. X*/
  29407. X
  29408. X#include <stdlib.h>
  29409. X#include <stdio.h>
  29410. X#include <string.h>
  29411. X#include <math.h>
  29412. X#include "fractint.h"
  29413. X#include "helpdefs.h"
  29414. X#include "prototyp.h"
  29415. X
  29416. X/* routines in this module    */
  29417. X
  29418. Xstatic int    vidcompare(VOIDCONSTPTR ,VOIDCONSTPTR );
  29419. Xstatic void   format_vid_inf(int i,char *err,char *buf);
  29420. Xstatic double vid_aspect(int tryxdots,int tryydots);
  29421. Xstatic void   format_item(int,char *);
  29422. Xstatic int    check_modekey(int,int);
  29423. X
  29424. X
  29425. Xextern int    initmode;         /* initial video mode        */
  29426. Xextern int    askvideo;
  29427. Xextern int    initbatch;        /* 1 if batch run (no kbd)  */
  29428. Xextern int    fractype;         /* fractal type         */
  29429. Xextern int    viewwindow;        /* 0 for full screen, 1 for window */
  29430. Xextern float  viewreduction;        /* window auto-sizing */
  29431. Xextern float  finalaspectratio;     /* for view shape and rotation */
  29432. Xextern int    viewxdots,viewydots;    /* explicit view sizing */
  29433. Xextern int    fileydots, filexdots, filecolors;
  29434. Xextern float  fileaspectratio;
  29435. Xextern int    skipxdots,skipydots;    /* for decoder, when reducing image */
  29436. Xextern char   readname[];        /* name of fractal input file */
  29437. Xextern int    save_system,save_release;
  29438. Xextern int    display3d;        /* 3D display flag: 0 = OFF */
  29439. Xextern struct videoinfo far videotable[];
  29440. Xextern struct videoinfo far *vidtbl;
  29441. Xextern int    vidtbllen;
  29442. Xextern float  screenaspect;
  29443. X
  29444. X
  29445. Xstruct vidinf {
  29446. X   int entnum;       /* videoentry subscript */
  29447. X   unsigned flags; /* flags for sort's compare, defined below */
  29448. X   };
  29449. X/* defines for flags; done this way instead of bit union to ensure ordering;
  29450. X   these bits represent the sort sequence for video mode list */
  29451. X#define VI_EXACT 0x8000 /* unless the one and only exact match */
  29452. X#define VI_NOKEY   512    /* if no function key assigned */
  29453. X#define VI_DISK1   256    /* disk video and size not exact */
  29454. X#define VI_SSMALL  128    /* screen smaller than file's screen */
  29455. X#define VI_SBIG     64    /* screen bigger than file's screen */
  29456. X#define VI_VSMALL   32    /* screen smaller than file's view */
  29457. X#define VI_VBIG     16    /* screen bigger than file's view */
  29458. X#define VI_CSMALL    8    /* mode has too few colors */
  29459. X#define VI_CBIG      4    /* mode has excess colors */
  29460. X#define VI_DISK2     2    /* disk video */
  29461. X#define VI_ASPECT    1    /* aspect ratio bad */
  29462. X
  29463. X
  29464. Xstatic int vidcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2)
  29465. X{
  29466. X   struct vidinf *ptr1,*ptr2;
  29467. X   ptr1 = (struct vidinf *)p1;
  29468. X   ptr2 = (struct vidinf *)p2;
  29469. X   if (ptr1->flags < ptr2->flags) return(-1);
  29470. X   if (ptr1->flags > ptr2->flags) return(1);
  29471. X   if (vidtbl[ptr1->entnum].keynum < vidtbl[ptr2->entnum].keynum) return(-1);
  29472. X   if (vidtbl[ptr1->entnum].keynum > vidtbl[ptr2->entnum].keynum) return(1);
  29473. X   if (ptr1->entnum < ptr2->entnum) return(-1);
  29474. X   return(1);
  29475. X}
  29476. X
  29477. Xstatic void format_vid_inf(int i,char *err,char *buf)
  29478. X{
  29479. X   char kname[5];
  29480. X   far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
  29481. X          sizeof(videoentry));
  29482. X   vidmode_keyname(videoentry.keynum,kname);
  29483. X   sprintf(buf,"%-5s %-25s %-4s %4d %4d %3d %-25s",  /* 76 chars */
  29484. X       kname, videoentry.name, err,
  29485. X       videoentry.xdots, videoentry.ydots,
  29486. X       videoentry.colors, videoentry.comment);
  29487. X   videoentry.xdots = 0; /* so tab_display knows to display nothing */
  29488. X}
  29489. X
  29490. Xstatic double vid_aspect(int tryxdots,int tryydots)
  29491. X{  /* calc resulting aspect ratio for specified dots in current mode */
  29492. X   return (double)tryydots / (double)tryxdots
  29493. X    * (double)videoentry.xdots / (double)videoentry.ydots
  29494. X    * screenaspect;
  29495. X   }
  29496. X
  29497. X
  29498. Xstatic struct vidinf *vidptr;
  29499. X
  29500. Xint get_video_mode(struct fractal_info *info)
  29501. X{
  29502. X   static char far hdg2[]={"key...name......................err..xdot.ydot.clr.comment.................."};
  29503. X   static char far warning[]={"\nWARNING: non-standard aspect ratio; loading will change your <v>iew settings"};
  29504. X   static char far select_msg[]={"\
  29505. XSelect a video mode.  Use the cursor keypad to move the pointer.\n\
  29506. XPress ENTER for selected mode, or use a video mode function key.\n\
  29507. XPress F1 for help, "};
  29508. X
  29509. X   struct vidinf vid[MAXVIDEOMODES];
  29510. X   int i,j;
  29511. X   int gotrealmode;
  29512. X   double ftemp,ftemp2;
  29513. X   unsigned tmpflags;
  29514. X
  29515. X   int tmpxdots,tmpydots;
  29516. X   float tmpreduce;
  29517. X   char *nameptr;
  29518. X   int    *attributes;
  29519. X   extern char temp1[256];
  29520. X   extern char dstack[]; /* for heading, avoid a 320 byte variable here  */
  29521. X             /* also, for attributes array, saves 600     */
  29522. X             /* both above necessary to avoid stack problems */
  29523. X   int oldhelpmode;
  29524. X   struct videoinfo far *vident;
  29525. X
  29526. X   initmode = -1;
  29527. X   load_fractint_cfg(0); /* get fractint.cfg into *vidtbl (== extraseg) */
  29528. X
  29529. X   /* try to find exact match for vid mode */
  29530. X   for (i = 0; i < vidtbllen; ++i) {
  29531. X      vident = &vidtbl[i];
  29532. X      if (info->xdots == vident->xdots && info->ydots == vident->ydots
  29533. X    && filecolors == vident->colors
  29534. X    && info->videomodeax == vident->videomodeax
  29535. X    && info->videomodebx == vident->videomodebx
  29536. X    && info->videomodecx == vident->videomodecx
  29537. X    && info->videomodedx == vident->videomodedx
  29538. X    && info->dotmode%100 == vident->dotmode%100) {
  29539. X     initmode = i;
  29540. X     break;
  29541. X     }
  29542. X      }
  29543. X
  29544. X   if (initmode == -1) /* try to find very good match for vid mode */
  29545. X      for (i = 0; i < vidtbllen; ++i) {
  29546. X     vident = &vidtbl[i];
  29547. X     if (info->xdots == vident->xdots && info->ydots == vident->ydots
  29548. X       && filecolors == vident->colors) {
  29549. X        initmode = i;
  29550. X        break;
  29551. X        }
  29552. X     }
  29553. X
  29554. X   /* setup table entry for each vid mode, flagged for how well it matches */
  29555. X   for (i = 0; i < vidtbllen; ++i) {
  29556. X      far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
  29557. X         sizeof(videoentry));
  29558. X      tmpflags = VI_EXACT;
  29559. X      if (videoentry.keynum == 0)
  29560. X     tmpflags |= VI_NOKEY;
  29561. X      if (info->xdots > videoentry.xdots || info->ydots > videoentry.ydots)
  29562. X     tmpflags |= VI_SSMALL;
  29563. X      else if (info->xdots < videoentry.xdots || info->ydots < videoentry.ydots)
  29564. X     tmpflags |= VI_SBIG;
  29565. X      if (filexdots > videoentry.xdots || fileydots > videoentry.ydots)
  29566. X     tmpflags |= VI_VSMALL;
  29567. X      else if (filexdots < videoentry.xdots || fileydots < videoentry.ydots)
  29568. X     tmpflags |= VI_VBIG;
  29569. X      if (filecolors > videoentry.colors)
  29570. X     tmpflags |= VI_CSMALL;
  29571. X      if (filecolors < videoentry.colors)
  29572. X     tmpflags |= VI_CBIG;
  29573. X      if (i == initmode)
  29574. X     tmpflags -= VI_EXACT;
  29575. X      if (videoentry.dotmode%100 == 11) {
  29576. X     tmpflags |= VI_DISK2;
  29577. X     if ((tmpflags & (VI_SBIG+VI_SSMALL+VI_VBIG+VI_VSMALL)) != 0)
  29578. X        tmpflags |= VI_DISK1;
  29579. X     }
  29580. X      if (fileaspectratio != 0 && videoentry.dotmode%100 != 11
  29581. X    && (tmpflags & VI_VSMALL) == 0) {
  29582. X     ftemp = vid_aspect(filexdots,fileydots);
  29583. X     if ( ftemp < fileaspectratio * 0.98
  29584. X       || ftemp > fileaspectratio * 1.02)
  29585. X        tmpflags |= VI_ASPECT;
  29586. X     }
  29587. X      vid[i].entnum = i;
  29588. X      vid[i].flags  = tmpflags;
  29589. X      }
  29590. X
  29591. X#ifndef XFRACT
  29592. X   gotrealmode = 0;
  29593. X   if (initmode < 0 || (askvideo && !initbatch)) {
  29594. X      /* no exact match or (askvideo=yes and batch=no), talk to user */
  29595. X
  29596. X      qsort(vid,vidtbllen,sizeof(vid[0]),vidcompare); /* sort modes */
  29597. X
  29598. X      attributes = (int *)&dstack[1000];
  29599. X      for (i = 0; i < vidtbllen; ++i)
  29600. X     attributes[i] = 1;
  29601. X      vidptr = &vid[0]; /* for format_item */
  29602. X
  29603. X      /* format heading */
  29604. X      if (info->info_id[0] == 'G')
  29605. X     strcpy(temp1,"      Non-fractal GIF");
  29606. X      else {
  29607. X     nameptr = curfractalspecific->name;
  29608. X     if (*nameptr == '*') ++nameptr;
  29609. X     if (display3d) nameptr = "3D Transform";
  29610. X     sprintf(temp1,"Type: %s",nameptr);
  29611. X     }
  29612. X      sprintf(dstack,"File: %-44s  %d x %d x %d\n%-52s",
  29613. X         readname,filexdots,fileydots,filecolors,temp1);
  29614. X      if (info->info_id[0] != 'G') {
  29615. X     if (save_system)
  29616. X        strcat(dstack,"WinFract ");
  29617. X     sprintf(temp1,"v%d.%01d",save_release/100,(save_release%100)/10);
  29618. X     if (save_release%100) {
  29619. X        i = strlen(temp1);
  29620. X        temp1[i] = (save_release%10) + '0';
  29621. X        temp1[i+1] = 0;
  29622. X        }
  29623. X     if (save_system == 0 && save_release <= 1410)
  29624. X        strcat(temp1," or earlier");
  29625. X     strcat(dstack,temp1);
  29626. X     }
  29627. X      strcat(dstack,"\n");
  29628. X      if (info->info_id[0] != 'G' && save_system == 0)
  29629. X     if (initmode < 0)
  29630. X        strcat(dstack,"Saved in unknown video mode.");
  29631. X     else {
  29632. X        format_vid_inf(initmode,"",temp1);
  29633. X        strcat(dstack,temp1);
  29634. X        }
  29635. X      if (fileaspectratio != 0 && fileaspectratio != screenaspect)
  29636. X     far_strcat(dstack,warning);
  29637. X      strcat(dstack,"\n");
  29638. X      /* set up instructions */
  29639. X      far_strcpy(temp1,select_msg);
  29640. X      if (info->info_id[0] != 'G')
  29641. X     strcat(temp1,"TAB for fractal information, ");
  29642. X      strcat(temp1,"ESCAPE to back out.");
  29643. X
  29644. X      oldhelpmode = helpmode;
  29645. X      helpmode = HELPLOADFILE;
  29646. X      i = fullscreen_choice(0,dstack,hdg2,temp1,vidtbllen,NULL,attributes,
  29647. X                     1,13,76,0,format_item,NULL,NULL,check_modekey);
  29648. X      helpmode = oldhelpmode;
  29649. X      if (i == -1)
  29650. X     return(-1);
  29651. X      if (i < 0) { /* returned -100 - videotable entry number */
  29652. X     initmode = -100 - i;
  29653. X     gotrealmode = 1;
  29654. X     }
  29655. X      else
  29656. X     initmode = vid[i].entnum;
  29657. X      }
  29658. X#else
  29659. X      initmode = 0;
  29660. X      j = vidtbl[0].keynum;
  29661. X      gotrealmode = 0;
  29662. X#endif
  29663. X
  29664. X   if (gotrealmode == 0) { /* translate from temp table to permanent */
  29665. X      if ((j = vidtbl[i=initmode].keynum) != 0) {
  29666. X     for (initmode = 0; initmode < MAXVIDEOTABLE-1; ++initmode)
  29667. X        if (videotable[initmode].keynum == j) break;
  29668. X     if (initmode >= MAXVIDEOTABLE-1) j = 0;
  29669. X     }
  29670. X      if (j == 0) /* mode has no key, add to reserved slot at end */
  29671. X     far_memcpy((char far *)&videotable[initmode=MAXVIDEOTABLE-1],
  29672. X            (char far *)&vidtbl[i],sizeof(*vidtbl));
  29673. X      }
  29674. X
  29675. X   /* ok, we're going to return with a video mode */
  29676. X
  29677. X   far_memcpy((char far *)&videoentry,(char far *)&videotable[initmode],
  29678. X          sizeof(videoentry));
  29679. X
  29680. X   skipxdots = skipydots = 0; /* set for no reduction */
  29681. X   if (videoentry.xdots < filexdots || videoentry.ydots < fileydots) {
  29682. X      /* set up to load only every nth pixel to make image fit */
  29683. X      skipxdots = skipydots = 1;
  29684. X      while (skipxdots * videoentry.xdots < filexdots) ++skipxdots;
  29685. X      while (skipydots * videoentry.ydots < fileydots) ++skipydots;
  29686. X      i = j = 0;
  29687. X      while (1) {
  29688. X     tmpxdots = (filexdots + skipxdots - 1) / skipxdots;
  29689. X     tmpydots = (fileydots + skipydots - 1) / skipydots;
  29690. X     if (fileaspectratio == 0 || videoentry.dotmode%100 == 11)
  29691. X        break;
  29692. X     /* reduce further if that improves aspect */
  29693. X     if ((ftemp = vid_aspect(tmpxdots,tmpydots)) > fileaspectratio) {
  29694. X        if (j) break; /* already reduced x, don't reduce y */
  29695. X        ftemp2 = vid_aspect(tmpxdots,(fileydots+skipydots)/(skipydots+1));
  29696. X        if (ftemp2 < fileaspectratio
  29697. X          && ftemp/fileaspectratio *0.9 <= fileaspectratio/ftemp2)
  29698. X           break; /* further y reduction is worse */
  29699. X        ++skipydots;
  29700. X        ++i;
  29701. X        }
  29702. X     else {
  29703. X        if (i) break; /* already reduced y, don't reduce x */
  29704. X        ftemp2 = vid_aspect((filexdots+skipxdots)/(skipxdots+1),tmpydots);
  29705. X        if (ftemp2 > fileaspectratio
  29706. X          && fileaspectratio/ftemp *0.9 <= ftemp2/fileaspectratio)
  29707. X           break; /* further x reduction is worse */
  29708. X        ++skipxdots;
  29709. X        ++j;
  29710. X        }
  29711. X     }
  29712. X      filexdots = tmpxdots;
  29713. X      fileydots = tmpydots;
  29714. X      --skipxdots;
  29715. X      --skipydots;
  29716. X      }
  29717. X
  29718. X   if ((finalaspectratio = fileaspectratio) == 0) /* assume display correct */
  29719. X      finalaspectratio = vid_aspect(filexdots,fileydots);
  29720. X   if (finalaspectratio >= screenaspect-0.02
  29721. X     && finalaspectratio <= screenaspect+0.02)
  29722. X      finalaspectratio = screenaspect;
  29723. X   i = finalaspectratio * 1000.0 + 0.5;
  29724. X   finalaspectratio = (double)i/1000.0; /* chop precision to 3 decimals */
  29725. X
  29726. X   /* setup view window stuff */
  29727. X   viewwindow = viewxdots = viewydots = 0;
  29728. X   if (filexdots != videoentry.xdots || fileydots != videoentry.ydots) {
  29729. X      /* image not exactly same size as screen */
  29730. X      viewwindow = 1;
  29731. X      ftemp = finalaspectratio
  29732. X        * (double)videoentry.ydots / (double)videoentry.xdots
  29733. X        / screenaspect;
  29734. X      if (finalaspectratio <= screenaspect) {
  29735. X     i = (double)videoentry.xdots / (double)filexdots * 20.0 + 0.5;
  29736. X     tmpreduce = (double)i/20.0; /* chop precision to nearest .05 */
  29737. X     i = (double)videoentry.xdots / tmpreduce + 0.5;
  29738. X     j = (double)i * ftemp + 0.5;
  29739. X     }
  29740. X      else {
  29741. X     i = (double)videoentry.ydots / (double)fileydots * 20.0 + 0.5;
  29742. X     tmpreduce = (double)i/20.0; /* chop precision to nearest .05 */
  29743. X     j = (double)videoentry.ydots / tmpreduce + 0.5;
  29744. X     i = (double)j / ftemp + 0.5;
  29745. X     }
  29746. X      if (i != filexdots || j != fileydots) { /* too bad, must be explicit */
  29747. X     viewxdots = filexdots;
  29748. X     viewydots = fileydots;
  29749. X     }
  29750. X      else
  29751. X     viewreduction = tmpreduce; /* ok, this works */
  29752. X      }
  29753. X   if (fabs(finalaspectratio - screenaspect) > .00001 || viewxdots != 0 ) {
  29754. X      static char far msg[] = {"\
  29755. XWarning: <V>iew parameters are being set to non-standard values.\n\
  29756. XRemember to reset them when finished with this image.1"};
  29757. X      stopmsg(4,msg);
  29758. X      }
  29759. X
  29760. X   return(0);
  29761. X}
  29762. X
  29763. Xstatic void format_item(int choice,char *buf)
  29764. X{
  29765. X   char errbuf[10];
  29766. X   unsigned tmpflags;
  29767. X   errbuf[0] = 0;
  29768. X   tmpflags = vidptr[choice].flags;
  29769. X   if (tmpflags & (VI_VSMALL+VI_CSMALL+VI_ASPECT)) strcat(errbuf,"*");
  29770. X   if (tmpflags & VI_VSMALL) strcat(errbuf,"R");
  29771. X   if (tmpflags & VI_CSMALL) strcat(errbuf,"C");
  29772. X   if (tmpflags & VI_ASPECT) strcat(errbuf,"A");
  29773. X   if (tmpflags & VI_VBIG)   strcat(errbuf,"v");
  29774. X   if (tmpflags & VI_CBIG)   strcat(errbuf,"c");
  29775. X   format_vid_inf(vidptr[choice].entnum,errbuf,buf);
  29776. X}
  29777. X
  29778. Xstatic int check_modekey(int curkey,int choice)
  29779. X{
  29780. X   int i;
  29781. X   return (((i = check_vidmode_key(0,curkey)) >= 0) ? -100-i : 0);
  29782. X}
  29783. X
  29784. SHAR_EOF
  29785. $TOUCH -am 1028230093 loadfdos.c &&
  29786. chmod 0644 loadfdos.c ||
  29787. echo "restore of loadfdos.c failed"
  29788. set `wc -c loadfdos.c`;Wc_c=$1
  29789. if test "$Wc_c" != "14560"; then
  29790.     echo original size 14560, current size $Wc_c
  29791. fi
  29792. # ============= loadfile.c ==============
  29793. echo "x - extracting loadfile.c (Text)"
  29794. sed 's/^X//' << 'SHAR_EOF' > loadfile.c &&
  29795. X/*
  29796. X    loadfile.c - load an existing fractal image, control level
  29797. X    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  29798. X*/
  29799. X
  29800. X#include <stdlib.h>
  29801. X#include <stdio.h>
  29802. X#include <string.h>
  29803. X#ifdef XFRACT
  29804. X#include <unistd.h>
  29805. X#endif
  29806. X#include "fractint.h"
  29807. X#include "fractype.h"
  29808. X#include "targa_lc.h"
  29809. X#include "prototyp.h"
  29810. X
  29811. X/* routines in this module    */
  29812. X
  29813. Xstatic int  find_fractal_info(char *,struct fractal_info *);
  29814. Xstatic void load_ext_blk(char far *loadptr,int loadlen);
  29815. Xstatic void skip_ext_blk(int *,int *);
  29816. Xstatic void backwardscompat();
  29817. X
  29818. Xint filetype;
  29819. Xint loaded3d;
  29820. X
  29821. Xextern char   maxfn;                    /* num trig functions if formula */
  29822. Xextern int    showfile;         /* has file been displayed yet? */
  29823. Xextern char   readname[];        /* name of fractal input file */
  29824. Xextern char   far *resume_info;     /* pointer to resume info if alloc'd */
  29825. Xextern int    resume_len;        /* length of resume info */
  29826. Xextern int    adapter;
  29827. Xextern int    calc_status;
  29828. Xextern int    initmode;         /* initial video mode        */
  29829. Xextern long   calctime;
  29830. Xextern int    initbatch;        /* 1 if batch run (no kbd)  */
  29831. Xextern int    maxit;
  29832. Xextern int    initincr;         /* maxiter incrmnt        */
  29833. Xextern char   usr_stdcalcmode;        /* pass mode            */
  29834. Xextern int    fractype;         /* fractal type         */
  29835. Xextern double xxmin,xxmax;        /* corner values        */
  29836. Xextern double yymin,yymax;        /* corner values        */
  29837. Xextern double xx3rd,yy3rd;        /* corner values        */
  29838. Xextern double param[];             /* parameters            */
  29839. Xextern int    fillcolor;        /* fill color: -1 = normal  */
  29840. Xextern int    inside;            /* inside color: 1=blue     */
  29841. Xextern int    outside;            /* outside color, if set    */
  29842. Xextern int    finattract;        /* finite attractor option  */
  29843. Xextern int    forcesymmetry;
  29844. Xextern int    LogFlag;            /* non-zero if logarithmic palettes */
  29845. Xextern int    rflag, rseed;
  29846. Xextern int    usr_periodicitycheck;
  29847. Xextern char   useinitorbit;
  29848. Xextern _CMPLX initorbit;
  29849. Xextern int    potflag;            /* continuous potential flag */
  29850. Xextern int    pot16bit;
  29851. Xextern double potparam[3];        /* three potential parameters*/
  29852. Xextern double inversion[];
  29853. Xextern int    decomp[];
  29854. Xextern int    usr_distest;        /* non-zero if distance estimator   */
  29855. Xextern int    distestwidth;
  29856. Xextern int    init3d[20];        /* '3d=nn/nn/nn/...' values */
  29857. Xextern char   usr_floatflag;        /* floating-point fractals? */
  29858. Xextern char   floatflag;
  29859. Xextern int    usr_biomorph;
  29860. Xextern char   FormName[];
  29861. Xextern char   LName[];
  29862. Xextern char   IFSName[];
  29863. Xextern int    bailout;            /* user input bailout value */
  29864. Xextern int    previewfactor;
  29865. Xextern int    xtrans;
  29866. Xextern int    ytrans;
  29867. Xextern int    red_crop_left;
  29868. Xextern int    red_crop_right;
  29869. Xextern int    blue_crop_left;
  29870. Xextern int    blue_crop_right;
  29871. Xextern int    red_bright;
  29872. Xextern int    blue_bright;
  29873. Xextern int    xadjust;
  29874. Xextern int    eyeseparation;
  29875. Xextern int    glassestype;
  29876. Xextern int    display3d;        /* 3D display flag: 0 = OFF */
  29877. Xextern int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  29878. Xextern int    viewwindow;        /* 0 for full screen, 1 for window */
  29879. Xextern float  viewreduction;        /* window auto-sizing */
  29880. Xextern float  finalaspectratio;     /* for view shape and rotation */
  29881. Xextern int    xdots, ydots;        /* # of dots on the logical screen */
  29882. Xextern int    viewxdots,viewydots;    /* explicit view sizing */
  29883. Xextern int    save_system,save_release;
  29884. Xextern int    Ambient;
  29885. Xextern int    RANDOMIZE;
  29886. Xextern int    haze;
  29887. Xextern int    transparent[2];
  29888. Xextern int    rotate_lo,rotate_hi;
  29889. Xextern int far *ranges;
  29890. Xextern int    rangeslen;
  29891. Xextern int    invert;
  29892. Xextern int    num_fractal_types;
  29893. Xextern float  screenaspect;
  29894. Xextern     double mxmaxfp;
  29895. Xextern     double mxminfp;
  29896. Xextern     double mymaxfp;
  29897. Xextern     double myminfp;
  29898. Xextern     int   zdots;
  29899. Xextern     float originfp;
  29900. Xextern     float depthfp;
  29901. Xextern     float heightfp;
  29902. Xextern     float widthfp;
  29903. Xextern     float distfp;
  29904. Xextern     float eyesfp;
  29905. Xextern     int   neworbittype;
  29906. Xextern     short juli3Dmode;
  29907. Xextern     int   major_method;  /* inverse julia method */
  29908. Xextern     int   minor_method;
  29909. X
  29910. Xstatic FILE *fp;
  29911. X
  29912. Xint fileydots, filexdots, filecolors;
  29913. Xfloat fileaspectratio;
  29914. X
  29915. Xint skipxdots,skipydots;    /* for decoder, when reducing image */
  29916. X
  29917. X
  29918. Xvoid loadfile_overlay() { }    /* for restore_active_ovly */
  29919. X
  29920. X#ifdef XFRACT
  29921. Xextern int decode_fractal_info();
  29922. X#endif
  29923. X
  29924. Xint read_overlay()    /* read overlay/3D files, if reqr'd */
  29925. X{
  29926. X   struct fractal_info read_info;
  29927. X   char oldfloatflag;
  29928. X   char msg[110];
  29929. X
  29930. X   ENTER_OVLY(OVLY_LOADFILE);
  29931. X
  29932. X   showfile = 1;        /* for any abort exit, pretend done */
  29933. X   initmode = -1;        /* no viewing mode set yet */
  29934. X   oldfloatflag = usr_floatflag;
  29935. X   loaded3d = 0;
  29936. X
  29937. X   if(strchr(readname,'.') == NULL)
  29938. X      strcat(readname,".gif");
  29939. X
  29940. X   if(find_fractal_info(readname,&read_info)) { /* didn't find a useable file */
  29941. X      sprintf(msg,"Sorry, %s isn't a file I can decode.",readname);
  29942. X      stopmsg(0,msg);
  29943. X      EXIT_OVLY;
  29944. X      return(-1);
  29945. X      }
  29946. X
  29947. X   maxit    = read_info.iterations;
  29948. X   fractype    = read_info.fractal_type;
  29949. X   if (fractype < 0 || fractype >= num_fractal_types) {
  29950. X      sprintf(msg,"Warning: %s has a bad fractal type; using 0",readname);
  29951. X      fractype = 0;
  29952. X   }
  29953. X   curfractalspecific = &fractalspecific[fractype];
  29954. X   xxmin    = read_info.xmin;
  29955. X   xxmax    = read_info.xmax;
  29956. X   yymin    = read_info.ymin;
  29957. X   yymax    = read_info.ymax;
  29958. X   param[0]    = read_info.creal;
  29959. X   param[1]    = read_info.cimag;
  29960. X   save_release = 1100; /* unless we find out better later on */
  29961. X
  29962. X   invert = 0;
  29963. X   if(read_info.version > 0) {
  29964. X      param[2]        = read_info.parm3;
  29965. X      roundfloatd(¶m[2]);
  29966. X      param[3]        = read_info.parm4;
  29967. X      roundfloatd(¶m[3]);
  29968. X      potparam[0]   = read_info.potential[0];
  29969. X      potparam[1]   = read_info.potential[1];
  29970. X      potparam[2]   = read_info.potential[2];
  29971. X      potflag        = (potparam[0] != 0.0);
  29972. X      rflag        = read_info.rflag;
  29973. X      rseed        = read_info.rseed;
  29974. X      inside        = read_info.inside;
  29975. X      LogFlag        = read_info.logmap;
  29976. X      inversion[0]  = read_info.invert[0];
  29977. X      inversion[1]  = read_info.invert[1];
  29978. X      inversion[2]  = read_info.invert[2];
  29979. X      if (inversion[0] != 0.0)
  29980. X     invert = 3;
  29981. X      decomp[0]     = read_info.decomp[0];
  29982. X      decomp[1]     = read_info.decomp[1];
  29983. X      usr_biomorph  = read_info.biomorph;
  29984. X      forcesymmetry = read_info.symmetry;
  29985. X      }
  29986. X
  29987. X   if(read_info.version > 1) {
  29988. X      save_release  = 1200;
  29989. X      if (!display3d
  29990. X    && (read_info.version <= 4 || read_info.flag3d > 0
  29991. X        || (curfractalspecific->flags&PARMS3D) )) {
  29992. X     int i;
  29993. X     for (i = 0; i < 16; i++)
  29994. X        init3d[i] = read_info.init3d[i];
  29995. X     previewfactor     = read_info.previewfactor;
  29996. X     xtrans      = read_info.xtrans;
  29997. X     ytrans      = read_info.ytrans;
  29998. X     red_crop_left     = read_info.red_crop_left;
  29999. X     red_crop_right  = read_info.red_crop_right;
  30000. X     blue_crop_left  = read_info.blue_crop_left;
  30001. X     blue_crop_right = read_info.blue_crop_right;
  30002. X     red_bright     = read_info.red_bright;
  30003. X     blue_bright     = read_info.blue_bright;
  30004. X     xadjust     = read_info.xadjust;
  30005. X     eyeseparation     = read_info.eyeseparation;
  30006. X     glassestype     = read_info.glassestype;
  30007. X     }
  30008. X      }
  30009. X
  30010. X   if(read_info.version > 2) {
  30011. X      save_release = 1300;
  30012. X      outside       = read_info.outside;
  30013. X      }
  30014. X
  30015. X   calc_status = 0;      /* defaults if version < 4 */
  30016. X   xx3rd = xxmin;
  30017. X   yy3rd = yymin;
  30018. X   usr_distest = 0;
  30019. X   calctime = 0;
  30020. X   if(read_info.version > 3) {
  30021. X      save_release = 1400;
  30022. X      xx3rd      = read_info.x3rd;
  30023. X      yy3rd      = read_info.y3rd;
  30024. X      calc_status = read_info.calc_status;
  30025. X      usr_stdcalcmode = read_info.stdcalcmode;
  30026. X      usr_distest     = read_info.distest;
  30027. X      usr_floatflag   = read_info.floatflag;
  30028. X      bailout      = read_info.bailout;
  30029. X      calctime      = read_info.calctime;
  30030. X      trigndx[0]  = read_info.trigndx[0];
  30031. X      trigndx[1]  = read_info.trigndx[1];
  30032. X      trigndx[2]  = read_info.trigndx[2];
  30033. X      trigndx[3]  = read_info.trigndx[3];
  30034. X      finattract  = read_info.finattract;
  30035. X      initorbit.x = read_info.initorbit[0];
  30036. X      initorbit.y = read_info.initorbit[1];
  30037. X      useinitorbit = read_info.useinitorbit;
  30038. X      usr_periodicitycheck = read_info.periodicity;
  30039. X      }
  30040. X
  30041. X   pot16bit = 0;
  30042. X   save_system = 0;
  30043. X   if(read_info.version > 4) {
  30044. X      pot16bit       = read_info.pot16bit;
  30045. X      if (pot16bit)
  30046. X     filexdots >>= 1;
  30047. X      fileaspectratio = read_info.faspectratio;
  30048. X      if (fileaspectratio < 0.01)    /* fix files produced in early v14.1 */
  30049. X     fileaspectratio = screenaspect;
  30050. X      save_system  = read_info.system;
  30051. X      save_release = read_info.release; /* from fmt 5 on we know real number */
  30052. X      if (read_info.version == 5    /* except a few early fmt 5 cases: */
  30053. X      && (save_release <= 0 || save_release >= 2000)) {
  30054. X     save_release = 1410;
  30055. X     save_system = 0;
  30056. X     }
  30057. X      if (!display3d && read_info.flag3d > 0) {
  30058. X     loaded3d    = 1;
  30059. X     Ambient    = read_info.ambient;
  30060. X     RANDOMIZE    = read_info.randomize;
  30061. X     haze        = read_info.haze;
  30062. X     transparent[0] = read_info.transparent[0];
  30063. X     transparent[1] = read_info.transparent[1];
  30064. X     }
  30065. X      }
  30066. X
  30067. X   rotate_lo = 1; rotate_hi = 255;
  30068. X   distestwidth = 71;
  30069. X   if(read_info.version > 5) {
  30070. X      rotate_lo     = read_info.rotate_lo;
  30071. X      rotate_hi     = read_info.rotate_hi;
  30072. X      distestwidth    = read_info.distestwidth;
  30073. X      }
  30074. X
  30075. X   if(read_info.version > 6) {
  30076. X      param[2]        = read_info.dparm3;
  30077. X      param[3]        = read_info.dparm4;
  30078. X      }
  30079. X
  30080. X   if(read_info.version > 7) {
  30081. X      fillcolor        = read_info.fillcolor;
  30082. X      }
  30083. X
  30084. X   if(read_info.version > 8) {
  30085. X   mxmaxfp   =  read_info.mxmaxfp        ;
  30086. X   mxminfp   =  read_info.mxminfp        ;
  30087. X   mymaxfp   =  read_info.mymaxfp        ;
  30088. X   myminfp   =  read_info.myminfp        ;
  30089. X   zdots     =  read_info.zdots          ;        
  30090. X   originfp  =  read_info.originfp       ;
  30091. X   depthfp   =  read_info.depthfp        ;    
  30092. X   heightfp  =  read_info.heightfp       ;
  30093. X   widthfp   =  read_info.widthfp        ;    
  30094. X   distfp    =  read_info.distfp         ;    
  30095. X   eyesfp    =  read_info.eyesfp         ;    
  30096. X   neworbittype = read_info.orbittype    ;
  30097. X   juli3Dmode   = read_info.juli3Dmode   ;
  30098. X   maxfn    =   read_info.maxfn          ;
  30099. X   major_method = read_info.inversejulia >> 8;
  30100. X   minor_method = read_info.inversejulia & 255;
  30101. X   param[4] = read_info.dparm5;
  30102. X   param[5] = read_info.dparm6;
  30103. X   param[6] = read_info.dparm7;
  30104. X   param[7] = read_info.dparm8;
  30105. X   param[8] = read_info.dparm9;
  30106. X   param[9] = read_info.dparm10;
  30107. X      }
  30108. X
  30109. X   if(read_info.version < 4) { /* pre-version 14.0? */
  30110. X      backwardscompat(&read_info); /* translate obsolete types */
  30111. X      if(LogFlag)
  30112. X     LogFlag = 2;
  30113. X      usr_floatflag = (curfractalspecific->isinteger) ? 0 : 1;
  30114. X      }
  30115. X
  30116. X   if (read_info.version < 5) { /* pre-version 15.0? */
  30117. X      if (LogFlag == 2) /* logmap=old changed again in format 5! */
  30118. X     LogFlag = -1;
  30119. X      if (decomp[0] > 0 && decomp[1] > 0)
  30120. X     bailout = decomp[1];
  30121. X      }
  30122. X   if(potflag) /* in version 15.x and 16.x logmap didn't work with pot */
  30123. X      if(read_info.version == 6 || read_info.version == 7)
  30124. X         LogFlag = 0;
  30125. X   set_trig_pointers(-1);
  30126. X
  30127. X   if(read_info.version < 9) { /* pre-version 18.0? */
  30128. X      /* forcesymmetry==1000 means we want to force symmetry but don't
  30129. X         know which symmetry yet, will find out in setsymmetry() */
  30130. X      if(outside==REAL || outside==IMAG || outside==MULT || outside==SUM)
  30131. X         if(forcesymmetry == 999)
  30132. X            forcesymmetry = 1000;
  30133. X      }
  30134. X   if(save_release < 1725) { /* pre-version 17.25 */
  30135. X      set_if_old_bif(); /* translate bifurcation types */
  30136. X   }
  30137. X
  30138. X   if (display3d)            /* PB - a klooge till the meaning of */
  30139. X      usr_floatflag = oldfloatflag; /*    floatflag in line3d is clarified */
  30140. X
  30141. X   if (overlay3d) {
  30142. X      initmode = adapter;       /* use previous adapter mode for overlays */
  30143. X      if (filexdots > xdots || fileydots > ydots) {
  30144. X     static char far msg[]={"Can't overlay with a larger image"};
  30145. X     stopmsg(0,msg);
  30146. X     EXIT_OVLY;
  30147. X     initmode = -1;
  30148. X     return(-1);
  30149. X     }
  30150. X      }
  30151. X   else {
  30152. X      int olddisplay3d,oldfloatflag,i;
  30153. X      olddisplay3d = display3d;
  30154. X      oldfloatflag = floatflag;
  30155. X      display3d = loaded3d;      /* for <tab> display during next */
  30156. X      floatflag = usr_floatflag; /* ditto */
  30157. X      i = get_video_mode(&read_info);
  30158. X      display3d = olddisplay3d;
  30159. X      floatflag = oldfloatflag;
  30160. X      if (i) {
  30161. X     EXIT_OVLY;
  30162. X     initmode = -1;
  30163. X     return(-1);
  30164. X     }
  30165. X      }
  30166. X
  30167. X   if (display3d) {
  30168. X      calc_status = 0;
  30169. X      fractype = PLASMA;
  30170. X      curfractalspecific = &fractalspecific[PLASMA];
  30171. X      param[0] = 0;
  30172. X      if (!initbatch)
  30173. X     if (get_3d_params() < 0) {
  30174. X        EXIT_OVLY;
  30175. X        initmode = -1;
  30176. X        return(-1);
  30177. X        }
  30178. X      }
  30179. X
  30180. X   showfile = 0;           /* trigger the file load */
  30181. X
  30182. X   EXIT_OVLY;
  30183. X   return(0);
  30184. X}
  30185. X
  30186. X
  30187. Xstatic int find_fractal_info(gif_file,info)
  30188. Xchar *gif_file;
  30189. Xstruct fractal_info *info;
  30190. X{
  30191. X   BYTE gifstart[18];
  30192. X   char temp1[81];
  30193. X   int scan_extend, block_type, block_len, data_len;
  30194. X   int fractinf_len;
  30195. X   int hdr_offset;
  30196. X
  30197. X   if((fp = fopen(gif_file,"rb"))==NULL)
  30198. X      return(-1);
  30199. X
  30200. X   fread(gifstart,18,1,fp);
  30201. X#ifndef XFRACT
  30202. X   if (strncmp(gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
  30203. X#else
  30204. X   if (strncmp((char *)gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
  30205. X#endif
  30206. X      if(fread(info,FRACTAL_INFO_SIZE,1,fp)==1 &&
  30207. X         strncmp(info->info_id,"Fractal",8)==0) {
  30208. X     filetype = 1; /* Targa 16 */
  30209. X     GET16(gifstart[O_VSIZE],fileydots);
  30210. X     GET16(gifstart[O_HSIZE],filexdots);
  30211. X     filecolors = info->colors;
  30212. X     fileaspectratio = screenaspect;
  30213. X     if(fileydots == info->ydots && filexdots == info->xdots) {
  30214. X        fclose(fp);
  30215. X        return(0);
  30216. X        }
  30217. X     }
  30218. X      fclose(fp);
  30219. X      return(-1);
  30220. X      }
  30221. X
  30222. X   filetype = 0; /* GIF */
  30223. X   GET16(gifstart[6],filexdots);
  30224. X   GET16(gifstart[8],fileydots);
  30225. X   filecolors = 2 << (gifstart[10] & 7);
  30226. X   fileaspectratio = 0; /* unknown */
  30227. X   if (gifstart[12]) { /* calc reasonably close value from gif header */
  30228. X      fileaspectratio = (64.0 / ((double)(gifstart[12]) + 15.0))
  30229. X              * (double)fileydots / (double)filexdots;
  30230. X      if ( fileaspectratio > screenaspect-0.03
  30231. X    && fileaspectratio < screenaspect+0.03)
  30232. X     fileaspectratio = screenaspect;
  30233. X      }
  30234. X   else
  30235. X      if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */
  30236. X     fileaspectratio = screenaspect;
  30237. X
  30238. X   if (resume_info != NULL) { /* free the prior area if there is one */
  30239. X      farmemfree(resume_info);
  30240. X      resume_info = NULL;
  30241. X      }
  30242. X   if (rangeslen) { /* free prior ranges */
  30243. X      farmemfree((char far *)ranges);
  30244. X      rangeslen = 0;
  30245. X      }
  30246. X
  30247. X   /* Format of .gif extension blocks is:
  30248. X      1 byte    '!', extension block identifier
  30249. X      1 byte    extension block number, 255
  30250. X      1 byte    length of id, 11
  30251. X     11 bytes   alpha id, "fractintnnn" with fractint, nnn is secondary id
  30252. X       n * {
  30253. X      1 byte    length of block info in bytes
  30254. X      x bytes   block info
  30255. X       }
  30256. X      1 byte    0, extension terminator
  30257. X      To scan extension blocks, we first look in file at length of fractal_info
  30258. X      (the main extension block) from end of file, looking for a literal known
  30259. X      to be at start of our block info.  Then we scan forward a bit, in case
  30260. X      the file is from an earlier fractint vsn with shorter fractal_info.
  30261. X      If fractal_info is found and is from vsn>=14, it includes the total length
  30262. X      of all extension blocks; we then scan them all first to last to load
  30263. X      any optional ones which are present.
  30264. X      Defined extension blocks:
  30265. X    fractint001    header, always present
  30266. X    fractint002    resume info for interrupted resumable image
  30267. X    fractint003    additional formula type info
  30268. X    fractint004    ranges info
  30269. X   */
  30270. X
  30271. X   memset(info,0,FRACTAL_INFO_SIZE);
  30272. X   fractinf_len = FRACTAL_INFO_SIZE + (FRACTAL_INFO_SIZE+254)/255;
  30273. X   fseek(fp,(long)(-1-fractinf_len),SEEK_END);
  30274. X   fread(info,1,FRACTAL_INFO_SIZE,fp);
  30275. X   if (strcmp(INFO_ID,info->info_id) == 0) {
  30276. X#ifdef XFRACT
  30277. X       decode_fractal_info(info,1);
  30278. X#endif
  30279. X      hdr_offset = -1-fractinf_len;
  30280. X   } else {
  30281. X      /* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */
  30282. X      int offset,i;
  30283. X      char tmpbuf[110];
  30284. X      hdr_offset = 0;
  30285. X      offset = 80; /* don't even check last 80 bytes of file for id */
  30286. X      while (offset < fractinf_len+513) { /* allow 512 garbage at eof */
  30287. X     offset += 100; /* go back 100 bytes at a time */
  30288. X     fseek(fp,(long)(0-offset),SEEK_END);
  30289. X     fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */
  30290. X     for (i = 0; i < 100; ++i)
  30291. X        if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */
  30292. X           strcpy(info->info_id,INFO_ID);
  30293. X           fseek(fp,(long)(hdr_offset=i-offset),SEEK_END);
  30294. X           fread(info,1,FRACTAL_INFO_SIZE,fp);
  30295. X#ifdef XFRACT
  30296. X           decode_fractal_info(info,1);
  30297. X#endif
  30298. X           offset = 10000; /* force exit from outer loop */
  30299. X           break;
  30300. X           }
  30301. X     }
  30302. X      }
  30303. X
  30304. X   if (hdr_offset) { /* we found INFO_ID */
  30305. X
  30306. X      if (info->version >= 4) {
  30307. X     /* first reload main extension block, reasons:
  30308. X          might be over 255 chars, and thus earlier load might be bad
  30309. X          find exact endpoint, so scan back to start of ext blks works
  30310. X        */
  30311. X     fseek(fp,(long)(hdr_offset-15),SEEK_END);
  30312. X     scan_extend = 1;
  30313. X     while (scan_extend) {
  30314. X        if (fgetc(fp) != '!' /* if not what we expect just give up */
  30315. X          || fread(temp1,1,13,fp) != 13
  30316. X          || strncmp(&temp1[2],"fractint",8))
  30317. X           break;
  30318. X        temp1[13] = 0;
  30319. X        block_type = atoi(&temp1[10]); /* e.g. "fractint002" */
  30320. X        switch (block_type) {
  30321. X           case 1: /* "fractint001", the main extension block */
  30322. X          if (scan_extend == 2) { /* we've been here before, done now */
  30323. X             scan_extend = 0;
  30324. X             break;
  30325. X             }
  30326. X          load_ext_blk((char far *)info,FRACTAL_INFO_SIZE);
  30327. X#ifdef XFRACT
  30328. X          decode_fractal_info(info,1);
  30329. X#endif
  30330. X          scan_extend = 2;
  30331. X          /* now we know total extension len, back up to first block */
  30332. X          fseek(fp,0L-info->tot_extend_len,SEEK_CUR);
  30333. X          break;
  30334. X           case 2: /* resume info */
  30335. X          skip_ext_blk(&block_len,&data_len); /* once to get lengths */
  30336. X          if ((resume_info = farmemalloc((long)data_len)) == NULL)
  30337. X             info->calc_status = 3; /* not resumable after all */
  30338. X          else {
  30339. X             fseek(fp,(long)(0-block_len),SEEK_CUR);
  30340. X             load_ext_blk(resume_info,data_len);
  30341. X             resume_len = data_len;
  30342. X             }
  30343. X          break;
  30344. X           case 3: /* formula info */
  30345. X          {
  30346. X          char *nameptr;
  30347. X          char tmpname[40];
  30348. X          load_ext_blk(tmpname,40);
  30349. X          switch (info->fractal_type) {
  30350. X             case LSYSTEM:
  30351. X            nameptr = LName;
  30352. X            break;
  30353. X             case IFS:
  30354. X             case IFS3D:
  30355. X            nameptr = IFSName;
  30356. X            break;
  30357. X             default:
  30358. X            nameptr = FormName;
  30359. X            break;
  30360. X             }
  30361. X          tmpname[ITEMNAMELEN] = 0;
  30362. X          strcpy(nameptr,tmpname);
  30363. X          /* perhaps in future add more here, check block_len for
  30364. X             backward compatibility */
  30365. X          }
  30366. X          break;
  30367. X           case 4: /* ranges info */
  30368. X          skip_ext_blk(&block_len,&data_len); /* once to get lengths */
  30369. X          if ((ranges = (int far *)farmemalloc((long)data_len))) {
  30370. X             fseek(fp,(long)(0-block_len),SEEK_CUR);
  30371. X             load_ext_blk((char far *)ranges,data_len);
  30372. X             rangeslen = data_len/2;
  30373. X#ifdef XFRACTINT
  30374. X             fix_ranges(ranges,rangeslen,1);
  30375. X#endif
  30376. X             }
  30377. X          break;
  30378. X           default:
  30379. X          skip_ext_blk(&block_len,&data_len);
  30380. X           }
  30381. X        }
  30382. X     }
  30383. X
  30384. X      fclose(fp);
  30385. X      fileaspectratio = screenaspect; /* if not >= v15, this is correct */
  30386. X      return(0);
  30387. X      }
  30388. X
  30389. X   strcpy(info->info_id, "GIFFILE");
  30390. X   info->iterations = 150;
  30391. X   info->fractal_type = PLASMA;
  30392. X   info->xmin = -1;
  30393. X   info->xmax = 1;
  30394. X   info->ymin = -1;
  30395. X   info->ymax = 1;
  30396. X   info->x3rd = -1;
  30397. X   info->y3rd = -1;
  30398. X   info->creal = 0;
  30399. X   info->cimag = 0;
  30400. X   info->videomodeax=255;
  30401. X   info->videomodebx=255;
  30402. X   info->videomodecx=255;
  30403. X   info->videomodedx=255;
  30404. X   info->dotmode = 0;
  30405. X   info->xdots = filexdots;
  30406. X   info->ydots = fileydots;
  30407. X   info->colors = filecolors;
  30408. X   info->version = 0; /* this forces lots more init at calling end too */
  30409. X
  30410. X   /* zero means we won */
  30411. X   fclose(fp);
  30412. X   return(0);
  30413. X}
  30414. X
  30415. Xstatic void load_ext_blk(char far *loadptr,int loadlen)
  30416. X{
  30417. X   int len;
  30418. X   while ((len = fgetc(fp)) > 0) {
  30419. X      while (--len >= 0) {
  30420. X     if (--loadlen >= 0)
  30421. X        *(loadptr++) = fgetc(fp);
  30422. X     else
  30423. X        fgetc(fp); /* discard excess characters */
  30424. X     }
  30425. X      }
  30426. X}
  30427. X
  30428. Xstatic void skip_ext_blk(int *block_len, int *data_len)
  30429. X{
  30430. X   int len;
  30431. X   *data_len = 0;
  30432. X   *block_len = 1;
  30433. X   while ((len = fgetc(fp)) > 0) {
  30434. X      fseek(fp,(long)len,SEEK_CUR);
  30435. X      *data_len += len;
  30436. X      *block_len += len + 1;
  30437. X      }
  30438. X}
  30439. X
  30440. X
  30441. X/* switch obsolete fractal types to new generalizations */
  30442. Xstatic void backwardscompat(struct fractal_info *info)
  30443. X{
  30444. X   switch(fractype) {
  30445. X      case LAMBDASINE:
  30446. X     fractype = LAMBDATRIGFP;
  30447. X     trigndx[0] = SIN;
  30448. X     break;
  30449. X      case LAMBDACOS    :
  30450. X     fractype = LAMBDATRIGFP;
  30451. X     trigndx[0] = COS;
  30452. X     break;
  30453. X      case LAMBDAEXP    :
  30454. X     fractype = LAMBDATRIGFP;
  30455. X     trigndx[0] = EXP;
  30456. X     break;
  30457. X      case MANDELSINE    :
  30458. X     fractype = MANDELTRIGFP;
  30459. X     trigndx[0] = SIN;
  30460. X     break;
  30461. X      case MANDELCOS    :
  30462. X     fractype = MANDELTRIGFP;
  30463. X     trigndx[0] = COS;
  30464. X     break;
  30465. X      case MANDELEXP    :
  30466. X     fractype = MANDELTRIGFP;
  30467. X     trigndx[0] = EXP;
  30468. X     break;
  30469. X      case MANDELSINH    :
  30470. X     fractype = MANDELTRIGFP;
  30471. X     trigndx[0] = SINH;
  30472. X     break;
  30473. X      case LAMBDASINH    :
  30474. X     fractype = LAMBDATRIGFP;
  30475. X     trigndx[0] = SINH;
  30476. X     break;
  30477. X      case MANDELCOSH    :
  30478. X     fractype = MANDELTRIGFP;
  30479. X     trigndx[0] = COSH;
  30480. X     break;
  30481. X      case LAMBDACOSH    :
  30482. X     fractype = LAMBDATRIGFP;
  30483. X     trigndx[0] = COSH;
  30484. X     break;
  30485. X      case LMANDELSINE    :
  30486. X     fractype = MANDELTRIG;
  30487. X     trigndx[0] = SIN;
  30488. X     break;
  30489. X      case LLAMBDASINE    :
  30490. X     fractype = LAMBDATRIG;
  30491. X     trigndx[0] = SIN;
  30492. X     break;
  30493. X      case LMANDELCOS    :
  30494. X     fractype = MANDELTRIG;
  30495. X     trigndx[0] = COS;
  30496. X     break;
  30497. X      case LLAMBDACOS    :
  30498. X     fractype = LAMBDATRIG;
  30499. X     trigndx[0] = COS;
  30500. X     break;
  30501. X      case LMANDELSINH    :
  30502. X     fractype = MANDELTRIG;
  30503. X     trigndx[0] = SINH;
  30504. X     break;
  30505. X      case LLAMBDASINH    :
  30506. X     fractype = LAMBDATRIG;
  30507. X     trigndx[0] = SINH;
  30508. X     break;
  30509. X      case LMANDELCOSH    :
  30510. X     fractype = MANDELTRIG;
  30511. X     trigndx[0] = COSH;
  30512. X     break;
  30513. X      case LLAMBDACOSH    :
  30514. X     fractype = LAMBDATRIG;
  30515. X     trigndx[0] = COSH;
  30516. X     break;
  30517. X      case LMANDELEXP    :
  30518. X     fractype = MANDELTRIG;
  30519. X     trigndx[0] = EXP;
  30520. X     break;
  30521. X      case LLAMBDAEXP    :
  30522. X     fractype = LAMBDATRIG;
  30523. X     trigndx[0] = EXP;
  30524. X     break;
  30525. X      case DEMM     :
  30526. X     fractype = MANDELFP;
  30527. X     usr_distest = (info->ydots - 1) * 2;
  30528. X     break;
  30529. X      case DEMJ     :
  30530. X     fractype = JULIAFP;
  30531. X     usr_distest = (info->ydots - 1) * 2;
  30532. X     break;
  30533. X      case MANDELLAMBDA :
  30534. X     useinitorbit = 2;
  30535. X     break;
  30536. X      }
  30537. X   curfractalspecific = &fractalspecific[fractype];
  30538. X}
  30539. X
  30540. X/* switch old bifurcation fractal types to new generalizations */
  30541. Xvoid set_if_old_bif(void)
  30542. X{
  30543. X/* set functions if not set already, may need to check 'functionpreloaded'
  30544. X   before calling this routine.  JCO 7/5/92 */
  30545. X
  30546. X   ENTER_OVLY(OVLY_LOADFILE);
  30547. X   switch(fractype) {
  30548. X      case BIFURCATION:
  30549. X      case LBIFURCATION:
  30550. X      case BIFSTEWART:
  30551. X      case LBIFSTEWART:
  30552. X      case BIFLAMBDA:
  30553. X      case LBIFLAMBDA:
  30554. X        set_trig_array(0,"ident");
  30555. X        break;
  30556. X
  30557. X      case BIFEQSINPI:
  30558. X      case LBIFEQSINPI:
  30559. X      case BIFADSINPI:
  30560. X      case LBIFADSINPI:
  30561. X        set_trig_array(0,"sin");
  30562. X        break;
  30563. X   }
  30564. X   EXIT_OVLY;
  30565. X}
  30566. SHAR_EOF
  30567. $TOUCH -am 1028230093 loadfile.c &&
  30568. chmod 0644 loadfile.c ||
  30569. echo "restore of loadfile.c failed"
  30570. set `wc -c loadfile.c`;Wc_c=$1
  30571. if test "$Wc_c" != "22666"; then
  30572.     echo original size 22666, current size $Wc_c
  30573. fi
  30574. # ============= loadmap.c ==============
  30575. echo "x - extracting loadmap.c (Text)"
  30576. sed 's/^X//' << 'SHAR_EOF' > loadmap.c &&
  30577. X/** loadmap.c **/
  30578. X
  30579. X
  30580. X#include    <stdio.h>
  30581. X#include    <stdlib.h>
  30582. X#ifndef XFRACT
  30583. X#include    <dos.h>
  30584. X#endif
  30585. X#include    <string.h>
  30586. X#include    "fractint.h"
  30587. X#include    "prototyp.h"
  30588. X
  30589. Xtypedef struct palett {
  30590. X   BYTE red;
  30591. X   BYTE green;
  30592. X   BYTE blue;
  30593. X} Palettetype;
  30594. X
  30595. Xextern Palettetype    dacbox[ 256 ];
  30596. Xextern unsigned far    *tga16;
  30597. Xextern long    far    *tga32;
  30598. Xextern char    far    *mapdacbox;
  30599. Xextern int        colorstate; /* comments in cmdfiles */
  30600. Xextern char        colorfile[];
  30601. X
  30602. X/***************************************************************************/
  30603. X
  30604. Xvoid SetTgaColors() {
  30605. Xunsigned    r, g, b, index;
  30606. X    if (tga16 != NULL)
  30607. X    for( index = 0; index < 256; index++ ) {
  30608. X        r = dacbox[index].red    << 2;
  30609. X        g = dacbox[index].green << 2;
  30610. X        b = dacbox[index].blue    << 2;
  30611. X        tga16[index] = ((r&248)<<7) | ((g&248)<<2) | (b>>3);
  30612. X        tga32[index] = ((long)r<<16) | (g<<8) | b;
  30613. X    }
  30614. X}
  30615. X
  30616. Xint ValidateLuts( char * fn )
  30617. X{
  30618. XFILE * f;
  30619. Xunsigned    r, g, b, index;
  30620. XCHAR    line[160];
  30621. XCHAR    temp[81];
  30622. X    strcpy (temp,fn);
  30623. X    if (strchr(temp,'.') == NULL) /* Did name have an extension? */
  30624. X        strcat(temp,".map");  /* No? Then add .map */
  30625. X    findpath( temp, line);          /* search the dos path */
  30626. X    f = fopen( line, "r" );
  30627. X    if (f == NULL) {
  30628. X        sprintf(line,"Could not load color map %s",fn);
  30629. X        stopmsg(0,line);
  30630. X        return 1;
  30631. X        }
  30632. X    for( index = 0; index < 256; index++ ) {
  30633. X        if (fgets(line,100,f) == NULL)
  30634. X            break;
  30635. X        sscanf( line, "%u %u %u", &r, &g, &b );
  30636. X        /** load global dac values **/
  30637. X        dacbox[index].red   = (r%256) >> 2;    /* maps default to 8 bits */
  30638. X        dacbox[index].green = (g%256) >> 2;    /* DAC wants 6 bits */
  30639. X        dacbox[index].blue  = (b%256) >> 2;
  30640. X    }
  30641. X    fclose( f );
  30642. X    while (index < 256)  { /* zap unset entries */
  30643. X        dacbox[index].red = dacbox[index].blue = dacbox[index].green = 40;
  30644. X        ++index;
  30645. X    }
  30646. X    SetTgaColors();
  30647. X    colorstate = 2;
  30648. X    strcpy(colorfile,fn);
  30649. X    return 0;
  30650. X}
  30651. X
  30652. X
  30653. X/***************************************************************************/
  30654. X
  30655. Xint SetColorPaletteName( char * fn )
  30656. X{
  30657. X    if( ValidateLuts( fn ) != 0)
  30658. X        return 1;
  30659. X    if( mapdacbox == NULL && (mapdacbox = farmemalloc(768L)) == NULL) {
  30660. X        static char far msg[]={"Insufficient memory for color map."};
  30661. X        stopmsg(0,msg);
  30662. X        return 1;
  30663. X        }
  30664. X    far_memcpy((char far *)mapdacbox,(char far *)dacbox,768);
  30665. X    /* PB, 900829, removed atexit(RestoreMap) stuff, goodbye covers it */
  30666. X    return 0;
  30667. X}
  30668. X
  30669. X
  30670. SHAR_EOF
  30671. $TOUCH -am 1028230093 loadmap.c &&
  30672. chmod 0644 loadmap.c ||
  30673. echo "restore of loadmap.c failed"
  30674. set `wc -c loadmap.c`;Wc_c=$1
  30675. if test "$Wc_c" != "2268"; then
  30676.     echo original size 2268, current size $Wc_c
  30677. fi
  30678. # ============= lorenz.c ==============
  30679. echo "x - extracting lorenz.c (Text)"
  30680. sed 's/^X//' << 'SHAR_EOF' > lorenz.c &&
  30681. X/*
  30682. X   This file contains two 3 dimensional orbit-type fractal
  30683. X   generators - IFS and LORENZ3D, along with code to generate
  30684. X   red/blue 3D images. Tim Wegner
  30685. X*/
  30686. X
  30687. X#include <stdio.h>
  30688. X#include <stdlib.h>
  30689. X#include <float.h>
  30690. X#include <math.h>
  30691. X#include <string.h>
  30692. X#include "mpmath.h"
  30693. X#include "fractint.h"
  30694. X#include "fractype.h"
  30695. X#include "prototyp.h"
  30696. X
  30697. X#define RANDOM(x)  (rand()%(x))
  30698. X
  30699. X/* BAD_PIXEL is used to cutoff orbits that are diverging. It might be better
  30700. Xto test the actual floating point prbit values, but this seems safe for now.
  30701. XA higher value cannot be used - to test, turn off math coprocessor and
  30702. Xuse +2.24 for type ICONS. If BAD_PIXEL is set to 20000, this will abort
  30703. XFractint with a math error. Note that this approach precludes zooming in very
  30704. Xfar to an orbit type. */
  30705. X
  30706. X#define BAD_PIXEL  10000L    /* pixels can't get this big */
  30707. X
  30708. Xstruct affine
  30709. X{
  30710. X   /* weird order so a,b,e and c,d,f are vectors */
  30711. X   double a;
  30712. X   double b;
  30713. X   double e;
  30714. X   double c;
  30715. X   double d;
  30716. X   double f;
  30717. X};
  30718. Xstruct l_affine
  30719. X{
  30720. X   /* weird order so a,b,e and c,d,f are vectors */
  30721. X   long a;
  30722. X   long b;
  30723. X   long e;
  30724. X   long c;
  30725. X   long d;
  30726. X   long f;
  30727. X};
  30728. Xstruct long3dvtinf /* data used by 3d view transform subroutine */
  30729. X{
  30730. X   long ct;        /* iteration counter */
  30731. X   long orbit[3];    /* interated function orbit value */
  30732. X   long iview[3];    /* perspective viewer's coordinates */
  30733. X   long viewvect[3];    /* orbit transformed for viewing */
  30734. X   long viewvect1[3];    /* orbit transformed for viewing */
  30735. X   long maxvals[3];
  30736. X   long minvals[3];
  30737. X   MATRIX doublemat;    /* transformation matrix */
  30738. X   MATRIX doublemat1;    /* transformation matrix */
  30739. X   long longmat[4][4];    /* long version of matrix */
  30740. X   long longmat1[4][4]; /* long version of matrix */
  30741. X   int row,col;     /* results */
  30742. X   int row1,col1;
  30743. X   struct l_affine cvt;
  30744. X};
  30745. Xstruct float3dvtinf /* data used by 3d view transform subroutine */
  30746. X{
  30747. X   long ct;        /* iteration counter */
  30748. X   double orbit[3];           /* interated function orbit value */
  30749. X   double viewvect[3];          /* orbit transformed for viewing */
  30750. X   double viewvect1[3];        /* orbit transformed for viewing */
  30751. X   double maxvals[3];
  30752. X   double minvals[3];
  30753. X   MATRIX doublemat;    /* transformation matrix */
  30754. X   MATRIX doublemat1;    /* transformation matrix */
  30755. X   int row,col;     /* results */
  30756. X   int row1,col1;
  30757. X   struct affine cvt;
  30758. X};
  30759. X
  30760. X/* Routines in this module    */
  30761. X
  30762. Xstatic int  ifs3dlong(void);
  30763. Xstatic int  ifs3dfloat(void);
  30764. Xstatic double determinant(double mat[3][3]);
  30765. Xstatic int  solve3x3(double mat[3][3],double vec[3],double ans[3]);
  30766. Xextern int  setup_convert_to_screen(struct affine *);
  30767. Xstatic int  l_setup_convert_to_screen(struct l_affine *);
  30768. Xstatic void setupmatrix(MATRIX);
  30769. Xstatic int  long3dviewtransf(struct long3dvtinf *inf);
  30770. Xstatic int  float3dviewtransf(struct float3dvtinf *inf);
  30771. Xstatic FILE *open_orbitsave();
  30772. Xstatic void _fastcall plothist(int x, int y, int color);
  30773. Xextern char far insufficient_ifs_mem[];
  30774. Xextern int numaffine;
  30775. Xstatic int realtime;
  30776. Xextern int orbitsave;
  30777. Xstatic char orbitsavename[]    = {"orbits.raw"};
  30778. Xstatic char orbitsave_format[] = {"%g %g %g 15\n"};
  30779. Xextern int active_system;
  30780. Xextern int overflow;
  30781. Xextern int soundflag;
  30782. Xextern int basehertz;
  30783. Xextern int fractype;
  30784. Xextern int glassestype;
  30785. Xextern int whichimage;
  30786. Xextern int init3d[];
  30787. Xextern char floatflag;
  30788. Xextern VECTOR view;
  30789. Xextern int xxadjust, yyadjust;
  30790. Xextern int xxadjust1, yyadjust1;
  30791. Xextern int xshift,yshift;
  30792. Xextern int xshift1,yshift1;
  30793. Xextern int    debugflag;            /* for debugging purposes */
  30794. Xextern int    xdots, ydots;        /* coordinates of dots on the screen  */
  30795. Xextern int    maxit;                /* try this many iterations */
  30796. Xextern double param[];
  30797. Xextern double    xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners  */
  30798. Xextern    int    diskvideo;            /* for disk-video klooges */
  30799. Xextern int    bitshift;            /* bit shift for fudge */
  30800. Xextern long    fudge;                /* fudge factor (2**n) */
  30801. Xextern int    colors;             /* maximum colors available */
  30802. Xextern int display3d;
  30803. Xextern double dxsize,dysize,delxx,delxx2,delyy,delyy2;
  30804. X
  30805. Xextern float far *ifs_defn;
  30806. Xextern int ifs_type;
  30807. X
  30808. Xstatic int t;
  30809. Xstatic long l_dx,l_dy,l_dz,l_dt,l_a,l_b,l_c,l_d;
  30810. Xstatic long l_adt,l_bdt,l_cdt,l_xdt,l_ydt;
  30811. Xstatic long l_initx,l_inity,l_initz;
  30812. Xstatic long initorbitlong[3];
  30813. X
  30814. Xstatic double dx,dy,dz,dt,a,b,c,d;
  30815. Xstatic double adt,bdt,cdt,xdt,ydt,zdt;
  30816. Xstatic double initx,inity,initz;
  30817. Xstatic double initorbit[3];
  30818. Xextern int inside;
  30819. Xextern int outside;
  30820. Xextern int orbit_delay;
  30821. X
  30822. Xextern void (_fastcall * standardplot)(int,int,int);
  30823. Xextern int  calc_status, resuming;
  30824. Xextern int  diskisactive;
  30825. Xextern char savename[];
  30826. X
  30827. X/*
  30828. X * The following declarations used for Inverse Julia.  MVS
  30829. X */
  30830. X
  30831. Xextern int    Init_Queue      (unsigned long);
  30832. Xextern void   Free_Queue      (void);
  30833. Xextern void   ClearQueue      (void);
  30834. Xextern int    QueueEmpty      (void);
  30835. Xextern int    QueueFull       (void);
  30836. Xextern int    QueueFullAlmost (void);
  30837. Xextern int    PushLong        (long ,  long);
  30838. Xextern int    PushFloat       (float,  float);
  30839. Xextern int    EnQueueLong     (long ,  long);
  30840. Xextern int    EnQueueFloat    (float,  float);
  30841. Xextern LCMPLX PopLong         (void);
  30842. Xextern _CMPLX PopFloat        (void);
  30843. Xextern LCMPLX DeQueueLong     (void);
  30844. Xextern _CMPLX DeQueueFloat    (void);
  30845. Xextern LCMPLX ComplexSqrtLong (long ,  long);
  30846. Xextern _CMPLX ComplexSqrtFloat(double, double);
  30847. Xstatic char far NoQueue[] =
  30848. X  "Not enough memory: switching to random walk.\n";
  30849. X
  30850. Xstatic int    maxhits;
  30851. Xint    run_length;
  30852. Xenum   {breadth_first, depth_first, random_walk, random_run} major_method;
  30853. Xenum   {left_first, right_first}                             minor_method;
  30854. Xstruct affine cvt;
  30855. Xstruct l_affine lcvt;
  30856. X
  30857. Xextern _CMPLX  old,  new;
  30858. Xextern LCMPLX lold, lnew;
  30859. X
  30860. Xdouble Cx, Cy;
  30861. Xlong   CxLong, CyLong;
  30862. X
  30863. X/*
  30864. X * end of Inverse Julia declarations;
  30865. X */
  30866. X
  30867. X/* these are potential user parameters */
  30868. Xint connect = 1;    /* flag to connect points with a line */
  30869. Xint euler = 0;        /* use implicit euler approximation for dynamic system */
  30870. Xint waste = 100;    /* waste this many points before plotting */
  30871. Xint projection = 2; /* projection plane - default is to plot x-y */
  30872. X
  30873. X/******************************************************************/
  30874. X/*           zoom box conversion functions          */
  30875. X/******************************************************************/
  30876. X
  30877. Xstatic double determinant(mat) /* determinant of 3x3 matrix */
  30878. Xdouble mat[3][3];
  30879. X{
  30880. X   /* calculate determinant of 3x3 matrix */
  30881. X   return(mat[0][0]*mat[1][1]*mat[2][2] +
  30882. X      mat[0][2]*mat[1][0]*mat[2][1] +
  30883. X      mat[0][1]*mat[1][2]*mat[2][0] -
  30884. X      mat[2][0]*mat[1][1]*mat[0][2] -
  30885. X      mat[1][0]*mat[0][1]*mat[2][2] -
  30886. X      mat[0][0]*mat[1][2]*mat[2][1]);
  30887. X
  30888. X}
  30889. X
  30890. Xstatic int solve3x3(mat,vec,ans) /* solve 3x3 inhomogeneous linear equations */
  30891. Xdouble mat[3][3], vec[3], ans[3];
  30892. X{
  30893. X   /* solve 3x3 linear equation [mat][ans] = [vec] */
  30894. X   double denom;
  30895. X   double tmp[3][3];
  30896. X   int i;
  30897. X   denom = determinant(mat);
  30898. X   if(fabs(denom) < DBL_EPSILON) /* test if can solve */
  30899. X     return(-1);
  30900. X   memcpy(tmp,mat,sizeof(double)*9);
  30901. X   for(i=0;i<3;i++)
  30902. X   {
  30903. X      tmp[0][i] = vec[0];
  30904. X      tmp[1][i] = vec[1];
  30905. X      tmp[2][i] = vec[2];
  30906. X      ans[i]  =  determinant(tmp)/denom;
  30907. X      tmp[0][i] = mat[0][i];
  30908. X      tmp[1][i] = mat[1][i];
  30909. X      tmp[2][i] = mat[2][i];
  30910. X    }
  30911. X    return(0);
  30912. X}
  30913. X
  30914. X
  30915. X/* Conversion of complex plane to screen coordinates for rotating zoom box.
  30916. X   Assume there is an affine transformation mapping complex zoom parallelogram
  30917. X   to rectangular screen. We know this map must map parallelogram corners to
  30918. X   screen corners, so we have following equations:
  30919. X
  30920. X      a*xxmin+b*yymax+e == 0        (upper left)
  30921. X      c*xxmin+d*yymax+f == 0
  30922. X
  30923. X      a*xx3rd+b*yy3rd+e == 0        (lower left)
  30924. X      c*xx3rd+d*yy3rd+f == ydots-1
  30925. X
  30926. X      a*xxmax+b*yymin+e == xdots-1  (lower right)
  30927. X      c*xxmax+d*yymin+f == ydots-1
  30928. X
  30929. X      First we must solve for a,b,c,d,e,f - (which we do once per image),
  30930. X      then we just apply the transformation to each orbit value.
  30931. X*/
  30932. X
  30933. Xint setup_convert_to_screen(struct affine *scrn_cnvt)
  30934. X{
  30935. X   /* we do this twice - rather than having six equations with six unknowns,
  30936. X      everything partitions to two sets of three equations with three
  30937. X      unknowns. Nice, because who wants to calculate a 6x6 determinant??
  30938. X    */
  30939. X   double mat[3][3];
  30940. X   double vec[3];
  30941. X   /*
  30942. X      first these equations - solve for a,b,e
  30943. X      a*xxmin+b*yymax+e == 0        (upper left)
  30944. X      a*xx3rd+b*yy3rd+e == 0        (lower left)
  30945. X      a*xxmax+b*yymin+e == xdots-1  (lower right)
  30946. X   */
  30947. X   mat[0][0] = xxmin;
  30948. X   mat[0][1] = yymax;
  30949. X   mat[0][2] = 1.0;
  30950. X   mat[1][0] = xx3rd;
  30951. X   mat[1][1] = yy3rd;
  30952. X   mat[1][2] = 1.0;
  30953. X   mat[2][0] = xxmax;
  30954. X   mat[2][1] = yymin;
  30955. X   mat[2][2] = 1.0;
  30956. X   vec[0]    = 0.0;
  30957. X   vec[1]    = 0.0;
  30958. X   vec[2]    = (double)(xdots-1);
  30959. X
  30960. X   if(solve3x3(mat,vec, &(scrn_cnvt->a)))
  30961. X      return(-1);
  30962. X   /*
  30963. X      now solve these:
  30964. X      c*xxmin+d*yymax+f == 0
  30965. X      c*xx3rd+d*yy3rd+f == ydots-1
  30966. X      c*xxmax+d*yymin+f == ydots-1
  30967. X      (mat[][] has not changed - only vec[])
  30968. X   */
  30969. X   vec[0]    = 0.0;
  30970. X   vec[1]    = (double)(ydots-1);
  30971. X   vec[2]    = (double)(ydots-1);
  30972. X
  30973. X   if(solve3x3(mat,vec, &scrn_cnvt->c))
  30974. X      return(-1);
  30975. X   return(0);
  30976. X}
  30977. X
  30978. Xstatic int l_setup_convert_to_screen(struct l_affine *l_cvt)
  30979. X{
  30980. X   struct affine cvt;
  30981. X
  30982. X   /* MCP 7-7-91, This function should return a something! */
  30983. X   if(setup_convert_to_screen(&cvt))
  30984. X      return(-1);
  30985. X   l_cvt->a = cvt.a*fudge; l_cvt->b = cvt.b*fudge; l_cvt->c = cvt.c*fudge;
  30986. X   l_cvt->d = cvt.d*fudge; l_cvt->e = cvt.e*fudge; l_cvt->f = cvt.f*fudge;
  30987. X
  30988. X   /* MCP 7-7-91 */
  30989. X   return(0);
  30990. X}
  30991. X
  30992. X
  30993. X/******************************************************************/
  30994. X/*   setup functions - put in fractalspecific[fractype].per_image */
  30995. X/******************************************************************/
  30996. X
  30997. Xstatic double orbit;
  30998. Xstatic long   l_orbit;
  30999. X
  31000. Xextern double sinx,cosx;
  31001. Xstatic long l_sinx,l_cosx;
  31002. X
  31003. Xint orbit3dlongsetup()
  31004. X{
  31005. X   connect = 1;
  31006. X   waste = 100;
  31007. X   projection = 2;
  31008. X   if (fractype==LHENON || fractype==KAM || fractype==KAM3D || 
  31009. X       fractype==INVERSEJULIA)
  31010. X      connect=0;
  31011. X   if(fractype==LROSSLER)
  31012. X      waste = 500;
  31013. X   if(fractype==LLORENZ)
  31014. X      projection = 1;
  31015. X
  31016. X   initorbitlong[0] = fudge;  /* initial conditions */
  31017. X   initorbitlong[1] = fudge;
  31018. X   initorbitlong[2] = fudge;
  31019. X
  31020. X   if(fractype==LHENON)
  31021. X   {
  31022. X      l_a =  param[0]*fudge;
  31023. X      l_b =  param[1]*fudge;
  31024. X      l_c =  param[2]*fudge;
  31025. X      l_d =  param[3]*fudge;
  31026. X   }
  31027. X   else if(fractype==KAM || fractype==KAM3D)
  31028. X   {
  31029. X      a   = param[0];        /* angle */
  31030. X      if(param[1] <= 0.0)
  31031. X     param[1] = .01;
  31032. X      l_b =  param[1]*fudge;    /* stepsize */
  31033. X      l_c =  param[2]*fudge;    /* stop */
  31034. X      t = l_d =  param[3];     /* points per orbit */
  31035. X
  31036. X      l_sinx = sin(a)*fudge;
  31037. X      l_cosx = cos(a)*fudge;
  31038. X      l_orbit = 0;
  31039. X      initorbitlong[0] = initorbitlong[1] = initorbitlong[2] = 0;
  31040. X   }
  31041. X   else if (fractype == INVERSEJULIA)
  31042. X   {
  31043. X      LCMPLX Sqrt;
  31044. X
  31045. X      CxLong = param[0] * fudge;
  31046. X      CyLong = param[1] * fudge;
  31047. X
  31048. X      maxhits    = (int) param[2];
  31049. X      run_length = (int) param[3];
  31050. X      if (maxhits == 0)
  31051. X      maxhits = 1;
  31052. X      else if (maxhits >= colors)
  31053. X      maxhits = colors - 1;
  31054. X
  31055. X      setup_convert_to_screen(&cvt);
  31056. X      /* Note: using bitshift of 21 for affine, 24 otherwise */
  31057. X
  31058. X      lcvt.a = cvt.a * (1L << 21);
  31059. X      lcvt.b = cvt.b * (1L << 21);
  31060. X      lcvt.c = cvt.c * (1L << 21);
  31061. X      lcvt.d = cvt.d * (1L << 21);
  31062. X      lcvt.e = cvt.e * (1L << 21);
  31063. X      lcvt.f = cvt.f * (1L << 21);
  31064. X
  31065. X      Sqrt = ComplexSqrtLong(fudge - 4 * CxLong, -4 * CyLong);
  31066. X
  31067. X      switch (major_method) {
  31068. X     case breadth_first:
  31069. X        if (Init_Queue((long)32*1024) == 0)
  31070. X        { /* can't get queue memory: fall back to random walk */
  31071. X           stopmsg(20, NoQueue);
  31072. X           major_method = random_walk;
  31073. X           goto lrwalk;
  31074. X        }
  31075. X        EnQueueLong((fudge + Sqrt.x) / 2,  Sqrt.y / 2);
  31076. X        EnQueueLong((fudge - Sqrt.x) / 2, -Sqrt.y / 2);
  31077. X        break;
  31078. X     case depth_first:
  31079. X        if (Init_Queue((long)32*1024) == 0)
  31080. X        { /* can't get queue memory: fall back to random walk */
  31081. X           stopmsg(20, NoQueue);
  31082. X           major_method = random_walk;
  31083. X           goto lrwalk;
  31084. X        }
  31085. X        switch (minor_method) {
  31086. X           case left_first:
  31087. X          PushLong((fudge + Sqrt.x) / 2,  Sqrt.y / 2);
  31088. X          PushLong((fudge - Sqrt.x) / 2, -Sqrt.y / 2);
  31089. X          break;
  31090. X           case right_first:
  31091. X          PushLong((fudge - Sqrt.x) / 2, -Sqrt.y / 2);
  31092. X          PushLong((fudge + Sqrt.x) / 2,  Sqrt.y / 2);
  31093. X          break;
  31094. X        }
  31095. X        break;
  31096. X     case random_walk:
  31097. Xlrwalk:
  31098. X        lnew.x = initorbitlong[0] = fudge + Sqrt.x / 2;
  31099. X        lnew.y = initorbitlong[1] =         Sqrt.y / 2;
  31100. X        break;
  31101. X     case random_run:
  31102. X        lnew.x = initorbitlong[0] = fudge + Sqrt.x / 2;
  31103. X        lnew.y = initorbitlong[1] =         Sqrt.y / 2;
  31104. X        break;
  31105. X      }
  31106. X   }
  31107. X   else
  31108. X   {
  31109. X      l_dt = param[0]*fudge;
  31110. X      l_a =  param[1]*fudge;
  31111. X      l_b =  param[2]*fudge;
  31112. X      l_c =  param[3]*fudge;
  31113. X   }
  31114. X
  31115. X   /* precalculations for speed */
  31116. X   l_adt = multiply(l_a,l_dt,bitshift);
  31117. X   l_bdt = multiply(l_b,l_dt,bitshift);
  31118. X   l_cdt = multiply(l_c,l_dt,bitshift);
  31119. X   return(1);
  31120. X}
  31121. X
  31122. Xint orbit3dfloatsetup()
  31123. X{
  31124. X   connect = 1;
  31125. X   waste = 100;
  31126. X   projection = 2;
  31127. X
  31128. X   if(fractype==FPHENON || fractype==FPPICKOVER || fractype==FPGINGERBREAD
  31129. X        || fractype == KAMFP || fractype == KAM3DFP
  31130. X        || fractype == FPHOPALONG || fractype == INVERSEJULIAFP)
  31131. X      connect=0;
  31132. X   if(fractype==FPLORENZ3D1 || fractype==FPLORENZ3D3 ||
  31133. X      fractype==FPLORENZ3D4)
  31134. X      waste = 750;
  31135. X   if(fractype==FPROSSLER)
  31136. X      waste = 500;
  31137. X   if(fractype==FPLORENZ)
  31138. X      projection = 1; /* plot x and z */
  31139. X
  31140. X   initorbit[0] = 1;  /* initial conditions */
  31141. X   initorbit[1] = 1;
  31142. X   initorbit[2] = 1;
  31143. X   if(fractype==FPGINGERBREAD)
  31144. X   {
  31145. X      initorbit[0] = param[0];    /* initial conditions */
  31146. X      initorbit[1] = param[1];
  31147. X   }
  31148. X
  31149. X   if(fractype==ICON || fractype==ICON3D)        /* DMF */
  31150. X   {
  31151. X      initorbit[0] = 0.01;  /* initial conditions */
  31152. X      initorbit[1] = 0.003;
  31153. X      connect = 0;
  31154. X      waste = 2000;
  31155. X   }
  31156. X
  31157. X   if(fractype==FPHENON || fractype==FPPICKOVER)
  31158. X   {
  31159. X      a =  param[0];
  31160. X      b =  param[1];
  31161. X      c =  param[2];
  31162. X      d =  param[3];
  31163. X   }
  31164. X   else if(fractype==ICON || fractype==ICON3D)        /* DMF */
  31165. X   {
  31166. X      initorbit[0] = 0.01;  /* initial conditions */
  31167. X      initorbit[1] = 0.003;
  31168. X      connect = 0;
  31169. X      waste = 2000;
  31170. X      /* Initialize parameters */
  31171. X      a  =   param[0];
  31172. X      b  =   param[1];
  31173. X      c  =   param[2];
  31174. X      d  =   param[3];
  31175. X   }
  31176. X   else if(fractype==KAMFP || fractype==KAM3DFP)
  31177. X   {
  31178. X      a = param[0];          /* angle */
  31179. X      if(param[1] <= 0.0)
  31180. X     param[1] = .01;
  31181. X      b =  param[1];    /* stepsize */
  31182. X      c =  param[2];    /* stop */
  31183. X      t = l_d =  param[3];     /* points per orbit */
  31184. X      sinx = sin(a);
  31185. X      cosx = cos(a);
  31186. X      orbit = 0;
  31187. X      initorbit[0] = initorbit[1] = initorbit[2] = 0;
  31188. X   }
  31189. X   else if(fractype==FPHOPALONG || fractype==FPMARTIN)
  31190. X   {
  31191. X      initorbit[0] = 0;  /* initial conditions */
  31192. X      initorbit[1] = 0;
  31193. X      initorbit[2] = 0;
  31194. X      connect = 0;
  31195. X      a =  param[0];
  31196. X      b =  param[1];
  31197. X      c =  param[2];
  31198. X      d =  param[3];
  31199. X   }
  31200. X   else if (fractype == INVERSEJULIAFP)
  31201. X   {
  31202. X      _CMPLX Sqrt;
  31203. X
  31204. X      Cx = param[0];
  31205. X      Cy = param[1];
  31206. X
  31207. X      maxhits    = (int) param[2];
  31208. X      run_length = (int) param[3];
  31209. X      if (maxhits == 0)
  31210. X      maxhits = 1;
  31211. X      else if (maxhits >= colors)
  31212. X      maxhits = colors - 1;
  31213. X
  31214. X      setup_convert_to_screen(&cvt);
  31215. X
  31216. X      /* find fixed points: guaranteed to be in the set */
  31217. X      Sqrt = ComplexSqrtFloat(1 - 4 * Cx, -4 * Cy);
  31218. X      switch ((int) major_method) {
  31219. X     case breadth_first:
  31220. X        if (Init_Queue((long)32*1024) == 0)
  31221. X        { /* can't get queue memory: fall back to random walk */
  31222. X           stopmsg(20, NoQueue);
  31223. X           major_method = random_walk;
  31224. X           goto rwalk;
  31225. X        }
  31226. X        EnQueueFloat((1 + Sqrt.x) / 2,  Sqrt.y / 2);
  31227. X        EnQueueFloat((1 - Sqrt.x) / 2, -Sqrt.y / 2);
  31228. X        break;
  31229. X     case depth_first:            /* depth first (choose direction) */
  31230. X        if (Init_Queue((long)32*1024) == 0)
  31231. X        { /* can't get queue memory: fall back to random walk */
  31232. X           stopmsg(20, NoQueue);
  31233. X           major_method = random_walk;
  31234. X           goto rwalk;
  31235. X        }
  31236. X        switch (minor_method) {
  31237. X           case left_first:
  31238. X          PushFloat((1 + Sqrt.x) / 2,  Sqrt.y / 2);
  31239. X          PushFloat((1 - Sqrt.x) / 2, -Sqrt.y / 2);
  31240. X          break;
  31241. X           case right_first:
  31242. X          PushFloat((1 - Sqrt.x) / 2, -Sqrt.y / 2);
  31243. X          PushFloat((1 + Sqrt.x) / 2,  Sqrt.y / 2);
  31244. X          break;
  31245. X        }
  31246. X        break;
  31247. X     case random_walk:
  31248. Xrwalk:
  31249. X        new.x = initorbit[0] = 1 + Sqrt.x / 2;
  31250. X        new.y = initorbit[1] = Sqrt.y / 2;
  31251. X        break;
  31252. X     case random_run:    /* random run, choose intervals */
  31253. X        major_method = random_run;
  31254. X        new.x = initorbit[0] = 1 + Sqrt.x / 2;
  31255. X        new.y = initorbit[1] = Sqrt.y / 2;
  31256. X        break;
  31257. X      }
  31258. X   }
  31259. X   else
  31260. X   {
  31261. X      dt = param[0];
  31262. X      a =  param[1];
  31263. X      b =  param[2];
  31264. X      c =  param[3];
  31265. X
  31266. X   }
  31267. X
  31268. X   /* precalculations for speed */
  31269. X   adt = a*dt;
  31270. X   bdt = b*dt;
  31271. X   cdt = c*dt;
  31272. X
  31273. X   return(1);
  31274. X}
  31275. X
  31276. X/******************************************************************/
  31277. X/*   orbit functions - put in fractalspecific[fractype].orbitcalc */
  31278. X/******************************************************************/
  31279. X
  31280. X/* Julia sets by inverse iterations added by Juan J. Buhler 4/3/92 */
  31281. X/* Integrated with Lorenz by Tim Wegner 7/20/92 */
  31282. X/* Add Modified Inverse Iteration Method, 11/92 by Michael Snyder  */
  31283. X
  31284. Xint
  31285. XMinverse_julia_orbit()
  31286. X{
  31287. X   static int   random_dir = 0, random_len = 0;
  31288. X   int    newrow, newcol;
  31289. X   int    color,  leftright;
  31290. X
  31291. X   /*
  31292. X    * First, compute new point
  31293. X    */
  31294. X   switch (major_method) {
  31295. X      case breadth_first:
  31296. X     if (QueueEmpty())
  31297. X        return -1;
  31298. X     new = DeQueueFloat();
  31299. X     break;
  31300. X      case depth_first:
  31301. X     if (QueueEmpty())
  31302. X        return -1;
  31303. X     new = PopFloat();
  31304. X     break;
  31305. X      case random_walk:
  31306. X#if 0
  31307. X     new = ComplexSqrtFloat(new.x - Cx, new.y - Cy);
  31308. X     if (RANDOM(2))
  31309. X     {
  31310. X        new.x = -new.x;
  31311. X        new.y = -new.y;
  31312. X     }
  31313. X#endif
  31314. X     break;
  31315. X      case random_run:
  31316. X#if 0
  31317. X     new = ComplexSqrtFloat(new.x - Cx, new.y - Cy);
  31318. X     if (random_len == 0)
  31319. X     {
  31320. X        random_len = RANDOM(run_length);
  31321. X        random_dir = RANDOM(3);
  31322. X     }
  31323. X     switch (random_dir) {
  31324. X        case 0:    /* left */
  31325. X           break;
  31326. X        case 1:    /* right */
  31327. X           new.x = -new.x;
  31328. X           new.y = -new.y;
  31329. X           break;
  31330. X        case 2:    /* random direction */
  31331. X           if (RANDOM(2))
  31332. X           {
  31333. X          new.x = -new.x;
  31334. X          new.y = -new.y;
  31335. X           }
  31336. X           break;
  31337. X     }
  31338. X#endif
  31339. X     break;
  31340. X   }
  31341. X
  31342. X   /*
  31343. X    * Next, find its pixel position
  31344. X    */
  31345. X   newcol = cvt.a * new.x + cvt.b * new.y + cvt.e;
  31346. X   newrow = cvt.c * new.x + cvt.d * new.y + cvt.f;
  31347. X
  31348. X   /*
  31349. X    * Now find the next point(s), and flip a coin to choose one.
  31350. X    */
  31351. X
  31352. X   new       = ComplexSqrtFloat(new.x - Cx, new.y - Cy);
  31353. X   leftright = (RANDOM(2)) ? 1 : -1;
  31354. X
  31355. X   if (newcol < 1 || newcol >= xdots || newrow < 1 || newrow >= ydots)
  31356. X   {
  31357. X      /*
  31358. X       * MIIM must skip points that are off the screen boundary,
  31359. X       * since it cannot read their color.
  31360. X       */
  31361. X      switch (major_method) {
  31362. X     case breadth_first:
  31363. X        EnQueueFloat(leftright * new.x, leftright * new.y);
  31364. X        return 1;
  31365. X     case depth_first:
  31366. X        PushFloat   (leftright * new.x, leftright * new.y);
  31367. X        return 1;
  31368. X     case random_run:
  31369. X     case random_walk:
  31370. X        break;
  31371. X      }
  31372. X   }
  31373. X
  31374. X   /*
  31375. X    * Read the pixel's color:
  31376. X    * For MIIM, if color >= maxhits, discard the point
  31377. X    *           else put the point's children onto the queue
  31378. X    */
  31379. X   color  = getcolor(newcol, newrow);
  31380. X   switch (major_method) {
  31381. X      case breadth_first:
  31382. X     if (color < maxhits)
  31383. X     {
  31384. X        putcolor(newcol, newrow, color+1);
  31385. X/*        new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); */
  31386. X        EnQueueFloat( new.x,  new.y);
  31387. X        EnQueueFloat(-new.x, -new.y);
  31388. X     }
  31389. X     break;
  31390. X      case depth_first:
  31391. X     if (color < maxhits)
  31392. X     {
  31393. X        putcolor(newcol, newrow, color+1);
  31394. X/*        new = ComplexSqrtFloat(new.x - Cx, new.y - Cy); */
  31395. X        if (minor_method == left_first)
  31396. X        {
  31397. X           if (QueueFullAlmost())
  31398. X          PushFloat(-new.x, -new.y);
  31399. X           else
  31400. X           {
  31401. X          PushFloat( new.x,  new.y);
  31402. X          PushFloat(-new.x, -new.y);
  31403. X           }
  31404. X        }
  31405. X        else
  31406. X        {
  31407. X           if (QueueFullAlmost())
  31408. X          PushFloat( new.x,  new.y);
  31409. X           else
  31410. X           {
  31411. X          PushFloat(-new.x, -new.y);
  31412. X          PushFloat( new.x,  new.y);
  31413. X           }
  31414. X        }
  31415. X     }
  31416. X     break;
  31417. X      case random_run:
  31418. X     if (random_len-- == 0)
  31419. X     {
  31420. X        random_len = RANDOM(run_length);
  31421. X        random_dir = RANDOM(3);
  31422. X     }
  31423. X     switch (random_dir) {
  31424. X        case 0:    /* left */
  31425. X           break;
  31426. X        case 1:    /* right */
  31427. X           new.x = -new.x;
  31428. X           new.y = -new.y;
  31429. X           break;
  31430. X        case 2:    /* random direction */
  31431. X           new.x = leftright * new.x;
  31432. X           new.y = leftright * new.y;
  31433. X           break;
  31434. X     }
  31435. X     if (color < colors-1)
  31436. X        putcolor(newcol, newrow, color+1);
  31437. X     break;
  31438. X      case random_walk:
  31439. X     if (color < colors-1)
  31440. X        putcolor(newcol, newrow, color+1);
  31441. X     new.x = leftright * new.x;
  31442. X     new.y = leftright * new.y;
  31443. X     break;
  31444. X   }
  31445. X   return 1;
  31446. X
  31447. X}
  31448. X
  31449. Xint
  31450. XLinverse_julia_orbit()
  31451. X{
  31452. X   static int   random_dir = 0, random_len = 0;
  31453. X   int    newrow, newcol;
  31454. X   int    color;
  31455. X
  31456. X   /*
  31457. X    * First, compute new point
  31458. X    */
  31459. X   switch (major_method) {
  31460. X      case breadth_first:
  31461. X     if (QueueEmpty())
  31462. X        return -1;
  31463. X     lnew = DeQueueLong();
  31464. X     break;
  31465. X      case depth_first:
  31466. X     if (QueueEmpty())
  31467. X        return -1;
  31468. X     lnew = PopLong();
  31469. X     break;
  31470. X      case random_walk:
  31471. X     lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong);
  31472. X     if (RANDOM(2))
  31473. X     {
  31474. X        lnew.x = -lnew.x;
  31475. X        lnew.y = -lnew.y;
  31476. X     }
  31477. X     break;
  31478. X      case random_run:
  31479. X     lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong);
  31480. X     if (random_len == 0)
  31481. X     {
  31482. X        random_len = RANDOM(run_length);
  31483. X        random_dir = RANDOM(3);
  31484. X     }
  31485. X     switch (random_dir) {
  31486. X        case 0:    /* left */
  31487. X           break;
  31488. X        case 1:    /* right */
  31489. X           lnew.x = -lnew.x;
  31490. X           lnew.y = -lnew.y;
  31491. X           break;
  31492. X        case 2:    /* random direction */
  31493. X           if (RANDOM(2))
  31494. X           {
  31495. X          lnew.x = -lnew.x;
  31496. X          lnew.y = -lnew.y;
  31497. X           }
  31498. X           break;
  31499. X     }
  31500. X   }
  31501. X
  31502. X   /*
  31503. X    * Next, find its pixel position
  31504. X    *
  31505. X    * Note: had to use a bitshift of 21 for this operation because
  31506. X    * otherwise the values of lcvt were truncated.  Used bitshift
  31507. X    * of 24 otherwise, for increased precision.
  31508. X    */
  31509. X   newcol = (multiply(lcvt.a, lnew.x >> (bitshift - 21), 21) +
  31510. X         multiply(lcvt.b, lnew.y >> (bitshift - 21), 21) + lcvt.e) >> 21;
  31511. X   newrow = (multiply(lcvt.c, lnew.x >> (bitshift - 21), 21) +
  31512. X         multiply(lcvt.d, lnew.y >> (bitshift - 21), 21) + lcvt.f) >> 21;
  31513. X
  31514. X   if (newcol < 1 || newcol >= xdots || newrow < 1 || newrow >= ydots)
  31515. X   {
  31516. X      /*
  31517. X       * MIIM must skip points that are off the screen boundary,
  31518. X       * since it cannot read their color.
  31519. X       */
  31520. X      if (RANDOM(2))
  31521. X     color =  1;
  31522. X      else
  31523. X     color = -1;
  31524. X      switch (major_method) {
  31525. X     case breadth_first:
  31526. X        lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong);
  31527. X        EnQueueLong(color * lnew.x, color * lnew.y);
  31528. X        break;
  31529. X     case depth_first:
  31530. X        lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong);
  31531. X        PushLong(color * lnew.x, color * lnew.y);
  31532. X        break;
  31533. X     case random_run:
  31534. X        random_len--;
  31535. X     case random_walk:
  31536. X        break;
  31537. X      }
  31538. X      return 1;
  31539. X   }
  31540. X
  31541. X   /*
  31542. X    * Read the pixel's color:
  31543. X    * For MIIM, if color >= maxhits, discard the point
  31544. X    *           else put the point's children onto the queue
  31545. X    */
  31546. X   color  = getcolor(newcol, newrow);
  31547. X   switch (major_method) {
  31548. X      case breadth_first:
  31549. X     if (color < maxhits)
  31550. X     {
  31551. X        putcolor(newcol, newrow, color+1);
  31552. X        lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong);
  31553. X        EnQueueLong( lnew.x,  lnew.y);
  31554. X        EnQueueLong(-lnew.x, -lnew.y);
  31555. X     }
  31556. X     break;
  31557. X      case depth_first:
  31558. X     if (color < maxhits)
  31559. X     {
  31560. X        putcolor(newcol, newrow, color+1);
  31561. X        lnew = ComplexSqrtLong(lnew.x - CxLong, lnew.y - CyLong);
  31562. X        if (minor_method == left_first)
  31563. X        {
  31564. X           if (QueueFullAlmost())
  31565. X          PushLong(-lnew.x, -lnew.y);
  31566. X           else
  31567. X           {
  31568. X          PushLong( lnew.x,  lnew.y);
  31569. X          PushLong(-lnew.x, -lnew.y);
  31570. X           }
  31571. X        }
  31572. X        else
  31573. X        {
  31574. X           if (QueueFullAlmost())
  31575. X          PushLong( lnew.x,  lnew.y);
  31576. X           else
  31577. X           {
  31578. X          PushLong(-lnew.x, -lnew.y);
  31579. X          PushLong( lnew.x,  lnew.y);
  31580. X           }
  31581. X        }
  31582. X     }
  31583. X     break;
  31584. X      case random_run:
  31585. X     random_len--;
  31586. X     /* fall through */
  31587. X      case random_walk:
  31588. X     if (color < colors-1)
  31589. X        putcolor(newcol, newrow, color+1);
  31590. X     break;
  31591. X   }
  31592. X   return 1;
  31593. X}
  31594. X
  31595. X#if 0
  31596. Xint inverse_julia_orbit(double *x, double *y, double *z)
  31597. X{
  31598. X   double r, xo, yo;
  31599. X   int waste;
  31600. X   if(*z >= 1.0) /* this assumes intial value is 1.0!!! */
  31601. X   {
  31602. X      waste = 20; /* skip these points at first */
  31603. X      *z = 0;
  31604. X   }
  31605. X   else
  31606. X      waste = 1;
  31607. X   while(waste--)
  31608. X   {
  31609. X      xo = *x - param[0]; 
  31610. X      yo = *y - param[1];
  31611. X      r  = sqrt(xo*xo + yo*yo);
  31612. X      *x  = sqrt((r + xo)/2);
  31613. X      if (yo < 0)
  31614. X         *x = - *x;
  31615. X      *y = sqrt((r - xo)/2);
  31616. X      if(RANDOM(10) > 4)
  31617. X      {
  31618. X          *x = -(*x);
  31619. X          *y = -(*y);
  31620. X      }
  31621. X   }
  31622. X   return(0);
  31623. X}
  31624. X#endif
  31625. X
  31626. Xint lorenz3dlongorbit(long *l_x, long *l_y, long *l_z)
  31627. X{
  31628. X      l_xdt = multiply(*l_x,l_dt,bitshift);
  31629. X      l_ydt = multiply(*l_y,l_dt,bitshift);
  31630. X      l_dx  = -multiply(l_adt,*l_x,bitshift) + multiply(l_adt,*l_y,bitshift);
  31631. X      l_dy  =  multiply(l_bdt,*l_x,bitshift) -l_ydt -multiply(*l_z,l_xdt,bitshift);
  31632. X      l_dz  = -multiply(l_cdt,*l_z,bitshift) + multiply(*l_x,l_ydt,bitshift);
  31633. X
  31634. X      *l_x += l_dx;
  31635. X      *l_y += l_dy;
  31636. X      *l_z += l_dz;
  31637. X      return(0);
  31638. X}
  31639. X
  31640. Xint lorenz3d1floatorbit(double *x, double *y, double *z)
  31641. X{
  31642. X      double norm;
  31643. X
  31644. X      xdt = (*x)*dt;
  31645. X      ydt = (*y)*dt;
  31646. X      zdt = (*z)*dt;
  31647. X
  31648. X      /* 1-lobe Lorenz */
  31649. X      norm = sqrt((*x)*(*x)+(*y)*(*y));
  31650. X      dx   = (-adt-dt)*(*x) + (adt-bdt)*(*y) + (dt-adt)*norm + ydt*(*z);
  31651. X      dy   = (bdt-adt)*(*x) - (adt+dt)*(*y) + (bdt+adt)*norm - xdt*(*z) -
  31652. X         norm*zdt;
  31653. X      dz   = (ydt/2) - cdt*(*z);
  31654. X
  31655. X      *x += dx;
  31656. X      *y += dy;
  31657. X      *z += dz;
  31658. X      return(0);
  31659. X}
  31660. X
  31661. Xint lorenz3dfloatorbit(double *x, double *y, double *z)
  31662. X{
  31663. X      xdt = (*x)*dt;
  31664. X      ydt = (*y)*dt;
  31665. X      zdt = (*z)*dt;
  31666. X
  31667. X      /* 2-lobe Lorenz (the original) */
  31668. X      dx  = -adt*(*x) + adt*(*y);
  31669. X      dy  =  bdt*(*x) - ydt - (*z)*xdt;
  31670. X      dz  = -cdt*(*z) + (*x)*ydt;
  31671. X
  31672. X      *x += dx;
  31673. X      *y += dy;
  31674. X      *z += dz;
  31675. X      return(0);
  31676. X}
  31677. X
  31678. Xint lorenz3d3floatorbit(double *x, double *y, double *z)
  31679. X{
  31680. X      double norm;
  31681. X
  31682. X      xdt = (*x)*dt;
  31683. X      ydt = (*y)*dt;
  31684. X      zdt = (*z)*dt;
  31685. X
  31686. X      /* 3-lobe Lorenz */
  31687. X      norm = sqrt((*x)*(*x)+(*y)*(*y));
  31688. X      dx   = (-(adt+dt)*(*x) + (adt-bdt+zdt)*(*y)) / 3 +
  31689. X         ((dt-adt)*((*x)*(*x)-(*y)*(*y)) +
  31690. X         2*(bdt+adt-zdt)*(*x)*(*y))/(3*norm);
  31691. X      dy   = ((bdt-adt-zdt)*(*x) - (adt+dt)*(*y)) / 3 +
  31692. X         (2*(adt-dt)*(*x)*(*y) +
  31693. X         (bdt+adt-zdt)*((*x)*(*x)-(*y)*(*y)))/(3*norm);
  31694. X      dz   = (3*xdt*(*x)*(*y)-ydt*(*y)*(*y))/2 - cdt*(*z);
  31695. X
  31696. X      *x += dx;
  31697. X      *y += dy;
  31698. X      *z += dz;
  31699. X      return(0);
  31700. X}
  31701. X
  31702. Xint lorenz3d4floatorbit(double *x, double *y, double *z)
  31703. X{
  31704. X      xdt = (*x)*dt;
  31705. X      ydt = (*y)*dt;
  31706. X      zdt = (*z)*dt;
  31707. X
  31708. X      /* 4-lobe Lorenz */
  31709. X      dx   = (-adt*(*x)*(*x)*(*x) + (2*adt+bdt-zdt)*(*x)*(*x)*(*y) +
  31710. X         (adt-2*dt)*(*x)*(*y)*(*y) + (zdt-bdt)*(*y)*(*y)*(*y)) /
  31711. X         (2 * ((*x)*(*x)+(*y)*(*y)));
  31712. X      dy   = ((bdt-zdt)*(*x)*(*x)*(*x) + (adt-2*dt)*(*x)*(*x)*(*y) +
  31713. X         (-2*adt-bdt+zdt)*(*x)*(*y)*(*y) - adt*(*y)*(*y)*(*y)) /
  31714. X         (2 * ((*x)*(*x)+(*y)*(*y)));
  31715. X      dz   = (2*xdt*(*x)*(*x)*(*y) - 2*xdt*(*y)*(*y)*(*y) - cdt*(*z));
  31716. X
  31717. X      *x += dx;
  31718. X      *y += dy;
  31719. X      *z += dz;
  31720. X      return(0);
  31721. X}
  31722. X
  31723. Xint henonfloatorbit(double *x, double *y, double *z)
  31724. X{
  31725. X      double newx,newy;
  31726. X      newx  = 1 + *y - a*(*x)*(*x);
  31727. X      newy  = b*(*x);
  31728. X      *x = newx;
  31729. X      *y = newy;
  31730. X      return(0);
  31731. X}
  31732. X
  31733. Xint henonlongorbit(long *l_x, long *l_y, long *l_z)
  31734. X{
  31735. X      long newx,newy;
  31736. X      newx = multiply(*l_x,*l_x,bitshift);
  31737. X      newx = multiply(newx,l_a,bitshift);
  31738. X      newx  = fudge + *l_y - newx;
  31739. X      newy  = multiply(l_b,*l_x,bitshift);
  31740. X      *l_x = newx;
  31741. X      *l_y = newy;
  31742. X      return(0);
  31743. X}
  31744. X
  31745. Xint rosslerfloatorbit(double *x, double *y, double *z)
  31746. X{
  31747. X      xdt = (*x)*dt;
  31748. X      ydt = (*y)*dt;
  31749. X
  31750. X      dx = -ydt - (*z)*dt;
  31751. X      dy = xdt + (*y)*adt;
  31752. X      dz = bdt + (*z)*xdt - (*z)*cdt;
  31753. X
  31754. X      *x += dx;
  31755. X      *y += dy;
  31756. X      *z += dz;
  31757. X      return(0);
  31758. X}
  31759. X
  31760. Xint pickoverfloatorbit(double *x, double *y, double *z)
  31761. X{
  31762. X      double newx,newy,newz;
  31763. X      newx = sin(a*(*y)) - (*z)*cos(b*(*x));
  31764. X      newy = (*z)*sin(c*(*x)) - cos(d*(*y));
  31765. X      newz = sin(*x);
  31766. X      *x = newx;
  31767. X      *y = newy;
  31768. X      *z = newz;
  31769. X      return(0);
  31770. X}
  31771. X/* page 149 "Science of Fractal Images" */
  31772. Xint gingerbreadfloatorbit(double *x, double *y, double *z)
  31773. X{
  31774. X      double newx;
  31775. X      newx = 1 - (*y) + fabs(*x);
  31776. X      *y = *x;
  31777. X      *x = newx;
  31778. X      return(0);
  31779. X}
  31780. X
  31781. Xint rosslerlongorbit(long *l_x, long *l_y, long *l_z)
  31782. X{
  31783. X      l_xdt = multiply(*l_x,l_dt,bitshift);
  31784. X      l_ydt = multiply(*l_y,l_dt,bitshift);
  31785. X
  31786. X      l_dx  = -l_ydt - multiply(*l_z,l_dt,bitshift);
  31787. X      l_dy  =  l_xdt + multiply(*l_y,l_adt,bitshift);
  31788. X      l_dz  =  l_bdt + multiply(*l_z,l_xdt,bitshift)
  31789. X             - multiply(*l_z,l_cdt,bitshift);
  31790. X
  31791. X      *l_x += l_dx;
  31792. X      *l_y += l_dy;
  31793. X      *l_z += l_dz;
  31794. X
  31795. X      return(0);
  31796. X}
  31797. X
  31798. X/* OSTEP  = Orbit Step (and inner orbit value) */
  31799. X/* NTURNS = Outside Orbit */
  31800. X/* TURN2  = Points per orbit */
  31801. X/* a      = Angle */
  31802. X
  31803. X
  31804. Xint kamtorusfloatorbit(double *r, double *s, double *z)
  31805. X{
  31806. X   double srr;
  31807. X   if(t++ >= l_d)
  31808. X   {
  31809. X      orbit += b;
  31810. X      (*r) = (*s) = orbit/3;
  31811. X      t = 0;
  31812. X      *z = orbit;
  31813. X      if(orbit > c)
  31814. X     return(1);
  31815. X   }
  31816. X   srr = (*s)-(*r)*(*r);
  31817. X   (*s)=(*r)*sinx+srr*cosx;
  31818. X   (*r)=(*r)*cosx-srr*sinx;
  31819. X   return(0);
  31820. X}
  31821. X
  31822. Xint kamtoruslongorbit(long *r, long *s, long *z)
  31823. X{
  31824. X   long srr;
  31825. X   if(t++ >= l_d)
  31826. X   {
  31827. X      l_orbit += l_b;
  31828. X      (*r) = (*s) = l_orbit/3;
  31829. X      t = 0;
  31830. X      *z = l_orbit;
  31831. X      if(l_orbit > l_c)
  31832. X     return(1);
  31833. X   }
  31834. X   srr = (*s)-multiply((*r),(*r),bitshift);
  31835. X   (*s)=multiply((*r),l_sinx,bitshift)+multiply(srr,l_cosx,bitshift);
  31836. X   (*r)=multiply((*r),l_cosx,bitshift)-multiply(srr,l_sinx,bitshift);
  31837. X   return(0);
  31838. X}
  31839. X/*#define sign(x) ((x)>0?1:((x)<0?(-1):0))*/
  31840. X#define sign(x) ((x)>=0?1:-1)
  31841. Xint hopalong2dfloatorbit(double *x, double *y, double *z)
  31842. X{
  31843. X   double tmp;
  31844. X   tmp = *y - sign(*x)*sqrt(fabs(b*(*x)-c));
  31845. X   *y = a - *x;
  31846. X   *x = tmp;
  31847. X   return(0);
  31848. X}
  31849. X
  31850. Xint martin2dfloatorbit(double *x, double *y, double *z)
  31851. X{
  31852. X   double tmp;
  31853. X   tmp = *y - sin(*x);
  31854. X   *y = a - *x;
  31855. X   *x = tmp;
  31856. X   return(0);
  31857. X}
  31858. X
  31859. Xint mandelcloudfloat(double *x, double *y, double *z)
  31860. X{
  31861. X    double newx,newy,x2,y2;
  31862. X    x2 = (*x)*(*x);
  31863. X    y2 = (*y)*(*y);
  31864. X    if (x2+y2>2) return 1;
  31865. X    newx = x2-y2+a;
  31866. X    newy = 2*(*x)*(*y)+b;
  31867. X    *x = newx;
  31868. X    *y = newy;
  31869. X    return(0);
  31870. X}
  31871. X
  31872. Xint dynamfloat(double *x, double *y, double *z)
  31873. X{
  31874. X      _CMPLX cp,tmp;
  31875. X      double newx,newy;
  31876. X      cp.x = b* *x;
  31877. X      cp.y = 0;
  31878. X      CMPLXtrig0(cp, tmp);
  31879. X      newy = *y + dt*sin(*x + a*tmp.x);
  31880. X      if (euler) {
  31881. X      *y = newy;
  31882. X      }
  31883. X
  31884. X      cp.x = b* *y;
  31885. X      cp.y = 0;
  31886. X      CMPLXtrig0(cp, tmp);
  31887. X      newx = *x - dt*sin(*y + a*tmp.x);
  31888. X      *x = newx;
  31889. X      *y = newy;
  31890. X      return(0);
  31891. X}
  31892. X
  31893. X/* dmf */
  31894. X#undef  LAMBDA
  31895. X#define LAMBDA  param[0]
  31896. X#define ALPHA   param[1]
  31897. X#define BETA    param[2]
  31898. X#define GAMMA   param[3]
  31899. X#define OMEGA   param[4]
  31900. X#define DEGREE  param[5]
  31901. X
  31902. Xint iconfloatorbit(double *x, double *y, double *z)
  31903. X{
  31904. X
  31905. X    double oldx, oldy, zzbar, zreal, zimag, za, zb, zn, p;
  31906. X    unsigned char i;
  31907. X
  31908. X    oldx = *x;
  31909. X    oldy = *y;
  31910. X
  31911. X    zzbar = oldx * oldx + oldy * oldy;
  31912. X    zreal = oldx;
  31913. X    zimag = oldy;
  31914. X
  31915. X    for(i=1; i <= DEGREE-2; i++) {
  31916. X        za = zreal * oldx - zimag * oldy;
  31917. X        zb = zimag * oldx + zreal * oldy;
  31918. X        zreal = za;
  31919. X        zimag = zb;
  31920. X    }
  31921. X    zn = oldx * zreal - oldy * zimag;
  31922. X    p = LAMBDA + ALPHA * zzbar + BETA * zn;
  31923. X    *x = p * oldx + GAMMA * zreal - OMEGA * oldy;
  31924. X    *y = p * oldy - GAMMA * zimag + OMEGA * oldx;
  31925. X
  31926. X/*    if (fractype==ICON3D) */
  31927. X    *z = zzbar; 
  31928. X    return(0);
  31929. X}
  31930. X#ifdef LAMBDA  /* Tim says this will make me a "good citizen" */
  31931. X#undef LAMBDA  /* Yeah, but you were bad, Dan - LAMBDA was already */
  31932. X#undef ALPHA   /* defined! <grin!> TW */
  31933. X#undef BETA
  31934. X#undef GAMMA
  31935. X#endif
  31936. X/**********************************************************************/
  31937. X/*   Main fractal engines - put in fractalspecific[fractype].calctype */
  31938. X/**********************************************************************/
  31939. X
  31940. Xint inverse_julia_per_image()
  31941. X{
  31942. X   int color = 0;
  31943. X
  31944. X   if (resuming)            /* can't resume */
  31945. X      return -1;
  31946. X
  31947. X   while (color >= 0)       /* generate points */
  31948. X   {
  31949. X      if (check_key())
  31950. X      {
  31951. X     Free_Queue();
  31952. X     return -1;
  31953. X      }
  31954. X      color = curfractalspecific->orbitcalc();
  31955. X      old = new;
  31956. X   }
  31957. X   Free_Queue();
  31958. X   return 0;
  31959. X}
  31960. X
  31961. Xint orbit2dfloat()
  31962. X{
  31963. X   FILE *fp;
  31964. X   double *soundvar;
  31965. X   double x,y,z;
  31966. X   int color,col,row;
  31967. X   int count;
  31968. X   int oldrow, oldcol;
  31969. X   double *p0,*p1,*p2;
  31970. X   struct affine cvt;
  31971. X   int ret,start;
  31972. X   start = 1;
  31973. X   
  31974. X   fp = open_orbitsave();
  31975. X   /* setup affine screen coord conversion */
  31976. X   setup_convert_to_screen(&cvt);
  31977. X
  31978. X   /* set up projection scheme */
  31979. X   if(projection==0)
  31980. X   {
  31981. X      p0 = &z;
  31982. X      p1 = &x;
  31983. X      p2 = &y;
  31984. X   }
  31985. X   else if(projection==1)
  31986. X   {
  31987. X      p0 = &x;
  31988. X      p1 = &z;
  31989. X      p2 = &y;
  31990. X   }
  31991. X   else if(projection==2)
  31992. X   {
  31993. X      p0 = &x;
  31994. X      p1 = &y;
  31995. X      p2 = &z;
  31996. X   }
  31997. X   if(soundflag==1)
  31998. X      soundvar = &x;
  31999. X   else if(soundflag==2)
  32000. X      soundvar = &y;
  32001. X   else if(soundflag==3)
  32002. X      soundvar = &z;
  32003. X
  32004. X   count = 0;
  32005. X   if(inside > 0)
  32006. X      color = inside;
  32007. X   if(color >= colors)
  32008. X      color = 1;
  32009. X   oldcol = oldrow = -1;
  32010. X   x = initorbit[0];
  32011. X   y = initorbit[1];
  32012. X   z = initorbit[2];
  32013. X
  32014. X   if (resuming)
  32015. X   {
  32016. X      start_resume();
  32017. X      get_resume(sizeof(count),&count,sizeof(color),&color,
  32018. X          sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol,
  32019. X          sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,
  32020. X          sizeof(t),&t,sizeof(orbit),&orbit,
  32021. X          0);
  32022. X      end_resume();
  32023. X   }
  32024. X
  32025. X   ret = 0;
  32026. X   while(1)
  32027. X   {
  32028. X      if(check_key())
  32029. X      {
  32030. X         nosnd();
  32031. X         alloc_resume(100,1);
  32032. X         put_resume(sizeof(count),&count,sizeof(color),&color,
  32033. X             sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol,
  32034. X             sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,
  32035. X             sizeof(t),&t,sizeof(orbit),&orbit,
  32036. X             0);
  32037. X         ret = -1;
  32038. X         break;
  32039. X      }
  32040. X
  32041. X      if (++count > 1000)
  32042. X      {        /* time to switch colors? */
  32043. X         count = 0;
  32044. X         if (++color >= colors)   /* another color to switch to? */
  32045. X        color = 1;  /* (don't use the background color) */
  32046. X      }
  32047. X
  32048. X      col = cvt.a*x + cvt.b*y + cvt.e;
  32049. X      row = cvt.c*x + cvt.d*y + cvt.f;
  32050. X      if ( col >= 0 && col < xdots && row >= 0 && row < ydots )
  32051. X      {
  32052. X         if (soundflag > 0)
  32053. X            snd((int)(*soundvar*100+basehertz));
  32054. X/* dmf */
  32055. X         if(fractype!=ICON)
  32056. X         {
  32057. X         if(oldcol != -1 && connect)
  32058. X            draw_line(col,row,oldcol,oldrow,color&(colors-1));
  32059. X            else
  32060. X            (*plot)(col,row,color&(colors-1));
  32061. X         } else {
  32062. X            /* should this be using plothist()? */
  32063. X            color = getcolor(col,row)+1;
  32064. X            if( color < colors ) /* color sticks on last value */
  32065. X               (*plot)(col,row,color);
  32066. X
  32067. X         }
  32068. X
  32069. X         oldcol = col;
  32070. X         oldrow = row;
  32071. X         start = 0;
  32072. X      }
  32073. X      else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */
  32074. X         return(ret);
  32075. X      else   
  32076. X         oldrow = oldcol = -1;
  32077. X
  32078. X      if(curfractalspecific->orbitcalc(p0, p1, p2))
  32079. X         break;
  32080. X      if(fp)
  32081. X         fprintf(fp,orbitsave_format,*p0,*p1,0.0);
  32082. X   }
  32083. X   if(fp)
  32084. X      fclose(fp);
  32085. X   return(ret);
  32086. X}
  32087. X
  32088. Xint orbit2dlong()
  32089. X{
  32090. X   FILE *fp;
  32091. X   long *soundvar;
  32092. X   long x,y,z;
  32093. X   int color,col,row;
  32094. X   int count;
  32095. X   int oldrow, oldcol;
  32096. X   long *p0,*p1,*p2;
  32097. X   struct l_affine cvt;
  32098. X   int ret,start;
  32099. X   start = 1;
  32100. X   fp = open_orbitsave();
  32101. X
  32102. X   /* setup affine screen coord conversion */
  32103. X   l_setup_convert_to_screen(&cvt);
  32104. X
  32105. X   /* set up projection scheme */
  32106. X   if(projection==0)
  32107. X   {
  32108. X      p0 = &z;
  32109. X      p1 = &x;
  32110. X      p2 = &y;
  32111. X   }
  32112. X   else if(projection==1)
  32113. X   {
  32114. X      p0 = &x;
  32115. X      p1 = &z;
  32116. X      p2 = &y;
  32117. X   }
  32118. X   else if(projection==2)
  32119. X   {
  32120. X      p0 = &x;
  32121. X      p1 = &y;
  32122. X      p2 = &z;
  32123. X   }
  32124. X   if(soundflag==1)
  32125. X      soundvar = &x;
  32126. X   else if(soundflag==2)
  32127. X      soundvar = &y;
  32128. X   else if(soundflag==3)
  32129. X      soundvar = &z;
  32130. X   count = 0;
  32131. X   if(inside > 0)
  32132. X      color = inside;
  32133. X   if(color >= colors)
  32134. X      color = 1;
  32135. X   oldcol = oldrow = -1;
  32136. X   x = initorbitlong[0];
  32137. X   y = initorbitlong[1];
  32138. X   z = initorbitlong[2];
  32139. X
  32140. X   if (resuming)
  32141. X   {
  32142. X      start_resume();
  32143. X      get_resume(sizeof(count),&count,sizeof(color),&color,
  32144. X          sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol,
  32145. X          sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,
  32146. X          sizeof(t),&t,sizeof(l_orbit),&l_orbit,
  32147. X          0);
  32148. X      end_resume();
  32149. X   }
  32150. X
  32151. X   ret = 0;
  32152. X   while(1)
  32153. X   {
  32154. X      if(check_key())
  32155. X      {
  32156. X         nosnd();
  32157. X         alloc_resume(100,1);
  32158. X         put_resume(sizeof(count),&count,sizeof(color),&color,
  32159. X         sizeof(oldrow),&oldrow,sizeof(oldcol),&oldcol,
  32160. X             sizeof(x),&x,sizeof(y),&y,sizeof(z),&z,
  32161. X             sizeof(t),&t,sizeof(l_orbit),&l_orbit,
  32162. X             0);
  32163. X         ret = -1;
  32164. X         break;
  32165. X      }
  32166. X      if (++count > 1000)
  32167. X      {        /* time to switch colors? */
  32168. X         count = 0;
  32169. X         if (++color >= colors)   /* another color to switch to? */
  32170. X            color = 1;  /* (don't use the background color) */
  32171. X      }
  32172. X
  32173. X      col = (multiply(cvt.a,x,bitshift) + multiply(cvt.b,y,bitshift) + cvt.e) >> bitshift;
  32174. X      row = (multiply(cvt.c,x,bitshift) + multiply(cvt.d,y,bitshift) + cvt.f) >> bitshift;
  32175. X      if(overflow)
  32176. X      {
  32177. X         overflow = 0;
  32178. X         return(ret);
  32179. X      }
  32180. X      if ( col >= 0 && col < xdots && row >= 0 && row < ydots )
  32181. X      {
  32182. X         if (soundflag > 0)
  32183. X         {
  32184. X            double yy;
  32185. X            yy = *soundvar;
  32186. X            yy = yy/fudge;
  32187. X            snd((int)(yy*100+basehertz));
  32188. X         }
  32189. X         if(oldcol != -1 && connect)
  32190. X            draw_line(col,row,oldcol,oldrow,color&(colors-1));
  32191. X         else if(!start)
  32192. X            (*plot)(col,row,color&(colors-1));
  32193. X         oldcol = col;
  32194. X         oldrow = row;
  32195. X         start = 0;
  32196. X      }
  32197. X      else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */
  32198. X         return(ret);
  32199. X      else   
  32200. X     oldrow = oldcol = -1;
  32201. X
  32202. X      /* Calculate the next point */
  32203. X      if(curfractalspecific->orbitcalc(p0, p1, p2))
  32204. X         break;
  32205. X      if(fp)
  32206. X         fprintf(fp,orbitsave_format,(double)*p0/fudge,(double)*p1/fudge,0.0);
  32207. X   }
  32208. X   if(fp)
  32209. X      fclose(fp);
  32210. X   return(ret);
  32211. X}
  32212. X
  32213. Xint orbit3dlongcalc()
  32214. X{
  32215. X   FILE *fp;
  32216. X   unsigned count;
  32217. X   int oldcol,oldrow;
  32218. X   int oldcol1,oldrow1;
  32219. X   struct long3dvtinf inf;
  32220. X   unsigned long maxct;
  32221. X   int color;
  32222. X   int ret;
  32223. X
  32224. X   /* setup affine screen coord conversion */
  32225. X   l_setup_convert_to_screen(&inf.cvt);
  32226. X
  32227. X   oldcol1 = oldrow1 = oldcol = oldrow = -1;
  32228. X   color = 2;
  32229. X   if(color >= colors)
  32230. X      color = 1;
  32231. X
  32232. X   inf.orbit[0] = initorbitlong[0];
  32233. X   inf.orbit[1] = initorbitlong[1];
  32234. X   inf.orbit[2] = initorbitlong[2];
  32235. X
  32236. X   if(diskvideo)                /* this would KILL a disk drive! */
  32237. X      notdiskmsg();
  32238. X
  32239. X   fp = open_orbitsave();
  32240. X
  32241. X   /* make maxct a function of screen size               */
  32242. X   maxct = maxit*40L;
  32243. X   count = inf.ct = 0L;
  32244. X   ret = 0;
  32245. X   while(inf.ct++ < maxct) /* loop until keypress or maxit */
  32246. X   {
  32247. X      /* calc goes here */
  32248. X      if (++count > 1000)
  32249. X      {        /* time to switch colors? */
  32250. X         count = 0;
  32251. X         if (++color >= colors)   /* another color to switch to? */
  32252. X            color = 1;        /* (don't use the background color) */
  32253. X      }
  32254. X      if(check_key())
  32255. X      {
  32256. X         nosnd();
  32257. X         ret = -1;
  32258. X         break;
  32259. X      }
  32260. X
  32261. X      curfractalspecific->orbitcalc(&inf.orbit[0],&inf.orbit[1],&inf.orbit[2]);
  32262. X      if(fp)
  32263. X         fprintf(fp,orbitsave_format,(double)inf.orbit[0]/fudge,(double)inf.orbit[1]/fudge,(double)inf.orbit[2]/fudge);
  32264. X      if (long3dviewtransf(&inf))
  32265. X      {
  32266. X         /* plot if inside window */
  32267. X         if (inf.col >= 0)
  32268. X         {
  32269. X            if(realtime)
  32270. X               whichimage=1;
  32271. X            if (soundflag > 0)
  32272. X            {
  32273. X               double yy;
  32274. X               yy = inf.viewvect[soundflag-1];
  32275. X               yy = yy/fudge;
  32276. X               snd((int)(yy*100+basehertz));
  32277. X            }
  32278. X            if(oldcol != -1 && connect)
  32279. X               draw_line(inf.col,inf.row,oldcol,oldrow,color&(colors-1));
  32280. X            else
  32281. X               (*plot)(inf.col,inf.row,color&(colors-1));
  32282. X         }
  32283. X         else if (inf.col == -2)
  32284. X            return(ret);
  32285. X         oldcol = inf.col;
  32286. X         oldrow = inf.row;
  32287. X         if(realtime)
  32288. X         {
  32289. X            whichimage=2;
  32290. X            /* plot if inside window */
  32291. X            if (inf.col1 >= 0)
  32292. X            {
  32293. X               if(oldcol1 != -1 && connect)
  32294. X                  draw_line(inf.col1,inf.row1,oldcol1,oldrow1,color&(colors-1));
  32295. X               else
  32296. X                  (*plot)(inf.col1,inf.row1,color&(colors-1));
  32297. X            }
  32298. X            else if (inf.col1 == -2)
  32299. X               return(ret);
  32300. X            oldcol1 = inf.col1;
  32301. X            oldrow1 = inf.row1;
  32302. X         }
  32303. X      }
  32304. X   }
  32305. X   if(fp)
  32306. X      fclose(fp);
  32307. X   return(ret);
  32308. X}
  32309. X
  32310. X
  32311. Xint orbit3dfloatcalc()
  32312. X{
  32313. X   FILE *fp;
  32314. X   unsigned count;
  32315. X   int oldcol,oldrow;
  32316. X   int oldcol1,oldrow1;
  32317. X   extern int init3d[];
  32318. X   unsigned long maxct;
  32319. X   int color;
  32320. X   int ret;
  32321. X   struct float3dvtinf inf;
  32322. X
  32323. X   /* setup affine screen coord conversion */
  32324. X   setup_convert_to_screen(&inf.cvt);
  32325. X
  32326. X   oldcol = oldrow = -1;
  32327. X   oldcol1 = oldrow1 = -1;
  32328. X   color = 2;
  32329. X   if(color >= colors)
  32330. X      color = 1;
  32331. X   inf.orbit[0] = initorbit[0];
  32332. X   inf.orbit[1] = initorbit[1];
  32333. X   inf.orbit[2] = initorbit[2];
  32334. X
  32335. X   if(diskvideo)                /* this would KILL a disk drive! */
  32336. X      notdiskmsg();
  32337. X
  32338. X   fp = open_orbitsave();
  32339. X
  32340. X   maxct = maxit*40L;
  32341. X   count = inf.ct = 0L;
  32342. X   ret = 0;
  32343. X   while(inf.ct++ < maxct) /* loop until keypress or maxit */
  32344. X   {
  32345. X      /* calc goes here */
  32346. X      if (++count > 1000)
  32347. X      {        /* time to switch colors? */
  32348. X         count = 0;
  32349. X         if (++color >= colors)   /* another color to switch to? */
  32350. X            color = 1;        /* (don't use the background color) */
  32351. X      }
  32352. X
  32353. X      if(check_key())
  32354. X      {
  32355. X         nosnd();
  32356. X         ret = -1;
  32357. X         break;
  32358. X      }
  32359. X
  32360. X      curfractalspecific->orbitcalc(&inf.orbit[0],&inf.orbit[1],&inf.orbit[2]);
  32361. X      if(fp)
  32362. X         fprintf(fp,orbitsave_format,inf.orbit[0],inf.orbit[1],inf.orbit[2]);
  32363. X      if (float3dviewtransf(&inf))
  32364. X      {
  32365. X         /* plot if inside window */
  32366. X         if (inf.col >= 0)
  32367. X         {
  32368. X        if(realtime)
  32369. X               whichimage=1;
  32370. X            if (soundflag > 0)
  32371. X               snd((int)(inf.viewvect[soundflag-1]*100+basehertz));
  32372. X            if(oldcol != -1 && connect)
  32373. X               draw_line(inf.col,inf.row,oldcol,oldrow,color&(colors-1));
  32374. X            else
  32375. X               (*plot)(inf.col,inf.row,color&(colors-1));
  32376. X         }
  32377. X         else if (inf.col == -2)
  32378. X            return(ret);
  32379. X         oldcol = inf.col;
  32380. X         oldrow = inf.row;
  32381. X         if(realtime)
  32382. X         {
  32383. X            whichimage=2;
  32384. X            /* plot if inside window */
  32385. X            if (inf.col1 >= 0)
  32386. X            {
  32387. X               if(oldcol1 != -1 && connect)
  32388. X                  draw_line(inf.col1,inf.row1,oldcol1,oldrow1,color&(colors-1));
  32389. X               else
  32390. X                  (*plot)(inf.col1,inf.row1,color&(colors-1));
  32391. X            }
  32392. X            else if (inf.col1 == -2)
  32393. X               return(ret);
  32394. X            oldcol1 = inf.col1;
  32395. X            oldrow1 = inf.row1;
  32396. X         }
  32397. X      }
  32398. X   }
  32399. X   if(fp)
  32400. X      fclose(fp);
  32401. X   return(ret);
  32402. X}
  32403. X
  32404. Xint dynam2dfloatsetup()
  32405. X{
  32406. X   connect = 0;
  32407. X   euler = 0;
  32408. X   d = param[0]; /* number of intervals */
  32409. X   if (d<0) {
  32410. X      d = -d;
  32411. X      connect = 1;
  32412. X   } 
  32413. X   else if (d==0) {
  32414. X      d = 1;
  32415. X   }
  32416. X   if (fractype==DYNAMICFP) {
  32417. X       a = param[2]; /* parameter */
  32418. X       b = param[3]; /* parameter */
  32419. X       dt = param[1]; /* step size */
  32420. X       if (dt<0) {
  32421. X      dt = -dt;
  32422. X      euler = 1;
  32423. X       }
  32424. X       if (dt==0) dt = 0.01;
  32425. X   }
  32426. X   if (outside == -5) {
  32427. X       plot = plothist;
  32428. X   }
  32429. X   return(1);
  32430. X}
  32431. X
  32432. X/*
  32433. X * This is the routine called to perform a time-discrete dynamical
  32434. X * system image.
  32435. X * The starting positions are taken by stepping across the image in steps
  32436. X * of parameter1 pixels.  maxit differential equation steps are taken, with
  32437. X * a step size of parameter2.
  32438. X */
  32439. Xint dynam2dfloat()
  32440. X{
  32441. X   FILE *fp;
  32442. X   double *soundvar;
  32443. X   double x,y,z;
  32444. X   int color,col,row;
  32445. X   int count;
  32446. X   int oldrow, oldcol;
  32447. X   double *p0,*p1;
  32448. X   struct affine cvt;
  32449. X   int ret;
  32450. X   int xstep, ystep; /* The starting position step number */
  32451. X   double xpixel, ypixel; /* Our pixel position on the screen */
  32452. X
  32453. X   fp = open_orbitsave();
  32454. X   /* setup affine screen coord conversion */
  32455. X   setup_convert_to_screen(&cvt);
  32456. X
  32457. X   p0 = &x;
  32458. X   p1 = &y;
  32459. X
  32460. X
  32461. X   if(soundflag==1)
  32462. X      soundvar = &x;
  32463. X   else if(soundflag==2)
  32464. X      soundvar = &y;
  32465. X   else if(soundflag==3)
  32466. X      soundvar = &z;
  32467. X
  32468. X   count = 0;
  32469. X   if(inside > 0)
  32470. X      color = inside;
  32471. X   if(color >= colors)
  32472. X      color = 1;
  32473. X   oldcol = oldrow = -1;
  32474. X
  32475. X   xstep = -1;
  32476. X   ystep = 0;
  32477. X
  32478. X   if (resuming) {
  32479. X       start_resume();
  32480. X       get_resume(sizeof(count),&count, sizeof(color),&color,
  32481. X         sizeof(oldrow),&oldrow, sizeof(oldcol),&oldcol,
  32482. X         sizeof(x),&x, sizeof(y), &y, sizeof(xstep), &xstep,
  32483. X         sizeof(ystep), &ystep, 0);
  32484. X       end_resume();
  32485. X   }
  32486. X
  32487. X   ret = 0;
  32488. X   while(1)
  32489. X   {
  32490. X      if(check_key())
  32491. X      {
  32492. X         nosnd();
  32493. X         alloc_resume(100,1);
  32494. X         put_resume(sizeof(count),&count, sizeof(color),&color,
  32495. X             sizeof(oldrow),&oldrow, sizeof(oldcol),&oldcol,
  32496. X             sizeof(x),&x, sizeof(y), &y, sizeof(xstep), &xstep,
  32497. X             sizeof(ystep), &ystep, 0);
  32498. X         ret = -1;
  32499. X         break;
  32500. X      }
  32501. X
  32502. X      xstep ++;
  32503. X      if (xstep>=d) {
  32504. X      xstep = 0;
  32505. X      ystep ++;
  32506. X      if (ystep>d) {
  32507. X          nosnd();
  32508. X          ret = -1;
  32509. X          break;
  32510. X      }
  32511. X      }
  32512. X
  32513. X      xpixel = dxsize*(xstep+.5)/d;
  32514. X      ypixel = dysize*(ystep+.5)/d;
  32515. X      x = (xxmin+delxx*xpixel) + (delxx2*ypixel);
  32516. X      y = (yymax-delyy*ypixel) + (-delyy2*xpixel);
  32517. X      if (fractype==MANDELCLOUD) {
  32518. X      a = x;
  32519. X      b = y;
  32520. X      }
  32521. X      oldcol = -1;
  32522. X
  32523. X      if (++color >= colors)   /* another color to switch to? */
  32524. X      color = 1;    /* (don't use the background color) */
  32525. X
  32526. X      for (count=0;count<maxit;count++) {
  32527. X
  32528. X      col = cvt.a*x + cvt.b*y + cvt.e;
  32529. X      row = cvt.c*x + cvt.d*y + cvt.f;
  32530. X      if ( col >= 0 && col < xdots && row >= 0 && row < ydots )
  32531. X      {
  32532. X         if (soundflag > 0)
  32533. X           snd((int)(*soundvar*100+basehertz));
  32534. X
  32535. X         if (count>=orbit_delay) {
  32536. X         if(oldcol != -1 && connect)
  32537. X            draw_line(col,row,oldcol,oldrow,color&(colors-1));
  32538. X         else if(count > 0 || fractype != MANDELCLOUD)
  32539. X            (*plot)(col,row,color&(colors-1));
  32540. X         }
  32541. X         oldcol = col;
  32542. X         oldrow = row;
  32543. X      }
  32544. X      else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */
  32545. X            return(ret);
  32546. X      else
  32547. X         oldrow = oldcol = -1;
  32548. X
  32549. X      if(curfractalspecific->orbitcalc(p0, p1, NULL))
  32550. X         break;
  32551. X      if(fp)
  32552. X          fprintf(fp,orbitsave_format,*p0,*p1,0.0);
  32553. X    }
  32554. X   }
  32555. X   if(fp)
  32556. X      fclose(fp);
  32557. X   return(ret);
  32558. X}
  32559. X
  32560. X/* this function's only purpose is to manage funnyglasses related */
  32561. X/* stuff so the code is not duplicated for ifs3d() and lorenz3d() */
  32562. Xint funny_glasses_call(int (*calc)())
  32563. X{
  32564. X   int status;
  32565. X   status = 0;
  32566. X   if(glassestype)
  32567. X      whichimage = 1;
  32568. X   else
  32569. X      whichimage = 0;
  32570. X   plot_setup();
  32571. X   plot = standardplot;
  32572. X   status = calc();
  32573. X   if(realtime && glassestype != 3)
  32574. X   {
  32575. X      realtime = 0;
  32576. X      return(status);
  32577. X   }
  32578. X   if(glassestype && status == 0 && display3d)
  32579. X   {
  32580. X      if(glassestype==3) /* photographer's mode */
  32581. X     if(active_system == 0) { /* dos version */
  32582. X        int i;
  32583. Xstatic char far firstready[]={"\
  32584. XFirst image (left eye) is ready.  Hit any key to see it,\n\
  32585. Xthen hit <s> to save, hit any other key to create second image."};
  32586. X        stopmsg(16,firstready);
  32587. X        while ((i = getakey()) == 's' || i == 'S') {
  32588. X           diskisactive = 1;
  32589. X           savetodisk(savename);
  32590. X           diskisactive = 0;
  32591. X           }
  32592. X        /* is there a better way to clear the screen in graphics mode? */
  32593. X        setvideomode(videoentry.videomodeax,
  32594. X        videoentry.videomodebx,
  32595. X        videoentry.videomodecx,
  32596. X        videoentry.videomodedx);
  32597. X     }
  32598. X     else {           /* Windows version */
  32599. Xstatic char far firstready2[]={"First (Left Eye) image is complete"};
  32600. X        stopmsg(0,firstready2);
  32601. X        clear_screen();
  32602. X        }
  32603. X      whichimage = 2;
  32604. X      plot_setup();
  32605. X      plot = standardplot;
  32606. X      /* is there a better way to clear the graphics screen ? */
  32607. X      if(status = calc())
  32608. X     return(status);
  32609. X      if(glassestype==3) /* photographer's mode */
  32610. X     if(active_system == 0) { /* dos version */
  32611. Xstatic char far secondready[]={"Second image (right eye) is ready"};
  32612. X        stopmsg(16,secondready);
  32613. X     }
  32614. X   }
  32615. X   return(status);
  32616. X}
  32617. X
  32618. X/* double version - mainly for testing */
  32619. Xstatic int ifs3dfloat()
  32620. X{
  32621. X   int color_method;
  32622. X   FILE *fp;
  32623. X   unsigned long maxct;
  32624. X   int color;
  32625. X
  32626. X   double newx,newy,newz,r,sum;
  32627. X
  32628. X   int k;
  32629. X   int ret;
  32630. X
  32631. X   struct float3dvtinf inf;
  32632. X
  32633. X   float far *ffptr;
  32634. X
  32635. X   /* setup affine screen coord conversion */
  32636. X   setup_convert_to_screen(&inf.cvt);
  32637. X   srand(1);
  32638. X   color_method = param[0];
  32639. X   if(diskvideo)                /* this would KILL a disk drive! */
  32640. X      notdiskmsg();
  32641. X
  32642. X   inf.orbit[0] = 0;
  32643. X   inf.orbit[1] = 0;
  32644. X   inf.orbit[2] = 0;
  32645. X
  32646. X   fp = open_orbitsave();
  32647. X
  32648. X   maxct = maxit*40L;
  32649. X   inf.ct = 0L;
  32650. X   ret = 0;
  32651. X   while(inf.ct++ < maxct) /* loop until keypress or maxit */
  32652. X   {
  32653. X      if( check_key() )  /* keypress bails out */
  32654. X      {
  32655. X     ret = -1;
  32656. X     break;
  32657. X      }
  32658. X      r = rand15();     /* generate fudged random number between 0 and 1 */
  32659. X      r /= 32767;
  32660. X
  32661. X      /* pick which iterated function to execute, weighted by probability */
  32662. X      sum = ifs_defn[12]; /* [0][12] */
  32663. X      k = 0;
  32664. X      while ( sum < r)
  32665. X      {
  32666. X     k++;
  32667. X     sum += ifs_defn[k*IFS3DPARM+12];
  32668. X     if (ifs_defn[(k+1)*IFS3DPARM+12] == 0) break; /* for safety */
  32669. X      }
  32670. X
  32671. X      /* calculate image of last point under selected iterated function */
  32672. X      ffptr = ifs_defn + k*IFS3DPARM; /* point to first parm in row */
  32673. X      newx = *ffptr * inf.orbit[0] +
  32674. X         *(ffptr+1) * inf.orbit[1] +
  32675. X         *(ffptr+2) * inf.orbit[2] + *(ffptr+9);
  32676. X      newy = *(ffptr+3) * inf.orbit[0] +
  32677. X         *(ffptr+4) * inf.orbit[1] +
  32678. X         *(ffptr+5) * inf.orbit[2] + *(ffptr+10);
  32679. X      newz = *(ffptr+6) * inf.orbit[0] +
  32680. X         *(ffptr+7) * inf.orbit[1] +
  32681. X         *(ffptr+8) * inf.orbit[2] + *(ffptr+11);
  32682. X
  32683. X      inf.orbit[0] = newx;
  32684. X      inf.orbit[1] = newy;
  32685. X      inf.orbit[2] = newz;
  32686. X      if(fp)
  32687. X      fprintf(fp,orbitsave_format,newx,newy,newz);
  32688. X      if (float3dviewtransf(&inf))
  32689. X      {
  32690. X     /* plot if inside window */
  32691. X     if (inf.col >= 0)
  32692. X     {
  32693. X        if(realtime)
  32694. X           whichimage=1;
  32695. X            if(color_method)
  32696. X               color = (k&(colors-1))+1;
  32697. X            else
  32698. X        color = getcolor(inf.col,inf.row)+1;
  32699. X        if( color < colors ) /* color sticks on last value */
  32700. X           (*plot)(inf.col,inf.row,color);
  32701. X     }
  32702. X         else if (inf.col == -2)
  32703. X            return(ret);
  32704. X     if(realtime)
  32705. X     {
  32706. X        whichimage=2;
  32707. X        /* plot if inside window */
  32708. X        if (inf.col1 >= 0)
  32709. X        {
  32710. X              if(color_method)
  32711. X                 color = (k&(colors-1))+1;
  32712. X              else
  32713. X            color = getcolor(inf.col1,inf.row1)+1;
  32714. X            if( color < colors ) /* color sticks on last value */
  32715. X          (*plot)(inf.col1,inf.row1,color);
  32716. X        }
  32717. X        else if (inf.col1 == -2)
  32718. X               return(ret);
  32719. X     }
  32720. X      }
  32721. X   } /* end while */
  32722. X   if(fp)
  32723. X      fclose(fp);
  32724. X   return(ret);
  32725. X}
  32726. X
  32727. Xint ifs()            /* front-end for ifs2d and ifs3d */
  32728. X{
  32729. X   if (ifs_defn == NULL && ifsload() < 0)
  32730. X      return(-1);
  32731. X   if(diskvideo)                /* this would KILL a disk drive! */
  32732. X      notdiskmsg();
  32733. X   return((ifs_type == 0) ? ifs2d() : ifs3d());
  32734. X}
  32735. X
  32736. X
  32737. X/* IFS logic shamelessly converted to integer math */
  32738. Xint ifs2d()
  32739. X{
  32740. X   int color_method;
  32741. X   FILE *fp;
  32742. X   unsigned long maxct,ct;
  32743. X   int col;
  32744. X   int row;
  32745. X   int color;
  32746. X   int ret;
  32747. X   long far *localifs;
  32748. X   long far *lfptr;
  32749. X   long x,y,newx,newy,r,sum, tempr;
  32750. X
  32751. X   int i,j,k;
  32752. X   struct l_affine cvt;
  32753. X   /* setup affine screen coord conversion */
  32754. X   l_setup_convert_to_screen(&cvt);
  32755. X
  32756. X   srand(1);
  32757. X   color_method = param[0];
  32758. X   if((localifs=(long far *)farmemalloc((long)numaffine*IFSPARM*sizeof(long)))==NULL)
  32759. X   {
  32760. X      stopmsg(0,insufficient_ifs_mem);
  32761. X      return(-1);
  32762. X   }
  32763. X
  32764. X   for (i = 0; i < numaffine; i++)    /* fill in the local IFS array */
  32765. X      for (j = 0; j < IFSPARM; j++)
  32766. X     localifs[i*IFSPARM+j] = ifs_defn[i*IFSPARM+j] * fudge;
  32767. X
  32768. X   tempr = fudge / 32767;     /* find the proper rand() fudge */
  32769. X
  32770. X   fp = open_orbitsave();
  32771. X
  32772. X   /* make maxct a function of screen size         */
  32773. X   /* 1k times maxit at EGA resolution seems about right */
  32774. X   maxct = (float)maxit*(1024.0*xdots*ydots)/(640.0*350.0);
  32775. X   ct = 0L;
  32776. X   x = y = 0;
  32777. X   ret = 0;
  32778. X   while(ct++ < maxct) /* loop until keypress or maxit */
  32779. X   {
  32780. X      if( check_key() )  /* keypress bails out */
  32781. X      {
  32782. X     ret = -1;
  32783. X     break;
  32784. X      }
  32785. X      r = rand15();     /* generate fudged random number between 0 and 1 */
  32786. X      r *= tempr;
  32787. X
  32788. X      /* pick which iterated function to execute, weighted by probability */
  32789. X      sum = localifs[6];  /* [0][6] */
  32790. X      k = 0;
  32791. X      while ( sum < r && k < numaffine-1) /* fixed bug of error if sum < 1 */
  32792. X     sum += localifs[++k*IFSPARM+6];
  32793. X      /* calculate image of last point under selected iterated function */
  32794. X      lfptr = localifs + k*IFSPARM; /* point to first parm in row */
  32795. X      newx = multiply(lfptr[0],x,bitshift) + 
  32796. X             multiply(lfptr[1],y,bitshift) + lfptr[4];
  32797. X      newy = multiply(lfptr[2],x,bitshift) + 
  32798. X             multiply(lfptr[3],y,bitshift) + lfptr[5];
  32799. X      x = newx;
  32800. X      y = newy;
  32801. X      if(fp)
  32802. X     fprintf(fp,orbitsave_format,(double)newx/fudge,(double)newy/fudge,0.0);
  32803. X
  32804. X      /* plot if inside window */
  32805. X      col = (multiply(cvt.a,x,bitshift) + multiply(cvt.b,y,bitshift) + cvt.e) >> bitshift;
  32806. X      row = (multiply(cvt.c,x,bitshift) + multiply(cvt.d,y,bitshift) + cvt.f) >> bitshift;
  32807. X      if ( col >= 0 && col < xdots && row >= 0 && row < ydots )
  32808. X      {
  32809. X     /* color is count of hits on this pixel */
  32810. X         if(color_method)
  32811. X            color = (k&(colors-1))+1;
  32812. X         else
  32813. X     color = getcolor(col,row)+1;
  32814. X     if( color < colors ) /* color sticks on last value */
  32815. X        (*plot)(col,row,color);
  32816. X      }
  32817. X      else if((long)abs(row) + (long)abs(col) > BAD_PIXEL) /* sanity check */
  32818. X            return(ret);
  32819. X   }
  32820. X   if(fp)
  32821. X      fclose(fp);
  32822. X   farmemfree(localifs);
  32823. X   return(ret);
  32824. X}
  32825. X
  32826. Xstatic int ifs3dlong()
  32827. X{
  32828. X   int color_method;   
  32829. X   FILE *fp;
  32830. X   extern int init3d[];
  32831. X   unsigned long maxct;
  32832. X   int color;
  32833. X   int ret;
  32834. X
  32835. X   long far *localifs;
  32836. X   long far *lfptr;
  32837. X   long newx,newy,newz,r,sum, tempr;
  32838. X
  32839. X   int i,j,k;
  32840. X
  32841. X   struct long3dvtinf inf;
  32842. X   srand(1);
  32843. X   color_method = param[0];
  32844. X   if((localifs=(long far *)farmemalloc((long)numaffine*IFS3DPARM*sizeof(long)))==NULL)
  32845. X   {
  32846. X      stopmsg(0,insufficient_ifs_mem);
  32847. X      return(-1);
  32848. X   }
  32849. X
  32850. X   /* setup affine screen coord conversion */
  32851. X   l_setup_convert_to_screen(&inf.cvt);
  32852. X
  32853. X   for (i = 0; i < numaffine; i++)    /* fill in the local IFS array */
  32854. X      for (j = 0; j < IFS3DPARM; j++)
  32855. X     localifs[i*IFS3DPARM+j] = ifs_defn[i*IFS3DPARM+j] * fudge;
  32856. X
  32857. X   tempr = fudge / 32767;     /* find the proper rand() fudge */
  32858. X
  32859. X   inf.orbit[0] = 0;
  32860. X   inf.orbit[1] = 0;
  32861. X   inf.orbit[2] = 0;
  32862. X
  32863. X   fp = open_orbitsave();
  32864. X
  32865. X   maxct = maxit*40L;
  32866. X   inf.ct = 0L;
  32867. X   ret = 0;
  32868. X   while(inf.ct++ < maxct) /* loop until keypress or maxit */
  32869. X   {
  32870. X      if( check_key() )  /* keypress bails out */
  32871. X      {
  32872. X     ret = -1;
  32873. X     break;
  32874. X      }
  32875. X      r = rand15();     /* generate fudged random number between 0 and 1 */
  32876. X      r *= tempr;
  32877. X
  32878. X      /* pick which iterated function to execute, weighted by probability */
  32879. X      sum = localifs[12];  /* [0][12] */
  32880. X      k = 0;
  32881. X      while ( sum < r && ++k < numaffine*IFS3DPARM)
  32882. X     sum += localifs[k*IFS3DPARM+12];
  32883. X
  32884. X      /* calculate image of last point under selected iterated function */
  32885. X      lfptr = localifs + k*IFS3DPARM; /* point to first parm in row */
  32886. X
  32887. X      /* calculate image of last point under selected iterated function */
  32888. X      newx = multiply(lfptr[0], inf.orbit[0], bitshift) +
  32889. X             multiply(lfptr[1], inf.orbit[1], bitshift) +
  32890. X         multiply(lfptr[2], inf.orbit[2], bitshift) + lfptr[9];
  32891. X      newy = multiply(lfptr[3], inf.orbit[0], bitshift) +
  32892. X         multiply(lfptr[4], inf.orbit[1], bitshift) +
  32893. X         multiply(lfptr[5], inf.orbit[2], bitshift) + lfptr[10];
  32894. X      newz = multiply(lfptr[6], inf.orbit[0], bitshift) +
  32895. X         multiply(lfptr[7], inf.orbit[1], bitshift) +
  32896. X         multiply(lfptr[8], inf.orbit[2], bitshift) + lfptr[11];
  32897. X
  32898. X      inf.orbit[0] = newx;
  32899. X      inf.orbit[1] = newy;
  32900. X      inf.orbit[2] = newz;
  32901. X      if(fp)
  32902. X     fprintf(fp,orbitsave_format,(double)newx/fudge,(double)newy/fudge,(double)newz/fudge);
  32903. X
  32904. X      if (long3dviewtransf(&inf))
  32905. X      {
  32906. X     if((long)abs(inf.row) + (long)abs(inf.col) > BAD_PIXEL) /* sanity check */
  32907. X            return(ret);
  32908. X     /* plot if inside window */
  32909. X     if (inf.col >= 0)
  32910. X     {
  32911. X        if(realtime)
  32912. X           whichimage=1;
  32913. X            if(color_method)
  32914. X               color = (k&(colors-1))+1;
  32915. X            else
  32916. X        color = getcolor(inf.col,inf.row)+1;
  32917. X        if( color < colors ) /* color sticks on last value */
  32918. X           (*plot)(inf.col,inf.row,color);
  32919. X     }
  32920. X     if(realtime)
  32921. X     {
  32922. X        whichimage=2;
  32923. X        /* plot if inside window */
  32924. X        if (inf.col1 >= 0)
  32925. X        {
  32926. X               if(color_method)
  32927. X                  color = (k&(colors-1))+1;
  32928. X               else
  32929. X           color = getcolor(inf.col1,inf.row1)+1;
  32930. X           if( color < colors ) /* color sticks on last value */
  32931. X          (*plot)(inf.col1,inf.row1,color);
  32932. X        }
  32933. X     }
  32934. X      }
  32935. X   }
  32936. X   if(fp)
  32937. X      fclose(fp);
  32938. X   farmemfree(localifs);
  32939. X   return(ret);
  32940. X}
  32941. X
  32942. Xstatic void setupmatrix(MATRIX doublemat)
  32943. X{
  32944. X   /* build transformation matrix */
  32945. X   identity (doublemat);
  32946. X
  32947. X   /* apply rotations - uses the same rotation variables as line3d.c */
  32948. X   xrot ((double)XROT / 57.29577,doublemat);
  32949. X   yrot ((double)YROT / 57.29577,doublemat);
  32950. X   zrot ((double)ZROT / 57.29577,doublemat);
  32951. X
  32952. X   /* apply scale */
  32953. X/*   scale((double)XSCALE/100.0,(double)YSCALE/100.0,(double)ROUGH/100.0,doublemat);*/
  32954. X
  32955. X}
  32956. X
  32957. Xint orbit3dfloat()
  32958. X{
  32959. X   display3d = -1;
  32960. X   if(0 < glassestype && glassestype < 3)
  32961. X      realtime = 1;
  32962. X   else
  32963. X      realtime = 0;
  32964. X   return(funny_glasses_call(orbit3dfloatcalc));
  32965. X}
  32966. X
  32967. Xint orbit3dlong()
  32968. X{
  32969. X   display3d = -1;
  32970. X   if(0 < glassestype && glassestype < 3)
  32971. X      realtime = 1;
  32972. X   else
  32973. X      realtime = 0;
  32974. X   return(funny_glasses_call(orbit3dlongcalc));
  32975. X}
  32976. X
  32977. Xint ifs3d()
  32978. X{
  32979. X   display3d = -1;
  32980. X
  32981. X   if(0 < glassestype && glassestype < 3)
  32982. X      realtime = 1;
  32983. X   else
  32984. X      realtime = 0;
  32985. X   if(floatflag)
  32986. X      return(funny_glasses_call(ifs3dfloat)); /* double version of ifs3d */
  32987. X   else
  32988. X      return(funny_glasses_call(ifs3dlong));  /* long version of ifs3d     */
  32989. X}
  32990. X
  32991. X
  32992. X
  32993. Xstatic int long3dviewtransf(struct long3dvtinf *inf)
  32994. X{
  32995. X   int i,j;
  32996. X   double tmpx, tmpy, tmpz;
  32997. X   long tmp;
  32998. X
  32999. X   if (inf->ct == 1)    /* initialize on first call */
  33000. X   {
  33001. X      for(i=0;i<3;i++)
  33002. X      {
  33003. X     inf->minvals[i] =  1L << 30;
  33004. X     inf->maxvals[i] = -inf->minvals[i];
  33005. X      }
  33006. X      setupmatrix(inf->doublemat);
  33007. X      if(realtime)
  33008. X     setupmatrix(inf->doublemat1);
  33009. X      /* copy xform matrix to long for for fixed point math */
  33010. X      for (i = 0; i < 4; i++)
  33011. X     for (j = 0; j < 4; j++)
  33012. X     {
  33013. X        inf->longmat[i][j] = inf->doublemat[i][j] * fudge;
  33014. X        if(realtime)
  33015. X           inf->longmat1[i][j] = inf->doublemat1[i][j] * fudge;
  33016. X     }
  33017. X   }
  33018. X
  33019. X   /* 3D VIEWING TRANSFORM */
  33020. X   longvmult(inf->orbit,inf->longmat,inf->viewvect,bitshift);
  33021. X   if(realtime)
  33022. X      longvmult(inf->orbit,inf->longmat1,inf->viewvect1,bitshift);
  33023. X
  33024. X   if(inf->ct <= waste) /* waste this many points to find minz and maxz */
  33025. X   {
  33026. X      /* find minz and maxz */
  33027. X      for(i=0;i<3;i++)
  33028. X     if ((tmp = inf->viewvect[i]) < inf->minvals[i])
  33029. X        inf->minvals[i] = tmp;
  33030. X     else if (tmp > inf->maxvals[i])
  33031. X        inf->maxvals[i] = tmp;
  33032. X
  33033. X      if(inf->ct == waste) /* time to work it out */
  33034. X      {
  33035. X     inf->iview[0] = inf->iview[1] = 0L; /* center viewer on origin */
  33036. X
  33037. X     /* z value of user's eye - should be more negative than extreme
  33038. X            negative part of image */
  33039. X     inf->iview[2] = (long)((inf->minvals[2]-inf->maxvals[2])*(double)ZVIEWER/100.0);
  33040. X
  33041. X     /* center image on origin */
  33042. X     tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0*fudge); /* center x */
  33043. X     tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0*fudge); /* center y */
  33044. X
  33045. X     /* apply perspective shift */
  33046. X     tmpx += ((double)xshift*(xxmax-xxmin))/(xdots);
  33047. X     tmpy += ((double)yshift*(yymax-yymin))/(ydots);
  33048. X     tmpz = -((double)inf->maxvals[2]) / fudge;
  33049. X     trans(tmpx,tmpy,tmpz,inf->doublemat);
  33050. X
  33051. X     if(realtime)
  33052. X     {
  33053. X        /* center image on origin */
  33054. X        tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0*fudge); /* center x */
  33055. X        tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0*fudge); /* center y */
  33056. X
  33057. X        tmpx += ((double)xshift1*(xxmax-xxmin))/(xdots);
  33058. X        tmpy += ((double)yshift1*(yymax-yymin))/(ydots);
  33059. X        tmpz = -((double)inf->maxvals[2]) / fudge;
  33060. X        trans(tmpx,tmpy,tmpz,inf->doublemat1);
  33061. X     }
  33062. X     for(i=0;i<3;i++)
  33063. X        view[i] = (double)inf->iview[i] / fudge;
  33064. X
  33065. X     /* copy xform matrix to long for for fixed point math */
  33066. X     for (i = 0; i < 4; i++)
  33067. X        for (j = 0; j < 4; j++)
  33068. X        {
  33069. X           inf->longmat[i][j] = inf->doublemat[i][j] * fudge;
  33070. X           if(realtime)
  33071. X          inf->longmat1[i][j] = inf->doublemat1[i][j] * fudge;
  33072. X        }
  33073. X      }
  33074. X      return(0);
  33075. X   }
  33076. X
  33077. X   /* inf->ct > waste */
  33078. X   /* apply perspective if requested */
  33079. X   if(ZVIEWER)
  33080. X   {
  33081. X      if(debugflag==22 || ZVIEWER < 100) /* use float for small persp */
  33082. X      {
  33083. X     /* use float perspective calc */
  33084. X     VECTOR tmpv;
  33085. X     for(i=0;i<3;i++)
  33086. X        tmpv[i] = (double)inf->viewvect[i] / fudge;
  33087. X     perspective(tmpv);
  33088. X     for(i=0;i<3;i++)
  33089. X        inf->viewvect[i] = tmpv[i]*fudge;
  33090. X     if(realtime)
  33091. X     {
  33092. X        for(i=0;i<3;i++)
  33093. X           tmpv[i] = (double)inf->viewvect1[i] / fudge;
  33094. X        perspective(tmpv);
  33095. X        for(i=0;i<3;i++)
  33096. X           inf->viewvect1[i] = tmpv[i]*fudge;
  33097. X     }
  33098. X      }
  33099. X      else
  33100. X      {
  33101. X     longpersp(inf->viewvect,inf->iview,bitshift);
  33102. X     if(realtime)
  33103. X        longpersp(inf->viewvect1,inf->iview,bitshift);
  33104. X      }
  33105. X   }
  33106. X
  33107. X   /* work out the screen positions */
  33108. X   inf->row = ((multiply(inf->cvt.c,inf->viewvect[0],bitshift) +
  33109. X        multiply(inf->cvt.d,inf->viewvect[1],bitshift) + inf->cvt.f)
  33110. X        >> bitshift)
  33111. X          + yyadjust;
  33112. X   inf->col = ((multiply(inf->cvt.a,inf->viewvect[0],bitshift) +
  33113. X        multiply(inf->cvt.b,inf->viewvect[1],bitshift) + inf->cvt.e)
  33114. X        >> bitshift)
  33115. X          + xxadjust;
  33116. X   if (inf->col < 0 || inf->col >= xdots || inf->row < 0 || inf->row >= ydots)
  33117. X   {
  33118. X      if((long)abs(inf->col)+(long)abs(inf->row) > BAD_PIXEL)
  33119. X        inf->col= inf->row = -2;
  33120. X      else
  33121. X        inf->col= inf->row = -1;
  33122. X   }    
  33123. X   if(realtime)
  33124. X   {
  33125. X      inf->row1 = ((multiply(inf->cvt.c,inf->viewvect1[0],bitshift) +
  33126. X            multiply(inf->cvt.d,inf->viewvect1[1],bitshift) +
  33127. X            inf->cvt.f) >> bitshift)
  33128. X          + yyadjust1;
  33129. X      inf->col1 = ((multiply(inf->cvt.a,inf->viewvect1[0],bitshift) +
  33130. X            multiply(inf->cvt.b,inf->viewvect1[1],bitshift) +
  33131. X            inf->cvt.e) >> bitshift)
  33132. X          + xxadjust1;
  33133. X      if (inf->col1 < 0 || inf->col1 >= xdots || inf->row1 < 0 || inf->row1 >= ydots)
  33134. X      {
  33135. X         if((long)abs(inf->col1)+(long)abs(inf->row1) > BAD_PIXEL)
  33136. X           inf->col1= inf->row1 = -2;
  33137. X         else
  33138. X           inf->col1= inf->row1 = -1;
  33139. X      }    
  33140. X   }
  33141. X   return(1);
  33142. X}
  33143. X
  33144. Xstatic int float3dviewtransf(struct float3dvtinf *inf)
  33145. X{
  33146. X   int i;
  33147. X   double tmpx, tmpy, tmpz;
  33148. X   double tmp;
  33149. X
  33150. X   if (inf->ct == 1)    /* initialize on first call */
  33151. X   {
  33152. X      for(i=0;i<3;i++)
  33153. X      {
  33154. X     inf->minvals[i] =  100000.0; /* impossible value */
  33155. X     inf->maxvals[i] = -100000.0;
  33156. X      }
  33157. X      setupmatrix(inf->doublemat);
  33158. X      if(realtime)
  33159. X     setupmatrix(inf->doublemat1);
  33160. X   }
  33161. X
  33162. X   /* 3D VIEWING TRANSFORM */
  33163. X   vmult(inf->orbit,inf->doublemat,inf->viewvect );
  33164. X   if(realtime)
  33165. X      vmult(inf->orbit,inf->doublemat1,inf->viewvect1);
  33166. X
  33167. X   if(inf->ct <= waste) /* waste this many points to find minz and maxz */
  33168. X   {
  33169. X      /* find minz and maxz */
  33170. X      for(i=0;i<3;i++)
  33171. X     if ((tmp = inf->viewvect[i]) < inf->minvals[i])
  33172. X        inf->minvals[i] = tmp;
  33173. X     else if (tmp > inf->maxvals[i])
  33174. X        inf->maxvals[i] = tmp;
  33175. X      if(inf->ct == waste) /* time to work it out */
  33176. X      {
  33177. X     view[0] = view[1] = 0; /* center on origin */
  33178. X     /* z value of user's eye - should be more negative than extreme
  33179. X               negative part of image */
  33180. X     view[2] = (inf->minvals[2]-inf->maxvals[2])*(double)ZVIEWER/100.0;
  33181. X
  33182. X     /* center image on origin */
  33183. X     tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0); /* center x */
  33184. X     tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0); /* center y */
  33185. X
  33186. X     /* apply perspective shift */
  33187. X     tmpx += ((double)xshift*(xxmax-xxmin))/(xdots);
  33188. X     tmpy += ((double)yshift*(yymax-yymin))/(ydots);
  33189. X     tmpz = -(inf->maxvals[2]);
  33190. X     trans(tmpx,tmpy,tmpz,inf->doublemat);
  33191. X
  33192. X     if(realtime)
  33193. X     {
  33194. X        /* center image on origin */
  33195. X        tmpx = (-inf->minvals[0]-inf->maxvals[0])/(2.0); /* center x */
  33196. X        tmpy = (-inf->minvals[1]-inf->maxvals[1])/(2.0); /* center y */
  33197. X
  33198. X        tmpx += ((double)xshift1*(xxmax-xxmin))/(xdots);
  33199. X        tmpy += ((double)yshift1*(yymax-yymin))/(ydots);
  33200. X        tmpz = -(inf->maxvals[2]);
  33201. X        trans(tmpx,tmpy,tmpz,inf->doublemat1);
  33202. X        }
  33203. X     }
  33204. X      return(0);
  33205. X      }
  33206. X
  33207. X   /* inf->ct > waste */
  33208. X   /* apply perspective if requested */
  33209. X   if(ZVIEWER)
  33210. X   {
  33211. X      perspective(inf->viewvect);
  33212. X      if(realtime)
  33213. X     perspective(inf->viewvect1);
  33214. X   }
  33215. X   inf->row = inf->cvt.c*inf->viewvect[0] + inf->cvt.d*inf->viewvect[1]
  33216. X        + inf->cvt.f + yyadjust;
  33217. X   inf->col = inf->cvt.a*inf->viewvect[0] + inf->cvt.b*inf->viewvect[1]
  33218. X        + inf->cvt.e + xxadjust;
  33219. X   if (inf->col < 0 || inf->col >= xdots || inf->row < 0 || inf->row >= ydots)
  33220. X   {
  33221. X      if((long)abs(inf->col)+(long)abs(inf->row) > BAD_PIXEL)
  33222. X        inf->col= inf->row = -2;
  33223. X      else
  33224. X        inf->col= inf->row = -1;
  33225. X   }    
  33226. X   if(realtime)
  33227. X   {
  33228. X      inf->row1 = inf->cvt.c*inf->viewvect1[0] + inf->cvt.d*inf->viewvect1[1]
  33229. X        + inf->cvt.f + yyadjust1;
  33230. X      inf->col1 = inf->cvt.a*inf->viewvect1[0] + inf->cvt.b*inf->viewvect1[1]
  33231. X        + inf->cvt.e + xxadjust1;
  33232. X      if (inf->col1 < 0 || inf->col1 >= xdots || inf->row1 < 0 || inf->row1 >= ydots)
  33233. X      {
  33234. X         if((long)abs(inf->col1)+(long)abs(inf->row1) > BAD_PIXEL)
  33235. X           inf->col1= inf->row1 = -2;
  33236. X         else
  33237. X           inf->col1= inf->row1 = -1;
  33238. X      }    
  33239. X   }
  33240. X   return(1);
  33241. X}
  33242. X
  33243. Xstatic FILE *open_orbitsave()
  33244. X{
  33245. X   FILE *fp;
  33246. X   if (orbitsave && (fp = fopen(orbitsavename,"w")))
  33247. X   {
  33248. X      fprintf(fp,"pointlist x y z color\n");
  33249. X      return fp;
  33250. X   }
  33251. X   return NULL;
  33252. X}
  33253. X
  33254. X/* Plot a histogram by incrementing the pixel each time it it touched */
  33255. Xstatic void _fastcall plothist(x, y, color)
  33256. Xint x,y,color;
  33257. X{
  33258. X    color = getcolor(x,y)+1;
  33259. X    if (color<colors) 
  33260. X    putcolor(x,y,color);
  33261. X}
  33262. X
  33263. X
  33264. X
  33265. X
  33266. SHAR_EOF
  33267. $TOUCH -am 1028230093 lorenz.c &&
  33268. chmod 0644 lorenz.c ||
  33269. echo "restore of lorenz.c failed"
  33270. set `wc -c lorenz.c`;Wc_c=$1
  33271. if test "$Wc_c" != "66158"; then
  33272.     echo original size 66158, current size $Wc_c
  33273. fi
  33274. # ============= lsys.c ==============
  33275. echo "x - extracting lsys.c (Text)"
  33276. sed 's/^X//' << 'SHAR_EOF' > lsys.c &&
  33277. X#include <stdio.h>
  33278. X#include <stdlib.h>
  33279. X#include <string.h>
  33280. X#include <math.h>
  33281. X#ifdef __TURBOC__
  33282. X#include <alloc.h>
  33283. X#elif !defined(__386BSD__)
  33284. X#include <malloc.h>
  33285. X#endif
  33286. X#include "fractint.h"
  33287. X#include "prototyp.h"
  33288. X
  33289. X#define size    ssize
  33290. X/* Needed for use of asm -- helps decide which pointer to function
  33291. X * to put into the struct lsys_cmds.
  33292. X */
  33293. Xextern int cpu;
  33294. Xextern int fpu;
  33295. Xextern int debugflag;
  33296. Xextern int xdots,ydots;
  33297. Xextern int colors;
  33298. Xextern char LFileName[];
  33299. Xextern char LName[];
  33300. Xextern double param[];
  33301. Xextern int overflow;
  33302. Xextern float  screenaspect;
  33303. X
  33304. Xstruct lsys_cmd {
  33305. X  char ch;
  33306. X  void (*f)(long n);
  33307. X  long n;
  33308. X};
  33309. X
  33310. Xstatic double      _fastcall getnumber(char far **);
  33311. Xstatic struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_cmd far **,int);
  33312. Xstatic int      _fastcall findscale(struct lsys_cmd far *, struct lsys_cmd far **, int);
  33313. Xstatic struct lsys_cmd far * _fastcall drawLSys(struct lsys_cmd far *, struct lsys_cmd far **, int);
  33314. Xstatic int      _fastcall readLSystemFile(char *);
  33315. Xstatic void      _fastcall free_rules_mem(void);
  33316. Xstatic int      _fastcall save_rule(char *,char far **);
  33317. Xstatic struct lsys_cmd far *SizeTransform(char far *s);
  33318. Xstatic struct lsys_cmd far *DrawTransform(char far *s);
  33319. Xstatic void free_lcmds();
  33320. X
  33321. Xstatic long aspect; /* aspect ratio of each pixel, ysize/xsize */
  33322. X
  33323. X/* Some notes to Adrian from PB, made when I integrated with v15:
  33324. X     printfs changed to work with new user interface
  33325. X     bug at end of readLSystemFile, the line which said rulind=0 fixed
  33326. X       to say *rulind=0
  33327. X     the calloc was not worthwhile, it was just for a 54 byte area, cheaper
  33328. X       to keep it as a static;    but there was a static 201 char buffer I
  33329. X       changed to not be static
  33330. X     use of strdup was a nono, caused problems running out of space cause
  33331. X       the memory allocated each time was never freed; I've changed to
  33332. X       use far memory and to free when done
  33333. X   */
  33334. X
  33335. Xlong sins[50];
  33336. Xlong coss[50];
  33337. X/* dmaxangle is maxangle - 1. */
  33338. Xchar maxangle,dmaxangle,curcolor;
  33339. Xlong size;
  33340. Xunsigned long realangle;
  33341. Xlong xpos,ypos;
  33342. Xchar counter,angle,reverse,stackoflow;
  33343. Xlong lsys_Xmin, lsys_Xmax, lsys_Ymin, lsys_Ymax;
  33344. X
  33345. X/* Macro to take an FP number and turn it into a
  33346. X * 16/16-bit fixed-point number.
  33347. X */
  33348. X#define FIXEDMUL    524288L
  33349. X#define FIXEDPT(x)    ((long) (FIXEDMUL * (x)))
  33350. X
  33351. X/* The number by which to multiply sines, cosines and other
  33352. X * values with magnitudes less than or equal to 1.
  33353. X * sins and coss are a 3/29 bit fixed-point scheme (so the
  33354. X * range is +/- 2, with good accuracy.    The range is to
  33355. X * avoid overflowing when the aspect ratio is taken into
  33356. X * account.
  33357. X */
  33358. X#define FIXEDLT1    536870912.0
  33359. X
  33360. X/* Multiply by this number to convert an unsigned 32-bit long
  33361. X * to an angle from 0-2PI.
  33362. X */
  33363. X#define ANGLE2DOUBLE    (2*PI / 4294967296.)
  33364. X
  33365. Xstatic int ispow2(long n)
  33366. X{
  33367. X  return (n == (n & -n));
  33368. X}
  33369. X
  33370. X
  33371. X#ifdef XFRACT
  33372. Xstatic void lsys_doplus(long n)
  33373. X{
  33374. X  if (reverse) {
  33375. X    if (++angle == maxangle)
  33376. X      angle = 0;
  33377. X  }
  33378. X  else {
  33379. X    if (angle)
  33380. X      angle--;
  33381. X    else
  33382. X      angle = dmaxangle;
  33383. X  }
  33384. X}
  33385. X#endif
  33386. X
  33387. X
  33388. X#ifdef XFRACT
  33389. X/* This is the same as lsys_doplus, except maxangle is a power of 2. */
  33390. Xstatic void lsys_doplus_pow2(long n)
  33391. X{
  33392. X  if (reverse) {
  33393. X    angle++;
  33394. X    angle &= dmaxangle;
  33395. X  }
  33396. X  else {
  33397. X    angle--;
  33398. X    angle &= dmaxangle;
  33399. X  }
  33400. X}
  33401. X#endif
  33402. X
  33403. X
  33404. X#ifdef XFRACT
  33405. Xstatic void lsys_dominus(long n)
  33406. X{
  33407. X  if (reverse) {
  33408. X    if (angle)
  33409. X      angle--;
  33410. X    else
  33411. X      angle = dmaxangle;
  33412. X  }
  33413. X  else {
  33414. X    if (++angle == maxangle)
  33415. X      angle = 0;
  33416. X  }
  33417. X}
  33418. X#endif
  33419. X
  33420. X
  33421. X#ifdef XFRACT
  33422. Xstatic void lsys_dominus_pow2(long n)
  33423. X{
  33424. X  if (reverse) {
  33425. X    angle--;
  33426. X    angle &= dmaxangle;
  33427. X  }
  33428. X  else {
  33429. X    angle++;
  33430. X    angle &= dmaxangle;
  33431. X  }
  33432. X}
  33433. X#endif
  33434. X
  33435. Xstatic void lsys_doslash(long n)
  33436. X{
  33437. X  if (reverse)
  33438. X    realangle -= n;
  33439. X  else
  33440. X    realangle += n;
  33441. X}
  33442. X#ifdef XFRACT
  33443. X#define lsys_doslash_386 lsys_doslash
  33444. X#endif
  33445. X
  33446. Xstatic void lsys_dobslash(long n)
  33447. X{
  33448. X  if (reverse)
  33449. X    realangle += n;
  33450. X  else
  33451. X    realangle -= n;
  33452. X}
  33453. X
  33454. X#ifdef XFRACT
  33455. X#define lsys_dobslash_386 lsys_dobslash
  33456. X#endif
  33457. X
  33458. Xstatic void lsys_doat(long n)
  33459. X{
  33460. X  size = multiply(size, n, 19);
  33461. X}
  33462. X
  33463. X#ifdef XFRACT
  33464. X#define lsys_doat_386 lsys_doat
  33465. X#endif
  33466. X
  33467. Xstatic void lsys_dopipe(long n)
  33468. X{
  33469. X  angle += maxangle / 2;
  33470. X  angle %= maxangle;
  33471. X}
  33472. X
  33473. X
  33474. X#ifdef XFRACT
  33475. Xstatic void lsys_dopipe_pow2(long n)
  33476. X{
  33477. X  angle += maxangle >> 1;
  33478. X  angle &= dmaxangle;
  33479. X}
  33480. X#endif
  33481. X
  33482. X
  33483. X#ifdef XFRACT
  33484. Xstatic void lsys_dobang(long n)
  33485. X{
  33486. X  reverse = ! reverse;
  33487. X}
  33488. X#endif
  33489. X
  33490. Xstatic void lsys_dosizedm(long n)
  33491. X{
  33492. X  double angle = (double) realangle * ANGLE2DOUBLE;
  33493. X  double s, c;
  33494. X  long fixedsin, fixedcos;
  33495. X  FPUsincos(&angle, &s, &c);
  33496. X  fixedsin = (long) (s * FIXEDLT1);
  33497. X  fixedcos = (long) (c * FIXEDLT1);
  33498. X
  33499. X  xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  33500. X  ypos += multiply(size, fixedsin, 29);
  33501. X
  33502. X/* xpos+=size*aspect*cos(realangle*PI/180);  */
  33503. X/* ypos+=size*sin(realangle*PI/180);         */
  33504. X  if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  33505. X  if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  33506. X  if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  33507. X  if (ypos<lsys_Ymin) lsys_Ymin=ypos;
  33508. X}
  33509. X
  33510. Xstatic void lsys_dosizegf(long n)
  33511. X{
  33512. X  xpos += multiply(size, (long) coss[angle], 29);
  33513. X  ypos += multiply(size, (long) sins[angle], 29);
  33514. X/* xpos+=size*coss[angle];                   */
  33515. X/* ypos+=size*sins[angle];                   */
  33516. X  if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  33517. X  if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  33518. X  if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  33519. X  if (ypos<lsys_Ymin) lsys_Ymin=ypos;
  33520. X}
  33521. X
  33522. X#ifdef XFRACT
  33523. X#define lsys_dosizegf_386 lsys_dosizegf
  33524. X#endif
  33525. X
  33526. Xstatic void lsys_dodrawd(long n)
  33527. X{
  33528. X  double angle = (double) realangle * ANGLE2DOUBLE;
  33529. X  double s, c;
  33530. X  long fixedsin, fixedcos;
  33531. X  int lastx, lasty;
  33532. X  FPUsincos(&angle, &s, &c);
  33533. X  fixedsin = (long) (s * FIXEDLT1);
  33534. X  fixedcos = (long) (c * FIXEDLT1);
  33535. X
  33536. X  lastx=(int) (xpos >> 19);
  33537. X  lasty=(int) (ypos >> 19);
  33538. X  xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  33539. X  ypos += multiply(size, fixedsin, 29);
  33540. X/* xpos+=size*aspect*cos(realangle*PI/180);   */
  33541. X/* ypos+=size*sin(realangle*PI/180);          */
  33542. X  draw_line(lastx,lasty,(int)(xpos >> 19),(int)(ypos>>19),curcolor);
  33543. X}
  33544. X
  33545. Xstatic void lsys_dodrawm(long n)
  33546. X{
  33547. X  double angle = (double) realangle * ANGLE2DOUBLE;
  33548. X  double s, c;
  33549. X  long fixedsin, fixedcos;
  33550. X  FPUsincos(&angle, &s, &c);
  33551. X  fixedsin = (long) (s * FIXEDLT1);
  33552. X  fixedcos = (long) (c * FIXEDLT1);
  33553. X
  33554. X/* xpos+=size*aspect*cos(realangle*PI/180);   */
  33555. X/* ypos+=size*sin(realangle*PI/180);          */
  33556. X  xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  33557. X  ypos += multiply(size, fixedsin, 29);
  33558. X}
  33559. X
  33560. Xstatic void lsys_dodrawg(long n)
  33561. X{
  33562. X  xpos += multiply(size, (long) coss[angle], 29);
  33563. X  ypos += multiply(size, (long) sins[angle], 29);
  33564. X/* xpos+=size*coss[angle];                    */
  33565. X/* ypos+=size*sins[angle];                    */
  33566. X}
  33567. X
  33568. X#ifdef XFRACT
  33569. X#define  lsys_dodrawg_386 lsys_dodrawg
  33570. X#endif
  33571. X
  33572. Xstatic void lsys_dodrawf(long n)
  33573. X{
  33574. X  int lastx = (int) (xpos >> 19);
  33575. X  int lasty = (int) (ypos >> 19);
  33576. X  xpos += multiply(size, (long) coss[angle], 29);
  33577. X  ypos += multiply(size, (long) sins[angle], 29);
  33578. X/* xpos+=size*coss[angle];                    */
  33579. X/* ypos+=size*sins[angle];                    */
  33580. X  draw_line(lastx,lasty,(int)(xpos>>19),(int)(ypos>>19),curcolor);
  33581. X}
  33582. X
  33583. Xstatic void lsys_dodrawc(long n)
  33584. X{
  33585. X  curcolor = ((int) n) % colors;
  33586. X}
  33587. X
  33588. Xstatic void lsys_dodrawgt(long n)
  33589. X{
  33590. X  curcolor -= n;
  33591. X  if ((curcolor &= colors-1) == 0)
  33592. X    curcolor = colors-1;
  33593. X}
  33594. X
  33595. Xstatic void lsys_dodrawlt(long n)
  33596. X{
  33597. X  curcolor += n;
  33598. X  if ((curcolor &= colors-1) == 0)
  33599. X    curcolor = 1;
  33600. X}
  33601. X
  33602. Xstatic double _fastcall getnumber(char far **str)
  33603. X{
  33604. X   char numstr[30];
  33605. X   float ret;
  33606. X   int i,root,inverse;
  33607. X
  33608. X   root=0;
  33609. X   inverse=0;
  33610. X   strcpy(numstr,"");
  33611. X   (*str)++;
  33612. X   switch (**str)
  33613. X   {
  33614. X   case 'q':
  33615. X      root=1;
  33616. X      (*str)++;
  33617. X      break;
  33618. X   case 'i':
  33619. X      inverse=1;
  33620. X      (*str)++;
  33621. X      break;
  33622. X   }
  33623. X   switch (**str)
  33624. X   {
  33625. X   case 'q':
  33626. X      root=1;
  33627. X      (*str)++;
  33628. X      break;
  33629. X   case 'i':
  33630. X      inverse=1;
  33631. X      (*str)++;
  33632. X      break;
  33633. X   }
  33634. X   i=0;
  33635. X   while (**str<='9' && **str>='0' || **str=='.')
  33636. X   {
  33637. X      numstr[i++]= **str;
  33638. X      (*str)++;
  33639. X   }
  33640. X   (*str)--;
  33641. X   numstr[i]=0;
  33642. X   ret=atof(numstr);
  33643. X   if (root)
  33644. X     ret=sqrt(ret);
  33645. X   if (inverse)
  33646. X     ret = 1/ret;
  33647. X   return ret;
  33648. X}
  33649. X
  33650. Xstatic struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *command, struct lsys_cmd far **rules, int depth)
  33651. X{
  33652. X   struct lsys_cmd far **rulind;
  33653. X   int tran;
  33654. X
  33655. Xif (overflow)     /* integer math routines overflowed */
  33656. X    return NULL;
  33657. X
  33658. X#ifndef __TURBOC__
  33659. X   if (stackavail() < 400) { /* leave some margin for calling subrtns */
  33660. X      stackoflow = 1;
  33661. X      return NULL;
  33662. X      }
  33663. X#endif
  33664. X
  33665. X   while (command->ch && command->ch !=']') {
  33666. X      if (! (counter++)) {
  33667. X     /* let user know we're not dead */
  33668. X     if (thinking(1,"L-System thinking (higher orders take longer)")) {
  33669. X        counter--;
  33670. X        return NULL;
  33671. X     }
  33672. X      }
  33673. X      tran=0;
  33674. X      if (depth) {
  33675. X     for(rulind=rules;*rulind;rulind++)
  33676. X        if ((*rulind)->ch==command->ch) {
  33677. X           tran=1;
  33678. X           if (findsize((*rulind)+1,rules,depth-1) == NULL)
  33679. X          return(NULL);
  33680. X        }
  33681. X      }
  33682. X      if (!depth || !tran) {
  33683. X    if (command->f)
  33684. X      (*command->f)(command->n);
  33685. X    else if (command->ch == '[') {
  33686. X      char saveang,saverev;
  33687. X      long savesize,savex,savey;
  33688. X      unsigned long saverang;
  33689. X
  33690. X      saveang=angle;
  33691. X      saverev=reverse;
  33692. X      savesize=size;
  33693. X      saverang=realangle;
  33694. X      savex=xpos;
  33695. X      savey=ypos;
  33696. X      if ((command=findsize(command+1,rules,depth)) == NULL)
  33697. X         return(NULL);
  33698. X      angle=saveang;
  33699. X      reverse=saverev;
  33700. X      size=savesize;
  33701. X      realangle=saverang;
  33702. X      xpos=savex;
  33703. X      ypos=savey;
  33704. X    }
  33705. X      }
  33706. X      command++;
  33707. X   }
  33708. X   return command;
  33709. X}
  33710. X
  33711. Xstatic int _fastcall findscale(struct lsys_cmd far *command, struct lsys_cmd far **rules, int depth)
  33712. X{
  33713. X   float horiz,vert;
  33714. X   double xmin, xmax, ymin, ymax;
  33715. X   double locsize;
  33716. X   double locaspect;
  33717. X   int i;
  33718. X   struct lsys_cmd far *fsret;
  33719. X   locaspect=screenaspect*xdots/ydots;
  33720. X   aspect = FIXEDPT(locaspect);
  33721. X   for(i=0;i<maxangle;i++) {
  33722. X      sins[i]=(long) ((sin(2*i*PI/maxangle)) * FIXEDLT1);
  33723. X      coss[i]=(long) ((locaspect * cos(2*i*PI/maxangle)) * FIXEDLT1);
  33724. X   }
  33725. X   xpos=ypos=lsys_Xmin=lsys_Xmax=lsys_Ymax=lsys_Ymin=angle=reverse=realangle=counter=0;
  33726. X   size=FIXEDPT(1);
  33727. X   fsret = findsize(command,rules,depth);
  33728. X   thinking(0, NULL); /* erase thinking message if any */
  33729. X   xmin = (double) lsys_Xmin / FIXEDMUL;
  33730. X   xmax = (double) lsys_Xmax / FIXEDMUL;
  33731. X   ymin = (double) lsys_Ymin / FIXEDMUL;
  33732. X   ymax = (double) lsys_Ymax / FIXEDMUL;
  33733. X   locsize = (double) size / FIXEDMUL;
  33734. X   if (fsret == NULL)
  33735. X      return 0;
  33736. X   if (xmax == xmin)
  33737. X      horiz = 1E37;
  33738. X   else
  33739. X      horiz = (xdots-10)/(xmax-xmin);
  33740. X   if (ymax == ymin)
  33741. X      vert = 1E37;
  33742. X   else
  33743. X      vert = (ydots-6) /(ymax-ymin);
  33744. X   locsize = (vert<horiz) ? vert : horiz;
  33745. X
  33746. X   if (horiz == 1E37)
  33747. X      xpos = FIXEDPT(xdots/2);
  33748. X   else
  33749. X      xpos = FIXEDPT(-xmin*(locsize)+5+((xdots-10)-(locsize)*(xmax-xmin))/2);
  33750. X   if (vert == 1E37)
  33751. X      ypos = FIXEDPT(ydots/2);
  33752. X   else
  33753. X      ypos = FIXEDPT(-ymin*(locsize)+3+((ydots-6)-(locsize)*(ymax-ymin))/2);
  33754. X   size = FIXEDPT(locsize);
  33755. X   return 1;
  33756. X}
  33757. X
  33758. Xstatic struct lsys_cmd far * _fastcall drawLSys(struct lsys_cmd far *command,struct lsys_cmd far **rules,int depth)
  33759. X{
  33760. X   struct lsys_cmd far **rulind;
  33761. X   int tran;
  33762. X
  33763. Xif (overflow)     /* integer math routines overflowed */
  33764. X    return NULL;
  33765. X
  33766. X#ifndef __TURBOC__
  33767. X   if (stackavail() < 400) { /* leave some margin for calling subrtns */
  33768. X      stackoflow = 1;
  33769. X      return NULL;
  33770. X      }
  33771. X#endif
  33772. X
  33773. X   while (command->ch && command->ch !=']') {
  33774. X      if (!(counter++)) {
  33775. X     if (check_key()) {
  33776. X        counter--;
  33777. X        return NULL;
  33778. X     }
  33779. X      }
  33780. X      tran=0;
  33781. X      if (depth) {
  33782. X     for(rulind=rules;*rulind;rulind++)
  33783. X        if ((*rulind)->ch == command->ch) {
  33784. X           tran=1;
  33785. X           if (drawLSys((*rulind)+1,rules,depth-1) == NULL)
  33786. X          return NULL;
  33787. X        }
  33788. X      }
  33789. X      if (!depth||!tran) {
  33790. X    if (command->f)
  33791. X      (*command->f)(command->n);
  33792. X    else if (command->ch == '[') {
  33793. X      char saveang,saverev,savecolor;
  33794. X      long savesize,savex,savey;
  33795. X      unsigned long saverang;
  33796. X
  33797. X      saveang=angle;
  33798. X      saverev=reverse;
  33799. X      savesize=size;
  33800. X      saverang=realangle;
  33801. X      savex=xpos;
  33802. X      savey=ypos;
  33803. X      savecolor=curcolor;
  33804. X      if ((command=drawLSys(command+1,rules,depth)) == NULL)
  33805. X         return(NULL);
  33806. X      angle=saveang;
  33807. X      reverse=saverev;
  33808. X      size=savesize;
  33809. X      realangle=saverang;
  33810. X      xpos=savex;
  33811. X      ypos=savey;
  33812. X      curcolor=savecolor;
  33813. X    }
  33814. X      }
  33815. X      command++;
  33816. X   }
  33817. X   return command;
  33818. X}
  33819. X
  33820. X#define MAXRULES 27 /* this limits rules to 25 */
  33821. Xstatic char far *ruleptrs[MAXRULES];
  33822. Xstatic struct lsys_cmd far *rules2[MAXRULES];
  33823. X
  33824. Xstatic int _fastcall readLSystemFile(char *str)
  33825. X{
  33826. X   int c;
  33827. X   char far **rulind;
  33828. X   int err=0;
  33829. X   int linenum,check=0;
  33830. X   char inline[161],fixed[161],*word;
  33831. X   FILE *infile;
  33832. X   char msgbuf[481]; /* enough for 6 full lines */
  33833. X
  33834. X   if (find_file_item(LFileName,str,&infile) < 0)
  33835. X      return -1;
  33836. X   while ((c = fgetc(infile)) != '{')
  33837. X      if (c == EOF) return -1;
  33838. X
  33839. X   maxangle=0;
  33840. X   for(linenum=0;linenum<MAXRULES;++linenum) ruleptrs[linenum]=NULL;
  33841. X   rulind= &ruleptrs[1];
  33842. X   msgbuf[0]=linenum=0;
  33843. X
  33844. X   while(fgets(inline,160,infile))  /* Max line length 160 chars */
  33845. X   {
  33846. X      linenum++;
  33847. X      if ((word = strchr(inline,';'))) /* strip comment */
  33848. X     *word = 0;
  33849. X      strlwr(inline);
  33850. X
  33851. X      if (strspn(inline," \t\n") < strlen(inline)) /* not a blank line */
  33852. X      {
  33853. X     word=strtok(inline," =\t\n");
  33854. X     if (!strcmp(word,"axiom"))
  33855. X     {
  33856. X        save_rule(strtok(NULL," \t\n"),&ruleptrs[0]);
  33857. X        check=1;
  33858. X     }
  33859. X     else if (!strcmp(word,"angle"))
  33860. X     {
  33861. X        maxangle=atoi(strtok(NULL," \t\n"));
  33862. X        dmaxangle = maxangle - 1;
  33863. X        check=1;
  33864. X     }
  33865. X     else if (!strcmp(word,"}"))
  33866. X        break;
  33867. X     else if (strlen(word)==1)
  33868. X     {
  33869. X        char *tok;
  33870. X        tok = strtok(NULL, " \t\n");
  33871. X        strcpy(fixed, word);
  33872. X        if (tok != NULL) {     /* Some strcat's die if they cat with NULL */
  33873. X        strcat(fixed, tok);
  33874. X        }
  33875. X        save_rule(fixed, rulind++);
  33876. X        check=1;
  33877. X     }
  33878. X     else
  33879. X        if (err<6)
  33880. X        {
  33881. X           sprintf(&msgbuf[strlen(msgbuf)],
  33882. X               "Syntax error line %d: %s\n",linenum,word);
  33883. X           ++err;
  33884. X        }
  33885. X     if (check)
  33886. X     {
  33887. X        check=0;
  33888. X        if(word=strtok(NULL," \t\n"))
  33889. X           if (err<6)
  33890. X           {
  33891. X          sprintf(&msgbuf[strlen(msgbuf)],
  33892. X             "Extra text after command line %d: %s\n",linenum,word);
  33893. X          ++err;
  33894. X           }
  33895. X     }
  33896. X      }
  33897. X   }
  33898. X   fclose(infile);
  33899. X   if (!ruleptrs[0] && err<6)
  33900. X   {
  33901. X      strcat(msgbuf,"Error:  no axiom\n");
  33902. X      ++err;
  33903. X   }
  33904. X   if ((maxangle<3||maxangle>50) && err<6)
  33905. X   {
  33906. X      strcat(msgbuf,"Error:  illegal or missing angle\n");
  33907. X      ++err;
  33908. X   }
  33909. X   if (err)
  33910. X   {
  33911. X      msgbuf[strlen(msgbuf)-1]=0; /* strip trailing \n */
  33912. X      stopmsg(0,msgbuf);
  33913. X      return -1;
  33914. X   }
  33915. X   *rulind=NULL;
  33916. X   return 0;
  33917. X}
  33918. X
  33919. Xstatic char loaded=0;
  33920. X
  33921. Xint Lsystem()
  33922. X{
  33923. X   int order;
  33924. X   char far **rulesc;
  33925. X   struct lsys_cmd far **sc;
  33926. X
  33927. X   if ( (!loaded) && LLoad())
  33928. X     return -1;
  33929. X
  33930. X   overflow = 0;        /* reset integer math overflow flag */
  33931. X
  33932. X   order=param[0];
  33933. X   if (order<=0)
  33934. X     order=0;
  33935. X   stackoflow = 0;
  33936. X
  33937. X   sc = rules2;
  33938. X   for (rulesc = ruleptrs; *rulesc; rulesc++)
  33939. X     *sc++ = SizeTransform(*rulesc);
  33940. X   *sc = NULL;
  33941. X
  33942. X   if (findscale(rules2[0], &rules2[1], order)) {
  33943. X      realangle = angle = reverse = 0;
  33944. X
  33945. X      free_lcmds();
  33946. X      sc = rules2;
  33947. X      for (rulesc = ruleptrs; *rulesc; rulesc++)
  33948. X    *sc++ = DrawTransform(*rulesc);
  33949. X      *sc = NULL;
  33950. X
  33951. X      /* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */
  33952. X      if ((curcolor=15) > colors) curcolor=colors-1;
  33953. X      drawLSys(rules2[0], &rules2[1], order);
  33954. X   }
  33955. X   if (stackoflow)
  33956. X   {
  33957. X      static char far msg[]={"insufficient memory, try a lower order"};
  33958. X      stopmsg(0,msg);
  33959. X   }
  33960. X   if (overflow) {
  33961. X      static char far msg[]={"Integer math routines failed, try a lower order"};
  33962. X      stopmsg(0,msg);
  33963. X      }
  33964. X   free_rules_mem();
  33965. X   free_lcmds();
  33966. X   loaded=0;
  33967. X   return 0;
  33968. X}
  33969. X
  33970. Xint LLoad()
  33971. X{
  33972. X   char i;
  33973. X   if (readLSystemFile(LName)) { /* error occurred */
  33974. X      free_rules_mem();
  33975. X      loaded=0;
  33976. X      return -1;
  33977. X   }
  33978. X   for(i=0;i<maxangle;i++) {
  33979. X      sins[i]=(long) ((sin(2*i*PI/maxangle)) * FIXEDLT1);
  33980. X      coss[i]=(long) (((double) aspect / (double) FIXEDMUL * cos(2*i*PI/maxangle)) * FIXEDLT1);
  33981. X   }
  33982. X   loaded=1;
  33983. X   return 0;
  33984. X}
  33985. X
  33986. Xstatic void _fastcall free_rules_mem()
  33987. X{
  33988. X   int i;
  33989. X   for(i=0;i<MAXRULES;++i)
  33990. X      if(ruleptrs[i]) farmemfree(ruleptrs[i]);
  33991. X}
  33992. X
  33993. Xstatic int _fastcall save_rule(char *rule,char far **saveptr)
  33994. X{
  33995. X   int i;
  33996. X   char far *tmpfar;
  33997. X   i=strlen(rule)+1;
  33998. X   if((tmpfar=farmemalloc((long)i))==NULL) {
  33999. X       stackoflow = 1;
  34000. X       return -1;
  34001. X       }
  34002. X   *saveptr=tmpfar;
  34003. X   while(--i>=0) *(tmpfar++)= *(rule++);
  34004. X   return 0;
  34005. X}
  34006. X
  34007. Xstatic struct lsys_cmd far *SizeTransform(char far *s)
  34008. X{
  34009. X  struct lsys_cmd far *ret;
  34010. X  struct lsys_cmd far *doub;
  34011. X  int maxval = 10;
  34012. X  int n = 0;
  34013. X  void (*f)(long);
  34014. X  long num;
  34015. X
  34016. X  void (*plus)(long) = (ispow2(maxangle)) ? lsys_doplus_pow2 : lsys_doplus;
  34017. X  void (*minus)(long) = (ispow2(maxangle)) ? lsys_dominus_pow2 : lsys_dominus;
  34018. X  void (*pipe)(long) = (ispow2(maxangle)) ? lsys_dopipe_pow2 : lsys_dopipe;
  34019. X
  34020. X  void (*slash)(long) =  (cpu == 386) ? lsys_doslash_386 : lsys_doslash;
  34021. X  void (*bslash)(long) = (cpu == 386) ? lsys_dobslash_386 : lsys_dobslash;
  34022. X  void (*at)(long) =     (cpu == 386) ? lsys_doat_386 : lsys_doat;
  34023. X  void (*dogf)(long) =   (cpu == 386) ? lsys_dosizegf_386 : lsys_dosizegf;
  34024. X
  34025. X  ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
  34026. X  if (ret == NULL) {
  34027. X       stackoflow = 1;
  34028. X       return NULL;
  34029. X       }
  34030. X  while (*s) {
  34031. X    f = NULL;
  34032. X    num = 0;
  34033. X    ret[n].ch = *s;
  34034. X    switch (*s) {
  34035. X      case '+': f = plus;            break;
  34036. X      case '-': f = minus;           break;
  34037. X      case '/': f = slash;           num = (long) (getnumber(&s) * 11930465L);    break;
  34038. X      case '\\': f = bslash;         num = (long) (getnumber(&s) * 11930465L);    break;
  34039. X      case '@': f = at;              num = FIXEDPT(getnumber(&s));    break;
  34040. X      case '|': f = pipe;            break;
  34041. X      case '!': f = lsys_dobang;     break;
  34042. X      case 'd':
  34043. X      case 'm': f = lsys_dosizedm;   break;
  34044. X      case 'g':
  34045. X      case 'f': f = dogf;       break;
  34046. X      case '[': num = 1;        break;
  34047. X      case ']': num = 2;        break;
  34048. X      default:
  34049. X    num = 3;
  34050. X    break;
  34051. X    }
  34052. X    ret[n].f = f;
  34053. X    ret[n].n = num;
  34054. X    if (++n == maxval) {
  34055. X      doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
  34056. X      if (doub == NULL) {
  34057. X         farmemfree(ret);
  34058. X         stackoflow = 1;
  34059. X         return NULL;
  34060. X         }
  34061. X      far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
  34062. X      farmemfree(ret);
  34063. X      ret = doub;
  34064. X      maxval <<= 1;
  34065. X    }
  34066. X    s++;
  34067. X  }
  34068. X  ret[n].ch = 0;
  34069. X  ret[n].f = NULL;
  34070. X  ret[n].n = 0;
  34071. X  n++;
  34072. X
  34073. X  doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
  34074. X  if (doub == NULL) {
  34075. X       farmemfree(ret);
  34076. X       stackoflow = 1;
  34077. X       return NULL;
  34078. X       }
  34079. X  far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
  34080. X  farmemfree(ret);
  34081. X  return doub;
  34082. X}
  34083. X
  34084. Xstatic struct lsys_cmd far *DrawTransform(char far *s)
  34085. X{
  34086. X  struct lsys_cmd far *ret;
  34087. X  struct lsys_cmd far *doub;
  34088. X  int maxval = 10;
  34089. X  int n = 0;
  34090. X  void (*f)(long);
  34091. X  long num;
  34092. X
  34093. X  void (*plus)(long) = (ispow2(maxangle)) ? lsys_doplus_pow2 : lsys_doplus;
  34094. X  void (*minus)(long) = (ispow2(maxangle)) ? lsys_dominus_pow2 : lsys_dominus;
  34095. X  void (*pipe)(long) = (ispow2(maxangle)) ? lsys_dopipe_pow2 : lsys_dopipe;
  34096. X
  34097. X  void (*slash)(long) =  (cpu == 386) ? lsys_doslash_386 : lsys_doslash;
  34098. X  void (*bslash)(long) = (cpu == 386) ? lsys_dobslash_386 : lsys_dobslash;
  34099. X  void (*at)(long) =     (cpu == 386) ? lsys_doat_386 : lsys_doat;
  34100. X  void (*drawg)(long) =  (cpu == 386) ? lsys_dodrawg_386 : lsys_dodrawg;
  34101. X
  34102. X  ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
  34103. X  if (ret == NULL) {
  34104. X       stackoflow = 1;
  34105. X       return NULL;
  34106. X       }
  34107. X  while (*s) {
  34108. X    f = NULL;
  34109. X    num = 0;
  34110. X    ret[n].ch = *s;
  34111. X    switch (*s) {
  34112. X      case '+': f = plus;            break;
  34113. X      case '-': f = minus;           break;
  34114. X      case '/': f = slash;           num = (long) (getnumber(&s) * 11930465L);    break;
  34115. X      case '\\': f = bslash;         num = (long) (getnumber(&s) * 11930465L);    break;
  34116. X      case '@': f = at;              num = FIXEDPT(getnumber(&s));    break;
  34117. X      case '|': f = pipe;            break;
  34118. X      case '!': f = lsys_dobang;     break;
  34119. X      case 'd': f = lsys_dodrawd;    break;
  34120. X      case 'm': f = lsys_dodrawm;    break;
  34121. X      case 'g': f = drawg;           break;
  34122. X      case 'f': f = lsys_dodrawf;    break;
  34123. X      case 'c': f = lsys_dodrawc;    num = getnumber(&s);    break;
  34124. X      case '<': f = lsys_dodrawlt;   num = getnumber(&s);    break;
  34125. X      case '>': f = lsys_dodrawgt;   num = getnumber(&s);    break;
  34126. X      case '[': num = 1;        break;
  34127. X      case ']': num = 2;        break;
  34128. X      default:
  34129. X    num = 3;
  34130. X    break;
  34131. X    }
  34132. X    ret[n].f = f;
  34133. X    ret[n].n = num;
  34134. X    if (++n == maxval) {
  34135. X      doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
  34136. X      if (doub == NULL) {
  34137. X           farmemfree(ret);
  34138. X           stackoflow = 1;
  34139. X           return NULL;
  34140. X           }
  34141. X      far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
  34142. X      farmemfree(ret);
  34143. X      ret = doub;
  34144. X      maxval <<= 1;
  34145. X    }
  34146. X    s++;
  34147. X  }
  34148. X  ret[n].ch = 0;
  34149. X  ret[n].f = NULL;
  34150. X  ret[n].n = 0;
  34151. X  n++;
  34152. X
  34153. X  doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
  34154. X  if (doub == NULL) {
  34155. X       farmemfree(ret);
  34156. X       stackoflow = 1;
  34157. X       return NULL;
  34158. X       }
  34159. X  far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
  34160. X  farmemfree(ret);
  34161. X  return doub;
  34162. X}
  34163. X
  34164. Xstatic void free_lcmds()
  34165. X{
  34166. X  struct lsys_cmd far **sc = rules2;
  34167. X
  34168. X  while (*sc)
  34169. X    farmemfree(*sc++);
  34170. X}
  34171. X
  34172. SHAR_EOF
  34173. $TOUCH -am 1028230093 lsys.c &&
  34174. chmod 0644 lsys.c ||
  34175. echo "restore of lsys.c failed"
  34176. set `wc -c lsys.c`;Wc_c=$1
  34177. if test "$Wc_c" != "21423"; then
  34178.     echo original size 21423, current size $Wc_c
  34179. fi
  34180. # ============= miscfrac.c ==============
  34181. echo "x - extracting miscfrac.c (Text)"
  34182. sed 's/^X//' << 'SHAR_EOF' > miscfrac.c &&
  34183. X/*
  34184. X
  34185. XMiscellaneous fractal-specific code (formerly in CALCFRAC.C)
  34186. X
  34187. X
  34188. X*/
  34189. X
  34190. X#include <stdio.h>
  34191. X#include <string.h>
  34192. X#include <stdlib.h>
  34193. X#include <float.h>
  34194. X#ifndef XFRACT
  34195. X#include <dos.h>
  34196. X#endif
  34197. X#include <limits.h>
  34198. X#include "fractint.h"
  34199. X#include "fractype.h"
  34200. X#include "mpmath.h"
  34201. X#include "targa_lc.h"
  34202. X#include "prototyp.h"
  34203. X
  34204. X/* routines in this module    */
  34205. X
  34206. Xstatic void set_Plasma_palette(void);
  34207. Xstatic U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb);
  34208. Xstatic void _fastcall subDivide(int x1,int y1,int x2,int y2);
  34209. Xstatic int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur);
  34210. Xstatic void verhulst(void);
  34211. Xstatic void Bif_Period_Init(void);
  34212. Xstatic int  _fastcall Bif_Periodic(int);
  34213. Xstatic void set_Cellular_palette(void);
  34214. X
  34215. XU16  (_fastcall *getpix)(int,int)  = (U16(_fastcall *)(int,int))getcolor;
  34216. X
  34217. Xextern int resuming;
  34218. Xextern char stdcalcmode;
  34219. Xextern int color, oldcolor, row, col, passes;
  34220. Xextern int ixstart, ixstop, iystart, iystop;
  34221. Xextern _CMPLX init,tmp,old,new,saved;
  34222. Xextern _CMPLX parm,parm2;
  34223. X
  34224. Xextern double far *dx0, far *dy0;
  34225. Xextern double far *dx1, far *dy1;
  34226. Xextern long far *lx0, far *ly0;
  34227. Xextern long far *lx1, far *ly1;
  34228. Xextern long delx, dely;
  34229. Xextern double deltaX, deltaY;
  34230. Xextern int sxoffs, syoffs, sxdots, sydots;
  34231. Xextern int xdots, ydots;
  34232. Xextern int maxit, inside, colors, andcolor, dotmode;
  34233. Xextern double param[];
  34234. Xextern int rflag, rseed;
  34235. Xextern int pot16bit, potflag;
  34236. Xextern int diskvideo;
  34237. Xextern int bitshift;
  34238. Xextern long fudge;
  34239. Xextern int show_orbit;
  34240. Xextern int periodicitycheck, integerfractal;
  34241. Xextern _LCMPLX linit;
  34242. Xextern _LCMPLX ltmp;
  34243. Xextern _LCMPLX lold,lnew,lparm,lparm2;
  34244. Xextern long ltempsqrx,ltempsqry;
  34245. Xextern double tempsqrx,tempsqry;
  34246. Xextern int overflow;
  34247. Xextern int kbdcount, max_kbdcount;
  34248. Xextern int reset_periodicity;
  34249. Xextern int calc_status;
  34250. Xextern int iterations, invert;
  34251. Xextern int save_release;
  34252. Xextern int LogFlag;
  34253. Xextern int (calctype());
  34254. Xextern int realcolor;
  34255. Xextern int nxtscreenflag;
  34256. Xextern double magnitude, rqlim, rqlim2, rqlim_save;
  34257. Xextern long lmagnitud, llimit, llimit2, lclosenuff, l16triglim;
  34258. Xextern int orbit_color, orbit_ptr, showdot;
  34259. Xextern int debugflag;
  34260. X
  34261. X#ifndef XFRACT
  34262. Xextern char dstack[4096];
  34263. Xextern char boxy[4096];
  34264. X#else
  34265. XBYTE dstack[4096];
  34266. X#endif
  34267. X
  34268. Xtypedef void (_fastcall *PLOT)(int,int,int);
  34269. X
  34270. X/***************** standalone engine for "test" ********************/
  34271. X
  34272. Xint test()
  34273. X{
  34274. X   int startrow,startpass,numpasses;
  34275. X   startrow = startpass = 0;
  34276. X   if (resuming)
  34277. X   {
  34278. X      start_resume();
  34279. X      get_resume(sizeof(int),&startrow,sizeof(int),&startpass,0);
  34280. X      end_resume();
  34281. X   }
  34282. X   if(teststart()) /* assume it was stand-alone, doesn't want passes logic */
  34283. X      return(0);
  34284. X   numpasses = (stdcalcmode == '1') ? 0 : 1;
  34285. X   for (passes=startpass; passes <= numpasses ; passes++)
  34286. X   {
  34287. X      for (row = startrow; row <= iystop; row=row+1+numpasses)
  34288. X      {
  34289. X     register int col;
  34290. X     for (col = 0; col <= ixstop; col++)       /* look at each point on screen */
  34291. X     {
  34292. X        register color;
  34293. X        init.y = dy0[row]+dy1[col];
  34294. X        init.x = dx0[col]+dx1[row];
  34295. X        if(check_key())
  34296. X        {
  34297. X           testend();
  34298. X           alloc_resume(20,1);
  34299. X           put_resume(sizeof(int),&row,sizeof(int),&passes,0);
  34300. X           return(-1);
  34301. X        }
  34302. X        color = testpt(init.x,init.y,parm.x,parm.y,maxit,inside);
  34303. X        if (color >= colors) /* avoid trouble if color is 0 */
  34304. X           if (colors < 16)
  34305. X          color &= andcolor;
  34306. X           else
  34307. X          color = ((color-1) % andcolor) + 1; /* skip color zero */
  34308. X        (*plot)(col,row,color);
  34309. X        if(numpasses && (passes == 0))
  34310. X           (*plot)(col,row+1,color);
  34311. X     }
  34312. X      }
  34313. X      startrow = passes + 1;
  34314. X   }
  34315. X   testend();
  34316. X   return(0);
  34317. X}
  34318. X
  34319. X/***************** standalone engine for "plasma" ********************/
  34320. X
  34321. Xstatic int iparmx;      /* iparmx = parm.x * 16 */
  34322. Xstatic int shiftvalue;  /* shift based on #colors */
  34323. Xextern int max_colors;
  34324. Xstatic int recur1=1;
  34325. Xstatic int pcolors;
  34326. Xstatic int recur_level = 0;
  34327. XU16 max_plasma;
  34328. X
  34329. X/* returns a random 16 bit value that is never 0 */
  34330. XU16 rand16()
  34331. X{
  34332. X   U16 value;
  34333. X   value = rand15();
  34334. X   value <<= 1;
  34335. X   value += rand15()&1;
  34336. X   if(value < 1)
  34337. X      value = 1;
  34338. X   return(value);
  34339. X}
  34340. X
  34341. Xvoid _fastcall putpot(int x, int y, U16 color)
  34342. X{
  34343. X   if(color < 1)
  34344. X      color = 1;
  34345. X   putcolor(x, y, color >> 8 ? color >> 8 : 1);  /* don't write 0 */
  34346. X   /* we don't write this if dotmode==11 because the above putcolor
  34347. X         was already a "writedisk" in that case */
  34348. X   if (dotmode != 11)
  34349. X      writedisk(x+sxoffs,y+syoffs,color >> 8);    /* upper 8 bits */
  34350. X   writedisk(x+sxoffs,y+sydots+syoffs,color&255); /* lower 8 bits */
  34351. X}
  34352. X
  34353. XU16 _fastcall getpot(int x, int y)
  34354. X{
  34355. X   U16 color;
  34356. X
  34357. X   color = (U16)readdisk(x+sxoffs,y+syoffs);
  34358. X   color = (color << 8) + (U16) readdisk(x+sxoffs,y+sydots+syoffs);
  34359. X   return(color);
  34360. X}
  34361. X
  34362. X
  34363. Xtypedef struct palett
  34364. X{
  34365. X   BYTE red;
  34366. X   BYTE green;
  34367. X   BYTE blue;
  34368. X}
  34369. XPalettetype;
  34370. X
  34371. Xextern Palettetype dacbox[256];
  34372. Xstatic int plasma_check;                        /* to limit kbd checking */
  34373. X
  34374. Xstatic U16 _fastcall adjust(int xa,int ya,int x,int y,int xb,int yb)
  34375. X{
  34376. X   S32 pseudorandom;
  34377. X   pseudorandom = ((S32)iparmx)*((rand15()-16383));
  34378. X/*   pseudorandom = pseudorandom*(abs(xa-xb)+abs(ya-yb));*/
  34379. X   pseudorandom = pseudorandom * recur1;
  34380. X   pseudorandom = pseudorandom >> shiftvalue;
  34381. X   pseudorandom = (((S32)getpix(xa,ya)+(S32)getpix(xb,yb)+1)>>1)+pseudorandom;
  34382. X   if(max_plasma == 0)
  34383. X   {
  34384. X      if (pseudorandom >= pcolors)
  34385. X         pseudorandom = pcolors-1;
  34386. X   }
  34387. X   else if (pseudorandom >= max_plasma)
  34388. X      pseudorandom = max_plasma;
  34389. X   if(pseudorandom < 1)
  34390. X      pseudorandom = 1;
  34391. X   plot(x,y,(U16)pseudorandom);
  34392. X   return((U16)pseudorandom);
  34393. X}
  34394. X
  34395. X
  34396. Xstatic int _fastcall new_subD (int x1,int y1,int x2,int y2, int recur)
  34397. X{
  34398. X   int x,y;
  34399. X   int nx1;
  34400. X   int nx;
  34401. X   int ny1, ny;
  34402. X   S32 i, v;
  34403. X
  34404. X   struct sub {
  34405. X      BYTE t; /* top of stack */
  34406. X      int v[16]; /* subdivided value */
  34407. X      BYTE r[16];  /* recursion level */
  34408. X   };
  34409. X
  34410. X   static struct sub subx, suby;
  34411. X
  34412. X   /*
  34413. X   recur1=1;
  34414. X   for (i=1;i<=recur;i++)
  34415. X      recur1 = recur1 * 2;
  34416. X   recur1=320/recur1;
  34417. X   */
  34418. X   recur1 = 320L >> recur;
  34419. X   suby.t = 2;
  34420. X   ny   = suby.v[0] = y2;
  34421. X   ny1 = suby.v[2] = y1;
  34422. X   suby.r[0] = suby.r[2] = 0;
  34423. X   suby.r[1] = 1;
  34424. X   y = suby.v[1] = (ny1 + ny) >> 1;
  34425. X
  34426. X   while (suby.t >= 1)
  34427. X   {
  34428. X      if ((++plasma_check & 0x0f) == 1)
  34429. X         if(check_key())
  34430. X         {
  34431. X/*   naah, we don't want to flush this key!!!
  34432. X                        getch();
  34433. X            */
  34434. X            plasma_check--;
  34435. X            return(1);
  34436. X         }
  34437. X      while (suby.r[suby.t-1] < recur)
  34438. X      {
  34439. X         /*     1.  Create new entry at top of the stack  */
  34440. X         /*     2.  Copy old top value to new top value.  */
  34441. X         /*            This is largest y value.           */
  34442. X         /*     3.  Smallest y is now old mid point       */
  34443. X         /*     4.  Set new mid point recursion level     */
  34444. X         /*     5.  New mid point value is average        */
  34445. X         /*            of largest and smallest            */
  34446. X
  34447. X         suby.t++;
  34448. X         ny1  = suby.v[suby.t] = suby.v[suby.t-1];
  34449. X         ny   = suby.v[suby.t-2];
  34450. X         suby.r[suby.t] = suby.r[suby.t-1];
  34451. X         y    = suby.v[suby.t-1]   = (ny1 + ny) >> 1;
  34452. X         suby.r[suby.t-1]   = (int)max(suby.r[suby.t], suby.r[suby.t-2])+1;
  34453. X      }
  34454. X      subx.t = 2;
  34455. X      nx  = subx.v[0] = x2;
  34456. X      nx1 = subx.v[2] = x1;
  34457. X      subx.r[0] = subx.r[2] = 0;
  34458. X      subx.r[1] = 1;
  34459. X      x = subx.v[1] = (nx1 + nx) >> 1;
  34460. X
  34461. X      while (subx.t >= 1)
  34462. X      {
  34463. X         while (subx.r[subx.t-1] < recur)
  34464. X         {
  34465. X            subx.t++; /* move the top ofthe stack up 1 */
  34466. X            nx1  = subx.v[subx.t] = subx.v[subx.t-1];
  34467. X            nx   = subx.v[subx.t-2];
  34468. X            subx.r[subx.t] = subx.r[subx.t-1];
  34469. X            x    = subx.v[subx.t-1]   = (nx1 + nx) >> 1;
  34470. X            subx.r[subx.t-1]   = (int)max(subx.r[subx.t],
  34471. X                subx.r[subx.t-2])+1;
  34472. X         }
  34473. X
  34474. X         if ((i = getpix(nx, y)) == 0)
  34475. X            i = adjust(nx,ny1,nx,y ,nx,ny);
  34476. X         v = i;
  34477. X         if ((i = getpix(x, ny)) == 0)
  34478. X            i = adjust(nx1,ny,x ,ny,nx,ny);
  34479. X         v += i;
  34480. X         if(getpix(x,y) == 0)
  34481. X         {
  34482. X            if ((i = getpix(x, ny1)) == 0)
  34483. X               i = adjust(nx1,ny1,x ,ny1,nx,ny1);
  34484. X            v += i;
  34485. X            if ((i = getpix(nx1, y)) == 0)
  34486. X               i = adjust(nx1,ny1,nx1,y ,nx1,ny);
  34487. X            v += i;
  34488. X            plot(x,y,(U16)((v + 2) >> 2));
  34489. X         }
  34490. X
  34491. X         if (subx.r[subx.t-1] == recur) subx.t = subx.t - 2;
  34492. X      }
  34493. X
  34494. X      if (suby.r[suby.t-1] == recur) suby.t = suby.t - 2;
  34495. X   }
  34496. X   return(0);
  34497. X}
  34498. X
  34499. Xstatic void _fastcall subDivide(int x1,int y1,int x2,int y2)
  34500. X{
  34501. X   int x,y;
  34502. X   S32 v,i;
  34503. X   if ((++plasma_check & 0x7f) == 1)
  34504. X      if(check_key())
  34505. X      {
  34506. X         plasma_check--;
  34507. X         return;
  34508. X      }
  34509. X   if(x2-x1<2 && y2-y1<2)
  34510. X      return;
  34511. X   recur_level++;
  34512. X   recur1 = 320L >> recur_level;
  34513. X
  34514. X   x = (x1+x2)>>1;
  34515. X   y = (y1+y2)>>1;
  34516. X   if((v=getpix(x,y1)) == 0)
  34517. X      v=adjust(x1,y1,x ,y1,x2,y1);
  34518. X   i=v;
  34519. X   if((v=getpix(x2,y)) == 0)
  34520. X      v=adjust(x2,y1,x2,y ,x2,y2);
  34521. X   i+=v;
  34522. X   if((v=getpix(x,y2)) == 0)
  34523. X      v=adjust(x1,y2,x ,y2,x2,y2);
  34524. X   i+=v;
  34525. X   if((v=getpix(x1,y)) == 0)
  34526. X      v=adjust(x1,y1,x1,y ,x1,y2);
  34527. X   i+=v;
  34528. X
  34529. X   if(getpix(x,y) == 0)
  34530. X      plot(x,y,(U16)((i+2)>>2));
  34531. X
  34532. X   subDivide(x1,y1,x ,y);
  34533. X   subDivide(x ,y1,x2,y);
  34534. X   subDivide(x ,y ,x2,y2);
  34535. X   subDivide(x1,y ,x ,y2);
  34536. X   recur_level--;
  34537. X}
  34538. X
  34539. Xint plasma()
  34540. X{
  34541. X   int i,k, n;
  34542. X   U16 rnd[4];
  34543. X   int OldPotFlag, OldPot16bit;
  34544. X
  34545. X   plasma_check = 0;
  34546. X
  34547. X   if(colors < 4) {
  34548. X      static char far plasmamsg[]={
  34549. X         "\
  34550. XPlasma Clouds can currently only be run in a 4-or-more-color video\n\
  34551. Xmode (and color-cycled only on VGA adapters [or EGA adapters in their\n\
  34552. X640x350x16 mode])."      };
  34553. X      stopmsg(0,plasmamsg);
  34554. X      return(-1);
  34555. X   }
  34556. X   iparmx = param[0] * 8;
  34557. X   if (parm.x <= 0.0) iparmx = 16;
  34558. X   if (parm.x >= 100) iparmx = 800;
  34559. X
  34560. X   if ((!rflag) && param[2] == 1)
  34561. X      --rseed;
  34562. X   if (param[2] != 0 && param[2] != 1)
  34563. X      rseed = param[2];
  34564. X   max_plasma = (U16)param[3];  /* max_plasma is used as a flag for potential */
  34565. X
  34566. X   if(max_plasma != 0)
  34567. X   {
  34568. X      if (pot_startdisk() >= 0)
  34569. X      {
  34570. X     max_plasma = (U16)(1L << 16) -1;
  34571. X     plot    = (PLOT)putpot;
  34572. X     getpix =  getpot;
  34573. X     OldPotFlag = potflag;
  34574. X     OldPot16bit = pot16bit;
  34575. X      }
  34576. X      else
  34577. X      {
  34578. X     max_plasma = 0;    /* can't do potential (startdisk failed) */
  34579. X     param[3]   = 0;
  34580. X     plot    = putcolor;
  34581. X       getpix  = (U16(_fastcall *)(int,int))getcolor;
  34582. X      }
  34583. X   }
  34584. X   else
  34585. X   {
  34586. X      plot    = putcolor;
  34587. X      getpix  = (U16(_fastcall *)(int,int))getcolor;
  34588. X   }
  34589. X   srand(rseed);
  34590. X   if (!rflag) ++rseed;
  34591. X
  34592. X   if (colors == 256)                   /* set the (256-color) palette */
  34593. X      set_Plasma_palette();             /* skip this if < 256 colors */
  34594. X
  34595. X   if (colors > 16)
  34596. X      shiftvalue = 18;
  34597. X   else
  34598. X   {
  34599. X      if (colors > 4)
  34600. X         shiftvalue = 22;
  34601. X      else
  34602. X      {
  34603. X         if (colors > 2)
  34604. X            shiftvalue = 24;
  34605. X         else
  34606. X            shiftvalue = 25;
  34607. X      }
  34608. X   }
  34609. X   if(max_plasma != 0)
  34610. X      shiftvalue = 10;
  34611. X
  34612. X   if(max_plasma == 0)
  34613. X   {
  34614. X      pcolors = min(colors, max_colors);
  34615. X      for(n = 0; n < 4; n++)
  34616. X         rnd[n] = 1+(((rand15()/pcolors)*(pcolors-1))>>(shiftvalue-11));
  34617. X   }
  34618. X   else
  34619. X      for(n = 0; n < 4; n++)
  34620. X         rnd[n] = rand16();
  34621. X   plot(      0,      0,  rnd[0]);
  34622. X   plot(xdots-1,      0,  rnd[1]);
  34623. X   plot(xdots-1,ydots-1,  rnd[2]);
  34624. X   plot(      0,ydots-1,  rnd[3]);
  34625. X
  34626. X   recur_level = 0;
  34627. X   if (param[1] == 0)
  34628. X      subDivide(0,0,xdots-1,ydots-1);
  34629. X   else
  34630. X   {
  34631. X      recur1 = i = k = 1;
  34632. X      while(new_subD(0,0,xdots-1,ydots-1,i)==0)
  34633. X      {
  34634. X         k = k * 2;
  34635. X         if (k  >(int)max(xdots-1,ydots-1))
  34636. X            break;
  34637. X         if (check_key())
  34638. X         {
  34639. X            n = 1;
  34640. X            goto done;
  34641. X         }
  34642. X         i++;
  34643. X      }
  34644. X   }
  34645. X   if (! check_key())
  34646. X      n = 0;
  34647. X   else
  34648. X      n = 1;
  34649. X   done:
  34650. X   if(max_plasma != 0)
  34651. X   {
  34652. X      potflag = OldPotFlag;
  34653. X      pot16bit = OldPot16bit;
  34654. X   }
  34655. X   plot    = putcolor;
  34656. X   getpix  = (U16(_fastcall *)(int,int))getcolor;
  34657. X   return(n);
  34658. X}
  34659. X
  34660. Xstatic void set_Plasma_palette()
  34661. X{
  34662. X   extern char far *mapdacbox;
  34663. X   static Palettetype Red    = {
  34664. X      63, 0, 0      };
  34665. X   static Palettetype Green  = {
  34666. X      0,63, 0      };
  34667. X   static Palettetype Blue   = {
  34668. X      0, 0,63      };
  34669. X   int i;
  34670. X
  34671. X   if (mapdacbox) return;               /* map= specified */
  34672. X
  34673. X   dacbox[0].red  = 0 ;
  34674. X   dacbox[0].green= 0 ;
  34675. X   dacbox[0].blue = 0 ;
  34676. X   for(i=1;i<=85;i++)
  34677. X   {
  34678. X      dacbox[i].red       = (i*Green.red   + (86-i)*Blue.red)/85;
  34679. X      dacbox[i].green     = (i*Green.green + (86-i)*Blue.green)/85;
  34680. X      dacbox[i].blue      = (i*Green.blue  + (86-i)*Blue.blue)/85;
  34681. X
  34682. X      dacbox[i+85].red    = (i*Red.red   + (86-i)*Green.red)/85;
  34683. X      dacbox[i+85].green  = (i*Red.green + (86-i)*Green.green)/85;
  34684. X      dacbox[i+85].blue   = (i*Red.blue  + (86-i)*Green.blue)/85;
  34685. X
  34686. X      dacbox[i+170].red   = (i*Blue.red   + (86-i)*Red.red)/85;
  34687. X      dacbox[i+170].green = (i*Blue.green + (86-i)*Red.green)/85;
  34688. X      dacbox[i+170].blue  = (i*Blue.blue  + (86-i)*Red.blue)/85;
  34689. X   }
  34690. X   SetTgaColors();      /* TARGA 3 June 89  j mclain */
  34691. X   spindac(0,1);
  34692. X}
  34693. X
  34694. X
  34695. X/***************** standalone engine for "diffusion" ********************/
  34696. X
  34697. X#define RANDOM(x)  (rand()%(x))
  34698. X
  34699. X/* This constant assumes that rand() returns a value from 0 to 32676 */
  34700. X#define FOURPI  (long)(4*PI*(double)(1L << 16))
  34701. X
  34702. Xint diffusion()
  34703. X{
  34704. X   int xmax,ymax,xmin,ymin;     /* Current maximum coordinates */
  34705. X   int border;   /* Distance between release point and fractal */
  34706. X   int mode;     /* Determines diffusion type:  0 = central (classic) */
  34707. X                 /*                             1 = falling particles */
  34708. X                 /*                             2 = square cavity     */
  34709. X   int i;
  34710. X   double cosine,sine,angle;
  34711. X   long lcosine,lsine;
  34712. X   int x,y;
  34713. X   float r, radius, f_tmp;
  34714. X   extern char floatflag;
  34715. X
  34716. X   if (diskvideo)
  34717. X      notdiskmsg();
  34718. X
  34719. X   bitshift = 16;
  34720. X   fudge = 1L << 16;
  34721. X
  34722. X   border = param[0];
  34723. X   mode = param[1];
  34724. X   if (mode > 2)
  34725. X      mode=0;
  34726. X
  34727. X   if (border <= 0)
  34728. X      border = 10;
  34729. X
  34730. X   srand(rseed);
  34731. X   if (!rflag) ++rseed;
  34732. X
  34733. X   if (mode == 0) {
  34734. X      xmax = xdots / 2 + border;  /* Initial box */
  34735. X      xmin = xdots / 2 - border;
  34736. X      ymax = ydots / 2 + border;
  34737. X      ymin = ydots / 2 - border;
  34738. X   }
  34739. X   if (mode == 1) {
  34740. X      xmax = xdots / 2 + border;  /* Initial box */
  34741. X      xmin = xdots / 2 - border;
  34742. X      ymin = ydots - 20;
  34743. X   }
  34744. X   if (mode == 2) {
  34745. X      if (xdots>ydots)
  34746. X         radius = ydots - 5;
  34747. X      else
  34748. X         radius = xdots - 5;
  34749. X   }
  34750. X   if (resuming) /* restore worklist, if we can't the above will stay in place */
  34751. X   {
  34752. X      start_resume();
  34753. X      if (mode != 2)
  34754. X         get_resume(sizeof(int),&xmax,sizeof(int),&xmin,sizeof(int),&ymax,
  34755. X             sizeof(int),&ymin,0);
  34756. X      else
  34757. X         get_resume(sizeof(int),&xmax,sizeof(int),&xmin,sizeof(int),&ymax,
  34758. X             sizeof(int),&radius,0);
  34759. X      end_resume();
  34760. X   }
  34761. X
  34762. X   if (mode==0)
  34763. X      putcolor(xdots / 2, ydots / 2,RANDOM(colors-1)+1);  /* Seed point */
  34764. X
  34765. X   if (mode==1)
  34766. X      for (i=0;i<=xdots;i++)
  34767. X         putcolor(i,ydots-1,colors-1);
  34768. X
  34769. X   if (mode==2){
  34770. X      if (xdots>ydots){
  34771. X         for (i=0;i<ydots;i++){
  34772. X            putcolor(xdots/2-ydots/2 , i , colors-1);
  34773. X            putcolor(xdots/2+ydots/2 , i , colors-1);
  34774. X            putcolor(xdots/2-ydots/2+i , 0 , colors-1);
  34775. X            putcolor(xdots/2-ydots/2+i , ydots-1 , colors-1);
  34776. X         }
  34777. X      }
  34778. X      else {
  34779. X         for (i=0;i<xdots;i++){
  34780. X            putcolor(0 , ydots/2-xdots/2+i , colors-1);
  34781. X            putcolor(xdots-1 , ydots/2-xdots/2+i , colors-1);
  34782. X            putcolor(i , ydots/2-xdots/2 , colors-1);
  34783. X            putcolor(i , ydots/2+xdots/2 , colors-1);
  34784. X         }
  34785. X      }
  34786. X   }
  34787. X
  34788. X   while (1)
  34789. X   {
  34790. X      /* Release new point on circle just inside the box */
  34791. X
  34792. X      if (mode==0)
  34793. X      {
  34794. X         if (floatflag)
  34795. X         {
  34796. X            angle=2*(double)rand()/(RAND_MAX/PI);
  34797. X            FPUsincos(&angle,&sine,&cosine);
  34798. X            x = cosine*(xmax-xmin) + xdots;
  34799. X            y = sine  *(ymax-ymin) + ydots;
  34800. X         }
  34801. X         else
  34802. X         {
  34803. X            SinCos086(multiply((long)rand15(),FOURPI,16),&lsine,&lcosine);
  34804. X            x = (lcosine*(long)(xmax-xmin) >> 16) + xdots;
  34805. X            y = (lsine  *(long)(ymax-ymin) >> 16) + ydots;
  34806. X         }
  34807. X
  34808. X         x = x >> 1; /* divide by 2 */
  34809. X         y = y >> 1;
  34810. X      }
  34811. X      if (mode==1)
  34812. X      {
  34813. X         y=ymin;
  34814. X         x=RANDOM(xmax-xmin) + (xdots-xmax+xmin)/2;
  34815. X      }
  34816. X      if (mode==2)
  34817. X      {
  34818. X         if (floatflag)
  34819. X         {
  34820. X            angle=2*(double)rand()/(RAND_MAX/PI);
  34821. X            FPUsincos(&angle,&sine,&cosine);
  34822. X            x = cosine*radius + xdots;
  34823. X            y = sine  *radius + ydots;
  34824. X         }
  34825. X         else
  34826. X         {
  34827. X            SinCos086(multiply((long)rand15(),FOURPI,16),&lsine,&lcosine);
  34828. X            x = (lcosine*(long)(radius) >> 16) + xdots;
  34829. X            y = (lsine  *(long)(radius) >> 16) + ydots;
  34830. X         }
  34831. X         x = x >> 1;
  34832. X         y = y >> 1;
  34833. X      }
  34834. X      /* Loop as long as the point (x,y) is surrounded by color 0 */
  34835. X      /* on all eight sides                                       */
  34836. X      while((getcolor(x+1,y+1) == 0) && (getcolor(x+1,y) == 0) &&
  34837. X          (getcolor(x+1,y-1) == 0) && (getcolor(x  ,y+1) == 0) &&
  34838. X          (getcolor(x  ,y-1) == 0) && (getcolor(x-1,y+1) == 0) &&
  34839. X          (getcolor(x-1,y) == 0) && (getcolor(x-1,y-1) == 0))
  34840. X      {
  34841. X         /* Erase moving point */
  34842. X         if (show_orbit)
  34843. X            putcolor(x,y,0);
  34844. X
  34845. X         /* Make sure point is inside the box (if mode==0)*/
  34846. X         if (mode==0){
  34847. X            if (x==xmax)
  34848. X               x--;
  34849. X            else if (x==xmin)
  34850. X               x++;
  34851. X            if (y==ymax)
  34852. X               y--;
  34853. X            else if (y==ymin)
  34854. X               y++;
  34855. X         }
  34856. X
  34857. X         if (mode==1)
  34858. X         {
  34859. X            if (x>xdots-2)
  34860. X               x--;
  34861. X            else if (x<1)
  34862. X               x++;
  34863. X            if (y<ymin)
  34864. X               y++;
  34865. X         }
  34866. X
  34867. X         /* Take one random step */
  34868. X         x += RANDOM(3) - 1;
  34869. X         y += RANDOM(3) - 1;
  34870. X
  34871. X         /* Check keyboard */
  34872. X         if ((++plasma_check & 0x7f) == 1)
  34873. X            if(check_key())
  34874. X            {
  34875. X               alloc_resume(20,1);
  34876. X               if (mode!=2)
  34877. X                  put_resume(sizeof(int),&xmax,sizeof(int),&xmin, sizeof(int),&ymax,
  34878. X                      sizeof(int),&ymin,0);
  34879. X               else
  34880. X                  put_resume(sizeof(int),&xmax,sizeof(int),&xmin, sizeof(int),&ymax,
  34881. X                      sizeof(int),&radius,0);
  34882. X
  34883. X               plasma_check--;
  34884. X               return 1;
  34885. X            }
  34886. X
  34887. X         /* Show the moving point */
  34888. X         if (show_orbit)
  34889. X            putcolor(x,y,RANDOM(colors-1)+1);
  34890. X
  34891. X      }
  34892. X      putcolor(x,y,RANDOM(colors-1)+1);
  34893. X
  34894. X      /* Is point too close to the edge? */
  34895. X
  34896. X      if (mode==0)
  34897. X      {
  34898. X         if (((x+border)>xmax) || ((x-border)<xmin)
  34899. X             || ((y-border)<ymin) || ((y+border)>ymax))
  34900. X         {
  34901. X            /* Increase box size, but not past the edge of the screen */
  34902. X            if (ymin != 1)
  34903. X            {
  34904. X               ymin--;
  34905. X               ymax++;
  34906. X            }
  34907. X            if (xmin != 1)
  34908. X            {
  34909. X               xmin--;
  34910. X               xmax++;
  34911. X            }
  34912. X            if ((ymin==1) || (xmin==1))
  34913. X               return 0;
  34914. X         }
  34915. X      }
  34916. X      if (mode==1)
  34917. X      {
  34918. X         if (y < ymin+5)
  34919. X            ymin = y - 5;
  34920. X         if (ymin<2)
  34921. X            return 0;
  34922. X      }
  34923. X      if (mode==2)
  34924. X      {
  34925. X         if (abs(x-xdots/2)<5 && abs(y-ydots/2)<5)
  34926. X            return 0;
  34927. X
  34928. X         r = (x-xdots/2)*(x-xdots/2)+(y-ydots/2)*(y-ydots/2);
  34929. X         fSqrt14(r,f_tmp);
  34930. X         r = 2 * f_tmp;
  34931. X         if (r < radius)
  34932. X            radius = r;
  34933. X      }
  34934. X   }
  34935. X}
  34936. X
  34937. X/************ standalone engine for "bifurcation" types ***************/
  34938. X
  34939. X/***************************************************************/
  34940. X/* The following code now forms a generalised Fractal Engine   */
  34941. X/* for Bifurcation fractal typeS.  By rights it now belongs in */
  34942. X/* CALCFRACT.C, but it's easier for me to leave it here !      */
  34943. X
  34944. X/* Original code by Phil Wilson, hacked around by Kev Allen.   */
  34945. X
  34946. X/* Besides generalisation, enhancements include Periodicity    */
  34947. X/* Checking during the plotting phase (AND halfway through the */
  34948. X/* filter cycle, if possible, to halve calc times), quicker    */
  34949. X/* floating-point calculations for the standard Verhulst type, */
  34950. X/* and new bifurcation types (integer bifurcation, f.p & int   */
  34951. X/* biflambda - the real equivalent of complex Lambda sets -    */
  34952. X/* and f.p renditions of bifurcations of r*sin(Pi*p), which    */
  34953. X/* spurred Mitchel Feigenbaum on to discover his Number).      */
  34954. X
  34955. X/* To add further types, extend the fractalspecific[] array in */
  34956. X/* usual way, with Bifurcation as the engine, and the name of  */
  34957. X/* the routine that calculates the next bifurcation generation */
  34958. X/* as the "orbitcalc" routine in the fractalspecific[] entry.  */
  34959. X
  34960. X/* Bifurcation "orbitcalc" routines get called once per screen */
  34961. X/* pixel column.  They should calculate the next generation    */
  34962. X/* from the doubles Rate & Population (or the longs lRate &    */
  34963. X/* lPopulation if they use integer math), placing the result   */
  34964. X/* back in Population (or lPopulation).  They should return 0  */
  34965. X/* if all is ok, or any non-zero value if calculation bailout  */
  34966. X/* is desirable (eg in case of errors, or the series tending   */
  34967. X/* to infinity).        Have fun !               */
  34968. X/***************************************************************/
  34969. X
  34970. X#define DEFAULTFILTER 1000     /* "Beauty of Fractals" recommends using 5000
  34971. X                   (p.25), but that seems unnecessary. Can
  34972. X                   override this value with a nonzero param1 */
  34973. X
  34974. X#define SEED 0.66        /* starting value for population */
  34975. X
  34976. Xstatic int far *verhulst_array;
  34977. Xunsigned int filter_cycles;
  34978. Xstatic unsigned int half_time_check;
  34979. Xstatic long   lPopulation, lRate;
  34980. Xdouble Population,  Rate;
  34981. Xstatic int    mono, outside_x;
  34982. Xstatic long   LPI;
  34983. X
  34984. Xint Bifurcation(void)
  34985. X{
  34986. X   unsigned long array_size;
  34987. X   int row, column;
  34988. X   column = 0;
  34989. X   if (resuming)
  34990. X   {
  34991. X      start_resume();
  34992. X      get_resume(sizeof(int),&column,0);
  34993. X      end_resume();
  34994. X   }
  34995. X   array_size =  (iystop + 1) * sizeof(int); /* should be iystop + 1 */
  34996. X   if ((verhulst_array = (int far *) farmemalloc(array_size)) == NULL)
  34997. X   {
  34998. X      static char far msg[]={"Insufficient free memory for calculation."};
  34999. X      stopmsg(0,msg);
  35000. X      return(-1);
  35001. X   }
  35002. X
  35003. X   LPI = PI * fudge;
  35004. X
  35005. X   for (row = 0; row <= iystop; row++) /* should be iystop */
  35006. X      verhulst_array[row] = 0;
  35007. X
  35008. X   mono = 0;
  35009. X   if (colors == 2)
  35010. X      mono = 1;
  35011. X   if (mono)
  35012. X   {
  35013. X      if (inside)
  35014. X      {
  35015. X     outside_x = 0;
  35016. X     inside = 1;
  35017. X      }
  35018. X      else
  35019. X     outside_x = 1;
  35020. X   }
  35021. X
  35022. X   filter_cycles = (parm.x <= 0) ? DEFAULTFILTER : parm.x;
  35023. X   half_time_check = FALSE;
  35024. X   if (periodicitycheck && maxit < filter_cycles)
  35025. X   {
  35026. X      filter_cycles = (filter_cycles - maxit + 1) / 2;
  35027. X      half_time_check = TRUE;
  35028. X   }
  35029. X
  35030. X   if (integerfractal)
  35031. X      linit.y = ly0[iystop];   /* Y-value of    */
  35032. X   else
  35033. X      init.y = dy0[iystop];   /* bottom pixels */
  35034. X
  35035. X   while (column <= ixstop)
  35036. X   {
  35037. X      if(check_key())
  35038. X      {
  35039. X     farmemfree((char far *)verhulst_array);
  35040. X     alloc_resume(10,1);
  35041. X     put_resume(sizeof(int),&column,0);
  35042. X     return(-1);
  35043. X      }
  35044. X      if (integerfractal)
  35045. X     lRate = lx0[column];
  35046. X      else
  35047. X     Rate = dx0[column];
  35048. X      verhulst();     /* calculate array once per column */
  35049. X
  35050. X      for (row = iystop; row >= 0; row--) /* should be iystop & >=0 */
  35051. X      {
  35052. X     int color;
  35053. X     color = verhulst_array[row];
  35054. X     if(color && mono)
  35055. X        color = inside;
  35056. X     else if((!color) && mono)
  35057. X        color = outside_x;
  35058. X     else if (color>=colors)
  35059. X        color = colors-1;
  35060. X     verhulst_array[row] = 0;
  35061. X     (*plot)(column,row,color); /* was row-1, but that's not right? */
  35062. X      }
  35063. X      column++;
  35064. X   }
  35065. X   farmemfree((char far *)verhulst_array);
  35066. X   return(0);
  35067. X}
  35068. X
  35069. Xstatic void verhulst()        /* P. F. Verhulst (1845) */
  35070. X{
  35071. X   unsigned int pixel_row, counter, errors;
  35072. X
  35073. X    if (integerfractal)
  35074. X       lPopulation = (parm.y == 0) ? SEED * fudge : parm.y * fudge;
  35075. X    else
  35076. X       Population = (parm.y == 0 ) ? SEED : parm.y;
  35077. X
  35078. X   errors = overflow = FALSE;
  35079. X
  35080. X   for (counter=0 ; counter < filter_cycles ; counter++)
  35081. X   {
  35082. X      errors = (*(curfractalspecific->orbitcalc))();
  35083. X      if (errors)
  35084. X     return;
  35085. X   }
  35086. X   if (half_time_check) /* check for periodicity at half-time */
  35087. X   {
  35088. X      Bif_Period_Init();
  35089. X      for (counter=0 ; counter < maxit ; counter++)
  35090. X      {
  35091. X     errors = (*(curfractalspecific->orbitcalc))();
  35092. X     if (errors) return;
  35093. X     if (periodicitycheck && Bif_Periodic(counter)) break;
  35094. X      }
  35095. X      if (counter >= maxit)   /* if not periodic, go the distance */
  35096. X      {
  35097. X     for (counter=0 ; counter < filter_cycles ; counter++)
  35098. X     {
  35099. X        errors = (*(curfractalspecific->orbitcalc))();
  35100. X        if (errors) return;
  35101. X     }
  35102. X      }
  35103. X   }
  35104. X
  35105. X   if (periodicitycheck) Bif_Period_Init();
  35106. X   for (counter=0 ; counter < maxit ; counter++)
  35107. X   {
  35108. X      errors = (*(curfractalspecific->orbitcalc))();
  35109. X      if (errors) return;
  35110. X
  35111. X      /* assign population value to Y coordinate in pixels */
  35112. X      if (integerfractal)
  35113. X     pixel_row = iystop - (lPopulation - linit.y) / dely; /* iystop */
  35114. X      else
  35115. X     pixel_row = iystop - (int)((Population - init.y) / deltaY);
  35116. X
  35117. X      /* if it's visible on the screen, save it in the column array */
  35118. X      if (pixel_row <= iystop) /* JCO 6/6/92 */
  35119. X     verhulst_array[ pixel_row ] ++;
  35120. X      if (periodicitycheck && Bif_Periodic(counter))
  35121. X      {
  35122. X     if (pixel_row <= iystop) /* JCO 6/6/92 */
  35123. X        verhulst_array[ pixel_row ] --;
  35124. X     break;
  35125. X      }
  35126. X   }
  35127. X}
  35128. Xstatic    long    lBif_closenuf, lBif_savedpop;    /* poss future use  */
  35129. Xstatic    double     Bif_closenuf,    Bif_savedpop;
  35130. Xstatic    int     Bif_savedinc,    Bif_savedand;
  35131. X
  35132. Xstatic void Bif_Period_Init()
  35133. X{
  35134. X   Bif_savedinc = 1;
  35135. X   Bif_savedand = 1;
  35136. X   if (integerfractal)
  35137. X   {
  35138. X      lBif_savedpop = -1;
  35139. X      lBif_closenuf = dely / 8;
  35140. X   }
  35141. X   else
  35142. X   {
  35143. X      Bif_savedpop = -1.0;
  35144. X      Bif_closenuf = deltaY / 8.0;
  35145. X   }
  35146. X}
  35147. X
  35148. Xstatic int _fastcall Bif_Periodic (time)  /* Bifurcation Population Periodicity Check */
  35149. Xint time;        /* Returns : 1 if periodicity found, else 0 */
  35150. X{
  35151. X   if ((time & Bif_savedand) == 0)    /* time to save a new value */
  35152. X   {
  35153. X      if (integerfractal) lBif_savedpop = lPopulation;
  35154. X      else             Bif_savedpop =  Population;
  35155. X      if (--Bif_savedinc == 0)
  35156. X      {
  35157. X     Bif_savedand = (Bif_savedand << 1) + 1;
  35158. X     Bif_savedinc = 4;
  35159. X      }
  35160. X   }
  35161. X   else             /* check against an old save */
  35162. X   {
  35163. X      if (integerfractal)
  35164. X      {
  35165. X     if (labs(lBif_savedpop-lPopulation) <= lBif_closenuf)
  35166. X        return(1);
  35167. X      }
  35168. X      else
  35169. X      {
  35170. X     if (fabs(Bif_savedpop-Population) <= Bif_closenuf)
  35171. X        return(1);
  35172. X      }
  35173. X   }
  35174. X   return(0);
  35175. X}
  35176. X
  35177. X/**********************************************************************/
  35178. X/*                                                      */
  35179. X/* The following are Bifurcation "orbitcalc" routines...              */
  35180. X/*                                                      */
  35181. X/**********************************************************************/
  35182. X#ifdef XFRACT
  35183. Xint BifurcLambda() /* Used by lyanupov */
  35184. X  {
  35185. X    Population = Rate * Population * (1 - Population);
  35186. X    return (fabs(Population) > BIG);
  35187. X  }
  35188. X#endif
  35189. X
  35190. X/* Modified formulas below to generalize bifurcations. JCO 7/3/92 */
  35191. X
  35192. X#define LCMPLXtrig0(arg,out) Arg1->l = (arg); ltrig0(); (out)=Arg1->l
  35193. X#define  CMPLXtrig0(arg,out) Arg1->d = (arg); dtrig0(); (out)=Arg1->d
  35194. X
  35195. Xint BifurcVerhulstTrig()
  35196. X  {
  35197. X/*  Population = Pop + Rate * fn(Pop) * (1 - fn(Pop)) */
  35198. X    tmp.x = Population;
  35199. X    tmp.y = 0;
  35200. X    CMPLXtrig0(tmp, tmp);
  35201. X    Population += Rate * tmp.x * (1 - tmp.x);
  35202. X    return (fabs(Population) > BIG);
  35203. X  }
  35204. X
  35205. Xint LongBifurcVerhulstTrig()
  35206. X  {
  35207. X#ifndef XFRACT
  35208. X    ltmp.x = lPopulation;
  35209. X    ltmp.y = 0;
  35210. X    LCMPLXtrig0(ltmp, ltmp);
  35211. X    ltmp.y = ltmp.x - multiply(ltmp.x,ltmp.x,bitshift);
  35212. X    lPopulation += multiply(lRate,ltmp.y,bitshift);
  35213. X    return (overflow);
  35214. X#endif
  35215. X  }
  35216. X
  35217. Xint BifurcStewartTrig()
  35218. X  {
  35219. X/*  Population = (Rate * fn(Population) * fn(Population)) - 1.0 */
  35220. X    tmp.x = Population;
  35221. X    tmp.y = 0;
  35222. X    CMPLXtrig0(tmp, tmp);
  35223. X    Population = (Rate * tmp.x * tmp.x) - 1.0;
  35224. X    return (fabs(Population) > BIG);
  35225. X  }
  35226. X
  35227. Xint LongBifurcStewartTrig()
  35228. X  {
  35229. X#ifndef XFRACT
  35230. X    ltmp.x = lPopulation;
  35231. X    ltmp.y = 0;
  35232. X    LCMPLXtrig0(ltmp, ltmp);
  35233. X    lPopulation = multiply(ltmp.x,ltmp.x,bitshift);
  35234. X    lPopulation = multiply(lPopulation,lRate,       bitshift);
  35235. X    lPopulation -= fudge;
  35236. X    return (overflow);
  35237. X#endif
  35238. X  }
  35239. X
  35240. Xint BifurcSetTrigPi()
  35241. X  {
  35242. X    tmp.x = Population * PI;
  35243. X    tmp.y = 0;
  35244. X    CMPLXtrig0(tmp, tmp);
  35245. X    Population = Rate * tmp.x;
  35246. X    return (fabs(Population) > BIG);
  35247. X  }
  35248. X
  35249. Xint LongBifurcSetTrigPi()
  35250. X  {
  35251. X#ifndef XFRACT
  35252. X    ltmp.x = multiply(lPopulation,LPI,bitshift);
  35253. X    ltmp.y = 0;
  35254. X    LCMPLXtrig0(ltmp, ltmp);
  35255. X    lPopulation = multiply(lRate,ltmp.x,bitshift);
  35256. X    return (overflow);
  35257. X#endif
  35258. X  }
  35259. X
  35260. Xint BifurcAddTrigPi()
  35261. X  {
  35262. X    tmp.x = Population * PI;
  35263. X    tmp.y = 0;
  35264. X    CMPLXtrig0(tmp, tmp);
  35265. X    Population += Rate * tmp.x;
  35266. X    return (fabs(Population) > BIG);
  35267. X  }
  35268. X
  35269. Xint LongBifurcAddTrigPi()
  35270. X  {
  35271. X#ifndef XFRACT
  35272. X    ltmp.x = multiply(lPopulation,LPI,bitshift);
  35273. X    ltmp.y = 0;
  35274. X    LCMPLXtrig0(ltmp, ltmp);
  35275. X    lPopulation += multiply(lRate,ltmp.x,bitshift);
  35276. X    return (overflow);
  35277. X#endif
  35278. X  }
  35279. X
  35280. Xint BifurcLambdaTrig()
  35281. X  {
  35282. X/*  Population = Rate * fn(Population) * (1 - fn(Population)) */
  35283. X    tmp.x = Population;
  35284. X    tmp.y = 0;
  35285. X    CMPLXtrig0(tmp, tmp);
  35286. X    Population = Rate * tmp.x * (1 - tmp.x);
  35287. X    return (fabs(Population) > BIG);
  35288. X  }
  35289. X
  35290. Xint LongBifurcLambdaTrig()
  35291. X  {
  35292. X#ifndef XFRACT
  35293. X    ltmp.x = lPopulation;
  35294. X    ltmp.y = 0;
  35295. X    LCMPLXtrig0(ltmp, ltmp);
  35296. X    ltmp.y = ltmp.x - multiply(ltmp.x,ltmp.x,bitshift);
  35297. X    lPopulation = multiply(lRate,ltmp.y,bitshift);
  35298. X    return (overflow);
  35299. X#endif
  35300. X  }
  35301. X
  35302. X#define LCMPLXpwr(arg1,arg2,out)    Arg2->l = (arg1); Arg1->l = (arg2);\
  35303. X     lStkPwr(); Arg1++; Arg2++; (out) = Arg2->l
  35304. X
  35305. Xlong beta;
  35306. X
  35307. Xint BifurcMay()
  35308. X  { /* X = (lambda * X) / (1 + X)^beta, from R.May as described in Pickover,
  35309. X            Computers, Pattern, Chaos, and Beauty, page 153 */
  35310. X    tmp.x = 1.0 + Population;
  35311. X    tmp.x = pow(tmp.x, -beta); /* pow in math.h included with mpmath.h */
  35312. X    Population = (Rate * Population) * tmp.x;
  35313. X    return (fabs(Population) > BIG);
  35314. X  }
  35315. X
  35316. Xint LongBifurcMay()
  35317. X  {
  35318. X#ifndef XFRACT
  35319. X    ltmp.x = lPopulation + fudge;
  35320. X    ltmp.y = 0;
  35321. X    lparm2.x = beta * fudge;
  35322. X    LCMPLXpwr(ltmp, lparm2, ltmp);
  35323. X    lPopulation = multiply(lRate,lPopulation,bitshift);
  35324. X    lPopulation = divide(lPopulation,ltmp.x,bitshift);
  35325. X    return (overflow);
  35326. X#endif
  35327. X  }
  35328. X
  35329. Xint BifurcMaySetup()
  35330. X  {
  35331. X
  35332. X   beta = (long)param[2];
  35333. X   if(beta < 2)
  35334. X      beta = 2;
  35335. X   param[2] = (double)beta;
  35336. X
  35337. X   timer(0,curfractalspecific->calctype);
  35338. X   return(0);
  35339. X  }
  35340. X
  35341. X/* Here Endeth the Generalised Bifurcation Fractal Engine   */
  35342. X
  35343. X/* END Phil Wilson's Code (modified slightly by Kev Allen et. al. !) */
  35344. X
  35345. X
  35346. X/******************* standalone engine for "popcorn" ********************/
  35347. X
  35348. Xint popcorn()    /* subset of std engine */
  35349. X{
  35350. X   int start_row;
  35351. X   start_row = 0;
  35352. X   if (resuming)
  35353. X   {
  35354. X      start_resume();
  35355. X      get_resume(sizeof(int),&start_row,0);
  35356. X      end_resume();
  35357. X   }
  35358. X   kbdcount=max_kbdcount;
  35359. X   plot = noplot;
  35360. X   tempsqrx = ltempsqrx = 0; /* PB added this to cover weird BAILOUTs */
  35361. X   for (row = start_row; row <= iystop; row++)
  35362. X   {
  35363. X      reset_periodicity = 1;
  35364. X      for (col = 0; col <= ixstop; col++)
  35365. X      {
  35366. X     if (StandardFractal() == -1) /* interrupted */
  35367. X     {
  35368. X        alloc_resume(10,1);
  35369. X        put_resume(sizeof(int),&row,0);
  35370. X        return(-1);
  35371. X     }
  35372. X     reset_periodicity = 0;
  35373. X      }
  35374. X   }
  35375. X   calc_status = 4;
  35376. X   return(0);
  35377. X}
  35378. X
  35379. X/******************* standalone engine for "lyapunov" *********************/
  35380. X/*** Roy Murphy [76376,721]                        ***/
  35381. X/*** revision history:                            ***/
  35382. X/*** initial version: Winter '91                    ***/
  35383. X/***    Fall '92 integration of Nicholas Wilt's ASM speedups        ***/
  35384. X/***    Jan 93' integration with calcfrac() yielding boundary tracing,    ***/
  35385. X/***    tesseral, and solid guessing, and inversion, inside=nnn        ***/
  35386. X/*** save_release behavior:                        ***/
  35387. X/***    1730 & prior: ignores inside=, calcmode='1', (a,b)->(x,y)    ***/
  35388. X/***    1731: other calcmodes and inside=nnn                ***/
  35389. X/***    1732: the infamous axis swap: (b,a)->(x,y),            ***/
  35390. X/***        the order parameter becomes a long int            ***/
  35391. X/**************************************************************************/
  35392. Xint lyaLength, lyaSeedOK;
  35393. Xint lyaRxy[34];
  35394. X
  35395. X#define WES 1   /* define WES to be 0 to use Nick's lyapunov.obj */
  35396. X#if WES
  35397. Xextern int lyapunov_cycles(double, double);
  35398. X#else
  35399. Xextern int lyapunov_cycles(int, double, double, double);
  35400. X#endif
  35401. X
  35402. Xint lyapunov_cycles_in_c(int, double, double);
  35403. X
  35404. Xlyapunov () {
  35405. X    double a, b;
  35406. X
  35407. X    if (check_key()) {
  35408. X    return -1;
  35409. X        }
  35410. X    overflow=FALSE;
  35411. X    if (param[1]==1) Population = (1.0+rand())/(2.0+RAND_MAX);
  35412. X    else if (param[1]==0) {
  35413. X    if (fabs(Population)>BIG || Population==0 || Population==1)
  35414. X        Population = (1.0+rand())/(2.0+RAND_MAX);
  35415. X    }
  35416. X    else Population = param[1];
  35417. X    (*plot)(col, row, 1);
  35418. X    if (invert) {
  35419. X    invertz2(&init);
  35420. X    a = init.y;
  35421. X    b = init.x;
  35422. X    }
  35423. X    else {
  35424. X    a = dy0[row]+dy1[col];
  35425. X    b = dx0[col]+dx1[row];
  35426. X    }
  35427. X#ifndef XFRACT
  35428. X    /*  the assembler routines don't work for a & b outside the
  35429. X    ranges 0 < a < 4 and 0 < b < 4. So, fall back on the C
  35430. X    routines if part of the image sticks out.
  35431. X    */
  35432. X#if WES
  35433. X        color=lyapunov_cycles(a, b);
  35434. X#else
  35435. X    if (lyaSeedOK && a>0 && b>0 && a<=4 && b<=4)
  35436. X    color=lyapunov_cycles(filter_cycles, Population, a, b);
  35437. X    else
  35438. X    color=lyapunov_cycles_in_c(filter_cycles, a, b);
  35439. X#endif
  35440. X#else
  35441. X    color=lyapunov_cycles_in_c(filter_cycles, a, b);
  35442. X#endif
  35443. X    if (inside>0 && color==0)
  35444. X    color = inside;
  35445. X    else if (color>=colors)
  35446. X    color = colors-1;
  35447. X    (*plot)(col, row, color);
  35448. X    return color;
  35449. X}
  35450. X
  35451. X
  35452. Xlya_setup () {
  35453. X    /* This routine sets up the sequence for forcing the Rate parameter
  35454. X    to vary between the two values.  It fills the array lyaRxy[] and
  35455. X    sets lyaLength to the length of the sequence.
  35456. X
  35457. X    The sequence is coded in the bit pattern in an integer.
  35458. X    Briefly, the sequence starts with an A the leading zero bits
  35459. X    are ignored and the remaining bit sequence is decoded.  The
  35460. X    sequence ends with a B.  Not all possible sequences can be
  35461. X    represented in this manner, but every possible sequence is
  35462. X    either represented as itself, as a rotation of one of the
  35463. X    representable sequences, or as the inverse of a representable
  35464. X    sequence (swapping 0s and 1s in the array.)  Sequences that
  35465. X    are the rotation and/or inverses of another sequence will generate
  35466. X    the same lyapunov exponents.
  35467. X
  35468. X    A few examples follow:
  35469. X        number    sequence
  35470. X          0    ab
  35471. X          1    aab
  35472. X          2    aabb
  35473. X          3    aaab
  35474. X          4    aabbb
  35475. X          5    aabab
  35476. X          6    aaabb (this is a duplicate of 4, a rotated inverse)
  35477. X          7    aaaab
  35478. X          8    aabbbb    etc.
  35479. X     */
  35480. X
  35481. X    long i;
  35482. X    int t;
  35483. X
  35484. X    if ((filter_cycles=param[2])==0)
  35485. X    filter_cycles=maxit/2;
  35486. X    lyaSeedOK = param[1]>0 && param[1]<=1 && debugflag!=90;
  35487. X    lyaLength = 1;
  35488. X
  35489. X    i = param[0];
  35490. X#ifndef XFRACT
  35491. X    if (save_release<1732) i &= 0x0FFFFL; /* make it a short to reporduce prior stuff*/
  35492. X#endif
  35493. X    lyaRxy[0] = 1;
  35494. X    for (t=31; t>=0; t--)
  35495. X    if (i & (1<<t)) break;
  35496. X    for (; t>=0; t--)
  35497. X    lyaRxy[lyaLength++] = (i & (1<<t)) != 0;
  35498. X    lyaRxy[lyaLength++] = 0;
  35499. X    if (save_release<1732)        /* swap axes prior to 1732 */
  35500. X    for (t=lyaLength; t>=0; t--)
  35501. X        lyaRxy[t] = !lyaRxy[t];
  35502. X    if (save_release<1731) {        /* ignore inside=, stdcalcmode */
  35503. X        stdcalcmode='1';
  35504. X    if (inside==1) inside = 0;
  35505. X    }
  35506. X    if (inside<0) {
  35507. X        static char far msg[]=
  35508. X        {"Sorry, inside options other than inside=nnn are not supported by the lyapunov"};
  35509. X        stopmsg(0,(char far *)msg);
  35510. X        inside=1;
  35511. X    }
  35512. X    return 1;
  35513. X}
  35514. X
  35515. Xint lyapunov_cycles_in_c(int filter_cycles, double a, double b) {
  35516. X    int color, count, i, lnadjust;
  35517. X    double lyap, total, temp;
  35518. X    /* e10=22026.4657948  e-10=0.0000453999297625 */
  35519. X
  35520. X    for (i=0; i<filter_cycles; i++) {
  35521. X    for (count=0; count<lyaLength; count++) {
  35522. X        Rate = lyaRxy[count] ? a : b;
  35523. X        if (curfractalspecific->orbitcalc()) {
  35524. X        overflow = TRUE;
  35525. X        goto jumpout;
  35526. X        }
  35527. X        }
  35528. X    }
  35529. X    total = 1.0;
  35530. X    lnadjust = 0;
  35531. X    for (i=0; i < maxit/2; i++) {
  35532. X    for (count = 0; count < lyaLength; count++) {
  35533. X        Rate = lyaRxy[count] ? a : b;
  35534. X        if (curfractalspecific->orbitcalc()) {
  35535. X        overflow = TRUE;
  35536. X        goto jumpout;
  35537. X        }
  35538. X        temp = fabs(Rate-2.0*Rate*Population);
  35539. X        if ((total *= (temp))==0) {
  35540. X        overflow = TRUE;
  35541. X        goto jumpout;
  35542. X        }
  35543. X        }
  35544. X    while (total > 22026.4657948) {
  35545. X        total *= 0.0000453999297625;
  35546. X        lnadjust += 10;
  35547. X        }
  35548. X    while (total < 0.0000453999297625) {
  35549. X        total *= 22026.4657948;
  35550. X        lnadjust -= 10;
  35551. X        }
  35552. X    }
  35553. X
  35554. Xjumpout:
  35555. X    if (overflow || total <= 0 || (temp = log(total) + lnadjust) > 0)
  35556. X    color = 0;
  35557. X    else {
  35558. X    if (LogFlag)
  35559. X    lyap = -temp/((double) lyaLength*i);
  35560. X    else
  35561. X    lyap = 1 - exp(temp/((double) lyaLength*i));
  35562. X    color = 1 + (int)(lyap * (colors-1));
  35563. X    }
  35564. X    return color;
  35565. X}
  35566. X
  35567. X
  35568. X/******************* standalone engine for "cellular" ********************/
  35569. X/* Originally coded by Ken Shirriff.
  35570. X   Modified beyond recognition by Jonathan Osuch.
  35571. X     Original or'd the neighborhood, changed to sum the neighborhood
  35572. X     Changed prompts and error messages
  35573. X     Added CA types
  35574. X     Set the palette to some standard? CA colors
  35575. X     Changed *cell_array to near and used dstack so put_line and get_line
  35576. X       could be used all the time
  35577. X     Made space bar generate next screen
  35578. X     Increased string/rule size to 16 digits and added CA types 9/20/92
  35579. X*/
  35580. X
  35581. X#define BAD_T         1
  35582. X#define BAD_MEM       2
  35583. X#define STRING1       3
  35584. X#define STRING2       4
  35585. X#define TABLEK        5
  35586. X#define TYPEKR        6
  35587. X#define RULELENGTH    7
  35588. X
  35589. X#define CELLULAR_DONE 10
  35590. X
  35591. X#ifndef XFRACT
  35592. Xstatic BYTE *cell_array[2];
  35593. X#else
  35594. Xstatic BYTE far *cell_array[2];
  35595. X#endif
  35596. X
  35597. XS16 r, k_1, rule_digits;
  35598. Xint lstscreenflag;
  35599. X
  35600. Xvoid abort_cellular(int err, int t)
  35601. X{
  35602. X   int i;
  35603. X   switch (err)
  35604. X   {
  35605. X      case BAD_T:
  35606. X         {
  35607. X         char msg[30];
  35608. X         sprintf(msg,"Bad t=%d, aborting\n", t);
  35609. X         stopmsg(0,(char far *)msg);
  35610. X         }
  35611. X         break;
  35612. X      case BAD_MEM:
  35613. X         {
  35614. X         static char far msg[]={"Insufficient free memory for calculation" };
  35615. X         stopmsg(0,msg);
  35616. X         }
  35617. X         break;
  35618. X      case STRING1:
  35619. X         {
  35620. X         static char far msg[]={"String can be a maximum of 16 digits" };
  35621. X         stopmsg(0,msg);
  35622. X         }
  35623. X         break;
  35624. X      case STRING2:
  35625. X         {
  35626. X         static char far msg[]={"Make string of 0's through  's" };
  35627. X         msg[27] = k_1 + 48; /* turn into a character value */
  35628. X         stopmsg(0,msg);
  35629. X         }
  35630. X         break;
  35631. X      case TABLEK:
  35632. X         {
  35633. X         static char far msg[]={"Make Rule with 0's through  's" };
  35634. X         msg[27] = k_1 + 48; /* turn into a character value */
  35635. X         stopmsg(0,msg);
  35636. X         }
  35637. X         break;
  35638. X      case TYPEKR:
  35639. X         {
  35640. X         static char far msg[]={"Type must be 21, 31, 41, 51, 61, 22, 32, \
  35641. X42, 23, 33, 24, 25, 26, 27" };
  35642. X         stopmsg(0,msg);
  35643. X         }
  35644. X         break;
  35645. X      case RULELENGTH:
  35646. X         {
  35647. X         static char far msg[]={"Rule must be    digits long" };
  35648. X         i = rule_digits / 10;
  35649. X         if(i==0)
  35650. X            msg[14] = rule_digits + 48;
  35651. X         else {
  35652. X            msg[13] = i;
  35653. X            msg[14] = rule_digits % 10 + 48;
  35654. X         }
  35655. X         stopmsg(0,msg);
  35656. X         }
  35657. X         break;
  35658. X      case CELLULAR_DONE:
  35659. X         break;
  35660. X   }
  35661. X   if(cell_array[0] != NULL)
  35662. X#ifndef XFRACT
  35663. X      cell_array[0] = NULL;
  35664. X#else
  35665. X      farmemfree((char far *)cell_array[0]);
  35666. X#endif
  35667. X   if(cell_array[1] != NULL)
  35668. X#ifndef XFRACT
  35669. X      cell_array[1] = NULL;
  35670. X#else
  35671. X      farmemfree((char far *)cell_array[1]);
  35672. X#endif
  35673. X}
  35674. X
  35675. Xcellular () {
  35676. X   S16 start_row;
  35677. X   S16 filled, notfilled;
  35678. X   U16 cell_table[32];
  35679. X   U16 init_string[16];
  35680. X   U16 kr, k;
  35681. X   U32 lnnmbr;
  35682. X   U16 i,j,l;
  35683. X   S16 t, t2;
  35684. X   S32 randparam;
  35685. X   double n;
  35686. X   char buf[30];
  35687. X
  35688. X   set_Cellular_palette();
  35689. X
  35690. X   randparam = param[0];
  35691. X   lnnmbr = param[3];
  35692. X   kr = param[2];
  35693. X   switch (kr) {
  35694. X     case 21:
  35695. X     case 31:
  35696. X     case 41:
  35697. X     case 51:
  35698. X     case 61:
  35699. X     case 22:
  35700. X     case 32:
  35701. X     case 42:
  35702. X     case 23:
  35703. X     case 33:
  35704. X     case 24:
  35705. X     case 25:
  35706. X     case 26:
  35707. X     case 27:
  35708. X        break;
  35709. X     default:
  35710. X        abort_cellular(TYPEKR, 0);
  35711. X        return -1;
  35712. X        break;
  35713. X   }
  35714. X
  35715. X   r = kr % 10; /* Number of nearest neighbors to sum */
  35716. X   k = kr / 10; /* Number of different states, k=3 has states 0,1,2 */
  35717. X   k_1 = k - 1; /* Highest state value, k=3 has highest state value of 2 */
  35718. X   rule_digits = (r * 2 + 1) * k_1 + 1; /* Number of digits in the rule */
  35719. X
  35720. X   if ((!rflag) && randparam == -1)
  35721. X       --rseed;
  35722. X   if (randparam != 0 && randparam != -1) {
  35723. X      n = param[0];
  35724. X      sprintf(buf,"%.16g",n); /* # of digits in initial string */
  35725. X      t = strlen(buf);
  35726. X      if (t>16 || t <= 0) {
  35727. X         abort_cellular(STRING1, 0);
  35728. X         return -1;
  35729. X      }
  35730. X      for (i=0;i<16;i++)
  35731. X         init_string[i] = 0; /* zero the array */
  35732. X      t2 = (S16) ((16 - t)/2);
  35733. X      for (i=0;i<t;i++) { /* center initial string in array */
  35734. X         init_string[i+t2] = buf[i] - 48; /* change character to number */
  35735. X         if (init_string[i+t2]>k_1) {
  35736. X            abort_cellular(STRING2, 0);
  35737. X            return -1;
  35738. X         }
  35739. X      }
  35740. X   }
  35741. X
  35742. X   srand(rseed);
  35743. X   if (!rflag) ++rseed;
  35744. X
  35745. X/* generate rule table from parameter 1 */
  35746. X#ifndef XFRACT
  35747. X   n = param[1];
  35748. X#else
  35749. X   /* gcc can't manage to convert a big double to an unsigned long properly. */
  35750. X   if (param[1]>0x7fffffff) {
  35751. X       n = (param[1]-0x7fffffff);
  35752. X       n += 0x7fffffff;
  35753. X   } else {
  35754. X       n = param[1];
  35755. X   }
  35756. X#endif
  35757. X   if (n == 0) { /* calculate a random rule */
  35758. X      n = rand15()%k;
  35759. X      for (i=1;i<rule_digits;i++) {
  35760. X         n *= 10;
  35761. X         n += rand15()%k;
  35762. X      }
  35763. X      param[1] = n;
  35764. X   }
  35765. X   sprintf(buf,"%.*g",rule_digits ,n);
  35766. X   t = strlen(buf);
  35767. X   if (rule_digits < t || t < 0) { /* leading 0s could make t smaller */
  35768. X      abort_cellular(RULELENGTH, 0);
  35769. X      return -1;
  35770. X   }
  35771. X   for (i=0;i<rule_digits;i++) /* zero the table */
  35772. X      cell_table[i] = 0;
  35773. X   for (i=0;i<t;i++) { /* reverse order */
  35774. X      cell_table[i] = buf[t-i-1] - 48; /* change character to number */
  35775. X      if (cell_table[i]>k_1) {
  35776. X         abort_cellular(TABLEK, 0);
  35777. X         return -1;
  35778. X      }
  35779. X   }
  35780. X
  35781. X
  35782. X   start_row = 0;
  35783. X#ifndef XFRACT
  35784. X  /* two 4096 byte arrays, at present at most 2024 + 1 bytes should be */
  35785. X  /* needed in each array (max screen width + 1) */
  35786. X   cell_array[0] = (BYTE *)&dstack[0]; /* dstack is in general.asm */
  35787. X   cell_array[1] = (BYTE *)&boxy[0]; /* boxy is in general.asm */
  35788. X#else
  35789. X   cell_array[0] = (BYTE far *)farmemalloc(ixstop+1);
  35790. X   cell_array[1] = (BYTE far *)farmemalloc(ixstop+1);
  35791. X#endif
  35792. X   if (cell_array[0]==NULL || cell_array[1]==NULL) {
  35793. X      abort_cellular(BAD_MEM, 0);
  35794. X      return(-1);
  35795. X   }
  35796. X
  35797. X/* nxtscreenflag toggled by space bar in fractint.c, 1 for continuous */
  35798. X/* 0 to stop on next screen */
  35799. X
  35800. X   filled = 0;
  35801. X   notfilled = 1-filled;
  35802. X   if (resuming && !nxtscreenflag && !lstscreenflag) {
  35803. X      start_resume();
  35804. X      get_resume(sizeof(int),&start_row,0);
  35805. X      end_resume();
  35806. X      get_line(start_row,0,ixstop,cell_array[filled]);
  35807. X   }
  35808. X   else if (nxtscreenflag && !lstscreenflag) {
  35809. X      start_resume();
  35810. X      end_resume();
  35811. X      get_line(iystop,0,ixstop,cell_array[filled]);
  35812. X      param[3] += iystop + 1;
  35813. X      start_row = -1; /* after 1st iteration its = 0 */
  35814. X   }
  35815. X   else {
  35816. X    if(rflag || randparam==0 || randparam==-1){
  35817. X      for (col=0;col<=ixstop;col++) {
  35818. X         cell_array[filled][col] = rand15()%k;
  35819. X      }
  35820. X    } /* end of if random */
  35821. X
  35822. X    else {
  35823. X      for (col=0;col<=ixstop;col++) { /* Clear from end to end */
  35824. X         cell_array[filled][col] = 0;
  35825. X      }
  35826. X      i = 0;
  35827. X      for (col=(ixstop-16)/2;col<(ixstop+16)/2;col++) { /* insert initial */
  35828. X         cell_array[filled][col] = init_string[i++];    /* string */
  35829. X      }
  35830. X    } /* end of if not random */
  35831. X    if (lnnmbr != 0)
  35832. X      lstscreenflag = 1;
  35833. X    else
  35834. X      lstscreenflag = 0;
  35835. X    put_line(start_row,0,ixstop,cell_array[filled]);
  35836. X   }
  35837. X   start_row++;
  35838. X
  35839. X/* This section calculates the starting line when it is not zero */
  35840. X/* This section can't be resumed since no screen output is generated */
  35841. X/* calculates the (lnnmbr - 1) generation */
  35842. X   if (lstscreenflag) { /* line number != 0 & not resuming & not continuing */
  35843. X     for (row = start_row; row < lnnmbr; row++) {
  35844. X      thinking(1,"Cellular thinking (higher start row takes longer)");
  35845. X      if(rflag || randparam==0 || randparam==-1){
  35846. X       /* Use a random border */
  35847. X       for (i=0;i<=r;i++) {
  35848. X         cell_array[notfilled][i]=rand15()%k;
  35849. X         cell_array[notfilled][ixstop-i]=rand15()%k;
  35850. X       }
  35851. X      }
  35852. X      else {
  35853. X       /* Use a zero border */
  35854. X       for (i=0;i<=r;i++) {
  35855. X         cell_array[notfilled][i]=0;
  35856. X         cell_array[notfilled][ixstop-i]=0;
  35857. X       }
  35858. X      }
  35859. X
  35860. X       t = 0; /* do first cell */
  35861. X       for (i=0;i<=r+r;i++)
  35862. X           t += cell_array[filled][i];
  35863. X       if (t>rule_digits || t<0) {
  35864. X         thinking(0, NULL);
  35865. X         abort_cellular(BAD_T, t);
  35866. X         return(-1);
  35867. X       }
  35868. X       cell_array[notfilled][r] = cell_table[t];
  35869. X
  35870. X           /* use a rolling sum in t */
  35871. X       for (col=r+1;col<ixstop-r;col++) { /* now do the rest */
  35872. X         t = t + cell_array[filled][col+r] - cell_array[filled][col-r-1];
  35873. X         if (t>rule_digits || t<0) {
  35874. X           thinking(0, NULL);
  35875. X           abort_cellular(BAD_T, t);
  35876. X           return(-1);
  35877. X         }
  35878. X         cell_array[notfilled][col] = cell_table[t];
  35879. X       }
  35880. X
  35881. X       filled = notfilled;
  35882. X       notfilled = 1-filled;
  35883. X       if (check_key()) {
  35884. X          thinking(0, NULL);
  35885. X          abort_cellular(CELLULAR_DONE, 0);
  35886. X          alloc_resume(10,1);
  35887. X          put_resume(sizeof(int),&row,0);
  35888. X          return -1;
  35889. X       }
  35890. X     }
  35891. X   start_row = 0;
  35892. X   thinking(0, NULL);
  35893. X   lstscreenflag = 0;
  35894. X   }
  35895. X
  35896. X/* This section does all the work */
  35897. Xcontloop:
  35898. X   for (row = start_row; row <= iystop; row++) {
  35899. X
  35900. X      if(rflag || randparam==0 || randparam==-1){
  35901. X       /* Use a random border */
  35902. X       for (i=0;i<=r;i++) {
  35903. X         cell_array[notfilled][i]=rand15()%k;
  35904. X         cell_array[notfilled][ixstop-i]=rand15()%k;
  35905. X       }
  35906. X      }
  35907. X      else {
  35908. X       /* Use a zero border */
  35909. X       for (i=0;i<=r;i++) {
  35910. X         cell_array[notfilled][i]=0;
  35911. X         cell_array[notfilled][ixstop-i]=0;
  35912. X       }
  35913. X      }
  35914. X
  35915. X       t = 0; /* do first cell */
  35916. X       for (i=0;i<=r+r;i++)
  35917. X           t += cell_array[filled][i];
  35918. X       if (t>rule_digits || t<0) {
  35919. X         thinking(0, NULL);
  35920. X         abort_cellular(BAD_T, t);
  35921. X         return(-1);
  35922. X       }
  35923. X       cell_array[notfilled][r] = cell_table[t];
  35924. X
  35925. X           /* use a rolling sum in t */
  35926. X       for (col=r+1;col<ixstop-r;col++) { /* now do the rest */
  35927. X         t = t + cell_array[filled][col+r] - cell_array[filled][col-r-1];
  35928. X         if (t>rule_digits || t<0) {
  35929. X           thinking(0, NULL);
  35930. X           abort_cellular(BAD_T, t);
  35931. X           return(-1);
  35932. X         }
  35933. X         cell_array[notfilled][col] = cell_table[t];
  35934. X       }
  35935. X
  35936. X       filled = notfilled;
  35937. X       notfilled = 1-filled;
  35938. X       put_line(row,0,ixstop,cell_array[filled]);
  35939. X       if (check_key()) {
  35940. X          abort_cellular(CELLULAR_DONE, 0);
  35941. X          alloc_resume(10,1);
  35942. X          put_resume(sizeof(int),&row,0);
  35943. X          return -1;
  35944. X       }
  35945. X   }
  35946. X   if(nxtscreenflag) {
  35947. X     param[3] += iystop + 1;
  35948. X     start_row = -1; /* after 1st iteration its = 0 */
  35949. X     goto contloop;
  35950. X   }
  35951. X  abort_cellular(CELLULAR_DONE, 0);
  35952. X  return 1;
  35953. X}
  35954. X
  35955. Xint CellularSetup(void)
  35956. X{
  35957. X   if (!resuming) {
  35958. X      nxtscreenflag = 0; /* initialize flag */
  35959. X   }
  35960. X   timer(0,curfractalspecific->calctype);
  35961. X   return(0);
  35962. X}
  35963. X
  35964. Xstatic void set_Cellular_palette()
  35965. X{
  35966. X   extern char far *mapdacbox;
  35967. X   static Palettetype Red    = {
  35968. X      42, 0, 0     };
  35969. X   static Palettetype Green  = {
  35970. X      10,35,10    };
  35971. X   static Palettetype Blue   = {
  35972. X      13,12,29    };
  35973. X   static Palettetype Yellow = {
  35974. X      60,58,18    };
  35975. X   static Palettetype Brown = {
  35976. X      42,21, 0    };
  35977. X   int i;
  35978. X
  35979. X   if (mapdacbox) return;        /* map= specified */
  35980. X
  35981. X   dacbox[0].red  = 0 ;
  35982. X   dacbox[0].green= 0 ;
  35983. X   dacbox[0].blue = 0 ;
  35984. X
  35985. X   dacbox[1].red     = Red.red;
  35986. X   dacbox[1].green = Red.green;
  35987. X   dacbox[1].blue  = Red.blue;
  35988. X
  35989. X   dacbox[2].red   = Green.red;
  35990. X   dacbox[2].green = Green.green;
  35991. X   dacbox[2].blue  = Green.blue;
  35992. X
  35993. X   dacbox[3].red   = Blue.red;
  35994. X   dacbox[3].green = Blue.green;
  35995. X   dacbox[3].blue  = Blue.blue;
  35996. X
  35997. X   dacbox[4].red   = Yellow.red;
  35998. X   dacbox[4].green = Yellow.green;
  35999. X   dacbox[4].blue  = Yellow.blue;
  36000. X
  36001. X   dacbox[5].red   = Brown.red;
  36002. X   dacbox[5].green = Brown.green;
  36003. X   dacbox[5].blue  = Brown.blue;
  36004. X
  36005. X   SetTgaColors();
  36006. X   spindac(0,1);
  36007. X}
  36008. X
  36009. X/* frothy basin routines */
  36010. Xstatic char froth3_256c[] = "froth3.map";
  36011. Xstatic char froth6_256c[] = "froth6.map";
  36012. Xstatic char froth3_16c[] =  "froth316.map";
  36013. Xstatic char froth6_16c[] =  "froth616.map";
  36014. Xint frothsix=0;
  36015. Xint froth_altcolor;
  36016. Xint froth_shades;
  36017. Xextern int colorstate;
  36018. X
  36019. X/* color maps which attempt to replicate the images of James Alexander. */
  36020. Xstatic void set_Froth_palette(void)
  36021. X   {
  36022. X   char *mapname;
  36023. X
  36024. X   if (colorstate != 0) /* 0 means dacbox matches default */
  36025. X      return;
  36026. X
  36027. X   if (colors >= 16)
  36028. X      {
  36029. X      if (colors >= 256)
  36030. X         {
  36031. X         if (frothsix)
  36032. X            mapname = froth6_256c;
  36033. X         else
  36034. X            mapname = froth3_256c;
  36035. X         }
  36036. X      else /* colors >= 16 */
  36037. X         {
  36038. X         if (frothsix)
  36039. X            mapname = froth6_16c;
  36040. X         else
  36041. X            mapname = froth3_16c;
  36042. X         }
  36043. X      if (ValidateLuts(mapname) != 0)
  36044. X         return;
  36045. X      colorstate = 0; /* treat map it as default */
  36046. X      spindac(0,1);
  36047. X      }
  36048. X   }
  36049. X
  36050. Xint froth_setup(void)
  36051. X   {
  36052. X   if (param[0] != 3 && param[0] != 6) /* if no match then*/
  36053. X      param[0] = 3;                    /* make it 3 */
  36054. X   frothsix = param[0] == 6;
  36055. X   froth_altcolor = param[1] != 0;
  36056. X   froth_shades = (colors-1) / (frothsix ? 6 : 3);
  36057. X   /* rqlim needs to be at least 6 or so */
  36058. X   if (rqlim < 6.0)
  36059. X      rqlim=6.0;
  36060. X   set_Froth_palette();
  36061. X   /* make the best of the .map situation */
  36062. X   orbit_color = !frothsix && colors >= 16 ? (froth_shades<<1)+1 : colors-1;
  36063. X   return 1;
  36064. X   }
  36065. X
  36066. X/* Froth Fractal type */
  36067. X  int calcfroth(void)   /* per pixel 1/2/g, called with row & col set */
  36068. X     {
  36069. X     int found_attractor=0;
  36070. X     double x, y, nx, ny, x2, y2;
  36071. X     long lx, ly, lnx, lny, lx2, ly2;
  36072. X
  36073. X/* These points were determined imperically and verified experimentally */
  36074. X/* using the program WL-Plot, a plotting program which has a mode for */
  36075. X/* orbits of recursive relations. */
  36076. X#define CLOSE    1e-6      /* seems like a good value */
  36077. X#define SQRT3    1.732050807568877193
  36078. X#define A        1.02871376822
  36079. X#define B1       (A/2)
  36080. X#define M2       SQRT3
  36081. X#define B2       (-A)
  36082. X#define M3       (-SQRT3)
  36083. X#define B3       (-A)
  36084. X#define X1MIN   -1.04368901270
  36085. X#define X1MAX    1.33928675524
  36086. X#define XMIDT   -0.339286755220
  36087. X#define X2MAX1   0.96729063460
  36088. X#define XMIDR    0.61508950585
  36089. X#define X3MIN1  -0.22419724936
  36090. X#define X2MIN2  -1.11508950586
  36091. X#define XMIDL   -0.27580275066
  36092. X#define X3MAX2   0.07639837810
  36093. X#define FROTH_BITSHIFT  28
  36094. X/* compiler should handle this at compile time */
  36095. X#define D_TO_L(x) ((long)((x)*(1L<<FROTH_BITSHIFT)))
  36096. X
  36097. X   orbit_ptr = 0;
  36098. X   color = 0;
  36099. X   if(showdot>0)
  36100. X      (*plot) (col, row, showdot&(colors-1));
  36101. X   if (!integerfractal) /* fp mode */
  36102. X      {
  36103. X      double close=  CLOSE;
  36104. X      double a=      A;
  36105. X      double b1=     B1;
  36106. X      double xmidt=  XMIDT;
  36107. X      double m2=     M2;
  36108. X      double b2=     B2;
  36109. X      double m3=     M3;
  36110. X      double b3=     B3;
  36111. X      double x1min=  X1MIN;
  36112. X      double x1max=  X1MAX;
  36113. X      double x2max1= X2MAX1;
  36114. X      double xmidr=  XMIDR;
  36115. X      double x3min1= X3MIN1;
  36116. X      double x2min2= X2MIN2;
  36117. X      double xmidl=  XMIDL;
  36118. X      double x3max2= X3MAX2;
  36119. X
  36120. X      if(invert)
  36121. X     {
  36122. X     invertz2(&tmp);
  36123. X     x = tmp.x;
  36124. X     y = tmp.y;
  36125. X     }
  36126. X      else
  36127. X     {
  36128. X     x = dx0[col]+dx1[row];
  36129. X     y = dy0[row]+dy1[col];
  36130. X     }
  36131. X
  36132. X      magnitude = (x2=sqr(x)) + (y2=sqr(y));
  36133. X      while (!found_attractor && (magnitude < rqlim) && (color < maxit))
  36134. X     {
  36135. X         /* simple formula: z = z^2 + conj(z*(-1+ai)) */
  36136. X     /* but it's the attractor that makes this so interesting */
  36137. X     nx = x2 - y2 - x - a*y;
  36138. X     ny = (x+x)*y - a*x + y;
  36139. X     x = nx;
  36140. X     y = ny;
  36141. X     if (frothsix) /* repeat mapping */
  36142. X        {
  36143. X        nx = sqr(x) - sqr(y) - x - a*y;
  36144. X        ny = (x+x)*y - a*x + y;
  36145. X        x = nx;
  36146. X        y = ny;
  36147. X        }
  36148. X     magnitude = (x2=sqr(x)) + (y2=sqr(y));
  36149. X     color++;
  36150. X
  36151. X     if (show_orbit)
  36152. X        plot_orbit(x, y, -1);
  36153. X
  36154. X         if (x > x1min && x < x1max && fabs(b1-y) < close)
  36155. X        {
  36156. X        if (!frothsix || x < xmidt)
  36157. X           found_attractor = 1;
  36158. X        else
  36159. X           found_attractor = 2;
  36160. X
  36161. X        }
  36162. X     else if (fabs(m2*x+b2-y) < close)
  36163. X        {
  36164. X        if (x > xmidr && x < x2max1)
  36165. X           found_attractor = !frothsix ? 2 : 4;
  36166. X        else if (x > x3min1 && x < xmidr)
  36167. X           found_attractor = !frothsix ? 3 : 6;
  36168. X        }
  36169. X     else if (fabs(m3*x+b3-y) < close)
  36170. X        {
  36171. X        if (x > x2min2 && x < xmidl)
  36172. X           found_attractor = !frothsix ? 2 : 3;
  36173. X        else if (x > xmidl && x < x3max2)
  36174. X           found_attractor = !frothsix ? 3 : 5;
  36175. X        }
  36176. X     }
  36177. X      }
  36178. X   else /* integer mode */
  36179. X      {
  36180. X      long lclose=   D_TO_L(CLOSE);
  36181. X      long la=       D_TO_L(A);
  36182. X      long lb1=      D_TO_L(B1);
  36183. X      long lxmidt=   D_TO_L(XMIDT);
  36184. X      long lm2=      D_TO_L(M2);
  36185. X      long lb2=      D_TO_L(B2);
  36186. X      long lm3=      D_TO_L(M3);
  36187. X      long lb3=      D_TO_L(B3);
  36188. X      long lx1min=   D_TO_L(X1MIN);
  36189. X      long lx1max=   D_TO_L(X1MAX);
  36190. X      long lx2max1=  D_TO_L(X2MAX1);
  36191. X      long lxmidr=   D_TO_L(XMIDR);
  36192. X      long lx3min1=  D_TO_L(X3MIN1);
  36193. X      long lx2min2=  D_TO_L(X2MIN2);
  36194. X      long lxmidl=   D_TO_L(XMIDL);
  36195. X      long lx3max2=  D_TO_L(X3MAX2);
  36196. X
  36197. X      if(invert)
  36198. X     {
  36199. X     invertz2(&tmp);
  36200. X     lx = tmp.x * fudge;
  36201. X     ly = tmp.y * fudge;
  36202. X     }
  36203. X      else
  36204. X     {
  36205. X     lx = lx0[col] + lx1[row];
  36206. X     ly = ly0[row] + ly1[col];
  36207. X     }
  36208. X
  36209. X      lmagnitud = (lx2=lsqr(lx)) + (ly2=lsqr(ly));
  36210. X      while (!found_attractor && (lmagnitud < llimit)
  36211. X         && (lmagnitud > 0) && (color < maxit))
  36212. X     {
  36213. X         /* simple formula: z = z^2 + conj(z*(-1+ai)) */
  36214. X     /* but it's the attractor that makes this so interesting */
  36215. X     lnx = lx2 - ly2 - lx - multiply(la,ly,bitshift);
  36216. X     lny = (multiply(lx,ly,bitshift)<<1) - multiply(la,lx,bitshift) + ly;
  36217. X     lx = lnx;
  36218. X     ly = lny;
  36219. X     if (frothsix)
  36220. X        {
  36221. X        lmagnitud = (lx2=lsqr(lx)) + (ly2=lsqr(ly));
  36222. X        if ((lmagnitud > llimit) || (lmagnitud < 0))
  36223. X           break;
  36224. X        lnx = lx2 - ly2 - lx - multiply(la,ly,bitshift);
  36225. X        lny = (multiply(lx,ly,bitshift)<<1) - multiply(la,lx,bitshift) + ly;
  36226. X        lx = lnx;
  36227. X        ly = lny;
  36228. X        }
  36229. X     lmagnitud = (lx2=lsqr(lx)) + (ly2=lsqr(ly));
  36230. X     color++;
  36231. X
  36232. X     if (show_orbit)
  36233. X        iplot_orbit(lx, ly, -1);
  36234. X
  36235. X         if (lx > lx1min && lx < lx1max && labs(lb1-ly) < lclose)
  36236. X        {
  36237. X        if (!frothsix || lx < lxmidt)
  36238. X           found_attractor = 1;
  36239. X        else
  36240. X           found_attractor = 2;
  36241. X        }
  36242. X     else if (labs(multiply(lm2,lx,bitshift)+lb2-ly) < lclose)
  36243. X        {
  36244. X        if (lx > lxmidr && lx < lx2max1)
  36245. X           found_attractor = !frothsix ? 2 : 4;
  36246. X        else if (lx > lx3min1 && lx < lxmidr)
  36247. X           found_attractor = !frothsix ? 3 : 6;
  36248. X        }
  36249. X     else if (labs(multiply(lm3,lx,bitshift)+lb3-ly) < lclose)
  36250. X        {
  36251. X        if (lx > lx2min2 && lx < lxmidl)
  36252. X           found_attractor = !frothsix ? 2 : 3;
  36253. X        else if (lx > lxmidl && lx < lx3max2)
  36254. X           found_attractor = !frothsix ? 3 : 5;
  36255. X        }
  36256. X     }
  36257. X      }
  36258. X   if (show_orbit)
  36259. X      scrub_orbit();
  36260. X
  36261. X   realcolor = color;
  36262. X   if ((kbdcount -= realcolor) <= 0)
  36263. X      {
  36264. X      if (check_key())
  36265. X     return (-1);
  36266. X      kbdcount = max_kbdcount;
  36267. X      }
  36268. X
  36269. X/* inside - Here's where non-palette based images would be nice.  Instead, */
  36270. X/* we'll use blocks of (colors-1)/3 or (colors-1)/6 and use special froth  */
  36271. X/* color maps in attempt to replicate the images of James Alexander.       */
  36272. X   if (found_attractor)
  36273. X      {
  36274. X      if (colors >= 256)
  36275. X     {
  36276. X     if (!froth_altcolor)
  36277. X        {
  36278. X        if (color > froth_shades)
  36279. X        color = froth_shades;
  36280. X        }
  36281. X     else
  36282. X        color = froth_shades * color / maxit;
  36283. X     if (color == 0)
  36284. X        color = 1;
  36285. X     color += froth_shades * (found_attractor-1);
  36286. X     }
  36287. X      else if (colors >= 16)
  36288. X     { /* only alternate coloring scheme available for 16 colors */
  36289. X     long lshade;
  36290. X
  36291. X/* Trying to make a better 16 color distribution. */
  36292. X/* Since their are only a few possiblities, just handle each case. */
  36293. X/* This is a mostly guess work here. */
  36294. X     lshade = ((long)color<<16)/maxit;
  36295. X     if (!frothsix)
  36296. X        {
  36297. X        if (lshade < 2622)       /* 0.04 */
  36298. X           color = 1;
  36299. X        else if (lshade < 10486) /* 0.16 */
  36300. X           color = 2;
  36301. X        else if (lshade < 23593) /* 0.36 */
  36302. X           color = 3;
  36303. X        else if (lshade < 41943) /* 0.64 */
  36304. X           color = 4;
  36305. X        else
  36306. X           color = 5;
  36307. X        color += 5 * (found_attractor-1);
  36308. X        }
  36309. X     else
  36310. X        {
  36311. X        if (lshade < 10486)      /* 0.16 */
  36312. X           color = 1;
  36313. X        else
  36314. X           color = 2;
  36315. X        color += 2 * (found_attractor-1);
  36316. X        }
  36317. X     }
  36318. X      else /* use a color corresponding to the attractor */
  36319. X     color = found_attractor;
  36320. X      oldcolor = color;
  36321. X      }
  36322. X   else if (color >= maxit)
  36323. X      color = oldcolor; /* inside, but didn't get sucked in by attractor. */
  36324. X   else /* outside */
  36325. X      color = 0; /* all outside points are color 0 */
  36326. X
  36327. X   (*plot)(col, row, color);
  36328. X
  36329. X   return color;
  36330. X
  36331. X#undef CLOSE
  36332. X#undef SQRT3
  36333. X#undef A
  36334. X#undef B1
  36335. X#undef XMIDT
  36336. X#undef M2
  36337. X#undef B2
  36338. X#undef M3
  36339. X#undef B3
  36340. X#undef X1MIN
  36341. X#undef X1MAX
  36342. X#undef X2MAX1
  36343. X#undef XMIDR
  36344. X#undef X3MIN1
  36345. X#undef X2MIN2
  36346. X#undef XMIDL
  36347. X#undef X3MAX2
  36348. X#undef FROTH_BITSHIFT
  36349. X#undef D_TO_L
  36350. X   }
  36351. SHAR_EOF
  36352. $TOUCH -am 1028230093 miscfrac.c &&
  36353. chmod 0644 miscfrac.c ||
  36354. echo "restore of miscfrac.c failed"
  36355. set `wc -c miscfrac.c`;Wc_c=$1
  36356. if test "$Wc_c" != "56787"; then
  36357.     echo original size 56787, current size $Wc_c
  36358. fi
  36359. # ============= miscovl.c ==============
  36360. echo "x - extracting miscovl.c (Text)"
  36361. sed 's/^X//' << 'SHAR_EOF' > miscovl.c &&
  36362. X/*
  36363. X    Overlayed odds and ends that don't fit anywhere else.
  36364. X*/
  36365. X
  36366. X#include <stdlib.h>
  36367. X#include <stdio.h>
  36368. X#include <string.h>
  36369. X#ifndef XFRACT
  36370. X#include <process.h>
  36371. X#include <dos.h>
  36372. X#include <stdarg.h>
  36373. X#include <io.h>
  36374. X#else
  36375. X#include <varargs.h>
  36376. X#endif
  36377. X#include "fractint.h"
  36378. X#include "fractype.h"
  36379. X#include "helpdefs.h"
  36380. X#include "prototyp.h"
  36381. X
  36382. X/* routines in this module    */
  36383. X
  36384. Xstatic void write_batch_parms(FILE *,char *,int);
  36385. X#ifndef XFRACT
  36386. Xstatic void put_parm(char *parm,...);
  36387. X#else
  36388. Xstatic void put_parm();
  36389. X#endif
  36390. X
  36391. Xstatic void put_parm_line(void);
  36392. Xstatic int getprec(double,double,double);
  36393. Xstatic void put_float(int,double,int);
  36394. Xstatic void put_filename(char *keyword,char *fname);
  36395. Xstatic void format_item(int choice,char *buf);
  36396. Xstatic int check_modekey(int curkey,int choice);
  36397. Xstatic int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2);
  36398. Xstatic void update_fractint_cfg(void);
  36399. Xextern int  debugflag;
  36400. Xextern int  xdots,ydots;
  36401. Xextern int  cpu;        /* cpu type            */
  36402. Xextern int  fpu;        /* fpu type            */
  36403. Xextern int  iit;        /* iit fpu?            */
  36404. Xextern int  video_type;
  36405. Xextern int  askvideo;
  36406. Xextern char overwrite;        /* 1 means ok to overwrite */
  36407. Xextern int  fillcolor;        /* fill color: -1 = normal*/
  36408. Xextern int  inside;        /* inside color: 1=blue     */
  36409. Xextern int  outside;        /* outside color, if set    */
  36410. Xextern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
  36411. Xextern double sxmin, sxmax, sx3rd, symin, symax, sy3rd; /* zoom box corners */
  36412. Xextern double param[];       /* up to four parameters    */
  36413. Xextern int  finattract;     /* finite attractor option  */
  36414. Xextern int  forcesymmetry;
  36415. Xextern int  LogFlag;        /* non-zero if logarithmic palettes */
  36416. Xextern int  rflag, rseed;
  36417. Xextern int  periodicitycheck;
  36418. Xextern int  potflag;        /* continuous potential flag */
  36419. Xextern int  pot16bit;        /* save 16 bit values for continuous potential */
  36420. Xextern double potparam[3];    /* three potential parameters*/
  36421. Xextern int  fractype;        /* if == 0, use Mandelbrot  */
  36422. Xextern BYTE usemag;
  36423. Xextern long delmin;
  36424. Xextern int  maxit;        /* try this many iterations */
  36425. Xextern int  invert;        /* non-zero if inversion active */
  36426. Xextern double inversion[];
  36427. Xextern int  decomp[];
  36428. Xextern int  distest;        /* non-zero if distance estimator   */
  36429. Xextern int  distestwidth;
  36430. Xextern int  init3d[20];     /* '3d=nn/nn/nn/...' values */
  36431. Xextern char floatflag;        /* floating-point fractals? */
  36432. Xextern int  usr_biomorph;
  36433. Xextern char FormFileName[];    /* file to find (type=)formulas in */
  36434. Xextern char FormName[];     /* Name of the Formula (if not null) */
  36435. Xextern char LFileName[];
  36436. Xextern char LName[];
  36437. Xextern char IFSFileName[];
  36438. Xextern char IFSName[];
  36439. Xextern int  bailout;        /* user input bailout value */
  36440. Xextern char useinitorbit;
  36441. Xextern _CMPLX initorbit;
  36442. Xextern int  display3d;        /* 3D display flag: 0 = OFF */
  36443. Xextern int  overlay3d;        /* 3D overlay flag: 0 = OFF */
  36444. Xextern int  loaded3d;
  36445. Xextern char readname[];     /* name of fractal input file */
  36446. Xextern int  showfile;        /* has file been displayed yet? */
  36447. Xextern int  transparent[];
  36448. Xextern char preview;        /* 3D preview mode flag */
  36449. Xextern char showbox;        /* flag to show box and vector in preview */
  36450. Xextern int  RANDOMIZE;        /* Color randomizing factor */
  36451. Xextern int  Targa_Out;  /* Selects full color with light source fills */
  36452. Xextern int  Ambient;        /* Darkness of shadows in light source */
  36453. Xextern int  haze;        /* Amount of haze to factor in in full color */
  36454. Xextern char light_name[];    /* Name of full color .TGA file */
  36455. Xextern int previewfactor;
  36456. Xextern int BRIEF;
  36457. Xextern int RAY;
  36458. Xextern int xtrans;
  36459. Xextern int ytrans;
  36460. Xextern int red_crop_left;
  36461. Xextern int red_crop_right;
  36462. Xextern int blue_crop_left;
  36463. Xextern int blue_crop_right;
  36464. Xextern int red_bright;
  36465. Xextern int blue_bright;
  36466. Xextern int xadjust;
  36467. Xextern int eyeseparation;
  36468. Xextern int glassestype;
  36469. Xextern BYTE trigndx[];
  36470. Xextern int rotate_lo,rotate_hi;
  36471. Xextern int far *ranges;
  36472. Xextern int rangeslen;
  36473. Xextern char CommandFile[80];
  36474. Xextern char CommandName[ITEMNAMELEN+1];
  36475. Xextern char far CommandComment1[57];
  36476. Xextern char far CommandComment2[57];
  36477. Xextern char far CommandComment3[57];
  36478. Xextern char far CommandComment4[57];
  36479. Xextern char usr_stdcalcmode;
  36480. X
  36481. Xextern int calc_status;
  36482. Xextern double    sxmin,sxmax,symin,symax,sx3rd,sy3rd;
  36483. X
  36484. X/* Julibrot variables TIW 1/24/93 */
  36485. Xextern double mxmaxfp, mxminfp, mymaxfp, myminfp, originfp;
  36486. Xextern double depthfp, heightfp, widthfp, distfp, eyesfp;
  36487. X
  36488. Xextern int zdots; 
  36489. Xextern int lastorbittype, neworbittype;
  36490. Xextern char *juli3Doptions[];
  36491. Xextern int juli3Dmode;
  36492. X
  36493. X/* viewwindows parameters */
  36494. Xextern int   viewwindow;
  36495. Xextern float viewreduction;
  36496. Xextern int   viewcrop;
  36497. Xextern float finalaspectratio;
  36498. Xextern int   viewxdots,viewydots;
  36499. X
  36500. Xextern int  colorstate;     /* comments in cmdfiles */
  36501. Xextern int  colors;
  36502. Xextern int  gotrealdac;
  36503. Xextern int  reallyega;
  36504. Xextern char colorfile[];
  36505. Xextern int  mapset;
  36506. Xextern char MAP_name[];
  36507. Xextern BYTE dacbox[256][3];
  36508. Xextern char far *mapdacbox;
  36509. Xextern int save_release;
  36510. X
  36511. Xextern char tstack[4096];
  36512. Xextern char s_cantopen[];
  36513. Xextern char s_cantwrite[];
  36514. Xextern char s_cantcreate[];
  36515. Xextern char s_cantunderstand[];
  36516. Xextern char s_cantfind[];
  36517. Xextern int calc_status;
  36518. X
  36519. Xextern struct videoinfo far videotable[];
  36520. X
  36521. X/* fullscreen_choice options */
  36522. X#define CHOICERETURNKEY 1
  36523. X#define CHOICEMENU    2
  36524. X#define CHOICEHELP    4
  36525. Xvoid miscovl_overlay() { }    /* for restore_active_ovly */
  36526. X
  36527. Xextern char s_real[];
  36528. Xextern char s_imag[];
  36529. Xextern char s_mult[];
  36530. Xextern char s_sum[];
  36531. Xextern char s_zmag[];
  36532. Xextern char s_bof60[];
  36533. Xextern char s_bof61[];
  36534. Xextern char s_maxiter[];
  36535. Xextern char s_epscross[];
  36536. Xextern char s_startrail[];
  36537. Xextern char s_normal[];
  36538. Xextern char s_period[];
  36539. X
  36540. Xchar *major[] = {"breadth","depth","walk","run"};
  36541. Xchar *minor[] = {"left","right"};
  36542. X
  36543. Xstatic FILE *parmfile;
  36544. X
  36545. X#define PAR_KEY(x)  ( x < 10 ? '0' + x : 'a' - 10 + x)
  36546. X
  36547. X#ifdef C6
  36548. X#pragma optimize("e",off)  /* MSC 6.00A messes up next rtn with "e" on */
  36549. X#endif
  36550. Xvoid make_batch_file()
  36551. X{
  36552. X   static char far hdg[]={"Save Current Parameters"};
  36553. X   /** added for pieces feature **/
  36554. X   double pdelx;
  36555. X   double pdely;
  36556. X   double pdelx2;
  36557. X   double pdely2;
  36558. X   unsigned int j, pxdots, pydots, xm, ym;
  36559. X   double pxxmin, pxxmax, pyymin, pyymax, pxx3rd, pyy3rd;
  36560. X   char vidmde[4];
  36561. X   int promptnum;
  36562. X   int piecespromts;
  36563. X   int have3rd;
  36564. X   /****/
  36565. X
  36566. X   int i;
  36567. X   char inpcommandfile[80], inpcommandname[ITEMNAMELEN + 1];
  36568. X   char inpcomment1[57], inpcomment2[57], inpcomment3[57], inpcomment4[57];
  36569. X   struct fullscreenvalues paramvalues[18];
  36570. X   char far *choices[18];
  36571. X   int gotinfile;
  36572. X   char outname[81], buf[256], buf2[128];
  36573. X   FILE *infile;
  36574. X   FILE *fpbat=NULL;
  36575. X   char colorspec[14];
  36576. X   int maxcolor;
  36577. X   int maxcolorindex;
  36578. X   char *sptr, *sptr2;
  36579. X   int oldhelpmode;
  36580. X
  36581. X   ENTER_OVLY(OVLY_MISCOVL);
  36582. X   stackscreen();
  36583. X   oldhelpmode = helpmode;
  36584. X   helpmode = HELPPARMFILE;
  36585. X
  36586. X   strcpy(colorspec, "n");
  36587. X   maxcolor = colors;
  36588. X   if (gotrealdac && !reallyega)
  36589. X   {
  36590. X      --maxcolor;
  36591. X/*    if (maxit < maxcolor)  remove 2 lines */
  36592. X/*       maxcolor = maxit;   so that whole palette is always saved */
  36593. X      if (inside > 0 && inside > maxcolor)
  36594. X         maxcolor = inside;
  36595. X      if (outside > 0 && outside > maxcolor)
  36596. X         maxcolor = outside;
  36597. X      if (distest < 0 && 0 - distest > maxcolor)
  36598. X         maxcolor = 0 - distest;
  36599. X      if (decomp[0] > maxcolor)
  36600. X         maxcolor = decomp[0] - 1;
  36601. X      if (potflag && potparam[0] >= maxcolor)
  36602. X         maxcolor = potparam[0];
  36603. X      if (++maxcolor > 256)
  36604. X         maxcolor = 256;
  36605. X      if (colorstate == 0)
  36606. X      {                         /* default colors */
  36607. X         if (mapdacbox)
  36608. X         {
  36609. X            colorspec[0] = '@';
  36610. X            sptr = MAP_name;
  36611. X         }
  36612. X      }
  36613. X      else
  36614. X      if (colorstate == 2)
  36615. X      {                         /* colors match colorfile */
  36616. X         colorspec[0] = '@';
  36617. X         sptr = colorfile;
  36618. X      }
  36619. X      else                      /* colors match no .map that we know of */
  36620. X         colorspec[0] = 'y';
  36621. X      if (colorspec[0] == '@')
  36622. X      {
  36623. X         if ((sptr2 = strrchr(sptr, SLASHC)))
  36624. X            sptr = sptr2 + 1;
  36625. X         if ((sptr2 = strrchr(sptr, ':')))
  36626. X            sptr = sptr2 + 1;
  36627. X         strncpy(&colorspec[1], sptr, 12);
  36628. X         colorspec[13] = 0;
  36629. X      }
  36630. X   }
  36631. X   strcpy(inpcommandfile, CommandFile);
  36632. X   strcpy(inpcommandname, CommandName);
  36633. X   far_strcpy(inpcomment1, CommandComment1);
  36634. X   far_strcpy(inpcomment2, CommandComment2);
  36635. X   far_strcpy(inpcomment3, CommandComment3);
  36636. X   far_strcpy(inpcomment4, CommandComment4);
  36637. X   if (CommandName[0] == 0)
  36638. X      strcpy(inpcommandname, "test");
  36639. X      /* TW added these  - and Bert moved them */
  36640. X      pxdots = xdots;
  36641. X      pydots = ydots;
  36642. X      vidmode_keyname(videoentry.keynum, vidmde);
  36643. X
  36644. X      xm = ym = 1;
  36645. X
  36646. X   while (1)
  36647. X   {
  36648. Xprompt_user:
  36649. X      promptnum = 0;
  36650. X      {
  36651. X         static char far tmp[] = {"Parameter file"};
  36652. X         choices[promptnum] = tmp;
  36653. X      }
  36654. X      paramvalues[promptnum].type = 0x100 + 56;
  36655. X      paramvalues[promptnum++].uval.sbuf = inpcommandfile;
  36656. X      {
  36657. X         static char far tmp[] = {"Name"};
  36658. X         choices[promptnum] = tmp;
  36659. X      }
  36660. X      paramvalues[promptnum].type = 0x100 + ITEMNAMELEN;
  36661. X      paramvalues[promptnum++].uval.sbuf = inpcommandname;
  36662. X      {
  36663. X         static char far tmp[] = {"Main comment"};
  36664. X         choices[promptnum] = tmp;
  36665. X      }
  36666. X      paramvalues[promptnum].type = 0x100 + 56;
  36667. X      paramvalues[promptnum++].uval.sbuf = inpcomment1;
  36668. X      {
  36669. X         static char far tmp[] = {"Second comment"};
  36670. X         choices[promptnum] = tmp;
  36671. X      }
  36672. X      paramvalues[promptnum].type = 0x100 + 56;;
  36673. X      paramvalues[promptnum++].uval.sbuf = inpcomment2;
  36674. X      {
  36675. X         static char far tmp[] = {"Third comment"};
  36676. X         choices[promptnum] = tmp;
  36677. X      }
  36678. X      paramvalues[promptnum].type = 0x100 + 56;;
  36679. X      paramvalues[promptnum++].uval.sbuf = inpcomment3;
  36680. X      {
  36681. X         static char far tmp[] = {"Fourth comment"};
  36682. X         choices[promptnum] = tmp;
  36683. X      }
  36684. X      paramvalues[promptnum].type = 0x100 + 56;;
  36685. X      paramvalues[promptnum++].uval.sbuf = inpcomment4;
  36686. X      if (gotrealdac && !reallyega)
  36687. X      {
  36688. X         {
  36689. X            static char far tmp[] = {"Record colors?"};
  36690. X            choices[promptnum] = tmp;
  36691. X         }
  36692. X         paramvalues[promptnum].type = 0x100 + 13;
  36693. X         paramvalues[promptnum++].uval.sbuf = colorspec;
  36694. X         {
  36695. X            static char far tmp[] = {"    (no | yes for full info | @filename to point to a map file)"};
  36696. X            choices[promptnum] = tmp;
  36697. X         }
  36698. X         paramvalues[promptnum++].type = '*';
  36699. X         {
  36700. X            static char far tmp[] = {"# of colors"};
  36701. X            choices[promptnum] = tmp;
  36702. X         }
  36703. X         maxcolorindex = promptnum;
  36704. X         paramvalues[promptnum].type = 'i';
  36705. X         paramvalues[promptnum++].uval.ival = maxcolor;
  36706. X         {
  36707. X            static char far tmp[] = {"    (if recording full color info)"};
  36708. X            choices[promptnum] = tmp;
  36709. X         }
  36710. X         paramvalues[promptnum++].type = '*';
  36711. X      }
  36712. X      {
  36713. X         static char tmp[] = {""};
  36714. X         choices[promptnum] = tmp;
  36715. X      }
  36716. X      paramvalues[promptnum++].type = '*';
  36717. X
  36718. X      {
  36719. X         static char far tmp[] = {"    **** The following is for generating images in pieces ****"};
  36720. X         choices[promptnum] = tmp;
  36721. X      }
  36722. X      paramvalues[promptnum++].type = '*';
  36723. X      {
  36724. X         static char far tmp[] = {"X Multiples"};
  36725. X         choices[promptnum] = tmp;
  36726. X      }
  36727. X      piecespromts = promptnum;
  36728. X      paramvalues[promptnum].type = 'i';
  36729. X      paramvalues[promptnum++].uval.ival = xm;
  36730. X
  36731. X      {
  36732. X         static char far tmp[] = {"Y Multiples"};
  36733. X         choices[promptnum] = tmp;
  36734. X      }
  36735. X      paramvalues[promptnum].type = 'i';
  36736. X      paramvalues[promptnum++].uval.ival = ym;
  36737. X
  36738. X#ifndef XFRACT
  36739. X      {
  36740. X         static char far tmp[] = {"Video mode"};
  36741. X         choices[promptnum] = tmp;
  36742. X      }
  36743. X      paramvalues[promptnum].type = 0x100 + 4;
  36744. X      paramvalues[promptnum++].uval.sbuf = vidmde;
  36745. X#endif
  36746. X
  36747. X      if (fullscreen_prompt(hdg,promptnum, choices, paramvalues, 0, 0, NULL) < 0)
  36748. X         break;
  36749. X
  36750. X      strcpy(CommandFile, inpcommandfile);
  36751. X      if (strchr(CommandFile, '.') == NULL)
  36752. X         strcat(CommandFile, ".par");   /* default extension .par */
  36753. X      strcpy(CommandName, inpcommandname);
  36754. X      far_strcpy(CommandComment1, inpcomment1);
  36755. X      far_strcpy(CommandComment2, inpcomment2);
  36756. X      far_strcpy(CommandComment3, inpcomment3);
  36757. X      far_strcpy(CommandComment4, inpcomment4);
  36758. X      if (gotrealdac && !reallyega)
  36759. X         if (paramvalues[maxcolorindex].uval.ival > 0 &&
  36760. X             paramvalues[maxcolorindex].uval.ival <= 256)
  36761. X            maxcolor = paramvalues[maxcolorindex].uval.ival;
  36762. X
  36763. X      promptnum = piecespromts;
  36764. X      xm = paramvalues[promptnum++].uval.ival;
  36765. X
  36766. X      ym = paramvalues[promptnum++].uval.ival;
  36767. X
  36768. X      /* sanity checks */
  36769. X      {
  36770. X      int i;
  36771. X      long xtotal, ytotal;
  36772. X
  36773. X      /* get resolution from the video name (which must be valid) */
  36774. X#ifndef XFRACT
  36775. X      pxdots = pydots = 0;
  36776. X      if ((i = check_vidmode_keyname(vidmde)) > 0)
  36777. X          if ((i = check_vidmode_key(0, i)) >= 0) {
  36778. X              /* get the resolution of this video mode */
  36779. X              pxdots = videotable[i].xdots;
  36780. X              pydots = videotable[i].ydots;
  36781. X              }
  36782. X      if (pxdots == 0 ) {
  36783. X          /* no corresponding video mode! */
  36784. X          static char far msg[] = {"Invalid video mode entry!"};
  36785. X          stopmsg(0,msg);
  36786. X          goto prompt_user;
  36787. X          }
  36788. X#endif
  36789. X
  36790. X      /* bounds range on xm, ym */
  36791. X      if (xm < 1 || xm > 36 || ym < 1 || ym > 36) {
  36792. X          static char far msg[] = {"X and Y components must be 1 to 36"};
  36793. X          stopmsg(0,msg);
  36794. X          goto prompt_user;
  36795. X          }
  36796. X
  36797. X      /* another sanity check: total resolution cannot exceed 65535 */
  36798. X      xtotal = xm;  ytotal = ym;
  36799. X      xtotal *= pxdots;  ytotal *= pydots;
  36800. X      if (xtotal > 65535L || ytotal > 65535L) {
  36801. X      static char far msg[] = {"Total resolution (X or Y) cannot exceed 65535"};
  36802. X          stopmsg(0,msg);
  36803. X          goto prompt_user;
  36804. X          }
  36805. X      }
  36806. X
  36807. X      strcpy(outname, CommandFile);
  36808. X      gotinfile = 0;
  36809. X      if (access(CommandFile, 0) == 0)
  36810. X      {                         /* file exists */
  36811. X         gotinfile = 1;
  36812. X         if (access(CommandFile, 6))
  36813. X         {
  36814. X            sprintf(buf, s_cantwrite, CommandFile);
  36815. X            stopmsg(0, buf);
  36816. X            continue;
  36817. X         }
  36818. X         i = strlen(outname);
  36819. X         while (--i >= 0 && outname[i] != SLASHC)
  36820. X            outname[i] = 0;
  36821. X         strcat(outname, "fractint.tmp");
  36822. X         infile = fopen(CommandFile, "rt");
  36823. X#ifndef XFRACT
  36824. X         setvbuf(infile, tstack, _IOFBF, 4096); /* improves speed */
  36825. X#endif
  36826. X      }
  36827. X      if ((parmfile = fopen(outname, "wt")) == NULL)
  36828. X      {
  36829. X         sprintf(buf, s_cantcreate, outname);
  36830. X         stopmsg(0, buf);
  36831. X         if (gotinfile)
  36832. X            fclose(infile);
  36833. X         continue;
  36834. X      }
  36835. X
  36836. X      if (gotinfile)
  36837. X      {
  36838. X         while (file_gets(buf, 255, infile) >= 0)
  36839. X         {
  36840. X            if (strchr(buf, '{')/* entry heading? */
  36841. X                && sscanf(buf, " %40[^ \t({]", buf2)
  36842. X                && stricmp(buf2, CommandName) == 0)
  36843. X            {                   /* entry with same name */
  36844. X               sprintf(buf2, "File already has an entry named %s\n\
  36845. XContinue to replace it, Cancel to back out", CommandName);
  36846. X               if (stopmsg(18, buf2) < 0)
  36847. X               {                /* cancel */
  36848. X                  fclose(infile);
  36849. X                  fclose(parmfile);
  36850. X                  unlink(outname);
  36851. X                  goto prompt_user;
  36852. X               }
  36853. X               while (strchr(buf, '}') == NULL
  36854. X                      && file_gets(buf, 255, infile) > 0)
  36855. X               {
  36856. X               }                /* skip to end of set */
  36857. X               break;
  36858. X            }
  36859. X            fputs(buf, parmfile);
  36860. X            fputc('\n', parmfile);
  36861. X         }
  36862. X      }
  36863. X/***** start here*/
  36864. X      if (xm > 1 || ym > 1)
  36865. X      {
  36866. X         if (xxmin != xx3rd || yymin != yy3rd)
  36867. X            have3rd = 1;
  36868. X         else
  36869. X            have3rd = 0;
  36870. X         if ((fpbat = fopen("makemig.bat", "w")) == NULL)
  36871. X            xm = ym = 0;
  36872. X         pdelx  = (xxmax - xx3rd) / (xm * pxdots - 1);   /* calculate stepsizes */
  36873. X         pdely  = (yymax - yy3rd) / (ym * pydots - 1);
  36874. X         pdelx2 = (xx3rd - xxmin) / (ym * pydots - 1);
  36875. X         pdely2 = (yy3rd - yymin) / (xm * pxdots - 1);
  36876. X
  36877. X         /* save corners */
  36878. X         pxxmin = xxmin;
  36879. X         pxxmax = xxmax;
  36880. X         pyymin = yymin;
  36881. X         pyymax = yymax;
  36882. X      }
  36883. X      for (i = 0; i < xm; i++)  /* columns */
  36884. X      for (j = 0; j < ym; j++)  /* rows    */
  36885. X      {
  36886. X         if (xm > 1 || ym > 1)
  36887. X         {
  36888. X            int w;
  36889. X            char c;
  36890. X            char PCommandName[80];
  36891. X            w=0;
  36892. X            while(w < strlen(CommandName))
  36893. X            {
  36894. X               c = CommandName[w];
  36895. X               if(isspace(c) || c == 0)
  36896. X                  break;
  36897. X               PCommandName[w] = c;
  36898. X               w++;
  36899. X            }
  36900. X            PCommandName[w] = 0;
  36901. X            {
  36902. X               char buf[20];
  36903. X               sprintf(buf,"_%c%c",PAR_KEY(i),PAR_KEY(j));
  36904. X               strcat(PCommandName,buf);
  36905. X            }
  36906. X            fprintf(parmfile, "%-19s{",PCommandName);
  36907. X            xxmin = pxxmin + pdelx*(i*pxdots) + pdelx2*(j*pydots);
  36908. X            xxmax = pxxmin + pdelx*((i+1)*pxdots - 1) + pdelx2*((j+1)*pydots - 1);
  36909. X            yymin = pyymax - pdely*((j+1)*pydots - 1) - pdely2*((i+1)*pxdots - 1);
  36910. X            yymax = pyymax - pdely*(j*pydots) - pdely2*(i*pxdots);
  36911. X            if (have3rd)
  36912. X            {
  36913. X               xx3rd = pxxmin + pdelx*(i*pxdots) + pdelx2*((j+1)*pydots - 1);
  36914. X               yy3rd = pyymax - pdely*((j+1)*pydots - 1) - pdely2*(i*pxdots);
  36915. X            }
  36916. X            else
  36917. X            {
  36918. X               xx3rd = xxmin;
  36919. X               yy3rd = yymin;
  36920. X            }
  36921. X            fprintf(fpbat,"Fractint batch=yes overwrite=yes @%s/%s\n",CommandFile,PCommandName);
  36922. X            fprintf(fpbat,"If Errorlevel 2 goto oops\n");
  36923. X         }
  36924. X         else
  36925. X            fprintf(parmfile, "%-19s{", CommandName);
  36926. X         if (CommandComment1[0])
  36927. X            fprintf(parmfile, " ; %Fs", CommandComment1);
  36928. X         fputc('\n', parmfile);
  36929. X         {
  36930. X            char buf[25];
  36931. X            memset(buf, ' ', 23);
  36932. X            buf[23] = 0;
  36933. X            buf[21] = ';';
  36934. X            if (CommandComment2[0])
  36935. X               fprintf(parmfile, "%s%Fs\n", buf, CommandComment2);
  36936. X            if (CommandComment3[0])
  36937. X               fprintf(parmfile, "%s%Fs\n", buf, CommandComment3);
  36938. X            if (CommandComment4[0])
  36939. X               fprintf(parmfile, "%s%Fs\n", buf, CommandComment4);
  36940. X         }
  36941. X         write_batch_parms(parmfile, colorspec, maxcolor);   /* write the parameters */
  36942. X         if(xm > 1 || ym > 1)
  36943. X         {
  36944. X            fprintf(parmfile,"  video=%s", vidmde);
  36945. X            fprintf(parmfile," savename=frmig_%c%c\n", PAR_KEY(i), PAR_KEY(j));
  36946. X         }
  36947. X         fprintf(parmfile, "  }\n\n");
  36948. X      }
  36949. X      if(xm > 1 || ym > 1)
  36950. X         {
  36951. X         fprintf(fpbat,"Fractint makemig=%d/%d\n",xm,ym);
  36952. X         fprintf(fpbat,"Rem Simplgif fractmig.gif simplgif.gif  in case you need it\n");
  36953. X         fprintf(fpbat,":oops\n");
  36954. X         fclose(fpbat);
  36955. X         }
  36956. X/*******end here */
  36957. X
  36958. X      if (gotinfile)
  36959. X      {                         /* copy the rest of the file */
  36960. X         while ((i = file_gets(buf, 255, infile)) == 0)
  36961. X         {
  36962. X         }                      /* skip blanks */
  36963. X         while (i >= 0)
  36964. X         {
  36965. X            fputs(buf, parmfile);
  36966. X            fputc('\n', parmfile);
  36967. X            i = file_gets(buf, 255, infile);
  36968. X         }
  36969. X         fclose(infile);
  36970. X      }
  36971. X      fclose(parmfile);
  36972. X      if (gotinfile)
  36973. X      {                         /* replace the original file with the new */
  36974. X         unlink(CommandFile);   /* success assumed on these lines       */
  36975. X         rename(outname, CommandFile);  /* since we checked earlier with
  36976. X                                         * access */
  36977. X      }
  36978. X      break;
  36979. X   }
  36980. X   helpmode = oldhelpmode;
  36981. X   unstackscreen();
  36982. X   EXIT_OVLY;
  36983. X}
  36984. X#ifdef C6
  36985. X#pragma optimize("e",on)  /* back to normal */
  36986. X#endif
  36987. X
  36988. Xstatic struct write_batch_data { /* buffer for parms to break lines nicely */
  36989. X   int len;
  36990. X   char buf[513];
  36991. X   } *wbdata;
  36992. X
  36993. Xstatic void write_batch_parms(FILE *batch,char *colorinf,int maxcolor)
  36994. X{
  36995. X   int i,j,k;
  36996. X   double Xctr, Yctr, Magnification;
  36997. X   struct write_batch_data wb_data;
  36998. X   char *sptr;
  36999. X   char buf[81];
  37000. X
  37001. X   wbdata = &wb_data;
  37002. X   wb_data.len = 0; /* force first parm to start on new line */
  37003. X
  37004. X   if (display3d <= 0) { /* a fractal was generated */
  37005. X
  37006. X      /****** fractal only parameters in this section *******/
  37007. X      put_parm(" reset");
  37008. X      if (save_release!=0) put_parm("=%d",save_release);
  37009. X
  37010. X      if (*(sptr = curfractalspecific->name) == '*') ++sptr;
  37011. X      put_parm( " type=%s",sptr);
  37012. X
  37013. X      if (fractype == JULIBROT || fractype == JULIBROTFP)
  37014. X      {
  37015. X           put_parm(" julibrotfromto=%.15g/%.15g/%.15g/%.15g",
  37016. X               mxmaxfp,mxminfp,mymaxfp,myminfp);
  37017. X         /* these rarely change */
  37018. X         if(originfp != 8 || heightfp != 7 || widthfp != 10 || distfp != 24
  37019. X                          || depthfp != 8 || zdots != 128)
  37020. X            put_parm(" julibrot3d=%d/%g/%g/%g/%g/%g",
  37021. X                zdots, originfp, depthfp, heightfp, widthfp,distfp);
  37022. X         if(eyesfp != 0)
  37023. X            put_parm(" julibroteyes=%g",eyesfp);
  37024. X         if(neworbittype != JULIA)
  37025. X         {
  37026. X            char *name;
  37027. X            name = fractalspecific[neworbittype].name;
  37028. X            if(*name=='*')
  37029. X               name++;
  37030. X            put_parm(" orbitname=%s",name);
  37031. X         }
  37032. X         if(juli3Dmode !=0)
  37033. X            put_parm(" 3Dmode=%s",juli3Doptions[juli3Dmode]);
  37034. X      }
  37035. X      if (fractype == FORMULA || fractype == FFORMULA)
  37036. X     put_parm( " formulafile=%s formulaname=%s",extract_filename(FormFileName),FormName);
  37037. X      if (fractype == LSYSTEM)
  37038. X     put_parm( " lfile=%s lname=%s",extract_filename(LFileName),LName);
  37039. X      if (fractype == IFS || fractype == IFS3D)
  37040. X     put_parm( " ifsfile=%s ifs=%s",extract_filename(IFSFileName),IFSName);
  37041. X      if (fractype == INVERSEJULIA || fractype == INVERSEJULIAFP)
  37042. X      {
  37043. X     extern int major_method, minor_method;
  37044. X     put_parm( " miim=%s/%s", major[major_method], minor[minor_method]);
  37045. X      }
  37046. X
  37047. X      showtrig(buf); /* this function is in miscres.c */
  37048. X      if (buf[0])
  37049. X     put_parm(buf);
  37050. X
  37051. X      if (usr_stdcalcmode != 'g')
  37052. X     put_parm(" passes=%c",usr_stdcalcmode);
  37053. X
  37054. X      if (usemag && cvtcentermag(&Xctr, &Yctr, &Magnification)) {
  37055. X     put_parm(" center-mag=");
  37056. X     put_parm((delmin > 1000) ? "%g/%g/%g"
  37057. X                  : "%+20.17lf/%+20.17lf/%+20.17lf",
  37058. X          Xctr,Yctr,Magnification);
  37059. X     }
  37060. X      else {
  37061. X     int xdigits,ydigits;
  37062. X     put_parm( " corners=");
  37063. X     xdigits = getprec(xxmin,xxmax,xx3rd);
  37064. X     ydigits = getprec(yymin,yymax,yy3rd);
  37065. X     put_float(0,xxmin,xdigits);
  37066. X     put_float(1,xxmax,xdigits);
  37067. X     put_float(1,yymin,ydigits);
  37068. X     put_float(1,yymax,ydigits);
  37069. X     if (xx3rd != xxmin || yy3rd != yymin) {
  37070. X        put_float(1,xx3rd,xdigits);
  37071. X        put_float(1,yy3rd,ydigits);
  37072. X        }
  37073. X     }
  37074. X
  37075. X      for (i = (MAXPARAMS-1); i >= 0; --i)
  37076. X     if (param[i] != 0.0) break;
  37077. X      if (i >= 0) {
  37078. X        if (fractype == CELLULAR)
  37079. X          put_parm(" params=%.1f",param[0]);
  37080. X        else
  37081. X#ifndef XFRACT
  37082. X     put_parm(" params=%.17Lg",(long double)param[0]);
  37083. X#else
  37084. X       put_parm(" params=%.17g",(double)param[0]);
  37085. X#endif
  37086. X     for (j = 1; j <= i; ++j)
  37087. X        if (fractype == CELLULAR)
  37088. X          put_parm("/%.1f",param[j]);
  37089. X        else
  37090. X#ifndef XFRACT
  37091. X        put_parm("/%.17Lg",(long double)param[j]);
  37092. X#else
  37093. X          put_parm("/%.17g",(double)param[j]);
  37094. X#endif
  37095. X     }
  37096. X
  37097. X      if(useinitorbit == 2)
  37098. X     put_parm( " initorbit=pixel");
  37099. X      else if(useinitorbit == 1)
  37100. X     put_parm( " initorbit=%.15g/%.15g",initorbit.x,initorbit.y);
  37101. X
  37102. X      if (floatflag)
  37103. X     put_parm( " float=y");
  37104. X
  37105. X      if (maxit != 150)
  37106. X     put_parm(" maxiter=%d",maxit);
  37107. X
  37108. X      if(bailout && (potflag == 0 || potparam[2] == 0.0))
  37109. X     put_parm( " bailout=%d",bailout);
  37110. X      if(fillcolor != -1) {
  37111. X       put_parm(" fillcolor=");
  37112. X    put_parm( "%d",fillcolor);
  37113. X      }
  37114. X      if (inside != 1) {
  37115. X     put_parm(" inside=");
  37116. X     if (inside == -1)
  37117. X        put_parm( s_maxiter);
  37118. X     else if (inside == -59)
  37119. X        put_parm(s_zmag);
  37120. X     else if (inside == -60)
  37121. X        put_parm(s_bof60);
  37122. X     else if (inside == -61)
  37123. X        put_parm(s_bof61);
  37124. X     else if (inside == -100)
  37125. X        put_parm(s_epscross);
  37126. X     else if (inside == -101)
  37127. X        put_parm(s_startrail);
  37128. X     else if (inside == -102)
  37129. X        put_parm(s_period);
  37130. X     else
  37131. X        put_parm( "%d",inside);
  37132. X     }
  37133. X      if (outside != -1)
  37134. X      {
  37135. X     put_parm(" outside=");
  37136. X     if (outside == -2)
  37137. X        put_parm(s_real);
  37138. X     else if (outside == -3)
  37139. X        put_parm(s_imag);
  37140. X     else if (outside == -4)
  37141. X        put_parm(s_mult);
  37142. X     else if (outside == -5)
  37143. X        put_parm(s_sum);
  37144. X     else
  37145. X        put_parm( "%d",outside);
  37146. X      }
  37147. X
  37148. X      if(LogFlag) {
  37149. X     put_parm( " logmap=");
  37150. X     if(LogFlag == -1)
  37151. X        put_parm( "old");
  37152. X     else if(LogFlag == 1)
  37153. X        put_parm( "yes");
  37154. X     else
  37155. X        put_parm( "%d", LogFlag);
  37156. X     }
  37157. X
  37158. X      if (potflag) {
  37159. X       put_parm( " potential=%d/%g/%d",
  37160. X           (int)potparam[0],potparam[1],(int)potparam[2]);
  37161. X       if(pot16bit)
  37162. X        put_parm( "/16bit");
  37163. X     }
  37164. X      if (invert)
  37165. X     put_parm( " invert=%g/%g/%g",
  37166. X         inversion[0], inversion[1], inversion[2]);
  37167. X      if (decomp[0])
  37168. X     put_parm( " decomp=%d", decomp[0]);
  37169. X      if (distest)
  37170. X     put_parm( " distest=%d/%d", distest, distestwidth);
  37171. X      if (usr_biomorph != -1)
  37172. X     put_parm( " biomorph=%d", usr_biomorph);
  37173. X      if (finattract)
  37174. X     put_parm(" finattract=y");
  37175. X
  37176. X      if (forcesymmetry != 999) {
  37177. X         static char far msg[] = 
  37178. X            {"Regenerate before <b> to get correct symmetry"};
  37179. X         if(forcesymmetry == 1000)
  37180. X            stopmsg(0,msg);
  37181. X     put_parm( " symmetry=");
  37182. X     if (forcesymmetry==XAXIS)
  37183. X        put_parm("xaxis");
  37184. X     else if(forcesymmetry==YAXIS)
  37185. X        put_parm("yaxis");
  37186. X     else if(forcesymmetry==XYAXIS)
  37187. X        put_parm("xyaxis");
  37188. X     else if(forcesymmetry==ORIGIN)
  37189. X        put_parm("origin");
  37190. X     else if(forcesymmetry==PI_SYM)
  37191. X        put_parm("pi");
  37192. X     else
  37193. X        put_parm("none");
  37194. X     }
  37195. X
  37196. X      if (periodicitycheck != 1)
  37197. X     put_parm( " periodicity=%d",periodicitycheck);
  37198. X
  37199. X      if (rflag)
  37200. X     put_parm( " rseed=%d",rseed);
  37201. X
  37202. X      if (rangeslen) {
  37203. X     put_parm(" ranges=");
  37204. X     i = 0;
  37205. X     while (i < rangeslen) {
  37206. X        if (i)
  37207. X           put_parm("/");
  37208. X        if (ranges[i] == -1) {
  37209. X           put_parm("-%d/",ranges[++i]);
  37210. X           ++i;
  37211. X           }
  37212. X        put_parm("%d",ranges[i++]);
  37213. X        }
  37214. X     }
  37215. X      }
  37216. X
  37217. X   if (display3d >= 1) {
  37218. X      /***** 3d transform only parameters in this section *****/
  37219. X      if(display3d == 2)
  37220. X         put_parm( " 3d=overlay");
  37221. X      else
  37222. X      put_parm( " 3d=yes");
  37223. X      if (loaded3d == 0)
  37224. X     put_filename("filename",readname);
  37225. X      if (SPHERE) {
  37226. X     put_parm( " sphere=y");
  37227. X     put_parm( " latitude=%d/%d", THETA1, THETA2);
  37228. X     put_parm( " longitude=%d/%d", PHI1, PHI2);
  37229. X     put_parm( " radius=%d", RADIUS);
  37230. X     }
  37231. X      put_parm( " scalexyz=%d/%d", XSCALE, YSCALE);
  37232. X      put_parm( " roughness=%d", ROUGH);
  37233. X      put_parm( " waterline=%d", WATERLINE);
  37234. X      if (FILLTYPE)
  37235. X     put_parm( " filltype=%d", FILLTYPE);
  37236. X      if (transparent[0] || transparent[1])
  37237. X     put_parm( " transparent=%d/%d", transparent[0],transparent[1]);
  37238. X      if (preview) {
  37239. X     put_parm( " preview=y");
  37240. X     if (showbox)
  37241. X        put_parm( " showbox=y");
  37242. X     put_parm( " coarse=%d",previewfactor);
  37243. X     }
  37244. X      if (RAY) {
  37245. X     put_parm( " ray=%d",RAY);
  37246. X     if (BRIEF)
  37247. X        put_parm(" brief=y");
  37248. X     }
  37249. X      if (FILLTYPE > 4) {
  37250. X     put_parm( " lightsource=%d/%d/%d", XLIGHT, YLIGHT, ZLIGHT);
  37251. X     if (LIGHTAVG)
  37252. X        put_parm( " smoothing=%d", LIGHTAVG);
  37253. X     }
  37254. X      if (RANDOMIZE)
  37255. X     put_parm( " randomize=%d",RANDOMIZE);
  37256. X
  37257. X      if (Targa_Out)
  37258. X     put_parm( " fullcolor=y");
  37259. X      if (Ambient)
  37260. X     put_parm( " ambient=%d",Ambient);
  37261. X      if (haze)
  37262. X     put_parm( " haze=%d",haze);
  37263. X      }
  37264. X
  37265. X   if (display3d) {        /* universal 3d */
  37266. X      /***** common (fractal & transform) 3d parameters in this section *****/
  37267. X      if (!SPHERE || display3d < 0)
  37268. X     put_parm( " rotation=%d/%d/%d", XROT, YROT, ZROT);
  37269. X      put_parm( " perspective=%d", ZVIEWER);
  37270. X      put_parm( " xyshift=%d/%d", XSHIFT, YSHIFT);
  37271. X      if(xtrans || ytrans)
  37272. X     put_parm( " xyadjust=%d/%d",xtrans,ytrans);
  37273. X      if(glassestype) {
  37274. X     put_parm( " stereo=%d",glassestype);
  37275. X     put_parm( " interocular=%d",eyeseparation);
  37276. X     put_parm( " converge=%d",xadjust);
  37277. X     put_parm( " crop=%d/%d/%d/%d",
  37278. X         red_crop_left,red_crop_right,blue_crop_left,blue_crop_right);
  37279. X     put_parm( " bright=%d/%d",
  37280. X         red_bright,blue_bright);
  37281. X     }
  37282. X      }
  37283. X
  37284. X   /***** universal parameters in this section *****/
  37285. X
  37286. X   if(viewwindow == 1)
  37287. X   {
  37288. X      put_parm(" viewwindows=%g/%g",viewreduction,finalaspectratio);
  37289. X      if(viewcrop)
  37290. X         put_parm("/yes");
  37291. X      else
  37292. X         put_parm("/no");
  37293. X      put_parm("/%d/%d",viewxdots,viewydots);
  37294. X   }
  37295. X   if (*colorinf != 'n') {
  37296. X      put_parm(" colors=");
  37297. X      if (*colorinf == '@')
  37298. X     put_parm(colorinf);
  37299. X      else {
  37300. X     int curc,scanc,force,diffmag;
  37301. X     int delta,diff1[4][3],diff2[4][3];
  37302. X     curc = force = 0;
  37303. X     while (1) {
  37304. X        /* emit color in rgb 3 char encoded form */
  37305. X        for (j = 0; j < 3; ++j) {
  37306. X           if ((k = dacbox[curc][j]) < 10) k += '0';
  37307. X           else if (k < 36)            k += ('A' - 10);
  37308. X           else                   k += ('_' - 36);
  37309. X           buf[j] = k;
  37310. X           }
  37311. X        buf[3] = 0;
  37312. X        put_parm(buf);
  37313. X        if (++curc >= maxcolor)     /* quit if done last color */
  37314. X           break;
  37315. X        /* Next a P Branderhorst special, a tricky scan for smooth-shaded
  37316. X           ranges which can be written as <nn> to compress .par file entry.
  37317. X           Method used is to check net change in each color value over
  37318. X           spans of 2 to 5 color numbers.  First time for each span size
  37319. X           the value change is noted.  After first time the change is
  37320. X           checked against noted change.  First time it differs, a
  37321. X           a difference of 1 is tolerated and noted as an alternate
  37322. X           acceptable change.  When change is not one of the tolerated
  37323. X           values, loop exits. */
  37324. X        if (force) {
  37325. X           --force;
  37326. X           continue;
  37327. X           }
  37328. X        scanc = curc;
  37329. X        while (scanc < maxcolor) {     /* scan while same diff to next */
  37330. X           if ((i = scanc - curc) > 3) /* check spans up to 4 steps */
  37331. X          i = 3;
  37332. X           for (k = 0; k <= i; ++k) {
  37333. X          for (j = 0; j < 3; ++j) { /* check pattern of chg per color */
  37334. X             delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j];
  37335. X             if (k == scanc - curc)
  37336. X            diff1[k][j] = diff2[k][j] = delta;
  37337. X             else
  37338. X            if (delta != diff1[k][j] && delta != diff2[k][j]) {
  37339. X               diffmag = abs(delta - diff1[k][j]);
  37340. X               if (diff1[k][j] != diff2[k][j] || diffmag != 1)
  37341. X                  break;
  37342. X               diff2[k][j] = delta;
  37343. X               }
  37344. X             }
  37345. X          if (j < 3) break; /* must've exited from inner loop above */
  37346. X          }
  37347. X           if (k <= i) break;   /* must've exited from inner loop above */
  37348. X           ++scanc;
  37349. X           }
  37350. X        /* now scanc-1 is next color which must be written explicitly */
  37351. X        if (scanc - curc > 2) { /* good, we have a shaded range */
  37352. X           if (scanc != maxcolor) {
  37353. X          if (diffmag < 3) {  /* not a sharp slope change? */
  37354. X             force = 2;       /* force more between ranges, to stop  */
  37355. X             --scanc;          /* "drift" when load/store/load/store/ */
  37356. X             }
  37357. X          if (k) {          /* more of the same             */
  37358. X             force += k;
  37359. X             --scanc;
  37360. X             }
  37361. X          }
  37362. X           if (--scanc - curc > 1) {
  37363. X          put_parm("<%d>",scanc-curc);
  37364. X          curc = scanc;
  37365. X          }
  37366. X           else           /* changed our mind */
  37367. X          force = 0;
  37368. X           }
  37369. X        }
  37370. X     }
  37371. X      }
  37372. X
  37373. X   if (rotate_lo != 1 || rotate_hi != 255)
  37374. X      put_parm( " cyclerange=%d/%d",rotate_lo,rotate_hi);
  37375. X
  37376. X   while (wbdata->len) /* flush the buffer */
  37377. X      put_parm_line();
  37378. X}
  37379. X
  37380. Xstatic void put_filename(char *keyword,char *fname)
  37381. X{
  37382. X   char *p;
  37383. X   if (*fname && !endswithslash(fname)) {
  37384. X      if ((p = strrchr(fname, SLASHC)))
  37385. X     if (*(fname = p+1) == 0) return;
  37386. X      put_parm(" %s=%s",keyword,fname);
  37387. X      }
  37388. X}
  37389. X
  37390. X#ifndef XFRACT
  37391. Xstatic void put_parm(char *parm,...)
  37392. X#else
  37393. Xstatic void put_parm(va_alist)
  37394. Xva_dcl
  37395. X#endif
  37396. X{
  37397. X   char *bufptr;
  37398. X   va_list args;
  37399. X
  37400. X#ifndef XFRACT
  37401. X   va_start(args,parm);
  37402. X#else
  37403. X   char * parm;
  37404. X
  37405. X   va_start(args);
  37406. X   parm = va_arg(args,char *);
  37407. X#endif
  37408. X   if (*parm == ' '             /* starting a new parm */
  37409. X     && wbdata->len == 0)    /* skip leading space */
  37410. X      ++parm;
  37411. X   bufptr = wbdata->buf + wbdata->len;
  37412. X   vsprintf(bufptr,parm,args);
  37413. X   while (*(bufptr++))
  37414. X      ++wbdata->len;
  37415. X   while (wbdata->len > 200)
  37416. X      put_parm_line();
  37417. X}
  37418. X
  37419. X#define NICELINELEN 68
  37420. X#define MAXLINELEN  72
  37421. X
  37422. Xstatic void put_parm_line()
  37423. X{
  37424. X   int len,c;
  37425. X   if ((len = wbdata->len) > NICELINELEN) {
  37426. X      len = NICELINELEN+1;
  37427. X      while (--len != 0 && wbdata->buf[len] != ' ') { }
  37428. X      if (len == 0) {
  37429. X     len = NICELINELEN-1;
  37430. X     while (++len < MAXLINELEN
  37431. X       && wbdata->buf[len] && wbdata->buf[len] != ' ') { }
  37432. X     }
  37433. X      }
  37434. X   c = wbdata->buf[len];
  37435. X   wbdata->buf[len] = 0;
  37436. X   fputs("  ",parmfile);
  37437. X   fputs(wbdata->buf,parmfile);
  37438. X   if (c && c != ' ')
  37439. X      fputc('\\',parmfile);
  37440. X   fputc('\n',parmfile);
  37441. X   if ((wbdata->buf[len] = c) == ' ')
  37442. X      ++len;
  37443. X   wbdata->len -= len;
  37444. X   strcpy(wbdata->buf,wbdata->buf+len);
  37445. X}
  37446. X
  37447. Xstatic int getprec(double a,double b,double c)
  37448. X{
  37449. X   double diff,temp;
  37450. X   int digits;
  37451. X   double highv = 1.0E20;
  37452. X   if ((diff = fabs(a - b)) == 0.0) diff = highv;
  37453. X   if ((temp = fabs(a - c)) == 0.0) temp = highv;
  37454. X   if (temp < diff) diff = temp;
  37455. X   if ((temp = fabs(b - c)) == 0.0) temp = highv;
  37456. X   if (temp < diff) diff = temp;
  37457. X   digits = 7;
  37458. X   if(debugflag >= 700 && debugflag < 720 )
  37459. X      digits =  debugflag - 700;
  37460. X   while (diff < 1.0 && digits < 17) {
  37461. X      diff *= 10;
  37462. X      ++digits;
  37463. X      }
  37464. X   return(digits);
  37465. X}
  37466. X
  37467. Xstatic void put_float(int slash,double fnum,int prec)
  37468. X{  char buf[40];
  37469. X   char *bptr, *dptr;
  37470. X   bptr = buf;
  37471. X   if (slash)
  37472. X      *(bptr++) = '/';
  37473. X/*   sprintf(bptr,"%1.*f",prec,fnum); */
  37474. X#ifndef XFRACT
  37475. X     sprintf(bptr,"%1.*Lg",prec,(long double)fnum);
  37476. X#else
  37477. X     sprintf(bptr,"%1.*g",prec,(double)fnum);
  37478. X#endif
  37479. X
  37480. X   if ((dptr = strchr(bptr,'.'))) {
  37481. X      ++dptr;
  37482. X      bptr = buf + strlen(buf);
  37483. X      while (--bptr > dptr && *bptr == '0')
  37484. X     *bptr = 0;
  37485. X      }
  37486. X   put_parm(buf);
  37487. X}
  37488. X
  37489. X#ifndef XFRACT
  37490. Xvoid shell_to_dos()
  37491. X{
  37492. X   char *comspec;
  37493. X   /* from fractint.c & calls no ovlys, doesn't need ENTER_OVLY */
  37494. X   if ((comspec = getenv("COMSPEC")) == NULL)
  37495. X      printf("Cannot find COMMAND.COM.\n");
  37496. X   else {
  37497. X      putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g");
  37498. X      spawnl(P_WAIT, comspec, NULL);
  37499. X      }
  37500. X}
  37501. X#endif
  37502. X
  37503. X
  37504. Xvoid showfreemem()
  37505. X{
  37506. X#ifndef XFRACT
  37507. X   extern int num_adapters;
  37508. X   extern char *adapters[];
  37509. X   char *tempptr;
  37510. X   BYTE huge *fartempptr;
  37511. X   unsigned i,i2;
  37512. X   long j,j2;
  37513. X
  37514. X   extern char supervga_list;    /* from the list in VIDEO.ASM */
  37515. X   char adapter_name[8];      /* entry lenth from VIDEO.ASM */
  37516. X   char *adapter_ptr;
  37517. X
  37518. X   ENTER_OVLY(OVLY_MISCOVL);
  37519. X   printf("\n CPU type: %d  FPU type: %d  IIT FPU: %d  Video: %d",
  37520. X      cpu, fpu, iit, video_type);
  37521. X         
  37522. X   adapter_ptr = &supervga_list;
  37523. X   
  37524. X   for(i = 0 ; ; i++) {        /* find the SuperVGA entry */
  37525. X       int j;
  37526. X       memcpy(adapter_name , adapter_ptr, 8);
  37527. X       adapter_ptr += 8;
  37528. X       if (adapter_name[0] == ' ') break;    /* end-of-the-list */
  37529. X       if (adapter_name[6] == 0) continue;    /* not our adapter */
  37530. X       adapter_name[6] = ' ';
  37531. X       for (j = 0; j < 8; j++)
  37532. X           if(adapter_name[j] == ' ')
  37533. X               adapter_name[j] = 0;
  37534. X       printf("  Video chip: %d (%s)",i+1,adapter_name);
  37535. X       }
  37536. X   printf("\n\n");
  37537. X
  37538. X   i = j = 0;
  37539. X   i2 = 0x8000;
  37540. X   while ((i2 >>= 1) != 0)
  37541. X      if ((tempptr = malloc(i+i2)) != NULL) {
  37542. X     free(tempptr);
  37543. X     i += i2;
  37544. X     }
  37545. X   printf(" %d NEAR bytes free \n", i);
  37546. X   j2 = 0x80000;
  37547. X   while ((j2 >>= 1) != 0)
  37548. X      if ((fartempptr = (BYTE huge *)farmemalloc(j+j2)) != NULL) {
  37549. X     farmemfree((void far*)fartempptr);
  37550. X     j += j2;
  37551. X     }
  37552. X   printf(" %ld FAR bytes free \n\n press any key to continue...\n", j);
  37553. X   getakey();
  37554. X   EXIT_OVLY;
  37555. X#endif
  37556. X}
  37557. X
  37558. X
  37559. Xedit_text_colors()
  37560. X{
  37561. X   extern int debugflag;
  37562. X   extern int lookatmouse;
  37563. X   int save_debugflag,save_lookatmouse;
  37564. X   int row,col,bkgrd;
  37565. X   int rowf,colf,rowt,colt;
  37566. X   char far *vidmem;
  37567. X   char far *savescreen;
  37568. X   char far *farp1; char far *farp2;
  37569. X   int i,j,k;
  37570. X   ENTER_OVLY(OVLY_MISCOVL);
  37571. X   save_debugflag = debugflag;
  37572. X   save_lookatmouse = lookatmouse;
  37573. X   debugflag = 0;   /* don't get called recursively */
  37574. X   lookatmouse = 2; /* text mouse sensitivity */
  37575. X   row = col = bkgrd = rowt = rowf = colt = colf = 0;
  37576. X   vidmem = MK_FP(0xB800,0);
  37577. X   while (1) {
  37578. X      if (row < 0)  row = 0;
  37579. X      if (row > 24) row = 24;
  37580. X      if (col < 0)  col = 0;
  37581. X      if (col > 79) col = 79;
  37582. X      movecursor(row,col);
  37583. X      i = getakey();
  37584. X      if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */
  37585. X      switch (i) {
  37586. X     case 27: /* esc */
  37587. X        debugflag = save_debugflag;
  37588. X        lookatmouse = save_lookatmouse;
  37589. X        movecursor(25,80);
  37590. X        EXIT_OVLY;
  37591. X        return 0;
  37592. X     case '/':
  37593. X        farp1 = savescreen = farmemalloc(4000L);
  37594. X        farp2 = vidmem;
  37595. X        for (i = 0; i < 4000; ++i) { /* save and blank */
  37596. X           *(farp1++) = *farp2;
  37597. X           *(farp2++) = 0;
  37598. X           }
  37599. X        for (i = 0; i < 8; ++i)      /* 8 bkgrd attrs */
  37600. X           for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */
  37601. X          k = i*16 + j;
  37602. X          farp1 = vidmem + i*320 + j*10;
  37603. X          *(farp1++) = ' '; *(farp1++) = k;
  37604. X          *(farp1++) = i+'0'; *(farp1++) = k;
  37605. X          *(farp1++) = (j < 10) ? j+'0' : j+'A'-10; *(farp1++) = k;
  37606. X          *(farp1++) = ' '; *(farp1++) = k;
  37607. X          }
  37608. X        getakey();
  37609. X        farp1 = vidmem;
  37610. X        farp2 = savescreen;
  37611. X        for (i = 0; i < 4000; ++i) /* restore */
  37612. X           *(farp1++) = *(farp2++);
  37613. X        farmemfree(savescreen);
  37614. X        break;
  37615. X     case ',':
  37616. X        rowf = row; colf = col; break;
  37617. X     case '.':
  37618. X        rowt = row; colt = col; break;
  37619. X     case ' ': /* next color is background */
  37620. X        bkgrd = 1; break;
  37621. X     case 1075: /* cursor left  */
  37622. X        --col; break;
  37623. X     case 1077: /* cursor right */
  37624. X        ++col; break;
  37625. X     case 1072: /* cursor up    */
  37626. X        --row; break;
  37627. X     case 1080: /* cursor down  */
  37628. X        ++row; break;
  37629. X     case 13:   /* enter */
  37630. X        *(vidmem + row*160 + col*2) = getakey();
  37631. X        break;
  37632. X     default:
  37633. X        if (i >= '0' && i <= '9')      i -= '0';
  37634. X        else if (i >= 'A' && i <= 'F') i -= 'A'-10;
  37635. X        else break;
  37636. X        for (j = rowf; j <= rowt; ++j)
  37637. X           for (k = colf; k <= colt; ++k) {
  37638. X          farp1 = vidmem + j*160 + k*2 + 1;
  37639. X          if (bkgrd) *farp1 = (*farp1 & 15) + i * 16;
  37640. X          else         *farp1 = (*farp1 & 0xf0) + i;
  37641. X          }
  37642. X        bkgrd = 0;
  37643. X     }
  37644. X      }
  37645. X}
  37646. X
  37647. X
  37648. Xextern int badconfig;
  37649. Xextern struct videoinfo far videotable[];
  37650. Xextern struct videoinfo far *vidtbl;
  37651. Xextern int vidtbllen;
  37652. Xextern int tabmode;
  37653. Xextern int adapter;
  37654. Xstatic int *entsptr;
  37655. Xstatic int modes_changed;
  37656. Xextern int mode7text;
  37657. X
  37658. Xint select_video_mode(int curmode)
  37659. X{
  37660. X   static char far hdg2[]={"key...name......................xdot.ydot.colr.comment.................."};
  37661. X   static char far hdg1[]={"Select Video Mode"};
  37662. X   int entnums[MAXVIDEOMODES];
  37663. X   int attributes[MAXVIDEOMODES];
  37664. X   int i,j,k,ret;
  37665. X   int oldtabmode,oldhelpmode;
  37666. X
  37667. X   ENTER_OVLY(OVLY_MISCOVL);
  37668. X
  37669. X   load_fractint_cfg(0);    /* load fractint.cfg to extraseg */
  37670. X
  37671. X   for (i = 0; i < vidtbllen; ++i) { /* init tables */
  37672. X      entnums[i] = i;
  37673. X      attributes[i] = 1;
  37674. X      }
  37675. X   entsptr = entnums;        /* for indirectly called subroutines */
  37676. X
  37677. X   qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */
  37678. X
  37679. X   /* pick default mode */
  37680. X   if (curmode < 0) {
  37681. X      switch (video_type) { /* set up a reasonable default (we hope) */
  37682. X     case 1:  videoentry.videomodeax = 8;    /* hgc */
  37683. X          videoentry.colors = 2;
  37684. X          break;
  37685. X     case 2:  videoentry.videomodeax = 4;    /* cga */
  37686. X          videoentry.colors = 4;
  37687. X          break;
  37688. X     case 3:  videoentry.videomodeax = 16;    /* ega */
  37689. X          videoentry.colors = 16;
  37690. X          if (mode7text) {        /* egamono */
  37691. X             videoentry.videomodeax = 15;
  37692. X             videoentry.colors = 2;
  37693. X             }
  37694. X          break;
  37695. X     default: videoentry.videomodeax = 19;    /* mcga/vga? */
  37696. X          videoentry.colors = 256;
  37697. X          break;
  37698. X     }
  37699. X      }
  37700. X   else
  37701. X      far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode],
  37702. X         sizeof(videoentry));
  37703. X#ifndef XFRACT
  37704. X   for (i = 0; i < vidtbllen; ++i) { /* find default mode */
  37705. X      if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax
  37706. X    && videoentry.colors      == vidtbl[entnums[i]].colors
  37707. X    && (curmode < 0
  37708. X        || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]],
  37709. X              sizeof(videoentry)) == 0))
  37710. X     break;
  37711. X      }
  37712. X   if (i >= vidtbllen) /* no match, default to first entry */
  37713. X      i = 0;
  37714. X
  37715. X   oldtabmode = tabmode;
  37716. X   oldhelpmode = helpmode;
  37717. X   modes_changed = 0;
  37718. X   tabmode = 0;
  37719. X   helpmode = HELPVIDSEL;
  37720. X   i = fullscreen_choice(CHOICEHELP,hdg1,hdg2,NULL,vidtbllen,NULL,attributes,
  37721. X                         1,16,72,i,format_item,NULL,NULL,check_modekey);
  37722. X   tabmode = oldtabmode;
  37723. X   helpmode = oldhelpmode;
  37724. X   if (i == -1) {
  37725. X   static char far msg[]={"Save new function key assignments or cancel changes?"};
  37726. X      if (modes_changed /* update fractint.cfg for new key assignments */
  37727. X    && badconfig == 0
  37728. X    && stopmsg(22,msg) == 0)
  37729. X     update_fractint_cfg();
  37730. X      EXIT_OVLY;
  37731. X      return(-1);
  37732. X      }
  37733. X   if (i < 0)    /* picked by function key */
  37734. X      i = -1 - i;
  37735. X   else     /* picked by Enter key */
  37736. X      i = entnums[i];
  37737. X#endif
  37738. X   far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
  37739. X          sizeof(videoentry));  /* the selected entry now in videoentry */
  37740. X
  37741. X#ifndef XFRACT
  37742. X   /* copy fractint.cfg table to resident table, note selected entry */
  37743. X   j = k = 0;
  37744. X   far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
  37745. X   for (i = 0; i < vidtbllen; ++i) {
  37746. X      if (vidtbl[i].keynum > 0) {
  37747. X     far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i],
  37748. X            sizeof(*vidtbl));
  37749. X     if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i],
  37750. X            sizeof(videoentry)) == 0)
  37751. X        k = vidtbl[i].keynum;
  37752. X     if (++j >= MAXVIDEOTABLE-1)
  37753. X        break;
  37754. X     }
  37755. X      }
  37756. X#else
  37757. X    k = vidtbl[0].keynum;
  37758. X#endif
  37759. X   if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */
  37760. X      far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1],
  37761. X         (char far *)&videoentry,sizeof(*vidtbl));
  37762. X      ret = 1400; /* special value for check_vidmode_key */
  37763. X      }
  37764. X
  37765. X   if (modes_changed /* update fractint.cfg for new key assignments */
  37766. X     && badconfig == 0)
  37767. X      update_fractint_cfg();
  37768. X
  37769. X   EXIT_OVLY;
  37770. X   return(ret);
  37771. X}
  37772. X
  37773. Xstatic void format_item(int choice,char *buf)
  37774. X{
  37775. X   char kname[5];
  37776. X   char biosflag;
  37777. X   far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]],
  37778. X          sizeof(videoentry));
  37779. X   vidmode_keyname(videoentry.keynum,kname);
  37780. X   biosflag = (videoentry.dotmode % 100 == 1) ? 'B' : ' ';
  37781. X   sprintf(buf,"%-5s %-25s %4d %4d %3d%c %-25s",  /* 72 chars */
  37782. X       kname, videoentry.name, videoentry.xdots, videoentry.ydots,
  37783. X       videoentry.colors, biosflag, videoentry.comment);
  37784. X}
  37785. X
  37786. Xstatic int check_modekey(int curkey,int choice)
  37787. X{
  37788. X   int i,j,k,ret;
  37789. X   if ((i = check_vidmode_key(1,curkey)) >= 0)
  37790. X      return(-1-i);
  37791. X   i = entsptr[choice];
  37792. X   ret = 0;
  37793. X   if ( (curkey == '-' || curkey == '+')
  37794. X     && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) {
  37795. X      static char far msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."};
  37796. X      if (badconfig)
  37797. X     stopmsg(0,msg);
  37798. X      else {
  37799. X     if (curkey == '-') {                   /* deassign key? */
  37800. X        if (vidtbl[i].keynum >= 1084) {
  37801. X           vidtbl[i].keynum = 0;
  37802. X           modes_changed = 1;
  37803. X           }
  37804. X        }
  37805. X     else {                 /* assign key? */
  37806. X        j = getakeynohelp();
  37807. X        if (j >= 1084 && j <= 1113) {
  37808. X           for (k = 0; k < vidtbllen; ++k) {
  37809. X          if (vidtbl[k].keynum == j) {
  37810. X             vidtbl[k].keynum = 0;
  37811. X             ret = -1; /* force redisplay */
  37812. X             }
  37813. X          }
  37814. X           vidtbl[i].keynum = j;
  37815. X           modes_changed = 1;
  37816. X           }
  37817. X        }
  37818. X     }
  37819. X      }
  37820. X   return(ret);
  37821. X}
  37822. X
  37823. Xstatic int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2)
  37824. X{
  37825. X   int i,j;
  37826. X   if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999;
  37827. X   if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999;
  37828. X   if (i < j || (i == j && *((int *)p1) < *((int *)p2)))
  37829. X      return(-1);
  37830. X   return(1);
  37831. X}
  37832. X
  37833. Xstatic void update_fractint_cfg()
  37834. X{
  37835. X#ifndef XFRACT
  37836. X   char cfgname[100],outname[100],buf[121],kname[5];
  37837. X   FILE *cfgfile,*outfile;
  37838. X   int far *cfglinenums;
  37839. X   int i,j,linenum,nextlinenum,nextmode;
  37840. X   struct videoinfo vident;
  37841. X
  37842. X   findpath("fractint.cfg",cfgname);
  37843. X
  37844. X   if (access(cfgname,6)) {
  37845. X      sprintf(buf,s_cantwrite,cfgname);
  37846. X      stopmsg(0,buf);
  37847. X      return;
  37848. X      }
  37849. X   strcpy(outname,cfgname);
  37850. X   i = strlen(outname);
  37851. X   while (--i >= 0 && outname[i] != SLASHC)
  37852. X   outname[i] = 0;
  37853. X   strcat(outname,"fractint.tmp");
  37854. X   if ((outfile = fopen(outname,"w")) == NULL) {
  37855. X      sprintf(buf,s_cantcreate,outname);
  37856. X      stopmsg(0,buf);
  37857. X      return;
  37858. X      }
  37859. X   cfgfile = fopen(cfgname,"r");
  37860. X
  37861. X   cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);
  37862. X   linenum = nextmode = 0;
  37863. X   nextlinenum = cfglinenums[0];
  37864. X   while (fgets(buf,120,cfgfile)) {
  37865. X      ++linenum;
  37866. X      if (linenum == nextlinenum) { /* replace this line */
  37867. X     far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode],
  37868. X            sizeof(videoentry));
  37869. X     vidmode_keyname(vident.keynum,kname);
  37870. X     strcpy(buf,vident.name);
  37871. X     i = strlen(buf);
  37872. X     while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */
  37873. X        --i;
  37874. X     j = i + 5;
  37875. X     while (j < 32) {        /* tab to column 33 */
  37876. X        buf[i++] = '\t';
  37877. X        j += 8;
  37878. X        }
  37879. X     buf[i] = 0;
  37880. X     fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%4d,%4d,%3d,%s\n",
  37881. X        kname,
  37882. X        buf,
  37883. X        vident.videomodeax,
  37884. X        vident.videomodebx,
  37885. X        vident.videomodecx,
  37886. X        vident.videomodedx,
  37887. X        vident.dotmode,
  37888. X        vident.xdots,
  37889. X        vident.ydots,
  37890. X        vident.colors,
  37891. X        vident.comment);
  37892. X     if (++nextmode >= vidtbllen)
  37893. X        nextlinenum = 32767;
  37894. X     else
  37895. X        nextlinenum = cfglinenums[nextmode];
  37896. X     }
  37897. X      else
  37898. X     fputs(buf,outfile);
  37899. X      }
  37900. X
  37901. X   fclose(cfgfile);
  37902. X   fclose(outfile);
  37903. X   unlink(cfgname);        /* success assumed on these lines        */
  37904. X   rename(outname,cfgname); /* since we checked earlier with access */
  37905. X#endif
  37906. X}
  37907. X
  37908. Xextern unsigned char olddacbox[256][3];
  37909. Xextern int gif87a_flag;
  37910. X
  37911. X/* make_mig() takes a collection of individual GIF images (all
  37912. X   presumably the same resolution and all presumably generated
  37913. X   by Fractint and its "divide and conquer" algorithm) and builds
  37914. X   a single multiple-image GIF out of them.  This routine is
  37915. X   invoked by the "batch=stitchmode/x/y" option, and is called
  37916. X   with the 'x' and 'y' parameters
  37917. X*/
  37918. X
  37919. Xmake_mig(unsigned int xmult, unsigned int ymult)
  37920. X{
  37921. Xunsigned int xstep, ystep;
  37922. Xunsigned int xres, yres;
  37923. Xunsigned int allxres, allyres, xtot, ytot;
  37924. Xunsigned int xloc, yloc;
  37925. Xunsigned int x, y;
  37926. Xunsigned char ichar;
  37927. Xunsigned int allitbl, itbl;
  37928. Xunsigned int i, j, k;
  37929. Xchar gifin[15], gifout[15];
  37930. Xint errorflag, inputerrorflag;
  37931. Xunsigned char *temp;
  37932. XFILE *out, *in;
  37933. Xchar msgbuf[81];
  37934. X
  37935. Xerrorflag = 0;                /* no errors so far */
  37936. X
  37937. Xstrcpy(gifout,"fractmig.gif");
  37938. X
  37939. Xtemp= &olddacbox[0][0];            /* a safe place for our temp data */
  37940. X
  37941. Xgif87a_flag = 1;            /* for now, force this */
  37942. X
  37943. X/* process each input image, one at a time */
  37944. Xfor (ystep = 0; ystep < ymult; ystep++) {
  37945. X    for (xstep = 0; xstep < xmult; xstep++) {
  37946. X
  37947. Xif (xstep == 0 && ystep == 0) {        /* first time through? */
  37948. X    static char far msg1[] = "Cannot create output file %s!\n";
  37949. X    static char far msg2[] = " \n Generating multi-image GIF file %s using";
  37950. X    static char far msg3[] = " %d X and %d Y components\n\n";
  37951. X    _fstrcpy(msgbuf, msg2);
  37952. X    printf(msgbuf, gifout);
  37953. X    _fstrcpy(msgbuf, msg3);
  37954. X    printf(msgbuf, xmult, ymult);
  37955. X    /* attempt to create the output file */
  37956. X    if ((out = fopen(gifout,"wb")) == NULL) {
  37957. X        _fstrcpy(msgbuf, msg1);
  37958. X        printf(msgbuf, gifout);
  37959. X        exit(1);
  37960. X        }
  37961. X    }
  37962. X
  37963. X        sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep));
  37964. X
  37965. X        if ((in = fopen(gifin,"rb")) == NULL) {
  37966. X            static char far msg1[] = "Can't open file %s!\n";
  37967. X            _fstrcpy(msgbuf, msg1);
  37968. X            printf(msgbuf, gifin);
  37969. X            exit(1);
  37970. X            }
  37971. X
  37972. X        inputerrorflag = 0;
  37973. X
  37974. X        /* (read, but only copy this if it's the first time through) */
  37975. X        if (fread(temp,13,1,in) != 1)    /* read the header and LDS */
  37976. X            inputerrorflag = 1;
  37977. X        memcpy(&xres, &temp[6], 2);    /* X-resolution */
  37978. X        memcpy(&yres, &temp[8], 2);    /* Y-resolution */
  37979. X
  37980. X        if (xstep == 0 && ystep == 0) {    /* first time through? */
  37981. X            allxres = xres;        /* save the "master" resolution */
  37982. X            allyres = yres;
  37983. X            xtot = xres * xmult;    /* adjust the image size */
  37984. X            ytot = yres * ymult;
  37985. X            memcpy(&temp[6], &xtot, 2);
  37986. X            memcpy(&temp[8], &ytot, 2);
  37987. X            if (gif87a_flag) {
  37988. X                temp[3] = '8';
  37989. X                temp[4] = '7';
  37990. X                temp[5] = 'a';
  37991. X                }
  37992. X            if (fwrite(temp,13,1,out) != 1)    /* write out the header */
  37993. X                errorflag = 1;
  37994. X            }                /* end of first-time-through */
  37995. X
  37996. X
  37997. X        ichar = temp[10] & 0x07;    /* find the color table size */
  37998. X        itbl = 1 << (++ichar);
  37999. X        ichar = temp[10] & 0x80;    /* is there a global color table? */
  38000. X        if (xstep == 0 && ystep == 0)    /* first time through? */
  38001. X            allitbl = itbl;        /* save the color table size */
  38002. X        if (ichar != 0) {        /* yup */
  38003. X            /* (read, but only copy this if it's the first time through) */
  38004. X            if(fread(temp,3*itbl,1,in) != 1)    /* read the global color table */
  38005. X                inputerrorflag = 2;
  38006. X            if (xstep == 0 && ystep == 0)    /* first time through? */
  38007. X                if (fwrite(temp,3*itbl,1,out) != 1)    /* write out the GCT */
  38008. X                    errorflag = 2;
  38009. X            }
  38010. X
  38011. X        if (xres != allxres || yres != allyres || itbl != allitbl) {
  38012. X            /* Oops - our pieces don't match */
  38013. X            static char far msg1[] = "File %s doesn't have the same resolution as its predecessors!\n";
  38014. X            _fstrcpy(msgbuf, msg1);
  38015. X            printf(msgbuf, gifin);
  38016. X            exit(1);
  38017. X            }
  38018. X
  38019. X        for (;;) {            /* process each information block */
  38020. X        if (fread(temp,1,1,in) != 1)    /* read the block identifier */
  38021. X            inputerrorflag = 3;
  38022. X
  38023. X        if (temp[0] == 0x2c) {        /* image descriptor block */
  38024. X            if (fread(&temp[1],9,1,in) != 1)    /* read the Image Descriptor */
  38025. X                inputerrorflag = 4;
  38026. X            memcpy(&xloc, &temp[1], 2);    /* X-location */
  38027. X            memcpy(&yloc, &temp[3], 2);    /* Y-location */
  38028. X            xloc += (xstep * xres);    /* adjust the locations */
  38029. X            yloc += (ystep * yres);
  38030. X            memcpy(&temp[1], &xloc, 2);
  38031. X            memcpy(&temp[3], &yloc, 2);
  38032. X            if (fwrite(temp,10,1,out) != 1)    /* write out the Image Descriptor */
  38033. X                errorflag = 4;
  38034. X
  38035. X            ichar = temp[9] & 0x80;    /* is there a local color table? */
  38036. X            if (ichar != 0) {        /* yup */
  38037. X                if (fread(temp,3*itbl,1,in) != 1)    /* read the local color table */
  38038. X                    inputerrorflag = 5;
  38039. X                if (fwrite(temp,3*itbl,1,out) != 1)    /* write out the LCT */
  38040. X                    errorflag = 5;
  38041. X                }
  38042. X
  38043. X            if (fread(temp,1,1,in) != 1)    /* LZH table size */
  38044. X                inputerrorflag = 6;
  38045. X            if (fwrite(temp,1,1,out) != 1)
  38046. X                errorflag = 6;
  38047. X            while (1) {
  38048. X                if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  38049. X                    break;
  38050. X                if (fread(temp,1,1,in) != 1)    /* block size */
  38051. X                    inputerrorflag = 7;
  38052. X                if (fwrite(temp,1,1,out) != 1)
  38053. X                    errorflag = 7;
  38054. X                if ((i = temp[0]) == 0)
  38055. X                    break;
  38056. X                if (fread(temp,i,1,in) != 1)    /* LZH data block */
  38057. X                    inputerrorflag = 8;
  38058. X                if (fwrite(temp,i,1,out) != 1)
  38059. X                    errorflag = 8;
  38060. X                }
  38061. X            }
  38062. X
  38063. X        if (temp[0] == 0x21) {        /* extension block */
  38064. X            /* (read, but only copy this if it's the last time through) */
  38065. X            if (fread(&temp[2],1,1,in) != 1)    /* read the block type */
  38066. X                inputerrorflag = 9;
  38067. X            if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
  38068. X                if (fwrite(temp,2,1,out) != 1)
  38069. X                    errorflag = 9;
  38070. X            while (1) {
  38071. X                if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  38072. X                    break;
  38073. X                if (fread(temp,1,1,in) != 1)    /* block size */
  38074. X                    inputerrorflag = 10;
  38075. X                if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
  38076. X                    if (fwrite(temp,1,1,out) != 1)
  38077. X                        errorflag = 10;
  38078. X                if ((i = temp[0]) == 0)
  38079. X                    break;
  38080. X                if (fread(temp,i,1,in) != 1)    /* data block */
  38081. X                    inputerrorflag = 11;
  38082. X                if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
  38083. X                    if (fwrite(temp,i,1,out) != 1)
  38084. X                        errorflag = 11;
  38085. X                }
  38086. X            }
  38087. X
  38088. X        if (temp[0] == 0x3b) {        /* end-of-stream indicator */
  38089. X            break;            /* done with this file */
  38090. X            }
  38091. X
  38092. X        if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  38093. X            break;
  38094. X
  38095. X        }
  38096. X        fclose(in);            /* done with an input GIF */
  38097. X
  38098. X        if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  38099. X            break;
  38100. X        }
  38101. X
  38102. X    if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  38103. X        break;
  38104. X    }
  38105. X
  38106. Xtemp[0] = 0x3b;            /* end-of-stream indicator */
  38107. Xif (fwrite(temp,1,1,out) != 1)
  38108. X    errorflag = 12;
  38109. Xfclose(out);            /* done with the output GIF */
  38110. X
  38111. Xif (inputerrorflag != 0) {    /* uh-oh - something failed */
  38112. X    static char far msg1[] = "\007 Process failed = early EOF on input file %s\n";
  38113. X    _fstrcpy(msgbuf, msg1);
  38114. X    printf(msgbuf, gifin);
  38115. X/* following line was for debugging
  38116. X    printf("inputerrorflag = %d\n", inputerrorflag);
  38117. X*/
  38118. X    }
  38119. X
  38120. Xif (errorflag != 0) {        /* uh-oh - something failed */
  38121. X    static char far msg1[] = "\007 Process failed = out of disk space?\n";
  38122. X    _fstrcpy(msgbuf, msg1);
  38123. X    printf(msgbuf);
  38124. X/* following line was for debugging
  38125. X    printf("errorflag = %d\n", errorflag);
  38126. X*/
  38127. X    }
  38128. X
  38129. X/* now delete each input image, one at a time */
  38130. Xif (errorflag == 0 && inputerrorflag == 0)
  38131. X  for (ystep = 0; ystep < ymult; ystep++) {
  38132. X    for (xstep = 0; xstep < xmult; xstep++) {
  38133. X        sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep));
  38134. X        remove(gifin);
  38135. X        }
  38136. X    }
  38137. X
  38138. X/* tell the world we're done */
  38139. Xif (errorflag == 0 && inputerrorflag == 0) {
  38140. X    static char far msg1[] = "File %s has been created (and its component files deleted)\n";
  38141. X    _fstrcpy(msgbuf, msg1);
  38142. X    printf(msgbuf, gifout);
  38143. X    }
  38144. X}
  38145. X
  38146. X/* This routine copies the current screen to by flipping x-axis, y-axis,
  38147. X   or both. Refuses to work if calculation in progress or if fractal
  38148. X   non-resumable. Clears zoombox if any. Resets corners so resulting fractal
  38149. X   is still valid. */
  38150. Xvoid flip_image(int key)
  38151. X{
  38152. X   int i, j, ix, iy, ixhalf, iyhalf, tempdot;
  38153. X
  38154. X   ENTER_OVLY(OVLY_MISCOVL);
  38155. X   /* fractal must be rotate-able and be finished */
  38156. X   if ((curfractalspecific->flags&NOROTATE) > 0 
  38157. X       || calc_status == 1   
  38158. X       || calc_status == 2)  
  38159. X      return;
  38160. X   clear_zoombox(); /* clear, don't copy, the zoombox */
  38161. X   ixhalf = xdots / 2;  
  38162. X   iyhalf = ydots / 2;
  38163. X   switch(key)
  38164. X   {
  38165. X   case 24:            /* control-X - reverse X-axis */
  38166. X      for (i = 0; i < ixhalf; i++) 
  38167. X      {
  38168. X         if(keypressed())
  38169. X            break;
  38170. X         for (j = 0; j < ydots; j++) 
  38171. X         {
  38172. X            tempdot=getcolor(i,j);
  38173. X            putcolor(i, j, getcolor(xdots-1-i,j));
  38174. X            putcolor(xdots-1-i, j, tempdot);
  38175. X         }
  38176. X      }
  38177. X      sxmin = xxmax + xxmin - xx3rd;
  38178. X      symax = yymax + yymin - yy3rd;
  38179. X      sxmax = xx3rd;
  38180. X      symin = yy3rd;
  38181. X      sx3rd = xxmax;
  38182. X      sy3rd = yymin;
  38183. X      reset_zoom_corners();
  38184. X      calc_status = 0;
  38185. X      break;
  38186. X   case 25:            /* control-Y - reverse Y-aXis */
  38187. X      for (j = 0; j < iyhalf; j++)
  38188. X      {
  38189. X         if(keypressed())
  38190. X            break;
  38191. X         for (i = 0; i < xdots; i++) 
  38192. X         {
  38193. X            tempdot=getcolor(i,j);
  38194. X            putcolor(i, j, getcolor(i,ydots-1-j));
  38195. X            putcolor(i,ydots-1-j, tempdot);
  38196. X         }
  38197. X      }
  38198. X      sxmin = xx3rd;
  38199. X      symax = yy3rd;
  38200. X      sxmax = xxmax + xxmin - xx3rd;
  38201. X      symin = yymax + yymin - yy3rd;
  38202. X      sx3rd = xxmin;
  38203. X      sy3rd = yymax;
  38204. X      calc_status = 0;
  38205. X      break;
  38206. X   case 26:            /* control-Z - reverse X and Y aXis */
  38207. X      for (i = 0; i < ixhalf; i++) 
  38208. X      {
  38209. X         if(keypressed())
  38210. X            break;
  38211. X         for (j = 0; j < ydots; j++) 
  38212. X         {
  38213. X            tempdot=getcolor(i,j);
  38214. X            putcolor(i, j, getcolor(xdots-1-i,ydots-1-j));
  38215. X            putcolor(xdots-1-i, ydots-1-j, tempdot);
  38216. X         }
  38217. X      }
  38218. X      sxmin = xxmax;
  38219. X      symax = yymin;
  38220. X      sxmax = xxmin;
  38221. X      symin = yymax;
  38222. X      sx3rd = xxmax + xxmin - xx3rd;
  38223. X      sy3rd = yymax + yymin - yy3rd;
  38224. X      break;
  38225. X   }
  38226. X   reset_zoom_corners();
  38227. X   calc_status = 0;
  38228. X   EXIT_OVLY;
  38229. X}
  38230. X
  38231. SHAR_EOF
  38232. $TOUCH -am 1028230093 miscovl.c &&
  38233. chmod 0644 miscovl.c ||
  38234. echo "restore of miscovl.c failed"
  38235. set `wc -c miscovl.c`;Wc_c=$1
  38236. if test "$Wc_c" != "56485"; then
  38237.     echo original size 56485, current size $Wc_c
  38238. fi
  38239. # ============= miscres.c ==============
  38240. echo "x - extracting miscres.c (Text)"
  38241. sed 's/^X//' << 'SHAR_EOF' > miscres.c &&
  38242. X/*
  38243. X    Resident odds and ends that don't fit anywhere else.
  38244. X*/
  38245. X
  38246. X#include <string.h>
  38247. X#include <stdlib.h>
  38248. X#include <stdio.h>
  38249. X#include <ctype.h>
  38250. X#include <time.h>
  38251. X#ifndef XFRACT
  38252. X#include <stdarg.h>
  38253. X#include <io.h>
  38254. X#else
  38255. X#include <varargs.h>
  38256. X#endif
  38257. X#include <math.h>
  38258. X#ifdef __TURBOC__
  38259. X#include <dir.h>
  38260. X#endif
  38261. X
  38262. X#include "fractint.h"
  38263. X#include "fractype.h"
  38264. X#include "helpdefs.h"
  38265. X#include "prototyp.h"
  38266. X
  38267. X/* routines in this module    */
  38268. X
  38269. Xstatic    void trigdetails(char *);
  38270. Xstatic void area();
  38271. X
  38272. Xint active_ovly = -1;
  38273. X
  38274. Xextern char IFSFileName[80];
  38275. Xextern char IFSName[40];
  38276. Xextern float far *ifs_defn;
  38277. Xextern int  ifs_changed;
  38278. Xextern int  ifs_type;
  38279. Xextern int neworbittype;
  38280. Xextern char temp[], temp1[256];   /* temporary strings          */
  38281. X
  38282. Xextern int  active_ovly;
  38283. Xextern int  xdots, ydots;
  38284. Xextern int  dotmode;
  38285. Xextern int  show_orbit;
  38286. Xextern int  debugflag;
  38287. Xextern int  maxit;
  38288. Xextern int  fractype;
  38289. Xextern int  got_status,curpass,totpasses,currow,curcol;
  38290. Xextern int  fileydots;
  38291. Xextern int  xxstart,xxstop,yystart,yystop;
  38292. Xextern int  display3d;
  38293. Xextern char overwrite;
  38294. Xextern int  inside;
  38295. Xextern int  outside;
  38296. Xextern double xxmax,xxmin,yymax,yymin,xx3rd,yy3rd;
  38297. X
  38298. X
  38299. X/* TW's static string consolidation campaign to help brain-dead compilers */
  38300. Xchar s_cantopen[]       = {"Can't open %s"};
  38301. Xchar s_cantwrite[]      = {"Can't write %s"};
  38302. Xchar s_cantcreate[]     = {"Can't create %s"};
  38303. Xchar s_cantunderstand[] = {"Can't understand %s"};
  38304. Xchar s_cantfind[]       = {"Can't find %s"};
  38305. X
  38306. X/* call next when returning from resident routine and unsure whether
  38307. X   caller is an overlay which has been displaced */
  38308. Xvoid restore_active_ovly()
  38309. X{
  38310. X
  38311. X   switch (active_ovly) {
  38312. X      case OVLY_MISCOVL:  miscovl_overlay();  break;
  38313. X      case OVLY_CMDFILES: cmdfiles_overlay(); break;
  38314. X      case OVLY_HELP:      help_overlay();     break;
  38315. X      case OVLY_PROMPTS1: prompts1_overlay(); break;
  38316. X      case OVLY_PROMPTS2: prompts2_overlay(); break;
  38317. X      case OVLY_LOADFILE: loadfile_overlay(); break;
  38318. X      case OVLY_ROTATE:   rotate_overlay();   break;
  38319. X      case OVLY_PRINTER:  printer_overlay();  break;
  38320. X      case OVLY_LINE3D:   line3d_overlay();   break;
  38321. X      case OVLY_ENCODER:  encoder_overlay();  break;
  38322. X      case OVLY_CALCFRAC: calcfrac_overlay(); break;
  38323. X      case OVLY_INTRO:      intro_overlay();    break;
  38324. X      case OVLY_DECODER:  decoder_overlay();  break;
  38325. X      }
  38326. X}
  38327. X
  38328. X
  38329. X#ifndef XFRACT
  38330. Xextern int splitpath(char *template,char *drive,char *dir,char *fname,char *ext);
  38331. Xextern int makepath(char *template,char *drive,char *dir,char *fname,char *ext);
  38332. X
  38333. Xvoid findpath(char *filename, char *fullpathname) /* return full pathnames */
  38334. X{
  38335. X   char fname[FILE_MAX_FNAME];
  38336. X   char ext[FILE_MAX_EXT];
  38337. X   extern int first_init;
  38338. X   if (filename[0] == SLASHC || (filename[0] && filename[1] == ':')) {
  38339. X      if(access(filename,0)==0) {   /* file exists */
  38340. X         strcpy(fullpathname,filename);
  38341. X         return;
  38342. X         }
  38343. X      else {
  38344. X         splitpath(filename ,NULL,NULL,fname,ext);
  38345. X         makepath(filename,""   ,"" ,fname,ext);
  38346. X         }
  38347. X      }
  38348. X   fullpathname[0] = 0;             /* indicate none found */
  38349. X#ifdef __TURBOC__                /* look for the file */
  38350. X   strcpy(fullpathname,searchpath(filename));
  38351. X#else
  38352. X   _searchenv(filename,"PATH",fullpathname);
  38353. X#endif
  38354. X   if (fullpathname[0] != 0)            /* found it! */
  38355. X      if (strncmp(&fullpathname[2],SLASHSLASH,2) == 0) /* stupid klooge! */
  38356. X     strcpy(&fullpathname[3],filename);
  38357. X}
  38358. X#endif
  38359. X
  38360. X
  38361. Xvoid notdiskmsg()
  38362. X{
  38363. Xstatic char far sorrymsg[]={
  38364. X"This type may be slow using a real-disk based 'video' mode, but may not \n\
  38365. Xbe too bad if you have enough expanded or extended memory. Press <Esc> to \n\
  38366. Xabort if it appears that your disk drive is working too hard."};
  38367. X   stopmsg(0,sorrymsg);
  38368. X}
  38369. X
  38370. X
  38371. X/* convert corners to center/mag */
  38372. Xint cvtcentermag(double *Xctr, double *Yctr, double *Magnification)
  38373. X{
  38374. X   double Width, Height, Radius, Ratio;
  38375. X   Width  = xxmax - xxmin;
  38376. X   Height = yymax - yymin;
  38377. X   Ratio = Height / Width;
  38378. X   if(xx3rd != xxmin || yy3rd != yymin || Width < 0
  38379. X     || (Width > 1e-8 && (Ratio <= 0.74 || Ratio >= 0.76))
  38380. X     || Ratio < 0.66 || Ratio > 0.84)
  38381. X      return(0);
  38382. X   /* calculate center and magnification */
  38383. X   Radius = Height / 2.0;
  38384. X   *Xctr = xxmin + (Width / 2.0);
  38385. X   *Yctr = yymin + Radius;
  38386. X   *Magnification = 1.0 / Radius;
  38387. X   return(1);
  38388. X}
  38389. X
  38390. X
  38391. Xvoid updatesavename(char *filename) /* go to the next file name */
  38392. X{
  38393. X   char *save, *hold;
  38394. X   char name[80],suffix[80];
  38395. X   char *dotptr;
  38396. X
  38397. X   strcpy(name,filename);
  38398. X   suffix[0] = 0;
  38399. X   if ((dotptr = strrchr(name,'.')) != NULL
  38400. X     && dotptr > strrchr(name,SLASHC)) {
  38401. X      strcpy(suffix,dotptr);
  38402. X      *dotptr = 0;
  38403. X      }
  38404. X
  38405. X   hold = name + strlen(name) - 1; /* start at the end */
  38406. X   while(hold >= name && (*hold == ' ' || isdigit(*hold))) /* skip backwards */
  38407. X      hold--;
  38408. X   hold++;            /* recover first digit */
  38409. X   while (*hold == '0')         /* skip leading zeros */
  38410. X      hold++;
  38411. X   save = hold;
  38412. X   while (*save) {        /* check for all nines */
  38413. X      if (*save != '9')
  38414. X     break;
  38415. X      save++;
  38416. X      }
  38417. X   if (!*save)            /* if the whole thing is nines then back */
  38418. X      save = hold - 1;        /* up one place. Note that this will eat */
  38419. X                /* your last letter if you go to far.     */
  38420. X   else
  38421. X      save = hold;
  38422. X   sprintf(save,"%d",atoi(hold)+1); /* increment the number */
  38423. X   strcpy(filename,name);
  38424. X   strcat(filename,suffix);
  38425. X}
  38426. X
  38427. Xint check_writefile(char *name,char *ext)
  38428. X{
  38429. X /* after v16 release, change encoder.c to also use this routine */
  38430. X   char openfile[80];
  38431. X   char opentype[20];
  38432. X   int i;
  38433. Xnextname:
  38434. X   strcpy(openfile,name);
  38435. X   strcpy(opentype,ext);
  38436. X   for (i = 0; i < strlen(openfile); i++)
  38437. X      if (openfile[i] == '.') {
  38438. X     strcpy(opentype,&openfile[i]);
  38439. X     openfile[i] = 0;
  38440. X     }
  38441. X   strcat(openfile,opentype);
  38442. X   if (access(openfile,0) != 0) /* file doesn't exist */
  38443. X   {
  38444. X      strcpy(name,openfile);
  38445. X      return 0;
  38446. X    }
  38447. X   /* file already exists */
  38448. X   if (overwrite == 0) {
  38449. X      updatesavename(name);
  38450. X      goto nextname;
  38451. X      }
  38452. X   return 1;
  38453. X}
  38454. X
  38455. X/* ('check_key()' was moved to FRACTINT.C for MSC7-overlay speed purposes) */
  38456. X/* ('timer()'     was moved to FRACTINT.C for MSC7-overlay speed purposes) */
  38457. X
  38458. XBYTE trigndx[] = {SIN,SQR,SINH,COSH};
  38459. X#ifndef XFRACT
  38460. Xvoid (*ltrig0)(void) = lStkSin;
  38461. Xvoid (*ltrig1)(void) = lStkSqr;
  38462. Xvoid (*ltrig2)(void) = lStkSinh;
  38463. Xvoid (*ltrig3)(void) = lStkCosh;
  38464. Xvoid (*mtrig0)(void) = mStkSin;
  38465. Xvoid (*mtrig1)(void) = mStkSqr;
  38466. Xvoid (*mtrig2)(void) = mStkSinh;
  38467. Xvoid (*mtrig3)(void) = mStkCosh;
  38468. X#endif
  38469. Xvoid (*dtrig0)(void) = dStkSin;
  38470. Xvoid (*dtrig1)(void) = dStkSqr;
  38471. Xvoid (*dtrig2)(void) = dStkSinh;
  38472. Xvoid (*dtrig3)(void) = dStkCosh;
  38473. X
  38474. Xstruct trig_funct_lst trigfn[] =
  38475. X/* changing the order of these alters meaning of *.fra file */
  38476. X/* maximum 6 characters in function names or recheck all related code */
  38477. X{
  38478. X#ifndef XFRACT
  38479. X   {"sin",   lStkSin,   dStkSin,   mStkSin   },
  38480. X   {"cosxx", lStkCosXX, dStkCosXX, mStkCosXX },
  38481. X   {"sinh",  lStkSinh,  dStkSinh,  mStkSinh  },
  38482. X   {"cosh",  lStkCosh,  dStkCosh,  mStkCosh  },
  38483. X   {"exp",   lStkExp,   dStkExp,   mStkExp   },
  38484. X   {"log",   lStkLog,   dStkLog,   mStkLog   },
  38485. X   {"sqr",   lStkSqr,   dStkSqr,   mStkSqr   },
  38486. X   {"recip", lStkRecip, dStkRecip, mStkRecip }, /* from recip on new in v16 */
  38487. X   {"ident", StkIdent,  StkIdent,  StkIdent  },
  38488. X   {"cos",   lStkCos,   dStkCos,   mStkCos   },
  38489. X   {"tan",   lStkTan,   dStkTan,   mStkTan   },
  38490. X   {"tanh",  lStkTanh,  dStkTanh,  mStkTanh  },
  38491. X   {"cotan", lStkCoTan, dStkCoTan, mStkCoTan },
  38492. X   {"cotanh",lStkCoTanh,dStkCoTanh,mStkCoTanh},
  38493. X   {"flip",  lStkFlip,  dStkFlip,  mStkFlip  },
  38494. X   {"conj",  lStkConj,  dStkConj,  mStkConj  },
  38495. X   {"zero",  lStkZero,  dStkZero,  mStkZero  },
  38496. X#else
  38497. X   {"sin",   dStkSin,   dStkSin,   dStkSin   },
  38498. X   {"cosxx", dStkCosXX, dStkCosXX, dStkCosXX },
  38499. X   {"sinh",  dStkSinh,  dStkSinh,  dStkSinh  },
  38500. X   {"cosh",  dStkCosh,  dStkCosh,  dStkCosh  },
  38501. X   {"exp",   dStkExp,   dStkExp,   dStkExp   },
  38502. X   {"log",   dStkLog,   dStkLog,   dStkLog   },
  38503. X   {"sqr",   dStkSqr,   dStkSqr,   dStkSqr   },
  38504. X   {"recip", dStkRecip, dStkRecip, dStkRecip }, /* from recip on new in v16 */
  38505. X   {"ident", StkIdent,  StkIdent,  StkIdent  },
  38506. X   {"cos",   dStkCos,   dStkCos,   dStkCos   },
  38507. X   {"tan",   dStkTan,   dStkTan,   dStkTan   },
  38508. X   {"tanh",  dStkTanh,  dStkTanh,  dStkTanh  },
  38509. X   {"cotan", dStkCoTan, dStkCoTan, dStkCoTan },
  38510. X   {"cotanh",dStkCoTanh,dStkCoTanh,dStkCoTanh},
  38511. X   {"flip",  dStkFlip,  dStkFlip,  dStkFlip  },
  38512. X   {"conj",  dStkConj,  dStkConj,  dStkConj  },
  38513. X   {"zero",  dStkZero,  dStkZero,  dStkZero  },
  38514. X#endif
  38515. X};
  38516. Xint numtrigfn = sizeof(trigfn)/sizeof(struct trig_funct_lst);
  38517. X
  38518. Xvoid showtrig(char *buf) /* return display form of active trig functions */
  38519. X{
  38520. X   char tmpbuf[30];
  38521. X   *buf = 0; /* null string if none */
  38522. X   trigdetails(tmpbuf);
  38523. X   if (tmpbuf[0])
  38524. X      sprintf(buf," function=%s",tmpbuf);
  38525. X}
  38526. X
  38527. Xstatic void trigdetails(char *buf)
  38528. X{
  38529. X   extern char maxfn;
  38530. X   int i, numfn;
  38531. X   char tmpbuf[20];
  38532. X   if(fractype==JULIBROT || fractype==JULIBROTFP)
  38533. X      numfn = (fractalspecific[neworbittype].flags >> 6) & 7;
  38534. X   else
  38535. X      numfn = (curfractalspecific->flags >> 6) & 7;
  38536. X   if(curfractalspecific == &fractalspecific[FORMULA] ||
  38537. X      curfractalspecific == &fractalspecific[FFORMULA]    )
  38538. X      numfn = maxfn;
  38539. X   *buf = 0; /* null string if none */
  38540. X   if (numfn>0) {
  38541. X      strcpy(buf,trigfn[trigndx[0]].name);
  38542. X      i = 0;
  38543. X      while(++i < numfn) {
  38544. X     sprintf(tmpbuf,"/%s",trigfn[trigndx[i]].name);
  38545. X     strcat(buf,tmpbuf);
  38546. X     }
  38547. X      }
  38548. X}
  38549. X
  38550. X/* set array of trig function indices according to "function=" command */
  38551. Xint set_trig_array(int k, char *name)
  38552. X{
  38553. X   char trigname[10];
  38554. X   int i;
  38555. X   char *slash;
  38556. X   strncpy(trigname,name,6);
  38557. X   trigname[6] = 0; /* safety first */
  38558. X
  38559. X   if ((slash = strchr(trigname,'/')))
  38560. X      *slash = 0;
  38561. X
  38562. X   strlwr(trigname);
  38563. X
  38564. X   for(i=0;i<numtrigfn;i++)
  38565. X   {
  38566. X      if(strcmp(trigname,trigfn[i].name)==0)
  38567. X      {
  38568. X     trigndx[k] = i;
  38569. X     set_trig_pointers(k);
  38570. X     break;
  38571. X      }
  38572. X   }
  38573. X   return(0);
  38574. X}
  38575. Xvoid set_trig_pointers(int which)
  38576. X{
  38577. X  /* set trig variable functions to avoid array lookup time */
  38578. X   int i;
  38579. X   switch(which)
  38580. X   {
  38581. X   case 0:
  38582. X#ifndef XFRACT
  38583. X      ltrig0 = trigfn[trigndx[0]].lfunct;
  38584. X      mtrig0 = trigfn[trigndx[0]].mfunct;
  38585. X#endif
  38586. X      dtrig0 = trigfn[trigndx[0]].dfunct;
  38587. X      break;
  38588. X   case 1:
  38589. X#ifndef XFRACT
  38590. X      ltrig1 = trigfn[trigndx[1]].lfunct;
  38591. X      mtrig1 = trigfn[trigndx[1]].mfunct;
  38592. X#endif
  38593. X      dtrig1 = trigfn[trigndx[1]].dfunct;
  38594. X      break;
  38595. X   case 2:
  38596. X#ifndef XFRACT
  38597. X      ltrig2 = trigfn[trigndx[2]].lfunct;
  38598. X      mtrig2 = trigfn[trigndx[2]].mfunct;
  38599. X#endif
  38600. X      dtrig2 = trigfn[trigndx[2]].dfunct;
  38601. X      break;
  38602. X   case 3:
  38603. X#ifndef XFRACT
  38604. X      ltrig3 = trigfn[trigndx[3]].lfunct;
  38605. X      mtrig3 = trigfn[trigndx[3]].mfunct;
  38606. X#endif
  38607. X      dtrig3 = trigfn[trigndx[3]].dfunct;
  38608. X      break;
  38609. X   default: /* do 'em all */
  38610. X      for(i=0;i<4;i++)
  38611. X     set_trig_pointers(i);
  38612. X      break;
  38613. X   }
  38614. X}
  38615. X
  38616. X
  38617. Xint tab_display()    /* display the status of the current image */
  38618. X{
  38619. X/* TW's static string consolidation campaign to help brain-dead compilers */
  38620. X   static char far sfractal_type[] =     {"Fractal type:"};
  38621. X   static char far s3D_transform[] =     {"3D Transform"};
  38622. X   static char far syou_are_cycling[] =  {"You are in color-cycling mode"};
  38623. X   static char far sfloating_point[] =   {"Floating-point"};
  38624. X   static char far sruns_forever[] =     {"Note: this type runs forever."};
  38625. X   static char far ssolid_guessing[] =   {"Solid Guessing"};
  38626. X   static char far sboundary_tracing[] = {"Boundary Tracing"};
  38627. X   static char far stesseral[] =         {"Tesseral"};
  38628. X   static char far scalculation_time[] = {"Calculation time:"};
  38629. X   static char far scornersxy[] =        {"Corners:                X                     Y"};
  38630. X   static char far stop_left[] =         {"top-left"};
  38631. X   static char far sbottom_right[] =     {"bottom-right"};
  38632. X   static char far scenter[] =           {"Center: "};
  38633. X   static char far smag[] =              {"  Mag: "};
  38634. X   static char far sbottom_left[] =      {"bottom-left"};
  38635. X   static char far sparams[] =           {"Params,"};
  38636. X   static char far siteration_maximum[] ={"Iteration maximum: "};
  38637. X   static char far seffective_bailout[] ={"     Effective bailout: "};
  38638. X   static char far scurrent_rseed[] =    {"Current 'rseed': "};
  38639. X   static char far sinversion_radius[] = {"Inversion radius: "};
  38640. X   static char far sxcenter[] =          {"  xcenter: "};
  38641. X   static char far sycenter[] =          {"  ycenter: "};
  38642. X   static char far sparms_chgd[] = {"Parms chgd since generated"};
  38643. X   static char far sstill_being[] = {"Still being generated"};
  38644. X   static char far sinterrupted_resumable[] = {"Interrupted, resumable"};
  38645. X   static char far sinterrupted_non_resumable[] = {"Interrupted, non-resumable"};
  38646. X   static char far simage_completed[] = {"Image completed"};
  38647. X   static char far sflag_is_activated[] = {" flag is activated"};
  38648. X   static char far sinteger_math[]      = {"Integer math is in use"};
  38649. X   static char far sin_use_required[] = {" in use (required)"};
  38650. X
  38651. X   extern char floatflag;
  38652. X   extern char usr_floatflag;
  38653. X   extern double param[];
  38654. X   extern double rqlim;
  38655. X   extern long calctime, timer_start;
  38656. X   extern int  calc_status;
  38657. X   extern char FormName[];
  38658. X   extern char LName[];
  38659. X   extern char IFSName[];
  38660. X   extern int  rseed;
  38661. X   extern int  invert;
  38662. X   int row, i, j;
  38663. X   double Xctr, Yctr, Magnification;
  38664. X   char msg[81];
  38665. X   char far *msgptr;
  38666. X   int key;
  38667. X
  38668. X   if (calc_status < 0)     /* no active fractal image */
  38669. X      return(0);        /* (no TAB on the credits screen) */
  38670. X   if (calc_status == 1)    /* next assumes CLK_TCK is 10^n, n>=2 */
  38671. X      calctime += (clock_ticks() - timer_start) / (CLK_TCK/100);
  38672. X   stackscreen();
  38673. Xtop:
  38674. X   helptitle();
  38675. X   setattr(1,0,C_GENERAL_MED,24*80); /* init rest to background */
  38676. X
  38677. X   row = 2;
  38678. X   putstring(row,2,C_GENERAL_MED,sfractal_type);
  38679. X   if (display3d > 0)
  38680. X      putstring(row,16,C_GENERAL_HI,s3D_transform);
  38681. X   else {
  38682. X      putstring(row,16,C_GENERAL_HI,
  38683. X       curfractalspecific->name[0] == '*' ?
  38684. X         &curfractalspecific->name[1] :
  38685. X         curfractalspecific->name);
  38686. X      i = 0;
  38687. X      if (fractype == FORMULA || fractype == FFORMULA)
  38688. X      {
  38689. X     putstring(row+1,16,C_GENERAL_HI,FormName);
  38690. X      i = strlen(FormName)+1;
  38691. X      }
  38692. X      trigdetails(msg);
  38693. X      putstring(row+1,16+i,C_GENERAL_HI,msg);
  38694. X      if (fractype == LSYSTEM)
  38695. X     putstring(row+1,16,C_GENERAL_HI,LName);
  38696. X      if (fractype == IFS || fractype == IFS3D)
  38697. X     putstring(row+1,16,C_GENERAL_HI,IFSName);
  38698. X      }
  38699. X
  38700. X   switch (calc_status) {
  38701. X      case 0:  msgptr = sparms_chgd;
  38702. X           break;
  38703. X      case 1:  msgptr = sstill_being;
  38704. X           break;
  38705. X      case 2:  msgptr = sinterrupted_resumable;
  38706. X           break;
  38707. X      case 3:  msgptr = sinterrupted_non_resumable;
  38708. X           break;
  38709. X      case 4:  msgptr = simage_completed;
  38710. X           break;
  38711. X      default: msgptr = "";
  38712. X      }
  38713. X   putstring(row,45,C_GENERAL_HI,msgptr);
  38714. X   if (helpmode == HELPCYCLING)
  38715. X      putstring(row+1,45,C_GENERAL_HI,syou_are_cycling);
  38716. X   row += 2;
  38717. X
  38718. X    i = j = 0;
  38719. X    if (display3d > 0) {
  38720. X       if (usr_floatflag)
  38721. X      j = 1;
  38722. X       }
  38723. X    else
  38724. X       if (floatflag)
  38725. X      j = (usr_floatflag) ? 1 : 2;
  38726. X    if (j) {
  38727. X       putstring(row,45,C_GENERAL_HI,sfloating_point);
  38728. X       putstring(-1,-1,C_GENERAL_HI,(j == 1) ? sflag_is_activated
  38729. X                         : sin_use_required );
  38730. X      i = 1;
  38731. X      }
  38732. X      else
  38733. X      {
  38734. X       putstring(row,45,C_GENERAL_HI,sinteger_math);
  38735. X      i = 1;
  38736. X      }
  38737. X   if (calc_status == 1 || calc_status == 2)
  38738. X      if (curfractalspecific->flags&INFCALC) {
  38739. X     putstring(row,2,C_GENERAL_HI,sruns_forever);
  38740. X     i = 1;
  38741. X     }
  38742. X   row += i;
  38743. X
  38744. X   if (calc_status == 1 || calc_status == 2)
  38745. X      if (curfractalspecific->flags&NORESUME)
  38746. X      {
  38747. X     static char far msg[] = {"Note: can't resume this type after interrupts other than <tab> and <F1>"};
  38748. X     putstring(row++,2,C_GENERAL_HI,msg);
  38749. X      }
  38750. X   ++row;
  38751. X
  38752. X   if (got_status >= 0 && (calc_status == 1 || calc_status == 2)) {
  38753. X      switch (got_status) {
  38754. X     case 0:
  38755. X        sprintf(msg,"%d Pass Mode",totpasses);
  38756. X        putstring(row,2,C_GENERAL_HI,msg);
  38757. X        break;
  38758. X     case 1:
  38759. X        putstring(row,2,C_GENERAL_HI,ssolid_guessing);
  38760. X        break;
  38761. X     case 2:
  38762. X        putstring(row,2,C_GENERAL_HI,sboundary_tracing);
  38763. X        break;
  38764. X     case 3:
  38765. X        sprintf(msg,"Processing row %d (of %d) of input image",currow,fileydots);
  38766. X        putstring(row,2,C_GENERAL_HI,msg);
  38767. X        break;
  38768. X     case 4:
  38769. X        putstring(row,2,C_GENERAL_HI,stesseral);
  38770. X        break;
  38771. X     }
  38772. X      ++row;
  38773. X      if (got_status != 3) {
  38774. X     sprintf(msg,"Working on block (y,x) [%d,%d]...[%d,%d], ",
  38775. X        yystart,xxstart,yystop,xxstop);
  38776. X     putstring(row,2,C_GENERAL_MED,msg);
  38777. X     if (got_status == 2 || got_status == 4) { /* btm or tesseral */
  38778. X        putstring(-1,-1,C_GENERAL_MED,"at ");
  38779. X        sprintf(msg,"[%d,%d]",currow,curcol);
  38780. X        putstring(-1,-1,C_GENERAL_HI,msg);
  38781. X        }
  38782. X     else {
  38783. X        if (totpasses > 1) {
  38784. X           putstring(-1,-1,C_GENERAL_MED,"pass ");
  38785. X           sprintf(msg,"%d",curpass);
  38786. X           putstring(-1,-1,C_GENERAL_HI,msg);
  38787. X           putstring(-1,-1,C_GENERAL_MED," of ");
  38788. X           sprintf(msg,"%d",totpasses);
  38789. X           putstring(-1,-1,C_GENERAL_HI,msg);
  38790. X           putstring(-1,-1,C_GENERAL_MED,", ");
  38791. X           }
  38792. X        putstring(-1,-1,C_GENERAL_MED,"at row ");
  38793. X        sprintf(msg,"%d",currow);
  38794. X        putstring(-1,-1,C_GENERAL_HI,msg);
  38795. X        }
  38796. X     ++row;
  38797. X     }
  38798. X      }
  38799. X   putstring(row,2,C_GENERAL_MED,scalculation_time);
  38800. X   sprintf(msg,"%3ld:%02ld:%02ld.%02ld", calctime/360000,
  38801. X      (calctime%360000)/6000, (calctime%6000)/100, calctime%100);
  38802. X   putstring(-1,-1,C_GENERAL_HI,msg);
  38803. X   row += 2;
  38804. X
  38805. X   if (videoentry.xdots) {
  38806. X      sprintf(msg,"Video: %dx%dx%d %s %s",
  38807. X          videoentry.xdots, videoentry.ydots, videoentry.colors,
  38808. X          videoentry.name, videoentry.comment);
  38809. X      putstring(row,2,C_GENERAL_MED,msg);
  38810. X      }
  38811. X   ++row;
  38812. X
  38813. X   putstring(row,2,C_GENERAL_MED,scornersxy);
  38814. X   putstring(++row,3,C_GENERAL_MED,stop_left);
  38815. X   sprintf(msg,"%20.16f  %20.16f",xxmin,yymax);
  38816. X   putstring(-1,17,C_GENERAL_HI,msg);
  38817. X   putstring(++row,3,C_GENERAL_MED,sbottom_right);
  38818. X   sprintf(msg,"%20.16f  %20.16f",xxmax,yymin);
  38819. X   putstring(-1,17,C_GENERAL_HI,msg);
  38820. X   adjust_corner(); /* make bottom left exact if very near exact */
  38821. X   if (cvtcentermag(&Xctr, &Yctr, &Magnification)) {
  38822. X      putstring(row+=2,2,C_GENERAL_MED,scenter);
  38823. X      sprintf(msg,"%20.16f %20.16f",Xctr,Yctr);
  38824. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38825. X      putstring(-1,-1,C_GENERAL_MED,smag);
  38826. X      if (Magnification < 1e6)
  38827. X     sprintf(msg,"%20.14f",Magnification);
  38828. X      else if (Magnification < 1e12)
  38829. X     sprintf(msg,"%20.8f",Magnification);
  38830. X      else
  38831. X     sprintf(msg,"%20.2f",Magnification);
  38832. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38833. X      }
  38834. X   else if (xxmin != xx3rd || yymin != yy3rd) {
  38835. X      putstring(++row,3,C_GENERAL_MED,sbottom_left);
  38836. X      sprintf(msg,"%20.16f  %20.16f",xx3rd,yy3rd);
  38837. X      putstring(-1,17,C_GENERAL_HI,msg);
  38838. X      }
  38839. X   putstring(row+=2,2,C_GENERAL_MED,sparams);
  38840. X   for (i = 0; i < 4; i++) {
  38841. X      sprintf(msg,"%3d: ",i+1);
  38842. X      putstring(-1,-1,C_GENERAL_MED,msg);
  38843. X      sprintf(msg,"%12.9f",param[i]);
  38844. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38845. X      }
  38846. X
  38847. X   putstring(row+=2,2,C_GENERAL_MED,siteration_maximum);
  38848. X   sprintf(msg,"%d",maxit);
  38849. X   putstring(-1,-1,C_GENERAL_HI,msg);
  38850. X   putstring(-1,-1,C_GENERAL_MED,seffective_bailout);
  38851. X   sprintf(msg,"%f",rqlim);
  38852. X   putstring(-1,-1,C_GENERAL_HI,msg);
  38853. X
  38854. X   if (fractype == PLASMA) {
  38855. X      putstring(++row,2,C_GENERAL_MED,scurrent_rseed);
  38856. X      sprintf(msg,"%d",rseed);
  38857. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38858. X      }
  38859. X
  38860. X   if(invert) {
  38861. X      extern double f_radius,f_xcenter,f_ycenter;
  38862. X      putstring(++row,2,C_GENERAL_MED,sinversion_radius);
  38863. X      sprintf(msg,"%12.9f",f_radius);
  38864. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38865. X      putstring(-1,-1,C_GENERAL_MED,sxcenter);
  38866. X      sprintf(msg,"%12.9f",f_xcenter);
  38867. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38868. X      putstring(-1,-1,C_GENERAL_MED,sycenter);
  38869. X      sprintf(msg,"%12.9f",f_ycenter);
  38870. X      putstring(-1,-1,C_GENERAL_HI,msg);
  38871. X      }
  38872. X
  38873. X   if ((row += 2) < 23) ++row;
  38874. Xwaitforkey:
  38875. X   putstringcenter(row,0,80,C_GENERAL_LO,
  38876. X       "...Press any key to continue, F6 for area...");
  38877. X   movecursor(25,80);
  38878. X#ifdef XFRACT
  38879. X   while (keypressed()) {
  38880. X       getakey();
  38881. X   }
  38882. X#endif
  38883. X   key = getakeynohelp();
  38884. X   if (key==F6) {
  38885. X       unstackscreen();
  38886. X       area();
  38887. X       stackscreen();
  38888. X/*       goto waitforkey;*/
  38889. X        goto top;
  38890. X   }
  38891. X   unstackscreen();
  38892. X   timer_start = clock_ticks(); /* tab display was "time out" */
  38893. X   return(0);
  38894. X}
  38895. X
  38896. Xstatic void area()
  38897. X{
  38898. X    /* apologies to UNIX folks, we PC guys have to save near space */
  38899. X    static char far warning[] = {"Warning: inside may not be unique\n"};
  38900. X    static char far total_area[] = {".  Total area "}; 
  38901. X    char far *msg;
  38902. X    int x,y;
  38903. X    char buf[160];
  38904. X    long cnt=0;
  38905. X    if (inside<0) {
  38906. X      static char far msg[] = {"Need solid inside to compute area"};
  38907. X      stopmsg(0,msg);
  38908. X      return;
  38909. X    }
  38910. X    for (y=0;y<ydots;y++) {
  38911. X      for (x=0;x<xdots;x++) {
  38912. X          if (getcolor(x,y)==inside) {
  38913. X              cnt++;
  38914. X          }
  38915. X      }
  38916. X    }
  38917. X    if (inside>0 && outside<0 && maxit>inside) {
  38918. X      msg = warning;
  38919. X    } else {
  38920. X      msg = (char far *)"";
  38921. X    }
  38922. X#ifndef XFRACT
  38923. X      sprintf(buf,"%Fs%ld inside pixels of %ld%Fs%f",
  38924. X              msg,cnt,(long)xdots*(long)ydots,total_area,
  38925. X              cnt/((float)xdots*(float)ydots)*(xxmax-xxmin)*(yymax-yymin));
  38926. X#else
  38927. X      sprintf(buf,"%s%ld inside pixels of %ld%s%f",
  38928. X              msg,cnt,(long)xdots*(long)ydots,total_area,
  38929. X              cnt/((float)xdots*(float)ydots)*(xxmax-xxmin)*(yymax-yymin));
  38930. X#endif
  38931. X    stopmsg(4,buf);
  38932. X}
  38933. X
  38934. Xint endswithslash(char *fl)
  38935. X{
  38936. X   int len;
  38937. X   len = strlen(fl);
  38938. X   if(len)
  38939. X      if(fl[--len] == SLASHC)
  38940. X     return(1);
  38941. X   return(0);
  38942. X}
  38943. X
  38944. Xchar far insufficient_ifs_mem[]={"Insufficient memory for IFS"};
  38945. X/* --------------------------------------------------------------------- */
  38946. Xint numaffine;
  38947. Xint ifsload()            /* read in IFS parameters */
  38948. X{
  38949. X   int i;
  38950. X   FILE *ifsfile;
  38951. X   char buf[201];
  38952. X   char *bufptr;
  38953. X   extern float tstack[];    /* shared temp */
  38954. X   int ret,rowsize;
  38955. X
  38956. X   if (ifs_defn) { /* release prior parms */
  38957. X      farmemfree((char far *)ifs_defn);
  38958. X      ifs_defn = NULL;
  38959. X      }
  38960. X
  38961. X   ifs_changed = ifs_type = 0;
  38962. X   rowsize = IFSPARM;
  38963. X   if (find_file_item(IFSFileName,IFSName,&ifsfile) < 0)
  38964. X      return(-1);
  38965. X
  38966. X   fgets(buf,200,ifsfile);
  38967. X   strlwr(buf);
  38968. X   bufptr = &buf[0];
  38969. X   while (*bufptr) {
  38970. X      if (strncmp(bufptr,"(3d)",4) == 0) {
  38971. X     ifs_type = 1;
  38972. X     rowsize = IFS3DPARM;
  38973. X     }
  38974. X      ++bufptr;
  38975. X      }
  38976. X
  38977. X   for (i = 0; i < (NUMIFS+1)*IFS3DPARM; ++i)
  38978. X      tstack[i] = 0.0;
  38979. X   i = ret = 0;
  38980. X   while (fscanf(ifsfile," %f ",&tstack[i])) {
  38981. X      if (++i >= NUMIFS*rowsize) {
  38982. X      static char far msg[]={"IFS definition has too many lines"};
  38983. X     stopmsg(0,msg);
  38984. X     ret = -1;
  38985. X     break;
  38986. X     }
  38987. X      }
  38988. X   if ((i % rowsize) != 0 || getc(ifsfile) != '}') {
  38989. X      static char far msg[]={"invalid IFS definition"};
  38990. X      stopmsg(0,msg);
  38991. X      ret = -1;
  38992. X      }
  38993. X   if (i == 0 && ret == 0) {
  38994. X      static char far msg[]={"Empty IFS definition"};
  38995. X      stopmsg(0,msg);
  38996. X      ret = -1;
  38997. X      }
  38998. X   fclose(ifsfile);
  38999. X
  39000. X   if (ret == 0) {
  39001. X      numaffine = i/rowsize;
  39002. X      if ((ifs_defn = (float far *)farmemalloc(
  39003. X            (long)((NUMIFS+1)*IFS3DPARM*sizeof(float)))) == NULL) {
  39004. X     stopmsg(0,insufficient_ifs_mem);
  39005. X     ret = -1;
  39006. X     }
  39007. X      else
  39008. X     for (i = 0; i < (NUMIFS+1)*IFS3DPARM; ++i)
  39009. X        ifs_defn[i] = tstack[i];
  39010. X   }
  39011. X   return(ret);
  39012. X}
  39013. X
  39014. Xint find_file_item(char *filename,char *itemname,FILE **infile)
  39015. X{
  39016. X   char tmpname[41];
  39017. X   char fullpathname[FILE_MAX_PATH];
  39018. X   long notepoint;
  39019. X   char buf[201];
  39020. X   int c;
  39021. X   findpath(filename, fullpathname); 
  39022. X   if ((*infile = fopen(fullpathname,"rt")) == NULL) {
  39023. X      sprintf(buf,s_cantopen,fullpathname);
  39024. X      stopmsg(0,buf);
  39025. X      return(-1);
  39026. X      }
  39027. X
  39028. X   while (1) {
  39029. X      while ((c = getc(*infile)) == ' ' || c == '\t' || c == '\n') { }
  39030. X      if (c == EOF) break;
  39031. X      if (c == ';') {
  39032. X     while ((c = fgetc(*infile)) != '\n' && c != EOF) { }
  39033. X     if (c == EOF) break;
  39034. X     continue;
  39035. X     }
  39036. X      notepoint = ftell(*infile) - 1;
  39037. X      ungetc(c,*infile);
  39038. X      if (fscanf(*infile," %40[^ \n\t({]",tmpname) == EOF) break;
  39039. X      while ((c = getc(*infile)) != EOF && c != '{' && c != '\n') { }
  39040. X      if (c == EOF) break;
  39041. X      if (c == '{') {
  39042. X     if (stricmp(tmpname,itemname) == 0) {
  39043. X        fseek(*infile,notepoint,SEEK_SET);
  39044. X        return(0);
  39045. X        }
  39046. X     while ((c = getc(*infile)) != '}' && c != EOF) { }
  39047. X     if (c == EOF) break;
  39048. X     }
  39049. X      }
  39050. X   fclose(*infile);
  39051. X   sprintf(buf,"'%s' definition not found",itemname);
  39052. X   stopmsg(0,buf);
  39053. X   return(-1);
  39054. X}
  39055. X
  39056. Xint file_gets(char *buf,int maxlen,FILE *infile)
  39057. X{
  39058. X   int len,c;
  39059. X   /* similar to 'fgets', but file may be in either text or binary mode */
  39060. X   /* returns -1 at eof, length of string otherwise */
  39061. X   if (feof(infile)) return -1;
  39062. X   len = 0;
  39063. X   while (len < maxlen) {
  39064. X      if ((c = getc(infile)) == EOF || c == '\032') {
  39065. X     if (len) break;
  39066. X     return -1;
  39067. X     }
  39068. X      if (c == '\n') break;             /* linefeed is end of line */
  39069. X      if (c != '\r') buf[len++] = c;    /* ignore c/r */
  39070. X      }
  39071. X   buf[len] = 0;
  39072. X   return len;
  39073. X}
  39074. X
  39075. Xint first_err = 1;
  39076. X
  39077. X#ifndef XFRACT
  39078. X#ifdef WINFRACT
  39079. X/* call this something else to dodge the QC4WIN bullet... */
  39080. Xint win_matherr( struct exception *except )
  39081. X#else
  39082. Xint matherr( struct exception *except )
  39083. X#endif
  39084. X{
  39085. X    extern int debugflag;
  39086. X    static char far msg[]={"Math error, but we'll try to keep going"};
  39087. X    if(first_err)
  39088. X    {
  39089. X       if(debugflag == 4000)stopmsg(0,msg);
  39090. X       first_err = 0;
  39091. X    }
  39092. X    if(debugflag)
  39093. X    {
  39094. X       static int ct = 0;
  39095. X       static FILE *fp=NULL;
  39096. X       if(fp==NULL)
  39097. X      fp = fopen("matherr","w");
  39098. X       if(ct++ < 100)
  39099. X       {
  39100. X      fprintf(fp,"err:  %d\nname: %s\narg:  %le\n",
  39101. X          except->type, except->name, except->arg1);
  39102. X      fflush(fp);
  39103. X       }
  39104. X    }
  39105. X    if( except->type == DOMAIN )
  39106. X    {
  39107. X    char buf[40];
  39108. X    sprintf(buf,"%le",except->arg1);
  39109. X    /* This test may be unnecessary - from my experiments if the
  39110. X       argument is too large or small the error is TLOSS not DOMAIN */
  39111. X    if(strstr(buf,"IN")||strstr(buf,"NAN"))  /* trashed arg? */
  39112. X               /* "IND" with MSC, "INF" with BC++ */
  39113. X    {
  39114. X       if( strcmp( except->name, "sin" ) == 0 )
  39115. X       {
  39116. X          except->retval = 0.0;
  39117. X          return(1);
  39118. X       }
  39119. X       else if( strcmp( except->name, "cos" ) == 0 )
  39120. X       {
  39121. X          except->retval = 1.0;
  39122. X          return(1);
  39123. X       }
  39124. X       else if( strcmp( except->name, "log" ) == 0 )
  39125. X       {
  39126. X          except->retval = 1.0;
  39127. X          return(1);
  39128. X       }
  39129. X       }
  39130. X    }
  39131. X    if( except->type == TLOSS )
  39132. X    {
  39133. X       /* try valiantly to keep going */
  39134. X       if( strcmp( except->name, "sin" ) == 0 )
  39135. X       {
  39136. X          except->retval = 0.5;
  39137. X          return(1);
  39138. X       }
  39139. X       else if( strcmp( except->name, "cos" ) == 0 )
  39140. X       {
  39141. X          except->retval = 0.5;
  39142. X          return(1);
  39143. X       }
  39144. X    }
  39145. X    /* shucks, no idea what went wrong, but our motto is "keep going!" */
  39146. X    except->retval = 1.0;
  39147. X    return(1);
  39148. X}
  39149. X#endif
  39150. X
  39151. Xvoid roundfloatd(double *x) /* make double converted from float look ok */
  39152. X{
  39153. X   char buf[30];
  39154. X   sprintf(buf,"%-10.7g",*x);
  39155. X   *x = atof(buf);
  39156. X}
  39157. X
  39158. X/* fake a keystroke, returns old pending key */
  39159. Xint ungetakey(int key)
  39160. X{
  39161. X   int old;
  39162. X   extern int keybuffer;
  39163. X   old = keybuffer;
  39164. X   keybuffer = key;
  39165. X   return(old);
  39166. X}
  39167. X
  39168. X/* use this indirect aproach so that we can put GIFVIEW.C in an overlay */
  39169. X
  39170. Xint gifview()
  39171. X{
  39172. X    return(gifview1());
  39173. X}
  39174. X
  39175. Xchar *extract_filename(char * fullfilename)
  39176. X{
  39177. X   static char fname_ext[FILE_MAX_FNAME+FILE_MAX_EXT];
  39178. X   char fname[FILE_MAX_FNAME];
  39179. X   char ext[FILE_MAX_EXT];
  39180. X   fname_ext[0] = 0;
  39181. X   splitpath(fullfilename ,NULL,NULL,fname,ext);
  39182. X   makepath(fname_ext,""   ,"" ,fname,ext);
  39183. X   return(fname_ext);
  39184. X}
  39185. SHAR_EOF
  39186. $TOUCH -am 1028230093 miscres.c &&
  39187. chmod 0644 miscres.c ||
  39188. echo "restore of miscres.c failed"
  39189. set `wc -c miscres.c`;Wc_c=$1
  39190. if test "$Wc_c" != "27230"; then
  39191.     echo original size 27230, current size $Wc_c
  39192. fi
  39193. # ============= mpmath_c.c ==============
  39194. echo "x - extracting mpmath_c.c (Text)"
  39195. sed 's/^X//' << 'SHAR_EOF' > mpmath_c.c &&
  39196. X/* MPMath_c.c (C) 1989, Mark C. Peterson, CompuServe [70441,3353]
  39197. X     All rights reserved.
  39198. X
  39199. X   Code may be used in any program provided the author is credited
  39200. X     either during program execution or in the documentation.  Source
  39201. X     code may be distributed only in combination with public domain or
  39202. X     shareware source code.  Source code may be modified provided the
  39203. X     copyright notice and this message is left unchanged and all
  39204. X     modifications are clearly documented.
  39205. X
  39206. X     I would appreciate a copy of any work which incorporates this code,
  39207. X     however this is optional.
  39208. X
  39209. X     Mark C. Peterson
  39210. X     405-C Queen St. Suite #181
  39211. X     Southington, CT 06489
  39212. X     (203) 276-9721
  39213. X*/
  39214. X
  39215. X#include <stdlib.h>
  39216. X#include "mpmath.h"
  39217. X#include "prototyp.h"
  39218. X
  39219. X#ifndef XFRACT
  39220. X
  39221. Xint MPaccuracy = 32;
  39222. X
  39223. Xstruct MP *MPsub(struct MP x, struct MP y) {
  39224. X   y.Exp ^= 0x8000;
  39225. X   return(MPadd(x, y));
  39226. X}
  39227. X
  39228. X/* added by TW */
  39229. Xstruct MP *MPsub086(struct MP x, struct MP y) {
  39230. X   y.Exp ^= 0x8000;
  39231. X   return(MPadd086(x, y));
  39232. X}
  39233. X
  39234. X/* added by TW */
  39235. Xstruct MP *MPsub386(struct MP x, struct MP y) {
  39236. X   y.Exp ^= 0x8000;
  39237. X   return(MPadd386(x, y));
  39238. X}
  39239. X
  39240. Xstruct MP *MPabs(struct MP x) {
  39241. X   x.Exp &= 0x7fff;
  39242. X   return(&x);
  39243. X}
  39244. X
  39245. Xstruct MPC MPCsqr(struct MPC x) {
  39246. X   struct MPC z;
  39247. X
  39248. X        z.x = *pMPsub(*pMPmul(x.x, x.x), *pMPmul(x.y, x.y));
  39249. X        z.y = *pMPmul(x.x, x.y);
  39250. X        z.y.Exp++;
  39251. X   return(z);
  39252. X}
  39253. X
  39254. Xstruct MP MPCmod(struct MPC x) {
  39255. X        return(*pMPadd(*pMPmul(x.x, x.x), *pMPmul(x.y, x.y)));
  39256. X}
  39257. X
  39258. Xstruct MPC MPCmul(struct MPC x, struct MPC y) {
  39259. X   struct MPC z;
  39260. X
  39261. X        z.x = *pMPsub(*pMPmul(x.x, y.x), *pMPmul(x.y, y.y));
  39262. X        z.y = *pMPadd(*pMPmul(x.x, y.y), *pMPmul(x.y, y.x));
  39263. X   return(z);
  39264. X}
  39265. X
  39266. Xstruct MPC MPCdiv(struct MPC x, struct MPC y) {
  39267. X   struct MP mod;
  39268. X
  39269. X   mod = MPCmod(y);
  39270. X        y.y.Exp ^= 0x8000;
  39271. X        y.x = *pMPdiv(y.x, mod);
  39272. X        y.y = *pMPdiv(y.y, mod);
  39273. X   return(MPCmul(x, y));
  39274. X}
  39275. X
  39276. Xstruct MPC MPCadd(struct MPC x, struct MPC y) {
  39277. X   struct MPC z;
  39278. X
  39279. X        z.x = *pMPadd(x.x, y.x);
  39280. X        z.y = *pMPadd(x.y, y.y);
  39281. X   return(z);
  39282. X}
  39283. X
  39284. Xstruct MPC MPCsub(struct MPC x, struct MPC y) {
  39285. X   struct MPC z;
  39286. X
  39287. X        z.x = *pMPsub(x.x, y.x);
  39288. X        z.y = *pMPsub(x.y, y.y);
  39289. X   return(z);
  39290. X}
  39291. X
  39292. Xstruct MPC MPCone = { 0x3fff, 0x80000000l, 0, 0l };
  39293. X
  39294. Xstruct MPC MPCpow(struct MPC x, int exp) {
  39295. X   struct MPC z;
  39296. X   struct MPC zz;
  39297. X
  39298. X   if(exp & 1)
  39299. X      z = x;
  39300. X   else
  39301. X      z = MPCone;
  39302. X   exp >>= 1;
  39303. X   while(exp) {
  39304. X                zz.x = *pMPsub(*pMPmul(x.x, x.x), *pMPmul(x.y, x.y));
  39305. X                zz.y = *pMPmul(x.x, x.y);
  39306. X                zz.y.Exp++;
  39307. X      x = zz;
  39308. X      if(exp & 1) {
  39309. X                        zz.x = *pMPsub(*pMPmul(z.x, x.x), *pMPmul(z.y, x.y));
  39310. X                        zz.y = *pMPadd(*pMPmul(z.x, x.y), *pMPmul(z.y, x.x));
  39311. X         z = zz;
  39312. X      }
  39313. X      exp >>= 1;
  39314. X   }
  39315. X   return(z);
  39316. X}
  39317. X
  39318. Xint MPCcmp(struct MPC x, struct MPC y) {
  39319. X   struct MPC z;
  39320. X
  39321. X        if(pMPcmp(x.x, y.x) || pMPcmp(x.y, y.y)) {
  39322. X                z.x = MPCmod(x);
  39323. X                z.y = MPCmod(y);
  39324. X                return(pMPcmp(z.x, z.y));
  39325. X   }
  39326. X   else
  39327. X      return(0);
  39328. X}
  39329. X
  39330. X_CMPLX MPC2cmplx(struct MPC x) {
  39331. X   _CMPLX z;
  39332. X
  39333. X        z.x = *pMP2d(x.x);
  39334. X        z.y = *pMP2d(x.y);
  39335. X   return(z);
  39336. X}
  39337. X
  39338. Xstruct MPC cmplx2MPC(_CMPLX z) {
  39339. X   struct MPC x;
  39340. X
  39341. X        x.x = *pd2MP(z.x);
  39342. X        x.y = *pd2MP(z.y);
  39343. X   return(x);
  39344. X}
  39345. X
  39346. X/* function pointer versions added by Tim Wegner 12/07/89 */
  39347. Xint        (*ppMPcmp)() = MPcmp086;
  39348. Xint        (*pMPcmp)(struct MP x, struct MP y) = MPcmp086;
  39349. Xstruct MP  *(*pMPmul)(struct MP x, struct MP y)= MPmul086;
  39350. Xstruct MP  *(*pMPdiv)(struct MP x, struct MP y)= MPdiv086;
  39351. Xstruct MP  *(*pMPadd)(struct MP x, struct MP y)= MPadd086;
  39352. Xstruct MP  *(*pMPsub)(struct MP x, struct MP y)= MPsub086;
  39353. Xstruct MP  *(*pd2MP)(double x)                 = d2MP086 ;
  39354. Xdouble *(*pMP2d)(struct MP m)                  = MP2d086 ;
  39355. Xstruct MP  *(*pfg2MP)(long x, int fg)          = fg2MP086;
  39356. X
  39357. Xvoid setMPfunctions(void) {
  39358. X   if(cpu == 386)
  39359. X   {
  39360. X      pMPmul = MPmul386;
  39361. X      pMPdiv = MPdiv386;
  39362. X      pMPadd = MPadd386;
  39363. X      pMPsub = MPsub386;
  39364. X      pMPcmp = MPcmp386;
  39365. X      pd2MP  = d2MP386 ;
  39366. X      pMP2d  = MP2d386 ;
  39367. X      pfg2MP = fg2MP386;
  39368. X   }
  39369. X   else
  39370. X   {
  39371. X      pMPmul = MPmul086;
  39372. X      pMPdiv = MPdiv086;
  39373. X      pMPadd = MPadd086;
  39374. X      pMPsub = MPsub086;
  39375. X      pMPcmp = MPcmp086;
  39376. X      pd2MP  = d2MP086 ;
  39377. X      pMP2d  = MP2d086 ;
  39378. X      pfg2MP = fg2MP086;
  39379. X   }
  39380. X}
  39381. X
  39382. X#endif /* XFRACT */
  39383. X
  39384. X#ifndef sqr
  39385. X#define sqr(x) ((x)*(x))
  39386. X#endif
  39387. X
  39388. Xextern int debugflag, fpu;
  39389. X
  39390. X_CMPLX ComplexPower(_CMPLX xx, _CMPLX yy) {
  39391. X   _CMPLX z, cLog, t;
  39392. X   double e2x, siny, cosy;
  39393. X
  39394. X   FPUcplxlog(&xx, &cLog);
  39395. X   FPUcplxmul(&cLog, &yy, &t);
  39396. X
  39397. X   if(fpu == 387)
  39398. X      FPUcplxexp387(&t, &z);
  39399. X   else {
  39400. X      if(t.x < -690)
  39401. X         e2x = 0;
  39402. X      else
  39403. X         e2x = exp(t.x);
  39404. X      FPUsincos(&t.y, &siny, &cosy);
  39405. X      z.x = e2x * cosy;
  39406. X      z.y = e2x * siny;
  39407. X   }
  39408. X   return(z);
  39409. X}
  39410. X
  39411. X/***** FRACTINT specific routines and variables *****/
  39412. X
  39413. X#ifndef TESTING_MATH
  39414. X
  39415. X#include <stdlib.h>
  39416. X
  39417. X#include "fractint.h"
  39418. X
  39419. Xextern double param[];
  39420. Xextern _CMPLX old, new, init;
  39421. Xextern double threshold, roverd, d1overd, dx0[], dy0[];
  39422. Xextern int periodicitycheck, row, col, debugflag;
  39423. X
  39424. X
  39425. X#include <stdlib.h>
  39426. X
  39427. Xextern int  xdots, ydots;     /* coordinates of dots on the screen  */
  39428. Xextern int  colors;           /* maximum colors available */
  39429. Xextern int  maxit;
  39430. X
  39431. XBYTE far *LogTable = (BYTE far *)0;
  39432. Xextern int LogFlag;
  39433. X   /* LogFlag == 1  -- standard log palettes
  39434. X      LogFlag == -1 -- 'old' log palettes
  39435. X      LogFlag >  1  -- compress counts < LogFlag into color #1
  39436. X      LogFlag < -1  -- use quadratic palettes based on square roots && compress
  39437. X   */
  39438. X
  39439. Xvoid SetupLogTable(void) {
  39440. X   float l, f, c, m;
  39441. X   unsigned n, prev, limit, lf;
  39442. X
  39443. X   if (LogFlag > -2) {
  39444. X      lf = (LogFlag > 1) ? LogFlag : 0;
  39445. X      if (lf >= maxit)
  39446. X         lf = maxit - 1;
  39447. X      Fg2Float((long)(maxit-lf), 0, m);
  39448. X      fLog14(m, m);
  39449. X      Fg2Float((long)(colors-(lf?2:1)), 0, c);
  39450. X      fDiv(m, c, m);
  39451. X      for (prev = 1; prev <= lf; prev++)
  39452. X         LogTable[prev] = 1;
  39453. X      for (n = (lf?2:1); n < colors; n++) {
  39454. X         Fg2Float((long)n, 0, f);
  39455. X         fMul16(f, m, f);
  39456. X         fExp14(f, l);
  39457. X         limit = Float2Fg(l, 0) + lf;
  39458. X         if (limit > maxit || n == colors-1)
  39459. X            limit = maxit;
  39460. X         while (prev <= limit)
  39461. X            LogTable[prev++] = n;
  39462. X      }
  39463. X   } else {
  39464. X      if ((lf = 0 - LogFlag) >= maxit)
  39465. X         lf = maxit - 1;
  39466. X      Fg2Float((long)(maxit-lf), 0, m);
  39467. X      fSqrt14(m, m);
  39468. X      Fg2Float((long)(colors-2), 0, c);
  39469. X      fDiv(m, c, m);
  39470. X      for (prev = 1; prev <= lf; prev++)
  39471. X         LogTable[prev] = 1;
  39472. X      for (n = 2; n < colors; n++) {
  39473. X         Fg2Float((long)n, 0, f);
  39474. X         fMul16(f, m, f);
  39475. X         fMul16(f, f, l);
  39476. X         limit = Float2Fg(l, 0) + lf;
  39477. X         if (limit > maxit || n == colors-1)
  39478. X            limit = maxit;
  39479. X         while (prev <= limit)
  39480. X            LogTable[prev++] = n;
  39481. X      }
  39482. X   }
  39483. X   LogTable[0] = 0;
  39484. X   if (LogFlag != -1)
  39485. X      for (n = 1; n < maxit; n++) /* spread top to incl unused colors */
  39486. X         if (LogTable[n] > LogTable[n-1])
  39487. X            LogTable[n] = LogTable[n-1]+1;
  39488. X}
  39489. X
  39490. Xlong far ExpFloat14(long xx) {
  39491. X   static float fLogTwo = (float)0.6931472;
  39492. X   int f;
  39493. X   long Ans;
  39494. X
  39495. X   f = 23 - (int)RegFloat2Fg(RegDivFloat(xx, *(long*)&fLogTwo), 0);
  39496. X   Ans = ExpFudged(RegFloat2Fg(xx, 16), f);
  39497. X   return(RegFg2Float(Ans, (char)f));
  39498. X}
  39499. X
  39500. Xextern _CMPLX tmp;
  39501. Xextern int color, colors;
  39502. Xdouble TwoPi;
  39503. X_CMPLX temp, t2, BaseLog;
  39504. X_CMPLX cdegree = { 3.0, 0.0 },
  39505. X               croot   = { 1.0, 0.0 };
  39506. X
  39507. Xint ComplexNewtonSetup(void) {
  39508. X   threshold = .001;
  39509. X   periodicitycheck = 0;
  39510. X   if(param[0] != 0.0 || param[1] != 0.0 || param[2] != 0.0 ||
  39511. X      param[3] != 0.0) {
  39512. X      croot.x = param[2];
  39513. X      croot.y = param[3];
  39514. X      cdegree.x = param[0];
  39515. X      cdegree.y = param[1];
  39516. X      FPUcplxlog(&croot, &BaseLog);
  39517. X      TwoPi = asin(1.0) * 4;
  39518. X   }
  39519. X   return(1);
  39520. X}
  39521. X
  39522. Xint ComplexNewton(void) {
  39523. X   _CMPLX cd1;
  39524. X
  39525. X   /* new = ((cdegree-1) * old**cdegree) + croot
  39526. X            ----------------------------------
  39527. X                 cdegree * old**(cdegree-1)         */
  39528. X
  39529. X   cd1.x = cdegree.x - 1.0;
  39530. X   cd1.y = cdegree.y;
  39531. X
  39532. X   temp = ComplexPower(old, cd1);
  39533. X   FPUcplxmul(&temp, &old, &new);
  39534. X
  39535. X   tmp.x = new.x - croot.x;
  39536. X   tmp.y = new.y - croot.y;
  39537. X   if((sqr(tmp.x) + sqr(tmp.y)) < threshold)
  39538. X      return(1);
  39539. X
  39540. X   FPUcplxmul(&new, &cd1, &tmp);
  39541. X   tmp.x += croot.x;
  39542. X   tmp.y += croot.y;
  39543. X
  39544. X   FPUcplxmul(&temp, &cdegree, &t2);
  39545. X   FPUcplxdiv(&tmp, &t2, &old);
  39546. X   if(DivideOverflow)
  39547. X   {
  39548. X      DivideOverflow = 0;
  39549. X      return(1);
  39550. X   }
  39551. X   new = old;
  39552. X   return(0);
  39553. X}
  39554. X
  39555. Xint ComplexBasin(void) {
  39556. X   _CMPLX cd1;
  39557. X   double mod;
  39558. X
  39559. X   /* new = ((cdegree-1) * old**cdegree) + croot
  39560. X            ----------------------------------
  39561. X                 cdegree * old**(cdegree-1)         */
  39562. X
  39563. X   cd1.x = cdegree.x - 1.0;
  39564. X   cd1.y = cdegree.y;
  39565. X
  39566. X   temp = ComplexPower(old, cd1);
  39567. X   FPUcplxmul(&temp, &old, &new);
  39568. X
  39569. X   tmp.x = new.x - croot.x;
  39570. X   tmp.y = new.y - croot.y;
  39571. X   if((sqr(tmp.x) + sqr(tmp.y)) < threshold) {
  39572. X      if(fabs(old.y) < .01)
  39573. X         old.y = 0.0;
  39574. X      FPUcplxlog(&old, &temp);
  39575. X      FPUcplxmul(&temp, &cdegree, &tmp);
  39576. X      mod = tmp.y/TwoPi;
  39577. X      color = (int)mod;
  39578. X      if(fabs(mod - color) > 0.5) {
  39579. X         if(mod < 0.0)
  39580. X            color--;
  39581. X         else
  39582. X            color++;
  39583. X      }
  39584. X      color += 2;
  39585. X      if(color < 0)
  39586. X         color += 128;
  39587. X      return(1);
  39588. X   }
  39589. X
  39590. X   FPUcplxmul(&new, &cd1, &tmp);
  39591. X   tmp.x += croot.x;
  39592. X   tmp.y += croot.y;
  39593. X
  39594. X   FPUcplxmul(&temp, &cdegree, &t2);
  39595. X   FPUcplxdiv(&tmp, &t2, &old);
  39596. X   if(DivideOverflow)
  39597. X   {
  39598. X      DivideOverflow = 0;
  39599. X      return(1);
  39600. X   }
  39601. X   new = old;
  39602. X   return(0);
  39603. X}
  39604. X
  39605. Xextern int Distribution, Offset, Slope;
  39606. Xextern long con;
  39607. X
  39608. X/*** PB, commented this out, it was unused, actual work is in prompts.c
  39609. Xint Starfield(void) {
  39610. X   int c;
  39611. X
  39612. X   plasma();
  39613. X   Distribution = (int)param[1];
  39614. X   con = (long)(param[2] / 100 * (1L << 16));
  39615. X   Slope = (int)param[3];
  39616. X   for(row = 0; row < ydots; row++) {
  39617. X      for(col = 0; col < xdots; col++) {
  39618. X         if(check_key())
  39619. X            return(-1);
  39620. X         c = getcolor(col, row);
  39621. X         putcolor(col, row, GausianNumber(c, colors));
  39622. X      }
  39623. X   }
  39624. X   return(0);
  39625. X}
  39626. X  ***/
  39627. X
  39628. X/*
  39629. X * Generate a gaussian distributed number.
  39630. X * The right half of the distribution is folded onto the lower half.
  39631. X * That is, the curve slopes up to the peak and then drops to 0.
  39632. X * The larger slope is, the smaller the standard deviation.
  39633. X * The values vary from 0+offset to range+offset, with the peak
  39634. X * at range+offset.
  39635. X * To make this more complicated, you only have a
  39636. X * 1 in Distribution*(1-Probability/Range*con)+1 chance of getting a
  39637. X * Gaussian; otherwise you just get offset.
  39638. X */
  39639. Xint GausianNumber(int Probability, int Range) {
  39640. X   int n, r;
  39641. X   long Accum = 0, p;
  39642. X
  39643. X   p = divide((long)Probability << 16, (long)Range << 16, 16);
  39644. X   p = multiply(p, con, 16);
  39645. X   p = multiply((long)Distribution << 16, p, 16);
  39646. X   if(!(rand15() % (Distribution - (int)(p >> 16) + 1))) {
  39647. X      for(n = 0; n < Slope; n++)
  39648. X         Accum += rand15();
  39649. X      Accum /= Slope;
  39650. X      r = (int)(multiply((long)Range << 15, Accum, 15) >> 14);
  39651. X      r = r - Range;
  39652. X      if(r < 0)
  39653. X         r = -r;
  39654. X      return(Range - r + Offset);
  39655. X   }
  39656. X   return(Offset);
  39657. X}
  39658. X
  39659. X#endif
  39660. SHAR_EOF
  39661. $TOUCH -am 1028230093 mpmath_c.c &&
  39662. chmod 0644 mpmath_c.c ||
  39663. echo "restore of mpmath_c.c failed"
  39664. set `wc -c mpmath_c.c`;Wc_c=$1
  39665. if test "$Wc_c" != "11132"; then
  39666.     echo original size 11132, current size $Wc_c
  39667. fi
  39668. # ============= parser.c ==============
  39669. echo "x - extracting parser.c (Text)"
  39670. sed 's/^X//' << 'SHAR_EOF' > parser.c &&
  39671. X/* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353]
  39672. X   All rights reserved.
  39673. X
  39674. X   Code may be used in any program provided the author is credited
  39675. X    either during program execution or in the documentation.  Source
  39676. X    code may be distributed only in combination with public domain or
  39677. X    shareware source code.  Source code may be modified provided the
  39678. X    copyright notice and this message is left unchanged and all
  39679. X    modifications are clearly documented.
  39680. X
  39681. X    I would appreciate a copy of any work which incorporates this code,
  39682. X    however this is optional.
  39683. X
  39684. X    Mark C. Peterson
  39685. X    405-C Queen St. Suite #181
  39686. X    Southington, CT 06489
  39687. X    (203) 276-9721
  39688. X*/
  39689. X
  39690. X/*    Chuck Ebbert (CompuServe [76306,1226] ) changed code marked 'CAE fp'    */
  39691. X/*   for fast 387 floating-point math.  See PARSERA.ASM and PARSERFP.C */
  39692. X/*   (13 Dec 1992.)  */
  39693. X/* */
  39694. X/*   Modified 12 July 1993 by CAE to fix crash when formula not found.  */
  39695. X
  39696. X#include <string.h>
  39697. X#include <ctype.h>
  39698. X#include <stdio.h>
  39699. X#include <stdlib.h>
  39700. X#include <float.h>                              /* TIW 04-22-91 */
  39701. X#include <time.h>
  39702. X#include "mpmath.h"
  39703. X#include "prototyp.h"
  39704. X
  39705. Xextern int CvtStk(void);    /* CAE fp */
  39706. Xextern int Transparent3D;                         /* MCP 5-30-91 */
  39707. X
  39708. X#ifdef WATCH_MP
  39709. Xdouble x1, y1, x2, y2;
  39710. X#endif
  39711. X
  39712. XMATH_TYPE MathType = D_MATH;
  39713. X/* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */
  39714. X
  39715. X/* PB 910417 added MAX_OPS and MAX_ARGS defines */
  39716. X#define MAX_ARGS 100
  39717. X#define MAX_OPS 250
  39718. Xstruct PEND_OP {
  39719. X   void (far *f)(void);
  39720. X   int p;
  39721. X};
  39722. X/* CAE fp added MAX_STORES and LOADS */
  39723. X#define MAX_STORES 125  /* at most only half the ops can be stores */
  39724. X#define MAX_LOADS  200  /* and 80% can be loads */
  39725. X
  39726. X/* PB 901103 made some of the following static for safety */
  39727. Xstatic struct PEND_OP far *o;
  39728. X
  39729. Xstatic void parser_allocate(void);
  39730. X
  39731. Xunion Arg *Arg1, *Arg2;
  39732. X/* PB 910417 removed unused "a" array */
  39733. X
  39734. X/* CAE fp  made some of the following non-static for PARSERA.ASM */
  39735. X/* Some of these variables should be renamed for safety */
  39736. Xunion Arg s[20], far * far *Store, far * far *Load;    /* static CAE fp */
  39737. Xint StoPtr, LodPtr, OpPtr;    /* static CAE fp */
  39738. X
  39739. Xstruct fls { /* function, load, store pointers  CAE fp */
  39740. X   void (near *function)(void);
  39741. X   union Arg near *operand;
  39742. X};
  39743. Xextern struct fls far *pfls; /* init in parserfp.c  CAE fp */
  39744. Xvoid (far * far *f)(void) = (void(far * far *)(void))0;    /* static CAE fp */
  39745. X
  39746. Xunsigned vsp, LastOp;    /* CAE fp made non-static */
  39747. Xstatic unsigned n, ErrPtr, posp, NextOp, InitN;
  39748. Xstatic int paren, SyntaxErr, ExpectingArg;
  39749. Xstruct ConstArg far *v = (struct ConstArg far *)0;    /* was static CAE fp */
  39750. Xint InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;    /* was static CAE fp */
  39751. Xstatic int Delta16;
  39752. Xdouble fgLimit;           /* TIW 05-04-91 */
  39753. Xstatic double fg;
  39754. Xstatic int ShiftBack;     /* TIW 06-18-90 */
  39755. Xstatic int SetRandom;     /* MCP 11-21-91 */
  39756. Xstatic int Randomized;
  39757. Xstatic unsigned long RandNum;
  39758. X
  39759. Xextern int bitshift;
  39760. Xextern int bitshiftless1;
  39761. Xextern int symmetry;          /* symmetry flag for calcmand()  */
  39762. Xextern double param[];
  39763. X
  39764. Xextern int debugflag;         /* BDT for debugging */
  39765. Xextern char boxx[8192];       /* PB 4-9-91, good place for the formula string */
  39766. Xextern int row, col, overflow, cpu, fpu;
  39767. Xextern _CMPLX old, new;
  39768. Xextern double far *dx0, far *dy0;
  39769. Xextern long far *lx0, far *ly0;     /* BDT moved these to FAR */
  39770. X
  39771. X#ifndef TESTING_MATH
  39772. Xextern double far *dx1, far *dy1;
  39773. Xextern long far *lx1, far *ly1;
  39774. X#define dShiftx dx1[row]
  39775. X#define dShifty dy1[col]
  39776. X#define lShiftx lx1[row]
  39777. X#define lShifty ly1[col]
  39778. X#else
  39779. X#define dShiftx 0.0
  39780. X#define dShifty 0.0
  39781. X#define lShiftx 0L
  39782. X#define lShifty 0L
  39783. X#endif
  39784. X
  39785. Xextern _LCMPLX lold, lnew;
  39786. Xextern char FormName[];
  39787. X
  39788. Xextern VOIDFARPTR typespecific_workarea;
  39789. X
  39790. X#define LastSqr v[4].a
  39791. X
  39792. Xstatic char far * far ErrStrings[] = {   /* TIW 03-31-91 added far */
  39793. X   "Should be an Argument",
  39794. X   "Should be an Operator",
  39795. X   "')' needs a matching '('",
  39796. X   "Need more ')'",
  39797. X   "Undefined Operator",
  39798. X   "Undefined Function",
  39799. X   "More than one ','",
  39800. X   "Table overflow"
  39801. X};
  39802. X
  39803. Xunsigned SkipWhiteSpace(char *Str) {
  39804. X   unsigned n, Done;
  39805. X
  39806. X   for(Done = n = 0; !Done; n++) {
  39807. X      switch(Str[n]) {
  39808. X      case ' ':
  39809. X      case '\t':
  39810. X      case '\n':
  39811. X      case '\r':
  39812. X         break;
  39813. X      default:
  39814. X         Done = 1;
  39815. X      }
  39816. X   }
  39817. X   return(n - 1);
  39818. X}
  39819. X
  39820. X/* Random number code, MCP 11-21-91 */
  39821. X
  39822. Xunsigned long NewRandNum(void)
  39823. X{
  39824. X   return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum);
  39825. X}
  39826. X
  39827. Xvoid lRandom(void)
  39828. X{
  39829. X   v[7].a.l.x = NewRandNum() >> (32 - bitshift);
  39830. X   v[7].a.l.y = NewRandNum() >> (32 - bitshift);
  39831. X}
  39832. X
  39833. Xvoid dRandom(void)
  39834. X{
  39835. X   long x, y;
  39836. X
  39837. X   /* Use the same algorithm as for fixed math so that they will generate
  39838. X      the same fractals when the srand() function is used. */
  39839. X   x = NewRandNum() >> (32 - bitshift);
  39840. X   y = NewRandNum() >> (32 - bitshift);
  39841. X   v[7].a.d.x = ((double)x / (1L << bitshift));
  39842. X   v[7].a.d.y = ((double)y / (1L << bitshift));
  39843. X}
  39844. X
  39845. X#ifndef XFRACT
  39846. Xvoid mRandom(void)
  39847. X{
  39848. X   long x, y;
  39849. X
  39850. X   /* Use the same algorithm as for fixed math so that they will generate
  39851. X      the same fractals when the srand() function is used. */
  39852. X   x = NewRandNum() >> (32 - bitshift);
  39853. X   y = NewRandNum() >> (32 - bitshift);
  39854. X   v[7].a.m.x = *fg2MP(x, bitshift);
  39855. X   v[7].a.m.y = *fg2MP(y, bitshift);
  39856. X}
  39857. X#endif
  39858. X
  39859. Xvoid SetRandFnct(void)
  39860. X{
  39861. X   unsigned Seed;
  39862. X
  39863. X   if(!SetRandom)
  39864. X      RandNum = Arg1->l.x ^ Arg1->l.y;
  39865. X
  39866. X   Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16);
  39867. X   srand(Seed);
  39868. X   SetRandom = 1;
  39869. X
  39870. X   /* Clear out the seed */
  39871. X   NewRandNum();
  39872. X   NewRandNum();
  39873. X   NewRandNum();
  39874. X}
  39875. X
  39876. Xvoid RandomSeed(void)
  39877. X{
  39878. X   time_t ltime;
  39879. X
  39880. X   /* Use the current time to randomize the random number sequence. */
  39881. X   time(<ime);
  39882. X   srand((unsigned int)ltime);
  39883. X
  39884. X   NewRandNum();
  39885. X   NewRandNum();
  39886. X   NewRandNum();
  39887. X   Randomized = 1;
  39888. X}
  39889. X
  39890. X#ifndef XFRACT
  39891. Xvoid lStkSRand(void)
  39892. X{
  39893. X   SetRandFnct();
  39894. X   lRandom();
  39895. X   Arg1->l = v[7].a.l;
  39896. X}
  39897. X#endif
  39898. X
  39899. X#ifndef XFRACT
  39900. Xvoid mStkSRand(void)
  39901. X{
  39902. X   Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp;
  39903. X   Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp;
  39904. X   SetRandFnct();
  39905. X   mRandom();
  39906. X   Arg1->m = v[7].a.m;
  39907. X}
  39908. X#endif
  39909. X
  39910. Xvoid dStkSRand(void)
  39911. X{
  39912. X   Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift));
  39913. X   Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift));
  39914. X   SetRandFnct();
  39915. X   dRandom();
  39916. X   Arg1->d = v[7].a.d;
  39917. X}
  39918. X
  39919. Xvoid (*StkSRand)(void) = dStkSRand;
  39920. X
  39921. Xvoid dStkAbs(void) {
  39922. X   Arg1->d.x = fabs(Arg1->d.x);
  39923. X   Arg1->d.y = fabs(Arg1->d.y);
  39924. X}
  39925. X
  39926. X#ifndef XFRACT
  39927. Xvoid mStkAbs(void) {
  39928. X   if(Arg1->m.x.Exp < 0)
  39929. X      Arg1->m.x.Exp = -Arg1->m.x.Exp;
  39930. X   if(Arg1->m.y.Exp < 0)
  39931. X      Arg1->m.y.Exp = -Arg1->m.y.Exp;
  39932. X}
  39933. X
  39934. Xvoid lStkAbs(void) {
  39935. X   Arg1->l.x = labs(Arg1->l.x);
  39936. X   Arg1->l.y = labs(Arg1->l.y);
  39937. X}
  39938. X#endif
  39939. X
  39940. Xvoid (*StkAbs)(void) = dStkAbs;
  39941. X
  39942. Xvoid dStkSqr(void) {
  39943. X   LastSqr.d.x = Arg1->d.x * Arg1->d.x;
  39944. X   LastSqr.d.y = Arg1->d.y * Arg1->d.y;
  39945. X   Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0;
  39946. X   Arg1->d.x = LastSqr.d.x - LastSqr.d.y;
  39947. X   LastSqr.d.x += LastSqr.d.y;
  39948. X   LastSqr.d.y = 0;
  39949. X}
  39950. X
  39951. X#ifndef XFRACT
  39952. Xvoid mStkSqr(void) {
  39953. X   LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x);
  39954. X   LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y);
  39955. X   Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y);
  39956. X   Arg1->m.y.Exp++;
  39957. X   Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y);
  39958. X   LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y);
  39959. X   LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0);
  39960. X}
  39961. X
  39962. Xvoid lStkSqr(void) {
  39963. X   LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift);
  39964. X   LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift);
  39965. X   Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1;
  39966. X   Arg1->l.x = LastSqr.l.x - LastSqr.l.y;
  39967. X   LastSqr.l.x += LastSqr.l.y;
  39968. X   LastSqr.l.y = 0L;
  39969. X}
  39970. X#endif
  39971. X
  39972. Xvoid (*StkSqr)(void) = dStkSqr;
  39973. X
  39974. Xvoid dStkAdd(void) {
  39975. X   Arg2->d.x += Arg1->d.x;
  39976. X   Arg2->d.y += Arg1->d.y;
  39977. X   Arg1--;
  39978. X   Arg2--;
  39979. X}
  39980. X
  39981. X#ifndef XFRACT
  39982. Xvoid mStkAdd(void) {
  39983. X   Arg2->m = MPCadd(Arg2->m, Arg1->m);
  39984. X   Arg1--;
  39985. X   Arg2--;
  39986. X}
  39987. X
  39988. Xvoid lStkAdd(void) {
  39989. X   Arg2->l.x += Arg1->l.x;
  39990. X   Arg2->l.y += Arg1->l.y;
  39991. X   Arg1--;
  39992. X   Arg2--;
  39993. X}
  39994. X#endif
  39995. X
  39996. Xvoid (*StkAdd)(void) = dStkAdd;
  39997. X
  39998. Xvoid dStkSub(void) {
  39999. X   Arg2->d.x -= Arg1->d.x;
  40000. X   Arg2->d.y -= Arg1->d.y;
  40001. X   Arg1--;
  40002. X   Arg2--;
  40003. X}
  40004. X
  40005. X#ifndef XFRACT
  40006. Xvoid mStkSub(void) {
  40007. X   Arg2->m = MPCsub(Arg2->m, Arg1->m);
  40008. X   Arg1--;
  40009. X   Arg2--;
  40010. X}
  40011. X
  40012. Xvoid lStkSub(void) {
  40013. X   Arg2->l.x -= Arg1->l.x;
  40014. X   Arg2->l.y -= Arg1->l.y;
  40015. X   Arg1--;
  40016. X   Arg2--;
  40017. X}
  40018. X#endif
  40019. X
  40020. Xvoid (*StkSub)(void) = dStkSub;
  40021. X
  40022. Xvoid dStkConj(void) {
  40023. X   Arg1->d.y = -Arg1->d.y;
  40024. X}
  40025. X
  40026. X#ifndef XFRACT
  40027. Xvoid mStkConj(void) {
  40028. X   Arg1->m.y.Exp ^= 0x8000;
  40029. X}
  40030. X
  40031. Xvoid lStkConj(void) {
  40032. X   Arg1->l.y = -Arg1->l.y;
  40033. X}
  40034. X#endif
  40035. X
  40036. Xvoid dStkZero(void) {
  40037. X   Arg1->d.y = Arg1->d.x = 0.0;
  40038. X}
  40039. X
  40040. X#ifndef XFRACT
  40041. Xvoid mStkZero(void) {
  40042. X   Arg1->m.x.Mant = Arg1->m.x.Exp = 0;
  40043. X   Arg1->m.y.Mant = Arg1->m.y.Exp = 0;
  40044. X}
  40045. X
  40046. Xvoid lStkZero(void) {
  40047. X   Arg1->l.y = Arg1->l.x = 0.0;
  40048. X}
  40049. X#endif
  40050. X
  40051. Xvoid (*StkConj)(void) = dStkConj;
  40052. X
  40053. Xvoid dStkReal(void) {
  40054. X   Arg1->d.y = 0.0;
  40055. X}
  40056. X
  40057. X#ifndef XFRACT
  40058. Xvoid mStkReal(void) {
  40059. X   Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  40060. X}
  40061. X
  40062. Xvoid lStkReal(void) {
  40063. X   Arg1->l.y = 0l;
  40064. X}
  40065. X#endif
  40066. X
  40067. Xvoid (*StkReal)(void) = dStkReal;
  40068. X
  40069. Xvoid dStkImag(void) {
  40070. X   Arg1->d.x = Arg1->d.y;
  40071. X   Arg1->d.y = 0.0;
  40072. X}
  40073. X
  40074. X#ifndef XFRACT
  40075. Xvoid mStkImag(void) {
  40076. X   Arg1->m.x = Arg1->m.y;
  40077. X   Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  40078. X}
  40079. X
  40080. Xvoid lStkImag(void) {
  40081. X   Arg1->l.x = Arg1->l.y;
  40082. X   Arg1->l.y = 0l;
  40083. X}
  40084. X#endif
  40085. X
  40086. Xvoid (*StkImag)(void) = dStkImag;
  40087. X
  40088. Xvoid dStkNeg(void) {
  40089. X   Arg1->d.x = -Arg1->d.x;
  40090. X   Arg1->d.y = -Arg1->d.y;
  40091. X}
  40092. X
  40093. X#ifndef XFRACT
  40094. Xvoid mStkNeg(void) {
  40095. X   Arg1->m.x.Exp ^= 0x8000;
  40096. X   Arg1->m.y.Exp ^= 0x8000;
  40097. X}
  40098. X
  40099. Xvoid lStkNeg(void) {
  40100. X   Arg1->l.x = -Arg1->l.x;
  40101. X   Arg1->l.y = -Arg1->l.y;
  40102. X}
  40103. X#endif
  40104. X
  40105. Xvoid (*StkNeg)(void) = dStkNeg;
  40106. X
  40107. Xvoid dStkMul(void) {
  40108. X   FPUcplxmul(&Arg2->d, &Arg1->d, &Arg2->d);
  40109. X   Arg1--;
  40110. X   Arg2--;
  40111. X}
  40112. X
  40113. X#ifndef XFRACT
  40114. Xvoid mStkMul(void) {
  40115. X   Arg2->m = MPCmul(Arg2->m, Arg1->m);
  40116. X   Arg1--;
  40117. X   Arg2--;
  40118. X}
  40119. X
  40120. Xvoid lStkMul(void) {
  40121. X   long x, y;
  40122. X
  40123. X   x = multiply(Arg2->l.x, Arg1->l.x, bitshift) -
  40124. X   multiply(Arg2->l.y, Arg1->l.y, bitshift);
  40125. X   y = multiply(Arg2->l.y, Arg1->l.x, bitshift) +
  40126. X   multiply(Arg2->l.x, Arg1->l.y, bitshift);
  40127. X   Arg2->l.x = x;
  40128. X   Arg2->l.y = y;
  40129. X   Arg1--;
  40130. X   Arg2--;
  40131. X}
  40132. X#endif
  40133. X
  40134. Xvoid (*StkMul)(void) = dStkMul;
  40135. X
  40136. Xvoid dStkDiv(void) {
  40137. X   FPUcplxdiv(&Arg2->d, &Arg1->d, &Arg2->d);
  40138. X   Arg1--;
  40139. X   Arg2--;
  40140. X}
  40141. X
  40142. X#ifndef XFRACT
  40143. Xvoid mStkDiv(void) {
  40144. X   Arg2->m = MPCdiv(Arg2->m, Arg1->m);
  40145. X   Arg1--;
  40146. X   Arg2--;
  40147. X}
  40148. X
  40149. Xvoid lStkDiv(void) {
  40150. X   long x, y, mod, x2, y2;
  40151. X
  40152. X   mod = multiply(Arg1->l.x, Arg1->l.x, bitshift) +
  40153. X   multiply(Arg1->l.y, Arg1->l.y, bitshift);
  40154. X   x = divide(Arg1->l.x, mod, bitshift);
  40155. X   y = -divide(Arg1->l.y, mod, bitshift);
  40156. X   /* pb 900617 changed next 4 lines to use x2,y2 instead of x,y */
  40157. X   x2 = multiply(Arg2->l.x, x, bitshift) - multiply(Arg2->l.y, y, bitshift);
  40158. X   y2 = multiply(Arg2->l.y, x, bitshift) + multiply(Arg2->l.x, y, bitshift);
  40159. X   Arg2->l.x = x2;
  40160. X   Arg2->l.y = y2;
  40161. X   Arg1--;
  40162. X   Arg2--;
  40163. X}
  40164. X#endif
  40165. X
  40166. Xvoid (*StkDiv)(void) = dStkDiv;
  40167. X
  40168. Xvoid StkSto(void) {
  40169. X   *Store[StoPtr++] = *Arg1;
  40170. X}
  40171. X
  40172. Xvoid StkLod(void) {
  40173. X   Arg1++;
  40174. X   Arg2++;
  40175. X   *Arg1 = *Load[LodPtr++];
  40176. X}
  40177. X
  40178. Xvoid dStkMod(void) {
  40179. X   Arg1->d.x = (Arg1->d.x * Arg1->d.x) + (Arg1->d.y * Arg1->d.y);
  40180. X   Arg1->d.y = 0.0;
  40181. X}
  40182. X
  40183. X#ifndef XFRACT
  40184. Xvoid mStkMod(void) {
  40185. X   Arg1->m.x = MPCmod(Arg1->m);
  40186. X   Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  40187. X}
  40188. X
  40189. Xvoid lStkMod(void) {
  40190. X   Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) +
  40191. X   multiply(Arg2->l.y, Arg1->l.y, bitshift);
  40192. X   if(Arg1->l.x < 0)
  40193. X      overflow = 1;
  40194. X   Arg1->l.y = 0L;
  40195. X}
  40196. X#endif
  40197. X
  40198. Xvoid (*StkMod)(void) = dStkMod;
  40199. X
  40200. Xvoid StkClr(void) {
  40201. X   s[0] = *Arg1;
  40202. X   Arg1 = &s[0];
  40203. X   Arg2 = Arg1;
  40204. X   Arg2--;
  40205. X}
  40206. X
  40207. X
  40208. X/* MCP 4-9-91, Added Flip() */
  40209. X
  40210. Xvoid dStkFlip(void) {
  40211. X   double t;
  40212. X
  40213. X   t = Arg1->d.x;
  40214. X   Arg1->d.x = Arg1->d.y;
  40215. X   Arg1->d.y = t;
  40216. X}
  40217. X
  40218. X#ifndef XFRACT
  40219. Xvoid mStkFlip(void) {
  40220. X   struct MP t;
  40221. X
  40222. X   t = Arg1->m.x;
  40223. X   Arg1->m.x = Arg1->m.y;
  40224. X   Arg1->m.y = t;
  40225. X}
  40226. X
  40227. Xvoid lStkFlip(void) {
  40228. X   long t;
  40229. X
  40230. X   t = Arg1->l.x;
  40231. X   Arg1->l.x = Arg1->l.y;
  40232. X   Arg1->l.y = t;
  40233. X}
  40234. X#endif
  40235. X
  40236. Xvoid (*StkFlip)(void) = dStkFlip;
  40237. X
  40238. Xvoid dStkSin(void) {
  40239. X   double sinx, cosx, sinhy, coshy;
  40240. X
  40241. X   FPUsincos(&Arg1->d.x, &sinx, &cosx);
  40242. X   FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  40243. X   Arg1->d.x = sinx*coshy;
  40244. X   Arg1->d.y = cosx*sinhy;
  40245. X}
  40246. X
  40247. X#ifndef XFRACT
  40248. Xvoid mStkSin(void) {
  40249. X   Arg1->d = MPC2cmplx(Arg1->m);
  40250. X   dStkSin();
  40251. X   Arg1->m = cmplx2MPC(Arg1->d);
  40252. X}
  40253. X
  40254. Xvoid lStkSin(void) {
  40255. X   long x, y, sinx, cosx, sinhy, coshy;
  40256. X   x = Arg1->l.x >> Delta16;
  40257. X   y = Arg1->l.y >> Delta16;
  40258. X   SinCos086(x, &sinx, &cosx);
  40259. X   SinhCosh086(y, &sinhy, &coshy);
  40260. X   Arg1->l.x = multiply(sinx, coshy, ShiftBack); /* TIW 06-18-90 */
  40261. X   Arg1->l.y = multiply(cosx, sinhy, ShiftBack); /* TIW 06-18-90 */
  40262. X}
  40263. X#endif
  40264. X
  40265. Xvoid (*StkSin)(void) = dStkSin;
  40266. X
  40267. X/* The following functions are supported by both the parser and for fn
  40268. X   variable replacement. TIW 04-22-91 */
  40269. X
  40270. Xvoid dStkTan(void) {
  40271. X   double sinx, cosx, sinhy, coshy, denom;
  40272. X   Arg1->d.x *= 2;
  40273. X   Arg1->d.y *= 2;
  40274. X   FPUsincos(&Arg1->d.x, &sinx, &cosx);
  40275. X   FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  40276. X   denom = cosx + coshy;
  40277. X   if(fabs(denom) <= DBL_MIN) return;
  40278. X   Arg1->d.x = sinx/denom;
  40279. X   Arg1->d.y = sinhy/denom;
  40280. X}
  40281. X
  40282. X#ifndef XFRACT
  40283. Xvoid mStkTan(void) {
  40284. X   Arg1->d = MPC2cmplx(Arg1->m);
  40285. X   dStkTan();
  40286. X   Arg1->m = cmplx2MPC(Arg1->d);
  40287. X}
  40288. X
  40289. Xvoid lStkTan(void) {
  40290. X   long x, y, sinx, cosx, sinhy, coshy, denom;
  40291. X   x = Arg1->l.x >> Delta16;
  40292. X   x = x << 1;
  40293. X   y = Arg1->l.y >> Delta16;
  40294. X   y = y << 1;
  40295. X   SinCos086(x, &sinx, &cosx);
  40296. X   SinhCosh086(y, &sinhy, &coshy);
  40297. X   denom = cosx + coshy;
  40298. X   if(denom == 0) return;
  40299. X   Arg1->l.x = divide(sinx,denom,bitshift);
  40300. X   Arg1->l.y = divide(sinhy,denom,bitshift);
  40301. X}
  40302. X#endif
  40303. X
  40304. Xvoid (*StkTan)(void) = dStkTan;
  40305. X
  40306. Xvoid dStkTanh(void) {
  40307. X   double siny, cosy, sinhx, coshx, denom;
  40308. X   Arg1->d.x *= 2;
  40309. X   Arg1->d.y *= 2;
  40310. X   FPUsincos(&Arg1->d.y, &siny, &cosy);
  40311. X   FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  40312. X   denom = coshx + cosy;
  40313. X   if(fabs(denom) <= DBL_MIN) return;
  40314. X   Arg1->d.x = sinhx/denom;
  40315. X   Arg1->d.y = siny/denom;
  40316. X}
  40317. X
  40318. X#ifndef XFRACT
  40319. Xvoid mStkTanh(void) {
  40320. X   Arg1->d = MPC2cmplx(Arg1->m);
  40321. X   dStkTanh();
  40322. X   Arg1->m = cmplx2MPC(Arg1->d);
  40323. X}
  40324. X
  40325. Xvoid lStkTanh(void) {
  40326. X   long x, y, siny, cosy, sinhx, coshx, denom;
  40327. X   x = Arg1->l.x >> Delta16;
  40328. X   x = x << 1;
  40329. X   y = Arg1->l.y >> Delta16;
  40330. X   y = y << 1;
  40331. X   SinCos086(y, &siny, &cosy);
  40332. X   SinhCosh086(x, &sinhx, &coshx);
  40333. X   denom = coshx + cosy;
  40334. X   if(denom == 0) return;
  40335. X   Arg1->l.x = divide(sinhx,denom,bitshift);
  40336. X   Arg1->l.y = divide(siny,denom,bitshift);
  40337. X}
  40338. X#endif
  40339. X
  40340. Xvoid (*StkTanh)(void) = dStkTanh;
  40341. X
  40342. Xvoid dStkCoTan(void) {
  40343. X   double sinx, cosx, sinhy, coshy, denom;
  40344. X   Arg1->d.x *= 2;
  40345. X   Arg1->d.y *= 2;
  40346. X   FPUsincos(&Arg1->d.x, &sinx, &cosx);
  40347. X   FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  40348. X   denom = coshy - cosx;
  40349. X   if(fabs(denom) <= DBL_MIN) return;
  40350. X   Arg1->d.x = sinx/denom;
  40351. X   Arg1->d.y = -sinhy/denom;
  40352. X}
  40353. X
  40354. X#ifndef XFRACT
  40355. Xvoid mStkCoTan(void) {
  40356. X   Arg1->d = MPC2cmplx(Arg1->m);
  40357. X   dStkCoTan();
  40358. X   Arg1->m = cmplx2MPC(Arg1->d);
  40359. X}
  40360. X
  40361. Xvoid lStkCoTan(void) {
  40362. X   long x, y, sinx, cosx, sinhy, coshy, denom;
  40363. X   x = Arg1->l.x >> Delta16;
  40364. X   x = x << 1;
  40365. X   y = Arg1->l.y >> Delta16;
  40366. X   y = y << 1;
  40367. X   SinCos086(x, &sinx, &cosx);
  40368. X   SinhCosh086(y, &sinhy, &coshy);
  40369. X   denom = coshy - cosx;
  40370. X   if(denom == 0) return;
  40371. X   Arg1->l.x = divide(sinx,denom,bitshift);
  40372. X   Arg1->l.y = -divide(sinhy,denom,bitshift);
  40373. X}
  40374. X#endif
  40375. X
  40376. Xvoid (*StkCoTan)(void) = dStkCoTan;
  40377. X
  40378. Xvoid dStkCoTanh(void) {
  40379. X   double siny, cosy, sinhx, coshx, denom;
  40380. X   Arg1->d.x *= 2;
  40381. X   Arg1->d.y *= 2;
  40382. X   FPUsincos(&Arg1->d.y, &siny, &cosy);
  40383. X   FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  40384. X   denom = coshx - cosy;
  40385. X   if(fabs(denom) <= DBL_MIN) return;
  40386. X   Arg1->d.x = sinhx/denom;
  40387. X   Arg1->d.y = -siny/denom;
  40388. X}
  40389. X
  40390. X#ifndef XFRACT
  40391. Xvoid mStkCoTanh(void) {
  40392. X   Arg1->d = MPC2cmplx(Arg1->m);
  40393. X   dStkCoTanh();
  40394. X   Arg1->m = cmplx2MPC(Arg1->d);
  40395. X}
  40396. X
  40397. Xvoid lStkCoTanh(void) {
  40398. X   long x, y, siny, cosy, sinhx, coshx, denom;
  40399. X   x = Arg1->l.x >> Delta16;
  40400. X   x = x << 1;
  40401. X   y = Arg1->l.y >> Delta16;
  40402. X   y = y << 1;
  40403. X   SinCos086(y, &siny, &cosy);
  40404. X   SinhCosh086(x, &sinhx, &coshx);
  40405. X   denom = coshx - cosy;
  40406. X   if(denom == 0) return;
  40407. X   Arg1->l.x = divide(sinhx,denom,bitshift);
  40408. X   Arg1->l.y = -divide(siny,denom,bitshift);
  40409. X}
  40410. X#endif
  40411. X
  40412. Xvoid (*StkCoTanh)(void) = dStkCoTanh;
  40413. X
  40414. X/* The following functions are not directly used by the parser - support
  40415. X   for the parser was not provided because the existing parser language
  40416. X   represents these quite easily. They are used for fn variable support
  40417. X   in miscres.c but are placed here because they follow the pattern of
  40418. X   the other parser functions. TIW 04-22-91 */
  40419. X
  40420. Xvoid dStkRecip(void) {
  40421. X   double mod;
  40422. X   mod =Arg1->d.x * Arg1->d.x + Arg1->d.y * Arg1->d.y;
  40423. X   if(mod <= DBL_MIN) return;
  40424. X   Arg1->d.x =  Arg1->d.x/mod;
  40425. X   Arg1->d.y = -Arg1->d.y/mod;
  40426. X}
  40427. X
  40428. X#ifndef XFRACT
  40429. Xvoid mStkRecip(void) {
  40430. X   struct MP mod;
  40431. X   mod = *MPadd(*MPmul(Arg1->m.x, Arg1->m.x),*MPmul(Arg1->m.y, Arg1->m.y));
  40432. X   if(mod.Mant <= 0L) return;
  40433. X   Arg1->m.x = *MPdiv(Arg1->m.x,mod);
  40434. X   Arg1->m.y = *MPdiv(Arg1->m.y,mod);
  40435. X   Arg1->m.y.Exp ^= 0x8000;
  40436. X}
  40437. X
  40438. Xvoid lStkRecip(void) {
  40439. X   long mod;
  40440. X   mod = multiply(Arg1->l.x,Arg1->l.x,bitshift)
  40441. X      + multiply(Arg1->l.y,Arg1->l.y,bitshift);
  40442. X   if(mod<=0L) return;
  40443. X   Arg1->l.x =  divide(Arg1->l.x,mod,bitshift);
  40444. X   Arg1->l.y = -divide(Arg1->l.y,mod,bitshift);
  40445. X}
  40446. X#endif
  40447. X
  40448. Xvoid StkIdent(void) { /* do nothing - the function Z */
  40449. X}
  40450. X/* End TIW 04-22-91 */
  40451. X
  40452. Xvoid dStkSinh(void) {
  40453. X   double siny, cosy, sinhx, coshx;
  40454. X
  40455. X   FPUsincos(&Arg1->d.y, &siny, &cosy);
  40456. X   FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  40457. X   Arg1->d.x = sinhx*cosy;
  40458. X   Arg1->d.y = coshx*siny;
  40459. X}
  40460. X
  40461. X#ifndef XFRACT
  40462. Xvoid mStkSinh(void) {
  40463. X   Arg1->d = MPC2cmplx(Arg1->m);
  40464. X   dStkSinh();
  40465. X   Arg1->m = cmplx2MPC(Arg1->d);
  40466. X}
  40467. X
  40468. Xvoid lStkSinh(void) {
  40469. X   long x, y, sinhx, coshx, siny, cosy;
  40470. X
  40471. X   x = Arg1->l.x >> Delta16;
  40472. X   y = Arg1->l.y >> Delta16;
  40473. X   SinCos086(y, &siny, &cosy);
  40474. X   SinhCosh086(x, &sinhx, &coshx);
  40475. X   Arg1->l.x = multiply(cosy, sinhx, ShiftBack); /* TIW 06-18-90 */
  40476. X   Arg1->l.y = multiply(siny, coshx, ShiftBack); /* TIW 06-18-90 */
  40477. X}
  40478. X#endif
  40479. X
  40480. Xvoid (*StkSinh)(void) = dStkSinh;
  40481. X
  40482. Xvoid dStkCos(void) {
  40483. X   double sinx, cosx, sinhy, coshy;
  40484. X
  40485. X   FPUsincos(&Arg1->d.x, &sinx, &cosx);
  40486. X   FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  40487. X   Arg1->d.x = cosx*coshy;
  40488. X   Arg1->d.y = -sinx*sinhy; /* TIW 04-25-91 sign */
  40489. X}
  40490. X
  40491. X#ifndef XFRACT
  40492. Xvoid mStkCos(void) {
  40493. X   Arg1->d = MPC2cmplx(Arg1->m);
  40494. X   dStkCos();
  40495. X   Arg1->m = cmplx2MPC(Arg1->d);
  40496. X}
  40497. X
  40498. Xvoid lStkCos(void) {
  40499. X   long x, y, sinx, cosx, sinhy, coshy;
  40500. X
  40501. X   x = Arg1->l.x >> Delta16;
  40502. X   y = Arg1->l.y >> Delta16;
  40503. X   SinCos086(x, &sinx, &cosx);
  40504. X   SinhCosh086(y, &sinhy, &coshy);
  40505. X   Arg1->l.x = multiply(cosx, coshy, ShiftBack); /* TIW 06-18-90 */
  40506. X   Arg1->l.y = -multiply(sinx, sinhy, ShiftBack); /* TIW 04-25-91 sign */
  40507. X}
  40508. X#endif
  40509. X
  40510. Xvoid (*StkCos)(void) = dStkCos;
  40511. X
  40512. X/* Bogus version of cos, to replicate bug which was in regular cos till v16: */
  40513. X
  40514. Xvoid dStkCosXX(void) {
  40515. X   dStkCos();
  40516. X   Arg1->d.y = -Arg1->d.y;
  40517. X}
  40518. X
  40519. X#ifndef XFRACT
  40520. Xvoid mStkCosXX(void) {
  40521. X   Arg1->d = MPC2cmplx(Arg1->m);
  40522. X   dStkCosXX();
  40523. X   Arg1->m = cmplx2MPC(Arg1->d);
  40524. X}
  40525. X
  40526. Xvoid lStkCosXX(void) {
  40527. X   lStkCos();
  40528. X   Arg1->l.y = -Arg1->l.y;
  40529. X}
  40530. X#endif
  40531. X
  40532. Xvoid (*StkCosXX)(void) = dStkCosXX;
  40533. X
  40534. Xvoid dStkCosh(void) {
  40535. X   double siny, cosy, sinhx, coshx;
  40536. X
  40537. X   FPUsincos(&Arg1->d.y, &siny, &cosy);
  40538. X   FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  40539. X   Arg1->d.x = coshx*cosy;
  40540. X   Arg1->d.y = sinhx*siny;
  40541. X}
  40542. X
  40543. X#ifndef XFRACT
  40544. Xvoid mStkCosh(void) {
  40545. X   Arg1->d = MPC2cmplx(Arg1->m);
  40546. X   dStkCosh();
  40547. X   Arg1->m = cmplx2MPC(Arg1->d);
  40548. X}
  40549. X
  40550. Xvoid lStkCosh(void) {
  40551. X   long x, y, sinhx, coshx, siny, cosy;
  40552. X
  40553. X   x = Arg1->l.x >> Delta16;
  40554. X   y = Arg1->l.y >> Delta16;
  40555. X   SinCos086(y, &siny, &cosy);
  40556. X   SinhCosh086(x, &sinhx, &coshx);
  40557. X   Arg1->l.x = multiply(cosy, coshx, ShiftBack); /* TIW 06-18-90 */
  40558. X   Arg1->l.y = multiply(siny, sinhx, ShiftBack); /* TIW 06-18-90 */
  40559. X}
  40560. X#endif
  40561. X
  40562. Xvoid (*StkCosh)(void) = dStkCosh;
  40563. X
  40564. Xvoid dStkLT(void) {
  40565. X   Arg2->d.x = (double)(Arg2->d.x < Arg1->d.x);
  40566. X   Arg2->d.y = 0.0;
  40567. X   Arg1--;
  40568. X   Arg2--;
  40569. X}
  40570. X
  40571. X#ifndef XFRACT
  40572. Xvoid mStkLT(void) {
  40573. X   Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == -1), 0);
  40574. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40575. X   Arg1--;
  40576. X   Arg2--;
  40577. X}
  40578. X
  40579. Xvoid lStkLT(void) {
  40580. X   Arg2->l.x = Arg2->l.x < Arg1->l.x;
  40581. X   Arg2->l.y = 0l;
  40582. X   Arg1--;
  40583. X   Arg2--;
  40584. X}
  40585. X#endif
  40586. X
  40587. Xvoid (*StkLT)(void) = dStkLT;
  40588. X
  40589. Xvoid dStkGT(void) {
  40590. X   Arg2->d.x = (double)(Arg2->d.x > Arg1->d.x);
  40591. X   Arg2->d.y = 0.0;
  40592. X   Arg1--;
  40593. X   Arg2--;
  40594. X}
  40595. X
  40596. X#ifndef XFRACT
  40597. Xvoid mStkGT(void) {
  40598. X   Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == 1), 0);
  40599. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40600. X   Arg1--;
  40601. X   Arg2--;
  40602. X}
  40603. X
  40604. Xvoid lStkGT(void) {
  40605. X   Arg2->l.x = Arg2->l.x > Arg1->l.x;
  40606. X   Arg2->l.y = 0l;
  40607. X   Arg1--;
  40608. X   Arg2--;
  40609. X}
  40610. X#endif
  40611. X
  40612. Xvoid (*StkGT)(void) = dStkGT;
  40613. X
  40614. Xvoid dStkLTE(void) {
  40615. X   Arg2->d.x = (double)(Arg2->d.x <= Arg1->d.x);
  40616. X   Arg2->d.y = 0.0;
  40617. X   Arg1--;
  40618. X   Arg2--;
  40619. X}
  40620. X
  40621. X#ifndef XFRACT
  40622. Xvoid mStkLTE(void) {
  40623. X   int comp;
  40624. X
  40625. X   comp = MPcmp(Arg2->m.x, Arg1->m.x);
  40626. X   Arg2->m.x = *fg2MP((long)(comp == -1 || comp == 0), 0);
  40627. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40628. X   Arg1--;
  40629. X   Arg2--;
  40630. X}
  40631. X
  40632. Xvoid lStkLTE(void) {
  40633. X   Arg2->l.x = Arg2->l.x <= Arg1->l.x;
  40634. X   Arg2->l.y = 0l;
  40635. X   Arg1--;
  40636. X   Arg2--;
  40637. X}
  40638. X#endif
  40639. X
  40640. Xvoid (*StkLTE)(void) = dStkLTE;
  40641. X
  40642. Xvoid dStkGTE(void) {
  40643. X   Arg2->d.x = (double)(Arg2->d.x >= Arg1->d.x);
  40644. X   Arg2->d.y = 0.0;
  40645. X   Arg1--;
  40646. X   Arg2--;
  40647. X}
  40648. X
  40649. X#ifndef XFRACT
  40650. Xvoid mStkGTE(void) {
  40651. X   int comp;
  40652. X
  40653. X   comp = MPcmp(Arg2->m.x, Arg1->m.x);
  40654. X   Arg2->m.x = *fg2MP((long)(comp == 1 || comp == 0), 0);
  40655. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40656. X   Arg1--;
  40657. X   Arg2--;
  40658. X}
  40659. X
  40660. Xvoid lStkGTE(void) {
  40661. X   Arg2->l.x = Arg2->l.x >= Arg1->l.x;
  40662. X   Arg2->l.y = 0l;
  40663. X   Arg1--;
  40664. X   Arg2--;
  40665. X}
  40666. X#endif
  40667. X
  40668. Xvoid (*StkGTE)(void) = dStkGTE;
  40669. X
  40670. Xvoid dStkEQ(void) {
  40671. X   Arg2->d.x = (double)(Arg2->d.x == Arg1->d.x);
  40672. X   Arg2->d.y = 0.0;
  40673. X   Arg1--;
  40674. X   Arg2--;
  40675. X}
  40676. X
  40677. X#ifndef XFRACT
  40678. Xvoid mStkEQ(void) {
  40679. X   int comp;
  40680. X
  40681. X   comp = MPcmp(Arg2->m.x, Arg1->m.x);
  40682. X   Arg2->m.x = *fg2MP((long)(comp == 0), 0);
  40683. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40684. X   Arg1--;
  40685. X   Arg2--;
  40686. X}
  40687. X
  40688. Xvoid lStkEQ(void) {
  40689. X   Arg2->l.x = Arg2->l.x == Arg1->l.x;
  40690. X   Arg2->l.y = 0l;
  40691. X   Arg1--;
  40692. X   Arg2--;
  40693. X}
  40694. X#endif
  40695. X
  40696. Xvoid (*StkEQ)(void) = dStkEQ;
  40697. X
  40698. Xvoid dStkNE(void) {
  40699. X   Arg2->d.x = (double)(Arg2->d.x != Arg1->d.x);
  40700. X   Arg2->d.y = 0.0;
  40701. X   Arg1--;
  40702. X   Arg2--;
  40703. X}
  40704. X
  40705. X#ifndef XFRACT
  40706. Xvoid mStkNE(void) {
  40707. X   int comp;
  40708. X
  40709. X   comp = MPcmp(Arg2->m.x, Arg1->m.x);
  40710. X   Arg2->m.x = *fg2MP((long)(comp != 0), 0);
  40711. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40712. X   Arg1--;
  40713. X   Arg2--;
  40714. X}
  40715. X
  40716. Xvoid lStkNE(void) {
  40717. X   Arg2->l.x = Arg2->l.x != Arg1->l.x;
  40718. X   Arg2->l.y = 0l;
  40719. X   Arg1--;
  40720. X   Arg2--;
  40721. X}
  40722. X#endif
  40723. X
  40724. Xvoid (*StkNE)(void) = dStkNE;
  40725. X
  40726. Xvoid dStkOR(void) {
  40727. X   Arg2->d.x = (double)(Arg2->d.x || Arg1->d.x);
  40728. X   Arg2->d.y = 0.0;
  40729. X   Arg1--;
  40730. X   Arg2--;
  40731. X}
  40732. X
  40733. X#ifndef XFRACT
  40734. Xvoid mStkOR(void) {
  40735. X   Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant || Arg1->m.x.Mant), 0);
  40736. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40737. X   Arg1--;
  40738. X   Arg2--;
  40739. X}
  40740. X
  40741. Xvoid lStkOR(void) {
  40742. X   Arg2->l.x = Arg2->l.x || Arg1->l.x;
  40743. X   Arg2->l.y = 0l;
  40744. X   Arg1--;
  40745. X   Arg2--;
  40746. X}
  40747. X#endif
  40748. X
  40749. Xvoid (*StkOR)(void) = dStkOR;
  40750. X
  40751. Xvoid dStkAND(void) {
  40752. X   Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x);
  40753. X   Arg2->d.y = 0.0;
  40754. X   Arg1--;
  40755. X   Arg2--;
  40756. X}
  40757. X
  40758. X#ifndef XFRACT
  40759. Xvoid mStkAND(void) {
  40760. X   Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant && Arg1->m.x.Mant), 0);
  40761. X   Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  40762. X   Arg1--;
  40763. X   Arg2--;
  40764. X}
  40765. X
  40766. Xvoid lStkAND(void) {
  40767. X   Arg2->l.x = Arg2->l.x && Arg1->l.x;
  40768. X   Arg2->l.y = 0l;
  40769. X   Arg1--;
  40770. X   Arg2--;
  40771. X}
  40772. X#endif
  40773. X
  40774. Xvoid (*StkAND)(void) = dStkAND;
  40775. X
  40776. Xvoid dStkLog(void) {
  40777. X   FPUcplxlog(&Arg1->d, &Arg1->d);
  40778. X}
  40779. X
  40780. X#ifndef XFRACT
  40781. Xvoid mStkLog(void) {
  40782. X   Arg1->d = MPC2cmplx(Arg1->m);
  40783. X   dStkLog();
  40784. X   Arg1->m = cmplx2MPC(Arg1->d);
  40785. X}
  40786. X
  40787. Xvoid lStkLog(void) {
  40788. X   _CMPLX x;
  40789. X
  40790. X   x.x = (double)Arg1->l.x / fg;
  40791. X   x.y = (double)Arg1->l.y / fg;
  40792. X   FPUcplxlog(&x, &x);
  40793. X   if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  40794. X      Arg1->l.x = (long)(x.x * fg);
  40795. X      Arg1->l.y = (long)(x.y * fg);
  40796. X   }
  40797. X   else
  40798. X      overflow = 1;
  40799. X}
  40800. X#endif
  40801. X
  40802. Xvoid (*StkLog)(void) = dStkLog;
  40803. X
  40804. Xvoid FPUcplxexp(_CMPLX *x, _CMPLX *z) {
  40805. X   double e2x, siny, cosy;
  40806. X
  40807. X   if(fpu == 387)
  40808. X      FPUcplxexp387(x, z);
  40809. X   else {
  40810. X      e2x = exp(x->x);
  40811. X      FPUsincos(&x->y, &siny, &cosy);
  40812. X      z->x = e2x * cosy;
  40813. X      z->y = e2x * siny;
  40814. X   }
  40815. X}
  40816. X
  40817. X   void dStkExp(void) {
  40818. X      FPUcplxexp(&Arg1->d, &Arg1->d);
  40819. X   }
  40820. X
  40821. X#ifndef XFRACT
  40822. Xvoid mStkExp(void) {
  40823. X   Arg1->d = MPC2cmplx(Arg1->m);
  40824. X   FPUcplxexp(&Arg1->d, &Arg1->d);
  40825. X   Arg1->m = cmplx2MPC(Arg1->d);
  40826. X}
  40827. X
  40828. Xvoid lStkExp(void) {
  40829. X   _CMPLX x;
  40830. X
  40831. X   x.x = (double)Arg1->l.x / fg;
  40832. X   x.y = (double)Arg1->l.y / fg;
  40833. X   FPUcplxexp(&x, &x);
  40834. X   if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  40835. X      Arg1->l.x = (long)(x.x * fg);
  40836. X      Arg1->l.y = (long)(x.y * fg);
  40837. X   }
  40838. X   else
  40839. X      overflow = 1;
  40840. X}
  40841. X#endif
  40842. X
  40843. Xvoid (*StkExp)(void) = dStkExp;
  40844. X
  40845. Xvoid dStkPwr(void) {
  40846. X   Arg2->d = ComplexPower(Arg2->d, Arg1->d);
  40847. X   Arg1--;
  40848. X   Arg2--;
  40849. X}
  40850. X
  40851. X#ifndef XFRACT
  40852. Xvoid mStkPwr(void) {
  40853. X   _CMPLX x, y;
  40854. X
  40855. X   x = MPC2cmplx(Arg2->m);
  40856. X   y = MPC2cmplx(Arg1->m);
  40857. X   x = ComplexPower(x, y);
  40858. X   Arg2->m = cmplx2MPC(x);
  40859. X   Arg1--;
  40860. X   Arg2--;
  40861. X}
  40862. X
  40863. Xvoid lStkPwr(void) {
  40864. X   _CMPLX x, y;
  40865. X
  40866. X   x.x = (double)Arg2->l.x / fg;
  40867. X   x.y = (double)Arg2->l.y / fg;
  40868. X   y.x = (double)Arg1->l.x / fg;
  40869. X   y.y = (double)Arg1->l.y / fg;
  40870. X   x = ComplexPower(x, y);
  40871. X   if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  40872. X      Arg2->l.x = (long)(x.x * fg);
  40873. X      Arg2->l.y = (long)(x.y * fg);
  40874. X   }
  40875. X   else
  40876. X      overflow = 1;
  40877. X   Arg1--;
  40878. X   Arg2--;
  40879. X}
  40880. X#endif
  40881. X
  40882. Xvoid (*StkPwr)(void) = dStkPwr;
  40883. X
  40884. Xvoid EndInit(void) {
  40885. X   LastInitOp = OpPtr;
  40886. X}
  40887. X
  40888. Xstruct ConstArg far *isconst(char *Str, int Len) {
  40889. X   _CMPLX z;
  40890. X   unsigned n, j;
  40891. X
  40892. X   for(n = 0; n < vsp; n++) {
  40893. X      if(v[n].len == Len) {
  40894. X         if(!strnicmp(v[n].s, Str, Len))
  40895. X         {
  40896. X            if(n == 7)        /* The formula uses 'rand'. */
  40897. X               RandomSeed();
  40898. X            return(&v[n]);
  40899. X         }
  40900. X      }
  40901. X   }
  40902. X   v[vsp].s = Str;
  40903. X   v[vsp].len = Len;
  40904. X   v[vsp].a.d.x = v[vsp].a.d.y = 0.0;
  40905. X   if(isdigit(Str[0]) || Str[0] == '.') {
  40906. X      if(o[posp-1].f == StkNeg) {
  40907. X         posp--;
  40908. X         Str = Str - 1;
  40909. X         InitN--;
  40910. X         v[vsp].len++;
  40911. X      }
  40912. X      for(n = 1; isdigit(Str[n]) || Str[n] == '.'; n++);
  40913. X      if(Str[n] == ',') {
  40914. X         j = n + SkipWhiteSpace(&Str[n+1]) + 1;
  40915. X         if(isdigit(Str[j]) || (Str[j] == '-' && isdigit(Str[j+1]))) {
  40916. X            z.y = atof(&Str[j]);
  40917. X            for(; isdigit(Str[j]) || Str[j] == '.' || Str[j] == '-'; j++);
  40918. X            v[vsp].len = j;
  40919. X         }
  40920. X         else
  40921. X            z.y = 0.0;
  40922. X      }
  40923. X      else
  40924. X         z.y = 0.0;
  40925. X      z.x = atof(Str);
  40926. X      switch(MathType) {
  40927. X      case D_MATH:
  40928. X         v[vsp].a.d = z;
  40929. X         break;
  40930. X#ifndef XFRACT
  40931. X      case M_MATH:
  40932. X         v[vsp].a.m = cmplx2MPC(z);
  40933. X         break;
  40934. X      case L_MATH:
  40935. X         v[vsp].a.l.x = (long)(z.x * fg);
  40936. X         v[vsp].a.l.y = (long)(z.y * fg);
  40937. X         break;
  40938. X#endif
  40939. X      }
  40940. X      v[vsp].s = Str;
  40941. X   }
  40942. X   return(&v[vsp++]);
  40943. X}
  40944. X
  40945. Xstruct FNCT_LIST {
  40946. X   char far *s;              /* TIW 03-31-91 added far */
  40947. X   void (**ptr)(void);
  40948. X};
  40949. X
  40950. X/* TIW 03-30-91 START */
  40951. Xextern BYTE trigndx[];
  40952. X
  40953. X#if 0
  40954. Xextern void (*ltrig0)(void);
  40955. Xextern void (*ltrig1)(void);
  40956. Xextern void (*ltrig2)(void);
  40957. Xextern void (*ltrig3)(void);
  40958. Xextern void (*dtrig0)(void);
  40959. Xextern void (*dtrig1)(void);
  40960. Xextern void (*dtrig2)(void);
  40961. Xextern void (*dtrig3)(void);
  40962. Xextern void (*mtrig0)(void);
  40963. Xextern void (*mtrig1)(void);
  40964. Xextern void (*mtrig2)(void);
  40965. Xextern void (*mtrig3)(void);
  40966. X#endif
  40967. X
  40968. Xvoid (*StkTrig0)(void) = dStkSin;
  40969. Xvoid (*StkTrig1)(void) = dStkSqr;
  40970. Xvoid (*StkTrig2)(void) = dStkSinh;
  40971. Xvoid (*StkTrig3)(void) = dStkCosh;
  40972. X
  40973. Xchar maxfn = 0;
  40974. X/* TIW 03-30-91 STOP */
  40975. X
  40976. Xstruct FNCT_LIST far FnctList[] = {   /* TIW 03-31-91 added far */
  40977. X   "sin",  &StkSin,
  40978. X   "sinh", &StkSinh,
  40979. X   "cos",  &StkCos,
  40980. X   "cosh", &StkCosh,
  40981. X   "sqr",  &StkSqr,
  40982. X   "log",  &StkLog,
  40983. X   "exp",  &StkExp,
  40984. X   "abs",  &StkAbs,
  40985. X   "conj", &StkConj,
  40986. X   "real", &StkReal,
  40987. X   "imag", &StkImag,
  40988. X   "fn1",  &StkTrig0,   /* TIW 03-30-91 */
  40989. X   "fn2",  &StkTrig1,   /* TIW 03-30-91 */
  40990. X   "fn3",  &StkTrig2,   /* TIW 03-30-91 */
  40991. X   "fn4",  &StkTrig3,   /* TIW 03-30-91 */
  40992. X   "flip", &StkFlip,    /* MCP 4-9-91 */
  40993. X   "tan",  &StkTan,     /* TIW 04-22-91 */
  40994. X   "tanh", &StkTanh,    /* TIW 04-22-91 */
  40995. X   "cotan",  &StkCoTan, /* TIW 04-24-91 */
  40996. X   "cotanh", &StkCoTanh,/* TIW 04-24-91 */
  40997. X   "cosxx", &StkCosXX,  /* PB  04-28-91 */
  40998. X   "srand", &StkSRand,  /* MCP 11-21-91 */
  40999. X};
  41000. X
  41001. Xvoid NotAFnct(void) { }
  41002. Xvoid FnctNotFound(void) { }
  41003. X
  41004. X/* determine if s names a function and if so which one */
  41005. X/* TIW 04-22-91 */
  41006. Xwhichfn(char *s, int len)
  41007. X{
  41008. X   int out;
  41009. X   if(len != 3)
  41010. X      out = 0;
  41011. X   else if(strnicmp(s,"fn",2))
  41012. X      out = 0;
  41013. X   else
  41014. X      out = atoi(s+2);
  41015. X   if(out < 1 || out > 4)
  41016. X      out = 0;
  41017. X   return(out);
  41018. X}
  41019. X
  41020. X#ifndef XFRACT
  41021. Xvoid (far *isfunct(char *Str, int Len))(void)
  41022. X#else
  41023. Xvoid (*isfunct(Str, Len))()
  41024. Xchar *Str;
  41025. Xint Len;
  41026. X#endif
  41027. X{
  41028. X   unsigned n;
  41029. X   int functnum;    /* TIW 04-22-91 */
  41030. X
  41031. X   n = SkipWhiteSpace(&Str[Len]);
  41032. X   if(Str[Len+n] == '(') {
  41033. X      for(n = 0; n < sizeof(FnctList) / sizeof(struct FNCT_LIST); n++) {
  41034. X         if(far_strlen(FnctList[n].s) == Len) {        /* TIW 03-31-91 added far */
  41035. X            if(!far_strnicmp(FnctList[n].s, Str, Len)) {  /* TIW 03-31-91 added far */
  41036. X               /* count function variables */
  41037. X               if((functnum = whichfn(Str, Len)) != 0)    /* TIW 04-22-91 */
  41038. X                  if(functnum > maxfn)                  /* TIW 04-22-91 */
  41039. X                     maxfn = functnum;                  /* TIW 04-22-91 */
  41040. X               return(*FnctList[n].ptr);
  41041. X            }
  41042. X         }
  41043. X      }
  41044. X      return(FnctNotFound);
  41045. X   }
  41046. X   return(NotAFnct);
  41047. X}
  41048. X
  41049. Xvoid RecSortPrec(void) {
  41050. X   int ThisOp = NextOp++;
  41051. X
  41052. X   while(o[ThisOp].p > o[NextOp].p && NextOp < posp)
  41053. X      RecSortPrec();
  41054. X   f[OpPtr++] = o[ThisOp].f;
  41055. X}
  41056. X
  41057. Xstatic char *Constants[] = {
  41058. X   "pixel",        /* v[0] */
  41059. X   "p1",           /* v[1] */
  41060. X   "p2",           /* v[2] */
  41061. X   "z",            /* v[3] */
  41062. X   "LastSqr",      /* v[4] */
  41063. X   "xy",           /* v[5] */
  41064. X   "zt",           /* v[6] */
  41065. X   "rand",         /* v[7] */
  41066. X};
  41067. X
  41068. Xstruct SYMETRY {
  41069. X   char *s;
  41070. X   int n;
  41071. X} SymStr[] = {
  41072. X   "NOSYM",         0,
  41073. X   "XAXIS_NOPARM", -1,
  41074. X   "XAXIS",         1,
  41075. X   "YAXIS_NOPARM", -2,
  41076. X   "YAXIS",         2,
  41077. X   "XYAXIS_NOPARM",-3,
  41078. X   "XYAXIS",        3,
  41079. X   "ORIGIN_NOPARM",-4,
  41080. X   "ORIGIN",        4,
  41081. X   "PI_SYM_NOPARM",-5,
  41082. X   "PI_SYM",        5,
  41083. X   "NOPLOT",       99,
  41084. X   "", 0
  41085. X};
  41086. X
  41087. Xint ParseStr(char *Str) {
  41088. X   struct ConstArg far *c;
  41089. X   int ModFlag = 999, Len, Equals = 0, Mod[20], mdstk = 0;
  41090. X   int NewStatement;
  41091. X   struct ERROR { int n, s; } far *e;
  41092. X
  41093. X   SetRandom = Randomized = 0;
  41094. X   e = (struct ERROR far *)farmemalloc(sizeof(struct ERROR) * 100L);
  41095. X   /* PB 910417 changed "o" to be a temporary alloc, during ParseStr only */
  41096. X   o = (struct PEND_OP far *)farmemalloc(sizeof(struct PEND_OP) * (long)MAX_OPS);
  41097. X   if(!e || !o || !typespecific_workarea) {
  41098. X      static char far msg[]={"Insufficient memory to run fractal type 'formula'"};
  41099. X      stopmsg(0,msg);
  41100. X      return(1);
  41101. X   }
  41102. X   switch(MathType) {
  41103. X   case D_MATH:
  41104. X      StkAdd = dStkAdd;
  41105. X      StkSub = dStkSub;
  41106. X      StkNeg = dStkNeg;
  41107. X      StkMul = dStkMul;
  41108. X      StkSin = dStkSin;
  41109. X      StkSinh = dStkSinh;
  41110. X      StkLT = dStkLT;
  41111. X      StkLTE = dStkLTE;
  41112. X      StkMod = dStkMod;
  41113. X      StkSqr = dStkSqr;
  41114. X      StkCos = dStkCos;
  41115. X      StkCosh = dStkCosh;
  41116. X      StkLog = dStkLog;
  41117. X      StkExp = dStkExp;
  41118. X      StkPwr = dStkPwr;
  41119. X      StkDiv = dStkDiv;
  41120. X      StkAbs = dStkAbs;
  41121. X      StkReal = dStkReal;
  41122. X      StkImag = dStkImag;
  41123. X      StkConj = dStkConj;
  41124. X      StkTrig0 = dtrig0;   /* TIW 03-30-91 */
  41125. X      StkTrig1 = dtrig1;   /* TIW 03-30-91 */
  41126. X      StkTrig2 = dtrig2;   /* TIW 03-30-91 */
  41127. X      StkTrig3 = dtrig3;   /* TIW 03-30-91 */
  41128. X      StkFlip = dStkFlip;
  41129. X      StkTan = dStkTan;    /* TIW 04-22-91 */
  41130. X      StkTanh = dStkTanh;  /* TIW 04-22-91 */
  41131. X      StkCoTan = dStkCoTan;    /* TIW 04-24-91 */
  41132. X      StkCoTanh = dStkCoTanh;  /* TIW 04-24-91 */
  41133. X      StkCosXX = dStkCosXX;    /* PB  04-28-91 */
  41134. X      StkGT  = dStkGT;         /* MCP 11-3-91 */
  41135. X      StkGTE = dStkGTE;        /* MCP 11-3-91 */
  41136. X      StkEQ  = dStkEQ;         /* MCP 11-3-91 */
  41137. X      StkNE  = dStkNE;         /* MCP 11-3-91 */
  41138. X      StkAND = dStkAND;        /* MCP 11-3-91 */
  41139. X      StkOR  = dStkOR ;        /* MCP 11-3-91 */
  41140. X      StkSRand = dStkSRand;    /* MCP 11-21-91 */
  41141. X      break;
  41142. X#ifndef XFRACT
  41143. X   case M_MATH:
  41144. X      StkAdd = mStkAdd;
  41145. X      StkSub = mStkSub;
  41146. X      StkNeg = mStkNeg;
  41147. X      StkMul = mStkMul;
  41148. X      StkSin = mStkSin;
  41149. X      StkSinh = mStkSinh;
  41150. X      StkLT = mStkLT;
  41151. X      StkLTE = mStkLTE;
  41152. X      StkMod = mStkMod;
  41153. X      StkSqr = mStkSqr;
  41154. X      StkCos = mStkCos;
  41155. X      StkCosh = mStkCosh;
  41156. X      StkLog = mStkLog;
  41157. X      StkExp = mStkExp;
  41158. X      StkPwr = mStkPwr;
  41159. X      StkDiv = mStkDiv;
  41160. X      StkAbs = mStkAbs;
  41161. X      StkReal = mStkReal;
  41162. X      StkImag = mStkImag;
  41163. X      StkConj = mStkConj;
  41164. X      StkTrig0 = mtrig0;  /* TIW 03-30-91 */
  41165. X      StkTrig1 = mtrig1;  /* TIW 03-30-91 */
  41166. X      StkTrig2 = mtrig2;  /* TIW 03-30-91 */
  41167. X      StkTrig3 = mtrig3;  /* TIW 03-30-91 */
  41168. X      StkFlip = mStkFlip;
  41169. X      StkTan  = mStkTan;  /* TIW 04-22-91 */
  41170. X      StkTanh  = mStkTanh;/* TIW 04-22-91 */
  41171. X      StkCoTan  = mStkCoTan;  /* TIW 04-24-91 */
  41172. X      StkCoTanh  = mStkCoTanh;/* TIW 04-24-91 */
  41173. X      StkCosXX = mStkCosXX;   /* PB  04-28-91 */
  41174. X      StkGT  = mStkGT;         /* MCP 11-3-91 */
  41175. X      StkGTE = mStkGTE;        /* MCP 11-3-91 */
  41176. X      StkEQ  = mStkEQ;         /* MCP 11-3-91 */
  41177. X      StkNE  = mStkNE;         /* MCP 11-3-91 */
  41178. X      StkAND = mStkAND;        /* MCP 11-3-91 */
  41179. X      StkOR  = mStkOR ;        /* MCP 11-3-91 */
  41180. X      StkSRand = mStkSRand;    /* MCP 11-21-91 */
  41181. X      break;
  41182. X   case L_MATH:
  41183. X      Delta16 = bitshift - 16;
  41184. X      ShiftBack = 32 - bitshift; /* TW 06-18-90 */
  41185. X      StkAdd = lStkAdd;
  41186. X      StkSub = lStkSub;
  41187. X      StkNeg = lStkNeg;
  41188. X      StkMul = lStkMul;
  41189. X      StkSin = lStkSin;
  41190. X      StkSinh = lStkSinh;
  41191. X      StkLT = lStkLT;
  41192. X      StkLTE = lStkLTE;
  41193. X      StkMod = lStkMod;
  41194. X      StkSqr = lStkSqr;
  41195. X      StkCos = lStkCos;
  41196. X      StkCosh = lStkCosh;
  41197. X      StkLog = lStkLog;
  41198. X      StkExp = lStkExp;
  41199. X      StkPwr = lStkPwr;
  41200. X      StkDiv = lStkDiv;
  41201. X      StkAbs = lStkAbs;
  41202. X      StkReal = lStkReal;
  41203. X      StkImag = lStkImag;
  41204. X      StkConj = lStkConj;
  41205. X      StkTrig0 = ltrig0;   /* TIW 03-30-91 */
  41206. X      StkTrig1 = ltrig1;   /* TIW 03-30-91 */
  41207. X      StkTrig2 = ltrig2;   /* TIW 03-30-91 */
  41208. X      StkTrig3 = ltrig3;   /* TIW 03-30-91 */
  41209. X      StkFlip = lStkFlip;
  41210. X      StkTan  = lStkTan;   /* TIW 04-22-91 */
  41211. X      StkTanh  = lStkTanh; /* TIW 04-22-91 */
  41212. X      StkCoTan  = lStkCoTan;   /* TIW 04-24-91 */
  41213. X      StkCoTanh  = lStkCoTanh; /* TIW 04-24-91 */
  41214. X      StkCosXX = lStkCosXX;    /* PB  04-28-91 */
  41215. X      StkGT  = lStkGT;         /* MCP 11-3-91 */
  41216. X      StkGTE = lStkGTE;        /* MCP 11-3-91 */
  41217. X      StkEQ  = lStkEQ;         /* MCP 11-3-91 */
  41218. X      StkNE  = lStkNE;         /* MCP 11-3-91 */
  41219. X      StkAND = lStkAND;        /* MCP 11-3-91 */
  41220. X      StkOR  = lStkOR ;        /* MCP 11-3-91 */
  41221. X      StkSRand = lStkSRand;    /* MCP 11-21-91 */
  41222. X      break;
  41223. X#endif
  41224. X   }
  41225. X   maxfn = 0;   /* TIW 03-30-91 */
  41226. X   for(vsp = 0; vsp < sizeof(Constants) / sizeof(char*); vsp++) {
  41227. X      v[vsp].s = Constants[vsp];
  41228. X      v[vsp].len = strlen(Constants[vsp]);
  41229. X   }
  41230. X
  41231. X   v[6].a.d.x = v[6].a.d.y = 0.0;
  41232. X   v[7].a = v[6].a;
  41233. X
  41234. X   switch(MathType) {
  41235. X   case D_MATH:
  41236. X      v[1].a.d.x = param[0];
  41237. X      v[1].a.d.y = param[1];
  41238. X      v[2].a.d.x = param[2];
  41239. X      v[2].a.d.y = param[3];
  41240. X      break;
  41241. X#ifndef XFRACT
  41242. X   case M_MATH:
  41243. X      v[1].a.m.x = *d2MP(param[0]);
  41244. X      v[1].a.m.y = *d2MP(param[1]);
  41245. X      v[2].a.m.x = *d2MP(param[2]);
  41246. X      v[2].a.m.y = *d2MP(param[3]);
  41247. X      break;
  41248. X   case L_MATH:
  41249. X      v[1].a.l.x = (long)(param[0] * fg);
  41250. X      v[1].a.l.y = (long)(param[1] * fg);
  41251. X      v[2].a.l.x = (long)(param[2] * fg);
  41252. X      v[2].a.l.y = (long)(param[3] * fg);
  41253. X      break;
  41254. X#endif
  41255. X   }
  41256. X
  41257. X   LastInitOp = ErrPtr = paren = OpPtr = LodPtr = StoPtr = posp = 0;
  41258. X   NewStatement = 1;
  41259. X   SyntaxErr = -1;
  41260. X   ExpectingArg = 1;
  41261. X   for(n = 0; Str[n]; n++) {
  41262. X      if(!Str[n])
  41263. X         break;
  41264. X      InitN = n;
  41265. X      switch(Str[n]) {
  41266. X      case ' ':
  41267. X      case '\t':
  41268. X      case '\r':
  41269. X      case '\n':
  41270. X         break;
  41271. X      case '(':
  41272. X         paren++;
  41273. X         if(!ExpectingArg)
  41274. X            SyntaxErr = 1;
  41275. X         break;
  41276. X      case ')':
  41277. X         if(paren)
  41278. X            paren--;
  41279. X         else
  41280. X            SyntaxErr = 2;
  41281. X         if(ExpectingArg) {
  41282. X            e[ErrPtr].n = InitN;
  41283. X            e[ErrPtr++].s = 0;
  41284. X         }
  41285. X         break;
  41286. X      case '|':
  41287. X         if(Str[n+1] == '|') {
  41288. X            if(ExpectingArg)
  41289. X               SyntaxErr = 0;
  41290. X            ExpectingArg = 1;
  41291. X            n++;
  41292. X            o[posp].f = StkOR;
  41293. X            o[posp++].p = 7 - (paren + Equals)*15;
  41294. X         }
  41295. X         else if(ModFlag == paren-1) {
  41296. X            if(ExpectingArg)
  41297. X               SyntaxErr = 0;
  41298. X            paren--;
  41299. X            ModFlag = Mod[--mdstk];
  41300. X         }
  41301. X         else {
  41302. X            if(!ExpectingArg)
  41303. X               SyntaxErr = 1;
  41304. X            Mod[mdstk++] = ModFlag;
  41305. X            o[posp].f = StkMod;
  41306. X            o[posp++].p = 2 - (paren + Equals)*15;
  41307. X            ModFlag = paren++;
  41308. X         }
  41309. X         break;
  41310. X      case ',':
  41311. X      case ';':
  41312. X         if(paren) {
  41313. X            e[ErrPtr].n = InitN;
  41314. X            e[ErrPtr++].s = 3;
  41315. X         }
  41316. X         if(!ExpectingArg) {
  41317. X            NewStatement = 1;
  41318. X            ExpectingArg = 1;
  41319. X            o[posp].f = (void(far*)(void))0;
  41320. X            o[posp++].p = 15;
  41321. X            o[posp].f = StkClr;
  41322. X            o[posp++].p = -30000;
  41323. X            Equals = paren = 0;
  41324. X         }
  41325. X         else if(!NewStatement)
  41326. X            SyntaxErr = 0;
  41327. X         break;
  41328. X      case ':':
  41329. X         if(paren) {
  41330. X            e[ErrPtr].n = InitN;
  41331. X            e[ErrPtr++].s = 3;
  41332. X         }
  41333. X         if(ExpectingArg)
  41334. X            SyntaxErr = 0;
  41335. X         else
  41336. X            ExpectingArg = 1;
  41337. X         o[posp].f = (void(far*)(void))0;
  41338. X         o[posp++].p = 15;
  41339. X         o[posp].f = EndInit;
  41340. X         o[posp++].p = -30000;
  41341. X         Equals = paren = 0;
  41342. X         LastInitOp = 10000;
  41343. X         NewStatement = 1;
  41344. X         break;
  41345. X      case '+':
  41346. X         if(ExpectingArg)
  41347. X            SyntaxErr = 0;
  41348. X         ExpectingArg = 1;
  41349. X         o[posp].f = StkAdd;
  41350. X         o[posp++].p = 4 - (paren + Equals)*15;
  41351. X         break;
  41352. X      case '-':
  41353. X         if(ExpectingArg) {
  41354. X            o[posp].f = StkNeg;
  41355. X            o[posp++].p = 2 - (paren + Equals)*15;
  41356. X         }
  41357. X         else {
  41358. X            o[posp].f = StkSub;
  41359. X            o[posp++].p = 4 - (paren + Equals)*15;
  41360. X            ExpectingArg = 1;
  41361. X         }
  41362. X         break;
  41363. X      case '&':
  41364. X         if(ExpectingArg)
  41365. X            SyntaxErr = 0;
  41366. X         ExpectingArg = 1;
  41367. X         if(Str[n+1] == '&') {
  41368. X            n++;
  41369. X            o[posp].f = StkAND;
  41370. X            o[posp++].p = 7 - (paren + Equals)*15;
  41371. X         }
  41372. X         else
  41373. X            SyntaxErr = 4;
  41374. X         break;
  41375. X      case '!':
  41376. X         if(Str[n+1] == '=') {
  41377. X            if(ExpectingArg)
  41378. X               SyntaxErr = 0;
  41379. X            ExpectingArg = 1;
  41380. X            n++;
  41381. X            o[posp].f = StkNE;
  41382. X            o[posp++].p = 6 - (paren + Equals)*15;
  41383. X         }
  41384. X         else
  41385. X            SyntaxErr = 4;
  41386. X         break;
  41387. X      case '<':
  41388. X         if(ExpectingArg)
  41389. X            SyntaxErr = 0;
  41390. X         ExpectingArg = 1;
  41391. X         if(Str[n+1] == '=') {
  41392. X            n++;
  41393. X            o[posp].f = StkLTE;
  41394. X         }
  41395. X         else
  41396. X            o[posp].f = StkLT;
  41397. X         o[posp++].p = 6 - (paren + Equals)*15;
  41398. X         break;
  41399. X      case '>':
  41400. X         if(ExpectingArg)
  41401. X            SyntaxErr = 0;
  41402. X         ExpectingArg = 1;
  41403. X         if(Str[n+1] == '=') {
  41404. X            n++;
  41405. X            o[posp].f = StkGTE;
  41406. X         }
  41407. X         else
  41408. X            o[posp].f = StkGT;
  41409. X         o[posp++].p = 6 - (paren + Equals)*15;
  41410. X         break;
  41411. X      case '*':
  41412. X         if(ExpectingArg)
  41413. X            SyntaxErr = 0;
  41414. X         ExpectingArg = 1;
  41415. X         o[posp].f = StkMul;
  41416. X         o[posp++].p = 3 - (paren + Equals)*15;
  41417. X         break;
  41418. X      case '/':
  41419. X         if(ExpectingArg)
  41420. X            SyntaxErr = 0;
  41421. X         ExpectingArg = 1;
  41422. X         o[posp].f = StkDiv;
  41423. X         o[posp++].p = 3 - (paren + Equals)*15;
  41424. X         break;
  41425. X      case '^':
  41426. X         if(ExpectingArg)
  41427. X            SyntaxErr = 0;
  41428. X         ExpectingArg = 1;
  41429. X         o[posp].f = StkPwr;
  41430. X         o[posp++].p = 2 - (paren + Equals)*15;
  41431. X         break;
  41432. X      case '=':
  41433. X         if(ExpectingArg)
  41434. X            SyntaxErr = 0;
  41435. X         ExpectingArg = 1;
  41436. X         if(Str[n+1] == '=') {
  41437. X            n++;
  41438. X            o[posp].f = StkEQ;
  41439. X            o[posp++].p = 6 - (paren + Equals)*15;
  41440. X         }
  41441. X         else
  41442. X         {
  41443. X            o[posp-1].f = StkSto;
  41444. X            o[posp-1].p = 5 - (paren + Equals)*15;
  41445. X            Store[StoPtr++] = Load[--LodPtr];
  41446. X            Equals++;
  41447. X         }
  41448. X         break;
  41449. X      default:
  41450. X         if(isalnum(Str[n]) || Str[n] == '.') {
  41451. X            while(isalnum(Str[n+1]) || Str[n+1] == '.')
  41452. X               n++;
  41453. X            if(!ExpectingArg) {
  41454. X               SyntaxErr = 1;
  41455. X            }
  41456. X            NewStatement = ExpectingArg = 0;
  41457. X            Len = (n+1)-InitN;
  41458. X            o[posp].f = isfunct(&Str[InitN], Len);
  41459. X            if(o[posp].f != NotAFnct) {
  41460. X               if(o[posp].f == FnctNotFound) {
  41461. X                  e[ErrPtr].n = InitN;
  41462. X                  e[ErrPtr++].s = 5;
  41463. X               }
  41464. X               else
  41465. X                  o[posp++].p = 1 - (paren + Equals)*15;
  41466. X               ExpectingArg = 1;
  41467. X            }
  41468. X            else {
  41469. X               c = isconst(&Str[InitN], Len);
  41470. X               Load[LodPtr++] = &(c->a);
  41471. X               o[posp].f = StkLod;
  41472. X               o[posp++].p = 1 - (paren + Equals)*15;
  41473. X               n = InitN + c->len - 1;
  41474. X               if(vsp >= MAX_ARGS-1) { /* PB 910417 safety test */
  41475. X                  e[ErrPtr].n = InitN;
  41476. X                  e[ErrPtr++].s = 7;
  41477. X                  break;
  41478. X               }
  41479. X            }
  41480. X         }
  41481. X         else {
  41482. X            if(ExpectingArg)
  41483. X               SyntaxErr = 0;
  41484. X            ExpectingArg = 1;
  41485. X            e[ErrPtr].n = InitN;
  41486. X            e[ErrPtr++].s = 4;
  41487. X         }
  41488. X         break;
  41489. X      }
  41490. X      if(SyntaxErr >= 0) {
  41491. X         e[ErrPtr].n = InitN;
  41492. X         e[ErrPtr++].s = SyntaxErr;
  41493. X         SyntaxErr = -1;
  41494. X      }
  41495. X      if(posp >= MAX_OPS-1) { /* PB 901103 added safety test here */
  41496. X         e[ErrPtr].n = InitN;
  41497. X         e[ErrPtr++].s = 7;
  41498. X         break;
  41499. X      }
  41500. X      if(ErrPtr > 50)         /* PB 910417 safety test */
  41501. X         break;
  41502. X   }
  41503. X
  41504. X   o[posp].f = (void(far*)(void))0;
  41505. X   o[posp++].p = 16;
  41506. X   if(paren > 0) {
  41507. X      e[ErrPtr].n = n;
  41508. X      e[ErrPtr++].s = 3;
  41509. X   }
  41510. X   if (ErrPtr) {
  41511. X      int i, j, k, m;
  41512. X      char msgbuf[700];  /* PB replaced printf loop by build msgbuf & stopmsg */
  41513. X      /* stopmsg defined to have max 9 lines, show at most first 3 errors */
  41514. X      msgbuf[0] = 0;
  41515. X      for(n = 0; n < ErrPtr && n < 3; n++) {
  41516. X         if (n)
  41517. X            strcat(msgbuf,"\n");
  41518. X#ifndef XFRACT
  41519. X         sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %Fs\n  ", e[n].s, /*TIW 03-31-91 added %Fs*/
  41520. X            ErrStrings[e[n].s]);
  41521. X#else
  41522. X         sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %s\n  ", e[n].s,
  41523. X            ErrStrings[e[n].s]);
  41524. X#endif
  41525. X         j = 24;
  41526. X         if ((i = e[n].n - j) < 0) {
  41527. X            j = e[n].n;
  41528. X            i = 0;
  41529. X         }
  41530. X         else {
  41531. X            strcat(msgbuf,"...");
  41532. X            j += 3;
  41533. X         }
  41534. X         k = strlen(msgbuf);
  41535. X         m = i + 66;
  41536. X         while (i < m && Str[i]) {
  41537. X            if ((msgbuf[k] = Str[i]) == '\n' || msgbuf[k] == '\t')
  41538. X               msgbuf[k] = ' ';
  41539. X            ++i;
  41540. X            ++k;
  41541. X         }
  41542. X         if (Str[i]) {
  41543. X            msgbuf[k++] = '.';
  41544. X            msgbuf[k++] = '.';
  41545. X            msgbuf[k++] = '.';
  41546. X         }
  41547. X         msgbuf[k++] = '\n';
  41548. X         while (--j >= -2)
  41549. X            msgbuf[k++] = ' ';
  41550. X         msgbuf[k++] = '^';
  41551. X         msgbuf[k] = 0;
  41552. X      }
  41553. X      stopmsg(8,msgbuf);
  41554. X   }
  41555. X   if(!ErrPtr) {
  41556. X      NextOp = 0;
  41557. X      LastOp = posp;
  41558. X      while(NextOp < posp) {
  41559. X         if(o[NextOp].f)
  41560. X            RecSortPrec();
  41561. X         else {
  41562. X            NextOp++;
  41563. X            LastOp--;
  41564. X         }
  41565. X      }
  41566. X   }
  41567. X   else
  41568. X      posp = 0;
  41569. X   farmemfree(o);
  41570. X   farmemfree(e);
  41571. X   /* PB 910417 free all arrays if error */
  41572. X   if (ErrPtr)
  41573. X      free_workarea();
  41574. X   return(ErrPtr);
  41575. X}
  41576. X
  41577. Xint Formula(void) {
  41578. X   if(FormName[0] == 0 || overflow) return(1);
  41579. X
  41580. X   LodPtr = InitLodPtr;
  41581. X   StoPtr = InitStoPtr;
  41582. X   OpPtr = InitOpPtr;
  41583. X
  41584. X   /* Set the random number, MCP 11-21-91 */
  41585. X   if(SetRandom || Randomized)
  41586. X   {
  41587. X      switch(MathType)
  41588. X      {
  41589. X      case D_MATH:
  41590. X         dRandom();
  41591. X         break;
  41592. X#ifndef XFRACT
  41593. X      case L_MATH:
  41594. X         lRandom();
  41595. X         break;
  41596. X      case M_MATH:
  41597. X         mRandom();
  41598. X#endif
  41599. X      }
  41600. X   }
  41601. X
  41602. X   Arg1 = &s[0];
  41603. X   Arg2 = Arg1-1;
  41604. X   while(OpPtr < LastOp) {
  41605. X      f[OpPtr++]();
  41606. X#ifdef WATCH_MP
  41607. X      x1 = *MP2d(Arg1->m.x);
  41608. X      y1 = *MP2d(Arg1->m.y);
  41609. X      x2 = *MP2d(Arg2->m.x);
  41610. X      y2 = *MP2d(Arg2->m.y);
  41611. X#endif
  41612. X   }
  41613. X
  41614. X   switch(MathType) {
  41615. X   case D_MATH:
  41616. X      old = new = v[3].a.d;
  41617. X      return(Arg1->d.x == 0.0);
  41618. X#ifndef XFRACT
  41619. X   case M_MATH:
  41620. X      old = new = MPC2cmplx(v[3].a.m);
  41621. X      return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0);
  41622. X   case L_MATH:
  41623. X      lold = lnew = v[3].a.l;
  41624. X      if(overflow)
  41625. X         return(1);
  41626. X      return(Arg1->l.x == 0L);
  41627. X#endif
  41628. X   }
  41629. X   return(1);
  41630. X}
  41631. X
  41632. Xint form_per_pixel(void) {
  41633. X   if (FormName[0] == 0) return(1);
  41634. X   overflow = LodPtr = StoPtr = OpPtr = 0;
  41635. X   Arg1 = &s[0];
  41636. X   Arg2 = Arg1;
  41637. X   Arg2--;
  41638. X   if(Transparent3D)
  41639. X   {
  41640. X      TranspPerPixel(MathType, &v[5].a, &v[6].a);
  41641. X      v[0].a = v[5].a;
  41642. X   }
  41643. X   else
  41644. X   {
  41645. X      switch(MathType)
  41646. X      {
  41647. X      case D_MATH:
  41648. X         v[5].a.d.x = (v[0].a.d.x = dx0[col]+dShiftx);
  41649. X         v[5].a.d.x = (v[0].a.d.y = dy0[row]+dShifty);
  41650. X         break;
  41651. X#ifndef XFRACT
  41652. X      case M_MATH:
  41653. X         v[5].a.m.x = (v[0].a.m.x = *d2MP(dx0[col]+dShiftx));
  41654. X         v[5].a.m.x = (v[0].a.m.y = *d2MP(dy0[row]+dShifty));
  41655. X         break;
  41656. X      case L_MATH:
  41657. X         v[5].a.l.x = (v[0].a.l.x = lx0[col]+lShiftx);
  41658. X         v[5].a.l.x = (v[0].a.l.y = ly0[row]+lShifty);
  41659. X         break;
  41660. X#endif
  41661. X      }
  41662. X   }
  41663. X
  41664. X   if(LastInitOp)
  41665. X      LastInitOp = LastOp;
  41666. X   while(OpPtr < LastInitOp)
  41667. X      f[OpPtr++]();
  41668. X
  41669. X   InitLodPtr = LodPtr;
  41670. X   InitStoPtr = StoPtr;
  41671. X   InitOpPtr = OpPtr;
  41672. X
  41673. X   if(overflow)
  41674. X      return(0);
  41675. X   else
  41676. X      return(1);
  41677. X}
  41678. X
  41679. Xchar *FormStr;
  41680. X
  41681. Xextern char FormFileName[];   /* BDT file to find the formulas in */
  41682. Xextern char FormName[];    /* BDT Name of the Formula (if not null) */
  41683. X
  41684. Xchar *FindFormula(char *Str) {
  41685. X   char *FormulaStr = (char *)0;
  41686. X   char StrBuff[201];      /* PB, to match a safety fix in parser */
  41687. X   /* MCP, changed to an automatic variable */
  41688. X   char fullfilename[100]; /* BDT Full file name */
  41689. X   unsigned Done;
  41690. X   int c;
  41691. X   FILE *File;
  41692. X
  41693. X   findpath(FormFileName, fullfilename);  /* BDT get full path name */
  41694. X
  41695. X   symmetry = 0;
  41696. X   if((File = fopen(fullfilename, "rt")) != NULL) { /* BDT use variable files */
  41697. X      while(StrBuff[0]=0,/* TIW 04-22-91 */ fscanf(File, "%200[^ \n\t({]", StrBuff) != EOF) {
  41698. X         if(!stricmp(StrBuff, Str) || !Str[0]) {
  41699. X            while((c = getc(File)) != EOF) {
  41700. X               if(c == '(') {
  41701. X                  StrBuff[0]=0; /* TIW 04-22-91 */
  41702. X                  fscanf(File, "%200[^)]", StrBuff);
  41703. X                  for(n = 0; SymStr[n].s[0]; n++) {
  41704. X                     if(!stricmp(SymStr[n].s, StrBuff)) {
  41705. X                        symmetry = SymStr[n].n;
  41706. X                        break;
  41707. X                     }
  41708. X                  }
  41709. X                  if(!SymStr[n].s[0]) {
  41710. X                     sprintf(fullfilename,"Undefined symmetry:\n  %.76s",
  41711. X                        StrBuff);
  41712. X                     stopmsg(0,fullfilename); /* PB printf -> stopmsg */
  41713. X                     FormulaStr = (char *)0;  /* PB 910511 */
  41714. XExit:
  41715. X                     fclose(File);
  41716. X                     return(FormulaStr);
  41717. X                  }
  41718. X               }
  41719. X               else if(c == '{')
  41720. X                  break;
  41721. X            }
  41722. X
  41723. X            /* MCP 4-9-91, Strip the comments inside the formula.  Might
  41724. X                           as well allow unlimited formula lengths while
  41725. X                           we're at it.
  41726. X            */
  41727. X
  41728. X            FormulaStr = boxx;
  41729. X            n = Done = 0;
  41730. X            while(!Done) {
  41731. X               switch(c = getc(File)) {
  41732. X                  static char far msg[]={"Unexpected EOF:  missing a '}'"};
  41733. X               case EOF:
  41734. XUnexpectedEOF:
  41735. X                  stopmsg(0, msg);
  41736. X                  FormulaStr = (char *)0;
  41737. X                  goto Exit;
  41738. X               case '}':
  41739. X                  FormulaStr[n++] = 0;
  41740. X                  Done = 1;
  41741. X                  break;
  41742. X               case ';':
  41743. X                  while((c = getc(File)) != '\n') {
  41744. X                     if(c == EOF)
  41745. X                        goto UnexpectedEOF;
  41746. X                  }
  41747. X                  FormulaStr[n++] = ',';
  41748. X                  break;
  41749. X               case ' ':                     /* Also strip out the
  41750. X                                                   white spaces */
  41751. X                                    
  41752. X               case '\t':
  41753. X                  break;
  41754. X               case '\n':
  41755. X                  FormulaStr[n++] = ',';
  41756. X                  break;
  41757. X               default:
  41758. X                  FormulaStr[n++] = c;
  41759. X               }
  41760. X               if (n >= 8192) { /* PB 4-9-91, added safety test */
  41761. X                  static char far msg[]={"Definition too large, missing a '}'?"};
  41762. X                  stopmsg(0, msg);
  41763. X                  FormulaStr = (char *)0;
  41764. X                  goto Exit;
  41765. X               }
  41766. X            }
  41767. X            goto Exit;
  41768. X         }
  41769. X
  41770. X         StrBuff[0]=0;  /* TIW 04-22-91 */
  41771. X         fscanf(File, "%200[ \n\t({]", StrBuff);
  41772. X         if(StrBuff[strcspn(StrBuff, "({")]) {
  41773. Xskipcomments:
  41774. X            fscanf(File, "%200[^}]", StrBuff);
  41775. X            if (getc(File)!= '}') goto skipcomments;
  41776. X         }
  41777. X      }
  41778. X      sprintf(fullfilename, "Formula \"%s\" not found", Str);
  41779. X      stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
  41780. X      FormulaStr = (char *)0;       /* PB 910511 */
  41781. X      goto Exit;
  41782. X   }
  41783. X   sprintf(fullfilename, "Unable to open %s", FormFileName);
  41784. X   stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
  41785. X   return((char *)0);            /* PB 910511 */
  41786. X}
  41787. X
  41788. Xint BadFormula() {
  41789. X   /*  moved from Parsera.Asm by CAE  12 July 1993  */
  41790. X
  41791. X   /*  this is called when a formula is bad, instead of calling  */
  41792. X   /*     the normal functions which will produce undefined results  */
  41793. X   return 1;
  41794. X}
  41795. X
  41796. Xint RunForm(char *Name) {  /*  returns 1 if an error occurred  */
  41797. X   /*  CAE changed fn 12 July 1993 to fix problem when formula not found  */
  41798. X
  41799. X   /*  first set the pointers so they point to a fn which always returns 1  */
  41800. X   curfractalspecific->per_pixel = BadFormula;
  41801. X   curfractalspecific->orbitcalc = BadFormula;
  41802. X
  41803. X   if (FormName[0] == 0 ){
  41804. X      return 1;  /*  and don't reset the pointers  */
  41805. X   }
  41806. X
  41807. X   parser_allocate();  /*  ParseStr() will test if this alloc worked  */
  41808. X
  41809. X   if((FormStr = FindFormula(Name)) != NULL ){
  41810. X      /*  formula was found  */
  41811. X      if (ParseStr(FormStr)){
  41812. X         /*  parse failed, don't change fn pointers  */
  41813. X         return 1;
  41814. X      }
  41815. X      else {
  41816. X         /*  parse succeeded so set the pointers back to good functions  */
  41817. X         curfractalspecific->per_pixel = form_per_pixel;
  41818. X         curfractalspecific->orbitcalc = Formula;
  41819. X         return 0;
  41820. X      }
  41821. X   }
  41822. X   else {
  41823. X      /*  formula not found, leave pointers set to BadFormula  */
  41824. X      return 1;                    /* PB, msg moved to FindFormula */
  41825. X   }
  41826. X}
  41827. X
  41828. Xint fpFormulaSetup(void) {
  41829. X#ifndef XFRACT
  41830. X   int RunFormRes;        /* CAE fp */
  41831. X
  41832. X   if (fpu > 0) {
  41833. X      MathType = D_MATH;
  41834. X      /* CAE changed below for fp */
  41835. X      RunFormRes = !RunForm(FormName); /* RunForm() returns 1 for failure */
  41836. X      if (RunFormRes && fpu >=387 && debugflag != 90 )
  41837. X         return CvtStk(); /* run fast assembler code in parsera.asm */
  41838. X      return RunFormRes;
  41839. X   }
  41840. X   else {
  41841. X      MathType = M_MATH;
  41842. X      return !RunForm(FormName);
  41843. X   }
  41844. X#else
  41845. X   MathType = D_MATH;
  41846. X   return(!RunForm(FormName));
  41847. X#endif
  41848. X}
  41849. X
  41850. Xint intFormulaSetup(void) {
  41851. X#ifdef XFRACT
  41852. X      printf("intFormulaSetup called!!!\n");
  41853. X      exit(-1);
  41854. X#endif
  41855. X      MathType = L_MATH;
  41856. X      fg = (double)(1L << bitshift);
  41857. X      fgLimit = (double)0x7fffffffL / fg;
  41858. X      ShiftBack = 32 - bitshift;
  41859. X      return(!RunForm(FormName));
  41860. X   }
  41861. X
  41862. X
  41863. X/* TIW added 06-20-90 so functions can be called from fractals.c */
  41864. Xvoid init_misc()
  41865. X{
  41866. X   static struct ConstArg far vv[5];
  41867. X   static union Arg argfirst,argsecond;
  41868. X   if(!v) /* PB 901103 added this test to avoid clobbering the real thing */
  41869. X      v = vv;  /* this is needed by lStkSqr and dStkSqr */
  41870. X   Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */
  41871. X   fg = (double)(1L << bitshift);
  41872. X   fgLimit = (double)0x7fffffffL / fg;
  41873. X   ShiftBack = 32 - bitshift;
  41874. X   Delta16 = bitshift - 16;
  41875. X   bitshiftless1 = bitshift-1;
  41876. X}
  41877. X
  41878. X/* PB 910417 here to end changed.
  41879. X    Allocate sub-arrays from one main farmemalloc, using global variable
  41880. X    typespecific_workarea; calcfrac.c releases this area when calculation
  41881. X    ends or is terminated.
  41882. X    Moved the "f" array to be allocated as part of this.
  41883. X    */
  41884. X
  41885. Xstatic void parser_allocate(void)
  41886. X{
  41887. X   /* CAE fp changed below for v18 */
  41888. X   /* Note that XFRACT will waste about 6k here for pfls */
  41889. X   /* Somewhat more memory is now allocated than in v17 here */
  41890. X   /* however Store and Load were reduced in size to help make up for it */
  41891. X
  41892. X   unsigned int f_size,Store_size,Load_size,v_size, p_size;
  41893. X   free_workarea();
  41894. X   f_size = sizeof(void(far * far *)(void)) * MAX_OPS;
  41895. X   Store_size = sizeof(union Arg far *) * MAX_STORES;
  41896. X   Load_size = sizeof(union Arg far *) * MAX_LOADS;
  41897. X   v_size = sizeof(struct ConstArg) * MAX_ARGS;
  41898. X   p_size = sizeof(struct fls far *) * MAX_OPS;
  41899. X   typespecific_workarea =
  41900. X   farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size));
  41901. X   f = (void(far * far *)(void))typespecific_workarea;
  41902. X   Store = (union Arg far * far *)(f + MAX_OPS);
  41903. X   Load = (union Arg far * far *)(Store + MAX_STORES);
  41904. X   v = (struct ConstArg far *)(Load + MAX_LOADS);
  41905. X   pfls = (struct fls far *)(v + MAX_ARGS);
  41906. X}
  41907. X
  41908. Xvoid free_workarea()
  41909. X{
  41910. X   if(typespecific_workarea) {
  41911. X      farmemfree(typespecific_workarea);
  41912. X      typespecific_workarea = NULL;
  41913. X   }
  41914. X   Store = (union Arg far * far *)0;
  41915. X   Load = (union Arg far * far *)0;
  41916. X   v = (struct ConstArg far *)0;
  41917. X   f = (void(far * far *)(void))0;    /* CAE fp */
  41918. X   pfls = (struct fls far * )0;   /* CAE fp */
  41919. X
  41920. X}
  41921. SHAR_EOF
  41922. $TOUCH -am 1028230093 parser.c &&
  41923. chmod 0644 parser.c ||
  41924. echo "restore of parser.c failed"
  41925. set `wc -c parser.c`;Wc_c=$1
  41926. if test "$Wc_c" != "54067"; then
  41927.     echo original size 54067, current size $Wc_c
  41928. fi
  41929. # ============= parserfp.c ==============
  41930. echo "x - extracting parserfp.c (Text)"
  41931. sed 's/^X//' << 'SHAR_EOF' > parserfp.c &&
  41932. X/* */
  41933. X/* PARSERFP.C  -- Part of FRACTINT fractal drawer. */
  41934. X/* */
  41935. X/*   By Chuck Ebbert  CompuServe [76306,1226] */
  41936. X/*                     internet: 76306.1226@compuserve.com  */
  41937. X/* */
  41938. X/* Fast floating-point parser code.  The functions beginning with */
  41939. X/*    "fStk" are in PARSERA.ASM.  PARSER.C calls this code after */
  41940. X/*    it has parsed the formula. */
  41941. X/* */
  41942. X/*   Converts the function pointers/load pointers/store pointers */
  41943. X/*       built by parsestr() into an optimized array of function */
  41944. X/*       pointer/operand pointer pairs. */
  41945. X/* */
  41946. X/* ******************************************************************* */
  41947. X/*                                                                     */
  41948. X/*  Copyright (C) 1992, 1993 Chuck Ebbert.  All rights reserved.       */
  41949. X/*                                                                     */
  41950. X/*    This code may be freely distributed and used in non-commercial   */
  41951. X/*    programs provided the author is credited either during program   */
  41952. X/*    execution or in the documentation, and this copyright notice     */
  41953. X/*    is left intact.  Sale of this code, or its use in any commercial */
  41954. X/*    product requires permission from the author.  Nominal            */
  41955. X/*    distribution and handling fees may be charged by shareware and   */
  41956. X/*    freeware distributors.                                           */
  41957. X/*                                                                     */
  41958. X/*       Chuck Ebbert                                                  */
  41959. X/*       1915 Blust Ln.                                                */
  41960. X/*       Enola, PA  17025                                              */
  41961. X/*                                                                     */
  41962. X/* ******************************************************************* */
  41963. X/* */
  41964. X/* Revised 12 July 1993 (for v18.1) by CAE to fix optimizer bug  */
  41965. X/* */
  41966. X/* Revised 22 MAR 1993 (for Fractint v18.0)  */
  41967. X/* */
  41968. X/* Uncomment the next line to enable debug. */
  41969. X/*      #define TESTFP 1  */
  41970. X/* */
  41971. X
  41972. X#include <string.h>
  41973. X#include <ctype.h>
  41974. X#include <stdio.h>
  41975. X#include <stdlib.h>
  41976. X#include <float.h>
  41977. X#include <time.h>
  41978. X#include "mpmath.h"
  41979. X#include "prototyp.h"
  41980. X
  41981. Xextern union Arg *Arg1, *Arg2;
  41982. X/* Some of these variables should be renamed for safety */
  41983. Xextern union Arg s[20], far * far *Store, far * far *Load;
  41984. Xextern int StoPtr, LodPtr, OpPtr;
  41985. Xextern int debugflag;
  41986. Xextern unsigned vsp, LastOp;
  41987. Xextern struct ConstArg far *v;
  41988. Xextern int inside;         /* "inside" color to use    */
  41989. Xextern int outside;        /* "outside" color to use   */
  41990. Xextern int potflag;        /* potential enabled? */
  41991. Xextern char useinitorbit;
  41992. Xextern int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;
  41993. Xextern void (far * far *f)(void);
  41994. X
  41995. Xstruct fls { /* function, load, store pointers  CAE fp */
  41996. X   void (near *function)(void);
  41997. X   union Arg near *operand;
  41998. X} far *pfls = (struct fls far *)0;
  41999. X
  42000. Xvoid  StkLod(void);
  42001. Xvoid  StkClr(void);
  42002. Xvoid  dStkAdd(void);
  42003. Xvoid  dStkSub(void);
  42004. Xvoid  dStkMul(void);
  42005. Xvoid  dStkDiv(void);
  42006. Xvoid  StkSto(void);
  42007. Xvoid  dStkSqr(void);
  42008. Xvoid  EndInit(void);
  42009. Xvoid  dStkMod(void);
  42010. Xvoid  dStkLTE(void);
  42011. Xvoid  dStkSin(void);
  42012. Xvoid  dStkCos(void);
  42013. Xvoid  dStkSinh(void);
  42014. Xvoid  dStkCosh(void);
  42015. Xvoid  dStkCosXX(void);
  42016. Xvoid  dStkTan(void);
  42017. Xvoid  dStkTanh(void);
  42018. Xvoid  dStkCoTan(void);
  42019. Xvoid  dStkCoTanh(void);
  42020. Xvoid  dStkLog(void);
  42021. Xvoid  dStkExp(void);
  42022. Xvoid  dStkPwr(void);
  42023. Xvoid  dStkLT(void);
  42024. Xvoid  dStkFlip(void);
  42025. Xvoid  dStkReal(void);
  42026. Xvoid  dStkImag(void);
  42027. Xvoid  dStkConj(void);
  42028. Xvoid  dStkNeg(void);
  42029. Xvoid  dStkAbs(void);
  42030. Xvoid  dStkRecip(void);
  42031. Xvoid  StkIdent(void);
  42032. Xvoid  dStkGT(void);
  42033. Xvoid  dStkGTE(void);
  42034. Xvoid  dStkNE(void);
  42035. Xvoid  dStkEQ(void);
  42036. Xvoid  dStkAND(void);
  42037. Xvoid  dStkOR(void);
  42038. X
  42039. X#define fgf(x) pfls[(x)].function
  42040. X#define opp(x) pfls[(x)].operand
  42041. X#define NO_OPERAND (void near *)0
  42042. X#define LastSqr v[4].a
  42043. X#define MAX_ARGS 100
  42044. X#define MAX_STACK 8
  42045. X#define TWO_FREE 6
  42046. X
  42047. X#ifndef XFRACT
  42048. X
  42049. Xvoid (near fStkPull2 )(void); /* pull up fpu stack from 2 to 4 */
  42050. Xvoid (near fStkPush2 )(void); /* push down fpu stack from 8 to 6 */
  42051. Xvoid (near fStkPush2a )(void); /* push down fpu stack from 6 to 4 */
  42052. Xvoid (near fStkPush4 )(void); /* push down fpu stack from 8 to 4 */
  42053. Xvoid (near fStkLodDup )(void); /* lod, dup */
  42054. Xvoid (near fStkLodSqr )(void); /* lod, sqr, dont save magnitude */
  42055. Xvoid (near fStkLodSqr2 )(void); /* lod, sqr, save magnitude */
  42056. Xvoid (near fStkStoDup )(void); /* store, duplicate */
  42057. Xvoid (near fStkStoSqr )(void); /* store, sqr, save lastsqr */
  42058. Xvoid (near fStkStoSqr0 )(void); /* store, sqr, dont save lastsqr */
  42059. Xvoid (near fStkLodDbl )(void); /* load, double */
  42060. Xvoid (near fStkStoDbl )(void); /* store, double */
  42061. Xvoid (near fStkReal2 )(void); /* fast ver. of real */
  42062. Xvoid (near fStkSqr )(void); /* sqr, save magnitude in lastsqr */
  42063. Xvoid (near fStkSqr0 )(void); /* sqr, no save magnitude */
  42064. Xvoid (near fStkClr1 )(void); /* clear fpu */
  42065. Xvoid (near fStkClr2 )(void); /* test stack top, clear fpu */
  42066. Xvoid (near fStkStoClr1 )(void); /* store, clr1 */
  42067. Xvoid (near fStkAdd )(void);
  42068. Xvoid (near fStkSub )(void);
  42069. Xvoid (near fStkSto )(void);
  42070. Xvoid (near fStkSto2 )(void); /* fast ver. of sto */
  42071. Xvoid (near fStkLod )(void);
  42072. Xvoid (near fStkEndInit )(void);
  42073. Xvoid (near fStkMod )(void);
  42074. Xvoid (near fStkMod2 )(void);
  42075. Xvoid (near fStkLodMod2 )(void);
  42076. Xvoid (near fStkStoMod2 )(void);
  42077. Xvoid (near fStkLTE )(void);
  42078. Xvoid (near fStkLodLTEMul )(void);
  42079. Xvoid (near fStkLTE2 )(void);
  42080. Xvoid (near fStkLodLTE )(void);
  42081. Xvoid (near fStkLodLTE2 )(void);
  42082. Xvoid (near fStkLodLTEAnd2 )(void);
  42083. Xvoid (near fStkLT )(void);
  42084. Xvoid (near fStkLodLTMul )(void);
  42085. Xvoid (near fStkLT2 )(void);
  42086. Xvoid (near fStkLodLT )(void);
  42087. Xvoid (near fStkLodLT2 )(void);
  42088. Xvoid (near fStkGTE )(void);
  42089. Xvoid (near fStkLodGTE )(void);
  42090. Xvoid (near fStkLodGTE2 )(void);
  42091. Xvoid (near fStkGT )(void);
  42092. Xvoid (near fStkGT2 )(void);
  42093. Xvoid (near fStkLodGT )(void);
  42094. Xvoid (near fStkLodGT2 )(void);
  42095. Xvoid (near fStkEQ )(void);
  42096. Xvoid (near fStkLodEQ )(void);
  42097. Xvoid (near fStkNE )(void);
  42098. Xvoid (near fStkLodNE )(void);
  42099. Xvoid (near fStkAND )(void);
  42100. Xvoid (near fStkANDClr2 )(void);
  42101. Xvoid (near fStkOR )(void);
  42102. Xvoid (near fStkSin )(void);
  42103. Xvoid (near fStkSinh )(void);
  42104. Xvoid (near fStkCos )(void);
  42105. Xvoid (near fStkCosXX )(void);
  42106. Xvoid (near fStkCosh )(void);
  42107. Xvoid (near fStkTan )(void);
  42108. Xvoid (near fStkTanh )(void);
  42109. Xvoid (near fStkCoTan )(void);
  42110. Xvoid (near fStkCoTanh )(void);
  42111. Xvoid (near fStkLog )(void);
  42112. Xvoid (near fStkExp )(void);
  42113. Xvoid (near fStkPwr )(void);
  42114. Xvoid (near fStkMul )(void);
  42115. Xvoid (near fStkDiv )(void);
  42116. Xvoid (near fStkFlip )(void);
  42117. Xvoid (near fStkReal )(void);
  42118. Xvoid (near fStkImag )(void);
  42119. Xvoid (near fStkRealFlip )(void);
  42120. Xvoid (near fStkImagFlip )(void);
  42121. Xvoid (near fStkConj )(void);
  42122. Xvoid (near fStkNeg )(void);
  42123. Xvoid (near fStkAbs )(void);
  42124. Xvoid (near fStkRecip )(void);
  42125. Xvoid (near fStkLodReal )(void);
  42126. Xvoid (near fStkLodRealC )(void);
  42127. Xvoid (near fStkLodImag )(void);
  42128. Xvoid (near fStkLodRealFlip )(void);
  42129. Xvoid (near fStkLodRealAbs )(void);
  42130. Xvoid (near fStkLodRealMul )(void);
  42131. Xvoid (near fStkLodRealAdd )(void);
  42132. Xvoid (near fStkLodRealSub )(void);
  42133. Xvoid (near fStkLodImagFlip )(void);
  42134. Xvoid (near fStkLodImagAbs )(void);
  42135. Xvoid (near fStkLodConj )(void);
  42136. Xvoid (near fStkLodAdd )(void);
  42137. Xvoid (near fStkLodSub )(void);
  42138. Xvoid (near fStkLodSubMod )(void);
  42139. Xvoid (near fStkLodMul )(void);
  42140. Xvoid (near fStkPLodAdd )(void);
  42141. Xvoid (near fStkPLodSub )(void);
  42142. Xvoid (near Img_Setup )(void);
  42143. X
  42144. X
  42145. Xstatic void (near *prevfptr )(void);
  42146. Xstatic int stkcnt, prevstkcnt, cvtptrx, prevlodptr, lastsqrused;
  42147. X
  42148. Xstatic void CvtFptr(void (near * ffptr)(void), int MinStk, int MaxStk,
  42149. X      int Delta )
  42150. X/* (MinStk <= 4, MaxStk >= TWO_FREE) */
  42151. X{
  42152. X   char testconst = 0;
  42153. X
  42154. X   if (stkcnt < MinStk ) { /* not enough operands on fpu stack */
  42155. X#ifdef TESTFP
  42156. X      stopmsg(0, "Inserted pull." );
  42157. X#endif
  42158. X      opp(cvtptrx) = NO_OPERAND;
  42159. X      fgf(cvtptrx++) = fStkPull2;  /* so adjust the stack, pull operand */
  42160. X      stkcnt += 2;
  42161. X   }
  42162. X   else if (stkcnt > MaxStk ) { /* too many operands */
  42163. X#ifdef TESTFP
  42164. X      stopmsg(0, "Inserted push." );
  42165. X#endif
  42166. X      opp(cvtptrx) = NO_OPERAND;
  42167. X      fgf(cvtptrx++) = fStkPush2;  /* push operand to adjust stack */
  42168. X      stkcnt -= 2;
  42169. X   }
  42170. X
  42171. X   /* set the operand pointer here */
  42172. X   if (ffptr == fStkSto ){ /* this must be before test for load */
  42173. X      opp(cvtptrx) = (void near *)(Store[StoPtr++]);
  42174. X   }
  42175. X   else if (ffptr == fStkLod && debugflag == 322 ){
  42176. X      /* if disabling optimizer, set load pointer here */
  42177. X      opp(cvtptrx) = (void near *)(Load[LodPtr++]);
  42178. X   }
  42179. X   else {
  42180. X      opp(cvtptrx) = NO_OPERAND;
  42181. X   }
  42182. X
  42183. X   if (debugflag == 322 ){
  42184. X      goto SkipOptimizer;
  42185. X   } /* --------------------------  begin optimizer  -------------- */
  42186. X
  42187. X   /* For the following: */
  42188. X   /*   * == cvtptrx points to this */
  42189. X   /*  () == this is about to be added to the array */
  42190. X
  42191. X   if (ffptr == fStkLod) { /* we are about to add Lod to the array */
  42192. X      if (prevfptr == fStkLod && Load[LodPtr-1] == Load[LodPtr] ) {
  42193. X         /* previous non-adjust operator was Lod of same operand */
  42194. X         /* i.e. found {? lodx ? (*lodx) } */
  42195. X         if (fgf(--cvtptrx) == fStkPush2 ){ /* prev fn was push */
  42196. X            /* {? lod *push (lod) } */
  42197. X            --cvtptrx; /* found {? *lod push (lod) } */
  42198. X            if (fgf(cvtptrx-1) == fStkPush2){ /* always more ops here */
  42199. X#ifdef TESTFP
  42200. X               stopmsg(0, "push *lod push (lod) -> push4 (*loddup)" );
  42201. X#endif
  42202. X               fgf(cvtptrx-1) = fStkPush4;
  42203. X            }
  42204. X            else { /* prev op not push */
  42205. X#ifdef TESTFP
  42206. X               stopmsg(0, "op *lod push (lod) -> op pusha(p=0) (*loddup)" );
  42207. X#endif
  42208. X               opp(cvtptrx) = NO_OPERAND; /* use 'alternate' push fn. */
  42209. X               fgf(cvtptrx++) = fStkPush2a; /* push with TWO_FREE on stack */
  42210. X               /* operand ptr will be set below */
  42211. X            }
  42212. X         }
  42213. X         else {  /* never {push *lod (lod) } so must be */
  42214. X#ifdef TESTFP
  42215. X            stopmsg(0, "op *lod (lod) -> op (*loddup)" );
  42216. X#endif
  42217. X         }
  42218. X         ffptr = fStkLodDup;
  42219. X      }
  42220. X      else if (prevfptr == fStkSto2
  42221. X               && Store[StoPtr-1] == Load[LodPtr] ){
  42222. X         /* store, load of same value */
  42223. X         /* only one operand on stack here when prev oper is Sto2 */
  42224. X         --cvtptrx;
  42225. X#ifdef TESTFP
  42226. X         stopmsg(0, "*sto2 (lod) -> (*stodup)" );
  42227. X#endif
  42228. X         ffptr = fStkStoDup;
  42229. X      }
  42230. X      /* This may cause roundoff problems when later operators */
  42231. X      /*  use the rounded value that was stored here, while the next */
  42232. X      /*  operator uses the more accurate internal value. */
  42233. X      else if (prevfptr == fStkStoClr1 && prevstkcnt == 2
  42234. X               && Store[StoPtr-1] == Load[LodPtr] ){
  42235. X         /* store, clear, load same value found */
  42236. X         /* only one operand was on stack so this is safe */
  42237. X         --cvtptrx;
  42238. X#ifdef TESTFP
  42239. X         stopmsg (0, "*StoClr1 (Lod) -> (*Sto2)" );
  42240. X#endif
  42241. X         ffptr = fStkSto2; /* use different Sto fn */
  42242. X      }
  42243. X      else {
  42244. X         /* the really awful hack below gets the first char of the name */
  42245. X         /*    of the variable being loaded */
  42246. X         testconst = **(((char * far *)Load[LodPtr] ) - 2 );
  42247. X         if ( !isalpha(testconst) && Load[LodPtr]->d.y == 0.0 ){
  42248. X            /* if first character not alpha, the var is a constant */
  42249. X#ifdef TESTFP
  42250. X            stopmsg (0, "(*lod) -> (*lodrealc)" );
  42251. X#endif
  42252. X            ffptr = fStkLodRealC; /* a real const is being loaded */
  42253. X         }
  42254. X      }
  42255. X      /* set the operand ptr here */
  42256. X      opp(cvtptrx) = (void near *)(Load[LodPtr++]);
  42257. X   }
  42258. X   else if (ffptr == fStkAdd ){
  42259. X      if (prevfptr == fStkLodDup ){ /* there is never a push before add */
  42260. X         --cvtptrx; /* found {? *loddup (add) } */
  42261. X         if (cvtptrx>0 && fgf(cvtptrx-1) == fStkPush2a ){
  42262. X            /* because {push lod lod } impossible so is {push loddup } */
  42263. X#ifdef TESTFP
  42264. X            stopmsg (0, "pusha *loddup (add) -> (*loddbl),stk+=2" );
  42265. X#endif
  42266. X            --cvtptrx;
  42267. X            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptr */
  42268. X            stkcnt += 2;
  42269. X         }
  42270. X         else if (cvtptrx>0 && fgf(cvtptrx-1) == fStkPush4 ){
  42271. X#ifdef TESTFP
  42272. X            stopmsg (0, "push4 *loddup (add) -> push2 (*loddbl),stk+=2" );
  42273. X#endif
  42274. X            fgf(cvtptrx-1) = fStkPush2;
  42275. X            stkcnt += 2;  /*  CAE added 12 July 1993 to fix bug  */
  42276. X         }
  42277. X         else {
  42278. X#ifdef TESTFP
  42279. X            stopmsg (0, "op *loddup (add) -> {op (*loddbl)" );
  42280. X#endif
  42281. X         }
  42282. X         ffptr = fStkLodDbl;
  42283. X      }
  42284. X      else if (prevfptr == fStkStoDup ){
  42285. X#ifdef TESTFP
  42286. X         stopmsg (0, "stodup (add) -> (stodbl)" );
  42287. X#endif
  42288. X         /* there are always exactly 4 on stack here */
  42289. X         --cvtptrx;
  42290. X         ffptr = fStkStoDbl;
  42291. X      }
  42292. X      else if (prevfptr == fStkLod ){ /* have found {lod (*add) } */
  42293. X         --cvtptrx;    /* {? *lod (add) } */
  42294. X         if (fgf(cvtptrx-1) == fStkPush2 ){
  42295. X#ifdef TESTFP
  42296. X            stopmsg (0, "*push load (add) -> (*plodadd),stk+=2" );
  42297. X#endif
  42298. X            --cvtptrx;
  42299. X            stkcnt += 2; /* eliminated a push */
  42300. X            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  42301. X            ffptr = fStkPLodAdd;
  42302. X         }
  42303. X         else {
  42304. X#ifdef TESTFP
  42305. X            stopmsg (0, "op *lod (add) -> op (*lodadd)" );
  42306. X#endif
  42307. X            ffptr = fStkLodAdd;
  42308. X         }
  42309. X      }
  42310. X      else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
  42311. X         --cvtptrx; /* found {? *lodreal (add) } */
  42312. X         if (fgf(cvtptrx-1) == fStkPush2 ){
  42313. X#ifdef TESTFP
  42314. X         stopmsg (0, "*push lodreal (add) -> (*lodrealadd),stk+=2" );
  42315. X#endif
  42316. X            --cvtptrx;
  42317. X            stkcnt += 2;    /* push eliminated */
  42318. X            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  42319. X         }
  42320. X         else {
  42321. X#ifdef TESTFP
  42322. X            stopmsg (0, "*lodreal (add) -> (*lodrealadd)" );
  42323. X#endif
  42324. X         }
  42325. X         ffptr = fStkLodRealAdd;
  42326. X      }
  42327. X   }
  42328. X   else if (ffptr == fStkSub ){
  42329. X      if (prevfptr == fStkLod ){
  42330. X         /* found {lod (*sub) } */
  42331. X         --cvtptrx; /* {*lod (sub) } */
  42332. X         /* there is never a sequence (lod push sub ) */
  42333. X         if (fgf(cvtptrx-1) == fStkPush2 ){
  42334. X#ifdef TESTFP
  42335. X            stopmsg (0, "*push lod (sub) -> (*plodsub),stk+=2" );
  42336. X#endif
  42337. X            --cvtptrx;
  42338. X            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  42339. X            stkcnt += 2; /* push was deleted so adj. stkcnt */
  42340. X            ffptr = fStkPLodSub;
  42341. X         }
  42342. X         else {
  42343. X#ifdef TESTFP
  42344. X            stopmsg (0, "*lod (sub) -> (*lodsub)" );
  42345. X#endif
  42346. X            ffptr = fStkLodSub;
  42347. X         }
  42348. X      }
  42349. X      else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
  42350. X         --cvtptrx; /* {? *lodreal (sub) } */
  42351. X         if (fgf(cvtptrx-1) == fStkPush2 ){
  42352. X#ifdef TESTFP
  42353. X            stopmsg (0, "*push lodreal (sub) -> (*lodrealsub),stk+=2" );
  42354. X#endif
  42355. X            --cvtptrx;
  42356. X            stkcnt += 2;    /* push eliminated */
  42357. X            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  42358. X         }
  42359. X         else {
  42360. X#ifdef TESTFP
  42361. X            stopmsg (0, "*lodreal (sub) -> (*lodrealsub)" );
  42362. X#endif
  42363. X         }
  42364. X         ffptr = fStkLodRealSub;
  42365. X      }
  42366. X   }
  42367. X   else if (ffptr == fStkMul ){
  42368. X      if (prevfptr == fStkLodDup ){
  42369. X         /* found {loddup ? (*mul) } */
  42370. X         if (fgf(--cvtptrx) == fStkPush2 ){
  42371. X#ifdef TESTFP
  42372. X            stopmsg (0, "loddup *push (mul) -> (*lodsqr),stk+=2" );
  42373. X#endif
  42374. X            stkcnt += 2; /* eliminate this push */
  42375. X            --cvtptrx;    /* prev is a LodDup */
  42376. X         }
  42377. X         else {
  42378. X#ifdef TESTFP
  42379. X            stopmsg (0, "*loddup (mul) -> (*lodsqr)" );
  42380. X#endif
  42381. X         }
  42382. X         ffptr = fStkLodSqr;
  42383. X      }
  42384. X      else if (prevfptr == fStkStoDup ){ /* no pushes here, 4 on stk. */
  42385. X#ifdef TESTFP
  42386. X         stopmsg (0, "stodup (mul) -> (*stosqr0)" );
  42387. X#endif
  42388. X         --cvtptrx;
  42389. X         ffptr = fStkStoSqr0; /* dont save lastsqr here ever */
  42390. X      }
  42391. X      else if (prevfptr == fStkLod ){
  42392. X         --cvtptrx; /* {lod *? (mul) } */
  42393. X         if (fgf(cvtptrx) == fStkPush2 ){ /* {lod *push (mul) } */
  42394. X            --cvtptrx; /* {? *lod push (mul) } */
  42395. X            if(fgf(cvtptrx-1) == fStkPush2 ){
  42396. X#ifdef TESTFP
  42397. X               stopmsg (0, "push *lod push (mul) -> push4 (*lodmul)" );
  42398. X#endif
  42399. X               fgf(cvtptrx-1) = fStkPush4;
  42400. X            }
  42401. X            else {
  42402. X#ifdef TESTFP
  42403. X               stopmsg (0, "op *lod push (mul) -> op pusha (*lodmul)" );
  42404. X#endif
  42405. X               opp(cvtptrx+1) = opp(cvtptrx); /* fix operand ptr */
  42406. X               fgf(cvtptrx) = fStkPush2a;
  42407. X               opp(cvtptrx++) = NO_OPERAND;
  42408. X            }
  42409. X         }
  42410. X         else {
  42411. X#ifdef TESTFP
  42412. X            stopmsg (0, "*lod (mul) -> (*lodmul)" );
  42413. X#endif
  42414. X         }
  42415. X         ffptr = fStkLodMul;
  42416. X      }
  42417. X      else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
  42418. X         --cvtptrx; /* found {lodreal *? (mul) } */
  42419. X         if (fgf(cvtptrx) == fStkPush2 ){
  42420. X#ifdef TESTFP
  42421. X            stopmsg (0, "lodreal *push2 (mul) -> (*lodrealmul),stk+=2" );
  42422. X#endif
  42423. X            --cvtptrx;
  42424. X            stkcnt += 2;    /* stack ends with TWO_FREE, not 4 */
  42425. X         }
  42426. X         else {
  42427. X#ifdef TESTFP
  42428. X            stopmsg (0, "*lodreal (mul) }-> {(*lodrealmul)" );
  42429. X#endif
  42430. X         }
  42431. X         ffptr = fStkLodRealMul;
  42432. X      }
  42433. X      else if (prevfptr == fStkLodLT && fgf(cvtptrx-1) != fStkPull2 ){
  42434. X         /* this shortcut fails if {Lod LT Pull Mul } found */
  42435. X#ifdef TESTFP
  42436. X         stopmsg (0, "LodLT (*Mul) -> (*LodLTMul)" );
  42437. X#endif
  42438. X         --cvtptrx; /* never { lod LT Push Mul } here */
  42439. X         ffptr = fStkLodLTMul;
  42440. X      }
  42441. X      else if (prevfptr == fStkLodLTE && fgf(cvtptrx-1) != fStkPull2 ){
  42442. X#ifdef TESTFP
  42443. X         stopmsg (0, "LodLTE (*mul) -> (*LodLTEmul)" );
  42444. X#endif
  42445. X         --cvtptrx;
  42446. X         ffptr = fStkLodLTEMul;
  42447. X      }
  42448. X   }
  42449. X   else if (ffptr == fStkClr1 && prevfptr == fStkSto ){
  42450. X#ifdef TESTFP
  42451. X         stopmsg (0, "sto (*clr1) -> (*stoclr1)" );
  42452. X#endif
  42453. X      --cvtptrx;
  42454. X      ffptr = fStkStoClr1;
  42455. X   }
  42456. X   else if (ffptr == fStkDiv ){
  42457. X      if (prevfptr == fStkLodRealC && vsp < MAX_ARGS - 1 ){
  42458. X         /* have found a divide by a real constant */
  42459. X         /*  and there is space to create a new one */
  42460. X         /* {lodrealc ? (*div) } */
  42461. X         --cvtptrx; /* change '/ const' to '* 1/const' */
  42462. X         if (fgf(cvtptrx) == fStkPush2 ){
  42463. X#ifdef TESTFP
  42464. X            stopmsg (0, "lodrealc *push (div) -> (*lodrealmul),stk+=2" );
  42465. X#endif
  42466. X            --cvtptrx;
  42467. X            stkcnt += 2;
  42468. X         }
  42469. X         else {
  42470. X#ifdef TESTFP
  42471. X            stopmsg (0, "*lodrealc (div) -> {(*lodrealmul)" );
  42472. X#endif
  42473. X         }
  42474. X         v[vsp].s = (void near *)0; /* this constant has no name */
  42475. X         v[vsp].len = 0;
  42476. X         v[vsp].a.d.x = 1.0 / Load[LodPtr-1]->d.x;
  42477. X         v[vsp].a.d.y = 0.0;
  42478. X         opp(cvtptrx) = (void near *)&v[vsp++].a; /* isn't C fun! */
  42479. X         ffptr = fStkLodRealMul;
  42480. X      }
  42481. X   }
  42482. X   else if (ffptr == fStkReal ){
  42483. X      if (prevfptr == fStkLod ){
  42484. X#ifdef TESTFP
  42485. X         stopmsg (0, "lod (*real) -> (*lodreal)" );
  42486. X#endif
  42487. X         --cvtptrx;
  42488. X         ffptr = fStkLodReal;
  42489. X      }
  42490. X      else if (stkcnt < MAX_STACK ){
  42491. X#ifdef TESTFP
  42492. X         stopmsg (0, "(*real) -> (*real2)" );
  42493. X#endif
  42494. X         ffptr = fStkReal2;
  42495. X      }
  42496. X   }
  42497. X   else if (ffptr == fStkImag && prevfptr == fStkLod ){
  42498. X#ifdef TESTFP
  42499. X         stopmsg (0, "lod (*imag) -> lodimag" );
  42500. X#endif
  42501. X      --cvtptrx;
  42502. X      ffptr = fStkLodImag;
  42503. X   }
  42504. X   else if (ffptr == fStkConj && prevfptr == fStkLod ){
  42505. X#ifdef TESTFP
  42506. X         stopmsg (0, "lod (*conj) -> (*lodconj)" );
  42507. X#endif
  42508. X      --cvtptrx;
  42509. X      ffptr = fStkLodConj;
  42510. X   }
  42511. X   else if (ffptr == fStkMod && stkcnt < MAX_STACK ){
  42512. X#ifdef TESTFP
  42513. X      stopmsg (0, "(*mod) -> (*mod2)" );
  42514. X#endif
  42515. X      ffptr = fStkMod2; /* use faster version if room on stack */
  42516. X      if (prevfptr == fStkLod ){
  42517. X#ifdef TESTFP
  42518. X         stopmsg (0, "lod (*mod2) -> (*lodmod2)" );
  42519. X#endif
  42520. X         --cvtptrx;
  42521. X         ffptr = fStkLodMod2;
  42522. X      }
  42523. X      else if (prevfptr == fStkSto || prevfptr == fStkSto2 ){
  42524. X#ifdef TESTFP
  42525. X         stopmsg (0, "sto (*mod2) -> (*stomod2)" );
  42526. X#endif
  42527. X         --cvtptrx;
  42528. X         ffptr = fStkStoMod2;
  42529. X      }
  42530. X      else if (prevfptr == fStkLodSub ){
  42531. X#ifdef TESTFP
  42532. X         stopmsg (0, "lodsub (*mod2) -> (*lodsubmod)" );
  42533. X#endif
  42534. X         --cvtptrx;
  42535. X         ffptr = fStkLodSubMod;
  42536. X      }
  42537. X   }
  42538. X   else if (ffptr == fStkFlip ){
  42539. X      if (prevfptr == fStkReal || prevfptr == fStkReal2 ){
  42540. X#ifdef TESTFP
  42541. X         stopmsg (0, "real (*flip) -> (*realflip)" );
  42542. X#endif
  42543. X         --cvtptrx;
  42544. X         ffptr = fStkRealFlip;
  42545. X      }
  42546. X      else if (prevfptr == fStkImag ){
  42547. X#ifdef TESTFP
  42548. X         stopmsg (0, "imag (*flip) -> (*imagflip)" );
  42549. X#endif
  42550. X         --cvtptrx;
  42551. X         ffptr = fStkImagFlip;
  42552. X      }
  42553. X      else if (prevfptr == fStkLodReal ){
  42554. X#ifdef TESTFP
  42555. X         stopmsg (0, "lodreal (*flip) -> (*lodrealflip)" );
  42556. X#endif
  42557. X         --cvtptrx;
  42558. X         ffptr = fStkLodRealFlip;
  42559. X      }
  42560. X      else if (prevfptr == fStkLodImag ){
  42561. X#ifdef TESTFP
  42562. X         stopmsg (0, "lodimag (*flip) -> (*lodimagflip)" );
  42563. X#endif
  42564. X         --cvtptrx;
  42565. X         ffptr = fStkLodImagFlip;
  42566. X      }
  42567. X   }
  42568. X   else if (ffptr == fStkAbs ){
  42569. X      if (prevfptr == fStkLodReal ){
  42570. X#ifdef TESTFP
  42571. X         stopmsg (0, "lodreal (*abs) -> (*lodrealabs)" );
  42572. X#endif
  42573. X         --cvtptrx;
  42574. X         ffptr = fStkLodRealAbs;
  42575. X      }
  42576. X      else if (prevfptr == fStkLodImag ){
  42577. X#ifdef TESTFP
  42578. X         stopmsg (0, "lodimag (*abs) -> (*lodimagabs)" );
  42579. X#endif
  42580. X         --cvtptrx;
  42581. X         ffptr = fStkLodImagAbs;
  42582. X      }
  42583. X   }
  42584. X   else if (ffptr == fStkSqr ){
  42585. X      if (prevfptr == fStkLod && fgf(cvtptrx-1) != fStkPush2 ){
  42586. X#ifdef TESTFP
  42587. X         stopmsg (0, "lod (*sqr) -> (*lodsqr)" );
  42588. X#endif
  42589. X         --cvtptrx;
  42590. X         ffptr = fStkLodSqr; /* assume no need to save lastsqr */
  42591. X         if (lastsqrused) {
  42592. X#ifdef TESTFP
  42593. X            stopmsg (0, "(*lodsqr) -> (*lodsqr2)" );
  42594. X#endif
  42595. X            ffptr = fStkLodSqr2; /* lastsqr is being used */
  42596. X         }
  42597. X      }
  42598. X      else if (prevfptr == fStkSto2 ){
  42599. X#ifdef TESTFP
  42600. X         stopmsg (0, "sto2 (*sqr) -> (*stosqr0)" );
  42601. X#endif
  42602. X         --cvtptrx;
  42603. X         ffptr = fStkStoSqr0; /* assume no need to save lastsqr */
  42604. X         if (lastsqrused) {
  42605. X#ifdef TESTFP
  42606. X            stopmsg (0, "(*stosqr0) -> (*stosqr)" );
  42607. X#endif
  42608. X            ffptr = fStkStoSqr; /* save lastsqr */
  42609. X         }
  42610. X      }
  42611. X      else {
  42612. X         if (!lastsqrused) {
  42613. X#ifdef TESTFP
  42614. X            stopmsg (0, "(*sqr) -> (*sqr0)" );
  42615. X#endif
  42616. X            ffptr = fStkSqr0; /* don't save lastsqr */
  42617. X         }
  42618. X      }
  42619. X   }
  42620. X   else if (ffptr == fStkLTE && ( prevfptr == fStkLod
  42621. X         || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  42622. X#ifdef TESTFP
  42623. X      stopmsg(0, "Lod (*LTE) -> (*LodLTE)" );
  42624. X#endif
  42625. X      --cvtptrx;
  42626. X      ffptr = fStkLodLTE;
  42627. X   }
  42628. X   else if (ffptr == fStkLT && ( prevfptr == fStkLod
  42629. X         || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  42630. X#ifdef TESTFP
  42631. X      stopmsg(0, "Lod (*LT) -> (*LodLT)" );
  42632. X#endif
  42633. X      --cvtptrx;
  42634. X      ffptr = fStkLodLT;
  42635. X   }
  42636. X   else if (ffptr == fStkGT && ( prevfptr == fStkLod
  42637. X         || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  42638. X#ifdef TESTFP
  42639. X      stopmsg(0, "Lod (*GT) -> (*LodGT)" );
  42640. X#endif
  42641. X      --cvtptrx;
  42642. X      ffptr = fStkLodGT;
  42643. X   }
  42644. X   else if (ffptr == fStkGTE && ( prevfptr == fStkLod
  42645. X         || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  42646. X#ifdef TESTFP
  42647. X      stopmsg(0, "Lod (*GTE) -> (*LodGTE)" );
  42648. X#endif
  42649. X      --cvtptrx;
  42650. X      ffptr = fStkLodGTE;
  42651. X   }
  42652. X   else if (ffptr == fStkNE && ( prevfptr == fStkLod
  42653. X         || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  42654. X#ifdef TESTFP
  42655. X      stopmsg(0, "Lod (*NE) -> (*LodNE)" );
  42656. X#endif
  42657. X      --cvtptrx;
  42658. X      ffptr = fStkLodNE;
  42659. X   }
  42660. X   else if (ffptr == fStkEQ && ( prevfptr == fStkLod
  42661. X         || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  42662. X#ifdef TESTFP
  42663. X      stopmsg(0, "Lod (*EQ) -> (*LodEQ)" );
  42664. X#endif
  42665. X      --cvtptrx;
  42666. X      ffptr = fStkLodEQ;
  42667. X   }
  42668. X
  42669. XSkipOptimizer:  /* -----------  end of optimizer code  ------------ */
  42670. X
  42671. X   fgf(cvtptrx++) = prevfptr = ffptr;
  42672. X   prevstkcnt = stkcnt;
  42673. X
  42674. X   if (Delta == 999 ){
  42675. X      stkcnt = 0;
  42676. X   }
  42677. X   else {
  42678. X      stkcnt += Delta;
  42679. X   }
  42680. X   return;
  42681. X}
  42682. X
  42683. Xint CvtStk() {    /* convert the array of ptrs */
  42684. X   extern int fform_per_pixel(void);    /* these fns are in parsera.asm */
  42685. X   extern int fFormula(void);
  42686. X   extern int BadFormula(void);
  42687. X   extern char FormName[];
  42688. X   void (far *ftst)(void);
  42689. X   void (near *ntst)(void);
  42690. X
  42691. X#ifdef TESTFP
  42692. X   if (debugflag == 322) {
  42693. X      stopmsg(0, "Skipping optimizer." );
  42694. X   }
  42695. X#endif
  42696. X
  42697. X   for (OpPtr = LodPtr = lastsqrused = 0; OpPtr < LastOp; OpPtr++) {
  42698. X      ftst = f[OpPtr];
  42699. X      if (ftst == StkLod && Load[LodPtr++] == &LastSqr ){
  42700. X         lastsqrused = 1; /* lastsqr is being used in the formula */
  42701. X      }
  42702. X      if (  ftst != StkLod  /* these are the supported parser fns */
  42703. X            && ftst != StkClr
  42704. X            && ftst != dStkAdd
  42705. X            && ftst != dStkSub
  42706. X            && ftst != dStkMul
  42707. X            && ftst != dStkDiv
  42708. X            && ftst != StkSto
  42709. X            && ftst != dStkSqr
  42710. X            && ftst != EndInit
  42711. X            && ftst != dStkMod
  42712. X            && ftst != dStkLTE
  42713. X            && ftst != dStkSin
  42714. X            && ftst != dStkCos
  42715. X            && ftst != dStkSinh
  42716. X            && ftst != dStkCosh
  42717. X            && ftst != dStkCosXX
  42718. X            && ftst != dStkTan
  42719. X            && ftst != dStkTanh
  42720. X            && ftst != dStkCoTan
  42721. X            && ftst != dStkCoTanh
  42722. X            && ftst != dStkLog
  42723. X            && ftst != dStkExp
  42724. X            && ftst != dStkPwr
  42725. X            && ftst != dStkLT
  42726. X            && ftst != dStkFlip
  42727. X            && ftst != dStkReal
  42728. X            && ftst != dStkImag
  42729. X            && ftst != dStkConj
  42730. X            && ftst != dStkNeg
  42731. X            && ftst != dStkAbs
  42732. X            && ftst != dStkRecip
  42733. X            && ftst != StkIdent
  42734. X            && ftst != dStkGT
  42735. X            && ftst != dStkGTE
  42736. X            && ftst != dStkNE
  42737. X            && ftst != dStkEQ
  42738. X            && ftst != dStkAND
  42739. X            && ftst != dStkOR ){
  42740. X         stopmsg(0, "Fast failure, using old code" );
  42741. X         return 1; /* Use old code */
  42742. X      }
  42743. X   }
  42744. X
  42745. X#ifdef TESTFP
  42746. X   if (lastsqrused) {
  42747. X      stopmsg(0, "LastSqr used" );
  42748. X   }
  42749. X   else {
  42750. X      stopmsg(0, "LastSqr not used" );
  42751. X   }
  42752. X#endif
  42753. X
  42754. X   if (f[LastOp-1] != StkClr ){ /* some formulas don't clear at the end! */
  42755. X#ifdef TESTFP
  42756. X      stopmsg (0, "clr added at end" );
  42757. X#endif
  42758. X      f[LastOp++] = StkClr;
  42759. X   }
  42760. X   prevfptr = (void (near *)(void))0;
  42761. X   prevstkcnt = 999; /* there was not previous stk cnt */
  42762. X   stkcnt = cvtptrx = 0;
  42763. X
  42764. X   for (OpPtr = LodPtr = StoPtr = 0; OpPtr < LastOp; OpPtr++) {
  42765. X      ftst = f[OpPtr];
  42766. X      if (ftst == StkLod ) {
  42767. X#ifdef TESTFP
  42768. X         stopmsg(0, "lod,0,TWO_FREE,2" );
  42769. X#endif
  42770. X         CvtFptr(fStkLod, 0, TWO_FREE, 2 );
  42771. X         continue;
  42772. X      }
  42773. X      if (ftst == StkClr ) {
  42774. X         if (OpPtr == LastOp - 1 ){
  42775. X#ifdef TESTFP
  42776. X            stopmsg(0, "clr2,0,MAX_STACK,999" );
  42777. X#endif
  42778. X            CvtFptr(fStkClr2, 0, MAX_STACK, 999 );
  42779. X         } else {
  42780. X#ifdef TESTFP
  42781. X            stopmsg(0, "clr1,0,MAX_STACK,999" );
  42782. X#endif
  42783. X            CvtFptr(fStkClr1, 0, MAX_STACK, 999 );
  42784. X         }
  42785. X         continue;
  42786. X      }
  42787. X      if (ftst == dStkAdd ) {
  42788. X#ifdef TESTFP
  42789. X         stopmsg(0, "add,4,MAX_STACK,-2" );
  42790. X#endif
  42791. X         CvtFptr(fStkAdd, 4, MAX_STACK, -2 );
  42792. X         continue;
  42793. X      }
  42794. X      if (ftst == dStkSub ) {
  42795. X#ifdef TESTFP
  42796. X         stopmsg(0, "sub,4,MAX_STACK,-2" );
  42797. X#endif
  42798. X         CvtFptr(fStkSub, 4, MAX_STACK, -2 );
  42799. X         continue;
  42800. X      }
  42801. X      if (ftst == dStkDiv ) {
  42802. X#ifdef TESTFP
  42803. X         stopmsg(0, "div,4,TWO_FREE,-2" );
  42804. X#endif
  42805. X         CvtFptr(fStkDiv, 4, TWO_FREE, -2 );
  42806. X         continue;
  42807. X      }
  42808. X      if (ftst == dStkMul ) {
  42809. X#ifdef TESTFP
  42810. X         stopmsg(0, "mul,4,TWO_FREE,-2" );
  42811. X#endif
  42812. X         CvtFptr(fStkMul, 4, TWO_FREE, -2 );
  42813. X         continue;
  42814. X      }
  42815. X      if (ftst == StkSto ) {
  42816. X#ifdef TESTFP
  42817. X         stopmsg(0, "sto,2,MAX_STACK,0" );
  42818. X#endif
  42819. X         CvtFptr(fStkSto, 2, MAX_STACK, 0 );
  42820. X         continue;
  42821. X      }
  42822. X      if (ftst == dStkSqr ) {
  42823. X#ifdef TESTFP
  42824. X         stopmsg(0, "sqr,2,TWO_FREE,0" );
  42825. X#endif
  42826. X         CvtFptr(fStkSqr, 2, TWO_FREE, 0 );
  42827. X         continue;
  42828. X      }
  42829. X      if (ftst == EndInit) {
  42830. X#ifdef TESTFP
  42831. X         stopmsg(0, "endinit,0,MAX_STACK,999" );
  42832. X#endif
  42833. X         CvtFptr(fStkEndInit, 0, MAX_STACK, 999 );
  42834. X         continue;
  42835. X      }
  42836. X      if (ftst == dStkMod ) {
  42837. X#ifdef TESTFP
  42838. X         stopmsg(0, "mod,2,MAX_STACK,0" );
  42839. X#endif
  42840. X         CvtFptr(fStkMod, 2, MAX_STACK, 0 );
  42841. X         continue;
  42842. X      }
  42843. X      if (ftst == dStkLTE ) {
  42844. X#ifdef TESTFP
  42845. X         stopmsg(0, "LTE,4,MAX_STACK,-2" );
  42846. X#endif
  42847. X         CvtFptr(fStkLTE, 4, MAX_STACK, -2 );
  42848. X         continue;
  42849. X      }
  42850. X      if (ftst == dStkSin ) {
  42851. X#ifdef TESTFP
  42852. X         stopmsg(0, "sin,2,TWO_FREE,0" );
  42853. X#endif
  42854. X         CvtFptr(fStkSin, 2, TWO_FREE, 0 );
  42855. X         continue;
  42856. X      }
  42857. X      if (ftst == dStkCos ) {
  42858. X#ifdef TESTFP
  42859. X         stopmsg(0, "cos,2,TWO_FREE,0" );
  42860. X#endif
  42861. X         CvtFptr(fStkCos, 2, TWO_FREE, 0 );
  42862. X         continue;
  42863. X      }
  42864. X      if (ftst == dStkSinh ) {
  42865. X#ifdef TESTFP
  42866. X         stopmsg(0, "sinh,2,TWO_FREE,0" );
  42867. X#endif
  42868. X         CvtFptr(fStkSinh, 2, TWO_FREE, 0 );
  42869. X         continue;
  42870. X      }
  42871. X      if (ftst == dStkCosh ) {
  42872. X#ifdef TESTFP
  42873. X         stopmsg(0, "cosh,2,TWO_FREE,0" );
  42874. X#endif
  42875. X         CvtFptr(fStkCosh, 2, TWO_FREE, 0 );
  42876. X         continue;
  42877. X      }
  42878. X      if (ftst == dStkCosXX ) {
  42879. X#ifdef TESTFP
  42880. X         stopmsg(0, "cosxx,2,TWO_FREE,0" );
  42881. X#endif
  42882. X         CvtFptr(fStkCosXX, 2, TWO_FREE, 0 );
  42883. X         continue;
  42884. X      }
  42885. X      if (ftst == dStkTan ) {
  42886. X#ifdef TESTFP
  42887. X         stopmsg(0, "tan,2,TWO_FREE,0" );
  42888. X#endif
  42889. X         CvtFptr(fStkTan, 2, TWO_FREE, 0 );
  42890. X         continue;
  42891. X      }
  42892. X      if (ftst == dStkTanh ) {
  42893. X#ifdef TESTFP
  42894. X         stopmsg(0, "tanh,2,TWO_FREE,0" );
  42895. X#endif
  42896. X         CvtFptr(fStkTanh, 2, TWO_FREE, 0 );
  42897. X         continue;
  42898. X      }
  42899. X      if (ftst == dStkCoTan ) {
  42900. X#ifdef TESTFP
  42901. X         stopmsg(0, "cotan,2,TWO_FREE,0" );
  42902. X#endif
  42903. X         CvtFptr(fStkCoTan, 2, TWO_FREE, 0 );
  42904. X         continue;
  42905. X      }
  42906. X      if (ftst == dStkCoTanh ) {
  42907. X#ifdef TESTFP
  42908. X         stopmsg(0, "cotanh,2,TWO_FREE,0" );
  42909. X#endif
  42910. X         CvtFptr(fStkCoTanh, 2, TWO_FREE, 0 );
  42911. X         continue;
  42912. X      }
  42913. X      if (ftst == dStkExp ) {
  42914. X#ifdef TESTFP
  42915. X         stopmsg(0, "exp,2,TWO_FREE,0" );
  42916. X#endif
  42917. X         CvtFptr(fStkExp, 2, TWO_FREE, 0 );
  42918. X         continue;
  42919. X      }
  42920. X      if (ftst == dStkLog ) {
  42921. X#ifdef TESTFP
  42922. X         stopmsg(0, "log,2,TWO_FREE,0" );
  42923. X#endif
  42924. X         CvtFptr(fStkLog, 2, TWO_FREE, 0 );
  42925. X         continue;
  42926. X      }
  42927. X      if (ftst == dStkPwr ) {
  42928. X#ifdef TESTFP
  42929. X         stopmsg(0, "pwr,4,TWO_FREE,-2" );
  42930. X#endif
  42931. X         CvtFptr(fStkPwr, 4, TWO_FREE, -2 );
  42932. X         continue;
  42933. X      }
  42934. X      if (ftst == dStkLT ) {
  42935. X#ifdef TESTFP
  42936. X         stopmsg(0, "LT,4,MAX_STACK,-2" );
  42937. X#endif
  42938. X         CvtFptr(fStkLT, 4, MAX_STACK, -2 );
  42939. X         continue;
  42940. X      }
  42941. X      if (ftst == dStkFlip ) {
  42942. X#ifdef TESTFP
  42943. X         stopmsg(0, "flip,2,MAX_STACK,0" );
  42944. X#endif
  42945. X         CvtFptr(fStkFlip, 2, MAX_STACK, 0 );
  42946. X         continue;
  42947. X      }
  42948. X      if (ftst == dStkReal ) {
  42949. X#ifdef TESTFP
  42950. X         stopmsg(0, "real,2,MAX_STACK,0" );
  42951. X#endif
  42952. X         CvtFptr(fStkReal, 2, MAX_STACK, 0 );
  42953. X         continue;
  42954. X      }
  42955. X      if (ftst == dStkImag ) {
  42956. X#ifdef TESTFP
  42957. X         stopmsg(0, "imag,2,MAX_STACK,0" );
  42958. X#endif
  42959. X         CvtFptr(fStkImag, 2, MAX_STACK, 0 );
  42960. X         continue;
  42961. X      }
  42962. X      if (ftst == dStkConj ) {
  42963. X#ifdef TESTFP
  42964. X         stopmsg(0, "conj,2,MAX_STACK,0" );
  42965. X#endif
  42966. X         CvtFptr(fStkConj, 2, MAX_STACK, 0 );
  42967. X         continue;
  42968. X      }
  42969. X      if (ftst == dStkNeg ) {
  42970. X#ifdef TESTFP
  42971. X         stopmsg(0, "neg,2,MAX_STACK,0" );
  42972. X#endif
  42973. X         CvtFptr(fStkNeg, 2, MAX_STACK, 0 );
  42974. X         continue;
  42975. X      }
  42976. X      if (ftst == dStkAbs ) {
  42977. X#ifdef TESTFP
  42978. X         stopmsg(0, "abs,2,MAX_STACK,0" );
  42979. X#endif
  42980. X         CvtFptr(fStkAbs, 2, MAX_STACK, 0 );
  42981. X         continue;
  42982. X      }
  42983. X      if (ftst == dStkRecip ) {
  42984. X#ifdef TESTFP
  42985. X         stopmsg(0, "recip,2,TWO_FREE,0" );
  42986. X#endif
  42987. X         CvtFptr(fStkRecip, 2, TWO_FREE, 0 );
  42988. X         continue;
  42989. X      }
  42990. X      if (ftst == StkIdent ) {
  42991. X#ifdef TESTFP
  42992. X         stopmsg(0, "ident skipped" );
  42993. X#endif
  42994. X         /* don't bother converting this one */
  42995. X         continue;
  42996. X      }
  42997. X      if (ftst == dStkGT ) {
  42998. X#ifdef TESTFP
  42999. X         stopmsg(0, "GT,4,MAX_STACK,-2" );
  43000. X#endif
  43001. X         CvtFptr(fStkGT, 4, MAX_STACK, -2 );
  43002. X         continue;
  43003. X      }
  43004. X      if (ftst == dStkGTE ) {
  43005. X#ifdef TESTFP
  43006. X         stopmsg(0, "GTE,4,MAX_STACK,-2" );
  43007. X#endif
  43008. X         CvtFptr(fStkGTE, 4, MAX_STACK, -2 );
  43009. X         continue;
  43010. X      }
  43011. X      if (ftst == dStkEQ ) {
  43012. X#ifdef TESTFP
  43013. X         stopmsg(0, "EQ,4,MAX_STACK,-2" );
  43014. X#endif
  43015. X         CvtFptr(fStkEQ, 4, MAX_STACK, -2 );
  43016. X         continue;
  43017. X      }
  43018. X      if (ftst == dStkNE ) {
  43019. X#ifdef TESTFP
  43020. X         stopmsg(0, "NE,4,MAX_STACK,-2" );
  43021. X#endif
  43022. X         CvtFptr(fStkNE, 4, MAX_STACK, -2 );
  43023. X         continue;
  43024. X      }
  43025. X      if (ftst == dStkOR ) {
  43026. X#ifdef TESTFP
  43027. X         stopmsg(0, "OR,4,MAX_STACK,-2" );
  43028. X#endif
  43029. X         CvtFptr(fStkOR, 4, MAX_STACK, -2 );
  43030. X         continue;
  43031. X      }
  43032. X      if (ftst == dStkAND ) {
  43033. X#ifdef TESTFP
  43034. X         stopmsg(0, "AND,4,MAX_STACK,-2" );
  43035. X#endif
  43036. X         CvtFptr(fStkAND, 4, MAX_STACK, -2 );
  43037. X         continue;
  43038. X      }
  43039. X      stopmsg(0, "Fast failure, using old code." );
  43040. X      return 1; /* this should never happen but is not fatal now */
  43041. X   }
  43042. X
  43043. X   if (debugflag == 322 ){
  43044. X      /* skip these optimizations too */
  43045. X      goto skipfinalopt;
  43046. X   } /* ---------------------------------- final optimizations ---- */
  43047. X
  43048. X   ntst = fgf(cvtptrx-2 ); /* cvtptrx -> one past last operator (clr2) */
  43049. X   if (ntst == fStkLT ){
  43050. X#ifdef TESTFP
  43051. X      stopmsg (0, "LT Clr2 -> LT2" );
  43052. X#endif
  43053. X      --cvtptrx;
  43054. X      fgf(cvtptrx-1) = fStkLT2;
  43055. X   }
  43056. X   else if (ntst == fStkLodLT ){
  43057. X#ifdef TESTFP
  43058. X      stopmsg (0, "LodLT Clr2 -> LodLT2" );
  43059. X#endif
  43060. X      --cvtptrx;
  43061. X      fgf(cvtptrx-1) = fStkLodLT2;
  43062. X   }
  43063. X   else if (ntst == fStkLTE ){
  43064. X#ifdef TESTFP
  43065. X      stopmsg (0, "LTE Clr2 -> LTE2" );
  43066. X#endif
  43067. X      --cvtptrx;
  43068. X      fgf(cvtptrx-1) = fStkLTE2;
  43069. X   }
  43070. X   else if (ntst == fStkLodLTE ){
  43071. X#ifdef TESTFP
  43072. X      stopmsg (0, "LodLTE Clr2 -> LodLTE2" );
  43073. X#endif
  43074. X      --cvtptrx;
  43075. X      fgf(cvtptrx-1) = fStkLodLTE2;
  43076. X   }
  43077. X   else if (ntst == fStkGT ){
  43078. X#ifdef TESTFP
  43079. X      stopmsg (0, "GT Clr2 -> GT2" );
  43080. X#endif
  43081. X      --cvtptrx;
  43082. X      fgf(cvtptrx-1) = fStkGT2;
  43083. X   }
  43084. X   else if (ntst == fStkLodGT ){
  43085. X#ifdef TESTFP
  43086. X      stopmsg (0, "LodGT Clr2 -> LodGT2" );
  43087. X#endif
  43088. X      --cvtptrx;
  43089. X      fgf(cvtptrx-1) = fStkLodGT2;
  43090. X   }
  43091. X   else if (ntst == fStkLodGTE ){
  43092. X#ifdef TESTFP
  43093. X      stopmsg (0, "LodGTE Clr2 -> LodGTE2" );
  43094. X#endif
  43095. X      --cvtptrx;
  43096. X      fgf(cvtptrx-1) = fStkLodGTE2;
  43097. X   }
  43098. X   else if (fgf(cvtptrx-2 ) == fStkAND ){
  43099. X#ifdef TESTFP
  43100. X      stopmsg (0, "AND Clr2 -> ANDClr2" );
  43101. X#endif
  43102. X      --cvtptrx;
  43103. X      fgf(cvtptrx-1) = fStkANDClr2;
  43104. X      ntst = fgf(cvtptrx-2);
  43105. X      if (ntst == fStkLodLTE ){
  43106. X#ifdef TESTFP
  43107. X         stopmsg (0, "LodLTE ANDClr2 -> LodLTEAnd2" );
  43108. X#endif
  43109. X         --cvtptrx;
  43110. X         fgf(cvtptrx-1) = fStkLodLTEAnd2;
  43111. X      }
  43112. X   }
  43113. X
  43114. Xskipfinalopt: /* ---------------- end of final optimizations ----- */
  43115. X
  43116. X   LastOp = cvtptrx; /* save the new operator count */
  43117. X   LastSqr.d.y = 0.0; /* do this once per image */
  43118. X
  43119. X   /* now change the pointers */
  43120. X   if (FormName[0] != 0 ){ /* but only if parse succeeded */
  43121. X      curfractalspecific->per_pixel = fform_per_pixel;
  43122. X      curfractalspecific->orbitcalc = fFormula;
  43123. X   }
  43124. X   else {
  43125. X      curfractalspecific->per_pixel = BadFormula;
  43126. X      curfractalspecific->orbitcalc = BadFormula;
  43127. X   }
  43128. X   Img_Setup(); /* call assembler setup code */
  43129. X   return 1;
  43130. X}
  43131. X
  43132. X#endif  /*  XFRACT  */
  43133. SHAR_EOF
  43134. $TOUCH -am 1028230093 parserfp.c &&
  43135. chmod 0644 parserfp.c ||
  43136. echo "restore of parserfp.c failed"
  43137. set `wc -c parserfp.c`;Wc_c=$1
  43138. if test "$Wc_c" != "35051"; then
  43139.     echo original size 35051, current size $Wc_c
  43140. fi
  43141. # ============= plot3d.c ==============
  43142. echo "x - extracting plot3d.c (Text)"
  43143. sed 's/^X//' << 'SHAR_EOF' > plot3d.c &&
  43144. X/*
  43145. X    This file includes miscellaneous plot functions and logic
  43146. X    for 3D, used by lorenz.c and line3d.c
  43147. X    By Tim Wegner and Marc Reinig.
  43148. X*/
  43149. X
  43150. X#include <stdio.h>
  43151. X#include <stdlib.h>
  43152. X#include "fractint.h"
  43153. X#include "fractype.h"
  43154. X#include "prototyp.h"
  43155. X
  43156. X/* Use these palette indices for red/blue - same on ega/vga */
  43157. X#define PAL_BLUE    1
  43158. X#define PAL_RED 2
  43159. X#define PAL_MAGENTA 3
  43160. X
  43161. Xextern void (_fastcall * standardplot)(int,int,int);
  43162. Xextern int Targa_Out, sxoffs, syoffs;
  43163. X
  43164. Xint whichimage;
  43165. Xextern int fractype;
  43166. Xextern int mapset;
  43167. Xextern int xadjust;
  43168. Xextern int yadjust;
  43169. Xextern int xxadjust;
  43170. Xextern int yyadjust;
  43171. Xextern int xshift;
  43172. Xextern int yshift;
  43173. Xextern char MAP_name[];
  43174. Xextern int init3d[];
  43175. Xextern int xdots;
  43176. Xextern int ydots;
  43177. Xextern int colors;
  43178. Xextern BYTE dacbox[256][3];
  43179. Xextern int debugflag;
  43180. X
  43181. Xextern int max_colors;
  43182. X
  43183. Xint xxadjust1;
  43184. Xint yyadjust1;
  43185. Xint eyeseparation = 0;
  43186. Xint glassestype = 0;
  43187. Xint xshift1;
  43188. Xint yshift1;
  43189. Xint xtrans = 0;
  43190. Xint ytrans = 0;
  43191. Xint red_local_left;
  43192. Xint red_local_right;
  43193. Xint blue_local_left;
  43194. Xint blue_local_right;
  43195. Xint red_crop_left   = 4;
  43196. Xint red_crop_right  = 0;
  43197. Xint blue_crop_left  = 0;
  43198. Xint blue_crop_right = 4;
  43199. Xint red_bright      = 80;
  43200. Xint blue_bright     = 100;
  43201. X  
  43202. XBYTE T_RED;
  43203. X
  43204. X/* Bresenham's algorithm for drawing line */
  43205. Xvoid _fastcall draw_line (int X1, int Y1, int X2, int Y2, int color)
  43206. X
  43207. X{               /* uses Bresenham algorithm to draw a line */
  43208. X    int dX, dY;                     /* vector components */
  43209. X    int row, col,
  43210. X        final,                      /* final row or column number */
  43211. X        G,                  /* used to test for new row or column */
  43212. X        inc1,           /* G increment when row or column doesn't change */
  43213. X        inc2;               /* G increment when row or column changes */
  43214. X    char pos_slope;
  43215. X    extern int xdots,ydots;
  43216. X
  43217. X    dX = X2 - X1;                   /* find vector components */
  43218. X    dY = Y2 - Y1;
  43219. X    pos_slope = (dX > 0);                   /* is slope positive? */
  43220. X    if (dY < 0)
  43221. X    pos_slope = !pos_slope;
  43222. X    if (abs (dX) > abs (dY))                /* shallow line case */
  43223. X    {
  43224. X        if (dX > 0)         /* determine start point and last column */
  43225. X        {
  43226. X            col = X1;
  43227. X            row = Y1;
  43228. X            final = X2;
  43229. X        }
  43230. X        else
  43231. X        {
  43232. X            col = X2;
  43233. X            row = Y2;
  43234. X            final = X1;
  43235. X        }
  43236. X        inc1 = 2 * abs (dY);            /* determine increments and initial G */
  43237. X        G = inc1 - abs (dX);
  43238. X        inc2 = 2 * (abs (dY) - abs (dX));
  43239. X        if (pos_slope)
  43240. X            while (col <= final)    /* step through columns checking for new row */
  43241. X            {
  43242. X                (*plot) (col, row, color);
  43243. X                col++;
  43244. X                if (G >= 0)             /* it's time to change rows */
  43245. X                {
  43246. X                    row++;      /* positive slope so increment through the rows */
  43247. X                    G += inc2;
  43248. X                }
  43249. X                else                        /* stay at the same row */
  43250. X                    G += inc1;
  43251. X            }
  43252. X        else
  43253. X            while (col <= final)    /* step through columns checking for new row */
  43254. X            {
  43255. X                (*plot) (col, row, color);
  43256. X                col++;
  43257. X                if (G > 0)              /* it's time to change rows */
  43258. X                {
  43259. X                    row--;      /* negative slope so decrement through the rows */
  43260. X                    G += inc2;
  43261. X                }
  43262. X                else                        /* stay at the same row */
  43263. X                    G += inc1;
  43264. X            }
  43265. X    }   /* if |dX| > |dY| */
  43266. X    else                            /* steep line case */
  43267. X    {
  43268. X        if (dY > 0)             /* determine start point and last row */
  43269. X        {
  43270. X            col = X1;
  43271. X            row = Y1;
  43272. X            final = Y2;
  43273. X        }
  43274. X        else
  43275. X        {
  43276. X            col = X2;
  43277. X            row = Y2;
  43278. X            final = Y1;
  43279. X        }
  43280. X        inc1 = 2 * abs (dX);            /* determine increments and initial G */
  43281. X        G = inc1 - abs (dY);
  43282. X        inc2 = 2 * (abs (dX) - abs (dY));
  43283. X        if (pos_slope)
  43284. X            while (row <= final)    /* step through rows checking for new column */
  43285. X            {
  43286. X                (*plot) (col, row, color);
  43287. X                row++;
  43288. X                if (G >= 0)                 /* it's time to change columns */
  43289. X                {
  43290. X                    col++;  /* positive slope so increment through the columns */
  43291. X                    G += inc2;
  43292. X                }
  43293. X                else                    /* stay at the same column */
  43294. X                    G += inc1;
  43295. X            }
  43296. X        else
  43297. X            while (row <= final)    /* step through rows checking for new column */
  43298. X            {
  43299. X                (*plot) (col, row, color);
  43300. X                row++;
  43301. X                if (G > 0)                  /* it's time to change columns */
  43302. X                {
  43303. X                    col--;  /* negative slope so decrement through the columns */
  43304. X                    G += inc2;
  43305. X                }
  43306. X                else                    /* stay at the same column */
  43307. X                    G += inc1;
  43308. X            }
  43309. X    }
  43310. X}   /* draw_line */
  43311. X
  43312. X
  43313. X/* use this for continuous colors later */
  43314. Xvoid _fastcall plot3dsuperimpose16b(int x,int y,int color)
  43315. X{
  43316. X    int tmp;
  43317. X    if (color != 0)         /* Keeps index 0 still 0 */
  43318. X    {
  43319. X        color = colors - color; /*  Reverses color order */
  43320. X        color = color / 4;
  43321. X        if(color == 0)
  43322. X            color = 1;
  43323. X    }
  43324. X    color = 3;
  43325. X    tmp = getcolor(x,y);
  43326. X
  43327. X    /* map to 4 colors */
  43328. X    if(whichimage == 1) /* RED */
  43329. X    {
  43330. X        if(red_local_left < x && x < red_local_right)
  43331. X        {
  43332. X            putcolor(x,y,color|tmp);
  43333. X            if (Targa_Out)                              
  43334. X                targa_color(x, y, color|tmp);
  43335. X        }
  43336. X    }
  43337. X    else if(whichimage == 2) /* BLUE */
  43338. X        if(blue_local_left < x && x < blue_local_right)
  43339. X        {
  43340. X            color = color <<2;
  43341. X            putcolor(x,y,color|tmp);
  43342. X            if (Targa_Out)                              
  43343. X                targa_color(x, y, color|tmp);
  43344. X        }
  43345. X}
  43346. X
  43347. Xvoid _fastcall plot3dsuperimpose16(int x,int y,int color)
  43348. X{
  43349. X    int tmp;
  43350. X
  43351. X    tmp = getcolor(x,y);
  43352. X
  43353. X    if(whichimage == 1) /* RED */
  43354. X    {
  43355. X        color = PAL_RED;
  43356. X        if(tmp > 0 && tmp != color)
  43357. X            color = PAL_MAGENTA;
  43358. X        if(red_local_left < x && x < red_local_right)
  43359. X        {
  43360. X            putcolor(x,y,color);
  43361. X            if (Targa_Out)                              
  43362. X                targa_color(x, y, color);
  43363. X        }
  43364. X    }
  43365. X    else if(whichimage == 2) /* BLUE */
  43366. X        if(blue_local_left < x && x < blue_local_right)
  43367. X        {
  43368. X            color = PAL_BLUE;
  43369. X            if(tmp > 0 && tmp != color)
  43370. X                color = PAL_MAGENTA;
  43371. X            putcolor(x,y,color);
  43372. X            if (Targa_Out)                              
  43373. X                targa_color(x, y, color);
  43374. X        }
  43375. X}
  43376. X
  43377. X
  43378. Xvoid _fastcall plot3dsuperimpose256(int x,int y,int color)
  43379. X{
  43380. X    int tmp;
  43381. X    BYTE t_c;
  43382. X
  43383. X    t_c = 255-color;
  43384. X
  43385. X    if (color != 0)         /* Keeps index 0 still 0 */
  43386. X    {
  43387. X        color = colors - color; /*  Reverses color order */
  43388. X        if (max_colors == 236)
  43389. X        color = 1 + color / 21; /*  Maps colors 1-255 to 13 even ranges */
  43390. X        else
  43391. X        color = 1 + color / 18; /*  Maps colors 1-255 to 15 even ranges */
  43392. X    }
  43393. X
  43394. X    tmp = getcolor(x,y);
  43395. X    /* map to 16 colors */
  43396. X    if(whichimage == 1) /* RED */
  43397. X    {
  43398. X        if(red_local_left < x && x < red_local_right)
  43399. X        {
  43400. X            /* Overwrite prev Red don't mess w/blue */
  43401. X            putcolor(x,y,color|(tmp&240));
  43402. X            if (Targa_Out)
  43403. X                if (!ILLUMINE)
  43404. X                    targa_color(x, y, color|(tmp&240));
  43405. X                else
  43406. X                    targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0);
  43407. X        }
  43408. X    }
  43409. X    else if(whichimage == 2) /* BLUE */
  43410. X        if(blue_local_left < x && x < blue_local_right)
  43411. X        {
  43412. X            /* Overwrite previous blue, don't mess with existing red */
  43413. X            color = color <<4;
  43414. X            putcolor(x,y,color|(tmp&15));
  43415. X            if (Targa_Out)                              
  43416. X                if (!ILLUMINE)
  43417. X                    targa_color(x, y, color|(tmp&15));
  43418. X                else
  43419. X                {
  43420. X                    targa_readdisk (x+sxoffs, y+syoffs, &T_RED, (BYTE *)&tmp, (BYTE *)&tmp);
  43421. X                    targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c);
  43422. X                }
  43423. X        }
  43424. X}
  43425. X
  43426. Xvoid _fastcall plotIFS3dsuperimpose256(int x,int y,int color)
  43427. X{
  43428. X    int tmp;
  43429. X    BYTE t_c;
  43430. X
  43431. X    t_c = 255-color;
  43432. X
  43433. X    if (color != 0)         /* Keeps index 0 still 0 */
  43434. X    {
  43435. X        /* my mind is fried - lower indices = darker colors is EASIER! */
  43436. X        color = colors - color; /*  Reverses color order */
  43437. X        if (max_colors == 236)
  43438. X        color = 1 + color / 21; /*  Maps colors 1-255 to 13 even ranges */
  43439. X        else
  43440. X        color = 1 + color / 18; /*  Looks weird but maps colors 1-255 to 15
  43441. X                    relatively even ranges */
  43442. X    }
  43443. X
  43444. X    tmp = getcolor(x,y);
  43445. X    /* map to 16 colors */
  43446. X    if(whichimage == 1) /* RED */
  43447. X    {
  43448. X        if(red_local_left < x && x < red_local_right)
  43449. X        {
  43450. X            putcolor(x,y,color|tmp);
  43451. X            if (Targa_Out)                              
  43452. X                if (!ILLUMINE)
  43453. X                    targa_color(x, y, color|tmp);
  43454. X                else
  43455. X                    targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0);
  43456. X        }
  43457. X    }
  43458. X    else if(whichimage == 2) /* BLUE */
  43459. X        if(blue_local_left < x && x < blue_local_right)
  43460. X        {
  43461. X            color = color <<4;
  43462. X            putcolor(x,y,color|tmp);
  43463. X            if (Targa_Out)                              
  43464. X                if (!ILLUMINE)
  43465. X                    targa_color(x, y, color|tmp);
  43466. X                else
  43467. X                {
  43468. X                    targa_readdisk (x+sxoffs, y+syoffs, &T_RED, (BYTE *)&tmp, (BYTE *)&tmp);
  43469. X                    targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c);
  43470. X                }
  43471. X        }
  43472. X}
  43473. X
  43474. Xvoid _fastcall plot3dalternate(int x,int y,int color)
  43475. X{
  43476. X    int tmp;
  43477. X    BYTE t_c;
  43478. X
  43479. X    t_c = 255-color;
  43480. X    /* lorez high color red/blue 3D plot function */
  43481. X    /* if which image = 1, compresses color to lower 128 colors */
  43482. X
  43483. X    /* my mind is STILL fried - lower indices = darker colors is EASIER! */
  43484. X    color = colors - color;
  43485. X    if((whichimage == 1) && !((x+y)&1)) /* - lower half palette */
  43486. X    {
  43487. X        if(red_local_left < x && x < red_local_right)
  43488. X        {
  43489. X            putcolor(x,y,color>>1);
  43490. X            if (Targa_Out)                              
  43491. X                if (!ILLUMINE)
  43492. X                    targa_color(x, y, color>>1);
  43493. X                else
  43494. X                    targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0);
  43495. X        }
  43496. X    }
  43497. X    else if((whichimage == 2) && ((x+y)&1) ) /* - upper half palette */
  43498. X    {
  43499. X        if(blue_local_left < x && x < blue_local_right)
  43500. X        {
  43501. X            putcolor(x,y,(color>>1)+(colors>>1));
  43502. X            if (Targa_Out)                              
  43503. X                if (!ILLUMINE)
  43504. X                    targa_color(x, y, (color>>1)+(colors>>1));
  43505. X                else
  43506. X                    targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c);
  43507. X        }
  43508. X    }
  43509. X}
  43510. X
  43511. Xvoid plot_setup()
  43512. X{
  43513. X    double d_red_bright, d_blue_bright;
  43514. X    int i;
  43515. X
  43516. X    /* set funny glasses plot function */
  43517. X    switch(glassestype)
  43518. X    {
  43519. X    case 1:
  43520. X        standardplot = plot3dalternate;
  43521. X        break;
  43522. X
  43523. X    case 2:
  43524. X        if(colors == 256)
  43525. X            if (fractype != IFS3D)
  43526. X                standardplot = plot3dsuperimpose256;
  43527. X            else
  43528. X                standardplot = plotIFS3dsuperimpose256;
  43529. X        else
  43530. X            standardplot = plot3dsuperimpose16;
  43531. X        break;
  43532. X
  43533. X    default:
  43534. X        standardplot = putcolor;
  43535. X        break;
  43536. X    }
  43537. X
  43538. X    xshift1 = xshift = (XSHIFT * (double)xdots)/100;
  43539. X    yshift1 = yshift = (YSHIFT * (double)ydots)/100;
  43540. X
  43541. X    if(glassestype)
  43542. X    {
  43543. X        red_local_left  =   (red_crop_left      * (double)xdots)/100.0;
  43544. X        red_local_right =   ((100 - red_crop_right) * (double)xdots)/100.0;
  43545. X        blue_local_left =   (blue_crop_left     * (double)xdots)/100.0;
  43546. X        blue_local_right =  ((100 - blue_crop_right) * (double)xdots)/100.0;
  43547. X        d_red_bright    =   (double)red_bright/100.0;
  43548. X        d_blue_bright   =   (double)blue_bright/100.0;
  43549. X
  43550. X        switch(whichimage)
  43551. X        {
  43552. X        case 1:
  43553. X            xshift  += (eyeseparation* (double)xdots)/200;
  43554. X            xxadjust = ((xtrans+xadjust)* (double)xdots)/100;
  43555. X            xshift1 -= (eyeseparation* (double)xdots)/200;
  43556. X            xxadjust1 = ((xtrans-xadjust)* (double)xdots)/100;
  43557. X            break;
  43558. X
  43559. X        case 2:
  43560. X            xshift  -= (eyeseparation* (double)xdots)/200;
  43561. X            xxadjust = ((xtrans-xadjust)* (double)xdots)/100;
  43562. X            break;
  43563. X        }
  43564. X    }
  43565. X    else
  43566. X        xxadjust = (xtrans* (double)xdots)/100;
  43567. X        yyadjust = -(ytrans* (double)ydots)/100;
  43568. X
  43569. X    if (mapset)
  43570. X    {
  43571. X        ValidateLuts(MAP_name); /* read the palette file */
  43572. X        if(glassestype==1 || glassestype==2)
  43573. X        {
  43574. X            if(glassestype == 2 && colors < 256)
  43575. X            {
  43576. X                dacbox[PAL_RED  ][0] = 63;
  43577. X                dacbox[PAL_RED  ][1] =  0;
  43578. X                dacbox[PAL_RED  ][2] =  0;
  43579. X
  43580. X                dacbox[PAL_BLUE ][0] =  0;
  43581. X                dacbox[PAL_BLUE ][1] =  0;
  43582. X                dacbox[PAL_BLUE ][2] = 63;
  43583. X
  43584. X                dacbox[PAL_MAGENTA][0] = 63;
  43585. X                dacbox[PAL_MAGENTA][1] =    0;
  43586. X                dacbox[PAL_MAGENTA][2] = 63;
  43587. X            }
  43588. X            for (i=0;i<256;i++)
  43589. X            {
  43590. X                dacbox[i][0] = dacbox[i][0] * d_red_bright;
  43591. X                dacbox[i][2] = dacbox[i][2] * d_blue_bright;
  43592. X            }
  43593. X        }
  43594. X        spindac(0,1); /* load it, but don't spin */
  43595. X    }
  43596. X}
  43597. SHAR_EOF
  43598. $TOUCH -am 1028230093 plot3d.c &&
  43599. chmod 0644 plot3d.c ||
  43600. echo "restore of plot3d.c failed"
  43601. set `wc -c plot3d.c`;Wc_c=$1
  43602. if test "$Wc_c" != "13679"; then
  43603.     echo original size 13679, current size $Wc_c
  43604. fi
  43605. # ============= printer.c ==============
  43606. echo "x - extracting printer.c (Text)"
  43607. sed 's/^X//' << 'SHAR_EOF' > printer.c &&
  43608. X/*  Printer.c
  43609. X *    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  43610. X *    Simple screen printing functions for FRACTINT
  43611. X *    By Matt Saucier CIS: [72371,3101]      7/2/89
  43612. X *    "True-to-the-spirit" of FRACTINT, this code makes few checks that you
  43613. X *    have specified a valid resolution for the printer (just in case yours
  43614. X *    has more dots/line than the Standard HP and IBM/EPSON,
  43615. X *    (eg, Wide Carriage, etc.))
  43616. X *
  43617. X *    PostScript support by Scott Taylor [72401,410] / (DGWM18A)   10/8/90
  43618. X *    For PostScript, use 'printer=PostScript/resolution' where resolution
  43619. X *    is ANY NUMBER between 10 and 600. Common values: 300,150,100,75.
  43620. X *    Default resolution for PostScript is 150 pixels/inch.
  43621. X *    At 200 DPI, a fractal that is 640x480 prints as a 3.2"x2.4" picture.
  43622. X *    PostScript printer names:
  43623. X *
  43624. X *    PostScript/PS            = Portrait printing
  43625. X *    PostScriptH/PostScriptL/PSH/PSL = Landscape printing
  43626. X *
  43627. X *    This code supports printers attached to a LPTx (1-3) parallel port.
  43628. X *    It also now supports serial printers AFTER THEY ARE CONFIGURED AND
  43629. X *    WORKING WITH THE DOS MODE COMMAND, eg. MODE COM1:9600,n,8,1 (for HP)
  43630. X *    (NOW you can also configure the serial port with the comport= command)
  43631. X *    Printing calls are made directly to the BIOS for DOS can't handle fast
  43632. X *    transfer of data to the HP.  (Or maybe visa-versa, HP can't handle the
  43633. X *    slow transfer of data from DOS)
  43634. X *
  43635. X *    I just added direct port access for COM1 and COM2 **ONLY**. This method
  43636. X *    does a little more testing than BIOS, and may work (especially on
  43637. X *    serial printer sharing devices) where the old method doesn't. I noticed
  43638. X *    maybe a 5% speed increase at 9600 baud. These are selected in the
  43639. X *    printer=.../.../31 for COM1 or 32 for COM2.
  43640. X *
  43641. X *    I also added direct parallel port access for LPT1 and LPT2 **ONLY**.
  43642. X *    This toggles the "INIT" line of the parallel port to reset the printer
  43643. X *    for each print session. It will also WAIT for a error / out of paper /
  43644. X *    not selected condition instead of quitting with an error.
  43645. X *
  43646. X *    Supported Printers:    Tested Ok:
  43647. X *     HP LaserJet
  43648. X *        LJ+,LJII         MDS
  43649. X *     Toshiba PageLaser     MDS (Set FRACTINT to use HP)
  43650. X *     IBM Graphics         MDS
  43651. X *     EPSON
  43652. X *        Models?         Untested.
  43653. X *     IBM LaserPrinter
  43654. X *        with PostScript     SWT
  43655. X *     HP Plotter         SWT
  43656. X *
  43657. X *    Future support to include OKI 20 (color) printer, and just about
  43658. X *    any printer you request.
  43659. X *
  43660. X *    Future modifications to include a more flexible, standard interface
  43661. X *    with the surrounding program, for easier portability to other
  43662. X *    programs.
  43663. X *
  43664. X * PostScript Styles:
  43665. X *  0  Dot
  43666. X *  1  Dot*           [Smoother]
  43667. X *  2  Inverted Dot
  43668. X *  3  Ring
  43669. X *  4  Inverted Ring
  43670. X *  5  Triangle        [45-45-90]
  43671. X *  6  Triangle*       [30-75-75]
  43672. X *  7  Grid
  43673. X *  8  Diamond
  43674. X *  9  Line
  43675. X * 10  Microwaves
  43676. X * 11  Ellipse
  43677. X * 12  RoundBox
  43678. X * 13  Custom
  43679. X * 14  Star
  43680. X * 15  Random
  43681. X * 16  Line*           [Not much different]
  43682. X *
  43683. X *  *  Alternate style
  43684. X *
  43685. X
  43686. X */
  43687. X
  43688. X#include <stdlib.h>
  43689. X
  43690. X#ifndef XFRACT
  43691. X#include <bios.h>
  43692. X#include <dos.h>
  43693. X#include <io.h>
  43694. X#endif
  43695. X
  43696. X#include <fcntl.h>
  43697. X#include <sys/types.h>
  43698. X#include <errno.h>
  43699. X#include <stdio.h>    /*** for vsprintf prototype ***/
  43700. X
  43701. X#ifndef XFRACT
  43702. X#include <conio.h>
  43703. X#include <stdarg.h>
  43704. X#else
  43705. X#include <varargs.h>
  43706. X#endif
  43707. X
  43708. X#include <string.h>
  43709. X#include <float.h>    /* for pow() */
  43710. X#include <math.h>    /*  "    "   */
  43711. X#include "fractint.h"
  43712. X#include "fractype.h"
  43713. X#include "prototyp.h"
  43714. X
  43715. X/* macros for near-space-saving purposes */
  43716. X/* CAE 9211 changed these for BC++ */
  43717. X#define PRINTER_PRINTF2(X,Y) {\
  43718. X   static char far tmp[] = X;\
  43719. X   Printer_printf(tmp,(Y));\
  43720. X}
  43721. X#define PRINTER_PRINTF3(X,Y,Z) {\
  43722. X   static char far tmp[] = X;\
  43723. X   Printer_printf(tmp,(Y),(Z));\
  43724. X}
  43725. X#define PRINTER_PRINTF4(X,Y,Z,W) {\
  43726. X   static char far tmp[] = X;\
  43727. X   Printer_printf(tmp,(Y),(Z),(W));\
  43728. X}
  43729. X
  43730. X/********      PROTOTYPES     ********/
  43731. X
  43732. X#ifndef XFRACT
  43733. Xstatic void Printer_printf(char far *fmt,...);
  43734. X#else
  43735. Xstatic void Printer_printf();
  43736. X#endif
  43737. Xstatic int  _fastcall printer(int c);
  43738. Xstatic void _fastcall print_title(int,int,char *);
  43739. Xstatic void printer_reset();
  43740. Xstatic rleprolog(int x,int y);
  43741. Xstatic void _fastcall graphics_init(int,int,char *);
  43742. X
  43743. X/********  EXTRN GLOBAL VARS  ********/
  43744. X
  43745. Xextern int xdots,ydots,            /* size of screen           */
  43746. X       fractype;               /* used for title block           */
  43747. Xextern SEGTYPE       extraseg;           /* used for buffering           */
  43748. Xextern BYTE dacbox[256][3];   /* for PostScript printing       */
  43749. Xextern BYTE dstack[2][3][400];
  43750. Xextern char FormName[];            /* for Title block info           */
  43751. Xextern char LName[];               /* for Title block info           */
  43752. Xextern char IFSName[];               /* for Title block info           */
  43753. Xextern char PrintName[];           /* Filename for print-to-file       */
  43754. Xextern float finalaspectratio;
  43755. Xextern double xxmin,xxmax,xx3rd,
  43756. X          yymin,yymax,yy3rd,param[]; /* for Title block info       */
  43757. Xextern int colors;
  43758. Xextern int dotmode;
  43759. Xextern unsigned int debugflag;
  43760. X
  43761. Xextern unsigned int  far pj_patterns[];
  43762. Xextern BYTE far pj_reds[];
  43763. Xextern BYTE far pj_blues[];
  43764. Xextern BYTE far pj_greens[];
  43765. X
  43766. X/********    GLOBALS       ********/
  43767. X
  43768. Xint Printer_Resolution,        /* 75,100,150,300 for HP;           */
  43769. X                   /* 60,120,240 for IBM;               */
  43770. X                   /* 90 or 180 for the PaintJet;           */
  43771. X                   /* 10-600 for PS                */
  43772. X                   /* 1-20 for Plotter               */
  43773. X    LPTNumber,               /* ==1,2,3 LPTx; or 11,12,13,14 for COM1-4  */
  43774. X                   /* 21,22 for direct port access for LPT1-2  */
  43775. X                   /* 31,32 for direct port access for COM1-2  */
  43776. X    Printer_Type,               /* ==1 HP,
  43777. X                      ==2 IBM/EPSON,
  43778. X                      ==3 Epson color,
  43779. X                      ==4 HP PaintJet,
  43780. X                      ==5,6 PostScript,
  43781. X                      ==7 HP Plotter           */
  43782. X    Printer_Titleblock,       /* Print info about the fractal?           */
  43783. X    Printer_Compress,          /* PostScript only - rle encode output       */
  43784. X    Printer_ColorXlat,          /* PostScript only - invert colors       */
  43785. X    Printer_SetScreen,          /* PostScript only - reprogram halftone ?    */
  43786. X    Printer_SFrequency,       /* PostScript only - Halftone Frequency K    */
  43787. X    Printer_SAngle,           /* PostScript only - Halftone angle     K    */
  43788. X    Printer_SStyle,           /* PostScript only - Halftone style     K    */
  43789. X    Printer_RFrequency,       /* PostScript only - Halftone Frequency R    */
  43790. X    Printer_RAngle,           /* PostScript only - Halftone angle     R    */
  43791. X    Printer_RStyle,           /* PostScript only - Halftone style     R    */
  43792. X    Printer_GFrequency,       /* PostScript only - Halftone Frequency G    */
  43793. X    Printer_GAngle,           /* PostScript only - Halftone angle     G    */
  43794. X    Printer_GStyle,           /* PostScript only - Halftone style     G    */
  43795. X    Printer_BFrequency,       /* PostScript only - Halftone Frequency B    */
  43796. X    Printer_BAngle,           /* PostScript only - Halftone angle     B    */
  43797. X    Printer_BStyle,           /* PostScript only - Halftone style     B    */
  43798. X    Print_To_File,          /* Print to file toggle               */
  43799. X    EPSFileType,          /* EPSFileType -
  43800. X                           1 = well-behaved,
  43801. X                           2 = much less behaved,
  43802. X                           3 = not well behaved       */
  43803. X    Printer_CRLF,             /* (0) CRLF (1) CR (2) LF                    */
  43804. X    ColorPS;                  /* (0) B&W  (1) Color                        */
  43805. Xint pj_width;
  43806. Xdouble ci,ck;
  43807. X
  43808. Xstatic int repeat, item, count, repeatitem, itembuf[128], rlebitsperitem,
  43809. X    rlebitshift, bitspersample, rleitem, repeatcount, itemsperline, items,
  43810. X    bitsperitem, bitshift;
  43811. X    
  43812. Xstatic void putitem(), rleputxelval(), rleflush(), rleputrest();
  43813. X
  43814. Xstatic int LPTn;           /* printer number we're gonna use */
  43815. X
  43816. Xstatic FILE *PRFILE;
  43817. X
  43818. X#define TONES 17           /* Number of PostScript halftone styles */
  43819. X
  43820. Xstatic char *HalfTone[TONES]=  {
  43821. X             "D mul exch D mul add 1 exch sub",
  43822. X             "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",
  43823. X             "D mul exch D mul add 1 sub",
  43824. X             "D mul exch D mul add 0.6 exch sub abs -0.5 mul",
  43825. X             "D mul exch D mul add 0.6 exch sub abs 0.5 mul",
  43826. X             "add 2 div",
  43827. X             "2 exch sub exch abs 2 mul sub 3 div",
  43828. X             "2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div",
  43829. X             "abs exch abs add 1 exch sub",
  43830. X             "pop",
  43831. X             "/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos",
  43832. X             "D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub",
  43833. X             "D mul D mul exch D mul D mul add 1 exch sub",
  43834. X             "D mul exch D mul add sqrt 1 exch sub",
  43835. X             "abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div",
  43836. X             "pop pop rand 1 add 10240 mod 5120 div 1 exch sub",
  43837. X             "pop abs 2 mul 1 exch sub"
  43838. X            };
  43839. X
  43840. Xvoid printer_overlay() { }    /* for restore_active_ovly */
  43841. X
  43842. X#ifdef __BORLANDC__
  43843. X#if(__BORLANDC__ > 2)
  43844. X   #pragma warn -eff
  43845. X#endif
  43846. X#endif
  43847. X
  43848. Xstatic char EndOfLine[3];
  43849. X
  43850. Xvoid Print_Screen()
  43851. X{
  43852. X    int y,j;
  43853. X    char buff[192];        /* buffer for 192 sets of pixels  */
  43854. X                /* This is very large so that we can*/
  43855. X                /* get reasonable times printing  */
  43856. X                /* from modes like MAXPIXELSxMAXPIXELS disk-*/
  43857. X                /* video.  When this was 24, a MAXPIXELS*/
  43858. X                /* by MAXPIXELS pic took over 2 hours to*/
  43859. X                /* print.  It takes about 15 min now*/
  43860. X    int BuffSiz;        /* how much of buff[] we'll use   */
  43861. X    char far *es;        /* pointer to extraseg for buffer */
  43862. X    int i,x,k,            /* more indices           */
  43863. X    imax,            /* maximum i value (ydots/8)      */
  43864. X    res,            /* resolution we're gonna' use    */
  43865. X    high,            /* if LPTn>10 COM == com port to use*/
  43866. X    low,            /* misc               */
  43867. X                /************************************/
  43868. X    ptrid;            /* Printer Id code.          */
  43869. X                /* Currently, the following are   */
  43870. X                /* assigned:              */
  43871. X                /*          1. HPLJ (all)      */
  43872. X                /*         Toshiba PageLaser*/
  43873. X                /*          2. IBM Graphics      */
  43874. X                /*          3. Color Printer      */
  43875. X                /*          4. HP PaintJet      */
  43876. X                /*          5. PostScript      */
  43877. X                /************************************/
  43878. X    int pj_color_ptr[256];    /* Paintjet color translation */
  43879. X
  43880. X    ENTER_OVLY(OVLY_PRINTER);
  43881. X                /********   SETUP VARIABLES  ********/
  43882. X    memset(buff,0,192);
  43883. X
  43884. X    EndOfLine[0]=(((Printer_CRLF==1) || (Printer_CRLF==0)) ? 0x0D : 0x0A);
  43885. X    EndOfLine[1]=((Printer_CRLF==0) ? 0x0A : 0x00);
  43886. X    EndOfLine[2]=0x00;
  43887. X
  43888. X    if (Print_To_File>0)
  43889. X      {
  43890. X      while ((PRFILE = fopen(PrintName,"r"))) {
  43891. X     j = fgetc(PRFILE);
  43892. X     fclose(PRFILE);
  43893. X     if (j == EOF) break;
  43894. X     updatesavename((char *)PrintName);
  43895. X     }
  43896. X      if ((PRFILE = fopen(PrintName,"wb"))==NULL) Print_To_File = 0;
  43897. X      }
  43898. X
  43899. X#ifdef XFRACT
  43900. X      putstring(3,0,0,"Printing to:");
  43901. X      putstring(4,0,0,PrintName);
  43902. X      putstring(5,0,0,"               ");
  43903. X#endif
  43904. X
  43905. X    es=MK_FP(extraseg,0);
  43906. X
  43907. X    LPTn=LPTNumber-1;
  43908. X    if (((LPTn>2)&&(LPTn<10))||
  43909. X    ((LPTn>13)&&(LPTn<20))||
  43910. X    ((LPTn>21)&&(LPTn<30))||
  43911. X    (LPTn<0)||(LPTn>31)) LPTn=0;   /* default of LPT1 (==0)      */
  43912. X    ptrid=Printer_Type;
  43913. X    if ((ptrid<1)||(ptrid>7)) ptrid=2; /* default of IBM/EPSON         */
  43914. X    res=Printer_Resolution;
  43915. X#ifndef XFRACT
  43916. X    if ((LPTn==20)||(LPTn==21))
  43917. X    {
  43918. X    k = (inp((LPTn==20) ? 0x37A : 0x27A)) & 0xF7;
  43919. X    outp((LPTn==20) ? 0x37A : 0x27A,k);
  43920. X    k = k & 0xFB;
  43921. X    outp((LPTn==20) ? 0x37A : 0x27A,k);
  43922. X    k = k | 0x0C;
  43923. X    outp((LPTn==20) ? 0x37A : 0x27A,k);
  43924. X    }
  43925. X    if ((LPTn==30)||(LPTn==31))
  43926. X    {
  43927. X    outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00);
  43928. X    outp((LPTn==30) ? 0x3FC : 0x2FC,0x00);
  43929. X    outp((LPTn==30) ? 0x3FC : 0x2FC,0x03);
  43930. X    }
  43931. X#endif
  43932. X
  43933. X    switch (ptrid) {
  43934. X
  43935. X    case 1:
  43936. X        if (res<75) res=75;
  43937. X        if ( (res<= 75)&&(ydots> 600)) res=100;
  43938. X        if ( (res<=100)&&(ydots> 800)) res=150;
  43939. X        if (((res<=150)&&(ydots>1200))||(res>300)) res=300;
  43940. X        break;
  43941. X
  43942. X    case 2:
  43943. X    case 3:
  43944. X        if (res<60) res=60;
  43945. X        if ((res<=60)&&(ydots>480)) res=120;
  43946. X        if (((res<=120)&&(ydots>960))||(res>240)) res=240;
  43947. X        break;
  43948. X
  43949. X    case 4: /****** PaintJet  *****/
  43950. X        {
  43951. X#ifndef XFRACT
  43952. X        /* Pieter Branderhorst:
  43953. X           My apologies if the numbers and approach here seem to be
  43954. X           picked out of a hat.  They were.  They happen to result in
  43955. X           a tolerable mapping of screen colors to printer colors on
  43956. X           my machine.  There are two sources of error in getting colors
  43957. X           to come out right.
  43958. X           1) Must match some dacbox values to the 330 PaintJet dithered
  43959. X          colors so that they look the same.  For this we use HP's
  43960. X          color values in printera.asm and modify by gamma separately
  43961. X          for each of red/green/blue.  This mapping is ok if the
  43962. X          preview shown on screen is a fairly close match to what
  43963. X          gets printed. The defaults are what work for me.
  43964. X           2) Must find nearest color in HP palette to each color in
  43965. X          current image. For this we use Lee Crocker's least sum of
  43966. X          differences squared approach, modified to spread the
  43967. X          values using gamma 1.7.  This mods was arrived at by
  43968. X          trial and error, just because it improves the mapping.
  43969. X           */
  43970. X        long ldist;
  43971. X        int r,g,b;
  43972. X        double gamma_val,gammadiv;
  43973. X        BYTE convert[256];
  43974. X        BYTE scale[64];
  43975. X
  43976. X        BYTE far *table_ptr;
  43977. X        res = (res < 150) ? 90 : 180;   /* 90 or 180 dpi */
  43978. X        if (Printer_SetScreen == 0) {
  43979. X        Printer_SFrequency = 21;  /* default red gamma */
  43980. X        Printer_SAngle       = 19;  /*       green gamma */
  43981. X        Printer_SStyle       = 16;  /*        blue gamma */
  43982. X        }
  43983. X        /* Convert the values in printera.asm.  We might do this just   */
  43984. X        /* once per run, but we'd need separate memory for that - can't */
  43985. X        /* just convert table in-place cause it could be in an overlay, */
  43986. X        /* might be paged out and then back in in original form.  Also, */
  43987. X        /* user might change gammas with a .par file entry mid-run.     */
  43988. X        for (j = 0; j < 3; ++j) {
  43989. X        switch (j) {
  43990. X            case 0: table_ptr = pj_reds;
  43991. X                i = Printer_SFrequency;
  43992. X                break;
  43993. X            case 1: table_ptr = pj_greens;
  43994. X                i = Printer_SAngle;
  43995. X                break;
  43996. X            case 2: table_ptr = pj_blues;
  43997. X                i = Printer_SStyle;
  43998. X            }
  43999. X        gamma_val = 10.0 / i;
  44000. X        gammadiv = pow(255,gamma_val) / 255;
  44001. X        for (i = 0; i < 256; ++i) { /* build gamma conversion table */
  44002. X            if ((i & 15) == 15)
  44003. X            thinking(1,"Calculating color translation");
  44004. X            convert[i] = (int)((pow((double)i,gamma_val) / gammadiv) + 0.5);
  44005. X            }
  44006. X        for (i = 0; i < 330; ++i) {
  44007. X            k = convert[table_ptr[i]];
  44008. X            if (k > 252) k = 252;
  44009. X            dstack[0][j][i] = (k + 2) >> 2;
  44010. X        }
  44011. X        }
  44012. X        /* build comparison lookup table */
  44013. X        gamma_val = 1.7;
  44014. X        gammadiv = pow(63,gamma_val) / 63;
  44015. X        for (i = 0; i < 64; ++i) {
  44016. X           if ((j = (int)((pow((double)i,gamma_val) / gammadiv) * 4 + 0.5)) < i)
  44017. X          j = i;
  44018. X           scale[i] = j;
  44019. X        }
  44020. X        for (i = 0; i < 3; ++i) /* convert values via lookup */
  44021. X        for (j = 0; j < 330; ++j)
  44022. X            dstack[1][i][j] = scale[dstack[0][i][j]];
  44023. X        /* Following code and the later code which writes to Paintjet    */
  44024. X        /* using pj_patterns was adapted from Lee Crocker's PGIF program */
  44025. X        for (i = 0; i < colors; ++i) { /* find nearest match colors */
  44026. X        r = scale[dacbox[i][0]];
  44027. X        g = scale[dacbox[i][1]];
  44028. X        b = scale[dacbox[i][2]];
  44029. X        ldist = 9999999;
  44030. X        /* check variance vs each PaintJet color */
  44031. X        /* if high-res 8 color mode, consider only 1st 8 colors */
  44032. X        j = (res == 90) ? 330 : 8;
  44033. X        while (--j >= 0) {
  44034. X            long dist;
  44035. X            dist  = (unsigned)(r-dstack[1][0][j]) * (r-dstack[1][0][j]);
  44036. X            dist += (unsigned)(g-dstack[1][1][j]) * (g-dstack[1][1][j]);
  44037. X            dist += (unsigned)(b-dstack[1][2][j]) * (b-dstack[1][2][j]);
  44038. X            if (dist < ldist) {
  44039. X            ldist = dist;
  44040. X            k = j;
  44041. X            }
  44042. X        }
  44043. X        pj_color_ptr[i] = k; /* remember best fit */
  44044. X        }
  44045. X        thinking(0,NULL);
  44046. X    /*  if (debugflag == 900 || debugflag == 902) {
  44047. X        color_test();
  44048. X        EXIT_OVLY;
  44049. X        return;
  44050. X        }  */
  44051. X        if (dotmode != 11) { /* preview */
  44052. X        memcpy(dstack[1],dacbox,768);
  44053. X        for (i = 0; i < colors; ++i)
  44054. X            for (j = 0; j < 3; ++j)
  44055. X            dacbox[i][j] = dstack[0][j][pj_color_ptr[i]];
  44056. X        spindac(0,1);
  44057. X        texttempmsg("Preview. Enter=go, Esc=cancel, k=keep");
  44058. X        i = getakeynohelp();
  44059. X        if (i == 'K' || i == 'k') {
  44060. X            EXIT_OVLY;
  44061. X            return;
  44062. X        }
  44063. X        memcpy(dacbox,dstack[1],768);
  44064. X        spindac(0,1);
  44065. X        if (i == 0x1B) {
  44066. X            EXIT_OVLY;
  44067. X            return;
  44068. X        }
  44069. X        }
  44070. X        break;
  44071. X#endif
  44072. X        }
  44073. X
  44074. X    case 5:
  44075. X    case 6: /***** PostScript *****/
  44076. X        if ( res < 10 && res != 0 ) res = 10; /* PostScript scales... */
  44077. X        if ( res > 600 ) res = 600; /* it can handle any range! */
  44078. X        if ((Printer_SStyle < 0) || (Printer_SStyle >= TONES))
  44079. X        Printer_SStyle = 0;
  44080. X        break;
  44081. X    }
  44082. X
  44083. X    /*****  Set up buffer size for immediate user gratification *****/
  44084. X    /*****    AKA, if we don't have to, don't buffer the data   *****/
  44085. X    BuffSiz=8;
  44086. X    if (xdots>1024) BuffSiz=192;
  44087. X
  44088. X    /*****   Initialize printer  *****/
  44089. X    if (Print_To_File < 1) {
  44090. X    printer_reset();
  44091. X    /* wait a bit, some printers need time after reset */
  44092. X    delay((ptrid == 4) ? 2000 : 500);
  44093. X    }
  44094. X
  44095. X    /******  INITIALIZE GRAPHICS MODES    ******/
  44096. X
  44097. X    graphics_init(ptrid,res,EndOfLine);
  44098. X
  44099. X    if (keypressed()) {     /* one last chance before we start...*/
  44100. X    EXIT_OVLY;
  44101. X    return;
  44102. X    }
  44103. X
  44104. X    memset(buff,0,192);
  44105. X
  44106. X                /*****    Get And Print Screen **** */
  44107. X    switch (ptrid) {
  44108. X
  44109. X    case 1:                /* HP LaserJet (et al)         */
  44110. X        imax=(ydots/8)-1;
  44111. X        for (x=0;((x<xdots)&&(!keypressed()));x+=BuffSiz) {
  44112. X        for (i=imax;((i>=0)&&(!keypressed()));i--) {
  44113. X            for (y=7;((y>=0)&&(!keypressed()));y--) {
  44114. X            for (j=0;j<BuffSiz;j++) {
  44115. X                if ((x+j)<xdots) {
  44116. X                buff[j]<<=1;
  44117. X                buff[j]+=(getcolor(x+j,i*8+y)&1);
  44118. X                }
  44119. X                }
  44120. X            }
  44121. X            for (j=0;j<BuffSiz;j++) {
  44122. X            *(es+j+BuffSiz*i)=buff[j];
  44123. X            buff[j]=0;
  44124. X            }
  44125. X            }
  44126. X        for (j=0;((j<BuffSiz)&&(!keypressed()));j++) {
  44127. X            if ((x+j)<xdots) {
  44128. X            PRINTER_PRINTF2("\033*b%iW",imax+1);
  44129. X            for (i=imax;((i>=0)&&(!keypressed()));i--) {
  44130. X                printer(*(es+j+BuffSiz*i));
  44131. X                }
  44132. X            }
  44133. X            }
  44134. X        }
  44135. X        if (!keypressed()) Printer_printf("\033*rB\014");
  44136. X        break;
  44137. X
  44138. X    case 2:                /* IBM Graphics/Epson         */
  44139. X        for (x=0;((x<xdots)&&(!keypressed()));x+=8) {
  44140. X        switch (res) {
  44141. X            case 60:  Printer_printf("\033K"); break;
  44142. X            case 120: Printer_printf("\033L"); break;
  44143. X            case 240: Printer_printf("\033Z"); break;
  44144. X            }
  44145. X        high=ydots/256;
  44146. X        low=ydots-(high*256);
  44147. X        printer(low);
  44148. X        printer(high);
  44149. X        for (y=ydots-1;(y>=0);y--) {
  44150. X            buff[0]=0;
  44151. X            for (i=0;i<8;i++) {
  44152. X            buff[0]<<=1;
  44153. X            buff[0]+=(getcolor(x+i,y)&1);
  44154. X            }
  44155. X            printer(buff[0]);
  44156. X            }
  44157. X        if (keypressed()) break;
  44158. X        Printer_printf(EndOfLine);
  44159. X        }
  44160. X        if (!keypressed()) printer(12);
  44161. X        break;
  44162. X
  44163. X    case 3:                /* IBM Graphics/Epson Color    */
  44164. X        high=ydots/256;
  44165. X        low=ydots%256;
  44166. X        for (x=0;((x<xdots)&&(!keypressed()));x+=8)
  44167. X        {
  44168. X        for (k=0; k<8; k++)  /* colors */
  44169. X            {
  44170. X            Printer_printf("\033r%d",k); /* set printer color */
  44171. X            switch (res)
  44172. X            {
  44173. X            case 60:  Printer_printf("\033K"); break;
  44174. X            case 120: Printer_printf("\033L"); break;
  44175. X            case 240: Printer_printf("\033Z"); break;
  44176. X            }
  44177. X            printer(low);
  44178. X            printer(high);
  44179. X            for (y=ydots-1;y>=0;y--)
  44180. X            {
  44181. X            buff[0]=0;
  44182. X            for (i=0;i<8;i++)
  44183. X                {
  44184. X                buff[0]<<=1;
  44185. X                if ((getcolor(x+i,y)%8)==k)
  44186. X                buff[0]++;
  44187. X                }
  44188. X            printer(buff[0]);
  44189. X            }
  44190. X            if (Printer_CRLF<2) printer(13);
  44191. X            }
  44192. X        if ((Printer_CRLF==0) || (Printer_CRLF==2)) printer(10);
  44193. X        }
  44194. X        printer(12);
  44195. X        printer(12);
  44196. X        printer_reset();
  44197. X        break;
  44198. X
  44199. X    case 4:               /* HP PaintJet       */
  44200. X        {
  44201. X        unsigned int fetchrows,fetched;
  44202. X        BYTE far *pixels, far *nextpixel;
  44203. X        /* for reasonable speed when using disk video, try to fetch
  44204. X           and store the info for 8 columns at a time instead of
  44205. X           doing getcolor calls down each column in separate passes */
  44206. X        fetchrows = 16;
  44207. X        while (1) {
  44208. X        if ((pixels = farmemalloc((long)(fetchrows)*ydots))) break;
  44209. X        if ((fetchrows >>= 1) == 0) {
  44210. X            static char far msg[]={"insufficient memory"};
  44211. X            stopmsg(0,msg);
  44212. X            break;
  44213. X        }
  44214. X        }
  44215. X        if (!pixels) break;
  44216. X        fetched = 0;
  44217. X        for (x = 0; (x < xdots && !keypressed()); ++x) {
  44218. X        if (fetched == 0) {
  44219. X            if ((fetched = xdots-x) > fetchrows)
  44220. X            fetched = fetchrows;
  44221. X            for (y = ydots-1; y >= 0; --y) {
  44222. X            if (debugflag == 602) /* flip image */
  44223. X                nextpixel = pixels + y;
  44224. X            else              /* reverse order for unflipped */
  44225. X                nextpixel = pixels + ydots-1 - y;
  44226. X            for (i = 0; i < fetched; ++i) {
  44227. X                *nextpixel = getcolor(x+i,y);
  44228. X                nextpixel += ydots;
  44229. X            }
  44230. X            }
  44231. X            nextpixel = pixels;
  44232. X        }
  44233. X        --fetched;
  44234. X        if (res == 180) { /* high-res 8 color mode */
  44235. X            int offset;
  44236. X            BYTE bitmask;
  44237. X            offset = -1;
  44238. X            bitmask = 0;
  44239. X            for (y = ydots - 1; y >= 0; --y) {
  44240. X            BYTE color;
  44241. X            if ((bitmask >>= 1) == 0) {
  44242. X                ++offset;
  44243. X                dstack[0][0][offset] = dstack[0][1][offset]
  44244. X                         = dstack[0][2][offset] = 0;
  44245. X                bitmask = 0x80;
  44246. X            }
  44247. X            /* translate 01234567 to 70123456 */
  44248. X            color = pj_color_ptr[*(nextpixel++)] - 1;
  44249. X            if ((color & 1)) dstack[0][0][offset] += bitmask;
  44250. X            if ((color & 2)) dstack[0][1][offset] += bitmask;
  44251. X            if ((color & 4)) dstack[0][2][offset] += bitmask;
  44252. X            }
  44253. X        }
  44254. X        else { /* 90 dpi, build 2 lines, 2 dots per pixel */
  44255. X            int bitct,offset;
  44256. X            bitct = offset = 0;
  44257. X            for (y = ydots - 1; y >= 0; --y) {
  44258. X            unsigned int color;
  44259. X            color = pj_patterns[pj_color_ptr[*(nextpixel++)]];
  44260. X            for (i = 0; i < 3; ++i) {
  44261. X                BYTE *bufptr;
  44262. X                bufptr = &dstack[0][i][offset];
  44263. X                *bufptr <<= 2;
  44264. X                if ((color & 0x1000)) *bufptr += 2;
  44265. X                if ((color & 0x0100)) ++*bufptr;
  44266. X                bufptr = &dstack[1][i][offset];
  44267. X                *bufptr <<= 2;
  44268. X                if ((color & 0x0010)) *bufptr += 2;
  44269. X                if ((color & 0x0001)) ++*bufptr;
  44270. X                color >>= 1;
  44271. X            }
  44272. X            if (++bitct == 4) {
  44273. X                bitct = 0;
  44274. X                ++offset;
  44275. X            }
  44276. X            }
  44277. X        }
  44278. X        for (i = 0; i < ((res == 90) ? 2 : 1); ++i) {
  44279. X            for (j = 0; j < 3; ++j) {
  44280. X            BYTE *bufptr,*bufend;
  44281. X            Printer_printf((j < 2) ? "\033*b%dV" : "\033*b%dW",
  44282. X                       pj_width);
  44283. X            bufend = pj_width + (bufptr = dstack[i][j]);
  44284. X            do {
  44285. X                while (printer(*bufptr)) { }
  44286. X            } while (++bufptr < bufend);
  44287. X            }
  44288. X        }
  44289. X        }
  44290. X        Printer_printf("\033*r0B"); /* end raster graphics */
  44291. X        if (!keypressed())
  44292. X           if (debugflag != 600)
  44293. X          printer(12); /* form feed */
  44294. X           else
  44295. X          Printer_printf("\n\n");
  44296. X        farmemfree(pixels);
  44297. X        break;
  44298. X        }
  44299. X
  44300. X    case 5:
  44301. X    case 6:     /***** PostScript Portrait & Landscape *****/
  44302. X        {
  44303. X        char convert[513];
  44304. X        if (!ColorPS)
  44305. X          for (i=0; i<256; ++i)
  44306. X                if (Printer_Compress) {
  44307. X                    convert[i] = (int)((.3*255./63. * (double)dacbox[i][0])+
  44308. X                                        (.59*255./63. * (double)dacbox[i][1])+
  44309. X                                        (.11*255./63. * (double)dacbox[i][2]));
  44310. X                } else
  44311. X                {
  44312. X                    sprintf(&convert[2*i], "%02X",
  44313. X                              (int)((.3*255./63. * (double)dacbox[i][0])+
  44314. X                                    (.59*255./63. * (double)dacbox[i][1])+
  44315. X                                    (.11*255./63. * (double)dacbox[i][2])));
  44316. X                }
  44317. X        i=0;
  44318. X        j=0;
  44319. X        for (y=0;((y<ydots)&&(!keypressed()));y++)
  44320. X        {   unsigned char bit8;
  44321. X        if (Printer_Compress) {
  44322. X            if (ColorPS) {
  44323. X            for (x=0;x<xdots;x++) {
  44324. X                k=getcolor(x,y);
  44325. X                rleputxelval((int)dacbox[k][0]<<2);
  44326. X            }
  44327. X            rleflush();
  44328. X            for (x=0;x<xdots;x++) {
  44329. X                k=getcolor(x,y);
  44330. X                rleputxelval((int)dacbox[k][1]<<2);
  44331. X            }
  44332. X            rleflush();
  44333. X            for (x=0;x<xdots;x++) {
  44334. X                k=getcolor(x,y);
  44335. X                rleputxelval((int)dacbox[k][2]<<2);
  44336. X            }
  44337. X            rleflush();
  44338. X             } else {
  44339. X            if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) {
  44340. X               for (x=0;x<xdots;x++) {
  44341. X                  k=getcolor(x,y);
  44342. X                  if (x % 8 == 0) {
  44343. X                 if (x) rleputxelval((int)bit8);
  44344. X                                 if (k == 0) bit8 = 0; else bit8 = 1;
  44345. X                  }
  44346. X                  else
  44347. X                 bit8 = (bit8 << 1) + ((k==0) ? 0 : 1);
  44348. X               }
  44349. X               if (xdots % 8) bit8 <<= (8 - (xdots % 8));
  44350. X                       rleputxelval((int)bit8);
  44351. X               rleflush();
  44352. X            } else {
  44353. X               for (x=0;x<xdots;x++) {
  44354. X                  k=getcolor(x,y);
  44355. X                  rleputxelval((int)(unsigned char)convert[k]);
  44356. X               }
  44357. X                 rleflush();
  44358. X            }
  44359. X             }
  44360. X        } else
  44361. X        {
  44362. X            for (x=0;x<xdots;x++)
  44363. X            {
  44364. X            k=getcolor(x,y);
  44365. X            if (ColorPS)
  44366. X              {
  44367. X              sprintf(&buff[i], "%02X%02X%02X", dacbox[k][0]<<2,
  44368. X                                dacbox[k][1]<<2,
  44369. X                                dacbox[k][2]<<2);
  44370. X              i+=6;
  44371. X              }
  44372. X            else
  44373. X              {
  44374. X              k*=2;
  44375. X              buff[i++]=convert[k];
  44376. X              buff[i++]=convert[k+1];
  44377. X              }
  44378. X            if (i>=64)
  44379. X            {
  44380. X                strcpy(&buff[i],"  ");
  44381. X                Printer_printf("%s%s",buff,EndOfLine);
  44382. X                i=0;
  44383. X                j++;
  44384. X                if (j>9)
  44385. X                {
  44386. X                j=0;
  44387. X                Printer_printf(EndOfLine);
  44388. X                }
  44389. X            }
  44390. X            }
  44391. X        }
  44392. X        }
  44393. X        if (Printer_Compress) {
  44394. X        rleputrest();
  44395. X        } else {
  44396. X        strcpy(&buff[i],"  ");
  44397. X        Printer_printf("%s%s",buff,EndOfLine);
  44398. X        i=0;
  44399. X        j++;
  44400. X        if (j>9)
  44401. X        {
  44402. X            j=0;
  44403. X            Printer_printf(EndOfLine);
  44404. X        }
  44405. X        }
  44406. X        if ( (EPSFileType > 0) && (EPSFileType <3) )
  44407. X        Printer_printf("%s%%%%Trailer%sEPSFsave restore%s",EndOfLine,
  44408. X            EndOfLine,EndOfLine);
  44409. X        else
  44410. X#ifndef XFRACT
  44411. X        PRINTER_PRINTF4("%sshowpage%s%c",EndOfLine,EndOfLine,4);
  44412. X#else
  44413. X        PRINTER_PRINTF3("%sshowpage%s",EndOfLine,EndOfLine);
  44414. X#endif
  44415. X        break;
  44416. X        }
  44417. X
  44418. X    case 7: /* HP Plotter */
  44419. X        {
  44420. X        double parm1,parm2;
  44421. X        for (i=0;i<3;i++)
  44422. X        {
  44423. X          PRINTER_PRINTF4("%sSP %d;%s\0",EndOfLine,(i+1),EndOfLine);
  44424. X          for (y=0;(y<ydots)&&(!keypressed());y++)
  44425. X          {
  44426. X        for (x=0;x<xdots;x++)
  44427. X        {
  44428. X          j=dacbox[getcolor(x,y)][i];
  44429. X          if (j>0)
  44430. X          {
  44431. X            switch(Printer_SStyle)
  44432. X            {
  44433. X              case 0:
  44434. X            ci=0.004582144*(double)j;
  44435. X            ck= -.007936057*(double)j;
  44436. X            parm1 = (double)x+.5+ci+(((double)i-1.0)/3);
  44437. X            parm2 = (double)y+.5+ck;
  44438. X            break;
  44439. X              case 1:
  44440. X            ci= -.004582144*(double)j+(((double)i+1.0)/8.0);
  44441. X            ck= -.007936057*(double)j;
  44442. X            parm1 = (double)x+.5+ci;
  44443. X            parm2 = (double)y+.5+ck;
  44444. X            break;
  44445. X              case 2:
  44446. X            ci= -.0078125*(double)j+(((double)i+1.0)*.003906250);
  44447. X            ck= -.0078125*(double)j;
  44448. X            parm1 = (double)x+.5+ci;
  44449. X            parm2 = (double)y+.5+ck;
  44450. X            break;
  44451. X            }
  44452. X            Printer_printf("PA %f,%f;PD;PR %f,%f;PU;\0",
  44453. X            parm1,parm2, ci*((double)-2), ck*((double)-2));
  44454. X          }
  44455. X        }
  44456. X          }
  44457. X        }
  44458. X        PRINTER_PRINTF3("%s;SC;PA 0,0;SP0;%s\0",EndOfLine,EndOfLine);
  44459. X        PRINTER_PRINTF2(";;SP 0;%s\0",EndOfLine);
  44460. X        break;
  44461. X        }
  44462. X    }
  44463. X
  44464. X    if (Print_To_File > 0) fclose(PRFILE);
  44465. X#ifndef XFRACT
  44466. X    if ((LPTn==30)||(LPTn==31))
  44467. X    {
  44468. X    for (x=0;x<2000;x++);
  44469. X    outp((LPTn==30) ? 0x3FC : 0x2FC,0x00);
  44470. X    outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00);
  44471. X    }
  44472. X#else
  44473. X    putstring(5,0,0,"Printing done\n");
  44474. X#endif
  44475. X    EXIT_OVLY;
  44476. X}
  44477. X
  44478. X
  44479. Xstatic void _fastcall graphics_init(int ptrid,int res,char *EndOfLine)
  44480. X{
  44481. X    int i,j;
  44482. X
  44483. X    switch (ptrid) {
  44484. X
  44485. X    case 1:
  44486. X        print_title(ptrid,res,EndOfLine);
  44487. X        PRINTER_PRINTF2("\033*t%iR\033*r0A",res);/* HP           */
  44488. X        break;
  44489. X
  44490. X    case 2:
  44491. X    case 3:
  44492. X        print_title(ptrid,res,EndOfLine);
  44493. X        Printer_printf("\033\063\030");/* IBM                   */
  44494. X        break;
  44495. X
  44496. X    case 4: /****** PaintJet *****/
  44497. X        print_title(ptrid,res,EndOfLine);
  44498. X        pj_width = ydots;
  44499. X        if (res == 90) pj_width <<= 1;
  44500. X        PRINTER_PRINTF2("\033*r0B\033*t180R\033*r3U\033*r%dS\033*b0M\033*r0A",
  44501. X        pj_width);
  44502. X        pj_width >>= 3;
  44503. X        break;
  44504. X
  44505. X    case 5:   /***** PostScript *****/
  44506. X    case 6:   /***** PostScript Landscape *****/
  44507. X        if (!((EPSFileType > 0) && (ptrid==5)))
  44508. X        PRINTER_PRINTF2("%%!PS-Adobe%s",EndOfLine);
  44509. X        if ((EPSFileType > 0) &&     /* Only needed if saving to .EPS */
  44510. X        (ptrid == 5))
  44511. X        {
  44512. X        PRINTER_PRINTF2("%%!PS-Adobe-1.0 EPSF-2.0%s",EndOfLine);
  44513. X
  44514. X        if (EPSFileType==1)
  44515. X            i=xdots+78;
  44516. X        else
  44517. X            i=(int)((double)xdots * (72.0 / (double)res))+78;
  44518. X
  44519. X        if (Printer_Titleblock==0)
  44520. X            {
  44521. X            if (EPSFileType==1) { j = ydots + 78; }
  44522. X            else { j = (int)(((double)ydots * (72.0 / (double)res) / (double)finalaspectratio)+78); }
  44523. X            }
  44524. X        else
  44525. X            {
  44526. X            if (EPSFileType==1) { j = ydots + 123; }
  44527. X            else { j = (int)(((double)ydots * (72.0 / (double)res))+123); }
  44528. X            }
  44529. X        PRINTER_PRINTF4("%%%%TemplateBox: 12 12 %d %d%s",i,j,EndOfLine);
  44530. X        PRINTER_PRINTF4("%%%%BoundingBox: 12 12 %d %d%s",i,j,EndOfLine);
  44531. X        PRINTER_PRINTF4("%%%%PrinterRect: 12 12 %d %d%s",i,j,EndOfLine);
  44532. X        PRINTER_PRINTF2("%%%%Creator: Fractint PostScript%s",EndOfLine);
  44533. X        Printer_printf("%%%%Title: A %s fractal - %s - Fractint EPSF Type %d%s",
  44534. X                       curfractalspecific->name[0]=='*' ?
  44535. X                       &curfractalspecific->name[1] :
  44536. X                       curfractalspecific->name,
  44537. X                       PrintName,
  44538. X                       EPSFileType,
  44539. X                       EndOfLine);
  44540. X        if (Printer_Titleblock==1)
  44541. X            PRINTER_PRINTF2("%%%%DocumentFonts: Helvetica%s",EndOfLine);
  44542. X        PRINTER_PRINTF2("%%%%EndComments%s",EndOfLine);
  44543. X        PRINTER_PRINTF2("/EPSFsave save def%s",EndOfLine);
  44544. X        PRINTER_PRINTF2("0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin%s",EndOfLine);
  44545. X        PRINTER_PRINTF2("10 setmiterlimit [] 0 setdash newpath%s",EndOfLine);
  44546. X        }
  44547. X
  44548. X        /* Common code for all PostScript */
  44549. X        PRINTER_PRINTF2("/Tr {translate} def%s",EndOfLine);
  44550. X        PRINTER_PRINTF2("/Mv {moveto} def%s",EndOfLine);
  44551. X        PRINTER_PRINTF2("/D {dup} def%s",EndOfLine);
  44552. X        PRINTER_PRINTF2("/Rh {readhexstring} def%s",EndOfLine);
  44553. X        PRINTER_PRINTF2("/Cf {currentfile} def%s",EndOfLine);
  44554. X        PRINTER_PRINTF2("/Rs {readstring} def%s",EndOfLine);
  44555. X
  44556. X        if (Printer_Compress) {
  44557. X        rleprolog(xdots,ydots);
  44558. X        } else 
  44559. X        {
  44560. X        PRINTER_PRINTF3("/picstr %d string def%s",
  44561. X            ColorPS?xdots*3:xdots,EndOfLine);
  44562. X        Printer_printf("/dopic { gsave %d %d 8 [%d 0 0 %d 0 %d]%s",
  44563. X                     xdots, ydots, xdots, -ydots, ydots,
  44564. X                     EndOfLine);
  44565. X        PRINTER_PRINTF2("{ Cf picstr Rh pop }%s", EndOfLine);
  44566. X        if (ColorPS)
  44567. X        {
  44568. X            PRINTER_PRINTF2(" false 3 colorimage grestore } def%s",
  44569. X             EndOfLine);
  44570. X        }
  44571. X        else
  44572. X        {
  44573. X            PRINTER_PRINTF2(" image grestore } def%s", EndOfLine);
  44574. X        }
  44575. X            }
  44576. X        if (Printer_Titleblock==1)
  44577. X        {
  44578. X        PRINTER_PRINTF2("/Helvetica findfont 8 scalefont setfont%s",EndOfLine);
  44579. X        if (ptrid==5) Printer_printf("30 60 Mv ");
  44580. X        else          Printer_printf("552 30 Mv 90 rotate ");
  44581. X        print_title(ptrid,res,EndOfLine);
  44582. X        if (ptrid==6) Printer_printf("-90 rotate ");
  44583. X        }
  44584. X
  44585. X        if (EPSFileType != 1) /* Do not use on a WELL BEHAVED .EPS */
  44586. X          {
  44587. X          if ((ptrid == 5)&&(EPSFileType==2)&&
  44588. X          ((Printer_ColorXlat!=0)||(Printer_SetScreen!=0)))
  44589. X            PRINTER_PRINTF2("%%%%BeginFeature%s",EndOfLine);
  44590. X          if (ColorPS)
  44591. X        {
  44592. X        if (Printer_ColorXlat==1)
  44593. X            PRINTER_PRINTF2("{1 exch sub} D D D setcolortransfer%s",EndOfLine);
  44594. X        if (Printer_ColorXlat>1)
  44595. X            PRINTER_PRINTF4("{%d mul round %d div} D D D setcolortransfer%s",
  44596. X                       Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  44597. X        if (Printer_ColorXlat<-1)
  44598. X            PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} D D D setcolortransfer",
  44599. X                       Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  44600. X
  44601. X        if (Printer_SetScreen==1)
  44602. X            {
  44603. X            Printer_printf("%d %d {%s}%s",
  44604. X                       Printer_RFrequency,
  44605. X                       Printer_RAngle,
  44606. X                       HalfTone[Printer_RStyle],
  44607. X                       EndOfLine);
  44608. X            Printer_printf("%d %d {%s}%s",
  44609. X                       Printer_GFrequency,
  44610. X                       Printer_GAngle,
  44611. X                       HalfTone[Printer_GStyle],
  44612. X                       EndOfLine);
  44613. X            Printer_printf("%d %d {%s}%s",
  44614. X                       Printer_BFrequency,
  44615. X                       Printer_BAngle,
  44616. X                       HalfTone[Printer_BStyle],
  44617. X                       EndOfLine);
  44618. X            Printer_printf("%d %d {%s}%s",
  44619. X                       Printer_SFrequency,
  44620. X                       Printer_SAngle,
  44621. X                       HalfTone[Printer_SStyle],
  44622. X                       EndOfLine);
  44623. X            PRINTER_PRINTF2("setcolorscreen%s", EndOfLine);
  44624. X            }
  44625. X            }
  44626. X          else
  44627. X          {
  44628. X         if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) {
  44629. X            /* b&w case requires no mask building */
  44630. X        }
  44631. X        else {
  44632. X           if (Printer_ColorXlat==1)
  44633. X              PRINTER_PRINTF2("{1 exch sub} settransfer%s",EndOfLine);
  44634. X           if (Printer_ColorXlat>1)
  44635. X              PRINTER_PRINTF4("{%d mul round %d div} settransfer%s",
  44636. X                      Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  44637. X           if (Printer_ColorXlat<-1)
  44638. X              PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} settransfer",
  44639. X                      Printer_ColorXlat,Printer_ColorXlat,EndOfLine);
  44640. X        
  44641. X           if (Printer_SetScreen==1)
  44642. X              Printer_printf("%d %d {%s} setscreen%s",
  44643. X                     Printer_SFrequency,
  44644. X                     Printer_SAngle,
  44645. X                     HalfTone[Printer_SStyle],
  44646. X                     EndOfLine);
  44647. X        }
  44648. X          }
  44649. X
  44650. X          if (ptrid == 5)
  44651. X         {
  44652. X            if ((EPSFileType==2)&&((Printer_ColorXlat!=0)||(Printer_SetScreen!=0)))
  44653. X            PRINTER_PRINTF2("%%%%EndFeature%s",EndOfLine);
  44654. X            if (res == 0)
  44655. X            {
  44656. X            PRINTER_PRINTF2("30 191.5 Tr 552 %4.1f",
  44657. X                    (552.0*(double)finalaspectratio));
  44658. X            }
  44659. X            else
  44660. X            {
  44661. X            PRINTER_PRINTF4("30 %d Tr %f %f",
  44662. X                     75 - ((Printer_Titleblock==1) ? 0 : 45),
  44663. X                     ((double)xdots*(72.0/(double)res)),
  44664. X                     ((double)xdots*(72.0/(double)res)*(double)finalaspectratio));
  44665. X            }
  44666. X          }
  44667. X        else                 /* For Horizontal PostScript */
  44668. X        {
  44669. X            if (res == 0)
  44670. X            {
  44671. X            PRINTER_PRINTF2("582 30 Tr 90 rotate 732 %4.1f",
  44672. X                    (732.0*(double)finalaspectratio));
  44673. X            }
  44674. X            else
  44675. X            {
  44676. X            PRINTER_PRINTF4("%d 30 Tr 90 rotate %f %f",
  44677. X                     537 + ((Printer_Titleblock==1) ? 0 : 45),
  44678. X                     ((double)xdots*(72.0/(double)res)),
  44679. X                     ((double)xdots*(72.0/(double)res)*(double)finalaspectratio));
  44680. X            }
  44681. X        }
  44682. X        PRINTER_PRINTF2(" scale%s",EndOfLine);
  44683. X          }
  44684. X
  44685. X        else if (ptrid == 5)       /* To be used on WELL-BEHAVED .EPS */
  44686. X        Printer_printf("30 %d Tr %d %d scale%s",
  44687. X                    75 - ((Printer_Titleblock==1) ? 0 : 45),
  44688. X                    xdots,ydots,EndOfLine);
  44689. X
  44690. X        PRINTER_PRINTF2("dopic%s",EndOfLine);
  44691. X        break;
  44692. X
  44693. X    case 7: /* HP Plotter */
  44694. X        if (res<1) res=1;
  44695. X        if (res>10) res=10;
  44696. X        ci = (((double)xdots*((double)res-1.0))/2.0);
  44697. X        ck = (((double)ydots*((double)res-1.0))/2.0);
  44698. X        Printer_printf(";IN;SP0;SC%d,%d,%d,%d;%s\0",
  44699. X        (int)(-ci),(int)((double)xdots+ci),
  44700. X        (int)((double)ydots+ck),(int)(-ck),EndOfLine);
  44701. X        break;
  44702. X    }
  44703. X}
  44704. X
  44705. X
  44706. Xstatic void _fastcall print_title(int ptrid,int res,char *EndOfLine)
  44707. X{
  44708. X    char buff[80];
  44709. X    int postscript;
  44710. X    if (Printer_Titleblock == 0)
  44711. X    return;
  44712. X    postscript = (ptrid == 5 || ptrid ==6);
  44713. X    if (!postscript)
  44714. X    Printer_printf(EndOfLine);
  44715. X    else
  44716. X    Printer_printf("(");
  44717. X    Printer_printf((curfractalspecific->name[0]=='*')
  44718. X             ? &curfractalspecific->name[1]
  44719. X             : curfractalspecific->name);
  44720. X    if (fractype == FORMULA || fractype == FFORMULA)
  44721. X    Printer_printf(" %s",FormName);
  44722. X    if (fractype == LSYSTEM)
  44723. X    Printer_printf(" %s",LName);
  44724. X    if (fractype == IFS || fractype == IFS3D)
  44725. X    Printer_printf(" %s",IFSName);
  44726. X    Printer_printf(" - %dx%d - %d DPI", xdots, ydots, res);
  44727. X    if (!postscript)
  44728. X    Printer_printf(EndOfLine);
  44729. X    else {
  44730. X    Printer_printf(") show%s",EndOfLine);
  44731. X    if (ptrid==5) Printer_printf("30 50 moveto (");
  44732. X    else          Printer_printf("-90 rotate 562 30 moveto 90 rotate (");
  44733. X    }
  44734. X    Printer_printf("Corners: Top-Left=%.16g/%.16g Bottom-Right=%.16g/%.16g",
  44735. X           xxmin,yymax,xxmax,yymin);
  44736. X    if (xx3rd != xxmin || yy3rd != yymin) {
  44737. X    if (!postscript)
  44738. X        Printer_printf("%s        ",EndOfLine);
  44739. X    Printer_printf(" Bottom-Left=%4.4f/%4.4f",xx3rd,yy3rd);
  44740. X    }
  44741. X    if (!postscript)
  44742. X    Printer_printf(EndOfLine);
  44743. X    else {
  44744. X    Printer_printf(") show%s",EndOfLine);
  44745. X    if (ptrid==5) Printer_printf("30 40 moveto (");
  44746. X    else          Printer_printf("-90 rotate 572 30 moveto 90 rotate (");
  44747. X    }
  44748. X    showtrig(buff);
  44749. X    Printer_printf("Parameters: %4.4f/%4.4f/%4.4f/%4.4f %s",
  44750. X           param[0],param[1],param[2],param[3],buff);
  44751. X    if (!postscript)
  44752. X    Printer_printf(EndOfLine);
  44753. X    else
  44754. X    Printer_printf(") show%s",EndOfLine);
  44755. X}
  44756. X
  44757. X/* This function prints a string to the the printer with BIOS calls. */
  44758. X
  44759. X#ifndef XFRACT
  44760. Xstatic void Printer_printf(char far *fmt,...)
  44761. X#else
  44762. Xstatic void Printer_printf(va_alist)
  44763. Xva_dcl
  44764. X#endif
  44765. X{
  44766. Xint i;
  44767. Xchar s[500];
  44768. Xint x=0;
  44769. Xva_list arg;
  44770. X
  44771. X#ifndef XFRACT
  44772. Xva_start(arg,fmt);
  44773. X#else
  44774. Xchar far *fmt;
  44775. Xva_start(arg);
  44776. Xfmt = va_arg(arg,char far *);
  44777. X#endif
  44778. X
  44779. X{
  44780. X   /* copy far to near string */
  44781. X   char fmt1[100];
  44782. X   i=0;
  44783. X   while(fmt[i]) {
  44784. X     fmt1[i] = fmt[i];
  44785. X     i++;
  44786. X   }
  44787. X   fmt1[i] = '\0';
  44788. X   vsprintf(s,fmt1,arg);
  44789. X}   
  44790. X
  44791. Xif (Print_To_File>0)    /* This is for printing to file */
  44792. X    fprintf(PRFILE,"%s",s);
  44793. Xelse            /* And this is for printing to printer */
  44794. X    while (s[x])
  44795. X    if (printer(s[x++])!=0)
  44796. X        while (!keypressed()) { if (printer(s[x-1])==0) break; }
  44797. X}
  44798. X
  44799. X/* This function standardizes both _bios_printer and _bios_serialcom
  44800. X * in one function.  It takes its arguments and rearranges them and calls
  44801. X * the appropriate bios call.  If it then returns result !=0, there is a
  44802. X * problem with the printer.
  44803. X */
  44804. Xstatic int _fastcall printer(int c)
  44805. X{
  44806. X    if (Print_To_File>0) return ((fprintf(PRFILE,"%c",c))<1);
  44807. X#ifndef XFRACT
  44808. X    if (LPTn<9)  return (((_bios_printer(0,LPTn,c))+0x0010)&0x0010);
  44809. X    if (LPTn<19) return ((_bios_serialcom(1,(LPTn-10),c))&0x9E00);
  44810. X    if ((LPTn==20)||(LPTn==21))
  44811. X    {
  44812. X    int PS=0;
  44813. X    while ((PS & 0xF8) != 0xD8)
  44814. X        { PS = inp((LPTn==20) ? 0x379 : 0x279);
  44815. X          if (keypressed()) return(1); }
  44816. X    outp((LPTn==20) ? 0x37C : 0x27C,c);
  44817. X    PS = inp((LPTn==20) ? 0x37A : 0x27A);
  44818. X    outp((LPTn==20) ? 0x37A : 0x27A,(PS | 0x01));
  44819. X    outp((LPTn==20) ? 0x37A : 0x27A,PS);
  44820. X    return(0);
  44821. X    }
  44822. X    if ((LPTn==30)||(LPTn==31))
  44823. X    {
  44824. X    while (((inp((LPTn==30) ? 0x3FE : 0x2FE)&0x30)!=0x30) ||
  44825. X           ((inp((LPTn==30) ? 0x3FD : 0x2FD)&0x60)!=0x60))
  44826. X        { if (keypressed()) return (1); }
  44827. X    outp((LPTn==30) ? 0x3F8 : 0x2F8,c);
  44828. X    return(0);
  44829. X    }
  44830. X#endif
  44831. X
  44832. X    /* MCP 7-7-91, If we made it down to here, we may as well error out. */
  44833. X    return(-1);
  44834. X}
  44835. X
  44836. X#ifdef __BORLANDC__
  44837. X#if(__BORLANDC__ > 2)
  44838. X   #pragma warn +eff
  44839. X#endif
  44840. X#endif
  44841. X
  44842. Xstatic void printer_reset()
  44843. X{
  44844. X#ifndef XFRACT
  44845. X    if (Print_To_File < 1)
  44846. X    if (LPTn<9)      _bios_printer(1,LPTn,0);
  44847. X    else if (LPTn<19) _bios_serialcom(3,(LPTn-10),0);
  44848. X#endif
  44849. X}
  44850. X
  44851. X
  44852. X/** debug code for pj_ color table checkout
  44853. Xcolor_test()
  44854. X{
  44855. X   int x,y,color,i,j,xx,yy;
  44856. X   int bw,cw,bh,ch;
  44857. X   setvideomode(videoentry.videomodeax,
  44858. X        videoentry.videomodebx,
  44859. X        videoentry.videomodecx,
  44860. X        videoentry.videomodedx);
  44861. X   bw = xdots/25; cw = bw * 2 / 3;
  44862. X   bh = ydots/10; ch = bh * 2 / 3;
  44863. X   dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 60;
  44864. X   if (debugflag == 902)
  44865. X      dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  44866. X   for (x = 0; x < 25; ++x)
  44867. X      for (y = 0; y < 10; ++y) {
  44868. X     if (x < 11) i = (32 - x) * 10 + y;
  44869. X         else    i = (24 - x) * 10 + y;
  44870. X     color = x * 10 + y + 1;
  44871. X     dacbox[color][0] = dstack[0][0][i];
  44872. X     dacbox[color][1] = dstack[0][1][i];
  44873. X     dacbox[color][2] = dstack[0][2][i];
  44874. X     for (i = 0; i < cw; ++i) {
  44875. X        xx = x * bw + bw / 6 + i;
  44876. X        yy = y * bh + bh / 6;
  44877. X        for (j = 0; j < ch; ++j)
  44878. X           putcolor(xx,yy++,color);
  44879. X        }
  44880. X     }
  44881. X   spindac(0,1);
  44882. X   getakey();
  44883. X}
  44884. X**/
  44885. X
  44886. X
  44887. X/*
  44888. X * The following code for compressed PostScript is based on pnmtops.c.  It is
  44889. X * copyright (C) 1989 by Jef Poskanzer, and carries the following notice:
  44890. X * "Permission to use, copy, modify, and distribute this software and its
  44891. X *  documentation for any purpose and without fee is hereby granted, provided
  44892. X *  that the above copyright notice appear in all copies and that both that
  44893. X *  copyright notice and this permission notice appear in supporting
  44894. X *  documentation.  This software is provided "as is" without express or
  44895. X *  implied warranty."
  44896. X */
  44897. X
  44898. Xstatic rleprolog(x,y)
  44899. Xint x,y;
  44900. X{
  44901. X    itemsperline = 0;
  44902. X    items = 0;
  44903. X    bitspersample = 8;
  44904. X    repeat = 1;
  44905. X    rlebitsperitem = 0;
  44906. X    rlebitshift = 0;
  44907. X    count = 0;
  44908. X
  44909. X    PRINTER_PRINTF2( "/rlestr1 1 string def%s", EndOfLine );
  44910. X    PRINTER_PRINTF2( "/rdrlestr {%s", EndOfLine );    /* s -- nr */
  44911. X    PRINTER_PRINTF2( "  /rlestr exch def%s", EndOfLine );    /* - */
  44912. X    PRINTER_PRINTF2( "  Cf rlestr1 Rh pop%s", EndOfLine );  /* s1 */
  44913. X    PRINTER_PRINTF2( "  0 get%s", EndOfLine );                     /* c */
  44914. X    PRINTER_PRINTF2( "  D 127 le {%s", EndOfLine );         /* c */
  44915. X    PRINTER_PRINTF2( "    Cf rlestr 0%s", EndOfLine );      /* c f s 0 */
  44916. X    PRINTER_PRINTF2( "    4 3 roll%s", EndOfLine );                /* f s 0 c */
  44917. X    PRINTER_PRINTF2( "    1 add  getinterval%s", EndOfLine );      /* f s */
  44918. X    PRINTER_PRINTF2( "    Rh pop%s", EndOfLine );    /* s */
  44919. X    PRINTER_PRINTF2( "    length%s", EndOfLine );                  /* nr */
  44920. X    PRINTER_PRINTF2( "  } {%s", EndOfLine );                       /* c */
  44921. X    PRINTER_PRINTF2( "    256 exch sub D%s", EndOfLine );     /* n n */
  44922. X    PRINTER_PRINTF2( "    Cf rlestr1 Rh pop%s", EndOfLine );/* n n s1 */
  44923. X    PRINTER_PRINTF2( "    0 get%s", EndOfLine );                   /* n n c */
  44924. X    PRINTER_PRINTF2( "    exch 0 exch 1 exch 1 sub {%s", EndOfLine );           /* n c 0 1 n-1*/
  44925. X    PRINTER_PRINTF2( "      rlestr exch 2 index put%s", EndOfLine );
  44926. X    PRINTER_PRINTF2( "    } for%s", EndOfLine );                   /* n c */
  44927. X    PRINTER_PRINTF2( "    pop%s", EndOfLine );                     /* nr */
  44928. X    PRINTER_PRINTF2( "  } ifelse%s", EndOfLine );                  /* nr */
  44929. X    PRINTER_PRINTF2( "} bind def%s", EndOfLine );
  44930. X    PRINTER_PRINTF2( "/Rs {%s", EndOfLine );           /* s -- s */
  44931. X    PRINTER_PRINTF2( "  D length 0 {%s", EndOfLine );         /* s l 0 */
  44932. X    PRINTER_PRINTF2( "    3 copy exch%s", EndOfLine );          /* s l n s n l*/
  44933. X    PRINTER_PRINTF2( "    1 index sub%s", EndOfLine );          /* s l n s n r*/
  44934. X    PRINTER_PRINTF2( "    getinterval%s", EndOfLine );          /* s l n ss */
  44935. X    PRINTER_PRINTF2( "    rdrlestr%s", EndOfLine );       /* s l n nr */
  44936. X    PRINTER_PRINTF2( "    add%s", EndOfLine );                     /* s l n */
  44937. X    PRINTER_PRINTF2( "    2 copy le { exit } if%s", EndOfLine );   /* s l n */
  44938. X    PRINTER_PRINTF2( "  } loop%s", EndOfLine );                    /* s l l */
  44939. X    PRINTER_PRINTF2( "  pop pop%s", EndOfLine );                   /* s */
  44940. X    PRINTER_PRINTF2( "} bind def%s", EndOfLine );
  44941. X    if (ColorPS) {
  44942. X    PRINTER_PRINTF3( "/rpicstr %d string def%s", x,EndOfLine );
  44943. X    PRINTER_PRINTF3( "/gpicstr %d string def%s", x,EndOfLine );
  44944. X    PRINTER_PRINTF3( "/bpicstr %d string def%s", x,EndOfLine );
  44945. X    } else {
  44946. X    PRINTER_PRINTF3( "/picstr %d string def%s", x,EndOfLine );
  44947. X    }
  44948. X    PRINTER_PRINTF2( "/dopic {%s", EndOfLine);
  44949. X    PRINTER_PRINTF2( "/gsave%s", EndOfLine);
  44950. X    if (ColorPS) {
  44951. X       PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine);
  44952. X    } else { /* b&w */
  44953. X       if (Printer_ColorXlat==-2) {
  44954. X          PRINTER_PRINTF4( "%d %d true%s", x, y, EndOfLine);
  44955. X       } else if (Printer_ColorXlat==2) {
  44956. X          PRINTER_PRINTF4( "%d %d false%s", x, y, EndOfLine);
  44957. X       } else {
  44958. X      PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine);
  44959. X       }
  44960. X    }
  44961. X    Printer_printf( "[%d 0 0 %d 0 %d]%s", x, -y, y, EndOfLine);
  44962. X    if (ColorPS) {
  44963. X    PRINTER_PRINTF2( "{rpicstr Rs}%s", EndOfLine);
  44964. X    PRINTER_PRINTF2( "{gpicstr Rs}%s", EndOfLine);
  44965. X    PRINTER_PRINTF2( "{bpicstr Rs}%s", EndOfLine);
  44966. X    PRINTER_PRINTF2( "true 3 colorimage%s", EndOfLine);
  44967. X    } else {
  44968. X       if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) {
  44969. X      /* save file space and printing time (if scaling is right) */
  44970. X      PRINTER_PRINTF2( "{picstr Rs} imagemask%s", EndOfLine);
  44971. X       } else {
  44972. X      PRINTER_PRINTF2( "{picstr Rs} image%s", EndOfLine);
  44973. X       }
  44974. X    }
  44975. X    PRINTER_PRINTF2( "} def%s", EndOfLine);
  44976. X}
  44977. X
  44978. Xstatic void
  44979. Xrleputbuffer()
  44980. X    {
  44981. X    int i;
  44982. X
  44983. X    if ( repeat )
  44984. X    {
  44985. X    item = 256 - count;
  44986. X    putitem();
  44987. X    item = repeatitem;
  44988. X    putitem();
  44989. X    }
  44990. X    else
  44991. X    {
  44992. X    item = count - 1;
  44993. X    putitem();
  44994. X    for ( i = 0; i < count; ++i )
  44995. X        {
  44996. X        item = itembuf[i];
  44997. X        putitem();
  44998. X        }
  44999. X    }
  45000. X    repeat = 1;
  45001. X    count = 0;
  45002. X    }
  45003. X
  45004. Xstatic void
  45005. Xrleputitem()
  45006. X    {
  45007. X    int i;
  45008. X
  45009. X    if ( count == 128 )
  45010. X    rleputbuffer();
  45011. X
  45012. X    if ( repeat && count == 0 )
  45013. X    { /* Still initializing a repeat buf. */
  45014. X    itembuf[count] = repeatitem = rleitem;
  45015. X    ++count;
  45016. X    }
  45017. X    else if ( repeat )
  45018. X    { /* Repeating - watch for end of run. */
  45019. X    if ( rleitem == repeatitem )
  45020. X        { /* Run continues. */
  45021. X        itembuf[count] = rleitem;
  45022. X        ++count;
  45023. X        }
  45024. X    else
  45025. X        { /* Run ended - is it long enough to dump? */
  45026. X        if ( count > 2 )
  45027. X        { /* Yes, dump a repeat-mode buffer and start a new one. */
  45028. X        rleputbuffer();
  45029. X        itembuf[count] = repeatitem = rleitem;
  45030. X        ++count;
  45031. X        }
  45032. X        else
  45033. X        { /* Not long enough - convert to non-repeat mode. */
  45034. X        repeat = 0;
  45035. X        itembuf[count] = repeatitem = rleitem;
  45036. X        ++count;
  45037. X        repeatcount = 1;
  45038. X        }
  45039. X        }
  45040. X    }
  45041. X    else
  45042. X    { /* Not repeating - watch for a run worth repeating. */
  45043. X    if ( rleitem == repeatitem )
  45044. X        { /* Possible run continues. */
  45045. X        ++repeatcount;
  45046. X        if ( repeatcount > 3 )
  45047. X        { /* Long enough - dump non-repeat part and start repeat. */
  45048. X        count = count - ( repeatcount - 1 );
  45049. X        rleputbuffer();
  45050. X        count = repeatcount;
  45051. X        for ( i = 0; i < count; ++i )
  45052. X            itembuf[i] = rleitem;
  45053. X        }
  45054. X        else
  45055. X        { /* Not long enough yet - continue as non-repeat buf. */
  45056. X        itembuf[count] = rleitem;
  45057. X        ++count;
  45058. X        }
  45059. X        }
  45060. X    else
  45061. X        { /* Broken run. */
  45062. X        itembuf[count] = repeatitem = rleitem;
  45063. X        ++count;
  45064. X        repeatcount = 1;
  45065. X        }
  45066. X    }
  45067. X
  45068. X    rleitem = 0;
  45069. X    rlebitsperitem = 0;
  45070. X    }
  45071. X
  45072. Xstatic void
  45073. Xputitem()
  45074. X    {
  45075. X    char* hexits = "0123456789abcdef";
  45076. X
  45077. X    if ( itemsperline == 30 )
  45078. X        {
  45079. X    Printer_printf("%s",EndOfLine);
  45080. X        itemsperline = 0;
  45081. X        }
  45082. X    Printer_printf("%c%c", hexits[item >> 4], hexits[item & 15] );
  45083. X    ++itemsperline;
  45084. X    ++items;
  45085. X    item = 0;
  45086. X    bitsperitem = 0;
  45087. X    bitshift = 8 - bitspersample;
  45088. X    }
  45089. X
  45090. Xstatic void
  45091. Xrleputxelval( xv )
  45092. X    int xv;
  45093. X    {
  45094. X    if ( rlebitsperitem == 8 )
  45095. X    rleputitem();
  45096. X    rleitem += xv<<bitshift;
  45097. X    rlebitsperitem += bitspersample;
  45098. X    rlebitshift -= bitspersample;
  45099. X    }
  45100. X
  45101. Xstatic void
  45102. Xrleflush()
  45103. X    {
  45104. X    if ( rlebitsperitem > 0 )
  45105. X    rleputitem();
  45106. X    if ( count > 0 )
  45107. X    rleputbuffer();
  45108. X    }
  45109. X
  45110. Xstatic void
  45111. Xrleputrest()
  45112. X    {
  45113. X    rleflush();
  45114. X    Printer_printf( "%s",EndOfLine );
  45115. X    Printer_printf( "grestore%s",EndOfLine );
  45116. X    }
  45117. SHAR_EOF
  45118. $TOUCH -am 1028230093 printer.c &&
  45119. chmod 0644 printer.c ||
  45120. echo "restore of printer.c failed"
  45121. set `wc -c printer.c`;Wc_c=$1
  45122. if test "$Wc_c" != "44938"; then
  45123.     echo original size 44938, current size $Wc_c
  45124. fi
  45125. # ============= prompts1.c ==============
  45126. echo "x - extracting prompts1.c (Text)"
  45127. sed 's/^X//' << 'SHAR_EOF' > prompts1.c &&
  45128. X/*
  45129. X    Various routines that prompt for things.
  45130. X    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  45131. X*/
  45132. X
  45133. X#include <stdlib.h>
  45134. X#include <stdio.h>
  45135. X#include <string.h>
  45136. X#include <ctype.h>
  45137. X#ifndef XFRACT
  45138. X#include <dos.h>
  45139. X#elif !defined(__386BSD__)
  45140. X#include <sys/types.h>
  45141. X#include <sys/stat.h>
  45142. X#include <sys/dir.h>
  45143. X#endif
  45144. X#ifdef __TURBOC__
  45145. X#include <alloc.h>
  45146. X#elif !defined(__386BSD__)
  45147. X#include <malloc.h>
  45148. X#endif
  45149. X
  45150. X#ifdef __hpux
  45151. X#include <sys/param.h>
  45152. X#define getwd(a) getcwd(a,MAXPATHLEN)
  45153. X#endif
  45154. X
  45155. X#include "fractint.h"
  45156. X#include "fractype.h"
  45157. X#include "helpdefs.h"
  45158. X#include "prototyp.h"
  45159. X
  45160. Xextern int Targa_Overlay;
  45161. Xextern int Targa_Out;
  45162. Xextern BYTE back_color[];
  45163. Xextern float  screenaspect;
  45164. X
  45165. X/* Routines defined in prompts2.c */
  45166. X
  45167. Xextern    int get_corners(void);
  45168. Xextern    int edit_ifs_params(void );
  45169. Xextern    int lccompare(VOIDCONSTPTR, VOIDCONSTPTR);
  45170. X
  45171. X/* Routines used in prompts2.c */
  45172. X
  45173. X    int prompt_checkkey(int curkey);
  45174. X    long get_file_entry(int,char *,char *,char *,char *);
  45175. X
  45176. X/* Routines in this module    */
  45177. X
  45178. Xstatic    int prompt_valuestring(char *buf,struct fullscreenvalues *val);
  45179. Xstatic    int input_field_list(int attr,char *fld,int vlen,char **list,int llen,
  45180. X                 int row,int col,int (*checkkey)(int));
  45181. Xstatic    int select_fracttype(int t);
  45182. Xstatic    int sel_fractype_help(int curkey, int choice);
  45183. X    int select_type_params(int newfractype,int oldfractype);
  45184. Xstatic    void set_default_parms(void);
  45185. Xstatic    long gfe_choose_entry(int,char *,char *,char *);
  45186. Xstatic    int check_gfe_key(int curkey,int choice);
  45187. Xstatic    void load_entry_text(FILE *entfile,char far *buf,int maxlines);
  45188. Xstatic    void format_parmfile_line(int,char *);
  45189. Xstatic    int get_light_params(void );
  45190. Xstatic    int check_mapfile(void );
  45191. Xstatic    int get_funny_glasses_params(void );
  45192. X
  45193. Xint julibrot;   /* flag for julibrot */
  45194. X
  45195. Xextern int numtrigfn;
  45196. Xextern int bailout;
  45197. X
  45198. Xextern struct moreparams far moreparams[];
  45199. Xstatic char funnyglasses_map_name[16];
  45200. Xextern char temp1[256];   /* temporary strings          */
  45201. Xextern int previewfactor;
  45202. Xextern int xtrans, ytrans;
  45203. Xextern int red_crop_left, red_crop_right;
  45204. Xextern int blue_crop_left, blue_crop_right;
  45205. Xextern int red_bright, blue_bright;
  45206. Xextern char showbox; /* flag to show box and vector in preview */
  45207. Xextern SEGTYPE extraseg;
  45208. Xextern int whichimage;
  45209. Xextern int xadjust;
  45210. Xextern int eyeseparation;
  45211. Xextern int glassestype;
  45212. Xchar   MAP_name[80] = "";
  45213. Xint    mapset = 0;
  45214. Xextern    int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  45215. Xextern    int    lookatmouse;
  45216. Xextern    int haze;
  45217. Xextern    int RANDOMIZE;
  45218. Xextern    char light_name[];
  45219. Xextern    int Ambient;
  45220. Xextern    int RAY;
  45221. Xextern    int BRIEF;
  45222. Xextern    char ray_name[];
  45223. X
  45224. Xextern    int    init3d[20];    /* '3d=nn/nn/nn/...' values */
  45225. Xextern    double    xxmin,xxmax;    /* initial corner values    */
  45226. Xextern    double    yymin,yymax;    /* initial corner values    */
  45227. X
  45228. Xextern    double    xx3rd,yy3rd;    /* initial corner values    */
  45229. Xextern    int    invert;     /* non-zero if inversion active */
  45230. Xextern    double    inversion[3];    /* radius, xcenter, ycenter */
  45231. Xextern    double    param[];        /* up to six parameters    */
  45232. Xextern    double    potparam[3];    /* three potential parameters*/
  45233. Xextern    int    fractype;    /* if == 0, use Mandelbrot  */
  45234. Xextern    char    preview;    /* 3D preview mode flag */
  45235. Xextern    int    transparent[];    /* transparency values */
  45236. Xextern    int    usr_biomorph;    /* Biomorph flag */
  45237. Xextern    int    viewcrop;
  45238. Xextern    float    finalaspectratio;
  45239. Xextern    int    textcbase;
  45240. Xextern    char    boxy[];
  45241. Xextern    int    display3d;
  45242. X
  45243. Xextern char LFileName[];    /* file to find the formulas in */
  45244. Xextern char LName[];        /* Name of the Formula (if not null) */
  45245. Xextern char FormFileName[];
  45246. Xextern char FormName[];
  45247. Xextern char IFSFileName[];
  45248. Xextern char IFSName[];
  45249. Xextern float far *ifs_defn;
  45250. Xextern int ifs_type;
  45251. Xextern int ifs_changed;
  45252. X
  45253. X/* fullscreen_choice options */
  45254. X#define CHOICEHELP    4
  45255. X
  45256. X#define GETFORMULA 0
  45257. X#define GETLSYS    1
  45258. X#define GETIFS       2
  45259. X#define GETPARM    3
  45260. X
  45261. X
  45262. Xchar ifsmask[13]     = {"*.ifs"};
  45263. Xchar formmask[13]    = {"*.frm"};
  45264. Xchar lsysmask[13]    = {"*.l"};
  45265. Xchar Glasses1Map[] = "glasses1.map";
  45266. X
  45267. Xvoid prompts1_overlay() { }    /* for restore_active_ovly */
  45268. X
  45269. X
  45270. X/* --------------------------------------------------------------------- */
  45271. X
  45272. Xint promptfkeys;
  45273. X
  45274. Xint fullscreen_prompt(    /* full-screen prompting routine */
  45275. X    char far *hdg,        /* heading, lines separated by \n */
  45276. X    int numprompts,     /* there are this many prompts (max) */
  45277. X    char far **prompts,     /* array of prompting pointers */
  45278. X    struct fullscreenvalues *values, /* array of values */
  45279. X    int options,        /* for future */
  45280. X    int fkeymask,        /* bit n on if Fn to cause return */
  45281. X    char far *extrainfo    /* extra info box to display, \n separated */
  45282. X    )
  45283. X{
  45284. X   char far *hdgscan;
  45285. X   int titlelines,titlewidth,titlerow;
  45286. X   int maxpromptwidth,maxfldwidth,maxcomment;
  45287. X   int boxrow,boxlines;
  45288. X   int boxcol,boxwidth;
  45289. X   int extralines,extrawidth,extrarow;
  45290. X   int instrrow;
  45291. X   int promptrow,promptcol,valuecol;
  45292. X   int curchoice;
  45293. X   int done, i, j;
  45294. X   int anyinput;
  45295. X   int savelookatmouse;
  45296. X   int curtype, curlen;
  45297. X   char buf[81];
  45298. X#ifndef XFRACT
  45299. Xstatic char far instr1[]  = {"Use " UPARR " and " DNARR " to select values to change"};
  45300. Xstatic char far instr2a[]  = {"Type in replacement value for selected field"};
  45301. Xstatic char far instr2b[]  = {"Use " LTARR " or " RTARR " to change value of selected field"};
  45302. X#else
  45303. X/* Some compilers don't accept "a" "b", so we have to fill in UPARR ourself.  */
  45304. Xstatic char far instr1[]  = {"Use up(K) and down(J) to select values to change"};
  45305. Xstatic char far instr2a[]  = {"Type in replacement value for selected field"};
  45306. Xstatic char far instr2b[]  = {"Use left(H) or right(L) to change value of selected field"};
  45307. X#endif
  45308. Xstatic char far instr3a[] = {"Press ENTER when finished (or ESCAPE to back out)"};
  45309. Xstatic char far instr3b[] = {"Press ENTER when finished, ESCAPE to back out, or F1 for help"};
  45310. Xstatic char far instr0a[] = {"No changeable parameters; press ENTER to exit"};
  45311. Xstatic char far instr0b[] = {"No changeable parameters; press ENTER to exit or F1 for help"};
  45312. X
  45313. X   ENTER_OVLY(OVLY_PROMPTS1);
  45314. X
  45315. X   if (numprompts <= 0) {    /* ?? nothing to do! */
  45316. X      EXIT_OVLY;
  45317. X      return(0);
  45318. X      }
  45319. X   
  45320. X   savelookatmouse = lookatmouse;
  45321. X   lookatmouse = 0;
  45322. X   promptfkeys = fkeymask;
  45323. X   helptitle();                /* clear screen, display title line  */
  45324. X   setattr(1,0,C_PROMPT_BKGRD,24*80);  /* init rest of screen to background */
  45325. X
  45326. X   hdgscan = hdg;               /* count title lines, find widest */
  45327. X   i = titlewidth = 0;
  45328. X   titlelines = 1;
  45329. X   while (*hdgscan) {
  45330. X      if (*(hdgscan++) == '\n') {
  45331. X     ++titlelines;
  45332. X     i = -1;
  45333. X     }
  45334. X      if (++i > titlewidth)
  45335. X     titlewidth = i;
  45336. X      }
  45337. X   extralines = extrawidth = i = 0;
  45338. X   if ((hdgscan = extrainfo))
  45339. X      if (*hdgscan == 0)
  45340. X     extrainfo = NULL;
  45341. X      else { /* count extra lines, find widest */
  45342. X     extralines = 3;
  45343. X     while (*hdgscan) {
  45344. X        if (*(hdgscan++) == '\n') {
  45345. X           if (extralines + numprompts + titlelines >= 20) {
  45346. X           *hdgscan = 0; /* full screen, cut off here */
  45347. X           break;
  45348. X           }
  45349. X           ++extralines;
  45350. X           i = -1;
  45351. X           }
  45352. X        if (++i > extrawidth)
  45353. X           extrawidth = i;
  45354. X        }
  45355. X     }
  45356. X
  45357. X   /* work out vertical positioning */
  45358. X   i = numprompts + titlelines + extralines + 3; /* total rows required */
  45359. X   j = (25 - i) / 2;               /* top row of it all when centered */
  45360. X   j -= j / 4;                   /* higher is better if lots extra */
  45361. X   boxlines = numprompts;
  45362. X   titlerow = 1 + j;
  45363. X   promptrow = boxrow = titlerow + titlelines;
  45364. X   if (titlerow > 2) {               /* room for blank between title & box? */
  45365. X      --titlerow;
  45366. X      --boxrow;
  45367. X      ++boxlines;
  45368. X      }
  45369. X   instrrow = boxrow+boxlines;
  45370. X   if (instrrow + 3 + extralines < 25) {
  45371. X      ++boxlines;    /* blank at bottom of box */
  45372. X      ++instrrow;
  45373. X      if (instrrow + 3 + extralines < 25)
  45374. X     ++instrrow; /* blank before instructions */
  45375. X      }
  45376. X   extrarow = instrrow + 2;
  45377. X   if (numprompts > 1) /* 3 instructions lines */
  45378. X      ++extrarow;
  45379. X   if (extrarow + extralines < 25)
  45380. X      ++extrarow;
  45381. X
  45382. X   /* work out horizontal positioning */
  45383. X   maxfldwidth = maxpromptwidth = maxcomment = anyinput = 0;
  45384. X   for (i = 0; i < numprompts; i++) {
  45385. X      if (values[i].type == 'y') {
  45386. X     static char *noyes[2] = {"no","yes"};
  45387. X     values[i].type = 'l';
  45388. X     values[i].uval.ch.vlen = 3;
  45389. X     values[i].uval.ch.list = noyes;
  45390. X     values[i].uval.ch.llen = 2;
  45391. X     }
  45392. X      j = far_strlen(prompts[i]);
  45393. X      if (values[i].type == '*') {
  45394. X     if (j > maxcomment)     maxcomment = j;
  45395. X     }
  45396. X      else {
  45397. X         anyinput = 1;
  45398. X     if (j > maxpromptwidth) maxpromptwidth = j;
  45399. X     j = prompt_valuestring(buf,&values[i]);
  45400. X     if (j > maxfldwidth)     maxfldwidth = j;
  45401. X     }
  45402. X      }
  45403. X   boxwidth = maxpromptwidth + maxfldwidth + 2;
  45404. X   if (maxcomment > boxwidth) boxwidth = maxcomment;
  45405. X   if ((boxwidth += 4) > 80) boxwidth = 80;
  45406. X   boxcol = (80 - boxwidth) / 2;       /* center the box */
  45407. X   promptcol = boxcol + 2;
  45408. X   valuecol = boxcol + boxwidth - maxfldwidth - 2;
  45409. X   if (boxwidth <= 76) {           /* make margin a bit wider if we can */
  45410. X      boxwidth += 2;
  45411. X      --boxcol;
  45412. X      }
  45413. X   if ((j = titlewidth) < extrawidth)
  45414. X      j = extrawidth;
  45415. X   if ((i = j + 4 - boxwidth) > 0) {   /* expand box for title/extra */
  45416. X      if (boxwidth + i > 80)
  45417. X     i = 80 - boxwidth;
  45418. X      boxwidth += i;
  45419. X      boxcol -= i / 2;
  45420. X      }
  45421. X   i = (90 - boxwidth) / 20;
  45422. X   boxcol    -= i;
  45423. X   promptcol -= i;
  45424. X   valuecol  -= i;
  45425. X
  45426. X   /* display box heading */
  45427. X   for (i = titlerow; i < boxrow; ++i)
  45428. X      setattr(i,boxcol,C_PROMPT_HI,boxwidth);
  45429. X   textcbase = boxcol + (boxwidth - titlewidth) / 2;
  45430. X   putstring(titlerow,0,C_PROMPT_HI,hdg);
  45431. X
  45432. X   /* display extra info */
  45433. X   if (extrainfo) {
  45434. X#ifndef XFRACT
  45435. X#define S1 '\xC4'
  45436. X#define S2 "\xC0"
  45437. X#define S3 "\xD9"
  45438. X#define S4 "\xB3"
  45439. X#define S5 "\xDA"
  45440. X#define S6 "\xBF"
  45441. X#else
  45442. X#define S1 '-'
  45443. X#define S2 "+" /* ll corner */
  45444. X#define S3 "+" /* lr corner */
  45445. X#define S4 "|"
  45446. X#define S5 "+" /* ul corner */
  45447. X#define S6 "+" /* ur corner */
  45448. X#endif
  45449. X      memset(buf,S1,80); buf[boxwidth-2] = 0;
  45450. X      textcbase = boxcol + 1;
  45451. X      putstring(extrarow,0,C_PROMPT_BKGRD,buf);
  45452. X      putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,buf);
  45453. X      --textcbase;
  45454. X      putstring(extrarow,0,C_PROMPT_BKGRD,S5);
  45455. X      putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S2);
  45456. X      textcbase += boxwidth - 1;
  45457. X      putstring(extrarow,0,C_PROMPT_BKGRD,S6);
  45458. X      putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S3);
  45459. X      textcbase = boxcol;
  45460. X      for (i = 1; i < extralines-1; ++i) {
  45461. X         putstring(extrarow+i,0,C_PROMPT_BKGRD,S4);
  45462. X         putstring(extrarow+i,boxwidth-1,C_PROMPT_BKGRD,S4);
  45463. X     }
  45464. X      textcbase += (boxwidth - extrawidth) / 2;
  45465. X      putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo);
  45466. X      }
  45467. X   textcbase = 0;
  45468. X
  45469. X   /* display empty box */
  45470. X   for (i = 0; i < boxlines; ++i)
  45471. X      setattr(boxrow+i,boxcol,C_PROMPT_LO,boxwidth);
  45472. X
  45473. X   /* display initial values */
  45474. X   for (i = 0; i < numprompts; i++) {
  45475. X      putstring(promptrow+i, promptcol, C_PROMPT_LO, prompts[i]);
  45476. X      prompt_valuestring(buf,&values[i]);
  45477. X      putstring(promptrow+i, valuecol, C_PROMPT_LO, buf);
  45478. X      }
  45479. X
  45480. X   if (!anyinput) {
  45481. X      putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
  45482. X        (helpmode > 0) ? instr0b : instr0a);
  45483. X      movecursor(25,80);
  45484. X      while (1) {
  45485. X        while (!keypressed()) { }
  45486. X        done = getakey();
  45487. X        switch(done) {
  45488. X           case ESC:
  45489. X              done = -1;
  45490. X           case ENTER:
  45491. X           case ENTER_2:
  45492. X              goto fullscreen_exit;
  45493. X           case F2:
  45494. X           case F3:
  45495. X           case F4:
  45496. X           case F5:
  45497. X           case F6:
  45498. X           case F7:
  45499. X           case F8:
  45500. X           case F9:
  45501. X           case F10:
  45502. X              if (promptfkeys & (1<<(done+1-F1)) )
  45503. X                 goto fullscreen_exit;
  45504. X           }
  45505. X        }
  45506. X      }
  45507. X
  45508. X
  45509. X   /* display footing */
  45510. X   if (numprompts > 1)
  45511. X      putstringcenter(instrrow++,0,80,C_PROMPT_BKGRD,instr1);
  45512. X   putstringcenter(instrrow+1,0,80,C_PROMPT_BKGRD,
  45513. X     (helpmode > 0) ? instr3b : instr3a);
  45514. X
  45515. X   curchoice = done = 0;
  45516. X   while (values[curchoice].type == '*') ++curchoice;
  45517. X
  45518. X   while (!done) {
  45519. X
  45520. X      curtype = values[curchoice].type;
  45521. X      curlen = prompt_valuestring(buf,&values[curchoice]);
  45522. X      putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
  45523. X              (curtype == 'l') ? instr2b : instr2a);
  45524. X      putstring(promptrow+curchoice,promptcol,C_PROMPT_HI,prompts[curchoice]);
  45525. X
  45526. X      if (curtype == 'l') {
  45527. X     i = input_field_list(
  45528. X        C_PROMPT_CHOOSE, buf, curlen,
  45529. X        values[curchoice].uval.ch.list, values[curchoice].uval.ch.llen,
  45530. X        promptrow+curchoice,valuecol, prompt_checkkey);
  45531. X     for (j = 0; j < values[curchoice].uval.ch.llen; ++j)
  45532. X        if (strcmp(buf,values[curchoice].uval.ch.list[j]) == 0) break;
  45533. X     values[curchoice].uval.ch.val = j;
  45534. X     }
  45535. X      else {
  45536. X     j = 0;
  45537. X     if (curtype == 'i') j = 3;
  45538. X     if (curtype == 'd') j = 5;
  45539. X     if (curtype == 'D') j = 7;
  45540. X     if (curtype == 'f') j = 1;
  45541. X     i = input_field(j, C_PROMPT_INPUT, buf, curlen,
  45542. X        promptrow+curchoice,valuecol,prompt_checkkey);
  45543. X     switch (values[curchoice].type) {
  45544. X        case 'd':
  45545. X        case 'D':
  45546. X           values[curchoice].uval.dval = atof(buf);
  45547. X           break;
  45548. X        case 'f':
  45549. X           values[curchoice].uval.dval = atof(buf);
  45550. X           roundfloatd(&values[curchoice].uval.dval);
  45551. X           break;
  45552. X        case 'i':
  45553. X           values[curchoice].uval.ival = atoi(buf);
  45554. X           break;
  45555. X        case 's':
  45556. X           strncpy(values[curchoice].uval.sval,buf,16);
  45557. X           break;
  45558. X        default: /* assume 0x100+n */
  45559. X           strcpy(values[curchoice].uval.sbuf,buf);
  45560. X        }
  45561. X     }
  45562. X
  45563. X      putstring(promptrow+curchoice,promptcol,C_PROMPT_LO,prompts[curchoice]);
  45564. X      j = strlen(buf);
  45565. X      memset(&buf[j],' ',80-j); buf[curlen] = 0;
  45566. X      putstring(promptrow+curchoice, valuecol, C_PROMPT_LO,  buf);
  45567. X
  45568. X      switch(i) {
  45569. X     case 0:  /* enter  */
  45570. X        done = 13;
  45571. X        break;
  45572. X     case -1: /* escape */
  45573. X     case F2:
  45574. X     case F3:
  45575. X     case F4:
  45576. X     case F5:
  45577. X     case F6:
  45578. X     case F7:
  45579. X     case F8:
  45580. X     case F9:
  45581. X     case F10:
  45582. X        done = i;
  45583. X        break;
  45584. X     case PAGE_UP:
  45585. X        curchoice = -1;
  45586. X     case DOWN_ARROW:
  45587. X     case DOWN_ARROW_2:
  45588. X        do {
  45589. X           if (++curchoice >= numprompts) curchoice = 0;
  45590. X           } while (values[curchoice].type == '*');
  45591. X        break;
  45592. X     case PAGE_DOWN:
  45593. X        curchoice = numprompts;
  45594. X     case UP_ARROW:
  45595. X     case UP_ARROW_2:
  45596. X        do {
  45597. X           if (--curchoice < 0) curchoice = numprompts - 1;
  45598. X           } while (values[curchoice].type == '*');
  45599. X        break;
  45600. X     }
  45601. X      }
  45602. X
  45603. Xfullscreen_exit:
  45604. X   movecursor(25,80);
  45605. X   lookatmouse = savelookatmouse;
  45606. X   EXIT_OVLY;
  45607. X   return(done);
  45608. X}
  45609. X
  45610. Xstatic int prompt_valuestring(char *buf,struct fullscreenvalues *val)
  45611. X{  /* format value into buf, return field width */
  45612. X   int i,ret;
  45613. X   switch (val->type) {
  45614. X      case 'd':
  45615. X     ret = 20;
  45616. X     i = 16;    /* cellular needs 16 (was 15)*/
  45617. X     while (1) {
  45618. X        sprintf(buf,"%.*g",i,val->uval.dval);
  45619. X        if (strlen(buf) <= ret) break;
  45620. X        --i;
  45621. X        }
  45622. X     break;
  45623. X      case 'D':
  45624. X     if (val->uval.dval<0) { /* We have to round the right way */
  45625. X         sprintf(buf,"%ld",(long)(val->uval.dval-.5));
  45626. X     }
  45627. X     else {
  45628. X         sprintf(buf,"%ld",(long)(val->uval.dval+.5));
  45629. X     }
  45630. X     ret = 20;
  45631. X     break;
  45632. X      case 'f':
  45633. X     sprintf(buf,"%.7g",val->uval.dval);
  45634. X     ret = 14;
  45635. X     break;
  45636. X      case 'i':
  45637. X     sprintf(buf,"%d",val->uval.ival);
  45638. X     ret = 6;
  45639. X     break;
  45640. X      case '*':
  45641. X     *buf = ret = 0;
  45642. X     break;
  45643. X      case 's':
  45644. X     strncpy(buf,val->uval.sval,16);
  45645. X     buf[15] = 0;
  45646. X     ret = 15;
  45647. X     break;
  45648. X      case 'l':
  45649. X     strcpy(buf,val->uval.ch.list[val->uval.ch.val]);
  45650. X     ret = val->uval.ch.vlen;
  45651. X     break;
  45652. X      default: /* assume 0x100+n */
  45653. X     strcpy(buf,val->uval.sbuf);
  45654. X     ret = val->type & 0xff;
  45655. X      }
  45656. X   return ret;
  45657. X}
  45658. X
  45659. Xint prompt_checkkey(int curkey)
  45660. X{
  45661. X   switch(curkey) {
  45662. X      case PAGE_UP:
  45663. X      case DOWN_ARROW:
  45664. X      case DOWN_ARROW_2:
  45665. X      case PAGE_DOWN:
  45666. X      case UP_ARROW:
  45667. X      case UP_ARROW_2:
  45668. X     return(curkey);
  45669. X      case F2:
  45670. X      case F3:
  45671. X      case F4:
  45672. X      case F5:
  45673. X      case F6:
  45674. X      case F7:
  45675. X      case F8:
  45676. X      case F9:
  45677. X      case F10:
  45678. X     if (promptfkeys & (1<<(curkey+1-F1)) )
  45679. X        return(curkey);
  45680. X      }
  45681. X   return(0);
  45682. X}
  45683. X
  45684. Xstatic int input_field_list(
  45685. X    int attr,          /* display attribute */
  45686. X    char *fld,          /* display form field value */
  45687. X    int vlen,          /* field length */
  45688. X    char **list,          /* list of values */
  45689. X    int llen,          /* number of entries in list */
  45690. X    int row,          /* display row */
  45691. X    int col,          /* display column */
  45692. X    int (*checkkey)(int)  /* routine to check non data keys, or NULL */
  45693. X    )
  45694. X{
  45695. X   int initval,curval;
  45696. X   char buf[81];
  45697. X   int curkey;
  45698. X   int i, j;
  45699. X   int ret,savelookatmouse;
  45700. X   savelookatmouse = lookatmouse;
  45701. X   lookatmouse = 0;
  45702. X   for (initval = 0; initval < llen; ++initval)
  45703. X      if (strcmp(fld,list[initval]) == 0) break;
  45704. X   if (initval >= llen) initval = 0;
  45705. X   curval = initval;
  45706. X   ret = -1;
  45707. X   while (1) {
  45708. X      strcpy(buf,list[curval]);
  45709. X      i = strlen(buf);
  45710. X      while (i < vlen)
  45711. X     buf[i++] = ' ';
  45712. X      buf[vlen] = 0;
  45713. X      putstring(row,col,attr,buf);
  45714. X      curkey = keycursor(row,col); /* get a keystroke */
  45715. X      switch (curkey) {
  45716. X     case ENTER:
  45717. X     case ENTER_2:
  45718. X        ret = 0;
  45719. X        goto inpfldl_end;
  45720. X     case ESC:
  45721. X        goto inpfldl_end;
  45722. X     case RIGHT_ARROW:
  45723. X     case RIGHT_ARROW_2:
  45724. X        if (++curval >= llen)
  45725. X           curval = 0;
  45726. X        break;
  45727. X     case LEFT_ARROW:
  45728. X     case LEFT_ARROW_2:
  45729. X        if (--curval < 0)
  45730. X           curval = llen - 1;
  45731. X        break;
  45732. X     case F5:
  45733. X        curval = initval;
  45734. X        break;
  45735. X     default:
  45736. X            if (nonalpha(curkey)) {
  45737. X           if (checkkey && (ret = (*checkkey)(curkey)))
  45738. X          goto inpfldl_end;
  45739. X           break;                     /* non alphanum char */
  45740. X           }
  45741. X        j = curval;
  45742. X        for (i = 0; i < llen; ++i) {
  45743. X           if (++j >= llen)
  45744. X          j = 0;
  45745. X           if ((*list[j] & 0xdf) == (curkey & 0xdf)) {
  45746. X          curval = j;
  45747. X          break;
  45748. X          }
  45749. X           }
  45750. X     }
  45751. X      }
  45752. Xinpfldl_end:
  45753. X   strcpy(fld,list[curval]);
  45754. X   lookatmouse = savelookatmouse;
  45755. X   return(ret);
  45756. X}
  45757. X
  45758. X
  45759. X/* --------------------------------------------------------------------- */
  45760. X
  45761. X/* MCP 7-7-91, This is static code, but not called anywhere */
  45762. X#ifdef DELETE_UNUSED_CODE
  45763. X
  45764. X/* compare for sort of type table */
  45765. Xstatic int compare(const VOIDPTR i, const VOIDPTR j)
  45766. X{
  45767. X   return(strcmp(fractalspecific[(int)*((BYTE*)i)].name,
  45768. X           fractalspecific[(int)*((BYTE*)j)].name));
  45769. X}
  45770. X
  45771. X/* --------------------------------------------------------------------- */
  45772. X
  45773. Xstatic void clear_line(int row, int start, int stop, int color) /* clear part of a line */
  45774. X{
  45775. X   int col;
  45776. X   for(col=start;col<= stop;col++)
  45777. X      putstring(row,col,color," ");
  45778. X}
  45779. X
  45780. X#endif
  45781. X
  45782. X/* --------------------------------------------------------------------- */
  45783. X
  45784. Xint get_fracttype()        /* prompt for and select fractal type */
  45785. X{
  45786. X   int done,i,oldfractype,t;
  45787. X   ENTER_OVLY(OVLY_PROMPTS1);
  45788. X   done = -1;
  45789. X   oldfractype = fractype;
  45790. X   while (1) {
  45791. X      if ((t = select_fracttype(fractype)) < 0)
  45792. X     break;
  45793. X      if ((i = select_type_params(t, fractype)) == 0) { /* ok, all done */
  45794. X     done = 0;
  45795. X     break;
  45796. X     }
  45797. X      if (i > 0) /* can't return to prior image anymore */
  45798. X     done = 1;
  45799. X      }
  45800. X   if (done < 0)
  45801. X      fractype = oldfractype;
  45802. X   curfractalspecific = &fractalspecific[fractype];
  45803. X   EXIT_OVLY;
  45804. X   return(done);
  45805. X}
  45806. X
  45807. Xstruct FT_CHOICE {
  45808. X      char name[15];
  45809. X      int  num;
  45810. X      };
  45811. Xstatic struct FT_CHOICE **ft_choices; /* for sel_fractype_help subrtn */
  45812. X
  45813. Xstatic int select_fracttype(int t) /* subrtn of get_fracttype, separated */
  45814. X                   /* so that storage gets freed up     */
  45815. X{
  45816. X   static char far head1[] = {"Select a Fractal Type"};
  45817. X   static char far head2[] = {"Select Orbit Algorithm for Julibrot"};
  45818. X   static char far instr[] = {"Press F2 for a description of the highlighted type"};
  45819. X   char head[40];
  45820. X   int oldhelpmode;
  45821. X   int numtypes, done;
  45822. X   int i, j;
  45823. X#define MAXFTYPES 200
  45824. X   char tname[40];
  45825. X   struct FT_CHOICE *choices[MAXFTYPES];
  45826. X   int attributes[MAXFTYPES];
  45827. X
  45828. X   /* steal existing array for "choices" */
  45829. X   choices[0] = (struct FT_CHOICE *)boxy;
  45830. X   attributes[0] = 1;
  45831. X   for (i = 1; i < MAXFTYPES; ++i) {
  45832. X      choices[i] = choices[i-1] + 1;
  45833. X      attributes[i] = 1;
  45834. X      }
  45835. X   ft_choices = &choices[0];
  45836. X
  45837. X   /* setup context sensitive help */
  45838. X   oldhelpmode = helpmode;
  45839. X   helpmode = HELPFRACTALS;
  45840. X
  45841. X   if(julibrot)
  45842. X      far_strcpy(head,head2);
  45843. X   else
  45844. X      far_strcpy(head,head1);    
  45845. X   if (t == IFS3D) t = IFS;
  45846. X   i = j = -1;
  45847. X   while(fractalspecific[++i].name) {
  45848. X      if(julibrot)
  45849. X      {
  45850. X        int isinteger;
  45851. X        isinteger = curfractalspecific->isinteger; 
  45852. X    if (!((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*'))
  45853. X       continue;
  45854. X      }
  45855. X      if (fractalspecific[i].name[0] == '*')
  45856. X     continue;
  45857. X      strcpy(choices[++j]->name,fractalspecific[i].name);
  45858. X      choices[j]->name[14] = 0; /* safety */
  45859. X      choices[j]->num = i;    /* remember where the real item is */
  45860. X      }
  45861. X   numtypes = j + 1;
  45862. X   qsort(choices,numtypes,sizeof(char *),lccompare); /* sort list */
  45863. X   j = 0;
  45864. X   for (i = 0; i < numtypes; ++i) /* find starting choice in sorted list */
  45865. X      if (choices[i]->num == t || choices[i]->num == fractalspecific[t].tofloat)
  45866. X     j = i;
  45867. X
  45868. X   tname[0] = 0;
  45869. X   done = fullscreen_choice(CHOICEHELP+8,head,NULL,instr,numtypes,
  45870. X         (char **)choices,attributes,0,0,0,j,NULL,tname,NULL,sel_fractype_help);
  45871. X   if (done >= 0)
  45872. X      done = choices[done]->num;
  45873. X   helpmode = oldhelpmode;
  45874. X   return(done);
  45875. X}
  45876. X
  45877. Xstatic int sel_fractype_help(int curkey,int choice)
  45878. X{
  45879. X   int oldhelpmode;
  45880. X   if (curkey == F2) {
  45881. X      oldhelpmode = helpmode;
  45882. X      helpmode = fractalspecific[(*(ft_choices+choice))->num].helptext;
  45883. X      help(0);
  45884. X      helpmode = oldhelpmode;
  45885. X      }
  45886. X   return(0);
  45887. X}
  45888. X
  45889. Xint select_type_params(    /* prompt for new fractal type parameters */
  45890. X    int newfractype,    /* new fractal type */
  45891. X    int oldfractype     /* previous fractal type */
  45892. X    )
  45893. X{
  45894. X   int ret,oldhelpmode;
  45895. X
  45896. X   oldhelpmode = helpmode;
  45897. X   ret = 0;
  45898. X   fractype = newfractype;
  45899. X   curfractalspecific = &fractalspecific[fractype];
  45900. X
  45901. X   if (fractype == LSYSTEM) {
  45902. X      helpmode = HT_LSYS;
  45903. X      if (get_file_entry(GETLSYS,"L-System",lsysmask,LFileName,LName) < 0) {
  45904. X     ret = 1;
  45905. X     goto sel_type_exit;
  45906. X     }
  45907. X      }
  45908. X   if (fractype == FORMULA || fractype == FFORMULA) {
  45909. X      helpmode = HT_FORMULA;
  45910. X      if (get_file_entry(GETFORMULA,"Formula",formmask,FormFileName,FormName) < 0) {
  45911. X     ret = 1;
  45912. X     goto sel_type_exit;
  45913. X     }
  45914. X      }
  45915. X   if (fractype == IFS || fractype == IFS3D) {
  45916. X      static char far ifsmsg[] = {
  45917. X#ifndef XFRACT
  45918. X         "Current IFS parameters have been edited but not saved.\n"
  45919. X         "Continue to replace them with new selection, cancel to keep them."};
  45920. X#else
  45921. X         "Current IFS parameters have been edited but not saved.\n\
  45922. XContinue to replace them with new selection, cancel to keep them."};
  45923. X#endif
  45924. X      helpmode = HT_IFS;
  45925. X      if (!ifs_defn || !ifs_changed || !stopmsg(22,ifsmsg))
  45926. X     if (get_file_entry(GETIFS,"IFS",ifsmask,IFSFileName,IFSName) < 0) {
  45927. X        ret = 1;
  45928. X        goto sel_type_exit;
  45929. X        }
  45930. X      }
  45931. X
  45932. X/* Added the following to accommodate fn bifurcations.  JCO 7/2/92 */
  45933. X   if(((fractype == BIFURCATION) || (fractype == LBIFURCATION)) &&
  45934. X     !((oldfractype == BIFURCATION) || (oldfractype == LBIFURCATION)))
  45935. X        set_trig_array(0,"ident");
  45936. X   if(((fractype == BIFSTEWART) || (fractype == LBIFSTEWART)) &&
  45937. X     !((oldfractype == BIFSTEWART) || (oldfractype == LBIFSTEWART)))
  45938. X        set_trig_array(0,"ident");
  45939. X   if(((fractype == BIFLAMBDA) || (fractype == LBIFLAMBDA)) &&
  45940. X     !((oldfractype == BIFLAMBDA) || (oldfractype == LBIFLAMBDA)))
  45941. X        set_trig_array(0,"ident");
  45942. X   if(((fractype == BIFEQSINPI) || (fractype == LBIFEQSINPI)) &&
  45943. X     !((oldfractype == BIFEQSINPI) || (oldfractype == LBIFEQSINPI)))
  45944. X        set_trig_array(0,"sin");
  45945. X   if(((fractype == BIFADSINPI) || (fractype == LBIFADSINPI)) &&
  45946. X     !((oldfractype == BIFADSINPI) || (oldfractype == LBIFADSINPI)))
  45947. X        set_trig_array(0,"sin");
  45948. X
  45949. X   set_default_parms();
  45950. X
  45951. X   if (get_fract_params(0) < 0)
  45952. X      ret = 1;
  45953. X   else {
  45954. X      if (newfractype != oldfractype) {
  45955. X     invert = 0;
  45956. X     inversion[0] = inversion[1] = inversion[2] = 0;
  45957. X     }
  45958. X      }
  45959. X
  45960. Xsel_type_exit:
  45961. X   helpmode = oldhelpmode;
  45962. X   return(ret);
  45963. X
  45964. X}
  45965. X
  45966. Xstatic void set_default_parms()
  45967. X{
  45968. X   int i;
  45969. X   xxmin = curfractalspecific->xmin;
  45970. X   xxmax = curfractalspecific->xmax;
  45971. X   yymin = curfractalspecific->ymin;
  45972. X   yymax = curfractalspecific->ymax;
  45973. X   xx3rd = xxmin;
  45974. X   yy3rd = yymin;
  45975. X   if (viewcrop && finalaspectratio != screenaspect)
  45976. X      aspectratio_crop(screenaspect,finalaspectratio);
  45977. X   for (i = 0; i < 4; i++) {
  45978. X      param[i] = curfractalspecific->paramvalue[i];
  45979. X      if (fractype != CELLULAR) /* don't round cellular */
  45980. X         roundfloatd(¶m[i]);
  45981. X   }
  45982. X   if(curfractalspecific->flags&MORE) {
  45983. X      int extra;
  45984. X      if((extra=find_extra_param(fractype)) > -1)
  45985. X         for(i=0;i<MAXPARAMS-4;i++) {
  45986. X            param[i+4] = moreparams[extra].paramvalue[i];
  45987. X         }
  45988. X   }
  45989. X}
  45990. X
  45991. X#define MAXFRACTALS 25 
  45992. Xextern int neworbittype, num_fractal_types;
  45993. X
  45994. Xint build_fractal_list(int fractals[], int *last_val, char *nameptr[])
  45995. X{
  45996. X    int numfractals,i;
  45997. X
  45998. X    numfractals = 0;
  45999. X    for (i = 0; i < num_fractal_types; i++)
  46000. X    {
  46001. X        int isinteger;
  46002. X        isinteger = curfractalspecific->isinteger; 
  46003. X    if ((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*')
  46004. X    {
  46005. X        fractals[numfractals] = i;
  46006. X        if (i == neworbittype || i == fractalspecific[neworbittype].tofloat)
  46007. X        *last_val = numfractals;
  46008. X        nameptr[numfractals] = fractalspecific[i].name;
  46009. X        numfractals++;
  46010. X        if (numfractals >= MAXFRACTALS)
  46011. X        break;
  46012. X    }
  46013. X    }
  46014. X    return (numfractals);
  46015. X}
  46016. Xchar far v00[] = {"Orbit Algorithm"};
  46017. Xchar far v0a[] = {"From cx (real part)"};
  46018. Xchar far v1a[] = {"From cy (imaginary part)"};
  46019. Xchar far v2a[] = {"To   cx (real part)"};
  46020. Xchar far v3a[] = {"To   cy (imaginary part)"};
  46021. X
  46022. X/* 4D Mandelbrot */
  46023. Xchar far v0b[] = {"From cj (3rd dim)"};
  46024. Xchar far v1b[] = {"From ck (4th dim)"};
  46025. Xchar far v2b[] = {"To   cj (3rd dim)"};
  46026. Xchar far v3b[] = {"To   ck (4th dim)"};
  46027. X
  46028. X/* 4D Julia */
  46029. Xchar far v0c[] = {"From zj (3rd dim)"};
  46030. Xchar far v1c[] = {"From zk (4th dim)"};
  46031. Xchar far v2c[] = {"To   zj (3rd dim)"};
  46032. Xchar far v3c[] = {"To   zk (4th dim)"};
  46033. X
  46034. Xchar far v4[] = {"Number of z pixels"};
  46035. Xchar far v5[] = {"Location of z origin"};
  46036. Xchar far v6[] = {"Depth of z"};
  46037. Xchar far v7[] = {"Screen height"};
  46038. Xchar far v8[] = {"Screen width"};
  46039. Xchar far v9[] = {"Distance to Screen"};
  46040. Xchar far v10[] = {"Distance between eyes"};
  46041. Xchar far v11[] = {"3D Mode"};
  46042. Xchar *juli3Doptions[] = {"monocular","lefteye","righteye","red-blue"};
  46043. X
  46044. X/* --------------------------------------------------------------------- */
  46045. Xint get_fract_params(int caller)    /* prompt for type-specific parms */
  46046. X{
  46047. X   char far *v0 = v0a;
  46048. X   char far *v1 = v1a;
  46049. X   char far *v2 = v2a;
  46050. X   char far *v3 = v3a;
  46051. X   char far *juliorbitname = NULL;
  46052. X   extern double mxmaxfp, mxminfp, mymaxfp, myminfp, originfp;
  46053. X   extern double depthfp, heightfp, widthfp, distfp, eyesfp;
  46054. X   extern int zdots; 
  46055. X   char *nameptr[MAXFRACTALS];
  46056. X   int fractals[MAXFRACTALS];
  46057. X   int i,j,k;
  46058. X   int curtype,numparams,numtrig,last_val;
  46059. X   struct fullscreenvalues paramvalues[30];
  46060. X   char far *choices[30];
  46061. X   int oldbailout;
  46062. X   int extra;
  46063. X   int numextra;
  46064. X   int promptnum;
  46065. X   char msg[120];
  46066. X   char *typename, *tmpptr;
  46067. X   char bailoutmsg[50];
  46068. X   int ret = 0;
  46069. X   int oldhelpmode;
  46070. X   static char far t11[] = {"Function (if needed by orbit formula)"};
  46071. X   static char far t1[] = {"First Function"};
  46072. X   static char far t2[] = {"Second Function"};
  46073. X   static char far t3[] = {"Third Function"};
  46074. X   static char far t4[] = {"Fourth Function"};
  46075. X   static char far *trg[] = {t1, t2, t3, t4};
  46076. X   extern char tstack[4096];
  46077. X   char *filename,*entryname;
  46078. X   FILE *entryfile;
  46079. X   char *trignameptr[25];
  46080. X   extern int  juli3Dmode;
  46081. X   struct fractalspecificstuff far *jborbit;
  46082. X   struct fractalspecificstuff far *savespecific;
  46083. X   int firstparm;
  46084. X   double oldparam[MAXPARAMS];
  46085. X   ENTER_OVLY(OVLY_PROMPTS1);
  46086. X   firstparm = 0;
  46087. X   if(fractype==JULIBROT || fractype==JULIBROTFP)
  46088. X      julibrot = 1;
  46089. X   else
  46090. X      julibrot = 0;
  46091. X   curtype = fractype;
  46092. X   if (curfractalspecific->name[0] == '*'
  46093. X     && (i = fractalspecific->tofloat) != NOFRACTAL
  46094. X     && fractalspecific[i].name[0] != '*')
  46095. X      curtype = i;
  46096. X   curfractalspecific = &fractalspecific[curtype];
  46097. X#if 0
  46098. X   if (curtype == IFS || curtype == IFS3D) {
  46099. X      ret = ((caller) ? edit_ifs_params() : 0);
  46100. X      goto gfp_exit;
  46101. X      }
  46102. X#endif
  46103. X   tstack[0] = 0;
  46104. X   if ((i = curfractalspecific->helpformula) < -1) {
  46105. X      if (i == -2) { /* special for formula */
  46106. X     filename = FormFileName;
  46107. X     entryname = FormName;
  46108. X     }
  46109. X      else {     /* -3, special for lsystem */
  46110. X     filename = LFileName;
  46111. X     entryname = LName;
  46112. X     }
  46113. X      if (find_file_item(filename,entryname,&entryfile) == 0) {
  46114. X     load_entry_text(entryfile,tstack,16);
  46115. X     fclose(entryfile);
  46116. X     }
  46117. X      }
  46118. X   else if (i >= 0) {
  46119. X      int c,lines;
  46120. X      if (i = read_help_topic(i,0,2000,tstack) > 0) i = 0;
  46121. X      tstack[2000-i] = 0;
  46122. X      i = j = lines = 0; k = 1;
  46123. X      while ((c = tstack[i++])) {
  46124. X     /* stop at ctl, blank, or line with col 1 nonblank, max 16 lines */
  46125. X     if (k && c == ' ' && ++k <= 5) { } /* skip 4 blanks at start of line */
  46126. X     else {
  46127. X        if (c == '\n') {
  46128. X           if (k) break; /* blank line */
  46129. X           if (++lines >= 16) break;
  46130. X           k = 1;
  46131. X           }
  46132. X        else if (c < 16) /* a special help format control char */
  46133. X           break;
  46134. X        else {
  46135. X           if (k == 1) /* line starts in column 1 */
  46136. X          break;
  46137. X           k = 0;
  46138. X           }
  46139. X        tstack[j++] = c;
  46140. X        }
  46141. X     }
  46142. X      while (--j >= 0 && tstack[j] == '\n') { }
  46143. X      tstack[j+1] = 0;
  46144. X      }
  46145. Xgfp_top:   
  46146. X   promptnum = 0;
  46147. X   if (julibrot)
  46148. X   {
  46149. X      i = select_fracttype(neworbittype);
  46150. X      if (i < 0) 
  46151. X      {
  46152. X         if (ret == 0)
  46153. X            ret = -1;
  46154. X         julibrot = 0;
  46155. X         goto gfp_exit;
  46156. X      }
  46157. X      else
  46158. X         neworbittype = i;
  46159. X      jborbit = &fractalspecific[neworbittype];
  46160. X      juliorbitname = jborbit->name;
  46161. X   }
  46162. X   promptnum = 0;
  46163. X
  46164. X   if(julibrot)
  46165. X   {
  46166. X      savespecific = curfractalspecific;
  46167. X      curfractalspecific = jborbit;
  46168. X      firstparm = 2; /* in most case Julibrot does not need first two parms */
  46169. X      if(neworbittype == QUATJULFP     ||   /* all parameters needed */ 
  46170. X         neworbittype == HYPERCMPLXJFP)
  46171. X         firstparm = 0; 
  46172. X      if(neworbittype == QUATFP        ||   /* no parameters needed */
  46173. X         neworbittype == HYPERCMPLXFP)
  46174. X         firstparm = 4; 
  46175. X   }   
  46176. X   numparams = 0;
  46177. X   
  46178. X   for (i = firstparm; i < 4; i++) 
  46179. X   {
  46180. X      char tmpbuf[30];
  46181. X      if (curfractalspecific->param[i][0] == 0) 
  46182. X         break;
  46183. X      numparams++;
  46184. X      choices[promptnum] = curfractalspecific->param[i];
  46185. X      paramvalues[promptnum].type = 'd';
  46186. X   
  46187. X      if (choices[promptnum][0] == '+') 
  46188. X      {
  46189. X         choices[promptnum]++;
  46190. X         paramvalues[promptnum].type = 'D';
  46191. X      }
  46192. X      sprintf(tmpbuf,"%.17g",param[i]);
  46193. X      paramvalues[promptnum].uval.dval = atof(tmpbuf);
  46194. X      oldparam[i] = paramvalues[promptnum++].uval.dval;
  46195. X   }
  46196. X   numextra = 0;
  46197. X   if(curfractalspecific->flags&MORE && !julibrot)
  46198. X   {
  46199. X      if((extra=find_extra_param(fractype))<-1)
  46200. X      {
  46201. X         char msg[30];
  46202. X         sprintf(msg,"find_extra_param error");
  46203. X         stopmsg(0,msg);
  46204. X      }
  46205. X      else
  46206. X      for (i=0;i<MAXPARAMS-4;i++) 
  46207. X      {
  46208. X         char tmpbuf[30];
  46209. X         if (moreparams[extra].param[i][0] == 0) 
  46210. X            break;
  46211. X         numextra++;
  46212. X         choices[promptnum] = moreparams[extra].param[i];
  46213. X         paramvalues[promptnum].type = 'd';
  46214. X         if (choices[promptnum][0] == '+') 
  46215. X         {
  46216. X            choices[promptnum]++;
  46217. X            paramvalues[promptnum].type = 'D';
  46218. X         }
  46219. X         sprintf(tmpbuf,"%.17g",param[i+4]);
  46220. X         paramvalues[promptnum].uval.dval = atof(tmpbuf);
  46221. X         oldparam[i+4] = paramvalues[promptnum++].uval.dval;
  46222. X      }
  46223. X   }
  46224. X   numtrig = (curfractalspecific->flags >> 6) & 7;
  46225. X   if(curtype==FORMULA || curtype==FFORMULA ) {
  46226. X      extern char maxfn;
  46227. X      numtrig = maxfn;
  46228. X      }
  46229. X
  46230. X   if ((i = numtrigfn) > 27) i = 27;
  46231. X   while (--i >= 0)
  46232. X      trignameptr[i] = trigfn[i].name;
  46233. X   for (i = 0; i < numtrig; i++) {
  46234. X      paramvalues[promptnum].type = 'l';
  46235. X      paramvalues[promptnum].uval.ch.val  = trigndx[i];
  46236. X      paramvalues[promptnum].uval.ch.llen = numtrigfn;
  46237. X      paramvalues[promptnum].uval.ch.vlen = 6;
  46238. X      paramvalues[promptnum].uval.ch.list = trignameptr;
  46239. X      choices[promptnum++] = trg[i];
  46240. X      }
  46241. X   if (*(typename = curfractalspecific->name) == '*')
  46242. X        ++typename;
  46243. X
  46244. X   if (curfractalspecific->orbit_bailout)
  46245. X      if (potparam[0] != 0.0 && potparam[2] != 0.0) 
  46246. X      {
  46247. X     paramvalues[promptnum].type = '*';
  46248. X     choices[promptnum++] = "Bailout: continuous potential (Y screen) value in use";
  46249. X      }
  46250. X      else 
  46251. X      {
  46252. X         static char far bailoutstr[] = {"Bailout value (0 means use default)"};
  46253. X     choices[promptnum] = bailoutstr;
  46254. X     paramvalues[promptnum].type = 'i';
  46255. X     paramvalues[promptnum++].uval.ival = oldbailout = bailout;
  46256. X     paramvalues[promptnum].type = '*';
  46257. X     i = curfractalspecific->orbit_bailout;
  46258. X     tmpptr = typename;
  46259. X     if (usr_biomorph != -1) 
  46260. X     {
  46261. X        i = 100;
  46262. X        tmpptr = "biomorph";
  46263. X     }
  46264. X     sprintf(bailoutmsg,"    (%s default is %d)",tmpptr,i);
  46265. X     choices[promptnum++] = bailoutmsg;
  46266. X      }
  46267. X   if (julibrot)
  46268. X   {
  46269. X      switch(neworbittype)
  46270. X      {
  46271. X      case QUATFP:
  46272. X      case HYPERCMPLXFP:
  46273. X          v0 = v0b; v1 = v1b; v2 = v2b; v3 = v3b;
  46274. X          break;
  46275. X      case QUATJULFP:
  46276. X      case HYPERCMPLXJFP:
  46277. X          v0 = v0c; v1 = v1c; v2 = v2c; v3 = v3c;
  46278. X          break;
  46279. X      default:
  46280. X          v0 = v0a; v1 = v1a; v2 = v2a; v3 = v3a;
  46281. X         break;
  46282. X      }
  46283. X
  46284. X      curfractalspecific = savespecific;
  46285. X      paramvalues[promptnum].uval.dval = mxmaxfp;
  46286. X      paramvalues[promptnum].type = 'f';
  46287. X      choices[promptnum++] = v0;
  46288. X      paramvalues[promptnum].uval.dval = mymaxfp;
  46289. X      paramvalues[promptnum].type = 'f';
  46290. X      choices[promptnum++] = v1;
  46291. X      paramvalues[promptnum].uval.dval = mxminfp;
  46292. X      paramvalues[promptnum].type = 'f';
  46293. X      choices[promptnum++] = v2;
  46294. X      paramvalues[promptnum].uval.dval = myminfp;
  46295. X      paramvalues[promptnum].type = 'f';
  46296. X      choices[promptnum++] = v3;
  46297. X      paramvalues[promptnum].uval.ival = zdots;
  46298. X      paramvalues[promptnum].type = 'i';
  46299. X      choices[promptnum++] = v4;
  46300. X
  46301. X      paramvalues[promptnum].type = 'l';
  46302. X      paramvalues[promptnum].uval.ch.val  = juli3Dmode;
  46303. X      paramvalues[promptnum].uval.ch.llen = 4;
  46304. X      paramvalues[promptnum].uval.ch.vlen = 9;
  46305. X      paramvalues[promptnum].uval.ch.list = juli3Doptions;
  46306. X      choices[promptnum++] = v11;
  46307. X
  46308. X      paramvalues[promptnum].uval.dval = eyesfp;
  46309. X      paramvalues[promptnum].type = 'f';
  46310. X      choices[promptnum++] = v10;
  46311. X      paramvalues[promptnum].uval.dval = originfp;
  46312. X      paramvalues[promptnum].type = 'f';
  46313. X      choices[promptnum++] = v5;
  46314. X      paramvalues[promptnum].uval.dval = depthfp;
  46315. X      paramvalues[promptnum].type = 'f';
  46316. X      choices[promptnum++] = v6;
  46317. X      paramvalues[promptnum].uval.dval = heightfp;
  46318. X      paramvalues[promptnum].type = 'f';
  46319. X      choices[promptnum++] = v7;
  46320. X      paramvalues[promptnum].uval.dval = widthfp;
  46321. X      paramvalues[promptnum].type = 'f';
  46322. X      choices[promptnum++] = v8;
  46323. X      paramvalues[promptnum].uval.dval = distfp;
  46324. X      paramvalues[promptnum].type = 'f';
  46325. X      choices[promptnum++] = v9;
  46326. X   }
  46327. X
  46328. X   if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
  46329. X   {
  46330. X      extern int  major_method;
  46331. X      extern int  minor_method;
  46332. X
  46333. X#ifdef RANDOM_RUN
  46334. X      static char far JIIMstr1[] =
  46335. X    "Breadth first, Depth first, Random Walk, Random Run?";
  46336. X      static char *JIIMmethod[] = {"Breadth", "Depth", "Walk", "Run"};
  46337. X#else
  46338. X      static char far JIIMstr1[] =
  46339. X    "Breadth first, Depth first, Random Walk";
  46340. X      static char *JIIMmethod[] = {"Breadth", "Depth", "Walk"};
  46341. X#endif
  46342. X      static char far JIIMstr2[] =
  46343. X    "Left first or Right first?";
  46344. X      static char *JIIMleftright[] = {"Left", "Right"};
  46345. X
  46346. X      choices[promptnum] = JIIMstr1;
  46347. X      paramvalues[promptnum].type = 'l';
  46348. X      paramvalues[promptnum].uval.ch.list = JIIMmethod;
  46349. X      paramvalues[promptnum].uval.ch.vlen = 7;
  46350. X#ifdef RANDOM_RUN
  46351. X      paramvalues[promptnum].uval.ch.llen = 4;
  46352. X#else
  46353. X      paramvalues[promptnum].uval.ch.llen = 3; /* disable random run */
  46354. X#endif
  46355. X      paramvalues[promptnum++].uval.ch.val  = major_method;
  46356. X
  46357. X      choices[promptnum] = JIIMstr2;
  46358. X      paramvalues[promptnum].type = 'l';
  46359. X      paramvalues[promptnum].uval.ch.list = JIIMleftright;
  46360. X      paramvalues[promptnum].uval.ch.vlen = 5;
  46361. X      paramvalues[promptnum].uval.ch.llen = 2;
  46362. X      paramvalues[promptnum++].uval.ch.val  = minor_method;
  46363. X   }
  46364. X
  46365. X   if (caller                /* <z> command ? */
  46366. X      && (display3d > 0 || promptnum == 0))
  46367. X      {
  46368. X       static char far msg[]={"Current type has no type-specific parameters"};
  46369. X       stopmsg(20,msg);
  46370. X       goto gfp_exit;
  46371. X       }
  46372. X   if(julibrot)
  46373. X   sprintf(msg,
  46374. X       "Julibrot Parameters (orbit= %s)\n(Press F6 for corner parameters)",
  46375. X       juliorbitname);
  46376. X   else
  46377. X   sprintf(msg,
  46378. X       "Parameters for fractal type %s\n(Press F6 for corner parameters)",
  46379. X       typename);
  46380. X
  46381. X   while (1) 
  46382. X   {
  46383. X      oldhelpmode = helpmode;
  46384. X      helpmode = curfractalspecific->helptext;
  46385. X      i = fullscreen_prompt(msg,promptnum,choices,paramvalues,0,0x40,tstack);
  46386. X      helpmode = oldhelpmode;
  46387. X      if (i < 0) 
  46388. X      {
  46389. X         if(julibrot)
  46390. X           goto gfp_top;
  46391. X     if (ret == 0)
  46392. X        ret = -1;
  46393. X     goto gfp_exit;
  46394. X      }
  46395. X      if (i != F6) 
  46396. X         break;
  46397. X      if (get_corners() > 0)
  46398. X     ret = 1;
  46399. X     }
  46400. X     promptnum = 0;
  46401. X     for ( i = firstparm; i < numparams+firstparm; i++) 
  46402. X     {
  46403. X        if (oldparam[i] != paramvalues[promptnum].uval.dval) 
  46404. X        {
  46405. X           param[i] = paramvalues[promptnum].uval.dval;
  46406. X          ret = 1;
  46407. X        }
  46408. X        ++promptnum;
  46409. X    }
  46410. X     for(i=0;i<numextra;i++)
  46411. X     {
  46412. X        if(oldparam[i+4] != paramvalues[promptnum].uval.dval)
  46413. X        {
  46414. X           param[i+4] = paramvalues[promptnum].uval.dval;
  46415. X           ret = 1;
  46416. X        }
  46417. X        ++promptnum;
  46418. X     }
  46419. X
  46420. X   for ( i = 0; i < numtrig; i++) 
  46421. X   {
  46422. X      if (paramvalues[promptnum].uval.ch.val != trigndx[i]) 
  46423. X      {
  46424. X     set_trig_array(i,trigfn[paramvalues[promptnum].uval.ch.val].name);
  46425. X     ret = 1;
  46426. X      }
  46427. X      ++promptnum;
  46428. X   }
  46429. X
  46430. X   if(julibrot)
  46431. X   {
  46432. X      savespecific = curfractalspecific;
  46433. X      curfractalspecific = jborbit;
  46434. X   }   
  46435. X
  46436. X   if (curfractalspecific->orbit_bailout)
  46437. X      if (potparam[0] != 0.0 && potparam[2] != 0.0) 
  46438. X     promptnum++;
  46439. X      else 
  46440. X      {
  46441. X         bailout = paramvalues[promptnum++].uval.ival;
  46442. X#ifndef XFRACT
  46443. X         if (bailout != 0 && (bailout < 4 || bailout > 32000))
  46444. X#else /* We have big integers, so why not allow big bailouts? */
  46445. X         if (bailout != 0 && (bailout < 4))
  46446. X#endif
  46447. X        bailout = oldbailout;
  46448. X         if (bailout != oldbailout)
  46449. X        ret = 1;
  46450. X     promptnum++;
  46451. X      }
  46452. X
  46453. X     if (julibrot)
  46454. X     {
  46455. X    mxmaxfp    = paramvalues[promptnum++].uval.dval;
  46456. X    mymaxfp    = paramvalues[promptnum++].uval.dval;
  46457. X    mxminfp    = paramvalues[promptnum++].uval.dval;
  46458. X    myminfp    = paramvalues[promptnum++].uval.dval;
  46459. X    zdots      = paramvalues[promptnum++].uval.ival;
  46460. X        juli3Dmode = paramvalues[promptnum++].uval.ch.val;
  46461. X    eyesfp     = paramvalues[promptnum++].uval.dval;
  46462. X    originfp   = paramvalues[promptnum++].uval.dval;
  46463. X    depthfp    = paramvalues[promptnum++].uval.dval;
  46464. X    heightfp   = paramvalues[promptnum++].uval.dval;
  46465. X    widthfp    = paramvalues[promptnum++].uval.dval;
  46466. X    distfp     = paramvalues[promptnum++].uval.dval;
  46467. X        ret = 1;  /* force new calc since not resumable anyway */
  46468. X     }
  46469. X      if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
  46470. X      {
  46471. X     extern int major_method, minor_method;
  46472. X
  46473. X     if (paramvalues[promptnum].uval.ch.val != major_method ||
  46474. X         paramvalues[promptnum+1].uval.ch.val != minor_method)
  46475. X        ret = 1;
  46476. X
  46477. X     major_method = paramvalues[promptnum  ].uval.ch.val;
  46478. X     minor_method = paramvalues[promptnum+1].uval.ch.val;
  46479. X      }
  46480. X
  46481. Xgfp_exit:
  46482. X   curfractalspecific = &fractalspecific[fractype];
  46483. X   EXIT_OVLY;
  46484. X   return(ret);
  46485. X}
  46486. X
  46487. Xint find_extra_param(int type)
  46488. X{
  46489. X   int i,ret,curtyp;
  46490. X   ret = -1;
  46491. X   i= -1;
  46492. X   while((curtyp=moreparams[++i].type) != type && curtyp != -1);
  46493. X   if(curtyp == type)
  46494. X     ret = i;
  46495. X   return(ret);
  46496. X}     
  46497. X
  46498. X
  46499. Xint check_orbit_name(char *orbitname)
  46500. X{
  46501. X   int i, numtypes, bad;
  46502. X   char *nameptr[MAXFRACTALS];
  46503. X   int fractals[MAXFRACTALS];
  46504. X   int curtype,numparams,numtrig,last_val;
  46505. X
  46506. X   ENTER_OVLY(OVLY_PROMPTS1);
  46507. X   numtypes = build_fractal_list(fractals, &last_val, nameptr);
  46508. X   bad = 1;
  46509. X   for(i=0;i<numtypes;i++)
  46510. X   {
  46511. X      if(strcmp(orbitname,nameptr[i]) == 0)
  46512. X      {
  46513. X         neworbittype = fractals[i];
  46514. X         bad = 0;
  46515. X         break;
  46516. X      }
  46517. X   }
  46518. X   EXIT_OVLY;
  46519. X   return(bad);
  46520. X}
  46521. X
  46522. X/* --------------------------------------------------------------------- */
  46523. X
  46524. X   static FILE *gfe_file;
  46525. X
  46526. Xlong get_file_entry(int type,char *title,char *fmask,
  46527. X              char *filename,char *entryname)
  46528. X{
  46529. X   /* Formula, LSystem, etc type structure, select from file */
  46530. X   /* containing definitions in the form    name { ... }     */
  46531. X   int newfile,firsttry;
  46532. X   long entry_pointer;
  46533. X   extern char tstack[4096];
  46534. X   newfile = 0;
  46535. X   while (1) {
  46536. X      firsttry = 0;
  46537. X      /* pb: binary mode used here - it is more work, but much faster, */
  46538. X      /*     especially when ftell or fgetpos is used               */
  46539. X      while (newfile || (gfe_file = fopen(filename, "rb")) == NULL) {
  46540. X     char buf[60];
  46541. X     newfile = 0;
  46542. X     if (firsttry) {
  46543. X        extern char s_cantfind[];
  46544. X        sprintf(temp1,s_cantfind, filename);
  46545. X        stopmsg(0,temp1);
  46546. X        }
  46547. X     sprintf(buf,"Select %s File",title);
  46548. X     if (getafilename(buf,fmask,filename) < 0)
  46549. X        return -1;
  46550. X     firsttry = 1; /* if around open loop again it is an error */
  46551. X     }
  46552. X      setvbuf(gfe_file,tstack,_IOFBF,4096); /* improves speed when file is big */
  46553. X      newfile = 0;
  46554. X      if ((entry_pointer = gfe_choose_entry(type,title,filename,entryname)) == -2) {
  46555. X     newfile = 1; /* go to file list, */
  46556. X     continue;    /* back to getafilename */
  46557. X     }
  46558. X      if (entry_pointer == -1)
  46559. X     return -1;
  46560. X      switch (type) {
  46561. X     case GETFORMULA:
  46562. X        if (RunForm(entryname) == 0) return 0;
  46563. X        break;
  46564. X     case GETLSYS:
  46565. X        if (LLoad() == 0) return 0;
  46566. X        break;
  46567. X     case GETIFS:
  46568. X        if (ifsload() == 0) {
  46569. X           fractype = (ifs_type == 0) ? IFS : IFS3D;
  46570. X           curfractalspecific = &fractalspecific[fractype];
  46571. X           set_default_parms(); /* to correct them if 3d */
  46572. X           return 0;
  46573. X           }
  46574. X        break;
  46575. X     case GETPARM:
  46576. X        return entry_pointer;
  46577. X     }
  46578. X      }
  46579. X}
  46580. X
  46581. X   struct entryinfo {
  46582. X      char name[ITEMNAMELEN+1];
  46583. X      long point; /* points to the ( or the { following the name */
  46584. X      };
  46585. X   static struct entryinfo **gfe_choices; /* for format_getparm_line */
  46586. X   static char *gfe_title;
  46587. X
  46588. Xstatic long gfe_choose_entry(int type,char *title,char *filename,char *entryname)
  46589. X/* subrtn of get_file_entry, separated so that storage gets freed up */
  46590. X{
  46591. X#define MAXENTRIES 200
  46592. X   static char far instr[]={"Press F6 to select different file, F2 for details of highlighted choice"};
  46593. X   int numentries, i;
  46594. X   char buf[101];
  46595. X   struct entryinfo *choices[MAXENTRIES];
  46596. X   int attributes[MAXENTRIES];
  46597. X   void (*formatitem)();
  46598. X   int boxwidth,boxdepth,colwidth;
  46599. X   long file_offset,name_offset;
  46600. X   extern struct entryinfo boxx[MAXENTRIES];
  46601. X
  46602. X   gfe_choices = &choices[0];
  46603. X   gfe_title = title;
  46604. X   for (i = 0; i < MAXENTRIES; i++) {
  46605. X      attributes[i] = 1;
  46606. X      choices[i] = &boxx[i];
  46607. X      }
  46608. X   numentries = 0;
  46609. X   file_offset = -1;
  46610. X
  46611. X   helptitle(); /* to display a clue when file big and next is slow */
  46612. X
  46613. X   while (1) { /* scan the file for entry names */
  46614. X      int c,len;
  46615. X      do {
  46616. X     ++file_offset;
  46617. X     c = getc(gfe_file);
  46618. X     } while (c == ' ' /* skip white space */
  46619. X           || c == '\t' || c == '\n' || c == '\r');
  46620. X      if (c == ';') {
  46621. X     do {
  46622. X        ++file_offset;
  46623. X        c = getc(gfe_file);
  46624. X        } while (c != '\n' && c != EOF && c != '\032');
  46625. X     if (c == EOF || c == '\032') break;
  46626. X     continue;
  46627. X     }
  46628. X      name_offset = file_offset;
  46629. X      len = 0; /* next equiv roughly to fscanf(..,"%40[^ \n\r\t({\032]",buf) */
  46630. X      while (c != ' ' && c != '\t' && c != '('
  46631. X    && c != '{' && c != '\n' && c != '\r' && c != EOF && c != '\032') {
  46632. X     if (len < 40) buf[len++] = c;
  46633. X     c = getc(gfe_file);
  46634. X     ++file_offset;
  46635. X     }
  46636. X      buf[len] = 0;
  46637. X      while (c != '{' && c != '\n' && c != '\r' && c != EOF && c != '\032') {
  46638. X     c = getc(gfe_file);
  46639. X     ++file_offset;
  46640. X     }
  46641. X      if (c == '{') {
  46642. X     while (c != '}' && c != EOF && c != '\032') {
  46643. X        c = getc(gfe_file);
  46644. X        ++file_offset;
  46645. X        }
  46646. X     if (c != '}') break;
  46647. X     buf[ITEMNAMELEN] = 0;
  46648. X     if (buf[0] != 0 && stricmp(buf,"comment") != 0) {
  46649. X        strcpy(boxx[numentries].name,buf);
  46650. X        boxx[numentries].point = name_offset;
  46651. X        if (++numentries >= MAXENTRIES) {
  46652. X           sprintf(buf,"Too many entries in file, first %d used",MAXENTRIES);
  46653. X           stopmsg(0,buf);
  46654. X           break;
  46655. X           }
  46656. X        }
  46657. X     }
  46658. X      else
  46659. X     if (c == EOF || c == '\032') break;
  46660. X      }
  46661. X
  46662. X   if (numentries == 0) {
  46663. X      static char far msg[]={"File doesn't contain any valid entries"};
  46664. X      stopmsg(0,msg);
  46665. X      fclose(gfe_file);
  46666. X      return -2; /* back to file list */
  46667. X      }
  46668. X
  46669. X   qsort((char **)choices,numentries,sizeof(char *),lccompare);
  46670. X
  46671. X   strcpy(buf,entryname); /* preset to last choice made */
  46672. X   sprintf(temp1,"%s Selection\nFile: %s",title,filename);
  46673. X   formatitem = NULL;
  46674. X   boxwidth = colwidth = boxdepth = 0;
  46675. X   if (type == GETPARM) {
  46676. X      formatitem = format_parmfile_line;
  46677. X      boxwidth = 1;
  46678. X      boxdepth = 16;
  46679. X      colwidth = 76;
  46680. X      }
  46681. X   i = fullscreen_choice(8,temp1,NULL,instr,numentries,(char **)choices,
  46682. X                           attributes,boxwidth,boxdepth,colwidth,0,
  46683. X               formatitem,buf,NULL,check_gfe_key);
  46684. X   fclose(gfe_file);
  46685. X   if (i < 0) {
  46686. X      if (i == 0-F6)
  46687. X     return -2; /* go back to file list */
  46688. X      return -1;    /* cancel */
  46689. X      }
  46690. X   strcpy(entryname, choices[i]->name);
  46691. X   return(choices[i]->point);
  46692. X}
  46693. X
  46694. Xstatic int check_gfe_key(int curkey,int choice)
  46695. X{
  46696. X   char infhdg[60];
  46697. X   char far *infbuf;
  46698. X
  46699. X   if (curkey == F6)
  46700. X      return 0-F6;
  46701. X   if (curkey == F2) {
  46702. X      infbuf = MK_FP(extraseg,0);
  46703. X      fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
  46704. X      load_entry_text(gfe_file,infbuf,16);
  46705. X      strcpy(infhdg,gfe_title);
  46706. X      strcat(infhdg," file entry:\n\n");
  46707. X /* ... instead, call help with buffer?  heading added */
  46708. X      stackscreen();
  46709. X      helptitle();
  46710. X      setattr(1,0,C_GENERAL_MED,24*80);
  46711. X      putstring(2,1,C_GENERAL_HI,infhdg);
  46712. X      textcbase = 2; /* left margin is 2 */
  46713. X      putstring(-1,0,C_GENERAL_MED,infbuf);
  46714. X      putstring(-1,0,C_GENERAL_LO,"\n\n\nPress any key to return to selection list");
  46715. X      textcbase = 0;
  46716. X      movecursor(25,80);
  46717. X      getakeynohelp();
  46718. X      unstackscreen();
  46719. X      }
  46720. X   return 0;
  46721. X}
  46722. X
  46723. Xstatic void load_entry_text(FILE *entfile,char far *buf,int maxlines)
  46724. X{
  46725. X   int linect,linelen,c;
  46726. X   linect = linelen = 0;
  46727. X   while ((c = fgetc(entfile)) != EOF && c != '\032') {
  46728. X      if (c != '\r') {
  46729. X     if (c == '\t') {
  46730. X        while ((linelen % 8) != 7 && linelen < 75) { /* 76 wide max */
  46731. X           *(buf++) = ' ';
  46732. X           ++linelen;
  46733. X           }
  46734. X        c = ' ';
  46735. X        }
  46736. X     if (c == '\n') {
  46737. X        if (++linect > maxlines) break;
  46738. X        linelen = -1;
  46739. X        }
  46740. X     if (++linelen > 75) {
  46741. X        if (linelen == 76) *(buf++) = '\021';
  46742. X        }
  46743. X     else
  46744. X        *(buf++) = c;
  46745. X     if (c == '}') break;
  46746. X     }
  46747. X      }
  46748. X   *buf = 0;
  46749. X}
  46750. X
  46751. Xstatic void format_parmfile_line(int choice,char *buf)
  46752. X{
  46753. X   int c,i;
  46754. X   char line[80];
  46755. X   fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
  46756. X   while (getc(gfe_file) != '{') { }
  46757. X   while ((c = getc(gfe_file)) == ' ' || c == '\t' || c == ';') { }
  46758. X   i = 0;
  46759. X   while (i < 56 && c != '\n' && c != '\r' && c != EOF && c != '\032') {
  46760. X      line[i++] = (c == '\t') ? ' ' : c;
  46761. X      c = getc(gfe_file);
  46762. X      }
  46763. X   line[i] = 0;
  46764. X   sprintf(buf,"%-20s%-56s",gfe_choices[choice]->name,line);
  46765. X}
  46766. X
  46767. X/* --------------------------------------------------------------------- */
  46768. X
  46769. Xint get_fract3d_params() /* prompt for 3D fractal parameters */
  46770. X{
  46771. X   int i,k,ret,oldhelpmode;
  46772. X   static char far hdg[] = {"3D Parameters"};
  46773. X   static char far p1[] = {"X-axis rotation in degrees"};
  46774. X   static char far p2[] = {"Y-axis rotation in degrees"};
  46775. X   static char far p3[] = {"Z-axis rotation in degrees"};
  46776. X   static char far p4[] = {"Perspective distance [1 - 999, 0 for no persp]"};
  46777. X   static char far p5[] = {"X shift with perspective (positive = right)"};
  46778. X   static char far p6[] = {"Y shift with perspective (positive = up   )"};
  46779. X   static char far p7[] = {"Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)"};
  46780. X   static char far *ifs3d_prompts[8] = {p1, p2, p3, p4, p5, p6, p7};
  46781. X   struct fullscreenvalues uvalues[20];
  46782. X
  46783. X   ENTER_OVLY(OVLY_PROMPTS1);
  46784. X   stackscreen();
  46785. X
  46786. X   k = 0;
  46787. X   uvalues[k].type = 'i';
  46788. X   uvalues[k++].uval.ival = XROT;
  46789. X   uvalues[k].type = 'i';
  46790. X   uvalues[k++].uval.ival = YROT;
  46791. X   uvalues[k].type = 'i';
  46792. X   uvalues[k++].uval.ival = ZROT;
  46793. X   uvalues[k].type = 'i';
  46794. X   uvalues[k++].uval.ival = ZVIEWER;
  46795. X   uvalues[k].type = 'i';
  46796. X   uvalues[k++].uval.ival = XSHIFT;
  46797. X   uvalues[k].type = 'i';
  46798. X   uvalues[k++].uval.ival = YSHIFT;
  46799. X   uvalues[k].type = 'i';
  46800. X   uvalues[k++].uval.ival = glassestype;
  46801. X
  46802. X   oldhelpmode = helpmode;
  46803. X   helpmode = HELP3DFRACT;
  46804. X   i = fullscreen_prompt(hdg,k,ifs3d_prompts,uvalues,0,0,NULL);
  46805. X   helpmode = oldhelpmode;
  46806. X   if (i < 0) {
  46807. X      ret = -1;
  46808. X      goto get_f3d_exit;
  46809. X      }
  46810. X
  46811. X   ret = k = 0;
  46812. X   XROT    =  uvalues[k++].uval.ival;
  46813. X   YROT    =  uvalues[k++].uval.ival;
  46814. X   ZROT    =  uvalues[k++].uval.ival;
  46815. X   ZVIEWER =  uvalues[k++].uval.ival;
  46816. X   XSHIFT  =  uvalues[k++].uval.ival;
  46817. X   YSHIFT  =  uvalues[k++].uval.ival;
  46818. X   glassestype = uvalues[k++].uval.ival;
  46819. X   if (glassestype < 0 || glassestype > 3) glassestype = 0;
  46820. X   if (glassestype)
  46821. X      if (get_funny_glasses_params() || check_mapfile())
  46822. X     ret = -1;
  46823. X
  46824. Xget_f3d_exit:
  46825. X   unstackscreen();
  46826. X   EXIT_OVLY;
  46827. X   return(ret);
  46828. X}
  46829. X
  46830. X/* --------------------------------------------------------------------- */
  46831. X/* These macros streamline the "save near space" campaign */ 
  46832. X
  46833. X#define LOADPROMPTS3D(X)     {\
  46834. X   static char far tmp[] = { X };\
  46835. X   prompts3d[++k]= tmp;\
  46836. X   }
  46837. X
  46838. X
  46839. Xint get_3d_params()    /* prompt for 3D parameters */
  46840. X{
  46841. X   static char far hdg[]={"3D Mode Selection"};
  46842. X   static char far hdg1[]={"Select 3D Fill Type"};
  46843. X   char *choices[10];
  46844. X   int attributes[21];
  46845. X   int sphere;
  46846. X   char far *s;
  46847. X   static char far s1[] = {"              Sphere 3D Parameters\n\
  46848. XSphere is on its side; North pole to right\n\
  46849. XLong. 180 is top, 0 is bottom; Lat. -90 is left, 90 is right"};
  46850. X   static char s2[]={"              Planar 3D Parameters\n\
  46851. XPre-rotation X axis is screen top; Y axis is left side\n\
  46852. XPre-rotation Z axis is coming at you out of the screen!"};
  46853. X   char far *prompts3d[21];
  46854. X   struct fullscreenvalues uvalues[21];
  46855. X   int i, k;
  46856. X   int oldhelpmode;
  46857. X
  46858. X   ENTER_OVLY(OVLY_PROMPTS1);
  46859. X
  46860. X#ifdef WINFRACT
  46861. X     {
  46862. X     extern int far wintext_textmode;
  46863. X    
  46864. X     if (wintext_textmode != 2)  /* are we in textmode? */
  46865. X         return(0);              /* no - prompts are already handled */
  46866. X     }
  46867. X#endif
  46868. Xrestart_1:
  46869. X    if (Targa_Out && overlay3d)
  46870. X        Targa_Overlay = 1;
  46871. X
  46872. X   k= -1;
  46873. X
  46874. X   LOADPROMPTS3D("Preview Mode?");
  46875. X   uvalues[k].type = 'y';
  46876. X   uvalues[k].uval.ch.val = preview;
  46877. X
  46878. X   LOADPROMPTS3D("    Show Box?");
  46879. X   uvalues[k].type = 'y';
  46880. X   uvalues[k].uval.ch.val = showbox;
  46881. X   
  46882. X   LOADPROMPTS3D("Coarseness, preview/grid/ray (in y dir)");
  46883. X   uvalues[k].type = 'i';
  46884. X   uvalues[k].uval.ival = previewfactor;
  46885. X
  46886. X   LOADPROMPTS3D("Spherical Projection?");
  46887. X   uvalues[k].type = 'y';
  46888. X   uvalues[k].uval.ch.val = sphere = SPHERE;
  46889. X
  46890. X   LOADPROMPTS3D("Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)");
  46891. X   uvalues[k].type = 'i';
  46892. X   uvalues[k].uval.ival = glassestype;
  46893. X
  46894. X   LOADPROMPTS3D("Ray trace out? (0=No, 1=DKB/POVRay, 2=VIVID, 3=RAW,");
  46895. X   uvalues[k].type = 'i';
  46896. X   uvalues[k].uval.ival = RAY;
  46897. X
  46898. X   LOADPROMPTS3D("                4=MTV, 5=RAYSHADE, 6=ACROSPIN, 7=DXF)");
  46899. X   uvalues[k].type = '*';
  46900. X
  46901. X   LOADPROMPTS3D("    Brief output?");
  46902. X   uvalues[k].type = 'y';
  46903. X   uvalues[k].uval.ch.val = BRIEF;
  46904. X
  46905. X   check_writefile(ray_name,".ray");
  46906. X   LOADPROMPTS3D("    Output File Name");
  46907. X   uvalues[k].type = 's';
  46908. X   strcpy(uvalues[k].uval.sval,ray_name);
  46909. X
  46910. X   LOADPROMPTS3D("Targa output?");
  46911. X   uvalues[k].type = 'y';
  46912. X   uvalues[k].uval.ch.val = Targa_Out;
  46913. X
  46914. X   oldhelpmode = helpmode;
  46915. X   helpmode = HELP3DMODE;
  46916. X
  46917. X   k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,0,NULL);
  46918. X   helpmode = oldhelpmode;
  46919. X   if (k < 0) {
  46920. X      EXIT_OVLY;
  46921. X      return(-1);
  46922. X      }
  46923. X
  46924. X   k=0;
  46925. X
  46926. X   preview = uvalues[k++].uval.ch.val;
  46927. X
  46928. X   showbox = uvalues[k++].uval.ch.val;
  46929. X
  46930. X   previewfactor  = uvalues[k++].uval.ival;
  46931. X
  46932. X   sphere = uvalues[k++].uval.ch.val;
  46933. X
  46934. X   glassestype = uvalues[k++].uval.ival;
  46935. X
  46936. X   RAY = uvalues[k++].uval.ival;
  46937. X   k++;
  46938. X   {
  46939. X      static char far msg[] = {
  46940. X"DKB/POV-Ray output is obsolete but still works. See \"Ray Tracing Output\" in\n\
  46941. Xthe online documentation."};
  46942. X      if(RAY == 1)
  46943. X         stopmsg(0,msg);
  46944. X   }
  46945. X   BRIEF = uvalues[k++].uval.ch.val;
  46946. X
  46947. X   strcpy(ray_name,uvalues[k++].uval.sval);
  46948. X
  46949. X   Targa_Out = uvalues[k++].uval.ch.val;
  46950. X
  46951. X   /* check ranges */
  46952. X   if(previewfactor < 2)
  46953. X      previewfactor = 2;
  46954. X   if(previewfactor > 2000)
  46955. X      previewfactor = 2000;
  46956. X
  46957. X   if(sphere && !SPHERE)
  46958. X   {
  46959. X      SPHERE = TRUE;
  46960. X      set_3d_defaults();
  46961. X   }
  46962. X   else if(!sphere && SPHERE)
  46963. X   {
  46964. X      SPHERE = FALSE;
  46965. X      set_3d_defaults();
  46966. X   }
  46967. X
  46968. X   if(glassestype < 0)
  46969. X      glassestype = 0;
  46970. X   if(glassestype > 3)
  46971. X      glassestype = 3;
  46972. X   if(glassestype)
  46973. X      whichimage = 1;
  46974. X
  46975. X   if (RAY < 0)
  46976. X      RAY = 0;
  46977. X   if (RAY > 7)
  46978. X      RAY = 7;
  46979. X
  46980. X   if (!RAY)
  46981. X   {
  46982. X      k = 0;
  46983. X      choices[k++] = "make a surface grid";
  46984. X      choices[k++] = "just draw the points";
  46985. X      choices[k++] = "connect the dots (wire frame)";
  46986. X      choices[k++] = "surface fill (colors interpolated)";
  46987. X      choices[k++] = "surface fill (colors not interpolated)";
  46988. X      choices[k++] = "solid fill (bars up from \"ground\")";
  46989. X      if(SPHERE)
  46990. X      {
  46991. X         choices[k++] = "light source";
  46992. X      }
  46993. X      else
  46994. X      {
  46995. X         choices[k++] = "light source before transformation";
  46996. X         choices[k++] = "light source after transformation";
  46997. X      }
  46998. X      for (i = 0; i < k; ++i)
  46999. X     attributes[i] = 1;
  47000. X      helpmode = HELP3DFILL;
  47001. X      i = fullscreen_choice(CHOICEHELP,hdg1,NULL,NULL,k,choices,attributes,
  47002. X                  0,0,0,FILLTYPE+1,NULL,NULL,NULL,NULL);
  47003. X      helpmode = oldhelpmode;
  47004. X      if (i < 0)
  47005. X     goto restart_1;
  47006. X      FILLTYPE = i-1;
  47007. X
  47008. X      if(glassestype)
  47009. X      {
  47010. X     if(get_funny_glasses_params())
  47011. X            goto restart_1;
  47012. X         }
  47013. X         if (check_mapfile())
  47014. X             goto restart_1;
  47015. X      }
  47016. X   restart_3:
  47017. X
  47018. X   if(SPHERE)
  47019. X   {
  47020. X      k = -1;
  47021. X      LOADPROMPTS3D("Longitude start (degrees)");
  47022. X      LOADPROMPTS3D("Longitude stop  (degrees)");
  47023. X      LOADPROMPTS3D("Latitude start  (degrees)");
  47024. X      LOADPROMPTS3D("Latitude stop   (degrees)");
  47025. X      LOADPROMPTS3D("Radius scaling factor in pct");
  47026. X   }
  47027. X   else
  47028. X   {
  47029. X      k = -1;
  47030. X      if (!RAY)
  47031. X      {
  47032. X         LOADPROMPTS3D("X-axis rotation in degrees");
  47033. X         LOADPROMPTS3D("Y-axis rotation in degrees");
  47034. X         LOADPROMPTS3D("Z-axis rotation in degrees");
  47035. X      }
  47036. X      LOADPROMPTS3D("X-axis scaling factor in pct");
  47037. X      LOADPROMPTS3D("Y-axis scaling factor in pct");
  47038. X   }
  47039. X   k = -1;
  47040. X   if (!(RAY && !SPHERE))
  47041. X   {
  47042. X      uvalues[++k].uval.ival   = XROT     ;
  47043. X      uvalues[k].type = 'i';
  47044. X      uvalues[++k].uval.ival   = YROT     ;
  47045. X      uvalues[k].type = 'i';
  47046. X      uvalues[++k].uval.ival   = ZROT     ;
  47047. X      uvalues[k].type = 'i';
  47048. X   }
  47049. X   uvalues[++k].uval.ival   = XSCALE    ;
  47050. X   uvalues[k].type = 'i';
  47051. X
  47052. X   uvalues[++k].uval.ival   = YSCALE    ;
  47053. X   uvalues[k].type = 'i';
  47054. X
  47055. X   LOADPROMPTS3D("Surface Roughness scaling factor in pct");
  47056. X   uvalues[k].type = 'i';
  47057. X   uvalues[k].uval.ival = ROUGH     ;
  47058. X
  47059. X   LOADPROMPTS3D("'Water Level' (minimum color value)");
  47060. X   uvalues[k].type = 'i';
  47061. X   uvalues[k].uval.ival = WATERLINE ;
  47062. X
  47063. X   if(!RAY)
  47064. X   {
  47065. X      LOADPROMPTS3D("Perspective distance [1 - 999, 0 for no persp])");
  47066. X      uvalues[k].type = 'i';
  47067. X      uvalues[k].uval.ival = ZVIEWER     ;
  47068. X
  47069. X      LOADPROMPTS3D("X shift with perspective (positive = right)");
  47070. X      uvalues[k].type = 'i';
  47071. X      uvalues[k].uval.ival = XSHIFT    ;
  47072. X   
  47073. X      LOADPROMPTS3D("Y shift with perspective (positive = up   )");
  47074. X      uvalues[k].type = 'i';
  47075. X      uvalues[k].uval.ival = YSHIFT    ;
  47076. X   
  47077. X      LOADPROMPTS3D("Image non-perspective X adjust (positive = right)");
  47078. X      uvalues[k].type = 'i';
  47079. X      uvalues[k].uval.ival = xtrans    ;
  47080. X   
  47081. X      LOADPROMPTS3D("Image non-perspective Y adjust (positive = up)");
  47082. X      uvalues[k].type = 'i';
  47083. X      uvalues[k].uval.ival = ytrans    ;
  47084. X   
  47085. X      LOADPROMPTS3D("First transparent color");
  47086. X      uvalues[k].type = 'i';
  47087. X      uvalues[k].uval.ival = transparent[0];
  47088. X   
  47089. X      LOADPROMPTS3D("Last transparent color");
  47090. X      uvalues[k].type = 'i';
  47091. X      uvalues[k].uval.ival = transparent[1];
  47092. X   }
  47093. X
  47094. X   LOADPROMPTS3D("Randomize Colors      (0 - 7, '0' disables)");
  47095. X   uvalues[k].type = 'i';
  47096. X   uvalues[k++].uval.ival = RANDOMIZE;
  47097. X
  47098. X   if (SPHERE)
  47099. X      s = s1;
  47100. X   else
  47101. X      s = s2;
  47102. X
  47103. X   helpmode = HELP3DPARMS;
  47104. X   k = fullscreen_prompt(s,k,prompts3d,uvalues,0,0,NULL);
  47105. X   helpmode = oldhelpmode;
  47106. X   if (k < 0)
  47107. X      goto restart_1;
  47108. X
  47109. X   k = 0;
  47110. X   if (!(RAY && !SPHERE))
  47111. X   {
  47112. X      XROT    = uvalues[k++].uval.ival;
  47113. X      YROT    = uvalues[k++].uval.ival;
  47114. X      ZROT    = uvalues[k++].uval.ival;
  47115. X   }
  47116. X   XSCALE     = uvalues[k++].uval.ival;
  47117. X   YSCALE     = uvalues[k++].uval.ival;
  47118. X   ROUGH      = uvalues[k++].uval.ival;
  47119. X   WATERLINE  = uvalues[k++].uval.ival;
  47120. X   if (!RAY)
  47121. X   {
  47122. X      ZVIEWER = uvalues[k++].uval.ival;
  47123. X   XSHIFT     = uvalues[k++].uval.ival;
  47124. X   YSHIFT     = uvalues[k++].uval.ival;
  47125. X   xtrans     = uvalues[k++].uval.ival;
  47126. X   ytrans     = uvalues[k++].uval.ival;
  47127. X   transparent[0] = uvalues[k++].uval.ival;
  47128. X   transparent[1] = uvalues[k++].uval.ival;
  47129. X   }
  47130. X   RANDOMIZE  = uvalues[k++].uval.ival;
  47131. X   if (RANDOMIZE >= 7) RANDOMIZE = 7;
  47132. X   if (RANDOMIZE <= 0) RANDOMIZE = 0;
  47133. X
  47134. X   if ((Targa_Out || ILLUMINE || RAY))
  47135. X    if(get_light_params())
  47136. X        goto restart_3;
  47137. X
  47138. XEXIT_OVLY;
  47139. Xreturn(0);
  47140. X}
  47141. X
  47142. X/* --------------------------------------------------------------------- */
  47143. Xstatic int get_light_params()
  47144. X{
  47145. X   static char far hdg[]={"Light Source Parameters"};
  47146. X   char far *prompts3d[13];
  47147. X   struct fullscreenvalues uvalues[13];
  47148. X
  47149. X   int k;
  47150. X   int oldhelpmode;
  47151. X
  47152. X   /* defaults go here */
  47153. X
  47154. X   k = -1;
  47155. X
  47156. X   if (ILLUMINE || RAY)
  47157. X   {
  47158. X   LOADPROMPTS3D("X value light vector");
  47159. X   uvalues[k].type = 'i';
  47160. X   uvalues[k].uval.ival = XLIGHT    ;
  47161. X
  47162. X   LOADPROMPTS3D("Y value light vector");
  47163. X   uvalues[k].type = 'i';
  47164. X   uvalues[k].uval.ival = YLIGHT    ;
  47165. X
  47166. X   LOADPROMPTS3D("Z value light vector");
  47167. X   uvalues[k].type = 'i';
  47168. X   uvalues[k].uval.ival = ZLIGHT    ;
  47169. X
  47170. X        if (!RAY)
  47171. X        {
  47172. X   LOADPROMPTS3D("Light Source Smoothing Factor");
  47173. X   uvalues[k].type = 'i';
  47174. X   uvalues[k].uval.ival = LIGHTAVG  ;
  47175. X
  47176. X   LOADPROMPTS3D("Ambient");
  47177. X   uvalues[k].type = 'i';
  47178. X   uvalues[k].uval.ival = Ambient;
  47179. X        }
  47180. X   }
  47181. X
  47182. X   if (Targa_Out && !RAY)
  47183. X   {
  47184. X    LOADPROMPTS3D("Haze Factor        (0 - 100, '0' disables)");
  47185. X    uvalues[k].type = 'i';
  47186. X    uvalues[k].uval.ival= haze;
  47187. X
  47188. X        if (!Targa_Overlay)
  47189. X    check_writefile(light_name,".tga");
  47190. X      LOADPROMPTS3D("Targa File Name  (Assume .tga)");
  47191. X    uvalues[k].type = 's';
  47192. X    strcpy(uvalues[k].uval.sval,light_name);
  47193. X
  47194. X      LOADPROMPTS3D("Back Ground Color (0 - 255)");
  47195. X      uvalues[k].type = '*';
  47196. X
  47197. X      LOADPROMPTS3D("   Red");
  47198. X      uvalues[k].type = 'i';
  47199. X      uvalues[k].uval.ival = (int)back_color[0];
  47200. X
  47201. X      LOADPROMPTS3D("   Green");
  47202. X      uvalues[k].type = 'i';
  47203. X      uvalues[k].uval.ival = (int)back_color[1];
  47204. X
  47205. X      LOADPROMPTS3D("   Blue");
  47206. X      uvalues[k].type = 'i';
  47207. X      uvalues[k].uval.ival = (int)back_color[2];
  47208. X
  47209. X      LOADPROMPTS3D("Overlay Targa File? (Y/N)");
  47210. X      uvalues[k].type = 'y';
  47211. X      uvalues[k].uval.ch.val = Targa_Overlay;
  47212. X
  47213. X   }
  47214. X
  47215. X   LOADPROMPTS3D("");
  47216. X
  47217. X   oldhelpmode = helpmode;
  47218. X   helpmode = HELP3DLIGHT;
  47219. X   k = fullscreen_prompt(hdg,k,prompts3d,uvalues,0,0,NULL);
  47220. X   helpmode = oldhelpmode;
  47221. X   if (k < 0)
  47222. X      return(-1);
  47223. X
  47224. X   k = 0;
  47225. X   if (ILLUMINE)
  47226. X   {
  47227. X      XLIGHT   = uvalues[k++].uval.ival;
  47228. X      YLIGHT   = uvalues[k++].uval.ival;
  47229. X      ZLIGHT   = uvalues[k++].uval.ival;
  47230. X      if (!RAY)
  47231. X        {
  47232. X      LIGHTAVG = uvalues[k++].uval.ival;
  47233. X      Ambient  = uvalues[k++].uval.ival;
  47234. X      if (Ambient >= 100) Ambient = 100;
  47235. X      if (Ambient <= 0) Ambient = 0;
  47236. X        }
  47237. X   }
  47238. X
  47239. X   if (Targa_Out && !RAY)
  47240. X   {
  47241. X    haze  =  uvalues[k++].uval.ival;
  47242. X    if (haze >= 100) haze = 100;
  47243. X    if (haze <= 0) haze = 0;
  47244. X        strcpy(light_name,uvalues[k++].uval.sval);
  47245. X        /* In case light_name conflicts with an existing name it is checked
  47246. X            again in line3d */
  47247. X        k++;
  47248. X        back_color[0] = (char)uvalues[k++].uval.ival % 255;
  47249. X        back_color[1] = (char)uvalues[k++].uval.ival % 255;
  47250. X        back_color[2] = (char)uvalues[k++].uval.ival % 255;
  47251. X        Targa_Overlay = uvalues[k].uval.ch.val;
  47252. X   }
  47253. X   return(0);
  47254. X}
  47255. X
  47256. X/* --------------------------------------------------------------------- */
  47257. X
  47258. X
  47259. Xstatic int check_mapfile()
  47260. X{
  47261. X   extern BYTE dacbox[256][3];
  47262. X   extern BYTE olddacbox[256][3];
  47263. X   int askflag = 0;
  47264. X   int i,oldhelpmode;
  47265. X   strcpy(temp1,"*");
  47266. X   if (mapset)
  47267. X      strcpy(temp1,MAP_name);
  47268. X   if (!(glassestype == 1 || glassestype == 2))
  47269. X      askflag = 1;
  47270. X   else
  47271. X      strcpy(temp1,funnyglasses_map_name);
  47272. X   while (TRUE) {
  47273. X      if (askflag) {
  47274. X     oldhelpmode = helpmode;
  47275. X     helpmode = -1;
  47276. X     i = field_prompt(0,"\
  47277. XEnter name of .MAP file to use,\n\
  47278. Xor '*' to use palette from the image to be loaded.",
  47279. X         NULL,temp1,60,NULL);
  47280. X     helpmode = oldhelpmode;
  47281. X     if (i < 0)
  47282. X        return(-1);
  47283. X        if (temp1[0] == '*') {
  47284. X            mapset = 0;
  47285. X            break;
  47286. X            }
  47287. X        }
  47288. X        memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  47289. X      i = ValidateLuts(temp1);
  47290. X      memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  47291. X      if (i != 0) { /* Oops, somethings wrong */
  47292. X         askflag = 1;
  47293. X     continue;
  47294. X     }
  47295. X      mapset = 1;
  47296. X      strcpy (MAP_name,temp1);
  47297. X      break;
  47298. X      }
  47299. X   return(0);
  47300. X}
  47301. X
  47302. Xstatic int get_funny_glasses_params()
  47303. X{
  47304. X   static char far hdg[]={"Funny Glasses Parameters"};
  47305. X   char far *prompts3d[10];
  47306. X
  47307. X   struct fullscreenvalues uvalues[10];
  47308. X
  47309. X   int k;
  47310. X   int oldhelpmode;
  47311. X
  47312. X   /* defaults */
  47313. X   if(ZVIEWER == 0)
  47314. X      ZVIEWER = 150;
  47315. X   if(eyeseparation == 0)
  47316. X   {
  47317. X      if(fractype==IFS3D || fractype==LLORENZ3D || fractype==FPLORENZ3D)
  47318. X      {
  47319. X     eyeseparation =  2;
  47320. X     xadjust       = -2;
  47321. X      }
  47322. X      else
  47323. X      {
  47324. X     eyeseparation =  3;
  47325. X     xadjust       =  0;
  47326. X      }
  47327. X   }
  47328. X
  47329. X   if(glassestype == 1)
  47330. X      strcpy(funnyglasses_map_name,Glasses1Map);
  47331. X   else if(glassestype == 2)
  47332. X   {
  47333. X      if(FILLTYPE == -1)
  47334. X     strcpy(funnyglasses_map_name,"grid.map");
  47335. X      else
  47336. X     strcpy(funnyglasses_map_name,"glasses2.map");
  47337. X   }
  47338. X
  47339. X   k = -1;
  47340. X   LOADPROMPTS3D("Interocular distance (as % of screen)");
  47341. X   uvalues[k].type = 'i';
  47342. X   uvalues[k].uval.ival= eyeseparation;
  47343. X
  47344. X   LOADPROMPTS3D("Convergence adjust (positive = spread greater)");
  47345. X   uvalues[k].type = 'i';
  47346. X   uvalues[k].uval.ival = xadjust;
  47347. X
  47348. X   LOADPROMPTS3D("Left  red image crop (% of screen)");
  47349. X   uvalues[k].type = 'i';
  47350. X   uvalues[k].uval.ival = red_crop_left;
  47351. X
  47352. X   LOADPROMPTS3D("Right red image crop (% of screen)");
  47353. X   uvalues[k].type = 'i';
  47354. X   uvalues[k].uval.ival = red_crop_right;
  47355. X
  47356. X   LOADPROMPTS3D("Left  blue image crop (% of screen)");
  47357. X   uvalues[k].type = 'i';
  47358. X   uvalues[k].uval.ival = blue_crop_left;
  47359. X
  47360. X   LOADPROMPTS3D("Right blue image crop (% of screen)");
  47361. X   uvalues[k].type = 'i';
  47362. X   uvalues[k].uval.ival = blue_crop_right;
  47363. X
  47364. X   LOADPROMPTS3D("Red brightness factor (%)");
  47365. X   uvalues[k].type = 'i';
  47366. X   uvalues[k].uval.ival = red_bright;
  47367. X
  47368. X   LOADPROMPTS3D("Blue brightness factor (%)");
  47369. X   uvalues[k].type = 'i';
  47370. X   uvalues[k].uval.ival = blue_bright;
  47371. X
  47372. X   if(glassestype == 1 || glassestype == 2)
  47373. X   {
  47374. X      LOADPROMPTS3D("Map File name");
  47375. X      uvalues[k].type = 's';
  47376. X      strcpy(uvalues[k].uval.sval,funnyglasses_map_name);
  47377. X   }
  47378. X
  47379. X   oldhelpmode = helpmode;
  47380. X   helpmode = HELP3DGLASSES;
  47381. X   k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,0,NULL);
  47382. X   helpmode = oldhelpmode;
  47383. X   if (k < 0)
  47384. X      return(-1);
  47385. X
  47386. X   k = 0;
  47387. X   eyeseparation   =  uvalues[k++].uval.ival;
  47388. X   xadjust       =  uvalues[k++].uval.ival;
  47389. X   red_crop_left   =  uvalues[k++].uval.ival;
  47390. X   red_crop_right  =  uvalues[k++].uval.ival;
  47391. X   blue_crop_left  =  uvalues[k++].uval.ival;
  47392. X   blue_crop_right =  uvalues[k++].uval.ival;
  47393. X   red_bright       =  uvalues[k++].uval.ival;
  47394. X   blue_bright       =  uvalues[k++].uval.ival;
  47395. X
  47396. X   if(glassestype == 1 || glassestype == 2)
  47397. X      strcpy(funnyglasses_map_name,uvalues[k].uval.sval);
  47398. X   return(0);
  47399. X}
  47400. SHAR_EOF
  47401. $TOUCH -am 1028230093 prompts1.c &&
  47402. chmod 0644 prompts1.c ||
  47403. echo "restore of prompts1.c failed"
  47404. set `wc -c prompts1.c`;Wc_c=$1
  47405. if test "$Wc_c" != "63669"; then
  47406.     echo original size 63669, current size $Wc_c
  47407. fi
  47408. # ============= prompts2.c ==============
  47409. echo "x - extracting prompts2.c (Text)"
  47410. sed 's/^X//' << 'SHAR_EOF' > prompts2.c &&
  47411. X/*
  47412. X    Various routines that prompt for things.
  47413. X    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  47414. X*/
  47415. X
  47416. X#include <stdlib.h>
  47417. X#include <stdio.h>
  47418. X#include <string.h>
  47419. X#include <ctype.h>
  47420. X#ifndef XFRACT
  47421. X#include <dos.h>
  47422. X#elif !defined(__386BSD__)
  47423. X#include <sys/types.h>
  47424. X#include <sys/stat.h>
  47425. X#include <sys/dir.h>
  47426. X#endif
  47427. X#ifdef __TURBOC__
  47428. X#include <alloc.h>
  47429. X#elif !defined(__386BSD__)
  47430. X#include <malloc.h>
  47431. X#endif
  47432. X
  47433. X#ifdef __hpux
  47434. X#include <sys/param.h>
  47435. X#define getwd(a) getcwd(a,MAXPATHLEN)
  47436. X#endif
  47437. X
  47438. X#include "fractint.h"
  47439. X#include "fractype.h"
  47440. X#include "helpdefs.h"
  47441. X#include "prototyp.h"
  47442. X
  47443. X/* Routines defined in prompts1.c */
  47444. X
  47445. Xextern    int prompt_checkkey(int curkey);
  47446. Xextern    long get_file_entry(int,char *,char *,char *,char *);
  47447. X
  47448. X/* Routines used in prompts1.c */
  47449. X
  47450. X    int get_corners(void);
  47451. X    int edit_ifs_params(void );
  47452. X    int lccompare(VOIDCONSTPTR, VOIDCONSTPTR); /* Needed in prompts1.c PAV */
  47453. X
  47454. X/* Routines in this module    */
  47455. X
  47456. Xstatic    int findfirst(char *path);
  47457. Xstatic  int check_f6_key(int curkey,int choice);
  47458. Xstatic    int findnext(void );
  47459. X    int splitpath(char *template,char *drive,char *dir,char *fname,char *ext);
  47460. X        int makepath(char *template,char *drive,char *dir,char *fname,char *ext);
  47461. Xstatic    void fix_dirname(char *dirname);
  47462. Xstatic    int expand_dirname(char *dirname,char *drive);
  47463. Xstatic    int filename_speedstr(int, int, int, char *, int);
  47464. Xstatic    int isadirectory(char *s);
  47465. Xstatic  int check_f6_key(int curkey,int choice);
  47466. X
  47467. Xextern int dotmode;
  47468. Xextern int orbit_delay;
  47469. Xextern char diskfilename[];
  47470. X
  47471. Xextern char *fract_dir1, *fract_dir2;
  47472. X
  47473. X#ifndef XFRACT
  47474. Xextern int strncasecmp(char *s,char *t,int ct);
  47475. X#endif
  47476. X
  47477. Xextern char temp1[256];   /* temporary strings          */
  47478. X
  47479. Xextern    double    xxmin,xxmax;    /* initial corner values    */
  47480. Xextern    double    yymin,yymax;    /* initial corner values    */
  47481. Xextern    BYTE usemag;
  47482. X
  47483. Xextern    int AntiAliasing;
  47484. Xextern double zzmin, zzmax, ttmin, ttmax;
  47485. Xextern int Transparent3D;
  47486. X
  47487. Xextern    double    xx3rd,yy3rd;    /* initial corner values    */
  47488. Xextern    int    invert;     /* non-zero if inversion active */
  47489. Xextern    double    inversion[3];    /* radius, xcenter, ycenter */
  47490. Xextern    int    pot16bit;
  47491. Xextern    int    disk16bit;
  47492. Xextern    double    potparam[3];    /* three potential parameters*/
  47493. Xextern    int    fractype;    /* if == 0, use Mandelbrot  */
  47494. Xextern    char    usr_floatflag;    /* floating-point fractals? */
  47495. Xextern    int    maxit;        /* try this many iterations */
  47496. Xextern    int    inside;     /* inside color */
  47497. Xextern    int    fillcolor;     /* fill color */
  47498. Xextern    int    outside;    /* outside color */
  47499. Xextern    int    finattract;    /* finite attractor switch */
  47500. Xextern    char    savename[80];    /* save files using this name */
  47501. Xextern    int    decomp[];    /* decomposition parameters */
  47502. Xextern    int    usr_distest;    /* distance estimator option */
  47503. Xextern    int    distestwidth;
  47504. Xextern    char    usr_stdcalcmode; /* '1', '2', 'g', 'b' */
  47505. Xextern    char    overwrite;     /* overwrite= flag */
  47506. Xextern    int    soundflag;    /* sound option */
  47507. Xextern    int    LogFlag;    /* non-zero if logarithmic palettes */
  47508. Xextern    int    usr_biomorph;    /* Biomorph flag */
  47509. X#if 0
  47510. X//extern    long    xmin, xmax, ymin, ymax; /* screen corner values */
  47511. X#endif
  47512. Xextern    int    xdots, ydots;    /* coordinates of dots on the screen  */
  47513. Xextern    int    colors;     /* maximum colors available */
  47514. Xextern    int    row, col;
  47515. Xextern    int    viewwindow;
  47516. Xextern    float    viewreduction;
  47517. Xextern    int    viewcrop;
  47518. Xextern    float    finalaspectratio;
  47519. Xextern    int    viewxdots,viewydots;
  47520. Xextern    int    textcbase;
  47521. Xextern    int    textrow,textcol;
  47522. Xextern    int    resave_flag;    /* resaving after a timed save */
  47523. Xextern    int    started_resaves;
  47524. Xextern    char    boxy[];
  47525. Xextern    int    rotate_lo,rotate_hi;
  47526. Xextern    int    rangeslen;
  47527. Xextern float  screenaspect;
  47528. X
  47529. Xextern  int  cmdarg(char *,int);
  47530. X
  47531. Xextern char CommandFile[];
  47532. Xextern char CommandName[];
  47533. Xextern float far *ifs_defn;
  47534. Xextern int ifs_type;
  47535. Xextern int ifs_changed;
  47536. Xextern int initbatch;        /* 1 if batch run (no kbd)  */
  47537. X
  47538. X/* speed key state values */
  47539. X#define MATCHING     0    /* string matches list - speed key mode */
  47540. X#define TEMPLATE    -2    /* wild cards present - buiding template */
  47541. X#define SEARCHPATH    -3    /* no match - building path search name */
  47542. X
  47543. X#define   FILEATTR     0x37       /* File attributes; select all but volume labels */
  47544. X#define   HIDDEN     2
  47545. X#define   SYSTEM     4
  47546. X#define   SUBDIR     16
  47547. X#define   MAXNUMFILES     300
  47548. X
  47549. Xstruct                   /* Allocate DTA and define structure */
  47550. X{
  47551. X     char path[21];            /* DOS path and filespec */
  47552. X     char attribute;            /* File attributes wanted */
  47553. X     int  ftime;            /* File creation time */
  47554. X     int  fdate;            /* File creation date */
  47555. X     long size;             /* File size in bytes */
  47556. X     char filename[13];         /* Filename and extension */
  47557. X} DTA;                   /* Disk Transfer Area */
  47558. X
  47559. X#define GETFORMULA 0
  47560. X#define GETLSYS    1
  47561. X#define GETIFS       2
  47562. X#define GETPARM    3
  47563. X
  47564. X/* --------------------------------------------------------------------- */
  47565. Xextern char s_iter[];
  47566. Xextern char s_real[];
  47567. Xextern char s_mult[];
  47568. Xextern char s_sum[];
  47569. Xextern char s_imag[];
  47570. Xextern char s_zmag[];
  47571. Xextern char s_bof60[];
  47572. Xextern char s_bof61[];
  47573. Xextern char s_maxiter[];
  47574. Xextern char s_epscross[];
  47575. Xextern char s_startrail[];
  47576. Xextern char s_normal[];
  47577. Xextern char s_period[];
  47578. X
  47579. Xchar commandmask[13] = {"*.par"};
  47580. X
  47581. Xvoid prompts2_overlay() { }    /* for restore_active_ovly */
  47582. X
  47583. X#if 0
  47584. X/* --------------------------------------------------------------------- */
  47585. X
  47586. Xextern int promptfkeys;
  47587. X
  47588. Xint edit_ifs_params()    /* prompt for IFS params */
  47589. X{
  47590. X   int totcols;
  47591. X   int i, j, k, numlines, ret;
  47592. X   FILE *tempfile;
  47593. X   char msg[81];
  47594. X   char filename[81];
  47595. X   float ftemp;
  47596. X   int oldhelpmode;
  47597. X   int low, hi;
  47598. X
  47599. X   if (!ifs_defn && !ifsload())
  47600. X      return(-1);
  47601. X
  47602. X   totcols = (ifs_type == 0) ? IFSPARM : IFS3DPARM;
  47603. X   ret = 0;
  47604. X   oldhelpmode = helpmode;
  47605. X   helpmode = HT_IFS;
  47606. X
  47607. X   low = 0;
  47608. X
  47609. X   for ( ;; ) {
  47610. Xstatic char far ifshdg2[]={"2D IFS Parameters"};
  47611. Xstatic char far ifshdg3[]={"3D IFS Parameters"};
  47612. Xstatic char far ifsparmmsg1[]={"#    a     b     c     d     e     f"};
  47613. Xstatic char far ifsparmmsg2[]={"     g     h     i     j     k     l"};
  47614. Xstatic char far ifsprompt[]={"\
  47615. XEnter the number of the line you want to edit,\n\
  47616. XS to save, F6 for corners, or ENTER to end ==>"};
  47617. X      int leftcol,promptrow,promptcol;
  47618. X#define IFS_NUM 12
  47619. X
  47620. X      for (numlines = 0; numlines < NUMIFS; numlines++) /* find the first zero entry */
  47621. X     if (ifs_defn[(numlines * totcols) + totcols - 1] <= 0.0001) break;
  47622. X
  47623. X      helptitle();
  47624. X      setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest of screen to background */
  47625. X      putstringcenter(2,0,80,C_GENERAL_HI,(ifs_type == 0) ? ifshdg2 : ifshdg3);
  47626. X      leftcol = (ifs_type == 0) ? 15 : 0;
  47627. X      putstring(4,leftcol+1,C_GENERAL_HI,ifsparmmsg1);
  47628. X      if (ifs_type != 0)
  47629. X     putstring(-1,-1,C_GENERAL_HI,ifsparmmsg2);
  47630. X      putstring(-1,-1,C_GENERAL_HI,"   prob \n\n");
  47631. X
  47632. X      hi = low+IFS_NUM;
  47633. X      if (hi>numlines) hi = numlines;
  47634. X      for (i = low; i < hi; i++) {
  47635. X     sprintf(msg,"%2d", i+1);
  47636. X     putstring(5+i-low,leftcol,C_GENERAL_HI,msg);
  47637. X     for (j = 0; j < totcols; j++) {
  47638. X        sprintf(msg,"%6.2f",ifs_defn[(i*totcols)+j]);
  47639. X        putstring(-1,-1,C_GENERAL_MED,msg);
  47640. X        }
  47641. X     }
  47642. X      if (hi<numlines) {
  47643. X     putstring(5+IFS_NUM,leftcol,C_GENERAL_HI,"(more)");
  47644. X      }
  47645. X
  47646. X      textcbase = 14;
  47647. X      putstring(5+i-low+1,0,C_GENERAL_HI,ifsprompt);
  47648. X      promptrow = textrow;
  47649. X      promptcol = textcol + textcbase + 1;
  47650. X      temp1[0] = textcbase = 0;
  47651. X      promptfkeys = 1<<6;
  47652. X      i = input_field(0,C_GENERAL_INPUT,temp1,2,promptrow,promptcol,
  47653. X          prompt_checkkey);
  47654. X      if (i<0) {
  47655. X      break;
  47656. X      } else if (i==PAGE_UP) {
  47657. X      low -= IFS_NUM;
  47658. X      if (low<0) low=0;
  47659. X      } else if (i==UP_ARROW) {
  47660. X      low -= 1;
  47661. X      if (low<0) low=0;
  47662. X      } else if (i==DOWN_ARROW) {
  47663. X      low += 1;
  47664. X      if (low+IFS_NUM>numlines) low=numlines-IFS_NUM;
  47665. X      if (low<0) low=0;
  47666. X      } else if (i==PAGE_DOWN) {
  47667. X      low += IFS_NUM;
  47668. X      if (low+IFS_NUM>numlines) low=numlines-IFS_NUM;
  47669. X      if (low<0) low=0;
  47670. X      } else if (i==F6) {
  47671. X      if (get_corners()) {
  47672. X          ret = 1;
  47673. X      }
  47674. X      } else if (i==0) {
  47675. X      if (temp1[0]==0) break;
  47676. X      } else {
  47677. X      continue;
  47678. X      }
  47679. X
  47680. X      putstring(promptrow,promptcol,C_GENERAL_HI,temp1);
  47681. X      if (temp1[0] == 's' || temp1[0] == 'S') {
  47682. X     stackscreen();
  47683. X     filename[0] = 0;
  47684. X     i = field_prompt(0,"Enter the name of the .IFS file to save:",
  47685. X             NULL,filename,60,NULL);
  47686. X     unstackscreen();
  47687. X     if (i != -1) {
  47688. X        if (strchr(filename,'.') == NULL)
  47689. X           strcat(filename,".ifs");
  47690. X        if ((tempfile=fopen(filename,"w")) != NULL) {
  47691. X           for (i = 0; i < numlines; i++) {
  47692. X          for (j = 0; j < totcols; j++)
  47693. X             fprintf(tempfile, "%6.2f", (float)ifs_defn[(i*totcols)+j]);
  47694. X          fprintf(tempfile, "\n");
  47695. X          }
  47696. X           fclose(tempfile);
  47697. X           ifs_changed = 0;
  47698. X           }
  47699. X        else {
  47700. X           static char far msg[]={"Could not create file"};
  47701. X           stopmsg(0,msg);
  47702. X           }
  47703. X        }
  47704. X     continue;
  47705. X     }
  47706. X      i = atoi(temp1) - 1;
  47707. X      if (i >= 0 && i < numlines) {
  47708. X     for (j = 0; j < totcols; j++) {
  47709. X        if (j < totcols-1)
  47710. X           sprintf(msg,"Parameter %c",'a'+j);
  47711. X        else
  47712. X           sprintf(msg,"Probability");
  47713. X        putstring(promptrow+2,25,C_GENERAL_HI,msg);
  47714. X        sprintf(temp1,"%6.2f",(float)ifs_defn[k=(i*totcols)+j]);
  47715. X        if (input_field(1,C_GENERAL_INPUT,temp1,6,
  47716. X                textrow,textcol+1,NULL) < 0)
  47717. X           break;
  47718. X        if (ifs_defn[k] != (ftemp = atof(temp1))) {
  47719. X           ifs_defn[k] = ftemp;
  47720. X           ret = ifs_changed = 1;
  47721. X           }
  47722. X        }
  47723. X     memset(msg,' ',80); msg[81] = 0;
  47724. X     putstring(promptrow+2,0,C_PROMPT_BKGRD,msg);
  47725. X     }
  47726. X      }
  47727. X
  47728. X   helpmode = oldhelpmode;
  47729. X   return(ret);
  47730. X}
  47731. X#endif
  47732. X/* --------------------------------------------------------------------- */
  47733. X/*
  47734. X    get_toggles() is called from FRACTINT.C whenever the 'x' key
  47735. X    is pressed.  This routine prompts for several options,
  47736. X    sets the appropriate variables, and returns the following code
  47737. X    to the calling routine:
  47738. X
  47739. X    -1  routine was ESCAPEd - no need to re-generate the image.
  47740. X     0  nothing changed, or minor variable such as "overwrite=".
  47741. X        No need to re-generate the image.
  47742. X     1  major variable changed (such as "inside=").  Re-generate
  47743. X        the image.
  47744. X
  47745. X    Finally, remember to insert variables in the list *and* check
  47746. X    for them in the same order!!!
  47747. X*/
  47748. X#define LOADCHOICES(X)     {\
  47749. X   static char far tmp[] = { X };\
  47750. X   choices[++k]= tmp;\
  47751. X   }
  47752. Xint get_toggles()
  47753. X{
  47754. X   static char far hdg[]={"        Basic Options\n\
  47755. X(not all combinations make sense)"};
  47756. X   char far *choices[20];
  47757. X   int oldhelpmode;
  47758. X   char prevsavename[81];
  47759. X   struct fullscreenvalues uvalues[25];
  47760. X   int i, j, k;
  47761. X   char old_usr_stdcalcmode;
  47762. X   int old_maxit,old_inside,old_outside,old_soundflag;
  47763. X   int old_logflag,old_biomorph,old_decomp;
  47764. X   int old_fillcolor;
  47765. X   static char *calcmodes[] ={"1","2","g","b","t"};
  47766. X   static char *soundmodes[5]={"yes","no","x","y","z"};
  47767. X
  47768. X   ENTER_OVLY(OVLY_PROMPTS2);
  47769. X
  47770. X   k = -1;
  47771. X
  47772. X   LOADCHOICES("Passes (1, 2, g[uessing], b[oundary trace], t[esseral])");
  47773. X   uvalues[k].type = 'l';
  47774. X   uvalues[k].uval.ch.vlen = 3;
  47775. X   uvalues[k].uval.ch.llen = sizeof(calcmodes)/sizeof(*calcmodes);
  47776. X   uvalues[k].uval.ch.list = calcmodes;
  47777. X   uvalues[k].uval.ch.val = (usr_stdcalcmode == '1') ? 0
  47778. X              : (usr_stdcalcmode == '2') ? 1
  47779. X                          : (usr_stdcalcmode == 'g') ? 2
  47780. X                          : (usr_stdcalcmode == 'b') ? 3 :4 ;
  47781. X   old_usr_stdcalcmode = usr_stdcalcmode;
  47782. X
  47783. X   LOADCHOICES("Floating Point Algorithm");
  47784. X   uvalues[k].type = 'y';
  47785. X   uvalues[k].uval.ch.val = usr_floatflag;
  47786. X
  47787. X   LOADCHOICES("Maximum Iterations (2 to 32767)");
  47788. X   uvalues[k].type = 'i';
  47789. X   uvalues[k].uval.ival = old_maxit = maxit;
  47790. X
  47791. X   LOADCHOICES("Inside Color (<nnn>,maxiter,zmag,bof60,bof61,epscr,star,per)");
  47792. X   uvalues[k].type = 's';
  47793. X   if(inside == -59)
  47794. X      strcpy(uvalues[k].uval.sval,s_zmag);
  47795. X   else if(inside == -60)
  47796. X      strcpy(uvalues[k].uval.sval,s_bof60);
  47797. X   else if(inside == -61)
  47798. X      strcpy(uvalues[k].uval.sval,s_bof61);
  47799. X   else if(inside == -100)
  47800. X      strcpy(uvalues[k].uval.sval,s_epscross);
  47801. X   else if(inside == -101)
  47802. X      strcpy(uvalues[k].uval.sval,s_startrail);
  47803. X   else if(inside == -102)
  47804. X      strcpy(uvalues[k].uval.sval,s_period);
  47805. X   else if(inside == -1)
  47806. X      strcpy(uvalues[k].uval.sval,s_maxiter);
  47807. X   else
  47808. X      sprintf(uvalues[k].uval.sval,"%d",inside);
  47809. X   old_inside = inside;
  47810. X
  47811. X   LOADCHOICES("Outside Color (<nnn>,iter,real,imag,mult,summ)");
  47812. X   uvalues[k].type = 's';
  47813. X   if(outside == -1)
  47814. X      strcpy(uvalues[k].uval.sval,s_iter);
  47815. X   else if(outside == -2)
  47816. X      strcpy(uvalues[k].uval.sval,s_real);
  47817. X   else if(outside == -3)
  47818. X      strcpy(uvalues[k].uval.sval,s_imag);
  47819. X   else if(outside == -4)
  47820. X      strcpy(uvalues[k].uval.sval,s_mult);
  47821. X   else if(outside == -5)
  47822. X      strcpy(uvalues[k].uval.sval,s_sum);
  47823. X   else
  47824. X      sprintf(uvalues[k].uval.sval,"%d",outside);
  47825. X   old_outside = outside;
  47826. X
  47827. X   LOADCHOICES("Savename (.GIF implied)");
  47828. X   uvalues[k].type = 's';
  47829. X   strcpy(prevsavename,savename);
  47830. X   strcpy(uvalues[k].uval.sval,savename);
  47831. X
  47832. X   LOADCHOICES("File Overwrite ('overwrite=')");
  47833. X   uvalues[k].type = 'y';
  47834. X   uvalues[k].uval.ch.val = overwrite;
  47835. X
  47836. X   LOADCHOICES("Sound (no, yes, x, y, z)");
  47837. X   uvalues[k].type = 'l';
  47838. X   uvalues[k].uval.ch.vlen = 3;
  47839. X   uvalues[k].uval.ch.llen = 5;
  47840. X   uvalues[k].uval.ch.list = soundmodes;
  47841. X   uvalues[k].uval.ch.val = 1 + (old_soundflag = soundflag);
  47842. X
  47843. X   if (rangeslen == 0) {
  47844. X      LOADCHOICES("Log Palette (0=no,1=yes,-1=old,+n=cmprsd,-n=sqrt)");
  47845. X      uvalues[k].type = 'i';
  47846. X      }
  47847. X   else {
  47848. X      LOADCHOICES("Log Palette (n/a, ranges= parameter is in effect)");
  47849. X      uvalues[k].type = '*';
  47850. X      }
  47851. X   uvalues[k].uval.ival = old_logflag = LogFlag;
  47852. X
  47853. X   LOADCHOICES("Biomorph Color (-1 means OFF)");
  47854. X   uvalues[k].type = 'i';
  47855. X   uvalues[k].uval.ival = old_biomorph = usr_biomorph;
  47856. X
  47857. X   LOADCHOICES("Decomp Option (2,4,8,..,256, 0=OFF)");
  47858. X   uvalues[k].type = 'i';
  47859. X   uvalues[k].uval.ival = old_decomp = decomp[0];
  47860. X
  47861. X   LOADCHOICES("Fill Color (normal,<nnn>) (works with passes=t and =b)");
  47862. X   uvalues[k].type = 's';
  47863. X   if(fillcolor < 0)
  47864. X      strcpy(uvalues[k].uval.sval,s_normal);
  47865. X   else
  47866. X      sprintf(uvalues[k].uval.sval,"%d",fillcolor);
  47867. X   old_fillcolor = fillcolor;
  47868. X   LOADCHOICES("Orbit delay (0 = none)");
  47869. X   uvalues[k].type = 'i';
  47870. X   uvalues[k].uval.ival = orbit_delay;
  47871. X
  47872. X/*
  47873. X   LOADCHOICES("Antialiasing (0 to 8)");
  47874. X   uvalues[k].type = 'i';
  47875. X   uvalues[k].uval.ival = AntiAliasing;
  47876. X*/
  47877. X
  47878. X   oldhelpmode = helpmode;
  47879. X   helpmode = HELPXOPTS;
  47880. X   i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,0,NULL);
  47881. X   helpmode = oldhelpmode;
  47882. X   if (i < 0) {
  47883. X      EXIT_OVLY;
  47884. X      return(-1);
  47885. X      }
  47886. X
  47887. X   /* now check out the results (*hopefully* in the same order <grin>) */
  47888. X   k = -1;
  47889. X   j = 0;   /* return code */
  47890. X
  47891. X   usr_stdcalcmode = calcmodes[uvalues[++k].uval.ch.val][0];
  47892. X   if (old_usr_stdcalcmode != usr_stdcalcmode) j = 1;
  47893. X
  47894. X   if (uvalues[++k].uval.ch.val != usr_floatflag) {
  47895. X      usr_floatflag = uvalues[k].uval.ch.val;
  47896. X      j = 1;
  47897. X      }
  47898. X
  47899. X   ++k;
  47900. X   maxit = uvalues[k].uval.ival;
  47901. X   if (maxit < 2) maxit = 2;
  47902. X
  47903. X/* 'maxit' is an int so it is always <= 32767, MCP 12-3-91
  47904. X   if (maxit > 32767) maxit = 32767;
  47905. X*/
  47906. X
  47907. X   if (maxit != old_maxit) j = 1;
  47908. X
  47909. X   if(strncmp(strlwr(uvalues[++k].uval.sval),s_zmag,4)==0)
  47910. X      inside = -59;
  47911. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_bof60,5)==0)
  47912. X      inside = -60;
  47913. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_bof61,5)==0)
  47914. X      inside = -61;
  47915. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_epscross,3)==0)
  47916. X      inside = -100;
  47917. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_startrail,4)==0)
  47918. X      inside = -101;
  47919. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_period,3)==0)
  47920. X      inside = -102;
  47921. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_maxiter,5)==0)
  47922. X      inside = -1;
  47923. X   else
  47924. X      inside = atoi(uvalues[k].uval.sval);
  47925. X   if (inside != old_inside) j = 1;
  47926. X
  47927. X   if(strncmp(strlwr(uvalues[++k].uval.sval),s_real,4)==0)
  47928. X      outside = -2;
  47929. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_imag,4)==0)
  47930. X      outside = -3;
  47931. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_mult,4)==0)
  47932. X      outside = -4;
  47933. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_sum,4)==0)
  47934. X      outside = -5;
  47935. X   else if(strncmp(strlwr(uvalues[k].uval.sval),s_iter,4)==0)
  47936. X      outside = -1;
  47937. X   else
  47938. X      outside = atoi(uvalues[k].uval.sval);
  47939. X   if (outside != old_outside) j = 1;
  47940. X
  47941. X   strcpy(savename,uvalues[++k].uval.sval);
  47942. X   if (strcmp(savename,prevsavename))
  47943. X      resave_flag = started_resaves = 0; /* forget pending increment */
  47944. X
  47945. X   overwrite = uvalues[++k].uval.ch.val;
  47946. X
  47947. X   soundflag = uvalues[++k].uval.ch.val - 1;
  47948. X   if (soundflag != old_soundflag && (soundflag > 1 || old_soundflag > 1))
  47949. X      j = 1;
  47950. X
  47951. X   LogFlag = uvalues[++k].uval.ival;
  47952. X   if (LogFlag != old_logflag) j = 1;
  47953. X
  47954. X   usr_biomorph = uvalues[++k].uval.ival;
  47955. X   if (usr_biomorph != old_biomorph) j = 1;
  47956. X
  47957. X   decomp[0] = uvalues[++k].uval.ival;
  47958. X   if (decomp[0] != old_decomp) j = 1;
  47959. X
  47960. X   if(strncmp(strlwr(uvalues[++k].uval.sval),s_normal,4)==0)
  47961. X      fillcolor = -1;
  47962. X   else
  47963. X      fillcolor = atoi(uvalues[k].uval.sval);
  47964. X   if (fillcolor != old_fillcolor) j = 1;
  47965. X
  47966. X   orbit_delay = uvalues[++k].uval.ival;
  47967. X
  47968. X/*
  47969. X   if(AntiAliasing != uvalues[++k].uval.ival) j = 1;
  47970. X   AntiAliasing = uvalues[k].uval.ival;
  47971. X   if(AntiAliasing < 0) AntiAliasing = 0;
  47972. X   if(AntiAliasing > 8) AntiAliasing = 8;
  47973. X*/
  47974. X
  47975. X   EXIT_OVLY;
  47976. X   return(j);
  47977. X}
  47978. X
  47979. X/*
  47980. X    get_toggles2() is similar to get_toggles, invoked by 'y' key
  47981. X*/
  47982. X
  47983. Xint get_toggles2()
  47984. X{
  47985. X   static char far hdg[]={"       Extended Options\n\
  47986. X(not all combinations make sense)"};
  47987. X   char far *choices[20];
  47988. X   int oldhelpmode;
  47989. X
  47990. X   struct fullscreenvalues uvalues[25];
  47991. X   int i, j, k;
  47992. X
  47993. X   int old_rotate_lo,old_rotate_hi;
  47994. X   int old_usr_distest,old_distestwidth;
  47995. X   double old_potparam[3],old_inversion[3];
  47996. X
  47997. X   ENTER_OVLY(OVLY_PROMPTS2);
  47998. X
  47999. X   /* fill up the choices (and previous values) arrays */
  48000. X   k = -1;
  48001. X
  48002. X   LOADCHOICES("Look for finite attractor (0=no,>0=yes,<0=phase)");
  48003. X   uvalues[k].type = 'i';
  48004. X   uvalues[k].uval.ch.val = finattract;
  48005. X
  48006. X   LOADCHOICES("Potential Max Color (0 means off)");
  48007. X   uvalues[k].type = 'i';
  48008. X   uvalues[k].uval.ival = old_potparam[0] = potparam[0];
  48009. X
  48010. X   LOADCHOICES("          Slope");
  48011. X   uvalues[k].type = 'd';
  48012. X   uvalues[k].uval.dval = old_potparam[1] = potparam[1];
  48013. X
  48014. X   LOADCHOICES("          Bailout");
  48015. X   uvalues[k].type = 'i';
  48016. X   uvalues[k].uval.ival = old_potparam[2] = potparam[2];
  48017. X
  48018. X   LOADCHOICES("          16 bit values");
  48019. X   uvalues[k].type = 'y';
  48020. X   uvalues[k].uval.ch.val = pot16bit;
  48021. X
  48022. X   LOADCHOICES("Distance Estimator (0=off, <0=edge, >0=on):");
  48023. X   uvalues[k].type = 'i';
  48024. X   uvalues[k].uval.ival = old_usr_distest = usr_distest;
  48025. X
  48026. X   LOADCHOICES("          width factor:");
  48027. X   uvalues[k].type = 'i';
  48028. X   uvalues[k].uval.ival = old_distestwidth = distestwidth;
  48029. X
  48030. X
  48031. X
  48032. X   LOADCHOICES("Inversion radius or \"auto\" (0 means off)");
  48033. X   LOADCHOICES("          center X coordinate or \"auto\"");
  48034. X   LOADCHOICES("          center Y coordinate or \"auto\"");
  48035. X   k = k - 3;
  48036. X   for (i= 0; i < 3; i++) {
  48037. X      uvalues[++k].type = 's';
  48038. X      if ((old_inversion[i] = inversion[i]) == AUTOINVERT)
  48039. X     sprintf(uvalues[k].uval.sval,"auto");
  48040. X      else
  48041. X     sprintf(uvalues[k].uval.sval,"%g",inversion[i]);
  48042. X      }
  48043. X   LOADCHOICES("  (use fixed radius & center when zooming)");
  48044. X   uvalues[k].type = '*';
  48045. X
  48046. X   LOADCHOICES("Color cycling from color (0 ... 254)");
  48047. X   uvalues[k].type = 'i';
  48048. X   uvalues[k].uval.ival = old_rotate_lo = rotate_lo;
  48049. X
  48050. X   LOADCHOICES("              to   color (1 ... 255)");
  48051. X   uvalues[k].type = 'i';
  48052. X   uvalues[k].uval.ival = old_rotate_hi = rotate_hi;
  48053. X
  48054. X   oldhelpmode = helpmode;
  48055. X   helpmode = HELPYOPTS;
  48056. X   i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,0,NULL);
  48057. X   helpmode = oldhelpmode;
  48058. X   if (i < 0) {
  48059. X      EXIT_OVLY;
  48060. X      return(-1);
  48061. X      }
  48062. X
  48063. X   /* now check out the results (*hopefully* in the same order <grin>) */
  48064. X   k = -1;
  48065. X   j = 0;   /* return code */
  48066. X
  48067. X   if (uvalues[++k].uval.ch.val != finattract) {
  48068. X      finattract = uvalues[k].uval.ch.val;
  48069. X      j = 1;
  48070. X      }
  48071. X
  48072. X   potparam[0] = uvalues[++k].uval.ival;
  48073. X   if (potparam[0] != old_potparam[0]) j = 1;
  48074. X
  48075. X   potparam[1] = uvalues[++k].uval.dval;
  48076. X   if (potparam[0] != 0.0 && potparam[1] != old_potparam[1]) j = 1;
  48077. X
  48078. X   potparam[2] = uvalues[++k].uval.ival;
  48079. X   if (potparam[0] != 0.0 && potparam[2] != old_potparam[2]) j = 1;
  48080. X
  48081. X   if (uvalues[++k].uval.ch.val != pot16bit) {
  48082. X      pot16bit = uvalues[k].uval.ch.val;
  48083. X      if (pot16bit) { /* turned it on */
  48084. X     if (potparam[0] != 0.0) j = 1;
  48085. X     }
  48086. X      else /* turned it off */
  48087. X     if (dotmode != 11) /* ditch the disk video */
  48088. X        enddisk();
  48089. X     else /* keep disk video, but ditch the fraction part at end */
  48090. X        disk16bit = 0;
  48091. X      }
  48092. X
  48093. X   ++k;
  48094. X   usr_distest = (uvalues[k].uval.ival > 32000) ? 32000 : uvalues[k].uval.ival;
  48095. X   if (usr_distest != old_usr_distest) j = 1;
  48096. X   ++k;
  48097. X   distestwidth = uvalues[k].uval.ival;
  48098. X   if (usr_distest && distestwidth != old_distestwidth) j = 1;
  48099. X
  48100. X   for (i = 0; i < 3; i++) {
  48101. X      if (uvalues[++k].uval.sval[0] == 'a' || uvalues[k].uval.sval[0] == 'A')
  48102. X     inversion[i] = AUTOINVERT;
  48103. X      else
  48104. X     inversion[i] = atof(uvalues[k].uval.sval);
  48105. X      if (old_inversion[i] != inversion[i]
  48106. X    && (i == 0 || inversion[0] != 0.0))
  48107. X     j = 1;
  48108. X      }
  48109. X   invert = (inversion[0] == 0.0) ? 0 : 3;
  48110. X   ++k;
  48111. X
  48112. X   rotate_lo = uvalues[++k].uval.ival;
  48113. X   rotate_hi = uvalues[++k].uval.ival;
  48114. X   if (rotate_lo < 0 || rotate_hi > 255 || rotate_lo > rotate_hi) {
  48115. X      rotate_lo = old_rotate_lo;
  48116. X      rotate_hi = old_rotate_hi;
  48117. X      }
  48118. X
  48119. X   EXIT_OVLY;
  48120. X   return(j);
  48121. X}
  48122. X
  48123. X/* --------------------------------------------------------------------- */
  48124. X/*
  48125. X    get_view_params() is called from FRACTINT.C whenever the 'v' key
  48126. X    is pressed.  Return codes are:
  48127. X    -1  routine was ESCAPEd - no need to re-generate the image.
  48128. X     0  minor variable changed.  No need to re-generate the image.
  48129. X     1  View changed.  Re-generate the image.
  48130. X*/
  48131. X
  48132. Xint get_view_params()
  48133. X{
  48134. X   static char far hdg[]={"View Window Options"};
  48135. X   char far *choices[8];
  48136. X
  48137. X   int oldhelpmode;
  48138. X   struct fullscreenvalues uvalues[25];
  48139. X   int i, k;
  48140. X   float old_viewreduction,old_aspectratio;
  48141. X   int old_viewwindow,old_viewcrop,old_viewxdots,old_viewydots;
  48142. X
  48143. X   ENTER_OVLY(OVLY_PROMPTS2);
  48144. X   stackscreen();
  48145. X
  48146. X   old_viewwindow    = viewwindow;
  48147. X   old_viewcrop      = viewcrop;
  48148. X   old_viewreduction = viewreduction;
  48149. X   old_aspectratio   = finalaspectratio;
  48150. X   old_viewxdots     = viewxdots;
  48151. X   old_viewydots     = viewydots;
  48152. X
  48153. Xget_view_restart:
  48154. X   /* fill up the previous values arrays */
  48155. X   k = -1;
  48156. X
  48157. X   LOADCHOICES("Preview display? (no for full screen)");
  48158. X   uvalues[k].type = 'y';
  48159. X   uvalues[k].uval.ch.val = viewwindow;
  48160. X
  48161. X   LOADCHOICES("Auto window size reduction factor");
  48162. X   uvalues[k].type = 'f';
  48163. X   uvalues[k].uval.dval = viewreduction;
  48164. X
  48165. X   LOADCHOICES("Final media overall aspect ratio, y/x");
  48166. X   uvalues[k].type = 'f';
  48167. X   uvalues[k].uval.dval = finalaspectratio;
  48168. X
  48169. X   LOADCHOICES("Crop starting coordinates to new aspect ratio?");
  48170. X   uvalues[k].type = 'y';
  48171. X   uvalues[k].uval.ch.val = viewcrop;
  48172. X
  48173. X   LOADCHOICES("Explicit size x pixels (0 for auto size)");
  48174. X   uvalues[k].type = 'i';
  48175. X   uvalues[k].uval.ival = viewxdots;
  48176. X
  48177. X   LOADCHOICES("              y pixels (0 to base on aspect ratio)");
  48178. X   uvalues[k].type = 'i';
  48179. X   uvalues[k].uval.ival = viewydots;
  48180. X
  48181. X   LOADCHOICES("");
  48182. X   uvalues[k].type = '*';
  48183. X
  48184. X   LOADCHOICES("Press F4 to reset view parameters to defaults.");
  48185. X   uvalues[k].type = '*';
  48186. X
  48187. X   oldhelpmode = helpmode;     /* this prevents HELP from activating */
  48188. X   helpmode = HELPVIEW;
  48189. X   i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,16,NULL);
  48190. X   helpmode = oldhelpmode;     /* re-enable HELP */
  48191. X   if (i < 0) {
  48192. X      viewwindow    = old_viewwindow;
  48193. X      viewcrop        = old_viewcrop;
  48194. X      viewreduction = old_viewreduction;
  48195. X      finalaspectratio = old_aspectratio;
  48196. X      viewxdots     = old_viewxdots;
  48197. X      viewydots     = old_viewydots;
  48198. X      unstackscreen();
  48199. X      EXIT_OVLY;
  48200. X      return(-1);
  48201. X      }
  48202. X
  48203. X   if (i == F4) {
  48204. X      viewwindow = viewxdots = viewydots = 0;
  48205. X      viewreduction = 4.2;
  48206. X      viewcrop = 1;
  48207. X      finalaspectratio = screenaspect;
  48208. X      goto get_view_restart;
  48209. X      }
  48210. X
  48211. X   /* now check out the results (*hopefully* in the same order <grin>) */
  48212. X   k = -1;
  48213. X
  48214. X   viewwindow = uvalues[++k].uval.ch.val;
  48215. X
  48216. X   viewreduction = uvalues[++k].uval.dval;
  48217. X
  48218. X   if ((finalaspectratio = uvalues[++k].uval.dval) == 0)
  48219. X      finalaspectratio = screenaspect;
  48220. X
  48221. X   viewcrop = uvalues[++k].uval.ch.val;
  48222. X
  48223. X   viewxdots = uvalues[++k].uval.ival;
  48224. X   viewydots = uvalues[++k].uval.ival;
  48225. X
  48226. X   if (finalaspectratio != old_aspectratio && viewcrop)
  48227. X      aspectratio_crop(old_aspectratio,finalaspectratio);
  48228. X
  48229. X   i = 0;
  48230. X   if (viewwindow != old_viewwindow
  48231. X      || (viewwindow
  48232. X     && (  viewreduction != old_viewreduction
  48233. X        || finalaspectratio != old_aspectratio
  48234. X        || viewxdots != old_viewxdots
  48235. X        || (viewydots != old_viewydots && viewxdots) ) ) )
  48236. X      i = 1;
  48237. X
  48238. X   unstackscreen();
  48239. X   EXIT_OVLY;
  48240. X   return(i);
  48241. X}
  48242. X
  48243. X/*
  48244. X    get_cmd_string() is called from FRACTINT.C whenever the 'g' key
  48245. X    is pressed.  Return codes are:
  48246. X    -1  routine was ESCAPEd - no need to re-generate the image.
  48247. X     0  parameter changed, no need to regenerate
  48248. X    >0  parameter changed, regenerate
  48249. X*/
  48250. X
  48251. Xint get_cmd_string()
  48252. X{
  48253. X   int oldhelpmode;
  48254. X   int i;
  48255. X   char cmdbuf[61];
  48256. X
  48257. X   ENTER_OVLY(OVLY_PROMPTS2);
  48258. X
  48259. X   oldhelpmode = helpmode;
  48260. X   helpmode = HELPCOMMANDS;
  48261. X   cmdbuf[0] = 0;
  48262. X   i = field_prompt(0,"Enter command string to use.",NULL,cmdbuf,60,NULL);
  48263. X   helpmode = oldhelpmode;
  48264. X   if (i >= 0 && cmdbuf[0] != 0)
  48265. X       i = cmdarg(cmdbuf, 2);
  48266. X
  48267. X   EXIT_OVLY;
  48268. X   return(i);
  48269. X}
  48270. X
  48271. X
  48272. X/* --------------------------------------------------------------------- */
  48273. X
  48274. Xint Distribution = 30, Offset = 0, Slope = 25;
  48275. Xlong con;
  48276. X
  48277. Xstatic char far sf1[] = {"Star Density in Pixels per Star"};
  48278. Xstatic char far sf2[] = {"Percent Clumpiness"};
  48279. Xstatic char far sf3[] = {"Ratio of Dim stars to Bright"};
  48280. Xstatic char far *starfield_prompts[] = {sf1,sf2,sf3};
  48281. X
  48282. Xstatic double starfield_values[4] = {
  48283. X    30.0,100.0,5.0,0.0
  48284. X    };
  48285. X
  48286. Xchar GreyFile[] = "altern.map";
  48287. X
  48288. Xint starfield(void)
  48289. X{
  48290. X   int c;
  48291. X   extern char busy;
  48292. X   busy = 1;
  48293. X   if (starfield_values[0] <   1.0) starfield_values[0] =   1.0;
  48294. X   if (starfield_values[0] > 100.0) starfield_values[0] = 100.0;
  48295. X   if (starfield_values[1] <   1.0) starfield_values[1] =   1.0;
  48296. X   if (starfield_values[1] > 100.0) starfield_values[1] = 100.0;
  48297. X   if (starfield_values[2] <   1.0) starfield_values[2] =   1.0;
  48298. X   if (starfield_values[2] > 100.0) starfield_values[2] = 100.0;
  48299. X
  48300. X   Distribution = (int)(starfield_values[0]);
  48301. X   con    = (long)(((starfield_values[1]) / 100.0) * (1L << 16));
  48302. X   Slope = (int)(starfield_values[2]);
  48303. X
  48304. X   if (ValidateLuts(GreyFile) != 0) {
  48305. X      static char far msg[]={"Unable to load ALTERN.MAP"};
  48306. X      stopmsg(0,msg);
  48307. X      busy = 0;
  48308. X      return(-1);
  48309. X      }
  48310. X   spindac(0,1);         /* load it, but don't spin */
  48311. X   for(row = 0; row < ydots; row++) {
  48312. X      for(col = 0; col < xdots; col++) {
  48313. X     if(keypressed()) {
  48314. X        buzzer(1);
  48315. X        busy = 0;
  48316. X        return(1);
  48317. X        }
  48318. X     c = getcolor(col, row);
  48319. X         if(c == inside)
  48320. X            c = colors-1;
  48321. X     putcolor(col, row, GausianNumber(c, colors));
  48322. X      }
  48323. X   }
  48324. X   buzzer(0);
  48325. X   busy = 0;
  48326. X   return(0);
  48327. X}
  48328. X
  48329. Xint get_starfield_params(void) {
  48330. X   static char far hdg[]={"Starfield Parameters"};
  48331. X   struct fullscreenvalues uvalues[3];
  48332. X   int oldhelpmode, status;
  48333. X   int i;
  48334. X
  48335. X   ENTER_OVLY(OVLY_PROMPTS2);
  48336. X
  48337. X   if(colors < 255) {
  48338. X      static char far msg[]={"starfield requires 256 color mode"};
  48339. X      stopmsg(0,msg);
  48340. X
  48341. X      EXIT_OVLY;
  48342. X      return(-1);
  48343. X   }
  48344. X   for (i = 0; i < 3; i++) {
  48345. X      uvalues[i].uval.dval = starfield_values[i];
  48346. X      uvalues[i].type = 'f';
  48347. X   }
  48348. X   stackscreen();
  48349. X   oldhelpmode = helpmode;
  48350. X   helpmode = HELPSTARFLD;
  48351. X   i = fullscreen_prompt(hdg,3,starfield_prompts,uvalues,0,0,NULL);
  48352. X   helpmode = oldhelpmode;
  48353. X   if (i < 0) {
  48354. X      unstackscreen();
  48355. X      EXIT_OVLY;
  48356. X      return(-1);
  48357. X      }
  48358. X   unstackscreen();
  48359. X
  48360. X   for (i = 0; i < 3; i++)
  48361. X      starfield_values[i] = uvalues[i].uval.dval;
  48362. X
  48363. X   EXIT_OVLY;
  48364. X   return(0);
  48365. X}
  48366. X
  48367. Xint get_a_number(double *x, double *y)
  48368. X{
  48369. X   static char far hdg[]={"Set Cursor Coordinates"};
  48370. X   double x1,y2;
  48371. X   char far *choices[2];
  48372. X
  48373. X   int oldhelpmode;
  48374. X   struct fullscreenvalues uvalues[2];
  48375. X   int i, k;
  48376. X
  48377. X   ENTER_OVLY(OVLY_PROMPTS2);
  48378. X   stackscreen();
  48379. X
  48380. X   /* fill up the previous values arrays */
  48381. X   k = -1;
  48382. X
  48383. X   LOADCHOICES("X coordinate at cursor");
  48384. X   uvalues[k].type = 'd';
  48385. X   uvalues[k].uval.dval = *x;
  48386. X
  48387. X   LOADCHOICES("Y coordinate at cursor");
  48388. X   uvalues[k].type = 'd';
  48389. X   uvalues[k].uval.dval = *y;
  48390. X
  48391. X   i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,25,NULL);
  48392. X   if (i < 0) {
  48393. X      unstackscreen();
  48394. X      EXIT_OVLY;
  48395. X      return(-1);
  48396. X      }
  48397. X
  48398. X   /* now check out the results (*hopefully* in the same order <grin>) */
  48399. X   k = -1;
  48400. X
  48401. X   *x = uvalues[++k].uval.dval;
  48402. X   *y = uvalues[++k].uval.dval;
  48403. X
  48404. X   unstackscreen();
  48405. X   EXIT_OVLY;
  48406. X   return(i);
  48407. X}
  48408. X
  48409. X/* --------------------------------------------------------------------- */
  48410. X
  48411. Xint get_commands()        /* execute commands from file */
  48412. X{
  48413. X   int ret;
  48414. X   FILE *parmfile;
  48415. X   long point;
  48416. X   int oldhelpmode;
  48417. X   ENTER_OVLY(OVLY_PROMPTS2);
  48418. X   ret = 0;
  48419. X   oldhelpmode = helpmode;
  48420. X   helpmode = HELPPARMFILE;
  48421. X   if ((point = get_file_entry(GETPARM,"Parameter Set",
  48422. X                   commandmask,CommandFile,CommandName)) >= 0
  48423. X     && (parmfile = fopen(CommandFile,"rb"))) {
  48424. X      fseek(parmfile,point,SEEK_SET);
  48425. X      ret = load_commands(parmfile);
  48426. X      }
  48427. X   helpmode = oldhelpmode;
  48428. X   EXIT_OVLY;
  48429. X   return(ret);
  48430. X}
  48431. X
  48432. X/* --------------------------------------------------------------------- */
  48433. X
  48434. Xvoid goodbye()            /* we done.  Bail out */
  48435. X{
  48436. X   static char far goodbyemessage[]={"   Thank You for using FRACTINT"};
  48437. X   extern BYTE exitmode;
  48438. X   extern int mode7text;
  48439. X   extern int made_dsktemp;
  48440. X#ifndef XFRACT
  48441. X   union REGS r;
  48442. X#endif
  48443. X
  48444. X#ifdef WINFRACT
  48445. X   return;
  48446. X#endif
  48447. X
  48448. X   setvideotext();
  48449. X#ifdef XFRACT
  48450. X   UnixDone();
  48451. X   printf("\n\n\n%s\n",goodbyemessage); /* printf takes far pointer */
  48452. X#else
  48453. X   r.h.al = (mode7text == 0) ? exitmode : 7;
  48454. X   r.h.ah = 0;
  48455. X   int86(0x10, &r, &r);
  48456. X   printf("\n\n\n%Fs\n",goodbyemessage); /* printf takes far pointer */
  48457. X#endif
  48458. X   movecursor(6,0);
  48459. X   discardgraphics(); /* if any emm/xmm tied up there, release it */
  48460. X   stopslideshow();
  48461. X#ifndef XFRACT
  48462. X   if (made_dsktemp)
  48463. X      remove(diskfilename);
  48464. X#endif
  48465. X   end_help();
  48466. X   if (initbatch == 3) /* exit with error code for batch file */
  48467. X     exit(2);
  48468. X   else if (initbatch == 4)
  48469. X     exit(1);
  48470. X   else
  48471. X     exit(0);
  48472. X}
  48473. X
  48474. X
  48475. X/* --------------------------------------------------------------------- */
  48476. X
  48477. X#ifdef XFRACT
  48478. Xstatic char searchdir[FILE_MAX_DIR];
  48479. Xstatic char searchname[FILE_MAX_PATH];
  48480. Xstatic char searchext[FILE_MAX_EXT];
  48481. Xstatic DIR *currdir = NULL;
  48482. X#endif
  48483. Xstatic int  findfirst(char *path)       /* Find 1st file (or subdir) meeting path/filespec */
  48484. X{
  48485. X#ifndef XFRACT
  48486. X     union REGS regs;
  48487. X     regs.h.ah = 0x1A;           /* Set DTA to filedata */
  48488. X     regs.x.dx = (unsigned)&DTA;
  48489. X     intdos(®s, ®s);
  48490. X     regs.h.ah = 0x4E;           /* Find 1st file meeting path */
  48491. X     regs.x.dx = (unsigned)path;
  48492. X     regs.x.cx = FILEATTR;
  48493. X     intdos(®s, ®s);
  48494. X     return(regs.x.ax);        /* Return error code */
  48495. X#else
  48496. X     if (currdir != NULL) {
  48497. X         closedir(currdir);
  48498. X         currdir = NULL;
  48499. X     }
  48500. X     splitpath(path,NULL,searchdir,searchname,searchext);
  48501. X     if (searchdir[0]=='\0') {
  48502. X         currdir = opendir(".");
  48503. X     } else {
  48504. X         currdir = opendir(searchdir);
  48505. X     }
  48506. X     if (currdir==NULL) {
  48507. X         return -1;
  48508. X     } else {
  48509. X         return findnext();
  48510. X     }
  48511. X#endif
  48512. X}
  48513. X
  48514. Xstatic int  findnext()        /* Find next file (or subdir) meeting above path/filespec */
  48515. X{
  48516. X#ifndef XFRACT
  48517. X     union REGS regs;
  48518. X     regs.h.ah = 0x4F;           /* Find next file meeting path */
  48519. X     regs.x.dx = (unsigned)&DTA;
  48520. X     intdos(®s, ®s);
  48521. X     return(regs.x.ax);
  48522. X#else
  48523. X#ifdef DIRENT
  48524. X     struct dirent *dirEntry;
  48525. X#else
  48526. X     struct direct *dirEntry;
  48527. X#endif
  48528. X     struct stat sbuf;
  48529. X     char thisname[FILE_MAX_PATH];
  48530. X     char tmpname[FILE_MAX_PATH];
  48531. X     char thisext[FILE_MAX_EXT];
  48532. X     while (1) {
  48533. X         dirEntry = readdir(currdir);
  48534. X         if (dirEntry == NULL) {
  48535. X             closedir(currdir);
  48536. X             currdir = NULL;
  48537. X             return -1;
  48538. X         } else if (dirEntry->d_ino != 0) {
  48539. X             splitpath(dirEntry->d_name,NULL,NULL,thisname,thisext);
  48540. X             if ((searchname[0]=='*' || strcmp(searchname,thisname)==0) &&
  48541. X                     (searchext[0]=='*' || strcmp(searchext,thisext)==0)) {
  48542. X                 strncpy(DTA.filename,dirEntry->d_name,20);
  48543. X                 DTA.filename[20]=='\0';
  48544. X                 strcpy(tmpname,searchdir);
  48545. X                 strcat(tmpname,"/");
  48546. X                 strcat(tmpname,dirEntry->d_name);
  48547. X                 stat(tmpname,&sbuf);
  48548. X                 if ((sbuf.st_mode&S_IFMT)==S_IFREG) {
  48549. X                     DTA.attribute = 0;
  48550. X                 } else if ((sbuf.st_mode&S_IFMT)==S_IFDIR) {
  48551. X                     DTA.attribute = SUBDIR;
  48552. X                 } else {
  48553. X                     continue;
  48554. X                 }
  48555. X                 DTA.size = sbuf.st_size;
  48556. X                 return 0;
  48557. X             }
  48558. X         }
  48559. X     }
  48560. X#endif
  48561. X}
  48562. X
  48563. Xint lccompare(VOIDCONSTPTR arg1, VOIDCONSTPTR arg2) /* for qsort */
  48564. X{
  48565. X   return(strncasecmp(*((char **)arg1),*((char **)arg2),40));
  48566. X}
  48567. X
  48568. Xstatic char *masks[] = {"*.pot","*.gif"};
  48569. Xstatic int speedstate;
  48570. X
  48571. Xint getafilename(char *hdg,char *template,char *flname)
  48572. X{
  48573. X   static char far instr[]={"Press F6 for default or environment directory"};
  48574. X   int masklen;
  48575. X   char filename[13];
  48576. X   char speedstr[81];
  48577. X   char tmpmask[FILE_MAX_PATH];   /* used to locate next file in list */
  48578. X   static int numtemplates = 1;
  48579. X   int i,j;
  48580. X   int out;
  48581. X   int retried;
  48582. X   struct CHOICE
  48583. X   {
  48584. X      char name[13];
  48585. X      char type;
  48586. X   }
  48587. X   *choices[MAXNUMFILES];
  48588. X   int attributes[MAXNUMFILES];
  48589. X   int filecount;   /* how many files */
  48590. X   int dircount;    /* how many directories */
  48591. X   int notroot;     /* not the root directory */
  48592. X
  48593. X   char drive[FILE_MAX_DRIVE];
  48594. X   char dir[FILE_MAX_DIR];
  48595. X   char fname[FILE_MAX_FNAME];
  48596. X   char ext[FILE_MAX_EXT];
  48597. X
  48598. X   ENTER_OVLY(OVLY_PROMPTS2);
  48599. X
  48600. X   /* steal existing array for "choices" */
  48601. X   choices[0] = (struct CHOICE *)boxy;
  48602. X   attributes[0] = 1;
  48603. X   for(i=1;i<MAXNUMFILES;i++)
  48604. X   {
  48605. X      choices[i] = choices[i-1] + 1;
  48606. X      attributes[i] = 1;
  48607. X   }
  48608. X
  48609. Xrestart:  /* return here if template or directory changes */
  48610. X
  48611. X   tmpmask[0] = 0;
  48612. X   if(flname[0] == 0)
  48613. X      strcpy(flname,DOTSLASH);
  48614. X   splitpath(flname ,drive,dir,fname,ext);
  48615. X   makepath(filename,""   ,"" ,fname,ext);
  48616. X   retried = 0;
  48617. Xretry_dir:
  48618. X   if (dir[0] == 0)
  48619. X      strcpy(dir,".");
  48620. X   expand_dirname(dir,drive);
  48621. X   makepath(tmpmask,drive,dir,"","");
  48622. X   fix_dirname(tmpmask);
  48623. X   if (retried == 0 && strcmp(dir,SLASH) && strcmp(dir,DOTSLASH))
  48624. X   {
  48625. X      tmpmask[(j = strlen(tmpmask) - 1)] = 0; /* strip trailing \ */
  48626. X      if (strchr(tmpmask,'*') || strchr(tmpmask,'?')
  48627. X    || findfirst(tmpmask) != 0
  48628. X    || (DTA.attribute & SUBDIR) == 0)
  48629. X      {
  48630. X         strcpy(dir,DOTSLASH);
  48631. X     ++retried;
  48632. X     goto retry_dir;
  48633. X      }
  48634. X      tmpmask[j] = SLASHC;
  48635. X   }
  48636. X   if(template[0])
  48637. X   {
  48638. X      numtemplates = 1;
  48639. X      splitpath(template,NULL,NULL,fname,ext);
  48640. X   }
  48641. X   else
  48642. X      numtemplates = sizeof(masks)/sizeof(masks[0]);
  48643. X   filecount = -1;
  48644. X   dircount  = 0;
  48645. X   notroot   = 0;
  48646. X   j = 0;
  48647. X   masklen = strlen(tmpmask);
  48648. X   strcat(tmpmask,"*.*");
  48649. X   out = findfirst(tmpmask);
  48650. X   while(out == 0 && filecount < MAXNUMFILES)
  48651. X   {
  48652. X      if((DTA.attribute & SUBDIR) && strcmp(DTA.filename,"."))
  48653. X      {
  48654. X#ifndef XFRACT
  48655. X     strlwr(DTA.filename);
  48656. X#endif
  48657. X     if(strcmp(DTA.filename,".."))
  48658. X            strcat(DTA.filename,SLASH);
  48659. X     strncpy(choices[++filecount]->name,DTA.filename,13);
  48660. X     choices[filecount]->name[12] = '\0';
  48661. X     choices[filecount]->type = 1;
  48662. X     dircount++;
  48663. X     if(strcmp(DTA.filename,"..")==0)
  48664. X        notroot = 1;
  48665. X      }
  48666. X      out = findnext();
  48667. X   }
  48668. X   tmpmask[masklen] = 0;
  48669. X   if(template[0])
  48670. X      makepath(tmpmask,drive,dir,fname,ext);
  48671. X   do
  48672. X   {
  48673. X      if(numtemplates > 1)
  48674. X     strcpy(&(tmpmask[masklen]),masks[j]);
  48675. X      out = findfirst(tmpmask);
  48676. X      while(out == 0 && filecount < MAXNUMFILES)
  48677. X      {
  48678. X     if(!(DTA.attribute & SUBDIR))
  48679. X     {
  48680. X        strlwr(DTA.filename);
  48681. X        strncpy(choices[++filecount]->name,DTA.filename,13);
  48682. X        choices[filecount]->type = 0;
  48683. X     }
  48684. X     out = findnext();
  48685. X      }
  48686. X   }
  48687. X   while (++j < numtemplates);
  48688. X   if (++filecount == 0)
  48689. X   {
  48690. X      strcpy(choices[filecount]->name,"*nofiles*");
  48691. X      choices[filecount]->type = 0;
  48692. X      ++filecount;
  48693. X   }
  48694. X   qsort(choices,filecount,sizeof(char *),lccompare); /* sort type list */
  48695. X   if(notroot == 0 && dir[0] && dir[0] != SLASHC) /* must be in root directory */
  48696. X   {
  48697. X      splitpath(tmpmask,drive,dir,fname,ext);
  48698. X      strcpy(dir,SLASH);
  48699. X      makepath(tmpmask,drive,dir,fname,ext);
  48700. X   }
  48701. X   if(numtemplates > 1)
  48702. X      strcat(tmpmask," *.pot");
  48703. X   strcpy(temp1,hdg);
  48704. X   strcat(temp1,"\nTemplate: ");
  48705. X   strcat(temp1,tmpmask);
  48706. X   strcpy(speedstr,filename);
  48707. X   if (speedstr[0] == 0)
  48708. X   {
  48709. X      for (i=0; i<filecount; i++) /* find first file */
  48710. X     if (choices[i]->type == 0)
  48711. X        break;
  48712. X      if (i >= filecount)
  48713. X     i = 0;
  48714. X   }
  48715. X   i = fullscreen_choice(8,temp1,NULL,instr,filecount,(char **)choices,
  48716. X          attributes,5,99,12,i,NULL,speedstr,filename_speedstr,check_f6_key);
  48717. X   if (i==-F6)
  48718. X   {
  48719. X      static int lastdir=0;
  48720. X      if (lastdir==0)
  48721. X      {
  48722. X     strcpy(dir,fract_dir1);
  48723. X      }
  48724. X      else
  48725. X      {
  48726. X     strcpy(dir,fract_dir2);
  48727. X      }
  48728. X      fix_dirname(dir);
  48729. X       makepath(flname,drive,dir,"","");
  48730. X       lastdir = 1-lastdir;
  48731. X       goto restart;
  48732. X   }
  48733. X   if (i < 0)
  48734. X   {
  48735. X      EXIT_OVLY;
  48736. X      return(-1);
  48737. X   }
  48738. X   if(speedstr[0] == 0 || speedstate == MATCHING)
  48739. X   {
  48740. X      if(choices[i]->type)
  48741. X      {
  48742. X     if(strcmp(choices[i]->name,"..") == 0) /* go up a directory */
  48743. X     {
  48744. X        if(strcmp(dir,DOTSLASH) == 0)
  48745. X           strcpy(dir,DOTDOTSLASH);
  48746. X        else
  48747. X        {
  48748. X           char *s;
  48749. X           if(s = strrchr(dir,SLASHC)) /* trailing slash */
  48750. X           {
  48751. X          *s = 0;
  48752. X          if(s = strrchr(dir,SLASHC))
  48753. X             *(s+1) = 0;
  48754. X           }
  48755. X        }
  48756. X     }
  48757. X     else  /* go down a directory */
  48758. X        strcat(dir,choices[i]->name);
  48759. X     fix_dirname(dir);
  48760. X     makepath(flname,drive,dir,"","");
  48761. X     goto restart;
  48762. X      }
  48763. X      splitpath(choices[i]->name,NULL,NULL,fname,ext);
  48764. X      makepath(flname,drive,dir,fname,ext);
  48765. X   }
  48766. X   else
  48767. X   {
  48768. X      if (speedstate == SEARCHPATH
  48769. X    && strchr(speedstr,'*') == 0 && strchr(speedstr,'?') == 0
  48770. X    && findfirst(speedstr) == 0
  48771. X    && (DTA.attribute & SUBDIR)) /* it is a directory */
  48772. X     speedstate = TEMPLATE;
  48773. X      if(speedstate == TEMPLATE)
  48774. X      {
  48775. X     /* extract from tempstr the pathname and template information,
  48776. X        being careful not to overwrite drive and directory if not
  48777. X        newly specified */
  48778. X     char drive1[FILE_MAX_DRIVE];
  48779. X     char dir1[FILE_MAX_DIR];
  48780. X     char fname1[FILE_MAX_FNAME];
  48781. X     char ext1[FILE_MAX_EXT];
  48782. X     splitpath(speedstr,drive1,dir1,fname1,ext1);
  48783. X     if(drive1[0])
  48784. X        strcpy(drive,drive1);
  48785. X     if(dir1[0])
  48786. X        strcpy(dir,dir1);
  48787. X     makepath(flname,drive,dir,fname1,ext1);
  48788. X     if(strchr(fname1,'*') || strchr(fname1,'?') ||
  48789. X         strchr(ext1  ,'*') || strchr(ext1  ,'?'))
  48790. X        makepath(template,"","",fname1,ext1);
  48791. X     else if(isadirectory(flname))
  48792. X        fix_dirname(flname);
  48793. X     goto restart;
  48794. X      }
  48795. X      else /* speedstate == SEARCHPATH */
  48796. X      {
  48797. X     char fullpath[80];
  48798. X      /* if (strchr(speedstr,'.') == NULL)
  48799. X        strcat(speedstr,".gif"); */
  48800. X     findpath(speedstr,fullpath);
  48801. X     if(fullpath[0])
  48802. X        strcpy(flname,fullpath);
  48803. X     else
  48804. X     {  /* failed, make diagnostic useful: */
  48805. X        strcpy(flname,speedstr);
  48806. X        if (strchr(speedstr,SLASHC) == NULL)
  48807. X        {
  48808. X           splitpath(speedstr,NULL,NULL,fname,ext);
  48809. X           makepath(flname,drive,dir,fname,ext);
  48810. X        }
  48811. X     }
  48812. X      }
  48813. X   }
  48814. X   EXIT_OVLY;
  48815. X   return(0);
  48816. X}
  48817. X
  48818. Xstatic int check_f6_key(int curkey,int choice)
  48819. X{
  48820. X   if (curkey == F6)
  48821. X      return 0-F6;
  48822. X   return 0;
  48823. X}
  48824. X
  48825. Xstatic int filename_speedstr(int row, int col, int vid,
  48826. X                 char *speedstring, int speed_match)
  48827. X{
  48828. X   extern char speed_prompt[];
  48829. X   char *prompt;
  48830. X   if ( strchr(speedstring,':')
  48831. X     || strchr(speedstring,'*') || strchr(speedstring,'*')
  48832. X     || strchr(speedstring,'?')) {
  48833. X      speedstate = TEMPLATE;  /* template */
  48834. X      prompt = "File Template";
  48835. X      }
  48836. X   else if (speed_match) {
  48837. X      speedstate = SEARCHPATH; /* does not match list */
  48838. X      prompt = "Search Path for";
  48839. X      }
  48840. X   else {
  48841. X      speedstate = MATCHING;
  48842. X      prompt = speed_prompt;
  48843. X      }
  48844. X   putstring(row,col,vid,prompt);
  48845. X   return(strlen(prompt));
  48846. X}
  48847. X
  48848. Xstatic int isadirectory(char *s)
  48849. X{
  48850. X   if(strchr(s,'*') || strchr(s,'?'))
  48851. X      return(0); /* for my purposes, not a directory */
  48852. X   if(findfirst(s) != 0) /* couldn't find it */
  48853. X   {
  48854. X      /* any better ideas?? */
  48855. X      if(strchr(s,SLASHC)) /* we'll guess it is a directory */
  48856. X     return(1);
  48857. X      else
  48858. X     return(0);  /* no slashes - we'll guess it's a file */
  48859. X   }
  48860. X   else if(DTA.attribute & SUBDIR)
  48861. X      return(1);   /* we're SURE it's a directory */
  48862. X   else
  48863. X      return(0);
  48864. X}
  48865. X
  48866. X
  48867. X#ifndef XFRACT    /* This routine moved to unix.c so we can use it in hc.c */
  48868. Xint splitpath(char *template,char *drive,char *dir,char *fname,char *ext)
  48869. X{
  48870. X   int length;
  48871. X   int len;
  48872. X   int offset;
  48873. X   char *tmp;
  48874. X
  48875. X   if(drive)
  48876. X      drive[0] = 0;
  48877. X   if(dir)
  48878. X      dir[0]   = 0;
  48879. X   if(fname)
  48880. X      fname[0] = 0;
  48881. X   if(ext)
  48882. X      ext[0]   = 0;
  48883. X
  48884. X   if((length = strlen(template)) == 0)
  48885. X      return(0);
  48886. X   offset = 0;
  48887. X
  48888. X   /* get drive */
  48889. X   if(length >= 2)
  48890. X      if(template[1] == ':')
  48891. X      {
  48892. X     if(drive)
  48893. X     {
  48894. X        drive[0] = template[offset++];
  48895. X        drive[1] = template[offset++];
  48896. X        drive[2] = 0;
  48897. X     }
  48898. X     else
  48899. X     {
  48900. X        offset++;
  48901. X        offset++;
  48902. X     }
  48903. X      }
  48904. X
  48905. X   /* get dir */
  48906. X   if(offset < length)
  48907. X   {
  48908. X      tmp = strrchr(template,SLASHC);
  48909. X      if(tmp)
  48910. X      {
  48911. X     tmp++;  /* first character after slash */
  48912. X     len = tmp - &template[offset];
  48913. X     if(len >=0 && len < 80 && dir)
  48914. X        strncpy(dir,&template[offset],len);
  48915. X     if(len < 80 && dir)
  48916. X        dir[len] = 0;
  48917. X     offset += len;
  48918. X      }
  48919. X   }
  48920. X   else
  48921. X      return(0);
  48922. X
  48923. X   /* get fname */
  48924. X   if(offset < length)
  48925. X   {
  48926. X      tmp = strrchr(template,'.');
  48927. X      if(tmp < strrchr(template,SLASHC) || tmp < strrchr(template,':'))
  48928. X     tmp = 0; /* in this case the '.' must be a directory */
  48929. X      if(tmp)
  48930. X      {
  48931. X     tmp++; /* first character past "." */
  48932. X     len = tmp - &template[offset];
  48933. X     if((len > 0) && (offset+len < length) && fname)
  48934. X     {
  48935. X        strncpy(fname,&template[offset],len);
  48936. X        fname[len] = 0;
  48937. X     }
  48938. X     offset += len;
  48939. X     if((offset < length) && ext)
  48940. X        strcpy(ext,&template[offset]);
  48941. X      }
  48942. X      else if((offset < length) && fname)
  48943. X     strcpy(fname,&template[offset]);
  48944. X   }
  48945. X   return(0);
  48946. X}
  48947. X#endif
  48948. X
  48949. Xmakepath(char *template,char *drive,char *dir,char *fname,char *ext)
  48950. X{
  48951. X#ifndef XFRACT
  48952. X   strcpy(template,drive);
  48953. X   strcat(template,dir);
  48954. X#else
  48955. X   strcpy(template,dir);
  48956. X#endif
  48957. X   strcat(template,fname);
  48958. X   strcat(template,ext);
  48959. X   return(0);
  48960. X}
  48961. X
  48962. X
  48963. X/* fix up directory names */
  48964. Xstatic void fix_dirname(char *dirname)
  48965. X{
  48966. X   int length;
  48967. X   /* scrub white space from end for safety */
  48968. X   length = strlen(dirname); /* index of last character */
  48969. X   while (--length >= 0 && isspace(dirname[length])) { }
  48970. X   dirname[++length] = 0;
  48971. X   /* make sure dirname ends with a slash */
  48972. X   if(length == 0 || dirname[length-1] != SLASHC)
  48973. X      strcat(dirname,SLASH);
  48974. X}
  48975. X
  48976. Xstatic int expand_dirname(char *dirname,char *drive)
  48977. X{
  48978. X   fix_dirname(dirname);
  48979. X   if (dirname[0] != SLASHC) {
  48980. X      char buf[81],curdir[81];
  48981. X#ifndef XFRACT
  48982. X      union REGS regs;
  48983. X      struct SREGS sregs;
  48984. X      curdir[0] = 0;
  48985. X      regs.h.ah = 0x47; /* get current directory */
  48986. X      regs.h.dl = 0;
  48987. X      if (drive[0] && drive[0] != ' ')
  48988. X     regs.h.dl = tolower(drive[0])-'a'+1;
  48989. X      regs.x.si = (unsigned int) &curdir[0];
  48990. X      segread(&sregs);
  48991. X      intdosx(®s, ®s, &sregs);
  48992. X#else
  48993. X      getwd(curdir);
  48994. X#endif
  48995. X      strcat(curdir,SLASH);
  48996. X      while (strncmp(dirname,DOTSLASH,2) == 0) {
  48997. X     strcpy(buf,&dirname[2]);
  48998. X     strcpy(dirname,buf);
  48999. X     }
  49000. X      while (strncmp(dirname,DOTDOTSLASH,3) == 0) {
  49001. X     char *s;
  49002. X     curdir[strlen(curdir)-1] = 0; /* strip trailing slash */
  49003. X     if (s = strrchr(curdir,SLASHC))
  49004. X        *s = 0;
  49005. X     strcat(curdir,SLASH);
  49006. X     strcpy(buf,&dirname[3]);
  49007. X     strcpy(dirname,buf);
  49008. X     }
  49009. X      strcpy(buf,dirname);
  49010. X      dirname[0] = 0;
  49011. X      if (curdir[0] != SLASHC)
  49012. X     strcpy(dirname,SLASH);
  49013. X      strcat(dirname,curdir);
  49014. X      strcat(dirname,buf);
  49015. X      }
  49016. X   return(0);
  49017. X}
  49018. X
  49019. X#define LOADPROMPTS(X)     {\
  49020. X   static char far tmp[] = { X };\
  49021. X   prompts[++nump]= tmp;\
  49022. X   }
  49023. X
  49024. Xint get_corners()
  49025. X{
  49026. X   struct fullscreenvalues values[15];
  49027. X   char far *prompts[15];
  49028. X   static char far xprompt[]={"          X"};
  49029. X   static char far yprompt[]={"          Y"};
  49030. X   static char far zprompt[]={"          Z"};
  49031. X   int i,nump,prompt_ret;
  49032. X   int cmag,transp3d;
  49033. X   double Xctr,Yctr,Mag;
  49034. X   BYTE ousemag;
  49035. X   double oxxmin,oxxmax,oyymin,oyymax,oxx3rd,oyy3rd;
  49036. X   double ozzmin,ozzmax,ottmin,ottmax;
  49037. X   /* note that hdg[15] is used for non-transparent heading: */
  49038. X   static char far hdg[]={"Transparent 3d Image Coordinates"};
  49039. X   int oldhelpmode;
  49040. X
  49041. X   transp3d = (Transparent3D && fractalspecific[fractype].orbitcalc == Formula);
  49042. X   oldhelpmode = helpmode;
  49043. X   ousemag = usemag;
  49044. X   oxxmin = xxmin; oxxmax = xxmax;
  49045. X   oyymin = yymin; oyymax = yymax;
  49046. X   oxx3rd = xx3rd; oyy3rd = yy3rd;
  49047. X   ozzmin = zzmin; ozzmax = zzmax;
  49048. X   ottmin = ttmin; ottmax = ttmax;
  49049. X
  49050. Xgc_loop:
  49051. X   for (i = 0; i < 15; ++i)
  49052. X      values[i].type = 'd'; /* most values on this screen are type d */
  49053. X   cmag = (!transp3d && usemag && cvtcentermag(&Xctr, &Yctr, &Mag));
  49054. X
  49055. X   nump = -1;
  49056. X   if (cmag) {
  49057. X      LOADPROMPTS("Center X");
  49058. X      values[nump].uval.dval = Xctr;
  49059. X      LOADPROMPTS("Center Y");
  49060. X      values[nump].uval.dval = Yctr;
  49061. X      LOADPROMPTS("Magnification");
  49062. X      values[nump].uval.dval = Mag;
  49063. X      LOADPROMPTS("");
  49064. X      values[nump].type = '*';
  49065. X      LOADPROMPTS("Press F7 to switch to \"corners\" mode");
  49066. X      values[nump].type = '*';
  49067. X      }
  49068. X
  49069. X   else {
  49070. X      LOADPROMPTS("Top-Left Corner");
  49071. X      values[nump].type = '*';
  49072. X      prompts[++nump] = xprompt;
  49073. X      values[nump].uval.dval = xxmin;
  49074. X      prompts[++nump] = yprompt;
  49075. X      values[nump].uval.dval = yymax;
  49076. X      if (transp3d) {
  49077. X         prompts[++nump] = zprompt;
  49078. X         values[nump].uval.dval = zzmin;
  49079. X      }
  49080. X      LOADPROMPTS("Bottom-Right Corner");
  49081. X      values[nump].type = '*';
  49082. X      prompts[++nump] = xprompt;
  49083. X      values[nump].uval.dval = xxmax;
  49084. X      prompts[++nump] = yprompt;
  49085. X      values[nump].uval.dval = yymin;
  49086. X      if (transp3d) {
  49087. X     prompts[++nump] = zprompt;
  49088. X     values[nump].uval.dval = zzmax;
  49089. X     }
  49090. X      if (transp3d) {
  49091. X     LOADPROMPTS("Time Step");
  49092. X     values[nump].type = '*';
  49093. X     LOADPROMPTS("          From");
  49094. X     values[nump].uval.dval = ttmin;
  49095. X     LOADPROMPTS("          To");
  49096. X     values[nump].uval.dval = ttmax;
  49097. X     }
  49098. X      else {
  49099. X     if (xxmin == xx3rd && yymin == yy3rd)
  49100. X        xx3rd = yy3rd = 0;
  49101. X     LOADPROMPTS("Bottom-left (zeros for top-left X, bottom-right Y)");
  49102. X     values[nump].type = '*';
  49103. X     prompts[++nump] = xprompt;
  49104. X     values[nump].uval.dval = xx3rd;
  49105. X     prompts[++nump] = yprompt;
  49106. X     values[nump].uval.dval = yy3rd;
  49107. X     LOADPROMPTS("Press F7 to switch to \"center-mag\" mode");
  49108. X     values[nump].type = '*';
  49109. X     }
  49110. X      }
  49111. X
  49112. X   LOADPROMPTS("Press F4 to reset to type default values");
  49113. X   values[nump].type = '*';
  49114. X
  49115. X   oldhelpmode = helpmode;
  49116. X   helpmode = HELPCOORDS;
  49117. X   prompt_ret = fullscreen_prompt((transp3d) ? hdg : &hdg[15],
  49118. X             nump+1, prompts, values, 0,
  49119. X             (transp3d) ? 0x10 : 0x90, /* function keys */
  49120. X             NULL);
  49121. X   helpmode = oldhelpmode;
  49122. X
  49123. X   if (prompt_ret < 0) {
  49124. X      usemag = ousemag;
  49125. X      xxmin = oxxmin; xxmax = oxxmax;
  49126. X      yymin = oyymin; yymax = oyymax;
  49127. X      xx3rd = oxx3rd; yy3rd = oyy3rd;
  49128. X      zzmin = ozzmin; zzmax = ozzmax;
  49129. X      ttmin = ottmin; ttmax = ottmax;
  49130. X      return -1;
  49131. X      }
  49132. X
  49133. X   if (prompt_ret == F4) { /* reset to type defaults */
  49134. X      xx3rd = xxmin = curfractalspecific->xmin;
  49135. X      xxmax        = curfractalspecific->xmax;
  49136. X      yy3rd = yymin = curfractalspecific->ymin;
  49137. X      yymax        = curfractalspecific->ymax;
  49138. X      if (viewcrop && finalaspectratio != screenaspect)
  49139. X     aspectratio_crop(screenaspect,finalaspectratio);
  49140. X      goto gc_loop;
  49141. X      }
  49142. X
  49143. X   if (cmag) {
  49144. X      if ( values[0].uval.dval != Xctr
  49145. X    || values[1].uval.dval != Yctr
  49146. X    || values[2].uval.dval != Mag) {
  49147. X     double radius,width;
  49148. X     radius = 1.0 / values[2].uval.dval;
  49149. X     width = radius * (1.0 / screenaspect);
  49150. X     yymax           = values[1].uval.dval + radius;
  49151. X     yy3rd = yymin = values[1].uval.dval - radius;
  49152. X     xxmax           = values[0].uval.dval + width;
  49153. X     xx3rd = xxmin = values[0].uval.dval - width;
  49154. X     }
  49155. X      }
  49156. X
  49157. X   else {
  49158. X      nump = 1;
  49159. X      xxmin = values[nump++].uval.dval;
  49160. X      yymax = values[nump++].uval.dval;
  49161. X      if (transp3d)
  49162. X     zzmin = values[nump++].uval.dval;
  49163. X      nump++;
  49164. X      xxmax = values[nump++].uval.dval;
  49165. X      yymin = values[nump++].uval.dval;
  49166. X      if (transp3d)
  49167. X     zzmax = values[nump++].uval.dval;
  49168. X      nump++;
  49169. X      if (transp3d) {
  49170. X     ttmin = values[nump++].uval.dval;
  49171. X     ttmax = values[nump++].uval.dval;
  49172. X     }
  49173. X      else {
  49174. X     xx3rd = values[nump++].uval.dval;
  49175. X     yy3rd = values[nump++].uval.dval;
  49176. X     if (xx3rd == 0 && yy3rd == 0) {
  49177. X        xx3rd = xxmin;
  49178. X        yy3rd = yymin;
  49179. X        }
  49180. X     }
  49181. X      }
  49182. X
  49183. X   if (prompt_ret == F7) { /* toggle corners/center-mag mode */
  49184. X      if (usemag == 0)
  49185. X     if (cvtcentermag(&Xctr, &Yctr, &Mag) == 0)
  49186. X     {
  49187. X        static char far msg[] = 
  49188. X           {"Corners rotated or stretched, can't use center-mag"};
  49189. X        stopmsg(0,msg);
  49190. X     }   
  49191. X     else
  49192. X        usemag = 1;
  49193. X      else
  49194. X     usemag = 0;
  49195. X      goto gc_loop;
  49196. X      }
  49197. X
  49198. X   return((xxmin == oxxmin && xxmax == oxxmax
  49199. X    && yymin == oyymin && yymax == oyymax
  49200. X    && xx3rd == oxx3rd && yy3rd == oyy3rd
  49201. X    && zzmin == ozzmin && zzmax == ozzmax
  49202. X    && ttmin == ottmin && ttmax == ottmax) ? 0 : 1);
  49203. X}
  49204. SHAR_EOF
  49205. $TOUCH -am 1028230093 prompts2.c &&
  49206. chmod 0644 prompts2.c ||
  49207. echo "restore of prompts2.c failed"
  49208. set `wc -c prompts2.c`;Wc_c=$1
  49209. if test "$Wc_c" != "49042"; then
  49210.     echo original size 49042, current size $Wc_c
  49211. fi
  49212. # ============= realdos.c ==============
  49213. echo "x - extracting realdos.c (Text)"
  49214. sed 's/^X//' << 'SHAR_EOF' > realdos.c &&
  49215. X/*
  49216. X    Miscellaneous C routines used only in DOS Fractint.
  49217. X*/
  49218. X
  49219. X#include <string.h>
  49220. X#include <stdio.h>
  49221. X#ifndef XFRACT
  49222. X#include <dos.h>
  49223. X#include <io.h>
  49224. X#include <process.h>
  49225. X#endif
  49226. X#include <sys/types.h>
  49227. X#include <sys/stat.h>
  49228. X#include <fcntl.h>
  49229. X#include <math.h>
  49230. X#include <stdlib.h>
  49231. X#include <ctype.h>
  49232. X#include "fractint.h"
  49233. X#include "fractype.h"
  49234. X#include "helpdefs.h"
  49235. X#include "prototyp.h"
  49236. X
  49237. X/* routines in this module    */
  49238. X
  49239. Xstatic int menu_checkkey(int curkey,int choice);
  49240. X
  49241. X/* uncomment following for book version */
  49242. X/* #define WAITE */
  49243. X
  49244. Xint release=1820; /* this has 2 implied decimals; increment it every synch */
  49245. Xint patchlevel=0; /* patchlevel for DOS version */
  49246. Xint xrelease=203;
  49247. X
  49248. X/* fullscreen_choice options */
  49249. X#define CHOICERETURNKEY 1
  49250. X#define CHOICEMENU    2
  49251. X#define CHOICEHELP    4
  49252. X
  49253. Xextern char diskfilename[];
  49254. Xextern int using_jiim;
  49255. Xextern int  xdots, ydots, sxdots, sydots, sxoffs, syoffs, vxdots;
  49256. Xextern int  colors;
  49257. Xextern int  dotmode;
  49258. Xextern int  oktoprint;
  49259. Xextern int  textrow, textcol, textrbase, textcbase;
  49260. Xextern int  debugflag;
  49261. Xextern int  fractype;
  49262. Xextern int  calc_status;
  49263. Xextern double param[];
  49264. Xextern int  tabmode;
  49265. Xextern int  color_dark,color_medium,color_bright;
  49266. Xextern int  lookatmouse;
  49267. Xextern int  gotrealdac;
  49268. Xextern int  reallyega;
  49269. Xextern SEGTYPE  extraseg;
  49270. Xextern int  active_system;
  49271. Xextern int  first_init;
  49272. Xextern int initbatch;        /* 1 if batch run (no kbd)  */
  49273. X
  49274. X
  49275. X/* int stopmsg(flags,message) displays message and waits for a key:
  49276. X     message should be a max of 9 lines with \n's separating them;
  49277. X       no leading or trailing \n's in message;
  49278. X       no line longer than 76 chars for best appearance;
  49279. X     flag options:
  49280. X       &1 if already in text display mode, stackscreen is not called
  49281. X      and message is displayed at (12,0) instead of (4,0)
  49282. X       &2 if continue/cancel indication is to be returned;
  49283. X      when not set, "Any key to continue..." is displayed
  49284. X      when set, "Escape to cancel, any other key to continue..."
  49285. X      -1 is returned for cancel, 0 for continue
  49286. X       &4 set to suppress buzzer
  49287. X       &8 for Fractint for Windows & parser - use a fixed pitch font
  49288. X      &16 for info only message (green box instead of red in DOS vsn)
  49289. X   */
  49290. Xint stopmsg (int flags, CHAR far *msg)
  49291. X{
  49292. X   int ret,toprow,color,savelookatmouse;
  49293. X   if (active_system == 0 /* DOS */
  49294. X     && first_init) {      /* & cmdfiles hasn't finished 1st try */
  49295. X      setvideotext();
  49296. X      buzzer(2);
  49297. X      putstring(0,0,15,"*** Error during startup:");
  49298. X      putstring(2,0,15,msg);
  49299. X      movecursor(8,0);
  49300. X#ifdef XFRACT
  49301. X      sleep(1);
  49302. X      UnixDone();
  49303. X#endif
  49304. X      exit(1);
  49305. X      }
  49306. X   if (initbatch == 1) { /* in batch mode */
  49307. X      initbatch = 4; /* used to set errorlevel */
  49308. X      return (-1);
  49309. X      }
  49310. X   ret = 0;
  49311. X   savelookatmouse = lookatmouse;
  49312. X   lookatmouse = -13;
  49313. X   if ((flags & 1))
  49314. X      blankrows(toprow=12,10,7);
  49315. X   else {
  49316. X      stackscreen();
  49317. X      toprow = 4;
  49318. X      movecursor(4,0);
  49319. X      }
  49320. X   textcbase = 2; /* left margin is 2 */
  49321. X   putstring(toprow,0,7,msg);
  49322. X   if (flags & 2)
  49323. X      putstring(textrow+2,0,7,"Escape to cancel, any other key to continue...");
  49324. X   else
  49325. X      putstring(textrow+2,0,7,"Any key to continue...");
  49326. X   textcbase = 0; /* back to full line */
  49327. X   color = (flags & 16) ? C_STOP_INFO : C_STOP_ERR;
  49328. X   setattr(toprow,0,color,(textrow+1-toprow)*80);
  49329. X   movecursor(25,80);    /* cursor off */
  49330. X   if ((flags & 4) == 0)
  49331. X      buzzer((flags & 16) ? 0 : 2);
  49332. X   while (keypressed()) /* flush any keyahead */
  49333. X      getakey();
  49334. X   if (getakeynohelp() == ESC)
  49335. X      ret = -1;
  49336. X   if ((flags & 1))
  49337. X      blankrows(toprow,10,7);
  49338. X   else
  49339. X      unstackscreen();
  49340. X   lookatmouse = savelookatmouse;
  49341. X   return ret;
  49342. X}
  49343. X
  49344. X
  49345. Xstatic char far *temptextsave = NULL;
  49346. Xstatic int  textxdots,textydots;
  49347. X
  49348. X/* texttempmsg(msg) displays a text message of up to 40 characters, waits
  49349. X      for a key press, restores the prior display, and returns (without
  49350. X      eating the key).
  49351. X      It works in almost any video mode - does nothing in some very odd cases
  49352. X      (HCGA hi-res with old bios), or when there isn't 10k of temp mem free. */
  49353. Xint texttempmsg(char *msgparm)
  49354. X{
  49355. X   if (showtempmsg(msgparm))
  49356. X      return(-1);
  49357. X#ifndef XFRACT
  49358. X   while (!keypressed()) {} /* wait for a keystroke but don't eat it */
  49359. X#else
  49360. X   waitkeypressed(0); /* wait for a keystroke but don't eat it */
  49361. X#endif
  49362. X   cleartempmsg();
  49363. X   return(0);
  49364. X}
  49365. X
  49366. Xvoid freetempmsg()
  49367. X{
  49368. X   if(temptextsave != NULL)
  49369. X      farmemfree(temptextsave);
  49370. X   temptextsave = NULL;
  49371. X}
  49372. X
  49373. Xint showtempmsg(char *msgparm)
  49374. X{
  49375. X   static long size = 0;
  49376. X   extern int color_dark,color_medium;
  49377. X   CHAR msg[41];
  49378. X   BYTE buffer[640];
  49379. X   char far *fartmp;
  49380. X   BYTE far *fontptr;
  49381. X   BYTE *bufptr;
  49382. X   int i,j,k,xrepeat,yrepeat,fontchar,charnum;
  49383. X   int save_sxoffs,save_syoffs;
  49384. X   strncpy(msg,msgparm,40);
  49385. X   msg[40] = 0; /* ensure max message len of 40 chars */
  49386. X   if (dotmode == 11) { /* disk video, screen in text mode, easy */
  49387. X      dvid_status(0,msg);
  49388. X      return(0);
  49389. X      }
  49390. X   if ((fontptr = findfont(0)) == NULL) { /* old bios, no font table? */
  49391. X      if (oktoprint == 0           /* can't printf */
  49392. X    || sxdots > 640 || sydots > 200) /* not willing to trust char cell size */
  49393. X     return(-1); /* sorry, message not displayed */
  49394. X      textydots = 8;
  49395. X      textxdots = sxdots;
  49396. X      }
  49397. X   else {
  49398. X      xrepeat = (sxdots >= 640) ? 2 : 1;
  49399. X      yrepeat = (sydots >= 300) ? 2 : 1;
  49400. X      textxdots = strlen(msg) * xrepeat * 8;
  49401. X      textydots = yrepeat * 8;
  49402. X      }
  49403. X   /* worst case needs 10k */
  49404. X   if(temptextsave !=NULL)
  49405. X      if(size != (long)textxdots * (long)textydots)
  49406. X         freetempmsg();      
  49407. X   size = (long)textxdots * (long)textydots;
  49408. X   save_sxoffs = sxoffs;
  49409. X   save_syoffs = syoffs;
  49410. X   sxoffs = syoffs = 0;
  49411. X   if(temptextsave == NULL) /* only save screen first time called */
  49412. X   {
  49413. X      if ((temptextsave = farmemalloc(size)) == NULL)
  49414. X         return(-1); /* sorry, message not displayed */
  49415. X      fartmp = temptextsave;
  49416. X      for (i = 0; i < textydots; ++i) {
  49417. X         get_line(i,0,textxdots-1,buffer);
  49418. X         for (j = 0; j < textxdots; ++j) /* copy it out to far memory */
  49419. X         *(fartmp++) = buffer[j];
  49420. X         }
  49421. X      }
  49422. X   if (fontptr == NULL) { /* bios must do it for us */
  49423. X      home();
  49424. X      printf(msg);
  49425. X      }
  49426. X   else { /* generate the characters */
  49427. X      find_special_colors(); /* get color_dark & color_medium set */
  49428. X      for (i = 0; i < 8; ++i) {
  49429. X     memset(buffer,color_dark,640);
  49430. X     bufptr = buffer;
  49431. X     charnum = -1;
  49432. X     while (msg[++charnum] != 0) {
  49433. X        fontchar = *(fontptr + msg[charnum]*8 + i);
  49434. X        for (j = 0; j < 8; ++j) {
  49435. X           for (k = 0; k < xrepeat; ++k) {
  49436. X          if ((fontchar & 0x80) != 0)
  49437. X             *bufptr = color_medium;
  49438. X          ++bufptr;
  49439. X          }
  49440. X           fontchar <<= 1;
  49441. X           }
  49442. X        }
  49443. X     for (j = 0; j < yrepeat; ++j)
  49444. X        put_line(i*yrepeat+j,0,textxdots-1,buffer);
  49445. X     }
  49446. X      }
  49447. X   sxoffs = save_sxoffs;
  49448. X   syoffs = save_syoffs;
  49449. X   return(0);
  49450. X}
  49451. X
  49452. Xvoid cleartempmsg()
  49453. X{
  49454. X   BYTE buffer[640];
  49455. X   char far *fartmp;
  49456. X   int i,j;
  49457. X   int save_sxoffs,save_syoffs;
  49458. X   if (dotmode == 11) /* disk video, easy */
  49459. X      dvid_status(0,"");
  49460. X   else if (temptextsave != NULL) {
  49461. X      save_sxoffs = sxoffs;
  49462. X      save_syoffs = syoffs;
  49463. X      sxoffs = syoffs = 0;
  49464. X      fartmp = temptextsave;
  49465. X      for (i = 0; i < textydots; ++i) {
  49466. X     for (j = 0; j < textxdots; ++j) /* copy back from far memory */
  49467. X        buffer[j] = *(fartmp++);
  49468. X     put_line(i,0,textxdots-1,buffer);
  49469. X     }
  49470. X     if(using_jiim == 0)  /* jiim frees memory with freetempmsg() */
  49471. X     {
  49472. X         farmemfree(temptextsave);
  49473. X         temptextsave = NULL;
  49474. X      }
  49475. X      sxoffs = save_sxoffs;
  49476. X      syoffs = save_syoffs;
  49477. X      }
  49478. X}
  49479. X
  49480. X
  49481. Xvoid blankrows(int row,int rows,int attr)
  49482. X{
  49483. X   char buf[81];
  49484. X   memset(buf,' ',80);
  49485. X   buf[80] = 0;
  49486. X   while (--rows >= 0)
  49487. X      putstring(row++,0,attr,buf);
  49488. X   }
  49489. X
  49490. X
  49491. Xvoid helptitle()
  49492. X{
  49493. X   char msg[80],buf[80];
  49494. X   setclear(); /* clear the screen */
  49495. X#ifdef XFRACT
  49496. X   sprintf(msg,"XFRACTINT  Version %d.%02d (FRACTINT Version %d.%02d)",
  49497. X           xrelease/100,xrelease%100, release/100,release%100);
  49498. X   putstringcenter(0,0,80,C_TITLE,msg);
  49499. X#else
  49500. X#ifdef WAITE
  49501. X   release=1821;
  49502. X   patchlevel = 0;
  49503. X   sprintf(msg,"Special FRACTINT Version %d.%01d",release/100,(release%100)/10);
  49504. X#else
  49505. X   sprintf(msg,"FRACTINT Version %d.%01d",release/100,(release%100)/10);
  49506. X#endif
  49507. X   if (release%10) {
  49508. X      sprintf(buf,"%01d",release%10);
  49509. X      strcat(msg,buf);
  49510. X      }
  49511. X#ifndef XFRACT
  49512. X   if (patchlevel) {
  49513. X      sprintf(buf," Patch %d",patchlevel);
  49514. X      strcat(msg,buf);
  49515. X      }
  49516. X#endif
  49517. X#ifdef WAITE /* realdos.c */
  49518. X   strcat(msg," for the Waite Group's Fractal Creations 2nd Ed.");
  49519. X#endif /* WAITE - realdos.c */
  49520. X   putstringcenter(0,0,80,C_TITLE,msg);
  49521. X#ifdef WAITE
  49522. X   return;
  49523. X#endif
  49524. X#endif
  49525. X/* uncomment next for production executable: */
  49526. X    return;
  49527. X   /*NOTREACHED*/
  49528. X   if (debugflag == 3002) return;
  49529. X/* putstring(0,2,C_TITLE_DEV,"Development Version"); */
  49530. X/* replace above by next after creating production release, for release source */
  49531. X   putstring(0,3,C_TITLE_DEV, "Customized Version"); 
  49532. X   putstring(0,55,C_TITLE_DEV,"Not for Public Release");
  49533. X}
  49534. X
  49535. X
  49536. Xint putstringcenter(int row, int col, int width, int attr, char far *msg)
  49537. X{
  49538. X   char buf[81];
  49539. X   int i,j,k;
  49540. X   i = 0;
  49541. X#ifdef XFRACT
  49542. X   if (width==80) width=79; /* Some systems choke in column 80 */
  49543. X#endif
  49544. X   while (msg[i]) ++i; /* strlen for a far */
  49545. X   if (i == 0) return(-1);
  49546. X   j = (width - i) / 2;
  49547. X   j -= (width + 10 - i) / 20; /* when wide a bit left of center looks better */
  49548. X   memset(buf,' ',width);
  49549. X   buf[width] = 0;
  49550. X   i = 0;
  49551. X   k = j;
  49552. X   while (msg[i]) buf[k++] = msg[i++]; /* strcpy for a far */
  49553. X   putstring(row,col,attr,buf);
  49554. X   return j;
  49555. X}
  49556. X
  49557. X
  49558. X#ifndef XFRACT
  49559. Xstatic int screenctr=-1;
  49560. X#else
  49561. Xstatic int screenctr=0;
  49562. X#endif
  49563. X#define MAXSCREENS 3
  49564. Xstatic BYTE far *savescreen[MAXSCREENS];
  49565. Xstatic int saverc[MAXSCREENS+1];
  49566. Xstatic FILE *savescf=NULL;
  49567. Xstatic char scsvfile[]="fractscr.tmp";
  49568. Xextern int text_type;
  49569. Xextern int textaddr;
  49570. X
  49571. Xvoid stackscreen()
  49572. X{
  49573. X#ifndef XFRACT
  49574. X   BYTE far *vidmem;
  49575. X   int savebytes;
  49576. X   int i;
  49577. X   BYTE far *ptr;
  49578. X   char buf[100];
  49579. X   saverc[screenctr+1] = textrow*80 + textcol;
  49580. X   if (++screenctr) { /* already have some stacked */
  49581. X     static char far msg[]={"stackscreen overflow"};
  49582. X      if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
  49583. X     stopmsg(1,msg);
  49584. X     exit(1);
  49585. X     }
  49586. X      vidmem = MK_FP(textaddr,0);
  49587. X      savebytes = (text_type == 0) ? 4000 : 16384;
  49588. X      if ((ptr = savescreen[i] = farmemalloc((long)savebytes)))
  49589. X     far_memcpy(ptr,vidmem,savebytes);
  49590. X      else {
  49591. X     if (savescf == NULL) { /* create file just once */
  49592. X        if ((savescf = fopen(scsvfile,"wb")) == NULL)
  49593. X           goto fileproblem;
  49594. X        if (fwrite(buf,MAXSCREENS,16384,savescf) != 16384)
  49595. X           goto fileproblem;
  49596. X        fclose(savescf);
  49597. X        if ((savescf = fopen(scsvfile,"r+b")) == NULL) {
  49598. X        static char far msg[]={"insufficient memory, aborting"};
  49599. Xfileproblem:   stopmsg(1,msg);
  49600. X           exit(1);
  49601. X           }
  49602. X        }
  49603. X     fseek(savescf,(long)(savebytes*i),SEEK_SET);
  49604. X     while (--savebytes >= 0)
  49605. X        putc(*(vidmem++),savescf);
  49606. X     }
  49607. X      setclear();
  49608. X      }
  49609. X   else
  49610. X      setfortext();
  49611. X#else
  49612. X   int i;
  49613. X   BYTE far *ptr;
  49614. X   saverc[screenctr+1] = textrow*80 + textcol;
  49615. X   if (++screenctr) { /* already have some stacked */
  49616. X         static char far msg[]={"stackscreen overflow"};
  49617. X      if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
  49618. X         stopmsg(1,msg);
  49619. X         exit(1);
  49620. X         }
  49621. X      if (ptr = savescreen[i] = farmemalloc(sizeof(int *)))
  49622. X         savecurses(ptr);
  49623. X      else {
  49624. X         stopmsg(1,msg);
  49625. X         exit(1);
  49626. X        }
  49627. X      setclear();
  49628. X      }
  49629. X   else
  49630. X      setfortext();
  49631. X#endif
  49632. X}
  49633. X
  49634. Xvoid unstackscreen()
  49635. X{
  49636. X#ifndef XFRACT
  49637. X   char far *vidmem;
  49638. X   int savebytes;
  49639. X   BYTE far *ptr;
  49640. X   textrow = saverc[screenctr] / 80;
  49641. X   textcol = saverc[screenctr] % 80;
  49642. X   if (--screenctr >= 0) { /* unstack */
  49643. X      vidmem = MK_FP(textaddr,0);
  49644. X      savebytes = (text_type == 0) ? 4000 : 16384;
  49645. X      if ((ptr = savescreen[screenctr])) {
  49646. X     far_memcpy(vidmem,ptr,savebytes);
  49647. X     farmemfree(ptr);
  49648. X     }
  49649. X      else {
  49650. X     fseek(savescf,(long)(savebytes*screenctr),SEEK_SET);
  49651. X     while (--savebytes >= 0)
  49652. X        *(vidmem++) = getc(savescf);
  49653. X     }
  49654. X      }
  49655. X   else
  49656. X      setforgraphics();
  49657. X   movecursor(-1,-1);
  49658. X#else
  49659. X   BYTE far *ptr;
  49660. X   textrow = saverc[screenctr] / 80;
  49661. X   textcol = saverc[screenctr] % 80;
  49662. X   if (--screenctr >= 0) { /* unstack */
  49663. X      ptr = savescreen[screenctr];
  49664. X      restorecurses(ptr);
  49665. X      farmemfree(ptr);
  49666. X      }
  49667. X   else
  49668. X      setforgraphics();
  49669. X   movecursor(-1,-1);
  49670. X#endif
  49671. X}
  49672. X
  49673. Xvoid discardscreen()
  49674. X{
  49675. X   if (--screenctr >= 0) { /* unstack */
  49676. X      if (savescreen[screenctr])
  49677. X     farmemfree(savescreen[screenctr]);
  49678. X      }
  49679. X   else
  49680. X      discardgraphics();
  49681. X}
  49682. X
  49683. X
  49684. X/* --------------------------------------------------------------------- */
  49685. X
  49686. Xchar speed_prompt[]="Speed key string";
  49687. X
  49688. Xint fullscreen_choice(
  49689. X    int options,         /* &2 use menu coloring scheme           */
  49690. X                 /* &4 include F1 for help in instructions */
  49691. X                 /* &8 add caller's instr after normal set */
  49692. X    char far *hdg,         /* heading info, \n delimited           */
  49693. X    char far *hdg2,         /* column heading or NULL               */
  49694. X    char far *instr,     /* instructions, \n delimited, or NULL    */
  49695. X    int numchoices,      /* How many choices in list           */
  49696. X    char **choices,      /* array of choice strings            */
  49697. X    int *attributes,     /* &3: 0 normal color, 1,3 highlight      */
  49698. X                 /* &256 marks a dummy entry           */
  49699. X    int boxwidth,         /* box width, 0 for calc (in items)       */
  49700. X    int boxdepth,         /* box depth, 0 for calc, 99 for max      */
  49701. X    int colwidth,         /* data width of a column, 0 for calc     */
  49702. X    int current,         /* start with this item               */
  49703. X    void (*formatitem)(),/* routine to display an item or NULL     */
  49704. X    char *speedstring,   /* returned speed key value, or NULL >[30]*/
  49705. X    int (*speedprompt)(),/* routine to display prompt or NULL      */
  49706. X    int (*checkkey)()    /* routine to check keystroke or NULL     */
  49707. X)
  49708. X   /* return is: n>=0 for choice n selected,
  49709. X         -1 for escape
  49710. X          k for checkkey routine return value k (if not 0 nor -1)
  49711. X      speedstring[0] != 0 on return if string is present
  49712. X      */
  49713. X{
  49714. Xstatic char far choiceinstr1a[]="Use the cursor keys to highlight your selection";
  49715. Xstatic char far choiceinstr1b[]="Use the cursor keys or type a value to make a selection";
  49716. Xstatic char far choiceinstr2a[]="Press ENTER for highlighted choice, or ESCAPE to back out";
  49717. Xstatic char far choiceinstr2b[]="Press ENTER for highlighted choice, ESCAPE to back out, or F1 for help";
  49718. Xstatic char far choiceinstr2c[]="Press ENTER for highlighted choice, or F1 for help";
  49719. X
  49720. X   int titlelines,titlewidth;
  49721. X   int reqdrows;
  49722. X   int topleftrow,topleftcol;
  49723. X   int topleftchoice;
  49724. X   int speedrow;  /* speed key prompt */
  49725. X   int boxitems;  /* boxwidth*boxdepth */
  49726. X   int curkey,increment,rev_increment;
  49727. X   int redisplay;
  49728. X   int i,j,k;
  49729. X   char far *charptr;
  49730. X   char buf[81];
  49731. X   int speed_match = 0;
  49732. X   char curitem[81];
  49733. X   char *itemptr;
  49734. X   int ret,savelookatmouse;
  49735. X
  49736. X   savelookatmouse = lookatmouse;
  49737. X   lookatmouse = 0;
  49738. X   ret = -1;
  49739. X   if (speedstring
  49740. X     && (i = strlen(speedstring)) > 0) { /* preset current to passed string */
  49741. X      current = 0;
  49742. X      while (current < numchoices
  49743. X    && (k = strncasecmp(speedstring,choices[current],i)) > 0)
  49744. X     ++current;
  49745. X      if (k < 0 && current > 0)  /* oops - overshot */
  49746. X     --current;
  49747. X      if (current >= numchoices) /* bumped end of list */
  49748. X     current = numchoices - 1;
  49749. X      }
  49750. X
  49751. X   while (1) {
  49752. X      if (current >= numchoices)  /* no real choice in the list? */
  49753. X     goto fs_choice_end;
  49754. X      if ((attributes[current] & 256) == 0)
  49755. X     break;
  49756. X      ++current;          /* scan for a real choice */
  49757. X      }
  49758. X
  49759. X   titlelines = titlewidth = 0;
  49760. X   if (hdg) {
  49761. X      charptr = hdg;          /* count title lines, find widest */
  49762. X      i = 0;
  49763. X      titlelines = 1;
  49764. X      while (*charptr) {
  49765. X     if (*(charptr++) == '\n') {
  49766. X        ++titlelines;
  49767. X        i = -1;
  49768. X        }
  49769. X     if (++i > titlewidth)
  49770. X        titlewidth = i;
  49771. X     }
  49772. X      }
  49773. X
  49774. X   if (colwidth == 0)          /* find widest column */
  49775. X      for (i = 0; i < numchoices; ++i)
  49776. X     if (strlen(choices[i]) > colwidth)
  49777. X        colwidth = strlen(choices[i]);
  49778. X
  49779. X   /* title(1), blank(1), hdg(n), blank(1), body(n), blank(1), instr(?) */
  49780. X   reqdrows = 3;          /* calc rows available */
  49781. X   if (hdg)
  49782. X      reqdrows += titlelines + 1;
  49783. X   if (instr) {           /* count instructions lines */
  49784. X      charptr = instr;
  49785. X      ++reqdrows;
  49786. X      while (*charptr)
  49787. X     if (*(charptr++) == '\n')
  49788. X        ++reqdrows;
  49789. X      if ((options & 8))      /* show std instr too */
  49790. X     reqdrows += 2;
  49791. X      }
  49792. X   else
  49793. X      reqdrows += 2;          /* standard instructions */
  49794. X   if (speedstring) ++reqdrows;   /* a row for speedkey prompt */
  49795. X   if (boxdepth > (i = 25 - reqdrows)) /* limit the depth to max */
  49796. X      boxdepth = i;
  49797. X   if (boxwidth == 0) {       /* pick box width and depth */
  49798. X      if (numchoices <= i - 2) {  /* single column is 1st choice if we can */
  49799. X     boxdepth = numchoices;
  49800. X     boxwidth = 1;
  49801. X     }
  49802. X      else {              /* sort-of-wide is 2nd choice */
  49803. X     boxwidth = 60 / (colwidth + 1);
  49804. X     if (boxwidth == 0
  49805. X       || (boxdepth = (numchoices+boxwidth-1)/boxwidth) > i - 2) {
  49806. X        boxwidth = 80 / (colwidth + 1); /* last gasp, full width */
  49807. X        if ((boxdepth = (numchoices+boxwidth-1)/boxwidth) > i)
  49808. X           boxdepth = i;
  49809. X        }
  49810. X     }
  49811. X      }
  49812. X   if ((i = 77 / boxwidth - colwidth) > 3) /* spaces to add @ left each choice */
  49813. X      i = 3;
  49814. X   j = boxwidth * (colwidth += i) + i;       /* overall width of box */
  49815. X   if (j < titlewidth+2)
  49816. X      j = titlewidth + 2;
  49817. X   if (j > 80)
  49818. X      j = 80;
  49819. X   if (j <= 70 && boxwidth == 2) {       /* special case makes menus nicer */
  49820. X      ++j;
  49821. X      ++colwidth;
  49822. X      }
  49823. X   k = (80 - j) / 2;               /* center the box */
  49824. X   k -= (90 - j) / 20;
  49825. X   topleftcol = k + i;               /* column of topleft choice */
  49826. X   i = (25 - reqdrows - boxdepth) / 2;
  49827. X   i -= i / 4;                   /* higher is better if lots extra */
  49828. X   topleftrow = 3 + titlelines + i;       /* row of topleft choice */
  49829. X
  49830. X   /* now set up the overall display */
  49831. X   helptitle();                /* clear, display title line */
  49832. X   setattr(1,0,C_PROMPT_BKGRD,24*80);       /* init rest to background */
  49833. X   for (i = topleftrow-1-titlelines; i < topleftrow+boxdepth+1; ++i)
  49834. X      setattr(i,k,C_PROMPT_LO,j);       /* draw empty box */
  49835. X   if (hdg) {
  49836. X      textcbase = (80 - titlewidth) / 2;   /* set left margin for putstring */
  49837. X      textcbase -= (90 - titlewidth) / 20; /* put heading into box */
  49838. X      putstring(topleftrow-titlelines-1,0,C_PROMPT_HI,hdg);
  49839. X      textcbase = 0;
  49840. X      }
  49841. X   if (hdg2)                   /* display 2nd heading */
  49842. X      putstring(topleftrow-1,topleftcol,C_PROMPT_MED,hdg2);
  49843. X   i = topleftrow + boxdepth + 1;
  49844. X   if (instr == NULL || (options & 8)) {   /* display default instructions */
  49845. X      if (i < 20) ++i;
  49846. X      if (speedstring) {
  49847. X     speedrow = i;
  49848. X     *speedstring = 0;
  49849. X     if (++i < 22) ++i;
  49850. X     }
  49851. X      putstringcenter(i++,0,80,C_PROMPT_BKGRD,
  49852. X        (speedstring) ? choiceinstr1b : choiceinstr1a);
  49853. X      putstringcenter(i++,0,80,C_PROMPT_BKGRD,
  49854. X        (options&CHOICEMENU) ? choiceinstr2c
  49855. X        : ((options&CHOICEHELP) ? choiceinstr2b : choiceinstr2a));
  49856. X      }
  49857. X   if (instr) {                /* display caller's instructions */
  49858. X      charptr = instr;
  49859. X      j = -1;
  49860. X      while ((buf[++j] = *(charptr++)))
  49861. X     if (buf[j] == '\n') {
  49862. X        buf[j] = 0;
  49863. X        putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
  49864. X        j = -1;
  49865. X        }
  49866. X      putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
  49867. X      }
  49868. X
  49869. X   boxitems = boxwidth * boxdepth;
  49870. X   topleftchoice = 0;               /* pick topleft for init display */
  49871. X   while (current - topleftchoice >= boxitems
  49872. X     || (current - topleftchoice > boxitems/2
  49873. X     && topleftchoice + boxitems < numchoices))
  49874. X      topleftchoice += boxwidth;
  49875. X   redisplay = 1;
  49876. X
  49877. X   while (1) { /* main loop */
  49878. X
  49879. X      if (redisplay) {                 /* display the current choices */
  49880. X     if ((options & CHOICEMENU) == 0) {
  49881. X        memset(buf,' ',80);
  49882. X        buf[boxwidth*colwidth] = 0;
  49883. X        for (i = (hdg2) ? 0 : -1; i <= boxdepth; ++i)  /* blank the box */
  49884. X           putstring(topleftrow+i,topleftcol,C_PROMPT_LO,buf);
  49885. X        }
  49886. X     for (i = 0; i+topleftchoice < numchoices && i < boxitems; ++i) {
  49887. X        /* display the choices */
  49888. X        if ((k = attributes[j = i+topleftchoice] & 3) == 1)
  49889. X           k = C_PROMPT_LO;
  49890. X        else if (k == 3)
  49891. X           k = C_PROMPT_HI;
  49892. X        else
  49893. X           k = C_PROMPT_MED;
  49894. X        if (formatitem)
  49895. X           (*formatitem)(j,charptr=buf);
  49896. X        else
  49897. X           charptr = choices[j];
  49898. X        putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  49899. X              k,charptr);
  49900. X        }
  49901. X     /***
  49902. X     ... format differs for summary/detail, whups, force box width to
  49903. X     ...  be 72 when detail toggle available?  (2 grey margin each
  49904. X     ...  side, 1 blue margin each side)
  49905. X     ***/
  49906. X     if (topleftchoice > 0 && hdg2 == NULL)
  49907. X        putstring(topleftrow-1,topleftcol,C_PROMPT_LO,"(more)");
  49908. X     if (topleftchoice + boxitems < numchoices)
  49909. X        putstring(topleftrow+boxdepth,topleftcol,C_PROMPT_LO,"(more)");
  49910. X     redisplay = 0;
  49911. X     }
  49912. X
  49913. X      i = current - topleftchoice;         /* highlight the current choice */
  49914. X      if (formatitem)
  49915. X     (*formatitem)(current,itemptr=curitem);
  49916. X      else
  49917. X     itemptr = choices[current];
  49918. X      putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  49919. X        C_CHOICE_CURRENT,itemptr);
  49920. X
  49921. X      if (speedstring) {             /* show speedstring if any */
  49922. X     memset(buf,' ',80);
  49923. X     buf[80] = 0;
  49924. X     putstring(speedrow,0,C_PROMPT_BKGRD,buf);
  49925. X     if (*speedstring) {             /* got a speedstring on the go */
  49926. X        putstring(speedrow,15,C_CHOICE_SP_INSTR," ");
  49927. X        if (speedprompt)
  49928. X           j = speedprompt(speedrow,16,C_CHOICE_SP_INSTR,speedstring,speed_match);
  49929. X        else {
  49930. X           putstring(speedrow,16,C_CHOICE_SP_INSTR,speed_prompt);
  49931. X           j = strlen(speed_prompt);
  49932. X           }
  49933. X        strcpy(buf,speedstring);
  49934. X        i = strlen(buf);
  49935. X        while (i < 30)
  49936. X           buf[i++] = ' ';
  49937. X        buf[i] = 0;
  49938. X        putstring(speedrow,16+j,C_CHOICE_SP_INSTR," ");
  49939. X        putstring(speedrow,17+j,C_CHOICE_SP_KEYIN,buf);
  49940. X        movecursor(speedrow,17+j+strlen(speedstring));
  49941. X        }
  49942. X     else
  49943. X        movecursor(25,80);
  49944. X     }
  49945. X      else
  49946. X     movecursor(25,80);
  49947. X
  49948. X#ifndef XFRACT
  49949. X      while (!keypressed()) { } /* enables help */
  49950. X#else
  49951. X      waitkeypressed(0); /* enables help */
  49952. X#endif
  49953. X      curkey = getakey();
  49954. X#ifdef XFRACT
  49955. X      if (curkey==F10) curkey=')';
  49956. X      if (curkey==F9) curkey='(';
  49957. X      if (curkey==F8) curkey='*';
  49958. X#endif
  49959. X
  49960. X      i = current - topleftchoice;         /* unhighlight current choice */
  49961. X      if ((k = attributes[current] & 3) == 1)
  49962. X     k = C_PROMPT_LO;
  49963. X      else if (k == 3)
  49964. X     k = C_PROMPT_HI;
  49965. X      else
  49966. X     k = C_PROMPT_MED;
  49967. X      putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  49968. X        k,itemptr);
  49969. X
  49970. X      increment = 0;
  49971. X      switch (curkey) {              /* deal with input key */
  49972. X     case ENTER:
  49973. X     case ENTER_2:
  49974. X        ret = current;
  49975. X        goto fs_choice_end;
  49976. X     case ESC:
  49977. X        goto fs_choice_end;
  49978. X     case DOWN_ARROW:
  49979. X     case DOWN_ARROW_2:
  49980. X        rev_increment = 0 - (increment = boxwidth);
  49981. X        break;
  49982. X     case UP_ARROW:
  49983. X     case UP_ARROW_2:
  49984. X        increment = 0 - (rev_increment = boxwidth);
  49985. X        break;
  49986. X     case RIGHT_ARROW:
  49987. X     case RIGHT_ARROW_2:
  49988. X        if (boxwidth == 1) break;
  49989. X        increment = 1; rev_increment = -1;
  49990. X        break;
  49991. X     case LEFT_ARROW:
  49992. X     case LEFT_ARROW_2:
  49993. X        if (boxwidth == 1) break;
  49994. X        increment = -1; rev_increment = 1;
  49995. X        break;
  49996. X     case PAGE_UP:
  49997. X        if (numchoices > boxitems) {
  49998. X           topleftchoice -= boxitems;
  49999. X           increment = -boxitems;
  50000. X           rev_increment = boxwidth;
  50001. X           redisplay = 1;
  50002. X           }
  50003. X        break;
  50004. X     case PAGE_DOWN:
  50005. X        if (numchoices > boxitems) {
  50006. X           topleftchoice += boxitems;
  50007. X           increment = boxitems;
  50008. X           rev_increment = -boxwidth;
  50009. X           redisplay = 1;
  50010. X           }
  50011. X        break;
  50012. X     case CTL_HOME:
  50013. X     case HOME:
  50014. X        current = -1;
  50015. X        increment = rev_increment = 1;
  50016. X        break;
  50017. X     case CTL_END:
  50018. X     case END:
  50019. X        current = numchoices;
  50020. X        increment = rev_increment = -1;
  50021. X        break;
  50022. X     default:
  50023. X        if (checkkey) {
  50024. X           if ((ret = (*checkkey)(curkey,current)) < -1 || ret > 0)
  50025. X          goto fs_choice_end;
  50026. X           if (ret == -1)
  50027. X          redisplay = -1;
  50028. X           }
  50029. X        ret = -1;
  50030. X        if (speedstring) {
  50031. X           i = strlen(speedstring);
  50032. X           if (curkey == 8 && i > 0) /* backspace */
  50033. X          speedstring[--i] = 0;
  50034. X           if (33 <= curkey && curkey <= 126 && i < 30) {
  50035. X          curkey = tolower(curkey);
  50036. X          speedstring[i] = curkey;
  50037. X          speedstring[++i] = 0;
  50038. X          }
  50039. X           if (i > 0) {         /* locate matching type */
  50040. X          current = 0;
  50041. X          while (current < numchoices
  50042. X            && (speed_match = strncasecmp(speedstring,choices[current],i)) > 0)
  50043. X             ++current;
  50044. X          if (speed_match < 0 && current > 0)  /* oops - overshot */
  50045. X             --current;
  50046. X          if (current >= numchoices) /* bumped end of list */
  50047. X             current = numchoices - 1;
  50048. X          }
  50049. X           }
  50050. X        break;
  50051. X     }
  50052. X
  50053. X      if (increment) {            /* apply cursor movement */
  50054. X     current += increment;
  50055. X     if (speedstring)        /* zap speedstring */
  50056. X        speedstring[0] = 0;
  50057. X     }
  50058. X      while (1) {            /* adjust to a non-comment choice */
  50059. X     if (current < 0 || current >= numchoices)
  50060. X         increment = rev_increment;
  50061. X     else if ((attributes[current] & 256) == 0)
  50062. X         break;
  50063. X     current += increment;
  50064. X     }
  50065. X      if (topleftchoice > numchoices - boxitems)
  50066. X     topleftchoice = ((numchoices+boxwidth-1)/boxwidth)*boxwidth - boxitems;
  50067. X      if (topleftchoice < 0)
  50068. X     topleftchoice = 0;
  50069. X      while (current < topleftchoice) {
  50070. X     topleftchoice -= boxwidth;
  50071. X     redisplay = 1;
  50072. X     }
  50073. X      while (current >= topleftchoice + boxitems) {
  50074. X     topleftchoice += boxwidth;
  50075. X     redisplay = 1;
  50076. X     }
  50077. X      }
  50078. X
  50079. Xfs_choice_end:
  50080. X   lookatmouse = savelookatmouse;
  50081. X   return(ret);
  50082. X
  50083. X}
  50084. X
  50085. X
  50086. X#ifndef XFRACT
  50087. X/* case independent version of strncmp */
  50088. Xint strncasecmp(char *s,char *t,int ct)
  50089. X{
  50090. X   for(; (tolower(*s) == tolower(*t)) && --ct ; s++,t++)
  50091. X      if(*s == '\0')
  50092. X     return(0);
  50093. X   return(tolower(*s) - tolower(*t));
  50094. X}
  50095. X#endif
  50096. X
  50097. X
  50098. Xstatic int menutype;
  50099. X#define MENU_HDG 3
  50100. X#define MENU_ITEM 1
  50101. X
  50102. Xint main_menu(int fullmenu)
  50103. X{
  50104. X   char *choices[44]; /* 2 columns * 22 rows */
  50105. X   int attributes[44];
  50106. X   int choicekey[44];
  50107. X   int i;
  50108. X   int nextleft,nextright;
  50109. X   int oldtabmode,oldhelpmode;
  50110. X   oldtabmode = tabmode;
  50111. X   oldhelpmode = helpmode;
  50112. Xtop:
  50113. X   menutype = fullmenu;
  50114. X   tabmode = 0;
  50115. X   for (i = 0; i < 44; ++i) {
  50116. X      attributes[i] = 256;
  50117. X      choices[i] = "";
  50118. X      choicekey[i] = -1;
  50119. X      }
  50120. X   nextleft = -2;
  50121. X   nextright = -1;
  50122. X
  50123. X   if (fullmenu) {
  50124. X      choices[nextleft+=2] = "      CURRENT IMAGE";
  50125. X      attributes[nextleft] = 256+MENU_HDG;
  50126. X      choicekey[nextleft+=2] = 13; /* enter */
  50127. X      attributes[nextleft] = MENU_ITEM;
  50128. X      if (calc_status == 2)
  50129. X     choices[nextleft] = "continue calculation";
  50130. X      else
  50131. X     choices[nextleft] = "return to image";
  50132. X      choicekey[nextleft+=2] = 9; /* tab */
  50133. X      attributes[nextleft] = MENU_ITEM;
  50134. X      choices[nextleft] = "info about image      <tab>";
  50135. X      choicekey[nextleft+=2] = -10;
  50136. X      attributes[nextleft] = MENU_ITEM;
  50137. X      choices[nextleft] = "zoom box functions...";
  50138. X      choicekey[nextleft+=2] = 'o';
  50139. X      attributes[nextleft] = MENU_ITEM;
  50140. X      choices[nextleft] = "orbits window          <o>";
  50141. X      if(!(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA))
  50142. X          nextleft+=2; 
  50143. X      }
  50144. X   choices[nextleft+=2] = "      NEW IMAGE";
  50145. X   attributes[nextleft] = 256+MENU_HDG;
  50146. X   choicekey[nextleft+=2] = DELETE;
  50147. X   attributes[nextleft] = MENU_ITEM;
  50148. X   choices[nextleft] = "select video mode...  <del>";
  50149. X   choicekey[nextleft+=2] = 't';
  50150. X   attributes[nextleft] = MENU_ITEM;
  50151. X   choices[nextleft] = "select fractal type    <t>";
  50152. X   if (fullmenu) {
  50153. X      if ((curfractalspecific->tojulia != NOFRACTAL
  50154. X      && param[0] == 0.0 && param[1] == 0.0)
  50155. X      || curfractalspecific->tomandel != NOFRACTAL) {
  50156. X         choicekey[nextleft+=2] = ' ';
  50157. X         attributes[nextleft] = MENU_ITEM;
  50158. X         choices[nextleft] = "toggle to/from julia <space>";
  50159. X      }    
  50160. X      if(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA) {
  50161. X         choicekey[nextleft+=2] = 'j';
  50162. X         attributes[nextleft] = MENU_ITEM;
  50163. X         choices[nextleft] = "toggle to/from inverse <j>";
  50164. X      }
  50165. X      choicekey[nextleft+=2] = '\\';
  50166. X      attributes[nextleft] = MENU_ITEM;
  50167. X      choices[nextleft] = "return to prior image  <\\>";
  50168. X   }
  50169. X   nextleft += 2;
  50170. X   choices[nextleft+=2] = "      OPTIONS";
  50171. X   attributes[nextleft] = 256+MENU_HDG;
  50172. X   choicekey[nextleft+=2] = 'x';
  50173. X   attributes[nextleft] = MENU_ITEM;
  50174. X   choices[nextleft] = "basic options...       <x>";
  50175. X   choicekey[nextleft+=2] = 'y';
  50176. X   attributes[nextleft] = MENU_ITEM;
  50177. X   choices[nextleft] = "extended options...    <y>";
  50178. X   choicekey[nextleft+=2] = 'z';
  50179. X   attributes[nextleft] = MENU_ITEM;
  50180. X   choices[nextleft] = "type-specific parms... <z>";
  50181. X   choicekey[nextleft+=2] = 'v';
  50182. X   attributes[nextleft] = MENU_ITEM;
  50183. X   choices[nextleft] = "view window options... <v>";
  50184. X   choicekey[nextleft+=2] = 'i';
  50185. X   attributes[nextleft] = MENU_ITEM;
  50186. X   choices[nextleft] = "fractal 3D parms...    <i>";
  50187. X
  50188. X   choices[nextright+=2] = "        FILE";
  50189. X   attributes[nextright] = 256+MENU_HDG;
  50190. X   choicekey[nextright+=2] = '@';
  50191. X   attributes[nextright] = MENU_ITEM;
  50192. X   choices[nextright] = "run saved command set... <@>";
  50193. X   if (fullmenu) {
  50194. X      choicekey[nextright+=2] = 's';
  50195. X      attributes[nextright] = MENU_ITEM;
  50196. X      choices[nextright] = "save image to file       <s>";
  50197. X      }
  50198. X   choicekey[nextright+=2] = 'r';
  50199. X   attributes[nextright] = MENU_ITEM;
  50200. X   choices[nextright] = "load image from file...  <r>";
  50201. X   choicekey[nextright+=2] = '3';
  50202. X   attributes[nextright] = MENU_ITEM;
  50203. X   choices[nextright] = "3d transform from file...<3>";
  50204. X   if (fullmenu) {
  50205. X      choicekey[nextright+=2] = '#';
  50206. X      attributes[nextright] = MENU_ITEM;
  50207. X      choices[nextright] = "3d overlay from file.....<#>";
  50208. X      choicekey[nextright+=2] = 'b';
  50209. X      attributes[nextright] = MENU_ITEM;
  50210. X      choices[nextright] = "save current parameters..<b>";
  50211. X      choicekey[nextright+=2] = 'p';
  50212. X      attributes[nextright] = MENU_ITEM;
  50213. X      choices[nextright] = "print image              <p>";
  50214. X      }
  50215. X   choicekey[nextright+=2] = 'd';
  50216. X   attributes[nextright] = MENU_ITEM;
  50217. X   choices[nextright] = "shell to dos             <d>";
  50218. X   choicekey[nextright+=2] = 'g';
  50219. X   attributes[nextright] = MENU_ITEM;
  50220. X   choices[nextright] = "give command string      <g>";
  50221. X   choicekey[nextright+=2] = ESC;
  50222. X   attributes[nextright] = MENU_ITEM;
  50223. X   choices[nextright] = "quit Fractint           <esc>";
  50224. X   choicekey[nextright+=2] = INSERT;
  50225. X   attributes[nextright] = MENU_ITEM;
  50226. X   choices[nextright] = "restart Fractint        <ins>";
  50227. X   if (fullmenu && gotrealdac && colors >= 16) {
  50228. X      nextright += 2;
  50229. X      choices[nextright+=2] = "       COLORS";
  50230. X      attributes[nextright] = 256+MENU_HDG;
  50231. X      /*** choicekey[nextright+=2] = -12;
  50232. X        attributes[nextright] = MENU_ITEM;
  50233. X        choices[nextright] = "color cycling menu...";
  50234. X        choicekey[nextright+=2] = -13;
  50235. X        attributes[nextright] = MENU_ITEM;
  50236. X        choices[nextright] = "palette editing menu..."; ***/
  50237. X      choicekey[nextright+=2] = 'c';
  50238. X      attributes[nextright] = MENU_ITEM;
  50239. X      choices[nextright] = "color cycling mode       <c>";
  50240. X      choicekey[nextright+=2] = '+';
  50241. X      attributes[nextright] = MENU_ITEM;
  50242. X      choices[nextright] = "rotate palette      <+>, <->";
  50243. X      if (colors > 16) {
  50244. X     if (!reallyega) {
  50245. X        choicekey[nextright+=2] = 'e';
  50246. X        attributes[nextright] = MENU_ITEM;
  50247. X        choices[nextright] = "palette editing mode     <e>";
  50248. X        }
  50249. X     choicekey[nextright+=2] = 'a';
  50250. X     attributes[nextright] = MENU_ITEM;
  50251. X     choices[nextright] = "make starfield           <a>";
  50252. X     }
  50253. X      }
  50254. X
  50255. X   i = (keypressed()) ? getakey() : 0;
  50256. X   if (menu_checkkey(i,0) == 0) {
  50257. X      helpmode = HELPMAIN;       /* switch help modes */
  50258. X      if ((nextleft += 2) < nextright)
  50259. X     nextleft = nextright + 1;
  50260. X      i = fullscreen_choice(CHOICEMENU,
  50261. X      "MAIN MENU",
  50262. X      NULL,NULL,nextleft,choices,attributes,
  50263. X      2,nextleft/2,29,0,NULL,NULL,NULL,menu_checkkey);
  50264. X      if (i == -1)     /* escape */
  50265. X     i = ESC;
  50266. X      else if (i < 0)
  50267. X     i = 0 - i;
  50268. X      else {              /* user selected a choice */
  50269. X     i = choicekey[i];
  50270. X     switch (i) {          /* check for special cases */
  50271. X        case -10:          /* zoombox functions */
  50272. X           helpmode = HELPZOOM;
  50273. X           help(0);
  50274. X           i = 0;
  50275. X           break;
  50276. X        }
  50277. X     }
  50278. X      }
  50279. X   if (i == ESC) {           /* escape from menu exits Fractint */
  50280. X      static char far s[] = "Exit from Fractint (y/n)? y";
  50281. X      helptitle();
  50282. X      setattr(1,0,C_GENERAL_MED,24*80);
  50283. X      for (i = 9; i <= 11; ++i)
  50284. X     setattr(i,18,C_GENERAL_INPUT,40);
  50285. X      putstringcenter(10,18,40,C_GENERAL_INPUT,s);
  50286. X      movecursor(25,80);
  50287. X      while ((i = getakey()) != 'y' && i != 'Y' && i != 13) {
  50288. X     if (i == 'n' || i == 'N')
  50289. X        goto top;
  50290. X     }
  50291. X      goodbye();
  50292. X      }
  50293. X   if (i == TAB) {
  50294. X      tab_display();
  50295. X      i = 0;
  50296. X      }
  50297. X   if (i == ENTER || i == ENTER_2)
  50298. X      i = 0;             /* don't trigger new calc */
  50299. X   tabmode = oldtabmode;
  50300. X   return(i);
  50301. X}
  50302. X
  50303. Xstatic int menu_checkkey(int curkey,int choice)
  50304. X{
  50305. X   int testkey;
  50306. X   testkey = (curkey>='A' && curkey<='Z') ? curkey+('a'-'A') : curkey;
  50307. X#ifdef XFRACT
  50308. X   /* We use F2 for shift-@, annoyingly enough */
  50309. X   if (testkey == F2) return(0-testkey);
  50310. X#endif
  50311. X   if (strchr("@txyzgvir3dj",testkey) || testkey == INSERT
  50312. X     || testkey == ESC || testkey == DELETE)
  50313. X      return(0-testkey);
  50314. X   if (menutype) {
  50315. X      if (strchr("\\sobp",testkey) || testkey == 9)
  50316. X     return(0-testkey);
  50317. X      if (testkey == ' ')
  50318. X     if ((curfractalspecific->tojulia != NOFRACTAL
  50319. X          && param[0] == 0.0 && param[1] == 0.0)
  50320. X       || curfractalspecific->tomandel != NOFRACTAL)
  50321. X     return(0-testkey);
  50322. X      if (gotrealdac && colors >= 16) {
  50323. X     if (strchr("c+-",testkey))
  50324. X        return(0-testkey);
  50325. X     if (colors > 16
  50326. X       && (testkey == 'a' || (!reallyega && testkey == 'e')))
  50327. X        return(0-testkey);
  50328. X     }
  50329. X      }
  50330. X   if (check_vidmode_key(0,testkey) >= 0)
  50331. X      return(0-testkey);
  50332. X   return(0);
  50333. X}
  50334. X
  50335. X
  50336. Xint input_field(
  50337. X    int options,          /* &1 numeric, &2 integer, &4 double */
  50338. X    int attr,          /* display attribute */
  50339. X    char *fld,          /* the field itself */
  50340. X    int len,          /* field length (declare as 1 larger for \0) */
  50341. X    int row,          /* display row */
  50342. X    int col,          /* display column */
  50343. X    int (*checkkey)(int)  /* routine to check non data keys, or NULL */
  50344. X    )
  50345. X{
  50346. X   char savefld[81];
  50347. X   char buf[81];
  50348. X   int insert, started, offset, curkey, display;
  50349. X   int i, j;
  50350. X   int ret,savelookatmouse;
  50351. X   savelookatmouse = lookatmouse;
  50352. X   lookatmouse = 0;
  50353. X   ret = -1;
  50354. X   strcpy(savefld,fld);
  50355. X   insert = started = offset = 0;
  50356. X   display = 1;
  50357. X   while (1) {
  50358. X      strcpy(buf,fld);
  50359. X      i = strlen(buf);
  50360. X      while (i < len)
  50361. X     buf[i++] = ' ';
  50362. X      buf[len] = 0;
  50363. X      if (display) {                    /* display current value */
  50364. X     putstring(row,col,attr,buf);
  50365. X     display = 0;
  50366. X     }
  50367. X      curkey = keycursor(row+insert,col+offset);  /* get a keystroke */
  50368. X      switch (curkey) {
  50369. X     case ENTER:
  50370. X     case ENTER_2:
  50371. X        ret = 0;
  50372. X        goto inpfld_end;
  50373. X     case ESC:
  50374. X        goto inpfld_end;
  50375. X     case RIGHT_ARROW:
  50376. X     case RIGHT_ARROW_2:
  50377. X        if (offset < len-1) ++offset;
  50378. X        started = 1;
  50379. X        break;
  50380. X     case LEFT_ARROW:
  50381. X     case LEFT_ARROW_2:
  50382. X        if (offset > 0) --offset;
  50383. X        started = 1;
  50384. X        break;
  50385. X     case HOME:
  50386. X        offset = 0;
  50387. X        started = 1;
  50388. X        break;
  50389. X     case END:
  50390. X        offset = strlen(fld);
  50391. X        started = 1;
  50392. X        break;
  50393. X     case 8:
  50394. X     case 127:                /* backspace */
  50395. X        if (offset > 0) {
  50396. X           j = strlen(fld);
  50397. X           for (i = offset-1; i < j; ++i)
  50398. X          fld[i] = fld[i+1];
  50399. X           --offset;
  50400. X           }
  50401. X        started = display = 1;
  50402. X        break;
  50403. X     case DELETE:                /* delete */
  50404. X        j = strlen(fld);
  50405. X        for (i = offset; i < j; ++i)
  50406. X           fld[i] = fld[i+1];
  50407. X        started = display = 1;
  50408. X        break;
  50409. X     case INSERT:                /* insert */
  50410. X        insert ^= 0x8000;
  50411. X        started = 1;
  50412. X        break;
  50413. X     case F5:
  50414. X        strcpy(fld,savefld);
  50415. X        insert = started = offset = 0;
  50416. X        display = 1;
  50417. X        break;
  50418. X     default:
  50419. X            if (nonalpha(curkey)) {
  50420. X           if (checkkey && (ret = (*checkkey)(curkey)))
  50421. X          goto inpfld_end;
  50422. X           break;                     /* non alphanum char */
  50423. X           }
  50424. X        if (offset >= len) break;             /* at end of field */
  50425. X        if (insert && started && strlen(fld) >= len)
  50426. X           break;                     /* insert & full */
  50427. X        if ((options & 1)
  50428. X          && (curkey < '0' || curkey > '9')
  50429. X          && curkey != '+' && curkey != '-') {
  50430. X           if ((options & 2))
  50431. X          break;
  50432. X           /* allow scientific notation, and specials "e" and "p" */
  50433. X           if ( ((curkey != 'e' && curkey != 'E') || offset >= 18)
  50434. X         && ((curkey != 'p' && curkey != 'P') || offset != 0 )
  50435. X         && curkey != '.')
  50436. X          break;
  50437. X           }
  50438. X        if (started == 0) /* first char is data, zap field */
  50439. X           fld[0] = 0;
  50440. X        if (insert) {
  50441. X           j = strlen(fld);
  50442. X           while (j >= offset) {
  50443. X          fld[j+1] = fld[j];
  50444. X          --j;
  50445. X          }
  50446. X           }
  50447. X        if (offset >= strlen(fld))
  50448. X           fld[offset+1] = 0;
  50449. X        fld[offset++] = curkey;
  50450. X        /* if "e" or "p" in first col make number e or pi */
  50451. X        if ((options & 3) == 1) { /* floating point */
  50452. X           double tmpd;
  50453. X           int specialv;
  50454. X           char tmpfld[30];
  50455. X           specialv = 0;
  50456. X           if (*fld == 'e' || *fld == 'E') {
  50457. X          tmpd = exp(1.0);
  50458. X          specialv = 1;
  50459. X          }
  50460. X           if (*fld == 'p' || *fld == 'P') {
  50461. X          tmpd = atan(1.0) * 4;
  50462. X          specialv = 1;
  50463. X          }
  50464. X           if (specialv) {
  50465. X          if ((options & 4) == 0)
  50466. X             roundfloatd(&tmpd);
  50467. X          sprintf(tmpfld,"%.15g",tmpd);
  50468. X          tmpfld[len-1] = 0; /* safety, field should be long enough */
  50469. X          strcpy(fld,tmpfld);
  50470. X          offset = 0;
  50471. X          }
  50472. X           }
  50473. X        started = display = 1;
  50474. X     }
  50475. X      }
  50476. Xinpfld_end:
  50477. X   lookatmouse = savelookatmouse;
  50478. X   return(ret);
  50479. X}
  50480. X
  50481. Xint field_prompt(
  50482. X    int options,        /* &1 numeric value, &2 integer */
  50483. X    char *hdg,        /* heading, \n delimited lines */
  50484. X    char *instr,        /* additional instructions or NULL */
  50485. X    char *fld,        /* the field itself */
  50486. X    int len,        /* field length (declare as 1 larger for \0) */
  50487. X    int (*checkkey)(int)   /* routine to check non data keys, or NULL */
  50488. X    )
  50489. X{
  50490. X   char *charptr;
  50491. X   int boxwidth,titlelines,titlecol,titlerow;
  50492. X   int promptcol;
  50493. X   int i,j;
  50494. X   char buf[81];
  50495. X   helptitle();               /* clear screen, display title */
  50496. X   setattr(1,0,C_PROMPT_BKGRD,24*80);      /* init rest to background */
  50497. X   charptr = hdg;              /* count title lines, find widest */
  50498. X   i = boxwidth = 0;
  50499. X   titlelines = 1;
  50500. X   while (*charptr) {
  50501. X      if (*(charptr++) == '\n') {
  50502. X     ++titlelines;
  50503. X     i = -1;
  50504. X     }
  50505. X      if (++i > boxwidth)
  50506. X     boxwidth = i;
  50507. X      }
  50508. X   if (len > boxwidth)
  50509. X      boxwidth = len;
  50510. X   i = titlelines + 4;              /* total rows in box */
  50511. X   titlerow = (25 - i) / 2;          /* top row of it all when centered */
  50512. X   titlerow -= titlerow / 4;          /* higher is better if lots extra */
  50513. X   titlecol = (80 - boxwidth) / 2;      /* center the box */
  50514. X   titlecol -= (90 - boxwidth) / 20;
  50515. X   promptcol = titlecol - (boxwidth-len)/2;
  50516. X   j = titlecol;              /* add margin at each side of box */
  50517. X   if ((i = (82-boxwidth)/4) > 3)
  50518. X      i = 3;
  50519. X   j -= i;
  50520. X   boxwidth += i * 2;
  50521. X   for (i = -1; i < titlelines+3; ++i)      /* draw empty box */
  50522. X      setattr(titlerow+i,j,C_PROMPT_LO,boxwidth);
  50523. X   textcbase = titlecol;          /* set left margin for putstring */
  50524. X   putstring(titlerow,0,C_PROMPT_HI,hdg); /* display heading */
  50525. X   textcbase = 0;
  50526. X   i = titlerow + titlelines + 4;
  50527. X   if (instr) {               /* display caller's instructions */
  50528. X      charptr = instr;
  50529. X      j = -1;
  50530. X      while ((buf[++j] = *(charptr++)))
  50531. X     if (buf[j] == '\n') {
  50532. X        buf[j] = 0;
  50533. X        putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
  50534. X        j = -1;
  50535. X        }
  50536. X      putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
  50537. X      }
  50538. X   else                   /* default instructions */
  50539. X      putstringcenter(i,0,80,C_PROMPT_BKGRD,
  50540. X          "Press ENTER when finished (or ESCAPE to back out)");
  50541. X   return(input_field(options,C_PROMPT_INPUT,fld,len,
  50542. X              titlerow+titlelines+1,promptcol,checkkey));
  50543. X}
  50544. X
  50545. X
  50546. X/* thinking(1,message):
  50547. X      if thinking message not yet on display, it is displayed;
  50548. X      otherwise the wheel is updated
  50549. X      returns 0 to keep going, -1 if keystroke pending
  50550. X   thinking(0,NULL):
  50551. X      call this when thinking phase is done
  50552. X   */
  50553. X
  50554. Xint thinking(int options,char *msg)
  50555. X{
  50556. X   static int thinkstate = -1;
  50557. X   static char *wheel[] = {"-","\\","|","/"};
  50558. X   static int thinkcol;
  50559. X   static int count=0;
  50560. X   char buf[81];
  50561. X   if (options == 0) {
  50562. X      if (thinkstate >= 0) {
  50563. X     thinkstate = -1;
  50564. X     unstackscreen();
  50565. X     }
  50566. X      return(0);
  50567. X      }
  50568. X   if (thinkstate < 0) {
  50569. X      stackscreen();
  50570. X      thinkstate = 0;
  50571. X      helptitle();
  50572. X      strcpy(buf,"  ");
  50573. X      strcat(buf,msg);
  50574. X      strcat(buf,"    ");
  50575. X      putstring(4,10,C_GENERAL_HI,buf);
  50576. X      thinkcol = textcol - 3;
  50577. X      count = 0;
  50578. X      }
  50579. X   if ((count++)<100) {
  50580. X       return 0;
  50581. X   }
  50582. X   count = 0;
  50583. X   putstring(4,thinkcol,C_GENERAL_HI,wheel[thinkstate]);
  50584. X   movecursor(25,80); /* turn off cursor */
  50585. X   thinkstate = (thinkstate + 1) & 3;
  50586. X   return (keypressed());
  50587. X}
  50588. X
  50589. X
  50590. Xvoid clear_screen(void)  /* a stub for a windows only subroutine */
  50591. X{
  50592. X}
  50593. X
  50594. X
  50595. X/* savegraphics/restoregraphics: video.asm subroutines */
  50596. X
  50597. Xstatic BYTE far *swapsavebuf;
  50598. Xstatic unsigned int memhandle;
  50599. Xunsigned long swaptotlen;
  50600. Xunsigned long swapoffset;
  50601. XBYTE far *swapvidbuf;
  50602. Xint swaplength;
  50603. Xstatic int swaptype = -1;
  50604. Xstatic int swapblklen; /* must be a power of 2 */
  50605. X#ifndef XFRACT
  50606. Xextern BYTE suffix[4096];
  50607. X#else
  50608. XBYTE suffix[4096];
  50609. X#endif
  50610. X
  50611. X#ifndef XFRACT
  50612. X
  50613. Xint savegraphics()
  50614. X{
  50615. X   extern int made_dsktemp;
  50616. X   int i;
  50617. X   struct XMM_Move   xmmparms;
  50618. X
  50619. X   discardgraphics(); /* if any emm/xmm in use from prior call, release it */
  50620. X   swaptotlen = (long)(vxdots > sxdots ? vxdots : sxdots) * (long)sydots;
  50621. X   i = colors;
  50622. X   while (i <= 16) {
  50623. X      swaptotlen >>= 1;
  50624. X      i = i * i;
  50625. X      }
  50626. X   swapoffset = 0;
  50627. X   if (debugflag != 420 && debugflag != 422 /* 422=xmm test, 420=disk test */
  50628. X     && (swapsavebuf = emmquery()) != NULL
  50629. X     && (memhandle = emmallocate((unsigned int)((swaptotlen + 16383) >> 14)))
  50630. X     != 0) {
  50631. X      swaptype = 0; /* use expanded memory */
  50632. X      swapblklen = 16384;
  50633. X      }
  50634. X   else if (debugflag != 420
  50635. X     && xmmquery() !=0
  50636. X     && (memhandle = xmmallocate((unsigned int)((swaptotlen + 1023) >> 10)))
  50637. X     != 0) {
  50638. X      swaptype = 1; /* use extended memory */
  50639. X      swapblklen = 16384;
  50640. X      }
  50641. X   else {
  50642. X      swaptype = 2; /* use disk */
  50643. X      swapblklen = 4096;
  50644. X
  50645. X   /* MCP 7-7-91, If 'memhandle' is an 'unsigned int', how is it ever going
  50646. X      to be equal to -1?
  50647. X
  50648. X      if ((memhandle = open(diskfilename,O_CREAT|O_WRONLY|O_BINARY,S_IWRITE))
  50649. X     == -1) {
  50650. X   */
  50651. X      if ((memhandle = open(diskfilename,O_CREAT|O_WRONLY|O_BINARY,S_IWRITE))
  50652. X     == 0xffff) {
  50653. X
  50654. X
  50655. Xdskfile_error:
  50656. X     setvideotext(); /* text mode */
  50657. X     setclear();
  50658. X         {
  50659. X            extern char diskfilename[];
  50660. X            static char far s1[] = {"error in temp file "};
  50661. X            static char far s2[] = { " (disk full?) - aborted\n\n"};
  50662. X        printf("%Fs%s%Fs",s1,diskfilename,s2);
  50663. X     }   
  50664. X     exit(1);
  50665. X     }
  50666. X      made_dsktemp = 1;
  50667. X      }
  50668. X   while (swapoffset < swaptotlen) {
  50669. X      swaplength = swapblklen;
  50670. X      if ((swapoffset & (swapblklen-1)) != 0)
  50671. X     swaplength = swapblklen - (swapoffset & (swapblklen-1));
  50672. X      if (swaplength > swaptotlen - swapoffset)
  50673. X     swaplength = swaptotlen - swapoffset;
  50674. X      (*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */
  50675. X      switch(swaptype) {
  50676. X     case 0:
  50677. X        emmgetpage((unsigned int)(swapoffset>>14),memhandle);
  50678. X        movewords(swaplength>>1,swapvidbuf,
  50679. X              swapsavebuf+(swapoffset&(swapblklen-1)));
  50680. X        break;
  50681. X     case 1:
  50682. X        xmmparms.Length = swaplength;
  50683. X        xmmparms.SourceHandle = 0; /* Source is conventional memory */
  50684. X        xmmparms.SourceOffset = (unsigned long)swapvidbuf;
  50685. X        xmmparms.DestHandle = memhandle;
  50686. X        xmmparms.DestOffset = swapoffset;
  50687. X        xmmmoveextended(&xmmparms);
  50688. X        break;
  50689. X     default:
  50690. X        movewords(swaplength>>1,swapvidbuf,(BYTE far *)suffix);
  50691. X        if (write(memhandle,suffix,swaplength) == -1)
  50692. X           goto dskfile_error;
  50693. X     }
  50694. X      swapoffset += swaplength;
  50695. X      }
  50696. X   if (swaptype == 2)
  50697. X      close(memhandle);
  50698. X   return 0;
  50699. X}
  50700. X
  50701. Xvoid restoregraphics()
  50702. X{
  50703. X   struct XMM_Move   xmmparms;
  50704. X
  50705. X   swapoffset = 0;
  50706. X   if (swaptype == 2)
  50707. X      memhandle = open(diskfilename,O_RDONLY|O_BINARY,S_IREAD);
  50708. X   swapvidbuf = MK_FP(extraseg+0x1000,0); /* for swapnormwrite case */
  50709. X   while (swapoffset < swaptotlen) {
  50710. X      swaplength = swapblklen;
  50711. X      if ((swapoffset & (swapblklen-1)) != 0)
  50712. X     swaplength = swapblklen - (swapoffset & (swapblklen-1));
  50713. X      if (swaplength > swaptotlen - swapoffset)
  50714. X     swaplength = swaptotlen - swapoffset;
  50715. X      if (swapsetup != swapnormread)
  50716. X     (*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */
  50717. X      switch(swaptype) {
  50718. X     case 0:
  50719. X        emmgetpage((unsigned int)(swapoffset>>14),memhandle);
  50720. X        movewords(swaplength>>1,swapsavebuf+(swapoffset&(swapblklen-1)),
  50721. X              swapvidbuf);
  50722. X        break;
  50723. X     case 1:
  50724. X        xmmparms.Length = swaplength;
  50725. X        xmmparms.SourceHandle = memhandle;
  50726. X        xmmparms.SourceOffset = swapoffset;
  50727. X        xmmparms.DestHandle = 0; /* conventional memory */
  50728. X        xmmparms.DestOffset = (unsigned long)swapvidbuf;
  50729. X        xmmmoveextended(&xmmparms);
  50730. X        break;
  50731. X     default:
  50732. X        read(memhandle,suffix,swaplength);
  50733. X        movewords(swaplength>>1,(BYTE far *)suffix,swapvidbuf);
  50734. X     }
  50735. X      if (swapsetup == swapnormread)
  50736. X     swapnormwrite();
  50737. X      swapoffset += swaplength;
  50738. X      }
  50739. X   if (swaptype == 2)
  50740. X      close(memhandle);
  50741. X   discardgraphics();
  50742. X}
  50743. X
  50744. X#endif
  50745. X
  50746. Xvoid discardgraphics() /* release expanded/extended memory if any in use */
  50747. X{
  50748. X#ifndef XFRACT
  50749. X   switch(swaptype) {
  50750. X      case 0:
  50751. X     emmdeallocate(memhandle);
  50752. X     break;
  50753. X      case 1:
  50754. X     xmmdeallocate(memhandle);
  50755. X      }
  50756. X   swaptype = -1;
  50757. X#endif
  50758. X}
  50759. X
  50760. Xextern int badconfig;
  50761. Xextern struct videoinfo far videotable[];
  50762. Xstruct videoinfo far *vidtbl;  /* temporarily loaded fractint.cfg info */
  50763. Xint vidtbllen;               /* number of entries in above           */
  50764. X
  50765. Xint load_fractint_cfg(int options)
  50766. X{
  50767. X   /* Reads fractint.cfg, loading videoinfo entries into extraseg. */
  50768. X   /* Sets vidtbl pointing to the loaded table, and returns the    */
  50769. X   /* number of entries (also sets vidtbllen to this).           */
  50770. X   /* Past vidtbl, cfglinenums are stored for update_fractint_cfg. */
  50771. X   /* If fractint.cfg is not found or invalid, issues a message    */
  50772. X   /* (first time the problem occurs only, and only if options is  */
  50773. X   /* zero) and uses the hard-coded table.               */
  50774. X
  50775. X   FILE *cfgfile;
  50776. X   struct videoinfo far *vident;
  50777. X   int far *cfglinenums;
  50778. X   int linenum;
  50779. X   int i, j, keynum, ax, bx, cx, dx, dotmode, xdots, ydots, colors;
  50780. X   int commas[10];
  50781. X   int textsafe2;
  50782. X   char tempstring[150];
  50783. X
  50784. X   vidtbl = MK_FP(extraseg,0);
  50785. X   cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);
  50786. X
  50787. X#ifdef XFRACT
  50788. X    badconfig = -1;
  50789. X#endif
  50790. X
  50791. X   if (badconfig)  /* fractint.cfg already known to be missing or bad */
  50792. X      goto use_resident_table;
  50793. X
  50794. X   findpath("fractint.cfg",tempstring);
  50795. X   if (tempstring[0] == 0                 /* can't find the file */
  50796. X     || (cfgfile = fopen(tempstring,"r")) == NULL)   /* can't open it */
  50797. X      goto bad_fractint_cfg;
  50798. X
  50799. X   vidtbllen = 0;
  50800. X   linenum = 0;
  50801. X   vident = vidtbl;
  50802. X   while (vidtbllen < MAXVIDEOMODES
  50803. X     && fgets(tempstring, 120, cfgfile)) {
  50804. X      ++linenum;
  50805. X      if (tempstring[0] == ';') continue;   /* comment line */
  50806. X      tempstring[120] = 0;
  50807. X      tempstring[strlen(tempstring)-1] = 0; /* zap trailing \n */
  50808. X      memset(commas,0,20);
  50809. X      i = j = -1;
  50810. X      while (1) {
  50811. X     if (tempstring[++i] < ' ') {
  50812. X        if (tempstring[i] == 0) break;
  50813. X        tempstring[i] = ' '; /* convert tab (or whatever) to blank */
  50814. X        }
  50815. X     else if (tempstring[i] == ',' && ++j < 10) {
  50816. X        commas[j] = i + 1;     /* remember start of next field */
  50817. X        tempstring[i] = 0;     /* make field a separate string */
  50818. X        }
  50819. X     }
  50820. X      keynum = check_vidmode_keyname(tempstring);
  50821. X      sscanf(&tempstring[commas[1]],"%x",&ax);
  50822. X      sscanf(&tempstring[commas[2]],"%x",&bx);
  50823. X      sscanf(&tempstring[commas[3]],"%x",&cx);
  50824. X      sscanf(&tempstring[commas[4]],"%x",&dx);
  50825. X      dotmode      = atoi(&tempstring[commas[5]]);
  50826. X      xdots      = atoi(&tempstring[commas[6]]);
  50827. X      ydots      = atoi(&tempstring[commas[7]]);
  50828. X      colors      = atoi(&tempstring[commas[8]]);
  50829. X      textsafe2   = dotmode / 100;
  50830. X      dotmode     %= 100;
  50831. X      if (j != 9 ||
  50832. X        keynum < 0 ||
  50833. X        dotmode < 0 || dotmode > 30 ||
  50834. X        textsafe2 < 0 || textsafe2 > 4 ||
  50835. X        xdots < 160 || xdots > MAXPIXELS ||
  50836. X        ydots < 160 || ydots > MAXPIXELS ||
  50837. X        (colors != 0 && colors != 2 && colors != 4 && colors != 16 &&
  50838. X         colors != 256)
  50839. X       )
  50840. X     goto bad_fractint_cfg;
  50841. X      cfglinenums[vidtbllen] = linenum; /* for update_fractint_cfg */
  50842. X      far_memcpy(vident->name,     (char far *)&tempstring[commas[0]],25);
  50843. X      far_memcpy(vident->comment,(char far *)&tempstring[commas[9]],25);
  50844. X      vident->name[25] = vident->comment[25] = 0;
  50845. X      vident->keynum      = keynum;
  50846. X      vident->videomodeax = ax;
  50847. X      vident->videomodebx = bx;
  50848. X      vident->videomodecx = cx;
  50849. X      vident->videomodedx = dx;
  50850. X      vident->dotmode      = textsafe2 * 100 + dotmode;
  50851. X      vident->xdots      = xdots;
  50852. X      vident->ydots      = ydots;
  50853. X      vident->colors      = colors;
  50854. X      ++vident;
  50855. X      ++vidtbllen;
  50856. X      }
  50857. X   fclose(cfgfile);
  50858. X   return (vidtbllen);
  50859. X
  50860. Xbad_fractint_cfg:
  50861. X   badconfig = -1; /* bad, no message issued yet */
  50862. X   if (options == 0)
  50863. X      bad_fractint_cfg_msg();
  50864. X
  50865. Xuse_resident_table:
  50866. X   vidtbllen = 0;
  50867. X   vident = vidtbl;
  50868. X   for (i = 0; i < MAXVIDEOTABLE; ++i) {
  50869. X      if (videotable[i].xdots) {
  50870. X     far_memcpy((char far *)vident,(char far *)&videotable[i],
  50871. X            sizeof(*vident));
  50872. X     ++vident;
  50873. X     ++vidtbllen;
  50874. X     }
  50875. X      }
  50876. X   return (vidtbllen);
  50877. X
  50878. X}
  50879. X
  50880. Xvoid bad_fractint_cfg_msg()
  50881. X{
  50882. Xstatic char far badcfgmsg[]={"\
  50883. XFile FRACTINT.CFG is missing or invalid.\n\
  50884. XSee Hardware Support and Video Modes in the full documentation for help.\n\
  50885. XI will continue with only the built-in video modes available."};
  50886. X   stopmsg(0,badcfgmsg);
  50887. X   badconfig = 1; /* bad, message issued */
  50888. X}
  50889. X
  50890. Xvoid load_videotable(int options)
  50891. X{
  50892. X   /* Loads fractint.cfg and copies the video modes which are */
  50893. X   /* assigned to function keys into videotable.          */
  50894. X   int keyents,i;
  50895. X   load_fractint_cfg(options); /* load fractint.cfg to extraseg */
  50896. X   keyents = 0;
  50897. X   far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
  50898. X   for (i = 0; i < vidtbllen; ++i) {
  50899. X      if (vidtbl[i].keynum > 0) {
  50900. X     far_memcpy((char far *)&videotable[keyents],(char far *)&vidtbl[i],
  50901. X            sizeof(*vidtbl));
  50902. X     if (++keyents >= MAXVIDEOTABLE)
  50903. X        break;
  50904. X     }
  50905. X      }
  50906. X}
  50907. X
  50908. Xint check_vidmode_key(int option,int k)
  50909. X{
  50910. X   int i;
  50911. X   /* returns videotable entry number if the passed keystroke is a  */
  50912. X   /* function key currently assigned to a video mode, -1 otherwise */
  50913. X   if (k == 1400)           /* special value from select_vid_mode  */
  50914. X      return(MAXVIDEOTABLE-1); /* for last entry with no key assigned */
  50915. X   if (k != 0)
  50916. X      if (option == 0) { /* check resident video mode table */
  50917. X     for (i = 0; i < MAXVIDEOTABLE; ++i) {
  50918. X        if (videotable[i].keynum == k)
  50919. X           return(i);
  50920. X        }
  50921. X     }
  50922. X      else { /* check full vidtbl */
  50923. X     for (i = 0; i < vidtbllen; ++i) {
  50924. X        if (vidtbl[i].keynum == k)
  50925. X           return(i);
  50926. X        }
  50927. X     }
  50928. X   return(-1);
  50929. X}
  50930. X
  50931. Xint check_vidmode_keyname(char *kname)
  50932. X{
  50933. X   /* returns key number for the passed keyname, 0 if not a keyname */
  50934. X   int i,keyset;
  50935. X   keyset = 1058;
  50936. X   if (*kname == 'S' || *kname == 's') {
  50937. X      keyset = 1083;
  50938. X      ++kname;
  50939. X      }
  50940. X   else if (*kname == 'C' || *kname == 'c') {
  50941. X      keyset = 1093;
  50942. X      ++kname;
  50943. X      }
  50944. X   else if (*kname == 'A' || *kname == 'a') {
  50945. X      keyset = 1103;
  50946. X      ++kname;
  50947. X      }
  50948. X   if (*kname != 'F' && *kname != 'f')
  50949. X      return(0);
  50950. X   if (*++kname < '1' || *kname > '9')
  50951. X      return(0);
  50952. X   i = *kname - '0';
  50953. X   if (*++kname != 0 && *kname != ' ') {
  50954. X      if (*kname != '0' || i != 1)
  50955. X     return(0);
  50956. X      i = 10;
  50957. X      ++kname;
  50958. X      }
  50959. X   while (*kname)
  50960. X      if (*(kname++) != ' ')
  50961. X     return(0);
  50962. X   if ((i += keyset) < 2)
  50963. X      i = 0;
  50964. X   return(i);
  50965. X}
  50966. X
  50967. Xvoid vidmode_keyname(int k,char *buf)
  50968. X{
  50969. X   /* set buffer to name of passed key number */
  50970. X   *buf = 0;
  50971. X   if (k > 0) {
  50972. X      if (k > 1103) {
  50973. X     *(buf++) = 'A';
  50974. X     k -= 1103;
  50975. X     }
  50976. X      else if (k > 1093) {
  50977. X     *(buf++) = 'C';
  50978. X     k -= 1093;
  50979. X     }
  50980. X      else if (k > 1083) {
  50981. X     *(buf++) = 'S';
  50982. X     k -= 1083;
  50983. X     }
  50984. X      else
  50985. X     k -= 1058;
  50986. X      sprintf(buf,"F%d",k);
  50987. X      }
  50988. X}
  50989. SHAR_EOF
  50990. $TOUCH -am 1028230093 realdos.c &&
  50991. chmod 0644 realdos.c ||
  50992. echo "restore of realdos.c failed"
  50993. set `wc -c realdos.c`;Wc_c=$1
  50994. if test "$Wc_c" != "51622"; then
  50995.     echo original size 51622, current size $Wc_c
  50996. fi
  50997. # ============= rotate.c ==============
  50998. echo "x - extracting rotate.c (Text)"
  50999. sed 's/^X//' << 'SHAR_EOF' > rotate.c &&
  51000. X/*
  51001. X    rotate.c - Routines that manipulate the Video DAC on VGA Adapters
  51002. X    This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  51003. X*/
  51004. X
  51005. X#include <stdlib.h>
  51006. X#include <stdio.h>
  51007. X#include <string.h>
  51008. X#include <time.h>
  51009. X#include "fractint.h"
  51010. X#include "helpdefs.h"
  51011. X#include "prototyp.h"
  51012. X
  51013. X/* routines in this module    */
  51014. X
  51015. Xstatic void pauserotate(void);
  51016. Xstatic void set_palette(),set_palette2(),set_palette3();
  51017. X
  51018. Xextern char temp1[];
  51019. X
  51020. Xextern    int    colors;         /* maximum colors available */
  51021. X
  51022. Xextern BYTE dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  51023. Xextern    int    gotrealdac;        /* dacbox valid? */
  51024. Xextern BYTE olddacbox[256][3];
  51025. Xextern int    daclearn, daccount;    /* used by the color-cyclers */
  51026. Xextern int    reallyega;        /* == 0 if it's really an EGA */
  51027. Xextern int    rotate_lo,rotate_hi;    /* range of colors to cycle */
  51028. Xextern int    colorstate; /* comments in cmdfiles */
  51029. Xextern char    colorfile[];
  51030. Xextern int    dotmode;
  51031. X
  51032. Xstatic int paused;            /* rotate-is-paused flag */
  51033. X
  51034. Xstatic BYTE Red[3]    = {63, 0, 0};    /* for shifted-Fkeys */
  51035. Xstatic BYTE Green[3]  = { 0,63, 0};
  51036. Xstatic BYTE Blue[3]   = { 0, 0,63};
  51037. Xstatic BYTE Black[3]  = { 0, 0, 0};
  51038. Xstatic BYTE White[3]  = {63,63,63};
  51039. Xstatic BYTE Yellow[3] = {63,63, 0};
  51040. Xstatic BYTE Brown[3]  = {31,31, 0};
  51041. X
  51042. Xchar mapmask[13] = {"*.map"};
  51043. X
  51044. X
  51045. Xvoid rotate_overlay() { }    /* for restore_active_ovly */
  51046. X
  51047. Xvoid rotate(int direction)    /* rotate-the-palette routine */
  51048. X{
  51049. Xint  kbdchar, more, last, next;
  51050. Xint fkey, step, fstep, istep, jstep, oldstep;
  51051. Xint incr, fromred, fromblue, fromgreen, tored, toblue, togreen;
  51052. Xint i, changecolor, changedirection;
  51053. Xint oldhelpmode;
  51054. Xint rotate_max,rotate_size;
  51055. X
  51056. Xstatic int fsteps[] = {2,4,8,12,16,24,32,40,54,100}; /* (for Fkeys) */
  51057. X
  51058. X   ENTER_OVLY(OVLY_ROTATE);
  51059. X
  51060. X   if (gotrealdac == 0            /* ??? no DAC to rotate! */
  51061. X     || colors < 16) {            /* strange things happen in 2x modes */
  51062. X      buzzer(2);
  51063. X      EXIT_OVLY;
  51064. X      return;
  51065. X      }
  51066. X
  51067. X   oldhelpmode = helpmode;        /* save the old help mode    */
  51068. X   helpmode = HELPCYCLING;        /* new help mode        */
  51069. X
  51070. X   paused = 0;                /* not paused            */
  51071. X   fkey = 0;                /* no random coloring        */
  51072. X   oldstep = step = 1;            /* single-step            */
  51073. X   fstep = 1;
  51074. X   changecolor = -1;            /* no color (rgb) to change    */
  51075. X   changedirection = 0;         /* no color direction to change */
  51076. X   incr = 999;                /* ready to randomize        */
  51077. X   srand((unsigned)time(NULL));     /* randomize things        */
  51078. X
  51079. X   if (direction == 0) {        /* firing up in paused mode?    */
  51080. X      pauserotate();            /* then force a pause        */
  51081. X      direction = 1;            /* and set a rotate direction    */
  51082. X      }
  51083. X
  51084. X   rotate_max = (rotate_hi < colors) ? rotate_hi : colors-1;
  51085. X   rotate_size = rotate_max - rotate_lo + 1;
  51086. X   last = rotate_max;            /* last box that was filled    */
  51087. X   next = rotate_lo;            /* next box to be filled    */
  51088. X   if (direction < 0) {
  51089. X      last = rotate_lo;
  51090. X      next = rotate_max;
  51091. X      }
  51092. X
  51093. X   more = 1;
  51094. X   while (more) {
  51095. X      if (dotmode == 11) {
  51096. X     if (!paused)
  51097. X        pauserotate();
  51098. X     }
  51099. X      else while(!keypressed()) { /* rotate until key hit, at least once so step=oldstep ok */
  51100. X     if (fkey > 0) {        /* randomizing is on */
  51101. X        for (istep = 0; istep < step; istep++) {
  51102. X           jstep = next + (istep * direction);
  51103. X           while (jstep < rotate_lo)  jstep += rotate_size;
  51104. X           while (jstep > rotate_max) jstep -= rotate_size;
  51105. X           if (++incr > fstep) {    /* time to randomize */
  51106. X          incr = 1;
  51107. X                  fstep = ((fsteps[fkey-1]* (rand15() >> 8)) >> 6) + 1;
  51108. X          fromred   = dacbox[last][0];
  51109. X          fromgreen = dacbox[last][1];
  51110. X          fromblue  = dacbox[last][2];
  51111. X                  tored     = rand15() >> 9;
  51112. X                  togreen   = rand15() >> 9;
  51113. X                  toblue    = rand15() >> 9;
  51114. X          }
  51115. X           dacbox[jstep][0] = fromred   + (((tored     - fromred  )*incr)/fstep);
  51116. X           dacbox[jstep][1] = fromgreen + (((togreen - fromgreen)*incr)/fstep);
  51117. X           dacbox[jstep][2] = fromblue  + (((toblue  - fromblue )*incr)/fstep);
  51118. X           }
  51119. X        }
  51120. X     if (step >= rotate_size) step = oldstep;
  51121. X     spindac(direction, step);
  51122. X     }
  51123. X      if (step >= rotate_size) step = oldstep;
  51124. X      kbdchar = getakey();
  51125. X      if (paused && (kbdchar != ' ' && kbdchar != 'c' && kbdchar != 'C' ))
  51126. X     paused = 0;            /* clear paused condition    */
  51127. X      switch (kbdchar) {
  51128. X     case '+':                      /* '+' means rotate forward     */
  51129. X         case RIGHT_ARROW:              /* RightArrow = rotate fwd      */
  51130. X        fkey = 0;
  51131. X        direction = 1;
  51132. X        last = rotate_max;
  51133. X        next = rotate_lo;
  51134. X        incr = 999;
  51135. X        break;
  51136. X     case '-':                      /* '-' means rotate backward    */
  51137. X         case LEFT_ARROW:               /* LeftArrow = rotate bkwd      */
  51138. X        fkey = 0;
  51139. X        direction = -1;
  51140. X        last = rotate_lo;
  51141. X        next = rotate_max;
  51142. X        incr = 999;
  51143. X        break;
  51144. X         case UP_ARROW:                 /* UpArrow means speed up       */
  51145. X        daclearn = 1;
  51146. X        if (++daccount >= colors) --daccount;
  51147. X        break;
  51148. X         case DOWN_ARROW:               /* DownArrow means slow down    */
  51149. X        daclearn = 1;
  51150. X        if (daccount > 1) daccount--;
  51151. X        break;
  51152. X     case '1':
  51153. X     case '2':
  51154. X     case '3':
  51155. X     case '4':
  51156. X     case '5':
  51157. X     case '6':
  51158. X     case '7':
  51159. X     case '8':
  51160. X     case '9':
  51161. X        step = kbdchar - '0';   /* change step-size */
  51162. X        if (step > rotate_size) step = rotate_size;
  51163. X        break;
  51164. X         case F1:                       /* F1 - F10:                    */
  51165. X         case F2:                       /* select a shading factor      */
  51166. X         case F3:
  51167. X         case F4:
  51168. X         case F5:
  51169. X         case F6:
  51170. X         case F7:
  51171. X         case F8:
  51172. X         case F9:
  51173. X         case F10:
  51174. X#ifndef XFRACT
  51175. X            fkey = kbdchar-1058;
  51176. X#else
  51177. X            switch (kbdchar) {
  51178. X               case F1:
  51179. X                  fkey = 1;break;
  51180. X               case F2:
  51181. X                  fkey = 2;break;
  51182. X               case F3:
  51183. X                  fkey = 3;break;
  51184. X               case F4:
  51185. X                  fkey = 4;break;
  51186. X               case F5:
  51187. X                  fkey = 5;break;
  51188. X               case F6:
  51189. X                  fkey = 6;break;
  51190. X               case F7:
  51191. X                  fkey = 7;break;
  51192. X               case F8:
  51193. X                  fkey = 8;break;
  51194. X               case F9:
  51195. X                  fkey = 9;break;
  51196. X               case F10:
  51197. X                  fkey = 10;break;
  51198. X            }
  51199. X#endif
  51200. X        if (reallyega) fkey = (fkey+1)>>1; /* limit on EGA */
  51201. X        fstep = 1;
  51202. X        incr = 999;
  51203. X        break;
  51204. X         case ENTER:                    /* enter key: randomize all colors */
  51205. X         case ENTER_2:                  /* also the Numeric-Keypad Enter */
  51206. X            fkey = rand15()/3277 + 1;
  51207. X        if (reallyega)        /* limit on EGAs */
  51208. X           fkey = (fkey+1)>>1;
  51209. X        fstep = 1;
  51210. X        incr = 999;
  51211. X        oldstep = step;
  51212. X        step = rotate_size;
  51213. X        break;
  51214. X     case 'r':                      /* color changes */
  51215. X        if (changecolor    == -1) changecolor = 0;
  51216. X     case 'g':                      /* color changes */
  51217. X        if (changecolor    == -1) changecolor = 1;
  51218. X     case 'b':                      /* color changes */
  51219. X        if (changecolor    == -1) changecolor = 2;
  51220. X        if (changedirection == 0) changedirection = -1;
  51221. X     case 'R':                      /* color changes */
  51222. X        if (changecolor    == -1) changecolor = 0;
  51223. X     case 'G':                      /* color changes */
  51224. X        if (changecolor    == -1) changecolor = 1;
  51225. X     case 'B':                      /* color changes */
  51226. X        if (dotmode == 11) break;
  51227. X        if (changecolor    == -1) changecolor = 2;
  51228. X        if (changedirection == 0) changedirection = 1;
  51229. X        if (reallyega) break;    /* no sense on real EGAs */
  51230. X        for (i = 1; i < 256; i++) {
  51231. X           dacbox[i][changecolor] += changedirection;
  51232. X           if (dacbox[i][changecolor] == 64)
  51233. X           dacbox[i][changecolor] = 63;
  51234. X           if (dacbox[i][changecolor] == 255)
  51235. X          dacbox[i][changecolor] = 0;
  51236. X           }
  51237. X        changecolor    = -1;    /* clear flags for next time */
  51238. X        changedirection = 0;
  51239. X        paused        = 0;    /* clear any pause */
  51240. X     case ' ':                      /* use the spacebar as a "pause" toggle */
  51241. X     case 'c':                      /* for completeness' sake, the 'c' too */
  51242. X     case 'C':
  51243. X        pauserotate();        /* pause */
  51244. X        break;
  51245. X     case '>':            /* single-step */
  51246. X     case '.':
  51247. X     case '<':
  51248. X     case ',':
  51249. X        if (kbdchar == '>' || kbdchar == '.') {
  51250. X           direction = 1;
  51251. X           last = rotate_max;
  51252. X           next = rotate_lo;
  51253. X           incr = 999;
  51254. X           }
  51255. X        else {
  51256. X           direction = -1;
  51257. X           last = rotate_lo;
  51258. X           next = rotate_max;
  51259. X           incr = 999;
  51260. X           }
  51261. X        fkey = 0;
  51262. X        spindac(direction,1);
  51263. X        if (! paused)
  51264. X           pauserotate();        /* pause */
  51265. X        break;
  51266. X     case 'd':                      /* load colors from "default.map" */
  51267. X     case 'D':
  51268. X        if (ValidateLuts("default") != 0)
  51269. X           break;
  51270. X        fkey = 0;            /* disable random generation */
  51271. X        pauserotate();        /* update palette and pause */
  51272. X        break;
  51273. X     case 'a':                      /* load colors from "altern.map" */
  51274. X     case 'A':
  51275. X        if (ValidateLuts("altern") != 0)
  51276. X           break;
  51277. X        fkey = 0;            /* disable random generation */
  51278. X        pauserotate();        /* update palette and pause */
  51279. X        break;
  51280. X     case 'l':                      /* load colors from a specified map */
  51281. X#ifndef XFRACT /* L is used for RIGHT_ARROW in Unix keyboard mapping */
  51282. X     case 'L':
  51283. X#endif
  51284. X        load_palette();
  51285. X        fkey = 0;            /* disable random generation */
  51286. X        pauserotate();        /* update palette and pause */
  51287. X        break;
  51288. X     case 's':                      /* save the palette */
  51289. X     case 'S':
  51290. X        save_palette();
  51291. X        fkey = 0;            /* disable random generation */
  51292. X        pauserotate();        /* update palette and pause */
  51293. X        break;
  51294. X         case ESC:                      /* escape */
  51295. X        more = 0;            /* time to bail out */
  51296. X        break;
  51297. X     default:            /* maybe a new palette */
  51298. X        if (reallyega) break;    /* no sense on real EGAs */
  51299. X        fkey = 0;            /* disable random generation */
  51300. X        if (kbdchar == 1084) set_palette(Black, White);
  51301. X        if (kbdchar == SF2) set_palette(Red, Yellow);
  51302. X        if (kbdchar == SF3) set_palette(Blue, Green);
  51303. X        if (kbdchar == SF4) set_palette(Black, Yellow);
  51304. X        if (kbdchar == SF5) set_palette(Black, Red);
  51305. X        if (kbdchar == SF6) set_palette(Black, Blue);
  51306. X        if (kbdchar == SF7) set_palette(Black, Green);
  51307. X        if (kbdchar == SF8) set_palette(Blue, Yellow);
  51308. X        if (kbdchar == SF9) set_palette(Red, Green);
  51309. X        if (kbdchar == 1093) set_palette(Green, White);
  51310. X        if (kbdchar == 1094) set_palette2(Black, White);
  51311. X        if (kbdchar == 1095) set_palette2(Red, Yellow);
  51312. X        if (kbdchar == 1096) set_palette2(Blue, Green);
  51313. X        if (kbdchar == 1097) set_palette2(Black, Yellow);
  51314. X        if (kbdchar == 1098) set_palette2(Black, Red);
  51315. X        if (kbdchar == 1099) set_palette2(Black, Blue);
  51316. X        if (kbdchar == 1100) set_palette2(Black, Green);
  51317. X        if (kbdchar == 1101) set_palette2(Blue, Yellow);
  51318. X        if (kbdchar == 1102) set_palette2(Red, Green);
  51319. X        if (kbdchar == 1103) set_palette2(Green, White);
  51320. X        if (kbdchar == 1104) set_palette3(Blue, Green, Red);
  51321. X        if (kbdchar == 1105) set_palette3(Blue, Yellow, Red);
  51322. X        if (kbdchar == 1106) set_palette3(Red, White, Blue);
  51323. X        if (kbdchar == 1107) set_palette3(Red, Yellow, White);
  51324. X        if (kbdchar == 1108) set_palette3(Black, Brown, Yellow);
  51325. X        if (kbdchar == 1109) set_palette3(Blue, Brown, Green);
  51326. X        if (kbdchar == 1110) set_palette3(Blue, Green, Green);
  51327. X        if (kbdchar == 1111) set_palette3(Blue, Green, White);
  51328. X        if (kbdchar == 1112) set_palette3(Green, Green, White);
  51329. X        if (kbdchar == 1113) set_palette3(Red, Blue, White);
  51330. X        pauserotate();  /* update palette and pause */
  51331. X        break;
  51332. X     }
  51333. X      }
  51334. X
  51335. X   helpmode = oldhelpmode;        /* return to previous help mode */
  51336. X   EXIT_OVLY;
  51337. X}
  51338. X
  51339. Xstatic void pauserotate()        /* pause-the-rotate routine */
  51340. X{
  51341. Xint olddaccount;            /* saved dac-count value goes here */
  51342. XBYTE olddac0,olddac1,olddac2;
  51343. X
  51344. X   if (paused)                /* if already paused , just clear */
  51345. X      paused = 0;
  51346. X   else {                /* else set border, wait for a key */
  51347. X      olddaccount = daccount;
  51348. X      olddac0 = dacbox[0][0];
  51349. X      olddac1 = dacbox[0][1];
  51350. X      olddac2 = dacbox[0][2];
  51351. X      daccount = 256;
  51352. X      dacbox[0][0] = 48;
  51353. X      dacbox[0][1] = 48;
  51354. X      dacbox[0][2] = 48;
  51355. X      spindac(0,1);            /* show white border */
  51356. X      if (dotmode == 11)
  51357. X         dvid_status(100," Paused in \"color cycling\" mode ");
  51358. X#ifndef XFRACT
  51359. X      while (!keypressed());          /* wait for any key */
  51360. X#else
  51361. X      waitkeypressed(0);                /* wait for any key */
  51362. X#endif
  51363. X      if (dotmode == 11)
  51364. X     dvid_status(0,"");
  51365. X      dacbox[0][0] = olddac0;
  51366. X      dacbox[0][1] = olddac1;
  51367. X      dacbox[0][2] = olddac2;
  51368. X      spindac(0,1);            /* show black border */
  51369. X      daccount = olddaccount;
  51370. X      paused = 1;
  51371. X      }
  51372. X}
  51373. X
  51374. Xstatic void set_palette(start, finish)
  51375. XBYTE start[3], finish[3];
  51376. X{
  51377. X   int i, j;
  51378. X   dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  51379. X   for(i=1;i<=255;i++)            /* fill the palette    */
  51380. X      for (j = 0; j < 3; j++)
  51381. X     dacbox[i][j] = (i*start[j] + (256-i)*finish[j])/255;
  51382. X}
  51383. X
  51384. Xstatic void set_palette2(start, finish)
  51385. XBYTE start[3], finish[3];
  51386. X{
  51387. X   int i, j;
  51388. X   dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  51389. X   for(i=1;i<=128;i++)
  51390. X      for (j = 0; j < 3; j++) {
  51391. X     dacbox[i][j]      = (i*finish[j] + (128-i)*start[j] )/128;
  51392. X     dacbox[i+127][j] = (i*start[j]  + (128-i)*finish[j])/128;
  51393. X      }
  51394. X}
  51395. X
  51396. Xstatic void set_palette3(start, middle, finish)
  51397. XBYTE start[3], middle[3], finish[3];
  51398. X{
  51399. X   int i, j;
  51400. X   dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  51401. X   for(i=1;i<=85;i++)
  51402. X      for (j = 0; j < 3; j++) {
  51403. X     dacbox[i][j]      = (i*middle[j] + (86-i)*start[j] )/85;
  51404. X     dacbox[i+85][j]  = (i*finish[j] + (86-i)*middle[j])/85;
  51405. X     dacbox[i+170][j] = (i*start[j]  + (86-i)*finish[j])/85;
  51406. X      }
  51407. X}
  51408. X
  51409. X
  51410. Xvoid save_palette()
  51411. X{
  51412. X   FILE *dacfile;
  51413. X   int i,oldhelpmode;
  51414. X   oldhelpmode = helpmode;
  51415. X   stackscreen();
  51416. X   temp1[0] = 0;
  51417. X   helpmode = HELPCOLORMAP;
  51418. X   i = field_prompt(0,"Name of map file to write",NULL,temp1,60,NULL);
  51419. X   unstackscreen();
  51420. X   if (i != -1 && temp1[0]) {
  51421. X      if (strchr(temp1,'.') == NULL)
  51422. X     strcat(temp1,".map");
  51423. X      dacfile = fopen(temp1,"w");
  51424. X      if (dacfile == NULL)
  51425. X     buzzer(2);
  51426. X      else {
  51427. X#ifndef XFRACT
  51428. X     for (i = 0; i < colors; i++)
  51429. X#else
  51430. X     for (i = 0; i < 256; i++)
  51431. X#endif
  51432. X        fprintf(dacfile, "%3d %3d %3d\n",
  51433. X            dacbox[i][0] << 2,
  51434. X            dacbox[i][1] << 2,
  51435. X            dacbox[i][2] << 2);
  51436. X     memcpy(olddacbox,dacbox,256*3);
  51437. X     colorstate = 2;
  51438. X     strcpy(colorfile,temp1);
  51439. X     }
  51440. X      fclose(dacfile);
  51441. X      }
  51442. X   helpmode = oldhelpmode;
  51443. X}
  51444. X
  51445. X
  51446. Xvoid load_palette(void)
  51447. X{
  51448. X   int i,oldhelpmode;
  51449. X   char filename[80];
  51450. X   oldhelpmode = helpmode;
  51451. X   strcpy(filename,colorfile);
  51452. X   stackscreen();
  51453. X   helpmode = HELPCOLORMAP;
  51454. X   i = getafilename("Select a MAP File",mapmask,filename);
  51455. X   unstackscreen();
  51456. X   if (i >= 0)
  51457. X      if (ValidateLuts(filename) == 0)
  51458. X     memcpy(olddacbox,dacbox,256*3);
  51459. X   helpmode = oldhelpmode;
  51460. X}
  51461. X
  51462. X
  51463. SHAR_EOF
  51464. $TOUCH -am 1028230093 rotate.c &&
  51465. chmod 0644 rotate.c ||
  51466. echo "restore of rotate.c failed"
  51467. set `wc -c rotate.c`;Wc_c=$1
  51468. if test "$Wc_c" != "14636"; then
  51469.     echo original size 14636, current size $Wc_c
  51470. fi
  51471. # ============= slideshw.c ==============
  51472. echo "x - extracting slideshw.c (Text)"
  51473. sed 's/^X//' << 'SHAR_EOF' > slideshw.c &&
  51474. X/***********************************************************************/
  51475. X/* These routines are called by getakey to allow keystrokes to control */
  51476. X/* Fractint to be read from a file.                       */
  51477. X/***********************************************************************/
  51478. X
  51479. X#include <stdio.h>
  51480. X#include <stdlib.h>
  51481. X#include <ctype.h>
  51482. X#include <time.h>
  51483. X#include <string.h>
  51484. X#ifndef XFRACT
  51485. X#include <conio.h>
  51486. X#endif
  51487. X#include "fractint.h"
  51488. X#include "prototyp.h"
  51489. X
  51490. Xstatic void sleep(int);
  51491. Xstatic int  showtempmsg_txt(int,int,int,int,char *);
  51492. Xstatic void message(int secs, char far *buf);
  51493. Xstatic void slideshowerr(char far *msg);
  51494. Xstatic int  get_scancode(char *mn);
  51495. Xstatic char far *get_mnemonic(int code);
  51496. X
  51497. Xstruct scancodes
  51498. X{
  51499. X   int code;
  51500. X   char far *mnemonic;
  51501. X};
  51502. Xstatic struct scancodes far scancodes[] =
  51503. X{
  51504. X   {  ENTER,      "ENTER"       },
  51505. X   {  INSERT,      "INSERT"      },
  51506. X   {  DELETE,      "DELETE"      },
  51507. X   {  ESC,      "ESC"         },
  51508. X   {  TAB,      "TAB"         },
  51509. X   {  PAGE_UP,      "PAGEUP"      },
  51510. X   {  PAGE_DOWN,  "PAGEDOWN"    },
  51511. X   {  HOME,      "HOME"        },
  51512. X   {  END,      "END"         },
  51513. X   {  LEFT_ARROW, "LEFT"        },
  51514. X   {  RIGHT_ARROW,"RIGHT"       },
  51515. X   {  UP_ARROW,   "UP"          },
  51516. X   {  DOWN_ARROW, "DOWN"        },
  51517. X   {  F1,      "F1"          },
  51518. X   {  -1,      NULL        }
  51519. X};
  51520. X#define stop sizeof(scancodes)/sizeof(struct scancodes)-1
  51521. X
  51522. Xstatic int get_scancode(char *mn)
  51523. X{
  51524. X   int i;
  51525. X   i = 0;
  51526. X   for(i=0;i< stop;i++)
  51527. X      if(far_strcmp((char far *)mn,scancodes[i].mnemonic)==0)
  51528. X     break;
  51529. X   return(scancodes[i].code);
  51530. X}
  51531. X
  51532. Xstatic char far *get_mnemonic(int code)
  51533. X{
  51534. X   int i;
  51535. X   i = 0;
  51536. X   for(i=0;i< stop;i++)
  51537. X      if(code == scancodes[i].code)
  51538. X     break;
  51539. X   return(scancodes[i].mnemonic);
  51540. X}
  51541. X#undef stop
  51542. X
  51543. Xchar busy = 0;
  51544. Xstatic FILE *fp = NULL;
  51545. Xextern int slides;
  51546. Xextern int text_type;
  51547. Xextern int calc_status;
  51548. Xextern char autoname[];
  51549. Xstatic long starttick;
  51550. Xstatic long ticks;
  51551. Xstatic int slowcount;
  51552. Xstatic unsigned int quotes;
  51553. Xstatic char calcwait = 0;
  51554. Xstatic int repeats = 0;
  51555. Xstatic int last = 0;
  51556. Xstatic char far smsg[] = "MESSAGE";
  51557. Xstatic char far sgoto[] = "GOTO";
  51558. Xstatic char far scalcwait[] = "CALCWAIT";
  51559. Xstatic char far swait[] = "WAIT";
  51560. X
  51561. X/* places a temporary message on the screen in text mode */
  51562. Xstatic int showtempmsg_txt(int row, int col, int attr,int secs,char *txt)
  51563. X{
  51564. X   int savescrn[80];
  51565. X   int i;
  51566. X   if(text_type > 1)
  51567. X      return(1);
  51568. X   for(i=0;i<80;i++)
  51569. X   {
  51570. X      movecursor(row,i);
  51571. X      savescrn[i] = get_a_char();
  51572. X   }
  51573. X   putstring(row,col,attr,txt);
  51574. X   movecursor(25,80);
  51575. X   sleep(secs);
  51576. X   for(i=0;i<80;i++)
  51577. X   {
  51578. X      movecursor(row,i);
  51579. X      put_a_char(savescrn[i]);
  51580. X   }
  51581. X   return(0);
  51582. X}
  51583. X
  51584. Xstatic void message(int secs, char far *buf)
  51585. X{
  51586. X   int i;
  51587. X   char nearbuf[41];
  51588. X   i = -1;
  51589. X   while(buf[++i] && i< 40)
  51590. X      nearbuf[i] = buf[i];
  51591. X   nearbuf[i] = 0;
  51592. X   if(text_type < 2)
  51593. X      showtempmsg_txt(0,0,7,secs,nearbuf);
  51594. X   else if (showtempmsg(nearbuf) == 0)
  51595. X      {
  51596. X     sleep(secs);
  51597. X     cleartempmsg();
  51598. X      }
  51599. X}
  51600. X
  51601. X/* this routine reads the file autoname and returns keystrokes */
  51602. Xint slideshw()
  51603. X{
  51604. X   int out,err,i;
  51605. X   char buffer[81];
  51606. X   if(calcwait)
  51607. X   {
  51608. X      if(calc_status == 1 || busy) /* restart timer - process not done */
  51609. X     return(0); /* wait for calc to finish before reading more keystrokes */
  51610. X      calcwait = 0;
  51611. X   }
  51612. X   if(fp==NULL)   /* open files first time through */
  51613. X      if(startslideshow()==0)
  51614. X     {
  51615. X     stopslideshow();
  51616. X     return (0);
  51617. X     }
  51618. X
  51619. X   if(ticks) /* if waiting, see if waited long enough */
  51620. X   {
  51621. X      if(clock_ticks() - starttick < ticks) /* haven't waited long enough */
  51622. X     return(0);
  51623. X      ticks = 0;
  51624. X   }
  51625. X   if (++slowcount <= 18)
  51626. X   {
  51627. X      starttick = clock_ticks();
  51628. X      ticks = CLK_TCK/5; /* a slight delay so keystrokes are visible */
  51629. X      if (slowcount > 10)
  51630. X     ticks /= 2;
  51631. X   }
  51632. X   if(repeats>0)
  51633. X   {
  51634. X      repeats--;
  51635. X      return(last);
  51636. X   }
  51637. Xstart:
  51638. X   if(quotes) /* reading a quoted string */
  51639. X   {
  51640. X      if((out=fgetc(fp)) != '\"' && out != EOF)
  51641. X     return(last=out);
  51642. X      quotes = 0;
  51643. X   }
  51644. X   /* skip white space: */
  51645. X   while ((out=fgetc(fp)) == ' ' || out == '\t' || out == '\n') { }
  51646. X   switch(out)
  51647. X   {
  51648. X      case EOF:
  51649. X     stopslideshow();
  51650. X     return(0);
  51651. X      case '\"':        /* begin quoted string */
  51652. X     quotes = 1;
  51653. X     goto start;
  51654. X      case ';':         /* comment from here to end of line, skip it */
  51655. X     while((out=fgetc(fp)) != '\n' && out != EOF) { }
  51656. X     goto start;
  51657. X      case '*':
  51658. X     if (fscanf(fp,"%d",&repeats) != 1
  51659. X       || repeats <= 1 || repeats >= 256 || feof(fp))
  51660. X     {
  51661. X        static char far msg[] = "error in * argument";
  51662. X        slideshowerr(msg);
  51663. X        last = repeats = 0;
  51664. X     }
  51665. X     repeats -= 2;
  51666. X     return(out = last);
  51667. X   }
  51668. X
  51669. X   i = 0;
  51670. X   while(1) /* get a token */
  51671. X   {
  51672. X      if(i < 80)
  51673. X     buffer[i++] = out;
  51674. X      if((out=fgetc(fp)) == ' ' || out == '\t' || out == '\n' || out == EOF)
  51675. X     break;
  51676. X   }
  51677. X   buffer[i] = 0;
  51678. X   if(buffer[i-1] == ':')
  51679. X      goto start;
  51680. X   out = -12345;
  51681. X   if(isdigit(buffer[0]))    /* an arbitrary scan code number - use it */
  51682. X     out=atoi(buffer);
  51683. X   else if(far_strcmp((char far *)buffer,smsg)==0)
  51684. X      {
  51685. X     int secs;
  51686. X     out = 0;
  51687. X     if (fscanf(fp,"%d",&secs) != 1)
  51688. X     {
  51689. X        static char far msg[] = "MESSAGE needs argument";
  51690. X        slideshowerr(msg);
  51691. X     }
  51692. X     else
  51693. X     {
  51694. X        int len;
  51695. X        char buf[41];
  51696. X        buf[40] = 0;
  51697. X        fgets(buf,40,fp);
  51698. X        len = strlen(buf);
  51699. X        buf[len-1]=0; /* zap newline */
  51700. X        message(secs,(char far *)buf);
  51701. X     }
  51702. X     out = 0;
  51703. X      }
  51704. X   else if(far_strcmp((char far *)buffer,sgoto)==0)
  51705. X      {
  51706. X     if (fscanf(fp,"%s",buffer) != 1)
  51707. X     {
  51708. X        static char far msg[] = "GOTO needs target";
  51709. X        slideshowerr(msg);
  51710. X        out = 0;
  51711. X     }
  51712. X     else
  51713. X     {
  51714. X        char buffer1[80];
  51715. X        rewind(fp);
  51716. X        strcat(buffer,":");
  51717. X        do
  51718. X        {
  51719. X           err = fscanf(fp,"%s",buffer1);
  51720. X        } while( err == 1 && strcmp(buffer1,buffer) != 0);
  51721. X        if(feof(fp))
  51722. X        {
  51723. X           static char far msg[] = "GOTO target not found";
  51724. X           slideshowerr(msg);
  51725. X           return(0);
  51726. X        }
  51727. X        goto start;
  51728. X     }
  51729. X      }
  51730. X   else if((i = get_scancode(buffer)) > 0)
  51731. X     out = i;
  51732. X   else if(far_strcmp(swait,(char far *)buffer)==0)
  51733. X      {
  51734. X     float fticks;
  51735. X     err = fscanf(fp,"%f",&fticks); /* how many ticks to wait */
  51736. X     fticks *= CLK_TCK;        /* convert from seconds to ticks */
  51737. X     if(err==1)
  51738. X     {
  51739. X        ticks = fticks;
  51740. X        starttick = clock_ticks();    /* start timing */
  51741. X     }
  51742. X     else
  51743. X     {
  51744. X        static char far msg[] = "WAIT needs argument";
  51745. X        slideshowerr(msg);
  51746. X     }
  51747. X     slowcount = out = 0;
  51748. X      }
  51749. X   else if(far_strcmp(scalcwait,(char far *)buffer)==0) /* wait for calc to finish */
  51750. X      {
  51751. X     calcwait = 1;
  51752. X     slowcount = out = 0;
  51753. X      }
  51754. X   else if((i=check_vidmode_keyname(buffer)))
  51755. X      out = i;
  51756. X   if(out == -12345)
  51757. X   {
  51758. X      extern char s_cantunderstand[];
  51759. X      char msg[80];
  51760. X      sprintf(msg,s_cantunderstand,buffer);
  51761. X      slideshowerr(msg);
  51762. X      out = 0;
  51763. X   }
  51764. X   return(last=out);
  51765. X}
  51766. X
  51767. Xstartslideshow()
  51768. X{
  51769. X   if((fp=fopen(autoname,"r"))==NULL)
  51770. X      slides = 0;
  51771. X   ticks = 0;
  51772. X   quotes = 0;
  51773. X   calcwait = 0;
  51774. X   slowcount = 0;
  51775. X   return(slides);
  51776. X}
  51777. X
  51778. Xvoid stopslideshow()
  51779. X{
  51780. X   if(fp)
  51781. X      fclose(fp);
  51782. X   fp = NULL;
  51783. X   slides = 0;
  51784. X}
  51785. X
  51786. Xvoid recordshw(int key)
  51787. X{
  51788. X   char far *mn;
  51789. X   float dt;
  51790. X   dt = ticks;       /* save time of last call */
  51791. X   ticks=clock_ticks();  /* current time */
  51792. X   if(fp==NULL)
  51793. X      if((fp=fopen(autoname,"w"))==NULL)
  51794. X     return;
  51795. X   dt = ticks-dt;
  51796. X   dt /= CLK_TCK;  /* dt now in seconds */
  51797. X   if(dt > .5) /* don't bother with less than half a second */
  51798. X   {
  51799. X      if(quotes) /* close quotes first */
  51800. X      {
  51801. X     quotes=0;
  51802. X     fprintf(fp,"\"\n",dt);
  51803. X      }
  51804. X      fprintf(fp,"WAIT %4.1f\n",dt);
  51805. X   }
  51806. X   if(key >= 32 && key < 128)
  51807. X   {
  51808. X      if(!quotes)
  51809. X      {
  51810. X     quotes=1;
  51811. X     fputc('\"',fp);
  51812. X      }
  51813. X      fputc(key,fp);
  51814. X   }
  51815. X   else
  51816. X   {
  51817. X      if(quotes) /* not an ASCII character - turn off quotes */
  51818. X      {
  51819. X     fprintf(fp,"\"\n");
  51820. X     quotes=0;
  51821. X      }
  51822. X      if((mn=get_mnemonic(key)) != NULL)
  51823. X#ifndef XFRACT
  51824. X      fprintf(fp,"%Fs",mn);
  51825. X#else
  51826. X          fprintf(fp,"%s",mn);
  51827. X#endif
  51828. X      else if (check_vidmode_key(0,key) >= 0)
  51829. X     {
  51830. X        char buf[10];
  51831. X        vidmode_keyname(key,buf);
  51832. X        fprintf(fp,buf);
  51833. X     }
  51834. X      else /* not ASCII and not FN key */
  51835. X     fprintf(fp,"%4d",key);
  51836. X      fputc('\n',fp);
  51837. X   }
  51838. X}
  51839. X
  51840. X/* suspend process # of seconds */
  51841. Xstatic void sleep(int secs)
  51842. X{
  51843. X   long stop;
  51844. X   stop = clock_ticks() + (long)secs*CLK_TCK;
  51845. X   while(clock_ticks() < stop && kbhit() == 0) { } /* bailout if key hit */
  51846. X}
  51847. X
  51848. Xstatic void slideshowerr(char far *msg)
  51849. X{
  51850. X   char msgbuf[300];
  51851. X   static char far errhdg[] = "Slideshow error:\n";
  51852. X   stopslideshow();
  51853. X   far_strcpy(msgbuf,errhdg);
  51854. X   far_strcat(msgbuf,msg);
  51855. X   stopmsg(0,msgbuf);
  51856. X}
  51857. SHAR_EOF
  51858. $TOUCH -am 1028230093 slideshw.c &&
  51859. chmod 0644 slideshw.c ||
  51860. echo "restore of slideshw.c failed"
  51861. set `wc -c slideshw.c`;Wc_c=$1
  51862. if test "$Wc_c" != "8468"; then
  51863.     echo original size 8468, current size $Wc_c
  51864. fi
  51865. # ============= targa.c ==============
  51866. echo "x - extracting targa.c (Text)"
  51867. sed 's/^X//' << 'SHAR_EOF' > targa.c &&
  51868. X/** targa.c **/
  51869. X
  51870. X#ifdef __TURBOC__
  51871. X#    pragma    warn -par
  51872. X#endif
  51873. X
  51874. X#define TARGA_DATA
  51875. X
  51876. X#include    <stdio.h>
  51877. X#include    <stdlib.h>
  51878. X#include    <string.h>
  51879. X#ifndef XFRACT
  51880. X#include    <conio.h>
  51881. X#endif
  51882. X#include    "targa.h"
  51883. X#include    "fractint.h"
  51884. X#include    "prototyp.h"
  51885. X
  51886. X
  51887. X/*************    ****************/
  51888. X
  51889. Xextern char far *mapdacbox;
  51890. X
  51891. X/*************    ****************/
  51892. X
  51893. Xvoid    WriteTGA( int x, int y, int index );
  51894. Xint    ReadTGA ( int x, int y );
  51895. Xvoid    EndTGA    ( void );
  51896. Xvoid    StartTGA( void );
  51897. Xvoid    ReopenTGA( void );
  51898. X
  51899. X/*************    ****************/
  51900. X
  51901. Xstatic unsigned _fastcall near Row16Calculate(unsigned,unsigned);
  51902. Xstatic void    _fastcall near PutPix16(int,int,int);
  51903. Xstatic unsigned _fastcall near GetPix16(int,int);
  51904. Xstatic unsigned _fastcall near Row32Calculate(unsigned,unsigned);
  51905. Xstatic void    _fastcall near PutPix32(int,int,int);
  51906. Xstatic unsigned _fastcall near GetPix32(int,int);
  51907. Xstatic void    _fastcall near DoFirstPixel(int,int,int);
  51908. Xstatic void _fastcall fatalerror(char far *);
  51909. Xstatic int  GetLine(int);
  51910. Xstatic void _fastcall near SetDispReg(int,int);
  51911. Xstatic int  VWait(void);
  51912. Xstatic void _fastcall SetVBorder(int,int);
  51913. Xstatic void _fastcall SetBorderColor(long);
  51914. Xstatic void _fastcall SetVertShift(int);
  51915. Xstatic void _fastcall SetInterlace(int);
  51916. Xstatic void _fastcall SetBlndReg(int);
  51917. Xstatic void _fastcall SetRGBorCV(int);
  51918. Xstatic void _fastcall SetVCRorCamera(int);
  51919. Xstatic void _fastcall SetMask(int);
  51920. Xstatic void _fastcall SetBlndReg(int);
  51921. Xstatic void _fastcall SetContrast(int);
  51922. Xstatic void _fastcall SetHue(int);
  51923. Xstatic void _fastcall SetSaturation(int);
  51924. Xstatic void _fastcall SetHBorder(int,int);
  51925. Xstatic void SetFixedRegisters(void);
  51926. Xstatic void _fastcall VCenterDisplay(int);
  51927. Xstatic void _fastcall SetOverscan(int);
  51928. Xstatic void _fastcall near TSetMode(int);
  51929. Xstatic int  GraphInit(void);
  51930. Xstatic void GraphEnd(void);
  51931. X
  51932. X/*************    ****************/
  51933. X
  51934. Xint         xorTARGA;
  51935. Xunsigned far *tga16 = NULL;  /* [256] */
  51936. Xlong     far *tga32;         /* [256] */
  51937. Xstatic int   last = 0;
  51938. X
  51939. X/*************    ****************/
  51940. X
  51941. Xextern int    sxdots,sydots;        /* # of dots on the physical screen */
  51942. Xstatic int    initialized;
  51943. X
  51944. X/*************    ****************/
  51945. X
  51946. Xstatic void    (near _fastcall *DoPixel) ( int x, int y, int index );
  51947. Xstatic void    (near _fastcall *PutPixel)( int x, int y, int index );
  51948. Xstatic unsigned (near _fastcall *GetPixel)( int x, int y );
  51949. X
  51950. X/**************************************************************************/
  51951. X#ifdef __BORLANDC__
  51952. X#if(__BORLANDC__ > 2)
  51953. X   #pragma warn -eff
  51954. X#endif
  51955. X#endif
  51956. X
  51957. Xstatic unsigned _fastcall near Row16Calculate( unsigned line, unsigned x1 )
  51958. X{
  51959. X    outp( DESTREG, (line >> 5) );
  51960. X    return( ((line & 31) << 10) | (x1 << 1) ); /* calc the pixel offset */
  51961. X}
  51962. X
  51963. X/**************************************************************************/
  51964. X
  51965. Xstatic void _fastcall near PutPix16( int x, int y, int index )
  51966. X{
  51967. Xunsigned far * ip;
  51968. X
  51969. X    /**************/
  51970. X    ip = MK_FP( MEMSEG, Row16Calculate( y, x ) );
  51971. X    if( ! xorTARGA )
  51972. X        *ip = tga16[index];
  51973. X    else
  51974. X        *ip = *ip ^ 0x7fff;
  51975. X}
  51976. X
  51977. X/**************************************************************************/
  51978. X
  51979. Xstatic unsigned _fastcall near GetPix16( int x, int y )
  51980. X{
  51981. Xregister unsigned pixel, index;
  51982. Xunsigned far * ip;
  51983. X    /**************/
  51984. X    ip = MK_FP( MEMSEG, Row16Calculate( y, x ) );
  51985. X    pixel = *ip & 0x7FFF;
  51986. X    if( pixel == tga16[last] ) return( last );
  51987. X    for( index = 0; index < 256; index++ )
  51988. X        if( pixel == tga16[index] ) {
  51989. X            last = index;
  51990. X            return( index );
  51991. X        }
  51992. X    return( 0 );
  51993. X}
  51994. X
  51995. X/**************************************************************************/
  51996. X
  51997. Xstatic unsigned _fastcall near Row32Calculate( unsigned line, unsigned x1 )
  51998. X{
  51999. X    outp( DESTREG, (line >> 4) );
  52000. X    return ( ((line & 15) << 11) | (x1 << 2) ); /* calc the pixel offset */
  52001. X}
  52002. X
  52003. X/**************************************************************************/
  52004. X
  52005. Xstatic void _fastcall near PutPix32( int x, int y, int index )
  52006. X{
  52007. Xlong far * lp;
  52008. X    lp = MK_FP( MEMSEG, Row32Calculate( y, x ) );
  52009. X    if( ! xorTARGA )
  52010. X        *lp = tga32[index];
  52011. X    else
  52012. X        *lp = *lp ^ 0x00FFFFFF;
  52013. X}
  52014. X
  52015. X/**************************************************************************/
  52016. X
  52017. Xstatic unsigned _fastcall near GetPix32( int x, int y )
  52018. X{
  52019. Xregister int index;
  52020. Xlong    pixel;
  52021. Xlong    far * lp;
  52022. X
  52023. X    lp = MK_FP( MEMSEG, Row32Calculate( y, x ) );
  52024. X    pixel = *lp & 0x00FFFFFF;
  52025. X    if( pixel == tga32[last] ) return( last );
  52026. X    for( index = 0; index < 256; index++ )
  52027. X        if( pixel == tga32[index] ) {
  52028. X            last = index;
  52029. X            return( index );
  52030. X        }
  52031. X    return( 0 );
  52032. X}
  52033. X
  52034. X/**************************************************************************/
  52035. X
  52036. Xstatic void _fastcall near DoFirstPixel( int x, int y, int index )
  52037. X{
  52038. Xint cnt;
  52039. X    TSetMode( targa.mode | 1 );
  52040. X    for( cnt = 0; cnt < targa.MaxBanks; cnt += 2 ) { /* erase */
  52041. X        outp( DESTREG, cnt );
  52042. X        outp( SRCREG,  cnt + 1 );
  52043. X        erasesegment(targa.memloc,0);  /** general.asm **/
  52044. X    }
  52045. X    TSetMode( targa.mode & 0xFFFE );
  52046. X    PutPixel = DoPixel;
  52047. X    (*PutPixel)( x, y, index );
  52048. X}
  52049. X
  52050. X#ifdef __BORLANDC__
  52051. X#if(__BORLANDC__ > 2)
  52052. X   #pragma warn +eff
  52053. X#endif
  52054. X#endif
  52055. X
  52056. X/***************************************************************************/
  52057. X
  52058. Xvoid WriteTGA( int x, int y, int index )
  52059. X{
  52060. X    OUTPORTB(MODEREG, targa.mode |= 1 );    /* TSetMode inline for speed */
  52061. X    (*PutPixel)( x, sydots-y, index&0xFF ); /* fix origin to match EGA/VGA */
  52062. X    OUTPORTB(MODEREG, targa.mode &= 0xFFFE );
  52063. X}
  52064. X
  52065. X/***************************************************************************/
  52066. X
  52067. Xint ReadTGA( int x, int y )
  52068. X{
  52069. Xint val;
  52070. X    OUTPORTB(MODEREG, targa.mode |= 1 );    /* TSetMode inline for speed */
  52071. X    val = (*GetPixel)( x, sydots-y );
  52072. X    OUTPORTB(MODEREG, targa.mode &= 0xFFFE );
  52073. X    return( val );
  52074. X}
  52075. X
  52076. X/***************************************************************************/
  52077. X
  52078. Xvoid EndTGA( void )
  52079. X{
  52080. X    if( initialized ) {
  52081. X        GraphEnd();
  52082. X        initialized = 0;
  52083. X    }
  52084. X}
  52085. X
  52086. X/***************************************************************************/
  52087. X
  52088. Xvoid StartTGA()
  52089. X{
  52090. Xint    i;
  52091. Xstatic char far couldntfind[]={"Could not find Targa card"};
  52092. Xstatic char far noenvvar[]={"TARGA environment variable missing"};
  52093. Xstatic char far insuffmem[]={"Insufficient memory for Targa"};
  52094. X
  52095. X    /****************/
  52096. X    if( initialized ) return;
  52097. X    initialized = 1;
  52098. X
  52099. X    /****************/
  52100. X    /* note that video.asm has already set the regualar video adapter */
  52101. X    /* to text mode (ax in Targa table entries is 3);          */
  52102. X    /* that's necessary because TARGA can live at 0xA000, we DO NOT   */
  52103. X    /* want to have an EGA/VGA in graphics mode!!              */
  52104. X    ReopenTGA(); /* clear text screen and display message */
  52105. X
  52106. X    /****************/
  52107. X    /*** look for and activate card ***/
  52108. X    if ((i = GraphInit()))
  52109. X        fatalerror((i == -1) ? couldntfind : noenvvar);
  52110. X
  52111. X    VCenterDisplay( sydots + 1 );
  52112. X
  52113. X    if (tga16 == NULL)
  52114. X        if ( (tga16 = (unsigned far *)farmemalloc(512L)) == NULL
  52115. X          || (tga32 = (long     far *)farmemalloc(1024L)) == NULL)
  52116. X        fatalerror(insuffmem);
  52117. X
  52118. X    SetTgaColors();
  52119. X
  52120. X    if( targa.boardType == 16 ) {
  52121. X        GetPixel = GetPix16;
  52122. X        DoPixel = PutPix16;
  52123. X    }
  52124. X    else {
  52125. X        GetPixel = GetPix32;
  52126. X        DoPixel = PutPix32;
  52127. X    }
  52128. X    PutPixel = DoFirstPixel;    /* on first pixel --> erase */
  52129. X
  52130. X    if( sydots == 482 ) SetOverscan( 1 );
  52131. X
  52132. X    TSetMode( targa.mode & 0xFFFE );
  52133. X
  52134. X    /****************/
  52135. X    if (mapdacbox == NULL && SetColorPaletteName("default") != 0)
  52136. X        exit( 1 ); /* stopmsg has already been issued */
  52137. X
  52138. X}
  52139. X
  52140. Xvoid ReopenTGA()
  52141. X{
  52142. Xstatic char far runningontarga[]={"Running On TrueVision TARGA Card"};
  52143. X    helptitle();
  52144. X    putstring(2,20,7,runningontarga);
  52145. X    movecursor(6,0); /* in case of brutal exit */
  52146. X}
  52147. X
  52148. Xstatic void _fastcall fatalerror(char far *msg)
  52149. X{
  52150. Xstatic char far abortmsg[]={"...aborting!"};
  52151. X    putstring(4,20,15,msg);
  52152. X    putstring(5,20,15,abortmsg);
  52153. X    movecursor(8,0);
  52154. X    exit(1);
  52155. X}
  52156. X
  52157. X
  52158. X
  52159. X/***  the rest of this module used to be separate, in tgasubs.c,  ***/
  52160. X/***  has now been merged into a single source              ***/
  52161. X
  52162. X/*******************************************************************/
  52163. X
  52164. Xstatic void _fastcall VCenterDisplay( int nLines )
  52165. X{
  52166. Xint    lines;
  52167. Xint top, bottom;
  52168. Xlong color;
  52169. X
  52170. X    lines  = nLines >> 1;        /* half value of last line 0..x */
  52171. X    top    = 140 - (lines >> 1);
  52172. X    bottom = top + lines;
  52173. X    SetVBorder( top, bottom );
  52174. X    SetVertShift( 255 - lines );    /* skip lines we're not using */
  52175. X
  52176. X    if( targa.boardType == 16 )
  52177. X        color = (12 << 10) | (12 << 5) | 12;
  52178. X    else
  52179. X        color = ((long)80 << 16) | (80 << 8) | 80;
  52180. X    SetBorderColor( color );
  52181. X}
  52182. X
  52183. X
  52184. X/*****************************************************************/
  52185. X
  52186. Xstatic void _fastcall near SetDispReg(int reg, int value)
  52187. X{
  52188. X    targa.DisplayRegister[reg] = value;
  52189. X
  52190. X    TSetMode(targa.mode&MSK_REGWRITE);  /* select Index Register write */
  52191. X    OUTPORTB(DRREG, reg);    /* select sync register */
  52192. X    /*
  52193. X     *        Set Mask register to write value to
  52194. X     *        display register and to set Bit 9 in the DR
  52195. X     */
  52196. X    TSetMode( ((targa.mode|(~MSK_REGWRITE))     /* turn on write bit */
  52197. X                   & MSK_BIT9       )     /* turn off Bit 9 */
  52198. X               | ((value&0x0100)>>1)); /* set bit 9 for value */
  52199. X    OUTPORTB(DRREG, value); /* select sync register */
  52200. X }
  52201. X
  52202. X/*****************************************************************/
  52203. X
  52204. X#define   WAITCOUNT  60000
  52205. X
  52206. Xstatic int VWait()
  52207. X{
  52208. Xint    rasterreg;
  52209. Xunsigned GiveUp;
  52210. X
  52211. X    rasterreg = RASTERREG;
  52212. X
  52213. X    /*
  52214. X     *    If beyond bottom of frame wait for next field
  52215. X     */
  52216. X    GiveUp= WAITCOUNT;
  52217. X    while ( (--GiveUp) && (GetLine(rasterreg) == 0) ) { }
  52218. X    if (GiveUp) {
  52219. X       /*
  52220. X        *       Wait for the bottom of the border
  52221. X        */
  52222. X       GiveUp= WAITCOUNT;
  52223. X       while ( (--GiveUp) && (GetLine(rasterreg) > 0) ) { }
  52224. X       }
  52225. X
  52226. X    return ( ( GiveUp ) ? 0 : -1);
  52227. X}
  52228. X
  52229. X
  52230. X/*****************************************************************/
  52231. X
  52232. Xstatic void _fastcall SetVBorder(int top, int bottom)
  52233. X{
  52234. X    /* top border */
  52235. X    if ( top < MIN_TOP ) top=MIN_TOP;
  52236. X    SetDispReg(TOPBORDER,top);
  52237. X    /* bottom border */
  52238. X    if ( bottom > MAX_BOTTOM ) bottom=MAX_BOTTOM;
  52239. X    SetDispReg(BOTTOMBORDER,bottom);
  52240. X
  52241. X    SetDispReg(DR10,top);
  52242. X    SetDispReg(DR11,bottom);
  52243. X}
  52244. X
  52245. X
  52246. X/*****************************************************************/
  52247. X
  52248. Xstatic void _fastcall SetRGBorCV(int type)
  52249. X{
  52250. X    /*  set the contrast level */
  52251. X    targa.RGBorCV = type;
  52252. X    targa.VCRCon = ( targa.VCRCon  & MSK_RGBORCV ) |
  52253. X                    (targa.RGBorCV<<SHF_RGBORCV) ;
  52254. X    OUTPORTB(VCRCON, targa.VCRCon );
  52255. X}
  52256. X
  52257. X/*****************************************************************/
  52258. X
  52259. Xstatic void _fastcall SetVCRorCamera(int type)
  52260. X{
  52261. X    targa.VCRorCamera = type&1;
  52262. X    targa.VCRCon = ( targa.VCRCon  & MSK_VCRORCAMERA ) |
  52263. X                    (targa.VCRorCamera<<SHF_VCRORCAMERA) ;
  52264. X    OUTPORTB(VCRCON, targa.VCRCon );
  52265. X}
  52266. X
  52267. X
  52268. X/*****************************************************************/
  52269. X
  52270. Xstatic void _fastcall SetBorderColor(long color)
  52271. X{
  52272. X    targa.BorderColor = color;
  52273. X    OUTPORTB(BORDER, (int)(0x0000ffffL&(color)));
  52274. X    OUTPORTB((BORDER+2), (int)((color)>>16));
  52275. X}
  52276. X
  52277. X/*****************************************************************/
  52278. X
  52279. Xstatic void _fastcall SetMask(int mask)
  52280. X{
  52281. X    /* mask to valid values and output to mode register */
  52282. X    targa.Mask = mask;
  52283. X    OUTPORTB(MASKREG, mask);
  52284. X}
  52285. X
  52286. X
  52287. X/*****************************************************************/
  52288. X
  52289. Xstatic void _fastcall SetVertShift(int preshift)
  52290. X{
  52291. X    /*  set the Vertical Preshift count  level */
  52292. X    targa.VertShift = preshift;
  52293. X    OUTPORTB(VERTPAN, preshift);
  52294. X}
  52295. X
  52296. X
  52297. X/*****************************************************************/
  52298. X
  52299. Xstatic void _fastcall SetOverscan(int mode)
  52300. X{
  52301. Xlong tempColor;
  52302. X
  52303. X    targa.ovrscnOn = mode;
  52304. X    if ( mode == 0 ) {
  52305. X            INPORTB(UNDERREG);  /*    select underscan mode */
  52306. X            SetHBorder(    (DEF_LEFT+targa.xOffset),
  52307. X                        (DEF_RIGHT+targa.xOffset));
  52308. X            SetDispReg(4,352);
  52309. X            SetDispReg(5,1);
  52310. X            SetBorderColor(targa.BorderColor);
  52311. X    }
  52312. X    else    {
  52313. X            INPORTB(OVERREG);   /*    select overrscan mode */
  52314. X            SetDispReg(0,64);   /*    Set four of the display registers */
  52315. X            SetDispReg(1,363);  /*    to values required for Overscan */
  52316. X            SetDispReg(4,363);
  52317. X            SetDispReg(5,17);
  52318. X            tempColor = targa.BorderColor;
  52319. X            SetBorderColor(0L);
  52320. X            targa.BorderColor = tempColor;
  52321. X    }
  52322. X}
  52323. X
  52324. X
  52325. X/*****************************************************************/
  52326. X
  52327. Xstatic void _fastcall SetInterlace(int type)
  52328. X{
  52329. X    targa.InterlaceMode= type & MSK_INTERLACE;
  52330. X    SetDispReg(INTREG, targa.InterlaceMode);
  52331. X    /*
  52332. X     *    SET THE INTERLACE BIT TO MATCH THE INTERLACE MODE AND
  52333. X     *    SCREEN RESOLUTION -  SCREEN PAGE
  52334. X     */
  52335. X    if ( ( targa.InterlaceMode >= 2 ) &&
  52336. X         ( targa.PageMode> 1 )    &&
  52337. X         ( (targa.PageMode&1) != 0 )  )
  52338. X        TSetMode(targa.mode|(~MSK_IBIT) );
  52339. X    else
  52340. X        TSetMode(targa.mode& MSK_IBIT);
  52341. X}
  52342. X
  52343. X
  52344. X/*****************************************************************/
  52345. X
  52346. Xstatic void _fastcall SetBlndReg(int value)
  52347. X{
  52348. X    /*  set the Vertical Preshift count  level */
  52349. X    if ( targa.boardType == 32 ) {
  52350. X        targa.VCRCon = (targa.VCRCon&0xfe) | value;
  52351. X        OUTPORTB(BLNDREG, value);
  52352. X        }
  52353. X}
  52354. X
  52355. X
  52356. X/*****************************************************************/
  52357. X
  52358. Xstatic void _fastcall near TSetMode(int mode)
  52359. X{
  52360. X    /* mask to valid values and output to mode register */
  52361. X    OUTPORTB(MODEREG, mode );
  52362. X    targa.mode = mode;
  52363. X}
  52364. X
  52365. X
  52366. X/*****************************************************************/
  52367. X
  52368. Xstatic void _fastcall SetContrast(int level)
  52369. X{
  52370. X    /*  set the contrast level */
  52371. X    targa.Contrast = level &((~MSK_CONTRAST)>>SHF_CONTRAST);
  52372. X    targa.VCRCon = ( targa.VCRCon  & MSK_CONTRAST ) |
  52373. X            (targa.Contrast<<SHF_CONTRAST) ;
  52374. X    OUTPORTB(VCRCON, targa.VCRCon );
  52375. X}
  52376. X
  52377. X
  52378. X/*****************************************************************/
  52379. X
  52380. Xstatic void _fastcall SetHue(int level)
  52381. X{
  52382. X    /*  set the hue level -  Mask to valid value */
  52383. X    targa.Hue = level&((~MSK_HUE)>>SHF_HUE);
  52384. X    /* mask to valid range */
  52385. X    targa.SatHue = (targa.SatHue&MSK_HUE) | (targa.Hue<<SHF_HUE);
  52386. X    OUTPORTB(SATHUE, targa.SatHue );
  52387. X}
  52388. X
  52389. X
  52390. X/*****************************************************************/
  52391. X
  52392. Xstatic void _fastcall SetSaturation(int level)
  52393. X{
  52394. X    /*  set the saturation level */
  52395. X    targa.Saturation= level&( (~MSK_SATURATION)>>SHF_SATURATION);
  52396. X    targa.SatHue =    (targa.SatHue&MSK_SATURATION) |
  52397. X             (targa.Saturation<<SHF_SATURATION);
  52398. X    OUTPORTB(SATHUE , targa.SatHue );
  52399. X}
  52400. X
  52401. X
  52402. X/*************************************************************/
  52403. X
  52404. X/*** UNUSED
  52405. Xstatic void _fastcall SetPageMode(int pageMode)
  52406. X{
  52407. X    pageMode &= 0x07;
  52408. X    targa.PageMode = pageMode;
  52409. X    VWait();
  52410. X    TSetMode( (targa.mode)&(MSK_RES) |((pageMode<<SHF_RES)&(~MSK_RES)) ) ;
  52411. X    if ( ( targa.DisplayRegister[20] >= 2 ) &&
  52412. X         ( pageMode> 1 )  &&
  52413. X         ( (pageMode&1) != 0 )      )    TSetMode(targa.mode|(~MSK_IBIT) );
  52414. X    else
  52415. X        TSetMode(targa.mode& MSK_IBIT);
  52416. X}
  52417. X***/
  52418. X
  52419. X
  52420. X/*****************************************************************/
  52421. X
  52422. Xstatic void _fastcall SetHBorder(int left, int right)
  52423. X{
  52424. X    SetDispReg(LEFTBORDER, left);    /* set horizontal left border */
  52425. X    SetDispReg(RIGHTBORDER,right);    /* set horizontal right border */
  52426. X/*
  52427. X *                    Set DR 8 and 9 since they
  52428. X *                    default to tracking DR0 and DR 1
  52429. X */
  52430. X    SetDispReg(DR8,left);
  52431. X    SetDispReg(DR9,left);
  52432. X}
  52433. X
  52434. X
  52435. X/*****************************************************************/
  52436. X
  52437. X/*** UNUSED
  52438. Xstatic void _fastcall SetGenlock(int OnOrOff)
  52439. X{
  52440. X    TSetMode( (targa.mode)&(MSK_GENLOCK)
  52441. X            |((OnOrOff<<SHF_GENLOCK)&(~MSK_GENLOCK)) );
  52442. X}
  52443. X***/
  52444. X
  52445. X
  52446. X/*****************************************************************/
  52447. X/* was asm, TC fast enough on AT */
  52448. X
  52449. Xstatic int GetLine( int port )
  52450. X{
  52451. Xint cnt;
  52452. Xint val1, val2;
  52453. X
  52454. X    val1 = INPORTB( port );
  52455. X    for( cnt = 0; cnt < 20; cnt++ ) {
  52456. X        val2 = INPORTB( port );
  52457. X        if( val1 == val2 )
  52458. X            break;
  52459. X        val1 = val2;
  52460. X    }
  52461. X    return( val1 );
  52462. X}
  52463. X
  52464. X
  52465. X/**********************************************************************
  52466. X              TINIT
  52467. X**********************************************************************/
  52468. X
  52469. Xstatic int GraphInit()
  52470. X{
  52471. Xint i;
  52472. Xint bottom, top;
  52473. Xchar *envptr;
  52474. Xunsigned switches, got_switches;
  52475. X
  52476. X    memset( &targa, 0, sizeof(targa) );
  52477. X
  52478. X    targa.boardType = TYPE_16;        /* default to T16 */
  52479. X    targa.xOffset = 0;  targa.yOffset = 0;    /* default to no offset */
  52480. X    targa.LinesPerField= DEF_ROWS/2;    /*  number of lines per field */
  52481. X    targa.AlwaysGenLock = DEF_GENLOCK;    /* default to genlock off */
  52482. X    targa.PageMode = 0;
  52483. X    targa.InterlaceMode = DEF_INT;        /* Defalut:  Interlace Mode 0 */
  52484. X    targa.Contrast= DEF_CONTRAST;
  52485. X    targa.Saturation = DEF_SATURATION;
  52486. X    targa.Hue = DEF_HUE;
  52487. X    targa.RGBorCV = CV;            /* default to Composite video */
  52488. X    targa.VCRorCamera = CAMERA;
  52489. X    targa.PanXOrig = 0; targa.PanYOrig=0;
  52490. X    targa.PageUpper= 0xffff;        /* set the bank flags to illega& values */
  52491. X    targa.PageLower= 0xffff;        /* so that they will be set the first time */
  52492. X    targa.ovrscnAvail = 0;            /* Assume no Overscan option */
  52493. X    targa.ovrscnOn = 0;
  52494. X
  52495. X    if ((envptr = getenv("TARGA")) == NULL)
  52496. X       return(-2);
  52497. X    switches = got_switches = 0;
  52498. X    while (*envptr) {
  52499. X       if (*envptr != ' ') ++got_switches;
  52500. X       if (*envptr >= '2' && *envptr <= '8')
  52501. X          switches |= (1 << ('8' - *envptr));
  52502. X       ++envptr;
  52503. X       }
  52504. X    if (got_switches == 0) { /* all blanks, use default */
  52505. X       targa.memloc = (signed int)0xA000;
  52506. X       targa.iobase = 0x220;
  52507. X       }
  52508. X    else {
  52509. X       targa.memloc = 0x8000 + ((switches & 0x70) << 8);
  52510. X       targa.iobase = 0x200  + ((switches & 0x0f) << 4);
  52511. X       }
  52512. X
  52513. X    if ((envptr = getenv("TARGASET"))) {
  52514. X       while(1) { /* parse next parameter */
  52515. X          while (*envptr == ' ' || *envptr == ',') ++envptr;
  52516. X          if (*envptr == 0) break;
  52517. X          if (*envptr >= 'a' && *envptr <= 'z') *envptr -= ('a'-'A');
  52518. X          i = atoi(envptr+1);
  52519. X          switch (*envptr) {
  52520. X         case 'T':
  52521. X            if (i == 16) targa.boardType = TYPE_16;
  52522. X            if (i == 24) targa.boardType = TYPE_24;
  52523. X            if (i == 32) targa.boardType = TYPE_32;
  52524. X            break;
  52525. X         /* case 'E' not done, meaning not clear */
  52526. X         case 'X':
  52527. X            targa.xOffset = i;
  52528. X            break;
  52529. X         case 'Y':
  52530. X            targa.yOffset = i;
  52531. X            break;
  52532. X         case 'I':
  52533. X            targa.InterlaceMode = i;
  52534. X            break;
  52535. X         /* case 'N' not done, I don't know how to handle it */
  52536. X         case 'R':
  52537. X            targa.RGBorCV = RGB;
  52538. X            break;
  52539. X         case 'B':
  52540. X            targa.VCRorCamera = CAMERA;
  52541. X            break;
  52542. X         case 'V':
  52543. X            targa.VCRorCamera = VCR;
  52544. X            break;
  52545. X         case 'G':
  52546. X            targa.AlwaysGenLock = 1;
  52547. X            break;
  52548. X         case 'C':
  52549. X            targa.Contrast = i * 31 / 100;
  52550. X            break;
  52551. X         case 'S':
  52552. X            targa.Saturation = i * 7 / 100;
  52553. X            break;
  52554. X         case 'H':
  52555. X            targa.Hue = i * 31 / 100;
  52556. X            break;
  52557. X         /* note: 'A' and 'O' defined but apply only to type M8 */
  52558. X         /* case 'P' not handled cause I don't know how */
  52559. X         }
  52560. X          while (*(++envptr) >= '0' && *envptr <= '9') { }
  52561. X          }
  52562. X       }
  52563. X
  52564. X    if ( targa.boardType == TYPE_16 ) {
  52565. X        targa.MaxBanks = 16;
  52566. X        targa.BytesPerPixel = 2;
  52567. X    }
  52568. X    if ( targa.boardType == TYPE_24 ) {
  52569. X        targa.MaxBanks = 32;
  52570. X        targa.BytesPerPixel = 3;
  52571. X    }
  52572. X    if ( targa.boardType == TYPE_32 ) {
  52573. X        targa.MaxBanks = 32;
  52574. X        targa.BytesPerPixel = 4;
  52575. X    }
  52576. X
  52577. X    /****** Compute # of rows per 32K bank    ********/
  52578. X    targa.RowsPerBank = 512/(targa.MaxBanks);
  52579. X    targa.AddressShift =  targa.MaxBanks>>4;
  52580. X
  52581. X    /*    if initializing CVA:  set these before we quit    */
  52582. X    SetSaturation(targa.Saturation);
  52583. X    SetHue(targa.Hue);
  52584. X    SetContrast( targa.Contrast);
  52585. X
  52586. X    /*    Set Genlock bit if always genlocked */
  52587. X    /*    Set before flipping and jerking screen */
  52588. X    TSetMode( (targa.AlwaysGenLock<<SHF_GENLOCK) | DEF_MODE);
  52589. X
  52590. X    SetBlndReg(0);        /*  disable blend mode on TARGA 32 */
  52591. X
  52592. X    SetInterlace(targa.InterlaceMode);
  52593. X    SetFixedRegisters();
  52594. X    SetOverscan( 0 );
  52595. X
  52596. X    top    = 140 - (targa.LinesPerField / 2);
  52597. X    bottom = top + targa.LinesPerField;
  52598. X    SetVBorder(top,bottom);
  52599. X    SetVertShift(256-targa.LinesPerField);
  52600. X
  52601. X    SetMask(DEF_MASK);
  52602. X    SetRGBorCV (targa.RGBorCV );
  52603. X    SetVCRorCamera(targa.VCRorCamera);
  52604. X
  52605. X    /*    See if the raster register is working correctly and
  52606. X        return error flag if its not         */
  52607. X    return (( VWait() == -1) ? -1 : 0);
  52608. X
  52609. X}
  52610. X
  52611. X
  52612. X/**************************************************************/
  52613. X
  52614. Xstatic void GraphEnd()
  52615. X{
  52616. X    TSetMode( (targa.mode)&MSK_MSEL );     /*  disable memory */
  52617. X}
  52618. X
  52619. X
  52620. X/**************************************************************/
  52621. X/* Set the registers which have required values */
  52622. X
  52623. X#define FIXED_REGS    10
  52624. X
  52625. Xstatic int FixedRegs[] = {
  52626. X    DR6,DR7,DR12,DR13,DR14,DR15,DR16,DR17,DR18,DR19
  52627. X};
  52628. X
  52629. Xstatic int FixedValue[] = {
  52630. X    DEF_DR6,DEF_DR7,DEF_DR12,DEF_DR13,DEF_DR14,
  52631. X    DEF_DR15,DEF_DR16,DEF_DR17,DEF_DR18,DEF_DR19
  52632. X};
  52633. X
  52634. Xstatic void SetFixedRegisters()
  52635. X{
  52636. Xint reg;
  52637. X
  52638. X    for ( reg=0; reg<FIXED_REGS; reg++)
  52639. X        SetDispReg(FixedRegs[reg],FixedValue[reg]);
  52640. X}
  52641. X
  52642. X
  52643. SHAR_EOF
  52644. $TOUCH -am 1028230093 targa.c &&
  52645. chmod 0644 targa.c ||
  52646. echo "restore of targa.c failed"
  52647. set `wc -c targa.c`;Wc_c=$1
  52648. if test "$Wc_c" != "19635"; then
  52649.     echo original size 19635, current size $Wc_c
  52650. fi
  52651. # ============= testpt.c ==============
  52652. echo "x - extracting testpt.c (Text)"
  52653. sed 's/^X//' << 'SHAR_EOF' > testpt.c &&
  52654. X/*
  52655. X
  52656. XWrite your fractal program here. initreal and initimag are the values in
  52657. Xthe complex plane; parm1, and parm2 are paramaters to be entered with the
  52658. X"params=" option (if needed). The function should return the color associated
  52659. Xwith initreal and initimag.  FRACTINT will repeatedly call your function with
  52660. Xthe values of initreal and initimag ranging over the rectangle defined by the
  52661. X"corners=" option. Assuming your formula is iterative, "maxit" is the maximum
  52662. Xiteration. If "maxit" is hit, color "inside" should be returned.
  52663. X
  52664. XNote that this routine could be sped up using external variables/arrays
  52665. Xrather than the current parameter-passing scheme.  The goal, however was
  52666. Xto make it as easy as possible to add fractal types, and this looked like
  52667. Xthe easiest way.
  52668. X
  52669. XThis module is part of an overlay, with calcfrac.c.  The routines in it
  52670. Xmust not be called by any part of Fractint other than calcfrac.
  52671. X
  52672. XThe sample code below is a straightforward Mandelbrot routine.
  52673. X
  52674. X*/
  52675. X
  52676. Xextern int xdots;        /* the screen is this many dots across */
  52677. Xextern int ydots;        /* the screen is this many dots down */
  52678. Xextern int colors;        /* the screen has this many colors */
  52679. X
  52680. Xint teststart()     /* this routine is called just before the fractal starts */
  52681. X{
  52682. X    return( 0 );
  52683. X}
  52684. X
  52685. Xvoid testend()         /* this routine is called just after the fractal ends */
  52686. X{
  52687. X}
  52688. X
  52689. X        /* this routine is called once for every pixel */
  52690. X    /* (note: possibly using the dual-pass / solif-guessing options */
  52691. X
  52692. Xtestpt(initreal,initimag,parm1,parm2,maxit,inside)
  52693. Xdouble initreal,initimag,parm1,parm2;
  52694. Xint maxit,inside;
  52695. X{
  52696. Xdouble oldreal, oldimag, newreal, newimag, magnitude;
  52697. Xint color;
  52698. X   oldreal=parm1;
  52699. X   oldimag=parm2;
  52700. X   magnitude = 0.0;
  52701. X   color = 0;
  52702. X   while ((magnitude < 4.0) && (color < maxit)) {
  52703. X      newreal = oldreal * oldreal - oldimag * oldimag + initreal;
  52704. X      newimag = 2 * oldreal * oldimag + initimag;
  52705. X      color++;
  52706. X      oldreal = newreal;
  52707. X      oldimag = newimag;
  52708. X      magnitude = newreal * newreal + newimag * newimag;
  52709. X      }
  52710. Xif (color >= maxit) color = inside;
  52711. Xreturn(color);
  52712. X}
  52713. SHAR_EOF
  52714. $TOUCH -am 1028230093 testpt.c &&
  52715. chmod 0644 testpt.c ||
  52716. echo "restore of testpt.c failed"
  52717. set `wc -c testpt.c`;Wc_c=$1
  52718. if test "$Wc_c" != "2048"; then
  52719.     echo original size 2048, current size $Wc_c
  52720. fi
  52721. # ============= tgaview.c ==============
  52722. echo "x - extracting tgaview.c (Text)"
  52723. sed 's/^X//' << 'SHAR_EOF' > tgaview.c &&
  52724. X
  52725. X/* Routine to decode Targa 16 bit RGB file
  52726. X   */
  52727. X
  52728. X/* 16 bit .tga files were generated for continuous potential "potfile"s
  52729. X   from version 9.? thru version 14.  Replaced by double row gif type
  52730. X   file (.pot) in version 15.  Delete this code after a few more revs.
  52731. X*/
  52732. X
  52733. X#include <stdio.h>
  52734. X#include "fractint.h"
  52735. X#include "targa_lc.h"
  52736. X#include "prototyp.h"
  52737. X
  52738. Xextern char readname[];         /* file name          */
  52739. Xextern unsigned int boxx[];        /* write-line routines use this */
  52740. Xextern int colors;
  52741. Xextern int rowcount;
  52742. X
  52743. Xstatic FILE *fptarga = NULL;        /* FILE pointer       */
  52744. Xextern unsigned int height;        /* image height       */
  52745. Xextern int (*outln)();
  52746. X
  52747. X/* Main entry decoder */
  52748. Xtgaview()
  52749. X{
  52750. X   int i;
  52751. X   int cs;
  52752. X   unsigned int width;
  52753. X   struct fractal_info info;
  52754. X   FILE *t16_open();
  52755. X
  52756. X   if((fptarga = t16_open(readname, (int *)&width, (int *)&height, &cs, (U8 *)&info))==NULL)
  52757. X      return(-1);
  52758. X
  52759. X   rowcount = 0;
  52760. X   for (i=0; i<height; ++i)
  52761. X   {
  52762. X       t16_getline(fptarga, width, (U16 *)boxx);
  52763. X       if ((*outln)(boxx,width))
  52764. X       {
  52765. X      fclose(fptarga);
  52766. X      fptarga = NULL;
  52767. X      return(-1);
  52768. X       }
  52769. X       if (keypressed())
  52770. X       {
  52771. X      fclose(fptarga);
  52772. X      fptarga = NULL;
  52773. X      return(-1);
  52774. X       }
  52775. X   }
  52776. X   fclose(fptarga);
  52777. X   fptarga = NULL;
  52778. X   return(0);
  52779. X}
  52780. X/* Outline function for 16 bit data with 8 bit fudge */
  52781. Xoutlin16(BYTE *buffer,int linelen)
  52782. X{
  52783. X    extern int rowcount;
  52784. X    U16 *buf;
  52785. X    int i;
  52786. X    buf = (U16 *)buffer;
  52787. X    for(i=0;i<linelen;i++)
  52788. X       putcolor(i,rowcount,buf[i]>>8); 
  52789. X    rowcount++;
  52790. X    return(0);
  52791. X}
  52792. SHAR_EOF
  52793. $TOUCH -am 1028230093 tgaview.c &&
  52794. chmod 0644 tgaview.c ||
  52795. echo "restore of tgaview.c failed"
  52796. set `wc -c tgaview.c`;Wc_c=$1
  52797. if test "$Wc_c" != "1504"; then
  52798.     echo original size 1504, current size $Wc_c
  52799. fi
  52800. # ============= tp3d.c ==============
  52801. echo "x - extracting tp3d.c (Text)"
  52802. sed 's/^X//' << 'SHAR_EOF' > tp3d.c &&
  52803. X#include <stdio.h>
  52804. X#include "mpmath.h"
  52805. X#include "fractint.h"
  52806. X#include "prototyp.h"
  52807. X
  52808. X/* 3D Transparency Variables, MCP 5-30-91 */
  52809. Xextern double xxmin, xxmax, yymin, yymax, zzmin, zzmax, ttmin, ttmax;
  52810. Xextern int Transparent3D, SolidCore, NumFrames;
  52811. Xextern unsigned CoreRed, CoreGreen, CoreBlue;
  52812. Xextern int tpdepth, tptime, symmetry, AntiAliasing;
  52813. X
  52814. Xextern int xdots, ydots, colors, bitshift;
  52815. Xextern int row, col, inside, ShadowColors;
  52816. Xextern int TPlusFlag, MaxColorRes, NonInterlaced;
  52817. X
  52818. Xtypedef struct palett {
  52819. X   BYTE red;
  52820. X   BYTE green;
  52821. X   BYTE blue;
  52822. X} Palettetype;
  52823. X
  52824. Xextern Palettetype    dacbox[ 256 ];
  52825. X
  52826. X
  52827. Xint far NewTPFractal, far _MathType;
  52828. Xstatic double dx, dy, dz, dt;
  52829. Xstatic long ldx, ldy, ldz, ldt;
  52830. Xstatic long lxxmin, lxxmax, lyymin, lyymax, lzzmin, lzzmax, lttmin, lttmax;
  52831. X
  52832. Xint TranspSymmetry = 0;
  52833. X
  52834. X/* TARGA+ prototypes */
  52835. Xint MatchTPlusMode(unsigned xdots, unsigned ydots, unsigned MaxColorRes,
  52836. X           unsigned PixelZoom, unsigned NonInterlaced);
  52837. Xint CheckForTPlus(void);
  52838. X
  52839. X#ifndef XFRACT
  52840. Xvoid (*PutTC)(int col, int row, unsigned long color) = WriteTPlusBankedPixel;
  52841. Xunsigned long (*GetTC)(int col, int row) = ReadTPlusBankedPixel;
  52842. X#else
  52843. Xvoid (*PutTC)(int , int , unsigned long ) = WriteTPlusBankedPixel;
  52844. Xunsigned long (*GetTC)(int , int ) = ReadTPlusBankedPixel;
  52845. X#endif
  52846. X
  52847. X
  52848. Xchar far * far TCError[] =
  52849. X{
  52850. X   "Could not match this video resolution to a TARGA+ mode",
  52851. X   "True Color disk video isn't implement yet, maybe later . . .",
  52852. X};
  52853. X
  52854. Xchar far *TrueColorAutoDetect(void)
  52855. X{
  52856. X   if(CheckForTPlus())
  52857. X   {
  52858. X      if(TPlusFlag)
  52859. X      {
  52860. X         if(MaxColorRes == 8)
  52861. X         {
  52862. X            if(!MatchTPlusMode(xdots, ydots, 24, 0, NonInterlaced))
  52863. X               return(TCError[0]);
  52864. X         }
  52865. X         else if(!MatchTPlusMode(xdots, ydots, MaxColorRes, 0, NonInterlaced))
  52866. X            return(TCError[0]);
  52867. X
  52868. X         PutTC = WriteTPlusBankedPixel;
  52869. X         GetTC = ReadTPlusBankedPixel;
  52870. X         return(0);
  52871. X      }
  52872. X   }
  52873. X
  52874. X   /* Check for other TC adapters here, such as the XGA , and place it
  52875. X      in a true color mode with a resolution identical to the one selected
  52876. X      by the user. */
  52877. X
  52878. X
  52879. X   /* If we don't have a TC adapter or it is being used as the display
  52880. X      screen, then simulate one using disk video */
  52881. X   return(TCError[1]); /* return the 'not implemented' message */
  52882. X}
  52883. X
  52884. Xvoid TranspPerPixel(int MathType, union Arg far *xy, union Arg far *zt)
  52885. X{
  52886. X   if(NewTPFractal)
  52887. X   {
  52888. X      double Fudge = (double)(1L << bitshift);
  52889. X      _MathType = MathType;              /* Save this for later */
  52890. X
  52891. X      dx = (xxmax - xxmin) / xdots;
  52892. X      dy = (yymin - yymax) / ydots;  /* reverse direction of y-axis */
  52893. X      dz = (zzmax - zzmin) / xdots;
  52894. X      dt = (ttmax - ttmin) / NumFrames;
  52895. X
  52896. X      lxxmin = (long)(xxmin * Fudge);
  52897. X      lxxmax = (long)(xxmax * Fudge);
  52898. X      ldx    = (long)(dx    * Fudge);
  52899. X
  52900. X      lyymin = (long)(yymin * Fudge);
  52901. X      lyymax = (long)(yymax * Fudge);
  52902. X      ldy    = (long)(dy    * Fudge);
  52903. X
  52904. X      lzzmin = (long)(zzmin * Fudge);
  52905. X      lzzmax = (long)(zzmax * Fudge);
  52906. X      ldz    = (long)(dz    * Fudge);
  52907. X
  52908. X      lttmin = (long)(ttmin * Fudge);
  52909. X      lttmax = (long)(ttmax * Fudge);
  52910. X      ldt    = (long)(dt    * Fudge);
  52911. X
  52912. X      NewTPFractal = 0;
  52913. X   }
  52914. X
  52915. X   switch(MathType)
  52916. X   {
  52917. X      /* For calculation purposes, 'x' and 'z' are swapped */
  52918. X      case D_MATH:
  52919. X           xy->d.x = xxmin + (dx * col);
  52920. X           xy->d.y = yymax + (dy * row);
  52921. X           zt->d.x = zzmin + (dz * tpdepth);
  52922. X           zt->d.y = ttmin + (dt * tptime);
  52923. X           break;
  52924. X#ifndef XFRACT
  52925. X      case M_MATH:
  52926. X           xy->m.x = *d2MP(xxmin + (dx * col));
  52927. X           xy->m.y = *d2MP(yymax + (dy * row));
  52928. X           zt->m.x = *d2MP(zzmin + (dz * tpdepth));
  52929. X           zt->m.y = *d2MP(ttmin + (dt * tptime));
  52930. X           break;
  52931. X      case L_MATH:
  52932. X           xy->l.x = lxxmin + (ldx * col);
  52933. X           xy->l.y = lyymax + (ldy * row);
  52934. X           zt->l.x = lzzmin + (ldz * tpdepth);
  52935. X           zt->l.y = lttmin + (ldt * tptime);
  52936. X#endif
  52937. X   }
  52938. X}
  52939. X
  52940. X
  52941. Xint Transp3DFnct()
  52942. X{
  52943. X   unsigned x, y, z, savedinside;
  52944. X   int r;
  52945. X   unsigned long lcolor;
  52946. X
  52947. X   for(x = tpdepth;  x < xdots; x++, tpdepth++)
  52948. X   {
  52949. X      /* Here we go!  Calculate 2D slices to create a 3D composite */
  52950. X      savedinside = inside;
  52951. X      inside = 255;
  52952. X      r = calcfract();
  52953. X      inside = savedinside;
  52954. X
  52955. X      if(r < 0)
  52956. X         return(r);                 /* return if iterupted */
  52957. X
  52958. X      for(y = 0; y < ydots; y++)
  52959. X      {
  52960. X         unsigned long Red = 0L, Green = 0L, Blue = 0L;
  52961. X         unsigned long r = 0L, g = 0L, b = 0L;
  52962. X         unsigned color;
  52963. X
  52964. X         for(z = 0; z < xdots; z++)  /* Total the color guns */
  52965. X         {
  52966. X            color = (*getcolor)(z, y);
  52967. X            if(color == 255 && SolidCore)
  52968. X            {                           /* Display a solid core */
  52969. X               r = ((long)CoreRed)   * (xdots - z) / xdots;
  52970. X               g = ((long)CoreGreen) * (xdots - z) / xdots;
  52971. X               b = ((long)CoreBlue)  * (xdots - z) / xdots;
  52972. X               break;
  52973. X            }
  52974. X            else
  52975. X            {
  52976. X               Red   += (dacbox[color].red << 2);
  52977. X               Green += (dacbox[color].green << 2);
  52978. X               Blue  += (dacbox[color].blue << 2);
  52979. X            }
  52980. X         }
  52981. X
  52982. X         /* Calculate an average color */
  52983. X         if(z)
  52984. X         {
  52985. X            Red /= z;
  52986. X            Green /= z;
  52987. X            Blue /= z;
  52988. X         }
  52989. X
  52990. X         /* Overlay solid color */
  52991. X         Red   |= r;
  52992. X         Green |= g;
  52993. X         Blue  |= b;
  52994. X
  52995. X         lcolor = (Red << 16) + (Green << 8) + Blue;
  52996. X         PutTC(x, y, lcolor);
  52997. X         if(TranspSymmetry == ORIGIN)
  52998. X            PutTC(xdots - x - 1, ydots - y - 1, lcolor);
  52999. X         else if(TranspSymmetry == XAXIS)
  53000. X         {
  53001. X            PutTC(x, ydots - y - 1, lcolor);
  53002. X            PutTC(xdots - x - 1, y, lcolor);
  53003. X            PutTC(xdots - x - 1, ydots - y - 1, lcolor);
  53004. X            if(y > (ydots >> 1))
  53005. X               break;
  53006. X         }
  53007. X      }
  53008. X      if(x > (xdots >> 1))
  53009. X      {
  53010. X         if(TranspSymmetry == ORIGIN || TranspSymmetry == XAXIS)
  53011. X            break;
  53012. X      }
  53013. X   }
  53014. X   return(0);
  53015. X}
  53016. X
  53017. Xvoid ShadowPutColor(unsigned xdot, unsigned ydot, unsigned color)
  53018. X{
  53019. X   ShadowVideo(0);
  53020. X   if(ShadowColors)
  53021. X      putcolor(xdot >> AntiAliasing, ydot >> AntiAliasing, color);
  53022. X   else
  53023. X   {
  53024. X      unsigned r, g, b;
  53025. X      unsigned long lcolor;
  53026. X
  53027. X      r = (dacbox[color].red << 2);
  53028. X      g = (dacbox[color].green << 2);
  53029. X      b = (dacbox[color].blue << 2);
  53030. X      lcolor = ((long)r << 16) + (g << 8) + b;
  53031. X      PutTC(xdot >> AntiAliasing, ydot >> AntiAliasing, lcolor);
  53032. X   }
  53033. X   ShadowVideo(1);
  53034. X}
  53035. X
  53036. Xvoid AntiAliasPass(void)
  53037. X{
  53038. X   unsigned x, y, i, j, PixelSize, a;
  53039. X   unsigned xAct, yAct, xRef, yRef;
  53040. X
  53041. X   PixelSize = (1 << AntiAliasing);
  53042. X   xAct = (xdots >> AntiAliasing);
  53043. X   yAct = (ydots >> AntiAliasing);
  53044. X
  53045. X   for(yRef = y = 0; y < yAct; y++, yRef += PixelSize)
  53046. X   {
  53047. X      for(xRef = x = 0; x < xAct; x++, xRef += PixelSize)
  53048. X      {
  53049. X         unsigned total = 0;
  53050. X         unsigned long r = 0, g = 0, b = 0, lcolor;
  53051. X
  53052. X         for(i = 0; i < PixelSize; i++)
  53053. X         {
  53054. X            for(j = 0; j < PixelSize; j++)
  53055. X            {
  53056. X               unsigned color;
  53057. X
  53058. X               color = readdisk(xRef + i, yRef + j);
  53059. X               if(ShadowColors)
  53060. X                  total += color;
  53061. X               else
  53062. X               {
  53063. X                  r += (dacbox[color].red << 2);
  53064. X                  g += (dacbox[color].green << 2);
  53065. X                  b += (dacbox[color].blue << 2);
  53066. X               }
  53067. X            }
  53068. X         }
  53069. X
  53070. X         a = AntiAliasing * AntiAliasing;
  53071. X         ShadowVideo(0);
  53072. X         if(ShadowColors)
  53073. X            putcolor(x, y, total >> a);
  53074. X         else
  53075. X         {
  53076. X            r >>= a;
  53077. X            g >>= a;
  53078. X            b >>= a;
  53079. X            lcolor = ((long)r << 16) + (g << 8) + b;
  53080. X            PutTC(x, y, lcolor);
  53081. X         }
  53082. X         ShadowVideo(1);
  53083. X      }
  53084. X   }
  53085. X}
  53086. X
  53087. SHAR_EOF
  53088. $TOUCH -am 1028230093 tp3d.c &&
  53089. chmod 0644 tp3d.c ||
  53090. echo "restore of tp3d.c failed"
  53091. set `wc -c tp3d.c`;Wc_c=$1
  53092. if test "$Wc_c" != "7735"; then
  53093.     echo original size 7735, current size $Wc_c
  53094. fi
  53095. # ============= tplus.c ==============
  53096. echo "x - extracting tplus.c (Text)"
  53097. sed 's/^X//' << 'SHAR_EOF' > tplus.c &&
  53098. X/* TPLUS.C, (C) 1991 The Yankee Programmer
  53099. X   All Rights Reserved.
  53100. X
  53101. X   This code may be distributed only when bundled with the Fractint
  53102. X   source code.
  53103. X
  53104. X   Mark C. Peterson
  53105. X   The Yankee Programmer
  53106. X   405-C Queen Street, Suite #181
  53107. X   Southington, CT 06489
  53108. X   (203) 276-9721
  53109. X
  53110. X*/
  53111. X
  53112. X#include <stdio.h>
  53113. X#ifndef XFRACT
  53114. X#include <conio.h>
  53115. X#include <string.h>
  53116. X#ifdef __TURBOC__
  53117. X#include <dos.h>
  53118. X#endif
  53119. X#include "port.h"
  53120. X#else
  53121. X#include "fractint.h"
  53122. X#endif
  53123. X#include "tplus.h"
  53124. X#include "prototyp.h"
  53125. X
  53126. Xstruct TPWrite far WriteOffsets = {
  53127. X      0,       1,    2,     3,      0x400,   0x401,      0x402,
  53128. X      0x403,   0x800,    0x801,     0x802,   0x803,   0xc00,      0xc01,
  53129. X      0xc02,   0xc03
  53130. X};
  53131. X
  53132. Xstruct TPRead far ReadOffsets = {
  53133. X      0,        2,     3,      0x400,   0x401,      0x402,
  53134. X      0x403,   0x800,    0x801,     0x802,   0x803,   0xc00,      0xc01,
  53135. X      0xc02,   0xc03
  53136. X};
  53137. X
  53138. Xstruct _BOARD far TPlus;
  53139. Xint TPlusErr = 0;
  53140. X
  53141. X#ifndef XFRACT
  53142. X
  53143. Xvoid WriteTPWord(unsigned Register, unsigned Number) {
  53144. X   OUTPORTB(TPlus.Write.INDIRECT, Register);
  53145. X   OUTPORTW(TPlus.Write.WBL, Number);
  53146. X}
  53147. X
  53148. Xvoid WriteTPByte(unsigned Register, unsigned Number) {
  53149. X   OUTPORTB(TPlus.Write.INDIRECT, Register);
  53150. X   OUTPORTB(TPlus.Write.WBL, Number);
  53151. X}
  53152. X
  53153. Xunsigned ReadTPWord(unsigned Register) {
  53154. X   OUTPORTB(TPlus.Write.INDIRECT, Register);
  53155. X   return(INPORTW(TPlus.Read.RBL));
  53156. X}
  53157. X
  53158. XBYTE ReadTPByte(unsigned Register) {
  53159. X   OUTPORTB(TPlus.Write.INDIRECT, Register);
  53160. X   return((BYTE)INPORTB(TPlus.Read.RBL));
  53161. X}
  53162. X
  53163. Xvoid DisableMemory(void) {
  53164. X   unsigned Mode1;
  53165. X
  53166. X   Mode1 = INPORTB(TPlus.Read.MODE1);
  53167. X   Mode1 &= 0xfe;
  53168. X   OUTPORTB(TPlus.Write.MODE1, Mode1);
  53169. X}
  53170. X
  53171. Xvoid EnableMemory(void) {
  53172. X   unsigned Mode1;
  53173. X
  53174. X   Mode1 = INPORTB(TPlus.Read.MODE1);
  53175. X   Mode1 |= 1;
  53176. X   OUTPORTB(TPlus.Write.MODE1, Mode1);
  53177. X}
  53178. X
  53179. Xstruct TPLUS_IO {
  53180. X   unsigned Cmd;
  53181. X   int Initx, Finalx, Inity, Finaly, Destx, Desty;
  53182. X   unsigned long Color;
  53183. X   unsigned RegsOffset, RegsSegment, RegListOffset, RegListSegment,
  53184. X        BoardNumber, StructSize;
  53185. X} far TPlusIO;
  53186. X
  53187. X#include <dos.h>
  53188. X
  53189. X/* TARGAP.SYS Commands */
  53190. X#define READALL    0
  53191. X#define WRITEALL   0
  53192. X#define NUMBOARDS  3
  53193. X#define FILLBLOCK  4
  53194. X#define GRABFIELD  4
  53195. X#define RESET       5
  53196. X#define GRABFRAME  5
  53197. X#define WAITFORVB  6
  53198. X#define SETBOARD   8
  53199. X#define IOBASE       9
  53200. X
  53201. X/* DOS IO Commands */
  53202. X#define DOS_READ   0x4402
  53203. X#define DOS_WRITE  0x4403
  53204. X
  53205. Xint hTPlus = -1;
  53206. Xunsigned NumTPlus = 0;
  53207. X
  53208. Xint TargapSys(int Command, unsigned DOS) {
  53209. X   struct TPLUS_IO far *IOPtr;
  53210. X   unsigned far *RegPtr;
  53211. X   union REGS r;
  53212. X   struct SREGS s;
  53213. X
  53214. X   if(hTPlus != -1) {
  53215. X      r.x.ax = DOS;
  53216. X      r.x.bx = hTPlus;
  53217. X      r.x.cx = sizeof(TPlusIO);
  53218. X      IOPtr = &TPlusIO;
  53219. X      RegPtr = TPlus.Reg;
  53220. X      r.x.dx = FP_OFF(IOPtr);
  53221. X      s.ds = FP_SEG(IOPtr);
  53222. X      TPlusIO.Cmd = Command;
  53223. X      TPlusIO.StructSize = sizeof(TPlus.Reg);
  53224. X      TPlusIO.RegsOffset = FP_OFF(RegPtr);
  53225. X      TPlusIO.RegsSegment = FP_SEG(RegPtr);
  53226. X      intdosx(&r, &r, &s);
  53227. X      return(!r.x.cflag);
  53228. X   }
  53229. X   return(0);
  53230. X}
  53231. X
  53232. Xint _SetBoard(int BoardNumber) {
  53233. X   TPlusIO.BoardNumber = BoardNumber;
  53234. X   return(TargapSys(SETBOARD, DOS_WRITE));
  53235. X}
  53236. X
  53237. X#include <stdio.h>
  53238. X
  53239. Xint TPlusLUT(BYTE far *LUTData, unsigned Index, unsigned Number,
  53240. X             unsigned DosFlag)
  53241. X{
  53242. X   struct TPLUS_IO far *IOPtr;
  53243. X   union REGS r;
  53244. X   struct SREGS s;
  53245. X
  53246. X   if(hTPlus != -1) {
  53247. X      r.x.ax = DosFlag;
  53248. X      r.x.bx = hTPlus;
  53249. X      r.x.cx = sizeof(TPlusIO);
  53250. X      IOPtr = &TPlusIO;
  53251. X      r.x.dx = FP_OFF(IOPtr);
  53252. X      s.ds = FP_SEG(IOPtr);
  53253. X      TPlusIO.Cmd = 9;
  53254. X      TPlusIO.StructSize = sizeof(TPlus.Reg);
  53255. X      TPlusIO.RegsOffset = FP_OFF(LUTData);
  53256. X      TPlusIO.RegsSegment = FP_SEG(LUTData);
  53257. X      TPlusIO.BoardNumber = Number;
  53258. X      TPlusIO.RegListOffset = Index;
  53259. X      intdosx(&r, &r, &s);
  53260. X      return(!r.x.cflag);
  53261. X   }
  53262. X   return(0);
  53263. X}
  53264. X
  53265. Xint SetVGA_LUT(void) {
  53266. X   char PathName[80];
  53267. X   FILE *Data;
  53268. X   BYTE LUTData[256 * 3];
  53269. X
  53270. X   findpath("tplus.dat", PathName);
  53271. X   if(PathName[0]) {
  53272. X      if((Data = fopen(PathName, "rb")) != 0) {
  53273. X     if(!fseek(Data, 16L << 8, SEEK_SET)) {
  53274. X        if(fread(LUTData, 1, sizeof(LUTData), Data) == sizeof(LUTData)) {
  53275. X           fclose(Data);
  53276. X           return(TPlusLUT(LUTData, 0, sizeof(LUTData), DOS_WRITE));
  53277. X        }
  53278. X     }
  53279. X      }
  53280. X   }
  53281. X   if(Data > 0)
  53282. X      fclose(Data);
  53283. X   return(0);
  53284. X}
  53285. X
  53286. Xint SetColorDepth(int Depth) {
  53287. X   if(TPlus.Reg[HIRES] && Depth == 4)
  53288. X      Depth = 2;
  53289. X   switch(Depth) {
  53290. X      case 1:
  53291. X     if(TPlus.Reg[XDOTS] > 512) {
  53292. X        TPlus.Reg[PERM] = 1;
  53293. X        TPlus.Reg[BYCAP] = 3;
  53294. X        TPlus.RowBytes = 10;
  53295. X     }
  53296. X     else {
  53297. X        TPlus.Reg[PERM] = 0;
  53298. X        TPlus.Reg[BYCAP] = 1;
  53299. X        TPlus.RowBytes = 9;
  53300. X     }
  53301. X     TPlus.Reg[BUFFPORTSRC] = 0;
  53302. X     TPlus.Reg[CM1] = 0;
  53303. X     TPlus.Reg[CM2] = 0;
  53304. X     TPlus.Reg[DEPTH] = 1;
  53305. X     TPlus.Reg[LIVE8] = 1;
  53306. X     TPlus.Reg[DISPMODE] = 0;
  53307. X     TPlus.Reg[LIVEPORTSRC] = 1;
  53308. X     TPlus.Reg[LUTBYPASS] = 0;
  53309. X     break;
  53310. X      case 2:
  53311. X     if(TPlus.Reg[XDOTS] > 512) {
  53312. X        TPlus.Reg[PERM] = 3;
  53313. X        TPlus.Reg[BYCAP] = 15;
  53314. X        TPlus.Reg[CM2] = 1;
  53315. X        TPlus.RowBytes = 11;
  53316. X     }
  53317. X     else {
  53318. X        TPlus.Reg[PERM] = 1;
  53319. X        TPlus.Reg[BYCAP] = 3;
  53320. X        TPlus.Reg[CM2] = 0;
  53321. X        TPlus.RowBytes = 10;
  53322. X     }
  53323. X     TPlus.Reg[BUFFPORTSRC] = 1;
  53324. X     TPlus.Reg[CM1] = 0;
  53325. X     TPlus.Reg[DEPTH] = 2;
  53326. X     TPlus.Reg[LIVE8] = 0;
  53327. X     TPlus.Reg[DISPMODE] = 0;
  53328. X     TPlus.Reg[LIVEPORTSRC] = 1;
  53329. X     TPlus.Reg[LUTBYPASS] = 1;
  53330. X     break;
  53331. X      case 3:
  53332. X      case 4:
  53333. X     TPlus.Reg[PERM] = (Depth == 3) ? 2 : 3;
  53334. X     TPlus.Reg[BYCAP] = 0xf;
  53335. X     TPlus.Reg[BUFFPORTSRC] = 3;
  53336. X     TPlus.Reg[CM1] = 1;
  53337. X     TPlus.Reg[CM2] = 1;
  53338. X     TPlus.Reg[DEPTH] = 4;
  53339. X     TPlus.Reg[LIVE8] = 0;
  53340. X     TPlus.Reg[DISPMODE] = 0;
  53341. X     TPlus.Reg[LIVEPORTSRC] = 1;
  53342. X     TPlus.Reg[LUTBYPASS] = 1;
  53343. X     TPlus.RowBytes = 11;
  53344. X     break;
  53345. X      default:
  53346. X     return(0);
  53347. X   }
  53348. X   TPlus.Plot = WriteTPlusBankedPixel;
  53349. X   TPlus.GetColor = ReadTPlusBankedPixel;
  53350. X   TPlus.Reg[LIVEMIXSRC] = 0;
  53351. X   TPlus.Reg[CM3] = 1;
  53352. X   TPlus.RowsPerBank = 16 - TPlus.RowBytes;
  53353. X   if(TargapSys(WRITEALL, DOS_WRITE)) {
  53354. X      if(Depth == 1)
  53355. X     SetVGA_LUT();
  53356. X      if(TPlus.ClearScreen)
  53357. X     ClearTPlusScreen();
  53358. X      TargapSys(READALL, DOS_READ);
  53359. X      return(Depth);
  53360. X   }
  53361. X   return(0);
  53362. X}
  53363. X
  53364. Xint SetBoard(int BoardNumber) {
  53365. X   unsigned ioBase, n;
  53366. X   unsigned long MemBase;
  53367. X
  53368. X   if(TPlus.ThisBoard != -1)
  53369. X      DisableMemory();
  53370. X   if(!_SetBoard(BoardNumber))
  53371. X      return(0);
  53372. X   if(!TargapSys(READALL, DOS_READ))
  53373. X      return(0);
  53374. X   TPlus.VerPan       = TPlus.Reg[VPAN];
  53375. X   TPlus.HorPan       = TPlus.Reg[HPAN];
  53376. X   TPlus.Top          = TPlus.Reg[TOP];
  53377. X   TPlus.Bottom       = TPlus.Reg[BOT];
  53378. X   TPlus.Bank64k      = 0xffff;         /* Force a bank switch */
  53379. X
  53380. X   MemBase      = TPlus.Reg[MEM_BASE];
  53381. X   MemBase += (TPlus.Reg[MEM_MAP] != 3) ? 8 : 0;
  53382. X   TPlus.Screen = (BYTE far *)(MemBase << 28);
  53383. X
  53384. X   if(!TargapSys(IOBASE, DOS_READ))
  53385. X      return(0);
  53386. X   ioBase = TPlusIO.BoardNumber;
  53387. X   TPlus.Read = ReadOffsets;
  53388. X   TPlus.Write = WriteOffsets;
  53389. X   for(n = 0; n < sizeof(TPlus.Read) / sizeof(unsigned); n++)
  53390. X      ((unsigned far *)&(TPlus.Read))[n] += ioBase;
  53391. X   for(n = 0; n < sizeof(TPlus.Write) / sizeof(unsigned); n++)
  53392. X      ((unsigned far *)&(TPlus.Write))[n] += ioBase;
  53393. X
  53394. X   EnableMemory();
  53395. X   return(1);
  53396. X}
  53397. X
  53398. Xint ResetBoard(int BoardNumber) {
  53399. X   int CurrBoard, Status = 0;
  53400. X
  53401. X   CurrBoard = TPlus.ThisBoard;
  53402. X   if(_SetBoard(BoardNumber))
  53403. X      Status = TargapSys(RESET, DOS_WRITE);
  53404. X   if(CurrBoard > 0)
  53405. X      _SetBoard(CurrBoard);
  53406. X   return(Status);
  53407. X}
  53408. X
  53409. X#include <fcntl.h>
  53410. X#include <io.h>
  53411. X
  53412. Xint CheckForTPlus(void) {
  53413. X   unsigned n;
  53414. X
  53415. X   if((hTPlus = open("TARGPLUS", O_RDWR | O_BINARY )) != -1) {
  53416. X      if(!TargapSys(NUMBOARDS, DOS_READ))
  53417. X     return(0);
  53418. X      NumTPlus = TPlusIO.BoardNumber;
  53419. X      TPlus.ThisBoard = -1;
  53420. X      TPlus.ClearScreen = 1;
  53421. X      for(n = 0; n < NumTPlus; n++)
  53422. X     if(!ResetBoard(n))
  53423. X        return(0);
  53424. X      if(SetBoard(0))
  53425. X     return(1);
  53426. X   }
  53427. X   return(0);
  53428. X}
  53429. X
  53430. Xint SetTPlusMode(int Mode, int NotIntFlag, int Depth, int Zoom) {
  53431. X   unsigned n;
  53432. X   char PathName[80];
  53433. X   FILE *Data;
  53434. X   unsigned NewRegs[128];
  53435. X
  53436. X   findpath("tplus.dat", PathName);
  53437. X   if(PathName[0]) {
  53438. X      if((Data = fopen(PathName, "rb")) != 0) {
  53439. X     if(!fseek(Data, (long)Mode << 8, SEEK_SET)) {
  53440. X        if(fread(NewRegs, 1, 256, Data) == 256) {
  53441. X           fclose(Data);
  53442. X           NewRegs[PE] = TPlus.Reg[PE];
  53443. X           NewRegs[OVLE] = TPlus.Reg[OVLE];
  53444. X           NewRegs[RGB] = TPlus.Reg[RGB];
  53445. X           NewRegs[SVIDEO] = TPlus.Reg[SVIDEO];
  53446. X           NewRegs[DAC567DATA] = TPlus.Reg[DAC567DATA];
  53447. X           NewRegs[VGASRC] = TPlus.Reg[VGASRC];
  53448. X           for(n = 0; n < 128; n++)
  53449. X          TPlus.Reg[n] = NewRegs[n];
  53450. X           if(TPlus.Reg[VTOP + 1] == 0xffff)
  53451. X          TPlus.Reg[NOT_INT] = 0;
  53452. X           else if(TPlus.Reg[VTOP] == 0xffff && !NotIntFlag) {
  53453. X          TPlusErr = 1;
  53454. X          return(0);
  53455. X           }
  53456. X           else
  53457. X          TPlus.Reg[NOT_INT] = NotIntFlag;
  53458. X           TPlus.xdots = TPlus.Reg[XDOTS];
  53459. X           TPlus.ydots = TPlus.Reg[YDOTS];
  53460. X           if(Zoom) {
  53461. X          TPlus.Reg[ZOOM] = Zoom;
  53462. X          TPlus.xdots >>= Zoom;
  53463. X          TPlus.ydots >>= Zoom;
  53464. X           }
  53465. X           return(SetColorDepth(Depth));
  53466. X        }
  53467. X     }
  53468. X      }
  53469. X   }
  53470. X   if(Data > 0)
  53471. X      fclose(Data);
  53472. X   return(0);
  53473. X}
  53474. X
  53475. Xint FillTPlusRegion(unsigned x, unsigned y, unsigned xdots, unsigned ydots,
  53476. X           unsigned long Color) {
  53477. X   int Status = 0;
  53478. X
  53479. X   TPlusIO.Initx = x;
  53480. X   TPlusIO.Inity = TPlus.Reg[YDOTS] - (y + ydots) - 2;
  53481. X   TPlusIO.Finalx = x + xdots - 1;
  53482. X   TPlusIO.Finaly = TPlus.Reg[YDOTS] - y - 1;
  53483. X   TPlusIO.Color = Color;
  53484. X   Status = TargapSys(FILLBLOCK, DOS_WRITE);
  53485. X   EnableMemory();
  53486. X   return(Status);
  53487. X}
  53488. X
  53489. Xvoid BlankScreen(unsigned long Color) {
  53490. X   unsigned BufferPort;
  53491. X
  53492. X   OUTPORTW(TPlus.Write.COLOR0, ((unsigned*)&Color)[0]);
  53493. X   OUTPORTB(TPlus.Write.COLOR2, ((unsigned*)&Color)[1]);
  53494. X   OUTPORTB(TPlus.Write.COLOR3, 0xff);
  53495. X   BufferPort = ReadTPByte(0xe9);
  53496. X   BufferPort |= 3;
  53497. X   WriteTPByte(0xe9, BufferPort);
  53498. X}
  53499. X
  53500. Xvoid UnBlankScreen(void) {
  53501. X   unsigned BufferPort;
  53502. X
  53503. X   BufferPort = ReadTPByte(0xe9);
  53504. X   BufferPort &= 0xfe;
  53505. X   WriteTPByte(0xe9, BufferPort);
  53506. X}
  53507. X
  53508. Xvoid EnableOverlayCapture(void) {
  53509. X   unsigned Mode2;
  53510. X
  53511. X   Mode2 = INPORTB(TPlus.Read.MODE2);
  53512. X   Mode2 |= (1 << 6);
  53513. X   Mode2 &= (0xff ^ (3 << 4));
  53514. X   Mode2 |= (1 << 5);
  53515. X   OUTPORTB(TPlus.Write.MODE2, Mode2);
  53516. X}
  53517. X
  53518. Xvoid DisableOverlayCapture(void) {
  53519. X   unsigned Mode2;
  53520. X
  53521. X   Mode2 = INPORTB(TPlus.Read.MODE2);
  53522. X   Mode2 &= (0xff ^ (7 << 4));
  53523. X   OUTPORTB(TPlus.Write.MODE2, Mode2);
  53524. X}
  53525. X
  53526. Xvoid ClearTPlusScreen(void) {
  53527. X   BlankScreen(0L);
  53528. X   EnableOverlayCapture();
  53529. X   TargapSys(WAITFORVB, DOS_READ);
  53530. X   TargapSys(WAITFORVB, DOS_READ);
  53531. X   TargapSys(WAITFORVB, DOS_READ);
  53532. X   DisableOverlayCapture();
  53533. X   UnBlankScreen();
  53534. X}
  53535. X
  53536. Xstatic struct {
  53537. X   unsigned xdots, ydots, Template, Zoom, Depth;
  53538. X} far ModeTable[] = {
  53539. X   512, 400, 0,  0, 4,
  53540. X   512, 476, 1,  0, 4,
  53541. X   512, 486, 2,  0, 4,
  53542. X   512, 576, 3,  0, 4,
  53543. X   640, 480, 4,  0, 2,
  53544. X   648, 486, 5,  0, 2,
  53545. X   720, 486, 6,  0, 2,
  53546. X   720, 576, 7,  0, 2,
  53547. X   756, 486, 8,  0, 2,
  53548. X   768, 576, 9,  0, 2,
  53549. X   800, 600, 10, 0, 2,
  53550. X   1024,768, 11, 0, 2,
  53551. X   640, 400, 13, 0, 2,
  53552. X   320, 200, 13, 1, 2,
  53553. X   512, 496, 14, 0, 4,
  53554. X   640, 496, 15, 0, 2,
  53555. X};
  53556. X
  53557. Xstatic unsigned TableSize = (sizeof(ModeTable) / sizeof(ModeTable[0]));
  53558. X
  53559. Xint MatchTPlusMode(unsigned xdots, unsigned ydots, unsigned MaxColorRes,
  53560. X           unsigned PixelZoom, unsigned NonInterlaced) {
  53561. X   unsigned n, Depth;
  53562. X
  53563. X   for(n = 0; n < TableSize; n++) {
  53564. X      if(ModeTable[n].xdots == xdots && ModeTable[n].ydots == ydots)
  53565. X     break;
  53566. X   }
  53567. X   if(n < TableSize) {
  53568. X      if(ModeTable[n].Zoom)
  53569. X     PixelZoom += ModeTable[n].Zoom;
  53570. X      if(PixelZoom > 4)
  53571. X     PixelZoom = 4;
  53572. X      switch(MaxColorRes) {
  53573. X     case 24:
  53574. X        Depth = 4;
  53575. X        break;
  53576. X     case 16:
  53577. X        Depth = 2;
  53578. X        break;
  53579. X     case 8:
  53580. X     default:
  53581. X        Depth = 1;
  53582. X        break;
  53583. X      }
  53584. X      if(ModeTable[n].Depth < Depth)
  53585. X     Depth = ModeTable[n].Depth;
  53586. X      return(SetTPlusMode(ModeTable[n].Template, NonInterlaced, Depth,
  53587. X         PixelZoom));
  53588. X   }
  53589. X   return(0);
  53590. X}
  53591. X
  53592. Xvoid TPlusZoom(int Zoom) {
  53593. X   unsigned Mode2;
  53594. X
  53595. X   Zoom &= 3;
  53596. X   Mode2 = INPORTB(TPlus.Read.MODE2);
  53597. X   Mode2 &= (0xff ^ (3 << 2));
  53598. X   Mode2 |= (Zoom << 2);
  53599. X   OUTPORTB(TPlus.Write.MODE2, Mode2);
  53600. X}
  53601. X
  53602. X#endif
  53603. SHAR_EOF
  53604. $TOUCH -am 1028230093 tplus.c &&
  53605. chmod 0644 tplus.c ||
  53606. echo "restore of tplus.c failed"
  53607. set `wc -c tplus.c`;Wc_c=$1
  53608. if test "$Wc_c" != "11727"; then
  53609.     echo original size 11727, current size $Wc_c
  53610. fi
  53611. # ============= zoom.c ==============
  53612. echo "x - extracting zoom.c (Text)"
  53613. sed 's/^X//' << 'SHAR_EOF' > zoom.c &&
  53614. X/*
  53615. X    zoom.c - routines for zoombox manipulation and for panning
  53616. X
  53617. X*/
  53618. X
  53619. X#include <float.h>
  53620. X#include <stdio.h>
  53621. X#include <stdlib.h>
  53622. X#include <string.h>
  53623. X#include "fractint.h"
  53624. X#include "prototyp.h"
  53625. X
  53626. X/* screen dimensions here are (1.0,1.0) corresponding to (xdots-1,ydots-1) */
  53627. Xextern double zbx,zby;           /* topleft of unrotated zoombox  */
  53628. Xextern double zwidth,zdepth,zskew; /* zoombox size & shape        */
  53629. Xextern int zrotate;           /* * 2.5 degree increments        */
  53630. Xextern int boxcount,boxx[],boxy[]; /* co-ords of each zoombox pixel */
  53631. Xextern int xdots,ydots,sxdots,sydots,sxoffs,syoffs;
  53632. Xextern double dxsize,dysize;       /* xdots-1, ydots-1            */
  53633. Xextern double xxmin,yymin,xxmax,yymax,xx3rd,yy3rd;
  53634. Xextern double sxmin,symin,sxmax,symax,sx3rd,sy3rd;
  53635. X/* top      left    corner of screen is (xxmin,yymax) */
  53636. X/* bottom left    corner of screen is (xx3rd,yy3rd) */
  53637. X/* bottom right corner of screen is (xxmax,yymin) */
  53638. Xextern double plotmx1,plotmx2,plotmy1,plotmy2;
  53639. X
  53640. Xextern int  calc_status;       /* status of calculations */
  53641. Xextern int  fractype;           /* fractal type */
  53642. Xextern char stdcalcmode;       /* '1', '2', 'g', 'b', or 't' */
  53643. Xextern int  num_worklist;       /* resume worklist for standard engine */
  53644. Xextern struct workliststuff worklist[MAXCALCWORK];
  53645. Xextern char dstack[4096];       /* common temp, used for get_line/put_line */
  53646. Xextern int  potflag;
  53647. Xextern int  pot16bit;
  53648. Xextern float finalaspectratio;
  53649. Xextern float  screenaspect;
  53650. X
  53651. Xstruct coords {
  53652. X    int x,y;
  53653. X    };
  53654. X
  53655. X#define PIXELROUND 0.00001
  53656. X
  53657. Xstatic void _fastcall drawlines(struct coords, struct coords, int, int);
  53658. Xstatic void _fastcall addbox(struct coords);
  53659. Xstatic void _fastcall zmo_calc(double, double, double *, double *);
  53660. Xstatic int  check_pan();
  53661. Xstatic void fix_worklist();
  53662. Xstatic void _fastcall move_row(int fromrow,int torow,int col);
  53663. X
  53664. Xvoid drawbox(int drawit)
  53665. X{   struct coords tl,bl,tr,br; /* dot addr of topleft, botleft, etc */
  53666. X    double tmpx,tmpy,dx,dy,rotcos,rotsin,ftemp1,ftemp2;
  53667. X    double fxwidth,fxskew,fydepth,fyskew,fxadj;
  53668. X
  53669. X    if (zwidth==0) { /* no box to draw */
  53670. X    if (boxcount!=0) { /* remove the old box from display */
  53671. X        clearbox();   /* asm routine */
  53672. X        boxcount = 0; }
  53673. X    reset_zoom_corners();
  53674. X    return; }
  53675. X
  53676. X    ftemp1 = PI*zrotate/72; /* convert to radians */
  53677. X    rotcos = cos(ftemp1);   /* sin & cos of rotation */
  53678. X    rotsin = sin(ftemp1);
  53679. X
  53680. X    /* do some calcs just once here to reduce fp work a bit */
  53681. X    fxwidth = sxmax-sx3rd;
  53682. X    fxskew  = sx3rd-sxmin;
  53683. X    fydepth = sy3rd-symax;
  53684. X    fyskew  = symin-sy3rd;
  53685. X    fxadj   = zwidth*zskew;
  53686. X
  53687. X    /* calc co-ords of topleft & botright corners of box */
  53688. X    tmpx = zwidth/-2+fxadj; /* from zoombox center as origin, on xdots scale */
  53689. X    tmpy = zdepth*finalaspectratio/2;
  53690. X    dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; /* delta x to rotate topleft */
  53691. X    dy = tmpy - (rotsin*tmpx + rotcos*tmpy); /* delta y to rotate topleft */
  53692. X    /* calc co-ords of topleft */
  53693. X    ftemp1 = zbx + dx + fxadj;
  53694. X    ftemp2 = zby + dy/finalaspectratio;
  53695. X    tl.x   = ftemp1*(dxsize+PIXELROUND); /* screen co-ords */
  53696. X    tl.y   = ftemp2*(dysize+PIXELROUND);
  53697. X    xxmin  = sxmin + ftemp1*fxwidth + ftemp2*fxskew; /* real co-ords */
  53698. X    yymax  = symax + ftemp2*fydepth + ftemp1*fyskew;
  53699. X    /* calc co-ords of bottom right */
  53700. X    ftemp1 = zbx + zwidth - dx - fxadj;
  53701. X    ftemp2 = zby - dy/finalaspectratio + zdepth;
  53702. X    br.x   = ftemp1*(dxsize+PIXELROUND);
  53703. X    br.y   = ftemp2*(dysize+PIXELROUND);
  53704. X    xxmax  = sxmin + ftemp1*fxwidth + ftemp2*fxskew;
  53705. X    yymin  = symax + ftemp2*fydepth + ftemp1*fyskew;
  53706. X
  53707. X    /* do the same for botleft & topright */
  53708. X    tmpx = zwidth/-2 - fxadj;
  53709. X    tmpy = 0.0-tmpy;
  53710. X    dx = (rotcos*tmpx - rotsin*tmpy) - tmpx;
  53711. X    dy = tmpy - (rotsin*tmpx + rotcos*tmpy);
  53712. X    ftemp1 = zbx + dx - fxadj;
  53713. X    ftemp2 = zby + dy/finalaspectratio + zdepth;
  53714. X    bl.x   = ftemp1*(dxsize+PIXELROUND);
  53715. X    bl.y   = ftemp2*(dysize+PIXELROUND);
  53716. X    xx3rd  = sxmin + ftemp1*fxwidth + ftemp2*fxskew;
  53717. X    yy3rd  = symax + ftemp2*fydepth + ftemp1*fyskew;
  53718. X    ftemp1 = zbx + zwidth - dx + fxadj;
  53719. X    ftemp2 = zby - dy/finalaspectratio;
  53720. X    tr.x   = ftemp1*(dxsize+PIXELROUND);
  53721. X    tr.y   = ftemp2*(dysize+PIXELROUND);
  53722. X
  53723. X    if (boxcount!=0) { /* remove the old box from display */
  53724. X    clearbox();   /* asm routine */
  53725. X    boxcount = 0; }
  53726. X
  53727. X    if (drawit) { /* caller wants box drawn as well as co-ords calc'd */
  53728. X#ifndef XFRACT
  53729. X    /* build the list of zoom box pixels */
  53730. X    addbox(tl); addbox(tr);           /* corner pixels */
  53731. X    addbox(bl); addbox(br);
  53732. X    drawlines(tl,tr,bl.x-tl.x,bl.y-tl.y); /* top & bottom lines */
  53733. X    drawlines(tl,bl,tr.x-tl.x,tr.y-tl.y); /* left & right lines */
  53734. X#else
  53735. X        boxx[0] = tl.x + sxoffs;
  53736. X        boxy[0] = tl.y + syoffs;
  53737. X        boxx[1] = tr.x + sxoffs;
  53738. X        boxy[1] = tr.y + syoffs;
  53739. X        boxx[2] = br.x + sxoffs;
  53740. X        boxy[2] = br.y + syoffs;
  53741. X        boxx[3] = bl.x + sxoffs;
  53742. X        boxy[3] = bl.y + syoffs;
  53743. X        boxcount = 1;
  53744. X#endif
  53745. X    dispbox();                  /* asm routine to paint it */
  53746. X    }
  53747. X    }
  53748. X
  53749. Xstatic void _fastcall drawlines(struct coords fr, struct coords to,
  53750. X                int dx, int dy)
  53751. X{   int xincr,yincr,ctr;
  53752. X    int altctr,altdec,altinc;
  53753. X    struct coords tmpp,line1,line2;
  53754. X
  53755. X    if (abs(to.x-fr.x) > abs(to.y-fr.y)) { /* delta.x > delta.y */
  53756. X    if (fr.x>to.x) { /* swap so from.x is < to.x */
  53757. X        tmpp = fr; fr = to; to = tmpp; }
  53758. X    xincr = (to.x-fr.x)*4/sxdots+1; /* do every 1st, 2nd, 3rd, or 4th dot */
  53759. X    ctr = (to.x-fr.x-1)/xincr;
  53760. X    altdec = abs(to.y-fr.y)*xincr;
  53761. X    altinc = to.x-fr.x;
  53762. X    altctr = altinc/2;
  53763. X    yincr = (to.y>fr.y)?1:-1;
  53764. X    line2.x = (line1.x = fr.x) + dx;
  53765. X    line2.y = (line1.y = fr.y) + dy;
  53766. X    while (--ctr>=0) {
  53767. X        line1.x += xincr;
  53768. X        line2.x += xincr;
  53769. X        altctr -= altdec;
  53770. X        while (altctr<0) {
  53771. X        altctr    += altinc;
  53772. X        line1.y += yincr;
  53773. X        line2.y += yincr;
  53774. X        }
  53775. X        addbox(line1);
  53776. X        addbox(line2);
  53777. X        }
  53778. X    }
  53779. X
  53780. X    else { /* delta.y > delta.x */
  53781. X    if (fr.y>to.y) { /* swap so from.y is < to.y */
  53782. X        tmpp = fr; fr = to; to = tmpp; }
  53783. X    yincr = (to.y-fr.y)*4/sydots+1; /* do every 1st, 2nd, 3rd, or 4th dot */
  53784. X    ctr = (to.y-fr.y-1)/yincr;
  53785. X    altdec = abs(to.x-fr.x)*yincr;
  53786. X    altinc = to.y-fr.y;
  53787. X    altctr = altinc/2;
  53788. X    xincr = (to.x>fr.x) ? 1 : -1;
  53789. X    line2.x = (line1.x = fr.x) + dx;
  53790. X    line2.y = (line1.y = fr.y) + dy;
  53791. X    while (--ctr>=0) {
  53792. X        line1.y += yincr;
  53793. X        line2.y += yincr;
  53794. X        altctr  -= altdec;
  53795. X        while (altctr<0) {
  53796. X        altctr    += altinc;
  53797. X        line1.x += xincr;
  53798. X        line2.x += xincr;
  53799. X        }
  53800. X        addbox(line1);
  53801. X        addbox(line2);
  53802. X        }
  53803. X    }
  53804. X    }
  53805. X
  53806. Xstatic void _fastcall addbox(struct coords point)
  53807. X{
  53808. X    point.x += sxoffs;
  53809. X    point.y += syoffs;
  53810. X    if (point.x >= 0 && point.x < sxdots && point.y >= 0 && point.y < sydots) {
  53811. X    boxx[boxcount] = point.x;
  53812. X    boxy[boxcount] = point.y;
  53813. X    ++boxcount;
  53814. X    }
  53815. X    }
  53816. X
  53817. Xvoid moveboxf(double dx, double dy)
  53818. X{   int align,row,col;
  53819. X    align = check_pan();
  53820. X    if (dx!=0.0) {
  53821. X    if ((zbx += dx) + zwidth/2 < 0)  /* center must stay onscreen */
  53822. X        zbx = zwidth/-2;
  53823. X    if (zbx + zwidth/2 > 1)
  53824. X        zbx = 1.0 - zwidth/2;
  53825. X    if (align != 0
  53826. X      && ((col = zbx*(dxsize+PIXELROUND)) & (align-1)) != 0) {
  53827. X        if (dx > 0) col += align;
  53828. X        col -= col & (align-1); /* adjust col to pass alignment */
  53829. X        zbx = (double)col/dxsize; }
  53830. X    }
  53831. X    if (dy!=0.0) {
  53832. X    if ((zby += dy) + zdepth/2 < 0)
  53833. X        zby = zdepth/-2;
  53834. X    if (zby + zdepth/2 > 1)
  53835. X        zby = 1.0 - zdepth/2;
  53836. X    if (align != 0
  53837. X      && ((row = zby*(dysize+PIXELROUND)) & (align-1)) != 0) {
  53838. X        if (dy > 0) row += align;
  53839. X        row -= row & (align-1);
  53840. X        zby = (double)row/dysize; }
  53841. X    }
  53842. X    }
  53843. X
  53844. Xstatic void _fastcall chgboxf(double dwidth, double ddepth)
  53845. X{
  53846. X    if (zwidth+dwidth > 1)
  53847. X    dwidth = 1.0-zwidth;
  53848. X    if (zwidth+dwidth < 0.05)
  53849. X    dwidth = 0.05-zwidth;
  53850. X    zwidth += dwidth;
  53851. X    if (zdepth+ddepth > 1)
  53852. X    ddepth = 1.0-zdepth;
  53853. X    if (zdepth+ddepth < 0.05)
  53854. X    ddepth = 0.05-zdepth;
  53855. X    zdepth += ddepth;
  53856. X    moveboxf(dwidth/-2,ddepth/-2); /* keep it centered & check limits */
  53857. X    }
  53858. X
  53859. Xvoid resizebox(int steps)
  53860. X{
  53861. X    double deltax,deltay;
  53862. X    if (zdepth*screenaspect > zwidth) { /* box larger on y axis */
  53863. X    deltay = steps * 0.036 / screenaspect;
  53864. X    deltax = zwidth * deltay / zdepth;
  53865. X    }
  53866. X    else {                /* box larger on x axis */
  53867. X    deltax = steps * 0.036;
  53868. X    deltay = zdepth * deltax / zwidth;
  53869. X    }
  53870. X    chgboxf(deltax,deltay);
  53871. X    }
  53872. X
  53873. Xvoid chgboxi(int dw, int dd)
  53874. X{   /* change size by pixels */
  53875. X    chgboxf( (double)dw/dxsize, (double)dd/dysize );
  53876. X    }
  53877. X
  53878. X#ifdef C6
  53879. X#pragma optimize("e",off)  /* MSC 6.00A messes up next rtn with "e" on */
  53880. X#endif
  53881. X
  53882. Xvoid zoomout() /* for ctl-enter, calc corners for zooming out */
  53883. X{   double savxxmin,savyymax,ftemp;
  53884. X    /* (xxmin,yymax), etc, are already set to zoombox corners;
  53885. X       (sxmin,symax), etc, are still the screen's corners;
  53886. X       use the same logic as plot_orbit stuff to first calculate current screen
  53887. X       corners relative to the zoombox, as if the zoombox were a square with
  53888. X       upper left (0,0) and width/depth 1; ie calc the current screen corners
  53889. X       as if plotting them from the zoombox;
  53890. X       then extend these co-ords from current real screen corners to get
  53891. X       new actual corners
  53892. X       */
  53893. X    ftemp = (yymin-yy3rd)*(xx3rd-xxmin) - (xxmax-xx3rd)*(yy3rd-yymax);
  53894. X    plotmx1 = (xx3rd-xxmin) / ftemp; /* reuse the plotxxx vars is safe */
  53895. X    plotmx2 = (yy3rd-yymax) / ftemp;
  53896. X    plotmy1 = (yymin-yy3rd) / ftemp;
  53897. X    plotmy2 = (xxmax-xx3rd) / ftemp;
  53898. X    savxxmin = xxmin; savyymax = yymax;
  53899. X    zmo_calc(sxmin-savxxmin,symax-savyymax,&xxmin,&yymax); /* new xxmin/xxmax */
  53900. X    zmo_calc(sxmax-savxxmin,symin-savyymax,&xxmax,&yymin);
  53901. X    zmo_calc(sx3rd-savxxmin,sy3rd-savyymax,&xx3rd,&yy3rd);
  53902. X    }
  53903. X
  53904. X#ifdef C6
  53905. X#pragma optimize("e",on)  /* back to normal */
  53906. X#endif
  53907. X
  53908. Xstatic void _fastcall zmo_calc(double dx, double dy, double *newx, double *newy)
  53909. X{   double tempx,tempy;
  53910. X    /* calc cur screen corner relative to zoombox, when zoombox co-ords
  53911. X       are taken as (0,0) topleft thru (1,1) bottom right */
  53912. X    tempx = dy * plotmx1 - dx * plotmx2;
  53913. X    tempy = dx * plotmy1 - dy * plotmy2;
  53914. X    /* calc new corner by extending from current screen corners */
  53915. X    *newx = sxmin + tempx*(sxmax-sx3rd) + tempy*(sx3rd-sxmin);
  53916. X    *newy = symax + tempy*(sy3rd-symax) + tempx*(symin-sy3rd);
  53917. X    }
  53918. X
  53919. Xvoid aspectratio_crop(float oldaspect,float newaspect)
  53920. X{
  53921. X   double ftemp,xmargin,ymargin;
  53922. X   if (newaspect > oldaspect) { /* new ratio is taller, crop x */
  53923. X      ftemp = (1.0 - oldaspect / newaspect) / 2;
  53924. X      xmargin = (xxmax - xx3rd) * ftemp;
  53925. X      ymargin = (yymin - yy3rd) * ftemp;
  53926. X      xx3rd += xmargin;
  53927. X      yy3rd += ymargin;
  53928. X      }
  53929. X   else               { /* new ratio is wider, crop y */
  53930. X      ftemp = (1.0 - newaspect / oldaspect) / 2;
  53931. X      xmargin = (xx3rd - xxmin) * ftemp;
  53932. X      ymargin = (yy3rd - yymax) * ftemp;
  53933. X      xx3rd -= xmargin;
  53934. X      yy3rd -= ymargin;
  53935. X      }
  53936. X   xxmin += xmargin;
  53937. X   yymax += ymargin;
  53938. X   xxmax -= xmargin;
  53939. X   yymin -= ymargin;
  53940. X}
  53941. X
  53942. Xstatic int check_pan() /* return 0 if can't, alignment requirement if can */
  53943. X{   int i,j;
  53944. X    if (calc_status != 2 && calc_status != 4)
  53945. X    return(0); /* not resumable, not complete */
  53946. X    if ( curfractalspecific->calctype != StandardFractal
  53947. X      && curfractalspecific->calctype != calcmand
  53948. X      && curfractalspecific->calctype != calcmandfp
  53949. X      && curfractalspecific->calctype != lyapunov)
  53950. X    return(0); /* not a worklist-driven type */
  53951. X    if (zwidth != 1.0 || zdepth != 1.0 || zskew != 0.0 || zrotate != 0.0)
  53952. X    return(0); /* not a full size unrotated unskewed zoombox */
  53953. X    /* can pan if we get this far */
  53954. X    if (calc_status == 4)
  53955. X    return(1); /* image completed, align on any pixel */
  53956. X    if (potflag && pot16bit)
  53957. X    return(1); /* 1 pass forced so align on any pixel */
  53958. X    if (stdcalcmode == 'b')
  53959. X    return(1); /* btm, align on any pixel */
  53960. X    if (stdcalcmode == 't')
  53961. X    return(0); /* tesselate, can't do it */
  53962. X    if (stdcalcmode != 'g' || (curfractalspecific->flags&NOGUESS)) {
  53963. X    if (stdcalcmode == '2') /* align on even pixel for 2pass */
  53964. X       return(2);
  53965. X    return(1); /* assume 1pass */
  53966. X    }
  53967. X    /* solid guessing */
  53968. X    start_resume();
  53969. X    get_resume(sizeof(int),&num_worklist,sizeof(worklist),worklist,0);
  53970. X    /* don't do end_resume! we're just looking */
  53971. X    i = 9;
  53972. X    for (j=0; j<num_worklist; ++j) /* find lowest pass in any pending window */
  53973. X    if (worklist[j].pass < i)
  53974. X        i = worklist[j].pass;
  53975. X    j = ssg_blocksize(); /* worst-case alignment requirement */
  53976. X    while (--i >= 0)
  53977. X    j = j>>1; /* reduce requirement */
  53978. X    return(j);
  53979. X    }
  53980. X
  53981. Xstatic void _fastcall move_row(int fromrow,int torow,int col)
  53982. X/* move a row on the screen */
  53983. X{   int startcol,endcol,tocol;
  53984. X    memset(dstack,0,xdots); /* use dstack as a temp for the row; clear it */
  53985. X    if (fromrow >= 0 && fromrow < ydots) {
  53986. X    tocol = startcol = 0;
  53987. X    endcol = xdots-1;
  53988. X    if (col < 0) {
  53989. X        tocol -= col;
  53990. X        endcol += col; }
  53991. X    if (col > 0)
  53992. X        startcol += col;
  53993. X    get_line(fromrow,startcol,endcol,(BYTE *)&dstack[tocol]);
  53994. X    }
  53995. X    put_line(torow,0,xdots-1,(BYTE *)dstack);
  53996. X    }
  53997. X
  53998. Xint init_pan_or_recalc(int do_zoomout) /* decide to recalc, or to chg worklist & pan */
  53999. X{   int i,j,row,col,y,alignmask,listfull;
  54000. X    if (zwidth == 0.0)
  54001. X    return(0); /* no zoombox, leave calc_status as is */
  54002. X    /* got a zoombox */
  54003. X    if ((alignmask=check_pan()-1) < 0) {
  54004. X    calc_status = 0; /* can't pan, trigger recalc */
  54005. X    return(0); }
  54006. X    if (zbx == 0.0 && zby == 0.0) {
  54007. X    clearbox();
  54008. X    return(0); } /* box is full screen, leave calc_status as is */
  54009. X    col = zbx*(dxsize+PIXELROUND); /* calc dest col,row of topleft pixel */
  54010. X    row = zby*(dysize+PIXELROUND);
  54011. X    if (do_zoomout) { /* invert row and col */
  54012. X    row = 0-row;
  54013. X    col = 0-col; }
  54014. X    if ((row&alignmask) != 0 || (col&alignmask) != 0) {
  54015. X    calc_status = 0; /* not on useable pixel alignment, trigger recalc */
  54016. X    return(0); }
  54017. X    /* pan */
  54018. X    num_worklist = 0;
  54019. X    if (calc_status == 2) {
  54020. X       start_resume();
  54021. X       get_resume(sizeof(int),&num_worklist,sizeof(worklist),worklist,0);
  54022. X       } /* don't do end_resume! we might still change our mind */
  54023. X    /* adjust existing worklist entries */
  54024. X    for (i=0; i<num_worklist; ++i) {
  54025. X    worklist[i].yystart -= row;
  54026. X    worklist[i].yystop  -= row;
  54027. X    worklist[i].yybegin -= row;
  54028. X    worklist[i].xxstart -= col;
  54029. X    worklist[i].xxstop  -= col;
  54030. X    }
  54031. X    /* add worklist entries for the new edges */
  54032. X    listfull = i = 0;
  54033. X    j = ydots-1;
  54034. X    if (row < 0) {
  54035. X    listfull |= add_worklist(0,xdots-1,0,0-row-1,0,0,0);
  54036. X    i = 0 - row; }
  54037. X    if (row > 0) {
  54038. X    listfull |= add_worklist(0,xdots-1,ydots-row,ydots-1,ydots-row,0,0);
  54039. X    j = ydots - row - 1; }
  54040. X    if (col < 0)
  54041. X    listfull |= add_worklist(0,0-col-1,i,j,i,0,0);
  54042. X    if (col > 0)
  54043. X    listfull |= add_worklist(xdots-col,xdots-1,i,j,i,0,0);
  54044. X    if (listfull != 0) {
  54045. X    static char far msg[] = {"\
  54046. XTables full, can't pan current image.\n\
  54047. XCancel resumes old image, continue pans and calculates a new one."};
  54048. X    if (stopmsg(2,msg)) {
  54049. X        zwidth = 0; /* cancel the zoombox */
  54050. X        drawbox(1); }
  54051. X    else
  54052. X        calc_status = 0; /* trigger recalc */
  54053. X    return(0); }
  54054. X    /* now we're committed */
  54055. X    calc_status = 2;
  54056. X    clearbox();
  54057. X    if (row > 0) /* move image up */
  54058. X    for (y=0; y<ydots; ++y) move_row(y+row,y,col);
  54059. X    else     /* move image down */
  54060. X    for (y=ydots; --y>=0;)    move_row(y+row,y,col);
  54061. X    fix_worklist(); /* fixup any out of bounds worklist entries */
  54062. X    alloc_resume(sizeof(worklist)+10,1); /* post the new worklist */
  54063. X    put_resume(sizeof(int),&num_worklist,sizeof(worklist),worklist,0);
  54064. X    return(0);
  54065. X    }
  54066. X
  54067. Xstatic void _fastcall restart_window(int wknum)
  54068. X/* force a worklist entry to restart */
  54069. X{   int yfrom,yto,xfrom,xto;
  54070. X    if ((yfrom = worklist[wknum].yystart) < 0) yfrom = 0;
  54071. X    if ((xfrom = worklist[wknum].xxstart) < 0) xfrom = 0;
  54072. X    if ((yto = worklist[wknum].yystop) >= ydots) yto = ydots - 1;
  54073. X    if ((xto = worklist[wknum].xxstop) >= xdots) xto = xdots - 1;
  54074. X    memset(dstack,0,xdots); /* use dstack as a temp for the row; clear it */
  54075. X    while (yfrom <= yto)
  54076. X    put_line(yfrom++,xfrom,xto,(BYTE *)dstack);
  54077. X    worklist[wknum].sym = worklist[wknum].pass = 0;
  54078. X    worklist[wknum].yybegin = worklist[wknum].yystart;
  54079. X}
  54080. X
  54081. Xstatic void fix_worklist() /* fix out of bounds and symmetry related stuff */
  54082. X{   int i,j,k;
  54083. X    struct workliststuff *wk;
  54084. X    for (i=0; i<num_worklist; ++i) {
  54085. X    wk = &worklist[i];
  54086. X    if ( wk->yystart >= ydots || wk->yystop < 0
  54087. X      || wk->xxstart >= xdots || wk->xxstop < 0) { /* offscreen, delete */
  54088. X        for (j=i+1; j<num_worklist; ++j)
  54089. X        worklist[j-1] = worklist[j];
  54090. X        --num_worklist;
  54091. X        --i;
  54092. X        continue; }
  54093. X    if (wk->yystart < 0) /* partly off top edge */
  54094. X        if ((wk->sym&1) == 0) /* no sym, easy */
  54095. X        wk->yystart = 0;
  54096. X        else { /* xaxis symmetry */
  54097. X        if ((j = wk->yystop + wk->yystart) > 0
  54098. X          && num_worklist < MAXCALCWORK) { /* split the sym part */
  54099. X            worklist[num_worklist] = worklist[i];
  54100. X            worklist[num_worklist].yystart = 0;
  54101. X            worklist[num_worklist++].yystop = j;
  54102. X            wk->yystart = j+1; }
  54103. X        else
  54104. X            wk->yystart = 0;
  54105. X        restart_window(i); /* restart the no-longer sym part */
  54106. X        }
  54107. X    if (wk->yystop >= ydots) { /* partly off bottom edge */
  54108. X       j = ydots-1;
  54109. X       if ((wk->sym&1) != 0) { /* uses xaxis symmetry */
  54110. X          if ((k = wk->yystart + (wk->yystop - j)) < j)
  54111. X         if (num_worklist >= MAXCALCWORK) /* no room to split */
  54112. X            restart_window(i);
  54113. X         else { /* split it */
  54114. X            worklist[num_worklist] = worklist[i];
  54115. X            worklist[num_worklist].yystart = k;
  54116. X            worklist[num_worklist++].yystop = j;
  54117. X            j = k-1; }
  54118. X          wk->sym &= -1 - 1; }
  54119. X       wk->yystop = j; }
  54120. X    if (wk->xxstart < 0) /* partly off left edge */
  54121. X        if ((wk->sym&2) == 0) /* no sym, easy */
  54122. X        wk->xxstart = 0;
  54123. X        else { /* yaxis symmetry */
  54124. X        if ((j = wk->xxstop + wk->xxstart) > 0
  54125. X          && num_worklist < MAXCALCWORK) { /* split the sym part */
  54126. X            worklist[num_worklist] = worklist[i];
  54127. X            worklist[num_worklist].xxstart = 0;
  54128. X            worklist[num_worklist++].xxstop = j;
  54129. X            wk->xxstart = j+1; }
  54130. X        else
  54131. X            wk->xxstart = 0;
  54132. X        restart_window(i); /* restart the no-longer sym part */
  54133. X        }
  54134. X    if (wk->xxstop >= xdots) { /* partly off right edge */
  54135. X       j = xdots-1;
  54136. X       if ((wk->sym&2) != 0) { /* uses xaxis symmetry */
  54137. X          if ((k = wk->xxstart + (wk->xxstop - j)) < j)
  54138. X         if (num_worklist >= MAXCALCWORK) /* no room to split */
  54139. X            restart_window(i);
  54140. X         else { /* split it */
  54141. X            worklist[num_worklist] = worklist[i];
  54142. X            worklist[num_worklist].xxstart = k;
  54143. X            worklist[num_worklist++].xxstop = j;
  54144. X            j = k-1; }
  54145. X          wk->sym &= -1 - 2; }
  54146. X       wk->xxstop = j; }
  54147. X    if (wk->yybegin < wk->yystart) wk->yybegin = wk->yystart;
  54148. X    if (wk->yybegin > wk->yystop)  wk->yybegin = wk->yystop;
  54149. X    }
  54150. X    tidy_worklist(); /* combine where possible, re-sort */
  54151. X}
  54152. X
  54153. SHAR_EOF
  54154. $TOUCH -am 1028230093 zoom.c &&
  54155. chmod 0644 zoom.c ||
  54156. echo "restore of zoom.c failed"
  54157. set `wc -c zoom.c`;Wc_c=$1
  54158. if test "$Wc_c" != "18354"; then
  54159.     echo original size 18354, current size $Wc_c
  54160. fi
  54161. # ============= fractint.h ==============
  54162. echo "x - extracting fractint.h (Text)"
  54163. sed 's/^X//' << 'SHAR_EOF' > fractint.h &&
  54164. X/* FRACTINT.H - common structures and values for the FRACTINT routines */
  54165. X
  54166. X#if defined(PUTTHEMHERE)        /* this MUST be defined ONLY in FRACTINT.C */
  54167. Xstruct videoinfo videoentry;
  54168. Xint helpmode;
  54169. X#endif
  54170. X
  54171. X#ifndef FRACTINT_H
  54172. X#define FRACTINT_H
  54173. X
  54174. X#if !defined(PUTTHEMHERE)  
  54175. Xextern struct videoinfo videoentry;
  54176. Xextern int        helpmode;
  54177. X#endif
  54178. X
  54179. X#include <math.h>
  54180. X#include "port.h"
  54181. X
  54182. Xtypedef BYTE BOOLEAN;
  54183. X
  54184. X#ifndef C6
  54185. X#define _fastcall    /* _fastcall is a Microsoft C6.00 extension */
  54186. X#endif
  54187. X
  54188. X#ifndef XFRACT
  54189. Xtypedef int SEGTYPE;
  54190. Xtypedef unsigned USEGTYPE;
  54191. X#ifdef __TURBOC__
  54192. X#   define _bios_printer(a,b,c)   biosprint((a),(c),(b))
  54193. X#   define _bios_serialcom(a,b,c) bioscom((a),(c),(b))
  54194. X#else
  54195. X#ifndef __WATCOMC__
  54196. X#ifndef MK_FP
  54197. X#   define MK_FP(seg,off) (VOIDFARPTR )( (((long)(seg))<<16) | \
  54198. X                                          ((unsigned)(off)) )
  54199. X#endif
  54200. X#endif
  54201. X#endif
  54202. X#else
  54203. Xtypedef char * SEGTYPE;
  54204. Xtypedef char * USEGTYPE;
  54205. X#   define MK_FP(seg,off) (VOIDFARPTR )(seg+off)
  54206. X#endif
  54207. X
  54208. X
  54209. X#ifndef XFRACT
  54210. X#define clock_ticks() clock()
  54211. X#endif
  54212. X
  54213. X#ifdef XFRACT
  54214. X#define _fstrcpy(to,from) strcpy(to,from)
  54215. X#endif
  54216. X
  54217. X/* these are used to declare arrays for file names */
  54218. X#define FILE_MAX_PATH  80       /* max length of path+filename  */
  54219. X#define FILE_MAX_DIR   80       /* max length of directory name */
  54220. X#define FILE_MAX_DRIVE  3       /* max length of drive letter   */
  54221. X#define FILE_MAX_FNAME  9       /* max length of filename       */
  54222. X#define FILE_MAX_EXT    5       /* max length of extension      */
  54223. X
  54224. X#define MAXPARAMS 10        /* maximum number of parameters */
  54225. X#define MAXPIXELS 2048        /* Maximum pixel count across/down the screen */
  54226. X#define DEFAULTASPECT 0.75    /* Assumed overall screen dimensions, y/x     */
  54227. X
  54228. Xstruct videoinfo {        /* All we need to know about a Video Adapter */
  54229. X    char    name[26];    /* Adapter name (IBM EGA, etc)        */
  54230. X    char    comment[26];    /* Comments (UNTESTED, etc)        */
  54231. X    int    keynum;     /* key number used to invoked this mode */
  54232. X                /* 2-10 = F2-10, 11-40 = S,C,A{F1-F10}    */
  54233. X    int    videomodeax;    /* begin with INT 10H, AX=(this)    */
  54234. X    int    videomodebx;    /*        ...and BX=(this)    */
  54235. X    int    videomodecx;    /*        ...and CX=(this)    */
  54236. X    int    videomodedx;    /*        ...and DX=(this)    */
  54237. X                /* NOTE:  IF AX==BX==CX==0, SEE BELOW    */
  54238. X    int    dotmode;    /* video access method used by asm code */
  54239. X                /*    1 == BIOS 10H, AH=12,13 (SLOW)    */
  54240. X                /*    2 == access like EGA/VGA    */
  54241. X                /*    3 == access like MCGA        */
  54242. X                /*    4 == Tseng-like  SuperVGA*256    */
  54243. X                /*    5 == P'dise-like SuperVGA*256   */
  54244. X                /*    6 == Vega-like     SuperVGA*256    */
  54245. X                /*    7 == "Tweaked" IBM-VGA ...*256  */
  54246. X                /*    8 == "Tweaked" SuperVGA ...*256 */
  54247. X                /*    9 == Targa Format        */
  54248. X                /*    10 = Hercules            */
  54249. X                /*    11 = "disk video" (no screen)   */
  54250. X                /*    12 = 8514/A            */
  54251. X                /*    13 = CGA 320x200x4, 640x200x2    */
  54252. X                /*    14 = Tandy 1000         */
  54253. X                /*    15 = TRIDENT  SuperVGA*256    */
  54254. X                /*    16 = Chips&Tech SuperVGA*256    */
  54255. X    int    xdots;        /* number of dots across the screen    */
  54256. X    int    ydots;        /* number of dots down the screen    */
  54257. X    int    colors;     /* number of colors available        */
  54258. X    };
  54259. X
  54260. X
  54261. X#define INFO_ID     "Fractal"
  54262. X#define FRACTAL_INFO   struct fractal_info
  54263. X
  54264. X/*
  54265. X * Note: because non-MSDOS machines store structures differently, we have
  54266. X * to do special processing of the fractal_info structure in loadfile.c.
  54267. X * Make sure changes to the structure here get reflected there.
  54268. X */
  54269. X#ifndef XFRACT
  54270. X#define FRACTAL_INFO_SIZE sizeof(FRACTAL_INFO)
  54271. X#else
  54272. X/* This value should be the MSDOS size, not the Unix size. */
  54273. X#define FRACTAL_INFO_SIZE 502
  54274. X#endif
  54275. X
  54276. Xstruct fractal_info        /*  for saving data in GIF file     */
  54277. X{
  54278. X    char  info_id[8];        /* Unique identifier for info block */
  54279. X    short iterations;
  54280. X    short fractal_type;        /* 0=Mandelbrot 1=Julia 2= ... */
  54281. X    double xmin;
  54282. X    double xmax;
  54283. X    double ymin;
  54284. X    double ymax;
  54285. X    double creal;
  54286. X    double cimag;
  54287. X    short videomodeax;
  54288. X    short videomodebx;
  54289. X    short videomodecx;
  54290. X    short videomodedx;
  54291. X    short dotmode;
  54292. X    short xdots;
  54293. X    short ydots;
  54294. X    short colors;
  54295. X    short version;        /* used to be 'future[0]' */
  54296. X    float parm3;
  54297. X    float parm4;
  54298. X    float potential[3];
  54299. X    short rseed;
  54300. X    short rflag;
  54301. X    short biomorph;
  54302. X    short inside;
  54303. X    short logmap;
  54304. X    float invert[3];
  54305. X    short decomp[2];
  54306. X    short symmetry;
  54307. X            /* version 2 stuff */
  54308. X    short init3d[16];
  54309. X    short previewfactor;
  54310. X    short xtrans;
  54311. X    short ytrans;
  54312. X    short red_crop_left;
  54313. X    short red_crop_right;
  54314. X    short blue_crop_left;
  54315. X    short blue_crop_right;
  54316. X    short red_bright;
  54317. X    short blue_bright;
  54318. X    short xadjust;
  54319. X    short eyeseparation;
  54320. X    short glassestype;
  54321. X            /* version 3 stuff, release 13 */
  54322. X    short outside;
  54323. X            /* version 4 stuff, release 14 */
  54324. X    double x3rd;      /* 3rd corner */
  54325. X    double y3rd;
  54326. X    char stdcalcmode;      /* 1/2/g/b */
  54327. X    char useinitorbit;      /* init Mandelbrot orbit flag */
  54328. X    short calc_status;      /* resumable, finished, etc */
  54329. X    long tot_extend_len;  /* total length of extension blocks in .gif file */
  54330. X    short distest;
  54331. X    short floatflag;
  54332. X    short bailout;
  54333. X    long calctime;
  54334. X    BYTE trigndx[4];      /* which trig functions selected */
  54335. X    short finattract;
  54336. X    double initorbit[2];  /* init Mandelbrot orbit values */
  54337. X    short periodicity;      /* periodicity checking */
  54338. X            /* version 5 stuff, release 15 */
  54339. X    short pot16bit;      /* save 16 bit continuous potential info */
  54340. X    float faspectratio;   /* finalaspectratio, y/x */
  54341. X    short system;       /* 0 for dos, 1 for windows */
  54342. X    short release;      /* release number, with 2 decimals implied */
  54343. X    short flag3d;       /* stored only for now, for future use */
  54344. X    short transparent[2];
  54345. X    short ambient;
  54346. X    short haze;
  54347. X    short randomize;
  54348. X            /* version 6 stuff, release 15.x */
  54349. X    short rotate_lo;
  54350. X    short rotate_hi;
  54351. X    short distestwidth;
  54352. X            /* version 7 stuff, release 16 */
  54353. X    double dparm3;
  54354. X    double dparm4;
  54355. X            /* version 8 stuff, release 17 */
  54356. X    short fillcolor;
  54357. X            /* version 9 stuff, release 18 */
  54358. X    double mxmaxfp;
  54359. X    double mxminfp;
  54360. X    double mymaxfp;
  54361. X    double myminfp;
  54362. X    short zdots;
  54363. X    float originfp;
  54364. X    float depthfp;
  54365. X    float heightfp;
  54366. X    float widthfp;
  54367. X    float distfp;
  54368. X    float eyesfp;
  54369. X    short orbittype;
  54370. X    short juli3Dmode;
  54371. X    short maxfn;
  54372. X    short inversejulia;
  54373. X    double dparm5;
  54374. X    double dparm6;
  54375. X    double dparm7;
  54376. X    double dparm8;
  54377. X    double dparm9;
  54378. X    double dparm10;
  54379. X    short future[50];      /* for stuff we haven't thought of yet */
  54380. X};
  54381. X
  54382. X
  54383. X
  54384. X#define MAXVIDEOMODES 300    /* maximum entries in fractint.cfg      */
  54385. X#ifndef XFRACT
  54386. X#define MAXVIDEOTABLE 40        /* size of the resident video modes table */
  54387. X#else
  54388. X#define MAXVIDEOTABLE 2         /* size of the resident video modes table */
  54389. X#endif
  54390. X
  54391. X#define AUTOINVERT -123456.789
  54392. X
  54393. X#define N_ATTR 8            /* max number of attractors    */
  54394. X
  54395. Xextern    long     l_at_rad;    /* finite attractor radius  */
  54396. Xextern    double     f_at_rad;    /* finite attractor radius  */
  54397. X
  54398. X#define NUMIFS      64     /* number of ifs functions in ifs array */
  54399. X#define IFSPARM    7     /* number of ifs parameters */
  54400. X#define IFS3DPARM 13     /* number of ifs 3D parameters */
  54401. X
  54402. X#define ITEMNAMELEN 18     /* max length of names in .frm/.l/.ifs/.fc */
  54403. X
  54404. Xstruct moreparams
  54405. X{
  54406. X   int      type;                        /* index in fractalname of the fractal */
  54407. X   char     *param[MAXPARAMS-4];    /* name of the parameters */
  54408. X   double   paramvalue[MAXPARAMS-4];     /* default parameter values */
  54409. X};
  54410. X
  54411. Xstruct fractalspecificstuff
  54412. X{
  54413. X   char  *name;             /* name of the fractal */
  54414. X                    /* (leading "*" supresses name display) */ 
  54415. X   char  *param[4];            /* name of the parameters */
  54416. X   double paramvalue[4];         /* default parameter values */
  54417. X   int     helptext;            /* helpdefs.h HT_xxxx, -1 for none */
  54418. X   int     helpformula;            /* helpdefs.h HF_xxxx, -1 for none */
  54419. X   int     flags;             /* constraints, bits defined below */
  54420. X   float xmin;                /* default XMIN corner */
  54421. X   float xmax;                /* default XMAX corner */
  54422. X   float ymin;                /* default YMIN corner */
  54423. X   float ymax;                /* default YMAX corner */
  54424. X   int     isinteger;            /* 1 if integerfractal, 0 otherwise */
  54425. X   int     tojulia;            /* mandel-to-julia switch */
  54426. X   int     tomandel;            /* julia-to-mandel switch */
  54427. X   int     tofloat;            /* integer-to-floating switch */
  54428. X   int     symmetry;            /* applicable symmetry logic
  54429. X                       0 = no symmetry
  54430. X                      -1 = y-axis symmetry (If No Params)
  54431. X                       1 = y-axis symmetry
  54432. X                      -2 = x-axis symmetry (No Parms)
  54433. X                       2 = x-axis symmetry
  54434. X                      -3 = y-axis AND x-axis (No Parms)
  54435. X                       3 = y-axis AND x-axis symmetry
  54436. X                      -4 = polar symmetry (No Parms)
  54437. X                       4 = polar symmetry
  54438. X                       5 = PI (sin/cos) symmetry
  54439. X                       6 = NEWTON (power) symmetry
  54440. X                                */
  54441. X   int (*orbitcalc)();        /* function that calculates one orbit */
  54442. X   int (*per_pixel)();        /* once-per-pixel init */
  54443. X   int (*per_image)();        /* once-per-image setup */
  54444. X   int (*calctype)();        /* name of main fractal function */
  54445. X   int orbit_bailout;        /* usual bailout value for orbit calc */
  54446. X};
  54447. X
  54448. X/* defines for symmetry */
  54449. X#define  NOSYM        0
  54450. X#define  XAXIS_NOPARM  -1
  54451. X#define  XAXIS        1
  54452. X#define  YAXIS_NOPARM  -2
  54453. X#define  YAXIS        2
  54454. X#define  XYAXIS_NOPARM -3
  54455. X#define  XYAXIS     3
  54456. X#define  ORIGIN_NOPARM -4
  54457. X#define  ORIGIN     4
  54458. X#define  PI_SYM_NOPARM -5
  54459. X#define  PI_SYM     5
  54460. X#define  XAXIS_NOIMAG  -6
  54461. X#define  XAXIS_NOREAL    6
  54462. X#define  NOPLOT        99
  54463. X#define  SETUP_SYM    100
  54464. X
  54465. X/* defines for inside/outside */
  54466. X#define ITER        -1
  54467. X#define REAL        -2
  54468. X#define IMAG        -3
  54469. X#define MULT        -4
  54470. X#define SUM         -5
  54471. X#define ZMAG       -59
  54472. X#define BOF60      -60
  54473. X#define BOF61      -61
  54474. X#define EPSCROSS  -100
  54475. X#define STARTRAIL -101
  54476. X#define PERIOD    -102
  54477. X
  54478. X/* bitmask defines for fractalspecific flags */
  54479. X#define  NOZOOM     1    /* zoombox not allowed at all       */
  54480. X#define  NOGUESS    2    /* solid guessing not allowed       */
  54481. X#define  NOTRACE    4    /* boundary tracing not allowed       */
  54482. X#define  NOROTATE    8    /* zoombox rotate/stretch not allowed */
  54483. X#define  NORESUME      16    /* can't interrupt and resume         */
  54484. X#define  INFCALC       32    /* this type calculates forever       */
  54485. X#define  TRIG1           64    /* number of trig functions in formula*/
  54486. X#define  TRIG2          128
  54487. X#define  TRIG3          192
  54488. X#define  TRIG4          256
  54489. X#define  WINFRAC      512    /* supported in WinFrac           */
  54490. X#define  PARMS3D     1024    /* uses 3d parameters           */
  54491. X#define  OKJB        2048    /* works with Julibrot */
  54492. X#define  MORE        4096    /* more than 4 parms */
  54493. X
  54494. Xextern struct fractalspecificstuff far fractalspecific[];
  54495. Xextern struct fractalspecificstuff far *curfractalspecific;
  54496. X
  54497. X#define DEFAULTFRACTALTYPE    ".gif"
  54498. X#define ALTERNATEFRACTALTYPE    ".fra"
  54499. X
  54500. X#ifndef _CMPLX_DEFINED
  54501. X#define _CMPLX_DEFINED
  54502. X
  54503. Xstruct DHyperComplex {
  54504. X    double x,y;
  54505. X    double z,t;  
  54506. X};
  54507. X
  54508. Xstruct LHyperComplex {
  54509. X    long x,y;
  54510. X    long z,t; 
  54511. X};
  54512. X
  54513. Xstruct DComplex {
  54514. X    double x,y;
  54515. X};
  54516. X
  54517. Xstruct LComplex {
  54518. X    long x,y;
  54519. X};
  54520. X
  54521. Xtypedef struct  DComplex         _CMPLX;
  54522. Xtypedef struct  LComplex         _LCMPLX;
  54523. Xtypedef struct  DHyperComplex    _HCMPLX;
  54524. Xtypedef struct  LHyperComplex    _LHCMPLX;
  54525. X#endif
  54526. X
  54527. X#ifndef sqr
  54528. X#define sqr(x) ((x)*(x))
  54529. X#endif
  54530. X
  54531. X#ifndef lsqr
  54532. X#define lsqr(x) (multiply((x),(x),bitshift))
  54533. X#endif
  54534. X
  54535. X#define CMPLXmod(z)      (sqr((z).x)+sqr((z).y))
  54536. X#define CMPLXconj(z)    ((z).y =  -((z).y))
  54537. X#define LCMPLXmod(z)       (lsqr((z).x)+lsqr((z).y))
  54538. X#define LCMPLXconj(z)    ((z).y =  -((z).y))
  54539. X
  54540. Xtypedef  _LCMPLX LCMPLX;
  54541. X
  54542. X/* 3D stuff - formerly in 3d.h */
  54543. X#ifndef dot_product
  54544. X#define dot_product(v1,v2)  ((v1)[0]*(v2)[0]+(v1)[1]*(v2)[1]+(v1)[2]*(v2)[2])  /* TW 7-09-89 */
  54545. X#endif
  54546. X
  54547. X#define    CMAX    4   /* maximum column (4 x 4 matrix) */
  54548. X#define    RMAX    4   /* maximum row     (4 x 4 matrix) */
  54549. X#define    DIM       3   /* number of dimensions */
  54550. X
  54551. Xtypedef double MATRIX [RMAX] [CMAX];  /* matrix of doubles */
  54552. Xtypedef int   IMATRIX [RMAX] [CMAX];  /* matrix of ints    */
  54553. Xtypedef long  LMATRIX [RMAX] [CMAX];  /* matrix of longs   */
  54554. X
  54555. X/* A MATRIX is used to describe a transformation from one coordinate
  54556. Xsystem to another.  Multiple transformations may be concatenated by
  54557. Xmultiplying their transformation matrices. */
  54558. X
  54559. Xtypedef double VECTOR [DIM];  /* vector of doubles */
  54560. Xtypedef int   IVECTOR [DIM];  /* vector of ints    */
  54561. Xtypedef long  LVECTOR [DIM];  /* vector of longs   */
  54562. X
  54563. X/* A VECTOR is an array of three coordinates [x,y,z] representing magnitude
  54564. Xand direction. A fourth dimension is assumed to always have the value 1, but
  54565. Xis not in the data structure */
  54566. X
  54567. X
  54568. X#define PI 3.14159265358979323846
  54569. X
  54570. X#define SPHERE      init3d[0]        /* sphere? 1 = yes, 0 = no  */
  54571. X#define ILLUMINE  (FILLTYPE>4)    /* illumination model        */
  54572. X
  54573. X/* regular 3D */
  54574. X#define XROT      init3d[1]    /* rotate x-axis 60 degrees */
  54575. X#define YROT      init3d[2]    /* rotate y-axis 90 degrees */
  54576. X#define ZROT      init3d[3]    /* rotate x-axis  0 degrees */
  54577. X#define XSCALE      init3d[4]    /* scale x-axis, 90 percent */
  54578. X#define YSCALE      init3d[5]    /* scale y-axis, 90 percent */
  54579. X
  54580. X/* sphere 3D */
  54581. X#define PHI1      init3d[1]    /* longitude start, 180     */
  54582. X#define PHI2      init3d[2]    /* longitude end ,   0        */
  54583. X#define THETA1      init3d[3]        /* latitude start,-90 degrees */
  54584. X#define THETA2      init3d[4]        /* latitude stop,  90 degrees */
  54585. X#define RADIUS      init3d[5]    /* should be user input */
  54586. X
  54587. X/* common parameters */
  54588. X#define ROUGH      init3d[6]    /* scale z-axis, 30 percent */
  54589. X#define WATERLINE init3d[7]    /* water level            */
  54590. X#define FILLTYPE  init3d[8]    /* fill type            */
  54591. X#define ZVIEWER   init3d[9]    /* perspective view point   */
  54592. X#define XSHIFT      init3d[10]    /* x shift */
  54593. X#define YSHIFT      init3d[11]    /* y shift */
  54594. X#define XLIGHT      init3d[12]    /* x light vector coordinate */
  54595. X#define YLIGHT      init3d[13]    /* y light vector coordinate */
  54596. X#define ZLIGHT      init3d[14]    /* z light vector coordinate */
  54597. X#define LIGHTAVG  init3d[15]    /* number of points to average */
  54598. X
  54599. X#ifndef TRUE
  54600. X#define TRUE 1
  54601. X#define FALSE 0
  54602. X#endif
  54603. X
  54604. X/* Math definitions (normally in float.h) that are missing on some systems. */
  54605. X#ifndef FLT_MIN
  54606. X#define FLT_MIN 1.17549435e-38
  54607. X#endif
  54608. X#ifndef FLT_MAX
  54609. X#define FLT_MAX 3.40282347e+38
  54610. X#endif
  54611. X#ifndef DBL_EPSILON
  54612. X#define DBL_EPSILON 2.2204460492503131e-16
  54613. X#endif
  54614. X
  54615. X#ifndef XFRACT
  54616. X#define UPARR "\x18"
  54617. X#define DNARR "\x19"
  54618. X#define RTARR "\x1A"
  54619. X#define LTARR "\x1B"
  54620. X#else
  54621. X#define UPARR "K"
  54622. X#define DNARR "J"
  54623. X#define RTARR "L"
  54624. X#define LTARR "H"
  54625. X#endif
  54626. X
  54627. X#define JIIM  0
  54628. X#define ORBIT 1
  54629. X
  54630. Xstruct workliststuff    /* work list entry for std escape time engines */
  54631. X{
  54632. X    int xxstart;    /* screen window for this entry */
  54633. X    int xxstop;
  54634. X    int yystart;
  54635. X    int yystop;
  54636. X    int yybegin;    /* start row within window, for 2pass/ssg resume */
  54637. X    int sym;    /* if symmetry in window, prevents bad combines */
  54638. X    int pass;    /* for 2pass and solid guessing */
  54639. X};
  54640. X#define MAXCALCWORK 12
  54641. X
  54642. Xextern BYTE trigndx[];
  54643. Xextern void (*ltrig0)(void), (*ltrig1)(void), (*ltrig2)(void), (*ltrig3)(void);
  54644. Xextern void (*dtrig0)(void), (*dtrig1)(void), (*dtrig2)(void), (*dtrig3)(void);
  54645. X
  54646. Xstruct trig_funct_lst
  54647. X{
  54648. X    char *name;
  54649. X    void (*lfunct)(void);
  54650. X    void (*dfunct)(void);
  54651. X    void (*mfunct)(void);
  54652. X} ;
  54653. Xextern struct trig_funct_lst trigfn[];
  54654. X
  54655. X/* function prototypes */
  54656. X
  54657. Xextern    void   (_fastcall *plot)(int, int, int);
  54658. X
  54659. X/* for overlay return stack */
  54660. X
  54661. X#define ENTER_OVLY(ovlyid)\
  54662. X   extern int active_ovly;\
  54663. X   int prev_ovly;\
  54664. X   prev_ovly = active_ovly;\
  54665. X   active_ovly = ovlyid
  54666. X#define EXIT_OVLY active_ovly = prev_ovly
  54667. X
  54668. X#define BIG 100000.0
  54669. X
  54670. X#define OVLY_MISCOVL   1
  54671. X#define OVLY_CMDFILES  2
  54672. X#define OVLY_HELP      3
  54673. X#define OVLY_PROMPTS1  4
  54674. X#define OVLY_PROMPTS2  5
  54675. X#define OVLY_LOADFILE  6
  54676. X#define OVLY_ROTATE    7
  54677. X#define OVLY_PRINTER   8
  54678. X#define OVLY_LINE3D    9
  54679. X#define OVLY_ENCODER  10
  54680. X#define OVLY_CALCFRAC 11
  54681. X#define OVLY_INTRO    12
  54682. X#define OVLY_DECODER  13
  54683. X
  54684. X
  54685. X#define CTL(x) ((x)&0x1f)
  54686. X
  54687. X/* nonalpha tests if we have a control character */
  54688. X#define nonalpha(c) ((c)<32 || (c)>127)
  54689. X
  54690. X/* keys */
  54691. X#define   INSERT     1082
  54692. X#define   DELETE     1083
  54693. X#define   PAGE_UP     1073
  54694. X#define   PAGE_DOWN     1081
  54695. X#define   CTL_HOME     1119
  54696. X#define   CTL_END     1117
  54697. X#define   LEFT_ARROW     1075
  54698. X#define   RIGHT_ARROW     1077
  54699. X#define   UP_ARROW     1072
  54700. X#define   DOWN_ARROW     1080
  54701. X#define   LEFT_ARROW_2     1115
  54702. X#define   RIGHT_ARROW_2  1116
  54703. X#define   UP_ARROW_2     1141
  54704. X#define   DOWN_ARROW_2     1145
  54705. X#define   HOME         1071
  54706. X#define   END         1079
  54707. X#define   ENTER      13
  54708. X#define   ENTER_2     1013
  54709. X#define   CTL_ENTER      10
  54710. X#define   CTL_ENTER_2    1010
  54711. X#define   CTL_PAGE_UP    1132
  54712. X#define   CTL_PAGE_DOWN  1118
  54713. X#define   CTL_MINUS      1142
  54714. X#define   CTL_PLUS       1144
  54715. X#define   CTL_INSERT     1146
  54716. X#define   CTL_DEL        1147
  54717. X#define   F1         1059
  54718. X#define   F2         1060
  54719. X#define   F3         1061
  54720. X#define   F4         1062
  54721. X#define   F5         1063
  54722. X#define   F6         1064
  54723. X#define   F7         1065
  54724. X#define   F8         1066
  54725. X#define   F9         1067
  54726. X#define   F10         1068
  54727. X#define   TAB            9
  54728. X#define   ESC            27
  54729. X#define   SPACE          32
  54730. X#define   SF1            1084
  54731. X#define   SF2            1085
  54732. X#define   SF3            1086
  54733. X#define   SF4            1087
  54734. X#define   SF5            1088
  54735. X#define   SF6            1089
  54736. X#define   SF7            1090
  54737. X#define   SF8            1091
  54738. X#define   SF9            1092
  54739. X#define   SF10           1093
  54740. X/* text colors */
  54741. X#define BLACK       0
  54742. X#define BLUE       1
  54743. X#define GREEN       2
  54744. X#define CYAN       3
  54745. X#define RED       4
  54746. X#define MAGENTA    5
  54747. X#define BROWN       6 /* dirty yellow on cga */
  54748. X#define WHITE       7
  54749. X/* use values below this for foreground only, they don't work background */
  54750. X#define GRAY       8 /* don't use this much - is black on cga */
  54751. X#define L_BLUE       9
  54752. X#define L_GREEN   10
  54753. X#define L_CYAN      11
  54754. X#define L_RED      12
  54755. X#define L_MAGENTA 13
  54756. X#define YELLOW      14
  54757. X#define L_WHITE   15
  54758. X#define INVERSE 0x8000 /* when 640x200x2 text or mode 7, inverse */
  54759. X#define BRIGHT    0x4000 /* when mode 7, bright */
  54760. X/* and their use: */
  54761. Xextern BYTE txtcolor[];
  54762. X#define C_TITLE       txtcolor[0]+BRIGHT
  54763. X#define C_TITLE_DEV      txtcolor[1]
  54764. X#define C_HELP_HDG      txtcolor[2]+BRIGHT
  54765. X#define C_HELP_BODY      txtcolor[3]
  54766. X#define C_HELP_INSTR      txtcolor[4]
  54767. X#define C_HELP_LINK      txtcolor[5]+BRIGHT
  54768. X#define C_HELP_CURLINK      txtcolor[6]+INVERSE
  54769. X#define C_PROMPT_BKGRD      txtcolor[7]
  54770. X#define C_PROMPT_TEXT      txtcolor[8]
  54771. X#define C_PROMPT_LO      txtcolor[9]
  54772. X#define C_PROMPT_MED      txtcolor[10]
  54773. X#ifndef XFRACT
  54774. X#define C_PROMPT_HI      txtcolor[11]+BRIGHT
  54775. X#else
  54776. X#define C_PROMPT_HI      txtcolor[11]
  54777. X#endif
  54778. X#define C_PROMPT_INPUT      txtcolor[12]+INVERSE
  54779. X#define C_PROMPT_CHOOSE   txtcolor[13]+INVERSE
  54780. X#define C_CHOICE_CURRENT  txtcolor[14]+INVERSE
  54781. X#define C_CHOICE_SP_INSTR txtcolor[15]
  54782. X#define C_CHOICE_SP_KEYIN txtcolor[16]+BRIGHT
  54783. X#define C_GENERAL_HI      txtcolor[17]+BRIGHT
  54784. X#define C_GENERAL_MED      txtcolor[18]
  54785. X#define C_GENERAL_LO      txtcolor[19]
  54786. X#define C_GENERAL_INPUT   txtcolor[20]+INVERSE
  54787. X#define C_DVID_BKGRD      txtcolor[21]
  54788. X#define C_DVID_HI      txtcolor[22]+BRIGHT
  54789. X#define C_DVID_LO      txtcolor[23]
  54790. X#define C_STOP_ERR      txtcolor[24]+BRIGHT
  54791. X#define C_STOP_INFO      txtcolor[25]+BRIGHT
  54792. X#define C_TITLE_LOW      txtcolor[26]
  54793. X#define C_AUTHDIV1      txtcolor[27]+INVERSE
  54794. X#define C_AUTHDIV2      txtcolor[28]+INVERSE
  54795. X#define C_PRIMARY      txtcolor[29]
  54796. X#define C_CONTRIB      txtcolor[30]
  54797. X
  54798. X/* structure for xmmmoveextended parameter */
  54799. Xstruct XMM_Move
  54800. X  {
  54801. X    unsigned long   Length;
  54802. X    unsigned int    SourceHandle;
  54803. X    unsigned long   SourceOffset;
  54804. X    unsigned int    DestHandle;
  54805. X    unsigned long   DestOffset;
  54806. X  };
  54807. X
  54808. X/* structure passed to fullscreen_prompts */
  54809. Xstruct fullscreenvalues
  54810. X{
  54811. X   int type;   /* 'd' for double, 'f' for float, 's' for string,   */
  54812. X           /* 'D' for integer in double, '*' for comment */
  54813. X           /* 'i' for integer, 'y' for yes=1 no=0              */
  54814. X           /* 0x100+n for string of length n           */
  54815. X           /* 'l' for one of a list of strings                 */
  54816. X   union
  54817. X   {
  54818. X      double dval;    /* when type 'd' or 'f'  */
  54819. X      int    ival;    /* when type is 'i'      */
  54820. X      char   sval[16];    /* when type is 's'      */
  54821. X      char  *sbuf;    /* when type is 0x100+n  */
  54822. X      struct {        /* when type is 'l'      */
  54823. X     int  val;    /*   selected choice     */
  54824. X     int  vlen;    /*   char len per choice */
  54825. X     char **list;    /*   list of values     */
  54826. X     int  llen;    /*   number of values     */
  54827. X      } ch;
  54828. X   } uval;
  54829. X};
  54830. X#endif
  54831. SHAR_EOF
  54832. $TOUCH -am 1028230093 fractint.h &&
  54833. chmod 0644 fractint.h ||
  54834. echo "restore of fractint.h failed"
  54835. set `wc -c fractint.h`;Wc_c=$1
  54836. if test "$Wc_c" != "19765"; then
  54837.     echo original size 19765, current size $Wc_c
  54838. fi
  54839. # ============= fractype.h ==============
  54840. echo "x - extracting fractype.h (Text)"
  54841. sed 's/^X//' << 'SHAR_EOF' > fractype.h &&
  54842. X#ifndef FRACTYPE_H
  54843. X#define FRACTYPE_H
  54844. X
  54845. X#define SIN        0
  54846. X#define COS        1
  54847. X#define SINH        2
  54848. X#define COSH        3
  54849. X#define EXP        4
  54850. X#define LOG        5
  54851. X#define SQR        6
  54852. X
  54853. X/* These MUST match the corresponding fractalspecific record in fractals.c */
  54854. X#define NOFRACTAL        -1
  54855. X#define MANDEL             0
  54856. X#define JULIA             1
  54857. X#define NEWTBASIN         2
  54858. X#define LAMBDA             3
  54859. X#define MANDELFP         4
  54860. X#define NEWTON             5
  54861. X#define JULIAFP          6
  54862. X#define PLASMA             7
  54863. X#define LAMBDASINE         8 /* obsolete */
  54864. X#define MANDELTRIGFP         8
  54865. X#define LAMBDACOS         9 /* obsolete */
  54866. X#define MANOWARFP         9
  54867. X#define LAMBDAEXP        10 /* obsolete */
  54868. X#define MANOWAR         10
  54869. X#define TEST            11
  54870. X#define SIERPINSKI        12
  54871. X#define BARNSLEYM1        13
  54872. X#define BARNSLEYJ1        14
  54873. X#define BARNSLEYM2        15
  54874. X#define BARNSLEYJ2        16
  54875. X#define MANDELSINE        17 /* obsolete */
  54876. X#define SQRTRIG         17
  54877. X#define MANDELCOS        18 /* obsolete */
  54878. X#define SQRTRIGFP        18
  54879. X#define MANDELEXP        19 /* obsolete */
  54880. X#define TRIGPLUSTRIG        19
  54881. X#define MANDELLAMBDA        20
  54882. X#define MARKSMANDEL        21
  54883. X#define MARKSJULIA        22
  54884. X#define UNITY            23
  54885. X#define MANDEL4         24
  54886. X#define JULIA4            25
  54887. X#define IFS            26
  54888. X#define IFS3D            27
  54889. X#define BARNSLEYM3        28
  54890. X#define BARNSLEYJ3        29
  54891. X#define DEMM            30 /* obsolete */
  54892. X#define TRIGSQR         30
  54893. X#define DEMJ            31 /* obsolete */
  54894. X#define TRIGSQRFP        31
  54895. X#define BIFURCATION        32
  54896. X#define MANDELSINH        33 /* obsolete */
  54897. X#define TRIGPLUSTRIGFP        33
  54898. X#define LAMBDASINH        34 /* obsolete */
  54899. X#define TRIGXTRIG        34
  54900. X#define MANDELCOSH        35 /* obsolete */
  54901. X#define TRIGXTRIGFP        35
  54902. X#define LAMBDACOSH        36 /* obsolete */
  54903. X#define SQR1OVERTRIG        36
  54904. X#define LMANDELSINE        37 /* obsolete */
  54905. X#define SQR1OVERTRIGFP        37
  54906. X#define LLAMBDASINE        38 /* obsolete */
  54907. X#define ZXTRIGPLUSZ        38
  54908. X#define LMANDELCOS        39 /* obsolete */
  54909. X#define ZXTRIGPLUSZFP        39
  54910. X#define LLAMBDACOS        40 /* obsolete */
  54911. X#define KAMFP            40
  54912. X#define LMANDELSINH        41 /* obsolete */
  54913. X#define KAM            41
  54914. X#define LLAMBDASINH        42 /* obsolete */
  54915. X#define KAM3DFP         42
  54916. X#define LMANDELCOSH        43 /* obsolete */
  54917. X#define KAM3D            43
  54918. X#define LLAMBDACOSH        44 /* obsolete */
  54919. X#define LAMBDATRIG        44
  54920. X#define LMANTRIGPLUSZSQRD    45
  54921. X#define LJULTRIGPLUSZSQRD    46
  54922. X#define FPMANTRIGPLUSZSQRD    47
  54923. X#define FPJULTRIGPLUSZSQRD    48
  54924. X#define LMANDELEXP        49 /* obsolete */
  54925. X#define LAMBDATRIGFP        49
  54926. X#define LLAMBDAEXP        50 /* obsolete */
  54927. X#define MANDELTRIG        50
  54928. X#define LMANDELZPOWER        51
  54929. X#define LJULIAZPOWER        52
  54930. X#define FPMANDELZPOWER        53
  54931. X#define FPJULIAZPOWER        54
  54932. X#define FPMANZTOZPLUSZPWR    55
  54933. X#define FPJULZTOZPLUSZPWR    56
  54934. X#define LMANTRIGPLUSEXP     57
  54935. X#define LJULTRIGPLUSEXP     58
  54936. X#define FPMANTRIGPLUSEXP    59
  54937. X#define FPJULTRIGPLUSEXP    60
  54938. X#define FPPOPCORN        61
  54939. X#define LPOPCORN        62
  54940. X#define FPLORENZ        63
  54941. X#define LLORENZ         64
  54942. X#define LLORENZ3D        65
  54943. X#define MPNEWTON        66
  54944. X#define MPNEWTBASIN        67
  54945. X#define COMPLEXNEWTON        68
  54946. X#define COMPLEXBASIN        69
  54947. X#define COMPLEXMARKSMAND    70
  54948. X#define COMPLEXMARKSJUL     71
  54949. X#define FORMULA         72
  54950. X#define FFORMULA        73
  54951. X#define SIERPINSKIFP        74
  54952. X#define LAMBDAFP        75
  54953. X#define BARNSLEYM1FP        76
  54954. X#define BARNSLEYJ1FP        77
  54955. X#define BARNSLEYM2FP        78
  54956. X#define BARNSLEYJ2FP        79
  54957. X#define BARNSLEYM3FP        80
  54958. X#define BARNSLEYJ3FP        81
  54959. X#define MANDELLAMBDAFP        82
  54960. X#define JULIBROT        83
  54961. X#define FPLORENZ3D        84
  54962. X#define LROSSLER        85
  54963. X#define FPROSSLER        86
  54964. X#define LHENON            87
  54965. X#define FPHENON         88
  54966. X#define FPPICKOVER        89
  54967. X#define FPGINGERBREAD        90
  54968. X#define DIFFUSION        91
  54969. X#define UNITYFP         92
  54970. X#define SPIDERFP        93
  54971. X#define SPIDER            94
  54972. X#define TETRATEFP        95
  54973. X#define MAGNET1M        96
  54974. X#define MAGNET1J        97
  54975. X#define MAGNET2M        98
  54976. X#define MAGNET2J        99
  54977. X#define LBIFURCATION           100
  54978. X#define LBIFLAMBDA           101
  54979. X#define BIFLAMBDA           102
  54980. X#define BIFADSINPI           103
  54981. X#define BIFEQSINPI           104
  54982. X#define FPPOPCORNJUL           105
  54983. X#define LPOPCORNJUL           106
  54984. X#define LSYSTEM            107
  54985. X#define MANOWARJFP           108
  54986. X#define MANOWARJ           109
  54987. X#define FNPLUSFNPIXFP           110
  54988. X#define FNPLUSFNPIXLONG        111
  54989. X#define MARKSMANDELPWRFP       112
  54990. X#define MARKSMANDELPWR           113
  54991. X#define TIMSERRORFP           114
  54992. X#define TIMSERROR           115
  54993. X#define LBIFEQSINPI           116
  54994. X#define LBIFADSINPI           117
  54995. X#define BIFSTEWART             118
  54996. X#define LBIFSTEWART            119
  54997. X#define FPHOPALONG             120
  54998. X#define FPCIRCLE               121
  54999. X#define FPMARTIN               122
  55000. X#define LYAPUNOV               123
  55001. X#define FPLORENZ3D1            124
  55002. X#define FPLORENZ3D3            125
  55003. X#define FPLORENZ3D4            126
  55004. X#define LLAMBDAFNFN            127
  55005. X#define FPLAMBDAFNFN           128
  55006. X#define LJULFNFN               129
  55007. X#define FPJULFNFN              130
  55008. X#define LMANLAMFNFN            131
  55009. X#define FPMANLAMFNFN           132
  55010. X#define LMANFNFN               133
  55011. X#define FPMANFNFN              134
  55012. X#define LBIFMAY                135
  55013. X#define BIFMAY                 136
  55014. X#define MPHALLEY               137
  55015. X#define HALLEY                 138
  55016. X#define DYNAMICFP              139
  55017. X#define QUATFP                 140
  55018. X#define QUATJULFP              141
  55019. X#define CELLULAR               142
  55020. X#define JULIBROTFP             143
  55021. X#define INVERSEJULIA           144
  55022. X#define INVERSEJULIAFP         145
  55023. X#define MANDELCLOUD            146
  55024. X#define PHOENIX                147
  55025. X#define PHOENIXFP              148
  55026. X#define MANDPHOENIX            149
  55027. X#define MANDPHOENIXFP          150
  55028. X#define HYPERCMPLXFP           151    
  55029. X#define HYPERCMPLXJFP           152
  55030. X#define FROTH                  153
  55031. X#define FROTHFP                154
  55032. X#define MANDEL4FP              155
  55033. X#define JULIA4FP               156
  55034. X#define MARKSMANDELFP          157
  55035. X#define MARKSJULIAFP           158
  55036. X#define ICON                   159
  55037. X#define ICON3D                 160
  55038. X
  55039. X/* demonstration Mandelbrot and Julia fractals
  55040. X
  55041. X#define DEMOWALK            161
  55042. X#define DEMOMANDEL          162
  55043. X#define DEMOJULIA           163
  55044. X#define DEMOMANDELFP        164
  55045. X#define DEMOJULIAFP         165
  55046. X
  55047. X*/
  55048. X
  55049. X
  55050. X#endif
  55051. SHAR_EOF
  55052. $TOUCH -am 1028230093 fractype.h &&
  55053. chmod 0644 fractype.h ||
  55054. echo "restore of fractype.h failed"
  55055. set `wc -c fractype.h`;Wc_c=$1
  55056. if test "$Wc_c" != "5675"; then
  55057.     echo original size 5675, current size $Wc_c
  55058. fi
  55059. # ============= fmath.h ==============
  55060. echo "x - extracting fmath.h (Text)"
  55061. sed 's/^X//' << 'SHAR_EOF' > fmath.h &&
  55062. X#ifndef FMATH_H
  55063. X#define FMATH_H
  55064. X
  55065. X/* FMath.h (C) 1989, Mark C. Peterson, CompuServe [70441,3353]
  55066. X     All rights reserved.
  55067. X
  55068. X   Code may be used in any program provided the author is credited
  55069. X     either during program execution or in the documentation.  Source
  55070. X     code may be distributed only in combination with public domain or
  55071. X     shareware source code.  Source code may be modified provided the
  55072. X     copyright notice and this message is left unchanged and all
  55073. X     modifications are clearly documented.
  55074. X
  55075. X     I would appreciate a copy of any work which incorporates this code,
  55076. X     however this is optional.
  55077. X
  55078. X     Mark C. Peterson
  55079. X     128 Hamden Ave., F
  55080. X     Waterbury, CT 06704
  55081. X     (203) 754-1162
  55082. X     
  55083. X     Notes below document changes to Mark's original file:
  55084. X     
  55085. X     Date       Change                                    Changer
  55086. X     ============================================================
  55087. X     07-16-89 - Added sqrt define per Mark's suggestion   TIW
  55088. X     07-26-89 - Added documentation and complex support   MCP
  55089. X*/
  55090. X
  55091. X/*****************
  55092. X * Documentation *
  55093. X *****************
  55094. X
  55095. X   #include "fmath.h"
  55096. X   float x, y, z;
  55097. X   int Pot, Fudge;
  55098. X
  55099. X                   23-bit accuracy (limit of type float)
  55100. X     Regular Implementation               Fast Math Implementation
  55101. X -------------------------------------------------------------------- 
  55102. X         z = x + y;                          fAdd(x, y, z);
  55103. X         z = x * y;                          fMul(x, y, z);
  55104. X         z = x * x;                          fSqr(x, z);
  55105. X         z = x / y;                          fDiv(x, y, z);
  55106. X         z = x * 2;                          fShift(x, 1, z);
  55107. X         z = x * 16;                         fShift(x, 4, z);
  55108. X         z = x / 32;                         fShift(x, -5, z);
  55109. X         z = x / (pow(2.0, (double)Pot));    fShift(x, -Pot, z);
  55110. X         z = (float)Pot * (1L << Fudge);     Fg2Float(Pot, Fudge, z);
  55111. X         Pot = (int)(z / (1L << Fudge));     Pot = Float2Fg(z, Fudge);
  55112. X
  55113. X                  Complex numbers using fComplex structures
  55114. X         z = x**2                            fSqrZ(&x, &z);      mod updated
  55115. X         z.mod = (z.x*z.x)+(z.y*z.y)         fModZ(&z);          mod updated
  55116. X         z = 1 / x                           fInvZ(&x, &z);      mod updated
  55117. X         z = x * y                           fMulZ(&x, &y, &z);  mod updated
  55118. X         z = x / y                           fDivZ(&x, &y, &z);  mod updated
  55119. X
  55120. X                            16-bit accuracy
  55121. X     Regular Implementation               Fast Math Implementation
  55122. X -------------------------------------------------------------------- 
  55123. X         z = x * y;                          fMul16(x, y, z);
  55124. X         z = x * x;                          fSqr16(x, z);
  55125. X
  55126. X                            14-bit accuracy
  55127. X     Regular Implementation               Fast Math Implementation
  55128. X -------------------------------------------------------------------- 
  55129. X         z = log(x);                         fLog14(x, z);
  55130. X         z = exp(x);                         fExp14(x, z);
  55131. X         z = pow(x, y);                      fPow14(x, y, z);
  55132. X
  55133. X                            12-bit accuracy
  55134. X     Regular Implementation               Fast Math Implementation
  55135. X -------------------------------------------------------------------- 
  55136. X         z = sin(x);                         fSin12(x, z);
  55137. X         z = cos(x);                         fCos12(x, z);
  55138. X         z = sinh(x);                        fSinh12(x, z);
  55139. X         z = cosh(x);                        fCosh12(x, z);
  55140. X
  55141. X                  Complex numbers using fComplex structures
  55142. X         z = sin(x)                          fSinZ(&x, &z);
  55143. X         z = cos(x)                          fCosZ(&x, &z);
  55144. X         z = tan(x)                          fTagZ(&x, &z);
  55145. X         z = sinh(x)                         fSinhZ(&x, &z);
  55146. X         z = cosh(x)                         fCoshZ(&x, &z);
  55147. X         z = tanh(x)                         fCoshZ(&x, &z);
  55148. X
  55149. XJust be sure to declare x, y, and z as type floats instead of type double.
  55150. X*/
  55151. X
  55152. Xlong 
  55153. X#ifndef XFRACT
  55154. X   far RegFg2Float(long x, char FudgeFact),
  55155. X   far RegSftFloat(long x, char Shift),
  55156. X#else
  55157. X   far RegFg2Float(long x, int FudgeFact),
  55158. X   far RegSftFloat(long x, int Shift),
  55159. X#endif
  55160. X   far RegFloat2Fg(long x, int Fudge),
  55161. X   far RegAddFloat(long x, long y),
  55162. X   far RegDivFloat(long x, long y),
  55163. X   far RegMulFloat(long x, long y),
  55164. X   far RegSqrFloat(long x),
  55165. X   far RegSubFloat(long x, long y);
  55166. Xlong
  55167. X   far r16Mul(long x, long y),
  55168. X   far r16Sqr(long x);
  55169. Xint
  55170. X    far sin13(long x),
  55171. X    far cos13(long x),
  55172. X    far FastCosine(int x),
  55173. X    far FastSine(int x);
  55174. Xlong
  55175. X    far FastHypCosine(int x),
  55176. X    far FastHypSine(int x),
  55177. X   far sinh13(long x),
  55178. X   far cosh13(long x);
  55179. Xlong far LogFudged(unsigned long x, int Fudge);
  55180. Xlong far LogFloat14(unsigned long x);
  55181. Xunsigned long far ExpFudged(long x, int Fudge);
  55182. Xlong far ExpFloat14(long x);
  55183. X
  55184. X#define fAdd(x, y, z) (void)((*(long*)&z) = RegAddFloat(*(long*)&x, *(long*)&y))
  55185. X#define fMul(x, y, z) (void)((*(long*)&z) = RegMulFloat(*(long*)&x, *(long*)&y))
  55186. X#define fDiv(x, y, z) (void)((*(long*)&z) = RegDivFloat(*(long*)&x, *(long*)&y))
  55187. X#define fSub(x, y, z) (void)((*(long*)&z) = RegSubFloat(*(long*)&x, *(long*)&y))
  55188. X#define fMul16(x, y, z) (void)((*(long*)&z) = r16Mul(*(long*)&x, *(long*)&y))
  55189. X#define fSqr16(x, z) (void)((*(long*)&z) = r16Sqr(*(long*)&x))
  55190. X#define fSqr(x, z) (void)((*(long*)&z) = RegSqrFloat(*(long*)&x))
  55191. X#define fShift(x, Shift, z) (void)((*(long*)&z) = \
  55192. X   RegSftFloat(*(long*)&x, Shift))
  55193. X#define Fg2Float(x, f, z) (void)((*(long*)&z) = RegFg2Float(x, f))
  55194. X#define Float2Fg(x, f) RegFloat2Fg(*(long*)&x, f)
  55195. X#define fSin12(x, z) (void)((*(long*)&z) = \
  55196. X   RegFg2Float((long)sin13(Float2Fg(x, 13)), 13))
  55197. X#define fCos12(x, z) (void)((*(long*)&z) = \
  55198. X   RegFg2Float((long)cos13(Float2Fg(x, 13)), 13))
  55199. X#define fSinh12(x, z) (void)((*(long*)&z) = \
  55200. X   RegFg2Float(sinh13(Float2Fg(x, 13)), 13))
  55201. X#define fCosh12(x, z) (void)((*(long*)&z) = \
  55202. X   RegFg2Float(cosh13(Float2Fg(x, 13)), 13))
  55203. X#define fLog14(x, z) (void)((*(long*)&z) = \
  55204. X    RegFg2Float(LogFloat14(*(long*)&x), 16))
  55205. X#define fExp14(x, z) (void)((*(long*)&z) = ExpFloat14(*(long*)&x));
  55206. X#define fPow14(x, y, z) fLog14(x, z); fMul16(z, y, z); fExp14(z, z)
  55207. X#define fSqrt14(x, z) fLog14(x, z); fShift(z, -1, z); fExp14(z, z)
  55208. X
  55209. Xstruct fComplex {
  55210. X   float x, y, mod;
  55211. X};
  55212. X
  55213. Xvoid 
  55214. X   fSqrZ(struct fComplex *x, struct fComplex *z),
  55215. X   fMod(struct fComplex *x),
  55216. X   fInvZ(struct fComplex *x, struct fComplex *z),
  55217. X   fMulZ(struct fComplex *x, struct fComplex *y, struct fComplex *z),
  55218. X   fDivZ(struct fComplex *x, struct fComplex *y, struct fComplex *z),
  55219. X   fSinZ(struct fComplex *x, struct fComplex *z),
  55220. X   fCosZ(struct fComplex *x, struct fComplex *z),
  55221. X   fTanZ(struct fComplex *x, struct fComplex *z),
  55222. X   fSinhZ(struct fComplex *x, struct fComplex *z),
  55223. X   fCoshZ(struct fComplex *x, struct fComplex *z),
  55224. X   fTanhZ(struct fComplex *x, struct fComplex *z);
  55225. X
  55226. X#endif
  55227. SHAR_EOF
  55228. $TOUCH -am 1028230093 fmath.h &&
  55229. chmod 0644 fmath.h ||
  55230. echo "restore of fmath.h failed"
  55231. set `wc -c fmath.h`;Wc_c=$1
  55232. if test "$Wc_c" != "6871"; then
  55233.     echo original size 6871, current size $Wc_c
  55234. fi
  55235. # ============= port.h ==============
  55236. echo "x - extracting port.h (Text)"
  55237. sed 's/^X//' << 'SHAR_EOF' > port.h &&
  55238. X/**************************************
  55239. X**
  55240. X** PORT.H : Miscellaneous definitions for portability.    Please add
  55241. X** to this file for any new machines/compilers you may have.
  55242. X**
  55243. X** XFRACT file "SHARED.H" merged into PORT.H on 3/14/92 by --CWM--
  55244. X*/
  55245. X
  55246. X#ifndef PORT_H        /* If this is defined, this file has been    */
  55247. X#define PORT_H         /* included already in this module.        */
  55248. X
  55249. X#ifdef XFRACT        /* XFRACT forces unix configuration! --CWM-- */
  55250. X#ifdef MSDOS
  55251. X#undef MSDOS
  55252. X#endif
  55253. X#ifdef __MSDOS__
  55254. X#undef __MSDOS__
  55255. X#endif
  55256. X#ifndef unix
  55257. X#define unix
  55258. X#endif
  55259. X#endif
  55260. X
  55261. X#ifdef MSDOS        /* Microsoft C 5.1 for OS/2 and MSDOS */
  55262. X    typedef unsigned char  U8;
  55263. X    typedef signed char    S8;
  55264. X    typedef unsigned short U16;
  55265. X    typedef signed short   S16;
  55266. X    typedef unsigned long  U32;
  55267. X    typedef signed long    S32;
  55268. X    typedef unsigned char  BYTE;
  55269. X    typedef unsigned char  CHAR;
  55270. X    typedef void          *VOIDPTR;
  55271. X    typedef void far      *VOIDFARPTR;
  55272. X    typedef void const    *VOIDCONSTPTR;
  55273. X
  55274. X    #define CONST          const
  55275. X    #define PRINTER        "/dev/prn"
  55276. X    #define LOBYTEFIRST    1
  55277. X    #define SLASHC         '\\'
  55278. X    #define SLASH          "\\"
  55279. X    #define SLASHSLASH     "\\\\"
  55280. X    #define SLASHDOT       "\\."
  55281. X    #define DOTSLASH       ".\\"
  55282. X    #define DOTDOTSLASH    "..\\"
  55283. X    #define READMODE    "rb"    /* Correct DOS text-mode        */
  55284. X    #define WRITEMODE    "wb"    /* file open "feature".         */
  55285. X
  55286. X    #define write1(ptr,len,n,stream) fwrite(ptr,len,n,stream)
  55287. X    #define write2(ptr,len,n,stream) fwrite(ptr,len,n,stream)
  55288. X    #define rand15() rand()
  55289. X
  55290. X#else            /* may be Turbo-C */
  55291. X#ifdef __MSDOS__        /* TURBO-C */
  55292. X    typedef unsigned char  U8;
  55293. X    typedef signed char    S8;
  55294. X    typedef unsigned short U16;
  55295. X    typedef signed short   S16;
  55296. X    typedef unsigned long  U32;
  55297. X    typedef signed long    S32;
  55298. X    typedef unsigned char  BYTE;
  55299. X    typedef unsigned char  CHAR;
  55300. X    typedef void          *VOIDPTR;
  55301. X    typedef void far      *VOIDFARPTR;
  55302. X    typedef void const    *VOIDCONSTPTR;
  55303. X
  55304. X    #define CONST          const
  55305. X    #define PRINTER        "/dev/prn"
  55306. X    #define LOBYTEFIRST    1
  55307. X    #define SLASHC         '\\'
  55308. X    #define SLASH          "\\"
  55309. X    #define SLASHSLASH     "\\\\"
  55310. X    #define SLASHDOT       "\\."
  55311. X    #define DOTSLASH       ".\\"
  55312. X    #define DOTDOTSLASH    "..\\"
  55313. X    #define READMODE    "rb"    /* Correct DOS text-mode        */
  55314. X    #define WRITEMODE    "wb"    /* file open "feature".         */
  55315. X
  55316. X    #define write1(ptr,len,n,stream) fwrite(ptr,len,n,stream)
  55317. X    #define write2(ptr,len,n,stream) fwrite(ptr,len,n,stream)
  55318. X    #define rand15() rand()
  55319. X
  55320. X#else            /* Have to nest because #elif is not portable */
  55321. X#ifdef AMIGA        /* Lattice C 3.02 for Amiga */
  55322. X    typedef UBYTE          U8;
  55323. X    typedef BYTE           S8;
  55324. X    typedef UWORD          U16;
  55325. X    typedef WORD           S16;
  55326. X    typedef unsigned int   U32;
  55327. X    typedef int            S32;
  55328. X    typedef UBYTE          BYTE;
  55329. X    typedef UBYTE          CHAR;
  55330. X    typedef void          *VOIDPTR;
  55331. X    typedef void          *VOIDFARPTR;
  55332. X    typedef void          *VOIDCONSTPTR;
  55333. X
  55334. X    #define CONST
  55335. X    #define PRINTER        "PRT:"
  55336. X    #define LOBYTEFIRST    0
  55337. X    #define SLASHC         '/'
  55338. X    #define SLASH          "/"
  55339. X    #define SLASHSLASH     "//"
  55340. X    #define SLASHDOT       "/."
  55341. X    #define DOTSLASH       "./"
  55342. X    #define DOTDOTSLASH    "../"
  55343. X    #define READMODE    "rb"
  55344. X    #define WRITEMODE    "wb"
  55345. X
  55346. X    #define write1(ptr,len,n,stream) (fputc(*(ptr),stream),1)
  55347. X    #define write2(ptr,len,n,stream) (fputc((*(ptr))&255,stream),fputc((*(ptr))>>8,stream),1)
  55348. X    #define rand15() (rand()&0x7FFF)
  55349. X
  55350. X#else
  55351. X#ifdef unix            /* Unix machine */
  55352. X    typedef unsigned char  U8;
  55353. X    typedef char           S8;
  55354. X    typedef unsigned short U16;
  55355. X    typedef short          S16;
  55356. X    typedef unsigned long  U32;
  55357. X    typedef long           S32;
  55358. X    typedef unsigned char  BYTE;
  55359. X    typedef char           CHAR;
  55360. X#ifdef BADVOID
  55361. X    typedef char          *VOIDPTR;
  55362. X    typedef char          *VOIDFARPTR;
  55363. X    typedef char          *VOIDCONSTPTR;
  55364. X#else
  55365. X    typedef void          *VOIDPTR;
  55366. X    typedef void          *VOIDFARPTR;
  55367. X    typedef void          *VOIDCONSTPTR;
  55368. X#endif
  55369. X
  55370. X#    define CONST
  55371. X#    define PRINTER        "/dev/lp"
  55372. X#    define SLASHC         '/'
  55373. X#    define SLASH          "/"
  55374. X#    define SLASHSLASH     "//"
  55375. X#    define SLASHDOT       "/."
  55376. X#    define DOTSLASH       "./"
  55377. X#    define DOTDOTSLASH    "../"
  55378. X#    define READMODE    "r"
  55379. X#    define WRITEMODE    "w"
  55380. X
  55381. X#    define write1(ptr,len,n,stream) (fputc(*(ptr),stream),1)
  55382. X#    define write2(ptr,len,n,stream) (fputc((*(ptr))&255,stream),fputc((*(ptr))>>8,stream),1)
  55383. X#    define rand15() (rand()&0x7FFF)
  55384. X
  55385. X#    include "unix.h"
  55386. X
  55387. X
  55388. X#endif
  55389. X#endif
  55390. X#endif
  55391. X#endif
  55392. X
  55393. X#ifdef LOBYTEFIRST
  55394. X#define GET16(c,i)        (i) = *((U16*)(&(c)))
  55395. X#else
  55396. X#define GET16(c,i)              (i) = (*(unsigned char *)&(c))+\
  55397. X                ((*((unsigned char*)&(c)+1))<<8)
  55398. X#endif
  55399. X
  55400. X#endif    /* PORT_H */
  55401. SHAR_EOF
  55402. $TOUCH -am 1028230093 port.h &&
  55403. chmod 0644 port.h ||
  55404. echo "restore of port.h failed"
  55405. set `wc -c port.h`;Wc_c=$1
  55406. if test "$Wc_c" != "4549"; then
  55407.     echo original size 4549, current size $Wc_c
  55408. fi
  55409. # ============= helpcom.h ==============
  55410. echo "x - extracting helpcom.h (Text)"
  55411. sed 's/^X//' << 'SHAR_EOF' > helpcom.h &&
  55412. X
  55413. X/*
  55414. X * helpcom.h
  55415. X *
  55416. X *
  55417. X * Common #defines, structures and code for HC.C and HELP.C
  55418. X *
  55419. X */
  55420. X
  55421. X#ifndef HELPCOM_H
  55422. X#define HELPCOM_H
  55423. X
  55424. X#include "port.h"
  55425. X
  55426. X/*
  55427. X * help file signature
  55428. X * If you get a syntax error, remove the LU from the end of the number.
  55429. X */
  55430. X
  55431. X#define HELP_SIG       (0xAFBC1823LU)
  55432. X
  55433. X
  55434. X/*
  55435. X * commands imbedded in the help text
  55436. X */
  55437. X
  55438. X#define CMD_LITERAL      1   /* next char taken literally */
  55439. X#define CMD_PARA      2   /* paragraph start code */
  55440. X#define CMD_LINK      3   /* hot-link start/end code */
  55441. X#define CMD_FF          4   /* force a form-feed */
  55442. X#define CMD_XONLINE      5   /* exclude from online help on/off */
  55443. X#define CMD_XDOC      6   /* exclude from printed document on/off */
  55444. X#define CMD_CENTER      7   /* center this line */
  55445. X#define CMD_SPACE      8   /* next byte is count of spaces */
  55446. X
  55447. X#define MAX_CMD       8
  55448. X
  55449. X
  55450. X/*
  55451. X * on-line help dimensions
  55452. X */
  55453. X
  55454. X#define SCREEN_WIDTH      (78)
  55455. X#define SCREEN_DEPTH      (22)
  55456. X#define SCREEN_INDENT      (1)
  55457. X
  55458. X
  55459. X/*
  55460. X * printed document dimensions
  55461. X */
  55462. X
  55463. X#define PAGE_WIDTH       (72)  /* width of printed text */
  55464. X#define PAGE_INDENT       (2)     /* indent all text by this much */
  55465. X#define TITLE_INDENT       (1)     /* indent titles by this much */
  55466. X
  55467. X#define PAGE_RDEPTH       (59)  /* the total depth (inc. heading) */
  55468. X#define PAGE_HEADING_DEPTH (3)     /* depth of the heading */
  55469. X#define PAGE_DEPTH       (PAGE_RDEPTH-PAGE_HEADING_DEPTH) /* depth of text */
  55470. X
  55471. X
  55472. X/*
  55473. X * Document page-break macros.    Goto to next page if this close (or closer)
  55474. X * to end of page when starting a CONTENT, TOPIC, or at a BLANK line.
  55475. X */
  55476. X
  55477. X#define CONTENT_BREAK (7)  /* start of a "DocContent" entry */
  55478. X#define TOPIC_BREAK   (4)  /* start of each topic under a DocContent entry */
  55479. X#define BLANK_BREAK   (2)  /* a blank line */
  55480. X
  55481. X
  55482. X/*
  55483. X * tokens returned by find_token_length
  55484. X */
  55485. X
  55486. X#define TOK_DONE    (0)   /* len == 0          */
  55487. X#define TOK_SPACE   (1)   /* a run of spaces      */
  55488. X#define TOK_LINK    (2)   /* an entire link      */
  55489. X#define TOK_PARA    (3)   /* a CMD_PARA       */
  55490. X#define TOK_NL        (4)   /* a new-line ('\n')    */
  55491. X#define TOK_FF        (5)   /* a form-feed (CMD_FF) */
  55492. X#define TOK_WORD    (6)   /* a word          */
  55493. X#define TOK_XONLINE (7)   /* a CMD_XONLINE      */
  55494. X#define TOK_XDOC    (8)   /* a CMD_XDOC       */
  55495. X#define TOK_CENTER  (9)   /* a CMD_CENTER      */
  55496. X
  55497. X
  55498. X/*
  55499. X * modes for find_token_length() and find_line_width()
  55500. X */
  55501. X
  55502. X#define ONLINE 1
  55503. X#define DOC    2
  55504. X
  55505. X
  55506. X/*
  55507. X * struct PD_INFO used by process_document()
  55508. X */
  55509. X
  55510. Xtypedef struct
  55511. X   {
  55512. X
  55513. X   /* used by process_document -- look but don't touch! */
  55514. X
  55515. X   int         pnum,
  55516. X         lnum;
  55517. X
  55518. X   /* PD_GET_TOPIC is allowed to change these */
  55519. X
  55520. X   char far *curr;
  55521. X   unsigned  len;
  55522. X
  55523. X   /* PD_GET_CONTENT is allowed to change these */
  55524. X
  55525. X   char far *id;
  55526. X   char far *title;
  55527. X   int         new_page;
  55528. X
  55529. X   /* general parameters */
  55530. X
  55531. X   char far *s;
  55532. X   int         i;
  55533. X
  55534. X
  55535. X   } PD_INFO;
  55536. X
  55537. X
  55538. X/*
  55539. X * Commands passed to (*get_info)() and (*output)() by process_document()
  55540. X */
  55541. X
  55542. Xenum  PD_COMMANDS
  55543. X   {
  55544. X
  55545. X/* commands sent to pd_output */
  55546. X
  55547. X   PD_HEADING,           /* call at the top of each page */
  55548. X   PD_FOOTING,        /* called at the end of each page */
  55549. X   PD_PRINT,        /* called to send text to the printer */
  55550. X   PD_PRINTN,        /* called to print a char n times */
  55551. X   PD_PRINT_SEC,    /* called to print the section title line */
  55552. X   PD_START_SECTION,    /* called at the start of each section */
  55553. X   PD_START_TOPIC,    /* called at the start of each topic */
  55554. X   PD_SET_SECTION_PAGE, /* set the current sections page number */
  55555. X   PD_SET_TOPIC_PAGE,    /* set the current topics page number */
  55556. X   PD_PERIODIC,     /* called just before curr is incremented to next token */
  55557. X
  55558. X/* commands sent to pd_get_info */
  55559. X
  55560. X   PD_GET_CONTENT,
  55561. X   PD_GET_TOPIC,
  55562. X   PD_RELEASE_TOPIC,
  55563. X   PD_GET_LINK_PAGE
  55564. X
  55565. X   } ;
  55566. X
  55567. X
  55568. Xtypedef int (*PD_FUNC)(int cmd, PD_INFO *pd, VOIDPTR info);
  55569. X
  55570. X
  55571. Xint _find_token_length(char far *curr, unsigned len, int *size, int *width);
  55572. Xint find_token_length(int mode, char far *curr, unsigned len, int *size, int *width);
  55573. Xint find_line_width(int mode, char far *curr, unsigned len);
  55574. Xint process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info);
  55575. X
  55576. X
  55577. X/*
  55578. X * Code common to both HC.C and HELP.C (in Fractint).
  55579. X * #include INCLUDE_COMMON once for each program
  55580. X */
  55581. X
  55582. X
  55583. X#endif
  55584. X#ifdef INCLUDE_COMMON
  55585. X
  55586. X
  55587. X#ifndef XFRACT
  55588. X#define getint(ptr) (*(int far *)(ptr))
  55589. X#define setint(ptr,n) (*(int far *)(ptr)) = n
  55590. X#else
  55591. X/* Get an int from an unaligned pointer
  55592. X * This routine is needed because this program uses unaligned 2 byte
  55593. X * pointers all over the place.
  55594. X */
  55595. Xgetint(ptr)
  55596. Xchar *ptr;
  55597. X{
  55598. X    int s;
  55599. X    bcopy(ptr,&s,sizeof(int));
  55600. X    return s;
  55601. X}
  55602. X
  55603. X/* Set an int to an unaligned pointer */
  55604. Xvoid setint(ptr, n)
  55605. Xint n;
  55606. Xchar *ptr;
  55607. X{
  55608. X    bcopy(&n,ptr,sizeof(int));
  55609. X}
  55610. X#endif
  55611. X
  55612. X
  55613. Xstatic int is_hyphen(char far *ptr)   /* true if ptr points to a real hyphen */
  55614. X   {                   /* checkes for "--" and " -" */
  55615. X   if ( *ptr != '-' )
  55616. X      return (0);    /* that was easy! */
  55617. X
  55618. X   --ptr;
  55619. X
  55620. X   return ( *ptr!=' ' && *ptr!='-' );
  55621. X   }
  55622. X
  55623. X
  55624. Xint _find_token_length(register char far *curr, unsigned len, int *size, int *width)
  55625. X   {
  55626. X   register int _size  = 0;
  55627. X   register int _width = 0;
  55628. X   int tok;
  55629. X
  55630. X   if (len == 0)
  55631. X      tok = TOK_DONE;
  55632. X
  55633. X   else
  55634. X      {
  55635. X      switch ( *curr )
  55636. X     {
  55637. X     case ' ':    /* it's a run of spaces */
  55638. X        tok = TOK_SPACE;
  55639. X        while ( *curr == ' ' && _size < len )
  55640. X           {
  55641. X           ++curr;
  55642. X           ++_size;
  55643. X           ++_width;
  55644. X           }
  55645. X        break;
  55646. X
  55647. X     case CMD_SPACE:
  55648. X        tok = TOK_SPACE;
  55649. X        ++curr;
  55650. X        ++_size;
  55651. X        _width = *curr;
  55652. X        ++curr;
  55653. X        ++_size;
  55654. X        break;
  55655. X
  55656. X     case CMD_LINK:
  55657. X        tok = TOK_LINK;
  55658. X            _size += 1+3*sizeof(int); /* skip CMD_LINK + topic_num + topic_off + page_num */
  55659. X            curr += 1+3*sizeof(int);
  55660. X
  55661. X        while ( *curr != CMD_LINK )
  55662. X           {
  55663. X           if ( *curr == CMD_LITERAL )
  55664. X          {
  55665. X          ++curr;
  55666. X          ++_size;
  55667. X          }
  55668. X           ++curr;
  55669. X           ++_size;
  55670. X           ++_width;
  55671. X           assert(_size < len);
  55672. X           }
  55673. X
  55674. X        ++_size;   /* skip ending CMD_LINK */
  55675. X        break;
  55676. X
  55677. X     case CMD_PARA:
  55678. X        tok = TOK_PARA;
  55679. X        _size += 3;     /* skip CMD_PARA + indent + margin */
  55680. X        break;
  55681. X
  55682. X     case CMD_XONLINE:
  55683. X        tok = TOK_XONLINE;
  55684. X        ++_size;
  55685. X        break;
  55686. X
  55687. X     case CMD_XDOC:
  55688. X        tok = TOK_XDOC;
  55689. X        ++_size;
  55690. X        break;
  55691. X
  55692. X     case CMD_CENTER:
  55693. X        tok = TOK_CENTER;
  55694. X        ++_size;
  55695. X        break;
  55696. X
  55697. X     case '\n':
  55698. X        tok = TOK_NL;
  55699. X        ++_size;
  55700. X        break;
  55701. X
  55702. X     case CMD_FF:
  55703. X        tok = TOK_FF;
  55704. X        ++_size;
  55705. X        break;
  55706. X
  55707. X     default:   /* it must be a word */
  55708. X        tok = TOK_WORD;
  55709. X        while (1)
  55710. X           {
  55711. X           if ( _size >= len )
  55712. X          break;
  55713. X
  55714. X           else if ( *curr == CMD_LITERAL )
  55715. X          {
  55716. X          curr += 2;
  55717. X          _size += 2;
  55718. X          _width += 1;
  55719. X          }
  55720. X
  55721. X           else if ( *curr == '\0' )
  55722. X          {
  55723. X          assert(0);
  55724. X          }
  55725. X
  55726. X           else if ((unsigned)*curr <= MAX_CMD || *curr == ' ' ||
  55727. X            *curr == '\n')
  55728. X          break;
  55729. X
  55730. X           else if ( *curr == '-' )
  55731. X          {
  55732. X          ++curr;
  55733. X          ++_size;
  55734. X          ++_width;
  55735. X          if ( is_hyphen(curr-1) )
  55736. X             break;
  55737. X          }
  55738. X
  55739. X           else
  55740. X          {
  55741. X          ++curr;
  55742. X          ++_size;
  55743. X          ++_width;
  55744. X          }
  55745. X           }
  55746. X        break;
  55747. X     } /* switch */
  55748. X      }
  55749. X
  55750. X   if (size  != NULL)    *size  = _size;
  55751. X   if (width != NULL)    *width = _width;
  55752. X
  55753. X   return (tok);
  55754. X   }
  55755. X
  55756. X
  55757. Xint find_token_length(int mode, char far *curr, unsigned len, int *size, int *width)
  55758. X   {
  55759. X   int tok;
  55760. X   int t;
  55761. X   int _size;
  55762. X
  55763. X   tok = _find_token_length(curr, len, &t, width);
  55764. X
  55765. X   if ( (tok == TOK_XONLINE && mode == ONLINE) ||
  55766. X    (tok == TOK_XDOC    && mode == DOC)     )
  55767. X      {
  55768. X      _size = 0;
  55769. X
  55770. X      while (1)
  55771. X     {
  55772. X     curr  += t;
  55773. X     len   -= t;
  55774. X     _size += t;
  55775. X
  55776. X     tok = _find_token_length(curr, len, &t, NULL);
  55777. X
  55778. X     if ( (tok == TOK_XONLINE && mode == ONLINE) ||
  55779. X          (tok == TOK_XDOC      && mode == DOC)    ||
  55780. X          (tok == TOK_DONE)                )
  55781. X        break;
  55782. X     }
  55783. X
  55784. X      _size += t;
  55785. X      }
  55786. X   else
  55787. X      _size = t;
  55788. X
  55789. X   if (size != NULL )
  55790. X      *size = _size;
  55791. X
  55792. X   return (tok);
  55793. X   }
  55794. X
  55795. X
  55796. Xint find_line_width(int mode, char far *curr, unsigned len)
  55797. X   {
  55798. X   int size   = 0,
  55799. X       width  = 0,
  55800. X       lwidth = 0,
  55801. X       done   = 0,
  55802. X       tok;
  55803. X
  55804. X   do
  55805. X      {
  55806. X      tok = find_token_length(mode, curr, len, &size, &width);
  55807. X
  55808. X      switch(tok)
  55809. X     {
  55810. X     case TOK_DONE:
  55811. X     case TOK_PARA:
  55812. X     case TOK_NL:
  55813. X     case TOK_FF:
  55814. X        done = 1;
  55815. X        break;
  55816. X
  55817. X     case TOK_XONLINE:
  55818. X     case TOK_XDOC:
  55819. X     case TOK_CENTER:
  55820. X        curr += size;
  55821. X        len -= size;
  55822. X        break;
  55823. X
  55824. X     default:   /* TOK_SPACE, TOK_LINK or TOK_WORD */
  55825. X        lwidth += width;
  55826. X        curr += size;
  55827. X        len -= size;
  55828. X        break;
  55829. X     }
  55830. X      }
  55831. X   while ( !done );
  55832. X
  55833. X   return (lwidth);
  55834. X   }
  55835. X
  55836. X
  55837. X#define DO_PRINTN(ch,n)  ( pd.s = &(ch), pd.i = (n), output(PD_PRINTN, &pd, info) )
  55838. X#define DO_PRINT(str,n)  ( pd.s = (str), pd.i = (n), output(PD_PRINT, &pd, info) )
  55839. X
  55840. X
  55841. Xint process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info)
  55842. X   {
  55843. X   int         skip_blanks;
  55844. X   int         tok;
  55845. X   int         size,
  55846. X         width;
  55847. X   int         col;
  55848. X   char      page_text[10];
  55849. X   PD_INFO   pd;
  55850. X   char      nl = '\n',
  55851. X         sp = ' ';
  55852. X   int         first_section,
  55853. X         first_topic;
  55854. X
  55855. X   pd.pnum = 1;
  55856. X   pd.lnum = 0;
  55857. X
  55858. X   col = 0;
  55859. X
  55860. X   output(PD_HEADING, &pd, info);
  55861. X
  55862. X   first_section = 1;
  55863. X
  55864. X   while ( get_info(PD_GET_CONTENT, &pd, info) )
  55865. X      {
  55866. X      if ( !output(PD_START_SECTION, &pd, info) )
  55867. X     return (0);
  55868. X
  55869. X      if ( pd.new_page && pd.lnum != 0 )
  55870. X     {
  55871. X     if ( !output(PD_FOOTING, &pd, info) )
  55872. X        return (0);
  55873. X     ++pd.pnum;
  55874. X     pd.lnum = 0;
  55875. X     if ( !output(PD_HEADING, &pd, info) )
  55876. X        return (0);
  55877. X     }
  55878. X
  55879. X      else
  55880. X     {
  55881. X     if ( pd.lnum+2 > PAGE_DEPTH-CONTENT_BREAK )
  55882. X        {
  55883. X        if ( !output(PD_FOOTING, &pd, info) )
  55884. X           return (0);
  55885. X        ++pd.pnum;
  55886. X        pd.lnum = 0;
  55887. X        if ( !output(PD_HEADING, &pd, info) )
  55888. X           return (0);
  55889. X        }
  55890. X     else if (pd.lnum > 0)
  55891. X        {
  55892. X        if ( !DO_PRINTN(nl, 2) )
  55893. X           return (0);
  55894. X        pd.lnum += 2;
  55895. X        }
  55896. X     }
  55897. X
  55898. X      if ( !output(PD_SET_SECTION_PAGE, &pd, info) )
  55899. X     return (0);
  55900. X
  55901. X      if ( !first_section )
  55902. X     {
  55903. X     if ( !output(PD_PRINT_SEC, &pd, info) )
  55904. X        return (0);
  55905. X     ++pd.lnum;
  55906. X     }
  55907. X
  55908. X      col = 0;
  55909. X
  55910. X      first_topic = 1;
  55911. X
  55912. X      while ( get_info(PD_GET_TOPIC, &pd, info) )
  55913. X     {
  55914. X     if ( !output(PD_START_TOPIC, &pd, info) )
  55915. X        return (0);
  55916. X
  55917. X     skip_blanks = 0;
  55918. X     col = 0;
  55919. X
  55920. X     if ( !first_section )     /* do not skip blanks for DocContents */
  55921. X        {
  55922. X        while (pd.len > 0)
  55923. X           {
  55924. X           tok = find_token_length(DOC, pd.curr, pd.len, &size, NULL);
  55925. X           if (tok != TOK_XDOC && tok != TOK_XONLINE &&
  55926. X           tok != TOK_NL   && tok != TOK_DONE )
  55927. X          break;
  55928. X           pd.curr += size;
  55929. X           pd.len  -= size;
  55930. X           }
  55931. X        if ( first_topic && pd.len != 0 )
  55932. X           {
  55933. X           if ( !DO_PRINTN(nl, 1) )
  55934. X          return (0);
  55935. X           ++pd.lnum;
  55936. X           }
  55937. X        }
  55938. X
  55939. X     if ( pd.lnum > PAGE_DEPTH-TOPIC_BREAK )
  55940. X        {
  55941. X        if ( !output(PD_FOOTING, &pd, info) )
  55942. X           return (0);
  55943. X        ++pd.pnum;
  55944. X        pd.lnum = 0;
  55945. X        if ( !output(PD_HEADING, &pd, info) )
  55946. X           return (0);
  55947. X        }
  55948. X     else if ( !first_topic )
  55949. X        {
  55950. X        if ( !DO_PRINTN(nl, 1) )
  55951. X           return (0);
  55952. X        pd.lnum++;
  55953. X        }
  55954. X
  55955. X     if ( !output(PD_SET_TOPIC_PAGE, &pd, info) )
  55956. X        return (0);
  55957. X
  55958. X     do
  55959. X        {
  55960. X        if ( !output(PD_PERIODIC, &pd, info) )
  55961. X           return (0);
  55962. X
  55963. X        tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);
  55964. X
  55965. X        switch ( tok )
  55966. X           {
  55967. X           case TOK_PARA:
  55968. X          {
  55969. X          int        indent,
  55970. X                margin;
  55971. X          unsigned  holdlen = 0;
  55972. X          char far *holdcurr = 0;
  55973. X          int        in_link = 0;
  55974. X
  55975. X          ++pd.curr;
  55976. X
  55977. X          indent = *pd.curr++;
  55978. X          margin = *pd.curr++;
  55979. X
  55980. X          pd.len -= 3;
  55981. X
  55982. X          if ( !DO_PRINTN(sp, indent) )
  55983. X             return (0);
  55984. X
  55985. X          col = indent;
  55986. X
  55987. X          while (1)
  55988. X             {
  55989. X             if ( !output(PD_PERIODIC, &pd, info) )
  55990. X            return (0);
  55991. X
  55992. X             tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);
  55993. X
  55994. X             if ( tok == TOK_NL || tok == TOK_FF )
  55995. X            break;
  55996. X
  55997. X             if ( tok == TOK_DONE )
  55998. X            {
  55999. X            if (in_link == 0)
  56000. X               {
  56001. X               col = 0;
  56002. X               ++pd.lnum;
  56003. X               if ( !DO_PRINTN(nl, 1) )
  56004. X                  return (0);
  56005. X               break;
  56006. X               }
  56007. X
  56008. X            else if (in_link == 1)
  56009. X               {
  56010. X               tok = TOK_SPACE;
  56011. X               width = 1;
  56012. X               size = 0;
  56013. X               ++in_link;
  56014. X               }
  56015. X
  56016. X            else if (in_link == 2)
  56017. X               {
  56018. X               tok = TOK_WORD;
  56019. X               width = strlen(page_text);
  56020. X               col += 8 - width;
  56021. X               size = 0;
  56022. X               pd.curr = page_text;
  56023. X               ++in_link;
  56024. X               }
  56025. X
  56026. X            else if (in_link == 3)
  56027. X               {
  56028. X               pd.curr = holdcurr;
  56029. X               pd.len = holdlen;
  56030. X               in_link = 0;
  56031. X               continue;
  56032. X               }
  56033. X            }
  56034. X
  56035. X             if ( tok == TOK_PARA )
  56036. X            {
  56037. X            col = 0;   /* fake a nl */
  56038. X            ++pd.lnum;
  56039. X            if ( !DO_PRINTN(nl, 1) )
  56040. X               return (0);
  56041. X            break;
  56042. X            }
  56043. X
  56044. X             if (tok == TOK_XONLINE || tok == TOK_XDOC )
  56045. X            {
  56046. X            pd.curr += size;
  56047. X            pd.len -= size;
  56048. X            continue;
  56049. X            }
  56050. X
  56051. X             if ( tok == TOK_LINK )
  56052. X            {
  56053. X            pd.s = pd.curr+1;
  56054. X            if ( get_info(PD_GET_LINK_PAGE, &pd, info) )
  56055. X               {
  56056. X               in_link = 1;
  56057. X               sprintf(page_text, "(p. %d)", pd.i);
  56058. X               }
  56059. X            else
  56060. X               in_link = 3;
  56061. X            holdcurr = pd.curr + size;
  56062. X            holdlen = pd.len - size;
  56063. X                        pd.len = size - 2 - 3*sizeof(int);
  56064. X                        pd.curr += 1 + 3*sizeof(int);
  56065. X            continue;
  56066. X            }
  56067. X
  56068. X             /* now tok is TOK_SPACE or TOK_WORD */
  56069. X
  56070. X             if (col+width > PAGE_WIDTH)
  56071. X            {       /* go to next line... */
  56072. X            if ( !DO_PRINTN(nl, 1) )
  56073. X               return (0);
  56074. X            if ( ++pd.lnum >= PAGE_DEPTH )
  56075. X               {
  56076. X               if ( !output(PD_FOOTING, &pd, info) )
  56077. X                  return (0);
  56078. X               ++pd.pnum;
  56079. X               pd.lnum = 0;
  56080. X               if ( !output(PD_HEADING, &pd, info) )
  56081. X                  return (0);
  56082. X               }
  56083. X
  56084. X            if ( tok == TOK_SPACE )
  56085. X               width = 0;    /* skip spaces at start of a line */
  56086. X
  56087. X            if ( !DO_PRINTN(sp, margin) )
  56088. X               return (0);
  56089. X            col = margin;
  56090. X            }
  56091. X
  56092. X             if (width > 0)
  56093. X            {
  56094. X            if (tok == TOK_SPACE)
  56095. X               {
  56096. X               if ( !DO_PRINTN(sp, width) )
  56097. X                  return (0);
  56098. X               }
  56099. X            else
  56100. X               {
  56101. X               if ( !DO_PRINT(pd.curr, (size==0) ? width : size) )
  56102. X                  return (0);
  56103. X               }
  56104. X            }
  56105. X
  56106. X             col += width;
  56107. X             pd.curr += size;
  56108. X             pd.len -= size;
  56109. X             }
  56110. X
  56111. X          skip_blanks = 0;
  56112. X          width = size = 0;
  56113. X          break;
  56114. X          }
  56115. X
  56116. X           case TOK_NL:
  56117. X          if (skip_blanks && col == 0)
  56118. X             break;
  56119. X
  56120. X          ++pd.lnum;
  56121. X
  56122. X          if ( pd.lnum >= PAGE_DEPTH || (col == 0 && pd.lnum >= PAGE_DEPTH-BLANK_BREAK) )
  56123. X             {
  56124. X             if ( col != 0 )    /* if last wasn't a blank line... */
  56125. X            {
  56126. X            if ( !DO_PRINTN(nl, 1) )
  56127. X               return (0);
  56128. X            }
  56129. X             if ( !output(PD_FOOTING, &pd, info) )
  56130. X            return (0);
  56131. X             ++pd.pnum;
  56132. X             pd.lnum = 0;
  56133. X             skip_blanks = 1;
  56134. X             if ( !output(PD_HEADING, &pd, info) )
  56135. X            return (0);
  56136. X             }
  56137. X          else
  56138. X             {
  56139. X             if ( !DO_PRINTN(nl, 1) )
  56140. X            return (0);
  56141. X             }
  56142. X
  56143. X          col = 0;
  56144. X          break;
  56145. X
  56146. X           case TOK_FF:
  56147. X          if (skip_blanks)
  56148. X             break;
  56149. X          if ( !output(PD_FOOTING, &pd, info) )
  56150. X             return (0);
  56151. X          col = 0;
  56152. X          pd.lnum = 0;
  56153. X          ++pd.pnum;
  56154. X          if ( !output(PD_HEADING, &pd, info) )
  56155. X             return (0);
  56156. X          break;
  56157. X
  56158. X           case TOK_CENTER:
  56159. X          width = (PAGE_WIDTH - find_line_width(DOC,pd.curr,pd.len)) / 2;
  56160. X          if ( !DO_PRINTN(sp, width) )
  56161. X             return (0);
  56162. X          break;
  56163. X
  56164. X           case TOK_LINK:
  56165. X          skip_blanks = 0;
  56166. X          if ( !DO_PRINT(pd.curr+1+3*sizeof(int),
  56167. X              size-3*sizeof(int)-2) )
  56168. X             return (0);
  56169. X          pd.s = pd.curr+1;
  56170. X          if ( get_info(PD_GET_LINK_PAGE, &pd, info) )
  56171. X             {
  56172. X             width += 9;
  56173. X             sprintf(page_text, " (p. %d)", pd.i);
  56174. X             if ( !DO_PRINT(page_text, strlen(page_text)) )
  56175. X            return (0);
  56176. X             }
  56177. X          break;
  56178. X
  56179. X           case TOK_WORD:
  56180. X          skip_blanks = 0;
  56181. X          if ( !DO_PRINT(pd.curr, size) )
  56182. X             return (0);
  56183. X          break;
  56184. X
  56185. X           case TOK_SPACE:
  56186. X          skip_blanks = 0;
  56187. X          if ( !DO_PRINTN(sp, width) )
  56188. X             return (0);
  56189. X          break;
  56190. X
  56191. X           case TOK_DONE:
  56192. X           case TOK_XONLINE:   /* skip */
  56193. X           case TOK_XDOC:       /* ignore */
  56194. X          break;
  56195. X
  56196. X           } /* switch */
  56197. X
  56198. X        pd.curr += size;
  56199. X        pd.len  -= size;
  56200. X        col     += width;
  56201. X        }
  56202. X     while (pd.len > 0);
  56203. X
  56204. X     get_info(PD_RELEASE_TOPIC, &pd, info);
  56205. X
  56206. X     first_topic = 0;
  56207. X     } /* while */
  56208. X
  56209. X      first_section = 0;
  56210. X      } /* while */
  56211. X
  56212. X   if ( !output(PD_FOOTING, &pd, info) )
  56213. X      return (0);
  56214. X
  56215. X   return (1);
  56216. X   }
  56217. X
  56218. X#undef DO_PRINT
  56219. X#undef DO_PRINTN
  56220. X
  56221. X
  56222. X#undef INCLUDE_COMMON
  56223. X#endif     /* #ifdef INCLUDE_COMMON */
  56224. SHAR_EOF
  56225. $TOUCH -am 1028230093 helpcom.h &&
  56226. chmod 0644 helpcom.h ||
  56227. echo "restore of helpcom.h failed"
  56228. set `wc -c helpcom.h`;Wc_c=$1
  56229. if test "$Wc_c" != "15703"; then
  56230.     echo original size 15703, current size $Wc_c
  56231. fi
  56232. # ============= helpdefs.h ==============
  56233. echo "x - extracting helpdefs.h (Text)"
  56234. sed 's/^X//' << 'SHAR_EOF' > helpdefs.h &&
  56235. X
  56236. X/*
  56237. X * helpdefs.h
  56238. X *
  56239. X * Contains #defines for help.
  56240. X *
  56241. X * Generated by HC from: help.src
  56242. X *
  56243. X */
  56244. X
  56245. X
  56246. X/* current help file version */
  56247. X
  56248. X#define HELP_VERSION                     100
  56249. X
  56250. X
  56251. X/* labels */
  56252. X
  56253. X#define HELP_INDEX                         0        /* index */
  56254. X#define HELP3D                             1
  56255. X#define HELP3DFILL                         2
  56256. X#define HELP3DFRACT                        3
  56257. X#define HELP3DGLASSES                      4
  56258. X#define HELP3DLIGHT                        5
  56259. X#define HELP3DMODE                         6
  56260. X#define HELP3DOVLY                         7
  56261. X#define HELP3DPARMS                        8
  56262. X#define HELPCOLORMAP                       9
  56263. X#define HELPCOMMANDS                      10
  56264. X#define HELPCOORDS                        11
  56265. X#define HELPCYCLING                       12
  56266. X#define HELPFRACTALS                      13
  56267. X#define HELPLOADFILE                      14
  56268. X#define HELPMAIN                          15
  56269. X#define HELPMENU                          16
  56270. X#define HELPPARMFILE                      17
  56271. X#define HELPSAVEREST                      18
  56272. X#define HELPSTARFLD                       19
  56273. X#define HELPVIDSEL                        20
  56274. X#define HELPVIEW                          21
  56275. X#define HELPXHAIR                         22
  56276. X#define HELPXOPTS                         23
  56277. X#define HELPYOPTS                         24
  56278. X#define HELPZOOM                          25
  56279. X#define HELP_JIIM                         26
  56280. X#define HELP_ORBITS                       27
  56281. X#define HF_BARNSJ1                        28
  56282. X#define HF_BARNSJ2                        29
  56283. X#define HF_BARNSJ3                        30
  56284. X#define HF_BARNSM1                        31
  56285. X#define HF_BARNSM2                        32
  56286. X#define HF_BARNSM3                        33
  56287. X#define HF_BIFEQSINPI                     34
  56288. X#define HF_BIFLAMBDA                      35
  56289. X#define HF_BIFMAY                         36
  56290. X#define HF_BIFPLUSSINPI                   37
  56291. X#define HF_BIFSTEWART                     38
  56292. X#define HF_BIFURCATION                    39
  56293. X#define HF_CELLULAR                       40
  56294. X#define HF_CIRCLE                         41
  56295. X#define HF_CMPLXMARKSJUL                  42
  56296. X#define HF_CMPLXMARKSMAND                 43
  56297. X#define HF_COMPLEXNEWT                    44
  56298. X#define HF_DIFFUS                         45
  56299. X#define HF_DYNAM                          46
  56300. X#define HF_FNPLUSFN                       47
  56301. X#define HF_FNPLUSFNPIX                    48
  56302. X#define HF_FNTIMESFN                      49
  56303. X#define HF_FNXZPLUSZ                      50
  56304. X#define HF_FNZTIMESZ                      51
  56305. X#define HF_FROTH                          52
  56306. X#define HF_GINGER                         53
  56307. X#define HF_HALLEY                         54
  56308. X#define HF_HENON                          55
  56309. X#define HF_HOPALONG                       56
  56310. X#define HF_HYPERC                         57
  56311. X#define HF_HYPERCJ                        58
  56312. X#define HF_ICON                           59
  56313. X#define HF_INVERSE                        60
  56314. X#define HF_JULFNPLUSEXP                   61
  56315. X#define HF_JULFNPLUSZSQRD                 62
  56316. X#define HF_JULIA                          63
  56317. X#define HF_JULIA4                         64
  56318. X#define HF_JULIAFNFN                      65
  56319. X#define HF_JULZPOWER                      66
  56320. X#define HF_JULZZPWR                       67
  56321. X#define HF_KAM                            68
  56322. X#define HF_LAMBDA                         69
  56323. X#define HF_LAMBDAFN                       70
  56324. X#define HF_LAMBDAFNFN                     71
  56325. X#define HF_LORENZ                         72
  56326. X#define HF_LORENZ3D1                      73
  56327. X#define HF_LORENZ3D3                      74
  56328. X#define HF_LORENZ3D4                      75
  56329. X#define HF_MAGJ1                          76
  56330. X#define HF_MAGJ2                          77
  56331. X#define HF_MAGM1                          78
  56332. X#define HF_MAGM2                          79
  56333. X#define HF_MANDEL                         80
  56334. X#define HF_MANDEL4                        81
  56335. X#define HF_MANDELCLOUD                    82
  56336. X#define HF_MANDELFNFN                     83
  56337. X#define HF_MANDFN                         84
  56338. X#define HF_MANDFNPLUSEXP                  85
  56339. X#define HF_MANDFNPLUSZSQRD                86
  56340. X#define HF_MANDPHOENIX                    87
  56341. X#define HF_MANLAMFNFN                     88
  56342. X#define HF_MANOWAR                        89
  56343. X#define HF_MANOWARJ                       90
  56344. X#define HF_MANZPOWER                      91
  56345. X#define HF_MANZZPWR                       92
  56346. X#define HF_MARKSJULIA                     93
  56347. X#define HF_MARKSMAND                      94
  56348. X#define HF_MARKSMANDPWR                   95
  56349. X#define HF_MARTIN                         96
  56350. X#define HF_MLAMBDA                        97
  56351. X#define HF_NEWT                           98
  56352. X#define HF_NEWTBAS                        99
  56353. X#define HF_PHOENIX                       100
  56354. X#define HF_PICKOVER                      101
  56355. X#define HF_PLASMA                        102
  56356. X#define HF_POPCJUL                       103
  56357. X#define HF_POPCORN                       104
  56358. X#define HF_QUAT                          105
  56359. X#define HF_QUATJ                         106
  56360. X#define HF_ROSS                          107
  56361. X#define HF_SIER                          108
  56362. X#define HF_SPIDER                        109
  56363. X#define HF_SQRFN                         110
  56364. X#define HF_SQROVFN                       111
  56365. X#define HF_TEST                          112
  56366. X#define HF_TETRATE                       113
  56367. X#define HF_TIMSERR                       114
  56368. X#define HF_UNITY                         115
  56369. X#define HT_BARNS                         116
  56370. X#define HT_BIF                           117
  56371. X#define HT_CELLULAR                      118
  56372. X#define HT_CIRCLE                        119
  56373. X#define HT_DIFFUS                        120
  56374. X#define HT_DYNAM                         121
  56375. X#define HT_FNORFN                        122
  56376. X#define HT_FORMULA                       123
  56377. X#define HT_FROTH                         124
  56378. X#define HT_GINGER                        125
  56379. X#define HT_HALLEY                        126
  56380. X#define HT_HENON                         127
  56381. X#define HT_HYPERC                        128
  56382. X#define HT_ICON                          129
  56383. X#define HT_IFS                           130
  56384. X#define HT_INVERSE                       131
  56385. X#define HT_JULIA                         132
  56386. X#define HT_JULIBROT                      133
  56387. X#define HT_KAM                           134
  56388. X#define HT_LAMBDA                        135
  56389. X#define HT_LAMBDAFN                      136
  56390. X#define HT_LORENZ                        137
  56391. X#define HT_LSYS                          138
  56392. X#define HT_LYAPUNOV                      139
  56393. X#define HT_MAGNET                        140
  56394. X#define HT_MANDEL                        141
  56395. X#define HT_MANDELCLOUD                   142
  56396. X#define HT_MANDFN                        143
  56397. X#define HT_MANDJUL4                      144
  56398. X#define HT_MARKS                         145
  56399. X#define HT_MARTIN                        146
  56400. X#define HT_MLAMBDA                       147
  56401. X#define HT_NEWT                          148
  56402. X#define HT_NEWTBAS                       149
  56403. X#define HT_NEWTCMPLX                     150
  56404. X#define HT_PHOENIX                       151
  56405. X#define HT_PICK                          152
  56406. X#define HT_PICKMJ                        153
  56407. X#define HT_PLASMA                        154
  56408. X#define HT_POPCORN                       155
  56409. X#define HT_QUAT                          156
  56410. X#define HT_ROSS                          157
  56411. X#define HT_SCOTSKIN                      158
  56412. X#define HT_SIER                          159
  56413. X#define HT_TEST                          160
  56414. X#define HT_UNITY                         161
  56415. X#define INTRO_AUTHORS                    162
  56416. X#define INTRO_CREDITS                    163
  56417. X
  56418. X
  56419. SHAR_EOF
  56420. $TOUCH -am 1028230093 helpdefs.h &&
  56421. chmod 0644 helpdefs.h ||
  56422. echo "restore of helpdefs.h failed"
  56423. set `wc -c helpdefs.h`;Wc_c=$1
  56424. if test "$Wc_c" != "7593"; then
  56425.     echo original size 7593, current size $Wc_c
  56426. fi
  56427. # ============= mpmath.h ==============
  56428. echo "x - extracting mpmath.h (Text)"
  56429. sed 's/^X//' << 'SHAR_EOF' > mpmath.h &&
  56430. X/*
  56431. X *  REMOVED FORMAL PARAMETERS FROM FUNCTION DEFINITIONS (1/4/92)
  56432. X */
  56433. X
  56434. X
  56435. X#ifndef MPMATH_H
  56436. X#define MPMATH_H
  56437. X
  56438. X#ifndef _CMPLX_DEFINED
  56439. X#define _CMPLX_DEFINED
  56440. X
  56441. Xstruct DHyperComplex {
  56442. X    double x,y;
  56443. X    double z,t;  
  56444. X};
  56445. X
  56446. Xstruct LHyperComplex {
  56447. X    long x,y;
  56448. X    long z,t; 
  56449. X};
  56450. X
  56451. Xstruct DComplex {
  56452. X    double x,y;
  56453. X};
  56454. X
  56455. Xstruct LComplex {
  56456. X    long x,y;
  56457. X};
  56458. X
  56459. Xtypedef struct  DComplex         _CMPLX;
  56460. Xtypedef struct  LComplex         _LCMPLX;
  56461. Xtypedef struct  DHyperComplex    _HCMPLX;
  56462. Xtypedef struct  LHyperComplex    _LHCMPLX;
  56463. X#endif
  56464. X
  56465. X#include <math.h>
  56466. X
  56467. X#ifdef XFRACT
  56468. X#define far
  56469. X#endif
  56470. X
  56471. X
  56472. X#ifndef XFRACT
  56473. Xstruct MP {
  56474. X   int Exp;
  56475. X        unsigned long Mant;
  56476. X};
  56477. X#else
  56478. Xstruct MP {
  56479. X   double val;
  56480. X};
  56481. X#endif
  56482. X
  56483. Xstruct MPC {
  56484. X        struct MP x, y;
  56485. X};
  56486. X
  56487. Xextern struct MP MPTrigTable[2][4][256], InvHalfPi, HalfPi, InvLn2, Ln2;
  56488. Xextern int MPaccuracy, MPOverflow;
  56489. Xextern int DivideOverflow;
  56490. X
  56491. X/* Mark Peterson's expanded floating point operators.  Automatically uses
  56492. X   either the 8086 or 80386 processor type specified in global 'cpu'. If
  56493. X   the operation results in an overflow (result < 2**(2**14), or division
  56494. X   by zero) the global 'MPoverflow' is set to one. */
  56495. X
  56496. Xextern int cpu;
  56497. X
  56498. X/* function pointer support added by Tim Wegner 12/07/89 */
  56499. Xextern int         (*pMPcmp)(struct MP , struct MP );
  56500. Xextern struct MP  *(*pMPmul)(struct MP , struct MP );
  56501. Xextern struct MP  *(*pMPdiv)(struct MP , struct MP );
  56502. Xextern struct MP  *(*pMPadd)(struct MP , struct MP );
  56503. Xextern struct MP  *(*pMPsub)(struct MP , struct MP );
  56504. Xextern struct MP  *(*pd2MP)(double )                ;
  56505. Xextern double     *(*pMP2d)(struct MP )             ;
  56506. X
  56507. X
  56508. X/*** Formula Declarations ***/
  56509. Xtypedef enum { D_MATH, M_MATH, L_MATH } MATH_TYPE;
  56510. Xextern MATH_TYPE MathType;
  56511. X
  56512. X#define fDiv(x, y, z) (void)((*(long*)&z) = RegDivFloat(*(long*)&x, *(long*)&y))
  56513. X#define fMul16(x, y, z) (void)((*(long*)&z) = r16Mul(*(long*)&x, *(long*)&y))
  56514. X#define fShift(x, Shift, z) (void)((*(long*)&z) = \
  56515. X   RegSftFloat(*(long*)&x, Shift))
  56516. X#define Fg2Float(x, f, z) (void)((*(long*)&z) = RegFg2Float(x, f))
  56517. X#define Float2Fg(x, f) RegFloat2Fg(*(long*)&x, f)
  56518. X#define fLog14(x, z) (void)((*(long*)&z) = \
  56519. X        RegFg2Float(LogFloat14(*(long*)&x), 16))
  56520. X#define fExp14(x, z) (void)((*(long*)&z) = ExpFloat14(*(long*)&x));
  56521. X#define fSqrt14(x, z) fLog14(x, z); fShift(z, -1, z); fExp14(z, z)
  56522. X
  56523. X/* the following are declared 4 dimensional as an experimnent */
  56524. X/* changeing declarations to _CMPLX and _LCMPLX restores the code */
  56525. X/* to 2D */
  56526. Xunion Arg {
  56527. X   _CMPLX     d;
  56528. X   struct MPC m;
  56529. X   _LCMPLX    l;
  56530. X/*
  56531. X   _DHCMPLX   dh; 
  56532. X   _LHCMPLX   lh; */  
  56533. X};
  56534. X
  56535. Xstruct ConstArg {
  56536. X   char *s;
  56537. X   int len;
  56538. X   union Arg a;
  56539. X};
  56540. X
  56541. Xextern union Arg *Arg1,*Arg2;
  56542. X
  56543. Xextern void lStkSin(void),lStkCos(void),lStkSinh(void),lStkCosh(void),lStkLog(void),lStkExp(void),lStkSqr(void);
  56544. Xextern void dStkSin(void),dStkCos(void),dStkSinh(void),dStkCosh(void),dStkLog(void),dStkExp(void),dStkSqr(void);
  56545. X
  56546. Xextern void (*ltrig0)(void);
  56547. Xextern void (*ltrig1)(void);
  56548. Xextern void (*ltrig2)(void);
  56549. Xextern void (*ltrig3)(void);
  56550. Xextern void (*dtrig0)(void);
  56551. Xextern void (*dtrig1)(void);
  56552. Xextern void (*dtrig2)(void);
  56553. Xextern void (*dtrig3)(void);
  56554. X
  56555. X/* -------------------------------------------------------------------- */
  56556. X/*   The following #defines allow the complex transcendental functions    */
  56557. X/*   in parser.c to be used here thus avoiding duplicated code.     */
  56558. X/* -------------------------------------------------------------------- */
  56559. X#ifndef XFRACT
  56560. X
  56561. X#define CMPLXmod(z)      (sqr((z).x)+sqr((z).y))
  56562. X#define CMPLXconj(z)    ((z).y =  -((z).y))
  56563. X#define LCMPLXmod(z)       (lsqr((z).x)+lsqr((z).y))
  56564. X#define LCMPLXconj(z)    ((z).y =  -((z).y))
  56565. X
  56566. X
  56567. X#define LCMPLXtrig0(arg,out) Arg1->l = (arg); ltrig0(); (out)=Arg1->l
  56568. X#define LCMPLXtrig1(arg,out) Arg1->l = (arg); ltrig1(); (out)=Arg1->l
  56569. X#define LCMPLXtrig2(arg,out) Arg1->l = (arg); ltrig2(); (out)=Arg1->l
  56570. X#define LCMPLXtrig3(arg,out) Arg1->l = (arg); ltrig3(); (out)=Arg1->l
  56571. X
  56572. X#endif /* XFRACT */
  56573. X
  56574. X#define  CMPLXtrig0(arg,out) Arg1->d = (arg); dtrig0(); (out)=Arg1->d
  56575. X#define  CMPLXtrig1(arg,out) Arg1->d = (arg); dtrig1(); (out)=Arg1->d
  56576. X#define  CMPLXtrig2(arg,out) Arg1->d = (arg); dtrig2(); (out)=Arg1->d
  56577. X#define  CMPLXtrig3(arg,out) Arg1->d = (arg); dtrig3(); (out)=Arg1->d
  56578. X
  56579. X#ifndef XFRACT
  56580. X
  56581. X#define LCMPLXsin(arg,out)   Arg1->l = (arg); lStkSin();  (out) = Arg1->l
  56582. X#define LCMPLXcos(arg,out)   Arg1->l = (arg); lStkCos();  (out) = Arg1->l
  56583. X#define LCMPLXsinh(arg,out)  Arg1->l = (arg); lStkSinh(); (out) = Arg1->l
  56584. X#define LCMPLXcosh(arg,out)  Arg1->l = (arg); lStkCosh(); (out) = Arg1->l
  56585. X#define LCMPLXlog(arg,out)   Arg1->l = (arg); lStkLog();  (out) = Arg1->l
  56586. X#define LCMPLXexp(arg,out)   Arg1->l = (arg); lStkExp();  (out) = Arg1->l
  56587. X/*
  56588. X#define LCMPLXsqr(arg,out)   Arg1->l = (arg); lStkSqr();  (out) = Arg1->l
  56589. X*/
  56590. X#define LCMPLXsqr(arg,out)   \
  56591. X   (out).x = lsqr((arg).x) - lsqr((arg).y);\
  56592. X   (out).y = multiply((arg).x, (arg).y, bitshiftless1)
  56593. X#define LCMPLXsqr_old(out)     \
  56594. X   (out).y = multiply(lold.x, lold.y, bitshiftless1);\
  56595. X   (out).x = ltempsqrx - ltempsqry\
  56596. X
  56597. X#define LCMPLXpwr(arg1,arg2,out)    Arg2->l = (arg1); Arg1->l = (arg2);\
  56598. X     lStkPwr(); Arg1++; Arg2++; (out) = Arg2->l
  56599. X#define LCMPLXmult(arg1,arg2,out)    Arg2->l = (arg1); Arg1->l = (arg2);\
  56600. X     lStkMul(); Arg1++; Arg2++; (out) = Arg2->l
  56601. X#define LCMPLXadd(arg1,arg2,out)    \
  56602. X    (out).x = (arg1).x + (arg2).x; (out).y = (arg1).y + (arg2).y
  56603. X#define LCMPLXsub(arg1,arg2,out)    \
  56604. X    (out).x = (arg1).x - (arg2).x; (out).y = (arg1).y - (arg2).y
  56605. X
  56606. X#define LCMPLXtimesreal(arg,real,out)    \
  56607. X    (out).x = multiply((arg).x,(real),bitshift);\
  56608. X    (out).y = multiply((arg).y,(real),bitshift)
  56609. X
  56610. X#define LCMPLXrecip(arg,out)    \
  56611. X{ long denom; denom = lsqr((arg).x) + lsqr((arg).y);\
  56612. Xif(denom==0L) overflow=1; else {(out).x = divide((arg).x,denom,bitshift);\
  56613. X(out).y = -divide((arg).y,denom,bitshift);}}
  56614. X#endif /* XFRACT */
  56615. X
  56616. X#define CMPLXsin(arg,out)    Arg1->d = (arg); dStkSin();  (out) = Arg1->d
  56617. X#define CMPLXcos(arg,out)    Arg1->d = (arg); dStkCos();  (out) = Arg1->d
  56618. X#define CMPLXsinh(arg,out)   Arg1->d = (arg); dStkSinh(); (out) = Arg1->d
  56619. X#define CMPLXcosh(arg,out)   Arg1->d = (arg); dStkCosh(); (out) = Arg1->d
  56620. X#define CMPLXlog(arg,out)    Arg1->d = (arg); dStkLog();  (out) = Arg1->d
  56621. X#define CMPLXexp(arg,out)    FPUcplxexp(&(arg), &(out))
  56622. X/*
  56623. X#define CMPLXsqr(arg,out)    Arg1->d = (arg); dStkSqr();  (out) = Arg1->d
  56624. X*/
  56625. X#define CMPLXsqr(arg,out)    \
  56626. X   (out).x = sqr((arg).x) - sqr((arg).y);\
  56627. X   (out).y = ((arg).x+(arg).x) * (arg).y
  56628. X#define CMPLXsqr_old(out)    \
  56629. X   (out).y = (old.x+old.x) * old.y;\
  56630. X   (out).x = tempsqrx - tempsqry
  56631. X
  56632. X#define CMPLXpwr(arg1,arg2,out)   (out)= ComplexPower((arg1), (arg2))
  56633. X#define CMPLXmult1(arg1,arg2,out)    Arg2->d = (arg1); Arg1->d = (arg2);\
  56634. X     dStkMul(); Arg1++; Arg2++; (out) = Arg2->d
  56635. X#define CMPLXmult(arg1,arg2,out)  \
  56636. X    {\
  56637. X       _CMPLX TmP;\
  56638. X       TmP.x = (arg1).x*(arg2).x - (arg1).y*(arg2).y;\
  56639. X       TmP.y = (arg1).x*(arg2).y + (arg1).y*(arg2).x;\
  56640. X       (out) = TmP;\
  56641. X     }
  56642. X#define CMPLXadd(arg1,arg2,out)    \
  56643. X    (out).x = (arg1).x + (arg2).x; (out).y = (arg1).y + (arg2).y
  56644. X#define CMPLXsub(arg1,arg2,out)    \
  56645. X    (out).x = (arg1).x - (arg2).x; (out).y = (arg1).y - (arg2).y
  56646. X#define CMPLXtimesreal(arg,real,out)   \
  56647. X    (out).x = (arg).x*(real);\
  56648. X    (out).y = (arg).y*(real)
  56649. X
  56650. X#define CMPLXrecip(arg,out)    \
  56651. X   { double denom; denom = sqr((arg).x) + sqr((arg).y);\
  56652. X     if(denom==0.0) {(out).x = 1.0e10;(out).y = 1.0e10;}else\
  56653. X    { (out).x =  (arg).x/denom;\
  56654. X     (out).y = -(arg).y/denom;}}
  56655. X
  56656. X#endif
  56657. SHAR_EOF
  56658. $TOUCH -am 1028230093 mpmath.h &&
  56659. chmod 0644 mpmath.h ||
  56660. echo "restore of mpmath.h failed"
  56661. set `wc -c mpmath.h`;Wc_c=$1
  56662. if test "$Wc_c" != "7413"; then
  56663.     echo original size 7413, current size $Wc_c
  56664. fi
  56665. # ============= targa.h ==============
  56666. echo "x - extracting targa.h (Text)"
  56667. sed 's/^X//' << 'SHAR_EOF' > targa.h &&
  56668. X/* targa.h */
  56669. X
  56670. X
  56671. X#ifndef TARGA_H
  56672. X#define TARGA_H
  56673. X
  56674. X#ifndef XFRACT
  56675. X#include    <dos.h>
  56676. X#endif
  56677. X
  56678. X
  56679. Xextern unsigned int _dataseg_xx;
  56680. X
  56681. X/****************************************************************/
  56682. X
  56683. X#ifdef __TURBOC__
  56684. X#    define        PEEK(a,b,c,d)        movedata( b, a, _DS, c, d)
  56685. X#    define        POKE(a,b,c,d)        movedata( _DS, c, b, a, d )
  56686. X#    define        OUTPORTB    outportb
  56687. X#    define        INPORTB     inportb
  56688. X#    define        OUTPORTW    outport
  56689. X#    define        INPORTW     inport
  56690. X#else
  56691. X#    define        PEEK(a,b,c,d)        movedata( b, a, _dataseg_xx, c, d)
  56692. X#    define        POKE(a,b,c,d)        movedata( _dataseg_xx, c, b, a, d )
  56693. X#    define        OUTPORTB    outp
  56694. X#    define        INPORTB     inp
  56695. X#    define        OUTPORTW    outpw
  56696. X#    define        INPORTW     inpw
  56697. X#endif
  56698. X
  56699. X#define  FALSE    0
  56700. X#ifdef TRUE
  56701. X#undef TRUE
  56702. X#endif
  56703. X#define  TRUE    1
  56704. X
  56705. X/****************************************************************/
  56706. X
  56707. X#define TSEG            0xA000
  56708. X#define TIOBASE     0x220
  56709. X
  56710. X
  56711. X/****************************************************************/
  56712. X
  56713. X
  56714. X#define     TYPE_8        8
  56715. X#define     TYPE_16     16
  56716. X#define     TYPE_24     24
  56717. X#define     TYPE_32     32
  56718. X#define     TYPE_M8     -8
  56719. X
  56720. X/*
  56721. X * TARGA: 400 to 482 rows x 512 pixels/row X 16 bits/pixel
  56722. X */
  56723. X
  56724. X#define XMIN        0
  56725. X#define YMIN        0
  56726. X#define XMAX        512            /* maximum X value */
  56727. X#define YMAX        512            /* maximum Y value */
  56728. X#define XRES        512            /* X resolution */
  56729. X#define YRES        512            /* Y Resolution */
  56730. X#define YVISMAX     (2*targa.LinesPerField) /* Maximum visible Y coordinate */
  56731. X#define YVISMIN     0            /* Minimum visible Y coordiate */
  56732. X#define DEF_ROWS    400            /* Default number of rows */
  56733. X
  56734. X#define IOBASE        targa.iobase        /* io base location of graphics registers */
  56735. X#define MEMSEG        targa.memloc        /*  use the variable so we can use */
  56736. X#define SCNSEG        targa.memloc        /*  the one defined in TARGA */
  56737. X#define SRCBANK     (targa.memloc+0x0800)    /*  use high-bank as source bank */
  56738. X#define DESTBANK    targa.memloc        /*  use lo-bank as destination bank */
  56739. X
  56740. X/*    Output register definitions     */
  56741. X#define MODEREG     (IOBASE+0xC00)    /* Mode Register address */
  56742. X#define MASKREG     (IOBASE+0x800)    /* Mask Registers */
  56743. X#define UNDERREG    (IOBASE+0x800)    /* Underscan register */
  56744. X#define OVERREG     (IOBASE+0x802)    /* overscan register */
  56745. X#define DESTREG     (IOBASE+0x802)    /* Address of Page Select Lower Register */
  56746. X#define SRCREG        (IOBASE+0x803)    /* Address of Page Select Upper Register */
  56747. X#define VCRCON        (IOBASE+0x400)    /* Address of Contrast/VidSrc Register */
  56748. X#define BLNDREG     VCRCON
  56749. X#define SATHUE        (IOBASE+0x402)    /* Satuation/Hue Register address */
  56750. X#define DRREG        (IOBASE+0x401)    /* ADDRESS OF Controller Write Register */
  56751. X#define VERTPAN     (IOBASE+0x403)    /* Address of Vertical Pan Register */
  56752. X#define BORDER        (IOBASE)    /* Address of Page Select Lower Register */
  56753. X
  56754. X/*    Input register definitions  */
  56755. X#define VIDEOSTATUS    (IOBASE+0xC02)    /* Video Status Register */
  56756. X#define RASTERREG    (IOBASE+0xC00)    /* Raster counter register */
  56757. X
  56758. X/*    Default register values     */
  56759. X#define DEF_MODE 1            /* Default mode register value */
  56760. X                                                            /*    Memory selected, 512x512, 1x */
  56761. X                                                            /*    Display mode */
  56762. X#define DEF_MASK    0        /* default memory mask */
  56763. X#define DEF_SATURATION    0x4        /* default saturation value */
  56764. X#define DEF_HUE     0x10        /* default hue value */
  56765. X#define DEF_CONTRAST    0x10        /* default contrast value */
  56766. X#define DEF_VIDSRC    0        /* default video source value - Composite */
  56767. X#define DEF_VERTPAN    56        /* assumes 400-line output */
  56768. X#define DEF_BORDER    0        /* default border color */
  56769. X
  56770. X
  56771. X/*    MASK AND SHIFT VALUE FOR REGISTERS CONTAINING SUBFIELDS  */
  56772. X/*
  56773. X *        ******************************************************
  56774. X *                    MODE REGISTERS
  56775. X *        ******************************************************
  56776. X */
  56777. X#define MSK_MSEL    0xfffC        /* memory select bits */
  56778. X#define SHF_MSEL    0x0000
  56779. X#define MSEL        1
  56780. X
  56781. X#define MSK_IBIT    0xfffb        /* Interlace bit */
  56782. X#define SHF_IBIT    2
  56783. X
  56784. X#define MSK_RES     0xFFC7        /* disp. resolution and screen select bits */
  56785. X#define SHF_RES     3
  56786. X#define S0_512X512_0    0        /* 512x512 resolution screen */
  56787. X#define S1_512X512_1    1
  56788. X#define S2_512X256_0    2        /* 512x256 resolution screen 0 */
  56789. X#define S3_512X256_1    3        /* 512x256 resolution screen 1 */
  56790. X#define S4_256X256_0    4        /* 256x256 resolution screen 0 */
  56791. X#define S5_256X256_1    5        /*            ....        */
  56792. X#define S6_256X256_2    6
  56793. X#define S7_256X256_3    7
  56794. X
  56795. X#define MSK_REGWRITE    0xFFBF        /* mask for display register write */
  56796. X#define SHF_REGWRITE    6
  56797. X#define REGINDEX    0        /* to write an index value */
  56798. X#define REGVALUE    1        /* to write a value */
  56799. X
  56800. X#define MSK_BIT9    0xFF7F        /* maks for high-order bit of DR's */
  56801. X#define SHF_BIT9    7
  56802. X
  56803. X#define MSK_TAPBITS    0xFCFF        /* mask for setting the tap bits */
  56804. X#define SHF_TAPBITS    8
  56805. X
  56806. X#define MSK_ZOOM    0xF3FF        /* Mask for zoom factor */
  56807. X#define SHF_ZOOM    10
  56808. X
  56809. X#define MSK_DISPLAY    0xCFFF        /* Mask for display mode */
  56810. X#define SHF_DISPLAY    12
  56811. X#define MEMORY_MODE    0
  56812. X#define LIVE_FIXED    1
  56813. X#define OVERLAY_MODE    2
  56814. X#define LIVE_LIVE    3
  56815. X#define DEF_DISPLAY    0
  56816. X
  56817. X#define MSK_CAPTURE    0xBFFF        /* Mask for capture bit */
  56818. X#define SHF_CAPTURE    14
  56819. X
  56820. X#define MSK_GENLOCK    0x7FFF        /* MASK FOR GENLOCK */
  56821. X#define SHF_GENLOCK    15
  56822. X#define DEF_GENLOCK    0
  56823. X
  56824. X/*    Video status input register     */
  56825. X#define FIELDBIT    0x0001
  56826. X#define VIDEOLOSS    0x0002
  56827. X
  56828. X/*    VIDEO SOURCE/CONTROL REGISTER     */
  56829. X#define MSK_CONTRAST    0xFFC1
  56830. X#define SHF_CONTRAST    1
  56831. X#define MAX_CONTRAST    0x1f
  56832. X
  56833. X#define MSK_RGBORCV    0xBF
  56834. X#define SHF_RGBORCV    6
  56835. X#define RGB        1
  56836. X#define CV        0
  56837. X
  56838. X#define MSK_VCRORCAMERA 0x7F
  56839. X#define SHF_VCRORCAMERA 7
  56840. X#define VCR        1
  56841. X#define CAMERA        0
  56842. X
  56843. X/*    HUE/SATUATION REGISTER    */
  56844. X#define MSK_HUE     0xE0
  56845. X#define SHF_HUE     0
  56846. X#define MAX_HUE     0x1f
  56847. X
  56848. X#define MSK_SATURATION    0x1F
  56849. X#define SHF_SATURATION    5
  56850. X#define MAX_SATURATION    0x07
  56851. X
  56852. X
  56853. X/*
  56854. X *    *********************************************
  56855. X *            Display register settings
  56856. X *    *********************************************
  56857. X *
  56858. X *    Screen Positioning Registers:
  56859. X *        DR 0-3
  56860. X */
  56861. X#define LEFTBORDER    0
  56862. X#define DEF_LEFT    85
  56863. X#define MIN_LEFT    75
  56864. X#define MAX_LEFT    95
  56865. X#define RIGHTBORDER    1
  56866. X#define DEF_RIGHT    (DEF_LEFT+256)
  56867. X#define TOPBORDER    2
  56868. X#define DEF_TOP     40
  56869. X#define MIN_TOP     20
  56870. X#define BOTTOMBORDER    3
  56871. X#define DEF_BOTTOM    (DEFTOP+DEFROWS/2)
  56872. X#define MAX_BOTTOM    261
  56873. X
  56874. X/*    REgisters which track 0-3     */
  56875. X#define DR8        8
  56876. X#define PRESHIFT    DR8
  56877. X#define EQU_DR8     DR0
  56878. X#define DR9        9
  56879. X#define EQU_DR9     DR1
  56880. X#define DR10        10
  56881. X#define EQU_DR10    DR2
  56882. X#define DR11        11
  56883. X#define EQU_DR11    DR3
  56884. X
  56885. X/*    REQUIRED REGISTERS    */
  56886. X#define DR4        4
  56887. X#define DEF_DR4     352
  56888. X#define DR5        5
  56889. X#define DEF_DR5     1
  56890. X#define DR6        6
  56891. X#define DEF_DR6     0
  56892. X#define DR7        7
  56893. X#define DEF_DR7     511
  56894. X#define DR12        12
  56895. X#define DEF_DR12    20
  56896. X#define DR13        13
  56897. X#define DEF_DR13    22
  56898. X#define DR14        14
  56899. X#define DEF_DR14    0
  56900. X#define DR15        15
  56901. X#define DEF_DR15    511
  56902. X#define DR16        16
  56903. X#define DEF_DR16    0
  56904. X#define DR17        17
  56905. X#define DEF_DR17    0
  56906. X#define DR18        18
  56907. X#define DEF_DR18    0
  56908. X#define DR19        19
  56909. X#define DEF_DR19    4
  56910. X
  56911. X/* interlace mode register & parameters */
  56912. X#define DR20        20
  56913. X#define INTREG        0x14
  56914. X#define DEF_INT     0        /* default to interlace mode 0 */
  56915. X#define MSK_INTERLACE    0x0003
  56916. X
  56917. X/**************************************************************/
  56918. X
  56919. X
  56920. Xtypedef struct {
  56921. X            /*    Board Configuration */
  56922. X    int        memloc;     /* memory segment */
  56923. X    int        iobase;     /*  IOBASE segment */
  56924. X    int        BytesPerPixel;    /* number of words per pixel */
  56925. X    int        RowsPerBank;    /* number of row per 64K bank */
  56926. X    int        MaxBanks;    /*   maximum bank id */
  56927. X    int        AddressShift;    /*   number of bits to shift address */
  56928. X
  56929. X        /*    Control registers */
  56930. X    int        mode;        /*  mode register */
  56931. X    int        Mask;        /*  mask register */
  56932. X    int        PageMode;    /*  current page mode (screen res. and page) */
  56933. X    unsigned    PageLower;    /*  Lower Page Select register */
  56934. X    unsigned    PageUpper;    /*  upper Page select register */
  56935. X    int        VCRCon;     /*  VCRContract register */
  56936. X    int        SatHue;     /* Hue and Saturation register */
  56937. X    long        BorderColor;    /*  Border color register */
  56938. X    int        VertShift;    /*  Vertical Pan Register */
  56939. X    int        PanXOrig, PanYOrig;    /* x,y pan origin */
  56940. X
  56941. X        /* TARGA-SET PARAMETERS */
  56942. X    int    boardType;        /*  See TYPE_XX  IN THIS FILE */
  56943. X        /*  FOR DEFINITION OF Board Types */
  56944. X    int    xOffset;        /*  X-offset */
  56945. X    int    yOffset;        /*  Y-Offset */
  56946. X    int    LinesPerField;        /*  maximum visible row count */
  56947. X    int    InterlaceMode;        /*  desired interlace mode */
  56948. X    int    AlwaysGenLock;        /*  Genlock always on or not  */
  56949. X    int    Contrast;        /*  Desired Contrast */
  56950. X    int    Hue;            /*  Desired Hue */
  56951. X    int    Saturation;        /*  Desired Satuation */
  56952. X    int    RGBorCV;        /*  CV or RGB Input */
  56953. X    int    VCRorCamera;        /*  VCR or Camera */
  56954. X    int    ovrscnAvail, ovrscnOn;    /*  ovrscnAvail  1  if Overscan installed */
  56955. X                                                            /*  ovrscnOn  1 if overscan is stretching */
  56956. X        /*    Display Registers */
  56957. X    int    DisplayRegister[22];
  56958. X
  56959. X} TARStruct;
  56960. X
  56961. X
  56962. X/****************************************************************/
  56963. X/*  Data Definitions */
  56964. X
  56965. X#ifdef TARGA_DATA
  56966. X#        define    _x_
  56967. X#        define    eq( val )    =val
  56968. X#else
  56969. X#        define    _x_    extern
  56970. X#        define    eq( val )
  56971. X#endif
  56972. X
  56973. X_x_ int tseg        eq(    TSEG );
  56974. X_x_ int tiobase eq(    TIOBASE );
  56975. X
  56976. X_x_ TARStruct        targa;
  56977. X
  56978. X#undef    _x_
  56979. X#undef    eq
  56980. X
  56981. X#endif
  56982. X
  56983. SHAR_EOF
  56984. $TOUCH -am 1028230093 targa.h &&
  56985. chmod 0644 targa.h ||
  56986. echo "restore of targa.h failed"
  56987. set `wc -c targa.h`;Wc_c=$1
  56988. if test "$Wc_c" != "8664"; then
  56989.     echo original size 8664, current size $Wc_c
  56990. fi
  56991. # ============= targa_lc.h ==============
  56992. echo "x - extracting targa_lc.h (Text)"
  56993. sed 's/^X//' << 'SHAR_EOF' > targa_lc.h &&
  56994. X#ifndef TARGA_LC_H
  56995. X#define TARGA_LC_H
  56996. X
  56997. X#define HEADERSIZE 18        /* Size, offsets, and masks for the */
  56998. X#define O_COMMENTLEN 0        /* TGA file header.  This is not a    */
  56999. X#define O_MAPTYPE 1            /* structure to avoid problems with    */
  57000. X#define O_FILETYPE 2        /* byte-packing and such.            */
  57001. X#define O_MAPORG 3
  57002. X#define O_MAPLEN 5
  57003. X#define O_MAPSIZE 7
  57004. X#define O_XORIGIN 8
  57005. X#define O_YORIGIN 10
  57006. X#define O_HSIZE 12
  57007. X#define O_VSIZE 14
  57008. X#define O_ESIZE 16
  57009. X#define O_FLAGS 17
  57010. X#define M_ORIGIN 0x20
  57011. X
  57012. X#define    T_NODATA 0
  57013. X#define T_RAWMAP 1
  57014. X#define T_RAWRGB 2
  57015. X#define T_RAWMON 3
  57016. X#define T_RLEMAP 9
  57017. X#define T_RLERGB 10
  57018. X#define T_RLEMON 11
  57019. X
  57020. X#endif
  57021. SHAR_EOF
  57022. $TOUCH -am 1028230093 targa_lc.h &&
  57023. chmod 0644 targa_lc.h ||
  57024. echo "restore of targa_lc.h failed"
  57025. set `wc -c targa_lc.h`;Wc_c=$1
  57026. if test "$Wc_c" != "618"; then
  57027.     echo original size 618, current size $Wc_c
  57028. fi
  57029. # ============= tplus.h ==============
  57030. echo "x - extracting tplus.h (Text)"
  57031. sed 's/^X//' << 'SHAR_EOF' > tplus.h &&
  57032. X/* TPLUS.H, (C) 1991 The Yankee Programmer
  57033. X   All Rights Reserved
  57034. X   
  57035. X   This code may be distributed only when bundled with the Fractint 
  57036. X   source code.
  57037. X   
  57038. X   Mark C. Peterson
  57039. X   The Yankee Programmer
  57040. X   405-C Queen Street, Suite #181
  57041. X   Southington, CT 06489
  57042. X   (203) 276-9721
  57043. X   
  57044. X*/
  57045. X
  57046. X#ifndef TPLUS_H
  57047. X#define TPLUS_H
  57048. X
  57049. X#ifdef CTL
  57050. X#undef CTL
  57051. X#endif
  57052. X
  57053. X#ifdef __TURBOC__
  57054. X#define        OUTPORTB    outportb
  57055. X#define        INPORTB     inportb
  57056. X#define        OUTPORTW    outport
  57057. X#define        INPORTW     inport
  57058. X#else
  57059. X#define        OUTPORTB    outp
  57060. X#define        INPORTB     inp
  57061. X#define        OUTPORTW    outpw
  57062. X#define        INPORTW     inpw
  57063. X#endif
  57064. X
  57065. Xstruct TPWrite {
  57066. X   unsigned 
  57067. X      COLOR0,  COLOR1,  COLOR2,  COLOR3,  VIDCON,  INDIRECT,   HUESAT,
  57068. X      OVSTRT,  MASKL,   MASKH,   LBNK,    HBNK,    MODE1,      MODE2,    
  57069. X      WBL,     WBH;
  57070. X};
  57071. X
  57072. Xstruct TPRead {
  57073. X   unsigned
  57074. X      VIDSTAT,          CTL,     MASKL,   LBNK,    READAD,     MODE1,       
  57075. X      OVSTRT,  USCAN,   MASKH,   OSCAN,   HBNK,    ROWCNT,     MODE2,
  57076. X      RBL,     RBH;
  57077. X};
  57078. X
  57079. X/* TPlus Register Data Offsets */
  57080. X#define     XDOTS       0
  57081. X#define     YDOTS       1
  57082. X#define     ASP_RATIO   2
  57083. X#define     DEPTH       4
  57084. X#define     PAGE        5
  57085. X#define     BOTBANK     7
  57086. X#define     TOPBANK     8
  57087. X#define     ZOOM        10
  57088. X#define     DISPMODE    11
  57089. X#define     DAC567DATA  15
  57090. X#define     VTOP        19
  57091. X#define     TOP         51
  57092. X#define     BOT         53
  57093. X#define     VPAN        55
  57094. X#define     NOT_INT     56
  57095. X#define     HIRES       61
  57096. X#define     PERM        64
  57097. X#define     BYCAP       68
  57098. X#define     PE          69
  57099. X#define     OVLE        70
  57100. X#define     HPAN        71
  57101. X#define     MEM_BASE    73
  57102. X#define     MEM_MAP     74
  57103. X#define     LIVEMIXSRC  91
  57104. X#define     RGB         93
  57105. X#define     SVIDEO      97
  57106. X#define     BUFFPORTSRC 98
  57107. X#define     CM1         101
  57108. X#define     CM2         102
  57109. X#define     LUTBYPASS   107
  57110. X#define     CM3         113
  57111. X#define     LIVEPORTSRC 115
  57112. X#define     LIVE8       116
  57113. X#define     VGASRC      123
  57114. X
  57115. Xstruct _BOARD {
  57116. X   int ThisBoard, ClearScreen;
  57117. X   BYTE far *Screen;
  57118. X   unsigned VerPan, HorPan, Top, Bottom;
  57119. X   unsigned xdots, ydots, Bank64k, RowBytes, RowsPerBank;
  57120. X   unsigned Reg[128];
  57121. X#ifndef XFRACT
  57122. X   void (*Plot)(int x, int y, unsigned long Color);
  57123. X   unsigned long (*GetColor)(int x, int y);
  57124. X#else
  57125. X   void (*Plot)();
  57126. X   unsigned long (*GetColor)();
  57127. X#endif
  57128. X
  57129. X   struct TPRead Read;
  57130. X   struct TPWrite Write;
  57131. X};
  57132. X
  57133. Xextern struct _BOARD far TPlus;
  57134. X
  57135. X#endif
  57136. SHAR_EOF
  57137. $TOUCH -am 1028230093 tplus.h &&
  57138. chmod 0644 tplus.h ||
  57139. echo "restore of tplus.h failed"
  57140. set `wc -c tplus.h`;Wc_c=$1
  57141. if test "$Wc_c" != "2388"; then
  57142.     echo original size 2388, current size $Wc_c
  57143. fi
  57144. # ============= prototyp.h ==============
  57145. echo "x - extracting prototyp.h (Text)"
  57146. sed 's/^X//' << 'SHAR_EOF' > prototyp.h &&
  57147. X/* includes needed to define the prototypes */
  57148. X
  57149. X#include <stdio.h>
  57150. X#include "mpmath.h"
  57151. X#include "port.h"
  57152. X#include "fractint.h"
  57153. X#include "helpcom.h"
  57154. X
  57155. X/*  calcmand -- assembler file prototypes */
  57156. X
  57157. Xextern int cdecl calcmandasm();
  57158. X
  57159. X/*  calmanfp -- assembler file prototypes */
  57160. X
  57161. Xextern void cdecl calcmandfpasmstart();
  57162. Xextern int  cdecl calcmandfpasm();
  57163. X
  57164. X/*  fpu087 -- assembler file prototypes */
  57165. X
  57166. Xextern void cdecl FPUcplxmul(_CMPLX *, _CMPLX *, _CMPLX *);
  57167. Xextern void cdecl FPUcplxdiv(_CMPLX *, _CMPLX *, _CMPLX *);
  57168. Xextern void cdecl FPUsincos(double *, double *, double *);
  57169. Xextern void cdecl FPUsinhcosh(double *, double *, double *);
  57170. Xextern void cdecl FPUcplxlog(_CMPLX *, _CMPLX *);
  57171. Xextern void cdecl SinCos086(long , long *, long *);
  57172. Xextern void cdecl SinhCosh086(long , long *, long *);
  57173. Xextern long far cdecl r16Mul(long , long );
  57174. Xextern long far cdecl RegFloat2Fg(long , int );
  57175. Xextern long cdecl Exp086(long);
  57176. Xextern unsigned long far cdecl ExpFudged(long , int );
  57177. Xextern long far cdecl RegDivFloat(long , long );
  57178. Xextern long far cdecl LogFudged(unsigned long , int );
  57179. Xextern long far cdecl LogFloat14(unsigned long );
  57180. X#ifndef XFRACT
  57181. Xextern long far cdecl RegFg2Float(long, char);
  57182. Xextern long far cdecl RegSftFloat(long, char);
  57183. X#else
  57184. Xextern long far cdecl RegFg2Float(long , int );
  57185. Xextern long far cdecl RegSftFloat(long , int );
  57186. X#endif
  57187. X
  57188. X/*  fpu387 -- assembler file prototypes */
  57189. X
  57190. Xextern void cdecl FPUaptan387(double *, double *, double *);
  57191. Xextern void cdecl FPUcplxexp387(_CMPLX *, _CMPLX *);
  57192. X
  57193. X/*  fracsuba -- assembler file prototypes */
  57194. X
  57195. Xextern int cdecl  longbailout( void );
  57196. Xextern int FManOWarfpFractal( void );
  57197. Xextern int FJuliafpFractal( void );
  57198. Xextern int FBarnsley1FPFractal( void );
  57199. Xextern int FBarnsley2FPFractal( void );
  57200. Xextern int FLambdaFPFractal( void );
  57201. X
  57202. X/*  general -- assembler file prototypes */
  57203. X
  57204. Xextern  long   cdecl multiply(long, long, int);
  57205. Xextern  long   cdecl divide(long, long, int);
  57206. Xextern  int    cdecl getakey(void);
  57207. Xextern  void   cdecl buzzer(int);
  57208. Xextern  void   cdecl farmemfree(VOIDFARPTR );
  57209. Xextern  int    cdecl far_strlen( char far *);
  57210. Xextern  int    cdecl far_strnicmp(char far *, char far *,int);
  57211. Xextern  void   cdecl far_strcpy( char far *, char far *);
  57212. Xextern  int    cdecl far_strcmp( char far *, char far *);
  57213. Xextern  void   cdecl far_stricmp(char far *, char far *);
  57214. Xextern  void   cdecl far_strcat( char far *, char far *);
  57215. Xextern  void   cdecl far_memset( VOIDFARPTR , int      , int);
  57216. Xextern  void   cdecl far_memcpy( VOIDFARPTR , VOIDFARPTR , int);
  57217. Xextern  int    cdecl far_memcmp( VOIDFARPTR , VOIDFARPTR , int);
  57218. Xextern  void   cdecl far_memicmp(VOIDFARPTR , VOIDFARPTR , int);
  57219. Xextern  void   cdecl emmdeallocate(unsigned int);
  57220. Xextern  void   cdecl emmgetpage(unsigned int, unsigned int);
  57221. Xextern  void   cdecl emmclearpage(unsigned int, unsigned int);
  57222. Xextern  int    cdecl keypressed(void);
  57223. Xextern  long   cdecl readticker( void );
  57224. Xextern  void   cdecl emmdeallocate(unsigned int);
  57225. Xextern  void   cdecl xmmdeallocate(unsigned int);
  57226. Xextern  void   cdecl snd( int );
  57227. Xextern  void   cdecl nosnd( void );
  57228. Xextern  void   cdecl initasmvars( void );
  57229. X
  57230. X#ifndef __BORLANDC__
  57231. Xextern  void   cdecl enable( void );
  57232. Xextern  void   cdecl disable( void );
  57233. Xextern  void   cdecl delay( int );
  57234. X#endif
  57235. X
  57236. Xextern  int    cdecl farread(int, VOIDFARPTR, unsigned);
  57237. Xextern  int    cdecl farwrite(int, VOIDFARPTR, unsigned);
  57238. Xextern  long   cdecl normalize(char far *);
  57239. Xextern  unsigned int cdecl xmmmoveextended(struct XMM_Move *);
  57240. Xextern  void   cdecl erasesegment(int, int);
  57241. Xextern  int    cdecl IITCoPro( void );
  57242. Xextern  int    cdecl F4x4Check( void );
  57243. Xextern  int    cdecl F4x4Lock( void );
  57244. Xextern  void   cdecl F4x4Free( void );
  57245. Xextern  int    cdecl getakeynohelp( void );
  57246. Xextern  unsigned int cdecl cmpextra( unsigned int, char *, int );
  57247. Xextern  unsigned int cdecl fromextra( unsigned int, char *, int );
  57248. Xextern  unsigned int cdecl toextra( unsigned int, char *, int );
  57249. Xextern  void   cdecl load_mat(double (*)[4]);
  57250. Xextern  VOIDFARPTR cdecl farmemalloc(long);
  57251. Xextern  unsigned int *cdecl xmmquery(void);
  57252. Xextern  BYTE far *cdecl emmquery(void);
  57253. Xextern  unsigned int cdecl emmgetfree(void);
  57254. Xextern  unsigned int cdecl emmallocate(unsigned int);
  57255. Xextern  unsigned int cdecl emmallocate(unsigned int);
  57256. Xextern  unsigned int cdecl xmmallocate(unsigned int);
  57257. Xextern  void   mult_vec_iit(VECTOR);
  57258. X
  57259. X/*  lsysa -- assembler file prototypes */
  57260. X
  57261. Xextern void lsys_doplus(long);
  57262. Xextern void lsys_doplus_pow2(long);
  57263. Xextern void lsys_dominus(long);
  57264. Xextern void lsys_dominus_pow2(long);
  57265. Xextern void lsys_dopipe_pow2(long);
  57266. Xextern void lsys_dobang(long);
  57267. X
  57268. X#ifndef XFRACT
  57269. Xextern void lsys_doslash_386(long);
  57270. Xextern void lsys_dobslash_386(long);
  57271. Xextern void lsys_doat_386(long);
  57272. Xextern void lsys_dosizegf_386(long);
  57273. Xextern void lsys_dodrawg_386(long);
  57274. X#endif
  57275. X
  57276. X/*  mpmath_a -- assembler file prototypes */
  57277. X
  57278. Xextern struct MP * MPmul086(struct MP , struct MP );
  57279. Xextern struct MP * MPdiv086(struct MP , struct MP );
  57280. Xextern struct MP * MPadd086(struct MP , struct MP );
  57281. Xextern int         MPcmp086(struct MP , struct MP );
  57282. Xextern struct MP * d2MP086(double );
  57283. Xextern double    * MP2d086(struct MP );
  57284. Xextern struct MP * fg2MP086(long , int );
  57285. Xextern struct MP * MPmul386(struct MP , struct MP );
  57286. Xextern struct MP * MPdiv386(struct MP , struct MP );
  57287. Xextern struct MP * MPadd386(struct MP , struct MP );
  57288. Xextern int         MPcmp386(struct MP , struct MP );
  57289. Xextern struct MP * d2MP386(double );
  57290. Xextern double    * MP2d386(struct MP );
  57291. Xextern struct MP * fg2MP386(long , int );
  57292. Xextern double *    MP2d(struct MP );
  57293. Xextern int         MPcmp(struct MP , struct MP );
  57294. Xextern struct MP * MPmul(struct MP , struct MP );
  57295. Xextern struct MP * MPadd(struct MP , struct MP );
  57296. Xextern struct MP * MPdiv(struct MP , struct MP );
  57297. Xextern struct MP * d2MP(double );  /* Convert double to type MP */
  57298. Xextern struct MP * fg2MP(long , int ); /* Convert fudged to type MP */
  57299. X
  57300. X/*  newton -- assembler file prototypes */
  57301. X
  57302. Xextern int cdecl    NewtonFractal2( void );
  57303. Xextern void cdecl   invertz2(_CMPLX *);
  57304. X
  57305. X/*  tplus_a -- assembler file prototypes */
  57306. X
  57307. Xextern void WriteTPlusBankedPixel(int, int, unsigned long);
  57308. Xextern unsigned long ReadTPlusBankedPixel(int, int);
  57309. X
  57310. X/*  video -- assembler file prototypes */
  57311. X
  57312. Xextern void   cdecl adapter_detect(void);
  57313. Xextern void   cdecl clearbox(void);
  57314. Xextern void   cdecl dispbox(void);
  57315. Xextern void   cdecl setvideotext(void);
  57316. Xextern void   cdecl setnullvideo(void);
  57317. Xextern void   cdecl setfortext(void);
  57318. Xextern void   cdecl setforgraphics(void);
  57319. Xextern void   cdecl swapnormwrite(void);
  57320. Xextern void   cdecl setclear(void);
  57321. Xextern int    cdecl SetupShadowVideo(void);
  57322. Xextern int    cdecl ShadowVideo(int);
  57323. Xextern int    cdecl keycursor(int,int);
  57324. Xextern void   cdecl swapnormread(void);
  57325. Xextern void   cdecl setvideomode(int, int, int, int);
  57326. Xextern void   cdecl movewords(int,BYTE far*,BYTE far*);
  57327. Xextern void   cdecl movecursor(int, int);
  57328. Xextern void   cdecl get_line(int, int, int, BYTE *);
  57329. Xextern void   cdecl put_line(int, int, int, BYTE *);
  57330. Xextern void   cdecl setattr(int, int, int, int);
  57331. Xextern void   cdecl putstring(int,int,int,CHAR far *);
  57332. Xextern void   cdecl spindac(int, int);
  57333. Xextern void   cdecl find_special_colors(void);
  57334. Xextern char   cdecl get_a_char(void);
  57335. Xextern void   cdecl put_a_char(int);
  57336. Xextern void   cdecl scrollup(int, int);
  57337. Xextern void   cdecl home(void);
  57338. Xextern BYTE far *cdecl  findfont(int);
  57339. Xextern int _fastcall getcolor(int, int);
  57340. Xextern void _fastcall putcolor(int, int, int);
  57341. Xextern int  out_line(BYTE *, int);
  57342. Xextern void   (*swapsetup)(void);
  57343. X
  57344. X/*  3d -- C file prototypes */
  57345. X
  57346. Xextern void identity(MATRIX);
  57347. Xextern void mat_mul(MATRIX,MATRIX,MATRIX);
  57348. Xextern void scale(double ,double ,double ,MATRIX);
  57349. Xextern void xrot(double ,MATRIX);
  57350. Xextern void yrot(double ,MATRIX);
  57351. Xextern void zrot(double ,MATRIX);
  57352. Xextern void trans(double ,double ,double ,MATRIX);
  57353. Xextern int cross_product(VECTOR,VECTOR,VECTOR);
  57354. Xextern int normalize_vector(VECTOR);
  57355. Xextern int vmult(VECTOR,MATRIX,VECTOR);
  57356. Xextern void mult_vec_c(VECTOR);
  57357. Xextern int perspective(VECTOR);
  57358. Xextern int longvmultpersp(LVECTOR,LMATRIX,LVECTOR,LVECTOR,LVECTOR,int);
  57359. Xextern int longpersp(LVECTOR,LVECTOR,int );
  57360. Xextern int longvmult(LVECTOR,LMATRIX,LVECTOR,int );
  57361. X
  57362. X/*  calcfrac -- C file prototypes */
  57363. X
  57364. Xextern void calcfrac_overlay(void);
  57365. Xextern int calcfract(void);
  57366. Xextern int calcmand(void);
  57367. Xextern int calcmandfp(void);
  57368. Xextern int StandardFractal(void);
  57369. Xextern int test(void);
  57370. Xextern int plasma(void);
  57371. Xextern int diffusion(void);
  57372. Xextern int Bifurcation(void );
  57373. Xextern int BifurcLambda(void);
  57374. Xextern int BifurcSetTrigPi(void);
  57375. Xextern int LongBifurcSetTrigPi(void);
  57376. Xextern int BifurcAddTrigPi(void);
  57377. Xextern int LongBifurcAddTrigPi(void);
  57378. Xextern int BifurcMay(void);
  57379. Xextern int BifurcMaySetup(void);
  57380. Xextern int LongBifurcMay(void);
  57381. Xextern int BifurcLambdaTrig(void);
  57382. Xextern int LongBifurcLambdaTrig(void);
  57383. Xextern int BifurcVerhulstTrig(void);
  57384. Xextern int LongBifurcVerhulstTrig(void);
  57385. Xextern int BifurcStewartTrig(void);
  57386. Xextern int LongBifurcStewartTrig(void);
  57387. Xextern int popcorn(void);
  57388. Xextern int lyapunov(void);
  57389. Xextern int lya_setup(void);
  57390. Xextern int cellular(void);
  57391. Xextern int CellularSetup(void);
  57392. Xextern int calcfroth(void);
  57393. Xextern int froth_setup(void);
  57394. Xextern int demowalk(void);
  57395. X
  57396. X/*  cmdfiles -- C file prototypes */
  57397. X
  57398. Xextern void cmdfiles_overlay(void);
  57399. Xextern int cmdfiles(int ,char **);
  57400. Xextern int load_commands(FILE *);
  57401. Xextern void set_3d_defaults(void);
  57402. X
  57403. X/*  decoder -- C file prototypes */
  57404. X
  57405. Xextern short decoder(short );
  57406. X
  57407. X/*  diskvid -- C file prototypes */
  57408. X
  57409. Xextern int startdisk(void);
  57410. Xextern int pot_startdisk(void);
  57411. Xextern int targa_startdisk(FILE *,int );
  57412. Xextern void enddisk(void);
  57413. X#ifndef XFRACT
  57414. Xextern int readdisk(unsigned int, unsigned int );
  57415. Xextern void writedisk(unsigned int, unsigned int, unsigned int );
  57416. X#else
  57417. Xextern int readdisk(int, int );
  57418. Xextern void writedisk(int, int, int );
  57419. X#endif
  57420. Xextern void targa_writedisk(unsigned int ,unsigned int ,BYTE ,BYTE ,BYTE );
  57421. Xextern void dvid_status(int ,char *);
  57422. X
  57423. X/*  editpal -- C file prototypes */
  57424. X
  57425. Xextern void EditPalette(void );
  57426. Xextern VOIDPTR mem_alloc(unsigned size);
  57427. Xvoid putrow(int x, int y, int width, char *buff);
  57428. Xvoid getrow(int x, int y, int width, char *buff);
  57429. Xvoid mem_init(VOIDPTR block, unsigned size);
  57430. Xvoid hline(int x, int y, int width, int color);
  57431. Xint Cursor_WaitKey(void);
  57432. Xvoid Cursor_CheckBlink(void);
  57433. X#ifdef XFRACT
  57434. Xvoid Cursor_StartMouseTracking(void);
  57435. Xvoid Cursor_EndMouseTracking(void);
  57436. X#endif
  57437. Xvoid clip_putcolor(int x, int y, int color);
  57438. Xint clip_getcolor(int x, int y);
  57439. XBOOLEAN Cursor_Construct (void);
  57440. Xvoid    Cursor_Destroy   (void);
  57441. Xvoid    Cursor_SetPos    (int x, int y);
  57442. Xvoid    Cursor_Move        (int xoff, int yoff);
  57443. Xint       Cursor_GetX        (void);
  57444. Xint       Cursor_GetY        (void);
  57445. Xvoid    Cursor_Hide        (void);
  57446. Xvoid    Cursor_Show        (void);
  57447. X
  57448. X/*  encoder -- C file prototypes */
  57449. X
  57450. Xextern void encoder_overlay(void);
  57451. Xextern int savetodisk(char *);
  57452. Xextern int encoder(void);
  57453. X
  57454. X/*  f16 -- C file prototypes */
  57455. X
  57456. Xextern FILE *t16_open(char *,int *,int *,int *,U8 *);
  57457. Xextern int t16_getline(FILE *,int ,U16 *);
  57458. X
  57459. X/*  fracsubr -- C file prototypes */
  57460. X
  57461. Xextern void calcfracinit(void);
  57462. Xextern void adjust_corner(void);
  57463. X#ifndef XFRACT
  57464. Xextern int put_resume(int ,... );
  57465. Xextern int get_resume(int ,... );
  57466. X#else
  57467. Xextern int put_resume();
  57468. Xextern int get_resume();
  57469. X#endif
  57470. Xextern int alloc_resume(int ,int );
  57471. Xextern int start_resume(void);
  57472. Xextern void end_resume(void);
  57473. Xextern void sleepms(long );
  57474. Xextern void iplot_orbit(long ,long ,int );
  57475. Xextern void plot_orbit(double ,double ,int );
  57476. Xextern void scrub_orbit(void);
  57477. Xextern int add_worklist(int ,int ,int ,int ,int ,int ,int );
  57478. Xextern void tidy_worklist(void);
  57479. Xextern void get_julia_attractor(double ,double );
  57480. Xextern int ssg_blocksize(void);
  57481. Xextern void _fastcall symPIplot(int ,int ,int );
  57482. Xextern void _fastcall symPIplot2J(int ,int ,int );
  57483. Xextern void _fastcall symPIplot4J(int ,int ,int );
  57484. Xextern void _fastcall symplot2(int ,int ,int );
  57485. Xextern void _fastcall symplot2Y(int ,int ,int );
  57486. Xextern void _fastcall symplot2J(int ,int ,int );
  57487. Xextern void _fastcall symplot4(int ,int ,int );
  57488. Xextern void _fastcall symplot2basin(int ,int ,int );
  57489. Xextern void _fastcall symplot4basin(int ,int ,int );
  57490. Xextern void _fastcall noplot(int ,int ,int );
  57491. X
  57492. X/*  fractals -- C file prototypes */
  57493. X
  57494. Xextern void FloatPreCalcMagnet2(void);
  57495. Xextern void cpower(_CMPLX *,int ,_CMPLX *);
  57496. Xextern int lcpower(_LCMPLX *,int ,_LCMPLX *,int );
  57497. Xextern int complex_mult(_CMPLX ,_CMPLX ,_CMPLX *);
  57498. Xextern int complex_div(_CMPLX ,_CMPLX ,_CMPLX *);
  57499. Xextern int lcomplex_mult(_LCMPLX ,_LCMPLX ,_LCMPLX *,int );
  57500. Xextern int MPCNewtonFractal(void);
  57501. Xextern int Barnsley1Fractal(void);
  57502. Xextern int Barnsley1FPFractal(void);
  57503. Xextern int Barnsley2Fractal(void);
  57504. Xextern int Barnsley2FPFractal(void);
  57505. Xextern int JuliaFractal(void);
  57506. Xextern int JuliafpFractal(void);
  57507. Xextern int LambdaFPFractal(void);
  57508. Xextern int LambdaFractal(void);
  57509. Xextern int SierpinskiFractal(void);
  57510. Xextern int SierpinskiFPFractal(void);
  57511. Xextern int LambdaexponentFractal(void);
  57512. Xextern int LongLambdaexponentFractal(void);
  57513. Xextern int FloatTrigPlusExponentFractal(void);
  57514. Xextern int LongTrigPlusExponentFractal(void);
  57515. Xextern int MarksLambdaFractal(void);
  57516. Xextern int MarksLambdafpFractal(void);
  57517. Xextern int UnityFractal(void);
  57518. Xextern int UnityfpFractal(void);
  57519. Xextern int Mandel4Fractal(void);
  57520. Xextern int Mandel4fpFractal(void);
  57521. Xextern int floatZtozPluszpwrFractal(void);
  57522. Xextern int longZpowerFractal(void);
  57523. Xextern int longCmplxZpowerFractal(void);
  57524. Xextern int floatZpowerFractal(void);
  57525. Xextern int floatCmplxZpowerFractal(void);
  57526. Xextern int Barnsley3Fractal(void);
  57527. Xextern int Barnsley3FPFractal(void);
  57528. Xextern int TrigPlusZsquaredFractal(void);
  57529. Xextern int TrigPlusZsquaredfpFractal(void);
  57530. Xextern int Richard8fpFractal(void);
  57531. Xextern int Richard8Fractal(void);
  57532. Xextern int PopcornFractal(void);
  57533. Xextern int LPopcornFractal(void);
  57534. Xextern int MarksCplxMand(void );
  57535. Xextern int SpiderfpFractal(void );
  57536. Xextern int SpiderFractal(void );
  57537. Xextern int TetratefpFractal(void);
  57538. Xextern int ZXTrigPlusZFractal(void);
  57539. Xextern int ScottZXTrigPlusZFractal(void);
  57540. Xextern int SkinnerZXTrigSubZFractal(void);
  57541. Xextern int ZXTrigPlusZfpFractal(void);
  57542. Xextern int ScottZXTrigPlusZfpFractal(void);
  57543. Xextern int SkinnerZXTrigSubZfpFractal(void);
  57544. Xextern int Sqr1overTrigFractal(void);
  57545. Xextern int Sqr1overTrigfpFractal(void);
  57546. Xextern int TrigPlusTrigFractal(void);
  57547. Xextern int TrigPlusTrigfpFractal(void);
  57548. Xextern int ScottTrigPlusTrigFractal(void);
  57549. Xextern int ScottTrigPlusTrigfpFractal(void);
  57550. Xextern int SkinnerTrigSubTrigFractal(void);
  57551. Xextern int SkinnerTrigSubTrigfpFractal(void);
  57552. Xextern int TrigXTrigfpFractal(void);
  57553. Xextern int TrigXTrigFractal(void);
  57554. Xextern int TryFloatFractal(int (*)());
  57555. Xextern int TrigPlusSqrFractal(void);
  57556. Xextern int TrigPlusSqrfpFractal(void);
  57557. Xextern int ScottTrigPlusSqrFractal(void);
  57558. Xextern int ScottTrigPlusSqrfpFractal(void);
  57559. Xextern int SkinnerTrigSubSqrFractal(void);
  57560. Xextern int SkinnerTrigSubSqrfpFractal(void);
  57561. Xextern int TrigZsqrdfpFractal(void);
  57562. Xextern int TrigZsqrdFractal(void);
  57563. Xextern int SqrTrigFractal(void);
  57564. Xextern int SqrTrigfpFractal(void);
  57565. Xextern int Magnet1Fractal(void);
  57566. Xextern int Magnet2Fractal(void);
  57567. Xextern int LambdaTrigFractal(void);
  57568. Xextern int LambdaTrigfpFractal(void);
  57569. Xextern int LambdaTrigFractal1(void);
  57570. Xextern int LambdaTrigfpFractal1(void);
  57571. Xextern int LambdaTrigFractal2(void);
  57572. Xextern int LambdaTrigfpFractal2(void);
  57573. Xextern int ManOWarFractal(void);
  57574. Xextern int ManOWarfpFractal(void);
  57575. Xextern int MarksMandelPwrfpFractal(void);
  57576. Xextern int MarksMandelPwrFractal(void);
  57577. Xextern int TimsErrorfpFractal(void);
  57578. Xextern int TimsErrorFractal(void);
  57579. Xextern int CirclefpFractal(void);
  57580. Xextern int long_julia_per_pixel(void);
  57581. Xextern int long_richard8_per_pixel(void);
  57582. Xextern int long_mandel_per_pixel(void);
  57583. Xextern int julia_per_pixel(void);
  57584. Xextern int marks_mandelpwr_per_pixel(void);
  57585. Xextern int mandel_per_pixel(void);
  57586. Xextern int marksmandel_per_pixel(void);
  57587. Xextern int marksmandelfp_per_pixel();
  57588. Xextern int marks_mandelpwrfp_per_pixel(void);
  57589. Xextern int mandelfp_per_pixel(void);
  57590. Xextern int juliafp_per_pixel(void);
  57591. Xextern int MPCjulia_per_pixel(void);
  57592. Xextern int otherrichard8fp_per_pixel(void);
  57593. Xextern int othermandelfp_per_pixel(void);
  57594. Xextern int otherjuliafp_per_pixel(void);
  57595. Xextern int trigmandelfp_per_pixel(void);
  57596. Xextern int trigjuliafp_per_pixel(void);
  57597. Xextern int trigXtrigmandelfp_per_pixel(void);
  57598. Xextern int trigXtrigjuliafp_per_pixel(void);
  57599. Xextern int MarksCplxMandperp(void );
  57600. Xextern int MandelSetup(void);
  57601. Xextern int MandelfpSetup();
  57602. Xextern int JuliaSetup(void);
  57603. Xextern int NewtonSetup(void);
  57604. Xextern int StandaloneSetup(void);
  57605. Xextern int UnitySetup(void);
  57606. Xextern int JuliafpSetup(void);
  57607. Xextern int MandellongSetup(void);
  57608. Xextern int JulialongSetup(void);
  57609. Xextern int TrigPlusSqrlongSetup(void);
  57610. Xextern int TrigPlusSqrfpSetup(void);
  57611. Xextern int TrigPlusTriglongSetup(void);
  57612. Xextern int TrigPlusTrigfpSetup(void);
  57613. Xextern int FnPlusFnSym(void);
  57614. Xextern int ZXTrigPlusZSetup(void);
  57615. Xextern int LambdaTrigSetup(void);
  57616. Xextern int JuliafnPlusZsqrdSetup(void);
  57617. Xextern int SqrTrigSetup(void);
  57618. Xextern int FnXFnSetup(void);
  57619. Xextern int MandelTrigSetup(void);
  57620. Xextern int MarksJuliaSetup(void);
  57621. Xextern int MarksJuliafpSetup();
  57622. Xextern int SierpinskiSetup(void);
  57623. Xextern int SierpinskiFPSetup(void);
  57624. Xextern int StandardSetup(void);
  57625. Xextern int LambdaTrigOrTrigFractal(void);
  57626. Xextern int LambdaTrigOrTrigfpFractal(void);
  57627. Xextern int LambdaTrigOrTrigSetup(void);
  57628. Xextern int JuliaTrigOrTrigFractal(void);
  57629. Xextern int JuliaTrigOrTrigfpFractal(void);
  57630. Xextern int JuliaTrigOrTrigSetup(void);
  57631. Xextern int ManlamTrigOrTrigSetup(void);
  57632. Xextern int MandelTrigOrTrigSetup(void);
  57633. Xextern int HalleySetup(void);
  57634. Xextern int HalleyFractal(void);
  57635. Xextern int Halley_per_pixel(void);
  57636. Xextern int MPCHalleyFractal(void);
  57637. Xextern int MPCHalley_per_pixel(void);
  57638. Xextern int dynamfloat(double *,double *,double*);
  57639. Xextern int mandelcloudfloat(double *,double *,double*);
  57640. Xextern int dynam2dfloatsetup(void);
  57641. Xextern int dynam2dfloat(void);
  57642. Xextern int QuaternionFPFractal(void);
  57643. Xextern int quaternionfp_per_pixel(void);
  57644. Xextern int quaternionjulfp_per_pixel(void);
  57645. Xextern int LongPhoenixFractal(void);
  57646. Xextern int PhoenixFractal(void);
  57647. Xextern int PhoenixSetup(void);
  57648. Xextern int long_phoenix_per_pixel(void);
  57649. Xextern int phoenix_per_pixel(void);
  57650. Xextern int MandPhoenixSetup(void);
  57651. Xextern int long_mandphoenix_per_pixel(void);
  57652. Xextern int mandphoenix_per_pixel(void);
  57653. Xextern int HyperComplexFPFractal(void);
  57654. X
  57655. X/*  fractint -- C file prototypes */
  57656. X
  57657. Xextern void main(int ,char **);
  57658. Xextern int key_count(int );
  57659. Xextern int cmp_line(BYTE *,int );
  57660. Xextern void flip_image(int kbdchar);
  57661. Xextern int pot_line(BYTE *,int );
  57662. Xextern void reset_zoom_corners(void);
  57663. Xextern void clear_zoombox(void);
  57664. Xextern int sound_line(BYTE *,int );
  57665. X
  57666. X/*  gifview -- C file prototypes */
  57667. X
  57668. Xextern int get_byte(void);
  57669. Xextern int get_bytes(BYTE *,int );
  57670. Xextern int gifview(void);
  57671. X
  57672. X/*  help -- C file prototypes */
  57673. X
  57674. Xextern int _find_token_length(char far *,unsigned int ,int *,int *);
  57675. Xextern int find_token_length(int ,char far *,unsigned int ,int *,int *);
  57676. Xextern int find_line_width(int ,char far *,unsigned int );
  57677. Xextern int process_document(PD_FUNC ,PD_FUNC ,VOIDPTR );
  57678. Xextern void help_overlay(void );
  57679. Xextern int help(int );
  57680. Xextern int read_help_topic(int ,int ,int ,VOIDFARPTR );
  57681. Xextern int makedoc_msg_func(int ,int );
  57682. Xextern void print_document(char *,int (*)(int ,int ),int );
  57683. Xextern int init_help(void );
  57684. Xextern void end_help(void );
  57685. X
  57686. X/*  intro -- C file prototypes */
  57687. X
  57688. Xextern void intro_overlay(void );
  57689. Xextern void intro(void );
  57690. X
  57691. X/*  jb -- C file prototypes */
  57692. X
  57693. Xextern int JulibrotSetup(void );
  57694. Xextern int JulibrotfpSetup(void );
  57695. Xextern int jb_per_pixel(void );
  57696. Xextern int jbfp_per_pixel(void );
  57697. Xextern int zline(long ,long );
  57698. Xextern int zlinefp(double ,double );
  57699. Xextern int Std4dFractal(void );
  57700. Xextern int Std4dfpFractal(void );
  57701. X
  57702. X/*  line3d -- C file prototypes */
  57703. X
  57704. Xextern void line3d_overlay(void);
  57705. Xextern int line3d(BYTE *,unsigned int );
  57706. Xextern int _fastcall targa_color(int ,int ,int );
  57707. Xextern int targa_validate(char *);
  57708. X
  57709. X/*  loadfdos -- C file prototypes */
  57710. X
  57711. Xextern int get_video_mode(struct fractal_info *);
  57712. X
  57713. X/*  loadfile -- C file prototypes */
  57714. X
  57715. Xextern void loadfile_overlay(void);
  57716. Xextern int read_overlay(void);
  57717. Xextern void set_if_old_bif(void);
  57718. X
  57719. X/*  loadmap -- C file prototypes */
  57720. X
  57721. Xextern void SetTgaColors(void);
  57722. Xextern int ValidateLuts(char *);
  57723. Xextern int SetColorPaletteName(char *);
  57724. X
  57725. X/*  lorenz -- C file prototypes */
  57726. X
  57727. Xextern int orbit3dlongsetup(void);
  57728. Xextern int orbit3dfloatsetup(void);
  57729. Xextern int lorenz3dlongorbit(long *,long *,long *);
  57730. Xextern int lorenz3d1floatorbit(double *,double *,double *);
  57731. Xextern int lorenz3dfloatorbit(double *,double *,double *);
  57732. Xextern int lorenz3d3floatorbit(double *,double *,double *);
  57733. Xextern int lorenz3d4floatorbit(double *,double *,double *);
  57734. Xextern int henonfloatorbit(double *,double *,double *);
  57735. Xextern int henonlongorbit(long *,long *,long *);
  57736. Xextern int inverse_julia_orbit(double *,double *,double *);
  57737. Xextern int Minverse_julia_orbit(void);
  57738. Xextern int Linverse_julia_orbit(void);
  57739. Xextern int inverse_julia_per_image(void);
  57740. Xextern int rosslerfloatorbit(double *,double *,double *);
  57741. Xextern int pickoverfloatorbit(double *,double *,double *);
  57742. Xextern int gingerbreadfloatorbit(double *,double *,double *);
  57743. Xextern int rosslerlongorbit(long *,long *,long *);
  57744. Xextern int kamtorusfloatorbit(double *,double *,double *);
  57745. Xextern int kamtoruslongorbit(long *,long *,long *);
  57746. Xextern int hopalong2dfloatorbit(double *,double *,double *);
  57747. Xextern int martin2dfloatorbit(double *,double *,double *);
  57748. Xextern int orbit2dfloat(void);
  57749. Xextern int orbit2dlong(void);
  57750. Xextern int orbit3dlongcalc(void);
  57751. Xextern int orbit3dfloatcalc(void);
  57752. Xextern int funny_glasses_call(int (*)());
  57753. Xextern int ifs(void);
  57754. Xextern int ifs2d(void);
  57755. Xextern int orbit3dfloat(void);
  57756. Xextern int orbit3dlong(void);
  57757. Xextern int ifs3d(void);
  57758. Xextern int iconfloatorbit(double *, double *, double *);  /* dmf */
  57759. X
  57760. X/*  lsys -- C file prototypes */
  57761. X
  57762. Xextern int Lsystem(void);
  57763. Xextern int LLoad(void);
  57764. X
  57765. X/*  miscovl -- C file prototypes */
  57766. X
  57767. Xextern void miscovl_overlay(void);
  57768. Xextern void make_batch_file(void);
  57769. Xextern void shell_to_dos(void);
  57770. Xextern void showfreemem(void);
  57771. Xextern int edit_text_colors(void);
  57772. Xextern int select_video_mode(int );
  57773. X
  57774. X/*  miscres -- C file prototypes */
  57775. X
  57776. X#ifndef XFRACT
  57777. Xextern int timer(int ,int (*)(),... );
  57778. Xextern int matherr(struct exception *);
  57779. X#else
  57780. Xextern int timer();
  57781. X#endif
  57782. Xextern void restore_active_ovly(void);
  57783. Xextern void findpath(char *,char *);
  57784. Xextern void notdiskmsg(void);
  57785. Xextern int cvtcentermag(double *,double *,double *);
  57786. Xextern void updatesavename(char *);
  57787. Xextern int check_writefile(char *,char *);
  57788. Xextern int check_key(void);
  57789. Xextern void showtrig(char *);
  57790. Xextern int set_trig_array(int ,char *);
  57791. Xextern void set_trig_pointers(int );
  57792. Xextern int tab_display(void);
  57793. Xextern int endswithslash(char *);
  57794. Xextern int ifsload(void);
  57795. Xextern int find_file_item(char *,char *,FILE **);
  57796. Xextern int file_gets(char *,int ,FILE *);
  57797. Xextern void roundfloatd(double *);
  57798. X
  57799. X/*  mpmath_c -- C file prototypes */
  57800. X
  57801. Xextern struct MP *MPsub(struct MP ,struct MP );
  57802. Xextern struct MP *MPsub086(struct MP ,struct MP );
  57803. Xextern struct MP *MPsub386(struct MP ,struct MP );
  57804. Xextern struct MP *MPabs(struct MP );
  57805. Xextern struct MPC MPCsqr(struct MPC );
  57806. Xextern struct MP MPCmod(struct MPC );
  57807. Xextern struct MPC MPCmul(struct MPC ,struct MPC );
  57808. Xextern struct MPC MPCdiv(struct MPC ,struct MPC );
  57809. Xextern struct MPC MPCadd(struct MPC ,struct MPC );
  57810. Xextern struct MPC MPCsub(struct MPC ,struct MPC );
  57811. Xextern struct MPC MPCpow(struct MPC ,int );
  57812. Xextern int MPCcmp(struct MPC ,struct MPC );
  57813. Xextern _CMPLX MPC2cmplx(struct MPC );
  57814. Xextern struct MPC cmplx2MPC(_CMPLX );
  57815. Xextern void setMPfunctions(void );
  57816. Xextern _CMPLX ComplexPower(_CMPLX ,_CMPLX );
  57817. Xextern void SetupLogTable(void );
  57818. Xextern long far ExpFloat14(long );
  57819. Xextern int ComplexNewtonSetup(void );
  57820. Xextern int ComplexNewton(void );
  57821. Xextern int ComplexBasin(void );
  57822. Xextern int GausianNumber(int ,int );
  57823. X
  57824. X/*  msccos -- C file prototypes */
  57825. X
  57826. Xextern double _cos(double );
  57827. X
  57828. X/*  parser -- C file prototypes */
  57829. X
  57830. Xextern unsigned int SkipWhiteSpace(char *);
  57831. Xextern unsigned long NewRandNum(void );
  57832. Xextern void lRandom(void );
  57833. Xextern void dRandom(void );
  57834. Xextern void mRandom(void );
  57835. Xextern void SetRandFnct(void );
  57836. Xextern void RandomSeed(void );
  57837. Xextern void lStkSRand(void );
  57838. Xextern void mStkSRand(void );
  57839. Xextern void dStkSRand(void );
  57840. Xextern void dStkAbs(void );
  57841. Xextern void mStkAbs(void );
  57842. Xextern void lStkAbs(void );
  57843. Xextern void dStkSqr(void );
  57844. Xextern void mStkSqr(void );
  57845. Xextern void lStkSqr(void );
  57846. Xextern void dStkAdd(void );
  57847. Xextern void mStkAdd(void );
  57848. Xextern void lStkAdd(void );
  57849. Xextern void dStkSub(void );
  57850. Xextern void mStkSub(void );
  57851. Xextern void lStkSub(void );
  57852. Xextern void dStkConj(void );
  57853. Xextern void mStkConj(void );
  57854. Xextern void lStkConj(void );
  57855. Xextern void dStkZero(void );
  57856. Xextern void mStkZero(void );
  57857. Xextern void lStkZero(void );
  57858. Xextern void dStkReal(void );
  57859. Xextern void mStkReal(void );
  57860. Xextern void lStkReal(void );
  57861. Xextern void dStkImag(void );
  57862. Xextern void mStkImag(void );
  57863. Xextern void lStkImag(void );
  57864. Xextern void dStkNeg(void );
  57865. Xextern void mStkNeg(void );
  57866. Xextern void lStkNeg(void );
  57867. Xextern void dStkMul(void );
  57868. Xextern void mStkMul(void );
  57869. Xextern void lStkMul(void );
  57870. Xextern void dStkDiv(void );
  57871. Xextern void mStkDiv(void );
  57872. Xextern void lStkDiv(void );
  57873. Xextern void StkSto(void );
  57874. Xextern void StkLod(void );
  57875. Xextern void dStkMod(void );
  57876. Xextern void mStkMod(void );
  57877. Xextern void lStkMod(void );
  57878. Xextern void StkClr(void );
  57879. Xextern void dStkFlip(void );
  57880. Xextern void mStkFlip(void );
  57881. Xextern void lStkFlip(void );
  57882. Xextern void dStkSin(void );
  57883. Xextern void mStkSin(void );
  57884. Xextern void lStkSin(void );
  57885. Xextern void dStkTan(void );
  57886. Xextern void mStkTan(void );
  57887. Xextern void lStkTan(void );
  57888. Xextern void dStkTanh(void );
  57889. Xextern void mStkTanh(void );
  57890. Xextern void lStkTanh(void );
  57891. Xextern void dStkCoTan(void );
  57892. Xextern void mStkCoTan(void );
  57893. Xextern void lStkCoTan(void );
  57894. Xextern void dStkCoTanh(void );
  57895. Xextern void mStkCoTanh(void );
  57896. Xextern void lStkCoTanh(void );
  57897. Xextern void dStkRecip(void );
  57898. Xextern void mStkRecip(void );
  57899. Xextern void lStkRecip(void );
  57900. Xextern void StkIdent(void );
  57901. Xextern void dStkSinh(void );
  57902. Xextern void mStkSinh(void );
  57903. Xextern void lStkSinh(void );
  57904. Xextern void dStkCos(void );
  57905. Xextern void mStkCos(void );
  57906. Xextern void lStkCos(void );
  57907. Xextern void dStkCosXX(void );
  57908. Xextern void mStkCosXX(void );
  57909. Xextern void lStkCosXX(void );
  57910. Xextern void dStkCosh(void );
  57911. Xextern void mStkCosh(void );
  57912. Xextern void lStkCosh(void );
  57913. Xextern void dStkLT(void );
  57914. Xextern void mStkLT(void );
  57915. Xextern void lStkLT(void );
  57916. Xextern void dStkGT(void );
  57917. Xextern void mStkGT(void );
  57918. Xextern void lStkGT(void );
  57919. Xextern void dStkLTE(void );
  57920. Xextern void mStkLTE(void );
  57921. Xextern void lStkLTE(void );
  57922. Xextern void dStkGTE(void );
  57923. Xextern void mStkGTE(void );
  57924. Xextern void lStkGTE(void );
  57925. Xextern void dStkEQ(void );
  57926. Xextern void mStkEQ(void );
  57927. Xextern void lStkEQ(void );
  57928. Xextern void dStkNE(void );
  57929. Xextern void mStkNE(void );
  57930. Xextern void lStkNE(void );
  57931. Xextern void dStkOR(void );
  57932. Xextern void mStkOR(void );
  57933. Xextern void lStkOR(void );
  57934. Xextern void dStkAND(void );
  57935. Xextern void mStkAND(void );
  57936. Xextern void lStkAND(void );
  57937. Xextern void dStkLog(void );
  57938. Xextern void mStkLog(void );
  57939. Xextern void lStkLog(void );
  57940. Xextern void FPUcplxexp(_CMPLX *,_CMPLX *);
  57941. Xextern void dStkExp(void );
  57942. Xextern void mStkExp(void );
  57943. Xextern void lStkExp(void );
  57944. Xextern void dStkPwr(void );
  57945. Xextern void mStkPwr(void );
  57946. Xextern void lStkPwr(void );
  57947. Xextern void (*mtrig0)(void);
  57948. Xextern void (*mtrig1)(void);
  57949. Xextern void (*mtrig2)(void);
  57950. Xextern void (*mtrig3)(void);
  57951. Xextern void EndInit(void );
  57952. Xextern struct ConstArg far *isconst(char *,int );
  57953. Xextern void NotAFnct(void );
  57954. Xextern void FnctNotFound(void );
  57955. Xextern int whichfn(char *,int );
  57956. X#ifndef XFRACT
  57957. Xextern void (far *isfunct(char *,int ))(void );
  57958. X#else
  57959. Xextern void (far *isfunct(char *,int ))();
  57960. X#endif
  57961. Xextern void RecSortPrec(void );
  57962. Xextern int ParseStr(char *);
  57963. Xextern int Formula(void );
  57964. Xextern int form_per_pixel(void );
  57965. Xextern char *FindFormula(char *);
  57966. Xextern int RunForm(char *);
  57967. Xextern int fpFormulaSetup(void );
  57968. Xextern int intFormulaSetup(void );
  57969. Xextern void init_misc(void);
  57970. Xextern void free_workarea(void);
  57971. X
  57972. X/*  plot3d -- C file prototypes */
  57973. X
  57974. Xextern void _fastcall draw_line(int ,int ,int ,int ,int );
  57975. Xextern void _fastcall plot3dsuperimpose16b(int ,int ,int );
  57976. Xextern void _fastcall plot3dsuperimpose16(int ,int ,int );
  57977. Xextern void _fastcall plot3dsuperimpose256(int ,int ,int );
  57978. Xextern void _fastcall plotIFS3dsuperimpose256(int ,int ,int );
  57979. Xextern void _fastcall plot3dalternate(int ,int ,int );
  57980. Xextern void plot_setup(void);
  57981. X
  57982. X/*  printer -- C file prototypes */
  57983. X
  57984. Xextern void printer_overlay(void);
  57985. Xextern void Print_Screen(void);
  57986. X
  57987. X/*  prompts -- C file prototypes */
  57988. X
  57989. Xextern void prompts_overlay(void);
  57990. Xextern int fullscreen_prompt(char far*,int ,char far **,struct fullscreenvalues *,int ,int ,char far *);
  57991. Xextern int get_fracttype(void);
  57992. Xextern int get_fract_params(int );
  57993. Xextern int get_fract3d_params(void);
  57994. Xextern int get_3d_params(void);
  57995. Xextern int get_toggles(void);
  57996. Xextern int get_toggles2(void);
  57997. Xextern int get_view_params(void);
  57998. Xextern int get_starfield_params(void );
  57999. Xextern int get_commands(void);
  58000. Xextern void goodbye(void);
  58001. Xextern int getafilename(char *,char *,char *);
  58002. Xextern int splitpath(char *template,char *drive,char *dir,char *fname,char *ext);
  58003. Xextern int makepath(char *template,char *drive,char *dir,char *fname,char *ext);
  58004. Xextern char *extract_filename(char * fullfilename);
  58005. X
  58006. X/*  realdos -- C file prototypes */
  58007. X
  58008. Xextern int stopmsg(int ,CHAR far *);
  58009. Xextern int texttempmsg(char *);
  58010. Xextern int showtempmsg(char *);
  58011. Xextern void cleartempmsg(void);
  58012. Xextern void blankrows(int ,int ,int );
  58013. Xextern void helptitle(void);
  58014. Xextern int putstringcenter(int ,int ,int ,int ,char far *);
  58015. Xextern void stackscreen(void);
  58016. Xextern void unstackscreen(void);
  58017. Xextern void discardscreen(void);
  58018. Xextern int fullscreen_choice(int ,char far*,char far*,char far*,int ,char **,int *,int ,int ,int ,int ,void (*)(),char *,int (*)(),int (*)());
  58019. X#ifndef XFRACT /* Unix should have this in string.h */
  58020. Xextern int strncasecmp(char *,char *,int );
  58021. X#endif
  58022. Xextern int main_menu(int );
  58023. Xextern int input_field(int ,int ,char *,int ,int ,int ,int (*)(int));
  58024. Xextern int field_prompt(int ,char *,char *,char *,int ,int (*)(int));
  58025. Xextern int thinking(int ,char *);
  58026. Xextern void clear_screen(void );
  58027. Xextern int savegraphics(void);
  58028. Xextern void restoregraphics(void);
  58029. Xextern void discardgraphics(void);
  58030. Xextern int load_fractint_cfg(int );
  58031. Xextern void bad_fractint_cfg_msg(void);
  58032. Xextern void load_videotable(int );
  58033. Xextern int check_vidmode_key(int ,int );
  58034. Xextern int check_vidmode_keyname(char *);
  58035. Xextern void vidmode_keyname(int ,char *);
  58036. X
  58037. X/*  rotate -- C file prototypes */
  58038. X
  58039. Xextern void rotate_overlay(void);
  58040. Xextern void rotate(int );
  58041. Xextern void save_palette(void);
  58042. Xextern void load_palette(void );
  58043. X
  58044. X/*  slideshw -- C file prototypes */
  58045. X
  58046. Xextern int slideshw(void);
  58047. Xextern int startslideshow(void);
  58048. Xextern void stopslideshow(void);
  58049. Xextern void recordshw(int );
  58050. X
  58051. X/*  targa -- C file prototypes */
  58052. X
  58053. Xextern void WriteTGA(int ,int ,int );
  58054. Xextern int ReadTGA(int ,int );
  58055. Xextern void EndTGA(void );
  58056. Xextern void StartTGA(void);
  58057. Xextern void ReopenTGA(void);
  58058. X
  58059. X/*  testpt -- C file prototypes */
  58060. X
  58061. Xextern int teststart(void);
  58062. Xextern void testend(void);
  58063. Xextern int testpt(double ,double ,double ,double ,int ,int );
  58064. X
  58065. X/*  tgaview -- C file prototypes */
  58066. X
  58067. Xextern int tgaview(void);
  58068. Xextern int outlin16(BYTE*,int );
  58069. X
  58070. X/*  tp3d -- C file prototypes */
  58071. X
  58072. Xextern char far *TrueColorAutoDetect(void );
  58073. Xextern void TranspPerPixel(int ,union Arg far *,union Arg far *);
  58074. Xextern int Transp3DFnct(void);
  58075. Xextern void ShadowPutColor(unsigned int ,unsigned int ,unsigned int );
  58076. Xextern void AntiAliasPass(void );
  58077. X
  58078. X/*  tplus -- C file prototypes */
  58079. X
  58080. Xextern void WriteTPWord(unsigned int ,unsigned int );
  58081. Xextern void WriteTPByte(unsigned int ,unsigned int );
  58082. Xextern unsigned int ReadTPWord(unsigned int );
  58083. Xextern BYTE ReadTPByte(unsigned int );
  58084. Xextern void DisableMemory(void );
  58085. Xextern void EnableMemory(void );
  58086. Xextern int TargapSys(int ,unsigned int );
  58087. Xextern int _SetBoard(int );
  58088. Xextern int TPlusLUT(BYTE far *,unsigned int ,unsigned int ,unsigned int );
  58089. Xextern int SetVGA_LUT(void );
  58090. Xextern int SetColorDepth(int );
  58091. Xextern int SetBoard(int );
  58092. Xextern int ResetBoard(int );
  58093. Xextern int CheckForTPlus(void );
  58094. Xextern int SetTPlusMode(int ,int ,int ,int );
  58095. Xextern int FillTPlusRegion(unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned long );
  58096. Xextern void BlankScreen(unsigned long );
  58097. Xextern void UnBlankScreen(void );
  58098. Xextern void EnableOverlayCapture(void );
  58099. Xextern void DisableOverlayCapture(void );
  58100. Xextern void ClearTPlusScreen(void );
  58101. Xextern int MatchTPlusMode(unsigned int ,unsigned int ,unsigned int ,unsigned int ,unsigned int );
  58102. Xextern void TPlusZoom(int );
  58103. X
  58104. X/*  yourvid -- C file prototypes */
  58105. X
  58106. Xextern int startvideo(void);
  58107. Xextern int endvideo(void);
  58108. Xextern void writevideo(int ,int ,int );
  58109. Xextern int readvideo(int ,int );
  58110. Xextern int readvideopalette(void);
  58111. Xextern int writevideopalette(void);
  58112. X#ifdef XFRACT
  58113. Xextern void readvideoline(int ,int, int, BYTE * );
  58114. Xextern void writevideoline(int ,int, int, BYTE * );
  58115. X#endif
  58116. X
  58117. X/*  zoom -- C file prototypes */
  58118. X
  58119. Xextern void drawbox(int );
  58120. Xextern void moveboxf(double ,double );
  58121. Xextern void resizebox(int );
  58122. Xextern void chgboxi(int ,int );
  58123. Xextern void zoomout(void);
  58124. Xextern void aspectratio_crop(float ,float );
  58125. Xextern int init_pan_or_recalc(int );
  58126. SHAR_EOF
  58127. $TOUCH -am 1028230093 prototyp.h &&
  58128. chmod 0644 prototyp.h ||
  58129. echo "restore of prototyp.h failed"
  58130. set `wc -c prototyp.h`;Wc_c=$1
  58131. if test "$Wc_c" != "33264"; then
  58132.     echo original size 33264, current size $Wc_c
  58133. fi
  58134. # ============= fractsrc.doc ==============
  58135. echo "x - extracting fractsrc.doc (Text)"
  58136. sed 's/^X//' << 'SHAR_EOF' > fractsrc.doc &&
  58137. XThe source code for Fractint is freely available.
  58138. X
  58139. XEnhancements to it are appreciated.  If you want to add something to
  58140. XFractint and join the Stone Soup Group, please do!  To submit changes,
  58141. Xsee "Contacting the Authors" in Fractint's online help.
  58142. X
  58143. X
  58144. XCopyright Information:
  58145. X======================
  58146. X
  58147. XSome parts of the source are from the public domain and are not
  58148. Xcopyrighted.
  58149. X
  58150. XSome parts of the source bear explicit copyright notices from the
  58151. Xauthor and are subject to the conditions listed there by the author.
  58152. X
  58153. XThe remainder of the source (not already public domain, no explicit
  58154. Xauthor's copyright notice) is Copyright 1990, 1991 by the Stone Soup Group
  58155. X(a loosely associated and ever-growing group of fanatic programmers).
  58156. X
  58157. XThe source code may be copied freely and may be used in other programs
  58158. Xunder the following conditions:
  58159. X  It may not be used in a commercial program which produces fractal images.
  58160. X  Please credit the author (in general, credit Fractint and the Stone Soup
  58161. X  Group) as the source of the code.
  58162. X
  58163. X
  58164. XDistribution of modified versions of Fractint:
  58165. X==============================================
  58166. X
  58167. XIf you enhance Fractint and want to distribute the results to others, the
  58168. Xpreferred approach is to join the Stone Soup Group - send us your
  58169. Xenhancements and get your name in lights in future versions of Fractint.
  58170. X
  58171. XWe prefer that a modified Fractint executable program not be distributed to
  58172. Xothers, but understand that you might want to give copies to friends.  This
  58173. Xis permitted, under the following conditions:
  58174. X  o The modified executable has a different name than "fractint.exe".
  58175. X  o The distribution includes a full unmodified copy of the corresponding
  58176. X    original version of fraint.exe.  (The easiest way is to copy fraint.exe
  58177. X    to yournew.exe, then "pkzip -a fraint.exe newfract.exe" to add your
  58178. X    version, and perhaps add a read.me file to describe it.)
  58179. X  o The heading displayed by the modified program clearly indicates that
  58180. X    it is a non-standard release.  E.g. you might change the heading to
  58181. X    say "Non-standard Fractint, Modified by John Doe".
  58182. X  o All author credits and distribution information in the online help
  58183. X    are unchanged (adding lines for your work is of course ok.)
  58184. X
  58185. XThe source code for a modified version of Fractint may not be distributed.
  58186. X(This is because we don't want any chance of confusion over which version
  58187. Xof a source file is the official release.)
  58188. X
  58189. X
  58190. XCompiling Fractint:
  58191. X===================
  58192. X
  58193. XFRASRC.EXE includes the complete source code for FRACTINT (.C and .ASM).
  58194. XRecognizing that not everyone HAS (or even wants) an assembler, much less
  58195. Xeither MASM 5.1 or Turbo-ASM, which are the only two assemblers that the
  58196. Xauthors are aware of that can handle these particular files, it also contains
  58197. Xa complete set of .OBJ files from the assembler code,
  58198. X
  58199. XThe distributed source will not compile to exactly match the Fractint
  58200. Xrelease - it compiles with a different version number and heading.
  58201. X
  58202. XThe Microsoft 6.00A C compiler and Microsoft 5.1 assembler are used for
  58203. XFractint releases, so that is the one combination of compiler/assembler
  58204. Xwhich is pretty much guaranteed to handle FRACTINT in all of its various
  58205. Xmutations.
  58206. X
  58207. XGiven that several of FRACTINT's co-authors now prefer (or only have!)
  58208. Xalternate combinations, we have re-arranged the code to (usually) handle
  58209. Xseveral popular alternatives.  In particular:
  58210. X
  58211. XMicrosoft C 6.00A and MASM 5.1:
  58212. X-------------------------------
  58213. XJust run MAKEFRAC.BAT, which invokes the Microsoft NMK utility using the
  58214. Xfiles FRACHELP.MAK, FRACTINT.MAK, and FRACTINT.LNK.  Note that the assembler
  58215. X.OBJ files have been included in the .ZIP file, so that you don't really
  58216. Xneed MASM unless you are going to modify one or more of them.  If you ARE
  58217. Xgoing to modify one of the assembler files, note that the distributed
  58218. Xversions rely on some nifty features added to version 5.1 (like the '.model
  58219. Xmedium,c' option) and will not assemble under older versions of MASM without
  58220. Xa LOT of work.
  58221. X
  58222. XNote that C 6.00 (the original release) had some problems.  We never used it
  58223. Xfor a Fractint release.  If you don't have the fixed version (6.00A) you
  58224. Xshould compile parser.c, loadfile.c, and calcfrac.c with no optimization,
  58225. Xusing the /qc option.  There might be other problems, those are the only
  58226. Xones we're aware of...
  58227. X
  58228. XWarning: FRACTINT.MAK uses C6.00A's most aggressive optimizations.  It is
  58229. Xassumed there is no aliasing.  See Microsoft's documentation on the /Oa
  58230. Xand /Oz options.
  58231. X
  58232. XMicrosoft C 5.1:
  58233. X----------------
  58234. XEdit MAKEFRAC.BAT: comment out the two "nmk ..." lines and uncomment
  58235. Xthe lines for C5.1.  Then run MAKEFRAC.
  58236. X
  58237. XQuick-C:
  58238. X--------
  58239. XFRACTINT is just too big for the interactive Quick-C (QC) environment.
  58240. XYou have to use the command-line variant of Quick-C (QCL).
  58241. X
  58242. XEdit MAKEFRAC.BAT: comment out the two "nmk ..." lines and uncomment
  58243. Xthe lines for QuickC.  Then run MAKEFRAC.
  58244. X
  58245. XWe're not sure all versions of QuickC work.  2.01 works as of
  58246. XFractint version 16.  Depending on how much memory you have available,
  58247. Xyou may have to manually compile some modules without the /O option.
  58248. X
  58249. XTurbo-C, Turbo-C++ and TASM
  58250. X---------------------------
  58251. XSorry, Turbo-C fans, but since version 14.0, FRACTINT requires TC++.
  58252. XThe lack of initialized FAR arrays and structures just did the older Turbo-C
  58253. Xproduct in.  The *good* news is that some of the FRACTINT authors now
  58254. Xuse Turbo-C++, so the odds of released FRACTINT distributions that do
  58255. Xnot compile with Turbo products are lower than they used to be.
  58256. X
  58257. XA TCFRACT.PRJ and TCHELP.PRJ file is included for Turbo-C users.  You should
  58258. Xrename these to FRACTINT.PRJ and HC.PRJ before compiling fractint.  
  58259. X
  58260. XWith TC++ you'll have to do a manual step for the help system each time you
  58261. Xcreate a new fractint.exe - see notes in next section.
  58262. X
  58263. X
  58264. XBorland C++ 3.0 and 3.1 Users
  58265. X-----------------------------
  58266. XRename the BCFRACT.PRJ and BCHELP.PRJ files to FRACTINT.PRJ and HC.PRJ.
  58267. XThe project file will generate the FRACTINT.HLP file, but you will still
  58268. Xhave to run "hc /a" from the DOS command line to append the help
  58269. Xinformation.
  58270. X
  58271. X
  58272. X
  58273. XHelp System
  58274. X===========
  58275. X
  58276. XYou'll need to set up the help files to get any online help from a modified
  58277. Xversion of Fractint.
  58278. X
  58279. XFor MSC users the MAKEFRAC.BAT file contains the necessary steps, you don't
  58280. Xneed to do anything special.
  58281. X
  58282. XTC++ users should:
  58283. X  start by creating HC.EXE using the supplied HC.PRJ file
  58284. X  run "hc /c" to create the file FRACTINT.HLP
  58285. X  each time you create a new fractint.exe, afterward run "hc /a" to append
  58286. X    FRACTINT.HLP to the new FRACTINT.EXE
  58287. X
  58288. XYou don't need to understand the rest of this section unless you have a
  58289. Xproblem.
  58290. X
  58291. XThe source for Fractint's help is in the files HELP.SRC, HELP2.SRC, HELP3.SRC,
  58292. XHELP4.SRC, and HELP5.SRC.  The format of these files is described in HC.DOC.
  58293. X
  58294. XThe program HC.C ("help compiler") is used to convert the help text into
  58295. Xthe form Fractint uses at run time.
  58296. X
  58297. XRunning "hc /c" compiles HELPx.SRC.  It produces the file HELPDEFS.H for
  58298. Xuse when compiling Fractint, and the file FRACTINT.HLP.
  58299. XRunning "hc /a" appends the FRACTINT.HLP file to FRACTINT.EXE to make the
  58300. Xcompiled help info available at run time.
  58301. X
  58302. X
  58303. XOverlays
  58304. X========
  58305. X
  58306. XNote: generally you won't have to worry about this!
  58307. XOnly the addition of huge code (new overlays), or work which changes the
  58308. Xrelationship between major components of Fractint, are likely to affect
  58309. Xthe overlay structure.    However, if you make changes in a module which has a
  58310. Xcomment at the start saying it is an overlay, please follow the guidelines
  58311. Xfor use of ENTER_OVLY and EXIT_OVLY described after the next paragraph.
  58312. X
  58313. XFractint uses the Microsoft Link overlay feature, to reduce the runtime
  58314. Xmemory required (which would otherwise exceed what DOS can give it.)
  58315. XSome caution is required with overlays.  Those source modules which are
  58316. Xpart of an overlay have a comment to indicate this at the start.  See the
  58317. Xfractint.lnk file for the current overlay structure.
  58318. XSome notes about overlays:
  58319. X  o The obvious one: control should not switch to different overlays
  58320. X    frequently, else Fractint will become sluggish.  If the overlay structure
  58321. X    changes, a test from floppy disk with no disk caching is a good idea.
  58322. X  o The linker cannot detect indirect calls (e.g. thing=routinename;
  58323. X    (*thing)();) to an overlay.  Routines in overlays should not be called
  58324. X    indirectly, except from within the same overlay.
  58325. X  o The overlay manager logic (inserted by the linker) does handle calls
  58326. X    from within one overlay to another - the new overlay is brought in
  58327. X    from disk (displacing the old one in memory), when the subroutine
  58328. X    finishes the old overlay is brought back into memory.
  58329. X  o The overlay manager logic does not handle situations like the following:
  58330. X    overlayA calls residentB(), which calls overlayC().  OverlayC is loaded
  58331. X    and executed ok, eventually control returns to residentB ok, BUT the
  58332. X    return from there to overlayA does NOT reload overlayA!  Fractint has
  58333. X    constructs called ENTER_OVLY and EXIT_OVLY to circumvent this problem.
  58334. X
  58335. XGuidelines for routines in overlayed modules:
  58336. X  o If the routine is local, declare it "static" to ensure this and to
  58337. X    make analysis of relationships among overlays easier.
  58338. X  o If the routine is called from external code (resident, or in another
  58339. X    overlay), the first executable line in the routine must be:
  58340. X      ENTER_OVLY(OVLY_XXX); /* XXX is the module name */
  58341. X    Each "return" from the routine (incl. the implicit one at the end) must
  58342. X    be preceded by:
  58343. X      EXIT_OVLY;
  58344. X  o When creating a new overlay XXX, add a new OVLY_XXX value to Fractint:
  58345. X    Fractint.h has a define for each OVLY_XXX value.  Miscres.c has a
  58346. X    routine "restore_active_ovly" which needs a new line for OVLY_XXX.
  58347. X    The source module needs a dummy routine "xxx_overlay".
  58348. X
  58349. X
  58350. XWhere the Goodies are
  58351. X=====================
  58352. X
  58353. XIt has come to our attention that people who have no interest in fractals
  58354. Xat all have been wandering through the FRACTINT source code just to get at
  58355. Xsome of the neat tricks buried therein.  Here are a few hints as to where
  58356. Xto look:
  58357. X
  58358. XFRACTINT.C    - The main routine.  Nothing special here.
  58359. XFRACTINT.H    - General Include file.  Nothing special here, either.
  58360. XFRACTYPE.H    - Fractal type-specific Include file.
  58361. X
  58362. XPROMPTS.C    - The full-screen prompting code (using support routines
  58363. X          in VIDEO.ASM)
  58364. XCMDFILES.C    - Command line and sstools.ini parsing.
  58365. X
  58366. XFRACTALS.C,    - Most of the fractal-specific code.  If you want to know
  58367. X CALCFRAC.C,      how a fractal is calculated, look in here.  Specific
  58368. X FRACSUBR.C      speed-em-up support for special fractal types is in:
  58369. X FRACSUBA.ASM
  58370. XCALCMAND.ASM    - Mandelbrot/Julia set calculations.
  58371. XNEWTON.ASM    - Newton calculations
  58372. XLORENZ.C    - Attractor fractals and IFS
  58373. XJB.C        - "Julibrot" fractal type calculations
  58374. XTESTPT.C    - "Roll-your-own" fractal routine
  58375. XMPMATH_C.C,    - Mark Peterson's "fast-math" support routines.
  58376. X MPMATH_A.ASM,      (this stuff puts some of the routines supplied by your
  58377. X FPU387.ASM,      favorite "C" compiler to shame!)
  58378. X FPU087.ASM,      ...
  58379. X FMATH.H,      ...
  58380. X MPMATH.H      ...
  58381. XPARSER.C    - The "type=formula" formula parser routines
  58382. XLSYS.C        - L-Systems code
  58383. X
  58384. XVIDEO.ASM    - Assembler code containing all of the video routines
  58385. X          (setting up the video, reading/writing pixels, zoom-box
  58386. X          code, color-cycling, graphics-to-text "help" switch,
  58387. X          ... with help from the routines below for special adapters:
  58388. XLOADMAP.C    - Load .map files.
  58389. XTARGA.C,    - TARGA Video Routines
  58390. X TARGA.H,      ...
  58391. XFR8514A.ASM    - 8514/A Routines
  58392. XTPLUS.C     - Targa+ video routines
  58393. X TPLUS.H      ...
  58394. X TPLUS_A.ASM      ...
  58395. XHGCFRA.ASM    - Hercules Video Routines
  58396. XDISKVID.C    - "DISK'RAM" video routines
  58397. XYOURVID.C    - "Roll-your-own" video routines
  58398. X
  58399. XGENERAL.ASM    - General assembler code having nothing to do with fractals.
  58400. X          Lots of the tricky stuff is in here, and many of the "C"
  58401. X          routines that perform tricky functions rely on support
  58402. X          code buried in here.    In particular, this routine has the:
  58403. X            CPU, FPU Detectors
  58404. X            Keyboard routines
  58405. X            Mouse routines
  58406. X            Expanded memory routines
  58407. X            32-bit scaled integer multiply and divide routines
  58408. X
  58409. XENCODER.C    - GIF Encoder routine.
  58410. XGIFVIEW.C,    - GIF Decoder routines.
  58411. X DECODER.C,
  58412. X TGAVIEW.C,      (including a TARGA-format decoder currently used only for
  58413. X F16.C,       loading obsolete .tga format "Continuous Potential" files)
  58414. X TARGA_LC.H      ...
  58415. XLOADFILE.C    - Loads the Fractint parameter info from a GIF file.
  58416. X LOADFDOS.C      subroutines for DOS Fractint only
  58417. X
  58418. XLINE3D.C,    - 3D manipulation routines
  58419. X 3D.C
  58420. XPLOT3D        - 3D subroutines for LINE3D.C and LORENZ.C
  58421. X
  58422. XROTATE.C    - routines which "spin" the VGA video-DAC.
  58423. XEDITPAL.C    - palette-editing mode
  58424. X
  58425. XHELP.C        - HELP support
  58426. XINTRO.C     - title screen
  58427. X
  58428. XZOOM.C        - Zoombox manipulation.
  58429. X
  58430. XPRINTER.C,    - The Printer Routines
  58431. X PRINTERA.ASM      Data used by PRINTER.C
  58432. X
  58433. XMISCRES.C    - Miscellaneous resident subroutines; nothing special.
  58434. XMISCOVL.C    - Miscellaneous overlayed subroutines; includes <B>atch
  58435. X          command.
  58436. XREALDOS.C    - Some subroutines isolated from Windows development work;
  58437. X          nothing special in here.
  58438. X
  58439. XPORT.H        - Some portability stuff, nothing special here.
  58440. X
  58441. XHow things are set up
  58442. X=====================
  58443. XI've had to go through a lot of the code to figure out how things are set
  58444. Xup.  These are my rough notes, which I'm including in case they can help
  58445. Xsomeone else. -- Ken Shirriff
  58446. X
  58447. XThe control flow is very confusing.  Here are some details:
  58448. X
  58449. XEach fractal type has an entry in the fractalspecific table in fractalp.c.
  58450. XEntries that are not displayed are marked with an asterisk.  Each entry is
  58451. Xmarked as int or not int, and either has a pointer to another entry
  58452. X(tofloat) or NOFRACTAL.  If you select float and the type is int or vice
  58453. Xversa, you will end up with the tofloat type.  (e.g. If you select entry
  58454. XMANDEL, and select floating point, you will get entry MANDELFP).  There are
  58455. Xalso pointers tojulia and tomandel, which allow you to switch between mandel
  58456. Xand julia.  The four functions listed are curfractalspecific->orbitcalc,
  58457. Xcurfractalspecific->per_pixel, curfractalspecific->per_image, and
  58458. Xcurfractalspecific->calctype.
  58459. X
  58460. Xmain calls calcfracinit.
  58461. Xcalcfractint: this sets up curfractalspecific, which is the appropriate entry
  58462. X    from the fractalspecific table.  This routine does the int/float
  58463. X    conversion.
  58464. X
  58465. Xmain calls calcfract, which calls timer, which calls perform_worklist
  58466. Xperform_worklist calls curfractalspecific->per_image, which is eg.  MandelSetup
  58467. XMandelSetup: sets calctype to curfractalspecific->calctype, or for special
  58468. X    cases (eg. decomposition) to StandardFractal
  58469. X
  58470. Xperform_worklist calls solidguess (or whatever drawing system)
  58471. Xsolidguess calls *calctype for each pixel; calctype is eg. StandardFractal
  58472. X
  58473. XStandardFractal calls curfractalspecific->per_pixel once, and then loops over
  58474. X    each iteration calling curfractalspecific->orbitcalc.  These routines
  58475. X    are eg.  mandel_per_pixel and JuliaFractal.
  58476. X
  58477. X
  58478. X
  58479. XHere is the structure of the main routine:
  58480. X
  58481. Xmain()
  58482. X{
  58483. X    initialize things
  58484. Xrestorestart:
  58485. X    if loading, look after specifying image
  58486. Ximagestart:
  58487. X    while (adapter<0) {
  58488. X    process keys from short main menu
  58489. X    }
  58490. X
  58491. X    while (1) {
  58492. X    if (calc_status != 2 || showfile==0) {
  58493. X        initialize videoentry from videotable[adapter]
  58494. X        initialize size, color, etc. from videoentry
  58495. X        setvideomode()
  58496. X    }
  58497. X    if (showfile==0) {
  58498. X        load file
  58499. X    }
  58500. X    calcfracinit();
  58501. X    save corners, zoom data
  58502. X    if (showfile != 0) {
  58503. X        calcfract(); /* calculates the fractal until interrupted */
  58504. X    }
  58505. Xresumeloop:
  58506. X    if (no key pressed) {
  58507. X        set keypress = 13 to continue
  58508. X    } else if (key pressed) {
  58509. X        check input key
  58510. X    } else if (batch mode) {
  58511. X        look after batch key
  58512. X    }
  58513. X
  58514. X    process key from long menu
  58515. X    }
  58516. X}
  58517. X
  58518. X
  58519. XHow the video entries are managed:
  58520. X
  58521. Xget_video_mode(fractal_info): This routine is used to select a video mode
  58522. X    to match a picture we're loading.  It loads vidtbl and then  tries to
  58523. X    find a video mode that matches that in fractal_info.  Asks the user to
  58524. X    select one if there's no good match.  Figures out how to reduce the image
  58525. X    to fit the screen.
  58526. X
  58527. Xselect_video_mode(curmode): This is the main-menu routine for the user to
  58528. X    pick a video mode.  picks default video mode, lets user select mode
  58529. X    from menu, copies entry to videoentry, puts entry in videotable if not
  58530. X    there, calls update_fractint_cfg if key reassigned, returns key
  58531. X    corresponding to mode
  58532. X
  58533. Xcheck_vidmode_key(option, keypress): if keypress corresponds to a videomode in
  58534. X    videotable (for option 0) or vidtbl (for option 1) return the videomode
  58535. X    index, else -1.
  58536. X
  58537. Xcheck_vidmode_keyname: converts ascii key name into key number
  58538. X
  58539. Xadapter_detect: checks for type of video (ega, cga, etc) and set video_type,
  58540. Xmode7text, textsafe.
  58541. X
  58542. Xload_videotable: reads the entries in fractint.cfg into vidtbl
  58543. X    copies entries with an associated function key into videotable
  58544. X
  58545. Xload_fractint_cfg: reads video modes in fractint.cfg into vidtbl
  58546. X    (or copies from videotable) if fractint.cfg missing or bad
  58547. X
  58548. Xupdate_fractint_cfg: writes the entry in videoentry into the fractint.cfg file.
  58549. X
  58550. Xvidtbl: contains the video modes from fractint.cfg
  58551. Xvideotable: contains video modes with function keys; initialized in video.asm
  58552. Xvideo_type: contains type: hgc, egc, cga, mcga
  58553. X
  58554. X
  58555. XHere is how the floating point modes are set up.
  58556. Xparser.c uses the MathTypes:
  58557. XD_MATH: uses double precision routines, such as dStkMul, and FPUsincos
  58558. X    This is used if we have a fpu.
  58559. XM_MATH: uses MP type (mantissa, exponent).  These routines such as mStkAdd
  58560. X    call MPCadd, which call pMPadd, which calls MPadd086 or MPadd386.
  58561. X    The MP routines work on multiple precision, MPC works on complex pairs
  58562. X    of multiple precision.
  58563. XL_MATH: uses integer math.  Routines such as lStkAdd.
  58564. SHAR_EOF
  58565. $TOUCH -am 1028230093 fractsrc.doc &&
  58566. chmod 0644 fractsrc.doc ||
  58567. echo "restore of fractsrc.doc failed"
  58568. set `wc -c fractsrc.doc`;Wc_c=$1
  58569. if test "$Wc_c" != "17535"; then
  58570.     echo original size 17535, current size $Wc_c
  58571. fi
  58572. # ============= debugfla.doc ==============
  58573. echo "x - extracting debugfla.doc (Text)"
  58574. sed 's/^X//' << 'SHAR_EOF' > debugfla.doc &&
  58575. XThis list complete as of version 14.
  58576. XNone of these are necessarily supported in future.
  58577. X
  58578. XAdd one to any debug value to trigger writing benchmark values to
  58579. Xthe file "bench".  This gets stripped at startup; so all values
  58580. Xused for other purposes are even.
  58581. X
  58582. XExample:  "fractint debug=8088" forces Fractint to think you have an
  58583. X8088/8086 CPU and ignore all of the tricky 186/286/386-specific stuff.
  58584. X"Fractint 8089" does the same thing, but also turns on the benchmark
  58585. Xtimer.
  58586. X
  58587. X16    video.asm    pretend not a vga
  58588. X22    lorenz.c    force float for 3D perspective
  58589. X50    fractint.c    compare <r>estored files
  58590. X70    fractint.c    set fpu = 0
  58591. X72    fractint.c    don't use fast >= 287 fpu routines
  58592. X90    fractals.c    force "C" mandel & julia code (no calcmand or calmanfp)
  58593. X90    fractals.c    force generic code for fn+fn etc types
  58594. X90 parser.c    force "C" parser code even if FPU >= 387
  58595. X100    calcmand.asm    force use of 'code32bit' logic
  58596. X200    fractint.c    time encoder
  58597. X322   parserfp.c  disable optimizer (FPU >= 387 only)
  58598. X420    diskvid.c    don't use extended/expanded mem (force disk)
  58599. X420    realdos.c      same for screen save (force disk)
  58600. X420    editpal.c      same for screen save (force disk)
  58601. X420    jiim.c            same for screen save (force disk)
  58602. X422    diskvid.c    don't use expanded mem (force extended or disk)
  58603. X422    realdos.c      same for screen save (force extended or disk)
  58604. X450    fractint.c    abort in batch mode if savename exists
  58605. X470    calcfract.c    disable prevention of color 0 for BTM
  58606. X600    printer.c    paintjet, no form feed
  58607. X602    printer.c    paintjet, flip image
  58608. X7nn     miscovl.c    set <b> getprec() digits variable to nn
  58609. X870    fractint.c    set fpu to max 87
  58610. X1010    fractals.c    force fp for newton & newtbasin (no mpc math)
  58611. X1234    fractint.c    force larger integer arithmetic bitshift value
  58612. X2222    line3d.c    show amount of extra seg memory used
  58613. X2224    line3d.c    old just-the-dots logic, probably a temporary thing
  58614. X2870    fractint.c    set fpu to max 287 iit off
  58615. X2872    fractint.c    set fpu to max 287 iit on
  58616. X3000    general.asm    '~' goes to color play mode
  58617. X3002    realdos.c    don't show development in heading
  58618. X3870    fractint.c    set fpu to max 387 iit off
  58619. X3872    fractint.c    set fpu to max 387 iit on
  58620. X4000    miscres.c    turn on math error message (off otherwise)
  58621. X8088    general.asm    set cpu = 86, ie dont use 32 bit stuff
  58622. X8088    fractint.c    set cpu = 86, (case in general.asm is redundant?)
  58623. X9002-9100 fractint.c    reduce video_type to (debug-9000)/2 if init was higher
  58624. X10000    fractint.c    display cpu, fpu, and free memory at startup
  58625. X10000    fractint.c    ? (try extra hard for minimal startup memory?)
  58626. X
  58627. Xnonzero value, line3d.c, show "normal vector" errors instead of just fixing
  58628. Xnonzero value, prompts.c, show info if fullscreen_prompt2 array invalid
  58629. X
  58630. SHAR_EOF
  58631. $TOUCH -am 1028230093 debugfla.doc &&
  58632. chmod 0644 debugfla.doc ||
  58633. echo "restore of debugfla.doc failed"
  58634. set `wc -c debugfla.doc`;Wc_c=$1
  58635. if test "$Wc_c" != "2610"; then
  58636.     echo original size 2610, current size $Wc_c
  58637. fi
  58638. # ============= hc.doc ==============
  58639. echo "x - extracting hc.doc (Text)"
  58640. sed 's/^X//' << 'SHAR_EOF' > hc.doc &&
  58641. X
  58642. X... First version documentation is followed by additional notes
  58643. X... for features added in subsequent versions.
  58644. X
  58645. X
  58646. X           FRACTINT Help Compiler Source File Format
  58647. X
  58648. X
  58649. X
  58650. X0. Contents
  58651. X
  58652. X    1.0     Help compiler input/output.
  58653. X    1.1       The source input file.
  58654. X    1.2       The header (.H) output file.
  58655. X    1.3       The binary (.HLP) output file.
  58656. X    2.0     Source (.SRC) file format.
  58657. X    2.1       Comments.
  58658. X    2.2       Defining the output filenames.
  58659. X    2.3       Defining the help file version.
  58660. X    2.4.0     Help topics.
  58661. X    2.4.1    Starting a help topic.
  58662. X    2.4.2.0    The help text.
  58663. X    2.4.2.1      Special characters.
  58664. X    2.4.3    Starting another page.
  58665. X    2.5.0     Labels.
  58666. X    2.5.1    The help index label (HELP_INDEX).
  58667. X    2.5.2    Private labels.
  58668. X    2.6.0     Hot-links.
  58669. X    2.6.1    Special hot-links.
  58670. X    2.7       Tables.
  58671. X
  58672. X
  58673. X1.0 Help compiler input/output.
  58674. X
  58675. X    The Help Compiler converts a source file into two output files: a "C"
  58676. X  header file which is #included in FRACTINT and a binary file used at run-
  58677. X  time.
  58678. X
  58679. X
  58680. X1.1 The source input file.
  58681. X
  58682. X    The Help compiler takes as input a help source file (.SRC).  See x.x.x
  58683. X  for the .SRC file format.  HELP.SRC is FRACTINT's help file source.
  58684. X
  58685. X
  58686. X1.2 The header (.H) output file.
  58687. X
  58688. X    The header (.H) file contains a #define macro for each non-private label
  58689. X  (see 2.5.0) and for the help file version (see 2.3).    The .H file is
  58690. X  included in FRACTINT and the macros are used to set the current help mode.
  58691. X
  58692. X    The Help Compiler will only modify the .H file when a non-private label
  58693. X  (see 2.5.0) is added or deleted or when the help file version (see 2.3)
  58694. X  is changed.  This minimizes the times when FRACTINT will need to be re-
  58695. X  compiled.  However, when the Help Compiler does modify the .H file it is
  58696. X  necessary to re-compile FRACTINT.
  58697. X
  58698. X  In FRACTINT this file is named HELPDEFS.H
  58699. X
  58700. X1.3 The binary (.HLP) output file.
  58701. X
  58702. X    The .HLP file is the binary file where compiled help informnation is
  58703. X  stored.  See HC.C and HELP.C if you're interested in the file format.  In
  58704. X  FRACTINT the file is named FRACTINT.HLP.  This file may be appended to
  58705. X  FRACTINT.EXE for distribution, see the Help Compiler command-line help
  58706. X  (type "HC" at the DOS prompt) more info.
  58707. X
  58708. X
  58709. X2.0 Source (.SRC) file format.
  58710. X
  58711. X    The source file defines output files, help file version, topics, labels
  58712. X  and hypertext-style hot-links with commands and hot-links.  Commands start
  58713. X  with a tilde ('~') in the first column of a line and continue to the end
  58714. X  of the line.    Hot-links, defined within the text, are surrounded by curly-
  58715. X  braces ('{' and '}').  Comment lines, which may appear anywhere in the
  58716. X  file, start with a semicolon (';') in the first column and continue to
  58717. X  the end of the line.
  58718. X
  58719. X
  58720. X2.1 Comments.
  58721. X
  58722. X    Any line starting with a semicolon (;) is a comment.  The comment
  58723. X  continues to the end of the line and may appear anywhere in the file.
  58724. X  The semicolon must be in the first column of the line.
  58725. X
  58726. X
  58727. X2.2 Defining the output filenames.
  58728. X
  58729. X    The output filenames are defined in the source file by the following
  58730. X  commands:
  58731. X
  58732. X    ~HdrFile=H_FILE
  58733. X    ~HlpFile=HLP_FILE
  58734. X
  58735. X  H_FILE is the .H filename and HLP_FILE is the .HLP filename.    These
  58736. X  commands must appear before the first topic.
  58737. X
  58738. X
  58739. X2.3 Defining the help file version.
  58740. X
  58741. X    The help file version number is stored in a special #define in the .H
  58742. X  file (named HELP_VERSION) and stored in the .HLP file header.  If the
  58743. X  version number in HELP_VERSION does not match the version in the .HLP file
  58744. X  the file will not be used.  This is mainly to make sure FRACTINT doesn't
  58745. X  try to read a help file other than the one the .EXE is expecting.  To
  58746. X  define the help version:
  58747. X
  58748. X    ~Version=nnn
  58749. X
  58750. X  Where nnn is a positive decimal version number.  (Suggested format is 100
  58751. X  for version 1.00, 150 for version 1.50, etc.)  This command must appear
  58752. X  before the first help topic.    -1 will be used if the version is not defined
  58753. X  in the .SRC file.
  58754. X
  58755. X
  58756. X2.4.0 Help topics.
  58757. X
  58758. X    The help topics come after the HdrFile=, HlpFile= and Version= commands
  58759. X  and continue until end-of-file.
  58760. X
  58761. X
  58762. X2.4.1 Starting a help topic.
  58763. X
  58764. X  To start a new help topic use the following format:
  58765. X
  58766. X    ~Topic=TITLE
  58767. X
  58768. X  "~Topic=" is the command to start a topic and TITLE is the text to display
  58769. X  at the top of each page.  The title continues to the '\n' and may contain
  58770. X  up to 65 characters.
  58771. X
  58772. X    In the example:
  58773. X
  58774. X    ~Title=Command Keys available while in Display Mode
  58775. X
  58776. X  "Command Keys avail..." is the TITLE which would displayed at the top of
  58777. X  each page.
  58778. X
  58779. X
  58780. X2.4.2.0 The help text.
  58781. X
  58782. X    The help text for each topic can be several pages long. Each page is 22
  58783. X  rows by 78 columns.  The first and last rows should be blank for the best
  58784. X  appearance.
  58785. X
  58786. X
  58787. X2.4.2.1 Special characters.
  58788. X
  58789. X    To insert reserved characters (like ';', '~', '\' and '{') into the help
  58790. X  text precede the character with a backslash ('\').  To insert any character
  58791. X  (except null) into the text follow a backslash with a decimal (not hex
  58792. X  or octal) ASCII character code.  For example:
  58793. X
  58794. X    \~  - puts a tilde in the text.
  58795. X    \24 - places an up-arrow in the text.
  58796. X
  58797. X
  58798. X2.4.3 Starting another page.
  58799. X
  58800. X    To start a new page in the same topic put two tildes (~~) at the start
  58801. X  of a line.  No other text is allowed on the line.  Each page can be up to
  58802. X  22 lines long.  (The Help Compiler will warn you if any page gets longer
  58803. X  than 22 lines.)  For the best appearance the first and last lines should
  58804. X  be blank.
  58805. X
  58806. X
  58807. X2.5.0 Labels.
  58808. X
  58809. X    A label is a name which in used to refer to a help topic.  A label is
  58810. X  used in hot-links or in FRACTINT for context-sensitive help.    When help
  58811. X  goes to a label (when a hot-link is selected or context-sensitive help
  58812. X  is called from FRACTINT) it goes to the page of the topic where the label
  58813. X  was defined.
  58814. X
  58815. X    To define a label for a topic insert the following command into the
  58816. X  topic's text:
  58817. X
  58818. X    ~(NAME)
  58819. X
  58820. X  NAME is the name of the label.  The name follows "C"-style conventions
  58821. X  for variable names.  Case is significant.  The label should start at the
  58822. X  beginning of a line and have no text following it on the line.  The line
  58823. X  line will not appear in the help text.
  58824. X
  58825. X    For example, if this line:
  58826. X
  58827. X  ~(HELPPLASMA)
  58828. X
  58829. X  was placed in page three of a topic using it in a hot-link (see 2.6.0)
  58830. X  or as context-sensitive help would "go to" page three of that topic.  The
  58831. X  user would then be free to page up and down through the entire topic.
  58832. X
  58833. X    Each topic must have at least one label otherwise it could not be
  58834. X  referred to.
  58835. X
  58836. X
  58837. X2.5.1 The help index label (HELP_INDEX).
  58838. X
  58839. X    When the user wants to go to the "help index" (by pressing F1 while
  58840. X  in help) help will go to a special label named "HELP_INDEX".  Other than
  58841. X  the requirement that it be in every .SRC file you may treat it as any
  58842. X  other label.    It can be used in links or as context-sensitive help.
  58843. X
  58844. X
  58845. X2.5.2 Private labels.
  58846. X
  58847. X    A private label is a label which is local to the help file.  It can be
  58848. X  used in hot-links but cannot be used as context-sensitive help.  A private
  58849. X  label is a label with an "at sign" ('@') as the first character of its
  58850. X  name.  The "at sign" is part of the name.  In the example:
  58851. X
  58852. X    ~(@HELPPLASMA)
  58853. X
  58854. X  "@HELPPLASMA" is a private label.
  58855. X
  58856. X    Private labels are not included in the .H file so you may add or delete
  58857. X  private labels without re-compiling FRACTINT.  Each non-private label
  58858. X  takes up some memory (4 bytes) in FRACTINT so it's best to use private
  58859. X  labels whenever possible.  Use private labels except when you want to use
  58860. X  the label as context-sensitive help.
  58861. X
  58862. X
  58863. X2.6.0 Hot-links.
  58864. X
  58865. X    A hypertext-style hot-link to a label can appear anywhere in the help
  58866. X    text.  To define a hot-link use the following syntax:
  58867. X
  58868. X    {LABEL TEXT}
  58869. X
  58870. X  LABEL is the label to link to and TEXT is the text that will be highlighted.
  58871. X  Only the TEXT field will appear on the help screen.  No blanks are allowed
  58872. X  before the LABEL.  In the sample hot-link:
  58873. X
  58874. X    {HELPMAIN Command Keys in display mode}
  58875. X
  58876. X  "HELPMAIN" is the LABEL and "Command keys in display mode" is the
  58877. X  TEXT to will be hightlighted.
  58878. X
  58879. X
  58880. X2.6.1 Special hot-links.
  58881. X
  58882. X    In addition to normal hot-links to labels "special" links to custom
  58883. X  functions (built into HELP.C) are allowed.  These hot-links have a
  58884. X  negative number (-2..) in place of the LABEL.  No special hot-links are
  58885. X  currently supported in FRACTINT.
  58886. X
  58887. X
  58888. X2.7 Tables.
  58889. X
  58890. X    A table is a way of arranging a group of hot-links into evenly-spaced
  58891. X  columns.  The format for a table is:
  58892. X
  58893. X    ~Table=WIDTH COLS INDENT
  58894. X
  58895. X    << LINKS... >>
  58896. X
  58897. X    ~EndTable
  58898. X
  58899. X  WIDTH is the width of each item, COLS is the number of columns in the
  58900. X  table and INDENT is the number of spaces to indent the table.  LINKS is
  58901. X  a list of hot-links (see 2.6.0) which will be arranged.  Only blanks and
  58902. X  new-lines are allowed between the hot-links; other characters generate
  58903. X  an error.
  58904. X
  58905. X    In the example table:
  58906. X
  58907. X    ~Table=20 3 9
  58908. X    {@ONE One}
  58909. X    {@TWO Two}
  58910. X    {@THREE Three}
  58911. X    {@FOUR Four}
  58912. X    {@FIVE Five}
  58913. X    {SIX Six}
  58914. X    {SEVEN Seven}
  58915. X    {EIGHT Eight}
  58916. X    ~EndTable
  58917. X
  58918. X  20 is the WIDTH, 3 is COLS and INDENT is 9.  The following text would
  58919. X  be produced by the table:
  58920. X
  58921. X    One            Two         Three
  58922. X    Four            Five        Six
  58923. X    Seven            Eight
  58924. X
  58925. X  Each item would be a hot-link linking to its corresponding label (@ONE for
  58926. X  "One", etc.)  Any legal hot-link (to private or non-private labels) may be
  58927. X  used in a table.
  58928. X
  58929. X    The same effect could be produced by arranging the hot-links into
  58930. X  columns yourself but using a table is usually easier (especially if the
  58931. X  label names vary in length).
  58932. X
  58933. X
  58934. X
  58935. X... Second version additional documentation:
  58936. X
  58937. X          New features of the Help Compiler (HC)
  58938. X          ======================================
  58939. X
  58940. X
  58941. XExpanded command format
  58942. X=======================
  58943. X
  58944. X    Several commands may be "strung together" by separating them with commas.
  58945. X  For example:
  58946. X
  58947. X       ~Topic=Help on help, Label=HELPONHELP, Format-
  58948. X
  58949. X  To have a comma as part of a command (like in a topic) precede it with a
  58950. X  backslash.
  58951. X
  58952. X    Commands can be imbedded in the text with the following format:
  58953. X
  58954. X       ~(command)
  58955. X
  58956. X  The text before the tilde and immediately after the ending parend will be
  58957. X  part of the help text.
  58958. X
  58959. X
  58960. XNew commands
  58961. X============
  58962. X
  58963. X    Format[+/-]        L   turns formatting on/off.
  58964. X    Online[+/-]        L   enables/disables display of text in the online
  58965. X               help.
  58966. X    Doc[+/-]           L   enables/disables display of text in the printed
  58967. X               document.  (Currently ignored.)
  58968. X    FormatExclude=NUM  G/L Set the column number in which formatting is
  58969. X               automatically disabled.  (ie. all text after
  58970. X               column NUM is unformatted.)    If before any topics
  58971. X               sets global value, if in a topic sets only for
  58972. X               that topic.
  58973. X    FormatExclude=n    G/L Turn this feature off.  This is the default at the
  58974. X               start of the source file.  Global if before topic,
  58975. X               local otherwise
  58976. X    FormatExclude[+/-] G/L Temporarily enable/disable this feature.  Has no
  58977. X               effect if "FormatDisable=n" is in effect.
  58978. X    FormatExclude=     L   Resets FormatExclude to its global value.
  58979. X    Center[+/-]        L   Enable/Disable automatic centering of text.
  58980. X
  58981. X    All commands with a "L" are local in scope -- they effect only the current
  58982. X  topic.  All commands with a "G" are global in scope.  Commands with "G/L" are
  58983. X  global if used before any topics are defined and local otherwise.  At the
  58984. X  start of each topic the following local settings are in effect:
  58985. X
  58986. X       ~Online+,Doc+,FormatExclude=,Format+,Center-
  58987. X
  58988. X
  58989. XModified commands
  58990. X=================
  58991. X
  58992. X  Label=NAME        replaces the ~(...) command
  58993. X  FF            replaces the ~~ command
  58994. X
  58995. X
  58996. XHot-Links
  58997. X=========
  58998. X
  58999. X  Hot-links have been expanded to support "implicit" links.  These are links
  59000. X  which link to the topic whose title matches the highlighted text.  They have
  59001. X  no label field.  In the example:
  59002. X
  59003. X       Press <C> to goto {Color Cycling Mode}.
  59004. X
  59005. X  The link will link to the topic whose title is "Color Cycling Mode".  The
  59006. X  link must match the topics' title exactly except for case and leading or
  59007. X  trailing blanks.
  59008. X
  59009. X  Normal "explicit" hot-links to labels must now have an equal sign
  59010. X  immediately after the opening curly-brace.  For example:
  59011. X
  59012. X       {=HELPONHELP How do I use help?}
  59013. X
  59014. X
  59015. X  Links to the label named "HELPONHELP".  (The equal sign is not part of the
  59016. X  labels name.)
  59017. X
  59018. X
  59019. XParagraph formatting
  59020. X====================
  59021. X
  59022. X  The HC determines the end of a paragraph when it encounters:
  59023. X
  59024. X    o a blank line.
  59025. X    o a change of indentation after the second line of a paragraph.
  59026. X    o a line ending with a backslash ('\').
  59027. X    o If FormatExclude is enabled any line starting beyond the cut-off
  59028. X      value.
  59029. X
  59030. X  The HC only looks at the left margin of the text to determine paragraph
  59031. X  breaks.  If your not sure the HC can determine a paragraph boundry
  59032. X  append a backslash to the end of the last line of the paragraph.
  59033. X
  59034. X  The following examples illustrate when you need to use a backslash to make
  59035. X  HC format correctly:
  59036. X
  59037. X  1. Paragraph headings.
  59038. X
  59039. X    Heading
  59040. X    Text which follows the heading.  This text is supposed
  59041. X    to be a separate "paragraph" from the heading but the HC
  59042. X    doesn't know that!
  59043. X
  59044. X  This text would be formatted into a single paragraph.  (The word "Text"
  59045. X  would immediately follow "Heading".)  To make it format correctly append
  59046. X  a backslash to the end of "Heading".
  59047. X
  59048. X  2. Single-line bullets.
  59049. X
  59050. X    o Don't branch.
  59051. X    o Use string instructions, but don't go much out of your way
  59052. X      to do so.
  59053. X    o Keep memory accesses to a minimum by avoiding memory operands
  59054. X      and keeping instructions short.
  59055. X
  59056. X    Since the HC cannot tell that the first bullet is a separate paragraph
  59057. X  from the second bullet it would put both bullets into one paragraph.    Any
  59058. X  bullet of two lines or more (assuming the intentation for the second line
  59059. X  of the bullet is different from the first) is OK.  Always add a backslash
  59060. X  to the end of single-line bullets.
  59061. X
  59062. X    In general, if you cannot determine where a paragraph boundry is by
  59063. X  looking at the indentation of each line use a backslash to force a
  59064. X  paragraph break.
  59065. X
  59066. X
  59067. X
  59068. X
  59069. X... Third version additional documentation:
  59070. X
  59071. X  New Commands
  59072. X  ============
  59073. X
  59074. X  ~Comment, ~EndComment
  59075. X    Use to start/end multi-line comments.
  59076. X
  59077. X  ~CompressSpaces[+/-]
  59078. X    Turn on/off the automatic compression of spaces.  Used for data topics
  59079. X    and when reading normal topics with read_topic()
  59080. X
  59081. X  ~Data=label_name
  59082. X    Starts a topic which contains data.  Think of it as a macro for:
  59083. X
  59084. X      ~Topic=, Label=label_name, Format-, CompressSpaces-
  59085. X
  59086. X    Data labels cannot be part of the document or displayed as online help.
  59087. X
  59088. X  ~BinInc filename
  59089. X    Includes a file in binray format (no processing) into a data topic.
  59090. X    This command only works for data topics.  Example:
  59091. X    ~Data=TPLUS_DAT
  59092. X    ~BinInc tplus.dat
  59093. X
  59094. X  ~DocContents
  59095. X    Defines the documents table of contents.  Text is allowed.    Table of
  59096. X    content entries have the following format:
  59097. X
  59098. X      { id, indent, name, [topic, ...] [, FF] }
  59099. X
  59100. X    id       is it's identification (ie, 1.2.1)
  59101. X    indent is the indentation level, (ie. 2)
  59102. X    name   is the text to display to display (ie. Fractint Commands)
  59103. X       If name is in quotes it is also assumed to also be the
  59104. X       title of the first topic.
  59105. X    topic  list of 0 or more topics to print under this item.  Entries
  59106. X       in quotes are assumed to be the title of a topic, other
  59107. X       entries are assumed to be labels.
  59108. X    FF       If this keyword is present the entry will start on a new page in
  59109. X       the document.
  59110. X    It isn't as complex as it sounds; see "~DocContents" in HELP.SRC for
  59111. X    examples.
  59112. X
  59113. X
  59114. X  Quoted implicit hot-links
  59115. X  =========================
  59116. X
  59117. X    HC will ignore quotes areound implicit hot-links when searching for
  59118. X    the matching title.  This allows hot-links like:
  59119. X
  59120. X      {"Video adapter notes"}
  59121. X
  59122. X    intead of:
  59123. X
  59124. X      "{Video adapter notes}"
  59125. X
  59126. X    This is so that the hot-link page numbers don't end up inside the
  59127. X    quotes like: "Video adapter notes (p. 21)".  It also keeps quotes from
  59128. X    being separated from the text in the online-help.
  59129. X
  59130. X
  59131. X  Document printing
  59132. X  =================
  59133. X
  59134. X    The new /p command-line option compiles the .SRC file and prints the
  59135. X    document.  It does NOT write the .HLP file.
  59136. X
  59137. X    The old /p option (set swap path) has been changed to /r.
  59138. X
  59139. X
  59140. X   Printing the document
  59141. X   =====================
  59142. X
  59143. X   The function prototype (in HELP.C) to print the document is:
  59144. X
  59145. X    void print_document(char *outfname, int (*msg_func)(int,int),
  59146. X                int save_extraseg);
  59147. X
  59148. X   outfname is the file to "print" to (usually "FRACTINT.DOC"), msg_func
  59149. X   is a function which is called at the top of each page, and save_extraseg
  59150. X   is true if the data in the extraseg should be preserved.
  59151. X
  59152. X   See print_doc_msg_func() in HELP.C for an example of how to use msg_func.
  59153. X   If msg_func is NULL no msg_func is called.
  59154. X
  59155. X
  59156. X   Printing from help
  59157. X   ==================
  59158. X
  59159. X   There are hooks to print the document from a help topic by selecting a
  59160. X   "special" hot-link. I suggest a format like:
  59161. X
  59162. X    ~Topic=Generating FRACINT.DOC
  59163. X
  59164. X    Explain that selecting yes will print the document, etc...
  59165. X
  59166. X    {=-2  Yes, generate FRACTINT.DOC now. }
  59167. X    {=-1  No, do NOT generate FRACTINT.DOC. }
  59168. X
  59169. X   Selecting yes will generate the document and then return to the previous
  59170. X   topic.  Selecting no will simply return to the previous topic (like
  59171. X   backspace does.)
  59172. X
  59173. X
  59174. X
  59175. SHAR_EOF
  59176. $TOUCH -am 1028230093 hc.doc &&
  59177. chmod 0644 hc.doc ||
  59178. echo "restore of hc.doc failed"
  59179. set `wc -c hc.doc`;Wc_c=$1
  59180. if test "$Wc_c" != "17114"; then
  59181.     echo original size 17114, current size $Wc_c
  59182. fi
  59183. # ============= calcmand.c ==============
  59184. echo "x - extracting calcmand.c (Text)"
  59185. sed 's/^X//' << 'SHAR_EOF' > calcmand.c &&
  59186. X/* calcmand.c
  59187. X * This file contains routines to replace calcmand.asm.
  59188. X *
  59189. X * This file Copyright 1991 Ken Shirriff.  It may be used according to the
  59190. X * fractint license conditions, blah blah blah.
  59191. X */
  59192. X
  59193. X#include <fractint.h>
  59194. X
  59195. Xunsigned long savedmask;
  59196. Xlong linitx, linity;
  59197. X
  59198. Xcalcmandasm() {
  59199. X    printf("Warning: called calcmandasm\n");
  59200. X}
  59201. Xcode16bit() {}
  59202. Xcheckperiod() {}
  59203. Xcode32bit() {}
  59204. SHAR_EOF
  59205. $TOUCH -am 1028230093 calcmand.c &&
  59206. chmod 0644 calcmand.c ||
  59207. echo "restore of calcmand.c failed"
  59208. set `wc -c calcmand.c`;Wc_c=$1
  59209. if test "$Wc_c" != "381"; then
  59210.     echo original size 381, current size $Wc_c
  59211. fi
  59212. # ============= calmanfp.c ==============
  59213. echo "x - extracting calmanfp.c (Text)"
  59214. sed 's/^X//' << 'SHAR_EOF' > calmanfp.c &&
  59215. X/* calmanfp.c
  59216. X * This file contains routines to replace calmanfp.asm.
  59217. X *
  59218. X * This file Copyright 1992 Ken Shirriff.  It may be used according to the
  59219. X * fractint license conditions, blah blah blah.
  59220. X */
  59221. X
  59222. X#include "fractint.h"
  59223. X#include "fractype.h"
  59224. X
  59225. Xextern _CMPLX init, parm, new;
  59226. X
  59227. Xextern int color, oldcolor, realcolor, periodicitycheck, reset_periodicity,
  59228. X    fractype, kbdcount, dotmode, show_orbit, orbit_ptr, potflag, maxit,
  59229. X    inside, outside, fpu;
  59230. X
  59231. Xextern double closenuff, magnitude, rqlim;
  59232. X
  59233. Xstatic int tmp_word, inside_color, periodicity_color;
  59234. X
  59235. Xcalcmandfpasmstart() {
  59236. X    if (inside<0) {
  59237. X    inside_color = maxit;
  59238. X    } else {
  59239. X    inside_color = inside;
  59240. X    }
  59241. X
  59242. X    if (periodicitycheck < 0) {
  59243. X    periodicity_color = 7;
  59244. X    } else {
  59245. X    periodicity_color = inside_color;
  59246. X    }
  59247. X    oldcolor = 0;
  59248. X    return 0;
  59249. X}
  59250. X
  59251. X#define ABS(x) ((x)>0?(x):-(x))
  59252. X#define close 0.01
  59253. X
  59254. Xcalcmandfpasm() {
  59255. X    int cx;
  59256. X    int savedand;
  59257. X    double x,y,x2, y2, xy, Cx, Cy, savedx, savedy;
  59258. X    int savedincr;
  59259. X
  59260. X    if (periodicitycheck==0 || periodicitycheck == -59) {
  59261. X    oldcolor = 0;
  59262. X    } else if (reset_periodicity==0) {
  59263. X    oldcolor = maxit-250;
  59264. X    }
  59265. X
  59266. X    /* initparms */
  59267. X    savedx = 0;
  59268. X    savedy = 0;
  59269. X    savedand = 1;
  59270. X    savedincr = 1;
  59271. X    orbit_ptr = 0;
  59272. X    kbdcount--; /* Only check the keyboard sometimes */
  59273. X    if (kbdcount<0) {
  59274. X    int key;
  59275. X    kbdcount = 1000;
  59276. X    key = keypressed();
  59277. X    if (key) {
  59278. X        if (key=='o' || key=='O') {
  59279. X        getakey();
  59280. X        show_orbit = 1-show_orbit;
  59281. X        } else {
  59282. X        color = -1;
  59283. X        return -1;
  59284. X        }
  59285. X    }
  59286. X    }
  59287. X
  59288. X    cx = maxit;
  59289. X
  59290. X    if (fractype != JULIAFP && fractype != JULIA) {
  59291. X    /* Mandelbrot_87 */
  59292. X    cx--;
  59293. X    Cx = init.x;
  59294. X    Cy = init.y;
  59295. X    x = parm.x+Cx;
  59296. X    y = parm.y+Cy;
  59297. X    } else {
  59298. X    /* dojulia_87 */
  59299. X    Cx = parm.x;
  59300. X    Cy = parm.y;
  59301. X    x = init.x;
  59302. X    y = init.y;
  59303. X    }
  59304. X    x2 = x*x;
  59305. X    y2 = y*y;
  59306. X    xy = x*y;
  59307. X
  59308. X    /* top_of_cs_loop_87 */
  59309. X    do {
  59310. X    x = x2-y2+Cx;
  59311. X    y = 2*xy+Cy;
  59312. X    if (outside<=-2) {
  59313. X        new.x = x;
  59314. X        new.y = y;
  59315. X    }
  59316. X    /* no_save_new_xy_87 */
  59317. X    if (inside==-100) {
  59318. X        /* epsilon_cross */
  59319. X        if (ABS(x)<0.01) {
  59320. X        realcolor = maxit-cx;
  59321. X        if (realcolor==0) realcolor++;
  59322. X        kbdcount -= realcolor;
  59323. X        color = GREEN;
  59324. X        oldcolor = 0;
  59325. X        goto pop_stack;
  59326. X        } else if (ABS(y)<0.01) {
  59327. X        realcolor = maxit-cx;
  59328. X        if (realcolor==0) realcolor++;
  59329. X        kbdcount -= realcolor;
  59330. X        color = BROWN;
  59331. X        oldcolor = 0;
  59332. X        goto pop_stack;
  59333. X        }
  59334. X    }
  59335. X    /* end_epsilon_cross_87 */
  59336. X    if (cx<oldcolor) {
  59337. X        if (savedand==0) {
  59338. X        savedx = x;
  59339. X        savedy = y;
  59340. X        savedincr--;
  59341. X        if (savedincr==0) {
  59342. X            savedand = (savedand<<1) + 1;
  59343. X            savedincr = 4;
  59344. X        } else {
  59345. X            if (ABS(x-savedx)<closenuff && ABS(y-savedy)<closenuff) {
  59346. X            oldcolor = 65535;
  59347. X            realcolor = maxit;
  59348. X            kbdcount = kbdcount-(maxit-cx);
  59349. X            color = periodicity_color;
  59350. X            goto pop_stack;
  59351. X            }
  59352. X        }
  59353. X        }
  59354. X    }
  59355. X    /* no_periodicity_check_87 */
  59356. X    if (show_orbit != 0) {
  59357. X        plot_orbit(x,y,-1);
  59358. X    }
  59359. X    /* no_show_orbit_87 */
  59360. X    x2 = x*x;
  59361. X    y2 = y*y;
  59362. X    xy = x*y;
  59363. X    if (potflag != 0) {
  59364. X        magnitude = x2+y2;
  59365. X    }
  59366. X    if (x2+y2 > rqlim) {
  59367. X        goto over_bailout_87;
  59368. X    }
  59369. X
  59370. X    cx--;
  59371. X    } while (cx>0);
  59372. X
  59373. X    /* reached maxit */
  59374. X    oldcolor = 65535;
  59375. X    kbdcount -= maxit;
  59376. X    realcolor = maxit;
  59377. X    if (inside==-59) {
  59378. X    color = (x2+y2)*maxit/2+1;
  59379. X    } else {
  59380. X        color = inside_color;
  59381. X    }
  59382. X
  59383. Xpop_stack:
  59384. X    
  59385. X    if (orbit_ptr) {
  59386. X    scrub_orbit();
  59387. X    }
  59388. X
  59389. X    return color;
  59390. X
  59391. Xover_bailout_87:
  59392. X    if (cx-10>=0) {
  59393. X    oldcolor = cx-10;
  59394. X    } else {
  59395. X    oldcolor = 0;
  59396. X    }
  59397. X    color = realcolor = maxit-cx;
  59398. X    if (realcolor==0) realcolor = 1;
  59399. X    kbdcount -= realcolor;
  59400. X    if (outside==-1) {
  59401. X    } else if (outside>-2) {
  59402. X    color = outside;
  59403. X    } else {
  59404. X    /* special_outside */
  59405. X    int ax;
  59406. X    if (outside==-2) {
  59407. X        color += new.x + 7;
  59408. X    } else if (outside==-3) {
  59409. X        color += new.y + 7;
  59410. X    } else if (outside==-4) {
  59411. X        if (new.y!=0) {
  59412. X        color *= new.x/new.y;
  59413. X        }
  59414. X    } else if (outside==-5) {
  59415. X        color +=  new.x + new.y;
  59416. X    }
  59417. X    /* check_color */
  59418. X    if (color<0 || color>maxit) {
  59419. X        color = 0;
  59420. X    }
  59421. X    }
  59422. X    goto pop_stack;
  59423. X
  59424. X}
  59425. SHAR_EOF
  59426. $TOUCH -am 1028230193 calmanfp.c &&
  59427. chmod 0644 calmanfp.c ||
  59428. echo "restore of calmanfp.c failed"
  59429. set `wc -c calmanfp.c`;Wc_c=$1
  59430. if test "$Wc_c" != "3910"; then
  59431.     echo original size 3910, current size $Wc_c
  59432. fi
  59433. # ============= diskvidu.c ==============
  59434. echo "x - extracting diskvidu.c (Text)"
  59435. sed 's/^X//' << 'SHAR_EOF' > diskvidu.c &&
  59436. X/*
  59437. X   "Disk-Video" for Unix routines.
  59438. X
  59439. X   All the expanded memory caching stuff has been removed for the Unix
  59440. X   version.  We just keep the data in memory and write it out to a file
  59441. X   when we're done.  (Let virtual memory look after the details.)
  59442. X
  59443. X*/
  59444. X
  59445. X#include <stdio.h>
  59446. X#ifndef XFRACT
  59447. X#include <dos.h>
  59448. X#endif
  59449. X#include "fractint.h"
  59450. X
  59451. Xextern int sxdots, sydots, colors;
  59452. Xextern int dotmode;      /* video access method, 11 if really disk video */
  59453. Xextern int diskisactive;  /* set by fractint to disable re-init */
  59454. Xextern int debugflag;
  59455. Xextern int diskflag;
  59456. X
  59457. X#define BOXROW     6
  59458. X#define BOXCOL     11
  59459. X#define BOXWIDTH 57
  59460. X#define BOXDEPTH 12
  59461. X
  59462. X#define TIMETODISPLAY 10000
  59463. X
  59464. Xint disk16bit=0;       /* storing 16 bit values for continuous potential */
  59465. X
  59466. Xextern int Shadowing, AntiAliasing;
  59467. X
  59468. Xstatic int timetodisplay;
  59469. Xstatic FILE *fp = NULL;
  59470. Xstatic int disktarga;
  59471. X
  59472. Xstatic int headerlength;
  59473. Xstatic unsigned int rowsize = 0;   /* doubles as a disk video not ok flag */
  59474. Xstatic unsigned int colsize;       /* sydots, *2 when pot16bit */
  59475. X
  59476. Xstatic BYTE *dataPtr = NULL;
  59477. X
  59478. Xint startdisk(),pot_startdisk();
  59479. Xvoid enddisk();
  59480. Xint targa_startdisk(FILE *, int);
  59481. Xvoid targa_readdisk (unsigned int, unsigned int,
  59482. X             BYTE *, BYTE *, BYTE *);
  59483. Xvoid targa_writedisk(unsigned int, unsigned int,
  59484. X             BYTE, BYTE, BYTE);
  59485. Xvoid dvid_status(int,char *);
  59486. X
  59487. Xint made_dsktemp = 0;
  59488. X
  59489. Xint startdisk()
  59490. X{
  59491. X   if (!diskisactive)
  59492. X      return(0);
  59493. X   headerlength = disktarga = 0;
  59494. X   return (common_startdisk(sxdots,sydots,colors));
  59495. X   }
  59496. X
  59497. Xint pot_startdisk()
  59498. X{
  59499. X   int i;
  59500. X   if (dotmode == 11) /* ditch the original disk file */
  59501. X      enddisk();
  59502. X   else
  59503. X      showtempmsg("clearing 16bit pot work area");
  59504. X   headerlength = disktarga = 0;
  59505. X   i = common_startdisk(sxdots,sydots<<1,colors);
  59506. X   cleartempmsg();
  59507. X   disk16bit = 1;
  59508. X   return (i);
  59509. X   }
  59510. X
  59511. Xint targa_startdisk(FILE *targafp,int overhead)
  59512. X{
  59513. X   int i;
  59514. X   if (dotmode == 11) { /* ditch the original disk file, make just the targa */
  59515. X      enddisk();      /* close the 'screen' */
  59516. X      setnullvideo(); /* set readdot and writedot routines to do nothing */
  59517. X      }
  59518. X   headerlength = overhead;
  59519. X   fp = targafp;
  59520. X   disktarga = 1;
  59521. X   i = common_startdisk(sxdots*3,sydots,colors);
  59522. X   return (i);
  59523. X}
  59524. X
  59525. Xint _fastcall near common_startdisk(int newrowsize, int newcolsize, int colors)
  59526. X{
  59527. X   int i,success;
  59528. X   long memorysize;
  59529. X
  59530. X   if (diskflag)
  59531. X      enddisk();
  59532. X   if (dotmode == 11) { /* otherwise, real screen also in use, don't hit it */
  59533. X      char buf[20];
  59534. X      helptitle();
  59535. X      setattr(1,0,C_DVID_BKGRD,24*80);    /* init rest to background */
  59536. X      for (i = 0; i < BOXDEPTH; ++i)
  59537. X     setattr(BOXROW+i,BOXCOL,C_DVID_LO,BOXWIDTH);  /* init box */
  59538. X      putstring(BOXROW+2,BOXCOL+4,C_DVID_HI,"'Disk-Video' mode");
  59539. X      putstring(BOXROW+4,BOXCOL+4,C_DVID_LO,"Screen resolution: ");
  59540. X      sprintf(buf,"%d x %d",sxdots,sydots);
  59541. X      putstring(-1,-1,C_DVID_LO,buf);
  59542. X      if (disktarga)
  59543. X     putstring(-1,-1,C_DVID_LO,"  24 bit Targa");
  59544. X      else {
  59545. X     putstring(-1,-1,C_DVID_LO,"  Colors: ");
  59546. X     sprintf(buf,"%d",colors);
  59547. X     putstring(-1,-1,C_DVID_LO,buf);
  59548. X     }
  59549. X      putstring(BOXROW+8,BOXCOL+4,C_DVID_LO,"Status:");
  59550. X      dvid_status(0,"clearing the 'screen'");
  59551. X      }
  59552. X   timetodisplay = TIMETODISPLAY;  /* time-to-display-status counter */
  59553. X
  59554. X   memorysize = (long)(newcolsize) * newrowsize;
  59555. X   diskflag = 1;
  59556. X   rowsize = newrowsize;
  59557. X   colsize = newcolsize;
  59558. X
  59559. X   if (dataPtr != NULL) {
  59560. X       free(dataPtr);
  59561. X   }
  59562. X   dataPtr = (BYTE *)malloc(memorysize);
  59563. X
  59564. X  bzero(dataPtr,memorysize);
  59565. X
  59566. Xcommon_okend:
  59567. X   if (dotmode == 11)
  59568. X      dvid_status(0,"");
  59569. X   return(0);
  59570. X}
  59571. X
  59572. Xvoid enddisk()
  59573. X{
  59574. X   diskflag = rowsize = disk16bit = 0;
  59575. X   fp           = NULL;
  59576. X}
  59577. X
  59578. Xint readdisk(int col, int row)
  59579. X{
  59580. X   char buf[41];
  59581. X   if (--timetodisplay < 0) {  /* time to display status? */
  59582. X      if (dotmode == 11) {
  59583. X     sprintf(buf," reading line %4d",
  59584. X        (row >= sydots) ? row-sydots : row); /* adjust when potfile */
  59585. X     dvid_status(0,buf);
  59586. X     }
  59587. X      timetodisplay = TIMETODISPLAY;
  59588. X      }
  59589. X   if (row>=colsize || col>=rowsize) {
  59590. X       return 0;
  59591. X   }
  59592. X   return dataPtr[row*rowsize+col];
  59593. X}
  59594. X
  59595. Xint FromMemDisk(long offset, int size, void far *dest)
  59596. X{
  59597. X   far_memcpy(dest, (void far *) (dataPtr+offset), size);
  59598. X   return 1;
  59599. X}
  59600. X
  59601. Xvoid targa_readdisk(unsigned int col, unsigned int row,
  59602. X            BYTE *red, BYTE *green, BYTE *blue)
  59603. X{
  59604. X   col *= 3;
  59605. X   *blue  = readdisk(col,row);
  59606. X   *green = readdisk(++col,row);
  59607. X   *red   = readdisk(col+1,row);
  59608. X}
  59609. X
  59610. Xvoid writedisk(int col, int row, int color)
  59611. X{
  59612. X   char buf[41];
  59613. X   if (--timetodisplay < 0) {  /* time to display status? */
  59614. X      if (dotmode == 11) {
  59615. X     sprintf(buf," writing line %4d",
  59616. X        (row >= sydots) ? row-sydots : row); /* adjust when potfile */
  59617. X     dvid_status(0,buf);
  59618. X     }
  59619. X      timetodisplay = TIMETODISPLAY;
  59620. X      }
  59621. X   if (row>=colsize || col>=rowsize) {
  59622. X       return;
  59623. X   }
  59624. X   dataPtr[row*rowsize+col] = color;
  59625. X   if (Shadowing) {
  59626. X      unsigned Mask;
  59627. X      Mask = (1 << AntiAliasing) - 1;
  59628. X      if(!(col & Mask) && !(row & Mask))
  59629. X     ShadowPutColor(col, row, color);
  59630. X      }
  59631. X}
  59632. X
  59633. Xint ToMemDisk(long offset, int size, void far *src)
  59634. X{
  59635. X    far_memcpy((void far *) (dataPtr+offset), src, size);
  59636. X    return 1;
  59637. X}
  59638. X
  59639. Xvoid targa_writedisk(unsigned int col, unsigned int row,
  59640. X            BYTE red, BYTE green, BYTE blue)
  59641. X{
  59642. X   writedisk(col*=3,row,blue);
  59643. X   writedisk(++col, row,green);
  59644. X   writedisk(col+1, row,red);
  59645. X}
  59646. X
  59647. Xvoid dvid_status(int line,char *msg)
  59648. X{
  59649. X   char buf[41];
  59650. X   int attrib;
  59651. X   memset(buf,' ',40);
  59652. X   memcpy(buf,msg,strlen(msg));
  59653. X   buf[40] = 0;
  59654. X   attrib = C_DVID_HI;
  59655. X   if (line >= 100) {
  59656. X      line -= 100;
  59657. X      attrib = C_STOP_ERR;
  59658. X      }
  59659. X   putstring(BOXROW+8+line,BOXCOL+12,attrib,buf);
  59660. X   movecursor(25,80);
  59661. X}
  59662. SHAR_EOF
  59663. $TOUCH -am 1028230193 diskvidu.c &&
  59664. chmod 0644 diskvidu.c ||
  59665. echo "restore of diskvidu.c failed"
  59666. set `wc -c diskvidu.c`;Wc_c=$1
  59667. if test "$Wc_c" != "5594"; then
  59668.     echo original size 5594, current size $Wc_c
  59669. fi
  59670. # ============= fpu087.c ==============
  59671. echo "x - extracting fpu087.c (Text)"
  59672. sed 's/^X//' << 'SHAR_EOF' > fpu087.c &&
  59673. X/* Fpu087.c
  59674. X * This file contains routines to replace fpu087.asm.
  59675. X *
  59676. X * This file Copyright 1991 Ken Shirriff.  It may be used according to the
  59677. X * fractint license conditions, blah blah blah.
  59678. X */
  59679. X
  59680. X#include <fractint.h>
  59681. X#include <mpmath.h>
  59682. X#include <math.h>
  59683. X
  59684. Xextern int DivideOverflow;
  59685. X
  59686. X/*
  59687. X *----------------------------------------------------------------------
  59688. X *
  59689. X * xxx086 --
  59690. X *
  59691. X *    Simulate integer math routines using floating point.
  59692. X *    This will of course slow things down, so this should all be
  59693. X *    changed at some point.
  59694. X *
  59695. X *----------------------------------------------------------------------
  59696. X */
  59697. X
  59698. Xvoid FPUaptan387(double *y, double *x, double *atan)
  59699. X{
  59700. X    *atan = atan2(*y,*x);
  59701. X}
  59702. X
  59703. Xvoid FPUcplxmul(_CMPLX *x, _CMPLX *y, _CMPLX *z)
  59704. X{
  59705. X    double tx;
  59706. X    tx = x->x * y->x - x->y * y->y;
  59707. X    z->y = x->x * y->y + x->y * y->x;
  59708. X    z->x = tx;
  59709. X}
  59710. X
  59711. Xvoid FPUcplxdiv(_CMPLX *x, _CMPLX *y, _CMPLX *z)
  59712. X{
  59713. X    double mod,tx,ty,yxmod,yymod;
  59714. X    mod = y->x * y->x + y->y * y->y;
  59715. X    if (mod==0) {
  59716. X    DivideOverflow++;
  59717. X    }
  59718. X    yxmod = y->x/mod;
  59719. X    yymod = - y->y/mod;
  59720. X    tx = x->x * yxmod - x->y * yymod;
  59721. X    z->y = x->x * yymod + x->y * yxmod;
  59722. X    z->x = tx;
  59723. X}
  59724. X
  59725. Xvoid FPUsincos(double *Angle, double *Sin, double *Cos)
  59726. X{
  59727. X    *Sin = sin(*Angle);
  59728. X    *Cos = cos(*Angle);
  59729. X}
  59730. X
  59731. Xvoid FPUsinhcosh(double *Angle, double *Sinh, double *Cosh)
  59732. X{
  59733. X    *Sinh = sinh(*Angle);
  59734. X    *Cosh = cosh(*Angle);
  59735. X}
  59736. X
  59737. Xvoid FPUcplxlog(_CMPLX *x, _CMPLX *z)
  59738. X{
  59739. X    double mod,zx,zy;
  59740. X    mod = sqrt(x->x*x->x + x->y*x->y);
  59741. X    zx = log(mod);
  59742. X    zy = atan2(x->y,x->x);
  59743. X
  59744. X    z->x = zx;
  59745. X    z->y = zy;
  59746. X}
  59747. X
  59748. Xvoid FPUcplxexp387(_CMPLX *x, _CMPLX *z)
  59749. X{
  59750. X    double pow,y;
  59751. X    y = x->y;
  59752. X    pow = exp(x->x);
  59753. X    z->x = pow*cos(y);
  59754. X    z->y = pow*sin(y);
  59755. X}
  59756. X
  59757. X/* Integer Routines */
  59758. Xvoid SinCos086(long x, long *sinx, long *cosx)
  59759. X{
  59760. X    double a;
  59761. X    a = x/(double)(1<<16);
  59762. X    *sinx = (long) (sin(a)*(double)(1<<16));
  59763. X    *cosx = (long) (cos(a)*(double)(1<<16));
  59764. X}
  59765. X
  59766. Xvoid SinhCosh086(long x, long *sinx, long *cosx)
  59767. X{
  59768. X    double a;
  59769. X    a = x/(double)(1<<16);
  59770. X    *sinx = (long) (sinh(a)*(double)(1<<16));
  59771. X    *cosx = (long) (cosh(a)*(double)(1<<16));
  59772. X}
  59773. X
  59774. Xlong Exp086(x)
  59775. Xlong x;
  59776. X{
  59777. X    return (long) (exp((double)x/(double)(1<<16))*(double)(1<<16));
  59778. X}
  59779. X
  59780. X#define em2float(l) (*(float *)&(l))
  59781. X#define float2em(f) (*(long *)&(f))
  59782. X
  59783. X/*
  59784. X * Input is a 16 bit offset number.  Output is shifted by Fudge.
  59785. X */
  59786. Xunsigned long ExpFudged(x, Fudge)
  59787. Xlong x;
  59788. Xint Fudge;
  59789. X{
  59790. X    return (long) (exp((double)x/(double)(1<<16))*(double)(1<<Fudge));
  59791. X}
  59792. X
  59793. X/* This multiplies two e/m numbers and returns an e/m number. */
  59794. Xlong r16Mul(x,y)
  59795. Xlong x,y;
  59796. X{
  59797. X    float f;
  59798. X    f = em2float(x)*em2float(y);
  59799. X    return float2em(f);
  59800. X}
  59801. X
  59802. X/* This takes an exp/mant number and returns a shift-16 number */
  59803. Xlong LogFloat14(x)
  59804. Xunsigned long x;
  59805. X{
  59806. X    return log((double)em2float(x))*(1<<16);
  59807. X}
  59808. X
  59809. X/* This divides two e/m numbers and returns an e/m number. */
  59810. Xlong RegDivFloat(x,y)
  59811. Xlong x,y;
  59812. X{
  59813. X    float f;
  59814. X    f = em2float(x)/em2float(y);
  59815. X    return float2em(f);
  59816. X}
  59817. X
  59818. X/*
  59819. X * This routine on the IBM converts shifted integer x,FudgeFact to 
  59820. X * the 4 byte number: exp,mant,mant,mant
  59821. X * Instead of using exp/mant format, we'll just use floats.
  59822. X * Note: If sizeof(float) != sizeof(long), we're hosed.
  59823. X */
  59824. Xlong RegFg2Float(x,FudgeFact)
  59825. Xlong x;
  59826. Xint FudgeFact;
  59827. X{
  59828. X    float f;
  59829. X    long l;
  59830. X    f = x/(float)(1<<FudgeFact);
  59831. X    l = float2em(f);
  59832. X    return l;
  59833. X}
  59834. X
  59835. X/*
  59836. X * This converts em to shifted integer format.
  59837. X */
  59838. Xlong RegFloat2Fg(x,Fudge)
  59839. Xlong x;
  59840. Xint Fudge;
  59841. X{
  59842. X    return em2float(x)*(float)(1<<Fudge);
  59843. X}
  59844. X
  59845. Xlong RegSftFloat(x, Shift)
  59846. Xlong x;
  59847. Xint Shift;
  59848. X{
  59849. X    float f;
  59850. X    f = em2float(x);
  59851. X    if (Shift>0) {
  59852. X    f *= (1<<Shift);
  59853. X    } else {
  59854. X    f /= (1<<Shift);
  59855. X    }
  59856. X    return float2em(f);
  59857. X}
  59858. SHAR_EOF
  59859. $TOUCH -am 1028230193 fpu087.c &&
  59860. chmod 0644 fpu087.c ||
  59861. echo "restore of fpu087.c failed"
  59862. set `wc -c fpu087.c`;Wc_c=$1
  59863. if test "$Wc_c" != "3671"; then
  59864.     echo original size 3671, current size $Wc_c
  59865. fi
  59866. # ============= fracsuba.c ==============
  59867. echo "x - extracting fracsuba.c (Text)"
  59868. sed 's/^X//' << 'SHAR_EOF' > fracsuba.c &&
  59869. X#include "fractint.h"
  59870. X
  59871. Xextern long ltempsqrx,ltempsqry;
  59872. Xextern long lmagnitud, llimit, llimit2, lclosenuff, l16triglim;
  59873. Xextern int overflow, bitshift;
  59874. Xextern _LCMPLX lold, lnew;
  59875. X
  59876. Xlongbailout()
  59877. X{
  59878. X    ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  59879. X    lmagnitud = ltempsqrx + ltempsqry;
  59880. X    if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
  59881. X    || labs(lnew.y) > llimit2 || overflow)
  59882. X        { overflow=0;
  59883. X        return(1); }
  59884. X    lold = lnew;
  59885. X    return(0);
  59886. X}
  59887. X
  59888. XFManOWarfpFractal() {}
  59889. XFJuliafpFractal() {}
  59890. XFBarnsley1FPFractal() {}
  59891. XFBarnsley2FPFractal() {}
  59892. XFLambdaFPFractal() {}
  59893. SHAR_EOF
  59894. $TOUCH -am 1028230193 fracsuba.c &&
  59895. chmod 0644 fracsuba.c ||
  59896. echo "restore of fracsuba.c failed"
  59897. set `wc -c fracsuba.c`;Wc_c=$1
  59898. if test "$Wc_c" != "589"; then
  59899.     echo original size 589, current size $Wc_c
  59900. fi
  59901. # ============= general.c ==============
  59902. echo "x - extracting general.c (Text)"
  59903. sed 's/^X//' << 'SHAR_EOF' > general.c &&
  59904. X/* generalasm.c
  59905. X * This file contains routines to replace general.asm.
  59906. X *
  59907. X * This file Copyright 1991 Ken Shirriff.  It may be used according to the
  59908. X * fractint license conditions, blah blah blah.
  59909. X */
  59910. X
  59911. X#include <string.h>
  59912. X#ifndef NOBSTRING
  59913. X/* If this gives you an error, read the README and modify the Makefile. */
  59914. X#include <bstring.h>
  59915. X#endif
  59916. X#include <stdio.h>
  59917. X#include <stdlib.h>
  59918. X#include <sys/types.h>
  59919. X#include <sys/time.h>
  59920. X#include "fractint.h"
  59921. X
  59922. Xint overflow = 0;
  59923. X
  59924. Xchar boxx[9216], boxy[4096];
  59925. Xchar boxvalues[2048];
  59926. Xchar tstack[4096];
  59927. X
  59928. Xextern int tabmode;
  59929. X
  59930. Xint DivideOverflow = 0;
  59931. Xint iit=0;
  59932. Xint cpu=0;        /* cpu type: 86, 186, 286, or 386 */
  59933. X#ifndef XFRACT
  59934. Xint fpu=0;        /* fpu type: 0, 87, 287, 387 */
  59935. X#else
  59936. Xint fpu=1;
  59937. X#endif
  59938. X
  59939. XSEGTYPE extraseg=0;        /* extra 64K segment (allocated by init) */
  59940. X/* ********************** Mouse Support Variables ************************** */
  59941. X
  59942. Xint lookatmouse=0;    /* see notes at mouseread routine */
  59943. Xint savebase=0;        /* base clock ticks */ 
  59944. Xint saveticks=0;    /* save after this many ticks */ 
  59945. Xint finishrow=0;    /* save when this row is finished */
  59946. X
  59947. Xint inside_help = 0;
  59948. X
  59949. Xextern int slides;    /* 1 for playback */
  59950. X
  59951. Xvoid toextra(tooffset, fromaddr, fromcount)
  59952. Xint tooffset;
  59953. Xchar *fromaddr;
  59954. Xint fromcount;
  59955. X{
  59956. X    bcopy(fromaddr,(char *)(extraseg+tooffset),fromcount);
  59957. X}
  59958. X
  59959. Xvoid fromextra(fromoffset, toaddr, tocount)
  59960. Xint fromoffset;
  59961. Xchar *toaddr;
  59962. Xint tocount;
  59963. X{
  59964. X    bcopy((char *)(extraseg+fromoffset),toaddr,tocount);
  59965. X}
  59966. X
  59967. Xint
  59968. Xcmpextra(cmpoffset,cmpaddr,cmpcount)
  59969. Xint cmpoffset;
  59970. Xchar *cmpaddr;
  59971. Xint cmpcount;
  59972. X{
  59973. X    return bcmp((char *)(extraseg+cmpoffset),cmpaddr,cmpcount);
  59974. X}
  59975. X
  59976. X/*
  59977. X; ****************** Function initasmvars() *****************************
  59978. X*/
  59979. Xvoid
  59980. Xinitasmvars()
  59981. X{
  59982. X    if (cpu!=0) return;
  59983. X    overflow = 0;
  59984. X    extraseg = malloc(0x18000);
  59985. X
  59986. X    /* set cpu type */
  59987. X    cpu = 1;
  59988. X
  59989. X    /* set fpu type */
  59990. X#ifndef XFRACT
  59991. X    fpu = 0;
  59992. X#else
  59993. X    fpu = 1;
  59994. X#endif
  59995. X
  59996. X}
  59997. X
  59998. Xvoid fpe_handler(int signum)
  59999. X{
  60000. X    overflow = 1;
  60001. X}
  60002. X
  60003. X/*
  60004. X;
  60005. X;       32-bit integer multiply routine with an 'n'-bit shift.
  60006. X;       Overflow condition returns 0x7fffh with overflow = 1;
  60007. X;
  60008. X;       long x, y, z, multiply();
  60009. X;       int n;
  60010. X;
  60011. X;       z = multiply(x,y,n)
  60012. X;
  60013. X*/
  60014. Xstatic float
  60015. Xtofloat(x,n)
  60016. Xlong x;
  60017. Xint n;
  60018. X{
  60019. X    return (float)x/(float)(1<<n);
  60020. X}
  60021. X/*
  60022. X * 32 bit integer multiply with n bit shift.
  60023. X * Note that we fake integer multiplication with floating point
  60024. X * multiplication.
  60025. X */
  60026. Xlong
  60027. Xmultiply(x, y, n)
  60028. Xlong x,y;
  60029. Xint n;
  60030. X{
  60031. X    register long l;
  60032. X    l = ((float)x)* ((float)y)/(float)(1<<n);
  60033. X    if (l==0x7fffffff) {
  60034. X    overflow = 1;
  60035. X    }
  60036. X    return l;
  60037. X}
  60038. X
  60039. X/*
  60040. X;
  60041. X;       32-bit integer divide routine with an 'n'-bit shift.
  60042. X;       Overflow condition returns 0x7fffh with overflow = 1;
  60043. X;
  60044. X;       z = divide(x,y,n);       z = x / y;
  60045. X*/
  60046. Xlong
  60047. Xdivide(x,y,n)
  60048. Xlong x,y;
  60049. Xint n;
  60050. X{
  60051. X    return (long) ( ((float)x)/ ((float)y)*(float)(1<<n));
  60052. X}
  60053. X
  60054. X/*
  60055. X; ****************** Function getakey() *****************************
  60056. X; **************** Function keypressed() ****************************
  60057. X
  60058. X;       'getakey()' gets a key from either a "normal" or an enhanced
  60059. X;       keyboard.   Returns either the vanilla ASCII code for regular
  60060. X;       keys, or 1000+(the scan code) for special keys (like F1, etc)
  60061. X;       Use of this routine permits the Control-Up/Down arrow keys on
  60062. X;       enhanced keyboards.
  60063. X;
  60064. X;       The concept for this routine was "borrowed" from the MSKermit
  60065. X;       SCANCHEK utility
  60066. X;
  60067. X;       'keypressed()' returns a zero if no keypress is outstanding,
  60068. X;       and the value that 'getakey()' will return if one is.  Note
  60069. X;       that you must still call 'getakey()' to flush the character.
  60070. X;       As a sidebar function, calls 'help()' if appropriate, or
  60071. X;       'tab_display()' if appropriate.
  60072. X;       Think of 'keypressed()' as a super-'kbhit()'.
  60073. X*/
  60074. Xint keybuffer = 0;
  60075. Xkeypressed() {
  60076. X    int ch;
  60077. X    ch = getkeynowait();
  60078. X    if (!ch) return 0;
  60079. X    keybuffer = ch;
  60080. X    if (ch==F1 && helpmode) {
  60081. X    keybuffer = 0;
  60082. X    inside_help = 1;
  60083. X    help(0);
  60084. X    inside_help = 0;
  60085. X    restore_active_ovly();
  60086. X    return 0;
  60087. X    } else if (ch==TAB && tabmode) {
  60088. X    keybuffer = 0;
  60089. X    tab_display();
  60090. X    restore_active_ovly();
  60091. X    return 0;
  60092. X    }
  60093. X    return ch;
  60094. X}
  60095. X
  60096. X/* Wait for a key.
  60097. X * This should be used instead of:
  60098. X * while (!keypressed()) {}
  60099. X * If timeout=1, waitkeypressed will time out after .5 sec.
  60100. X */
  60101. Xwaitkeypressed(timeout)
  60102. Xint timeout;
  60103. X{
  60104. X    int status;
  60105. X    while (!keybuffer) {
  60106. X    keybuffer = getkeyint(1);
  60107. X    if (timeout) break;
  60108. X    }
  60109. X    return keypressed();
  60110. X}
  60111. X
  60112. X/*
  60113. X * This routine returns a key, ignoring F1
  60114. X */
  60115. Xgetakeynohelp() {
  60116. X    int ch;
  60117. X    while (1) {
  60118. X    ch = getakey();
  60119. X    if (ch != F1) break;
  60120. X    }
  60121. X    return ch;
  60122. X}
  60123. X/* 
  60124. X * This routine returns a keypress
  60125. X */
  60126. Xgetakey()
  60127. X{
  60128. X    int ch;
  60129. X
  60130. X    do {
  60131. X    ch = getkeyint(1);
  60132. X    } while (ch==0);
  60133. X    return ch;
  60134. X}
  60135. X
  60136. X/*
  60137. X * This routine returns the current key, or 0.
  60138. X */
  60139. Xgetkeynowait() {
  60140. X    return getkeyint(0);
  60141. X}
  60142. X
  60143. X/*
  60144. X * This is the low level key handling routine.
  60145. X * If block is set, we want to block before returning, since we are waiting
  60146. X * for a key press.
  60147. X * We also have to handle the slide file, etc.
  60148. X */
  60149. X
  60150. Xgetkeyint(block)
  60151. Xint block;
  60152. X{
  60153. X    int ch;
  60154. X    int curkey;
  60155. X    if (keybuffer) {
  60156. X    ch = keybuffer;
  60157. X    keybuffer = 0;
  60158. X    return ch;
  60159. X    }
  60160. X    curkey = xgetkey(0);
  60161. X    if (slides==1 && curkey == ESC) {
  60162. X    stopslideshow();
  60163. X    return 0;
  60164. X    }
  60165. X
  60166. X    if (curkey==0 && slides==1) {
  60167. X    curkey = slideshw();
  60168. X    }
  60169. X
  60170. X    if (curkey==0 && block) {
  60171. X    curkey = xgetkey(1);
  60172. X    if (slides==1 && curkey == ESC) {
  60173. X        stopslideshow();
  60174. X        return 0;
  60175. X    }
  60176. X    }
  60177. X
  60178. X    if (curkey && slides==2) {
  60179. X    recordshw(curkey);
  60180. X    }
  60181. X
  60182. X    return curkey;
  60183. X}
  60184. X
  60185. X/*
  60186. X; ****************** Function buzzer(int buzzertype) *******************
  60187. X;
  60188. X;       Sound a tone based on the value of the parameter
  60189. X;
  60190. X;       0 = normal completion of task
  60191. X;       1 = interrupted task
  60192. X;       2 = error contition
  60193. X
  60194. X;       "buzzer()" codes:  strings of two-word pairs
  60195. X;               (frequency in cycles/sec, delay in milliseconds)
  60196. X;               frequency == 0 means no sound
  60197. X;               delay     == 0 means end-of-tune
  60198. X*/
  60199. Xvoid
  60200. Xbuzzer(buzzertype)
  60201. Xint buzzertype;
  60202. X{
  60203. X    printf("\007");
  60204. X    fflush(stdout);
  60205. X    if (buzzertype==0) {
  60206. X    redrawscreen();
  60207. X    }
  60208. X}
  60209. X
  60210. X/*
  60211. X; ***************** Function delay(int delaytime) ************************
  60212. X;
  60213. X;       performs a delay loop for 'delaytime' milliseconds
  60214. X*/
  60215. Xvoid
  60216. Xdelay(delaytime)
  60217. Xint delaytime;
  60218. X{
  60219. X    static struct timeval delay;
  60220. X    delay.tv_sec = delaytime/1000;
  60221. X    delay.tv_usec = (delaytime%1000)*1000;
  60222. X    (void) select(0, (int *) 0, (int *) 0, (int *) 0, &delay);
  60223. X}
  60224. X
  60225. X/*
  60226. X; ************** Function tone(int frequency,int delaytime) **************
  60227. X;
  60228. X;       buzzes the speaker with this frequency for this amount of time
  60229. X*/
  60230. Xvoid
  60231. Xtone(frequency, delaytime)
  60232. Xint frequency, delaytime;
  60233. X{
  60234. X}
  60235. X
  60236. X/*
  60237. X; ************** Function snd(int hertz) and nosnd() **************
  60238. X;
  60239. X;       turn the speaker on with this frequency (snd) or off (nosnd)
  60240. X;
  60241. X; *****************************************************************
  60242. X*/
  60243. Xvoid
  60244. Xsnd(hertz)
  60245. Xint hertz;
  60246. X{
  60247. X}
  60248. X
  60249. Xvoid
  60250. Xnosnd()
  60251. X{}
  60252. X
  60253. X/*
  60254. X; long readticker() returns current bios ticker value
  60255. X*/
  60256. Xlong
  60257. Xreadticker()
  60258. X{
  60259. X    return clock_ticks();
  60260. X}
  60261. X
  60262. X/*
  60263. X; ************************* Far Segment RAM Support **************************
  60264. X;
  60265. X;
  60266. X;       farptr = (char far *)farmemalloc(long bytestoalloc);
  60267. X;       (void)farmemfree(farptr);
  60268. X*/
  60269. X
  60270. XVOIDPTR 
  60271. Xfarmemalloc(len)
  60272. Xlong len;
  60273. X{
  60274. X    return (VOIDPTR )malloc((unsigned)len);
  60275. X}
  60276. X
  60277. Xvoid
  60278. Xfarmemfree(addr)
  60279. XVOIDPTR addr;
  60280. X{
  60281. X    free((char *)addr);
  60282. X}
  60283. X
  60284. Xerasesegment(segaddress,segvalue)
  60285. X{
  60286. X}
  60287. X
  60288. X
  60289. Xint
  60290. Xfarread(handle, buf, len)
  60291. Xint handle;
  60292. XVOIDPTR buf;
  60293. Xunsigned len;
  60294. X{
  60295. X    return read(handle, buf, len);
  60296. X}
  60297. X
  60298. Xint
  60299. Xfarwrite(handle, buf, len)
  60300. Xint handle;
  60301. XVOIDPTR buf;
  60302. Xunsigned len;
  60303. X{
  60304. X    return write(handle,buf,len);
  60305. X}
  60306. X
  60307. X
  60308. Xlong
  60309. Xnormalize(ptr)
  60310. Xchar *ptr;
  60311. X{
  60312. X    return (long) ptr;
  60313. X}
  60314. X
  60315. X/*
  60316. X; *************** Far string/memory functions *********
  60317. X*/
  60318. Xint
  60319. Xfar_strlen (a)
  60320. Xchar *a;
  60321. X{
  60322. X    return strlen(a);
  60323. X}
  60324. X
  60325. X
  60326. Xint
  60327. Xfar_strcpy (a,b)
  60328. Xchar *a,*b;
  60329. X{
  60330. X    return (int)strcpy(a,b);
  60331. X}
  60332. X
  60333. Xint
  60334. Xfar_strcmp (a,b)
  60335. Xchar *a, *b;
  60336. X{
  60337. X    return strcmp(a,b);
  60338. X}
  60339. X
  60340. Xint
  60341. Xfar_stricmp(a,b)
  60342. Xchar *a,*b;
  60343. X{
  60344. X    return stricmp(a,b);
  60345. X}
  60346. X
  60347. Xint
  60348. Xfar_strnicmp(a,b,n)
  60349. Xchar *a,*b;
  60350. Xint n;
  60351. X{
  60352. X    return strnicmp(a,b,n);
  60353. X}
  60354. X
  60355. Xint
  60356. Xfar_strcat (a,b)
  60357. Xchar *a,*b;
  60358. X{
  60359. X    return (int)strcat(a,b);
  60360. X}
  60361. X
  60362. Xint
  60363. Xfar_memset ( a,c,len)
  60364. XVOIDPTR a;
  60365. Xint c;
  60366. Xint len;
  60367. X{
  60368. X    return (int)memset(a,c,len);
  60369. X}
  60370. X
  60371. Xint
  60372. Xfar_memcpy ( a,b,len)
  60373. XVOIDFARPTR a,b;
  60374. Xint len;
  60375. X{
  60376. X    memcpy(a,b,len);
  60377. X    return (int)a;
  60378. X}
  60379. X
  60380. Xint
  60381. Xfar_memcmp (a,b,len)
  60382. XVOIDFARPTR a,b;
  60383. Xint len;
  60384. X{
  60385. X    return memcmp(a,b,len);
  60386. X}
  60387. X
  60388. Xint
  60389. Xfar_memicmp(a,b,len)
  60390. XVOIDFARPTR a,b;
  60391. Xint len;
  60392. X{
  60393. X    return memicmp(a,b,len);
  60394. X}
  60395. X
  60396. X/*
  60397. X * Extended memory support
  60398. X */
  60399. X
  60400. XBYTE *
  60401. Xemmquery()
  60402. X{
  60403. X}
  60404. X
  60405. Xunsigned int
  60406. Xemmgetfree()
  60407. X{}
  60408. X
  60409. Xunsigned int
  60410. Xemmallocate(len)
  60411. Xunsigned int len;
  60412. X{}
  60413. X
  60414. Xvoid
  60415. Xemmdeallocate(len)
  60416. Xunsigned int len;
  60417. X{}
  60418. X
  60419. Xvoid
  60420. Xemmgetpage(a,b)
  60421. Xunsigned int a, b;
  60422. X{}
  60423. X
  60424. Xvoid
  60425. Xemmclearpage(a,b)
  60426. Xunsigned int a, b;
  60427. X{}
  60428. X
  60429. X
  60430. Xunsigned int *
  60431. Xxmmquery()
  60432. X{}
  60433. X
  60434. Xunsigned int
  60435. Xxmmallocate(a)
  60436. Xunsigned int a;
  60437. X{}
  60438. X
  60439. Xvoid
  60440. Xxmmdeallocate(a)
  60441. Xunsigned int a;
  60442. X{}
  60443. X
  60444. Xvoid
  60445. Xxmmmoveextended(a)
  60446. Xint a;
  60447. X{}
  60448. X
  60449. X/*
  60450. X * IIT coprocessor routines.
  60451. X */
  60452. X
  60453. Xload_mat(matrix)
  60454. Xdouble matrix[16];
  60455. X{}
  60456. X
  60457. Xvoid
  60458. Xmult_vec_iit(vector)
  60459. Xdouble vector[3];
  60460. X{}
  60461. X
  60462. Xint
  60463. XIITCoPro() {
  60464. X    return 0;
  60465. X}
  60466. X
  60467. Xint F4x4Check()
  60468. X{
  60469. X}
  60470. X
  60471. Xvoid F4x4Free() {}
  60472. X
  60473. Xint F4x4Lock() {}
  60474. X
  60475. X
  60476. X/* --------------------------------------------------------------------
  60477. X * The following routines are used for encoding/decoding gif images.
  60478. X * If we aren't on a PC, things are rough for decoding the fractal info
  60479. X * structure in the GIF file.  These routines look after converting the
  60480. X * MS_DOS format data into a form we can use.
  60481. X * If dir==0, we convert to MSDOS form.  Otherwise we convert from MSDOS.
  60482. X */
  60483. X
  60484. Xstatic getChar(), getInt(), getLong(), getFloat(), getDouble();
  60485. X
  60486. Xdecode_fractal_info(info,dir)
  60487. X    struct fractal_info *info;
  60488. X    int dir;
  60489. X{
  60490. X    unsigned char *buf;
  60491. X    unsigned char *bufPtr;
  60492. X    int i;
  60493. X
  60494. X    if (dir==1) {
  60495. X    buf = (unsigned char *)malloc(FRACTAL_INFO_SIZE);
  60496. X    bufPtr = buf;
  60497. X    bcopy((char *)info,(char *)buf,FRACTAL_INFO_SIZE);
  60498. X    }  else {
  60499. X    buf = (unsigned char *)malloc(sizeof(struct fractal_info));
  60500. X    bufPtr = buf;
  60501. X    bcopy((char *)info,(char *)buf,sizeof(struct fractal_info));
  60502. X    }
  60503. X
  60504. X    if (dir==1) {
  60505. X    strncpy(info->info_id,bufPtr,8);
  60506. X    } else {
  60507. X    strncpy(bufPtr,info->info_id,8);
  60508. X    }
  60509. X    bufPtr += 8;
  60510. X    getInt(&info->iterations,&bufPtr,dir);
  60511. X    getInt(&info->fractal_type,&bufPtr,dir);
  60512. X    getDouble(&info->xmin,&bufPtr,dir);
  60513. X    getDouble(&info->xmax,&bufPtr,dir);
  60514. X    getDouble(&info->ymin,&bufPtr,dir);
  60515. X    getDouble(&info->ymax,&bufPtr,dir);
  60516. X    getDouble(&info->creal,&bufPtr,dir);
  60517. X    getDouble(&info->cimag,&bufPtr,dir);
  60518. X    getInt(&info->videomodeax,&bufPtr,dir);
  60519. X    getInt(&info->videomodebx,&bufPtr,dir);
  60520. X    getInt(&info->videomodecx,&bufPtr,dir);
  60521. X    getInt(&info->videomodedx,&bufPtr,dir);
  60522. X    getInt(&info->dotmode,&bufPtr,dir);
  60523. X    getInt(&info->xdots,&bufPtr,dir);
  60524. X    getInt(&info->ydots,&bufPtr,dir);
  60525. X    getInt(&info->colors,&bufPtr,dir);
  60526. X    getInt(&info->version,&bufPtr,dir);
  60527. X    getFloat(&info->parm3,&bufPtr,dir);
  60528. X    getFloat(&info->parm4,&bufPtr,dir);
  60529. X    getFloat(&info->potential[0],&bufPtr,dir);
  60530. X    getFloat(&info->potential[1],&bufPtr,dir);
  60531. X    getFloat(&info->potential[2],&bufPtr,dir);
  60532. X    getInt(&info->rseed,&bufPtr,dir);
  60533. X    getInt(&info->rflag,&bufPtr,dir);
  60534. X    getInt(&info->biomorph,&bufPtr,dir);
  60535. X    getInt(&info->inside,&bufPtr,dir);
  60536. X    getInt(&info->logmap,&bufPtr,dir);
  60537. X    getFloat(&info->invert[0],&bufPtr,dir);
  60538. X    getFloat(&info->invert[1],&bufPtr,dir);
  60539. X    getFloat(&info->invert[2],&bufPtr,dir);
  60540. X    getInt(&info->decomp[0],&bufPtr,dir);
  60541. X    getInt(&info->decomp[1],&bufPtr,dir);
  60542. X    getInt(&info->symmetry,&bufPtr,dir);
  60543. X    for (i=0;i<16;i++) {
  60544. X    getInt(&info->init3d[i],&bufPtr,dir);
  60545. X    }
  60546. X    getInt(&info->previewfactor,&bufPtr,dir);
  60547. X    getInt(&info->xtrans,&bufPtr,dir);
  60548. X    getInt(&info->ytrans,&bufPtr,dir);
  60549. X    getInt(&info->red_crop_left,&bufPtr,dir);
  60550. X    getInt(&info->red_crop_right,&bufPtr,dir);
  60551. X    getInt(&info->blue_crop_left,&bufPtr,dir);
  60552. X    getInt(&info->blue_crop_right,&bufPtr,dir);
  60553. X    getInt(&info->red_bright,&bufPtr,dir);
  60554. X    getInt(&info->blue_bright,&bufPtr,dir);
  60555. X    getInt(&info->xadjust,&bufPtr,dir);
  60556. X    getInt(&info->eyeseparation,&bufPtr,dir);
  60557. X    getInt(&info->glassestype,&bufPtr,dir);
  60558. X    getInt(&info->outside,&bufPtr,dir);
  60559. X    getDouble(&info->x3rd,&bufPtr,dir);
  60560. X    getDouble(&info->y3rd,&bufPtr,dir);
  60561. X    getChar(&info->stdcalcmode,&bufPtr,dir);
  60562. X    getChar(&info->useinitorbit,&bufPtr,dir);
  60563. X    getInt(&info->calc_status,&bufPtr,dir);
  60564. X    getLong(&info->tot_extend_len,&bufPtr,dir);
  60565. X    getInt(&info->distest,&bufPtr,dir);
  60566. X    getInt(&info->floatflag,&bufPtr,dir);
  60567. X    getInt(&info->bailout,&bufPtr,dir);
  60568. X    getLong(&info->calctime,&bufPtr,dir);
  60569. X    for (i=0;i<4;i++) {
  60570. X    getChar(&info->trigndx[i],&bufPtr,dir);
  60571. X    }
  60572. X    getInt(&info->finattract,&bufPtr,dir);
  60573. X    getDouble(&info->initorbit[0],&bufPtr,dir);
  60574. X    getDouble(&info->initorbit[1],&bufPtr,dir);
  60575. X    getInt(&info->periodicity,&bufPtr,dir);
  60576. X    getInt(&info->pot16bit,&bufPtr,dir);
  60577. X    getFloat(&info->faspectratio,&bufPtr,dir);
  60578. X    getInt(&info->system,&bufPtr,dir);
  60579. X    getInt(&info->release,&bufPtr,dir);
  60580. X    getInt(&info->flag3d,&bufPtr,dir);
  60581. X    getInt(&info->transparent[0],&bufPtr,dir);
  60582. X    getInt(&info->transparent[1],&bufPtr,dir);
  60583. X    getInt(&info->ambient,&bufPtr,dir);
  60584. X    getInt(&info->haze,&bufPtr,dir);
  60585. X    getInt(&info->randomize,&bufPtr,dir);
  60586. X    getInt(&info->rotate_lo,&bufPtr,dir);
  60587. X    getInt(&info->rotate_hi,&bufPtr,dir);
  60588. X    getInt(&info->distestwidth,&bufPtr,dir);
  60589. X    getDouble(&info->dparm3,&bufPtr,dir);
  60590. X    getDouble(&info->dparm4,&bufPtr,dir);
  60591. X    getInt(&info->fillcolor,&bufPtr,dir);
  60592. X    getDouble(&info->mxmaxfp,&bufPtr,dir);
  60593. X    getDouble(&info->mxminfp,&bufPtr,dir);
  60594. X    getDouble(&info->mymaxfp,&bufPtr,dir);
  60595. X    getDouble(&info->myminfp,&bufPtr,dir);
  60596. X    getInt(&info->zdots,&bufPtr,dir);
  60597. X    getFloat(&info->originfp,&bufPtr,dir);
  60598. X    getFloat(&info->depthfp,&bufPtr,dir);
  60599. X    getFloat(&info->heightfp,&bufPtr,dir);
  60600. X    getFloat(&info->widthfp,&bufPtr,dir);
  60601. X    getFloat(&info->distfp,&bufPtr,dir);
  60602. X    getFloat(&info->eyesfp,&bufPtr,dir);
  60603. X    getInt(&info->orbittype,&bufPtr,dir);
  60604. X    getInt(&info->juli3Dmode,&bufPtr,dir);
  60605. X    getInt(&info->maxfn,&bufPtr,dir);
  60606. X    getInt(&info->inversejulia,&bufPtr,dir);
  60607. X    getDouble(&info->dparm5,&bufPtr,dir);
  60608. X    getDouble(&info->dparm6,&bufPtr,dir);
  60609. X    getDouble(&info->dparm7,&bufPtr,dir);
  60610. X    getDouble(&info->dparm8,&bufPtr,dir);
  60611. X    getDouble(&info->dparm9,&bufPtr,dir);
  60612. X    getDouble(&info->dparm10,&bufPtr,dir);
  60613. X    for (i=0;i<50;i++) {
  60614. X    getInt(&info->future[i],&bufPtr,dir);
  60615. X    }
  60616. X    if (bufPtr-buf != FRACTAL_INFO_SIZE) {
  60617. X    printf("Warning: loadfile miscount on fractal_info structure.\n");
  60618. X    printf("Components add up to %d bytes, but FRACTAL_INFO_SIZE = %d\n",
  60619. X        bufPtr-buf, FRACTAL_INFO_SIZE);
  60620. X    }
  60621. X    if (dir==0) {
  60622. X    bcopy((char *)buf,(char *)info,FRACTAL_INFO_SIZE);
  60623. X    }
  60624. X
  60625. X    free(buf);
  60626. X}
  60627. X
  60628. X/*
  60629. X * This routine gets a char out of the buffer.
  60630. X * It updates the buffer pointer accordingly.
  60631. X */
  60632. Xstatic getChar(dst,src,dir)
  60633. X    unsigned char *dst;
  60634. X    unsigned char **src;
  60635. X    int dir;
  60636. X{
  60637. X    if (dir==1) {
  60638. X    *dst = **src;
  60639. X    } else {
  60640. X    **src = *dst;
  60641. X    }
  60642. X    (*src)++;
  60643. X}
  60644. X
  60645. X/*
  60646. X * This routine gets an int out of the buffer.
  60647. X * It updates the buffer pointer accordingly.
  60648. X */
  60649. Xstatic getInt(dst,src,dir)
  60650. X    short *dst;
  60651. X    unsigned char **src;
  60652. X    int dir;
  60653. X{
  60654. X    if (dir==1) {
  60655. X    *dst = (*src)[0] + ((((char *)(*src))[1])<<8);
  60656. X    } else {
  60657. X    (*src)[0] = (*dst)&0xff;
  60658. X    (*src)[1] = ((*dst)&0xff00)>>8;
  60659. X    }
  60660. X    (*src) += 2; /* sizeof(int) in MS_DOS */
  60661. X}
  60662. X
  60663. X/*
  60664. X * This routine gets a long out of the buffer.
  60665. X * It updates the buffer pointer accordingly.
  60666. X */
  60667. Xstatic getLong(dst,src,dir)
  60668. X    long *dst;
  60669. X    unsigned char **src;
  60670. X    int dir;
  60671. X{
  60672. X    if (dir==1) {
  60673. X    *dst = ((unsigned long)((*src)[0])) +
  60674. X        (((unsigned long)((*src)[1]))<<8) +
  60675. X        (((unsigned long)((*src)[2]))<<16) +
  60676. X        (((long)(((char *)(*src))[3]))<<24);
  60677. X    } else {
  60678. X    (*src)[0] = (*dst)&0xff;
  60679. X    (*src)[1] = ((*dst)&0xff00)>>8;
  60680. X    (*src)[2] = ((*dst)&0xff0000)>>8;
  60681. X    (*src)[3] = ((*dst)&0xff000000)>>8;
  60682. X    }
  60683. X    (*src) += 4; /* sizeof(long) in MS_DOS */
  60684. X}
  60685. X
  60686. X#define P4 16.
  60687. X#define P7 128.
  60688. X#define P8 256.
  60689. X#define P12 4096.
  60690. X#define P15 32768.
  60691. X#define P20 1048576.
  60692. X#define P23 8388608.
  60693. X#define P28 268435456.
  60694. X#define P36 68719476736.
  60695. X#define P44 17592186044416.
  60696. X#define P52 4503599627370496.
  60697. X
  60698. X
  60699. X/*
  60700. X * This routine gets a double out of the buffer, or puts a double into the
  60701. X * buffer;
  60702. X * It updates the buffer pointer accordingly.
  60703. X */
  60704. Xstatic getDouble(dst,src,dir)
  60705. X    double *dst;
  60706. X    unsigned char **src;
  60707. X    int dir;
  60708. X{
  60709. X    int e;
  60710. X    double f;
  60711. X    int i;
  60712. X    if (dir==1) {
  60713. X    for (i=0;i<8;i++) {
  60714. X        if ((*src)[i] != 0) break;
  60715. X    }
  60716. X    if (i==8) {
  60717. X        *dst = 0;
  60718. X    } else {
  60719. X        e = (((*src)[7]&0x7f)<<4) + (((*src)[6]&0xf0)>>4) - 1023;
  60720. X        f = 1 + ((*src)[6]&0x0f)/P4 + (*src)[5]/P12 + (*src)[4]/P20 +
  60721. X        (*src)[3]/P28 + (*src)[2]/P36 + (*src)[1]/P44 + (*src)[0]/P52;
  60722. X        f *= pow(2.,(double)e);
  60723. X        if ((*src)[7]&0x80) {
  60724. X        f = -f;
  60725. X        }
  60726. X        *dst = f;
  60727. X    }
  60728. X    } else {
  60729. X    if (*dst==0) {
  60730. X        bzero((char *)(*src),8);
  60731. X    } else {
  60732. X        int s=0;
  60733. X        f = *dst;
  60734. X        if (f<0) {
  60735. X        s = 0x80;
  60736. X        f = -f;
  60737. X        }
  60738. X        e = log(f)/log(2.);
  60739. X        f = f/pow(2.,(double)e) - 1;
  60740. X        if (f<0) {
  60741. X        e--;
  60742. X        f = (f+1)*2-1;
  60743. X        } else if (f>=1) {
  60744. X        e++;
  60745. X        f = (f+1)/2-1;
  60746. X        }
  60747. X        e += 1023;
  60748. X        (*src)[7] = s | ((e&0x7f0)>>4);
  60749. X        f *= P4;
  60750. X        (*src)[6] = ((e&0x0f)<<4) | (((int)f)&0x0f);
  60751. X        f = (f-(int)f)*P8;
  60752. X        (*src)[5] = (((int)f)&0xff);
  60753. X        f = (f-(int)f)*P8;
  60754. X        (*src)[4] = (((int)f)&0xff);
  60755. X        f = (f-(int)f)*P8;
  60756. X        (*src)[3] = (((int)f)&0xff);
  60757. X        f = (f-(int)f)*P8;
  60758. X        (*src)[2] = (((int)f)&0xff);
  60759. X        f = (f-(int)f)*P8;
  60760. X        (*src)[1] = (((int)f)&0xff);
  60761. X        f = (f-(int)f)*P8;
  60762. X        (*src)[0] = (((int)f)&0xff);
  60763. X    }
  60764. X    }
  60765. X    *src += 8; /* sizeof(double) in MSDOS */
  60766. X}
  60767. X
  60768. X/*
  60769. X * This routine gets a float out of the buffer.
  60770. X * It updates the buffer pointer accordingly.
  60771. X */
  60772. Xstatic getFloat(dst,src,dir)
  60773. X    float *dst;
  60774. X    unsigned char **src;
  60775. X    int dir;
  60776. X{
  60777. X    int e;
  60778. X    double f;
  60779. X    int i;
  60780. X    if (dir==1) {
  60781. X    for (i=0;i<4;i++) {
  60782. X        if ((*src)[i] != 0) break;
  60783. X    }
  60784. X    if (i==4) {
  60785. X        *dst = 0;
  60786. X    } else {
  60787. X        e = (((*src)[3]&0x7f)<<1)| (((*src)[2]&0x80)>>7) - 127;
  60788. X        f = 1 + ((*src)[2]&0x7f)/P7 + (*src)[1]/P15 + (*src)[0]/P23;
  60789. X        f *= pow(2.,(double)e);
  60790. X        if ((*src)[3]&0x80) {
  60791. X        f = -f;
  60792. X        }
  60793. X        *dst = f;
  60794. X    }
  60795. X    } else {
  60796. X    if (*dst==0) {
  60797. X        bzero((char *)(*src),4);
  60798. X    } else {
  60799. X        int s=0;
  60800. X        f = *dst;
  60801. X        if (f<0) {
  60802. X        s = 0x80;
  60803. X        f = -f;
  60804. X        }
  60805. X        e = log(f)/log(2.);
  60806. X        f = f/pow(2.,(double)e) - 1;
  60807. X        if (f<0) {
  60808. X        e--;
  60809. X        f = (f+1)*2-1;
  60810. X        } else if (f>=1) {
  60811. X        e++;
  60812. X        f = (f+1)/2-1;
  60813. X        }
  60814. X        e += 127;
  60815. X        (*src)[3] = s | ((e&0xf7)>>1);
  60816. X        f *= P7;
  60817. X        (*src)[2] = ((e&0x01)<<7) | (((int)f)&0x7f);
  60818. X        f = (f-(int)f)*P8;
  60819. X        (*src)[1] = (((int)f)&0xff);
  60820. X        f = (f-(int)f)*P8;
  60821. X        (*src)[0] = (((int)f)&0xff);
  60822. X    }
  60823. X    }
  60824. X    *src += 4; /* sizeof(float) in MSDOS */
  60825. X}
  60826. X
  60827. X/*
  60828. X * Fix up the ranges data.
  60829. X */
  60830. Xfix_ranges(ranges,num,dir)
  60831. X    int *ranges, num;
  60832. X    int dir;
  60833. X{
  60834. X    unsigned char *buf;
  60835. X    unsigned char *bufPtr;
  60836. X    int i;
  60837. X
  60838. X    if (dir==1) {
  60839. X    buf = (unsigned char *)malloc(num*2);
  60840. X    bufPtr = buf;
  60841. X    bcopy((char *)ranges, (char *)buf, num*2);
  60842. X    } else {
  60843. X    buf = (unsigned char *)malloc(num*sizeof(int));
  60844. X    bufPtr = buf;
  60845. X    bcopy((char *)ranges, (char *)buf, num*sizeof(int));
  60846. X    }
  60847. X    for (i=0;i<num;i++) {
  60848. X    getInt(&ranges[i],bufPtr,dir);
  60849. X    }
  60850. X    free((char *)buf);
  60851. X}
  60852. SHAR_EOF
  60853. $TOUCH -am 1028230193 general.c &&
  60854. chmod 0644 general.c ||
  60855. echo "restore of general.c failed"
  60856. set `wc -c general.c`;Wc_c=$1
  60857. if test "$Wc_c" != "19394"; then
  60858.     echo original size 19394, current size $Wc_c
  60859. fi
  60860. # ============= printera.c ==============
  60861. echo "x - extracting printera.c (Text)"
  60862. sed 's/^X//' << 'SHAR_EOF' > printera.c &&
  60863. X/*
  60864. X *  printera.c
  60865. X *
  60866. X *
  60867. X *  Paintjet tables for printer.c, in here so that we can link them
  60868. X *  as part of the printer.c overlay and not waste far space.
  60869. X *
  60870. X *  The tables were copied from Lee Crocker's PGIF program, with
  60871. X *  the 8 undithered colors moved to the first 8 table slots.
  60872. X *
  60873. X *  This file contains various lookup tables used by PJGIF.  Patterns contains
  60874. X *  unsigned values representing each of the 330 HP PaintJet colors.  Each color
  60875. X *  at 90 DPI is composed of four dots in 8 colors.  Each hex digit of these
  60876. X *  unsigned values represents one of the four dots.  Although the PaintJet will
  60877. X *  produce these patterns automatically in 90 DPI mode, it is much faster to do
  60878. X *  it in software with the PaintJet in 8-color 180 DPI mode.
  60879. X *
  60880. X *  920501 Hans Wolfgang Schulze converted from printera.asm for xfractint.
  60881. X *       (hans@garfield.metal2.polymtl.ca)
  60882. X */
  60883. X
  60884. X#include "port.h"
  60885. X
  60886. Xunsigned int far pj_patterns [] = {
  60887. X      0x7777,0x0000,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,
  60888. X             0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
  60889. X      0x0110,0x0120,0x0130,0x0140,0x0150,0x0160,0x0170,0x0220,
  60890. X      0x0230,0x0240,0x0250,0x0260,0x0270,0x0330,0x0340,0x0350,
  60891. X      0x0360,0x0370,0x0440,0x0450,0x0460,0x0470,0x0550,0x0560,
  60892. X      0x0570,0x0660,0x0670,0x0770,0x0111,0x0112,0x0113,0x0114,
  60893. X      0x0115,0x0116,0x0117,0x2012,0x0123,0x0124,0x0125,0x0126,
  60894. X      0x0127,0x3013,0x0134,0x0135,0x0136,0x0137,0x4014,0x0145,
  60895. X      0x0146,0x0147,0x5015,0x0156,0x0157,0x6016,0x0167,0x7017,
  60896. X      0x0222,0x0223,0x0224,0x0225,0x0226,0x0227,0x3023,0x0234,
  60897. X      0x0235,0x0236,0x0237,0x4024,0x0245,0x0246,0x0247,0x5025,
  60898. X      0x0256,0x0257,0x6026,0x0267,0x7027,0x0333,0x0334,0x0335,
  60899. X      0x0336,0x0337,0x4034,0x0345,0x0346,0x0347,0x5035,0x0356,
  60900. X      0x0357,0x6036,0x0367,0x7037,0x0444,0x0445,0x0446,0x0447,
  60901. X      0x5045,0x0456,0x0457,0x6046,0x0467,0x7047,0x0555,0x0556,
  60902. X      0x0557,0x6056,0x0567,0x7057,0x0666,0x0667,0x7067,0x0777,
  60903. X             0x1112,0x1113,0x1114,0x1115,0x1116,0x1117,0x2112,
  60904. X      0x1123,0x2114,0x2115,0x2116,0x2117,0x3113,0x3114,0x3115,
  60905. X      0x3116,0x3117,0x4114,0x4115,0x4116,0x4117,0x5115,0x5116,
  60906. X      0x5117,0x6116,0x6117,0x7117,0x1222,0x1223,0x1224,0x1225,
  60907. X      0x1226,0x1227,0x3123,0x1234,0x1235,0x1236,0x1237,0x4124,
  60908. X      0x1245,0x1246,0x1247,0x5125,0x1256,0x1257,0x6126,0x1267,
  60909. X      0x7127,0x1333,0x1334,0x1335,0x1336,0x1337,0x4134,0x1345,
  60910. X      0x1346,0x1347,0x5135,0x1356,0x1357,0x6136,0x1367,0x7137,
  60911. X      0x1444,0x1445,0x1446,0x1447,0x5145,0x1456,0x1457,0x6146,
  60912. X      0x1467,0x7147,0x1555,0x1556,0x1557,0x6156,0x1567,0x7157,
  60913. X      0x1666,0x1667,0x7167,0x1777,       0x2223,0x2224,0x2225,
  60914. X      0x2226,0x2227,0x3223,0x3224,0x3225,0x3226,0x3227,0x4224,
  60915. X      0x4225,0x4226,0x4227,0x5225,0x5226,0x5227,0x6226,0x6227,
  60916. X      0x7227,0x2333,0x2334,0x2335,0x2336,0x2337,0x4234,0x2345,
  60917. X      0x2346,0x2347,0x5235,0x2356,0x2357,0x6236,0x2367,0x7237,
  60918. X      0x2444,0x2445,0x2446,0x2447,0x5245,0x2456,0x2457,0x6246,
  60919. X      0x2467,0x7247,0x2555,0x2556,0x2557,0x6256,0x2567,0x7257,
  60920. X      0x2666,0x2667,0x7267,0x2777,       0x3334,0x3335,0x3336,
  60921. X      0x3337,0x4334,0x4335,0x4336,0x4337,0x5335,0x5336,0x5337,
  60922. X      0x6336,0x6337,0x7337,0x3444,0x3445,0x3446,0x3447,0x5345,
  60923. X      0x3456,0x3457,0x6346,0x3467,0x7347,0x3555,0x3556,0x3557,
  60924. X      0x6356,0x3567,0x7357,0x3666,0x3667,0x7367,0x3777,
  60925. X      0x4445,0x4446,0x4447,0x5445,0x5446,0x5447,0x6446,0x6447,
  60926. X      0x7447,0x4555,0x4556,0x4557,0x6456,0x4567,0x7457,0x4666,
  60927. X      0x4667,0x7467,0x4777,       0x5556,0x5557,0x6556,0x6557,
  60928. X      0x7557,0x5666,0x5667,0x7567,0x5777,       0x6667,0x7667,
  60929. X      0x6777};
  60930. X
  60931. X/*
  60932. X * The 3 tables below contain the red, green, and blue values (on a scale of
  60933. X *  0..255) of each of the 330 PaintJet colors.  These values are based on data
  60934. X *  generously provided by HP customer service.
  60935. X *       11 <- changed black's value from this, seemed wrong
  60936. X *         135 <- changed red's value from this
  60937. X *           11 <- changed blue's value from this
  60938. X */
  60939. Xunsigned char far pj_reds[] = {
  60940. X        229,  2,145,  7,227,  9,136, 5,
  60941. X             17, 10, 17, 10, 16, 10, 16, 29, 16, 32, 15, 30, 15, 31,  9,
  60942. X     15, 10, 15,  9, 13, 37, 15, 32, 16, 36, 10, 15,  9, 13, 30, 15,
  60943. X     31,  8, 13, 38, 62, 26, 68, 26, 63, 26, 68, 16, 35, 16, 33, 16,
  60944. X     33, 77, 26, 69, 29, 77, 16, 31, 16, 31, 64, 27, 71, 16, 36, 81,
  60945. X      9, 15, 10, 15,  8, 13, 37, 15, 31, 15, 33, 10, 15,  9, 13, 29,
  60946. X     15, 28,  8, 12, 28, 98, 28, 79, 32, 94, 16, 34, 17, 35, 73, 30,
  60947. X     82, 17, 43,101, 11, 15, 10, 13, 29, 15, 27,  9, 13, 25, 65, 27,
  60948. X     71, 16, 35, 88,  7, 12, 39,110,     54,146, 53,136, 58,144, 29,
  60949. X     57, 28, 53, 29, 56,159, 54,144, 61,160, 27, 51, 28, 52,135, 55,
  60950. X    144, 30, 60,159, 14, 23, 15, 22, 14, 21, 64, 30, 58, 32, 64, 15,
  60951. X     22, 15, 21, 54, 31, 56, 14, 22, 64,185, 59,160, 69,185, 29, 57,
  60952. X     31, 60,145, 63,162, 33, 71,186, 15, 22, 16, 21, 50, 30, 52, 15,
  60953. X     21, 54,134, 58,145, 30, 60,161, 15, 22, 69,187,     13,  9, 14,
  60954. X      6, 11, 31, 14, 27, 12, 27, 10, 14,  9, 12, 24,  9, 23,  6,  9,
  60955. X     22, 76, 23, 61, 25, 74, 15, 29, 14, 28, 55, 23, 62, 12, 30, 73,
  60956. X         11, 15, 10, 12, 25, 14, 23,  8, 11, 20, 50, 22, 53, 13, 26, 61,
  60957. X          5,  8, 21, 71,     71,189, 87,227, 30, 63, 32, 69,164, 76,190,
  60958. X         37, 89,227, 15, 22, 14, 20, 54, 31, 57, 14, 21, 63,147, 67,163,
  60959. X         33, 72,191, 13, 24, 94,228,     15, 10, 13, 26, 14, 23, 10, 13,
  60960. X         20, 50, 23, 50, 15, 26, 52,  8, 11, 23, 65,     60,147, 32, 67,
  60961. X        166, 14, 24, 77,194,      8, 32, 97};
  60962. X
  60963. X/*
  60964. X *                   11 <- changed black's value from this, seemed wrong
  60965. X *                           65 <- changed green from this
  60966. X */
  60967. X
  60968. Xunsigned char far pj_greens[] = {
  60969. X        224,  2, 20, 72,211, 10, 11, 55,
  60970. X             12, 15, 19, 11, 11, 14, 17, 14, 18, 22, 12, 13, 16, 19, 24,
  60971. X         29, 16, 17, 23, 27, 41, 17, 22, 29, 39, 11, 10, 14, 14, 11, 14,
  60972. X         17, 21, 25, 40, 16, 21, 28, 14, 16, 19, 25, 28, 37, 18, 20, 26,
  60973. X         33, 48, 20, 26, 33, 46, 13, 12, 16, 18, 14, 18, 22, 24, 30, 42,
  60974. X         40, 49, 25, 27, 39, 50, 69, 27, 33, 48, 66, 17, 17, 24, 27, 19,
  60975. X         28, 35, 38, 48, 68,100, 32, 46, 65, 98, 18, 22, 29, 36, 27, 39,
  60976. X         54, 49, 71,105, 11, 10, 14, 12, 10, 14, 13, 20, 20, 25, 11, 15,
  60977. X         18, 22, 29, 49, 36, 46, 69,111,     23, 31, 16, 19, 22, 28, 30,
  60978. X         37, 20, 22, 28, 34, 54, 22, 29, 36, 53, 14, 15, 17, 19, 17, 19,
  60979. X         26, 25, 32, 46, 43, 50, 27, 28, 41, 49, 68, 29, 37, 51, 68, 19,
  60980. X         19, 25, 28, 22, 30, 36, 40, 47, 66,104, 35, 51, 68,105, 20, 24,
  60981. X         31, 37, 30, 38, 56, 50, 69,103, 13, 12, 15, 14, 13, 15, 16, 21,
  60982. X         21, 26, 14, 16, 22, 23, 28, 44, 35, 42, 62,102,     78, 40, 44,
  60983. X         65, 78, 98, 43, 53, 76, 99, 26, 27, 36, 40, 29, 43, 50, 63, 75,
  60984. X         99,136, 49, 69, 98,142, 28, 32, 42, 51, 39, 52, 73, 77,103,145,
  60985. X         17, 17, 21, 21, 18, 22, 24, 34, 37, 43, 19, 23, 30, 40, 48, 69,
  60986. X         62, 76,101,147,     72,113,145,218, 33, 42, 52, 71, 61, 77,116,
  60987. X        105,148,221, 18, 17, 21, 23, 21, 26, 30, 37, 43, 64, 30, 35, 48,
  60988. X         50, 69,115, 77, 99,149,224,     10, 13, 11, 10, 12, 11, 17, 16,
  60989. X         15,  9, 11, 12, 17, 17, 22, 26, 27, 36, 61,     14, 18, 21, 26,
  60990. X         48, 34, 41, 68,115,     69, 99,149};
  60991. X
  60992. X/*                    15 <- changed black's value from this, seemed wrong
  60993. X *                           56 <- changed green from this
  60994. X *                                          163 <- changed cyan from this
  60995. X */
  60996. Xunsigned char far pj_blues[] = {
  60997. X        216,  2, 34, 48, 33, 73, 64,168,
  60998. X             18, 19, 18, 20, 19, 22, 21, 22, 24, 22, 26, 24, 27, 24, 27,
  60999. X         24, 29, 27, 31, 29, 22, 27, 25, 30, 28, 31, 29, 33, 33, 28, 32,
  61000. X         32, 41, 40, 46, 28, 32, 28, 34, 30, 36, 31, 35, 32, 38, 34, 41,
  61001. X         35, 27, 35, 31, 39, 34, 40, 37, 44, 40, 34, 42, 37, 49, 47, 45,
  61002. X         40, 36, 43, 40, 47, 43, 33, 40, 36, 45, 41, 44, 41, 49, 46, 40,
  61003. X         49, 45, 58, 56, 58, 30, 38, 34, 44, 40, 42, 39, 49, 46, 38, 49,
  61004. X         46, 59, 62, 67, 49, 46, 55, 52, 44, 55, 52, 64, 64, 66, 43, 55,
  61005. X         53, 66, 70, 78, 87, 91,101,115,     39, 34, 42, 37, 43, 36, 45,
  61006. X         38, 47, 42, 49, 43, 34, 41, 36, 44, 38, 49, 45, 52, 46, 40, 47,
  61007. X         42, 56, 51, 45, 49, 45, 52, 48, 56, 50, 40, 47, 44, 52, 47, 54,
  61008. X         51, 59, 55, 47, 58, 50, 66, 60, 56, 34, 44, 38, 48, 42, 52, 47,
  61009. X         56, 50, 42, 51, 46, 64, 59, 57, 60, 56, 64, 61, 52, 61, 57, 72,
  61010. X         67, 64, 48, 58, 53, 69, 65, 65, 87, 83, 87, 94,     53, 59, 55,
  61011. X         64, 60, 46, 53, 49, 59, 54, 60, 56, 65, 62, 53, 62, 58, 76, 71,
  61012. X         68, 41, 50, 45, 56, 51, 58, 53, 63, 59, 49, 60, 56, 74, 71, 71,
  61013. X         66, 63, 73, 70, 60, 69, 67, 84, 81, 79, 55, 67, 64, 84, 81, 83,
  61014. X        104,104,106,116,     32, 40, 53, 48, 54, 50, 61, 57, 46, 59, 56,
  61015. X         76, 75, 80, 64, 59, 70, 67, 57, 69, 65, 83, 81, 85, 54, 68, 66,
  61016. X         86, 88, 96,110,114,125,137,     71, 81, 78, 68, 77, 76, 93, 92,
  61017. X         90, 65, 77, 75, 92, 93, 96,117,119,126,138,     78, 79, 98,102,
  61018. X        110,124,131,143,157,    173,185,200};
  61019. SHAR_EOF
  61020. $TOUCH -am 1028230193 printera.c &&
  61021. chmod 0644 printera.c ||
  61022. echo "restore of printera.c failed"
  61023. set `wc -c printera.c`;Wc_c=$1
  61024. if test "$Wc_c" != "8947"; then
  61025.     echo original size 8947, current size $Wc_c
  61026. fi
  61027. # ============= tplus_a.c ==============
  61028. echo "x - extracting tplus_a.c (Text)"
  61029. sed 's/^X//' << 'SHAR_EOF' > tplus_a.c &&
  61030. X/* tplus_a.c
  61031. X * This file contains routines to replace tplus_a.asm.
  61032. X *
  61033. X * This file Copyright 1992 Ken Shirriff.  It may be used according to the
  61034. X * fractint license conditions, blah blah blah.
  61035. X */
  61036. X
  61037. X#include <fractint.h>
  61038. X
  61039. XWriteTPlusBankedPixel() {}
  61040. XReadTPlusBankedPixel() {}
  61041. XMatchTPlusMode() {}
  61042. SHAR_EOF
  61043. $TOUCH -am 1028230193 tplus_a.c &&
  61044. chmod 0644 tplus_a.c ||
  61045. echo "restore of tplus_a.c failed"
  61046. set `wc -c tplus_a.c`;Wc_c=$1
  61047. if test "$Wc_c" != "295"; then
  61048.     echo original size 295, current size $Wc_c
  61049. fi
  61050. # ============= video.c ==============
  61051. echo "x - extracting video.c (Text)"
  61052. sed 's/^X//' << 'SHAR_EOF' > video.c &&
  61053. X#include <curses.h>
  61054. X#include <string.h>
  61055. X#include "fractint.h"
  61056. X#include "prototyp.h"
  61057. X
  61058. X/*
  61059. X * This file contains Unix versions of the routines in video.asm
  61060. X * Copyright 1992 Ken Shirriff
  61061. X */
  61062. X
  61063. Xextern int colors,rotate_lo,rotate_hi;
  61064. Xextern int boxx[],boxy[],boxcount;
  61065. X
  61066. Xextern unsigned char *xgetfont();
  61067. X
  61068. XWINDOW *curwin;
  61069. X
  61070. Xextern int boxcount;
  61071. Xextern int dotmode;
  61072. Xextern int sxdots,sydots,sxoffs,syoffs;
  61073. Xint daclearn = 0;
  61074. Xint dacnorm = 0;
  61075. Xint daccount = 0;
  61076. Xint ShadowColors;
  61077. Xint goodmode    =    0;    /* if non-zero, OK to read/write pixels */
  61078. Xvoid (*dotwrite)(int, int, int);
  61079. X                /* write-a-dot routine */
  61080. Xint (*dotread)(int, int);     /* read-a-dot routine */
  61081. Xvoid (*linewrite)();        /* write-a-line routine */
  61082. Xvoid (*lineread)();        /* read-a-line routine */
  61083. Xint andcolor    =    0;      /* "and" value used for color selection */
  61084. Xint diskflag    =    0;    /* disk video active flag */
  61085. X
  61086. Xint videoflag    =    0;    /* special "your-own-video" flag */
  61087. X
  61088. Xvoid (*swapsetup)(void)    =NULL;    /* setfortext/graphics setup routine */
  61089. Xint color_dark    =    0;    /* darkest color in palette */
  61090. Xint color_bright    =0;    /* brightest color in palette */
  61091. Xint color_medium    =0;    /* nearest to medbright grey in palette
  61092. X                   Zoom-Box values (2K x 2K screens max) */
  61093. Xint boxcolor    =    0;    /* Zoom-Box color */
  61094. Xint reallyega    =    0;    /* 1 if its an EGA posing as a VGA */
  61095. Xint gotrealdac    =    0;    /* 1 if loaddac has a dacbox */
  61096. Xint rowcount    =    0;    /* row-counter for decoder and out_line */
  61097. Xint video_type    =    0;    /* actual video adapter type:
  61098. X                    0  = type not yet determined
  61099. X                    1  = Hercules
  61100. X                    2  = CGA (assumed if nothing else)
  61101. X                    3  = EGA
  61102. X                    4  = MCGA
  61103. X                    5  = VGA
  61104. X                    6  = VESA (not yet checked)
  61105. X                   11  = 8514/A (not yet checked)
  61106. X                   12  = TIGA    (not yet checked)
  61107. X                   13  = TARGA    (not yet checked)
  61108. X                   100 = x monochrome
  61109. X                   101 = x 256 colors
  61110. X                   */
  61111. Xint svga_type    =    0;    /*  (forced) SVGA type
  61112. X                    1 = ahead "A" type
  61113. X                    2 = ATI
  61114. X                    3 = C&T
  61115. X                    4 = Everex
  61116. X                    5 = Genoa
  61117. X                    6 = Ncr
  61118. X                    7 = Oak-Tech
  61119. X                    8 = Paradise
  61120. X                    9 = Trident
  61121. X                   10 = Tseng 3000
  61122. X                   11 = Tseng 4000
  61123. X                   12 = Video-7
  61124. X                   13 = ahead "B" type
  61125. X                   14 = "null" type (for testing only) */
  61126. Xint mode7text    =    0;    /* nonzero for egamono and hgc */
  61127. Xint textaddr    =    0xb800;    /* b800 for mode 3, b000 for mode 7 */
  61128. Xint textsafe    =    0;    /* 0 = default, runup chgs to 1
  61129. X                  1 = yes
  61130. X                  2 = no, use 640x200
  61131. X                  3 = bios, yes plus use int 10h-1Ch
  61132. X                  4 = save, save entire image */
  61133. Xint text_type    =    1;    /* current mode's type of text:
  61134. X                    0  = real text, mode 3 (or 7)
  61135. X                    1  = 640x200x2, mode 6
  61136. X                    2  = some other mode, graphics */
  61137. Xint textrow     =    0;    /* for putstring(-1,...) */
  61138. Xint textcol     =    0;    /* for putstring(..,-1,...) */
  61139. Xint textrbase    =    0;    /* textrow is relative to this */
  61140. Xint textcbase    =    0;    /* textcol is relative to this */
  61141. Xextern unsigned char dacbox[];
  61142. Xint vesa_detect =    1;    /* set to 0 to disable VESA-detection */
  61143. X
  61144. X/*
  61145. X
  61146. X;        |--Adapter/Mode-Name------|-------Comments-----------|
  61147. X
  61148. X;        |------INT 10H------|Dot-|--Resolution---|
  61149. X;        |key|--AX---BX---CX---DX|Mode|--X-|--Y-|Color|
  61150. X*/
  61151. X
  61152. Xstruct videoinfo videotable[MAXVIDEOTABLE] = {
  61153. X    {"xfractint mode           ","                         ",
  61154. X     999, 0,     0,   0,   0,    19, 640, 480,  256},
  61155. X    {"unused  mode             ","                         ",
  61156. X     0, 0,     0,   0,   0,    0, 0, 0,  0},
  61157. X       };
  61158. X
  61159. Xvoid setforgraphics();
  61160. X
  61161. Xvoid
  61162. Xnullwrite(a,b,c)
  61163. Xint a,b,c;
  61164. X{}
  61165. X
  61166. Xint
  61167. Xnullread(a,b)
  61168. Xint a,b;
  61169. X{
  61170. X    return 0;
  61171. X}
  61172. X
  61173. Xvoid setnullvideo()
  61174. X{
  61175. X    dotwrite = nullwrite;
  61176. X    dotread = nullread;
  61177. X}
  61178. X
  61179. Xvoid normalineread();
  61180. Xvoid normaline();
  61181. X
  61182. X/*
  61183. X; ********************** Function setvideotext() ************************
  61184. X
  61185. X;       Sets video to text mode, using setvideomode to do the work.
  61186. X*/
  61187. Xvoid
  61188. Xsetvideotext() {
  61189. X    dotmode = 0;
  61190. X    setvideomode(3,0,0,0);
  61191. X}
  61192. X
  61193. X/*
  61194. X; **************** Function setvideomode(ax, bx, cx, dx) ****************
  61195. X;       This function sets the (alphanumeric or graphic) video mode
  61196. X;       of the monitor.   Called with the proper values of AX thru DX.
  61197. X;       No returned values, as there is no particular standard to
  61198. X;       adhere to in this case.
  61199. X
  61200. X;       (SPECIAL "TWEAKED" VGA VALUES:  if AX==BX==CX==0, assume we have a
  61201. X;       genuine VGA or register compatable adapter and program the registers
  61202. X;       directly using the coded value in DX)
  61203. X
  61204. X; Unix: We ignore ax,bx,cx,dx.  dotmode is the "mode" field in the video
  61205. X; table.  We use mode 19 for the X window.
  61206. X*/
  61207. Xvoid
  61208. Xsetvideomode(ax,bx,cx,dx)
  61209. Xint ax,bx,cx,dx;
  61210. X{
  61211. X    if (diskflag) {
  61212. X    enddisk();
  61213. X    }
  61214. X    if (videoflag) {
  61215. X    endvideo();
  61216. X    videoflag = 0;
  61217. X    }
  61218. X    goodmode = 1;
  61219. X    switch (dotmode) {
  61220. X    case 0: /* text */
  61221. X        clear();
  61222. X        /*
  61223. X        touchwin(curwin);
  61224. X        */
  61225. X        wrefresh(curwin);
  61226. X        break;
  61227. X    case 11:
  61228. X        startdisk();
  61229. X        dotwrite = writedisk;
  61230. X        dotread = readdisk;
  61231. X        lineread = normalineread;
  61232. X        linewrite = normaline;
  61233. X        break;
  61234. X    case 19: /* X window */
  61235. X        wclear(curwin); /* ???? */
  61236. X        putstring(0, 0, 0,
  61237. X            "Press operation key, or <Esc> to return to Main Menu");
  61238. X        wrefresh(curwin);
  61239. X        dotwrite = writevideo;
  61240. X        dotread = readvideo;
  61241. X        lineread = readvideoline;
  61242. X        linewrite = writevideoline;
  61243. X        videoflag = 1;
  61244. X        startvideo();
  61245. X        setforgraphics();
  61246. X        break;
  61247. X    default:
  61248. X        printf("Bad mode %d\n", dotmode);
  61249. X        exit(-1);
  61250. X    } 
  61251. X    if (dotmode !=0) {
  61252. X    loaddac();
  61253. X    andcolor = colors-1;
  61254. X    boxcount =0;
  61255. X    }
  61256. X}
  61257. X
  61258. Xloaddac()
  61259. X{
  61260. X    readvideopalette();
  61261. X}
  61262. X
  61263. X
  61264. X/*
  61265. X; **************** Function getcolor(xdot, ydot) *******************
  61266. X
  61267. X;       Return the color on the screen at the (xdot,ydot) point
  61268. X*/
  61269. Xint
  61270. Xgetcolor(xdot,ydot)
  61271. Xint xdot,ydot;
  61272. X{
  61273. X    int x1,y1;
  61274. X    x1 = xdot+sxoffs;
  61275. X    y1 = ydot+syoffs;
  61276. X    if (x1<0 || y1<0 || x1>=sxdots || y1>=sydots) return 0;
  61277. X    return dotread(x1,y1);
  61278. X}
  61279. X
  61280. X/*
  61281. X; ************** Function putcolor(xdot, ydot, color) *******************
  61282. X
  61283. X;       write the color on the screen at the (xdot,ydot) point
  61284. X*/
  61285. Xvoid
  61286. Xputcolor(xdot,ydot,color)
  61287. Xint xdot,ydot,color;
  61288. X{
  61289. X    dotwrite(xdot+sxoffs,ydot+syoffs,color&andcolor);
  61290. X}
  61291. X
  61292. X/*
  61293. X; **************** Function movecursor(row, col)  **********************
  61294. X
  61295. X;       Move the cursor (called before printfs)
  61296. X*/
  61297. Xvoid
  61298. Xmovecursor(row,col)
  61299. Xint row, col;
  61300. X{
  61301. X    if (row==-1) {
  61302. X    row = textrow;
  61303. X    } else {
  61304. X    textrow = row;
  61305. X    }
  61306. X    if (col==-1) {
  61307. X    col = textcol;
  61308. X    } else {
  61309. X    textcol = col;
  61310. X    }
  61311. X    wmove(curwin,row,col);
  61312. X}
  61313. X
  61314. X/*
  61315. X; **************** Function keycursor(row, col)  **********************
  61316. X
  61317. X;       Subroutine to wait cx ticks, or till keystroke pending
  61318. X*/
  61319. Xkeycursor(row,col)
  61320. X{
  61321. X    int ch;
  61322. X    movecursor(row,col);
  61323. X    wrefresh(curwin);
  61324. X    waitkeypressed(0);
  61325. X    return getakey();
  61326. X}
  61327. X
  61328. X/*
  61329. X; PUTSTR.asm puts a string directly to video display memory. Called from C by:
  61330. X;    putstring(row, col, attr, string) where
  61331. X;         row, col = row and column to start printing.
  61332. X;         attr = color attribute.
  61333. X;         string = far pointer to the null terminated string to print.
  61334. X;    Written for the A86 assembler (which has much less 'red tape' than MASM)
  61335. X;    by Bob Montgomery, Orlando, Fla.             7-11-88
  61336. X;    Adapted for MASM 5.1 by Tim Wegner          12-11-89
  61337. X;    Furthur mucked up to handle graphics
  61338. X;       video modes by Bert Tyler                 1-07-90
  61339. X;    Reworked for:  row,col update/inherit;
  61340. X;       620x200x2 inverse video;  far ptr to string;
  61341. X;       fix to avoid scrolling when last posn chgd;
  61342. X;       divider removed;  newline ctl chars;  PB  9-25-90
  61343. X*/
  61344. Xvoid
  61345. Xputstring(row, col, attr, msg)
  61346. Xint row,col, attr;
  61347. XCHAR far *msg;
  61348. X{
  61349. X    int so=0;
  61350. X
  61351. X    if (row!=-1) textrow = row;
  61352. X    if (col!=-1) textcol = col;
  61353. X
  61354. X    if (attr & INVERSE || attr & BRIGHT) {
  61355. X    wstandout(curwin);
  61356. X    so = 1;
  61357. X    }
  61358. X    wmove(curwin,textrow+textrbase, textcol+textcbase);
  61359. X    while (1) {
  61360. X    if (*msg=='\0') break;
  61361. X    if (*msg=='\n') {
  61362. X        textcol = 0;
  61363. X        textrow++;
  61364. X        wmove(curwin,textrow+textrbase, textcol+textcbase);
  61365. X    } else {
  61366. X        char *ptr;
  61367. X        ptr = strchr(msg,'\n');
  61368. X        if (ptr==NULL) {
  61369. X        waddstr(curwin,msg);
  61370. X        break;
  61371. X        } else {
  61372. X        waddch(curwin,*msg);
  61373. X        }
  61374. X    }
  61375. X    msg++;
  61376. X    }
  61377. X    if (so) {
  61378. X    wstandend(curwin);
  61379. X    }
  61380. X
  61381. X    wrefresh(curwin);
  61382. X    fflush(stdout);
  61383. X    getyx(curwin,textrow,textcol);
  61384. X    textrow -= textrbase;
  61385. X    textcol -= textcbase;
  61386. X}
  61387. X
  61388. X/*
  61389. X; setattr(row, col, attr, count) where
  61390. X;         row, col = row and column to start printing.
  61391. X;         attr = color attribute.
  61392. X;         count = number of characters to set
  61393. X;         This routine works only in real color text mode.
  61394. X*/
  61395. Xvoid
  61396. Xsetattr(row, col, attr, count)
  61397. Xint row, col, attr, count;
  61398. X{
  61399. X    movecursor(row,col);
  61400. X}
  61401. X
  61402. X/*
  61403. X; **************** Function home()  ********************************
  61404. X
  61405. X;       Home the cursor (called before printfs)
  61406. X*/
  61407. Xvoid
  61408. Xhome()
  61409. X{
  61410. X    wmove(curwin,0,0);
  61411. X    textrow = 0;
  61412. X    textcol = 0;
  61413. X}
  61414. X
  61415. X
  61416. X/*
  61417. X; ************* Function scrollup(toprow, botrow) ******************
  61418. X
  61419. X;       Scroll the screen up (from toprow to botrow)
  61420. X*/
  61421. Xvoid
  61422. Xscrollup(top, bot)
  61423. Xint top,bot;
  61424. X{
  61425. X    wmove(curwin,top,0);
  61426. X    wdeleteln(curwin);
  61427. X    wmove(curwin,bot,0);
  61428. X    winsertln(curwin);
  61429. X    wrefresh(curwin);
  61430. X}
  61431. X
  61432. X/*
  61433. X; *************** Function spindac(direction, rstep) ********************
  61434. X
  61435. X;       Rotate the MCGA/VGA DAC in the (plus or minus) "direction"
  61436. X;       in "rstep" increments - or, if "direction" is 0, just replace it.
  61437. X*/
  61438. Xvoid
  61439. Xspindac(dir, inc)
  61440. Xint dir, inc;
  61441. X{
  61442. X    int i,top;
  61443. X    unsigned char tmp[3];
  61444. X    unsigned char *dacbot;
  61445. X    int len;
  61446. X    if (colors<16) return;
  61447. X    if (dir != 0 && rotate_lo<colors && rotate_lo<rotate_hi) {
  61448. X    top = rotate_hi>colors ? colors-1:rotate_hi;
  61449. X    dacbot = dacbox+3*rotate_lo;
  61450. X    len = (top-rotate_lo)*3*sizeof(unsigned char);
  61451. X    if (dir>0) {
  61452. X        for (i=0;i<inc;i++) {
  61453. X        bcopy(dacbot,tmp,3*sizeof(unsigned char));
  61454. X        bcopy(dacbot+3*sizeof(unsigned char),dacbot,len);
  61455. X        bcopy(tmp,dacbot+len,3*sizeof(unsigned char));
  61456. X        }
  61457. X    } else {
  61458. X        for (i=0;i<inc;i++) {
  61459. X        bcopy(dacbot+len,tmp,3*sizeof(unsigned char));
  61460. X        bcopy(dacbot,dacbot+3*sizeof(unsigned char),len);
  61461. X        bcopy(tmp,dacbot,3*sizeof(unsigned char));
  61462. X        }
  61463. X    }
  61464. X    }
  61465. X    writevideopalette();
  61466. X    delay(colors-daccount-1);
  61467. X}
  61468. X
  61469. X/*
  61470. X; ---- Help (Video) Support
  61471. X; ********* Functions setfortext() and setforgraphics() ************
  61472. X
  61473. X;       setfortext() resets the video for text mode and saves graphics data
  61474. X;       setforgraphics() restores the graphics mode and data
  61475. X;       setclear() clears the screen after setfortext()
  61476. X*/
  61477. Xvoid
  61478. Xsetfortext()
  61479. X{
  61480. X}
  61481. X
  61482. Xvoid
  61483. Xsetclear()
  61484. X{
  61485. X    wclear(curwin);
  61486. X    wrefresh(curwin);
  61487. X}
  61488. X
  61489. Xvoid
  61490. Xsetforgraphics()
  61491. X{
  61492. X    startvideo();
  61493. X    spindac(0,1);
  61494. X}
  61495. X
  61496. Xunsigned char *fontTab = NULL;
  61497. X
  61498. X/*
  61499. X; ************** Function findfont(n) ******************************
  61500. X
  61501. X;       findfont(0) returns far pointer to 8x8 font table if it can
  61502. X;                   find it, NULL otherwise;
  61503. X;                   nonzero parameter reserved for future use
  61504. X*/
  61505. XBYTE *
  61506. Xfindfont(fontparm)
  61507. Xint fontparm;
  61508. X{
  61509. X    if (fontTab==NULL) {
  61510. X    fontTab = xgetfont();
  61511. X    }
  61512. X    return (BYTE *)fontTab;
  61513. X}
  61514. X
  61515. X/*
  61516. X; ******************** Zoombox functions **************************
  61517. X*/
  61518. X
  61519. X/*
  61520. X * The IBM method is that boxx[],boxy[] is a set of locations, and boxvalues
  61521. X * is the values in these locations.
  61522. X * Instead of using this box save/restore technique, we'll put the corners
  61523. X * in boxx[0],boxy[0],1,2,3 and then use xor.
  61524. X */
  61525. X
  61526. Xvoid
  61527. Xdispbox()
  61528. X{
  61529. X    if (boxcount) {
  61530. X    setlinemode(1);
  61531. X    drawline(boxx[0],boxy[0],boxx[1],boxy[1]);
  61532. X    drawline(boxx[1],boxy[1],boxx[2],boxy[2]);
  61533. X    drawline(boxx[2],boxy[2],boxx[3],boxy[3]);
  61534. X    drawline(boxx[3],boxy[3],boxx[0],boxy[0]);
  61535. X    setlinemode(0);
  61536. X    xsync();
  61537. X    }
  61538. X}
  61539. X
  61540. Xvoid
  61541. Xclearbox()
  61542. X{
  61543. X    dispbox();
  61544. X}
  61545. X
  61546. Xint
  61547. XCheckForTPlus()
  61548. X{
  61549. X    return 0;
  61550. X}
  61551. X
  61552. X/*
  61553. X; Passing this routine 0 turns off shadow, nonzero turns it on.
  61554. X*/
  61555. Xint
  61556. XShadowVideo(on)
  61557. Xint on;
  61558. X{
  61559. X    return 0;
  61560. X}
  61561. X
  61562. Xint
  61563. XSetupShadowVideo()
  61564. X{
  61565. X    return 0;
  61566. X}
  61567. X
  61568. X/*
  61569. X; adapter_detect:
  61570. X;       This routine performs a few quick checks on the type of
  61571. X;       video adapter installed.
  61572. X;       It sets variables video_type and textsafe,
  61573. X;       and fills in a few bank-switching routines.
  61574. X*/
  61575. Xint done_detect = 0;
  61576. Xvoid
  61577. Xadapter_detect()
  61578. X{
  61579. X    if (done_detect) return;
  61580. X    done_detect = 1;
  61581. X    textsafe = 2;
  61582. X    if (colors==2) {
  61583. X    video_type = 100;
  61584. X    } else {
  61585. X    video_type = 101;
  61586. X    }
  61587. X}
  61588. X
  61589. X/*
  61590. X; **************** internal Read/Write-a-line routines *********************
  61591. X;
  61592. X;       These routines are called by out_line(), put_line() and get_line().
  61593. X*/
  61594. X
  61595. Xvoid
  61596. Xnormaline(y,x,lastx,pixels)
  61597. Xint x,y,lastx;
  61598. XBYTE *pixels;
  61599. X{
  61600. X    int i,width;
  61601. X    width = lastx-x+1;
  61602. X    for (i=0;i<width;i++) {
  61603. X    dotwrite(x+i,y,pixels[i]);
  61604. X    }
  61605. X}
  61606. X
  61607. Xvoid
  61608. Xnormalineread(y,x,lastx,pixels)
  61609. Xint x,y,lastx;
  61610. XBYTE *pixels;
  61611. X{
  61612. X    int i,width;
  61613. X    width = lastx-x+1;
  61614. X    for (i=0;i<width;i++) {
  61615. X    pixels[i] = dotread(x+i,y);
  61616. X    }
  61617. X}
  61618. X
  61619. X/*
  61620. X; *************** Function find_special_colors ********************
  61621. X
  61622. X;       Find the darkest and brightest colors in palette, and a medium
  61623. X;       color which is reasonably bright and reasonably grey.
  61624. X*/
  61625. Xvoid
  61626. Xfind_special_colors()
  61627. X{
  61628. X    int maxb = 0;
  61629. X    int minb = 99999;
  61630. X    int med = 0;
  61631. X    int maxgun, mingun;
  61632. X    int brt;
  61633. X    int i;
  61634. X
  61635. X    color_dark = 0;
  61636. X    color_medium = 7;
  61637. X    color_bright = 15;
  61638. X
  61639. X    if (colors==2) {
  61640. X    color_medium = 1;
  61641. X    color_bright = 1;
  61642. X    return;
  61643. X    }
  61644. X
  61645. X    if (!gotrealdac) return;
  61646. X
  61647. X    for (i=0;i<colors;i++) {
  61648. X    brt = dacbox[i*3+0]+dacbox[i*3+1]+dacbox[i*3+2];
  61649. X    if (brt>maxb) {
  61650. X        maxb = brt;
  61651. X        color_bright = i;
  61652. X    }
  61653. X    if (brt<minb) {
  61654. X        minb = brt;
  61655. X        color_dark = i;
  61656. X    }
  61657. X    if (brt<150 && brt>80) {
  61658. X        maxgun = mingun = dacbox[i*3+0];
  61659. X        if (dacbox[i*3+1]>dacbox[i*3+0]) {
  61660. X        maxgun = dacbox[i*3+1];
  61661. X        } else {
  61662. X        mingun = dacbox[i*3+1];
  61663. X        }
  61664. X        if(dacbox[i*3+2]>maxgun) maxgun = dacbox[i*3+2];
  61665. X        if(dacbox[i*3+2]<mingun) mingun = dacbox[i*3+2];
  61666. X        if (brt-(maxgun-mingun)/2>med) {
  61667. X        color_medium = i;
  61668. X        med = brt-(maxgun-mingun)/2;
  61669. X        }
  61670. X    }
  61671. X    }
  61672. X}
  61673. X
  61674. X/*
  61675. X; *************** Functions get_a_char, put_a_char ********************
  61676. X
  61677. X;       Get and put character and attribute at cursor
  61678. X;       Hi nybble=character, low nybble attribute. Text mode only
  61679. X*/
  61680. Xchar
  61681. Xget_a_char()
  61682. X{
  61683. X}
  61684. X
  61685. Xvoid
  61686. Xput_a_char(ch)
  61687. Xint ch;
  61688. X{
  61689. X}
  61690. X
  61691. X/*
  61692. X; ***Function get_line(int row,int startcol,int stopcol, unsigned char *pixels)
  61693. X
  61694. X;       This routine is a 'line' analog of 'getcolor()', and gets a segment
  61695. X;       of a line from the screen and stores it in pixels[] at one byte per
  61696. X;       pixel
  61697. X;       Called by the GIF decoder
  61698. X*/
  61699. X
  61700. Xvoid
  61701. Xget_line(row, startcol, stopcol, pixels)
  61702. Xint row,startcol,stopcol;
  61703. XBYTE *pixels;
  61704. X{
  61705. X    if (startcol+sxoffs>=sxdots||row+syoffs>=sydots) return;
  61706. X    lineread(row+syoffs,startcol+sxoffs,stopcol+sxoffs,pixels);
  61707. X}
  61708. X
  61709. X/*
  61710. X; ***Function put_line(int row,int startcol,int stopcol, unsigned char *pixels)
  61711. X
  61712. X;       This routine is a 'line' analog of 'putcolor()', and puts a segment
  61713. X;       of a line from the screen and stores it in pixels[] at one byte per
  61714. X;       pixel
  61715. X;       Called by the GIF decoder
  61716. X*/
  61717. X
  61718. Xvoid
  61719. Xput_line(row, startcol, stopcol, pixels)
  61720. Xint row, startcol, stopcol;
  61721. XBYTE *pixels;
  61722. X{
  61723. X    if (startcol+sxoffs>=sxdots||row+syoffs>sydots) return;
  61724. X    linewrite(row+syoffs,startcol+sxoffs,stopcol+sxoffs,pixels);
  61725. X}
  61726. X
  61727. X/*
  61728. X; ***************Function out_line(pixels,linelen) *********************
  61729. X
  61730. X;       This routine is a 'line' analog of 'putcolor()', and sends an
  61731. X;       entire line of pixels to the screen (0 <= xdot < xdots) at a clip
  61732. X;       Called by the GIF decoder
  61733. X*/
  61734. Xint
  61735. Xout_line(pixels, linelen)
  61736. XBYTE *pixels;
  61737. Xint linelen;
  61738. X{
  61739. X    if (rowcount+syoffs>=sydots) return 0;
  61740. X    linewrite(rowcount+syoffs,sxoffs,linelen+sxoffs-1,pixels);
  61741. X    rowcount++;
  61742. X    return 0;
  61743. X}
  61744. X
  61745. X/*
  61746. X; far move routine for savegraphics/restoregraphics
  61747. X*/
  61748. Xvoid
  61749. Xmovewords(len, fromptr, toptr)
  61750. Xint len;
  61751. XBYTE *fromptr, *toptr;
  61752. X{
  61753. X    bcopy(fromptr, toptr, len);
  61754. X}
  61755. X
  61756. Xvoid swapnormread() {}
  61757. Xvoid swapnormwrite() {}
  61758. X
  61759. X/*
  61760. X * Implement stack and unstack window functions by using multiple curses
  61761. X * windows.
  61762. X */
  61763. Xsavecurses(ptr)
  61764. XWINDOW **ptr;
  61765. X{
  61766. X    ptr[0] = curwin;
  61767. X    curwin = newwin(0,0,0,0);
  61768. X    touchwin(curwin);
  61769. X    wrefresh(curwin);
  61770. X}
  61771. X
  61772. Xrestorecurses(ptr)
  61773. XWINDOW **ptr;
  61774. X{
  61775. X    delwin(curwin);
  61776. X    curwin = ptr[0];
  61777. X    touchwin(curwin);
  61778. X    wrefresh(curwin);
  61779. X}
  61780. X
  61781. SHAR_EOF
  61782. $TOUCH -am 1028230193 video.c &&
  61783. chmod 0644 video.c ||
  61784. echo "restore of video.c failed"
  61785. set `wc -c video.c`;Wc_c=$1
  61786. if test "$Wc_c" != "15972"; then
  61787.     echo original size 15972, current size $Wc_c
  61788. fi
  61789. # ============= unix.c ==============
  61790. echo "x - extracting unix.c (Text)"
  61791. sed 's/^X//' << 'SHAR_EOF' > unix.c &&
  61792. X/* Unix.c
  61793. X * This file contains compatibility routines.
  61794. X *
  61795. X * This file Copyright 1991 Ken Shirriff.  It may be used according to the
  61796. X * fractint license conditions, blah blah blah.
  61797. X */
  61798. X
  61799. X#include <stdio.h>
  61800. X#include <stdlib.h>
  61801. X#include <sys/time.h>
  61802. X#include <sys/types.h>
  61803. X#include <sys/file.h>
  61804. X#include <sys/stat.h>
  61805. X#include <string.h>
  61806. X#include <ctype.h>
  61807. X#include "port.h"
  61808. X
  61809. Xint iocount;
  61810. X
  61811. X/*
  61812. X *----------------------------------------------------------------------
  61813. X *
  61814. X * clock_ticks --
  61815. X *
  61816. X *      Return time in CLK_TCK ticks.
  61817. X *
  61818. X * Results:
  61819. X *      Time.
  61820. X *
  61821. X * Side effects:
  61822. X *      None.
  61823. X *
  61824. X *----------------------------------------------------------------------
  61825. X */
  61826. Xlong
  61827. Xclock_ticks()
  61828. X{
  61829. X    struct timeval tim;
  61830. X    gettimeofday(&tim,NULL);
  61831. X    return tim.tv_sec*CLK_TCK + tim.tv_usec*CLK_TCK/1000000;
  61832. X}
  61833. X
  61834. X/* stub */
  61835. Xintdos() {}
  61836. X
  61837. X/*
  61838. X *----------------------------------------------------------------------
  61839. X *
  61840. X * kbhit --
  61841. X *
  61842. X *      Get a key.
  61843. X *
  61844. X * Results:
  61845. X *      1 if key, 0 otherwise.
  61846. X *
  61847. X * Side effects:
  61848. X *      None.
  61849. X *
  61850. X *----------------------------------------------------------------------
  61851. X */
  61852. Xint
  61853. Xkbhit()
  61854. X{
  61855. X    return 0;
  61856. X}
  61857. X
  61858. X/*
  61859. X *----------------------------------------------------------------------
  61860. X *
  61861. X * stackavail --
  61862. X *
  61863. X *      Returns amout of stack available.
  61864. X *
  61865. X * Results:
  61866. X *      Available stack.
  61867. X *
  61868. X * Side effects:
  61869. X *      None.
  61870. X *
  61871. X *----------------------------------------------------------------------
  61872. X */
  61873. Xlong
  61874. Xstackavail()
  61875. X{
  61876. X    return 8192;
  61877. X}
  61878. X
  61879. X#ifndef HAVESTRI
  61880. X/*
  61881. X *----------------------------------------------------------------------
  61882. X *
  61883. X * stricmp --
  61884. X *
  61885. X *      Compare strings, ignoring case.
  61886. X *
  61887. X * Results:
  61888. X *      -1,0,1.
  61889. X *
  61890. X * Side effects:
  61891. X *      None.
  61892. X *
  61893. X *----------------------------------------------------------------------
  61894. X */
  61895. Xstricmp(s1, s2)
  61896. X    register char *s1, *s2;        /* Strings to compare. */
  61897. X{
  61898. X    int c1, c2;
  61899. X
  61900. X    while (1) {
  61901. X    c1 = *s1++;
  61902. X    c2 = *s2++;
  61903. X    if (isupper(c1)) c1 = tolower(c1);
  61904. X    if (isupper(c2)) c2 = tolower(c2);
  61905. X    if (c1 != c2) {
  61906. X        return c1 - c2;
  61907. X    }
  61908. X    if (c1 == 0) {
  61909. X        return 0;
  61910. X    }
  61911. X    }
  61912. X}
  61913. X/*
  61914. X *----------------------------------------------------------------------
  61915. X *
  61916. X * strnicmp --
  61917. X *
  61918. X *      Compare strings, ignoring case.  Maximum length is specified.
  61919. X *
  61920. X * Results:
  61921. X *      -1,0,1.
  61922. X *
  61923. X * Side effects:
  61924. X *      None.
  61925. X *
  61926. X *----------------------------------------------------------------------
  61927. X */
  61928. Xint
  61929. Xstrnicmp(s1, s2, numChars)
  61930. X    register char *s1, *s2;        /* Strings to compare. */
  61931. X    register int numChars;        /* Max number of chars to compare. */
  61932. X{
  61933. X    register char c1, c2;
  61934. X
  61935. X    for ( ; numChars > 0; --numChars) {
  61936. X    c1 = *s1++;
  61937. X    c2 = *s2++;
  61938. X    if (isupper(c1)) c1 = tolower(c1);
  61939. X    if (isupper(c2)) c2 = tolower(c2);
  61940. X    if (c1 != c2) {
  61941. X        return c1 - c2;
  61942. X    }
  61943. X    if (c1 == '\0') {
  61944. X        return 0;
  61945. X    }
  61946. X    }
  61947. X    return 0;
  61948. X}
  61949. X#endif
  61950. X
  61951. X/*
  61952. X *----------------------------------------------------------------------
  61953. X *
  61954. X * strlwr --
  61955. X *
  61956. X *      Convert string to lower case.
  61957. X *
  61958. X * Results:
  61959. X *      The string.
  61960. X *
  61961. X * Side effects:
  61962. X *      Modifies the string.
  61963. X *
  61964. X *----------------------------------------------------------------------
  61965. X */
  61966. Xchar *
  61967. Xstrlwr(s)
  61968. X    char *s;
  61969. X{
  61970. X    register char *sptr=s;
  61971. X    while (*sptr != '\0') {
  61972. X    if (isupper(*sptr)) {
  61973. X        *sptr = tolower(*sptr);
  61974. X    }
  61975. X    sptr++;
  61976. X    }
  61977. X    return s;
  61978. X}
  61979. X/*
  61980. X *----------------------------------------------------------------------
  61981. X *
  61982. X * strupr --
  61983. X *
  61984. X *      Convert string to upper case.
  61985. X *
  61986. X * Results:
  61987. X *      The string.
  61988. X *
  61989. X * Side effects:
  61990. X *      Modifies the string.
  61991. X *
  61992. X *----------------------------------------------------------------------
  61993. X */
  61994. Xchar *
  61995. Xstrupr(s)
  61996. X    char *s;
  61997. X{
  61998. X    register char *sptr=s;
  61999. X    while (*sptr != '\0') {
  62000. X    if (islower(*sptr)) {
  62001. X        *sptr = toupper(*sptr);
  62002. X    }
  62003. X    sptr++;
  62004. X    }
  62005. X    return s;
  62006. X}
  62007. X/*
  62008. X *----------------------------------------------------------------------
  62009. X *
  62010. X * memicmp --
  62011. X *
  62012. X *      Compare memory (like memcmp), but ignoring case.
  62013. X *
  62014. X * Results:
  62015. X *      -1,0,1.
  62016. X *
  62017. X * Side effects:
  62018. X *      None.
  62019. X *
  62020. X *----------------------------------------------------------------------
  62021. X */
  62022. Xint
  62023. Xmemicmp(s1, s2, n)
  62024. X        register char *s1, *s2;
  62025. X        register n;
  62026. X{
  62027. X        register char c1,c2;
  62028. X        while (--n >= 0)
  62029. X        c1 = *s1++;
  62030. X        if (isupper(c1)) c1 = tolower(c1);
  62031. X        c2 = *s2++;
  62032. X        if (isupper(c2)) c2 = tolower(c2);
  62033. X                if (c1 != c2)
  62034. X                        return (c1 - c2);
  62035. X        return (0);
  62036. X}
  62037. X
  62038. X/*
  62039. X *----------------------------------------------------------------------
  62040. X *
  62041. X * findpath --
  62042. X *
  62043. X *      Find where a file is.
  62044. X *    We return filename if it is an absolute path.
  62045. X *    Otherwise we first try FRACTDIR/filename, SRCDIR/filename,
  62046. X *      and then ./filename.
  62047. X *
  62048. X * Results:
  62049. X *      Returns full pathname in fullpathname.
  62050. X *
  62051. X * Side effects:
  62052. X *      None.
  62053. X *
  62054. X *----------------------------------------------------------------------
  62055. X */
  62056. Xvoid
  62057. Xfindpath(filename, fullpathname)
  62058. Xchar *filename, *fullpathname;
  62059. X{
  62060. X    int fd;
  62061. X    char *fractdir;
  62062. X
  62063. X    if (filename[0]=='/') {
  62064. X    strcpy(fullpathname,filename);
  62065. X    return;
  62066. X    }
  62067. X    fractdir = getenv("FRACTDIR");
  62068. X    if (fractdir != NULL) {
  62069. X    strcpy(fullpathname,fractdir);
  62070. X    strcat(fullpathname,"/");
  62071. X    strcat(fullpathname,filename);
  62072. X    fd = open(fullpathname,O_RDONLY);
  62073. X    if (fd != -1) {
  62074. X        close(fd);
  62075. X        return;
  62076. X    }
  62077. X    }
  62078. X    strcpy(fullpathname,SRCDIR);
  62079. X    strcat(fullpathname,"/");
  62080. X    strcat(fullpathname,filename);
  62081. X    fd = open(fullpathname,O_RDONLY);
  62082. X    if (fd != -1) {
  62083. X    close(fd);
  62084. X    return;
  62085. X    }
  62086. X    strcpy(fullpathname,"./");
  62087. X    strcat(fullpathname,filename);
  62088. X}
  62089. X
  62090. X/*
  62091. X *----------------------------------------------------------------------
  62092. X *
  62093. X * filelength --
  62094. X *
  62095. X *      Find length of a file.
  62096. X *
  62097. X * Results:
  62098. X *      Length.
  62099. X *
  62100. X * Side effects:
  62101. X *      None.
  62102. X *
  62103. X *----------------------------------------------------------------------
  62104. X */
  62105. Xint filelength(fd)
  62106. Xint fd;
  62107. X{
  62108. X    struct stat buf;
  62109. X    fstat(fd,&buf);
  62110. X    return buf.st_size;
  62111. X}
  62112. X
  62113. X/*
  62114. X *----------------------------------------------------------------------
  62115. X *
  62116. X * splitpath --
  62117. X *
  62118. X *      This is the splitpath code from prompts.c
  62119. X *
  62120. X * Results:
  62121. X *      Returns drive, dir, base, and extension.
  62122. X *
  62123. X * Side effects:
  62124. X *      None.
  62125. X *
  62126. X *----------------------------------------------------------------------
  62127. X */
  62128. Xsplitpath(char *template,char *drive,char *dir,char *fname,char *ext)
  62129. X{
  62130. X   int length;
  62131. X   int len;
  62132. X   int offset;
  62133. X   char *tmp;
  62134. X
  62135. X   if(drive)
  62136. X      drive[0] = 0;
  62137. X   if(dir)
  62138. X      dir[0]   = 0;
  62139. X   if(fname)
  62140. X      fname[0] = 0;
  62141. X   if(ext)
  62142. X      ext[0]   = 0;
  62143. X
  62144. X   if((length = strlen(template)) == 0)
  62145. X      return(0);
  62146. X   offset = 0;
  62147. X
  62148. X   /* get drive */
  62149. X   if(length >= 2)
  62150. X      if(template[1] == ':')
  62151. X      {
  62152. X     if(drive)
  62153. X     {
  62154. X        drive[0] = template[offset++];
  62155. X        drive[1] = template[offset++];
  62156. X        drive[2] = 0;
  62157. X     }
  62158. X     else
  62159. X     {
  62160. X        offset++;
  62161. X        offset++;
  62162. X     }
  62163. X      }
  62164. X
  62165. X   /* get dir */
  62166. X   if(offset < length)
  62167. X   {
  62168. X      tmp = strrchr(template,SLASHC);
  62169. X      if(tmp)
  62170. X      {
  62171. X     tmp++;  /* first character after slash */
  62172. X     len = tmp - &template[offset];
  62173. X     if(len >=0 && len < 80 && dir)
  62174. X        strncpy(dir,&template[offset],len);
  62175. X     if(len < 80 && dir)
  62176. X        dir[len] = 0;
  62177. X     offset += len;
  62178. X      }
  62179. X   }
  62180. X   else
  62181. X      return(0);
  62182. X
  62183. X   /* get fname */
  62184. X   if(offset < length)
  62185. X   {
  62186. X      tmp = strrchr(template,'.');
  62187. X      if(tmp < strrchr(template,SLASHC) || tmp < strrchr(template,':'))
  62188. X     tmp = 0; /* in this case the '.' must be a directory */
  62189. X      if(tmp)
  62190. X      {
  62191. X     tmp++; /* first character past "." */
  62192. X     len = tmp - &template[offset];
  62193. X     if((len > 0) && (offset+len < length) && fname)
  62194. X     {
  62195. X        strncpy(fname,&template[offset],len);
  62196. X        fname[len] = 0;
  62197. X     }
  62198. X     offset += len;
  62199. X     if((offset < length) && ext)
  62200. X        strcpy(ext,&template[offset]);
  62201. X      }
  62202. X      else if((offset < length) && fname)
  62203. X     strcpy(fname,&template[offset]);
  62204. X   }
  62205. X   return(0);
  62206. X}
  62207. X
  62208. X_splitpath(char *template,char *drive,char *dir,char *fname,char *ext)
  62209. X{
  62210. X    return splitpath(template,drive,dir,fname,ext);
  62211. X}
  62212. X
  62213. X/* SGI lacks ftime.  This ftime simulation routine is from Frank Chen */
  62214. X#ifdef FTIME
  62215. Xvoid ftime(tp)
  62216. Xstruct timeb    *tp;
  62217. X{
  62218. X        struct timeval  timep;
  62219. X        struct timezone timezp;
  62220. X
  62221. X        if ( gettimeofday(&timep,&timezp) != 0) {
  62222. X                perror("error in gettimeofday");
  62223. X                exit(0);
  62224. X        }
  62225. X        tp->time = timep.tv_sec;
  62226. X        tp->millitm = timep.tv_usec/1000;
  62227. X        tp->timezone = timezp.tz_minuteswest;
  62228. X        tp->dstflag = timezp.tz_dsttime;
  62229. X}
  62230. X#endif
  62231. SHAR_EOF
  62232. $TOUCH -am 1028230193 unix.c &&
  62233. chmod 0644 unix.c ||
  62234. echo "restore of unix.c failed"
  62235. set `wc -c unix.c`;Wc_c=$1
  62236. if test "$Wc_c" != "8340"; then
  62237.     echo original size 8340, current size $Wc_c
  62238. fi
  62239. # ============= unixscr.c ==============
  62240. echo "x - extracting unixscr.c (Text)"
  62241. sed 's/^X//' << 'SHAR_EOF' > unixscr.c &&
  62242. X/* Unixscr.c
  62243. X * This file contains routines for the Unix port of fractint.
  62244. X * It uses the current window for text and creates an X window for graphics.
  62245. X *
  62246. X * This file Copyright 1991 Ken Shirriff.  It may be used according to the
  62247. X * fractint license conditions, blah blah blah.
  62248. X *
  62249. X * Some of the X stuff is based on xloadimage by Jim Frost.
  62250. X * The FindWindowRoot routine is from ssetroot by Tom LaStrange.
  62251. X * Other root window stuff is based on xmartin, by Ed Kubaitis.
  62252. X * Some of the colormap stuff is from Mike Yang (mikey@sgi.com).
  62253. X * Some of the zoombox code is from Bill Broadley.
  62254. X * David Sanderson straightened out a bunch of include file problems.
  62255. X */
  62256. X
  62257. X#include <stdio.h>
  62258. X#include <stdlib.h>
  62259. X#include <curses.h>
  62260. X#include <X11/Xlib.h>
  62261. X#include <X11/keysym.h>
  62262. X#include <X11/Xatom.h>
  62263. X#include <signal.h>
  62264. X#include <sys/types.h>
  62265. X#ifdef _AIX
  62266. X#include <sys/select.h>
  62267. X#endif
  62268. X#include <sys/time.h>
  62269. X#include <sys/ioctl.h>
  62270. X#ifdef FPUERR
  62271. X#include <floatingpoint.h>
  62272. X#endif
  62273. X#ifdef __hpux
  62274. X#include <sys/file.h>
  62275. X#endif
  62276. X#include <fcntl.h>
  62277. X#include "fractint.h"
  62278. X#include "prototyp.h"
  62279. X#include "helpdefs.h"
  62280. X#ifdef linux
  62281. X#define FNDELAY O_NDELAY
  62282. X#endif
  62283. X
  62284. X/* Check if there is a character waiting for us.  */
  62285. X#define input_pending() (ioctl(0,FIONREAD,&iocount),(int)iocount)
  62286. X
  62287. X/* external variables (set in the FRACTINT.CFG file, but findable here */
  62288. X
  62289. Xextern    int    dotmode;        /* video access method (= 19)       */
  62290. Xextern    int    sxdots, sydots;     /* total # of dots on the screen   */
  62291. Xextern    int    sxoffs, syoffs;     /* offset of drawing area          */
  62292. Xextern    int    colors;         /* maximum colors available       */
  62293. Xextern    int    initmode;
  62294. Xextern    int    adapter;
  62295. Xextern    int    gotrealdac;
  62296. Xextern    int    inside_help;
  62297. Xextern  float    finalaspectratio;
  62298. Xextern  float    screenaspect;
  62299. Xextern    int    lookatmouse;
  62300. X
  62301. Xextern struct videoinfo videotable[];
  62302. X
  62303. X/* the video-palette array (named after the VGA adapter's video-DAC) */
  62304. X
  62305. Xextern unsigned char dacbox[256][3];
  62306. X
  62307. Xextern void drawbox();
  62308. X
  62309. Xextern int text_type;
  62310. Xextern int helpmode;
  62311. Xextern int rotate_hi;
  62312. X
  62313. Xextern void fpe_handler();
  62314. X
  62315. Xextern WINDOW *curwin;
  62316. X
  62317. Xstatic int onroot = 0;
  62318. Xstatic int fullscreen = 0;
  62319. Xstatic int sharecolor = 0;
  62320. Xstatic int privatecolor = 0;
  62321. Xstatic int fixcolors = 0;
  62322. Xstatic int sync = 0; /* Run X events synchronously (debugging) */
  62323. Xint slowdisplay = 0; /* We have a slow display, so don't print too much */
  62324. Xstatic int simple_input = 0; /* Use simple input (debugging) */
  62325. Xstatic char *Xdisplay = "";
  62326. Xstatic char *Xgeometry = NULL;
  62327. X
  62328. Xstatic int unixDisk = 0; /* Flag if we use the disk video mode */
  62329. X
  62330. Xstatic int old_fcntl;
  62331. X
  62332. Xstatic int doesBacking;
  62333. X
  62334. X/*
  62335. X * The pixtab stuff is so we can map from fractint pixel values 0-n to
  62336. X * the actual color table entries which may be anything.
  62337. X */
  62338. Xstatic int usepixtab = 0;
  62339. Xstatic unsigned long pixtab[256];
  62340. Xstatic int ipixtab[256];
  62341. X
  62342. Xstatic int fastmode = 0; /* Don't draw pixels 1 at a time */
  62343. Xstatic int alarmon = 0; /* 1 if the refresh alarm is on */
  62344. Xstatic int doredraw = 0; /* 1 if we have a redraw waiting */
  62345. X
  62346. X/* Static routines */
  62347. Xstatic Window FindRootWindow(void);
  62348. Xstatic Window pr_dwmroot(Display *dpy, Window pwin);
  62349. Xstatic int errhand(Display *dp, XErrorEvent *xe);
  62350. Xstatic int getachar(void);
  62351. Xstatic int handleesc(void); 
  62352. Xstatic int translatekey(int ch); 
  62353. Xstatic int xcmapstuff(void); 
  62354. Xstatic int xhandleevents(void); 
  62355. Xstatic void RemoveRootPixmap(void);
  62356. Xstatic void doneXwindow(void);
  62357. Xstatic void initdacbox(void);
  62358. Xstatic void setredrawscreen(void); 
  62359. Xstatic void clearXwindow(void);
  62360. X#ifdef FPUERR
  62361. Xstatic void continue_hdl(int sig, int code, struct sigcontext *scp,
  62362. X    char *addr);
  62363. X#endif
  62364. X
  62365. Xstatic int mousefkey[4][4] /* [button][dir] */ = {
  62366. X    {RIGHT_ARROW,LEFT_ARROW,DOWN_ARROW,UP_ARROW},
  62367. X    {0,0,PAGE_DOWN,PAGE_UP},
  62368. X    {CTL_PLUS,CTL_MINUS,CTL_DEL,CTL_INSERT},
  62369. X    {CTL_END,CTL_HOME,CTL_PAGE_DOWN,CTL_PAGE_UP}
  62370. X};
  62371. X
  62372. X/*
  62373. X *----------------------------------------------------------------------
  62374. X *
  62375. X * unixarg --
  62376. X *
  62377. X *    See if we want to do something with the argument.
  62378. X *
  62379. X * Results:
  62380. X *    Returns 1 if we parsed the argument.
  62381. X *
  62382. X * Side effects:
  62383. X *    Increments i if we use more than 1 argument.
  62384. X *
  62385. X *----------------------------------------------------------------------
  62386. X */
  62387. Xint
  62388. Xunixarg(argc,argv,i)
  62389. Xint argc;
  62390. Xchar **argv;
  62391. Xint *i;
  62392. X{
  62393. X    if (strcmp(argv[*i],"-display")==0 && (*i)+1<argc) {
  62394. X    Xdisplay = argv[(*i)+1];
  62395. X    (*i)++;
  62396. X    return 1;
  62397. X    } else if (strcmp(argv[*i],"-fullscreen")==0) {
  62398. X    fullscreen = 1;
  62399. X    return 1;
  62400. X    } else if (strcmp(argv[*i],"-disk")==0) {
  62401. X    unixDisk = 1;
  62402. X    return 1;
  62403. X    } else if (strcmp(argv[*i],"-onroot")==0) {
  62404. X    onroot = 1;
  62405. X    return 1;
  62406. X    } else if (strcmp(argv[*i],"-share")==0) {
  62407. X    sharecolor = 1;
  62408. X    return 1;
  62409. X    } else if (strcmp(argv[*i],"-fast")==0) {
  62410. X    fastmode = 1;
  62411. X    return 1;
  62412. X    } else if (strcmp(argv[*i],"-simple")==0) {
  62413. X    simple_input = 1;
  62414. X    return 1;
  62415. X    } else if (strcmp(argv[*i],"-slowdisplay")==0) {
  62416. X    slowdisplay = 1;
  62417. X    return 1;
  62418. X    } else if (strcmp(argv[*i],"-sync")==0) {
  62419. X    sync = 1;
  62420. X    return 1;
  62421. X    } else if (strcmp(argv[*i],"-private")==0) {
  62422. X    privatecolor = 1;
  62423. X    return 1;
  62424. X    } else if (strcmp(argv[*i],"-fixcolors")==0 && *i+1<argc) {
  62425. X    fixcolors = atoi(argv[(*i)+1]);
  62426. X    (*i)++;
  62427. X    return 1;
  62428. X    } else if (strcmp(argv[*i],"-geometry")==0 && *i+1<argc) {
  62429. X    Xgeometry = argv[(*i)+1];
  62430. X    (*i)++;
  62431. X    return 1;
  62432. X    } else {
  62433. X    return 0;
  62434. X    }
  62435. X}
  62436. X/*
  62437. X *----------------------------------------------------------------------
  62438. X *
  62439. X * UnixInit --
  62440. X *
  62441. X *    Initialize the windows and stuff.
  62442. X *
  62443. X * Results:
  62444. X *    None.
  62445. X *
  62446. X * Side effects:
  62447. X *    Initializes windows.
  62448. X *
  62449. X *----------------------------------------------------------------------
  62450. X */
  62451. Xvoid
  62452. XUnixInit()
  62453. X{
  62454. X    /*
  62455. X     * Check a bunch of important conditions
  62456. X     */
  62457. X    if (sizeof(short) != 2) {
  62458. X    fprintf(stderr,"Error: need short to be 2 bytes\n");
  62459. X    exit(-1);
  62460. X    }
  62461. X    if (sizeof(long) < sizeof(FLOAT4)) {
  62462. X    fprintf(stderr,"Error: need sizeof(long)>=sizeof(FLOAT4)\n");
  62463. X    exit(-1);
  62464. X    }
  62465. X
  62466. X    initscr();
  62467. X    curwin = stdscr;
  62468. X    cbreak();
  62469. X    noecho();
  62470. X
  62471. X    if (standout()) {
  62472. X    text_type = 1;
  62473. X    standend();
  62474. X    } else {
  62475. X    text_type = 1;
  62476. X    }
  62477. X
  62478. X    signal(SIGINT,goodbye);
  62479. X    signal(SIGFPE, fpe_handler);
  62480. X    /*
  62481. X    signal(SIGTSTP,goodbye);
  62482. X    */
  62483. X#ifdef FPUERR
  62484. X    signal(SIGABRT,SIG_IGN);
  62485. X    /*
  62486. X        setup the IEEE-handler to forget all common ( invalid,
  62487. X        divide by zero, overflow ) signals. Here we test, if 
  62488. X        such ieee trapping is supported.
  62489. X    */
  62490. X    if (ieee_handler("set","common",continue_hdl) != 0 )
  62491. X        printf("ieee trapping not supported here \n");
  62492. X#endif
  62493. X}
  62494. X
  62495. X/*
  62496. X *----------------------------------------------------------------------
  62497. X *
  62498. X * UnixDone --
  62499. X *
  62500. X *    Cleanup windows and stuff.
  62501. X *
  62502. X * Results:
  62503. X *    None.
  62504. X *
  62505. X * Side effects:
  62506. X *    Cleans up.
  62507. X *
  62508. X *----------------------------------------------------------------------
  62509. X */
  62510. X
  62511. Xvoid
  62512. XUnixDone()
  62513. X{
  62514. X    if (!unixDisk) {
  62515. X    doneXwindow();
  62516. X    }
  62517. X    if (!simple_input) {
  62518. X    fcntl(0,F_SETFL,old_fcntl);
  62519. X    }
  62520. X    mvcur(0,COLS-1, LINES-1,0);
  62521. X    nocbreak();
  62522. X    echo();
  62523. X    endwin();
  62524. X}
  62525. X
  62526. X/*
  62527. X *----------------------------------------------------------------------
  62528. X *
  62529. X * errhand --
  62530. X *
  62531. X *    Called on an X server error.
  62532. X *
  62533. X * Results:
  62534. X *    None.
  62535. X *
  62536. X * Side effects:
  62537. X *    Prints the error message.
  62538. X *
  62539. X *----------------------------------------------------------------------
  62540. X */
  62541. Xstatic int errhand(dp,xe)
  62542. XDisplay *dp;
  62543. XXErrorEvent *xe;
  62544. X{
  62545. X        char buf[200];
  62546. X        fflush(stdout);
  62547. X        printf("X Error: %d %d %d %d\n",xe->type,xe->error_code,
  62548. X        xe->request_code, xe->minor_code);
  62549. X        XGetErrorText(dp,xe->error_code,buf,200);
  62550. X        printf("%s\n",buf);
  62551. X}
  62552. X
  62553. X#ifdef FPUERR
  62554. X/*
  62555. X *----------------------------------------------------------------------
  62556. X *
  62557. X * continue_hdl --
  62558. X *
  62559. X *    Handle an IEEE fpu error.
  62560. X *    This routine courtesy of Ulrich Hermes
  62561. X *    <hermes@olymp.informatik.uni-dortmund.de>
  62562. X *
  62563. X * Results:
  62564. X *    None.
  62565. X *
  62566. X * Side effects:
  62567. X *    Clears flag.
  62568. X *
  62569. X *----------------------------------------------------------------------
  62570. X */
  62571. Xstatic void
  62572. Xcontinue_hdl(sig,code,scp,addr)
  62573. Xint sig, code;
  62574. X
  62575. Xstruct sigcontext *scp;
  62576. Xchar *addr;
  62577. X
  62578. X{
  62579. X    int i;
  62580. X    char out[20];
  62581. X    /*        if you want to get all messages enable this statement.    */
  62582. X    /*  printf("ieee exception code %x occurred at pc %X\n",code,scp->sc_pc); */
  62583. X    /*    clear all excaption flags                      */
  62584. X    i = ieee_flags("clear","exception","all",out);
  62585. X}
  62586. X#endif
  62587. X
  62588. X#define DEFX 640
  62589. X#define DEFY 480
  62590. X#define DEFXY "640x480+0+0"
  62591. X
  62592. Xstatic Display *Xdp = NULL;
  62593. Xstatic Window Xw;
  62594. Xstatic GC Xgc = NULL;
  62595. Xstatic Visual *Xvi;
  62596. Xstatic Screen *Xsc;
  62597. Xstatic Colormap    Xcmap;
  62598. Xstatic int Xdepth;
  62599. Xstatic XImage *Ximage =NULL;
  62600. Xstatic char *Xdata;
  62601. Xstatic int Xdscreen;
  62602. Xstatic Pixmap    Xpixmap = 0;
  62603. Xstatic int Xwinwidth=DEFX,Xwinheight=DEFY;
  62604. Xstatic Window Xroot;
  62605. Xstatic int xlastcolor = -1;
  62606. Xstatic int xlastfcn = GXcopy;
  62607. Xstatic BYTE *pixbuf = NULL;
  62608. X
  62609. X/*
  62610. X *----------------------------------------------------------------------
  62611. X *
  62612. X * initUnixWindow --
  62613. X *
  62614. X *    Make the X window.
  62615. X *
  62616. X * Results:
  62617. X *    None.
  62618. X *
  62619. X * Side effects:
  62620. X *    Makes window.
  62621. X *
  62622. X *----------------------------------------------------------------------
  62623. X */
  62624. X
  62625. Xvoid
  62626. XinitUnixWindow()
  62627. X{
  62628. X    XSetWindowAttributes Xwatt;
  62629. X    XGCValues Xgcvals;
  62630. X    int Xwinx=0,Xwiny=0;
  62631. X    int i;
  62632. X
  62633. X    if (Xdp != NULL) {
  62634. X       /* We are already initialized */
  62635. X       return;
  62636. X    }
  62637. X
  62638. X    if (!simple_input) {
  62639. X    old_fcntl = fcntl(0,F_GETFL);
  62640. X    fcntl(0,F_SETFL,FNDELAY);
  62641. X    }
  62642. X
  62643. X    /*
  62644. X    initmode = 0;
  62645. X    */
  62646. X    adapter = 0;
  62647. X
  62648. X    /* We have to do some X stuff even for disk video, to parse the geometry
  62649. X     * string */
  62650. X
  62651. X    if (unixDisk) {
  62652. X    int offx, offy;
  62653. X    fastmode = 0;
  62654. X    gotrealdac=1;
  62655. X    colors = 256;
  62656. X    for (i=0;i<colors;i++) {
  62657. X        pixtab[i] = i;
  62658. X        ipixtab[i] = i;
  62659. X    }
  62660. X    if (fixcolors>0) {
  62661. X        colors = fixcolors;
  62662. X    }
  62663. X    if (Xgeometry) {
  62664. X        XParseGeometry(Xgeometry, &offx, &offy, (unsigned int *)&Xwinwidth,
  62665. X            (unsigned int *)&Xwinheight);
  62666. X    }
  62667. X    sxdots = Xwinwidth;
  62668. X    sydots = Xwinheight;
  62669. X    } else {
  62670. X    Xdp = XOpenDisplay(Xdisplay);
  62671. X    if (Xdp==NULL) {
  62672. X        fprintf(stderr,"Could not open display %s\n",Xdisplay);
  62673. X        fprintf(stderr,"Note: xfractint can run without X in -disk mode\n");
  62674. X        UnixDone();
  62675. X        exit(-1);
  62676. X    }
  62677. X    Xdscreen = XDefaultScreen(Xdp);
  62678. X    if (Xgeometry && !onroot) {
  62679. X        XGeometry(Xdp, Xdscreen, Xgeometry, DEFXY, 0, 1, 1, 0, 0,
  62680. X            &Xwinx, &Xwiny, &Xwinwidth, &Xwinheight);
  62681. X    }
  62682. X    if (sync) {
  62683. X        XSynchronize(Xdp,True);
  62684. X    }
  62685. X    XSetErrorHandler(errhand);
  62686. X    Xsc = ScreenOfDisplay(Xdp,Xdscreen);
  62687. X    Xvi = XDefaultVisualOfScreen(Xsc);
  62688. X    Xdepth = DefaultDepth(Xdp,Xdscreen);
  62689. X    colors = 1<<Xdepth;
  62690. X    if (colors>256) colors = 256;
  62691. X    if (fixcolors>0) {
  62692. X        colors = fixcolors;
  62693. X    }
  62694. X    switch (Xvi->class) {
  62695. X        case DirectColor:
  62696. X        case PseudoColor:
  62697. X        case GrayScale:
  62698. X        gotrealdac=1;
  62699. X        break;
  62700. X        case TrueColor:
  62701. X        case StaticColor:
  62702. X        case StaticGray:
  62703. X        default:
  62704. X        gotrealdac=0;
  62705. X        break;
  62706. X    }
  62707. X
  62708. X    if (fullscreen || onroot) {
  62709. X        Xwinwidth = DisplayWidth(Xdp,Xdscreen);
  62710. X        Xwinheight = DisplayHeight(Xdp,Xdscreen);
  62711. X    }
  62712. X    sxdots = Xwinwidth;
  62713. X    sydots = Xwinheight;
  62714. X
  62715. X    Xwatt.background_pixel = BlackPixelOfScreen(Xsc);
  62716. X    Xwatt.bit_gravity = StaticGravity;
  62717. X    doesBacking = DoesBackingStore(Xsc);
  62718. X    if (doesBacking) {
  62719. X        Xwatt.backing_store = Always;
  62720. X    } else {
  62721. X        Xwatt.backing_store = NotUseful;
  62722. X    }
  62723. X    if (onroot) {
  62724. X        Xroot = FindRootWindow();
  62725. X        RemoveRootPixmap();
  62726. X        /*
  62727. X        XSetWindowBackground(Xdp,Xroot);
  62728. X        */
  62729. X        Xgc = XCreateGC(Xdp,Xroot,0,&Xgcvals);
  62730. X        Xpixmap = XCreatePixmap(Xdp,Xroot,Xwinwidth,Xwinheight,Xdepth);
  62731. X        Xw = Xroot;
  62732. X        XFillRectangle(Xdp,Xpixmap,Xgc,0,0,Xwinwidth,Xwinheight);
  62733. X        XSetWindowBackgroundPixmap(Xdp,Xroot,Xpixmap);
  62734. X    } else {
  62735. X        Xroot = DefaultRootWindow(Xdp);
  62736. X        Xw = XCreateWindow(Xdp, Xroot, Xwinx, Xwiny, Xwinwidth,
  62737. X            Xwinheight, 0, Xdepth, InputOutput, CopyFromParent,
  62738. X            CWBackPixel|CWBitGravity|CWBackingStore, &Xwatt);
  62739. X        XStoreName(Xdp,Xw,"xfractint");
  62740. X        Xgc = XCreateGC(Xdp,Xw,0,&Xgcvals);
  62741. X    }
  62742. X    colors = xcmapstuff();
  62743. X    if (rotate_hi==255) rotate_hi = colors-1;
  62744. X    if (!onroot) {
  62745. X        XSetBackground(Xdp,Xgc,pixtab[0]);
  62746. X        XSetForeground(Xdp,Xgc,pixtab[1]);
  62747. X        Xwatt.background_pixel = pixtab[0];
  62748. X        XChangeWindowAttributes(Xdp,Xw,CWBackPixel,&Xwatt);
  62749. X        XMapWindow(Xdp,Xw);
  62750. X    }
  62751. X    if (onroot) {
  62752. X        XSelectInput(Xdp,Xw,KeyPressMask|KeyReleaseMask|ExposureMask);
  62753. X    } else {
  62754. X        XSelectInput(Xdp,Xw,KeyPressMask|KeyReleaseMask|ExposureMask|
  62755. X            ButtonPressMask|ButtonReleaseMask|PointerMotionMask);
  62756. X    }
  62757. X
  62758. X    resizeWindow();
  62759. X    xsync();
  62760. X    }
  62761. X
  62762. X    initdacbox();
  62763. X
  62764. X    videotable[0].xdots = sxdots;
  62765. X    videotable[0].ydots = sydots;
  62766. X    videotable[0].colors = colors;
  62767. X    videotable[0].dotmode = (unixDisk) ? 11 : 19;
  62768. X}
  62769. X/*
  62770. X *----------------------------------------------------------------------
  62771. X *
  62772. X * doneXwindow --
  62773. X *
  62774. X *    Clean up the X stuff.
  62775. X *
  62776. X * Results:
  62777. X *    None.
  62778. X *
  62779. X * Side effects:
  62780. X *    Frees window, etc.
  62781. X *
  62782. X *----------------------------------------------------------------------
  62783. X */
  62784. Xstatic void
  62785. XdoneXwindow()
  62786. X{
  62787. X    if (Xdp==NULL) {
  62788. X    return;
  62789. X    }
  62790. X    if (Xgc) {
  62791. X    XFreeGC(Xdp,Xgc);
  62792. X    }
  62793. X    if (Xpixmap) {
  62794. X    XFreePixmap(Xdp,Xpixmap);
  62795. X    Xpixmap = (Pixmap)NULL;
  62796. X    }
  62797. X    XFlush(Xdp);
  62798. X    /*
  62799. X    XCloseDisplay(Xdp);
  62800. X    */
  62801. X    Xdp = NULL;
  62802. X}
  62803. X
  62804. X/*
  62805. X *----------------------------------------------------------------------
  62806. X *
  62807. X * clearXwindow --
  62808. X *
  62809. X *    Clears X window.
  62810. X *
  62811. X * Results:
  62812. X *    None.
  62813. X *
  62814. X * Side effects:
  62815. X *    Clears window.
  62816. X *
  62817. X *----------------------------------------------------------------------
  62818. X */
  62819. Xstatic void
  62820. XclearXwindow()
  62821. X{
  62822. X    char *ptr;
  62823. X    int i,len;
  62824. X    if (pixtab[0] != 0) {
  62825. X    /*
  62826. X     * Initialize image to pixtab[0].
  62827. X     */
  62828. X    if (colors==2) {
  62829. X        for (i=0;i<Ximage->bytes_per_line;i++) {
  62830. X        Ximage->data[i] = 0xff;
  62831. X        }
  62832. X    } else {
  62833. X        for (i=0;i<Ximage->bytes_per_line;i++) {
  62834. X        Ximage->data[i] = pixtab[0];
  62835. X        }
  62836. X    }
  62837. X    for (i=1;i<Ximage->height;i++) {
  62838. X        bcopy(Ximage->data,Ximage->data+i*Ximage->bytes_per_line,
  62839. X        Ximage->bytes_per_line);
  62840. X    }
  62841. X    } else {
  62842. X    /*
  62843. X     * Initialize image to 0's.
  62844. X     */
  62845. X    bzero(Ximage->data,Ximage->bytes_per_line*Ximage->height);
  62846. X    }
  62847. X    xlastcolor = -1;
  62848. X    XSetForeground(Xdp, Xgc, pixtab[0]);
  62849. X    if (onroot) {
  62850. X    XFillRectangle(Xdp,Xpixmap,Xgc,0,0,Xwinwidth,Xwinheight);
  62851. X    }
  62852. X    XFillRectangle(Xdp,Xw,Xgc,0,0,Xwinwidth,Xwinheight);
  62853. X    xsync();
  62854. X}
  62855. X
  62856. X/*
  62857. X *----------------------------------------------------------------------
  62858. X *
  62859. X * initdacbox --
  62860. X *
  62861. X * Put something nice in the dac.
  62862. X *
  62863. X * The conditions are:
  62864. X *    Colors 1 and 2 should be bright so ifs fractals show up.
  62865. X *    Color 15 should be bright for lsystem.
  62866. X *    Color 1 should be bright for bifurcation.
  62867. X *    Colors 1,2,3 should be distinct for periodicity.
  62868. X *    The color map should look good for mandelbrot.
  62869. X *    The color map should be good if only 128 colors are used.
  62870. X *
  62871. X * Results:
  62872. X *    None.
  62873. X *
  62874. X * Side effects:
  62875. X *    Loads the dac.
  62876. X *
  62877. X *----------------------------------------------------------------------
  62878. X */
  62879. Xstatic void
  62880. Xinitdacbox()
  62881. X{
  62882. X    int i;
  62883. X    if (colors==2) {
  62884. X    dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  62885. X    dacbox[1][0] = dacbox[1][1] = dacbox[1][2] = 63;
  62886. X    } else {
  62887. X    for (i=0;i<256;i++) {
  62888. X            dacbox[i][0] = (i>>5)*8+7;
  62889. X            dacbox[i][1] = (((i+16)&28)>>2)*8+7;
  62890. X            dacbox[i][2] = (((i+2)&3))*16+15;
  62891. X    }
  62892. X    dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  62893. X    dacbox[1][0] = dacbox[1][1] = dacbox[1][2] = 63;
  62894. X    dacbox[2][0] = 47; dacbox[2][1] = dacbox[2][2] = 63;
  62895. X    }
  62896. X    writevideopalette();
  62897. X}
  62898. X
  62899. X
  62900. Xint startvideo()
  62901. X{
  62902. X    clearXwindow();
  62903. X    return(0);
  62904. X}
  62905. X
  62906. Xint endvideo()
  62907. X{
  62908. X    return(0);                /* set flag: video ended */
  62909. X
  62910. X}
  62911. X
  62912. X/*
  62913. X *----------------------------------------------------------------------
  62914. X *
  62915. X * resizeWindow --
  62916. X *
  62917. X *    Look after resizing the window if necessary.
  62918. X *
  62919. X * Results:
  62920. X *    Returns 1 for resize, 0 for no resize.
  62921. X *
  62922. X * Side effects:
  62923. X *    May reallocate data structures.
  62924. X *
  62925. X *----------------------------------------------------------------------
  62926. X */
  62927. Xint
  62928. XresizeWindow()
  62929. X{
  62930. X    static int oldx = -1, oldy = -1;
  62931. X    int junki;
  62932. X    unsigned int junkui;
  62933. X    Window *junkw;
  62934. X    unsigned int width, height;
  62935. X    int Xmwidth;
  62936. X    Status status;
  62937. X
  62938. X    if (unixDisk) return 0;
  62939. X
  62940. X    XGetGeometry(Xdp,Xw,&junkw,&junki, &junki, &width, &height,
  62941. X        &junkui, &junkui);
  62942. X
  62943. X    if (oldx != width || oldy != height) {
  62944. X    sxdots = width;
  62945. X    sydots = height;
  62946. X    videotable[0].xdots = sxdots;
  62947. X    videotable[0].ydots = sydots;
  62948. X    oldx = sxdots;
  62949. X    oldy = sydots;
  62950. X    Xwinwidth = sxdots;
  62951. X    Xwinheight = sydots;
  62952. X    screenaspect = sydots/(float)sxdots;
  62953. X    finalaspectratio = screenaspect;
  62954. X    Xmwidth = (Xdepth > 1)? sxdots: (1 + sxdots/8);
  62955. X    if (pixbuf != NULL) {
  62956. X        free(pixbuf);
  62957. X    }
  62958. X    pixbuf = (BYTE *) malloc(Xwinwidth *sizeof(BYTE));
  62959. X    if (Ximage != NULL) {
  62960. X        free(Ximage->data);
  62961. X        XDestroyImage(Ximage);
  62962. X    }
  62963. X    Ximage = XCreateImage(Xdp,Xvi,Xdepth, ZPixmap, 0, NULL, sxdots,
  62964. X        sydots,8, Xmwidth);
  62965. X    if (Ximage == NULL) {
  62966. X        printf("XCreateImage failed\n");
  62967. X        UnixDone();
  62968. X        exit(-1);
  62969. X    }
  62970. X    Ximage->data = malloc(Ximage->bytes_per_line * Ximage->height);
  62971. X    if (Ximage->data==NULL) {
  62972. X        fprintf(stderr,"Malloc failed: %d\n", Ximage->bytes_per_line *
  62973. X            Ximage->height);
  62974. X        exit(-1);
  62975. X    }
  62976. X    clearXwindow();
  62977. X    return 1;
  62978. X    } else {
  62979. X    return 0;
  62980. X    }
  62981. X}
  62982. X
  62983. X/*
  62984. X *----------------------------------------------------------------------
  62985. X *
  62986. X * xcmapstuff --
  62987. X *
  62988. X *    Set up the colormap appropriately
  62989. X *
  62990. X * Results:
  62991. X *    Number of colors.
  62992. X *
  62993. X * Side effects:
  62994. X *    Sets colormap.
  62995. X *
  62996. X *----------------------------------------------------------------------
  62997. X */
  62998. Xstatic int
  62999. Xxcmapstuff()
  63000. X{
  63001. X    int ncells,i,powr;
  63002. X
  63003. X    if (onroot) {
  63004. X    privatecolor = 0;
  63005. X    }
  63006. X    for (i=0;i<colors;i++) {
  63007. X    pixtab[i] = i;
  63008. X    ipixtab[i] = 999;
  63009. X    }
  63010. X    if (!gotrealdac) {
  63011. X    } else if (sharecolor) {
  63012. X    gotrealdac = 0;
  63013. X    } else if (privatecolor) {
  63014. X    Xcmap = XCreateColormap(Xdp,Xw,Xvi,AllocAll);
  63015. X    XSetWindowColormap(Xdp,Xw,Xcmap);
  63016. X    } else {
  63017. X    Xcmap = DefaultColormap(Xdp,Xdscreen);
  63018. X    for (powr=Xdepth;powr>=1;powr--) {
  63019. X        ncells = 1<<powr;
  63020. X        if (ncells>colors) continue;
  63021. X        if (XAllocColorCells(Xdp,Xcmap,False,NULL,0,pixtab,
  63022. X            (unsigned int)ncells)) {
  63023. X        colors = ncells;
  63024. X        printf("%d colors\n",colors);
  63025. X        usepixtab = 1;
  63026. X        break;
  63027. X        }
  63028. X    }
  63029. X    if (!usepixtab) {
  63030. X        printf("Couldn't allocate any colors\n");
  63031. X        gotrealdac = 0;
  63032. X    }
  63033. X    }
  63034. X    for (i=0;i<colors;i++) {
  63035. X    ipixtab[pixtab[i]] = i;
  63036. X    }
  63037. X    /* We must make sure if any color uses position 0, that it is 0.
  63038. X     * This is so we can clear the image with bzero.
  63039. X     * So, suppose fractint 0 = cmap 42, cmap 0 = fractint 55.
  63040. X     * Then want fractint 0 = cmap 0, cmap 42 = fractint 55.
  63041. X     * I.e. pixtab[55] = 42, ipixtab[42] = 55.
  63042. X     */
  63043. X    if (ipixtab[0] == 999) {
  63044. X    ipixtab[0] = 0;
  63045. X    } else if (ipixtab[0] != 0) {
  63046. X    int other;
  63047. X    other = ipixtab[0];
  63048. X    pixtab[other] = pixtab[0];
  63049. X    ipixtab[pixtab[other]] = other;
  63050. X    pixtab[0] = 0;
  63051. X    ipixtab[0] = 0;
  63052. X    }
  63053. X
  63054. X    if (!gotrealdac && colors==2 && BlackPixelOfScreen(Xsc)!=0) {
  63055. X    pixtab[0] = ipixtab[0] = 1;
  63056. X    pixtab[1] = ipixtab[1] = 0;
  63057. X    usepixtab = 1;
  63058. X    }
  63059. X
  63060. X    return colors;
  63061. X}
  63062. X/*
  63063. X *----------------------------------------------------------------------
  63064. X *
  63065. X * writevideoline --
  63066. X *
  63067. X *    Write a line of pixels to the screen.
  63068. X *
  63069. X * Results:
  63070. X *    None.
  63071. X *
  63072. X * Side effects:
  63073. X *    Draws pixels.
  63074. X *
  63075. X *----------------------------------------------------------------------
  63076. X */
  63077. Xvoid
  63078. Xwritevideoline(y,x,lastx,pixels)
  63079. Xint x,y,lastx;
  63080. XBYTE *pixels;
  63081. X{
  63082. X    int width;
  63083. X    int i;
  63084. X    BYTE *pixline;
  63085. X
  63086. X#if 1
  63087. X    if (x==lastx) {
  63088. X    writevideo(x,y,pixels[0]);
  63089. X    return;
  63090. X    }
  63091. X    width = lastx-x+1;
  63092. X    if (usepixtab) {
  63093. X    for (i=0;i<width;i++) {
  63094. X        pixbuf[i] = pixtab[pixels[i]];
  63095. X    }
  63096. X    pixline = pixbuf;
  63097. X    } else {
  63098. X    pixline = pixels;
  63099. X    }
  63100. X    for (i=0;i<width;i++) {
  63101. X    XPutPixel(Ximage,x+i,y,pixline[i]);
  63102. X    }
  63103. X    if (fastmode==1 && helpmode != HELPXHAIR) {
  63104. X    if (!alarmon) {
  63105. X        schedulealarm(0);
  63106. X    }
  63107. X    } else {
  63108. X    XPutImage(Xdp,Xw,Xgc,Ximage,x,y,x,y,width,1);
  63109. X    if (onroot) {
  63110. X        XPutImage(Xdp,Xpixmap,Xgc,Ximage,x,y,x,y,width,1);
  63111. X    }
  63112. X    }
  63113. X#else
  63114. X    width = lastx-x+1;
  63115. X    for (i=0;i<width;i++) {
  63116. X    writevideo(x+i,y,pixels[i]);
  63117. X    }
  63118. X#endif
  63119. X}
  63120. X/*
  63121. X *----------------------------------------------------------------------
  63122. X *
  63123. X * readvideoline --
  63124. X *
  63125. X *    Reads a line of pixels from the screen.
  63126. X *
  63127. X * Results:
  63128. X *    None.
  63129. X *
  63130. X * Side effects:
  63131. X *    Gets pixels
  63132. X *
  63133. X *----------------------------------------------------------------------
  63134. X */
  63135. Xvoid
  63136. Xreadvideoline(y,x,lastx,pixels)
  63137. Xint x,y,lastx;
  63138. XBYTE *pixels;
  63139. X{
  63140. X    int i,width;
  63141. X    width = lastx-x+1;
  63142. X    for (i=0;i<width;i++) {
  63143. X    pixels[i] = readvideo(x+i,y);
  63144. X    }
  63145. X}
  63146. X
  63147. X/*
  63148. X *----------------------------------------------------------------------
  63149. X *
  63150. X * writevideo --
  63151. X *
  63152. X *    Write a point to the screen
  63153. X *
  63154. X * Results:
  63155. X *    None.
  63156. X *
  63157. X * Side effects:
  63158. X *    Draws point.
  63159. X *
  63160. X *----------------------------------------------------------------------
  63161. X */
  63162. Xvoid writevideo(int x, int y, int color)
  63163. X{
  63164. X#if DEBUG /* Debugging checks */
  63165. X    if (color>=colors || color < 0) {
  63166. X    printf("Color %d too big %d\n", color, colors);
  63167. X    }
  63168. X    if (x>=sxdots || x<0 || y>=sydots || y<0) {
  63169. X    printf("Bad coord %d %d\n", x,y);
  63170. X    }
  63171. X#endif
  63172. X    if (xlastcolor != color) {
  63173. X    XSetForeground(Xdp,Xgc,pixtab[color]);
  63174. X    xlastcolor = color;
  63175. X    }
  63176. X    XPutPixel(Ximage,x,y,pixtab[color]);
  63177. X    if (fastmode==1 && helpmode != HELPXHAIR) {
  63178. X    if (!alarmon) {
  63179. X        schedulealarm(0);
  63180. X    }
  63181. X    } else {
  63182. X    XDrawPoint(Xdp,Xw,Xgc,x,y);
  63183. X    if (onroot) {
  63184. X        XDrawPoint(Xdp,Xpixmap,Xgc,x,y);
  63185. X    }
  63186. X    }
  63187. X}
  63188. X
  63189. X/*
  63190. X *----------------------------------------------------------------------
  63191. X *
  63192. X * readvideo --
  63193. X *
  63194. X *    Read a point from the screen
  63195. X *
  63196. X * Results:
  63197. X *    Value of point.
  63198. X *
  63199. X * Side effects:
  63200. X *    None.
  63201. X *
  63202. X *----------------------------------------------------------------------
  63203. X */
  63204. Xint readvideo(int x, int y)
  63205. X{
  63206. X    return ipixtab[XGetPixel(Ximage,x,y)];
  63207. X}
  63208. X
  63209. XXColor cols[256];
  63210. X
  63211. X/*
  63212. X *----------------------------------------------------------------------
  63213. X *
  63214. X * readvideopalette --
  63215. X *    Reads the current video palette into dacbox.
  63216. X *    
  63217. X *
  63218. X * Results:
  63219. X *    None.
  63220. X *
  63221. X * Side effects:
  63222. X *    Fills in dacbox.
  63223. X *
  63224. X *----------------------------------------------------------------------
  63225. X */
  63226. Xint readvideopalette()
  63227. X{
  63228. X
  63229. X    int i;
  63230. X    if (gotrealdac==0) return -1;
  63231. X    for (i=0;i<256;i++) {
  63232. X    dacbox[i][0] = cols[i].red/1024;
  63233. X    dacbox[i][1] = cols[i].green/1024;
  63234. X    dacbox[i][2] = cols[i].blue/1024;
  63235. X    }
  63236. X    return 0;
  63237. X
  63238. X}
  63239. X
  63240. X/*
  63241. X *----------------------------------------------------------------------
  63242. X *
  63243. X * writevideopalette --
  63244. X *    Writes dacbox into the video palette.
  63245. X *    
  63246. X *
  63247. X * Results:
  63248. X *    None.
  63249. X *
  63250. X * Side effects:
  63251. X *    Changes the displayed colors.
  63252. X *
  63253. X *----------------------------------------------------------------------
  63254. X */
  63255. Xint writevideopalette()
  63256. X{
  63257. X    int i;
  63258. X
  63259. X    if (!gotrealdac) return -1;
  63260. X    for(i=0;i<256;i++) {
  63261. X    cols[i].pixel = pixtab[i];
  63262. X    cols[i].flags = DoRed | DoGreen | DoBlue;
  63263. X    cols[i].red = dacbox[i][0]*1024;
  63264. X    cols[i].green = dacbox[i][1]*1024;
  63265. X    cols[i].blue = dacbox[i][2]*1024;
  63266. X    }
  63267. X    if (!unixDisk) {
  63268. X    XStoreColors(Xdp,Xcmap,cols,colors);
  63269. X    XFlush(Xdp);
  63270. X    }
  63271. X    return 0;
  63272. X
  63273. X}
  63274. X/*
  63275. X *----------------------------------------------------------------------
  63276. X *
  63277. X * setlinemode --
  63278. X *
  63279. X *    Set line mode to 0=draw or 1=xor.
  63280. X *
  63281. X * Results:
  63282. X *    None.
  63283. X *
  63284. X * Side effects:
  63285. X *    Sets mode.
  63286. X *
  63287. X *----------------------------------------------------------------------
  63288. X */
  63289. Xvoid
  63290. Xsetlinemode(mode)
  63291. Xint mode;
  63292. X{
  63293. X    if (unixDisk) return;
  63294. X    xlastcolor = -1;
  63295. X    if (mode==0) {
  63296. X    XSetFunction(Xdp, Xgc, GXcopy);
  63297. X    xlastfcn = GXcopy;
  63298. X    } else {
  63299. X    XSetForeground(Xdp, Xgc, colors-1);
  63300. X    xlastcolor = -1;
  63301. X    XSetFunction(Xdp, Xgc, GXxor);
  63302. X    xlastfcn = GXxor;
  63303. X    }
  63304. X}
  63305. X
  63306. X/*
  63307. X *----------------------------------------------------------------------
  63308. X *
  63309. X * drawline --
  63310. X *
  63311. X *    Draw a line.
  63312. X *
  63313. X * Results:
  63314. X *    None.
  63315. X *
  63316. X * Side effects:
  63317. X *    Modifies window.
  63318. X *
  63319. X *----------------------------------------------------------------------
  63320. X */
  63321. Xvoid
  63322. Xdrawline(x1,y1,x2,y2)
  63323. Xint x1,y1,x2,y2;
  63324. X{
  63325. X    if (!unixDisk) {
  63326. X    XDrawLine(Xdp,Xw,Xgc,x1,y1,x2,y2);
  63327. X    }
  63328. X}
  63329. X/*
  63330. X *----------------------------------------------------------------------
  63331. X *
  63332. X * xsync --
  63333. X *
  63334. X *    Sync the x server
  63335. X *
  63336. X * Results:
  63337. X *    None.
  63338. X *
  63339. X * Side effects:
  63340. X *    Modifies window.
  63341. X *
  63342. X *----------------------------------------------------------------------
  63343. X */
  63344. Xvoid
  63345. Xxsync()
  63346. X{
  63347. X    if (!unixDisk) {
  63348. X    XSync(Xdp,False);
  63349. X    }
  63350. X}
  63351. X/*
  63352. X *----------------------------------------------------------------------
  63353. X *
  63354. X * getachar --
  63355. X *
  63356. X *    Gets a character.
  63357. X *
  63358. X * Results:
  63359. X *    Key.
  63360. X *
  63361. X * Side effects:
  63362. X *    Reads key.
  63363. X *
  63364. X *----------------------------------------------------------------------
  63365. X */
  63366. Xstatic int
  63367. Xgetachar()
  63368. X{
  63369. X    if (simple_input) {
  63370. X    return getchar();
  63371. X    } else {
  63372. X    char ch;
  63373. X    int status;
  63374. X    status = read(0,&ch,1);
  63375. X    if (status<0) {
  63376. X        return -1;
  63377. X    } else {
  63378. X        return ch;
  63379. X    }
  63380. X    }
  63381. X}
  63382. X
  63383. Xstatic int xbufkey = 0;        /* Buffered X key */
  63384. X/*
  63385. X *----------------------------------------------------------------------
  63386. X *
  63387. X * xgetkey --
  63388. X *
  63389. X *    Get a key from the keyboard or the X server.
  63390. X *    Blocks if block = 1.
  63391. X *
  63392. X * Results:
  63393. X *    Key, or 0 if no key and not blocking.
  63394. X *    Times out after .5 second.
  63395. X *
  63396. X * Side effects:
  63397. X *    Processes X events.
  63398. X *
  63399. X *----------------------------------------------------------------------
  63400. X */
  63401. Xint
  63402. Xxgetkey(block)
  63403. Xint block;
  63404. X{
  63405. X    static int skipcount = 0;
  63406. X    int ch,ch2;
  63407. X    fd_set reads;
  63408. X    int status;
  63409. X    static struct timeval tout;
  63410. X    tout.tv_sec = 0;
  63411. X    tout.tv_usec = 500000;
  63412. X    while (1) {
  63413. X    if (input_pending()) {
  63414. X        ch = getachar();
  63415. X        if (ch == ESC) {
  63416. X        return handleesc();
  63417. X        } else {
  63418. X        return translatekey(ch);
  63419. X        }
  63420. X    }
  63421. X
  63422. X    /* Don't check X events every time, since that is expensive */
  63423. X    skipcount++;
  63424. X    if (block==0 && skipcount<25) break;
  63425. X    skipcount = 0;
  63426. X
  63427. X    if (!unixDisk) {
  63428. X        xhandleevents();
  63429. X    }
  63430. X    if (xbufkey) {
  63431. X        ch = xbufkey;
  63432. X        xbufkey = 0;
  63433. X        skipcount = 9999; /* If we got a key, check right away next time */
  63434. X        return translatekey(ch);
  63435. X    }
  63436. X    if (!block) break;
  63437. X    FD_ZERO(&reads);
  63438. X    FD_SET(0,&reads);
  63439. X    if (unixDisk) {
  63440. X        status = select(1,&reads,NULL,NULL,&tout);
  63441. X    } else {
  63442. X        FD_SET(ConnectionNumber(Xdp),&reads);
  63443. X        status = select(ConnectionNumber(Xdp)+1,&reads,NULL,NULL,&tout);
  63444. X    }
  63445. X    if (status<=0) {
  63446. X        return 0;
  63447. X    }
  63448. X    }
  63449. X    return 0;
  63450. X}
  63451. X/*
  63452. X *----------------------------------------------------------------------
  63453. X *
  63454. X * translatekey --
  63455. X *
  63456. X *    Translate an input key into MSDOS format.  The purpose of this
  63457. X *    routine is to do the mappings like U -> PAGE_UP.
  63458. X *
  63459. X * Results:
  63460. X *    New character;
  63461. X *
  63462. X * Side effects:
  63463. X *    None.
  63464. X *
  63465. X *----------------------------------------------------------------------
  63466. X */
  63467. Xstatic int
  63468. Xtranslatekey(ch)
  63469. Xint ch;
  63470. X{
  63471. X    if (ch>='a' && ch<='z') {
  63472. X    return ch;
  63473. X    } else {
  63474. X    switch (ch) {
  63475. X        case 'I':
  63476. X        return INSERT;
  63477. X        case 'D':
  63478. X        return DELETE;
  63479. X        case 'U':
  63480. X        return PAGE_UP;
  63481. X        case 'N':
  63482. X        return PAGE_DOWN;
  63483. X        case CTL('O'):
  63484. X        return CTL_HOME;
  63485. X        case CTL('E'):
  63486. X        return CTL_END;
  63487. X        case 'H':
  63488. X        return LEFT_ARROW;
  63489. X        case 'L':
  63490. X        return RIGHT_ARROW;
  63491. X        case 'K':
  63492. X        return UP_ARROW;
  63493. X        case 'J':
  63494. X        return DOWN_ARROW;
  63495. X        case 1115:
  63496. X        return LEFT_ARROW_2;
  63497. X        case 1116:
  63498. X        return RIGHT_ARROW_2;
  63499. X        case 1141:
  63500. X        return UP_ARROW_2;
  63501. X        case 1145:
  63502. X        return DOWN_ARROW_2;
  63503. X        case 'O':
  63504. X        return HOME;
  63505. X        case 'E':
  63506. X        return END;
  63507. X        case '\n':
  63508. X        return ENTER;
  63509. X        case CTL('T'):
  63510. X        return CTL_ENTER;
  63511. X        case -2:
  63512. X        return CTL_ENTER_2;
  63513. X        case CTL('U'):
  63514. X        return CTL_PAGE_UP;
  63515. X        case CTL('N'):
  63516. X        return CTL_PAGE_DOWN;
  63517. X        case '{':
  63518. X        return CTL_MINUS;
  63519. X        case '}':
  63520. X        return CTL_PLUS;
  63521. X        /* we need ^I for tab */
  63522. X#if 0
  63523. X        case CTL('I'):
  63524. X        return CTL_INSERT;
  63525. X#endif
  63526. X        case CTL('D'):
  63527. X        return CTL_DEL;
  63528. X        case '!':
  63529. X        return F1;
  63530. X        case '@':
  63531. X        return F2;
  63532. X        case '#':
  63533. X        return F3;
  63534. X        case '$':
  63535. X        return F4;
  63536. X        case '%':
  63537. X        return F5;
  63538. X        case '^':
  63539. X        return F6;
  63540. X        case '&':
  63541. X        return F7;
  63542. X        case '*':
  63543. X        return F8;
  63544. X        case '(':
  63545. X        return F9;
  63546. X        case ')':
  63547. X        return F10;
  63548. X        default:
  63549. X        return ch;
  63550. X    }
  63551. X    }
  63552. X}
  63553. X
  63554. X/*
  63555. X *----------------------------------------------------------------------
  63556. X *
  63557. X * handleesc --
  63558. X *
  63559. X *    Handle an escape key.  This may be an escape key sequence
  63560. X *    indicating a function key was pressed.
  63561. X *
  63562. X * Results:
  63563. X *    Key.
  63564. X *
  63565. X * Side effects:
  63566. X *    Reads keys.
  63567. X *
  63568. X *----------------------------------------------------------------------
  63569. X */
  63570. Xstatic int
  63571. Xhandleesc()
  63572. X{
  63573. X    int ch1,ch2,ch3;
  63574. X    if (simple_input) {
  63575. X    return ESC;
  63576. X    }
  63577. X#ifdef __hpux
  63578. X    /* HP escape key sequences. */
  63579. X    ch1 = getachar();
  63580. X    if (ch1==-1) {
  63581. X    delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63582. X    ch1 = getachar();
  63583. X    }
  63584. X    if (ch1==-1) {
  63585. X    return ESC;
  63586. X    }
  63587. X    switch (ch1) {
  63588. X    case 'A':
  63589. X        return UP_ARROW;
  63590. X    case 'B':
  63591. X        return DOWN_ARROW;
  63592. X    case 'D':
  63593. X        return LEFT_ARROW;
  63594. X    case 'C':
  63595. X        return RIGHT_ARROW;
  63596. X    case 'd':
  63597. X        return HOME;
  63598. X    }
  63599. X    if (ch1 != '[') return ESC;
  63600. X    ch1 = getachar();
  63601. X    if (ch1==-1) {
  63602. X    delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63603. X    ch1 = getachar();
  63604. X    }
  63605. X    if (ch1==-1 || !isdigit(ch1)) return ESC;
  63606. X    ch2 = getachar();
  63607. X    if (ch2==-1) {
  63608. X    delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63609. X    ch2 = getachar();
  63610. X    }
  63611. X    if (ch2==-1) return ESC;
  63612. X    if (isdigit(ch2)) {
  63613. X    ch3 = getachar();
  63614. X    if (ch3==-1) {
  63615. X        delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63616. X        ch3 = getachar();
  63617. X    }
  63618. X    if (ch3 != '~') return ESC;
  63619. X    ch2 = (ch2-'0')*10+ch3-'0';
  63620. X    } else if (ch3 != '~') {
  63621. X    return ESC;
  63622. X    } else {
  63623. X    ch2 = ch2-'0';
  63624. X    }
  63625. X    switch (ch2) {
  63626. X    case 5:
  63627. X        return PAGE_UP;
  63628. X    case 6:
  63629. X        return PAGE_DOWN;
  63630. X    case 29:
  63631. X        return F1; /* help */
  63632. X    case 11:
  63633. X        return F1;
  63634. X    case 12:
  63635. X        return F2;
  63636. X    case 13:
  63637. X        return F3;
  63638. X    case 14:
  63639. X        return F4;
  63640. X    case 15:
  63641. X        return F5;
  63642. X    case 17:
  63643. X        return F6;
  63644. X    case 18:
  63645. X        return F7;
  63646. X    case 19:
  63647. X        return F8;
  63648. X    default:
  63649. X        return ESC;
  63650. X    }
  63651. X#else
  63652. X    /* SUN escape key sequences */
  63653. X    ch1 = getachar();
  63654. X    if (ch1==-1) {
  63655. X    delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63656. X    ch1 = getachar();
  63657. X    }
  63658. X    if (ch1 != '[') {        /* See if we have esc [ */
  63659. X    return ESC;
  63660. X    }
  63661. X    ch1 = getachar();
  63662. X    if (ch1==-1) {
  63663. X    delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63664. X    ch1 = getachar();
  63665. X    }
  63666. X    if (ch1==-1) {
  63667. X    return ESC;
  63668. X    }
  63669. X    switch (ch1) {
  63670. X    case 'A':        /* esc [ A */
  63671. X        return UP_ARROW;
  63672. X    case 'B':        /* esc [ B */
  63673. X        return DOWN_ARROW;
  63674. X    case 'C':        /* esc [ C */
  63675. X        return RIGHT_ARROW;
  63676. X    case 'D':        /* esc [ D */
  63677. X        return LEFT_ARROW;
  63678. X    default:
  63679. X        break;
  63680. X    }
  63681. X    ch2 = getachar();
  63682. X    if (ch2==-1) {
  63683. X    delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63684. X    ch2 = getachar();
  63685. X    }
  63686. X    if (ch2 == '~') {        /* esc [ ch1 ~ */
  63687. X    switch (ch1) {
  63688. X        case '2':        /* esc [ 2 ~ */
  63689. X        return INSERT;
  63690. X        case '3':        /* esc [ 3 ~ */
  63691. X        return DELETE;
  63692. X        case '5':        /* esc [ 5 ~ */
  63693. X        return PAGE_UP;
  63694. X        case '6':        /* esc [ 6 ~ */
  63695. X        return PAGE_DOWN;
  63696. X        default:
  63697. X        return ESC;
  63698. X    }
  63699. X    } else if (ch2==-1) {
  63700. X    return ESC;
  63701. X    } else {
  63702. X    ch3 = getachar();
  63703. X    if (ch3==-1) {
  63704. X        delay(250); /* Wait 1/4 sec to see if a control sequence follows */
  63705. X        ch3 = getachar();
  63706. X    }
  63707. X    if (ch3 != '~') {    /* esc [ ch1 ch2 ~ */
  63708. X        return ESC;
  63709. X    }
  63710. X    if (ch1=='1') {
  63711. X        switch (ch2) {
  63712. X        case '1':    /* esc [ 1 1 ~ */
  63713. X            return F1;
  63714. X        case '2':    /* esc [ 1 2 ~ */
  63715. X            return F2;
  63716. X        case '3':    /* esc [ 1 3 ~ */
  63717. X            return F3;
  63718. X        case '4':    /* esc [ 1 4 ~ */
  63719. X            return F4;
  63720. X        case '5':    /* esc [ 1 5 ~ */
  63721. X            return F5;
  63722. X        case '6':    /* esc [ 1 6 ~ */
  63723. X            return F6;
  63724. X        case '7':    /* esc [ 1 7 ~ */
  63725. X            return F7;
  63726. X        case '8':    /* esc [ 1 8 ~ */
  63727. X            return F8;
  63728. X        case '9':    /* esc [ 1 9 ~ */
  63729. X            return F9;
  63730. X        default:
  63731. X            return ESC;
  63732. X        }
  63733. X    } else if (ch1=='2') {
  63734. X        switch (ch2) {
  63735. X        case '0':    /* esc [ 2 0 ~ */
  63736. X            return F10;
  63737. X        case '8':    /* esc [ 2 8 ~ */
  63738. X            return F1;  /* HELP */
  63739. X        default:
  63740. X            return ESC;
  63741. X        }
  63742. X    } else {
  63743. X        return ESC;
  63744. X    }
  63745. X    }
  63746. X#endif
  63747. X}
  63748. X
  63749. X
  63750. Xextern double zwidth, zdepth, zrotate, zskew, zbx, zby, dxsize,dysize;
  63751. Xextern int zoomoff;
  63752. X
  63753. Xextern int editpal_cursor;
  63754. Xextern void Cursor_SetPos();
  63755. X
  63756. Xint XZoomWaiting = 0;
  63757. X
  63758. X#define SENS 1
  63759. X#define ABS(x) ((x)>0?(x):-(x))
  63760. X#define MIN(x,y) ((x)<(y)?(x):(y))
  63761. X#define SIGN(x) ((x)>0?1:-1)
  63762. X
  63763. X/*
  63764. X *----------------------------------------------------------------------
  63765. X *
  63766. X * xhandleevents --
  63767. X *
  63768. X *    Handles X events.
  63769. X *
  63770. X * Results:
  63771. X *    None.
  63772. X *
  63773. X * Side effects:
  63774. X *    Does event action.
  63775. X *
  63776. X *----------------------------------------------------------------------
  63777. X */
  63778. Xstatic int
  63779. Xxhandleevents()
  63780. X{
  63781. X    XEvent xevent;
  63782. X    static ctl_mode = 0;
  63783. X    static shift_mode = 0;
  63784. X    int bandx0,bandy0,bandx1,bandy1;
  63785. X    static int bnum=0;
  63786. X    static int lastx,lasty;
  63787. X    static int dx,dy;
  63788. X
  63789. X    if (doredraw) {
  63790. X    redrawscreen();
  63791. X    }
  63792. X
  63793. X    while (XPending(Xdp) && !xbufkey) {
  63794. X    XNextEvent(Xdp,&xevent);
  63795. X    switch (((XAnyEvent *)&xevent)->type) {
  63796. X        case KeyRelease:
  63797. X        {
  63798. X        char buffer[1];
  63799. X        KeySym keysym;
  63800. X        (void) XLookupString(&xevent,buffer,1,&keysym,NULL);
  63801. X        switch (keysym) {
  63802. X            case XK_Control_L:
  63803. X            case XK_Control_R:
  63804. X            ctl_mode = 0;
  63805. X            break;
  63806. X            case XK_Shift_L:
  63807. X            case XK_Shift_R:
  63808. X            shift_mode = 0;
  63809. X            break;
  63810. X        }
  63811. X        }
  63812. X        break;
  63813. X        case KeyPress:
  63814. X        {
  63815. X        int charcount;
  63816. X        char buffer[1];
  63817. X        KeySym keysym;
  63818. X        int compose;
  63819. X        charcount = XLookupString(&xevent,buffer,1,&keysym,NULL);
  63820. X        switch (keysym) {
  63821. X            case XK_Control_L:
  63822. X            case XK_Control_R:
  63823. X            ctl_mode = 1;
  63824. X            return;
  63825. X            case XK_Shift_L:
  63826. X            case XK_Shift_R:
  63827. X            shift_mode = 1;
  63828. X            break;
  63829. X            case XK_Home:
  63830. X            case XK_R7:
  63831. X            xbufkey = ctl_mode ? CTL_HOME : HOME;
  63832. X            return;
  63833. X            case XK_Left:
  63834. X            case XK_R10:
  63835. X            xbufkey = ctl_mode ? LEFT_ARROW_2 : LEFT_ARROW;
  63836. X            return;
  63837. X            case XK_Right:
  63838. X            case XK_R12:
  63839. X            xbufkey = ctl_mode ? RIGHT_ARROW_2 : RIGHT_ARROW;
  63840. X            return;
  63841. X            case XK_Down:
  63842. X            case XK_R14:
  63843. X            xbufkey = ctl_mode ? DOWN_ARROW_2 : DOWN_ARROW;
  63844. X            return;
  63845. X            case XK_Up:
  63846. X            case XK_R8:
  63847. X            xbufkey = ctl_mode ? UP_ARROW_2 : UP_ARROW;
  63848. X            return;
  63849. X            case XK_Insert:
  63850. X            xbufkey = ctl_mode ? CTL_INSERT : INSERT;
  63851. X            return;
  63852. X            case XK_Delete:
  63853. X            xbufkey = ctl_mode ? CTL_DEL : DELETE;
  63854. X            return;
  63855. X            case XK_End:
  63856. X            case XK_R13:
  63857. X            xbufkey = ctl_mode ? CTL_END : END;
  63858. X            return;
  63859. X            case XK_Help:
  63860. X            xbufkey = F1;
  63861. X            return;
  63862. X            case XK_Prior:
  63863. X            case XK_R9:
  63864. X            xbufkey = ctl_mode ? CTL_PAGE_UP : PAGE_UP;
  63865. X             return;
  63866. X            case XK_Next:
  63867. X            case XK_R15:
  63868. X            xbufkey = ctl_mode ? CTL_PAGE_DOWN : PAGE_DOWN;
  63869. X             return;
  63870. X            case XK_F1:
  63871. X            case XK_L1:
  63872. X            xbufkey = shift_mode ? SF1: F1;
  63873. X            return;
  63874. X            case XK_F2:
  63875. X            case XK_L2:
  63876. X            xbufkey = shift_mode ? SF2: F2;
  63877. X            return;
  63878. X            case XK_F3:
  63879. X            case XK_L3:
  63880. X            xbufkey = shift_mode ? SF3: F3;
  63881. X            return;
  63882. X            case XK_F4:
  63883. X            case XK_L4:
  63884. X            xbufkey = shift_mode ? SF4: F4;
  63885. X            return;
  63886. X            case XK_F5:
  63887. X            case XK_L5:
  63888. X            xbufkey = shift_mode ? SF5: F5;
  63889. X            return;
  63890. X            case XK_F6:
  63891. X            case XK_L6:
  63892. X            xbufkey = shift_mode ? SF6: F6;
  63893. X            return;
  63894. X            case XK_F7:
  63895. X            case XK_L7:
  63896. X            xbufkey = shift_mode ? SF7: F7;
  63897. X            return;
  63898. X            case XK_F8:
  63899. X            case XK_L8:
  63900. X            xbufkey = shift_mode ? SF8: F8;
  63901. X            return;
  63902. X            case XK_F9:
  63903. X            case XK_L9:
  63904. X            xbufkey = shift_mode ? SF9: F9;
  63905. X            return;
  63906. X            case XK_F10:
  63907. X            case XK_L10:
  63908. X            xbufkey = shift_mode ? SF10: F10;
  63909. X            return;
  63910. X            case '+':
  63911. X             xbufkey = ctl_mode ? CTL_PLUS : '+';
  63912. X             return;
  63913. X            case '-':
  63914. X             xbufkey = ctl_mode ? CTL_MINUS : '-';
  63915. X             return;
  63916. X             break;
  63917. X            case XK_Return:
  63918. X            case XK_KP_Enter:
  63919. X             xbufkey = ctl_mode ? CTL('T') : '\n';
  63920. X             return;
  63921. X        }
  63922. X        if (charcount==1) {
  63923. X            xbufkey = buffer[0];
  63924. X            if (xbufkey=='\003') {
  63925. X            goodbye();
  63926. X            }
  63927. X        }
  63928. X        }
  63929. X        break;
  63930. X        case MotionNotify:
  63931. X        {
  63932. X        if (editpal_cursor && !inside_help) {
  63933. X            while ( XCheckWindowEvent(Xdp,Xw,PointerMotionMask,
  63934. X            &xevent)) {}
  63935. X
  63936. X            if (xevent.xmotion.state&Button2Mask ||
  63937. X                (xevent.xmotion.state&Button1Mask &&
  63938. X                xevent.xmotion.state&Button3Mask)) {
  63939. X            bnum = 3;
  63940. X            } else if (xevent.xmotion.state&Button1Mask) {
  63941. X            bnum = 1;
  63942. X            } else if (xevent.xmotion.state&Button3Mask) {
  63943. X            bnum = 2;
  63944. X            } else {
  63945. X            bnum = 0;
  63946. X            }
  63947. X
  63948. X#define MSCALE 1
  63949. X
  63950. X            if (lookatmouse==3 && bnum != 0) {
  63951. X            dx += (xevent.xmotion.x-lastx)/MSCALE;
  63952. X            dy += (xevent.xmotion.y-lasty)/MSCALE;
  63953. X            lastx = xevent.xmotion.x;
  63954. X            lasty = xevent.xmotion.y;
  63955. X            } else {
  63956. X            Cursor_SetPos(xevent.xmotion.x, xevent.xmotion.y);
  63957. X            xbufkey = ENTER;
  63958. X            }
  63959. X
  63960. X        }
  63961. X        }
  63962. X        break;
  63963. X        case ButtonPress:
  63964. X        {
  63965. X        int done = 0;
  63966. X        int banding = 0;
  63967. X        if (lookatmouse==3 || zoomoff == 0) {
  63968. X            lastx = xevent.xbutton.x;
  63969. X            lasty = xevent.xbutton.y;
  63970. X            break;
  63971. X        }
  63972. X        bandx1 = bandx0 = xevent.xbutton.x;
  63973. X        bandy1 = bandy0 = xevent.xbutton.y;
  63974. X        while (!done) {
  63975. X            XNextEvent(Xdp,&xevent);
  63976. X            switch (xevent.type) {
  63977. X            case MotionNotify:
  63978. X            while ( XCheckWindowEvent(Xdp,Xw,PointerMotionMask,
  63979. X                &xevent)) {}
  63980. X            if (banding) {
  63981. X                XDrawRectangle(Xdp,Xw,Xgc,MIN(bandx0,bandx1),
  63982. X                MIN(bandy0,bandy1), ABS(bandx1-bandx0),
  63983. X                ABS(bandy1-bandy0));
  63984. X            }
  63985. X            bandx1 = xevent.xmotion.x;
  63986. X            bandy1 = xevent.xmotion.y;
  63987. X            if (ABS(bandx1-bandx0)*finalaspectratio >
  63988. X                ABS(bandy1-bandy0)) {
  63989. X                bandy1 = SIGN(bandy1-bandy0)*ABS(bandx1-bandx0)*
  63990. X                finalaspectratio + bandy0;
  63991. X            } else {
  63992. X                bandx1 = SIGN(bandx1-bandx0)*ABS(bandy1-bandy0)/
  63993. X                finalaspectratio + bandx0;
  63994. X            }
  63995. X            if (!banding) {
  63996. X                /* Don't start rubber-banding until the mouse
  63997. X                   gets moved.  Otherwise a click messes up the
  63998. X                   window */
  63999. X                if (ABS(bandx1-bandx0)>10 ||
  64000. X                    ABS(bandy1-bandy0)>10) {
  64001. X                banding = 1;
  64002. X                XSetForeground(Xdp, Xgc, colors-1);
  64003. X                XSetFunction(Xdp, Xgc, GXxor);
  64004. X                }
  64005. X            }
  64006. X            if (banding) {
  64007. X                XDrawRectangle(Xdp,Xw,Xgc,MIN(bandx0,bandx1),
  64008. X                MIN(bandy0,bandy1), ABS(bandx1-bandx0),
  64009. X                ABS(bandy1-bandy0));
  64010. X            }
  64011. X            XFlush(Xdp);
  64012. X            break;
  64013. X            case ButtonRelease:
  64014. X            done = 1;
  64015. X            break;
  64016. X            }
  64017. X        }
  64018. X        if (!banding) {
  64019. X            break;
  64020. X        }
  64021. X        XDrawRectangle(Xdp,Xw,Xgc,MIN(bandx0,bandx1),
  64022. X            MIN(bandy0,bandy1), ABS(bandx1-bandx0),
  64023. X            ABS(bandy1-bandy0));
  64024. X        if (bandx1==bandx0) {
  64025. X            bandx1 = bandx0+1;
  64026. X        }
  64027. X        if (bandy1==bandy0) {
  64028. X            bandy1 = bandy0+1;
  64029. X        }
  64030. X        zrotate = 0;
  64031. X        zskew = 0;
  64032. X        zbx = (MIN(bandx0,bandx1)-sxoffs)/dxsize;
  64033. X        zby = (MIN(bandy0,bandy1)-syoffs)/dysize;
  64034. X        zwidth = ABS(bandx1-bandx0)/dxsize;
  64035. X        zdepth = zwidth;
  64036. X        if (!inside_help) {
  64037. X            xbufkey = ENTER;
  64038. X        }
  64039. X        if (xlastcolor != -1) {
  64040. X            XSetForeground(Xdp, Xgc, xlastcolor);
  64041. X        }
  64042. X        XSetFunction(Xdp, Xgc, xlastfcn);
  64043. X        XZoomWaiting = 1;
  64044. X        drawbox(0);
  64045. X        }
  64046. X        break;
  64047. X        case Expose:
  64048. X        if (!doesBacking) {
  64049. X        int x,y,w,h;
  64050. X        x = xevent.xexpose.x;
  64051. X        y = xevent.xexpose.y;
  64052. X        w = xevent.xexpose.width;
  64053. X        h = xevent.xexpose.height;
  64054. X        if (x+w>sxdots) {
  64055. X            w = sxdots-x;
  64056. X        }
  64057. X        if (y+h>sydots) {
  64058. X            h = sydots-y;
  64059. X        }
  64060. X        if (x<sxdots && y<sydots && w>0 && h>0) {
  64061. X
  64062. X            XPutImage(Xdp,Xw,Xgc,Ximage,xevent.xexpose.x,
  64063. X                xevent.xexpose.y, xevent.xexpose.x,
  64064. X                xevent.xexpose.y, xevent.xexpose.width,
  64065. X                xevent.xexpose.height);
  64066. X        }
  64067. X        }
  64068. X        break;
  64069. X    }
  64070. X    }
  64071. X
  64072. X    if (!xbufkey && editpal_cursor && !inside_help && lookatmouse == 3 &&
  64073. X        (dx != 0 || dy != 0)) {
  64074. X    if (ABS(dx)>ABS(dy)) {
  64075. X        if (dx>0) {
  64076. X        xbufkey = mousefkey[bnum][0]; /* right */
  64077. X        dx--;
  64078. X        } else if (dx<0) {
  64079. X        xbufkey = mousefkey[bnum][1]; /* left */
  64080. X        dx++;
  64081. X        }
  64082. X    } else {
  64083. X        if (dy>0) {
  64084. X        xbufkey = mousefkey[bnum][2]; /* down */
  64085. X        dy--;
  64086. X        } else if (dy<0) {
  64087. X        xbufkey = mousefkey[bnum][3]; /* up */
  64088. X        dy++;
  64089. X        }
  64090. X    }
  64091. X    }
  64092. X
  64093. X}
  64094. X
  64095. X#define w_root Xroot
  64096. X#define dpy Xdp
  64097. X#define scr Xdscreen
  64098. X/*
  64099. X *----------------------------------------------------------------------
  64100. X *
  64101. X * pr_dwmroot --
  64102. X *
  64103. X *    Search for a dec window manager root window.
  64104. X *
  64105. X * Results:
  64106. X *    Returns the root window.
  64107. X *
  64108. X * Side effects:
  64109. X *    None.
  64110. X *
  64111. X *----------------------------------------------------------------------
  64112. X */
  64113. Xstatic Window
  64114. Xpr_dwmroot(dpy, pwin)
  64115. XDisplay *dpy;
  64116. XWindow  pwin;
  64117. X{
  64118. X   /* search for DEC Window Manager root */
  64119. X   XWindowAttributes pxwa,cxwa;
  64120. X   Window  root,parent,*child;
  64121. X   unsigned int     i,nchild;
  64122. X
  64123. X    if (!XGetWindowAttributes(dpy,pwin,&pxwa)) {
  64124. X    printf("Search for root: XGetWindowAttributes failed\n");
  64125. X    return RootWindow(dpy, scr);
  64126. X    }
  64127. X    if (XQueryTree(dpy,pwin,&root,&parent,&child,&nchild)) {
  64128. X    for (i = 0; i < nchild; i++) {
  64129. X        if (!XGetWindowAttributes(dpy,child[i],&cxwa)) {
  64130. X        printf("Search for root: XGetWindowAttributes failed\n");
  64131. X        return RootWindow(dpy, scr);
  64132. X        }
  64133. X        if (pxwa.width == cxwa.width && pxwa.height == cxwa.height) {
  64134. X        return(pr_dwmroot(dpy, child[i]));
  64135. X        }
  64136. X    }
  64137. X    return(pwin);
  64138. X    } else {
  64139. X    printf("xfractint: failed to find root window\n");
  64140. X    return RootWindow(dpy, scr);
  64141. X    }
  64142. X}
  64143. X
  64144. X/*
  64145. X *----------------------------------------------------------------------
  64146. X *
  64147. X * FindRootWindow --
  64148. X *
  64149. X *    Find the root or virtual root window.
  64150. X *
  64151. X * Results:
  64152. X *    Returns the root window.
  64153. X *
  64154. X * Side effects:
  64155. X *    None.
  64156. X *
  64157. X *----------------------------------------------------------------------
  64158. X */
  64159. Xstatic Window
  64160. XFindRootWindow()
  64161. X{
  64162. X   int i;
  64163. X   w_root = RootWindow(dpy,scr);
  64164. X   w_root = pr_dwmroot(dpy, w_root); /* search for DEC wm root */
  64165. X
  64166. X{  /* search for swm/tvtwm root (from ssetroot by Tom LaStrange) */
  64167. X   Atom __SWM_VROOT = None;
  64168. X   Window rootReturn, parentReturn, *children;
  64169. X   unsigned int numChildren;
  64170. X
  64171. X   __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);
  64172. X   XQueryTree(dpy, w_root, &rootReturn, &parentReturn, &children, &numChildren);
  64173. X   for (i = 0; i < numChildren; i++) {
  64174. X      Atom actual_type;
  64175. X      int actual_format;
  64176. X      unsigned long nitems, bytesafter;
  64177. X      Window *newRoot = NULL;
  64178. X
  64179. X      if (XGetWindowProperty (dpy, children[i], __SWM_VROOT,(long)0,(long)1,
  64180. X         False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter,
  64181. X         (unsigned char **) &newRoot) == Success && newRoot) {
  64182. X         w_root = *newRoot; break;
  64183. X         }
  64184. X      }
  64185. X   }
  64186. X   return w_root;
  64187. X}
  64188. X
  64189. X/*
  64190. X *----------------------------------------------------------------------
  64191. X *
  64192. X * RemoveRootPixmap --
  64193. X *
  64194. X *    Clean up old pixmap on the root window.
  64195. X *
  64196. X * Results:
  64197. X *    None.
  64198. X *
  64199. X * Side effects:
  64200. X *    Pixmap is cleaned up.
  64201. X *
  64202. X *----------------------------------------------------------------------
  64203. X */
  64204. Xstatic void
  64205. XRemoveRootPixmap()
  64206. X{
  64207. X    Atom prop,type;
  64208. X    int format;
  64209. X    unsigned long nitems,after;
  64210. X    Pixmap *pm;
  64211. X
  64212. X    prop = XInternAtom(Xdp,"_XSETROOT_ID",False);
  64213. X    if (XGetWindowProperty(Xdp,Xroot,prop,(long)0,(long)1,1,AnyPropertyType,
  64214. X        &type, &format, &nitems, &after, (unsigned char **)&pm) ==
  64215. X        Success && nitems == 1) {
  64216. X    if (type==XA_PIXMAP && format==32 && after==0) {
  64217. X        XKillClient(Xdp,(XID)*pm);
  64218. X        XFree((char *)pm);
  64219. X    }
  64220. X    }
  64221. X}
  64222. Xstatic unsigned char *fontPtr = NULL;
  64223. X/*
  64224. X *----------------------------------------------------------------------
  64225. X *
  64226. X * xgetfont --
  64227. X *
  64228. X *    Get an 8x8 font.
  64229. X *
  64230. X * Results:
  64231. X *    Returns a pointer to the bits.
  64232. X *
  64233. X * Side effects:
  64234. X *    None.
  64235. X *
  64236. X *----------------------------------------------------------------------
  64237. X */
  64238. Xunsigned char *
  64239. Xxgetfont()
  64240. X{
  64241. X    XFontStruct *font_info;
  64242. X    Pixmap font_pixmap;
  64243. X    XImage *font_image;
  64244. X    char str[8];
  64245. X    int i,j,k,l;
  64246. X    int width;
  64247. X    fontPtr = (unsigned char *)malloc(128*8);
  64248. X    bzero(fontPtr,128*8);
  64249. X    XSetBackground(Xdp,Xgc,0);
  64250. X    xlastcolor = -1;
  64251. X    XSetForeground(Xdp,Xgc,1);
  64252. X#define FONT "-*-*-medium-r-*-*-9-*-*-*-*-*-iso8859-*"
  64253. X    font_info = XLoadQueryFont(Xdp,FONT);
  64254. X    if (font_info==NULL) {
  64255. X    printf("No %s\n", FONT);
  64256. X    }
  64257. X    if (font_info==NULL || font_info->max_bounds.width>8 ||
  64258. X        font_info->max_bounds.width != font_info->min_bounds.width) {
  64259. X    printf("Bad font: %s\n", FONT);
  64260. X    sleep(2);
  64261. X    font_info = XLoadQueryFont(Xdp,"6x12");
  64262. X    }
  64263. X    if (font_info==NULL) return NULL;
  64264. X    width = font_info->max_bounds.width;
  64265. X    if (font_info->max_bounds.width>8 ||
  64266. X        font_info->max_bounds.width != font_info->min_bounds.width) {
  64267. X    printf("Bad font\n");
  64268. X    return NULL;
  64269. X    }
  64270. X    font_pixmap = XCreatePixmap(Xdp,Xw,64,8,Xdepth);
  64271. X
  64272. X    for (i=0;i<128;i+=8) {
  64273. X    for (j=0;j<8;j++) {
  64274. X        str[j] = i+j;
  64275. X    }
  64276. X    XDrawImageString(Xdp,font_pixmap,Xgc,0,8,str,8);
  64277. X    font_image = XGetImage(Xdp,font_pixmap,0,0,64,8,AllPlanes,XYPixmap);
  64278. X    for (j=0;j<8;j++) {
  64279. X        for (k=0;k<8;k++) {
  64280. X        for (l=0;l<width;l++) {
  64281. X            if (XGetPixel(font_image,j*width+l,k)) {
  64282. X            fontPtr[(i+j)*8+k] = (fontPtr[(i+j)*8+k]<<1)|1;
  64283. X            } else {
  64284. X            fontPtr[(i+j)*8+k] = (fontPtr[(i+j)*8+k]<<1);
  64285. X            }
  64286. X        }
  64287. X        }
  64288. X    }
  64289. X    XDestroyImage(font_image);
  64290. X    }
  64291. X    return fontPtr;
  64292. X}
  64293. X
  64294. X/*
  64295. X *----------------------------------------------------------------------
  64296. X *
  64297. X * shell_to_dos --
  64298. X *
  64299. X *    Exit to a unix shell.
  64300. X *
  64301. X * Results:
  64302. X *    None.
  64303. X *
  64304. X * Side effects:
  64305. X *    Goes to shell
  64306. X *
  64307. X *----------------------------------------------------------------------
  64308. X */
  64309. X#define SHELL "/bin/csh"
  64310. Xvoid
  64311. Xshell_to_dos()
  64312. X{
  64313. X    int (*sigint)();
  64314. X    char *shell;
  64315. X    char *argv[2];
  64316. X    int pid, donepid;
  64317. X
  64318. X    sigint = (int(*)())signal(SIGINT, SIG_IGN);
  64319. X    shell = getenv("SHELL");
  64320. X    if (shell==NULL) {
  64321. X    shell = SHELL;
  64322. X    }
  64323. X    argv[0] = shell;
  64324. X    argv[1] = NULL;
  64325. X
  64326. X    /* Clean up the window */
  64327. X
  64328. X    if (!simple_input) {
  64329. X    fcntl(0,F_SETFL,old_fcntl);
  64330. X    }
  64331. X    mvcur(0,COLS-1, LINES-1,0);
  64332. X    nocbreak();
  64333. X    echo();
  64334. X    endwin();
  64335. X
  64336. X    /* Fork the shell */
  64337. X
  64338. X    pid = fork();
  64339. X    if (pid < 0) {
  64340. X    perror("fork to shell");
  64341. X    }
  64342. X    if (pid==0) {
  64343. X    execvp(shell, argv);
  64344. X    perror("fork to shell");
  64345. X    exit(1);
  64346. X    }
  64347. X
  64348. X    /* Wait for the shell to finish */
  64349. X
  64350. X    while (1) {
  64351. X    donepid = wait(0);
  64352. X    if (donepid<0 || donepid==pid) break;
  64353. X    }
  64354. X
  64355. X    /* Go back to curses mode */
  64356. X
  64357. X    initscr();
  64358. X    curwin = stdscr;
  64359. X    cbreak();
  64360. X    noecho();
  64361. X    if (!simple_input) {
  64362. X    old_fcntl = fcntl(0,F_GETFL);
  64363. X    fcntl(0,F_SETFL,FNDELAY);
  64364. X    }
  64365. X
  64366. X    (void) signal(SIGINT, sigint);
  64367. X    putchar('\n');
  64368. X}
  64369. X
  64370. X/*
  64371. X *----------------------------------------------------------------------
  64372. X *
  64373. X * schedulealarm --
  64374. X *
  64375. X *    Start the refresh alarm
  64376. X *
  64377. X * Results:
  64378. X *    None.
  64379. X *
  64380. X * Side effects:
  64381. X *    Starts the alarm.
  64382. X *
  64383. X *----------------------------------------------------------------------
  64384. X */
  64385. X#define DRAW_INTERVAL 6
  64386. Xvoid
  64387. Xschedulealarm(soon)
  64388. Xint soon;
  64389. X{
  64390. X    if (!fastmode) return;
  64391. X    signal(SIGALRM, setredrawscreen);
  64392. X    if (soon) {
  64393. X    alarm(1);
  64394. X    } else {
  64395. X    alarm(DRAW_INTERVAL);
  64396. X    }
  64397. X    alarmon = 1;
  64398. X}
  64399. X
  64400. X/*
  64401. X *----------------------------------------------------------------------
  64402. X *
  64403. X * setredrawscreen --
  64404. X *
  64405. X *    Set the screen refresh flag
  64406. X *
  64407. X * Results:
  64408. X *    None.
  64409. X *
  64410. X * Side effects:
  64411. X *    Sets the flag.
  64412. X *
  64413. X *----------------------------------------------------------------------
  64414. X */
  64415. Xstatic void
  64416. Xsetredrawscreen()
  64417. X{
  64418. X    doredraw = 1;
  64419. X}
  64420. X
  64421. X/*
  64422. X *----------------------------------------------------------------------
  64423. X *
  64424. X * redrawscreen --
  64425. X *
  64426. X *    Refresh the screen.
  64427. X *
  64428. X * Results:
  64429. X *    None.
  64430. X *
  64431. X * Side effects:
  64432. X *    Redraws the screen.
  64433. X *
  64434. X *----------------------------------------------------------------------
  64435. X */
  64436. Xvoid
  64437. Xredrawscreen()
  64438. X{
  64439. X    if (alarmon) {
  64440. X    XPutImage(Xdp,Xw,Xgc,Ximage,0,0,0,0,sxdots,sydots);
  64441. X    if (onroot) {
  64442. X        XPutImage(Xdp,Xpixmap,Xgc,Ximage,0,0,0,0,sxdots,sydots);
  64443. X    }
  64444. X    alarmon = 0;
  64445. X    }
  64446. X    doredraw = 0;
  64447. X}
  64448. X
  64449. SHAR_EOF
  64450. $TOUCH -am 1028230193 unixscr.c &&
  64451. chmod 0644 unixscr.c ||
  64452. echo "restore of unixscr.c failed"
  64453. set `wc -c unixscr.c`;Wc_c=$1
  64454. if test "$Wc_c" != "46415"; then
  64455.     echo original size 46415, current size $Wc_c
  64456. fi
  64457. # ============= unix.h ==============
  64458. echo "x - extracting unix.h (Text)"
  64459. sed 's/^X//' << 'SHAR_EOF' > unix.h &&
  64460. X/* UNIX.H - unix port declarations */
  64461. X
  64462. X
  64463. X#ifndef _UNIX_H
  64464. X#define _UNIX_H
  64465. X
  64466. X#define far
  64467. X#define cdecl
  64468. X#define huge
  64469. X#define near
  64470. X#ifndef RAND_MAX
  64471. X#define RAND_MAX 0x7fffffff
  64472. X#endif
  64473. X#define O_BINARY 0
  64474. X#ifdef CLK_TCK
  64475. X#undef CLK_TCK
  64476. X#endif
  64477. X#define CLK_TCK 1000
  64478. Xtypedef float FLOAT4;
  64479. Xtypedef short INT2;
  64480. Xtypedef unsigned short UINT2;
  64481. Xtypedef int INT4;
  64482. Xtypedef unsigned int UINT4;
  64483. X#define max(a,b) ((a)>(b)?(a):(b))
  64484. X#define min(a,b) ((a)<(b)?(a):(b))
  64485. X#define remove(x) unlink(x)
  64486. X#define _MAX_FNAME 20
  64487. X#define _MAX_EXT 4
  64488. X#define chsize(fd,len) ftruncate(fd,len)
  64489. X
  64490. X#define inp(x) 0
  64491. X#define outp(x,y)
  64492. X
  64493. X#ifndef labs
  64494. X#define labs(x) ((x)>0?(x):-(x))
  64495. X#endif
  64496. X
  64497. X/* We get a problem with connect, since it is used by X */
  64498. X#define connect connect1
  64499. X/* dysize may conflict with time.h */
  64500. X#define dysize dysize1
  64501. X/* inline is a reserved word */
  64502. X#define inline inline1
  64503. X
  64504. X/* Some stdio.h's don't have this */
  64505. X#ifndef SEEK_SET
  64506. X#define SEEK_SET 0
  64507. X#endif
  64508. X#ifndef SEEK_CUR
  64509. X#define SEEK_CUR 1
  64510. X#endif
  64511. X#ifndef SEEK_END
  64512. X#define SEEK_END 2
  64513. X#endif
  64514. X
  64515. Xextern int iocount;
  64516. X
  64517. Xchar *strlwr(char *s);
  64518. Xchar *strupr(char *s);
  64519. X
  64520. X
  64521. X/* bcopy is probably faster than memmove, memcpy */
  64522. X#define memcpy(dst,src,n) bcopy(src,dst,n)
  64523. X#define memmove(dst,src,n) bcopy(src,dst,n)
  64524. X
  64525. X/*
  64526. X * These defines are so movedata, etc. will work properly, without worrying
  64527. X * about the silly segment stuff.
  64528. X */
  64529. X#define movedata(s_seg,s_off,d_seg,d_off,len) bcopy(s_off,d_off,len)
  64530. Xstruct SREGS {
  64531. X    int ds;
  64532. X};
  64533. X#define FP_SEG(x) 0
  64534. X#define FP_OFF(x) ((char *)(x))
  64535. X#define segread(x)
  64536. X
  64537. X/*
  64538. X * SGI and 386BSD don't have timeb
  64539. X */
  64540. X#ifdef __386BSD__
  64541. X#define FTIME
  64542. X#endif
  64543. X
  64544. X#ifdef SYSVSGI
  64545. X#define FTIME
  64546. Xstruct timeb
  64547. X{
  64548. X        time_t  time;
  64549. X        unsigned short millitm;
  64550. X        int   timezone;
  64551. X        int   dstflag;
  64552. X};
  64553. X#else
  64554. X#ifdef FTIME
  64555. X#include <sys/timeb.h>
  64556. X#endif
  64557. X#endif
  64558. X
  64559. X/* External functions in unixscr.c */
  64560. X
  64561. Xint unixarg(int argc, char **argv, int *i);
  64562. X    /* Parses xfractint-specific command line arguments */
  64563. Xvoid UnixInit(void);
  64564. X    /* initializes curses text window and the signal handlers. */
  64565. Xvoid initUnixWindow(void);
  64566. X    /* initializes the graphics window, colormap, etc. */
  64567. Xvoid UnixDone(void);
  64568. X    /* cleans up X window and curses. */
  64569. Xint startvideo(void);
  64570. X    /* clears the graphics window */
  64571. Xint endvideo(void);
  64572. X    /* just a stub. */
  64573. Xint readvideo(int x, int y);
  64574. X    /* reads a pixel from the screen. */
  64575. Xvoid readvideoline(int y, int x, int lastx, BYTE *pixels);
  64576. X    /* reads a line of pixels from the screen. */
  64577. Xvoid writevideo(int x, int y, int color);
  64578. X    /* writes a pixel to the screen. */
  64579. Xvoid writevideoline(int y, int x, int lastx, BYTE *pixels);
  64580. X    /* writes a line of pixels to the screen. */
  64581. Xint readvideopalette(void);
  64582. X    /* reads the current colormap into dacbox. */
  64583. Xint writevideopalette(void);
  64584. X    /* writes the current colormap from dacbox. */
  64585. Xint resizeWindow(void);
  64586. X    /* Checks if the window has been resized, and handles the resize.  */
  64587. Xint xgetkey(int block);
  64588. X    /* Checks if a key has been pressed. */
  64589. Xunsigned char * xgetfont(void);
  64590. X    /* Returns bitmap of an 8x8 font. */
  64591. Xvoid drawline(int x1, int y1, int x2, int y2);
  64592. X    /* Draws a line from (x1,y1) to (x2,y2). */
  64593. Xvoid setlinemode(int mode);
  64594. X    /* Sets line mode to draw or xor. */
  64595. Xvoid shell_to_dos(void);
  64596. X    /* Calls a Unix subshell. */
  64597. Xvoid xsync(void);
  64598. X    /* Forces all window events to be processed. */
  64599. Xvoid redrawscreen(void);
  64600. X    /* Used with schedulealarm.  Xfractint has a delayed write mode,
  64601. X     * where the screen is updated only every few seconds.
  64602. X     */
  64603. Xvoid schedulealarm(int soon);
  64604. X    /* Schedules the next delayed update. */
  64605. X
  64606. X#endif
  64607. SHAR_EOF
  64608. $TOUCH -am 1028230193 unix.h &&
  64609. chmod 0644 unix.h ||
  64610. echo "restore of unix.h failed"
  64611. set `wc -c unix.h`;Wc_c=$1
  64612. if test "$Wc_c" != "3507"; then
  64613.     echo original size 3507, current size $Wc_c
  64614. fi
  64615. # ============= Makefile ==============
  64616. echo "x - extracting Makefile (Text)"
  64617. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  64618. X#
  64619. X# Makefile for xfractint
  64620. X#
  64621. X
  64622. X# SRCDIR should be a path to the directory that will hold fractint.hlp
  64623. X# You will have to copy fractint.hlp to SRCDIR and make it world readable.
  64624. X# SRCDIR should also hold the .par, .frm, etc. files
  64625. XSRCDIR = /usr/local/bin/X11/fractint
  64626. X# BINDIR is where you put your X11 binaries
  64627. XBINDIR = /usr/local/bin/X11
  64628. X# MANDIR is where you put your chapter 1 man pages
  64629. XMANDIR = /user/local/man/man1
  64630. X
  64631. X#SRCDIR = /users/shirriff/fractfiles
  64632. X#BINDIR = /users/shirriff/fractfiles
  64633. X#MANDIR = /users/shirriff/fractfiles
  64634. X
  64635. XNOBSTRING =
  64636. XHAVESTRI =
  64637. XDEBUG =
  64638. X
  64639. X# For Ultrix, uncomment the NOBSTRING line.
  64640. X# For SunOS, uncomment the NOBSTRING and HAVESTRI lines, so bstring.h will
  64641. X# not be included, and the library stricmp will be used.
  64642. X# For HPUX, uncomment the NOBSTRING line, change the DEFINES line, the CFLAGS
  64643. X# line, the CC line, and the LIBS line.
  64644. X# For AIX or OSF/1, change the DEFINES and LIB lines.
  64645. X# For Apollo, uncomment the NOBSTRING line.  You must also remove the
  64646. X#     source references to unistd.h, malloc.h, and alloc.h.
  64647. X# For 386BSD, uncomment the NOBSTRING line.  Depending on your system, you
  64648. X#     may have to change the "#elif !defined(__386BSD__)" at the top of
  64649. X#     prompts2.c to "#else".
  64650. X#
  64651. X# HPUX fixes thanks to David Allport, Bill Broadley, and R. Lloyd.
  64652. X# AIX fixes thanks to David Sanderson & Elliot Jaffe.
  64653. X# OSF/1 fixes thanks to Ronald Record.
  64654. X# 386BSD fixes thanks to Paul Richards and Andreas Gustafsson.
  64655. X# Apollo fixes thanks to Carl Heidrich
  64656. X# Linux fixes thanks to Darcy Boese
  64657. X# Makefile dependency fixes thanks to Paul Roberts.
  64658. X
  64659. X#DEBUG adds some sanity checking but will slow xfractint down
  64660. X#DEBUG = -DEBUG
  64661. X#NOBSTRING = -DNOBSTRING
  64662. X#HAVESTRI = -DHAVESTRI
  64663. X# If your compiler doesn't handle void *, define -DBADVOID
  64664. X# If you get SIGFPE errors define -DFPUERR
  64665. X# For HPUX, add -DSYS5
  64666. X# and maybe add -DSYSV -D_CLASSIC_ANSI_TYPES
  64667. X# For AIX, add -DNOBSTRING and -DDIRENT
  64668. X# AIX may also need -D_POSIX_SOURCE -D_ALL_SOURCE -D_NONSTD_TYPES
  64669. X# For Dec Alpha, add -DFTIME -DNOBSTRING -DDIRENT
  64670. X# For SGI, you may have to add -DSYSVSGI
  64671. XDEFINES = -DXFRACT $(NOBSTRING) $(HAVESTRI) $(DEBUG)
  64672. X
  64673. X#Maybe -D_CONST will fix problems with constant type in include files?
  64674. X#For HPUX, use CFLAGS = -I. $(DEFINES) -I/usr/include/X11R4 +O3 +Obb1000
  64675. X#For SGI, add -cckr to CFLAGS
  64676. X#For 386BSD, add -I/usr/X386/include to CFLAGS
  64677. X#For Apollo add -I/usr/include/X11 to CFLAGS
  64678. X#Some systems need -static on the CFLAGS.
  64679. X#For Linux, add -DLINUX to CFLAGS
  64680. X
  64681. X#CFLAGS = -I. -D_CONST $(DEFINES)
  64682. XCFLAGS = -I. $(DEFINES)
  64683. X
  64684. X# Gcc is usually the only compiler that works for this
  64685. X# For HPUX, use CC = cc -Aa -D_HPUX_SOURCE
  64686. X# For AIX, maybe use CC = xlc, but other AIX users found cc works, xlc doesn't.
  64687. X# For Apollo use CC = cc -A cpu,mathlib_sr10  -A systype,bsd4.3 
  64688. XCC = gcc
  64689. XCC = cc
  64690. X
  64691. X# For HPUX, use LIBS = -L /usr/lib/X11R4 -lX11 -lm -lcurses -ltermcap
  64692. X# For AIX or OSF/1, add -lbsd
  64693. X# For 386BSD, add -L/usr/X386/lib to LIBS
  64694. X# For Apollo, change -lX11 to -L/usr/X11/libX11
  64695. XLIBS = -lX11 -lm -lcurses -ltermcap
  64696. X
  64697. XOLDSRC = 3d.c calcfrac.c cmdfiles.c decoder.c editpal.c encoder.c f16.c \
  64698. Xfracsubr.c fractalp.c fractals.c fractint.c gifview.c hc.c hcmplx.c \
  64699. Xhelp.c intro.c \
  64700. Xjb.c jiim.c line3d.c loadfdos.c loadfile.c loadmap.c lorenz.c lsys.c \
  64701. Xmiscfrac.c miscovl.c miscres.c mpmath_c.c parser.c parserfp.c plot3d.c \
  64702. Xprinter.c prompts1.c prompts2.c realdos.c rotate.c slideshw.c targa.c \
  64703. Xtestpt.c tgaview.c tp3d.c tplus.c zoom.c fractint.h fractype.h fmath.h port.h \
  64704. Xhelpcom.h helpdefs.h mpmath.h targa.h targa_lc.h tplus.h prototyp.h \
  64705. Xfractsrc.doc debugfla.doc hc.doc
  64706. X
  64707. XNEWSRC = calcmand.c calmanfp.c diskvidu.c fpu087.c fracsuba.c general.c \
  64708. Xprintera.c tplus_a.c video.c unix.c unixscr.c unix.h \
  64709. XMakefile versions
  64710. X
  64711. XHELPFILES = help.src help2.src help3.src help4.src help5.src
  64712. X
  64713. XSRCFILES = $(OLDSRC) $(NEWSRC) $(HELPFILES)
  64714. X
  64715. XPARFILES = cellular.par fractint.par icons.par phoenix.par
  64716. X
  64717. XFRMFILES = fractint.frm
  64718. X
  64719. XIFSFILES = fractint.ifs
  64720. X
  64721. XLFILES = fractint.l penrose.l tiling.l
  64722. X
  64723. XMAPFILES = \
  64724. Xaltern.map blues.map chroma.map default.map firestrm.map froth3.map \
  64725. Xfroth316.map froth6.map froth616.map gamma1.map gamma2.map glasses1.map \
  64726. Xglasses2.map goodega.map green.map grey.map grid.map headache.map \
  64727. Xlandscap.map lyapunov.map neon.map paintjet.map royal.map topo.map \
  64728. Xvolcano.map
  64729. X
  64730. XOLDRUN = $(PARFILES) $(FRMFILES) $(IFSFILES) $(LFILES) \
  64731. X$(MAPFILES) demo.key
  64732. X
  64733. XNEWRUN = fractint0.doc README xfractint.man 
  64734. X
  64735. XNEWFILES = $(NEWSRC) $(NEWRUN)
  64736. X
  64737. XRUNFILES = $(OLDRUN) $(NEWRUN)
  64738. X
  64739. XFILES = $(SRCFILES) $(RUNFILES)
  64740. X
  64741. XOBJS = \
  64742. X3d.o calcfrac.o calcmand.o calmanfp.o cmdfiles.o decoder.o diskvidu.o \
  64743. Xeditpal.o encoder.o f16.o fpu087.o fracsuba.o fracsubr.o fractalp.o \
  64744. Xfractals.o fractint.o general.o gifview.o hcmplx.o help.o intro.o jb.o jiim.o \
  64745. Xline3d.o loadfdos.o loadfile.o loadmap.o lorenz.o lsys.o miscfrac.o miscovl.o \
  64746. Xmiscres.o mpmath_c.o parser.o parserfp.o plot3d.o  printer.o printera.o \
  64747. Xprompts1.o prompts2.o realdos.o rotate.o slideshw.o targa.o testpt.o \
  64748. Xtgaview.o tp3d.o tplus.o tplus_a.o unix.o unixscr.o video.o zoom.o
  64749. X
  64750. XHOBJS = hc.o unix.o
  64751. X
  64752. XHELP = help.src help2.src help3.src help4.src help5.src
  64753. X
  64754. X#Need to prevent lex from doing fractint.l -> fractint.c
  64755. X.SUFFIXES:
  64756. X.SUFFIXES: .o .c .s .h
  64757. X
  64758. Xxfractint: fractint.hlp $(OBJS)
  64759. X    $(CC) -o xfractint $(CFLAGS) $(OBJS) $(LIBS)
  64760. X    strip xfractint
  64761. X
  64762. Xtar:    $(FILES)
  64763. X    tar cfh xfractint.tar $(FILES)
  64764. X
  64765. Xtidy:
  64766. X    rm -f $(OBJS) $(HOBJS)
  64767. X
  64768. Xclean:
  64769. X    rm -f $(OBJS) $(HOBJS) fractint.doc fractint.hlp hc xfractint helpdefs.h
  64770. X
  64771. Xinstall: xfractint fractint.hlp
  64772. X    cp xfractint $(BINDIR)/xfractint
  64773. X    strip $(BINDIR)/xfractint
  64774. X    chmod a+x $(BINDIR)/xfractint
  64775. X    cp fractint.hlp $(PARFILES) $(FRMFILES) $(IFSFILES) $(LFILES) $(MAPFILES) $(SRCDIR)
  64776. X    (cd $(SRCDIR); chmod a+r fractint.hlp $(PARFILES) $(FRMFILES) $(IFSFILES) $(LFILES) $(MAPFILES) )
  64777. X    cp xfractint.man $(MANDIR)/xfractint.1
  64778. X    chmod a+r $(MANDIR)/xfractint.1
  64779. X
  64780. Xfractint.hlp: hc $(HELP)
  64781. X    ./hc /c
  64782. X
  64783. Xmakedoc: doc
  64784. X
  64785. Xfractint.doc: doc
  64786. X
  64787. Xdoc: hc $(HELP)
  64788. X    ./hc /p
  64789. X
  64790. Xhc:    $(HOBJS)
  64791. X    $(CC) -o hc $(CFLAGS) $(HOBJS)
  64792. X
  64793. Xunix.o:    unix.c
  64794. X    $(CC) $(CFLAGS) -DSRCDIR=\"$(SRCDIR)\" -c unix.c
  64795. X
  64796. Xfractint.o: fractint.c
  64797. X    $(CC) $(CFLAGS) -DSRCDIR=\"$(SRCDIR)\" -c fractint.c
  64798. X
  64799. Xhelp.o: help.c
  64800. X    $(CC) $(CFLAGS) -DSRCDIR=\"$(SRCDIR)\" -c help.c
  64801. X
  64802. Xsharsrc:    $(SRCFILES)
  64803. X    shar -s shirriff@sprite.Berkeley.EDU $(SRCFILES) > xfsrc.shar
  64804. X
  64805. Xsharrun:    $(RUNFILES)
  64806. X    shar -s shirriff@sprite.Berkeley.EDU $(RUNFILES) > xfrun.shar
  64807. X
  64808. Xshar:    $(FILES)
  64809. X    shar -s shirriff@sprite.Berkeley.EDU $(FILES) > xfractint.shar
  64810. X
  64811. Xsharc:    $(FILES)
  64812. X    shar -s shirriff@sprite.Berkeley.EDU $(FILES) > xfractint.shar; compress xfractint.shar
  64813. X
  64814. Xshartw: $(OLDSRC) $(HELPFILES)
  64815. X    shar -s shirriff@sprite.Berkeley.EDU $(OLDSRC) $(HELPFILES)> source.tw;compress \
  64816. X    source.tw
  64817. X
  64818. Xcheckout:
  64819. X    co -l -r4.5 -q -f $(FILES)
  64820. X
  64821. Xcheckin: $(OLDRUN) $(OLDSRC)
  64822. X    ci -u -f -r5.2 -m"xfractint 2.1 pre sync" $(FILES)
  64823. X
  64824. Xunlock: $(FILES)
  64825. X    co -u -f $(FILES)
  64826. X
  64827. Xoutdate: $(FILES)
  64828. X    rcs -o3.5 $(FILES)
  64829. X
  64830. Xmerge: $(SRCFILES) $(HELPFILES)
  64831. X    for i in $(SRCFILES) ; do \
  64832. X        rcsmerge -r3.1 -r3.1.1.1 $$i; \
  64833. X    done
  64834. X
  64835. Xtags: $(SRCFILES)
  64836. X    ctags $(SRCFILES)
  64837. X
  64838. Xdiff:
  64839. X    echo "use make -i"; \
  64840. X    for i in $(FILES) ; do \
  64841. X        (diff -c $$i v18 > diffs/$$i; true;); \
  64842. X        true; \
  64843. X    done
  64844. X
  64845. Xcopy: $(FILES)
  64846. X    mv $(FILES) backup
  64847. X
  64848. X
  64849. X# DO NOT DELETE THIS LINE -- make depend depends on it.
  64850. X
  64851. X3d.o: 3d.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64852. X
  64853. Xcalcfrac.o: calcfrac.c fractint.h port.h fractype.h mpmath.h targa_lc.h \
  64854. X            prototyp.h helpcom.h
  64855. X
  64856. Xcalcmand.o: calcmand.c fractint.h port.h
  64857. X
  64858. Xcalmanfp.o: calmanfp.c fractint.h port.h fractype.h
  64859. X
  64860. Xcmdfiles.o: cmdfiles.c fractint.h port.h fractype.h prototyp.h mpmath.h \
  64861. X            helpcom.h
  64862. X
  64863. Xdecoder.o: decoder.c prototyp.h mpmath.h port.h fractint.h helpcom.h
  64864. X
  64865. Xdiskvidu.o: diskvidu.c fractint.h port.h
  64866. X
  64867. Xeditpal.o: editpal.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64868. X
  64869. Xencoder.o: encoder.c fractint.h port.h fractype.h prototyp.h mpmath.h helpcom.h
  64870. X
  64871. Xf16.o: f16.c targa_lc.h prototyp.h mpmath.h port.h fractint.h helpcom.h
  64872. X
  64873. Xfpu087.o: fpu087.c fractint.h port.h mpmath.h
  64874. X
  64875. Xfracsuba.o: fracsuba.c fractint.h port.h
  64876. X
  64877. Xfracsubr.o: fracsubr.c fractint.h port.h fractype.h mpmath.h prototyp.h \
  64878. X            helpcom.h
  64879. X
  64880. Xfractalp.o: fractalp.c fractint.h port.h mpmath.h helpdefs.h fractype.h \
  64881. X            prototyp.h helpcom.h
  64882. X
  64883. Xfractals.o: fractals.c fractint.h port.h mpmath.h helpdefs.h fractype.h \
  64884. X            prototyp.h helpcom.h
  64885. X
  64886. Xfractint.o: fractint.c prototyp.h mpmath.h port.h fractint.h helpcom.h \
  64887. X            fractype.h helpdefs.h
  64888. X
  64889. Xgeneral.o: general.c fractint.h port.h
  64890. X
  64891. Xgifview.o: gifview.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64892. X
  64893. Xhc.o: hc.c helpcom.h port.h
  64894. X
  64895. Xhelp.o: help.c fractint.h port.h helpcom.h helpdefs.h prototyp.h mpmath.h
  64896. X
  64897. Xintro.o: intro.c fractint.h port.h helpdefs.h prototyp.h mpmath.h helpcom.h
  64898. X
  64899. Xjb.o: jb.c fractint.h port.h mpmath.h helpdefs.h prototyp.h helpcom.h
  64900. X
  64901. Xjiim.o: jiim.c helpdefs.h fractint.h port.h fractype.h prototyp.h mpmath.h \
  64902. X        helpcom.h
  64903. X
  64904. Xline3d.o: line3d.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64905. X
  64906. Xloadfdos.o: loadfdos.c fractint.h port.h helpdefs.h prototyp.h mpmath.h \
  64907. X            helpcom.h
  64908. X
  64909. Xloadfile.o: loadfile.c fractint.h port.h fractype.h targa_lc.h prototyp.h \
  64910. X            mpmath.h helpcom.h
  64911. X
  64912. Xloadmap.o: loadmap.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64913. X
  64914. Xlorenz.o: lorenz.c mpmath.h fractint.h port.h fractype.h prototyp.h helpcom.h
  64915. X
  64916. Xlsys.o: lsys.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64917. X
  64918. Xmiscovl.o: miscovl.c fractint.h port.h fractype.h helpdefs.h prototyp.h \
  64919. X            mpmath.h helpcom.h
  64920. X
  64921. Xmiscres.o: miscres.c fractint.h port.h fractype.h helpdefs.h prototyp.h \
  64922. X            mpmath.h helpcom.h
  64923. X
  64924. Xmpmath_c.o: mpmath_c.c mpmath.h prototyp.h port.h fractint.h helpcom.h
  64925. X
  64926. Xparser.o: parser.c mpmath.h prototyp.h port.h fractint.h helpcom.h
  64927. X
  64928. Xplot3d.o: plot3d.c fractint.h port.h fractype.h prototyp.h mpmath.h helpcom.h
  64929. X
  64930. Xprinter.o: printer.c fractint.h port.h fractype.h prototyp.h mpmath.h helpcom.h
  64931. X
  64932. Xprintera.o: printera.c port.h
  64933. X
  64934. Xprompts1.o: prompts1.c fractint.h port.h fractype.h helpdefs.h prototyp.h \
  64935. X            mpmath.h helpcom.h
  64936. X
  64937. Xprompts2.o: prompts2.c fractint.h port.h fractype.h helpdefs.h prototyp.h \
  64938. X            mpmath.h helpcom.h
  64939. X
  64940. Xrealdos.o: realdos.c fractint.h port.h fractype.h helpdefs.h prototyp.h \
  64941. X            mpmath.h helpcom.h
  64942. X
  64943. Xrotate.o: rotate.c fractint.h port.h helpdefs.h prototyp.h mpmath.h helpcom.h
  64944. X
  64945. Xslideshw.o: slideshw.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64946. X
  64947. Xtarga.o: targa.c targa.h fractint.h port.h prototyp.h mpmath.h helpcom.h
  64948. X
  64949. Xtgaview.o: tgaview.c fractint.h port.h targa_lc.h prototyp.h mpmath.h helpcom.h
  64950. X
  64951. Xtp3d.o: tp3d.c mpmath.h fractint.h port.h prototyp.h helpcom.h
  64952. X
  64953. Xtplus.o: tplus.c port.h tplus.h prototyp.h mpmath.h fractint.h helpcom.h
  64954. X
  64955. Xtplus_a.o: tplus_a.c fractint.h port.h
  64956. X
  64957. Xunix.o: unix.c port.h
  64958. X
  64959. Xunixscr.o: unixscr.c fractint.h port.h prototyp.h mpmath.h helpcom.h helpdefs.h
  64960. X
  64961. Xvideo.o: video.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64962. X
  64963. Xzoom.o: zoom.c fractint.h port.h prototyp.h mpmath.h helpcom.h
  64964. SHAR_EOF
  64965. $TOUCH -am 1028230193 Makefile &&
  64966. chmod 0644 Makefile ||
  64967. echo "restore of Makefile failed"
  64968. set `wc -c Makefile`;Wc_c=$1
  64969. if test "$Wc_c" != "10830"; then
  64970.     echo original size 10830, current size $Wc_c
  64971. fi
  64972. # ============= versions ==============
  64973. echo "x - extracting versions (Text)"
  64974. sed 's/^X//' << 'SHAR_EOF' > versions &&
  64975. XREVISION INFORMATION:
  64976. X
  64977. XVersion 0.01: (Jan 3, 1992)
  64978. X    Initial version.  Some fractals work.
  64979. XVersion 0.03: (Jan 4, 1992)
  64980. X    Most fractals work.
  64981. X    Handles colors better.
  64982. XVersion 0.04:
  64983. X    Has working zoom box, lsys.
  64984. XVersion 0.05:
  64985. X    Routines to get a pixel and write a line of pixels implemented.
  64986. X    Has working diffusion, region guessing.
  64987. X    GIF save works.
  64988. X    MP math routines work(?).
  64989. X    Boundary trace works.
  64990. XVersion 0.06:
  64991. X    Log colormaps work
  64992. X    X cursor keys work.
  64993. XVersion 0.07: (Jan 9, 1992)
  64994. X    File input screens work.
  64995. X    Sun cursor keys work in text window.
  64996. X    Fixed rand().
  64997. X    Plasma works.
  64998. X    Ifs fractals work.
  64999. X    Man page included.
  65000. XVersion 0.08:
  65001. X    Compilation problems with SunOS fixed (I hope).
  65002. X    Got root window drawing working, colormap sharing, private colormap.
  65003. X    Got printer support working.
  65004. X    Palette editing works.
  65005. X    Control-cursor works.
  65006. X    GIF read works.
  65007. X    3d display works.
  65008. XVersion 1.00: (Feb 6, 1992)
  65009. X    Updated to fractint 17.00.
  65010. XVersion 1.01: (May 16, 1992)
  65011. X    GIF89a read and write works.
  65012. X    hc problems fixed: many thanks to Roberto Flor and Thomas Winder.
  65013. X    Mouse support for zoom boxes and palette editor.
  65014. X    New feature: use periodicity as an inside method.
  65015. X    Corner selection works.
  65016. X    Default color map changed so bifurcation, ifs, lsystem show up better.
  65017. X    Fixed bug with bifurcation pixel row.
  65018. X    Fixed bug with manzpower: incorrect if real=2, imag != 0
  65019. X    Fixed problem with ^D's killing shell when exiting xfractint.
  65020. X    No longer prints to column 80, which messed up some displays.
  65021. XVersion 1.02: (May 17, 1992)
  65022. X    Fixed problem with help on Suns.
  65023. XVersion 1.03: (June 11, 1992)
  65024. X    Fixed problem with loading gifs on Suns.
  65025. X    Fixed problems with @ and tab keys.
  65026. X    Added shell to dos.
  65027. X    Added floating point Mandelbrot computation.
  65028. X    Added -fast flag for faster X-windows drawing.
  65029. X    Added HPUX flags to Makefile.
  65030. X    Added window resizing.
  65031. X    Changed default colormap again.
  65032. X    Got disk video working.
  65033. X    Added -slowdisplay flag to prevent xfractint from hanging on slow displays.
  65034. X    Added compressed PostScript output.
  65035. X    Added dithered GIF reads.
  65036. XVersion 1.04: (July 9, 1992)
  65037. X    Merged with fractint 17.25.
  65038. X    Added quaternions.
  65039. X    Added dynamic systems.
  65040. X    Added cellular automata.
  65041. X    Added floating point julibrot.
  65042. X    Added gamma to palette editor.
  65043. X    Added command string specification during execution.
  65044. X    Always set floating point flag and removed unused MP floating point code.
  65045. X    Improved ifs editing.
  65046. X    Fixed problem with potential and < 256 colors.
  65047. X    Fixed complexnewton and newtbasin.
  65048. X    Fixed a bug in helpcom.h with formatting of links.
  65049. X    Allow 256 entry map files, even with < 256 colors.
  65050. X    Added integer restriction to parameter entry.
  65051. XVersion 1.05 (July 13, 1992)
  65052. X    Fixed problems with include files and type declarations.
  65053. X    Sped up negative powers.
  65054. XVersion 1.06 (Sept 24, 1992)
  65055. X    Merged with latest fractint (17.27).
  65056. X    Added attractor basin phase plotting for Julia sets.
  65057. X    Improved finite attractor code to find more attractors.
  65058. X    Added (untested) make install option.
  65059. X    Added mandelcloud type.
  65060. XVersion 1.07: (Nov 1, 1992)
  65061. X    Merged with latest fractint (17.29).
  65062. X    Added many more .map, .par files, thanks to Dan Goldwater.
  65063. X    Fixed segfault in postscript printing.
  65064. X    Fixed disk video size selection.
  65065. X    Fixed color printing.
  65066. XVersion 1.08: (Nov 2, 1992)
  65067. X    Fixed some definitions.
  65068. XVersion 1.09:
  65069. X    Got batch mode working.
  65070. X    Added support for xfractint library directory (setenv FRACTDIR).
  65071. X    Merged with fractint17.31
  65072. X    Has device-resolution postscript.
  65073. X    Makefile improvements.
  65074. X    Added still more .map, .par, etc. files, thanks to Dan Goldwater.
  65075. X    Fixed a hc.c wordsize problem (thanks to David Gibson).
  65076. XVersion 2.00: (June 5, 1993)
  65077. X    Merged with fractint 18.00.
  65078. XVersion 2.01: (June 11, 1993)
  65079. X    Fixed gamma conflict.
  65080. XVersion 2.02: (July 28, 1993)
  65081. X    Fixed Makefile for Linux (thanks to Darcy Boese)
  65082. X    Synced with fractint 18.1
  65083. X    Made changes so xfractint will work on 64-bit Alphas.
  65084. XVersion 2.03 (Oct 9, 1993)
  65085. X    Synced with fractint 18.2
  65086. XVersion 2.04 (Oct 28, 1993)
  65087. X    CD-ROM release.  Contains cursor fix for JIIM.
  65088. SHAR_EOF
  65089. $TOUCH -am 1028230193 versions &&
  65090. chmod 0644 versions ||
  65091. echo "restore of versions failed"
  65092. set `wc -c versions`;Wc_c=$1
  65093. if test "$Wc_c" != "4195"; then
  65094.     echo original size 4195, current size $Wc_c
  65095. fi
  65096. # ============= help.src ==============
  65097. echo "x - extracting help.src (Text)"
  65098. sed 's/^X//' << 'SHAR_EOF' > help.src &&
  65099. X;
  65100. X; HELP.SRC
  65101. X;
  65102. X;
  65103. X~HdrFile=HELPDEFS.H
  65104. X~HlpFile=FRACTINT.HLP
  65105. X~Version=100
  65106. X~FormatExclude=8
  65107. X;
  65108. X;
  65109. X;
  65110. X~Topic=Main Help Index, Label=HELPMENU
  65111. X~Label=HELP_INDEX
  65112. X
  65113. X~Format-
  65114. X   { Using Help }                { Fractals and the PC }
  65115. X   { Introduction }                { Distribution of Fractint }
  65116. X   { Conditions on Use }            { Contacting the Authors }
  65117. X   { Getting Started }                { The Stone Soup Story }
  65118. X   { New Features in Version 18.2 }        { A Word About the Authors }
  65119. X                      { Other Fractal Products }
  65120. X   { Display Mode Commands }            { Fractint on Unix }
  65121. X   { Color Cycling Commands }            { Using Fractint With a Mouse }
  65122. X   { Palette Editing Commands }         { Video Adapter Notes }
  65123. X                      { GIF Save File Format }
  65124. X   { Summary of Fractal Types }
  65125. X                      { Common Problems }
  65126. X   { Doodads\, Bells\, and Whistles }
  65127. X   { "3D" Images }                          { Bibliography }
  65128. X   { Palette Maps }                { Other Programs }
  65129. X                      { Revision History }
  65130. X   { Startup Parameters\, Parameter Files }  { Version13 to 14 Conversion }
  65131. X   { Batch Mode }
  65132. X   { "Disk-Video" Modes }                   { Printing Fractint Documentation }
  65133. X~Format+
  65134. X;
  65135. X;
  65136. X;
  65137. X~DocContents
  65138. X{     , 0, "New Features in Version 18.2", FF}
  65139. X
  65140. X{     , 0, "Introduction", "Conditions on Use", FF}
  65141. X
  65142. X{1.   , 0, Fractint Commands, FF}
  65143. X{1.1  , 1, "Getting Started"}
  65144. X{1.2  , 1, "Plotting Commands"}
  65145. X{1.3  , 1, "Zoom box Commands"}
  65146. X{1.4  , 1, "Color Cycling Commands"}
  65147. X{1.5  , 1, "Palette Editing Commands"}
  65148. X{1.6  , 1, "Image Save/Restore Commands"}
  65149. X{1.7  , 1, "Print Command"}
  65150. X{1.8  , 1, "Parameter Save/Restore Commands"}
  65151. X{1.9  , 1, "\"3D\" Commands"}
  65152. X{1.10 , 1, "Interrupting and Resuming"}
  65153. X{1.11 , 1, "Orbits Window"}
  65154. X{1.12 , 1, "View Window"}
  65155. X{1.13 , 1, "Video Mode Function Keys"}
  65156. X{1.14 , 1, "Hints"}
  65157. X{1.15 , 1, "Fractint on Unix"}
  65158. X
  65159. X{2.   , 0, "Fractal Types", FF}
  65160. X{2.1  , 1, "The Mandelbrot Set"}
  65161. X{2.2  , 1, "Julia Sets"}
  65162. X{2.3  , 1, "Julia Toggle Spacebar Commands"}
  65163. X{2.4  , 1, "Inverse Julias"}
  65164. X{2.5  , 1, "Newton domains of attraction"}
  65165. X{2.6  , 1, "Newton"}
  65166. X{2.7  , 1, "Complex Newton"}
  65167. X{2.8  , 1, "Lambda Sets"}
  65168. X{2.9  , 1, "Mandellambda Sets"}
  65169. X{2.10 , 1, "Circle"}
  65170. X{2.11 , 1, "Plasma Clouds"}
  65171. X{2.12 , 1, "Lambdafn"}
  65172. X{2.13 , 1, "Mandelfn"}
  65173. X{2.14 , 1, "Barnsley Mandelbrot/Julia Sets"}
  65174. X{2.15 , 1, "Barnsley IFS Fractals"}
  65175. X{2.16 , 1, "Sierpinski Gasket"}
  65176. X{2.17 , 1, "Quartic Mandelbrot/Julia"}
  65177. X{2.18 , 1, "Distance Estimator"}
  65178. X{2.19 , 1, "Pickover Mandelbrot/Julia Types"}
  65179. X{2.20 , 1, "Pickover Popcorn"}
  65180. X{2.21 , 1, "Peterson Variations"}
  65181. X{2.22 , 1, "Unity"}
  65182. X{2.23 , 1, "Scott Taylor / Lee Skinner Variations"}
  65183. X{2.24 , 1, "Kam Torus"}
  65184. X{2.25 , 1, "Bifurcation"}
  65185. X{2.26 , 1, "Orbit Fractals"}
  65186. X{2.27 , 1, "Lorenz Attractors"}
  65187. X{2.28 , 1, "Rossler Attractors"}
  65188. X{2.29 , 1, "Henon Attractors"}
  65189. X{2.30 , 1, "Pickover Attractors"}
  65190. X{2.31 , 1, "Gingerbreadman"}
  65191. X{2.32 , 1, "Martin Attractors"}
  65192. X{2.33 , 1, "Icon"}
  65193. X{2.34 , 1, "Test"}
  65194. X{2.35 , 1, "Formula"}
  65195. X{2.36 , 1, "Julibrots"}
  65196. X{2.37 , 1, "Diffusion Limited Aggregation"}
  65197. X{2.38 , 1, "Magnetic Fractals"}
  65198. X{2.39 , 1, "L-Systems"}
  65199. X{2.40 , 1, "Lyapunov Fractals"}
  65200. X{2.41 , 1, "fn||fn Fractals"}
  65201. X{2.42 , 1, "Halley"}
  65202. X{2.43 , 1, "Dynamic System"}
  65203. X{2.44 , 1, "Mandelcloud"}
  65204. X{2.45 , 1, "Quaternion"}
  65205. X{2.46 , 1, "HyperComplex"}
  65206. X{2.47 , 1, "Cellular Automata"}
  65207. X{2.48 , 1, "Phoenix"}
  65208. X{2.49 , 1, "Frothy Basins"}
  65209. X
  65210. X{3.   , 0, Doodads\, Bells\, and Whistles, FF}
  65211. X{3.1  , 1, "Drawing Method"}
  65212. X{3.2  , 1, "Palette Maps"}
  65213. X{3.3  , 1, "Autokey Mode"}
  65214. X{3.4  , 1, "Distance Estimator Method"}
  65215. X{3.5  , 1, "Inversion"}
  65216. X{3.6  , 1, "Decomposition"}
  65217. X{3.7  , 1, "Logarithmic Palettes and Color Ranges"}
  65218. X{3.8  , 1, "Biomorphs"}
  65219. X{3.9  , 1, "Continuous Potential"}
  65220. X{3.10 , 1, "Starfields"}
  65221. X
  65222. X{4.   , 0, "\"3D\" Images", "3D Overview", FF}
  65223. X{4.1  , 1, "3D Mode Selection"}
  65224. X{4.2  , 1, "Select Fill Type Screen"}
  65225. X{4.3  , 1, "Stereo 3D Viewing"}
  65226. X{4.4  , 1, "Rectangular Coordinate Transformation"}
  65227. X{4.5  , 1, "3D Color Parameters"}
  65228. X{4.6  , 1, "Light Source Parameters"}
  65229. X{4.7  , 1, "Spherical Projection"}
  65230. X{4.8  , 1, "3D Overlay Mode"}
  65231. X{4.9  , 1, "Special Note for CGA or Hercules Users"}
  65232. X{4.10 , 1, "Making Terrains"}
  65233. X{4.11 , 1, "Making 3D Slides"}
  65234. X{4.12 , 1, "Interfacing with Ray Tracing Programs"}
  65235. X
  65236. X{5.   , 0, Command Line Parameters\, Parameter Files\, Batch Mode, "Introduction to Parameters", FF}
  65237. X{5.1  , 1, "Using the DOS Command Line"}
  65238. X{5.2  , 1, "Setting Defaults (SSTOOLS.INI File)"}
  65239. X{5.3  , 1, "Parameter Files and the <@> Command"}
  65240. X{5.4  , 1, "General Parameter Syntax"}
  65241. X{5.5  , 1, "Startup Parameters"}
  65242. X{5.6  , 1, "Calculation Mode Parameters"}
  65243. X{5.7  , 1, "Fractal Type Parameters"}
  65244. X{5.8  , 1, "Image Calculation Parameters"}
  65245. X{5.9  , 1, "Color Parameters"}
  65246. X{5.10 , 1, "Doodad Parameters"}
  65247. X{5.11 , 1, "File Parameters"}
  65248. X{5.12 , 1, "Video Parameters"}
  65249. X{5.13 , 1, "Sound Parameters"}
  65250. X{5.14 , 1, "Printer Parameters"}
  65251. X{5.15 , 1, "PostScript Parameters"}
  65252. X{5.16 , 1, "PaintJet Parameters"}
  65253. X{5.17 , 1, "Plotter Parameters"}
  65254. X{5.18 , 1, "3D Parameters"}
  65255. X{5.19 , 1, "Batch Mode"}
  65256. X
  65257. X{6.   , 0, Hardware Support, FF}
  65258. X{6.1  , 1, Notes on Video Modes\, \"Standard\" and Otherwise,
  65259. X            "Video Adapter Notes", "EGA", "Tweaked VGA", "Super-VGA",
  65260. X            "8514/A", "XGA", "Targa", "Targa+"}
  65261. X{6.2  , 1, "\"Disk-Video\" Modes"}
  65262. X{6.3  , 1, "Customized Video Modes\, FRACTINT.CFG"}
  65263. X
  65264. X{7.   , 0, "Common Problems", FF}
  65265. X
  65266. X{8.   , 0, "Fractals and the PC", FF}
  65267. X{8.1  , 1, A Little History}
  65268. X{8.1.1, 2, "Before Mandelbrot"}
  65269. X{8.1.2, 2, "Who Is This Guy\, Anyway?"}
  65270. X{8.2  , 1, A Little Code}
  65271. X{8.2.1, 2, "Periodicity Logic"}
  65272. X{8.2.2, 2, "Limitations of Integer Math (And How We Cope)"}
  65273. X{8.2.3, 2, "The Fractint \"Fractal Engine\" Architecture"}
  65274. X
  65275. X{Appendix A, 0, Mathematics of the Fractal Types,
  65276. X           "Summary of Fractal Types",
  65277. X           "Inside=bof60|bof61|zmag|period",
  65278. X           "Inside=epscross|startrail",
  65279. X           "Finite Attractors",
  65280. X           "Trig Identities", FF}
  65281. X
  65282. X{Appendix B, 0, Stone Soup With Pixels: The Authors,
  65283. X           "The Stone Soup Story",
  65284. X           "A Word About the Authors",
  65285. X           "Distribution of Fractint",
  65286. X           "Contacting the Authors", FF}
  65287. X
  65288. X{Appendix C, 0, "GIF Save File Format", FF}
  65289. X
  65290. X{Appendix D, 0, Other Fractal Products, FF}
  65291. X
  65292. X{Appendix E, 0, "Bibliography", FF}
  65293. X
  65294. X{Appendix F, 0, "Other Programs", FF}
  65295. X
  65296. X{Appendix G, 0, Revision History,
  65297. X           "Version 17",
  65298. X           "Version 16",
  65299. X           "Version 15",
  65300. X           "Versions 12 through 14",
  65301. X           "Versions  1 through 11",
  65302. X           FF}
  65303. X
  65304. X{Appendix H, 0, Version13 to Version 14 Type Mapping, "Version13 to 14 Conversion", FF}
  65305. X;
  65306. X; End of DoContents
  65307. X;
  65308. X;
  65309. X;
  65310. X~Topic=Using Help
  65311. X; This topic is online only.
  65312. X
  65313. XUse the following keys in help mode:
  65314. X
  65315. X   F1           Go to the main help index.
  65316. X
  65317. X   PgDn/PgUp       Go to the next/previous page.
  65318. X
  65319. X   Backspace       Go to the previous topic.
  65320. X
  65321. X   Escape       Exit help mode.
  65322. X
  65323. X   Enter       Select (go to) highlighted hot-link.
  65324. X
  65325. X   Tab/Shift-Tab   Move to the next/previous hot-link.
  65326. X
  65327. X   \24 \25 \27 \26       Move to a hot-link.
  65328. X
  65329. X   Home/End       Move to the first/last hot-link.
  65330. X;
  65331. X;
  65332. X;
  65333. X~Topic=Printing Fractint Documentation
  65334. X
  65335. XYou can generate a text file containing full Fractint documentation by
  65336. Xselecting the "Generate FRACTINT.DOC now" hot-link below and pressing
  65337. XEnter, or by using the DOS command "fractint makedoc=filename" ("filename"
  65338. Xis the name of the file to be written; it defaults to FRACTINT.DOC.)
  65339. X
  65340. XAll information in the documentation file is also available in the online
  65341. Xhelp, so extracting it is a matter of preference - you can print the
  65342. Xfile (e.g.  DOS command "print fractint.doc" or "copy fractint.doc prn")
  65343. Xor read it with a text editor.    It contains over 100 pages of information,
  65344. Xhas a table of contents, and is cross-referenced by page number.
  65345. X
  65346. X  {=-101 Exit without generating FRACTINT.DOC}
  65347. X
  65348. X  {=-100 Generate FRACTINT.DOC now}
  65349. X
  65350. XFractint's great (and unique as far as we know) online help and integrated
  65351. Xdocumentation file software was written by Ethan Nagel.
  65352. X;
  65353. X;
  65354. X;
  65355. X~Topic=New Features in Version 18.2
  65356. XVersions 18.1 and 18.2 are bug-fix releases for version 18.0.  Changes from
  65357. X18.1 to 18.2 include:
  65358. X
  65359. X The <b> command now causes filenames only to be written in PAR files.
  65360. X
  65361. X Fractint will now search directories in the PATH for files not found in the 
  65362. X requested the requested directory or the current directory. If you place 
  65363. X .MAP, .FRM, etc. in directories in your PATH, then Fractint will find them.
  65364. X
  65365. X Fixed bug that caused fractals using PI symmetry to fail at high resolution.
  65366. X
  65367. X Fractals interrupted with <3> or <r> can now resume.
  65368. X
  65369. X The palette editor's <u> (undo) now works.
  65370. X
  65371. X The <s> command in orbit/Julia window mode is no longer case sensitive.
  65372. X
  65373. X Added warnings that the POV-Ray output is obsolete (but has been left in).
  65374. X Use POV-Ray's height field facility instead or create and convert RAW files.
  65375. X
  65376. X Fixed several IFS bugs.
  65377. X
  65378. XChanges from 18.0 to 18.1 include:
  65379. X
  65380. X Overlay tuning - the Mandelbrot/Julia Set fractals are now back up
  65381. X to 17.x speeds
  65382. X
  65383. X Disk Video modes now work correctly with VESA video adapters (they
  65384. X used to use the same array for different purposes, confusing each other)
  65385. X
  65386. X 1024x768x256 and 2048x2048x256 disk video modes work again
  65387. X
  65388. X Parameter-file processing no longer crashes Fractint if it attempts to
  65389. X run a formula requiring access to a non-existent FRM file
  65390. X
  65391. X IFS arrays no longer overrun their array space
  65392. X
  65393. X type=cellular fixes
  65394. X
  65395. X "autologmap=2" now correctly picks up the minimum color
  65396. X
  65397. X The use of disk-video mode with random-access fractal types is now
  65398. X legal (it generates a warning message but lets you proceed if you
  65399. X really want to)
  65400. X
  65401. X The Lsystems "spinning-wheel" now spins slower (removing needless overhead)
  65402. X
  65403. X Changes to contributors' addresses in the Help screens
  65404. X
  65405. X(The remainder of this "new features" section is from version 18.0)
  65406. X
  65407. XNew fractal types:
  65408. X
  65409. X 19 new fractal types, including:
  65410. X
  65411. X New fractal types - 'lambda(fn||fn)', 'julia(fn||fn)', 'manlam(fn||fn)',
  65412. X 'mandel(fn||fn)', 'halley', 'phoenix', 'mandphoenix', 'cellular',
  65413. X generalized bifurcation, and 'bifmay' - from Jonathan Osuch.
  65414. X
  65415. X New Mandelcloud, Quaternion, Dynamic System, Cellular Automata fractal
  65416. X types from Ken Shirriff.
  65417. X
  65418. X New HyperComplex fractal types from Timothy Wegner
  65419. X
  65420. X New ICON type from Dan Farmer, including a PAR file of examples.
  65421. X
  65422. X New Frothy Basin fractal types (and PAR entries) by Wesley Loewer
  65423. X
  65424. X MIIM (Modified Inverse Iteration Method) implementation of Inverse Julia
  65425. X from Michael Snyder.
  65426. X
  65427. X New Inverse Julia fractal type from Juan Buhler.
  65428. X
  65429. X New floating-point versions of Markslambda, Marksmandel, Mandel4,
  65430. X and Julia4 types (chosen automatically if the floating-point option
  65431. X is enabled).
  65432. X
  65433. XNew options/features:
  65434. X
  65435. X New assembler-based parser logic from Chuck Ebbert - significantly
  65436. X faster than the C-based code it replaces!
  65437. X
  65438. X New assembler-based Lyapunov logic from Nicholas Wilt and Wes Loewer.
  65439. X Roughly six times faster than the old version!
  65440. X
  65441. X New Orbits-on-a-window / Julia-in-a-window options:\
  65442. X  1) The old Overlay option is now '#' (Shift-3).\
  65443. X  2) During generation, 'O' brings up orbits (as before) - after\
  65444. X     generation, 'O' brings up new orbits Windows mode.\
  65445. X  3) Control-O brings up new orbits Windows mode at any time.\
  65446. X  4) Spacebar toggles between Inverse Julia mode and the Julia set and\
  65447. X     back to the Mandelbrot set.\
  65448. X These new "in-a-window" modes are really neat!  See {Orbits Window}
  65449. X and {Julia Toggle Spacebar Commands} for details.
  65450. X
  65451. X New multi-image GIF support in the <B> command.  You can now generate
  65452. X 65535x65535x256 fractal images using Fractint (if you have the disk
  65453. X space, of course).  This option builds special PAR entries and a
  65454. X MAKEMIG.BAT file that you later use to invoke Fractint multiple times
  65455. X to generate individual sections of the image and (in a final step)
  65456. X stitch them all together.  If your other software can't handle
  65457. X Multiple-image GIFs, a SIMPLGIF program is also supplied that converts
  65458. X MIGS into simgle-image GIFs.  Press F1 at the <B> prompts screen for
  65459. X details.
  65460. X
  65461. X Fractint's decoder now handles Multi-Image Gifs.
  65462. X
  65463. X New SuperVGA/VESA Autodetect logic from the latest version of
  65464. X VGAKIT.  Sure hope we didn't break anything.
  65465. X
  65466. X New register-compatible 8514/A code from Jonathan Osuch.  By default,
  65467. X Fractint now looks first for the presence of an 8514/A register-compatible
  65468. X adapter and then (and only if it doesn't find one) the presence of the
  65469. X 8514/A API (IE, HDILOAD is no longer necessary for register-compatible
  65470. X "8514/a" adapters).  Fractint can be forced to use the 8514/A API by using
  65471. X a new command-line option, "afi=yes".  Jonathan also added ATI's
  65472. X "8514/a-style" 800x600x256 and 1280x1024x16 modes.
  65473. X
  65474. X New XGA-detection logic for ISA-based XGA-2 systems.
  65475. X
  65476. X The palette editor now has a "freestyle" editing option.  See
  65477. X {Palette Editing Commands} for details.
  65478. X
  65479. X
  65480. X Fractint is now more "batch file" friendly.  When running Fractint from
  65481. X a batch file, pressing any key will cause Fractint to exit with an
  65482. X errorlevel = 2.  Any error that interrupts an image save to disk will
  65483. X cause an exit with errorlevel = 2.  Any error that prevents an
  65484. X image from being generated will cause an exit with errorlevel = 1.
  65485. X
  65486. X New Control-X, Control-Y, and Control-Z options flip a fractal image
  65487. X along the X-axis, Y-axis, and Origin, respectively.
  65488. X
  65489. X New area calculation mode in TAB screen from Ken Shirriff 
  65490. X (for accuracy use inside=0).
  65491. X The TAB screen now indicates when the Integer Math algorithms are in use.
  65492. X
  65493. X The palette must now be explicitly changed, it will not reset to the default
  65494. X unexpectedly when doing things like switching video modes.
  65495. X The Julibrot type has been generalized.
  65496. X Julibrot fractals can now be generated from PAR files.
  65497. X
  65498. X Added <b> command support for viewwindows. 
  65499. X
  65500. X Added room for two additional PAR comments in the <B> command
  65501. X
  65502. X New coloring method for IFS shows which parts of fractal came from
  65503. X which transform.
  65504. X
  65505. X Added attractor basin phase plotting for Julia sets from Ken Shirriff.
  65506. X
  65507. X Improved finite attractor code to find more attractors from Ken Shirriff.
  65508. X
  65509. X New zero function, to be used in PAR files to replace old integer tan, tanh
  65510. X
  65511. X Debugflag=10000 now reports video chipset in use as well as CPU/FPU
  65512. X type and available memory
  65513. X
  65514. X Added 6 additional parameters for params= for those fractal types that
  65515. X need them.
  65516. X
  65517. X New 'matherr()' logic lets Fractint get more aggressive when these errors
  65518. X happen.
  65519. X
  65520. X New autologmap option (log=+-2) from Robin Bussell that ensures that
  65521. X all palette values are used by searching the screen border for the lowest
  65522. X value and then setting log= to +- that color.
  65523. X
  65524. X Two new diffusion options - falling and square cavity.
  65525. X
  65526. X Three new Editpal commands: '!', '@' and '#' commands (that's
  65527. X <shift-1>, <shift-2>, and <shift-3>) to swap R<->G, G<->B, R<->B.
  65528. X
  65529. X Parameter files now use a slightly shorter maximum line length, making
  65530. X them a bit more readable when stuffed into messages on Compuserve.
  65531. X
  65532. X Plasma now has 16-bit .POT output for use with Ray tracers. The "old"
  65533. X algorithm has been modified so that the plasma effect is independent
  65534. X of resolution.
  65535. X
  65536. X Slight modification to the Raytrace code to make it compatible with
  65537. X Rayshade 4.0 patch level 6.
  65538. X
  65539. X Improved boundary-tracing logic from Wesley Loewer.
  65540. X
  65541. X Command-line parameters can now be entered on-the-fly using the <g> key
  65542. X thanks to Ken Shirriff.
  65543. X
  65544. X Dithered gif images can now be loaded onto a b/w display.
  65545. X Thanks to Ken Shirriff.
  65546. X
  65547. X Pictures can now be output as compressed PostScript.
  65548. X Thanks to Ken Shirriff.
  65549. X
  65550. X Periodicity is a new inside coloring option.
  65551. X Thanks to Ken Shirriff.
  65552. X
  65553. X Fixes: symmetry values for the SQR functions, bailout for the floating-pt
  65554. X versions of 'lambdafn' and 'mandelfn' fractals from Jonathan Osuch.
  65555. X
  65556. X "Flip", "conj" operators are now selectable in the parser
  65557. X
  65558. X New DXF Raytracing option from Dennis Bragg.
  65559. X
  65560. X Improved boundary-tracing logic from Wesley Loewer.
  65561. X
  65562. X New MSC7-style overlay structure is used if MAKEFRAC.BAT specifies MSC7.
  65563. X (with new FRACTINT.DEF and FRACTINT.LNK files for MSC7 users).  Several
  65564. X modules have been re-organized to take advantage of this new overlay
  65565. X capability if compiled under MSC7.
  65566. X Fractint now looks first any embedded help inside FRACTINT.EXE, and then
  65567. X for an external FRACTINT.HLP file before giving up. Previous releases
  65568. X required that the help text be embedded inside FRACTINT.EXE.
  65569. X
  65570. XBug fixes:
  65571. X
  65572. X Corrected formulas displayed for Marksmandel, Cmplxmarksmandel, and
  65573. X  associated julia types.
  65574. X
  65575. X BTM and precision fixes.
  65576. X
  65577. X Symmetry logic changed for various "outside=" options
  65578. X
  65579. X Symmetry value for EXP function in lambdafn and lambda(fn||fn) fixed.
  65580. X
  65581. X Fixed bug where math errors prevented save in batch mode.
  65582. X The <3> and <r> commands no longer destroy image -- user can back out
  65583. X with ESC and image is still there.
  65584. X
  65585. X Fixed display of correct number of Julibrot parameters, and Julibrot
  65586. X relaxes and doesn't constantly force ALTERN.MAP.
  65587. X
  65588. X Fixed tesseral type for condition when border is all one color but center
  65589. X contains image.
  65590. X
  65591. X Fixed integer mandel and julia when used with parameters > +1.99 and < -1.99
  65592. X
  65593. X Eliminated recalculation when generating a julia type from a mandelbrot
  65594. X type when the 'z' screen is viewed for the first time.
  65595. X
  65596. X Minor logic change to prevent double-clutching into and out of graphics
  65597. X mode when pressing, say, the 'x' key from a menu screen.
  65598. X
  65599. X Changed non-US phone number for the Houston Public (Software) Library
  65600. X
  65601. X The "Y" screen is now "Extended Options" instead of "Extended Doodads"
  65602. X
  65603. X ...and probably a lot more bux-fixes that we've since forgotten that
  65604. X we've implemented.
  65605. X
  65606. X~Topic=Introduction
  65607. X
  65608. XFRACTINT plots and manipulates images of "objects" -- actually, sets of
  65609. Xmathematical points -- that have fractal dimension.
  65610. XSee {"Fractals and the PC"} for some
  65611. Xhistorical and mathematical background on fractal geometry, a discipline
  65612. Xnamed and popularized by mathematician Benoit Mandelbrot. For now, these
  65613. Xsets of points have three important properties:
  65614. X
  65615. X1) They are generated by relatively simple calculations repeated over and
  65616. Xover, feeding the results of each step back into the next -- something
  65617. Xcomputers can do very rapidly.
  65618. X
  65619. X2) They are, quite literally, infinitely complex: they reveal more and
  65620. Xmore detail without limit as you plot smaller and smaller areas. Fractint
  65621. Xlets you "zoom in" by positioning a small box and hitting <Enter> to
  65622. Xredraw the boxed area at full-screen size; its maximum linear
  65623. X"magnification" is over a trillionfold.
  65624. X
  65625. X3) They can be astonishingly beautiful, especially using PC color
  65626. Xdisplays' ability to assign colors to selected points, and (with VGA
  65627. Xdisplays or EGA in 640x350x16 mode) to "animate" the images by quickly
  65628. Xshifting those color assignments.
  65629. X~OnlineFF
  65630. X
  65631. XFor a demonstration of some of Fractint's features, run the demonstration
  65632. Xfile included with this release (DEMO.BAT) by typing "demo" at the DOS
  65633. Xprompt. You can stop the demonstration at any time by pressing <Esc>.
  65634. X
  65635. XThe name FRACTINT was chosen because the program generates many of its
  65636. Ximages using INTeger math, rather than the floating point calculations
  65637. Xused by most such programs. That means that you don't need a math co-
  65638. Xprocessor chip (aka floating point unit or FPU), although for a few
  65639. Xfractal types where floating point math is faster, the program recognizes
  65640. Xand automatically uses an 80x87 chip if it's present. It's even faster on
  65641. Xsystems using Intel's 80386 and 80486 microprocessors, where the integer
  65642. Xmath can be executed in their native 32-bit mode.
  65643. X
  65644. XFractint works with many adapters and graphics modes from CGA to the
  65645. X1024x768, 256-color XGA mode. Even "larger" images, up to 2048x2048x256,
  65646. Xcan be plotted to expanded memory, extended memory, or disk: this bypasses
  65647. Xthe screen and allows you to create images with higher resolution than
  65648. Xyour current display can handle, and to run in "background" under multi-
  65649. Xtasking control programs such as DESQview and Windows 3.
  65650. X~OnlineFF
  65651. X
  65652. XFractint is an experiment in collaboration. Many volunteers have joined
  65653. XBert Tyler, the program's first author, in improving successive versions. 
  65654. XThrough electronic mail messages, first on CompuServe's PICS forum and now 
  65655. Xon GRAPHDEV, new versions are hacked out and debugged a little at a time.
  65656. XFractint was born fast, and none of us has seen any other fractal plotter
  65657. Xclose to the present version for speed, versatility, and all-around
  65658. Xwonderfulness. (If you have, tell us so we can steal somebody else's ideas
  65659. Xinstead of each other's.)
  65660. XSee {The Stone Soup Story} and {A Word About the Authors} for information
  65661. Xabout the authors, and see {Contacting the Authors} for how to contribute
  65662. Xyour own ideas and code.
  65663. X;
  65664. X;
  65665. X;
  65666. X~Topic=Conditions on Use
  65667. X
  65668. XFractint is freeware. The copyright is retained by the Stone Soup Group.
  65669. X
  65670. XFractint may be freely copied and distributed in unmodified form but may
  65671. Xnot be sold. (A nominal distribution fee may be charged for media and
  65672. Xhandling by freeware and shareware distributors.) Fractint may be used
  65673. Xpersonally or in a business - if you can do your job better by using
  65674. XFractint, or using images from it, that's great! It may not be given away
  65675. Xwith commercial products without explicit permission from the Stone Soup
  65676. XGroup.
  65677. X
  65678. XThere is no warranty of Fractint's suitability for any purpose, nor any
  65679. Xacceptance of liability, express or implied.
  65680. X
  65681. X **********************************************************************\
  65682. X * Contribution policy: Don't want money. Got money. Want admiration. *\
  65683. X **********************************************************************
  65684. X~OnlineFF
  65685. X
  65686. XSource code for Fractint is also freely available - see
  65687. X{Distribution of Fractint}.
  65688. XSee the FRACTSRC.DOC file included with the source for conditions on use.
  65689. X(In most cases we just want credit.)
  65690. X;
  65691. X;
  65692. X;
  65693. X~Topic=Getting Started
  65694. X
  65695. XTo start the program, enter FRACTINT at the DOS prompt. The program
  65696. Xdisplays an initial "credits" screen. If Fractint doesn't start properly,
  65697. Xplease see {Common Problems}.
  65698. X
  65699. XHitting <Enter> gets you from the initial screen to the main menu. You can
  65700. Xselect options from the menu by moving the highlight with the cursor arrow
  65701. Xkeys
  65702. X~Doc-
  65703. X(\24 \25 \27 \26)
  65704. X~Doc+
  65705. Xand pressing <Enter>, or you can enter commands directly.
  65706. X
  65707. XAs soon as you select a video mode, Fractint begins drawing an image - the
  65708. X"full" Mandelbrot set if you haven't selected another fractal type.
  65709. X
  65710. XFor a quick start, after starting Fractint try one of the following:\
  65711. X  If you have MCGA, VGA, or better:  <F3>\
  65712. X  If you have EGA:             <F9>\
  65713. X  If you have CGA:             <F5>\
  65714. X  Otherwise, monochrome:         <F6>
  65715. X
  65716. XAfter the initial Mandelbrot image has been displayed, try zooming
  65717. Xinto it (see {Zoom Box Commands}) and color cycling (see
  65718. X{Color Cycling Commands}).
  65719. XOnce you're comfortable with these basics, start exploring other
  65720. Xfunctions from the main menu.
  65721. X
  65722. XHelp is available from the menu and at most other points in Fractint by
  65723. Xpressing the <F1> key.
  65724. X
  65725. XAT ANY TIME, you can hit
  65726. X~Doc-
  65727. Xone of the keys described in {Display Mode Commands}
  65728. X~Doc+,Online-
  65729. Xa command key
  65730. X~Online+
  65731. Xto select a function. You do not need to wait for a calculation
  65732. Xto finish, nor do you have to return to the main menu.
  65733. X
  65734. XWhen entering commands, note that for the "typewriter" keys, upper and
  65735. Xlower case are equivalent, e.g. <B> and <b> have the same result.
  65736. X
  65737. XMany commands and parameters can be passed to FRACTINT as command-line
  65738. Xarguments or read from a configuration file;
  65739. X~Doc-
  65740. Xsee {Startup Parameters\, Parameter Files} for details.
  65741. X~Doc+,Online-
  65742. Xsee "Command Line Parameters, Parameter Files, Batch Mode" for details.
  65743. X~Online+
  65744. X;
  65745. X;
  65746. X;
  65747. X~Topic=Display Mode Commands
  65748. X;
  65749. X; This topic is online only
  65750. X
  65751. X~Format-
  65752. X   { Summary of Commands }
  65753. X   { Plotting Commands}
  65754. X   { Zoom Box Commands }
  65755. X   { Image Save/Restore Commands }
  65756. X   { Print Command }
  65757. X   { Parameter Save/Restore Commands }
  65758. X   { Interrupting and Resuming }
  65759. X   { Orbits Window }
  65760. X   { View Window }
  65761. X   { \"3D\" Commands }
  65762. X   { Video Mode Function Keys }
  65763. X   { Hints }
  65764. X;
  65765. X;
  65766. X;
  65767. X~Topic=Summary of Commands, Label=HELPMAIN
  65768. X; This topic is online only
  65769. X~Doc-
  65770. X
  65771. XHit any of these keys at the menu or while drawing or viewing a fractal.
  65772. XCommands marked with an '*' are also available at the credits screen.
  65773. X
  65774. X~Format-
  65775. X{Plotting Commands}
  65776. X * Delete,F2,F3,.. Select a Video Mode and draw (or redraw) current fractal
  65777. X * F1           HELP! (Enter help mode)
  65778. X   Esc or m       Go to main menu
  65779. X   \\            Redraw previous screen (you can 'back out' recursively)
  65780. X   Tab           Display information about the current fractal image
  65781. X * t           Select a new fractal type and parameters
  65782. X * x           Set a number of options and doodads
  65783. X * y           Set extended options and doodads
  65784. X * z           Set fractal type-specific parameters
  65785. X   c or + or -       Enter Color-Cycling Mode (see {=HELPCYCLING Color Cycling Commands})
  65786. X   e           Enter Palette-Editing Mode (see {=HELPXHAIR Palette Editing Commands})
  65787. X   Spacebar       Mandelbrot/Julia Set toggle.
  65788. X   Enter       Continue an interrupted calculation (e.g. after a save)
  65789. X * f           toggle the floating-point algorithm option ON or OFF
  65790. X * i           Set parameters for 3D fractal types
  65791. X * Insert       Restart the program (at the credits screen)
  65792. X   a           Convert the current image into a fractal 'starfield'
  65793. X   o           toggles 'orbits' option on and off during image generation
  65794. X * d           Shell to DOS (type 'exit' at the DOS prompt to return)
  65795. X   Ctrl-X       Flip the current image along the screen's X-axis
  65796. X   Ctrl-Y       Flip the current image along the screen's Y-axis
  65797. X   Ctrl-Z       Flip the current image along the screen's Origin
  65798. X
  65799. X{Image Save/Restore Commands}
  65800. X   s           Save the current screen image to disk
  65801. X * r           Restore a saved (or .GIF) image ('3' or 'o' for 3-D)
  65802. X
  65803. X{Orbits Window}
  65804. X   o           Turns on Orbits Window mode after image generation
  65805. X   ctrl-o       Turns on Orbits Window mode 
  65806. X
  65807. X{View Window}
  65808. X * v           Set view window parameters (reduction, aspect ratio)
  65809. X
  65810. X{Print Command}
  65811. X   p           Print the screen (command-line options set printer type)
  65812. X~OnlineFF
  65813. X{Parameter Save/Restore Commands}
  65814. X   b           Save commands describing the current image in a file
  65815. X           (writes an entry to be used with @ command)
  65816. X * @           Run a set of commands (in command line format) from a file
  65817. X   g           Give a startup parameter: {Summary of all Parameters}
  65818. X
  65819. X{\"3D\" Commands}
  65820. X * 3           3D transform a saved (or .GIF) image
  65821. X   # (shift-3)       same as 3, but overlay the current image
  65822. X
  65823. X{Zoom Box Commands}
  65824. X   PageUp       When no Zoom Box is active, bring one up
  65825. X           When active already, shrink it
  65826. X   PageDown       Expand the Zoom Box
  65827. X           Expanding past the screen size cancels the Zoom Box
  65828. X   \24 \25 \27 \26       Pan (Move) the Zoom Box
  65829. X   Ctrl- \24 \25 \27 \26   Fast-Pan the Zoom Box (may require an enhanced keyboard)
  65830. X   Enter       Redraw the Screen or area inside the Zoom Box
  65831. X   Ctrl-Enter       'Zoom-out' - expands the image so that your current
  65832. X           image is positioned inside the current zoom-box location.
  65833. X   Ctrl-Pad+/Pad-  Rotate the Zoom Box
  65834. X   Ctrl-PgUp/PgDn  Change Zoom Box vertical size (change its aspect ratio)
  65835. X   Ctrl-Home/End   Change Zoom Box shape
  65836. X   Ctrl-Ins/Del    Change Zoom Box color
  65837. X
  65838. X{Interrupting and Resuming}
  65839. X
  65840. X{Video Mode Function Keys}
  65841. X~Doc+
  65842. X;
  65843. X;
  65844. X;
  65845. X~Topic=Plotting Commands
  65846. X
  65847. XFunction keys & various combinations are used to select a video mode and
  65848. Xredraw the screen.  For a quick start try one of the following:\
  65849. X  If you have MCGA, VGA, or better:  <F3>\
  65850. X  If you have EGA:             <F9>\
  65851. X  If you have CGA:             <F5>\
  65852. X  Otherwise, monochrome:         <F6>\
  65853. X
  65854. X<F1>\
  65855. XDisplay a help screen. The function keys available in help mode are
  65856. Xdisplayed at the bottom of the help screen.
  65857. X
  65858. X<M> or <Esc>\
  65859. XReturn from a displayed image to the main menu.
  65860. X
  65861. X<Esc>\
  65862. XFrom the main menu, <Esc> is used to exit from Fractint.
  65863. X
  65864. X<Delete>\
  65865. XSame as choosing "select video mode" from the main menu.
  65866. XGoes to the "select video mode" screen.  See {Video Mode Function Keys}.
  65867. X
  65868. X<\\> (previously <Home>)\
  65869. XRedraw the previous image. The program tracks 25 sets of previous
  65870. Xcoordinates and fractal types, but does not remember other options which
  65871. Xwere different for those past images.
  65872. X
  65873. X<Tab>\
  65874. XDisplay the current fractal type, parameters, video mode, screen or (if
  65875. Xdisplayed) zoom-box coordinates, maximum iteration count, and other
  65876. Xinformation useful in keeping track of where you are.  The Tab function is
  65877. Xnon-destructive - if you press it while in the midst of generating an
  65878. Ximage, you will continue generating it when you return.  The Tab function
  65879. Xtells you if your image is still being generated or has finished - a handy
  65880. Xfeature for those overnight, 1024x768 resolution fractal images.  If the
  65881. Ximage is incomplete, it also tells you whether it can be interrupted and
  65882. Xresumed.  (Any function other than <Tab> and <F1> counts as an
  65883. X"interrupt".)
  65884. X
  65885. XThe Tab screen also includes a pixel-counting function, which will count
  65886. Xthe number of pixels colored in the inside color.  This gives an estimate
  65887. Xof the area of the fractal.  Note that the inside color must be different
  65888. Xfrom the outside color(s) for this to work; inside=0 is a good choice.
  65889. X
  65890. X<T>\
  65891. XSelect a fractal type. Move the cursor to your choice (or type the first
  65892. Xfew letters of its name) and hit <Enter>. Next you will be prompted for
  65893. Xany parameters used by the selected type - hit <Enter> for the defaults.
  65894. XSee {Fractal Types} for a list of supported types.
  65895. X
  65896. X<X>\
  65897. XSelect a number of eXtended options. Brings up a full-screen menu of
  65898. Xoptions, any of which you can change at will.  These options are:\
  65899. X  "passes=" - see {Drawing Method}\
  65900. X  Floating point toggle - see <F> key description below\
  65901. X  "maxiter=" - see {Image Calculation Parameters}\
  65902. X  "inside=" and "outside=" - see {Color Parameters}\
  65903. X  "savename=" filename - see {File Parameters}\
  65904. X  "overwrite=" option - see {File Parameters}\
  65905. X  "sound=" option - see {Sound Parameters}\
  65906. X  "logmap=" - see {Logarithmic Palettes and Color Ranges}\
  65907. X  "biomorph=" - see {Biomorphs}\
  65908. X  "decomp=" - see {Decomposition}\
  65909. X  "fillcolor=" - see {Drawing Method}\
  65910. X
  65911. X<F>\
  65912. XToggles the use of floating-point algorithms
  65913. X(see {"Limitations of Integer Math (And How We Cope)"}).
  65914. XWhether floating point is in
  65915. Xuse is shown on the <Tab> status screen.  The floating point option can
  65916. Xalso be turned on and off using the "X" options screen.
  65917. XIf you have a non-Intel floating point chip which supports the full 387
  65918. Xinstruction set, see the "FPU=" command in {Startup Parameters}
  65919. Xto get the most out of your chip.
  65920. X
  65921. X<Y>\
  65922. XMore options which we couldn't fit under the <X> command:\
  65923. X  "finattract=" - see {Finite Attractors}\
  65924. X  "potential=" parameters - see {Continuous Potential}\
  65925. X  "invert=" parameters - see {Inversion}\
  65926. X  "distest=" parameters - see {Distance Estimator Method}\
  65927. X  "cyclerange=" - see {Color Cycling Commands}\
  65928. X
  65929. X<Z>\
  65930. XModify the parameters specific to the currently selected fractal type.
  65931. XThis command lets you modify the parameters which are requested when you
  65932. Xselect a new fractal type with the <T> command, without having to repeat
  65933. Xthat selection. You can enter "e" or "p" in column one of the input fields
  65934. Xto get the numbers e and pi (2.71828... and 3.14159...).\
  65935. XFrom the fractal parameters screen, you can press <F6> to bring up a
  65936. Xsub parameter screen for the coordinates of the image's corners.
  65937. X; With the IFS fractal type, <Z> brings up the IFS editor (see
  65938. X; {=HT_IFS Barnsley IFS Fractals}).
  65939. X
  65940. X<+> or <->\
  65941. XSwitch to color-cycling mode and begin cycling the palette
  65942. Xby shifting each color to the next "contour."  See {Color Cycling Commands}.\
  65943. X<C>\
  65944. XSwitch to color-cycling mode but do not start cycling.
  65945. XThe normally black "overscan" border of the screen changes to white.
  65946. XSee {Color Cycling Commands}.
  65947. X
  65948. X<E>\
  65949. XEnter Palette-Editing Mode.  See {Palette Editing Commands}.
  65950. X
  65951. X<Spacebar>\
  65952. XToggle between Mandelbrot set images and their corresponding Julia-set
  65953. Ximages. Read the notes in {=HT_JULIA Fractal Types, Julia Sets}
  65954. Xbefore trying this option if you want to see anything interesting.
  65955. X
  65956. X<J>\
  65957. XToggle between Julia escape time fractal and the Inverse Julia orbit
  65958. Xfractal. See {=HT_INVERSE Inverse Julias}
  65959. X
  65960. X<Enter>\
  65961. XEnter is used to resume calculation after a pause. It is only
  65962. Xnecessary to do this when there is a message on the screen waiting to be
  65963. Xacknowledged, such as the message shown after you save an image to disk.
  65964. X
  65965. X<I>\
  65966. XModify 3D transformation parameters used with 3D fractal types such as
  65967. X"Lorenz3D" and 3D "IFS" definitions, including the selection of
  65968. X{=HELP3DGLASSES "funny glasses"} red/blue 3D.
  65969. X
  65970. X<A>\
  65971. XConvert the current image into a fractal 'starfield'.  See {Starfields}.
  65972. X
  65973. X<O> (the letter, not the number)\
  65974. XIf pressed while an image is being generated, toggles the display of
  65975. Xintermediate results -- the "orbits" Fractint uses as it calculates values
  65976. Xfor each point. Slows the display a bit, but shows you how clever the
  65977. Xprogram is behind the scenes. (See "A Little Code" in
  65978. X{"Fractals and the PC"}.)
  65979. X
  65980. X<D>\
  65981. XShell to DOS. Return to Fractint by entering "exit" at a DOS prompt.
  65982. X~OnlineFF
  65983. X<Insert>\
  65984. XRestart at the "credits" screen and reset most variables to their initial
  65985. Xstate.    Variables which are not reset are: savename, lightname, video,
  65986. Xstartup filename.
  65987. X;
  65988. X;
  65989. X;
  65990. X~Topic=Zoom Box Commands, Label=HELPZOOM
  65991. X
  65992. XZoom Box functions can be invoked while an image is being generated or when
  65993. Xit has been completely drawn.  Zooming is supported for most fractal types,
  65994. Xbut not all.
  65995. X
  65996. XThe general approach to using the zoom box is:    Frame an area using
  65997. Xthe keys described below,
  65998. Xthen <Enter> to expand what's in the frame to fill the
  65999. Xwhole screen (zoom in); or <Ctrl><Enter> to shrink the current image into
  66000. Xthe framed area (zoom out). With a mouse, double-click the left button to
  66001. Xzoom in, double click the right button to zoom out.
  66002. X
  66003. X<Page Up>, <Page Down>\
  66004. XUse <Page Up> to initially bring up the zoom box. It starts at full screen
  66005. Xsize. Subsequent use of these keys makes the zoom box smaller or larger.
  66006. XUsing <Page Down> to enlarge the zoom box when it is already at maximum
  66007. Xsize removes the zoom box from the display. Moving the mouse away from you
  66008. Xor toward you while holding the left button down performs the same
  66009. Xfunctions as these keys.
  66010. X
  66011. XUsing the cursor "arrow" keys
  66012. X~Doc-
  66013. X(\24 \25 \27 \26)
  66014. X~Doc+
  66015. Xor moving
  66016. Xthe mouse without holding any buttons down, moves the zoom box.
  66017. X
  66018. XHolding <Ctrl> while pressing cursor "arrow" keys moves the box 5 times
  66019. Xfaster.  (This only works with enhanced keyboards.)
  66020. X
  66021. XPanning: If you move a fullsize zoombox and don't change anything else
  66022. Xbefore performing the zoom, Fractint just moves what's already on the
  66023. Xscreen and then fills in the new edges, to reduce drawing time. This
  66024. Xfeature applies to most fractal types but not all.  A side effect is that
  66025. Xwhile an image is incomplete, a full size zoom box moves in steps larger
  66026. Xthan one pixel.  Fractint keeps the box on multiple pixel boundaries, to
  66027. Xmake panning possible.    As a multi-pass (e.g. solid guessing) image
  66028. Xapproaches completion, the zoom box can move in smaller increments.
  66029. X
  66030. XIn addition to resizing the zoom box and moving it around, you can do some
  66031. Xrather warped things with it.  If you're a new Fractint user, we recommend
  66032. Xskipping the rest of the zoom box functions for now and coming back to
  66033. Xthem when you're comfortable with the basic zoom box functions.
  66034. X
  66035. X<Ctrl><Keypad->, <Ctrl><Keypad+>\
  66036. XHolding <Ctrl> and pressing the numeric keypad's + or - keys rotates the
  66037. Xzoom box. Moving the mouse left or right while holding the right button
  66038. Xdown performs the same function.
  66039. X
  66040. X<Ctrl><Page Up>, <Ctrl><Page Down>\
  66041. XThese commands change the zoom box's "aspect ratio", stretching or
  66042. Xshrinking it vertically. Moving the mouse away from you or toward you
  66043. Xwhile holding both buttons (or the middle button on a 3-button mouse) down
  66044. Xperforms the same function. There are no commands to directly stretch or
  66045. Xshrink the zoom box horizontally - the same effect can be achieved by
  66046. Xcombining vertical stretching and resizing.
  66047. X
  66048. X<Ctrl><Home>, <Ctrl><End>\
  66049. XThese commands "skew" the zoom box, moving the top and bottom edges in
  66050. Xopposite directions. Moving the mouse left or right while holding both
  66051. Xbuttons (or the middle button on a 3-button mouse) down performs the same
  66052. Xfunction. There are no commands to directly skew the left and right edges
  66053. X- the same effect can be achieved by using these functions combined with
  66054. Xrotation.
  66055. X
  66056. X<Ctrl><Insert>, <Ctrl><Delete>\
  66057. XThese commands change the zoom box color. This is useful when you're
  66058. Xhaving trouble seeing the zoom box against the colors around it. Moving
  66059. Xthe mouse away from you or toward you while holding the right button down
  66060. Xperforms the same function.
  66061. X
  66062. XYou may find it difficult to figure out what combination of size, position
  66063. Xrotation, stretch, and skew to use to get a particular result.    (We do.)\
  66064. XA good way to get a feel for all these functions is to play with the
  66065. XGingerbreadman fractal type. Gingerbreadman's shape makes it easy to
  66066. Xsee what you're doing to him. A warning though: Gingerbreadman will run
  66067. Xforever, he's never quite done! So, pre-empt with your next zoom when he's
  66068. Xbaked enough.
  66069. X
  66070. XIf you accidentally change your zoom box shape or rotate and
  66071. Xforget which way is up, just use <PageDown> to make it bigger until it
  66072. Xdisappears, then <PageUp> to get a fresh one.  With a
  66073. Xmouse, after removing the old zoom box from the display release and
  66074. Xre-press the left button for a fresh one.
  66075. X
  66076. XIf your screen does not have a 4:3 "aspect ratio" (i.e. if the visible
  66077. Xdisplay area on it is not 1.333 times as wide as it is high), rotating and
  66078. Xzooming will have some odd effects - angles will change, including the
  66079. Xzoom box's shape itself, circles (if you are so lucky as to see any with a
  66080. Xnon-standard aspect ratio) become non-circular, and so on. The vast
  66081. Xmajority of PC screens *do* have a 4:3 aspect ratio.
  66082. X
  66083. XZooming is not implemented for the plasma and diffusion fractal types, nor
  66084. Xfor overlayed and 3D images. A few fractal types support zooming but
  66085. Xdo not support rotation and skewing - nothing happens when you try it.
  66086. X;
  66087. X;
  66088. X;
  66089. X~Topic=Image Save/Restore Commands, Label=HELPSAVEREST
  66090. X
  66091. X<S> saves the current image to disk. All parameters required to recreate
  66092. Xthe image are saved with it. Progress is marked by colored lines moving
  66093. Xdown the screen's edges.
  66094. X
  66095. XThe default filename for the first image saved after starting Fractint is
  66096. XFRACT001.GIF;  subsequent saves in the same session are automatically
  66097. Xincremented 002, 003... Use the "savename=" parameter or <X> options
  66098. Xscreen to change the name. By default, files left over from previous
  66099. Xsessions are not overwritten - the first unused FRACTnnn name is used.
  66100. XUse the "overwrite=yes" parameter or <X> options screen) to overwrite
  66101. Xexisting files.
  66102. X
  66103. XA save operation can be interrupted by pressing any key. If you interrupt,
  66104. Xyou'll be asked whether to keep or discard the partial file.
  66105. X
  66106. X<R> restores an image previously saved with <S>, or an ordinary GIF file.
  66107. XAfter pressing <R> you are shown the file names in the current directory
  66108. Xwhich match the current file mask. To select a file to restore, move the
  66109. Xcursor to it (or type the first few letters of its name) and press
  66110. X<Enter>.
  66111. X
  66112. XDirectories are shown in the file list with a "\\" at the end of the name.
  66113. XWhen you select a directory, the contents of that directory are shown. Or,
  66114. Xyou can type the name of a different directory (and optionally a different
  66115. Xdrive) and press <Enter> for a new display. You can also type a mask such
  66116. Xas "*.XYZ" and press <Enter> to display files whose name ends with the
  66117. Xmatching suffix (XYZ).
  66118. X
  66119. XYou can use <F6> to switch directories to the default fractint directory
  66120. Xor to your own directory which is specified through the DOS environment
  66121. Xvariable "FRACTDIR".
  66122. X
  66123. XOnce you have selected a file to restore, a summary description of the
  66124. Xfile is shown, with a video mode selection list. Usually you can just
  66125. Xpress <Enter> to go past this screen and load the image. Other choices
  66126. Xavailable at this point are:\
  66127. X  Cursor keys: select a different video mode\
  66128. X  <Tab>: display more information about the fractal\
  66129. X  <F1>: for help about the "err" column in displayed video modes\
  66130. XIf you restore a file into a video mode which does not have the same pixel
  66131. Xdimensions as the file, Fractint will make some adjustments:  The view
  66132. Xwindow parameters (see <V> command) will automatically be set to an
  66133. Xappropriate size, and if the image is larger than the screen dimensions,
  66134. Xit will be reduced by using only every Nth pixel during the restore.
  66135. X;
  66136. X;
  66137. X;
  66138. X~Topic=Print Command
  66139. X
  66140. X<P>\
  66141. X
  66142. XPrint the current fractal image on your (Laserjet, Paintjet, Epson-
  66143. Xcompatible, PostScript, or HP-GL) printer.
  66144. X
  66145. XSee {"Setting Defaults (SSTOOLS.INI File)"} and {"Printer Parameters"}
  66146. Xfor how to let Fractint know about your printer setup.
  66147. X
  66148. X{"Disk-Video" Modes} can be used to
  66149. Xgenerate images for printing at higher resolutions than your screen
  66150. Xsupports.
  66151. X;
  66152. X;
  66153. X;
  66154. X~Topic=Parameter Save/Restore Commands, Label=HELPPARMFILE
  66155. X
  66156. XParameter files can be used to save/restore all options and settings
  66157. Xrequired to recreate particular images.  The parameters required to
  66158. Xdescribe an image require very little disk space, especially compared with
  66159. Xsaving the image itself.
  66160. X
  66161. X<@>
  66162. X
  66163. XThe <@> command loads a set of parameters describing an image.
  66164. X(Actually, it can also be used to set non-image parameters such as SOUND,
  66165. Xbut at this point we're interested in images. Other uses of parameter
  66166. Xfiles are discussed in {"Parameter Files and the <@> Command"}.)
  66167. X
  66168. XWhen you hit <@>, Fractint displays the names of the entries in the
  66169. Xcurrently selected parameter file.  The default parameter file,
  66170. XFRACTINT.PAR, is included with the Fractint release and contains
  66171. Xparameters for some sample images.
  66172. X
  66173. XAfter pressing <@>, highlight an entry and press <Enter> to load it, or
  66174. Xpress <F6> to change to another parameter file.
  66175. X
  66176. XNote that parameter file entries specify all calculation related
  66177. Xparameters, but do not specify things like the video mode - the image will
  66178. Xbe plotted in your currently selected mode.
  66179. X
  66180. X<B>
  66181. X
  66182. XThe <B> command saves the parameters required to describe the currently
  66183. Xdisplayed image, which can subsequently be used with the <@> command to
  66184. Xrecreate it.
  66185. X
  66186. XAfter you press <B>, Fractint prompts for:
  66187. X
  66188. X  Parameter file:  The name of the file to store the parameters in.  You
  66189. X  should use some name like "myimages" instead of fractint.par, so that
  66190. X  your images are kept separate from the ones released with new versions
  66191. X  of Fractint. You can use the PARMFILE= command in SSTOOLS.INI
  66192. X  to set the default parameter file name to "myimages" or whatever.
  66193. X  (See {"Setting Defaults (SSTOOLS.INI File)"} and "parmfile=" in
  66194. X  {"File Parameters"}.)
  66195. X
  66196. X  Name:  The name you want to assign to the entry, to be displayed when
  66197. X  the <@> command is used.
  66198. X
  66199. X  Main comment:  A comment to be shown beside the entry in the <@> command
  66200. X  display.
  66201. X
  66202. X  Second, Third, and Fourth comment:  Additional comments to store in the 
  66203. X  file with the entry. These comments go in the file only, and are not 
  66204. X  displayed by the <@> command.
  66205. X
  66206. X  Record colors?:  Whether color information should be included in the
  66207. X  entry. Usually the default value displayed by Fractint is what you want.
  66208. X  Allowed values are:\
  66209. X  "no" - Don't record colors. This is the default if the image is using
  66210. X     your video adapter's default colors.
  66211. X  "@mapfilename" - When these parameters are used, load colors from the
  66212. X     named color map file. This is the default if you are currently using
  66213. X     colors from a color map file.
  66214. X  "yes" - Record the colors in detail. This is the default when you've
  66215. X     changed the display colors by using the palette editor or by color
  66216. X     cycling. The only reason that this isn't what Fractint always does
  66217. X     for the <B> command is that color information can be bulky - up to
  66218. X     nearly 1K of disk space. That may not
  66219. X     sound like much, but can add up when you consider the thousands of
  66220. X     wonderful images you may find you just *have* to record...
  66221. X     Smooth-shaded ranges of colors are compressed, so if that's used a
  66222. X     lot in an image the color information won't be as bulky.
  66223. X
  66224. X  # of colors:    This only matters if "Record colors?" is set to "yes".  It
  66225. X  specifies the number of colors to record. Recording less colors will
  66226. X  take less space. Usually the default value displayed by Fractint is what
  66227. X  you want. You might want to increase it in some cases, e.g. if you are
  66228. X  using a 256 color mode with maxiter 150, and have used the palette
  66229. X  editor to set all 256 possible colors for use with color cycling, then
  66230. X  you'll want to set the "# of colors" to 256.
  66231. X
  66232. X  At the bottom of the input screen are inputs for Fractint's "pieces"
  66233. X  divide-and-conquer feature. You can create multiple PAR entries that
  66234. X  break an image up into pieces so that you can generate the image pieces 
  66235. X  one by one. There are two reasons for doing this. The first is in case the
  66236. X  fractal is very slow, and you want to generate parts of the image at the 
  66237. X  same time on several computers. The second is that you might want to make 
  66238. X  an image greater than 2048 x 2048. The parameters for this feature are:
  66239. X     X Multiples - How many divisions of final image in the x direction\
  66240. X     Y Multiples - How many divisions of final image in the y direction\
  66241. X     Video mode  - Fractint video mode for each piece (e.g. "F3")\
  66242. X
  66243. X  The last item defaults to the current video mode. If either X Multiples or
  66244. X  Y Multiples are greater than 1, then multiple numbered PAR entries for the
  66245. X  pieces are added to the PAR file, and a MAKEMIG.BAT file is created that
  66246. X  builds all of the component pieces and then stitches them together into
  66247. X  a "multi-image" GIF.  The current limitations of the "divide and conquer"
  66248. X  algorithm are 36 or fewer X and Y multiples (so you are limited to "only"
  66249. X  36x36=1296 component images), and a final resolution limit in both the
  66250. X  X and Y directions of 65,535 (a limitation of "only" four billion pixels
  66251. X  or so).
  66252. X  The final image generated by MAKEMIG is a "multi-image" GIF file called
  66253. X  FRACTMIG.GIF.  In case you have other software that can't handle
  66254. X  multi-image GIF files, MAKEMIG includes a final (but commented out) call
  66255. X  to SIMPLGIF, a companion program that reads a GIF file that may contain
  66256. X  little tricks like multiple images and creates a simple GIF from it.
  66257. X  Fair warning: SIMPLGIF needs room to build a composite image while it
  66258. X  works, and it does that using a temporary disk file equal to the size
  66259. X  of the final image - and a 64Kx64K GIF image requires a 4GB temporary
  66260. X  disk file!
  66261. X
  66262. X<G>
  66263. X
  66264. XThe <G> command lets you give a startup parameter interactively.
  66265. X;
  66266. X;
  66267. X;
  66268. X~Topic=<X> Options Screen, Label=HELPXOPTS
  66269. X; This topic is online context-sensitive only.
  66270. X
  66271. X   Passes - see {Drawing Method}\
  66272. X   Fillcolor - see {Drawing Method}\
  66273. X   Floating Point Algorithm - see notes below\
  66274. X   Maximum Iterations - see {Image Calculation Parameters}\
  66275. X   Inside and Outside colors - see {Color Parameters}\
  66276. X   Savename and File Overwrite - see {File Parameters}\
  66277. X   Sound option - see {Sound Parameters}\
  66278. X   Log Palette - see {Logarithmic Palettes and Color Ranges}\
  66279. X   Biomorph Color - see {Biomorphs}\
  66280. X   Decomp Option - see {Decomposition}\
  66281. X
  66282. XYou can toggle the use of floating-point algorithms on this screen (see
  66283. X{"Limitations of Integer Math (And How We Cope)"}).  Whether floating
  66284. Xpoint is in use is shown on the <Tab> status screen.  If you have a
  66285. Xnon-Intel floating point chip which supports the full 387 instruction set,
  66286. Xsee the "FPU=" command in {Startup Parameters} to get the most out of your
  66287. Xchip.
  66288. X;
  66289. X;
  66290. X~Topic=<Y> Options Screen, Label=HELPYOPTS
  66291. X; This topic is online context-sensitive only.
  66292. X
  66293. X   Finite attractor - see{ Finite Attractors }\
  66294. X
  66295. X   Potential parameters - see{ Continuous Potential }\
  66296. X
  66297. X   Distance Estimator parameters - see{ Distance Estimator Method }\
  66298. X
  66299. X   Inversion parameters - see{ Inversion }\
  66300. X
  66301. X   Color cycling range - see{ Color Cycling Commands }\
  66302. X;
  66303. X;
  66304. X~Topic=Image Coordinates Screen, Label=HELPCOORDS
  66305. X; This topic is online context-sensitive only.
  66306. X
  66307. XYou can directly enter corner coordinates on this screen instead of
  66308. Xusing the zoom box to move around.  You can also use <F4> to reset
  66309. Xthe coordinates to the defaults for the current fractal type.
  66310. X
  66311. XThere are two formats for the display: corners or center-mag.  You can
  66312. Xtoggle between the two by using <F7>.
  66313. X
  66314. XIn corners mode, corner coordinate values are entered directly.  Usually
  66315. Xonly the top-left and bottom-right corners need be specified - the
  66316. Xbottom left corner can be entered as zeros to default to an ordinary
  66317. Xunrotated rectangular area.  For rotated or skewed images, the bottom
  66318. Xleft corner must also be specified.
  66319. X
  66320. XCenter-mag mode can only be used with unrotated unstretched images.
  66321. XIn this mode the image area is described by entering the coordinates for
  66322. Xthe center of the rectangle, and its magnification factor.
  66323. X;
  66324. X;
  66325. X;
  66326. X~Topic=Interrupting and Resuming
  66327. X
  66328. XFractint command keys can be loosely grouped as:
  66329. X
  66330. X o Keys which suspend calculation of the current image (if one is being
  66331. X   calculated) and automatically resume after the function.  <Tab>
  66332. X   (display status information) and <F1> (display help), are the only
  66333. X   keys in this group.
  66334. X
  66335. X o Keys which automatically trigger calculation of a new image.
  66336. X   Examples:  selecting a video mode (e.g. <F3>);  selecting a fractal
  66337. X   type using <T>;  using the <X> screen to change an option such as
  66338. X   maximum iterations.
  66339. X
  66340. X o Keys which do something, then wait for you to indicate what to do
  66341. X   next.  Examples:  <M> to go to main menu;  <C> to enter color cycling
  66342. X   mode;  <PageUp> to bring up a zoom box.  After using a command in this
  66343. X   group, calculation automatically resumes when you return from the
  66344. X   function (e.g. <Esc> from color cycling, <PageDn> to clear zoom box).
  66345. X   There are a few fractal types which cannot resume calculation, they
  66346. X   are noted below.  Note that after saving an image with <S>, you must
  66347. X   press <Enter> to clear the "saved" message from the screen and resume.
  66348. X
  66349. XAn image which is <S>aved before it completes can later be <R>estored and
  66350. Xcontinued. The calculation is automatically resumed when you restore such
  66351. Xan image.
  66352. X
  66353. XWhen a slow fractal type resumes after an interruption in the third
  66354. Xcategory above, there may be a lag while nothing visible happens.  This is
  66355. Xbecause most cases of resume restart at the beginning of a screen line.
  66356. XIf unsure, you can check whether calculation has resumed with the <Tab>
  66357. Xkey.
  66358. X
  66359. XThe following fractal types cannot (currently) be resumed: plasma, 3d
  66360. Xtransformations, julibrot, and 3d orbital types like lorenz3d.    To check
  66361. Xwhether resuming an image is possible, use the <Tab> key while it is
  66362. Xcalculating.  It is resumable unless there is a note under the fractal
  66363. Xtype saying it is not.
  66364. X
  66365. XThe {Batch Mode} section discusses how to resume in batch mode.
  66366. X
  66367. XTo <R>estore and resume a "formula", "lsystem", or "ifs" type fractal your
  66368. X"formulafile", "lfile", or "ifsfile" must contain the required name.
  66369. X;
  66370. X;
  66371. X;
  66372. X~Topic=Orbits Window, Label=HELP_ORBITS
  66373. XThe <O> key turns on the Orbit mode.  In this mode a cursor appears 
  66374. Xover the fractal. A window appears showing the orbit used in the 
  66375. Xcalculation of the color at the point where the cursor is. Move the 
  66376. Xcursor around the fractal using the arrow keys or the mouse and watch
  66377. Xthe orbits change. Try entering the Orbits mode with View Windows (<V>)
  66378. Xturned on. The following keys take effect in Orbits mode.\
  66379. X<c>         Circle toggle - makes little circles with radii inversely\
  66380. X            proportional to the iteration. Press <c> again to toggle\
  66381. X            back to point-by-point display of orbits.\
  66382. X<l>         Line toggle - connects orbits with lines (can use with <c>)\
  66383. X<n>         Numbers toggle - shows coordinates of the cursor on the\ 
  66384. X            screen. Press <n> again to turn off numbers.\
  66385. X<p>         Enter pixel coordinates directly\ 
  66386. X<h>         Hide fractal toggle. Works only if View Windows is turned on\ 
  66387. X            and set for a small window (such as the default size.) Hides the\ 
  66388. X            fractal, allowing the orbit to take up the whole screen. Press\
  66389. X            <h> again to uncover the fractal.\
  66390. X<s>         Saves the fractal, cursor, orbits, and numbers as they appear\
  66391. X            on the screen.\
  66392. X<<> or <,>  Zoom orbits image smaller\
  66393. X<>> or <.>  Zoom orbits image larger\
  66394. X<z>         Restore default zoom.\
  66395. X;
  66396. X;
  66397. X;
  66398. X~Topic=View Window, Label=HELPVIEW
  66399. X
  66400. XThe <V> command is used to set the view window parameters described below.
  66401. XThese parameters can be used to:\
  66402. X o Define a small window on the screen which is to contain the generated
  66403. X   images. Using a small window speeds up calculation time (there are
  66404. X   fewer pixels to generate). You can use a small window to explore
  66405. X   quickly, then turn the view window off to recalculate the image at
  66406. X   full screen size.
  66407. X o Generate an image with a different "aspect ratio"; e.g. in a square
  66408. X   window or in a tall skinny rectangle.
  66409. X o View saved GIF images which have pixel dimensions different from any
  66410. X   mode supported by your hardware. This use of view windows occurs
  66411. X   automatically when you restore such an image.
  66412. X
  66413. X"Preview display"\
  66414. XSet this to "yes" to turn on view window, "no" for full screen display.
  66415. XWhile this is "no", the only view parameter which has any affect is "final
  66416. Xmedia aspect ratio". When a view window is being used, all other Fractint
  66417. Xfunctions continue to operate normally - you can zoom, color-cycle, and
  66418. Xall the rest.
  66419. X
  66420. X"Reduction factor"\
  66421. XWhen an explicit size is not given, this determines the view window size,
  66422. Xas a factor of the screen size.  E.g. a reduction factor of 2 makes the
  66423. Xwindow 1/2 as big as the screen in both dimensions.
  66424. X
  66425. X"Final media aspect ratio"\
  66426. XThis is the height of the final image you want, divided by the width. The
  66427. Xdefault is 0.75 because standard PC monitors have a height:width ratio of
  66428. X3:4. E.g. set this to 2.0 for an image twice as high as it is wide. The
  66429. Xeffect of this parameter is visible only when "preview display" is
  66430. Xenabled.
  66431. X
  66432. X"Crop starting coordinates"\
  66433. XThis parameter affects what happens when you change the aspect ratio. If
  66434. Xset to "no", then when you change aspect ratio, the prior image will be
  66435. Xsqueezed or stretched to fit into the new shape. If set to "yes", the
  66436. Xprior image is "cropped" to avoid squeezing or stretching.
  66437. X
  66438. X"Explicit size"\
  66439. XSetting these to non-zero values over-rides the "reduction factor" with
  66440. Xexplicit sizes in pixels. If only the "x pixels" size is specified, the "y
  66441. Xpixels" size is calculated automatically based on x and the aspect ratio.
  66442. X
  66443. XMore about final aspect ratio:    If you want to produce a high quality
  66444. Xhard-copy image which is say 8" high by 5" down, based on a vertical
  66445. X"slice" of an existing image, you could use a procedure like the
  66446. Xfollowing. You'll need some method of converting a GIF image to your final
  66447. Xmedia (slide or whatever) - Fractint can only do the whole job with a
  66448. XPostScript printer, it does not preserve aspect ratio with other printers.
  66449. X o restore the existing image\
  66450. X o set view parameters: preview to yes, reduction to anything (say 2),
  66451. X   aspect ratio to 1.6, and crop to yes
  66452. X o zoom, rotate, whatever, till you get the desired final image\
  66453. X o set preview display back to no\
  66454. X o trigger final calculation in some high res disk video mode, using the
  66455. X   appropriate video mode function key
  66456. X o print directly to a PostScript printer, or save the result as a GIF
  66457. X   file and use external utilities to convert to hard copy.
  66458. X;
  66459. X;
  66460. X;
  66461. X~Topic=\"3D\" Commands
  66462. X
  66463. XSee {\"3D\" Images} for details of these commands.
  66464. X
  66465. X<3>\
  66466. XRestore a saved image as a 3D "landscape", translating its color
  66467. Xinformation into "height". You will be prompted for all KINDS of options.
  66468. X
  66469. X<#>\
  66470. XRestore in 3D and overlay the result on the current screen.
  66471. X;
  66472. X;
  66473. X;
  66474. X~Topic=Video Mode Function Keys, Label=HELPVIDSEL
  66475. X
  66476. XFractint supports *so* many video modes that we've given up trying to
  66477. Xreserve a keyboard combination for each of them.
  66478. X
  66479. XAny supported video mode can be selected by going to the "Select Video Mode"
  66480. Xscreen (from main menu or by using <Delete>), then using the cursor up and down
  66481. Xarrow keys and/or <PageUp> and <PageDown> keys to highlight the desired mode,
  66482. Xthen pressing <Enter>.
  66483. X
  66484. XUp to 39 modes can be assigned to the keys F2-F10, SF1-SF10 <Shift>+<Fn>),
  66485. XCF1-CF10 (<Ctrl>+<Fn>), and AF1-AF10 (<Alt>+<Fn>).  The modes assigned to
  66486. Xfunction keys can be invoked directly by pressing the assigned key, without
  66487. Xgoing to the video mode selection screen.
  66488. X
  66489. X30 key combinations can be reassigned:    <F1> to <F10> combined with any of
  66490. X<Shift>, <Ctrl>, or <Alt>.
  66491. XThe video modes assigned to <F2> through <F10> can not be
  66492. Xchanged - these are assigned to the most common video modes, which might
  66493. Xbe used in demonstration files or batches.
  66494. X
  66495. XTo reassign a function key to a mode you often use, go to the "select
  66496. Xvideo mode" screen, highlight the video
  66497. Xmode, press the keypad (gray) <+> key, then press the desired
  66498. Xfunction key or key combination.  The new key assignment will be remembered
  66499. Xfor future runs.
  66500. X
  66501. XTo unassign a key (so that it doesn't invoke any video
  66502. Xmode), highlight the mode currently selected by the key and press the
  66503. Xkeypad (gray) <-> key.
  66504. X
  66505. XA note about the "select video modes" screen:
  66506. Xthe video modes which are displayed with a 'B' suffix in the number
  66507. Xof colors are modes which have no custom programming - they use the BIOS
  66508. Xand are S-L-O-W ones.
  66509. X
  66510. XSee {"Video Adapter Notes"} for comments about particular adapters.
  66511. X
  66512. XSee {"Disk-Video" Modes} for a description of these non-display modes.
  66513. X
  66514. XSee {"Customized Video Modes\, FRACTINT.CFG"} for information about
  66515. Xadding your own video modes.
  66516. X;
  66517. X;
  66518. X;
  66519. X~Topic=Hints
  66520. X
  66521. XRemember, you do NOT have to wait for the program to finish a full screen
  66522. Xdisplay before entering a command. If you see an interesting spot you want
  66523. Xto zoom in on while the screen is half-done, don't wait -- do it! If you
  66524. Xthink after seeing the first few lines that another video mode would look
  66525. Xbetter, go ahead -- Fractint will shift modes and start the redraw at
  66526. Xonce. When it finishes a display, it beeps and waits for your next
  66527. Xcommand.
  66528. X
  66529. XIn general, the most interesting areas are the "border" areas where the
  66530. Xcolors are changing rapidly. Zoom in on them for the best results. The
  66531. Xfirst Mandelbrot-set (default) fractal image has a large, solid-colored
  66532. Xinterior that is the slowest to display; there's nothing to be seen by
  66533. Xzooming there.
  66534. X
  66535. XPlotting time is directly proportional to the number of pixels in a
  66536. Xscreen, and hence increases with the resolution of the video mode.
  66537. XYou may want to start in a low-resolution mode for quick progress while
  66538. Xzooming in, and switch to a higher-resolution mode
  66539. Xwhen things get interesting. Or use the
  66540. Xsolid guessing mode and pre-empt with
  66541. Xa zoom before it finishes. Plotting time also varies with the maximum
  66542. Xiteration setting, the fractal type, and your choice of drawing mode.
  66543. XSolid-guessing (the default) is fastest, but it can be wrong:
  66544. Xperfectionists will want to use dual-pass mode (its first-pass preview is
  66545. Xhandy if you might zoom pre-emptively) or single-pass mode.
  66546. X
  66547. XWhen you start systematically exploring, you can save time (and hey, every
  66548. Xlittle bit helps -- these "objects" are INFINITE, remember!) by <S>aving
  66549. Xyour last screen in a session to a file, and then going straight to it the
  66550. Xnext time by using the command FRACTINT FRACTxxx (the .GIF extension is
  66551. Xassumed), or by starting Fractint normally and then using the <R> command
  66552. Xto reload the saved file. Or you could hit <B> to create a parameter file
  66553. Xentry with the "recipe" for a given image, and next time use the <@>
  66554. Xcommand to re-plot it.
  66555. X;
  66556. X;
  66557. X;
  66558. X~Topic=Fractint on Unix
  66559. X
  66560. XFractint has been ported to Unix to run under X Windows.  This version is
  66561. Xcalled "Xfractint".  Xfractint may be obtained by anonymous ftp to
  66562. Xsprite.Berkeley.EDU, in the file xfractnnn.shar.Z.
  66563. X
  66564. XXfractint is still under development and is not as reliable as the IBM PC
  66565. Xversion.
  66566. X
  66567. XContact Ken Shirriff (shirriff@cs.Berkeley.EDU) for information on Xfractint.
  66568. X
  66569. XXfractint is a straight port of the IBM PC version.  Thus, it uses the
  66570. XIBM user interface.  If you do not have function keys, or Xfractint does
  66571. Xnot accept them from your keyboard, use the following key mappings:
  66572. X
  66573. X     IBM             Unix\
  66574. X     F1 to F10       Shift-1 to Shift-0\
  66575. X     INSERT          I\
  66576. X     DELETE          D\
  66577. X     PAGE_UP         U\
  66578. X     PAGE_DOWN       N\
  66579. X     LEFT_ARROW      H\
  66580. X     RIGHT_ARROW     L\
  66581. X     UP_ARROW        K\
  66582. X     DOWN_ARROW      J\
  66583. X     HOME            O\
  66584. X     END             E\
  66585. X     CTL_PLUS        \}\
  66586. X     CTL_MINUS       \{
  66587. X
  66588. XXfractint takes the following options:
  66589. X
  66590. X-onroot\
  66591. XPuts the image on the root window.
  66592. X
  66593. X-fast\
  66594. XUses a faster drawing technique.
  66595. X
  66596. X-disk\
  66597. XUses disk video.
  66598. X
  66599. X-geometry WxH[\{+-X}\{+-Y}]\
  66600. XChanges the geometry of the image window.
  66601. X
  66602. X-display displayname\
  66603. XSpecifies the X11 display to use.
  66604. X
  66605. X-private\
  66606. XAllocates the entire colormap (i.e. more colors).
  66607. X
  66608. X-share\
  66609. XShares the current colormap.
  66610. X
  66611. X-fixcolors n\
  66612. XUses only n colors.
  66613. X
  66614. X-slowdisplay\
  66615. XPrevents xfractint from hanging on the title page with slow displays.
  66616. X
  66617. X-simple\
  66618. XUses simpler keyboard handling, which makes debugging easier.
  66619. X
  66620. XCommon problems:
  66621. X
  66622. XIf you get the message "Couldn't find fractint.hlp", you can\
  66623. Xa) Do "setenv FRACTDIR /foo", replacing /foo with the directory containing
  66624. Xfractint.hlp.\
  66625. Xb) Run xfractint from the directory containing fractint.hlp, or\
  66626. Xc) Copy fractint.hlp to /usr/local/bin/X11/fractint
  66627. X
  66628. XIf you get the message "Invalid help signature", the problem is due to
  66629. Xbyteorder.  You are probably using a Sun help file on a Dec machine or
  66630. Xvice versa.
  66631. X
  66632. XIf xfractint doesn't accept input, try typing into both the graphics window
  66633. Xand the text window.  On some systems, only one of these works.
  66634. X
  66635. XIf you are using Openwindows and can't get xfractint to accept input, add
  66636. Xto your .Xdefaults file:\
  66637. XOpenWindows.FocusLenience:      True
  66638. X
  66639. XIf you cannot view the GIFs that xfractint creates, the problem is that
  66640. Xxfractint creates GIF89a format and your viewer probably only handles
  66641. XGIF87a format.  Run "xfractint gif87a=y" to produce GIF87a format.
  66642. X
  66643. XBecause many shifted characters are used to simulate IBM keys, you can't
  66644. Xenter capitalized filenames.
  66645. X;
  66646. X;
  66647. X;
  66648. X~Topic=Color Cycling Commands, Label=@ColorCycling
  66649. X
  66650. X~Doc-
  66651. XSee {=HELPCYCLING Color Cycling Command Summary} for a summary of commands.
  66652. X
  66653. X~Doc+
  66654. XColor-cycling mode is entered with the 'c', '+', or '-' keys from an image,
  66655. Xor with the 'c' key from Palette-Editing mode.
  66656. X
  66657. XThe color-cycling commands are available ONLY for VGA adapters and EGA
  66658. Xadapters in 640x350x16 mode.  You can also enter color-cycling while
  66659. Xusing a disk-video mode, to load or save a palette - other functions are
  66660. Xnot supported in disk-video.
  66661. X
  66662. XNote that the colors available on an EGA adapter (16 colors at a
  66663. Xtime out of a palette of 64) are limited compared to those of VGA, super-
  66664. XVGA, and MCGA (16 or 256 colors at a time out of a palette of 262,144). So
  66665. Xcolor-cycling in general looks a LOT better in the latter modes. Also,
  66666. Xbecause of the EGA palette restrictions, some commands are not available
  66667. Xwith EGA adapters.
  66668. X
  66669. XColor cycling applies to the color numbers selected by the "cyclerange="
  66670. Xcommand line parameter (also changeable via the <Y> options screen and via
  66671. Xthe palette editor).  By default, color numbers 1 to 255 inclusive are
  66672. Xcycled.  On some images you might want to set "inside=0" (<X> options or
  66673. Xcommand line parameter) to exclude the "lake" from color cycling.
  66674. X
  66675. XWhen you are in color-cycling mode, you will either see the screen colors
  66676. Xcycling, or will see a white "overscan" border when paused, as a reminder
  66677. Xthat you are still in this mode.  The keyboard commands available once
  66678. Xyou've entered color-cycling. are described below.
  66679. X
  66680. X<F1>\
  66681. XBring up a HELP screen with commands specific to color cycling mode.
  66682. X
  66683. X<Esc>\
  66684. XLeave color-cycling mode.
  66685. X
  66686. X<+> or <->\
  66687. XBegin cycling the palette by shifting each color to the next "contour."
  66688. X<+> cycles the colors in one direction, <-> in the other.
  66689. X
  66690. X'<' or '>'\
  66691. XForce a color-cycling pause, disable random colorizing, and single-step
  66692. Xthrough a one color-cycle.  For "fine-tuning" your image colors.
  66693. X
  66694. XCursor up/down\
  66695. XIncrease/decrease the cycling speed. High speeds may cause a harmless
  66696. Xflicker at the top of the screen.
  66697. X
  66698. X<F2> through <F10>\
  66699. XSwitches from simple rotation to color selection using randomly generated
  66700. Xcolor bands of short (F2) to long (F10) duration.
  66701. X
  66702. X<1> through <9>\
  66703. XCauses the screen to be updated every 'n' color cycles (the default is 1).
  66704. XHandy for slower computers.
  66705. X
  66706. X<Enter>\
  66707. XRandomly selects a function key (F2 through F10) and then updates ALL the
  66708. Xscreen colors prior to displaying them for instant, random colors.  Hit
  66709. Xthis over and over again (we do).
  66710. X
  66711. X<Spacebar>\
  66712. XPause cycling with white overscan area. Cycling restarts with any command
  66713. Xkey (including another spacebar).
  66714. X
  66715. X<Shift><F1>-<F10>\
  66716. XPause cycling and reset the palette to a preset two color "straight"
  66717. Xassignment, such as a spread from black to white. (Not for EGA)
  66718. X
  66719. X<Ctrl><F1>-<F10>\
  66720. XPause & set a 2-color cyclical assignment, e.g. red->yellow->red (not EGA).
  66721. X
  66722. X<Alt><F1>-<F10>\
  66723. XPause & set a 3-color cyclical assignment, e.g. green->white->blue (not EGA).
  66724. X
  66725. X<R>, <G>, <B>\
  66726. XPause and increase the red, green, or blue component of all colors by a
  66727. Xsmall amount (not for EGA). Note the case distinction of this vs:
  66728. X
  66729. X<r>, <g>, <b>\
  66730. XPause and decrease the red, green, or blue component of all colors by a
  66731. Xsmall amount (not for EGA).
  66732. X
  66733. X<D> or <A>\
  66734. XPause and load an external color map from the files DEFAULT.MAP or
  66735. XALTERN.MAP, supplied with the program.
  66736. X
  66737. X<L>\
  66738. XPause and load an external color map (.MAP file).  Several .MAP files are
  66739. Xsupplied with Fractint.  See {Palette Maps}.
  66740. X
  66741. X<S>\
  66742. XPause, prompt for a filename, and save the current palette to the named
  66743. Xfile (.MAP assumed).  See {Palette Maps}.
  66744. X;
  66745. X;
  66746. X;
  66747. X~Topic=Color Cycling Command Summary, Label=HELPCYCLING
  66748. X; This topic is online only
  66749. X
  66750. X~Format-
  66751. X  See {Color Cycling Commands} for full documentation.
  66752. X
  66753. X  F1           HELP! (Enter help mode and display this screen)
  66754. X  Esc           Exit from color-cycling mode
  66755. X  + or -       (re)-set the direction of the color-cycling
  66756. X~Doc-
  66757. X  \27 \26           (re)-set the direction of the color-cycling (just like +/-)
  66758. X  \24 \25           SpeedUp/SlowDown the color cycling process
  66759. X~Doc+,Online-
  66760. X  Right/Left Arrow (re)-set the direction of the color-cycling (just like +/-)
  66761. X  Up/Down Arrow    SpeedUp/SlowDown the color cycling process
  66762. X~Online+
  66763. X  F2 thru F10       Select Short--Medium--Long (randomly-generated) color bands
  66764. X  1  thru 9       Cycle through 'nn' colors between screen updates (default=1)
  66765. X  Enter        Randomly (re)-select all new colors    [TRY THIS ONE!]
  66766. X  Spacebar       Pause until another key is hit
  66767. X  < or >       Pause and single-step through one color-cycle
  66768. X* SF1 thru AF10    Pause and reset the Palette to one of 30 fixed sequences
  66769. X  d or a       pause and load the palette from DEFAULT.MAP or ALTERN.MAP
  66770. X  l           load palette from a map file
  66771. X  s           save palette to a map file
  66772. X* r or g or b or   force a pause and Lower (lower case) or Raise (upper case)
  66773. X* R or G or B       the Red, Green, or Blue component of the fractal image
  66774. X;
  66775. X;
  66776. X;
  66777. X~Topic=Palette Editing Commands
  66778. X
  66779. X~Doc-
  66780. XSee {=HELPXHAIR Palette Editing Command Summary} for a summary of commands.
  66781. X
  66782. X~Doc+
  66783. XPalette-editing mode provides a number of tools for modifying the colors
  66784. Xin an image.  It can be used only with MCGA or higher adapters, and only
  66785. Xwith 16 or 256 color video modes.
  66786. XMany thanks to Ethan Nagel for creating the palette editor.
  66787. X
  66788. XUse the <E> key to enter palette-editing mode from a displayed image or
  66789. Xfrom the main menu.
  66790. X
  66791. XWhen this mode is entered, an empty palette frame is displayed. You can
  66792. Xuse the cursor keys to position the frame outline, and <Pageup> and
  66793. X<Pagedn> to change its size.  (The upper and lower limits on the size
  66794. Xdepend on the current video mode.)  When the frame is positioned where you
  66795. Xwant it, hit Enter to display the current palette in the frame.
  66796. X
  66797. XNote that the palette frame shows R(ed) G(reen) and B(lue) values for two
  66798. Xcolor registers at the top.  The active color register has a solid frame,
  66799. Xthe inactive register's frame is dotted.  Within the active register, the
  66800. Xactive color component is framed.
  66801. X
  66802. XUsing the commands described below, you can assign particular colors to
  66803. Xthe registers and manipulate them.  Note that at any given time there are
  66804. Xtwo colors "X"d - these are pre-empted by the editor to display the
  66805. Xpalette frame. They can be edited but the results won't be visible. You
  66806. Xcan change which two colors are borrowed ("X"d out) by using the <v>
  66807. Xcommand.
  66808. X
  66809. XOnce the palette frame is displayed and filled in, the following commands
  66810. Xare available:
  66811. X
  66812. X<F1>\
  66813. XBring up a HELP screen with commands specific to palette-editing mode.
  66814. X
  66815. X<Esc>\
  66816. XLeave palette-editing mode
  66817. X
  66818. X<H>\
  66819. XHide the palette frame to see full image; the cross-hair remains visible
  66820. Xand all functions remain enabled; hit <H> again to restore the palette
  66821. Xdisplay.
  66822. X
  66823. XCursor keys\
  66824. XMove the cross-hair cursor around. In 'auto' mode (the default) the color
  66825. Xunder the center of the cross-hair is automatically assigned to the active
  66826. Xcolor register. Control-Cursor keys move the cross-hair faster. A mouse
  66827. Xcan also be used to move around.
  66828. X
  66829. X<R> <G> <B>\
  66830. XSelect the Red, Green, or Blue component of the active color register for
  66831. Xsubsequent commands
  66832. X
  66833. X<Insert> <Delete>\
  66834. XSelect previous or next color component in active register
  66835. X
  66836. X<+> <->\
  66837. XIncrease or decrease the active color component value by 1  Numeric keypad
  66838. X(gray) + and - keys do the same.
  66839. X
  66840. X<Pageup> <Pagedn>\
  66841. XIncrease or decrease the active color component value by 5; Moving the
  66842. Xmouse up/down with left button held is the same
  66843. X
  66844. X<0> <1> <2> <3> <4> <5>\
  66845. XSet the active color component's value to 0 10 20 ... 60
  66846. X
  66847. X<Space>\
  66848. XSelect the other color register as the active one.  In the default 'auto'
  66849. Xmode this results in the now-inactive register being set to remember the
  66850. Xcolor under the cursor, and the now-active register changing from whatever
  66851. Xit had previously remembered to now follow the color.
  66852. X
  66853. X<,> <.>\
  66854. XRotate the palette one step.  By default colors 1 through 255 inclusive
  66855. Xare rotated.  This range can be over-ridden with the "cyclerange"
  66856. Xparameter, the <Y> options screen, or the <O> command described below.
  66857. X
  66858. X"<" ">"\
  66859. XRotate the palette continuously (until next keystroke)
  66860. X
  66861. X<O>\
  66862. XSet the color cycling range to the range of colors currently defined by
  66863. Xthe color registers.
  66864. X
  66865. X<C>\
  66866. XEnter Color-Cycling Mode.  When you invoke color-cycling from here, it
  66867. Xwill subsequently return to palette-editing when you <Esc> from it.
  66868. XSee {Color Cycling Commands}.
  66869. X
  66870. X<=>\
  66871. XCreate a smoothly shaded range of colors between the colors selected by
  66872. Xthe two color registers.
  66873. X
  66874. X<M>\
  66875. XSpecify a gamma value for the shading created by <=>.
  66876. X
  66877. X<D>\
  66878. XDuplicate the inactive color register's values to the active color
  66879. Xregister.
  66880. X
  66881. X<T>\
  66882. XStripe-shade - create a smoothly shaded range of colors between the two
  66883. Xcolor registers, setting only every Nth register.  After hitting <T>, hit
  66884. Xa numeric key from 2 to 9 to specify N.  For example, if you press <T>
  66885. X<3>, smooth shading is done between the two color registers, affecting
  66886. Xonly every 3rd color between them.  The other colors between them remain
  66887. Xunchanged.
  66888. X
  66889. X<W>\
  66890. XConvert current palette to gray-scale.    (If the <X> or <Y> exclude ranges
  66891. Xdescribed later are in force, only the active range of colors is converted
  66892. Xto gray-scale.)
  66893. X
  66894. X<Shift-F2> ... <Shift-F9>\
  66895. XStore the current palette in a temporary save area associated with the
  66896. Xfunction key.  The temporary save palettes are useful for quickly
  66897. Xcomparing different palettes or the effect of some changes - see next
  66898. Xcommand.  The temporary palettes are only remembered until you exit from
  66899. Xpalette-editing mode.
  66900. X
  66901. X<F2> ... <F9>\
  66902. XRestore the palette from a temporary save area.  If you haven't previously
  66903. Xsaved a palette for the function key, you'll get a simple grey scale.
  66904. X
  66905. X<L>\
  66906. XPause and load an external color map (.MAP file).  See {Palette Maps}.
  66907. X
  66908. X<S>\
  66909. XPause, prompt for a filename, and save the current palette to the named
  66910. Xfile (.MAP assumed).  See {Palette Maps}.
  66911. X
  66912. X<I>\
  66913. XInvert frame colors.  With some colors the palette is easier to see when
  66914. Xthe frame colors are interchanged.
  66915. X~OnlineFF
  66916. X<\\>\
  66917. XMove or resize the palette frame.  The frame outline is drawn - it can
  66918. Xthen be repositioned and sized with the cursor keys, <Pageup> and
  66919. X<Pagedn>, just as was done when first entering palette-editing mode.  Hit
  66920. XEnter when done moving/sizing.
  66921. X
  66922. X<V>\
  66923. XUse the colors currently selected by the two color registers for the
  66924. Xpalette editor's frame.  When palette editing mode is entered, the last
  66925. Xtwo colors are "X"d out for use by the palette editor; this command can be
  66926. Xused to replace the default with two other color numbers.
  66927. X
  66928. X<A>\
  66929. XToggle 'auto' mode on or off.  When on (the default), the active color
  66930. Xregister follows the cursor; when off, <Enter> must be pressed to set the
  66931. Xactive register to the color under the cursor.
  66932. X
  66933. X<Enter>\
  66934. XOnly useful when 'auto' is off, as described above; double clicking the
  66935. Xleft mouse button is the same as Enter.
  66936. X
  66937. X<X>\
  66938. XToggle 'exclude' mode on or off - when toggled on, only those image pixels
  66939. Xwhich match the active color are displayed.
  66940. X
  66941. X<Y>\
  66942. XToggle 'exclude' range on or off - similar to <X>, but all pixels matching
  66943. Xcolors in the range of the two color registers are displayed.
  66944. X
  66945. X<N>\
  66946. XMake a negative color palette - will convert only current color if in 'x' 
  66947. Xmode or range between editors in 'y' mode or entire palette if in "normal" 
  66948. Xmode.
  66949. X
  66950. X<!>\
  66951. X<@>\
  66952. X<#>\
  66953. XSwap R<->G, G<->B, and R<->B columns. These keys are shifted 1, 2, and 3,
  66954. Xwhich you may find easier to remember.
  66955. X
  66956. X<U>\
  66957. XUndoes the last palette editor command.  Will undo all the way to the 
  66958. Xbeginning of the current session.
  66959. X~OnlineFF
  66960. X<E>
  66961. XRedoes the undone palette editor commands.
  66962. X
  66963. X<F>\
  66964. XToggles "Freestyle mode" on and off (Freestyle mode changes a range of
  66965. Xpalette values smoothly from a center value outward).
  66966. XWith your cursor inside the palette box, press the <F> key to enter
  66967. XFreestyle mode.  A default range of colors will be selected for you
  66968. Xcentered at the cursor (the ends of the color range are noted by putting
  66969. Xdashed lines around the corresponding palette values). While in Freestyle
  66970. Xmode:
  66971. X Moving the mouse changes the location of the range of colors that are
  66972. X affected.
  66973. X Control-Insert/Delete or the shifted-right-mouse-button changes the
  66974. X size of the affected palette range.
  66975. X The normal color editing keys (R,G,B,1-6, etc) set the central color
  66976. X of the affected palette range.
  66977. X~OnlineFF
  66978. X Pressing ENTER or double-clicking the left mouse button makes the
  66979. X palette changes permanent (if you don't perform this step, any
  66980. X palette changes disappear when you press the <F> key again to exit
  66981. X freestyle mode).
  66982. X;
  66983. X;
  66984. X;
  66985. X~Topic=Palette Editing Command Summary, Label=HELPXHAIR
  66986. X; This topic is online only.
  66987. X
  66988. X~Format-
  66989. X  See {Palette Editing Commands} for full documentation.
  66990. X
  66991. X  F1           HELP! (Enter help mode and display this screen)
  66992. X  Esc           Exit from palette editing mode
  66993. X  h           Hide/unhide the palette frame
  66994. X  Cursor keys       Move the cross-hair cursor around. Control-Cursor keys
  66995. X           move faster. A mouse can also be used to move around.
  66996. X  r or g or b       Select the the Red, Green, or Blue component of the
  66997. X           active color register for subsequent commands
  66998. X  Insert or Delete Select previous or next color component in active register
  66999. X  + or -       Increase or decrease the active color component by 1
  67000. X  Pageup or Pagedn Increase or decrease the active color component by 5;
  67001. X           Moving the mouse up/down with left button held is the same
  67002. X  0 1 2 3 4 5 6    Set active color component to 0 10 20 ... 60
  67003. X  Space        Select the other color register as the active one
  67004. X  , or .       Rotate the palette one step
  67005. X  < or >       Rotate the palette continuously (until next keystroke)
  67006. X  c           Enter Color-Cycling Mode (see {=HELPCYCLING Color Cycling Commands})
  67007. X  =           Create a smoothly shaded range of colors
  67008. X  m           Set the gamma value for '='.
  67009. X~FF
  67010. X  d           Duplicate the inactive color register in active color
  67011. X  t           Stripe-shade; after hitting 't', hit a number from 2 to 9
  67012. X           which is used as stripe width
  67013. X  Shift-F2,F3,..F9 Store the current palette in a temporary save area
  67014. X           associated with the function key
  67015. X  F2,F3,...,F9       Restore the palette from a temporary save area
  67016. X  w           Convert palette (or current exclude range) to gray-scale
  67017. X  \\            Move or resize the palette frame
  67018. X  i           Invert frame colors, useful with dark colors
  67019. X  a           Toggle 'auto' mode on or off - when on, the active color
  67020. X           register follows the cursor; when off, Enter must be hit
  67021. X           to set the register to the color under the cursor
  67022. X  Enter        Only useful when 'auto' is off, as described above; double
  67023. X           clicking the left mouse button is the same as Enter
  67024. X  x           Toggle 'exclude' mode on or off
  67025. X  y           Toggle 'exclude' range on or off
  67026. X  o           Set the 'cyclerange' (range affected by color cycling
  67027. X           commands) to the range of the two registers
  67028. X  n           Make a negative color palette
  67029. X  u           Undoes the last command
  67030. X  e           Redoes the last undone command
  67031. X~FF
  67032. X  !           Swap red and green columns
  67033. X  @           Swap green and blue columns
  67034. X  #           Swap red and blue columns
  67035. X  f                Enter Palette-Editing Mode.  See {Palette Editing Commands}
  67036. X                   for details.
  67037. X;
  67038. X;
  67039. X; Fractal Types:
  67040. X~Include help2.src
  67041. X;
  67042. X; Doodads, 3D:
  67043. X~Include help3.src
  67044. X;
  67045. X; Parameters, Video Adapters & Modes:
  67046. X~Include help4.src
  67047. X;
  67048. X; The rest:
  67049. X~Include help5.src
  67050. X;
  67051. X;
  67052. SHAR_EOF
  67053. $TOUCH -am 1028230193 help.src &&
  67054. chmod 0644 help.src ||
  67055. echo "restore of help.src failed"
  67056. set `wc -c help.src`;Wc_c=$1
  67057. if test "$Wc_c" != "76566"; then
  67058.     echo original size 76566, current size $Wc_c
  67059. fi
  67060. # ============= help2.src ==============
  67061. echo "x - extracting help2.src (Text)"
  67062. sed 's/^X//' << 'SHAR_EOF' > help2.src &&
  67063. X~Topic=Summary of Fractal Types, Label=HELPFRACTALS
  67064. X~Format-
  67065. X~Doc-
  67066. XFor detailed descriptions, select a hot-link below, see {Fractal Types},
  67067. Xor use <F2> from the fractal type selection screen.
  67068. X~Doc+,Online-
  67069. XSUMMARY OF FRACTAL TYPES
  67070. X~Online+
  67071. X~CompressSpaces-
  67072. X;
  67073. X; Note that prompts.c pulls formulas out of the following for <Z> screen,
  67074. X; using the HF_xxx labels.  It assumes a rigid formatting structure for
  67075. X; the formulas:
  67076. X;    4 leading blanks (which get stripped on <Z> screen)
  67077. X;    lines no wider than 76 characters (not counting initial 4 spaces)
  67078. X;    formula ends at any of:
  67079. X;    blank line
  67080. X;    line which begins in column 1
  67081. X;    format ctl char (~xxx, {xxx}, \x)
  67082. X;
  67083. X
  67084. X{=HT_BARNS barnsleyj1}
  67085. X~Label=HF_BARNSJ1
  67086. X      z(0) = pixel;
  67087. X      z(n+1) = (z-1)*c if real(z) >= 0, else
  67088. X      z(n+1) = (z+1)*c
  67089. X    Two parameters: real and imaginary parts of c
  67090. X{=HT_BARNS barnsleyj2}
  67091. X~Label=HF_BARNSJ2
  67092. X      z(0) = pixel;
  67093. X      if real(z(n)) * imag(c) + real(c) * imag(z((n)) >= 0
  67094. X     z(n+1) = (z(n)-1)*c
  67095. X      else
  67096. X     z(n+1) = (z(n)+1)*c
  67097. X    Two parameters: real and imaginary parts of c
  67098. X{=HT_BARNS barnsleyj3}
  67099. X~Label=HF_BARNSJ3
  67100. X      z(0) = pixel;
  67101. X      if real(z(n) > 0 then z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1)
  67102. X     + i * (2*real(z((n)) * imag(z((n))) else
  67103. X      z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1 + real(c) * real(z(n))
  67104. X         + i * (2*real(z((n)) * imag(z((n)) + imag(c) * real(z(n))
  67105. X    Two parameters: real and imaginary parts of c.
  67106. X~OnlineFF
  67107. X{=HT_BARNS barnsleym1}
  67108. X~Label=HF_BARNSM1
  67109. X      z(0) = c = pixel;
  67110. X      if real(z) >= 0 then
  67111. X    z(n+1) = (z-1)*c
  67112. X      else
  67113. X    z(n+1) = (z+1)*c.
  67114. X    Parameters are perturbations of z(0)
  67115. X{=HT_BARNS barnsleym2}
  67116. X~Label=HF_BARNSM2
  67117. X      z(0) = c = pixel;
  67118. X      if real(z)*imag(c) + real(c)*imag(z) >= 0
  67119. X    z(n+1) = (z-1)*c
  67120. X      else
  67121. X    z(n+1) = (z+1)*c
  67122. X    Parameters are perturbations of z(0)
  67123. X{=HT_BARNS barnsleym3}
  67124. X~Label=HF_BARNSM3
  67125. X      z(0) = c = pixel;
  67126. X      if real(z(n) > 0 then z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1)
  67127. X     + i * (2*real(z((n)) * imag(z((n))) else
  67128. X      z(n+1) = (real(z(n))^2 - imag(z(n))^2 - 1 + real(c) * real(z(n))
  67129. X     + i * (2*real(z((n)) * imag(z((n)) + imag(c) * real(z(n))
  67130. X    Parameters are perturbations of z(0)
  67131. X~OnlineFF
  67132. X
  67133. X{=HT_BIF bifurcation}
  67134. X~Label=HF_BIFURCATION
  67135. X    Pictorial representation of a population growth model.
  67136. X      Let P = new population, p = oldpopulation, r = growth rate
  67137. X      The model is: P = p + r*fn(p)*(1-fn(p)).
  67138. X    Three parameters: Filter Cycles, Seed Population, and Function.
  67139. X{=HT_BIF bif+sinpi}
  67140. X~Label=HF_BIFPLUSSINPI
  67141. X    Bifurcation variation: model is: P = p + r*fn(PI*p).
  67142. X    Three parameters: Filter Cycles, Seed Population, and Function.
  67143. X{=HT_BIF bif=sinpi}
  67144. X~Label=HF_BIFEQSINPI
  67145. X    Bifurcation variation: model is: P = r*fn(PI*p).
  67146. X    Three parameters: Filter Cycles, Seed Population, and Function.
  67147. X{=HT_BIF biflambda}
  67148. X~Label=HF_BIFLAMBDA
  67149. X    Bifurcation variation: model is: P = r*fn(p)*(1-fn(p)).
  67150. X    Three parameters: Filter Cycles, Seed Population, and Function.
  67151. X{=HT_BIF bifstewart}
  67152. X~Label=HF_BIFSTEWART
  67153. X    Bifurcation variation: model is: P = (r*fn(p)*fn(p)) - 1.
  67154. X    Three parameters: Filter Cycles, Seed Population, and Function.
  67155. X{=HT_BIF bifmay}
  67156. X~Label=HF_BIFMAY
  67157. X    Bifurcation variation: model is: P = r*p / ((1+p)^beta).
  67158. X    Three parameters: Filter Cycles, Seed Population, and Beta.
  67159. X~OnlineFF
  67160. X
  67161. X{=HT_CELLULAR cellular}
  67162. X~Label=HF_CELLULAR
  67163. X    One-dimensional cellular automata or line automata.  The type of CA
  67164. X    is given by kr, where k is the number of different states of the
  67165. X    automata and r is the radius of the neighborhood.  The next generation
  67166. X    is determined by the sum of the neighborhood and the specified rule.
  67167. X    Four parameters: Initial String, Rule, Type, and Starting Row Number.
  67168. X    For Type = 21, 31, 41, 51, 61, 22, 32, 42, 23, 33, 24, 25, 26, 27
  67169. X        Rule =  4,  7, 10, 13, 16,  6, 11, 16,  8, 15, 10, 12, 14, 16 digits
  67170. X
  67171. X{=HT_CIRCLE circle}
  67172. X~Label=HF_CIRCLE
  67173. X    Circle pattern by John Connett
  67174. X      x + iy = pixel
  67175. X      z = a*(x^2 + y^2)
  67176. X      c = integer part of z
  67177. X      color = c modulo(number of colors)
  67178. X
  67179. X{=HT_MARKS cmplxmarksjul}
  67180. X~Label=HF_CMPLXMARKSJUL
  67181. X    A generalization of the marksjulia fractal.
  67182. X      z(0) = pixel;
  67183. X      z(n+1) = (c^exp)*z(n)^2 + c.
  67184. X    Four parameters: real and imaginary parts of c and exp.
  67185. X~OnlineFF
  67186. X
  67187. X{=HT_MARKS cmplxmarksmand}
  67188. X~Label=HF_CMPLXMARKSMAND
  67189. X    A generalization of the marksmandel fractal.
  67190. X      z(0) = c = pixel;
  67191. X      z(n+1) = (c^exp)*z(n)^2 + c.
  67192. X    Four parameters: real and imaginary parts of
  67193. X    perturbation of z(0) and exp.
  67194. X
  67195. X{=HT_NEWTCMPLX complexnewton\, complexbasin}
  67196. X~Label=HF_COMPLEXNEWT
  67197. X    Newton fractal types extended to complex degrees. Complexnewton
  67198. X    colors pixels according to the number of iterations required to
  67199. X    escape to a root. Complexbasin colors pixels according to which
  67200. X    root captures the orbit. The equation is based on the newton
  67201. X    formula for solving the equation z^p = r
  67202. X      z(0) = pixel;
  67203. X      z(n+1) = ((p - 1) * z(n)^p + r)/(p * z(n)^(p - 1)).
  67204. X    Four parameters: real & imaginary parts of degree p and root r
  67205. X
  67206. X{=HT_DIFFUS diffusion}
  67207. X~Label=HF_DIFFUS
  67208. X    Diffusion Limited Aggregation.  Randomly moving points
  67209. X    accumulate.  Two parameters: border width (default 10), type
  67210. X~OnlineFF
  67211. X
  67212. X{=HT_DYNAM dynamic}
  67213. X~Label=HF_DYNAM
  67214. X    Time-discrete dynamic system.
  67215. X      x(0) = y(0) = start position.
  67216. X      y(n+1) = y(n) + f( x(n) )
  67217. X      x(n+1) = x(n) - f( y(n) )
  67218. X      f(k) = sin(k + a*fn1(b*k))
  67219. X    For implicit Euler approximation: x(n+1) = x(n) - f( y(n+1) )
  67220. X    Five parameters: start position step, dt, a, b, and the function fn1.
  67221. X
  67222. X{=HT_SCOTSKIN fn+fn(pix)}
  67223. X~Label=HF_FNPLUSFNPIX
  67224. X      c = z(0) = pixel;
  67225. X      z(n+1) = fn1(z) + p*fn2(c)
  67226. X    Six parameters: real and imaginary parts of the perturbation
  67227. X    of z(0) and factor p, and the functions fn1, and fn2.
  67228. X
  67229. X{=HT_SCOTSKIN fn(z*z)}
  67230. X~Label=HF_FNZTIMESZ
  67231. X      z(0) = pixel;
  67232. X      z(n+1) = fn(z(n)*z(n))
  67233. X    One parameter: the function fn.
  67234. X~OnlineFF
  67235. X
  67236. X{=HT_SCOTSKIN fn*fn}
  67237. X~Label=HF_FNTIMESFN
  67238. X      z(0) = pixel; z(n+1) = fn1(n)*fn2(n)
  67239. X    Two parameters: the functions fn1 and fn2.
  67240. X
  67241. X{=HT_SCOTSKIN fn*z+z}
  67242. X~Label=HF_FNXZPLUSZ
  67243. X      z(0) = pixel; z(n+1) = p1*fn(z(n))*z(n) + p2*z(n)
  67244. X    Five parameters: the real and imaginary components of
  67245. X    p1 and p2, and the function fn.
  67246. X
  67247. X{=HT_SCOTSKIN fn+fn}
  67248. X~Label=HF_FNPLUSFN
  67249. X      z(0) = pixel;
  67250. X      z(n+1) = p1*fn1(z(n))+p2*fn2(z(n))
  67251. X    Six parameters: The real and imaginary components of
  67252. X    p1 and p2, and the functions fn1 and fn2.
  67253. X
  67254. X{=HT_FORMULA formula}
  67255. X    Formula interpreter - write your own formulas as text files!
  67256. X~OnlineFF
  67257. X
  67258. X{=HT_FROTH frothybasin}
  67259. X~Label=HF_FROTH
  67260. X    Pixel color is determined by which attractor captures the orbit.  The
  67261. X    shade of color is determined by the number of iterations required to
  67262. X    capture the orbit.
  67263. X      z(0) = pixel;  z(n+1) = z(n)^2 - c*conj(z(n))
  67264. X      where c = 1 + ai,  and  a = 1.02871376822...
  67265. X
  67266. X{=HT_GINGER gingerbread}
  67267. X~Label=HF_GINGER
  67268. X    Orbit in two dimensions defined by:
  67269. X      x(n+1) = 1 - y(n) + |x(n)|
  67270. X      y(n+1) = x(n)
  67271. X    Two parameters: initial values of x(0) and y(0).
  67272. X
  67273. X{=HT_HALLEY halley}
  67274. X~Label=HF_HALLEY
  67275. X      Halley map for the function: F = z(z^a - 1) = 0
  67276. X      z(0) = pixel;
  67277. X      z(n+1) = z(n) - R * F / [F' - (F" * F / 2 * F')]
  67278. X      bailout when: abs(mod(z(n+1)) - mod(z(n)) < epsilon
  67279. X    Three parameters: order of z (a), relaxation coefficient (R),
  67280. X                      small number for bailout (epsilon).
  67281. X~OnlineFF
  67282. X{=HT_HENON henon}
  67283. X~Label=HF_HENON
  67284. X    Orbit in two dimensions defined by:
  67285. X      x(n+1) = 1 + y(n) - a*x(n)*x(n)
  67286. X      y(n+1) = b*x(n)
  67287. X    Two parameters: a and b
  67288. X
  67289. X{=HT_MARTIN hopalong}
  67290. X~Label=HF_HOPALONG
  67291. X    Hopalong attractor by Barry Martin - orbit in two dimensions.
  67292. X      z(0) = y(0) = 0;
  67293. X      x(n+1) = y(n) - sign(x(n))*sqrt(abs(b*x(n)-c))
  67294. X      y(n+1) = a - x(n)
  67295. X    Parameters are a, b, and c.
  67296. X
  67297. X{=HT_HYPERC hypercomplex}
  67298. X~Label=HF_HYPERC
  67299. X    HyperComplex Mandelbrot set.
  67300. X      h(0)   = (0,0,0,0)
  67301. X      h(n+1) = fn(h(n)) + C.
  67302. X      where "fn" is sin, cos, log, sqr etc.
  67303. X    Two parameters: cj, ck
  67304. X    C = (xpixel,ypixel,cj,ck)
  67305. X~OnlineFF
  67306. X
  67307. X{=HT_HYPERC hypercomplexj}
  67308. X~Label=HF_HYPERCJ
  67309. X    HyperComplex Julia set.
  67310. X      h(0)   = (xpixel,ypixel,zj,zk)
  67311. X      h(n+1) = fn(h(n)) + C.
  67312. X      where "fn" is sin, cos, log, sqr etc.
  67313. X    Six parameters: c1, ci, cj, ck
  67314. X    C = (c1,ci,cj,ck)
  67315. X
  67316. X{=HT_ICON icon, icon3d}
  67317. X~Label=HF_ICON
  67318. X    Orbit in three dimensions defined by:
  67319. X      p = lambda + alpha * magnitude + beta * (x(n)*zreal - y(n)*zimag)
  67320. X      x(n+1) = p * x(n) + gamma * zreal - omega * y(n)
  67321. X      y(n+1) = p * y(n) - gamma * zimag + omega * x(n)
  67322. X      (3D version uses magnitude for z)
  67323. X      Parameters:  Lambda, Alpha, Beta, Gamma, Omega, and Degree
  67324. X
  67325. X{=HT_IFS IFS}
  67326. X    Barnsley IFS (Iterated Function System) fractals. Apply
  67327. X    contractive affine mappings.
  67328. X~OnlineFF
  67329. X
  67330. X{=HT_PICKMJ julfn+exp}
  67331. X~Label=HF_JULFNPLUSEXP
  67332. X    A generalized Clifford Pickover fractal.
  67333. X      z(0) = pixel;
  67334. X      z(n+1) = fn(z(n)) + e^z(n) + c.
  67335. X    Three parameters: real & imaginary parts of c, and fn
  67336. X
  67337. X{=HT_PICKMJ julfn+zsqrd}
  67338. X~Label=HF_JULFNPLUSZSQRD
  67339. X      z(0) = pixel;
  67340. X      z(n+1) = fn(z(n)) + z(n)^2 + c
  67341. X    Three parameters: real & imaginary parts of c, and fn
  67342. X
  67343. X{=HT_JULIA julia}
  67344. X~Label=HF_JULIA
  67345. X    Classic Julia set fractal.
  67346. X      z(0) = pixel; z(n+1) = z(n)^2 + c.
  67347. X    Two parameters: real and imaginary parts of c.
  67348. X~OnlineFF
  67349. X
  67350. X{=HT_INVERSE julia_inverse}
  67351. X~Label=HF_INVERSE
  67352. X    Inverse Julia function - "orbit" traces Julia set in two dimensions.
  67353. X      z(0) = a point on the Julia Set boundary; z(n+1) = +- sqrt(z(n) - c)
  67354. X    Parameters: Real and Imaginary parts of c
  67355. X           Maximum Hits per Pixel (similar to max iters)
  67356. X           Breadth First, Depth First or Random Walk Tree Traversal
  67357. X           Left or Right First Branching (in Depth First mode only)
  67358. X        Try each traversal method, keeping everything else the same.
  67359. X        Notice the differences in the way the image evolves.  Start with
  67360. X        a fairly low Maximum Hit limit, then increase it.  The hit limit
  67361. X        cannot be higher than the maximum colors in your video mode.
  67362. X
  67363. X{=HT_FNORFN julia(fn||fn)}
  67364. X~Label=HF_JULIAFNFN
  67365. X      z(0) = pixel;
  67366. X      if modulus(z(n)) < shift value, then
  67367. X         z(n+1) = fn1(z(n)) + c,
  67368. X      else
  67369. X         z(n+1) = fn2(z(n)) + c.
  67370. X    Five parameters: real, imaginary portions of c, shift value,
  67371. X                     fn1 and fn2.
  67372. X~OnlineFF
  67373. X
  67374. X{=HT_MANDJUL4 julia4}
  67375. X~Label=HF_JULIA4
  67376. X    Fourth-power Julia set fractals, a special case
  67377. X    of julzpower kept for speed.
  67378. X      z(0) = pixel;
  67379. X      z(n+1) = z(n)^4 + c.
  67380. X    Two parameters: real and imaginary parts of c.
  67381. X
  67382. X{=HT_JULIBROT julibrot}
  67383. X    'Julibrot' 4-dimensional fractals.
  67384. X
  67385. X{=HT_PICKMJ julzpower}
  67386. X~Label=HF_JULZPOWER
  67387. X      z(0) = pixel;
  67388. X      z(n+1) = z(n)^m + c.
  67389. X    Three parameters: real & imaginary parts of c, exponent m
  67390. X
  67391. X{=HT_PICKMJ julzzpwr}
  67392. X~Label=HF_JULZZPWR
  67393. X      z(0) = pixel;
  67394. X      z(n+1) = z(n)^z(n) + z(n)^m + c.
  67395. X    Three parameters: real & imaginary parts of c, exponent m
  67396. X~OnlineFF
  67397. X
  67398. X{=HT_KAM kamtorus, kamtorus3d}
  67399. X~Label=HF_KAM
  67400. X    Series of orbits superimposed.
  67401. X    3d version has 'orbit' the z dimension.
  67402. X      x(0) = y(0) = orbit/3;
  67403. X      x(n+1) = x(n)*cos(a) + (x(n)*x(n)-y(n))*sin(a)
  67404. X      y(n+1) = x(n)*sin(a) - (x(n)*x(n)-y(n))*cos(a)
  67405. X    After each orbit, 'orbit' is incremented by a step size.
  67406. X    Parameters: a, step size, stop value for 'orbit', and
  67407. X    points per orbit.
  67408. X
  67409. X{=HT_LAMBDA lambda}
  67410. X~Label=HF_LAMBDA
  67411. X    Classic Lambda fractal. 'Julia' variant of Mandellambda.
  67412. X      z(0) = pixel;
  67413. X      z(n+1) = lambda*z(n)*(1 - z(n)).
  67414. X    Two parameters: real and imaginary parts of lambda.
  67415. X
  67416. X{=HT_LAMBDAFN lambdafn}
  67417. X~Label=HF_LAMBDAFN
  67418. X      z(0) = pixel;
  67419. X      z(n+1) = lambda * fn(z(n)).
  67420. X    Three parameters: real, imag portions of lambda, and fn
  67421. X~OnlineFF
  67422. X
  67423. X{=HT_FNORFN lambda(fn||fn)}
  67424. X~Label=HF_LAMBDAFNFN
  67425. X      z(0) = pixel;
  67426. X      if modulus(z(n)) < shift value, then
  67427. X         z(n+1) = lambda * fn1(z(n)),
  67428. X      else
  67429. X         z(n+1) = lambda * fn2(z(n)).
  67430. X    Five parameters: real, imaginary portions of lambda, shift value,
  67431. X                     fn1 and fn2.
  67432. X
  67433. X{=HT_LORENZ lorenz, lorenz3d}
  67434. X~Label=HF_LORENZ
  67435. X    Lorenz two lobe attractor - orbit in three dimensions.
  67436. X    In 2d the x and y components are projected to form the image.
  67437. X      z(0) = y(0) = z(0) = 1;
  67438. X      x(n+1) = x(n) + (-a*x(n)*dt) + (     a*y(n)*dt)
  67439. X      y(n+1) = y(n) + ( b*x(n)*dt) - (       y(n)*dt) - (z(n)*x(n)*dt)
  67440. X      z(n+1) = z(n) + (-c*z(n)*dt) + (x(n)*y(n)*dt)
  67441. X    Parameters are dt, a, b, and c.
  67442. X~OnlineFF
  67443. X
  67444. X{=HT_LORENZ lorenz3d1}
  67445. X~Label=HF_LORENZ3D1
  67446. X    Lorenz one lobe attractor - orbit in three dimensions.
  67447. X    The original formulas were developed by Rick Miranda and Emily Stone.
  67448. X      z(0) = y(0) = z(0) = 1; norm = sqrt(x(n)^2 + y(n)^2)
  67449. X      x(n+1) = x(n) + (-a*dt-dt)*x(n) + (a*dt-b*dt)*y(n) 
  67450. X         + (dt-a*dt)*norm + y(n)*dt*z(n)
  67451. X      y(n+1) = y(n) + (b*dt-a*dt)*x(n) - (a*dt+dt)*y(n) 
  67452. X         + (b*dt+a*dt)*norm - x(n)*dt*z(n) - norm*z(n)*dt
  67453. X      z(n+1) = z(n) +(y(n)*dt/2) - c*dt*z(n)
  67454. X    Parameters are dt, a, b, and c.
  67455. X~OnlineFF
  67456. X
  67457. X{=HT_LORENZ lorenz3d3}
  67458. X~Label=HF_LORENZ3D3
  67459. X    Lorenz three lobe attractor - orbit in three dimensions.
  67460. X    The original formulas were developed by Rick Miranda and Emily Stone.
  67461. X      z(0) = y(0) = z(0) = 1; norm = sqrt(x(n)^2 + y(n)^2)
  67462. X      x(n+1) = x(n) +(-(a*dt+dt)*x(n) + (a*dt-b*dt+z(n)*dt)*y(n))/3 
  67463. X          + ((dt-a*dt)*(x(n)^2-y(n)^2) 
  67464. X          + 2*(b*dt+a*dt-z(n)*dt)*x(n)*y(n))/(3*norm)
  67465. X      y(n+1) = y(n) +((b*dt-a*dt-z(n)*dt)*x(n) - (a*dt+dt)*y(n))/3 
  67466. X          + (2*(a*dt-dt)*x(n)*y(n) 
  67467. X          + (b*dt+a*dt-z(n)*dt)*(x(n)^2-y(n)^2))/(3*norm)
  67468. X      z(n+1) = z(n) +(3*x(n)*dt*x(n)*y(n)-y(n)*dt*y(n)^2)/2 - c*dt*z(n)
  67469. X    Parameters are dt, a, b, and c.
  67470. X~OnlineFF
  67471. X{=HT_LORENZ lorenz3d4}
  67472. X~Label=HF_LORENZ3D4
  67473. X    Lorenz four lobe attractor - orbit in three dimensions.
  67474. X    The original formulas were developed by Rick Miranda and Emily Stone.
  67475. X      z(0) = y(0) = z(0) = 1; 
  67476. X      x(n+1) = x(n) +(-a*dt*x(n)^3 
  67477. X         + (2*a*dt+b*dt-z(n)*dt)*x(n)^2*y(n) + (a*dt-2*dt)*x(n)*y(n)^2 
  67478. X         + (z(n)*dt-b*dt)*y(n)^3) / (2 * (x(n)^2+y(n)^2))
  67479. X      y(n+1) = y(n) +((b*dt-z(n)*dt)*x(n)^3 + (a*dt-2*dt)*x(n)^2*y(n) 
  67480. X         + (-2*a*dt-b*dt+z(n)*dt)*x(n)*y(n)^2 
  67481. X         - a*dt*y(n)^3) / (2 * (x(n)^2+y(n)^2))
  67482. X      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))
  67483. X    Parameters are dt, a, b, and c.
  67484. X
  67485. X{=HT_LSYS lsystem}
  67486. X    Using a turtle-graphics control language and starting with
  67487. X    an initial axiom string, carries out string substitutions the
  67488. X    specified number of times (the order), and plots the resulting.
  67489. X
  67490. X{=HT_LYAPUNOV lyapunov}
  67491. X    Derived from the Bifurcation fractal, the Lyapunov plots the Lyapunov
  67492. X    Exponent for a population model where the Growth parameter varies between
  67493. X    two values in a periodic manner.
  67494. X~OnlineFF
  67495. X
  67496. X{=HT_MAGNET magnet1j}
  67497. X~Label=HF_MAGJ1
  67498. X      z(0) = pixel;
  67499. X        [  z(n)^2 + (c-1)  ] 2
  67500. X      z(n+1) =    | ---------------- | 
  67501. X        [  2*z(n) + (c-2)  ]
  67502. X    Parameters: the real and imaginary parts of c
  67503. X
  67504. X{=HT_MAGNET magnet1m}
  67505. X~Label=HF_MAGM1
  67506. X      z(0) = 0; c = pixel;
  67507. X        [  z(n)^2 + (c-1)  ] 2
  67508. X      z(n+1) =    | ---------------- | 
  67509. X        [  2*z(n) + (c-2)  ]
  67510. X    Parameters: the real & imaginary parts of perturbation of z(0)
  67511. X
  67512. X{=HT_MAGNET magnet2j}
  67513. X~Label=HF_MAGJ2
  67514. X      z(0) = pixel;
  67515. X        [  z(n)^3 + 3*(C-1)*z(n) + (C-1)*(C-2)           ] 2
  67516. X      z(n+1) =    |  -------------------------------------------- |
  67517. X        [  3*(z(n)^2) + 3*(C-2)*z(n) + (C-1)*(C-2) + 1 ]
  67518. X    Parameters: the real and imaginary parts of c
  67519. X~OnlineFF
  67520. X{=HT_MAGNET magnet2m}
  67521. X~Label=HF_MAGM2
  67522. X      z(0) = 0; c = pixel;
  67523. X        [  z(n)^3 + 3*(C-1)*z(n) + (C-1)*(C-2)           ] 2
  67524. X      z(n+1) =    |  -------------------------------------------- |
  67525. X        [  3*(z(n)^2) + 3*(C-2)*z(n) + (C-1)*(C-2) + 1 ]
  67526. X    Parameters: the real and imaginary parts of perturbation of z(0)
  67527. X
  67528. X{=HT_MANDEL mandel}
  67529. X~Label=HF_MANDEL
  67530. X    Classic Mandelbrot set fractal.
  67531. X      z(0) = c = pixel;
  67532. X      z(n+1) = z(n)^2 + c.
  67533. X    Two parameters: real & imaginary perturbations of z(0)
  67534. X
  67535. X{=HT_FNORFN mandel(fn||fn)}
  67536. X~Label=HF_MANDELFNFN
  67537. X      c = pixel;
  67538. X      z(0) = p1
  67539. X      if modulus(z(n)) < shift value, then
  67540. X         z(n+1) = fn1(z(n)) + c,
  67541. X      else
  67542. X         z(n+1) = fn2(z(n)) + c.
  67543. X    Five parameters: real, imaginary portions of p1, shift value,
  67544. X                     fn1 and fn2.
  67545. X~OnlineFF
  67546. X
  67547. X{=HT_MANDELCLOUD mandelcloud}
  67548. X~Label=HF_MANDELCLOUD
  67549. X    Displays orbits of Mandelbrot set:
  67550. X      z(0) = c = pixel;
  67551. X      z(n+1) = z(n)^2 + c.
  67552. X    One parameter: number of intervals
  67553. X
  67554. X{=HT_MANDJUL4 mandel4}
  67555. X~Label=HF_MANDEL4
  67556. X    Special case of mandelzpower kept for speed.
  67557. X      z(0) = c = pixel;
  67558. X      z(n+1) = z(n)^4 + c.
  67559. X    Parameters: real & imaginary perturbations of z(0)
  67560. X
  67561. X{=HT_MANDFN mandelfn}
  67562. X~Label=HF_MANDFN
  67563. X      z(0) = c = pixel;
  67564. X      z(n+1) = c*fn(z(n)).
  67565. X    Parameters: real & imaginary perturbations of z(0), and fn
  67566. X~OnlineFF
  67567. X
  67568. X{=HT_FNORFN manlam(fn||fn)}
  67569. X~Label=HF_MANLAMFNFN
  67570. X      c = pixel;
  67571. X      z(0) = p1
  67572. X      if modulus(z(n)) < shift value, then
  67573. X         z(n+1) = fn1(z(n)) * c, else
  67574. X         z(n+1) = fn2(z(n)) * c.
  67575. X    Five parameters: real, imaginary parts of p1, shift value, fn1, fn2.
  67576. X
  67577. X{=HT_MARTIN Martin}
  67578. X~Label=HF_MARTIN
  67579. X    Attractor fractal by Barry Martin - orbit in two dimensions.
  67580. X      z(0) = y(0) = 0;
  67581. X      x(n+1) = y(n) - sin(x(n))
  67582. X      y(n+1) = a - x(n)
  67583. X    Parameter is a (try a value near pi)
  67584. X
  67585. X{=HT_MLAMBDA mandellambda}
  67586. X~Label=HF_MLAMBDA
  67587. X      z(0) = .5; lambda = pixel;
  67588. X      z(n+1) = lambda*z(n)*(1 - z(n)).
  67589. X    Parameters: real & imaginary perturbations of z(0)
  67590. X~OnlineFF
  67591. X
  67592. X{=HT_PHOENIX mandphoenix}
  67593. X~Label=HF_MANDPHOENIX
  67594. X      z(0) = p1, y(0) = 0;
  67595. X      For degree of Z = 0:
  67596. X        z(n+1) = z(n)^2 + pixel.x + (pixel.y)y(n), y(n+1) = z(n)
  67597. X      For degree of Z >= 2:
  67598. X        z(n+1) = z(n)^degree + pz(n)^(degree-1) + qy(n), y(n+1) = z(n)
  67599. X      For degree of Z <= -3:
  67600. X        z(n+1) = z(n)^|degree| + pz(n)^(|degree|-2) + qy(n), y(n+1) = z(n)
  67601. X    Three parameters: real part of z(0), imaginary part of z(0), and the
  67602. X      degree of Z.
  67603. X
  67604. X{=HT_PICKMJ manfn+exp}
  67605. X~Label=HF_MANDFNPLUSEXP
  67606. X    'Mandelbrot-Equivalent' for the julfn+exp fractal.
  67607. X      z(0) = c = pixel;
  67608. X      z(n+1) = fn(z(n)) + e^z(n) + C.
  67609. X    Parameters: real & imaginary perturbations of z(0), and fn
  67610. X~OnlineFF
  67611. X
  67612. X{=HT_PICKMJ manfn+zsqrd}
  67613. X~Label=HF_MANDFNPLUSZSQRD
  67614. X    'Mandelbrot-Equivalent' for the Julfn+zsqrd fractal.
  67615. X      z(0) = c = pixel;
  67616. X      z(n+1) = fn(z(n)) + z(n)^2 + c.
  67617. X    Parameters: real & imaginary perturbations of z(0), and fn
  67618. X
  67619. X{=HT_SCOTSKIN manowar}
  67620. X~Label=HF_MANOWAR
  67621. X      c = z1(0) = z(0) = pixel;
  67622. X      z(n+1) = z(n)^2 + z1(n) + c;
  67623. X      z1(n+1) = z(n);
  67624. X    Parameters: real & imaginary perturbations of z(0)
  67625. X
  67626. X{=HT_SCOTSKIN manowar}
  67627. X~Label=HF_MANOWARJ
  67628. X      z1(0) = z(0) = pixel;
  67629. X      z(n+1) = z(n)^2 + z1(n) + c;
  67630. X      z1(n+1) = z(n);
  67631. X    Parameters: real & imaginary perturbations of c
  67632. X~OnlineFF
  67633. X
  67634. X{=HT_PICKMJ manzpower}
  67635. X~Label=HF_MANZPOWER
  67636. X    'Mandelbrot-Equivalent' for julzpower.
  67637. X      z(0) = c = pixel;
  67638. X      z(n+1) = z(n)^exp + c; try exp = e = 2.71828...
  67639. X    Parameters: real & imaginary perturbations of z(0), real &
  67640. X    imaginary parts of exponent exp.
  67641. X
  67642. X{=HT_PICKMJ manzzpwr}
  67643. X~Label=HF_MANZZPWR
  67644. X    'Mandelbrot-Equivalent' for the julzzpwr fractal.
  67645. X      z(0) = c = pixel
  67646. X      z(n+1) = z(n)^z(n) + z(n)^exp + C.
  67647. X    Parameters: real & imaginary perturbations of z(0), and exponent
  67648. X
  67649. X{=HT_MARKS marksjulia}
  67650. X~Label=HF_MARKSJULIA
  67651. X    A variant of the julia-lambda fractal.
  67652. X      z(0) = pixel;
  67653. X      z(n+1) = (c^exp)*z(n)^2 + c.
  67654. X    Parameters: real & imaginary parts of c, and exponent
  67655. X~OnlineFF
  67656. X
  67657. X{=HT_MARKS marksmandel}
  67658. X~Label=HF_MARKSMAND
  67659. X    A variant of the mandel-lambda fractal.
  67660. X      z(0) = c = pixel;
  67661. X      z(n+1) = (c^exp)*z(n)^2 + c.
  67662. X    Parameters: real & imaginary perturbations of z(0), and exponent
  67663. X
  67664. X{=HT_MARKS marksmandelpwr}
  67665. X~Label=HF_MARKSMANDPWR
  67666. X    The marksmandelpwr formula type generalized (it previously
  67667. X    had fn=sqr hard coded).
  67668. X      z(0) = pixel, c = z(0) ^ (z(0) - 1):
  67669. X      z(n+1) = c * fn(z(n)) + pixel,
  67670. X    Parameters: real and imaginary perturbations of z(0), and fn
  67671. X
  67672. X{=HT_NEWTBAS newtbasin}
  67673. X~Label=HF_NEWTBAS
  67674. X    Based on the Newton formula for finding the roots of z^p - 1.
  67675. X    Pixels are colored according to which root captures the orbit.
  67676. X      z(0) = pixel;
  67677. X      z(n+1) = ((p-1)*z(n)^p + 1)/(p*z(n)^(p - 1)).
  67678. X    Two parameters: the polynomial degree p, and a flag to turn
  67679. X    on color stripes to show alternate iterations.
  67680. X~OnlineFF
  67681. X
  67682. X{=HT_NEWT newton}
  67683. X~Label=HF_NEWT
  67684. X    Based on the Newton formula for finding the roots of z^p - 1.
  67685. X    Pixels are colored according to the iteration when the orbit
  67686. X    is captured by a root.
  67687. X      z(0) = pixel;
  67688. X      z(n+1) = ((p-1)*z(n)^p + 1)/(p*z(n)^(p - 1)).
  67689. X    One parameter: the polynomial degree p.
  67690. X
  67691. X{=HT_PHOENIX phoenix}
  67692. X~Label=HF_PHOENIX
  67693. X      z(0) = pixel, y(0) = 0;
  67694. X      For degree of Z = 0: z(n+1) = z(n)^2 + p + qy(n), y(n+1) = z(n)
  67695. X      For degree of Z >= 2:
  67696. X        z(n+1) = z(n)^degree + pz(n)^(degree-1) + qy(n), y(n+1) = z(n)
  67697. X      For degree of Z <= -3:
  67698. X        z(n+1) = z(n)^|degree| + pz(n)^(|degree|-2) + qy(n), y(n+1) = z(n)
  67699. X    Three parameters: real p, real q, and the degree of Z.
  67700. X~OnlineFF
  67701. X{=HT_PICK pickover}
  67702. X~Label=HF_PICKOVER
  67703. X    Orbit in three dimensions defined by:
  67704. X      x(n+1) = sin(a*y(n)) - z(n)*cos(b*x(n))
  67705. X      y(n+1) = z(n)*sin(c*x(n)) - cos(d*y(n))
  67706. X      z(n+1) = sin(x(n))
  67707. X    Parameters: a, b, c, and d.
  67708. X
  67709. X{=HT_PLASMA plasma}
  67710. X~Label=HF_PLASMA
  67711. X    Random, cloud-like formations.  Requires 4 or more colors.
  67712. X    A recursive algorithm repeatedly subdivides the screen and
  67713. X    colors pixels according to an average of surrounding pixels
  67714. X    and a random color, less random as the grid size decreases.
  67715. X    Four parameters: 'graininess' (.5 to 50, default = 2), old/new
  67716. X    algorithm, seed value used, 16-bit out output selection.
  67717. X
  67718. X{=HT_POPCORN popcorn}
  67719. X~Label=HF_POPCORN
  67720. X    The orbits in two dimensions defined by:
  67721. X      x(0) = xpixel, y(0) = ypixel;
  67722. X      x(n+1) = x(n) - h*sin(y(n) + tan(3*y(n))
  67723. X      y(n+1) = y(n) - h*sin(x(n) + tan(3*x(n))
  67724. X    are plotted for each screen pixel and superimposed.
  67725. X    One parameter: step size h.
  67726. X~OnlineFF
  67727. X
  67728. X{=HT_POPCORN popcornjul}
  67729. X~Label=HF_POPCJUL
  67730. X    Conventional Julia using the popcorn formula:
  67731. X      x(0) = xpixel, y(0) = ypixel;
  67732. X      x(n+1) = x(n) - h*sin(y(n) + tan(3*y(n))
  67733. X      y(n+1) = y(n) - h*sin(x(n) + tan(3*x(n))
  67734. X    One parameter: step size h.
  67735. X
  67736. X{=HT_QUAT quatjul}
  67737. X~Label=HF_QUATJ
  67738. X    Quaternion Julia set.
  67739. X      q(0)   = (xpixel,ypixel,zj,zk)
  67740. X      q(n+1) = q(n)*q(n) + c.
  67741. X    Four parameters: c, ci, cj, ck
  67742. X    c = (c1,ci,cj,ck)
  67743. X
  67744. X{=HT_QUAT quat}
  67745. X~Label=HF_QUAT
  67746. X    Quaternion Mandelbrot set.
  67747. X      q(0)   = (0,0,0,0)
  67748. X      q(n+1) = q(n)*q(n) + c.
  67749. X    Two parameters: cj,ck
  67750. X    c = (xpixel,ypixel,cj,ck)
  67751. X~OnlineFF
  67752. X
  67753. X{=HT_ROSS rossler3D}
  67754. X~Label=HF_ROSS
  67755. X    Orbit in three dimensions defined by:
  67756. X      x(0) = y(0) = z(0) = 1;
  67757. X      x(n+1) = x(n) - y(n)*dt -   z(n)*dt
  67758. X      y(n+1) = y(n) + x(n)*dt + a*y(n)*dt
  67759. X      z(n+1) = z(n) + b*dt + x(n)*z(n)*dt - c*z(n)*dt
  67760. X    Parameters are dt, a, b, and c.
  67761. X
  67762. X{=HT_SIER sierpinski}
  67763. X~Label=HF_SIER
  67764. X    Sierpinski gasket - Julia set producing a 'Swiss cheese triangle'
  67765. X      z(n+1) = (2*x,2*y-1) if y > .5;
  67766. X      else (2*x-1,2*y) if x > .5;
  67767. X      else (2*x,2*y)
  67768. X    No parameters.
  67769. X
  67770. X{=HT_SCOTSKIN spider}
  67771. X~Label=HF_SPIDER
  67772. X      c(0) = z(0) = pixel;
  67773. X      z(n+1) = z(n)^2 + c(n);
  67774. X      c(n+1) = c(n)/2 + z(n+1)
  67775. X    Parameters: real & imaginary perturbation of z(0)
  67776. X~OnlineFF
  67777. X
  67778. X{=HT_SCOTSKIN sqr(1/fn)}
  67779. X~Label=HF_SQROVFN
  67780. X      z(0) = pixel;
  67781. X      z(n+1) = (1/fn(z(n))^2
  67782. X    One parameter: the function fn.
  67783. X
  67784. X{=HT_SCOTSKIN sqr(fn)}
  67785. X~Label=HF_SQRFN
  67786. X      z(0) = pixel;
  67787. X      z(n+1) = fn(z(n))^2
  67788. X    One parameter: the function fn.
  67789. X
  67790. X{=HT_TEST test}
  67791. X~Label=HF_TEST
  67792. X    'test' point letting us (and you!) easily add fractal types via
  67793. X    the c module testpt.c.  Default set up is a mandelbrot fractal.
  67794. X    Four parameters: user hooks (not used by default testpt.c).
  67795. X
  67796. X{=HT_SCOTSKIN tetrate}
  67797. X~Label=HF_TETRATE
  67798. X      z(0) = c = pixel;
  67799. X      z(n+1) = c^z(n)
  67800. X    Parameters: real & imaginary perturbation of z(0)
  67801. X~OnlineFF
  67802. X
  67803. X{=HT_MARKS tim's_error}
  67804. X~Label=HF_TIMSERR
  67805. X    A serendipitous coding error in marksmandelpwr brings to life
  67806. X    an ancient pterodactyl!  (Try setting fn to sqr.)
  67807. X      z(0) = pixel, c = z(0) ^ (z(0) - 1):
  67808. X      tmp = fn(z(n))
  67809. X      real(tmp) = real(tmp) * real(c) - imag(tmp) * imag(c);
  67810. X      imag(tmp) = real(tmp) * imag(c) - imag(tmp) * real(c);
  67811. X      z(n+1) = tmp + pixel;
  67812. X    Parameters: real & imaginary perturbations of z(0) and function fn
  67813. X
  67814. X{=HT_UNITY unity}
  67815. X~Label=HF_UNITY
  67816. X      z(0) = pixel;
  67817. X      x = real(z(n)), y = imag(z(n))
  67818. X      One = x^2 + y^2;
  67819. X      y = (2 - One) * x;
  67820. X      x = (2 - One) * y;
  67821. X      z(n+1) = x + i*y
  67822. X    No parameters.
  67823. X~CompressSpaces+
  67824. X;
  67825. X;
  67826. X;
  67827. X~Topic=Fractal Types
  67828. X
  67829. XA list of the fractal types and their mathematics can be found in the
  67830. X{Summary of Fractal Types}.  Some notes about how Fractint calculates
  67831. Xthem are in "A Little Code" in {"Fractals and the PC"}.
  67832. X
  67833. XFractint starts by default with the Mandelbrot set. You can change that by
  67834. Xusing the command-line argument "TYPE=" followed by one of the
  67835. Xfractal type names, or by using the <T> command and
  67836. Xselecting the type - if parameters are needed, you will be prompted for
  67837. Xthem.
  67838. X
  67839. XIn the text that follows, due to the limitations of the ASCII character
  67840. Xset, "a*b" means "a times b", and "a^b" means "a to the power b".
  67841. X
  67842. X~Doc-
  67843. XPress <PageDown> for type selection list.
  67844. X~FF
  67845. XSelect a fractal type:
  67846. X
  67847. X~Table=40 2 0
  67848. X{ The Mandelbrot Set }
  67849. X{ Julia Sets }
  67850. X{ Inverse Julias }
  67851. X{ Newton domains of attraction }
  67852. X{ Newton }
  67853. X{ Complex Newton }
  67854. X{ Lambda Sets }
  67855. X{ Mandellambda Sets }
  67856. X{ Plasma Clouds }
  67857. X{ Lambdafn }
  67858. X{ Mandelfn }
  67859. X{ Barnsley Mandelbrot/Julia Sets }
  67860. X{ Barnsley IFS Fractals }
  67861. X{ Sierpinski Gasket }
  67862. X{ Quartic Mandelbrot/Julia }
  67863. X{ Distance Estimator }
  67864. X{ Pickover Mandelbrot/Julia Types }
  67865. X{ Pickover Popcorn }
  67866. X{ Dynamic System }
  67867. X{ Quaternion }
  67868. X{ Peterson Variations }
  67869. X{ Unity }
  67870. X{ Circle }
  67871. X{ Scott Taylor / Lee Skinner Variations }
  67872. X{ Kam Torus }
  67873. X{ Bifurcation }
  67874. X{ Orbit Fractals }
  67875. X{ Lorenz Attractors }
  67876. X{ Rossler Attractors }
  67877. X{ Henon Attractors }
  67878. X{ Pickover Attractors }
  67879. X{ Martin Attractors }
  67880. X{ Gingerbreadman }
  67881. X{ Test }
  67882. X{ Formula }
  67883. X{ Julibrots }
  67884. X{ Diffusion Limited Aggregation }
  67885. X{ Magnetic Fractals }
  67886. X{ L-Systems }
  67887. X{ Lyapunov Fractals }
  67888. X{ fn||fn Fractals }
  67889. X{ Halley }
  67890. X{ Cellular Automata }
  67891. X{ Phoenix }
  67892. X{ Frothy Basins }
  67893. X{ Icon }
  67894. X{ Hypercomplex }
  67895. X~EndTable
  67896. X~Doc+
  67897. X;
  67898. X;
  67899. X~Topic=The Mandelbrot Set, Label=HT_MANDEL
  67900. X(type=mandel)
  67901. X
  67902. XThis set is the classic: the only one implemented in many plotting
  67903. Xprograms, and the source of most of the printed fractal images published
  67904. Xin recent years. Like most of the other types in Fractint, it is simply a
  67905. Xgraph: the x (horizontal) and y (vertical) coordinate axes represent
  67906. Xranges of two independent quantities, with various colors used to
  67907. Xsymbolize levels of a third quantity which depends on the first two. So
  67908. Xfar, so good: basic analytic geometry.
  67909. X
  67910. XNow things get a bit hairier. The x axis is ordinary, vanilla real
  67911. Xnumbers. The y axis is an imaginary number, i.e. a real number times i,
  67912. Xwhere i is the square root of -1. Every point on the plane -- in this
  67913. Xcase, your PC's display screen -- represents a complex number of the form:
  67914. X
  67915. X    x-coordinate + i * y-coordinate
  67916. X
  67917. XIf your math training stopped before you got to imaginary and complex
  67918. Xnumbers, this is not the place to catch up. Suffice it to say that they
  67919. Xare just as "real" as the numbers you count fingers with (they're used
  67920. Xevery day by electrical engineers) and they can undergo the same kinds of
  67921. Xalgebraic operations.
  67922. X
  67923. XOK, now pick any complex number -- any point on the complex plane -- and
  67924. Xcall it C, a constant. Pick another, this time one which can vary, and
  67925. Xcall it Z. Starting with Z=0 (i.e., at the origin, where the real and
  67926. Ximaginary axes cross), calculate the value of the expression
  67927. X
  67928. X    Z^2 + C
  67929. X
  67930. XTake the result, make it the new value of the variable Z, and calculate
  67931. Xagain. Take that result, make it Z, and do it again, and so on: in
  67932. Xmathematical terms, iterate the function Z(n+1) = Z(n)^2 + C. For certain
  67933. Xvalues of C, the result "levels off" after a while. For all others, it
  67934. Xgrows without limit. The Mandelbrot set you see at the start -- the solid-
  67935. Xcolored lake (blue by default), the blue circles sprouting from it, and
  67936. Xindeed every point of that color -- is the set of all points C for which
  67937. Xthe value of Z is less than 2 after 150 iterations (150 is the default setting,
  67938. Xchangeable via the <X> options screen or "maxiter=" parameter).
  67939. XAll the surrounding "contours" of other colors represent points for which Z
  67940. Xexceeds 2 after 149 iterations (the contour closest to the M-set itself),
  67941. X148 iterations, (the next one out), and so on.
  67942. X
  67943. XWe actually don't test for Z exceeding 2 - we test Z squared against 4
  67944. Xinstead because it is easier.  This value (FOUR usually) is known as the
  67945. X"bailout" value for the calculation, because we stop iterating for the
  67946. Xpoint when it is reached.  The bailout value can be changed on the <Z>
  67947. Xoptions screen but the default is usually best.
  67948. X
  67949. XSome features of interest:
  67950. X
  67951. X1. Use the <X> options screen to increase the maximum number of iterations.
  67952. XNotice that the boundary of the M-set becomes more and more convoluted (the
  67953. Xtechnical terms are "wiggly," "squiggly," and "utterly bizarre") as the Z-
  67954. Xvalues for points that were still within the set after 150 iterations turn
  67955. Xout to exceed 2 after 200, 500, or 1200. In fact, it can be proven that
  67956. Xthe true boundary is infinitely long: detail without limit.
  67957. X
  67958. X2. Although there appear to be isolated "islands" of blue, zoom in -- that
  67959. Xis, plot for a smaller range of coordinates to show more detail -- and
  67960. Xyou'll see that there are fine "causeways" of blue connecting them to the
  67961. Xmain set. As you zoomed, smaller islands became visible; the same is true
  67962. Xfor them. In fact, there are no isolated points in the M-set: it is
  67963. X"connected" in a strict mathematical sense.
  67964. X
  67965. X3. The upper and lower halves of the first image are symmetric (a fact
  67966. Xthat Fractint makes use of here and in some other fractal types to speed
  67967. Xplotting). But notice that the same general features -- lobed discs,
  67968. Xspirals, starbursts -- tend to repeat themselves (although never exactly)
  67969. Xat smaller and smaller scales, so that it can be impossible to judge by
  67970. Xeye the scale of a given image.
  67971. X
  67972. X4. In a sense, the contour colors are window-dressing: mathematically, it
  67973. Xis the properties of the M-set itself that are interesting, and no
  67974. Xinformation about it would be lost if all points outside the set were
  67975. Xassigned the same color. If you're a serious, no-nonsense type, you may
  67976. Xwant to cycle the colors just once to see the kind of silliness that other
  67977. Xpeople enjoy, and then never do it again. Go ahead. Just once, now. We
  67978. Xtrust you.
  67979. X;
  67980. X;
  67981. X~Topic=Julia Sets, Label=HT_JULIA
  67982. X(type=julia)
  67983. X
  67984. XThese sets were named for mathematician Gaston Julia, and can be generated
  67985. Xby a simple change in the iteration process described for the
  67986. X{=HT_MANDEL Mandelbrot Set}.  Start with a
  67987. Xspecified value of C, "C-real + i * C-imaginary"; use as the initial value
  67988. Xof Z "x-coordinate + i * y-coordinate"; and repeat the same iteration,
  67989. XZ(n+1) = Z(n)^2 + C.
  67990. X
  67991. XThere is a Julia set corresponding to every point on the complex plane --
  67992. Xan infinite number of Julia sets. But the most visually interesting tend
  67993. Xto be found for the same C values where the M-set image is busiest, i.e.
  67994. Xpoints just outside the boundary. Go too far inside, and the corresponding
  67995. XJulia set is a circle; go too far outside, and it breaks up into scattered
  67996. Xpoints. In fact, all Julia sets for C within the M-set share the
  67997. X"connected" property of the M-set, and all those for C outside lack it.
  67998. X
  67999. XFractint's spacebar toggle lets you "flip" between any view of the M-set
  68000. Xand the Julia set for the point C at the center of that screen. You can
  68001. Xthen toggle back, or zoom your way into the Julia set for a while and then
  68002. Xreturn to the M-set. So if the infinite complexity of the M-set palls,
  68003. Xremember: each of its infinite points opens up a whole new Julia set.
  68004. X
  68005. XHistorically, the Julia sets came first: it was while looking at the M-set
  68006. Xas an "index" of all the Julia sets' origins that Mandelbrot noticed its
  68007. Xproperties.
  68008. X
  68009. XThe relationship between the {=HT_MANDEL Mandelbrot} set and Julia set can
  68010. Xhold between
  68011. Xother sets as well.  Many of Fractint's types are "Mandelbrot/Julia" pairs
  68012. X(sometimes called "M-sets" or "J-sets". All these are generated by
  68013. Xequations that are of the form z(k+1) = f(z(k),c), where the function
  68014. Xorbit is the sequence z(0), z(1), ..., and the variable c is a complex
  68015. Xparameter of the equation. The value c is fixed for "Julia" sets and is
  68016. Xequal to the first two parameters entered with the "params=Creal/Cimag"
  68017. Xcommand. The initial orbit value z(0) is the complex number corresponding
  68018. Xto the screen pixel. For Mandelbrot sets, the parameter c is the complex
  68019. Xnumber corresponding to the screen pixel. The value z(0) is c plus a
  68020. Xperturbation equal to the values of the first two parameters.  See
  68021. Xthe discussion of {=HT_MLAMBDA Mandellambda Sets}.
  68022. XThis approach may or may not be the
  68023. X"standard" way to create "Mandelbrot" sets out of "Julia" sets.
  68024. X
  68025. XSome equations have additional parameters.  These values are entered as the
  68026. Xthird for fourth params= value for both Julia and Mandelbrot sets. The
  68027. Xvariables x and y refer to the real and imaginary parts of z; similarly,
  68028. Xcx and cy are the real and imaginary parts of the parameter c and fx(z)
  68029. Xand fy(z) are the real and imaginary parts of f(z). The variable c is
  68030. Xsometimes called lambda for historical reasons.
  68031. X
  68032. XNOTE: if you use the "PARAMS=" argument to warp the M-set by starting with
  68033. Xan initial value of Z other than 0, the M-set/J-sets correspondence breaks
  68034. Xdown and the spacebar toggle no longer works.
  68035. X;
  68036. X;
  68037. X~Topic=Julia Toggle Spacebar Commands, Label=HELP_JIIM
  68038. XThe spacebar toggle has been enhanced for the classic Mandelbrot and Julia 
  68039. Xtypes. When viewing the Mandelbrot, the spacebar turns on a window mode that 
  68040. Xdisplays the Inverse Julia corresponding to the cursor position in a window. 
  68041. XPressing the spacebar then causes the regular Julia escape time fractal 
  68042. Xcorresponding to the cursor position to be generated. The following keys 
  68043. Xtake effect in Inverse Julia mode. 
  68044. X
  68045. X<Space>     Generate the escape-time Julia Set corresponding to the cursor\
  68046. X            position. Only works if fractal is a "Mandelbrot" type.\
  68047. X<n>         Numbers toggle - shows coordinates of the cursor on the\ 
  68048. X            screen. Press <n> again to turn off numbers.\
  68049. X<p>         Enter new pixel coordinates directly\ 
  68050. X<h>         Hide fractal toggle. Works only if View Windows is turned on\ 
  68051. X            and set for a small window (such as the default size.) Hides \ 
  68052. X            the fractal, allowing the orbit to take up the whole screen. \
  68053. X            Press <h> again to uncover the fractal.\
  68054. X<s>         Saves the fractal, cursor, orbits, and numbers.\
  68055. X<<> or <,>  Zoom inverse julia image smaller.\
  68056. X<>> or <.>  Zoom inverse julia image larger.\
  68057. X<z>         Restore default zoom.\
  68058. X
  68059. XThe Julia Inverse window is only implemented for the classic Mandelbrot
  68060. X(type=mandel). For other "Mandelbrot" types <space> turns on the cursor 
  68061. Xwithout the Julia window, and allows you to select coordinates of the
  68062. Xmatching Julia set in a way similar to the use of the zoom box with the 
  68063. XMandelbrot/Julia toggle in previous Fractint versions.
  68064. X;
  68065. X;
  68066. X~Topic=Inverse Julias, Label=HT_INVERSE
  68067. X(type=julia_inverse)
  68068. X
  68069. XPick a function, such as the familiar Z(n) = Z(n-1) squared plus C
  68070. X(the defining function of the Mandelbrot Set).  If you pick a point Z(0)
  68071. Xat random from the complex plane, and repeatedly apply the function to it,
  68072. Xyou get a sequence of new points called an orbit, which usually either 
  68073. Xzips out toward infinity or zooms in toward one or more "attractor" points
  68074. Xnear the middle of the plane.  The set of all points that are "attracted"
  68075. Xto infinity is called the "Basin of Attraction" of infinity.  Each of the
  68076. Xother attractors also has its own Basin of Attraction.  Why is it called
  68077. Xa Basin?  Imagine a lake, and all the water in it "draining" into the
  68078. Xattractor.  The boundary between these basins is called the Julia Set of
  68079. Xthe function.
  68080. X
  68081. XThe boundary between the basins of attraction is sort of like a 
  68082. Xrepeller; all orbits move away from it, toward one of the attractors.
  68083. XBut if we define a new function as the inverse of the old one, as for
  68084. Xinstance Z(n) = sqrt(Z(n-1) minus C), then the old attractors become
  68085. Xrepellers, and the former boundary itself becomes the attractor!  Now,
  68086. Xstarting from any point, all orbits are drawn irresistibly to the Julia
  68087. XSet!  In fact, once an orbit reaches the boundary, it will continue to
  68088. Xhop about until it traces the entire Julia Set!  This method for drawing
  68089. XJulia Sets is called the Inverse Iteration Method, or IIM for short.
  68090. X
  68091. XUnfortunately, some parts of each Julia Set boundary are far more 
  68092. Xattractive to inverse orbits than others are, so that as an orbit 
  68093. Xtraces out the set, it keeps coming back to these attractive parts
  68094. Xagain and again, only occasionally visiting the less attractive parts.
  68095. XThus it may take an infinite length of time to draw the entire set.
  68096. XTo hasten the process, we can keep track of how many times each pixel
  68097. Xon our computer screen is visited by an orbit, and whenever an orbit
  68098. Xreaches a pixel that has already been visited more than a certain number
  68099. Xof times, we can consider that orbit finished and move on to another one.
  68100. XThis "hit limit" thus becomes similar to the iteration limit used in the
  68101. Xtraditional escape-time fractal algorithm.  This is called the Modified
  68102. XInverse Iteration Method, or MIIM, and is much faster than the IIM.
  68103. X
  68104. XNow, the inverse of Mandelbrot's classic function is a square root, and
  68105. Xthe square root actually has two solutions; one positive, one negative.
  68106. XTherefore at each step of each orbit of the inverse function there is
  68107. Xa decision; whether to use the positive or the negative square root.  
  68108. XEach one gives rise to a new point on the Julia Set, so each is a good
  68109. Xchoice.  This series of choices defines a binary decision tree, each
  68110. Xpoint on the Julia Set giving rise to two potential child points.  
  68111. XThere are many interesting ways to traverse a binary tree, among them
  68112. XBreadth first, Depth first (left or negative first), Depth first (right
  68113. Xor positive first), and completely at random.  It turns out that most 
  68114. Xtraversal methods lead to the same or similar pictures, but that how the
  68115. Ximage evolves as the orbits trace it out differs wildly depending on the
  68116. Xtraversal method chosen.  As far as I know, this fact is an original 
  68117. Xdiscovery, and this version of FRACTINT is its first publication.
  68118. X
  68119. XPick a Julia constant such as Z(0) = (-.74543, .11301), the popular
  68120. XSeahorse Julia, and try drawing it first Breadth first, then Depth first
  68121. X(right first), Depth first (left first), and finally with Random Walk.
  68122. X
  68123. XCaveats: the video memory is used in the algorithm, to keep track of 
  68124. Xhow many times each pixel has been visited (by changing it's color). 
  68125. XTherefore the algorithm will not work well if you zoom in far enough that
  68126. Xpart of the Julia Set is off the screen.
  68127. X
  68128. XBugs:   Not working with Disk Video.
  68129. X        Not resumeable.
  68130. X
  68131. XThe <J> key toggles between the Inverse Julia orbit and the 
  68132. Xcorresponding Julia escape time fractal.
  68133. X;
  68134. X;
  68135. X~Topic=Newton domains of attraction, Label=HT_NEWTBAS
  68136. X(type=newtbasin)
  68137. X
  68138. XThe Newton formula is an algorithm used to find the roots of polynomial
  68139. Xequations by successive "guesses" that converge on the correct value as
  68140. Xyou feed the results of each approximation back into the formula. It works
  68141. Xvery well -- unless you are unlucky enough to pick a value that is on a
  68142. Xline BETWEEN two actual roots. In that case, the sequence explodes into
  68143. Xchaos, with results that diverge more and more wildly as you continue the
  68144. Xiteration.
  68145. X
  68146. XThis fractal type shows the results for the polynomial Z^n - 1, which has
  68147. Xn roots in the complex plane. Use the <T>ype command and enter "newtbasin"
  68148. Xin response to the prompt. You will be asked for a parameter, the "order"
  68149. Xof the equation (an integer from 3 through 10 -- 3 for x^3-1, 7 for x^7-1,
  68150. Xetc.). A second parameter is a flag to turn on alternating shades showing
  68151. Xchanges in the number of iterations needed to attract an orbit. Some
  68152. Xpeople like stripes and some don't, as always, Fractint gives you a
  68153. Xchoice!
  68154. X
  68155. XThe coloring of the plot shows the "basins of attraction" for each root of
  68156. Xthe polynomial -- i.e., an initial guess within any area of a given color
  68157. Xwould lead you to one of the roots. As you can see, things get a bit weird
  68158. Xalong certain radial lines or "spokes," those being the lines between
  68159. Xactual roots. By "weird," we mean infinitely complex in the good old
  68160. Xfractal sense. Zoom in and see for yourself.
  68161. X
  68162. XThis fractal type is symmetric about the origin, with the number of
  68163. X"spokes" depending on the order you select. It uses floating-point math if
  68164. Xyou have an FPU, or a somewhat slower integer algorithm if you don't have
  68165. Xone.
  68166. X~Doc-
  68167. X
  68168. XSee also: {Newton}
  68169. X~Doc+
  68170. X;
  68171. X;
  68172. X~Topic=Newton, Label=HT_NEWT
  68173. X(type=newton)
  68174. X
  68175. XThe generating formula here is identical to that for {=HT_NEWTBAS newtbasin},
  68176. Xbut the
  68177. Xcoloring scheme is different. Pixels are colored not according to the root
  68178. Xthat would be "converged on" if you started using Newton's formula from
  68179. Xthat point, but according to the iteration when the value is close to a
  68180. Xroot.  For example, if the calculations for a particular pixel converge to
  68181. Xthe 7th root on the 23rd iteration, NEWTBASIN will color that pixel using
  68182. Xcolor #7, but NEWTON will color it using color #23.
  68183. X
  68184. XIf you have a 256-color mode, use it: the effects can be much livelier
  68185. Xthan those you get with type=newtbasin, and color cycling becomes, like,
  68186. Xdownright cosmic. If your "corners" choice is symmetrical, Fractint
  68187. Xexploits the symmetry for faster display.
  68188. X
  68189. XThe applicable "params=" values are the same as newtbasin. Try "params=4."
  68190. XOther values are 3 through 10. 8 has twice the symmetry and is faster. As
  68191. Xwith newtbasin, an FPU helps.
  68192. X;
  68193. X;
  68194. X~Topic=Complex Newton, Label=HT_NEWTCMPLX
  68195. X(type=complexnewton/complexbasin)
  68196. X
  68197. XWell, hey, "Z^n - 1" is so boring when you can use "Z^a - b" where "a" and
  68198. X"b" are complex numbers!  The new "complexnewton" and "complexbasin"
  68199. Xfractal types are just the old {=HT_NEWT "newton"} and
  68200. X{=HT_NEWTBAS "newtbasin"} fractal types with
  68201. Xthis little added twist.  When you select these fractal types, you are
  68202. Xprompted for four values (the real and imaginary portions of "a" and "b").
  68203. XIf "a" has a complex portion, the fractal has a discontinuity along the
  68204. Xnegative axis - relax, we finally figured out that it's *supposed* to be
  68205. Xthere!
  68206. X;
  68207. X;
  68208. X~Topic=Lambda Sets, Label=HT_LAMBDA
  68209. X(type=lambda)
  68210. X
  68211. XThis type calculates the Julia set of the formula lambda*Z*(1-Z). That is,
  68212. Xthe value Z[0] is initialized with the value corresponding to each pixel
  68213. Xposition, and the formula iterated. The pixel is colored according to the
  68214. Xiteration when the sum of the squares of the real and imaginary parts
  68215. Xexceeds 4.
  68216. X
  68217. XTwo parameters, the real and imaginary parts of lambda, are required. Try
  68218. X0 and 1 to see the classical fractal "dragon". Then try 0.2 and 1 for a
  68219. Xlot more detail to zoom in on.
  68220. X
  68221. XIt turns out that all quadratic Julia-type sets can be calculated using
  68222. Xjust the formula z^2+c (the "classic" Julia"), so that this type is
  68223. Xredundant, but we include it for reason of it's prominence in the history
  68224. Xof fractals.
  68225. X;
  68226. X;
  68227. X~Topic=Mandellambda Sets, Label=HT_MLAMBDA
  68228. X(type=mandellambda)
  68229. X
  68230. XThis type is the "Mandelbrot equivalent" of the {=HT_LAMBDA lambda} set.
  68231. XA comment is
  68232. Xin order here. Almost all the Fractint "Mandelbrot" sets are created from
  68233. Xorbits generated using formulas like z(n+1) = f(z(n),C), with z(0) and C
  68234. Xinitialized to the complex value corresponding to the current pixel. Our
  68235. Xreasoning was that "Mandelbrots" are maps of the corresponding "Julias".
  68236. XUsing this scheme each pixel of a "Mandelbrot" is colored the same as the
  68237. XJulia set corresponding to that pixel. However, Kevin Allen informs us
  68238. Xthat the MANDELLAMBDA set appears in the literature with z(0) initialized
  68239. Xto a critical point (a point where the derivative of the formula is zero),
  68240. Xwhich in this case happens to be the point (.5,0). Since Kevin knows more
  68241. Xabout Dr. Mandelbrot than we do, and Dr. Mandelbrot knows more about
  68242. Xfractals than we do, we defer! Starting with version 14 Fractint
  68243. Xcalculates MANDELAMBDA Dr. Mandelbrot's way instead of our way. But ALL
  68244. XTHE OTHER "Mandelbrot" sets in Fractint are still calculated OUR way!
  68245. X(Fortunately for us, for the classic Mandelbrot Set these two methods are
  68246. Xthe same!)
  68247. X
  68248. XWell now, folks, apart from questions of faithfulness to fractals named in
  68249. Xthe literature (which we DO take seriously!), if a formula makes a
  68250. Xbeautiful fractal, it is not wrong. In fact some of the best fractals in
  68251. XFractint are the results of mistakes! Nevertheless, thanks to Kevin for
  68252. Xkeeping us accurate!
  68253. X
  68254. X(See description of "initorbit=" command in {Image Calculation Parameters}
  68255. Xfor a way to experiment with different orbit intializations).
  68256. X;
  68257. X;
  68258. X~Topic=Circle, Label=HT_CIRCLE
  68259. X(type=circle)
  68260. X
  68261. XThis fractal types is from A. K. Dewdney's "Computer Recreations" column
  68262. Xin "Scientific American". It is attributed to John Connett of the 
  68263. XUniversity of Minnesota.
  68264. X
  68265. X(Don't tell anyone, but this fractal type is not really a fractal!)
  68266. X
  68267. XFascinating Moire patterns can be formed by calculating x^2 + y^2 for
  68268. Xeach pixel in a piece of the complex plane. After multiplication by a 
  68269. Xmagnification factor (the parameter), the number is truncated to an integer 
  68270. Xand mapped to a color via color = value modulo (number of colors). That is, 
  68271. Xthe integer is divided by the number of colors, and the remainder is the 
  68272. Xcolor index value used.  The resulting image is not a fractal because all 
  68273. Xdetail is lost after zooming in too far. Try it with different resolution 
  68274. Xvideo modes - the results may surprise you!
  68275. X;
  68276. X;
  68277. X~Topic=Plasma Clouds, Label=HT_PLASMA
  68278. X(type=plasma)
  68279. X
  68280. XPlasma clouds ARE real live fractals, even though we didn't know it at
  68281. Xfirst. They are generated by a recursive algorithm that randomly picks
  68282. Xcolors of the corner of a rectangle, and then continues recursively
  68283. Xquartering previous rectangles. Random colors are averaged with those of
  68284. Xthe outer rectangles so that small neighborhoods do not show much change,
  68285. Xfor a smoothed-out, cloud-like effect. The more colors your video mode
  68286. Xsupports, the better.  The result, believe it or not, is a fractal
  68287. Xlandscape viewed as a contour map, with colors indicating constant
  68288. Xelevation.  To see this, save and view with the <3> command
  68289. X(see {\"3D\" Images})
  68290. Xand your "cloud" will be converted to a mountain!
  68291. X
  68292. XYou've GOT to try {=@ColorCycling color cycling} on these (hit "+" or "-").
  68293. XIf you
  68294. Xhaven't been hypnotized by the drawing process, the writhing colors will
  68295. Xdo it for sure. We have now implemented subliminal messages to exploit the
  68296. Xuser's vulnerable state; their content varies with your bank balance,
  68297. Xpolitics, gender, accessibility to a Fractint programmer, and so on. A
  68298. Xfree copy of Microsoft C to the first person who spots them.
  68299. X
  68300. XThis type accepts four parameters.
  68301. X
  68302. XThe first determines how abruptly the colors change. A value of .5 yields
  68303. Xbland clouds, while 50 yields very grainy ones. The default value is 2.
  68304. X
  68305. XThe second determines whether to use the original algorithm (0) or a
  68306. Xmodified one (1). The new one gives the same type of images but draws
  68307. Xthe dots in a different order. It will let you see
  68308. Xwhat the final image will look like much sooner than the old one.
  68309. X
  68310. XThe third determines whether to use a new seed for generating the
  68311. Xnext plasma cloud (0) or to use the previous seed (1).
  68312. X
  68313. XThe fourth parameter turns on 16-bit .POT output which provides much
  68314. Xsmoother height gradations. This is especially useful for creating 
  68315. Xmountain landscapes when using the plasma output with a ray tracer
  68316. Xsuch as POV-Ray.
  68317. X
  68318. XWith parameter three set to 1, the next plasma cloud generated will be 
  68319. Xidentical to the previous but at whatever new resolution is desired.
  68320. X
  68321. XZooming is ignored, as each plasma-cloud screen is generated randomly.
  68322. X
  68323. XThe random number seed used for each plasma image is displayed on the
  68324. X<tab> information screen, and can be entered with the command line
  68325. Xparameter "rseed=" to recreate a particular image. 
  68326. X
  68327. XThe algorithm is based on the Pascal program distributed by Bret Mulvey as
  68328. XPLASMA.ARC. We have ported it to C and integrated it with Fractint's
  68329. Xgraphics and animation facilities. This implementation does not use
  68330. Xfloating-point math. The algorithm was modified starting with version 18 
  68331. Xso that the plasma effect is independent of screen resolution.
  68332. X
  68333. XSaved plasma-cloud screens are EXCELLENT starting images for fractal
  68334. X"landscapes" created with the {\"3D\" commands}.
  68335. X;
  68336. X;
  68337. X~Topic=Lambdafn, Label=HT_LAMBDAFN
  68338. X(type=lambdafn)
  68339. X
  68340. XFunction=[sin|cos|sinh|cosh|exp|log|sqr|...]) is specified with this type.
  68341. XPrior to version 14, these types were lambdasine, lambdacos, lambdasinh,
  68342. Xlambdacos, and lambdaexp.  Where we say "lambdasine" or some such below,
  68343. Xthe good reader knows we mean "lambdafn with function=sin".)
  68344. X
  68345. XThese types calculate the Julia set of the formula lambda*fn(Z), for
  68346. Xvarious values of the function "fn", where lambda and Z are both complex.
  68347. XTwo values, the real and imaginary parts of lambda, should be given in the
  68348. X"params=" option.  For the feathery, nested spirals of LambdaSines and the
  68349. Xfrost-on-glass patterns of LambdaCosines, make the real part = 1, and try
  68350. Xvalues for the imaginary part ranging from 0.1 to 0.4 (hint: values near
  68351. X0.4 have the best patterns). In these ranges the Julia set "explodes". For
  68352. Xthe tongues and blobs of LambdaExponents, try a real part of 0.379 and an
  68353. Ximaginary part of 0.479.
  68354. X
  68355. XA coprocessor used to be almost mandatory: each LambdaSine/Cosine
  68356. Xiteration calculates a hyperbolic sine, hyperbolic cosine, a sine, and a
  68357. Xcosine (the LambdaExponent iteration "only" requires an exponent, sine,
  68358. Xand cosine operation)!    However, Fractint now computes these
  68359. Xtranscendental functions with fast integer math. In a few cases the fast
  68360. Xmath is less accurate, so we have kept the old slow floating point code.
  68361. XTo use the old code, invoke with the float=yes option, and, if you DON'T
  68362. Xhave a coprocessor, go on a LONG vacation!
  68363. X;
  68364. X;
  68365. X~Topic=Halley, Label=HT_HALLEY
  68366. X(type=halley)
  68367. X
  68368. XThe Halley map is an algorithm used to find the roots of polynomial
  68369. Xequations by successive "guesses" that converge on the correct value as
  68370. Xyou feed the results of each approximation back into the formula. It works
  68371. Xvery well -- unless you are unlucky enough to pick a value that is on a
  68372. Xline BETWEEN two actual roots. In that case, the sequence explodes into
  68373. Xchaos, with results that diverge more and more wildly as you continue the
  68374. Xiteration.
  68375. X
  68376. XThis fractal type shows the results for the polynomial Z(Z^a - 1), which
  68377. Xhas a+1 roots in the complex plane. Use the <T>ype command and enter
  68378. X"halley" in response to the prompt. You will be asked for a parameter, the
  68379. X"order" of the equation (an integer from 2 through 10 -- 2 for Z(Z^2 - 1),
  68380. X7 for Z(Z^7 - 1), etc.). A second parameter is the relaxation coefficient,
  68381. Xand is used to control the convergence stability. A number greater than
  68382. Xone increases the chaotic behavior and a number less than one decreases the
  68383. Xchaotic behavior. The third parameter is the value used to determine when
  68384. Xthe formula has converged. The test for convergence is
  68385. X||Z(n+1)|^2 - |Z(n)|^2| < epsilon. This convergence test produces the
  68386. Xwhisker-like projections which generally point to a root.
  68387. X;
  68388. X;
  68389. X~Topic=Phoenix, Label=HT_PHOENIX
  68390. X(type=phoenix, mandphoenix)
  68391. X
  68392. XThe phoenix type defaults to the original phoenix curve discovered by
  68393. XShigehiro Ushiki, "Phoenix", IEEE Transactions on Circuits and Systems,
  68394. XVol. 35, No. 7, July 1988, pp. 788-789.  These images do not have the
  68395. XX and Y axis swapped as is normal for this type.
  68396. X
  68397. XThe mandphoenix type is the corresponding Mandelbrot set image of the
  68398. Xphoenix type.  The spacebar toggles between the two as long as the
  68399. Xmandphoenix type has an initial Z(0) of (0,0).  The mandphoenix is not
  68400. Xan effective index to the phoenix type, so explore the wild blue yonder.
  68401. X
  68402. XTo reproduce the Mandelbrot set image of the phoenix type as shown in
  68403. XStevens' book, "Fractal Programming in C", set initorbit=0/0 on the
  68404. Xcommand line or with the <g> key.  The colors need to be rotated one
  68405. Xposition because Stevens uses the values from the previous calculation
  68406. Xinstead of the current calculation to determine when to bailout.
  68407. X;
  68408. X;
  68409. X~Topic=fn||fn Fractals, Label=HT_FNORFN
  68410. X(type=lambda(fn||fn), manlam(fn||fn), julia(fn||fn), mandel(fn||fn))
  68411. X
  68412. XTwo functions=[sin|cos|sinh|cosh|exp|log|sqr|...]) are specified with
  68413. Xthese types.  The two functions are alternately used in the calculation
  68414. Xbased on a comparison between the modulus of the current Z and the
  68415. Xshift value.  The first function is used if the modulus of Z is less
  68416. Xthan the shift value and the second function is used otherwise.
  68417. X
  68418. XThe lambda(fn||fn) type calculates the Julia set of the formula
  68419. Xlambda*fn(Z), for various values of the function "fn", where lambda
  68420. Xand Z are both complex.  Two values, the real and imaginary parts of
  68421. Xlambda, should be given in the "params=" option.  The third value is
  68422. Xthe shift value.  The space bar will generate the corresponding
  68423. X"psuedo Mandelbrot" set, manlam(fn||fn).
  68424. X
  68425. XThe manlam(fn||fn) type calculates the "psuedo Mandelbrot" set of the
  68426. Xformula fn(Z)*C, for various values of the function "fn", where C
  68427. Xand Z are both complex.  Two values, the real and imaginary parts of
  68428. XZ(0), should be given in the "params=" option.  The third value is
  68429. Xthe shift value.  The space bar will generate the corresponding
  68430. Xjulia set, lamda(fn||fn).
  68431. X
  68432. XThe julia(fn||fn) type calculates the Julia set of the formula
  68433. Xfn(Z)+C, for various values of the function "fn", where C
  68434. Xand Z are both complex.  Two values, the real and imaginary parts of
  68435. XC, should be given in the "params=" option.  The third value is
  68436. Xthe shift value.  The space bar will generate the corresponding
  68437. Xmandelbrot set, mandel(fn||fn).
  68438. X
  68439. XThe mandel(fn||fn) type calculates the Mandelbrot set of the formula
  68440. Xfn(Z)+C, for various values of the function "fn", where C
  68441. Xand Z are both complex.  Two values, the real and imaginary parts of
  68442. XZ(0), should be given in the "params=" option.  The third value is
  68443. Xthe shift value.  The space bar will generate the corresponding
  68444. Xjulia set, julia(fn||fn).
  68445. X;
  68446. X;
  68447. X~Topic=Mandelfn, Label=HT_MANDFN
  68448. X(type=mandelfn)
  68449. X
  68450. XFunction=[sin|cos|sinh|cosh|exp|log|sqr|...]) is specified with this type.
  68451. XPrior to version 14, these types were mandelsine, mandelcos, mandelsinh,
  68452. Xmandelcos, and mandelexp. Same comment about our lapses into the old
  68453. Xterminology as above!
  68454. X
  68455. XThese are "pseudo-Mandelbrot" mappings for the {=HT_LAMBDAFN LambdaFn}
  68456. XJulia functions.
  68457. XThey map to their corresponding Julia sets via the spacebar command in
  68458. Xexactly the same fashion as the original M/J sets.  In general, they are
  68459. Xinteresting mainly because of that property (the function=exp set in
  68460. Xparticular is rather boring). Generate the appropriate "Mandelfn" set,
  68461. Xzoom on a likely spot where the colors are changing rapidly, and hit the
  68462. Xspacebar key to plot the Julia set for that particular point.
  68463. X
  68464. XTry "FRACTINT TYPE=MANDELFN CORNERS=4.68/4.76/-.03/.03 FUNCTION=COS" for a
  68465. Xgraphic demonstration that we're not taking Mandelbrot's name in vain
  68466. Xhere. We didn't even know these little buggers were here until Mark
  68467. XPeterson found this a few hours before the version incorporating Mandelfns
  68468. Xwas released.
  68469. X
  68470. XNote: If you created images using the lambda or mandel "fn" types prior to
  68471. Xversion 14, and you wish to update the fractal information in the "*.fra"
  68472. Xfile, simply read the files and save again. You can do this in batch mode
  68473. Xvia a command line such as:
  68474. X
  68475. X     "fractint oldfile.fra savename=newfile.gif batch=yes"
  68476. X
  68477. XFor example, this procedure can convert a version 13 "type=lambdasine"
  68478. Ximage to a version 14 "type=lambdafn function=sin" GIF89a image.  We do
  68479. Xnot promise to keep this "backward compatibility" past version 14 - if you
  68480. Xwant to keep the fractal information in your *.fra files accurate, we
  68481. Xrecommend conversion.  See {GIF Save File Format}.
  68482. X;
  68483. X;
  68484. X~Topic=Barnsley Mandelbrot/Julia Sets, Label=HT_BARNS
  68485. X(type=barnsleym1/.../j3)
  68486. X
  68487. XMichael Barnsley has written a fascinating college-level text, "Fractals
  68488. XEverywhere," on fractal geometry and its graphic applications. (See
  68489. X{Bibliography}.) In it, he applies the principle of the M and J
  68490. Xsets to more general functions of two complex variables.
  68491. X
  68492. XWe have incorporated three of Barnsley's examples in Fractint. Their
  68493. Xappearance suggests polarized-light microphotographs of minerals, with
  68494. Xpatterns that are less organic and more crystalline than those of the M/J
  68495. Xsets. Each example has both a "Mandelbrot" and a "Julia" type. Toggle
  68496. Xbetween them using the spacebar.
  68497. X
  68498. XThe parameters have the same meaning as they do for the "regular"
  68499. XMandelbrot and Julia. For types M1, M2, and M3, they are used to "warp"
  68500. Xthe image by setting the initial value of Z. For the types J1 through J3,
  68501. Xthey are the values of C in the generating formulas.
  68502. X
  68503. XBe sure to try the <O>rbit function while plotting these types.
  68504. X;
  68505. X;
  68506. X~Topic=Barnsley IFS Fractals, Label=HT_IFS
  68507. X(type=ifs)
  68508. X
  68509. XOne of the most remarkable spin-offs of fractal geometry is the ability to
  68510. X"encode" realistic images in very small sets of numbers -- parameters for
  68511. Xa set of functions that map a region of two-dimensional space onto itself.
  68512. XIn principle (and increasingly in practice), a scene of any level of
  68513. Xcomplexity and detail can be stored as a handful of numbers, achieving
  68514. Xamazing "compression" ratios... how about a super-VGA image of a forest,
  68515. Xmore than 300,000 pixels at eight bits apiece, from a 1-KB "seed" file?
  68516. X
  68517. XAgain, Michael Barnsley and his co-workers at the Georgia Institute of
  68518. XTechnology are to be thanked for pushing the development of these iterated
  68519. Xfunction systems (IFS).
  68520. X
  68521. XWhen you select this fractal type, Fractint scans the current IFS file
  68522. X(default is FRACTINT.IFS, a set of definitions supplied with Fractint) for
  68523. XIFS definitions, then prompts you for the IFS name you wish to run. Fern
  68524. Xand 3dfern are good ones to start with. You can press <F6> at the
  68525. Xselection screen if you want to select a different .IFS file you've
  68526. Xwritten.
  68527. X
  68528. XNote that some Barnsley IFS values generate images quite a bit smaller
  68529. Xthan the initial (default) screen. Just bring up the zoom box, center it
  68530. Xon the small image, and hit <Enter> to get a full-screen image.
  68531. X
  68532. XTo change the number of dots Fractint generates for an IFS image before
  68533. Xstopping, you can change the "maximum iterations" parameter on the <X>
  68534. Xoptions screen.
  68535. X
  68536. XFractint supports two types of IFS images: 2D and 3D. In order to fully
  68537. Xappreciate 3D IFS images, since your monitor is presumably 2D, we have
  68538. Xadded rotation, translation, and perspective capabilities. These share
  68539. Xvalues with the same variables used in Fractint's other 3D facilities; for
  68540. Xtheir meaning see {"Rectangular Coordinate Transformation"}.
  68541. XYou can enter these values from the command line using:
  68542. X
  68543. Xrotation=xrot/yrot/zrot       (try 30/30/30)\
  68544. Xshift=xshift/yshift          (shifts BEFORE applying perspective!)\
  68545. Xperspective=viewerposition    (try 200)\
  68546. X
  68547. XAlternatively, entering <I> from main screen will allow you to modify
  68548. Xthese values. The defaults are the same as for regular 3D, and are not
  68549. Xalways optimum for 3D IFS. With the 3dfern IFS type, try
  68550. Xrotation=30/30/30. Note that applying shift when using perspective changes
  68551. Xthe picture -- your "point of view" is moved.
  68552. X
  68553. XA truly wild variation of 3D may be seen by entering "2" for the stereo
  68554. Xmode (see {"Stereo 3D Viewing"}),
  68555. Xputting on red/blue "funny glasses", and watching the fern develop
  68556. Xwith full depth perception right there before your eyes!
  68557. X
  68558. XThis feature USED to be dedicated to Bruce Goren, as a bribe to get him to
  68559. Xsend us MORE knockout stereo slides of 3D ferns, now that we have made it
  68560. Xso easy! Bruce, what have you done for us *LATELY* ?? (Just kidding,
  68561. Xreally!)
  68562. X
  68563. XEach line in an IFS definition (look at FRACTINT.IFS with your editor for
  68564. Xexamples) contains the parameters for one of the generating functions,
  68565. Xe.g. in FERN:
  68566. X~Format-
  68567. X   a    b     c    d    e    f      p
  68568. X ___________________________________
  68569. X   0     0    0  .16    0    0     .01
  68570. X .85   .04 -.04  .85    0  1.6     .85
  68571. X .2   -.26  .23  .22    0  1.6     .07
  68572. X-.15   .28  .26  .24    0  .44     .07
  68573. X
  68574. XThe values on each line define a matrix, vector, and probability:
  68575. X    matrix   vector  prob
  68576. X    |a b|     |e|     p
  68577. X    |c d|     |f|
  68578. X~Format+
  68579. X
  68580. XThe "p" values are the probabilities assigned to each function (how often
  68581. Xit is used), which add up to one. Fractint supports up to 32 functions,
  68582. Xalthough usually three or four are enough.
  68583. X
  68584. X3D IFS definitions are a bit different.  The name is followed by (3D) in
  68585. Xthe definition file, and each line of the definition contains 13 numbers:
  68586. Xa b c d e f g h i j k l p, defining:
  68587. X    matrix   vector  prob\
  68588. X    |a b c|   |j|     p\
  68589. X    |d e f|   |k|\
  68590. X    |g h i|   |l|\
  68591. X
  68592. X;You can experiment with changes to IFS definitions interactively by using
  68593. X;Fractint's <Z> command.  After selecting an IFS definition, hit <Z> to
  68594. X;bring up the IFS editor. This editor displays the current IFS values, lets
  68595. X;you modify them, and lets you save your modified values as a text file
  68596. X;which you can then merge into an XXX.IFS file for future use with
  68597. X;Fractint.
  68598. X;
  68599. XThe program FDESIGN can be used to design IFS fractals - see
  68600. X{=@FDESIGN FDESIGN}.
  68601. X
  68602. XYou can save the points in your IFS fractal in the file ORBITS.RAW which is
  68603. Xoverwritten each time a fractal is generated. The program Acrospin can
  68604. Xread this file and will let you view the fractal from any angle using
  68605. Xthe cursor keys. See {=@ACROSPIN Acrospin}.
  68606. X;
  68607. X;
  68608. X~Topic=Sierpinski Gasket, Label=HT_SIER
  68609. X(type=sierpinski)
  68610. X
  68611. XAnother pre-Mandelbrot classic, this one found by W. Sierpinski around
  68612. XWorld War I. It is generated by dividing a triangle into four congruent
  68613. Xsmaller triangles, doing the same to each of them, and so on, yea, even
  68614. Xunto infinity. (Notice how hard we try to avoid reiterating "iterating"?)
  68615. X
  68616. XIf you think of the interior triangles as "holes", they occupy more and
  68617. Xmore of the total area, while the "solid" portion becomes as hopelessly
  68618. Xfragile as that gasket you HAD to remove without damaging it -- you
  68619. Xremember, that Sunday afternoon when all the parts stores were closed?
  68620. XThere's a three-dimensional equivalent using nested tetrahedrons instead
  68621. Xof triangles, but it generates too much pyramid power to be safely
  68622. Xunleashed yet.
  68623. X
  68624. XThere are no parameters for this type. We were able to implement it with
  68625. Xinteger math routines, so it runs fairly quickly even without an FPU.
  68626. X;
  68627. X;
  68628. X~Topic=Quartic Mandelbrot/Julia, Label=HT_MANDJUL4
  68629. X(type=mandel4/julia4)
  68630. X
  68631. XThese fractal types are the moral equivalent of the original M and J sets,
  68632. Xexcept that they use the formula Z(n+1) = Z(n)^4 + C, which adds
  68633. Xadditional pseudo-symmetries to the plots. The "Mandel4" set maps to the
  68634. X"Julia4" set via -- surprise! -- the spacebar toggle. The M4 set is kind
  68635. Xof boring at first (the area between the "inside" and the "outside" of the
  68636. Xset is pretty thin, and it tends to take a few zooms to get to any
  68637. Xinteresting sections), but it looks nice once you get there. The Julia
  68638. Xsets look nice right from the start.
  68639. X
  68640. XOther powers, like Z(n)^3 or Z(n)^7, work in exactly the same fashion. We
  68641. Xused this one only because we're lazy, and Z(n)^4 = (Z(n)^2)^2.
  68642. X;
  68643. X;
  68644. X~Topic=Distance Estimator
  68645. X(distest=nnn/nnn)
  68646. X
  68647. XThis used to be type=demm and type=demj.  These types have not died, but
  68648. Xare only hiding!  They are equivalent to the mandel and julia types with
  68649. Xthe "distest=" option selected with a predetermined value.
  68650. X
  68651. XThe {Distance Estimator Method}
  68652. Xcan be used to produce higher quality images of M and J sets,
  68653. Xespecially suitable for printing in black and white.
  68654. X
  68655. XIf you have some *.fra files made with the old types demm/demj, you may
  68656. Xwant to convert them to the new form.  See the {=HT_MANDFN Mandelfn}
  68657. Xsection for directions to carry out the conversion.
  68658. X;
  68659. X;
  68660. X~Topic=Pickover Mandelbrot/Julia Types, Label=HT_PICKMJ
  68661. X(type=manfn+zsqrd/julfn+zsqrd, manzpowr/julzpowr, manzzpwr/julzzpwr,
  68662. Xmanfn+exp/julfn+exp - formerly included man/julsinzsqrd and
  68663. Xman/julsinexp which have now been generalized)
  68664. X
  68665. XThese types have been explored by Clifford A. Pickover, of the IBM Thomas
  68666. XJ. Watson Research center. As implemented in Fractint, they are regular
  68667. XMandelbrot/Julia set pairs that may be plotted with or without the
  68668. X{=@Biomorphs "biomorph"} option Pickover used to create organic-looking
  68669. Xbeasties (see
  68670. Xbelow). These types are produced with formulas built from the functions
  68671. Xz^z, z^n, sin(z), and e^z for complex z. Types with "power" or "pwr" in
  68672. Xtheir name have an exponent value as a third parameter. For example,
  68673. Xtype=manzpower params=0/0/2 is our old friend the classical Mandelbrot,
  68674. Xand type=manzpower params=0/0/4 is the Quartic Mandelbrot. Other values of
  68675. Xthe exponent give still other fractals.  Since these WERE the original
  68676. X"biomorph" types, we should give an example.  Try:
  68677. X
  68678. X    FRACTINT type=manfn+zsqrd biomorph=0 corners=-8/8/-6/6 function=sin
  68679. X
  68680. Xto see a big biomorph digesting little biomorphs!
  68681. X;
  68682. X;
  68683. X~Topic=Pickover Popcorn, Label=HT_POPCORN
  68684. X(type=popcorn/popcornjul)
  68685. X
  68686. XHere is another Pickover idea. This one computes and plots the orbits of
  68687. Xthe dynamic system defined by:
  68688. X
  68689. X     x(n+1) = x(n) - h*sin(y(n)+tan(3*y(n))\
  68690. X     y(n+1) = y(n) - h*sin(x(n)+tan(3*x(n))\
  68691. X
  68692. Xwith the initializers x(0) and y(0) equal to ALL the complex values within
  68693. Xthe "corners" values, and h=.01.  ALL these orbits are superimposed,
  68694. Xresulting in "popcorn" effect.  You may want to use a maxiter value less
  68695. Xthan normal - Pickover recommends a value of 50.  As a bonus,
  68696. Xtype=popcornjul shows the Julia set generated by these same equations with
  68697. Xthe usual escape-time coloring. Turn on orbit viewing with the "O"
  68698. Xcommand, and as you watch the orbit pattern you may get some insight as to
  68699. Xwhere the popcorn comes from. Although you can zoom and rotate popcorn,
  68700. Xthe results may not be what you'd expect, due to the superimposing of
  68701. Xorbits and arbitrary use of color. Just for fun we added type popcornjul,
  68702. Xwhich is the plain old Julia set calculated from the same formula.
  68703. X;
  68704. X;
  68705. X~Topic=Dynamic System, Label=HT_DYNAM
  68706. X(type=dynamic, dynamic2)
  68707. X
  68708. XThese fractals are based on a cyclic system of differential equations:
  68709. X     x'(t) = -f(y(t))\
  68710. X     y'(t) = f(x(t))\
  68711. XThese equations are approximated by using a small time step dt, forming
  68712. Xa time-discrete dynamic system:
  68713. X     x(n+1) = x(n) - dt*f(y(n))\
  68714. X     y(n+1) = y(n) + dt*f(x(n))\
  68715. XThe initial values x(0) and y(0) are set to various points in the plane, 
  68716. Xthe dynamic system is iterated, and the resulting orbit points are plotted.
  68717. X
  68718. XIn fractint, the function f is restricted to:
  68719. X      f(k) = sin(k + a*fn1(b*k))
  68720. XThe parameters are the spacing of the initial points, the time step dt,
  68721. Xand the parameters (a,b,fn1) that affect the function f.
  68722. XNormally the orbit points are plotted individually, but for a negative
  68723. Xspacing the points are connected.
  68724. X
  68725. XThis fractal is similar to the {=HT_POPCORN Pickover Popcorn}.
  68726. X~OnlineFF
  68727. XA variant is the implicit Euler approximation:
  68728. X     y(n+1) = y(n) + dt*f(x(n))\
  68729. X     x(n+1) = x(n) - dt*f(y(n+1))\
  68730. XThis variant results in complex orbits.  The implicit Euler approximation
  68731. Xis selected by entering dt<0.
  68732. X
  68733. XThere are two options that have unusual effects on these fractals.  The
  68734. XOrbit Delay value controls how many initial points are computed before
  68735. Xthe orbits are displayed on the screen.  This allows the orbit to settle
  68736. Xdown.  The outside=summ option causes each pixel to increment color every
  68737. Xtime an orbit touches it; the resulting display is a 2-d histogram.
  68738. X
  68739. XThese fractals are discussed in Chapter 14 of Pickover's "Computers,
  68740. XPattern, Chaos, and Beauty".
  68741. X;
  68742. X;
  68743. X~Topic=Mandelcloud, Label=HT_MANDELCLOUD
  68744. X(type=mandelcloud)
  68745. X
  68746. XThis fractal computes the Mandelbrot function, but displays it differently.
  68747. XIt starts with regularly spaced initial pixels and displays the resulting
  68748. Xorbits.  This idea is somewhat similar to the {=HT_DYNAM Dynamic System}.
  68749. X
  68750. XThere are two options that have unusual effects on this fractal.  The
  68751. XOrbit Delay value controls how many initial points are computed before
  68752. Xthe orbits are displayed on the screen.  This allows the orbit to settle
  68753. Xdown.  The outside=summ option causes each pixel to increment color every
  68754. Xtime an orbit touches it; the resulting display is a 2-d histogram.
  68755. X
  68756. XThis fractal was invented by Noel Giffin.
  68757. X
  68758. X;
  68759. X;
  68760. X~Topic=Peterson Variations, Label=HT_MARKS
  68761. X(type=marksmandel, marksjulia, cmplxmarksmand, cmplxmarksjul, marksmandelpwr,
  68762. Xtim's_error)
  68763. X
  68764. XThese fractal types are contributions of Mark Peterson. MarksMandel and
  68765. XMarksJulia are two families of fractal types that are linked in the same
  68766. Xmanner as the classic Mandelbrot/Julia sets: each MarksMandel set can be
  68767. Xconsidered as a mapping into the MarksJulia sets, and is linked with the
  68768. Xspacebar toggle. The basic equation for these sets is:
  68769. X      Z(n+1) = ((lambda^exp) * Z(n)^2) + lambda
  68770. Xwhere Z(0) = 0.0 and lambda is (x + iy) for MarksMandel. For MarksJulia,
  68771. XZ(0) = (x + iy) and lambda is a constant (taken from the MarksMandel
  68772. Xspacebar toggle, if that method is used). The exponent is a positive
  68773. Xinteger or a complex number. We call these "families" because each value
  68774. Xof the exponent yields a different MarksMandel set, which turns out to be
  68775. Xa kinda-polygon with (exponent+1) sides. The exponent value is the third
  68776. Xparameter, after the "initialization warping" values. Typically one would
  68777. Xuse null warping values, and specify the exponent with something like
  68778. X"PARAMS=0/0/4", which creates an unwarped, pentagonal MarksMandel set.
  68779. X
  68780. XIn the process of coding MarksMandelPwr formula type, Tim Wegner
  68781. Xcreated the type "tim's_error" after making an interesting coding mistake.
  68782. X;
  68783. X;
  68784. X~Topic=Unity, Label=HT_UNITY
  68785. X(type=unity)
  68786. X
  68787. XThis Peterson variation began with curiosity about other "Newton-style"
  68788. Xapproximation processes. A simple one,
  68789. X
  68790. X   One = (x * x) + (y * y); y = (2 - One) * x;     x = (2 - One) * y;
  68791. X
  68792. Xproduces the fractal called Unity.
  68793. X
  68794. XOne of its interesting features is the "ghost lines." The iteration loop
  68795. Xbails out when it reaches the number 1 to within the resolution of a
  68796. Xscreen pixel. When you zoom a section of the image, the bailout criterion
  68797. Xis adjusted, causing some lines to become thinner and others thicker.
  68798. X
  68799. XOnly one line in Unity that forms a perfect circle: the one at a radius of
  68800. X1 from the origin. This line is actually infinitely thin. Zooming on it
  68801. Xreveals only a thinner line, up (down?) to the limit of accuracy for the
  68802. Xalgorithm. The same thing happens with other lines in the fractal, such as
  68803. Xthose around |x| = |y| = (1/2)^(1/2) = .7071
  68804. X
  68805. XTry some other tortuous approximations using the {=HT_TEST TEST stub} and
  68806. Xlet us know what you come up with!
  68807. X;
  68808. X;
  68809. X~Topic=Scott Taylor / Lee Skinner Variations, Label=HT_SCOTSKIN
  68810. X(type=fn(z*z), fn*fn, fn*z+z, fn+fn, sqr(1/fn), sqr(fn), spider,
  68811. Xtetrate, manowar)
  68812. X
  68813. XTwo of Fractint's faithful users went bonkers when we introduced the
  68814. X"formula" type, and came up with all kinds of variations on escape-time
  68815. Xfractals using trig functions.    We decided to put them in as regular
  68816. Xtypes, but there were just too many! So we defined the types with variable
  68817. Xfunctions and let you, the, overwhelmed user, specify what the functions
  68818. Xshould be! Thus Scott Taylor's "z = sin(z) + z^2" formula type is now the
  68819. X"fn+fn" regular type, and EITHER function can be one of sin, cos, tan, cotan,
  68820. Xsinh, cosh, tanh, cotanh, exp, log, sqr, recip, ident, conj, flip, or cosxx.
  68821. XPlus we give you 4 parameters to set, the complex
  68822. Xcoefficients of the two functions!  Thus the innocent-looking "fn+fn" type
  68823. Xis really 256 different types in disguise, not counting the damage
  68824. Xdone by the parameters!
  68825. X
  68826. X Some functions that require further explanation:
  68827. X
  68828. X conj()   - returns the complex conjugate of the argument. That is, changes
  68829. X            sign of the imaginary component of argument: (x,y) becomes (x,-y)
  68830. X ident()  - identity function. Leaves the value of the argument unchanged,
  68831. X            acting like a "z" term in a formula.
  68832. X~OnlineFF
  68833. X flip()   - Swap the real and imaginary components of the complex number.
  68834. X            e.g. (4,5) would become (5,4)
  68835. X
  68836. XLee informs us that you should not judge fractals by their "outer"
  68837. Xappearance. For example, the images produced by z = sin(z) + z^2 and z =
  68838. Xsin(z) - z^2 look very similar, but are different when you zoom in.
  68839. X;
  68840. X;
  68841. X~Topic=Kam Torus, Label=HT_KAM
  68842. X(type=kamtorus, kamtorus3d)
  68843. X
  68844. XThis type is created by superimposing orbits generated by a set of
  68845. Xequations, with a variable incremented each time.
  68846. X
  68847. X     x(0) = y(0) = orbit/3;\
  68848. X     x(n+1) = x(n)*cos(a) + (x(n)*x(n)-y(n))*sin(a)\
  68849. X     y(n+1) = x(n)*sin(a) - (x(n)*x(n)-y(n))*cos(a)\
  68850. X
  68851. XAfter each orbit, 'orbit' is incremented by a step size. The parameters
  68852. Xare angle "a", step size for incrementing 'orbit', stop value for 'orbit',
  68853. Xand points per orbit. Try this with a stop value of 5 with sound=x for
  68854. Xsome weird fractal music (ok, ok, fractal noise)! You will also see the
  68855. XKAM Torus head into some chaotic territory that Scott Taylor wanted to
  68856. Xhide from you by setting the defaults the way he did, but now we have
  68857. Xrevealed all!
  68858. X
  68859. XThe 3D variant is created by treating 'orbit' as the z coordinate.
  68860. X
  68861. XWith both variants, you can adjust the "maxiter" value (<X> options
  68862. Xscreen or parameter maxiter=) to change the number of orbits plotted.
  68863. X;
  68864. X;
  68865. X~Topic=Bifurcation, Label=HT_BIF
  68866. X(type=bifxxx)
  68867. X
  68868. XThe wonder of fractal geometry is that such complex forms can arise from
  68869. Xsuch simple generating processes. A parallel surprise has emerged in the
  68870. Xstudy of dynamical systems: that simple, deterministic equations can yield
  68871. Xchaotic behavior, in which the system never settles down to a steady state
  68872. Xor even a periodic loop. Often such systems behave normally up to a
  68873. Xcertain level of some controlling parameter, then go through a transition
  68874. Xin which there are two possible solutions, then four, and finally a
  68875. Xchaotic array of possibilities.
  68876. X
  68877. XThis emerged many years ago in biological models of population growth.
  68878. XConsider a (highly over-simplified) model in which the rate of growth is
  68879. Xpartly a function of the size of the current population:
  68880. X
  68881. XNew Population =  Growth Rate * Old Population * (1 - Old Population)
  68882. X
  68883. Xwhere population is normalized to be between 0 and 1. At growth rates less
  68884. Xthan 200 percent, this model is stable: for any starting value, after
  68885. Xseveral generations the population settles down to a stable level. But for
  68886. Xrates over 200 percent, the equation's curve splits or "bifurcates" into
  68887. Xtwo discrete solutions, then four, and soon becomes chaotic.
  68888. X
  68889. XType=bifurcation illustrates this model. (Although it's now considered a
  68890. Xpoor one for real populations, it helped get people thinking about chaotic
  68891. Xsystems.) The horizontal axis represents growth rates, from 190 percent
  68892. X(far left) to 400 percent; the vertical axis normalized population values,
  68893. Xfrom 0 to 4/3. Notice that within the chaotic region, there are narrow
  68894. Xbands where there is a small, odd number of stable values. It turns out
  68895. Xthat the geometry of this branching is fractal; zoom in where changing
  68896. Xpixel colors look suspicious, and see for yourself.
  68897. X
  68898. XThree parameters apply to bifurcations: Filter Cycles, Seed Population,
  68899. Xand Function or Beta.
  68900. X
  68901. XFilter Cycles (default 1000) is the number of iterations to be done before
  68902. Xplotting maxiter population values. This gives the iteration time to settle
  68903. Xinto the characteristic patterns that constitute the bifurcation diagram,
  68904. Xand results in a clean-looking plot.  However, using lower values produces
  68905. Xinteresting results too. Set Filter Cycles to 1 for an unfiltered map.
  68906. X
  68907. XSeed Population (default 0.66) is the initial population value from which
  68908. Xall others are calculated. For filtered maps the final image is independent
  68909. Xof Seed Population value in the valid range (0.0 < Seed Population < 1.0).
  68910. X~OnlineFF
  68911. XSeed Population becomes effective in unfiltered maps - try setting Filter
  68912. XCycles to 1 (unfiltered) and Seed Population to 0.001 ("PARAMS=1/.001" on
  68913. Xthe command line). This results in a map overlaid with nice curves. Each
  68914. XSeed Population value results in a different set of curves.
  68915. X
  68916. XFunction (default "ident") is the function applied to the old population
  68917. Xbefore the new population is determined. The "ident" function calculates
  68918. Xthe same bifurcation fractal that was generated before these formulae
  68919. Xwere generalized.
  68920. X
  68921. XBeta is used in the bifmay bifurcations and is the power to which the
  68922. Xdenominator is raised.
  68923. X
  68924. XNote that fractint normally uses periodicity checking to speed up
  68925. Xbifurcation computation.  However, in some cases a better quality image
  68926. Xwill be obtained if you turn off periodicity checking with "periodicity=no";
  68927. Xfor instance, if you use a high number of iterations and a smooth
  68928. Xcolormap.
  68929. X
  68930. XMany formulae can be used to produce bifurcations.  Mitchel Feigenbaum
  68931. Xstudied lots of bifurcations in the mid-70's, using a HP-65 calculator
  68932. X(IBM PCs, Fractals, and Fractint, were all Sci-Fi then !). He studied
  68933. Xwhere bifurcations occurred, for the formula r*p*(1-p), the one described
  68934. Xabove.    He found that the ratios of lengths of adjacent areas of
  68935. Xbifurcation were four and a bit.  These ratios vary, but, as the growth
  68936. Xrate increases, they tend to a limit of 4.669+.  This helped him guess
  68937. Xwhere bifurcation points would be, and saved lots of time.
  68938. X
  68939. XWhen he studied bifurcations of r*sin(PI*p) he found a similar pattern,
  68940. Xwhich is not surprising in itself.  However, 4.669+ popped out, again.
  68941. XDifferent formulae, same number ?  Now, THAT's surprising !  He tried many
  68942. Xother formulae and ALWAYS got 4.669+ - Hot Damn !!!  So hot, in fact, that
  68943. Xhe phoned home and told his Mom it would make him Famous ! He also went on
  68944. Xto tell other scientists.  The rest is History...
  68945. X
  68946. X(It has been conjectured that if Feigenbaum had a copy of Fractint, and
  68947. Xused it to study bifurcations, he may never have found his Number, as it
  68948. Xonly became obvious from long perusal of hand-written lists of values,
  68949. Xwithout the distraction of wild color-cycling effects !).
  68950. X~OnlineFF
  68951. XWe now know that this number is as universal as PI or E. It appears in
  68952. Xsituations ranging from fluid-flow turbulence, electronic oscillators,
  68953. Xchemical reactions, and even the Mandelbrot Set - yup, fraid so:
  68954. X"budding" of the Mandelbrot Set along the negative real axis occurs at
  68955. Xintervals determined by Feigenbaum's Number, 4.669201660910.....
  68956. X
  68957. XFractint does not make direct use of the Feigenbaum Number (YET !).
  68958. XHowever, it does now reflect the fact that there is a whole sub-species of
  68959. XBifurcation-type fractals.  Those implemented to date, and the related
  68960. Xformulae, (writing P for pop[n+1] and p for pop[n]) are :
  68961. X
  68962. X  bifurcation  P =  p + r*fn(p)*(1-fn(p))  Verhulst Bifurcations.\
  68963. X  biflambda    P =      r*fn(p)*(1-fn(p))  Real equivalent of Lambda Sets.\
  68964. X  bif+sinpi    P =  p + r*fn(PI*p)         Population scenario based on...\
  68965. X  bif=sinpi    P =      r*fn(PI*p)         ...Feigenbaum's second formula.\
  68966. X  bifstewart   P =      r*fn(p)*fn(p) - 1  Stewart Map.\
  68967. X  bifmay       P =      r*p / ((1+p)^b)    May Map.\
  68968. X
  68969. XIt took a while for bifurcations to appear here, despite them being over a
  68970. Xcentury old, and intimately related to chaotic systems. However, they are
  68971. Xnow truly alive and well in Fractint!
  68972. X;
  68973. X;
  68974. X~Topic=Orbit Fractals
  68975. X
  68976. XOrbit Fractals are generated by plotting an orbit path in two or three
  68977. Xdimensional space.
  68978. X
  68979. XSee {Lorenz Attractors}, {Rossler Attractors},
  68980. X{Henon Attractors}, {Pickover Attractors}, {Gingerbreadman},
  68981. Xand {Martin Attractors}.
  68982. X
  68983. XThe orbit trajectory for these types can be saved in the file ORBITS.RAW
  68984. Xby invoking
  68985. XFractint with the "orbitsave=yes" command-line option.  This file will
  68986. Xbe overwritten each time you generate a new fractal, so rename it if you
  68987. Xwant to save it.  A nifty program called Acrospin can read these files and
  68988. Xrapidly rotate them in 3-D - see {=@ACROSPIN Acrospin}.
  68989. X;
  68990. X;
  68991. X~Topic=Lorenz Attractors, Label=HT_LORENZ
  68992. X(type=lorenz/lorenz3d)
  68993. X
  68994. XThe "Lorenz Attractor" is a "simple" set of three deterministic equations
  68995. Xdeveloped by Edward Lorenz while studying the non- repeatability of
  68996. Xweather patterns.  The weather forecaster's basic problem is that even
  68997. Xvery tiny changes in initial patterns ("the beating of a butterfly's
  68998. Xwings" - the official term is "sensitive dependence on initial
  68999. Xconditions") eventually reduces the best weather forecast to rubble.
  69000. X
  69001. XThe lorenz attractor is the plot of the orbit of a dynamic system
  69002. Xconsisting of three first order non-linear differential equations. The
  69003. Xsolution to the differential equation is vector-valued function of one
  69004. Xvariable.  If you think of the variable as time, the solution traces an
  69005. Xorbit.    The orbit is made up of two spirals at an angle to each other in
  69006. Xthree dimensions. We change the orbit color as time goes on to add a
  69007. Xlittle dazzle to the image.  The equations are:
  69008. X
  69009. X        dx/dt = -a*x + a*y\
  69010. X        dy/dt =  b*x - y   -z*x\
  69011. X        dz/dt = -c*z + x*y\
  69012. X
  69013. XWe solve these differential equations approximately using a method known
  69014. Xas the first order taylor series.  Calculus teachers everywhere will kill
  69015. Xus for saying this, but you treat the notation for the derivative dx/dt as
  69016. Xthough it really is a fraction, with "dx" the small change in x that
  69017. Xhappens when the time changes "dt".  So multiply through the above
  69018. Xequations by dt, and you will have the change in the orbit for a small
  69019. Xtime step. We add these changes to the old vector to get the new vector
  69020. Xafter one step. This gives us:
  69021. X
  69022. X         xnew = x + (-a*x*dt) + (a*y*dt)\
  69023. X         ynew = y + (b*x*dt) - (y*dt) - (z*x*dt)\
  69024. X         znew = z + (-c*z*dt) + (x*y*dt)\
  69025. X
  69026. X         (default values: dt = .02, a = 5, b = 15, c = 1)
  69027. X
  69028. XWe connect the successive points with a line, project the resulting 3D
  69029. Xorbit onto the screen, and voila! The Lorenz Attractor!
  69030. X
  69031. XWe have added two versions of the Lorenz Attractor.  "Type=lorenz" is the
  69032. XLorenz attractor as seen in everyday 2D.  "Type=lorenz3d" is the same set
  69033. Xof equations with the added twist that the results are run through our
  69034. Xperspective 3D routines, so that you get to view it from different angles
  69035. X(you can modify your perspective "on the fly" by using the <I> command.)
  69036. XIf you set the "stereo" option to "2", and have red/blue funny glasses on,
  69037. Xyou will see the attractor orbit with depth perception.
  69038. X
  69039. XHint: the default perspective values (x = 60, y = 30, z = 0) aren't the
  69040. Xbest ones to use for fun Lorenz Attractor viewing.  Experiment a bit -
  69041. Xstart with rotation values of 0/0/0 and then change to 20/0/0 and 40/0/0
  69042. Xto see the attractor from different angles.- and while you're at it, use a
  69043. Xnon-zero perspective point Try 100 and see what happens when you get
  69044. X*inside* the Lorenz orbits.  Here comes one - Duck!  While you are at it,
  69045. Xturn on the sound with the "X". This way you'll at least hear it coming!
  69046. X
  69047. XDifferent Lorenz attractors can be created using different parameters.
  69048. XFour parameters are used. The first is the time-step (dt). The default
  69049. Xvalue is .02. A smaller value makes the plotting go slower; a larger value
  69050. Xis faster but rougher. A line is drawn to connect successive orbit values.
  69051. XThe 2nd, third, and fourth parameters are coefficients used in the
  69052. Xdifferential equation (a, b, and c). The default values are 5, 15, and 1.
  69053. XTry changing these a little at a time to see the result.
  69054. X;
  69055. X;
  69056. X~Topic=Rossler Attractors, Label=HT_ROSS
  69057. X(type=rossler3D)
  69058. X
  69059. XThis fractal is named after the German Otto Rossler, a non-practicing
  69060. Xmedical doctor who approached chaos with a bemusedly philosophical
  69061. Xattitude.  He would see strange attractors as philosophical objects. His
  69062. Xfractal namesake looks like a band of ribbon with a fold in it. All we can
  69063. Xsay is we used the same calculus-teacher-defeating trick of multiplying
  69064. Xthe equations by "dt" to solve the differential equation and generate the
  69065. Xorbit.    This time we will skip straight to the orbit generator - if you
  69066. Xfollowed what we did above with type {=HT_LORENZ Lorenz} you can easily
  69067. Xreverse engineer the differential equations.
  69068. X
  69069. X         xnew = x - y*dt -     z*dt\
  69070. X         ynew = y + x*dt + a*y*dt\
  69071. X         znew = z + b*dt + x*z*dt - c*z*dt\
  69072. X
  69073. XDefault parameters are dt = .04, a = .2, b = .2, c = 5.7
  69074. X;
  69075. X;
  69076. X~Topic=Henon Attractors, Label=HT_HENON
  69077. X(type=henon)
  69078. X
  69079. XMichel Henon was an astronomer at Nice observatory in southern France. He
  69080. Xcame to the subject of fractals via investigations of the orbits of
  69081. Xastronomical objects.  The strange attractor most often linked with
  69082. XHenon's name comes not from a differential equation, but from the world of
  69083. Xdiscrete mathematics - difference equations. The Henon map is an example
  69084. Xof a very simple dynamic system that exhibits strange behavior. The orbit
  69085. Xtraces out a characteristic banana shape, but on close inspection, the
  69086. Xshape is made up of thicker and thinner parts.    Upon magnification, the
  69087. Xthicker bands resolve to still other thick and thin components.  And so it
  69088. Xgoes forever! The equations that generate this strange pattern perform the
  69089. Xmathematical equivalent of repeated stretching and folding, over and over
  69090. Xagain.
  69091. X
  69092. X         xnew =  1 + y - a*x*x\
  69093. X         ynew =  b*x\
  69094. X
  69095. XThe default parameters are a=1.4 and b=.3.
  69096. X;
  69097. X;
  69098. X~Topic=Pickover Attractors, Label=HT_PICK
  69099. X(type=pickover)
  69100. X
  69101. XClifford A. Pickover of the IBM Thomas J. Watson Research center is such a
  69102. Xcreative source for fractals that we attach his name to this one only with
  69103. Xgreat trepidation.  Probably tomorrow he'll come up with another one and
  69104. Xwe'll be back to square one trying to figure out a name!
  69105. X
  69106. XThis one is the three dimensional orbit defined by:
  69107. X
  69108. X         xnew = sin(a*y) - z*cos(b*x)\
  69109. X         ynew = z*sin(c*x) - cos(d*y)\
  69110. X         znew = sin(x)\
  69111. X
  69112. XDefault parameters are: a = 2.24, b = .43, c = -.65, d = -2.43
  69113. X;
  69114. X;
  69115. X~Topic=Gingerbreadman, Label=HT_GINGER
  69116. X(type=gingerbreadman)
  69117. X
  69118. XThis simple fractal is a charming example stolen from "Science of Fractal
  69119. XImages", p. 149.
  69120. X
  69121. X         xnew = 1 - y + |x|\
  69122. X         ynew = x
  69123. X
  69124. XThe initial x and y values are set by parameters, defaults x=-.1, y = 0.
  69125. X;
  69126. X;
  69127. X~Topic=Martin Attractors, Label=HT_MARTIN
  69128. X(type=hopalong/martin)
  69129. X
  69130. XThese fractal types are from A. K. Dewdney's "Computer Recreations" column
  69131. Xin "Scientific American". They are attributed to Barry Martin of Aston 
  69132. XUniversity in Birmingham, England. 
  69133. X
  69134. XHopalong is an "orbit" type fractal like lorenz. The image is obtained by 
  69135. Xiterating this formula after setting z(0) = y(0) = 0:\
  69136. X      x(n+1) = y(n) - sign(x(n))*sqrt(abs(b*x(n)-c))\
  69137. X      y(n+1) = a - x(n)\
  69138. XParameters are a, b, and c. The function "sign()"  returns 1 if the argument 
  69139. Xis positive, -1 if argument is negative.
  69140. X
  69141. XThis fractal continues to develop in surprising ways after many iterations.
  69142. X
  69143. XAnother Martin fractal is simpler. The iterated formula is:\
  69144. X      x(n+1) = y(n) - sin(x(n))\
  69145. X      y(n+1) = a - x(n)\
  69146. XThe parameter is "a". Try values near the number pi.
  69147. X;
  69148. X;
  69149. X;
  69150. X~Topic=Icon, Label=HT_ICON
  69151. X(type=icon/icon3d)
  69152. X
  69153. X  This fractal type was inspired by the book "Symmetry in Chaos"
  69154. X  by Michael Field and Martin Golubitsky (ISBN 0-19-853689-5, Oxford Press)
  69155. X
  69156. X  To quote from the book's jacket,
  69157. X
  69158. X    "Field and Golubitsky describe how a chaotic process eventually can
  69159. X    lead to symmetric patterns (in a river, for instance, photographs of
  69160. X    the turbulent movement of eddies, taken over time, often reveal
  69161. X    patterns on the average."
  69162. X
  69163. X  The Icon type implemented here maps the classic population logistic
  69164. X  map of bifurcation fractals onto the complex plane in Dn symmetry.
  69165. X
  69166. X  The initial points plotted are the more chaotic initial orbits, but
  69167. X  as you wait, delicate webs will begin to form as the orbits settle
  69168. X  into a more periodic pattern.  Since pixels are colored by the number
  69169. X  of times they are hit, the more periodic paths will become clarified
  69170. X  with time.  These fractals run continuously.
  69171. X
  69172. XThere are 6 parameters:  Lambda, Alpha, Beta, Gamma, Omega, and Degree
  69173. X    Omega  0 = Dn, or dihedral (rotation + reflectional) symmetry
  69174. X          !0 = Zn, or cyclic (rotational) symmetry
  69175. X    Degree = n, or Degree of symmetry
  69176. X;
  69177. X;
  69178. X;
  69179. X~Topic=Quaternion, Label=HT_QUAT
  69180. X(type=quat,quatjul)
  69181. X
  69182. XThese fractals are based on quaternions.  Quaternions are an extension of
  69183. Xcomplex numbers, with 4 parts instead of 2.  That is, a quaternion Q
  69184. Xequals a+ib+jc+kd, where a,b,c,d are reals.  Quaternions have rules for
  69185. Xaddition and multiplication.  The normal Mandelbrot and Julia formulas
  69186. Xcan be generalized to use quaternions instead of complex numbers.
  69187. X
  69188. XThere is one complication.  Complex numbers have 2 parts, so they can
  69189. Xbe displayed on a plane.  Quaternions have 4 parts, so they require 4
  69190. Xdimensions to view.  That is, the quaternion Mandelbrot set is actually a
  69191. X4-dimensional object.  Each quaternion C generates a 4-dimensional Julia set.
  69192. X
  69193. XOne method of displaying the 4-dimensional object is to take a 3-dimensional
  69194. Xslice and render the resulting object in 3-dimensional perspective.
  69195. XFractint isn't that sophisticated, so it merely displays a 2-dimensional
  69196. Xslice of the resulting object. (Note: Now Fractint is that sophisticated! 
  69197. XSee the Julibrot type!)
  69198. X
  69199. XIn fractint, for the Julia set, you can specify the four parameters
  69200. Xof the quaternion constant: c=(c1,ci,cj,ck), but the 2-dimensional slice 
  69201. Xof the z-plane Julia set is fixed to (xpixel,ypixel,0,0).
  69202. X
  69203. XFor the Mandelbrot set, you can specify the position of the c-plane slice:
  69204. X(xpixel,ypixel,cj,ck).
  69205. X
  69206. XThese fractals are discussed in Chapter 10 of Pickover's "Computers,
  69207. XPattern, Chaos, and Beauty".
  69208. X;
  69209. X;
  69210. X~Topic=HyperComplex, Label=HT_HYPERC
  69211. X(type=hypercomplex,hypercomplexj)
  69212. X
  69213. XThese fractals are based on hypercomplex numbers, which like quaternions
  69214. Xare a four dimensional generalization of complex numbers. It is not 
  69215. Xpossible to fully generalize the complex numbers to four dimensions without
  69216. Xsacrificing some of the algebraic properties shared by real and complex 
  69217. Xnumbers. Quaternions violate the commutative law of multiplication, which 
  69218. Xsays z1*z2 = z2*z1. Hypercomplex numbers fail the rule that says all non-zero
  69219. Xelements have multiplicative inverses - that is, if z is not 0, there
  69220. Xshould be a number 1/z such that (1/z)*(z) = 1. This law holds most of the
  69221. Xtime but not all the time for hypercomplex numbers. 
  69222. X
  69223. XHowever hypercomplex numbers have a wonderful property for fractal purposes.
  69224. XEvery function defined for complex numbers has a simple generalization 
  69225. Xto hypercomplex numbers. Fractint's implementation takes advantage of this
  69226. Xby using "fn" variables - the iteration formula is\
  69227. X    h(n+1) = fn(h(n)) + C.\
  69228. Xwhere "fn" is the hypercomplex generalization of sin, cos, log, sqr etc.
  69229. X~OnlineFF
  69230. XYou can see 3D versions of these fractals using fractal type Julibrot.
  69231. XHypercomplex numbers were brought to our attention by Clyde Davenport,
  69232. Xauthor of "A Hypercomplex Calculus with Applications to Relativity",
  69233. XISBN 0-9623837-0-8.
  69234. X;
  69235. X;
  69236. X
  69237. X~Topic=Cellular Automata, Label=HT_CELLULAR
  69238. X(type=cellular)
  69239. X
  69240. XThese fractals are generated by 1-dimensional cellular automata.  Consider
  69241. Xa 1-dimensional line of cells, where each cell can have the value 0 or 1.
  69242. XIn each time step, the new value of a cell is computed from the old value
  69243. Xof the cell and the values of its neighbors.  On the screen, each horizontal
  69244. Xrow shows the value of the cells at any one time.  The time axis proceeds
  69245. Xdown the screen, with each row computed from the row above.
  69246. X
  69247. XDifferent classes of cellular automata can be described by how many different
  69248. Xstates a cell can have (k), and how many neighbors on each side are examined
  69249. X(r).  Fractint implements the binary nearest neighbor cellular automata
  69250. X(k=2,r=1), the binary next-nearest neighbor cellular automata (k=2,r=2),
  69251. Xand the ternary nearest neighbor cellular automata (k=3,r=1) and several
  69252. Xothers.
  69253. X
  69254. XThe rules used here determine the next state of a given cell by using the
  69255. Xsum of the states in the cell's neighborhood.  The sum of the cells in the
  69256. Xneighborhood are mapped by rule to the new value of the cell.  For the
  69257. Xbinary nearest neighbor cellular automata, only the closest neighbor on
  69258. Xeach side is used.  This results in a 4 digit rule controlling the
  69259. Xgeneration of each new line:  if each of the cells in the neighborhood is
  69260. X1, the maximum sum is 1+1+1 = 3 and the sum can range from 0 to 3, or 4
  69261. Xvalues.  This results in a 4 digit rule.  For instance, in the rule 1010,
  69262. Xstarting from the right we have 0->0, 1->1, 2->0, 3->1.  If the cell's
  69263. Xneighborhood sums to 2, the new cell value would be 0.
  69264. X
  69265. XFor the next-nearest cellular automata (kr = 22), each pixel is determined
  69266. Xfrom the pixel value and the two neighbors on each side.  This results in
  69267. Xa 6 digit rule.
  69268. X
  69269. XFor the ternary nearest neighbor cellular automata (kr = 31), each cell
  69270. Xcan have the value 0, 1, or 2.  A single neighbor on each side is examined,
  69271. Xresulting in a 7 digit rule.
  69272. X
  69273. X  kr  #'s in rule  example rule     | kr  #'s in rule  example rule\
  69274. X  21      4        1010             | 42     16        2300331230331001\
  69275. X  31      7        1211001          | 23      8        10011001\
  69276. X  41     10        3311100320       | 33     15        021110101210010\
  69277. X  51     13        2114220444030    | 24     10        0101001110\
  69278. X  61     16        3452355321541340 | 25     12        110101011001\
  69279. X  22      6        011010           | 26     14        00001100000110\
  69280. X  32     11        21212002010      | 27     16        0010000000000110\
  69281. X
  69282. XThe starting row of cells can be set to a pattern of up to 16 digits or to a
  69283. Xrandom pattern.  The borders are set to zeros if a pattern is entered or are
  69284. Xset randomly if the starting row is set randomly.
  69285. X
  69286. XA zero rule will randomly generate the rule to use.
  69287. X
  69288. XHitting the space bar toggles between continuously generating the cellular
  69289. Xautomata and stopping at the end of the current screen.
  69290. X
  69291. XRecommended reading:
  69292. X"Computer Software in Science and Mathematics", Stephen Wolfram, Scientific
  69293. XAmerican, September, 1984.
  69294. X"Abstract Mathematical Art", Kenneth E. Perry, BYTE, December, 1986.
  69295. X"The Armchair Universe", A. K. Dewdney, W. H. Freeman and Company, 1988.
  69296. X"Complex Patterns Generated by Next Nearest Neighbors Cellular Automata",
  69297. XWentian Li, Computers & Graphics, Volume 13, Number 4.
  69298. X;
  69299. X;
  69300. X~Topic=Test, Label=HT_TEST
  69301. X(type=test)
  69302. X
  69303. XThis is a stub that we (and you!) use for trying out new fractal types.
  69304. X"Type=test" fractals make use of Fractint's structure and features for
  69305. Xwhatever code is in the routine 'testpt()' (located in the small source
  69306. Xfile TESTPT.C) to determine the color of a particular pixel.
  69307. X
  69308. XIf you have a favorite fractal type that you believe would fit nicely into
  69309. XFractint, just rewrite the C function in TESTPT.C (or use the prototype
  69310. Xfunction there, which is a simple M-set implementation) with an algorithm
  69311. Xthat computes a color based on a point in the complex plane.
  69312. X
  69313. XAfter you get it working, send your code to one of the authors and we
  69314. Xmight just add it to the next release of Fractint, with full credit to
  69315. Xyou. Our criteria are: 1) an interesting image and 2) a formula
  69316. Xsignificantly different from types already supported. (Bribery may also
  69317. Xwork. THIS author is completely honest, but I don't trust those other
  69318. Xguys.) Be sure to include an explanation of your algorithm and the
  69319. Xparameters supported, preferably formatted as you see here to simplify
  69320. Xfolding it into the documentation.
  69321. X;
  69322. X;
  69323. X~Topic=Formula, Label=HT_FORMULA
  69324. X(type=formula)
  69325. X
  69326. XThis is a "roll-your-own" fractal interpreter - you don't even need a
  69327. Xcompiler!
  69328. X
  69329. XTo run a "type=formula" fractal, you first need a text file containing
  69330. Xformulas (there's a sample file - FRACTINT.FRM - included with this
  69331. Xdistribution).    When you select the "formula" fractal type, Fractint scans
  69332. Xthe current formula file (default is FRACTINT.FRM) for formulas, then
  69333. Xprompts you for the formula name you wish to run.  After prompting for any
  69334. Xparameters, the formula is parsed for syntax errors and then the fractal
  69335. Xis generated. If you want to use a different formula file, press <F6> when
  69336. Xyou are prompted to select a formula name.
  69337. X
  69338. XThere are two command-line options that work with type=formula
  69339. X("formulafile=" and "formulaname="), useful when you are using this
  69340. Xfractal type in batch mode.
  69341. X
  69342. XThe following documentation is supplied by Mark Peterson, who wrote the
  69343. Xformula interpreter:
  69344. X
  69345. XFormula fractals allow you to create your own fractal formulas.  The
  69346. Xgeneral format is:
  69347. X
  69348. X   Mandelbrot(XAXIS) \{ z = Pixel:  z = sqr(z) + pixel, |z| <= 4 \}\
  69349. X      |     |       |            |           |\
  69350. X     Name     Symmetry      Initial      Iteration      Bailout\
  69351. X              Condition              Criteria\
  69352. X
  69353. XInitial conditions are set, then the iterations performed until the
  69354. Xbailout criteria is true or 'z' turns into a periodic loop.
  69355. XAll variables are created automatically by their usage and treated as
  69356. Xcomplex.  If you declare 'v = 2' then the variable 'v' is treated as a
  69357. Xcomplex with an imaginary value of zero.
  69358. X
  69359. X~Format-
  69360. X      Predefined Variables (x, y)
  69361. X      --------------------------------------------
  69362. X      z         used for periodicity checking
  69363. X      p1         parameters 1 and 2
  69364. X      p2         parameters 3 and 4
  69365. X      pixel      screen coordinates
  69366. X          LastSqr        Modulus from the last sqr() function
  69367. X          rand           Complex random number
  69368. X
  69369. X          Precedence
  69370. X          --------------------------------------------
  69371. X          1              sin(), cos(), sinh(), cosh(), cosxx(),
  69372. X                         tan(), cotan(), tanh(), cotanh(),
  69373. X                         sqr, log(), exp(), abs(), conj(), real(),
  69374. X                         imag(), flip(), fn1(), fn2(), fn3(), fn4(),
  69375. X                         srand()
  69376. X          2              - (negation), ^ (power)
  69377. X          3              * (multiplication), / (division)
  69378. X          4              + (addition), - (subtraction)
  69379. X          5              = (assignment)
  69380. X          6              < (less than), <= (less than or equal to)
  69381. X                         > (greater than), >= (greater than or equal to)
  69382. X                         == (equal to), != (not equal to)
  69383. X          7              && (logical AND), || (logical OR)
  69384. X~Format+
  69385. X
  69386. XPrecedence may be overridden by use of parenthesis.  Note the modulus
  69387. Xsquared operator |z| is also parenthetic and always sets the imaginary
  69388. Xcomponent to zero.  This means 'c * |z - 4|' first subtracts 4 from z,
  69389. Xcalculates the modulus squared then multiplies times 'c'.  Nested modulus
  69390. Xsquared operators require overriding parenthesis:\
  69391. X      c * |z + (|pixel|)|\
  69392. X
  69393. XThe functions fn1(...) to fn4(...) are variable functions - when used,
  69394. Xthe user is prompted at run time (on the <Z> screen) to specify one of
  69395. Xsin, cos, sinh, cosh, exp, log, sqr, etc. for each required variable function.
  69396. X
  69397. XThe formulas are performed using either integer or floating point
  69398. Xmathematics depending on the <F> floating point toggle.  If you do not
  69399. Xhave an FPU then type MPC math is performed in lieu of traditional
  69400. Xfloating point.
  69401. X
  69402. XThe 'rand' predefined variable is changed with each iteration to a new
  69403. Xrandom number with the real and imaginary components containing a value
  69404. Xbetween zero and 1. Use the srand() function to initialize the random
  69405. Xnumbers to a consistent random number sequence.  If a formula does not
  69406. Xcontain the srand() function, then the formula compiler will use the system
  69407. Xtime to initialize the sequence.  This could cause a different fractal to be
  69408. Xgenerated each time the formula is used depending on how the formula is
  69409. Xwritten.
  69410. X
  69411. XRemember that when using integer math there is a limited dynamic range, so
  69412. Xwhat you think may be a fractal could really be just a limitation of the
  69413. Xinteger math range.  God may work with integers, but His dynamic range is
  69414. Xmany orders of magnitude greater than our puny 32 bit mathematics!  Always
  69415. Xverify with the floating point <F> toggle.
  69416. X;
  69417. X;
  69418. X~Topic=Frothy Basins, Label=HT_FROTH
  69419. X(type=frothybasin)
  69420. X
  69421. XFrothy Basins, or Riddled Basins, were discovered by James C. Alexander of
  69422. Xthe University of Maryland.  The discussion below is derived from a two page
  69423. Xarticle entitled "Basins of Froth" in Science News, November 14, 1992 and
  69424. Xfrom correspondence with others, including Dr. Alexander.
  69425. X
  69426. XThe equations that generate this fractal are not very different from those
  69427. Xthat generate many other orbit fractals.
  69428. X
  69429. X~Format-
  69430. X      z(0) = pixel;
  69431. X      z(n+1) = z(n)^2 - c*conj(z(n))
  69432. X      where c = 1 + ai,  and  a = 1.02871376822...
  69433. X~Format+
  69434. X
  69435. XOne of the things that makes this fractal so interesting is the shape of
  69436. Xthe dynamical system's attractors.  It is not at all uncommon for a
  69437. Xdynamical system to have non-point attractors.  Shapes such as circles are
  69438. Xvery common.  Strange attractors are attractors which are themselves
  69439. Xfractal.  What is unusual about this system, however, is that the
  69440. Xattractors intersect.  This is the first case in which such a phenomenon
  69441. Xhas been observed.  The three attractors for this system are made up of
  69442. Xline segments which overlap to form an equilateral triangle.  This
  69443. Xattractor triangle can be seen by pressing the 'o' key while the fractal
  69444. Xis being generated to turn on the "show orbits" option.
  69445. X
  69446. XAn interesting variation on this fractal can be generated by applying the
  69447. Xabove mapping twice per each iteration.  The result is that each of the
  69448. Xthree attractors is split into two parts, giving the system six
  69449. Xattractors.
  69450. X
  69451. XThese are also called "Riddled Basins" because each basin is riddled with
  69452. Xholes.  Which attractor a point is eventually pulled into is extremely
  69453. Xsensitive to its initial position.  A very slight change in any direction
  69454. Xmay cause it to end up on a different attractor.  As a result, the basins
  69455. Xare thoroughly intermingled. The effect appears to be a frothy mixture that
  69456. Xhas been subjected to lots of stirring and folding.
  69457. X
  69458. XPixel color is determined by which attractor captures the orbit.  The shade
  69459. Xof color is determined by the number of iterations required to capture the
  69460. Xorbit.  In Fractint, the actual shade of color used depends on how many
  69461. Xcolors are available in the video mode being used.
  69462. X
  69463. XIf 256 colors are available, the default coloring scheme is determined by
  69464. Xthe number of iterations that were required to capture the orbit.  An
  69465. Xalternative coloring scheme can be used where the shade is determined by
  69466. Xthe iterations required divided by the maximum iterations.  This method is
  69467. Xespecially useful on deeply zoomed images.
  69468. X
  69469. XIf only 16 colors are available, then only the alternative coloring
  69470. Xscheme is used.  If fewer than 16 colors are available, then Fractint
  69471. Xjust colors the basins without any shading.
  69472. X;
  69473. X;
  69474. X~Topic=Julibrots, Label=HT_JULIBROT
  69475. X(type=julibrot)
  69476. X
  69477. XThe Julibrot fractal type uses a general-purpose renderer for visualizing 
  69478. Xthree dimensional solid fractals. Originally Mark Peterson developed
  69479. Xthis rendering mechanism to view a 3-D sections of a 4-D structure he
  69480. Xcalled a "Julibrot".  This structure, also called "layered Julia set" in 
  69481. Xthe fractal literature, hinges on the relationship between the Mandelbrot 
  69482. Xand Julia sets. Each Julia set is created using a fixed value c in the 
  69483. Xiterated formula z^2 + c. The Julibrot is created by layering Julia sets 
  69484. Xin the x-y plane and continuously varying c, creating new Julia sets as z is
  69485. Xincremented. The solid shape thus created is rendered by shading the surface 
  69486. Xusing a brightness inversely proportional to the virtual viewer's eye. 
  69487. X
  69488. XStarting with Fractint version 18, the Julibrot engine can be used
  69489. Xwith other Julia formulas besides the classic z^2 + c. The first field on 
  69490. Xthe Julibrot parameter screen lets you select which orbit formula to use.
  69491. X
  69492. XYou can also use the Julibrot renderer to visualize 3D cross sections of
  69493. Xtrue four dimensional Quaternion and Hypercomplex fractals. 
  69494. X
  69495. XThe Julibrot Parameter Screens
  69496. X
  69497. XOrbit Algorithm - select the orbit algorithm to use. The available 
  69498. X   possibilities include 2-D Julia and both mandelbrot and Julia variants
  69499. X   of the 4-D Quaternion and Hypercomplex fractals.
  69500. X
  69501. XOrbit parameters - the next screen lets you fill in any parameters 
  69502. X   belonging to the orbit algorithm. This list of parameters is not
  69503. X   necessarily the same as the list normally presented for the orbit
  69504. X   algorithm, because some of these parameters are used in the Julibrot
  69505. X   layering process. 
  69506. X
  69507. X   From/To Parameters
  69508. X   These parameters allow you to specify the "Mandelbrot" values used to
  69509. X   generate the layered Julias. The parameter c in the Julia formulas will
  69510. X   be incremented in steps ranging from the "from" x and y values to the
  69511. X   "to" x and y values. If the orbit formula is one of the "true" four 
  69512. X   dimensional fractal types quat, quatj, hypercomplex, or hypercomplexj, 
  69513. X   then these numbers are used with the 3rd and 4th dimensional values.
  69514. X
  69515. X   The "from/to" variables are different for the different kinds of orbit
  69516. X   algorithm.
  69517. X
  69518. X      2D Julia sets - complex number formula z' = f(z) + c\
  69519. X         The "from/to" parameters change the values of c.\
  69520. X      4D Julia sets - Quaternion or Hypercomplex formula z' = f(z) + c\
  69521. X         The four dimensions of c are set by the orbit parameters.\
  69522. X         The first two dimensions of z are determined by the corners values.\
  69523. X         The third and fourth dimensions of z are the "to/from" variables.\
  69524. X      4D Mandelbrot sets - Quaternion or Hypercomplex formula z' = f(z) + c\
  69525. X         The first two dimensions of c are determined by the corners values.\
  69526. X         The third and fourth dimensions of c are the "to/from" variables.\
  69527. X
  69528. XDistance between the eyes - set this to 2.5 if you want a red/blue
  69529. X   anaglyph image, 0 for a normal greyscale image.
  69530. X
  69531. XNumber of z pixels - this sets how many layers are rendered in the screen
  69532. X   z-axis. Use a higher value with higher resolution video modes.
  69533. X
  69534. XThe remainder of the parameters are needed to construct the red/blue
  69535. Xpicture so that the fractal appears with the desired depth and proper 'z'
  69536. Xlocation.  With the origin set to 8 inches beyond the screen plane and the
  69537. Xdepth of the fractal at 8 inches the default fractal will appear to start
  69538. Xat 4 inches beyond the screen and extend to 12 inches if your eyeballs are
  69539. X2.5 inches apart and located at a distance of 24 inches from the screen.
  69540. XThe screen dimensions provide the reference frame.
  69541. X
  69542. X;
  69543. X;
  69544. X~Topic=Diffusion Limited Aggregation, Label=HT_DIFFUS
  69545. X(type=diffusion)
  69546. X
  69547. XThis type begins with a single point in the center of the screen.
  69548. XSubsequent points move around randomly until coming into contact with the
  69549. Xfirst point, at which time their locations are fixed and they are colored
  69550. Xrandomly.  This process repeats until the fractals reaches the edge of the
  69551. Xscreen.  Use the show orbits function to see the points' random motion.
  69552. X
  69553. XOne unfortunate problem is that on a large screen, this process will tend
  69554. Xto take eons.  To speed things up, the points are restricted to a box
  69555. Xaround the initial point.  The first and only parameter to diffusion
  69556. Xcontains the size of the border between the fractal and the edge of the
  69557. Xbox.  If you make this number small, the fractal will look more solid and
  69558. Xwill be generated more quickly.
  69559. X
  69560. XDiffusion was inspired by a Scientific American article a couple of years
  69561. Xback which includes actual pictures of real physical phenomena that behave
  69562. Xlike this.
  69563. X
  69564. XThanks to Adrian Mariano for providing the diffusion code and
  69565. Xdocumentation. Juan J. Buhler added the additional options.
  69566. X;
  69567. X;
  69568. X~Topic=Lyapunov Fractals, Label=HT_LYAPUNOV
  69569. X(type=lyapunov)
  69570. X
  69571. XThe Bifurcation fractal illustrates what happens in a simple population
  69572. Xmodel as the growth rate increases.  The Lyapunov fractal expands that model
  69573. Xinto two dimensions by letting the growth rate vary in a periodic fashion
  69574. Xbetween two values.  Each pair of growth rates is run through a logistic
  69575. Xpopulation model and a value called the Lyapunov Exponent is calculated for
  69576. Xeach pair and is plotted. The Lyapunov Exponent is calculated by adding up
  69577. Xlog | r - 2*r*x| over many cycles of the population model and dividing by the
  69578. Xnumber of cycles. Negative Lyapunov exponents indicate a stable, periodic
  69579. Xbehavior and are plotted in color. Positive Lyapunov exponents indicate
  69580. Xchaos (or a diverging model) and are colored black.
  69581. X
  69582. XOrder parameter.
  69583. XEach possible periodic sequence yields a two dimensional space to explore.
  69584. XThe Order parameter selects a sequence.  The default value 0 represents the
  69585. Xsequence ab which alternates between the two values of the growth parameter.
  69586. XOn the screen, the a values run vertically and the b values run
  69587. Xhorizontally. Here is how to calculate the space parameter for any desired
  69588. Xsequence.  Take your sequence of a's and b's and arrange it so that it starts
  69589. Xwith at least 2 a's and ends with a b. It may be necessary to rotate the
  69590. Xsequence or swap a's and b's. Strike the first a and the last b off the list
  69591. Xand replace each remaining a with a 1 and each remaining b with a zero.
  69592. XInterpret this as a binary number and convert it into decimal.
  69593. X
  69594. XAn Example.
  69595. XI like sonnets.  A sonnet is a poem with fourteen lines that has the
  69596. Xfollowing rhyming sequence: abba abba abab cc.  Ignoring the rhyming couplet
  69597. Xat the end, let's calculate the Order parameter for this pattern.
  69598. X
  69599. X  abbaabbaabab         doesn't start with at least 2 a's \
  69600. X  aabbaabababb         rotate it \
  69601. X  1001101010           drop the first and last, replace with 0's and 1's \
  69602. X  512+64+32+8+2 = 618
  69603. X
  69604. XAn Order parameter of 618 gives the Lyapunov equivalent of a sonnet.  "How do
  69605. XI make thee? Let me count the ways..."
  69606. X
  69607. XPopulation Seed.
  69608. XWhen two parts of a Lyapunov overlap, which spike overlaps which is strongly
  69609. Xdependent on the initial value of the population model.  Any changes from
  69610. Xusing a different starting value between 0 and 1 may be subtle. The values 0
  69611. Xand 1 are interpreted in a special manner. A Seed of 1 will choose a random
  69612. Xnumber between 0 and 1 at the start of each pixel. A Seed of 0 will suppress
  69613. Xresetting the seed value between pixels unless the population model diverges
  69614. Xin which case a random seed will be used on the next pixel.
  69615. X
  69616. XFilter Cycles.
  69617. XLike the Bifurcation model, the Lyapunov allow you to set the number of
  69618. Xcycles that will be run to allow the model to approach equilibrium before
  69619. Xthe lyapunov exponent calculation is begun. The default value of 0 uses one
  69620. Xhalf of the iterations before beginning the calculation of the exponent.
  69621. XReference.
  69622. XA.K. Dewdney, Mathematical Recreations, Scientific American, Sept. 1991
  69623. X;
  69624. X;
  69625. X~Topic=Magnetic Fractals, Label=HT_MAGNET
  69626. X(type=magnet1m/.../magnet2j)
  69627. X
  69628. XThese fractals use formulae derived from the study of hierarchical
  69629. Xlattices, in the context of magnetic renormalisation transformations.
  69630. XThis kinda stuff is useful in an area of theoretical physics that deals
  69631. Xwith magnetic phase-transitions (predicting at which temperatures a given
  69632. Xsubstance will be magnetic, or non-magnetic).  In an attempt to clarify
  69633. Xthe results obtained for Real temperatures (the kind that you and I can
  69634. Xfeel), the study moved into the realm of Complex Numbers, aiming to spot
  69635. XReal phase-transitions by finding the intersections of lines representing
  69636. XComplex phase-transitions with the Real Axis.  The first people to try
  69637. Xthis were two physicists called Yang and Lee, who found the situation a
  69638. Xbit more complex than first expected, as the phase boundaries for Complex
  69639. Xtemperatures are (surprise!) fractals.
  69640. X
  69641. XAnd that's all the technical (?) background you're getting here!  For more
  69642. Xdetails (are you SERIOUS ?!) read "The Beauty of Fractals".  When you
  69643. Xunderstand it all, you might like to rewrite this section, before you
  69644. Xstart your new job as a professor of theoretical physics...
  69645. X
  69646. XIn Fractint terms, the important bits of the above are "Fractals",
  69647. X"Complex Numbers", "Formulae", and "The Beauty of Fractals".  Lifting the
  69648. XFormulae straight out of the Book and iterating them over the Complex
  69649. Xplane (just like the Mandelbrot set) produces Fractals.
  69650. X
  69651. XThe formulae are a bit more complicated than the Z^2+C used for the
  69652. XMandelbrot Set, that's all.  They are :
  69653. X
  69654. X~Format-
  69655. X          [          ] 2
  69656. X          |  Z^2 + (C-1)  |
  69657. X    MAGNET1 : | ------------- | 
  69658. X          |  2*Z + (C-2)  |
  69659. X          [          ]
  69660. X
  69661. X          [                        ] 2
  69662. X          |     Z^3 + 3*(C-1)*Z + (C-1)*(C-2)        |
  69663. X    MAGNET2 : | --------------------------------------- | 
  69664. X          |  3*(Z^2) + 3*(C-2)*Z + (C-1)*(C-2) + 1  |
  69665. X          [                        ]
  69666. X~Format+
  69667. X
  69668. XThese aren't quite as horrific as they look (oh yeah ?!) as they only
  69669. Xinvolve two variables (Z and C), but cubing things, doing division, and
  69670. Xeventually squaring the result (all in Complex Numbers) don't exactly
  69671. Xspell S-p-e-e-d !  These are NOT the fastest fractals in Fractint !
  69672. X
  69673. XAs you might expect, for both formulae there is a single related
  69674. XMandelbrot-type set (magnet1m, magnet2m) and an infinite number of related
  69675. XJulia-type sets (magnet1j, magnet2j), with the usual toggle between the
  69676. Xcorresponding Ms and Js via the spacebar.
  69677. X
  69678. XIf you fancy delving into the Julia-types by hand, you will be prompted
  69679. Xfor the Real and Imaginary parts of the parameter denoted by C.  The
  69680. Xresult is symmetrical about the Real axis (and therefore the initial image
  69681. Xgets drawn in half the usual time) if you specify a value of Zero for the
  69682. XImaginary part of C.
  69683. X
  69684. XFractint Historical Note:  Another complication (besides the formulae) in
  69685. Ximplementing these fractal types was that they all have a finite attractor
  69686. X(1.0 + 0.0i), as well as the usual one (Infinity).  This fact spurred the
  69687. Xdevelopment of Finite Attractor logic in Fractint.  Without this code you
  69688. Xcan still generate these fractals, but you usually end up with a pretty
  69689. Xboring image that is mostly deep blue "lake", courtesy of Fractint's
  69690. Xstandard {Periodicity Logic}.
  69691. XSee {Finite Attractors} for more
  69692. Xinformation on this aspect of Fractint internals.
  69693. X
  69694. X(Thanks to Kevin Allen for Magnetic type documentation above).
  69695. X;
  69696. X;
  69697. X~Topic=L-Systems, Label=HT_LSYS
  69698. X(type=lsystem)
  69699. X
  69700. XThese fractals are constructed from line segments using rules specified in
  69701. Xdrawing commands.  Starting with an initial string, the axiom,
  69702. Xtransformation rules are applied a specified number of times, to produce
  69703. Xthe final command string which is used to draw the image.
  69704. X
  69705. XLike the type=formula fractals, this type requires a separate data file.
  69706. XA sample file, FRACTINT.L, is included with this distribution.    When you
  69707. Xselect type lsystem, the current lsystem file is read and you are asked
  69708. Xfor the lsystem name you wish to run. Press <F6> at this point if you wish
  69709. Xto use a different lsystem file. After selecting an lsystem, you are asked
  69710. Xfor one parameter - the "order", or number of times to execute all the
  69711. Xtransformation rules.  It is wise to start with small orders, because the
  69712. Xsize of the substituted command string grows exponentially and it is very
  69713. Xeasy to exceed your resolution.  (Higher orders take longer to generate
  69714. Xtoo.)  The command line options "lname=" and "lfile=" can be used to over-
  69715. Xride the default file name and lsystem name.
  69716. X
  69717. XEach L-System entry in the file contains a specification of the angle, the
  69718. Xaxiom, and the transformation rules.  Each item must appear on its own
  69719. Xline and each line must be less than 160 characters long.
  69720. X
  69721. XThe statement "angle n" sets the angle to 360/n degrees; n must be an
  69722. Xinteger greater than two and less than fifty.
  69723. X
  69724. X"Axiom string" defines the axiom.
  69725. X
  69726. XTransformation rules are specified as "a=string" and convert the single
  69727. Xcharacter 'a' into "string."  If more than one rule is specified for a
  69728. Xsingle character all of the strings will be added together.  This allows
  69729. Xspecifying transformations longer than the 160 character limit.
  69730. XTransformation rules may operate on any characters except space, tab or
  69731. X'}'.
  69732. X
  69733. XAny information after a ; (semi-colon) on a line is treated as a comment.
  69734. X
  69735. XHere is a sample lsystem:
  69736. X
  69737. X~Format-
  69738. XDragon \{      ; Name of lsystem, \{ indicates start
  69739. X  Angle 8     ; Specify the angle increment to 45 degrees
  69740. X  Axiom FX     ; Starting character string
  69741. X  F=         ; First rule:    Delete 'F'
  69742. X  y=+FX--FY+     ; Change 'y' into  "+fx--fy+"
  69743. X  x=-FX++FY-     ; Similar transformation on 'x'
  69744. X}         ; final } indicates end
  69745. X
  69746. XThe standard drawing commands are:
  69747. X    F Draw forward
  69748. X    G Move forward (without drawing)
  69749. X    + Increase angle
  69750. X    - Decrease angle
  69751. X    | Try to turn 180 degrees. (If angle is odd, the turn
  69752. X      will be the largest possible turn less than 180 degrees.)
  69753. X~Format+
  69754. X
  69755. XThese commands increment angle by the user specified angle value. They
  69756. Xshould be used when possible because they are fast. If greater flexibility
  69757. Xis needed, use the following commands which keep a completely separate
  69758. Xangle pointer which is specified in degrees.
  69759. X
  69760. X~Format-
  69761. X    D    Draw forward
  69762. X    M    Move forward
  69763. X    \nn Increase angle nn degrees
  69764. X    /nn Decrease angle nn degrees
  69765. X
  69766. XColor control:
  69767. X    Cnn Select color nn
  69768. X    <nn Increment color by nn
  69769. X    >nn decrement color by nn
  69770. X
  69771. XAdvanced commands:
  69772. X    !      Reverse directions (Switch meanings of +, - and \, /)
  69773. X    @nnn  Multiply line segment size by nnn
  69774. X      nnn may be a plain number, or may be preceded by
  69775. X          I for inverse, or Q for square root.
  69776. X          (e.g.  @IQ2 divides size by the square root of 2)
  69777. X    [      Push.  Stores current angle and position on a stack
  69778. X    ]      Pop.    Return to location of last push
  69779. X~Format+
  69780. X
  69781. XOther characters are perfectly legal in command strings.  They are ignored
  69782. Xfor drawing purposes, but can be used to achieve complex translations.
  69783. X;
  69784. X;
  69785. X;
  69786. SHAR_EOF
  69787. $TOUCH -am 1028230193 help2.src &&
  69788. chmod 0644 help2.src ||
  69789. echo "restore of help2.src failed"
  69790. set `wc -c help2.src`;Wc_c=$1
  69791. if test "$Wc_c" != "116316"; then
  69792.     echo original size 116316, current size $Wc_c
  69793. fi
  69794. # ============= help3.src ==============
  69795. echo "x - extracting help3.src (Text)"
  69796. sed 's/^X//' << 'SHAR_EOF' > help3.src &&
  69797. X~Topic=Doodads\, Bells\, and Whistles
  69798. X
  69799. X~Format-
  69800. X   { Drawing Method }
  69801. X   { Autokey Mode }
  69802. X   { Distance Estimator Method }
  69803. X   { Inversion }
  69804. X   { Decomposition }
  69805. X   { Logarithmic Palettes and Color Ranges }
  69806. X   { Biomorphs }
  69807. X   { Continuous Potential }
  69808. X   { Starfields }
  69809. X~Format+
  69810. X;
  69811. X;
  69812. X;
  69813. X~Topic=Drawing Method
  69814. X
  69815. XThe "passes option" (<X> options screen or "passes=" parameter)
  69816. Xselects single-pass, dual-pass, or solid-guessing
  69817. X(default) mode.  This option applies to most fractal types.
  69818. X
  69819. XSingle-pass mode ("1") draws the screen pixel by pixel.
  69820. X
  69821. XDual-pass ("2") generates a "coarse" screen first as a preview
  69822. Xusing 2x2-pixel boxes, and then generates the rest of the dots with a
  69823. Xsecond pass.
  69824. X
  69825. XSolid-guessing ("g") is the default.  It performs from two to four
  69826. Xvisible passes -
  69827. Xmore in higher resolution video modes. Its first visible pass is
  69828. Xactually two passes - one pixel per 4x4, 8x8, or 16x16 pixel box
  69829. Xis generated, and the guessing logic is
  69830. Xapplied to fill in the blocks at the next level (2x2, 4x4, or 8x8).
  69831. XSubsequent passes fill in the display at the next finer resolution,
  69832. Xskipping blocks which are surrounded by the same color. Solid-guessing can
  69833. Xguess wrong, but it sure guesses quickly!
  69834. X
  69835. XBoundary Tracing ("b"), which only
  69836. Xworks with fractal types (such as the Mandelbrot set, but not the Newton
  69837. Xtype) that do not contain "islands" of colors, finds a color "boundary",
  69838. Xtraces it around the screen, and then "blits" in the color over the
  69839. Xenclosed area.
  69840. X
  69841. XTesseral ("t") is a sort of "super-solid-guessing" option that successively
  69842. Xdivides the image into subsections.  It's actually slower than the
  69843. Xsolid-guessing algorithm, but it looks neat, so we left it in.\
  69844. X
  69845. XThe "fillcolor=" option in the <X> screen or on the command line sets a 
  69846. Xfixed color to be used by the Boundary Tracing and Tesseral calculations 
  69847. Xfor filling in defined regions. The effect of this is to show off the 
  69848. Xboundaries of the areas delimited by these two methods. 
  69849. X;
  69850. X;
  69851. X~Topic=Autokey Mode
  69852. X
  69853. XThe autokey feature allows you to set up beautiful self-running demo
  69854. X"loops". You can set up hypnotic sequences to attract people to a booth,
  69855. Xto generate sequences for special effects, to teach how Fractal exploring
  69856. Xis done, etc.
  69857. X
  69858. XA sample autokey file (DEMO.KEY) and a batch to run it (DEMO.BAT) are
  69859. Xincluded with Fractint. Type "demo" at the DOS prompt to run it.
  69860. X
  69861. XAutokey record mode is enabled with the command line parameter
  69862. X"AUTOKEY=RECORD". Keystrokes are saved in an intelligible text format in a
  69863. Xfile called AUTO.KEY. You can change the file name with the "AUTOKEYNAME="
  69864. Xparameter.
  69865. X
  69866. XPlayback is enabled with the parameter "AUTOKEY=PLAY". Playback can be
  69867. Xterminated by pressing the <Esc> key.
  69868. X
  69869. XAfter using record mode to capture an autokey file, you'll probably want
  69870. Xto touch it up using your editor before playing it back.
  69871. X
  69872. XSeparate lines are not necessary but you'll probably find it
  69873. Xeasier to understand an autokey file if you put each command on a separate
  69874. Xline. Autokey files can contain the following:
  69875. X
  69876. X  Quoted strings. Fractint reads whatever is between the quotes just as if
  69877. X  you had typed it. For example,
  69878. X      "t" "ifs"
  69879. X  issues the "t" (type) command and then enters the letters i", "f", and
  69880. X  "s" to select the ifs type.
  69881. X
  69882. X  Symbols for function keys used to select a video mode. Examples:\
  69883. X      F3  -- Function key 3\
  69884. X      SF3 --<Shift> and <F3> together\
  69885. X
  69886. X  Special keys: ENTER ESC F1 PAGEUP PAGEDOWN HOME END LEFT RIGHT UP DOWN
  69887. X  INSERT DELETE TAB
  69888. X
  69889. X  WAIT <nnn.n> -- wait nnn.n seconds before continuing
  69890. X
  69891. X  CALCWAIT -- pause until the current fractal calculation or file save or
  69892. X  restore is finished. This command makes demo files more robust since
  69893. X  calculation times depend on the  speed of the machine running the demo -
  69894. X  a "WAIT 10" command may allow enough time to complete a fractal on one
  69895. X  machine, but not on another. The record mode does not generate this
  69896. X  command - it should be added by hand to the autokey file whenever there
  69897. X  is a process that should be allowed to run to completion.
  69898. X
  69899. X  GOTO target -- The autokey file continues to be read from the label
  69900. X  "target". The label can be any word that does not duplicate a key word.
  69901. X  It must be present somewhere in the autokey file with a colon after it.
  69902. X  Example:\
  69903. X      MESSAGE 2 This is executed once\
  69904. X      start:\
  69905. X      MESSAGE 2 This is executed repeatedly\
  69906. X      GOTO start\
  69907. X  GOTO is mainly useful for writing continuous loop demonstrations. It can
  69908. X  also be useful when debugging an autokey file, to skip sections of it.
  69909. X
  69910. X  ; -- A semi-colon indicates that the rest of the line containing it is a
  69911. X  comment.
  69912. X
  69913. X  MESSAGE nn <Your message here> -- Places a message on the top of the
  69914. X  screen for nn seconds
  69915. X
  69916. XMaking Fractint demos can be tricky. Here are some suggestions which may
  69917. Xhelp:
  69918. X
  69919. X  Start Fractint with "fractint autokeyname=mydemo.key autokey=record".
  69920. X  Use a unique name each time you run so that you don't overwrite prior
  69921. X  files.
  69922. X
  69923. X  When in record mode, avoid using the cursor keys to select filenames,
  69924. X  fractal types, formula names, etc. Instead, try to type in names. This
  69925. X  will ensure that the exact item you want gets chosen during playback
  69926. X  even if the list is different then.
  69927. X
  69928. X  Beware of video mode assumptions. It is safest to build a separate demo
  69929. X  for different resolution monitors.
  69930. X
  69931. X  When in the record mode, try to type names quickly, then pause. If you
  69932. X  pause partway through a name Fractint will break up the string in the
  69933. X  .KEY file. E.g. if you paused in the middle of typing fract001, you
  69934. X  might get:\
  69935. X      "fract"\
  69936. X      WAIT 2.2\
  69937. X      "001"\
  69938. X  No harm done, but messy to clean up. Fractint ignores pauses
  69939. X  less than about 1/2 second.
  69940. X
  69941. X  DO pause when you want the viewer to see what is happening during
  69942. X  playback.
  69943. X
  69944. X  When done recording, clean up your mydemo.key file. Insert a CALCWAIT
  69945. X  after each keystroke which triggers something that takes a variable
  69946. X  amount of time (calculating a fractal, restoring a file, saving a file).
  69947. X
  69948. X  Add comments with ";" to the file so you know what is going on in
  69949. X  future.
  69950. X
  69951. X  It is a good idea to use INSERT before a GOTO which restarts the demo.
  69952. X  The <insert> key resets Fractint as if you exited the program and
  69953. X  restarted it.
  69954. X
  69955. XWarning: an autokey file built for this version of Fractint will probably
  69956. Xrequire some retouching before it works with future releases of Fractint.
  69957. XWe have no intention of making sure that the same sequence of keystrokes
  69958. Xwill have exactly the same effect from one version of Fractint to the
  69959. Xnext. That would require pretty much freezing Fractint development, and we
  69960. Xjust love to keep enhancing it!
  69961. X;
  69962. X;
  69963. X;
  69964. X~Topic=Distance Estimator Method
  69965. X
  69966. XThis is Phil Wilson's implementation of an alternate method for the M and
  69967. XJ sets, based on work by mathematician John Milnor and described in "The
  69968. XScience of Fractal Images", p. 198.  While it can take full advantage of
  69969. Xyour color palette, one of the best uses is in preparing monochrome images
  69970. Xfor a printer.    Using the 1600x1200x2 disk-video mode and an HP LaserJet,
  69971. Xwe have produced pictures of quality equivalent to the black and white
  69972. Xillustrations of the M-set in "The Beauty of Fractals."
  69973. X
  69974. XThe distance estimator method widens very thin "strands" which are part of
  69975. Xthe "inside" of the set.  Instead of hiding invisibly between pixels,
  69976. Xthese strands are made one pixel wide.
  69977. X
  69978. XThough this option is available with any escape time fractal type, the
  69979. Xformula used is specific to the mandel and julia types - for most other
  69980. Xtypes it doesn't do a great job.
  69981. X
  69982. XTo turn on the distance estimator method with any escape time  fractal
  69983. Xtype, set the "Distance Estimator" value on the <Y> options screen (or use
  69984. Xthe "distest=" command line parameter).
  69985. X
  69986. XSetting the distance estimator option to a negative value -nnn enables
  69987. Xedge-tracing mode.  The edge of the set is display as color number nnn.
  69988. XThis option works best when the "inside" and "outside" color values are
  69989. Xalso set to some other value(s).
  69990. X
  69991. XIn a 2 color (monochrome) mode, setting to any positive value results in
  69992. Xthe inside of the set being expanded to include edge points, and the
  69993. Xoutside points being displayed in the other color.
  69994. X
  69995. XIn color modes, setting to value 1 causes the edge points to be displayed
  69996. Xusing the inside color and the outside points to be displayed in their
  69997. Xusual colors.  Setting to a value greater than one causes the outside
  69998. Xpoints to be displayed as contours, colored according to their distance
  69999. Xfrom the inside of the set.  Use a higher value for narrower color bands,
  70000. Xa lower value for wider ones.  1000 is a good value to start with.
  70001. X
  70002. XThe second distance estimator parameter ("width factor") sets the distance
  70003. Xfrom the inside of the set which is to be considered as part of the
  70004. Xinside.  This value is expressed as a percentage of a pixel width, the
  70005. Xdefault is 71.
  70006. X
  70007. XYou should use 1 or 2 pass mode with the distance estimator method, to
  70008. Xavoid missing some of the thin strands made visible by it.  For the
  70009. Xhighest quality, "maxiter" should also be set to a high value, say 1000 or
  70010. Xso.  You'll probably also want "inside" set to zero, to get a black
  70011. Xinterior.
  70012. X
  70013. XEnabling the distance estimator method automatically toggles to floating
  70014. Xpoint mode. When you reset distest back to zero, remember to also turn off
  70015. Xfloating point mode if you want it off.
  70016. X
  70017. XUnfortunately, images using the distance estimator method can take many
  70018. Xhours to calculate even on a fast machine with a coprocessor, especially
  70019. Xif a high "maxiter" value is used.  One way of dealing with this is to
  70020. Xleave it turned off while you find and frame an image.    Then hit <B> to
  70021. Xsave the current image information in a parameter file
  70022. X(see {Parameter Save/Restore Commands}).  Use an editor to change the parameter
  70023. Xfile entry, adding "distest=1", "video=something" to select a high-
  70024. Xresolution monochrome disk-video mode, "maxiter=1000", and "inside=0". Run
  70025. Xthe parameter file entry with the <@> command when you won't be needing
  70026. Xyour machine for a while (over the weekend?)
  70027. X;
  70028. X;
  70029. X;
  70030. X~Topic=Inversion
  70031. X
  70032. XMany years ago there was a brief craze for "anamorphic art": images
  70033. Xpainted and viewed with the use of a cylindrical mirror, so that  they
  70034. Xlooked weirdly distorted on the canvas but correct in the distorted
  70035. Xreflection. (This byway of art history may be a useful defense when your
  70036. Xfriends and family give you odd looks for staring at fractal images color-
  70037. Xcycling on a CRT.)
  70038. X
  70039. XThe Inversion option performs a related transformation on most of the
  70040. Xfractal types. You define the center point and radius of a circle;
  70041. XFractint maps each point inside the circle to a corresponding point
  70042. Xoutside, and vice-versa. This is known to mathematicians as inverting (or
  70043. Xif you want to get precise, "everting") the plane, and is something they
  70044. Xcan contemplate without getting a headache. John Milnor (also mentioned
  70045. Xin connection with the {Distance Estimator Method}), made his name in the
  70046. X1950s with a method for everting a seven-dimensional sphere, so we have a
  70047. Xlot of catching up to do.
  70048. X
  70049. XFor example, if a point inside the circle is 1/3 of the way from the
  70050. Xcenter to the radius, it is mapped to a point along the same radial line,
  70051. Xbut at a distance of (3 * radius) from the origin. An outside point at 4
  70052. Xtimes the radius is mapped inside at 1/4 the radius.
  70053. X
  70054. XThe inversion parameters on the <Y> options screen allow entry of the
  70055. Xradius and center coordinates of the inversion circle. A default choice of
  70056. X-1 sets the radius at 1/6 the smaller dimension of the image currently on
  70057. Xthe screen.  The default values for Xcenter and Ycenter use the
  70058. Xcoordinates currently mapped to the center of the screen.
  70059. X
  70060. XTry this one out with a {=HT_NEWT Newton} plot, so its radial "spokes"
  70061. Xwill give you
  70062. Xsomething to hang on to. Plot a Newton-method image, then set the
  70063. Xinversion radius to 1, with default center coordinates. The center
  70064. X"explodes" to the periphery.
  70065. X
  70066. XInverting through a circle not centered on the origin produces bizarre
  70067. Xeffects that we're not even going to try to describe. Aren't computers
  70068. Xwonderful?
  70069. X;
  70070. X;
  70071. X;
  70072. X~Topic=Decomposition
  70073. X
  70074. XYou'll remember that most fractal types are calculated by iterating a
  70075. Xsimple function of a complex number, producing another complex number,
  70076. Xuntil either the number exceeds some pre-defined "bailout" value, or the
  70077. Xiteration limit is reached. The pixel corresponding to the starting point
  70078. Xis then colored based on the result of that calculation.
  70079. X
  70080. XThe decomposition option ("decomp=", on the <X> screen) toggles to another
  70081. Xcoloring protocol.  Here the points are colored according to which
  70082. Xquadrant of the complex plane (negative real/positive imaginary, positive
  70083. Xreal/positive imaginary, etc.) the final value is in. If you use 4 as the
  70084. Xparameter, points ending up in each quadrant are given their own color; if
  70085. X2 (binary decomposition), points in alternating quadrants are given 2
  70086. Xalternating colors.
  70087. X
  70088. XThe result is a kind of warped checkerboard coloring, even in areas that
  70089. Xwould ordinarily be part of a single contour. Remember, for the M-set all
  70090. Xpoints whose final values exceed 2 (by any amount) after, say, 80
  70091. Xiterations are normally the same color; under decomposition, Fractint runs
  70092. X[bailout-value] iterations and then colors according to where the actual
  70093. Xfinal value falls on the complex plane.
  70094. X
  70095. XWhen using decomposition, a higher bailout value will give a more accurate
  70096. Xplot, at some expense in speed.  You might want to set the bailout value
  70097. X(in the parameters prompt following selection of a new fractal type;
  70098. Xpresent for most but not all types) to a higher value than the default.  A
  70099. Xvalue of about 50 is a good compromise for M/J sets.
  70100. X;
  70101. X;
  70102. X;
  70103. X~Topic=Logarithmic Palettes and Color Ranges
  70104. X
  70105. XBy default, Fractint maps iterations to colors 1:1. I.e. if the
  70106. Xcalculation for a fractal "escapes" (exceeds the bailout value) after N
  70107. Xiterations, the pixel is colored as color number N. If N is greater than
  70108. Xthe number of colors available, it wraps around. So, if you are using a
  70109. X16-color video mode, and you are using the default maximum iteration count
  70110. Xof 150, your image will run through the 16-color palette 150/16 = 9.375
  70111. Xtimes.
  70112. X
  70113. XWhen you use Logarithmic palettes, the entire range of iteration values is
  70114. Xcompressed to map to one span of the color range.  This results in
  70115. Xspectacularly different images if you are using a high iteration limit
  70116. Xnear the current iteration maximum of 32000 and are zooming in on an area
  70117. Xnear a "lakelet".
  70118. X
  70119. XWhen using a compressed palette in a 256 color mode, we suggest changing
  70120. Xyour colors from the usual defaults.  The last few colors in the default
  70121. XIBM VGA color map are black.  This results in points nearest the "lake"
  70122. Xsmearing into a single dark band, with little contrast from the blue (by
  70123. Xdefault) lake.
  70124. X
  70125. XFractint has a number of types of compressed palette, selected by the "Log
  70126. XPalette" line on the <X> screen, or by the "logmap=" command line
  70127. Xparameter:
  70128. X
  70129. X  logmap=1: for standard logarithmic palette.
  70130. X
  70131. X  logmap=-1: "old" logarithmic palette. This variant was the only one used
  70132. X  before Fractint 14.0. It differs from logmap=1 in that some colors are
  70133. X  not used - logmap=1 "spreads" low color numbers which are unused by
  70134. X  logmap=-1's pure logarithmic mapping so that all colors are assigned.
  70135. X
  70136. X  logmap=N (>1): Same as logmap=1, but starting from iteration count N.
  70137. X  Pixels with iteration counts less than N are mapped to color 1. This is
  70138. X  useful when zooming in an area near the lake where no points in the
  70139. X  image have low iteration counts - it makes use of the low colors which
  70140. X  would otherwise be unused.
  70141. X
  70142. X  logmap=-N (<-1): Similar to logmap=N, but uses a square root
  70143. X  distribution of the colors instead of a logarithmic one.
  70144. X
  70145. X  logmap=2 or -2: Auto calculates the logmap value for maximum effect.
  70146. X
  70147. XAnother way to change the 1:1 mapping of iteration counts to colors is to
  70148. Xuse the "RANGES=" parameter.  It has the format:\
  70149. X   RANGES=aa/bb/cc/dd/...
  70150. X
  70151. XIteration counts up to and including the first value are mapped to color
  70152. Xnumber 0, up to and including the second value to color number 1, and so
  70153. Xon. The values must be in ascending order.
  70154. X
  70155. XA negative value can be specified for "striping". The negative value
  70156. Xspecifies a stripe width, the value following it specifies the limit of
  70157. Xthe striped range.  Two alternating colors are used within the striped
  70158. Xrange.
  70159. X
  70160. XExample:\
  70161. X   RANGES=0/10/30/-5/65/79/32000\
  70162. XThis example maps iteration counts to colors as follows:
  70163. X
  70164. X~Format-
  70165. X    color    iterations
  70166. X    -------------------
  70167. X      0      unused (formula always iterates at least once)
  70168. X      1       1 to 10
  70169. X      2      11 to 30
  70170. X      3      31 to 35, 41 to 45, 51 to 55, and 61 to 65
  70171. X      4      36 to 40, 46 to 50, and 56 to 60
  70172. X      5      66 to 79
  70173. X      6      80 and greater
  70174. X~Format+
  70175. XNote that the maximum value in a RANGES parameter is 32767.
  70176. X;
  70177. X;
  70178. X;
  70179. X~Topic=Biomorphs, Label=@Biomorphs
  70180. X
  70181. XRelated to {Decomposition} are the "biomorphs" invented by Clifford
  70182. XPickover, and discussed by A. K. Dewdney in the July 1989 "Scientific
  70183. XAmerican", page 110.  These are so-named because this coloring scheme
  70184. Xmakes many fractals look like one-celled animals.  The idea is simple.
  70185. XThe escape-time algorithm terminates an iterating formula when the size of
  70186. Xthe orbit value exceeds a predetermined bailout value. Normally the pixel
  70187. Xcorresponding to that orbit is colored according to the iteration when
  70188. Xbailout happened. To create biomorphs, this is modified so that if EITHER
  70189. Xthe real OR the imaginary component is LESS than the bailout, then the
  70190. Xpixel is set to the "biomorph" color. The effect is a bit better with
  70191. Xhigher bailout values: the bailout is automatically set to 100 when this
  70192. Xoption is in effect. You can try other values with the "bailout=" option.
  70193. X
  70194. XThe biomorph option is turned on via the "biomorph=nnn" command-line
  70195. Xoption (where "nnn" is the color to use on the affected pixels).  When
  70196. Xtoggling to Julia sets, the default corners are three times bigger than
  70197. Xnormal to allow seeing the biomorph appendages. Does not work with all
  70198. Xtypes - in particular it fails with any of the mandelsine family. However,
  70199. Xif you are stuck with monochrome graphics, try it - works great in two-
  70200. Xcolor modes. Try it with the marksmandel and marksjulia types.
  70201. X;
  70202. X;
  70203. X;
  70204. X~Topic=Continuous Potential
  70205. X
  70206. XNote: This option can only be used with 256 color modes.
  70207. X
  70208. XFractint's images are usually calculated by the "level set" method,
  70209. Xproducing bands of color corresponding to regions where the calculation
  70210. Xgives the same value. When "3D" transformed (see {\"3D\" Images}),
  70211. Xmost images other than plasma
  70212. Xclouds are like terraced landscapes: most of the surface is either
  70213. Xhorizontal or vertical.
  70214. X
  70215. XTo get the best results with the "illuminated" 3D fill options 5 and 6,
  70216. Xthere is an alternative approach that yields continuous changes in colors.
  70217. X
  70218. XContinuous potential is approximated by calculating
  70219. X
  70220. X     potential =  log(modulus)/2^iterations
  70221. X
  70222. Xwhere "modulus" is the orbit value (magnitude of the complex number) when
  70223. Xthe modulus bailout was exceeded, at the "iterations" iteration.  Clear as
  70224. Xmud, right?
  70225. X
  70226. XFortunately, you don't have to understand all the details. However, there
  70227. XARE a few points to understand. First, Fractint's criterion for halting a
  70228. Xfractal calculation, the "modulus bailout value", is generally set to 4.
  70229. XContinuous potential is inaccurate at such a low value.
  70230. X
  70231. XThe bad news is that the integer math which makes the "mandel" and "julia"
  70232. Xtypes so fast imposes a hard-wired maximum value of 127. You can still
  70233. Xmake interesting images from those types, though, so don't avoid them. You
  70234. Xwill see "ridges" in the "hillsides." Some folks like the effect.
  70235. X
  70236. XThe good news is that the other fractal types, particularly the (generally
  70237. Xslower) floating point algorithms, have no such limitation.  The even
  70238. Xbetter news is that there is a floating-point algorithm for the "mandel"
  70239. Xand "julia" types.  To force the use of a floating-point algorithm, use
  70240. XFractint with the "FLOAT=YES" command-line toggle.  Only a few fractal
  70241. Xtypes like plasma clouds, the Barnsley IFS type, and "test" are unaffected
  70242. Xby this toggle.
  70243. X
  70244. XThe parameters for continuous potential are:\
  70245. X    potential=maxcolor[/slope[/modulus[/16bit]]]\
  70246. XThese parameters are present on the <Y> options screen.
  70247. X
  70248. X"Maxcolor" is the color corresponding to zero potential, which plots as
  70249. Xthe TOP of the mountain. Generally this should be set to one less than the
  70250. Xnumber of colors, i.e. usually 255. Remember that the last few colors of
  70251. Xthe default IBM VGA palette are BLACK, so you won't see what you are
  70252. Xreally getting unless you change to a different palette.
  70253. X
  70254. X"Slope" affects how rapidly the colors change -- the slope of the
  70255. X"mountains" created in 3D. If this is too low, the palette will not cover
  70256. Xall the potential values and large areas will be black. If it is too high,
  70257. Xthe range of colors in the picture will be much less than those available.
  70258. XThere is no easy way to predict in advance what this value should be.
  70259. X
  70260. X"Modulus" is the bailout value used to determine when an orbit has
  70261. X"escaped". Larger values give more accurate and smoother potential. A
  70262. Xvalue of 500 gives excellent results. As noted, this value must be <128
  70263. Xfor the integer fractal types (if you select a higher number, they will
  70264. Xuse 127).
  70265. X
  70266. X"16bit":  If you transform a continuous potential image to 3D, the
  70267. Xillumination modes 5 and 6 will work fine, but the colors will look a bit
  70268. Xgranular. This is because even with 256 colors, the continuous potential
  70269. Xis being truncated to integers. The "16bit" option can be used to add an
  70270. Xextra 8 bits of goodness to each stored pixel, for a much smoother result
  70271. Xwhen transforming to 3D.
  70272. X
  70273. XFractint's visible behavior is unchanged when 16bit is enabled, except
  70274. Xthat solid guessing and boundary tracing are not used. But when you save
  70275. Xan image generated with 16bit continuous potential:\
  70276. X o The saved file is a fair bit larger.\
  70277. X o Fractint names the file with a .POT extension instead of .GIF, if you
  70278. X   didn't specify an extension in "savename".
  70279. X o The image can be used as input to a subsequent <3> command to get the
  70280. X   promised smoother effect.
  70281. X o If you happen to view the saved image with a GIF viewer other than
  70282. X   Fractint, you'll find that it is twice as wide as it is supposed to
  70283. X   be. (Guess where the extra goodness was stored!) Though these files
  70284. X   are structurally legal GIF files the double-width business made us
  70285. X   think they should perhaps not be called GIF - hence the .POT filename
  70286. X   extension.
  70287. X
  70288. XA 16bit (.POT) file can be converted to an ordinary 8 bit GIF by
  70289. X<R>estoring it, changing "16bit" to "no" on the <Y> options screen, and
  70290. X<S>aving.
  70291. X
  70292. XYou might find with 16bit continuous potential that there's a long delay
  70293. Xat the start of an image, and disk activity during calculation. Fractint
  70294. Xuses its disk-video cache area to store the extra 8 bits per pixel - if
  70295. Xthere isn't sufficient memory available, the cache will page to disk.
  70296. X
  70297. XThe following commands can be used to recreate the image that Mark
  70298. XPeterson first prototyped for us, and named "MtMand":
  70299. X
  70300. X    TYPE=mandel\
  70301. X    CORNERS=-0.19920/-0.11/1.0/1.06707\
  70302. X    INSIDE=255\
  70303. X    MAXITER=255\
  70304. X    POTENTIAL=255/2000/1000/16bit\
  70305. X    PASSES=1\
  70306. X    FLOAT=yes\
  70307. X
  70308. XNote that prior to version 15.0, Fractint:\
  70309. X o Produced "16 bit TGA potfiles" This format is no longer generated, but
  70310. X   you can still (for a release or two) use <R> and <3> with those files.
  70311. X o Assumed "inside=maxit" for continuous potential. It now uses the
  70312. X   current "inside=" value - to recreate prior results you must be
  70313. X   explicit about this parameter.
  70314. X;
  70315. X;
  70316. X;
  70317. X~Topic=Starfields, Label=HELPSTARFLD
  70318. X
  70319. XOnce you have generated your favorite fractal image, you can convert it
  70320. Xinto a fractal starfield with the 'a' transformation (for 'astronomy'? -
  70321. Xonce again, all of the good letters were gone already).  Stars are
  70322. Xgenerated on a pixel-by-pixel basis - the odds that a particular pixel
  70323. Xwill coalesce into a star are based (partially) on the color index of that
  70324. Xpixel.
  70325. X
  70326. X(The following was supplied by Mark Peterson, the starfield author).
  70327. X
  70328. XIf the screen were entirely black and the 'Star Density per Pixel' were
  70329. Xset to 30 then a starfield transformation would create an evenly
  70330. Xdistributed starfield with an average of one star for every 30 pixels.
  70331. X
  70332. XIf you're on a 320x200 screen then you have 64000 pixels and would end up
  70333. Xwith about 2100 stars.    By introducing the variable of 'Clumpiness' we can
  70334. Xcreate more stars in areas that have higher color values.  At 100%
  70335. XClumpiness a color value of 255 will change the average of finding a star
  70336. Xat that location to 50:50.  A lower clumpiness values will lower the
  70337. Xamount of probability weighting.  To create a spiral galaxy draw your
  70338. Xfavorite spiral fractal (IFS, Julia, or Mandelbrot) and perform a
  70339. Xstarfield transformation.  For general starfields I'd recommend
  70340. Xtransforming a plasma fractal.
  70341. X
  70342. XReal starfields have many more dim stars than bright ones because very few
  70343. Xstars are close enough to appear bright.  To achieve this effect the
  70344. Xprogram will create a bell curve based on the value of ratio of Dim stars
  70345. Xto bright stars.  After calculating the bell curve the curve is folded in
  70346. Xhalf and the peak used to represent the number of dim stars.
  70347. X
  70348. XStarfields can only be shown in 256 colors.  Fractint will automatically
  70349. Xtry to load ALTERN.MAP and abort if the map file cannot be found.
  70350. X;
  70351. X;
  70352. X;
  70353. X~Topic=Palette Maps, Label=HELPCOLORMAP
  70354. X
  70355. XIf you have a VGA, MCGA, Super-VGA, 8514/A, XGA, TARGA, or TARGA+ video
  70356. Xadapter, you can save and restore color palettes for use
  70357. Xwith any image.  To load a palette onto an existing image, use
  70358. Xthe <L> command in color-cycling or palette-editing mode.  To save a
  70359. Xpalette, use the <S> command in those modes.  To change the default
  70360. Xpalette for an entire run, use the command line "map=" parameter.
  70361. X
  70362. XThe default filetype for color-map files is ".MAP".
  70363. X
  70364. XThese color-maps are ASCII text
  70365. Xfiles set up as a series of RGB triplet values (one triplet per
  70366. Xline, encoded as the red, green, and blue [RGB] components of the color).
  70367. X
  70368. XNote that .MAP file color values are in GIF format - values go from 0 (low) to
  70369. X255 (high), so for a VGA adapter they get divided by 4 before being
  70370. Xstuffed into the VGA's Video-DAC registers (so '6' and '7' end up
  70371. Xreferring to the same color value).
  70372. X~OnlineFF
  70373. X
  70374. X~Format-
  70375. XFractint is distributed with some sample .MAP files:
  70376. X   ALTERN.MAP     the famous "Peterson-Vigneau Pseudo-Grey Scale"
  70377. X   BLUES.MAP     for rainy days, by Daniel Egnor
  70378. X   CHROMA.MAP     general purpose, chromatic
  70379. X   DEFAULT.MAP     the VGA start-up values
  70380. X   FIRESTRM.MAP  general purpose, muted fire colors
  70381. X   GAMMA1.MAP and GAMMA2.MAP  Lee Crocker's response to ALTERN.MAP
  70382. X   GLASSES1.MAP  used with 3d glasses modes
  70383. X   GLASSES2.MAP  used with 3d glasses modes
  70384. X   GOODEGA.MAP     for EGA users
  70385. X   GREEN.MAP     shaded green
  70386. X   GREY.MAP     another grey variant
  70387. X   GRID.MAP     for stereo surface grid images
  70388. X   HEADACHE.MAP  major stripes, by D. Egnor (try cycling and hitting <2>)
  70389. X   LANDSCAP.MAP  Guruka Singh Khalsa's favorite map for plasma "landscapes"
  70390. X   NEON.MAP     a flashy map, by Daniel Egnor
  70391. X   PAINTJET.MAP  high resolution mode PaintJet colors
  70392. X   ROYAL.MAP     the royal purple, by Daniel Egnor
  70393. X   TOPO.MAP     Monte Davis's contribution to full color terrain
  70394. X   VOLCANO.MAP     an explosion of lava, by Daniel Egnor
  70395. X~Format+
  70396. X;
  70397. X;
  70398. X;
  70399. X~Topic=\"3D\" Images, Label=HELP3D
  70400. X; Empty in docs, just to have the hotlink defined at chapter level.
  70401. X~Format-,Doc-
  70402. X
  70403. X   { 3D Overview }
  70404. X   { 3D Mode Selection }
  70405. X   { Select Fill Type Screen }
  70406. X   { Stereo 3D Viewing }
  70407. X   { Rectangular Coordinate Transformation }
  70408. X   { 3D Color Parameters }
  70409. X   { Light Source Parameters }
  70410. X   { Spherical Projection }
  70411. X   { 3D Overlay Mode }
  70412. X   { Special Note for CGA or Hercules Users }
  70413. X   { Making Terrains }
  70414. X   { Making 3D Slides }
  70415. X   { Interfacing with Ray Tracing Programs }
  70416. X~Format+,Doc+
  70417. X;
  70418. X;
  70419. X;
  70420. X~Topic=3D Overview
  70421. X
  70422. XFractint can restore images in "3D". Important: we use quotation marks
  70423. Xbecause it does not CREATE images of 3D fractal objects (there are such,
  70424. Xbut we're not there yet.) Instead, it restores .GIF images as a 3D
  70425. XPROJECTION or STEREO IMAGE PAIR.  The iteration values you've come to know
  70426. Xand love, the ones that determine pixel colors, are translated into
  70427. X"height" so that your saved screen becomes a landscape viewed in
  70428. Xperspective. You can even wrap the landscape onto a sphere for realistic-
  70429. Xlooking planets and moons that never existed outside your PC!
  70430. X
  70431. XWe suggest starting with a saved plasma-cloud screen. Hit <3> in main
  70432. Xcommand mode to begin the process. Next, select the file to be
  70433. Xtransformed, and the video mode. (Usually you want the same video mode the
  70434. Xfile was generated in; other choices may or may not work.)
  70435. X
  70436. XAfter hitting <3>, you'll be bombarded with a long series of options.
  70437. XNot to worry: all
  70438. Xof them have defaults chosen to yield an acceptable starting image, so the
  70439. Xfirst time out just pump your way through with the <Enter> key. When you
  70440. Xenter a different value for any option, that becomes the default value the
  70441. Xnext time you hit <3>, so you can change one option at a time until you
  70442. Xget what you want. Generally <ESC> will take you back to the previous
  70443. Xscreen.
  70444. X
  70445. XOnce you're familiar with the effects of the 3D option values you have a
  70446. Xvariety of options on how to specify them. You can specify them all on the
  70447. Xcommand line (there ARE a lot of them so they may not all fit within the
  70448. XDOS command line limits), with an SSTOOLS.INI file, or with a parameter
  70449. Xfile.
  70450. X
  70451. XHere's an example for you power FRACTINTers, the command
  70452. X
  70453. X      FRACTINT MYFILE SAVENAME=MY3D 3D=YES BATCH=YES
  70454. X
  70455. Xwould make Fractint load MYFILE.GIF, re-plot it as a 3D landscape (taking
  70456. Xall of the defaults), save the result as MY3D.GIF, and exit to DOS. By the
  70457. Xtime you've come back with that cup of coffee, you'll have a new world to
  70458. Xview, if not conquer.
  70459. X
  70460. XNote that the image created by 3D transformation is treated as if it were
  70461. Xa plasma cloud - We have NO idea how to retain the ability to zoom and pan
  70462. Xaround a 3D image that has been twisted, stretched, perspective-ized, and
  70463. Xwater-leveled. Actually, we do, but it involves the kind of hardware that
  70464. XIndustrial Light & Magic, Pixar et al. use for feature films. So if you'd
  70465. Xlike to send us a check equivalent to George Lucas' net from the "Star
  70466. XWars" series...
  70467. X;
  70468. X;
  70469. X;
  70470. X~Topic=3D Mode Selection, Label=HELP3DMODE
  70471. X
  70472. XAfter hitting <3> and getting past the filename prompt and video mode
  70473. Xselection, you're presented with a "3d Mode Selection" screen.  If you
  70474. Xwish to change the default for any of the following parameters,
  70475. Xuse the cursor keys to move through the menu. When you're
  70476. Xsatisfied press <Enter>.
  70477. X
  70478. XPreview Mode:
  70479. X   Preview mode provides a rapid look at your transformed image using by
  70480. X   skipping a lot of rows and filling the image in. Good for quickly
  70481. X   discovering the best parameters. Let's face it, the Fractint authors
  70482. X   most famous for "blazingly fast" code *DIDN'T* write the 3D routines!
  70483. X   [Pieter: "But they *are* picking away it and making some progress in
  70484. X   each release."]
  70485. X
  70486. XShow Box:
  70487. X   If you have selected Preview Mode you have another option to worry
  70488. X   about. This is the option to show the image box in scaled and rotated
  70489. X   coordinates x, y, and z. The box only appears in rectangular
  70490. X   transformations and shows how the final image will be oriented. If you
  70491. X   select light source in the next screen, it will also show you the
  70492. X   light source vector so you can tell where the light is coming from in
  70493. X   relation to your image. Sorry no head or tail on the vector yet.
  70494. X
  70495. X~OnlineFF
  70496. XCoarseness:
  70497. X   This sets how many divisions the image will be divided into in the y
  70498. X   direction, if you select preview mode, ray tracing output, or grid fill
  70499. X   in the "Select Fill Type" screen.
  70500. X
  70501. XSpherical Projection:
  70502. X   The next question asks if you want a sphere projection. This will take
  70503. X   your image and map it onto a plane if you answer "no" or a sphere if
  70504. X   you answer "yes" as described above. Try it and you'll see what we
  70505. X   mean.  See {Spherical Projection}.
  70506. X
  70507. XStereo:
  70508. X
  70509. X   Stereo sound in Fractint? Well, not yet. Fractint now allows you to
  70510. X   create 3D images for use with red/blue glasses like 3D comics you may
  70511. X   have seen, or images like Captain EO.
  70512. X
  70513. X   Option 0 is normal old 3D you can look at with just your eyes.
  70514. X
  70515. X   Options 1 and 2 require the special red/blue-green glasses.    They are
  70516. X   meant to be viewed right on the screen or on a color print off of the
  70517. X   screen. The image can be made to hover entirely or partially in front
  70518. X   of the screen. Great fun!  These two options give a gray scale image
  70519. X   when viewed.
  70520. X
  70521. X   Option 1 gives 64 shades of gray but with half the spatial resolution
  70522. X   you have selected. It works by writing the red and blue images on
  70523. X   adjacent pixels, which is why it eats half your resolution. In
  70524. X   general, we recommend you use this only with resolutions above
  70525. X   640x350. Use this mode for continuous potential landscapes where you
  70526. X   *NEED* all those shades.
  70527. X
  70528. X   Option "2" gives you full spatial resolution but with only 16 shades
  70529. X   of gray. If the red and blue images overlap, the colors are mixed.
  70530. X   Good for wire-frame images (we call them surface grids), lorenz3d and
  70531. X   3D IFS. Works fine in 16 color modes.
  70532. X
  70533. X   Option 3 is for creating stereo pair images for view later with more
  70534. X   specialized equipment. It allows full color images to be presented in
  70535. X   glorious stereo. The left image presented on the screen first. You may
  70536. X   photograph it or save it. Then the second image is presented, you may
  70537. X   do the same as the first image. You can then take the two images and
  70538. X   convert them to a stereo image pair as outlined by Bruce Goren (see
  70539. X   below).
  70540. X
  70541. X   Also see {Stereo 3D Viewing}.
  70542. X
  70543. X~OnlineFF
  70544. XRay Tracing Output:
  70545. X
  70546. X   Fractint can create files of its 3d transformations which are
  70547. X   compatible with many ray tracing programs. Currently four are supported
  70548. X   directly: DKB (now obsolete), VIVID, MTV, and RAYSHADE. In addition a "RAW"
  70549. X   output is supported which can be relatively easily transformed to be 
  70550. X   usable by many other products. 
  70551. X   One other option is supported: ACROSPIN.  This is not a ray tracer,
  70552. X   but the same Fractint options apply - see {=@ACROSPIN Acrospin}.
  70553. X
  70554. X   Option values:\
  70555. X      0  disables the creation of ray tracing output\
  70556. X      1  DKB format (obsolete-see below)\
  70557. X      2  VIVID format\
  70558. X      3  generic format (must be massaged externally)\
  70559. X      4  MTV format\
  70560. X      5  RAYSHADE format\
  70561. X      6  ACROSPIN format\
  70562. X   Users of POV-Ray can use the DKB output and convert to POV-Ray with the 
  70563. X   DKB2POV utility that comes with POV-Ray. A better (faster) approach is to 
  70564. X   create a RAW output file and convert to POV-Ray with RAW2POV.  A still
  70565. X   better approach is to use POV-Ray's height field feature to directly
  70566. X   read the fractal .GIF or .POT file and do the 3D transformation inside
  70567. X   POV-Ray.
  70568. X
  70569. X   All ray tracing files consist of triangles which follow the surface
  70570. X   created by Fractint during the 3d transform. Triangles which lie below
  70571. X   the "water line" are not created in order to avoid causing unnecessary
  70572. X   work for the poor ray tracers which are already overworked.
  70573. X   A simple plane can be substituted by the user at the
  70574. X   waterline if needed.
  70575. X
  70576. X   The size (and therefore the number) of triangles created is determined
  70577. X   by the "coarse" parameter setting. While generating the ray tracing
  70578. X   file, you will view the image from above and watch it partitioned into
  70579. X   triangles.
  70580. X
  70581. X   The color of each triangle is the average of the color of its verticies
  70582. X   in the original image, unless BRIEF is selected.
  70583. X
  70584. X   If BRIEF is selected, a default color is assigned at the begining of the
  70585. X   file and is used for all triangles.
  70586. X
  70587. X   Also see {Interfacing with Ray Tracing Programs}.
  70588. X
  70589. XBrief output:
  70590. X
  70591. X   This is a ray tracing sub-option.
  70592. X   When it is set to yes, Fractint creates a considerably
  70593. X   smaller and somewhat faster file. In this mode, all triangles
  70594. X   use the default color specified at the begining of the file.
  70595. X   This color should be edited to supply the color of your choice.
  70596. X
  70597. XTarga Output:
  70598. X
  70599. X   If you want any of the 3d transforms you select to be saved as a
  70600. X   Targa-24 file or overlayed onto one, select yes for this option.
  70601. X   The overlay option in the final screen determines whether you will
  70602. X   create a new file or overlay an existing one.
  70603. X
  70604. XMAP File name:
  70605. X
  70606. X   Imediately after selecting the previous options, you will be given the
  70607. X   chance to select an alternate color MAP file. The default is to
  70608. X   use the current MAP. If you want another MAP used, then enter your
  70609. X   selection at this point.
  70610. X
  70611. XOutput File Name:
  70612. X
  70613. X   This is a ray tracing sub-option, used to specify the name of the
  70614. X   file to be written.    The default name is FRACT001.RAY.  The name is
  70615. X   incremented by one each time a file is written.
  70616. X   If you have not set "overwrite=yes" then
  70617. X   the file name will also be automatically incremented to avoid
  70618. X   over-writing previous files.
  70619. X
  70620. X~Online-
  70621. XWhen you are satisfied with your selections press enter to go
  70622. Xto the next parameter screen.
  70623. X~Online+
  70624. X;
  70625. X;
  70626. X;
  70627. X~Topic=Select Fill Type Screen, Label=HELP3DFILL
  70628. X
  70629. XThis option exists because in the course of the 3D projection, portions
  70630. Xof the original image may be stretched to fit the new surface. Points of
  70631. Xan image that formerly were right next to each other, now may have a space
  70632. Xbetween them. This option generally determines what to do with the space
  70633. Xbetween the mapped dots. It is not used if you have selected a value for
  70634. XRAY other than 0.
  70635. X
  70636. XFor an illustration, pick the second option "just draw the points", which
  70637. Xjust maps points to corresponding points. Generally this will leave empty
  70638. Xspace between many of the points. Therefore you can choose various
  70639. Xalgorithms that "fill in" the space between the points in various ways.
  70640. X
  70641. XLater, try the first option "make a surface grid." This option will make a
  70642. Xgrid of the surface which is as many divisions in the original "y"
  70643. Xdirection as was set in "coarse" in the first screen. It is very fast, and
  70644. Xcan give you a good idea what the final relationship of parts of your
  70645. Xpicture will look like.
  70646. X
  70647. XLater, try the second option "connect the dots (wire frame)", then "surface
  70648. Xfills" - "colors interpolated" and "colors not interpolated", the general
  70649. Xfavorites of the authors. Solid fill, while it reveals the pseudo-geology
  70650. Xunder your pseudo-landscape, inevitably takes longer.
  70651. X
  70652. XLater, try the light source fill types. These two algorithms allow you to
  70653. Xposition the "sun" over your "landscape." Each pixel is colored according
  70654. Xto the angle the surface makes with an imaginary light source. You will be
  70655. Xasked to enter the three coordinates of the vector pointing toward the
  70656. Xlight in a following parameter screen - see {Light Source Parameters}.
  70657. X
  70658. X"Light source before transformation" uses the illumination direction without
  70659. Xtransforming it. The light source is fixed relative to your computer screen.
  70660. XIf you generate a sequence of images with progressive rotation, the effect is
  70661. Xas if you and the light source are fixed and the object is rotating. Therefore
  70662. Xas the object rotates features of the object move in and out of the light.
  70663. XThis fill option was incorrect prior to version 16.1, and has been changed.
  70664. X
  70665. X"Light source after transformation" applies the same transformation to both
  70666. Xthe light direction and the object. Since both the light direction and the
  70667. Xobject are transformed, if you generate a sequence of images with the rotation
  70668. Xprogressively changed, the effect is as if the image and the light source
  70669. Xare fixed in relation to each other and you orbit around the image. The
  70670. Xillumination of features on the object is constant, but you see the object
  70671. Xfrom different angles. This fill option was correct in earlier Fractint
  70672. Xversions and has not been changed.
  70673. X
  70674. XFor ease of discussion we will refer to the following fill types by these
  70675. Xnumbers:
  70676. X    1 - surface grid\
  70677. X    2 - (default) - no fill at all - just draw the dots\
  70678. X    3 - wire frame - joins points with lines\
  70679. X    4 - surface fill - (colors interpolated)\
  70680. X    5 - surface fill - (interpolation turned off)\
  70681. X    6 - solid fill - draws lines from the "ground" up to the point\
  70682. X    7 - surface fill with light model - calculated before 3D transforms\
  70683. X    8 - surface fill with light model - calculated after 3D transforms\
  70684. X
  70685. XTypes 4, 7, and 8 interpolate colors when filling, making a very smooth
  70686. Xfill if the palette is continuous. This may not be desirable if the
  70687. Xpalette is not continuous. Type 5 is the same as type 4 with interpolation
  70688. Xturned off. You might want to use fill type 5, for example, to project
  70689. Xa .GIF photograph onto a sphere. With type 4, you might see the filled-in
  70690. Xpoints, since chances are the palette is not continuous; type 5 fills
  70691. Xthose same points in with the colors of adjacent pixels. However, for most
  70692. Xfractal images, fill type 4 works better.
  70693. X
  70694. XThis screen is not available if you have selected a ray tracing option.
  70695. X;
  70696. X;
  70697. X;
  70698. X~Topic=Stereo 3D Viewing, Label=HELP3DGLASSES
  70699. X
  70700. XThe "Funny Glasses" (stereo 3D) parameter screen is presented only if
  70701. Xyou select a non-zero stereo option in the prior 3D parameters.
  70702. X(See {3D Mode Selection}.)
  70703. XWe suggest you definitely use defaults at first on this screen.
  70704. X
  70705. XWhen you look at an image with both eyes, each eye sees the image in
  70706. Xslightly different perspective because they see it from different places.
  70707. X
  70708. XThe first selection you must make is ocular separation, the distance the
  70709. Xbetween the viewers eyes. This is measured as a % of screen and is an
  70710. Ximportant factor in setting the position of the final stereo image in
  70711. Xfront of or behind the CRT Screen.
  70712. X
  70713. XThe second selection is convergence, also as a % of screen. This tends to
  70714. Xmove the image forward and back to set where it floats. More positive
  70715. Xvalues move the image towards the viewer. The value of this parameter
  70716. Xneeds to be set in conjunction with the setting of ocular separation and
  70717. Xthe perspective distance. It directly adjusts the overall separation of
  70718. Xthe two stereo images. Beginning anaglyphers love to create images
  70719. Xfloating mystically in front of the screen, but grizzled old 3D veterans
  70720. Xlook upon such antics with disdain, and believe the image should be safely
  70721. Xinside the monitor where it belongs!
  70722. X
  70723. XLeft and Right Red and Blue image crop (% of screen also) help keep the
  70724. Xvisible part of the right image the same as the visible part of the left
  70725. Xby cropping them. If there is too much in the field of either eye that the
  70726. Xother doesn't see, the stereo effect can be ruined.
  70727. X
  70728. XRed and Blue brightness factor. The generally available red/blue-green
  70729. Xglasses, made for viewing on ink on paper and not the light from a CRT,
  70730. Xlet in more red light in the blue-green lens than we would like. This
  70731. Xleaves a ghost of the red image on the blue-green image (definitely not
  70732. Xdesired in stereo images). We have countered this by adjusting the
  70733. Xintensity of the red and blue values on the CRT. In general you should not
  70734. Xhave to adjust this.
  70735. X
  70736. XThe final entry is Map file name (present only if stereo=1 or stereo=2
  70737. Xwas selected).
  70738. XIf you have a special map file you want
  70739. Xto use for Stereo 3D this is the place to enter its name. Generally
  70740. Xglasses1.map is for type 1 (alternating pixels), and glasses2.map is for
  70741. Xtype 2 (superimposed pixels). Grid.map is great for wire-frame images
  70742. Xusing 16 color modes.
  70743. X
  70744. XThis screen is not available if you have selected a ray tracing option.
  70745. X;
  70746. X;
  70747. X;
  70748. X~Topic=3D Fractal Parameters, Label=HELP3DFRACT
  70749. X; This topic is online only.
  70750. X
  70751. XThe parameters on this screen are a subset of the zillions of options
  70752. Xavailable for Fractint's 3D image transformations.
  70753. XThis screen's parameters are those which also affect 3D fractal types like
  70754. Xlorenz3d and kamtorus3d.
  70755. XSince they are documented elsewhere, we won't repeat ourselves:
  70756. X
  70757. XFor a description of rotation, perspective, and shift parameters, please
  70758. Xsee {Rectangular Coordinate Transformation}.  Ignore the paragraphs about
  70759. X"scaling" and "water level" - those parts apply only to 3D Transforms.
  70760. X
  70761. XFor a description of the stereo option, please see the "stereo" subheading
  70762. Xin {3D Mode Selection}.
  70763. X;
  70764. X;
  70765. X;
  70766. X~Topic=Rectangular Coordinate Transformation, Label=HELP3DPARMS
  70767. X
  70768. XThe first entries are rotation values around the X, Y, and Z axes. Think
  70769. Xof your starting image as a flat map: the X value tilts the bottom of your
  70770. Xmonitor towards you by X degrees, the Y value pulls the left side of the
  70771. Xmonitor towards you, and the Z value spins it counter-clockwise. Note that
  70772. Xthese are NOT independent rotations: the image is rotated first along the
  70773. XX-axis, then along the Y-axis, and finally along the Z-axis. Those are
  70774. XYOUR axes, not those of your (by now hopelessly skewed) monitor. All
  70775. Xrotations actually occur through the center of the original image. Rotation
  70776. Xparameters are not used when a ray tracing option has been selected.
  70777. X
  70778. XThen there are three scaling factors in percent. Initially, leave the X
  70779. Xand Y axes alone and play with Z, now the vertical axis, which translates
  70780. Xinto surface "roughness."  High values of Z make spiky, on-beyond-Alpine
  70781. Xmountains and improbably deep valleys; low values make gentle, rolling
  70782. Xterrain. Negative roughness is legal: if you're doing an M-set image and
  70783. Xwant Mandelbrot Lake to be below the ground, instead of eerily floating
  70784. Xabove, try a roughness of about -30%.
  70785. X
  70786. XNext we need a water level -- really a minimum-color value that performs
  70787. Xthe function "if (color < waterlevel) color = waterlevel". So it plots all
  70788. Xcolors "below" the one you choose at the level of that color, with the
  70789. Xeffect of filling in "valleys" and converting them to "lakes."
  70790. X
  70791. XNow we enter a perspective distance, which you can think of as the
  70792. X"distance" from your eye to the image. A zero value (the default) means no
  70793. Xperspective calculations, which allows use of a faster algorithm.
  70794. XPerspective distance is not available if you have selected a ray tracing
  70795. Xoption.
  70796. X
  70797. XFor non-zero values, picture a box with the original X-Y plane of your
  70798. Xflat fractal on the bottom, and your 3D fractal inside. A perspective
  70799. Xvalue of 100% places your eye right at the edge of the box and yields
  70800. Xfairly severe distortion, like a close view through a wide-angle lens.
  70801. X200% puts your eye as far from the front of the box as the back is behind.
  70802. X300% puts your eye twice as far from the front of the box as the back is,
  70803. Xetc. Try about 150% for reasonable results. Much larger values put you far
  70804. Xaway for even less distortion, while values smaller than 100% put you
  70805. X"inside" the box. Try larger values first, and work your way in.
  70806. X
  70807. XNext, you are prompted for two types of X and Y shifts (now back in the
  70808. Xplane of your screen) that let you move the final image around if you'd
  70809. Xlike to re-center it. The first set, x and y shift with perspective, move
  70810. Xthe image and the effect changes the perspective you see. The second set,
  70811. X"x and y adjust without perspective", move the image but do not change
  70812. Xperspective.  They are used just for positioning the final image on the
  70813. Xscreen. Shifting of any type is not available if you have selected a ray
  70814. Xtracing option.
  70815. X~Doc-
  70816. X
  70817. X{3D Color Parameters} are also requested on the same input screen.\
  70818. X
  70819. XIf you are doing a {Spherical Projection}, special parameters for
  70820. Xit are requested at the start of this screen.
  70821. X~Doc+
  70822. X;
  70823. X;
  70824. X;
  70825. X~Topic=3D Color Parameters
  70826. X
  70827. XYou are asked for a range of "transparent" colors, if any. This
  70828. Xoption is most useful when using the {3D Overlay Mode}.  Enter the
  70829. Xcolor range (minimum and maximum value) for which you do not want to
  70830. Xoverwrite whatever may already be on the screen. The default is no
  70831. Xtransparency (overwrite everything).
  70832. X
  70833. XNow, for the final option. This one will smooth the transition between
  70834. Xcolors by randomizing them and reduce the banding that occurs with some
  70835. Xmaps. Select the value of randomize to between 0 (for no effect) and 7 (to
  70836. Xrandomize your colors almost beyond use). 3 is a good starting point.
  70837. X
  70838. XThat's all for this screen. Press enter for these parameters and the
  70839. Xnext and final screen will appear (honestly!).
  70840. X;
  70841. X;
  70842. X;
  70843. X~Topic=Light Source Parameters, Label=HELP3DLIGHT
  70844. X
  70845. XThis one deals with all the aspects of light source and Targa files.
  70846. X
  70847. XYou must choose the direction of the light from the light source. This will
  70848. Xbe scaled in the x, y, and z directions the same as the image. For
  70849. Xexample, 1,1,3 positions the light to come from the lower right front of
  70850. Xthe screen in relation to the untransformed image. It is important to
  70851. Xremember that these coordinates are scaled the same as your image. Thus,
  70852. X"1,1,1" positions the light to come from a direction of equal distances to
  70853. Xthe right, below and in front of each pixel on the original image.
  70854. XHowever, if the x,y,z scale is set to 90,90,30 the result will be from
  70855. Xequal distances to the right and below each pixel but from only 1/3 the
  70856. Xdistance in front of the screen i.e.. it will be low in the sky, say,
  70857. Xafternoon or morning.
  70858. X
  70859. XThen you are asked for a smoothing factor. Unless you used
  70860. X{Continuous Potential} when generating the starting image, the
  70861. Xillumination when using light source fills may appear "sparkly", like a
  70862. Xsandy beach in bright sun. A smoothing factor of 2 or 3 will allow you to
  70863. Xsee the large-scale shapes better.
  70864. X
  70865. XSmoothing is primarily useful when doing light source fill types with plasma
  70866. Xclouds. If your fractal is not a plasma cloud and has features with
  70867. Xsharply defined boundaries (e.g. Mandelbrot Lake), smoothing may cause
  70868. Xthe colors to run. This is a feature, not a bug. (A copyrighted response
  70869. Xof [your favorite commercial software company here], used by permission.)
  70870. X
  70871. XThe ambient option sets the minimum light value a surface has if it has no
  70872. Xdirect lighting at all. All light values are scaled from this value to
  70873. Xwhite. This effectively adjusts the depth of the shadows and sets the
  70874. Xoverall contrast of the image.
  70875. X
  70876. XIf you selected the full color option, you have a few more choices.
  70877. XThe next is the haze factor. Set this to make distant objects more hazy.
  70878. XClose up objects will have little effect, distant objects will have most.
  70879. X0 disables the function. 100 is the maximum effect, the farthest objects
  70880. Xwill be lost in the mist. Currently, this does not really use distance
  70881. Xfrom the viewer, we cheat and use the y value of the original image. So
  70882. Xthe effect really only works if the y-rotation (set earlier) is between
  70883. X+/- 30.
  70884. X
  70885. XNext, you can chose the name under which to save your Targa file. If you
  70886. Xhave a RAM disk handy, you might want to create the file on it, for speed.
  70887. XSo include its  full path name in this option. If you have not set
  70888. X"overwrite=yes" then the file name will be incremented to avoid over-writing
  70889. Xprevious files. If you are going to overlay an existing Targa file, enter
  70890. Xits name here.
  70891. X
  70892. XNext, you may select the background color for the Targa file. The default
  70893. Xbackground on the Targa file is sky blue. Enter the Red, Green, and Blue
  70894. Xcomponent for the background color you wish.
  70895. X
  70896. XFinally, absolutely the last option (this time we mean it): you can now
  70897. Xchoose to overlay an existing Targa-24, type 2, non mapped, top-to-bottom
  70898. Xfile, such as created by Fractint or PVRay. The Targa file specified above
  70899. Xwill be overlayed with new info just as a GIF is overlayed on screen. Note:
  70900. Xit is not necessary to use the "O" overlay command to overlay Targa files.
  70901. XThe Targa_Overlay option must be set to yes, however.
  70902. X
  70903. X
  70904. XYou'll probably want to adjust the final colors for monochrome fill types
  70905. Xusing light source via {=@ColorCycling color cycling}.
  70906. XTry one of the more continuous
  70907. Xpalettes (<F8> through <F10>), or load the GRAY palette with the
  70908. X<A>lternate-map command.
  70909. X
  70910. X~Online-
  70911. XNow, lie down for a while in a quiet room with a damp washcloth on your
  70912. Xforehead. Feeling better? Good -- because it's time to go back almost to
  70913. Xthe top of the 3D options and just say yes to:
  70914. X~Online+
  70915. X;
  70916. X;
  70917. X;
  70918. X~Topic=Spherical Projection
  70919. X
  70920. XPicture a globe lying on its side, "north" pole to the right. (It's our
  70921. Xplanet, and we'll position it the way we like.) You will be mapping the X
  70922. Xand Y axes of the starting image to latitude and longitude on the globe,
  70923. Xso that what was a horizontal row of pixels follows a line of longitude.
  70924. XThe defaults exactly cover the hemisphere facing you, from longitude 180
  70925. Xdegrees (top) to 0 degrees (bottom) and latitude -90 (left) to latitude 90
  70926. X(right). By changing them you can map the image to a piece of the
  70927. Xhemisphere or wrap it clear around the globe.
  70928. X
  70929. XThe next entry is for a radius factor that controls the over-all size of
  70930. Xthe globe. All the rest of the entries are the same as in the landscape
  70931. Xprojection. You may want less surface roughness for a plausible look,
  70932. Xunless you prefer small worlds with big topography, a la "The Little
  70933. XPrince."
  70934. X
  70935. XWARNING: When the "construction" process begins at the edge of the globe
  70936. X(default) or behind it, it's plotting points that will be hidden by
  70937. Xsubsequent points as the process sweeps around the sphere toward you. Our
  70938. Xnifty hidden-point algorithms "know" this, and the first few dozen lines
  70939. Xmay be invisible unless a high mountain happens to poke over the horizon.
  70940. XIf you start a spherical projection and the screen stays black, wait for a
  70941. Xwhile (a longer while for higher resolution or fill type 6) to see if
  70942. Xpoints start to appear. Would we lie to you? If you're still waiting hours
  70943. Xlater, first check that the power's still on, then consider a faster
  70944. Xsystem.
  70945. X;
  70946. X;
  70947. X;
  70948. X~Topic=3D Overlay Mode, Label=HELP3DOVLY
  70949. X
  70950. XWhile the <3> command (see {\"3D\" Images})
  70951. Xcreates its image on a blank screen, the <#> (or <shift-3> on some 
  70952. Xkeyboards) command
  70953. Xdraws a second image over an existing displayed image. This image can be
  70954. Xany restored image from a <R> command or the result of a just executed <3>
  70955. Xcommand. So you can do a landscape, then press <#> and choose spherical
  70956. Xprojection to re-plot that image or another as a moon in the sky above the
  70957. Xlandscape. <#> can be repeated as many times as you like.
  70958. X
  70959. XIt's worth noting that not all that many years ago, one of us watched
  70960. XBenoit Mandelbrot and fractal-graphics wizard Dick Voss creating just such
  70961. Xa moon-over-landscape image at IBM's research center in Yorktown Heights,
  70962. XNY. The system was a large and impressive mainframe with floating-point
  70963. Xfacilities bigger than the average minicomputer, running LBLGRAPH -- what
  70964. XMandelbrot calls "an independent-minded and often very ill-mannered heap
  70965. Xof graphics programs that originated in work by Alex Hurwitz and Jack
  70966. XWright of IBM Los Angeles."
  70967. X
  70968. XWe'd like to salute LBLGRAPH, its successors, and their creators, because
  70969. Xit was their graphic output (like "Planetrise over Labelgraph Hill," plate
  70970. XC9 in Mandelbrot's "Fractal Geometry of Nature") that helped turn fractal
  70971. Xgeometry from a mathematical curiosity into a phenomenon. We'd also like
  70972. Xto point out that it wasn't as fast, flexible or pretty as Fractint on a
  70973. X386/16 PC with S-VGA graphics. Now, a lot of the difference has to do with
  70974. Xthe incredible progress of micro-processor power since then, so a lot of
  70975. Xthe credit should go to Intel rather than to our highly tuned code. OK,
  70976. Xtwist our arms -- it IS awfully good code.
  70977. X;
  70978. X;
  70979. X;
  70980. X~Topic=Special Note for CGA or Hercules Users
  70981. X
  70982. XIf you are one of those unfortunates with a CGA or Hercules 2-color
  70983. Xmonochrome graphics, it is now possible for you to make 3D projection
  70984. Ximages.
  70985. X
  70986. XTry the following unfortunately circuitous approach. Invoke Fractint,
  70987. Xmaking sure you have set askvideo=yes. Use a disk-video mode to create a
  70988. X256 color fractal. You might want to edit the fractint.cfg file to make a
  70989. Xdisk-video mode with the same pixel dimensions as your normal video. Using
  70990. Xthe "3" command, enter the file name of the saved 256 color file, then
  70991. Xselect your 2 or 4
  70992. Xcolor mode, and answer the other 3D prompts. You will then see a 3D
  70993. Xprojection of the fractal. Another example of Stone Soup responsiveness to
  70994. Xour fan mail!
  70995. X;
  70996. X;
  70997. X;
  70998. X~Topic=Making Terrains
  70999. X
  71000. XIf you enjoy using Fractint for making landscapes, we have several new
  71001. Xfeatures for you to work with. When doing 3d transformations banding tends
  71002. Xto occur because all pixels of a given height end up the same color. Now,
  71003. Xcolors can be randomized to make the transitions between different colors
  71004. Xat different altitudes smoother. Use the new "RANDOMIZE= " variable to
  71005. Xaccomplish this. If your light source images all look like lunar
  71006. Xlandscapes since they are all monochrome and have very dark shadows, we
  71007. Xnow allow you to set the ambient light for adjusting the contrast of the
  71008. Xfinal image. Use the "Ambient= " variable. In addition to being able to
  71009. Xcreate scenes with light sources in monochrome, you can now do it in full
  71010. Xcolor as well. Setting fullcolor=1 will generate a Targa-24 file with a
  71011. Xfull color image which will be a combination of the original colors of the
  71012. Xsource image (or map file if you select map=something) and the amount of
  71013. Xlight which reflects off a given point on the surface. Since there can be
  71014. X256 different colors in the original image and 256 levels of light, you
  71015. Xcan now generate an image with *lots* of colors. To convert it to a GIF if
  71016. Xyou can't view Targa files directly, you can use PICLAB (see
  71017. X{Other Programs}), and the following commands:
  71018. X
  71019. X    SET PALETTE 256\
  71020. X    SET CREZ 8\
  71021. X    TLOAD yourfile.tga\
  71022. X    MAKEPAL\
  71023. X    MAP\
  71024. X    GSAVE yourfile.gif\
  71025. X    EXIT\
  71026. XUsing the full color option allows you to also set a haze factor with the
  71027. X"haze= " variable to make more distant objects more hazy.
  71028. X
  71029. XAs a default, full color files also have the background set to sky blue.
  71030. XWarning, the files which are created with the full color option are very
  71031. Xlarge, 3 bytes per pixel. So be sure to use a disk with enough space.
  71032. XThe file is created using Fractint's disk-video caching, but is always
  71033. Xcreated on real disk (expanded or extended memory is not used.) Try the
  71034. Xfollowing settings of the new variables in sequence to get a feel for the
  71035. Xeffect of each one:\
  71036. X    ;use this with any filltype\
  71037. X    map=topo\
  71038. X    randomize=3; adjusting this smooths color transitions\
  71039. X
  71040. X    ;now add this using filltype 5 or 6\
  71041. X    ambient=20; adjusting this changes the contrast\
  71042. X    filltype=6\
  71043. X    smoothing=2; makes the light not quite as granular as the terrain\
  71044. X
  71045. X    ;now add the following, and this is where it gets slow\
  71046. X    fullcolor=1; use PICLAB to reduce resulting lightfile to a GIF\
  71047. X
  71048. X    ;and finally this\
  71049. X    haze=20; sets the amount of haze for distant objects\
  71050. X
  71051. XWhen full color is being used, the image you see on the screen will
  71052. Xrepresent the amount of light being reflected, not the colors in the final
  71053. Ximage. Don't be disturbed if the colors look weird, they are an artifact
  71054. Xof the process being used. The image being created in the lightfile won't
  71055. Xlook like the screen.
  71056. X
  71057. XHowever, if you are worried, hit ESC several times and when Fractint gets
  71058. Xto the end of the current line it will abort. Your partial image will be
  71059. Xthere as LIGHT001.TGA or with whatever file name you selected with the
  71060. Xlightname option. Convert it as described above and adjust any parameters
  71061. Xyou are not happy with. Its a little awkward, but we haven't figured
  71062. Xout a better way yet.
  71063. X;
  71064. X;
  71065. X;
  71066. X~Topic=Making 3D Slides
  71067. X
  71068. XBruce Goren, CIS's resident stereoscopic maven, contributed these tips on
  71069. Xwhat to do with your 3D images (Bruce inspired and prodded us so much we
  71070. Xautomated much of what follows, allowing both this and actual on screen
  71071. Xstereo viewing, but we included it here for reference and a brief
  71072. Xtutorial.)
  71073. X
  71074. X"I use a Targa 32 video card and TOPAS graphic software, moving the
  71075. Xviewport or imaginary camera left and right to create two separate views
  71076. Xof the stationary object in x,y,z, space. The distance between the two
  71077. Xviews, known as the inter-ocular distance, toe-in or convergence angle, is
  71078. Xcritical. It makes the difference between good 3-D and headache-generating
  71079. Xbad 3-D.
  71080. X
  71081. X"For a 3D fractal landscape, I created and photographed the left and right
  71082. Xeye views as if flying by in an imaginary airplane and mounted the film
  71083. Xchips for stereo viewing. To make my image, first I generated a plasma
  71084. Xcloud based on a color map I calculated to resemble a geological survey
  71085. Xmap (available on CIS as TARGA.MAP). In the 3D reconstruction, I used a
  71086. Xperspective value of 150 and shifted the camera -15 and +15 on the X-axis
  71087. Xfor the left and right views. All other values were left to the defaults.
  71088. X
  71089. X"The images are captured on a Matrix 3000 film recorder -- basically a box
  71090. Xwith a high-resolution (1400 lines) black and white TV and a 35mm camera
  71091. X(Konica FS-1) looking at the TV screen through a filter wheel. The Matrix
  71092. X3000 can be calibrated for 8 different film types, but so far I have only
  71093. Xused Kodak Ektachrome 64 daylight for slides and a few print films. I
  71094. Xglass mount the film chips myself.
  71095. X
  71096. X"Each frame is exposed three times, once through each of the red, blue,
  71097. Xand green filters to create a color image from computer video without the
  71098. Xscan-lines which normally result from photographing television screens.
  71099. XThe aspect ratio of the resulting images led me to mount the chips using
  71100. Xthe 7-sprocket Busch-European Emde masks. The best source of Stereo
  71101. Xmounting and viewing supplies I know of is an outfit called Reel 3-D
  71102. XEnterprises, Inc. at P.O. Box 2368, Culver City, CA 90231, tel. 213-837-
  71103. X2368. "My platform is an IBM PC/AT crystal-swapped up to 9 MHz. The math
  71104. Xco-processor runs on a separate 8-MHz accessory sub-board.  The system
  71105. Xcurrently has 6.5 MB of RAM."
  71106. X;
  71107. X;
  71108. X;
  71109. X~Topic=Interfacing with Ray Tracing Programs
  71110. X
  71111. X(Also see "Ray Tracing Output", "Brief", and "Output File Name"
  71112. Xin {"3D Mode Selection"}.)
  71113. X
  71114. XFractint allows you to save your 3d transforms in files which may be
  71115. Xfed to a ray tracer (or to "Acrospin").
  71116. XHowever, they are not ready to be traced by
  71117. Xthemselves. For one thing, no light source is included. They are
  71118. Xactually meant to be included within other ray tracing files.
  71119. X
  71120. XSince the intent is to produce an object which may be included in a larger
  71121. Xray tracing scene, it is expected that all rotations, shifts, and final
  71122. Xscaling will be done by the ray tracer. Thus, in creating the images, no
  71123. Xfacilities for rotations or shifting is provided. Scaling is provided to
  71124. Xachieve the correct aspect ratio.
  71125. X
  71126. XWARNING! The files created using the RAY option can be huge. Setting
  71127. XCOARSE to 40 will result in over 2000 triangles. Each triangle can utilize
  71128. Xfrom 50 to 200 bytes each to describe, so your ray tracing files can
  71129. Xrapidly approach or exceed 1Meg. Make sure you have enough disk space before
  71130. Xyou start.
  71131. X
  71132. XEach file starts with a comment identifying the version of Fractint
  71133. Xby which it was created. The file ends with a comment giving the number
  71134. Xof triangles in the file.
  71135. X
  71136. XThe files consist of long strips of adjacent triangles. Triangles are
  71137. Xclockwise or counter clockwise depending on the target ray tracer.
  71138. XCurrently, MTV and Rayshade are the only ones which use counter clockwise
  71139. Xtriangles. The size of the triangles is set by the COARSE setting in the
  71140. Xmain 3d menu. Color information about each individual triangle is included
  71141. Xfor all files unless in the brief mode.
  71142. X
  71143. XTo keep the poor ray tracer from working too hard, if WATERLINE is set
  71144. Xto a non zero value, no triangle which lies entirely at or below the
  71145. Xcurrent setting of WATERLINE is written to the ray tracing file.  These
  71146. Xmay be replaced by a simple plane in the syntax of the ray tracer you are
  71147. Xusing.
  71148. X
  71149. XFractint's coordinate system has the origin of the x-y plane at the upper
  71150. Xleft hand corner of the screen, with positive x to the right and positive
  71151. Xy down. The ray tracing files have the origin of the x-y plane moved to
  71152. Xthe center of the screen with positive x to the right and positive y up.
  71153. XIncreasing values of the color index are out of the screen and in the +z
  71154. Xdirection. The color index 0 will be found in the xy plane at z=-1.
  71155. X
  71156. XWhen x- y- and zscale are set to 100, the surface created by the
  71157. Xtriangles will fall within a box of +/- 1.0 in all 3 directions. Changing
  71158. Xscale will change the size and/or aspect ratio of the enclosed object.
  71159. X
  71160. XWe will only describe the structure of the RAW format here. If you want
  71161. Xto understand any of the ray tracing file formats besides RAW, please
  71162. Xsee your favorite ray tracer docs.
  71163. X
  71164. XThe RAW format simply consists of a series of clockwise triangles. If
  71165. XBRIEF=yes, Each line is a vertex with coordinates x, y, and z. Each
  71166. Xtriangle is separated by a couple of CR's from the next. If BRIEF=no, the
  71167. Xfirst line in each triangle description if the r,g,b value of the triangle.
  71168. X
  71169. XSetting BRIEF=yes produces shorter files with the color of each triangle
  71170. Xremoved - all triangles will be the same color. These files are
  71171. Xotherwise identical to normal files but will run faster than the non BRIEF
  71172. Xfiles.    Also, with BRIEF=yes, you may be able to get files with more
  71173. Xtriangles to run than with BRIEF=no.
  71174. X
  71175. XThe DKB format is now obsolete. POV-Ray users should use the RAW output 
  71176. Xand convert to POV-Ray using the POV Group's RAW2POV utility. POV-Ray 
  71177. Xusers can also do all 3D transformations within POV-Ray using height fields.
  71178. X;
  71179. X;
  71180. X;
  71181. X
  71182. X
  71183. SHAR_EOF
  71184. $TOUCH -am 1028230193 help3.src &&
  71185. chmod 0644 help3.src ||
  71186. echo "restore of help3.src failed"
  71187. set `wc -c help3.src`;Wc_c=$1
  71188. if test "$Wc_c" != "64400"; then
  71189.     echo original size 64400, current size $Wc_c
  71190. fi
  71191. # ============= help4.src ==============
  71192. echo "x - extracting help4.src (Text)"
  71193. sed 's/^X//' << 'SHAR_EOF' > help4.src &&
  71194. X~Topic=Startup Parameters\, Parameter Files
  71195. X; This topic is online only.
  71196. X
  71197. X~Format-
  71198. X    { Summary of all Parameters }
  71199. X    { Introduction to Parameters }
  71200. X    { Using the DOS Command Line }
  71201. X    { Setting Defaults (SSTOOLS.INI File) }
  71202. X    { Parameter Files and the <@> Command }
  71203. X    { General Parameter Syntax }
  71204. X    { Startup Parameters }
  71205. X    { Calculation Mode Parameters }
  71206. X    { Fractal Type Parameters }
  71207. X    { Image Calculation Parameters }
  71208. X    { Color Parameters }
  71209. X    { Doodad Parameters }
  71210. X    { File Parameters }
  71211. X    { Sound Parameters }
  71212. X    { Video Parameters }
  71213. X    { Printer Parameters }
  71214. X    { 3D Parameters }
  71215. X;
  71216. X;
  71217. X~Topic=Summary of all Parameters, Label=HELPCOMMANDS
  71218. X; This topic is online only.
  71219. X~Format-
  71220. X
  71221. X{Startup Parameters}
  71222. X  @filename[/setname]       Process commands from a file
  71223. X  [filename=]filename       Start with this saved file (one saved by FRACTINT
  71224. X               or a generic GIF file [treated as a plasma cloud])
  71225. X               ('filename=' is required except on command line)
  71226. X  batch=yes           Batch mode run (display image, save-to-disk, exit)
  71227. X  autokey=play|record       Playback or record keystrokes
  71228. X  autokeyname=filename       File for autokey mode, default AUTO.KEY
  71229. X  fpu=387|iit|noiit       Assume 387 or IIT fpu is present or absent
  71230. X  makedoc=filename       Create Fractint documentation file
  71231. X
  71232. X{Calculation Mode Parameters}
  71233. X  passes=1|2|g|b|t       Select Single-Pass, Dual-Pass, Solid-Guessing,
  71234. X               Boundary-Tracing, or the Tesseral drawing
  71235. X               algorithms
  71236. X  fillcolor=normal|<nnn>   Sets a block fill color for use with Boundary
  71237. X                     Tracing and Tesseral options          
  71238. X  float=yes           For most functions changes from integer math to fp
  71239. X  symmetry=xxxx        Force symmetry to None, Xaxis, Yaxis, XYaxis,
  71240. X               Origin, or Pi symmetry.  Useful for debugging.
  71241. X~FF
  71242. X
  71243. X{Fractal Type Parameters}
  71244. X  type=fractaltype       Perform this Fractal Type (Default = mandel)
  71245. X               See {Fractal Types} for a full list
  71246. X  params=xxx[/xxx[/...       Begin with these extra Parameter values
  71247. X               (Examples:  params=4   params=-0.480/0.626)
  71248. X  function=fn1/.../fn4       Allows specification of transcendental functions
  71249. X               with types using variable functions. Values are
  71250. X               sin, cos, tan, cotan, sinh, cosh, tanh, cotanh,
  71251. X               exp, log, sqr, recip (1/z), ident (identity),
  71252. X               conj, flip, zero, and cosxx (cos with bug)
  71253. X  formulaname=name       Formula name for 'type=formula' fractals
  71254. X  lname=name           Lsystem name for 'type=lsystem' fractals
  71255. X  ifs=name           IFS name for 'type=ifs' fractals
  71256. X  3dmode=monocular|left|right|red-blue  Sets the 3D mode used with Julibrot
  71257. X  julibrot3d=nn[/nn[/nn[/nn[/nn[/nn]]]]]")  Sets Julibrot 3D parameters zdots, 
  71258. X                           origin, depth, height, width, and distance
  71259. X  julibroteyes=nn          Distance between the virtual eyes for Julibrot
  71260. X  julibrotfromto=nn/nn[/nn/nn] "From-to" parameters used for Julibrot 
  71261. X  miim=[depth|breadth|walk]/[left|right]/[xxx/yyy[/zzz]] Params for MIIM
  71262. X                           julias.  xxx/yyy = julia constant, zzz = max hits.
  71263. X                           Eg. miim=depth/left/-.74543/.11301/3
  71264. X~FF
  71265. X{Image Calculation Parameters}
  71266. X  corners=xmin/xmax/ymin/ymax[/x3rd/y3rd]
  71267. X               Begin with these Coordinates
  71268. X               (Example: corners=-0.739/-0.736/0.288/0.291)
  71269. X  center-mag=[Xctr/Yctr/Mag] An alternative method of entering corners.
  71270. X               With no parameters causes <B> command to output
  71271. X               'center-mag=' instead of corners.
  71272. X  maxiter=nnn           Maximum number of iterations (default = 150)
  71273. X  bailout=nnnn           Use this as the iteration bailout value (instead
  71274. X               of the default (4.0 for most fractal types)
  71275. X  initorbit=nnn/nnn       Sets the value used to initialize Mandelbrot orbits
  71276. X               to the given complex number (real and imag parts)
  71277. X  orbitdelay=nn           Slows up the display of orbits (by nn/10000 sec)
  71278. X  initorbit=pixel       Sets the value used to initialize Mandelbrot orbits
  71279. X               to the complex number corresponding to the screen
  71280. X               pixel. This is the default for most types.
  71281. X  periodicity=[no|show|nnn] Controls periodicity checking. 'no' turns checking
  71282. X               off; entering a number nnn controls the tightness
  71283. X               of checking (default 1, higher is more stringent)
  71284. X               'show' or a neg value colors 'caught' points white.
  71285. X  rseed=nnnnn           Random number seed, for reproducable Plasma Clouds
  71286. X  showdot=nn           Colors the current dot being calculated color nn.
  71287. X~FF
  71288. X{Color Parameters}
  71289. X  inside=nnn|maxiter|zmag|bof60|bof61|epscr|star|per
  71290. X               Fractal interior color (inside=0 for black)
  71291. X  outside=nnn|iter|real|imag|mult|summ  Fractal exterior color options
  71292. X  map=filename           Use 'filename' as the default color map (vga/targa)
  71293. X  colors=@filename|colorspec Sets current image color map from file or spec,
  71294. X               vga or higher only
  71295. X  cyclerange=nnn/nnn       Range of colors to cycle (default 1/255)
  71296. X  cyclelimit=nnn       Color-cycler speed-limit (1 to 256, default = 55)
  71297. X  textcolors=aa/bb/cc/...  Set text screen colors
  71298. X  textcolors=mono       Set text screen colors to simple black and white
  71299. X  shortmap=yes           Uses the compact .map file format
  71300. X
  71301. X{Doodad Parameters}
  71302. X  logmap=yes|old|nn       Yes maps logarithm of iteration to color. Old uses
  71303. X               pre vsn 14 logic. >1 compresses, <-1 for quadratic.
  71304. X  ranges=nn/nn/nn/...       Ranges of iteration values to map to colors
  71305. X  distest=nnn/nnn       Distance Estimator Method
  71306. X  decomp=nn           'Decomposition' toggle, value 2 to 256.
  71307. X  biomorph=nnn           Biomorph Coloring
  71308. X  potential=nn[/nn[/nn[/16bit]]]  Continuous Potential
  71309. X  invert=nn/nn/nn       Turns on inversion - turns images 'inside out'
  71310. X~FF
  71311. X  finattract=yes       Look for finite attractor in julia types
  71312. X  exitnoask=yes           bypasses the final "are you sure?" exit screen
  71313. X
  71314. X{Sound Parameters}
  71315. X  sound=off|x|y|z          Nobody ever plays with fractals at work, do they?
  71316. X                           x|y|z can be used to add sound to attractor
  71317. X                           fractals, the orbits command, and reading GIFs.
  71318. X  hertz=nnn                Base frequency for attractor sound effects
  71319. X
  71320. X{File Parameters}
  71321. X  savename=filename       Save files using this name (instead of FRACT001)
  71322. X  overwrite=no|yes       Don't over-write existing files
  71323. X  savetime=nnn           Autosave image every nnn minutes of calculation
  71324. X  gif87a=yes           Save GIF files in the older GIF87a format (with
  71325. X               no FRACTINT extension blocks)
  71326. X  dither=yes           Dither color GIFs read into a b/w display.
  71327. X  parmfile=filename       File for <@> and <b> commands, default FRACTINT.PAR
  71328. X  formulafile=filename       File for type=formula, default FRACTINT.FRM
  71329. X  lfile=filename       File for type=lsystem, default FRACTINT.L
  71330. X  ifsfile=filename       File for type=ifs, default FRACTINT.IFS
  71331. X  orbitsave=yes        Causes IFS and orbit fractals orbit points to be
  71332. X               saved in the file ORBITS.RAW
  71333. X~FF
  71334. X
  71335. X{Video Parameters}
  71336. X  video=xxx           Begin with this video mode (Example: Video=F2)
  71337. X  askvideo=no           Skip the prompt for video mode when restoring files
  71338. X  adapter=hgc|cga|ega|egamono|mcga|vga
  71339. X                           Assume this (standard) video adapter is present
  71340. X  adapter=ATI|Everex|Trident|NCR|Video7|Genoa|Paradise|Chipstech|
  71341. X                           Tseng3000|Tseng4000|AheadA|AheadB|Oaktech
  71342. X                           Assume the named SuperVGA Chip set is present and
  71343. X                           enable its non-standard SuperVGA modes.
  71344. X  afi=yes                  Disables the register-compatible 8514/A logic
  71345. X                           and forces the use of the 8514/A API (HDILOAD)
  71346. X  textsafe=yes|no|bios|save  For use when images are not restored correctly on
  71347. X               return from a text display
  71348. X  exitmode=nn           Sets the bios-supported videomode to use upon exit
  71349. X               (if not mode 3) - nn is the mode in hexadecimal
  71350. X  viewwindows=xx[/xx[/yes|no[/nn[/nn]]]]
  71351. X               Set the reduction factor, final media aspect ratio,
  71352. X               crop starting coordinates (y/n), explicit x size,
  71353. X               and explicit y size
  71354. X~FF
  71355. X
  71356. X{Printer Parameters}
  71357. X  printer=type[/res[/lpt#[/-1]]]
  71358. X               Set the printer type, dots/inch, and port#
  71359. X               types: IBM, EPSON, CO (Star Micronix),
  71360. X                  HP (LaserJet), PA (Paintjet),
  71361. X                  PS (PostScript portrait), PSL (landscape)
  71362. X               port# 1-3 LPTn, 11-14 COMn, 21-22 direct parallel,
  71363. X                 31-32 direct serial
  71364. X  linefeed=crlf|lf|cr       Control characters to emit at end of each line
  71365. X  title=yes           Print a title with the output
  71366. X  printfile=filename       Print to specified file
  71367. X  epsf=1|2|3|...       Forces print to file; default filename fract001.eps,
  71368. X               forces PostScript mode
  71369. X  translate=yes|nnn       PostScript only; yes prints negative image;
  71370. X               >0 reduces image colors; <0 color reduce+negative
  71371. X  halftone=frq/angl/styl   PostScript: defines halftone screen
  71372. X  halftone=r/g/b       PaintJet: contrast adjustment
  71373. X  comport=port/baud/opts   COM port initialization. Port=1,2,3,etc.
  71374. X               baud=115,150,300,600,1200,2400,4800,9600
  71375. X               options 7,8 | 1,2 | e,n,o (any order)
  71376. X               Example: comport=1/9600/n71
  71377. X~FF
  71378. X  colorps=yes|no           Enable or Disable the color postscript extensions
  71379. X  rleps=yes|no             Enable or Disable the postscript rle encoding
  71380. X
  71381. X{3D Parameters}
  71382. X  3d=yes|overlay       Resets 3D to defaults, starts 3D mode. If overlay
  71383. X               specified, does not clear existing graphics screen
  71384. X  preview=yes           Turns on 3D 'preview' default mode
  71385. X  showbox=yes           Turns on 3D 'showbox' default mode
  71386. X  sphere=yes           Turns on 3D sphere mode
  71387. X  coarse=nnn           Sets Preview 'coarseness' default value
  71388. X  stereo=nnn           Sets Stereo (R/B 3D) option:  0 = none,
  71389. X               1 = alternate, 2 = superimpose, 3 = photo
  71390. X  ray=nnn           selects raytrace output file format
  71391. X  brief=yes           selects brief or verbose file for DKB output
  71392. X
  71393. X  interocular=nnn       Sets 3D Interocular distance default value
  71394. X  converge=nnn           Sets 3D Convergence default value
  71395. X  crop=nnn/nnn/nnn/nnn       Sets 3D red-left, red-right, blue-left,
  71396. X               and blue-right cropping default valuess
  71397. X  bright=nnn/nnn       Sets 3D red and blue brightness defaults,
  71398. X
  71399. X  longitude=nn/nn       Longitude minumim and maximum
  71400. X  latitude=nn/nn       Latitude minimum and maximum
  71401. X  radius=nn           Radius scale factor
  71402. X  rotation=nn[/nn[/nn]]    Rotation abount x,y, and z axes
  71403. X  scalexyz=nn/nn/nn       X, Y, and Z scale factors
  71404. X  roughness=nn           Same as Z scale factor
  71405. X  waterline=nn           Colors this number and below will be 'inside' color
  71406. X  filltype=nn           3D filltype
  71407. X  perspective=nn       Perspective viewer distance (100 is at the edge)
  71408. X  xyshift=nn/nn        Shift image in x & y directions (alters viewpoint)
  71409. X  lightsource=nn/nn/nn       The coordinates of the light source vector
  71410. X  smoothing=nn           Smooths rough images in light source mode
  71411. X  transparent=mm/nn       Sets colors 'mm' to 'nn as transparent
  71412. X  xyadjust=nnn/nnn       Sets 3D X and Y adjustment defaults,
  71413. X  randomize=nnn        smoothes 3d color transitions between elevations
  71414. X  fullcolor=yes        allows creation of full color .TGA image with
  71415. X               light source fill types
  71416. X  ambient=nnn           sets depth of shadows and contrast when using
  71417. X               light source fill types
  71418. X  haze=nnn           sets haze for distant objects if fullcolor=1
  71419. X  lightname=filename       fullcolor output file name, default FRACT001.TGA
  71420. X;
  71421. X;
  71422. X~Topic=Introduction to Parameters
  71423. X
  71424. XFractint accepts command-line parameters that allow you to start it with a
  71425. Xparticular video mode, fractal type, starting coordinates, and just about
  71426. Xevery other parameter and option.
  71427. X
  71428. XThese parameters can also be specified in a SSTOOLS.INI file, to set them
  71429. Xevery time you run Fractint.
  71430. X
  71431. XThey can also be specified as named groups in a .PAR (parameter) file
  71432. Xwhich you can then call up while running Fractint by using the <@>
  71433. Xcommand.
  71434. X
  71435. XIn all three cases (DOS command line, SSTOOLS.INI, and parameter file) the
  71436. Xparameters use the same syntax, usually a series of keyword=value commands
  71437. Xlike SOUND=OFF.  Each parameter is described in detail in subsequent
  71438. Xsections.
  71439. X;
  71440. X;
  71441. X~Topic=Using the DOS Command Line
  71442. X
  71443. XYou can specify parameters when you start Fractint from DOS by using a
  71444. Xcommand like:
  71445. X
  71446. X    FRACTINT SOUND=OFF FILENAME=MYIMAGE.GIF
  71447. X
  71448. XThe individual parameters are separated by one or more spaces (an
  71449. Xparameter itself may not include spaces). Upper or lower case may be
  71450. Xused, and parameters can be in any order.
  71451. X
  71452. XSince DOS commands are limited to 128 characters, Fractint has a special
  71453. Xcommand you can use when you have a lot of startup parameters (or have a
  71454. Xset of parameters you use frequently):
  71455. X
  71456. X    FRACTINT @MYFILE
  71457. X
  71458. XWhen @filename is specified on the command line, Fractint reads parameters
  71459. Xfrom the specified file as if they were keyed on the command line.  You
  71460. Xcan create the file with a text editor, putting one "keyword=value"
  71461. Xparameter on each line.
  71462. X;
  71463. X;
  71464. X~Topic=Setting Defaults (SSTOOLS.INI File)
  71465. XEvery time Fractint runs, it searches the current directory, and then the
  71466. Xdirectories in your DOS PATH, for a file named SSTOOLS.INI.  If it finds
  71467. Xthis file, it begins by reading parameters from it.  This file is useful
  71468. Xfor setting parameters you always want, such as those defining your
  71469. Xprinter setup.
  71470. X
  71471. XSSTOOLS.INI is divided into sections belonging to particular programs.
  71472. XEach section begins with a label in brackets. Fractint looks for the label
  71473. X[fractint], and ignores any lines it finds in the file belonging to any
  71474. Xother label. If an SSTOOLS.INI file looks like this:
  71475. X
  71476. X  [fractint]\
  71477. X  sound=off     ; (for home use only)\
  71478. X  printer=hp     ; my printer is a LaserJet\
  71479. X  inside=0     ; using "traditional" black\
  71480. X  [startrek]\
  71481. X  warp=9.5     ; Captain, I dinna think the engines can take it!\
  71482. X
  71483. XFractint will use only the second, third, and fourth lines of the file.
  71484. X(Why use a convention like that when Fractint is the only program you know
  71485. Xof that uses an SSTOOLS.INI file?  Because there are other programs (such
  71486. Xas Lee Crocker's PICLAB) that now use the same file, and there may one day
  71487. Xbe other, sister programs to Fractint using that file.)
  71488. X;
  71489. X;
  71490. X~Topic=Parameter Files and the <@> Command
  71491. X
  71492. XYou can change parameters on-the-fly while running Fractint by using the
  71493. X<@> command and a parameter file. Parameter files contain named groups of
  71494. Xparameters, looking something like this:
  71495. X
  71496. X  quickdraw \{        ; a set of parameters named quickdraw\
  71497. X     maxiter=150\
  71498. X     float=no\
  71499. X     }\
  71500. X  slowdraw \{        ; another set of parameters\
  71501. X     maxiter=2000\
  71502. X     float=yes\
  71503. X     }\
  71504. X
  71505. XIf you use the <@> command and select a parameter file containing the
  71506. Xabove example, Fractint will show two choices: quickdraw and slowdraw. You
  71507. Xmove the cursor to highlight one of the choices and press <Enter> to set
  71508. Xthe parameters specified in the file by that choice.
  71509. X
  71510. XThe default parameter file name is FRACTINT.PAR. A different file can be
  71511. Xselected with the "parmfile=" option, or by using <@> and then hitting
  71512. X<F6>.
  71513. X
  71514. XYou can create parameter files with a text editor, or for some uses, by
  71515. Xusing the <B> command. Parameter files can be used in a number of ways,
  71516. Xsome examples:
  71517. X
  71518. X  o To save the parameters for a favorite image. Fractint can do this for
  71519. X    you with the <B> command.
  71520. X
  71521. X  o To save favorite sets of 3D transformation parameters. Fractint can do
  71522. X    this for you with the <B> command.
  71523. X
  71524. X  o To set up different sets of parameters you use occasionally. For
  71525. X    instance, if you have two printers, you might want to set up a group
  71526. X    of parameters describing each.
  71527. X
  71528. X  o To save image parameters for later use in batch mode - see
  71529. X    {Batch Mode}.
  71530. X
  71531. XSee {"Parameter Save/Restore Commands"} for details about the <@> and
  71532. X<B> commands.
  71533. X;
  71534. X;
  71535. X~Topic=General Parameter Syntax
  71536. X
  71537. XParameters must be separated by one or more spaces.
  71538. X
  71539. XUpper and lower case can be used in keywords and values.
  71540. X
  71541. XAnything on a line following a ; (semi-colon) is ignored, i.e. is a
  71542. Xcomment.
  71543. X
  71544. XIn parameter files and SSTOOLS.INI:\
  71545. X  o Individual parameters can be entered on separate lines.\
  71546. X  o Long values can be split onto multiple lines by ending a line with a \\
  71547. X    (backslash) - leading spaces on the following line are ignored, the
  71548. X    information on the next line from the first non-blank character onward
  71549. X    is appended to the prior line.
  71550. X
  71551. XSome terminology:\
  71552. X  KEYWORD=nnn           enter a number in place of "nnn"\
  71553. X  KEYWORD=[filename]       you supply filename\
  71554. X  KEYWORD=yes|no|whatever  choose one of "yes", "no", or "whatever"\
  71555. X  KEYWORD=1st[/2nd[/3rd]]  the slash-separated parameters "2nd" and
  71556. X               "3rd" are optional
  71557. X;
  71558. X;
  71559. X~Topic=Startup Parameters
  71560. X
  71561. X@FILENAME\
  71562. XCauses Fractint to read "filename" for parameters. When it finishes, it
  71563. Xresumes reading its own command line -- i.e., "FRACTINT MAXITER=250
  71564. X@MYFILE PASSES=1" is legal. This option is only valid on the DOS command
  71565. Xline, as Fractint is not clever enough to deal with multiple indirection.
  71566. X
  71567. X@FILENAME/GROUPNAME\
  71568. XLike @FILENAME, but reads a named group of parameters from a parameter
  71569. Xfile.  See {"Parameter Files and the <@> Command"}.
  71570. X
  71571. XFILENAME=[name]\
  71572. XCauses Fractint to read the named file, which must either have been saved
  71573. Xfrom an earlier Fractint session or be a generic GIF file, and use that as
  71574. Xthe starting point, bypassing the initial information screens. The
  71575. Xfiletype is optional and defaults to .GIF. Non-Fractint GIF files are
  71576. Xrestored as fractal type "plasma".\
  71577. XOn the DOS command line you may omit FILENAME= and just give the file name.
  71578. X
  71579. XBATCH=yes\
  71580. XSee {Batch Mode}.
  71581. X
  71582. XAUTOKEY=play|record\
  71583. XSpecifying "play" runs Fractint in playback mode - keystrokes are read
  71584. Xfrom the autokey file (see next parameter) and interpreted as if they're
  71585. Xbeing entered from the keyboard.\
  71586. XSpecifying "record" runs in recording mode - all keystrokes are recorded
  71587. Xin the autokey file.\
  71588. XSee also {Autokey Mode}.
  71589. X
  71590. XAUTOKEYNAME=[filename]\
  71591. XSpecifies the file name to be used in autokey mode. The default file name
  71592. Xis AUTO.KEY.
  71593. X
  71594. XFPU=387|IIT|NOIIT\
  71595. XThis parameter is useful if you have an unusual coprocessor chip. If you
  71596. Xhave a 80287 replacement chip with full 80387 functionality use "FPU=387"
  71597. Xto inform Fractint to take advantage of those extra 387 instructions.
  71598. XIf you have the IIT fpu, but don't have IIT's 'f4x4int.com' TSR loaded,
  71599. Xuse "FPU=IIT" to force Fractint to use that chip's matrix multiplication
  71600. Xroutine automatically to speed up 3-D transformations (if you have an IIT
  71601. Xfpu and have that TSR loaded, Fractint will auto-detect the presence of
  71602. Xthe fpu and TSR and use its extra capabilities automatically).
  71603. XSince all IIT chips support 80387 instructions, enabling the IIT code also
  71604. Xenables Fractint's use of all 387 instructions.
  71605. XSetting "FPU=NOIIT" disables Fractint's IIT Auto-detect capability.
  71606. XWarning: multi-tasking operating systems such as Windows and DesQView
  71607. Xdon't automatically save the IIT chip extra registers, so running two
  71608. Xprograms at once that both use the IIT's matrix multiply feature but
  71609. Xdon't use the handshaking provided by that 'f4x4int.com' program,
  71610. Xerrors will result.
  71611. X
  71612. XMAKEDOC[=filename]\
  71613. XCreate Fractint documentation file (for printing or viewing with a text
  71614. Xeditor) and then return to DOS.  Filename defaults to FRACTINT.DOC.
  71615. XThere's also a function in Fractint's online help which can be used to
  71616. Xproduce the documentation file -
  71617. X~Doc-
  71618. Xsee {Printing Fractint Documentation}.
  71619. X~Doc+,Online-
  71620. Xuse "Printing Fractint Documentation" from the main help index.
  71621. X~Online+
  71622. X;
  71623. X;
  71624. X~Topic=Calculation Mode Parameters
  71625. X
  71626. XPASSES=1|2|guess|btm|tesseral\
  71627. XSelects single-pass, dual-pass, solid-Guessing mode, Boundary Tracing,
  71628. Xor the Tesseral algorithm.  See {Drawing Method}.
  71629. X
  71630. XFILLCOLOR=normal|<nnn>\
  71631. XSets a color to be used for block fill by Boundary Tracing and Tesseral
  71632. Xalgorithms.  See {Drawing Method}.
  71633. X
  71634. XFLOAT=yes\
  71635. XMost fractal types have both a fast integer math and a floating point
  71636. Xversion. The faster, but possibly less accurate, integer version is the
  71637. Xdefault. If you have a new 80486 or other fast machine with a math
  71638. Xcoprocessor, or if you are using the continuous potential option (which
  71639. Xlooks best with high bailout values not possible with our integer math
  71640. Ximplementation), you may prefer to use floating point. Just add
  71641. X"float=yes" to the command line to do so.
  71642. XAlso see {"Limitations of Integer Math (And How We Cope)"}.
  71643. X
  71644. XSYMMETRY=xxx\
  71645. XForces symmetry to None, Xaxis, Yaxis, XYaxis, Origin, or Pi symmetry.
  71646. XUseful for debugging.
  71647. X;
  71648. X;
  71649. X~Topic=Fractal Type Parameters
  71650. X
  71651. XTYPE=[name]\
  71652. XSelects the fractal type to calculate. The default is type "mandel".
  71653. X
  71654. XPARAMS=n/n/n/n...\
  71655. XSet optional (required, for some fractal types) values used in the
  71656. Xcalculations. These numbers typically represent the real and imaginary
  71657. Xportions of some startup value, and are described in detail as needed in
  71658. X{Fractal Types}.\
  71659. X(Example: FRACTINT TYPE=julia PARAMS=-0.48/0.626 would wait at the opening
  71660. Xscreen for you to select a video mode, but then proceed straight to the
  71661. XJulia set for the stated x (real) and y (imaginary) coordinates.)
  71662. X
  71663. XFUNCTION=[fn1[/fn2[/fn3[/fn4]]]]\
  71664. XAllows setting variable functions found in some fractal type formulae.
  71665. XPossible values are sin, cos, tan, cotan, sinh, cosh, tanh, cotanh, exp,
  71666. Xlog, sqr, recip (i.e. 1/z), ident (i.e. identity), and cosxx (cos with
  71667. Xa pre version 16 bug).
  71668. X
  71669. XFORMULANAME=[formulaname]\
  71670. XSpecifies the default formula name for type=formula fractals.  (I.e. the
  71671. Xname of a formula defined in the FORMULAFILE.) Required if you want to
  71672. Xgenerate one of these fractal types in batch mode, as this is the only way
  71673. Xto specify a formula name in that case.
  71674. X
  71675. XLNAME=[lsystemname]\
  71676. XSpecifies the default L-System name. (I.e. the name of an entry in the
  71677. XLFILE.) Required if you want to generate one of these fractal types in
  71678. Xbatch mode, as this is the only way to specify an L-System name in that
  71679. Xcase.
  71680. X
  71681. XIFS=[ifsname]\
  71682. XSpecifies the default IFS name. (I.e. the name of an entry in the
  71683. XIFSFILE.) Required if you want to generate one of these fractal types in
  71684. Xbatch mode, as this is the only way to specify an IFS name in that case.
  71685. X;
  71686. X;
  71687. X~Topic=Image Calculation Parameters
  71688. XMAXITER=nnn\
  71689. XReset the iteration maximum (the number of iterations at which the program
  71690. Xgives up and says 'OK, this point seems to be part of the set in question
  71691. Xand should be colored [insidecolor]') from the default 150. Values range
  71692. Xfrom 10 to 32000 (super-high iteration limits like 30000 are useful when
  71693. Xusing logarithmic palettes).  See {The Mandelbrot Set} for a description
  71694. Xof the iteration method of calculating fractals.\
  71695. X"maxiter=" can also be used to adjust the number of orbits plotted for
  71696. X3D "attractor" fractal types such as lorenz3d and kamtorus.
  71697. X
  71698. XCORNERS=xmin/xmax/ymin/ymax[/x3rd/y3rd]\
  71699. XExample: corners=-0.739/-0.736/0.288/0.291\
  71700. XBegin with these coordinates as the range of x and y coordinates, rather
  71701. Xthan the default values of (for type=mandel) -2.0/2.0/-1.5/1.5. When you
  71702. Xspecify four values (the usual case), this defines a rectangle: x-
  71703. Xcoordinates are mapped to the screen, left to right, from xmin to xmax, y-
  71704. Xcoordinates are mapped to the screen, bottom to top, from ymin to ymax.
  71705. XSix parameters can be used to describe any rotated or stretched
  71706. Xparallelogram:    (xmin,ymax) are the coordinates used for the top-left
  71707. Xcorner of the screen, (xmax,ymin) for the bottom-right corner, and
  71708. X(x3rd,y3rd) for the bottom-left.
  71709. X
  71710. XCENTER-MAG=[Xctr/Yctr/Mag]\
  71711. XThis is an alternative way to enter corners as a center point and a
  71712. Xmagnification that is popular with some fractal programs and publications.
  71713. XEntering just "CENTER-MAG=" tells Fractint whether to use this form rather
  71714. Xthan corners when saving parameters with  the <B> command. The <TAB>
  71715. Xstatus display shows the "corners" in both forms.  Note that an aspect
  71716. Xratio of 1.3333 is assumed; if you have altered the zoom box proportions
  71717. Xor rotated the zoom box, this form can no longer be used.
  71718. X
  71719. XBAILOUT=nnn\
  71720. XOver-rides the default bailout criterion for escape-time fractals. Can
  71721. Xalso be set from the parameters screen after selecting a fractal type.
  71722. XSee description of bailout in {The Mandelbrot Set}.
  71723. X
  71724. XRESET\
  71725. XCauses Fractint to reset all calculation related parameters to their
  71726. Xdefault values. Non-calculation parameters such as "printer=", "sound=",
  71727. Xand "savename=" are not affected. RESET should be specified at the start
  71728. Xof each parameter file entry (used with the <@> command) which defines an
  71729. Ximage, so that the entry need not describe every possible parameter - when
  71730. Xinvoked, all parameters not specifically set by the entry will have
  71731. Xpredictable values (the defaults).
  71732. X
  71733. XINITORBIT=pixel\
  71734. XINITORBIT=nnn/nnn\
  71735. XAllows control over the value used to begin each Mandelbrot-type orbit.
  71736. X"initorbit=pixel" is the default for most types; this command initializes
  71737. Xthe orbit to the complex number corresponding to the screen pixel. The
  71738. Xcommand "initorbit=nnn/nnn" uses the entered value as the initializer. See
  71739. Xthe discussion of the {Mandellambda Sets} for more on this topic.
  71740. X
  71741. XORBITDELAY=<nn>\
  71742. XSlows up the display of orbits using the <o> command
  71743. Xfor folks with hot new computers. Units are in 1/10000 seconds per
  71744. Xorbit point.  ORBITDELAY=10 therefore allows you to see each pixel's
  71745. Xorbit point for about one millisecond. For best display of orbits,
  71746. Xtry passes=1 and a moderate resolution such as 320x200.  Note that
  71747. Xthe first time you press the 'o' key with the 'orbitdelay' function
  71748. Xactive, your computer will pause for a half-second or so to calibrate
  71749. Xa high-resolution timer.        
  71750. X
  71751. XPERIODICITY=no|show|nnn\
  71752. XControls periodicity checking (see {Periodicity Logic}).
  71753. X"no" turns it off, "show" lets
  71754. Xyou see which pixels were painted as "inside" due to being caught
  71755. Xby periodicity.  Specifying a number causes a more conservative
  71756. Xperiodicity test (each increase of 1 divides test tolerance by 2).
  71757. XEntering a negative number lets you turn on "show" with that number. Type
  71758. Xlambdafn function=exp needs periodicity turned off to be accurate -- there
  71759. Xmay be other cases.
  71760. X
  71761. XRSEED=nnnn\
  71762. XThe initial random-number "seed" for plasma clouds is taken from your PC's
  71763. Xinternal clock-timer. This argument forces a value (which you can see in
  71764. Xthe <Tab> display), and allows you to reproduce plasma clouds. A detailed
  71765. Xdiscussion of why a TRULY random number may be impossible to define, let
  71766. Xalone generate, will have to wait for "FRACTINT: The 3-MB Doc File."
  71767. X
  71768. XSHOWDOT=<nn>\
  71769. XColors the pixel being calculated color <nn>. Useful for very slow
  71770. Xfractals for showing you the calculation status.
  71771. X;
  71772. X;
  71773. X~Topic=Color Parameters
  71774. XINSIDE=nnn|bof60|bof61|zmag|attractor|epscross|startrail|period\
  71775. XSet the color of the interior: for
  71776. Xexample, "inside=0" makes the M-set "lake" a stylish basic black. A setting of
  71777. X-1 makes inside=maxiter. Three more options reveal hidden structure inside the
  71778. Xlake.  Inside=bof60 and inside=bof61, are named after the figures on pages 60
  71779. Xand 61 of "Beauty of Fractals".  See {Inside=bof60|bof61|zmag|period}
  71780. Xfor a brilliant explanation of what these do!
  71781. X
  71782. XInside=zmag is a method of coloring based on the magnitude of Z after the
  71783. Xmaximum iterations have been reached.  The affect along the edges of the
  71784. XMandelbrot is like thin-metal welded sculpture.
  71785. X
  71786. XInside=epscross colors pixels green or yellow according to whether their 
  71787. Xorbits swing close to the Y-axis or X-axis, respectively. Inside=starcross
  71788. Xhas a coloring scheme based on clusters of points in the orbits. Best with
  71789. Xoutside=<nnn>. For more information, see {Inside=epscross|startrail}.
  71790. X
  71791. XInside=period colors pixels according to the period of their eventual orbit.
  71792. X
  71793. XNote that the "Look for finite attractor" option on the <Y> options screen
  71794. Xwill override the selected inside option if an attractor is found - see
  71795. X{Finite Attractors}.
  71796. X
  71797. XOUTSIDE=nnn|iter|real|imag|summ|mult\
  71798. XThe classic method of coloring outside
  71799. Xthe fractal is to color according to how many iterations were required before
  71800. XZ reached the bailout value, usually 4. This is the method used when
  71801. XOUTSIDE=iter.
  71802. X
  71803. XHowever, when Z reaches bailout the real and imaginary components can be at
  71804. Xvery diferent values.  OUTSIDE=real and OUTSIDE=imag color using the iteration
  71805. Xvalue plus the real or imaginary values.  OUTSIDE=summ uses the sum of all
  71806. Xthese values.  These options can give a startling 3d quality to otherwise flat
  71807. Ximages and can change some boring images to wonderful ones. OUTSIDE=mult
  71808. Xcolors by multiplying the iteration by real divided by imaginary. There was no
  71809. Xmathematical reason for this, it just seemed like a good idea.
  71810. X
  71811. XOutside=nnn sets the color of the exterior to some number of your choosing:
  71812. Xfor example, "OUTSIDE=1" makes all points not INSIDE the fractal set to color
  71813. X1 (blue). Note that defining an OUTSIDE color forces any image to be a
  71814. Xtwo-color one: either a point is INSIDE the set, or it's OUTSIDE it.
  71815. X
  71816. XMAP=[filename]\
  71817. XReads in a replacement color map from [filename]. This map replaces the
  71818. Xdefault color map of your video adapter. Requires a VGA or higher adapter.
  71819. XThe difference
  71820. Xbetween this argument and an alternate map read in via <L> in color-
  71821. Xcommand mode is that this one applies to the entire run.
  71822. XSee {Palette Maps}.
  71823. X
  71824. XCOLORS=@filename|colorspecification\
  71825. XSets colors for the current image, like the <L> function in color cycling
  71826. Xand palette editing modes. Unlike the MAP= parameter, colors set with
  71827. XCOLORS= do not replace the default - when you next select a new video
  71828. Xmode, colors will revert to their defaults.\
  71829. XCOLORS=@filename tells Fractint to use a color map file named "filename".
  71830. XSee {Palette Maps}.\
  71831. XCOLORS=colorspecification specifies the colors directly. The value of
  71832. X"colorspecification" is rather long (768 characters for 256 color modes),
  71833. Xand its syntax is not documented here. This form of the COLORS= command is
  71834. Xnot intended for manual use - it exists for use by the <B> command when
  71835. Xsaving the description of a nice image.
  71836. X
  71837. XCYCLERANGE=nnn/nnn\
  71838. XSets the range of color numbers to be animated during color cycling.  The
  71839. Xdefault is 1/255, i.e. just color number 0 (usually black) is not cycled.
  71840. X
  71841. XCYCLELIMIT=nnn\
  71842. XSets the speed of color cycling. Technically, the number of DAC registers
  71843. Xupdated during a single vertical refresh cycle. Legal values are 1 - 256,
  71844. Xdefault is 55.
  71845. X
  71846. XTEXTCOLORS=mono\
  71847. XSet text screen colors to simple black and white.
  71848. X
  71849. XTEXTCOLORS=aa/bb/cc/...\
  71850. XSet text screen colors. Omit any value to use the default (e.g.
  71851. Xtextcolors=////50 to set just the 5th value). Each value is a 2 digit
  71852. Xhexadecimal value; 1st digit is background color (from 0 to 7), 2nd digit
  71853. Xis foreground color (from 0 to F).\
  71854. X~Format-
  71855. XColor values are:
  71856. X    0 black    8 gray
  71857. X    1 blue    9 light blue
  71858. X    2 green    A light green
  71859. X    3 cyan    B light cyan
  71860. X    4 red    C light red
  71861. X    5 magenta    D light magenta
  71862. X    6 brown    E yellow
  71863. X    7 white    F bright white
  71864. X31 colors can be specified, their meanings are as follows:
  71865. X~OnlineFF
  71866. X  heading:
  71867. X    1  Fractint version info
  71868. X    2  heading line development info (not used in released version)
  71869. X  help:
  71870. X    3  sub-heading
  71871. X    4  main text
  71872. X    5  instructions at bottom of screen
  71873. X    6  hotlink field
  71874. X    7  highlighted (current) hotlink
  71875. X  menu, selection boxes, parameter input boxes:
  71876. X    8  background around box and instructions at bottom
  71877. X    9  emphasized text outside box
  71878. X   10  low intensity information in box
  71879. X   11  medium intensity information in box
  71880. X   12  high intensity information in box (e.g. heading)
  71881. X   13  current keyin field
  71882. X   14  current keyin field when it is limited to one of n values
  71883. X   15  current choice in multiple choice list
  71884. X   16  speed key prompt in multiple choice list
  71885. X   17  speed key keyin in multiple choice list
  71886. X  general (tab key display, IFS parameters, "thinking" display):
  71887. X   18  high intensity information
  71888. X   19  medium intensity information
  71889. X   20  low intensity information
  71890. X   21  current keyin field
  71891. X  disk video:
  71892. X   22  background around box
  71893. X   23  high intensity information
  71894. X   24  low intensity information
  71895. X  diagnostic messages:
  71896. X   25  error
  71897. X   26  information
  71898. X  credits screen:
  71899. X   27  bottom lines
  71900. X   28  high intensity divider line
  71901. X   29  low intensity divider line
  71902. X   30  primary authors
  71903. X   31  contributing authors
  71904. XThe default is
  71905. X   textcolors=1F/1A/2E/70/28/71/31/78/70/17/
  71906. X          1F/1E/2F/3F/5F/07/0D/71/70/78/0F/
  71907. X          70/0E/0F/4F/20/17/20/28/0F/07
  71908. X(In a real command file, all values must be on one line.)
  71909. X~Format+
  71910. X;
  71911. X;
  71912. X~Topic=Doodad Parameters
  71913. X
  71914. XLOGMAP=yes|old|n\
  71915. XSelects a compressed relationship between escape-time iterations and
  71916. Xpalette colors.  See {"Logarithmic Palettes and Color Ranges"} for details.
  71917. X
  71918. XRANGES=nn/nn/nn/...\
  71919. XSpecifies ranges of escape-time iteration counts to be mapped to each
  71920. Xcolor number.  See {"Logarithmic Palettes and Color Ranges"} for details.
  71921. X
  71922. XDISTEST=nnn/nnn\
  71923. XA nonzero value in the first parameter enables the distance estimator
  71924. Xmethod. The second parameter specifies the "width factor", defaults to 71.
  71925. XSee {"Distance Estimator Method"} for details.
  71926. X
  71927. XDECOMP=2|4|8|16|32|64|128|256\
  71928. XInvokes the corresponding decomposition coloring scheme.
  71929. XSee {Decomposition} for details.
  71930. X
  71931. XBIOMORPH=nnn\
  71932. XTurn on biomorph option; set affected pixels to color nnn.
  71933. XSee {Biomorphs} for details.
  71934. X
  71935. XPOTENTIAL=maxcolor[/slope[/modulus[/16bit]]]\
  71936. XEnables the "continuous potential" coloring mode for all fractal types
  71937. Xexcept plasma clouds, attractor types such as lorenz, and IFS. The four
  71938. Xarguments define the maximum color value, the slope of the potential
  71939. Xcurve, the modulus "bailout" value, and whether 16 bit values are to be
  71940. Xcalculated.  Example: "POTENTIAL=240/2000/40/16bit". The Mandelbrot and
  71941. XJulia types ignore the modulus bailout value and use their own hardwired
  71942. Xvalue of 4.0 instead.  See {Continuous Potential} for details.
  71943. X
  71944. XINVERT=nn/nn/nn\
  71945. XTurns on inversion. The parameters are radius of inversion, x-coordinate
  71946. Xof center, and y-coordinate of center. -1 as the first parameter sets the
  71947. Xradius to 1/6 the smaller screen dimension; no x/y parameters defaults to
  71948. Xcenter of screen. The values are displayed with the <Tab> command.
  71949. XSee {Inversion} for details.
  71950. X
  71951. XFINATTRACT=no|yes\
  71952. XAnother option to show coloring inside some Julia "lakes" to show escape
  71953. Xtime to finite attractors. Works with lambda, magnet types, and possibly
  71954. Xothers.  See {Finite Attractors} for more information.
  71955. X
  71956. XEXITNOASK=yes\
  71957. XThis option forces Fractint to bypass the final "are you sure?" exit
  71958. Xscreen when the ESCAPE key is pressed from the main image-generation
  71959. Xscreen.  Added at the request of Ward Christensen.  It's his funeral <grin>.
  71960. X;
  71961. X;
  71962. X~Topic=File Parameters
  71963. X
  71964. XSAVENAME=[name]\
  71965. XSet the filename to use when you <S>ave a screen. The default filename is
  71966. XFRACT001. The .GIF extension is optional (Example: SAVENAME=myfile)
  71967. X
  71968. XOVERWRITE=no|yes\
  71969. XSets the savename overwrite flag (default is 'no'). If 'yes', saved files
  71970. Xwill over-write existing files from previous sessions; otherwise the
  71971. Xautomatic incrementing of FRACTnnn.GIF will find the first unused
  71972. Xfilename.
  71973. X
  71974. XSAVETIME=nnn\
  71975. XTells Fractint to automatically do a save every nnn minutes while a
  71976. Xcalculation is in progress.  This is mainly useful with long batches - see
  71977. X{Batch Mode}.
  71978. X
  71979. XGIF87a=YES\
  71980. XBackward-compatibility switch to force creation of GIF files in the GIF87a
  71981. Xformat. As of version 14, Fractint defaults to the new GIF89a format which
  71982. Xpermits storage of fractal information within the format. GIF87a=YES is
  71983. Xonly needed if you wish to view Fractint images with a GIF decoder that
  71984. Xcannot accept the newer format.  See {GIF Save File Format}.
  71985. X
  71986. XDITHER=YES\
  71987. XDither a color file into two colors for display on a b/w display.  This give
  71988. Xa poor-quality display of gray levels.  Note that if you have a 2-color
  71989. Xdisplay, you can create a 256-color gif with disk video and then read it
  71990. Xback in dithered.
  71991. X
  71992. XPARMFILE=[parmfilename]\
  71993. XSpecifies the default parameter file to be used by the <@> and <B>
  71994. Xcommands.  If not specified, the default is FRACTINT.PAR.
  71995. X
  71996. XFORMULAFILE=[formulafilename]\
  71997. XSpecifies the formula file for type=formula fractals (default is
  71998. XFRACTINT.FRM).    Handy if you want to generate one of these fractal types
  71999. Xin batch mode.
  72000. X
  72001. XLFILE=[lsystemfile]\
  72002. XSpecifies the default L-System file for type=lsystem fractals (if not
  72003. XFRACTINT.L).
  72004. X
  72005. XIFSFILE=[ifsfilename]\
  72006. XSpecifies the default file for type=ifs fractals (default is
  72007. XFRACTINT.IFS).
  72008. X
  72009. XFILENAME=[.suffix]\
  72010. XSets the default file extension used for the <r> command.
  72011. XWhen this parameter is omitted, the
  72012. Xdefault file mask shows .GIF and .POT files.  You might want to specify
  72013. Xthis parameter and the SAVENAME= parameter in your SSTOOLS.INI file if you
  72014. Xkeep your fractal images separate from other .GIF files by using a
  72015. Xdifferent suffix for them.
  72016. X
  72017. XORBITSAVE=yes\
  72018. XCauses the file ORBITS.RAW to be opened and the points generated by orbit
  72019. Xfractals or IFS fractals to be saved in a raw format. This file can be read
  72020. Xby the Acrospin program which can rotate and scale the image rapidly in
  72021. Xresponse to cursor-key commands. The filename ORBITS.RAW is fixed and will
  72022. Xbe overwritten each time a new fractal is generated with this option.\
  72023. X(see {Barnsley IFS Fractals} {Orbit Fractals} {=@ACROSPIN Acrospin});
  72024. X;
  72025. X~Topic=Video Parameters
  72026. X
  72027. XVIDEO=xxx\
  72028. XSet the initial video mode (and bypass the informational screens). Handy
  72029. Xfor batch runs. (Example: VIDEO=F4 for IBM 16-color VGA.)
  72030. XYou can obtain the current VIDEO= values (key assignments) from the
  72031. X"select video mode" screens inside Fractint. If you want to do a batch run
  72032. Xwith a video mode which isn't currently assigned to a key, you'll have to
  72033. Xmodify the key assignments - see {"Video Mode Function Keys"}.
  72034. X
  72035. XASKVIDEO=yes|no\
  72036. XIf "no," this eliminates the prompt asking you if a file to be restored is
  72037. XOK for your current video hardware.\
  72038. XWARNING: every version of Fractint so far has had a bigger, better, but
  72039. Xshuffled-around video table. Since calling for a mode your hardware
  72040. Xdoesn't support can leave your system in limbo, be careful about leaving
  72041. Xthe above two parameters in a command file to be used with future versions
  72042. Xof Fractint, particularly for the super-VGA modes.
  72043. X
  72044. XADAPTER=hgc|cga|ega|egamono|mcga|vga|ATI|Everex|Trident|NCR|Video7|Genoa|
  72045. X        Paradise|Chipstech|Tseng3000|Tseng4000|AheadA|AheadB|Oaktech\
  72046. XBypasses Fractint's internal video autodetect logic and assumes that the
  72047. Xspecified kind of adapter is present. Use this parameter only if you
  72048. Xencounter video problems without it.  Specifying adapter=vga with an SVGA
  72049. Xadapter will make its extended modes unusable with Fractint.  All of the
  72050. Xoptions after the "VGA" option specify specific SuperVGA chipsets which
  72051. Xare capable of video resolutions higher than that of a "vanilla" VGA adapter.
  72052. XNote that Fractint cares about the Chipset your adapter uses internally,
  72053. Xnot the name of the company that sold it to you.
  72054. X
  72055. XVESADETECT=yes|no\
  72056. XSpecify no to bypass VESA video detection logic. Try this if you encounter
  72057. Xvideo problems with a VESA compliant video adapter or driver.
  72058. X
  72059. XAFI=yes|8514|no\
  72060. XNormally, when you attempt to use an 8514/A-specific video mode, Fractint
  72061. Xfirst attempts to detect the presence of an 8514/A register-compatible
  72062. Xadapter.  If it fails to find one, it then attempts to detect the presence
  72063. Xof an 8514/A-compatible API (IE, IBM's HDILOAD or its equivalent).  
  72064. XFractint then uses either its register-compatible or its API-compatible
  72065. Xvideo logic based on the results of those tests.  If you have an
  72066. X"8514/A-compatible" video adapter that passes Fractint's
  72067. Xregister-compatible detection logic but doesn't work correctly with
  72068. XFractint's register-compatible video logic, setting "afi=yes" will
  72069. Xforce Fractint to bypass the register-compatible code and look only for
  72070. Xthe API interface.
  72071. X
  72072. XTEXTSAFE=yes|no|bios|save\
  72073. XWhen you switch from a graphics image to text mode (e.g. when you use <F1>
  72074. Xwhile a fractal is on display), Fractint remembers the graphics image, and
  72075. Xrestores it when you return from the text mode.
  72076. XThis should be no big deal - there are a number of well-defined ways
  72077. XFractint could do this which *should* work on any video adapter.  They
  72078. Xdon't - every fast approach we've tried runs into a bug on one video
  72079. Xadapter or another.  So, we've implemented a fast way which works on most
  72080. Xadapters in most modes as the default, and added this parameter for use
  72081. Xwhen the default approach doesn't work.\
  72082. XIf you experience the following problems, please fool around with this
  72083. Xparameter to try to fix the problem:\
  72084. X  o Garbled image, or lines or dashes on image, when returning to image
  72085. X    after going to menu, <tab> display, or help.\
  72086. X  o Blank screen when starting Fractint.\
  72087. XThe problems most often occur in higher resolution modes. We have not
  72088. Xencountered them at all in modes under 320x200x256 - for those modes
  72089. XFractint always uses a fast image save/restore approach.\
  72090. XTextsafe options:\
  72091. X  yes: This is the default. When switching to/from graphics, Fractint
  72092. X    saves just that part of video memory which EGA/VGA adapters are
  72093. X    supposed to modify during the mode changes.
  72094. X  no: This forces use of monochrome 640x200x2 mode for text displays (when
  72095. X    there is a high resolution graphics image to be saved.) This choice is
  72096. X    fast but uses chunky and colorless characters. If it turns out to be
  72097. X    the best choice for you, you might want to also specify
  72098. X    "textcolors=mono" for a more consistent appearance in text screens.
  72099. X  bios: This saves memory in the same way as textsafe=yes, but uses the
  72100. X    adapter's BIOS routines to save/restore the graphics state.  This
  72101. X    approach is fast and ought to work on all adapters. Sadly, we've found
  72102. X    that very few adapters implement this function perfectly.
  72103. X  save: This is the last choice to try. It should work on all adapters in
  72104. X    all modes but it is slow. It tells Fractint to save/restore the entire
  72105. X    image. Expanded or extended memory is used for the save if you have
  72106. X    enough available; otherwise a temporary disk file is used. The speed
  72107. X    of textsafe=save will be acceptable on some machines but not others.
  72108. X    The speed depends on:\
  72109. X      o Cpu and video adapter speed.\
  72110. X      o Whether enough expanded or extended memory is available.\
  72111. X      o Video mode of image being remembered. A few special modes are
  72112. X    *very* slow compared to the rest. The slow ones are: 2 and 4 color
  72113. X    modes with resolution higher than 640x480; custom modes for ATI
  72114. X    EGA Wonder, Paradise EGA-480, STB, Compaq portable 386, AT&T 6300,
  72115. X    and roll-your-own video modes implemented with customized
  72116. X    "yourvid.c" code.
  72117. XIf you want to tune Fractint to use different "textsafe" options for
  72118. Xdifferent video modes, see {"Customized Video Modes\, FRACTINT.CFG"}.
  72119. X(E.g. you might
  72120. Xwant to use the slower textsafe=save approach just for a few high-
  72121. Xresolution modes which have problems with textsafe=yes.)
  72122. X
  72123. XEXITMODE=nn\
  72124. XSets the bios-supported videomode to use upon exit to the specified value.
  72125. Xnn is in hexadecimal.  The default is 3, which resets to 80x25 color text
  72126. Xmode on exit. With Hercules Graphics Cards, and with monochrome EGA
  72127. Xsystems, the exit mode is always 7 and is unaffected by this parameter.
  72128. X
  72129. XTPLUS=yes|no\
  72130. XFor TARGA+ adapters. Setting this to 'no' pretends a TARGA+ is NOT
  72131. Xinstalled.
  72132. X
  72133. XNONINTERLACED=yes|no\
  72134. XFor TARGA+ adapters. Setting this to 'yes' will configure the adapter to a
  72135. Xnon-interlaced mode whenever possible.    It should only be used with a
  72136. Xmultisynch monitor. The default is no, i.e. interlaced.
  72137. X
  72138. XMAXCOLORRES=8|16|24\
  72139. XFor TARGA+ adapters. This determines the number of bits to use for color
  72140. Xresolution.  8 bit color is equivalent to VGA color resolution. The 16 and
  72141. X24 bit color resolutions are true color video modes which are not yet
  72142. Xsupported by Fractint but are hopefully coming soon.
  72143. X
  72144. XPIXELZOOM=0|1|2|3\
  72145. XFor TARGA+ adapters. Lowers the video mode resolution by powers of 2. For
  72146. Xexample, the 320x200 video resolution on the TARGA+ is actually the
  72147. X640x400 video mode with a pixel zoom of 1.  Using the 640x400 video mode
  72148. Xwith a zoom of 3 would lower the resolution by 8, which is 2 raised to the
  72149. X3rd power, for a full screen resolution of 80x50 pixels.
  72150. X
  72151. XVIEWWINDOWS=xx[/xx[/yes|no[/nn[/nn]]]]
  72152. XSet the reduction factor, final media aspect ratio, crop starting
  72153. Xcoordinates (y/n), explicit x size, and explicit y size, see {"View Window"}.
  72154. X;
  72155. X;
  72156. X~Topic=Sound Parameters
  72157. X
  72158. XSOUND=off|x|y|z\
  72159. XWe're all MUCH too busy to waste time with Fractint at work, and no doubt
  72160. Xyou are too, so "sound=off" is included only for use at home, to avoid
  72161. Xwaking the kids or your Significant Other, late at night. (By the way,
  72162. Xdidn't you tell yourself "just one more zoom on LambdaSine" an hour ago?)
  72163. XSuggestions for a "boss" hot-key will be cheerfully ignored, as this
  72164. Xsucker is getting big enough without including a spreadsheet screen too.
  72165. XThe "sound=x/y/x" options are for the "attractor" fractals, like the
  72166. XLorenz fractals - they play with the sound on your PC speaker as they are
  72167. Xgenerating an image, based on the X or Y or Z co-ordinate they are
  72168. Xdisplaying at the moment.  At the moment, "sound=x" (or y or z) really
  72169. Xdoesn't work very well when using an integer algorithm - try it with the
  72170. Xfloating-point toggle set, instead.
  72171. X
  72172. XThe scope of the sound command has been extended. You can now hear the
  72173. Xsound of fractal orbits--just turn on sound from the command line or the
  72174. X<X> menu, fire up a fractal, and try the <O>rbits command. Use the
  72175. Xorbitdelay=<nnn> command (also on the <X> menu) to dramatically alter
  72176. Xthe effect, which ranges from an unearthly scream to a series of discrete
  72177. Xtones. Not recommended when people you have to live with are nearby!
  72178. XRemember, we don't promise that it will sound beautiful!
  72179. X
  72180. XYou can also "hear" any image that Fractint can decode; turn on sound
  72181. Xbefore using <R> to read in a GIF file. We have no idea if this feature
  72182. Xis useful. It was inspired by the comments of an on-line friend who is
  72183. Xblind. We solicit feedback and suggestions from anyone who finds these
  72184. Xsound features interesting or useful. The orbitdelay command also affects
  72185. Xthe sound of decoding images.
  72186. X
  72187. XHERTZ=nnn\
  72188. XAdjusts the sound produced by the "sound=x/y/z" option.  Legal values are
  72189. X200 through 10000.
  72190. X;
  72191. X;
  72192. X~Topic=Printer Parameters
  72193. X
  72194. X~Doc-
  72195. XGeneral printer parameters are described below.\
  72196. XAdditional parameters for specific types of printers are described in:\
  72197. X     {PostScript Parameters}\
  72198. X     {PaintJet Parameters}\
  72199. X     {Plotter Parameters}\
  72200. X
  72201. X~Doc+
  72202. XPRINTER=type[/resolution[/port#]]\
  72203. XDefines your printer setup. The SSTOOLS.INI file is a REAL handy place to
  72204. Xput this option, so that it's available whenever you have that sudden,
  72205. Xirresistible urge for hard copy.
  72206. X~Format-
  72207. XPrinter types:
  72208. X  IB  IBM-compatible (default)
  72209. X  EP  Epson-compatible
  72210. X  HP  LaserJet
  72211. X  CO  Star Micronics Color printer, supposedly Epson-color-compatible
  72212. X  PA  Paintjet
  72213. X  PS  PostScript
  72214. X  PSL Postscript, landscape mode
  72215. X  PL  Plotter using HP-GL
  72216. XResolution:
  72217. X  In dots per inch.
  72218. X  Epson/IBM: 60, 120, 240
  72219. X  LaserJet: 75, 150, 300
  72220. X  PaintJet: 90, 180
  72221. X  PostScript: 10 through 600, or special value 0 to print full page to
  72222. X  within about .4" of the edges (in portrait mode, width is full page and
  72223. X  height is adjusted to 3:4 aspect ratio)
  72224. X  Plotter: 1 to 10 for 1/Nth of page (e.g. 2 for 1/2 page)
  72225. XPort:
  72226. X  1, 2, 3 for LPT1-3 via BIOS
  72227. X  11, 12, 13, 14 for COM1-4 via BIOS
  72228. X  21, 22 for LPT1 or LPT2 using direct port access (faster when it works)
  72229. X  31, 32 for COM1 or COM2 using direct port access
  72230. X~Format+
  72231. X
  72232. XCOMPORT=port/baud/options\
  72233. XSerial printer port initialization.\
  72234. XPort=1,2,3,etc.\
  72235. XBaud=115,150,300,600,1200,2400,4800,9600\
  72236. XOptions: 7,8 | 1,2 | e,n,o (any order).\
  72237. XExample: comport=1/9600/n81 for COM1 set to 9600, no parity, 8 bits per
  72238. Xcharacter, 1 stop bit.
  72239. X
  72240. XLINEFEED=crlf|lf|cr\
  72241. XSpecifies the control characters to emit at end of each line:  carriage
  72242. Xreturn and linefeed, just linefeed, or just carriage return.  The default
  72243. Xis crlf.
  72244. X
  72245. XTITLE=yes\
  72246. XIf specified, title information is added to printouts.
  72247. X
  72248. XPRINTFILE=filename\
  72249. XCauses output data for the printer to be written to the named file on disk
  72250. Xinstead of to a printer port. The filename is incremented by 1 each time
  72251. Xan image is printed - e.g. if the name is FRAC01.PRN, the second print
  72252. Xoperation writes to FRAC02.PRN, etc. Existing files are not overwritten -
  72253. Xif the file exists, the filename is incremented to a new name.
  72254. X;
  72255. X;
  72256. X~Topic=PostScript Parameters
  72257. X
  72258. XEPSF=1|2|3\
  72259. XForces print-to-file and PostScript. If PRINTFILE is not specified, the
  72260. Xdefault filename is FRACT001.EPS. The number determines how 'well-behaved'
  72261. Xa .EPS file is. 1 means by-the-book. 2 allows some EPS 'no-nos' like
  72262. Xsettransfer and setscreen - BUT includes code that should make the code
  72263. Xstill work without affecting the rest of the non-EPS document. 3 is a
  72264. Xfree-for-all.
  72265. X
  72266. XCOLORPS=YES|NO - Enable or disable the color extensions.
  72267. X
  72268. XRLEPS=YES|NO\
  72269. XEnable or disable run length encoding of the PostScript file.  Run length
  72270. Xencoding will make the PostScript file much smaller, but it may take longer
  72271. Xto print.  The run length encoding code is based on pnmtops, which is
  72272. Xcopyright (C) 1989 by Jef Poskanzer, and carries the following notice:
  72273. X"Permission to use, copy, modify, and distribute this software and its
  72274. Xdocumentation for any purpose and without fee is hereby granted, provided
  72275. Xthat the above copyright notice appear in all copies and that both that
  72276. Xcopyright notice and this permission notice appear in supporting
  72277. Xdocumentation.  This software is provided "as is" without express or
  72278. Ximplied warranty."
  72279. X
  72280. XTRANSLATE=yes|-n|n\
  72281. XTranslate=yes prints the negative image of the fractal.
  72282. XTranslate=n reduces the image to that many colors. A negative value causes
  72283. Xa color reduction as well as a negative image.
  72284. X
  72285. XHALFTONE=frq/ang/sty[/f/a/s/f/a/s/f/a/s]\
  72286. XTells the PostScript printer how to define its halftone screen. The first
  72287. Xvalue, frequency, defines the number of halftone lines per inch. The
  72288. Xsecond chooses the angle (in degrees) that the screen lies at. The third
  72289. Xoption chooses the halftone 'spot' style. Good default frequencies are
  72290. Xbetween 60 and 80; Good default angles are 45 and 0; the default style is
  72291. X0. If the halftone= option is not specified, Fractint will print using the
  72292. Xprinter's default halftone screen, which should have been already set to
  72293. Xdo a fine job on the printer.
  72294. X
  72295. XThese are the only three used when colorps=no. When color PS printing is
  72296. Xbeing used, the other nine options specify the red, green, then blue
  72297. Xscreens. A negative number in any of these places will cause it to use
  72298. Xthe previous (or default) value for that parameter. NOTE: Especially when
  72299. Xusing color, the built-in screens in the printer's ROM may be the best
  72300. Xchoice for printing.
  72301. X~OnlineFF
  72302. XThe default values are as follows: halftone=45/45/1/45/75/1/45/15/1/45/0/1
  72303. Xand these will be used if Fractint's halftone is chosen over the printer's
  72304. Xbuilt-in screen.
  72305. X~Format-
  72306. X
  72307. XCurrent halftone styles:
  72308. X    0 Dot
  72309. X    1 Dot (Smoother)
  72310. X    2 Dot (Inverted)
  72311. X    3 Ring (Black)
  72312. X    4 Ring (White)
  72313. X    5 Triangle (Right)
  72314. X    6 Triangle (Isosceles)
  72315. X    7 Grid
  72316. X    8 Diamond
  72317. X    9 Line
  72318. X   10 Microwaves
  72319. X   11 Ellipse
  72320. X   12 Rounded Box
  72321. X   13 Custom
  72322. X   14 Star
  72323. X   15 Random
  72324. X   16 Line (slightly different)
  72325. X~Format+
  72326. X~OnlineFF
  72327. X
  72328. XA note on device-resolution black and white printing\
  72329. X----------------------------------------------------\
  72330. X
  72331. XThis mode of printing can now be done much more quickly, and takes a
  72332. Xlot less file space. Just set EPSF=0 PRINTER=PSx/nnn COLORPS=NO
  72333. XRLEPS=YES TRANSLATE=m, where x is P or L for portrait/landscape, nnn is
  72334. Xyour printer's resolution, m is 2 or -2 for positive or negative
  72335. Xprinting respectively. This combination of parameters will print
  72336. Xexactly one printer pixel per each image pixel and it will keep the
  72337. Xproportions of the picture, if both your screen and printer have
  72338. Xsquare pixels (or the same pixel-aspect). Choose a proper (read large)
  72339. Xwindow size to fill as much of the paper as possible for the most
  72340. Xspectacular results.  2048 by 2048 is barely enough to fill the width
  72341. Xof a letter size page with 300 dpi printer resolution.  For higher
  72342. Xresolution printers, you will wish fractint supported larger window
  72343. Xsizes (hint, hint...). Bug reports and/or suggestions should be
  72344. Xforwarded to Yavuz Onder (post to sci.fractals, no e-mail yet).
  72345. X~OnlineFF
  72346. X
  72347. XA word from the author (Scott Taylor)\
  72348. X-------------------------------------\
  72349. X
  72350. XColor PostScript printing is new to me. I don't even have a color printer to
  72351. Xtest it on. (Don't want money. Want a Color PostScript printer!) The initial
  72352. Xtests seem to have worked. I am still testing and don't know whether or not
  72353. Xsome sort of gamma correction will be needed. I'll have to wait and see about
  72354. Xthat one.
  72355. X;
  72356. X;
  72357. X~Topic=PaintJet Parameters
  72358. XNote that the pixels printed by the PaintJet are square.
  72359. XThus, a printout of an image
  72360. Xcreated in a video mode with a 4:3 pixel ratio (such as 640x480 or
  72361. X800x600) will come out matching the screen; other modes (such as 320x200)
  72362. Xwill come out stretched.
  72363. X
  72364. XBlack and white images, or images using the 8 high resolution PaintJet
  72365. Xcolors, come out very nicely.  Some images using the full spectrum of
  72366. XPaintJet colors are very nice, some are disappointing.
  72367. X
  72368. XWhen 180 dots per inch is selected (in PRINTER= command), high resolution
  72369. X8 color printing is done.  When 90 dpi is selected, low resolution
  72370. Xprinting using the full 330 dithered color palette is done.  In both
  72371. Xcases, Fractint starts by finding the nearest color supported by the
  72372. XPaintJet for each color in your image.    The translation is then
  72373. Xdisplayed (unless the current display mode is disk video).  This display
  72374. X*should* be a fairly good match to what will be printed
  72375. X- it won't be perfect most of the time but should give some idea
  72376. Xof how the output will look.  At this point you can <Enter> to go ahead
  72377. Xand print, <Esc> to cancel, or <k> to cancel and keep the
  72378. Xadjusted colors.
  72379. X
  72380. XNote that you can use the color map PAINTJET.MAP to create images which
  72381. Xuse the 8 high resolution colors available on the PaintJet.  Also, two
  72382. Xhigh-resolution disk video modes are available for creating full page
  72383. Ximages.
  72384. X
  72385. XIf you find that the preview image seems very wrong (doesn't match what
  72386. Xactually gets printed) or think that Fractint could be doing a better job
  72387. Xof picking PaintJet colors to match your image's colors, you can try
  72388. Xplaying with the following parameter.  Fair warning: this is a very
  72389. Xtricky business and you may find it a very frustrating business trying to
  72390. Xget it right.
  72391. X
  72392. XHALFTONE=r/g/b\
  72393. X(The parameter name is not appropriate - we appropriated a PostScript
  72394. Xparameter for double duty here.)\
  72395. XThis separately sets the "gamma" adjustment for each of the red, green,
  72396. Xand blue color components.  Think of "gamma" as being
  72397. Xlike the contrast adjustment on your screen.  Higher gamma values for all
  72398. Xthree components results in colors with more contrast being produced
  72399. Xon the printer.  Since each color component can have its gamma separately
  72400. Xadjusted, you can change the resulting color mix subtly (or drastically!)\
  72401. XEach gamma value entered has one implied decimal digit.\
  72402. XThe default is "halftone=21/19/16", for red 2.1, green 1.9, and blue 1.6.
  72403. X(A note from Pieter Branderhorst: I wrote this stuff to come out reasonably
  72404. Xon my monitor/printer.    I'm a bit suspicious of the guns on my monitor;
  72405. Xif the colors seem ridiculously wrong on your system you might start by
  72406. Xtrying halftone=17/17/17.)
  72407. X;
  72408. X;
  72409. X~Topic=Plotter Parameters
  72410. X
  72411. XPlotters which understand HP-GL commands are supported. To use a plotter,
  72412. Xdraw a SMALL image (32x20 or 64x40) using the <v>iew screen options.  Put
  72413. Xa red pen in the first holder in the plotter, green in the second, blue in
  72414. Xthe third.  Now press <P> to start plotting.  Now get a cup of coffee...
  72415. Xor two... or three.  It'll take a while to plot.  Experiment with
  72416. Xdifferent resolutions, plot areas, plotstyles, and even change pens to
  72417. Xcreate weird-colored images.
  72418. X
  72419. XPLOTSTYLE=0|1|2\
  72420. X0: 3 parallel lines (red/green/blue) are drawn for each pixel, arranged
  72421. X  like "///".  Each bar is scaled according to the intensity of the
  72422. X  corresponding color in the pixel.  Using different pen colors (e.g.
  72423. X  blue, green, violet) can come out nicely.  The trick is to not tell
  72424. X  anyone what color the bars are supposed to represent and they will
  72425. X  accept these plotted colors because they do look nice...
  72426. X1: Same as 0, but the lines are also twisted.  This removes some of the
  72427. X  'order' of the image which is a nice effect.  It also leaves more
  72428. X  whitespace making the image much lighter, but colors such as yellow are
  72429. X  actually visible.
  72430. X2: Color lines are at the same angle and overlap each other.  This type
  72431. X  has the most whitespace.  Quality improves as you increase the number of
  72432. X  pixels squeezed into the same size on the plotter.
  72433. X;
  72434. X;
  72435. X~Topic=3D Parameters
  72436. X
  72437. XTo stay out of trouble, specify all the 3D parameters, even if you want to
  72438. Xuse what you think are the default values. It takes a little practice to
  72439. Xlearn what the default values really are. The best way to create a set of
  72440. Xparameters is to use the <B> command on an image you like and then use an
  72441. Xeditor to modify the resulting parameter file.
  72442. X
  72443. X3D=Yes\
  72444. X3D=Overlay\
  72445. XResets all 3d parameters to default values. If FILENAME= is given, forces
  72446. Xa restore to be performed in 3D mode (handy when used with 'batch=yes' for 
  72447. Xbatch-mode 3D images). If specified, 3D=Yes should come before any other 
  72448. X3d parameters on the command line or in a parameter file entry. The form
  72449. X3D=Overlay is identical except that the previous graphics screen is not
  72450. Xcleared, as with the <#> (<shift-3> on some keyboards) overlay command. 
  72451. XUseful for building parameter files that use the 3D overlay feature.\
  72452. X
  72453. XThe options below override the 3D defaults:
  72454. X~Format-
  72455. XPREVIEW=yes           Turns on 3D 'preview' default mode
  72456. XSHOWBOX=yes           Turns on 3D 'showbox' default mode
  72457. XCOARSE=nn           Sets Preview 'coarseness' default value
  72458. XSPHERE=yes           Turns on spherical projection mode
  72459. XSTEREO=n           Selects the type of stereo image creation
  72460. XRAY=nnn            selects raytrace output file format
  72461. XBRIEF=yes           selects brief or verbose file for DKB output
  72462. X
  72463. XINTEROCULAR=nn           Sets the interocular distance for stereo
  72464. XCONVERGE=nn           Determines the overall image separation
  72465. XCROP=nn/nn/nn/nn       Trims the edges off stereo pairs
  72466. XBRIGHT=nn/nn           Compensates funny glasses filter parameters
  72467. XLONGITUDE=nn/nn        Longitude minimum and maximum
  72468. XLATITUDE=nn/nn           Latitude minimum and maximum
  72469. XRADIUS=nn           Radius scale factor
  72470. XROTATION=nn[/nn[/nn]]       Rotation about x,y, and z axes
  72471. XSCALEZYZ=nn/nn/nn       X,y,and z scale factors
  72472. XROUGHNESS=nn           Same as z scale factor
  72473. XWATERLINE=nn           Colors nn and below will be "inside" color
  72474. XFILLTYPE=nn           3D filltype
  72475. XPERSPECTIVE=nn           Perspective distance
  72476. XXYSHIFT=nn/nn           Shift image in x and y directions with
  72477. X                perspective
  72478. XLIGHTSOURCE=nn/nn/nn       Coordinates for light-source vector
  72479. XSMOOTHING=nn           Smooths images in light-source fill modes
  72480. XTRANSPARENT=min/max       Defines a range of colors to be treated as
  72481. X                "transparent" when <#>Overlaying 3D images.
  72482. XXYADJUST=nn/nn           This shifts the image in the x/y dir without
  72483. X                perspective
  72484. X~Format+
  72485. X
  72486. XBelow are new commands as of version 14 that support Marc Reinig's terrain
  72487. Xfeatures.
  72488. X
  72489. XRANDOMIZE=nnn (0 - 100)\
  72490. XThis feature randomly varies the color of a pixel to near by colors.
  72491. XUseful to minimize map banding in 3d transformations. Usable with all
  72492. XFILLTYPES. 0 disables, max values is 7. Try 3 - 5.
  72493. X
  72494. XAMBIENT=nnn (0 - 100)\
  72495. XSet the depth of the shadows when using full color and light source
  72496. Xfilltypes. "0" disables the function, higher values lower the contrast.
  72497. X
  72498. XFULLCOLOR=yes\
  72499. XValid with any light source FILLTYPE. Allows you to create a Targa-24 file
  72500. Xwhich uses the color of the image being transformed or the map you select
  72501. Xand shades it as you would see it in real life. Well, its better than B&W.
  72502. XA good map file to use is topo
  72503. X
  72504. XHAZE=nnn (0 - 100)\
  72505. XGives more realistic terrains by setting the amount of haze for distant
  72506. Xobjects when using full color in light source FILLTYPES. Works only in the
  72507. X"y" direction currently, so don't use it with much y rotation. Try
  72508. X"rotation=85/0/0". 0 disables.
  72509. X
  72510. XLIGHTNAME=<filename>\
  72511. XThe name of the Targa-24 file to be created when using full color with
  72512. Xlight source. Default is light001.tga. If overwrite=no (the default), the
  72513. Xfile name will be incremented until an unused filename is found.
  72514. XBackground in this file will be sky blue.
  72515. X;
  72516. X;
  72517. X;
  72518. X~Topic=Batch Mode
  72519. X
  72520. XIt IS possible, believe it or not, to become so jaded with the screen
  72521. Xdrawing process, so familiar with the types and options, that you just
  72522. Xwant to hit a key and do something else until the final images are safe on
  72523. Xdisk.  To do this, start Fractint with the BATCH=yes parameter.  To set up
  72524. Xa batch run with the parameters required for a particular image you might:
  72525. X  o Find an interesting area.  Note the parameters from the <Tab> display.
  72526. X    Then use an editor to write a batch file.
  72527. X  o Find an interesting area.  Set all the options you'll want in the
  72528. X    batch run.    Use the <B> command to store the parameters in a file.
  72529. X    Then use an editor to add the additional required batch mode
  72530. X    parameters (such as VIDEO=) to the generated parameter file entry.
  72531. X    Then run the batch using "fractint @myname.par/myentry" (if you told
  72532. X    the <B> command to use file "myname" and to name the entry "myentry").
  72533. X
  72534. XAnother approach to batch mode calculations, using "FILENAME=" and resume,
  72535. Xis described later.
  72536. X
  72537. XWhen modifying a parameter file entry generated by the <B> command, the
  72538. Xonly parameters you must add for a batch mode run are "BATCH=yes", and
  72539. X"VIDEO=xxx" to select a video mode.  You might want to also add
  72540. X"SAVENAME=[name]" to name the result as something other than the default
  72541. XFRACT001.GIF.  Or, you might find it easier to leave the generated
  72542. Xparameter file unchanged and add these parameters by using a command like:
  72543. X   fractint @myname.par/myentry batch=y video=AF3 savename=mygif
  72544. X
  72545. X"BATCH=yes" tells Fractint to run in batch mode -- that is, Fractint draws
  72546. Xthe image using whatever other parameters you specified, then acts as if
  72547. Xyou had hit <S> to save the image, then exits to DOS.
  72548. X
  72549. X"FILENAME=" can be used with "BATCH=yes" to resume calculation of an
  72550. Xincomplete image.  For instance, you might interactively find an image you
  72551. Xlike; then select some slow options (a high resolution disk video mode,
  72552. Xdistance estimator method, high maxiter, or whatever);    start the
  72553. Xcalculation;  then interrupt immediately with a <S>ave.  Rename the save
  72554. Xfile (fract001.gif if it is the first in the session and you didn't name
  72555. Xit with the <X> options or "savename=") to xxx.gif. Later you can run
  72556. XFractint in batch mode to finish the job:\
  72557. X    fractint batch=yes filename=xxx savename=xxx
  72558. X
  72559. X"SAVETIME=nnn" is useful with long batch calculations, to store a
  72560. Xcheckpoint every nnn minutes.  If you start a many hour calculation with
  72561. Xsay "savetime=60", and a power failure occurs during the calculation,
  72562. Xyou'll have lost at most an hour of work on the image.  You can resume
  72563. Xcalculation from the save file as above.  Automatic saves triggered by
  72564. XSAVETIME do not increment the save file name. The same file is overwritten
  72565. Xby each auto save until the image completes.  But note that Fractint does
  72566. Xnot directly over-write save files.  Instead, each save operation writes a
  72567. Xtemporary file FRACTINT.TMP, then deletes the prior save file, then
  72568. Xrenames FRACTINT.TMP to be the new save file.  This protects against power
  72569. Xfailures which occur during a save operation - if such a power failure
  72570. Xoccurs, the prior save file is intact and there's a harmless incomplete
  72571. XFRACTINT.TMP on your disk.
  72572. X
  72573. XIf you want to spread a many-hour image over multiple bits of free machine
  72574. Xtime you could use a command like:\
  72575. X    fractint batch=yes filename=xxx savename=xxx savetime=60 video=F3\
  72576. XWhile this batch is running, hit <S> (almost any key actually) to tell
  72577. Xfractint to save what it has done so far and give your machine back.  A status
  72578. Xcode of 2 is returned by fractint to the batch file.  Kick off the batch
  72579. Xagain when you have another time slice for it.
  72580. X
  72581. XWhile running a batch file, pressing any key will cause Fractint to exit
  72582. Xwith an errorlevel = 2.  Any error that interrupts an image save to disk
  72583. Xwill cause an exit with errorlevel = 2.  Any error that prevents an image
  72584. Xfrom being generated will cause an exit with errorlevel = 1.
  72585. X
  72586. XThe SAVETIME= parameter, and batch resumes of partial calculations, only
  72587. Xwork with fractal types which can be resumed.  See
  72588. X{"Interrupting and Resuming"} for information about non-resumable types.
  72589. X;
  72590. X;
  72591. X;
  72592. X~Topic=Video Adapter Notes
  72593. X
  72594. XTrue to the spirit of public-domain programming, Fractint makes only a
  72595. Xlimited attempt to verify that your video adapter can run in the mode you
  72596. Xspecify, or even that an adapter is present, before writing to it.
  72597. XSo if you use the "video=" command line parameter, check it before using
  72598. Xa new version of Fractint -
  72599. Xthe old key combo may now call an ultraviolet holographic mode.
  72600. X~Doc-
  72601. X
  72602. XComments about some particular video adapters:\
  72603. X    { EGA }      { Tweaked VGA }   { Super-VGA }\
  72604. X    { 8514/A }      { XGA }\
  72605. X    { Targa }      { Targa+ }\
  72606. X
  72607. XAlso see {Customized Video Modes\, FRACTINT.CFG}.
  72608. X~Doc+
  72609. X;
  72610. X;
  72611. X~Topic=EGA
  72612. X~Format-,Online-
  72613. XEGA
  72614. X~Format+,Online+
  72615. X
  72616. XFractint assumes that every EGA adapter has a full 256K of memory
  72617. X(and can therefore display 640 x 350 x 16 colors), but does nothing to
  72618. Xverify that fact before slinging pixels.
  72619. X;
  72620. X;
  72621. X~Topic=Tweaked VGA
  72622. X~Format-,Online-
  72623. X"TWEAKED" VGA MODES
  72624. X~Format+,Online+
  72625. X
  72626. XThe IBM VGA adapter is a highly programmable device, and can be set up to
  72627. Xdisplay many video-mode combinations beyond those "officially" supported
  72628. Xby the IBM BIOS. E.g. 320x400x256 and 360x480x256 (the latter is one of
  72629. Xour favorites).
  72630. XThese video modes are perfectly legal, but temporarily
  72631. Xreprogram the adapter (IBM or fully register-compatible) in a non-standard
  72632. Xmanner that the BIOS does not recognize.
  72633. X
  72634. XFractint also contains code that sets up the IBM (or any truly register-
  72635. Xcompatible) VGA adapter for several extended modes such as 704x528,
  72636. X736x552, 768x576, and 800x600. It does this by programming the VGA
  72637. Xcontroller to use the fastest dot-clock on the IBM adapter (28.322 MHz),
  72638. Xthrowing more pixels, and reducing the refresh rate to make up for it.
  72639. X
  72640. XThese modes push many monitors beyond their rated specs, in terms of both
  72641. Xresolution and refresh rate. Signs that your monitor is having problems
  72642. Xwith a particular "tweaked" mode include:
  72643. X o vertical or horizontal overscan (displaying dots beyond the edges of
  72644. X   your visible CRT area)
  72645. X o flickering (caused by a too-slow refresh rate)\
  72646. X o vertical roll or total garbage on the screen (your monitor simply
  72647. X   can't keep up, or is attempting to "force" the image into a pre-set
  72648. X   mode that doesn't fit).
  72649. X
  72650. XWe have successfully tested the modes up to 768x576 on an IBM PS/2 Model
  72651. X80 connected to IBM 8513, IBM 8514, NEC Multisync II, and Zenith 1490
  72652. Xmonitors (all of which exhibit some overscan and flicker at the highest
  72653. Xrates), and have tested 800x600 mode on the NEC Multisync II (although it
  72654. Xtook some twiddling of the vertical-size control).
  72655. X;
  72656. X;
  72657. X~Topic=Super-VGA
  72658. X~Format-,Online-
  72659. XSUPER-EGA AND SUPER-VGA MODES
  72660. X~Format+,Online+
  72661. X
  72662. XSince version 12.0, we've used both John Bridges' SuperVGA Autodetecting
  72663. Xlogic *and* VESA adapter detection, so that many brand-specific SuperVGA
  72664. Xmodes have been combined into single video mode selection entries.
  72665. XThere is now exactly one entry for SuperVGA 640x480x256 mode, for instance.
  72666. XIf Fractint's automatic SuperVGA/VESA detection logic guesses wrong,
  72667. Xand you know which SuperVGA chipset your video adapter uses, you can use
  72668. Xthe "adapter=" command-line option to force Fractint to assume the presence
  72669. Xof a specific SuperVGA Chipset - see {Video Parameters} for details.
  72670. X;
  72671. X;
  72672. X~Topic=8514/A
  72673. X~Format-,Online-
  72674. X8514/A MODES
  72675. X~Format+,Online+
  72676. X
  72677. XThe IBM 8514/A modes (640x480 and 1024x768) default to using the hardware
  72678. Xregisters.  If an error occurs when trying to open the adapter, an attempt
  72679. Xwill be made to use IBM's software interface, and requires the preloading
  72680. Xof IBM's HDILOAD TSR utility.
  72681. X
  72682. XThe Adex 1280x1024 modes were written for and tested on an Adex
  72683. XCorporation 8514/A using a Brooktree DAC.  The ATI GU 800x600x256 and
  72684. X1280x1024x16 modes require a ROM bios version of 1.3 or higher for 800x600
  72685. Xand 1.4 or higher for 1280x1024.
  72686. X
  72687. XThere are two sets of 8514/A modes: full sets (640x480, 800x600, 1024x768,
  72688. X1280x1024) which cover the entire screen and do NOT have a border color
  72689. X(so that you cannot tell when you are "paused" in a color-cycling mode),
  72690. Xand partial sets (632x474, 792x594, 1016x762, 1272x1018) with small border
  72691. Xareas which do turn white when you are paused in color-cycling mode. Also,
  72692. Xwhile these modes are declared to be 256-color, if you do not have your
  72693. X8514/A adapter loaded with its full complement of memory you will actually
  72694. Xbe in 16-color mode. The hardware register 16-color modes have not been
  72695. Xtested.
  72696. X
  72697. XIf your 8514/A adapter is not truly register compatible and Fractint does
  72698. Xnot detect this, use of the adapter interface can be forced by using afi=y
  72699. Xor afi=8514 in your SSTOOLS.INI file.
  72700. X
  72701. XFinally, because IBM's adapter interface does not handle drawing single
  72702. Xpixels very well (we have to draw a 1x1 pixel "box"), generating the zoom
  72703. Xbox when using the interface is excruciatingly slow. Still, it works!
  72704. X;
  72705. X;
  72706. X~Topic=XGA
  72707. X~Format-,Online-
  72708. XXGA MODES
  72709. X~Format+,Online+
  72710. X
  72711. XThe XGA adapter is supported using the VESA/SuperVGA Autodetect modes -
  72712. Xthe XGA looks like just another SuperVGA adapter to Fractint.
  72713. XThe supported XGA modes are 640x480x256, 1024x768x16, 1024x768x256,
  72714. X800x600x16, and 800x600x256.  Note that the 1024x768x256 mode requires
  72715. Xa full 1MB of adapter memory, the 1024x768 modes require a high-rez
  72716. Xmonitor, and the 800x600 modes require a multisynching monitor such
  72717. Xas the NEC 2A.
  72718. X;
  72719. X;
  72720. X~Topic=Targa
  72721. X~Format-,Online-
  72722. XTARGA MODES
  72723. X~Format+,Online+
  72724. X
  72725. XTARGA support for Fractint is provided courtesy of Joe McLain and has been
  72726. Xenhanced with the help of Bruce Goren and Richard Biddle.  To use a TARGA
  72727. Xboard with Fractint, you must define two DOS environment variables,
  72728. X"TARGA" and "TARGASET".  The definition of these variables is standardized
  72729. Xby Truevision; if you have a TARGA board you probably already have added
  72730. X"SET" statements for these variables to your AUTOEXEC.BAT file.
  72731. XBe aware that there are a LOT of possible TARGA configurations, and a LOT
  72732. Xof opportunities for a TARGA board and a VGA or EGA board to interfere
  72733. Xwith each other, and we may not have all of them smoothed away yet.  Also,
  72734. Xthe TARGA boards have an entirely different color-map scheme than the VGA
  72735. Xcards, and at the moment they cannot be run through the color-cycling
  72736. Xmenu. The "MAP=" argument (see {Color Parameters}),
  72737. Xhowever, works with both TARGA and
  72738. XVGA boards and enables you to redefine the default color maps with either
  72739. Xboard.
  72740. X;
  72741. X;
  72742. X~Topic=Targa+
  72743. X~Format-,Online-
  72744. XTARGA+ MODES
  72745. X~Format+,Online+
  72746. X
  72747. XTo use the special modes supported for TARGA+ adapters, the TARGAP.SYS
  72748. Xdevice driver has to be loaded, and the TPLUS.DAT file (included with
  72749. XFractint) must be in the same directory as Fractint.  The video modes with
  72750. Xnames containing "True Color Autodetect" can be used with the Targa+.  You
  72751. Xmight want to use the command line parameters "tplus=", "noninterlaced=",
  72752. X"maxcolorres=", and "pixelzoom=" (see {Video Parameters})
  72753. Xin your SSTOOLS.INI file to modify Fractint's use of the adapter.
  72754. X;
  72755. X;
  72756. X~Topic="Disk-Video" Modes
  72757. X
  72758. XThese "video modes" do not involve a video adapter at all. They use (in
  72759. Xorder or preference) your expanded memory, your extended memory, or your
  72760. Xdisk drive (as file FRACTINT.$$$) to store the fractal image. These modes
  72761. Xare useful for creating images beyond the capacity of your video adapter
  72762. Xright up to the current internal limit of 2048 x 2048 x 256,
  72763. Xe.g. for subsequent printing.
  72764. XThey're also useful for
  72765. Xbackground processing under multi-tasking DOS managers - create an image
  72766. Xin a disk-video mode, save it, then restore it in a real video mode.
  72767. X
  72768. XWhile you are using a disk-video mode, your screen will display text
  72769. Xinformation indicating whether memory or your disk drive is being used,
  72770. Xand what portion of the "screen" is being read from or written to.  A
  72771. X"Cache size" figure is also displayed. 64K is the maximum cache size.  If
  72772. Xyou see a number less than this, it means that you don't have a lot of
  72773. Xmemory free, and that performance will be less than optimum.  With a very
  72774. Xlow cache size such as 4 or 6k, performance gets considerably worse in
  72775. Xcases using solid guessing, boundary tracing, plasma, or anything else
  72776. Xwhich paints the screen non-linearly.  If you have this problem, all we
  72777. Xcan suggest is having fewer TSR utilities loaded before starting Fractint,
  72778. Xor changing in your config.sys file, such as reducing a very high BUFFERS
  72779. Xvalue.
  72780. X
  72781. XThe zoom box is disabled during disk-video modes (you couldn't see where
  72782. Xit is anyway).    So is the orbit display feature.
  72783. X
  72784. X{=@ColorCycling Color Cycling} can be used during disk-video modes,
  72785. Xbut only to load or save a color palette.
  72786. X
  72787. XWhen using real disk for your disk-video, Fractint will not generate some
  72788. X"attractor" types (e.g. lorenz) nor "IFS" images.  These would kill your
  72789. Xdisk drive.  Boundary tracing is allowed - it may give your drive a bit of
  72790. Xa workout, but is generally tolerable.
  72791. X
  72792. XWhen using a real disk, and you are not directing the file to a RAM disk,
  72793. Xand you aren't using a disk caching program on your machine, specifying
  72794. XBUFFERS=10 (or more) in your config.sys file is best for performance.
  72795. XBUFFERS=10,2 or even BUFFERS=10,4 is also good.  It is also best to keep
  72796. Xyour disk relatively "compressed" (or "defragmented") if you have a
  72797. Xutility to do this.
  72798. X
  72799. XIn order to use extended memory, you must have HIMEM.SYS or an equivalent
  72800. Xthat supports the XMS 2.0 standard or higher.  Also, you can't have a
  72801. XVDISK installed in extended memory.  Himem.sys is distributed with
  72802. XMicrosoft Windows 286/386 and 3.0.  If you have problems using the
  72803. Xextended memory, try rebooting with just himem.sys loaded and see if that
  72804. Xclears up the problem.
  72805. X
  72806. XIf you are running background disk-video fractals under Windows 3, and you
  72807. Xdon't have a lot of real memory (over 2Mb), you might find it best to
  72808. Xforce Fractint to use real disk for disk-video modes.  (Force this by
  72809. Xusing a .pif file with extended memory and expanded memory set to zero.)
  72810. XTry this if your disk goes crazy when generating background images, which
  72811. Xare supposedly using extended or expanded memory.  This problem can occur
  72812. Xbecause, to multi-task, sometimes Windows must page an application's
  72813. Xexpanded or extended memory to disk, in big chunks. Fractint's own cached
  72814. Xdisk access may be faster in such cases.
  72815. X;
  72816. X;
  72817. X;
  72818. X~Topic=Customized Video Modes\, FRACTINT.CFG
  72819. X
  72820. XIf you have a favorite adapter/video mode that you would like to add to
  72821. XFractint... if you want some new sizes of disk-video modes... if you want
  72822. Xto remove table entries that do not apply to your system... if you want to
  72823. Xspecify different "textsafe=" options for different video modes... relief
  72824. Xis here, and without even learning "C"!
  72825. X
  72826. XYou can do these things by modifying the FRACTINT.CFG file with your text
  72827. Xeditor. Saving a backup copy of FRACTINT.CFG first is of course highly
  72828. Xrecommended!
  72829. X
  72830. XFractint uses a video adapter table for most of what it needs to know
  72831. Xabout any particular adapter/mode combination. The table is loaded from
  72832. XFRACTINT.CFG each time Fractint is run. It can contain information for
  72833. Xup to 300 adapter/mode combinations. The table entries, and the function
  72834. Xkeys they are tied to, are displayed in the "select video mode" screen.
  72835. X
  72836. XThis table makes adding support for various third-party video cards and
  72837. Xtheir modes much easier, at least for the ones that pretend to be
  72838. Xstandard with extra dots and/or colors. There is even a special
  72839. X"roll-your-own" video mode (mode 19) enabling those of you with "C"
  72840. Xcompilers and a copy of the Fractint source to generate video modes
  72841. Xsupporting whatever adapter you may have.
  72842. X
  72843. XThe table as currently distributed begins with nine standard and several
  72844. Xnon-standard IBM video modes that have been exercised successfully with a
  72845. XPS/2 model 80. These entries, coupled with the descriptive comments in the
  72846. Xtable definition and the information supplied (or that should have been
  72847. Xsupplied!) with your video adapter, should be all you need to add your own
  72848. Xentries.
  72849. X
  72850. XAfter the IBM and quasi-pseudo-demi-IBM modes, the table contains an ever-
  72851. Xincreasing number of entries for other adapters. Almost all of these
  72852. Xentries have been added because someone like you sent us spec sheets, or
  72853. Xmodified Fractint to support them and then informed us about it.
  72854. X
  72855. XLines in FRACTINT.CFG which begin with a semi-colon are treated as comments.
  72856. XThe rest of the lines must have eleven fields separated by commas.
  72857. XThe fields are defined as:
  72858. X
  72859. X~Format-
  72860. X1. Key assignment. F2 to F10, SF1 to SF10, CF1 to CF10, or AF1 to AF10.
  72861. X   Blank if no key is assigned to the mode.
  72862. X2. The name of the adapter/video mode (25 chars max, no leading blanks).
  72863. X   The adapter is set up for that mode via INT 10H, with:
  72864. X3. AX = this,
  72865. X4. BX = this,
  72866. X5. CX = this, and
  72867. X6. DX = this (hey, having all these registers wasn't OUR idea!)
  72868. X7. An encoded value describing how to write to your video memory in that
  72869. X   mode. Currently available codes are:
  72870. X  1) Use the BIOS (INT 10H, AH=12/13, AL=color) (last resort - SLOW!)
  72871. X  2) Pretend it's a (perhaps super-res) EGA/VGA
  72872. X  3) Pretend it's an MCGA
  72873. X  4) SuperVGA 256-Color mode using the Tseng Labs chipset
  72874. X  5) SuperVGA 256-Color mode using the Paradise chipset
  72875. X  6) SuperVGA 256-Color mode using the Video-7 chipset
  72876. X  7) Non-Standard IBM VGA 360 x 480 x 256-Color mode
  72877. X  8) SuperVGA 1024x768x16 mode for the Everex chipset
  72878. X  9) TARGA video modes
  72879. X 10) HERCULES video mode
  72880. X 11) Non-Video, i.e. "disk-video"
  72881. X 12) 8514/A video modes
  72882. X 13) CGA 320x200x4-color and 640x200x2-color modes
  72883. X 14) Reserved for Tandy 1000 video modes
  72884. X 15) SuperVGA 256-Color mode using the Trident chipset
  72885. X 16) SuperVGA 256-Color mode using the Chips & Tech chipset
  72886. X 17) SuperVGA 256-Color mode using the ATI VGA Wonder chipset
  72887. X 18) SuperVGA 256-Color mode using the EVEREX chipset
  72888. X 19) Roll-your-own video mode (as you've defined it in YOURVID.C)
  72889. X 20) SuperVGA 1024x768x16 mode for the ATI VGA Wonder chipset
  72890. X 21) SuperVGA 1024x768x16 mode for the Tseng Labs chipset
  72891. X 22) SuperVGA 1024x768x16 mode for the Trident chipset
  72892. X 23) SuperVGA 1024x768x16 mode for the Video 7 chipset
  72893. X 24) SuperVGA 1024x768x16 mode for the Paradise chipset
  72894. X 25) SuperVGA 1024x768x16 mode for the Chips & Tech chipset
  72895. X 26) SuperVGA 1024x768x16 mode for the Everex Chipset
  72896. X 27) SuperVGA Auto-Detect mode (we poke around looking for your adapter)
  72897. X 28) VESA modes
  72898. X 29) True Color Auto-Detect (currently only Targa+ supported)
  72899. XAdd 100, 200, 300, or 400 to this code to specify an over-ride "textsafe="
  72900. X option to be used with the mode.  100=yes, 200=no, 300=bios, 400=save.
  72901. X E.g. 428 for a VESA mode with textsafe=save forced.
  72902. X8. The number of pixels across the screen (X - 160 to 2048)
  72903. X9. The number of pixels down the screen (Y - 160 to 2048)
  72904. X10. The number of available colors (2, 4, 16, or 256)
  72905. X11. A comment describing the mode (25 chars max, leading blanks are OK)
  72906. X~Format+
  72907. X
  72908. XNOTE that the AX, BX, CX, and DX fields use hexadecimal notation (fifteen
  72909. X==> 'f', sixteen ==> '10'), because that's the way most adapter
  72910. Xdocumentation describes it. The other fields use standard decimal
  72911. Xnotation.
  72912. X
  72913. XIf you look closely at the default entries, you will notice that the IBM
  72914. XVGA entries labeled "tweaked" and "non standard" have entries in the table
  72915. Xwith AX = BX = CX = 0, and DX = some other number. Those are special flags
  72916. Xthat we used to tell the program to custom-program the VGA adapter, and
  72917. Xare NOT undocumented BIOS calls. Maybe they should be, but they aren't.
  72918. X
  72919. XIf you have a fancy adapter and a new video mode that works on it, and it
  72920. Xis not currently supported, PLEASE GET THAT INFORMATION TO US!    We will
  72921. Xadd the video mode to the list on our next release, and give you credit
  72922. Xfor it. Which brings up another point: If you can confirm that a
  72923. Xparticular video adapter/mode works (or that it doesn't), and the program
  72924. Xsays it is UNTESTED, please get that information to us also.  Thanks in
  72925. Xadvance!
  72926. X;
  72927. X;
  72928. X;
  72929. SHAR_EOF
  72930. $TOUCH -am 1028230193 help4.src &&
  72931. chmod 0644 help4.src ||
  72932. echo "restore of help4.src failed"
  72933. set `wc -c help4.src`;Wc_c=$1
  72934. if test "$Wc_c" != "79101"; then
  72935.     echo original size 79101, current size $Wc_c
  72936. fi
  72937. # ============= help5.src ==============
  72938. echo "x - extracting help5.src (Text)"
  72939. sed 's/^X//' << 'SHAR_EOF' > help5.src &&
  72940. X~Topic=Common Problems
  72941. X
  72942. XOf course, Fractint would never stoop to having a "common" problem.  These
  72943. Xnotes describe some, ahem, "special situations" which come up occasionally
  72944. Xand which even we haven't the gall to label as "features".
  72945. X
  72946. XHang during startup:\
  72947. X  There might be a problem with Fractint's video detection logic and your
  72948. X  particular video adapter. Try running with "fractint adapter=xxx" where
  72949. X  xxx is cga, ega, egamono, mcga, or vga.  If "adapter=vga" works, and you
  72950. X  really have a SuperVGA adapter capable of higher video modes, there are
  72951. X  other "adapter=" options for a number of SuperVGA chipsets - please see
  72952. X  the full selection in {Video Parameters} for details.  If this solves the
  72953. X  problem, create an SSTOOLS.INI file with the "adapter=xxx" command in it
  72954. X  so that the fix will apply to every run.\
  72955. X  Another possible cause:  If you install the latest Fractint in say
  72956. X  directory "newfrac", then run it from another directory with the command
  72957. X  "\\newfrac\\fractint", *and* you have an older version of fractint.exe
  72958. X  somewhere in your DOS PATH, a silent hang is all you'll get.  See the
  72959. X  notes under the "Cannot find FRACTINT.EXE message" problem for the reason.\
  72960. X  Another possibility: try one of the "textsafe" parameter choices
  72961. X  described in {Video Parameters}.
  72962. X
  72963. XScrambled image when returning from a text mode display:\
  72964. X  If an image which has been partly or completely generated gets partly
  72965. X  destroyed when you return to it from the menu, help, or the information
  72966. X  display, please try the various "textsafe" parameter options - see
  72967. X  {Video Parameters} for details.  If this cures the problem, create
  72968. X  an SSTOOLS.INI file with the "textsafe=xxx" command so that the fix will
  72969. X  apply to every run.
  72970. X
  72971. X"Holes" in an image while it is being drawn:\
  72972. X  Little squares colored in your "inside" color, in a pattern of every
  72973. X  second square of that size, in solid guessing mode, both across and down
  72974. X  (i.e., 1 out of 4), are
  72975. X  a symptom of an image which should be calculated with more conservative
  72976. X  periodicity checking than the default.  See the Periodicity parameter
  72977. X  under {Image Calculation Parameters}.
  72978. X
  72979. XBlack bar at top of screen during color cycling on 8086/8088 machines:\
  72980. X  (This might happen intermittently, not every run.)\
  72981. X  "fractint cyclelimit=10" might cure the problem.  If so, increase
  72982. X  the cyclelimit value (try increasing by 5 or 10 each time) until the
  72983. X  problem reappears, then back off one step and add that cyclelimit value
  72984. X  to your SSTOOLS.INI file.
  72985. X
  72986. XOther video problems:
  72987. X
  72988. X  If you are using a VESA driver with your video adapter, the first thing
  72989. X  to try is the "vesadetect=no" parameter. If that fixes the problem, add
  72990. X  it to your SSTOOLS.INI file to make the fix permanent.
  72991. X
  72992. X  It may help to explicitly specify your type of adapter - see the
  72993. X  "adapter=" parameter in {Video Parameters}.
  72994. X
  72995. X  We've had one case where a video driver for Windows does not work
  72996. X  properly with Fractint.  If running under Windows, DesqView, or some
  72997. X  other layered environment, try running Fractint directly from DOS to see
  72998. X  if that avoids the problem.\
  72999. X  We've also had one case of a problem co-existing with "386 to the Max".
  73000. X
  73001. X  We've had one report of an EGA adapter which got scrambled images in
  73002. X  all modes until "textsafe=no" was used (see {Video Parameters}).
  73003. X
  73004. X  Also, see {Video Adapter Notes} for information
  73005. X  about enhanced video modes - Fractint makes only limited attempts to
  73006. X  verify that a video mode you request is actually supported by your
  73007. X  adapter.
  73008. X~OnlineFF
  73009. X
  73010. XOther Hangs and Strange Behavior:\
  73011. X  We've had some problems (hangs and solid beeps) on an FPU equipped
  73012. X  machine when running under Windows 3's enhanced mode.  The only ways
  73013. X  around the problem we can find are to either run the Fractint image
  73014. X  involved outside Windows, or to use the DOS command "SET NO87=nofpu"
  73015. X  before running Fractint.  (This SET command makes Fractint ignore your
  73016. X  fpu, so things might be a lot slower as a result.)
  73017. X
  73018. XInsufficient memory:\
  73019. X  Fractint requires a fair bit of memory to run.  Most machines with at
  73020. X  least 640k (ok sticklers, make that "PC-compatible machines") will have
  73021. X  no problem.  Machines with 512k and machines with many TSR utilities
  73022. X  and/or a LAN interface may have problems.  Some Fractint features
  73023. X  allocate memory when required during a run.  If you get a message about
  73024. X  insufficient memory, or suspect that some problem is due to a memory
  73025. X  shortage, you could try commenting out some TSR utilities in your
  73026. X  AUTOEXEC.BAT file, some non-critical drivers in your CONFIG.SYS file, or
  73027. X  reducing the BUFFERS parameter in your CONFIG.SYS.
  73028. X~OnlineFF
  73029. X
  73030. X"Cannot find FRACTINT.EXE" message:\
  73031. X  Fractint is an overlayed program - some parts of it are brought from
  73032. X  disk into memory only when used.  The overlay manager needs to know
  73033. X  where to find the program.  It must be named FRACTINT.EXE (which it is
  73034. X  unless somebody renamed it), and you should either be in the directory
  73035. X  containing it when you start Fractint, or that directory should be in
  73036. X  your DOS PATH.
  73037. X
  73038. X"File FRACTINT.CFG is missing or invalid" message:\
  73039. X  You should either start Fractint while you are in the directory
  73040. X  containing it, or should have that directory in your DOS PATH variable.
  73041. X  If that isn't the problem, maybe you have a FRACTINT.CFG file from an
  73042. X  older release of Fractint lying around? If so, best rename or delete it.
  73043. X  If that isn't the problem either, then the FRACTINT.CFG included in the
  73044. X  FRAINT.EXE release file has probably been changed or deleted. Best
  73045. X  reinstall Fractint to get a fresh copy.
  73046. X~OnlineFF
  73047. X
  73048. XSome other program doesn't like GIF files created by Fractint:\
  73049. X  Fractint generates nice clean GIF89A spec files, honest! But telling
  73050. X  this to the other program isn't likely to change its mind. Instead, try
  73051. X  an option which might get around the problem: run Fractint with the
  73052. X  command line option "gif87a=yes" and then save an image. Fractint will
  73053. X  store the image in the older GIF87A format, without any fractal
  73054. X  parameters in it (so you won't be able to load the image back into
  73055. X  Fractint and zoom into it - the fractal type, coordinates, etc. are not
  73056. X  stored in this older format), and without an "aspect ratio" in the GIF
  73057. X  header (we've seen one utility which doesn't like that field.)
  73058. X
  73059. XDisk video mode performance:\
  73060. X  This won't be blindingly fast at the best of times, but there are things
  73061. X  which can slow it down and can be tuned.  See {"Disk-Video" Modes}
  73062. X  for details.
  73063. X;
  73064. X;
  73065. X;
  73066. X~Topic=Fractals and the PC
  73067. X;
  73068. X; empty for document, present just so we can reference the subject
  73069. X
  73070. X~Format-,Doc-
  73071. X
  73072. X    A Little History:
  73073. X       { Before Mandelbrot }
  73074. X       { Who Is This Guy, Anyway? }
  73075. X
  73076. X    A Little Code:
  73077. X       { Periodicity Logic }
  73078. X       { Limitations of Integer Math (And How We Cope) }
  73079. X       { The Fractint "Fractal Engine" Architecture }
  73080. X
  73081. X    A Little Math:
  73082. X       { Summary of Fractal Types }
  73083. X       { Inside=bof60|bof61|zmag|period }
  73084. X       { Inside=epscross|startrail }
  73085. X       { Finite Attractors }
  73086. X       { Trig Identities }
  73087. X~Format+,Doc+
  73088. X;
  73089. X;
  73090. X~Topic=Before Mandelbrot
  73091. X
  73092. XLike new forms of life, new branches of mathematics and science don't
  73093. Xappear from nowhere. The ideas of fractal geometry can be traced to the
  73094. Xlate nineteenth century, when mathematicians created shapes -- sets of
  73095. Xpoints -- that seemed to have no counterpart in nature.  By a wonderful
  73096. Xirony, the "abstract" mathematics descended from that work has now turned
  73097. Xout to be MORE appropriate than any other for describing many natural
  73098. Xshapes and processes.
  73099. X
  73100. XPerhaps we shouldn't be surprised.  The Greek geometers worked out the
  73101. Xmathematics of the conic sections for its formal beauty; it was two
  73102. Xthousand years before Copernicus and Brahe, Kepler and Newton overcame the
  73103. Xpreconception that all heavenly motions must be circular, and found the
  73104. Xellipse, parabola, and hyperbola in the paths of planets, comets, and
  73105. Xprojectiles.
  73106. X
  73107. XIn the 17th century Newton and Leibniz created calculus, with its
  73108. Xtechniques for "differentiating" or finding the derivative of functions --
  73109. Xin geometric terms, finding the tangent of a curve at any given point.
  73110. XTrue, some functions were discontinuous, with no tangent at a gap or an
  73111. Xisolated point. Some had singularities: abrupt changes in direction at
  73112. Xwhich the idea of a tangent becomes meaningless. But these were seen as
  73113. Xexceptional, and attention was focused on the "well-behaved" functions
  73114. Xthat worked well in modeling nature.
  73115. X
  73116. XBeginning in the early 1870s, though, a 50-year crisis transformed
  73117. Xmathematical thinking. Weierstrass described a function that was
  73118. Xcontinuous but nondifferentiable -- no tangent could be described at any
  73119. Xpoint. Cantor showed how a simple, repeated procedure could turn a line
  73120. Xinto a dust of scattered points, and Peano generated a convoluted curve
  73121. Xthat eventually touches every point on a plane. These shapes seemed to
  73122. Xfall "between" the usual categories of one-dimensional lines, two-
  73123. Xdimensional planes and three-dimensional volumes. Most still saw them as
  73124. X"pathological" cases, but here and there they began to find applications.
  73125. X
  73126. XIn other areas of mathematics, too, strange shapes began to crop up.
  73127. XPoincare attempted to analyze the stability of the solar system in the
  73128. X1880s and found that the many-body dynamical problem resisted traditional
  73129. Xmethods. Instead, he developed a qualitative approach, a "state space" in
  73130. Xwhich each point represented a different planetary orbit, and studied what
  73131. Xwe would now call the topology -- the "connectedness" -- of whole families
  73132. Xof orbits. This approach revealed that while many initial motions quickly
  73133. Xsettled into the familiar curves, there were also strange, "chaotic"
  73134. Xorbits that never became periodic and predictable.
  73135. X
  73136. XOther investigators trying to understand fluctuating, "noisy" phenomena --
  73137. Xthe flooding of the Nile, price series in economics, the jiggling of
  73138. Xmolecules in Brownian motion in fluids -- found that traditional models
  73139. Xcould not match the data. They had to introduce apparently arbitrary
  73140. Xscaling features, with spikes in the data becoming rarer as they grew
  73141. Xlarger, but never disappearing entirely.
  73142. X
  73143. XFor many years these developments seemed unrelated, but there were
  73144. Xtantalizing hints of a common thread. Like the pure mathematicians' curves
  73145. Xand the chaotic orbital motions, the graphs of irregular time series often
  73146. Xhad the property of self-similarity: a magnified small section looked very
  73147. Xsimilar to a large one over a wide range of scales.
  73148. X;
  73149. X;
  73150. X~Topic=Who Is This Guy\, Anyway?
  73151. X
  73152. XWhile many pure and applied mathematicians advanced these trends, it is
  73153. XBenoit Mandelbrot above all who saw what they had in common and pulled the
  73154. Xthreads together into the new discipline.
  73155. X
  73156. XHe was born in Warsaw in 1924, and moved to France in 1935. In a time when
  73157. XFrench mathematical training was strongly analytic, he visualized problems
  73158. Xwhenever possible, so that he could attack them in geometric terms.  He
  73159. Xattended the Ecole Polytechnique, then Caltech, where he encountered the
  73160. Xtangled motions of fluid turbulence.
  73161. X
  73162. XIn 1958 he joined IBM, where he began a mathematical analysis of
  73163. Xelectronic "noise" -- and began to perceive a structure in it, a hierarchy
  73164. Xof fluctuations of all sizes, that could not be explained by existing
  73165. Xstatistical methods. Through the years that followed, one seemingly
  73166. Xunrelated problem after another was drawn into the growing body of ideas
  73167. Xhe would come to call fractal geometry.
  73168. X
  73169. XAs computers gained more graphic capabilities, the skills of his mind's
  73170. Xeye were reinforced by visualization on display screens and plotters.
  73171. XAgain and again, fractal models produced results -- series of flood
  73172. Xheights, or cotton prices -- that experts said looked like "the real
  73173. Xthing."
  73174. X
  73175. XVisualization was extended to the physical world as well. In a provocative
  73176. Xessay titled "How Long Is the Coast of Britain?" Mandelbrot noted that the
  73177. Xanswer depends on the scale at which one measures: it grows longer and
  73178. Xlonger as one takes into account every bay and inlet, every stone, every
  73179. Xgrain of sand. And he codified the "self-similarity" characteristic of
  73180. Xmany fractal shapes -- the reappearance of geometrically similar features
  73181. Xat all scales.
  73182. X
  73183. XFirst in isolated papers and lectures, then in two editions of his seminal
  73184. Xbook, he argued that many of science's traditional mathematical models are
  73185. Xill-suited to natural forms and processes: in fact, that many of the
  73186. X"pathological" shapes mathematicians had discovered generations before are
  73187. Xuseful approximations of tree bark and lung tissue, clouds and galaxies.
  73188. X
  73189. XMandelbrot was named an IBM Fellow in 1974, and continues to work at the
  73190. XIBM Watson Research Center. He has also been a visiting professor and
  73191. Xguest lecturer at many universities.
  73192. X;
  73193. X;
  73194. X~Topic=Periodicity Logic
  73195. X
  73196. XThe "Mandelbrot Lake" in the center of the M-set images is the traditional
  73197. Xbane of plotting programs. It sucks up the most computer time because it
  73198. Xalways reaches the iteration limit -- and yet the most interesting areas
  73199. Xare invariably right at the edge the lake.
  73200. X(See {The Mandelbrot Set} for a description of the iteration process.)
  73201. X
  73202. XThanks to Mark Peterson for pointing out (well, he more like beat us over
  73203. Xthe head until we paid attention) that the iteration values in the middle
  73204. Xof Mandelbrot Lake tend to decay to periodic loops (i.e., Z(n+m) == Z(n),
  73205. Xa fact that is pointed out on pages 58-61 of "The Beauty of Fractals"). An
  73206. Xintelligent program (like the one he wrote) would check for this
  73207. Xperiodicity once in a while, recognize that iterations caught in a loop
  73208. Xare going to max out, and bail out early.
  73209. X
  73210. XFor speed purposes, the current version of the program turns this checking
  73211. Xalgorithm on only if the last pixel generated was in the lake.    (The
  73212. Xchecking itself takes a small amount of time, and the pixels on the very
  73213. Xedge of the lake tend to decay to periodic loops very slowly, so this
  73214. Xcompromise turned out to be the fastest generic answer).
  73215. X
  73216. XTry a full M-set plot with a 1000-iteration maximum with any other
  73217. Xprogram, and then try it on this one for a pretty dramatic proof of the
  73218. Xvalue of periodicity checking.
  73219. X
  73220. XYou can get a visual display of the periodicity effects if you press
  73221. X<O>rbits while plotting. This toggles display of the intermediate
  73222. Xiterations during the generation process.  It also gives you an idea of
  73223. Xhow much work your poor little PC is going through for you!  If you use
  73224. Xthis toggle, it's best to disable solid-guessing first using <1> or <2>
  73225. Xbecause in its second pass, solid-guessing bypasses many of the pixel
  73226. Xcalculations precisely where the orbits are most interesting.
  73227. X
  73228. XMark was also responsible for pointing out that 16-bit integer math was
  73229. Xgood enough for the first few levels of M/J images, where the round-off
  73230. Xerrors stay well within the area covered by a single pixel. Fractint now
  73231. Xuses 16-bit math where applicable, which makes a big difference on non-32-
  73232. Xbit PCs.
  73233. X;
  73234. X;
  73235. X~Topic=Limitations of Integer Math (And How We Cope)
  73236. X
  73237. XBy default, Fractint uses 16-bit and/or 32-bit integer math to generate
  73238. Xnearly all its fractal types. The advantage of integer math is speed: this
  73239. Xis by far the fastest such plotter that we have ever seen on any PC. The
  73240. Xdisadvantage is an accuracy limit. Integer math represents numbers like
  73241. X1.00 as 32-bit integers of the form [1.00 * (2^29)] (approximately
  73242. Xa range of 500,000,000) for the Mandelbrot and Julia sets. Other integer
  73243. Xfractal types use a bitshift of 24 rather than 29, so 1.0 is stored
  73244. Xinternally as [1.00 * (2^*24)]. This yields accuracy of better than 8
  73245. Xsignificant digits, and works fine... until the initial values of the
  73246. Xcalculations on consecutive pixels differ only in the ninth decimal place.
  73247. X
  73248. XAt that point, if Fractint has a floating-point algorithm handy for that
  73249. Xparticular fractal type (and virtually all of the fractal types have one
  73250. Xthese days), it will silently switch over to the floating-point algorithm
  73251. Xand keep right on going.  Fair warning - if you don't have an FPU, the
  73252. Xeffect is that of a rocket sled hitting a wall of jello, and even if you
  73253. Xdo, the slowdown is noticeable.
  73254. X
  73255. XIf it has no floating-point algorithm, Fractint does the best it can: it
  73256. Xswitches to its minimal drawing mode, with adjacent pixels having initial
  73257. Xvalues differing by 1 (really 0.000000002).  Attempts to zoom further may
  73258. Xresult in moving the image around a bit, but won't actually zoom.  If you
  73259. Xare stuck with an integer algorithm, you can reach minimal mode with your
  73260. Xfifth consecutive "maximum zoom", each of which covers about 0.25% of the
  73261. Xprevious screen. By then your full-screen image is an area less than
  73262. X1/(10^13)th [\~0.0000000000001] the area of the initial screen.  (If your
  73263. Ximage is rotated or stretched very slightly, you can run into the wall of
  73264. Xjello as early as the fourth consecutive maximum zoom.    Rotating or
  73265. Xstretching by larger amounts has less impact on how soon you run into it.)
  73266. X
  73267. XThink of it this way: at minimal drawing mode, your VGA display would have
  73268. Xto have a surface area of over one million square miles just to be able to
  73269. Xdisplay the entire M-set using the integer algorithms.    Using the
  73270. Xfloating-point algorithms, your display would have to be big enough to fit
  73271. Xthe entire solar system out to the orbit of Saturn inside it.  So there's
  73272. Xa considerable saving on hardware, electricity and desk space involved
  73273. Xhere.  Also, you don't have to take out asteroid insurance.
  73274. X
  73275. X32 bit integers also limit the largest number which can be stored.  This
  73276. Xdoesn't matter much since numbers outside the supported range (which is
  73277. Xbetween -4 and +4) produce a boring single color. If you try to zoom-out
  73278. Xto reduce the entire Mandelbrot set to a speck, or to squeeze
  73279. Xit to a pancake, you'll find you can't do so in integer math mode.
  73280. X;
  73281. X;
  73282. X~Topic=The Fractint "Fractal Engine" Architecture
  73283. X
  73284. XSeveral of the authors would never ADMIT this, but Fractint has evolved a
  73285. Xpowerful and flexible architecture that makes adding new fractals very
  73286. Xeasy. (They would never admit this because they pride themselves on being
  73287. Xthe sort that mindlessly but happily hacks away at code and "sees if it
  73288. Xworks and doesn't hang the machine".)
  73289. X
  73290. XMany fractal calculations work by taking a rectangle in the complex plane,
  73291. Xand, point by point, calculating a color corresponding to that point.
  73292. XFurthermore, the color calculation is often done by iterating a function
  73293. Xover and over until some bailout condition is met.
  73294. X(See {The Mandelbrot Set} for a description of the iteration process.)
  73295. X
  73296. XIn implementing such a scheme, there are three fractal-specific
  73297. Xcalculations that take place within a framework that is pretty much the
  73298. Xsame for them all.  Rather than copy the same code over and over, we
  73299. Xcreated a standard fractal engine that calls three functions that may be
  73300. Xbolted in temporarily to the engine.  The "bolting in" process uses the C
  73301. Xlanguage mechanism of variable function pointers.
  73302. X
  73303. XThese three functions are:
  73304. X
  73305. X   1) a setup function that is run once per image, to do any required
  73306. X   initialization of variables,
  73307. X
  73308. X   2) a once-per-pixel function that does whatever initialization has to
  73309. X   be done to calculate a color for one pixel, and
  73310. X
  73311. X   3) a once-per-orbit-iteration function, which is the fundamental
  73312. X   fractal algorithm that is repeatedly iterated in the fractal
  73313. X   calculation.
  73314. X
  73315. XThe common framework that calls these functions can contain all sorts of
  73316. Xspeedups, tricks, and options that the fractal implementor need not worry
  73317. Xabout.    All that is necessary is to write the three functions in the
  73318. Xcorrect way, and BINGO! - all options automatically apply. What makes it
  73319. Xeven easier is that usually one can re-use functions 1) and 2) written for
  73320. Xother fractals, and therefore only need to write function 3).
  73321. X
  73322. XThen it occurred to us that there might be more than one sort of fractal
  73323. Xengine, so we even allowed THAT to be bolted in. And we created a data
  73324. Xstructure for each fractal that includes pointers to these four functions,
  73325. Xvarious prompts, a default region of the complex plane, and various
  73326. Xmiscellaneous bits of information that allow toggling between Julia and
  73327. XMandelbrot or toggling between the various kinds of math used in
  73328. Ximplementation.
  73329. X
  73330. XThat sounds pretty flexible, but there is one drawback - you have to be a
  73331. XC programmer and have a C compiler to make use of it! So we took it a step
  73332. Xfurther, and designed a built-in high level compiler, so that you can
  73333. Xenter the formulas for the various functions in a formula file in a
  73334. Xstraightforward algebra-like language, and Fractint will compile them and
  73335. Xbolt them in for you!
  73336. X
  73337. XThere is a terrible down side to this flexibility.  Fractint users
  73338. Xeverywhere are going berserk. Fractal-inventing creativity is running
  73339. Xrampant. Proposals for new fractal types are clogging the mail and the
  73340. Xtelephones.
  73341. X
  73342. XAll we can say is that non-productivity software has never been so potent,
  73343. Xand we're sorry, it's our fault!
  73344. X
  73345. XFractint was compiled using Microsoft C 6.00A and Microsoft Assembler 5.1,
  73346. Xusing the "Medium" model. Note that the assembler code uses the "C" model
  73347. Xoption added to version 5.1, and must be assembled with the /MX or /ML
  73348. Xswitch to link with the "C" code. Because it has become too large to
  73349. Xdistribute comfortably as a single compressed file, and because many
  73350. Xdownloaders have no intention of ever modifying it, Fractint is now
  73351. Xdistributed as two files: one containing FRACTINT.EXE, auxiliary files and
  73352. Xthis document, and another containing complete source code (including a
  73353. X.MAK file and MAKEFRAC.BAT).  See {Distribution of Fractint}.
  73354. X;
  73355. X;
  73356. X;
  73357. X~Topic=Inside=bof60|bof61|zmag|period
  73358. X~Format-,Online-
  73359. X
  73360. XINSIDE=BOF60|BOF61|ZMAG|PERIOD
  73361. X~Format+,Online+
  73362. X
  73363. XHere is an *ATTEMPTED* explanation of what the inside=bof60 and
  73364. Xinside=bof61 options do. This explanation is hereby dedicated to Adrian
  73365. XMariano, who badgered it out of us! For the *REAL* explanation, see
  73366. X"Beauty of Fractals", page 62.
  73367. X
  73368. XLet p(z) be the function that is repeatedly iterated to generate a fractal
  73369. Xusing the escape-time algorithm.  For example, p(z) = z^2+c in the case of
  73370. Xa Julia set. Then let pk(z) be the result of iterating the function p for
  73371. Xk iterations. (The "k" should be shown as a superscript.) We could also
  73372. Xuse the notation pkc(z) when the function p has a parameter c, as it does
  73373. Xin our example.  Now hold your breath and get your thinking cap on. Define
  73374. Xa(c) = inf\{|pck(0)|:k=1,2,3,...}. In English - a(c) is the greatest lower
  73375. Xbound of the images of zero of as many iterations as you like. Put another
  73376. Xway, a(c) is the closest to the origin any point in the orbit starting
  73377. Xwith 0 gets. Then the index (c) is the value of k (the iteration) when
  73378. Xthat closest point was achieved.  Since there may be more than one,
  73379. Xindex(c) is the least such. Got it?  Good, because the "Beauty of
  73380. XFractals" explanation of this, is, ahhhh, *TERSE* ! Now for the punch
  73381. Xline. Inside=bof60 colors the lake alternating shades according to the
  73382. Xlevel sets of a(c).  Each band represents solid areas of the fractal where
  73383. Xthe closest value of the orbit to the origin is the same.  Inside=bof61
  73384. Xshow domains where index(c) is constant.  That is, areas where the
  73385. Xiteration when the orbit swooped closest to the origin has the same value.
  73386. XWell, folks, that's the best we can do! Improved explanations will be
  73387. Xaccepted for the next edition!
  73388. X
  73389. Xinside=zmag is similar. This option colors inside pixels according to
  73390. Xthe magnitude of the orbit point when maxiter was reached, using the formula
  73391. Xcolor = (x^2 + y^2) * maxiter/2 + 1.
  73392. X
  73393. Xinside=period colors pixels according to the length of their eventual cycle.
  73394. XFor example, points that approach a fixed point have color=1.  Points that
  73395. Xapproach a 2-cycle have color=2.  Points that do not approach a cycle during
  73396. Xthe iterations performed have color=maxit.  This option works best with a
  73397. Xfairly large number of iterations.
  73398. X;
  73399. X;
  73400. X;
  73401. X~Topic=Inside=epscross|startrail
  73402. X~Format-,Online-
  73403. X
  73404. XINSIDE=EPSCROSS|STARTRAIL
  73405. X~Format+,Online+
  73406. X
  73407. XKenneth Hooper has written a paper entitled "A Note On Some Internal
  73408. XStructures Of The Mandelbrot Set" published in "Computers and Graphics", Vol
  73409. X15, No.2, pp. 295-297.    In that article he describes Clifford Pickover's
  73410. X"epsilon cross" method which creates some mysterious plant-like tendrils in
  73411. Xthe Mandelbrot set. The algorithm is this. In the escape-time calculation of a
  73412. Xfractal, if the orbit comes within .01 of the Y-axis, the orbit is terminated
  73413. Xand the pixel is colored green. Similarly, the pixel is colored yellow if it
  73414. Xapproaches the X-axis. Strictly speaking, this is not an "inside" option
  73415. Xbecause a point destined to escape could be caught by this bailout criterion.
  73416. X
  73417. XHooper has another coloring scheme called "star trails" that involves
  73418. Xdetecting clusters of points being traversed by the orbit. A table of tangents
  73419. Xof each orbit point is built, and the pixel colored according to how many
  73420. Xorbit points are near the first one before the orbit flies out of the cluster.
  73421. XThis option looks fine with maxiter=16, which greatly speeds the calculation.
  73422. X
  73423. XBoth of these options should be tried with the outside color fixed
  73424. X(outside=<nnn>) so that the "lake" structure revealed by the algorithms can be
  73425. Xmore clearly seen. Epsilon Cross is fun to watch with boundary tracing turned
  73426. Xon - even though the result is incorrect it is interesting! Shucks - what
  73427. Xdoes "incorrect" mean in chaos theory anyway?!
  73428. X;
  73429. X;
  73430. X;
  73431. X~Topic=Finite Attractors
  73432. X~Format-,Online-
  73433. X
  73434. XFINITE ATTRACTORS
  73435. X~Format+,Online+
  73436. X
  73437. XMany of Fractint's fractals involve the iteration of functions of complex
  73438. Xnumbers until some "bailout" value is exceeded, then coloring the
  73439. Xassociated pixel according to the number of iterations performed.  This
  73440. Xprocess identifies which values tend to infinity when iterated, and gives
  73441. Xus a rough measure of how "quickly" they get there.
  73442. X
  73443. XIn dynamical terms, we say that "Infinity is an Attractor", as many
  73444. Xinitial values get "attracted" to it when iterated.  The set of all points
  73445. Xthat are attracted to infinity is termed The Basin of Attraction of
  73446. XInfinity.  The coloring algorithm used divides this Basin of Attraction
  73447. Xinto many distinct sets, each a single band of one color, representing all
  73448. Xthe points that are "attracted" to Infinity at the same "rate".  These
  73449. Xsets (bands of color) are termed "Level Sets" - all points in such a set
  73450. Xare at the same "Level" away from the attractor, in terms of numbers of
  73451. Xiterations required to exceed the bailout value.
  73452. X
  73453. XThus, Fractint produces colored images of the Level Sets of the Basin of
  73454. XAttraction of Infinity, for all fractals that iterate functions of Complex
  73455. Xnumbers, at least.  Now we have a sound mathematical definition of what
  73456. XFractint's "bailout" processing generates, and we have formally introduced
  73457. Xthe terms Attractor, Basin of Attraction, and Level Set, so you should
  73458. Xhave little trouble following the rest of this section!
  73459. X
  73460. XFor certain Julia-type fractals, Fractint can also display the Level Sets
  73461. Xof Basins of Attraction of Finite Attractors.  This capability is a by-
  73462. Xproduct of the implementation of the MAGNETic fractal types, which always
  73463. Xhave at least one Finite Attractor.
  73464. X
  73465. XThis option can be invoked by setting the "Look for finite attractor"
  73466. Xoption on the <Y> options screen, or by giving the "finattract=yes"
  73467. Xcommand-line option.
  73468. X
  73469. XMost Julia-types that have a "lake" (normally colored blue by default)
  73470. Xhave a Finite Attractor within this lake, and the lake turns out to be,
  73471. Xquite appropriately, the Basin of Attraction of this Attractor.
  73472. X
  73473. XThe "finattract=yes" option (command-line or <Y> options screen)
  73474. Xinstructs Fractint to seek out and identify a possible Finite Attractor
  73475. Xand, if found, to display the Level Sets of its Basin of Attraction, in
  73476. Xaddition to those of the Basin of Attraction of Infinity.  In many cases
  73477. Xthis results in a "lake" with colored "waves" in it;  in other cases there
  73478. Xmay be little change in the lake's appearance.
  73479. X
  73480. XFor a quick demonstration, select a fractal type of LAMBDA, with a
  73481. Xparameter of 0.5 + 0.5i.  You will obtain an image with a large blue lake.
  73482. XNow set "Look for finite attractor" to 1 with the "Y" menu.
  73483. XThe image will be re-drawn
  73484. Xwith a much more colorful lake.  A Finite Attractor lives in the center of
  73485. Xone of the resulting "ripple" patterns in the lake - turn the <O>rbits
  73486. Xdisplay on to see where it is - the orbits of all initial points that are
  73487. Xin the lake converge there.
  73488. X
  73489. XFractint tests for the presence of a Finite Attractor by iterating a
  73490. XCritical Value of the fractal's function.  If the iteration doesn't bail
  73491. Xout before exceeding twice the iteration limit, it is almost certain that
  73492. Xwe have a Finite Attractor - we assume that we have.
  73493. X
  73494. XNext we define a small circle around it and, after each iteration, as well
  73495. Xas testing for the usual bailout value being exceeded, we test to see if
  73496. Xwe've hit the circle. If so, we bail out and color our pixels according to
  73497. Xthe number of iterations performed.  Result - a nicely colored-in lake
  73498. Xthat displays the Level Sets of the Basin of Attraction of the Finite
  73499. XAttractor.  Sometimes !
  73500. X
  73501. XFirst exception: This does not work for the lakes of Mandel-types.  Every
  73502. Xpoint in a Mandel-type is, in effect, a single point plucked from one of
  73503. Xits related Julia-types.  A Mandel-type's lake has an infinite number of
  73504. Xpoints, and thus an infinite number of related Julia-type sets, and
  73505. Xconsequently an infinite number of finite attractors too.  It *MAY* be
  73506. Xpossible to color in such a lake, by determining the attractor for EVERY
  73507. Xpixel, but this would probably treble (at least) the number of iterations
  73508. Xneeded to draw the image.  Due to this overhead, Finite Attractor logic
  73509. Xhas not been implemented for Mandel-types.
  73510. X
  73511. XSecondly, certain Julia-types with lakes may not respond to this
  73512. Xtreatment, depending on the parameter value used.  E.g., the Lambda Set
  73513. Xfor 0.5 + 0.5i responds well; the Lambda Set for 0.0 + 1.0i does not - its
  73514. Xlake stays blue.  Attractors that consist of single points, or a cycle of
  73515. Xa finite number of points are ok.  Others are not.  If you're into fractal
  73516. Xtechnospeke, the implemented approach fails if the Julia-type is a
  73517. XParabolic case, or has Siegel Disks, or has Herman Rings.
  73518. X
  73519. XHowever, all the difficult cases have one thing in common - they all have
  73520. Xa parameter value that falls exactly on the edge of the related Mandel-
  73521. Xtype's lake.  You can avoid them by intelligent use of the Mandel-Julia
  73522. XSpace-Bar toggle:  Pick a view of the related Mandel-type where the center
  73523. Xof the screen is inside the lake, but not too close to its edge, then use
  73524. Xthe space-bar toggle.  You should obtain a usable Julia-type with a lake,
  73525. Xif you follow this guideline.
  73526. X
  73527. XThirdly, the initial implementation only works for Julia-types that use
  73528. Xthe "Standard" fractal engine in Fractint.  Fractals with their own
  73529. Xspecial algorithms are not affected by Finite Attractor logic, as yet.
  73530. X
  73531. XFinally, the finite attractor code will not work if it fails to detect
  73532. Xa finite attractor.  If the number of iterations is set too low, the finite
  73533. Xattractor may be missed.
  73534. X
  73535. XDespite these restrictions, the Finite Attractor logic can produce
  73536. Xinteresting results.  Just bear in mind that it is principally a bonus
  73537. Xoff-shoot from the development of the MAGNETic fractal types, and is not
  73538. Xspecifically tuned for optimal performance for other Julia types.
  73539. X
  73540. X(Thanks to Kevin Allen for the above).
  73541. X
  73542. XThere is a second type of finite attractor coloring, which is selected
  73543. Xby setting "Look for Finite Attractor" to a negative value.  This colors
  73544. Xpoints by the phase of the convergence to the finite attractor,
  73545. Xinstead of by the speed of convergence.
  73546. X
  73547. XFor example, consider the Julia set for -0.1 + 0.7i, which is the three-lobed
  73548. X"rabbit" set.  The Finite Attractor is an orbit of length three; call these
  73549. Xvalues a, b, and c.  Then, the Julia set iteration can converge to one of
  73550. Xthree sequences: a,b,c,a,b,c,..., or b,c,a,b,c,..., or c,a,b,c,a,b,...  
  73551. XThe Finite Attractor phase option colors the interior of the Julia set with
  73552. Xthree colors, depending on which of the three sequences the orbit converges
  73553. Xto.  Internally, the code determines one point of the orbit, say "a", and
  73554. Xthe length of the orbit cycle, say 3.  It then iterates until the sequence
  73555. Xconverges to a, and then uses the iteration number modulo 3 to determine the
  73556. Xcolor.
  73557. X
  73558. X;
  73559. X;
  73560. X~Topic=Trig Identities
  73561. X~Online-
  73562. X
  73563. XTRIG IDENTITIES
  73564. X~Online+
  73565. X
  73566. XThe following trig identities are invaluable for coding fractals that use
  73567. Xcomplex-valued transcendental functions.
  73568. X
  73569. X~Format-
  73570. X   e^(x+iy) = (e^x)cos(y) + i(e^x)sin(y)
  73571. X
  73572. X   sin(x+iy)  = sin(x)cosh(y) + icos(x)sinh(y)
  73573. X   cos(x+iy)  = cos(x)cosh(y) - isin(x)sinh(y)
  73574. X   sinh(x+iy) = sinh(x)cos(y) + icosh(x)sin(y)
  73575. X   cosh(x+iy) = cosh(x)cos(y) + isinh(x)sin(y)
  73576. X
  73577. X   cosxx(x+iy) = cos(x)cosh(y) + isin(x)sinh(y)
  73578. X     (cosxx is present in Fractint to provide compatibility with a bug
  73579. X     which was in its cos calculation before version 16)
  73580. X
  73581. X   ln(x+iy) = (1/2)ln(x*x + y*y) + i(arctan(y/x) + 2kPi)
  73582. X                    (k = 0, +-1, +-2, +-....)
  73583. X
  73584. X             sin(2x)           sinh(2y)
  73585. X   tan(x+iy) = ------------------  + i------------------
  73586. X           cos(2x) + cosh(2y)     cos(2x) + cosh(2y)
  73587. X~OnlineFF
  73588. X
  73589. X            sinh(2x)            sin(2y)
  73590. X   tanh(x+iy) = ------------------ + i------------------
  73591. X        cosh(2x) + cos(2y)    cosh(2x) + cos(2y)
  73592. X
  73593. X         sin(2x) - i*sinh(2y)
  73594. X   cotan(x+iy) = --------------------
  73595. X          cosh(2y) - cos(2x)
  73596. X
  73597. X          sinh(2x) - i*sin(2y)
  73598. X   cotanh(x+iy) = --------------------
  73599. X           cosh(2x) - cos(2y)
  73600. X
  73601. X   z^z = e^(log(z)*z)
  73602. X
  73603. X   log(x+iy) = 1/2(log(x*x + y*y) + i(arc_tan(y/x))
  73604. X
  73605. X   e^(x+iy) = (cosh(x) + sinh(x)) * (cos(y) + isin(y))
  73606. X        = e^x * (cos(y) + isin(y))
  73607. X        = (e^x * cos(y)) + i(e^x * sin(y))
  73608. X~Format+
  73609. X;
  73610. X;
  73611. X;
  73612. X~Topic=GIF Save File Format
  73613. X
  73614. XSince version 5.0, Fractint has had the <S>ave-to-disk command, which
  73615. Xstores screen images in the extremely compact, flexible .GIF (Graphics
  73616. XInterchange Format) widely supported on Compuserve. Version 7.0 added the
  73617. X<R>estore-from-disk capability.
  73618. X
  73619. XUntil version 14, Fractint saved images as .FRA files, which were a
  73620. Xnon-standard extension of the then-current GIF87a specification.  The
  73621. Xreason was that GIF87a did not offer a place to store the extra
  73622. Xinformation needed by Fractint to implement the
  73623. X<R> feature -- i.e., the parameters that let you keep zooming, etc.
  73624. Xas if the restored file had just been created in this session.
  73625. XThe .FRA format worked with all of the popular GIF decoders that we
  73626. Xtested, but these were not true GIF files. For one thing,
  73627. Xinformation after the GIF terminator (which is where we put the extra info)
  73628. Xhas the potential to confuse the
  73629. Xonline GIF viewers used on Compuserve. For another, it is the opinion of
  73630. Xsome GIF developers that the addition of this extra information violates
  73631. Xthe GIF87a spec. That's why we used the default filetype .FRA instead.
  73632. X
  73633. XSince version 14, Fractint has used a genuine .GIF format, using the
  73634. XGIF89a spec - an upwardly compatible extension of GIF87a, released by
  73635. XCompuserve on August 1 1990.
  73636. XThis new spec allows the
  73637. Xplacement of application data within "extension blocks".
  73638. XIn version 14 we changed our default savename extension from .FRA
  73639. Xto .GIF.
  73640. X
  73641. XThere is one significant advantage to the new GIF89a format compared to
  73642. Xthe old GIF87a-based .FRA format for Fractint purposes:  the new .GIF
  73643. Xfiles may be uploaded to the Compuserve graphics forums (such as
  73644. XFractint's home forum, GRAPHDEV) with fractal information intact.  Therefore
  73645. Xanyone downloading a Fractint image from Compuserve will also be
  73646. Xdownloading all the information needed to regenerate the image.
  73647. X
  73648. XFractint can still read .FRA files generated by
  73649. Xearlier versions.  If for some reason you wish to save files in the older
  73650. XGIF87a format, for example because your favorite GIF decoder has not yet
  73651. Xbeen upgraded to GIF89a, use the command-line parameter "GIF87a=yes".
  73652. XThen any saved files will use the original GIF87a format without any
  73653. Xapplication-specific information.
  73654. X
  73655. XAn easy way to convert an older .FRA file into true .GIF format suitable
  73656. Xfor uploading is something like this at the DOS prompt:\
  73657. X    FRACTINT MYFILE.FRA SAVENAME=MYFILE.GIF BATCH=YES\
  73658. XFractint will load MYFILE.FRA, save it in true .GIF format as MYFILE.GIF,
  73659. Xand return to DOS.
  73660. X
  73661. XGIF and "Graphics Interchange Format" are trademarks of Compuserve
  73662. XIncorporated, an H&R Block Company.
  73663. X;
  73664. X;
  73665. X;
  73666. X~Topic=Using Fractint With a Mouse
  73667. X; This topic is online only.
  73668. X
  73669. X~FormatExclude-
  73670. XLeft Button:   Brings up and sizes the Zoom Box.   While holding down the
  73671. X           left button, push the mouse forward to shrink the Zoom Box,
  73672. X           and pull it back to expand it.
  73673. X           Double-clicking the left button performs the Zoom.
  73674. X
  73675. XRight Button:  While holding the right button held down, move the mouse
  73676. X           from side to side to 'rotate' the Zoom Box.  Move the mouse
  73677. X           forward or back to change the Zoom Box color.
  73678. X           Double-clicking the right button performs a 'Zoom-Out'.
  73679. X
  73680. XBoth Buttons:  (or the middle button, if you have three of them) While
  73681. X           holding down both buttons, move the mouse up and down to
  73682. X           stretch/shrink the height of the Zoom Box, or side to side
  73683. X           to 'squish' the Zoom Box into a non-rectangular shape.
  73684. X
  73685. XZoom and Pan using the mouse typically consists of pushing in the left
  73686. Xbutton, sizing the zoom box, letting go of the button, panning to the
  73687. Xgeneral area, then double-clicking the left button to perform the Zoom.
  73688. X;
  73689. X;
  73690. X;
  73691. X~Topic=Selecting a video mode when loading a file, Label=HELPLOADFILE
  73692. X; This topic is only online, context-sensitive.
  73693. X~Format-
  73694. X
  73695. XThe most suitable video modes for the file are listed first.
  73696. X
  73697. XThe 'err' column in the video mode information indicates:
  73698. X  blank  mode seems perfect for this image
  73699. X  v     image smaller than screen, will be loaded in a <v>iew window
  73700. X  c     mode has more colors than image needs
  73701. X  *     a major problem, one or more of the following is also shown:
  73702. X   C     mode has too few colors
  73703. X   R     image larger than screen, Fractint will reduce the image, possibly
  73704. X     into a <v>iew window, and maybe with aspect ratio a bit wrong
  73705. X   A     mode has the wrong shape of pixels for this image
  73706. X;
  73707. X;
  73708. X;
  73709. X~Topic=Distribution of Fractint
  73710. X~Format-,Online-
  73711. X
  73712. XDISTRIBUTION OF FRACTINT
  73713. X~Format+,Online+
  73714. X
  73715. XNew versions of FRACTINT are uploaded to the CompuServe network, and make
  73716. Xtheir way to other systems from that point.  FRACTINT is available as
  73717. Xtwo self-extracting archive files - FRAINT.EXE (executable & documentation)
  73718. Xand FRASRC.EXE (source code).
  73719. X
  73720. XThe latest version can always be found on CompuServe in the "Fractal Sources"
  73721. Xlibrary of the GRAPHDEV forum.  If you're not a Compuserve subscriber, but
  73722. Xwish to get more information about Compuserve and its graphics forums,
  73723. Xfeel free to call their 800 number (800-848-8199) and ask for operator
  73724. Xnumber 229.
  73725. X
  73726. XIf you don't have access to Compuserve, many other sites tend to carry
  73727. Xthese files shortly after their initial release (although sometimes
  73728. Xusing different naming conventions).  For instance...
  73729. X
  73730. XIf you speak Internet and FTP, SIMTEL20 and its various mirror sites
  73731. Xtend to carry new versions of Fractint shortly after they are released.
  73732. Xlook in the PD:<MSDOS.GRAPHICS> directory for files named FRA*.*.  Then
  73733. Xagain, if you don't speak Internet and FTP...
  73734. X~OnlineFF
  73735. X
  73736. XYour favorite local BBS probably carries these files as well (although
  73737. Xperhaps not the latest versions) using naming conventions like FRA*.ZIP.
  73738. XOne BBS that *does* carry the latest version is the "Ideal Studies BBS"
  73739. X(508)757-1806, 1200/2400/9600HST.  Peter Longo is the SYSOP and a true
  73740. Xfractal fanatic.  There is a very short registration, and thereafter the
  73741. Xentire board is open to callers on the first call.  Then again, if you
  73742. Xdon't even have a modem...
  73743. X
  73744. XMany Shareware/Freeware library services will ship you diskettes containing
  73745. Xthe latest versions of Fractint for a nominal fee that basically covers
  73746. Xtheir cost of packaging and a small profit that we don't mind them making.
  73747. XOne in particular is the Public (Software) Library, PO Box 35705,
  73748. XHouston, TX 77235-5705, USA.  Their phone number is 800-242-4775 (outside
  73749. Xthe US, dial 713-524-6394).  Ask for item #9112 for five 5.25" disks, #9113
  73750. Xfor three 3.5" disks.  Cost is $6.99 plus $4 S&H in the U.S./Canada, $11
  73751. XS&H overseas.
  73752. X
  73753. XIn Europe, the latest versions are available from another Fractint enthusiast,
  73754. XJon Horner - Editor of FRAC'Cetera, a disk-based fractal/chaos resource.
  73755. XDisk prices for UK/Europe are: 5.25" HD BP4.50/5.00  : 3.5" HD BP (British
  73756. XPounds) 5.00/5.50.  Prices include p&p (airmail to Europe).  Contact:
  73757. XJon Horner, FRAC'Cetera, Le Mont Ardaine, Rue des Ardaines, St. Peters,
  73758. XGuernsey GY7 9EU, CI, UK.  Phone (44) 0481 63689.  CIS 100112,1700
  73759. X
  73760. XThe X Windows port of Fractint maintained by Ken Shirriff is available
  73761. Xvia FTP from sprite.berkeley.edu. 
  73762. X
  73763. X;
  73764. X;
  73765. X~Topic=Contacting the Authors
  73766. X~Format-,Online-
  73767. X
  73768. XCONTACTING THE AUTHORS
  73769. X~Format+,Online+
  73770. X
  73771. XCommunication between the programmers for development of the next version of
  73772. XFractint takes place in GRAPHDEV (Graphics Developers) Section 4 (Fractal
  73773. XSources) of CompuServe (CIS).
  73774. X
  73775. XAccess to the GRAPHDEV forum is open to any and all interested
  73776. Xin computer generated fractals.
  73777. XNew members are always welcome!
  73778. XStop on by if you have any questions or
  73779. Xjust want to take a peek at what's getting tossed into the soup.
  73780. XAlso, you'll find many GIF image files generated by fellow Fractint fans
  73781. Xand many fractal programs as well in the GRAPHDEV forum's data library 5.
  73782. X
  73783. XIf you're not a Compuserve subscriber, but wish to get more information
  73784. Xabout Compuserve and its graphics forums, feel free to call their 800
  73785. Xnumber (800-848-8199) and ask for operator number 229.
  73786. X
  73787. X~Format-
  73788. XBert Tyler        [73477,433] on CIS
  73789. X                        73477.433@compuserve.com on Internet
  73790. X
  73791. XTimothy Wegner        [71320,675] on CIS
  73792. X                        twegner@mitre.org on Internet
  73793. X~Format+
  73794. X;
  73795. X;
  73796. X~Topic=The Stone Soup Story
  73797. X~Format-,Online-
  73798. XTHE STONE SOUP STORY
  73799. X~Format+,Online+
  73800. X
  73801. XOnce upon a time, somewhere in Eastern Europe, there was a great famine.
  73802. XPeople jealously hoarded whatever food they could find, hiding it even
  73803. Xfrom their friends and neighbors. One day a peddler drove his wagon into a
  73804. Xvillage, sold a few of his wares, and began asking questions as if he
  73805. Xplanned to stay for the night.
  73806. X
  73807. X[No!  No!  It was three Russian Soldiers! - Lee Crocker]\
  73808. X[Wait!    I heard it was a Wandering Confessor! - Doug Quinn]\
  73809. X[Well *my* kids have a book that uses Russian Soldiers! - Bert]\
  73810. X[Look, who's writing this documentation, anyway? - Monte]\
  73811. X[Ah, but who gets it *last* and gets to upload it? - Bert]\
  73812. X
  73813. X"There's not a bite to eat in the whole province," he was told. "Better
  73814. Xkeep moving on."
  73815. X
  73816. X"Oh, I have everything I need," he said. "In fact, I was thinking of
  73817. Xmaking some stone soup to share with all of you." He pulled an iron
  73818. Xcauldron from his wagon, filled it with water, and built a fire under it.
  73819. XThen, with great ceremony, he drew an ordinary-looking stone from a velvet
  73820. Xbag and dropped it into the water.
  73821. X
  73822. XBy now, hearing the rumor of food, most of the villagers had come to the
  73823. Xsquare or watched from their windows. As the peddler sniffed the "broth"
  73824. Xand licked his lips in anticipation, hunger began to overcome their
  73825. Xskepticism.
  73826. X
  73827. X"Ahh," the peddler said to himself rather loudly, "I do like a tasty stone
  73828. Xsoup. Of course, stone soup with CABBAGE -- that's hard to beat."
  73829. X
  73830. XSoon a villager approached hesitantly, holding a cabbage he'd retrieved
  73831. Xfrom its hiding place, and added it to the pot. "Capital!" cried the
  73832. Xpeddler. "You know, I once had stone soup with cabbage and a bit of salt
  73833. Xbeef as well, and it was fit for a king."
  73834. X
  73835. XThe village butcher managed to find some salt beef...and so it went,
  73836. Xthrough potatoes, onions, carrots, mushrooms, and so on, until there was
  73837. Xindeed a delicious meal for all. The villagers offered the peddler a great
  73838. Xdeal of money for the magic stone, but he refused to sell and traveled on
  73839. Xthe next day. And from that time on, long after the famine had ended, they
  73840. Xreminisced about the finest soup they'd ever had.
  73841. X
  73842. X                ***
  73843. X
  73844. XThat's the way Fractint has grown, with quite a bit of magic, although
  73845. Xwithout the element of deception. (You don't have to deceive programmers
  73846. Xto make them think that hours of painstaking, often frustrating work is
  73847. Xfun... they do it to themselves.)
  73848. X
  73849. XIt wouldn't have happened, of course, without Benoit Mandelbrot and the
  73850. Xexplosion of interest in fractal graphics that has grown from his work at
  73851. XIBM. Or without the example of other Mandelplotters for the PC. Or without
  73852. Xthose wizards who first realized you could perform Mandelbrot calculations
  73853. Xusing integer math (it wasn't us - we just recognize good algorithms when
  73854. Xwe steal--uhh--see them).  Or those graphics experts who hang around the
  73855. XCompuserve PICS forum and keep adding video modes to the program.  Or...
  73856. X~Doc-
  73857. X(continued in {A Word About the Authors})
  73858. X~Doc+
  73859. X;
  73860. X;
  73861. X~Topic=A Word About the Authors
  73862. X~Format-,Online-
  73863. X
  73864. XA WORD ABOUT THE AUTHORS
  73865. X~Format+,Online+
  73866. X
  73867. XFractint is the result of a synergy between the main authors, many
  73868. Xcontributors, and published sources.  All four of the main authors have
  73869. Xhad a hand in many aspects of the code.  However, each author has certain
  73870. Xareas of greater contribution and creativity.  Since there is not room in
  73871. Xthe credits screen for the contributions of the main authors, we list these
  73872. Xhere to facilitate those who would like to communicate with us on
  73873. Xparticular subjects.
  73874. X
  73875. XBert Tyler is the original author.  He wrote the "blindingly fast" 386-
  73876. Xspecific 32 bit integer math code and the original video mode logic. Bert
  73877. Xmade Stone Soup possible, and provides a sense of direction when we need
  73878. Xit. His forte is writing fast 80x86 assembler, his knowledge of a variety
  73879. Xof video hardware, and his skill at hacking up the code we send him!
  73880. X
  73881. XBert has a BA in mathematics from Cornell University.  He has been in
  73882. Xprogramming since he got a job at the computer center in his sophomore
  73883. Xyear at college - in other words, he hasn't done an honest day's work in
  73884. Xhis life.  He has been known to pass himself off as a PC expert, a UNIX
  73885. Xexpert, a statistician, and even a financial modeling expert.  He is
  73886. Xcurrently masquerading as an independent PC consultant, supporting the PC-
  73887. Xto-Mainframe communications environment at NIH.  If you sent mail from the
  73888. XInternet to an NIH staffer on his 3+Mail system, it was probably Bert's
  73889. Xcode that mangled it during the Internet-to-3+Mail conversion.    He also
  73890. Xclaims to support the MS-Kermit environment at NIH. Fractint is Bert's
  73891. Xfirst effort at building a graphics program.
  73892. X
  73893. XTim Wegner contributed the original implementation of palette animation,
  73894. Xand is responsible for most of the 3D mechanisms.  He provided the main
  73895. Xoutlines of the "StandardFractal" engine and data structures, and is
  73896. Xaccused by his cohorts of being "obsessed with options".  Tim is quite
  73897. Xproud of having originally integrated the 256 color super VGA modes in
  73898. XFractint, especially since he knows almost nothing about it!
  73899. X
  73900. XTim has BA and MA degrees in mathematics from Carleton College and the
  73901. XUniversity of California Berkeley.  He worked for 7 years overseas as a
  73902. Xvolunteer, doing things like working with Egyptian villagers building
  73903. Xwater systems. Since returning to the US in 1982, he has written shuttle
  73904. Xnavigation software, a software support environment prototype, and
  73905. Xsupported strategic information planning, all at NASA's Johnson Space
  73906. XCenter.
  73907. X
  73908. XMark Peterson invented the periodicity detection logic, several original
  73909. Xfractal types, transcendental function libraries, alternate math
  73910. Ximplementations, the formula compiler, and the "Julibrot" intrinsic 3D
  73911. Xfractals - in other words, most of the truly original ideas in Fractint!
  73912. X
  73913. XMark's knowledge of higher mathematics and programming was achieved almost
  73914. Xentirely through self-study.  Mark has written several magazine articles on
  73915. Xcomputer programming and is coauthor of a book on Fractint called Fractal
  73916. XCreations.  Mark is also a free-lance computer consultant specializing in high
  73917. Xperformance applications.
  73918. X
  73919. XPieter Branderhorst is a late-comer to the group who likes to distract the
  73920. Xother authors with enhancements impacting at least half of the source at
  73921. Xonce.  His contributions include super solid guessing, image rotation,
  73922. Xresume, fast disk caching, and the new user interface.    More than any of
  73923. Xthe authors, he has personally touched and massaged the entire source.
  73924. X
  73925. XPieter left high school to work with computers, back when huge machines
  73926. Xhad 64k of core.  He's been happily computing since, mostly programming
  73927. Xand designing software from comms firmware to database and o/s, and
  73928. Xanything between, and large scale online transaction processing
  73929. Xapplications.  He has worked as a free-lance computer consultant (whatever
  73930. Xthat means) since 1983.
  73931. X;
  73932. X;
  73933. X~Topic=Other Fractal Products
  73934. X
  73935. X(Forgive us, but we just *have* to begin this section with a plug for
  73936. X*our* fractal products...)
  73937. X
  73938. XFractint's primary authors have written several books about fractals,
  73939. XFractint, and Winfract (the Windows version of Fractint).
  73940. X
  73941. XThe book about Fractint is The Waite Group's Fractal Creations (Copyright
  73942. X(C) 1991 Waite Group Press, ISBN # 1-878739-05-0).  The original book was
  73943. Xbased on Fractint version 15 - the second edition (which should hit
  73944. Xyour favorite local bookstore sometime in the fall of 1993) is based
  73945. Xon version 18.  The book about Winfract is The Waite Group's Fractals
  73946. Xfor Windows (Copyright (C) 1992 Waite Group Press, ISBN # 1-878739-25-5).
  73947. X
  73948. X~Format-
  73949. XFractal Creations and Fractals for Windows include:
  73950. X o A guided tour of Fractint/Winfract.
  73951. X o A detailed manual and reference section of commands.
  73952. X o A tutorial on fractals.
  73953. X o A reference containing tips, explanations, and examples of parameters
  73954. X   for all the Fractals generated by Fractint/Winfract.
  73955. X o Secrets on how the programs work internally.
  73956. X o 3-D red/blue glasses.
  73957. X o A fold-out color poster of the most spectacular fractals.
  73958. X o A disk containing either Fractint or Winfract and demonstration files.
  73959. X o (Fractals for Windows and the second edition of Fractal Creations only)
  73960. X   A complete copy of the source code with a chapter explaining how the
  73961. X   program works.
  73962. X~Format+
  73963. X
  73964. XIf you enjoy Fractint, you're sure to enjoy Fractal Creations. The book
  73965. Xincludes Fractint and is an excellent companion to the program.  If you
  73966. Xuse the Windows environment, be sure to pick up a copy of Fractals for
  73967. XWindows as well.
  73968. X;
  73969. X;
  73970. X~OnlineFF
  73971. X
  73972. XA great fractals newsletter is "Amygdala" published by Rollo Silver. 
  73973. XYou'll find equal parts fractal algorithms, humor, reviews, and ideas.
  73974. XWrite to: 
  73975. X   Amygdala\
  73976. X   Box 219\
  73977. X   San Cristobal, NM 87564\
  73978. X   USA\
  73979. X   Email:rsilver@lanl.gov\
  73980. X   Phone: 505-586-0197\
  73981. X
  73982. X
  73983. XAnother great fractals newsletter (this one based in the UK) is
  73984. X"FRAC'Cetera", a disk-based fractal/chaos resource published by
  73985. XJon Horner.  Contact:
  73986. X
  73987. X   Jon Horner\
  73988. X   FRAC'Cetera\
  73989. X   Le Mont Ardaine\
  73990. X   Rue des Ardaines\
  73991. X   ST Peters\
  73992. X   Guernsey GY7 9EU, CI, UK\
  73993. X   Email: 100112.1700@compuserve.com\
  73994. X   PH: (44) 0481 63689\
  73995. X;
  73996. X;
  73997. X~Topic=Bibliography
  73998. X
  73999. XBARNSLEY, Michael: "Fractals Everywhere," Academic Press, 1988.
  74000. X
  74001. XDEWDNEY, A. K., "Computer Recreations" columns in "Scientific American" --
  74002. X   8/85, 7/87, 11/87, 12/88, 7/89.
  74003. X
  74004. XFEDER, Jens: "Fractals," Plenum, 1988.\
  74005. X   Quite technical, with good coverage of applications in fluid
  74006. X   percolation, game theory, and other areas.
  74007. X
  74008. XGLEICK, James: "Chaos: Making a New Science," Viking Press, 1987.\
  74009. X   The best non-technical account of the revolution in our understanding
  74010. X   of dynamical systems and its connections with fractal geometry.
  74011. X
  74012. XMANDELBROT, Benoit: "The Fractal Geometry of Nature," W. H. Freeman & Co.,
  74013. X   1982.\
  74014. X   An even more revised and expanded version of the 1977 work. A rich and
  74015. X   sometimes confusing stew of formal and informal mathematics, the
  74016. X   prehistory of fractal geometry, and everything else. Best taken in
  74017. X   small doses.
  74018. X~OnlineFF
  74019. X
  74020. XMANDELBROT, Benoit: "Fractals: Form, Chance, and Dimension," W. H. Freeman
  74021. X   & Co., 1977.\
  74022. X   A much revised translation of "Les objets fractals: forme, hasard, et
  74023. X   dimension," Flammarion, 1975.
  74024. X
  74025. XPEITGEN, Heinz-Otto & RICHTER, Peter: "The Beauty of Fractals," Springer-
  74026. X   Verlag, 1986.\
  74027. X   THE coffee-table book of fractal images, knowledgeable on computer
  74028. X   graphics as well as the mathematics they portray.
  74029. X
  74030. XPEITGEN, Heinz-Otto & SAUPE, Ditmar: "The Science of Fractal Images,"
  74031. X   Springer-Verlag, 1988.\
  74032. X   A fantastic work, with a few nice pictures, but mostly filled with
  74033. X   *equations*!!!
  74034. X
  74035. XPICKOVER, Clifford: "Computers, Pattern, Chaos, and Beauty," St. Martin's
  74036. X   Press, 1990.\
  74037. X
  74038. XSCHROEDER, Manfred: "Fractals, Chaos, Power Laws," W. H. Freeman
  74039. X   & Co., 1991.\
  74040. X
  74041. XWEGNER, Timothy & PETERSON, Mark: "Fractal Creations," Waite Group Press,
  74042. X   1991 (second edition, by Wegner and Tyler, due in the fall of 1993).\
  74043. X   If we tell you how *wonderful* this book is you might think we were
  74044. X   bragging, so let's just call it:  THE definitive companion to Fractint!
  74045. X
  74046. XWEGNER, Timothy & PETERSON, Mark & TYLER, Bert, & Branderhorst, Pieter:
  74047. X   "Fractals for Windows," Waite Group Press, 1992.\
  74048. X   This book is to Winfract (the Windows version of Fractint) what
  74049. X   "Fractals for Windows" is to Fractint.
  74050. X;
  74051. X;
  74052. X~Topic=Other Programs
  74053. X
  74054. XWINFRACT. Bert Tyler has ported Fractint to run under Windows 3!  The same
  74055. Xunderlying code is used, with a Windows user interface.  Winfract has
  74056. Xalmost all the functionality of Fractint - the biggest difference is the
  74057. Xabsence of a zillion weird video modes.  Fractint for DOS will continue to
  74058. Xbe the definitive version.  Winfract is available from CompuServe in
  74059. XGRAPHDEV Lib 4, as WINFRA.ZIP (executable) and WINSRC.ZIP (source).
  74060. X
  74061. X
  74062. XPICLAB, by Lee Crocker - a freeware image manipulation utility available
  74063. Xfrom Compuserve in PICS Lib 10, as PICLAB.EXE.    PICLAB can do very
  74064. Xsophisticated resizing and color manipulation of GIF and TGA files.  It
  74065. Xcan be used to reduce 24 bit TGA files generated with the Fractint
  74066. X"lightname" option to GIF files.
  74067. X
  74068. X~OnlineFF
  74069. X
  74070. X~Label=@FDESIGN
  74071. XFDESIGN, by Doug Nelson (CIS ID 70431,3374) - a freeware IFS fractal
  74072. Xgenerator available from Compuserve in GRAPHDEV Lib 4, and probably on your
  74073. Xlocal BBS.  This program requires a VGA adapter and a Microsoft-compatible
  74074. Xmouse, and a floating point coprocessor is highly recommended.    It
  74075. Xgenerates IFS fractals in a *much* more intuitive fashion than Fractint.
  74076. XIt can also (beginning with version 3.0) save its IFS formulas in
  74077. XFractint-style .IFS files.
  74078. X
  74079. X~Label=@ACROSPIN
  74080. XACROSPIN, by David Parker - An inexpensive commercial program that reads
  74081. Xan object definition file and creates images that can be rapidly rotated
  74082. Xin three dimensions. The Fractint "orbitsave=yes" option creates files that
  74083. Xthis program can read for orbit-type fractals and IFS fractals. Contact:
  74084. X   David Parker             801-966-2580\
  74085. X   P O Box 26871            800-227-6248\
  74086. X   Salt Lake City, UT  84126-0871
  74087. X;
  74088. X;
  74089. X~Topic=Revision History
  74090. X
  74091. X  Please select one of:
  74092. X
  74093. X      {Version 17}
  74094. X
  74095. X      {Version 16}
  74096. X
  74097. X      {Version 15}
  74098. X
  74099. X      {Versions 12 through 14}
  74100. X
  74101. X      {Versions  1 through 11}
  74102. X;
  74103. X~Topic=Version 17
  74104. X
  74105. XVersion 17.2, 3/92
  74106. X
  74107. X - Fixed a bug which caused Fractint to hang when a Continuous Potential\
  74108. X   Bailout value was set (using the 'Y') screen and then the 'Z' screen\
  74109. X   was activated.\
  74110. X - fixed a bug which caused "batch=yes" runs to abort whenever any\
  74111. X   key was pressed.\
  74112. X - bug-fixes in the Stereo3D/Targa logic from Marc Reinig.\
  74113. X - Fractint now works correctly again on FPU-less 8088s when\
  74114. X   zoomed deeply into the Mandelbrot/Julia sets\
  74115. X - The current image is no longer marked as "not resumable" on a\
  74116. X   Shell-To-Dos ("D") command.\
  74117. X - fixed a bug which prevented the "help" functions from working\
  74118. X   properly during fractal-type selection for some fractal types.\
  74119. X
  74120. XVersion 17.1, 3/92
  74121. X
  74122. X - fixed a bug which caused PCs with no FPU to lock up when they attempted\
  74123. X   to use some fractal types.\
  74124. X - fixed a color-cycling bug which caused the palette to single-step \
  74125. X   when you pressed ESCAPE to exit color-cycling.\
  74126. X - fixed the action of the '<' and '>' keys during color-cycling.\
  74127. X
  74128. XVersion 17.0, 2/92
  74129. X
  74130. X- New fractal types (but of course!): 
  74131. X
  74132. XLyapunov Fractals from Roy Murphy (see {Lyapunov Fractals} for details)
  74133. X
  74134. X'BifStewart' (Stewart Map bifurcation) fractal type and new bifurcation
  74135. Xparameters (filter cycles, seed population) from Kevin Allen.
  74136. X
  74137. XLorenz3d1, Lorenz3d2, and Lorenz3d3 fractal types from Scott Taylor.
  74138. XNote that a bug in the Lorenz3d1 fractal prevents zooming-out from
  74139. Xworking with it at the moment.
  74140. X
  74141. XMartin, Circle, and Hopalong (culled from Dewdney's Scientific American
  74142. XArticle)
  74143. X
  74144. XLots of new entries in fractint.par.
  74145. X
  74146. XNew ".L" files (TILING.L, PENROSE.L)
  74147. X
  74148. XNew 'rand()' function added to the 'type=formula' parser
  74149. X
  74150. X- New fractal generation options:
  74151. X
  74152. XNew 'Tesseral' calculation algorithm (use the 'X' option list to
  74153. Xselect it) from  Chris Lusby Taylor.
  74154. X
  74155. XNew 'Fillcolor=' option shows off Boundary Tracing and Tesseral structure
  74156. X
  74157. Xinside=epscross and inside=startrail options taken from a paper by
  74158. XKenneth Hooper, with credit also to Clifford Pickover
  74159. X
  74160. XNew Color Postscript Printer support from Scott Taylor.
  74161. X
  74162. XSound= command now works with <O>rbits and <R>ead commands.
  74163. X
  74164. XNew 'orbitdelay' option in X-screen and command-line interface
  74165. X
  74166. XNew "showdot=nn" command-line option that displays the pixel currently
  74167. Xbeing worked on using the specified color value (useful for those lloooonngg
  74168. Ximages being calculated using solid guessing - "where is it now?").
  74169. X
  74170. XNew 'exitnoask=yes' commandline/SSTOOLS.INI option to avoid the final
  74171. X"are you sure?" screen
  74172. X
  74173. XNew plasma-cloud options.  The interface at the moment (documented here and
  74174. X  here only because it might change later) lets you:\
  74175. X  - use an alternate drawing algorithm that gives you an earlier preview\
  74176. X    of the finished image.
  74177. X  - re-generate your favorite plasma cloud (say, at a higher resolution)
  74178. X    by forcing a re-select of the random seed.\
  74179. X
  74180. XNew 'N' (negative palette) option from Scott Taylor - the documentation at
  74181. Xthis point is:    Pressing 'N' while in the palette editor will invert
  74182. Xeach color. It will convert only the current color if it is in 'x' mode,
  74183. Xa range if in 'y' mode, and every color if not in either the 'x' or 'y' mode.
  74184. X
  74185. X- Speedups:
  74186. X
  74187. XNew, faster floating-point Mandelbrot/Julia set code from Wesley Loewer,
  74188. XFrank Fussenegger and Chris Lusby Taylor (in separate contributions).
  74189. X
  74190. XFaster non-386 integer Mandelbrot code from Chris Lusby Taylor, Mike Gelvin
  74191. Xand Bill Townsend (in separate contributions)
  74192. X
  74193. XNew integer Lsystems logic from Nicholas Wilt
  74194. X
  74195. XFinite-Attractor fixups and Lambda/mandellambda speedups from Kevin Allen.
  74196. X
  74197. XGIF Decoder speedups from Mike Gelvin
  74198. X
  74199. X- Bug-fixes and other enhancements:
  74200. X
  74201. XFractint now works with 8088-based AMSTRAD computers.
  74202. X
  74203. XThe video logic is improved so that (we think) fewer video boards will need
  74204. X"textsafe=save" for correct operation.
  74205. X
  74206. XFixed a bug in the VESA interface which effectively messed up adapters
  74207. Xwith unusual VESA-style access, such as STB's S3 chipset.
  74208. X
  74209. XFixed a color-cycling bug that would at times restore the wrong colors
  74210. Xto your image if you exited out of color-cycling, displayed a 'help'
  74211. Xscreen, and then returned to the image.
  74212. X
  74213. XFixed the XGA video logic so that its 256-color modes use the same 
  74214. Xdefault 256 colors as the VGA adapter's 320x200x256 mode.
  74215. X
  74216. XFixed the 3D bug that caused bright spots on surfaces
  74217. Xto show as black blotches of color 0 when using a light source.
  74218. X
  74219. XFixed an image-generation bug that sometimes caused image regeneration
  74220. Xto restart even if not required if the image had been zoomed in
  74221. Xto the point that floating-point had been automatically activated.
  74222. X
  74223. XAdded autodetection and 640x480x256 support for the Compaq Advanced VGA
  74224. XSystems board - I wonder if it works?
  74225. X
  74226. XAdded VGA register-compatible 320x240x256 video mode.
  74227. X
  74228. XFixed the "logmap=yes" option to (again) take effect for continuous potential
  74229. Ximages.  This was broken in version 15.x.
  74230. X
  74231. XThe colors for the floating-point algorithm of the Julia fractal
  74232. Xnow match the colors for the integer algorithm.
  74233. X
  74234. XIf the GIF Encoder (the "Save" command) runs out of disk space, it now
  74235. Xtells you about it.
  74236. X
  74237. XIf you select both the boundary-tracing algorithm and either "inside=0"
  74238. Xor "outside=0", the algorithm will now give you an error message instead
  74239. Xof silently failing.
  74240. X
  74241. XUpdated 3D logic from Marc Reinig.
  74242. X
  74243. XMinor changes to permit IFS3D fractal types to be handled properly
  74244. Xusing the "B" command.
  74245. X
  74246. XMinor changes to the "Obtaining the latest Source" section to refer
  74247. Xto BBS access (Peter Longo's) and mailed diskettes (the Public (Software)
  74248. XLibrary).
  74249. X
  74250. X~Topic=Version 16
  74251. X
  74252. XVersion 16.12, 8/91
  74253. X
  74254. X  Fix to cure some video problems reported with Amstrad
  74255. X     8088/8086-based PCs.
  74256. X
  74257. XVersion 16.11, 7/91
  74258. X
  74259. X  SuperVGA Autodetect fixed for older Tseng 3000 adapters.\
  74260. X
  74261. X  New "adapter=" options to force the selection of specific SuperVGA
  74262. X     adapter types.  See {Video Parameters} for details.\
  74263. X
  74264. X  Integer/Floating-Point math toggle is changed only temporarily
  74265. X     if floating-point math is forced due to deep zooming.\
  74266. X
  74267. X  Fractint now survives being modified by McAfee's "SCAN /AV" option.\
  74268. X
  74269. X  Bug Fixes for Acrospin interface, 3D "Light Source Before
  74270. X     Transformation" fill type, and GIF decoder.\
  74271. X
  74272. X  New options in the <Z> parameters screen allow you to directly
  74273. X     enter image coordinates.\
  74274. X
  74275. X  New "inside=zmag" and "outside=real|imag|mult|summ" options.\
  74276. X
  74277. X  The GIF Decoder now survives reading GIF files with a local color map.\
  74278. X  Improved IIT Math Coprocessor support.\
  74279. X
  74280. X  New color-cycling single-step options, '<' and '>'.\
  74281. X
  74282. XVersion 16.0, 6/91
  74283. X
  74284. X  Integrated online help / fractint.doc system from Ethan Nagel.
  74285. X    To create a printable fractint.doc file see {Startup Parameters}.
  74286. X
  74287. X  Over 350 screens of online help! Try pressing <F1> just about anywhere!\
  74288. X
  74289. X  New "autokey" feature.  Type "demo" to run the included demo.bat and
  74290. X    demo.key files for a great demonstration of Fractint.
  74291. X    See {Autokey Mode} for details.
  74292. X
  74293. X  New <@> command executes a saved set of commands.  The <b> command has
  74294. X    changed to write the current image's parameters as a named set of
  74295. X    commands in a structured file.  Saved sets of commands can subsequently
  74296. X    be executed with the <@> command.
  74297. X    See {Parameter Save/Restore Commands}.
  74298. X    A default "fractint.par" file is included with the release.
  74299. X
  74300. X  New <z> command allows changing fractal type-specific parameters without
  74301. X    going back through the <t> (fractal type selection) screen.
  74302. X
  74303. X  Ray tracer interface from Marc Reinig, generates 3d transform output for a
  74304. X    number of ray tracers; see {"Interfacing with Ray Tracing Programs"}
  74305. X
  74306. X  Selection of video modes and structure of "fractint.cfg" have changed. If
  74307. X    you have a customized fractint.cfg file, you'll have to rebuild it based
  74308. X    on this release's version. You can customize the assignment of your
  74309. X    favorite video modes to function keys; see {Video Mode Function Keys}.
  74310. X    <delete> is a new command key which goes directly to video mode selection.
  74311. X
  74312. X  New "cyclerange" option (command line and <y> options screen) from Hugh
  74313. X    Steele. Limits color cycling to a specified range of colors.
  74314. X
  74315. X  Improved {Distance Estimator Method} algorithm from Phil Wilson.\
  74316. X
  74317. X  New "ranges=" option from Norman Hills.
  74318. X    See {Logarithmic Palettes and Color Ranges} for details.
  74319. X
  74320. X  type=formula definitions can use "variable functions" to select
  74321. X    sin, cos, sinh, cosh, exp, log, etc at run time;
  74322. X    new built-ins tan, tanh, cotan, cotanh, and flip
  74323. X    are available with type=formula; see Type {Formula}
  74324. X
  74325. X  New <w> command in palette editing mode to convert image to greyscale\
  74326. X
  74327. X  All "fn" fractal types (e.g. fn*fn) can now use new functions tan, tanh,
  74328. X    cotan, cotanh, recip, and ident; bug in prior cos function fixed, new
  74329. X    function cosxx (conjugate of cos) is the old erroneous cos calculation
  74330. X
  74331. X  New L-Systems from Herb Savage\
  74332. X  New IFS types from Alex Matulich\
  74333. X  Many new formulas in fractint.frm, including a large group from
  74334. X    JM Richard-Collard
  74335. X  Generalized type manzpwr with complex exponent per Lee Skinner's request\
  74336. X  Initial orbit parameter added to Gingerbreadman fractal type\
  74337. X
  74338. X  New color maps (neon, royal, volcano, blues, headache) from Daniel Egnor\
  74339. X
  74340. X  IFS type has changed to use a single file containing named entries
  74341. X    (instead of a separate xxx.ifs file per type); the <z> command brings up
  74342. X    IFS editor (used to be <i> command).  See {=HT_IFS Barnsley IFS Fractals}.
  74343. X
  74344. X  Much improved support for PaintJet printers; see {PaintJet Parameters}\
  74345. X
  74346. X  From Scott Taylor:\
  74347. X    Support for plotters using HP-GL; see {Plotter Parameters}\
  74348. X    Lots of new PostScript halftones; see {PostScript Parameters}\
  74349. X    "printer=PS[L]/0/..." for full page PostScript; see {PostScript Parameters}\
  74350. X    Option to drive printer ports directly (faster); see {Printer Parameters}\
  74351. X    Option to change printer end of line control chars; see {Printer Parameters}
  74352. X
  74353. X  Support for XGA video adapter\
  74354. X  Support for Targa+ video adapter\
  74355. X  16 color VGA mode enhancements:\
  74356. X    Now use the first 16 colors of .map files to be more predictable\
  74357. X    Palette editor now works with these modes\
  74358. X    Color cycling now works properly with these modes
  74359. X  Targa video adapter fixes; Fractint now uses (and requires) the "targa"
  74360. X    and "targaset" environment variables for Targa systems
  74361. X  "vesadetect=no" parameter to bypass use of VESA video driver; try
  74362. X    this if you encounter video problems with a VESA driver
  74363. X  Upgraded video adapter detect and handling from John Bridges; autodetect
  74364. X    added for NCR, Trident 8900, Tseng 4000, Genoa (this code
  74365. X    is from a beta release of VGAKIT, we're not sure it all works yet)
  74366. X
  74367. X  Zoom box is included in saved/printed images (but, is not recognized as
  74368. X    anything special when such an image is restored)
  74369. X
  74370. X  The colors numbers reserved by the palette editor are now selectable with
  74371. X    the new <v> palette editing mode command
  74372. X
  74373. X  Option to use IIT floating point chip's special matrix arithmetic for
  74374. X    faster 3D transforms; see "fpu=" in {Startup Parameters}
  74375. X
  74376. X  Disk video cache increased to 64k; disk video does less seeking when
  74377. X    running to real disk
  74378. X  Faster floating point code for 287 and higher fpus, for types mandel,
  74379. X    julia, barnsleyj1/m1/j2/m2, lambda, manowar, from Chuck Ebbert
  74380. X
  74381. X  "filename=.xxx" can be used to set default <r> function file mask\
  74382. X
  74383. X  Selection of type formula or lsys now goes directly to entry selection
  74384. X    (file selection step is now skipped); to change to a different file, use
  74385. X    <F6> from the entry selection screen
  74386. X
  74387. X  Three new values have been added to the textcolors= parameter; if you use
  74388. X    this parameter you should update it by inserting values for the new 6th,
  74389. X    7th, 9th, and 13th positions; see "textcolors=" in {Color Parameters}
  74390. X
  74391. X  The formula type's imag() function has changed to return the result as
  74392. X    a real number
  74393. X
  74394. X  Fractal type-specific parameters (entered after selecting a new fractal
  74395. X    type with <T>) now restart at their default values each time you select
  74396. X    a new fractal type
  74397. X
  74398. X  Floating point input fields can now be entered in scientific notation (e.g.
  74399. X    11.234e-20). Entering the letters "e" and "p" in the first column causes
  74400. X    the numbers e=2.71828... and pi=3.14159... to be entered.
  74401. X
  74402. X  New option "orbitsave=yes" to create files for Acrospin for
  74403. X    some types (see {Barnsley IFS Fractals}, {Orbit Fractals},
  74404. X    {=@ACROSPIN Acrospin})
  74405. X
  74406. X  Bug fixes:\
  74407. X    Problem with Hercules adapter auto-detection repaired.\
  74408. X    Problems with VESA video adapters repaired (we're not sure we've got them
  74409. X      all yet...)\
  74410. X    3D transforms fixed to work at high resolutions (> 1000 dots).\
  74411. X    3D parameters no longer clobbered when restoring non-3D images.\
  74412. X    L-Systems fixed to not crash when order too high for available memory.\
  74413. X    PostScript EPS file fixes.\
  74414. X    Bad leftmost pixels with floating point at 2048 dot resolution fixed.\
  74415. X    3D transforms fixed to use current <x> screen float/integer setting.\
  74416. X    Restore of images using inversion fixed.\
  74417. X    Error in "cos" function (used with "fn" type fractals) fixed; prior
  74418. X      incorrect function still available as "cosxx" for compatibility
  74419. X
  74420. X  Old 3D=nn/nn/nn/... form of 3D transform parameters no longer supported\
  74421. X
  74422. X  Fractint source code now Microsoft C6.00A compatible.
  74423. X;
  74424. X;
  74425. X~Topic=Version 15
  74426. X
  74427. XVersion 15.11, 3/91, companion to Fractal Creations, not for general
  74428. Xrelease
  74429. X
  74430. X  Autokey feature, IIT fpu support, and some bug fixes publicly released in
  74431. X  version 16.
  74432. X
  74433. X
  74434. XVersion 15 and 15.1, 12/90
  74435. X
  74436. X  New user interface! Enjoy! Some key assignments have changed and some have
  74437. X    been removed.
  74438. X  New palette editing from Ethan Nagel.\
  74439. X  Reduced memory requirements - Fractint now uses overlays and will run on a
  74440. X    512K machine.
  74441. X  New <v>iew command: use to get small window for fast preview, or to setup
  74442. X    an image which will eventually be rendered on hard copy with different
  74443. X    aspect ratio
  74444. X  L-System fractal type from Adrian Mariano\
  74445. X  Postscript printer support from Scott Taylor\
  74446. X  Better Tandy video support and faster CGA video from Joseph A Albrecht\
  74447. X  16 bit continuous potential files have changed considerably;    see the
  74448. X    Continuous Potential section for details.  Continuous potential is now
  74449. X    resumable.
  74450. X  Mandelbrot calculation is faster again (thanks to Mike Gelvin) - double
  74451. X    speed in 8086 32 bit case
  74452. X  Compressed log palette and sqrt palette from Chuck Ebbert\
  74453. X  Calculation automatically resumes whenever current image is resumable and
  74454. X    is not paused for a visible reason.
  74455. X  Auto increment of savename changed to be more predictable\
  74456. X  New video modes:\
  74457. X    trident 1024x768x256 mode\
  74458. X    320x480x256 tweak mode (good for reduced 640x480 viewing)\
  74459. X    changed NEC GB-1, hopefully it works now\
  74460. X  Integer mandelbrot and julia now work with periodicitycheck\
  74461. X  Initial zoombox color auto-picked for better contrast (usually)\
  74462. X  New adapter=cga|ega|mcga|vga for systems having trouble with auto-detect\
  74463. X  New textsafe=no|yes for systems having trouble with garbled text mode\
  74464. X  <r> and <3> commands now present list of video modes to pick from; <r> can
  74465. X    reduce a non-standard or unviewable image size.
  74466. X  Diffusion fractal type is now resumable after interrupt/save\
  74467. X  Exitmode=n parameter, sets video mode to n when exiting from fractint\
  74468. X  When savetime is used with 1 and 2 pass and solid guessing, saves are
  74469. X    deferred till the beginning of a new row, so that no calculation time is
  74470. X    lost.
  74471. X  3d photographer's mode now allows the first image to be saved to disk\
  74472. X  textcolors=mono|12/34/56/... -- allows setting user interface colors\
  74473. X  Code (again!) compilable under TC++ (we think!)\
  74474. X  .TIW files (from v9.3) are no longer supported as input to 3D
  74475. X    transformations
  74476. X  bug fixes:\
  74477. X    multiple restores (msc 6.0, fixed in 14.0r)\
  74478. X    repeating 3d loads problem; slow 3d loads of images with float=yes\
  74479. X    map= is now a real substitute for default colors\
  74480. X    starfield and julibrot no longer cause permanent color map replacement\
  74481. X    starfield parameters bug fix - if you couldn't get the starfield
  74482. X    parameters to do anything interesting before, try again with this\
  74483. X    release\
  74484. X    Newton and newtbasin orbit display fixed
  74485. X
  74486. X Version 15.1:
  74487. X
  74488. X  Fixed startup and text screen problems on systems with VESA compliant
  74489. X    video adapters.
  74490. X  New textsafe=save|bios options.\
  74491. X  Fixes for EGA with monochrome monitor, and for Hercules Graphics Card.
  74492. X    Both should now be auto-detected and operate correctly in text modes.
  74493. X    Options adapter=egamono and adapter=hgc added.
  74494. X  Fixed color L-Systems to not use color 0 (black).\
  74495. X  PostScript printing fix.
  74496. X;
  74497. X~Topic=Versions 12 through 14
  74498. X
  74499. XVersion 14, 8/90
  74500. X
  74501. X  LAST MINUTE NEWS FLASH!\
  74502. X    Compuserve announces the GIF89a on August 1, 1990, and Fractint supports
  74503. X    it on August 2! GIF files can now contain fractal information!  Fractint
  74504. X    now saves its files in the new GIF89a format by default, and uses .GIF
  74505. X    rather than .FRA as a default filetype.  Note that Fractint still
  74506. X    *looks* for a .FRA file on file restores if it can't find a .GIF file,
  74507. X    and can be coerced into using the old GIF87a format with the new
  74508. X    'gif87a=yes' command-line option.
  74509. X
  74510. X  Pieter Branderhorst mounted a major campaign to get his name in lights:\
  74511. X  Mouse interface:  Diagonals, faster movement, improved feel. Mouse button
  74512. X    assignments have changed - see the online help.
  74513. X  Zoom box enhancements:  The zoom box can be rotated, stretched, skewed,
  74514. X    and panned partially offscreen.  See "More Zoom Box Commands".
  74515. X  FINALLY!! You asked for it and we (eventually, by talking Pieter into it
  74516. X    [actually he grabbed it]) did it!  Images can be saved before
  74517. X    completion, for a subsequent restore and continue.    See "Interrupting
  74518. X    and Resuming" and "Batch Mode".
  74519. X  Off-center symmetry:    Fractint now takes advantage of x or y axis symmetry
  74520. X    anywhere on the screen to reduce drawing time.
  74521. X  Panning:  If you move an image up, down, left, or right, and don't change
  74522. X    anything else, only the new edges are calculated.
  74523. X  Disk-video caching - it is now possible, reasonable even, to do most
  74524. X    things with disk video, including solid guessing, 3d, and plasma.
  74525. X  Logarithmic palette changed to use all colors.  It now matches regular
  74526. X    palette except near the "lake".  "logmap=old" gets the old way.
  74527. X  New "savetime=nnn" parameter to save checkpoints during long calculations.\
  74528. X  Calculation time is shown in <Tab> display.
  74529. X
  74530. X  Kevin C Allen    Finite Attractor, Bifurcation Engine, Magnetic fractals...\
  74531. X  Made Bifurcation/Verhulst into a generalized Fractal Engine (like
  74532. X    StandardFractal, but for Bifurcation types), and implemented periodicity
  74533. X    checking for Bifurcation types to speed them up.
  74534. X  Added Integer version of Verhulst Bifurcation (lots faster now). Integer
  74535. X    is the default.  The Floating-Point toggle works, too.
  74536. X  Added NEW Fractal types BIFLAMBDA, BIF+SINPI, and BIF=SINPI. These are
  74537. X    Bifurcation types that make use of the new Engine. Floating-
  74538. X    point/Integer toggle is available for BIFLAMBDA. The SINPI types are
  74539. X    Floating-Point only, at this time.
  74540. X  Corrected the generation of the MandelLambda Set.  Sorry, but it's always
  74541. X    been wrong (up to v 12, at least).    Ask Mandelbrot !
  74542. X  Added NEW Fractal types MAGNET1M, MAGNET1J, MAGNET2M, MAGNET2J from "The
  74543. X    Beauty of Fractals".  Floating-Point only, so far, but what do you
  74544. X    expect with THESE formulae ?!
  74545. X  Added new symmetry types XAXIS NOIMAG and XAXIS NOREAL, required by the
  74546. X    new MAGNETic Fractal types.
  74547. X  Added Finite Attractor Bailout (FAB) logic to detect when iterations are
  74548. X    approaching a known finite attractor. This is required by the new
  74549. X    MAGNETic Fractal types.
  74550. X  Added Finite Attractor Detection (FAD) logic which can be used by *SOME*
  74551. X    Julia types prior to generating an image, to test for finite attractors,
  74552. X    and find their values, for use by FAB logic. Can be used by the new
  74553. X    MAGNETic Fractal Types, Lambda Sets, and some other Julia types too.
  74554. X
  74555. X  Mike Burkey sent us new tweaked video modes:\
  74556. X    VGA     - 400x600x256   376x564x256   400x564x256\
  74557. X    ATI VGA - 832x612x256
  74558. X  New HP Paintjet support from Chris Martin\
  74559. X  New "FUNCTION=" command to allow substition of different transcendental
  74560. X    functions for variables in types (allows one type with four of these
  74561. X    variables to represent 7*7*7*7 different types!
  74562. X  ALL KINDS of new fractal types, some using "FUNCTION=": fn(z*z), fn*fn,
  74563. X    fn*z+z, fn+fn, sqr(1/fn), sqr(fn), spider, tetrate, and Manowar. Most of
  74564. X    these are generalizations of formula fractal types contributed by Scott
  74565. X    Taylor and Lee Skinner.
  74566. X  Distance Estimator logic can now be applied to many fractal types using
  74567. X    distest= option. The types "demm" and "demj" have been replaced by
  74568. X    "type=mandel distest=nnn" and "type=julia distest=nnn"
  74569. X  Added extended memory support for diskvideo thanks to Paul Varner\
  74570. X  Added support for "center and magnification" format for corners.\
  74571. X  Color 0 is no longer generated except when specifically requested with
  74572. X    inside= or outside=.
  74573. X  Formula name is now included in <Tab> display and in <S>aved images.\
  74574. X  Bug fixes - formula type and diskvideo, batch file outside=-1 problem.\
  74575. X  Now you can produce your favorite fractal terrains in full color instead
  74576. X    of boring old monochrome! Use the fullcolor option in 3d! Along with a
  74577. X    few new 3D options.
  74578. X  New "INITORBIT=" command to allow alternate Mandelbrot set orbit
  74579. X    initialization.
  74580. X
  74581. X
  74582. XVersion 13.0, 5/90
  74583. X
  74584. X  F1 was made the help key.\
  74585. X    Use F1 for help\
  74586. X    Use F9 for EGA 320x200x16 video mode\
  74587. X    Use CF4 for EGA 640x200x16 mode (if anybody uses that mode)\
  74588. X  Super-Solid-guessing (three or more passes) from Pieter Branderhorst
  74589. X    (replaces the old solid-guessing mode)
  74590. X  Boundary Tracing option from David Guenther ("fractint passes=btm", or use
  74591. X    the new 'x' options screen)
  74592. X  "outside=nnn" option sets all points not "inside" the fractal to color
  74593. X    "nnn" (and generates a two-color image).
  74594. X  'x' option from the main menu brings up a full-screen menu of many popular
  74595. X    options and toggle switches
  74596. X  "Speed Key" feature for fractal type selection (either use the cursor keys
  74597. X    for point-and-shoot, or just start typing the name of your favorite
  74598. X    fractal type)
  74599. X  "Attractor" fractals (Henon, Rossler, Pickover, Gingerbread)\
  74600. X  Diffusion fractal type by Adrian Mariano\
  74601. X  "type=formula" formulas from Scott Taylor and Lee H. Skinner.\
  74602. X  "sound=" options for attractor fractals.  Sound=x  plays speaker tones
  74603. X    according to the 'x' attractor value  Sound=y  plays speaker tones
  74604. X    according to the 'y' attractor value.  Sound=z  plays speaker tones
  74605. X    according to the 'z' attractor value  (These options are best invoked
  74606. X    with the floating-point algorithm flag set.)
  74607. X  "hertz=" option for adjusting the "sound=x/y/z" output.\
  74608. X  Printer support for color printers (printer=color) from Kurt Sowa\
  74609. X  Trident 4000 and Oak Technologies SuperVGA support from John Bridges\
  74610. X  Improved 8514/A support (the zoom-box keeps up with the cursor keys now!)\
  74611. X  Tandy 1000 640x200x16 mode from Brian Corbino (which does not, as yet,
  74612. X    work with the F1(help) and TAB functions)
  74613. X  The Julibrot fractal type and the Starmap option now automatically verify
  74614. X    that they have been selected with a 256-color palette, and search for,
  74615. X    and use, the appropriate GLASSESn.MAP or ALTERN.MAP palette map when
  74616. X    invoked.  *You* were supposed to be doing that manually all along, but
  74617. X    *you* probably never read the docs, huh?
  74618. X  Bug Fixes:\
  74619. X    TAB key now works after R(estore) commands\
  74620. X    PS/2 Model 30 (MCGA) adapters should be able to select 320x200x256 mode
  74621. X      again (we think)\
  74622. X    Everex video adapters should work with the Autodetect modes again (we
  74623. X      think)
  74624. X
  74625. X
  74626. XVersion 12.0, 3/90
  74627. X
  74628. X  New SuperVGA Autodetecting and VESA Video modes (you tell us the
  74629. X    resolution you want, and we'll figure out how to do it)
  74630. X  New Full-Screen Entry for most prompting\
  74631. X  New Fractal formula interpreter ('type=formula') - roll your own fractals
  74632. X    without using a "C" compiler!
  74633. X  New 'Julibrot' fractal type\
  74634. X  Added floating point option to all remaining fractal types.\
  74635. X  Real (funny glasses) 3D - Now with "real-time" lorenz3D!!\
  74636. X  Non-Destructive <TAB> - Check out what your fractal parameters are without
  74637. X    stopping the generation of a fractal image
  74638. X  New Cross-Hair mode for changing individual palette colors (VGA only)\
  74639. X  Zooming beyond the limits of Integer algorithms (with automatic switchover
  74640. X    to a floating-point algorithm when you zoom in "too far")
  74641. X  New 'inside=bof60', 'inside=bof61' ("Beauty of Fractals, Page nn") options\
  74642. X  New starmap ('a' - for astrology? astronomy?) transformation option\
  74643. X  Restrictions on the options available when using Expanded Memory
  74644. X    "Disk/RAM" video mode have been removed
  74645. X  And a lot of other nice little clean-up features that we've already
  74646. X    forgotten that we've added...
  74647. X  Added capability to create 3D projection images (just barely) for people
  74648. X    with 2 or 4 color video boards.
  74649. X;
  74650. X~Topic=Versions  1 through 11
  74651. X
  74652. XVersion 11.0, 1/90
  74653. X
  74654. X  More fractal types\
  74655. X    mandelsinh/lambdasinh     mandelcosh/lambdacosh\
  74656. X    mansinzsqrd/julsinzsqrd     mansinexp/julsinexp\
  74657. X    manzzprw/julzzpwr         manzpower/julzpower\
  74658. X    lorenz (from Rob Beyer)     lorenz3d\
  74659. X    complexnewton         complexbasin\
  74660. X    dynamic             popcorn\
  74661. X  Most fractal types given an integer and a floating point algorithm.
  74662. X    "Float=yes" option now determines whether integer or floating-point
  74663. X    algorithms are used for most fractal types.  "F" command toggles the use
  74664. X    of floating-point algorithms, flagged in the <Tab> status display
  74665. X  8/16/32/../256-Way decomposition option (from Richard Finegold)\
  74666. X  "Biomorph=", "bailout=", "symmetry="  and "askvideo=" options\
  74667. X  "T(ransform)" option in the IFS editor lets you select 3D options (used
  74668. X    with the Lorenz3D fractal type)
  74669. X  The "T(ype)" command uses a new "Point-and-Shoot" method of selecting
  74670. X    fractal types rather than prompting you for a type name
  74671. X  Bug fixes to continuous-potential algorithm on integer fractals, GIF
  74672. X    encoder, and IFS editor
  74673. X
  74674. X
  74675. XVersion 10.0, 11/89
  74676. X
  74677. X  Barnsley IFS type (Rob Beyer)\
  74678. X  Barnsley IFS3D type\
  74679. X  MandelSine/Cos/Exp type\
  74680. X  MandelLambda/MarksLambda/Unity type\
  74681. X  BarnsleyM1/J1/M2/J2/M3/J3 type\
  74682. X  Mandel4/Julia4 type\
  74683. X  Sierpinski gasket type\
  74684. X  Demm/Demj and bifurcation types (Phil Wilson), "test" is "mandel" again\
  74685. X  <I>nversion command for most fractal types\
  74686. X  <Q>uaternary decomposition toggle and "DECOMP=" argument\
  74687. X  <E>ditor for Barnsley IFS parameters\
  74688. X  Command-line options for 3D parameters\
  74689. X  Spherical 3D calculations 5x faster\
  74690. X  3D now clips properly to screen edges and works at extreme perspective\
  74691. X  "RSEED=" argument for reproducible plasma clouds\
  74692. X  Faster plasma clouds (by 40% on a 386)\
  74693. X  Sensitivity to "continuous potential" algorithm for all types except
  74694. X    plasma and IFS
  74695. X  Palette-map <S>ave and Restore (<M>) commands\
  74696. X  <L>ogarithmic and <N>ormal palette-mapping commands and arguments\
  74697. X  Maxiter increased to 32,000 to support log palette maps\
  74698. X  .MAP and .IFS files can now reside anywhere along the DOS path\
  74699. X  Direct-video support for Hercules adapters (Dean Souleles)\
  74700. X  Tandy 1000 160x200x16 mode (Tom Price)\
  74701. X  320x400x256 register-compatible-VGA "tweaked" mode\
  74702. X  ATI VGA Wonder 1024x768x16 direct-video mode (Mark Peterson)\
  74703. X  1024x768x16 direct-video mode for all supported chipsets\
  74704. X  Tseng 640x400x256 mode\
  74705. X  "Roll-your-own" video mode 19\
  74706. X  New video-table "hot-keys" eliminate need for enhanced keyboard to access
  74707. X    later entries
  74708. X
  74709. X
  74710. XVersion 9.3, 8/89
  74711. X
  74712. X  <P>rint command and "PRINTER=" argument (Matt Saucier)\
  74713. X  8514/A video modes (Kyle Powell)\
  74714. X  SSTOOLS.INI sensitivity and '@THISFILE' argument\
  74715. X  Continuous-potential algorithm for Mandelbrot/Julia sets\
  74716. X  Light source 3D option for all fractal types\
  74717. X  "Distance estimator" M/J method (Phil Wilson) implemented as "test" type\
  74718. X  LambdaCosine and LambdaExponent types\
  74719. X  Color cycling mode for 640x350x16 EGA adapters\
  74720. X  Plasma clouds for 16-color and 4-color video modes\
  74721. X  Improved TARGA support (Joe McLain)\
  74722. X  CGA modes now use direct-video read/writes\
  74723. X  Tandy 1000 320x200x16 and 640x200x4 modes (Tom Price)\
  74724. X  TRIDENT chip-set super-VGA video modes (Lew Ramsey)\
  74725. X  Direct-access video modes for TRIDENT, Chips & Technologies, and ATI VGA
  74726. X    WONDER adapters (John Bridges). and, unlike version 9.1, they WORK in
  74727. X    version 9.3!)
  74728. X  "zoom-out" (<Ctrl><Enter>) command\
  74729. X  <D>os command for shelling out\
  74730. X  2/4/16-color Disk/RAM video mode capability and 2-color video modes
  74731. X    supporting full-page printer graphics
  74732. X  "INSIDE=-1" option (treated dynamically as "INSIDE=maxiter")\
  74733. X  Improved <H>elp and sound routines (even a "SOUND=off" argument)\
  74734. X  Turbo-C and TASM compatibility (really!  Would we lie to you?)
  74735. X
  74736. X
  74737. XVersion 8.1, 6/89
  74738. X
  74739. X  <3>D restore-from-disk and 3D <O>verlay commands, "3D=" argument\
  74740. X  Fast Newton algorithm including inversion option (Lee Crocker)\
  74741. X  16-bit Mandelbrot/Julia logic for 386-class speed with non-386 PCs on
  74742. X    "large" images (Mark Peterson)
  74743. X  Restore now loads .GIF files (as plasma clouds)\
  74744. X  TARGA video modes and color-map file options (Joe McLain)\
  74745. X  30 new color-cycling palette options (<Shft><F1> to <Alt><F10>)\
  74746. X  "Disk-video, RAM-video, EMS-video" modes\
  74747. X  Lambda sets now use integer math (with 80386 speedups)\
  74748. X  "WARN=yes" argument to prevent over-writing old .GIF files
  74749. X
  74750. X
  74751. XVersion 7.0, 4/89
  74752. X
  74753. X  Restore from disk (from prior save-to-disk using v. 7.0 or later)\
  74754. X  New types: Newton, Lambda, Mandelfp, Juliafp, Plasma, Lambdasine\
  74755. X  Many new color-cycling options (for VGA adapters only)\
  74756. X  New periodicity logic (Mark Peterson)\
  74757. X  Initial displays recognize (and use) symmetry\
  74758. X  Solid-guessing option (now the default)\
  74759. X  Context-sensitive <H>elp\
  74760. X  Customizable video mode configuration file (FRACTINT.CFG)\
  74761. X  "Batch mode" option\
  74762. X  Improved super-VGA support (with direct video read/writes)\
  74763. X  Non-standard 360 x 480 x 256 color mode on a STANDARD IBM VGA!
  74764. X
  74765. X
  74766. XVersion 6.0, 2/89
  74767. X
  74768. X  32-bit integer math emulated for non-386 processors; FRACT386 renamed
  74769. X    FRACTINT
  74770. X  More video modes
  74771. X
  74772. X
  74773. XVersion 5.1, 1/89
  74774. X
  74775. X  Save to disk\
  74776. X  New! Improved! (and Incompatible!) optional arguments format\
  74777. X  "Correct" initial image aspect ratio\
  74778. X  More video modes
  74779. X
  74780. X
  74781. XVersion 4.0, 12/88
  74782. X
  74783. X  Mouse support (Mike Kaufman)\
  74784. X  Dynamic iteration limits\
  74785. X  Color cycling\
  74786. X  Dual-pass mode\
  74787. X  More video modes, including "tweaked" modes for IBM VGA and register-
  74788. X    compatible adapters
  74789. X
  74790. X
  74791. XVersion 3.1, 11/88
  74792. X
  74793. X  Julia sets
  74794. X
  74795. X
  74796. XVersion 2.1, 10/23/88 (the "debut" on CIS)
  74797. X
  74798. X  Video table\
  74799. X  CPU type detector
  74800. X
  74801. X
  74802. XVersion 2.0, 10/10/88
  74803. X
  74804. X  Zoom and pan
  74805. X
  74806. X
  74807. XVersion 1.0, 9/88
  74808. X
  74809. X  The original, blindingly fast, 386-specific 32-bit integer algorithm
  74810. X;
  74811. X;
  74812. X;
  74813. X~Topic=Version13 to 14 Conversion
  74814. X
  74815. XA number of types in Fractint version 13 and earlier were generalized in
  74816. Xversion 14. We added a "backward compatibility" hook that (hopefully)
  74817. Xautomatically translates these to the new form when the old files are
  74818. Xread. Files may be converted via:
  74819. X
  74820. X   FRACTINT OLDFILE.FRA SAVENAME=NEWFILE.GIF BATCH=YES
  74821. X
  74822. XIn a few cases the biomorph flag was incorrectly set in older files.  In
  74823. Xthat case, add "biomorph=no" to the command line.
  74824. X
  74825. XThis procedure can also be used to convert any *.fra file to the new
  74826. XGIF89a spec, which now allows storage of fractal information.
  74827. X
  74828. X
  74829. X~Format-
  74830. XTYPES CHANGED FROM VERSION 13 -
  74831. X
  74832. X
  74833. XV13 NAME        V14 NAME + PARAMETERS
  74834. X--------        --------------------------------------
  74835. X
  74836. XLOGMAP=YES        LOGMAP=OLD   for identical Logmap type
  74837. X
  74838. XDEMJ            JULIA DISTEST=nnn
  74839. X
  74840. XDEMM            MANDEL DISTEST=nnn
  74841. X
  74842. X            Note: DISTEST also available on many other types
  74843. X
  74844. XMANSINEXP        MANFN+EXP FUNCTION=SIN
  74845. X
  74846. X            Note: New functions for this type are
  74847. X                  cos sinh cosh exp log sqr
  74848. X
  74849. XJULSINEXP        JULFN+EXP FUNCTION=SIN
  74850. X
  74851. X            Note: New functions for this type are
  74852. X                  cos sinh cosh exp log sqr
  74853. X
  74854. XMANSINZSQRD        MANFN+ZSQRD FUNCTION=SQR/SIN
  74855. X
  74856. X            Note: New functions for this type are
  74857. X                  cos sinh cosh exp log sqr
  74858. X
  74859. XJULSINZSQRD        JULFN+ZSQRD FUNCTION=SQR/SIN
  74860. X
  74861. X            Note: New functions for this type are
  74862. X                  cos sinh cosh exp log sqr
  74863. X
  74864. XLAMBDACOS        LAMBDAFN FUNCTION=COS
  74865. X
  74866. XLAMBDACOSH        LAMBDAFN FUNCTION=COSH
  74867. X
  74868. XLAMBDAEXP        LAMBDAFN FUNCTION=EXP
  74869. X
  74870. XLAMBDASINE        LAMBDAFN FUNCTION=SIN
  74871. X
  74872. XLAMBDASINH        LAMBDAFN FUNCTION=SINH
  74873. X
  74874. X            Note: New functions for this type are
  74875. X                  log sqr
  74876. X
  74877. XMANDELCOS        MANDELFN FUNCTION=COS
  74878. X
  74879. XMANDELCOSH        MANDELFN FUNCTION=COSH
  74880. X
  74881. XMANDELEXP        MANDELFN FUNCTION=EXP
  74882. X
  74883. XMANDELSINE        MANDELFN FUNCTION=SIN
  74884. X
  74885. XMANDELSINH        MANDELFN FUNCTION=SINH
  74886. X
  74887. X            Note: New functions for this type are
  74888. X                  log sqr
  74889. X
  74890. XMANDELLAMBDA        MANDELLAMBDA INITORBIT=PIXEL
  74891. X
  74892. XPOPCORN SYMMETRY=NONE    POPCORNJUL
  74893. X
  74894. X-------------------------------------------------------------
  74895. X
  74896. XFormulas from FRACTINT.FRM in version 13
  74897. X
  74898. XMANDELGLASS        MANDELLAMBDA INITORBIT=.5/0
  74899. X
  74900. XINVMANDEL        V13 divide bug may cause some image differences.
  74901. X
  74902. XNEWTON4         V13 divide bug may cause some image differences.
  74903. X
  74904. XSPIDER            V13 divide bug may cause some image differences.
  74905. X
  74906. XMANDELSINE        MANDELFN FUNCTION=SIN BAILOUT=50
  74907. X
  74908. XMANDELCOSINE        MANDELFN FUNCTION=COS BAILOUT=50
  74909. X
  74910. XMANDELHYPSINE        MANDELFN FUNCTION=SINH BAILOUT=50
  74911. X
  74912. XMANDELHYPCOSINE     MANDELFN FUNCTION=COSH BAILOUT=50
  74913. X
  74914. XSCOTTSIN PARAMS=nnn    FN+FN FUNCTION=SIN/SQR BAILOUT=nnn+3
  74915. X
  74916. XSCOTTSINH PARAMS=nnn    FN+FN FUNCTION=SINH/SQR BAILOUT=nnn+3
  74917. X
  74918. XSCOTTCOS PARAMS=nnn    FN+FN FUNCTION=COS/SQR BAILOUT=nnn+3
  74919. X
  74920. XSCOTTCOSH PARAMS=nnn    FN+FN FUNCTION=COSH/SQR BAILOUT=nnn+3
  74921. X
  74922. XSCOTTLPC PARAMS=nnn    FN+FN FUNCTION=LOG/COS BAILOUT=nnn+3
  74923. X
  74924. XSCOTTLPS PARAMS=nnn    FN+FN FUNCTION=LOG/SIN BAILOUT=nnn+3
  74925. X            Note: New functions for this type are
  74926. X            sin/sin sin/cos sin/sinh sin/cosh sin/exp
  74927. X            cos/cos cos/sinh cos/cosh cos/exp
  74928. X            sinh/sinh sinh/cosh sinh/exp sinh/log
  74929. X            cosh/cosh cosh/exp cosh/log
  74930. X            exp/exp exp/log exp/sqr log/log log/sqr sqr/sqr
  74931. X
  74932. XSCOTTSZSA PARAMS=nnn    FN(Z*Z) FUNCTION=SIN BAILOUT=nnn+3
  74933. X
  74934. XSCOTTCZSA PARAMS=nnn    FN(Z*Z) FUNCTION=COS BAILOUT=nnn+3
  74935. X
  74936. X            Note: New functions for this type are
  74937. X            sinh cosh exp log sqr
  74938. X
  74939. XSCOTTZSZZ PARAMS=nnn    FN*Z+Z FUNCTION=SIN BAILOUT=nnn+3
  74940. X
  74941. XSCOTTZCZZ PARAMS=nnn    FN*Z+Z FUNCTION=COS BAILOUT=nnn+3
  74942. X
  74943. X            Note: New functions for this type are
  74944. X            sinh cosh exp log sqr
  74945. X
  74946. XSCOTTSZSB PARAMS=nnn    FN*FN FUNCTION=SIN/SIN BAILOUT=nnn+3
  74947. X
  74948. XSCOTTCZSB PARAMS=nnn    FN*FN FUNCTION=COS/COS BAILOUT=nnn+3
  74949. X
  74950. XSCOTTLTS PARAMS=nnn    FN*FN FUNCTION=LOG/SIN BAILOUT=nnn+3
  74951. X
  74952. XSCOTTLTC PARAMS=nnn    FN*FN FUNCTION=LOG/COS BAILOUT=nnn+3
  74953. X
  74954. X            Note: New functions for this type are
  74955. X            sin/cos sin/sinh sin/cosh sin/exp sin/sqr
  74956. X            cos/sinh cos/cosh cos/exp cos/sqr
  74957. X            sinh/sinh sinh/cosh sinh/exp sinh/log sinh/sqr
  74958. X            cosh/cosh cosh/exp cosh/log cosh/sqr
  74959. X            exp/exp exp/log exp/sqr log/log log/sqr sqr/sqr
  74960. X
  74961. XSCOTTSIC PARAMS=nnn    SQR(1/FN) FUNCTION=COS BAILOUT=nnn+3
  74962. X
  74963. XSCOTTSIS PARAMS=nnn    SQR(1/FN) FUNCTION=SIN BAILOUT=nnn+3
  74964. X
  74965. XTETRATE PARAMS=nnn    TETRATE BAILOUT=nnn+3
  74966. X
  74967. X            Note: New function type sqr(1/fn) with
  74968. X                  sin cos sinh cosh exp log sqr
  74969. X
  74970. X            Note: New function type sqr(fn) with
  74971. X                  sin cos sinh cosh exp log sqr
  74972. X~Format+
  74973. X;
  74974. X;
  74975. X~Data=INTRO_AUTHORS
  74976. X;
  74977. X; FRACTINT intro screen primary authors
  74978. X;
  74979. X Primary Authors
  74980. X Bert Tyler          CompuServe (CIS) ID: [73477,433]
  74981. X Timothy Wegner       CIS ID: [71320,675]   Internet: twegner@mitre.org
  74982. X Mark Peterson          CIS ID: [70441,3353]
  74983. X Pieter Branderhorst  CIS ID: [72611,2257]
  74984. X Contributing Authors
  74985. X
  74986. X
  74987. X; room for 14 authors at a time here
  74988. X
  74989. X
  74990. X
  74991. X
  74992. X
  74993. X
  74994. X
  74995. X
  74996. X
  74997. X
  74998. X
  74999. X
  75000. X SPACEBAR toggles scrolling off/on
  75001. X   Copyright (C) 1990-93 The Stone Soup Group.  Fractint may be freely copied
  75002. X   and distributed but may not be sold.  See help for more information.
  75003. X;
  75004. X;
  75005. X;
  75006. X~Data=INTRO_CREDITS
  75007. X;
  75008. X; FRACTINT intro screen contributing authors.
  75009. X;
  75010. X          ...
  75011. X Michael Abrash   360x480x256, 320x400x256 VGA video modes
  75012. X Joseph Albrecht  Tandy video, CGA video speedup
  75013. X Kevin Allen      kevina@microsoft.com Finite attractor, bifurcation engine
  75014. X Steve Bennett      restore-from-disk logic
  75015. X Rob Beyer      [71021,2074] Barnsley IFS, Lorenz fractals
  75016. X Francois Blais      [70700,446] Lyapunov Fractals, LYAPUNOV.MAP
  75017. X Dennis Bragg     [75300,2456] DXF Raytracing output option
  75018. X Juan J. Buhler   jbuhler@usina.org.ar Diffusion options, inverse Julia type 
  75019. X Mike Burkey      376x564x256, 400x564x256, and 832x612x256 VGA video modes
  75020. X Robin Bussell      Palette-editor "freestyle" option
  75021. X John Bridges      [75300,2137] superVGA support, 360x480x256 mode
  75022. X Brian Corbino      [71611,702] Tandy 1000 640x200x16 video mode
  75023. X Lee Crocker      [73407,2030] Fast Newton, Inversion, Decomposition..
  75024. X Monte Davis      [71450,3542] Documentation
  75025. X Chuck Ebbert      [76306,1226] cmprsd & sqrt logmap, fpu speedups
  75026. X Dan Farmer      [70703,1632] orbits enhancements
  75027. X Richard Finegold [76701,153] 8/16/../256-Way Decomposition option
  75028. X Frank Fussenegger Mandelbrot speedups
  75029. X Mike Gelvin      [73337,520] Mandelbrot speedups
  75030. X Lawrence Gozum   [73437,2372] Tseng 640x400x256 Video Mode
  75031. X David Guenther   [70531,3525] Boundary Tracing algorithm
  75032. X Norman Hills      [71621,1352] Ranges option
  75033. X Richard Hughes   [70461,3272] "inside=", "outside=" coloring options
  75034. X Mike Kaufman      [kaufman@eecs.nwu.edu] mouse support, other features
  75035. X Wesley Loewer    fast fp Mandel/Julia/Lyapunov, boundary trace, frothybasin
  75036. X Adrian Mariano   [adrian@cam.cornell.edu] Diffusion & L-Systems
  75037. X Charles Marslett [75300,1636] VESA video and IIT math chip support
  75038. X Joe McLain      [75066,1257] TARGA Support, color-map files
  75039. X Bob Montgomery   [73357,3140] (Author of VPIC) Fast text I/O routines
  75040. X Bret Mulvey      plasma clouds
  75041. X Roy Murphy      [76376,721] Lyapunov Fractals
  75042. X Ethan Nagel      [70022,2552] Palette editor, integrated help/doc system
  75043. X Jonathan Osuch   [73277,1432] IIT detect, register-compatible 8514/A code
  75044. X Marc Reinig      [72410,77] Lots of 3D options
  75045. X Kyle Powell      [76704,12] 8514/A Support
  75046. X Matt Saucier      [72371,3101] Printer Support
  75047. X Herb Savage      [75260,217] 'inside=bof60', 'inside=bof61' options
  75048. X Ken Shirriff     shirriff@sprite.berkeley.edu Quaternions, CA, Xfract port
  75049. X Lee Skinner      [75450,3631] Tetrate fractal types and more
  75050. X Dean Souleles      [75115,1671] Hercules Support
  75051. X Kurt Sowa      [73467,2013] Color Printer Support
  75052. X Hugh Steele      cyclerange feature
  75053. X John Swenson      [75300,2136] Postscript printer features
  75054. X Chris Taylor      Floating&Fixed-point algorithm speedups, Tesseral Option
  75055. X Scott Taylor      [72401,410] PostScript, Kam Torus, many fn types.
  75056. X Bill Townsend      Mandelbrot Speedups
  75057. X Paul Varner      [73237,441] Extended Memory support for Disk Video
  75058. X Dave Warker      Integer Mandelbrot Fractals concept
  75059. X Aaron Williams   Register-compatible 8514/A code
  75060. X Phil Wilson      [76247,3145] Distance Estimator, Bifurcation fractals
  75061. X Nicholas Wilt      Lsystem speedups
  75062. X Richard Wilton   Tweaked VGA Video modes
  75063. X          ...
  75064. X; Byte Magazine      Tweaked VGA Modes
  75065. X; MS-Kermit      Keyboard Routines
  75066. X; PC Magazine      Sound Routines
  75067. X; PC Tech Journal  CPU, FPU Detectors
  75068. X;
  75069. X;
  75070. SHAR_EOF
  75071. $TOUCH -am 1028230193 help5.src &&
  75072. chmod 0644 help5.src ||
  75073. echo "restore of help5.src failed"
  75074. set `wc -c help5.src`;Wc_c=$1
  75075. if test "$Wc_c" != "93177"; then
  75076.     echo original size 93177, current size $Wc_c
  75077. fi
  75078. exit 0
  75079.