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
7 * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
\r
8 * 2007, 2008, 2009 Free Software Foundation, Inc.
\r
10 * XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess,
\r
11 * which was written and is copyrighted by Wayne Christopher.
\r
13 * The following terms apply to Digital Equipment Corporation's copyright
\r
14 * interest in XBoard:
\r
15 * ------------------------------------------------------------------------
\r
16 * All Rights Reserved
\r
18 * Permission to use, copy, modify, and distribute this software and its
\r
19 * documentation for any purpose and without fee is hereby granted,
\r
20 * provided that the above copyright notice appear in all copies and that
\r
21 * both that copyright notice and this permission notice appear in
\r
22 * supporting documentation, and that the name of Digital not be
\r
23 * used in advertising or publicity pertaining to distribution of the
\r
24 * software without specific, written prior permission.
\r
26 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
\r
27 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
\r
28 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
\r
29 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
\r
30 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
\r
31 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
\r
33 * ------------------------------------------------------------------------
\r
35 * The following terms apply to the enhanced version of XBoard
\r
36 * distributed by the Free Software Foundation:
\r
37 * ------------------------------------------------------------------------
\r
39 * GNU XBoard is free software: you can redistribute it and/or modify
\r
40 * it under the terms of the GNU General Public License as published by
\r
41 * the Free Software Foundation, either version 3 of the License, or (at
\r
42 * your option) any later version.
\r
44 * GNU XBoard is distributed in the hope that it will be useful, but
\r
45 * WITHOUT ANY WARRANTY; without even the implied warranty of
\r
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
47 * General Public License for more details.
\r
49 * You should have received a copy of the GNU General Public License
\r
50 * along with this program. If not, see http://www.gnu.org/licenses/. *
\r
52 *------------------------------------------------------------------------
\r
53 ** See the file ChangeLog for a revision history. */
\r
55 // This file collects all patches for the JAWS version, so they can all be included in winboard.c
\r
56 // in one big swoop. At the bottom of this file you can read instructions for how to patch
\r
57 // WinBoard to work with JAWS with the aid of this file. Note that the code in this file
\r
58 // is for WinBoard 4.3 and later; for older WB versions you would have to throw out the
\r
59 // piece names for all pieces from Guard to Unicorn, #define ONE as '1', AAA as 'a',
\r
60 // BOARD_LEFT as 0, BOARD_RGHT and BOARD_HEIGHT as 8, and set holdingssizes to 0.
\r
61 // You will need to build with jaws.rc in stead of winboard.rc.
\r
63 // from common.h, but 'extern' added to it, so the actual declaraton can remain in backend.c
\r
65 extern long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement;
\r
68 // from moves.h, but no longer needed, as the new routines are all moved to winboard.c
\r
70 extern char* PieceToName P((ChessSquare p, int i));
\r
71 extern char* SquareToChar P((int Xpos));
\r
72 extern char* SquareToNum P((int Ypos));
\r
73 extern int CoordToNum P((char c));
\r
77 // from moves.c, added WinBoard_F piece types and ranks / files
\r
79 char *squareToChar[] = { "ay", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };
\r
81 char *squareToNum[] = {"naught", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
\r
83 char *ordinals[] = {"zeroth", "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "nineth"};
\r
85 char *pieceToName[] = {
\r
86 "White Pawn", "White Knight", "White Bishop", "White Rook", "White Queen",
\r
87 "White Guard", "White Elephant", "White Arch Bishop", "White Chancellor",
\r
88 "White General", "White Man", "White Cannon", "White Night Rider",
\r
89 "White Crowned Bishop", "White Crowned Rook", "White Grass Hopper", "White Veteran",
\r
90 "White Falcon", "White Amazon", "White Snake", "White Unicorn",
\r
92 "Black Pawn", "Black Knight", "Black Bishop", "Black Rook", "Black Queen",
\r
93 "Black Guard", "Black Elephant", "Black Arch Bishop", "Black Chancellor",
\r
94 "Black General", "Black Man", "Black Cannon", "Black Night Rider",
\r
95 "Black Crowned Bishop", "Black Crowned Rook", "Black Grass Hopper", "Black Veteran",
\r
96 "Black Falcon", "Black Amazon", "Black Snake", "Black Unicorn",
\r
104 if(isdigit(c)) return c - ONE;
\r
105 if(c >= 'a') return c - AAA;
\r
109 char* PieceToName(p, i)
\r
113 if(i) return pieceToName[(int) p];
\r
114 return pieceToName[(int) p]+6;
\r
117 char* SquareToChar(x)
\r
120 return squareToChar[x - BOARD_LEFT];
\r
123 char* SquareToNum(y)
\r
126 return squareToNum[y + (gameInfo.boardHeight < 10)];
\r
130 // from winboard.c: all new routines
\r
132 #include "jfwapi.h"
\r
135 typedef JFWAPI BOOL (WINAPI *PSAYSTRING)(LPCTSTR lpszStrinToSpeak, BOOL bInterrupt);
\r
137 PSAYSTRING RealSayString;
\r
139 VOID SayString(char *mess, BOOL flag)
\r
140 { // for debug file
\r
141 char buf[MSG_SIZ], *p;
\r
142 if(appData.debugMode) fprintf(debugFP, "SAY '%s'\n", mess);
\r
144 if(p = StrCaseStr(buf, "Xboard adjudication:")) {
\r
146 for(i=19; i>1; i--) p[i] = p[i-1];
\r
149 RealSayString(buf, flag);
\r
152 //static int fromX = 0, fromY = 0;
\r
153 static int oldFromX, oldFromY;
\r
154 static int timeflag;
\r
155 static int suppressClocks = 0;
\r
156 static int suppressOneKey = 0;
\r
160 { // to be called at beginning of WinMain, after InitApplication and InitInstance
\r
161 HINSTANCE hApi = LoadLibrary("jfwapi32.dll");
\r
163 DisplayInformation("Missing jfwapi32.dll");
\r
167 RealSayString = (PSAYSTRING)GetProcAddress(hApi, "JFWSayString");
\r
168 if(!RealSayString) {
\r
169 DisplayInformation("SayString returned a null pointer");
\r
174 // [HGM] kludge to reduce need for modification of winboard.c: mak tinyLayout menu identical
\r
175 // to standard layout, so that code for switching between them does not have to be deleted
\r
176 HMENU hmenu = GetMenu(hwndMain);
\r
179 menuBarText[0][5] = "&JAWS";
\r
180 for(i=0; i<7; i++) menuBarText[1][i] = menuBarText[0][i];
\r
181 for (i=0; menuBarText[tinyLayout][i]; i++) {
\r
182 ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP,
\r
183 (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]);
\r
185 DrawMenuBar(hwndMain);
\r
188 /* initialize cursor position */
\r
190 SetHighlights(fromX, fromY, -1, -1);
\r
191 DrawPosition(FALSE, NULL);
\r
192 oldFromX = oldFromY = -1;
\r
194 if(hwndConsole) SetFocus(hwndConsole);
\r
199 KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
201 ChessSquare currentPiece;
\r
202 char *piece, *xchar, *ynum ;
\r
205 if(fromX == -1 || fromY == -1) {
\r
206 fromX = BOARD_LEFT; fromY = 0;
\r
210 if(fromX == BOARD_RGHT+1) fromX -= 2; else
\r
211 if(fromX == BOARD_LEFT) { if(fromY >= BOARD_HEIGHT - gameInfo.holdingsSize) fromX -= 2; } else
\r
212 if(fromX > BOARD_LEFT) fromX--;
\r
215 if(fromX == BOARD_LEFT-2) fromX += 2; else
\r
216 if(fromX == BOARD_RGHT-1) { if(fromY < gameInfo.holdingsSize) fromX += 2; } else
\r
217 if(fromX < BOARD_RGHT-1) fromX++;
\r
220 if(fromX == BOARD_RGHT+1) { if(fromY < gameInfo.holdingsSize - 1) fromY++; } else
\r
221 if(fromY < BOARD_HEIGHT-1) fromY++;
\r
224 if(fromX == BOARD_LEFT-2) { if(fromY > BOARD_HEIGHT - gameInfo.holdingsSize) fromY--; } else
\r
225 if(fromY > 0) fromY--;
\r
228 SetHighlights(fromX, fromY, -1, -1);
\r
229 DrawPosition(FALSE, NULL);
\r
230 currentPiece = boards[currentMove][fromY][fromX];
\r
231 piece = PieceToName(currentPiece,1);
\r
232 if(currentPiece != EmptySquare) MessageBeep(currentPiece < (int)BlackPawn ? MB_OK : MB_ICONEXCLAMATION);
\r
233 if(fromX == BOARD_LEFT - 2) {
\r
234 SayString("black holdings", FALSE);
\r
235 if(currentPiece != EmptySquare) {
\r
237 n = boards[currentMove][fromY][1];
\r
238 sprintf(buf, "%d %s%s", n, piece+6, n == 1 ? "" : "s");
\r
239 SayString(buf, TRUE);
\r
242 if(fromX == BOARD_RGHT + 1) {
\r
243 SayString("white holdings", FALSE);
\r
244 if(currentPiece != EmptySquare) {
\r
246 n = boards[currentMove][fromY][BOARD_WIDTH-2];
\r
247 sprintf(buf, "%d %s%s", n, piece+6, n == 1 ? "" : "s");
\r
248 SayString(buf, TRUE);
\r
251 if(fromX >= BOARD_LEFT && fromX < BOARD_RGHT) {
\r
253 xchar = SquareToChar(fromX);
\r
254 ynum = SquareToNum(fromY);
\r
255 if(currentPiece != EmptySquare) {
\r
256 // SayString(piece[0] == 'W' ? "white" : "black", TRUE);
\r
257 sprintf(buf, "%s %s %s", piece, xchar, ynum);
\r
258 } else sprintf(buf, "%s %s", xchar, ynum);
\r
259 SayString(buf, TRUE);
\r
264 extern char castlingRights[MAX_MOVES][BOARD_SIZE];
\r
265 int PosFlags(int nr);
\r
268 int rf, ff, rt, ft;
\r
273 extern void ReadCallback P((Board board, int flags, ChessMove kind,
\r
274 int rf, int ff, int rt, int ft,
\r
275 VOIDSTAR closure));
\r
277 void ReadCallback(board, flags, kind, rf, ff, rt, ft, closure)
\r
281 int rf, ff, rt, ft;
\r
284 register ReadClosure *cl = (ReadClosure *) closure;
\r
285 ChessSquare possiblepiece;
\r
286 char *piece, *xchar, *ynum ;
\r
288 //if(appData.debugMode) fprintf(debugFP, "%c%c%c%c\n", ff+AAA, rf+ONE, ft+AAA, rt+ONE);
\r
289 if(cl->ff == ff && cl->rf == rf) {
\r
290 possiblepiece = board[rt][ft];
\r
291 if(possiblepiece != EmptySquare) {
\r
292 piece = PieceToName(possiblepiece,1);
\r
293 xchar = SquareToChar(ft);
\r
294 ynum = SquareToNum(rt);
\r
295 SayString(xchar , FALSE);
\r
296 SayString(ynum, FALSE);
\r
297 SayString(piece, FALSE);
\r
301 if(cl->ft == ft && cl->rt == rt) {
\r
302 possiblepiece = board[rf][ff];
\r
303 piece = PieceToName(possiblepiece,1);
\r
304 xchar = SquareToChar(ff);
\r
305 ynum = SquareToNum(rf);
\r
306 SayString(xchar , FALSE);
\r
307 SayString(ynum, FALSE);
\r
308 SayString(piece, FALSE);
\r
314 PossibleAttackMove()
\r
317 ChessSquare piece, victim;
\r
318 int removedSelectedPiece = 0, swapColor;
\r
320 //if(appData.debugMode) fprintf(debugFP, "PossibleAttackMove %d %d %d %d\n", fromX, fromY, oldFromX, oldFromY);
\r
321 if(fromY < 0 || fromY >= BOARD_HEIGHT) return;
\r
322 if(fromX < BOARD_LEFT || fromX >= BOARD_RGHT) { SayString("holdings",FALSE); return; }
\r
324 piece = boards[currentMove][fromY][fromX];
\r
325 if(piece == EmptySquare) { // if square is empty, try to substitute selected piece
\r
326 if(oldFromX >= 0 && oldFromY >= 0) {
\r
327 piece = boards[currentMove][oldFromY][oldFromX];
\r
328 boards[currentMove][oldFromY][oldFromX] = EmptySquare;
\r
329 removedSelectedPiece = 1;
\r
330 SayString("Your", FALSE);
\r
331 SayString(PieceToName(piece, 0), FALSE);
\r
332 SayString("would have", FALSE);
\r
333 } else { SayString("You must select a piece first", FALSE); return; }
\r
336 victim = boards[currentMove][fromY][fromX];
\r
337 boards[currentMove][fromY][fromX] = piece; // make sure piece is actally there
\r
338 SayString("possible captures from here are", FALSE);
\r
340 swapColor = piece < (int)BlackPawn && !WhiteOnMove(currentMove) ||
\r
341 piece >= (int)BlackPawn && WhiteOnMove(currentMove);
\r
342 cl.count = 0; cl.rf = fromY; cl.ff = fromX; cl.rt = cl.ft = -1;
\r
343 GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), EP_NONE,
\r
344 castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);
\r
345 if(cl.count == 0) SayString("None", FALSE);
\r
346 boards[currentMove][fromY][fromX] = victim; // repair
\r
348 if( removedSelectedPiece ) boards[currentMove][oldFromY][oldFromX] = piece;
\r
356 ChessSquare piece = EmptySquare, victim;
\r
358 if(fromY < 0 || fromY >= BOARD_HEIGHT) return;
\r
359 if(fromX < BOARD_LEFT || fromX >= BOARD_RGHT) { SayString("holdings",FALSE); return; }
\r
361 if(oldFromX >= 0 && oldFromY >= 0) { // if piece is selected, remove it
\r
362 piece = boards[currentMove][oldFromY][oldFromX];
\r
363 boards[currentMove][oldFromY][oldFromX] = EmptySquare;
\r
366 SayString("Pieces that can capture you are", FALSE);
\r
368 victim = boards[currentMove][fromY][fromX]; // put dummy piece on target square, to activate Pawn captures
\r
369 boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen;
\r
370 cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;
\r
371 GenLegal(boards[currentMove], PosFlags(currentMove+1), EP_NONE,
\r
372 castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);
\r
373 if(cl.count == 0) SayString("None", FALSE);
\r
375 SayString("You are defended by", FALSE);
\r
377 boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? BlackQueen : WhiteQueen;
\r
378 cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;
\r
379 GenLegal(boards[currentMove], PosFlags(currentMove), EP_NONE,
\r
380 castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);
\r
381 if(cl.count == 0) SayString("None", FALSE);
\r
382 boards[currentMove][fromY][fromX] = victim; // put back original occupant
\r
384 if(oldFromX >= 0 && oldFromY >= 0) { // put back possibl selected piece
\r
385 boards[currentMove][oldFromY][oldFromX] = piece;
\r
392 ChessSquare currentpiece;
\r
393 char *piece, *xchar, *ynum ;
\r
395 ynum = SquareToNum(fromY);
\r
397 if(fromY < 0) return;
\r
399 for (xPos=BOARD_LEFT; xPos<BOARD_RGHT; xPos++) {
\r
400 currentpiece = boards[currentMove][fromY][xPos];
\r
401 if(currentpiece != EmptySquare) {
\r
402 piece = PieceToName(currentpiece,1);
\r
403 xchar = SquareToChar(xPos);
\r
404 SayString(xchar , FALSE);
\r
405 SayString(ynum, FALSE);
\r
406 SayString(piece, FALSE);
\r
411 SayString("rank", FALSE);
\r
412 SayString(ynum, FALSE);
\r
413 SayString("empty", FALSE);
\r
420 ChessSquare currentpiece;
\r
421 char *piece, *xchar, *ynum ;
\r
423 xchar = SquareToChar(fromX);
\r
425 if(fromX < 0) return;
\r
427 for (yPos=0; yPos<BOARD_HEIGHT; yPos++) {
\r
428 currentpiece = boards[currentMove][yPos][fromX];
\r
429 if(currentpiece != EmptySquare) {
\r
430 piece = PieceToName(currentpiece,1);
\r
431 ynum = SquareToNum(yPos);
\r
432 SayString(xchar , FALSE);
\r
433 SayString(ynum, FALSE);
\r
434 SayString(piece, FALSE);
\r
439 SayString(xchar, FALSE);
\r
440 SayString("file empty", FALSE);
\r
447 ChessSquare currentpiece;
\r
448 char *piece, *xchar, *ynum ;
\r
451 if(fromX < 0 || fromY < 0) return;
\r
453 if(fromX < BOARD_RGHT-1 && fromY < BOARD_HEIGHT-1) {
\r
454 SayString("The diagnol squares to your upper right contain", FALSE);
\r
457 while(yPos<BOARD_HEIGHT && xPos<BOARD_RGHT) {
\r
458 currentpiece = boards[currentMove][yPos][xPos];
\r
459 piece = PieceToName(currentpiece,1);
\r
460 xchar = SquareToChar(xPos);
\r
461 ynum = SquareToNum(yPos);
\r
462 SayString(xchar , FALSE);
\r
463 SayString(ynum, FALSE);
\r
464 SayString(piece, FALSE);
\r
469 else SayString("There is no squares to your upper right", FALSE);
\r
471 if(fromX > BOARD_LEFT && fromY < BOARD_HEIGHT-1) {
\r
472 SayString("The diagnol squares to your upper left contain", FALSE);
\r
475 while(yPos<BOARD_HEIGHT && xPos>=BOARD_LEFT) {
\r
476 currentpiece = boards[currentMove][yPos][xPos];
\r
477 piece = PieceToName(currentpiece,1);
\r
478 xchar = SquareToChar(xPos);
\r
479 ynum = SquareToNum(yPos);
\r
480 SayString(xchar , FALSE);
\r
481 SayString(ynum, FALSE);
\r
482 SayString(piece, FALSE);
\r
487 else SayString("There is no squares to your upper left", FALSE);
\r
493 ChessSquare currentpiece;
\r
494 char *piece, *xchar, *ynum ;
\r
497 if(fromX < 0 || fromY < 0) return;
\r
499 if(fromX < BOARD_RGHT-1 && fromY > 0) {
\r
500 SayString("The diagnol squares to your lower right contain", FALSE);
\r
503 while(yPos>=0 && xPos<BOARD_RGHT) {
\r
504 currentpiece = boards[currentMove][yPos][xPos];
\r
505 piece = PieceToName(currentpiece,1);
\r
506 xchar = SquareToChar(xPos);
\r
507 ynum = SquareToNum(yPos);
\r
508 SayString(xchar , FALSE);
\r
509 SayString(ynum, FALSE);
\r
510 SayString(piece, FALSE);
\r
515 else SayString("There is no squares to your lower right", FALSE);
\r
517 if(fromX > BOARD_LEFT && fromY > 0) {
\r
518 SayString("The diagnol squares to your lower left contain", FALSE);
\r
521 while(yPos>=0 && xPos>=BOARD_LEFT) {
\r
522 currentpiece = boards[currentMove][yPos][xPos];
\r
523 piece = PieceToName(currentpiece,1);
\r
524 xchar = SquareToChar(xPos);
\r
525 ynum = SquareToNum(yPos);
\r
526 SayString(xchar , FALSE);
\r
527 SayString(ynum, FALSE);
\r
528 SayString(piece, FALSE);
\r
533 else SayString("There is no squares to your lower left", FALSE);
\r
539 ChessSquare currentpiece, oldpiece;
\r
540 char *piece, *xchar, *ynum ;
\r
542 oldpiece = boards[currentMove][fromY][fromX];
\r
543 if(oldpiece == WhiteKnight || oldpiece == BlackKnight)
\r
544 SayString("The possible squares a Knight could move to are", FALSE);
\r
546 SayString("The squares a Knight could possibly attack from are", FALSE);
\r
548 if (fromY+2 < BOARD_HEIGHT && fromX-1 >= BOARD_LEFT) {
\r
549 currentpiece = boards[currentMove][fromY+2][fromX-1];
\r
550 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
551 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
552 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
554 piece = PieceToName(currentpiece,1);
\r
555 xchar = SquareToChar(fromX-1);
\r
556 ynum = SquareToNum(fromY+2);
\r
557 SayString(xchar , FALSE);
\r
558 SayString(ynum, FALSE);
\r
559 SayString(piece, FALSE);
\r
563 if (fromY+2 < BOARD_HEIGHT && fromX+1 < BOARD_RGHT) {
\r
564 currentpiece = boards[currentMove][fromY+2][fromX+1];
\r
565 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
566 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
567 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
569 piece = PieceToName(currentpiece,1);
\r
570 xchar = SquareToChar(fromX+1);
\r
571 ynum = SquareToNum(fromY+2);
\r
572 SayString(xchar , FALSE);
\r
573 SayString(ynum, FALSE);
\r
574 SayString(piece, FALSE);
\r
578 if (fromY+1 < BOARD_HEIGHT && fromX+2 < BOARD_RGHT) {
\r
579 currentpiece = boards[currentMove][fromY+1][fromX+2];
\r
580 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
581 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
582 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
584 piece = PieceToName(currentpiece,1);
\r
585 xchar = SquareToChar(fromX+2);
\r
586 ynum = SquareToNum(fromY+1);
\r
587 SayString(xchar , FALSE);
\r
588 SayString(ynum, FALSE);
\r
589 SayString(piece, FALSE);
\r
593 if (fromY-1 >= 0 && fromX+2 < BOARD_RGHT) {
\r
594 currentpiece = boards[currentMove][fromY-1][fromX+2];
\r
595 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
596 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
597 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
599 piece = PieceToName(currentpiece,1);
\r
600 xchar = SquareToChar(fromX+2);
\r
601 ynum = SquareToNum(fromY-1);
\r
602 SayString(xchar , FALSE);
\r
603 SayString(ynum, FALSE);
\r
604 SayString(piece, FALSE);
\r
608 if (fromY-2 >= 0 && fromX+1 < BOARD_RGHT) {
\r
609 currentpiece = boards[currentMove][fromY-2][fromX+1];
\r
610 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
611 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
612 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
614 piece = PieceToName(currentpiece,1);
\r
615 xchar = SquareToChar(fromX+1);
\r
616 ynum = SquareToNum(fromY-2);
\r
617 SayString(xchar , FALSE);
\r
618 SayString(ynum, FALSE);
\r
619 SayString(piece, FALSE);
\r
623 if (fromY-2 >= 0 && fromX-1 >= BOARD_LEFT) {
\r
624 currentpiece = boards[currentMove][fromY-2][fromX-1];
\r
625 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
626 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
627 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
629 piece = PieceToName(currentpiece,1);
\r
630 xchar = SquareToChar(fromX-1);
\r
631 ynum = SquareToNum(fromY-2);
\r
632 SayString(xchar , FALSE);
\r
633 SayString(ynum, FALSE);
\r
634 SayString(piece, FALSE);
\r
638 if (fromY-1 >= 0 && fromX-2 >= BOARD_LEFT) {
\r
639 currentpiece = boards[currentMove][fromY-1][fromX-2];
\r
640 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
641 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
642 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
644 piece = PieceToName(currentpiece,1);
\r
645 xchar = SquareToChar(fromX-2);
\r
646 ynum = SquareToNum(fromY-1);
\r
647 SayString(xchar , FALSE);
\r
648 SayString(ynum, FALSE);
\r
649 SayString(piece, FALSE);
\r
653 if (fromY+1 < BOARD_HEIGHT && fromX-2 >= BOARD_LEFT) {
\r
654 currentpiece = boards[currentMove][fromY+1][fromX-2];
\r
655 if(((oldpiece == WhiteKnight) && (currentpiece > WhiteKing))
\r
656 || ((oldpiece == BlackKnight) && (currentpiece < BlackPawn || currentpiece == EmptySquare))
\r
657 || (oldpiece == EmptySquare) && (currentpiece == WhiteKnight || currentpiece == BlackKnight))
\r
659 piece = PieceToName(currentpiece,1);
\r
660 xchar = SquareToChar(fromX-2);
\r
661 ynum = SquareToNum(fromY+1);
\r
662 SayString(xchar , FALSE);
\r
663 SayString(ynum, FALSE);
\r
664 SayString(piece, FALSE);
\r
670 SayPieces(ChessSquare p)
\r
672 ChessSquare currentpiece;
\r
673 char *piece, *xchar, *ynum ;
\r
674 int yPos, xPos, count = 0;
\r
677 if(p == WhitePlay) SayString("White pieces", FALSE); else
\r
678 if(p == BlackPlay) SayString("Black pieces", FALSE); else
\r
679 if(p == EmptySquare) SayString("Pieces", FALSE); else {
\r
680 sprintf(buf, "%ss", PieceToName(p,1));
\r
681 SayString(buf, FALSE);
\r
683 SayString("are located", FALSE);
\r
684 for(yPos=0; yPos<BOARD_HEIGHT; yPos++) {
\r
685 for(xPos=BOARD_LEFT; xPos<BOARD_RGHT; xPos++) {
\r
686 currentpiece = boards[currentMove][yPos][xPos];
\r
687 if(p == BlackPlay && currentpiece >= BlackPawn && currentpiece <= BlackKing ||
\r
688 p == WhitePlay && currentpiece >= WhitePawn && currentpiece <= WhiteKing )
\r
689 piece = PieceToName(currentpiece,0);
\r
690 else if(p == EmptySquare && currentpiece != EmptySquare)
\r
691 piece = PieceToName(currentpiece,1);
\r
692 else if(p == currentpiece)
\r
696 if(count == 0) SayString("at", FALSE);
\r
697 xchar = SquareToChar(xPos);
\r
698 ynum = SquareToNum(yPos);
\r
699 SayString(xchar , FALSE);
\r
700 SayString(ynum, FALSE);
\r
701 if(piece) SayString(piece, FALSE);
\r
705 if(count == 0) SayString("nowhere", FALSE);
\r
711 ChessSquare currentpiece;
\r
712 char *piece, *xchar, *ynum ;
\r
713 if(fromX < BOARD_LEFT) { SayString("You strayed into the white holdings", FALSE); return; }
\r
714 if(fromX >= BOARD_RGHT) { SayString("You strayed into the black holdings", FALSE); return; }
\r
715 currentpiece = boards[currentMove][fromY][fromX];
\r
716 piece = PieceToName(currentpiece,1);
\r
717 ynum = SquareToNum(fromY);
\r
718 xchar = SquareToChar(fromX);
\r
719 SayString("Your current position is", FALSE);
\r
720 SayString(xchar, FALSE);
\r
721 SayString(ynum, FALSE);
\r
722 SayString(piece, FALSE);
\r
723 if((fromX-BOARD_LEFT) ^ fromY)
\r
724 SayString("on a dark square",FALSE);
\r
726 SayString("on a light square",FALSE);
\r
728 PossibleAttacked();
\r
736 ChessSquare currentpiece;
\r
737 char *piece, *xchar, *ynum ;
\r
739 if(gameInfo.holdingsWidth) {
\r
741 for(Ypos=0; Ypos<gameInfo.holdingsSize; Ypos++) {
\r
742 int n = boards[currentMove][Ypos][BOARD_WIDTH-2];
\r
743 if(n) { char buf[MSG_SIZ];
\r
744 if(!first++) SayString("white holds", FALSE);
\r
745 currentpiece = boards[currentMove][Ypos][BOARD_WIDTH-1];
\r
746 piece = PieceToName(currentpiece,0);
\r
747 sprintf(buf, "%d %s%s", n, piece, (n==1 ? "" : "s") );
\r
748 SayString(buf, FALSE);
\r
752 for(Ypos=BOARD_HEIGHT-1; Ypos>=BOARD_HEIGHT - gameInfo.holdingsSize; Ypos--) {
\r
753 int n = boards[currentMove][Ypos][1];
\r
754 if(n) { char buf[MSG_SIZ];
\r
755 if(!first++) SayString("black holds", FALSE);
\r
756 currentpiece = boards[currentMove][Ypos][0];
\r
757 piece = PieceToName(currentpiece,0);
\r
758 sprintf(buf, "%d %s%s", n, piece, (n==1 ? "" : "s") );
\r
759 SayString(buf, FALSE);
\r
764 for(Ypos=BOARD_HEIGHT-1; Ypos>=0; Ypos--) {
\r
765 ynum = ordinals[Ypos + (gameInfo.boardHeight < 10)];
\r
766 SayString(ynum, FALSE);
\r
767 SayString("rank", FALSE);
\r
768 for(Xpos=BOARD_LEFT; Xpos<BOARD_RGHT; Xpos++) {
\r
769 currentpiece = boards[currentMove][Ypos][Xpos];
\r
770 if(currentpiece != EmptySquare) {
\r
771 int count = 0, oldX = Xpos;
\r
773 piece = PieceToName(currentpiece,1);
\r
774 while(Xpos < BOARD_RGHT && boards[currentMove][Ypos][Xpos] == currentpiece)
\r
777 sprintf(buf, "%d %ss", count, piece);
\r
778 } else sprintf(buf, "%s", piece);
\r
780 SayString(buf, FALSE);
\r
782 int count = 0, oldX = Xpos;
\r
783 while(Xpos < BOARD_RGHT && boards[currentMove][Ypos][Xpos] == EmptySquare)
\r
785 if(Xpos == BOARD_RGHT && oldX == BOARD_LEFT)
\r
786 SayString("all", FALSE);
\r
790 sprintf(buf, "%d", count);
\r
791 SayString(buf, FALSE);
\r
795 SayString("empty", FALSE);
\r
805 if(gameMode == MachinePlaysBlack || gameMode == IcsPlayingBlack) {
\r
806 if(WhiteOnMove(currentMove))
\r
807 SayString("It is your turn", FALSE);
\r
808 else SayString("It is your opponents turn", FALSE);
\r
809 } else if(gameMode == MachinePlaysWhite || gameMode == IcsPlayingWhite) {
\r
810 if(WhiteOnMove(currentMove))
\r
811 SayString("It is your opponents turn", FALSE);
\r
812 else SayString("It is your turn", FALSE);
\r
814 if(WhiteOnMove(currentMove))
\r
815 SayString("White is on move here", FALSE);
\r
816 else SayString("Black is on move here", FALSE);
\r
822 SayMachineMove(int evenIfDuplicate)
\r
824 int len, xPos, yPos, moveNr, secondSpace = 0, castle = 0, n;
\r
825 ChessSquare currentpiece;
\r
826 char *piece, *xchar, *ynum, *p;
\r
827 char c, buf[MSG_SIZ], comment[MSG_SIZ];
\r
828 static char disambiguation[2];
\r
829 static int previousMove = 0;
\r
831 if(appData.debugMode) fprintf(debugFP, "Message = '%s'\n", messageText);
\r
832 if(gameMode == BeginningOfGame) return;
\r
833 if(messageText[0] == '[') return;
\r
835 if(isdigit(messageText[0])) { // message is move, possibly with thinking output
\r
836 int dotCount = 0, spaceCount = 0;
\r
837 sscanf(messageText, "%d", &moveNr);
\r
839 // [HGM] show: better extraction of move
\r
840 while (messageText[len] != NULLCHAR) {
\r
841 if(messageText[len] == '.' && spaceCount == 0) dotCount++;
\r
842 if(messageText[len] == ' ') { if(++spaceCount == 2) secondSpace = len; }
\r
843 if(messageText[len] == '{') { // we detected a comment
\r
844 if(isalpha(messageText[len+1]) ) sscanf(messageText+len, "{%[^}]}", comment);
\r
847 if(messageText[len] == '[') { // we detected thinking output
\r
848 int depth; float score=0; char c, lastMover = (dotCount == 3 ? 'B' : 'W');
\r
849 if(sscanf(messageText+len+1, "%d]%c%f", &depth, &c, &score) > 1) {
\r
850 if(c == ' ') { // if not explicitly specified, figure out source of thinking output
\r
852 case MachinePlaysWhite:
\r
853 case IcsPlayingWhite:
\r
855 case IcsPlayingBlack:
\r
856 case MachinePlaysBlack:
\r
862 if(c != lastMover) return; // line is thinking output of future move, ignore.
\r
863 if(2*moveNr - (dotCount < 2) == previousMove)
\r
864 return; // do not repeat same move; likely ponder output
\r
865 sprintf(buf, "score %s %d at %d ply",
\r
866 score > 0 ? "plus" : score < 0 ? "minus" : "",
\r
867 (int) (fabs(score)*100+0.5),
\r
869 SayString(buf, FALSE); // move + thinking output describing it; say it.
\r
871 while(messageText[len-1] == ' ') len--; // position just behind move;
\r
874 if(messageText[len] == '(') { // ICS time printed behind move
\r
875 while(messageText[len+1] && messageText[len] != ')') len++; // skip it
\r
879 if(secondSpace) len = secondSpace; // position behind move
\r
880 if(messageText[len-1] == '+' || messageText[len-1] == '#') { /* you are in checkmate */
\r
881 len--; // strip off check or mate indicator
\r
883 if(messageText[len-2] == '=') { /* promotion */
\r
884 len-=2; // strip off promotion piece
\r
885 SayString("promotion", FALSE);
\r
888 n = 2*moveNr - (dotCount < 2);
\r
890 if(previousMove != 2*moveNr + (dotCount > 1) || evenIfDuplicate) {
\r
892 previousMove = 2*moveNr + (dotCount > 1); // remember move nr of move last spoken
\r
893 sprintf(number, "%d", moveNr);
\r
895 yPos = CoordToNum(messageText[len-1]); /* turn char coords to ints */
\r
896 xPos = CoordToNum(messageText[len-2]);
\r
897 if(xPos < 0 || xPos > 11) return; // prevent crashes if no coord string available to speak
\r
898 if(yPos < 0 || yPos > 9) return;
\r
899 currentpiece = boards[n][yPos][xPos];
\r
900 piece = PieceToName(currentpiece,0);
\r
901 ynum = SquareToNum(yPos);
\r
902 xchar = SquareToChar(xPos);
\r
903 c = messageText[len-3];
\r
904 if(c == 'x') c = messageText[len-4];
\r
905 if(!isdigit(c) && c < 'a' && c != '@') c = 0;
\r
906 disambiguation[0] = c;
\r
907 SayString(WhiteOnMove(n) ? "Black" : "White", FALSE);
\r
908 SayString("move", FALSE);
\r
909 SayString(number, FALSE);
\r
910 // if(c==0 || c=='@') SayString("a", FALSE);
\r
911 // intercept castling moves
\r
912 p = StrStr(messageText, "O-O-O");
\r
913 if(p && p-messageText < len) {
\r
914 SayString("queen side castling",FALSE);
\r
917 p = StrStr(messageText, "O-O");
\r
918 if(p && p-messageText < len) {
\r
919 SayString("king side castling",FALSE);
\r
924 SayString(piece, FALSE);
\r
925 if(c == '@') SayString("dropped on", FALSE); else
\r
926 if(c) SayString(disambiguation, FALSE);
\r
927 SayString("to", FALSE);
\r
928 SayString(xchar, FALSE);
\r
929 SayString(ynum, FALSE);
\r
930 if(messageText[len-3] == 'x') {
\r
931 currentpiece = boards[n-1][yPos][xPos];
\r
932 if(currentpiece != EmptySquare) {
\r
933 piece = PieceToName(currentpiece,0);
\r
934 SayString("Capturing a",FALSE);
\r
935 SayString(piece, FALSE);
\r
936 } else SayString("Capturing onn passann",FALSE);
\r
938 if(messageText[len] == '+') SayString("check", FALSE); else
\r
939 if(messageText[len] == '#') {
\r
940 SayString("finishing off", FALSE);
\r
941 SayString(WhiteOnMove(n) ? "White" : "Black", FALSE);
\r
946 /* say comment after move, possibly with result */
\r
948 if(StrStr(messageText, " 1-0")) p = "white wins"; else
\r
949 if(StrStr(messageText, " 0-1")) p = "black wins"; else
\r
950 if(StrStr(messageText, " 1/2-1/2")) p = "game ends in a draw";
\r
953 if(!StrCaseStr(comment, "draw") &&
\r
954 !StrCaseStr(comment, "white") &&
\r
955 !StrCaseStr(comment, "black") ) {
\r
956 SayString(p, FALSE);
\r
957 SayString("due to", FALSE);
\r
960 SayString(comment, FALSE); // alphabetic comment (usually game end)
\r
961 } else if(p) SayString(p, FALSE);
\r
964 /* starts not with digit */
\r
965 if(StrCaseStr(messageText, "illegal")) PlayIcsUnfinishedSound();
\r
966 SayString(messageText, FALSE);
\r
974 char buf1[50], buf2[50];
\r
976 static long int lastWhiteTime, lastBlackTime;
\r
978 suppressClocks = 1; // if user is using alt+T command, no reason to display them
\r
979 if(abs(lastWhiteTime - whiteTimeRemaining) < 1000 && abs(lastBlackTime - blackTimeRemaining) < 1000)
\r
980 suppressClocks = 0; // back on after two requests in rapid succession
\r
981 sprintf(buf1, "%s", TimeString(whiteTimeRemaining));
\r
983 SayString("White's remaining time is", FALSE);
\r
984 SayString(str1, FALSE);
\r
985 sprintf(buf2, "%s", TimeString(blackTimeRemaining));
\r
987 SayString("Black's remaining time is", FALSE);
\r
988 SayString(str2, FALSE);
\r
989 lastWhiteTime = whiteTimeRemaining;
\r
990 lastBlackTime = blackTimeRemaining;
\r
994 Toggle(Boolean *b, char *mess)
\r
997 SayString(mess, FALSE);
\r
998 SayString("is now", FALSE);
\r
999 SayString(*b ? "on" : "off", FALSE);
\r
1002 /* handles keyboard moves in a click-click fashion */
\r
1004 KeyboardMove(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
1006 ChessSquare currentpiece;
\r
1009 static BOOLEAN sameAgain = FALSE;
\r
1010 switch (message) {
\r
1012 sameAgain = FALSE;
\r
1013 if(oldFromX == fromX && oldFromY == fromY) {
\r
1015 /* click on same square */
\r
1018 else if(oldFromX != -1) {
\r
1020 ChessSquare pdown, pup;
\r
1021 pdown = boards[currentMove][oldFromY][oldFromX];
\r
1022 pup = boards[currentMove][fromY][fromX];
\r
1024 if (gameMode == EditPosition ||
\r
1025 !((WhitePawn <= pdown && pdown <= WhiteKing &&
\r
1026 WhitePawn <= pup && pup <= WhiteKing) ||
\r
1027 (BlackPawn <= pdown && pdown <= BlackKing &&
\r
1028 BlackPawn <= pup && pup <= BlackKing))) {
\r
1029 /* EditPosition, empty square, or different color piece;
\r
1030 click-click move is possible */
\r
1032 if (IsPromotion(oldFromX, oldFromY, fromX, fromY)) {
\r
1033 if (appData.alwaysPromoteToQueen) {
\r
1034 UserMoveEvent(oldFromX, oldFromY, fromX, fromY, 'q');
\r
1037 toX = fromX; toY = fromY; fromX = oldFromX; fromY = oldFromY;
\r
1038 PromotionPopup(hwnd);
\r
1039 fromX = toX; fromY = toY;
\r
1043 UserMoveEvent(oldFromX, oldFromY, fromX, fromY, NULLCHAR);
\r
1045 oldFromX = oldFromY = -1;
\r
1050 /* First downclick, or restart on a square with same color piece */
\r
1051 if (OKToStartUserMove(fromX, fromY)) {
\r
1054 currentpiece = boards[currentMove][fromY][fromX];
\r
1055 piece = PieceToName(currentpiece,1);
\r
1056 SayString(piece, FALSE);
\r
1057 SayString("selected", FALSE);
\r
1060 oldFromX = oldFromY = -1;
\r
1065 if (oldFromX == fromX && oldFromY == fromY) {
\r
1066 /* Upclick on same square */
\r
1068 /* Clicked same square twice: abort click-click move */
\r
1069 oldFromX = oldFromY = -1;
\r
1070 currentpiece = boards[currentMove][fromY][fromX];
\r
1071 piece = PieceToName(currentpiece,0);
\r
1072 SayString(piece, FALSE);
\r
1073 SayString("unselected", FALSE);
\r
1081 { // return TRUE for times we want to announce
\r
1083 x = (x+50)/100; // tenth of seconds
\r
1084 if(x <= 100) return (x%10 == 0);
\r
1085 if(x <= 600) return (x%100 == 0);
\r
1086 if(x <= 6000) return (x%600 == 0);
\r
1087 return (x%3000 == 0);
\r
1091 if(isalpha((char)wParam)) {
\r
1092 /* capitals of any ind are intercepted and distinguished by left and right shift */
\r
1093 int mine = GetKeyState(VK_RSHIFT) < 0;
\r
1094 if(mine || GetKeyState(VK_LSHIFT) < 0) {
\r
1097 #define JAWS_ALT_INTERCEPT \
\r
1098 if(suppressOneKey) {\
\r
1099 suppressOneKey = 0;\
\r
1100 if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) break;\
\r
1102 if ((char)wParam == 022 && gameMode == EditPosition) { /* <Ctl R>. Pop up piece menu */\
\r
1103 POINT pt; int x, y;\
\r
1104 SquareToPos(fromY, fromX, &x, &y);\
\r
1105 pt.x = x; pt.y = y;\
\r
1106 if(gameInfo.variant != VariantShogi)\
\r
1107 MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\
\r
1109 MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\
\r
1113 #define JAWS_REPLAY \
\r
1114 case '\020': /* ctrl P */\
\r
1115 { char buf[MSG_SIZ];\
\r
1116 if(GetWindowText(hwnd, buf, MSG_SIZ-1))\
\r
1117 SayString(buf, FALSE);\
\r
1121 #define JAWS_KB_NAVIGATION \
\r
1125 if(GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) < 0) {\
\r
1126 /* Control + Alt + letter used for speaking piece positions */\
\r
1127 static int lastTime; static char lastChar;\
\r
1128 int mine = 0, time = GetTickCount(); char c;\
\r
1130 if((char)wParam == lastChar && time-lastTime < 250) mine = 1;\
\r
1131 lastChar = wParam; lastTime = time;\
\r
1134 if(gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) mine = !mine;\
\r
1136 if(ToLower(c) == 'x') {\
\r
1137 SayPieces(mine ? WhitePlay : BlackPlay);\
\r
1138 suppressOneKey = 1;\
\r
1141 if(CharToPiece(c) != EmptySquare) {\
\r
1142 SayPieces(CharToPiece(mine ? ToUpper(c) : ToLower(c)));\
\r
1143 suppressOneKey = 1;\
\r
1148 switch (wParam) {\
\r
1153 KeyboardEvent(hwnd, message, wParam, lParam);\
\r
1156 KeyboardMove(hwnd, message, wParam, lParam);\
\r
1161 switch (wParam) {\
\r
1163 KeyboardMove(hwnd, message, wParam, lParam);\
\r
1168 #define JAWS_MENU_ITEMS \
\r
1169 case IDM_PossibleAttackMove: /*What can I possible attack from here */\
\r
1170 PossibleAttackMove();\
\r
1173 case IDM_PossibleAttacked: /*what can possible attack this square*/\
\r
1174 PossibleAttacked();\
\r
1177 case IDM_ReadRow: /* Read the current row of pieces */\
\r
1181 case IDM_ReadColumn: /* Read the current column of pieces */\
\r
1185 case IDM_SayCurrentPos: /* Say current position including color */\
\r
1189 case IDM_SayAllBoard: /* Say the whole board from bottom to top */\
\r
1193 case IDM_SayMachineMove: /* Say the last move made */\
\r
1195 SayMachineMove(1);\
\r
1198 case IDM_SayUpperDiagnols: /* Says the diagnol positions above you */\
\r
1199 SayUpperDiagnols();\
\r
1202 case IDM_SayLowerDiagnols: /* Say the diagnol positions below you */\
\r
1203 SayLowerDiagnols();\
\r
1206 case IDM_SayBlackPieces: /*Say the opponents pieces */\
\r
1207 SayPieces(BlackPlay);\
\r
1210 case IDM_SayWhitePieces: /*Say the opponents pieces */\
\r
1211 SayPieces(WhitePlay);\
\r
1214 case IDM_SayClockTime: /*Say the clock time */\
\r
1218 case IDM_SayWhosTurn: /* Say whos turn it its */\
\r
1222 case IDM_SayKnightMoves: /* Say Knights (L-shaped) move */\
\r
1223 SayKnightMoves();\
\r
1226 case OPT_PonderNextMove: /* Toggle option setting */\
\r
1227 Toggle(&appData.ponderNextMove, "ponder");\
\r
1230 case OPT_AnimateMoving: /* Toggle option setting */\
\r
1231 Toggle(&appData.animate, "animate moving");\
\r
1234 case OPT_AutoFlag: /* Toggle option setting */\
\r
1235 Toggle(&appData.autoCallFlag, "auto flag");\
\r
1238 case OPT_AlwaysQueen: /* Toggle option setting */\
\r
1239 Toggle(&appData.alwaysPromoteToQueen, "always promote to queen");\
\r
1242 case OPT_TestLegality: /* Toggle option setting */\
\r
1243 Toggle(&appData.testLegality, "legality testing");\
\r
1246 case OPT_HideThinkFromHuman: /* Toggle option setting */\
\r
1247 Toggle(&appData.hideThinkingFromHuman, "hide thinking");\
\r
1248 ShowThinkingEvent();\
\r
1251 case OPT_SaveExtPGN: /* Toggle option setting */\
\r
1252 Toggle(&appData.saveExtendedInfoInPGN, "extended P G N info");\
\r
1255 case OPT_ExtraInfoInMoveHistory: /* Toggle option setting */\
\r
1256 Toggle(&appData.showEvalInMoveHistory, "extra info in move histoty");\
\r
1261 #define JAWS_INIT if (!InitJAWS()) return (FALSE);
\r
1263 #define JAWS_DELETE(X)
\r
1265 #define JAWS_SILENCE if(suppressClocks) return;
\r
1267 #define SAY(S) SayString((S), FALSE)
\r
1269 #define SAYMACHINEMOVE() SayMachineMove(0)
\r
1271 // After inclusion of this file somewhere early in winboard.c, the remaining part of the patch
\r
1272 // is scattered over winboard.c for actually calling the routines.
\r
1274 // * move fromX, fromY declaration to front, before incusion of this file. (Can be permanent change in winboard.c.)
\r
1275 // * call InitJAWS(), after calling InitIntance(). (Using JAWS_INIT macro)
\r
1276 // * add keyboard cases in main switch of WndProc, though JAWS_KB_NAVIGATION above, e.g. before WM_CHAR case.
\r
1277 // * change the WM_CHAR case of same switch from "if(appData.icsActive)" to "if(appData.icsActive JAWS_IF_TAB)"
\r
1278 // * add new menu cases in WM_COMMAND case of WndProc, e.g. before IDM_Forward. (throug macro defined above)
\r
1279 // * add SAYMACHINEMOVE(); at the end of DisplayMessage();
\r
1280 // * add SAY("board"); in WM_CHAR case of ConsoleTextSubclass, just before "SetFocus(buttondesc..."
\r