2 * JAWS.c -- Code for Windows front end to XBoard to use it with JAWS
\r
4 * Copyright 1991 by Digital Equipment Corporation, Maynard,
\r
5 * Massachusetts. Enhancements Copyright
\r
6 * 1992-2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software
\r
9 * XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess,
\r
10 * which was written and is copyrighted by Wayne Christopher.
\r
12 * The following terms apply to Digital Equipment Corporation's copyright
\r
13 * interest in XBoard:
\r
14 * ------------------------------------------------------------------------
\r
15 * All Rights Reserved
\r
17 * Permission to use, copy, modify, and distribute this software and its
\r
18 * documentation for any purpose and without fee is hereby granted,
\r
19 * provided that the above copyright notice appear in all copies and that
\r
20 * both that copyright notice and this permission notice appear in
\r
21 * supporting documentation, and that the name of Digital not be
\r
22 * used in advertising or publicity pertaining to distribution of the
\r
23 * software without specific, written prior permission.
\r
25 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
\r
26 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
\r
27 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
\r
28 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
\r
29 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
\r
30 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
\r
32 * ------------------------------------------------------------------------
\r
34 * The following terms apply to the enhanced version of XBoard
\r
35 * distributed by the Free Software Foundation:
\r
36 * ------------------------------------------------------------------------
\r
38 * GNU XBoard is free software: you can redistribute it and/or modify
\r
39 * it under the terms of the GNU General Public License as published by
\r
40 * the Free Software Foundation, either version 3 of the License, or (at
\r
41 * your option) any later version.
\r
43 * GNU XBoard is distributed in the hope that it will be useful, but
\r
44 * WITHOUT ANY WARRANTY; without even the implied warranty of
\r
45 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
46 * General Public License for more details.
\r
48 * You should have received a copy of the GNU General Public License
\r
49 * along with this program. If not, see http://www.gnu.org/licenses/. *
\r
51 *------------------------------------------------------------------------
\r
52 ** See the file ChangeLog for a revision history. */
\r
54 // This file collects all patches for the JAWS version, so they can all be included in winboard.c
\r
55 // in one big swoop. At the bottom of this file you can read instructions for how to patch
\r
56 // WinBoard to work with JAWS with the aid of this file. Note that the code in this file
\r
57 // is for WinBoard 4.3 and later; for older WB versions you would have to throw out the
\r
58 // piece names for all pieces from Guard to Unicorn, #define ONE as '1', AAA as 'a',
\r
59 // BOARD_LEFT as 0, BOARD_RGHT and BOARD_HEIGHT as 8, and set holdingssizes to 0.
\r
60 // You will need to build with jaws.rc in stead of winboard.rc.
\r
62 // from common.h, but 'extern' added to it, so the actual declaraton can remain in backend.c
\r
64 extern long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement;
\r
67 // from moves.h, but no longer needed, as the new routines are all moved to winboard.c
\r
69 extern char* PieceToName P((ChessSquare p, int i));
\r
70 extern char* SquareToChar P((int Xpos));
\r
71 extern char* SquareToNum P((int Ypos));
\r
72 extern int CoordToNum P((char c));
\r
76 // from moves.c, added WinBoard_F piece types and ranks / files
\r
78 char *squareToChar[] = { "ay", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };
\r
80 char *squareToNum[] = {"naught", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
\r
82 char *ordinals[] = {"zeroth", "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "nineth"};
\r
84 char *pieceToName[] = {
\r
85 "White Pawn", "White Knight", "White Bishop", "White Rook", "White Queen",
\r
86 "White Guard", "White Elephant", "White Arch Bishop", "White Chancellor",
\r
87 "White General", "White Man", "White Cannon", "White Night Rider",
\r
88 "White Crowned Bishop", "White Crowned Rook", "White Grass Hopper", "White Veteran",
\r
89 "White Falcon", "White Amazon", "White Snake", "White Unicorn",
\r
91 "Black Pawn", "Black Knight", "Black Bishop", "Black Rook", "Black Queen",
\r
92 "Black Guard", "Black Elephant", "Black Arch Bishop", "Black Chancellor",
\r
93 "Black General", "Black Man", "Black Cannon", "Black Night Rider",
\r
94 "Black Crowned Bishop", "Black Crowned Rook", "Black Grass Hopper", "Black Veteran",
\r
95 "Black Falcon", "Black Amazon", "Black Snake", "Black Unicorn",
\r
103 if(isdigit(c)) return c - ONE;
\r
104 if(c >= 'a') return c - AAA;
\r
108 char* PieceToName(p, i)
\r
112 if(i) return pieceToName[(int) p];
\r
113 return pieceToName[(int) p]+6;
\r
116 char* SquareToChar(x)
\r
119 return squareToChar[x - BOARD_LEFT];
\r
122 char* SquareToNum(y)
\r
125 return squareToNum[y + (gameInfo.boardHeight < 10)];
\r
129 // from winboard.c: all new routines
\r
131 #include "jfwapi.h"
\r
134 typedef JFWAPI BOOL (WINAPI *PSAYSTRING)(LPCTSTR lpszStrinToSpeak, BOOL bInterrupt);
\r
136 PSAYSTRING RealSayString;
\r
138 VOID SayString(char *mess, BOOL flag)
\r
139 { // for debug file
\r
140 char buf[MSG_SIZ], *p;
\r
141 if(appData.debugMode) fprintf(debugFP, "SAY '%s'\n", mess);
\r
143 if(p = StrCaseStr(buf, "Xboard adjudication:")) {
\r
145 for(i=19; i>1; i--) p[i] = p[i-1];
\r
148 RealSayString(buf, flag);
\r
151 //static int fromX = 0, fromY = 0;
\r
152 static int oldFromX, oldFromY;
\r
153 static int timeflag;
\r
154 static int suppressClocks = 0;
\r
155 static int suppressOneKey = 0;
\r
159 { // to be called at beginning of WinMain, after InitApplication and InitInstance
\r
160 HINSTANCE hApi = LoadLibrary("jfwapi32.dll");
\r
162 DisplayInformation("Missing jfwapi32.dll");
\r
166 RealSayString = (PSAYSTRING)GetProcAddress(hApi, "JFWSayString");
\r
167 if(!RealSayString) {
\r
168 DisplayInformation("SayString returned a null pointer");
\r
173 // [HGM] kludge to reduce need for modification of winboard.c: mak tinyLayout menu identical
\r
174 // to standard layout, so that code for switching between them does not have to be deleted
\r
175 HMENU hmenu = GetMenu(hwndMain);
\r
178 menuBarText[0][5] = "&JAWS";
\r
179 for(i=0; i<7; i++) menuBarText[1][i] = menuBarText[0][i];
\r
180 for (i=0; menuBarText[tinyLayout][i]; i++) {
\r
181 ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP,
\r
182 (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]);
\r
184 DrawMenuBar(hwndMain);
\r
187 /* initialize cursor position */
\r
189 SetHighlights(fromX, fromY, -1, -1);
\r
190 DrawPosition(FALSE, NULL);
\r
191 oldFromX = oldFromY = -1;
\r
193 if(hwndConsole) SetFocus(hwndConsole);
\r
198 KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
200 ChessSquare currentPiece;
\r
201 char *piece, *xchar, *ynum ;
\r
204 if(fromX == -1 || fromY == -1) {
\r
205 fromX = BOARD_LEFT; fromY = 0;
\r
209 if(fromX == BOARD_RGHT+1) fromX -= 2; else
\r
210 if(fromX == BOARD_LEFT) { if(fromY >= BOARD_HEIGHT - gameInfo.holdingsSize) fromX -= 2; } else
\r
211 if(fromX > BOARD_LEFT) fromX--;
\r
214 if(fromX == BOARD_LEFT-2) fromX += 2; else
\r
215 if(fromX == BOARD_RGHT-1) { if(fromY < gameInfo.holdingsSize) fromX += 2; } else
\r
216 if(fromX < BOARD_RGHT-1) fromX++;
\r
219 if(fromX == BOARD_RGHT+1) { if(fromY < gameInfo.holdingsSize - 1) fromY++; } else
\r
220 if(fromY < BOARD_HEIGHT-1) fromY++;
\r
223 if(fromX == BOARD_LEFT-2) { if(fromY > BOARD_HEIGHT - gameInfo.holdingsSize) fromY--; } else
\r
224 if(fromY > 0) fromY--;
\r
227 SetHighlights(fromX, fromY, -1, -1);
\r
228 DrawPosition(FALSE, NULL);
\r
229 currentPiece = boards[currentMove][fromY][fromX];
\r
230 piece = PieceToName(currentPiece,1);
\r
231 if(currentPiece != EmptySquare) MessageBeep(currentPiece < (int)BlackPawn ? MB_OK : MB_ICONEXCLAMATION);
\r
232 if(fromX == BOARD_LEFT - 2) {
\r
233 SayString("black holdings", FALSE);
\r
234 if(currentPiece != EmptySquare) {
\r
236 n = boards[currentMove][fromY][1];
\r
237 sprintf(buf, "%d %s%s", n, piece+6, n == 1 ? "" : "s");
\r
238 SayString(buf, TRUE);
\r
241 if(fromX == BOARD_RGHT + 1) {
\r
242 SayString("white holdings", FALSE);
\r
243 if(currentPiece != EmptySquare) {
\r
245 n = boards[currentMove][fromY][BOARD_WIDTH-2];
\r
246 sprintf(buf, "%d %s%s", n, piece+6, n == 1 ? "" : "s");
\r
247 SayString(buf, TRUE);
\r
250 if(fromX >= BOARD_LEFT && fromX < BOARD_RGHT) {
\r
252 xchar = SquareToChar(fromX);
\r
253 ynum = SquareToNum(fromY);
\r
254 if(currentPiece != EmptySquare) {
\r
255 // SayString(piece[0] == 'W' ? "white" : "black", TRUE);
\r
256 sprintf(buf, "%s %s %s", piece, xchar, ynum);
\r
257 } else sprintf(buf, "%s %s", xchar, ynum);
\r
258 SayString(buf, TRUE);
\r
263 extern char castlingRights[MAX_MOVES][BOARD_SIZE];
\r
264 int PosFlags(int nr);
\r
267 int rf, ff, rt, ft;
\r
272 extern void ReadCallback P((Board board, int flags, ChessMove kind,
\r
273 int rf, int ff, int rt, int ft,
\r
274 VOIDSTAR closure));
\r
276 void ReadCallback(board, flags, kind, rf, ff, rt, ft, closure)
\r
280 int rf, ff, rt, ft;
\r
283 register ReadClosure *cl = (ReadClosure *) closure;
\r
284 ChessSquare possiblepiece;
\r
285 char *piece, *xchar, *ynum ;
\r
287 //if(appData.debugMode) fprintf(debugFP, "%c%c%c%c\n", ff+AAA, rf+ONE, ft+AAA, rt+ONE);
\r
288 if(cl->ff == ff && cl->rf == rf) {
\r
289 possiblepiece = board[rt][ft];
\r
290 if(possiblepiece != EmptySquare) {
\r
291 piece = PieceToName(possiblepiece,1);
\r
292 xchar = SquareToChar(ft);
\r
293 ynum = SquareToNum(rt);
\r
294 SayString(xchar , FALSE);
\r
295 SayString(ynum, FALSE);
\r
296 SayString(piece, FALSE);
\r
300 if(cl->ft == ft && cl->rt == rt) {
\r
301 possiblepiece = board[rf][ff];
\r
302 piece = PieceToName(possiblepiece,1);
\r
303 xchar = SquareToChar(ff);
\r
304 ynum = SquareToNum(rf);
\r
305 SayString(xchar , FALSE);
\r
306 SayString(ynum, FALSE);
\r
307 SayString(piece, FALSE);
\r
313 PossibleAttackMove()
\r
316 ChessSquare piece, victim;
\r
317 int removedSelectedPiece = 0, swapColor;
\r
319 //if(appData.debugMode) fprintf(debugFP, "PossibleAttackMove %d %d %d %d\n", fromX, fromY, oldFromX, oldFromY);
\r
320 if(fromY < 0 || fromY >= BOARD_HEIGHT) return;
\r
321 if(fromX < BOARD_LEFT || fromX >= BOARD_RGHT) { SayString("holdings",FALSE); return; }
\r
323 piece = boards[currentMove][fromY][fromX];
\r
324 if(piece == EmptySquare) { // if square is empty, try to substitute selected piece
\r
325 if(oldFromX >= 0 && oldFromY >= 0) {
\r
326 piece = boards[currentMove][oldFromY][oldFromX];
\r
327 boards[currentMove][oldFromY][oldFromX] = EmptySquare;
\r
328 removedSelectedPiece = 1;
\r
329 SayString("Your", FALSE);
\r
330 SayString(PieceToName(piece, 0), FALSE);
\r
331 SayString("would have", FALSE);
\r
332 } else { SayString("You must select a piece first", FALSE); return; }
\r
335 victim = boards[currentMove][fromY][fromX];
\r
336 boards[currentMove][fromY][fromX] = piece; // make sure piece is actally there
\r
337 SayString("possible captures from here are", FALSE);
\r
339 swapColor = piece < (int)BlackPawn && !WhiteOnMove(currentMove) ||
\r
340 piece >= (int)BlackPawn && WhiteOnMove(currentMove);
\r
341 cl.count = 0; cl.rf = fromY; cl.ff = fromX; cl.rt = cl.ft = -1;
\r
342 GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), EP_NONE,
\r
343 castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);
\r
344 if(cl.count == 0) SayString("None", FALSE);
\r
345 boards[currentMove][fromY][fromX] = victim; // repair
\r
347 if( removedSelectedPiece ) boards[currentMove][oldFromY][oldFromX] = piece;
\r
355 ChessSquare piece = EmptySquare, victim;
\r
357 if(fromY < 0 || fromY >= BOARD_HEIGHT) return;
\r
358 if(fromX < BOARD_LEFT || fromX >= BOARD_RGHT) { SayString("holdings",FALSE); return; }
\r
360 if(oldFromX >= 0 && oldFromY >= 0) { // if piece is selected, remove it
\r
361 piece = boards[currentMove][oldFromY][oldFromX];
\r
362 boards[currentMove][oldFromY][oldFromX] = EmptySquare;
\r
365 SayString("Pieces that can capture you are", FALSE);
\r
367 victim = boards[currentMove][fromY][fromX]; // put dummy piece on target square, to activate Pawn captures
\r
368 boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen;
\r
369 cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;
\r
370 GenLegal(boards[currentMove], PosFlags(currentMove+1), EP_NONE,
\r
371 castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);
\r
372 if(cl.count == 0) SayString("None", FALSE);
\r
374 SayString("You are defended by", FALSE);
\r
376 boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? BlackQueen : WhiteQueen;
\r
377 cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;
\r
378 GenLegal(boards[currentMove], PosFlags(currentMove), EP_NONE,
\r
379 castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);
\r
380 if(cl.count == 0) SayString("None", FALSE);
\r
381 boards[currentMove][fromY][fromX] = victim; // put back original occupant
\r
383 if(oldFromX >= 0 && oldFromY >= 0) { // put back possibl selected piece
\r
384 boards[currentMove][oldFromY][oldFromX] = piece;
\r
391 ChessSquare currentpiece;
\r
392 char *piece, *xchar, *ynum ;
\r
394 ynum = SquareToNum(fromY);
\r
396 if(fromY < 0) return;
\r
398 for (xPos=BOARD_LEFT; xPos<BOARD_RGHT; xPos++) {
\r
399 currentpiece = boards[currentMove][fromY][xPos];
\r
400 if(currentpiece != EmptySquare) {
\r
401 piece = PieceToName(currentpiece,1);
\r
402 xchar = SquareToChar(xPos);
\r
403 SayString(xchar , FALSE);
\r
404 SayString(ynum, FALSE);
\r
405 SayString(piece, FALSE);
\r
410 SayString("rank", FALSE);
\r
411 SayString(ynum, FALSE);
\r
412 SayString("empty", FALSE);
\r
419 ChessSquare currentpiece;
\r
420 char *piece, *xchar, *ynum ;
\r
422 xchar = SquareToChar(fromX);
\r
424 if(fromX < 0) return;
\r
426 for (yPos=0; yPos<BOARD_HEIGHT; yPos++) {
\r
427 currentpiece = boards[currentMove][yPos][fromX];
\r
428 if(currentpiece != EmptySquare) {
\r
429 piece = PieceToName(currentpiece,1);
\r
430 ynum = SquareToNum(yPos);
\r
431 SayString(xchar , FALSE);
\r
432 SayString(ynum, FALSE);
\r
433 SayString(piece, FALSE);
\r
438 SayString(xchar, FALSE);
\r
439 SayString("file empty", FALSE);
\r
446 ChessSquare currentpiece;
\r
447 char *piece, *xchar, *ynum ;
\r
450 if(fromX < 0 || fromY < 0) return;
\r
452 if(fromX < BOARD_RGHT-1 && fromY < BOARD_HEIGHT-1) {
\r
453 SayString("The diagnol squares to your upper right contain", FALSE);
\r
456 while(yPos<BOARD_HEIGHT && xPos<BOARD_RGHT) {
\r
457 currentpiece = boards[currentMove][yPos][xPos];
\r
458 piece = PieceToName(currentpiece,1);
\r
459 xchar = SquareToChar(xPos);
\r
460 ynum = SquareToNum(yPos);
\r
461 SayString(xchar , FALSE);
\r
462 SayString(ynum, FALSE);
\r
463 SayString(piece, FALSE);
\r
468 else SayString("There is no squares to your upper right", FALSE);
\r
470 if(fromX > BOARD_LEFT && fromY < BOARD_HEIGHT-1) {
\r
471 SayString("The diagnol squares to your upper left contain", FALSE);
\r
474 while(yPos<BOARD_HEIGHT && xPos>=BOARD_LEFT) {
\r
475 currentpiece = boards[currentMove][yPos][xPos];
\r
476 piece = PieceToName(currentpiece,1);
\r
477 xchar = SquareToChar(xPos);
\r
478 ynum = SquareToNum(yPos);
\r
479 SayString(xchar , FALSE);
\r
480 SayString(ynum, FALSE);
\r
481 SayString(piece, FALSE);
\r
486 else SayString("There is no squares to your upper left", FALSE);
\r
492 ChessSquare currentpiece;
\r
493 char *piece, *xchar, *ynum ;
\r
496 if(fromX < 0 || fromY < 0) return;
\r
498 if(fromX < BOARD_RGHT-1 && fromY > 0) {
\r
499 SayString("The diagnol squares to your lower right contain", FALSE);
\r
502 while(yPos>=0 && xPos<BOARD_RGHT) {
\r
503 currentpiece = boards[currentMove][yPos][xPos];
\r
504 piece = PieceToName(currentpiece,1);
\r
505 xchar = SquareToChar(xPos);
\r
506 ynum = SquareToNum(yPos);
\r
507 SayString(xchar , FALSE);
\r
508 SayString(ynum, FALSE);
\r
509 SayString(piece, FALSE);
\r
514 else SayString("There is no squares to your lower right", FALSE);
\r
516 if(fromX > BOARD_LEFT && fromY > 0) {
\r
517 SayString("The diagnol squares to your lower left contain", FALSE);
\r
520 while(yPos>=0 && xPos>=BOARD_LEFT) {
\r
521 currentpiece = boards[currentMove][yPos][xPos];
\r
522 piece = PieceToName(currentpiece,1);
\r
523 xchar = SquareToChar(xPos);
\r
524 ynum = SquareToNum(yPos);
\r
525 SayString(xchar , FALSE);
\r
526 SayString(ynum, FALSE);
\r
527 SayString(piece, FALSE);
\r
532 else SayString("There is no squares to your lower left", FALSE);
\r
538 ChessSquare currentpiece, oldpiece;
\r
539 char *piece, *xchar, *ynum ;
\r
541 oldpiece = boards[currentMove][fromY][fromX];
\r
542 if(oldpiece == WhiteKnight || oldpiece == BlackKnight)
\r
543 SayString("The possible squares a Knight could move to are", FALSE);
\r
545 SayString("The squares a Knight could possibly attack from are", FALSE);
\r
547 if (fromY+2 < BOARD_HEIGHT && fromX-1 >= BOARD_LEFT) {
\r
548 currentpiece = boards[currentMove][fromY+2][fromX-1];
\r
549 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
550 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
551 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
553 piece = PieceToName(currentpiece,1);
\r
554 xchar = SquareToChar(fromX-1);
\r
555 ynum = SquareToNum(fromY+2);
\r
556 SayString(xchar , FALSE);
\r
557 SayString(ynum, FALSE);
\r
558 SayString(piece, FALSE);
\r
562 if (fromY+2 < BOARD_HEIGHT && fromX+1 < BOARD_RGHT) {
\r
563 currentpiece = boards[currentMove][fromY+2][fromX+1];
\r
564 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
565 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
566 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
568 piece = PieceToName(currentpiece,1);
\r
569 xchar = SquareToChar(fromX+1);
\r
570 ynum = SquareToNum(fromY+2);
\r
571 SayString(xchar , FALSE);
\r
572 SayString(ynum, FALSE);
\r
573 SayString(piece, FALSE);
\r
577 if (fromY+1 < BOARD_HEIGHT && fromX+2 < BOARD_RGHT) {
\r
578 currentpiece = boards[currentMove][fromY+1][fromX+2];
\r
579 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
580 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
581 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
583 piece = PieceToName(currentpiece,1);
\r
584 xchar = SquareToChar(fromX+2);
\r
585 ynum = SquareToNum(fromY+1);
\r
586 SayString(xchar , FALSE);
\r
587 SayString(ynum, FALSE);
\r
588 SayString(piece, FALSE);
\r
592 if (fromY-1 >= 0 && fromX+2 < BOARD_RGHT) {
\r
593 currentpiece = boards[currentMove][fromY-1][fromX+2];
\r
594 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
595 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
596 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
598 piece = PieceToName(currentpiece,1);
\r
599 xchar = SquareToChar(fromX+2);
\r
600 ynum = SquareToNum(fromY-1);
\r
601 SayString(xchar , FALSE);
\r
602 SayString(ynum, FALSE);
\r
603 SayString(piece, FALSE);
\r
607 if (fromY-2 >= 0 && fromX+1 < BOARD_RGHT) {
\r
608 currentpiece = boards[currentMove][fromY-2][fromX+1];
\r
609 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
610 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
611 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
613 piece = PieceToName(currentpiece,1);
\r
614 xchar = SquareToChar(fromX+1);
\r
615 ynum = SquareToNum(fromY-2);
\r
616 SayString(xchar , FALSE);
\r
617 SayString(ynum, FALSE);
\r
618 SayString(piece, FALSE);
\r
622 if (fromY-2 >= 0 && fromX-1 >= BOARD_LEFT) {
\r
623 currentpiece = boards[currentMove][fromY-2][fromX-1];
\r
624 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
625 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
626 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
628 piece = PieceToName(currentpiece,1);
\r
629 xchar = SquareToChar(fromX-1);
\r
630 ynum = SquareToNum(fromY-2);
\r
631 SayString(xchar , FALSE);
\r
632 SayString(ynum, FALSE);
\r
633 SayString(piece, FALSE);
\r
637 if (fromY-1 >= 0 && fromX-2 >= BOARD_LEFT) {
\r
638 currentpiece = boards[currentMove][fromY-1][fromX-2];
\r
639 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
640 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
641 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
643 piece = PieceToName(currentpiece,1);
\r
644 xchar = SquareToChar(fromX-2);
\r
645 ynum = SquareToNum(fromY-1);
\r
646 SayString(xchar , FALSE);
\r
647 SayString(ynum, FALSE);
\r
648 SayString(piece, FALSE);
\r
652 if (fromY+1 < BOARD_HEIGHT && fromX-2 >= BOARD_LEFT) {
\r
653 currentpiece = boards[currentMove][fromY+1][fromX-2];
\r
654 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
655 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
656 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
658 piece = PieceToName(currentpiece,1);
\r
659 xchar = SquareToChar(fromX-2);
\r
660 ynum = SquareToNum(fromY+1);
\r
661 SayString(xchar , FALSE);
\r
662 SayString(ynum, FALSE);
\r
663 SayString(piece, FALSE);
\r
669 SayPieces(ChessSquare p)
\r
671 ChessSquare currentpiece;
\r
672 char *piece, *xchar, *ynum ;
\r
673 int yPos, xPos, count = 0;
\r
676 if(p == WhitePlay) SayString("White pieces", FALSE); else
\r
677 if(p == BlackPlay) SayString("Black pieces", FALSE); else
\r
678 if(p == EmptySquare) SayString("Pieces", FALSE); else {
\r
679 sprintf(buf, "%ss", PieceToName(p,1));
\r
680 SayString(buf, FALSE);
\r
682 SayString("are located", FALSE);
\r
683 for(yPos=0; yPos<BOARD_HEIGHT; yPos++) {
\r
684 for(xPos=BOARD_LEFT; xPos<BOARD_RGHT; xPos++) {
\r
685 currentpiece = boards[currentMove][yPos][xPos];
\r
686 if(p == BlackPlay && currentpiece >= BlackPawn && currentpiece <= BlackKing ||
\r
687 p == WhitePlay && currentpiece >= WhitePawn && currentpiece <= WhiteKing )
\r
688 piece = PieceToName(currentpiece,0);
\r
689 else if(p == EmptySquare && currentpiece != EmptySquare)
\r
690 piece = PieceToName(currentpiece,1);
\r
691 else if(p == currentpiece)
\r
695 if(count == 0) SayString("at", FALSE);
\r
696 xchar = SquareToChar(xPos);
\r
697 ynum = SquareToNum(yPos);
\r
698 SayString(xchar , FALSE);
\r
699 SayString(ynum, FALSE);
\r
700 if(piece) SayString(piece, FALSE);
\r
704 if(count == 0) SayString("nowhere", FALSE);
\r
710 ChessSquare currentpiece;
\r
711 char *piece, *xchar, *ynum ;
\r
712 if(fromX < BOARD_LEFT) { SayString("You strayed into the white holdings", FALSE); return; }
\r
713 if(fromX >= BOARD_RGHT) { SayString("You strayed into the black holdings", FALSE); return; }
\r
714 currentpiece = boards[currentMove][fromY][fromX];
\r
715 piece = PieceToName(currentpiece,1);
\r
716 ynum = SquareToNum(fromY);
\r
717 xchar = SquareToChar(fromX);
\r
718 SayString("Your current position is", FALSE);
\r
719 SayString(xchar, FALSE);
\r
720 SayString(ynum, FALSE);
\r
721 SayString(piece, FALSE);
\r
722 if((fromX-BOARD_LEFT) ^ fromY)
\r
723 SayString("on a dark square",FALSE);
\r
725 SayString("on a light square",FALSE);
\r
727 PossibleAttacked();
\r
735 ChessSquare currentpiece;
\r
736 char *piece, *xchar, *ynum ;
\r
738 if(gameInfo.holdingsWidth) {
\r
740 for(Ypos=0; Ypos<gameInfo.holdingsSize; Ypos++) {
\r
741 int n = boards[currentMove][Ypos][BOARD_WIDTH-2];
\r
742 if(n) { char buf[MSG_SIZ];
\r
743 if(!first++) SayString("white holds", FALSE);
\r
744 currentpiece = boards[currentMove][Ypos][BOARD_WIDTH-1];
\r
745 piece = PieceToName(currentpiece,0);
\r
746 sprintf(buf, "%d %s%s", n, piece, (n==1 ? "" : "s") );
\r
747 SayString(buf, FALSE);
\r
751 for(Ypos=BOARD_HEIGHT-1; Ypos>=BOARD_HEIGHT - gameInfo.holdingsSize; Ypos--) {
\r
752 int n = boards[currentMove][Ypos][1];
\r
753 if(n) { char buf[MSG_SIZ];
\r
754 if(!first++) SayString("black holds", FALSE);
\r
755 currentpiece = boards[currentMove][Ypos][0];
\r
756 piece = PieceToName(currentpiece,0);
\r
757 sprintf(buf, "%d %s%s", n, piece, (n==1 ? "" : "s") );
\r
758 SayString(buf, FALSE);
\r
763 for(Ypos=BOARD_HEIGHT-1; Ypos>=0; Ypos--) {
\r
764 ynum = ordinals[Ypos + (gameInfo.boardHeight < 10)];
\r
765 SayString(ynum, FALSE);
\r
766 SayString("rank", FALSE);
\r
767 for(Xpos=BOARD_LEFT; Xpos<BOARD_RGHT; Xpos++) {
\r
768 currentpiece = boards[currentMove][Ypos][Xpos];
\r
769 if(currentpiece != EmptySquare) {
\r
770 int count = 0, oldX = Xpos;
\r
772 piece = PieceToName(currentpiece,1);
\r
773 while(Xpos < BOARD_RGHT && boards[currentMove][Ypos][Xpos] == currentpiece)
\r
776 sprintf(buf, "%d %ss", count, piece);
\r
777 } else sprintf(buf, "%s", piece);
\r
779 SayString(buf, FALSE);
\r
781 int count = 0, oldX = Xpos;
\r
782 while(Xpos < BOARD_RGHT && boards[currentMove][Ypos][Xpos] == EmptySquare)
\r
784 if(Xpos == BOARD_RGHT && oldX == BOARD_LEFT)
\r
785 SayString("all", FALSE);
\r
789 sprintf(buf, "%d", count);
\r
790 SayString(buf, FALSE);
\r
794 SayString("empty", FALSE);
\r
804 if(gameMode == MachinePlaysBlack || gameMode == IcsPlayingBlack) {
\r
805 if(WhiteOnMove(currentMove))
\r
806 SayString("It is your turn", FALSE);
\r
807 else SayString("It is your opponents turn", FALSE);
\r
808 } else if(gameMode == MachinePlaysWhite || gameMode == IcsPlayingWhite) {
\r
809 if(WhiteOnMove(currentMove))
\r
810 SayString("It is your opponents turn", FALSE);
\r
811 else SayString("It is your turn", FALSE);
\r
813 if(WhiteOnMove(currentMove))
\r
814 SayString("White is on move here", FALSE);
\r
815 else SayString("Black is on move here", FALSE);
\r
821 SayMachineMove(int evenIfDuplicate)
\r
823 int len, xPos, yPos, moveNr, secondSpace = 0, castle = 0, n;
\r
824 ChessSquare currentpiece;
\r
825 char *piece, *xchar, *ynum, *p;
\r
826 char c, buf[MSG_SIZ], comment[MSG_SIZ];
\r
827 static char disambiguation[2];
\r
828 static int previousMove = 0;
\r
830 if(appData.debugMode) fprintf(debugFP, "Message = '%s'\n", messageText);
\r
831 if(gameMode == BeginningOfGame) return;
\r
832 if(messageText[0] == '[') return;
\r
834 if(isdigit(messageText[0])) { // message is move, possibly with thinking output
\r
835 int dotCount = 0, spaceCount = 0;
\r
836 sscanf(messageText, "%d", &moveNr);
\r
838 // [HGM] show: better extraction of move
\r
839 while (messageText[len] != NULLCHAR) {
\r
840 if(messageText[len] == '.' && spaceCount == 0) dotCount++;
\r
841 if(messageText[len] == ' ') { if(++spaceCount == 2) secondSpace = len; }
\r
842 if(messageText[len] == '{') { // we detected a comment
\r
843 if(isalpha(messageText[len+1]) ) sscanf(messageText+len, "{%[^}]}", comment);
\r
846 if(messageText[len] == '[') { // we detected thinking output
\r
847 int depth; float score=0; char c, lastMover = (dotCount == 3 ? 'B' : 'W');
\r
848 if(sscanf(messageText+len+1, "%d]%c%f", &depth, &c, &score) > 1) {
\r
849 if(c == ' ') { // if not explicitly specified, figure out source of thinking output
\r
851 case MachinePlaysWhite:
\r
852 case IcsPlayingWhite:
\r
854 case IcsPlayingBlack:
\r
855 case MachinePlaysBlack:
\r
861 if(c != lastMover) return; // line is thinking output of future move, ignore.
\r
862 if(2*moveNr - (dotCount < 2) == previousMove)
\r
863 return; // do not repeat same move; likely ponder output
\r
864 sprintf(buf, "score %s %d at %d ply",
\r
865 score > 0 ? "plus" : score < 0 ? "minus" : "",
\r
866 (int) (fabs(score)*100+0.5),
\r
868 SayString(buf, FALSE); // move + thinking output describing it; say it.
\r
870 while(messageText[len-1] == ' ') len--; // position just behind move;
\r
873 if(messageText[len] == '(') { // ICS time printed behind move
\r
874 while(messageText[len+1] && messageText[len] != ')') len++; // skip it
\r
878 if(secondSpace) len = secondSpace; // position behind move
\r
879 if(messageText[len-1] == '+' || messageText[len-1] == '#') { /* you are in checkmate */
\r
880 len--; // strip off check or mate indicator
\r
882 if(messageText[len-2] == '=') { /* promotion */
\r
883 len-=2; // strip off promotion piece
\r
884 SayString("promotion", FALSE);
\r
887 n = 2*moveNr - (dotCount < 2);
\r
889 if(previousMove != 2*moveNr + (dotCount > 1) || evenIfDuplicate) {
\r
891 previousMove = 2*moveNr + (dotCount > 1); // remember move nr of move last spoken
\r
892 sprintf(number, "%d", moveNr);
\r
894 yPos = CoordToNum(messageText[len-1]); /* turn char coords to ints */
\r
895 xPos = CoordToNum(messageText[len-2]);
\r
896 if(xPos < 0 || xPos > 11) return; // prevent crashes if no coord string available to speak
\r
897 if(yPos < 0 || yPos > 9) return;
\r
898 currentpiece = boards[n][yPos][xPos];
\r
899 piece = PieceToName(currentpiece,0);
\r
900 ynum = SquareToNum(yPos);
\r
901 xchar = SquareToChar(xPos);
\r
902 c = messageText[len-3];
\r
903 if(c == 'x') c = messageText[len-4];
\r
904 if(!isdigit(c) && c < 'a' && c != '@') c = 0;
\r
905 disambiguation[0] = c;
\r
906 SayString(WhiteOnMove(n) ? "Black" : "White", FALSE);
\r
907 SayString("move", FALSE);
\r
908 SayString(number, FALSE);
\r
909 // if(c==0 || c=='@') SayString("a", FALSE);
\r
910 // intercept castling moves
\r
911 p = StrStr(messageText, "O-O-O");
\r
912 if(p && p-messageText < len) {
\r
913 SayString("queen side castling",FALSE);
\r
916 p = StrStr(messageText, "O-O");
\r
917 if(p && p-messageText < len) {
\r
918 SayString("king side castling",FALSE);
\r
923 SayString(piece, FALSE);
\r
924 if(c == '@') SayString("dropped on", FALSE); else
\r
925 if(c) SayString(disambiguation, FALSE);
\r
926 SayString("to", FALSE);
\r
927 SayString(xchar, FALSE);
\r
928 SayString(ynum, FALSE);
\r
929 if(messageText[len-3] == 'x') {
\r
930 currentpiece = boards[n-1][yPos][xPos];
\r
931 if(currentpiece != EmptySquare) {
\r
932 piece = PieceToName(currentpiece,0);
\r
933 SayString("Capturing a",FALSE);
\r
934 SayString(piece, FALSE);
\r
935 } else SayString("Capturing onn passann",FALSE);
\r
937 if(messageText[len] == '+') SayString("check", FALSE); else
\r
938 if(messageText[len] == '#') {
\r
939 SayString("finishing off", FALSE);
\r
940 SayString(WhiteOnMove(n) ? "White" : "Black", FALSE);
\r
945 /* say comment after move, possibly with result */
\r
947 if(StrStr(messageText, " 1-0")) p = "white wins"; else
\r
948 if(StrStr(messageText, " 0-1")) p = "black wins"; else
\r
949 if(StrStr(messageText, " 1/2-1/2")) p = "game ends in a draw";
\r
952 if(!StrCaseStr(comment, "draw") &&
\r
953 !StrCaseStr(comment, "white") &&
\r
954 !StrCaseStr(comment, "black") ) {
\r
955 SayString(p, FALSE);
\r
956 SayString("due to", FALSE);
\r
959 SayString(comment, FALSE); // alphabetic comment (usually game end)
\r
960 } else if(p) SayString(p, FALSE);
\r
963 /* starts not with digit */
\r
964 if(StrCaseStr(messageText, "illegal")) PlayIcsUnfinishedSound();
\r
965 SayString(messageText, FALSE);
\r
973 char buf1[50], buf2[50];
\r
975 static long int lastWhiteTime, lastBlackTime;
\r
977 suppressClocks = 1; // if user is using alt+T command, no reason to display them
\r
978 if(abs(lastWhiteTime - whiteTimeRemaining) < 1000 && abs(lastBlackTime - blackTimeRemaining) < 1000)
\r
979 suppressClocks = 0; // back on after two requests in rapid succession
\r
980 sprintf(buf1, "%s", TimeString(whiteTimeRemaining));
\r
982 SayString("White's remaining time is", FALSE);
\r
983 SayString(str1, FALSE);
\r
984 sprintf(buf2, "%s", TimeString(blackTimeRemaining));
\r
986 SayString("Black's remaining time is", FALSE);
\r
987 SayString(str2, FALSE);
\r
988 lastWhiteTime = whiteTimeRemaining;
\r
989 lastBlackTime = blackTimeRemaining;
\r
993 Toggle(Boolean *b, char *mess)
\r
996 SayString(mess, FALSE);
\r
997 SayString("is now", FALSE);
\r
998 SayString(*b ? "on" : "off", FALSE);
\r
1001 /* handles keyboard moves in a click-click fashion */
\r
1003 KeyboardMove(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
1005 ChessSquare currentpiece;
\r
1008 static BOOLEAN sameAgain = FALSE;
\r
1009 switch (message) {
\r
1011 sameAgain = FALSE;
\r
1012 if(oldFromX == fromX && oldFromY == fromY) {
\r
1014 /* click on same square */
\r
1017 else if(oldFromX != -1) {
\r
1019 ChessSquare pdown, pup;
\r
1020 pdown = boards[currentMove][oldFromY][oldFromX];
\r
1021 pup = boards[currentMove][fromY][fromX];
\r
1023 if (gameMode == EditPosition ||
\r
1024 !((WhitePawn <= pdown && pdown <= WhiteKing &&
\r
1025 WhitePawn <= pup && pup <= WhiteKing) ||
\r
1026 (BlackPawn <= pdown && pdown <= BlackKing &&
\r
1027 BlackPawn <= pup && pup <= BlackKing))) {
\r
1028 /* EditPosition, empty square, or different color piece;
\r
1029 click-click move is possible */
\r
1031 if (IsPromotion(oldFromX, oldFromY, fromX, fromY)) {
\r
1032 if (appData.alwaysPromoteToQueen) {
\r
1033 UserMoveEvent(oldFromX, oldFromY, fromX, fromY, 'q');
\r
1036 toX = fromX; toY = fromY; fromX = oldFromX; fromY = oldFromY;
\r
1037 PromotionPopup(hwnd);
\r
1038 fromX = toX; fromY = toY;
\r
1042 UserMoveEvent(oldFromX, oldFromY, fromX, fromY, NULLCHAR);
\r
1044 oldFromX = oldFromY = -1;
\r
1049 /* First downclick, or restart on a square with same color piece */
\r
1050 if (OKToStartUserMove(fromX, fromY)) {
\r
1053 currentpiece = boards[currentMove][fromY][fromX];
\r
1054 piece = PieceToName(currentpiece,1);
\r
1055 SayString(piece, FALSE);
\r
1056 SayString("selected", FALSE);
\r
1059 oldFromX = oldFromY = -1;
\r
1064 if (oldFromX == fromX && oldFromY == fromY) {
\r
1065 /* Upclick on same square */
\r
1067 /* Clicked same square twice: abort click-click move */
\r
1068 oldFromX = oldFromY = -1;
\r
1069 currentpiece = boards[currentMove][fromY][fromX];
\r
1070 piece = PieceToName(currentpiece,0);
\r
1071 SayString(piece, FALSE);
\r
1072 SayString("unselected", FALSE);
\r
1080 { // return TRUE for times we want to announce
\r
1082 x = (x+50)/100; // tenth of seconds
\r
1083 if(x <= 100) return (x%10 == 0);
\r
1084 if(x <= 600) return (x%100 == 0);
\r
1085 if(x <= 6000) return (x%600 == 0);
\r
1086 return (x%3000 == 0);
\r
1090 if(isalpha((char)wParam)) {
\r
1091 /* capitals of any ind are intercepted and distinguished by left and right shift */
\r
1092 int mine = GetKeyState(VK_RSHIFT) < 0;
\r
1093 if(mine || GetKeyState(VK_LSHIFT) < 0) {
\r
1096 #define JAWS_ALT_INTERCEPT \
\r
1097 if(suppressOneKey) {\
\r
1098 suppressOneKey = 0;\
\r
1099 if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) break;\
\r
1101 if ((char)wParam == 022 && gameMode == EditPosition) { /* <Ctl R>. Pop up piece menu */\
\r
1102 POINT pt; int x, y;\
\r
1103 SquareToPos(fromY, fromX, &x, &y);\
\r
1104 pt.x = x; pt.y = y;\
\r
1105 if(gameInfo.variant != VariantShogi)\
\r
1106 MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\
\r
1108 MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\
\r
1112 #define JAWS_REPLAY \
\r
1113 case '\020': /* ctrl P */\
\r
1114 { char buf[MSG_SIZ];\
\r
1115 if(GetWindowText(hwnd, buf, MSG_SIZ-1))\
\r
1116 SayString(buf, FALSE);\
\r
1120 #define JAWS_KB_NAVIGATION \
\r
1124 if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) {\
\r
1125 /* Control + Alt + letter used for speaking piece positions */\
\r
1126 static int lastTime; static char lastChar;\
\r
1127 int mine = 0, time = GetTickCount(); char c;\
\r
1129 if((char)wParam == lastChar && time-lastTime < 250) mine = 1;\
\r
1130 lastChar = wParam; lastTime = time;\
\r
1133 if(gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) mine = !mine;\
\r
1135 if(ToLower(c) == 'x') {\
\r
1136 SayPieces(mine ? WhitePlay : BlackPlay);\
\r
1137 suppressOneKey = 1;\
\r
1140 if(CharToPiece(c) != EmptySquare) {\
\r
1141 SayPieces(CharToPiece(mine ? ToUpper(c) : ToLower(c)));\
\r
1142 suppressOneKey = 1;\
\r
1147 switch (wParam) {\
\r
1152 KeyboardEvent(hwnd, message, wParam, lParam);\
\r
1155 KeyboardMove(hwnd, message, wParam, lParam);\
\r
1160 switch (wParam) {\
\r
1162 KeyboardMove(hwnd, message, wParam, lParam);\
\r
1167 #define JAWS_MENU_ITEMS \
\r
1168 case IDM_PossibleAttackMove: /*What can I possible attack from here */\
\r
1169 PossibleAttackMove();\
\r
1172 case IDM_PossibleAttacked: /*what can possible attack this square*/\
\r
1173 PossibleAttacked();\
\r
1176 case IDM_ReadRow: /* Read the current row of pieces */\
\r
1180 case IDM_ReadColumn: /* Read the current column of pieces */\
\r
1184 case IDM_SayCurrentPos: /* Say current position including color */\
\r
1188 case IDM_SayAllBoard: /* Say the whole board from bottom to top */\
\r
1192 case IDM_SayMachineMove: /* Say the last move made */\
\r
1194 SayMachineMove(1);\
\r
1197 case IDM_SayUpperDiagnols: /* Says the diagnol positions above you */\
\r
1198 SayUpperDiagnols();\
\r
1201 case IDM_SayLowerDiagnols: /* Say the diagnol positions below you */\
\r
1202 SayLowerDiagnols();\
\r
1205 case IDM_SayBlackPieces: /*Say the opponents pieces */\
\r
1206 SayPieces(BlackPlay);\
\r
1209 case IDM_SayWhitePieces: /*Say the opponents pieces */\
\r
1210 SayPieces(WhitePlay);\
\r
1213 case IDM_SayClockTime: /*Say the clock time */\
\r
1217 case IDM_SayWhosTurn: /* Say whos turn it its */\
\r
1221 case IDM_SayKnightMoves: /* Say Knights (L-shaped) move */\
\r
1222 SayKnightMoves();\
\r
1225 case OPT_PonderNextMove: /* Toggle option setting */\
\r
1226 Toggle(&appData.ponderNextMove, "ponder");\
\r
1229 case OPT_AnimateMoving: /* Toggle option setting */\
\r
1230 Toggle(&appData.animate, "animate moving");\
\r
1233 case OPT_AutoFlag: /* Toggle option setting */\
\r
1234 Toggle(&appData.autoCallFlag, "auto flag");\
\r
1237 case OPT_AlwaysQueen: /* Toggle option setting */\
\r
1238 Toggle(&appData.alwaysPromoteToQueen, "always promote to queen");\
\r
1241 case OPT_TestLegality: /* Toggle option setting */\
\r
1242 Toggle(&appData.testLegality, "legality testing");\
\r
1245 case OPT_HideThinkFromHuman: /* Toggle option setting */\
\r
1246 Toggle(&appData.hideThinkingFromHuman, "hide thinking");\
\r
1247 ShowThinkingEvent();\
\r
1250 case OPT_SaveExtPGN: /* Toggle option setting */\
\r
1251 Toggle(&appData.saveExtendedInfoInPGN, "extended P G N info");\
\r
1254 case OPT_ExtraInfoInMoveHistory: /* Toggle option setting */\
\r
1255 Toggle(&appData.showEvalInMoveHistory, "extra info in move histoty");\
\r
1260 #define JAWS_INIT if (!InitJAWS()) return (FALSE);
\r
1262 #define JAWS_DELETE(X)
\r
1264 #define JAWS_SILENCE if(suppressClocks) return;
\r
1266 #define SAY(S) SayString((S), FALSE)
\r
1268 #define SAYMACHINEMOVE() SayMachineMove(0)
\r
1270 // After inclusion of this file somewhere early in winboard.c, the remaining part of the patch
\r
1271 // is scattered over winboard.c for actually calling the routines.
\r
1273 // * move fromX, fromY declaration to front, before incusion of this file. (Can be permanent change in winboard.c.)
\r
1274 // * call InitJAWS(), after calling InitIntance(). (Using JAWS_INIT macro)
\r
1275 // * add keyboard cases in main switch of WndProc, though JAWS_KB_NAVIGATION above, e.g. before WM_CHAR case.
\r
1276 // * change the WM_CHAR case of same switch from "if(appData.icsActive)" to "if(appData.icsActive JAWS_IF_TAB)"
\r
1277 // * add new menu cases in WM_COMMAND case of WndProc, e.g. before IDM_Forward. (throug macro defined above)
\r
1278 // * add SAYMACHINEMOVE(); at the end of DisplayMessage();
\r
1279 // * add SAY("board"); in WM_CHAR case of ConsoleTextSubclass, just before "SetFocus(buttondesc..."
\r