home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / sgf2mi13.taz / sgf2mi13 / game2eps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-05  |  15.7 KB  |  779 lines

  1. /* #[info:            */
  2. /************************************************************************
  3.  *                                    *
  4.  *                Jan van der Steen                *
  5.  *                                    *
  6.  *          Centre for Mathematics and Computer Science        *
  7.  *              Amsterdam, the Netherlands            *
  8.  *                                    *
  9.  *----------------------------------------------------------------------*
  10.  * File      : game2eps.c                         *
  11.  * Purpose : Emit a Go Game Using PostScript directives            *
  12.  * Version : 1.23                         *
  13.  * Modified: 3/5/93 16:50:30                        *
  14.  * Author  : Jan van der Steen (jansteen@cwi.nl)             *
  15.  ************************************************************************/
  16. /* #]info:            */ 
  17. /* #[include:            */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <assert.h>
  23. #include <time.h>
  24. #include "gogame.h"
  25. #include "game2eps.h"
  26. #include "sysdep.h"
  27.  
  28. /* #]include:            */ 
  29. /* #[extern:            */
  30.  
  31. extern    int     prn_dev;
  32. extern    EPSFINFO epsf;
  33. extern    int     caching;    /* Caching mode                */
  34. extern    int     coords;    /* Print coordinates            */
  35. extern    char *     program;
  36.  
  37. /* #]extern:            */ 
  38. /* #[define:            */
  39.  
  40. #define NODE2EPSI(g,n)    (NODE2I(g,n) - g->gm_size/2)
  41. #define NODE2EPSJ(g,n)    (NODE2J(g,n) - g->gm_size/2)
  42. #define NODE2TEXI(g,n)    (NODE2J(g,n) + 'a' + ((NODE2J(g,n) > 8) ? 1 : 0))
  43. #define NODE2TEXJ(g,n)    (NODE2I(g,n) +  1)
  44. #define NODE2IGSI(g,n)    (NODE2I(g,n) + 'a' + ((NODE2I(g,n) > 8) ? 1 : 0))
  45. #define NODE2IGSJ(g,n)    (g->gm_size - NODE2J(g,n))
  46.  
  47. /* #]define:            */ 
  48. /* #[typedef:            */
  49.  
  50. #ifdef __STDC__
  51. #    define    PROTO(s) s
  52. #else
  53. #    define    PROTO(s) ()
  54. #endif
  55.  
  56. typedef struct dev_info {
  57.     int        (*dev_init   ) PROTO((GOGAME *g, int dianr, int min, int max));
  58.     void    (*dev_cadd   ) PROTO((GOMOVE *m));
  59.     void    (*dev_cdel   ) PROTO((GOGAME *g, GONODE *p));
  60.     void    (*dev_stone  ) PROTO((GOGAME *g, GONODE *p));
  61.     void    (*dev_move   ) PROTO((GOGAME *g, GOMOVE *m));
  62.     void    (*dev_onstone) PROTO((GOGAME *g, GONODE *p, int color, int nr));
  63.     void    (*dev_onmove ) PROTO((GOGAME *g, GONODE *p, int color, int nr));
  64.     void    (*dev_mark   ) PROTO((GOGAME *g, GONODE *p, MARK m));
  65.     void    (*dev_char   ) PROTO((GOGAME *g, GONODE *p, MARK m));
  66.     void    (*dev_exit   ) PROTO((int d, int n1, int n2));
  67. } PRN_DEVICE;
  68.  
  69. #undef PROTO
  70.  
  71. /* #]typedef:            */ 
  72. /* #[prototype:            */
  73.  
  74. #ifdef __STDC__
  75. #    define    PROTO(s) s
  76. #else
  77. #    define    PROTO(s) ()
  78. #endif
  79.  
  80. /*
  81.  * Encapsulated PostScript method
  82.  */
  83. static int    eps_init    PROTO((GOGAME *g, int nr, int min, int max));
  84. static void    eps_cadd    PROTO((GOMOVE *m));
  85. static void    eps_cdel    PROTO((GOGAME *g, GONODE *p));
  86. static void    eps_stone    PROTO((GOGAME *g, GONODE *p));
  87. static void    eps_move    PROTO((GOGAME *g, GOMOVE *m));
  88. static void    eps_onstone    PROTO((GOGAME *g, GONODE *p, int c, int nr));
  89. static void    eps_onmove    PROTO((GOGAME *g, GONODE *p, int c, int nr));
  90. static void    eps_mark    PROTO((GOGAME *g, GONODE *p, MARK m));
  91. static void    eps_char    PROTO((GOGAME *g, GONODE *p, MARK m));
  92. static void    eps_exit    PROTO((int d, int n1, int n2));
  93.  
  94. /*
  95.  * Hanna Ko{\l}odziejska's TeX method
  96.  */
  97. static int    tex_init    PROTO((GOGAME *g, int nr, int min, int max));
  98. static void    tex_cadd    PROTO((GOMOVE *m));
  99. static void    tex_cdel    PROTO((GOGAME *g, GONODE *p));
  100. static void    tex_stone    PROTO((GOGAME *g, GONODE *p));
  101. static void    tex_move    PROTO((GOGAME *g, GOMOVE *m));
  102. static void    tex_onstone    PROTO((GOGAME *g, GONODE *p, int c, int nr));
  103. static void    tex_onmove    PROTO((GOGAME *g, GONODE *p, int c, int nr));
  104. static void    tex_mark    PROTO((GOGAME *g, GONODE *p, MARK m));
  105. static void    tex_char    PROTO((GOGAME *g, GONODE *p, MARK m));
  106. static void    tex_exit    PROTO((int d, int n1, int n2));
  107.  
  108. static void    con_cat        PROTO((char *s));
  109. static void    con_printf    PROTO((char *fmt, ...));
  110. static char *    n2hanna        PROTO((int n, int color));
  111.  
  112.  
  113. #undef PROTO
  114.  
  115. /* #]prototype:            */ 
  116. /* #[static:            */
  117.  
  118. PRN_DEVICE prn_devices[] = {
  119.     {
  120.         eps_init,
  121.         eps_cadd,
  122.         eps_cdel,
  123.         eps_stone,
  124.         eps_move,
  125.         eps_onstone,
  126.         eps_onmove,
  127.         eps_mark,
  128.         eps_char,
  129.         eps_exit,
  130.     },{
  131.         tex_init,
  132.         tex_cadd,
  133.         tex_cdel,
  134.         tex_stone,
  135.         tex_move,
  136.         tex_onstone,
  137.         tex_onmove,
  138.         tex_mark,
  139.         tex_char,
  140.         tex_exit,
  141.     }
  142. };
  143.  
  144. static FILE *    fp;            /* The created eps file        */
  145.  
  146. /* #]static:            */ 
  147.  
  148. /* #[con_cat:            */
  149.  
  150. /*
  151.  * When we need more ko/connect message space we allocate
  152.  * it in chunks of CONNECTCHUNK bytes
  153.  */
  154. #define    CONNECTCHUNK    1024
  155.  
  156. static void
  157. con_cat(s)
  158. /*
  159.  * s != (char *) 0    Append s to connect buffer
  160.  * s == (char *) 0    Flush the connect buffer
  161.  */
  162. char *s;
  163. {
  164.     static char *    con = (char *) 0;
  165.     static char *    con_p;
  166.     static int        n = 0;
  167.  
  168.     /*
  169.      * Flush request ?!
  170.      */
  171.     if (s == (char *) 0) {
  172.     if (con != (char *) 0 && *con) {
  173.         fprintf(stdout, "    \\connect{%s}\n", con);
  174.         *con  = 0;
  175.         con_p = con;
  176.     } else {
  177.         fprintf(stdout, "    \\connect{}\n");
  178.     }
  179.     return;
  180.     }
  181.  
  182.     /*
  183.      * Do we have enough space
  184.      */
  185.     if (con == (char *) 0 || (int)(con_p - con + strlen(s)) + 3 > n) {
  186.     if (n == 0) {
  187.         con  = (char *) malloc(CONNECTCHUNK);
  188.         *con = 0;
  189.     } else con = (char *) realloc(con, n + CONNECTCHUNK);
  190.     n += CONNECTCHUNK;
  191.     }
  192.     if (con == (char *) 0) {
  193.     fprintf(stderr, "Out of memory in con_cat()\n");
  194.     exit(1);
  195.     }
  196.  
  197.     /*
  198.      * Catenate the string
  199.      */
  200.     if (*con != 0) strcat(con, ", ");
  201.     strcat(con, s);
  202. }
  203.  
  204. /* #]con_cat:            */ 
  205. /* #[con_printf:        */
  206.  
  207. #if defined (__STDC__)
  208.     /*#[ANSI-C:    */
  209.  
  210. #include <stdarg.h>
  211.  
  212. static void
  213. con_printf(char *fmt, ...)
  214. {
  215.     va_list argpoint;
  216.     char msg[1024];
  217.  
  218.     va_start(argpoint, fmt);
  219.     vsprintf(msg, fmt, argpoint);
  220.     va_end(argpoint);
  221.     con_cat(msg);
  222. }
  223.  
  224.     /*#]ANSI-C:    */ 
  225. #else
  226.     /*#[not ANSI-C:    */
  227.  
  228. #include <varargs.h>
  229.  
  230. /*VARARGS1*/
  231. static void
  232. con_printf(va_alist)
  233. va_dcl
  234. {
  235.     va_list    argpoint;
  236.     char *    fmt;
  237.     char    msg[256];
  238.  
  239.     va_start(argpoint);
  240.     fmt  = va_arg(argpoint, char *);
  241.     vsprintf(msg, fmt, argpoint);
  242.     va_end(argpoint);
  243.     con_cat(msg);
  244. }
  245.     /*#]not ANSI-C:    */ 
  246. #endif
  247.  
  248. /* #]con_printf:        */ 
  249. /* #[n2hanna:            */
  250.  
  251. static char *
  252. n2hanna(n, color)
  253. /*
  254.  * The Hanna fonts have numbered stones up to 252.
  255.  * We want to use them in captions if possibly.
  256.  */
  257. int n;
  258. int color;
  259. {
  260.     static char texnum[128];
  261.  
  262.     if (n <= 252)
  263.     sprintf(texnum,
  264.         "\\mbox{\\text%s{%d}}",
  265.         (color == BLACK) ? "black" : "white",
  266.         n);
  267.     else
  268.     sprintf(texnum, "%d", n);
  269.  
  270.     return texnum;
  271. }
  272.  
  273. /* #]n2hanna:            */ 
  274.  
  275. /* #[game2eps:            */
  276.  
  277. void
  278. game2eps(gogame, n, min, max)
  279. /*
  280.  * Print a diagram of the position at move max,
  281.  * only numbering the stones in the interval:
  282.  *
  283.  *    min <= numbered stones <= max.
  284.  */
  285. GOGAME *gogame;
  286. int    n;
  287. int    min;
  288. int    max;
  289. {
  290.     PRN_DEVICE *device = prn_devices+prn_dev;
  291.     GOMOVE     *m;
  292.     PLACE    p;
  293.  
  294.     (device->dev_init)(gogame, n, min, max);
  295.  
  296.     /*
  297.      * Print numbered stones between min and max while
  298.      * maintaining the printable stone array (gn_print in GONODE)
  299.      */
  300.     for (m = gogame->gm_move; m && m->mv_nr <= max; m = m->mv_next) {
  301.     assert(m->mv_place != (GONODE *) 0);
  302.  
  303.     if (m->mv_nr >= min) {
  304. /*
  305.          #[numbered stones:
  306. */
  307.         if (m->mv_place->gn_print == 0) {
  308.         (device->dev_move)(gogame, m);
  309.         (device->dev_cadd)(m);
  310.         m->mv_place->gn_print = m->mv_nr;
  311.         }
  312.         else {
  313.         ((m->mv_place->gn_print > 0)
  314.             ? (device->dev_onmove)    /* On a    numbered stone */
  315.             : (device->dev_onstone))    /* On an unnumbered stone */
  316.             (gogame, m->mv_place, m->mv_side, m->mv_nr);
  317.         }
  318. /*
  319.          #]numbered stones: 
  320. */
  321.     } else {
  322. /*
  323.          #[unnumbered stones:
  324. */
  325.         CHAIN *c;
  326.         /*
  327.          * First we remove the captured chains while preserving
  328.          * stones played at a later stage (ishi-no-shita).
  329.          */
  330.         for (c = m->mv_captured; c != (CHAIN *) 0; c = c->ch_next) {
  331.             GONODE *node = c->ch_stone->mv_place;
  332.  
  333.         assert(node != (GONODE *) 0);
  334.         if (node->gn_print < 0) {
  335.             node->gn_print = PRINT_NOTHING;
  336.             (device->dev_cdel)(gogame, node);
  337.             node->gn_cache = 0;
  338.         }
  339.         }
  340.  
  341.         /*
  342.          * Account the unnumbered stones
  343.          */
  344.         if (m->mv_place->gn_print == 0) {
  345.         m->mv_place->gn_print = (m->mv_side == BLACK)
  346.                     ? PRINT_BLACK
  347.                     : PRINT_WHITE;
  348.         } else {
  349.         fprintf(stderr, "[%d at occupied (%c,%d)]", m->mv_nr,
  350.                 NODE2IGSI(gogame, m->mv_place),
  351.                 NODE2IGSJ(gogame, m->mv_place));
  352.         }
  353. /*
  354.          #]unnumbered stones: 
  355. */
  356.     }
  357.     }
  358.  
  359. /* #[print unnumbered stones:    */
  360.  
  361.     /*
  362.      * Add the unnumbered stones
  363.      */
  364.     for (m = gogame->gm_move; m && m->mv_nr <= max; m = m->mv_next) {
  365.     assert(m->mv_place != (GONODE *) 0);
  366.     if (m->mv_nr < min && m->mv_place->gn_print < 0) {
  367.         (device->dev_stone)(gogame, m->mv_place);
  368.     }
  369.     }
  370.  
  371. /* #]print unnumbered stones:    */ 
  372.  
  373.     (device->dev_exit)(n, min, max);
  374.  
  375.     /*
  376.      * Clear the print status fields
  377.      */
  378.     for (p = 0; p < gogame->gm_size*gogame->gm_size; p++) {
  379.     NODE(gogame,p)->gn_print = 0;
  380.     }
  381.  
  382.     /*
  383.      * Flush the ko/connect messages
  384.      */
  385.     con_cat((char *) 0);
  386. }
  387.  
  388. /* #]game2eps:            */ 
  389.  
  390. /* #[eps_init:        */
  391.  
  392. static int
  393. eps_init(gogame, n, min, max)
  394. /*
  395.  * Open the EPSF file and print the header
  396.  */
  397. GOGAME *gogame;
  398. int    n;
  399. int    min;
  400. int    max;
  401. {
  402.     char    epsffile[1024];
  403.     char *    thetime;
  404.     long    seconds;
  405.     long    tenth_mm  = 250L*epsf.eps_size/72;
  406.     int        eps_width = epsf.eps_size;
  407.  
  408.     fprintf(stderr, "[");
  409.  
  410.     /*
  411.      * Account the coordinates too
  412.      */
  413.     if (coords) eps_width += 2*eps_width/gogame->gm_size;
  414.  
  415.     /*
  416.      * Get the creation time
  417.      */
  418.     time(&seconds);
  419.     thetime = ctime(&seconds);
  420.  
  421.     /*
  422.      * Construct the epsf filename
  423.      */
  424.     sprintf(epsffile, "%s%c%s.%03d",
  425.         epsf.eps_dir,
  426.         PATHSEP,
  427.         epsf.eps_name,
  428.         n);
  429.     if ((fp = fopen(epsffile, "w")) == (FILE *) 0) {
  430.     fprintf(stderr, "Couldn't create: \"%s\"\n", epsffile);
  431.     exit(1);
  432.     }
  433.  
  434.     fprintf(fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
  435.     fprintf(fp, "%%%%Title: %s-%s (%d-%d)\n",
  436.         (gogame->gm_white) ? gogame->gm_white : "unknown",
  437.         (gogame->gm_black) ? gogame->gm_black : "unknown",
  438.         min, max);
  439.     fprintf(fp, "%%%%Creator: %s\n", program);
  440.     fprintf(fp, "%%%%CreationDate: %s", thetime);
  441.     fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n", eps_width, eps_width);
  442.     fprintf(fp, "%%%%EndComments\n");
  443.     fprintf(fp, "Liberty begin\n");
  444.     fprintf(fp, "/caching %s def\n", (caching) ? "true" : "false");
  445.     fprintf(fp, "/coords  %s def\n", (coords ) ? "true" : "false");
  446.     fprintf(fp, "%d %ld.%02ld boardinit\n", gogame->gm_size,
  447.         tenth_mm/100, tenth_mm - 100*(tenth_mm/100));
  448.     fprintf(fp, "board\n");
  449.  
  450.     return 1;
  451. }
  452.  
  453. /* #]eps_init:        */ 
  454. /* #[eps_cadd:        */
  455.  
  456. static void
  457. eps_cadd(move)
  458. GOMOVE *move;
  459. {
  460.     move->mv_place->gn_cache = (move->mv_side == BLACK)
  461.                 ? PRINT_BLACK
  462.                 : PRINT_WHITE;
  463. }
  464.  
  465. /* #]eps_cadd:        */ 
  466. /* #[eps_cdel:        */
  467.  
  468. static void
  469. eps_cdel(gogame, node)
  470. GOGAME *gogame;
  471. GONODE *node;
  472. {
  473.     if (caching)
  474.     fprintf(fp, "%d %d cd\n",
  475.         NODE2EPSI(gogame, node),
  476.         NODE2EPSJ(gogame, node));
  477. }
  478.  
  479. /* #]eps_cdel:        */ 
  480. /* #[eps_stone:        */
  481.  
  482. static void
  483. eps_stone(gogame, node)
  484. GOGAME *gogame;
  485. GONODE *node;
  486. {
  487.     if (caching && node->gn_cache == node->gn_print) return;
  488.  
  489.     fprintf(fp, "%d %d %cs\n",
  490.         NODE2EPSI(gogame, node),
  491.         NODE2EPSJ(gogame, node),
  492.         (node->gn_print == PRINT_BLACK) ? 'b' : 'w');
  493. }
  494.  
  495. /* #]eps_stone:        */ 
  496. /* #[eps_move:        */
  497.  
  498. static void
  499. eps_move(gogame, move)
  500. GOGAME *gogame;
  501. GOMOVE *move;
  502. {
  503.     fprintf(fp, "(%d) %d %d %cst\n",
  504.         ((move->mv_nr - 1) % 100) + 1,
  505.         NODE2EPSI(gogame, move->mv_place),
  506.         NODE2EPSJ(gogame, move->mv_place),
  507.         (move->mv_side == BLACK) ? 'b' : 'w');
  508. }
  509.  
  510. /* #]eps_move:        */ 
  511. /* #[eps_onstone:    */
  512.  
  513. static void
  514. eps_onstone(gogame, node, color, movenr)
  515. /*
  516.  * We could try something more fancy here, like checking all neighbours,
  517.  * or adding a mark on the stone (if any)...
  518.  */
  519. GOGAME *gogame;
  520. GONODE *node;
  521. int    color;
  522. int    movenr;
  523. {
  524.     con_printf("%d at (%c,%d)",
  525.         movenr,
  526.         NODE2IGSI(gogame, node),
  527.         NODE2IGSJ(gogame, node));
  528. }
  529.  
  530. /* #]eps_onstone:    */ 
  531. /* #[eps_onmove:    */
  532.  
  533. static void
  534. eps_onmove(gogame, node, color, movenr)
  535. /*
  536.  * A move on the same spot as a previous move
  537.  */
  538. GOGAME *gogame;
  539. GONODE *node;
  540. int    color;
  541. int    movenr;
  542. {
  543.     switch(node->gn_print) {
  544.     case PRINT_BLACK  :
  545.     case PRINT_WHITE  :
  546.     case PRINT_NOTHING: con_printf("%d at (%c,%d)", movenr,
  547.                     NODE2IGSI(gogame, node),
  548.                     NODE2IGSJ(gogame, node));
  549.                 break;
  550.     default          : con_printf("%d at %d", movenr, node->gn_print);
  551.                 break;
  552.     }
  553. }
  554.  
  555. /* #]eps_onmove:    */ 
  556. /* #[eps_mark:        */
  557.  
  558. static void
  559. eps_mark(gogame, node, mark)
  560. GOGAME *gogame;
  561. GONODE *node;
  562. MARK    mark;
  563. {
  564.     fprintf(stderr, "[MARK %d on (%c,%d) ignored]",
  565.             mark,
  566.             NODE2IGSI(gogame, node),
  567.             NODE2IGSJ(gogame, node));
  568. }
  569.  
  570. /* #]eps_mark:        */ 
  571. /* #[eps_char:        */
  572.  
  573. static void
  574. eps_char(gogame, node, mark)
  575. GOGAME *gogame;
  576. GONODE *node;
  577. MARK    mark;
  578. {
  579.     fprintf(stderr, "[CHAR %d on (%c,%d) ignored]",
  580.             mark,
  581.             NODE2IGSI(gogame, node),
  582.             NODE2IGSJ(gogame, node));
  583. }
  584.  
  585. /* #]eps_char:        */ 
  586. /* #[eps_exit:        */
  587.  
  588. static void
  589. eps_exit(n, min, max)
  590. /*
  591.  * Print the EPSF trailer and close the file
  592.  */
  593. int    n;
  594. int    min;
  595. int    max;
  596. {
  597.     fprintf(fp, "end\n");
  598.     fprintf(fp, "%%%%Trailer\n");
  599.     fclose (fp);
  600.     fprintf(stderr, "%d (%d-%d)]", n, min, max);
  601. }
  602.  
  603. /* #]eps_exit:        */ 
  604.  
  605. /* #[tex_init:        */
  606.  
  607. static int
  608. tex_init(gogame, n, min, max)
  609. GOGAME *gogame;
  610. int    n;
  611. int    min;
  612. int    max;
  613. {
  614.     fprintf(stderr, "[");
  615.     fprintf(stdout, "%%%% #[diagram %03d (%d-%d):\n", n, min, max);
  616.     fprintf(stdout, "\\inifulldiagram\n");
  617.  
  618.     return 1;
  619. }
  620.  
  621. /* #]tex_init:        */ 
  622. /* #[tex_cadd:        */
  623.  
  624. static void
  625. tex_cadd(move)
  626. GOMOVE *move;
  627. {
  628.     move->mv_place->gn_cache = (move->mv_side == BLACK)
  629.                 ? PRINT_BLACK
  630.                 : PRINT_WHITE;
  631. }
  632.  
  633. /* #]tex_cadd:        */ 
  634. /* #[tex_cdel:        */
  635.  
  636. static void
  637. tex_cdel(gogame, node)
  638. GOGAME *gogame;
  639. GONODE *node;
  640. {
  641.     if (caching)
  642.     fprintf(stdout, "%% [DC(%c,%d)]\n",
  643.         NODE2TEXI(gogame, node),
  644.         NODE2TEXJ(gogame, node));
  645. }
  646.  
  647. /* #]tex_cdel:        */ 
  648. /* #[tex_stone:        */
  649.  
  650. static void
  651. tex_stone(gogame, node)
  652. GOGAME *gogame;
  653. GONODE *node;
  654. {
  655.     fprintf(stdout, "\\p:%c-%d=\\%c.\n",
  656.         NODE2TEXI(gogame, node),
  657.         NODE2TEXJ(gogame, node),
  658.         (node->gn_print == PRINT_BLACK) ? 'b' : 'w');
  659. }
  660.  
  661. /* #]tex_stone:        */ 
  662. /* #[tex_move:        */
  663.  
  664. static void
  665. tex_move(gogame, move)
  666. GOGAME *gogame;
  667. GOMOVE *move;
  668. {
  669.     fprintf(stdout, "\\p:%c-%d=\\%c{%d}\n",
  670.         NODE2TEXI(gogame, move->mv_place),
  671.         NODE2TEXJ(gogame, move->mv_place),
  672.         (move->mv_side == BLACK) ? 'b' : 'w',
  673.         ((move->mv_nr - 1) % 100) + 1);
  674. }
  675.  
  676. /* #]tex_move:        */ 
  677. /* #[tex_onstone:    */
  678.  
  679. static void
  680. tex_onstone(gogame, node, color, movenr)
  681. /*
  682.  * A move on the same spot as a previous move
  683.  */
  684. GOGAME *gogame;
  685. GONODE *node;
  686. int    color;
  687. int    movenr;
  688. {
  689.     con_printf("%s at (%c,%d)",
  690.         n2hanna(movenr, color),
  691.         NODE2IGSI(gogame, node),
  692.         NODE2IGSJ(gogame, node));
  693. }
  694.  
  695. /* #]tex_onstone:    */ 
  696. /* #[tex_onmove:    */
  697.  
  698. static void
  699. tex_onmove(gogame, node, color, movenr)
  700. /*
  701.  * A move at the same spot as another move
  702.  */
  703. GOGAME *gogame;
  704. GONODE *node;
  705. int    color;
  706. int    movenr;
  707. {
  708.     switch(node->gn_print) {
  709.     case PRINT_BLACK  :
  710.     case PRINT_WHITE  :
  711.     case PRINT_NOTHING:
  712.         con_printf("%s at (%c,%d)",
  713.                 n2hanna(movenr, color),
  714.                 NODE2IGSI(gogame, node),
  715.                 NODE2IGSJ(gogame, node));
  716.         break;
  717.     default:
  718.         {
  719.             char onmove[128];
  720.  
  721.             strcpy(onmove, n2hanna(movenr, color));
  722.             strcat(onmove, " at ");
  723.             strcat(onmove, n2hanna(node->gn_print,
  724.                   ((node->gn_print + movenr) & 0x01)
  725.                       ? (color == BLACK) ? WHITE : BLACK
  726.                       : color));
  727.             con_printf(onmove);
  728.         }
  729.         break;
  730.     }
  731. }
  732.  
  733. /* #]tex_onmove:    */ 
  734. /* #[tex_mark:        */
  735.  
  736. static void
  737. tex_mark(gogame, node, mark)
  738. GOGAME *gogame;
  739. GONODE *node;
  740. MARK    mark;
  741. {
  742.     fprintf(stderr, "[MARK %d on (%c,%d) ignored]",
  743.             mark,
  744.             NODE2IGSI(gogame, node),
  745.             NODE2IGSJ(gogame, node));
  746. }
  747.  
  748. /* #]tex_mark:        */ 
  749. /* #[tex_char:        */
  750.  
  751. static void
  752. tex_char(gogame, node, mark)
  753. GOGAME *gogame;
  754. GONODE *node;
  755. MARK    mark;
  756. {
  757.     fprintf(stderr, "[CHAR %d on (%c,%d) ignored]",
  758.             mark,
  759.             NODE2IGSI(gogame, node),
  760.             NODE2IGSJ(gogame, node));
  761. }
  762.  
  763. /* #]tex_char:        */ 
  764. /* #[tex_exit:        */
  765.  
  766. static void
  767. tex_exit(n, min, max)
  768. int    n;
  769. int    min;
  770. int    max;
  771. {
  772.     fprintf(stdout, "\\showfulldiagram\n");
  773.     fprintf(stdout, "%%%% #]diagram %03d (%d-%d): \n", n, min, max);
  774.     fprintf(stderr, "%d (%d-%d)]", n, min, max);
  775. }
  776.  
  777. /* #]tex_exit:        */ 
  778.  
  779.