Warnings: correctly use #ifdef for declarations.
[gnushogi.git] / gnushogi / commondsp.c
index 50dc032..14fd387 100644 (file)
@@ -4,11 +4,15 @@
  *     Common display routines for GNU Shogi.
  *
  * ----------------------------------------------------------------------
- *
- * Copyright (c) 2012 Free Software Foundation
+ * Copyright (c) 1993, 1994, 1995 Matthias Mutz
+ * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
+ * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
  *
  * GNU SHOGI is based on GNU CHESS
  *
+ * Copyright (c) 1988, 1989, 1990 John Stanback
+ * Copyright (c) 1992 Free Software Foundation
+ *
  * This file is part of GNU SHOGI.
  *
  * GNU Shogi is free software; you can redistribute it and/or modify it
  *
  */
 
+/* request *snprintf prototypes */
+#define _POSIX_C_SOURCE 200112L
+#include <stdio.h>
+
 #if defined HAVE_GETTIMEOFDAY
 #include <sys/time.h>
 #endif
 #include <sys/types.h>
 #include <sys/file.h>
 
-#include <curses.h>
 #include "gnushogi.h"
 
 char mvstr[4][6];
-char *InPtr;
-int InBackground = false;
+int mycnt1, mycnt2;
+static char *InPtr;
+struct display *dsp = &raw_display;
 
+short xboard = false;
 
 #if defined(BOOKTEST)
 
@@ -86,20 +95,20 @@ movealgbr(short m, char *s)
         s++;
         *s = '*';
         s++;
-        *s = cxx[column(t)];
+        *s = COL_NAME(column(t));
         s++;
-        *s = rxx[row(t)];
+        *s = ROW_NAME(row(t));
         s++;
     }
     else
     {
-        *s = cxx[column(f)];
+        *s = COL_NAME(column(f));
         s++;
-        *s = rxx[row(f)];
+        *s = ROW_NAME(row(f));
         s++;
-        *s = cxx[column(t)];
+        *s = COL_NAME(column(t));
         s++;
-        *s = rxx[row(t)];
+        *s = ROW_NAME(row(t));
         s++;
 
         if (flag & promote)
@@ -121,10 +130,22 @@ movealgbr(short m, char *s)
 #endif /* BOOKTEST */
 
 
-
-
 /*
  * Generate move strings in different formats.
+ *
+ * INPUT:
+ * - f                                 piece to be moved
+ *   - 0 < f < NO_SQUARES                              source square
+ *   - NO_SQUARES <= f NO_SQUARES + 2*NO_PIECES                dropped piece modulo NO_PIECES
+ * - t & 0x7f                          target square
+ * - t & 0x80                          promotion flag
+ * - flag
+ *   - if flag & dropmask, piece type encoded in flag & pmask
+ *
+ * FIXME: that makes 2 ways to specify drops and promotions, why ?
+ *
+ * OUTPUT:
+ * - GLOBAL mvstr
  */
 
 void
@@ -150,12 +171,8 @@ algbr(short f, short t, short flag)
 
     if ((f == t) && ((f != 0) || (t != 0)))
     {
-        if (!barebones)
-        {
-            if (NOT_CURSES)
-                printf("error in algbr: FROM=TO=%d, flag=0x%4x\n", t, flag);
-            else
-                printw("error in algbr: FROM=TO=%d, flag=0x%4x\n", t, flag);
+        if (!XSHOGI) {
+            dsp->Printf("error in algbr: FROM=TO=%d, flag=0x%4x\n", t, flag);
         }
 
         mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
@@ -165,9 +182,9 @@ algbr(short f, short t, short flag)
         short piece = flag & pmask;
 
         mvstr[0][0] = pxx[piece];
-        mvstr[0][1] = '*';
-        mvstr[0][2] = cxx[column(t)];
-        mvstr[0][3] = rxx[row(t)];
+        mvstr[0][1] = xboard ? '@' : '*';
+        mvstr[0][2] = COL_NAME(column(t));
+        mvstr[0][3] = ROW_NAME(row(t));
         mvstr[0][4] = '\0';
         strcpy(mvstr[1], mvstr[0]);
         strcpy(mvstr[2], mvstr[0]);
@@ -175,20 +192,27 @@ algbr(short f, short t, short flag)
     }
     else if ((f != 0) || (t != 0))
     {
-        /* algebraic notation */
-        mvstr[0][0] = cxx[column(f)];
-        mvstr[0][1] = rxx[row(f)];
-        mvstr[0][2] = cxx[column(t)];
-        mvstr[0][3] = rxx[row(t)];
-        mvstr[0][4] = mvstr[3][0] = '\0';
+        /* pure coordinates notation */
+        mvstr[0][0] = COL_NAME(column(f));
+        mvstr[0][1] = ROW_NAME(row(f));
+        mvstr[0][2] = COL_NAME(column(t));
+        mvstr[0][3] = ROW_NAME(row(t));
+        mvstr[0][4] = '\0';
+
+        /* algebraic notation without disambiguation */
         mvstr[1][0] = pxx[board[f]];
+        mvstr[1][1] = mvstr[0][2];    /* to column */
+        mvstr[1][2] = mvstr[0][3];    /* to row */
+        mvstr[1][3] = '\0';
 
+        /* algebraic notation with row disambiguation */
         mvstr[2][0] = mvstr[1][0];
         mvstr[2][1] = mvstr[0][1];
+        mvstr[2][2] = mvstr[0][2];    /* to column */
+        mvstr[2][3] = mvstr[0][3];    /* to row */
+        mvstr[2][4] = '\0';
 
-        mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
-        mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
-        mvstr[2][4] = mvstr[1][3] = '\0';
+        /* algebraic notation with column disambiguation */
         strcpy(mvstr[3], mvstr[2]);
         mvstr[3][1] = mvstr[0][0];
 
@@ -207,7 +231,6 @@ algbr(short f, short t, short flag)
 }
 
 
-
 /*
  * Compare the string 's' to the list of legal moves available for the
  * opponent. If a match is found, make the move on the board.
@@ -288,20 +311,7 @@ VerifyMove(char *s, VerifyMove_mode iop, unsigned short *mv)
         if (SqAttacked(PieceList[opponent][0], computer, &blocked))
         {
             UnmakeMove(opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
-
-            if (NOT_CURSES)
-            {
-                /* Illegal move in check */
-                printf(CP[77], mvstr[0]);
-                printf("\n");
-            }
-            else
-            {
-                /* Illegal move in check */
-                sprintf(buffer, CP[77], s);
-                ShowMessage(buffer);
-            }
-
+            dsp->AlwaysShowMessage("Illegal move (in check): %s", s);
             return false;
         }
         else
@@ -309,7 +319,7 @@ VerifyMove(char *s, VerifyMove_mode iop, unsigned short *mv)
             if (iop == VERIFY_AND_TRY_MODE)
                 return true;
 
-            UpdateDisplay(xnode.f, xnode.t, 0, (short) xnode.flags);
+            dsp->UpdateDisplay(xnode.f, xnode.t, 0, (short) xnode.flags);
             GameList[GameCnt].depth = GameList[GameCnt].score = 0;
             GameList[GameCnt].nodes = 0;
             ElapsedTime(COMPUTE_AND_INIT_MODE);
@@ -334,7 +344,7 @@ VerifyMove(char *s, VerifyMove_mode iop, unsigned short *mv)
                     char buf[20];
 
                     sprintf(buf, "%s mates!\n", ColorStr[opponent]);
-                    ShowMessage(buf);
+                    dsp->ShowMessage(buf);
                     flag.mate = true;
                 }
             }
@@ -343,31 +353,20 @@ VerifyMove(char *s, VerifyMove_mode iop, unsigned short *mv)
         }
     }
 
-    if (NOT_CURSES)
-    {
-        /* Illegal move */
-        printf (CP[75], s);
-    }
-    else /* Curses. */
-    {
-        /* Illegal move */
-        sprintf(buffer, CP[76], s);
-        ShowMessage(buffer);
-    }
+    dsp->AlwaysShowMessage("Illegal move (no match): %s", s);
 
-    if (!barebones && (cnt > 1))
+    if (!XSHOGI && (cnt > 1))
     {
-        sprintf(buffer, CP[32], s);
-        ShowMessage(buffer);
+        sprintf(buffer, "Ambiguous Move %s!", s);
+        dsp->ShowMessage(buffer);
     }
 
     return false;
 }
 
 
-
 static int
-parser(char *f, int side, short *fpiece)
+parser(char *f, short *fpiece)
 {
     int c1, r1, c2, r2;
     short i, p = false;
@@ -386,17 +385,17 @@ parser(char *f, int side, short *fpiece)
 
     if (f[1] == '*' || f[1] == '\'')
     {
-        c2 = '9' - f[2];
-        r2 = 'i' - f[3];
+        c2 = COL_NUM(f[2]);
+        r2 = ROW_NUM(f[3]);
 
         return ((NO_SQUARES + *fpiece) << 8) | locn(r2, c2);
     }
     else
     {
-        c1 = '9' - f[1];
-        r1 = 'i' - f[2];
-        c2 = '9' - f[3];
-        r2 = 'i' - f[4];
+        c1 = COL_NUM(f[1]);
+        r1 = ROW_NUM(f[2]);
+        c2 = COL_NUM(f[3]);
+        r2 = ROW_NUM(f[4]);
         p = (f[5] == '+') ? 0x80 : 0;
 
         return (locn(r1, c1) << 8) | locn(r2, c2) | p;
@@ -415,7 +414,6 @@ skip()
 }
 
 
-
 void
 skipb()
 {
@@ -424,8 +422,25 @@ skipb()
 }
 
 
+void RequestInputString(char* buffer, unsigned bufsize)
+{
+    static char fmt[10];
+    int ret = snprintf(fmt, sizeof(fmt), "%%%us", bufsize);
+    if (ret < 0 ) {
+        perror("RequestInputString snprintf");
+        exit(1);
+    }
+    if (ret >= sizeof(fmt)) {
+        fprintf(stderr,
+                "Insufficient format-buffer size in %s for bufsize=%u\n",
+                __FUNCTION__, bufsize);
+        exit(1);
+    }
+    dsp->doRequestInputString(fmt, buffer);
+}
 
-void
+
+static void
 GetGame(void)
 {
     FILE *fd;
@@ -434,29 +449,15 @@ GetGame(void)
     short sq;
     short side, isp;
 
-    if (savefile[0])
-    {
+    if (savefile[0]) {
         strcpy(fname, savefile);
-    }
-    else
-    {
-        /* Enter file name */
-        ShowMessage(CP[63]);
-
-        if (NOT_CURSES)
-        {
-            scanf("%s", fname);
-        }
-        else
-        {
-            fflush(stdout);
-            scanw("%s", fname);
-        }
+    } else {
+        dsp->ShowMessage("Enter file name: ");
+        RequestInputString(fname, sizeof(fname)-1);
     }
 
-    /* shogi.000 */
     if (fname[0] == '\0')
-        strcpy(fname, CP[137]);
+        strcpy(fname, "shogi.000");
 
     if ((fd = fopen(fname, "r")) != NULL)
     {
@@ -570,10 +571,12 @@ GetGame(void)
             skipb();
             Captured[side][pawn] = atoi(InPtr);
             skip();
+#ifndef MINISHOGI
             Captured[side][lance] = atoi(InPtr);
             skip();
             Captured[side][knight] = atoi(InPtr);
             skip();
+#endif
             Captured[side][silver] = atoi(InPtr);
             skip();
             Captured[side][gold] = atoi(InPtr);
@@ -601,7 +604,7 @@ GetGame(void)
             InPtr = fname;
             skipb();
             g = &GameList[GameCnt];
-            g->gmove = parser(InPtr, side, &g->fpiece);
+            g->gmove = parser(InPtr, &g->fpiece);
             skip();
             g->score = atoi(InPtr);
             skip();
@@ -633,7 +636,7 @@ GetGame(void)
                 }
 
                 skip();
-                g->color = ((*InPtr == CP[119][0]) ? white : black);
+                g->color = ((*InPtr == 'W') ? white : black);
                 skip();
                 g->piece = (*InPtr == '+'
                             ? promoted[piece]
@@ -654,14 +657,13 @@ GetGame(void)
 
     ZeroRPT();
     InitializeStats();
-    UpdateDisplay(0, 0, 1, 0);
+    dsp->UpdateDisplay(0, 0, 1, 0);
     Sdepth = 0;
     hint = 0;
 }
 
 
-
-void
+static void
 SaveGame(void)
 {
     FILE *fd;
@@ -671,52 +673,39 @@ SaveGame(void)
     short side, piece;
     char empty[2] = "\n";
 
-    if (savefile[0])
-    {
+    if (savefile[0]) {
         strcpy(fname, savefile);
+    } else {
+        dsp->ShowMessage("Enter file name: ");
+        RequestInputString(fname, sizeof(fname)-1);
     }
-    else
-    {
-        /* Enter file name */
-        ShowMessage(CP[63]);
 
-        if (NOT_CURSES)
-        {
-            scanf("%s", fname);
-        }
-        else
-        {
-            fflush(stdout);
-            scanw("%s", fname);
-        }
-    }
-
-    if (fname[0] == '\0')        /* shogi.000 */
-        strcpy(fname, CP[137]);
+    if (fname[0] == '\0')
+        strcpy(fname, "shogi.000");
 
     if ((fd = fopen(fname, "w")) != NULL)
     {
         char *b, *w;
-        b = w = CP[74];
+        b = w = "Human   ";
 
         if (computer == white)
-            w = CP[141];
+            w = "computer";
 
         if (computer == black)
-            b = CP[141];
+            b = "computer";
 
-        fprintf(fd, CP[37], w, b, Game50,
+        fprintf(fd, "White %s Black %s %d %s\n", w, b, Game50,
                 flag.force ? "force" : "");
         fputs(empty, fd);
-        fprintf(fd, CP[111], TCflag, OperatorTime);
-        fprintf(fd, CP[117],
+        fprintf(fd, "TimeControl %d Operator Time %d\n", TCflag, OperatorTime);
+        fprintf(fd, "Black Clock %ld Moves %d\nWhite Clock %ld Moves %d\n",
                 TimeControl.clock[black], TimeControl.moves[black],
                 TimeControl.clock[white], TimeControl.moves[white]);
         fputs(empty, fd);
 
         for (i = NO_ROWS - 1; i > -1; i--)
         {
-            fprintf(fd, "%c ", 'i' - i);
+            fprintf(fd, "%c ", ROW_NAME(i));
 
             for (c = 0; c < NO_COLS; c++)
             {
@@ -751,16 +740,24 @@ SaveGame(void)
         }
 
         fputs(empty, fd);
+#ifndef MINISHOGI
         fprintf(fd, "   9 8 7 6 5 4 3 2 1\n");
         fputs(empty, fd);
         fprintf(fd, "   p  l  n  s  g  b  r  k\n");
+#else
+        fprintf(fd, "   5 4 3 2 1\n");
+        fputs(empty, fd);
+        fprintf(fd, "   p  s  g  b  r  k\n");
+#endif
 
         for (side = 0; side <= 1; side++)
         {
             fprintf(fd, "%c", (side == black) ? 'B' : 'W');
             fprintf(fd, " %2d", Captured[side][pawn]);
+#ifndef MINISHOGI
             fprintf(fd, " %2d", Captured[side][lance]);
             fprintf(fd, " %2d", Captured[side][knight]);
+#endif
             fprintf(fd, " %2d", Captured[side][silver]);
             fprintf(fd, " %2d", Captured[side][gold]);
             fprintf(fd, " %2d", Captured[side][bishop]);
@@ -770,7 +767,7 @@ SaveGame(void)
         }
 
         fputs(empty, fd);
-        fputs(CP[126], fd);
+        fputs("  move   score depth   nodes   time flags                         capture\n", fd);
 
         for (i = 1; i <= GameCnt; i++)
         {
@@ -804,24 +801,21 @@ SaveGame(void)
 
         fclose(fd);
 
-        /* Game saved */
-        ShowMessage(CP[70]);
+        dsp->ShowMessage("Game saved");
     }
     else
     {
-        /* ShowMessage("Could not open file"); */
-        ShowMessage(CP[48]);
+        dsp->ShowMessage("Could not open file");
     }
 }
 
 
-
 /*
  * GetXGame, SaveXGame and BookGame used to only be defined if
  * xshogi wasn't defined -- wonder why?
  */
 
-void
+static void
 GetXGame(void)
 {
     FILE *fd;
@@ -830,21 +824,11 @@ GetXGame(void)
     short sq;
     short side, isp;
 
-    /* Enter file name */
-    ShowMessage(CP[63]);
+    dsp->ShowMessage("Enter file name: ");
+    RequestInputString(fname, sizeof(fname)-1);
 
-    if (NOT_CURSES)
-    {
-        scanf("%s", fname);
-    }
-    else
-    {
-        fflush(stdout);
-        scanw("%s", fname);
-    }
-
-    if (fname[0] == '\0') /* XSHOGI.position.read */
-        strcpy(fname, CP[205]);
+    if (fname[0] == '\0')
+        strcpy(fname, "xshogi.position.read");
 
     if ((fd = fopen(fname, "r")) != NULL)
     {
@@ -858,7 +842,7 @@ GetXGame(void)
 #ifdef notdef
         fname[6] = '\0';
 
-        if (strcmp(fname, CP[206]))
+        if (strcmp(fname, "xshogi"))
             return;
 #endif
 
@@ -924,10 +908,12 @@ GetXGame(void)
             InPtr = fname;
             Captured[side][pawn]   = atoi(InPtr);
             skip();
+#ifndef MINISHOGI
             Captured[side][lance]  = atoi(InPtr);
             skip();
             Captured[side][knight] = atoi(InPtr);
             skip();
+#endif
             Captured[side][silver] = atoi(InPtr);
             skip();
             Captured[side][gold]   = atoi(InPtr);
@@ -952,13 +938,13 @@ GetXGame(void)
     Game50 = 1;
     ZeroRPT();
     InitializeStats();
-    UpdateDisplay(0, 0, 1, 0);
+    dsp->UpdateDisplay(0, 0, 1, 0);
     Sdepth = 0;
     hint = 0;
 }
 
 
-void
+static void
 SaveXGame(void)
 {
     FILE *fd;
@@ -967,29 +953,16 @@ SaveXGame(void)
     short sq, piece;
     short side, isp;
 
-    /* Enter file name */
-    ShowMessage(CP[63]);
-
-    if (NOT_CURSES)
-    {
-        scanf("%s", fname);
-    }
-    else
-    {
-        fflush(stdout);
-        scanw("%s", fname);
-    }
+    dsp->ShowMessage("Enter file name: ");
+    RequestInputString(fname, sizeof(fname)-1);
 
-    if (fname[0] == '\0') /* XSHOGI.position.read */
-        strcpy(fname, CP[205]);
+    if (fname[0] == '\0')
+        strcpy(fname, "xshogi.position.read");
 
     if ((fd = fopen(fname, "w")) != NULL)
     {
-        /* xshogi position file ... */
         fputs("# xshogi position file -- \n", fd);
-        /* -- empty line -- */
         fputs("\n", fd);
-        /* -- empty line -- */
         fputs("\n", fd);
 
         for (i = NO_ROWS - 1; i > -1; i--)
@@ -1021,10 +994,17 @@ SaveXGame(void)
 
         for (side = 0; side <= 1; side++)
         {
-            sprintf(fname, "%d %d %d %d %d %d %d %d\n",
+            sprintf(fname,
+#ifndef MINISHOGI
+                   "%d %d %d %d %d %d %d %d\n",
+#else
+                   "%d %d %d %d %d %d\n",
+#endif
                     Captured[side][pawn],
+#ifndef MINISHOGI
                     Captured[side][lance],
                     Captured[side][knight],
+#endif
                     Captured[side][silver],
                     Captured[side][gold],
                     Captured[side][bishop],
@@ -1044,31 +1024,19 @@ SaveXGame(void)
 }
 
 
-void
+static void
 BookSave(void)
 {
     FILE *fd;
     char fname[256], sflags[4];
     short i, j, f, t;
 
-    if (savefile[0])
-    {
+    if (savefile[0]) {
         strcpy(fname, savefile);
-    }
-    else
-    {
+    } else {
         /* Enter file name */
-        ShowMessage(CP[63]);
-
-        if (NOT_CURSES)
-        {
-            scanf("%s", fname);
-        }
-        else
-        {
-            fflush(stdout);
-            scanw("%s", fname);
-        }
+        dsp->ShowMessage("Enter file name: ");
+        RequestInputString(fname, sizeof(fname)-1);
     }
 
     if (fname[0] == '\0')
@@ -1139,18 +1107,15 @@ BookSave(void)
 
         fclose(fd);
 
-        /* Game saved */
-        ShowMessage(CP[70]);
+        dsp->ShowMessage("Game saved");
     }
     else
     {
-        /* ShowMessage("Could not open file"); */
-        ShowMessage(CP[48]);
+        dsp->ShowMessage("Could not open file");
     }
 }
 
 
-
 void
 ListGame(void)
 {
@@ -1173,13 +1138,13 @@ ListGame(void)
         dbuf[16] = '\0';
         dbuf[19] = '\0';
 
-        /* use format "CLp16.Jan01-020304B" when patchlevel is 16,
+        /* use format "CL.Jan01-020304B" when
            date is Jan 1
            time is 02:03:04
            program played white */
 
-        sprintf(fname, "CLp%s.%s%s-%s%s%s%c",
-                patchlevel, dbuf + 4, dbuf + 8, dbuf + 11, dbuf + 14,
+        sprintf(fname, "CL.%s%s-%s%s%s%c",
+                dbuf + 4, dbuf + 8, dbuf + 11, dbuf + 14,
                 dbuf + 17, ColorStr[computer][0]);
 
         /* replace space padding with 0 */
@@ -1194,14 +1159,13 @@ ListGame(void)
 
     if (!fd)
     {
-        printf(CP[219], fname);
+        printf("Open failure for file: %s", fname);
         exit(1);
     }
 
-    /* fprintf(fd, "gnushogi game %d\n", u); */
-    fprintf(fd, CP[161], version, patchlevel);
-    fputs(CP[10], fd);
-    fputs(CP[11], fd);
+    fprintf(fd, "gnushogi %s game\n", PACKAGE_VERSION);
+    fputs("         score  depth   nodes  time         ", fd);
+    fputs("         score  depth   nodes  time\n", fd);
 
     for (i = 1; i <= GameCnt; i++)
     {
@@ -1248,9 +1212,9 @@ ListGame(void)
 
     if (GameList[GameCnt].flags & draw)
     {
-        fprintf(fd, CP[54], DRAW);
+        fprintf(fd, "Draw %s\n", DRAW);
 
-        if (DRAW == CP[101])
+        if (DRAW == DRAW_REPETITION)
         {
             short j;
 
@@ -1279,8 +1243,7 @@ ListGame(void)
 }
 
 
-
-void
+static void
 FlagMove(char c)
 {
     switch(c)
@@ -1302,13 +1265,11 @@ FlagMove(char c)
 }
 
 
-
-
 /*
  * Undo the most recent half-move.
  */
 
-void
+static void
 Undo(void)
 {
     short f, t;
@@ -1357,69 +1318,15 @@ Undo(void)
     flag.mate = false;
     Sdepth = 0;
     player = player ^ 1;
-    ShowSidetoMove();
-    UpdateDisplay(0, 0, 1, 0);
+    dsp->ShowSidetoMove();
+    dsp->UpdateDisplay(0, 0, 1, 0);
 
     if (flag.regularstart)
         Book = false;
 }
 
 
-
-void
-FlagString(unsigned short flags, char *s)
-{
-    short l, piece;
-    *s = '\0';
-
-    if (flags & promote)
-        strcat(s, " promote");
-
-    if (flags & dropmask)
-        strcat(s, " drop:");
-
-    if ((piece = (flags & pmask)))
-    {
-        l = strlen(s);
-
-        if (is_promoted[piece])
-            s[l++] = '+';
-
-        s[l++] = pxx[piece];
-        s[l] = '\0';
-    }
-
-    if (flags & capture)
-        strcat(s, " capture");
-
-    if (flags & exact)
-        strcat(s, " exact");
-
-    if (flags & tesuji)
-        strcat(s, " tesuji");
-
-    if (flags & check)
-        strcat(s, " check");
-
-    if (flags & draw)
-        strcat(s, " draw");
-
-    if (flags & stupid)
-        strcat(s, " stupid");
-
-    if (flags & questionable)
-        strcat(s, " questionable");
-
-    if (flags & kingattack)
-        strcat(s, " kingattack");
-
-    if (flags & book)
-        strcat(s, " book");
-}
-
-
-
-void
+static void
 TestSpeed(void(*f)(short side, short ply,
                    short in_check, short blockable),
           unsigned j)
@@ -1429,7 +1336,7 @@ TestSpeed(void(*f)(short side, short ply,
 #endif
 
     unsigned i;
-    long cnt, rate, t1, t2;
+    long cnt, t1, t2;
 
 #ifdef HAVE_GETTIMEOFDAY
     struct timeval tv;
@@ -1469,26 +1376,15 @@ TestSpeed(void(*f)(short side, short ply,
     else
         et = 1;
 
-    rate = (((et) ? ((cnt * 100) / et) : 0));
-
-#ifdef DYNAMIC_ZNODES
-    if (rate > 0)
-        znodes = rate;
-#endif
-
-    if (NOT_CURSES)
-        printf(CP[91], cnt, rate);
-    else
-        ShowNodeCnt(cnt);
+    dsp->ShowNodeCnt(cnt);
 }
 
 
-
-void
+static void
 TestPSpeed(short(*f) (short side), unsigned j)
 {
-    short i;
-    long cnt, rate, t1, t2;
+    unsigned i;
+    long cnt, t1, t2;
 #ifdef HAVE_GETTIMEOFDAY
     struct timeval tv;
 #endif
@@ -1517,32 +1413,22 @@ TestPSpeed(short(*f) (short side), unsigned j)
     else
         et = 1;
 
-    rate = (et) ? ((cnt * 100) / et) : 0;
-
-    /* printf("Nodes= %ld Nodes/sec= %ld\n", cnt, rate); */
-
-    if (NOT_CURSES)
-        printf(CP[91], cnt, rate);
-    else
-        ShowNodeCnt(cnt);
+    dsp->ShowNodeCnt(cnt);
 }
 
 
-
-void
-SetOppTime(char *s)
+static void
+SetOppTime(char *time)
 {
-    char *time;
-    int m, t, sec;
+    int m, t;
 
-    sec = 0;
-    time = &s[strlen(CP[228])];
     t = (int)strtol(time, &time, 10);
 
     if (*time == ':')
     {
         time++;
-        sec = (int)strtol(time, &time, 10);
+       /* FIXME: sec is parsed but ignored */
+        (void)strtol(time, &time, 10);
     }
 
     m = (int)strtol(time, &time, 10);
@@ -1563,21 +1449,18 @@ SetOppTime(char *s)
 }
 
 
-
-void
-SetMachineTime(char *s)
+static void
+SetMachineTime(char *time)
 {
-    char *time;
-    int m, t, sec;
+    int m, t;
 
-    time = &s[strlen(CP[197])];
-    sec = 0;
     t = (int)strtol(time, &time, 10);
 
     if (*time == ':')
     {
         time++;
-        sec = (int)strtol(time, &time, 10);
+       /* FIXME: sec is parsed but ignored */
+        (void)strtol(time, &time, 10);
     }
 
     m = (int)strtol(time, &time, 10);
@@ -1598,25 +1481,22 @@ SetMachineTime(char *s)
 }
 
 
-
-
-
 /* FIXME!  This is truly the function from hell! */
 
 /*
  * Process the user's command. If easy mode is OFF (the computer is thinking
  * on opponents time) and the program is out of book, then make the 'hint'
  * move on the board and call SelectMove() to find a response. The user
- * terminates the search by entering ^C (quit siqnal) before entering a
- * command. If the opponent does not make the hint move, then set Sdepth to
- * zero.
+ * terminates the search by entering a command. If the opponent does not make
+ * the hint move, then set Sdepth to zero.
  */
 
 void
 InputCommand(char *command)
 {
-    int eof = 0;
+#ifdef QUIETBACKGROUND
     short have_shown_prompt = false;
+#endif
     short ok, done, is_move = false;
     unsigned short mv;
     char s[80], sx[80];
@@ -1642,10 +1522,8 @@ InputCommand(char *command)
         algbr((short) hint >> 8, (short) hint & 0xff, false);
         strcpy(s, mvstr[0]);
 
-#if !defined NOPOST
         if (flag.post)
-            GiveHint();
-#endif
+            dsp->GiveHint();
 
         /* do the hint move */
         if (VerifyMove(s, VERIFY_AND_TRY_MODE, &mv))
@@ -1653,16 +1531,7 @@ InputCommand(char *command)
             Sdepth = 0;
 
 #ifdef QUIETBACKGROUND
-            if (NOT_CURSES)
-            {
-                PromptForMove();
-            }
-            else
-            {
-                ShowSidetoMove();
-                ShowPrompt();
-            }
-
+            dsp->ShowPrompt();
             have_shown_prompt = true;
 #endif /* QUIETBACKGROUND */
 
@@ -1709,15 +1578,7 @@ InputCommand(char *command)
         {
 #endif /* QUIETBACKGROUND */
 
-            if (NOT_CURSES)
-            {
-                PromptForMove();
-            }
-            else
-            {
-                ShowSidetoMove();
-                ShowPrompt();
-            }
+            dsp->ShowPrompt();
 
 #ifdef QUIETBACKGROUND
         }
@@ -1725,36 +1586,20 @@ InputCommand(char *command)
         have_shown_prompt = false;
 #endif /* QUIETBACKGROUND */
 
-        if (command == NULL)
-        {
-            if (NOT_CURSES)
-            {
-                s[0] = sx[0] = '\0';
-
-                while(!sx[0])
-                    (void)fgets(sx, 80, stdin);
-            }
-            else
-            {
-                fflush(stdout);
-                eof = (getstr(sx) == ERR);
-            }
-        }
-        else
-        {
+        if (command == NULL) {
+            int eof = dsp->GetString(sx);
+            if (eof)
+                dsp->ExitShogi();
+        } else {
             strcpy(sx, command);
             done = true;
         }
 
-        sscanf(sx, "%s", s);
-
-        if (eof)
-            ExitShogi();
-
-        if (s[0] == '\0')
+        /* extract first word */
+        if (sscanf(sx, "%s", s) < 1)
             continue;
 
-        if (strcmp(s, CP[131]) == 0)   /* bd -- display board */
+        if (strcmp(s, "bd") == 0)   /* bd -- display board */
         {
             /* FIXME: Hack alert! */
             short old_xshogi = XSHOGI;
@@ -1762,45 +1607,61 @@ InputCommand(char *command)
             if (old_xshogi)
                 display_type = DISPLAY_RAW;
 
-            ClearScreen();
-            UpdateDisplay(0, 0, 1, 0);
+            dsp->ClearScreen();
+            dsp->UpdateDisplay(0, 0, 1, 0);
 
             if (old_xshogi)
                 display_type = DISPLAY_X;
         }
         else if (strcmp(s, "post") == 0)
         {
-            flag.post = !flag.post;
+            flag.post = (xboard ? 1 : !flag.post);
+        }
+        else if (strcmp(s, "nopost") == 0)
+        {
+            flag.post = 0;
         }
-        else if (strcmp(s, CP[129]) == 0)
+        else if (strcmp(s, "alg") == 0 ||
+                 strcmp(s, "accepted") == 0 || strcmp(s, "rejected") == 0 ||
+                 strcmp(s, "variant") == 0 || strcmp(s, "computer") == 0)
         {
-            /* noop */ ; /* alg */
+            /* noop */ ;
         }
-        else if ((strcmp(s, CP[180]) == 0)
-                 || (strcmp(s, CP[216]) == 0))  /* quit exit */
+        else if ((strcmp(s, "quit") == 0)
+                 || (strcmp(s, "exit") == 0))
         {
             flag.quit = true;
         }
-#if !defined NOPOST
-        else if (strcmp(s, CP[178]) == 0)  /* post */
+        else if (strcmp(s, "xboard") == 0)
         {
-            flag.post = !flag.post;
+            xboard = true;
+            strcpy(ColorStr[0], "White");
+            strcpy(ColorStr[1], "Black");
         }
+        else if (strcmp(s, "protover") == 0)
+        {
+            printf("feature myname=\"GNU %sShogi %s\" variants=\"%sshogi\" debug=1 setboard=0 sigint=0 done=1\n",
+#ifdef MINISHOGI
+                                       "mini", PACKAGE_VERSION, "5x5+5_"
+#else
+                                         "",   PACKAGE_VERSION, ""
 #endif
-        else if ((strcmp(s, CP[191]) == 0)
-                 || (strcmp(s, CP[154]) == 0))  /* set edit */
+                  );
+        }
+        else if ((strcmp(s, "set") == 0)
+                 || (strcmp(s, "edit") == 0))
         {
-            EditBoard();
+            dsp->EditBoard();
         }
-        else if (NOT_CURSES && (strcmp(s, CP[190]) == 0))  /* setup */
+        else if (strcmp(s, "setup") == 0)
         {
-            SetupBoard();
+            dsp->SetupBoard();
         }
-        else if (strcmp(s, CP[156]) == 0)  /* first */
+        else if (strcmp(s, "first") == 0)
         {
             ok = true;
         }
-        else if (strcmp(s, CP[162]) == 0)  /* go */
+        else if (strcmp(s, "go") == 0)
         {
             ok = true;
             flag.force = false;
@@ -1816,15 +1677,15 @@ InputCommand(char *command)
                 opponent = white;
             }
         }
-        else if (strcmp(s, CP[166]) == 0)  /* help */
+        else if (strcmp(s, "help") == 0)
         {
-            help();
+            dsp->help();
         }
-        else if (strcmp(s, CP[221]) == 0)  /* material */
+        else if (strcmp(s, "material") == 0)
         {
             flag.material = !flag.material;
         }
-        else if (strcmp(s, CP[157]) == 0)  /* force */
+        else if (strcmp(s, "force") == 0)
         {
             if (XSHOGI)
             {
@@ -1837,61 +1698,65 @@ InputCommand(char *command)
                 flag.bothsides = false;
             }
         }
-        else if (strcmp(s, CP[134]) == 0)  /* book */
+        else if (strcmp(s, "book") == 0)
         {
             Book = Book ? 0 : BOOKFAIL;
         }
-        else if (strcmp(s, CP[172]) == 0)  /* new */
+        else if (strcmp(s, "new") == 0)
         {
             NewGame();
-            UpdateDisplay(0, 0, 1, 0);
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (strcmp(s, CP[171]) == 0)  /* list */
+        else if (strcmp(s, "list") == 0)
         {
             ListGame();
         }
-        else if ((strcmp(s, CP[169]) == 0)
-                 || (strcmp(s, CP[217]) == 0))  /* level clock */
+        else if (strcmp(s, "level") == 0)
         {
-            SelectLevel(sx);
+            dsp->SelectLevel(sx + strlen("level"));
         }
-        else if (strcmp(s, CP[165]) == 0)  /* hash */
+        else if (strcmp(s, "clock") == 0)
+        {
+            dsp->SelectLevel(sx + strlen("clock"));
+        }
+        else if (strcmp(s, "hash") == 0)
         {
             flag.hash = !flag.hash;
         }
-        else if (strcmp(s, CP[227]) == 0)  /* gamein */
+        else if (strcmp(s, "gamein") == 0)
         {
             flag.gamein = !flag.gamein;
         }
-        else if (strcmp(s, CP[226]) == 0)  /* beep */
+        else if (strcmp(s, "beep") == 0)
         {
             flag.beep = !flag.beep;
         }
-        else if (strcmp(s, CP[197]) == 0)  /* time */
+        else if (strcmp(s, "time") == 0)
         {
-            SetMachineTime(sx);
+            SetMachineTime(sx + strlen("time"));
         }
-        else if (strcmp(s, CP[228]) == 0)  /* otime */
+        else if ((strcmp(s, "otime") == 0) ||
+                 (xboard && (strcmp(s, "otim")) == 0))
         {
-            SetOppTime(sx);
+            SetOppTime(sx + strlen("otime"));
         }
-        else if (strcmp(s, CP[33]) == 0)   /* Awindow */
+        else if (strcmp(s, "Awindow") == 0)
         {
-            ChangeAlphaWindow();
+            dsp->ChangeAlphaWindow();
         }
-        else if (strcmp(s, CP[39]) == 0)   /* Bwindow */
+        else if (strcmp(s, "Bwindow") == 0)
         {
-            ChangeBetaWindow();
+            dsp->ChangeBetaWindow();
         }
-        else if (strcmp(s, CP[183]) == 0)  /* rcptr */
+        else if (strcmp(s, "rcptr") == 0)
         {
             flag.rcptr = !flag.rcptr;
         }
-        else if (strcmp(s, CP[168]) == 0)  /* hint */
+        else if (strcmp(s, "hint") == 0)
         {
-            GiveHint();
+            dsp->GiveHint();
         }
-        else if (strcmp(s, CP[135]) == 0)  /* both */
+        else if (strcmp(s, "both") == 0)
         {
             flag.bothsides = !flag.bothsides;
             flag.force = false;
@@ -1900,13 +1765,13 @@ InputCommand(char *command)
             SelectMove(opponent, FOREGROUND_MODE);
             ok = true;
         }
-        else if (strcmp(s, CP[185]) == 0)  /* reverse */
+        else if (strcmp(s, "reverse") == 0)
         {
             flag.reverse = !flag.reverse;
-            ClearScreen();
-            UpdateDisplay(0, 0, 1, 0);
+            dsp->ClearScreen();
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (strcmp(s, CP[195]) == 0)  /* switch */
+        else if (strcmp(s, "switch") == 0)
         {
             computer = computer ^ 1;
             opponent = opponent ^ 1;
@@ -1914,8 +1779,9 @@ InputCommand(char *command)
             flag.force = false;
             Sdepth = 0;
             ok = true;
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (strcmp(s, CP[203]) == 0)  /* black */
+        else if (xboard ? strcmp(s, "white") == 0 : strcmp(s, "black") == 0)
         {
             computer = white;
             opponent = black;
@@ -1927,7 +1793,7 @@ InputCommand(char *command)
              * ok = true; don't automatically start with black command
              */
         }
-        else if (strcmp(s, CP[133]) == 0)  /* white */
+        else if (xboard ? strcmp(s, "black") == 0 : strcmp(s, "white") == 0)
         {
             computer = black;
             opponent = white;
@@ -1939,25 +1805,25 @@ InputCommand(char *command)
              * ok = true; don't automatically start with white command
              */
         }
-        else if (strcmp(s, CP[201]) == 0 && GameCnt > 0)   /* undo */
+        else if (strcmp(s, "undo") == 0 && GameCnt > 0)
         {
             Undo();
         }
-        else if (strcmp(s, CP[184]) == 0 && GameCnt > 1)   /* remove */
+        else if (strcmp(s, "remove") == 0 && GameCnt > 1)
         {
             Undo();
             Undo();
         }
         /* CHECKME: are these next three correct? */
-        else if (!XSHOGI && strcmp(s, CP[207]) == 0)  /* xget */
+        else if (!XSHOGI && strcmp(s, "xget") == 0)
         {
             GetXGame();
         }
-        else if (!XSHOGI && strcmp(s, "xsave") == 0)        /* xsave */
+        else if (!XSHOGI && strcmp(s, "xsave") == 0)
         {
             SaveXGame();
         }
-        else if (!XSHOGI && strcmp(s, "bsave") == 0)        /* bsave */
+        else if (!XSHOGI && strcmp(s, "bsave") == 0)
         {
             BookSave();
         }
@@ -1972,62 +1838,66 @@ InputCommand(char *command)
         {
             FlagMove(*s);
         }
-        else if (strcmp(s, CP[160]) == 0)    /* get */
+        else if (strcmp(s, "get") == 0)
         {
             GetGame();
         }
-        else if (strcmp(s, CP[189]) == 0)    /* save */
+        else if (strcmp(s, "save") == 0)
         {
             SaveGame();
         }
-        else if (strcmp(s, CP[151]) == 0)    /* depth */
+        else if (strcmp(s, "depth") == 0)
+        {
+            dsp->ChangeSearchDepth(sx + strlen("depth"));
+        }
+        else if (strcmp(s, "sd") == 0)
         {
-            ChangeSearchDepth();
+            dsp->ChangeSearchDepth(sx + strlen("sd"));
         }
-        else if (strcmp(s, CP[164]) == 0)    /* hashdepth */
+        else if (strcmp(s, "hashdepth") == 0)
         {
-            ChangeHashDepth();
+            dsp->ChangeHashDepth();
         }
-        else if (strcmp(s, CP[182]) == 0)    /* random */
+        else if (strcmp(s, "random") == 0)
         {
             dither = DITHER;
         }
-        else if (strcmp(s, CP[229]) == 0)    /* hard */
+        else if (strcmp(s, "hard") == 0)
         {
             flag.easy = false;
         }
-        else if (strcmp(s, CP[152]) == 0)    /* easy */
+        else if (strcmp(s, "easy") == 0)
         {
             flag.easy = !flag.easy;
         }
-        else if (strcmp(s, CP[230]) == 0)    /* tsume */
+        else if (strcmp(s, "tsume") == 0)
         {
             flag.tsume = !flag.tsume;
         }
-        else if (strcmp(s, CP[143]) == 0)    /* contempt */
+        else if (strcmp(s, "contempt") == 0)
         {
-            SetContempt();
+            dsp->SetContempt();
         }
-        else if (strcmp(s, CP[209]) == 0)    /* xwndw */
+        else if (strcmp(s, "xwndw") == 0)
         {
-            ChangeXwindow();
+            dsp->ChangeXwindow();
         }
-        else if (strcmp(s, CP[186]) == 0)    /* rv */
+        else if (strcmp(s, "rv") == 0)
         {
             flag.rv = !flag.rv;
-            UpdateDisplay(0, 0, 1, 0);
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (strcmp(s, CP[145]) == 0)    /* coords */
+        else if (strcmp(s, "coords") == 0)
         {
             flag.coords = !flag.coords;
-            UpdateDisplay(0, 0, 1, 0);
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (strcmp(s, CP[193]) == 0)    /* stars */
+        else if (strcmp(s, "stars") == 0)
         {
             flag.stars = !flag.stars;
-            UpdateDisplay(0, 0, 1, 0);
+            dsp->UpdateDisplay(0, 0, 1, 0);
         }
-        else if (!XSHOGI && strcmp(s, CP[5]) == 0)          /* moves */
+        else if (!XSHOGI && strcmp(s, "moves") == 0)
         {
             short temp;
 
@@ -2043,44 +1913,44 @@ InputCommand(char *command)
 #endif
                 SwagHt = 0;
 
-            ShowMessage(CP[108]);  /* test movelist */
+            dsp->ShowMessage("Testing MoveList Speed");
             temp = generate_move_flags;
             generate_move_flags = true;
             TestSpeed(MoveList, 1);
             generate_move_flags = temp;
-            ShowMessage(CP[107]);  /* test capturelist */
+            dsp->ShowMessage("Testing CaptureList Speed");
             TestSpeed(CaptureList, 1);
-            ShowMessage(CP[85]);   /* test score position */
+            dsp->ShowMessage("Testing Eval Speed");
             ExaminePosition(opponent);
             TestPSpeed(ScorePosition, 1);
         }
-        else if (!XSHOGI && strcmp(s, CP[196]) == 0)    /* test */
+        else if (!XSHOGI && strcmp(s, "test") == 0)
         {
 #ifdef SLOW_CPU
-            ShowMessage(CP[108]); /* test movelist */
+            dsp->ShowMessage("Testing MoveList Speed");
             TestSpeed(MoveList, 2000);
-            ShowMessage(CP[107]); /* test capturelist */
+            dsp->ShowMessage("Testing CaptureList Speed");
             TestSpeed(CaptureList, 3000);
-            ShowMessage(CP[85]); /* test score position */
+            dsp->ShowMessage("Testing Eval Speed");
             ExaminePosition(opponent);
             TestPSpeed(ScorePosition, 1500);
 #else
-            ShowMessage(CP[108]); /* test movelist */
+            dsp->ShowMessage("Testing MoveList Speed");
             TestSpeed(MoveList, 20000);
-            ShowMessage(CP[107]); /* test capturelist */
+            dsp->ShowMessage("Testing CaptureList Speed");
             TestSpeed(CaptureList, 30000);
-            ShowMessage(CP[85]); /* test score position */
+            dsp->ShowMessage("Testing Eval Speed");
             ExaminePosition(opponent);
             TestPSpeed(ScorePosition, 15000);
 #endif
         }
-        else if (!XSHOGI && strcmp(s, CP[179]) == 0) /* p */
+        else if (!XSHOGI && strcmp(s, "p") == 0)
         {
-            ShowPostnValues();
+            dsp->ShowPostnValues();
         }
-        else if (!XSHOGI && strcmp(s, CP[148]) == 0)    /* debug */
+        else if (!XSHOGI && strcmp(s, "debug") == 0)
         {
-            DoDebug();
+            dsp->DoDebug();
         }
         else
         {
@@ -2095,8 +1965,8 @@ InputCommand(char *command)
 
                 if (rpt >= 3)
                 {
-                    DRAW = CP[101];
-                    ShowMessage(DRAW);
+                    DRAW = DRAW_REPETITION;
+                    dsp->ShowMessage(DRAW);
                     GameList[GameCnt].flags |= draw;
 
                         flag.mate = true;
@@ -2127,50 +1997,5 @@ InputCommand(char *command)
             printf("%d. %s %ld\n",
                    ++mycnt2, s, TimeControl.clock[player] * 10);
         }
-
-#ifdef notdef /* optional pass best line to frontend with move */
-#  if !defined NOPOST
-
-        if (flag.post && !flag.mate)
-        {
-            int i;
-
-            printf(" %6d ", MSCORE);
-
-            for (i = 1; MV[i] > 0; i++)
-            {
-                algbr((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
-                printf("%5s ", mvstr[0]);
-            }
-        }
-#  endif
-        printf("\n");
-#endif
-    }
-
-    signal(SIGUSR1, TerminateSearch);
-}
-
-
-
-
-void
-SetTimeControl(void)
-{
-    if (TCflag)
-    {
-        TimeControl.moves[black] = TimeControl.moves[white] = TCmoves;
-        TimeControl.clock[black] += 6000L * TCminutes + TCseconds * 100;
-        TimeControl.clock[white] += 6000L * TCminutes + TCseconds * 100;
     }
-    else
-    {
-        TimeControl.moves[black] = TimeControl.moves[white] = 0;
-        TimeControl.clock[black] = TimeControl.clock[white] = 0;
-    }
-
-    flag.onemove = (TCmoves == 1);
-    et = 0;
-    ElapsedTime(COMPUTE_AND_INIT_MODE);
 }
-