File: common\slideshw.c

    1 /***********************************************************************/
    2 /* These routines are called by getakey to allow keystrokes to control */
    3 /* Fractint to be read from a file.                                    */
    4 /***********************************************************************/
    5 
    6 #include <ctype.h>
    7 #include <time.h>
    8 #include <string.h>
    9 #ifndef XFRACT
   10 #include <conio.h>
   11 #endif
   12 
   13   /* see Fractint.c for a description of the "include"  hierarchy */
   14 #include "port.h"
   15 #include "prototyp.h"
   16 
   17 static void sleep_secs(int);
   18 static int  showtempmsg_txt(int,int,int,int,char *);
   19 static void message(int secs, char far *buf);
   20 static void slideshowerr(char far *msg);
   21 static int  get_scancode(char *mn);
   22 static void get_mnemonic(int code, char *mnemonic);
   23 
   24 static FCODE s_ENTER     [] = "ENTER"     ;
   25 static FCODE s_INSERT    [] = "INSERT"    ;
   26 static FCODE s_DELETE    [] = "DELETE"    ;
   27 static FCODE s_ESC       [] = "ESC"       ;
   28 static FCODE s_TAB       [] = "TAB"       ;
   29 static FCODE s_PAGEUP    [] = "PAGEUP"    ;
   30 static FCODE s_PAGEDOWN  [] = "PAGEDOWN"  ;
   31 static FCODE s_HOME      [] = "HOME"      ;
   32 static FCODE s_END       [] = "END"       ;
   33 static FCODE s_LEFT      [] = "LEFT"      ;
   34 static FCODE s_RIGHT     [] = "RIGHT"     ;
   35 static FCODE s_UP        [] = "UP"        ;
   36 static FCODE s_DOWN      [] = "DOWN"      ;
   37 static FCODE s_F1        [] = "F1"        ;
   38 static FCODE s_CTRL_RIGHT[] = "CTRL_RIGHT";
   39 static FCODE s_CTRL_LEFT [] = "CTRL_LEFT" ;
   40 static FCODE s_CTRL_DOWN [] = "CTRL_DOWN" ;
   41 static FCODE s_CTRL_UP   [] = "CTRL_UP"   ;
   42 static FCODE s_CTRL_END  [] = "CTRL_END"  ;
   43 static FCODE s_CTRL_HOME [] = "CTRL_HOME" ;
   44 
   45 #define MAX_MNEMONIC    20   /* max size of any mnemonic string */
   46 
   47 struct scancodes
   48 {
   49    int code;
   50    FCODE *mnemonic;
   51 };
   52 
   53 static struct scancodes far scancodes[] =
   54 {
   55    {  ENTER,         s_ENTER     },
   56    {  INSERT,        s_INSERT    },
   57    {  DELETE,        s_DELETE    },
   58    {  ESC,           s_ESC       },
   59    {  TAB,           s_TAB       },
   60    {  PAGE_UP,       s_PAGEUP    },
   61    {  PAGE_DOWN,     s_PAGEDOWN  },
   62    {  HOME,          s_HOME      },
   63    {  END,           s_END       },
   64    {  LEFT_ARROW,    s_LEFT      },
   65    {  RIGHT_ARROW,   s_RIGHT     },
   66    {  UP_ARROW,      s_UP        },
   67    {  DOWN_ARROW,    s_DOWN      },
   68    {  F1,            s_F1        },
   69    {  RIGHT_ARROW_2, s_CTRL_RIGHT},
   70    {  LEFT_ARROW_2,  s_CTRL_LEFT },
   71    {  DOWN_ARROW_2,  s_CTRL_DOWN },
   72    {  UP_ARROW_2,    s_CTRL_UP   },
   73    {  CTL_END,       s_CTRL_END  },
   74    {  CTL_HOME,      s_CTRL_HOME },
   75    {  -1,             NULL       }
   76 };
   77 #define stop sizeof(scancodes)/sizeof(struct scancodes)-1
   78 
   79 static int get_scancode(char *mn)
   80 {
   81    int i;
   82    i = 0;
   83    for(i=0;i< stop;i++)
   84       if(far_strcmp((char far *)mn,scancodes[i].mnemonic)==0)
   85          break;
   86    return(scancodes[i].code);
   87 }
   88 
   89 static void get_mnemonic(int code,char *mnemonic)
   90 {
   91    int i;
   92    i = 0;
   93    *mnemonic = 0;
   94    for(i=0;i< stop;i++)
   95       if(code == scancodes[i].code)
   96       {
   97          far_strcpy(mnemonic,scancodes[i].mnemonic);
   98          break;
   99       }   
  100 }
  101 #undef stop
  102 
  103 char busy = 0;
  104 static FILE *fpss = NULL;
  105 static long starttick;
  106 static long ticks;
  107 static int slowcount;
  108 static unsigned int quotes;
  109 static char calcwait = 0;
  110 static int repeats = 0;
  111 static int last1 = 0;
  112 static FCODE smsg[] = "MESSAGE";
  113 static FCODE sgoto[] = "GOTO";
  114 static FCODE scalcwait[] = "CALCWAIT";
  115 static FCODE swait[] = "WAIT";
  116 
  117 /* places a temporary message on the screen in text mode */
  118 static int showtempmsg_txt(int row, int col, int attr,int secs,char *txt)
  119 {
  120    int savescrn[80];
  121    int i;
  122    if(text_type > 1)
  123       return(1);
  124    for(i=0;i<80;i++)
  125    {
  126       movecursor(row,i);
  127       savescrn[i] = get_a_char();
  128    }
  129    putstring(row,col,attr,txt);
  130    movecursor(25,80);
  131    sleep_secs(secs);
  132    for(i=0;i<80;i++)
  133    {
  134       movecursor(row,i);
  135       put_a_char(savescrn[i]);
  136    }
  137    return(0);
  138 }
  139 
  140 static void message(int secs, char far *buf)
  141 {
  142    int i;
  143    char nearbuf[41];
  144    i = -1;
  145    while(buf[++i] && i< 40)
  146       nearbuf[i] = buf[i];
  147    nearbuf[i] = 0;
  148    if(text_type < 2)
  149       showtempmsg_txt(0,0,7,secs,nearbuf);
  150    else if (showtempmsg(nearbuf) == 0)
  151       {
  152          sleep_secs(secs);
  153          cleartempmsg();
  154       }
  155 }
  156 
  157 /* this routine reads the file autoname and returns keystrokes */
  158 int slideshw()
  159 {
  160    int out,err,i;
  161    char buffer[81];
  162    if(calcwait)
  163    {
  164       if(calc_status == 1 || busy) /* restart timer - process not done */
  165          return(0); /* wait for calc to finish before reading more keystrokes */
  166       calcwait = 0;
  167    }
  168    if(fpss==NULL)   /* open files first time through */
  169       if(startslideshow()==0)
  170          {
  171          stopslideshow();
  172          return (0);
  173          }
  174 
  175    if(ticks) /* if waiting, see if waited long enough */
  176    {
  177       if(clock_ticks() - starttick < ticks) /* haven't waited long enough */
  178          return(0);
  179       ticks = 0;
  180    }
  181    if (++slowcount <= 18)
  182    {
  183       starttick = clock_ticks();
  184       ticks = CLK_TCK/5; /* a slight delay so keystrokes are visible */
  185       if (slowcount > 10)
  186          ticks /= 2;
  187    }
  188    if(repeats>0)
  189    {
  190       repeats--;
  191       return(last1);
  192    }
  193 start:
  194    if(quotes) /* reading a quoted string */
  195    {
  196       if((out=fgetc(fpss)) != '\"' && out != EOF)
  197          return(last1 = out);
  198       quotes = 0;
  199    }
  200    /* skip white space: */
  201    while ((out=fgetc(fpss)) == ' ' || out == '\t' || out == '\n') { }
  202    switch(out)
  203    {
  204       case EOF:
  205          stopslideshow();
  206          return(0);
  207       case '\"':        /* begin quoted string */
  208          quotes = 1;
  209          goto start;
  210       case ';':         /* comment from here to end of line, skip it */
  211          while((out=fgetc(fpss)) != '\n' && out != EOF) { }
  212          goto start;
  213       case '*':
  214          if (fscanf(fpss,"%d",&repeats) != 1
  215            || repeats <= 1 || repeats >= 256 || feof(fpss))
  216          {
  217             static FCODE msg[] = "error in * argument";
  218             slideshowerr(msg);
  219             last1 = repeats = 0;
  220          }
  221          repeats -= 2;
  222          return(out = last1);
  223    }
  224 
  225    i = 0;
  226    for(;;) /* get a token */
  227    {
  228       if(i < 80)
  229          buffer[i++] = (char)out;
  230       if((out=fgetc(fpss)) == ' ' || out == '\t' || out == '\n' || out == EOF)
  231          break;
  232    }
  233    buffer[i] = 0;
  234    if(buffer[i-1] == ':')
  235       goto start;
  236    out = -12345;
  237    if(isdigit(buffer[0]))       /* an arbitrary scan code number - use it */
  238          out=atoi(buffer);
  239    else if(far_strcmp((char far *)buffer,smsg)==0)
  240       {
  241          int secs;
  242          out = 0;
  243          if (fscanf(fpss,"%d",&secs) != 1)
  244          {
  245             static FCODE msg[] = "MESSAGE needs argument";
  246             slideshowerr(msg);
  247          }
  248          else
  249          {
  250             int len;
  251             char buf[41];
  252             buf[40] = 0;
  253             fgets(buf,40,fpss);
  254             len = strlen(buf);
  255             buf[len-1]=0; /* zap newline */
  256             message(secs,(char far *)buf);
  257          }
  258          out = 0;
  259       }
  260    else if(far_strcmp((char far *)buffer,sgoto)==0)
  261       {
  262          if (fscanf(fpss,"%s",buffer) != 1)
  263          {
  264             static FCODE msg[] = "GOTO needs target";
  265             slideshowerr(msg);
  266             out = 0;
  267          }
  268          else
  269          {
  270             char buffer1[80];
  271             rewind(fpss);
  272             strcat(buffer,":");
  273             do
  274             {
  275                err = fscanf(fpss,"%s",buffer1);
  276             } while( err == 1 && strcmp(buffer1,buffer) != 0);
  277             if(feof(fpss))
  278             {
  279                static FCODE msg[] = "GOTO target not found";
  280                slideshowerr(msg);
  281                return(0);
  282             }
  283             goto start;
  284          }
  285       }
  286    else if((i = get_scancode(buffer)) > 0)
  287          out = i;
  288    else if(far_strcmp(swait,(char far *)buffer)==0)
  289       {
  290          float fticks;
  291          err = fscanf(fpss,"%f",&fticks); /* how many ticks to wait */
  292          fticks *= CLK_TCK;             /* convert from seconds to ticks */
  293          if(err==1)
  294          {
  295             ticks = (long)fticks;
  296             starttick = clock_ticks();  /* start timing */
  297          }
  298          else
  299          {
  300             static FCODE msg[] = "WAIT needs argument";
  301             slideshowerr(msg);
  302          }
  303          slowcount = out = 0;
  304       }
  305    else if(far_strcmp(scalcwait,(char far *)buffer)==0) /* wait for calc to finish */
  306       {
  307          calcwait = 1;
  308          slowcount = out = 0;
  309       }
  310    else if((i=check_vidmode_keyname(buffer)) != 0)
  311       out = i;
  312    if(out == -12345)
  313    {
  314       char msg[MSGLEN];
  315       sprintf(msg,s_cantunderstand,buffer);
  316       slideshowerr(msg);
  317       out = 0;
  318    }
  319    return(last1 = out);
  320 }
  321 
  322 int
  323 startslideshow()
  324 {
  325    if((fpss=fopen(autoname,"r"))==NULL)
  326       slides = 0;
  327    ticks = 0;
  328    quotes = 0;
  329    calcwait = 0;
  330    slowcount = 0;
  331    return(slides);
  332 }
  333 
  334 void stopslideshow()
  335 {
  336    if(fpss)
  337       fclose(fpss);
  338    fpss = NULL;
  339    slides = 0;
  340 }
  341 
  342 void recordshw(int key)
  343 {
  344    char mn[MAX_MNEMONIC];
  345    float dt;
  346    dt = (float)ticks;      /* save time of last call */
  347    ticks=clock_ticks();  /* current time */
  348    if(fpss==NULL)
  349       if((fpss=fopen(autoname,"w"))==NULL)
  350          return;
  351    dt = ticks-dt;
  352    dt /= CLK_TCK;  /* dt now in seconds */
  353    if(dt > .5) /* don't bother with less than half a second */
  354    {
  355       if(quotes) /* close quotes first */
  356       {
  357          quotes=0;
  358          fprintf(fpss,"\"\n");
  359       }
  360       fprintf(fpss,"WAIT %4.1f\n",dt);
  361    }
  362    if(key >= 32 && key < 128)
  363    {
  364       if(!quotes)
  365       {
  366          quotes=1;
  367          fputc('\"',fpss);
  368       }
  369       fputc(key,fpss);
  370    }
  371    else
  372    {
  373       if(quotes) /* not an ASCII character - turn off quotes */
  374       {
  375          fprintf(fpss,"\"\n");
  376          quotes=0;
  377       }
  378       get_mnemonic(key,mn);
  379       if(*mn)
  380           fprintf(fpss,"%s",mn);
  381       else if (check_vidmode_key(0,key) >= 0)
  382          {
  383             char buf[10];
  384             vidmode_keyname(key,buf);
  385             fprintf(fpss,buf);
  386          }
  387       else /* not ASCII and not FN key */
  388          fprintf(fpss,"%4d",key);
  389       fputc('\n',fpss);
  390    }
  391 }
  392 
  393 /* suspend process # of seconds */
  394 static void sleep_secs(int secs)
  395 {
  396    long stop;
  397    stop = clock_ticks() + (long)secs*CLK_TCK;
  398    while(clock_ticks() < stop && kbhit() == 0) { } /* bailout if key hit */
  399 }
  400 
  401 static void slideshowerr(char far *msg)
  402 {
  403    char msgbuf[300];
  404    static FCODE errhdg[] = "Slideshow error:\n";
  405    stopslideshow();
  406    far_strcpy(msgbuf,errhdg);
  407    far_strcat(msgbuf,msg);
  408    stopmsg(0,msgbuf);
  409 }
  410