home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume18 / notation / part02 / drivers.c < prev    next >
C/C++ Source or Header  |  1991-04-13  |  14KB  |  551 lines

  1. #include<stdio.h>
  2.  
  3. #include <ctype.h>
  4. #include "chesstype.h"
  5. #include "notation.h"
  6. #include "drivers.h"
  7.  
  8. /* postscript characters translation table
  9.    one entry per piece
  10.    each entry has four fields:
  11.    - white piece on white case
  12.    - white piece on black case
  13.    - black piece on ...
  14.    ..
  15.  */
  16. #define PSINDEX(a,b) ((((a)==WHITE)?0:2)+(((b)%2)?0:1))
  17.  
  18. static char * postscript_table[][4] = {
  19.   { " ", "x",     " ", "x"     }, /* void */
  20.   { "k", "\\373", "K", "\\360" }, /* king */
  21.   { "q", "\\317", "Q", "\\316" }, /* queen */
  22.   { "r", "\\250", "R", "\\345" }, /* rook */
  23.   { "b", "\\272", "B", "\\365" }, /* bishop */
  24.   { "n", "\\265", "N", "\\366" }, /* knight */
  25.   { "p", "\\271", "P", "\\270" }  /* pawn */
  26. };
  27.  
  28. /* TeX table for using the chess figure in board design */
  29. static char * metafont_table[][4] = {
  30.   /*   W/W      W/B      B/W      B/B */
  31.   { "\\WWW", "\\DDD", "\\WWW", "\\DDD" }, /* void */
  32.   { "\\WKW", "\\WKB", "\\BKW", "\\BKB" }, /* king */
  33.   { "\\WQW", "\\WQB", "\\BQW", "\\BQB" }, /* queen */
  34.   { "\\WRW", "\\WRB", "\\BRW", "\\BRB" }, /* rook */
  35.   { "\\WBW", "\\WBB", "\\BBW", "\\BBB" }, /* bishop */
  36.   { "\\WNW", "\\WNB", "\\BNW", "\\BNB" }, /* knight */
  37.   { "\\WPW", "\\WPB", "\\BPW", "\\BPB" }  /* pawn */
  38. };
  39.  
  40. /* TeX table for using the chess figures in move description */
  41. static char * latex_table[] = {
  42.   "\\FigVoid", "\\FigK", "\\FigQ", "\\FigR", "\\FigB", "\\FigN", "\\FigP"
  43. };
  44.  
  45. /* various tex symbols */
  46. static char FigDash[] = "\\FigDash";
  47. static char FigCapt[] = "\\FigCapt";
  48. static char FigDots[] = "\\FigDots";
  49. static char FigDot[] = "\\FigDot";
  50.  
  51. #define G_ROQUE  "O-O-O" 
  52. #define P_ROQUE  "O-O" 
  53.  
  54. static FILE * ftmp ;
  55.  
  56.  
  57. /* ---------------- output functions ---------------- */
  58.  
  59. /* convert a roque in term of king's move */
  60. static int roque_to_move(m)
  61.      depl * m;
  62. {
  63.  
  64.   m->piece = KING;
  65.   m->fromcol   = 5;
  66.   if (m->type == GRANDROQUE)  
  67.     m->tocol = 3;
  68.   else
  69.     m->tocol = 7;
  70.  
  71.   if (m->whiteturn)
  72.     m->fromlig = m->tolig = 1;
  73.   else
  74.     m->fromlig = m->tolig = 8;
  75.  
  76.   return(TRUE);
  77. }
  78.  
  79. /* (kind of) buffering of output */
  80. static void init_buffer(d,side)
  81.      format * d;
  82.      int side ;
  83. {
  84.   switch (d->type) {
  85.   case D_ASCII:
  86.     if (side != BLACK) (void) sprintf(d->white_buffer,"...");
  87.     if (side != WHITE) (void) sprintf(d->black_buffer,"   ");
  88.     break;
  89.   case D_TEX:
  90.     if (side != BLACK) (void) sprintf(d->white_buffer,"%s",FigDots);
  91.     if (side != WHITE) (void) sprintf(d->black_buffer,"~");
  92.     break;
  93.   default:
  94.     if (side != BLACK) d->white_buffer[0] = '\0' ;
  95.     if (side != WHITE) d->black_buffer[0] = '\0' ;
  96.     break;
  97.   }
  98. }
  99.  
  100. /* this procedure is responsible for PRINTING the move */
  101. static void flush_buffer(d)
  102.      format * d;
  103. {
  104.   
  105.   /* if we have been inteerupted (by a comment, a board display etc...
  106.      if the move is black
  107.      we display <movenumber> ... <blackmove>
  108.      */
  109.   if ((d->interrupt == TRUE) && (d->iswhiteturn == FALSE)) {
  110.     switch (d->type) {
  111.     case D_TEX:
  112.       (void) fprintf(d->outfile,
  113.              "\\noindent\\movenumber{\\bf %s\\FigDot}\\whitemove{%s}\\blackmove{%s}\n", 
  114.              d->move_buffer,FigDots,d->black_buffer);
  115.       break;
  116.     case D_GNU:
  117.       /* no special case for GNU */
  118.       (void) fprintf(d->outfile,"\t%s\n",d->black_buffer);
  119.       break;    
  120.     default:
  121.       (void) fprintf(d->outfile,"%3s.%9s%9s\n", 
  122.              d->move_buffer,"...",d->black_buffer);
  123.       break;
  124.     }
  125.     d->interrupt = FALSE ;
  126.   } else {
  127.   /* else (no interrupt)
  128.      we display either white or black move 
  129.      */
  130.     switch (d->type) {
  131.     case D_TEX:
  132.       if (d->iswhiteturn)
  133.     (void) fprintf(d->outfile,
  134.                "\\noindent\\movenumber{\\bf %s\\FigDot}\\whitemove{%s}", d->move_buffer,d->white_buffer);
  135.       else
  136.     (void) fprintf(d->outfile,
  137.                "\\blackmove{%s}\n",d->black_buffer);
  138.       break;
  139.     case D_GNU:
  140.       if (d->iswhiteturn)
  141.     (void) fprintf(d->outfile,"\t%s",d-> white_buffer);
  142.       else
  143.     (void) fprintf(d->outfile,"\t%s\n",d->black_buffer);
  144.       break;    
  145.     default:
  146.       if (d->iswhiteturn)
  147.     (void) fprintf(d->outfile,"%3s.%9s", d->move_buffer,d->white_buffer);
  148.       else
  149.     (void) fprintf(d->outfile,"%9s\n", d->black_buffer);
  150.       break;
  151.     }
  152.   } /* end printing */
  153.  
  154.   /* reset buffer */
  155.   if (! d->iswhiteturn)
  156.     init_buffer(d,VOID);
  157.   d->interrupt = FALSE;
  158. }
  159.  
  160. /* a generic parametrised driver for move output
  161.    */
  162. static void output_move_generic(dr,d)
  163.      format * dr;
  164.      depl *d;
  165. {
  166.   char ligne[128] ;
  167.   char themove[128] ;
  168.   char thepiece[16]  ;
  169.   char debcol[16];
  170.   char frommove[16]  ;
  171.   char tomove[16] ;
  172.   char lie[16] ;
  173.   char prom[16];
  174.  
  175.   int ambigue = FALSE ;
  176.  
  177.   ligne[0] = themove[0] = thepiece[0] = debcol[0]  = '\0';
  178.   frommove[0] = tomove[0] = lie[0] = prom[0] = '\0' ;
  179.  
  180.  
  181.   (void) sprintf (dr->move_buffer,"%d",d->move);
  182.  
  183.   if ((d->type == PETITROQUE) && !dr->roque_alg)
  184.     (void) sprintf (themove,"%s",P_ROQUE);
  185.   if ((d->type == GRANDROQUE) && !dr->roque_alg)
  186.     (void) sprintf (themove,"%s",G_ROQUE);
  187.   if (dr->roque_alg && 
  188.       ((d->type == GRANDROQUE) || (d->type == PETITROQUE)))
  189.     (void) roque_to_move(d);
  190.  
  191.   if (dr-> roque_alg || 
  192.       ((d->type != GRANDROQUE) && (d->type != PETITROQUE))) {
  193.  
  194.     /* we check here for ambiguous move */
  195.     if ((d->type != GRANDROQUE) && (d->type != PETITROQUE)) {
  196.       ambigue = ambiguity (d->piece, d->tolig,d->tocol);
  197.       /* if ( (ambigue ) && (d->piece != PAWN ))
  198.        * (void) fprintf (stderr,"ambiguity at move %d",tos->move);
  199.        */
  200.     }
  201.     themove[0] = '\0' ;
  202.     if ((dr->output_move_format == SHORTENED) 
  203.     && (d->type == PRISE) && (d->piece == PAWN))
  204.       (void) sprintf (debcol, "%c",coltoletter(d->fromcol));
  205.  
  206.     if (dr->print_piece)
  207.       if (d->piece != PAWN || dr->print_pawn) {
  208.     if (dr->type == D_TEX )
  209.       (void) sprintf(thepiece,"%s ",latex_table[d->piece]);
  210.     else
  211.       (void) sprintf(thepiece,"%c",dr->out_table[d->piece]);
  212.       }
  213.  
  214.     if ((dr->output_move_format == ALGEBRAIC))
  215.       (void)sprintf(frommove,"%c%c",
  216.             coltoletter(d->fromcol),ligtoletter(d->fromlig));
  217.     if ( ambigue && dr->print_liaison ) {
  218.       (void) sprintf(lie,"-");
  219.       (void)sprintf(frommove,"%c%c",
  220.             coltoletter(d->fromcol),ligtoletter(d->fromlig));
  221.       debcol[0] = '\0' ;
  222.     }
  223.     if (d->promotion) {
  224.       if (dr->print_piece) {
  225.     if (dr->type == D_TEX )
  226.       (void) sprintf(prom,"=%s ",latex_table[d->promotion]);
  227.       else
  228.         (void) sprintf(prom,"=%c",dr->out_table[d->promotion]);
  229.       }
  230.     }
  231.           
  232.     if (dr->print_liaison) {
  233.       if ((d->type == PRISE) || (d->type == PROM_ET_PRISE) 
  234.       || (d->type == EN_PASSANT) )
  235.     (void) sprintf(lie,"%c",'x');
  236.       else
  237.     if ((dr->output_move_format == ALGEBRAIC))
  238.       (void) sprintf(lie,"%c",'-');
  239.     }
  240.     
  241.     (void) sprintf(tomove,"%c%c",coltoletter(d->tocol),ligtoletter(d->tolig));
  242.  
  243.     (void) sprintf (themove,"%s%s%s%s%s%s",
  244.             thepiece,debcol,frommove,lie, tomove,prom);
  245.   }
  246.  
  247.   if (d->whiteturn)
  248.     (void) sprintf (dr->white_buffer, "%s",themove);
  249.   else
  250.     (void) sprintf (dr->black_buffer, "%s",themove);
  251.  
  252.   dr->iswhiteturn = d->whiteturn; 
  253.  
  254.   /*fprintf(dr->outfile, "=%d=%d= ",d->move,d->whiteturn);*/
  255.   flush_buffer(dr); 
  256. }
  257.  
  258. /* ---------------- ascii driver ----------  */
  259. static void output_init_ascii(dr) 
  260. format *dr;
  261. {}
  262.     
  263. static void output_board_ascii(dr,g)
  264.      format * dr;
  265.      game * g;
  266. {
  267.   register int i,j;
  268.  
  269.   dr->interrupt = TRUE;
  270.  
  271.   (void) fprintf(dr->outfile,"\n\n");
  272.   for (i=8 ; i >=1 ; i--) {
  273.     if (dr->coordinates)
  274.       (void) fprintf(dr->outfile,"%d ",i);
  275.     (void) fputc('|',dr->outfile);
  276.     for (j=1 ; j<9 ; j++) {
  277.       if (g->board[i][j] != VOID) {
  278.     if (g->color[i][j] == WHITE) 
  279.      (void) fputc(dr->out_table[g->board[i][j]], dr->outfile);
  280.     else 
  281.       (void) fputc(tolower(dr->out_table[g->board[i][j]]),dr->outfile);
  282.       } else
  283.     (void) fputc ( ((i+j)% 2)?' ':'/', dr->outfile);
  284.       (void) fputc('|', dr->outfile);
  285.     }
  286.     (void) fputc('\n', dr->outfile);
  287.   }
  288.   if (dr->coordinates)
  289.     (void) fprintf(dr->outfile,"   a b c d e f g h\n");
  290.   (void) fprintf(dr->outfile,"\n");
  291. }
  292.  
  293. /* ---------------- postscript --------- */
  294.  
  295. static void output_board_ps(dr,g)
  296.      format *dr;
  297.      game * g;
  298. {
  299.   register int i,j;
  300.   register int c;
  301.   char chaine[MAXTOKLEN];
  302.  
  303.   /* header file */
  304.   (void) strcpy(chaine,LIB_DIR);
  305.   if ((ftmp = fopen(strcat(chaine,PS_HEADER),"r")) == NULL)
  306.     message((stderr,"Can't open ps header file.\n"));
  307.   else {
  308.     while ((c = getc(ftmp)) != EOF)
  309.       (void) fputc(c,dr->outfile);
  310.     (void) fclose(ftmp);
  311.   }
  312.  
  313.   (void) fprintf(dr->outfile,"( ________) 72 714 T\n");
  314.   for (i=8 ; i >=1 ; i--) {
  315.     (void) fprintf(dr->outfile,"(/");
  316.     for (j=1 ; j<9 ; j++) {
  317.     (void) fprintf(dr->outfile,"%s",
  318.            postscript_table[g->board[i][j]][PSINDEX(g->color[i][j],(i+j))]);
  319.     }
  320.     (void) fprintf(dr->outfile,"\\\\) 72 %d T\n",474 + (i-1)*30);
  321.   }
  322.   (void) fprintf(dr->outfile,"( --------) 72 444 T\n");
  323.  
  324.   /* footer file */
  325.   (void) strcpy(chaine,LIB_DIR);
  326.   if ((ftmp = fopen(strcat(chaine,PS_FOOTER),"r")) == NULL)
  327.     message((stderr,"Can't open ps footer file.\n"));
  328.   else {
  329.     while ((c = getc(ftmp)) != EOF)
  330.       (void) fputc(c,dr->outfile);
  331.     (void) fclose(ftmp);
  332.   }
  333. }
  334.  
  335. /* ---------------- nroff --------------- */
  336. static void output_init_roff(dr)
  337.      format *dr;
  338. {
  339. }
  340.  
  341. static void output_board_roff(dr,g)
  342.      format *dr;
  343.      game * g;
  344. {
  345.   register int i,j;
  346.  
  347.   dr->interrupt = TRUE;
  348.  
  349.   (void) fprintf(dr->outfile,".br\n");
  350.   for (i=8 ; i >=1 ; i--) {
  351.     (void) fprintf(dr->outfile,".ce\n  ");
  352.     for (j=1 ; j<9 ; j++) {
  353.       if (g->board[i][j] != VOID) {
  354.     if (g->color[i][j] == WHITE) 
  355.      (void) fputc(dr->out_table[g->board[i][j]], dr->outfile);
  356.     else 
  357.       (void) fputc(tolower(dr->out_table[g->board[i][j]]),dr->outfile);
  358.       } else
  359.     /*(void) fputc ( ((i+j)% 2)?' ':'/', dr->outfile);*/
  360.     (void) fprintf(dr->outfile,".");
  361.     }
  362.     (void) fprintf(dr->outfile,"\n.br\n");
  363.   }
  364.   (void) fprintf(dr->outfile,"\n");
  365. }
  366.  
  367. /* ---------------- tex -------------------- */
  368. static void output_init_tex(dr)
  369.      format *dr;
  370. {
  371.   register int c;
  372.   char chaine[MAXTOKLEN];
  373.  
  374.   /* header file */
  375.   (void) strcpy(chaine,LIB_DIR);
  376.   if ((ftmp = fopen(strcat(chaine,TEX_HEADER),"r")) == NULL)
  377.     message((stderr,"Can't open tex header file.\n"));
  378.   else {
  379.     while ((c = getc(ftmp)) != EOF)
  380.       (void) fputc(c,dr->outfile);
  381.     (void) fclose(ftmp);
  382.   }
  383. }
  384.  
  385. static void output_board_tex(dr,g)
  386.      format *dr;
  387.      game * g;
  388. {
  389.   register int i,j;
  390.  
  391.   dr->interrupt = TRUE;
  392.  
  393.   (void) fprintf(dr->outfile,"\n\n");
  394.   (void)fprintf(dr->outfile,"$$\\vbox{\\bigskip\\offinterlineskip\\tabskip=0pt\n");
  395.   (void) fprintf(dr->outfile,"\\halign{#\\vvrule &#&#&#&#&#&#&#&#&#\\vvrule \\cr\n");
  396.   (void) fprintf(dr->outfile,"\\noalign{\\hhrule}\n");
  397.   for (i=8 ; i >=1 ; i--) {
  398.     (void) fprintf(dr->outfile,"&");
  399.     for (j=1 ; j < 9 ; j++) {
  400.     (void) fprintf(dr->outfile,"%s",
  401.            metafont_table[g->board[i][j]][PSINDEX(g->color[i][j],(i+j))]);
  402.       (void) fprintf(dr->outfile,"&");
  403.     }
  404.     (void) fprintf(dr->outfile,"\\cr \n");
  405.   }
  406.   (void) fprintf(dr->outfile,"\\noalign{\\hhrule}}}$$");
  407.   (void) fprintf(dr->outfile,"");
  408.   (void) fprintf(dr->outfile,"\n\n");
  409. }
  410.  
  411. static void output_end_tex(dr)
  412.      format *dr;
  413.   (void) fprintf(dr->outfile, "~\n\n\n\\end{document}\n");
  414. }
  415.  
  416. /* ------------------ gnu - xchess ---------- */
  417.  
  418. static void output_init_gnu(dr)
  419.      format *dr;
  420. {
  421.   (void) fprintf(dr->outfile, "X Chess -- Mon Dec 10 11:47:18 MET 1990\n");
  422.   (void) fprintf(dr->outfile,"\tGame played on dumbkopft.irisa.fr:0.0\n");
  423.   (void) fprintf(dr->outfile,"\talgebraic\n");
  424. }
  425.  
  426. /* ---------------- driver handler ---------- */
  427. /* dummy driver */
  428. static void null_driver() {}
  429.  
  430. /* the drivers */
  431. void output_init(dr)
  432.      format *dr ;
  433. {
  434.   dr->out_init(dr);
  435. }
  436.  
  437. void output_move(dr,d)
  438.      format *dr ;
  439.      depl *d;
  440. {
  441.   dr->out_move(dr,d);
  442. }
  443.  
  444. void output_board(dr,g)
  445.      format *dr ;
  446.      game *g ;
  447. {
  448.   dr->out_board(dr,g);
  449. }
  450.  
  451. void output_end(dr)
  452.      format *dr ;
  453. {
  454.   dr->out_end(dr);
  455. }
  456.  
  457.  
  458. format * new_driver()
  459. {
  460.   format * tmp;
  461.   int i; 
  462.  
  463.   tmp = (format *) malloc (sizeof(format));
  464.   ALLOCP(tmp);
  465.   /*for (i=0; i < ((sizeof (format))/ sizeof (int)) ; i++)
  466.     ((int *) tmp)[i] = 0;*/
  467.   return(tmp);
  468. }
  469.  
  470. void init_driver(dr,driver)
  471.      format * dr;
  472.      int driver;
  473. {
  474.   dr->type = driver ;
  475.  
  476.   switch (dr->type) {
  477.   case D_ASCII:
  478.     dr->print_move = TRUE;
  479.     dr->print_piece = TRUE;
  480.     dr->print_pawn = FALSE;
  481.     dr->roque_alg = FALSE;
  482.     dr->print_liaison = TRUE;
  483.     dr->out_init = output_init_ascii;
  484.     dr->out_move = output_move_generic;
  485.     dr->out_board = output_board_ascii;
  486.     dr->out_end = null_driver;
  487.     break;
  488.   case D_POST:
  489.     dr->out_init = null_driver;
  490.     dr->out_move = null_driver;
  491.     dr->out_board = output_board_ps;
  492.     dr->out_end = null_driver;
  493.     break;
  494.   case D_TEX:
  495.     dr->print_move = TRUE;
  496.     dr->print_piece = TRUE;
  497.     dr->print_pawn = FALSE;
  498.     dr->roque_alg = FALSE;
  499.     dr->print_liaison = TRUE;
  500.     dr->out_init = output_init_tex;
  501.     dr->out_move = output_move_generic;
  502.     dr->out_board = output_board_tex;
  503.     dr->out_end = output_end_tex;
  504.     break;
  505.   case D_ROFF:
  506.     dr->print_move = TRUE;
  507.     dr->print_piece = TRUE;
  508.     dr->print_pawn = FALSE;
  509.     dr->roque_alg = FALSE;
  510.     dr->print_liaison = TRUE;
  511.     dr->out_init = output_init_roff;
  512.     dr->out_move = output_move_generic;
  513.     dr->out_board = output_board_roff;
  514.     dr->out_end = null_driver;
  515.     break;
  516.   case D_XCHESS:
  517.     dr->print_move = TRUE;
  518.     dr->print_piece = FALSE;
  519.     dr->print_pawn = FALSE;
  520.     dr->roque_alg = TRUE;
  521.     dr->print_liaison = FALSE;
  522.     dr->out_init = output_init_gnu;
  523.     dr->out_move = output_move_generic;
  524.     dr->out_board = null_driver;
  525.     dr->out_end = null_driver;
  526.     break;
  527.   case D_GNU:
  528.     dr->print_move = FALSE;
  529.     dr->print_piece = FALSE;
  530.     dr->print_pawn = FALSE;
  531.     dr->roque_alg = TRUE;
  532.     dr->print_liaison = FALSE;
  533.     dr->out_init = null_driver;
  534.     dr->out_move = output_move_generic;
  535.     dr->out_board = null_driver;
  536.     dr->out_end = null_driver;
  537.     break;
  538.   default:
  539.     error((stderr,"unknown driver"));
  540.     break;
  541.   }
  542.   if (dr->only_board)
  543.     dr->out_move = null_driver ;
  544.  
  545.   dr->variation_level = 0;
  546.   dr->iswhiteturn = FALSE ;
  547.   dr->interrupt = FALSE;
  548.   init_buffer(dr, VOID);
  549. }
  550.