home *** CD-ROM | disk | FTP | other *** search
/ Computerworld 1996 March / Computerworld_1996-03_cd.bin / idg_cd3 / grafika / fraktaly / frasr192 / framain2.c < prev    next >
C/C++ Source or Header  |  1995-04-08  |  55KB  |  1,697 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #ifndef XFRACT
  6. #include <io.h>
  7. #include <dos.h>
  8. #include <stdarg.h>
  9. #else
  10. #include <varargs.h>
  11. #endif
  12. #include <ctype.h>
  13. #include "prototyp.h"
  14. #include "fractype.h"
  15. #include "helpdefs.h"
  16.  
  17. #if 0
  18. /* makes a handly list of jul-man pairs, not for release */
  19. static void julman()
  20. {
  21.    FILE *fp;
  22.    int i;
  23.    fp = dir_fopen(workdir,"toggle.txt","w");
  24.    i = -1;
  25.    while(fractalspecific[++i].name)
  26.    {
  27.       if(fractalspecific[i].tojulia != NOFRACTAL && fractalspecific[i].name[0] != '*')
  28.          fprintf(fp,"%s  %s\n",fractalspecific[i].name,
  29.              fractalspecific[fractalspecific[i].tojulia].name);  
  30.    }
  31.    fclose(fp);
  32. }
  33. #endif
  34.  
  35. /* routines in this module    */
  36.  
  37. int main_menu_switch(int*,int*,int*,char*,int);
  38. int big_while_loop(int *kbdmore, char *stacked, int resumeflag);
  39. static void move_zoombox(int);
  40. char fromtext_flag = 0;        /* = 1 if we're in graphics mode */
  41. static int call_line3d(BYTE *pixels, int linelen);
  42. static    void note_zoom(void);
  43. static    void restore_zoom(void);
  44. static    void move_zoombox(int keynum);
  45. static    void cmp_line_cleanup(void);
  46. static void _fastcall restore_history_info(int);
  47. static void _fastcall save_history_info(void);
  48.  
  49. static char far *savezoom;
  50. static  int       historyptr = -1;    /* user pointer into history tbl  */
  51. static  int       saveptr = 0;     /* save ptr into history tbl      */
  52. static  int       historyflag;     /* are we backing off in history? */
  53. void (*outln_cleanup) (void);
  54.  
  55. int big_while_loop(int *kbdmore, char *stacked, int resumeflag)
  56. {
  57.    int       frommandel;            /* if julia entered from mandel */
  58.    int       axmode=0, bxmode, cxmode, dxmode; /* video mode (BIOS ##)    */
  59.    double  ftemp;            /* fp temp            */
  60.    int       i;                /* temporary loop counters    */
  61.    int kbdchar;
  62.    frommandel = 0;
  63.    if(resumeflag)
  64.       goto resumeloop;
  65.     for(;;) {            /* eternal loop */
  66.       if (calc_status != 2 || showfile == 0) {
  67. #ifdef XFRACT
  68.          if (resizeWindow()) {
  69.          calc_status = -1;
  70.      }
  71. #endif
  72.      far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter],
  73.             sizeof(videoentry));
  74.      axmode  = videoentry.videomodeax; /* video mode (BIOS call)   */
  75.      bxmode  = videoentry.videomodebx; /* video mode (BIOS call)   */
  76.      cxmode  = videoentry.videomodecx; /* video mode (BIOS call)   */
  77.      dxmode  = videoentry.videomodedx; /* video mode (BIOS call)   */
  78.      dotmode = videoentry.dotmode;       /* assembler dot read/write */
  79.      xdots     = videoentry.xdots;       /* # dots across the screen */
  80.      ydots     = videoentry.ydots;       /* # dots down the screen   */
  81.      colors  = videoentry.colors;       /* # colors available */
  82.      textsafe2 = dotmode / 100;
  83.      dotmode  %= 100;
  84.      sxdots  = xdots;
  85.      sydots  = ydots;
  86.      sxoffs = syoffs = 0;
  87.  
  88.      diskvideo = 0;         /* set diskvideo flag */
  89.      if (dotmode == 11)        /* default assumption is disk */
  90.         diskvideo = 2;
  91.  
  92.      memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  93.      diskisactive = 1;        /* flag for disk-video routines */
  94.  
  95.      if (overlay3d) {
  96.         unstackscreen();        /* restore old graphics image */
  97.         overlay3d = 0;
  98.         }
  99.  
  100.      else {
  101.                setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
  102.         if (goodmode == 0) {
  103.            static FCODE msg[] = {"That video mode is not available with your adapter."};
  104.            static FCODE TPlusStr[] = "This video mode requires 'noninterlaced=yes'";
  105.  
  106.            if(TPlusErr) {
  107.           stopmsg(0, TPlusStr);
  108.           TPlusErr = 0;
  109.           }
  110.            else {
  111.           stopmsg(0,msg);
  112.           askvideo = TRUE;
  113.           }
  114.            initmode = -1;
  115.            setvideotext(); /* switch to text mode */
  116.            /* goto restorestart; */
  117.            return(RESTORESTART);
  118.            }
  119.         }
  120.  
  121.      diskisactive = 0;        /* flag for disk-video routines */
  122.      if (savedac || colorpreloaded) {
  123.         memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  124.         spindac(0,1);
  125.         colorpreloaded = 0;
  126.         }
  127.      else { /* reset DAC to defaults, which setvideomode has done for us */
  128.         if (mapdacbox) { /* but there's a map=, so load that */
  129.            far_memcpy((char far *)dacbox,mapdacbox,768);
  130.            spindac(0,1);
  131.            }
  132.         else if ((dotmode == 11 && colors == 256) || !colors) {
  133.            /* disk video, setvideomode via bios didn't get it right, so: */
  134. #ifndef XFRACT
  135.            ValidateLuts("default"); /* read the default palette file */
  136. #endif
  137.            }
  138.         colorstate = 0;
  139.         }
  140.      if (viewwindow) {
  141.         ftemp = finalaspectratio
  142.             * (double)sydots / (double)sxdots / screenaspect;
  143.         if ((xdots = viewxdots) != 0) { /* xdots specified */
  144.            if ((ydots = viewydots) == 0) /* calc ydots? */
  145.           ydots = (int)((double)xdots * ftemp + 0.5);
  146.            }
  147.         else
  148.            if (finalaspectratio <= screenaspect) {
  149.           xdots = (int)((double)sxdots / viewreduction + 0.5);
  150.           ydots = (int)((double)xdots * ftemp + 0.5);
  151.           }
  152.            else {
  153.           ydots = (int)((double)sydots / viewreduction + 0.5);
  154.           xdots = (int)((double)ydots / ftemp + 0.5);
  155.           }
  156.         if (xdots > sxdots || ydots > sydots) {
  157.            static FCODE msg[] = {"View window too large; using full screen."};
  158.            stopmsg(0,msg);
  159.            xdots = sxdots;
  160.            ydots = sydots;
  161.            }
  162.         else if (xdots <= sxdots/20 || ydots <= sydots/20) { /* so ssg works */
  163.            static FCODE msg[] = {"View window too small; using full screen."};
  164.            stopmsg(0,msg);
  165.            xdots = sxdots;
  166.            ydots = sydots;
  167.            }
  168.         sxoffs = (sxdots - xdots) / 2;
  169.         syoffs = (sydots - ydots) / 3;
  170.         }
  171.      dxsize = xdots - 1;        /* convert just once now */
  172.      dysize = ydots - 1;
  173.      }
  174.       if(savedac == 0)
  175.         savedac = 2;            /* assume we save next time (except jb) */
  176.       else
  177.       savedac = 1;            /* assume we save next time */
  178.       if (initbatch == 0)
  179.      lookatmouse = -PAGE_UP;    /* mouse left button == pgup */
  180.  
  181.       if(showfile == 0) {        /* loading an image */
  182.      outln_cleanup = NULL;        /* outln routine can set this */
  183.      if (display3d)         /* set up 3D decoding */
  184.         outln = call_line3d;
  185.      else if(filetype >= 1)     /* old .tga format input file */
  186.         outln = outlin16;
  187.      else if(comparegif)        /* debug 50 */
  188.         outln = cmp_line;
  189.      else if(pot16bit) {        /* .pot format input file */
  190.         if (pot_startdisk() < 0)
  191.         {                /* pot file failed?  */
  192.            showfile = 1;
  193.            potflag  = 0;
  194.            pot16bit = 0;
  195.            initmode = -1;
  196.            calc_status = 2;        /* "resume" without 16-bit */
  197.            setvideotext();
  198.            get_fracttype();
  199.            /* goto imagestart; */
  200.            return(IMAGESTART);
  201.         }
  202.         outln = pot_line;
  203.      }
  204.      else                /* regular gif/fra input file */
  205.             if(soundflag > 0)
  206.                outln = sound_line;      /* sound decoding */
  207.             else
  208.                outln = out_line;        /* regular decoding */
  209.      if(filetype == 0)
  210.      {
  211.         if(iit == 2 && usr_floatflag != 0)
  212.            if(F4x4Lock()==0)
  213.               iit = -1;  /* semaphore not free - no iit */
  214.         if(debugflag==2224)
  215.          {
  216.             char buf[80];
  217.             sprintf(buf,"iit=%d floatflag=%d",iit,usr_floatflag);
  218.             stopmsg(4,(char far *)buf);
  219.          }
  220.  
  221.         i = funny_glasses_call(gifview);
  222.         if(iit == 2)
  223.            F4x4Free();      /* unlock semaphore */
  224.         else if(iit == -1)
  225.            iit = 2;         /* semaphore operating */
  226.      }
  227.      else
  228.         i = funny_glasses_call(tgaview);
  229.      if(outln_cleanup)        /* cleanup routine defined? */
  230.         (*outln_cleanup)();
  231.      if(i == 0)
  232.         buzzer(0);
  233.      else {
  234.         calc_status = -1;
  235.         if (keypressed()) {
  236.            static FCODE msg[] = {"*** load incomplete ***"};
  237.            buzzer(1);
  238.            while (keypressed()) getakey();
  239.            texttempmsg(msg);
  240.            }
  241.         }
  242.      }
  243.  
  244.       zoomoff = 1;            /* zooming is enabled */
  245.       if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0)
  246.      zoomoff = 0;            /* for these cases disable zooming */
  247.       calcfracinit();
  248. #ifdef XFRACT
  249.       schedulealarm(1);
  250. #endif
  251.  
  252.       sxmin = xxmin; /* save 3 corners for zoom.c ref points */
  253.       sxmax = xxmax;
  254.       sx3rd = xx3rd;
  255.       symin = yymin;
  256.       symax = yymax;
  257.       sy3rd = yy3rd;
  258.  
  259.       if(bf_math)
  260.       {
  261.          copy_bf(bfsxmin,bfxmin);
  262.          copy_bf(bfsxmax,bfxmax);
  263.          copy_bf(bfsymin,bfymin);
  264.          copy_bf(bfsymax,bfymax);
  265.          copy_bf(bfsx3rd,bfx3rd);
  266.          copy_bf(bfsy3rd,bfy3rd);
  267.       }
  268.       save_history_info();
  269.       if (display3d || showfile) {    /* paranoia: these vars don't get set */
  270.      save_system  = active_system;    /*   unless really doing some work,   */
  271.      }                /*   so simple <r> + <s> keeps number */
  272.  
  273.       if(showfile == 0) {        /* image has been loaded */
  274.      showfile = 1;
  275.      if (initbatch == 1 && calc_status == 2)
  276.         initbatch = -1; /* flag to finish calc before save */
  277.      if (loaded3d)        /* 'r' of image created with '3' */
  278.         display3d = 1;  /* so set flag for 'b' command */
  279.      }
  280.       else {                /* draw an image */
  281.      diskisactive = 1;        /* flag for disk-video routines */
  282.      if (initsavetime != 0        /* autosave and resumable? */
  283.        && (curfractalspecific->flags&NORESUME) == 0) {
  284.         savebase = readticker(); /* calc's start time */
  285.         saveticks = abs(initsavetime);
  286.         saveticks *= 1092; /* bios ticks/minute */
  287.         if ((saveticks & 65535L) == 0)
  288.            ++saveticks; /* make low word nonzero */
  289.         finishrow = -1;
  290.         }
  291.      i = calcfract();    /* draw the fractal using "C" */
  292.      if (i == 0)
  293.         buzzer(0); /* finished!! */
  294.  
  295.      saveticks = 0;         /* turn off autosave timer */
  296.      if (dotmode == 11 && i == 0) /* disk-video */
  297.      {
  298.         static FCODE o_msg[] = {"Image has been completed"};
  299.         char msg[sizeof(o_msg)];
  300.         far_strcpy(msg,o_msg);
  301.         dvid_status(0,msg);
  302.      }   
  303.      diskisactive = 0;        /* flag for disk-video routines */
  304.      }
  305.  
  306. #ifndef XFRACT
  307.       boxcount = 0;            /* no zoom box yet  */
  308.       zwidth = 0;
  309. #else
  310.       if (!XZoomWaiting) {
  311.       boxcount = 0;            /* no zoom box yet  */
  312.       zwidth = 0;
  313.       }
  314. #endif
  315.  
  316.       if (fractype == PLASMA && cpu > 88) {
  317.      cyclelimit = 256;        /* plasma clouds need quick spins */
  318.      daccount = 256;
  319.      daclearn = 1;
  320.      }
  321.  
  322. resumeloop:                /* return here on failed overlays */
  323.  
  324.       *kbdmore = 1;
  325.       while (*kbdmore == 1) {        /* loop through command keys */
  326.      if (timedsave != 0) {
  327.         if (timedsave == 1) {    /* woke up for timed save */
  328.            getakey();     /* eat the dummy char */
  329.            kbdchar = 's'; /* do the save */
  330.            resave_flag = 1;
  331.            timedsave = 2;
  332.            }
  333.         else {            /* save done, resume */
  334.            timedsave = 0;
  335.            resave_flag = 2;
  336.            kbdchar = ENTER;
  337.            }
  338.         }
  339.      else if (initbatch == 0) {    /* not batch mode */
  340.         lookatmouse = (zwidth == 0) ? -PAGE_UP : 3;
  341.         if (calc_status == 2 && zwidth == 0 && !keypressed()) {
  342.           kbdchar = ENTER ;  /* no visible reason to stop, continue */
  343.         } else {     /* wait for a real keystroke */
  344.           if (autobrowse && !no_sub_images) kbdchar = 'l';
  345.            else
  346.            {
  347. #ifndef XFRACT
  348.            while (!keypressed());/* { }*/  /* enables help */
  349. #else
  350.            waitkeypressed(0);
  351. #endif
  352.            kbdchar = getakey();
  353.            }
  354.            if (kbdchar == ESC || kbdchar == 'm' || kbdchar == 'M') {
  355.           if (kbdchar == ESC && escape_exit != 0)
  356.               /* don't ask, just get out */
  357.               goodbye();
  358.           stackscreen();
  359. #ifndef XFRACT
  360.           kbdchar = main_menu(1);
  361. #else
  362.           if (XZoomWaiting) {
  363.               kbdchar = ENTER;
  364.           } else {
  365.               kbdchar = main_menu(1);
  366.               if (XZoomWaiting) {
  367.               kbdchar = ENTER;
  368.               }
  369.           }
  370. #endif
  371.           if (kbdchar == '\\' || kbdchar == CTL_BACKSLASH ||
  372.               kbdchar == 'h' || kbdchar == 8 ||
  373.               check_vidmode_key(0,kbdchar) >= 0)
  374.              discardscreen();
  375.           else if (kbdchar == 'x' || kbdchar == 'y' ||
  376.                kbdchar == 'z' || kbdchar == 'g' ||
  377.                kbdchar == 'v' || kbdchar == 2)
  378.              fromtext_flag = 1;
  379.           else 
  380.              unstackscreen();
  381.           }
  382.            }
  383.         }
  384.      else {        /* batch mode, fake next keystroke */
  385.  
  386. /* initbatch == -1  flag to finish calc before save */
  387. /* initbatch == 0   not in batch mode */
  388. /* initbatch == 1   normal batch mode */
  389. /* initbatch == 2   was 1, now do a save */
  390. /* initbatch == 3   bailout with errorlevel == 2, error occurred, no save */
  391. /* initbatch == 4   bailout with errorlevel == 1, interrupted, try to save */
  392. /* initbatch == 5   was 4, now do a save */
  393.  
  394.         if (initbatch == -1) {    /* finish calc */
  395.            kbdchar = ENTER;
  396.            initbatch = 1;
  397.            }
  398.         else if (initbatch == 1 || initbatch == 4 ) {    /* save-to-disk */
  399. /*
  400.            while(keypressed())
  401.          getakey();
  402. */
  403.            if (debugflag == 50)
  404.           kbdchar = 'r';
  405.            else
  406.           kbdchar = 's';
  407.            if(initbatch == 1) initbatch = 2;
  408.            if(initbatch == 4) initbatch = 5;
  409.            }
  410.         else {
  411.            if(calc_status != 4) initbatch = 3; /* bailout with error */
  412.            goodbye();        /* done, exit */
  413.            }
  414.         }
  415.  
  416. #ifndef XFRACT
  417.          if ('A' <= kbdchar && kbdchar <= 'Z')
  418.             kbdchar = tolower(kbdchar);
  419. #endif
  420.  
  421.          switch(main_menu_switch(&kbdchar,&frommandel,kbdmore,stacked,axmode))
  422.          {
  423.          case IMAGESTART:
  424.             return(IMAGESTART);
  425.          case RESTORESTART:
  426.             return(RESTORESTART);
  427.          case RESTART:
  428.             return(RESTART);
  429.          case CONTINUE:
  430.             continue;
  431.          default:
  432.             break;
  433.          }
  434.      if (zoomoff == 1 && *kbdmore == 1) /* draw/clear a zoom box? */
  435.         drawbox(1);
  436. #ifdef XFRACT
  437.      if (resizeWindow()) {
  438.          calc_status = -1;
  439.      }
  440. #endif
  441.      }
  442.       }
  443. /*  return(0); */
  444. }
  445.  
  446. int main_menu_switch(int *kbdchar, int *frommandel, int *kbdmore, char *stacked, int axmode)
  447. {
  448.    int i,k;
  449.    static double  jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */
  450.    static double  jxx3rd, jyy3rd;
  451.    /*
  452.    char drive[FILE_MAX_DRIVE];
  453.    char dir[FILE_MAX_DIR];
  454.    char fname[FILE_MAX_FNAME];
  455.    char ext[FILE_MAX_EXT];
  456.    */
  457.    switch (*kbdchar)
  458.    {
  459.    case 't':            /* new fractal type             */
  460.       julibrot = 0;
  461.       clear_zoombox();
  462.       stackscreen();
  463.       if ((i = get_fracttype()) >= 0)
  464.       {
  465.      discardscreen();
  466.      savedac = 0;
  467.      save_release = release;
  468.      no_mag_calc = 0;
  469.      use_old_period = 0;
  470.      if (i == 0)
  471.      {
  472.         initmode = adapter;
  473.         *frommandel = 0;
  474.      }
  475.      else if (initmode < 0)    /* it is supposed to be... */
  476.         setvideotext();    /* reset to text mode       */
  477.      return(IMAGESTART);
  478.       }
  479.       unstackscreen();
  480.       break;
  481.    case 24:            /* Ctl-X, Ctl-Y, CTL-Z do flipping */
  482.    case 25:
  483.    case 26:
  484.       flip_image(*kbdchar);
  485.       break;
  486.    case 'x':            /* invoke options screen        */
  487.    case 'y':
  488.    case 'z':            /* type specific parms */
  489.    case 'g':
  490.    case 'v':
  491.    case 2:
  492.       if (fromtext_flag == 1)
  493.      fromtext_flag = 0;
  494.       else
  495.      stackscreen();
  496.       if (*kbdchar == 'x')
  497.      i = get_toggles();
  498.       else if (*kbdchar == 'y')
  499.      i = get_toggles2();
  500.       else if (*kbdchar == 'z')
  501.      i = get_fract_params(1);
  502.       else if (*kbdchar == 'v')
  503.      i = get_view_params();    /* get the parameters */
  504.       else if (*kbdchar == 2)
  505.      i = get_browse_params();
  506.       else
  507.      i = get_cmd_string();
  508.       unstackscreen();
  509.       if (i > 0)        /* time to redraw? */
  510.      *kbdmore = calc_status = 0;
  511.       break;
  512. #ifndef XFRACT
  513.    case '@':            /* execute commands */
  514.    case '2':            /* execute commands */
  515. #else
  516.    case F2:            /* execute commands */
  517. #endif
  518.       stackscreen();
  519.       i = get_commands();
  520.       if (initmode != -1)
  521.       {                /* video= was specified */
  522.      adapter = initmode;
  523.      initmode = -1;
  524.      i |= 1;
  525.      savedac = 0;
  526.       }
  527.       else if (colorpreloaded)
  528.       {                /* colors= was specified */
  529.      spindac(0, 1);
  530.      colorpreloaded = 0;
  531.       }
  532.       else if ((i & 8))        /* reset was specified */
  533.      savedac = 0;
  534.       if ((i & 4))
  535.       {                /* 3d = was specified */
  536.      *kbdchar = '3';
  537.      unstackscreen();
  538.      goto do_3d_transform;    /* pretend '3' was keyed */
  539.       }
  540.       if ((i & 1))
  541.       {                /* fractal parameter changed */
  542.      discardscreen();
  543.      /* backwards_v18();*/  /* moved this to cmdfiles.c */
  544.      /* backwards_v19();*/
  545.      *kbdmore = calc_status = 0;
  546.       }
  547.       else
  548.      unstackscreen();
  549.       break;
  550.    case 'f':            /* floating pt toggle           */
  551.       if (usr_floatflag == 0)
  552.      usr_floatflag = 1;
  553.       else
  554.      usr_floatflag = 0;
  555.       initmode = adapter;
  556.       return(IMAGESTART);
  557.    case 'i':            /* 3d fractal parms */
  558.       if (get_fract3d_params() >= 0)    /* get the parameters */
  559.      calc_status = *kbdmore = 0;    /* time to redraw */
  560.       break;
  561. #if 0
  562.    case 'w':
  563.       /*chk_keys();*/
  564.       /*julman();*/
  565.       break;
  566. #endif
  567.    case 1:                     /* ^a Ant */
  568.       clear_zoombox();
  569.       {
  570.      int oldtype, err, i;
  571.      double oldparm[MAXPARAMS];
  572.      oldtype = fractype;
  573.      for(i=0;i<MAXPARAMS;i++)
  574.         oldparm[i] = param[i];
  575.      if (fractype != ANT)
  576.      {
  577.         fractype = ANT;
  578.         curfractalspecific = &fractalspecific[fractype];
  579.             load_params(fractype);
  580.      }
  581.      if (!fromtext_flag)
  582.         stackscreen();
  583.      fromtext_flag = 0;
  584.      if ((err = get_fract_params(2)) >= 0)
  585.      {
  586.         unstackscreen();
  587.         if (ant() >= 0)
  588.            calc_status = 0;
  589.      }
  590.      else
  591.         unstackscreen();
  592.      fractype = oldtype;
  593.      for(i=0;i<MAXPARAMS;i++)
  594.         param[i] = oldparm[i];
  595.      if (err >= 0)
  596.         return(CONTINUE);
  597.       }
  598.       break;
  599.    case 'k':                    /* ^s is irritating, give user a single key */
  600.    case 19:            /* ^s RDS */
  601.       clear_zoombox();
  602.       if (get_rds_params() >= 0)
  603.       {
  604.      if (do_AutoStereo() >= 0)
  605.         calc_status = 0;
  606.      return(CONTINUE);
  607.       }
  608.       break;
  609.    case 'a':            /* starfield parms               */
  610.       clear_zoombox();
  611.       if (get_starfield_params() >= 0)
  612.       {
  613.      if (starfield() >= 0)
  614.         calc_status = 0;
  615.      return(CONTINUE);
  616.       }
  617.       break;
  618.    case 15:            /* ctrl-o */
  619.    case 'o':
  620.       /* must use standard fractal and have a float variant */
  621.       if ((fractalspecific[fractype].calctype == StandardFractal
  622.        || fractalspecific[fractype].calctype == calcfroth) &&
  623.       (fractalspecific[fractype].isinteger == 0 ||
  624.        fractalspecific[fractype].tofloat != NOFRACTAL) &&
  625.        !bf_math /* for now no arbitrary precision support */ )
  626.       {
  627.      clear_zoombox();
  628.      Jiim(ORBIT);
  629.       }
  630.       break;
  631.    case SPACE:            /* spacebar, toggle mand/julia     */
  632.       if(bf_math)
  633.          break;
  634.       if (fractype == CELLULAR)
  635.       {
  636.      if (nxtscreenflag)
  637.         nxtscreenflag = 0;    /* toggle flag to stop generation */
  638.      else
  639.         nxtscreenflag = 1;    /* toggle flag to generate next screen */
  640.      calc_status = 2;
  641.      *kbdmore = 0;
  642.       }
  643.       else
  644.       {
  645.      if (curfractalspecific->tojulia != NOFRACTAL
  646.          && param[0] == 0.0 && param[1] == 0.0)
  647.      {
  648.         /* switch to corresponding Julia set */
  649.         int key;
  650.         if ((fractype == MANDEL || fractype == MANDELFP) && bf_math == 0)
  651.           hasinverse = 1;
  652.         else
  653.           hasinverse = 0;
  654.         clear_zoombox();
  655.         Jiim(JIIM);
  656.         key = getakey();    /* flush keyboard buffer */
  657.         if (key != SPACE)
  658.         {
  659.           ungetakey(key);
  660.           break;
  661.         }
  662.         fractype = curfractalspecific->tojulia;
  663.         curfractalspecific = &fractalspecific[fractype];
  664.         if (xcjul == BIG || ycjul == BIG)
  665.         {
  666.            param[0] = (xxmax + xxmin) / 2;
  667.            param[1] = (yymax + yymin) / 2;
  668.         }
  669.         else
  670.         {
  671.            param[0] = xcjul;
  672.            param[1] = ycjul;
  673.            xcjul = ycjul = BIG;
  674.         }
  675.         jxxmin = sxmin;
  676.         jxxmax = sxmax;
  677.         jyymax = symax;
  678.         jyymin = symin;
  679.         jxx3rd = sx3rd;
  680.         jyy3rd = sy3rd;
  681.         *frommandel = 1;
  682.         xxmin = curfractalspecific->xmin;
  683.         xxmax = curfractalspecific->xmax;
  684.         yymin = curfractalspecific->ymin;
  685.         yymax = curfractalspecific->ymax;
  686.         xx3rd = xxmin;
  687.         yy3rd = yymin;
  688.         if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29)
  689.         {
  690.            xxmin *= 3.0;
  691.            xxmax *= 3.0;
  692.            yymin *= 3.0;
  693.            yymax *= 3.0;
  694.            xx3rd *= 3.0;
  695.            yy3rd *= 3.0;
  696.         }
  697.         zoomoff = 1;
  698.         calc_status = 0;
  699.         *kbdmore = 0;
  700.      }
  701.      else if (curfractalspecific->tomandel != NOFRACTAL)
  702.      {
  703.         /* switch to corresponding Mandel set */
  704.         fractype = curfractalspecific->tomandel;
  705.         curfractalspecific = &fractalspecific[fractype];
  706.         if (*frommandel)
  707.         {
  708.            xxmin = jxxmin;
  709.            xxmax = jxxmax;
  710.            yymin = jyymin;
  711.            yymax = jyymax;
  712.            xx3rd = jxx3rd;
  713.            yy3rd = jyy3rd;
  714.         }
  715.         else
  716.         {
  717.            xxmin = xx3rd = curfractalspecific->xmin;
  718.            xxmax = curfractalspecific->xmax;
  719.            yymin = yy3rd = curfractalspecific->ymin;
  720.            yymax = curfractalspecific->ymax;
  721.         }
  722.             SaveC.x = param[0];
  723.         SaveC.y = param[1];
  724.         param[0] = 0;
  725.         param[1] = 0;
  726.         zoomoff = 1;
  727.         calc_status = 0;
  728.         *kbdmore = 0;
  729.      }
  730.      else
  731.         buzzer(2);        /* can't switch */
  732.       }                /* end of else for if == cellular */
  733.       break;
  734.    case 'j':            /* inverse julia toggle */
  735.       /* if the inverse types proliferate, something more elegant will be
  736.        * needed */
  737.       if (fractype == JULIA || fractype == JULIAFP || fractype == INVERSEJULIA)
  738.       {
  739.      static int oldtype = -1;
  740.      if (fractype == JULIA || fractype == JULIAFP)
  741.      {
  742.         oldtype = fractype;
  743.         fractype = INVERSEJULIA;
  744.      }
  745.      else if (fractype == INVERSEJULIA)
  746.      {
  747.         if (oldtype != -1)
  748.            fractype = oldtype;
  749.         else
  750.            fractype = JULIA;
  751.      }
  752.      curfractalspecific = &fractalspecific[fractype];
  753.      zoomoff = 1;
  754.      calc_status = 0;
  755.      *kbdmore = 0;
  756.       }
  757. #if 0
  758.       else if (fractype == MANDEL || fractype == MANDELFP)
  759.       {
  760.      clear_zoombox();
  761.      Jiim(JIIM);
  762.       }
  763. #endif
  764.       else
  765.      buzzer(2);
  766.       break;
  767.    case '\\':            /* return to prev image    */
  768.    case CTL_BACKSLASH:
  769.    case 'h':
  770.    case 8:
  771.       if (name_stack_ptr >= 1)
  772.       {
  773.      /* go back one file if somewhere to go (ie. browsing) */
  774.      name_stack_ptr--;
  775.      strcpy(browsename, file_name_stack[name_stack_ptr]);
  776.      /*
  777.      splitpath(browsename, NULL, NULL, fname, ext);
  778.      splitpath(readname, drive, dir, NULL, NULL);
  779.      makepath(readname, drive, dir, fname, ext);
  780.      */
  781.      merge_pathnames(readname,browsename,2);
  782.      browsing = TRUE;
  783.      no_sub_images = FALSE;
  784.      showfile = 0;
  785.      if (askvideo)
  786.      {
  787.         stackscreen();    /* save graphics image */
  788.         *stacked = 1;
  789.      }
  790.      return(RESTORESTART);
  791.       }
  792.       else if(maxhistory > 0 && bf_math == 0)
  793.       {
  794.          if(*kbdchar == '\\' || *kbdchar == 'h')
  795.         if (--historyptr < 0)
  796.            historyptr = maxhistory - 1;
  797.      if(*kbdchar == CTL_BACKSLASH || *kbdchar == 8)
  798.         if (++historyptr >= maxhistory)
  799.            historyptr = 0;
  800.          restore_history_info(historyptr);
  801.      zoomoff = 1;
  802.      initmode = adapter;
  803.      if (curfractalspecific->isinteger != 0 &&
  804.          curfractalspecific->tofloat != NOFRACTAL)
  805.         usr_floatflag = 0;
  806.      if (curfractalspecific->isinteger == 0 &&
  807.          curfractalspecific->tofloat != NOFRACTAL)
  808.         usr_floatflag = 1;
  809.      historyflag = 1;    /* avoid re-store parms due to rounding errs */
  810.      return(IMAGESTART);
  811.       }
  812.       break;
  813.    case 'd':            /* shell to MS-DOS              */
  814.       stackscreen();
  815. #ifndef XFRACT
  816.       if (axmode == 0 || axmode > 7)
  817.       {
  818.      static FCODE dosmsg[] =
  819.      {"\
  820. Note:  Your graphics image is still squirreled away in your video\n\
  821. adapter's memory.  Switching video modes will clobber part of that\n\
  822. image.  Sorry - it's the best we could do."};
  823.      putstring(0, 0, 7, dosmsg);
  824.      movecursor(6, 0);
  825.       }
  826. #endif
  827.       shell_to_dos();
  828.       unstackscreen();
  829. /*           calc_status = 0; */
  830.       break;
  831.    case 'c':            /* switch to color cycling      */
  832.    case '+':            /* rotate palette               */
  833.    case '-':            /* rotate palette               */
  834.       clear_zoombox();
  835.       memcpy(olddacbox, dacbox, 256 * 3);
  836.       rotate((*kbdchar == 'c') ? 0 : ((*kbdchar == '+') ? 1 : -1));
  837.       if (memcmp(olddacbox, dacbox, 256 * 3))
  838.       {
  839.      colorstate = 1;
  840.          save_history_info();
  841.       }   
  842.       return(CONTINUE);
  843.    case 'e':            /* switch to color editing      */
  844.       clear_zoombox();
  845.       if (dacbox[0][0] != 255 && !reallyega && colors >= 16
  846.       && dotmode != 11)
  847.       {
  848.      int oldhelpmode;
  849.      oldhelpmode = helpmode;
  850.      memcpy(olddacbox, dacbox, 256 * 3);
  851.      helpmode = HELPXHAIR;
  852.      EditPalette();
  853.      helpmode = oldhelpmode;
  854.      if (memcmp(olddacbox, dacbox, 256 * 3))
  855.          {
  856.         colorstate = 1;
  857.             save_history_info();
  858.          }   
  859.       }
  860.       return(CONTINUE);
  861.    case 's':            /* save-to-disk                 */
  862.       diskisactive = 1;        /* flag for disk-video routines */
  863.       note_zoom();
  864.       savetodisk(savename);
  865.       restore_zoom();
  866.       diskisactive = 0;        /* flag for disk-video routines */
  867.       return(CONTINUE);
  868.    case '#':            /* 3D overlay                   */
  869. #ifdef XFRACT
  870.    case F3:            /* 3D overlay                   */
  871. #endif
  872.       clear_zoombox();
  873.       overlay3d = 1;
  874.    case '3':            /* restore-from (3d)            */
  875.     do_3d_transform:
  876.       if (overlay3d)
  877.      display3d = 2;        /* for <b> command          */
  878.       else
  879.      display3d = 1;
  880.    case 'r':            /* restore-from                 */
  881.       comparegif = 0;
  882.       *frommandel = 0;
  883.       if (browsing)
  884.       {
  885.      browsing = FALSE;
  886.       }
  887.       if (*kbdchar == 'r')
  888.       {
  889.      if (debugflag == 50)
  890.      {
  891.         comparegif = overlay3d = 1;
  892.         if (initbatch == 2)
  893.         {
  894.            stackscreen();    /* save graphics image */
  895.            strcpy(readname, savename);
  896.            showfile = 0;
  897.            return(RESTORESTART);
  898.         }
  899.      }
  900.      else
  901.         comparegif = overlay3d = 0;
  902.      display3d = 0;
  903.       }
  904.       stackscreen();        /* save graphics image */
  905.       if (overlay3d)
  906.      *stacked = 0;
  907.       else
  908.      *stacked = 1;
  909.       if (resave_flag)
  910.       {
  911.      updatesavename(savename);    /* do the pending increment */
  912.      resave_flag = started_resaves = 0;
  913.       }
  914.       showfile = -1;
  915.       return(RESTORESTART);
  916.       /* RB */
  917.    case 'l':
  918.    case 'L':            /* Look for other files within this view */
  919.       if ((zwidth == 0) && (!diskvideo))    /* not zooming & no disk
  920.                          * video */
  921.       {
  922.      int oldhelpmode;
  923.      oldhelpmode = helpmode;
  924.      helpmode = HELPBROWSE;
  925.      switch (fgetwindow())
  926.      {
  927.      case ENTER:
  928.      case ENTER_2:
  929.         showfile = 0;    /* trigger load */
  930.         browsing = TRUE;    /* but don't ask for the file name as it's
  931.                  * just been selected */
  932.         if (name_stack_ptr == 15)
  933.         {            /* about to run off the end of the file
  934.                  * history stack so shift it all back one to
  935.                  * make room, lose the 1st one */
  936.            int tmp;
  937.            for (tmp = 1; tmp < 16; tmp++)
  938.           strcpy(file_name_stack[tmp - 1], file_name_stack[tmp]);
  939.            name_stack_ptr = 14;
  940.         }
  941.         name_stack_ptr++;
  942.         strcpy(file_name_stack[name_stack_ptr], browsename);
  943.         /*
  944.         splitpath(browsename, NULL, NULL, fname, ext);
  945.         splitpath(readname, drive, dir, NULL, NULL);
  946.         makepath(readname, drive, dir, fname, ext);
  947.         */
  948.         merge_pathnames(readname,browsename,2);
  949.         if (askvideo)
  950.         {
  951.            stackscreen();    /* save graphics image */
  952.            *stacked = 1;
  953.         }
  954.         return(RESTORESTART);    /* hop off and do it!! */
  955.      case '\\':
  956.         if (name_stack_ptr >= 1)
  957.         {
  958.            /* go back one file if somewhere to go (ie. browsing) */
  959.            name_stack_ptr--;
  960.            strcpy(browsename, file_name_stack[name_stack_ptr]);
  961.            /*
  962.            splitpath(browsename, NULL, NULL, fname, ext);
  963.            splitpath(readname, drive, dir, NULL, NULL);
  964.            makepath(readname, drive, dir, fname, ext);
  965.            */
  966.            merge_pathnames(readname,browsename,2);
  967.            browsing = TRUE;
  968.            showfile = 0;
  969.            if (askvideo)
  970.            {
  971.           stackscreen();/* save graphics image */
  972.           *stacked = 1;
  973.            }
  974.            return(RESTORESTART);
  975.         }            /* otherwise fall through and turn off
  976.                  * browsing */
  977.      case ESC:
  978.      case 'l':        /* turn it off */
  979.      case 'L':
  980.         browsing = FALSE;
  981.         helpmode = oldhelpmode;
  982.         break;
  983.      case 's':
  984.         browsing = FALSE;
  985.         helpmode = oldhelpmode;
  986.         savetodisk(savename);
  987.         break;
  988.      default:        /* or no files found, leave the state of
  989.                  * browsing */
  990.         break;        /* alone */
  991.      }
  992.       }
  993.       else
  994.       {
  995.      browsing = FALSE;
  996.      buzzer(2);        /* can't browse if zooming or diskvideo */
  997.       }
  998.       break;
  999.    case 'b':            /* make batch file              */
  1000.       make_batch_file();
  1001.       break;
  1002.    case 'p':            /* print current image          */
  1003.       note_zoom();
  1004.       Print_Screen();
  1005.       restore_zoom();
  1006.       if (!keypressed())
  1007.      buzzer(0);
  1008.       else
  1009.       {
  1010.      buzzer(1);
  1011.      getakey();
  1012.       }
  1013.       return(CONTINUE);
  1014.    case ENTER:            /* Enter                        */
  1015.    case ENTER_2:        /* Numeric-Keypad Enter         */
  1016. #ifdef XFRACT
  1017.       XZoomWaiting = 0;
  1018. #endif
  1019.       if (zwidth != 0.0)
  1020.       {                /* do a zoom */
  1021.      init_pan_or_recalc(0);
  1022.      *kbdmore = 0;
  1023.       }
  1024.       if (calc_status != 4)    /* don't restart if image complete */
  1025.      *kbdmore = 0;
  1026.       break;
  1027.    case CTL_ENTER:        /* control-Enter                */
  1028.    case CTL_ENTER_2:        /* Control-Keypad Enter         */
  1029.       init_pan_or_recalc(1);
  1030.       *kbdmore = 0;
  1031.       zoomout();        /* calc corners for zooming out */
  1032.       break;
  1033.    case INSERT:        /* insert                       */
  1034.       setvideotext();        /* force text mode */
  1035.       return(RESTART);
  1036.    case LEFT_ARROW:        /* cursor left                  */
  1037.    case RIGHT_ARROW:        /* cursor right                 */
  1038.    case UP_ARROW:        /* cursor up                    */
  1039.    case DOWN_ARROW:        /* cursor down                  */
  1040.    case LEFT_ARROW_2:        /* Ctrl-cursor left             */
  1041.    case RIGHT_ARROW_2:        /* Ctrl-cursor right            */
  1042.    case UP_ARROW_2:        /* Ctrl-cursor up               */
  1043.    case DOWN_ARROW_2:        /* Ctrl-cursor down             */
  1044.       move_zoombox(*kbdchar);
  1045.       break;
  1046.    case CTL_HOME:        /* Ctrl-home                    */
  1047.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1048.       {
  1049.      i = key_count(CTL_HOME);
  1050.      if ((zskew -= 0.02 * i) < -0.48)
  1051.         zskew = -0.48;
  1052.       }
  1053.       break;
  1054.    case CTL_END:        /* Ctrl-end                     */
  1055.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1056.       {
  1057.      i = key_count(CTL_END);
  1058.      if ((zskew += 0.02 * i) > 0.48)
  1059.         zskew = 0.48;
  1060.       }
  1061.       break;
  1062.    case CTL_PAGE_UP:        /* Ctrl-pgup                    */
  1063.       if (boxcount)
  1064.      chgboxi(0, -2 * key_count(CTL_PAGE_UP));
  1065.       break;
  1066.    case CTL_PAGE_DOWN:        /* Ctrl-pgdn                    */
  1067.       if (boxcount)
  1068.      chgboxi(0, 2 * key_count(CTL_PAGE_DOWN));
  1069.       break;
  1070.    case PAGE_UP:        /* page up                      */
  1071.       if (zoomoff == 1)
  1072.      if (zwidth == 0)
  1073.      {            /* start zoombox */
  1074.         zwidth = zdepth = 1;
  1075.         zskew = zrotate = 0;
  1076.         zbx = zby = 0;
  1077.         find_special_colors();
  1078.         boxcolor = color_bright;
  1079.      }
  1080.      else
  1081.         resizebox(0 - key_count(PAGE_UP));
  1082.       break;
  1083.    case PAGE_DOWN:        /* page down                    */
  1084.       if (boxcount)
  1085.       {
  1086.      if (zwidth >= .999 && zdepth >= 0.999)    /* end zoombox */
  1087.         zwidth = 0;
  1088.      else
  1089.         resizebox(key_count(PAGE_DOWN));
  1090.       }
  1091.       break;
  1092.    case CTL_MINUS:        /* Ctrl-kpad-                  */
  1093.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1094.      zrotate += key_count(CTL_MINUS);
  1095.       break;
  1096.    case CTL_PLUS:        /* Ctrl-kpad+               */
  1097.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1098.      zrotate -= key_count(CTL_PLUS);
  1099.       break;
  1100.    case CTL_INSERT:        /* Ctrl-ins                 */
  1101.       boxcolor += key_count(CTL_INSERT);
  1102.       break;
  1103.    case CTL_DEL:        /* Ctrl-del                 */
  1104.       boxcolor -= key_count(CTL_DEL);
  1105.       break;
  1106.    case DELETE:        /* select video mode from list */
  1107.       stackscreen();
  1108.       *kbdchar = select_video_mode(adapter);
  1109.       if (check_vidmode_key(0, *kbdchar) >= 0)    /* picked a new mode? */
  1110.      discardscreen();
  1111.       else
  1112.      unstackscreen();
  1113.       /* fall through */
  1114.    default:            /* other (maybe a valid Fn key) */
  1115.       if ((k = check_vidmode_key(0, *kbdchar)) >= 0)
  1116.       {
  1117.      adapter = k;
  1118. /*          if (videotable[adapter].dotmode != 11       Took out so that */
  1119. /*            || videotable[adapter].colors != colors)  DAC is not reset */
  1120. /*             savedac = 0;                    when changing video modes */
  1121.      calc_status = 0;
  1122.      *kbdmore = 0;
  1123.      return(CONTINUE);
  1124.       }
  1125.       break;
  1126.    }                /* end of the big switch */
  1127.    return(0);
  1128. }
  1129.  
  1130. static int call_line3d(BYTE *pixels, int linelen)
  1131. {
  1132.    /* this routine exists because line3d might be in an overlay */
  1133.    return(line3d(pixels,linelen));
  1134. }
  1135.  
  1136. static void note_zoom()
  1137. {
  1138.    if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */
  1139.       if ((savezoom = farmemalloc((long)(5*boxcount))) == NULL)
  1140.      clear_zoombox(); /* not enuf mem so clear the box */
  1141.       else {
  1142.      reset_zoom_corners(); /* reset these to overall image, not box */
  1143.      far_memcpy(savezoom,boxx,boxcount*2);
  1144.      far_memcpy(savezoom+boxcount*2,boxy,boxcount*2);
  1145.      far_memcpy(savezoom+boxcount*4,boxvalues,boxcount);
  1146.      }
  1147.       }
  1148. }
  1149.  
  1150. static void restore_zoom()
  1151. {
  1152.    if (boxcount) { /* restore zoombox arrays */
  1153.       far_memcpy(boxx,savezoom,boxcount*2);
  1154.       far_memcpy(boxy,savezoom+boxcount*2,boxcount*2);
  1155.       far_memcpy(boxvalues,savezoom+boxcount*4,boxcount);
  1156.       farmemfree(savezoom);
  1157.       drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */
  1158.       }
  1159. }
  1160.  
  1161. /* do all pending movement at once for smooth mouse diagonal moves */
  1162. static void move_zoombox(int keynum)
  1163. {  int vertical, horizontal, getmore;
  1164.    if (boxcount == 0)
  1165.       return;
  1166.    vertical = horizontal = 0;
  1167.    getmore = 1;
  1168.    while (getmore) {
  1169.       switch (keynum) {
  1170.          case LEFT_ARROW:               /* cursor left */
  1171.             --horizontal;
  1172.             break;
  1173.          case RIGHT_ARROW:              /* cursor right */
  1174.             ++horizontal;
  1175.             break;
  1176.          case UP_ARROW:                 /* cursor up */
  1177.             --vertical;
  1178.             break;
  1179.          case DOWN_ARROW:               /* cursor down */
  1180.             ++vertical;
  1181.             break;
  1182.          case LEFT_ARROW_2:             /* Ctrl-cursor left */
  1183.             horizontal -= 5;
  1184.             break;
  1185.          case RIGHT_ARROW_2:             /* Ctrl-cursor right */
  1186.             horizontal += 5;
  1187.             break;
  1188.          case UP_ARROW_2:               /* Ctrl-cursor up */
  1189.             vertical -= 5;
  1190.             break;
  1191.          case DOWN_ARROW_2:             /* Ctrl-cursor down */
  1192.         vertical += 5;
  1193.         break;
  1194.      default:
  1195.         getmore = 0;
  1196.      }
  1197.       if (getmore) {
  1198.      if (getmore == 2)        /* eat last key used */
  1199.         getakey();
  1200.      getmore = 2;
  1201.      keynum = keypressed();     /* next pending key */
  1202.      }
  1203.       }
  1204.    if (horizontal != 0)
  1205.       moveboxf((double)horizontal/dxsize,0.0);
  1206.    if (vertical != 0)
  1207.       moveboxf(0.0,(double)vertical/dysize);
  1208. }
  1209.  
  1210. /* displays differences between current image file and new image */
  1211. static FILE *cmp_fp;
  1212. static errcount;
  1213. int cmp_line(BYTE *pixels, int linelen)
  1214. {
  1215.    int row,col;
  1216.    int oldcolor;
  1217.    if((row = rowcount++) == 0) {
  1218.       errcount = 0;
  1219.       cmp_fp = dir_fopen(workdir,"cmperr",(initbatch)?"a":"w");
  1220.       outln_cleanup = cmp_line_cleanup;
  1221.       }
  1222.    if(pot16bit) { /* 16 bit info, ignore odd numbered rows */
  1223.       if((row & 1) != 0) return(0);
  1224.       row >>= 1;
  1225.       }
  1226.    for(col=0;col<linelen;col++) {
  1227.       oldcolor=getcolor(col,row);
  1228.       if(oldcolor==(int)pixels[col])
  1229.      putcolor(col,row,0);
  1230.       else {
  1231.      if(oldcolor==0)
  1232.         putcolor(col,row,1);
  1233.      ++errcount;
  1234.      if(initbatch == 0)
  1235.         fprintf(cmp_fp,"#%5d col %3d row %3d old %3d new %3d\n",
  1236.            errcount,col,row,oldcolor,pixels[col]);
  1237.      }
  1238.       }
  1239.    return(0);
  1240. }
  1241.  
  1242. static void cmp_line_cleanup(void)
  1243. {
  1244.    char *timestring;
  1245.    time_t ltime;
  1246.    if(initbatch) {
  1247.       time(<ime);
  1248.       timestring = ctime(<ime);
  1249.       timestring[24] = 0; /*clobber newline in time string */
  1250.       fprintf(cmp_fp,"%s compare to %s has %5d errs\n",
  1251.              timestring,readname,errcount);
  1252.       }
  1253.    fclose(cmp_fp);
  1254. }
  1255.  
  1256. int pot_line(BYTE *pixels, int linelen)
  1257. {
  1258.    int row,col,saverowcount;
  1259.    if (rowcount == 0)
  1260.       if (pot_startdisk() < 0)
  1261.      return -1;
  1262.    saverowcount = rowcount;
  1263.    row = (rowcount >>= 1);
  1264.    if ((saverowcount & 1) != 0) /* odd line */
  1265.       row += ydots;
  1266.    else             /* even line */
  1267.       if (dotmode != 11) /* display the line too */
  1268.      out_line(pixels,linelen);
  1269.    for (col = 0; col < xdots; ++col)
  1270.       writedisk(col+sxoffs,row+syoffs,*(pixels+col));
  1271.    rowcount = saverowcount + 1;
  1272.    return(0);
  1273. }
  1274.  
  1275. void clear_zoombox()
  1276. {
  1277.    zwidth = 0;
  1278.    drawbox(0);
  1279.    reset_zoom_corners();
  1280. }
  1281.  
  1282. void reset_zoom_corners()
  1283. {
  1284.    xxmin = sxmin;
  1285.    xxmax = sxmax;
  1286.    xx3rd = sx3rd;
  1287.    yymax = symax;
  1288.    yymin = symin;
  1289.    yy3rd = sy3rd;
  1290.    if(bf_math)
  1291.    {
  1292.       copy_bf(bfxmin,bfsxmin);
  1293.       copy_bf(bfxmax,bfsxmax);
  1294.       copy_bf(bfymin,bfsymin);
  1295.       copy_bf(bfymax,bfsymax);
  1296.       copy_bf(bfx3rd,bfsx3rd);
  1297.       copy_bf(bfy3rd,bfsy3rd);
  1298.    }
  1299. }
  1300.  
  1301. /*
  1302.    Function setup287code is called by main() when a 287
  1303.    or better fpu is detected.
  1304. */
  1305. #define ORBPTR(x) fractalspecific[x].orbitcalc
  1306. void setup287code()
  1307. {
  1308.    ORBPTR(MANDELFP)      = ORBPTR(JULIAFP)     = FJuliafpFractal;
  1309.    ORBPTR(BARNSLEYM1FP)   = ORBPTR(BARNSLEYJ1FP) = FBarnsley1FPFractal;
  1310.    ORBPTR(BARNSLEYM2FP)   = ORBPTR(BARNSLEYJ2FP) = FBarnsley2FPFractal;
  1311.    ORBPTR(MANOWARFP)      = ORBPTR(MANOWARJFP)     = FManOWarfpFractal;
  1312.    ORBPTR(MANDELLAMBDAFP) = ORBPTR(LAMBDAFP)     = FLambdaFPFractal;
  1313. }
  1314.  
  1315. int sound_line(BYTE *pixels, int linelen)
  1316. {
  1317.    int i;
  1318.    for(i=0;i<linelen;i++)
  1319.    {
  1320.       putcolor(i,rowcount,pixels[i]);
  1321.       if(orbit_delay > 0)
  1322.          sleepms(orbit_delay);
  1323.       snd((int)(pixels[i]*3000/colors+basehertz));
  1324.       if(keypressed())
  1325.       {
  1326.         nosnd();
  1327.         return(-1);
  1328.       }
  1329.    }
  1330.    nosnd();
  1331.    rowcount++;
  1332.    return(0);
  1333. }
  1334.  
  1335. /* read keystrokes while = specified key, return 1+count;    */
  1336. /* used to catch up when moving zoombox is slower than keyboard */
  1337. int key_count(int keynum)
  1338. {  int ctr;
  1339.    ctr = 1;
  1340.    while (keypressed() == keynum) {
  1341.       getakey();
  1342.       ++ctr;
  1343.       }
  1344.    return ctr;
  1345. }
  1346.  
  1347. static void _fastcall save_history_info()
  1348. {
  1349.    HISTORY current;
  1350.    if(maxhistory <= 0 || bf_math)
  1351.       return;
  1352.    far_memset((void far *)¤t,0,sizeof(HISTORY));
  1353.    current.fractal_type    = (short)fractype                  ;
  1354.    current.xmin          = xxmin                     ;
  1355.    current.xmax          = xxmax                     ;
  1356.    current.ymin          = yymin                     ;
  1357.    current.ymax          = yymax                     ;
  1358.    current.creal          = param[0]                  ;
  1359.    current.cimag          = param[1]                  ;
  1360.    current.dparm3          = param[2]                  ;
  1361.    current.dparm4          = param[3]                  ;
  1362.    current.dparm5          = param[4]                  ;
  1363.    current.dparm6          = param[5]                  ;
  1364.    current.dparm7          = param[6]                  ;
  1365.    current.dparm8          = param[7]                  ;
  1366.    current.dparm9          = param[8]                  ;
  1367.    current.dparm10         = param[9]                  ;
  1368.    current.fillcolor          = (short)fillcolor                 ;
  1369.    current.potential[0]    = potparam[0]               ;
  1370.    current.potential[1]    = potparam[1]               ;
  1371.    current.potential[2]    = potparam[2]               ;
  1372.    current.rflag          = (short)rflag                     ;
  1373.    current.rseed          = (short)rseed                     ;
  1374.    current.inside          = (short)inside                    ;
  1375.    current.logmap          = (short)LogFlag                   ;
  1376.    current.invert[0]       = inversion[0]              ;
  1377.    current.invert[1]       = inversion[1]              ;
  1378.    current.invert[2]       = inversion[2]              ;
  1379.    current.decomp          = (short)decomp[0];                ;
  1380.    current.biomorph        = (short)biomorph                  ;
  1381.    current.symmetry          = (short)forcesymmetry             ;
  1382.    current.init3d[0]       = (short)init3d[0]                 ;
  1383.    current.init3d[1]       = (short)init3d[1]                 ;
  1384.    current.init3d[2]       = (short)init3d[2]                 ;
  1385.    current.init3d[3]       = (short)init3d[3]                 ;
  1386.    current.init3d[4]       = (short)init3d[4]                 ;
  1387.    current.init3d[5]       = (short)init3d[5]                 ;
  1388.    current.init3d[6]       = (short)init3d[6]                 ;
  1389.    current.init3d[7]       = (short)init3d[7]                 ;
  1390.    current.init3d[8]       = (short)init3d[8]                 ;
  1391.    current.init3d[9]       = (short)init3d[9]                 ;
  1392.    current.init3d[10]       = (short)init3d[10]               ;
  1393.    current.init3d[11]       = (short)init3d[12]               ;
  1394.    current.init3d[12]       = (short)init3d[13]               ;
  1395.    current.init3d[13]       = (short)init3d[14]               ;
  1396.    current.init3d[14]       = (short)init3d[15]               ;
  1397.    current.init3d[15]       = (short)init3d[16]               ;
  1398.    current.previewfactor   = (short)previewfactor             ;
  1399.    current.xtrans          = (short)xtrans                    ;
  1400.    current.ytrans          = (short)ytrans                    ;
  1401.    current.red_crop_left   = (short)red_crop_left             ;
  1402.    current.red_crop_right  = (short)red_crop_right            ;
  1403.    current.blue_crop_left  = (short)blue_crop_left            ;
  1404.    current.blue_crop_right = (short)blue_crop_right           ;
  1405.    current.red_bright      = (short)red_bright                ;
  1406.    current.blue_bright     = (short)blue_bright               ;
  1407.    current.xadjust          = (short)xadjust                   ;
  1408.    current.yadjust          = (short)yadjust                   ;
  1409.    current.eyeseparation   = (short)eyeseparation             ;
  1410.    current.glassestype     = (short)glassestype               ;
  1411.    current.outside          = (short)outside                   ;
  1412.    current.x3rd          = xx3rd                     ;
  1413.    current.y3rd          = yy3rd                     ;
  1414.    current.stdcalcmode     = stdcalcmode               ;
  1415.    current.three_pass      = three_pass                ;
  1416.    current.distest          = (short)distest                   ;
  1417.    current.trigndx[0]      = trigndx[0]                ;
  1418.    current.trigndx[1]      = trigndx[1]                ;
  1419.    current.trigndx[2]      = trigndx[2]                ;
  1420.    current.trigndx[3]      = trigndx[3]                ;
  1421.    current.finattract      = (short)finattract                ;
  1422.    current.initorbit[0]    = initorbit.x               ;
  1423.    current.initorbit[1]    = initorbit.y               ;
  1424.    current.useinitorbit    = useinitorbit              ;
  1425.    current.periodicity     = (short)periodicitycheck          ;
  1426.    current.pot16bit          = (short)disk16bit                 ;
  1427.    current.release          = (short)release                   ;
  1428.    current.save_release    = (short)save_release              ;
  1429.    current.flag3d          = (short)display3d                 ;
  1430.    current.ambient          = (short)Ambient                   ;
  1431.    current.randomize       = (short)RANDOMIZE                 ;
  1432.    current.haze          = (short)haze                      ;
  1433.    current.transparent[0]  = (short)transparent[0]            ;
  1434.    current.transparent[1]  = (short)transparent[1]            ;
  1435.    current.rotate_lo       = (short)rotate_lo                 ;
  1436.    current.rotate_hi       = (short)rotate_hi                 ;
  1437.    current.distestwidth    = (short)distestwidth              ;
  1438.    current.mxmaxfp         = mxmaxfp                   ;
  1439.    current.mxminfp         = mxminfp                   ;
  1440.    current.mymaxfp         = mymaxfp                   ;
  1441.    current.myminfp         = myminfp                   ;
  1442.    current.zdots           = (short)zdots                  ;
  1443.    current.originfp        = originfp                  ;
  1444.    current.depthfp         = depthfp                      ;
  1445.    current.heightfp        = heightfp                  ;
  1446.    current.widthfp         = widthfp                      ;
  1447.    current.distfp          = distfp                      ;
  1448.    current.eyesfp          = eyesfp                      ;
  1449.    current.orbittype       = (short)neworbittype              ;
  1450.    current.juli3Dmode      = (short)juli3Dmode                ;
  1451.    current.maxfn           = maxfn                     ;
  1452.    current.major_method    = (short)major_method              ;
  1453.    current.minor_method    = (short)minor_method              ;
  1454.    current.bailout         = bailout                   ;
  1455.    current.bailoutest      = (short)bailoutest                ;
  1456.    current.iterations      = maxit                     ;
  1457.    current.old_demm_colors = (short)old_demm_colors;
  1458.    far_memcpy(current.dac,dacbox,256*3);
  1459.    switch(fractype)
  1460.    {
  1461.    case FORMULA:
  1462.    case FFORMULA:
  1463.       far_strncpy(current.filename,FormFileName,80);
  1464.       far_strncpy(current.itemname,FormName,ITEMNAMELEN+1);
  1465.       break;
  1466.    case IFS:
  1467.    case IFS3D:
  1468.       far_strncpy(current.filename,IFSFileName,80);
  1469.       far_strncpy(current.itemname,IFSName,ITEMNAMELEN+1);
  1470.       break;
  1471.    case LSYSTEM:
  1472.       far_strncpy(current.filename,LFileName,80);
  1473.       far_strncpy(current.itemname,LName,ITEMNAMELEN+1);
  1474.       break;
  1475.    default:
  1476.       *(current.filename) = 0;
  1477.       *(current.itemname) = 0;
  1478.       break;
  1479.    }
  1480.    if (historyptr == -1)    /* initialize the history file */
  1481.    {
  1482.       int i;
  1483.       for (i = 0; i < maxhistory; i++) 
  1484.          history[i] = current;
  1485.       historyflag = saveptr = historyptr = 0;    /* initialize history ptr */
  1486.    }
  1487.    else if(historyflag == 1)
  1488.       historyflag = 0;   /* coming from user history command, don't save */
  1489.    else if(far_memcmp(¤t,&history[saveptr],sizeof(HISTORY)))
  1490.    {
  1491.       char msg[80];
  1492.       if(++saveptr >= maxhistory)  /* back to beginning of circular buffer */
  1493.          saveptr = 0; 
  1494.       if(++historyptr >= maxhistory)  /* move user pointer in parallel */
  1495.          historyptr = 0; 
  1496.       history[saveptr] = current;
  1497.       sprintf(msg,"saving image in history %d",saveptr);
  1498.       /* stopmsg(0,msg); */
  1499.    }
  1500. }
  1501.  
  1502. static void _fastcall restore_history_info(int i)
  1503. {
  1504.    char msg[80];
  1505.    sprintf(msg,"restoring msg %d",i);
  1506.    /* stopmsg(0,msg); */
  1507.    if(maxhistory <= 0 || bf_math)
  1508.       return;
  1509.    invert = 0;
  1510.    calc_status = 0;
  1511.    resuming = 0;
  1512.    fractype              = history[i].fractal_type   ;
  1513.    xxmin                 = history[i].xmin         ;
  1514.    xxmax                 = history[i].xmax         ;
  1515.    yymin                 = history[i].ymin         ;
  1516.    yymax                 = history[i].ymax         ;
  1517.    param[0]              = history[i].creal         ;
  1518.    param[1]              = history[i].cimag         ;
  1519.    param[2]              = history[i].dparm3         ;
  1520.    param[3]              = history[i].dparm4         ;
  1521.    param[4]              = history[i].dparm5         ;
  1522.    param[5]              = history[i].dparm6         ;
  1523.    param[6]              = history[i].dparm7         ;
  1524.    param[7]              = history[i].dparm8         ;
  1525.    param[8]              = history[i].dparm9         ;
  1526.    param[9]              = history[i].dparm10        ;
  1527.    fillcolor             = history[i].fillcolor         ;
  1528.    potparam[0]           = history[i].potential[0]   ;
  1529.    potparam[1]           = history[i].potential[1]   ;
  1530.    potparam[2]           = history[i].potential[2]   ;
  1531.    rflag                 = history[i].rflag         ;
  1532.    rseed                 = history[i].rseed         ;
  1533.    inside                = history[i].inside         ;
  1534.    LogFlag               = history[i].logmap         ;
  1535.    inversion[0]          = history[i].invert[0]      ;
  1536.    inversion[1]          = history[i].invert[1]      ;
  1537.    inversion[2]          = history[i].invert[2]      ;
  1538.    decomp[0]             = history[i].decomp         ;
  1539.    usr_biomorph          = history[i].biomorph       ;
  1540.    biomorph              = history[i].biomorph         ;
  1541.    forcesymmetry         = history[i].symmetry         ;
  1542.    init3d[0]             = history[i].init3d[0]      ;
  1543.    init3d[1]             = history[i].init3d[1]      ;
  1544.    init3d[2]             = history[i].init3d[2]      ;
  1545.    init3d[3]             = history[i].init3d[3]      ;
  1546.    init3d[4]             = history[i].init3d[4]      ;
  1547.    init3d[5]             = history[i].init3d[5]      ;
  1548.    init3d[6]             = history[i].init3d[6]      ;
  1549.    init3d[7]             = history[i].init3d[7]      ;
  1550.    init3d[8]             = history[i].init3d[8]      ;
  1551.    init3d[9]             = history[i].init3d[9]      ;
  1552.    init3d[10]            = history[i].init3d[10]     ;
  1553.    init3d[12]            = history[i].init3d[11]     ;
  1554.    init3d[13]            = history[i].init3d[12]     ;
  1555.    init3d[14]            = history[i].init3d[13]     ;
  1556.    init3d[15]            = history[i].init3d[14]     ;
  1557.    init3d[16]            = history[i].init3d[15]     ;
  1558.    previewfactor         = history[i].previewfactor  ;
  1559.    xtrans                = history[i].xtrans         ;
  1560.    ytrans                = history[i].ytrans         ;
  1561.    red_crop_left         = history[i].red_crop_left  ;
  1562.    red_crop_right        = history[i].red_crop_right ;
  1563.    blue_crop_left        = history[i].blue_crop_left ;
  1564.    blue_crop_right       = history[i].blue_crop_right;
  1565.    red_bright            = history[i].red_bright     ;
  1566.    blue_bright           = history[i].blue_bright    ;
  1567.    xadjust               = history[i].xadjust         ;
  1568.    yadjust               = history[i].yadjust         ;
  1569.    eyeseparation         = history[i].eyeseparation  ;
  1570.    glassestype           = history[i].glassestype    ;
  1571.    outside               = history[i].outside         ;
  1572.    xx3rd                 = history[i].x3rd         ;
  1573.    yy3rd                 = history[i].y3rd         ;
  1574.    usr_stdcalcmode       = history[i].stdcalcmode    ;
  1575.    stdcalcmode           = history[i].stdcalcmode    ;
  1576.    three_pass            = history[i].three_pass     ;
  1577.    distest               = history[i].distest         ;
  1578.    usr_distest           = history[i].distest        ;
  1579.    trigndx[0]            = history[i].trigndx[0]     ;
  1580.    trigndx[1]            = history[i].trigndx[1]     ;
  1581.    trigndx[2]            = history[i].trigndx[2]     ;
  1582.    trigndx[3]            = history[i].trigndx[3]     ;
  1583.    finattract            = history[i].finattract     ;
  1584.    initorbit.x           = history[i].initorbit[0]   ;
  1585.    initorbit.y           = history[i].initorbit[1]   ;
  1586.    useinitorbit          = history[i].useinitorbit   ;
  1587.    periodicitycheck      = history[i].periodicity    ;
  1588.    usr_periodicitycheck  = history[i].periodicity    ;
  1589.    disk16bit             = history[i].pot16bit         ;
  1590.    release               = history[i].release         ;
  1591.    save_release          = history[i].save_release   ;
  1592.    display3d             = history[i].flag3d         ;
  1593.    Ambient               = history[i].ambient         ;
  1594.    RANDOMIZE             = history[i].randomize      ;
  1595.    haze                  = history[i].haze         ;
  1596.    transparent[0]        = history[i].transparent[0] ;
  1597.    transparent[1]        = history[i].transparent[1] ;
  1598.    rotate_lo             = history[i].rotate_lo      ;
  1599.    rotate_hi             = history[i].rotate_hi      ;
  1600.    distestwidth          = history[i].distestwidth   ;
  1601.    mxmaxfp               = history[i].mxmaxfp        ;
  1602.    mxminfp               = history[i].mxminfp        ;
  1603.    mymaxfp               = history[i].mymaxfp        ;
  1604.    myminfp               = history[i].myminfp        ;
  1605.    zdots                 = history[i].zdots          ;        
  1606.    originfp              = history[i].originfp       ;
  1607.    depthfp               = history[i].depthfp        ;    
  1608.    heightfp              = history[i].heightfp       ;
  1609.    widthfp               = history[i].widthfp        ;    
  1610.    distfp                = history[i].distfp         ;    
  1611.    eyesfp                = history[i].eyesfp         ;    
  1612.    neworbittype          = history[i].orbittype      ;
  1613.    juli3Dmode            = history[i].juli3Dmode     ;
  1614.    maxfn                 = history[i].maxfn          ;
  1615.    major_method          = (enum Major)history[i].major_method   ;
  1616.    minor_method          = (enum Minor)history[i].minor_method   ;
  1617.    bailout               = history[i].bailout        ;
  1618.    bailoutest            = (enum bailouts)history[i].bailoutest     ;
  1619.    maxit                 = history[i].iterations     ;
  1620.    old_demm_colors       = history[i].old_demm_colors;
  1621.    curfractalspecific    = &fractalspecific[fractype];
  1622.    potflag               = (potparam[0] != 0.0);
  1623.    if (inversion[0] != 0.0)
  1624.       invert = 3;
  1625.    usr_floatflag = (char)((curfractalspecific->isinteger) ? 0 : 1);
  1626.    far_memcpy(dacbox,history[i].dac,256*3);
  1627.    far_memcpy(olddacbox,history[i].dac,256*3);
  1628.    if(mapdacbox)
  1629.       far_memcpy(mapdacbox,history[i].dac,256*3);
  1630.    spindac(0,1);
  1631.    if(fractype == JULIBROT || fractype == JULIBROTFP)
  1632.       savedac = 0;
  1633.    else
  1634.       savedac = 1;
  1635.    switch(fractype)
  1636.    {
  1637.    case FORMULA:
  1638.    case FFORMULA:
  1639.       far_strncpy(FormFileName,history[i].filename,80);
  1640.       far_strncpy(FormName,    history[i].itemname,ITEMNAMELEN+1);
  1641.       break;
  1642.    case IFS:
  1643.    case IFS3D:
  1644.       far_strncpy(IFSFileName,history[i].filename,80);
  1645.       far_strncpy(IFSName    ,history[i].itemname,ITEMNAMELEN+1);
  1646.       break;
  1647.    case LSYSTEM:
  1648.       far_strncpy(LFileName,history[i].filename,80);
  1649.       far_strncpy(LName    ,history[i].itemname,ITEMNAMELEN+1);
  1650.       break;
  1651.    default:
  1652.       break;
  1653.    }
  1654. }
  1655.  
  1656. void checkfreemem(int secondpass)
  1657. {
  1658.    int oldmaxhistory;
  1659.    char far *tmp;
  1660.    static FCODE msg[] = 
  1661.       {" I'm sorry, but you don't have enough free memory \n to run this program.\n\n"};
  1662.    static FCODE msg2[] = {"To save memory, reduced maxhistory to "}; 
  1663.    tmp = farmemalloc(4096L);
  1664.    oldmaxhistory = maxhistory;
  1665.    if(secondpass && !history)
  1666.    {
  1667.       while(maxhistory >= 0) /* decrease history if necessary */
  1668.       {
  1669.          history = (HISTORY far *) 
  1670.             farmemalloc(((unsigned long)maxhistory * sizeof(HISTORY)));
  1671.          if(history)
  1672.             break;
  1673.          maxhistory--;   
  1674.       }
  1675.    }   
  1676.    if(extraseg == 0 || tmp == NULL)
  1677.    {    
  1678.       buzzer(2);
  1679. #ifndef XFRACT
  1680.       printf("%Fs",(char far *)msg);
  1681. #else
  1682.       printf("%s",msg);
  1683. #endif            
  1684.       exit(1);
  1685.    }
  1686.    farmemfree(tmp); /* was just to check for min space */
  1687.    if(secondpass && maxhistory < oldmaxhistory)
  1688.    {
  1689. #ifndef XFRACT
  1690.       printf("%Fs%d\n%Fs\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue);
  1691. #else
  1692.       printf("%s%d\n%s\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue);
  1693. #endif            
  1694.       getakey(); 
  1695.    }
  1696. }
  1697.