+++ /dev/null
-/*\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