Merge commit 'master-20091122' into gtk
authorArun Persaud <arun@nubati.net>
Sat, 9 Jan 2010 22:17:21 +0000 (14:17 -0800)
committerArun Persaud <arun@nubati.net>
Sat, 9 Jan 2010 22:17:21 +0000 (14:17 -0800)
Conflicts:
backend.c
configure.ac
xboard.c
xengineoutput.c
xhistory.c

62 files changed:
Makefile.am
backend.c [changed mode: 0755->0644]
backend.h
book.c
common.h
configure.ac
engineoutput.c [new file with mode: 0644]
engineoutput.h [new file with mode: 0644]
evalgraph.c [new file with mode: 0644]
evalgraph.h [new file with mode: 0644]
frontend.h
gamelist.c [changed mode: 0755->0644]
gettext.h [changed mode: 0755->0644]
moves.c
moves.h
parser.h
parser.l [changed mode: 0755->0644]
shogibitmaps/README [deleted file]
shogibitmaps/sa58o.bmp [deleted file]
shogibitmaps/sb58o.bmp [deleted file]
shogibitmaps/sc58o.bmp [deleted file]
shogibitmaps/sf58o.bmp [deleted file]
shogibitmaps/sg58o.bmp [deleted file]
shogibitmaps/sh58o.bmp [deleted file]
shogibitmaps/sk58o.bmp [deleted file]
shogibitmaps/sk58w.bmp [deleted file]
shogibitmaps/sl58o.bmp [deleted file]
shogibitmaps/sl58w.bmp [deleted file]
shogibitmaps/sn58o.bmp [deleted file]
shogibitmaps/sn58w.bmp [deleted file]
shogibitmaps/sp58o.bmp [deleted file]
shogibitmaps/sp58w.bmp [deleted file]
shogibitmaps/sr58o.bmp [deleted file]
shogibitmaps/sr58w.bmp [deleted file]
shogibitmaps/ss58o.bmp [deleted file]
shogibitmaps/su58o.bmp [deleted file]
shogibitmaps/sw58o.bmp [deleted file]
shogibitmaps/sw58w.bmp [deleted file]
winboard/config.h
winboard/jaws.c
winboard/makefile.gcc
winboard/makefile.ms
winboard/resource.h
winboard/wchat.c
winboard/wclipbrd.c
winboard/wedittags.c
winboard/wedittags.h [deleted file]
winboard/wengineo.c
winboard/wevalgraph.c
winboard/wgamelist.c
winboard/wgamelist.h [deleted file]
winboard/whistory.c
winboard/winboard.c
winboard/winboard.h
winboard/winboard.rc
winboard/wlayout.c
winboard/woptions.c
xboard.c
xboard.h
xengineoutput.c
xhistory.c
xoptions.c

index bb1a656..d678c54 100644 (file)
@@ -23,6 +23,7 @@ xboard_SOURCES = backend.c backend.h backendz.h \
                 uci.c \
                 xboard.c xboard.h \
                 xedittags.c xedittags.h \
+                engineoutput.c engineoutput.h \
                 xengineoutput.c \
                 xgamelist.c xgamelist.h\
                 xhistory.c  xhistory.h \
@@ -30,7 +31,7 @@ xboard_SOURCES = backend.c backend.h backendz.h \
                 $(ZPY)
 xboard_LDADD = -lm  @XAW_LIBS@ @GTK_LIBS@
 
-EXTRA_DIST = pixmaps  bitmaps shogibitmaps \
+EXTRA_DIST = pixmaps bitmaps winboard\
        xboard.texi gpl.texinfo texi2man texinfo.tex xboard.man \
        COPYRIGHT FAQ.html engine-intf.html ics-parsing.txt readme.htm readme_HGM.txt zippy.README
 
old mode 100755 (executable)
new mode 100644 (file)
index ce49de2..3223279
--- a/backend.c
+++ b/backend.c
@@ -160,7 +160,7 @@ int LoadGameFromFile P((char *filename, int n, char *title, int useList));
 int LoadPositionFromFile P((char *filename, int n, char *title));
 int SavePositionToFile P((char *filename));
 void ApplyMove P((int fromX, int fromY, int toX, int toY, int promoChar,
-                 Board board, char *castle, char *ep));
+                                                                               Board board));
 void MakeMove P((int fromX, int fromY, int toX, int toY, int promoChar));
 void ShowMove P((int fromX, int fromY, int toX, int toY));
 int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,
@@ -168,7 +168,7 @@ int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,
 void BackwardInner P((int target));
 void ForwardInner P((int target));
 void GameEnds P((ChessMove result, char *resultDetails, int whosays));
-void EditPositionDone P((void));
+void EditPositionDone P((Boolean fakeRights));
 void PrintOpponents P((FILE *fp));
 void PrintPosition P((FILE *fp, int move));
 void StartChessProgram P((ChessProgramState *cps));
@@ -441,47 +441,58 @@ AppData appData;
 
 Board boards[MAX_MOVES];
 /* [HGM] Following 7 needed for accurate legality tests: */
-signed char  epStatus[MAX_MOVES];
-signed char  castlingRights[MAX_MOVES][BOARD_SIZE]; // stores files for pieces with castling rights or -1
-signed char  castlingRank[BOARD_SIZE]; // and corresponding ranks
-signed char  initialRights[BOARD_SIZE], FENcastlingRights[BOARD_SIZE], fileRights[BOARD_SIZE];
+signed char  castlingRank[BOARD_FILES]; // and corresponding ranks
+signed char  initialRights[BOARD_FILES];
 int   nrCastlingRights; // For TwoKings, or to implement castling-unknown status
 int   initialRulePlies, FENrulePlies;
-char  FENepStatus;
 FILE  *serverMoves = NULL; // next two for broadcasting (/serverMoves option)
 int loadFlag = 0;
 int shuffleOpenings;
 int mute; // mute all sounds
 
-ChessSquare  FIDEArray[2][BOARD_SIZE] = {
+// [HGM] vari: next 12 to save and restore variations
+#define MAX_VARIATIONS 10
+int framePtr = MAX_MOVES-1; // points to free stack entry
+int storedGames = 0;
+int savedFirst[MAX_VARIATIONS];
+int savedLast[MAX_VARIATIONS];
+int savedFramePtr[MAX_VARIATIONS];
+char *savedDetails[MAX_VARIATIONS];
+ChessMove savedResult[MAX_VARIATIONS];
+
+void PushTail P((int firstMove, int lastMove));
+Boolean PopTail P((Boolean annotate));
+void CleanupTail P((void));
+
+ChessSquare  FIDEArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
        WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackBishop, BlackQueen,
        BlackKing, BlackBishop, BlackKnight, BlackRook }
 };
 
-ChessSquare twoKingsArray[2][BOARD_SIZE] = {
+ChessSquare twoKingsArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
        WhiteKing, WhiteKing, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackBishop, BlackQueen,
         BlackKing, BlackKing, BlackKnight, BlackRook }
 };
 
-ChessSquare  KnightmateArray[2][BOARD_SIZE] = {
+ChessSquare  KnightmateArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteMan, WhiteBishop, WhiteQueen,
         WhiteUnicorn, WhiteBishop, WhiteMan, WhiteRook },
     { BlackRook, BlackMan, BlackBishop, BlackQueen,
         BlackUnicorn, BlackBishop, BlackMan, BlackRook }
 };
 
-ChessSquare fairyArray[2][BOARD_SIZE] = { /* [HGM] Queen side differs from King side */
+ChessSquare fairyArray[2][BOARD_FILES] = { /* [HGM] Queen side differs from King side */
     { WhiteCannon, WhiteNightrider, WhiteAlfil, WhiteQueen,
         WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
     { BlackCannon, BlackNightrider, BlackAlfil, BlackQueen,
        BlackKing, BlackBishop, BlackKnight, BlackRook }
 };
 
-ChessSquare ShatranjArray[2][BOARD_SIZE] = { /* [HGM] (movGen knows about Shatranj Q and P) */
+ChessSquare ShatranjArray[2][BOARD_FILES] = { /* [HGM] (movGen knows about Shatranj Q and P) */
     { WhiteRook, WhiteKnight, WhiteAlfil, WhiteKing,
         WhiteFerz, WhiteAlfil, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackAlfil, BlackKing,
@@ -489,36 +500,36 @@ ChessSquare ShatranjArray[2][BOARD_SIZE] = { /* [HGM] (movGen knows about Shatra
 };
 
 
-#if (BOARD_SIZE>=10)
-ChessSquare ShogiArray[2][BOARD_SIZE] = {
+#if (BOARD_FILES>=10)
+ChessSquare ShogiArray[2][BOARD_FILES] = {
     { WhiteQueen, WhiteKnight, WhiteFerz, WhiteWazir,
         WhiteKing, WhiteWazir, WhiteFerz, WhiteKnight, WhiteQueen },
     { BlackQueen, BlackKnight, BlackFerz, BlackWazir,
         BlackKing, BlackWazir, BlackFerz, BlackKnight, BlackQueen }
 };
 
-ChessSquare XiangqiArray[2][BOARD_SIZE] = {
+ChessSquare XiangqiArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteAlfil, WhiteFerz,
         WhiteWazir, WhiteFerz, WhiteAlfil, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackAlfil, BlackFerz,
         BlackWazir, BlackFerz, BlackAlfil, BlackKnight, BlackRook }
 };
 
-ChessSquare CapablancaArray[2][BOARD_SIZE] = {
+ChessSquare CapablancaArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteAngel, WhiteBishop, WhiteQueen,
         WhiteKing, WhiteBishop, WhiteMarshall, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackAngel, BlackBishop, BlackQueen,
         BlackKing, BlackBishop, BlackMarshall, BlackKnight, BlackRook }
 };
 
-ChessSquare GreatArray[2][BOARD_SIZE] = {
+ChessSquare GreatArray[2][BOARD_FILES] = {
     { WhiteDragon, WhiteKnight, WhiteAlfil, WhiteGrasshopper, WhiteKing,
         WhiteSilver, WhiteCardinal, WhiteAlfil, WhiteKnight, WhiteDragon },
     { BlackDragon, BlackKnight, BlackAlfil, BlackGrasshopper, BlackKing,
         BlackSilver, BlackCardinal, BlackAlfil, BlackKnight, BlackDragon },
 };
 
-ChessSquare JanusArray[2][BOARD_SIZE] = {
+ChessSquare JanusArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteAngel, WhiteKnight, WhiteBishop, WhiteKing,
         WhiteQueen, WhiteBishop, WhiteKnight, WhiteAngel, WhiteRook },
     { BlackRook, BlackAngel, BlackKnight, BlackBishop, BlackKing,
@@ -526,7 +537,7 @@ ChessSquare JanusArray[2][BOARD_SIZE] = {
 };
 
 #ifdef GOTHIC
-ChessSquare GothicArray[2][BOARD_SIZE] = {
+ChessSquare GothicArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen, WhiteMarshall,
         WhiteKing, WhiteAngel, WhiteBishop, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackBishop, BlackQueen, BlackMarshall,
@@ -537,7 +548,7 @@ ChessSquare GothicArray[2][BOARD_SIZE] = {
 #endif // !GOTHIC
 
 #ifdef FALCON
-ChessSquare FalconArray[2][BOARD_SIZE] = {
+ChessSquare FalconArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteBishop, WhiteLance, WhiteQueen,
         WhiteKing, WhiteLance, WhiteBishop, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackBishop, BlackLance, BlackQueen,
@@ -547,23 +558,23 @@ ChessSquare FalconArray[2][BOARD_SIZE] = {
 #define FalconArray CapablancaArray
 #endif // !FALCON
 
-#else // !(BOARD_SIZE>=10)
+#else // !(BOARD_FILES>=10)
 #define XiangqiPosition FIDEArray
 #define CapablancaArray FIDEArray
 #define GothicArray FIDEArray
 #define GreatArray FIDEArray
-#endif // !(BOARD_SIZE>=10)
+#endif // !(BOARD_FILES>=10)
 
-#if (BOARD_SIZE>=12)
-ChessSquare CourierArray[2][BOARD_SIZE] = {
+#if (BOARD_FILES>=12)
+ChessSquare CourierArray[2][BOARD_FILES] = {
     { WhiteRook, WhiteKnight, WhiteAlfil, WhiteBishop, WhiteMan, WhiteKing,
         WhiteFerz, WhiteWazir, WhiteBishop, WhiteAlfil, WhiteKnight, WhiteRook },
     { BlackRook, BlackKnight, BlackAlfil, BlackBishop, BlackMan, BlackKing,
         BlackFerz, BlackWazir, BlackBishop, BlackAlfil, BlackKnight, BlackRook }
 };
-#else // !(BOARD_SIZE>=12)
+#else // !(BOARD_FILES>=12)
 #define CourierArray CapablancaArray
-#endif // !(BOARD_SIZE>=12)
+#endif // !(BOARD_FILES>=12)
 
 
 Board initialPosition;
@@ -644,10 +655,10 @@ InitBackEnd1()
     {
         int i, j;
 
-        for( i=0; i<MAX_MOVES; i++ ) {
+        for( i=0; i<=framePtr; i++ ) {
             pvInfoList[i].depth = -1;
-            epStatus[i]=EP_NONE;
-            for( j=0; j<BOARD_SIZE; j++ ) castlingRights[i][j] = -1;
+            boards[i][EP_STATUS] = EP_NONE;
+            for( j=0; j<BOARD_FILES-2; j++ ) boards[i][CASTLING][j] = NoRights;
         }
     }
 
@@ -794,7 +805,8 @@ InitBackEnd1()
 
     if (appData.icsActive) {
         appData.clockMode = TRUE;  /* changes dynamically in ICS mode */
-    } else if (*appData.searchTime != NULLCHAR || appData.noChessProgram) {
+//    } else if (*appData.searchTime != NULLCHAR || appData.noChessProgram) {
+    } else if (appData.noChessProgram) { // [HGM] st: searchTime mode now also is clockMode
        appData.clockMode = FALSE;
        first.sendTime = second.sendTime = 0;
     }
@@ -1192,10 +1204,9 @@ InitBackEnd3 P((void))
             }
             /* [HGM] loadPos: make that every new game uses the setup */
             /* from file as long as we do not switch variant          */
-            if(!blackPlaysFirst) { int i;
+            if(!blackPlaysFirst) {
                 startedFromPositionFile = TRUE;
                 CopyBoard(filePosition, boards[0]);
-                for(i=0; i<BOARD_SIZE; i++) fileRights[i] = castlingRights[0][i];
             }
        }
        if (initialMode == AnalyzeMode) {
@@ -1904,7 +1915,7 @@ CopyHoldings(Board board, char *holdings, ChessSquare lowestPiece)
     ChessSquare piece;
 
     if(gameInfo.holdingsWidth < 2)  return;
-    if(gameInfo.variant != VariantBughouse && board[BOARD_SIZE-1][BOARD_SIZE-2])
+    if(gameInfo.variant != VariantBughouse && board[HOLDINGS_SET])
        return; // prevent overwriting by pre-board holdings
 
     if( (int)lowestPiece >= BlackPawn ) {
@@ -2080,7 +2091,8 @@ read_from_ics(isr, closure, data, count, error)
 
     if (appData.debugMode) { int f = forwardMostMove;
         fprintf(debugFP, "ics input %d, castling = %d %d %d %d %d %d\n", f,
-                castlingRights[f][0],castlingRights[f][1],castlingRights[f][2],castlingRights[f][3],castlingRights[f][4],castlingRights[f][5]);
+                boards[f][CASTLING][0],boards[f][CASTLING][1],boards[f][CASTLING][2],
+                boards[f][CASTLING][3],boards[f][CASTLING][4],boards[f][CASTLING][5]);
     }
     if (count > 0) {
        /* If last read ended with a partial line that we couldn't parse,
@@ -2305,7 +2317,7 @@ read_from_ics(isr, closure, data, count, error)
                        chattingPartner = -1;
                    } else
                    if(!suppressKibitz) // [HGM] kibitz
-                       AppendComment(forwardMostMove, StripHighlight(parse));
+                       AppendComment(forwardMostMove, StripHighlight(parse), TRUE);
                    else { // [HGM kibitz: divert memorized engine kibitz to engine-output window
                        int nrDigit = 0, nrAlph = 0, i;
                        if(parse_pos > MSG_SIZ - 30) // defuse unreasonably long input
@@ -3305,7 +3317,7 @@ read_from_ics(isr, closure, data, count, error)
                         /* [HGM] copy holdings to board holdings area */
                         CopyHoldings(boards[forwardMostMove], white_holding, WhitePawn);
                         CopyHoldings(boards[forwardMostMove], black_holding, BlackPawn);
-                        boards[forwardMostMove][BOARD_SIZE-1][BOARD_SIZE-2] = 1; // flag holdings as set
+                        boards[forwardMostMove][HOLDINGS_SET] = 1; // flag holdings as set
 #if ZIPPY
                        if (appData.zippyPlay && first.initDone) {
                            ZippyHoldings(white_holding, black_holding,
@@ -3438,7 +3450,7 @@ ParseBoard12(string)
     /* Convert the move number to internal form */
     moveNum = (moveNum - 1) * 2;
     if (to_play == 'B') moveNum++;
-    if (moveNum >= MAX_MOVES) {
+    if (moveNum > framePtr) { // [HGM] vari: do not run into saved variations
       DisplayFatalError(_("Game too long; increase MAX_MOVES and recompile"),
                        0, 1);
       return;
@@ -3658,7 +3670,7 @@ ParseBoard12(string)
       }
     }
     CopyBoard(boards[moveNum], board);
-    boards[moveNum][BOARD_SIZE-1][BOARD_SIZE-2] = 0; // [HGM] indicate holdings not set
+    boards[moveNum][HOLDINGS_SET] = 0; // [HGM] indicate holdings not set
     if (moveNum == 0) {
        startedFromSetupPosition =
          !CompareBoards(board, initialPosition);
@@ -3681,38 +3693,38 @@ ParseBoard12(string)
 
         for(i=BOARD_LEFT, j= -1; i<BOARD_RGHT; i++)
             if(board[0][i] == WhiteRook) j = i;
-        initialRights[0] = castlingRights[moveNum][0] = (castle_ws == 0 && gameInfo.variant != VariantFischeRandom ? -1 : j);
+        initialRights[0] = boards[moveNum][CASTLING][0] = (castle_ws == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
         for(i=BOARD_RGHT-1, j= -1; i>=BOARD_LEFT; i--)
             if(board[0][i] == WhiteRook) j = i;
-        initialRights[1] = castlingRights[moveNum][1] = (castle_wl == 0 && gameInfo.variant != VariantFischeRandom ? -1 : j);
+        initialRights[1] = boards[moveNum][CASTLING][1] = (castle_wl == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
         for(i=BOARD_LEFT, j= -1; i<BOARD_RGHT; i++)
             if(board[BOARD_HEIGHT-1][i] == BlackRook) j = i;
-        initialRights[3] = castlingRights[moveNum][3] = (castle_bs == 0 && gameInfo.variant != VariantFischeRandom ? -1 : j);
+        initialRights[3] = boards[moveNum][CASTLING][3] = (castle_bs == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
         for(i=BOARD_RGHT-1, j= -1; i>=BOARD_LEFT; i--)
             if(board[BOARD_HEIGHT-1][i] == BlackRook) j = i;
-        initialRights[4] = castlingRights[moveNum][4] = (castle_bl == 0 && gameInfo.variant != VariantFischeRandom ? -1 : j);
+        initialRights[4] = boards[moveNum][CASTLING][4] = (castle_bl == 0 && gameInfo.variant != VariantFischeRandom ? NoRights : j);
 
        if(gameInfo.variant == VariantKnightmate) { wKing = WhiteUnicorn; bKing = BlackUnicorn; }
         for(k=BOARD_LEFT; k<BOARD_RGHT; k++)
-            if(board[0][k] == wKing) initialRights[2] = castlingRights[moveNum][2] = k;
+            if(board[0][k] == wKing) initialRights[2] = boards[moveNum][CASTLING][2] = k;
         for(k=BOARD_LEFT; k<BOARD_RGHT; k++)
             if(board[BOARD_HEIGHT-1][k] == bKing)
-                initialRights[5] = castlingRights[moveNum][5] = k;
+                initialRights[5] = boards[moveNum][CASTLING][5] = k;
     } else { int r;
-        r = castlingRights[moveNum][0] = initialRights[0];
-        if(board[0][r] != WhiteRook) castlingRights[moveNum][0] = -1;
-        r = castlingRights[moveNum][1] = initialRights[1];
-        if(board[0][r] != WhiteRook) castlingRights[moveNum][1] = -1;
-        r = castlingRights[moveNum][3] = initialRights[3];
-        if(board[BOARD_HEIGHT-1][r] != BlackRook) castlingRights[moveNum][3] = -1;
-        r = castlingRights[moveNum][4] = initialRights[4];
-        if(board[BOARD_HEIGHT-1][r] != BlackRook) castlingRights[moveNum][4] = -1;
+        r = boards[moveNum][CASTLING][0] = initialRights[0];
+        if(board[0][r] != WhiteRook) boards[moveNum][CASTLING][0] = NoRights;
+        r = boards[moveNum][CASTLING][1] = initialRights[1];
+        if(board[0][r] != WhiteRook) boards[moveNum][CASTLING][1] = NoRights;
+        r = boards[moveNum][CASTLING][3] = initialRights[3];
+        if(board[BOARD_HEIGHT-1][r] != BlackRook) boards[moveNum][CASTLING][3] = NoRights;
+        r = boards[moveNum][CASTLING][4] = initialRights[4];
+        if(board[BOARD_HEIGHT-1][r] != BlackRook) boards[moveNum][CASTLING][4] = NoRights;
         /* wildcastle kludge: always assume King has rights */
-        r = castlingRights[moveNum][2] = initialRights[2];
-        r = castlingRights[moveNum][5] = initialRights[5];
+        r = boards[moveNum][CASTLING][2] = initialRights[2];
+        r = boards[moveNum][CASTLING][5] = initialRights[5];
     }
     /* [HGM] e.p. rights. Assume that ICS sends file number here? */
-    epStatus[moveNum] = double_push == -1 ? EP_NONE : double_push + BOARD_LEFT;
+    boards[moveNum][EP_STATUS] = double_push == -1 ? EP_NONE : double_push + BOARD_LEFT;
 
 
     if (ics_getting_history == H_GOT_REQ_HEADER ||
@@ -3802,7 +3814,8 @@ ParseBoard12(string)
   if (appData.debugMode) {
     if (appData.debugMode) { int f = forwardMostMove;
         fprintf(debugFP, "parseboard %d, castling = %d %d %d %d %d %d\n", f,
-                castlingRights[f][0],castlingRights[f][1],castlingRights[f][2],castlingRights[f][3],castlingRights[f][4],castlingRights[f][5]);
+                boards[f][CASTLING][0],boards[f][CASTLING][1],boards[f][CASTLING][2],
+                boards[f][CASTLING][3],boards[f][CASTLING][4],boards[f][CASTLING][5]);
     }
     fprintf(debugFP, "accepted move %s from ICS, parse it.\n", move_str);
     fprintf(debugFP, "moveNum = %d\n", moveNum);
@@ -3848,11 +3861,10 @@ ParseBoard12(string)
          // end of long SAN patch
          if (valid) {
            (void) CoordsToAlgebraic(boards[moveNum - 1],
-                                    PosFlags(moveNum - 1), EP_UNKNOWN,
+                                    PosFlags(moveNum - 1),
                                     fromY, fromX, toY, toX, promoChar,
                                     parseList[moveNum-1]);
-            switch (MateTest(boards[moveNum], PosFlags(moveNum), EP_UNKNOWN,
-                             castlingRights[moveNum]) ) {
+            switch (MateTest(boards[moveNum], PosFlags(moveNum)) ) {
              case MT_NONE:
              case MT_STALEMATE:
              default:
@@ -4504,12 +4516,12 @@ void SetUpShuffle(Board board, int number)
            // Last King gets castling rights
            while(piecesLeft[(int)WhiteUnicorn]) {
                i = put(board, WhiteUnicorn, 0, piecesLeft[(int)WhiteRook]/2, ANY);
-               initialRights[2]  = initialRights[5]  = castlingRights[0][2] = castlingRights[0][5] = i;
+               initialRights[2]  = initialRights[5]  = boards[0][CASTLING][2] = boards[0][CASTLING][5] = i;
            }
 
            while(piecesLeft[(int)WhiteKing]) {
                i = put(board, WhiteKing, 0, piecesLeft[(int)WhiteRook]/2, ANY);
-               initialRights[2]  = initialRights[5]  = castlingRights[0][2] = castlingRights[0][5] = i;
+               initialRights[2]  = initialRights[5]  = boards[0][CASTLING][2] = boards[0][CASTLING][5] = i;
            }
 
 
@@ -4524,9 +4536,9 @@ void SetUpShuffle(Board board, int number)
                if(PosFlags(0) & F_FRC_TYPE_CASTLING) { // first and last Rook get FRC castling rights
                        if(first) {
                                first=0;
-                               initialRights[1]  = initialRights[4]  = castlingRights[0][1] = castlingRights[0][4] = i;
+                               initialRights[1]  = initialRights[4]  = boards[0][CASTLING][1] = boards[0][CASTLING][4] = i;
                        }
-                       initialRights[0]  = initialRights[3]  = castlingRights[0][0] = castlingRights[0][3] = i;
+                       initialRights[0]  = initialRights[3]  = boards[0][CASTLING][0] = boards[0][CASTLING][3] = i;
                }
        }
        for(i=BOARD_LEFT; i<BOARD_RGHT; i++) { // copy black from white
@@ -4600,7 +4612,7 @@ void
 InitPosition(redraw)
      int redraw;
 {
-    ChessSquare (* pieces)[BOARD_SIZE];
+    ChessSquare (* pieces)[BOARD_FILES];
     int i, j, pawnRow, overrule,
     oldx = gameInfo.boardWidth,
     oldy = gameInfo.boardHeight,
@@ -4611,10 +4623,10 @@ InitPosition(redraw)
 
     /* [AS] Initialize pv info list [HGM] and game status */
     {
-        for( i=0; i<MAX_MOVES; i++ ) {
+        for( i=0; i<=framePtr; i++ ) { // [HGM] vari: spare saved variations
             pvInfoList[i].depth = 0;
-            epStatus[i]=EP_NONE;
-            for( j=0; j<BOARD_SIZE; j++ ) castlingRights[i][j] = -1;
+            boards[i][EP_STATUS] = EP_NONE;
+            for( j=0; j<BOARD_FILES-2; j++ ) boards[i][CASTLING][j] = NoRights;
         }
 
         initialRulePlies = 0; /* 50-move counter start */
@@ -4636,8 +4648,10 @@ InitPosition(redraw)
     gameInfo.boardHeight   = 8;
     gameInfo.holdingsSize  = 0;
     nrCastlingRights = -1; /* [HGM] Kludge to indicate default should be used */
-    for(i=0; i<BOARD_SIZE; i++) initialRights[i] = -1; /* but no rights yet */
-    SetCharTable(pieceToChar, "PNBRQ...........Kpnbrq...........k");
+    for(i=0; i<BOARD_FILES-2; i++)
+      initialPosition[CASTLING][i] = initialRights[i] = NoRights; /* but no rights yet */
+    initialPosition[EP_STATUS] = EP_NONE;
+    SetCharTable(pieceToChar, "PNBRQ...........Kpnbrq...........k"); 
 
     switch (gameInfo.variant) {
     case VariantFischeRandom:
@@ -4670,12 +4684,12 @@ InitPosition(redraw)
       gameInfo.boardWidth = 10;
       SetCharTable(pieceToChar, "PNBRQ..JKpnbrq..jk");
       nrCastlingRights = 6;
-        castlingRights[0][0] = initialRights[0] = BOARD_RGHT-1;
-        castlingRights[0][1] = initialRights[1] = BOARD_LEFT;
-        castlingRights[0][2] = initialRights[2] =(BOARD_WIDTH-1)>>1;
-        castlingRights[0][3] = initialRights[3] = BOARD_RGHT-1;
-        castlingRights[0][4] = initialRights[4] = BOARD_LEFT;
-        castlingRights[0][5] = initialRights[5] =(BOARD_WIDTH-1)>>1;
+        initialPosition[CASTLING][0] = initialRights[0] = BOARD_RGHT-1;
+        initialPosition[CASTLING][1] = initialRights[1] = BOARD_LEFT;
+        initialPosition[CASTLING][2] = initialRights[2] =(BOARD_WIDTH-1)>>1;
+        initialPosition[CASTLING][3] = initialRights[3] = BOARD_RGHT-1;
+        initialPosition[CASTLING][4] = initialRights[4] = BOARD_LEFT;
+        initialPosition[CASTLING][5] = initialRights[5] =(BOARD_WIDTH-1)>>1;
       break;
     case VariantFalcon:
       pieces = FalconArray;
@@ -4701,8 +4715,7 @@ InitPosition(redraw)
       pieces = CourierArray;
       gameInfo.boardWidth  = 12;
       nrCastlingRights = 0;
-      SetCharTable(pieceToChar, "PNBR.FE..WMKpnbr.fe..wmk");
-      for(i=0; i<BOARD_SIZE; i++) initialRights[i] = -1;
+      SetCharTable(pieceToChar, "PNBR.FE..WMKpnbr.fe..wmk"); 
       break;
     case VariantKnightmate:
       pieces = KnightmateArray;
@@ -4738,7 +4751,6 @@ InitPosition(redraw)
     case VariantNoCastle:
       pieces = FIDEArray;
       nrCastlingRights = 0;
-      for(i=0; i<BOARD_SIZE; i++) initialRights[i] = -1;
       /* !!?unconstrained back-rank shuffle */
       shuffleOpenings = 1;
       break;
@@ -4758,8 +4770,8 @@ InitPosition(redraw)
         gameInfo.holdingsSize = i;
     }
     if(gameInfo.holdingsSize) gameInfo.holdingsWidth = 2;
-    if(BOARD_HEIGHT > BOARD_SIZE || BOARD_WIDTH > BOARD_SIZE)
-        DisplayFatalError(_("Recompile to support this BOARD_SIZE!"), 0, 2);
+    if(BOARD_HEIGHT > BOARD_RANKS || BOARD_WIDTH > BOARD_FILES)
+        DisplayFatalError(_("Recompile to support this BOARD_RANKS or BOARD_FILES!"), 0, 2);
 
     pawnRow = gameInfo.boardHeight - 7; /* seems to work in all common variants */
     if(pawnRow < 1) pawnRow = 1;
@@ -4806,13 +4818,12 @@ InitPosition(redraw)
         /*       This sets default castling rights from none to normal corners   */
         /* Variants with other castling rights must set them themselves above    */
         nrCastlingRights = 6;
-
-        castlingRights[0][0] = initialRights[0] = BOARD_RGHT-1;
-        castlingRights[0][1] = initialRights[1] = BOARD_LEFT;
-        castlingRights[0][2] = initialRights[2] = BOARD_WIDTH>>1;
-        castlingRights[0][3] = initialRights[3] = BOARD_RGHT-1;
-        castlingRights[0][4] = initialRights[4] = BOARD_LEFT;
-        castlingRights[0][5] = initialRights[5] = BOARD_WIDTH>>1;
+        initialPosition[CASTLING][0] = initialRights[0] = BOARD_RGHT-1;
+        initialPosition[CASTLING][1] = initialRights[1] = BOARD_LEFT;
+        initialPosition[CASTLING][2] = initialRights[2] = BOARD_WIDTH>>1;
+        initialPosition[CASTLING][3] = initialRights[3] = BOARD_RGHT-1;
+        initialPosition[CASTLING][4] = initialRights[4] = BOARD_LEFT;
+        initialPosition[CASTLING][5] = initialRights[5] = BOARD_WIDTH>>1;
      }
 
      if(gameInfo.variant == VariantSuper) Prelude(initialPosition);
@@ -4833,7 +4844,7 @@ InitPosition(redraw)
       /* [HGM] loadPos: use PositionFile for every new game */
       CopyBoard(initialPosition, filePosition);
       for(i=0; i<nrCastlingRights; i++)
-          castlingRights[0][i] = initialRights[i] = fileRights[i];
+          initialRights[i] = filePosition[CASTLING][i];
       startedFromSetupPosition = TRUE;
     }
 
@@ -5009,7 +5020,6 @@ HasPromotionChoice(int fromX, int fromY, int toX, int toY, char *promoChoice)
              gameMode == IcsPlayingBlack &&  WhiteOnMove(currentMove);
     if(appData.testLegality && !premove) {
        moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
-                       epStatus[currentMove], castlingRights[currentMove],
                        fromY, fromX, toY, toX, NULLCHAR);
        if(moveType != WhitePromotionQueen && moveType  != BlackPromotionQueen &&
           moveType != WhitePromotionKnight && moveType != BlackPromotionKnight)
@@ -5103,12 +5113,6 @@ OKToStartUserMove(x, y)
            /* Could disallow this or prompt for confirmation */
            cmailOldMove = -1;
        }
-       if (currentMove < forwardMostMove) {
-           /* Discarding moves */
-           /* Could prompt for confirmation here,
-              but I don't think that's such a good idea */
-           forwardMostMove = currentMove;
-       }
        break;
 
       case BeginningOfGame:
@@ -5137,6 +5141,7 @@ OKToStartUserMove(x, y)
        break;
     }
     if (currentMove != forwardMostMove && gameMode != AnalyzeMode
+       && gameMode != EditGame // [HGM] vari: treat as AnalyzeMode
        && gameMode != AnalyzeFile && gameMode != Training) {
        DisplayMoveError(_("Displayed position is not current"));
        return FALSE;
@@ -5300,7 +5305,6 @@ UserMoveTest(fromX, fromY, toX, toY, promoChar, captureOwn)
 
     /* [HGM] always test for legality, to get promotion info */
     moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
-                          epStatus[currentMove], castlingRights[currentMove],
                                          fromY, fromX, toY, toX, promoChar);
     /* [HGM] but possibly ignore an IllegalMove result */
     if (appData.testLegality) {
@@ -5309,7 +5313,7 @@ UserMoveTest(fromX, fromY, toX, toY, promoChar, captureOwn)
             return ImpossibleMove;
        }
     }
-    if(appData.debugMode) fprintf(debugFP, "moveType 3 = %d, promochar = %x\n", moveType, promoChar);
+
     return moveType;
     /* [HGM] <popupFix> in stead of calling FinishMove directly, this
        function is made into one that returns an OK move type if FinishMove
@@ -5329,9 +5333,6 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
 {
   char *bookHit = 0;
 
-  if(appData.debugMode)
-    fprintf(debugFP, "moveType 5 = %d, promochar = %x\n", moveType, promoChar);
-
   if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) && promoChar != NULLCHAR)
     {
       // [HGM] superchess: suppress promotions to non-available piece
@@ -5352,44 +5353,39 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
      move type in caller when we know the move is a legal promotion */
   if(moveType == NormalMove && promoChar)
     moveType = PromoCharToMoveType(WhiteOnMove(currentMove), promoChar);
-
-  if(appData.debugMode) 
-    fprintf(debugFP, "moveType 1 = %d, promochar = %x\n", moveType, promoChar);
-
+  
+  /* [HGM] <popupFix> kludge to avoid having to know the exact promotion
+     move type in caller when we know the move is a legal promotion */
+  if(moveType == NormalMove && promoChar)
+    moveType = PromoCharToMoveType(WhiteOnMove(currentMove), promoChar);
+  
   /* [HGM] convert drag-and-drop piece drops to standard form */
-  if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) 
+  if( (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && fromY != DROP_RANK )
     {
       moveType = WhiteOnMove(currentMove) ? WhiteDrop : BlackDrop;
-      if(appData.debugMode) 
-       fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", 
-               moveType, currentMove, fromX, fromY, boards[currentMove][fromY][fromX]);
-      //         fromX = boards[currentMove][fromY][fromX];
+      if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", 
+                                   moveType, currentMove, fromX, fromY, boards[currentMove][fromY][fromX]);
       // holdings might not be sent yet in ICS play; we have to figure out which piece belongs here
-      if(fromX == 0) 
-       fromY = BOARD_HEIGHT-1 - fromY; // black holdings upside-down
-
+      if(fromX == 0) fromY = BOARD_HEIGHT-1 - fromY; // black holdings upside-down
       fromX = fromX ? WhitePawn : BlackPawn; // first piece type in selected holdings
-
-      while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) 
-       fromX++; 
-
+      while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++; 
       fromY = DROP_RANK;
     }
-
+  
   /* [HGM] <popupFix> The following if has been moved here from
-     UserMoveEvent(). Because it seemed to belon here (why not allow
+     UserMoveEvent(). Because it seemed to belong here (why not allow
      piece drops in training games?), and because it can only be
      performed after it is known to what we promote. */
-  if (gameMode == Training)
+  if (gameMode == Training) 
     {
       /* compare the move played on the board to the next move in the
        * game. If they match, display the move and the opponent's response.
        * If they don't match, display an error message.
        */
       int saveAnimate;
-      Board testBoard; char testRights[BOARD_SIZE]; char testStatus;
+      Board testBoard;
       CopyBoard(testBoard, boards[currentMove]);
-      ApplyMove(fromX, fromY, toX, toY, promoChar, testBoard, testRights, &testStatus);
+      ApplyMove(fromX, fromY, toX, toY, promoChar, testBoard);
 
       if (CompareBoards(testBoard, boards[currentMove+1]))
        {
@@ -5422,10 +5418,10 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
 
   /* Ok, now we know that the move is good, so we can kill
      the previous line in Analysis Mode */
-  if (gameMode == AnalyzeMode && currentMove < forwardMostMove)
-    {
-      forwardMostMove = currentMove;
-    }
+  if ((gameMode == AnalyzeMode || gameMode == EditGame) 
+                               && currentMove < forwardMostMove) {
+    PushTail(currentMove, forwardMostMove); // [HGM] vari: save tail of game
+  }
 
   /* If we need the chess program but it's dead, restart it */
   ResurrectChessProgram();
@@ -5462,7 +5458,8 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
        }
       ModeHighlight();
     }
-  if(appData.debugMode) fprintf(debugFP, "moveType 2 = %d, promochar = %x\n", moveType, promoChar);
+    ModeHighlight();
+  }
 
   /* Relay move to ICS or chess engine */
   if (appData.icsActive)
@@ -5498,31 +5495,13 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
 
   ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
 
-  switch (gameMode)
+  switch (gameMode) 
     {
     case EditGame:
-      switch (MateTest(boards[currentMove], PosFlags(currentMove),
-                      EP_UNKNOWN, castlingRights[currentMove]) )
-       {
-       case MT_NONE:
-       case MT_CHECK:
-         break;
-       case MT_CHECKMATE:
-       case MT_STAINMATE:
-         if (WhiteOnMove(currentMove))
-           {
-             GameEnds(BlackWins, "Black mates", GE_PLAYER);
-           }
-         else
-           {
-             GameEnds(WhiteWins, "White mates", GE_PLAYER);
-           }
-         break;
-       case MT_STALEMATE:
-         GameEnds(GameIsDrawn, "Stalemate", GE_PLAYER);
-         break;
-    }
-      break;
+      switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
+      case MT_NONE:
+      case MT_CHECK:
+       break;
 
     case MachinePlaysBlack:
     case MachinePlaysWhite:
@@ -5944,7 +5923,8 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
 
     if (appData.debugMode) { int f = forwardMostMove;
         fprintf(debugFP, "machine move %d, castling = %d %d %d %d %d %d\n", f,
-                castlingRights[f][0],castlingRights[f][1],castlingRights[f][2],castlingRights[f][3],castlingRights[f][4],castlingRights[f][5]);
+                boards[f][CASTLING][0],boards[f][CASTLING][1],boards[f][CASTLING][2],
+                boards[f][CASTLING][3],boards[f][CASTLING][4],boards[f][CASTLING][5]);
     }
         if(cps->alphaRank) AlphaRank(machineMove, 4);
         if (!ParseOneMove(machineMove, forwardMostMove, &moveType,
@@ -5972,12 +5952,11 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                                                               ) {
            ChessMove moveType;
            moveType = LegalityTest(boards[forwardMostMove], PosFlags(forwardMostMove),
-                        epStatus[forwardMostMove], castlingRights[forwardMostMove],
                              fromY, fromX, toY, toX, promoChar);
            if (appData.debugMode) {
                 int i;
                 for(i=0; i< nrCastlingRights; i++) fprintf(debugFP, "(%d,%d) ",
-                    castlingRights[forwardMostMove][i], castlingRank[i]);
+                    boards[forwardMostMove][CASTLING][i], castlingRank[i]);
                 fprintf(debugFP, "castling rights\n");
            }
             if(moveType == IllegalMove) {
@@ -6077,7 +6056,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
 
        if( gameMode == TwoMachinesPlay ) {
          // [HGM] some adjudications useful with buggy engines
-            int k, count = 0, epFile = epStatus[forwardMostMove]; static int bare = 1;
+            int k, count = 0; static int bare = 1;
          if(gameInfo.holdingsSize == 0 || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
 
 
@@ -6139,7 +6118,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                /* Some material-based adjudications that have to be made before stalemate test */
                if(gameInfo.variant == VariantAtomic && NrK < 2) {
                    // [HGM] atomic: stm must have lost his King on previous move, as destroying own K is illegal
-                    epStatus[forwardMostMove] = EP_CHECKMATE; // make claimable as if stm is checkmated
+                    boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // make claimable as if stm is checkmated
                     if(appData.checkMates) {
                         SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move
                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
@@ -6152,7 +6131,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                /* Bare King in Shatranj (loses) or Losers (wins) */
                 if( NrW == 1 || NrPieces - NrW == 1) {
                   if( gameInfo.variant == VariantLosers) { // [HGM] losers: bare King wins (stm must have it first)
-                    epStatus[forwardMostMove] = EP_WINS;  // mark as win, so it becomes claimable
+                    boards[forwardMostMove][EP_STATUS] = EP_WINS;  // mark as win, so it becomes claimable
                     if(appData.checkMates) {
                         SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets to see move
                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
@@ -6163,7 +6142,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                  } else
                   if( gameInfo.variant == VariantShatranj && --bare < 0)
                   {    /* bare King */
-                       epStatus[forwardMostMove] = EP_WINS; // make claimable as win for stm
+                       boards[forwardMostMove][EP_STATUS] = EP_WINS; // make claimable as win for stm
                        if(appData.checkMates) {
                            /* but only adjudicate if adjudication enabled */
                            SendMoveToProgram(forwardMostMove-1, cps->other); // make sure opponent gets move
@@ -6177,17 +6156,16 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
 
 
             // don't wait for engine to announce game end if we can judge ourselves
-            switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove), epFile,
-                                       castlingRights[forwardMostMove]) ) {
+            switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove)) ) {
              case MT_CHECK:
                if(gameInfo.variant == Variant3Check) { // [HGM] 3check: when in check, test if 3rd time
                    int i, checkCnt = 0;    // (should really be done by making nr of checks part of game state)
                    for(i=forwardMostMove-2; i>=backwardMostMove; i-=2) {
-                       if(MateTest(boards[i], PosFlags(i), epStatus[i], castlingRights[i]) == MT_CHECK)
+                       if(MateTest(boards[i], PosFlags(i)) == MT_CHECK)
                            checkCnt++;
                        if(checkCnt >= 2) {
                            reason = "Xboard adjudication: 3rd check";
-                           epStatus[forwardMostMove] = EP_CHECKMATE;
+                           boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE;
                            break;
                        }
                    }
@@ -6198,25 +6176,25 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
              case MT_STALEMATE:
              case MT_STAINMATE:
                reason = "Xboard adjudication: Stalemate";
-               if(epStatus[forwardMostMove] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
-                   epStatus[forwardMostMove] = EP_STALEMATE;   // default result for stalemate is draw
+               if((signed char)boards[forwardMostMove][EP_STATUS] != EP_CHECKMATE) { // [HGM] don't touch win through baring or K-capt
+                   boards[forwardMostMove][EP_STATUS] = EP_STALEMATE;   // default result for stalemate is draw
                    if(gameInfo.variant == VariantLosers  || gameInfo.variant == VariantGiveaway) // [HGM] losers:
-                       epStatus[forwardMostMove] = EP_WINS;    // in these variants stalemated is always a win
+                       boards[forwardMostMove][EP_STATUS] = EP_WINS;    // in these variants stalemated is always a win
                    else if(gameInfo.variant == VariantSuicide) // in suicide it depends
-                       epStatus[forwardMostMove] = NrW == NrPieces-NrW ? EP_STALEMATE :
+                       boards[forwardMostMove][EP_STATUS] = NrW == NrPieces-NrW ? EP_STALEMATE :
                                                   ((NrW < NrPieces-NrW) != WhiteOnMove(forwardMostMove) ?
                                                                        EP_CHECKMATE : EP_WINS);
                    else if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantXiangqi)
-                       epStatus[forwardMostMove] = EP_CHECKMATE; // and in these variants being stalemated loses
+                       boards[forwardMostMove][EP_STATUS] = EP_CHECKMATE; // and in these variants being stalemated loses
                }
                break;
              case MT_CHECKMATE:
                reason = "Xboard adjudication: Checkmate";
-               epStatus[forwardMostMove] = (gameInfo.variant == VariantLosers ? EP_WINS : EP_CHECKMATE);
+               boards[forwardMostMove][EP_STATUS] = (gameInfo.variant == VariantLosers ? EP_WINS : EP_CHECKMATE);
                break;
            }
 
-               switch(i = epStatus[forwardMostMove]) {
+               switch(i = (signed char)boards[forwardMostMove][EP_STATUS]) {
                    case EP_STALEMATE:
                        result = GameIsDrawn; break;
                    case EP_CHECKMATE:
@@ -6241,7 +6219,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                 {    /* KBK, KNK, KK of KBKB with like Bishops */
 
                      /* always flag draws, for judging claims */
-                     epStatus[forwardMostMove] = EP_INSUF_DRAW;
+                     boards[forwardMostMove][EP_STATUS] = EP_INSUF_DRAW;
 
                      if(appData.materialDraws) {
                          /* but only adjudicate them if adjudication enabled */
@@ -6274,10 +6252,10 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
          
          if (appData.debugMode) { int i;
            fprintf(debugFP, "repeat test fmm=%d bmm=%d ep=%d, reps=%d\n",
-                   forwardMostMove, backwardMostMove, epStatus[backwardMostMove],
+                   forwardMostMove, backwardMostMove, boards[backwardMostMove][EP_STATUS],
                    appData.drawRepeats);
            for( i=forwardMostMove; i>=backwardMostMove; i-- )
-             fprintf(debugFP, "%d ep=%d\n", i, epStatus[i]);
+             fprintf(debugFP, "%d ep=%d\n", i, (signed char)boards[i][EP_STATUS]);
            
          }
 
@@ -6285,26 +6263,26 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                 count = 0;
                 for(k = forwardMostMove-2;
                     k>=backwardMostMove && k>=forwardMostMove-100 &&
-                        epStatus[k] < EP_UNKNOWN &&
-                        epStatus[k+2] <= EP_NONE && epStatus[k+1] <= EP_NONE;
+                        (signed char)boards[k][EP_STATUS] < EP_UNKNOWN &&
+                        (signed char)boards[k+2][EP_STATUS] <= EP_NONE && (signed char)boards[k+1][EP_STATUS] <= EP_NONE;
                     k-=2)
                 {   int rights=0;
                     if(CompareBoards(boards[k], boards[forwardMostMove])) {
                         /* compare castling rights */
-                        if( castlingRights[forwardMostMove][2] != castlingRights[k][2] &&
-                             (castlingRights[k][0] >= 0 || castlingRights[k][1] >= 0) )
+                        if( boards[forwardMostMove][CASTLING][2] != boards[k][CASTLING][2] &&
+                             (boards[k][CASTLING][0] != NoRights || boards[k][CASTLING][1] != NoRights) )
                                 rights++; /* King lost rights, while rook still had them */
-                        if( castlingRights[forwardMostMove][2] >= 0 ) { /* king has rights */
-                            if( castlingRights[forwardMostMove][0] != castlingRights[k][0] ||
-                                castlingRights[forwardMostMove][1] != castlingRights[k][1] )
+                        if( boards[forwardMostMove][CASTLING][2] != NoRights ) { /* king has rights */
+                            if( boards[forwardMostMove][CASTLING][0] != boards[k][CASTLING][0] ||
+                                boards[forwardMostMove][CASTLING][1] != boards[k][CASTLING][1] )
                                    rights++; /* but at least one rook lost them */
                         }
-                        if( castlingRights[forwardMostMove][5] != castlingRights[k][5] &&
-                             (castlingRights[k][3] >= 0 || castlingRights[k][4] >= 0) )
-                                rights++;
-                        if( castlingRights[forwardMostMove][5] >= 0 ) {
-                            if( castlingRights[forwardMostMove][3] != castlingRights[k][3] ||
-                                castlingRights[forwardMostMove][4] != castlingRights[k][4] )
+                        if( boards[forwardMostMove][CASTLING][5] != boards[k][CASTLING][5] &&
+                             (boards[k][CASTLING][3] != NoRights || boards[k][CASTLING][4] != NoRights) )
+                                rights++; 
+                        if( boards[forwardMostMove][CASTLING][5] != NoRights ) {
+                            if( boards[forwardMostMove][CASTLING][3] != boards[k][CASTLING][3] ||
+                                boards[forwardMostMove][CASTLING][4] != boards[k][CASTLING][4] )
                                    rights++;
                         }
                         if( rights == 0 && ++count > appData.drawRepeats-2
@@ -6317,11 +6295,9 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                                // [HGM] xiangqi: check for forbidden perpetuals
                                int m, ourPerpetual = 1, hisPerpetual = 1;
                                for(m=forwardMostMove; m>k; m-=2) {
-                                   if(MateTest(boards[m], PosFlags(m),
-                                                       EP_NONE, castlingRights[m]) != MT_CHECK)
+                                   if(MateTest(boards[m], PosFlags(m)) != MT_CHECK)
                                        ourPerpetual = 0; // the current mover did not always check
-                                   if(MateTest(boards[m-1], PosFlags(m-1),
-                                                       EP_NONE, castlingRights[m-1]) != MT_CHECK)
+                                   if(MateTest(boards[m-1], PosFlags(m-1)) != MT_CHECK)
                                        hisPerpetual = 0; // the opponent did not always check
                                }
                                if(appData.debugMode) fprintf(debugFP, "XQ perpetual test, our=%d, his=%d\n",
@@ -6351,21 +6327,21 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                              return;
                         }
                         if( rights == 0 && count > 1 ) /* occurred 2 or more times before */
-                             epStatus[forwardMostMove] = EP_REP_DRAW;
+                             boards[forwardMostMove][EP_STATUS] = EP_REP_DRAW;
                     }
                 }
 
                 /* Now we test for 50-move draws. Determine ply count */
                 count = forwardMostMove;
                 /* look for last irreversble move */
-                while( epStatus[count] <= EP_NONE && count > backwardMostMove )
+                while( (signed char)boards[count][EP_STATUS] <= EP_NONE && count > backwardMostMove )
                     count--;
                 /* if we hit starting position, add initial plies */
                 if( count == backwardMostMove )
                     count -= initialRulePlies;
                 count = forwardMostMove - count;
                 if( count >= 100)
-                         epStatus[forwardMostMove] = EP_RULE_DRAW;
+                         boards[forwardMostMove][EP_STATUS] = EP_RULE_DRAW;
                          /* this is used to judge if draw claims are legal */
                 if(appData.ruleMoves > 0 && count >= 2*appData.ruleMoves) {
                         SendToProgram("force\n", cps->other); // suppress reply
@@ -6382,11 +6358,11 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
                  */
                 if( cps->other->offeredDraw || cps->offeredDraw ) {
                          char *p = NULL;
-                         if(epStatus[forwardMostMove] == EP_RULE_DRAW)
+                         if((signed char)boards[forwardMostMove][EP_STATUS] == EP_RULE_DRAW)
                              p = "Draw claim: 50-move rule";
-                         if(epStatus[forwardMostMove] == EP_REP_DRAW)
+                         if((signed char)boards[forwardMostMove][EP_STATUS] == EP_REP_DRAW)
                              p = "Draw claim: 3-fold repetition";
-                         if(epStatus[forwardMostMove] == EP_INSUF_DRAW)
+                         if((signed char)boards[forwardMostMove][EP_STATUS] == EP_INSUF_DRAW)
                              p = "Draw claim: insufficient mating material";
                          if( p != NULL ) {
                             SendToProgram("force\n", cps->other); // suppress reply
@@ -6488,7 +6464,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
      * want this, I was asked to put it in, and obliged.
      */
     if (!strncmp(message, "setboard ", 9)) {
-        Board initial_position; int i;
+        Board initial_position;
 
         GameEnds(GameUnfinished, "Engine aborts game", GE_XBOARD);
 
@@ -6499,9 +6475,6 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
            Reset(TRUE, FALSE);
            CopyBoard(boards[0], initial_position);
            initialRulePlies = FENrulePlies;
-           epStatus[0] = FENepStatus;
-           for( i=0; i<nrCastlingRights; i++ )
-                castlingRights[0][i] = FENcastlingRights[i];
            if(blackPlaysFirst) gameMode = MachinePlaysWhite;
            else gameMode = MachinePlaysBlack;
            DrawPosition(FALSE, boards[currentMove]);
@@ -6739,7 +6712,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats.
            if (ParseOneMove(buf1, forwardMostMove, &moveType,
                                 &fromX, &fromY, &toX, &toY, &promoChar)) {
                (void) CoordsToAlgebraic(boards[forwardMostMove],
-                                   PosFlags(forwardMostMove), EP_UNKNOWN,
+                                   PosFlags(forwardMostMove),
                                    fromY, fromX, toY, toX, promoChar, buf1);
                snprintf(buf2, sizeof(buf2), _("Hint: %s"), buf1);
                DisplayInformation(buf2);
@@ -7361,18 +7334,15 @@ ParseGameHistory(game)
            return;
        }
        (void) CoordsToAlgebraic(boards[boardIndex], PosFlags(boardIndex),
-                                EP_UNKNOWN, fromY, fromX, toY, toX, promoChar,
+                                fromY, fromX, toY, toX, promoChar,
                                 parseList[boardIndex]);
        CopyBoard(boards[boardIndex + 1], boards[boardIndex]);
-        {int i; for(i=0; i<BOARD_SIZE; i++) castlingRights[boardIndex+1][i] = castlingRights[boardIndex][i];}
        /* currentMoveString is set as a side-effect of yylex */
        strcpy(moveList[boardIndex], currentMoveString);
        strcat(moveList[boardIndex], "\n");
        boardIndex++;
-       ApplyMove(fromX, fromY, toX, toY, promoChar, boards[boardIndex],
-                                       castlingRights[boardIndex], &epStatus[boardIndex]);
-        switch (MateTest(boards[boardIndex], PosFlags(boardIndex),
-                                 EP_UNKNOWN, castlingRights[boardIndex]) ) {
+       ApplyMove(fromX, fromY, toX, toY, promoChar, boards[boardIndex]);
+        switch (MateTest(boards[boardIndex], PosFlags(boardIndex)) ) {
          case MT_NONE:
          case MT_STALEMATE:
          default:
@@ -7392,12 +7362,10 @@ ParseGameHistory(game)
 
 /* Apply a move to the given board  */
 void
-ApplyMove(fromX, fromY, toX, toY, promoChar, board, castling, ep)
+ApplyMove(fromX, fromY, toX, toY, promoChar, board)
      int fromX, fromY, toX, toY;
      int promoChar;
      Board board;
-     char *castling;
-     char *ep;
 {
   ChessSquare captured = board[toY][toX], piece, king; int p, oldEP = EP_NONE, berolina = 0;
 
@@ -7406,41 +7374,41 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board, castling, ep)
     { int i;
 
       if(gameInfo.variant == VariantBerolina) berolina = EP_BEROLIN_A;
-      oldEP = *ep;
-      *ep = EP_NONE;
+      oldEP = (signed char)board[EP_STATUS];
+      board[EP_STATUS] = EP_NONE;
 
-      if( board[toY][toX] != EmptySquare )
-           *ep = EP_CAPTURE;
+      if( board[toY][toX] != EmptySquare ) 
+           board[EP_STATUS] = EP_CAPTURE;  
 
       if( board[fromY][fromX] == WhitePawn ) {
            if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers
-              *ep = EP_PAWN_MOVE;
+              board[EP_STATUS] = EP_PAWN_MOVE;
            if( toY-fromY==2) {
                if(toX>BOARD_LEFT   && board[toY][toX-1] == BlackPawn &&
                        gameInfo.variant != VariantBerolina || toX < fromX)
-                     *ep = toX | berolina;
+                     board[EP_STATUS] = toX | berolina;
                if(toX<BOARD_RGHT-1 && board[toY][toX+1] == BlackPawn &&
-                       gameInfo.variant != VariantBerolina || toX > fromX)
-                     *ep = toX;
+                 gameInfo.variant != VariantBerolina || toX > fromX) 
+                board[EP_STATUS] = toX;
           }
       } else
       if( board[fromY][fromX] == BlackPawn ) {
            if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers
-              *ep = EP_PAWN_MOVE;
+              board[EP_STATUS] = EP_PAWN_MOVE; 
            if( toY-fromY== -2) {
                if(toX>BOARD_LEFT   && board[toY][toX-1] == WhitePawn &&
                        gameInfo.variant != VariantBerolina || toX < fromX)
-                     *ep = toX | berolina;
+                     board[EP_STATUS] = toX | berolina;
                if(toX<BOARD_RGHT-1 && board[toY][toX+1] == WhitePawn &&
-                       gameInfo.variant != VariantBerolina || toX > fromX)
-                     *ep = toX;
+                       gameInfo.variant != VariantBerolina || toX > fromX) 
+                     board[EP_STATUS] = toX;
           }
        }
 
        for(i=0; i<nrCastlingRights; i++) {
-           if(castling[i] == fromX && castlingRank[i] == fromY ||
-              castling[i] == toX   && castlingRank[i] == toY
-             ) castling[i] = -1; // revoke for moved or captured piece
+           if(board[CASTLING][i] == fromX && castlingRank[i] == fromY ||
+              board[CASTLING][i] == toX   && castlingRank[i] == toY   
+             ) board[CASTLING][i] = NoRights; // revoke for moved or captured piece
        }
 
     }
@@ -7749,7 +7717,7 @@ MakeMove(fromX, fromY, toX, toY, promoChar)
         fflush(serverMoves);
     }
 
-    if (forwardMostMove+1 >= MAX_MOVES) {
+    if (forwardMostMove+1 > framePtr) { // [HGM] vari: do not run into saved variations
       DisplayFatalError(_("Game too long; increase MAX_MOVES and recompile"),
                        0, 1);
       return;
@@ -7759,9 +7727,7 @@ MakeMove(fromX, fromY, toX, toY, promoChar)
        commentList[forwardMostMove+1] = NULL;
     }
     CopyBoard(boards[forwardMostMove+1], boards[forwardMostMove]);
-    {int i; for(i=0; i<BOARD_SIZE; i++) castlingRights[forwardMostMove+1][i] = castlingRights[forwardMostMove][i];}
-    ApplyMove(fromX, fromY, toX, toY, promoChar, boards[forwardMostMove+1],
-                               castlingRights[forwardMostMove+1], &epStatus[forwardMostMove+1]);
+    ApplyMove(fromX, fromY, toX, toY, promoChar, boards[forwardMostMove+1]);
     forwardMostMove++; // [HGM] bare: moved to after ApplyMove, to make sure clock interrupt finds complete board
     SwitchClocks(); // uses forwardMostMove, so must be done after incrementing it !
     timeRemaining[0][forwardMostMove] = whiteTimeRemaining;
@@ -7774,12 +7740,10 @@ MakeMove(fromX, fromY, toX, toY, promoChar)
     CoordsToComputerAlgebraic(fromY, fromX, toY, toX, promoChar,
                              moveList[forwardMostMove - 1]);
     (void) CoordsToAlgebraic(boards[forwardMostMove - 1],
-                            PosFlags(forwardMostMove - 1), EP_UNKNOWN,
+                            PosFlags(forwardMostMove - 1),
                             fromY, fromX, toY, toX, promoChar,
                             parseList[forwardMostMove - 1]);
-    switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove),
-                       epStatus[forwardMostMove], /* [HGM] use true e.p. */
-                            castlingRights[forwardMostMove]) ) {
+    switch (MateTest(boards[forwardMostMove], PosFlags(forwardMostMove)) ) {
       case MT_NONE:
       case MT_STALEMATE:
       default:
@@ -8186,15 +8150,15 @@ GameEnds(result, resultDetails, whosays)
                                             second.twoMachinesColor[0] ;
 
                // [HGM] losers: because the logic is becoming a bit hairy, determine true result first
-               if(epStatus[forwardMostMove] == EP_CHECKMATE) {
+               if((signed char)boards[forwardMostMove][EP_STATUS] == EP_CHECKMATE) {
                    /* [HGM] verify: engine mate claims accepted if they were flagged */
                    trueResult = WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins;
                } else
-               if(epStatus[forwardMostMove] == EP_WINS) { // added code for games where being mated is a win
+               if((signed char)boards[forwardMostMove][EP_STATUS] == EP_WINS) { // added code for games where being mated is a win
                    /* [HGM] verify: engine mate claims accepted if they were flagged */
                    trueResult = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins;
                } else
-               if(epStatus[forwardMostMove] == EP_STALEMATE) { // only used to indicate draws now
+               if((signed char)boards[forwardMostMove][EP_STATUS] == EP_STALEMATE) { // only used to indicate draws now
                    trueResult = GameIsDrawn; // default; in variants where stalemate loses, Status is CHECKMATE
                }
 
@@ -8205,7 +8169,7 @@ GameEnds(result, resultDetails, whosays)
                      result == BlackWins && claimer == 'b'   ) ) { // case to verify: engine claims own win
                      if (appData.debugMode) {
                        fprintf(debugFP, "result=%d sp=%d move=%d\n",
-                               result, epStatus[forwardMostMove], forwardMostMove);
+                               result, (signed char)boards[forwardMostMove][EP_STATUS], forwardMostMove);
                      }
                      if(result != trueResult) {
                              sprintf(buf, "False win claim: '%s'", resultDetails);
@@ -8213,9 +8177,9 @@ GameEnds(result, resultDetails, whosays)
                              resultDetails = buf;
                      }
                 } else
-                if( result == GameIsDrawn && epStatus[forwardMostMove] > EP_DRAWS
+                if( result == GameIsDrawn && (signed char)boards[forwardMostMove][EP_STATUS] > EP_DRAWS
                     && (forwardMostMove <= backwardMostMove ||
-                        epStatus[forwardMostMove-1] > EP_DRAWS ||
+                        (signed char)boards[forwardMostMove-1][EP_STATUS] > EP_DRAWS ||
                         (claimer=='b')==(forwardMostMove&1))
                                                                                   ) {
                       /* [HGM] verify: draws that were not flagged are false claims */
@@ -8233,7 +8197,7 @@ GameEnds(result, resultDetails, whosays)
               && result != GameIsDrawn)
            {   int i, j, k=0, color = (result==WhiteWins ? (int)WhitePawn : (int)BlackPawn);
                for(j=BOARD_LEFT; j<BOARD_RGHT; j++) for(i=0; i<BOARD_HEIGHT; i++) {
-                       int p = (int)boards[forwardMostMove][i][j] - color;
+                       int p = (signed char)boards[forwardMostMove][i][j] - color;
                        if(p >= 0 && p <= (int)WhiteKing) k++;
                }
                if (appData.debugMode) {
@@ -8544,6 +8508,7 @@ Reset(redraw, init)
        fprintf(debugFP, "Reset(%d, %d) from gameMode %d\n",
                redraw, init, gameMode);
     }
+    CleanupTail(); // [HGM] vari: delete any stored variations
     pausing = pauseExamInvalid = FALSE;
     startedFromSetupPosition = blackPlaysFirst = FALSE;
     firstMove = TRUE;
@@ -8715,14 +8680,9 @@ LoadGameOneMove(readAhead)
        if (appData.debugMode)
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
-       if (*p == '{' || *p == '[' || *p == '(') {
-           p[strlen(p) - 1] = NULLCHAR;
-           p++;
-       }
 
        /* append the comment but don't display it */
-       while (*p == '\n') p++;
-       AppendComment(currentMove, p);
+       AppendComment(currentMove, p, FALSE);
        return TRUE;
 
       case WhiteCapturesEnPassant:
@@ -8809,8 +8769,7 @@ LoadGameOneMove(readAhead)
       case (ChessMove) 0:      /* end of file */
        if (appData.debugMode)
          fprintf(debugFP, "Parser hit end of file\n");
-       switch (MateTest(boards[currentMove], PosFlags(currentMove),
-                         EP_UNKNOWN, castlingRights[currentMove]) ) {
+       switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
          case MT_NONE:
          case MT_CHECK:
            break;
@@ -8845,8 +8804,7 @@ LoadGameOneMove(readAhead)
        /* Reached start of next game in file */
        if (appData.debugMode)
          fprintf(debugFP, "Parsed start of next game: %s\n", yy_text);
-       switch (MateTest(boards[currentMove], PosFlags(currentMove),
-                         EP_UNKNOWN, castlingRights[currentMove]) ) {
+       switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
          case MT_NONE:
          case MT_CHECK:
            break;
@@ -9005,9 +8963,7 @@ MakeRegisteredMove()
            promoChar = cmailMove[lastLoadGameNumber - 1][4];
            MakeMove(fromX, fromY, toX, toY, promoChar);
            ShowMove(fromX, fromY, toX, toY);
-
-           switch (MateTest(boards[currentMove], PosFlags(currentMove),
-                             EP_UNKNOWN, castlingRights[currentMove]) ) {
+           switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
              case MT_NONE:
              case MT_CHECK:
                break;
@@ -9396,9 +9352,8 @@ LoadGame(f, gameNumber, title, useList)
           /* [HGM] copy FEN attributes as well. Bugfix 4.3.14m and 4.3.15e: moved to after 'blackPlaysFirst' */
           {   int i;
               initialRulePlies = FENrulePlies;
-              epStatus[forwardMostMove] = FENepStatus;
               for( i=0; i< nrCastlingRights; i++ )
-                  initialRights[i] = castlingRights[forwardMostMove][i] = FENcastlingRights[i];
+                  initialRights[i] = initial_position[CASTLING][i];
           }
          yyboardindex = forwardMostMove;
          free(gameInfo.fen);
@@ -9414,12 +9369,7 @@ LoadGame(f, gameNumber, title, useList)
            if (appData.debugMode)
              fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
            p = yy_text;
-           if (*p == '{' || *p == '[' || *p == '(') {
-               p[strlen(p) - 1] = NULLCHAR;
-               p++;
-           }
-           while (*p == '\n') p++;
-           AppendComment(currentMove, p);
+           AppendComment(currentMove, p, FALSE);
            yyboardindex = forwardMostMove;
            cm = (ChessMove) yylex();
        }
@@ -9520,12 +9470,7 @@ LoadGame(f, gameNumber, title, useList)
        if (appData.debugMode)
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
-       if (*p == '{' || *p == '[' || *p == '(') {
-           p[strlen(p) - 1] = NULLCHAR;
-           p++;
-       }
-       while (*p == '\n') p++;
-       AppendComment(currentMove, p);
+       AppendComment(currentMove, p, FALSE);
        yyboardindex = forwardMostMove;
        cm = (ChessMove) yylex();
     }
@@ -9747,17 +9692,11 @@ LoadPosition(f, positionNumber, title)
        currentMove = forwardMostMove = backwardMostMove = 0;
        DisplayMessage("", _("White to play"));
     }
-          /* [HGM] copy FEN attributes as well */
-          {   int i;
-              initialRulePlies = FENrulePlies;
-              epStatus[forwardMostMove] = FENepStatus;
-              for( i=0; i< nrCastlingRights; i++ )
-                  castlingRights[forwardMostMove][i] = FENcastlingRights[i];
-          }
+    initialRulePlies = FENrulePlies; /* [HGM] copy FEN attributes as well */
     SendBoard(&first, forwardMostMove);
     if (appData.debugMode) {
 int i, j;
-  for(i=0;i<2;i++){for(j=0;j<6;j++)fprintf(debugFP, " %d", castlingRights[i][j]);fprintf(debugFP,"\n");}
+  for(i=0;i<2;i++){for(j=0;j<6;j++)fprintf(debugFP, " %d", boards[i][CASTLING][j]);fprintf(debugFP,"\n");}
   for(j=0;j<6;j++)fprintf(debugFP, " %d", initialRights[j]);fprintf(debugFP,"\n");
         fprintf(debugFP, "Load Position\n");
     }
@@ -9977,7 +9916,7 @@ SaveGamePGN(f)
        /* Print comments preceding this move */
        if (commentList[i] != NULL) {
            if (linelen > 0) fprintf(f, "\n");
-           fprintf(f, "{\n%s}\n", commentList[i]);
+           fprintf(f, "%s", commentList[i]);
            linelen = 0;
            newblock = TRUE;
        }
@@ -10030,17 +9969,9 @@ SaveGamePGN(f)
         /* [AS] Add PV info if present */
         if( i >= 0 && appData.saveExtendedInfoInPGN && pvInfoList[i].depth > 0 ) {
             /* [HGM] add time */
-            char buf[MSG_SIZ]; int seconds = 0;
+            char buf[MSG_SIZ]; int seconds;
 
-            if(i >= backwardMostMove) {
-               if(WhiteOnMove(i))
-                       seconds = timeRemaining[0][i] - timeRemaining[0][i+1]
-                                 + GetTimeQuota(i/2) / (1000*WhitePlayer()->timeOdds);
-               else
-                       seconds = timeRemaining[1][i] - timeRemaining[1][i+1]
-                                  + GetTimeQuota(i/2) / (1000*WhitePlayer()->other->timeOdds);
-            }
-            seconds = (seconds+50)/100; // deci-seconds, rounded to nearest
+            seconds = (pvInfoList[i].time+5)/10; // deci-seconds, rounded to nearest
 
             if( seconds <= 0) buf[0] = 0; else
             if( seconds < 30 ) sprintf(buf, " %3.1f%c", seconds/10., 0); else {
@@ -10080,7 +10011,7 @@ SaveGamePGN(f)
 
     /* Print comments after last move */
     if (commentList[i] != NULL) {
-       fprintf(f, "{\n%s}\n", commentList[i]);
+       fprintf(f, "%s\n", commentList[i]);
     }
 
     /* Print result */
@@ -10169,7 +10100,7 @@ SaveGame(f, dummy, dummy2)
      int dummy;
      char *dummy2;
 {
-    if (gameMode == EditPosition) EditPositionDone();
+    if (gameMode == EditPosition) EditPositionDone(TRUE);
     lastSavedGame = GameCheckSum(); // [HGM] save: remember ID of last saved game to prevent double saving
     if (appData.oldSaveStyle)
       return SaveGameOldStyle(f);
@@ -10209,7 +10140,7 @@ SavePosition(f, dummy, dummy2)
 {
     time_t tm;
     char *fen;
-
+    if (gameMode == EditPosition) EditPositionDone(TRUE);
     if (appData.oldSaveStyle) {
        tm = time((time_t *) NULL);
 
@@ -10786,8 +10717,8 @@ MachineWhiteEvent()
        gameMode == EndOfGame)
        EditGameEvent();
 
-    if (gameMode == EditPosition)
-        EditPositionDone();
+    if (gameMode == EditPosition) 
+        EditPositionDone(TRUE);
 
     if (!WhiteOnMove(currentMove)) {
        DisplayError(_("It is not White's turn"), 0);
@@ -10867,8 +10798,8 @@ MachineBlackEvent()
        gameMode == EndOfGame)
         EditGameEvent();
 
-    if (gameMode == EditPosition)
-        EditPositionDone();
+    if (gameMode == EditPosition) 
+        EditPositionDone(TRUE);
 
     if (WhiteOnMove(currentMove)) {
        DisplayError(_("It is not Black's turn"), 0);
@@ -10975,7 +10906,7 @@ TwoMachinesEvent P((void))
        if (gameMode != EditGame) return;
        break;
       case EditPosition:
-       EditPositionDone();
+       EditPositionDone(TRUE);
        break;
       case AnalyzeMode:
       case AnalyzeFile:
@@ -10986,7 +10917,8 @@ TwoMachinesEvent P((void))
        break;
     }
 
-    forwardMostMove = currentMove;
+//    forwardMostMove = currentMove;
+    TruncateGame(); // [HGM] vari: MachineWhite and MachineBlack do this...
     ResurrectChessProgram();   /* in case first program isn't running */
 
     if (second.pr == NULL) {
@@ -11113,7 +11045,7 @@ IcsClientEvent()
        break;
 
       case EditPosition:
-       EditPositionDone();
+       EditPositionDone(TRUE);
        break;
 
       case AnalyzeMode:
@@ -11154,7 +11086,7 @@ EditGameEvent()
        }
        break;
       case EditPosition:
-       EditPositionDone();
+       EditPositionDone(TRUE);
        break;
       case AnalyzeMode:
       case AnalyzeFile:
@@ -11261,32 +11193,30 @@ ExitAnalyzeMode()
 }
 
 void
-EditPositionDone()
+EditPositionDone(Boolean fakeRights)
 {
     int king = gameInfo.variant == VariantKnightmate ? WhiteUnicorn : WhiteKing;
 
     startedFromSetupPosition = TRUE;
     InitChessProgram(&first, FALSE);
-    castlingRights[0][2] = castlingRights[0][5] = BOARD_WIDTH>>1;
+    if(fakeRights) { // [HGM] suppress this if we just pasted a FEN.
+      boards[0][EP_STATUS] = EP_NONE;
+      boards[0][CASTLING][2] = boards[0][CASTLING][5] = BOARD_WIDTH>>1;
     if(boards[0][0][BOARD_WIDTH>>1] == king) {
-       castlingRights[0][1] = boards[0][0][BOARD_LEFT] == WhiteRook ? 0 : -1;
-       castlingRights[0][0] = boards[0][0][BOARD_RGHT-1] == WhiteRook ? BOARD_RGHT-1 : -1;
-    } else castlingRights[0][2] = -1;
+       boards[0][CASTLING][1] = boards[0][0][BOARD_LEFT] == WhiteRook ? 0 : NoRights;
+       boards[0][CASTLING][0] = boards[0][0][BOARD_RGHT-1] == WhiteRook ? BOARD_RGHT-1 : NoRights;
+      } else boards[0][CASTLING][2] = NoRights;
     if(boards[0][BOARD_HEIGHT-1][BOARD_WIDTH>>1] == WHITE_TO_BLACK king) {
-       castlingRights[0][4] = boards[0][BOARD_HEIGHT-1][BOARD_LEFT] == BlackRook ? 0 : -1;
-       castlingRights[0][3] = boards[0][BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook ? BOARD_RGHT-1 : -1;
-    } else castlingRights[0][5] = -1;
+       boards[0][CASTLING][4] = boards[0][BOARD_HEIGHT-1][BOARD_LEFT] == BlackRook ? 0 : NoRights;
+       boards[0][CASTLING][3] = boards[0][BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook ? BOARD_RGHT-1 : NoRights;
+      } else boards[0][CASTLING][5] = NoRights;
+    }
     SendToProgram("force\n", &first);
     if (blackPlaysFirst) {
        strcpy(moveList[0], "");
        strcpy(parseList[0], "");
        currentMove = forwardMostMove = backwardMostMove = 1;
        CopyBoard(boards[1], boards[0]);
-       /* [HGM] copy rights as well, as this code is also used after pasting a FEN */
-       { int i;
-         epStatus[1] = epStatus[0];
-         for(i=0; i<nrCastlingRights; i++) castlingRights[1][i] = castlingRights[0][i];
-       }
     } else {
        currentMove = forwardMostMove = backwardMostMove = 0;
     }
@@ -11554,7 +11484,7 @@ DeclineEvent()
            StrStr(commentList[cmailOldMove], WhiteOnMove(cmailOldMove) ?
                   "Black offers a draw" : "White offers a draw")) {
 #ifdef NOTDEF
-           AppendComment(cmailOldMove, "Draw declined");
+           AppendComment(cmailOldMove, "Draw declined", TRUE);
            DisplayComment(cmailOldMove - 1, "Draw declined");
 #endif /*NOTDEF*/
        } else {
@@ -11636,7 +11566,7 @@ DrawEvent()
        } else if (currentMove == cmailOldMove + 1) {
            char *offer = WhiteOnMove(cmailOldMove) ?
              "White offers a draw" : "Black offers a draw";
-           AppendComment(currentMove, offer);
+           AppendComment(currentMove, offer, TRUE);
            DisplayComment(currentMove - 1, offer);
            cmailMoveType[lastLoadGameNumber - 1] = CMAIL_DRAW;
        } else {
@@ -11912,7 +11842,7 @@ void
 ToStartEvent()
 {
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
-       /* to optimze, we temporarily turn off analysis mode while we undo
+       /* to optimize, we temporarily turn off analysis mode while we undo
         * all the moves. Otherwise we get analysis output after each undo.
         */
         if (first.analysisSupport) {
@@ -11953,6 +11883,9 @@ ToNrEvent(int to)
 void
 RevertEvent()
 {
+    if(PopTail(TRUE)) { // [HGM] vari: restore old game tail
+       return;
+    }
     if (gameMode != IcsExamining) {
        DisplayError(_("You are not examining a game"), 0);
        return;
@@ -12050,6 +11983,7 @@ TruncateGameEvent()
 void
 TruncateGame()
 {
+    CleanupTail(); // [HGM] vari: only keep current variation if we explicitly truncate
     if (forwardMostMove > currentMove) {
        if (gameInfo.resultDetails != NULL) {
            free(gameInfo.resultDetails);
@@ -12107,7 +12041,7 @@ BookEvent()
        }
        break;
       case EditPosition:
-       EditPositionDone();
+       EditPositionDone(TRUE);
        break;
       case TwoMachinesPlay:
        return;
@@ -12212,6 +12146,14 @@ SetGameInfo()
 {
     /* This routine is used only for certain modes */
     VariantClass v = gameInfo.variant;
+    ChessMove r = GameUnfinished;
+    char *p = NULL;
+
+    if(gameMode == EditGame) { // [HGM] vari: do not erase result on EditGame
+       r = gameInfo.result; 
+       p = gameInfo.resultDetails; 
+       gameInfo.resultDetails = NULL;
+    }
     ClearGameInfo(&gameInfo);
     gameInfo.variant = v;
 
@@ -12264,6 +12206,8 @@ SetGameInfo()
        gameInfo.round = StrSave("-");
        gameInfo.white = StrSave("-");
        gameInfo.black = StrSave("-");
+       gameInfo.result = r;
+       gameInfo.resultDetails = p;
        break;
 
       case EditPosition:
@@ -12313,10 +12257,23 @@ ReplaceComment(index, text)
        commentList[index] = NULL;
        return;
     }
+  if( *text == '{' && strchr(text, '}') || // [HGM] braces: if certainy malformed, put braces
+      *text == '[' && strchr(text, ']') || // otherwise hope the user knows what he is doing
+      *text == '(' && strchr(text, ')')) { // (perhaps check if this parses as comment-only?)
     commentList[index] = (char *) malloc(len + 2);
     strncpy(commentList[index], text, len);
     commentList[index][len] = '\n';
     commentList[index][len + 1] = NULLCHAR;
+  } else { 
+    // [HGM] braces: if text does not start with known OK delimiter, put braces around it.
+    char *p;
+    commentList[index] = (char *) malloc(len + 6);
+    strcpy(commentList[index], "{\n");
+    strncpy(commentList[index]+2, text, len);
+    commentList[index][len+2] = NULLCHAR;
+    while(p = strchr(commentList[index], '}')) *p = ')'; // kill all } to make it one comment
+    strcat(commentList[index], "\n}\n");
+  }
 }
 
 void
@@ -12335,13 +12292,15 @@ CrushCRs(text)
 }
 
 void
-AppendComment(index, text)
+AppendComment(index, text, addBraces)
      int index;
      char *text;
+     Boolean addBraces; // [HGM] braces: tells if we should add {}
 {
     int oldlen, len;
     char *old;
 
+if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces); fflush(debugFP);
     text = GetInfoFromComment( index, text ); /* [HGM] PV time: strip PV info from comment */
 
     CrushCRs(text);
@@ -12354,17 +12313,30 @@ AppendComment(index, text)
     if (commentList[index] != NULL) {
        old = commentList[index];
        oldlen = strlen(old);
-       commentList[index] = (char *) malloc(oldlen + len + 2);
+       while(commentList[index][oldlen-1] ==  '\n')
+         commentList[index][--oldlen] = NULLCHAR;
+       commentList[index] = (char *) malloc(oldlen + len + 6); // might waste 4
        strcpy(commentList[index], old);
        free(old);
-       strncpy(&commentList[index][oldlen], text, len);
-       commentList[index][oldlen + len] = '\n';
-       commentList[index][oldlen + len + 1] = NULLCHAR;
+       // [HGM] braces: join "{A\n}\n" + "{\nB}" as "{A\nB\n}"
+       if(commentList[index][oldlen-1] == '}' && (text[0] == '{' || addBraces)) {
+         if(addBraces) addBraces = FALSE; else { text++; len--; }
+         while (*text == '\n') { text++; len--; }
+         commentList[index][--oldlen] = NULLCHAR;
+      }
+       if(addBraces) strcat(commentList[index], "\n{\n");
+       else          strcat(commentList[index], "\n");
+       strcat(commentList[index], text);
+       if(addBraces) strcat(commentList[index], "\n}\n");
+       else          strcat(commentList[index], "\n");
     } else {
-       commentList[index] = (char *) malloc(len + 2);
-       strncpy(commentList[index], text, len);
-       commentList[index][len] = '\n';
-       commentList[index][len + 1] = NULLCHAR;
+       commentList[index] = (char *) malloc(len + 6); // perhaps wastes 4...
+       if(addBraces)
+            strcpy(commentList[index], "{\n");
+       else commentList[index][0] = NULLCHAR;
+       strcat(commentList[index], text);
+       strcat(commentList[index], "\n");
+       if(addBraces) strcat(commentList[index], "}\n");
     }
 }
 
@@ -12408,21 +12380,24 @@ char *GetInfoFromComment( int index, char * text )
 
             if( s_emt != NULL ) {
             }
+               return text;
         }
         else {
             /* We expect something like: [+|-]nnn.nn/dd */
             int score_lo = 0;
 
+            if(*text != '{') return text; // [HGM] braces: must be normal comment
+
             sep = strchr( text, '/' );
             if( sep == NULL || sep < (text+4) ) {
                 return text;
             }
 
             time = -1; sec = -1; deci = -1;
-            if( sscanf( text, "%d.%d/%d %d:%d", &score, &score_lo, &depth, &time, &sec ) != 5 &&
-               sscanf( text, "%d.%d/%d %d.%d", &score, &score_lo, &depth, &time, &deci ) != 5 &&
-                sscanf( text, "%d.%d/%d %d", &score, &score_lo, &depth, &time ) != 4 &&
-                sscanf( text, "%d.%d/%d", &score, &score_lo, &depth ) != 3   ) {
+            if( sscanf( text+1, "%d.%d/%d %d:%d", &score, &score_lo, &depth, &time, &sec ) != 5 &&
+               sscanf( text+1, "%d.%d/%d %d.%d", &score, &score_lo, &depth, &time, &deci ) != 5 &&
+                sscanf( text+1, "%d.%d/%d %d", &score, &score_lo, &depth, &time ) != 4 &&
+                sscanf( text+1, "%d.%d/%d", &score, &score_lo, &depth ) != 3   ) {
                 return text;
             }
 
@@ -12457,6 +12432,7 @@ char *GetInfoFromComment( int index, char * text )
         pvInfoList[index-1].depth = depth;
         pvInfoList[index-1].score = score;
         pvInfoList[index-1].time  = 10*time; // centi-sec
+        if(*sep == '}') *sep = 0; else *--sep = '{';
     }
     return sep;
 }
@@ -12486,13 +12462,13 @@ SendToProgram(message, cps)
                          && !endingGame) { /* [HGM] crash: to not hang GameEnds() writing to deceased engines */
        sprintf(buf, _("Error writing to %s chess program"), cps->which);
         if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */
-            if(epStatus[forwardMostMove] <= EP_DRAWS) {
+            if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
                 gameInfo.result = GameIsDrawn; /* [HGM] accept exit as draw claim */
                 sprintf(buf, "%s program exits in draw position (%s)", cps->which, cps->program);
             } else {
                 gameInfo.result = cps->twoMachinesColor[0]=='w' ? BlackWins : WhiteWins;
             }
-            gameInfo.resultDetails = buf;
+            gameInfo.resultDetails = StrSave(buf);
         }
         DisplayFatalError(buf, error, 1);
     }
@@ -12517,13 +12493,13 @@ ReceiveFromProgram(isr, closure, message, count, error)
                    _("Error: %s chess program (%s) exited unexpectedly"),
                    cps->which, cps->program);
         if(gameInfo.resultDetails==NULL) { /* [HGM] crash: if game in progress, give reason for abort */
-                if(epStatus[forwardMostMove] <= EP_DRAWS) {
+                if((signed char)boards[forwardMostMove][EP_STATUS] <= EP_DRAWS) {
                     gameInfo.result = GameIsDrawn; /* [HGM] accept exit as draw claim */
                     sprintf(buf, _("%s program exits in draw position (%s)"), cps->which, cps->program);
                 } else {
                     gameInfo.result = cps->twoMachinesColor[0]=='w' ? BlackWins : WhiteWins;
                 }
-                gameInfo.resultDetails = buf;
+                gameInfo.resultDetails = StrSave(buf);
             }
            RemoveInputSource(cps->isr);
            DisplayFatalError(buf, 0, 1);
@@ -12971,7 +12947,7 @@ PonderNextMoveEvent(newState)
      int newState;
 {
     if (newState == appData.ponderNextMove) return;
-    if (gameMode == EditPosition) EditPositionDone();
+    if (gameMode == EditPosition) EditPositionDone(TRUE);
     if (newState) {
        SendToProgram("hard\n", &first);
        if (gameMode == TwoMachinesPlay) {
@@ -12994,7 +12970,7 @@ NewSettingEvent(option, command, value)
 {
     char buf[MSG_SIZ];
 
-    if (gameMode == EditPosition) EditPositionDone();
+    if (gameMode == EditPosition) EditPositionDone(TRUE);
     sprintf(buf, "%s%s %d\n", (option ? "option ": ""), command, value);
     SendToProgram(buf, &first);
     if (gameMode == TwoMachinesPlay) {
@@ -13013,7 +12989,7 @@ ShowThinkingEvent()
 
     if (oldState == newState) return;
     oldState = newState;
-    if (gameMode == EditPosition) EditPositionDone();
+    if (gameMode == EditPosition) EditPositionDone(TRUE);
     if (oldState) {
        SendToProgram("post\n", &first);
        if (gameMode == TwoMachinesPlay) {
@@ -13210,7 +13186,7 @@ CheckFlags()
 void
 CheckTimeControl()
 {
-    if (!appData.clockMode || appData.icsActive ||
+    if (!appData.clockMode || appData.icsActive || searchTime || // [HGM] st: no inc in st mode
        gameMode == PlayFromGameFile || forwardMostMove == 0) return;
 
     /*
@@ -13336,6 +13312,9 @@ ResetClocks()
     (void) StopClockTimer();
     if (appData.icsActive) {
        whiteTimeRemaining = blackTimeRemaining = 0;
+    } else if (searchTime) {
+       whiteTimeRemaining = 1000*searchTime / WhitePlayer()->timeOdds;
+       blackTimeRemaining = 1000*searchTime / WhitePlayer()->other->timeOdds;
     } else { /* [HGM] correct new time quote for time odds */
         whiteTimeRemaining = GetTimeQuota(-1) / WhitePlayer()->timeOdds;
         blackTimeRemaining = GetTimeQuota(-1) / WhitePlayer()->other->timeOdds;
@@ -13465,6 +13444,12 @@ SwitchClocks()
        break;
     }
 
+    if (searchTime) { // [HGM] st: set clock of player that has to move to max time
+       if(WhiteOnMove(forwardMostMove))
+            whiteTimeRemaining = 1000*searchTime / WhitePlayer()->timeOdds;
+       else blackTimeRemaining = 1000*searchTime / WhitePlayer()->other->timeOdds;
+    }
+
     tickStartTM = now;
     intendedTickLength = NextTickLength(WhiteOnMove(forwardMostMove) ?
       whiteTimeRemaining : blackTimeRemaining);
@@ -13770,30 +13755,30 @@ PositionToFEN(move, overrideCastling)
      q = p;
      if(gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom) {
        /* [HGM] write directly from rights */
-           if(castlingRights[move][2] >= 0 &&
-              castlingRights[move][0] >= 0   )
-                *p++ = castlingRights[move][0] + AAA + 'A' - 'a';
-           if(castlingRights[move][2] >= 0 &&
-              castlingRights[move][1] >= 0   )
-                *p++ = castlingRights[move][1] + AAA + 'A' - 'a';
-           if(castlingRights[move][5] >= 0 &&
-              castlingRights[move][3] >= 0   )
-                *p++ = castlingRights[move][3] + AAA;
-           if(castlingRights[move][5] >= 0 &&
-              castlingRights[move][4] >= 0   )
-                *p++ = castlingRights[move][4] + AAA;
+           if(boards[move][CASTLING][2] != NoRights &&
+              boards[move][CASTLING][0] != NoRights   )
+                *p++ = boards[move][CASTLING][0] + AAA + 'A' - 'a';
+           if(boards[move][CASTLING][2] != NoRights &&
+              boards[move][CASTLING][1] != NoRights   )
+                *p++ = boards[move][CASTLING][1] + AAA + 'A' - 'a';
+           if(boards[move][CASTLING][5] != NoRights &&
+              boards[move][CASTLING][3] != NoRights   )
+                *p++ = boards[move][CASTLING][3] + AAA;
+           if(boards[move][CASTLING][5] != NoRights &&
+              boards[move][CASTLING][4] != NoRights   )
+                *p++ = boards[move][CASTLING][4] + AAA;
      } else {
 
         /* [HGM] write true castling rights */
         if( nrCastlingRights == 6 ) {
-            if(castlingRights[move][0] == BOARD_RGHT-1 &&
-               castlingRights[move][2] >= 0  ) *p++ = 'K';
-            if(castlingRights[move][1] == BOARD_LEFT &&
-               castlingRights[move][2] >= 0  ) *p++ = 'Q';
-            if(castlingRights[move][3] == BOARD_RGHT-1 &&
-               castlingRights[move][5] >= 0  ) *p++ = 'k';
-            if(castlingRights[move][4] == BOARD_LEFT &&
-               castlingRights[move][5] >= 0  ) *p++ = 'q';
+            if(boards[move][CASTLING][0] == BOARD_RGHT-1 &&
+               boards[move][CASTLING][2] != NoRights  ) *p++ = 'K';
+            if(boards[move][CASTLING][1] == BOARD_LEFT &&
+               boards[move][CASTLING][2] != NoRights  ) *p++ = 'Q';
+            if(boards[move][CASTLING][3] == BOARD_RGHT-1 &&
+               boards[move][CASTLING][5] != NoRights  ) *p++ = 'k';
+            if(boards[move][CASTLING][4] == BOARD_LEFT &&
+               boards[move][CASTLING][5] != NoRights  ) *p++ = 'q';
         }
      }
      if (q == p) *p++ = '-'; /* No castling rights */
@@ -13820,8 +13805,8 @@ PositionToFEN(move, overrideCastling)
        }
     } else if(move == backwardMostMove) {
        // [HGM] perhaps we should always do it like this, and forget the above?
-       if(epStatus[move] >= 0) {
-           *p++ = epStatus[move] + AAA;
+       if((signed char)boards[move][EP_STATUS] >= 0) {
+           *p++ = boards[move][EP_STATUS] + AAA;
            *p++ = whiteToPlay ? '6'+BOARD_HEIGHT-8 : '3';
        } else {
            *p++ = '-';
@@ -13839,11 +13824,11 @@ PositionToFEN(move, overrideCastling)
         if (appData.debugMode) { int k;
             fprintf(debugFP, "write FEN 50-move: %d %d %d\n", initialRulePlies, forwardMostMove, backwardMostMove);
             for(k=backwardMostMove; k<=forwardMostMove; k++)
-                fprintf(debugFP, "e%d. p=%d\n", k, epStatus[k]);
+                fprintf(debugFP, "e%d. p=%d\n", k, (signed char)boards[k][EP_STATUS]);
 
         }
 
-        while(j > backwardMostMove && epStatus[j] <= EP_NONE) j--,i++;
+        while(j > backwardMostMove && (signed char)boards[j][EP_STATUS] <= EP_NONE) j--,i++;
         if( j == backwardMostMove ) i += initialRulePlies;
         sprintf(p, "%d ", i);
         p += i>=100 ? 4 : i >= 10 ? 3 : 2;
@@ -13887,7 +13872,7 @@ ParseFEN(board, blackPlaysFirst, fen)
                 while (emptycount--)
                         board[i][(j++)+gameInfo.holdingsWidth] = EmptySquare;
                break;
-#if(BOARD_SIZE >= 10)
+#if(BOARD_FILES >= 10)
             } else if(*p=='x' || *p=='X') { /* [HGM] X means 10 */
                 p++; emptycount=10;
                 if (j + emptycount > gameInfo.boardWidth) return FALSE;
@@ -13969,17 +13954,17 @@ ParseFEN(board, blackPlaysFirst, fen)
     /* return the extra info in global variiables             */
 
     /* set defaults in case FEN is incomplete */
-    FENepStatus = EP_UNKNOWN;
+    board[EP_STATUS] = EP_UNKNOWN;
     for(i=0; i<nrCastlingRights; i++ ) {
-        FENcastlingRights[i] =
-            gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom ? -1 : initialRights[i];
+        board[CASTLING][i] =
+            gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom ? NoRights : initialRights[i];
     }   /* assume possible unless obviously impossible */
-    if(initialRights[0]>=0 && board[castlingRank[0]][initialRights[0]] != WhiteRook) FENcastlingRights[0] = -1;
-    if(initialRights[1]>=0 && board[castlingRank[1]][initialRights[1]] != WhiteRook) FENcastlingRights[1] = -1;
-    if(initialRights[2]>=0 && board[castlingRank[2]][initialRights[2]] != WhiteKing) FENcastlingRights[2] = -1;
-    if(initialRights[3]>=0 && board[castlingRank[3]][initialRights[3]] != BlackRook) FENcastlingRights[3] = -1;
-    if(initialRights[4]>=0 && board[castlingRank[4]][initialRights[4]] != BlackRook) FENcastlingRights[4] = -1;
-    if(initialRights[5]>=0 && board[castlingRank[5]][initialRights[5]] != BlackKing) FENcastlingRights[5] = -1;
+    if(initialRights[0]>=0 && board[castlingRank[0]][initialRights[0]] != WhiteRook) board[CASTLING][0] = NoRights;
+    if(initialRights[1]>=0 && board[castlingRank[1]][initialRights[1]] != WhiteRook) board[CASTLING][1] = NoRights;
+    if(initialRights[2]>=0 && board[castlingRank[2]][initialRights[2]] != WhiteKing) board[CASTLING][2] = NoRights;
+    if(initialRights[3]>=0 && board[castlingRank[3]][initialRights[3]] != BlackRook) board[CASTLING][3] = NoRights;
+    if(initialRights[4]>=0 && board[castlingRank[4]][initialRights[4]] != BlackRook) board[CASTLING][4] = NoRights;
+    if(initialRights[5]>=0 && board[castlingRank[5]][initialRights[5]] != BlackKing) board[CASTLING][5] = NoRights;
     FENrulePlies = 0;
 
     while(*p==' ') p++;
@@ -13987,7 +13972,7 @@ ParseFEN(board, blackPlaysFirst, fen)
       if(*p=='K' || *p=='Q' || *p=='k' || *p=='q' || *p=='-') {
           /* castling indicator present, so default becomes no castlings */
           for(i=0; i<nrCastlingRights; i++ ) {
-                 FENcastlingRights[i] = -1;
+                 board[CASTLING][i] = NoRights;
           }
       }
       while(*p=='K' || *p=='Q' || *p=='k' || *p=='q' || *p=='-' ||
@@ -14003,23 +13988,23 @@ ParseFEN(board, blackPlaysFirst, fen)
         switch(c) {
           case'K':
               for(i=BOARD_RGHT-1; board[0][i]!=WhiteRook && i>whiteKingFile; i--);
-              FENcastlingRights[0] = i != whiteKingFile ? i : -1;
-              FENcastlingRights[2] = whiteKingFile;
+              board[CASTLING][0] = i != whiteKingFile ? i : NoRights;
+              board[CASTLING][2] = whiteKingFile;
               break;
           case'Q':
               for(i=BOARD_LEFT; board[0][i]!=WhiteRook && i<whiteKingFile; i++);
-              FENcastlingRights[1] = i != whiteKingFile ? i : -1;
-              FENcastlingRights[2] = whiteKingFile;
+              board[CASTLING][1] = i != whiteKingFile ? i : NoRights;
+              board[CASTLING][2] = whiteKingFile;
               break;
           case'k':
               for(i=BOARD_RGHT-1; board[BOARD_HEIGHT-1][i]!=BlackRook && i>blackKingFile; i--);
-              FENcastlingRights[3] = i != blackKingFile ? i : -1;
-              FENcastlingRights[5] = blackKingFile;
+              board[CASTLING][3] = i != blackKingFile ? i : NoRights;
+              board[CASTLING][5] = blackKingFile;
               break;
           case'q':
               for(i=BOARD_LEFT; board[BOARD_HEIGHT-1][i]!=BlackRook && i<blackKingFile; i++);
-              FENcastlingRights[4] = i != blackKingFile ? i : -1;
-              FENcastlingRights[5] = blackKingFile;
+              board[CASTLING][4] = i != blackKingFile ? i : NoRights;
+              board[CASTLING][5] = blackKingFile;
           case '-':
               break;
           default: /* FRC castlings */
@@ -14027,32 +14012,32 @@ ParseFEN(board, blackPlaysFirst, fen)
                   for(i=BOARD_LEFT; i<BOARD_RGHT; i++)
                     if(board[BOARD_HEIGHT-1][i] == BlackKing) break;
                   if(i == BOARD_RGHT) break;
-                  FENcastlingRights[5] = i;
+                  board[CASTLING][5] = i;
                   c -= AAA;
                   if(board[BOARD_HEIGHT-1][c] <  BlackPawn ||
                      board[BOARD_HEIGHT-1][c] >= BlackKing   ) break;
                   if(c > i)
-                      FENcastlingRights[3] = c;
+                      board[CASTLING][3] = c;
                   else
-                      FENcastlingRights[4] = c;
+                      board[CASTLING][4] = c;
               } else { /* white rights */
                   for(i=BOARD_LEFT; i<BOARD_RGHT; i++)
                     if(board[0][i] == WhiteKing) break;
                   if(i == BOARD_RGHT) break;
-                  FENcastlingRights[2] = i;
+                  board[CASTLING][2] = i;
                   c -= AAA - 'a' + 'A';
                   if(board[0][c] >= WhiteKing) break;
                   if(c > i)
-                      FENcastlingRights[0] = c;
+                      board[CASTLING][0] = c;
                   else
-                      FENcastlingRights[1] = c;
+                      board[CASTLING][1] = c;
               }
         }
       }
     if (appData.debugMode) {
         fprintf(debugFP, "FEN castling rights:");
         for(i=0; i<nrCastlingRights; i++)
-        fprintf(debugFP, " %d", FENcastlingRights[i]);
+        fprintf(debugFP, " %d", board[CASTLING][i]);
         fprintf(debugFP, "\n");
     }
 
@@ -14063,13 +14048,13 @@ ParseFEN(board, blackPlaysFirst, fen)
     if(gameInfo.variant != VariantShogi    && gameInfo.variant != VariantXiangqi &&
        gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier ) {
       if(*p=='-') {
-        p++; FENepStatus = EP_NONE;
+        p++; board[EP_STATUS] = EP_NONE;
       } else {
          char c = *p++ - AAA;
 
          if(c < BOARD_LEFT || c >= BOARD_RGHT) return TRUE;
          if(*p >= '0' && *p <='9') *p++;
-         FENepStatus = c;
+         board[EP_STATUS] = c;
       }
     }
 
@@ -14096,14 +14081,8 @@ EditPositionPasteFEN(char *fen)
       EditPositionEvent();
       blackPlaysFirst = savedBlackPlaysFirst;
       CopyBoard(boards[0], initial_position);
-          /* [HGM] copy FEN attributes as well */
-          {   int i;
-              initialRulePlies = FENrulePlies;
-              epStatus[0] = FENepStatus;
-              for( i=0; i<nrCastlingRights; i++ )
-                  castlingRights[0][i] = FENcastlingRights[i];
-          }
-      EditPositionDone();
+      initialRulePlies = FENrulePlies; /* [HGM] copy FEN attributes as well */
+      EditPositionDone(FALSE); // [HGM] fake: do not fake rights if we had FEN
       DisplayBothClocks();
       DrawPosition(FALSE, boards[currentMove]);
     }
@@ -14216,3 +14195,110 @@ int wrap(char *dest, char *src, int count, int width, int *lp)
 
     return len;
 }
+
+// [HGM] vari: routines for shelving variations
+
+void 
+PushTail(int firstMove, int lastMove)
+{
+       int i, j, nrMoves = lastMove - firstMove;
+
+       if(appData.icsActive) { // only in local mode
+               forwardMostMove = currentMove; // mimic old ICS behavior
+               return;
+       }
+       if(storedGames >= MAX_VARIATIONS-1) return;
+
+       // push current tail of game on stack
+       savedResult[storedGames] = gameInfo.result;
+       savedDetails[storedGames] = gameInfo.resultDetails;
+       gameInfo.resultDetails = NULL;
+       savedFirst[storedGames] = firstMove;
+       savedLast [storedGames] = lastMove;
+       savedFramePtr[storedGames] = framePtr;
+       framePtr -= nrMoves; // reserve space for the boards
+       for(i=nrMoves; i>=1; i--) { // copy boards to stack, working downwards, in case of overlap
+           CopyBoard(boards[framePtr+i], boards[firstMove+i]);
+           for(j=0; j<MOVE_LEN; j++)
+               moveList[framePtr+i][j] = moveList[firstMove+i-1][j];
+           for(j=0; j<2*MOVE_LEN; j++)
+               parseList[framePtr+i][j] = parseList[firstMove+i-1][j];
+           timeRemaining[0][framePtr+i] = timeRemaining[0][firstMove+i];
+           timeRemaining[1][framePtr+i] = timeRemaining[1][firstMove+i];
+           pvInfoList[framePtr+i] = pvInfoList[firstMove+i-1];
+           pvInfoList[firstMove+i-1].depth = 0;
+           commentList[framePtr+i] = commentList[firstMove+i];
+           commentList[firstMove+i] = NULL;
+       }
+
+       storedGames++;
+       forwardMostMove = currentMove; // truncte game so we can start variation
+       if(storedGames == 1) GreyRevert(FALSE);
+}
+
+Boolean
+PopTail(Boolean annotate)
+{
+       int i, j, nrMoves;
+       char buf[8000], moveBuf[20];
+
+       if(appData.icsActive) return FALSE; // only in local mode
+       if(!storedGames) return FALSE; // sanity
+
+       storedGames--;
+       ToNrEvent(savedFirst[storedGames]); // sets currentMove
+       nrMoves = savedLast[storedGames] - currentMove;
+       if(annotate) {
+               int cnt = 10;
+               if(!WhiteOnMove(currentMove)) sprintf(buf, "(%d...", currentMove+2>>1);
+               else strcpy(buf, "(");
+               for(i=currentMove; i<forwardMostMove; i++) {
+                       if(WhiteOnMove(i))
+                            sprintf(moveBuf, " %d. %s", i+2>>1, SavePart(parseList[i]));
+                       else sprintf(moveBuf, " %s", SavePart(parseList[i]));
+                       strcat(buf, moveBuf);
+                       if(!--cnt) { strcat(buf, "\n"); cnt = 10; }
+               }
+               strcat(buf, ")");
+       }
+       for(i=1; i<nrMoves; i++) { // copy last variation back
+           CopyBoard(boards[currentMove+i], boards[framePtr+i]);
+           for(j=0; j<MOVE_LEN; j++)
+               moveList[currentMove+i-1][j] = moveList[framePtr+i][j];
+           for(j=0; j<2*MOVE_LEN; j++)
+               parseList[currentMove+i-1][j] = parseList[framePtr+i][j];
+           timeRemaining[0][currentMove+i] = timeRemaining[0][framePtr+i];
+           timeRemaining[1][currentMove+i] = timeRemaining[1][framePtr+i];
+           pvInfoList[currentMove+i-1] = pvInfoList[framePtr+i];
+           if(commentList[currentMove+i]) free(commentList[currentMove+i]);
+           commentList[currentMove+i] = commentList[framePtr+i];
+           commentList[framePtr+i] = NULL;
+       }
+       if(annotate) AppendComment(currentMove+1, buf, FALSE);
+       framePtr = savedFramePtr[storedGames];
+       gameInfo.result = savedResult[storedGames];
+       if(gameInfo.resultDetails != NULL) {
+           free(gameInfo.resultDetails);
+      }
+       gameInfo.resultDetails = savedDetails[storedGames];
+       forwardMostMove = currentMove + nrMoves;
+       if(storedGames == 0) GreyRevert(TRUE);
+       return TRUE;
+}
+
+void 
+CleanupTail()
+{      // remove all shelved variations
+       int i;
+       for(i=0; i<storedGames; i++) {
+           if(savedDetails[i])
+               free(savedDetails[i]);
+           savedDetails[i] = NULL;
+       }
+       for(i=framePtr; i<MAX_MOVES; i++) {
+               if(commentList[i]) free(commentList[i]);
+               commentList[i] = NULL;
+       }
+       framePtr = MAX_MOVES-1;
+       storedGames = 0;
+}
index b44c45a..3ad4966 100644 (file)
--- a/backend.h
+++ b/backend.h
@@ -181,7 +181,7 @@ void ProcessICSInitScript P((FILE * f));
 void EditCommentEvent P((void));
 void ReplaceComment P((int index, char *text));
 int ReplaceTags P((char *tags, GameInfo *gi));/* returns nonzero on error */
-void AppendComment P((int index, char *text));
+void AppendComment P((int index, char *text, Boolean addBraces));
 void ReloadCmailMsgEvent P((int unregister));
 void MailMoveEvent P((void));
 void EditTagsEvent P((void));
@@ -347,13 +347,6 @@ typedef struct _CPS {
 
 extern ChessProgramState first, second;
 
-/* [AS] Search stats from chessprogram, for the played move */
-typedef struct {
-    int score;  /* Centipawns */
-    int depth;  /* Plies */
-    int time;   /* Milliseconds */
-} ChessProgramStats_Move;
-
 /* Search stats from chessprogram */
 typedef struct {
   char movelist[2*MSG_SIZ]; /* Last PV we were sent */
@@ -374,5 +367,6 @@ typedef struct {
 extern ChessProgramStats_Move pvInfoList[MAX_MOVES];
 extern int shuffleOpenings;
 extern ChessProgramStats programStats;
+extern int opponentKibitzes; // used by wengineo.c
 
 #endif /* _BACKEND */
diff --git a/book.c b/book.c
index ba7a9af..b574073 100644 (file)
--- a/book.c
+++ b/book.c
@@ -65,8 +65,6 @@ entry_t entry_none = {
 };
 
 char *promote_pieces=" nbrqac=";
-extern char castlingRights[][BOARD_SIZE];
-extern char epStatus[];
 
 uint64 Random64[781] = {
    U64(0x9D39247E33776D41), U64(0x2AF7398005AAA5C7), U64(0x44DB015024623547), U64(0x9C15F73E62A76AE2),
@@ -312,16 +310,16 @@ uint64 hash(int moveNr)
     }
     // Holdings not implemented yet!
 
-    if(castlingRights[moveNr][2] >= 0) {
-       if(castlingRights[moveNr][0] >= 0) key^=RandomCastle[0];
-       if(castlingRights[moveNr][1] >= 0) key^=RandomCastle[1];
+    if(boards[moveNr][CASTLING][2] != NoRights) {
+       if(boards[moveNr][CASTLING][0] != NoRights) key^=RandomCastle[0];
+       if(boards[moveNr][CASTLING][1] != NoRights) key^=RandomCastle[1];
     }
-    if(castlingRights[moveNr][5] >= 0) {
-       if(castlingRights[moveNr][3] >= 0) key^=RandomCastle[2];
-       if(castlingRights[moveNr][4] >= 0) key^=RandomCastle[3];
+    if(boards[moveNr][CASTLING][5] != NoRights) {
+       if(boards[moveNr][CASTLING][3] != NoRights) key^=RandomCastle[2];
+       if(boards[moveNr][CASTLING][4] != NoRights) key^=RandomCastle[3];
     }
 
-    f = epStatus[moveNr];
+    f = boards[moveNr][EP_STATUS];
     if(f >= 0 && f < 8){
         if(!WhiteOnMove(moveNr)){
            // the test for neighboring Pawns might not be needed, 
index 72e66ba..03f7bb0 100644 (file)
--- a/common.h
+++ b/common.h
@@ -125,13 +125,17 @@ int pclose(FILE *);
    outside world in ASCII. In a similar way, the different rank numbering
    systems (starting at rank 0 or 1) are implemented by redefining '1'.
 */
-#define BOARD_SIZE              16            /* [HGM] for in declarations */
-#define BOARD_HEIGHT (gameInfo.boardHeight)   // [HGM] made user adjustable 
+#define BOARD_RANKS             11             /* [HGM] for in declarations  */
+#define BOARD_FILES             16             /* [HGM] for in declarations  */
+#define BOARD_HEIGHT (gameInfo.boardHeight)    /* [HGM] made user adjustable */
 #define BOARD_WIDTH  (gameInfo.boardWidth + 2*gameInfo.holdingsWidth)   
-#define BOARD_LEFT   (gameInfo.holdingsWidth) // [HGM] play-board edges     
+#define BOARD_LEFT   (gameInfo.holdingsWidth)  /* [HGM] play-board edges     */
 #define BOARD_RGHT   (gameInfo.boardWidth + gameInfo.holdingsWidth)
-#define ONE          ('1'-(BOARD_HEIGHT>9))   // [HGM] foremost board rank  
-#define AAA          ('a'-BOARD_LEFT)         // [HGM] leftmost board file  
+#define CASTLING     (BOARD_RANKS-1)           /* [HGM] hide in upper rank   */
+#define EP_STATUS    CASTLING][(BOARD_FILES-2) /* [HGM] in upper rank        */
+#define HOLDINGS_SET CASTLING][(BOARD_FILES-1) /* [HGM] in upper-right corner*/
+#define ONE          ('1'-(BOARD_HEIGHT>9))    /* [HGM] foremost board rank  */
+#define AAA          ('a'-BOARD_LEFT)          /* [HGM] leftmost board file  */
 #define DROP_RANK               -3
 #define MAX_MOVES              1000
 #define MSG_SIZ                        512
@@ -164,10 +168,18 @@ int pclose(FILE *);
 #define JAIL_SQUARE_COLOR       "#808080"
 #define HIGHLIGHT_SQUARE_COLOR "#FFFF00"
 #define PREMOVE_HIGHLIGHT_COLOR        "#FF0000"
+#define LOWTIMEWARNING_COLOR    "#FF0000"
 #define BELLCHAR                '\007'
 #define NULLCHAR                '\000'
 #define FEATURE_TIMEOUT         10000 /*ms*/
 
+/* Default to no flashing (the "usual" XBoard behavior) */
+#define FLASH_COUNT    0               /* Number of times to flash */
+#define FLASH_RATE     5               /* Flashes per second */
+
+/* Default delay per character (in msec) while sending login script */
+#define MS_LOGIN_DELAY  0
+
 /* Zippy defaults */
 #define ZIPPY_TALK FALSE
 #define ZIPPY_PLAY FALSE
@@ -209,6 +221,7 @@ typedef enum {
     BlackCannon, BlackNightrider, BlackCardinal, BlackDragon, BlackGrasshopper,
     BlackSilver, BlackFalcon, BlackLance, BlackCobra, BlackUnicorn, BlackKing,
     EmptySquare, 
+    NoRights, // [HGM] gamestate: for castling rights hidden in board[CASTLING]
     ClearBoard, WhitePlay, BlackPlay, PromotePiece, DemotePiece /*for use on EditPosition menus*/
   } ChessSquare;
 
@@ -220,7 +233,7 @@ typedef enum {
 #define SHOGI          (int)EmptySquare + (int)
 
 
-typedef ChessSquare Board[BOARD_SIZE][BOARD_SIZE];
+typedef ChessSquare Board[BOARD_RANKS][BOARD_FILES];
 
 typedef enum {
     WhiteKingSideCastle = 1, WhiteQueenSideCastle,
@@ -438,7 +451,7 @@ typedef struct {
                          ICS logon script (xboard only) */
     Boolean colorize;  /* If True, use the following colors to color text */
     /* Strings for colors, as "fg, bg, bold" (strings used in xboard only) */
-    char *colorShout;
+    char *colorShout;    // [HGM] IMPORTANT: order must conform to ColorClass definition
     char *colorSShout;
     char *colorChannel1;
     char *colorChannel;
@@ -449,7 +462,7 @@ typedef struct {
     char *colorSeek;
     char *colorNormal;
     char *soundProgram; /* sound-playing program */
-    char *soundShout;
+    char *soundShout;     // [HGM] IMPORTANT: order must be as in ColorClass
     char *soundSShout;
     char *soundChannel1;
     char *soundChannel;
@@ -458,12 +471,13 @@ typedef struct {
     char *soundChallenge;
     char *soundRequest;
     char *soundSeek;
-    char *soundMove;
+    char *soundMove;     // [HGM] IMPORTANT: order must be as in SoundClass
+    char *soundBell;
+    char *soundIcsAlarm;
     char *soundIcsWin;
     char *soundIcsLoss;
     char *soundIcsDraw;
     char *soundIcsUnfinished;
-    char *soundIcsAlarm;
     Boolean reuseFirst;
     Boolean reuseSecond;
     Boolean animateDragging; /* If True, animate mouse dragging of pieces */
@@ -606,6 +620,7 @@ typedef struct {
     char *wrapContSeq; /* continuation sequence when xboard wraps text */
     Boolean useInternalWrap; /* use internal wrapping -- noJoin usurps this if set */
     Boolean pasteSelection; /* paste X selection instead of clipboard */
+    int nrVariations;   /* [HGM] multivar  */
 } AppData, *AppDataPtr;
 
 /* [AS] PGN tags (for showing in the game list) */
@@ -655,6 +670,14 @@ typedef struct {
     int holdingsWidth; /* number of files left and right of board, 0 or 2   */
 } GameInfo;
 
+/* [AS] Search stats from chessprogram, for the played move */
+// [HGM] moved here from backend.h because it occurs in declarations of front-end functions
+typedef struct {
+    int score;  /* Centipawns */
+    int depth;  /* Plies */
+    int time;   /* Milliseconds */
+} ChessProgramStats_Move;
+
 // [HGM] chat  
 #define MAX_CHAT 3
 extern int chatCount;
index 3fe3aa0..5d8e00e 100644 (file)
@@ -335,7 +335,7 @@ dnl| USE_PTYS=1
 
 dnl| add some libs for OS X
   *-apple-* )
-    X_LIBS="$X_LIBS -lX11 -lXt"    
+    X_LIBS="$X_LIBS -lXmu -lX11 -lXt "    
   ;;
 esac
 
diff --git a/engineoutput.c b/engineoutput.c
new file mode 100644 (file)
index 0000000..9c493ad
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * engineoutput.c - split-off backe-end from Engine output (PV) by HGM
+ *
+ * Author: Alessandro Scotti (Dec 2005)
+ *
+ * Copyright 2005 Alessandro Scotti
+ *
+ * ------------------------------------------------------------------------
+ *
+ * GNU XBoard is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU XBoard is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.  *
+ *
+ *------------------------------------------------------------------------
+ ** See the file ChangeLog for a revision history.  */
+
+#define SHOW_PONDERING
+
+#include "config.h"
+
+#include <stdio.h>
+#include <malloc.h>
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else /* not STDC_HEADERS */
+# if HAVE_STRING_H
+#  include <string.h>
+# else /* not HAVE_STRING_H */
+#  include <strings.h>
+# endif /* not HAVE_STRING_H */
+#endif /* not STDC_HEADERS */
+
+#include "common.h"
+#include "frontend.h"
+#include "backend.h"
+#include "engineoutput.h"
+
+typedef struct {
+    char * name;
+    int which;
+    int depth;
+    u64 nodes;
+    int score;
+    int time;
+    char * pv;
+    char * hint;
+    int an_move_index;
+    int an_move_count;
+} EngineOutputData;
+
+// called by other front-end
+void EngineOutputUpdate( FrontEndProgramStats * stats );
+void OutputKibitz(int window, char *text);
+
+// module back-end routines
+static void VerifyDisplayMode();
+static void UpdateControls( EngineOutputData * ed );
+
+static int  lastDepth[2] = { -1, -1 };
+static int  lastForwardMostMove[2] = { -1, -1 };
+static int  engineState[2] = { -1, -1 };
+
+#define MAX_VAR 400
+static int scores[MAX_VAR], textEnd[MAX_VAR], curDepth[2], nrVariations[2];
+
+// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments
+void SetEngineState( int which, int state, char * state_data )
+{
+    int x_which = 1 - which;
+
+    if( engineState[ which ] != state ) {
+        engineState[ which ] = state;
+
+        switch( state ) {
+        case STATE_THINKING:
+            SetIcon( which, nStateIcon, nThinking );
+            if( engineState[ x_which ] == STATE_THINKING ) {
+                SetEngineState( x_which, STATE_IDLE, "" );
+            }
+            break;
+        case STATE_PONDERING:
+            SetIcon( which, nStateIcon, nPondering );
+            break;
+        case STATE_ANALYZING:
+            SetIcon( which, nStateIcon, nAnalyzing );
+            break;
+        default:
+            SetIcon( which, nStateIcon, nClear );
+            break;
+        }
+    }
+
+    if( state_data != 0 ) {
+        DoSetWindowText( which, nStateData, state_data );
+    }
+}
+
+// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles.
+void SetProgramStats( FrontEndProgramStats * stats ) // now directly called by back-end
+{
+    EngineOutputData ed;
+    int clearMemo = FALSE;
+    int which;
+    int depth;
+
+    if( stats == 0 ) {
+        SetEngineState( 0, STATE_IDLE, "" );
+        SetEngineState( 1, STATE_IDLE, "" );
+        return;
+    }
+
+    if(gameMode == IcsObserving && !appData.icsEngineAnalyze)
+       return; // [HGM] kibitz: shut up engine if we are observing an ICS game
+
+    which = stats->which;
+    depth = stats->depth;
+
+    if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) {
+        return;
+    }
+
+    if( !EngineOutputDialogExists() ) {
+        return;
+    }
+
+    VerifyDisplayMode();
+
+    ed.which = which;
+    ed.depth = depth;
+    ed.nodes = stats->nodes;
+    ed.score = stats->score;
+    ed.time = stats->time;
+    ed.pv = stats->pv;
+    ed.hint = stats->hint;
+    ed.an_move_index = stats->an_move_index;
+    ed.an_move_count = stats->an_move_count;
+
+    /* Get target control. [HGM] this is moved to front end, which get them from a table */
+    if( which == 0 ) {
+        ed.name = first.tidy;
+    }
+    else {
+        ed.name = second.tidy;
+    }
+
+    /* Clear memo if needed */
+    if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1) ) {
+        clearMemo = TRUE;
+    }
+
+    if( lastForwardMostMove[which] != forwardMostMove ) {
+        clearMemo = TRUE;
+    }
+
+    if( clearMemo ) { DoClearMemo(which); nrVariations[which] = 0; }
+
+    /* Update */
+    lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge
+    lastForwardMostMove[which] = forwardMostMove;
+
+    if( ed.pv != 0 && ed.pv[0] == ' ' ) {
+        if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */
+            ed.pv = "";
+        }
+    }
+
+    UpdateControls( &ed );
+}
+
+#define ENGINE_COLOR_WHITE      'w'
+#define ENGINE_COLOR_BLACK      'b'
+#define ENGINE_COLOR_UNKNOWN    ' '
+
+// pure back end
+static char GetEngineColor( int which )
+{
+    char result = ENGINE_COLOR_UNKNOWN;
+
+    if( which == 0 || which == 1 ) {
+        ChessProgramState * cps;
+
+        switch (gameMode) {
+        case MachinePlaysBlack:
+        case IcsPlayingBlack:
+            result = ENGINE_COLOR_BLACK;
+            break;
+        case MachinePlaysWhite:
+        case IcsPlayingWhite:
+            result = ENGINE_COLOR_WHITE;
+            break;
+        case AnalyzeMode:
+        case AnalyzeFile:
+            result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;
+            break;
+        case TwoMachinesPlay:
+            cps = (which == 0) ? &first : &second;
+            result = cps->twoMachinesColor[0];
+            result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;
+            break;
+        default: ; // does not happen, but suppresses pedantic warnings
+        }
+    }
+
+    return result;
+}
+
+// pure back end
+static char GetActiveEngineColor()
+{
+    char result = ENGINE_COLOR_UNKNOWN;
+
+    if( gameMode == TwoMachinesPlay ) {
+        result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;
+    }
+
+    return result;
+}
+
+// pure back end
+static int IsEnginePondering( int which )
+{
+    int result = FALSE;
+
+    switch (gameMode) {
+    case MachinePlaysBlack:
+    case IcsPlayingBlack:
+        if( WhiteOnMove(forwardMostMove) ) result = TRUE;
+        break;
+    case MachinePlaysWhite:
+    case IcsPlayingWhite:
+        if( ! WhiteOnMove(forwardMostMove) ) result = TRUE;
+        break;
+    case TwoMachinesPlay:
+        if( GetActiveEngineColor() != ENGINE_COLOR_UNKNOWN ) {
+            if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE;
+        }
+        break;
+    default: ; // does not happen, but suppresses pedantic warnings
+    }
+
+    return result;
+}
+
+// back end
+static void SetDisplayMode( int mode )
+{
+    if( windowMode != mode ) {
+        windowMode = mode;
+
+        ResizeWindowControls( mode );
+    }
+}
+
+// pure back end
+static void VerifyDisplayMode()
+{
+    int mode;
+
+    /* Get proper mode for current game */
+    switch( gameMode ) {
+    case IcsObserving:    // [HGM] ICS analyze
+       if(!appData.icsEngineAnalyze) return;
+    case AnalyzeMode:
+    case AnalyzeFile:
+    case MachinePlaysWhite:
+    case MachinePlaysBlack:
+        mode = 0;
+        break;
+    case IcsPlayingWhite:
+    case IcsPlayingBlack:
+        mode = appData.zippyPlay && opponentKibitzes; // [HGM] kibitz
+        break;
+    case TwoMachinesPlay:
+        mode = 1;
+        break;
+    default:
+        /* Do not change */
+        return;
+    }
+
+    SetDisplayMode( mode );
+}
+
+// back end. Determine what icon to set in the color-icon field, and print it
+void SetEngineColorIcon( int which )
+{
+    char color = GetEngineColor(which);
+    int nicon = 0;
+
+    if( color == ENGINE_COLOR_BLACK )
+        nicon = nColorBlack;
+    else if( color == ENGINE_COLOR_WHITE )
+        nicon = nColorWhite;
+    else
+        nicon = nColorUnknown;
+
+    SetIcon( which, nColorIcon, nicon );
+}
+
+#define MAX_NAME_LENGTH 32
+
+// [HGM] multivar: sort Thinking Output within one depth on score
+
+static int InsertionPoint( int len, EngineOutputData * ed )
+{
+       int i, offs = 0, newScore = ed->score, n = ed->which;
+
+       if(ed->nodes == 0 && ed->score == 0 && ed->time == 0)
+               newScore = 1e6; // info lines inserted on top
+       if(ed->depth != curDepth[n]) { // depth has changed
+               curDepth[n] = ed->depth;
+               nrVariations[n] = 0; // throw away everything we had
+       }
+       // loop through all lines. Note even / odd used for different panes
+       for(i=nrVariations[n]-2; i>=0; i-=2) {
+               // put new item behind those we haven't looked at
+               offs = textEnd[i+n];
+               textEnd[i+n+2] = offs + len;
+               scores[i+n+2] = newScore;
+               if(newScore < scores[i+n]) break;
+               // if it had higher score as previous, move previous in stead
+               scores[i+n+2] = scores[i+n];
+               textEnd[i+n+2] = textEnd[i+n] + len;
+       }
+       if(i<0) {
+               offs = 0;
+               textEnd[n] = offs + len;
+               scores[n] = newScore;
+       }
+       nrVariations[n] += 2;
+      return offs;
+}
+
+
+// pure back end, now SetWindowText is called via wrapper DoSetWindowText
+static void UpdateControls( EngineOutputData * ed )
+{
+//    int isPondering = FALSE;
+
+    char s_label[MAX_NAME_LENGTH + 32];
+    
+    char * name = ed->name;
+
+    /* Label */
+    if( name == 0 || *name == '\0' ) {
+        name = "?";
+    }
+
+    strncpy( s_label, name, MAX_NAME_LENGTH );
+    s_label[ MAX_NAME_LENGTH-1 ] = '\0';
+
+#ifdef SHOW_PONDERING
+    if( IsEnginePondering( ed->which ) ) {
+        char buf[8];
+
+        buf[0] = '\0';
+
+        if( ed->hint != 0 && *ed->hint != '\0' ) {
+            strncpy( buf, ed->hint, sizeof(buf) );
+            buf[sizeof(buf)-1] = '\0';
+        }
+        else if( ed->pv != 0 && *ed->pv != '\0' ) {
+            char * sep = strchr( ed->pv, ' ' );
+            int buflen = sizeof(buf);
+
+            if( sep != NULL ) {
+                buflen = sep - ed->pv + 1;
+                if( buflen > sizeof(buf) ) buflen = sizeof(buf);
+            }
+
+            strncpy( buf, ed->pv, buflen );
+            buf[ buflen-1 ] = '\0';
+        }
+
+        SetEngineState( ed->which, STATE_PONDERING, buf );
+    }
+    else if( gameMode == TwoMachinesPlay ) {
+        SetEngineState( ed->which, STATE_THINKING, "" );
+    }
+    else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile
+         || (gameMode == IcsObserving && appData.icsEngineAnalyze)) { // [HGM] ICS-analyze
+        char buf[64];
+        int time_secs = ed->time / 100;
+        int time_mins = time_secs / 60;
+
+        buf[0] = '\0';
+
+        if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) {
+            char mov[16];
+
+            strncpy( mov, ed->hint, sizeof(mov) );
+            mov[ sizeof(mov)-1 ] = '\0';
+
+            sprintf( buf, "[%d] %d/%d: %s [%02d:%02d:%02d]", ed->depth, ed->an_move_index,
+                       ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 );
+        }
+
+        SetEngineState( ed->which, STATE_ANALYZING, buf );
+    }
+    else {
+        SetEngineState( ed->which, STATE_IDLE, "" );
+    }
+#endif
+
+    DoSetWindowText( ed->which, nLabel, s_label );
+
+    s_label[0] = '\0';
+
+    if( ed->time > 0 && ed->nodes > 0 ) {
+        unsigned long nps_100 = ed->nodes / ed->time;
+
+        if( nps_100 < 100000 ) {
+            sprintf( s_label, "NPS: %lu", nps_100 * 100 );
+        }
+        else {
+            sprintf( s_label, "NPS: %.1fk", nps_100 / 10.0 );
+        }
+    }
+
+    DoSetWindowText( ed->which, nLabelNPS, s_label );
+
+    /* Memo */
+    if( ed->pv != 0 && *ed->pv != '\0' ) {
+        char s_nodes[24];
+        char s_score[16];
+        char s_time[24];
+        char buf[256];
+        int buflen;
+        int time_secs = ed->time / 100;
+        int time_cent = ed->time % 100;
+
+        /* Nodes */
+        if( ed->nodes < 1000000 ) {
+            sprintf( s_nodes, u64Display, ed->nodes );
+        }
+        else {
+            sprintf( s_nodes, "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 );
+        }
+
+        /* Score */
+        if( ed->score > 0 ) {
+            sprintf( s_score, "+%.2f", ed->score / 100.0 );
+        }
+        else {
+            sprintf( s_score, "%.2f", ed->score / 100.0 );
+        }
+
+        /* Time */
+        sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent );
+
+        /* Put all together... */
+       if(ed->nodes == 0 && ed->score == 0 && ed->time == 0) sprintf( buf, "%3d\t", ed->depth ); else 
+       sprintf( buf, "%3d\t%s\t%s\t%s\t", ed->depth, s_score, s_nodes, s_time );
+
+        /* Add PV */
+        buflen = strlen(buf);
+
+        strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen );
+
+        buf[ sizeof(buf) - 3 ] = '\0';
+
+        strcat( buf + buflen, "\r\n" );
+
+        /* Update memo */
+        InsertIntoMemo( ed->which, buf, InsertionPoint(strlen(buf), ed) );
+    }
+
+    /* Colors */
+    SetEngineColorIcon( ed->which );
+}
+
+// [HGM] kibitz: write kibitz line; split window for it if necessary
+void OutputKibitz(int window, char *text)
+{
+       if(!EngineOutputIsUp()) return;
+       if(!opponentKibitzes) { // on first kibitz of game, clear memos
+           DoClearMemo(1);
+           if(gameMode == IcsObserving) DoClearMemo(0);
+       }
+       opponentKibitzes = TRUE; // this causes split window DisplayMode in ICS modes.
+       VerifyDisplayMode();
+       if(gameMode == IcsObserving) {
+           DoSetWindowText(0, nLabel, gameInfo.white);
+           SetIcon( 0, nColorIcon,  nColorWhite);
+           SetIcon( 0, nStateIcon,  nClear);
+       }
+       DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name
+       SetIcon( 1, nColorIcon,  gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);
+       SetIcon( 1, nStateIcon,  nClear);
+       InsertIntoMemo(window-1, text, 0); // [HGM] multivar: always at top
+}
diff --git a/engineoutput.h b/engineoutput.h
new file mode 100644 (file)
index 0000000..febbd34
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * wengineo.h -- Clipboard routines for WinBoard
+ *
+ * Copyright 2000,2009 Free Software Foundation, Inc.
+ *
+ * Enhancements Copyright 2005 Alessandro Scotti
+ *
+ * ------------------------------------------------------------------------
+ *
+ * GNU XBoard is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU XBoard is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.  *
+ *
+ *------------------------------------------------------------------------
+ ** See the file ChangeLog for a revision history.  */
+
+// [HGM] define numbers to indicate icons, for referring to them in platform-independent way
+#define nColorBlack   1
+#define nColorWhite   2
+#define nColorUnknown 3
+#define nClear        4
+#define nPondering    5
+#define nThinking     6
+#define nAnalyzing    7
+
+// [HGM] same for output fields (note that there are two of each type, one per color)
+#define nColorIcon 1
+#define nStateIcon 2
+#define nLabel     3
+#define nStateData 4
+#define nLabelNPS  5
+#define nMemo      6
+
+/* Module variables */
+#define H_MARGIN            2
+#define V_MARGIN            2
+#define LABEL_V_DISTANCE    1   /* Distance between label and memo */
+#define SPLITTER_SIZE       4   /* Distance between first memo and second label */
+
+#define ICON_SIZE           14
+
+#define STATE_UNKNOWN   -1
+#define STATE_THINKING   0
+#define STATE_IDLE       1
+#define STATE_PONDERING  2
+#define STATE_ANALYZING  3
+
+extern int  windowMode;
+
+// back-end called by front-end
+void SetEngineState( int which, int state, char * state_data );
+
+// front-end called by back-end
+void SetIcon( int which, int field, int nIcon );
+void DoSetWindowText(int which, int field, char *s_label);
+void InsertIntoMemo( int which, char * text, int where );
+void DoClearMemo(int which);
+void ResizeWindowControls( int mode );
+int EngineOutputDialogExists();
+
diff --git a/evalgraph.c b/evalgraph.c
new file mode 100644 (file)
index 0000000..9aa1fe7
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * evalgraph.c - Evaluation graph back-end part
+ *
+ * Author: Alessandro Scotti (Dec 2005)
+ *
+ * Copyright 2005 Alessandro Scotti
+ *
+ * ------------------------------------------------------------------------
+ *
+ * GNU XBoard is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU XBoard is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.  *
+ *
+ *------------------------------------------------------------------------
+ ** See the file ChangeLog for a revision history.  */
+
+// code refactored by HGM to obtain front-end / back-end separation
+
+#include "config.h"
+
+#include <stdio.h>
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else /* not STDC_HEADERS */
+# if HAVE_STRING_H
+#  include <string.h>
+# else /* not HAVE_STRING_H */
+#  include <strings.h>
+# endif /* not HAVE_STRING_H */
+#endif /* not STDC_HEADERS */
+
+#include "common.h"
+#include "frontend.h"
+#include "backend.h"
+#include "evalgraph.h"
+
+/* Module globals */
+ChessProgramStats_Move * currPvInfo;
+int currFirst = 0;
+int currLast = 0;
+int currCurrent = -1;
+
+int nWidthPB = 0;
+int nHeightPB = 0;
+
+int MarginX = 18;
+int MarginW = 4;
+int MarginH = 4;
+
+// back-end
+static void DrawLine( int x1, int y1, int x2, int y2, int penType )
+{
+    DrawSegment( x1, y1, NULL, NULL, PEN_NONE );
+    DrawSegment( x2, y2, NULL, NULL, penType );
+}
+
+// back-end
+static void DrawLineEx( int x1, int y1, int x2, int y2, int penType )
+{
+    int savX, savY;
+    DrawSegment( x1, y1, &savX, &savY, PEN_NONE );
+    DrawSegment( x2, y2, NULL, NULL, penType );
+    DrawSegment( savX, savY, NULL, NULL, PEN_NONE );
+}
+
+// back-end
+static int GetPvScore( int index )
+{
+    int score = currPvInfo[ index ].score;
+
+    if( index & 1 ) score = -score; /* Flip score for black */
+
+    return score;
+}
+
+// back-end
+/*
+    For a centipawn value, this function returns the height of the corresponding
+    histogram, centered on the reference axis.
+
+    Note: height can be negative!
+*/
+static int GetValueY( int value )
+{
+    if( value < -700 ) value = -700;
+    if( value > +700 ) value = +700;
+
+    return (nHeightPB / 2) - (int)(value * (nHeightPB - 2*MarginH) / 1400.0);
+}
+
+// the brush selection is made part of the DrawLine, by passing a style argument
+// the wrapper for doing the text output makes this back-end
+static void DrawAxisSegmentHoriz( int value, Boolean drawValue )
+{
+    int y = GetValueY( value*100 );
+
+    if( drawValue ) {
+        char buf[MSG_SIZ], *b = buf;
+
+        if( value > 0 ) *b++ = '+';
+       sprintf(b, "%d", value);
+
+       DrawEvalText(buf, strlen(buf), y);
+    }
+    // [HGM] counts on DrawEvalText to have select transparent background for dotted line!
+    DrawLine( MarginX, y, MarginX + MarginW, y, PEN_BLACK ); // Y-axis tick marks
+    DrawLine( MarginX + MarginW, y, nWidthPB - MarginW, y, PEN_DOTTED ); // hor grid
+}
+
+// The DrawLines again must select their own brush.
+// the initial brush selection is useless? BkMode needed for dotted line and text
+static void DrawAxis()
+{
+    int cy = nHeightPB / 2;
+    
+//    SelectObject( hdcPB, GetStockObject(NULL_BRUSH) );
+
+//    SetBkMode( hdcPB, TRANSPARENT );
+
+    DrawAxisSegmentHoriz( +5, TRUE );
+    DrawAxisSegmentHoriz( +3, FALSE );
+    DrawAxisSegmentHoriz( +1, FALSE );
+    DrawAxisSegmentHoriz(  0, TRUE );
+    DrawAxisSegmentHoriz( -1, FALSE );
+    DrawAxisSegmentHoriz( -3, FALSE );
+    DrawAxisSegmentHoriz( -5, TRUE );
+
+    DrawLine( MarginX + MarginW, cy, nWidthPB - MarginW, cy, PEN_BLACK ); // x-axis
+    DrawLine( MarginX + MarginW, MarginH, MarginX + MarginW, nHeightPB - MarginH, PEN_BLACK ); // y-axis
+}
+
+// back-end
+static void DrawHistogram( int x, int y, int width, int value, int side )
+{
+    int left, top, right, bottom;
+
+    if( value > -25 && value < +25 ) return;
+
+    left = x;
+    right = left + width + 1;
+
+    if( value > 0 ) {
+        top = GetValueY( value );
+        bottom = y+1;
+    }
+    else {
+        top = y;
+        bottom = GetValueY( value ) + 1;
+    }
+
+
+    if( width == MIN_HIST_WIDTH ) {
+        right--;
+        DrawRectangle( left, top, right, bottom, side, FILLED );
+    }
+    else {
+        DrawRectangle( left, top, right, bottom, side, OPEN );
+    }
+}
+
+// back-end
+static void DrawSeparator( int index, int x )
+{
+    if( index > 0 ) {
+        if( index == currCurrent ) {
+            DrawLineEx( x, MarginH, x, nHeightPB - MarginH, PEN_BLUEDOTTED );
+        }
+        else if( (index % 20) == 0 ) {
+            DrawLineEx( x, MarginH, x, nHeightPB - MarginH, PEN_DOTTED );
+        }
+    }
+}
+
+// made back-end by replacing MoveToEx and LineTo by DrawSegment
+/* Actually draw histogram as a diagram, cause there's too much data */
+static void DrawHistogramAsDiagram( int cy, int paint_width, int hist_count )
+{
+    double step;
+    int i;
+
+    /* Rescale the graph every few moves (as opposed to every move) */
+    hist_count -= hist_count % 8;
+    hist_count += 8;
+    hist_count /= 2;
+
+    step = (double) paint_width / (hist_count + 1);
+
+    for( i=0; i<2; i++ ) {
+        int index = currFirst;
+        int side = (currCurrent + i + 1) & 1; /* Draw current side last */
+        double x = MarginX + MarginW;
+
+        if( (index & 1) != side ) {
+            x += step / 2;
+            index++;
+        }
+
+        DrawSegment( (int) x, cy, NULL, NULL, PEN_NONE );
+
+        index += 2;
+
+        while( index < currLast ) {
+            x += step;
+
+            DrawSeparator( index, (int) x );
+
+            /* Extend line up to current point */
+            if( currPvInfo[index].depth > 0 ) {
+                DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, PEN_BOLD + side );
+            }
+
+            index += 2;
+        }
+    }
+}
+
+// back-end, delete pen selection
+static void DrawHistogramFull( int cy, int hist_width, int hist_count )
+{
+    int i;
+
+//    SelectObject( hdcPB, GetStockObject(BLACK_PEN) );
+
+    for( i=0; i<hist_count; i++ ) {
+        int index = currFirst + i;
+        int x = MarginX + MarginW + index * hist_width;
+
+        /* Draw a separator every 10 moves */
+        DrawSeparator( index, x );
+
+        /* Draw histogram */
+        if( currPvInfo[i].depth > 0 ) {
+            DrawHistogram( x, cy, hist_width, GetPvScore(index), index & 1 );
+        }
+    }
+}
+
+typedef struct {
+    int cy;
+    int hist_width;
+    int hist_count;
+    int paint_width;
+} VisualizationData;
+
+// back-end
+static Boolean InitVisualization( VisualizationData * vd )
+{
+    Boolean result = FALSE;
+
+    vd->cy = nHeightPB / 2;
+    vd->hist_width = MIN_HIST_WIDTH;
+    vd->hist_count = currLast - currFirst;
+    vd->paint_width = nWidthPB - MarginX - 2*MarginW;
+
+    if( vd->hist_count > 0 ) {
+        result = TRUE;
+
+        /* Compute width */
+        vd->hist_width = vd->paint_width / vd->hist_count;
+
+        if( vd->hist_width > MAX_HIST_WIDTH ) vd->hist_width = MAX_HIST_WIDTH;
+
+        vd->hist_width -= vd->hist_width % 2;
+    }
+
+    return result;
+}
+
+// back-end
+static void DrawHistograms()
+{
+    VisualizationData vd;
+
+    if( InitVisualization( &vd ) ) {
+        if( vd.hist_width < MIN_HIST_WIDTH ) {
+            DrawHistogramAsDiagram( vd.cy, vd.paint_width, vd.hist_count );
+        }
+        else {
+            DrawHistogramFull( vd.cy, vd.hist_width, vd.hist_count );
+        }
+    }
+}
+
+// back-end
+int GetMoveIndexFromPoint( int x, int y )
+{
+    int result = -1;
+    int start_x = MarginX + MarginW;
+    VisualizationData vd;
+
+    if( x >= start_x && InitVisualization( &vd ) ) {
+        /* Almost an hack here... we duplicate some of the paint logic */
+        if( vd.hist_width < MIN_HIST_WIDTH ) {
+            double step;
+
+            vd.hist_count -= vd.hist_count % 8;
+            vd.hist_count += 8;
+            vd.hist_count /= 2;
+
+            step = (double) vd.paint_width / (vd.hist_count + 1);
+            step /= 2;
+
+            result = (int) (0.5 + (double) (x - start_x) / step);
+        }
+        else {
+            result = (x - start_x) / vd.hist_width;
+        }
+    }
+
+    if( result >= currLast ) {
+        result = -1;
+    }
+
+    return result;
+}
+
+// init and display part split of so they can be moved to front end
+void PaintEvalGraph( void )
+{
+    /* Draw */
+    DrawRectangle(0, 0, nWidthPB, nHeightPB, 2, FILLED);
+    DrawAxis();
+    DrawHistograms();
+}
+
diff --git a/evalgraph.h b/evalgraph.h
new file mode 100644 (file)
index 0000000..e305abd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * evalgraph.h -- Evaluation Graph window
+ *
+ * Copyright 2000,2009 Free Software Foundation, Inc.
+ *
+ * Enhancements Copyright 2005 Alessandro Scotti
+ *
+ * ------------------------------------------------------------------------
+ *
+ * GNU XBoard is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU XBoard is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.  *
+ *
+ *------------------------------------------------------------------------
+ ** See the file ChangeLog for a revision history.  
+ */
+
+#define MIN_HIST_WIDTH  4
+#define MAX_HIST_WIDTH  10
+
+#define PEN_NONE       0
+#define PEN_BLACK      1
+#define PEN_DOTTED     2
+#define PEN_BLUEDOTTED 3
+#define PEN_BOLD       4 /* or 5 for black */
+
+#define FILLED 1
+#define OPEN   0
+
+/* Module globals */
+ChessProgramStats_Move * currPvInfo;
+extern int currFirst;
+extern int currLast;
+extern int currCurrent;
+
+extern int nWidthPB;
+extern int nHeightPB;
+
+extern int MarginX;
+extern int MarginW;
+extern int MarginH;
+
+// calls from back-end part into front-end part
+void DrawSegment( int x, int y, int *lastX, int *lastY, int penType );
+void DrawRectangle( int left, int top, int right, int bottom, int side, int style );
+void DrawEvalText(char *buf, int cbBuf, int y);
+
+// calls of front-end part into back-end part
+extern int GetMoveIndexFromPoint( int x, int y );
+extern void PaintEvalGraph( void );
+
index 622eeec..9b43b46 100644 (file)
@@ -186,6 +186,8 @@ void ThawUI P((void));
 extern char *programName;
 extern int commentUp;
 
+void GreyRevert P((Boolean grey));
+
 typedef struct FrontEndProgramStats_TAG {
     int which;
     int depth;
@@ -200,4 +202,9 @@ typedef struct FrontEndProgramStats_TAG {
 
 void SetProgramStats P(( FrontEndProgramStats * stats )); /* [AS] */
 
+void EngineOutputPopUp P((void));
+void EngineOutputPopDown P((void));
+int  EngineOutputIsUp P((void));
+int  EngineOutputDialogExists P((void));
+
 #endif
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/moves.c b/moves.c
index 2a017c3..12f9b63 100644 (file)
--- a/moves.c
+++ b/moves.c
@@ -69,7 +69,7 @@ int BlackPiece P((ChessSquare));
 int SameColor P((ChessSquare, ChessSquare));
 int PosFlags(int index);
 
-extern signed char initialRights[BOARD_SIZE]; /* [HGM] all rights enabled, set in InitPosition */
+extern signed char initialRights[BOARD_FILES]; /* [HGM] all rights enabled, set in InitPosition */
 
 
 int WhitePiece(piece)
@@ -227,6 +227,9 @@ void CopyBoard(to, from)
     for (i = 0; i < BOARD_HEIGHT; i++)
       for (j = 0; j < BOARD_WIDTH; j++)
        to[i][j] = from[i][j];
+    for (j = 0; j < BOARD_FILES-1; j++) // [HGM] gamestate: copy castling rights and ep status
+       to[CASTLING][j] = from[CASTLING][j];
+    to[HOLDINGS_SET] = 0; // flag used in ICS play
 }
 
 int CompareBoards(board1, board2)
@@ -251,15 +254,15 @@ int CompareBoards(board1, board2)
    EP_UNKNOWN if we don't know and want to allow all e.p. captures.
    Promotion moves generated are to Queen only.
 */
-void GenPseudoLegal(board, flags, epfile, callback, closure)
+void GenPseudoLegal(board, flags, callback, closure)
      Board board;
      int flags;
-     int epfile;
      MoveCallback callback;
      VOIDSTAR closure;
 {
     int rf, ff;
     int i, j, d, s, fs, rs, rt, ft, m;
+    int epfile = (signed char)board[EP_STATUS]; // [HGM] gamestate: extract ep status from board
 
     for (rf = 0; rf < BOARD_HEIGHT; rf++) 
       for (ff = BOARD_LEFT; ff < BOARD_RGHT; ff++) {
@@ -748,22 +751,20 @@ typedef struct {
    true if castling is not yet ruled out by a move of the king or
    rook.  Return TRUE if the player on move is currently in check and
    F_IGNORE_CHECK is not set.  [HGM] add castlingRights parameter */
-int GenLegal(board, flags, epfile, castlingRights, callback, closure)
+int GenLegal(board, flags, callback, closure)
      Board board;
      int flags;
-     int epfile;
-     char castlingRights[];
      MoveCallback callback;
      VOIDSTAR closure;
 {
     GenLegalClosure cl;
     int ff, ft, k, left, right;
     int ignoreCheck = (flags & F_IGNORE_CHECK) != 0;
-    ChessSquare wKing = WhiteKing, bKing = BlackKing;
+    ChessSquare wKing = WhiteKing, bKing = BlackKing, *castlingRights = board[CASTLING];
 
     cl.cb = callback;
     cl.cl = closure;
-    GenPseudoLegal(board, flags, epfile, GenLegalCallback, (VOIDSTAR) &cl);
+    GenPseudoLegal(board, flags, GenLegalCallback, (VOIDSTAR) &cl);
 
     if (!ignoreCheck &&
        CheckTest(board, flags, -1, -1, -1, -1, FALSE)) return TRUE;
@@ -782,7 +783,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             board[0][BOARD_RGHT-3] == EmptySquare &&
             board[0][BOARD_RGHT-2] == EmptySquare &&
             board[0][BOARD_RGHT-1] == WhiteRook &&
-            castlingRights[0] >= 0 && /* [HGM] check rights */
+            castlingRights[0] != NoRights && /* [HGM] check rights */
             ( castlingRights[2] == ff || castlingRights[6] == ff ) &&
             (ignoreCheck ||                             
             (!CheckTest(board, flags, 0, ff, 0, ff + 1, FALSE) &&
@@ -802,7 +803,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             board[0][BOARD_LEFT+2] == EmptySquare &&
             board[0][BOARD_LEFT+1] == EmptySquare &&
             board[0][BOARD_LEFT+0] == WhiteRook &&
-            castlingRights[1] >= 0 && /* [HGM] check rights */
+            castlingRights[1] != NoRights && /* [HGM] check rights */
             ( castlingRights[2] == ff || castlingRights[6] == ff ) &&
            (ignoreCheck ||
             (!CheckTest(board, flags, 0, ff, 0, ff - 1, FALSE) &&
@@ -821,7 +822,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             board[BOARD_HEIGHT-1][BOARD_RGHT-3] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_RGHT-2] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook &&
-            castlingRights[3] >= 0 && /* [HGM] check rights */
+            castlingRights[3] != NoRights && /* [HGM] check rights */
             ( castlingRights[5] == ff || castlingRights[7] == ff ) &&
            (ignoreCheck ||
             (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 1, FALSE) &&
@@ -841,7 +842,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             board[BOARD_HEIGHT-1][BOARD_LEFT+2] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_LEFT+1] == EmptySquare &&
             board[BOARD_HEIGHT-1][BOARD_LEFT+0] == BlackRook &&
-            castlingRights[4] >= 0 && /* [HGM] check rights */
+            castlingRights[4] != NoRights && /* [HGM] check rights */
             ( castlingRights[5] == ff || castlingRights[7] == ff ) &&
            (ignoreCheck ||
             (!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 1, FALSE) &&
@@ -862,7 +863,7 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
 
     if ((flags & F_WHITE_ON_MOVE) != 0) {
         ff = castlingRights[2]; /* King file if we have any rights */
-        if(ff > 0 && board[0][ff] == WhiteKing) {
+        if(ff != NoRights && board[0][ff] == WhiteKing) {
     if (appData.debugMode) {
         fprintf(debugFP, "FRC castling, %d %d %d %d %d %d\n",
                 castlingRights[0],castlingRights[1],ff,castlingRights[3],castlingRights[4],castlingRights[5]);
@@ -871,49 +872,49 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure)
             left  = ff+1;
             right = BOARD_RGHT-2;
             if(ff == BOARD_RGHT-2) left = right = ff-1;    /* special case */
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[0][k] != EmptySquare) ft = -1;
-            for(k=left; k<right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[0][ft] == WhiteRook)
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[0][k] != EmptySquare) ft = NoRights;
+            for(k=left; k<right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[0][ft] == WhiteRook)
                 callback(board, flags, WhiteHSideCastleFR, 0, ff, 0, ft, closure);
 
             ft = castlingRights[1]; /* Rook file if we have A-side rights */
             left  = BOARD_LEFT+2;
             right = ff-1;
             if(ff <= BOARD_LEFT+2) { left = ff+1; right = BOARD_LEFT+3; }
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[0][k] != EmptySquare) ft = -1;
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[0][k] != EmptySquare) ft = NoRights;
             if(ff > BOARD_LEFT+2) 
-            for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[0][ft] == WhiteRook)
+            for(k=left+1; k<=right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[0][ft] == WhiteRook)
                 callback(board, flags, WhiteASideCastleFR, 0, ff, 0, ft, closure);
         }
     } else {
         ff = castlingRights[5]; /* King file if we have any rights */
-        if(ff > 0 && board[BOARD_HEIGHT-1][ff] == BlackKing) {
+        if(ff != NoRights && board[BOARD_HEIGHT-1][ff] == BlackKing) {
             ft = castlingRights[3]; /* Rook file if we have H-side rights */
             left  = ff+1;
             right = BOARD_RGHT-2;
             if(ff == BOARD_RGHT-2) left = right = ff-1;    /* special case */
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1;
-            for(k=left; k<right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = NoRights;
+            for(k=left; k<right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[BOARD_HEIGHT-1][ft] == BlackRook)
                 callback(board, flags, BlackHSideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);
 
             ft = castlingRights[4]; /* Rook file if we have A-side rights */
             left  = BOARD_LEFT+2;
             right = ff-1;
             if(ff <= BOARD_LEFT+2) { left = ff+1; right = BOARD_LEFT+3; }
-            for(k=left; k<=right && ft >= 0; k++) /* first test if blocked */
-                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1;
+            for(k=left; k<=right && ft != NoRights; k++) /* first test if blocked */
+                if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = NoRights;
             if(ff > BOARD_LEFT+2) 
-            for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */
-                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;
-            if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)
+            for(k=left+1; k<=right && ft != NoRights; k++) /* then if not checked */
+                if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = NoRights;
+            if(ft != NoRights && board[BOARD_HEIGHT-1][ft] == BlackRook)
                 callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);
         }
     }
@@ -999,8 +1000,7 @@ int CheckTest(board, flags, rf, ff, rt, ft, enPassant)
                           cl.check++;
               }
 
-             GenPseudoLegal(board, flags ^ F_WHITE_ON_MOVE, -1,
-                            CheckTestCallback, (VOIDSTAR) &cl);
+             GenPseudoLegal(board, flags ^ F_WHITE_ON_MOVE, CheckTestCallback, (VOIDSTAR) &cl);
              goto undo_move;  /* 2-level break */
          }
       }
@@ -1043,13 +1043,12 @@ void LegalityTestCallback(board, flags, kind, rf, ff, rt, ft, closure)
       cl->kind = kind;
 }
 
-ChessMove LegalityTest(board, flags, epfile, castlingRights, rf, ff, rt, ft, promoChar)
+ChessMove LegalityTest(board, flags, rf, ff, rt, ft, promoChar)
      Board board;
-     int flags, epfile;
+     int flags;
      int rf, ff, rt, ft, promoChar;
-     char castlingRights[];
 {
-    LegalityTestClosure cl; ChessSquare piece = board[rf][ff];
+    LegalityTestClosure cl; ChessSquare piece = board[rf][ff], *castlingRights = board[CASTLING];
     
     if (appData.debugMode) {
         int i;
@@ -1069,7 +1068,7 @@ ChessMove LegalityTest(board, flags, epfile, castlingRights, rf, ff, rt, ft, pro
     cl.ft = ft;
     cl.kind = IllegalMove;
     cl.captures = 0; // [HGM] losers: prepare to count legal captures.
-    GenLegal(board, flags, epfile, castlingRights, LegalityTestCallback, (VOIDSTAR) &cl);
+    GenLegal(board, flags, LegalityTestCallback, (VOIDSTAR) &cl);
     if((flags & F_MANDATORY_CAPTURE) && cl.captures && board[rt][ft] == EmptySquare
                && cl.kind != WhiteCapturesEnPassant && cl.kind != BlackCapturesEnPassant)
        return(IllegalMove); // [HGM] losers: if there are legal captures, non-capts are illegal
@@ -1142,10 +1141,9 @@ void MateTestCallback(board, flags, kind, rf, ff, rt, ft, closure)
 }
 
 /* Return MT_NONE, MT_CHECK, MT_CHECKMATE, or MT_STALEMATE */
-int MateTest(board, flags, epfile, castlingRights)
+int MateTest(board, flags)
      Board board;
-     int flags, epfile;
-     char castlingRights[];
+     int flags;
 {
     MateTestClosure cl;
     int inCheck, r, f, myPieces=0, hisPieces=0, nrKing=0;
@@ -1173,7 +1171,7 @@ int MateTest(board, flags, epfile, castlingRights)
                if(myPieces == 1) return MT_BARE;
     }
     cl.count = 0;
-    inCheck = GenLegal(board, flags, epfile, castlingRights, MateTestCallback, (VOIDSTAR) &cl);
+    inCheck = GenLegal(board, flags, MateTestCallback, (VOIDSTAR) &cl);
     // [HGM] 3check: yet to do!
     if (cl.count > 0) {
        return inCheck ? MT_CHECK : MT_NONE;
@@ -1230,9 +1228,9 @@ void DisambiguateCallback(board, flags, kind, rf, ff, rt, ft, closure)
     }
 }
 
-void Disambiguate(board, flags, epfile, closure)
+void Disambiguate(board, flags, closure)
      Board board;
-     int flags, epfile;
+     int flags;
      DisambiguateClosure *closure;
 {
     int illegal = 0; char c = closure->promoCharIn;
@@ -1245,12 +1243,11 @@ void Disambiguate(board, flags, epfile, closure)
                              closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,
                              closure->promoCharIn, closure->promoCharIn >= ' ' ? closure->promoCharIn : '-');
     }
-    GenLegal(board, flags, epfile, initialRights, DisambiguateCallback, (VOIDSTAR) closure);
+    GenLegal(board, flags, DisambiguateCallback, (VOIDSTAR) closure);
     if (closure->count == 0) {
        /* See if it's an illegal move due to check */
         illegal = 1;
-        GenLegal(board, flags|F_IGNORE_CHECK, epfile, initialRights, DisambiguateCallback,
-                (VOIDSTAR) closure);   
+        GenLegal(board, flags|F_IGNORE_CHECK, DisambiguateCallback, (VOIDSTAR) closure);       
        if (closure->count == 0) {
            /* No, it's not even that */
     if (appData.debugMode) { int i, j;
@@ -1380,10 +1377,9 @@ void CoordsToAlgebraicCallback(board, flags, kind, rf, ff, rt, ft, closure)
 /* Convert coordinates to normal algebraic notation.
    promoChar must be NULLCHAR or 'x' if not a promotion.
 */
-ChessMove CoordsToAlgebraic(board, flags, epfile,
-                           rf, ff, rt, ft, promoChar, out)
+ChessMove CoordsToAlgebraic(board, flags, rf, ff, rt, ft, promoChar, out)
      Board board;
-     int flags, epfile;
+     int flags;
      int rf, ff, rt, ft;
      int promoChar;
      char out[MOVE_LEN];
@@ -1414,12 +1410,11 @@ ChessMove CoordsToAlgebraic(board, flags, epfile,
     switch (piece) {
       case WhitePawn:
       case BlackPawn:
-        kind = LegalityTest(board, flags, epfile, initialRights, rf, ff, rt, ft, promoChar);
+        kind = LegalityTest(board, flags, rf, ff, rt, ft, promoChar);
        if (kind == IllegalMove && !(flags&F_IGNORE_CHECK)) {
            /* Keep short notation if move is illegal only because it
                leaves the player in check, but still return IllegalMove */
-            kind = LegalityTest(board, flags|F_IGNORE_CHECK, epfile, initialRights,
-                              rf, ff, rt, ft, promoChar);
+            kind = LegalityTest(board, flags|F_IGNORE_CHECK, rf, ff, rt, ft, promoChar);
            if (kind == IllegalMove) break;
            kind = IllegalMove;
        }
@@ -1463,8 +1458,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile,
        if((piece == WhiteKing && board[rt][ft] == WhiteRook) ||
           (piece == BlackKing && board[rt][ft] == BlackRook)) {
          if(ft > ff) strcpy(out, "O-O"); else strcpy(out, "O-O-O");
-            return LegalityTest(board, flags, epfile, initialRights,
-                               rf, ff, rt, ft, promoChar);
+            return LegalityTest(board, flags, rf, ff, rt, ft, promoChar);
        }
        /* End of code added by Tord */
        /* Test for castling or ICS wild castling */
@@ -1486,8 +1480,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile,
               this situation.  So I am not going to worry about it;
               I'll just generate an ambiguous O-O in this case.
            */
-            return LegalityTest(board, flags, epfile, initialRights,
-                               rf, ff, rt, ft, promoChar);
+            return LegalityTest(board, flags, rf, ff, rt, ft, promoChar);
        }
 
        /* else fall through */
@@ -1500,15 +1493,13 @@ ChessMove CoordsToAlgebraic(board, flags, epfile,
        cl.piece = piece;
        cl.kind = IllegalMove;
        cl.rank = cl.file = cl.either = 0;
-        GenLegal(board, flags, epfile, initialRights,
-                CoordsToAlgebraicCallback, (VOIDSTAR) &cl);
+        GenLegal(board, flags, CoordsToAlgebraicCallback, (VOIDSTAR) &cl);
 
        if (cl.kind == IllegalMove && !(flags&F_IGNORE_CHECK)) {
            /* Generate pretty moves for moving into check, but
               still return IllegalMove.
            */
-            GenLegal(board, flags|F_IGNORE_CHECK, epfile, initialRights,
-                    CoordsToAlgebraicCallback, (VOIDSTAR) &cl);
+            GenLegal(board, flags|F_IGNORE_CHECK, CoordsToAlgebraicCallback, (VOIDSTAR) &cl);
            if (cl.kind == IllegalMove) break;
            cl.kind = IllegalMove;
        }
@@ -1735,7 +1726,7 @@ int PerpetualChase(int first, int last)
         if(appData.debugMode) fprintf(debugFP, "judge position %i\n", i);
        chaseStackPointer = 0;   // clear stack that is going to hold possible chases
        // determine all captures possible after the move, and put them on chaseStack
-       GenLegal(boards[i+1], PosFlags(i), EP_NONE, initialRights, AttacksCallback, &cl);
+       GenLegal(boards[i+1], PosFlags(i), AttacksCallback, &cl);
        if(appData.debugMode) { int n; 
            for(n=0; n<chaseStackPointer; n++) 
                 fprintf(debugFP, "%c%c%c%c ", chaseStack[n].ff+AAA, chaseStack[n].rf+ONE, 
@@ -1747,7 +1738,7 @@ int PerpetualChase(int first, int last)
        cl.ff = moveList[i][0]-AAA+BOARD_LEFT;
        cl.rt = moveList[i][3]-ONE;
        cl.ft = moveList[i][2]-AAA+BOARD_LEFT;
-       GenLegal(boards[i],   PosFlags(i), EP_NONE, initialRights, ExistingAttacksCallback, &cl);
+       GenLegal(boards[i],   PosFlags(i), ExistingAttacksCallback, &cl);
        if(appData.debugMode) { int n; 
            for(n=0; n<chaseStackPointer; n++) 
                 fprintf(debugFP, "%c%c%c%c ", chaseStack[n].ff+AAA, chaseStack[n].rf+ONE, 
@@ -1766,7 +1757,7 @@ int PerpetualChase(int first, int last)
                continue; // C or H attack on R is always chase; leave on chaseStack
 
            if(attacker == victim) {
-                if(LegalityTest(boards[i+1], PosFlags(i+1), EP_NONE, initialRights, chaseStack[j].rt, 
+                if(LegalityTest(boards[i+1], PosFlags(i+1), chaseStack[j].rt, 
                    chaseStack[j].ft, chaseStack[j].rf, chaseStack[j].ff, NULLCHAR) == NormalMove) {
                        // we can capture back with equal piece, so this is no chase but a sacrifice
                         chaseStack[j] = chaseStack[--chaseStackPointer]; // delete the capture from the chaseStack
@@ -1787,7 +1778,7 @@ int PerpetualChase(int first, int last)
            if(appData.debugMode) {
                fprintf(debugFP, "test if we can recapture %c%c\n", cl.ft+AAA, cl.rt+ONE);
            }
-            GenLegal(boards[i+1], PosFlags(i+1), EP_NONE, initialRights, ProtectedCallback, &cl); // try all moves
+            GenLegal(boards[i+1], PosFlags(i+1), ProtectedCallback, &cl); // try all moves
            // unmake the capture
            boards[i+1][chaseStack[j].rf][chaseStack[j].ff] = boards[i+1][chaseStack[j].rt][chaseStack[j].ft];
             boards[i+1][chaseStack[j].rt][chaseStack[j].ft] = captured;
diff --git a/moves.h b/moves.h
index b2fcec6..032e988 100644 (file)
--- a/moves.h
+++ b/moves.h
@@ -103,7 +103,7 @@ typedef void (*MoveCallback) P((Board board, int flags, ChessMove kind,
    EP_UNKNOWN if we don't know and want to allow all e.p. captures.
    Promotion moves generated are to Queen only.
 */
-extern void GenPseudoLegal P((Board board, int flags, int epfile,
+extern void GenPseudoLegal P((Board board, int flags,
                              MoveCallback callback, VOIDSTAR closure));
 
 /* Like GenPseudoLegal, but include castling moves and (unless 
@@ -112,8 +112,7 @@ extern void GenPseudoLegal P((Board board, int flags, int epfile,
    ruled out by a move of the king or rook.  Return TRUE if the player
    on move is currently in check and F_IGNORE_CHECK is not set.
 */
-extern int GenLegal P((Board board, int flags, int epfile,
-                        char castlingRights[], /* [HGM] */
+extern int GenLegal P((Board board, int flags,
                        MoveCallback callback, VOIDSTAR closure));
 
 /* If the player on move were to move from (rf, ff) to (rt, ft), would
@@ -129,8 +128,7 @@ extern int CheckTest P((Board board, int flags,
 /* Is a move from (rf, ff) to (rt, ft) legal for the player whom the
    flags say is on move?  Other arguments as in GenPseudoLegal.
    Returns the type of move made, taking promoChar into account. */
-extern ChessMove LegalityTest P((Board board, int flags, int epfile,
-                                 char castlingRights[], /* [HGM] */
+extern ChessMove LegalityTest P((Board board, int flags,
                                 int rf, int ff, int rt, int ft,
                                 int promoChar));
 
@@ -146,8 +144,7 @@ extern ChessMove LegalityTest P((Board board, int flags, int epfile,
 #define MT_NOKING    9 /* [HGM] atomic: for games lost through king capture              */
 
 /* Return MT_NONE, MT_CHECK, MT_CHECKMATE, or MT_STALEMATE */
-extern int MateTest P((Board board, int flags, int epfile,
-                                        char castlingRights[])); /* [HGM] */
+extern int MateTest P((Board board, int flags));
 
 typedef struct {
     /* Input data */
@@ -163,13 +160,12 @@ typedef struct {
 } DisambiguateClosure;
 
 /* Disambiguate a partially-known move */
-void Disambiguate P((Board board, int flags, int epfile,
-                    DisambiguateClosure *closure));
+void Disambiguate P((Board board, int flags, DisambiguateClosure *closure));
 
 
 /* Convert coordinates to normal algebraic notation.
    promoChar must be NULLCHAR or '.' if not a promotion.
 */
-ChessMove CoordsToAlgebraic P((Board board, int flags, int epfile,
+ChessMove CoordsToAlgebraic P((Board board, int flags,
                               int rf, int ff, int rt, int ft,
                               int promoChar, char out[MOVE_LEN]));
index 78e8de6..9e726de 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -62,5 +62,4 @@ extern int yyskipmoves;  /* If TRUE, all moves are reported as AmbiguousMove
 extern char *yy_text;  /* Needed because yytext can be either a char[]
                          or a (non-constant) char* */
 extern int yyoffset P((void));
-extern signed char initialRights[BOARD_SIZE];
-extern signed char castlingRights[MAX_MOVES][BOARD_SIZE];
+extern signed char initialRights[BOARD_FILES];
old mode 100755 (executable)
new mode 100644 (file)
index d96b95a..7dda43f
--- a/parser.l
+++ b/parser.l
@@ -244,8 +244,6 @@ extern void CopyBoard P((Board to, Board from));
 \r
     result = LegalityTest(boards[yyboardindex],\r
                          PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.!\r
-                         EP_UNKNOWN,\r
-                          initialRights, /* [HGM] assume all castlings allowed */\r
                           currentMoveString[1] - ONE,\r
                           currentMoveString[0] - AAA,\r
                           currentMoveString[3] - ONE,\r
@@ -306,8 +304,6 @@ extern void CopyBoard P((Board to, Board from));
 \r
     result = LegalityTest(boards[yyboardindex],\r
                          PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.!\r
-                         EP_UNKNOWN,\r
-                          initialRights, /* [HGM] assume all castlings allowed */\r
                           currentMoveString[1] - ONE,\r
                           currentMoveString[0] - AAA,\r
                           currentMoveString[3] - ONE,\r
@@ -360,8 +356,7 @@ extern void CopyBoard P((Board to, Board from));
       return IllegalMove;\r
 \r
 \r
-    Disambiguate(boards[yyboardindex],\r
-                PosFlags(yyboardindex), EP_UNKNOWN, &cl);\r
+    Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl);\r
 \r
     currentMoveString[0] = cl.ff + AAA;\r
     currentMoveString[1] = cl.rf + ONE;\r
@@ -415,8 +410,7 @@ extern void CopyBoard P((Board to, Board from));
     if(c != '=' && c != '+' && c != NULLCHAR && CharToPiece(c) == EmptySquare)\r
       return IllegalMove;\r
 \r
-    Disambiguate(boards[yyboardindex],\r
-                PosFlags(yyboardindex), EP_UNKNOWN, &cl);\r
+    Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl);\r
 \r
     currentMoveString[0] = cl.ff + AAA;\r
     currentMoveString[1] = cl.rf + ONE;\r
@@ -492,8 +486,6 @@ extern void CopyBoard P((Board to, Board from));
 \r
     result = LegalityTest(boards[yyboardindex],\r
                          PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.!\r
-                         EP_UNKNOWN,\r
-                          initialRights, /* [HGM] assume all castlings allowed */\r
                           currentMoveString[1] - ONE,\r
                           currentMoveString[0] - AAA,\r
                           currentMoveString[3] - ONE,\r
@@ -533,8 +525,6 @@ extern void CopyBoard P((Board to, Board from));
 \r
     result = LegalityTest(boards[yyboardindex],\r
                          PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: might think we can e.p.!\r
-                         EP_UNKNOWN,\r
-                          initialRights, /* [HGM] assume all castlings allowed */\r
                           currentMoveString[1] - ONE,\r
                           currentMoveString[0] - AAA,\r
                           currentMoveString[3] - ONE,\r
@@ -591,8 +581,7 @@ extern void CopyBoard P((Board to, Board from));
        cl.ftIn <  BOARD_LEFT     )\r
       return 0;\r
 \r
-    Disambiguate(boards[yyboardindex],\r
-                PosFlags(yyboardindex), EP_UNKNOWN, &cl);\r
+    Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl);\r
 \r
     currentMoveString[0] = cl.ff + AAA;\r
     currentMoveString[1] = cl.rf + ONE;\r
@@ -652,8 +641,7 @@ extern void CopyBoard P((Board to, Board from));
        cl.ftIn <  BOARD_LEFT     )\r
       return 0;\r
 \r
-    Disambiguate(boards[yyboardindex],\r
-                PosFlags(yyboardindex), EP_UNKNOWN, &cl);\r
+    Disambiguate(boards[yyboardindex], PosFlags(yyboardindex), &cl);\r
 \r
     currentMoveString[0] = cl.ff + AAA;\r
     currentMoveString[1] = cl.rf + ONE;\r
@@ -718,8 +706,6 @@ extern void CopyBoard P((Board to, Board from));
     }\r
     return (int) LegalityTest(boards[yyboardindex],\r
                              PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.!\r
-                             EP_UNKNOWN,\r
-                              castlingRights[yyboardindex], /* [HGM] use true castling rights */\r
                              rf, ff, rt, ft, NULLCHAR);\r
 }\r
 \r
@@ -775,8 +761,6 @@ extern void CopyBoard P((Board to, Board from));
 \r
     return (int) LegalityTest(boards[yyboardindex],\r
                              PosFlags(yyboardindex)&~F_MANDATORY_CAPTURE, // [HGM] losers: e.p.!\r
-                             EP_UNKNOWN,\r
-                              castlingRights[yyboardindex], /* [HGM] use true castling rights */\r
                              rf, ff, rt, ft, NULLCHAR);\r
 }\r
 \r
diff --git a/shogibitmaps/README b/shogibitmaps/README
deleted file mode 100644 (file)
index 94e05c4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-These bitmaps are distributed under the GNU GENERAL PUBLIC LICENSE
-coming with xboard.
diff --git a/shogibitmaps/sa58o.bmp b/shogibitmaps/sa58o.bmp
deleted file mode 100644 (file)
index fcae346..0000000
Binary files a/shogibitmaps/sa58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sb58o.bmp b/shogibitmaps/sb58o.bmp
deleted file mode 100644 (file)
index 75b2be2..0000000
Binary files a/shogibitmaps/sb58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sc58o.bmp b/shogibitmaps/sc58o.bmp
deleted file mode 100644 (file)
index 84bef21..0000000
Binary files a/shogibitmaps/sc58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sf58o.bmp b/shogibitmaps/sf58o.bmp
deleted file mode 100644 (file)
index 5c1d43a..0000000
Binary files a/shogibitmaps/sf58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sg58o.bmp b/shogibitmaps/sg58o.bmp
deleted file mode 100644 (file)
index 580814c..0000000
Binary files a/shogibitmaps/sg58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sh58o.bmp b/shogibitmaps/sh58o.bmp
deleted file mode 100644 (file)
index 8b906eb..0000000
Binary files a/shogibitmaps/sh58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sk58o.bmp b/shogibitmaps/sk58o.bmp
deleted file mode 100644 (file)
index 8b57f9e..0000000
Binary files a/shogibitmaps/sk58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sk58w.bmp b/shogibitmaps/sk58w.bmp
deleted file mode 100644 (file)
index a419066..0000000
Binary files a/shogibitmaps/sk58w.bmp and /dev/null differ
diff --git a/shogibitmaps/sl58o.bmp b/shogibitmaps/sl58o.bmp
deleted file mode 100644 (file)
index 799b21a..0000000
Binary files a/shogibitmaps/sl58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sl58w.bmp b/shogibitmaps/sl58w.bmp
deleted file mode 100644 (file)
index dc1ce99..0000000
Binary files a/shogibitmaps/sl58w.bmp and /dev/null differ
diff --git a/shogibitmaps/sn58o.bmp b/shogibitmaps/sn58o.bmp
deleted file mode 100644 (file)
index 387e28f..0000000
Binary files a/shogibitmaps/sn58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sn58w.bmp b/shogibitmaps/sn58w.bmp
deleted file mode 100644 (file)
index b1c6af2..0000000
Binary files a/shogibitmaps/sn58w.bmp and /dev/null differ
diff --git a/shogibitmaps/sp58o.bmp b/shogibitmaps/sp58o.bmp
deleted file mode 100644 (file)
index 62be42b..0000000
Binary files a/shogibitmaps/sp58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sp58w.bmp b/shogibitmaps/sp58w.bmp
deleted file mode 100644 (file)
index 2e623c8..0000000
Binary files a/shogibitmaps/sp58w.bmp and /dev/null differ
diff --git a/shogibitmaps/sr58o.bmp b/shogibitmaps/sr58o.bmp
deleted file mode 100644 (file)
index 6f6d142..0000000
Binary files a/shogibitmaps/sr58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sr58w.bmp b/shogibitmaps/sr58w.bmp
deleted file mode 100644 (file)
index 87469d3..0000000
Binary files a/shogibitmaps/sr58w.bmp and /dev/null differ
diff --git a/shogibitmaps/ss58o.bmp b/shogibitmaps/ss58o.bmp
deleted file mode 100644 (file)
index e1aa7ad..0000000
Binary files a/shogibitmaps/ss58o.bmp and /dev/null differ
diff --git a/shogibitmaps/su58o.bmp b/shogibitmaps/su58o.bmp
deleted file mode 100644 (file)
index 9bdce85..0000000
Binary files a/shogibitmaps/su58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sw58o.bmp b/shogibitmaps/sw58o.bmp
deleted file mode 100644 (file)
index cb6029f..0000000
Binary files a/shogibitmaps/sw58o.bmp and /dev/null differ
diff --git a/shogibitmaps/sw58w.bmp b/shogibitmaps/sw58w.bmp
deleted file mode 100644 (file)
index e90dde3..0000000
Binary files a/shogibitmaps/sw58w.bmp and /dev/null differ
index f751669..76750fa 100644 (file)
 #define PACKAGE_NAME "WinBoard"\r
 \r
 /* Define to the full name and version of this package. */\r
-#define PACKAGE_STRING "WinBoard 4.4.1"\r
+#define PACKAGE_STRING "WinBoard master-200911122"\r
 \r
 /* Define to the one symbol short name of this package. */\r
 #define PACKAGE_TARNAME "winboard"\r
 \r
 /* Define to the version of this package. */\r
-#define PACKAGE_VERSION "4.4.1"\r
+#define PACKAGE_VERSION "master-20091122"\r
 \r
 /* Define the Windows-specific FILE version info.  this *MUST* be four comma separated 16-bit integers */\r
-#define PACKAGE_FILEVERSION 4,4,1,0\r
+#define PACKAGE_FILEVERSION 4,4,2,0\r
 \r
 #define PTY_ITERATION\r
 \r
index a9cfd7f..27612fb 100644 (file)
@@ -352,7 +352,6 @@ KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        return;\r
 }\r
 \r
-extern char castlingRights[MAX_MOVES][BOARD_SIZE];\r
 int PosFlags(int nr);\r
 \r
 typedef struct {\r
@@ -431,8 +430,7 @@ PossibleAttackMove()
        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), EP_NONE, \r
-                                               castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);\r
+       GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), ReadCallback, (VOIDSTAR) &cl);\r
        if(cl.count == 0) SayString("None", FALSE);\r
        boards[currentMove][fromY][fromX] = victim; // repair\r
 \r
@@ -459,16 +457,14 @@ PossibleAttacked()
        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), EP_NONE, \r
-                                               castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);\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), EP_NONE, \r
-                                               castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);\r
+       GenLegal(boards[currentMove], PosFlags(currentMove), ReadCallback, (VOIDSTAR) &cl);\r
        if(cl.count == 0) SayString("None", FALSE);\r
        boards[currentMove][fromY][fromX] = victim; // put back original occupant\r
 \r
@@ -1184,11 +1180,11 @@ NiceTime(int x)
 }\r
 \r
 #define JAWS_ARGS \\r
-  { "beepOffBoard", ArgInt, (LPVOID) beeps, TRUE },\\r
-  { "beepEmpty", ArgInt, (LPVOID) (beeps+1), TRUE },\\r
-  { "beepWhite", ArgInt, (LPVOID) (beeps+2), TRUE },\\r
-  { "beepBlack", ArgInt, (LPVOID) (beeps+3), TRUE },\\r
-  { "beepHoldings", ArgInt, (LPVOID) (beeps+4), TRUE },\\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
index e8a7e99..4c73c8d 100644 (file)
@@ -5,9 +5,9 @@ PROJ=winboard
 \r
 \r
 OBJS=backend.o book.o gamelist.o lists.o moves.o pgntags.o uci.o zippy.o\\r
- parser.o wbres.o wclipbrd.o wedittags.o wengineo.o wevalgraph.o\\r
+ parser.o wbres.o wclipbrd.o wedittags.o wengineoutput.o wevalgraph.o\\r
  wgamelist.o whistory.o winboard.o wlayout.o woptions.o wsnap.o\\r
- wsockerr.o help.o wsettings.o wchat.o\r
+ wsockerr.o help.o wsettings.o wchat.o engineoutput.o evalgraph.o\r
 \r
 \r
 # make compiling less spammy\r
@@ -86,8 +86,8 @@ $(PROJ).exe: $(OBJS) $(PROJ).hlp
 \r
 \r
 winboard.o: winboard.c config.h winboard.h ../common.h ../frontend.h ../backend.h \\r
-       ../moves.h wgamelist.h defaults.h resource.h wclipbrd.h \\r
-       wedittags.h wsockerr.h woptions.h wsnap.h ../lists.h help.h\r
+       ../moves.h defaults.h resource.h wclipbrd.h \\r
+       wsockerr.h woptions.h wsnap.h ../lists.h help.h\r
        $(call compile, $<)\r
 \r
 backend.o: ../backend.c config.h ../common.h ../frontend.h ../backend.h \\r
@@ -114,30 +114,38 @@ wclipbrd.o: wclipbrd.c config.h ../common.h ../frontend.h ../backend.h \
        $(call compile, $<)\r
 \r
 wedittags.o: wedittags.c config.h ../common.h winboard.h resource.h ../frontend.h \\r
-       ../backend.h ../lists.h wedittags.h\r
+       ../backend.h ../lists.h\r
        $(call compile, $<)\r
 \r
 wgamelist.o: wgamelist.c config.h. ../common.h winboard.h resource.h ../frontend.h \\r
-       ../backend.h wgamelist.h ../lists.h\r
+       ../backend.h ../lists.h\r
        $(call compile, $<)\r
 \r
 woptions.o: woptions.c config.h ../common.h ../frontend.h ../backend.h ../lists.h \\r
        defaults.h winboard.h resource.h\r
        $(call compile, $<)\r
 \r
-wengineo.o: wengineo.c config.h ../common.h ../frontend.h ../backend.h \\r
-       ../lists.h winboard.h resource.h wsnap.h\r
+wengineoutput.o: wengineoutput.c ../engineoutput.h config.h ../common.h \\r
+       ../frontend.h ../backend.h ../lists.h winboard.h resource.h wsnap.h\r
+       $(call compile, $<)\r
+\r
+engineoutput.o: ../engineoutput.c ../engineoutput.h config.h ../common.h \\r
+       ../frontend.h ../backend.h ../lists.h\r
        $(call compile, $<)\r
 \r
 whistory.o: whistory.c config.h ../common.h ../frontend.h ../backend.h \\r
        ../lists.h winboard.h resource.h wsnap.h\r
        $(call compile, $<)\r
 \r
-wevalgraph.o: wevalgraph.c config.h ../common.h ../frontend.h ../backend.h \\r
-       ../lists.h winboard.h resource.h wsnap.h\r
+wevalgraph.o: wevalgraph.c ../evalgraph.h config.h ../common.h ../frontend.h \\r
+       ../backend.h ../lists.h winboard.h resource.h wsnap.h\r
+       $(call compile, $<)\r
+\r
+evalgraph.o: ../evalgraph.c ../evalgraph.h config.h ../common.h ../frontend.h \\r
+       ../backend.h ../lists.h\r
        $(call compile, $<)\r
 \r
-wlayout.o: wlayout.c config.h ../common.h winboard.h resource.h\r
+wlayout.o: wlayout.c config.h ../common.h ../frontend.h winboard.h resource.h\r
        $(call compile, $<)\r
 \r
 wsockerr.o: wsockerr.c wsockerr.h\r
index 10c95fd..e81f17a 100644 (file)
@@ -13,9 +13,9 @@ PROJ = winboard
 \r
 \r
 OBJS=backend.obj book.obj gamelist.obj lists.obj moves.obj pgntags.obj uci.obj\\r
- zippy.obj parser.obj wclipbrd.obj wedittags.obj wengineo.obj wevalgraph.obj\\r
+ zippy.obj parser.obj wclipbrd.obj wedittags.obj wengineoutput.obj wevalgraph.obj\\r
  wgamelist.obj whistory.obj winboard.obj wlayout.obj woptions.obj wsnap.obj\\r
- wsockerr.obj help.obj wsettings.obj wchat.obj\r
+ wsockerr.obj help.obj wsettings.obj wchat.obj engineoutput.obj evalgraph.obj\r
 \r
 \r
 # Debugging?\r
@@ -122,20 +122,24 @@ wclipbrd.obj: wclipbrd.c config.h ../common.h ../frontend.h ../backend.h \
         $(CC) $(CFLAGS) wclipbrd.c\r
 \r
 wedittags.obj: wedittags.c config.h ../common.h winboard.h resource.h ../frontend.h \\r
-        ../backend.h ../lists.h wedittags.h\r
+        ../backend.h ../lists.h\r
         $(CC) $(CFLAGS) wedittags.c\r
 \r
 wgamelist.obj: wgamelist.c config.h. ../common.h winboard.h resource.h ../frontend.h \\r
-        ../backend.h wgamelist.h ../lists.h\r
+        ../backend.h ../lists.h\r
         $(CC) $(CFLAGS) wgamelist.c\r
 \r
 woptions.obj: woptions.c config.h ../common.h ../frontend.h ../backend.h \\r
        ../lists.h defaults.h winboard.h resource.h\r
         $(CC) $(CFLAGS) woptions.c\r
 \r
-wengineo.obj: wengineo.c config.h ../common.h ../frontend.h ../backend.h \\r
+wengineoutput.obj: wengineoutput.c config.h ../common.h ../frontend.h ../backend.h \\r
        ../lists.h winboard.h resource.h wsnap.h\r
-        $(CC) $(CFLAGS) wengineo.c\r
+        $(CC) $(CFLAGS) wengineoutput.c\r
+\r
+engineoutput.obj: ../engineoutput.c ../engineoutput.h config.h ../common.h \\r
+       ../frontend.h ../backend.h ../lists.h\r
+        $(CC) $(CFLAGS) ../engineoutput.c\r
 \r
 whistory.obj: whistory.c config.h ../common.h ../frontend.h ../backend.h \\r
        ../lists.h winboard.h resource.h wsnap.h\r
@@ -145,7 +149,11 @@ wevalgraph.obj: wevalgraph.c config.h ../common.h ../frontend.h ../backend.h \
        ../lists.h winboard.h resource.h wsnap.h\r
         $(CC) $(CFLAGS) wevalgraph.c\r
 \r
-wlayout.obj: wlayout.c config.h ../common.h winboard.h resource.h\r
+evalgraph.obj: ../evalgraph.c ../evalgraph.h config.h ../common.h ../frontend.h \\r
+       ../backend.h ../lists.h\r
+        $(CC) $(CFLAGS) ../evalgraph.c\r
+\r
+wlayout.obj: wlayout.c config.h ../common.h ../frontend.h winboard.h resource.h\r
         $(CC) $(CFLAGS) wlayout.c\r
 \r
 wsockerr.obj: wsockerr.c wsockerr.h\r
index 744509d..93e5517 100644 (file)
@@ -89,6 +89,9 @@
 #define OPT_TCTime2                     409\r
 #define OPT_TCOdds1                     410\r
 #define OPT_TCOdds2                     411\r
+#define OPT_TCUseFixed                  412\r
+#define OPT_TCFixed                     413\r
+#define OPT_TCftext                     414\r
 #define DLG_PremoveOptions              450\r
 #define DLG_GeneralOptions              453\r
 #define DLG_IcsOptions                  454\r
index a2b0825..fbf3e15 100644 (file)
@@ -32,8 +32,8 @@
 #include <dlgs.h>\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
+#include "winboard.h"\r
 #include "backend.h"\r
 \r
 #include "wsnap.h"\r
@@ -180,8 +180,9 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
                if(!atoi(chatPartner[partner])) {\r
                    sprintf(buf, "> %s\n", mess); // echo only tells to handle, not channel\r
                InsertIntoMemo(hDlg, buf);\r
-               }\r
                sprintf(buf, "xtell %s %s\n", chatPartner[partner], mess);\r
+               } else\r
+               sprintf(buf, "tell %s %s\n", chatPartner[partner], mess);\r
            }\r
            SendToICS(buf);\r
            break;\r
index 6f546a4..f13e77f 100644 (file)
@@ -32,9 +32,9 @@
 #include <sys/stat.h>\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
+#include "winboard.h"\r
 #include "wclipbrd.h"\r
 \r
 /* Imports from winboard.c */\r
@@ -50,6 +50,7 @@ CopyFENToClipboard()
 {\r
   char *fen = NULL;\r
 \r
+  if(gameMode == EditPosition) EditPositionDone(TRUE); // [HGM] mak sure castling rights are set consistently\r
   fen = PositionToFEN(currentMove, NULL);\r
   if (!fen) {\r
     DisplayError("Unable to convert position to FEN.", 0);\r
index 3039f4c..965e723 100644 (file)
 #include <dlgs.h>\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
-#include "wedittags.h"\r
+#include "winboard.h"\r
 \r
 /* Module globals */\r
 static char *editTagsText;\r
-HWND editTagsDialog = NULL;\r
 BOOL editTagsUp = FALSE;\r
 BOOL canEditTags = FALSE;\r
-int editTagsX, editTagsY, editTagsW, editTagsH;\r
 \r
 /* Imports from winboard.c */\r
 extern HINSTANCE hInst;\r
@@ -86,18 +83,18 @@ EditTagsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       GetClientRect(hDlg, &rect);\r
       sizeX = rect.right;\r
       sizeY = rect.bottom;\r
-      if (editTagsX != CW_USEDEFAULT && editTagsY != CW_USEDEFAULT &&\r
-         editTagsW != CW_USEDEFAULT && editTagsH != CW_USEDEFAULT) {\r
+      if (wpTags.x != CW_USEDEFAULT && wpTags.y != CW_USEDEFAULT &&\r
+         wpTags.width != CW_USEDEFAULT && wpTags.height != CW_USEDEFAULT) {\r
        WINDOWPLACEMENT wp;\r
-       EnsureOnScreen(&editTagsX, &editTagsY, 0, 0);\r
+       EnsureOnScreen(&wpTags.x, &wpTags.y, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
        wp.showCmd = SW_SHOW;\r
        wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-       wp.rcNormalPosition.left = editTagsX;\r
-       wp.rcNormalPosition.right = editTagsX + editTagsW;\r
-       wp.rcNormalPosition.top = editTagsY;\r
-       wp.rcNormalPosition.bottom = editTagsY + editTagsH;\r
+       wp.rcNormalPosition.left = wpTags.x;\r
+       wp.rcNormalPosition.right = wpTags.x + wpTags.width;\r
+       wp.rcNormalPosition.top = wpTags.y;\r
+       wp.rcNormalPosition.bottom = wpTags.y + wpTags.height;\r
        SetWindowPlacement(hDlg, &wp);\r
 \r
        GetClientRect(hDlg, &rect);\r
diff --git a/winboard/wedittags.h b/winboard/wedittags.h
deleted file mode 100644 (file)
index e27a338..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*\r
- * wedittags.h -- EditTags window for WinBoard\r
- *\r
- * Copyright 1995,2009 Free Software Foundation, Inc.\r
- *\r
- * Enhancements Copyright 2005 Alessandro Scotti\r
- *\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
-VOID EditTagsProc(void);\r
-extern HWND editTagsDialog;\r
-extern int editTagsX, editTagsY, editTagsW, editTagsH;\r
-\r
index 1c3238f..bb51525 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Engine output (PV)\r
+ * wengineoutput.c - split-off front-end of Engine output (PV) by HGM\r
  *\r
  * Author: Alessandro Scotti (Dec 2005)\r
  *\r
 #include <dlgs.h>\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
+#include "winboard.h"\r
 \r
 #include "wsnap.h"\r
+#include "engineoutput.h"\r
 \r
-// [HGM] define numbers to indicate icons, for referring to them in platform-independent way\r
-#define nColorBlack   1\r
-#define nColorWhite   2\r
-#define nColorUnknown 3\r
-#define nClear        4\r
-#define nPondering    5\r
-#define nThinking     6\r
-#define nAnalyzing    7\r
-\r
+/* Module variables */\r
+int  windowMode = 1;\r
+static BOOLEAN engineOutputDialogUp = FALSE;\r
 HICON icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle\r
-\r
-// [HGM] same for output fields (note that there are two of each type, one per color)\r
-#define nColorIcon 1\r
-#define nStateIcon 2\r
-#define nLabel     3\r
-#define nStateData 4\r
-#define nLabelNPS  5\r
-#define nMemo      6\r
-\r
 HWND outputField[2][7]; // [HGM] front-end array to translate output field to window handle\r
 \r
-void EngineOutputPopUp();\r
-void EngineOutputPopDown();\r
-int  EngineOutputIsUp();\r
-\r
-#define SHOW_PONDERING\r
-\r
-/* Imports from backend.c */\r
-char * SavePart(char *str);\r
-extern int opponentKibitzes;\r
-\r
-/* Imports from winboard.c */\r
-extern HWND engineOutputDialog;\r
-extern int     engineOutputDialogUp;\r
-\r
-extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
-\r
-extern WindowPlacement wpEngineOutput;\r
-\r
-extern BoardSize boardSize;\r
-\r
-/* Module variables */\r
-#define H_MARGIN            2\r
-#define V_MARGIN            2\r
-#define LABEL_V_DISTANCE    1   /* Distance between label and memo */\r
-#define SPLITTER_SIZE       4   /* Distance between first memo and second label */\r
-\r
-#define ICON_SIZE           14\r
-\r
-#define STATE_UNKNOWN   -1\r
-#define STATE_THINKING   0\r
-#define STATE_IDLE       1\r
-#define STATE_PONDERING  2\r
-#define STATE_ANALYZING  3\r
-\r
-static int  windowMode = 1;\r
-\r
-static int  needInit = TRUE;\r
-\r
-static int  lastDepth[2] = { -1, -1 };\r
-static int  lastForwardMostMove[2] = { -1, -1 };\r
-static int  engineState[2] = { -1, -1 };\r
-\r
-typedef struct {\r
-//    HWND hColorIcon; // [HGM] the output-control handles are no loger passed,\r
-//    HWND hLabel;     //       to give better front-end / back-end separation\r
-//    HWND hStateIcon; //       the front-end routines now get them from a (front-end)\r
-//    HWND hStateData; //       table, indexed by output-field indicators.\r
-//    HWND hLabelNPS;\r
-//    HWND hMemo;\r
-    char * name;\r
-    int which;\r
-    int depth;\r
-    u64 nodes;\r
-    int score;\r
-    int time;\r
-    char * pv;\r
-    char * hint;\r
-    int an_move_index;\r
-    int an_move_count;\r
-} EngineOutputData;\r
-\r
-static void VerifyDisplayMode();\r
-static void UpdateControls( EngineOutputData * ed );\r
-static void SetEngineState( int which, int state, char * state_data );\r
-\r
 // front end\r
 static HICON LoadIconEx( int id )\r
 {\r
@@ -138,7 +58,6 @@ static HICON LoadIconEx( int id )
 // This cleanses most other routines of front-end stuff, so they can go into the back end.\r
 static void InitializeEngineOutput()\r
 {\r
- //   if( needInit ) { // needInit was already tested before call\r
        // [HGM] made this into a table, rather than separate global variables\r
         icons[nColorBlack]   = LoadIconEx( IDI_BLACK_14 );\r
         icons[nColorWhite]   = LoadIconEx( IDI_WHITE_14 );\r
@@ -163,8 +82,6 @@ static void InitializeEngineOutput()
         outputField[1][nStateData] = GetDlgItem( engineOutputDialog, IDC_StateData2 );\r
         outputField[1][nLabelNPS]  = GetDlgItem( engineOutputDialog, IDC_Engine2_NPS );\r
         outputField[1][nMemo]      = GetDlgItem( engineOutputDialog, IDC_EngineMemo2 );\r
-//        needInit = FALSE;\r
-//    }\r
 }\r
 \r
 // front end\r
@@ -248,8 +165,9 @@ static void PositionControlSet( HWND hDlg, int x, int y, int clientWidth, int me
 }\r
 \r
 // Also here some of the size calculations should go to the back end, and their actual application to a front-end routine\r
-static void ResizeWindowControls( HWND hDlg, int mode )\r
+void ResizeWindowControls( int mode )\r
 {\r
+    HWND hDlg = engineOutputDialog; // [HGM] used to be parameter, but routine is called from back-end\r
     RECT rc;\r
     int headerHeight = GetHeaderHeight();\r
 //    int labelHeight = GetControlHeight( hDlg, IDC_EngineLabel1 );\r
@@ -306,16 +224,16 @@ static void ResizeWindowControls( HWND hDlg, int mode )
 }\r
 \r
 // front end. Actual printing of PV lines into the output field\r
-static void InsertIntoMemo( int which, char * text )\r
+void InsertIntoMemo( int which, char * text, int where )\r
 {\r
-    SendMessage( outputField[which][nMemo], EM_SETSEL, 0, 0 );\r
+    SendMessage( outputField[which][nMemo], EM_SETSEL, where, where ); // [HGM] multivar: choose insertion point\r
 \r
     SendMessage( outputField[which][nMemo], EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text );\r
 }\r
 \r
 // front end. Associates an icon with an output field ("control" in Windows jargon).\r
 // [HGM] let it find out the output field from the 'which' number by itself\r
-static void SetIcon( int which, int field, int nIcon )\r
+void SetIcon( int which, int field, int nIcon )\r
 {\r
 \r
     if( nIcon != 0 ) {\r
@@ -341,7 +259,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA
 \r
             RestoreWindowPlacement( hDlg, &wpEngineOutput ); /* Restore window placement */\r
 \r
-            ResizeWindowControls( hDlg, windowMode );\r
+            ResizeWindowControls( windowMode );\r
 \r
            /* Set font */\r
            SendDlgItemMessage( engineOutputDialog, IDC_EngineMemo1, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 ));\r
@@ -383,7 +301,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA
         break;\r
 \r
     case WM_SIZE:\r
-        ResizeWindowControls( hDlg, windowMode );\r
+        ResizeWindowControls( windowMode );\r
         break;\r
 \r
     case WM_ENTERSIZEMOVE:\r
@@ -406,6 +324,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA
 void EngineOutputPopUp()\r
 {\r
   FARPROC lpProc;\r
+  static int  needInit = TRUE;\r
   \r
   CheckMenuItem(GetMenu(hwndMain), IDM_ShowEngineOutput, MF_CHECKED);\r
 \r
@@ -452,404 +371,14 @@ void DoClearMemo(int which)
         SendMessage( outputField[which][nMemo], WM_SETTEXT, 0, (LPARAM) "" );\r
 }\r
 \r
-//------------------------ pure back-end routines -------------------------------\r
-\r
-\r
-// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments\r
-static void SetEngineState( int which, int state, char * state_data )\r
-{\r
-    int x_which = 1 - which;\r
-\r
-    if( engineState[ which ] != state ) {\r
-        engineState[ which ] = state;\r
-\r
-        switch( state ) {\r
-        case STATE_THINKING:\r
-            SetIcon( which, nStateIcon, nThinking );\r
-            if( engineState[ x_which ] == STATE_THINKING ) {\r
-                SetEngineState( x_which, STATE_IDLE, "" );\r
-            }\r
-            break;\r
-        case STATE_PONDERING:\r
-            SetIcon( which, nStateIcon, nPondering );\r
-            break;\r
-        case STATE_ANALYZING:\r
-            SetIcon( which, nStateIcon, nAnalyzing );\r
-            break;\r
-        default:\r
-            SetIcon( which, nStateIcon, nClear );\r
-            break;\r
-        }\r
-    }\r
-\r
-    if( state_data != 0 ) {\r
-        DoSetWindowText( which, nStateData, state_data );\r
-    }\r
-}\r
-\r
-// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles.\r
-void EngineOutputUpdate( FrontEndProgramStats * stats )\r
-{\r
-    EngineOutputData ed;\r
-    int clearMemo = FALSE;\r
-    int which;\r
-    int depth;\r
-\r
-    if( stats == 0 ) {\r
-        SetEngineState( 0, STATE_IDLE, "" );\r
-        SetEngineState( 1, STATE_IDLE, "" );\r
-        return;\r
-    }\r
-\r
-    if(gameMode == IcsObserving && !appData.icsEngineAnalyze)\r
-       return; // [HGM] kibitz: shut up engine if we are observing an ICS game\r
-\r
-    which = stats->which;\r
-    depth = stats->depth;\r
-\r
-    if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) {\r
-        return;\r
-    }\r
-\r
-    if( engineOutputDialog == NULL ) {\r
-        return;\r
-    }\r
-\r
-    VerifyDisplayMode();\r
-\r
-    ed.which = which;\r
-    ed.depth = depth;\r
-    ed.nodes = stats->nodes;\r
-    ed.score = stats->score;\r
-    ed.time = stats->time;\r
-    ed.pv = stats->pv;\r
-    ed.hint = stats->hint;\r
-    ed.an_move_index = stats->an_move_index;\r
-    ed.an_move_count = stats->an_move_count;\r
-\r
-    /* Get target control. [HGM] this is moved to front end, which get them from a table */\r
-    if( which == 0 ) {\r
-        ed.name = first.tidy;\r
-    }\r
-    else {\r
-        ed.name = second.tidy;\r
-    }\r
-\r
-    /* Clear memo if needed */\r
-    if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1) ) {\r
-        clearMemo = TRUE;\r
-    }\r
-\r
-    if( lastForwardMostMove[which] != forwardMostMove ) {\r
-        clearMemo = TRUE;\r
-    }\r
-\r
-    if( clearMemo ) DoClearMemo(which);\r
-\r
-    /* Update */\r
-    lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge\r
-    lastForwardMostMove[which] = forwardMostMove;\r
-\r
-    if( ed.pv != 0 && ed.pv[0] == ' ' ) {\r
-        if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */\r
-            ed.pv = "";\r
-        }\r
-    }\r
-\r
-    UpdateControls( &ed );\r
-}\r
-\r
-#define ENGINE_COLOR_WHITE      'w'\r
-#define ENGINE_COLOR_BLACK      'b'\r
-#define ENGINE_COLOR_UNKNOWN    ' '\r
-\r
-// pure back end\r
-char GetEngineColor( int which )\r
-{\r
-    char result = ENGINE_COLOR_UNKNOWN;\r
-\r
-    if( which == 0 || which == 1 ) {\r
-        ChessProgramState * cps;\r
-\r
-        switch (gameMode) {\r
-        case MachinePlaysBlack:\r
-        case IcsPlayingBlack:\r
-            result = ENGINE_COLOR_BLACK;\r
-            break;\r
-        case MachinePlaysWhite:\r
-        case IcsPlayingWhite:\r
-            result = ENGINE_COLOR_WHITE;\r
-            break;\r
-        case AnalyzeMode:\r
-        case AnalyzeFile:\r
-            result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;\r
-            break;\r
-        case TwoMachinesPlay:\r
-            cps = (which == 0) ? &first : &second;\r
-            result = cps->twoMachinesColor[0];\r
-            result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;\r
-            break;\r
-        default: ; // does not happen, but suppresses pedantic warnings\r
-        }\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// pure back end\r
-char GetActiveEngineColor()\r
-{\r
-    char result = ENGINE_COLOR_UNKNOWN;\r
-\r
-    if( gameMode == TwoMachinesPlay ) {\r
-        result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// pure back end\r
-static int IsEnginePondering( int which )\r
-{\r
-    int result = FALSE;\r
-\r
-    switch (gameMode) {\r
-    case MachinePlaysBlack:\r
-    case IcsPlayingBlack:\r
-        if( WhiteOnMove(forwardMostMove) ) result = TRUE;\r
-        break;\r
-    case MachinePlaysWhite:\r
-    case IcsPlayingWhite:\r
-        if( ! WhiteOnMove(forwardMostMove) ) result = TRUE;\r
-        break;\r
-    case TwoMachinesPlay:\r
-        if( GetActiveEngineColor() != ENGINE_COLOR_UNKNOWN ) {\r
-            if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE;\r
-        }\r
-        break;\r
-    default: ; // does not happen, but suppresses pedantic warnings\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// back end\r
-static void SetDisplayMode( int mode )\r
-{\r
-    if( windowMode != mode ) {\r
-        windowMode = mode;\r
-\r
-        ResizeWindowControls( engineOutputDialog, mode );\r
-    }\r
-}\r
-\r
-// pure back end\r
-static void VerifyDisplayMode()\r
-{\r
-    int mode;\r
-\r
-    /* Get proper mode for current game */\r
-    switch( gameMode ) {\r
-    case IcsObserving:    // [HGM] ICS analyze\r
-       if(!appData.icsEngineAnalyze) return;\r
-    case AnalyzeMode:\r
-    case AnalyzeFile:\r
-    case MachinePlaysWhite:\r
-    case MachinePlaysBlack:\r
-        mode = 0;\r
-        break;\r
-    case IcsPlayingWhite:\r
-    case IcsPlayingBlack:\r
-        mode = appData.zippyPlay && opponentKibitzes; // [HGM] kibitz\r
-        break;\r
-    case TwoMachinesPlay:\r
-        mode = 1;\r
-        break;\r
-    default:\r
-        /* Do not change */\r
-        return;\r
-    }\r
-\r
-    SetDisplayMode( mode );\r
-}\r
-\r
-// back end. Determine what icon to se in the color-icon field, and print it\r
-static void SetEngineColorIcon( int which )\r
-{\r
-    char color = GetEngineColor(which);\r
-    int nicon = 0;\r
-\r
-    if( color == ENGINE_COLOR_BLACK )\r
-        nicon = nColorBlack;\r
-    else if( color == ENGINE_COLOR_WHITE )\r
-        nicon = nColorWhite;\r
-    else\r
-        nicon = nColorUnknown;\r
-\r
-    SetIcon( which, nColorIcon, nicon );\r
-}\r
-\r
-#define MAX_NAME_LENGTH 32\r
-\r
-// pure back end, now SetWindowText is called via wrapper DoSetWindowText\r
-static void UpdateControls( EngineOutputData * ed )\r
-{\r
-//    int isPondering = FALSE;\r
-\r
-    char s_label[MAX_NAME_LENGTH + 32];\r
-    \r
-    char * name = ed->name;\r
-\r
-    /* Label */\r
-    if( name == 0 || *name == '\0' ) {\r
-        name = "?";\r
-    }\r
-\r
-    strncpy( s_label, name, MAX_NAME_LENGTH );\r
-    s_label[ MAX_NAME_LENGTH-1 ] = '\0';\r
-\r
-#ifdef SHOW_PONDERING\r
-    if( IsEnginePondering( ed->which ) ) {\r
-        char buf[8];\r
-\r
-        buf[0] = '\0';\r
-\r
-        if( ed->hint != 0 && *ed->hint != '\0' ) {\r
-            strncpy( buf, ed->hint, sizeof(buf) );\r
-            buf[sizeof(buf)-1] = '\0';\r
-        }\r
-        else if( ed->pv != 0 && *ed->pv != '\0' ) {\r
-            char * sep = strchr( ed->pv, ' ' );\r
-            int buflen = sizeof(buf);\r
-\r
-            if( sep != NULL ) {\r
-                buflen = sep - ed->pv + 1;\r
-                if( buflen > sizeof(buf) ) buflen = sizeof(buf);\r
-            }\r
-\r
-            strncpy( buf, ed->pv, buflen );\r
-            buf[ buflen-1 ] = '\0';\r
-        }\r
-\r
-        SetEngineState( ed->which, STATE_PONDERING, buf );\r
-    }\r
-    else if( gameMode == TwoMachinesPlay ) {\r
-        SetEngineState( ed->which, STATE_THINKING, "" );\r
-    }\r
-    else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile\r
-         || (gameMode == IcsObserving && appData.icsEngineAnalyze)) { // [HGM] ICS-analyze\r
-        char buf[64];\r
-        int time_secs = ed->time / 100;\r
-        int time_mins = time_secs / 60;\r
-\r
-        buf[0] = '\0';\r
-\r
-        if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) {\r
-            char mov[16];\r
-\r
-            strncpy( mov, ed->hint, sizeof(mov) );\r
-            mov[ sizeof(mov)-1 ] = '\0';\r
-\r
-            sprintf( buf, "%d/%d: %s [%02d:%02d:%02d]", ed->an_move_index, ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 );\r
-        }\r
-\r
-        SetEngineState( ed->which, STATE_ANALYZING, buf );\r
-    }\r
-    else {\r
-        SetEngineState( ed->which, STATE_IDLE, "" );\r
-    }\r
-#endif\r
-\r
-    DoSetWindowText( ed->which, nLabel, s_label );\r
-\r
-    s_label[0] = '\0';\r
-\r
-    if( ed->time > 0 && ed->nodes > 0 ) {\r
-        unsigned long nps_100 = ed->nodes / ed->time;\r
-\r
-        if( nps_100 < 100000 ) {\r
-            sprintf( s_label, "NPS: %lu", nps_100 * 100 );\r
-        }\r
-        else {\r
-            sprintf( s_label, "NPS: %.1fk", nps_100 / 10.0 );\r
-        }\r
-    }\r
-\r
-    DoSetWindowText( ed->which, nLabelNPS, s_label );\r
-\r
-    /* Memo */\r
-    if( ed->pv != 0 && *ed->pv != '\0' ) {\r
-        char s_nodes[24];\r
-        char s_score[16];\r
-        char s_time[24];\r
-        char buf[256];\r
-        int buflen;\r
-        int time_secs = ed->time / 100;\r
-        int time_cent = ed->time % 100;\r
-\r
-        /* Nodes */\r
-        if( ed->nodes < 1000000 ) {\r
-            sprintf( s_nodes, u64Display, ed->nodes );\r
-        }\r
-        else {\r
-            sprintf( s_nodes, "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 );\r
-        }\r
-\r
-        /* Score */\r
-        if( ed->score > 0 ) {\r
-            sprintf( s_score, "+%.2f", ed->score / 100.0 );\r
-        }\r
-        else {\r
-            sprintf( s_score, "%.2f", ed->score / 100.0 );\r
-        }\r
-\r
-        /* Time */\r
-        sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent );\r
-\r
-        /* Put all together... */\r
-       if(ed->nodes == 0 && ed->score == 0 && ed->time == 0) sprintf( buf, "%3d\t", ed->depth ); else \r
-       sprintf( buf, "%3d\t%s\t%s\t%s\t", ed->depth, s_score, s_nodes, s_time );\r
-\r
-        /* Add PV */\r
-        buflen = strlen(buf);\r
-\r
-        strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen );\r
-\r
-        buf[ sizeof(buf) - 3 ] = '\0';\r
-\r
-        strcat( buf + buflen, "\r\n" );\r
-\r
-        /* Update memo */\r
-        InsertIntoMemo( ed->which, buf );\r
-    }\r
-\r
-    /* Colors */\r
-    SetEngineColorIcon( ed->which );\r
-}\r
-\r
-// back end\r
+// front end (because only other front-end wants to know)\r
 int EngineOutputIsUp()\r
 {\r
     return engineOutputDialogUp;\r
 }\r
 \r
-// [HGM] kibitz: write kibitz line; split window for it if necessary\r
-void OutputKibitz(int window, char *text)\r
+// front end, to give back-end access to engineOutputDialog\r
+int EngineOutputDialogExists()\r
 {\r
-       if(!EngineOutputIsUp()) return;\r
-       if(!opponentKibitzes) { // on first kibitz of game, clear memos\r
-           DoClearMemo(1);\r
-           if(gameMode == IcsObserving) DoClearMemo(0);\r
-       }\r
-       opponentKibitzes = TRUE; // this causes split window DisplayMode in ICS modes.\r
-       VerifyDisplayMode();\r
-       if(gameMode == IcsObserving) {\r
-           DoSetWindowText(0, nLabel, gameInfo.white);\r
-           SetIcon( 0, nColorIcon,  nColorWhite);\r
-           SetIcon( 0, nStateIcon,  nClear);\r
-       }\r
-       DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name\r
-       SetIcon( 1, nColorIcon,  gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);\r
-       SetIcon( 1, nStateIcon,  nClear);\r
-       InsertIntoMemo(window-1, text);\r
+    return engineOutputDialog != NULL;\r
 }\r
index be51991..ec57ab3 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Evaluation graph\r
+ * wevalgraph.c - Evaluation graph front-end part\r
  *\r
  * Author: Alessandro Scotti (Dec 2005)\r
  *\r
 \r
 #include "config.h"\r
 \r
-#include <windows.h> /* required for all Windows applications */\r
-//include <richedit.h>\r
+#include <windows.h>\r
+#include <commdlg.h>\r
+#include <dlgs.h>\r
 #include <stdio.h>\r
-//include <stdlib.h>\r
-//include <malloc.h>\r
 \r
 #include "common.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
-\r
-/* Imports from winboard.c */\r
-extern BOOLEAN evalGraphDialogUp; // should be back-end variable, and defined here\r
-\r
-/* Module globals */ // used to communicate between back-end and front-end part\r
-static ChessProgramStats_Move * currPvInfo;\r
-static int currFirst = 0;\r
-static int currLast = 0;\r
-static int currCurrent = -1;\r
-\r
-static int nWidthPB = 0;\r
-static int nHeightPB = 0;\r
-\r
-static int MarginX = 18;\r
-static int MarginW = 4;\r
-static int MarginH = 4;\r
-\r
-#define MIN_HIST_WIDTH  4\r
-#define MAX_HIST_WIDTH  10\r
-\r
-#define PEN_NONE       0\r
-#define PEN_BLACK      1\r
-#define PEN_DOTTED     2\r
-#define PEN_BLUEDOTTED 3\r
-#define PEN_BOLD       4 /* or 5 for black */\r
-\r
-#define FILLED 1\r
-#define OPEN   0\r
-\r
-// calls from back-end part into front-end\r
-static void DrawSegment( int x, int y, int *lastX, int *lastY, int penType );\r
-void DrawRectangle( int left, int top, int right, int bottom, int side, int style );\r
-void DrawEvalText(char *buf, int cbBuf, int y);\r
-\r
-\r
-// back-end\r
-static void DrawLine( int x1, int y1, int x2, int y2, int penType )\r
-{\r
-    DrawSegment( x1, y1, NULL, NULL, PEN_NONE );\r
-    DrawSegment( x2, y2, NULL, NULL, penType );\r
-}\r
-\r
-// back-end\r
-static void DrawLineEx( int x1, int y1, int x2, int y2, int penType )\r
-{\r
-    int savX, savY;\r
-    DrawSegment( x1, y1, &savX, &savY, PEN_NONE );\r
-    DrawSegment( x2, y2, NULL, NULL, penType );\r
-    DrawSegment( savX, savY, NULL, NULL, PEN_NONE );\r
-}\r
-\r
-// back-end\r
-static int GetPvScore( int index )\r
-{\r
-    int score = currPvInfo[ index ].score;\r
-\r
-    if( index & 1 ) score = -score; /* Flip score for black */\r
-\r
-    return score;\r
-}\r
-\r
-// back-end\r
-/*\r
-    For a centipawn value, this function returns the height of the corresponding\r
-    histogram, centered on the reference axis.\r
-\r
-    Note: height can be negative!\r
-*/\r
-static int GetValueY( int value )\r
-{\r
-    if( value < -700 ) value = -700;\r
-    if( value > +700 ) value = +700;\r
-\r
-    return (nHeightPB / 2) - (int)(value * (nHeightPB - 2*MarginH) / 1400.0);\r
-}\r
-\r
-// the brush selection is made part of the DrawLine, by passing a style argument\r
-// the wrapper for doing the text output makes this back-end\r
-static void DrawAxisSegmentHoriz( int value, BOOL drawValue )\r
-{\r
-    int y = GetValueY( value*100 );\r
-\r
-    if( drawValue ) {\r
-        char buf[MSG_SIZ], *b = buf;\r
-\r
-        if( value > 0 ) *b++ = '+';\r
-       sprintf(b, "%d", value);\r
-\r
-       DrawEvalText(buf, strlen(buf), y);\r
-    }\r
-    // [HGM] counts on DrawEvalText to have select transparent background for dotted line!\r
-    DrawLine( MarginX, y, MarginX + MarginW, y, PEN_BLACK ); // Y-axis tick marks\r
-    DrawLine( MarginX + MarginW, y, nWidthPB - MarginW, y, PEN_DOTTED ); // hor grid\r
-}\r
-\r
-// The DrawLines again must select their own brush.\r
-// the initial brush selection is useless? BkMode needed for dotted line and text\r
-static void DrawAxis()\r
-{\r
-    int cy = nHeightPB / 2;\r
-    \r
-//    SelectObject( hdcPB, GetStockObject(NULL_BRUSH) );\r
-\r
-//    SetBkMode( hdcPB, TRANSPARENT );\r
-\r
-    DrawAxisSegmentHoriz( +5, TRUE );\r
-    DrawAxisSegmentHoriz( +3, FALSE );\r
-    DrawAxisSegmentHoriz( +1, FALSE );\r
-    DrawAxisSegmentHoriz(  0, TRUE );\r
-    DrawAxisSegmentHoriz( -1, FALSE );\r
-    DrawAxisSegmentHoriz( -3, FALSE );\r
-    DrawAxisSegmentHoriz( -5, TRUE );\r
-\r
-    DrawLine( MarginX + MarginW, cy, nWidthPB - MarginW, cy, PEN_BLACK ); // x-axis\r
-    DrawLine( MarginX + MarginW, MarginH, MarginX + MarginW, nHeightPB - MarginH, PEN_BLACK ); // y-axis\r
-}\r
-\r
-// back-end\r
-static void DrawHistogram( int x, int y, int width, int value, int side )\r
-{\r
-    int left, top, right, bottom;\r
-\r
-    if( value > -25 && value < +25 ) return;\r
-\r
-    left = x;\r
-    right = left + width + 1;\r
-\r
-    if( value > 0 ) {\r
-        top = GetValueY( value );\r
-        bottom = y+1;\r
-    }\r
-    else {\r
-        top = y;\r
-        bottom = GetValueY( value ) + 1;\r
-    }\r
-\r
-\r
-    if( width == MIN_HIST_WIDTH ) {\r
-        right--;\r
-        DrawRectangle( left, top, right, bottom, side, FILLED );\r
-    }\r
-    else {\r
-        DrawRectangle( left, top, right, bottom, side, OPEN );\r
-    }\r
-}\r
-\r
-// back-end\r
-static void DrawSeparator( int index, int x )\r
-{\r
-    if( index > 0 ) {\r
-        if( index == currCurrent ) {\r
-            DrawLineEx( x, MarginH, x, nHeightPB - MarginH, PEN_BLUEDOTTED );\r
-        }\r
-        else if( (index % 20) == 0 ) {\r
-            DrawLineEx( x, MarginH, x, nHeightPB - MarginH, PEN_DOTTED );\r
-        }\r
-    }\r
-}\r
-\r
-// made back-end by replacing MoveToEx and LineTo by DrawSegment\r
-/* Actually draw histogram as a diagram, cause there's too much data */\r
-static void DrawHistogramAsDiagram( int cy, int paint_width, int hist_count )\r
-{\r
-    double step;\r
-    int i;\r
-\r
-    /* Rescale the graph every few moves (as opposed to every move) */\r
-    hist_count -= hist_count % 8;\r
-    hist_count += 8;\r
-    hist_count /= 2;\r
-\r
-    step = (double) paint_width / (hist_count + 1);\r
-\r
-    for( i=0; i<2; i++ ) {\r
-        int index = currFirst;\r
-        int side = (currCurrent + i + 1) & 1; /* Draw current side last */\r
-        double x = MarginX + MarginW;\r
-\r
-        if( (index & 1) != side ) {\r
-            x += step / 2;\r
-            index++;\r
-        }\r
-\r
-        DrawSegment( (int) x, cy, NULL, NULL, PEN_NONE );\r
-\r
-        index += 2;\r
-\r
-        while( index < currLast ) {\r
-            x += step;\r
-\r
-            DrawSeparator( index, (int) x );\r
-\r
-            /* Extend line up to current point */\r
-            if( currPvInfo[index].depth > 0 ) {\r
-                DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, PEN_BOLD + side );\r
-            }\r
-\r
-            index += 2;\r
-        }\r
-    }\r
-}\r
-\r
-// back-end, delete pen selection\r
-static void DrawHistogramFull( int cy, int hist_width, int hist_count )\r
-{\r
-    int i;\r
-\r
-//    SelectObject( hdcPB, GetStockObject(BLACK_PEN) );\r
-\r
-    for( i=0; i<hist_count; i++ ) {\r
-        int index = currFirst + i;\r
-        int x = MarginX + MarginW + index * hist_width;\r
-\r
-        /* Draw a separator every 10 moves */\r
-        DrawSeparator( index, x );\r
-\r
-        /* Draw histogram */\r
-        if( currPvInfo[i].depth > 0 ) {\r
-            DrawHistogram( x, cy, hist_width, GetPvScore(index), index & 1 );\r
-        }\r
-    }\r
-}\r
-\r
-typedef struct {\r
-    int cy;\r
-    int hist_width;\r
-    int hist_count;\r
-    int paint_width;\r
-} VisualizationData;\r
-\r
-// back-end\r
-static Boolean InitVisualization( VisualizationData * vd )\r
-{\r
-    BOOL result = FALSE;\r
-\r
-    vd->cy = nHeightPB / 2;\r
-    vd->hist_width = MIN_HIST_WIDTH;\r
-    vd->hist_count = currLast - currFirst;\r
-    vd->paint_width = nWidthPB - MarginX - 2*MarginW;\r
-\r
-    if( vd->hist_count > 0 ) {\r
-        result = TRUE;\r
-\r
-        /* Compute width */\r
-        vd->hist_width = vd->paint_width / vd->hist_count;\r
-\r
-        if( vd->hist_width > MAX_HIST_WIDTH ) vd->hist_width = MAX_HIST_WIDTH;\r
-\r
-        vd->hist_width -= vd->hist_width % 2;\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// back-end\r
-static void DrawHistograms()\r
-{\r
-    VisualizationData vd;\r
-\r
-    if( InitVisualization( &vd ) ) {\r
-        if( vd.hist_width < MIN_HIST_WIDTH ) {\r
-            DrawHistogramAsDiagram( vd.cy, vd.paint_width, vd.hist_count );\r
-        }\r
-        else {\r
-            DrawHistogramFull( vd.cy, vd.hist_width, vd.hist_count );\r
-        }\r
-    }\r
-}\r
-\r
-// back-end\r
-int GetMoveIndexFromPoint( int x, int y )\r
-{\r
-    int result = -1;\r
-    int start_x = MarginX + MarginW;\r
-    VisualizationData vd;\r
-\r
-    if( x >= start_x && InitVisualization( &vd ) ) {\r
-        /* Almost an hack here... we duplicate some of the paint logic */\r
-        if( vd.hist_width < MIN_HIST_WIDTH ) {\r
-            double step;\r
-\r
-            vd.hist_count -= vd.hist_count % 8;\r
-            vd.hist_count += 8;\r
-            vd.hist_count /= 2;\r
-\r
-            step = (double) vd.paint_width / (vd.hist_count + 1);\r
-            step /= 2;\r
-\r
-            result = (int) (0.5 + (double) (x - start_x) / step);\r
-        }\r
-        else {\r
-            result = (x - start_x) / vd.hist_width;\r
-        }\r
-    }\r
-\r
-    if( result >= currLast ) {\r
-        result = -1;\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// init and display part split of so they can be moved to front end\r
-void PaintEvalGraph( void )\r
-{\r
-    /* Draw */\r
-    DrawRectangle(0, 0, nWidthPB, nHeightPB, 2, FILLED);\r
-    DrawAxis();\r
-    DrawHistograms();\r
-}\r
-\r
-Boolean EvalGraphIsUp()\r
-{\r
-    return evalGraphDialogUp;\r
-}\r
-\r
-// ------------------------------------------ front-end starts here ----------------------------------------------\r
-\r
-#include <commdlg.h>\r
-#include <dlgs.h>\r
-\r
 #include "winboard.h"\r
+#include "evalgraph.h"\r
 #include "wsnap.h"\r
 \r
 #define WM_REFRESH_GRAPH    (WM_USER + 1)\r
 \r
-void EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
-void EvalGraphPopUp();\r
-void EvalGraphPopDown();\r
-Boolean EvalGraphIsUp();\r
-\r
-// calls of front-end part into back-end part\r
-extern int GetMoveIndexFromPoint( int x, int y );\r
-extern void PaintEvalGraph( void );\r
-\r
-/* Imports from winboard.c */\r
-extern HWND evalGraphDialog;\r
-extern BOOLEAN evalGraphDialogUp; // should be back-end, really\r
-\r
-extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
-\r
-extern WindowPlacement wpEvalGraph;\r
+/* Module globals */\r
+static BOOLEAN evalGraphDialogUp;\r
 \r
 static COLORREF crWhite = RGB( 0xFF, 0xFF, 0xB0 );\r
 static COLORREF crBlack = RGB( 0xAD, 0x5D, 0x3D );\r
@@ -388,8 +52,13 @@ static HBITMAP hbmPB = NULL;
 static HPEN pens[6]; // [HGM] put all pens in one array\r
 static HBRUSH hbrHist[3] = { NULL, NULL, NULL };\r
 \r
+Boolean EvalGraphIsUp()\r
+{\r
+    return evalGraphDialogUp;\r
+}\r
+\r
 // [HGM] front-end, added as wrapper to avoid use of LineTo and MoveToEx in other routines (so they can be back-end) \r
-static void DrawSegment( int x, int y, int *lastX, int *lastY, int penType )\r
+void DrawSegment( int x, int y, int *lastX, int *lastY, int penType )\r
 {\r
     POINT stPt;\r
     if(penType == PEN_NONE) MoveToEx( hdcPB, x, y, &stPt ); else {\r
@@ -642,4 +311,3 @@ VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pv
         SendMessage( evalGraphDialog, WM_REFRESH_GRAPH, 0, 0 );\r
     }\r
 }\r
-\r
index 26c843b..31d36ff 100644 (file)
 #include <dlgs.h>\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
+#include "winboard.h"\r
 \r
 #include "wsnap.h"\r
-#include "wgamelist.h"\r
-\r
-extern BoardSize boardSize;\r
 \r
 /* Module globals */\r
-HWND gameListDialog = NULL;\r
-BOOLEAN gameListUp = FALSE;\r
-FILE* gameFile;\r
-char* gameFileName = NULL;\r
-\r
-/* Imports from winboard.c */\r
-extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
-extern WindowPlacement wpGameList;\r
+static BOOLEAN gameListUp = FALSE;\r
+static FILE* gameFile;\r
+static char* gameFileName = NULL;\r
 \r
 struct GameListStats\r
 {\r
@@ -265,7 +256,9 @@ GameListDialog(HWND hDlg, UINT message,     WPARAM wParam, LPARAM lParam)
                              newSizeX, newSizeY);\r
        sizeX = newSizeX;\r
        sizeY = newSizeY;\r
-      }\r
+      } \r
+   else \r
+     GetActualPlacement( gameListDialog, &wpGameList );\r
 \r
       GameListUpdateTitle( hDlg, szDlgTitle, count, ((ListGame *) gameList.tailPred)->number, &stats );\r
     }\r
diff --git a/winboard/wgamelist.h b/winboard/wgamelist.h
deleted file mode 100644 (file)
index aa554f9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*\r
- * wgamelist.h -- Game list window for WinBoard\r
- *\r
- * Copyright 1995,2009 Free Software Foundation, Inc.\r
- *\r
- * Enhancements Copyright 2005 Alessandro Scotti\r
- *\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
-VOID ShowGameListProc(void);\r
-extern HWND gameListDialog;\r
-extern int gameListX, gameListY, gameListW, gameListH;\r
index 73ae025..933359c 100644 (file)
 #include <dlgs.h>\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
+#include "winboard.h"\r
 \r
 #include "wsnap.h"\r
 \r
-VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
-VOID MoveHistoryPopUp();\r
-VOID MoveHistoryPopDown();\r
-BOOL MoveHistoryIsUp();\r
-\r
-/* Imports from backend.c */\r
-char * SavePart(char *str);\r
-\r
-/* Imports from winboard.c */\r
-extern HWND moveHistoryDialog;\r
-extern BOOLEAN moveHistoryDialogUp;\r
-\r
-extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
-\r
-extern WindowPlacement wpMoveHistory;\r
-\r
-extern BoardSize boardSize;\r
-\r
 /* Module globals */\r
 typedef char MoveHistoryString[ MOVE_LEN*2 ];\r
+static BOOLEAN moveHistoryDialogUp = FALSE;\r
 \r
 static int lastFirst = 0;\r
 static int lastLast = 0;\r
index 5a8df2b..ee5fa0c 100644 (file)
 #endif\r
 \r
 #include "common.h"\r
-#include "winboard.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
+#include "winboard.h"\r
 #include "moves.h"\r
 #include "wclipbrd.h"\r
-#include "wgamelist.h"\r
-#include "wedittags.h"\r
 #include "woptions.h"\r
 #include "wsockerr.h"\r
 #include "defaults.h"\r
@@ -158,10 +156,10 @@ char installDir[MSG_SIZ];
 \r
 BoardSize boardSize;\r
 BOOLEAN chessProgram;\r
-static int boardX, boardY;\r
+//static int boardX, boardY;\r
 int  minX, minY; // [HGM] placement: volatile limits on upper-left corner\r
 static int squareSize, lineGap, minorSize;\r
-static int winWidth, winHeight, winW, winH;\r
+static int winW, winH;\r
 static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo\r
 static int logoHeight = 0;\r
 static char messageText[MESSAGE_TEXT_MAX];\r
@@ -181,8 +179,6 @@ char *secondChessProgramNames;
 #define PALETTESIZE 256\r
 \r
 HINSTANCE hInst;          /* current instance */\r
-HWND hwndMain = NULL;        /* root window*/\r
-HWND hwndConsole = NULL;\r
 BOOLEAN alwaysOnTop = FALSE;\r
 RECT boardRect;\r
 COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
@@ -197,8 +193,8 @@ static HBRUSH lightSquareBrush, darkSquareBrush,
   blackSquareBrush, /* [HGM] for band between board and holdings */\r
   explodeBrush,     /* [HGM] atomic */\r
   whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/;\r
-static POINT gridEndpoints[(BOARD_SIZE + 1) * 4];\r
-static DWORD gridVertexCounts[(BOARD_SIZE + 1) * 2];\r
+static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2];\r
+static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2];\r
 static HPEN gridPen = NULL;\r
 static HPEN highlightPen = NULL;\r
 static HPEN premovePen = NULL;\r
@@ -220,7 +216,7 @@ static HBITMAP darkBackTexture = NULL;
 static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
 static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
 static int backTextureSquareSize = 0;\r
-static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE];\r
+static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOARD_FILES];\r
 \r
 #if __GNUC__ && !defined(_winmajor)\r
 #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */\r
@@ -346,15 +342,7 @@ static char *commentTitle;
 static char *commentText;\r
 static int commentIndex;\r
 static Boolean editComment = FALSE;\r
-HWND commentDialog = NULL;\r
-int commentUp = FALSE;\r
-static int commentX, commentY, commentH, commentW;\r
 \r
-static char *analysisTitle;\r
-static char *analysisText;\r
-HWND analysisDialog = NULL;\r
-BOOLEAN analysisDialogUp = FALSE;\r
-static int analysisX, analysisY, analysisH, analysisW;\r
 \r
 char errorTitle[MSG_SIZ];\r
 char errorMessage[2*MSG_SIZ];\r
@@ -424,37 +412,27 @@ VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);
 int NewGameFRC();\r
 int GameListOptions();\r
 \r
-HWND moveHistoryDialog = NULL;\r
-BOOLEAN moveHistoryDialogUp = FALSE;\r
-\r
-WindowPlacement wpMoveHistory;\r
+int dummy; // [HGM] for obsolete args\r
 \r
+HWND hwndMain = NULL;        /* root window*/\r
+HWND hwndConsole = NULL;\r
+HWND commentDialog = NULL;\r
+HWND moveHistoryDialog = NULL;\r
 HWND evalGraphDialog = NULL;\r
-BOOLEAN evalGraphDialogUp = FALSE;\r
-\r
-WindowPlacement wpEvalGraph;\r
-\r
 HWND engineOutputDialog = NULL;\r
-BOOLEAN engineOutputDialogUp = FALSE;\r
+HWND gameListDialog = NULL;\r
+HWND editTagsDialog = NULL;\r
+\r
+int commentUp = FALSE;\r
 \r
+WindowPlacement wpMain;\r
+WindowPlacement wpConsole;\r
+WindowPlacement wpComment;\r
+WindowPlacement wpMoveHistory;\r
+WindowPlacement wpEvalGraph;\r
 WindowPlacement wpEngineOutput;\r
 WindowPlacement wpGameList;\r
-WindowPlacement wpConsole;\r
-\r
-VOID MoveHistoryPopUp();\r
-VOID MoveHistoryPopDown();\r
-VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
-BOOL MoveHistoryIsUp();\r
-\r
-VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
-VOID EvalGraphPopUp();\r
-VOID EvalGraphPopDown();\r
-BOOL EvalGraphIsUp();\r
-\r
-VOID EngineOutputPopUp();\r
-VOID EngineOutputPopDown();\r
-BOOL EngineOutputIsUp();\r
-VOID EngineOutputUpdate( FrontEndProgramStats * stats );\r
+WindowPlacement wpTags;\r
 \r
 VOID EngineOptionsPopup(); // [HGM] settings\r
 \r
@@ -861,15 +839,15 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)
   InitBackEnd2();\r
 \r
   /* Make the window visible; update its client area; and return "success" */\r
-  EnsureOnScreen(&boardX, &boardY, minX, minY);\r
+  EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY);\r
   wp.length = sizeof(WINDOWPLACEMENT);\r
   wp.flags = 0;\r
   wp.showCmd = nCmdShow;\r
   wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-  wp.rcNormalPosition.left = boardX;\r
-  wp.rcNormalPosition.right = boardX + winWidth;\r
-  wp.rcNormalPosition.top = boardY;\r
-  wp.rcNormalPosition.bottom = boardY + winHeight;\r
+  wp.rcNormalPosition.left = wpMain.x;\r
+  wp.rcNormalPosition.right = wpMain.x + wpMain.width;\r
+  wp.rcNormalPosition.top = wpMain.y;\r
+  wp.rcNormalPosition.bottom = wpMain.y + wpMain.height;\r
   SetWindowPlacement(hwndMain, &wp);\r
 \r
   if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
@@ -897,6 +875,9 @@ typedef enum {
   ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window\r
 } ArgType;\r
 \r
+typedef void *ArgIniType;\r
+#define INVALID (ArgIniType) 6915 /* Some number unlikely to be needed as default for anything */\r
+\r
 typedef struct {\r
   char *argName;\r
   ArgType argType;\r
@@ -917,532 +898,553 @@ typedef struct {
   ***/\r
   LPVOID argLoc;\r
   BOOL save;\r
+  ArgIniType defaultValue;\r
 } ArgDescriptor;\r
 \r
 int junk;\r
+\r
+#define XBOARD FALSE\r
+\r
 ArgDescriptor argDescriptors[] = {\r
   /* positional arguments */\r
-  { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
-  { "", ArgNone, NULL },\r
+  { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE, INVALID },\r
+  { "", ArgNone, NULL, FALSE, INVALID },\r
   /* keyword arguments */\r
   JAWS_ARGS\r
-  { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE },\r
-  { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE },\r
-  { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE },\r
-  { "bpc", ArgColor, (LPVOID) &blackPieceColor, FALSE },\r
-  { "lightSquareColor", ArgColor, (LPVOID) &lightSquareColor, TRUE },\r
-  { "lsc", ArgColor, (LPVOID) &lightSquareColor, FALSE },\r
-  { "darkSquareColor", ArgColor, (LPVOID) &darkSquareColor, TRUE },\r
-  { "dsc", ArgColor, (LPVOID) &darkSquareColor, FALSE },\r
-  { "highlightSquareColor", ArgColor, (LPVOID) &highlightSquareColor, TRUE },\r
-  { "hsc", ArgColor, (LPVOID) &highlightSquareColor, FALSE },\r
-  { "premoveHighlightColor", ArgColor, (LPVOID) &premoveHighlightColor, TRUE },\r
-  { "phc", ArgColor, (LPVOID) &premoveHighlightColor, FALSE },\r
-  { "movesPerSession", ArgInt, (LPVOID) &appData.movesPerSession, TRUE },\r
-  { "mps", ArgInt, (LPVOID) &appData.movesPerSession, FALSE },\r
-  { "initString", ArgString, (LPVOID) &appData.initString, FALSE },\r
-  { "firstInitString", ArgString, (LPVOID) &appData.initString, FALSE },\r
-  { "secondInitString", ArgString, (LPVOID) &appData.secondInitString, FALSE },\r
+  { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE, INVALID },\r
+  { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE, INVALID },\r
+  { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE, INVALID },\r
+  { "bpc", ArgColor, (LPVOID) &blackPieceColor, FALSE, INVALID },\r
+  { "lightSquareColor", ArgColor, (LPVOID) &lightSquareColor, TRUE, INVALID },\r
+  { "lsc", ArgColor, (LPVOID) &lightSquareColor, FALSE, INVALID },\r
+  { "darkSquareColor", ArgColor, (LPVOID) &darkSquareColor, TRUE, INVALID },\r
+  { "dsc", ArgColor, (LPVOID) &darkSquareColor, FALSE, INVALID },\r
+  { "highlightSquareColor", ArgColor, (LPVOID) &highlightSquareColor, TRUE, INVALID },\r
+  { "hsc", ArgColor, (LPVOID) &highlightSquareColor, FALSE, INVALID },\r
+  { "premoveHighlightColor", ArgColor, (LPVOID) &premoveHighlightColor, TRUE, INVALID },\r
+  { "phc", ArgColor, (LPVOID) &premoveHighlightColor, FALSE, INVALID },\r
+  { "movesPerSession", ArgInt, (LPVOID) &appData.movesPerSession, TRUE, (ArgIniType) MOVES_PER_SESSION },\r
+  { "mps", ArgInt, (LPVOID) &appData.movesPerSession, FALSE, INVALID },\r
+  { "initString", ArgString, (LPVOID) &appData.initString, FALSE, INVALID },\r
+  { "firstInitString", ArgString, (LPVOID) &appData.initString, FALSE, (ArgIniType) INIT_STRING },\r
+  { "secondInitString", ArgString, (LPVOID) &appData.secondInitString, FALSE, (ArgIniType) INIT_STRING },\r
   { "firstComputerString", ArgString, (LPVOID) &appData.firstComputerString,\r
-    FALSE },\r
+    FALSE, (ArgIniType) COMPUTER_STRING },\r
   { "secondComputerString", ArgString, (LPVOID) &appData.secondComputerString,\r
-    FALSE },\r
+    FALSE, (ArgIniType) COMPUTER_STRING },\r
   { "firstChessProgram", ArgFilename, (LPVOID) &appData.firstChessProgram,\r
-    FALSE },\r
-  { "fcp", ArgFilename, (LPVOID) &appData.firstChessProgram, FALSE },\r
+    FALSE, (ArgIniType) FIRST_CHESS_PROGRAM },\r
+  { "fcp", ArgFilename, (LPVOID) &appData.firstChessProgram, FALSE, INVALID },\r
   { "secondChessProgram", ArgFilename, (LPVOID) &appData.secondChessProgram,\r
-    FALSE },\r
-  { "scp", ArgFilename, (LPVOID) &appData.secondChessProgram, FALSE },\r
-  { "firstPlaysBlack", ArgBoolean, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "fb", ArgTrue, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "xfb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "-fb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE },\r
-  { "noChessProgram", ArgBoolean, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "ncp", ArgTrue, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "xncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "-ncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE },\r
-  { "firstHost", ArgString, (LPVOID) &appData.firstHost, FALSE },\r
-  { "fh", ArgString, (LPVOID) &appData.firstHost, FALSE },\r
-  { "secondHost", ArgString, (LPVOID) &appData.secondHost, FALSE },\r
-  { "sh", ArgString, (LPVOID) &appData.secondHost, FALSE },\r
-  { "firstDirectory", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE },\r
-  { "fd", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE },\r
-  { "secondDirectory", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE },\r
-  { "sd", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE },\r
-  /*!!bitmapDirectory?*/\r
-  { "remoteShell", ArgFilename, (LPVOID) &appData.remoteShell, FALSE },\r
-  { "rsh", ArgFilename, (LPVOID) &appData.remoteShell, FALSE },\r
-  { "remoteUser", ArgString, (LPVOID) &appData.remoteUser, FALSE },\r
-  { "ruser", ArgString, (LPVOID) &appData.remoteUser, FALSE },\r
-  { "timeDelay", ArgFloat, (LPVOID) &appData.timeDelay, TRUE },\r
-  { "td", ArgFloat, (LPVOID) &appData.timeDelay, FALSE },\r
-  { "timeControl", ArgString, (LPVOID) &appData.timeControl, TRUE },\r
-  { "tc", ArgString, (LPVOID) &appData.timeControl, FALSE },\r
-  { "timeIncrement", ArgInt, (LPVOID) &appData.timeIncrement, TRUE },\r
-  { "inc", ArgInt, (LPVOID) &appData.timeIncrement, FALSE },\r
-  { "internetChessServerMode", ArgBoolean, (LPVOID) &appData.icsActive, FALSE },\r
-  { "ics", ArgTrue, (LPVOID) &appData.icsActive, FALSE },\r
-  { "xics", ArgFalse, (LPVOID) &appData.icsActive, FALSE },\r
-  { "-ics", ArgFalse, (LPVOID) &appData.icsActive, FALSE },\r
-  { "internetChessServerHost", ArgString, (LPVOID) &appData.icsHost, FALSE },\r
-  { "icshost", ArgString, (LPVOID) &appData.icsHost, FALSE },\r
-  { "internetChessServerPort", ArgString, (LPVOID) &appData.icsPort, FALSE },\r
-  { "icsport", ArgString, (LPVOID) &appData.icsPort, FALSE },\r
-  { "internetChessServerCommPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "icscomm", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "internetChessServerComPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "icscom", ArgString, (LPVOID) &appData.icsCommPort, FALSE },\r
-  { "internetChessServerLogonScript", ArgFilename, (LPVOID) &appData.icsLogon, FALSE },\r
-  { "icslogon", ArgFilename, (LPVOID) &appData.icsLogon, FALSE },\r
-  { "useTelnet", ArgBoolean, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "telnet", ArgTrue, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "xtelnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "-telnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE },\r
-  { "telnetProgram", ArgFilename, (LPVOID) &appData.telnetProgram, FALSE },\r
-  { "icshelper", ArgFilename, (LPVOID) &appData.icsHelper, FALSE },\r
-  { "gateway", ArgString, (LPVOID) &appData.gateway, FALSE },\r
-  { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
-  { "lgf", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
-  { "loadGameIndex", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE },\r
-  { "lgi", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE },\r
-  { "saveGameFile", ArgFilename, (LPVOID) &appData.saveGameFile, TRUE },\r
-  { "sgf", ArgFilename, (LPVOID) &appData.saveGameFile, FALSE },\r
-  { "autoSaveGames", ArgBoolean, (LPVOID) &appData.autoSaveGames, TRUE },\r
-  { "autosave", ArgTrue, (LPVOID) &appData.autoSaveGames, FALSE },\r
-  { "xautosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE },\r
-  { "-autosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE },\r
-  { "loadPositionFile", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE },\r
-  { "lpf", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE },\r
-  { "loadPositionIndex", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE },\r
-  { "lpi", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE },\r
-  { "savePositionFile", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE },\r
-  { "spf", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE },\r
-  { "matchMode", ArgBoolean, (LPVOID) &appData.matchMode, FALSE },\r
-  { "mm", ArgTrue, (LPVOID) &appData.matchMode, FALSE },\r
-  { "xmm", ArgFalse, (LPVOID) &appData.matchMode, FALSE },\r
-  { "-mm", ArgFalse, (LPVOID) &appData.matchMode, FALSE },\r
-  { "matchGames", ArgInt, (LPVOID) &appData.matchGames, FALSE },\r
-  { "mg", ArgInt, (LPVOID) &appData.matchGames, FALSE },\r
-  { "monoMode", ArgBoolean, (LPVOID) &appData.monoMode, TRUE },\r
-  { "mono", ArgTrue, (LPVOID) &appData.monoMode, FALSE },\r
-  { "xmono", ArgFalse, (LPVOID) &appData.monoMode, FALSE },\r
-  { "-mono", ArgFalse, (LPVOID) &appData.monoMode, FALSE },\r
-  { "debugMode", ArgBoolean, (LPVOID) &appData.debugMode, FALSE },\r
-  { "debug", ArgTrue, (LPVOID) &appData.debugMode, FALSE },\r
-  { "xdebug", ArgFalse, (LPVOID) &appData.debugMode, FALSE },\r
-  { "-debug", ArgFalse, (LPVOID) &appData.debugMode, FALSE },\r
-  { "clockMode", ArgBoolean, (LPVOID) &appData.clockMode, FALSE },\r
-  { "clock", ArgTrue, (LPVOID) &appData.clockMode, FALSE },\r
-  { "xclock", ArgFalse, (LPVOID) &appData.clockMode, FALSE },\r
-  { "-clock", ArgFalse, (LPVOID) &appData.clockMode, FALSE },\r
-  { "searchTime", ArgString, (LPVOID) &appData.searchTime, FALSE },\r
-  { "st", ArgString, (LPVOID) &appData.searchTime, FALSE },\r
-  { "searchDepth", ArgInt, (LPVOID) &appData.searchDepth, FALSE },\r
-  { "depth", ArgInt, (LPVOID) &appData.searchDepth, FALSE },\r
-  { "showCoords", ArgBoolean, (LPVOID) &appData.showCoords, TRUE },\r
-  { "coords", ArgTrue, (LPVOID) &appData.showCoords, FALSE },\r
-  { "xcoords", ArgFalse, (LPVOID) &appData.showCoords, FALSE },\r
-  { "-coords", ArgFalse, (LPVOID) &appData.showCoords, FALSE },\r
-  { "showThinking", ArgBoolean, (LPVOID) &appData.showThinking, TRUE },\r
-  { "thinking", ArgTrue, (LPVOID) &appData.showThinking, FALSE },\r
-  { "xthinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE },\r
-  { "-thinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE },\r
-  { "ponderNextMove", ArgBoolean, (LPVOID) &appData.ponderNextMove, TRUE },\r
-  { "ponder", ArgTrue, (LPVOID) &appData.ponderNextMove, FALSE },\r
-  { "xponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE },\r
-  { "-ponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE },\r
-  { "periodicUpdates", ArgBoolean, (LPVOID) &appData.periodicUpdates, TRUE },\r
-  { "periodic", ArgTrue, (LPVOID) &appData.periodicUpdates, FALSE },\r
-  { "xperiodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE },\r
-  { "-periodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE },\r
-  { "popupExitMessage", ArgBoolean, (LPVOID) &appData.popupExitMessage, TRUE },\r
-  { "exit", ArgTrue, (LPVOID) &appData.popupExitMessage, FALSE },\r
-  { "xexit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE },\r
-  { "-exit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE },\r
-  { "popupMoveErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, TRUE },\r
-  { "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE },\r
-  { "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE },\r
-  { "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE },\r
+    FALSE, (ArgIniType) SECOND_CHESS_PROGRAM },\r
+  { "scp", ArgFilename, (LPVOID) &appData.secondChessProgram, FALSE, INVALID },\r
+  { "firstPlaysBlack", ArgBoolean, (LPVOID) &appData.firstPlaysBlack, FALSE, FALSE },\r
+  { "fb", ArgTrue, (LPVOID) &appData.firstPlaysBlack, FALSE, FALSE },\r
+  { "xfb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE, INVALID },\r
+  { "-fb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE, INVALID },\r
+  { "noChessProgram", ArgBoolean, (LPVOID) &appData.noChessProgram, FALSE, FALSE },\r
+  { "ncp", ArgTrue, (LPVOID) &appData.noChessProgram, FALSE, INVALID },\r
+  { "xncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE, INVALID },\r
+  { "-ncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE, INVALID },\r
+  { "firstHost", ArgString, (LPVOID) &appData.firstHost, FALSE, (ArgIniType) FIRST_HOST },\r
+  { "fh", ArgString, (LPVOID) &appData.firstHost, FALSE, INVALID },\r
+  { "secondHost", ArgString, (LPVOID) &appData.secondHost, FALSE, (ArgIniType) SECOND_HOST },\r
+  { "sh", ArgString, (LPVOID) &appData.secondHost, FALSE, INVALID },\r
+  { "firstDirectory", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE, (ArgIniType) FIRST_DIRECTORY },\r
+  { "fd", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE, INVALID },\r
+  { "secondDirectory", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE, (ArgIniType) SECOND_DIRECTORY },\r
+  { "sd", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE, INVALID },\r
+\r
+  /* some options only used by the XBoard front end, and ignored in WinBoard         */\r
+  /* Their saving is controlled by XBOARD, which in WinBoard is defined as FALSE */\r
+  { "internetChessServerInputBox", ArgBoolean, (LPVOID) &appData.icsInputBox, XBOARD, (ArgIniType) FALSE },\r
+  { "icsinput", ArgTrue, (LPVOID) &appData.icsInputBox, FALSE, INVALID },\r
+  { "xicsinput", ArgFalse, (LPVOID) &appData.icsInputBox, FALSE, INVALID },\r
+  { "cmail", ArgString, (LPVOID) &appData.cmailGameName, FALSE, (ArgIniType) "" },\r
+  { "soundProgram", ArgFilename, (LPVOID) &appData.soundProgram, XBOARD, (ArgIniType) "play" },\r
+  { "fontSizeTolerance", ArgInt, (LPVOID) &appData.fontSizeTolerance, XBOARD, (ArgIniType) 4 },\r
+  { "lowTimeWarningColor", ArgColor, (LPVOID) &appData.lowTimeWarningColor, XBOARD, \r
+       (ArgIniType) LOWTIMEWARNING_COLOR },\r
+  { "lowTimeWarning", ArgBoolean, (LPVOID) &appData.lowTimeWarning, XBOARD, (ArgIniType) FALSE },\r
+  { "titleInWindow", ArgBoolean, (LPVOID) &appData.titleInWindow, XBOARD, (ArgIniType) FALSE },\r
+  { "title", ArgTrue, (LPVOID) &appData.titleInWindow, FALSE, INVALID },\r
+  { "xtitle", ArgFalse, (LPVOID) &appData.titleInWindow, FALSE, INVALID },\r
+  { "flashCount", ArgInt, (LPVOID) &appData.flashCount, XBOARD, (ArgIniType) FLASH_COUNT },\r
+  { "flashRate", ArgInt, (LPVOID) &appData.flashRate, XBOARD, (ArgIniType) FLASH_RATE },\r
+  { "pixmapDirectory", ArgFilename, (LPVOID) &appData.pixmapDirectory, XBOARD, (ArgIniType) "" },\r
+  { "pixmap", ArgFilename, (LPVOID) &appData.pixmapDirectory, FALSE, INVALID },\r
+  { "bitmapDirectory", ArgFilename, (LPVOID) &appData.bitmapDirectory, XBOARD, (ArgIniType) "" },\r
+  { "bm", ArgFilename, (LPVOID) &appData.bitmapDirectory, FALSE, INVALID },\r
+  { "msLoginDelay", ArgInt, (LPVOID) &appData.msLoginDelay, XBOARD, (ArgIniType) MS_LOGIN_DELAY },\r
+  { "pasteSelection", ArgBoolean, (LPVOID) &appData.pasteSelection, XBOARD, (ArgIniType) FALSE },\r
+\r
+  { "remoteShell", ArgFilename, (LPVOID) &appData.remoteShell, FALSE, (ArgIniType) REMOTE_SHELL },\r
+  { "rsh", ArgFilename, (LPVOID) &appData.remoteShell, FALSE, INVALID },\r
+  { "remoteUser", ArgString, (LPVOID) &appData.remoteUser, FALSE, INVALID },\r
+  { "ruser", ArgString, (LPVOID) &appData.remoteUser, FALSE, INVALID },\r
+  { "timeDelay", ArgFloat, (LPVOID) &appData.timeDelay, TRUE, INVALID },\r
+  { "td", ArgFloat, (LPVOID) &appData.timeDelay, FALSE, INVALID },\r
+  { "timeControl", ArgString, (LPVOID) &appData.timeControl, TRUE, (ArgIniType) TIME_CONTROL },\r
+  { "tc", ArgString, (LPVOID) &appData.timeControl, FALSE, INVALID },\r
+  { "timeIncrement", ArgInt, (LPVOID) &appData.timeIncrement, TRUE, (ArgIniType) TIME_INCREMENT },\r
+  { "inc", ArgInt, (LPVOID) &appData.timeIncrement, FALSE, INVALID },\r
+  { "internetChessServerMode", ArgBoolean, (LPVOID) &appData.icsActive, FALSE, INVALID },\r
+  { "ics", ArgTrue, (LPVOID) &appData.icsActive, FALSE, (ArgIniType) FALSE },\r
+  { "xics", ArgFalse, (LPVOID) &appData.icsActive, FALSE, INVALID },\r
+  { "-ics", ArgFalse, (LPVOID) &appData.icsActive, FALSE, INVALID },\r
+  { "internetChessServerHost", ArgString, (LPVOID) &appData.icsHost, FALSE, (ArgIniType) "" },\r
+  { "icshost", ArgString, (LPVOID) &appData.icsHost, FALSE, INVALID },\r
+  { "internetChessServerPort", ArgString, (LPVOID) &appData.icsPort, FALSE, (ArgIniType) ICS_PORT },\r
+  { "icsport", ArgString, (LPVOID) &appData.icsPort, FALSE, INVALID },\r
+  { "internetChessServerCommPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE, (ArgIniType) ICS_COMM_PORT },\r
+  { "icscomm", ArgString, (LPVOID) &appData.icsCommPort, FALSE, INVALID },\r
+  { "internetChessServerComPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE, INVALID },\r
+  { "icscom", ArgString, (LPVOID) &appData.icsCommPort, FALSE, INVALID },\r
+  { "internetChessServerLogonScript", ArgFilename, (LPVOID) &appData.icsLogon, FALSE, (ArgIniType) ICS_LOGON },\r
+  { "icslogon", ArgFilename, (LPVOID) &appData.icsLogon, FALSE, INVALID },\r
+  { "useTelnet", ArgBoolean, (LPVOID) &appData.useTelnet, FALSE, INVALID },\r
+  { "telnet", ArgTrue, (LPVOID) &appData.useTelnet, FALSE, INVALID },\r
+  { "xtelnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE, INVALID },\r
+  { "-telnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE, INVALID },\r
+  { "telnetProgram", ArgFilename, (LPVOID) &appData.telnetProgram, FALSE, (ArgIniType) TELNET_PROGRAM },\r
+  { "internetChessserverHelper", ArgFilename, (LPVOID) &appData.icsHelper, \r
+       FALSE, INVALID }, // for XB\r
+  { "icshelper", ArgFilename, (LPVOID) &appData.icsHelper, FALSE, (ArgIniType) "" },\r
+  { "gateway", ArgString, (LPVOID) &appData.gateway, FALSE, (ArgIniType) "" },\r
+  { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE, (ArgIniType) "" },\r
+  { "lgf", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE, INVALID },\r
+  { "loadGameIndex", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE, (ArgIniType) 0 },\r
+  { "lgi", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE, INVALID },\r
+  { "saveGameFile", ArgFilename, (LPVOID) &appData.saveGameFile, TRUE, (ArgIniType) "" },\r
+  { "sgf", ArgFilename, (LPVOID) &appData.saveGameFile, FALSE, INVALID },\r
+  { "autoSaveGames", ArgBoolean, (LPVOID) &appData.autoSaveGames, TRUE, (ArgIniType) FALSE },\r
+  { "autosave", ArgTrue, (LPVOID) &appData.autoSaveGames, FALSE, INVALID },\r
+  { "xautosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE, INVALID },\r
+  { "-autosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE, INVALID },\r
+  { "loadPositionFile", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE, (ArgIniType) "" },\r
+  { "lpf", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE, INVALID },\r
+  { "loadPositionIndex", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE, (ArgIniType) 1 },\r
+  { "lpi", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE, INVALID },\r
+  { "savePositionFile", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE, (ArgIniType) "" },\r
+  { "spf", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE, INVALID },\r
+  { "matchMode", ArgBoolean, (LPVOID) &appData.matchMode, FALSE, (ArgIniType) FALSE },\r
+  { "mm", ArgTrue, (LPVOID) &appData.matchMode, FALSE, INVALID },\r
+  { "xmm", ArgFalse, (LPVOID) &appData.matchMode, FALSE, INVALID },\r
+  { "-mm", ArgFalse, (LPVOID) &appData.matchMode, FALSE, INVALID },\r
+  { "matchGames", ArgInt, (LPVOID) &appData.matchGames, FALSE, (ArgIniType) 0 },\r
+  { "mg", ArgInt, (LPVOID) &appData.matchGames, FALSE, INVALID },\r
+  { "monoMode", ArgBoolean, (LPVOID) &appData.monoMode, TRUE, (ArgIniType) FALSE },\r
+  { "mono", ArgTrue, (LPVOID) &appData.monoMode, FALSE, INVALID },\r
+  { "xmono", ArgFalse, (LPVOID) &appData.monoMode, FALSE, INVALID },\r
+  { "-mono", ArgFalse, (LPVOID) &appData.monoMode, FALSE, INVALID },\r
+  { "debugMode", ArgBoolean, (LPVOID) &appData.debugMode, FALSE, (ArgIniType) FALSE },\r
+  { "debug", ArgTrue, (LPVOID) &appData.debugMode, FALSE, INVALID },\r
+  { "xdebug", ArgFalse, (LPVOID) &appData.debugMode, FALSE, INVALID },\r
+  { "-debug", ArgFalse, (LPVOID) &appData.debugMode, FALSE, INVALID },\r
+  { "clockMode", ArgBoolean, (LPVOID) &appData.clockMode, FALSE, (ArgIniType) TRUE },\r
+  { "clock", ArgTrue, (LPVOID) &appData.clockMode, FALSE, INVALID },\r
+  { "xclock", ArgFalse, (LPVOID) &appData.clockMode, FALSE, INVALID },\r
+  { "-clock", ArgFalse, (LPVOID) &appData.clockMode, FALSE, INVALID },\r
+  { "searchTime", ArgString, (LPVOID) &appData.searchTime, FALSE, (ArgIniType) "" },\r
+  { "st", ArgString, (LPVOID) &appData.searchTime, FALSE, INVALID },\r
+  { "searchDepth", ArgInt, (LPVOID) &appData.searchDepth, FALSE, (ArgIniType) 0 },\r
+  { "depth", ArgInt, (LPVOID) &appData.searchDepth, FALSE, INVALID },\r
+  { "showCoords", ArgBoolean, (LPVOID) &appData.showCoords, TRUE, (ArgIniType) FALSE },\r
+  { "coords", ArgTrue, (LPVOID) &appData.showCoords, FALSE, INVALID },\r
+  { "xcoords", ArgFalse, (LPVOID) &appData.showCoords, FALSE, INVALID },\r
+  { "-coords", ArgFalse, (LPVOID) &appData.showCoords, FALSE, INVALID },\r
+  { "showThinking", ArgBoolean, (LPVOID) &appData.showThinking, TRUE, (ArgIniType) FALSE },\r
+  { "thinking", ArgTrue, (LPVOID) &appData.showThinking, FALSE, INVALID },\r
+  { "xthinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE, INVALID },\r
+  { "-thinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE, INVALID },\r
+  { "ponderNextMove", ArgBoolean, (LPVOID) &appData.ponderNextMove, TRUE, (ArgIniType) TRUE },\r
+  { "ponder", ArgTrue, (LPVOID) &appData.ponderNextMove, FALSE, INVALID },\r
+  { "xponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE, INVALID },\r
+  { "-ponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE, INVALID },\r
+  { "periodicUpdates", ArgBoolean, (LPVOID) &appData.periodicUpdates, TRUE, (ArgIniType) TRUE },\r
+  { "periodic", ArgTrue, (LPVOID) &appData.periodicUpdates, FALSE, INVALID },\r
+  { "xperiodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE, INVALID },\r
+  { "-periodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE, INVALID },\r
+  { "popupExitMessage", ArgBoolean, (LPVOID) &appData.popupExitMessage, TRUE, (ArgIniType) TRUE },\r
+  { "exit", ArgTrue, (LPVOID) &appData.popupExitMessage, FALSE, INVALID },\r
+  { "xexit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE, INVALID },\r
+  { "-exit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE, INVALID },\r
+  { "popupMoveErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, TRUE, (ArgIniType) FALSE },\r
+  { "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE, INVALID },\r
+  { "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE, INVALID },\r
+  { "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE, INVALID },\r
   { "popUpErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, \r
-    FALSE }, /* only so that old WinBoard.ini files from betas can be read */\r
-  { "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE },\r
-  { "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE },\r
-  { "coordFont", ArgFont, (LPVOID) COORD_FONT, TRUE },\r
-  { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE },\r
-  { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE },\r
-  { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE },\r
-  { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */\r
+    FALSE, INVALID }, /* only so that old WinBoard.ini files from betas can be read */\r
+  { "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE, INVALID },\r
+  { "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE, INVALID },\r
+  { "coordFont", ArgFont, (LPVOID) COORD_FONT, TRUE, INVALID },\r
+  { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE, INVALID },\r
+  { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE, INVALID },\r
+  { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE, INVALID },\r
+  { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE, INVALID }, /* [AS] */\r
   { "boardSize", ArgBoardSize, (LPVOID) &boardSize,\r
-    TRUE }, /* must come after all fonts */\r
-  { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE },\r
+    TRUE, (ArgIniType) -1 }, /* must come after all fonts */\r
+  { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE, INVALID },\r
   { "ringBellAfterMoves", ArgBoolean, (LPVOID) &appData.ringBellAfterMoves,\r
-    FALSE }, /* historical; kept only so old winboard.ini files will parse */\r
-  { "alwaysOnTop", ArgBoolean, (LPVOID) &alwaysOnTop, TRUE },\r
-  { "top", ArgTrue, (LPVOID) &alwaysOnTop, FALSE },\r
-  { "xtop", ArgFalse, (LPVOID) &alwaysOnTop, FALSE },\r
-  { "-top", ArgFalse, (LPVOID) &alwaysOnTop, FALSE },\r
-  { "autoCallFlag", ArgBoolean, (LPVOID) &appData.autoCallFlag, TRUE },\r
-  { "autoflag", ArgTrue, (LPVOID) &appData.autoCallFlag, FALSE },\r
-  { "xautoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE },\r
-  { "-autoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE },\r
-  { "autoComment", ArgBoolean, (LPVOID) &appData.autoComment, TRUE },\r
-  { "autocomm", ArgTrue, (LPVOID) &appData.autoComment, FALSE },\r
-  { "xautocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE },\r
-  { "-autocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE },\r
-  { "autoObserve", ArgBoolean, (LPVOID) &appData.autoObserve, TRUE },\r
-  { "autobs", ArgTrue, (LPVOID) &appData.autoObserve, FALSE },\r
-  { "xautobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE },\r
-  { "-autobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE },\r
-  { "flipView", ArgBoolean, (LPVOID) &appData.flipView, FALSE },\r
-  { "flip", ArgTrue, (LPVOID) &appData.flipView, FALSE },\r
-  { "xflip", ArgFalse, (LPVOID) &appData.flipView, FALSE },\r
-  { "-flip", ArgFalse, (LPVOID) &appData.flipView, FALSE },\r
-  { "autoFlipView", ArgBoolean, (LPVOID) &appData.autoFlipView, TRUE },\r
-  { "autoflip", ArgTrue, (LPVOID) &appData.autoFlipView, FALSE },\r
-  { "xautoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE },\r
-  { "-autoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE },\r
-  { "autoRaiseBoard", ArgBoolean, (LPVOID) &appData.autoRaiseBoard, TRUE },\r
-  { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE },\r
-  { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE },\r
-  { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE },\r
-  { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE },\r
-  { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE },\r
-  { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE },\r
-  { "-queen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE },\r
-  { "oldSaveStyle", ArgBoolean, (LPVOID) &appData.oldSaveStyle, TRUE },\r
-  { "oldsave", ArgTrue, (LPVOID) &appData.oldSaveStyle, FALSE },\r
-  { "xoldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE },\r
-  { "-oldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE },\r
-  { "quietPlay", ArgBoolean, (LPVOID) &appData.quietPlay, TRUE },\r
-  { "quiet", ArgTrue, (LPVOID) &appData.quietPlay, FALSE },\r
-  { "xquiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE },\r
-  { "-quiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE },\r
-  { "getMoveList", ArgBoolean, (LPVOID) &appData.getMoveList, TRUE },\r
-  { "moves", ArgTrue, (LPVOID) &appData.getMoveList, FALSE },\r
-  { "xmoves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE },\r
-  { "-moves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE },\r
-  { "testLegality", ArgBoolean, (LPVOID) &appData.testLegality, TRUE },\r
-  { "legal", ArgTrue, (LPVOID) &appData.testLegality, FALSE },\r
-  { "xlegal", ArgFalse, (LPVOID) &appData.testLegality, FALSE },\r
-  { "-legal", ArgFalse, (LPVOID) &appData.testLegality, FALSE },\r
-  { "premove", ArgBoolean, (LPVOID) &appData.premove, TRUE },\r
-  { "pre", ArgTrue, (LPVOID) &appData.premove, FALSE },\r
-  { "xpre", ArgFalse, (LPVOID) &appData.premove, FALSE },\r
-  { "-pre", ArgFalse, (LPVOID) &appData.premove, FALSE },\r
-  { "premoveWhite", ArgBoolean, (LPVOID) &appData.premoveWhite, TRUE },\r
-  { "prewhite", ArgTrue, (LPVOID) &appData.premoveWhite, FALSE },\r
-  { "xprewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE },\r
-  { "-prewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE },\r
-  { "premoveWhiteText", ArgString, (LPVOID) &appData.premoveWhiteText, TRUE },\r
-  { "premoveBlack", ArgBoolean, (LPVOID) &appData.premoveBlack, TRUE },\r
-  { "preblack", ArgTrue, (LPVOID) &appData.premoveBlack, FALSE },\r
-  { "xpreblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE },\r
-  { "-preblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE },\r
-  { "premoveBlackText", ArgString, (LPVOID) &appData.premoveBlackText, TRUE },\r
-  { "icsAlarm", ArgBoolean, (LPVOID) &appData.icsAlarm, TRUE},\r
+    FALSE, (ArgIniType) TRUE }, /* historical; kept only so old winboard.ini files will parse */\r
+  { "bell", ArgTrue, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB\r
+  { "xbell", ArgFalse, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB\r
+  { "movesound", ArgTrue, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB\r
+  { "xmovesound", ArgFalse, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB\r
+  { "alwaysOnTop", ArgBoolean, (LPVOID) &alwaysOnTop, TRUE, INVALID },\r
+  { "top", ArgTrue, (LPVOID) &alwaysOnTop, FALSE, INVALID },\r
+  { "xtop", ArgFalse, (LPVOID) &alwaysOnTop, FALSE, INVALID },\r
+  { "-top", ArgFalse, (LPVOID) &alwaysOnTop, FALSE, INVALID },\r
+  { "autoCallFlag", ArgBoolean, (LPVOID) &appData.autoCallFlag, TRUE, (ArgIniType) FALSE },\r
+  { "autoflag", ArgTrue, (LPVOID) &appData.autoCallFlag, FALSE, INVALID },\r
+  { "xautoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE, INVALID },\r
+  { "-autoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE, INVALID },\r
+  { "autoComment", ArgBoolean, (LPVOID) &appData.autoComment, TRUE, (ArgIniType) FALSE },\r
+  { "autocomm", ArgTrue, (LPVOID) &appData.autoComment, FALSE, INVALID },\r
+  { "xautocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE, INVALID },\r
+  { "-autocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE, INVALID },\r
+  { "autoObserve", ArgBoolean, (LPVOID) &appData.autoObserve, TRUE, (ArgIniType) FALSE },\r
+  { "autobs", ArgTrue, (LPVOID) &appData.autoObserve, FALSE, INVALID },\r
+  { "xautobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE, INVALID },\r
+  { "-autobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE, INVALID },\r
+  { "flipView", ArgBoolean, (LPVOID) &appData.flipView, FALSE, (ArgIniType) FALSE },\r
+  { "flip", ArgTrue, (LPVOID) &appData.flipView, FALSE, INVALID },\r
+  { "xflip", ArgFalse, (LPVOID) &appData.flipView, FALSE, INVALID },\r
+  { "-flip", ArgFalse, (LPVOID) &appData.flipView, FALSE, INVALID },\r
+  { "autoFlipView", ArgBoolean, (LPVOID) &appData.autoFlipView, TRUE, (ArgIniType) TRUE },\r
+  { "autoflip", ArgTrue, (LPVOID) &appData.autoFlipView, FALSE, INVALID },\r
+  { "xautoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE, INVALID },\r
+  { "-autoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE, INVALID },\r
+  { "autoRaiseBoard", ArgBoolean, (LPVOID) &appData.autoRaiseBoard, TRUE, (ArgIniType) TRUE },\r
+  { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE, INVALID },\r
+  { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE, INVALID },\r
+  { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE, INVALID },\r
+  { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE, (ArgIniType) FALSE },\r
+  { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE, INVALID },\r
+  { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE, INVALID },\r
+  { "-queen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE, INVALID },\r
+  { "oldSaveStyle", ArgBoolean, (LPVOID) &appData.oldSaveStyle, TRUE, (ArgIniType) FALSE },\r
+  { "oldsave", ArgTrue, (LPVOID) &appData.oldSaveStyle, FALSE, INVALID },\r
+  { "xoldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE, INVALID },\r
+  { "-oldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE, INVALID },\r
+  { "quietPlay", ArgBoolean, (LPVOID) &appData.quietPlay, TRUE, (ArgIniType) FALSE },\r
+  { "quiet", ArgTrue, (LPVOID) &appData.quietPlay, FALSE, INVALID },\r
+  { "xquiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE, INVALID },\r
+  { "-quiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE, INVALID },\r
+  { "getMoveList", ArgBoolean, (LPVOID) &appData.getMoveList, TRUE, (ArgIniType) TRUE },\r
+  { "moves", ArgTrue, (LPVOID) &appData.getMoveList, FALSE, INVALID },\r
+  { "xmoves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE, INVALID },\r
+  { "-moves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE, INVALID },\r
+  { "testLegality", ArgBoolean, (LPVOID) &appData.testLegality, TRUE, (ArgIniType) TRUE },\r
+  { "legal", ArgTrue, (LPVOID) &appData.testLegality, FALSE, INVALID },\r
+  { "xlegal", ArgFalse, (LPVOID) &appData.testLegality, FALSE, INVALID },\r
+  { "-legal", ArgFalse, (LPVOID) &appData.testLegality, FALSE, INVALID },\r
+  { "premove", ArgBoolean, (LPVOID) &appData.premove, TRUE, (ArgIniType) TRUE },\r
+  { "pre", ArgTrue, (LPVOID) &appData.premove, FALSE, INVALID },\r
+  { "xpre", ArgFalse, (LPVOID) &appData.premove, FALSE, INVALID },\r
+  { "-pre", ArgFalse, (LPVOID) &appData.premove, FALSE, INVALID },\r
+  { "premoveWhite", ArgBoolean, (LPVOID) &appData.premoveWhite, TRUE, (ArgIniType) FALSE },\r
+  { "prewhite", ArgTrue, (LPVOID) &appData.premoveWhite, FALSE, INVALID },\r
+  { "xprewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE, INVALID },\r
+  { "-prewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE, INVALID },\r
+  { "premoveWhiteText", ArgString, (LPVOID) &appData.premoveWhiteText, TRUE, (ArgIniType) "" },\r
+  { "premoveBlack", ArgBoolean, (LPVOID) &appData.premoveBlack, TRUE, (ArgIniType) FALSE },\r
+  { "preblack", ArgTrue, (LPVOID) &appData.premoveBlack, FALSE, INVALID },\r
+  { "xpreblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE, INVALID },\r
+  { "-preblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE, INVALID },\r
+  { "premoveBlackText", ArgString, (LPVOID) &appData.premoveBlackText, TRUE, (ArgIniType) "" },\r
+  { "icsAlarm", ArgBoolean, (LPVOID) &appData.icsAlarm, TRUE, (ArgIniType) TRUE},\r
   { "alarm", ArgTrue, (LPVOID) &appData.icsAlarm, FALSE},\r
   { "xalarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE},\r
   { "-alarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE},\r
-  { "icsAlarmTime", ArgInt, (LPVOID) &appData.icsAlarmTime, TRUE},\r
-  { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE},\r
-  { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE},\r
-  { "edit", ArgTrue, (LPVOID) &appData.localLineEditing, FALSE },\r
-  { "xedit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE },\r
-  { "-edit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE },\r
-  { "animateMoving", ArgBoolean, (LPVOID) &appData.animate, TRUE },\r
-  { "animate", ArgTrue, (LPVOID) &appData.animate, FALSE },\r
-  { "xanimate", ArgFalse, (LPVOID) &appData.animate, FALSE },\r
-  { "-animate", ArgFalse, (LPVOID) &appData.animate, FALSE },\r
-  { "animateSpeed", ArgInt, (LPVOID) &appData.animSpeed, TRUE },\r
-  { "animateDragging", ArgBoolean, (LPVOID) &appData.animateDragging, TRUE },\r
-  { "drag", ArgTrue, (LPVOID) &appData.animateDragging, FALSE },\r
-  { "xdrag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE },\r
-  { "-drag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE },\r
-  { "blindfold", ArgBoolean, (LPVOID) &appData.blindfold, TRUE },\r
-  { "blind", ArgTrue, (LPVOID) &appData.blindfold, FALSE },\r
-  { "xblind", ArgFalse, (LPVOID) &appData.blindfold, FALSE },\r
-  { "-blind", ArgFalse, (LPVOID) &appData.blindfold, FALSE },\r
+  { "icsAlarmTime", ArgInt, (LPVOID) &appData.icsAlarmTime, TRUE, (ArgIniType) 5000},\r
+  { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE, (ArgIniType) TRUE},\r
+  { "edit", ArgTrue, (LPVOID) &appData.localLineEditing, FALSE, INVALID },\r
+  { "xedit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE, INVALID },\r
+  { "-edit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE, INVALID },\r
+  { "animateMoving", ArgBoolean, (LPVOID) &appData.animate, TRUE, (ArgIniType) TRUE },\r
+  { "animate", ArgTrue, (LPVOID) &appData.animate, FALSE, INVALID },\r
+  { "xanimate", ArgFalse, (LPVOID) &appData.animate, FALSE, INVALID },\r
+  { "-animate", ArgFalse, (LPVOID) &appData.animate, FALSE, INVALID },\r
+  { "animateSpeed", ArgInt, (LPVOID) &appData.animSpeed, TRUE, (ArgIniType) 10 },\r
+  { "animateDragging", ArgBoolean, (LPVOID) &appData.animateDragging, TRUE, (ArgIniType) TRUE },\r
+  { "drag", ArgTrue, (LPVOID) &appData.animateDragging, FALSE, INVALID },\r
+  { "xdrag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE, INVALID },\r
+  { "-drag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE, INVALID },\r
+  { "blindfold", ArgBoolean, (LPVOID) &appData.blindfold, TRUE, (ArgIniType) FALSE },\r
+  { "blind", ArgTrue, (LPVOID) &appData.blindfold, FALSE, INVALID },\r
+  { "xblind", ArgFalse, (LPVOID) &appData.blindfold, FALSE, INVALID },\r
+  { "-blind", ArgFalse, (LPVOID) &appData.blindfold, FALSE, INVALID },\r
   { "highlightLastMove", ArgBoolean,\r
-    (LPVOID) &appData.highlightLastMove, TRUE },\r
-  { "highlight", ArgTrue, (LPVOID) &appData.highlightLastMove, FALSE },\r
-  { "xhighlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE },\r
-  { "-highlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE },\r
+    (LPVOID) &appData.highlightLastMove, TRUE, (ArgIniType) TRUE },\r
+  { "highlight", ArgTrue, (LPVOID) &appData.highlightLastMove, FALSE, INVALID },\r
+  { "xhighlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE, INVALID },\r
+  { "-highlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE, INVALID },\r
   { "highlightDragging", ArgBoolean,\r
-    (LPVOID) &appData.highlightDragging, TRUE },\r
-  { "highdrag", ArgTrue, (LPVOID) &appData.highlightDragging, FALSE },\r
-  { "xhighdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE },\r
-  { "-highdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE },\r
-  { "colorizeMessages", ArgBoolean, (LPVOID) &appData.colorize, TRUE },\r
-  { "colorize", ArgTrue, (LPVOID) &appData.colorize, FALSE },\r
-  { "xcolorize", ArgFalse, (LPVOID) &appData.colorize, FALSE },\r
-  { "-colorize", ArgFalse, (LPVOID) &appData.colorize, FALSE },\r
-  { "colorShout", ArgAttribs, (LPVOID) ColorShout, TRUE },\r
-  { "colorSShout", ArgAttribs, (LPVOID) ColorSShout, TRUE },\r
-  { "colorChannel1", ArgAttribs, (LPVOID) ColorChannel1, TRUE },\r
-  { "colorChannel", ArgAttribs, (LPVOID) ColorChannel, TRUE },\r
-  { "colorKibitz", ArgAttribs, (LPVOID) ColorKibitz, TRUE },\r
-  { "colorTell", ArgAttribs, (LPVOID) ColorTell, TRUE },\r
-  { "colorChallenge", ArgAttribs, (LPVOID) ColorChallenge, TRUE },\r
-  { "colorRequest", ArgAttribs, (LPVOID) ColorRequest, TRUE },\r
-  { "colorSeek", ArgAttribs, (LPVOID) ColorSeek, TRUE },\r
-  { "colorNormal", ArgAttribs, (LPVOID) ColorNormal, TRUE },\r
-  { "colorBackground", ArgColor, (LPVOID) &consoleBackgroundColor, TRUE },\r
-  { "soundShout", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorShout].sound.name, TRUE },\r
-  { "soundSShout", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorSShout].sound.name, TRUE },\r
-  { "soundChannel1", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorChannel1].sound.name, TRUE },\r
-  { "soundChannel", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorChannel].sound.name, TRUE },\r
-  { "soundKibitz", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorKibitz].sound.name, TRUE },\r
-  { "soundTell", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorTell].sound.name, TRUE },\r
-  { "soundChallenge", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorChallenge].sound.name, TRUE },\r
-  { "soundRequest", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorRequest].sound.name, TRUE },\r
-  { "soundSeek", ArgFilename,\r
-    (LPVOID) &textAttribs[ColorSeek].sound.name, TRUE },\r
-  { "soundMove", ArgFilename, (LPVOID) &sounds[(int)SoundMove].name, TRUE },\r
-  { "soundBell", ArgFilename, (LPVOID) &sounds[(int)SoundBell].name, TRUE },\r
-  { "soundIcsWin", ArgFilename, (LPVOID) &sounds[(int)SoundIcsWin].name,TRUE },\r
-  { "soundIcsLoss", ArgFilename, \r
-    (LPVOID) &sounds[(int)SoundIcsLoss].name, TRUE },\r
-  { "soundIcsDraw", ArgFilename, \r
-    (LPVOID) &sounds[(int)SoundIcsDraw].name, TRUE },\r
-  { "soundIcsUnfinished", ArgFilename, \r
-    (LPVOID) &sounds[(int)SoundIcsUnfinished].name, TRUE},\r
-  { "soundIcsAlarm", ArgFilename, \r
-    (LPVOID) &sounds[(int)SoundAlarm].name, TRUE },\r
-  { "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "xreuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE },\r
-  { "-reuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE },\r
+    (LPVOID) &appData.highlightDragging, TRUE, INVALID },\r
+  { "highdrag", ArgTrue, (LPVOID) &appData.highlightDragging, FALSE, INVALID },\r
+  { "xhighdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE, INVALID },\r
+  { "-highdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE, INVALID },\r
+  { "colorizeMessages", ArgBoolean, (LPVOID) &appData.colorize, TRUE, (ArgIniType) TRUE },\r
+  { "colorize", ArgTrue, (LPVOID) &appData.colorize, FALSE, INVALID },\r
+  { "xcolorize", ArgFalse, (LPVOID) &appData.colorize, FALSE, INVALID },\r
+  { "-colorize", ArgFalse, (LPVOID) &appData.colorize, FALSE, INVALID },\r
+  { "colorShout", ArgAttribs, (LPVOID) ColorShout, TRUE, INVALID },\r
+  { "colorSShout", ArgAttribs, (LPVOID) ColorSShout, TRUE, INVALID },\r
+  { "colorChannel1", ArgAttribs, (LPVOID) ColorChannel1, TRUE, INVALID },\r
+  { "colorChannel", ArgAttribs, (LPVOID) ColorChannel, TRUE, INVALID },\r
+  { "colorKibitz", ArgAttribs, (LPVOID) ColorKibitz, TRUE, INVALID },\r
+  { "colorTell", ArgAttribs, (LPVOID) ColorTell, TRUE, INVALID },\r
+  { "colorChallenge", ArgAttribs, (LPVOID) ColorChallenge, TRUE, INVALID },\r
+  { "colorRequest", ArgAttribs, (LPVOID) ColorRequest, TRUE, INVALID },\r
+  { "colorSeek", ArgAttribs, (LPVOID) ColorSeek, TRUE, INVALID },\r
+  { "colorNormal", ArgAttribs, (LPVOID) ColorNormal, TRUE, INVALID },\r
+  { "colorBackground", ArgColor, (LPVOID) &consoleBackgroundColor, TRUE, INVALID },\r
+  { "soundShout", ArgFilename, (LPVOID) &appData.soundShout, TRUE, (ArgIniType) "" },\r
+  { "soundSShout", ArgFilename, (LPVOID) &appData.soundSShout, TRUE, (ArgIniType) "" },\r
+  { "soundCShout", ArgFilename, (LPVOID) &appData.soundSShout, TRUE, (ArgIniType) "" }, // for XB\r
+  { "soundChannel1", ArgFilename, (LPVOID) &appData.soundChannel1, TRUE, (ArgIniType) "" },\r
+  { "soundChannel", ArgFilename, (LPVOID) &appData.soundChannel, TRUE, (ArgIniType) "" },\r
+  { "soundKibitz", ArgFilename, (LPVOID) &appData.soundKibitz, TRUE, (ArgIniType) "" },\r
+  { "soundTell", ArgFilename, (LPVOID) &appData.soundTell, TRUE, (ArgIniType) "" },\r
+  { "soundChallenge", ArgFilename, (LPVOID) &appData.soundChallenge, TRUE, (ArgIniType) "" },\r
+  { "soundRequest", ArgFilename, (LPVOID) &appData.soundRequest, TRUE, (ArgIniType) "" },\r
+  { "soundSeek", ArgFilename, (LPVOID) &appData.soundSeek, TRUE, (ArgIniType) "" },\r
+  { "soundMove", ArgFilename, (LPVOID) &appData.soundMove, TRUE, (ArgIniType) "" },\r
+  { "soundBell", ArgFilename, (LPVOID) &appData.soundBell, TRUE, (ArgIniType) SOUND_BELL },\r
+  { "soundIcsWin", ArgFilename, (LPVOID) &appData.soundIcsWin, TRUE, (ArgIniType) "" },\r
+  { "soundIcsLoss", ArgFilename, (LPVOID) &appData.soundIcsLoss, TRUE, (ArgIniType) "" },\r
+  { "soundIcsDraw", ArgFilename, (LPVOID) &appData.soundIcsDraw, TRUE, (ArgIniType) "" },\r
+  { "soundIcsUnfinished", ArgFilename, (LPVOID) &appData.soundIcsUnfinished, TRUE, (ArgIniType) "" },\r
+  { "soundIcsAlarm", ArgFilename, (LPVOID) &appData.soundIcsAlarm, TRUE, (ArgIniType) "" },\r
+  { "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE, (ArgIniType) TRUE },\r
+  { "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE, INVALID },\r
+  { "xreuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE, INVALID },\r
+  { "-reuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE, INVALID },\r
   { "reuseChessPrograms", ArgBoolean,\r
-    (LPVOID) &appData.reuseFirst, FALSE }, /* backward compat only */\r
-  { "reuseSecond", ArgBoolean, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "reuse2", ArgTrue, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
-  { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE },\r
-  { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
-  { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
-  { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE },\r
-  { "chessProgram", ArgBoolean, (LPVOID) &chessProgram, FALSE },\r
-  { "cp", ArgTrue, (LPVOID) &chessProgram, FALSE },\r
-  { "xcp", ArgFalse, (LPVOID) &chessProgram, FALSE },\r
-  { "-cp", ArgFalse, (LPVOID) &chessProgram, FALSE },\r
-  { "icsMenu", ArgString, (LPVOID) &icsTextMenuString, TRUE },\r
-  { "icsNames", ArgString, (LPVOID) &icsNames, TRUE },\r
+    (LPVOID) &appData.reuseFirst, FALSE, INVALID }, /* backward compat only */\r
+  { "reuseSecond", ArgBoolean, (LPVOID) &appData.reuseSecond, FALSE, (ArgIniType) TRUE },\r
+  { "reuse2", ArgTrue, (LPVOID) &appData.reuseSecond, FALSE, INVALID },\r
+  { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE, INVALID },\r
+  { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE, INVALID },\r
+  { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE, INVALID },\r
+  { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE, (ArgIniType) SETTINGS_FILE },\r
+  { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE, INVALID },\r
+  { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE, (ArgIniType) TRUE },\r
+  { "chessProgram", ArgBoolean, (LPVOID) &chessProgram, FALSE, (ArgIniType) FALSE },\r
+  { "cp", ArgTrue, (LPVOID) &chessProgram, FALSE, INVALID },\r
+  { "xcp", ArgFalse, (LPVOID) &chessProgram, FALSE, INVALID },\r
+  { "-cp", ArgFalse, (LPVOID) &chessProgram, FALSE, INVALID },\r
+  { "icsMenu", ArgString, (LPVOID) &icsTextMenuString, TRUE, (ArgIniType) ICS_TEXT_MENU_DEFAULT },\r
+  { "icsNames", ArgString, (LPVOID) &icsNames, TRUE, (ArgIniType) ICS_NAMES },\r
   { "firstChessProgramNames", ArgString, (LPVOID) &firstChessProgramNames,\r
-    TRUE },\r
+    TRUE, (ArgIniType) FCP_NAMES },\r
   { "secondChessProgramNames", ArgString, (LPVOID) &secondChessProgramNames,\r
-    TRUE },\r
-  { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
-  { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
-  { "variant", ArgString, (LPVOID) &appData.variant, FALSE },\r
-  { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE },\r
-  { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE },\r
-  { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE },\r
-  { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE },\r
-  { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
-  { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
+    TRUE, (ArgIniType) SCP_NAMES },\r
+  { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE, (ArgIniType) "" },\r
+  { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE, INVALID },\r
+  { "variant", ArgString, (LPVOID) &appData.variant, FALSE, (ArgIniType) "normal" },\r
+  { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE, (ArgIniType) PROTOVER },\r
+  { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE, (ArgIniType) PROTOVER },\r
+  { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE, (ArgIniType) TRUE },\r
+  { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE, INVALID },\r
+  { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE, INVALID },\r
+  { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE, INVALID },\r
+\r
   /* [AS] New features */\r
-  { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE },\r
-  { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE },\r
-  { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE },\r
-  { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE },\r
-  { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE },\r
-  { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE },\r
-  { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE },\r
-  { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE },\r
-  { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE },\r
-  { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE },\r
-  { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE },\r
-  { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE },\r
-  { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE },\r
-  { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE },\r
-  { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE },\r
-  { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE },\r
-  { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE },\r
-  { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE },\r
-  { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE },\r
-  { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
-  { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
-  { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE },\r
-  { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE },\r
-  { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE },\r
-  { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE },\r
-  { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE },\r
-  { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE },\r
-  { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE },\r
-  { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE },\r
-  { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE },\r
-  { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE },\r
-  { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE },\r
-  { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE },\r
-  { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE },\r
-  { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE },\r
-  { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE },\r
-  { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE },\r
-  { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE },\r
-  { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
-  { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
-  { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
-  { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
-  { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
-  { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
-  { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE },\r
-  { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE },\r
-  { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE },\r
-  { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE }, \r
-  { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE },\r
-  { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE },\r
+  { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE, (ArgIniType) FALSE },\r
+  { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE, (ArgIniType) FALSE },\r
+  { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE, (ArgIniType) FALSE },\r
+  { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE, (ArgIniType) FALSE },\r
+  { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE, (ArgIniType) "" },\r
+  { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE, (ArgIniType) "" },\r
+  { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE, (ArgIniType) BACK_TEXTURE_MODE_PLAIN },\r
+  { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE, (ArgIniType) BACK_TEXTURE_MODE_PLAIN },\r
+  { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE, (ArgIniType) "" },\r
+  { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE, (ArgIniType) "" },\r
+  { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE, (ArgIniType) 0 },\r
+  { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE, (ArgIniType) 0 },\r
+  { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE, (ArgIniType) 0 },\r
+  { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE, (ArgIniType) 0 },\r
+  { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE, (ArgIniType) 80 },\r
+  { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE, (ArgIniType) 1 },\r
+  { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE, (ArgIniType) 0 },\r
+  { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE, (ArgIniType) 0 },\r
+  { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE, (ArgIniType) 0 },\r
+  { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE, (ArgIniType) "winboard.debug" },\r
+  { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE, INVALID },\r
+  { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE, (ArgIniType) "Computer Chess Game" },\r
+  { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE, (ArgIniType) -1 },\r
+  { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE, (ArgIniType) GLT_DEFAULT_TAGS },\r
+  { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE, (ArgIniType) TRUE },\r
+  { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE, (ArgIniType) TRUE },\r
+  { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE, INVALID },\r
+  { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE, INVALID },\r
+  { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE, (ArgIniType) FALSE },\r
+  { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE, INVALID },\r
+  { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE, (ArgIniType) TRUE },\r
+  { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE, (ArgIniType) TRUE },\r
+  { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE, (ArgIniType) TRUE },\r
+  { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE, (ArgIniType) TRUE },\r
+  { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE, (ArgIniType) FALSE },\r
+  { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE, INVALID },\r
+  { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE, (ArgIniType) FALSE },\r
+  { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE, INVALID },\r
+  { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE, (ArgIniType) TRUE },\r
+  { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE, INVALID },\r
+  { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE, INVALID },\r
+  { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE, (ArgIniType) TRUE },\r
+  { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE, INVALID },\r
+  { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE, INVALID },\r
+  { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE, (ArgIniType) "" },\r
+  { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE, (ArgIniType) FALSE },\r
+  { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE, (ArgIniType) "" },\r
+  { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE, (ArgIniType) 64 }, \r
+  { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE, (ArgIniType) 4 },\r
+  { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE, (ArgIniType) "c:\\egtb" },\r
 \r
   /* [HGM] board-size, adjudication and misc. options */\r
-  { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE },\r
-  { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE },\r
-  { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE },\r
-  { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE },\r
-  { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE },\r
-  { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE },\r
-  { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE },\r
-  { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE },\r
-  { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE },\r
-  { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE },\r
-  { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE },\r
-  { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE },\r
-  { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE },\r
-  { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE },\r
-  { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE },\r
-  { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE },\r
-  { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE },\r
-  { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE },\r
-  { "userName", ArgString, (LPVOID) &appData.userName, FALSE },\r
-  { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE },\r
-  { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE },\r
-  { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE },\r
-  { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE },\r
-  { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE },\r
-  { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE },\r
-  { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE },\r
-  { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE },\r
-  { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE },\r
-  { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE },\r
-  { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE },\r
-  { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE },\r
-  { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE },\r
-  { "icstype", ArgInt, (LPVOID) &ics_type, FALSE },\r
-  { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE },\r
+  { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE, (ArgIniType) -1 },\r
+  { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE, (ArgIniType) -1 },\r
+  { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE, (ArgIniType) -1 },\r
+  { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE, (ArgIniType) 10000 },\r
+  { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE, INVALID },\r
+  { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE, (ArgIniType) FALSE },\r
+  { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE, (ArgIniType) FALSE },\r
+  { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE, (ArgIniType) FALSE },\r
+  { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE, (ArgIniType) FALSE },\r
+  { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE, (ArgIniType) FALSE },\r
+  { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE, (ArgIniType) FALSE },\r
+  { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE, (ArgIniType) FALSE },\r
+  { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE, (ArgIniType) FALSE },\r
+  { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE, (ArgIniType) FALSE },\r
+  { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE, (ArgIniType) 51 },\r
+  { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE, (ArgIniType) 6 },\r
+  { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE, INVALID },\r
+  { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE, (ArgIniType) 1 },\r
+  { "userName", ArgString, (LPVOID) &appData.userName, FALSE, INVALID },\r
+  { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE, INVALID },\r
+  { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE, INVALID },\r
+  { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE, (ArgIniType) 1 },\r
+  { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE, (ArgIniType) "" },\r
+  { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE, INVALID },\r
+  { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE, INVALID },\r
+  { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE, INVALID },\r
+  { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE, INVALID },\r
+  { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE, (ArgIniType) "" },\r
+  { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE, (ArgIniType) "" },\r
+  { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE, (ArgIniType) "" },\r
+  { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE, (ArgIniType) "" },\r
+  { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE, INVALID },\r
+  { "icstype", ArgInt, (LPVOID) &ics_type, FALSE, INVALID },\r
+  { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE, INVALID },\r
 \r
 #ifdef ZIPPY\r
-  { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "xzt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "-zt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE },\r
-  { "zippyPlay", ArgBoolean, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "zp", ArgTrue, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "xzp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "-zp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE },\r
-  { "zippyLines", ArgFilename, (LPVOID) &appData.zippyLines, FALSE },\r
-  { "zippyPinhead", ArgString, (LPVOID) &appData.zippyPinhead, FALSE },\r
-  { "zippyPassword", ArgString, (LPVOID) &appData.zippyPassword, FALSE },\r
-  { "zippyPassword2", ArgString, (LPVOID) &appData.zippyPassword2, FALSE },\r
+  { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE, (ArgIniType) ZIPPY_TALK },\r
+  { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE, INVALID },\r
+  { "xzt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE, INVALID },\r
+  { "-zt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE, INVALID },\r
+  { "zippyPlay", ArgBoolean, (LPVOID) &appData.zippyPlay, FALSE, (ArgIniType) ZIPPY_PLAY },\r
+  { "zp", ArgTrue, (LPVOID) &appData.zippyPlay, FALSE, INVALID },\r
+  { "xzp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE, INVALID },\r
+  { "-zp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE, INVALID },\r
+  { "zippyLines", ArgFilename, (LPVOID) &appData.zippyLines, FALSE, (ArgIniType) ZIPPY_LINES },\r
+  { "zippyPinhead", ArgString, (LPVOID) &appData.zippyPinhead, FALSE, (ArgIniType) ZIPPY_PINHEAD },\r
+  { "zippyPassword", ArgString, (LPVOID) &appData.zippyPassword, FALSE, (ArgIniType) ZIPPY_PASSWORD },\r
+  { "zippyPassword2", ArgString, (LPVOID) &appData.zippyPassword2, FALSE, (ArgIniType) ZIPPY_PASSWORD2 },\r
   { "zippyWrongPassword", ArgString, (LPVOID) &appData.zippyWrongPassword,\r
-    FALSE },\r
-  { "zippyAcceptOnly", ArgString, (LPVOID) &appData.zippyAcceptOnly, FALSE },\r
-  { "zippyUseI", ArgBoolean, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "zui", ArgTrue, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "xzui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "-zui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE },\r
-  { "zippyBughouse", ArgInt, (LPVOID) &appData.zippyBughouse, FALSE },\r
+    FALSE, (ArgIniType) ZIPPY_WRONG_PASSWORD },\r
+  { "zippyAcceptOnly", ArgString, (LPVOID) &appData.zippyAcceptOnly, FALSE, (ArgIniType) ZIPPY_ACCEPT_ONLY },\r
+  { "zippyUseI", ArgBoolean, (LPVOID) &appData.zippyUseI, FALSE, (ArgIniType) ZIPPY_USE_I },\r
+  { "zui", ArgTrue, (LPVOID) &appData.zippyUseI, FALSE, INVALID },\r
+  { "xzui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE, INVALID },\r
+  { "-zui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE, INVALID },\r
+  { "zippyBughouse", ArgInt, (LPVOID) &appData.zippyBughouse, FALSE, (ArgIniType) ZIPPY_BUGHOUSE },\r
   { "zippyNoplayCrafty", ArgBoolean, (LPVOID) &appData.zippyNoplayCrafty,\r
-    FALSE },\r
-  { "znc", ArgTrue, (LPVOID) &appData.zippyNoplayCrafty, FALSE },\r
-  { "xznc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE },\r
-  { "-znc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE },\r
-  { "zippyGameEnd", ArgString, (LPVOID) &appData.zippyGameEnd, FALSE },\r
-  { "zippyGameStart", ArgString, (LPVOID) &appData.zippyGameStart, FALSE },\r
-  { "zippyAdjourn", ArgBoolean, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "zadj", ArgTrue, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "xzadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "-zadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE },\r
-  { "zippyAbort", ArgBoolean, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "zab", ArgTrue, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "xzab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "-zab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE },\r
-  { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE },\r
-  { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE },\r
-  { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE },\r
-  { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE },\r
+    FALSE, (ArgIniType) ZIPPY_NOPLAY_CRAFTY },\r
+  { "znc", ArgTrue, (LPVOID) &appData.zippyNoplayCrafty, FALSE, INVALID },\r
+  { "xznc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE, INVALID },\r
+  { "-znc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE, INVALID },\r
+  { "zippyGameEnd", ArgString, (LPVOID) &appData.zippyGameEnd, FALSE, (ArgIniType) ZIPPY_GAME_END },\r
+  { "zippyGameStart", ArgString, (LPVOID) &appData.zippyGameStart, FALSE, (ArgIniType) ZIPPY_GAME_START },\r
+  { "zippyAdjourn", ArgBoolean, (LPVOID) &appData.zippyAdjourn, FALSE, (ArgIniType) ZIPPY_ADJOURN },\r
+  { "zadj", ArgTrue, (LPVOID) &appData.zippyAdjourn, FALSE, INVALID },\r
+  { "xzadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE, INVALID },\r
+  { "-zadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE, INVALID },\r
+  { "zippyAbort", ArgBoolean, (LPVOID) &appData.zippyAbort, FALSE, (ArgIniType) ZIPPY_ABORT },\r
+  { "zab", ArgTrue, (LPVOID) &appData.zippyAbort, FALSE, INVALID },\r
+  { "xzab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE, INVALID },\r
+  { "-zab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE, INVALID },\r
+  { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE, (ArgIniType) ZIPPY_VARIANTS },\r
+  { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE, (ArgIniType) ZIPPY_MAX_GAMES},\r
+  { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE, (ArgIniType) ZIPPY_REPLAY_TIMEOUT },\r
+  { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE, INVALID },\r
   /* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */\r
-  { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE },\r
+  { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE, INVALID },\r
 #endif\r
   /* [HGM] options for broadcasting and time odds */\r
-  { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE },\r
-  { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE },\r
-  { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE },\r
-  { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE },\r
-  { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE },\r
-  { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE },\r
-  { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE },\r
-  { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE },\r
-  { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE },\r
-  { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE },\r
-  { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE },\r
-  { "keepLineBreaksICS", ArgBoolean, (LPVOID) &appData.noJoin, TRUE },\r
-  { "wrapContinuationSequence", ArgString, (LPVOID) &appData.wrapContSeq, FALSE },\r
-  { "useInternalWrap", ArgTrue, (LPVOID) &appData.useInternalWrap, FALSE }, /* noJoin usurps this if set */\r
+  { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE, (ArgIniType) NULL },\r
+  { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE, (ArgIniType) FALSE },\r
+  { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE, (ArgIniType) 15 },\r
+  { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE, (ArgIniType) 1 },\r
+  { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE, (ArgIniType) 1 },\r
+  { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE, INVALID },\r
+  { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE, (ArgIniType) 1 },\r
+  { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE, (ArgIniType) 1 },\r
+  { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE, (ArgIniType) -1 },\r
+  { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE, (ArgIniType) -1 },\r
+  { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE, INVALID },\r
+  { "keepLineBreaksICS", ArgBoolean, (LPVOID) &appData.noJoin, TRUE, INVALID },\r
+  { "wrapContinuationSequence", ArgString, (LPVOID) &appData.wrapContSeq, FALSE, INVALID },\r
+  { "useInternalWrap", ArgTrue, (LPVOID) &appData.useInternalWrap, FALSE, INVALID }, /* noJoin usurps this if set */\r
   \r
   // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others\r
-  { "minX", ArgZ, (LPVOID) &minX, FALSE }, // [HGM] placement: to make suer auxialary windows can be placed\r
-  { "minY", ArgZ, (LPVOID) &minY, FALSE },\r
-  { "winWidth",  ArgInt, (LPVOID) &winWidth,  TRUE }, // [HGM] placement: dummies to remember right & bottom\r
-  { "winHeight", ArgInt, (LPVOID) &winHeight, TRUE }, //       for attaching auxiliary windows to them\r
-  { "x", ArgInt, (LPVOID) &boardX, TRUE },\r
-  { "y", ArgInt, (LPVOID) &boardY, TRUE },\r
-  { "icsX", ArgX,   (LPVOID) &wpConsole.x, TRUE },\r
-  { "icsY", ArgY,   (LPVOID) &wpConsole.y, TRUE },\r
-  { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE },\r
-  { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE },\r
-  { "analysisX", ArgX,   (LPVOID) &analysisX, FALSE }, // [HGM] placement: analysis window no longer exists\r
-  { "analysisY", ArgY,   (LPVOID) &analysisY, FALSE }, //       provided for compatibility with old ini files\r
-  { "analysisW", ArgInt, (LPVOID) &analysisW, FALSE },\r
-  { "analysisH", ArgInt, (LPVOID) &analysisH, FALSE },\r
-  { "commentX", ArgX,   (LPVOID) &commentX, TRUE },\r
-  { "commentY", ArgY,   (LPVOID) &commentY, TRUE },\r
-  { "commentW", ArgInt, (LPVOID) &commentW, TRUE },\r
-  { "commentH", ArgInt, (LPVOID) &commentH, TRUE },\r
-  { "tagsX", ArgX,   (LPVOID) &editTagsX, TRUE },\r
-  { "tagsY", ArgY,   (LPVOID) &editTagsY, TRUE },\r
-  { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE },\r
-  { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE },\r
-  { "gameListX", ArgX,   (LPVOID) &wpGameList.x, TRUE },\r
-  { "gameListY", ArgY,   (LPVOID) &wpGameList.y, TRUE },\r
-  { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE },\r
-  { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE },\r
+  { "minX", ArgZ, (LPVOID) &minX, FALSE, INVALID }, // [HGM] placement: to make suer auxialary windows can be placed\r
+  { "minY", ArgZ, (LPVOID) &minY, FALSE, INVALID },\r
+  { "winWidth",  ArgInt, (LPVOID) &wpMain.width,  TRUE, INVALID }, // [HGM] placement: dummies to remember right & bottom\r
+  { "winHeight", ArgInt, (LPVOID) &wpMain.height, TRUE, INVALID }, //       for attaching auxiliary windows to them\r
+  { "x", ArgInt, (LPVOID) &wpMain.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "y", ArgInt, (LPVOID) &wpMain.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "icsX", ArgX,   (LPVOID) &wpConsole.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "icsY", ArgY,   (LPVOID) &wpConsole.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "analysisX", ArgX,   (LPVOID) &dummy, FALSE, INVALID }, // [HGM] placement: analysis window no longer exists\r
+  { "analysisY", ArgY,   (LPVOID) &dummy, FALSE, INVALID }, //       provided for compatibility with old ini files\r
+  { "analysisW", ArgInt, (LPVOID) &dummy, FALSE, INVALID },\r
+  { "analysisH", ArgInt, (LPVOID) &dummy, FALSE, INVALID },\r
+  { "commentX", ArgX,   (LPVOID) &wpComment.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "commentY", ArgY,   (LPVOID) &wpComment.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "commentW", ArgInt, (LPVOID) &wpComment.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "commentH", ArgInt, (LPVOID) &wpComment.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "tagsX", ArgX,   (LPVOID) &wpTags.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "tagsY", ArgY,   (LPVOID) &wpTags.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "tagsW", ArgInt, (LPVOID) &wpTags.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "tagsH", ArgInt, (LPVOID) &wpTags.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "gameListX", ArgX,   (LPVOID) &wpGameList.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "gameListY", ArgY,   (LPVOID) &wpGameList.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
   /* [AS] Layout stuff */\r
-  { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE },\r
-  { "moveHistoryX", ArgX,   (LPVOID) &wpMoveHistory.x, TRUE },\r
-  { "moveHistoryY", ArgY,   (LPVOID) &wpMoveHistory.y, TRUE },\r
-  { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE },\r
-  { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE },\r
-\r
-  { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE },\r
-  { "evalGraphX", ArgX,   (LPVOID) &wpEvalGraph.x, TRUE },\r
-  { "evalGraphY", ArgY,   (LPVOID) &wpEvalGraph.y, TRUE },\r
-  { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE },\r
-  { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE },\r
-\r
-  { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE },\r
-  { "engineOutputX", ArgX,   (LPVOID) &wpEngineOutput.x, TRUE },\r
-  { "engineOutputY", ArgY,   (LPVOID) &wpEngineOutput.y, TRUE },\r
-  { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE },\r
-  { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE },\r
-\r
-  { NULL, ArgNone, NULL, FALSE }\r
+  { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE, (ArgIniType) TRUE },\r
+  { "moveHistoryX", ArgX,   (LPVOID) &wpMoveHistory.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "moveHistoryY", ArgY,   (LPVOID) &wpMoveHistory.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+\r
+  { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE, (ArgIniType) TRUE },\r
+  { "evalGraphX", ArgX,   (LPVOID) &wpEvalGraph.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "evalGraphY", ArgY,   (LPVOID) &wpEvalGraph.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+\r
+  { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE, (ArgIniType) TRUE },\r
+  { "engineOutputX", ArgX,   (LPVOID) &wpEngineOutput.x, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "engineOutputY", ArgY,   (LPVOID) &wpEngineOutput.y, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+  { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE, (ArgIniType) CW_USEDEFAULT },\r
+\r
+  { NULL, ArgNone, NULL, FALSE, INVALID }\r
 };\r
 \r
 \r
@@ -1777,16 +1779,16 @@ ParseArgs(GetFunc get, void *cl)
       break;\r
 \r
     case ArgX:\r
-      *(int *) ad->argLoc = atoi(argValue) + boardX; // [HGM] placement: translate stored relative to absolute \r
+      *(int *) ad->argLoc = atoi(argValue) + wpMain.x; // [HGM] placement: translate stored relative to absolute \r
       break;\r
 \r
     case ArgY:\r
-      *(int *) ad->argLoc = atoi(argValue) + boardY; // (this is really kludgey, it should be done where used...)\r
+      *(int *) ad->argLoc = atoi(argValue) + wpMain.y; // (this is really kludgey, it should be done where used...)\r
       break;\r
 \r
     case ArgZ:\r
       *(int *) ad->argLoc = atoi(argValue);\r
-      EnsureOnScreen(&boardX, &boardY, minX, minY); \r
+      EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY); \r
       break;\r
 \r
     case ArgFloat:\r
@@ -1903,33 +1905,64 @@ SetDefaultTextAttribs()
 \r
 VOID\r
 SetDefaultSounds()\r
-{\r
+{ // [HGM] only sounds for which no option exists\r
   ColorClass cc;\r
-  SoundClass sc;\r
-  for (cc = (ColorClass)0; cc < NColorClasses; cc++) {\r
+  for (cc = ColorNormal; cc < NColorClasses; cc++) {\r
     textAttribs[cc].sound.name = strdup("");\r
     textAttribs[cc].sound.data = NULL;\r
   }\r
-  for (sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
-    sounds[sc].name = strdup("");\r
-    sounds[sc].data = NULL;\r
-  }\r
-  sounds[(int)SoundBell].name = strdup(SOUND_BELL);\r
 }\r
 \r
 VOID\r
 LoadAllSounds()\r
-{\r
+{ // [HGM] import name from appData first\r
   ColorClass cc;\r
   SoundClass sc;\r
-  for (cc = (ColorClass)0; cc < NColorClasses; cc++) {\r
+  for (cc = (ColorClass)0; cc < ColorNormal; cc++) {\r
+    textAttribs[cc].sound.name = strdup((&appData.soundShout)[cc]);\r
+    textAttribs[cc].sound.data = NULL;\r
     MyLoadSound(&textAttribs[cc].sound);\r
   }\r
   for (sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
+    sounds[sc].name = strdup((&appData.soundMove)[sc]);\r
+    sounds[sc].data = NULL;\r
     MyLoadSound(&sounds[sc]);\r
   }\r
 }\r
 \r
+void\r
+SetDefaultsFromList()\r
+{ // [HGM] ini: take defaults from argDescriptor list\r
+  int i;\r
+\r
+  for(i=0; argDescriptors[i].argName != NULL; i++) {\r
+    if(argDescriptors[i].defaultValue != INVALID)\r
+      switch(argDescriptors[i].argType) {\r
+        case ArgBoolean:\r
+        case ArgTrue:\r
+        case ArgFalse:\r
+          *(Boolean *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue;\r
+          break;\r
+        case ArgInt:\r
+        case ArgX:\r
+        case ArgY:\r
+        case ArgZ:\r
+          *(int *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue;\r
+          break;\r
+        case ArgString:\r
+        case ArgFilename:\r
+        case ArgSettingsFilename:\r
+          *(char **) argDescriptors[i].argLoc = (char *)argDescriptors[i].defaultValue;\r
+          break;\r
+        case ArgBoardSize:\r
+          *(BoardSize *) argDescriptors[i].argLoc = (BoardSize)argDescriptors[i].defaultValue;\r
+          break;\r
+        case ArgFloat: // floats cannot be casted to int without precision loss\r
+        default: ; // some arg types cannot be initialized through table\r
+    }\r
+  }\r
+}\r
+\r
 VOID\r
 InitAppData(LPSTR lpCmdLine)\r
 {\r
@@ -1940,6 +1973,18 @@ InitAppData(LPSTR lpCmdLine)
   programName = szAppName;\r
 \r
   /* Initialize to defaults */\r
+  SetDefaultsFromList(); // this sets most defaults\r
+\r
+  // some parameters for which there are no options!\r
+  appData.Iconic = FALSE; /*unused*/\r
+  appData.cmailGameName = "";\r
+  appData.icsEngineAnalyze = FALSE;\r
+\r
+  // float: casting to int is not harmless, so default cannot be contained in table\r
+  appData.timeDelay = TIME_DELAY;\r
+\r
+  // colors have platform-dependent option format and internal representation\r
+  // their setting and parsing must remain in front-end\r
   lightSquareColor = ParseColorName(LIGHT_SQUARE_COLOR);\r
   darkSquareColor = ParseColorName(DARK_SQUARE_COLOR);\r
   whitePieceColor = ParseColorName(WHITE_PIECE_COLOR);\r
@@ -1947,89 +1992,15 @@ InitAppData(LPSTR lpCmdLine)
   highlightSquareColor = ParseColorName(HIGHLIGHT_SQUARE_COLOR);\r
   premoveHighlightColor = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);\r
   consoleBackgroundColor = ParseColorName(COLOR_BKGD);\r
+  // the following must be moved out of appData to front-end variables\r
+  appData.evalHistColorWhite = ParseColorName( "#FFFFB0" );\r
+  appData.evalHistColorBlack = ParseColorName( "#AD5D3D" );\r
+  appData.highlightArrowColor = ParseColorName( "#FFFF80" );\r
+\r
+  // some complex, platform-dependent stuff\r
   SetDefaultTextAttribs();\r
   SetDefaultSounds();\r
-  appData.movesPerSession = MOVES_PER_SESSION;\r
-  appData.initString = INIT_STRING;\r
-  appData.secondInitString = INIT_STRING;\r
-  appData.firstComputerString = COMPUTER_STRING;\r
-  appData.secondComputerString = COMPUTER_STRING;\r
-  appData.firstChessProgram = FIRST_CHESS_PROGRAM;\r
-  appData.secondChessProgram = SECOND_CHESS_PROGRAM;\r
-  appData.firstPlaysBlack = FALSE;\r
-  appData.noChessProgram = FALSE;\r
-  chessProgram = FALSE;\r
-  appData.firstHost = FIRST_HOST;\r
-  appData.secondHost = SECOND_HOST;\r
-  appData.firstDirectory = FIRST_DIRECTORY;\r
-  appData.secondDirectory = SECOND_DIRECTORY;\r
-  appData.bitmapDirectory = "";\r
-  appData.remoteShell = REMOTE_SHELL;\r
-  appData.remoteUser = "";\r
-  appData.timeDelay = TIME_DELAY;\r
-  appData.timeControl = TIME_CONTROL;\r
-  appData.timeIncrement = TIME_INCREMENT;\r
-  appData.icsActive = FALSE;\r
-  appData.icsHost = "";\r
-  appData.icsPort = ICS_PORT;\r
-  appData.icsCommPort = ICS_COMM_PORT;\r
-  appData.icsLogon = ICS_LOGON;\r
-  appData.icsHelper = "";\r
-  appData.useTelnet = FALSE;\r
-  appData.telnetProgram = TELNET_PROGRAM;\r
-  appData.gateway = "";\r
-  appData.loadGameFile = "";\r
-  appData.loadGameIndex = 0;\r
-  appData.saveGameFile = "";\r
-  appData.autoSaveGames = FALSE;\r
-  appData.loadPositionFile = "";\r
-  appData.loadPositionIndex = 1;\r
-  appData.savePositionFile = "";\r
-  appData.matchMode = FALSE;\r
-  appData.matchGames = 0;\r
-  appData.monoMode = FALSE;\r
-  appData.debugMode = FALSE;\r
-  appData.clockMode = TRUE;\r
-  boardSize = (BoardSize) -1; /* determine by screen size */\r
-  appData.Iconic = FALSE; /*unused*/\r
-  appData.searchTime = "";\r
-  appData.searchDepth = 0;\r
-  appData.showCoords = FALSE;\r
-  appData.ringBellAfterMoves = TRUE; /*obsolete in WinBoard*/\r
-  appData.autoCallFlag = FALSE;\r
-  appData.flipView = FALSE;\r
-  appData.autoFlipView = TRUE;\r
-  appData.cmailGameName = "";\r
-  appData.alwaysPromoteToQueen = FALSE;\r
-  appData.oldSaveStyle = FALSE;\r
-  appData.quietPlay = FALSE;\r
-  appData.showThinking = FALSE;\r
-  appData.ponderNextMove = TRUE;\r
-  appData.periodicUpdates = TRUE;\r
-  appData.popupExitMessage = TRUE;\r
-  appData.popupMoveErrors = FALSE;\r
-  appData.autoObserve = FALSE;\r
-  appData.autoComment = FALSE;\r
-  appData.animate = TRUE;\r
-  appData.animSpeed = 10;\r
-  appData.animateDragging = TRUE;\r
-  appData.highlightLastMove = TRUE;\r
-  appData.getMoveList = TRUE;\r
-  appData.testLegality = TRUE;\r
-  appData.premove = TRUE;\r
-  appData.premoveWhite = FALSE;\r
-  appData.premoveWhiteText = "";\r
-  appData.premoveBlack = FALSE;\r
-  appData.premoveBlackText = "";\r
-  appData.icsAlarm = TRUE;\r
-  appData.icsAlarmTime = 5000;\r
-  appData.autoRaiseBoard = TRUE;\r
-  appData.localLineEditing = TRUE;\r
-  appData.colorize = TRUE;\r
-  appData.reuseFirst = TRUE;\r
-  appData.reuseSecond = TRUE;\r
-  appData.blindfold = FALSE;\r
-  appData.icsEngineAnalyze = FALSE;\r
+\r
   memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 +\r
   dcb.DCBlength = sizeof(DCB);\r
   dcb.BaudRate = 9600;\r
@@ -2048,132 +2019,6 @@ InitAppData(LPSTR lpCmdLine)
   dcb.ByteSize = 7;\r
   dcb.Parity = SPACEPARITY;\r
   dcb.StopBits = ONESTOPBIT;\r
-  settingsFileName = SETTINGS_FILE;\r
-  saveSettingsOnExit = TRUE;\r
-  boardX = CW_USEDEFAULT;\r
-  boardY = CW_USEDEFAULT;\r
-  analysisX = CW_USEDEFAULT; \r
-  analysisY = CW_USEDEFAULT; \r
-  analysisW = CW_USEDEFAULT;\r
-  analysisH = CW_USEDEFAULT;\r
-  commentX = CW_USEDEFAULT; \r
-  commentY = CW_USEDEFAULT; \r
-  commentW = CW_USEDEFAULT;\r
-  commentH = CW_USEDEFAULT;\r
-  editTagsX = CW_USEDEFAULT; \r
-  editTagsY = CW_USEDEFAULT; \r
-  editTagsW = CW_USEDEFAULT;\r
-  editTagsH = CW_USEDEFAULT;\r
-  icsTextMenuString = ICS_TEXT_MENU_DEFAULT;\r
-  icsNames = ICS_NAMES;\r
-  firstChessProgramNames = FCP_NAMES;\r
-  secondChessProgramNames = SCP_NAMES;\r
-  appData.initialMode = "";\r
-  appData.variant = "normal";\r
-  appData.firstProtocolVersion = PROTOVER;\r
-  appData.secondProtocolVersion = PROTOVER;\r
-  appData.showButtonBar = TRUE;\r
-\r
-   /* [AS] New properties (see comments in header file) */\r
-  appData.firstScoreIsAbsolute = FALSE;\r
-  appData.secondScoreIsAbsolute = FALSE;\r
-  appData.saveExtendedInfoInPGN = FALSE;\r
-  appData.hideThinkingFromHuman = FALSE;\r
-  appData.liteBackTextureFile = "";\r
-  appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
-  appData.darkBackTextureFile = "";\r
-  appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
-  appData.renderPiecesWithFont = "";\r
-  appData.fontToPieceTable = "";\r
-  appData.fontBackColorWhite = 0;\r
-  appData.fontForeColorWhite = 0;\r
-  appData.fontBackColorBlack = 0;\r
-  appData.fontForeColorBlack = 0;\r
-  appData.fontPieceSize = 80;\r
-  appData.overrideLineGap = 1;\r
-  appData.adjudicateLossThreshold = 0;\r
-  appData.delayBeforeQuit = 0;\r
-  appData.delayAfterQuit = 0;\r
-  appData.nameOfDebugFile = "winboard.debug";\r
-  appData.pgnEventHeader = "Computer Chess Game";\r
-  appData.defaultFrcPosition = -1;\r
-  appData.gameListTags = GLT_DEFAULT_TAGS;\r
-  appData.saveOutOfBookInfo = TRUE;\r
-  appData.showEvalInMoveHistory = TRUE;\r
-  appData.evalHistColorWhite = ParseColorName( "#FFFFB0" );\r
-  appData.evalHistColorBlack = ParseColorName( "#AD5D3D" );\r
-  appData.highlightMoveWithArrow = FALSE;\r
-  appData.highlightArrowColor = ParseColorName( "#FFFF80" );\r
-  appData.useStickyWindows = TRUE;\r
-  appData.adjudicateDrawMoves = 0;\r
-  appData.autoDisplayComment = TRUE;\r
-  appData.autoDisplayTags = TRUE;\r
-  appData.firstIsUCI = FALSE;\r
-  appData.secondIsUCI = FALSE;\r
-  appData.firstHasOwnBookUCI = TRUE;\r
-  appData.secondHasOwnBookUCI = TRUE;\r
-  appData.polyglotDir = "";\r
-  appData.usePolyglotBook = FALSE;\r
-  appData.polyglotBook = "";\r
-  appData.defaultHashSize = 64;\r
-  appData.defaultCacheSizeEGTB = 4;\r
-  appData.defaultPathEGTB = "c:\\egtb";\r
-  appData.firstOptions = "";\r
-  appData.secondOptions = "";\r
-\r
-  InitWindowPlacement( &wpGameList );\r
-  InitWindowPlacement( &wpMoveHistory );\r
-  InitWindowPlacement( &wpEvalGraph );\r
-  InitWindowPlacement( &wpEngineOutput );\r
-  InitWindowPlacement( &wpConsole );\r
-\r
-  /* [HGM] User-selectable board size, adjudication control, miscellaneous */\r
-  appData.NrFiles      = -1;\r
-  appData.NrRanks      = -1;\r
-  appData.holdingsSize = -1;\r
-  appData.testClaims   = FALSE;\r
-  appData.checkMates   = FALSE;\r
-  appData.materialDraws= FALSE;\r
-  appData.trivialDraws = FALSE;\r
-  appData.ruleMoves    = 51;\r
-  appData.drawRepeats  = 6;\r
-  appData.matchPause   = 10000;\r
-  appData.alphaRank    = FALSE;\r
-  appData.allWhite     = FALSE;\r
-  appData.upsideDown   = FALSE;\r
-  appData.serverPause  = 15;\r
-  appData.serverMovesName   = NULL;\r
-  appData.suppressLoadMoves = FALSE;\r
-  appData.firstTimeOdds  = 1;\r
-  appData.secondTimeOdds = 1;\r
-  appData.firstAccumulateTC  = 1; // combine previous and current sessions\r
-  appData.secondAccumulateTC = 1;\r
-  appData.firstNPS  = -1; // [HGM] nps: use wall-clock time\r
-  appData.secondNPS = -1;\r
-  appData.engineComments = 1;\r
-  appData.smpCores = 1; // [HGM] SMP: max nr of cores\r
-  appData.egtFormats = "";\r
-\r
-#ifdef ZIPPY\r
-  appData.zippyTalk = ZIPPY_TALK;\r
-  appData.zippyPlay = ZIPPY_PLAY;\r
-  appData.zippyLines = ZIPPY_LINES;\r
-  appData.zippyPinhead = ZIPPY_PINHEAD;\r
-  appData.zippyPassword = ZIPPY_PASSWORD;\r
-  appData.zippyPassword2 = ZIPPY_PASSWORD2;\r
-  appData.zippyWrongPassword = ZIPPY_WRONG_PASSWORD;\r
-  appData.zippyAcceptOnly = ZIPPY_ACCEPT_ONLY;\r
-  appData.zippyUseI = ZIPPY_USE_I;\r
-  appData.zippyBughouse = ZIPPY_BUGHOUSE;\r
-  appData.zippyNoplayCrafty = ZIPPY_NOPLAY_CRAFTY;\r
-  appData.zippyGameEnd = ZIPPY_GAME_END;\r
-  appData.zippyGameStart = ZIPPY_GAME_START;\r
-  appData.zippyAdjourn = ZIPPY_ADJOURN;\r
-  appData.zippyAbort = ZIPPY_ABORT;\r
-  appData.zippyVariants = ZIPPY_VARIANTS;\r
-  appData.zippyMaxGames = ZIPPY_MAX_GAMES;\r
-  appData.zippyReplayTimeout = ZIPPY_REPLAY_TIMEOUT;\r
-#endif\r
 \r
   /* Point font array elements to structures and\r
      parse default font names */\r
@@ -2193,9 +2038,9 @@ InitAppData(LPSTR lpCmdLine)
   ParseArgs(StringGet, &lpCmdLine);\r
 \r
   /* [HGM] make sure board size is acceptable */\r
-  if(appData.NrFiles > BOARD_SIZE ||\r
-     appData.NrRanks > BOARD_SIZE   )\r
-      DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2);\r
+  if(appData.NrFiles > BOARD_FILES ||\r
+     appData.NrRanks > BOARD_RANKS   )\r
+      DisplayFatalError("Recompile with BOARD_RANKS or BOARD_FILES, to support this size", 0, 2);\r
 \r
   /* [HGM] After parsing the options from the .ini file, and overruling them\r
    * with options from the command line, we now make an even higher priority\r
@@ -2304,16 +2149,73 @@ InitMenuChecks()
                                     MF_CHECKED : MF_UNCHECKED));\r
 }\r
 \r
+// [HGM] args: these three cases taken out to stay in front-end\r
+void\r
+SaveFontArg(FILE *f, ArgDescriptor *ad)\r
+{      // in WinBoard every board size has its own font, and the "argLoc" identifies the table,\r
+       // while the curent board size determines the element. This system should be ported to XBoard.\r
+       // What the table contains pointers to, and how to print the font description, remains platform-dependent\r
+        int bs;\r
+       for (bs=0; bs<NUM_SIZES; bs++) {\r
+         MyFontParams *mfp = &font[bs][(int) ad->argLoc]->mfp;\r
+          fprintf(f, "/size=%s ", sizeInfo[bs].name);\r
+         fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n",\r
+           ad->argName, mfp->faceName, mfp->pointSize,\r
+            mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "",\r
+           mfp->bold ? "b" : "",\r
+           mfp->italic ? "i" : "",\r
+           mfp->underline ? "u" : "",\r
+           mfp->strikeout ? "s" : "",\r
+            (int)mfp->charset);\r
+       }\r
+      }\r
+\r
+VOID\r
+ExportSounds()\r
+{ // [HGM] copy the names from the internal WB variables to appData\r
+  ColorClass cc;\r
+  SoundClass sc;\r
+  for (cc = (ColorClass)0; cc < ColorNormal; cc++)\r
+    (&appData.soundShout)[cc] = textAttribs[cc].sound.name;\r
+  for (sc = (SoundClass)0; sc < NSoundClasses; sc++)\r
+    (&appData.soundMove)[sc] = sounds[sc].name;\r
+}\r
+\r
+void\r
+SaveAttribsArg(FILE *f, ArgDescriptor *ad)\r
+{      // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though\r
+       MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc];\r
+       fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName,\r
+          (ta->effects & CFE_BOLD) ? "b" : "",\r
+          (ta->effects & CFE_ITALIC) ? "i" : "",\r
+          (ta->effects & CFE_UNDERLINE) ? "u" : "",\r
+          (ta->effects & CFE_STRIKEOUT) ? "s" : "",\r
+          (ta->effects) ? " " : "",\r
+         ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff);\r
+      }\r
+\r
+void\r
+SaveColor(FILE *f, ArgDescriptor *ad)\r
+{      // in WinBoard the color is an int and has to be converted to text. In X it would be a string already?\r
+       COLORREF color = *(COLORREF *)ad->argLoc;\r
+       fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, \r
+         color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
+}\r
+\r
+int\r
+MainWindowUp()\r
+{ // [HGM] args: allows testing if main window is realized from back-end\r
+  return hwndMain != NULL;\r
+}\r
 \r
 VOID\r
 SaveSettings(char* name)\r
 {\r
   FILE *f;\r
   ArgDescriptor *ad;\r
-  WINDOWPLACEMENT wp;\r
   char dir[MSG_SIZ];\r
 \r
-  if (!hwndMain) return;\r
+  if (!MainWindowUp()) return;\r
 \r
   GetCurrentDirectory(MSG_SIZ, dir);\r
   SetCurrentDirectory(installDir);\r
@@ -2331,83 +2233,26 @@ SaveSettings(char* name)
   fprintf(f, "; Use a shortcut, an @indirection file, or a .bat file instead.\n");\r
   fprintf(f, ";\n");\r
 \r
-  wp.length = sizeof(WINDOWPLACEMENT);\r
-  GetWindowPlacement(hwndMain, &wp);\r
-  boardX = wp.rcNormalPosition.left;\r
-  boardY = wp.rcNormalPosition.top;\r
-\r
-  if (hwndConsole) {\r
-    GetWindowPlacement(hwndConsole, &wp);\r
-    wpConsole.x = wp.rcNormalPosition.left;\r
-    wpConsole.y = wp.rcNormalPosition.top;\r
-    wpConsole.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpConsole.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (analysisDialog) {\r
-    GetWindowPlacement(analysisDialog, &wp);\r
-    analysisX = wp.rcNormalPosition.left;\r
-    analysisY = wp.rcNormalPosition.top;\r
-    analysisW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    analysisH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (commentDialog) {\r
-    GetWindowPlacement(commentDialog, &wp);\r
-    commentX = wp.rcNormalPosition.left;\r
-    commentY = wp.rcNormalPosition.top;\r
-    commentW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    commentH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (editTagsDialog) {\r
-    GetWindowPlacement(editTagsDialog, &wp);\r
-    editTagsX = wp.rcNormalPosition.left;\r
-    editTagsY = wp.rcNormalPosition.top;\r
-    editTagsW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    editTagsH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
-\r
-  if (gameListDialog) {\r
-    GetWindowPlacement(gameListDialog, &wp);\r
-    wpGameList.x = wp.rcNormalPosition.left;\r
-    wpGameList.y = wp.rcNormalPosition.top;\r
-    wpGameList.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpGameList.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
+  GetActualPlacement(hwndMain, &wpMain);\r
+  GetActualPlacement(hwndConsole, &wpConsole);\r
+  GetActualPlacement(commentDialog, &wpComment);\r
+  GetActualPlacement(editTagsDialog, &wpTags);\r
+  GetActualPlacement(gameListDialog, &wpGameList);\r
 \r
   /* [AS] Move history */\r
   wpMoveHistory.visible = MoveHistoryIsUp();\r
-  \r
-  if( moveHistoryDialog ) {\r
-    GetWindowPlacement(moveHistoryDialog, &wp);\r
-    wpMoveHistory.x = wp.rcNormalPosition.left;\r
-    wpMoveHistory.y = wp.rcNormalPosition.top;\r
-    wpMoveHistory.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpMoveHistory.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
+  GetActualPlacement(moveHistoryDialog, &wpMoveHistory);\r
 \r
   /* [AS] Eval graph */\r
   wpEvalGraph.visible = EvalGraphIsUp();\r
-\r
-  if( evalGraphDialog ) {\r
-    GetWindowPlacement(evalGraphDialog, &wp);\r
-    wpEvalGraph.x = wp.rcNormalPosition.left;\r
-    wpEvalGraph.y = wp.rcNormalPosition.top;\r
-    wpEvalGraph.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpEvalGraph.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
+  GetActualPlacement(evalGraphDialog, &wpEvalGraph);\r
 \r
   /* [AS] Engine output */\r
   wpEngineOutput.visible = EngineOutputIsUp();\r
+  GetActualPlacement(engineOutputDialog, &wpEngineOutput);\r
 \r
-  if( engineOutputDialog ) {\r
-    GetWindowPlacement(engineOutputDialog, &wp);\r
-    wpEngineOutput.x = wp.rcNormalPosition.left;\r
-    wpEngineOutput.y = wp.rcNormalPosition.top;\r
-    wpEngineOutput.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
-    wpEngineOutput.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
-  }\r
+  // [HGM] in WB we have to copy sound names to appData first\r
+  ExportSounds();\r
 \r
   for (ad = argDescriptors; ad->argName != NULL; ad++) {\r
     if (!ad->save) continue;\r
@@ -2443,10 +2288,10 @@ SaveSettings(char* name)
       fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc);\r
       break;\r
     case ArgX:\r
-      fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardX); // [HGM] placement: stor relative value\r
+      fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - wpMain.x); // [HGM] placement: stor relative value\r
       break;\r
     case ArgY:\r
-      fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardY);\r
+      fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - wpMain.y);\r
       break;\r
     case ArgFloat:\r
       fprintf(f, "/%s=%g\n", ad->argName, *(float *)ad->argLoc);\r
@@ -2462,23 +2307,9 @@ SaveSettings(char* name)
       if (!*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName);\r
       break;\r
     case ArgColor:\r
-      {\r
-       COLORREF color = *(COLORREF *)ad->argLoc;\r
-       fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, \r
-         color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
-      }\r
+      SaveColor(f, ad);\r
       break;\r
     case ArgAttribs:\r
-      {\r
-       MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc];\r
-       fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName,\r
-          (ta->effects & CFE_BOLD) ? "b" : "",\r
-          (ta->effects & CFE_ITALIC) ? "i" : "",\r
-          (ta->effects & CFE_UNDERLINE) ? "u" : "",\r
-          (ta->effects & CFE_STRIKEOUT) ? "s" : "",\r
-          (ta->effects) ? " " : "",\r
-         ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff);\r
-      }\r
       break;\r
     case ArgFilename:\r
       if (strchr(*(char **)ad->argLoc, '\"')) {\r
@@ -2492,21 +2323,7 @@ SaveSettings(char* name)
              sizeInfo[*(BoardSize *)ad->argLoc].name);\r
       break;\r
     case ArgFont:\r
-      {\r
-        int bs;\r
-       for (bs=0; bs<NUM_SIZES; bs++) {\r
-         MyFontParams *mfp = &font[bs][(int) ad->argLoc]->mfp;\r
-          fprintf(f, "/size=%s ", sizeInfo[bs].name);\r
-         fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n",\r
-           ad->argName, mfp->faceName, mfp->pointSize,\r
-            mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "",\r
-           mfp->bold ? "b" : "",\r
-           mfp->italic ? "i" : "",\r
-           mfp->underline ? "u" : "",\r
-           mfp->strikeout ? "s" : "",\r
-            (int)mfp->charset);\r
-       }\r
-      }\r
+      SaveFontArg(f, ad);\r
       break;\r
     case ArgCommSettings:\r
       PrintCommSettings(f, ad->argName, (DCB *)ad->argLoc);\r
@@ -3032,7 +2849,7 @@ void CreatePiecesFromFont()
                 }\r
                 else if( strstr(lf.lfFaceName,"GC2004D") != NULL ) {\r
                     /* Good Companion (Some characters get warped as literal :-( */\r
-                    char s[] = "1cmWG0ñueOS¯®oYI23wgQU";\r
+                    char s[] = "1cmWG0??S??oYI23wgQU";\r
                     s[0]=0xB9; s[1]=0xA9; s[6]=0xB1; s[11]=0xBB; s[12]=0xAB; s[17]=0xB3;\r
                     SetCharTable(pieceToFontChar, s);\r
                 }\r
@@ -3200,10 +3017,10 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */\r
   if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize;\r
 \r
-  oldRect.left = boardX; //[HGM] placement: remember previous window params\r
-  oldRect.top = boardY;\r
-  oldRect.right = boardX + winWidth;\r
-  oldRect.bottom = boardY + winHeight;\r
+  oldRect.left = wpMain.x; //[HGM] placement: remember previous window params\r
+  oldRect.top = wpMain.y;\r
+  oldRect.right = wpMain.x + wpMain.width;\r
+  oldRect.bottom = wpMain.y + wpMain.height;\r
 \r
   tinyLayout = sizeInfo[boardSize].tinyLayout;\r
   smallLayout = sizeInfo[boardSize].smallLayout;\r
@@ -3311,49 +3128,49 @@ InitDrawingSizes(BoardSize boardSize, int flags)
   winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
     GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN;\r
   if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only\r
-  winWidth = winW;  // [HGM] placement: set through temporary which can used by initial sizing choice\r
-  winHeight = winH; //       without disturbing window attachments\r
+  wpMain.width = winW;  // [HGM] placement: set through temporary which can used by initial sizing choice\r
+  wpMain.height = winH; //       without disturbing window attachments\r
   GetWindowRect(hwndMain, &wrect);\r
-  SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight,\r
+  SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height,\r
               SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE);\r
 \r
   // [HGM] placement: let attached windows follow size change.\r
-  ReattachAfterSize( &oldRect, winWidth, winHeight, moveHistoryDialog, &wpMoveHistory );\r
-  ReattachAfterSize( &oldRect, winWidth, winHeight, evalGraphDialog, &wpEvalGraph );\r
-  ReattachAfterSize( &oldRect, winWidth, winHeight, engineOutputDialog, &wpEngineOutput );\r
-  ReattachAfterSize( &oldRect, winWidth, winHeight, gameListDialog, &wpGameList );\r
-  ReattachAfterSize( &oldRect, winWidth, winHeight, hwndConsole, &wpConsole );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, moveHistoryDialog, &wpMoveHistory );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, evalGraphDialog, &wpEvalGraph );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, engineOutputDialog, &wpEngineOutput );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, gameListDialog, &wpGameList );\r
+  ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, hwndConsole, &wpConsole );\r
 \r
   /* compensate if menu bar wrapped */\r
   GetClientRect(hwndMain, &crect);\r
   offby = boardRect.bottom + OUTER_MARGIN - crect.bottom;\r
-  winHeight += offby;\r
+  wpMain.height += offby;\r
   switch (flags) {\r
   case WMSZ_TOPLEFT:\r
     SetWindowPos(hwndMain, NULL, \r
-                 wrect.right - winWidth, wrect.bottom - winHeight, \r
-                 winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
+                 wrect.right - wpMain.width, wrect.bottom - wpMain.height, \r
+                 wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER);\r
     break;\r
 \r
   case WMSZ_TOPRIGHT:\r
   case WMSZ_TOP:\r
     SetWindowPos(hwndMain, NULL, \r
-                 wrect.left, wrect.bottom - winHeight, \r
-                 winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
+                 wrect.left, wrect.bottom - wpMain.height, \r
+                 wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER);\r
     break;\r
 \r
   case WMSZ_BOTTOMLEFT:\r
   case WMSZ_LEFT:\r
     SetWindowPos(hwndMain, NULL, \r
-                 wrect.right - winWidth, wrect.top, \r
-                 winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
+                 wrect.right - wpMain.width, wrect.top, \r
+                 wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER);\r
     break;\r
 \r
   case WMSZ_BOTTOMRIGHT:\r
   case WMSZ_BOTTOM:\r
   case WMSZ_RIGHT:\r
   default:\r
-    SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight,\r
+    SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height,\r
                SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE);\r
     break;\r
   }\r
@@ -4234,8 +4051,8 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)
   if( liteBackTexture != NULL || darkBackTexture != NULL ) {\r
       static int backTextureBoardSize; /* [HGM] boardsize: also new texture if board format changed */\r
       if( backTextureSquareSize != squareSize \r
-       || backTextureBoardSize != BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT) {\r
-         backTextureBoardSize = BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT;\r
+       || backTextureBoardSize != BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT) {\r
+         backTextureBoardSize = BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT;\r
           backTextureSquareSize = squareSize;\r
           RebuildTextureSquareInfo();\r
       }\r
@@ -6252,18 +6069,18 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             RECT rcMain;\r
 \r
 //            GetWindowRect( hwnd, &rcMain ); //[HGM] sticky: in XP this returned new position, not old\r
-           rcMain.left   = boardX;           //              replace by these 4 lines to reconstruct old rect\r
-           rcMain.right  = boardX + winWidth;\r
-           rcMain.top    = boardY;\r
-           rcMain.bottom = boardY + winHeight;\r
+           rcMain.left   = wpMain.x;           //              replace by these 4 lines to reconstruct old rect\r
+           rcMain.right  = wpMain.x + wpMain.width;\r
+           rcMain.top    = wpMain.y;\r
+           rcMain.bottom = wpMain.y + wpMain.height;\r
             \r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory );\r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph );\r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput );\r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, gameListDialog, &wpGameList );\r
             ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole );\r
-           boardX = lpwp->x;\r
-            boardY = lpwp->y;\r
+           wpMain.x = lpwp->x;\r
+            wpMain.y = lpwp->y;\r
         }\r
     }\r
     break;\r
@@ -7026,18 +6843,18 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       GetClientRect(hDlg, &rect);\r
       sizeX = rect.right;\r
       sizeY = rect.bottom;\r
-      if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT &&\r
-         commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) {\r
+      if (wpComment.x != CW_USEDEFAULT && wpComment.y != CW_USEDEFAULT &&\r
+         wpComment.width != CW_USEDEFAULT && wpComment.height != CW_USEDEFAULT) {\r
        WINDOWPLACEMENT wp;\r
-       EnsureOnScreen(&commentX, &commentY, 0, 0);\r
+       EnsureOnScreen(&wpComment.x, &wpComment.y, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
        wp.showCmd = SW_SHOW;\r
        wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-       wp.rcNormalPosition.left = commentX;\r
-       wp.rcNormalPosition.right = commentX + commentW;\r
-       wp.rcNormalPosition.top = commentY;\r
-       wp.rcNormalPosition.bottom = commentY + commentH;\r
+       wp.rcNormalPosition.left = wpComment.x;\r
+       wp.rcNormalPosition.right = wpComment.x + wpComment.width;\r
+       wp.rcNormalPosition.top = wpComment.y;\r
+       wp.rcNormalPosition.bottom = wpComment.y + wpComment.height;\r
        SetWindowPlacement(hDlg, &wp);\r
 \r
        GetClientRect(hDlg, &rect);\r
@@ -7186,13 +7003,8 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        }\r
        // [HGM] movenum: allow move number to be typed in any mode\r
        if(sscanf(move, "%d", &n) == 1 && n != 0 ) {\r
-         currentMove = 2*n-1;\r
-         if(currentMove > forwardMostMove)  currentMove = forwardMostMove;\r
-         if(currentMove < backwardMostMove) currentMove = backwardMostMove;\r
+         ToNrEvent(2*n-1);\r
          EndDialog(hDlg, TRUE);\r
-         DrawPosition(TRUE, boards[currentMove]);\r
-         if(currentMove > backwardMostMove) DisplayMove(currentMove - 1);\r
-         else DisplayMessage("", "");\r
          return TRUE;\r
        }\r
       }\r
@@ -7416,7 +7228,7 @@ GothicDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
   case WM_INITDIALOG:\r
     GetWindowRect(hDlg, &rChild);\r
 \r
-    SetWindowPos(hDlg, NULL, boardX, boardY-height, winWidth, height,\r
+    SetWindowPos(hDlg, NULL, wpMain.x, wpMain.y-height, wpMain.width, height,\r
                                                              SWP_NOZORDER);\r
 \r
     /* \r
@@ -8037,10 +7849,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    // [HGM] Chessknight's change 2004-07-13\r
    else { /* Determine Defaults */\r
        WINDOWPLACEMENT wp;\r
-       wpConsole.x = winWidth + 1;\r
-       wpConsole.y = boardY;\r
-       wpConsole.width = screenWidth -  winWidth;\r
-       wpConsole.height = winHeight;\r
+       wpConsole.x = wpMain.width + 1;\r
+       wpConsole.y = wpMain.y;\r
+       wpConsole.width = screenWidth -  wpMain.width;\r
+       wpConsole.height = wpMain.height;\r
        EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
        wp.length = sizeof(WINDOWPLACEMENT);\r
        wp.flags = 0;\r
@@ -8569,6 +8381,13 @@ typedef struct {
 } Enables;\r
 \r
 VOID\r
+GreyRevert(Boolean grey)\r
+{ // [HGM] vari: for retracting variations in local mode\r
+  HMENU hmenu = GetMenu(hwndMain);\r
+  EnableMenuItem(hmenu, IDM_Revert, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED));\r
+}\r
+\r
+VOID\r
 SetMenuEnables(HMENU hmenu, Enables *enab)\r
 {\r
   while (enab->item > 0) {\r
@@ -10490,86 +10309,6 @@ StartAnalysisClock()
                                        (UINT) 2000, NULL);\r
 }\r
 \r
-LRESULT CALLBACK\r
-AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
-  static HANDLE hwndText;\r
-  RECT rect;\r
-  static int sizeX, sizeY;\r
-  int newSizeX, newSizeY, flags;\r
-  MINMAXINFO *mmi;\r
-\r
-  switch (message) {\r
-  case WM_INITDIALOG: /* message: initialize dialog box */\r
-    /* Initialize the dialog items */\r
-    hwndText = GetDlgItem(hDlg, OPT_AnalysisText);\r
-    SetWindowText(hDlg, analysisTitle);\r
-    SetDlgItemText(hDlg, OPT_AnalysisText, analysisText);\r
-    /* Size and position the dialog */\r
-    if (!analysisDialog) {\r
-      analysisDialog = hDlg;\r
-      flags = SWP_NOZORDER;\r
-      GetClientRect(hDlg, &rect);\r
-      sizeX = rect.right;\r
-      sizeY = rect.bottom;\r
-      if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT &&\r
-         analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) {\r
-       WINDOWPLACEMENT wp;\r
-       EnsureOnScreen(&analysisX, &analysisY, 0, 0);\r
-       wp.length = sizeof(WINDOWPLACEMENT);\r
-       wp.flags = 0;\r
-       wp.showCmd = SW_SHOW;\r
-       wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
-       wp.rcNormalPosition.left = analysisX;\r
-       wp.rcNormalPosition.right = analysisX + analysisW;\r
-       wp.rcNormalPosition.top = analysisY;\r
-       wp.rcNormalPosition.bottom = analysisY + analysisH;\r
-       SetWindowPlacement(hDlg, &wp);\r
-\r
-       GetClientRect(hDlg, &rect);\r
-       newSizeX = rect.right;\r
-       newSizeY = rect.bottom;\r
-        ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY,\r
-                             newSizeX, newSizeY);\r
-       sizeX = newSizeX;\r
-       sizeY = newSizeY;\r
-      }\r
-    }\r
-    return FALSE;\r
-\r
-  case WM_COMMAND: /* message: received a command */\r
-    switch (LOWORD(wParam)) {\r
-    case IDCANCEL:\r
-      if (appData.icsActive && appData.icsEngineAnalyze) { /* [DM] icsEngineAnalyze */\r
-          ExitAnalyzeMode();\r
-          ModeHighlight();\r
-          return TRUE;\r
-      }\r
-      EditGameEvent();\r
-      return TRUE;\r
-    default:\r
-      break;\r
-    }\r
-    break;\r
-\r
-  case WM_SIZE:\r
-    newSizeX = LOWORD(lParam);\r
-    newSizeY = HIWORD(lParam);\r
-    ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, newSizeX, newSizeY);\r
-    sizeX = newSizeX;\r
-    sizeY = newSizeY;\r
-    break;\r
-\r
-  case WM_GETMINMAXINFO:\r
-    /* Prevent resizing window too small */\r
-    mmi = (MINMAXINFO *) lParam;\r
-    mmi->ptMinTrackSize.x = 100;\r
-    mmi->ptMinTrackSize.y = 100;\r
-    break;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
 VOID\r
 SetHighlights(int fromX, int fromY, int toX, int toY)\r
 {\r
@@ -10774,8 +10513,3 @@ HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current )
 \r
     EvalGraphSet( first, last, current, pvInfoList );\r
 }\r
-\r
-void SetProgramStats( FrontEndProgramStats * stats )\r
-{\r
-    EngineOutputUpdate( stats );\r
-}\r
index 973aab6..443f728 100644 (file)
@@ -173,6 +173,19 @@ extern MyFont *font[NUM_SIZES][NUM_FONTS];
 #define COPY_TMP "wbcopy.tmp"\r
 #define PASTE_TMP "wbpaste.tmp"\r
 \r
+/* variables */\r
+extern HINSTANCE hInst;\r
+extern HWND hwndMain;\r
+extern BoardSize boardSize;\r
+\r
+// [HGM] Some stuff to allo a platform-independent reference to windows\r
+// This should be moved to frontend.h in due time\r
+\r
+typedef enum {\r
+  W_Main, W_Console, W_Comment, W_Tags, W_GameList, \r
+  W_MoveHist, W_EngineOut, W_GameList, NUM_WINDOWS\r
+} WindowID;\r
+\r
 /* [AS] Layout management */\r
 typedef struct {\r
     Boolean visible;\r
@@ -182,10 +195,37 @@ typedef struct {
     int height;\r
 } WindowPlacement;\r
 \r
-VOID InitWindowPlacement( WindowPlacement * wp );\r
+extern WindowPlacement placementTab[NUM_WINDOWS];\r
+extern HWND hwndTab[NUM_WINDOWS]; // this remains pure front-end.\r
 \r
+VOID InitWindowPlacement( WindowPlacement * wp );\r
 VOID RestoreWindowPlacement( HWND hWnd, WindowPlacement * wp );\r
-\r
 VOID ReattachAfterMove( LPRECT lprcOldPos, int new_x, int new_y, HWND hWndChild, WindowPlacement * pwpChild );\r
-\r
 VOID ReattachAfterSize( LPRECT lprcOldPos, int new_w, int new_h, HWND hWndChild, WindowPlacement * pwpChild );\r
+BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp );\r
+\r
+extern WindowPlacement wpEngineOutput;\r
+extern WindowPlacement wpEvalGraph;\r
+extern WindowPlacement wpMoveHistory;\r
+extern WindowPlacement wpGameList;\r
+extern WindowPlacement wpTags;\r
+\r
+VOID MoveHistoryPopUp();\r
+VOID MoveHistoryPopDown();\r
+VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
+BOOL MoveHistoryIsUp();\r
+extern HWND moveHistoryDialog;\r
+\r
+VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
+VOID EvalGraphPopUp();\r
+VOID EvalGraphPopDown();\r
+Boolean EvalGraphIsUp();\r
+extern HWND evalGraphDialog;\r
+\r
+extern HWND engineOutputDialog;\r
+\r
+VOID ShowGameListProc(void);\r
+extern HWND gameListDialog;\r
+\r
+VOID EditTagsProc(void);\r
+extern HWND editTagsDialog;\r
index c61067b..0214ca2 100644 (file)
@@ -54,7 +54,7 @@ BEGIN
                     OPT_MESS,6,85,120,16\r
 END\r
 \r
-DLG_TimeControl DIALOG DISCARDABLE  6, 18, 263, 172\r
+DLG_TimeControl DIALOG DISCARDABLE  6, 18, 263, 212\r
 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
 CAPTION "Time Control"\r
 FONT 8, "MS Sans Serif"\r
@@ -65,6 +65,8 @@ BEGIN
                     BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,36,113,10\r
     CONTROL         "Incremental clock",OPT_TCUseInc,"Button",\r
                     BS_AUTORADIOBUTTON | WS_TABSTOP,7,73,107,10\r
+    CONTROL         "Fixed time per move",OPT_TCUseFixed,"Button",\r
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,7,124,107,10\r
     LTEXT           "Number of moves:",OPT_TCtext1,15,52,58,8,NOT WS_GROUP\r
     EDITTEXT        OPT_TCMoves,77,52,22,12,ES_AUTOHSCROLL | WS_GROUP\r
     LTEXT           "Within number of minutes:",OPT_TCtext2,113,54,81,8,NOT \r
@@ -76,14 +78,17 @@ BEGIN
     LTEXT           "Plus number of seconds per move:",406,15,105,109,8,NOT \r
                     WS_GROUP\r
     EDITTEXT        OPT_TCInc,127,103,32,12,ES_AUTOHSCROLL\r
-    LTEXT           "",408,185,108,67,8,NOT WS_GROUP\r
-    LTEXT           "Time-Odds Factors:",IDC_STATIC,6,118,150,8,NOT WS_GROUP\r
-    EDITTEXT        OPT_TCOdds1,47,131,26,12,ES_AUTOHSCROLL | WS_GROUP\r
-    LTEXT           "Engine #1:",IDC_STATIC,6,133,41,8,NOT WS_GROUP\r
-    EDITTEXT        OPT_TCOdds2,124,131,26,12,ES_AUTOHSCROLL\r
-    LTEXT           "Engine #2:",IDC_STATIC,83,133,41,8,NOT WS_GROUP\r
-    PUSHBUTTON      "OK",IDOK,29,150,40,14,WS_GROUP\r
-    PUSHBUTTON      "Cancel",IDCANCEL,85,150,40,14\r
+    LTEXT           "Maximum seconds per move:",OPT_TCftext,15,142,109,8,NOT \r
+                    WS_GROUP\r
+    EDITTEXT        OPT_TCFixed,127,140,32,12,ES_AUTOHSCROLL\r
+    LTEXT           "",408,185,148,67,8,NOT WS_GROUP\r
+    LTEXT           "Time-Odds Factors:",IDC_STATIC,6,158,150,8,NOT WS_GROUP\r
+    EDITTEXT        OPT_TCOdds1,47,171,32,12,ES_AUTOHSCROLL | WS_GROUP\r
+    LTEXT           "Engine #1:",IDC_STATIC,6,173,40,8,NOT WS_GROUP\r
+    EDITTEXT        OPT_TCOdds2,127,171,32,12,ES_AUTOHSCROLL\r
+    LTEXT           "Engine #2:",IDC_STATIC,86,173,40,8,NOT WS_GROUP\r
+    PUSHBUTTON      "OK",IDOK,29,190,40,14,WS_GROUP\r
+    PUSHBUTTON      "Cancel",IDCANCEL,85,190,40,14\r
 END\r
 \r
 DLG_LoadOptions DIALOG DISCARDABLE  10, 18, 136, 55\r
index 04f6eb6..2442466 100644 (file)
@@ -33,6 +33,7 @@
 #include <dlgs.h>\r
 \r
 #include "common.h"\r
+#include "frontend.h"\r
 #include "winboard.h"\r
 \r
 VOID RestoreWindowPlacement( HWND hWnd, WindowPlacement * wp )\r
@@ -93,7 +94,7 @@ static BOOL IsDefaultPlacement( WindowPlacement * wp )
     return result;\r
 }\r
 \r
-static BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp )\r
+BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp )\r
 {\r
     BOOL result = FALSE;\r
 \r
index aaab83b..dfc1bfb 100755 (executable)
-/*
- * woptions.c -- Options dialog box routines for WinBoard
- *
- * Copyright 2000,2009 Free Software Foundation, Inc.
- *
- * Enhancements Copyright 2005 Alessandro Scotti
- *
- * ------------------------------------------------------------------------
- *
- * GNU XBoard is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at
- * your option) any later version.
- *
- * GNU XBoard is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.  *
- *
- *------------------------------------------------------------------------
- ** See the file ChangeLog for a revision history.  */
-
-#include "config.h"
-
-#include <windows.h>   /* required for all Windows applications */
-#include <stdio.h>
-#include <stdlib.h>
-#include <shlobj.h>    /* [AS] Requires NT 4.0 or Win95 */
-#include <ctype.h>
-
-#include "common.h"
-#include "winboard.h"
-#include "backend.h"
-#include "woptions.h"
-#include "defaults.h"
-#include "wedittags.h"
-#include <richedit.h>
-
-#if __GNUC__
-#include <errno.h>
-#include <string.h>
-#endif
-
-/* Imports from winboard.c */
-
-extern MyFont *font[NUM_SIZES][NUM_FONTS];
-extern HINSTANCE hInst;          /* current instance */
-extern HWND hwndMain;            /* root window*/
-extern BOOLEAN alwaysOnTop;
-extern RECT boardRect;
-extern COLORREF lightSquareColor, darkSquareColor, whitePieceColor, 
-  blackPieceColor, highlightSquareColor, premoveHighlightColor;
-extern HPALETTE hPal;
-extern BoardSize boardSize;
-extern COLORREF consoleBackgroundColor;
-extern MyColorizeAttribs colorizeAttribs[]; /* do I need the size? */
-extern MyTextAttribs textAttribs[];
-extern MySound sounds[];
-extern ColorClass currentColorClass;
-extern HWND hwndConsole;
-extern char *defaultTextAttribs[];
-extern HWND commentDialog;
-extern HWND moveHistoryDialog;
-extern HWND engineOutputDialog;
-extern char installDir[];
-extern HWND hCommPort;    /* currently open comm port */
-extern DCB dcb;
-extern BOOLEAN chessProgram;
-extern int startedFromPositionFile; /* [HGM] loadPos */
-
-/* types */
-
-typedef struct {
-  char *label;
-  unsigned value;
-} ComboData;
-
-typedef struct {
-  char *label;
-  char *name;
-} SoundComboData;
-
-/* module prototypes */
-
-LRESULT CALLBACK GeneralOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK BoardOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK NewVariant(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK IcsOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK FontOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK CommPortOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK LoadOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK SaveOptions(HWND, UINT, WPARAM, LPARAM);
-LRESULT CALLBACK TimeControl(HWND, UINT, WPARAM, LPARAM);
-VOID ChangeBoardSize(BoardSize newSize);
-VOID PaintSampleSquare(
-    HWND     hwnd, 
-    int      ctrlid, 
-    COLORREF squareColor, 
-    COLORREF pieceColor,
-    COLORREF squareOutlineColor,
-    COLORREF pieceDetailColor,
-    BOOL     isWhitePiece,
-    BOOL     isMono,
-    HBITMAP  pieces[3] 
-    );
-VOID PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color);
-VOID SetBoardOptionEnables(HWND hDlg);
-BoardSize BoardOptionsWhichRadio(HWND hDlg);
-BOOL APIENTRY MyCreateFont(HWND hwnd, MyFont *font);
-VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);
-LRESULT CALLBACK ColorizeTextDialog(HWND , UINT, WPARAM, LPARAM);
-VOID ColorizeTextPopup(HWND hwnd, ColorClass cc);
-VOID SetIcsOptionEnables(HWND hDlg);
-VOID SetSampleFontText(HWND hwnd, int id, const MyFont *mf);
-VOID CopyFont(MyFont *dest, const MyFont *src);
-void InitSoundComboData(SoundComboData *scd);
-void ResetSoundComboData(SoundComboData *scd);
-void InitSoundCombo(HWND hwndCombo, SoundComboData *scd);
-int SoundDialogWhichRadio(HWND hDlg);
-VOID SoundDialogSetEnables(HWND hDlg, int radio);
-char * SoundDialogGetName(HWND hDlg, int radio);
-void DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name);
-VOID ParseCommSettings(char *arg, DCB *dcb);
-VOID PrintCommSettings(FILE *f, char *name, DCB *dcb);
-void InitCombo(HANDLE hwndCombo, ComboData *cd);
-void SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value);
-VOID SetLoadOptionEnables(HWND hDlg);
-VOID SetSaveOptionEnables(HWND hDlg);
-VOID SetTimeControlEnables(HWND hDlg);
-void NewSettingEvent(int option, char *command, int value);
-
-/*---------------------------------------------------------------------------*\
- *
- * General Options Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-
-LRESULT CALLBACK
-GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  static Boolean oldShowCoords;
-  static Boolean oldBlindfold;
-  static Boolean oldShowButtonBar;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    oldShowCoords = appData.showCoords;
-    oldBlindfold  = appData.blindfold;
-    oldShowButtonBar = appData.showButtonBar;
-
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-
-    /* Initialize the dialog items */
-#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))
-
-    CHECK_BOX(OPT_AlwaysOnTop, alwaysOnTop);
-    CHECK_BOX(OPT_AlwaysQueen, appData.alwaysPromoteToQueen);
-    CHECK_BOX(OPT_AnimateDragging, appData.animateDragging);
-    CHECK_BOX(OPT_AnimateMoving, appData.animate);
-    CHECK_BOX(OPT_AutoFlag, appData.autoCallFlag);
-    CHECK_BOX(OPT_AutoFlipView, appData.autoFlipView);
-    CHECK_BOX(OPT_AutoRaiseBoard, appData.autoRaiseBoard);
-    CHECK_BOX(OPT_Blindfold, appData.blindfold);
-    CHECK_BOX(OPT_HighlightDragging, appData.highlightDragging);
-    CHECK_BOX(OPT_HighlightLastMove, appData.highlightLastMove);
-    CHECK_BOX(OPT_PeriodicUpdates, appData.periodicUpdates);
-    CHECK_BOX(OPT_PonderNextMove, appData.ponderNextMove);
-    CHECK_BOX(OPT_PopupExitMessage, appData.popupExitMessage);
-    CHECK_BOX(OPT_PopupMoveErrors, appData.popupMoveErrors);
-    CHECK_BOX(OPT_ShowButtonBar, appData.showButtonBar);
-    CHECK_BOX(OPT_ShowCoordinates, appData.showCoords);
-    CHECK_BOX(OPT_ShowThinking, appData.showThinking);
-    CHECK_BOX(OPT_TestLegality, appData.testLegality);
-    CHECK_BOX(OPT_HideThinkFromHuman, appData.hideThinkingFromHuman);
-    CHECK_BOX(OPT_SaveExtPGN, appData.saveExtendedInfoInPGN);
-    CHECK_BOX(OPT_ExtraInfoInMoveHistory, appData.showEvalInMoveHistory);
-    CHECK_BOX(OPT_HighlightMoveArrow, appData.highlightMoveWithArrow);
-
-#undef CHECK_BOX
-
-    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlag),
-                appData.icsActive || !appData.noChessProgram);
-    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlipView),
-                appData.icsActive || !appData.noChessProgram);
-    EnableWindow(GetDlgItem(hDlg, OPT_PonderNextMove),
-                !appData.noChessProgram);
-    EnableWindow(GetDlgItem(hDlg, OPT_PeriodicUpdates), 
-                !appData.noChessProgram && !appData.icsActive);
-    EnableWindow(GetDlgItem(hDlg, OPT_ShowThinking), 
-                !appData.noChessProgram);
-    return TRUE;
-
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-      
-#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))
-
-      alwaysOnTop                  = IS_CHECKED(OPT_AlwaysOnTop);
-      appData.alwaysPromoteToQueen = IS_CHECKED(OPT_AlwaysQueen);
-      appData.animateDragging      = IS_CHECKED(OPT_AnimateDragging);
-      appData.animate              = IS_CHECKED(OPT_AnimateMoving);
-      appData.autoCallFlag         = IS_CHECKED(OPT_AutoFlag);
-      appData.autoFlipView         = IS_CHECKED(OPT_AutoFlipView);
-      appData.autoRaiseBoard       = IS_CHECKED(OPT_AutoRaiseBoard);
-      appData.blindfold            = IS_CHECKED(OPT_Blindfold);
-      appData.highlightDragging    = IS_CHECKED(OPT_HighlightDragging);
-      appData.highlightLastMove    = IS_CHECKED(OPT_HighlightLastMove);
-      PeriodicUpdatesEvent(          IS_CHECKED(OPT_PeriodicUpdates));
-      PonderNextMoveEvent(           IS_CHECKED(OPT_PonderNextMove));
-      appData.popupExitMessage     = IS_CHECKED(OPT_PopupExitMessage);
-      appData.popupMoveErrors      = IS_CHECKED(OPT_PopupMoveErrors);
-      appData.showButtonBar        = IS_CHECKED(OPT_ShowButtonBar);
-      appData.showCoords           = IS_CHECKED(OPT_ShowCoordinates);
-      // [HGM] thinking: next three moved up
-      appData.saveExtendedInfoInPGN= IS_CHECKED(OPT_SaveExtPGN);
-      appData.hideThinkingFromHuman= IS_CHECKED(OPT_HideThinkFromHuman);
-      appData.showEvalInMoveHistory= IS_CHECKED(OPT_ExtraInfoInMoveHistory);
-      appData.showThinking         = IS_CHECKED(OPT_ShowThinking);
-      ShowThinkingEvent(); // [HGM] thinking: tests four options
-      appData.testLegality         = IS_CHECKED(OPT_TestLegality);
-      appData.highlightMoveWithArrow=IS_CHECKED(OPT_HighlightMoveArrow);
-
-#undef IS_CHECKED
-
-      SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
-                  0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-#if AOT_CONSOLE
-      if (hwndConsole) {
-       SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
-                    0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-      }
-#endif
-      if (!appData.highlightLastMove) {
-       ClearHighlights();
-       DrawPosition(FALSE, NULL);
-      }
-      /* 
-       * for some reason the redraw seems smoother when we invalidate
-       * the board rect after the call to EndDialog()
-       */
-      EndDialog(hDlg, TRUE);
-
-      if (oldShowButtonBar != appData.showButtonBar) {
-       InitDrawingSizes(boardSize, 0);
-      } else if ((oldShowCoords != appData.showCoords) || 
-                (oldBlindfold != appData.blindfold)) {
-       InvalidateRect(hwndMain, &boardRect, FALSE);
-      }
-
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID 
-GeneralOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc;
-
-  lpProc = MakeProcInstance((FARPROC)GeneralOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_GeneralOptions), hwnd,
-           (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-/*---------------------------------------------------------------------------*\
- *
- * Board Options Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-const int SAMPLE_SQ_SIZE = 54;
-
-VOID
-ChangeBoardSize(BoardSize newSize)
-{
-  if (newSize != boardSize) {
-    boardSize = newSize;
-    InitDrawingSizes(boardSize, 0);
-  }
-}
-
-VOID
-PaintSampleSquare(
-    HWND     hwnd, 
-    int      ctrlid, 
-    COLORREF squareColor, 
-    COLORREF pieceColor,
-    COLORREF squareOutlineColor,
-    COLORREF pieceDetailColor,
-    BOOL     isWhitePiece,
-    BOOL     isMono,
-    HBITMAP  pieces[3] 
-    )
-{
-  HBRUSH  brushSquare;
-  HBRUSH  brushSquareOutline;
-  HBRUSH  brushPiece;
-  HBRUSH  brushPieceDetail;
-  HBRUSH  oldBrushPiece = NULL;
-  HBRUSH  oldBrushSquare;
-  HBITMAP oldBitmapMem;
-  HBITMAP oldBitmapTemp;
-  HBITMAP bufferBitmap;
-  RECT    rect;
-  HDC     hdcScreen, hdcMem, hdcTemp;
-  HPEN    pen, oldPen;
-  HWND    hCtrl = GetDlgItem(hwnd, ctrlid);
-  int     x, y;
-
-  const int SOLID   = 0;
-  const int WHITE   = 1;
-  const int OUTLINE = 2;
-  const int BORDER  = 4;
-
-  InvalidateRect(hCtrl, NULL, TRUE);
-  UpdateWindow(hCtrl);
-  GetClientRect(hCtrl, &rect);
-  x = rect.left + (BORDER / 2);
-  y = rect.top  + (BORDER / 2);
-  hdcScreen = GetDC(hCtrl);
-  hdcMem  = CreateCompatibleDC(hdcScreen);
-  hdcTemp = CreateCompatibleDC(hdcScreen);
-
-  bufferBitmap = CreateCompatibleBitmap(hdcScreen, rect.right-rect.left+1,
-                                       rect.bottom-rect.top+1);
-  oldBitmapMem = SelectObject(hdcMem, bufferBitmap);
-  if (!isMono) {
-    SelectPalette(hdcMem, hPal, FALSE);
-  }
-  brushSquare         = CreateSolidBrush(squareColor);
-  brushSquareOutline  = CreateSolidBrush(squareOutlineColor);
-  brushPiece          = CreateSolidBrush(pieceColor);
-  brushPieceDetail    = CreateSolidBrush(pieceDetailColor);
-
-  /* 
-   * first draw the rectangle 
-   */
-  pen      = CreatePen(PS_SOLID, BORDER, squareOutlineColor);
-  oldPen   = (HPEN)  SelectObject(hdcMem, pen);
-  oldBrushSquare = (HBRUSH)SelectObject(hdcMem, brushSquare);
-  Rectangle(hdcMem, rect.left, rect.top, rect.right, rect.bottom);
-
-  /* 
-   * now draw the piece
-   */
-  if (isMono) {
-    oldBitmapTemp = SelectObject(hdcTemp, pieces[OUTLINE]);
-    BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, hdcTemp, 0, 0,
-          isWhitePiece ? SRCCOPY : NOTSRCCOPY);
-    SelectObject(hdcTemp, oldBitmapTemp);
-  } else {
-    if (isWhitePiece) {
-      oldBitmapTemp = SelectObject(hdcTemp, pieces[WHITE]);
-      oldBrushPiece = SelectObject(hdcMem, brushPiece);
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
-            hdcTemp, 0, 0, 0x00B8074A);
-      /* Use black for outline of white pieces */
-      SelectObject(hdcTemp, pieces[OUTLINE]);
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
-            hdcTemp, 0, 0, SRCAND);
-    } else {
-      /* Use square color for details of black pieces */
-      oldBitmapTemp = SelectObject(hdcTemp, pieces[SOLID]);
-      oldBrushPiece = SelectObject(hdcMem, brushPiece);
-      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, 
-            hdcTemp, 0, 0, 0x00B8074A);
-    }
-    SelectObject(hdcMem, oldBrushPiece);
-    SelectObject(hdcTemp, oldBitmapTemp);
-  }
-  /* 
-   * copy the memory dc to the screen
-   */
-  SelectObject(hdcMem, bufferBitmap);
-  BitBlt(hdcScreen, rect.left, rect.top,
-        rect.right - rect.left,
-        rect.bottom - rect.top,
-        hdcMem, rect.left, rect.top, SRCCOPY);
-  SelectObject(hdcMem, oldBitmapMem);
-  /* 
-   * clean up
-   */
-  SelectObject(hdcMem, oldBrushPiece);
-  SelectObject(hdcMem, oldPen);
-  DeleteObject(brushPiece);
-  DeleteObject(brushPieceDetail);
-  DeleteObject(brushSquare);
-  DeleteObject(brushSquareOutline);
-  DeleteObject(pen);
-  DeleteDC(hdcTemp);
-  DeleteDC(hdcMem);
-  ReleaseDC(hCtrl, hdcScreen);
-}
-
-
-VOID
-PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color)
-{
-  HDC    hdc;
-  HBRUSH brush, oldBrush;
-  RECT   rect;
-  HWND   hCtrl = GetDlgItem(hwnd, ctrlid);
-
-  hdc = GetDC(hCtrl);
-  InvalidateRect(hCtrl, NULL, TRUE);
-  UpdateWindow(hCtrl);
-  GetClientRect(hCtrl, &rect);
-  brush = CreateSolidBrush(color);
-  oldBrush = (HBRUSH)SelectObject(hdc, brush);
-  Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
-  SelectObject(hdc, oldBrush);
-  DeleteObject(brush);
-  ReleaseDC(hCtrl, hdc);
-}
-
-
-VOID
-SetBoardOptionEnables(HWND hDlg)
-{
-  if (IsDlgButtonChecked(hDlg, OPT_Monochrome)) {
-    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_HIDE);
-    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_HIDE);
-    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_HIDE);
-    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_HIDE);
-
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), FALSE);
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), FALSE);
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), FALSE);
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), FALSE);
-  } else {
-    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_SHOW);
-    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_SHOW);
-    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_SHOW);
-    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_SHOW);
-
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), TRUE);
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), TRUE);
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), TRUE);
-    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), TRUE);
-  }
-}
-
-BoardSize 
-BoardOptionsWhichRadio(HWND hDlg)
-{
-  return (IsDlgButtonChecked(hDlg, OPT_SizeTiny) ? SizeTiny :
-         (IsDlgButtonChecked(hDlg, OPT_SizeTeeny) ? SizeTeeny :
-         (IsDlgButtonChecked(hDlg, OPT_SizeDinky) ? SizeDinky :
-         (IsDlgButtonChecked(hDlg, OPT_SizePetite) ? SizePetite :
-         (IsDlgButtonChecked(hDlg, OPT_SizeSlim) ? SizeSlim :
-         (IsDlgButtonChecked(hDlg, OPT_SizeSmall) ? SizeSmall :
-         (IsDlgButtonChecked(hDlg, OPT_SizeMediocre) ? SizeMediocre :
-         (IsDlgButtonChecked(hDlg, OPT_SizeMiddling) ? SizeMiddling :
-         (IsDlgButtonChecked(hDlg, OPT_SizeAverage) ? SizeAverage :
-         (IsDlgButtonChecked(hDlg, OPT_SizeModerate) ? SizeModerate :
-         (IsDlgButtonChecked(hDlg, OPT_SizeMedium) ? SizeMedium :
-         (IsDlgButtonChecked(hDlg, OPT_SizeBulky) ? SizeBulky :
-         (IsDlgButtonChecked(hDlg, OPT_SizeLarge) ? SizeLarge :
-         (IsDlgButtonChecked(hDlg, OPT_SizeBig) ? SizeBig :
-         (IsDlgButtonChecked(hDlg, OPT_SizeHuge) ? SizeHuge :
-         (IsDlgButtonChecked(hDlg, OPT_SizeGiant) ? SizeGiant :
-         (IsDlgButtonChecked(hDlg, OPT_SizeColossal) ? SizeColossal :
-          SizeTitanic )))))))))))))))));
-}
-
-LRESULT CALLBACK
-BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  static Boolean  mono, white, flip;
-  static BoardSize size;
-  static COLORREF lsc, dsc, wpc, bpc, hsc, phc;
-  static HBITMAP pieces[3];
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    switch (boardSize) {
-    case SizeTiny:
-      CheckDlgButton(hDlg, OPT_SizeTiny, TRUE);
-      break;
-    case SizeTeeny:
-      CheckDlgButton(hDlg, OPT_SizeTeeny, TRUE);
-      break;
-    case SizeDinky:
-      CheckDlgButton(hDlg, OPT_SizeDinky, TRUE);
-      break;
-    case SizePetite:
-      CheckDlgButton(hDlg, OPT_SizePetite, TRUE);
-      break;
-    case SizeSlim:
-      CheckDlgButton(hDlg, OPT_SizeSlim, TRUE);
-      break;
-    case SizeSmall:
-      CheckDlgButton(hDlg, OPT_SizeSmall, TRUE);
-      break;
-    case SizeMediocre:
-      CheckDlgButton(hDlg, OPT_SizeMediocre, TRUE);
-      break;
-    case SizeMiddling:
-      CheckDlgButton(hDlg, OPT_SizeMiddling, TRUE);
-      break;
-    case SizeAverage:
-      CheckDlgButton(hDlg, OPT_SizeAverage, TRUE);
-      break;
-    case SizeModerate:
-      CheckDlgButton(hDlg, OPT_SizeModerate, TRUE);
-      break;
-    case SizeMedium:
-      CheckDlgButton(hDlg, OPT_SizeMedium, TRUE);
-      break;
-    case SizeBulky:
-      CheckDlgButton(hDlg, OPT_SizeBulky, TRUE);
-      break;
-    case SizeLarge:
-      CheckDlgButton(hDlg, OPT_SizeLarge, TRUE);
-      break;
-    case SizeBig:
-      CheckDlgButton(hDlg, OPT_SizeBig, TRUE);
-      break;
-    case SizeHuge:
-      CheckDlgButton(hDlg, OPT_SizeHuge, TRUE);
-      break;
-    case SizeGiant:
-      CheckDlgButton(hDlg, OPT_SizeGiant, TRUE);
-      break;
-    case SizeColossal:
-      CheckDlgButton(hDlg, OPT_SizeColossal, TRUE);
-      break;
-    case SizeTitanic:
-      CheckDlgButton(hDlg, OPT_SizeTitanic, TRUE);
-    default: ; // should not happen, but suppresses warning on pedantic compilers
-    }
-
-    if (appData.monoMode)
-      CheckDlgButton(hDlg, OPT_Monochrome, TRUE);
-
-    if (appData.allWhite)
-      CheckDlgButton(hDlg, OPT_AllWhite, TRUE);
-
-    if (appData.upsideDown)
-      CheckDlgButton(hDlg, OPT_UpsideDown, TRUE);
-
-    pieces[0] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "s");
-    pieces[1] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "w");
-    pieces[2] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "o");
-       
-    lsc = lightSquareColor;
-    dsc = darkSquareColor;
-    wpc = whitePieceColor;
-    bpc = blackPieceColor;
-    hsc = highlightSquareColor;
-    phc = premoveHighlightColor;
-    mono = appData.monoMode;
-    white= appData.allWhite;
-    flip = appData.upsideDown;
-    size = boardSize;
-
-    SetBoardOptionEnables(hDlg);
-    return TRUE;
-
-  case WM_PAINT:
-    PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);
-    PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);
-    PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);
-    PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);
-    PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);
-    PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);
-    PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
-       TRUE, mono, pieces);
-    PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
-       FALSE, mono, pieces);
-
-    return FALSE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* 
-       * if we call EndDialog() after the call to ChangeBoardSize(),
-       * then ChangeBoardSize() does not take effect, although the new
-       * boardSize is saved. Go figure...
-       */
-      EndDialog(hDlg, TRUE);
-
-      size = BoardOptionsWhichRadio(hDlg);
-
-      /*
-       * did any settings change?
-       */
-      if (size != boardSize) {
-       ChangeBoardSize(size);
-      }
-
-      if ((mono != appData.monoMode) ||
-         (lsc  != lightSquareColor) ||
-         (dsc  != darkSquareColor) ||
-         (wpc  != whitePieceColor) ||
-         (bpc  != blackPieceColor) ||
-         (hsc  != highlightSquareColor) ||
-          (flip != appData.upsideDown) ||
-          (white != appData.allWhite) ||
-         (phc  != premoveHighlightColor)) {
-
-         lightSquareColor = lsc;
-         darkSquareColor = dsc;
-         whitePieceColor = wpc;
-         blackPieceColor = bpc;
-         highlightSquareColor = hsc;
-         premoveHighlightColor = phc;
-         appData.monoMode = mono;
-          appData.allWhite = white;
-          appData.upsideDown = flip;
-
-         InitDrawingColors();
-         InitDrawingSizes(boardSize, 0);
-         InvalidateRect(hwndMain, &boardRect, FALSE);
-      }
-      DeleteObject(pieces[0]);
-      DeleteObject(pieces[1]);
-      DeleteObject(pieces[2]);
-      return TRUE;
-
-    case IDCANCEL:
-      DeleteObject(pieces[0]);
-      DeleteObject(pieces[1]);
-      DeleteObject(pieces[2]);
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case OPT_ChooseLightSquareColor:
-      if (ChangeColor(hDlg, &lsc)) 
-       PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);
-       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
-           TRUE, mono, pieces);
-      break;
-
-    case OPT_ChooseDarkSquareColor:
-      if (ChangeColor(hDlg, &dsc)) 
-       PaintColorBlock(hDlg, OPT_DarkSquareColor, dsc);
-       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
-           FALSE, mono, pieces);
-      break;
-
-    case OPT_ChooseWhitePieceColor:
-      if (ChangeColor(hDlg, &wpc)) 
-       PaintColorBlock(hDlg, OPT_WhitePieceColor, wpc);
-       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
-           TRUE, mono, pieces);
-      break;
-
-    case OPT_ChooseBlackPieceColor:
-      if (ChangeColor(hDlg, &bpc)) 
-       PaintColorBlock(hDlg, OPT_BlackPieceColor, bpc);
-       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
-           FALSE, mono, pieces);
-      break;
-
-    case OPT_ChooseHighlightSquareColor:
-      if (ChangeColor(hDlg, &hsc)) 
-       PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);
-       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
-           TRUE, mono, pieces);
-      break;
-
-    case OPT_ChoosePremoveHighlightColor:
-      if (ChangeColor(hDlg, &phc)) 
-       PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);
-       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
-           FALSE, mono, pieces);
-      break;
-
-    case OPT_DefaultBoardColors:
-      lsc = ParseColorName(LIGHT_SQUARE_COLOR);
-      dsc = ParseColorName(DARK_SQUARE_COLOR);
-      wpc = ParseColorName(WHITE_PIECE_COLOR);
-      bpc = ParseColorName(BLACK_PIECE_COLOR);
-      hsc = ParseColorName(HIGHLIGHT_SQUARE_COLOR);
-      phc = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);
-      mono = FALSE;
-      white= FALSE;
-      flip = FALSE;
-      CheckDlgButton(hDlg, OPT_Monochrome, FALSE);
-      CheckDlgButton(hDlg, OPT_AllWhite,   FALSE);
-      CheckDlgButton(hDlg, OPT_UpsideDown, FALSE);
-      PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);
-      PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);
-      PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);
-      PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);
-      PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);
-      PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);
-      SetBoardOptionEnables(hDlg);
-      PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,
-         TRUE, mono, pieces);
-      PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,
-         FALSE, mono, pieces);
-      break;
-
-    case OPT_Monochrome:
-      mono = !mono;
-      SetBoardOptionEnables(hDlg);
-      break;
-
-    case OPT_AllWhite:
-      white = !white;
-      SetBoardOptionEnables(hDlg);
-      break;
-
-    case OPT_UpsideDown:
-      flip = !flip;
-      SetBoardOptionEnables(hDlg);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-
-VOID
-BoardOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)BoardOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_BoardOptions), hwnd,
-         (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-VariantClass
-VariantWhichRadio(HWND hDlg)
-{
-  return (IsDlgButtonChecked(hDlg, OPT_VariantFairy) ? VariantFairy :
-         (IsDlgButtonChecked(hDlg, OPT_VariantGothic) ? VariantGothic :
-         (IsDlgButtonChecked(hDlg, OPT_VariantCrazyhouse) ? VariantCrazyhouse :
-         (IsDlgButtonChecked(hDlg, OPT_VariantBughouse) ? VariantBughouse :
-         (IsDlgButtonChecked(hDlg, OPT_VariantCourier) ? VariantCourier :
-         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :
-         (IsDlgButtonChecked(hDlg, OPT_VariantShogi) ? VariantShogi :
-         (IsDlgButtonChecked(hDlg, OPT_VariantXiangqi) ? VariantXiangqi :
-         (IsDlgButtonChecked(hDlg, OPT_VariantCapablanca) ? VariantCapablanca :
-         (IsDlgButtonChecked(hDlg, OPT_VariantTwoKings) ? VariantTwoKings :
-         (IsDlgButtonChecked(hDlg, OPT_VariantKnightmate) ? VariantKnightmate :
-         (IsDlgButtonChecked(hDlg, OPT_VariantLosers) ? VariantLosers :
-         (IsDlgButtonChecked(hDlg, OPT_VariantSuicide) ? VariantSuicide :
-         (IsDlgButtonChecked(hDlg, OPT_VariantAtomic) ? VariantAtomic :
-         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :
-         (IsDlgButtonChecked(hDlg, OPT_VariantFRC) ? VariantFischeRandom :
-         (IsDlgButtonChecked(hDlg, OPT_VariantCylinder) ? VariantCylinder :
-         (IsDlgButtonChecked(hDlg, OPT_VariantFalcon) ? VariantFalcon :
-         (IsDlgButtonChecked(hDlg, OPT_VariantCRC) ? VariantCapaRandom :
-         (IsDlgButtonChecked(hDlg, OPT_VariantSuper) ? VariantSuper :
-         (IsDlgButtonChecked(hDlg, OPT_VariantBerolina) ? VariantBerolina :
-         (IsDlgButtonChecked(hDlg, OPT_VariantJanus) ? VariantJanus :
-         (IsDlgButtonChecked(hDlg, OPT_VariantWildcastle) ? VariantWildCastle :
-         (IsDlgButtonChecked(hDlg, OPT_VariantNocastle) ? VariantNoCastle :
-         (IsDlgButtonChecked(hDlg, OPT_Variant3Check) ? Variant3Check :
-         (IsDlgButtonChecked(hDlg, OPT_VariantGreat) ? VariantGreat :
-         (IsDlgButtonChecked(hDlg, OPT_VariantGiveaway) ? VariantGiveaway :
-         (IsDlgButtonChecked(hDlg, OPT_VariantTwilight) ? VariantTwilight :
-          VariantNormal ))))))))))))))))))))))))))));
-}
-
-LRESULT CALLBACK
-NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  static VariantClass v;
-  static int n1_ok, n2_ok, n3_ok;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    switch (gameInfo.variant) {
-    case VariantNormal:
-      CheckDlgButton(hDlg, OPT_VariantNormal, TRUE);
-      break;
-    case VariantCrazyhouse:
-      CheckDlgButton(hDlg, OPT_VariantCrazyhouse, TRUE);
-      break;
-    case VariantBughouse:
-      CheckDlgButton(hDlg, OPT_VariantBughouse, TRUE);
-      break;
-    case VariantShogi:
-      CheckDlgButton(hDlg, OPT_VariantShogi, TRUE);
-      break;
-    case VariantXiangqi:
-      CheckDlgButton(hDlg, OPT_VariantXiangqi, TRUE);
-      break;
-    case VariantCapablanca:
-      CheckDlgButton(hDlg, OPT_VariantCapablanca, TRUE);
-      break;
-    case VariantGothic:
-      CheckDlgButton(hDlg, OPT_VariantGothic, TRUE);
-      break;
-    case VariantCourier:
-      CheckDlgButton(hDlg, OPT_VariantCourier, TRUE);
-      break;
-    case VariantKnightmate:
-      CheckDlgButton(hDlg, OPT_VariantKnightmate, TRUE);
-      break;
-    case VariantTwoKings:
-      CheckDlgButton(hDlg, OPT_VariantTwoKings, TRUE);
-      break;
-    case VariantFairy:
-      CheckDlgButton(hDlg, OPT_VariantFairy, TRUE);
-      break;
-    case VariantAtomic:
-      CheckDlgButton(hDlg, OPT_VariantAtomic, TRUE);
-      break;
-    case VariantSuicide:
-      CheckDlgButton(hDlg, OPT_VariantSuicide, TRUE);
-      break;
-    case VariantLosers:
-      CheckDlgButton(hDlg, OPT_VariantLosers, TRUE);
-      break;
-    case VariantShatranj:
-      CheckDlgButton(hDlg, OPT_VariantShatranj, TRUE);
-      break;
-    case VariantFischeRandom:
-      CheckDlgButton(hDlg, OPT_VariantFRC, TRUE);
-      break;
-    case VariantCapaRandom:
-      CheckDlgButton(hDlg, OPT_VariantCRC, TRUE);
-      break;
-    case VariantFalcon:
-      CheckDlgButton(hDlg, OPT_VariantFalcon, TRUE);
-      break;
-    case VariantCylinder:
-      CheckDlgButton(hDlg, OPT_VariantCylinder, TRUE);
-      break;
-    case Variant3Check:
-      CheckDlgButton(hDlg, OPT_Variant3Check, TRUE);
-      break;
-    case VariantSuper:
-      CheckDlgButton(hDlg, OPT_VariantSuper, TRUE);
-      break;
-    case VariantBerolina:
-      CheckDlgButton(hDlg, OPT_VariantBerolina, TRUE);
-      break;
-    case VariantJanus:
-      CheckDlgButton(hDlg, OPT_VariantJanus, TRUE);
-      break;
-    case VariantWildCastle:
-      CheckDlgButton(hDlg, OPT_VariantWildcastle, TRUE);
-      break;
-    case VariantNoCastle:
-      CheckDlgButton(hDlg, OPT_VariantNocastle, TRUE);
-      break;
-    case VariantGreat:
-      CheckDlgButton(hDlg, OPT_VariantGreat, TRUE);
-      break;
-    case VariantGiveaway:
-      CheckDlgButton(hDlg, OPT_VariantGiveaway, TRUE);
-      break;
-    case VariantTwilight:
-      CheckDlgButton(hDlg, OPT_VariantTwilight, TRUE);
-      break;
-    default: ;
-    }
-
-    SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );
-    SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );
-
-    SetDlgItemInt( hDlg, IDC_Ranks, -1, TRUE );
-    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );
-
-    SetDlgItemInt( hDlg, IDC_Holdings, -1, TRUE );
-    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );
-
-    n1_ok = n2_ok = n3_ok = FALSE;
-
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* 
-       * if we call EndDialog() after the call to ChangeBoardSize(),
-       * then ChangeBoardSize() does not take effect, although the new
-       * boardSize is saved. Go figure...
-       */
-      EndDialog(hDlg, TRUE);
-
-      v = VariantWhichRadio(hDlg);
-      if(!appData.noChessProgram) { char *name = VariantName(v), buf[MSG_SIZ];
-       if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {
-           /* [HGM] in protocol 2 we check if variant is suported by engine */
-           sprintf(buf, "Variant %s not supported by %s", name, first.tidy);
-           DisplayError(buf, 0);
-           return TRUE; /* treat as "Cancel" if first engine does not support it */
-       } else
-       if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {
-           sprintf(buf, "Warning: second engine (%s) does not support this!", second.tidy);
-           DisplayError(buf, 0);   /* use of second engine is optional; only warn user */
-       }
-      }
-
-      gameInfo.variant = v;
-      appData.variant = VariantName(v);
-
-      appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );
-      appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );
-      appData.holdingsSize = (int) GetDlgItemInt(hDlg, IDC_Holdings, NULL, FALSE );
-
-      if(!n1_ok) appData.NrFiles = -1;
-      if(!n2_ok) appData.NrRanks = -1;
-      if(!n3_ok) appData.holdingsSize = -1;
-
-      shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */
-      startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */
-      appData.pieceToCharTable = NULL;
-      Reset(TRUE, TRUE);
-
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case IDC_Ranks:
-    case IDC_Files:
-    case IDC_Holdings:
-        if( HIWORD(wParam) == EN_CHANGE ) {
-
-            GetDlgItemInt(hDlg, IDC_Files, &n1_ok, FALSE );
-            GetDlgItemInt(hDlg, IDC_Ranks, &n2_ok, FALSE );
-            GetDlgItemInt(hDlg, IDC_Holdings, &n3_ok, FALSE );
-
-            /*EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok ? TRUE : FALSE );*/
-        }
-        return TRUE;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-
-VOID
-NewVariantPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)NewVariantDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_NewVariant), hwnd,
-         (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * ICS Options Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-BOOL APIENTRY
-MyCreateFont(HWND hwnd, MyFont *font)
-{
-  CHOOSEFONT cf;
-  HFONT hf;
-
-  /* Initialize members of the CHOOSEFONT structure. */
-  cf.lStructSize = sizeof(CHOOSEFONT);
-  cf.hwndOwner = hwnd;
-  cf.hDC = (HDC)NULL;
-  cf.lpLogFont = &font->lf;
-  cf.iPointSize = 0;
-  cf.Flags = CF_SCREENFONTS|/*CF_ANSIONLY|*/CF_INITTOLOGFONTSTRUCT;
-  cf.rgbColors = RGB(0,0,0);
-  cf.lCustData = 0L;
-  cf.lpfnHook = (LPCFHOOKPROC)NULL;
-  cf.lpTemplateName = (LPSTR)NULL;
-  cf.hInstance = (HINSTANCE) NULL;
-  cf.lpszStyle = (LPSTR)NULL;
-  cf.nFontType = SCREEN_FONTTYPE;
-  cf.nSizeMin = 0;
-  cf.nSizeMax = 0;
-
-  /* Display the CHOOSEFONT common-dialog box. */
-  if (!ChooseFont(&cf)) {
-    return FALSE;
-  }
-
-  /* Create a logical font based on the user's   */
-  /* selection and return a handle identifying   */
-  /* that font. */
-  hf = CreateFontIndirect(cf.lpLogFont);
-  if (hf == NULL) {
-    return FALSE;
-  }
-
-  font->hf = hf;
-  font->mfp.pointSize = (float) (cf.iPointSize / 10.0);
-  font->mfp.bold = (font->lf.lfWeight >= FW_BOLD);
-  font->mfp.italic = font->lf.lfItalic;
-  font->mfp.underline = font->lf.lfUnderline;
-  font->mfp.strikeout = font->lf.lfStrikeOut;
-  font->mfp.charset = font->lf.lfCharSet;
-  strcpy(font->mfp.faceName, font->lf.lfFaceName);
-  return TRUE;
-}
-
-
-VOID
-UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca)
-{
-  CHARFORMAT cf;
-  cf.cbSize = sizeof(CHARFORMAT);
-  cf.dwMask = 
-    CFM_COLOR|CFM_CHARSET|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE;
-  cf.crTextColor = mca->color;
-  cf.dwEffects = mca->effects;
-  strcpy(cf.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName);
-  /* 
-   * The 20.0 below is in fact documented. yHeight is expressed in twips.
-   * A twip is 1/20 of a font's point size. See documentation of CHARFORMAT.
-   * --msw
-   */
-  cf.yHeight = (int)(font[boardSize][CONSOLE_FONT]->mfp.pointSize * 20.0 + 0.5);
-  cf.bCharSet = DEFAULT_CHARSET; /* should be ignored anyway */
-  cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
-  SendDlgItemMessage(hDlg, id, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
-}
-
-LRESULT CALLBACK
-ColorizeTextDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  static MyColorizeAttribs mca;
-  static ColorClass cc;
-  COLORREF background = (COLORREF)0;
-
-  switch (message) {
-  case WM_INITDIALOG:
-    cc = (ColorClass)lParam;
-    mca = colorizeAttribs[cc];
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    CheckDlgButton(hDlg, OPT_Bold, (mca.effects & CFE_BOLD) != 0);
-    CheckDlgButton(hDlg, OPT_Italic, (mca.effects & CFE_ITALIC) != 0);
-    CheckDlgButton(hDlg, OPT_Underline, (mca.effects & CFE_UNDERLINE) != 0);
-    CheckDlgButton(hDlg, OPT_Strikeout, (mca.effects & CFE_STRIKEOUT) != 0);
-
-    /* get the current background color from the parent window */
-    SendMessage(GetWindow(hDlg, GW_OWNER),WM_COMMAND, 
-               (WPARAM)WM_USER_GetConsoleBackground, 
-               (LPARAM)&background);
-
-    /* set the background color */
-    SendDlgItemMessage(hDlg, OPT_Sample, EM_SETBKGNDCOLOR, FALSE, background);
-
-    SetDlgItemText(hDlg, OPT_Sample, mca.name);
-    UpdateSampleText(hDlg, OPT_Sample, &mca);
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-      colorizeAttribs[cc] = mca;
-      textAttribs[cc].color = mca.color;
-      textAttribs[cc].effects = mca.effects;
-      Colorize(currentColorClass, TRUE);
-      if (cc == ColorNormal) {
-       CHARFORMAT cf;
-       cf.cbSize = sizeof(CHARFORMAT);
-       cf.dwMask = CFM_COLOR;
-       cf.crTextColor = mca.color;
-       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
-         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
-      }
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case OPT_ChooseColor:
-      ChangeColor(hDlg, &mca.color);
-      UpdateSampleText(hDlg, OPT_Sample, &mca);
-      return TRUE;
-
-    default:
-      mca.effects =
-       (IsDlgButtonChecked(hDlg, OPT_Bold) ? CFE_BOLD : 0) |
-       (IsDlgButtonChecked(hDlg, OPT_Italic) ? CFE_ITALIC : 0) |
-       (IsDlgButtonChecked(hDlg, OPT_Underline) ? CFE_UNDERLINE : 0) |
-       (IsDlgButtonChecked(hDlg, OPT_Strikeout) ? CFE_STRIKEOUT : 0);
-      UpdateSampleText(hDlg, OPT_Sample, &mca);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID
-ColorizeTextPopup(HWND hwnd, ColorClass cc)
-{
-  FARPROC lpProc;
-
-  lpProc = MakeProcInstance((FARPROC)ColorizeTextDialog, hInst);
-  DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_Colorize),
-    hwnd, (DLGPROC)lpProc, (LPARAM) cc);
-  FreeProcInstance(lpProc);
-}
-
-VOID
-SetIcsOptionEnables(HWND hDlg)
-{
-#define ENABLE_DLG_ITEM(x,y) EnableWindow(GetDlgItem(hDlg,(x)), (y))
-
-  UINT state = IsDlgButtonChecked(hDlg, OPT_Premove);
-  ENABLE_DLG_ITEM(OPT_PremoveWhite, state);
-  ENABLE_DLG_ITEM(OPT_PremoveWhiteText, state);
-  ENABLE_DLG_ITEM(OPT_PremoveBlack, state);
-  ENABLE_DLG_ITEM(OPT_PremoveBlackText, state);
-
-  ENABLE_DLG_ITEM(OPT_IcsAlarmTime, IsDlgButtonChecked(hDlg, OPT_IcsAlarm));
-
-#undef ENABLE_DLG_ITEM
-}
-
-
-LRESULT CALLBACK
-IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  char buf[MSG_SIZ];
-  int number;
-  int i;
-  static COLORREF cbc;
-  static MyColorizeAttribs *mca;
-  COLORREF *colorref;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-
-    mca = colorizeAttribs;
-
-    for (i=0; i < NColorClasses - 1; i++) {
-      mca[i].color   = textAttribs[i].color;
-      mca[i].effects = textAttribs[i].effects;
-    }
-    cbc = consoleBackgroundColor;
-
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-
-    /* Initialize the dialog items */
-#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))
-
-    CHECK_BOX(OPT_AutoComment, appData.autoComment);
-    CHECK_BOX(OPT_AutoObserve, appData.autoObserve);
-    CHECK_BOX(OPT_GetMoveList, appData.getMoveList);
-    CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);
-    CHECK_BOX(OPT_QuietPlay, appData.quietPlay);
-    CHECK_BOX(OPT_Premove, appData.premove);
-    CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);
-    CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);
-    CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);
-    CHECK_BOX(OPT_DontColorize, !appData.colorize);
-
-#undef CHECK_BOX
-
-    sprintf(buf, "%d", appData.icsAlarmTime / 1000);
-    SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);
-    SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);
-    SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);
-
-    SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);
-    SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);
-
-    SetDlgItemText(hDlg, OPT_SampleShout,     mca[ColorShout].name);
-    SetDlgItemText(hDlg, OPT_SampleSShout,    mca[ColorSShout].name);
-    SetDlgItemText(hDlg, OPT_SampleChannel1,  mca[ColorChannel1].name);
-    SetDlgItemText(hDlg, OPT_SampleChannel,   mca[ColorChannel].name);
-    SetDlgItemText(hDlg, OPT_SampleKibitz,    mca[ColorKibitz].name);
-    SetDlgItemText(hDlg, OPT_SampleTell,      mca[ColorTell].name);
-    SetDlgItemText(hDlg, OPT_SampleChallenge, mca[ColorChallenge].name);
-    SetDlgItemText(hDlg, OPT_SampleRequest,   mca[ColorRequest].name);
-    SetDlgItemText(hDlg, OPT_SampleSeek,      mca[ColorSeek].name);
-    SetDlgItemText(hDlg, OPT_SampleNormal,    mca[ColorNormal].name);
-
-    UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);
-    UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);
-    UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);
-    UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);
-    UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);
-    UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);
-    UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);
-    UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);
-    UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);
-    UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);
-
-    SetIcsOptionEnables(hDlg);
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-
-    case WM_USER_GetConsoleBackground: 
-      /* the ColorizeTextDialog needs the current background color */
-      colorref = (COLORREF *)lParam;
-      *colorref = cbc;
-      return FALSE;
-
-    case IDOK:
-      /* Read changed options from the dialog box */
-      GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);
-      if (sscanf(buf, "%d", &number) != 1 || (number < 0)){
-         MessageBox(hDlg, "Invalid ICS Alarm Time",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-      }
-
-#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))
-
-      appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);
-      appData.premove          = IS_CHECKED(OPT_Premove);
-      appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);
-      appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);
-      appData.autoComment      = IS_CHECKED(OPT_AutoComment);
-      appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);
-      appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);
-      appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);
-      appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);
-
-#undef IS_CHECKED
-
-      appData.icsAlarmTime = number * 1000;
-      GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);
-      GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);
-
-      if (appData.localLineEditing) {
-       DontEcho();
-       EchoOn();
-      } else {
-       DoEcho();
-       EchoOff();
-      }
-
-      appData.colorize =
-       (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);
-
+/*\r
+ * woptions.c -- Options dialog box routines for WinBoard\r
+ *\r
+ * Copyright 2000,2009 Free Software Foundation, Inc.\r
+ *\r
+ * Enhancements Copyright 2005 Alessandro Scotti\r
+ *\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
+#include "config.h"\r
+\r
+#include <windows.h>   /* required for all Windows applications */\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <shlobj.h>    /* [AS] Requires NT 4.0 or Win95 */\r
+#include <ctype.h>\r
+\r
+#include "common.h"\r
+#include "frontend.h"\r
+#include "winboard.h"\r
+#include "backend.h"\r
+#include "woptions.h"\r
+#include "defaults.h"\r
+#include <richedit.h>\r
+\r
+#if __GNUC__\r
+#include <errno.h>\r
+#include <string.h>\r
+#endif\r
+\r
+/* Imports from winboard.c */\r
+\r
+extern MyFont *font[NUM_SIZES][NUM_FONTS];\r
+extern HINSTANCE hInst;          /* current instance */\r
+extern HWND hwndMain;            /* root window*/\r
+extern BOOLEAN alwaysOnTop;\r
+extern RECT boardRect;\r
+extern COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
+  blackPieceColor, highlightSquareColor, premoveHighlightColor;\r
+extern HPALETTE hPal;\r
+extern BoardSize boardSize;\r
+extern COLORREF consoleBackgroundColor;\r
+extern MyColorizeAttribs colorizeAttribs[]; /* do I need the size? */\r
+extern MyTextAttribs textAttribs[];\r
+extern MySound sounds[];\r
+extern ColorClass currentColorClass;\r
+extern HWND hwndConsole;\r
+extern char *defaultTextAttribs[];\r
+extern HWND commentDialog;\r
+extern HWND moveHistoryDialog;\r
+extern HWND engineOutputDialog;\r
+extern char installDir[];\r
+extern HWND hCommPort;    /* currently open comm port */\r
+extern DCB dcb;\r
+extern BOOLEAN chessProgram;\r
+extern int startedFromPositionFile; /* [HGM] loadPos */\r
+extern int searchTime;\r
+\r
+/* types */\r
+\r
+typedef struct {\r
+  char *label;\r
+  unsigned value;\r
+} ComboData;\r
+\r
+typedef struct {\r
+  char *label;\r
+  char *name;\r
+} SoundComboData;\r
+\r
+/* module prototypes */\r
+\r
+LRESULT CALLBACK GeneralOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK BoardOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK NewVariant(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK IcsOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK FontOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK CommPortOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK LoadOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK SaveOptions(HWND, UINT, WPARAM, LPARAM);\r
+LRESULT CALLBACK TimeControl(HWND, UINT, WPARAM, LPARAM);\r
+VOID ChangeBoardSize(BoardSize newSize);\r
+VOID PaintSampleSquare(\r
+    HWND     hwnd, \r
+    int      ctrlid, \r
+    COLORREF squareColor, \r
+    COLORREF pieceColor,\r
+    COLORREF squareOutlineColor,\r
+    COLORREF pieceDetailColor,\r
+    BOOL     isWhitePiece,\r
+    BOOL     isMono,\r
+    HBITMAP  pieces[3] \r
+    );\r
+VOID PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color);\r
+VOID SetBoardOptionEnables(HWND hDlg);\r
+BoardSize BoardOptionsWhichRadio(HWND hDlg);\r
+BOOL APIENTRY MyCreateFont(HWND hwnd, MyFont *font);\r
+VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);\r
+LRESULT CALLBACK ColorizeTextDialog(HWND , UINT, WPARAM, LPARAM);\r
+VOID ColorizeTextPopup(HWND hwnd, ColorClass cc);\r
+VOID SetIcsOptionEnables(HWND hDlg);\r
+VOID SetSampleFontText(HWND hwnd, int id, const MyFont *mf);\r
+VOID CopyFont(MyFont *dest, const MyFont *src);\r
+void InitSoundComboData(SoundComboData *scd);\r
+void ResetSoundComboData(SoundComboData *scd);\r
+void InitSoundCombo(HWND hwndCombo, SoundComboData *scd);\r
+int SoundDialogWhichRadio(HWND hDlg);\r
+VOID SoundDialogSetEnables(HWND hDlg, int radio);\r
+char * SoundDialogGetName(HWND hDlg, int radio);\r
+void DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name);\r
+VOID ParseCommSettings(char *arg, DCB *dcb);\r
+VOID PrintCommSettings(FILE *f, char *name, DCB *dcb);\r
+void InitCombo(HANDLE hwndCombo, ComboData *cd);\r
+void SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value);\r
+VOID SetLoadOptionEnables(HWND hDlg);\r
+VOID SetSaveOptionEnables(HWND hDlg);\r
+VOID SetTimeControlEnables(HWND hDlg);\r
+void NewSettingEvent(int option, char *command, int value);\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * General Options Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+\r
+LRESULT CALLBACK\r
+GeneralOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  static Boolean oldShowCoords;\r
+  static Boolean oldBlindfold;\r
+  static Boolean oldShowButtonBar;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    oldShowCoords = appData.showCoords;\r
+    oldBlindfold  = appData.blindfold;\r
+    oldShowButtonBar = appData.showButtonBar;\r
+\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+\r
+    /* Initialize the dialog items */\r
+#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
+\r
+    CHECK_BOX(OPT_AlwaysOnTop, alwaysOnTop);\r
+    CHECK_BOX(OPT_AlwaysQueen, appData.alwaysPromoteToQueen);\r
+    CHECK_BOX(OPT_AnimateDragging, appData.animateDragging);\r
+    CHECK_BOX(OPT_AnimateMoving, appData.animate);\r
+    CHECK_BOX(OPT_AutoFlag, appData.autoCallFlag);\r
+    CHECK_BOX(OPT_AutoFlipView, appData.autoFlipView);\r
+    CHECK_BOX(OPT_AutoRaiseBoard, appData.autoRaiseBoard);\r
+    CHECK_BOX(OPT_Blindfold, appData.blindfold);\r
+    CHECK_BOX(OPT_HighlightDragging, appData.highlightDragging);\r
+    CHECK_BOX(OPT_HighlightLastMove, appData.highlightLastMove);\r
+    CHECK_BOX(OPT_PeriodicUpdates, appData.periodicUpdates);\r
+    CHECK_BOX(OPT_PonderNextMove, appData.ponderNextMove);\r
+    CHECK_BOX(OPT_PopupExitMessage, appData.popupExitMessage);\r
+    CHECK_BOX(OPT_PopupMoveErrors, appData.popupMoveErrors);\r
+    CHECK_BOX(OPT_ShowButtonBar, appData.showButtonBar);\r
+    CHECK_BOX(OPT_ShowCoordinates, appData.showCoords);\r
+    CHECK_BOX(OPT_ShowThinking, appData.showThinking);\r
+    CHECK_BOX(OPT_TestLegality, appData.testLegality);\r
+    CHECK_BOX(OPT_HideThinkFromHuman, appData.hideThinkingFromHuman);\r
+    CHECK_BOX(OPT_SaveExtPGN, appData.saveExtendedInfoInPGN);\r
+    CHECK_BOX(OPT_ExtraInfoInMoveHistory, appData.showEvalInMoveHistory);\r
+    CHECK_BOX(OPT_HighlightMoveArrow, appData.highlightMoveWithArrow);\r
+\r
+#undef CHECK_BOX\r
+\r
+    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlag),\r
+                appData.icsActive || !appData.noChessProgram);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_AutoFlipView),\r
+                appData.icsActive || !appData.noChessProgram);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_PonderNextMove),\r
+                !appData.noChessProgram);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_PeriodicUpdates), \r
+                !appData.noChessProgram && !appData.icsActive);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ShowThinking), \r
+                !appData.noChessProgram);\r
+    return TRUE;\r
+\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+      \r
+#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
+\r
+      alwaysOnTop                  = IS_CHECKED(OPT_AlwaysOnTop);\r
+      appData.alwaysPromoteToQueen = IS_CHECKED(OPT_AlwaysQueen);\r
+      appData.animateDragging      = IS_CHECKED(OPT_AnimateDragging);\r
+      appData.animate              = IS_CHECKED(OPT_AnimateMoving);\r
+      appData.autoCallFlag         = IS_CHECKED(OPT_AutoFlag);\r
+      appData.autoFlipView         = IS_CHECKED(OPT_AutoFlipView);\r
+      appData.autoRaiseBoard       = IS_CHECKED(OPT_AutoRaiseBoard);\r
+      appData.blindfold            = IS_CHECKED(OPT_Blindfold);\r
+      appData.highlightDragging    = IS_CHECKED(OPT_HighlightDragging);\r
+      appData.highlightLastMove    = IS_CHECKED(OPT_HighlightLastMove);\r
+      PeriodicUpdatesEvent(          IS_CHECKED(OPT_PeriodicUpdates));\r
+      PonderNextMoveEvent(           IS_CHECKED(OPT_PonderNextMove));\r
+      appData.popupExitMessage     = IS_CHECKED(OPT_PopupExitMessage);\r
+      appData.popupMoveErrors      = IS_CHECKED(OPT_PopupMoveErrors);\r
+      appData.showButtonBar        = IS_CHECKED(OPT_ShowButtonBar);\r
+      appData.showCoords           = IS_CHECKED(OPT_ShowCoordinates);\r
+      // [HGM] thinking: next three moved up\r
+      appData.saveExtendedInfoInPGN= IS_CHECKED(OPT_SaveExtPGN);\r
+      appData.hideThinkingFromHuman= IS_CHECKED(OPT_HideThinkFromHuman);\r
+      appData.showEvalInMoveHistory= IS_CHECKED(OPT_ExtraInfoInMoveHistory);\r
+      appData.showThinking         = IS_CHECKED(OPT_ShowThinking);\r
+      ShowThinkingEvent(); // [HGM] thinking: tests four options\r
+      appData.testLegality         = IS_CHECKED(OPT_TestLegality);\r
+      appData.highlightMoveWithArrow=IS_CHECKED(OPT_HighlightMoveArrow);\r
+\r
+#undef IS_CHECKED\r
+\r
+      SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
+                  0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
+#if AOT_CONSOLE\r
+      if (hwndConsole) {\r
+       SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
+                    0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
+      }\r
+#endif\r
+      if (!appData.highlightLastMove) {\r
+       ClearHighlights();\r
+       DrawPosition(FALSE, NULL);\r
+      }\r
+      /* \r
+       * for some reason the redraw seems smoother when we invalidate\r
+       * the board rect after the call to EndDialog()\r
+       */\r
+      EndDialog(hDlg, TRUE);\r
+\r
+      if (oldShowButtonBar != appData.showButtonBar) {\r
+       InitDrawingSizes(boardSize, 0);\r
+      } else if ((oldShowCoords != appData.showCoords) || \r
+                (oldBlindfold != appData.blindfold)) {\r
+       InvalidateRect(hwndMain, &boardRect, FALSE);\r
+      }\r
+\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID \r
+GeneralOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc;\r
+\r
+  lpProc = MakeProcInstance((FARPROC)GeneralOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_GeneralOptions), hwnd,\r
+           (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Board Options Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+const int SAMPLE_SQ_SIZE = 54;\r
+\r
+VOID\r
+ChangeBoardSize(BoardSize newSize)\r
+{\r
+  if (newSize != boardSize) {\r
+    boardSize = newSize;\r
+    InitDrawingSizes(boardSize, 0);\r
+  }\r
+}\r
+\r
+VOID\r
+PaintSampleSquare(\r
+    HWND     hwnd, \r
+    int      ctrlid, \r
+    COLORREF squareColor, \r
+    COLORREF pieceColor,\r
+    COLORREF squareOutlineColor,\r
+    COLORREF pieceDetailColor,\r
+    BOOL     isWhitePiece,\r
+    BOOL     isMono,\r
+    HBITMAP  pieces[3] \r
+    )\r
+{\r
+  HBRUSH  brushSquare;\r
+  HBRUSH  brushSquareOutline;\r
+  HBRUSH  brushPiece;\r
+  HBRUSH  brushPieceDetail;\r
+  HBRUSH  oldBrushPiece = NULL;\r
+  HBRUSH  oldBrushSquare;\r
+  HBITMAP oldBitmapMem;\r
+  HBITMAP oldBitmapTemp;\r
+  HBITMAP bufferBitmap;\r
+  RECT    rect;\r
+  HDC     hdcScreen, hdcMem, hdcTemp;\r
+  HPEN    pen, oldPen;\r
+  HWND    hCtrl = GetDlgItem(hwnd, ctrlid);\r
+  int     x, y;\r
+\r
+  const int SOLID   = 0;\r
+  const int WHITE   = 1;\r
+  const int OUTLINE = 2;\r
+  const int BORDER  = 4;\r
+\r
+  InvalidateRect(hCtrl, NULL, TRUE);\r
+  UpdateWindow(hCtrl);\r
+  GetClientRect(hCtrl, &rect);\r
+  x = rect.left + (BORDER / 2);\r
+  y = rect.top  + (BORDER / 2);\r
+  hdcScreen = GetDC(hCtrl);\r
+  hdcMem  = CreateCompatibleDC(hdcScreen);\r
+  hdcTemp = CreateCompatibleDC(hdcScreen);\r
+\r
+  bufferBitmap = CreateCompatibleBitmap(hdcScreen, rect.right-rect.left+1,\r
+                                       rect.bottom-rect.top+1);\r
+  oldBitmapMem = SelectObject(hdcMem, bufferBitmap);\r
+  if (!isMono) {\r
+    SelectPalette(hdcMem, hPal, FALSE);\r
+  }\r
+  brushSquare         = CreateSolidBrush(squareColor);\r
+  brushSquareOutline  = CreateSolidBrush(squareOutlineColor);\r
+  brushPiece          = CreateSolidBrush(pieceColor);\r
+  brushPieceDetail    = CreateSolidBrush(pieceDetailColor);\r
+\r
+  /* \r
+   * first draw the rectangle \r
+   */\r
+  pen      = CreatePen(PS_SOLID, BORDER, squareOutlineColor);\r
+  oldPen   = (HPEN)  SelectObject(hdcMem, pen);\r
+  oldBrushSquare = (HBRUSH)SelectObject(hdcMem, brushSquare);\r
+  Rectangle(hdcMem, rect.left, rect.top, rect.right, rect.bottom);\r
+\r
+  /* \r
+   * now draw the piece\r
+   */\r
+  if (isMono) {\r
+    oldBitmapTemp = SelectObject(hdcTemp, pieces[OUTLINE]);\r
+    BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, hdcTemp, 0, 0,\r
+          isWhitePiece ? SRCCOPY : NOTSRCCOPY);\r
+    SelectObject(hdcTemp, oldBitmapTemp);\r
+  } else {\r
+    if (isWhitePiece) {\r
+      oldBitmapTemp = SelectObject(hdcTemp, pieces[WHITE]);\r
+      oldBrushPiece = SelectObject(hdcMem, brushPiece);\r
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
+            hdcTemp, 0, 0, 0x00B8074A);\r
+      /* Use black for outline of white pieces */\r
+      SelectObject(hdcTemp, pieces[OUTLINE]);\r
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
+            hdcTemp, 0, 0, SRCAND);\r
+    } else {\r
+      /* Use square color for details of black pieces */\r
+      oldBitmapTemp = SelectObject(hdcTemp, pieces[SOLID]);\r
+      oldBrushPiece = SelectObject(hdcMem, brushPiece);\r
+      BitBlt(hdcMem, x, y, SAMPLE_SQ_SIZE, SAMPLE_SQ_SIZE, \r
+            hdcTemp, 0, 0, 0x00B8074A);\r
+    }\r
+    SelectObject(hdcMem, oldBrushPiece);\r
+    SelectObject(hdcTemp, oldBitmapTemp);\r
+  }\r
+  /* \r
+   * copy the memory dc to the screen\r
+   */\r
+  SelectObject(hdcMem, bufferBitmap);\r
+  BitBlt(hdcScreen, rect.left, rect.top,\r
+        rect.right - rect.left,\r
+        rect.bottom - rect.top,\r
+        hdcMem, rect.left, rect.top, SRCCOPY);\r
+  SelectObject(hdcMem, oldBitmapMem);\r
+  /* \r
+   * clean up\r
+   */\r
+  SelectObject(hdcMem, oldBrushPiece);\r
+  SelectObject(hdcMem, oldPen);\r
+  DeleteObject(brushPiece);\r
+  DeleteObject(brushPieceDetail);\r
+  DeleteObject(brushSquare);\r
+  DeleteObject(brushSquareOutline);\r
+  DeleteObject(pen);\r
+  DeleteDC(hdcTemp);\r
+  DeleteDC(hdcMem);\r
+  ReleaseDC(hCtrl, hdcScreen);\r
+}\r
+\r
+\r
+VOID\r
+PaintColorBlock(HWND hwnd, int ctrlid, COLORREF color)\r
+{\r
+  HDC    hdc;\r
+  HBRUSH brush, oldBrush;\r
+  RECT   rect;\r
+  HWND   hCtrl = GetDlgItem(hwnd, ctrlid);\r
+\r
+  hdc = GetDC(hCtrl);\r
+  InvalidateRect(hCtrl, NULL, TRUE);\r
+  UpdateWindow(hCtrl);\r
+  GetClientRect(hCtrl, &rect);\r
+  brush = CreateSolidBrush(color);\r
+  oldBrush = (HBRUSH)SelectObject(hdc, brush);\r
+  Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);\r
+  SelectObject(hdc, oldBrush);\r
+  DeleteObject(brush);\r
+  ReleaseDC(hCtrl, hdc);\r
+}\r
+\r
+\r
+VOID\r
+SetBoardOptionEnables(HWND hDlg)\r
+{\r
+  if (IsDlgButtonChecked(hDlg, OPT_Monochrome)) {\r
+    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_HIDE);\r
+    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_HIDE);\r
+\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), FALSE);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), FALSE);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), FALSE);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), FALSE);\r
+  } else {\r
+    ShowWindow(GetDlgItem(hDlg, OPT_LightSquareColor), SW_SHOW);\r
+    ShowWindow(GetDlgItem(hDlg, OPT_DarkSquareColor), SW_SHOW);\r
+    ShowWindow(GetDlgItem(hDlg, OPT_WhitePieceColor), SW_SHOW);\r
+    ShowWindow(GetDlgItem(hDlg, OPT_BlackPieceColor), SW_SHOW);\r
+\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseLightSquareColor), TRUE);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseDarkSquareColor), TRUE);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseWhitePieceColor), TRUE);\r
+    EnableWindow(GetDlgItem(hDlg, OPT_ChooseBlackPieceColor), TRUE);\r
+  }\r
+}\r
+\r
+BoardSize \r
+BoardOptionsWhichRadio(HWND hDlg)\r
+{\r
+  return (IsDlgButtonChecked(hDlg, OPT_SizeTiny) ? SizeTiny :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeTeeny) ? SizeTeeny :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeDinky) ? SizeDinky :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizePetite) ? SizePetite :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeSlim) ? SizeSlim :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeSmall) ? SizeSmall :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeMediocre) ? SizeMediocre :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeMiddling) ? SizeMiddling :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeAverage) ? SizeAverage :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeModerate) ? SizeModerate :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeMedium) ? SizeMedium :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeBulky) ? SizeBulky :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeLarge) ? SizeLarge :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeBig) ? SizeBig :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeHuge) ? SizeHuge :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeGiant) ? SizeGiant :\r
+         (IsDlgButtonChecked(hDlg, OPT_SizeColossal) ? SizeColossal :\r
+          SizeTitanic )))))))))))))))));\r
+}\r
+\r
+LRESULT CALLBACK\r
+BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  static Boolean  mono, white, flip;\r
+  static BoardSize size;\r
+  static COLORREF lsc, dsc, wpc, bpc, hsc, phc;\r
+  static HBITMAP pieces[3];\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    switch (boardSize) {\r
+    case SizeTiny:\r
+      CheckDlgButton(hDlg, OPT_SizeTiny, TRUE);\r
+      break;\r
+    case SizeTeeny:\r
+      CheckDlgButton(hDlg, OPT_SizeTeeny, TRUE);\r
+      break;\r
+    case SizeDinky:\r
+      CheckDlgButton(hDlg, OPT_SizeDinky, TRUE);\r
+      break;\r
+    case SizePetite:\r
+      CheckDlgButton(hDlg, OPT_SizePetite, TRUE);\r
+      break;\r
+    case SizeSlim:\r
+      CheckDlgButton(hDlg, OPT_SizeSlim, TRUE);\r
+      break;\r
+    case SizeSmall:\r
+      CheckDlgButton(hDlg, OPT_SizeSmall, TRUE);\r
+      break;\r
+    case SizeMediocre:\r
+      CheckDlgButton(hDlg, OPT_SizeMediocre, TRUE);\r
+      break;\r
+    case SizeMiddling:\r
+      CheckDlgButton(hDlg, OPT_SizeMiddling, TRUE);\r
+      break;\r
+    case SizeAverage:\r
+      CheckDlgButton(hDlg, OPT_SizeAverage, TRUE);\r
+      break;\r
+    case SizeModerate:\r
+      CheckDlgButton(hDlg, OPT_SizeModerate, TRUE);\r
+      break;\r
+    case SizeMedium:\r
+      CheckDlgButton(hDlg, OPT_SizeMedium, TRUE);\r
+      break;\r
+    case SizeBulky:\r
+      CheckDlgButton(hDlg, OPT_SizeBulky, TRUE);\r
+      break;\r
+    case SizeLarge:\r
+      CheckDlgButton(hDlg, OPT_SizeLarge, TRUE);\r
+      break;\r
+    case SizeBig:\r
+      CheckDlgButton(hDlg, OPT_SizeBig, TRUE);\r
+      break;\r
+    case SizeHuge:\r
+      CheckDlgButton(hDlg, OPT_SizeHuge, TRUE);\r
+      break;\r
+    case SizeGiant:\r
+      CheckDlgButton(hDlg, OPT_SizeGiant, TRUE);\r
+      break;\r
+    case SizeColossal:\r
+      CheckDlgButton(hDlg, OPT_SizeColossal, TRUE);\r
+      break;\r
+    case SizeTitanic:\r
+      CheckDlgButton(hDlg, OPT_SizeTitanic, TRUE);\r
+    default: ; // should not happen, but suppresses warning on pedantic compilers\r
+    }\r
+\r
+    if (appData.monoMode)\r
+      CheckDlgButton(hDlg, OPT_Monochrome, TRUE);\r
+\r
+    if (appData.allWhite)\r
+      CheckDlgButton(hDlg, OPT_AllWhite, TRUE);\r
+\r
+    if (appData.upsideDown)\r
+      CheckDlgButton(hDlg, OPT_UpsideDown, TRUE);\r
+\r
+    pieces[0] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "s");\r
+    pieces[1] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "w");\r
+    pieces[2] = DoLoadBitmap(hInst, "n", SAMPLE_SQ_SIZE, "o");\r
+       \r
+    lsc = lightSquareColor;\r
+    dsc = darkSquareColor;\r
+    wpc = whitePieceColor;\r
+    bpc = blackPieceColor;\r
+    hsc = highlightSquareColor;\r
+    phc = premoveHighlightColor;\r
+    mono = appData.monoMode;\r
+    white= appData.allWhite;\r
+    flip = appData.upsideDown;\r
+    size = boardSize;\r
+\r
+    SetBoardOptionEnables(hDlg);\r
+    return TRUE;\r
+\r
+  case WM_PAINT:\r
+    PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
+    PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);\r
+    PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);\r
+    PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);\r
+    PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
+    PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
+    PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
+       TRUE, mono, pieces);\r
+    PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
+       FALSE, mono, pieces);\r
+\r
+    return FALSE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* \r
+       * if we call EndDialog() after the call to ChangeBoardSize(),\r
+       * then ChangeBoardSize() does not take effect, although the new\r
+       * boardSize is saved. Go figure...\r
+       */\r
+      EndDialog(hDlg, TRUE);\r
+\r
+      size = BoardOptionsWhichRadio(hDlg);\r
+\r
+      /*\r
+       * did any settings change?\r
+       */\r
+      if (size != boardSize) {\r
+       ChangeBoardSize(size);\r
+      }\r
+\r
+      if ((mono != appData.monoMode) ||\r
+         (lsc  != lightSquareColor) ||\r
+         (dsc  != darkSquareColor) ||\r
+         (wpc  != whitePieceColor) ||\r
+         (bpc  != blackPieceColor) ||\r
+         (hsc  != highlightSquareColor) ||\r
+          (flip != appData.upsideDown) ||\r
+          (white != appData.allWhite) ||\r
+         (phc  != premoveHighlightColor)) {\r
+\r
+         lightSquareColor = lsc;\r
+         darkSquareColor = dsc;\r
+         whitePieceColor = wpc;\r
+         blackPieceColor = bpc;\r
+         highlightSquareColor = hsc;\r
+         premoveHighlightColor = phc;\r
+         appData.monoMode = mono;\r
+          appData.allWhite = white;\r
+          appData.upsideDown = flip;\r
+\r
+         InitDrawingColors();\r
+         InitDrawingSizes(boardSize, 0);\r
+         InvalidateRect(hwndMain, &boardRect, FALSE);\r
+      }\r
+      DeleteObject(pieces[0]);\r
+      DeleteObject(pieces[1]);\r
+      DeleteObject(pieces[2]);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      DeleteObject(pieces[0]);\r
+      DeleteObject(pieces[1]);\r
+      DeleteObject(pieces[2]);\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case OPT_ChooseLightSquareColor:\r
+      if (ChangeColor(hDlg, &lsc)) \r
+       PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
+       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
+           TRUE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_ChooseDarkSquareColor:\r
+      if (ChangeColor(hDlg, &dsc)) \r
+       PaintColorBlock(hDlg, OPT_DarkSquareColor, dsc);\r
+       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
+           FALSE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_ChooseWhitePieceColor:\r
+      if (ChangeColor(hDlg, &wpc)) \r
+       PaintColorBlock(hDlg, OPT_WhitePieceColor, wpc);\r
+       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
+           TRUE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_ChooseBlackPieceColor:\r
+      if (ChangeColor(hDlg, &bpc)) \r
+       PaintColorBlock(hDlg, OPT_BlackPieceColor, bpc);\r
+       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
+           FALSE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_ChooseHighlightSquareColor:\r
+      if (ChangeColor(hDlg, &hsc)) \r
+       PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
+       PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
+           TRUE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_ChoosePremoveHighlightColor:\r
+      if (ChangeColor(hDlg, &phc)) \r
+       PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
+       PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
+           FALSE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_DefaultBoardColors:\r
+      lsc = ParseColorName(LIGHT_SQUARE_COLOR);\r
+      dsc = ParseColorName(DARK_SQUARE_COLOR);\r
+      wpc = ParseColorName(WHITE_PIECE_COLOR);\r
+      bpc = ParseColorName(BLACK_PIECE_COLOR);\r
+      hsc = ParseColorName(HIGHLIGHT_SQUARE_COLOR);\r
+      phc = ParseColorName(PREMOVE_HIGHLIGHT_COLOR);\r
+      mono = FALSE;\r
+      white= FALSE;\r
+      flip = FALSE;\r
+      CheckDlgButton(hDlg, OPT_Monochrome, FALSE);\r
+      CheckDlgButton(hDlg, OPT_AllWhite,   FALSE);\r
+      CheckDlgButton(hDlg, OPT_UpsideDown, FALSE);\r
+      PaintColorBlock(hDlg, OPT_LightSquareColor, lsc);\r
+      PaintColorBlock(hDlg, OPT_DarkSquareColor,  dsc);\r
+      PaintColorBlock(hDlg, OPT_WhitePieceColor,  wpc);\r
+      PaintColorBlock(hDlg, OPT_BlackPieceColor,  bpc);\r
+      PaintColorBlock(hDlg, OPT_HighlightSquareColor, hsc);\r
+      PaintColorBlock(hDlg, OPT_PremoveHighlightColor, phc);\r
+      SetBoardOptionEnables(hDlg);\r
+      PaintSampleSquare(hDlg, OPT_SampleLightSquare, lsc, wpc, hsc, bpc,\r
+         TRUE, mono, pieces);\r
+      PaintSampleSquare(hDlg, OPT_SampleDarkSquare, dsc, bpc, phc, wpc,\r
+         FALSE, mono, pieces);\r
+      break;\r
+\r
+    case OPT_Monochrome:\r
+      mono = !mono;\r
+      SetBoardOptionEnables(hDlg);\r
+      break;\r
+\r
+    case OPT_AllWhite:\r
+      white = !white;\r
+      SetBoardOptionEnables(hDlg);\r
+      break;\r
+\r
+    case OPT_UpsideDown:\r
+      flip = !flip;\r
+      SetBoardOptionEnables(hDlg);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+VOID\r
+BoardOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)BoardOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_BoardOptions), hwnd,\r
+         (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+VariantClass\r
+VariantWhichRadio(HWND hDlg)\r
+{\r
+  return (IsDlgButtonChecked(hDlg, OPT_VariantFairy) ? VariantFairy :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantGothic) ? VariantGothic :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantCrazyhouse) ? VariantCrazyhouse :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantBughouse) ? VariantBughouse :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantCourier) ? VariantCourier :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantShogi) ? VariantShogi :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantXiangqi) ? VariantXiangqi :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantCapablanca) ? VariantCapablanca :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantTwoKings) ? VariantTwoKings :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantKnightmate) ? VariantKnightmate :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantLosers) ? VariantLosers :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantSuicide) ? VariantSuicide :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantAtomic) ? VariantAtomic :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantShatranj) ? VariantShatranj :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantFRC) ? VariantFischeRandom :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantCylinder) ? VariantCylinder :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantFalcon) ? VariantFalcon :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantCRC) ? VariantCapaRandom :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantSuper) ? VariantSuper :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantBerolina) ? VariantBerolina :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantJanus) ? VariantJanus :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantWildcastle) ? VariantWildCastle :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantNocastle) ? VariantNoCastle :\r
+         (IsDlgButtonChecked(hDlg, OPT_Variant3Check) ? Variant3Check :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantGreat) ? VariantGreat :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantGiveaway) ? VariantGiveaway :\r
+         (IsDlgButtonChecked(hDlg, OPT_VariantTwilight) ? VariantTwilight :\r
+          VariantNormal ))))))))))))))))))))))))))));\r
+}\r
+\r
+LRESULT CALLBACK\r
+NewVariantDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  static VariantClass v;\r
+  static int n1_ok, n2_ok, n3_ok;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    switch (gameInfo.variant) {\r
+    case VariantNormal:\r
+      CheckDlgButton(hDlg, OPT_VariantNormal, TRUE);\r
+      break;\r
+    case VariantCrazyhouse:\r
+      CheckDlgButton(hDlg, OPT_VariantCrazyhouse, TRUE);\r
+      break;\r
+    case VariantBughouse:\r
+      CheckDlgButton(hDlg, OPT_VariantBughouse, TRUE);\r
+      break;\r
+    case VariantShogi:\r
+      CheckDlgButton(hDlg, OPT_VariantShogi, TRUE);\r
+      break;\r
+    case VariantXiangqi:\r
+      CheckDlgButton(hDlg, OPT_VariantXiangqi, TRUE);\r
+      break;\r
+    case VariantCapablanca:\r
+      CheckDlgButton(hDlg, OPT_VariantCapablanca, TRUE);\r
+      break;\r
+    case VariantGothic:\r
+      CheckDlgButton(hDlg, OPT_VariantGothic, TRUE);\r
+      break;\r
+    case VariantCourier:\r
+      CheckDlgButton(hDlg, OPT_VariantCourier, TRUE);\r
+      break;\r
+    case VariantKnightmate:\r
+      CheckDlgButton(hDlg, OPT_VariantKnightmate, TRUE);\r
+      break;\r
+    case VariantTwoKings:\r
+      CheckDlgButton(hDlg, OPT_VariantTwoKings, TRUE);\r
+      break;\r
+    case VariantFairy:\r
+      CheckDlgButton(hDlg, OPT_VariantFairy, TRUE);\r
+      break;\r
+    case VariantAtomic:\r
+      CheckDlgButton(hDlg, OPT_VariantAtomic, TRUE);\r
+      break;\r
+    case VariantSuicide:\r
+      CheckDlgButton(hDlg, OPT_VariantSuicide, TRUE);\r
+      break;\r
+    case VariantLosers:\r
+      CheckDlgButton(hDlg, OPT_VariantLosers, TRUE);\r
+      break;\r
+    case VariantShatranj:\r
+      CheckDlgButton(hDlg, OPT_VariantShatranj, TRUE);\r
+      break;\r
+    case VariantFischeRandom:\r
+      CheckDlgButton(hDlg, OPT_VariantFRC, TRUE);\r
+      break;\r
+    case VariantCapaRandom:\r
+      CheckDlgButton(hDlg, OPT_VariantCRC, TRUE);\r
+      break;\r
+    case VariantFalcon:\r
+      CheckDlgButton(hDlg, OPT_VariantFalcon, TRUE);\r
+      break;\r
+    case VariantCylinder:\r
+      CheckDlgButton(hDlg, OPT_VariantCylinder, TRUE);\r
+      break;\r
+    case Variant3Check:\r
+      CheckDlgButton(hDlg, OPT_Variant3Check, TRUE);\r
+      break;\r
+    case VariantSuper:\r
+      CheckDlgButton(hDlg, OPT_VariantSuper, TRUE);\r
+      break;\r
+    case VariantBerolina:\r
+      CheckDlgButton(hDlg, OPT_VariantBerolina, TRUE);\r
+      break;\r
+    case VariantJanus:\r
+      CheckDlgButton(hDlg, OPT_VariantJanus, TRUE);\r
+      break;\r
+    case VariantWildCastle:\r
+      CheckDlgButton(hDlg, OPT_VariantWildcastle, TRUE);\r
+      break;\r
+    case VariantNoCastle:\r
+      CheckDlgButton(hDlg, OPT_VariantNocastle, TRUE);\r
+      break;\r
+    case VariantGreat:\r
+      CheckDlgButton(hDlg, OPT_VariantGreat, TRUE);\r
+      break;\r
+    case VariantGiveaway:\r
+      CheckDlgButton(hDlg, OPT_VariantGiveaway, TRUE);\r
+      break;\r
+    case VariantTwilight:\r
+      CheckDlgButton(hDlg, OPT_VariantTwilight, TRUE);\r
+      break;\r
+    default: ;\r
+    }\r
+\r
+    SetDlgItemInt( hDlg, IDC_Files, -1, TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_Files, EM_SETSEL, 0, -1 );\r
+\r
+    SetDlgItemInt( hDlg, IDC_Ranks, -1, TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
+\r
+    SetDlgItemInt( hDlg, IDC_Holdings, -1, TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_Ranks, EM_SETSEL, 0, -1 );\r
+\r
+    n1_ok = n2_ok = n3_ok = FALSE;\r
+\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* \r
+       * if we call EndDialog() after the call to ChangeBoardSize(),\r
+       * then ChangeBoardSize() does not take effect, although the new\r
+       * boardSize is saved. Go figure...\r
+       */\r
+      EndDialog(hDlg, TRUE);\r
+\r
+      v = VariantWhichRadio(hDlg);\r
+      if(!appData.noChessProgram) { char *name = VariantName(v), buf[MSG_SIZ];\r
+       if (first.protocolVersion > 1 && StrStr(first.variants, name) == NULL) {\r
+           /* [HGM] in protocol 2 we check if variant is suported by engine */\r
+           sprintf(buf, "Variant %s not supported by %s", name, first.tidy);\r
+           DisplayError(buf, 0);\r
+           return TRUE; /* treat as "Cancel" if first engine does not support it */\r
+       } else\r
+       if (second.initDone && second.protocolVersion > 1 && StrStr(second.variants, name) == NULL) {\r
+           sprintf(buf, "Warning: second engine (%s) does not support this!", second.tidy);\r
+           DisplayError(buf, 0);   /* use of second engine is optional; only warn user */\r
+       }\r
+      }\r
+\r
+      gameInfo.variant = v;\r
+      appData.variant = VariantName(v);\r
+\r
+      appData.NrFiles = (int) GetDlgItemInt(hDlg, IDC_Files, NULL, FALSE );\r
+      appData.NrRanks = (int) GetDlgItemInt(hDlg, IDC_Ranks, NULL, FALSE );\r
+      appData.holdingsSize = (int) GetDlgItemInt(hDlg, IDC_Holdings, NULL, FALSE );\r
+\r
+      if(!n1_ok) appData.NrFiles = -1;\r
+      if(!n2_ok) appData.NrRanks = -1;\r
+      if(!n3_ok) appData.holdingsSize = -1;\r
+\r
+      shuffleOpenings = FALSE; /* [HGM] shuffle: possible shuffle reset when we switch */\r
+      startedFromPositionFile = FALSE; /* [HGM] loadPos: no longer valid in new variant */\r
+      appData.pieceToCharTable = NULL;\r
+      Reset(TRUE, TRUE);\r
+\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case IDC_Ranks:\r
+    case IDC_Files:\r
+    case IDC_Holdings:\r
+        if( HIWORD(wParam) == EN_CHANGE ) {\r
+\r
+            GetDlgItemInt(hDlg, IDC_Files, &n1_ok, FALSE );\r
+            GetDlgItemInt(hDlg, IDC_Ranks, &n2_ok, FALSE );\r
+            GetDlgItemInt(hDlg, IDC_Holdings, &n3_ok, FALSE );\r
+\r
+            /*EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok ? TRUE : FALSE );*/\r
+        }\r
+        return TRUE;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+VOID\r
+NewVariantPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)NewVariantDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_NewVariant), hwnd,\r
+         (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * ICS Options Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+BOOL APIENTRY\r
+MyCreateFont(HWND hwnd, MyFont *font)\r
+{\r
+  CHOOSEFONT cf;\r
+  HFONT hf;\r
+\r
+  /* Initialize members of the CHOOSEFONT structure. */\r
+  cf.lStructSize = sizeof(CHOOSEFONT);\r
+  cf.hwndOwner = hwnd;\r
+  cf.hDC = (HDC)NULL;\r
+  cf.lpLogFont = &font->lf;\r
+  cf.iPointSize = 0;\r
+  cf.Flags = CF_SCREENFONTS|/*CF_ANSIONLY|*/CF_INITTOLOGFONTSTRUCT;\r
+  cf.rgbColors = RGB(0,0,0);\r
+  cf.lCustData = 0L;\r
+  cf.lpfnHook = (LPCFHOOKPROC)NULL;\r
+  cf.lpTemplateName = (LPSTR)NULL;\r
+  cf.hInstance = (HINSTANCE) NULL;\r
+  cf.lpszStyle = (LPSTR)NULL;\r
+  cf.nFontType = SCREEN_FONTTYPE;\r
+  cf.nSizeMin = 0;\r
+  cf.nSizeMax = 0;\r
+\r
+  /* Display the CHOOSEFONT common-dialog box. */\r
+  if (!ChooseFont(&cf)) {\r
+    return FALSE;\r
+  }\r
+\r
+  /* Create a logical font based on the user's   */\r
+  /* selection and return a handle identifying   */\r
+  /* that font. */\r
+  hf = CreateFontIndirect(cf.lpLogFont);\r
+  if (hf == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  font->hf = hf;\r
+  font->mfp.pointSize = (float) (cf.iPointSize / 10.0);\r
+  font->mfp.bold = (font->lf.lfWeight >= FW_BOLD);\r
+  font->mfp.italic = font->lf.lfItalic;\r
+  font->mfp.underline = font->lf.lfUnderline;\r
+  font->mfp.strikeout = font->lf.lfStrikeOut;\r
+  font->mfp.charset = font->lf.lfCharSet;\r
+  strcpy(font->mfp.faceName, font->lf.lfFaceName);\r
+  return TRUE;\r
+}\r
+\r
+\r
+VOID\r
+UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca)\r
+{\r
+  CHARFORMAT cf;\r
+  cf.cbSize = sizeof(CHARFORMAT);\r
+  cf.dwMask = \r
+    CFM_COLOR|CFM_CHARSET|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_FACE|CFM_SIZE;\r
+  cf.crTextColor = mca->color;\r
+  cf.dwEffects = mca->effects;\r
+  strcpy(cf.szFaceName, font[boardSize][CONSOLE_FONT]->mfp.faceName);\r
+  /* \r
+   * The 20.0 below is in fact documented. yHeight is expressed in twips.\r
+   * A twip is 1/20 of a font's point size. See documentation of CHARFORMAT.\r
+   * --msw\r
+   */\r
+  cf.yHeight = (int)(font[boardSize][CONSOLE_FONT]->mfp.pointSize * 20.0 + 0.5);\r
+  cf.bCharSet = DEFAULT_CHARSET; /* should be ignored anyway */\r
+  cf.bPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
+  SendDlgItemMessage(hDlg, id, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
+}\r
+\r
+LRESULT CALLBACK\r
+ColorizeTextDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  static MyColorizeAttribs mca;\r
+  static ColorClass cc;\r
+  COLORREF background = (COLORREF)0;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG:\r
+    cc = (ColorClass)lParam;\r
+    mca = colorizeAttribs[cc];\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    CheckDlgButton(hDlg, OPT_Bold, (mca.effects & CFE_BOLD) != 0);\r
+    CheckDlgButton(hDlg, OPT_Italic, (mca.effects & CFE_ITALIC) != 0);\r
+    CheckDlgButton(hDlg, OPT_Underline, (mca.effects & CFE_UNDERLINE) != 0);\r
+    CheckDlgButton(hDlg, OPT_Strikeout, (mca.effects & CFE_STRIKEOUT) != 0);\r
+\r
+    /* get the current background color from the parent window */\r
+    SendMessage(GetWindow(hDlg, GW_OWNER),WM_COMMAND, \r
+               (WPARAM)WM_USER_GetConsoleBackground, \r
+               (LPARAM)&background);\r
+\r
+    /* set the background color */\r
+    SendDlgItemMessage(hDlg, OPT_Sample, EM_SETBKGNDCOLOR, FALSE, background);\r
+\r
+    SetDlgItemText(hDlg, OPT_Sample, mca.name);\r
+    UpdateSampleText(hDlg, OPT_Sample, &mca);\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+      colorizeAttribs[cc] = mca;\r
+      textAttribs[cc].color = mca.color;\r
+      textAttribs[cc].effects = mca.effects;\r
+      Colorize(currentColorClass, TRUE);\r
+      if (cc == ColorNormal) {\r
+       CHARFORMAT cf;\r
+       cf.cbSize = sizeof(CHARFORMAT);\r
+       cf.dwMask = CFM_COLOR;\r
+       cf.crTextColor = mca.color;\r
+       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
+         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
+      }\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case OPT_ChooseColor:\r
+      ChangeColor(hDlg, &mca.color);\r
+      UpdateSampleText(hDlg, OPT_Sample, &mca);\r
+      return TRUE;\r
+\r
+    default:\r
+      mca.effects =\r
+       (IsDlgButtonChecked(hDlg, OPT_Bold) ? CFE_BOLD : 0) |\r
+       (IsDlgButtonChecked(hDlg, OPT_Italic) ? CFE_ITALIC : 0) |\r
+       (IsDlgButtonChecked(hDlg, OPT_Underline) ? CFE_UNDERLINE : 0) |\r
+       (IsDlgButtonChecked(hDlg, OPT_Strikeout) ? CFE_STRIKEOUT : 0);\r
+      UpdateSampleText(hDlg, OPT_Sample, &mca);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+ColorizeTextPopup(HWND hwnd, ColorClass cc)\r
+{\r
+  FARPROC lpProc;\r
+\r
+  lpProc = MakeProcInstance((FARPROC)ColorizeTextDialog, hInst);\r
+  DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_Colorize),\r
+    hwnd, (DLGPROC)lpProc, (LPARAM) cc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+VOID\r
+SetIcsOptionEnables(HWND hDlg)\r
+{\r
+#define ENABLE_DLG_ITEM(x,y) EnableWindow(GetDlgItem(hDlg,(x)), (y))\r
+\r
+  UINT state = IsDlgButtonChecked(hDlg, OPT_Premove);\r
+  ENABLE_DLG_ITEM(OPT_PremoveWhite, state);\r
+  ENABLE_DLG_ITEM(OPT_PremoveWhiteText, state);\r
+  ENABLE_DLG_ITEM(OPT_PremoveBlack, state);\r
+  ENABLE_DLG_ITEM(OPT_PremoveBlackText, state);\r
+\r
+  ENABLE_DLG_ITEM(OPT_IcsAlarmTime, IsDlgButtonChecked(hDlg, OPT_IcsAlarm));\r
+\r
+#undef ENABLE_DLG_ITEM\r
+}\r
+\r
+\r
+LRESULT CALLBACK\r
+IcsOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  char buf[MSG_SIZ];\r
+  int number;\r
+  int i;\r
+  static COLORREF cbc;\r
+  static MyColorizeAttribs *mca;\r
+  COLORREF *colorref;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+\r
+    mca = colorizeAttribs;\r
+\r
+    for (i=0; i < NColorClasses - 1; i++) {\r
+      mca[i].color   = textAttribs[i].color;\r
+      mca[i].effects = textAttribs[i].effects;\r
+    }\r
+    cbc = consoleBackgroundColor;\r
+\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+\r
+    /* Initialize the dialog items */\r
+#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
+\r
+    CHECK_BOX(OPT_AutoComment, appData.autoComment);\r
+    CHECK_BOX(OPT_AutoObserve, appData.autoObserve);\r
+    CHECK_BOX(OPT_GetMoveList, appData.getMoveList);\r
+    CHECK_BOX(OPT_LocalLineEditing, appData.localLineEditing);\r
+    CHECK_BOX(OPT_QuietPlay, appData.quietPlay);\r
+    CHECK_BOX(OPT_Premove, appData.premove);\r
+    CHECK_BOX(OPT_PremoveWhite, appData.premoveWhite);\r
+    CHECK_BOX(OPT_PremoveBlack, appData.premoveBlack);\r
+    CHECK_BOX(OPT_IcsAlarm, appData.icsAlarm);\r
+    CHECK_BOX(OPT_DontColorize, !appData.colorize);\r
+\r
+#undef CHECK_BOX\r
+\r
+    sprintf(buf, "%d", appData.icsAlarmTime / 1000);\r
+    SetDlgItemText(hDlg, OPT_IcsAlarmTime, buf);\r
+    SetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText);\r
+    SetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText);\r
+\r
+    SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
+    SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
+\r
+    SetDlgItemText(hDlg, OPT_SampleShout,     mca[ColorShout].name);\r
+    SetDlgItemText(hDlg, OPT_SampleSShout,    mca[ColorSShout].name);\r
+    SetDlgItemText(hDlg, OPT_SampleChannel1,  mca[ColorChannel1].name);\r
+    SetDlgItemText(hDlg, OPT_SampleChannel,   mca[ColorChannel].name);\r
+    SetDlgItemText(hDlg, OPT_SampleKibitz,    mca[ColorKibitz].name);\r
+    SetDlgItemText(hDlg, OPT_SampleTell,      mca[ColorTell].name);\r
+    SetDlgItemText(hDlg, OPT_SampleChallenge, mca[ColorChallenge].name);\r
+    SetDlgItemText(hDlg, OPT_SampleRequest,   mca[ColorRequest].name);\r
+    SetDlgItemText(hDlg, OPT_SampleSeek,      mca[ColorSeek].name);\r
+    SetDlgItemText(hDlg, OPT_SampleNormal,    mca[ColorNormal].name);\r
+\r
+    UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
+    UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
+    UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
+    UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
+    UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
+    UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
+    UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
+    UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
+    UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
+    UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
+\r
+    SetIcsOptionEnables(hDlg);\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+\r
+    case WM_USER_GetConsoleBackground: \r
+      /* the ColorizeTextDialog needs the current background color */\r
+      colorref = (COLORREF *)lParam;\r
+      *colorref = cbc;\r
+      return FALSE;\r
+\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+      GetDlgItemText(hDlg, OPT_IcsAlarmTime, buf, MSG_SIZ);\r
+      if (sscanf(buf, "%d", &number) != 1 || (number < 0)){\r
+         MessageBox(hDlg, "Invalid ICS Alarm Time",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+      }\r
+\r
+#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
+\r
+      appData.icsAlarm         = IS_CHECKED(OPT_IcsAlarm);\r
+      appData.premove          = IS_CHECKED(OPT_Premove);\r
+      appData.premoveWhite     = IS_CHECKED(OPT_PremoveWhite);\r
+      appData.premoveBlack     = IS_CHECKED(OPT_PremoveBlack);\r
+      appData.autoComment      = IS_CHECKED(OPT_AutoComment);\r
+      appData.autoObserve      = IS_CHECKED(OPT_AutoObserve);\r
+      appData.getMoveList      = IS_CHECKED(OPT_GetMoveList);\r
+      appData.localLineEditing = IS_CHECKED(OPT_LocalLineEditing);\r
+      appData.quietPlay        = IS_CHECKED(OPT_QuietPlay);\r
+\r
+#undef IS_CHECKED\r
+\r
+      appData.icsAlarmTime = number * 1000;\r
+      GetDlgItemText(hDlg, OPT_PremoveWhiteText, appData.premoveWhiteText, 5);\r
+      GetDlgItemText(hDlg, OPT_PremoveBlackText, appData.premoveBlackText, 5);\r
+\r
+      if (appData.localLineEditing) {\r
+       DontEcho();\r
+       EchoOn();\r
+      } else {\r
+       DoEcho();\r
+       EchoOff();\r
+      }\r
+\r
+      appData.colorize =\r
+       (Boolean)!IsDlgButtonChecked(hDlg, OPT_DontColorize);\r
+\r
     ChangedConsoleFont();\r
 \r
-    if (!appData.colorize) {
-       CHARFORMAT cf;
-       COLORREF background = ParseColorName(COLOR_BKGD);
-       /*
-       SetDefaultTextAttribs();
-        Colorize(currentColorClass);
-       */
-       cf.cbSize = sizeof(CHARFORMAT);
-       cf.dwMask = CFM_COLOR;
-       cf.crTextColor = ParseColorName(COLOR_NORMAL);
-\r
-       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
-         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
-        SendDlgItemMessage(hwndConsole, OPT_ConsoleText, 
-         EM_SETBKGNDCOLOR, FALSE, background);
-       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
-         EM_SETBKGNDCOLOR, FALSE, background);
-      }
-
-      if (cbc != consoleBackgroundColor) {
-       consoleBackgroundColor = cbc;
-       if (appData.colorize) {
-         SendDlgItemMessage(hwndConsole, OPT_ConsoleText, 
-           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);
-         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, 
-           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);
-       }
-      }
-
-      for (i=0; i < NColorClasses - 1; i++) {
-       textAttribs[i].color   = mca[i].color;
-       textAttribs[i].effects = mca[i].effects;
-      }
-
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case OPT_ChooseShoutColor:
-      ColorizeTextPopup(hDlg, ColorShout);
-      UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);
-      break;
-
-    case OPT_ChooseSShoutColor:
-      ColorizeTextPopup(hDlg, ColorSShout);
-      UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);
-      break;
-
-    case OPT_ChooseChannel1Color:
-      ColorizeTextPopup(hDlg, ColorChannel1);
-      UpdateSampleText(hDlg, OPT_SampleChannel1, 
-                      &colorizeAttribs[ColorChannel1]);
-      break;
-
-    case OPT_ChooseChannelColor:
-      ColorizeTextPopup(hDlg, ColorChannel);
-      UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);
-      break;
-
-    case OPT_ChooseKibitzColor:
-      ColorizeTextPopup(hDlg, ColorKibitz);
-      UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);
-      break;
-
-    case OPT_ChooseTellColor:
-      ColorizeTextPopup(hDlg, ColorTell);
-      UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);
-      break;
-
-    case OPT_ChooseChallengeColor:
-      ColorizeTextPopup(hDlg, ColorChallenge);
-      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);
-      break;
-
-    case OPT_ChooseRequestColor:
-      ColorizeTextPopup(hDlg, ColorRequest);
-      UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);
-      break;
-
-    case OPT_ChooseSeekColor:
-      ColorizeTextPopup(hDlg, ColorSeek);
-      UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);
-      break;
-
-    case OPT_ChooseNormalColor:
-      ColorizeTextPopup(hDlg, ColorNormal);
-      UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);
-      break;
-
-    case OPT_ChooseBackgroundColor:
-      if (ChangeColor(hDlg, &cbc)) {
-       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);
-       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);
-      }
-      break;
-
-    case OPT_DefaultColors:
-      for (i=0; i < NColorClasses - 1; i++)
-       ParseAttribs(&mca[i].color, 
-                    &mca[i].effects,
-                    defaultTextAttribs[i]);
-
-      cbc = ParseColorName(COLOR_BKGD);
-      SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);
-      SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);
-
-      UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);
-      UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);
-      UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);
-      UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);
-      UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);
-      UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);
-      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);
-      UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);
-      UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);
-      UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);
-      break;
-
-    default:
-      SetIcsOptionEnables(hDlg);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID
-IcsOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,
-           (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * Fonts Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-VOID
-SetSampleFontText(HWND hwnd, int id, const MyFont *mf)
-{
-  char buf[MSG_SIZ];
-  HWND hControl;
-  HDC hdc;
-  CHARFORMAT cf;
-  SIZE size;
-  RECT rectClient, rectFormat;
-  HFONT oldFont;
-  POINT center;
-  int len;
-
-  len = sprintf(buf, "%.0f pt. %s%s%s\n",
-               mf->mfp.pointSize, mf->mfp.faceName,
-               mf->mfp.bold ? " bold" : "",
-               mf->mfp.italic ? " italic" : "");
-  SetDlgItemText(hwnd, id, buf);
-
-  hControl = GetDlgItem(hwnd, id);
-  hdc = GetDC(hControl);
-  SetMapMode(hdc, MM_TEXT);    /* 1 pixel == 1 logical unit */
-  oldFont = SelectObject(hdc, mf->hf);
-  
-  /* get number of logical units necessary to display font name */
-  GetTextExtentPoint32(hdc, buf, len, &size);
-
-  /* calculate formatting rectangle in the rich edit control.  
-   * May be larger or smaller than the actual control.
-   */
-  GetClientRect(hControl, &rectClient);
-  center.x = (rectClient.left + rectClient.right) / 2;
-  center.y = (rectClient.top  + rectClient.bottom) / 2;
-  rectFormat.top    = center.y - (size.cy / 2) - 1;
-  rectFormat.bottom = center.y + (size.cy / 2) + 1;
-  rectFormat.left   = center.x - (size.cx / 2) - 1;
-  rectFormat.right  = center.x + (size.cx / 2) + 1;
-
-  cf.cbSize = sizeof(CHARFORMAT);
-  cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;
-  cf.dwEffects = 0;
-  if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;
-  if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
-  strcpy(cf.szFaceName, mf->mfp.faceName);
-  /*
-   * yHeight is expressed in twips.  A twip is 1/20 of a font's point
-   * size. See documentation of CHARFORMAT.  --msw
-   */
-  cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);
-  cf.bCharSet = mf->lf.lfCharSet;
-  cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;
-
-  /* format the text in the rich edit control */
-  SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);
-  SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);
-
-  /* clean up */
-  SelectObject(hdc, oldFont);
-  ReleaseDC(hControl, hdc);
-}
-
-VOID
-CopyFont(MyFont *dest, const MyFont *src)
-{
-  dest->mfp.pointSize = src->mfp.pointSize;
-  dest->mfp.bold      = src->mfp.bold;
-  dest->mfp.italic    = src->mfp.italic;
-  dest->mfp.underline = src->mfp.underline;
-  dest->mfp.strikeout = src->mfp.strikeout;
-  dest->mfp.charset   = src->mfp.charset;
-  lstrcpy(dest->mfp.faceName, src->mfp.faceName);
-  CreateFontInMF(dest);
-}
-
-
-LRESULT CALLBACK
-FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  static MyFont workFont[NUM_FONTS];
-  static BOOL firstPaint;
-  int i;
-  RECT rect;
-
-  switch (message) {
-  case WM_INITDIALOG:
-
-    /* copy the current font settings into a working copy */
-    for (i=0; i < NUM_FONTS; i++)
-      CopyFont(&workFont[i], font[boardSize][i]);
-
-    if (!appData.icsActive)
-      EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);
-
-    firstPaint = TRUE; /* see rant below */
-
-    /* If I don't call SetFocus(), the dialog won't respond to the keyboard
-     * when first drawn. Why is this the only dialog that behaves this way? Is
-     * is the WM_PAINT stuff below?? Sigh...
-     */
-    SetFocus(GetDlgItem(hDlg, IDOK));
-    break;
-
-  case WM_PAINT:
-    /* This should not be necessary. However, if SetSampleFontText() is called
-     * in response to WM_INITDIALOG, the strings are not properly centered in
-     * the controls when the dialog first appears. I can't figure out why, so
-     * this is the workaround.  --msw
-     */
-    if (firstPaint) {
-      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);
-      firstPaint = FALSE;
-    }
-    break;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-
-    case IDOK:
-      /* again, it seems to avoid redraw problems if we call EndDialog first */
-      EndDialog(hDlg, FALSE);
-
-      /* copy modified settings back to the fonts array */
-      for (i=0; i < NUM_FONTS; i++)
-       CopyFont(font[boardSize][i], &workFont[i]);
-
-      /* a sad necessity due to the original design of having a separate
-       * console font, tags font, and comment font for each board size.  IMHO
-       * these fonts should not be dependent on the current board size.  I'm
-       * running out of time, so I am doing this hack rather than redesign the
-       * data structure. Besides, I think if I redesigned the data structure, I
-       * might break backwards compatibility with old winboard.ini files.
-       * --msw
-       */
-      for (i=0; i < NUM_SIZES; i++) {
-       CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);
-       CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);
-       CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);
-       CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);
-      }
-      /* end sad necessity */
-
-      InitDrawingSizes(boardSize, 0);
-      InvalidateRect(hwndMain, NULL, TRUE);
-
-      if (commentDialog) {
-       SendDlgItemMessage(commentDialog, OPT_CommentText,
-         WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf, 
-         MAKELPARAM(TRUE, 0));
-       GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);
-       InvalidateRect(commentDialog, &rect, TRUE);
-      }
-
-      if (editTagsDialog) {
-       SendDlgItemMessage(editTagsDialog, OPT_TagsText,
-         WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, 
-         MAKELPARAM(TRUE, 0));
-       GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);
-       InvalidateRect(editTagsDialog, &rect, TRUE);
-      }
-
-      if( moveHistoryDialog != NULL ) {
-       SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,
-         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, 
-         MAKELPARAM(TRUE, 0));
-        SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );
-//     InvalidateRect(editTagsDialog, NULL, TRUE); // [HGM] this ws improperly cloned?
-      }
-
-      if( engineOutputDialog != NULL ) {
-       SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo1,
-         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, 
-         MAKELPARAM(TRUE, 0));
-       SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo2,
-         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, 
-         MAKELPARAM(TRUE, 0));
-      }
-
-      if (hwndConsole) {
-       ChangedConsoleFont();
-      }
-
-      for (i=0; i<NUM_FONTS; i++)
-       DeleteObject(&workFont[i].hf);
-
-      return TRUE;
-
-    case IDCANCEL:
-      for (i=0; i<NUM_FONTS; i++)
-       DeleteObject(&workFont[i].hf);
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case OPT_ChooseClockFont:
-      MyCreateFont(hDlg, &workFont[CLOCK_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);
-      break;
-
-    case OPT_ChooseMessageFont:
-      MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);
-      break;
-
-    case OPT_ChooseCoordFont:
-      MyCreateFont(hDlg, &workFont[COORD_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);
-      break;
-
-    case OPT_ChooseTagFont:
-      MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);
-      break;
-
-    case OPT_ChooseCommentsFont:
-      MyCreateFont(hDlg, &workFont[COMMENT_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);
-      break;
-
-    case OPT_ChooseConsoleFont:
-      MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);
-      break;
-
-    case OPT_ChooseMoveHistoryFont:
-      MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);
-      break;
-
-    case OPT_DefaultFonts:
-      for (i=0; i<NUM_FONTS; i++) {
-       DeleteObject(&workFont[i].hf);
-       ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);
-       CreateFontInMF(&workFont[i]);
-      }
-      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);
-      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);
-      break;
-    }
-  }
-  return FALSE;
-}
-
-VOID
-FontsOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,
-         (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * Sounds Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-
-SoundComboData soundComboData[] = {
-  {"Move", NULL},
-  {"Bell", NULL},
-  {"ICS Alarm", NULL},
-  {"ICS Win", NULL},
-  {"ICS Loss", NULL},
-  {"ICS Draw", NULL},
-  {"ICS Unfinished", NULL},
-  {"Shout", NULL},
-  {"SShout/CShout", NULL},
-  {"Channel 1", NULL},
-  {"Channel", NULL},
-  {"Kibitz", NULL},
-  {"Tell", NULL},
-  {"Challenge", NULL},
-  {"Request", NULL},
-  {"Seek", NULL},
-  {NULL, NULL},
-};
-
-
-void
-InitSoundComboData(SoundComboData *scd)
-{
-  SoundClass sc;
-  ColorClass cc;
-  int index;
-
-  /* copy current sound settings to combo array */
-
-  for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {
-    scd[sc].name = strdup(sounds[sc].name);
-  }
-  for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {
-    index = (int)cc + (int)NSoundClasses;
-    scd[index].name = strdup(textAttribs[cc].sound.name);
-  }
-}
-
-
-void
-ResetSoundComboData(SoundComboData *scd)
-{
-  while (scd->label) {
-    if (scd->name != NULL) {
-      free (scd->name);
-      scd->name = NULL;
-    }
-    scd++;
-  }
-}
-
-void
-InitSoundCombo(HWND hwndCombo, SoundComboData *scd)
-{
-  char buf[255];
-  DWORD err;
-  DWORD cnt = 0;
-  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
-
-  /* send the labels to the combo box */
-  while (scd->label) {
-    err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) scd->label);
-    if (err != cnt++) {
-      sprintf(buf, "InitSoundCombo(): err '%d', cnt '%d'\n",
-         (int)err, (int)cnt);
-      MessageBox(NULL, buf, NULL, MB_OK);
-    }
-    scd++;
-  }
-  SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);
-}
-
-int
-SoundDialogWhichRadio(HWND hDlg)
-{
-  if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;
-  if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;
-  if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;
-  if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;
-  return -1;
-}
-
-VOID
-SoundDialogSetEnables(HWND hDlg, int radio)
-{
-  EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),
-              radio == OPT_BuiltInSound);
-  EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);
-  EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);
-}
-
-char *
-SoundDialogGetName(HWND hDlg, int radio)
-{
-  static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];
-  char *dummy, *ret;
-  switch (radio) {
-  case OPT_NoSound:
-  default:
-    return "";
-  case OPT_DefaultBeep:
-    return "$";
-  case OPT_BuiltInSound:
-    buf[0] = '!';
-    GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);
-    return buf;
-  case OPT_WavFile:
-    GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));
-    GetCurrentDirectory(MSG_SIZ, buf3);
-    SetCurrentDirectory(installDir);
-    if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {
-      ret = buf2;
-    } else {
-      ret = buf;
-    }
-    SetCurrentDirectory(buf3);
-    return ret;
-  }
-}
-
-void
-DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)
-{
-  int radio;
-  /* 
-   * I think it's best to clear the combo and edit boxes. It looks stupid
-   * to have a value from another sound event sitting there grayed out.
-   */
-  SetDlgItemText(hDlg, OPT_WavFileName, "");
-  SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
-
-  if (appData.debugMode)
-      fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);
-  switch (name[0]) {
-  case NULLCHAR:
-    radio = OPT_NoSound;
-    break;
-  case '$':
-    if (name[1] == NULLCHAR) {
-      radio = OPT_DefaultBeep;
-    } else {
-      radio = OPT_WavFile;
-      SetDlgItemText(hDlg, OPT_WavFileName, name);
-    }
-    break;
-  case '!':
-    if (name[1] == NULLCHAR) {
-      radio = OPT_NoSound;
-    } else {
-      radio = OPT_BuiltInSound;
-      if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1, 
-                     (LPARAM) (name + 1)) == CB_ERR) {
-       SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
-       SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));
-      }
-    }
-    break;
-  default:
-    radio = OPT_WavFile;
-    SetDlgItemText(hDlg, OPT_WavFileName, name);
-    break;
-  }
-  SoundDialogSetEnables(hDlg, radio);
-  CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);
-}
-    
-
-char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;
-
-LRESULT CALLBACK
-SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  static HWND hSoundCombo;
-  static DWORD index;
-  static HWND hBISN;
-  int radio;
-  MySound tmp;
-  FILE *f;
-  char buf[MSG_SIZ];
-  char *newName;
-  SoundClass sc;
-  ColorClass cc;
-  SoundComboData *scd;
-  int oldMute;
-
-  switch (message) {
-  case WM_INITDIALOG:
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-
-    /* Initialize the built-in sounds combo */
-    hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);
-     InitComboStrings(hBISN, builtInSoundNames);
-
-    /* Initialize the  sound events combo */
-    index = 0;
-    InitSoundComboData(soundComboData);
-    hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);
-    InitSoundCombo(hSoundCombo, soundComboData);
-
-    /* update the dialog */
-    DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-
-    if (((HWND)lParam == hSoundCombo) && 
-       (HIWORD(wParam) == CBN_SELCHANGE)) {
-      /* 
-       * the user has selected a new sound event. We must store the name for
-       * the previously selected event, then retrieve the name for the
-       * newly selected event and update the dialog. 
-       */
-      radio = SoundDialogWhichRadio(hDlg);
-      newName = strdup(SoundDialogGetName(hDlg, radio));
-      
-      if (strcmp(newName, soundComboData[index].name) != 0) {
-       free(soundComboData[index].name);
-       soundComboData[index].name = newName;
-      } else {
-       free(newName);
-       newName = NULL;
-      }
-      /* now get the settings for the newly selected event */
-      index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
-      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);
-      
-      return TRUE;
-    }
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* 
-       * save the name for the currently selected sound event 
-       */
-      radio = SoundDialogWhichRadio(hDlg);
-      newName = strdup(SoundDialogGetName(hDlg, radio));
-
-      if (strcmp(soundComboData[index].name, newName) != 0) {
-       free(soundComboData[index].name);
-       soundComboData[index].name = newName;
-      } else {
-       free(newName);
-       newName = NULL;
-      }
-
-      /* save all the sound names that changed and load the sounds */
-
-      for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {
-       if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {
-         free(sounds[sc].name);
-         sounds[sc].name = strdup(soundComboData[sc].name);
-         MyLoadSound(&sounds[sc]);
-       }
-      }
-      for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {
-       index = (int)cc + (int)NSoundClasses;
-       if (strcmp(soundComboData[index].name, 
-                  textAttribs[cc].sound.name) != 0) {
-         free(textAttribs[cc].sound.name);
-         textAttribs[cc].sound.name = strdup(soundComboData[index].name);
-         MyLoadSound(&textAttribs[cc].sound);
-       }
-      }
-
-       mute = FALSE; // [HGM] mute: switch sounds automatically on if we select one
-      CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,MF_BYCOMMAND|MF_UNCHECKED);
-      ResetSoundComboData(soundComboData);
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      ResetSoundComboData(soundComboData);
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case OPT_DefaultSounds:
-      /* can't use SetDefaultSounds() because we need to be able to "undo" if
-       * user selects "Cancel" later on. So we do it the hard way here.
-       */
-      scd = &soundComboData[0];
-      while (scd->label != NULL) {
-       if (scd->name != NULL) free(scd->name);
-       scd->name = strdup("");
-       scd++;
-      }
-      free(soundComboData[(int)SoundBell].name);
-      soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);
-      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);
-      break;
-
-    case OPT_PlaySound:
-      radio = SoundDialogWhichRadio(hDlg);
-      tmp.name = strdup(SoundDialogGetName(hDlg, radio));
-      tmp.data = NULL;
-      MyLoadSound(&tmp);
-       oldMute = mute; mute = FALSE; // [HGM] mute: always sound when user presses play, ignorig mute setting
-      MyPlaySound(&tmp);
-       mute = oldMute;
-      if (tmp.data  != NULL) FreeResource(tmp.data); // technically obsolete fn, but tmp.data is NOT malloc'd mem
-      if (tmp.name != NULL) free(tmp.name);
-      return TRUE;
-
-    case OPT_BrowseSound:
-      f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,
-       "Browse for Sound File", NULL, NULL, buf);
-      if (f != NULL) {
-       fclose(f);
-       SetDlgItemText(hDlg, OPT_WavFileName, buf);
-      }
-      return TRUE;
-
-    default:
-      radio = SoundDialogWhichRadio(hDlg);
-      SoundDialogSetEnables(hDlg, radio);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-
-VOID SoundOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc;
-
-  lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);
-  FreeProcInstance(lpProc);
-}
-
-
-/*---------------------------------------------------------------------------*\
- *
- * Comm Port dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-
-#define FLOW_NONE   0
-#define FLOW_XOFF   1
-#define FLOW_CTS    2
-#define FLOW_DSR    3
-
-#define PORT_NONE
-
-ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},
-                          {"COM3", 3}, {"COM4", 4}, {NULL, 0} };
-ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},
-                          {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},
-                          {"38400", 38400}, {NULL, 0} };
-ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };
-ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},
-                          {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };
-ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},
-                          {"2", TWOSTOPBITS}, {NULL, 0} };
-ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},
-                          {"DSR", FLOW_DSR}, {NULL, 0} };
-
-
-VOID
-ParseCommSettings(char *arg, DCB *dcb)
-{
-  int dataRate, count;
-  char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];
-  ComboData *cd;
-  count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",
-    &dataRate, bits, parity, stopBits, flow);
-  if (count != 5) goto cant_parse;
-  dcb->BaudRate = dataRate;
-  cd = cdDataBits;
-  while (cd->label != NULL) {
-    if (StrCaseCmp(cd->label, bits) == 0) {
-      dcb->ByteSize = cd->value;
-      break;
-    }
-    cd++;
-  }
-  if (cd->label == NULL) goto cant_parse;
-  cd = cdParity;
-  while (cd->label != NULL) {
-    if (StrCaseCmp(cd->label, parity) == 0) {
-      dcb->Parity = cd->value;
-      break;
-    }
-    cd++;
-  }
-  if (cd->label == NULL) goto cant_parse;
-  cd = cdStopBits;
-  while (cd->label != NULL) {
-    if (StrCaseCmp(cd->label, stopBits) == 0) {
-      dcb->StopBits = cd->value;
-      break;
-    }
-    cd++;
-  }
-  cd = cdFlow;
-  if (cd->label == NULL) goto cant_parse;
-  while (cd->label != NULL) {
-    if (StrCaseCmp(cd->label, flow) == 0) {
-      switch (cd->value) {
-      case FLOW_NONE:
-       dcb->fOutX = FALSE;
-       dcb->fOutxCtsFlow = FALSE;
-       dcb->fOutxDsrFlow = FALSE;
-       break;
-      case FLOW_CTS:
-       dcb->fOutX = FALSE;
-       dcb->fOutxCtsFlow = TRUE;
-       dcb->fOutxDsrFlow = FALSE;
-       break;
-      case FLOW_DSR:
-       dcb->fOutX = FALSE;
-       dcb->fOutxCtsFlow = FALSE;
-       dcb->fOutxDsrFlow = TRUE;
-       break;
-      case FLOW_XOFF:
-       dcb->fOutX = TRUE;
-       dcb->fOutxCtsFlow = FALSE;
-       dcb->fOutxDsrFlow = FALSE;
-       break;
-      }
-      break;
-    }
-    cd++;
-  }
-  if (cd->label == NULL) goto cant_parse;
-  return;
-cant_parse:
-    ExitArgError("Can't parse com port settings", arg);
-}
-
-
-VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)
-{
-  char *flow = "??", *parity = "??", *stopBits = "??";
-  ComboData *cd;
-  
-  cd = cdParity;
-  while (cd->label != NULL) {
-    if (dcb->Parity == cd->value) {
-      parity = cd->label;
-      break;
-    }
-    cd++;
-  }
-  cd = cdStopBits;
-  while (cd->label != NULL) {
-    if (dcb->StopBits == cd->value) {
-      stopBits = cd->label;
-      break;
-    }
-    cd++;
-  }
-  if (dcb->fOutX) {
-    flow = cdFlow[FLOW_XOFF].label;
-  } else if (dcb->fOutxCtsFlow) {
-    flow = cdFlow[FLOW_CTS].label;
-  } else if (dcb->fOutxDsrFlow) {
-    flow = cdFlow[FLOW_DSR].label;
-  } else {
-    flow = cdFlow[FLOW_NONE].label;
-  }
-  fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,
-    (int)dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);
-}
-
-
-void
-InitCombo(HANDLE hwndCombo, ComboData *cd)
-{
-  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
-
-  while (cd->label != NULL) {
-    SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);
-    cd++;
-  }
-}
-
-void
-SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)
-{
-  int i;
-
-  i = 0;
-  while (cd->label != NULL) {
-    if (cd->value == value) {
-      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);
-      return;
-    }
-    cd++;
-    i++;
-  }
-}
-
-LRESULT CALLBACK
-CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,  LPARAM lParam)
-{
-  char buf[MSG_SIZ];
-  HANDLE hwndCombo;
-  char *p;
-  LRESULT index;
-  unsigned value;
-  int err;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    /* !! There should probably be some synchronization
-       in accessing hCommPort and dcb.  Or does modal nature
-       of this dialog box do it for us?
-       */
-    hwndCombo = GetDlgItem(hDlg, OPT_Port);
-    InitCombo(hwndCombo, cdPort);
-    p = strrchr(appData.icsCommPort, '\\');
-    if (p++ == NULL) p = appData.icsCommPort;
-    if ((*p == '\0') ||
-       (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {
-      SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");
-    }
-    EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/
-
-    hwndCombo = GetDlgItem(hDlg, OPT_DataRate);
-    InitCombo(hwndCombo, cdDataRate);
-    sprintf(buf, "%u", (int)dcb.BaudRate);
-    if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {
-      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
-      SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);
-    }
-
-    hwndCombo = GetDlgItem(hDlg, OPT_Bits);
-    InitCombo(hwndCombo, cdDataBits);
-    SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);
-
-    hwndCombo = GetDlgItem(hDlg, OPT_Parity);
-    InitCombo(hwndCombo, cdParity);
-    SelectComboValue(hwndCombo, cdParity, dcb.Parity);
-
-    hwndCombo = GetDlgItem(hDlg, OPT_StopBits);
-    InitCombo(hwndCombo, cdStopBits);
-    SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);
-
-    hwndCombo = GetDlgItem(hDlg, OPT_Flow);
-    InitCombo(hwndCombo, cdFlow);
-    if (dcb.fOutX) {
-      SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);
-    } else if (dcb.fOutxCtsFlow) {
-      SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);
-    } else if (dcb.fOutxDsrFlow) {
-      SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);
-    } else {
-      SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);
-    }
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-#ifdef NOTDEF
-      /* !! Currently we can't change comm ports in midstream */
-      hwndCombo = GetDlgItem(hDlg, OPT_Port);
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
-      if (index == PORT_NONE) {
-       appData.icsCommPort = "";
-       if (hCommPort != NULL) {
-         CloseHandle(hCommPort);
-         hCommPort = NULL;
-       }
-       EndDialog(hDlg, TRUE);
-       return TRUE;
-      }
-      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);
-      appData.icsCommPort = strdup(buf);
-      if (hCommPort != NULL) {
-       CloseHandle(hCommPort);
-       hCommPort = NULL;
-      }
-      /* now what?? can't really do this; have to fix up the ChildProc
-        and InputSource records for the comm port that we gave to the
-        back end. */
-#endif /*NOTDEF*/
-
-      hwndCombo = GetDlgItem(hDlg, OPT_DataRate);
-      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);
-      if (sscanf(buf, "%u", &value) != 1) {
-       MessageBox(hDlg, "Invalid data rate",
-                  "Option Error", MB_OK|MB_ICONEXCLAMATION);
-       return TRUE;
-      }
-      dcb.BaudRate = value;
-
-      hwndCombo = GetDlgItem(hDlg, OPT_Bits);
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
-      dcb.ByteSize = cdDataBits[index].value;
-
-      hwndCombo = GetDlgItem(hDlg, OPT_Parity);
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
-      dcb.Parity = cdParity[index].value;
-
-      hwndCombo = GetDlgItem(hDlg, OPT_StopBits);
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
-      dcb.StopBits = cdStopBits[index].value;
-
-      hwndCombo = GetDlgItem(hDlg, OPT_Flow);
-      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
-      switch (cdFlow[index].value) {
-      case FLOW_NONE:
-       dcb.fOutX = FALSE;
-       dcb.fOutxCtsFlow = FALSE;
-       dcb.fOutxDsrFlow = FALSE;
-       break;
-      case FLOW_CTS:
-       dcb.fOutX = FALSE;
-       dcb.fOutxCtsFlow = TRUE;
-       dcb.fOutxDsrFlow = FALSE;
-       break;
-      case FLOW_DSR:
-       dcb.fOutX = FALSE;
-       dcb.fOutxCtsFlow = FALSE;
-       dcb.fOutxDsrFlow = TRUE;
-       break;
-      case FLOW_XOFF:
-       dcb.fOutX = TRUE;
-       dcb.fOutxCtsFlow = FALSE;
-       dcb.fOutxDsrFlow = FALSE;
-       break;
-      }
-      if (!SetCommState(hCommPort, (LPDCB) &dcb)) {
-       err = GetLastError();
-       switch(MessageBox(hDlg, 
-                        "Failed to set comm port state;\r\ninvalid options?",
-                        "Option Error", MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {
-       case IDABORT:
-         DisplayFatalError("Failed to set comm port state", err, 1);
-         exit(1);  /*is it ok to do this from here?*/
-
-       case IDRETRY:
-         return TRUE;
-
-       case IDIGNORE:
-         EndDialog(hDlg, TRUE);
-         return TRUE;
-       }
-      }
-
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    default:
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID
-CommPortOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * Load Options dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-VOID
-SetLoadOptionEnables(HWND hDlg)
-{
-  UINT state;
-
-  state = IsDlgButtonChecked(hDlg, OPT_Autostep);
-  EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);
-}
-
-LRESULT CALLBACK
-LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  char buf[MSG_SIZ];
-  float fnumber;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    if (appData.timeDelay >= 0.0) {
-      CheckDlgButton(hDlg, OPT_Autostep, TRUE);
-      sprintf(buf, "%.2g", appData.timeDelay);
-      SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);
-    } else {
-      CheckDlgButton(hDlg, OPT_Autostep, FALSE);
-    }
-    SetLoadOptionEnables(hDlg);
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-      if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {
-       GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);
-       if (sscanf(buf, "%f", &fnumber) != 1) {
-         MessageBox(hDlg, "Invalid load game step rate",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-       }
-       appData.timeDelay = fnumber;
-      } else {
-       appData.timeDelay = (float) -1.0;
-      }
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    default:
-      SetLoadOptionEnables(hDlg);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-
-VOID 
-LoadOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * Save Options dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-VOID
-SetSaveOptionEnables(HWND hDlg)
-{
-  UINT state;
-
-  state = IsDlgButtonChecked(hDlg, OPT_Autosave);
-  EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);
-  if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&
-      !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {
-    CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);
-  }
-
-  state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);
-  EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);
-}
-
-LRESULT CALLBACK
-SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  char buf[MSG_SIZ];
-  FILE *f;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    if (*appData.saveGameFile != NULLCHAR) {
-      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);
-      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);
-      SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);
-    } else if (appData.autoSaveGames) {
-      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);
-      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);
-    } else {
-      CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);
-    }
-    if (appData.oldSaveStyle) {
-      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);
-    } else {
-      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);
-    }
-    CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );
-    SetSaveOptionEnables(hDlg);
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-      if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {
-       appData.autoSaveGames = TRUE;
-       if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {
-         appData.saveGameFile = "";
-       } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {
-         GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);
-         if (*buf == NULLCHAR) {
-           MessageBox(hDlg, "Invalid save game file name",
-                      "Option Error", MB_OK|MB_ICONEXCLAMATION);
-           return FALSE;
-         }
-         if ((isalpha(buf[0]) && buf[1] == ':') ||
-           (buf[0] == '\\' && buf[1] == '\\')) {
-           appData.saveGameFile = strdup(buf);
-         } else {
-           char buf2[MSG_SIZ], buf3[MSG_SIZ];
-           char *dummy;
-           GetCurrentDirectory(MSG_SIZ, buf3);
-           SetCurrentDirectory(installDir);
-           if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {
-             appData.saveGameFile = strdup(buf2);
-           } else {
-             appData.saveGameFile = strdup(buf);
-           }
-           SetCurrentDirectory(buf3);
-         }
-       }
-      } else {
-       appData.autoSaveGames = FALSE;
-       appData.saveGameFile = "";
-      }
-      appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);
-      appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case OPT_AVBrowse:
-      f = OpenFileDialog(hDlg, "a", NULL, 
-                        appData.oldSaveStyle ? "gam" : "pgn", 
-                        GAME_FILT, "Browse for Auto Save File", 
-                        NULL, NULL, buf);
-      if (f != NULL) {
-       fclose(f);
-       SetDlgItemText(hDlg, OPT_AVFilename, buf);
-      }
-      break;
-
-    default:
-      SetSaveOptionEnables(hDlg);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID
-SaveOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * Time Control Options dialog functions
- *
-\*---------------------------------------------------------------------------*/
-
-VOID
-SetTimeControlEnables(HWND hDlg)
-{
-  UINT state;
-
-  state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);
-  EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);
-}
-
-
-LRESULT CALLBACK
-TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  char buf[MSG_SIZ];
-  int mps, increment, odds1, odds2;
-  BOOL ok, ok2;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-    /* Initialize the dialog items */
-    if (appData.clockMode && !appData.icsActive) {
-      if (appData.timeIncrement == -1) {
-       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseInc,
-                        OPT_TCUseMoves);
-       SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);
-       SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,
-                     FALSE);
-       SetDlgItemText(hDlg, OPT_TCTime2, "");
-       SetDlgItemText(hDlg, OPT_TCInc, "");
-      } else {
-       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseInc,
-                        OPT_TCUseInc);
-       SetDlgItemText(hDlg, OPT_TCTime, "");
-       SetDlgItemText(hDlg, OPT_TCMoves, "");
-       SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);
-       SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);
-      }
-      SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);
-      SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);
-      SetTimeControlEnables(hDlg);
-    }
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-      if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {
-       increment = -1;
-       mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);
-       if (!ok || mps <= 0) {
-         MessageBox(hDlg, "Invalid moves per time control",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-       }
-       GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);
-       if (!ParseTimeControl(buf, increment, mps)) {
-         MessageBox(hDlg, "Invalid minutes per time control",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-       }
-      } else {
-       increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);
-       mps = appData.movesPerSession;
-       if (!ok || increment < 0) {
-         MessageBox(hDlg, "Invalid increment",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-       }
-       GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);
-       if (!ParseTimeControl(buf, increment, mps)) {
-         MessageBox(hDlg, "Invalid initial time",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-       }
-      }
-      odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);
-      odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);
-      if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {
-         MessageBox(hDlg, "Invalid time-odds factor",
-                    "Option Error", MB_OK|MB_ICONEXCLAMATION);
-         return FALSE;
-      }
-      appData.timeControl = strdup(buf);
-      appData.movesPerSession = mps;
-      appData.timeIncrement = increment;
-      appData.firstTimeOdds  = first.timeOdds  = odds1;
-      appData.secondTimeOdds = second.timeOdds = odds2;
-      Reset(TRUE, TRUE);
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    default:
-      SetTimeControlEnables(hDlg);
-      break;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID
-TimeControlOptionsPopup(HWND hwnd)
-{
-  if (gameMode != BeginningOfGame) {
-    DisplayError("Changing time control during a game is not implemented", 0);
-  } else {
-    FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);
-    DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);
-    FreeProcInstance(lpProc);
-  }
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * Engine Options Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))
-#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))
-
-#define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))
-
-LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-
-    /* Initialize the dialog items */
-    CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);
-    CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);
-    CHECK_BOX(IDC_EpShowThinking, appData.showThinking);
-    CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);
-
-    CHECK_BOX(IDC_TestClaims, appData.testClaims);
-    CHECK_BOX(IDC_DetectMates, appData.checkMates);
-    CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);
-    CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);
-
-    CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);
-    CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);
-
-    SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );
-    SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );
-
-    SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );
-    SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );
-
-    SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );
-    SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );
-
-    SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );
-    SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );
-
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      /* Read changed options from the dialog box */
-      PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));
-      PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));
-      appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up
-      appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);
-      ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output
-      appData.testClaims    = IS_CHECKED(IDC_TestClaims);
-      appData.checkMates    = IS_CHECKED(IDC_DetectMates);
-      appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);
-      appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);
-
-      appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );
-      appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );
-      appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );
-      appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );
-
-      appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);
-      appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);
-
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case IDC_EpDrawMoveCount:
-    case IDC_EpAdjudicationThreshold:
-    case IDC_DrawRepeats:
-    case IDC_RuleMoves:
-        if( HIWORD(wParam) == EN_CHANGE ) {
-            int n1_ok;
-            int n2_ok;
-            int n3_ok;
-            int n4_ok;
-
-            GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );
-            GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );
-            GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );
-            GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );
-
-            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );
-        }
-        return TRUE;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID EnginePlayOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc;
-
-  lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
-
-/*---------------------------------------------------------------------------*\
- *
- * UCI Options Dialog functions
- *
-\*---------------------------------------------------------------------------*/
-static BOOL BrowseForFolder( const char * title, char * path )
-{
-    BOOL result = FALSE;
-    BROWSEINFO bi;
-    LPITEMIDLIST pidl;
-
-    ZeroMemory( &bi, sizeof(bi) );
-
-    bi.lpszTitle = title == 0 ? "Choose Folder" : title;
-    bi.ulFlags = BIF_RETURNONLYFSDIRS;
-
-    pidl = SHBrowseForFolder( &bi );
-
-    if( pidl != 0 ) {
-        IMalloc * imalloc = 0;
-
-        if( SHGetPathFromIDList( pidl, path ) ) {
-            result = TRUE;
-        }
-
-        if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {
-            imalloc->lpVtbl->Free(imalloc,pidl);
-            imalloc->lpVtbl->Release(imalloc);
-        }
-    }
-
-    return result;
-}
-
-LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  char buf[MAX_PATH];
-  int oldCores;
-
-  switch (message) {
-  case WM_INITDIALOG: /* message: initialize dialog box */
-
-    /* Center the dialog over the application window */
-    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
-
-    /* Initialize the dialog items */
-    SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );
-    SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );
-    SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );
-    SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );
-    CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );
-    SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );
-    // [HGM] smp: input field for nr of cores:
-    SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );
-    // [HGM] book: tick boxes for own book use
-    CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );
-    CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );
-
-    SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );
-
-    return TRUE;
-
-  case WM_COMMAND: /* message: received a command */
-    switch (LOWORD(wParam)) {
-    case IDOK:
-      GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );
-      appData.polyglotDir = strdup(buf);
-      appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );
-      appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );
-      GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );
-      appData.defaultPathEGTB = strdup(buf);
-      GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );
-      appData.polyglotBook = strdup(buf);
-      appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );
-      // [HGM] smp: get nr of cores:
-      oldCores = appData.smpCores;
-      appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );
-      if(appData.smpCores != oldCores) NewSettingEvent(FALSE, "cores", appData.smpCores);
-      // [HGM] book: read tick boxes for own book use
-      appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );
-      appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );
-
-      if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);
-      EndDialog(hDlg, TRUE);
-      return TRUE;
-
-    case IDCANCEL:
-      EndDialog(hDlg, FALSE);
-      return TRUE;
-
-    case IDC_BrowseForBook:
-      {
-          char filter[] = { 
-              'A','l','l',' ','F','i','l','e','s', 0,
-              '*','.','*', 0,
-              'B','I','N',' ','F','i','l','e','s', 0,
-              '*','.','b','i','n', 0,
-              0 };
-
-          OPENFILENAME ofn;
-
-          strcpy( buf, "" );
-
-          ZeroMemory( &ofn, sizeof(ofn) );
-
-          ofn.lStructSize = sizeof(ofn);
-          ofn.hwndOwner = hDlg;
-          ofn.hInstance = hInst;
-          ofn.lpstrFilter = filter;
-          ofn.lpstrFile = buf;
-          ofn.nMaxFile = sizeof(buf);
-          ofn.lpstrTitle = "Choose Book";
-          ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;
-
-          if( GetOpenFileName( &ofn ) ) {
-              SetDlgItemText( hDlg, IDC_BookFile, buf );
-          }
-      }
-      return TRUE;
-
-    case IDC_BrowseForPolyglotDir:
-      if( BrowseForFolder( "Choose Polyglot Directory", buf ) ) {
-        SetDlgItemText( hDlg, IDC_PolyglotDir, buf );
-
-        strcat( buf, "\\polyglot.exe" );
-
-        if( GetFileAttributes(buf) == 0xFFFFFFFF ) {
-            MessageBox( hDlg, "Polyglot was not found in the specified folder!", "Warning", MB_OK | MB_ICONWARNING );
-        }
-      }
-      return TRUE;
-
-    case IDC_BrowseForEGTB:
-      if( BrowseForFolder( "Choose EGTB Directory:", buf ) ) {
-        SetDlgItemText( hDlg, IDC_PathToEGTB, buf );
-      }
-      return TRUE;
-
-    case IDC_HashSize:
-    case IDC_SizeOfEGTB:
-        if( HIWORD(wParam) == EN_CHANGE ) {
-            int n1_ok;
-            int n2_ok;
-
-            GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );
-            GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );
-
-            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );
-        }
-        return TRUE;
-    }
-    break;
-  }
-  return FALSE;
-}
-
-VOID UciOptionsPopup(HWND hwnd)
-{
-  FARPROC lpProc;
-
-  lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);
-  DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);
-  FreeProcInstance(lpProc);
-}
+    if (!appData.colorize) {\r
+       CHARFORMAT cf;\r
+       COLORREF background = ParseColorName(COLOR_BKGD);\r
+       /*\r
+       SetDefaultTextAttribs();\r
+        Colorize(currentColorClass);\r
+       */\r
+       cf.cbSize = sizeof(CHARFORMAT);\r
+       cf.dwMask = CFM_COLOR;\r
+       cf.crTextColor = ParseColorName(COLOR_NORMAL);\r
+\r
+       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
+         EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
+        SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+         EM_SETBKGNDCOLOR, FALSE, background);\r
+       SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
+         EM_SETBKGNDCOLOR, FALSE, background);\r
+      }\r
+\r
+      if (cbc != consoleBackgroundColor) {\r
+       consoleBackgroundColor = cbc;\r
+       if (appData.colorize) {\r
+         SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
+         SendDlgItemMessage(hwndConsole, OPT_ConsoleInput, \r
+           EM_SETBKGNDCOLOR, FALSE, consoleBackgroundColor);\r
+       }\r
+      }\r
+\r
+      for (i=0; i < NColorClasses - 1; i++) {\r
+       textAttribs[i].color   = mca[i].color;\r
+       textAttribs[i].effects = mca[i].effects;\r
+      }\r
+\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case OPT_ChooseShoutColor:\r
+      ColorizeTextPopup(hDlg, ColorShout);\r
+      UpdateSampleText(hDlg, OPT_SampleShout, &mca[ColorShout]);\r
+      break;\r
+\r
+    case OPT_ChooseSShoutColor:\r
+      ColorizeTextPopup(hDlg, ColorSShout);\r
+      UpdateSampleText(hDlg, OPT_SampleSShout, &mca[ColorSShout]);\r
+      break;\r
+\r
+    case OPT_ChooseChannel1Color:\r
+      ColorizeTextPopup(hDlg, ColorChannel1);\r
+      UpdateSampleText(hDlg, OPT_SampleChannel1, \r
+                      &colorizeAttribs[ColorChannel1]);\r
+      break;\r
+\r
+    case OPT_ChooseChannelColor:\r
+      ColorizeTextPopup(hDlg, ColorChannel);\r
+      UpdateSampleText(hDlg, OPT_SampleChannel, &mca[ColorChannel]);\r
+      break;\r
+\r
+    case OPT_ChooseKibitzColor:\r
+      ColorizeTextPopup(hDlg, ColorKibitz);\r
+      UpdateSampleText(hDlg, OPT_SampleKibitz, &mca[ColorKibitz]);\r
+      break;\r
+\r
+    case OPT_ChooseTellColor:\r
+      ColorizeTextPopup(hDlg, ColorTell);\r
+      UpdateSampleText(hDlg, OPT_SampleTell, &mca[ColorTell]);\r
+      break;\r
+\r
+    case OPT_ChooseChallengeColor:\r
+      ColorizeTextPopup(hDlg, ColorChallenge);\r
+      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
+      break;\r
+\r
+    case OPT_ChooseRequestColor:\r
+      ColorizeTextPopup(hDlg, ColorRequest);\r
+      UpdateSampleText(hDlg, OPT_SampleRequest, &mca[ColorRequest]);\r
+      break;\r
+\r
+    case OPT_ChooseSeekColor:\r
+      ColorizeTextPopup(hDlg, ColorSeek);\r
+      UpdateSampleText(hDlg, OPT_SampleSeek, &mca[ColorSeek]);\r
+      break;\r
+\r
+    case OPT_ChooseNormalColor:\r
+      ColorizeTextPopup(hDlg, ColorNormal);\r
+      UpdateSampleText(hDlg, OPT_SampleNormal, &mca[ColorNormal]);\r
+      break;\r
+\r
+    case OPT_ChooseBackgroundColor:\r
+      if (ChangeColor(hDlg, &cbc)) {\r
+       SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
+       SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
+      }\r
+      break;\r
+\r
+    case OPT_DefaultColors:\r
+      for (i=0; i < NColorClasses - 1; i++)\r
+       ParseAttribs(&mca[i].color, \r
+                    &mca[i].effects,\r
+                    defaultTextAttribs[i]);\r
+\r
+      cbc = ParseColorName(COLOR_BKGD);\r
+      SendDlgItemMessage(hDlg, OPT_SampleShout,     EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleSShout,    EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleChannel1,  EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleChannel,   EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleKibitz,    EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleTell,      EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleChallenge, EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleRequest,   EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleSeek,      EM_SETBKGNDCOLOR, 0, cbc);\r
+      SendDlgItemMessage(hDlg, OPT_SampleNormal,    EM_SETBKGNDCOLOR, 0, cbc);\r
+\r
+      UpdateSampleText(hDlg, OPT_SampleShout,     &mca[ColorShout]);\r
+      UpdateSampleText(hDlg, OPT_SampleSShout,    &mca[ColorSShout]);\r
+      UpdateSampleText(hDlg, OPT_SampleChannel1,  &mca[ColorChannel1]);\r
+      UpdateSampleText(hDlg, OPT_SampleChannel,   &mca[ColorChannel]);\r
+      UpdateSampleText(hDlg, OPT_SampleKibitz,    &mca[ColorKibitz]);\r
+      UpdateSampleText(hDlg, OPT_SampleTell,      &mca[ColorTell]);\r
+      UpdateSampleText(hDlg, OPT_SampleChallenge, &mca[ColorChallenge]);\r
+      UpdateSampleText(hDlg, OPT_SampleRequest,   &mca[ColorRequest]);\r
+      UpdateSampleText(hDlg, OPT_SampleSeek,      &mca[ColorSeek]);\r
+      UpdateSampleText(hDlg, OPT_SampleNormal,    &mca[ColorNormal]);\r
+      break;\r
+\r
+    default:\r
+      SetIcsOptionEnables(hDlg);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+IcsOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)IcsOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_IcsOptions), hwnd,\r
+           (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Fonts Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+VOID\r
+SetSampleFontText(HWND hwnd, int id, const MyFont *mf)\r
+{\r
+  char buf[MSG_SIZ];\r
+  HWND hControl;\r
+  HDC hdc;\r
+  CHARFORMAT cf;\r
+  SIZE size;\r
+  RECT rectClient, rectFormat;\r
+  HFONT oldFont;\r
+  POINT center;\r
+  int len;\r
+\r
+  len = sprintf(buf, "%.0f pt. %s%s%s\n",\r
+               mf->mfp.pointSize, mf->mfp.faceName,\r
+               mf->mfp.bold ? " bold" : "",\r
+               mf->mfp.italic ? " italic" : "");\r
+  SetDlgItemText(hwnd, id, buf);\r
+\r
+  hControl = GetDlgItem(hwnd, id);\r
+  hdc = GetDC(hControl);\r
+  SetMapMode(hdc, MM_TEXT);    /* 1 pixel == 1 logical unit */\r
+  oldFont = SelectObject(hdc, mf->hf);\r
+  \r
+  /* get number of logical units necessary to display font name */\r
+  GetTextExtentPoint32(hdc, buf, len, &size);\r
+\r
+  /* calculate formatting rectangle in the rich edit control.  \r
+   * May be larger or smaller than the actual control.\r
+   */\r
+  GetClientRect(hControl, &rectClient);\r
+  center.x = (rectClient.left + rectClient.right) / 2;\r
+  center.y = (rectClient.top  + rectClient.bottom) / 2;\r
+  rectFormat.top    = center.y - (size.cy / 2) - 1;\r
+  rectFormat.bottom = center.y + (size.cy / 2) + 1;\r
+  rectFormat.left   = center.x - (size.cx / 2) - 1;\r
+  rectFormat.right  = center.x + (size.cx / 2) + 1;\r
+\r
+  cf.cbSize = sizeof(CHARFORMAT);\r
+  cf.dwMask = CFM_FACE|CFM_SIZE|CFM_CHARSET|CFM_BOLD|CFM_ITALIC;\r
+  cf.dwEffects = 0;\r
+  if (mf->lf.lfWeight == FW_BOLD) cf.dwEffects |= CFE_BOLD;\r
+  if (mf->lf.lfItalic) cf.dwEffects |= CFE_ITALIC;\r
+  strcpy(cf.szFaceName, mf->mfp.faceName);\r
+  /*\r
+   * yHeight is expressed in twips.  A twip is 1/20 of a font's point\r
+   * size. See documentation of CHARFORMAT.  --msw\r
+   */\r
+  cf.yHeight = (int)(mf->mfp.pointSize * 20.0 + 0.5);\r
+  cf.bCharSet = mf->lf.lfCharSet;\r
+  cf.bPitchAndFamily = mf->lf.lfPitchAndFamily;\r
+\r
+  /* format the text in the rich edit control */\r
+  SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cf);\r
+  SendMessage(hControl, EM_SETRECT, (WPARAM)0, (LPARAM) &rectFormat);\r
+\r
+  /* clean up */\r
+  SelectObject(hdc, oldFont);\r
+  ReleaseDC(hControl, hdc);\r
+}\r
+\r
+VOID\r
+CopyFont(MyFont *dest, const MyFont *src)\r
+{\r
+  dest->mfp.pointSize = src->mfp.pointSize;\r
+  dest->mfp.bold      = src->mfp.bold;\r
+  dest->mfp.italic    = src->mfp.italic;\r
+  dest->mfp.underline = src->mfp.underline;\r
+  dest->mfp.strikeout = src->mfp.strikeout;\r
+  dest->mfp.charset   = src->mfp.charset;\r
+  lstrcpy(dest->mfp.faceName, src->mfp.faceName);\r
+  CreateFontInMF(dest);\r
+}\r
+\r
+\r
+LRESULT CALLBACK\r
+FontOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  static MyFont workFont[NUM_FONTS];\r
+  static BOOL firstPaint;\r
+  int i;\r
+  RECT rect;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG:\r
+\r
+    /* copy the current font settings into a working copy */\r
+    for (i=0; i < NUM_FONTS; i++)\r
+      CopyFont(&workFont[i], font[boardSize][i]);\r
+\r
+    if (!appData.icsActive)\r
+      EnableWindow(GetDlgItem(hDlg, OPT_ChooseConsoleFont), FALSE);\r
+\r
+    firstPaint = TRUE; /* see rant below */\r
+\r
+    /* If I don't call SetFocus(), the dialog won't respond to the keyboard\r
+     * when first drawn. Why is this the only dialog that behaves this way? Is\r
+     * is the WM_PAINT stuff below?? Sigh...\r
+     */\r
+    SetFocus(GetDlgItem(hDlg, IDOK));\r
+    break;\r
+\r
+  case WM_PAINT:\r
+    /* This should not be necessary. However, if SetSampleFontText() is called\r
+     * in response to WM_INITDIALOG, the strings are not properly centered in\r
+     * the controls when the dialog first appears. I can't figure out why, so\r
+     * this is the workaround.  --msw\r
+     */\r
+    if (firstPaint) {\r
+      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
+      firstPaint = FALSE;\r
+    }\r
+    break;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+\r
+    case IDOK:\r
+      /* again, it seems to avoid redraw problems if we call EndDialog first */\r
+      EndDialog(hDlg, FALSE);\r
+\r
+      /* copy modified settings back to the fonts array */\r
+      for (i=0; i < NUM_FONTS; i++)\r
+       CopyFont(font[boardSize][i], &workFont[i]);\r
+\r
+      /* a sad necessity due to the original design of having a separate\r
+       * console font, tags font, and comment font for each board size.  IMHO\r
+       * these fonts should not be dependent on the current board size.  I'm\r
+       * running out of time, so I am doing this hack rather than redesign the\r
+       * data structure. Besides, I think if I redesigned the data structure, I\r
+       * might break backwards compatibility with old winboard.ini files.\r
+       * --msw\r
+       */\r
+      for (i=0; i < NUM_SIZES; i++) {\r
+       CopyFont(font[i][EDITTAGS_FONT], &workFont[EDITTAGS_FONT]);\r
+       CopyFont(font[i][CONSOLE_FONT],  &workFont[CONSOLE_FONT]);\r
+       CopyFont(font[i][COMMENT_FONT],  &workFont[COMMENT_FONT]);\r
+       CopyFont(font[i][MOVEHISTORY_FONT],  &workFont[MOVEHISTORY_FONT]);\r
+      }\r
+      /* end sad necessity */\r
+\r
+      InitDrawingSizes(boardSize, 0);\r
+      InvalidateRect(hwndMain, NULL, TRUE);\r
+\r
+      if (commentDialog) {\r
+       SendDlgItemMessage(commentDialog, OPT_CommentText,\r
+         WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf, \r
+         MAKELPARAM(TRUE, 0));\r
+       GetClientRect(GetDlgItem(commentDialog, OPT_CommentText), &rect);\r
+       InvalidateRect(commentDialog, &rect, TRUE);\r
+      }\r
+\r
+      if (editTagsDialog) {\r
+       SendDlgItemMessage(editTagsDialog, OPT_TagsText,\r
+         WM_SETFONT, (WPARAM)font[boardSize][EDITTAGS_FONT]->hf, \r
+         MAKELPARAM(TRUE, 0));\r
+       GetClientRect(GetDlgItem(editTagsDialog, OPT_TagsText), &rect);\r
+       InvalidateRect(editTagsDialog, &rect, TRUE);\r
+      }\r
+\r
+      if( moveHistoryDialog != NULL ) {\r
+       SendDlgItemMessage(moveHistoryDialog, IDC_MoveHistory,\r
+         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
+         MAKELPARAM(TRUE, 0));\r
+        SendMessage( moveHistoryDialog, WM_INITDIALOG, 0, 0 );\r
+//     InvalidateRect(editTagsDialog, NULL, TRUE); // [HGM] this ws improperly cloned?\r
+      }\r
+\r
+      if( engineOutputDialog != NULL ) {\r
+       SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo1,\r
+         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
+         MAKELPARAM(TRUE, 0));\r
+       SendDlgItemMessage(engineOutputDialog, IDC_EngineMemo2,\r
+         WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, \r
+         MAKELPARAM(TRUE, 0));\r
+      }\r
+\r
+      if (hwndConsole) {\r
+       ChangedConsoleFont();\r
+      }\r
+\r
+      for (i=0; i<NUM_FONTS; i++)\r
+       DeleteObject(&workFont[i].hf);\r
+\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      for (i=0; i<NUM_FONTS; i++)\r
+       DeleteObject(&workFont[i].hf);\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case OPT_ChooseClockFont:\r
+      MyCreateFont(hDlg, &workFont[CLOCK_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
+      break;\r
+\r
+    case OPT_ChooseMessageFont:\r
+      MyCreateFont(hDlg, &workFont[MESSAGE_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
+      break;\r
+\r
+    case OPT_ChooseCoordFont:\r
+      MyCreateFont(hDlg, &workFont[COORD_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
+      break;\r
+\r
+    case OPT_ChooseTagFont:\r
+      MyCreateFont(hDlg, &workFont[EDITTAGS_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
+      break;\r
+\r
+    case OPT_ChooseCommentsFont:\r
+      MyCreateFont(hDlg, &workFont[COMMENT_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
+      break;\r
+\r
+    case OPT_ChooseConsoleFont:\r
+      MyCreateFont(hDlg, &workFont[CONSOLE_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
+      break;\r
+\r
+    case OPT_ChooseMoveHistoryFont:\r
+      MyCreateFont(hDlg, &workFont[MOVEHISTORY_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
+      break;\r
+\r
+    case OPT_DefaultFonts:\r
+      for (i=0; i<NUM_FONTS; i++) {\r
+       DeleteObject(&workFont[i].hf);\r
+       ParseFontName(font[boardSize][i]->def, &workFont[i].mfp);\r
+       CreateFontInMF(&workFont[i]);\r
+      }\r
+      SetSampleFontText(hDlg, OPT_SampleClockFont, &workFont[CLOCK_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleMessageFont, &workFont[MESSAGE_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleCoordFont, &workFont[COORD_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleTagFont, &workFont[EDITTAGS_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleCommentsFont, &workFont[COMMENT_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleConsoleFont, &workFont[CONSOLE_FONT]);\r
+      SetSampleFontText(hDlg, OPT_SampleMoveHistoryFont, &workFont[MOVEHISTORY_FONT]);\r
+      break;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+FontsOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)FontOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_Fonts), hwnd,\r
+         (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Sounds Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+\r
+SoundComboData soundComboData[] = {\r
+  {"Move", NULL},\r
+  {"Bell", NULL},\r
+  {"ICS Alarm", NULL},\r
+  {"ICS Win", NULL},\r
+  {"ICS Loss", NULL},\r
+  {"ICS Draw", NULL},\r
+  {"ICS Unfinished", NULL},\r
+  {"Shout", NULL},\r
+  {"SShout/CShout", NULL},\r
+  {"Channel 1", NULL},\r
+  {"Channel", NULL},\r
+  {"Kibitz", NULL},\r
+  {"Tell", NULL},\r
+  {"Challenge", NULL},\r
+  {"Request", NULL},\r
+  {"Seek", NULL},\r
+  {NULL, NULL},\r
+};\r
+\r
+\r
+void\r
+InitSoundComboData(SoundComboData *scd)\r
+{\r
+  SoundClass sc;\r
+  ColorClass cc;\r
+  int index;\r
+\r
+  /* copy current sound settings to combo array */\r
+\r
+  for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
+    scd[sc].name = strdup(sounds[sc].name);\r
+  }\r
+  for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
+    index = (int)cc + (int)NSoundClasses;\r
+    scd[index].name = strdup(textAttribs[cc].sound.name);\r
+  }\r
+}\r
+\r
+\r
+void\r
+ResetSoundComboData(SoundComboData *scd)\r
+{\r
+  while (scd->label) {\r
+    if (scd->name != NULL) {\r
+      free (scd->name);\r
+      scd->name = NULL;\r
+    }\r
+    scd++;\r
+  }\r
+}\r
+\r
+void\r
+InitSoundCombo(HWND hwndCombo, SoundComboData *scd)\r
+{\r
+  char buf[255];\r
+  DWORD err;\r
+  DWORD cnt = 0;\r
+  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
+\r
+  /* send the labels to the combo box */\r
+  while (scd->label) {\r
+    err = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) scd->label);\r
+    if (err != cnt++) {\r
+      sprintf(buf, "InitSoundCombo(): err '%d', cnt '%d'\n",\r
+         (int)err, (int)cnt);\r
+      MessageBox(NULL, buf, NULL, MB_OK);\r
+    }\r
+    scd++;\r
+  }\r
+  SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+}\r
+\r
+int\r
+SoundDialogWhichRadio(HWND hDlg)\r
+{\r
+  if (IsDlgButtonChecked(hDlg, OPT_NoSound)) return OPT_NoSound;\r
+  if (IsDlgButtonChecked(hDlg, OPT_DefaultBeep)) return OPT_DefaultBeep;\r
+  if (IsDlgButtonChecked(hDlg, OPT_BuiltInSound)) return OPT_BuiltInSound;\r
+  if (IsDlgButtonChecked(hDlg, OPT_WavFile)) return OPT_WavFile;\r
+  return -1;\r
+}\r
+\r
+VOID\r
+SoundDialogSetEnables(HWND hDlg, int radio)\r
+{\r
+  EnableWindow(GetDlgItem(hDlg, OPT_BuiltInSoundName),\r
+              radio == OPT_BuiltInSound);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_WavFileName), radio == OPT_WavFile);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_BrowseSound), radio == OPT_WavFile);\r
+}\r
+\r
+char *\r
+SoundDialogGetName(HWND hDlg, int radio)\r
+{\r
+  static char buf[MSG_SIZ], buf2[MSG_SIZ], buf3[MSG_SIZ];\r
+  char *dummy, *ret;\r
+  switch (radio) {\r
+  case OPT_NoSound:\r
+  default:\r
+    return "";\r
+  case OPT_DefaultBeep:\r
+    return "$";\r
+  case OPT_BuiltInSound:\r
+    buf[0] = '!';\r
+    GetDlgItemText(hDlg, OPT_BuiltInSoundName, buf + 1, sizeof(buf) - 1);\r
+    return buf;\r
+  case OPT_WavFile:\r
+    GetDlgItemText(hDlg, OPT_WavFileName, buf, sizeof(buf));\r
+    GetCurrentDirectory(MSG_SIZ, buf3);\r
+    SetCurrentDirectory(installDir);\r
+    if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
+      ret = buf2;\r
+    } else {\r
+      ret = buf;\r
+    }\r
+    SetCurrentDirectory(buf3);\r
+    return ret;\r
+  }\r
+}\r
+\r
+void\r
+DisplaySelectedSound(HWND hDlg, HWND hCombo, const char *name)\r
+{\r
+  int radio;\r
+  /* \r
+   * I think it's best to clear the combo and edit boxes. It looks stupid\r
+   * to have a value from another sound event sitting there grayed out.\r
+   */\r
+  SetDlgItemText(hDlg, OPT_WavFileName, "");\r
+  SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
+\r
+  if (appData.debugMode)\r
+      fprintf(debugFP, "DisplaySelectedSound(,,'%s'):\n", name);\r
+  switch (name[0]) {\r
+  case NULLCHAR:\r
+    radio = OPT_NoSound;\r
+    break;\r
+  case '$':\r
+    if (name[1] == NULLCHAR) {\r
+      radio = OPT_DefaultBeep;\r
+    } else {\r
+      radio = OPT_WavFile;\r
+      SetDlgItemText(hDlg, OPT_WavFileName, name);\r
+    }\r
+    break;\r
+  case '!':\r
+    if (name[1] == NULLCHAR) {\r
+      radio = OPT_NoSound;\r
+    } else {\r
+      radio = OPT_BuiltInSound;\r
+      if (SendMessage(hCombo, CB_SELECTSTRING, (WPARAM) -1, \r
+                     (LPARAM) (name + 1)) == CB_ERR) {\r
+       SendMessage(hCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
+       SendMessage(hCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) (name + 1));\r
+      }\r
+    }\r
+    break;\r
+  default:\r
+    radio = OPT_WavFile;\r
+    SetDlgItemText(hDlg, OPT_WavFileName, name);\r
+    break;\r
+  }\r
+  SoundDialogSetEnables(hDlg, radio);\r
+  CheckRadioButton(hDlg, OPT_NoSound, OPT_WavFile, radio);\r
+}\r
+    \r
+\r
+char *builtInSoundNames[] = BUILT_IN_SOUND_NAMES;\r
+\r
+LRESULT CALLBACK\r
+SoundOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  static HWND hSoundCombo;\r
+  static DWORD index;\r
+  static HWND hBISN;\r
+  int radio;\r
+  MySound tmp;\r
+  FILE *f;\r
+  char buf[MSG_SIZ];\r
+  char *newName;\r
+  SoundClass sc;\r
+  ColorClass cc;\r
+  SoundComboData *scd;\r
+  int oldMute;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG:\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+\r
+    /* Initialize the built-in sounds combo */\r
+    hBISN = GetDlgItem(hDlg, OPT_BuiltInSoundName);\r
+     InitComboStrings(hBISN, builtInSoundNames);\r
+\r
+    /* Initialize the  sound events combo */\r
+    index = 0;\r
+    InitSoundComboData(soundComboData);\r
+    hSoundCombo = GetDlgItem(hDlg, CBO_Sounds);\r
+    InitSoundCombo(hSoundCombo, soundComboData);\r
+\r
+    /* update the dialog */\r
+    DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+\r
+    if (((HWND)lParam == hSoundCombo) && \r
+       (HIWORD(wParam) == CBN_SELCHANGE)) {\r
+      /* \r
+       * the user has selected a new sound event. We must store the name for\r
+       * the previously selected event, then retrieve the name for the\r
+       * newly selected event and update the dialog. \r
+       */\r
+      radio = SoundDialogWhichRadio(hDlg);\r
+      newName = strdup(SoundDialogGetName(hDlg, radio));\r
+      \r
+      if (strcmp(newName, soundComboData[index].name) != 0) {\r
+       free(soundComboData[index].name);\r
+       soundComboData[index].name = newName;\r
+      } else {\r
+       free(newName);\r
+       newName = NULL;\r
+      }\r
+      /* now get the settings for the newly selected event */\r
+      index = SendMessage(hSoundCombo, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);\r
+      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
+      \r
+      return TRUE;\r
+    }\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* \r
+       * save the name for the currently selected sound event \r
+       */\r
+      radio = SoundDialogWhichRadio(hDlg);\r
+      newName = strdup(SoundDialogGetName(hDlg, radio));\r
+\r
+      if (strcmp(soundComboData[index].name, newName) != 0) {\r
+       free(soundComboData[index].name);\r
+       soundComboData[index].name = newName;\r
+      } else {\r
+       free(newName);\r
+       newName = NULL;\r
+      }\r
+\r
+      /* save all the sound names that changed and load the sounds */\r
+\r
+      for ( sc = (SoundClass)0; sc < NSoundClasses; sc++) {\r
+       if (strcmp(soundComboData[sc].name, sounds[sc].name) != 0) {\r
+         free(sounds[sc].name);\r
+         sounds[sc].name = strdup(soundComboData[sc].name);\r
+         MyLoadSound(&sounds[sc]);\r
+       }\r
+      }\r
+      for ( cc = (ColorClass)0; cc < NColorClasses - 2; cc++) {\r
+       index = (int)cc + (int)NSoundClasses;\r
+       if (strcmp(soundComboData[index].name, \r
+                  textAttribs[cc].sound.name) != 0) {\r
+         free(textAttribs[cc].sound.name);\r
+         textAttribs[cc].sound.name = strdup(soundComboData[index].name);\r
+         MyLoadSound(&textAttribs[cc].sound);\r
+       }\r
+      }\r
+\r
+       mute = FALSE; // [HGM] mute: switch sounds automatically on if we select one\r
+      CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,MF_BYCOMMAND|MF_UNCHECKED);\r
+      ResetSoundComboData(soundComboData);\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      ResetSoundComboData(soundComboData);\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case OPT_DefaultSounds:\r
+      /* can't use SetDefaultSounds() because we need to be able to "undo" if\r
+       * user selects "Cancel" later on. So we do it the hard way here.\r
+       */\r
+      scd = &soundComboData[0];\r
+      while (scd->label != NULL) {\r
+       if (scd->name != NULL) free(scd->name);\r
+       scd->name = strdup("");\r
+       scd++;\r
+      }\r
+      free(soundComboData[(int)SoundBell].name);\r
+      soundComboData[(int)SoundBell].name = strdup(SOUND_BELL);\r
+      DisplaySelectedSound(hDlg, hBISN, soundComboData[index].name);\r
+      break;\r
+\r
+    case OPT_PlaySound:\r
+      radio = SoundDialogWhichRadio(hDlg);\r
+      tmp.name = strdup(SoundDialogGetName(hDlg, radio));\r
+      tmp.data = NULL;\r
+      MyLoadSound(&tmp);\r
+       oldMute = mute; mute = FALSE; // [HGM] mute: always sound when user presses play, ignorig mute setting\r
+      MyPlaySound(&tmp);\r
+       mute = oldMute;\r
+      if (tmp.data  != NULL) FreeResource(tmp.data); // technically obsolete fn, but tmp.data is NOT malloc'd mem\r
+      if (tmp.name != NULL) free(tmp.name);\r
+      return TRUE;\r
+\r
+    case OPT_BrowseSound:\r
+      f = OpenFileDialog(hDlg, "rb", NULL, "wav", SOUND_FILT,\r
+       "Browse for Sound File", NULL, NULL, buf);\r
+      if (f != NULL) {\r
+       fclose(f);\r
+       SetDlgItemText(hDlg, OPT_WavFileName, buf);\r
+      }\r
+      return TRUE;\r
+\r
+    default:\r
+      radio = SoundDialogWhichRadio(hDlg);\r
+      SoundDialogSetEnables(hDlg, radio);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+VOID SoundOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc;\r
+\r
+  lpProc = MakeProcInstance((FARPROC)SoundOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_Sound), hwnd, (DLGPROC)lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Comm Port dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+\r
+#define FLOW_NONE   0\r
+#define FLOW_XOFF   1\r
+#define FLOW_CTS    2\r
+#define FLOW_DSR    3\r
+\r
+#define PORT_NONE\r
+\r
+ComboData cdPort[]     = { {"None", PORT_NONE}, {"COM1", 1}, {"COM2", 2},\r
+                          {"COM3", 3}, {"COM4", 4}, {NULL, 0} };\r
+ComboData cdDataRate[] = { {"110", 110}, {"300", 300}, {"600", 600}, {"1200", 1200},\r
+                          {"2400", 2400}, {"4800", 4800}, {"9600", 9600}, {"19200", 19200},\r
+                          {"38400", 38400}, {NULL, 0} };\r
+ComboData cdDataBits[] = { {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {NULL, 0} };\r
+ComboData cdParity[]   = { {"None", NOPARITY}, {"Odd", ODDPARITY}, {"Even", EVENPARITY},\r
+                          {"Mark", MARKPARITY}, {"Space", SPACEPARITY}, {NULL, 0} };\r
+ComboData cdStopBits[] = { {"1", ONESTOPBIT}, {"1.5", ONE5STOPBITS},\r
+                          {"2", TWOSTOPBITS}, {NULL, 0} };\r
+ComboData cdFlow[]     = { {"None", FLOW_NONE}, {"Xoff/Xon", FLOW_XOFF}, {"CTS", FLOW_CTS},\r
+                          {"DSR", FLOW_DSR}, {NULL, 0} };\r
+\r
+\r
+VOID\r
+ParseCommSettings(char *arg, DCB *dcb)\r
+{\r
+  int dataRate, count;\r
+  char bits[MSG_SIZ], parity[MSG_SIZ], stopBits[MSG_SIZ], flow[MSG_SIZ];\r
+  ComboData *cd;\r
+  count = sscanf(arg, "%d%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]%*[, ]%[^, ]",\r
+    &dataRate, bits, parity, stopBits, flow);\r
+  if (count != 5) goto cant_parse;\r
+  dcb->BaudRate = dataRate;\r
+  cd = cdDataBits;\r
+  while (cd->label != NULL) {\r
+    if (StrCaseCmp(cd->label, bits) == 0) {\r
+      dcb->ByteSize = cd->value;\r
+      break;\r
+    }\r
+    cd++;\r
+  }\r
+  if (cd->label == NULL) goto cant_parse;\r
+  cd = cdParity;\r
+  while (cd->label != NULL) {\r
+    if (StrCaseCmp(cd->label, parity) == 0) {\r
+      dcb->Parity = cd->value;\r
+      break;\r
+    }\r
+    cd++;\r
+  }\r
+  if (cd->label == NULL) goto cant_parse;\r
+  cd = cdStopBits;\r
+  while (cd->label != NULL) {\r
+    if (StrCaseCmp(cd->label, stopBits) == 0) {\r
+      dcb->StopBits = cd->value;\r
+      break;\r
+    }\r
+    cd++;\r
+  }\r
+  cd = cdFlow;\r
+  if (cd->label == NULL) goto cant_parse;\r
+  while (cd->label != NULL) {\r
+    if (StrCaseCmp(cd->label, flow) == 0) {\r
+      switch (cd->value) {\r
+      case FLOW_NONE:\r
+       dcb->fOutX = FALSE;\r
+       dcb->fOutxCtsFlow = FALSE;\r
+       dcb->fOutxDsrFlow = FALSE;\r
+       break;\r
+      case FLOW_CTS:\r
+       dcb->fOutX = FALSE;\r
+       dcb->fOutxCtsFlow = TRUE;\r
+       dcb->fOutxDsrFlow = FALSE;\r
+       break;\r
+      case FLOW_DSR:\r
+       dcb->fOutX = FALSE;\r
+       dcb->fOutxCtsFlow = FALSE;\r
+       dcb->fOutxDsrFlow = TRUE;\r
+       break;\r
+      case FLOW_XOFF:\r
+       dcb->fOutX = TRUE;\r
+       dcb->fOutxCtsFlow = FALSE;\r
+       dcb->fOutxDsrFlow = FALSE;\r
+       break;\r
+      }\r
+      break;\r
+    }\r
+    cd++;\r
+  }\r
+  if (cd->label == NULL) goto cant_parse;\r
+  return;\r
+cant_parse:\r
+    ExitArgError("Can't parse com port settings", arg);\r
+}\r
+\r
+\r
+VOID PrintCommSettings(FILE *f, char *name, DCB *dcb)\r
+{\r
+  char *flow = "??", *parity = "??", *stopBits = "??";\r
+  ComboData *cd;\r
+  \r
+  cd = cdParity;\r
+  while (cd->label != NULL) {\r
+    if (dcb->Parity == cd->value) {\r
+      parity = cd->label;\r
+      break;\r
+    }\r
+    cd++;\r
+  }\r
+  cd = cdStopBits;\r
+  while (cd->label != NULL) {\r
+    if (dcb->StopBits == cd->value) {\r
+      stopBits = cd->label;\r
+      break;\r
+    }\r
+    cd++;\r
+  }\r
+  if (dcb->fOutX) {\r
+    flow = cdFlow[FLOW_XOFF].label;\r
+  } else if (dcb->fOutxCtsFlow) {\r
+    flow = cdFlow[FLOW_CTS].label;\r
+  } else if (dcb->fOutxDsrFlow) {\r
+    flow = cdFlow[FLOW_DSR].label;\r
+  } else {\r
+    flow = cdFlow[FLOW_NONE].label;\r
+  }\r
+  fprintf(f, "/%s=%d,%d,%s,%s,%s\n", name,\r
+    (int)dcb->BaudRate, dcb->ByteSize, parity, stopBits, flow);\r
+}\r
+\r
+\r
+void\r
+InitCombo(HANDLE hwndCombo, ComboData *cd)\r
+{\r
+  SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
+\r
+  while (cd->label != NULL) {\r
+    SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) cd->label);\r
+    cd++;\r
+  }\r
+}\r
+\r
+void\r
+SelectComboValue(HANDLE hwndCombo, ComboData *cd, unsigned value)\r
+{\r
+  int i;\r
+\r
+  i = 0;\r
+  while (cd->label != NULL) {\r
+    if (cd->value == value) {\r
+      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) i, (LPARAM) 0);\r
+      return;\r
+    }\r
+    cd++;\r
+    i++;\r
+  }\r
+}\r
+\r
+LRESULT CALLBACK\r
+CommPortOptionsDialog(HWND hDlg, UINT message, WPARAM wParam,  LPARAM lParam)\r
+{\r
+  char buf[MSG_SIZ];\r
+  HANDLE hwndCombo;\r
+  char *p;\r
+  LRESULT index;\r
+  unsigned value;\r
+  int err;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow(hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    /* !! There should probably be some synchronization\r
+       in accessing hCommPort and dcb.  Or does modal nature\r
+       of this dialog box do it for us?\r
+       */\r
+    hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
+    InitCombo(hwndCombo, cdPort);\r
+    p = strrchr(appData.icsCommPort, '\\');\r
+    if (p++ == NULL) p = appData.icsCommPort;\r
+    if ((*p == '\0') ||\r
+       (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) p) == CB_ERR)) {\r
+      SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) "None");\r
+    }\r
+    EnableWindow(hwndCombo, hCommPort == NULL); /*!! don't allow change for now*/\r
+\r
+    hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
+    InitCombo(hwndCombo, cdDataRate);\r
+    sprintf(buf, "%u", (int)dcb.BaudRate);\r
+    if (SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) buf) == CB_ERR) {\r
+      SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
+      SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
+    }\r
+\r
+    hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
+    InitCombo(hwndCombo, cdDataBits);\r
+    SelectComboValue(hwndCombo, cdDataBits, dcb.ByteSize);\r
+\r
+    hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
+    InitCombo(hwndCombo, cdParity);\r
+    SelectComboValue(hwndCombo, cdParity, dcb.Parity);\r
+\r
+    hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
+    InitCombo(hwndCombo, cdStopBits);\r
+    SelectComboValue(hwndCombo, cdStopBits, dcb.StopBits);\r
+\r
+    hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
+    InitCombo(hwndCombo, cdFlow);\r
+    if (dcb.fOutX) {\r
+      SelectComboValue(hwndCombo, cdFlow, FLOW_XOFF);\r
+    } else if (dcb.fOutxCtsFlow) {\r
+      SelectComboValue(hwndCombo, cdFlow, FLOW_CTS);\r
+    } else if (dcb.fOutxDsrFlow) {\r
+      SelectComboValue(hwndCombo, cdFlow, FLOW_DSR);\r
+    } else {\r
+      SelectComboValue(hwndCombo, cdFlow, FLOW_NONE);\r
+    }\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+#ifdef NOTDEF\r
+      /* !! Currently we can't change comm ports in midstream */\r
+      hwndCombo = GetDlgItem(hDlg, OPT_Port);\r
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+      if (index == PORT_NONE) {\r
+       appData.icsCommPort = "";\r
+       if (hCommPort != NULL) {\r
+         CloseHandle(hCommPort);\r
+         hCommPort = NULL;\r
+       }\r
+       EndDialog(hDlg, TRUE);\r
+       return TRUE;\r
+      }\r
+      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
+      appData.icsCommPort = strdup(buf);\r
+      if (hCommPort != NULL) {\r
+       CloseHandle(hCommPort);\r
+       hCommPort = NULL;\r
+      }\r
+      /* now what?? can't really do this; have to fix up the ChildProc\r
+        and InputSource records for the comm port that we gave to the\r
+        back end. */\r
+#endif /*NOTDEF*/\r
+\r
+      hwndCombo = GetDlgItem(hDlg, OPT_DataRate);\r
+      SendMessage(hwndCombo, WM_GETTEXT, (WPARAM) MSG_SIZ, (LPARAM) buf);\r
+      if (sscanf(buf, "%u", &value) != 1) {\r
+       MessageBox(hDlg, "Invalid data rate",\r
+                  "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+       return TRUE;\r
+      }\r
+      dcb.BaudRate = value;\r
+\r
+      hwndCombo = GetDlgItem(hDlg, OPT_Bits);\r
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+      dcb.ByteSize = cdDataBits[index].value;\r
+\r
+      hwndCombo = GetDlgItem(hDlg, OPT_Parity);\r
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+      dcb.Parity = cdParity[index].value;\r
+\r
+      hwndCombo = GetDlgItem(hDlg, OPT_StopBits);\r
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+      dcb.StopBits = cdStopBits[index].value;\r
+\r
+      hwndCombo = GetDlgItem(hDlg, OPT_Flow);\r
+      index = SendMessage(hwndCombo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+      switch (cdFlow[index].value) {\r
+      case FLOW_NONE:\r
+       dcb.fOutX = FALSE;\r
+       dcb.fOutxCtsFlow = FALSE;\r
+       dcb.fOutxDsrFlow = FALSE;\r
+       break;\r
+      case FLOW_CTS:\r
+       dcb.fOutX = FALSE;\r
+       dcb.fOutxCtsFlow = TRUE;\r
+       dcb.fOutxDsrFlow = FALSE;\r
+       break;\r
+      case FLOW_DSR:\r
+       dcb.fOutX = FALSE;\r
+       dcb.fOutxCtsFlow = FALSE;\r
+       dcb.fOutxDsrFlow = TRUE;\r
+       break;\r
+      case FLOW_XOFF:\r
+       dcb.fOutX = TRUE;\r
+       dcb.fOutxCtsFlow = FALSE;\r
+       dcb.fOutxDsrFlow = FALSE;\r
+       break;\r
+      }\r
+      if (!SetCommState(hCommPort, (LPDCB) &dcb)) {\r
+       err = GetLastError();\r
+       switch(MessageBox(hDlg, \r
+                        "Failed to set comm port state;\r\ninvalid options?",\r
+                        "Option Error", MB_ABORTRETRYIGNORE|MB_ICONQUESTION)) {\r
+       case IDABORT:\r
+         DisplayFatalError("Failed to set comm port state", err, 1);\r
+         exit(1);  /*is it ok to do this from here?*/\r
+\r
+       case IDRETRY:\r
+         return TRUE;\r
+\r
+       case IDIGNORE:\r
+         EndDialog(hDlg, TRUE);\r
+         return TRUE;\r
+       }\r
+      }\r
+\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    default:\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+CommPortOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)CommPortOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_CommPort), hwnd, (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Load Options dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+VOID\r
+SetLoadOptionEnables(HWND hDlg)\r
+{\r
+  UINT state;\r
+\r
+  state = IsDlgButtonChecked(hDlg, OPT_Autostep);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_ASTimeDelay), state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_AStext1), state);\r
+}\r
+\r
+LRESULT CALLBACK\r
+LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  char buf[MSG_SIZ];\r
+  float fnumber;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    if (appData.timeDelay >= 0.0) {\r
+      CheckDlgButton(hDlg, OPT_Autostep, TRUE);\r
+      sprintf(buf, "%.2g", appData.timeDelay);\r
+      SetDlgItemText(hDlg, OPT_ASTimeDelay, buf);\r
+    } else {\r
+      CheckDlgButton(hDlg, OPT_Autostep, FALSE);\r
+    }\r
+    SetLoadOptionEnables(hDlg);\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+      if (IsDlgButtonChecked(hDlg, OPT_Autostep)) {\r
+       GetDlgItemText(hDlg, OPT_ASTimeDelay, buf, MSG_SIZ);\r
+       if (sscanf(buf, "%f", &fnumber) != 1) {\r
+         MessageBox(hDlg, "Invalid load game step rate",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+       }\r
+       appData.timeDelay = fnumber;\r
+      } else {\r
+       appData.timeDelay = (float) -1.0;\r
+      }\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    default:\r
+      SetLoadOptionEnables(hDlg);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+VOID \r
+LoadOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)LoadOptions, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_LoadOptions), hwnd, (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Save Options dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+VOID\r
+SetSaveOptionEnables(HWND hDlg)\r
+{\r
+  UINT state;\r
+\r
+  state = IsDlgButtonChecked(hDlg, OPT_Autosave);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_AVPrompt), state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_AVToFile), state);\r
+  if (state && !IsDlgButtonChecked(hDlg, OPT_AVPrompt) &&\r
+      !IsDlgButtonChecked(hDlg, OPT_AVToFile)) {\r
+    CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
+  }\r
+\r
+  state = state && IsDlgButtonChecked(hDlg, OPT_AVToFile);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_AVFilename), state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_AVBrowse), state);\r
+}\r
+\r
+LRESULT CALLBACK\r
+SaveOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  char buf[MSG_SIZ];\r
+  FILE *f;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    if (*appData.saveGameFile != NULLCHAR) {\r
+      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
+      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVToFile);\r
+      SetDlgItemText(hDlg, OPT_AVFilename, appData.saveGameFile);\r
+    } else if (appData.autoSaveGames) {\r
+      CheckDlgButton(hDlg, OPT_Autosave, (UINT) TRUE);\r
+      CheckRadioButton(hDlg, OPT_AVPrompt, OPT_AVToFile, OPT_AVPrompt);\r
+    } else {\r
+      CheckDlgButton(hDlg, OPT_Autosave, (UINT) FALSE);\r
+    }\r
+    if (appData.oldSaveStyle) {\r
+      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_Old);\r
+    } else {\r
+      CheckRadioButton(hDlg, OPT_PGN, OPT_Old, OPT_PGN);\r
+    }\r
+    CheckDlgButton( hDlg, OPT_OutOfBookInfo, appData.saveOutOfBookInfo );\r
+    SetSaveOptionEnables(hDlg);\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+      if (IsDlgButtonChecked(hDlg, OPT_Autosave)) {\r
+       appData.autoSaveGames = TRUE;\r
+       if (IsDlgButtonChecked(hDlg, OPT_AVPrompt)) {\r
+         appData.saveGameFile = "";\r
+       } else /*if (IsDlgButtonChecked(hDlg, OPT_AVToFile))*/ {\r
+         GetDlgItemText(hDlg, OPT_AVFilename, buf, MSG_SIZ);\r
+         if (*buf == NULLCHAR) {\r
+           MessageBox(hDlg, "Invalid save game file name",\r
+                      "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+           return FALSE;\r
+         }\r
+         if ((isalpha(buf[0]) && buf[1] == ':') ||\r
+           (buf[0] == '\\' && buf[1] == '\\')) {\r
+           appData.saveGameFile = strdup(buf);\r
+         } else {\r
+           char buf2[MSG_SIZ], buf3[MSG_SIZ];\r
+           char *dummy;\r
+           GetCurrentDirectory(MSG_SIZ, buf3);\r
+           SetCurrentDirectory(installDir);\r
+           if (GetFullPathName(buf, MSG_SIZ, buf2, &dummy)) {\r
+             appData.saveGameFile = strdup(buf2);\r
+           } else {\r
+             appData.saveGameFile = strdup(buf);\r
+           }\r
+           SetCurrentDirectory(buf3);\r
+         }\r
+       }\r
+      } else {\r
+       appData.autoSaveGames = FALSE;\r
+       appData.saveGameFile = "";\r
+      }\r
+      appData.oldSaveStyle = IsDlgButtonChecked(hDlg, OPT_Old);\r
+      appData.saveOutOfBookInfo = IsDlgButtonChecked( hDlg, OPT_OutOfBookInfo );\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case OPT_AVBrowse:\r
+      f = OpenFileDialog(hDlg, "a", NULL, \r
+                        appData.oldSaveStyle ? "gam" : "pgn", \r
+                        GAME_FILT, "Browse for Auto Save File", \r
+                        NULL, NULL, buf);\r
+      if (f != NULL) {\r
+       fclose(f);\r
+       SetDlgItemText(hDlg, OPT_AVFilename, buf);\r
+      }\r
+      break;\r
+\r
+    default:\r
+      SetSaveOptionEnables(hDlg);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+SaveOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc = MakeProcInstance((FARPROC)SaveOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_SaveOptions), hwnd, (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Time Control Options dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+VOID\r
+SetTimeControlEnables(HWND hDlg)\r
+{\r
+  UINT state;\r
+\r
+  state = IsDlgButtonChecked(hDlg, OPT_TCUseMoves)\r
+       + 2*IsDlgButtonChecked(hDlg, OPT_TCUseFixed);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state == 1);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state == 1);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state == 1);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state == 1);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCTime2), !state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCInc), !state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCitext1), !state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCitext2), !state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCitext3), !state);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCFixed), state == 2);\r
+  EnableWindow(GetDlgItem(hDlg, OPT_TCftext), state == 2);\r
+}\r
+\r
+\r
+LRESULT CALLBACK\r
+TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  char buf[MSG_SIZ], *tc;\r
+  int mps, increment, odds1, odds2, st;\r
+  BOOL ok, ok2;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+    /* Initialize the dialog items */\r
+    if (appData.clockMode && !appData.icsActive) {\r
+      if (searchTime) {\r
+       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
+                        OPT_TCUseFixed);\r
+       SetDlgItemInt(hDlg, OPT_TCFixed, searchTime, FALSE);\r
+      } else\r
+      if (appData.timeIncrement == -1) {\r
+       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
+                        OPT_TCUseMoves);\r
+       SetDlgItemText(hDlg, OPT_TCTime, appData.timeControl);\r
+       SetDlgItemInt(hDlg, OPT_TCMoves, appData.movesPerSession,\r
+                     FALSE);\r
+       SetDlgItemText(hDlg, OPT_TCTime2, "");\r
+       SetDlgItemText(hDlg, OPT_TCInc, "");\r
+      } else {\r
+       CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed,\r
+                        OPT_TCUseInc);\r
+       SetDlgItemText(hDlg, OPT_TCTime, "");\r
+       SetDlgItemText(hDlg, OPT_TCMoves, "");\r
+       SetDlgItemText(hDlg, OPT_TCTime2, appData.timeControl);\r
+       SetDlgItemInt(hDlg, OPT_TCInc, appData.timeIncrement, FALSE);\r
+      }\r
+      SetDlgItemInt(hDlg, OPT_TCOdds1, 1, FALSE);\r
+      SetDlgItemInt(hDlg, OPT_TCOdds2, 1, FALSE);\r
+      SetTimeControlEnables(hDlg);\r
+    }\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      mps = appData.movesPerSession;\r
+      increment = appData.timeIncrement;\r
+      tc = appData.timeControl;\r
+      st = 0;\r
+      /* Read changed options from the dialog box */\r
+      if (IsDlgButtonChecked(hDlg, OPT_TCUseFixed)) {\r
+       st = GetDlgItemInt(hDlg, OPT_TCFixed, &ok, FALSE);\r
+       if (!ok || st <= 0) {\r
+         MessageBox(hDlg, "Invalid max time per move",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+       }\r
+      } else\r
+      if (IsDlgButtonChecked(hDlg, OPT_TCUseMoves)) {\r
+       increment = -1;\r
+       mps = GetDlgItemInt(hDlg, OPT_TCMoves, &ok, FALSE);\r
+       if (!ok || mps <= 0) {\r
+         MessageBox(hDlg, "Invalid moves per time control",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+       }\r
+       GetDlgItemText(hDlg, OPT_TCTime, buf, MSG_SIZ);\r
+       if (!ParseTimeControl(buf, increment, mps)) {\r
+         MessageBox(hDlg, "Invalid minutes per time control",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+       }\r
+      tc = buf;\r
+      } else {\r
+       increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE);\r
+       if (!ok || increment < 0) {\r
+         MessageBox(hDlg, "Invalid increment",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+       }\r
+       GetDlgItemText(hDlg, OPT_TCTime2, buf, MSG_SIZ);\r
+       if (!ParseTimeControl(buf, increment, mps)) {\r
+         MessageBox(hDlg, "Invalid initial time",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+       }\r
+      tc = buf;\r
+      }\r
+      odds1 = GetDlgItemInt(hDlg, OPT_TCOdds1, &ok, FALSE);\r
+      odds2 = GetDlgItemInt(hDlg, OPT_TCOdds2, &ok2, FALSE);\r
+      if (!ok || !ok2 || odds1 <= 0 || odds2 <= 0) {\r
+         MessageBox(hDlg, "Invalid time-odds factor",\r
+                    "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+         return FALSE;\r
+      }\r
+      searchTime = st;\r
+      appData.timeControl = strdup(tc);\r
+      appData.movesPerSession = mps;\r
+      appData.timeIncrement = increment;\r
+      appData.firstTimeOdds  = first.timeOdds  = odds1;\r
+      appData.secondTimeOdds = second.timeOdds = odds2;\r
+      Reset(TRUE, TRUE);\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    default:\r
+      SetTimeControlEnables(hDlg);\r
+      break;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID\r
+TimeControlOptionsPopup(HWND hwnd)\r
+{\r
+  if (gameMode != BeginningOfGame) {\r
+    DisplayError("Changing time control during a game is not implemented", 0);\r
+  } else {\r
+    FARPROC lpProc = MakeProcInstance((FARPROC)TimeControl, hInst);\r
+    DialogBox(hInst, MAKEINTRESOURCE(DLG_TimeControl), hwnd, (DLGPROC) lpProc);\r
+    FreeProcInstance(lpProc);\r
+  }\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * Engine Options Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+#define CHECK_BOX(x,y) CheckDlgButton(hDlg, (x), (BOOL)(y))\r
+#define IS_CHECKED(x) (Boolean)IsDlgButtonChecked(hDlg, (x))\r
+\r
+#define INT_ABS( n )    ((n) >= 0 ? (n) : -(n))\r
+\r
+LRESULT CALLBACK EnginePlayOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+\r
+    /* Initialize the dialog items */\r
+    CHECK_BOX(IDC_EpPeriodicUpdates, appData.periodicUpdates);\r
+    CHECK_BOX(IDC_EpPonder, appData.ponderNextMove);\r
+    CHECK_BOX(IDC_EpShowThinking, appData.showThinking);\r
+    CHECK_BOX(IDC_EpHideThinkingHuman, appData.hideThinkingFromHuman);\r
+\r
+    CHECK_BOX(IDC_TestClaims, appData.testClaims);\r
+    CHECK_BOX(IDC_DetectMates, appData.checkMates);\r
+    CHECK_BOX(IDC_MaterialDraws, appData.materialDraws);\r
+    CHECK_BOX(IDC_TrivialDraws, appData.trivialDraws);\r
+\r
+    CHECK_BOX(IDC_ScoreAbs1, appData.firstScoreIsAbsolute);\r
+    CHECK_BOX(IDC_ScoreAbs2, appData.secondScoreIsAbsolute);\r
+\r
+    SetDlgItemInt( hDlg, IDC_EpDrawMoveCount, appData.adjudicateDrawMoves, TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_EpDrawMoveCount, EM_SETSEL, 0, -1 );\r
+\r
+    SetDlgItemInt( hDlg, IDC_EpAdjudicationThreshold, INT_ABS(appData.adjudicateLossThreshold), TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_EpAdjudicationThreshold, EM_SETSEL, 0, -1 );\r
+\r
+    SetDlgItemInt( hDlg, IDC_RuleMoves, appData.ruleMoves, TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_RuleMoves, EM_SETSEL, 0, -1 );\r
+\r
+    SetDlgItemInt( hDlg, IDC_DrawRepeats, INT_ABS(appData.drawRepeats), TRUE );\r
+    SendDlgItemMessage( hDlg, IDC_DrawRepeats, EM_SETSEL, 0, -1 );\r
+\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      /* Read changed options from the dialog box */\r
+      PeriodicUpdatesEvent(          IS_CHECKED(IDC_EpPeriodicUpdates));\r
+      PonderNextMoveEvent(           IS_CHECKED(IDC_EpPonder));\r
+      appData.hideThinkingFromHuman= IS_CHECKED(IDC_EpHideThinkingHuman); // [HGM] thinking: moved up\r
+      appData.showThinking   = IS_CHECKED(IDC_EpShowThinking);\r
+      ShowThinkingEvent(); // [HGM] thinking: tests all options that need thinking output\r
+      appData.testClaims    = IS_CHECKED(IDC_TestClaims);\r
+      appData.checkMates    = IS_CHECKED(IDC_DetectMates);\r
+      appData.materialDraws = IS_CHECKED(IDC_MaterialDraws);\r
+      appData.trivialDraws  = IS_CHECKED(IDC_TrivialDraws);\r
+\r
+      appData.adjudicateDrawMoves = GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, NULL, FALSE );\r
+      appData.adjudicateLossThreshold = - (int) GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, NULL, FALSE );\r
+      appData.ruleMoves = GetDlgItemInt(hDlg, IDC_RuleMoves, NULL, FALSE );\r
+      appData.drawRepeats = (int) GetDlgItemInt(hDlg, IDC_DrawRepeats, NULL, FALSE );\r
+\r
+      appData.firstScoreIsAbsolute  = IS_CHECKED(IDC_ScoreAbs1);\r
+      appData.secondScoreIsAbsolute = IS_CHECKED(IDC_ScoreAbs2);\r
+\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case IDC_EpDrawMoveCount:\r
+    case IDC_EpAdjudicationThreshold:\r
+    case IDC_DrawRepeats:\r
+    case IDC_RuleMoves:\r
+        if( HIWORD(wParam) == EN_CHANGE ) {\r
+            int n1_ok;\r
+            int n2_ok;\r
+            int n3_ok;\r
+            int n4_ok;\r
+\r
+            GetDlgItemInt(hDlg, IDC_EpDrawMoveCount, &n1_ok, FALSE );\r
+            GetDlgItemInt(hDlg, IDC_EpAdjudicationThreshold, &n2_ok, FALSE );\r
+            GetDlgItemInt(hDlg, IDC_RuleMoves, &n3_ok, FALSE );\r
+            GetDlgItemInt(hDlg, IDC_DrawRepeats, &n4_ok, FALSE );\r
+\r
+            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok && n3_ok && n4_ok ? TRUE : FALSE );\r
+        }\r
+        return TRUE;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID EnginePlayOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc;\r
+\r
+  lpProc = MakeProcInstance((FARPROC)EnginePlayOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_EnginePlayOptions), hwnd, (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
+ * UCI Options Dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+static BOOL BrowseForFolder( const char * title, char * path )\r
+{\r
+    BOOL result = FALSE;\r
+    BROWSEINFO bi;\r
+    LPITEMIDLIST pidl;\r
+\r
+    ZeroMemory( &bi, sizeof(bi) );\r
+\r
+    bi.lpszTitle = title == 0 ? "Choose Folder" : title;\r
+    bi.ulFlags = BIF_RETURNONLYFSDIRS;\r
+\r
+    pidl = SHBrowseForFolder( &bi );\r
+\r
+    if( pidl != 0 ) {\r
+        IMalloc * imalloc = 0;\r
+\r
+        if( SHGetPathFromIDList( pidl, path ) ) {\r
+            result = TRUE;\r
+        }\r
+\r
+        if( SUCCEEDED( SHGetMalloc ( &imalloc ) ) ) {\r
+            imalloc->lpVtbl->Free(imalloc,pidl);\r
+            imalloc->lpVtbl->Release(imalloc);\r
+        }\r
+    }\r
+\r
+    return result;\r
+}\r
+\r
+LRESULT CALLBACK UciOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+  char buf[MAX_PATH];\r
+  int oldCores;\r
+\r
+  switch (message) {\r
+  case WM_INITDIALOG: /* message: initialize dialog box */\r
+\r
+    /* Center the dialog over the application window */\r
+    CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
+\r
+    /* Initialize the dialog items */\r
+    SetDlgItemText( hDlg, IDC_PolyglotDir, appData.polyglotDir );\r
+    SetDlgItemInt( hDlg, IDC_HashSize, appData.defaultHashSize, TRUE );\r
+    SetDlgItemText( hDlg, IDC_PathToEGTB, appData.defaultPathEGTB );\r
+    SetDlgItemInt( hDlg, IDC_SizeOfEGTB, appData.defaultCacheSizeEGTB, TRUE );\r
+    CheckDlgButton( hDlg, IDC_UseBook, (BOOL) appData.usePolyglotBook );\r
+    SetDlgItemText( hDlg, IDC_BookFile, appData.polyglotBook );\r
+    // [HGM] smp: input field for nr of cores:\r
+    SetDlgItemInt( hDlg, IDC_Cores, appData.smpCores, TRUE );\r
+    // [HGM] book: tick boxes for own book use\r
+    CheckDlgButton( hDlg, IDC_OwnBook1, (BOOL) appData.firstHasOwnBookUCI );\r
+    CheckDlgButton( hDlg, IDC_OwnBook2, (BOOL) appData.secondHasOwnBookUCI );\r
+\r
+    SendDlgItemMessage( hDlg, IDC_PolyglotDir, EM_SETSEL, 0, -1 );\r
+\r
+    return TRUE;\r
+\r
+  case WM_COMMAND: /* message: received a command */\r
+    switch (LOWORD(wParam)) {\r
+    case IDOK:\r
+      GetDlgItemText( hDlg, IDC_PolyglotDir, buf, sizeof(buf) );\r
+      appData.polyglotDir = strdup(buf);\r
+      appData.defaultHashSize = GetDlgItemInt(hDlg, IDC_HashSize, NULL, FALSE );\r
+      appData.defaultCacheSizeEGTB = GetDlgItemInt(hDlg, IDC_SizeOfEGTB, NULL, FALSE );\r
+      GetDlgItemText( hDlg, IDC_PathToEGTB, buf, sizeof(buf) );\r
+      appData.defaultPathEGTB = strdup(buf);\r
+      GetDlgItemText( hDlg, IDC_BookFile, buf, sizeof(buf) );\r
+      appData.polyglotBook = strdup(buf);\r
+      appData.usePolyglotBook = (Boolean) IsDlgButtonChecked( hDlg, IDC_UseBook );\r
+      // [HGM] smp: get nr of cores:\r
+      oldCores = appData.smpCores;\r
+      appData.smpCores = GetDlgItemInt(hDlg, IDC_Cores, NULL, FALSE );\r
+      if(appData.smpCores != oldCores) NewSettingEvent(FALSE, "cores", appData.smpCores);\r
+      // [HGM] book: read tick boxes for own book use\r
+      appData.firstHasOwnBookUCI  = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook1 );\r
+      appData.secondHasOwnBookUCI = (Boolean) IsDlgButtonChecked( hDlg, IDC_OwnBook2 );\r
+\r
+      if(gameMode == BeginningOfGame) Reset(TRUE, TRUE);\r
+      EndDialog(hDlg, TRUE);\r
+      return TRUE;\r
+\r
+    case IDCANCEL:\r
+      EndDialog(hDlg, FALSE);\r
+      return TRUE;\r
+\r
+    case IDC_BrowseForBook:\r
+      {\r
+          char filter[] = { \r
+              'A','l','l',' ','F','i','l','e','s', 0,\r
+              '*','.','*', 0,\r
+              'B','I','N',' ','F','i','l','e','s', 0,\r
+              '*','.','b','i','n', 0,\r
+              0 };\r
+\r
+          OPENFILENAME ofn;\r
+\r
+          strcpy( buf, "" );\r
+\r
+          ZeroMemory( &ofn, sizeof(ofn) );\r
+\r
+          ofn.lStructSize = sizeof(ofn);\r
+          ofn.hwndOwner = hDlg;\r
+          ofn.hInstance = hInst;\r
+          ofn.lpstrFilter = filter;\r
+          ofn.lpstrFile = buf;\r
+          ofn.nMaxFile = sizeof(buf);\r
+          ofn.lpstrTitle = "Choose Book";\r
+          ofn.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_HIDEREADONLY;\r
+\r
+          if( GetOpenFileName( &ofn ) ) {\r
+              SetDlgItemText( hDlg, IDC_BookFile, buf );\r
+          }\r
+      }\r
+      return TRUE;\r
+\r
+    case IDC_BrowseForPolyglotDir:\r
+      if( BrowseForFolder( "Choose Polyglot Directory", buf ) ) {\r
+        SetDlgItemText( hDlg, IDC_PolyglotDir, buf );\r
+\r
+        strcat( buf, "\\polyglot.exe" );\r
+\r
+        if( GetFileAttributes(buf) == 0xFFFFFFFF ) {\r
+            MessageBox( hDlg, "Polyglot was not found in the specified folder!", "Warning", MB_OK | MB_ICONWARNING );\r
+        }\r
+      }\r
+      return TRUE;\r
+\r
+    case IDC_BrowseForEGTB:\r
+      if( BrowseForFolder( "Choose EGTB Directory:", buf ) ) {\r
+        SetDlgItemText( hDlg, IDC_PathToEGTB, buf );\r
+      }\r
+      return TRUE;\r
+\r
+    case IDC_HashSize:\r
+    case IDC_SizeOfEGTB:\r
+        if( HIWORD(wParam) == EN_CHANGE ) {\r
+            int n1_ok;\r
+            int n2_ok;\r
+\r
+            GetDlgItemInt(hDlg, IDC_HashSize, &n1_ok, FALSE );\r
+            GetDlgItemInt(hDlg, IDC_SizeOfEGTB, &n2_ok, FALSE );\r
+\r
+            EnableWindow( GetDlgItem(hDlg, IDOK), n1_ok && n2_ok ? TRUE : FALSE );\r
+        }\r
+        return TRUE;\r
+    }\r
+    break;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+VOID UciOptionsPopup(HWND hwnd)\r
+{\r
+  FARPROC lpProc;\r
+\r
+  lpProc = MakeProcInstance((FARPROC)UciOptionsDialog, hInst);\r
+  DialogBox(hInst, MAKEINTRESOURCE(DLG_OptionsUCI), hwnd, (DLGPROC) lpProc);\r
+  FreeProcInstance(lpProc);\r
+}\r
index 1665f4c..a3fda95 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -208,8 +208,6 @@ extern char *getenv();
 void EngineOutputProc P((Widget w, XEvent *event,
  String *prms, Cardinal *nprms));
 
-void EngineOutputPopDown();
-
 
 #ifdef __EMX__
 #ifndef HAVE_USLEEP
@@ -309,7 +307,6 @@ static void CreateAnimVars P((void));
 static void DragPieceMove P((int x, int y));
 static void DrawDragPiece P((void));
 char *ModeToWidgetName P((GameMode mode));
-void EngineOutputUpdate( FrontEndProgramStats * stats );
 void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -352,6 +349,10 @@ Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget,
   commentShell, promotionShell, whitePieceMenu, blackPieceMenu, dropMenu,
   menuBarWidget,  editShell, errorShell, analysisShell,
   ICSInputShell, fileNameShell, askQuestionShell;
+
+//XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
+//XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
+
 Font clockFontID, coordFontID, countFontID;
 XFontStruct *clockFontStruct, *coordFontStruct, *countFontStruct;
 XtAppContext appContext;
@@ -2270,9 +2271,9 @@ main(argc, argv)
     }
 
     /* [HGM,HR] make sure board size is acceptable */
-    if(appData.NrFiles > BOARD_SIZE ||
-       appData.NrRanks > BOARD_SIZE   )
-      DisplayFatalError(_("Recompile with BOARD_SIZE > 12, to support this size"), 0, 2);
+    if(appData.NrFiles > BOARD_FILES ||
+       appData.NrRanks > BOARD_RANKS   )
+        DisplayFatalError(_("Recompile with larger BOARD_RANKS or BOARD_FILES to support this size"), 0, 2);
 
 #if !HIGHDRAG
     /* This feature does not work; animation needs a rewrite */
@@ -2777,6 +2778,20 @@ ResetFrontEnd()
 }
 
 void
+GreyRevert(grey)
+     Boolean grey;
+{
+    Widget w;
+    if (!menuBarWidget) return;
+    w = XtNameToWidget(menuBarWidget, "menuStep.Revert");
+    if (w == NULL) {
+      DisplayError("menuStep.Revert", 0);
+    } else {
+      XtSetSensitive(w, !grey);
+    }
+}
+
+void
 SetMenuEnables(enab)
      Enables *enab;
 {
@@ -3811,7 +3826,7 @@ static int check_castle_draw(newb, oldb, rrow, rcol)
     return 0;
 }
 
-static int damage[BOARD_SIZE][BOARD_SIZE];
+static int damage[BOARD_RANKS][BOARD_FILES];
 
 /*
  * event handler for redrawing the board
@@ -6995,14 +7010,6 @@ DrawDragPiece ()
   damage[player.startBoardY][player.startBoardX] = TRUE;
 }
 
-void
-SetProgramStats( FrontEndProgramStats * stats )
-{
-  // [HR] TODO
-  // [HGM] done, but perhaps backend should call this directly?
-    EngineOutputUpdate( stats );
-}
-
 #include <sys/ioctl.h>
 int get_term_width()
 {
index 5806d53..9f3cdd7 100644 (file)
--- a/xboard.h
+++ b/xboard.h
@@ -107,12 +107,7 @@ typedef struct {
 #define FIRST_CHESS_PROGRAM    "fairymax"
 #define SECOND_CHESS_PROGRAM   "fairymax"
 
-/* Default to no flashing (the "usual" XBoard behavior) */
-#define FLASH_COUNT    0               /* Number of times to flash */
-#define FLASH_RATE     5               /* Flashes per second */
-
-/* Default delay per character (in msec) while sending login script */
-#define MS_LOGIN_DELAY  0
+#define XBOARD True
 
 typedef int (*FileProc) P((FILE *f, int n, char *title));
 void CatchDeleteWindow(Widget w, String procname);
index 2096f2e..7162631 100644 (file)
@@ -70,7 +70,7 @@ extern char *getenv();
 #include "frontend.h"
 #include "backend.h"
 #include "xboard.h"
-// Add xengineo.h later
+#include "engineoutput.h"
 #include "gettext.h"
 
 #ifdef ENABLE_NLS
@@ -106,74 +106,30 @@ extern int squareSize;
 extern Pixmap xMarkPixmap, wIconPixmap, bIconPixmap;
 extern char *layoutName;
 
-// temporary kludge to avoid compile errors untill all Windows code has been replaced
-#define HICON int *
-#define HWND  int *
-
-// [HGM] define numbers to indicate icons, for referring to them in platform-independent way
-#define nColorBlack   1
-#define nColorWhite   2
-#define nColorUnknown 3
-#define nClear        4
-#define nPondering    5
-#define nThinking     6
-#define nAnalyzing    7
-
 Pixmap icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle
-
-// [HGM] same for output fields (note that there are two of each type, one per color)
-#define nColorIcon 1
-#define nStateIcon 2
-#define nLabel     3
-#define nStateData 4
-#define nLabelNPS  5
-#define nMemo      6
-
 Widget outputField[2][7]; // [HGM] front-end array to translate output field to window handle
 
 void EngineOutputPopDown();
 void engineOutputPopUp();
 int  EngineOutputIsUp();
-static void SetEngineColorIcon( int which );
-
-#define SHOW_PONDERING
+void SetEngineColorIcon( int which );
 
 /* Imports from backend.c */
 char * SavePart(char *str);
 extern int opponentKibitzes;
 
-/* Imports from winboard.c */
-//extern HWND engineOutputDialog;
-extern Arg layoutArgs[2], formArgs[2];
+/* Imports from xboard.c */
+extern Arg layoutArgs[2], formArgs[2], messageArgs[4];
 
 //extern WindowPlacement wpEngineOutput;
 
 Position engineOutputX = -1, engineOutputY = -1;
 Dimension engineOutputW, engineOutputH;
 Widget engineOutputShell;
-int engineOutputDialogUp;
+static int engineOutputDialogUp;
 
 /* Module variables */
-#define H_MARGIN            2
-#define V_MARGIN            2
-#define LABEL_V_DISTANCE    1   /* Distance between label and memo */
-#define SPLITTER_SIZE       4   /* Distance between first memo and second label */
-
-#define ICON_SIZE           14
-
-#define STATE_UNKNOWN   -1
-#define STATE_THINKING   0
-#define STATE_IDLE       1
-#define STATE_PONDERING  2
-#define STATE_ANALYZING  3
-
-static int  windowMode = 1;
-
-static int  needInit = TRUE;
-
-static int  lastDepth[2] = { -1, -1 };
-static int  lastForwardMostMove[2] = { -1, -1 };
-static int  engineState[2] = { -1, -1 };
+int  windowMode = 1;
 
 typedef struct {
     char * name;
@@ -188,9 +144,7 @@ typedef struct {
     int an_move_count;
 } EngineOutputData;
 
-static void VerifyDisplayMode();
-static void UpdateControls( EngineOutputData * ed );
-static void SetEngineState( int which, int state, char * state_data );
+//static void UpdateControls( EngineOutputData * ed );
 
 void ReadIcon(char *pixData[], int iconNr)
 {
@@ -226,18 +180,18 @@ void DoSetWindowText(int which, int field, char *s_label)
        XtSetValues(outputField[which][field], &arg, 1);
 }
 
-static void InsertIntoMemo( int which, char * text )
+void InsertIntoMemo( int which, char * text, int where )
 {
        Arg arg; XawTextBlock t; Widget edit;
 
        t.ptr = text; t.firstPos = 0; t.length = strlen(text); t.format = XawFmt8Bit;
        edit = XtNameToWidget(engineOutputShell, which ? "*form2.text" : "*form.text");
-       XawTextReplace(edit, 0, 0, &t);
+       XawTextReplace(edit, where, where, &t);
 //     XtSetArg(arg, XtNstring, (XtArgVal) text);
 //     XtSetValues(outputField[which][nMemo], &arg, 1);
 }
 
-static void SetIcon( int which, int field, int nIcon )
+void SetIcon( int which, int field, int nIcon )
 {
     Arg arg;
 
@@ -450,14 +404,14 @@ Widget EngineOutputCreate(name, text)
     return shell;
 }
 
-void ResizeWindowControls(shell, mode)
-       Widget shell;
+void ResizeWindowControls(mode)
        int mode;
 {
     Widget form1, form2;
     Arg args[16];
     int j;
     Dimension ew_height, tmp;
+    Widget shell = engineOutputShell;
 
     form1 = XtNameToWidget(shell, "*form");
     form2 = XtNameToWidget(shell, "*form2");
@@ -493,6 +447,7 @@ EngineOutputPopUp()
     Arg args[16];
     int j;
     Widget edit;
+    static int  needInit = TRUE;
     static char *title = _("Engine output"), *text = _("This feature is experimental");
 
     if (engineOutputShell == NULL) {
@@ -555,382 +510,14 @@ void EngineOutputPopDown()
     ShowThinkingEvent(); // [HGM] thinking: might need to shut off thinking output
 }
 
-//------------------------ pure back-end routines -------------------------------
-
-
-// back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments
-static void SetEngineState( int which, int state, char * state_data )
-{
-    int x_which = 1 - which;
-
-    if( engineState[ which ] != state ) {
-        engineState[ which ] = state;
-
-        switch( state ) {
-        case STATE_THINKING:
-            SetIcon( which, nStateIcon, nThinking );
-            if( engineState[ x_which ] == STATE_THINKING ) {
-                SetEngineState( x_which, STATE_IDLE, "" );
-            }
-            break;
-        case STATE_PONDERING:
-            SetIcon( which, nStateIcon, nPondering );
-            break;
-        case STATE_ANALYZING:
-            SetIcon( which, nStateIcon, nAnalyzing );
-            break;
-        default:
-            SetIcon( which, nStateIcon, nClear );
-            break;
-        }
-    }
-
-    if( state_data != 0 ) {
-        DoSetWindowText( which, nStateData, state_data );
-    }
-}
-
-// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles.
-void EngineOutputUpdate( FrontEndProgramStats * stats )
-{
-    EngineOutputData ed;
-    int clearMemo = FALSE;
-    int which;
-    int depth;
-
-    if( stats == 0 ) {
-        SetEngineState( 0, STATE_IDLE, "" );
-        SetEngineState( 1, STATE_IDLE, "" );
-        return;
-    }
-
-    if(gameMode == IcsObserving && !appData.icsEngineAnalyze)
-       return; // [HGM] kibitz: shut up engine if we are observing an ICS game
-
-    which = stats->which;
-    depth = stats->depth;
-
-    if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) {
-        return;
-    }
-
-    if( engineOutputShell == NULL ) {
-        return;
-    }
-
-    VerifyDisplayMode();
-
-    ed.which = which;
-    ed.depth = depth;
-    ed.nodes = stats->nodes;
-    ed.score = stats->score;
-    ed.time = stats->time;
-    ed.pv = stats->pv;
-    ed.hint = stats->hint;
-    ed.an_move_index = stats->an_move_index;
-    ed.an_move_count = stats->an_move_count;
-
-    /* Get target control. [HGM] this is moved to front end, which get them from a table */
-    if( which == 0 ) {
-        ed.name = first.tidy;
-    }
-    else {
-        ed.name = second.tidy;
-    }
-
-    /* Clear memo if needed */
-    if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1) ) {
-        clearMemo = TRUE;
-    }
-
-    if( lastForwardMostMove[which] != forwardMostMove ) {
-        clearMemo = TRUE;
-    }
-
-    if( clearMemo ) DoClearMemo(which);
-
-    /* Update */
-    lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge
-    lastForwardMostMove[which] = forwardMostMove;
-
-    if( ed.pv != 0 && ed.pv[0] == ' ' ) {
-        if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */
-            ed.pv = "";
-        }
-    }
-
-    UpdateControls( &ed );
-}
-
-#define ENGINE_COLOR_WHITE      'w'
-#define ENGINE_COLOR_BLACK      'b'
-#define ENGINE_COLOR_UNKNOWN    ' '
-
-// pure back end
-char GetEngineColor( int which )
-{
-    char result = ENGINE_COLOR_UNKNOWN;
-
-    if( which == 0 || which == 1 ) {
-        ChessProgramState * cps;
-
-        switch (gameMode) {
-        case MachinePlaysBlack:
-        case IcsPlayingBlack:
-            result = ENGINE_COLOR_BLACK;
-            break;
-        case MachinePlaysWhite:
-        case IcsPlayingWhite:
-            result = ENGINE_COLOR_WHITE;
-            break;
-        case AnalyzeMode:
-        case AnalyzeFile:
-            result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;
-            break;
-        case TwoMachinesPlay:
-            cps = (which == 0) ? &first : &second;
-            result = cps->twoMachinesColor[0];
-            result = result == 'w' ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;
-            break;
-        }
-    }
-
-    return result;
-}
-
-// pure back end
-char GetActiveEngineColor()
-{
-    char result = ENGINE_COLOR_UNKNOWN;
-
-    if( gameMode == TwoMachinesPlay ) {
-        result = WhiteOnMove(forwardMostMove) ? ENGINE_COLOR_WHITE : ENGINE_COLOR_BLACK;
-    }
-
-    return result;
-}
-
-// pure back end
-static int IsEnginePondering( int which )
-{
-    int result = FALSE;
-
-    switch (gameMode) {
-    case MachinePlaysBlack:
-    case IcsPlayingBlack:
-        if( WhiteOnMove(forwardMostMove) ) result = TRUE;
-        break;
-    case MachinePlaysWhite:
-    case IcsPlayingWhite:
-        if( ! WhiteOnMove(forwardMostMove) ) result = TRUE;
-        break;
-    case TwoMachinesPlay:
-        if( GetActiveEngineColor() != ENGINE_COLOR_UNKNOWN ) {
-            if( GetEngineColor( which ) != GetActiveEngineColor() ) result = TRUE;
-        }
-        break;
-    }
-
-    return result;
-}
-
-// back end
-static void SetDisplayMode( int mode )
-{
-    if( windowMode != mode ) {
-        windowMode = mode;
-
-        ResizeWindowControls( engineOutputShell, mode );
-    }
-}
-
-// pure back end
-void VerifyDisplayMode()
-{
-    int mode;
-
-    /* Get proper mode for current game */
-    switch( gameMode ) {
-    case IcsObserving:    // [HGM] ICS analyze
-       if(!appData.icsEngineAnalyze) return;
-    case AnalyzeMode:
-    case AnalyzeFile:
-    case MachinePlaysWhite:
-    case MachinePlaysBlack:
-        mode = 0;
-        break;
-    case IcsPlayingWhite:
-    case IcsPlayingBlack:
-        mode = appData.zippyPlay && opponentKibitzes; // [HGM] kibitz
-        break;
-    case TwoMachinesPlay:
-        mode = 1;
-        break;
-    default:
-        /* Do not change */
-        return;
-    }
-
-    SetDisplayMode( mode );
-}
-
-// back end. Determine what icon to se in the color-icon field, and print it
-static void SetEngineColorIcon( int which )
-{
-    char color = GetEngineColor(which);
-    int nicon = 0;
-
-    if( color == ENGINE_COLOR_BLACK )
-        nicon = nColorBlack;
-    else if( color == ENGINE_COLOR_WHITE )
-        nicon = nColorWhite;
-    else
-        nicon = nColorUnknown;
-
-    SetIcon( which, nColorIcon, nicon );
-}
-
-#define MAX_NAME_LENGTH 32
-
-// pure back end, now SetWindowText is called via wrapper DoSetWindowText
-static void UpdateControls( EngineOutputData * ed )
+int EngineOutputIsUp()
 {
-    int isPondering = FALSE;
-
-    char s_label[MAX_NAME_LENGTH + 32];
-    
-    char * name = ed->name;
-
-    /* Label */
-    if( name == 0 || *name == '\0' ) {
-        name = "?";
-    }
-
-    strncpy( s_label, name, MAX_NAME_LENGTH );
-    s_label[ MAX_NAME_LENGTH-1 ] = '\0';
-
-#ifdef SHOW_PONDERING
-    if( IsEnginePondering( ed->which ) ) {
-        char buf[8];
-
-        buf[0] = '\0';
-
-        if( ed->hint != 0 && *ed->hint != '\0' ) {
-            strncpy( buf, ed->hint, sizeof(buf) );
-            buf[sizeof(buf)-1] = '\0';
-        }
-        else if( ed->pv != 0 && *ed->pv != '\0' ) {
-            char * sep = strchr( ed->pv, ' ' );
-            int buflen = sizeof(buf);
-
-            if( sep != NULL ) {
-                buflen = sep - ed->pv + 1;
-                if( buflen > sizeof(buf) ) buflen = sizeof(buf);
-            }
-
-            strncpy( buf, ed->pv, buflen );
-            buf[ buflen-1 ] = '\0';
-        }
-
-        SetEngineState( ed->which, STATE_PONDERING, buf );
-    }
-    else if( gameMode == TwoMachinesPlay ) {
-        SetEngineState( ed->which, STATE_THINKING, "" );
-    }
-    else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile 
-         || gameMode == IcsObserving && appData.icsEngineAnalyze) { // [HGM] ICS-analyze
-        char buf[64];
-        int time_secs = ed->time / 100;
-        int time_mins = time_secs / 60;
-
-        buf[0] = '\0';
-
-        if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) {
-            char mov[16];
-
-            strncpy( mov, ed->hint, sizeof(mov) );
-            mov[ sizeof(mov)-1 ] = '\0';
-
-           sprintf( buf, "[%d] %d/%d: %s [%02d:%02d:%02d]", ed->depth, ed->an_move_index,
-                       ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 );
-        }
-
-        SetEngineState( ed->which, STATE_ANALYZING, buf );
-    }
-    else {
-        SetEngineState( ed->which, STATE_IDLE, "" );
-    }
-#endif
-
-    DoSetWindowText( ed->which, nLabel, s_label );
-
-    s_label[0] = '\0';
-
-    if( ed->time > 0 && ed->nodes > 0 ) {
-        unsigned long nps_100 = ed->nodes / ed->time;
-
-        if( nps_100 < 100000 ) {
-            sprintf( s_label, _("NPS: %lu"), nps_100 * 100 );
-        }
-        else {
-            sprintf( s_label, _("NPS: %.1fk"), nps_100 / 10.0 );
-        }
-    }
-
-    DoSetWindowText( ed->which, nLabelNPS, s_label );
-
-    /* Memo */
-    if( ed->pv != 0 && *ed->pv != '\0' ) {
-        char s_nodes[24];
-        char s_score[16];
-        char s_time[24];
-        char buf[256];
-        int buflen;
-        int time_secs = ed->time / 100;
-        int time_cent = ed->time % 100;
-
-        /* Nodes */
-        if( ed->nodes < 1000000 ) {
-            sprintf( s_nodes, u64Display, ed->nodes );
-        }
-        else {
-            sprintf( s_nodes, "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 );
-        }
-
-        /* Score */
-        if( ed->score > 0 ) {
-            sprintf( s_score, "+%.2f", ed->score / 100.0 );
-        } else
-            sprintf( s_score, "%.2f", ed->score / 100.0 );
-
-        /* Time */
-        sprintf( s_time, "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent );
-
-        /* Put all together... */
-       if(ed->nodes == 0 && ed->score == 0 && ed->time == 0) sprintf( buf, "%3d\t", ed->depth ); else 
-        sprintf( buf, "%3d  %s  %s\t%s\t", ed->depth, s_score, s_nodes, s_time );
-
-        /* Add PV */
-        buflen = strlen(buf);
-
-        strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen );
-
-        buf[ sizeof(buf) - 3 ] = '\0';
-
-        strcat( buf + buflen, "\n" );
-
-        /* Update memo */
-        InsertIntoMemo( ed->which, buf );
-    }
-
-    /* Colors */
-    SetEngineColorIcon( ed->which );
+    return engineOutputDialogUp;
 }
 
-// back end
-int EngineOutputIsUp()
+int EngineOutputDialogExists()
 {
-    return engineOutputDialogUp;
+    return engineOutputShell != NULL;
 }
 
 void
@@ -945,26 +532,4 @@ EngineOutputProc(w, event, prms, nprms)
   } else {
     EngineOutputPopUp();
   }
-//  ToNrEvent(currentMove);
-}
-
-// [HGM] kibitz: write kibitz line; split window for it if necessary
-void OutputKibitz(int window, char *text)
-{
-       if(!EngineOutputIsUp()) return;
-       if(!opponentKibitzes) { // on first kibitz of game, clear memos
-           DoClearMemo(1);
-           if(gameMode == IcsObserving) DoClearMemo(0);
-       }
-       opponentKibitzes = TRUE; // this causes split window DisplayMode in ICS modes.
-       VerifyDisplayMode();
-       if(gameMode == IcsObserving) {
-           DoSetWindowText(0, nLabel, gameInfo.white);
-           SetIcon( 0, nColorIcon,  nColorWhite);
-           SetIcon( 0, nStateIcon,  nClear);
-       }
-       DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name
-       SetIcon( 1, nColorIcon,  gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);
-       SetIcon( 1, nStateIcon,  nClear);
-       InsertIntoMemo(window-1, text);
 }
index 1a29626..2b861eb 100644 (file)
@@ -63,6 +63,8 @@ extern GtkWidget               *GUI_History;
 extern GtkListStore            *LIST_MoveHistory;
 
 String dots=" ... ";
+Position gameHistoryX, gameHistoryY;
+Dimension gameHistoryW;
 
 void
 HistoryPopDown(object, user_data)
@@ -173,6 +175,137 @@ void HistoryCreate()
              <Key>Right: ForwardProc() \n";
 
     return;
+    /*-------- create the widgets ---------------*/
+//    j = 0;
+//    XtSetArg(args[j], XtNresizable, True);  j++;
+//    XtSetArg(args[j], XtNallowShellResize, True);  j++;
+//#if TOPLEVEL
+//    hist->sh =
+//      XtCreatePopupShell(_("Move list"), topLevelShellWidgetClass,
+//                      shellWidget, args, j);
+//#else
+//    hist->sh =
+//      XtCreatePopupShell(_("Move list"), transientShellWidgetClass,
+//                      shellWidget, args, j);
+//#endif
+//    j = 0;
+//    XtSetArg(args[j], XtNborderWidth, 0); j++;
+//    XtSetArg(args[j], XtNdefaultDistance, 0);  j++;
+//      layout =
+//      XtCreateManagedWidget(layoutName, formWidgetClass, hist->sh,
+//                         args, j);
+//
+//    j = 0;
+//    XtSetArg(args[j], XtNborderWidth, 0); j++;
+//    XtSetArg(args[j], XtNresizable, True);  j++;
+//
+//    form =
+//      XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
+//     j=0;
+//
+//    j = 0;
+//
+//    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
+//    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
+//    XtSetArg(args[j], XtNright, XtChainRight);  j++;
+//
+//    XtSetArg(args[j], XtNborderWidth, 1); j++;
+//    XtSetArg(args[j], XtNresizable, False);  j++;
+//    XtSetArg(args[j], XtNallowVert, True); j++;
+//    XtSetArg(args[j], XtNallowHoriz, True);  j++;
+//    XtSetArg(args[j], XtNforceBars, False); j++;
+//    XtSetArg(args[j], XtNheight, 280); j++;
+//    hist->viewport =
+//      XtCreateManagedWidget("viewport", viewportWidgetClass,
+//                         form, args, j);
+//    j=0;
+//    XtSetArg(args[j], XtNborderWidth, 0); j++;
+//    XtSetArg(args[j], XtNorientation,XtorientHorizontal);j++;
+//    hist->vbox =
+//      XtCreateManagedWidget("vbox", formWidgetClass, hist->viewport, args, j);
+//
+//    j=0;
+//    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
+//    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
+//
+//    XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
+//    XtSetArg(args[j], XtNforceColumns, True);  j++;
+//    XtSetArg(args[j], XtNverticalList, True);  j++;
+//    XtSetArg(args[j], XtNborderWidth, 0); j++;
+//    XtSetArg(args[j], XtNresizable,True);j++;
+//    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
+//    hist->mvn = XtCreateManagedWidget("movesn", listWidgetClass,
+//                                   hist->vbox, args, j);
+//    XtAddCallback(hist->mvn, XtNcallback, HistoryMoveProc, (XtPointer) hist);
+//
+//    j=0;
+//    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
+//    XtSetArg(args[j], XtNright, XtRubber);  j++;
+//
+//    XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
+//    XtSetArg(args[j], XtNforceColumns, True);  j++;
+//    XtSetArg(args[j], XtNverticalList, True);  j++;
+//    XtSetArg(args[j], XtNborderWidth, 0); j++;
+//    XtSetArg(args[j], XtNresizable,True);j++;
+//    XtSetArg(args[j], XtNfromHoriz, hist->mvn);  j++;
+//    hist->mvw = XtCreateManagedWidget("movesw", listWidgetClass,
+//                                   hist->vbox, args, j);
+//    XtAddCallback(hist->mvw, XtNcallback, HistoryMoveProc, (XtPointer) hist);
+//
+//    j=0;
+//    XtSetArg(args[j], XtNtop, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
+//    XtSetArg(args[j], XtNleft, XtRubber);  j++;
+//    XtSetArg(args[j], XtNright,  XtRubber);  j++;
+//
+//    XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
+//    XtSetArg(args[j], XtNforceColumns, True);  j++;
+//    XtSetArg(args[j], XtNverticalList, True);  j++;
+//    XtSetArg(args[j], XtNborderWidth, 0); j++;
+//    XtSetArg(args[j], XtNresizable,True);j++;
+//    XtSetArg(args[j], XtNfromHoriz, hist->mvw);  j++;
+//    hist->mvb = XtCreateManagedWidget("movesb", listWidgetClass,
+//                                   hist->vbox, args, j);
+//    XtAddCallback(hist->mvb, XtNcallback, HistoryMoveProc, (XtPointer) hist);
+//
+//    j=0;
+//    XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
+//    XtSetArg(args[j], XtNtop, XtChainBottom);  j++;
+//    XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
+//    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
+//    XtSetArg(args[j], XtNfromVert, hist->viewport);  j++;
+//    b_close= XtCreateManagedWidget(_("Close"), commandWidgetClass,
+//                                form, args, j);
+//    XtAddCallback(b_close, XtNcallback, HistoryPopDown, (XtPointer) 0);
+//
+//    XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr));
+//
+//    XtRealizeWidget(hist->sh);
+//    CatchDeleteWindow(hist->sh, "HistoryPopDown");
+//
+//    for(i=1;i<hist->aNr;i++){
+//      strcpy(hist->white[i],dots);
+//      strcpy(hist->black[i],"");
+//     }
+//
+//  // [HGM] restore old position
+//  j = 0;
+//  XtSetArg(args[j], XtNx, &gameHistoryX);  j++;
+//  XtSetArg(args[j], XtNy, &gameHistoryY);  j++;
+//  XtSetArg(args[j], XtNwidth, &gameHistoryW);  j++;
+//  XtGetValues(shellWidget, args, j);
+//  j = 0;
+//  XtSetArg(args[j], XtNx, gameHistoryX + gameHistoryW);  j++;
+//  XtSetArg(args[j], XtNy, gameHistoryY);  j++;
+//  XtSetValues(hist->sh, args, j);
+//    XtRealizeWidget(hist->sh);
+//
+//    return hist->sh;
 }
 
 void
index 6c3d8aa..c154030 100644 (file)
@@ -45,6 +45,7 @@ extern char *getenv();
 #if HAVE_UNISTD_H
 # include <unistd.h>
 #endif
+#include <stdint.h>
 
 #include <X11/Intrinsic.h>
 #include <X11/StringDefs.h>