home *** CD-ROM | disk | FTP | other *** search
/ Chestnut's Multimedia Mania / MM_MANIA.ISO / windows / winfrac / windos2.c < prev    next >
C/C++ Source or Header  |  1992-10-07  |  34KB  |  1,159 lines

  1.  
  2. /* Windows versions of DOS functions needed by PROMPTS.C */
  3.  
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <dos.h>
  7. #include <sys\types.h>
  8. #include <sys\stat.h>
  9. #include <fcntl.h>
  10. #include <math.h>
  11. #include "fractint.h"
  12. #include "fractype.h"
  13. #include "helpdefs.h"
  14.  
  15. /* routines in this module    */
  16. void movecursor(int row, int col);
  17. void setattr(int row, int col, int attr, int count);
  18. int  putstringcenter(int row, int col, int width, int attr, char far *msg);
  19. void putstring(int row, int col, int attr, unsigned char far *buf);
  20. int  fullscreen_choice(
  21.          int options, char *hdg, char *hdg2, char *instr, int numchoices,
  22.          char **choices, int *attributes, int boxwidth, int boxdepth,
  23.          int colwidth, int current, void (*formatitem)(),
  24.          char *speedstring, int (*speedprompt)(), int (*checkkey)());
  25. int  strncasecmp(char *s,char *t,int ct);
  26. int  input_field(int options, int attr, char *fld, int len, int row, int col, int (*checkkey)(int) );
  27. int  field_prompt(int options, char *hdg, char *instr, char *fld, int len, int (*checkkey)() );
  28. void helptitle(void);
  29. void stackscreen(void);
  30. void unstackscreen(void);
  31. void discardscreen(void);
  32. void load_palette(void);
  33. void save_palette(void);
  34. void fractint_help(void);
  35.  
  36. /* faked/unimplemented routines */
  37.  
  38. void stopslideshow() {}
  39. void aspectratio_crop() {}
  40. void setvideotext() {}
  41. void vidmode_keyname() {}
  42. void load_fractint_cfg() {}
  43. void check_vidmode_key() {}
  44.  
  45. struct videoinfo far *vidtbl;
  46. int vidtbllen = 0;
  47. int badconfig = 0;
  48.  
  49. int in_fractint_help = 0;
  50.  
  51. int win_release = 1750;
  52. char far win_comment[] =
  53. /*   {" "};                /*  publicly-released version */
  54. /*   {"Test Version - Not for Release"};   /* interim test versions */
  55. /*     {"'Public Beta' Release"};   /* interim test versions */
  56.      {"'Fractals for Windows' Release"};   /* interim test versions */
  57.  
  58. extern int time_to_resume;         /* time to resume? */
  59.  
  60. int text_type = 0;
  61. int textrow = 0, textcol = 0;
  62. int textrbase = 0, textcbase = 0;
  63. int lookatmouse;
  64.  
  65. /* fullscreen_choice options */
  66. #define CHOICERETURNKEY 1
  67. #define CHOICEMENU    2
  68. #define CHOICEHELP    4
  69.  
  70. char speed_prompt[]="Speed key string";
  71.  
  72. int fullscreen_choice(
  73.     int options,         /* &2 use menu coloring scheme           */
  74.                  /* &4 include F1 for help in instructions */
  75.                  /* &8 add caller's instr after normal set */
  76.     char *hdg,         /* heading info, \n delimited           */
  77.     char *hdg2,         /* column heading or NULL               */
  78.     char *instr,         /* instructions, \n delimited, or NULL    */
  79.     int numchoices,      /* How many choices in list           */
  80.     char **choices,      /* array of choice strings            */
  81.     int *attributes,     /* &3: 0 normal color, 1,3 highlight      */
  82.                  /* &256 marks a dummy entry           */
  83.     int boxwidth,         /* box width, 0 for calc (in items)       */
  84.     int boxdepth,         /* box depth, 0 for calc, 99 for max      */
  85.     int colwidth,         /* data width of a column, 0 for calc     */
  86.     int current,         /* start with this item               */
  87.     void (*formatitem)(),/* routine to display an item or NULL     */
  88.     char *speedstring,   /* returned speed key value, or NULL >[30]*/
  89.     int (*speedprompt)(),/* routine to display prompt or NULL      */
  90.     int (*checkkey)()    /* routine to check keystroke or NULL     */
  91. )
  92.    /* return is: n>=0 for choice n selected,
  93.          -1 for escape
  94.           k for checkkey routine return value k (if not 0 nor -1)
  95.       speedstring[0] != 0 on return if string is present
  96.       */
  97. {
  98. static char far choiceinstr1a[]="Use the cursor keys to highlight your selection";
  99. static char far choiceinstr1b[]="Use the cursor keys or type a value to make a selection";
  100. static char far choiceinstr2a[]="Press ENTER for highlighted choice, or ESCAPE to back out";
  101. static char far choiceinstr2b[]="Press ENTER for highlighted choice, ESCAPE to back out, or F1 for help";
  102. static char far choiceinstr2c[]="Press ENTER for highlighted choice, or F1 for help";
  103.  
  104.    int titlelines,titlewidth;
  105.    int reqdrows;
  106.    int topleftrow,topleftcol;
  107.    int topleftchoice;
  108.    int speedrow;  /* speed key prompt */
  109.    int boxitems;  /* boxwidth*boxdepth */
  110.    int curkey,increment,rev_increment;
  111.    int redisplay;
  112.    int i,j,k;
  113.    char *charptr;
  114.    char buf[81];
  115.    int speed_match = 0;
  116.    char curitem[81];
  117.    char *itemptr;
  118.    int ret,savelookatmouse;
  119.  
  120.    savelookatmouse = lookatmouse;
  121.    lookatmouse = 0;
  122.    ret = -1;
  123.    if (speedstring
  124.      && (i = strlen(speedstring)) > 0) { /* preset current to passed string */
  125.       current = 0;
  126.       while (current < numchoices
  127.     && (k = strncasecmp(speedstring,choices[current],i)) > 0)
  128.      ++current;
  129.       if (k < 0 && current > 0)  /* oops - overshot */
  130.      --current;
  131.       if (current >= numchoices) /* bumped end of list */
  132.      current = numchoices - 1;
  133.       }
  134.  
  135.    while (1) {
  136.       if (current >= numchoices)  /* no real choice in the list? */
  137.      goto fs_choice_end;
  138.       if ((attributes[current] & 256) == 0)
  139.      break;
  140.       ++current;          /* scan for a real choice */
  141.       }
  142.  
  143.    titlelines = titlewidth = 0;
  144.    if (hdg) {
  145.       charptr = hdg;          /* count title lines, find widest */
  146.       i = 0;
  147.       titlelines = 1;
  148.       while (*charptr) {
  149.      if (*(charptr++) == '\n') {
  150.         ++titlelines;
  151.         i = -1;
  152.         }
  153.      if (++i > titlewidth)
  154.         titlewidth = i;
  155.      }
  156.       }
  157.  
  158.    if (colwidth == 0)          /* find widest column */
  159.       for (i = 0; i < numchoices; ++i)
  160.      if (strlen(choices[i]) > colwidth)
  161.         colwidth = strlen(choices[i]);
  162.  
  163.    /* title(1), blank(1), hdg(n), blank(1), body(n), blank(1), instr(?) */
  164.    reqdrows = 3;          /* calc rows available */
  165.    if (hdg)
  166.       reqdrows += titlelines + 1;
  167.    if (instr) {           /* count instructions lines */
  168.       charptr = instr;
  169.       ++reqdrows;
  170.       while (*charptr)
  171.      if (*(charptr++) == '\n')
  172.         ++reqdrows;
  173.       if ((options & 8))      /* show std instr too */
  174.      reqdrows += 2;
  175.       }
  176.    else
  177.       reqdrows += 2;          /* standard instructions */
  178.    if (speedstring) ++reqdrows;   /* a row for speedkey prompt */
  179.    if (boxdepth > (i = 25 - reqdrows)) /* limit the depth to max */
  180.       boxdepth = i;
  181.    if (boxwidth == 0) {       /* pick box width and depth */
  182.       if (numchoices <= i - 2) {  /* single column is 1st choice if we can */
  183.      boxdepth = numchoices;
  184.      boxwidth = 1;
  185.      }
  186.       else {              /* sort-of-wide is 2nd choice */
  187.      boxwidth = 60 / (colwidth + 1);
  188.      if (boxwidth == 0
  189.        || (boxdepth = (numchoices+boxwidth-1)/boxwidth) > i - 2) {
  190.         boxwidth = 80 / (colwidth + 1); /* last gasp, full width */
  191.         if ((boxdepth = (numchoices+boxwidth-1)/boxwidth) > i)
  192.            boxdepth = i;
  193.         }
  194.      }
  195.       }
  196.    if ((i = 77 / boxwidth - colwidth) > 3) /* spaces to add @ left each choice */
  197.       i = 3;
  198.    j = boxwidth * (colwidth += i) + i;       /* overall width of box */
  199.    if (j < titlewidth+2)
  200.       j = titlewidth + 2;
  201.    if (j > 80)
  202.       j = 80;
  203.    if (j <= 70 && boxwidth == 2) {       /* special case makes menus nicer */
  204.       ++j;
  205.       ++colwidth;
  206.       }
  207.    k = (80 - j) / 2;               /* center the box */
  208.    k -= (90 - j) / 20;
  209.    topleftcol = k + i;               /* column of topleft choice */
  210.    i = (25 - reqdrows - boxdepth) / 2;
  211.    i -= i / 4;                   /* higher is better if lots extra */
  212.    topleftrow = 3 + titlelines + i;       /* row of topleft choice */
  213.  
  214.    /* now set up the overall display */
  215.    helptitle();                /* clear, display title line */
  216.    setattr(1,0,C_PROMPT_BKGRD,24*80);       /* init rest to background */
  217.    for (i = topleftrow-1-titlelines; i < topleftrow+boxdepth+1; ++i)
  218.       setattr(i,k,C_PROMPT_LO,j);       /* draw empty box */
  219.    if (hdg) {
  220.       textcbase = (80 - titlewidth) / 2;   /* set left margin for putstring */
  221.       textcbase -= (90 - titlewidth) / 20; /* put heading into box */
  222.       putstring(topleftrow-titlelines-1,0,C_PROMPT_HI,hdg);
  223.       textcbase = 0;
  224.       }
  225.    if (hdg2)                   /* display 2nd heading */
  226.       putstring(topleftrow-1,topleftcol,C_PROMPT_MED,hdg2);
  227.    i = topleftrow + boxdepth + 1;
  228.    if (instr == NULL || (options & 8)) {   /* display default instructions */
  229.       if (i < 20) ++i;
  230.       if (speedstring) {
  231.      speedrow = i;
  232.      *speedstring = 0;
  233.      if (++i < 22) ++i;
  234.      }
  235.       putstringcenter(i++,0,80,C_PROMPT_BKGRD,
  236.         (speedstring) ? choiceinstr1b : choiceinstr1a);
  237.       putstringcenter(i++,0,80,C_PROMPT_BKGRD,
  238.         (options&CHOICEMENU) ? choiceinstr2c
  239.         : ((options&CHOICEHELP) ? choiceinstr2b : choiceinstr2a));
  240.       }
  241.    if (instr) {                /* display caller's instructions */
  242.       charptr = instr;
  243.       j = -1;
  244.       while ((buf[++j] = *(charptr++)))
  245.      if (buf[j] == '\n') {
  246.         buf[j] = 0;
  247.         putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
  248.         j = -1;
  249.         }
  250.       putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
  251.       }
  252.  
  253.    boxitems = boxwidth * boxdepth;
  254.    topleftchoice = 0;               /* pick topleft for init display */
  255.    while (current - topleftchoice >= boxitems
  256.      || (current - topleftchoice > boxitems/2
  257.      && topleftchoice + boxitems < numchoices))
  258.       topleftchoice += boxwidth;
  259.    redisplay = 1;
  260.  
  261.    while (1) { /* main loop */
  262.  
  263.       if (redisplay) {                 /* display the current choices */
  264.      if ((options & CHOICEMENU) == 0) {
  265.         memset(buf,' ',80);
  266.         buf[boxwidth*colwidth] = 0;
  267.         for (i = (hdg2) ? 0 : -1; i <= boxdepth; ++i)  /* blank the box */
  268.            putstring(topleftrow+i,topleftcol,C_PROMPT_LO,buf);
  269.         }
  270.      for (i = 0; i+topleftchoice < numchoices && i < boxitems; ++i) {
  271.         /* display the choices */
  272.         if ((k = attributes[j = i+topleftchoice] & 3) == 1)
  273.            k = C_PROMPT_LO;
  274.         else if (k == 3)
  275.            k = C_PROMPT_HI;
  276.         else
  277.            k = C_PROMPT_MED;
  278.         if (formatitem)
  279.            (*formatitem)(j,charptr=buf);
  280.         else
  281.            charptr = choices[j];
  282.         putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  283.               k,charptr);
  284.         }
  285.      /***
  286.      ... format differs for summary/detail, whups, force box width to
  287.      ...  be 72 when detail toggle available?  (2 grey margin each
  288.      ...  side, 1 blue margin each side)
  289.      ***/
  290.      if (topleftchoice > 0 && hdg2 == NULL)
  291.         putstring(topleftrow-1,topleftcol,C_PROMPT_LO,"(more)");
  292.      if (topleftchoice + boxitems < numchoices)
  293.         putstring(topleftrow+boxdepth,topleftcol,C_PROMPT_LO,"(more)");
  294.      redisplay = 0;
  295.      }
  296.  
  297.       i = current - topleftchoice;         /* highlight the current choice */
  298.       if (formatitem)
  299.      (*formatitem)(current,itemptr=curitem);
  300.       else
  301.      itemptr = choices[current];
  302.       putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  303.         C_CHOICE_CURRENT,itemptr);
  304.  
  305.       if (speedstring) {             /* show speedstring if any */
  306.      memset(buf,' ',80);
  307.      buf[80] = 0;
  308.      putstring(speedrow,0,C_PROMPT_BKGRD,buf);
  309.      if (*speedstring) {             /* got a speedstring on the go */
  310.         putstring(speedrow,15,C_CHOICE_SP_INSTR," ");
  311.         if (speedprompt)
  312.            j = speedprompt(speedrow,16,C_CHOICE_SP_INSTR,speedstring,speed_match);
  313.         else {
  314.            putstring(speedrow,16,C_CHOICE_SP_INSTR,speed_prompt);
  315.            j = strlen(speed_prompt);
  316.            }
  317.         strcpy(buf,speedstring);
  318.         i = strlen(buf);
  319.         while (i < 30)
  320.            buf[i++] = ' ';
  321.         buf[i] = 0;
  322.         putstring(speedrow,16+j,C_CHOICE_SP_INSTR," ");
  323.         putstring(speedrow,17+j,C_CHOICE_SP_KEYIN,buf);
  324.         movecursor(speedrow,17+j+strlen(speedstring));
  325.         }
  326.      else
  327.         movecursor(25,80);
  328.      }
  329.       else
  330.      movecursor(25,80);
  331.  
  332. /*    while (!keypressed()) { } /* enables help */
  333. /*      curkey = getakey(); */
  334.       curkey = keycursor(-2,-2);
  335.  
  336.       i = current - topleftchoice;         /* unhighlight current choice */
  337.       if ((k = attributes[current] & 3) == 1)
  338.      k = C_PROMPT_LO;
  339.       else if (k == 3)
  340.      k = C_PROMPT_HI;
  341.       else
  342.      k = C_PROMPT_MED;
  343.       putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
  344.         k,itemptr);
  345.  
  346.       increment = 0;
  347.       switch (curkey) {              /* deal with input key */
  348.      case ENTER:
  349.      case ENTER_2:
  350.         ret = current;
  351.         goto fs_choice_end;
  352.      case ESC:
  353.         goto fs_choice_end;
  354.      case DOWN_ARROW:
  355.      case DOWN_ARROW_2:
  356.         rev_increment = 0 - (increment = boxwidth);
  357.         break;
  358.      case UP_ARROW:
  359.      case UP_ARROW_2:
  360.         increment = 0 - (rev_increment = boxwidth);
  361.         break;
  362.      case RIGHT_ARROW:
  363.      case RIGHT_ARROW_2:
  364.         if (boxwidth == 1) break;
  365.         increment = 1; rev_increment = -1;
  366.         break;
  367.      case LEFT_ARROW:
  368.      case LEFT_ARROW_2:
  369.         if (boxwidth == 1) break;
  370.         increment = -1; rev_increment = 1;
  371.         break;
  372.      case PAGE_UP:
  373.         if (numchoices > boxitems) {
  374.            topleftchoice -= boxitems;
  375.            increment = -boxitems;
  376.            rev_increment = boxwidth;
  377.            redisplay = 1;
  378.            }
  379.         break;
  380.      case PAGE_DOWN:
  381.         if (numchoices > boxitems) {
  382.            topleftchoice += boxitems;
  383.            increment = boxitems;
  384.            rev_increment = -boxwidth;
  385.            redisplay = 1;
  386.            }
  387.         break;
  388.      case CTL_HOME:
  389.         current = -1;
  390.         increment = rev_increment = 1;
  391.         break;
  392.      case CTL_END:
  393.         current = numchoices;
  394.         increment = rev_increment = -1;
  395.         break;
  396.      default:
  397.         if (checkkey) {
  398.            if ((ret = (*checkkey)(curkey,current)) < -1 || ret > 0)
  399.           goto fs_choice_end;
  400.            if (ret == -1)
  401.           redisplay = -1;
  402.            }
  403.         ret = -1;
  404.         if (speedstring) {
  405.            i = strlen(speedstring);
  406.            if (curkey == 8 && i > 0) /* backspace */
  407.           speedstring[--i] = 0;
  408.            if (33 <= curkey && curkey <= 126 && i < 30) {
  409.           curkey = tolower(curkey);
  410.           speedstring[i] = curkey;
  411.           speedstring[++i] = 0;
  412.           }
  413.            if (i > 0) {         /* locate matching type */
  414.           current = 0;
  415.           while (current < numchoices
  416.             && (speed_match = strncasecmp(speedstring,choices[current],i)) > 0)
  417.              ++current;
  418.           if (speed_match < 0 && current > 0)  /* oops - overshot */
  419.              --current;
  420.           if (current >= numchoices) /* bumped end of list */
  421.              current = numchoices - 1;
  422.           }
  423.            }
  424.         break;
  425.      }
  426.  
  427.       if (increment) {            /* apply cursor movement */
  428.      current += increment;
  429.      if (speedstring)        /* zap speedstring */
  430.         speedstring[0] = 0;
  431.      }
  432.       while (1) {            /* adjust to a non-comment choice */
  433.      if (current < 0 || current >= numchoices)
  434.          increment = rev_increment;
  435.      else if ((attributes[current] & 256) == 0)
  436.          break;
  437.      current += increment;
  438.      }
  439.       if (topleftchoice > numchoices - boxitems)
  440.      topleftchoice = ((numchoices+boxwidth-1)/boxwidth)*boxwidth - boxitems;
  441.       if (topleftchoice < 0)
  442.      topleftchoice = 0;
  443.       while (current < topleftchoice) {
  444.      topleftchoice -= boxwidth;
  445.      redisplay = 1;
  446.      }
  447.       while (current >= topleftchoice + boxitems) {
  448.      topleftchoice += boxwidth;
  449.      redisplay = 1;
  450.      }
  451.       }
  452.  
  453. fs_choice_end:
  454.    lookatmouse = savelookatmouse;
  455.    return(ret);
  456.  
  457. }
  458.  
  459. int input_field(
  460.     int options,          /* &1 numeric, &2 integer, &4 double */
  461.     int attr,          /* display attribute */
  462.     char *fld,          /* the field itself */
  463.     int len,          /* field length (declare as 1 larger for \0) */
  464.     int row,          /* display row */
  465.     int col,          /* display column */
  466.     int (*checkkey)(int)  /* routine to check non data keys, or NULL */
  467.     )
  468. {
  469.    char savefld[81];
  470.    char buf[81];
  471.    int insert, started, offset, curkey, display;
  472.    int i, j;
  473.    int ret,savelookatmouse;
  474.    savelookatmouse = lookatmouse;
  475.    lookatmouse = 0;
  476.    ret = -1;
  477.    strcpy(savefld,fld);
  478.    insert = started = offset = 0;
  479.    display = 1;
  480.    while (1) {
  481.       strcpy(buf,fld);
  482.       i = strlen(buf);
  483.       while (i < len)
  484.      buf[i++] = ' ';
  485.       buf[len] = 0;
  486.       if (display) {                    /* display current value */
  487.      putstring(row,col,attr,buf);
  488.      display = 0;
  489.      }
  490.       curkey = keycursor(row+insert,col+offset);  /* get a keystroke */
  491.       switch (curkey) {
  492.      case ENTER:
  493.      case ENTER_2:
  494.         ret = 0;
  495.         goto inpfld_end;
  496.      case ESC:
  497.         goto inpfld_end;
  498.      case RIGHT_ARROW:
  499.      case RIGHT_ARROW_2:
  500.         if (offset < len) ++offset;
  501.         started = 1;
  502.         break;
  503.      case LEFT_ARROW:
  504.      case LEFT_ARROW_2:
  505.         if (offset > 0) --offset;
  506.         started = 1;
  507.         break;
  508.      case HOME:
  509.         offset = 0;
  510.         started = 1;
  511.         break;
  512.      case END:
  513.         offset = strlen(fld);
  514.         started = 1;
  515.         break;
  516.      case 8:
  517.      case 127:                /* backspace */
  518.         if (offset > 0) {
  519.            j = strlen(fld);
  520.            for (i = offset-1; i < j; ++i)
  521.           fld[i] = fld[i+1];
  522.            --offset;
  523.            }
  524.         started = display = 1;
  525.         break;
  526.      case DELETE:                /* delete */
  527.         j = strlen(fld);
  528.         for (i = offset; i < j; ++i)
  529.            fld[i] = fld[i+1];
  530.         started = display = 1;
  531.         break;
  532.      case 1082:                /* insert */
  533.         insert ^= 0x8000;
  534.         started = 1;
  535.         break;
  536.      case F5:
  537.         strcpy(fld,savefld);
  538.         insert = started = offset = 0;
  539.         display = 1;
  540.         break;
  541.      default:
  542.         if (curkey < 32 || curkey >= 127) {
  543.            if (checkkey && (ret = (*checkkey)(curkey)))
  544.           goto inpfld_end;
  545.            break;                     /* non alphanum char */
  546.            }
  547.         if (offset >= len) break;             /* at end of field */
  548.         if (insert && started && strlen(fld) >= len)
  549.            break;                     /* insert & full */
  550.         if ((options & 1)
  551.           && (curkey < '0' || curkey > '9')
  552.           && curkey != '+' && curkey != '-') {
  553.            if ((options & 2))
  554.           break;
  555.            /* allow scientific notation, and specials "e" and "p" */
  556.            if ( ((curkey != 'e' && curkey != 'E') || offset >= 18)
  557.          && ((curkey != 'p' && curkey != 'P') || offset != 0 )
  558.          && curkey != '.')
  559.           break;
  560.            }
  561.         if (started == 0) /* first char is data, zap field */
  562.            fld[0] = 0;
  563.         if (insert) {
  564.            j = strlen(fld);
  565.            while (j >= offset) {
  566.           fld[j+1] = fld[j];
  567.           --j;
  568.           }
  569.            }
  570.         if (offset >= strlen(fld))
  571.            fld[offset+1] = 0;
  572.         fld[offset++] = curkey;
  573.         /* if "e" or "p" in first col make number e or pi */
  574.         if ((options & 3) == 1) { /* floating point */
  575.            double tmpd;
  576.            int specialv;
  577.            char tmpfld[30];
  578.            specialv = 0;
  579.            if (*fld == 'e' || *fld == 'E') {
  580.           tmpd = exp(1.0);
  581.           specialv = 1;
  582.           }
  583.            if (*fld == 'p' || *fld == 'P') {
  584.           tmpd = atan(1.0) * 4;
  585.           specialv = 1;
  586.           }
  587.            if (specialv) {
  588.           if ((options & 4) == 0)
  589.              roundfloatd(&tmpd);
  590.           sprintf(tmpfld,"%.15g",tmpd);
  591.           tmpfld[len-1] = 0; /* safety, field should be long enough */
  592.           strcpy(fld,tmpfld);
  593.           offset = 0;
  594.           }
  595.            }
  596.         started = display = 1;
  597.      }
  598.       }
  599. inpfld_end:
  600.    lookatmouse = savelookatmouse;
  601.    return(ret);
  602. }
  603.  
  604. int field_prompt(
  605.     int options,        /* &1 numeric value, &2 integer */
  606.     char *hdg,        /* heading, \n delimited lines */
  607.     char *instr,        /* additional instructions or NULL */
  608.     char *fld,        /* the field itself */
  609.     int len,        /* field length (declare as 1 larger for \0) */
  610.     int (*checkkey)()   /* routine to check non data keys, or NULL */
  611.     )
  612. {
  613.    char *charptr;
  614.    int boxwidth,titlelines,titlecol,titlerow;
  615.    int promptcol;
  616.    int i,j;
  617.    char buf[81];
  618.    helptitle();               /* clear screen, display title */
  619.    setattr(1,0,C_PROMPT_BKGRD,24*80);      /* init rest to background */
  620.    charptr = hdg;              /* count title lines, find widest */
  621.    i = boxwidth = 0;
  622.    titlelines = 1;
  623.    while (*charptr) {
  624.       if (*(charptr++) == '\n') {
  625.      ++titlelines;
  626.      i = -1;
  627.      }
  628.       if (++i > boxwidth)
  629.      boxwidth = i;
  630.       }
  631.    if (len > boxwidth)
  632.       boxwidth = len;
  633.    i = titlelines + 4;              /* total rows in box */
  634.    titlerow = (25 - i) / 2;          /* top row of it all when centered */
  635.    titlerow -= titlerow / 4;          /* higher is better if lots extra */
  636.    titlecol = (80 - boxwidth) / 2;      /* center the box */
  637.    titlecol -= (90 - boxwidth) / 20;
  638.    promptcol = titlecol - (boxwidth-len)/2;
  639.    j = titlecol;              /* add margin at each side of box */
  640.    if ((i = (82-boxwidth)/4) > 3)
  641.       i = 3;
  642.    j -= i;
  643.    boxwidth += i * 2;
  644.    for (i = -1; i < titlelines+3; ++i)      /* draw empty box */
  645.       setattr(titlerow+i,j,C_PROMPT_LO,boxwidth);
  646.    textcbase = titlecol;          /* set left margin for putstring */
  647.    putstring(titlerow,0,C_PROMPT_HI,hdg); /* display heading */
  648.    textcbase = 0;
  649.    i = titlerow + titlelines + 4;
  650.    if (instr) {               /* display caller's instructions */
  651.       charptr = instr;
  652.       j = -1;
  653.       while ((buf[++j] = *(charptr++)))
  654.      if (buf[j] == '\n') {
  655.         buf[j] = 0;
  656.         putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
  657.         j = -1;
  658.         }
  659.       putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
  660.       }
  661.    else                   /* default instructions */
  662.       putstringcenter(i,0,80,C_PROMPT_BKGRD,
  663.           "Press ENTER when finished (or ESCAPE to back out)");
  664.    return(input_field(options,C_PROMPT_INPUT,fld,len,
  665.               titlerow+titlelines+1,promptcol,checkkey));
  666. }
  667.  
  668. void helptitle()
  669. {
  670.    char msg[80],buf[10];
  671.    setclear(); /* clear the screen */
  672. #ifdef WAITE
  673.    sprintf(msg,"Special WINFRACT  Version %d.%01d",win_release/100,
  674.        (win_release%100)/10);
  675. #else
  676.    sprintf(msg,"WINFRACT  Version %d.%01d",win_release/100,
  677.        (win_release%100)/10);
  678. #endif
  679.    if (win_release%10) {
  680.       sprintf(buf,"%01d",win_release%10);
  681.       strcat(msg,buf);
  682.       }
  683. #ifdef WAITE /* realdos.c */
  684.    strcat(msg," for the Waite Group's Fractals for Windows");
  685. #endif /* WAITE - realdos.c */
  686.    putstringcenter(0,0,80,C_TITLE,msg);
  687. #ifdef WAITE
  688.    return;
  689. #endif
  690. /* uncomment next for production executable: */
  691.    putstring(0,2,C_TITLE_DEV,"'Public-Beta' Release"); 
  692.    return;
  693.    putstring(0,2,C_TITLE_DEV,"Development Version"); 
  694. /* replace above by next after creating production release, for release source */
  695. /* putstring(0,3,C_TITLE_DEV, "Customized Version"); */
  696.    putstring(0,53,C_TITLE_DEV,"Not for Public Release");
  697. }
  698.  
  699. static int screenctr=-1;
  700. #define MAXSCREENS 3
  701. static unsigned char far *savescreen[MAXSCREENS];
  702. static int saverc[MAXSCREENS+1];
  703. static FILE *savescf=NULL;
  704. static char scsvfile[]="fractscr.tmp";
  705.  
  706. void stackscreen()
  707. {
  708.    extern unsigned char far wintext_chars[25][80];
  709.    extern unsigned char far wintext_attrs[25][80];
  710.    int savebytes;
  711.    int i;
  712.    unsigned char far *ptr;
  713.    char buf[100];
  714.    saverc[screenctr+1] = textrow*80 + textcol;
  715.    if (++screenctr) { /* already have some stacked */
  716.      static char far msg[]={"stackscreen overflow"};
  717.       if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
  718.      stopmsg(1,msg);
  719.      exit(1);
  720.      }
  721.       savebytes = 25*80;
  722.       if ((ptr = savescreen[i] = farmemalloc((long)(2*savebytes)))) {
  723.      far_memcpy(ptr,wintext_chars,savebytes);
  724.      far_memcpy(ptr+savebytes,wintext_attrs,savebytes);
  725.      }
  726.       else {
  727.         static char far msg[]={"insufficient memory, aborting"};
  728. fileproblem:   stopmsg(1,msg);
  729.            exit(1);
  730.      }
  731.       setclear();
  732.       }
  733.    else
  734.       setfortext();
  735. }
  736.  
  737. void unstackscreen()
  738. {
  739.    extern unsigned char far wintext_chars[25][80];
  740.    extern unsigned char far wintext_attrs[25][80];
  741.    int savebytes;
  742.    unsigned char far *ptr;
  743.    textrow = saverc[screenctr] / 80;
  744.    textcol = saverc[screenctr] % 80;
  745.    if (--screenctr >= 0) { /* unstack */
  746.       savebytes = 25*80;
  747.       if ((ptr = savescreen[screenctr])) {
  748.      far_memcpy(wintext_chars,ptr,savebytes);
  749.      far_memcpy(wintext_attrs,ptr+savebytes,savebytes);
  750.          wintext_paintscreen(0,80,0,25);
  751.      farmemfree(ptr);
  752.      }
  753.       }
  754.    else
  755.       setforgraphics();
  756.    movecursor(-1,-1);
  757. }
  758.  
  759. void discardscreen()
  760. {
  761.    if (--screenctr >= 0) { /* unstack */
  762.       if (savescreen[screenctr])
  763.      farmemfree(savescreen[screenctr]);
  764.       }
  765.    else
  766.       discardgraphics();
  767. }
  768.  
  769. int discardgraphics()
  770. {
  771. }
  772.  
  773. setfortext()
  774. {
  775. wintext_texton();
  776. }
  777.  
  778. setforgraphics()
  779. {
  780. wintext_textoff();
  781. }
  782.  
  783. setclear()
  784. {
  785. extern int far wintext_buffer_init;
  786.  
  787.     wintext_buffer_init = 0;
  788.     wintext_paintscreen(0,80,0,25);
  789. }
  790.  
  791. int putstringcenter(int row, int col, int width, int attr, char far *msg)
  792. {
  793.    char buf[81];
  794.    int i,j,k;
  795.    i = 0;
  796.    while (msg[i]) ++i; /* strlen for a far */
  797.    if (i == 0) return(-1);
  798.    j = (width - i) / 2;
  799.    j -= (width + 10 - i) / 20; /* when wide a bit left of center looks better */
  800.    memset(buf,' ',width);
  801.    buf[width] = 0;
  802.    i = 0;
  803.    k = j;
  804.    while (msg[i]) buf[k++] = msg[i++]; /* strcpy for a far */
  805.    putstring(row,col,attr,buf);
  806.    return j;
  807. }
  808.  
  809. void putstring(int row, int col, int attr, unsigned char far *buf)
  810. {
  811.     extern unsigned char far wintext_chars[25][80];
  812.     extern unsigned char far wintext_attrs[25][80];
  813.     int i, j, k, maxrow, maxcol;
  814.     char xc, xa;
  815.  
  816.     if (row == -1) row = textrow;
  817.     if (col == -1) col = textcol;
  818.  
  819.     j = maxrow = row;
  820.     k = maxcol = col-1;
  821.  
  822.     for (i = 0; (xc = buf[i]) != 0; i++) {
  823.         if (xc == 13 || xc == 10) {
  824.             j++;
  825.             k = -1;
  826.             }
  827.         else {
  828.             if ((++k) + textcbase >= 80) {
  829.                 j++;
  830.                 k = 0;
  831.                 }
  832.             if (j+textrbase >= 25) j = 24-textrbase;
  833.             if (k+textcbase >= 80) k = 79-textcbase;
  834.             if (maxrow < j) maxrow = j;
  835.             if (maxcol < k) maxcol = k;
  836.             xa = (attr & 0x0ff);
  837.             wintext_chars[j+textrbase][k+textcbase] = xc;
  838.             wintext_attrs[j+textrbase][k+textcbase] = xa;
  839.             }
  840.         }
  841.     if (i > 0) {
  842.         textrow = j;
  843.         textcol = k + 1;
  844.         wintext_paintscreen(
  845.             col+textcbase, maxcol+textcbase,
  846.             row+textrbase, maxrow+textrbase);
  847.         }
  848. }
  849.  
  850. void setattr(int row, int col, int attr, int count)
  851. {
  852. extern unsigned char far wintext_attrs[25][80];
  853.     int i, j, k, maxrow, maxcol;
  854.     char xc, xa;
  855.  
  856.     j = maxrow = row;
  857.     k = maxcol = col-1;
  858.  
  859.     xa = (attr & 0x0ff);
  860.     for (i = 0; i < count; i++) {
  861.         if ((++k + textcbase) >= 80) {
  862.             j++;
  863.             k = 0;
  864.             }
  865.         if (j+textrbase >= 25) j = 24-textrbase;
  866.         if (k+textcbase >= 80) k = 79-textcbase;
  867.         if (maxrow < j) maxrow = j;
  868.         if (maxcol < k) maxcol = k;
  869.         wintext_attrs[j+textrbase][k+textcbase] = xa;
  870.         }
  871.     if (count > 0)
  872.         wintext_paintscreen(
  873.             col+textcbase, maxcol+textcbase,
  874.             row+textrbase, maxrow+textrbase);
  875. }
  876.  
  877. void movecursor(int row, int col)
  878. {
  879. int cursor_type;
  880.  
  881.     cursor_type = -1;
  882.     if (row >= 25 || col >= 80) {
  883.         row=1;
  884.         col=1;
  885.         cursor_type = 0;
  886.         }
  887.     if (row >= 0)
  888.         textrow = row;
  889.     if (col >= 0)
  890.         textcol = col;
  891.     wintext_cursor(col, row, -1);
  892. }
  893.  
  894. int keycursor(int row, int col)
  895. {
  896. int i, cursor_style;
  897.  
  898. if (row == -2 && col == -2) 
  899.     return(fractint_getkeypress(1));
  900.  
  901. if (row == -1)
  902.     row = textrow;
  903. if (col == -1)
  904.     col = textcol;
  905.  
  906. cursor_style = 1;
  907. if (row < 0) {
  908.     cursor_style = 2;
  909.     row = row & 0x7fff;
  910.     }
  911.  
  912. i = fractint_getkeypress(0);
  913. if (i == 0)
  914.     wintext_cursor(col, row, cursor_style);
  915. i = fractint_getkeypress(1);
  916. wintext_cursor(col, row, 0);
  917.  
  918. return(i);
  919.  
  920. }
  921.  
  922. /* get a "fractint-style" keystroke, with "help" sensitivity */
  923. int fractint_getkeypress(int option)
  924. {
  925. int i;
  926.  
  927. restart:
  928.     i = wintext_getkeypress(option);
  929.     if (i == 0)
  930.         return(i);
  931.     /* "fractint-i-size" the keystroke */
  932.     if (i != 0 && (i & 255) == 0)  /* function key? */
  933.         i = (i >> 8) + 1000;
  934.     else
  935.         i = (i & 255);
  936.     if (i == F1) {    /* F1  - bring up Windows-style help */
  937.         if (option == 0) wintext_getkeypress(1);
  938.         winfract_help();
  939.         goto restart;
  940.         }
  941.     if (i == (F1+35)) {  /* Control-F1  - bring up Fractint-style help */
  942.         if (option == 0) wintext_getkeypress(1);
  943.         if (! in_fractint_help) {
  944.             fractint_help();
  945.             goto restart;
  946.             }
  947.         }
  948.  
  949. return(i);
  950.  
  951. }
  952.  
  953. int getakeynohelp() {
  954. return(fractint_getkeypress(1));
  955. }
  956.  
  957. int strncasecmp(char *s,char *t,int ct)
  958. {
  959.    for(; (tolower(*s) == tolower(*t)) && --ct ; s++,t++)
  960.       if(*s == '\0')
  961.      return(0);
  962.    return(tolower(*s) - tolower(*t));
  963. }
  964.  
  965. extern char temp1[];
  966. extern    int    colors;
  967. extern unsigned char dacbox[256][3];
  968. extern unsigned char olddacbox[256][3];
  969. extern int colorstate;
  970. extern char    colorfile[];
  971. char mapmask[13] = {"*.map"};
  972.  
  973. void save_palette()
  974. {
  975.    FILE *dacfile;
  976.    int i,oldhelpmode;
  977.    oldhelpmode = helpmode;
  978.    stackscreen();
  979.    temp1[0] = 0;
  980.    helpmode = HELPCOLORMAP;
  981.    i = field_prompt(0,"Name of map file to write",NULL,temp1,60,NULL);
  982.    unstackscreen();
  983.    if (i != -1 && temp1[0]) {
  984.       if (strchr(temp1,'.') == NULL)
  985.      strcat(temp1,".map");
  986.       dacfile = fopen(temp1,"w");
  987.       if (dacfile == NULL)
  988.      buzzer(2);
  989.       else {
  990.      for (i = 0; i < colors; i++)
  991.         fprintf(dacfile, "%3d %3d %3d\n",
  992.             dacbox[i][0] << 2,
  993.             dacbox[i][1] << 2,
  994.             dacbox[i][2] << 2);
  995.      memcpy(olddacbox,dacbox,256*3);
  996.      colorstate = 2;
  997.      strcpy(colorfile,temp1);
  998.      }
  999.       fclose(dacfile);
  1000.       }
  1001.    helpmode = oldhelpmode;
  1002. }
  1003.  
  1004.  
  1005. void load_palette(void)
  1006. {
  1007.    int i,oldhelpmode;
  1008.    char filename[80];
  1009.    oldhelpmode = helpmode;
  1010.    strcpy(filename,colorfile);
  1011.    stackscreen();
  1012.    helpmode = HELPCOLORMAP;
  1013.    i = getafilename("Select a MAP File",mapmask,filename);
  1014.    unstackscreen();
  1015.    if (i >= 0)
  1016.       if (ValidateLuts(filename) == 0) {
  1017.      memcpy(olddacbox,dacbox,256*3);
  1018.      colorstate = 2;
  1019.      strcpy(colorfile,filename);
  1020.      }
  1021.    helpmode = oldhelpmode;
  1022. }
  1023.  
  1024. void fractint_help()
  1025. {
  1026.    int i,oldhelpmode;
  1027.  
  1028.    in_fractint_help = 1;
  1029.    oldhelpmode = helpmode;
  1030.    helpmode = HELP_INDEX;
  1031.    help(0);
  1032.    in_fractint_help = 0;
  1033.    helpmode = oldhelpmode;
  1034. }
  1035.  
  1036. FILE *parmfile;
  1037.  
  1038. int win_make_batch_file()
  1039. {
  1040.    int i,numparms;
  1041.    int gotinfile;
  1042.    char outname[81],buf[256],buf2[128];
  1043.    FILE *infile;
  1044.    char colorspec[14];
  1045.    int maxcolor;
  1046.    char *sptr,*sptr2;
  1047.    extern char CommandFile[];
  1048.    extern char CommandName[];
  1049.    extern char CommandComment1[];
  1050.    extern char CommandComment2[];
  1051.    extern int  colorstate;
  1052.    extern int win_temp1, win_temp2;
  1053.    extern char colorfile[];
  1054.    extern int  mapset;
  1055.    extern char MAP_name[];
  1056.  
  1057. #ifdef WINFRACT
  1058. extern char suffix[4096];
  1059. #else
  1060. extern char dstack[4096];
  1061. #endif
  1062.    extern char boxx[8192];
  1063.    extern char s_cantopen[];
  1064.    extern char s_cantwrite[];
  1065.    extern char s_cantcreate[];
  1066.    extern char s_cantunderstand[];
  1067.    extern char s_cantfind[];
  1068.  
  1069.       if (strchr(CommandFile,'.') == NULL)
  1070.          strcat(CommandFile,".par"); /* default extension .par */
  1071.       if (win_temp2 > 0 && win_temp2 <= 256)
  1072.         maxcolor = win_temp2;
  1073.       strcpy(colorspec,"n");
  1074.       if (win_temp1 == 0) {      /* default colors */
  1075.      }
  1076.       else if (win_temp1 == 2) { /* colors match colorfile */
  1077.      colorspec[0] = '@';
  1078.      sptr = colorfile;
  1079.      }
  1080.       else              /* colors match no .map that we know of */
  1081.      colorspec[0] = 'y';
  1082.       if (colorspec[0] == '@') {
  1083.      if ((sptr2 = strrchr(sptr,'\\'))) sptr = sptr2 + 1;
  1084.      if ((sptr2 = strrchr(sptr,':')))  sptr = sptr2 + 1;
  1085.      strncpy(&colorspec[1],sptr,12);
  1086.      colorspec[13] = 0;
  1087.      }
  1088.  
  1089.       strcpy(outname,CommandFile);
  1090.       gotinfile = 0;
  1091.       if (access(CommandFile,0) == 0) { /* file exists */
  1092.      gotinfile = 1;
  1093.      if (access(CommandFile,6)) {
  1094.         sprintf(buf,s_cantwrite,CommandFile);
  1095.         stopmsg(0,buf);
  1096.         return(0);
  1097.         }
  1098.      i = strlen(outname);
  1099.      while (--i >= 0 && outname[i] != '\\')
  1100.      outname[i] = 0;
  1101.      strcat(outname,"fractint.tmp");
  1102.      infile = fopen(CommandFile,"rt");
  1103.      setvbuf(infile,suffix,_IOFBF,4096); /* improves speed */
  1104.      }
  1105.       if ((parmfile = fopen(outname,"wt")) == NULL) {
  1106.      sprintf(buf,s_cantcreate,outname);
  1107.      stopmsg(0,buf);
  1108.      if (gotinfile) fclose(infile);
  1109.      return(0);
  1110.      }
  1111.  
  1112.       if (gotinfile) {
  1113.      while (file_gets(buf,255,infile) >= 0) {
  1114.         if (strchr(buf,'{')                    /* entry heading? */
  1115.           && sscanf(buf," %40[^ \t({]",buf2)
  1116.           && stricmp(buf2,CommandName) == 0) { /* entry with same name */
  1117.            sprintf(buf2,"File already has an entry named %s\n\
  1118. Continue to replace it, Cancel to back out",CommandName);
  1119.            if (stopmsg(18,buf2) < 0) {        /* cancel */
  1120.           fclose(infile);
  1121.           fclose(parmfile);
  1122.           unlink(outname);
  1123.           return(0);
  1124.           }
  1125.            while (strchr(buf,'}') == NULL
  1126.          && file_gets(buf,255,infile) > 0 ) { } /* skip to end of set */
  1127.            break;
  1128.            }
  1129.         fputs(buf,parmfile);
  1130.         fputc('\n',parmfile);
  1131.         }
  1132.      }
  1133.  
  1134.       fprintf(parmfile,"%-19s{",CommandName);
  1135.       if (CommandComment1[0]) fprintf(parmfile," ; %s",CommandComment1);
  1136.       fputc('\n',parmfile);
  1137.       if (CommandComment2[0])
  1138.      fprintf(parmfile,"                     ; %s\n",CommandComment2);
  1139.       write_batch_parms(parmfile,colorspec,maxcolor); /* write the parameters */
  1140.       fprintf(parmfile,"  }\n\n");
  1141.  
  1142.       if (gotinfile) {    /* copy the rest of the file */
  1143.      while ((i = file_gets(buf,255,infile)) == 0) { } /* skip blanks */
  1144.      while (i >= 0) {
  1145.         fputs(buf,parmfile);
  1146.         fputc('\n',parmfile);
  1147.         i = file_gets(buf,255,infile);
  1148.         }
  1149.      fclose(infile);
  1150.      }
  1151.       fclose(parmfile);
  1152.       if (gotinfile) {    /* replace the original file with the new */
  1153.      unlink(CommandFile);          /* success assumed on these lines       */
  1154.      rename(outname,CommandFile); /* since we checked earlier with access */
  1155.      }
  1156.  
  1157. return(1);
  1158. }
  1159.