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