home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / windows / winsrc.zip / MISCRES.C < prev    next >
Text File  |  1990-12-17  |  18KB  |  615 lines

  1. /*
  2.     Resident odds and ends that don't fit anywhere else.
  3. */
  4.  
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <time.h>
  10. #include <stdarg.h>
  11. #ifdef __TURBOC__
  12. #include <dir.h>
  13. #endif
  14. #include "fractint.h"
  15. #include "fractype.h"
  16.  
  17. /* routines in this module    */
  18.  
  19. extern    void restore_active_ovly(void );
  20. extern    void findpath(char *filename,char *fullpathname);
  21. extern    void notdiskmsg(void );
  22. extern    int cvtcentermag(double *Xctr,double *Yctr,double *Magnification);
  23. extern    void updatesavename(char *name);
  24. extern    int check_key(void );
  25. extern    int timer(int timertype,int(*subrtn)(),...);
  26. extern    void showtrig(char *buf);
  27. extern    int set_trig_array(int k,char *name);
  28. extern    void set_trig_pointers(int which);
  29. extern    int tab_display(void );
  30. extern    int endswithslash(char *fl);
  31. extern    int ifsgetfile(void );
  32. extern    int ifs3dgetfile(void );
  33.  
  34. static    void trigdetails(char *);
  35.  
  36. int active_ovly = -1;
  37. long timer_start,timer_interval;    /* timer(...) start & total */
  38.  
  39. extern    char    ifsfilename[80];    /* IFS code file */
  40. extern    char    ifs3dfilename[80];  /* IFS 3D code file */
  41. extern char temp[], temp1[256];   /* temporary strings          */
  42.  
  43. extern int  active_ovly;
  44. extern int  xdots, ydots;
  45. extern int  dotmode;
  46. extern int  show_orbit;
  47. extern int  timerflag;
  48. extern int  debugflag;
  49. extern int  maxit;
  50. extern int  fractype;
  51. extern int  got_status,curpass,totpasses,currow,curcol;
  52. extern int  xxstart,xxstop,yystart,yystop;
  53. extern int  display3d;
  54.  
  55. /* call next when returning from resident routine and unsure whether
  56.    caller is an overlay which has been displaced */
  57. void restore_active_ovly()
  58. {
  59.    switch (active_ovly) {
  60.       case OVLY_MISCOVL:  miscovl_overlay();  break;
  61.       case OVLY_CMDFILES: cmdfiles_overlay(); break;
  62.       case OVLY_HELP:      help_overlay();     break;
  63.       case OVLY_PROMPTS:  prompts_overlay();  break;
  64.       case OVLY_LOADFILE: loadfile_overlay(); break;
  65.       case OVLY_ROTATE:   rotate_overlay();   break;
  66.       case OVLY_PRINTER:  printer_overlay();  break;
  67.       case OVLY_LINE3D:   line3d_overlay();   break;
  68.       case OVLY_ENCODER:  encoder_overlay();  break;
  69.       case OVLY_CALCFRAC: calcfrac_overlay(); break;
  70.       }
  71. }
  72.  
  73.  
  74. void findpath(char *filename, char *fullpathname) /* return full pathnames */
  75. {
  76.    if (filename[0] == '\\'
  77.      || (filename[0] && filename[1] == ':')) {
  78.       strcpy(fullpathname,filename);
  79.       return;
  80.       }
  81.    fullpathname[0] = 0;             /* indicate none found */
  82. #ifdef __TURBOC__                /* look for the file */
  83.    strcpy(fullpathname,searchpath(filename));
  84. #else
  85.    _searchenv(filename,"PATH",fullpathname);
  86. #endif
  87.    if (fullpathname[0] != 0)            /* found it! */
  88.       if (strncmp(&fullpathname[2],"\\\\",2) == 0) /* stupid klooge! */
  89.      strcpy(&fullpathname[3],filename);
  90. }
  91.  
  92.  
  93. void notdiskmsg()
  94. {
  95. static char far sorrymsg[]={"\
  96. I'm sorry, but because of its random-screen-access algorithms, this\n\
  97. type cannot be created using a real-disk based 'video' mode."};
  98.    stopmsg(1,sorrymsg);
  99. }
  100.  
  101.  
  102. /* convert corners to center/mag */
  103. int cvtcentermag(double *Xctr, double *Yctr, double *Magnification)
  104. {
  105.    extern double xxmax,xxmin,yymax,yymin,xx3rd,yy3rd;
  106.    double Width, Height, Radius, Ratio;
  107.    Width  = xxmax - xxmin;
  108.    Height = yymax - yymin;
  109.    Ratio = Height / Width;
  110.    if(xx3rd != xxmin || yy3rd != yymin || Width < 0
  111.      || (Width > 1e-8 && (Ratio <= 0.74 || Ratio >= 0.76))
  112.      || Ratio < 0.66 || Ratio > 0.84)
  113.       return(0);
  114.    /* calculate center and magnification */
  115.    Radius = Height / 2.0;
  116.    *Xctr = xxmin + (Width / 2.0);
  117.    *Yctr = yymin + Radius;
  118.    *Magnification = 1.0 / Radius;
  119.    return(1);
  120. }
  121.  
  122.  
  123. void updatesavename(char *filename) /* go to the next file name */
  124. {
  125.    char *save, *hold;
  126.    char name[80],suffix[80];
  127.    char *dotptr;
  128.  
  129.    strcpy(name,filename);
  130.    suffix[0] = 0;
  131.    if ((dotptr = strrchr(name,'.')) != NULL
  132.      && dotptr > strrchr(name,'\\')) {
  133.       strcpy(suffix,dotptr);
  134.       *dotptr = 0;
  135.       }
  136.  
  137.    hold = name + strlen(name) - 1; /* start at the end */
  138.    while(hold >= name && (*hold == ' ' || isdigit(*hold))) /* skip backwards */
  139.       hold--;
  140.    hold++;            /* recover first digit */
  141.    while (*hold == '0')         /* skip leading zeros */
  142.       hold++;
  143.    save = hold;
  144.    while (*save) {        /* check for all nines */
  145.       if (*save != '9')
  146.      break;
  147.       save++;
  148.       }
  149.    if (!*save)            /* if the whole thing is nines then back */
  150.       save = hold - 1;        /* up one place. Note that this will eat */
  151.                 /* your last letter if you go to far.     */
  152.    else
  153.       save = hold;
  154.    itoa(atoi(hold) + 1, save, 10); /* increment the number */
  155.    strcpy(filename,name);
  156.    strcat(filename,suffix);
  157. }
  158.  
  159.  
  160. int check_key()
  161. {
  162.    int key;
  163.    if((key = keypressed()) != 0) {
  164.       if(key != 'o' && key != 'O')
  165.      return(-1);
  166.       getakey();
  167.       if (dotmode != 11)
  168.      show_orbit = 1 - show_orbit;
  169.    }
  170.    return(0);
  171. }
  172.  
  173.  
  174. /* timer function:
  175.      timer(0,(*fractal)())        fractal engine
  176.      timer(1,NULL,int width)        decoder
  177.      timer(2)                encoder
  178.   */
  179. int timer(int timertype,int(*subrtn)(),...)
  180. {
  181.    va_list arg_marker;    /* variable arg list */
  182.    char *timestring;
  183.    time_t ltime;
  184.    FILE *fp;
  185.    int out;
  186.    int i;
  187.    int do_bench;
  188.  
  189.    va_start(arg_marker,subrtn);
  190.    do_bench = timerflag; /* record time? */
  191.    if (timertype == 2)     /* encoder, record time only if debug=200 */
  192.       do_bench = (debugflag == 200);
  193.    if(do_bench)
  194.       fp=fopen("bench","a");
  195.    timer_start = clock();
  196.    switch(timertype) {
  197.       case 0:
  198.      out = (*subrtn)();
  199.      break;
  200.       case 1:
  201.      i = va_arg(arg_marker,int);
  202.      out = decoder(i);         /* not indirect, safer with overlays */
  203.      break;
  204.       case 2:
  205.      out = encoder();         /* not indirect, safer with overlays */
  206.      break;
  207.       }
  208.    /* next assumes CLK_TCK is 10^n, n>=2 */
  209.    timer_interval = (clock() - timer_start) / (CLK_TCK/100);
  210.  
  211.    if(do_bench) {
  212.       time(<ime);
  213.       timestring = ctime(<ime);
  214.       timestring[24] = 0; /*clobber newline in time string */
  215.       switch(timertype) {
  216.      case 1:
  217.         fprintf(fp,"decode ");
  218.         break;
  219.      case 2:
  220.         fprintf(fp,"encode ");
  221.         break;
  222.      }
  223.       fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%d",
  224.       timestring,
  225.       fractalspecific[fractype].name,
  226.       xdots,
  227.       ydots,
  228.       maxit);
  229.       fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100);
  230.       if(fp != NULL)
  231.      fclose(fp);
  232.       }
  233.    return(out);
  234. }
  235.  
  236.  
  237. extern void lStkSin(void), dStkSin(void), lStkCos(void), dStkCos(void);
  238. extern void lStkSinh(void),dStkSinh(void),lStkCosh(void),dStkCosh(void);
  239. extern void lStkExp(void), dStkExp(void), lStkLog(void), dStkLog(void);
  240. extern void lStkSqr(void), dStkSqr(void);
  241.  
  242. unsigned char trigndx[] = {SIN,SQR,SINH,COSH};
  243. void (*ltrig0)() = lStkSin;
  244. void (*ltrig1)() = lStkSqr;
  245. void (*ltrig2)() = lStkSinh;
  246. void (*ltrig3)() = lStkCosh;
  247. void (*dtrig0)() = dStkSin;
  248. void (*dtrig1)() = dStkSqr;
  249. void (*dtrig2)() = dStkSinh;
  250. void (*dtrig3)() = dStkCosh;
  251.  
  252. struct trig_funct_lst trigfn[] =
  253. /* changing the order of these alters meaning of *.fra file */
  254. {
  255.    {"sin", lStkSin, dStkSin },
  256.    {"cos", lStkCos, dStkCos },
  257.    {"sinh",lStkSinh,dStkSinh},
  258.    {"cosh",lStkCosh,dStkCosh},
  259.    {"exp", lStkExp, dStkExp },
  260.    {"log", lStkLog, dStkLog },
  261.    {"sqr", lStkSqr, dStkSqr }
  262. };
  263.  
  264. void showtrig(char *buf) /* return display form of active trig functions */
  265. {
  266.    char tmpbuf[30];
  267.    *buf = 0; /* null string if none */
  268.    trigdetails(tmpbuf);
  269.    if (tmpbuf[0])
  270.       sprintf(buf," function=%s",tmpbuf);
  271. }
  272.  
  273. static void trigdetails(char *buf)
  274. {
  275.    int i, numfn;
  276.    char tmpbuf[20];
  277.    *buf = 0; /* null string if none */
  278.    if ((numfn = (fractalspecific[fractype].flags >> 6) & 7)) {
  279.       strcpy(buf,trigfn[trigndx[0]].name);
  280.       i = 0;
  281.       while(++i < numfn) {
  282.      sprintf(tmpbuf,"/%s",trigfn[trigndx[i]].name);
  283.      strcat(buf,tmpbuf);
  284.      }
  285.       }
  286. }
  287.  
  288. /* set array of trig function indices according to "function=" command */
  289. int set_trig_array(int k, char *name)
  290. {
  291.    char trigname[6];
  292.    int i, lstlen;
  293.    char *slash;
  294.    strncpy(trigname,name,5);
  295.    trigname[5] = 0; /* safety first */
  296.  
  297.    if ((slash = strchr(trigname,'/')))
  298.       *slash = 0;
  299.  
  300.    strlwr(trigname);
  301.    lstlen = sizeof(trigfn)/sizeof(struct trig_funct_lst);
  302.  
  303.    for(i=0;i<lstlen;i++)
  304.    {
  305.       if(strcmp(trigname,trigfn[i].name)==0)
  306.       {
  307.      trigndx[k] = i;
  308.      set_trig_pointers(k);
  309.      break;
  310.       }
  311.    }
  312.    return(0);
  313. }
  314. void set_trig_pointers(int which)
  315. {
  316.   /* set trig variable functions to avoid array lookup time */
  317.    int i;
  318.    switch(which)
  319.    {
  320.    case 0:
  321.       ltrig0 = trigfn[trigndx[0]].lfunct;
  322.       dtrig0 = trigfn[trigndx[0]].dfunct;
  323.       break;
  324.    case 1:
  325.       ltrig1 = trigfn[trigndx[1]].lfunct;
  326.       dtrig1 = trigfn[trigndx[1]].dfunct;
  327.       break;
  328.    case 2:
  329.       ltrig2 = trigfn[trigndx[2]].lfunct;
  330.       dtrig2 = trigfn[trigndx[2]].dfunct;
  331.       break;
  332.    case 3:
  333.       ltrig3 = trigfn[trigndx[3]].lfunct;
  334.       dtrig3 = trigfn[trigndx[3]].dfunct;
  335.       break;
  336.    default: /* do 'em all */
  337.       for(i=0;i<4;i++)
  338.      set_trig_pointers(i);
  339.       break;
  340.    }
  341. }
  342.  
  343.  
  344. int tab_display()    /* display the status of the current image */
  345. {
  346.    extern char usr_floatflag;
  347.    extern double xxmin, xxmax, xx3rd, yymin, yymax, yy3rd;
  348.    extern double param[4];
  349.    extern double rqlim;
  350.    extern long calctime, timer_start;
  351.    extern int  calc_status;
  352.    extern char FormName[];
  353.    extern int  rseed;
  354.    extern char LName[];
  355.    extern int  invert;
  356.    int row, i;
  357.    double Xctr, Yctr, Magnification;
  358.    char msg[81];
  359.    char *msgptr;
  360.  
  361.    if (calc_status < 0)     /* no active fractal image */
  362.       return(0);        /* (no TAB on the credits screen) */
  363.    if (calc_status == 1)    /* next assumes CLK_TCK is 10^n, n>=2 */
  364.       calctime += (clock() - timer_start) / (CLK_TCK/100);
  365.    stackscreen();
  366.    helptitle();
  367.    setattr(1,0,C_GENERAL_MED,24*80); /* init rest to background */
  368.  
  369.    row = 3;
  370.    putstring(row,2,C_GENERAL_MED,"Fractal type:");
  371.    if (display3d > 0)
  372.       putstring(row,16,C_GENERAL_HI,"3D Transform");
  373.    else {
  374.       putstring(row,16,C_GENERAL_HI,
  375.        fractalspecific[fractype].name[0] == '*' ?
  376.          &fractalspecific[fractype].name[1] :
  377.          fractalspecific[fractype].name);
  378.       trigdetails(msg);
  379.       putstring(row+1,16,C_GENERAL_HI,msg);
  380.       if (fractype == FORMULA || fractype == FFORMULA)
  381.      putstring(row+1,16,C_GENERAL_HI,FormName);
  382.       if (fractype == LSYSTEM)
  383.      putstring(row+1,16,C_GENERAL_HI,LName);
  384.       }
  385.    switch (calc_status) {
  386.       case 0:  msgptr = "Parms chgd since generated";
  387.            break;
  388.       case 1:  msgptr = "Still being generated";
  389.            break;
  390.       case 2:  msgptr = "Interrupted, resumable";
  391.            break;
  392.       case 3:  msgptr = "Interrupted, non-resumable";
  393.            break;
  394.       case 4:  msgptr = "Image completed";
  395.            break;
  396.       default: msgptr = "";
  397.       }
  398.    putstring(row,45,C_GENERAL_HI,msgptr);
  399.    if (helpmode == HELPCYCLING)
  400.       putstring(row+1,45,C_GENERAL_HI,"You are in color-cycling mode");
  401.    row += 2;
  402.  
  403.    i = 0;
  404.    if (usr_floatflag) {
  405.       putstring(row,45,C_GENERAL_HI,"Floating-point flag is activated");
  406.       i = 1;
  407.       }
  408.    if (calc_status == 1 || calc_status == 2)
  409.       if (fractalspecific[fractype].flags&INFCALC) {
  410.      putstring(row,2,C_GENERAL_HI,"Note: this type runs forever.");
  411.      i = 1;
  412.      }
  413.    row += i;
  414.  
  415.    if (calc_status == 1 || calc_status == 2)
  416.       if (fractalspecific[fractype].flags&NORESUME)
  417.      putstring(row++,2,C_GENERAL_HI,"Note: can't resume this type after interrupts other than <tab> and <F1>");
  418.    ++row;
  419.  
  420.    if (got_status >= 0 && (calc_status == 1 || calc_status == 2)) {
  421.       if (got_status == 1)
  422.      putstring(row,2,C_GENERAL_HI,"Solid Guessing");
  423.       else if (got_status == 2)
  424.      putstring(row,2,C_GENERAL_HI,"Boundary Tracing");
  425.       else {
  426.      sprintf(msg,"%d Pass Mode",totpasses);
  427.      putstring(row,2,C_GENERAL_HI,msg);
  428.      }
  429.       ++row;
  430.       sprintf(msg,"Working on block (y,x) [%d,%d]...[%d,%d], ",
  431.          yystart,xxstart,yystop,xxstop);
  432.       putstring(row,2,C_GENERAL_MED,msg);
  433.       if (got_status == 2) { /* btm */
  434.      putstring(-1,-1,C_GENERAL_MED,"at ");
  435.      sprintf(msg,"[%d,%d]",currow,curcol);
  436.      putstring(-1,-1,C_GENERAL_HI,msg);
  437.      }
  438.       else {
  439.      if (totpasses > 1) {
  440.         putstring(-1,-1,C_GENERAL_MED,"pass ");
  441.         sprintf(msg,"%d",curpass);
  442.         putstring(-1,-1,C_GENERAL_HI,msg);
  443.         putstring(-1,-1,C_GENERAL_MED," of ");
  444.         sprintf(msg,"%d",totpasses);
  445.         putstring(-1,-1,C_GENERAL_HI,msg);
  446.         putstring(-1,-1,C_GENERAL_MED,", ");
  447.         }
  448.      putstring(-1,-1,C_GENERAL_MED,"at row ");
  449.      sprintf(msg,"%d",currow);
  450.      putstring(-1,-1,C_GENERAL_HI,msg);
  451.      }
  452.       ++row;
  453.       }
  454.    putstring(row,2,C_GENERAL_MED,"Calculation time:");
  455.    sprintf(msg,"%3ld:%02ld:%02ld.%02ld", calctime/360000,
  456.       (calctime%360000)/6000, (calctime%6000)/100, calctime%100);
  457.    putstring(-1,-1,C_GENERAL_HI,msg);
  458.    row += 2;
  459.  
  460.    putstring(row,2,C_GENERAL_MED,"Corners:                X                     Y");
  461.    putstring(++row,3,C_GENERAL_MED,"top-left");
  462.    sprintf(msg,"%20.16f  %20.16f",xxmin,yymax);
  463.    putstring(-1,17,C_GENERAL_HI,msg);
  464.    putstring(++row,3,C_GENERAL_MED,"bottom-right");
  465.    sprintf(msg,"%20.16f  %20.16f",xxmax,yymin);
  466.    putstring(-1,17,C_GENERAL_HI,msg);
  467.    adjust_corner(); /* make bottom left exact if very near exact */
  468.    if (cvtcentermag(&Xctr, &Yctr, &Magnification)) {
  469.       putstring(row+=2,2,C_GENERAL_MED,"Center: ");
  470.       sprintf(msg,"%20.16f %20.16f",Xctr,Yctr);
  471.       putstring(-1,-1,C_GENERAL_HI,msg);
  472.       putstring(-1,-1,C_GENERAL_MED,"  Mag: ");
  473.       if (Magnification < 1e6)
  474.      sprintf(msg,"%20.14f",Magnification);
  475.       else if (Magnification < 1e12)
  476.      sprintf(msg,"%20.8f",Magnification);
  477.       else
  478.      sprintf(msg,"%20.2f",Magnification);
  479.       putstring(-1,-1,C_GENERAL_HI,msg);
  480.       }
  481.    else if (xxmin != xx3rd || yymin != yy3rd) {
  482.       putstring(++row,3,C_GENERAL_MED,"bottom-left");
  483.       sprintf(msg,"%20.16f  %20.16f",xx3rd,yy3rd);
  484.       putstring(-1,17,C_GENERAL_HI,msg);
  485.       }
  486.    putstring(row+=2,2,C_GENERAL_MED,"Params,");
  487.    for (i = 0; i < 4; i++) {
  488.       sprintf(msg,"%3d: ",i+1);
  489.       putstring(-1,-1,C_GENERAL_MED,msg);
  490.       sprintf(msg,"%12.9f",param[i]);
  491.       putstring(-1,-1,C_GENERAL_HI,msg);
  492.       }
  493.  
  494.    putstring(row+=2,2,C_GENERAL_MED,"Iteration maximum: ");
  495.    sprintf(msg,"%d",maxit);
  496.    putstring(-1,-1,C_GENERAL_HI,msg);
  497.    putstring(-1,-1,C_GENERAL_MED,"     Effective bailout: ");
  498.    sprintf(msg,"%f",rqlim);
  499.    putstring(-1,-1,C_GENERAL_HI,msg);
  500.  
  501.    if (fractype == PLASMA) {
  502.       putstring(++row,2,C_GENERAL_MED,"Current 'rseed': ");
  503.       sprintf(msg,"%d",rseed);
  504.       putstring(-1,-1,C_GENERAL_HI,msg);
  505.       }
  506.  
  507.    if(invert) {
  508.       extern double f_radius,f_xcenter,f_ycenter;
  509.       putstring(++row,2,C_GENERAL_MED,"Inversion radius: ");
  510.       sprintf(msg,"%12.9f",f_radius);
  511.       putstring(-1,-1,C_GENERAL_HI,msg);
  512.       putstring(-1,-1,C_GENERAL_MED,"  xcenter: ");
  513.       sprintf(msg,"%12.9f",f_xcenter);
  514.       putstring(-1,-1,C_GENERAL_HI,msg);
  515.       putstring(-1,-1,C_GENERAL_MED,"  ycenter: ");
  516.       sprintf(msg,"%12.9f",f_ycenter);
  517.       putstring(-1,-1,C_GENERAL_HI,msg);
  518.       }
  519.  
  520.    if ((row += 2) < 23) ++row;
  521.    putstringcenter(row,0,80,C_GENERAL_LO,"...Press any key to continue...");
  522.    movecursor(25,80);
  523.    getakey();
  524.    unstackscreen();
  525.    timer_start = clock(); /* tab display was "time out" */
  526.    return(0);
  527. }
  528.  
  529.  
  530. int endswithslash(char *fl)
  531. {
  532.    int len;
  533.    len = strlen(fl);
  534.    if(len)
  535.       if(fl[--len]=='\\')
  536.      return(1);
  537.    return(0);
  538. }
  539.  
  540. /* --------------------------------------------------------------------- */
  541.  
  542. int ifsgetfile()       /* read in IFS parameters */
  543. {
  544.    FILE  *ifsfile;        /* IFS code file pointer */
  545.    float localifs[IFSPARM];
  546.    int i, j;
  547.  
  548.    /* read in IFS codes from file */
  549.    if (!endswithslash(ifsfilename)) {
  550.       if ( (ifsfile = fopen( ifsfilename,"r" )) != NULL ) {
  551.      i = -1;
  552.      while (fgets(temp1, 155, ifsfile) != NULL) {
  553.         if (++i >= NUMIFS) break;
  554.         sscanf(temp1," %f %f %f %f %f %f %f",
  555.            &localifs[0], &localifs[1], &localifs[2], &localifs[3],
  556.            &localifs[4], &localifs[5], &localifs[6]  );
  557.         if (i == 0 && localifs[6] == 0) {
  558.            char msg[200];
  559.            sprintf(msg,"%s invalid (perhaps it is IFS3D?)",ifsfilename);
  560.            stopmsg(0,msg);
  561.            fclose(ifsfile);
  562.            return(-1);
  563.            }
  564.         for (j = 0; j < IFSPARM; j++) {
  565.            initifs[i][j]   = localifs[j];
  566.            initifs[i+1][j] = 0.0;
  567.            }
  568.         }
  569.      fclose(ifsfile);
  570.      }
  571.       }
  572.    return(0);
  573. }
  574.  
  575. /* --------------------------------------------------------------------- */
  576.  
  577. int ifs3dgetfile()     /* read in 3D IFS parameters */
  578. {
  579.    FILE  *ifsfile;        /* IFS code file pointer */
  580.    float localifs[IFS3DPARM];
  581.    int i, j;
  582.  
  583.    /* read in IFS codes from file */
  584.    if (!endswithslash(ifs3dfilename)) {
  585.       if ( (ifsfile = fopen( ifs3dfilename,"r" )) != NULL ) {
  586.      i = -1;
  587.      while (fgets(temp1, 155, ifsfile) != NULL) {
  588.         if (++i >= NUMIFS) break;
  589.         j = sscanf(temp1," %f %f %f %f %f %f %f %f %f %f %f %f %f",
  590.            &localifs[ 0], &localifs[ 1], &localifs[ 2],
  591.            &localifs[ 3], &localifs[ 4], &localifs[ 5],
  592.            &localifs[ 6], &localifs[ 7], &localifs[ 8],
  593.            &localifs[ 9], &localifs[10], &localifs[11],
  594.            &localifs[12]
  595.            );
  596.         if (i == 0 && j < 13) {
  597.            char msg[200];
  598.            sprintf(msg,"%s invalid (perhaps it is 2D IFS?)",ifs3dfilename);
  599.            stopmsg(0,msg);
  600.            fclose(ifsfile);
  601.            return(-1);
  602.            }
  603.         for (j = 0; j < IFS3DPARM; j++) {
  604.            initifs3d[i][j]     = localifs[j];
  605.            initifs3d[i+1][j] = 0.0;
  606.            }
  607.         }
  608.      fclose(ifsfile);
  609.      }
  610.       }
  611.    return(0);
  612. }
  613.  
  614.  
  615.