Drop non-curses support from Curses_ElapsedTime.
[gnushogi.git] / gnushogi / cursesdsp.c
index 692ffa8..7b37fc6 100644 (file)
  *
  * This file is part of GNU SHOGI.
  *
- * GNU Shogi is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
+ * GNU Shogi is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 3 of the License,
+ * or (at your option) any later version.
  *
- * GNU Shogi is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with GNU Shogi; see the file COPYING.  If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with GNU Shogi; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ * ----------------------------------------------------------------------
  */
 
 
 #include <ctype.h>
 #include <signal.h>
+#include <stdio.h>
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include "gnushogi.h"
 #include "cursesdsp.h"
 
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if HAVE_SYS_FILIO_H
+/* Definition of FIONREAD */
+#include <sys/filio.h>
+#endif
+
+#if HAVE_ERRNO_H
+/* Definition of errno(). */
+#include <errno.h>
+#endif
+
 #define FLUSH_SCANW fflush(stdout), scanw
 
 int mycnt1, mycnt2;
 
 #define TAB (58)
 
-#define VIR_C(s)  ((flag.reverse) ? (8 - column(s)) : column(s))
-#define VIR_R(s)  ((flag.reverse) ? (8 - row(s)) : row(s))
+#define VIR_C(s)  ((flag.reverse) ? (NO_COLS - 1 - column(s)) : column(s))
+#define VIR_R(s)  ((flag.reverse) ? (NO_ROWS - 1 - row(s)) : row(s))
 
 unsigned short MV[MAXDEPTH];
 int MSCORE;
@@ -58,13 +74,14 @@ char *DRAW;
 /* FIXME: change this name, puh-leeze! */
 
 static void UpdateCatched(void);
-
+static void DrawPiece(short sq);
+static void ShowScore(short score);
 
 /****************************************
  * Trivial output functions.
  ****************************************/
 
-void
+static void
 ClearEoln(void)
 {
     clrtoeol();
@@ -80,7 +97,7 @@ Curses_ClearScreen(void)
 }
 
 
-void
+static void
 ClearMessage(void)
 {
     gotoXY(TAB, 6);
@@ -88,8 +105,7 @@ ClearMessage(void)
 }
 
 
-
-void
+static void
 gotoXY(short x, short y)
 {
     move(y - 1, x - 1);
@@ -149,7 +165,46 @@ Curses_ShowMessage(char *s)
 
 
 void
-ShowNodeCnt(long NodeCnt)
+Curses_AlwaysShowMessage(const char *format, ...)
+{
+    static char buffer[60];
+    va_list ap;
+    va_start(ap, format);
+    vsnprintf(buffer, sizeof(buffer), format, ap);
+    Curses_ShowMessage(buffer);
+    va_end(ap);
+}
+
+
+void
+Curses_Printf(const char *format, ...)
+{
+    static char buffer[60];
+    va_list ap;
+    va_start(ap, format);
+    vsnprintf(buffer, sizeof(buffer), format, ap);
+    printw("%s", buffer);
+    va_end(ap);
+}
+
+
+void
+Curses_doRequestInputString(const char* fmt, char* buffer)
+{
+    FLUSH_SCANW(fmt, buffer);
+}
+
+
+int
+Curses_GetString(char* sx)
+{
+    fflush(stdout);
+    return (getstr(sx) == ERR);
+}
+
+
+void
+Curses_ShowNodeCnt(long NodeCnt)
 {
     gotoXY(TAB, 22);
     /* printw(CP[90], NodeCnt, (et > 100) ? NodeCnt / (et / 100) : 0); */
@@ -164,7 +219,7 @@ Curses_ShowPatternCount(short side, short n)
 {
     if (flag.post)
     {
-        gotoXY(TAB + 10 + 3 * side, 20);
+        gotoXY(TAB + 10 + 3 * side, 20);         /* CHECKME */
 
         if (n >= 0)
             printw("%3d", n);
@@ -174,19 +229,20 @@ Curses_ShowPatternCount(short side, short n)
 }
 
 
-void
+static void
 ShowPlayers(void)
 {
-    gotoXY(5, ((flag.reverse) ? 23 : 2));
+    gotoXY(5, ((flag.reverse) ? (5 + 2*NO_ROWS) : 2));
     printw("%s", (computer == white) ? CP[218] : CP[74]);
-    gotoXY(5, ((flag.reverse) ? 2 : 23));
+    gotoXY(5, ((flag.reverse) ? 2 : (5 + 2*NO_ROWS)));
     printw("%s", (computer == black) ? CP[218] : CP[74]);
 }
 
 
-void
-ShowPrompt(void)
+static void
+Curses_ShowPrompt(void)
 {
+    Curses_ShowSidetoMove();
     gotoXY(TAB, 17);
     printw(CP[121]);     /* Your move is? */
     ClearEoln();
@@ -244,7 +300,7 @@ Curses_ShowResults(short score, unsigned short *bstline, char ch)
 }
 
 
-void
+static void
 ShowScore(short score)
 {
     gotoXY(TAB, 5);
@@ -271,12 +327,10 @@ Curses_ShowStage(void)
     ClearEoln();
 }
 
-
 /****************************************
  * End of trivial output routines.
  ****************************************/
 
-
 void
 Curses_Initialize(void)
 {
@@ -303,7 +357,6 @@ Curses_ExitShogi(void)
 }
 
 
-
 void
 Curses_Die(int sig)
 {
@@ -323,7 +376,6 @@ Curses_Die(int sig)
 }
 
 
-
 void
 Curses_TerminateSearch(int sig)
 {
@@ -340,7 +392,6 @@ Curses_TerminateSearch(int sig)
 }
 
 
-
 void
 Curses_help(void)
 {
@@ -500,8 +551,8 @@ Curses_EditBoard(void)
         }
         else
         {
-            c = '9' - s[1];
-            r = 'i' - s[2];
+            c = COL_NAME(s[1]);
+            r = ROW_NAME(s[2]);
         }
 
         if ((c >= 0) && (c < NO_COLS) && (r >= 0) && (r < NO_ROWS))
@@ -539,7 +590,6 @@ Curses_EditBoard(void)
 }
 
 
-
 static void 
 UpdateCatched()
 {
@@ -591,7 +641,6 @@ UpdateCatched()
 }
 
 
-
 void
 Curses_SearchStartStuff(short side)
 {
@@ -600,7 +649,7 @@ Curses_SearchStartStuff(short side)
     signal(SIGINT, Curses_TerminateSearch);
     signal(SIGQUIT, Curses_TerminateSearch);
 
-    for (i = 4; i < 14; i++)
+    for (i = 4; i < 14; i++)                     /* CHECKME */
     {
         gotoXY(TAB, i);
         ClearEoln();
@@ -608,7 +657,6 @@ Curses_SearchStartStuff(short side)
 }
 
 
-
 void
 Curses_OutputMove(void)
 {
@@ -674,8 +722,7 @@ Curses_OutputMove(void)
 }
 
 
-
-void
+static void
 UpdateClocks(void)
 {
     short m, s;
@@ -713,8 +760,7 @@ UpdateClocks(void)
 }
 
 
-
-void
+static void
 DrawPiece(short sq)
 {
     char y;
@@ -747,23 +793,20 @@ DrawPiece(short sq)
         y = pxx[(int)piece];
     }
 
-    gotoXY(8 + 5 * VIR_C(sq), 4 + 2 * (8 - VIR_R(sq)));
+    gotoXY(8 + 5 * VIR_C(sq), 4 + 2 * ((NO_ROWS - 1) - VIR_R(sq)));
     printw("%c%c%c%c", l, p, y, r);
 }
 
 
-
-
 /*
  * Curses_ShowPostnValue(): must have called ExaminePosition() first
  */
-
 void
 Curses_ShowPostnValue(short sq)
 {
     short score;
 
-    gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));
+    gotoXY(4 + 5 * VIR_C(sq), 5 + 2 * (7 - VIR_R(sq)));        /* CHECKME */
     score = ScorePosition(color[sq]);
 
     if (color[sq] != neutral)
@@ -783,7 +826,6 @@ Curses_ShowPostnValue(short sq)
 }
 
 
-
 void
 Curses_ShowPostnValues(void)
 {
@@ -804,11 +846,11 @@ Curses_ShowPostnValues(void)
 }
 
 
-
 void
 Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
 {
     short i, sq, z;
+    int j;
 
     if (redraw)
     {
@@ -818,31 +860,38 @@ Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
         i = 2;
         gotoXY(3, ++i);
 
-        printw("    +----+----+----+----+----+----+----+----+----+");
+        printw("    +");
+       for (j=0; j<NO_COLS; j++)
+           printw("----+");
 
-        while (i < 20)
+        while (i <= 1 + 2*NO_ROWS)
         {
             gotoXY(1, ++i);
 
             if (flag.reverse)
                 z = (i / 2) - 1;
             else
-                z = 11 - ((i + 1) / 2);
+                z = NO_ROWS + 2 - ((i + 1) / 2);
 
-            printw("    %c |    |    |    |    |    |"
-                   "    |    |    |    |", 'a' + 9 - z);
+            printw("    %c |", ROW_NAME(z+1));
+           for (j=0; j<NO_COLS; j++)
+               printw("    |");
 
             gotoXY(3, ++i);
 
-            if (i < 20)
+            if (i < 2 + 2*NO_ROWS)
             {
-                printw("    +----+----+----+----+----+----+----+----+----+");
+               printw("    +");
+               for (j=0; j<NO_COLS; j++)
+                   printw("----+");
             }
         }
 
-        printw("    +----+----+----+----+----+----+----+----+----+");
+       printw("    +");
+       for (j=0; j<NO_COLS; j++)
+           printw("----+");
 
-        gotoXY(3, 22);
+        gotoXY(3, 4 + 2*NO_ROWS);
         printw("    ");
 
         if (flag.reverse)
@@ -908,9 +957,6 @@ Curses_UpdateDisplay(short f, short t, short redraw, short isspec)
 }
 
 
-extern char *InPtr;
-
-
 void
 Curses_ChangeAlphaWindow(void)
 {
@@ -921,7 +967,6 @@ Curses_ChangeAlphaWindow(void)
 }
 
 
-
 void
 Curses_ChangeBetaWindow(void)
 {
@@ -932,7 +977,6 @@ Curses_ChangeBetaWindow(void)
 }
 
 
-
 void
 Curses_GiveHint(void)
 {
@@ -952,7 +996,6 @@ Curses_GiveHint(void)
 }
 
 
-
 void
 Curses_ChangeSearchDepth(void)
 {
@@ -980,7 +1023,6 @@ Curses_SetContempt(void)
 }
 
 
-
 void
 Curses_ChangeXwindow(void)
 {
@@ -989,7 +1031,6 @@ Curses_ChangeXwindow(void)
 }
 
 
-
 void
 Curses_SelectLevel(char *sx)
 {
@@ -1100,7 +1141,6 @@ Curses_SelectLevel(char *sx)
 }
 
 
-
 void
 Curses_DoDebug(void)
 {
@@ -1148,7 +1188,6 @@ Curses_DoDebug(void)
 }
 
 
-
 void
 Curses_DoTable(short table[NO_SQUARES])
 {
@@ -1163,4 +1202,92 @@ Curses_DoTable(short table[NO_SQUARES])
 } 
 
 
+/*
+ * Determine the time that has passed since the search was started. If the
+ * elapsed time exceeds the target(ResponseTime + ExtraTime) then set timeout
+ * to true which will terminate the search.
+ * iop = COMPUTE_MODE calculate et, bump ETnodes
+ * iop = COMPUTE_AND_INIT_MODE calculate et, set timeout if time exceeded,
+ *     set reference time
+ */
+void
+Curses_ElapsedTime(ElapsedTime_mode iop)
+{
+    long current_time;
+    int  i;
+    int  nchar;
+
+#ifdef HAVE_GETTIMEOFDAY
+    struct timeval tv;
+#endif
+
+    if ((i = ioctl((int) 0, FIONREAD, &nchar)))
+    {
+        perror("FIONREAD");
+        fprintf(stderr,
+                "You probably have a non-ANSI <ioctl.h>; "
+                "see README. %d %d %x\n",
+                i, errno, FIONREAD);
+        exit(1);
+    }
+
+    if (nchar)
+    {
+        if (!flag.timeout)
+            flag.back = true;
+
+        flag.bothsides = false;
+    }
+
+#ifdef HAVE_GETTIMEOFDAY
+    gettimeofday(&tv, NULL);
+    current_time = tv.tv_sec*100 + (tv.tv_usec/10000);
+#else
+    et = ((current_time = time((long *) 0)) - time0) * 100;
+#endif
+
+#ifdef INTERRUPT_TEST
+    if (iop == INIT_INTERRUPT_MODE)
+    {
+        itime0 = current_time;
+    }
+    else if (iop == COMPUTE_INTERRUPT_MODE)
+    {
+        it = current_time - itime0;
+    }
+    else
+#endif
+    {
+#ifdef HAVE_GETTIMEOFDAY
+        et = current_time - time0;
+#endif
+        ETnodes = NodeCnt + znodes;
 
+        if (et < 0)
+        {
+#ifdef INTERRUPT_TEST
+            printf("elapsed time %ld not positive\n", et);
+#endif
+            et = 0;
+        }
+
+        if (iop == COMPUTE_AND_INIT_MODE)
+        {
+            if ((et > (ResponseTime + ExtraTime)) && (Sdepth > MINDEPTH))
+                flag.timeout = true;
+
+            time0 = current_time;
+        }
+
+#ifdef QUIETBACKGROUND
+        if (!background)
+#endif
+            UpdateClocks();
+    }
+}
+
+void
+Curses_SetupBoard(void)
+{
+    Curses_ShowMessage("'setup' command is not supported in Cursesmode");
+}