Create new (empty) branch for board themes
[xboard.git] / winboard / jaws.c
diff --git a/winboard/jaws.c b/winboard/jaws.c
deleted file mode 100644 (file)
index aa843ad..0000000
+++ /dev/null
@@ -1,1400 +0,0 @@
-/*\r
- * JAWS.c -- Code for Windows front end to XBoard to use it with JAWS\r
- *\r
- * Copyright 1991 by Digital Equipment Corporation, Maynard,\r
- * Massachusetts.\r
- *\r
- * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,\r
- * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free\r
- * Software Foundation, Inc.\r
- *\r
- * XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess,\r
- * which was written and is copyrighted by Wayne Christopher.\r
- *\r
- * The following terms apply to Digital Equipment Corporation's copyright\r
- * interest in XBoard:\r
- * ------------------------------------------------------------------------\r
- * All Rights Reserved\r
- *\r
- * Permission to use, copy, modify, and distribute this software and its\r
- * documentation for any purpose and without fee is hereby granted,\r
- * provided that the above copyright notice appear in all copies and that\r
- * both that copyright notice and this permission notice appear in\r
- * supporting documentation, and that the name of Digital not be\r
- * used in advertising or publicity pertaining to distribution of the\r
- * software without specific, written prior permission.\r
- *\r
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING\r
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL\r
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR\r
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\r
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\r
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
- * SOFTWARE.\r
- * ------------------------------------------------------------------------\r
- *\r
- * The following terms apply to the enhanced version of XBoard\r
- * distributed by the Free Software Foundation:\r
- * ------------------------------------------------------------------------\r
- *\r
- * GNU XBoard is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License, or (at\r
- * your option) any later version.\r
- *\r
- * GNU XBoard is distributed in the hope that it will be useful, but\r
- * WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program. If not, see http://www.gnu.org/licenses/.  *\r
- *\r
- *------------------------------------------------------------------------\r
- ** See the file ChangeLog for a revision history.  */\r
-\r
-// This file collects all patches for the JAWS version, so they can all be included in winboard.c\r
-// in one big swoop. At the bottom of this file you can read instructions for how to patch\r
-// WinBoard to work with JAWS with the aid of this file. Note that the code in this file\r
-// is for WinBoard 4.3 and later; for older WB versions you would have to throw out the\r
-// piece names for all pieces from Guard to Unicorn, #define ONE as '1', AAA as 'a',\r
-// BOARD_LEFT as 0, BOARD_RGHT and BOARD_HEIGHT as 8, and set holdingssizes to 0.\r
-// You will need to build with jaws.rc in stead of winboard.rc.\r
-\r
-// from resource.h\r
-\r
-#define IDM_PossibleAttackMove          1800\r
-#define IDM_PossibleAttacked            1801\r
-#define IDM_SayMachineMove              1802\r
-#define IDM_ReadRow                     1803\r
-#define IDM_ReadColumn                  1804\r
-#define IDM_SayCurrentPos               1805\r
-#define IDM_SayAllBoard                 1806\r
-#define IDM_SayUpperDiagnols            1807\r
-#define IDM_SayLowerDiagnols            1808\r
-#define IDM_SayClockTime                1810\r
-#define IDM_SayWhosTurn                 1811\r
-#define IDM_SayKnightMoves              1812\r
-#define ID_SHITTY_HI                    1813\r
-#define IDM_SayWhitePieces              1816\r
-#define IDM_SayBlackPieces              1817\r
-\r
-\r
-// from common.h, but 'extern' added to it, so the actual declaraton can remain in backend.c\r
-\r
-extern long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement;\r
-\r
-// from moves.c, added WinBoard_F piece types and ranks / files\r
-\r
-char *squareToChar[] = { "ay", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };\r
-\r
-char *squareToNum[] = {"naught", "1", "2", "3", "4", "5", "6", "7", "8", "9" };\r
-\r
-char *ordinals[] = {"zeroth", "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "nineth"};\r
-\r
-char *pieceToName[] = {\r
-               "White Pawn", "White Knight", "White Bishop", "White Rook", "White Queen",\r
-               "White Guard", "White Elephant", "White Arch Bishop", "White Chancellor",\r
-               "White General", "White Man", "White Cannon", "White Night Rider",\r
-               "White Crowned Bishop", "White Crowned Rook", "White Grass Hopper", "White Veteran",\r
-               "White Falcon", "White Amazon", "White Snake", "White Unicorn",\r
-               "White King",\r
-               "Black Pawn", "Black Knight", "Black Bishop", "Black Rook", "Black Queen",\r
-               "Black Guard", "Black Elephant", "Black Arch Bishop", "Black Chancellor",\r
-               "Black General", "Black Man", "Black Cannon", "Black Night Rider",\r
-               "Black Crowned Bishop", "Black Crowned Rook", "Black Grass Hopper", "Black Veteran",\r
-               "Black Falcon", "Black Amazon", "Black Snake", "Black Unicorn",\r
-               "Black King",\r
-               "Empty"\r
-       };\r
-\r
-char *pieceTypeName[] = {\r
-               "Pawn", "Knight", "Bishop", "Rook", "Queen",\r
-               "Guard", "Elephant", "Arch Bishop", "Chancellor",\r
-               "General", "Man", "Cannon", "Night Rider",\r
-               "Crowned Bishop", "Crowned Rook", "Grass Hopper", "Veteran",\r
-               "Falcon", "Amazon", "Snake", "Unicorn",\r
-               "King",\r
-               "Pawn", "Knight", "Bishop", "Rook", "Queen",\r
-               "Guard", "Elephant", "Arch Bishop", "Chancellor",\r
-               "General", "Man", "Cannon", "Night Rider",\r
-               "Crowned Bishop", "Crowned Rook", "Grass Hopper", "Veteran",\r
-               "Falcon", "Amazon", "Snake", "Unicorn",\r
-               "King",\r
-               "Empty"\r
-       };\r
-\r
-int CoordToNum(c)\r
-               char c;\r
-{\r
-       if(isdigit(c)) return c - ONE;\r
-       if(c >= 'a') return c - AAA;\r
-       return 0;\r
-}\r
-\r
-char* PieceToName(p, i)\r
-       ChessSquare p;\r
-       int i;\r
-{\r
-       if(i) return pieceToName[(int) p];\r
-               return pieceTypeName[(int) p];\r
-}\r
-\r
-char* SquareToChar(x)\r
-                       int x;\r
-{\r
-               return squareToChar[x - BOARD_LEFT];\r
-}\r
-\r
-char* SquareToNum(y)\r
-                       int y;\r
-{\r
-               return squareToNum[y + (gameInfo.boardHeight < 10)];\r
-}\r
-\r
-\r
-// from winboard.c: all new routines\r
-#define JFWAPI __declspec(dllimport)\r
-JFWAPI BOOL WINAPI JFWSayString (LPCTSTR lpszStrinToSpeak, BOOL bInterrupt);\r
-\r
-typedef JFWAPI BOOL (WINAPI *PSAYSTRING)(LPCTSTR lpszStrinToSpeak, BOOL bInterrupt);\r
-\r
-PSAYSTRING RealSayString;\r
-\r
-VOID SayString(char *mess, BOOL flag)\r
-{ // for debug file\r
-       static char buf[8000], *p;\r
-        int l = strlen(buf);\r
-       if(appData.debugMode) fprintf(debugFP, "SAY '%s'\n", mess);\r
-        if(l) buf[l++] = ' '; // separate by space from previous\r
-       safeStrCpy(buf+l, _(mess), 8000-1-l); // buffer\r
-        if(!flag) return; // wait for flush\r
-       if(p = StrCaseStr(buf, "Xboard adjudication:")) {\r
-               int i;\r
-               for(i=19; i>1; i--) p[i] = p[i-1];\r
-               p[1] = ' ';\r
-       }\r
-       RealSayString(buf, !strcmp(mess, " ")); // kludge to indicate flushing of interruptable speach\r
-       if(appData.debugMode) fprintf(debugFP, "SPEAK '%s'\n", buf);\r
-       buf[0] = NULLCHAR;\r
-}\r
-\r
-//static int fromX = 0, fromY = 0;\r
-static int oldFromX, oldFromY;\r
-static int timeflag;\r
-static int suppressClocks = 0;\r
-static int suppressOneKey = 0;\r
-static HANDLE hAccelJAWS;\r
-\r
-typedef struct { char *name; int code; } MenuItemDesc;\r
-\r
-MenuItemDesc menuItemJAWS[] = {\r
-{"Say Clock &Time\tAlt+T",      IDM_SayClockTime },\r
-{"-", 0 },\r
-{"Say Last &Move\tAlt+M",       IDM_SayMachineMove },\r
-{"Say W&ho's Turn\tAlt+X",      IDM_SayWhosTurn },\r
-{"-", 0 },\r
-{"Say Complete &Position\tAlt+P",IDM_SayAllBoard },\r
-{"Say &White Pieces\tAlt+W",    IDM_SayWhitePieces },\r
-{"Say &Black Pieces\tAlt+B",    IDM_SayBlackPieces },\r
-{"Say Board &Rank\tAlt+R",      IDM_ReadRow },\r
-{"Say Board &File\tAlt+F",      IDM_ReadColumn },\r
-{"-", 0 },\r
-{"Say &Upper Diagonals\tAlt+U",  IDM_SayUpperDiagnols },\r
-{"Say &Lower Diagonals\tAlt+L",  IDM_SayLowerDiagnols },\r
-{"Say K&night Moves\tAlt+N",    IDM_SayKnightMoves },\r
-{"Say Current &Square\tAlt+S",  IDM_SayCurrentPos },\r
-{"Say &Attacks\tAlt+A",         IDM_PossibleAttackMove },\r
-{"Say Attacke&d\tAlt+D",        IDM_PossibleAttacked },\r
-{NULL, 0}\r
-};\r
-\r
-ACCEL acceleratorsJAWS[] = {\r
-{FVIRTKEY|FALT, 'T', IDM_SayClockTime },\r
-{FVIRTKEY|FALT, 'M', IDM_SayMachineMove },\r
-{FVIRTKEY|FALT, 'X', IDM_SayWhosTurn },\r
-{FVIRTKEY|FALT, 'P', IDM_SayAllBoard },\r
-{FVIRTKEY|FALT, 'W', IDM_SayWhitePieces },\r
-{FVIRTKEY|FALT, 'B', IDM_SayBlackPieces },\r
-{FVIRTKEY|FALT, 'R', IDM_ReadRow },\r
-{FVIRTKEY|FALT, 'F', IDM_ReadColumn },\r
-{FVIRTKEY|FALT, 'U', IDM_SayUpperDiagnols },\r
-{FVIRTKEY|FALT, 'L', IDM_SayLowerDiagnols },\r
-{FVIRTKEY|FALT, 'N', IDM_SayKnightMoves },\r
-{FVIRTKEY|FALT, 'S', IDM_SayCurrentPos },\r
-{FVIRTKEY|FALT, 'A', IDM_PossibleAttackMove },\r
-{FVIRTKEY|FALT, 'D', IDM_PossibleAttacked }\r
-};\r
-\r
-void\r
-AdaptMenu()\r
-{\r
-       HMENU menuMain, menuJAWS;\r
-       MENUBARINFO helpMenuInfo;\r
-       int i;\r
-\r
-       helpMenuInfo.cbSize = sizeof(helpMenuInfo);\r
-       menuMain = GetMenu(hwndMain);\r
-       menuJAWS = CreatePopupMenu();\r
-\r
-       for(i=0; menuItemJAWS[i].name; i++) {\r
-           if(menuItemJAWS[i].name[0] == '-')\r
-                AppendMenu(menuJAWS, MF_SEPARATOR, (UINT_PTR) 0, NULL);\r
-           else AppendMenu(menuJAWS, MF_ENABLED|MF_STRING,\r
-                       (UINT_PTR) menuItemJAWS[i].code, (LPCTSTR) _(menuItemJAWS[i].name));\r
-       }\r
-       InsertMenu(menuMain, 7, MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING,\r
-               (UINT_PTR) menuJAWS, "&JAWS");\r
-       oldMenuItemState[8] = oldMenuItemState[7];\r
-       DrawMenuBar(hwndMain);\r
-}\r
-\r
-BOOL\r
-InitJAWS()\r
-{      // to be called at beginning of WinMain, after InitApplication and InitInstance\r
-       HINSTANCE hApi = LoadLibrary("jfwapi32.dll");\r
-       if(!hApi) {\r
-               DisplayInformation("Missing jfwapi32.dll");\r
-               return (FALSE);\r
-       }\r
-\r
-       RealSayString = (PSAYSTRING)GetProcAddress(hApi, "JFWSayString");\r
-       if(!RealSayString) {\r
-               DisplayInformation("SayString returned a null pointer");\r
-               return (FALSE);\r
-       }\r
-\r
-       {\r
-               // [HGM] kludge to reduce need for modification of winboard.c: make tinyLayout menu identical\r
-               // to standard layout, so that code for switching between them does not have to be deleted\r
-               int i;\r
-\r
-               AdaptMenu();\r
-               menuBarText[0][8] = menuBarText[0][7]; menuBarText[0][7] = "&JAWS";\r
-               for(i=0; i<9; i++) menuBarText[2][i] = menuBarText[1][i] = menuBarText[0][i];\r
-       }\r
-\r
-       hAccelJAWS = CreateAcceleratorTable(acceleratorsJAWS, 14);\r
-\r
-       /* initialize cursor position */\r
-       fromX = fromY = 0;\r
-       SetHighlights(fromX, fromY, -1, -1);\r
-       DrawPosition(FALSE, NULL);\r
-       oldFromX = oldFromY = -1;\r
-\r
-       if(hwndConsole) SetFocus(hwndConsole);\r
-       return TRUE;\r
-}\r
-\r
-int beeps[] = { 1, 0, 0, 0, 0 };\r
-int beepCodes[] = { 0, MB_OK, MB_ICONERROR, MB_ICONQUESTION, MB_ICONEXCLAMATION, MB_ICONASTERISK };\r
-static int dropX = -1, dropY = -1;\r
-\r
-VOID\r
-KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-       ChessSquare currentPiece;\r
-       char *piece, *xchar, *ynum ;\r
-       int n, beepType = 1; // empty beep\r
-\r
-       if(fromX == -1 || fromY == -1) { // if we just dropped piece, stay at that square\r
-               fromX = dropX; fromY = dropY;\r
-               dropX = dropY = -1; // but only once\r
-        }\r
-       if(fromX == -1 || fromY == -1) {\r
-               fromX = BOARD_LEFT; fromY = 0;\r
-        }\r
-       switch(wParam) {\r
-       case VK_LEFT:\r
-               if(fromX == BOARD_RGHT+1) fromX -= 2; else\r
-               if(fromX == BOARD_LEFT) { if(fromY >= BOARD_HEIGHT - gameInfo.holdingsSize) fromX -= 2; else beepType = 0; } else\r
-               if(fromX > BOARD_LEFT) fromX--; else beepType = 0; // off-board beep\r
-               break;\r
-       case VK_RIGHT:\r
-               if(fromX == BOARD_LEFT-2) fromX += 2; else\r
-               if(fromX == BOARD_RGHT-1) { if(fromY < gameInfo.holdingsSize) fromX += 2; else beepType = 0; } else\r
-               if(fromX < BOARD_RGHT-1) fromX++; else beepType = 0;\r
-               break;\r
-       case VK_UP:\r
-               if(fromX == BOARD_RGHT+1) { if(fromY < gameInfo.holdingsSize - 1) fromY++; else beepType = 0; } else\r
-               if(fromY < BOARD_HEIGHT-1) fromY++; else beepType = 0;\r
-               break;\r
-       case VK_DOWN:\r
-               if(fromX == BOARD_LEFT-2) { if(fromY > BOARD_HEIGHT - gameInfo.holdingsSize) fromY--; else beepType = 0; } else\r
-               if(fromY > 0) fromY--; else beepType = 0;\r
-               break;\r
-       }\r
-       SetHighlights(fromX, fromY, -1, -1);\r
-       DrawPosition(FALSE, NULL);\r
-       currentPiece = boards[currentMove][fromY][fromX];\r
-       piece = PieceToName(currentPiece,1);\r
-       if(beepType == 1 && currentPiece != EmptySquare) beepType = currentPiece < (int) BlackPawn ? 2 : 3; // white or black beep\r
-       if(beeps[beepType] == beeps[1] && (fromX == BOARD_RGHT+1 || fromX == BOARD_LEFT-2)) beepType = 4; // holdings beep\r
-       beepType = beeps[beepType]%6;\r
-       if(beepType) MessageBeep(beepCodes[beepType]);\r
-       if(fromX == BOARD_LEFT - 2) {\r
-               SayString("black holdings", FALSE);\r
-               if(currentPiece != EmptySquare) {\r
-                       char buf[MSG_SIZ];\r
-                       n = boards[currentMove][fromY][1];\r
-                       snprintf(buf, MSG_SIZ, "%d %s%s", n, PieceToName(currentPiece,0), n == 1 ? "" : "s");\r
-                       SayString(buf, FALSE);\r
-               }\r
-               SayString(" ", TRUE);\r
-       } else\r
-       if(fromX == BOARD_RGHT + 1) {\r
-               SayString("white holdings", FALSE);\r
-               if(currentPiece != EmptySquare) {\r
-                       char buf[MSG_SIZ];\r
-                       n = boards[currentMove][fromY][BOARD_WIDTH-2];\r
-                       snprintf(buf, MSG_SIZ,"%d %s%s", n, PieceToName(currentPiece,0), n == 1 ? "" : "s");\r
-                       SayString(buf, FALSE);\r
-               }\r
-               SayString(" ", TRUE);\r
-       } else\r
-       if(fromX >= BOARD_LEFT && fromX < BOARD_RGHT) {\r
-               char buf[MSG_SIZ];\r
-               xchar = SquareToChar(fromX);\r
-               ynum = SquareToNum(fromY);\r
-               if(currentPiece != EmptySquare) {\r
-                 snprintf(buf, MSG_SIZ, "%s %s %s", xchar, ynum, piece);\r
-               } else snprintf(buf, MSG_SIZ, "%s %s", xchar, ynum);\r
-               SayString(buf, FALSE);\r
-               SayString(" ", TRUE);\r
-       }\r
-       return;\r
-}\r
-\r
-int PosFlags(int nr);\r
-\r
-typedef struct {\r
-    int rf, ff, rt, ft;\r
-    int onlyCaptures;\r
-    int count;\r
-} ReadClosure;\r
-\r
-extern void ReadCallback P((Board board, int flags, ChessMove kind,\r
-                               int rf, int ff, int rt, int ft,\r
-                               VOIDSTAR closure));\r
-\r
-void ReadCallback(board, flags, kind, rf, ff, rt, ft, closure)\r
-     Board board;\r
-     int flags;\r
-     ChessMove kind;\r
-     int rf, ff, rt, ft;\r
-     VOIDSTAR closure;\r
-{\r
-    register ReadClosure *cl = (ReadClosure *) closure;\r
-    ChessSquare possiblepiece;\r
-    char *piece, *xchar, *ynum ;\r
-\r
-//if(appData.debugMode) fprintf(debugFP, "%c%c%c%c\n", ff+AAA, rf+ONE, ft+AAA, rt+ONE);\r
-    if(cl->ff == ff && cl->rf == rf) {\r
-       possiblepiece = board[rt][ft];\r
-       if(possiblepiece != EmptySquare) {\r
-               piece = PieceToName(possiblepiece,1);\r
-               xchar = SquareToChar(ft);\r
-               ynum  = SquareToNum(rt);\r
-               SayString(xchar , FALSE);\r
-               SayString(ynum, FALSE);\r
-               SayString(piece, FALSE);\r
-               cl->count++;\r
-       }\r
-    }\r
-    if(cl->ft == ft && cl->rt == rt) {\r
-       possiblepiece = board[rf][ff];\r
-               piece = PieceToName(possiblepiece,1);\r
-               xchar = SquareToChar(ff);\r
-               ynum  = SquareToNum(rf);\r
-               SayString(xchar , FALSE);\r
-               SayString(ynum, FALSE);\r
-               SayString(piece, FALSE);\r
-               cl->count++;\r
-    }\r
-}\r
-\r
-VOID\r
-PossibleAttackMove()\r
-{\r
-       ReadClosure cl;\r
-       ChessSquare piece, victim;\r
-       int removedSelectedPiece = 0, swapColor;\r
-\r
-//if(appData.debugMode) fprintf(debugFP, "PossibleAttackMove %d %d %d %d\n", fromX, fromY, oldFromX, oldFromY);\r
-       if(fromY < 0 || fromY >= BOARD_HEIGHT) return;\r
-       if(fromX < BOARD_LEFT || fromX >= BOARD_RGHT) { SayString("holdings",TRUE); return; }\r
-\r
-       piece = boards[currentMove][fromY][fromX];\r
-       if(piece == EmptySquare) { // if square is empty, try to substitute selected piece\r
-           if(oldFromX >= 0 && oldFromY >= 0) {\r
-               piece = boards[currentMove][oldFromY][oldFromX];\r
-               boards[currentMove][oldFromY][oldFromX] = EmptySquare;\r
-               removedSelectedPiece = 1;\r
-               SayString("Your", FALSE);\r
-               SayString(PieceToName(piece, 0), FALSE);\r
-               SayString("would have", FALSE);\r
-           } else { SayString("You must select a piece first", TRUE); return; }\r
-       }\r
-\r
-       victim = boards[currentMove][fromY][fromX];\r
-       boards[currentMove][fromY][fromX] = piece; // make sure piece is actally there\r
-       SayString("possible captures from here are", FALSE);\r
-\r
-       swapColor = piece <  (int)BlackPawn && !WhiteOnMove(currentMove) ||\r
-                   piece >= (int)BlackPawn &&  WhiteOnMove(currentMove);\r
-       cl.count = 0; cl.rf = fromY; cl.ff = fromX; cl.rt = cl.ft = -1;\r
-       GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), ReadCallback, (VOIDSTAR) &cl);\r
-       if(cl.count == 0) SayString("None", FALSE);\r
-       SayString("", TRUE); // flush\r
-       boards[currentMove][fromY][fromX] = victim; // repair\r
-\r
-       if( removedSelectedPiece ) boards[currentMove][oldFromY][oldFromX] = piece;\r
-}\r
-\r
-\r
-VOID\r
-PossibleAttacked()\r
-{\r
-       ReadClosure cl;\r
-       ChessSquare piece = EmptySquare, victim;\r
-\r
-       if(fromY < 0 || fromY >= BOARD_HEIGHT) return;\r
-       if(fromX < BOARD_LEFT || fromX >= BOARD_RGHT) { SayString("holdings",TRUE); return; }\r
-\r
-       if(oldFromX >= 0 && oldFromY >= 0) { // if piece is selected, remove it\r
-               piece = boards[currentMove][oldFromY][oldFromX];\r
-               boards[currentMove][oldFromY][oldFromX] = EmptySquare;\r
-       }\r
-\r
-       SayString("Pieces that can capture you are", FALSE);\r
-\r
-       victim = boards[currentMove][fromY][fromX]; // put dummy piece on target square, to activate Pawn captures\r
-       boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen;\r
-       cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;\r
-       GenLegal(boards[currentMove], PosFlags(currentMove+1), ReadCallback, (VOIDSTAR) &cl);\r
-       if(cl.count == 0) SayString("None", FALSE);\r
-\r
-       SayString("You are defended by", FALSE);\r
-\r
-       boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? BlackQueen : WhiteQueen;\r
-       cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;\r
-       GenLegal(boards[currentMove], PosFlags(currentMove), ReadCallback, (VOIDSTAR) &cl);\r
-       if(cl.count == 0) SayString("None", FALSE);\r
-       SayString("", TRUE); // flush\r
-       boards[currentMove][fromY][fromX] = victim; // put back original occupant\r
-\r
-       if(oldFromX >= 0 && oldFromY >= 0) { // put back possibl selected piece\r
-               boards[currentMove][oldFromY][oldFromX] = piece;\r
-       }\r
-}\r
-\r
-VOID\r
-ReadRow()\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum ;\r
-       int xPos, count=0;\r
-       ynum = SquareToNum(fromY);\r
-\r
-       if(fromY < 0) return;\r
-\r
-       for (xPos=BOARD_LEFT; xPos<BOARD_RGHT; xPos++) {\r
-               currentpiece = boards[currentMove][fromY][xPos];\r
-               if(currentpiece != EmptySquare) {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(xPos);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-                       count++;\r
-               }\r
-       }\r
-       if(count == 0) {\r
-               SayString("rank", FALSE);\r
-               SayString(ynum, FALSE);\r
-               SayString("empty", FALSE);\r
-       }\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-ReadColumn()\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum ;\r
-       int yPos, count=0;\r
-       xchar = SquareToChar(fromX);\r
-\r
-       if(fromX < 0) return;\r
-\r
-       for (yPos=0; yPos<BOARD_HEIGHT; yPos++) {\r
-               currentpiece = boards[currentMove][yPos][fromX];\r
-               if(currentpiece != EmptySquare) {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       ynum = SquareToNum(yPos);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-                       count++;\r
-               }\r
-       }\r
-       if(count == 0) {\r
-               SayString(xchar, FALSE);\r
-               SayString("file empty", FALSE);\r
-       }\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayUpperDiagnols()\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum ;\r
-       int yPos, xPos;\r
-\r
-       if(fromX < 0 || fromY < 0) return;\r
-\r
-       if(fromX < BOARD_RGHT-1 && fromY < BOARD_HEIGHT-1) {\r
-               SayString("The diagnol squares to your upper right contain", FALSE);\r
-               yPos = fromY+1;\r
-               xPos = fromX+1;\r
-               while(yPos<BOARD_HEIGHT && xPos<BOARD_RGHT) {\r
-                       currentpiece = boards[currentMove][yPos][xPos];\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(xPos);\r
-                       ynum = SquareToNum(yPos);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-                       yPos++;\r
-                       xPos++;\r
-               }\r
-       }\r
-       else SayString("There is no squares to your upper right", FALSE);\r
-\r
-       if(fromX > BOARD_LEFT && fromY < BOARD_HEIGHT-1) {\r
-               SayString("The diagnol squares to your upper left contain", FALSE);\r
-               yPos = fromY+1;\r
-               xPos = fromX-1;\r
-               while(yPos<BOARD_HEIGHT && xPos>=BOARD_LEFT) {\r
-                       currentpiece = boards[currentMove][yPos][xPos];\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(xPos);\r
-                       ynum = SquareToNum(yPos);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-                       yPos++;\r
-                       xPos--;\r
-               }\r
-       }\r
-       else SayString("There is no squares to your upper left", FALSE);\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayLowerDiagnols()\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum ;\r
-       int yPos, xPos;\r
-\r
-       if(fromX < 0 || fromY < 0) return;\r
-\r
-       if(fromX < BOARD_RGHT-1 && fromY > 0) {\r
-               SayString("The diagnol squares to your lower right contain", FALSE);\r
-               yPos = fromY-1;\r
-               xPos = fromX+1;\r
-               while(yPos>=0 && xPos<BOARD_RGHT) {\r
-                       currentpiece = boards[currentMove][yPos][xPos];\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(xPos);\r
-                       ynum = SquareToNum(yPos);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-                       yPos--;\r
-                       xPos++;\r
-               }\r
-       }\r
-       else SayString("There is no squares to your lower right", FALSE);\r
-\r
-       if(fromX > BOARD_LEFT && fromY > 0) {\r
-               SayString("The diagnol squares to your lower left contain", FALSE);\r
-               yPos = fromY-1;\r
-               xPos = fromX-1;\r
-               while(yPos>=0 && xPos>=BOARD_LEFT) {\r
-                       currentpiece = boards[currentMove][yPos][xPos];\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(xPos);\r
-                       ynum = SquareToNum(yPos);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-                       yPos--;\r
-                       xPos--;\r
-               }\r
-       }\r
-       else SayString("There is no squares to your lower left", FALSE);\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayKnightMoves()\r
-{\r
-       ChessSquare currentpiece, oldpiece;\r
-       char *piece, *xchar, *ynum ;\r
-\r
-       oldpiece = boards[currentMove][fromY][fromX];\r
-       if(oldpiece == WhiteKnight || oldpiece == BlackKnight)\r
-               SayString("The possible squares a Knight could move to are", FALSE);\r
-       else\r
-               SayString("The squares a Knight could possibly attack from are", FALSE);\r
-\r
-       if (fromY+2 < BOARD_HEIGHT && fromX-1 >= BOARD_LEFT) {\r
-               currentpiece = boards[currentMove][fromY+2][fromX-1];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX-1);\r
-                       ynum = SquareToNum(fromY+2);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY+2 < BOARD_HEIGHT && fromX+1 < BOARD_RGHT) {\r
-               currentpiece = boards[currentMove][fromY+2][fromX+1];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX+1);\r
-                       ynum = SquareToNum(fromY+2);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY+1 < BOARD_HEIGHT && fromX+2 < BOARD_RGHT) {\r
-               currentpiece = boards[currentMove][fromY+1][fromX+2];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX+2);\r
-                       ynum = SquareToNum(fromY+1);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY-1 >= 0 && fromX+2 < BOARD_RGHT) {\r
-               currentpiece = boards[currentMove][fromY-1][fromX+2];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX+2);\r
-                       ynum = SquareToNum(fromY-1);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY-2 >= 0 && fromX+1 < BOARD_RGHT) {\r
-               currentpiece = boards[currentMove][fromY-2][fromX+1];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX+1);\r
-                       ynum = SquareToNum(fromY-2);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY-2 >= 0 && fromX-1 >= BOARD_LEFT) {\r
-               currentpiece = boards[currentMove][fromY-2][fromX-1];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX-1);\r
-                       ynum = SquareToNum(fromY-2);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY-1 >= 0 && fromX-2 >= BOARD_LEFT) {\r
-               currentpiece = boards[currentMove][fromY-1][fromX-2];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX-2);\r
-                       ynum = SquareToNum(fromY-1);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-\r
-       if (fromY+1 < BOARD_HEIGHT && fromX-2 >= BOARD_LEFT) {\r
-               currentpiece = boards[currentMove][fromY+1][fromX-2];\r
-               if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))\r
-                       || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))\r
-                       || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))\r
-               {\r
-                       piece = PieceToName(currentpiece,1);\r
-                       xchar = SquareToChar(fromX-2);\r
-                       ynum = SquareToNum(fromY+1);\r
-                       SayString(xchar , FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       SayString(piece, FALSE);\r
-               }\r
-       }\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayPieces(ChessSquare p)\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum ;\r
-       int yPos, xPos, count = 0;\r
-       char buf[50];\r
-\r
-       if(p == WhitePlay)   SayString("White pieces", FALSE); else\r
-       if(p == BlackPlay)   SayString("Black pieces", FALSE); else\r
-       if(p == EmptySquare) SayString("Pieces", FALSE); else {\r
-         snprintf(buf, sizeof(buf)/sizeof(buf[0]),"%ss", PieceToName(p,1));\r
-               SayString(buf, FALSE);\r
-       }\r
-       SayString("are located", FALSE);\r
-       for(yPos=0; yPos<BOARD_HEIGHT; yPos++) {\r
-               for(xPos=BOARD_LEFT; xPos<BOARD_RGHT; xPos++) {\r
-                       currentpiece = boards[currentMove][yPos][xPos];\r
-                       if(p == BlackPlay && currentpiece >= BlackPawn && currentpiece <= BlackKing ||\r
-                          p == WhitePlay && currentpiece >= WhitePawn && currentpiece <= WhiteKing   )\r
-                               piece = PieceToName(currentpiece,0);\r
-                       else if(p == EmptySquare && currentpiece != EmptySquare)\r
-                               piece = PieceToName(currentpiece,1);\r
-                       else if(p == currentpiece)\r
-                               piece = NULL;\r
-                       else continue;\r
-\r
-                               if(count == 0) SayString("at", FALSE);\r
-                               xchar = SquareToChar(xPos);\r
-                               ynum = SquareToNum(yPos);\r
-                               SayString(xchar , FALSE);\r
-                               SayString(ynum, FALSE);\r
-                               if(piece) SayString(piece, FALSE);\r
-                               count++;\r
-               }\r
-       }\r
-       if(count == 0) SayString("nowhere", FALSE);\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayCurrentPos()\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum ;\r
-       if(fromX <  BOARD_LEFT) { SayString("You strayed into the white holdings", FALSE); return; }\r
-       if(fromX >= BOARD_RGHT) { SayString("You strayed into the black holdings", FALSE); return; }\r
-       currentpiece = boards[currentMove][fromY][fromX];\r
-       piece = PieceToName(currentpiece,1);\r
-       ynum = SquareToNum(fromY);\r
-       xchar = SquareToChar(fromX);\r
-       SayString("Your current position is", FALSE);\r
-       SayString(xchar, FALSE);\r
-       SayString(ynum, FALSE);\r
-       SayString(piece, FALSE);\r
-       if(((fromX-BOARD_LEFT) ^ fromY)&1)\r
-               SayString("on a light square",FALSE);\r
-       else\r
-               SayString("on a dark square",FALSE);\r
-\r
-       PossibleAttacked();\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayAllBoard()\r
-{\r
-       int Xpos, Ypos;\r
-       ChessSquare currentpiece;\r
-       char *piece, *ynum ;\r
-\r
-       if(gameInfo.holdingsWidth) {\r
-               int first = 0;\r
-               for(Ypos=0; Ypos<gameInfo.holdingsSize; Ypos++) {\r
-                       int n = boards[currentMove][Ypos][BOARD_WIDTH-2];\r
-                       if(n) {\r
-                         char buf[MSG_SIZ];\r
-                         if(!first++)\r
-                           SayString("white holds", FALSE);\r
-                         currentpiece = boards[currentMove][Ypos][BOARD_WIDTH-1];\r
-                         piece = PieceToName(currentpiece,0);\r
-                         snprintf(buf, MSG_SIZ,"%d %s%s", n, piece, (n==1 ? "" : "s") );\r
-                         SayString(buf, FALSE);\r
-                       }\r
-               }\r
-               first = 0;\r
-               for(Ypos=BOARD_HEIGHT-1; Ypos>=BOARD_HEIGHT - gameInfo.holdingsSize; Ypos--) {\r
-                       int n = boards[currentMove][Ypos][1];\r
-                       if(n) {\r
-                         char buf[MSG_SIZ];\r
-                         if(!first++)\r
-                           SayString("black holds", FALSE);\r
-                         currentpiece = boards[currentMove][Ypos][0];\r
-                         piece = PieceToName(currentpiece,0);\r
-                         snprintf(buf, MSG_SIZ, "%d %s%s", n, piece, (n==1 ? "" : "s") );\r
-                         SayString(buf, FALSE);\r
-                       }\r
-               }\r
-       }\r
-\r
-       for(Ypos=BOARD_HEIGHT-1; Ypos>=0; Ypos--) {\r
-               ynum = ordinals[Ypos + (gameInfo.boardHeight < 10)];\r
-               SayString(ynum, FALSE);\r
-               SayString("rank", FALSE);\r
-               for(Xpos=BOARD_LEFT; Xpos<BOARD_RGHT; Xpos++) {\r
-                       currentpiece = boards[currentMove][Ypos][Xpos];\r
-                       if(currentpiece != EmptySquare) {\r
-                               int count = 0;\r
-                               char buf[50];\r
-                               piece = PieceToName(currentpiece,1);\r
-                               while(Xpos < BOARD_RGHT && boards[currentMove][Ypos][Xpos] == currentpiece)\r
-                                       Xpos++, count++;\r
-                               if(count > 1)\r
-                                 snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%d %ss", count, piece);\r
-                               else\r
-                                 snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s", piece);\r
-                               Xpos--;\r
-                               SayString(buf, FALSE);\r
-                       } else {\r
-                               int count = 0, oldX = Xpos;\r
-                               while(Xpos < BOARD_RGHT && boards[currentMove][Ypos][Xpos] == EmptySquare)\r
-                                       Xpos++, count++;\r
-                               if(Xpos == BOARD_RGHT && oldX == BOARD_LEFT)\r
-                                       SayString("all", FALSE);\r
-                               else{\r
-                                   if(count > 1) {\r
-                                       char buf[10];\r
-                                       snprintf(buf, sizeof(buf)/sizeof(buf[0]),"%d", count);\r
-                                       SayString(buf, FALSE);\r
-                                   }\r
-                                   Xpos--;\r
-                               }\r
-                               SayString("empty", FALSE);\r
-                       }\r
-               }\r
-       }\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayWhosTurn()\r
-{\r
-       if(gameMode == MachinePlaysBlack || gameMode == IcsPlayingWhite) {\r
-               if(WhiteOnMove(currentMove))\r
-                       SayString("It is your turn", FALSE);\r
-               else    SayString("It is your opponents turn", FALSE);\r
-       } else if(gameMode == MachinePlaysWhite || gameMode == IcsPlayingBlack) {\r
-               if(WhiteOnMove(currentMove))\r
-                       SayString("It is your opponents turn", FALSE);\r
-               else    SayString("It is your turn", FALSE);\r
-       } else {\r
-               if(WhiteOnMove(currentMove))\r
-                       SayString("White is on move here", FALSE);\r
-               else    SayString("Black is on move here", FALSE);\r
-       }\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-extern char *commentList[];\r
-\r
-VOID\r
-SayMachineMove(int evenIfDuplicate)\r
-{\r
-       int len, xPos, yPos, moveNr, secondSpace = 0, castle = 0, n;\r
-       ChessSquare currentpiece;\r
-       char *piece, *xchar, *ynum, *p, checkMark = 0;\r
-       char c, buf[MSG_SIZ], comment[MSG_SIZ];\r
-       static char disambiguation[2];\r
-       static int previousMove = 0;\r
-\r
-       if(appData.debugMode) fprintf(debugFP, "Message = '%s'\n", messageText);\r
-       if(gameMode == BeginningOfGame) return;\r
-       if(messageText[0] == '[') return;\r
-       comment[0]= 0;\r
-           if(isdigit(messageText[0])) { // message is move, possibly with thinking output\r
-               int dotCount = 0, spaceCount = 0;\r
-               sscanf(messageText, "%d", &moveNr);\r
-               len = 0;\r
-               // [HGM] show: better extraction of move\r
-               while (messageText[len] != NULLCHAR) {\r
-                   if(messageText[len] == '.' && spaceCount == 0) dotCount++;\r
-                   if(messageText[len] == ' ') { if(++spaceCount == 2) secondSpace = len; }\r
-                   if(messageText[len] == '{') { // we detected a comment\r
-                       if(isalpha(messageText[len+1]) ) sscanf(messageText+len, "{%[^}]}", comment);\r
-                       break;\r
-                   }\r
-                   if(messageText[len] == '[') { // we detected thinking output\r
-                       int depth; float score=0; char c, lastMover = (dotCount == 3 ? 'B' : 'W');\r
-                       if(sscanf(messageText+len+1, "%d]%c%f", &depth, &c, &score) > 1) {\r
-                           if(c == ' ') { // if not explicitly specified, figure out source of thinking output\r
-                               switch(gameMode) {\r
-                                 case MachinePlaysWhite:\r
-                                 case IcsPlayingWhite:\r
-                                   c = 'W'; break;\r
-                                 case IcsPlayingBlack:\r
-                                 case MachinePlaysBlack:\r
-                                   c = 'B';\r
-                                 default:\r
-                                   break;\r
-                               }\r
-                           }\r
-                           if(c != lastMover && !evenIfDuplicate) return; // line is thinking output of future move, ignore.\r
-                           if(2*moveNr - (dotCount < 2) == previousMove)\r
-                               return; // do not repeat same move; likely ponder output\r
-                           snprintf(buf, MSG_SIZ, "score %s %d at %d ply",\r
-                                       score > 0 ? "plus" : score < 0 ? "minus" : "",\r
-                                       (int) (fabs(score)*100+0.5),\r
-                                       depth );\r
-                           SayString(buf, FALSE); // move + thinking output describing it; say it.\r
-                       }\r
-                       while(messageText[len-1] == ' ') len--; // position just behind move;\r
-                       break;\r
-                   }\r
-                   if(messageText[len] == '(') { // ICS time printed behind move\r
-                       while(messageText[len+1] && messageText[len] != ')') len++; // skip it\r
-                   }\r
-                   len++;\r
-               }\r
-               if(secondSpace) len = secondSpace; // position behind move\r
-               if(messageText[len-1] == '+' || messageText[len-1] == '#') {  /* you are in checkmate */\r
-                       len--; // strip off check or mate indicator\r
-                     checkMark = messageText[len]; // make sure still seen after we stip off promo piece\r
-               }\r
-               if(messageText[len-2] == '=') {  /* promotion */\r
-                       len-=2; // strip off promotion piece\r
-                       SayString("promotion", FALSE);\r
-               }\r
-\r
-               n = 2*moveNr - (dotCount < 2);\r
-\r
-               if(previousMove != 2*moveNr + (dotCount > 1) || evenIfDuplicate) {\r
-                   char number[20];\r
-                   previousMove = 2*moveNr + (dotCount > 1); // remember move nr of move last spoken\r
-                   snprintf(number, sizeof(number)/sizeof(number[0]),"%d", moveNr);\r
-\r
-                   yPos = CoordToNum(messageText[len-1]);  /* turn char coords to ints */\r
-                   xPos = CoordToNum(messageText[len-2]);\r
-                   if(xPos < 0 || xPos > 11) return; // prevent crashes if no coord string available to speak\r
-                   if(yPos < 0 || yPos > 9)  return;\r
-                   currentpiece = boards[n][yPos][xPos];\r
-                   piece = PieceToName(currentpiece,0);\r
-                   ynum = SquareToNum(yPos);\r
-                   xchar = SquareToChar(xPos);\r
-                   c = messageText[len-3];\r
-                   if(c == 'x') c = messageText[len-4];\r
-                   if(!isdigit(c) && c < 'a' && c != '@') c = 0;\r
-                   disambiguation[0] = c;\r
-                   SayString(WhiteOnMove(n) ? "Black" : "White", FALSE);\r
-                   SayString("move", FALSE);\r
-                   SayString(number, FALSE);\r
-//                 if(c==0 || c=='@') SayString("a", FALSE);\r
-                   // intercept castling moves\r
-                   p = StrStr(messageText, "O-O-O");\r
-                   if(p && p-messageText < len) {\r
-                       SayString("queen side castling",FALSE);\r
-                       castle = 1;\r
-                   } else {\r
-                       p = StrStr(messageText, "O-O");\r
-                       if(p && p-messageText < len) {\r
-                           SayString("king side castling",FALSE);\r
-                           castle = 1;\r
-                       }\r
-                   }\r
-                   if(!castle) {\r
-                       SayString(piece, FALSE);\r
-                       if(c == '@') SayString("dropped on", FALSE); else\r
-                       if(c) SayString(disambiguation, FALSE);\r
-                       SayString("to", FALSE);\r
-                       SayString(xchar, FALSE);\r
-                       SayString(ynum, FALSE);\r
-                       if(messageText[len-3] == 'x') {\r
-                               currentpiece = boards[n-1][yPos][xPos];\r
-                               if(currentpiece != EmptySquare) {\r
-                                       piece = PieceToName(currentpiece,0);\r
-                                       SayString("Capturing a",FALSE);\r
-                                       SayString(piece, FALSE);\r
-                               } else SayString("Capturing onn passann",FALSE);\r
-                       }\r
-                   }\r
-                   if(checkMark == '+') SayString("check", FALSE); else\r
-                   if(checkMark == '#') {\r
-                               SayString("finishing off", FALSE);\r
-                               SayString(WhiteOnMove(n) ? "White" : "Black", FALSE);\r
-                   }\r
-               }\r
-\r
-               /* say comment after move, possibly with result */\r
-               p = NULL;\r
-               if(StrStr(messageText, " 1-0")) p = "white wins"; else\r
-               if(StrStr(messageText, " 0-1")) p = "black wins"; else\r
-               if(StrStr(messageText, " 1/2-1/2")) p = "game ends in a draw";\r
-               if(comment[0]) {\r
-                   if(p) {\r
-                       if(!StrCaseStr(comment, "draw") &&\r
-                          !StrCaseStr(comment, "white") &&\r
-                          !StrCaseStr(comment, "black") ) {\r
-                               SayString(p, FALSE);\r
-                               SayString("due to", FALSE);\r
-                       }\r
-                   }\r
-                   SayString(comment, FALSE); // alphabetic comment (usually game end)\r
-               } else if(p) SayString(p, FALSE);\r
-\r
-               if(commentDialog && commentList[currentMove]) SetFocus(commentDialog);\r
-\r
-           } else {\r
-               /* starts not with digit */\r
-               if(StrCaseStr(messageText, "illegal")) PlayIcsUnfinishedSound();\r
-               SayString(messageText, FALSE);\r
-           }\r
-\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-SayClockTime()\r
-{\r
-       char buf1[50], buf2[50];\r
-       char *str1, *str2;\r
-       static long int lastWhiteTime, lastBlackTime;\r
-\r
-       suppressClocks = 1; // if user is using alt+T command, no reason to display them\r
-       if(abs(lastWhiteTime - whiteTimeRemaining) < 1000 && abs(lastBlackTime - blackTimeRemaining) < 1000)\r
-               suppressClocks = 0; // back on after two requests in rapid succession\r
-       snprintf(buf1, sizeof(buf1)/sizeof(buf1[0]),"%s", TimeString(whiteTimeRemaining));\r
-       str1 = buf1;\r
-       SayString("White clock", FALSE);\r
-       SayString(str1, FALSE);\r
-       snprintf(buf2, sizeof(buf2)/sizeof(buf2[0]), "%s", TimeString(blackTimeRemaining));\r
-       str2 = buf2;\r
-       SayString("Black clock", FALSE);\r
-       SayString(str2, FALSE);\r
-       lastWhiteTime = whiteTimeRemaining;\r
-       lastBlackTime = blackTimeRemaining;\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-VOID\r
-Toggle(Boolean *b, char *mess)\r
-{\r
-       *b = !*b;\r
-       SayString(mess, FALSE);\r
-       SayString("is now", FALSE);\r
-       SayString(*b ? "on" : "off", FALSE);\r
-       SayString("", TRUE); // flush\r
-}\r
-\r
-/* handles keyboard moves in a click-click fashion */\r
-VOID\r
-KeyboardMove(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-       ChessSquare currentpiece;\r
-       char *piece;\r
-\r
-       static BOOLEAN sameAgain = FALSE;\r
-       switch (message) {\r
-       case WM_KEYDOWN:\r
-               sameAgain = FALSE;\r
-               if(oldFromX == fromX && oldFromY == fromY) {\r
-                       sameAgain = TRUE;\r
-                       /* click on same square */\r
-                       break;\r
-               }\r
-               else if(oldFromX != -1) {\r
-\r
-                       ChessSquare pdown, pup;\r
-      pdown = boards[currentMove][oldFromY][oldFromX];\r
-      pup = boards[currentMove][fromY][fromX];\r
-\r
-               if (gameMode == EditPosition ||\r
-                       !((WhitePawn <= pdown && pdown <= WhiteKing &&\r
-                                WhitePawn <= pup && pup <= WhiteKing) ||\r
-                               (BlackPawn <= pdown && pdown <= BlackKing &&\r
-                                BlackPawn <= pup && pup <= BlackKing))) {\r
-                       /* EditPosition, empty square, or different color piece;\r
-                       click-click move is possible */\r
-                       char promoChoice = NULLCHAR;\r
-\r
-                       if (HasPromotionChoice(oldFromX, oldFromY, fromX, fromY, &promoChoice)) {\r
-                               if (appData.alwaysPromoteToQueen) {\r
-                                       UserMoveEvent(oldFromX, oldFromY, fromX, fromY, 'q');\r
-                               }\r
-                               else {\r
-                                       toX = fromX; toY = fromY; fromX = oldFromX; fromY = oldFromY;\r
-                                       PromotionPopup(hwnd);\r
-                                       fromX = toX; fromY = toY;\r
-                               }\r
-                       }\r
-                       else {\r
-                               UserMoveEvent(oldFromX, oldFromY, fromX, fromY, promoChoice);\r
-                       }\r
-               oldFromX = oldFromY = -1;\r
-               break;\r
-               }\r
-\r
-               }\r
-               /* First downclick, or restart on a square with same color piece */\r
-               if (OKToStartUserMove(fromX, fromY)) {\r
-               oldFromX = fromX;\r
-               oldFromY = fromY;\r
-               currentpiece = boards[currentMove][fromY][fromX];\r
-               piece = PieceToName(currentpiece,1);\r
-               SayString(piece, FALSE);\r
-               SayString("selected", TRUE);\r
-               }\r
-               else {\r
-               oldFromX = oldFromY = -1;\r
-               }\r
-               break;\r
-\r
-       case WM_KEYUP:\r
-               if (oldFromX == fromX && oldFromY == fromY) {\r
-      /* Upclick on same square */\r
-      if (sameAgain) {\r
-       /* Clicked same square twice: abort click-click move */\r
-                       oldFromX = oldFromY = -1;\r
-                       currentpiece = boards[currentMove][fromY][fromX];\r
-                       piece = PieceToName(currentpiece,0);\r
-                       SayString(piece, FALSE);\r
-                       SayString("unselected", TRUE);\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-int\r
-NiceTime(int x)\r
-{      // return TRUE for times we want to announce\r
-       if(x<0) return 0;\r
-       x = (x+50)/100;   // tenth of seconds\r
-       if(x <= 100) return (x%10 == 0);\r
-       if(x <= 600) return (x%100 == 0);\r
-       if(x <= 6000) return (x%600 == 0);\r
-       return (x%3000 == 0);\r
-}\r
-\r
-#define JAWS_ARGS \\r
-  { "beepOffBoard", ArgInt, (LPVOID) beeps, TRUE, (ArgIniType) 1 },\\r
-  { "beepEmpty", ArgInt, (LPVOID) (beeps+1), TRUE, (ArgIniType) 0 },\\r
-  { "beepWhite", ArgInt, (LPVOID) (beeps+2), TRUE, (ArgIniType) 0 },\\r
-  { "beepBlack", ArgInt, (LPVOID) (beeps+3), TRUE, (ArgIniType) 0 },\\r
-  { "beepHoldings", ArgInt, (LPVOID) (beeps+4), TRUE, (ArgIniType) 0 },\\r
-\r
-#define JAWS_ALT_INTERCEPT \\r
-           if(suppressOneKey) {\\r
-               suppressOneKey = 0;\\r
-               if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) break;\\r
-           }\\r
-           if ((char)wParam == 022 && gameMode == EditPosition) { /* <Ctl R>. Pop up piece menu */\\r
-               POINT pt; int x, y;\\r
-               SquareToPos(fromY, fromX, &x, &y);\\r
-               dropX = fromX; dropY = fromY;\\r
-               pt.x = x; pt.y = y;\\r
-               if(gameInfo.variant != VariantShogi)\\r
-                   MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\\r
-               else\\r
-                   MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\\r
-               break;\\r
-           }\\r
-\r
-#define JAWS_REPLAY \\r
-    case '\020': /* ctrl P */\\r
-      { char buf[MSG_SIZ];\\r
-       if(GetWindowText(hwnd, buf, MSG_SIZ-1))\\r
-               SayString(buf, TRUE);\\r
-      }\\r
-      return 0;\\r
-\r
-#define JAWS_KBDOWN_NAVIGATION \\r
-\\r
-\\r
-               if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) {\\r
-                   /* Control + Alt + letter used for speaking piece positions */\\r
-                   static int lastTime; static char lastChar;\\r
-                   int mine = 0, time = GetTickCount(); char c;\\r
-\\r
-                   if((char)wParam == lastChar && time-lastTime < 250) mine = 1;\\r
-                   lastChar = wParam; lastTime = time;\\r
-                   c = wParam;\\r
-\\r
-                   if(gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) mine = !mine;\\r
-\\r
-                   if(ToLower(c) == 'x') {\\r
-                       SayPieces(mine ? WhitePlay : BlackPlay);\\r
-                       suppressOneKey = 1;\\r
-                       break;\\r
-                   } else\\r
-                   if(CharToPiece(c) != EmptySquare) {\\r
-                       SayPieces(CharToPiece(mine ? ToUpper(c) : ToLower(c)));\\r
-                       suppressOneKey = 1;\\r
-                       break;\\r
-                   }\\r
-               }\\r
-\\r
-               switch (wParam) {\\r
-               case VK_LEFT:\\r
-               case VK_RIGHT:\\r
-               case VK_UP:\\r
-               case VK_DOWN:\\r
-                       KeyboardEvent(hwnd, message, wParam, lParam);\\r
-                       break;\\r
-               case VK_SPACE:\\r
-                        shiftKey = GetKeyState(VK_SHIFT) < 0;\\r
-                       KeyboardMove(hwnd, message, wParam, lParam);\\r
-                       break;\\r
-               }\\r
-\r
-#define JAWS_KBUP_NAVIGATION \\r
-               switch (wParam) {\\r
-               case VK_SPACE:\\r
-                       KeyboardMove(hwnd, message, wParam, lParam);\\r
-                       break;\\r
-               }\\r
-\r
-#define JAWS_MENU_ITEMS \\r
-               case IDM_PossibleAttackMove:  /*What can I possible attack from here */\\r
-                       PossibleAttackMove();\\r
-                       break;\\r
-\\r
-               case IDM_PossibleAttacked:  /*what can possible attack this square*/\\r
-                       PossibleAttacked();\\r
-                       break;\\r
-\\r
-               case IDM_ReadRow:   /* Read the current row of pieces */\\r
-                       ReadRow();\\r
-                       break;\\r
-\\r
-               case IDM_ReadColumn:   /* Read the current column of pieces */\\r
-                       ReadColumn();\\r
-                       break;\\r
-\\r
-               case IDM_SayCurrentPos: /* Say current position including color */\\r
-                       SayCurrentPos();\\r
-                       break;\\r
-\\r
-               case IDM_SayAllBoard:  /* Say the whole board from bottom to top */\\r
-                       SayAllBoard();\\r
-                       break;\\r
-\\r
-               case IDM_SayMachineMove:  /* Say the last move made */\\r
-                       timeflag = 1;\\r
-                       SayMachineMove(1);\\r
-                       break;\\r
-\\r
-               case IDM_SayUpperDiagnols:  /* Says the diagnol positions above you */\\r
-                       SayUpperDiagnols();\\r
-                       break;\\r
-\\r
-               case IDM_SayLowerDiagnols:  /* Say the diagnol positions below you */\\r
-                       SayLowerDiagnols();\\r
-                       break;\\r
-\\r
-               case IDM_SayBlackPieces: /*Say the opponents pieces */\\r
-                       SayPieces(BlackPlay);\\r
-                       break;\\r
-\\r
-               case IDM_SayWhitePieces: /*Say the opponents pieces */\\r
-                       SayPieces(WhitePlay);\\r
-                       break;\\r
-\\r
-               case IDM_SayClockTime:  /*Say the clock time */\\r
-                       SayClockTime();\\r
-                       break;\\r
-\\r
-               case IDM_SayWhosTurn:   /* Say whos turn it its */\\r
-                       SayWhosTurn();\\r
-                       break;\\r
-\\r
-               case IDM_SayKnightMoves:  /* Say Knights (L-shaped) move */\\r
-                       SayKnightMoves();\\r
-                       break;\\r
-\\r
-               case OPT_PonderNextMove:  /* Toggle option setting */\\r
-                       Toggle(&appData.ponderNextMove, "ponder");\\r
-                       break;\\r
-\\r
-               case OPT_AnimateMoving:  /* Toggle option setting */\\r
-                       Toggle(&appData.animate, "animate moving");\\r
-                       break;\\r
-\\r
-               case OPT_AutoFlag:  /* Toggle option setting */\\r
-                       Toggle(&appData.autoCallFlag, "auto flag");\\r
-                       break;\\r
-\\r
-               case OPT_AlwaysQueen:  /* Toggle option setting */\\r
-                       Toggle(&appData.alwaysPromoteToQueen, "always promote to queen");\\r
-                       break;\\r
-\\r
-               case OPT_TestLegality:  /* Toggle option setting */\\r
-                       Toggle(&appData.testLegality, "legality testing");\\r
-                       break;\\r
-\\r
-               case OPT_HideThinkFromHuman:  /* Toggle option setting */\\r
-                       Toggle(&appData.hideThinkingFromHuman, "hide thinking");\\r
-                       ShowThinkingEvent();\\r
-                       break;\\r
-\\r
-               case OPT_SaveExtPGN:  /* Toggle option setting */\\r
-                       Toggle(&appData.saveExtendedInfoInPGN, "extended P G N info");\\r
-                       break;\\r
-\\r
-               case OPT_ExtraInfoInMoveHistory:  /* Toggle option setting */\\r
-                       Toggle(&appData.showEvalInMoveHistory, "extra info in move histoty");\\r
-                       break;\\r
-\\r
-\r
-\r
-#define JAWS_ACCEL \\r
-       !(!frozen && TranslateAccelerator(hwndMain, hAccelJAWS, &msg)) &&\r
-\r
-#define JAWS_INIT if (!InitJAWS()) return (FALSE);\r
-\r
-#define JAWS_DELETE(X)\r
-\r
-#define JAWS_SILENCE if(suppressClocks) return;\r
-\r
-#define JAWS_COPYRIGHT \\r
-       SetDlgItemText(hDlg, OPT_MESS, "Auditory/Keyboard Enhancements  By:  Ed Rodriguez (sort of)");\r
-\r
-#define SAY(S) SayString((S), TRUE)\r
-\r
-#define SAYMACHINEMOVE() SayMachineMove(0)\r
-\r
-// After inclusion of this file somewhere early in winboard.c, the remaining part of the patch\r
-// is scattered over winboard.c for actually calling the routines.\r