home *** CD-ROM | disk | FTP | other *** search
/ Mega A/V / mega_av.zip / mega_av / GRAPHUTL / FRPOR172.ZIP / MISCOVL.C < prev    next >
C/C++ Source or Header  |  1992-03-02  |  34KB  |  1,174 lines

  1. /*
  2.     Overlayed odds and ends that don't fit anywhere else.
  3. */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #ifndef XFRACT
  9. #include <process.h>
  10. #include <dos.h>
  11. #include <stdarg.h>
  12. #else
  13. #include <varargs.h>
  14. #endif
  15. #include "fractint.h"
  16. #include "fractype.h"
  17. #include "helpdefs.h"
  18.  
  19. /* routines in this module    */
  20.  
  21. void miscovl_overlay(void);
  22. void make_batch_file(void);
  23. void shell_to_dos(void);
  24. void showfreemem(void);
  25. int  select_video_mode(int);
  26.  
  27. static void write_batch_parms(FILE *,char *,int);
  28. #ifndef XFRACT
  29. static void put_parm(char *parm,...);
  30. #else
  31. static void put_parm();
  32. #endif
  33.  
  34. static void put_parm_line(void);
  35. static int getprec(double,double,double);
  36. static void put_float(int,double,int);
  37. static void put_filename(char *keyword,char *fname);
  38. static void format_item(int choice,char *buf);
  39. static int check_modekey(int curkey,int choice);
  40. static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2);
  41. static void update_fractint_cfg(void);
  42.  
  43. extern int  cpu;        /* cpu type            */
  44. extern int  fpu;        /* fpu type            */
  45. extern int  iit;        /* iit fpu?            */
  46. extern int  video_type;
  47. extern int  askvideo;
  48. extern char overwrite;        /* 1 means ok to overwrite */
  49. extern int  fillcolor;        /* fill color: -1 = normal*/
  50. extern int  inside;        /* inside color: 1=blue     */
  51. extern int  outside;        /* outside color, if set    */
  52. extern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
  53. extern double param[4];     /* up to four parameters    */
  54. extern int  finattract;     /* finite attractor option  */
  55. extern int  forcesymmetry;
  56. extern int  LogFlag;        /* non-zero if logarithmic palettes */
  57. extern int  rflag, rseed;
  58. extern int  periodicitycheck;
  59. extern int  potflag;        /* continuous potential flag */
  60. extern int  pot16bit;        /* save 16 bit values for continuous potential */
  61. extern double potparam[3];    /* three potential parameters*/
  62. extern int  fractype;        /* if == 0, use Mandelbrot  */
  63. extern BYTE usemag;
  64. extern long delmin;
  65. extern int  maxit;        /* try this many iterations */
  66. extern int  invert;        /* non-zero if inversion active */
  67. extern double inversion[];
  68. extern int  decomp[];
  69. extern int  distest;        /* non-zero if distance estimator   */
  70. extern int  distestwidth;
  71. extern int  init3d[20];     /* '3d=nn/nn/nn/...' values */
  72. extern char floatflag;        /* floating-point fractals? */
  73. extern int  usr_biomorph;
  74. extern char FormFileName[];    /* file to find (type=)formulas in */
  75. extern char FormName[];     /* Name of the Formula (if not null) */
  76. extern char LFileName[];
  77. extern char LName[];
  78. extern char IFSFileName[];
  79. extern char IFSName[];
  80. extern int  bailout;        /* user input bailout value */
  81. extern char useinitorbit;
  82. extern struct complex initorbit;
  83. extern int  display3d;        /* 3D display flag: 0 = OFF */
  84. extern int  loaded3d;
  85. extern char readname[];     /* name of fractal input file */
  86. extern int  showfile;        /* has file been displayed yet? */
  87. extern int  transparent[];
  88. extern char preview;        /* 3D preview mode flag */
  89. extern char showbox;        /* flag to show box and vector in preview */
  90. extern int  RANDOMIZE;        /* Color randomizing factor */
  91. extern int  Targa_Out;  /* Selects full color with light source fills */
  92. extern int  Ambient;        /* Darkness of shadows in light source */
  93. extern int  haze;        /* Amount of haze to factor in in full color */
  94. extern char light_name[];    /* Name of full color .TGA file */
  95. extern int previewfactor;
  96. extern int BRIEF;
  97. extern int RAY;
  98. extern int xtrans;
  99. extern int ytrans;
  100. extern int red_crop_left;
  101. extern int red_crop_right;
  102. extern int blue_crop_left;
  103. extern int blue_crop_right;
  104. extern int red_bright;
  105. extern int blue_bright;
  106. extern int xadjust;
  107. extern int eyeseparation;
  108. extern int glassestype;
  109. extern BYTE trigndx[];
  110. extern int rotate_lo,rotate_hi;
  111. extern int far *ranges;
  112. extern int rangeslen;
  113. extern char CommandFile[80];
  114. extern char CommandName[ITEMNAMELEN+1];
  115. extern char CommandComment1[57];
  116. extern char CommandComment2[57];
  117. extern char usr_stdcalcmode;
  118.  
  119. extern int  colorstate;     /* comments in cmdfiles */
  120. extern int  colors;
  121. extern int  gotrealdac;
  122. extern int  reallyega;
  123. extern char colorfile[];
  124. extern int  mapset;
  125. extern char MAP_name[];
  126. extern BYTE dacbox[256][3];
  127. extern char far *mapdacbox;
  128.  
  129. extern char dstack[4096];
  130. extern char boxx[8192];
  131. extern char s_cantopen[];
  132. extern char s_cantwrite[];
  133. extern char s_cantcreate[];
  134. extern char s_cantunderstand[];
  135. extern char s_cantfind[];
  136.  
  137.  
  138. extern int fullscreen_prompt(char *hdg,int numprompts,char * far *prompts,
  139.            struct fullscreenvalues values[],int options,int fkeymask,
  140.            char far *extrainfo);
  141.  
  142. /* fullscreen_choice options */
  143. #define CHOICERETURNKEY 1
  144. #define CHOICEMENU    2
  145. #define CHOICEHELP    4
  146. int  fullscreen_choice(
  147.          int options, char *hdg, char *hdg2, char *instr, int numchoices,
  148.          char **choices, int *attributes, int boxwidth, int boxdepth,
  149.          int colwidth, int current, void (*formatitem)(),
  150.          char *speedstring, int (*speedprompt)(), int (*checkkey)());
  151.  
  152.  
  153. void miscovl_overlay() { }    /* for restore_active_ovly */
  154.  
  155. extern char s_real[];
  156. extern char s_imag[];
  157. extern char s_mult[];
  158. extern char s_sum[];
  159. extern char s_zmag[];
  160. extern char s_bof60[];
  161. extern char s_bof61[];
  162. extern char s_maxiter[];
  163.  
  164. static FILE *parmfile;
  165.  
  166. #ifdef C6
  167. #pragma optimize("e",off)  /* MSC 6.00A messes up next rtn with "e" on */
  168. #endif
  169. void make_batch_file()
  170. {
  171.    int i,numparms;
  172.    char inpcommandfile[80],inpcommandname[ITEMNAMELEN+1];
  173.    char inpcomment1[57],inpcomment2[57];
  174.    struct fullscreenvalues paramvalues[8];
  175.    char *choices[8];
  176.    int gotinfile;
  177.    char outname[81],buf[256],buf2[128];
  178.    FILE *infile;
  179.    char colorspec[14];
  180.    int maxcolor;
  181.    char *sptr,*sptr2;
  182.    int oldhelpmode;
  183.  
  184.    ENTER_OVLY(OVLY_MISCOVL);
  185.    stackscreen();
  186.    oldhelpmode = helpmode;
  187.    helpmode = HELPPARMFILE;
  188.  
  189.    strcpy(colorspec,"n");
  190.    maxcolor = colors;
  191.    if (gotrealdac && !reallyega) {
  192.       --maxcolor;
  193.       if (maxit < maxcolor) maxcolor = maxit;
  194.       if (inside  > 0 && inside    > maxcolor) maxcolor = inside;
  195.       if (outside > 0 && outside   > maxcolor) maxcolor = outside;
  196.       if (distest < 0 && 0-distest > maxcolor) maxcolor = 0-distest;
  197.       if (decomp[0] > maxcolor) maxcolor = decomp[0] - 1;
  198.       if (potflag && potparam[0] >= maxcolor) maxcolor = potparam[0];
  199.       if (++maxcolor > 256) maxcolor = 256;
  200.       if (colorstate == 0) {      /* default colors */
  201.      if (mapdacbox) {
  202.         colorspec[0] = '@';
  203.         sptr = MAP_name;
  204.         }
  205.      }
  206.       else if (colorstate == 2) { /* colors match colorfile */
  207.      colorspec[0] = '@';
  208.      sptr = colorfile;
  209.      }
  210.       else              /* colors match no .map that we know of */
  211.      colorspec[0] = 'y';
  212.       if (colorspec[0] == '@') {
  213.      if ((sptr2 = strrchr(sptr,SLASHC))) sptr = sptr2 + 1;
  214.      if ((sptr2 = strrchr(sptr,':')))  sptr = sptr2 + 1;
  215.      strncpy(&colorspec[1],sptr,12);
  216.      colorspec[13] = 0;
  217.      }
  218.       }
  219.    strcpy(inpcommandfile,CommandFile);
  220.    strcpy(inpcommandname,CommandName);
  221.    strcpy(inpcomment1,CommandComment1);
  222.    strcpy(inpcomment2,CommandComment2);
  223.    if (CommandName[0] == 0)
  224.       strcpy(inpcommandname,"test");
  225.  
  226.    while (1) {
  227.  
  228. prompt_user:
  229.       choices[0] = "Parameter file";
  230.       paramvalues[0].type = 0x100+56;
  231.       paramvalues[0].uval.sbuf = inpcommandfile;
  232.       choices[1] = "Name";
  233.       paramvalues[1].type = 0x100+ITEMNAMELEN;
  234.       paramvalues[1].uval.sbuf = inpcommandname;
  235.       choices[2] = "Main comment";
  236.       paramvalues[2].type = 0x100+56;
  237.       paramvalues[2].uval.sbuf = inpcomment1;
  238.       choices[3] = "Second comment";
  239.       paramvalues[3].type = 0x100+56;;
  240.       paramvalues[3].uval.sbuf = inpcomment2;
  241.       numparms = 4;
  242.       if (gotrealdac && !reallyega) {
  243.      choices[4] = "Record colors?";
  244.      paramvalues[4].type = 0x100+13;
  245.      paramvalues[4].uval.sbuf = colorspec;
  246.      choices[5] = "    (no | yes for full info | @filename to point to a map file)";
  247.      paramvalues[5].type = '*';
  248.      choices[6] = "# of colors";
  249.      paramvalues[6].type = 'i';
  250.      paramvalues[6].uval.ival = maxcolor;
  251.      choices[7] = "    (if recording full color info)";
  252.      paramvalues[7].type = '*';
  253.      numparms = 8;
  254.      }
  255.  
  256.       if (fullscreen_prompt("Save Current Parameters",
  257.                 numparms,choices,paramvalues,0,0,NULL) < 0)
  258.      break;
  259.  
  260.       strcpy(CommandFile,inpcommandfile);
  261.       if (strchr(CommandFile,'.') == NULL)
  262.      strcat(CommandFile,".par"); /* default extension .par */
  263.       strcpy(CommandName,inpcommandname);
  264.       strcpy(CommandComment1,inpcomment1);
  265.       strcpy(CommandComment2,inpcomment2);
  266.       if (paramvalues[6].uval.ival > 0 && paramvalues[6].uval.ival <= 256)
  267.      maxcolor = paramvalues[6].uval.ival;
  268.  
  269.       strcpy(outname,CommandFile);
  270.       gotinfile = 0;
  271.       if (access(CommandFile,0) == 0) { /* file exists */
  272.      gotinfile = 1;
  273.      if (access(CommandFile,6)) {
  274.         sprintf(buf,s_cantwrite,CommandFile);
  275.         stopmsg(0,buf);
  276.         continue;
  277.         }
  278.      i = strlen(outname);
  279.      while (--i >= 0 && outname[i] != SLASHC)
  280.      outname[i] = 0;
  281.      strcat(outname,"fractint.tmp");
  282.      infile = fopen(CommandFile,"rt");
  283.      setvbuf(infile,dstack,_IOFBF,4096); /* improves speed */
  284.      }
  285.       if ((parmfile = fopen(outname,"wt")) == NULL) {
  286.      sprintf(buf,s_cantcreate,outname);
  287.      stopmsg(0,buf);
  288.      if (gotinfile) fclose(infile);
  289.      continue;
  290.      }
  291.       setvbuf(infile,boxx,_IOFBF,8192); /* improves speed */
  292.  
  293.       if (gotinfile) {
  294.      while (file_gets(buf,255,infile) >= 0) {
  295.         if (strchr(buf,'{')                    /* entry heading? */
  296.           && sscanf(buf," %40[^ \t({]",buf2)
  297.           && stricmp(buf2,CommandName) == 0) { /* entry with same name */
  298.            sprintf(buf2,"File already has an entry named %s\n\
  299. Continue to replace it, Cancel to back out",CommandName);
  300.            if (stopmsg(18,buf2) < 0) {        /* cancel */
  301.           fclose(infile);
  302.           fclose(parmfile);
  303.           unlink(outname);
  304.           goto prompt_user;
  305.           }
  306.            while (strchr(buf,'}') == NULL
  307.          && file_gets(buf,255,infile) > 0 ) { } /* skip to end of set */
  308.            break;
  309.            }
  310.         fputs(buf,parmfile);
  311.         fputc('\n',parmfile);
  312.         }
  313.      }
  314.  
  315.       fprintf(parmfile,"%-19s{",CommandName);
  316.       if (CommandComment1[0]) fprintf(parmfile," ; %s",CommandComment1);
  317.       fputc('\n',parmfile);
  318.       if (CommandComment2[0])
  319.      fprintf(parmfile,"                     ; %s\n",CommandComment2);
  320.       write_batch_parms(parmfile,colorspec,maxcolor); /* write the parameters */
  321.       fprintf(parmfile,"  }\n\n");
  322.  
  323.       if (gotinfile) {    /* copy the rest of the file */
  324.      while ((i = file_gets(buf,255,infile)) == 0) { } /* skip blanks */
  325.      while (i >= 0) {
  326.         fputs(buf,parmfile);
  327.         fputc('\n',parmfile);
  328.         i = file_gets(buf,255,infile);
  329.         }
  330.      fclose(infile);
  331.      }
  332.       fclose(parmfile);
  333.       if (gotinfile) {    /* replace the original file with the new */
  334.      unlink(CommandFile);          /* success assumed on these lines       */
  335.      rename(outname,CommandFile); /* since we checked earlier with access */
  336.      }
  337.  
  338.       break;
  339.       }
  340.  
  341.    helpmode = oldhelpmode;
  342.    unstackscreen();
  343.    EXIT_OVLY;
  344. }
  345. #ifdef C6
  346. #pragma optimize("e",on)  /* back to normal */
  347. #endif
  348.  
  349. static struct write_batch_data { /* buffer for parms to break lines nicely */
  350.    int len;
  351.    char buf[513];
  352.    } *wbdata;
  353.  
  354. static void write_batch_parms(FILE *batch,char *colorinf,int maxcolor)
  355. {
  356.    int i,j,k;
  357.    double Xctr, Yctr, Magnification;
  358.    struct write_batch_data wb_data;
  359.    char *sptr;
  360.    char buf[81];
  361.  
  362.    wbdata = &wb_data;
  363.    wb_data.len = 0; /* force first parm to start on new line */
  364.  
  365.    if (display3d <= 0) { /* a fractal was generated */
  366.  
  367.       /****** fractal only parameters in this section *******/
  368.       put_parm(" reset");
  369.  
  370.       if (*(sptr = curfractalspecific->name) == '*') ++sptr;
  371.       put_parm( " type=%s",sptr);
  372.  
  373.       if (fractype == FORMULA || fractype == FFORMULA)
  374.      put_parm( " formulafile=%s formulaname=%s",FormFileName,FormName);
  375.       if (fractype == LSYSTEM)
  376.     put_parm( " lfile=%s lname=%s",LFileName,LName);
  377.       if (fractype == IFS || fractype == IFS3D)
  378.     put_parm( " ifsfile=%s ifs=%s",IFSFileName,IFSName);
  379.  
  380.       showtrig(buf); /* this function is in miscres.c */
  381.       if (buf[0])
  382.      put_parm(buf);
  383.  
  384.       if (usr_stdcalcmode != 'g')
  385.      put_parm(" passes=%c",usr_stdcalcmode);
  386.  
  387.       if (usemag && cvtcentermag(&Xctr, &Yctr, &Magnification)) {
  388.      put_parm(" center-mag=");
  389.      put_parm((delmin > 1000) ? "%g/%g/%g"
  390.                   : "%+20.17lf/%+20.17lf/%+20.17lf",
  391.           Xctr,Yctr,Magnification);
  392.      }
  393.       else {
  394.      int xdigits,ydigits;
  395.      put_parm( " corners=");
  396.      xdigits = getprec(xxmin,xxmax,xx3rd);
  397.      ydigits = getprec(yymin,yymax,yy3rd);
  398.      put_float(0,xxmin,xdigits);
  399.      put_float(1,xxmax,xdigits);
  400.      put_float(1,yymin,ydigits);
  401.      put_float(1,yymax,ydigits);
  402.      if (xx3rd != xxmin || yy3rd != yymin) {
  403.         put_float(1,xx3rd,xdigits);
  404.         put_float(1,yy3rd,ydigits);
  405.         }
  406.      }
  407.  
  408.       for (i = 3; i >= 0; --i)
  409.      if (param[i] != 0.0) break;
  410.       if (i >= 0) {
  411.      put_parm(" params=%.15g",param[0]);
  412.      for (j = 1; j <= i; ++j)
  413.         put_parm("/%.15g",param[j]);
  414.      }
  415.  
  416.       if(useinitorbit == 2)
  417.      put_parm( " initorbit=pixel");
  418.       else if(useinitorbit == 1)
  419.      put_parm( " initorbit=%.15g/%.15g",initorbit.x,initorbit.y);
  420.  
  421.       if (floatflag)
  422.      put_parm( " float=y");
  423.  
  424.       if (maxit != 150)
  425.      put_parm(" maxiter=%d",maxit);
  426.  
  427.       if(bailout && (potflag == 0 || potparam[2] == 0.0))
  428.      put_parm( " bailout=%d",bailout);
  429.       if(fillcolor != -1) {
  430.        put_parm(" fillcolor=");
  431.     put_parm( "%d",fillcolor);
  432.       }
  433.       if (inside != 1) {
  434.      put_parm(" inside=");
  435.      if (inside == -1)
  436.         put_parm( s_maxiter);
  437.      else if (inside == -59)
  438.         put_parm(s_zmag);
  439.      else if (inside == -60)
  440.         put_parm(s_bof60);
  441.      else if (inside == -61)
  442.         put_parm(s_bof61);
  443.      else
  444.         put_parm( "%d",inside);
  445.      }
  446.       if (outside != -1)
  447.       {
  448.      put_parm(" outside=");
  449.      if (outside == -2)
  450.         put_parm(s_real);
  451.      else if (outside == -3)
  452.         put_parm(s_imag);
  453.      else if (outside == -4)
  454.         put_parm(s_mult);
  455.      else if (outside == -5)
  456.         put_parm(s_sum);
  457.      else
  458.         put_parm( "%d",outside);
  459.       }
  460.  
  461.       if(LogFlag) {
  462.      put_parm( " logmap=");
  463.      if(LogFlag == -1)
  464.         put_parm( "old");
  465.      else if(LogFlag == 1)
  466.         put_parm( "yes");
  467.      else
  468.         put_parm( "%d", LogFlag);
  469.      }
  470.  
  471.       if (potflag) {
  472.      put_parm( " potential=%d/%d/%d",
  473.          (int)potparam[0],(int)potparam[1],(int)potparam[2]);
  474.      if(pot16bit)
  475.         put_parm( "/16bit");
  476.      }
  477.       if (invert)
  478.      put_parm( " invert=%g/%g/%g",
  479.          inversion[0], inversion[1], inversion[2]);
  480.       if (decomp[0])
  481.      put_parm( " decomp=%d", decomp[0]);
  482.       if (distest)
  483.      put_parm( " distest=%d/%d", distest, distestwidth);
  484.       if (usr_biomorph != -1)
  485.      put_parm( " biomorph=%d", usr_biomorph);
  486.       if (finattract)
  487.      put_parm(" finattract=y");
  488.  
  489.       if (forcesymmetry != 999) {
  490.      put_parm( " symmetry=");
  491.      if (forcesymmetry==XAXIS)
  492.         put_parm("xaxis");
  493.      else if(forcesymmetry==YAXIS)
  494.         put_parm("yaxis");
  495.      else if(forcesymmetry==XYAXIS)
  496.         put_parm("xyaxis");
  497.      else if(forcesymmetry==ORIGIN)
  498.         put_parm("origin");
  499.      else if(forcesymmetry==PI_SYM)
  500.         put_parm("pi");
  501.      else
  502.         put_parm("none");
  503.      }
  504.  
  505.       if (periodicitycheck != 1)
  506.      put_parm( " periodicity=%d",periodicitycheck);
  507.  
  508.       if (rflag)
  509.      put_parm( " rseed=%d",rseed);
  510.  
  511.       if (rangeslen) {
  512.      put_parm(" ranges=");
  513.      i = 0;
  514.      while (i < rangeslen) {
  515.         if (i)
  516.            put_parm("/");
  517.         if (ranges[i] == -1) {
  518.            put_parm("-%d/",ranges[++i]);
  519.            ++i;
  520.            }
  521.         put_parm("%d",ranges[i++]);
  522.         }
  523.      }
  524.       }
  525.  
  526.    if (display3d >= 1) {
  527.       /***** 3d transform only parameters in this section *****/
  528.       put_parm( " 3d=yes");
  529.       if (loaded3d == 0)
  530.      put_filename("filename",readname);
  531.       if (SPHERE) {
  532.      put_parm( " sphere=y");
  533.      put_parm( " latitude=%d/%d", THETA1, THETA2);
  534.      put_parm( " longitude=%d/%d", PHI1, PHI2);
  535.      put_parm( " radius=%d", RADIUS);
  536.      }
  537.       put_parm( " scalexyz=%d/%d", XSCALE, YSCALE);
  538.       put_parm( " roughness=%d", ROUGH);
  539.       put_parm( " waterline=%d", WATERLINE);
  540.       if (FILLTYPE)
  541.      put_parm( " filltype=%d", FILLTYPE);
  542.       if (transparent[0] || transparent[1])
  543.      put_parm( " transparent=%d/%d", transparent[0],transparent[1]);
  544.       if (preview) {
  545.      put_parm( " preview=y");
  546.      if (showbox)
  547.         put_parm( " showbox=y");
  548.      put_parm( " coarse=%d",previewfactor);
  549.      }
  550.       if (RAY) {
  551.      put_parm( " ray=%d",RAY);
  552.      if (BRIEF)
  553.         put_parm(" brief=y");
  554.      }
  555.       if (FILLTYPE > 4) {
  556.      put_parm( " lightsource=%d/%d/%d", XLIGHT, YLIGHT, ZLIGHT);
  557.      if (LIGHTAVG)
  558.         put_parm( " smoothing=%d", LIGHTAVG);
  559.      }
  560.       if (RANDOMIZE)
  561.      put_parm( " randomize=%d",RANDOMIZE);
  562.  
  563.       if (Targa_Out)
  564.      put_parm( " fullcolor=y");
  565.       if (Ambient)
  566.      put_parm( " ambient=%d",Ambient);
  567.       if (haze)
  568.      put_parm( " haze=%d",haze);
  569.       }
  570.  
  571.    if (display3d) {        /* universal 3d */
  572.       /***** common (fractal & transform) 3d parameters in this section *****/
  573.       if (!SPHERE || display3d < 0)
  574.      put_parm( " rotation=%d/%d/%d", XROT, YROT, ZROT);
  575.       put_parm( " perspective=%d", ZVIEWER);
  576.       put_parm( " xyshift=%d/%d", XSHIFT, YSHIFT);
  577.       if(xtrans || ytrans)
  578.      put_parm( " xyadjust=%d/%d",xtrans,ytrans);
  579.       if(glassestype) {
  580.      put_parm( " stereo=%d",glassestype);
  581.      put_parm( " interocular=%d",eyeseparation);
  582.      put_parm( " converge=%d",xadjust);
  583.      put_parm( " crop=%d/%d/%d/%d",
  584.          red_crop_left,red_crop_right,blue_crop_left,blue_crop_right);
  585.      put_parm( " bright=%d/%d",
  586.          red_bright,blue_bright);
  587.      }
  588.       }
  589.  
  590.    /***** universal parameters in this section *****/
  591.  
  592.    if (*colorinf != 'n') {
  593.       put_parm(" colors=");
  594.       if (*colorinf == '@')
  595.      put_parm(colorinf);
  596.       else {
  597.      int curc,scanc,force,diffmag;
  598.      int delta,diff1[4][3],diff2[4][3];
  599.      curc = force = 0;
  600.      while (1) {
  601.         /* emit color in rgb 3 char encoded form */
  602.         for (j = 0; j < 3; ++j) {
  603.            if ((k = dacbox[curc][j]) < 10) k += '0';
  604.            else if (k < 36)            k += ('A' - 10);
  605.            else                   k += ('_' - 36);
  606.            buf[j] = k;
  607.            }
  608.         buf[3] = 0;
  609.         put_parm(buf);
  610.         if (++curc >= maxcolor)     /* quit if done last color */
  611.            break;
  612.         /* Next a P Branderhorst special, a tricky scan for smooth-shaded
  613.            ranges which can be written as <nn> to compress .par file entry.
  614.            Method used is to check net change in each color value over
  615.            spans of 2 to 5 color numbers.  First time for each span size
  616.            the value change is noted.  After first time the change is
  617.            checked against noted change.  First time it differs, a
  618.            a difference of 1 is tolerated and noted as an alternate
  619.            acceptable change.  When change is not one of the tolerated
  620.            values, loop exits. */
  621.         if (force) {
  622.            --force;
  623.            continue;
  624.            }
  625.         scanc = curc;
  626.         while (scanc < maxcolor) {     /* scan while same diff to next */
  627.            if ((i = scanc - curc) > 3) /* check spans up to 4 steps */
  628.           i = 3;
  629.            for (k = 0; k <= i; ++k) {
  630.           for (j = 0; j < 3; ++j) { /* check pattern of chg per color */
  631.              delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j];
  632.              if (k == scanc - curc)
  633.             diff1[k][j] = diff2[k][j] = delta;
  634.              else
  635.             if (delta != diff1[k][j] && delta != diff2[k][j]) {
  636.                diffmag = abs(delta - diff1[k][j]);
  637.                if (diff1[k][j] != diff2[k][j] || diffmag != 1)
  638.                   break;
  639.                diff2[k][j] = delta;
  640.                }
  641.              }
  642.           if (j < 3) break; /* must've exited from inner loop above */
  643.           }
  644.            if (k <= i) break;   /* must've exited from inner loop above */
  645.            ++scanc;
  646.            }
  647.         /* now scanc-1 is next color which must be written explicitly */
  648.         if (scanc - curc > 2) { /* good, we have a shaded range */
  649.            if (scanc != maxcolor) {
  650.           if (diffmag < 3) {  /* not a sharp slope change? */
  651.              force = 2;       /* force more between ranges, to stop  */
  652.              --scanc;          /* "drift" when load/store/load/store/ */
  653.              }
  654.           if (k) {          /* more of the same             */
  655.              force += k;
  656.              --scanc;
  657.              }
  658.           }
  659.            if (--scanc - curc > 1) {
  660.           put_parm("<%d>",scanc-curc);
  661.           curc = scanc;
  662.           }
  663.            else           /* changed our mind */
  664.           force = 0;
  665.            }
  666.         }
  667.      }
  668.       }
  669.  
  670.    if (rotate_lo != 1 || rotate_hi != 255)
  671.       put_parm( " cyclerange=%d/%d",rotate_lo,rotate_hi);
  672.  
  673.    while (wbdata->len) /* flush the buffer */
  674.       put_parm_line();
  675. }
  676.  
  677. static void put_filename(char *keyword,char *fname)
  678. {
  679.    char *p;
  680.    if (*fname && !endswithslash(fname)) {
  681.       if ((p = strrchr(fname, SLASHC)))
  682.      if (*(fname = p+1) == 0) return;
  683.       put_parm(" %s=%s",keyword,fname);
  684.       }
  685. }
  686.  
  687. #ifndef XFRACT
  688. static void put_parm(char *parm,...)
  689. #else
  690. static void put_parm(va_alist)
  691. va_dcl
  692. #endif
  693. {
  694.    char *bufptr;
  695.    va_list args;
  696.  
  697. #ifndef XFRACT
  698.    va_start(args,parm);
  699. #else
  700.    char * parm;
  701.  
  702.    va_start(args);
  703.    parm = va_arg(args,char *);
  704. #endif
  705.    if (*parm == ' '             /* starting a new parm */
  706.      && wbdata->len == 0)    /* skip leading space */
  707.       ++parm;
  708.    bufptr = wbdata->buf + wbdata->len;
  709.    vsprintf(bufptr,parm,args);
  710.    while (*(bufptr++))
  711.       ++wbdata->len;
  712.    while (wbdata->len > 200)
  713.       put_parm_line();
  714. }
  715.  
  716. #define NICELINELEN 72
  717. #define MAXLINELEN  76
  718.  
  719. static void put_parm_line()
  720. {
  721.    int len,c;
  722.    if ((len = wbdata->len) > NICELINELEN) {
  723.       len = NICELINELEN+1;
  724.       while (--len != 0 && wbdata->buf[len] != ' ') { }
  725.       if (len == 0) {
  726.      len = NICELINELEN-1;
  727.      while (++len < MAXLINELEN
  728.        && wbdata->buf[len] && wbdata->buf[len] != ' ') { }
  729.      }
  730.       }
  731.    c = wbdata->buf[len];
  732.    wbdata->buf[len] = 0;
  733.    fputs("  ",parmfile);
  734.    fputs(wbdata->buf,parmfile);
  735.    if (c && c != ' ')
  736.       fputc('\\',parmfile);
  737.    fputc('\n',parmfile);
  738.    if ((wbdata->buf[len] = c) == ' ')
  739.       ++len;
  740.    wbdata->len -= len;
  741.    strcpy(wbdata->buf,wbdata->buf+len);
  742. }
  743.  
  744. static int getprec(double a,double b,double c)
  745. {
  746.    double diff,temp;
  747.    int digits;
  748.    double highv = 1.0E20;
  749.    if ((diff = fabs(a - b)) == 0.0) diff = highv;
  750.    if ((temp = fabs(a - c)) == 0.0) temp = highv;
  751.    if (temp < diff) diff = temp;
  752.    if ((temp = fabs(b - c)) == 0.0) temp = highv;
  753.    if (temp < diff) diff = temp;
  754.    digits = 5;
  755.    while (diff < 1.0 && digits < 17) {
  756.       diff *= 10;
  757.       ++digits;
  758.       }
  759.    return((digits < 6) ? 6 : digits);
  760. }
  761.  
  762. static void put_float(int slash,double fnum,int prec)
  763. {  char buf[40];
  764.    char *bptr, *dptr;
  765.    bptr = buf;
  766.    if (slash)
  767.       *(bptr++) = '/';
  768.    sprintf(bptr,"%1.*f",prec,fnum);
  769.    if ((dptr = strchr(bptr,'.'))) {
  770.       ++dptr;
  771.       bptr = buf + strlen(buf);
  772.       while (--bptr > dptr && *bptr == '0')
  773.      *bptr = 0;
  774.       }
  775.    put_parm(buf);
  776. }
  777.  
  778. void shell_to_dos()
  779. {
  780. #ifndef XFRACT
  781.    char *comspec;
  782.    /* from fractint.c & calls no ovlys, doesn't need ENTER_OVLY */
  783.    if ((comspec = getenv("COMSPEC")) == NULL)
  784.       printf("Cannot find COMMAND.COM.\n");
  785.    else {
  786.       putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g");
  787.       spawnl(P_WAIT, comspec, NULL);
  788.       }
  789. #endif
  790. }
  791.  
  792.  
  793. void showfreemem()
  794. {
  795.    char *tempptr;
  796.    BYTE huge *fartempptr;
  797.    unsigned i,i2;
  798.    long j,j2;
  799.    ENTER_OVLY(OVLY_MISCOVL);
  800.    printf("\n CPU type: %d  FPU type: %d  IIT FPU: %d  Video: %d\n\n",
  801.       cpu, fpu, iit, video_type);
  802.    i = j = 0;
  803.    i2 = 0x8000;
  804.    while ((i2 >>= 1) != 0)
  805.       if ((tempptr = malloc(i+i2)) != NULL) {
  806.      free(tempptr);
  807.      i += i2;
  808.      }
  809.    printf(" %d NEAR bytes free \n", i);
  810.    j2 = 0x80000;
  811.    while ((j2 >>= 1) != 0)
  812.       if ((fartempptr = (BYTE huge *)farmemalloc(j+j2)) != NULL) {
  813.      farmemfree((void far*)fartempptr);
  814.      j += j2;
  815.      }
  816.    printf(" %ld FAR bytes free \n\n press any key to continue...\n", j);
  817.    getakey();
  818.    EXIT_OVLY;
  819. }
  820.  
  821.  
  822. edit_text_colors()
  823. {
  824.    extern int debugflag;
  825.    extern int lookatmouse;
  826.    int save_debugflag,save_lookatmouse;
  827.    int row,col,bkgrd;
  828.    int rowf,colf,rowt,colt;
  829.    char far *vidmem;
  830.    char far *savescreen;
  831.    char far *farp1; char far *farp2;
  832.    int i,j,k;
  833.    ENTER_OVLY(OVLY_MISCOVL);
  834.    save_debugflag = debugflag;
  835.    save_lookatmouse = lookatmouse;
  836.    debugflag = 0;   /* don't get called recursively */
  837.    lookatmouse = 2; /* text mouse sensitivity */
  838.    row = col = bkgrd = rowt = rowf = colt = colf = 0;
  839.    vidmem = MK_FP(0xB800,0);
  840.    while (1) {
  841.       if (row < 0)  row = 0;
  842.       if (row > 24) row = 24;
  843.       if (col < 0)  col = 0;
  844.       if (col > 79) col = 79;
  845.       movecursor(row,col);
  846.       i = getakey();
  847.       if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */
  848.       switch (i) {
  849.      case 27: /* esc */
  850.         debugflag = save_debugflag;
  851.         lookatmouse = save_lookatmouse;
  852.         movecursor(25,80);
  853.         EXIT_OVLY;
  854.         return 0;
  855.      case '/':
  856.         farp1 = savescreen = farmemalloc(4000L);
  857.         farp2 = vidmem;
  858.         for (i = 0; i < 4000; ++i) { /* save and blank */
  859.            *(farp1++) = *farp2;
  860.            *(farp2++) = 0;
  861.            }
  862.         for (i = 0; i < 8; ++i)      /* 8 bkgrd attrs */
  863.            for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */
  864.           k = i*16 + j;
  865.           farp1 = vidmem + i*320 + j*10;
  866.           *(farp1++) = ' '; *(farp1++) = k;
  867.           *(farp1++) = i+'0'; *(farp1++) = k;
  868.           *(farp1++) = (j < 10) ? j+'0' : j+'A'-10; *(farp1++) = k;
  869.           *(farp1++) = ' '; *(farp1++) = k;
  870.           }
  871.         getakey();
  872.         farp1 = vidmem;
  873.         farp2 = savescreen;
  874.         for (i = 0; i < 4000; ++i) /* restore */
  875.            *(farp1++) = *(farp2++);
  876.         farmemfree(savescreen);
  877.         break;
  878.      case ',':
  879.         rowf = row; colf = col; break;
  880.      case '.':
  881.         rowt = row; colt = col; break;
  882.      case ' ': /* next color is background */
  883.         bkgrd = 1; break;
  884.      case 1075: /* cursor left  */
  885.         --col; break;
  886.      case 1077: /* cursor right */
  887.         ++col; break;
  888.      case 1072: /* cursor up    */
  889.         --row; break;
  890.      case 1080: /* cursor down  */
  891.         ++row; break;
  892.      case 13:   /* enter */
  893.         *(vidmem + row*160 + col*2) = getakey();
  894.         break;
  895.      default:
  896.         if (i >= '0' && i <= '9')      i -= '0';
  897.         else if (i >= 'A' && i <= 'F') i -= 'A'-10;
  898.         else break;
  899.         for (j = rowf; j <= rowt; ++j)
  900.            for (k = colf; k <= colt; ++k) {
  901.           farp1 = vidmem + j*160 + k*2 + 1;
  902.           if (bkgrd) *farp1 = (*farp1 & 15) + i * 16;
  903.           else         *farp1 = (*farp1 & 0xf0) + i;
  904.           }
  905.         bkgrd = 0;
  906.      }
  907.       }
  908. }
  909.  
  910.  
  911. extern int badconfig;
  912. extern struct videoinfo far videotable[];
  913. extern struct videoinfo far *vidtbl;
  914. extern int vidtbllen;
  915. extern int tabmode;
  916. extern int adapter;
  917. static int *entsptr;
  918. static int modes_changed;
  919. extern int mode7text;
  920.  
  921. int select_video_mode(int curmode)
  922. {
  923.    int entnums[MAXVIDEOMODES];
  924.    int attributes[MAXVIDEOMODES];
  925.    int i,j,k,ret;
  926.    int oldtabmode,oldhelpmode;
  927.  
  928.    ENTER_OVLY(OVLY_MISCOVL);
  929.  
  930.    load_fractint_cfg(0);    /* load fractint.cfg to extraseg */
  931.  
  932.    for (i = 0; i < vidtbllen; ++i) { /* init tables */
  933.       entnums[i] = i;
  934.       attributes[i] = 1;
  935.       }
  936.    entsptr = entnums;        /* for indirectly called subroutines */
  937.  
  938.    qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */
  939.  
  940.    /* pick default mode */
  941.    if (curmode < 0) {
  942.       switch (video_type) { /* set up a reasonable default (we hope) */
  943.      case 1:  videoentry.videomodeax = 8;    /* hgc */
  944.           videoentry.colors = 2;
  945.           break;
  946.      case 2:  videoentry.videomodeax = 4;    /* cga */
  947.           videoentry.colors = 4;
  948.           break;
  949.      case 3:  videoentry.videomodeax = 16;    /* ega */
  950.           videoentry.colors = 16;
  951.           if (mode7text) {        /* egamono */
  952.              videoentry.videomodeax = 15;
  953.              videoentry.colors = 2;
  954.              }
  955.           break;
  956.      default: videoentry.videomodeax = 19;    /* mcga/vga? */
  957.           videoentry.colors = 256;
  958.           break;
  959.      }
  960.       }
  961.    else
  962.       far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode],
  963.          sizeof(videoentry));
  964. #ifndef XFRACT
  965.    for (i = 0; i < vidtbllen; ++i) { /* find default mode */
  966.       if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax
  967.     && videoentry.colors      == vidtbl[entnums[i]].colors
  968.     && (curmode < 0
  969.         || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]],
  970.               sizeof(videoentry)) == 0))
  971.      break;
  972.       }
  973.    if (i >= vidtbllen) /* no match, default to first entry */
  974.       i = 0;
  975.  
  976.    oldtabmode = tabmode;
  977.    oldhelpmode = helpmode;
  978.    modes_changed = 0;
  979.    tabmode = 0;
  980.    helpmode = HELPVIDSEL;
  981.    i = fullscreen_choice(CHOICEHELP,"Select Video Mode",
  982.  "key...name......................xdot.ydot.colr.comment..................",
  983.           NULL,vidtbllen,NULL,attributes,
  984.           1,16,72,i,format_item,NULL,NULL,check_modekey);
  985.    tabmode = oldtabmode;
  986.    helpmode = oldhelpmode;
  987.    if (i == -1) {
  988.    static char far msg[]={"Save new function key assignments or cancel changes?"};
  989.       if (modes_changed /* update fractint.cfg for new key assignments */
  990.     && badconfig == 0
  991.     && stopmsg(22,msg) == 0)
  992.      update_fractint_cfg();
  993.       EXIT_OVLY;
  994.       return(-1);
  995.       }
  996.    if (i < 0)    /* picked by function key */
  997.       i = -1 - i;
  998.    else     /* picked by Enter key */
  999.       i = entnums[i];
  1000. #endif
  1001.    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
  1002.           sizeof(videoentry));  /* the selected entry now in videoentry */
  1003.  
  1004. #ifndef XFRACT
  1005.    /* copy fractint.cfg table to resident table, note selected entry */
  1006.    j = k = 0;
  1007.    far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
  1008.    for (i = 0; i < vidtbllen; ++i) {
  1009.       if (vidtbl[i].keynum > 0) {
  1010.      far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i],
  1011.             sizeof(*vidtbl));
  1012.      if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i],
  1013.             sizeof(videoentry)) == 0)
  1014.         k = vidtbl[i].keynum;
  1015.      if (++j >= MAXVIDEOTABLE-1)
  1016.         break;
  1017.      }
  1018.       }
  1019. #else
  1020.     k = vidtbl[0].keynum;
  1021. #endif
  1022.    if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */
  1023.       far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1],
  1024.          (char far *)&videoentry,sizeof(*vidtbl));
  1025.       ret = 1400; /* special value for check_vidmode_key */
  1026.       }
  1027.  
  1028.    if (modes_changed /* update fractint.cfg for new key assignments */
  1029.      && badconfig == 0)
  1030.       update_fractint_cfg();
  1031.  
  1032.    EXIT_OVLY;
  1033.    return(ret);
  1034. }
  1035.  
  1036. static void format_item(int choice,char *buf)
  1037. {
  1038.    char kname[5];
  1039.    char biosflag;
  1040.    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]],
  1041.           sizeof(videoentry));
  1042.    vidmode_keyname(videoentry.keynum,kname);
  1043.    biosflag = (videoentry.dotmode % 100 == 1) ? 'B' : ' ';
  1044.    sprintf(buf,"%-5s %-25s %4d %4d %3d%c %-25s",  /* 72 chars */
  1045.        kname, videoentry.name, videoentry.xdots, videoentry.ydots,
  1046.        videoentry.colors, biosflag, videoentry.comment);
  1047. }
  1048.  
  1049. static int check_modekey(int curkey,int choice)
  1050. {
  1051.    int i,j,k,ret;
  1052.    if ((i = check_vidmode_key(1,curkey)) >= 0)
  1053.       return(-1-i);
  1054.    i = entsptr[choice];
  1055.    ret = 0;
  1056.    if ( (curkey == '-' || curkey == '+')
  1057.      && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) {
  1058.       static char far msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."};
  1059.       if (badconfig)
  1060.      stopmsg(0,msg);
  1061.       else {
  1062.      if (curkey == '-') {                   /* deassign key? */
  1063.         if (vidtbl[i].keynum >= 1084) {
  1064.            vidtbl[i].keynum = 0;
  1065.            modes_changed = 1;
  1066.            }
  1067.         }
  1068.      else {                 /* assign key? */
  1069.         j = getakeynohelp();
  1070.         if (j >= 1084 && j <= 1113) {
  1071.            for (k = 0; k < vidtbllen; ++k) {
  1072.           if (vidtbl[k].keynum == j) {
  1073.              vidtbl[k].keynum = 0;
  1074.              ret = -1; /* force redisplay */
  1075.              }
  1076.           }
  1077.            vidtbl[i].keynum = j;
  1078.            modes_changed = 1;
  1079.            }
  1080.         }
  1081.      }
  1082.       }
  1083.    return(ret);
  1084. }
  1085.  
  1086. static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2)
  1087. {
  1088.    int i,j;
  1089.    if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999;
  1090.    if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999;
  1091.    if (i < j || (i == j && *((int *)p1) < *((int *)p2)))
  1092.       return(-1);
  1093.    return(1);
  1094. }
  1095.  
  1096. static void update_fractint_cfg()
  1097. {
  1098.    char cfgname[100],outname[100],buf[121],kname[5];
  1099.    FILE *cfgfile,*outfile;
  1100.    int far *cfglinenums;
  1101.    int i,j,linenum,nextlinenum,nextmode;
  1102.    struct videoinfo vident;
  1103.  
  1104. #ifndef XFRACT
  1105.    findpath("fractint.cfg",cfgname);
  1106. #else
  1107.    findpath("xfracint.cfg",cfgname);
  1108. #endif
  1109.  
  1110.    if (access(cfgname,6)) {
  1111.       sprintf(buf,s_cantwrite,cfgname);
  1112.       stopmsg(0,buf);
  1113.       return;
  1114.       }
  1115.    strcpy(outname,cfgname);
  1116.    i = strlen(outname);
  1117.    while (--i >= 0 && outname[i] != SLASHC)
  1118.    outname[i] = 0;
  1119.    strcat(outname,"fractint.tmp");
  1120.    if ((outfile = fopen(outname,"w")) == NULL) {
  1121.       sprintf(buf,s_cantcreate,outname);
  1122.       stopmsg(0,buf);
  1123.       return;
  1124.       }
  1125.    cfgfile = fopen(cfgname,"r");
  1126.  
  1127.    cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);
  1128.    linenum = nextmode = 0;
  1129.    nextlinenum = cfglinenums[0];
  1130.    while (fgets(buf,120,cfgfile)) {
  1131.       ++linenum;
  1132.       if (linenum == nextlinenum) { /* replace this line */
  1133.      far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode],
  1134.             sizeof(videoentry));
  1135.      vidmode_keyname(vident.keynum,kname);
  1136.      strcpy(buf,vident.name);
  1137.      i = strlen(buf);
  1138.      while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */
  1139.         --i;
  1140.      j = i + 5;
  1141.      while (j < 32) {        /* tab to column 33 */
  1142.         buf[i++] = '\t';
  1143.         j += 8;
  1144.         }
  1145.      buf[i] = 0;
  1146.      fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%4d,%4d,%3d,%s\n",
  1147.         kname,
  1148.         buf,
  1149.         vident.videomodeax,
  1150.         vident.videomodebx,
  1151.         vident.videomodecx,
  1152.         vident.videomodedx,
  1153.         vident.dotmode,
  1154.         vident.xdots,
  1155.         vident.ydots,
  1156.         vident.colors,
  1157.         vident.comment);
  1158.      if (++nextmode >= vidtbllen)
  1159.         nextlinenum = 32767;
  1160.      else
  1161.         nextlinenum = cfglinenums[nextmode];
  1162.      }
  1163.       else
  1164.      fputs(buf,outfile);
  1165.       }
  1166.  
  1167.    fclose(cfgfile);
  1168.    fclose(outfile);
  1169.    unlink(cfgname);        /* success assumed on these lines        */
  1170.    rename(outname,cfgname); /* since we checked earlier with access */
  1171. }
  1172.  
  1173.  
  1174.