From: Arun Persaud Date: Sat, 9 Jan 2010 22:17:21 +0000 (-0800) Subject: Merge commit 'master-20091122' into gtk X-Git-Tag: gtk-20100118~13 X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=2dee3c0dc5b669d4e5f3464866b056a5bbca252e;hp=f492ab86d8d68a4391c6214c050fcc6c77bd11c0;p=xboard.git Merge commit 'master-20091122' into gtk Conflicts: backend.c configure.ac xboard.c xengineoutput.c xhistory.c --- diff --git a/Makefile.am b/Makefile.am index bb1a656..d678c54 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/backend.c b/backend.c old mode 100755 new mode 100644 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= 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_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_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>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 || 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 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] 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] 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; iBOARD_LEFT && board[toY][toX-1] == BlackPawn && gameInfo.variant != VariantBerolina || toX < fromX) - *ep = toX | berolina; + board[EP_STATUS] = toX | berolina; if(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 fromX) - *ep = toX; + gameInfo.variant != VariantBerolina || toX > fromX) + board[EP_STATUS] = toX; } } for(i=0; i= 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 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= 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 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=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; iwhiteKingFile; 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 && iblackKingFile; 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= 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= 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= 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= 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>1); + else strcpy(buf, "("); + for(i=currentMove; i>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= 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, diff --git a/common.h b/common.h index 72e66ba..03f7bb0 100644 --- 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; diff --git a/configure.ac b/configure.ac index 3fe3aa0..5d8e00e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 0000000..9c493ad --- /dev/null +++ b/engineoutput.c @@ -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 +#include + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +# if HAVE_STRING_H +# include +# else /* not HAVE_STRING_H */ +# include +# 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 index 0000000..febbd34 --- /dev/null +++ b/engineoutput.h @@ -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 index 0000000..9aa1fe7 --- /dev/null +++ b/evalgraph.c @@ -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 + +#if STDC_HEADERS +# include +# include +#else /* not STDC_HEADERS */ +# if HAVE_STRING_H +# include +# else /* not HAVE_STRING_H */ +# include +# 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 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 index 0000000..e305abd --- /dev/null +++ b/evalgraph.h @@ -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 ); + diff --git a/frontend.h b/frontend.h index 622eeec..9b43b46 100644 --- a/frontend.h +++ b/frontend.h @@ -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 diff --git a/gamelist.c b/gamelist.c old mode 100755 new mode 100644 diff --git a/gettext.h b/gettext.h old mode 100755 new mode 100644 diff --git a/moves.c b/moves.c index 2a017c3..12f9b63 100644 --- 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= 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= 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= 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= 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= (int)BlackPawn && WhiteOnMove(currentMove); cl.count = 0; cl.rf = fromY; cl.ff = fromX; cl.rt = cl.ft = -1; - GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), EP_NONE, - castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl); + GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), ReadCallback, (VOIDSTAR) &cl); if(cl.count == 0) SayString("None", FALSE); boards[currentMove][fromY][fromX] = victim; // repair @@ -459,16 +457,14 @@ PossibleAttacked() victim = boards[currentMove][fromY][fromX]; // put dummy piece on target square, to activate Pawn captures boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen; cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1; - GenLegal(boards[currentMove], PosFlags(currentMove+1), EP_NONE, - castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl); + GenLegal(boards[currentMove], PosFlags(currentMove+1), ReadCallback, (VOIDSTAR) &cl); if(cl.count == 0) SayString("None", FALSE); SayString("You are defended by", FALSE); boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? BlackQueen : WhiteQueen; cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1; - GenLegal(boards[currentMove], PosFlags(currentMove), EP_NONE, - castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl); + GenLegal(boards[currentMove], PosFlags(currentMove), ReadCallback, (VOIDSTAR) &cl); if(cl.count == 0) SayString("None", FALSE); boards[currentMove][fromY][fromX] = victim; // put back original occupant @@ -1184,11 +1180,11 @@ NiceTime(int x) } #define JAWS_ARGS \ - { "beepOffBoard", ArgInt, (LPVOID) beeps, TRUE },\ - { "beepEmpty", ArgInt, (LPVOID) (beeps+1), TRUE },\ - { "beepWhite", ArgInt, (LPVOID) (beeps+2), TRUE },\ - { "beepBlack", ArgInt, (LPVOID) (beeps+3), TRUE },\ - { "beepHoldings", ArgInt, (LPVOID) (beeps+4), TRUE },\ + { "beepOffBoard", ArgInt, (LPVOID) beeps, TRUE, (ArgIniType) 1 },\ + { "beepEmpty", ArgInt, (LPVOID) (beeps+1), TRUE, (ArgIniType) 0 },\ + { "beepWhite", ArgInt, (LPVOID) (beeps+2), TRUE, (ArgIniType) 0 },\ + { "beepBlack", ArgInt, (LPVOID) (beeps+3), TRUE, (ArgIniType) 0 },\ + { "beepHoldings", ArgInt, (LPVOID) (beeps+4), TRUE, (ArgIniType) 0 },\ #define JAWS_ALT_INTERCEPT \ if(suppressOneKey) {\ diff --git a/winboard/makefile.gcc b/winboard/makefile.gcc index e8a7e99..4c73c8d 100644 --- a/winboard/makefile.gcc +++ b/winboard/makefile.gcc @@ -5,9 +5,9 @@ PROJ=winboard OBJS=backend.o book.o gamelist.o lists.o moves.o pgntags.o uci.o zippy.o\ - parser.o wbres.o wclipbrd.o wedittags.o wengineo.o wevalgraph.o\ + parser.o wbres.o wclipbrd.o wedittags.o wengineoutput.o wevalgraph.o\ wgamelist.o whistory.o winboard.o wlayout.o woptions.o wsnap.o\ - wsockerr.o help.o wsettings.o wchat.o + wsockerr.o help.o wsettings.o wchat.o engineoutput.o evalgraph.o # make compiling less spammy @@ -86,8 +86,8 @@ $(PROJ).exe: $(OBJS) $(PROJ).hlp winboard.o: winboard.c config.h winboard.h ../common.h ../frontend.h ../backend.h \ - ../moves.h wgamelist.h defaults.h resource.h wclipbrd.h \ - wedittags.h wsockerr.h woptions.h wsnap.h ../lists.h help.h + ../moves.h defaults.h resource.h wclipbrd.h \ + wsockerr.h woptions.h wsnap.h ../lists.h help.h $(call compile, $<) backend.o: ../backend.c config.h ../common.h ../frontend.h ../backend.h \ @@ -114,30 +114,38 @@ wclipbrd.o: wclipbrd.c config.h ../common.h ../frontend.h ../backend.h \ $(call compile, $<) wedittags.o: wedittags.c config.h ../common.h winboard.h resource.h ../frontend.h \ - ../backend.h ../lists.h wedittags.h + ../backend.h ../lists.h $(call compile, $<) wgamelist.o: wgamelist.c config.h. ../common.h winboard.h resource.h ../frontend.h \ - ../backend.h wgamelist.h ../lists.h + ../backend.h ../lists.h $(call compile, $<) woptions.o: woptions.c config.h ../common.h ../frontend.h ../backend.h ../lists.h \ defaults.h winboard.h resource.h $(call compile, $<) -wengineo.o: wengineo.c config.h ../common.h ../frontend.h ../backend.h \ - ../lists.h winboard.h resource.h wsnap.h +wengineoutput.o: wengineoutput.c ../engineoutput.h config.h ../common.h \ + ../frontend.h ../backend.h ../lists.h winboard.h resource.h wsnap.h + $(call compile, $<) + +engineoutput.o: ../engineoutput.c ../engineoutput.h config.h ../common.h \ + ../frontend.h ../backend.h ../lists.h $(call compile, $<) whistory.o: whistory.c config.h ../common.h ../frontend.h ../backend.h \ ../lists.h winboard.h resource.h wsnap.h $(call compile, $<) -wevalgraph.o: wevalgraph.c config.h ../common.h ../frontend.h ../backend.h \ - ../lists.h winboard.h resource.h wsnap.h +wevalgraph.o: wevalgraph.c ../evalgraph.h config.h ../common.h ../frontend.h \ + ../backend.h ../lists.h winboard.h resource.h wsnap.h + $(call compile, $<) + +evalgraph.o: ../evalgraph.c ../evalgraph.h config.h ../common.h ../frontend.h \ + ../backend.h ../lists.h $(call compile, $<) -wlayout.o: wlayout.c config.h ../common.h winboard.h resource.h +wlayout.o: wlayout.c config.h ../common.h ../frontend.h winboard.h resource.h $(call compile, $<) wsockerr.o: wsockerr.c wsockerr.h diff --git a/winboard/makefile.ms b/winboard/makefile.ms index 10c95fd..e81f17a 100644 --- a/winboard/makefile.ms +++ b/winboard/makefile.ms @@ -13,9 +13,9 @@ PROJ = winboard OBJS=backend.obj book.obj gamelist.obj lists.obj moves.obj pgntags.obj uci.obj\ - zippy.obj parser.obj wclipbrd.obj wedittags.obj wengineo.obj wevalgraph.obj\ + zippy.obj parser.obj wclipbrd.obj wedittags.obj wengineoutput.obj wevalgraph.obj\ wgamelist.obj whistory.obj winboard.obj wlayout.obj woptions.obj wsnap.obj\ - wsockerr.obj help.obj wsettings.obj wchat.obj + wsockerr.obj help.obj wsettings.obj wchat.obj engineoutput.obj evalgraph.obj # Debugging? @@ -122,20 +122,24 @@ wclipbrd.obj: wclipbrd.c config.h ../common.h ../frontend.h ../backend.h \ $(CC) $(CFLAGS) wclipbrd.c wedittags.obj: wedittags.c config.h ../common.h winboard.h resource.h ../frontend.h \ - ../backend.h ../lists.h wedittags.h + ../backend.h ../lists.h $(CC) $(CFLAGS) wedittags.c wgamelist.obj: wgamelist.c config.h. ../common.h winboard.h resource.h ../frontend.h \ - ../backend.h wgamelist.h ../lists.h + ../backend.h ../lists.h $(CC) $(CFLAGS) wgamelist.c woptions.obj: woptions.c config.h ../common.h ../frontend.h ../backend.h \ ../lists.h defaults.h winboard.h resource.h $(CC) $(CFLAGS) woptions.c -wengineo.obj: wengineo.c config.h ../common.h ../frontend.h ../backend.h \ +wengineoutput.obj: wengineoutput.c config.h ../common.h ../frontend.h ../backend.h \ ../lists.h winboard.h resource.h wsnap.h - $(CC) $(CFLAGS) wengineo.c + $(CC) $(CFLAGS) wengineoutput.c + +engineoutput.obj: ../engineoutput.c ../engineoutput.h config.h ../common.h \ + ../frontend.h ../backend.h ../lists.h + $(CC) $(CFLAGS) ../engineoutput.c whistory.obj: whistory.c config.h ../common.h ../frontend.h ../backend.h \ ../lists.h winboard.h resource.h wsnap.h @@ -145,7 +149,11 @@ wevalgraph.obj: wevalgraph.c config.h ../common.h ../frontend.h ../backend.h \ ../lists.h winboard.h resource.h wsnap.h $(CC) $(CFLAGS) wevalgraph.c -wlayout.obj: wlayout.c config.h ../common.h winboard.h resource.h +evalgraph.obj: ../evalgraph.c ../evalgraph.h config.h ../common.h ../frontend.h \ + ../backend.h ../lists.h + $(CC) $(CFLAGS) ../evalgraph.c + +wlayout.obj: wlayout.c config.h ../common.h ../frontend.h winboard.h resource.h $(CC) $(CFLAGS) wlayout.c wsockerr.obj: wsockerr.c wsockerr.h diff --git a/winboard/resource.h b/winboard/resource.h index 744509d..93e5517 100644 --- a/winboard/resource.h +++ b/winboard/resource.h @@ -89,6 +89,9 @@ #define OPT_TCTime2 409 #define OPT_TCOdds1 410 #define OPT_TCOdds2 411 +#define OPT_TCUseFixed 412 +#define OPT_TCFixed 413 +#define OPT_TCftext 414 #define DLG_PremoveOptions 450 #define DLG_GeneralOptions 453 #define DLG_IcsOptions 454 diff --git a/winboard/wchat.c b/winboard/wchat.c index a2b0825..fbf3e15 100644 --- a/winboard/wchat.c +++ b/winboard/wchat.c @@ -32,8 +32,8 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" +#include "winboard.h" #include "backend.h" #include "wsnap.h" @@ -180,8 +180,9 @@ LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam if(!atoi(chatPartner[partner])) { sprintf(buf, "> %s\n", mess); // echo only tells to handle, not channel InsertIntoMemo(hDlg, buf); - } sprintf(buf, "xtell %s %s\n", chatPartner[partner], mess); + } else + sprintf(buf, "tell %s %s\n", chatPartner[partner], mess); } SendToICS(buf); break; diff --git a/winboard/wclipbrd.c b/winboard/wclipbrd.c index 6f546a4..f13e77f 100644 --- a/winboard/wclipbrd.c +++ b/winboard/wclipbrd.c @@ -32,9 +32,9 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "wclipbrd.h" /* Imports from winboard.c */ @@ -50,6 +50,7 @@ CopyFENToClipboard() { char *fen = NULL; + if(gameMode == EditPosition) EditPositionDone(TRUE); // [HGM] mak sure castling rights are set consistently fen = PositionToFEN(currentMove, NULL); if (!fen) { DisplayError("Unable to convert position to FEN.", 0); diff --git a/winboard/wedittags.c b/winboard/wedittags.c index 3039f4c..965e723 100644 --- a/winboard/wedittags.c +++ b/winboard/wedittags.c @@ -35,17 +35,14 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" -#include "wedittags.h" +#include "winboard.h" /* Module globals */ static char *editTagsText; -HWND editTagsDialog = NULL; BOOL editTagsUp = FALSE; BOOL canEditTags = FALSE; -int editTagsX, editTagsY, editTagsW, editTagsH; /* Imports from winboard.c */ extern HINSTANCE hInst; @@ -86,18 +83,18 @@ EditTagsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetClientRect(hDlg, &rect); sizeX = rect.right; sizeY = rect.bottom; - if (editTagsX != CW_USEDEFAULT && editTagsY != CW_USEDEFAULT && - editTagsW != CW_USEDEFAULT && editTagsH != CW_USEDEFAULT) { + if (wpTags.x != CW_USEDEFAULT && wpTags.y != CW_USEDEFAULT && + wpTags.width != CW_USEDEFAULT && wpTags.height != CW_USEDEFAULT) { WINDOWPLACEMENT wp; - EnsureOnScreen(&editTagsX, &editTagsY, 0, 0); + EnsureOnScreen(&wpTags.x, &wpTags.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = editTagsX; - wp.rcNormalPosition.right = editTagsX + editTagsW; - wp.rcNormalPosition.top = editTagsY; - wp.rcNormalPosition.bottom = editTagsY + editTagsH; + wp.rcNormalPosition.left = wpTags.x; + wp.rcNormalPosition.right = wpTags.x + wpTags.width; + wp.rcNormalPosition.top = wpTags.y; + wp.rcNormalPosition.bottom = wpTags.y + wpTags.height; SetWindowPlacement(hDlg, &wp); GetClientRect(hDlg, &rect); diff --git a/winboard/wedittags.h b/winboard/wedittags.h deleted file mode 100644 index e27a338..0000000 --- a/winboard/wedittags.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * wedittags.h -- EditTags window for WinBoard - * - * Copyright 1995,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. */ - -VOID EditTagsProc(void); -extern HWND editTagsDialog; -extern int editTagsX, editTagsY, editTagsW, editTagsH; - diff --git a/winboard/wengineo.c b/winboard/wengineo.c index 1c3238f..bb51525 100644 --- a/winboard/wengineo.c +++ b/winboard/wengineo.c @@ -1,5 +1,5 @@ /* - * Engine output (PV) + * wengineoutput.c - split-off front-end of Engine output (PV) by HGM * * Author: Alessandro Scotti (Dec 2005) * @@ -34,99 +34,19 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "wsnap.h" +#include "engineoutput.h" -// [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 - +/* Module variables */ +int windowMode = 1; +static BOOLEAN engineOutputDialogUp = FALSE; HICON 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 - HWND outputField[2][7]; // [HGM] front-end array to translate output field to window handle -void EngineOutputPopUp(); -void EngineOutputPopDown(); -int EngineOutputIsUp(); - -#define SHOW_PONDERING - -/* Imports from backend.c */ -char * SavePart(char *str); -extern int opponentKibitzes; - -/* Imports from winboard.c */ -extern HWND engineOutputDialog; -extern int engineOutputDialogUp; - -extern HINSTANCE hInst; -extern HWND hwndMain; - -extern WindowPlacement wpEngineOutput; - -extern BoardSize boardSize; - -/* 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 }; - -typedef struct { -// HWND hColorIcon; // [HGM] the output-control handles are no loger passed, -// HWND hLabel; // to give better front-end / back-end separation -// HWND hStateIcon; // the front-end routines now get them from a (front-end) -// HWND hStateData; // table, indexed by output-field indicators. -// HWND hLabelNPS; -// HWND hMemo; - 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; - -static void VerifyDisplayMode(); -static void UpdateControls( EngineOutputData * ed ); -static void SetEngineState( int which, int state, char * state_data ); - // front end static HICON LoadIconEx( int id ) { @@ -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. static void InitializeEngineOutput() { - // if( needInit ) { // needInit was already tested before call // [HGM] made this into a table, rather than separate global variables icons[nColorBlack] = LoadIconEx( IDI_BLACK_14 ); icons[nColorWhite] = LoadIconEx( IDI_WHITE_14 ); @@ -163,8 +82,6 @@ static void InitializeEngineOutput() outputField[1][nStateData] = GetDlgItem( engineOutputDialog, IDC_StateData2 ); outputField[1][nLabelNPS] = GetDlgItem( engineOutputDialog, IDC_Engine2_NPS ); outputField[1][nMemo] = GetDlgItem( engineOutputDialog, IDC_EngineMemo2 ); -// needInit = FALSE; -// } } // front end @@ -248,8 +165,9 @@ static void PositionControlSet( HWND hDlg, int x, int y, int clientWidth, int me } // Also here some of the size calculations should go to the back end, and their actual application to a front-end routine -static void ResizeWindowControls( HWND hDlg, int mode ) +void ResizeWindowControls( int mode ) { + HWND hDlg = engineOutputDialog; // [HGM] used to be parameter, but routine is called from back-end RECT rc; int headerHeight = GetHeaderHeight(); // int labelHeight = GetControlHeight( hDlg, IDC_EngineLabel1 ); @@ -306,16 +224,16 @@ static void ResizeWindowControls( HWND hDlg, int mode ) } // front end. Actual printing of PV lines into the output field -static void InsertIntoMemo( int which, char * text ) +void InsertIntoMemo( int which, char * text, int where ) { - SendMessage( outputField[which][nMemo], EM_SETSEL, 0, 0 ); + SendMessage( outputField[which][nMemo], EM_SETSEL, where, where ); // [HGM] multivar: choose insertion point SendMessage( outputField[which][nMemo], EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text ); } // front end. Associates an icon with an output field ("control" in Windows jargon). // [HGM] let it find out the output field from the 'which' number by itself -static void SetIcon( int which, int field, int nIcon ) +void SetIcon( int which, int field, int nIcon ) { if( nIcon != 0 ) { @@ -341,7 +259,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA RestoreWindowPlacement( hDlg, &wpEngineOutput ); /* Restore window placement */ - ResizeWindowControls( hDlg, windowMode ); + ResizeWindowControls( windowMode ); /* Set font */ SendDlgItemMessage( engineOutputDialog, IDC_EngineMemo1, WM_SETFONT, (WPARAM)font[boardSize][MOVEHISTORY_FONT]->hf, MAKELPARAM(TRUE, 0 )); @@ -383,7 +301,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA break; case WM_SIZE: - ResizeWindowControls( hDlg, windowMode ); + ResizeWindowControls( windowMode ); break; case WM_ENTERSIZEMOVE: @@ -406,6 +324,7 @@ LRESULT CALLBACK EngineOutputProc( HWND hDlg, UINT message, WPARAM wParam, LPARA void EngineOutputPopUp() { FARPROC lpProc; + static int needInit = TRUE; CheckMenuItem(GetMenu(hwndMain), IDM_ShowEngineOutput, MF_CHECKED); @@ -452,404 +371,14 @@ void DoClearMemo(int which) SendMessage( outputField[which][nMemo], WM_SETTEXT, 0, (LPARAM) "" ); } -//------------------------ 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( engineOutputDialog == 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; - default: ; // does not happen, but suppresses pedantic warnings - } - } - - 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; - default: ; // does not happen, but suppresses pedantic warnings - } - - return result; -} - -// back end -static void SetDisplayMode( int mode ) -{ - if( windowMode != mode ) { - windowMode = mode; - - ResizeWindowControls( engineOutputDialog, 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 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 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: %s [%02d:%02d:%02d]", 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 ); - } - - /* Colors */ - SetEngineColorIcon( ed->which ); -} - -// back end +// front end (because only other front-end wants to know) int EngineOutputIsUp() { return engineOutputDialogUp; } -// [HGM] kibitz: write kibitz line; split window for it if necessary -void OutputKibitz(int window, char *text) +// front end, to give back-end access to engineOutputDialog +int EngineOutputDialogExists() { - 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); + return engineOutputDialog != NULL; } diff --git a/winboard/wevalgraph.c b/winboard/wevalgraph.c index be51991..ec57ab3 100644 --- a/winboard/wevalgraph.c +++ b/winboard/wevalgraph.c @@ -1,5 +1,5 @@ /* - * Evaluation graph + * wevalgraph.c - Evaluation graph front-end part * * Author: Alessandro Scotti (Dec 2005) * @@ -27,358 +27,22 @@ #include "config.h" -#include /* required for all Windows applications */ -//include +#include +#include +#include #include -//include -//include #include "common.h" #include "frontend.h" #include "backend.h" - -/* Imports from winboard.c */ -extern BOOLEAN evalGraphDialogUp; // should be back-end variable, and defined here - -/* Module globals */ // used to communicate between back-end and front-end part -static ChessProgramStats_Move * currPvInfo; -static int currFirst = 0; -static int currLast = 0; -static int currCurrent = -1; - -static int nWidthPB = 0; -static int nHeightPB = 0; - -static int MarginX = 18; -static int MarginW = 4; -static int MarginH = 4; - -#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 - -// calls from back-end part into front-end -static 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); - - -// 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, BOOL 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 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 ) -{ - BOOL 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(); -} - -Boolean EvalGraphIsUp() -{ - return evalGraphDialogUp; -} - -// ------------------------------------------ front-end starts here ---------------------------------------------- - -#include -#include - #include "winboard.h" +#include "evalgraph.h" #include "wsnap.h" #define WM_REFRESH_GRAPH (WM_USER + 1) -void EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo ); -void EvalGraphPopUp(); -void EvalGraphPopDown(); -Boolean EvalGraphIsUp(); - -// calls of front-end part into back-end part -extern int GetMoveIndexFromPoint( int x, int y ); -extern void PaintEvalGraph( void ); - -/* Imports from winboard.c */ -extern HWND evalGraphDialog; -extern BOOLEAN evalGraphDialogUp; // should be back-end, really - -extern HINSTANCE hInst; -extern HWND hwndMain; - -extern WindowPlacement wpEvalGraph; +/* Module globals */ +static BOOLEAN evalGraphDialogUp; static COLORREF crWhite = RGB( 0xFF, 0xFF, 0xB0 ); static COLORREF crBlack = RGB( 0xAD, 0x5D, 0x3D ); @@ -388,8 +52,13 @@ static HBITMAP hbmPB = NULL; static HPEN pens[6]; // [HGM] put all pens in one array static HBRUSH hbrHist[3] = { NULL, NULL, NULL }; +Boolean EvalGraphIsUp() +{ + return evalGraphDialogUp; +} + // [HGM] front-end, added as wrapper to avoid use of LineTo and MoveToEx in other routines (so they can be back-end) -static void DrawSegment( int x, int y, int *lastX, int *lastY, int penType ) +void DrawSegment( int x, int y, int *lastX, int *lastY, int penType ) { POINT stPt; if(penType == PEN_NONE) MoveToEx( hdcPB, x, y, &stPt ); else { @@ -642,4 +311,3 @@ VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pv SendMessage( evalGraphDialog, WM_REFRESH_GRAPH, 0, 0 ); } } - diff --git a/winboard/wgamelist.c b/winboard/wgamelist.c index 26c843b..31d36ff 100644 --- a/winboard/wgamelist.c +++ b/winboard/wgamelist.c @@ -35,25 +35,16 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "wsnap.h" -#include "wgamelist.h" - -extern BoardSize boardSize; /* Module globals */ -HWND gameListDialog = NULL; -BOOLEAN gameListUp = FALSE; -FILE* gameFile; -char* gameFileName = NULL; - -/* Imports from winboard.c */ -extern HINSTANCE hInst; -extern HWND hwndMain; -extern WindowPlacement wpGameList; +static BOOLEAN gameListUp = FALSE; +static FILE* gameFile; +static char* gameFileName = NULL; struct GameListStats { @@ -265,7 +256,9 @@ GameListDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) newSizeX, newSizeY); sizeX = newSizeX; sizeY = newSizeY; - } + } + else + GetActualPlacement( gameListDialog, &wpGameList ); GameListUpdateTitle( hDlg, szDlgTitle, count, ((ListGame *) gameList.tailPred)->number, &stats ); } diff --git a/winboard/wgamelist.h b/winboard/wgamelist.h deleted file mode 100644 index aa554f9..0000000 --- a/winboard/wgamelist.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * wgamelist.h -- Game list window for WinBoard - * - * Copyright 1995,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. */ - -VOID ShowGameListProc(void); -extern HWND gameListDialog; -extern int gameListX, gameListY, gameListW, gameListH; diff --git a/winboard/whistory.c b/winboard/whistory.c index 73ae025..933359c 100644 --- a/winboard/whistory.c +++ b/winboard/whistory.c @@ -34,33 +34,15 @@ #include #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "wsnap.h" -VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo ); -VOID MoveHistoryPopUp(); -VOID MoveHistoryPopDown(); -BOOL MoveHistoryIsUp(); - -/* Imports from backend.c */ -char * SavePart(char *str); - -/* Imports from winboard.c */ -extern HWND moveHistoryDialog; -extern BOOLEAN moveHistoryDialogUp; - -extern HINSTANCE hInst; -extern HWND hwndMain; - -extern WindowPlacement wpMoveHistory; - -extern BoardSize boardSize; - /* Module globals */ typedef char MoveHistoryString[ MOVE_LEN*2 ]; +static BOOLEAN moveHistoryDialogUp = FALSE; static int lastFirst = 0; static int lastLast = 0; diff --git a/winboard/winboard.c b/winboard/winboard.c index 5a8df2b..ee5fa0c 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -80,13 +80,11 @@ #endif #include "common.h" -#include "winboard.h" #include "frontend.h" #include "backend.h" +#include "winboard.h" #include "moves.h" #include "wclipbrd.h" -#include "wgamelist.h" -#include "wedittags.h" #include "woptions.h" #include "wsockerr.h" #include "defaults.h" @@ -158,10 +156,10 @@ char installDir[MSG_SIZ]; BoardSize boardSize; BOOLEAN chessProgram; -static int boardX, boardY; +//static int boardX, boardY; int minX, minY; // [HGM] placement: volatile limits on upper-left corner static int squareSize, lineGap, minorSize; -static int winWidth, winHeight, winW, winH; +static int winW, winH; static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo static int logoHeight = 0; static char messageText[MESSAGE_TEXT_MAX]; @@ -181,8 +179,6 @@ char *secondChessProgramNames; #define PALETTESIZE 256 HINSTANCE hInst; /* current instance */ -HWND hwndMain = NULL; /* root window*/ -HWND hwndConsole = NULL; BOOLEAN alwaysOnTop = FALSE; RECT boardRect; COLORREF lightSquareColor, darkSquareColor, whitePieceColor, @@ -197,8 +193,8 @@ static HBRUSH lightSquareBrush, darkSquareBrush, blackSquareBrush, /* [HGM] for band between board and holdings */ explodeBrush, /* [HGM] atomic */ whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/; -static POINT gridEndpoints[(BOARD_SIZE + 1) * 4]; -static DWORD gridVertexCounts[(BOARD_SIZE + 1) * 2]; +static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2]; +static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2]; static HPEN gridPen = NULL; static HPEN highlightPen = NULL; static HPEN premovePen = NULL; @@ -220,7 +216,7 @@ static HBITMAP darkBackTexture = NULL; static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN; static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN; static int backTextureSquareSize = 0; -static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE]; +static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOARD_FILES]; #if __GNUC__ && !defined(_winmajor) #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */ @@ -346,15 +342,7 @@ static char *commentTitle; static char *commentText; static int commentIndex; static Boolean editComment = FALSE; -HWND commentDialog = NULL; -int commentUp = FALSE; -static int commentX, commentY, commentH, commentW; -static char *analysisTitle; -static char *analysisText; -HWND analysisDialog = NULL; -BOOLEAN analysisDialogUp = FALSE; -static int analysisX, analysisY, analysisH, analysisW; char errorTitle[MSG_SIZ]; char errorMessage[2*MSG_SIZ]; @@ -424,37 +412,27 @@ VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca); int NewGameFRC(); int GameListOptions(); -HWND moveHistoryDialog = NULL; -BOOLEAN moveHistoryDialogUp = FALSE; - -WindowPlacement wpMoveHistory; +int dummy; // [HGM] for obsolete args +HWND hwndMain = NULL; /* root window*/ +HWND hwndConsole = NULL; +HWND commentDialog = NULL; +HWND moveHistoryDialog = NULL; HWND evalGraphDialog = NULL; -BOOLEAN evalGraphDialogUp = FALSE; - -WindowPlacement wpEvalGraph; - HWND engineOutputDialog = NULL; -BOOLEAN engineOutputDialogUp = FALSE; +HWND gameListDialog = NULL; +HWND editTagsDialog = NULL; + +int commentUp = FALSE; +WindowPlacement wpMain; +WindowPlacement wpConsole; +WindowPlacement wpComment; +WindowPlacement wpMoveHistory; +WindowPlacement wpEvalGraph; WindowPlacement wpEngineOutput; WindowPlacement wpGameList; -WindowPlacement wpConsole; - -VOID MoveHistoryPopUp(); -VOID MoveHistoryPopDown(); -VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo ); -BOOL MoveHistoryIsUp(); - -VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo ); -VOID EvalGraphPopUp(); -VOID EvalGraphPopDown(); -BOOL EvalGraphIsUp(); - -VOID EngineOutputPopUp(); -VOID EngineOutputPopDown(); -BOOL EngineOutputIsUp(); -VOID EngineOutputUpdate( FrontEndProgramStats * stats ); +WindowPlacement wpTags; VOID EngineOptionsPopup(); // [HGM] settings @@ -861,15 +839,15 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) InitBackEnd2(); /* Make the window visible; update its client area; and return "success" */ - EnsureOnScreen(&boardX, &boardY, minX, minY); + EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = nCmdShow; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = boardX; - wp.rcNormalPosition.right = boardX + winWidth; - wp.rcNormalPosition.top = boardY; - wp.rcNormalPosition.bottom = boardY + winHeight; + wp.rcNormalPosition.left = wpMain.x; + wp.rcNormalPosition.right = wpMain.x + wpMain.width; + wp.rcNormalPosition.top = wpMain.y; + wp.rcNormalPosition.bottom = wpMain.y + wpMain.height; SetWindowPlacement(hwndMain, &wp); if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, @@ -897,6 +875,9 @@ typedef enum { ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window } ArgType; +typedef void *ArgIniType; +#define INVALID (ArgIniType) 6915 /* Some number unlikely to be needed as default for anything */ + typedef struct { char *argName; ArgType argType; @@ -917,532 +898,553 @@ typedef struct { ***/ LPVOID argLoc; BOOL save; + ArgIniType defaultValue; } ArgDescriptor; int junk; + +#define XBOARD FALSE + ArgDescriptor argDescriptors[] = { /* positional arguments */ - { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, - { "", ArgNone, NULL }, + { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE, INVALID }, + { "", ArgNone, NULL, FALSE, INVALID }, /* keyword arguments */ JAWS_ARGS - { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE }, - { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE }, - { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE }, - { "bpc", ArgColor, (LPVOID) &blackPieceColor, FALSE }, - { "lightSquareColor", ArgColor, (LPVOID) &lightSquareColor, TRUE }, - { "lsc", ArgColor, (LPVOID) &lightSquareColor, FALSE }, - { "darkSquareColor", ArgColor, (LPVOID) &darkSquareColor, TRUE }, - { "dsc", ArgColor, (LPVOID) &darkSquareColor, FALSE }, - { "highlightSquareColor", ArgColor, (LPVOID) &highlightSquareColor, TRUE }, - { "hsc", ArgColor, (LPVOID) &highlightSquareColor, FALSE }, - { "premoveHighlightColor", ArgColor, (LPVOID) &premoveHighlightColor, TRUE }, - { "phc", ArgColor, (LPVOID) &premoveHighlightColor, FALSE }, - { "movesPerSession", ArgInt, (LPVOID) &appData.movesPerSession, TRUE }, - { "mps", ArgInt, (LPVOID) &appData.movesPerSession, FALSE }, - { "initString", ArgString, (LPVOID) &appData.initString, FALSE }, - { "firstInitString", ArgString, (LPVOID) &appData.initString, FALSE }, - { "secondInitString", ArgString, (LPVOID) &appData.secondInitString, FALSE }, + { "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE, INVALID }, + { "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE, INVALID }, + { "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE, INVALID }, + { "bpc", ArgColor, (LPVOID) &blackPieceColor, FALSE, INVALID }, + { "lightSquareColor", ArgColor, (LPVOID) &lightSquareColor, TRUE, INVALID }, + { "lsc", ArgColor, (LPVOID) &lightSquareColor, FALSE, INVALID }, + { "darkSquareColor", ArgColor, (LPVOID) &darkSquareColor, TRUE, INVALID }, + { "dsc", ArgColor, (LPVOID) &darkSquareColor, FALSE, INVALID }, + { "highlightSquareColor", ArgColor, (LPVOID) &highlightSquareColor, TRUE, INVALID }, + { "hsc", ArgColor, (LPVOID) &highlightSquareColor, FALSE, INVALID }, + { "premoveHighlightColor", ArgColor, (LPVOID) &premoveHighlightColor, TRUE, INVALID }, + { "phc", ArgColor, (LPVOID) &premoveHighlightColor, FALSE, INVALID }, + { "movesPerSession", ArgInt, (LPVOID) &appData.movesPerSession, TRUE, (ArgIniType) MOVES_PER_SESSION }, + { "mps", ArgInt, (LPVOID) &appData.movesPerSession, FALSE, INVALID }, + { "initString", ArgString, (LPVOID) &appData.initString, FALSE, INVALID }, + { "firstInitString", ArgString, (LPVOID) &appData.initString, FALSE, (ArgIniType) INIT_STRING }, + { "secondInitString", ArgString, (LPVOID) &appData.secondInitString, FALSE, (ArgIniType) INIT_STRING }, { "firstComputerString", ArgString, (LPVOID) &appData.firstComputerString, - FALSE }, + FALSE, (ArgIniType) COMPUTER_STRING }, { "secondComputerString", ArgString, (LPVOID) &appData.secondComputerString, - FALSE }, + FALSE, (ArgIniType) COMPUTER_STRING }, { "firstChessProgram", ArgFilename, (LPVOID) &appData.firstChessProgram, - FALSE }, - { "fcp", ArgFilename, (LPVOID) &appData.firstChessProgram, FALSE }, + FALSE, (ArgIniType) FIRST_CHESS_PROGRAM }, + { "fcp", ArgFilename, (LPVOID) &appData.firstChessProgram, FALSE, INVALID }, { "secondChessProgram", ArgFilename, (LPVOID) &appData.secondChessProgram, - FALSE }, - { "scp", ArgFilename, (LPVOID) &appData.secondChessProgram, FALSE }, - { "firstPlaysBlack", ArgBoolean, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "fb", ArgTrue, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "xfb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "-fb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE }, - { "noChessProgram", ArgBoolean, (LPVOID) &appData.noChessProgram, FALSE }, - { "ncp", ArgTrue, (LPVOID) &appData.noChessProgram, FALSE }, - { "xncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE }, - { "-ncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE }, - { "firstHost", ArgString, (LPVOID) &appData.firstHost, FALSE }, - { "fh", ArgString, (LPVOID) &appData.firstHost, FALSE }, - { "secondHost", ArgString, (LPVOID) &appData.secondHost, FALSE }, - { "sh", ArgString, (LPVOID) &appData.secondHost, FALSE }, - { "firstDirectory", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE }, - { "fd", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE }, - { "secondDirectory", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE }, - { "sd", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE }, - /*!!bitmapDirectory?*/ - { "remoteShell", ArgFilename, (LPVOID) &appData.remoteShell, FALSE }, - { "rsh", ArgFilename, (LPVOID) &appData.remoteShell, FALSE }, - { "remoteUser", ArgString, (LPVOID) &appData.remoteUser, FALSE }, - { "ruser", ArgString, (LPVOID) &appData.remoteUser, FALSE }, - { "timeDelay", ArgFloat, (LPVOID) &appData.timeDelay, TRUE }, - { "td", ArgFloat, (LPVOID) &appData.timeDelay, FALSE }, - { "timeControl", ArgString, (LPVOID) &appData.timeControl, TRUE }, - { "tc", ArgString, (LPVOID) &appData.timeControl, FALSE }, - { "timeIncrement", ArgInt, (LPVOID) &appData.timeIncrement, TRUE }, - { "inc", ArgInt, (LPVOID) &appData.timeIncrement, FALSE }, - { "internetChessServerMode", ArgBoolean, (LPVOID) &appData.icsActive, FALSE }, - { "ics", ArgTrue, (LPVOID) &appData.icsActive, FALSE }, - { "xics", ArgFalse, (LPVOID) &appData.icsActive, FALSE }, - { "-ics", ArgFalse, (LPVOID) &appData.icsActive, FALSE }, - { "internetChessServerHost", ArgString, (LPVOID) &appData.icsHost, FALSE }, - { "icshost", ArgString, (LPVOID) &appData.icsHost, FALSE }, - { "internetChessServerPort", ArgString, (LPVOID) &appData.icsPort, FALSE }, - { "icsport", ArgString, (LPVOID) &appData.icsPort, FALSE }, - { "internetChessServerCommPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "icscomm", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "internetChessServerComPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "icscom", ArgString, (LPVOID) &appData.icsCommPort, FALSE }, - { "internetChessServerLogonScript", ArgFilename, (LPVOID) &appData.icsLogon, FALSE }, - { "icslogon", ArgFilename, (LPVOID) &appData.icsLogon, FALSE }, - { "useTelnet", ArgBoolean, (LPVOID) &appData.useTelnet, FALSE }, - { "telnet", ArgTrue, (LPVOID) &appData.useTelnet, FALSE }, - { "xtelnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE }, - { "-telnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE }, - { "telnetProgram", ArgFilename, (LPVOID) &appData.telnetProgram, FALSE }, - { "icshelper", ArgFilename, (LPVOID) &appData.icsHelper, FALSE }, - { "gateway", ArgString, (LPVOID) &appData.gateway, FALSE }, - { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, - { "lgf", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE }, - { "loadGameIndex", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE }, - { "lgi", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE }, - { "saveGameFile", ArgFilename, (LPVOID) &appData.saveGameFile, TRUE }, - { "sgf", ArgFilename, (LPVOID) &appData.saveGameFile, FALSE }, - { "autoSaveGames", ArgBoolean, (LPVOID) &appData.autoSaveGames, TRUE }, - { "autosave", ArgTrue, (LPVOID) &appData.autoSaveGames, FALSE }, - { "xautosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE }, - { "-autosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE }, - { "loadPositionFile", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE }, - { "lpf", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE }, - { "loadPositionIndex", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE }, - { "lpi", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE }, - { "savePositionFile", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE }, - { "spf", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE }, - { "matchMode", ArgBoolean, (LPVOID) &appData.matchMode, FALSE }, - { "mm", ArgTrue, (LPVOID) &appData.matchMode, FALSE }, - { "xmm", ArgFalse, (LPVOID) &appData.matchMode, FALSE }, - { "-mm", ArgFalse, (LPVOID) &appData.matchMode, FALSE }, - { "matchGames", ArgInt, (LPVOID) &appData.matchGames, FALSE }, - { "mg", ArgInt, (LPVOID) &appData.matchGames, FALSE }, - { "monoMode", ArgBoolean, (LPVOID) &appData.monoMode, TRUE }, - { "mono", ArgTrue, (LPVOID) &appData.monoMode, FALSE }, - { "xmono", ArgFalse, (LPVOID) &appData.monoMode, FALSE }, - { "-mono", ArgFalse, (LPVOID) &appData.monoMode, FALSE }, - { "debugMode", ArgBoolean, (LPVOID) &appData.debugMode, FALSE }, - { "debug", ArgTrue, (LPVOID) &appData.debugMode, FALSE }, - { "xdebug", ArgFalse, (LPVOID) &appData.debugMode, FALSE }, - { "-debug", ArgFalse, (LPVOID) &appData.debugMode, FALSE }, - { "clockMode", ArgBoolean, (LPVOID) &appData.clockMode, FALSE }, - { "clock", ArgTrue, (LPVOID) &appData.clockMode, FALSE }, - { "xclock", ArgFalse, (LPVOID) &appData.clockMode, FALSE }, - { "-clock", ArgFalse, (LPVOID) &appData.clockMode, FALSE }, - { "searchTime", ArgString, (LPVOID) &appData.searchTime, FALSE }, - { "st", ArgString, (LPVOID) &appData.searchTime, FALSE }, - { "searchDepth", ArgInt, (LPVOID) &appData.searchDepth, FALSE }, - { "depth", ArgInt, (LPVOID) &appData.searchDepth, FALSE }, - { "showCoords", ArgBoolean, (LPVOID) &appData.showCoords, TRUE }, - { "coords", ArgTrue, (LPVOID) &appData.showCoords, FALSE }, - { "xcoords", ArgFalse, (LPVOID) &appData.showCoords, FALSE }, - { "-coords", ArgFalse, (LPVOID) &appData.showCoords, FALSE }, - { "showThinking", ArgBoolean, (LPVOID) &appData.showThinking, TRUE }, - { "thinking", ArgTrue, (LPVOID) &appData.showThinking, FALSE }, - { "xthinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE }, - { "-thinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE }, - { "ponderNextMove", ArgBoolean, (LPVOID) &appData.ponderNextMove, TRUE }, - { "ponder", ArgTrue, (LPVOID) &appData.ponderNextMove, FALSE }, - { "xponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE }, - { "-ponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE }, - { "periodicUpdates", ArgBoolean, (LPVOID) &appData.periodicUpdates, TRUE }, - { "periodic", ArgTrue, (LPVOID) &appData.periodicUpdates, FALSE }, - { "xperiodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE }, - { "-periodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE }, - { "popupExitMessage", ArgBoolean, (LPVOID) &appData.popupExitMessage, TRUE }, - { "exit", ArgTrue, (LPVOID) &appData.popupExitMessage, FALSE }, - { "xexit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE }, - { "-exit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE }, - { "popupMoveErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, TRUE }, - { "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE }, - { "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE }, - { "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE }, + FALSE, (ArgIniType) SECOND_CHESS_PROGRAM }, + { "scp", ArgFilename, (LPVOID) &appData.secondChessProgram, FALSE, INVALID }, + { "firstPlaysBlack", ArgBoolean, (LPVOID) &appData.firstPlaysBlack, FALSE, FALSE }, + { "fb", ArgTrue, (LPVOID) &appData.firstPlaysBlack, FALSE, FALSE }, + { "xfb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE, INVALID }, + { "-fb", ArgFalse, (LPVOID) &appData.firstPlaysBlack, FALSE, INVALID }, + { "noChessProgram", ArgBoolean, (LPVOID) &appData.noChessProgram, FALSE, FALSE }, + { "ncp", ArgTrue, (LPVOID) &appData.noChessProgram, FALSE, INVALID }, + { "xncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE, INVALID }, + { "-ncp", ArgFalse, (LPVOID) &appData.noChessProgram, FALSE, INVALID }, + { "firstHost", ArgString, (LPVOID) &appData.firstHost, FALSE, (ArgIniType) FIRST_HOST }, + { "fh", ArgString, (LPVOID) &appData.firstHost, FALSE, INVALID }, + { "secondHost", ArgString, (LPVOID) &appData.secondHost, FALSE, (ArgIniType) SECOND_HOST }, + { "sh", ArgString, (LPVOID) &appData.secondHost, FALSE, INVALID }, + { "firstDirectory", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE, (ArgIniType) FIRST_DIRECTORY }, + { "fd", ArgFilename, (LPVOID) &appData.firstDirectory, FALSE, INVALID }, + { "secondDirectory", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE, (ArgIniType) SECOND_DIRECTORY }, + { "sd", ArgFilename, (LPVOID) &appData.secondDirectory, FALSE, INVALID }, + + /* some options only used by the XBoard front end, and ignored in WinBoard */ + /* Their saving is controlled by XBOARD, which in WinBoard is defined as FALSE */ + { "internetChessServerInputBox", ArgBoolean, (LPVOID) &appData.icsInputBox, XBOARD, (ArgIniType) FALSE }, + { "icsinput", ArgTrue, (LPVOID) &appData.icsInputBox, FALSE, INVALID }, + { "xicsinput", ArgFalse, (LPVOID) &appData.icsInputBox, FALSE, INVALID }, + { "cmail", ArgString, (LPVOID) &appData.cmailGameName, FALSE, (ArgIniType) "" }, + { "soundProgram", ArgFilename, (LPVOID) &appData.soundProgram, XBOARD, (ArgIniType) "play" }, + { "fontSizeTolerance", ArgInt, (LPVOID) &appData.fontSizeTolerance, XBOARD, (ArgIniType) 4 }, + { "lowTimeWarningColor", ArgColor, (LPVOID) &appData.lowTimeWarningColor, XBOARD, + (ArgIniType) LOWTIMEWARNING_COLOR }, + { "lowTimeWarning", ArgBoolean, (LPVOID) &appData.lowTimeWarning, XBOARD, (ArgIniType) FALSE }, + { "titleInWindow", ArgBoolean, (LPVOID) &appData.titleInWindow, XBOARD, (ArgIniType) FALSE }, + { "title", ArgTrue, (LPVOID) &appData.titleInWindow, FALSE, INVALID }, + { "xtitle", ArgFalse, (LPVOID) &appData.titleInWindow, FALSE, INVALID }, + { "flashCount", ArgInt, (LPVOID) &appData.flashCount, XBOARD, (ArgIniType) FLASH_COUNT }, + { "flashRate", ArgInt, (LPVOID) &appData.flashRate, XBOARD, (ArgIniType) FLASH_RATE }, + { "pixmapDirectory", ArgFilename, (LPVOID) &appData.pixmapDirectory, XBOARD, (ArgIniType) "" }, + { "pixmap", ArgFilename, (LPVOID) &appData.pixmapDirectory, FALSE, INVALID }, + { "bitmapDirectory", ArgFilename, (LPVOID) &appData.bitmapDirectory, XBOARD, (ArgIniType) "" }, + { "bm", ArgFilename, (LPVOID) &appData.bitmapDirectory, FALSE, INVALID }, + { "msLoginDelay", ArgInt, (LPVOID) &appData.msLoginDelay, XBOARD, (ArgIniType) MS_LOGIN_DELAY }, + { "pasteSelection", ArgBoolean, (LPVOID) &appData.pasteSelection, XBOARD, (ArgIniType) FALSE }, + + { "remoteShell", ArgFilename, (LPVOID) &appData.remoteShell, FALSE, (ArgIniType) REMOTE_SHELL }, + { "rsh", ArgFilename, (LPVOID) &appData.remoteShell, FALSE, INVALID }, + { "remoteUser", ArgString, (LPVOID) &appData.remoteUser, FALSE, INVALID }, + { "ruser", ArgString, (LPVOID) &appData.remoteUser, FALSE, INVALID }, + { "timeDelay", ArgFloat, (LPVOID) &appData.timeDelay, TRUE, INVALID }, + { "td", ArgFloat, (LPVOID) &appData.timeDelay, FALSE, INVALID }, + { "timeControl", ArgString, (LPVOID) &appData.timeControl, TRUE, (ArgIniType) TIME_CONTROL }, + { "tc", ArgString, (LPVOID) &appData.timeControl, FALSE, INVALID }, + { "timeIncrement", ArgInt, (LPVOID) &appData.timeIncrement, TRUE, (ArgIniType) TIME_INCREMENT }, + { "inc", ArgInt, (LPVOID) &appData.timeIncrement, FALSE, INVALID }, + { "internetChessServerMode", ArgBoolean, (LPVOID) &appData.icsActive, FALSE, INVALID }, + { "ics", ArgTrue, (LPVOID) &appData.icsActive, FALSE, (ArgIniType) FALSE }, + { "xics", ArgFalse, (LPVOID) &appData.icsActive, FALSE, INVALID }, + { "-ics", ArgFalse, (LPVOID) &appData.icsActive, FALSE, INVALID }, + { "internetChessServerHost", ArgString, (LPVOID) &appData.icsHost, FALSE, (ArgIniType) "" }, + { "icshost", ArgString, (LPVOID) &appData.icsHost, FALSE, INVALID }, + { "internetChessServerPort", ArgString, (LPVOID) &appData.icsPort, FALSE, (ArgIniType) ICS_PORT }, + { "icsport", ArgString, (LPVOID) &appData.icsPort, FALSE, INVALID }, + { "internetChessServerCommPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE, (ArgIniType) ICS_COMM_PORT }, + { "icscomm", ArgString, (LPVOID) &appData.icsCommPort, FALSE, INVALID }, + { "internetChessServerComPort", ArgString, (LPVOID) &appData.icsCommPort, FALSE, INVALID }, + { "icscom", ArgString, (LPVOID) &appData.icsCommPort, FALSE, INVALID }, + { "internetChessServerLogonScript", ArgFilename, (LPVOID) &appData.icsLogon, FALSE, (ArgIniType) ICS_LOGON }, + { "icslogon", ArgFilename, (LPVOID) &appData.icsLogon, FALSE, INVALID }, + { "useTelnet", ArgBoolean, (LPVOID) &appData.useTelnet, FALSE, INVALID }, + { "telnet", ArgTrue, (LPVOID) &appData.useTelnet, FALSE, INVALID }, + { "xtelnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE, INVALID }, + { "-telnet", ArgFalse, (LPVOID) &appData.useTelnet, FALSE, INVALID }, + { "telnetProgram", ArgFilename, (LPVOID) &appData.telnetProgram, FALSE, (ArgIniType) TELNET_PROGRAM }, + { "internetChessserverHelper", ArgFilename, (LPVOID) &appData.icsHelper, + FALSE, INVALID }, // for XB + { "icshelper", ArgFilename, (LPVOID) &appData.icsHelper, FALSE, (ArgIniType) "" }, + { "gateway", ArgString, (LPVOID) &appData.gateway, FALSE, (ArgIniType) "" }, + { "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE, (ArgIniType) "" }, + { "lgf", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE, INVALID }, + { "loadGameIndex", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE, (ArgIniType) 0 }, + { "lgi", ArgInt, (LPVOID) &appData.loadGameIndex, FALSE, INVALID }, + { "saveGameFile", ArgFilename, (LPVOID) &appData.saveGameFile, TRUE, (ArgIniType) "" }, + { "sgf", ArgFilename, (LPVOID) &appData.saveGameFile, FALSE, INVALID }, + { "autoSaveGames", ArgBoolean, (LPVOID) &appData.autoSaveGames, TRUE, (ArgIniType) FALSE }, + { "autosave", ArgTrue, (LPVOID) &appData.autoSaveGames, FALSE, INVALID }, + { "xautosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE, INVALID }, + { "-autosave", ArgFalse, (LPVOID) &appData.autoSaveGames, FALSE, INVALID }, + { "loadPositionFile", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE, (ArgIniType) "" }, + { "lpf", ArgFilename, (LPVOID) &appData.loadPositionFile, FALSE, INVALID }, + { "loadPositionIndex", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE, (ArgIniType) 1 }, + { "lpi", ArgInt, (LPVOID) &appData.loadPositionIndex, FALSE, INVALID }, + { "savePositionFile", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE, (ArgIniType) "" }, + { "spf", ArgFilename, (LPVOID) &appData.savePositionFile, FALSE, INVALID }, + { "matchMode", ArgBoolean, (LPVOID) &appData.matchMode, FALSE, (ArgIniType) FALSE }, + { "mm", ArgTrue, (LPVOID) &appData.matchMode, FALSE, INVALID }, + { "xmm", ArgFalse, (LPVOID) &appData.matchMode, FALSE, INVALID }, + { "-mm", ArgFalse, (LPVOID) &appData.matchMode, FALSE, INVALID }, + { "matchGames", ArgInt, (LPVOID) &appData.matchGames, FALSE, (ArgIniType) 0 }, + { "mg", ArgInt, (LPVOID) &appData.matchGames, FALSE, INVALID }, + { "monoMode", ArgBoolean, (LPVOID) &appData.monoMode, TRUE, (ArgIniType) FALSE }, + { "mono", ArgTrue, (LPVOID) &appData.monoMode, FALSE, INVALID }, + { "xmono", ArgFalse, (LPVOID) &appData.monoMode, FALSE, INVALID }, + { "-mono", ArgFalse, (LPVOID) &appData.monoMode, FALSE, INVALID }, + { "debugMode", ArgBoolean, (LPVOID) &appData.debugMode, FALSE, (ArgIniType) FALSE }, + { "debug", ArgTrue, (LPVOID) &appData.debugMode, FALSE, INVALID }, + { "xdebug", ArgFalse, (LPVOID) &appData.debugMode, FALSE, INVALID }, + { "-debug", ArgFalse, (LPVOID) &appData.debugMode, FALSE, INVALID }, + { "clockMode", ArgBoolean, (LPVOID) &appData.clockMode, FALSE, (ArgIniType) TRUE }, + { "clock", ArgTrue, (LPVOID) &appData.clockMode, FALSE, INVALID }, + { "xclock", ArgFalse, (LPVOID) &appData.clockMode, FALSE, INVALID }, + { "-clock", ArgFalse, (LPVOID) &appData.clockMode, FALSE, INVALID }, + { "searchTime", ArgString, (LPVOID) &appData.searchTime, FALSE, (ArgIniType) "" }, + { "st", ArgString, (LPVOID) &appData.searchTime, FALSE, INVALID }, + { "searchDepth", ArgInt, (LPVOID) &appData.searchDepth, FALSE, (ArgIniType) 0 }, + { "depth", ArgInt, (LPVOID) &appData.searchDepth, FALSE, INVALID }, + { "showCoords", ArgBoolean, (LPVOID) &appData.showCoords, TRUE, (ArgIniType) FALSE }, + { "coords", ArgTrue, (LPVOID) &appData.showCoords, FALSE, INVALID }, + { "xcoords", ArgFalse, (LPVOID) &appData.showCoords, FALSE, INVALID }, + { "-coords", ArgFalse, (LPVOID) &appData.showCoords, FALSE, INVALID }, + { "showThinking", ArgBoolean, (LPVOID) &appData.showThinking, TRUE, (ArgIniType) FALSE }, + { "thinking", ArgTrue, (LPVOID) &appData.showThinking, FALSE, INVALID }, + { "xthinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE, INVALID }, + { "-thinking", ArgFalse, (LPVOID) &appData.showThinking, FALSE, INVALID }, + { "ponderNextMove", ArgBoolean, (LPVOID) &appData.ponderNextMove, TRUE, (ArgIniType) TRUE }, + { "ponder", ArgTrue, (LPVOID) &appData.ponderNextMove, FALSE, INVALID }, + { "xponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE, INVALID }, + { "-ponder", ArgFalse, (LPVOID) &appData.ponderNextMove, FALSE, INVALID }, + { "periodicUpdates", ArgBoolean, (LPVOID) &appData.periodicUpdates, TRUE, (ArgIniType) TRUE }, + { "periodic", ArgTrue, (LPVOID) &appData.periodicUpdates, FALSE, INVALID }, + { "xperiodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE, INVALID }, + { "-periodic", ArgFalse, (LPVOID) &appData.periodicUpdates, FALSE, INVALID }, + { "popupExitMessage", ArgBoolean, (LPVOID) &appData.popupExitMessage, TRUE, (ArgIniType) TRUE }, + { "exit", ArgTrue, (LPVOID) &appData.popupExitMessage, FALSE, INVALID }, + { "xexit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE, INVALID }, + { "-exit", ArgFalse, (LPVOID) &appData.popupExitMessage, FALSE, INVALID }, + { "popupMoveErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, TRUE, (ArgIniType) FALSE }, + { "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE, INVALID }, + { "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE, INVALID }, + { "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE, INVALID }, { "popUpErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, - FALSE }, /* only so that old WinBoard.ini files from betas can be read */ - { "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE }, - { "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE }, - { "coordFont", ArgFont, (LPVOID) COORD_FONT, TRUE }, - { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE }, - { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE }, - { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE }, - { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */ + FALSE, INVALID }, /* only so that old WinBoard.ini files from betas can be read */ + { "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE, INVALID }, + { "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE, INVALID }, + { "coordFont", ArgFont, (LPVOID) COORD_FONT, TRUE, INVALID }, + { "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE, INVALID }, + { "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE, INVALID }, + { "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE, INVALID }, + { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE, INVALID }, /* [AS] */ { "boardSize", ArgBoardSize, (LPVOID) &boardSize, - TRUE }, /* must come after all fonts */ - { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE }, + TRUE, (ArgIniType) -1 }, /* must come after all fonts */ + { "size", ArgBoardSize, (LPVOID) &boardSize, FALSE, INVALID }, { "ringBellAfterMoves", ArgBoolean, (LPVOID) &appData.ringBellAfterMoves, - FALSE }, /* historical; kept only so old winboard.ini files will parse */ - { "alwaysOnTop", ArgBoolean, (LPVOID) &alwaysOnTop, TRUE }, - { "top", ArgTrue, (LPVOID) &alwaysOnTop, FALSE }, - { "xtop", ArgFalse, (LPVOID) &alwaysOnTop, FALSE }, - { "-top", ArgFalse, (LPVOID) &alwaysOnTop, FALSE }, - { "autoCallFlag", ArgBoolean, (LPVOID) &appData.autoCallFlag, TRUE }, - { "autoflag", ArgTrue, (LPVOID) &appData.autoCallFlag, FALSE }, - { "xautoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE }, - { "-autoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE }, - { "autoComment", ArgBoolean, (LPVOID) &appData.autoComment, TRUE }, - { "autocomm", ArgTrue, (LPVOID) &appData.autoComment, FALSE }, - { "xautocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE }, - { "-autocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE }, - { "autoObserve", ArgBoolean, (LPVOID) &appData.autoObserve, TRUE }, - { "autobs", ArgTrue, (LPVOID) &appData.autoObserve, FALSE }, - { "xautobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE }, - { "-autobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE }, - { "flipView", ArgBoolean, (LPVOID) &appData.flipView, FALSE }, - { "flip", ArgTrue, (LPVOID) &appData.flipView, FALSE }, - { "xflip", ArgFalse, (LPVOID) &appData.flipView, FALSE }, - { "-flip", ArgFalse, (LPVOID) &appData.flipView, FALSE }, - { "autoFlipView", ArgBoolean, (LPVOID) &appData.autoFlipView, TRUE }, - { "autoflip", ArgTrue, (LPVOID) &appData.autoFlipView, FALSE }, - { "xautoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE }, - { "-autoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE }, - { "autoRaiseBoard", ArgBoolean, (LPVOID) &appData.autoRaiseBoard, TRUE }, - { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE }, - { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE }, - { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE }, - { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE }, - { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, - { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, - { "-queen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE }, - { "oldSaveStyle", ArgBoolean, (LPVOID) &appData.oldSaveStyle, TRUE }, - { "oldsave", ArgTrue, (LPVOID) &appData.oldSaveStyle, FALSE }, - { "xoldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE }, - { "-oldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE }, - { "quietPlay", ArgBoolean, (LPVOID) &appData.quietPlay, TRUE }, - { "quiet", ArgTrue, (LPVOID) &appData.quietPlay, FALSE }, - { "xquiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE }, - { "-quiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE }, - { "getMoveList", ArgBoolean, (LPVOID) &appData.getMoveList, TRUE }, - { "moves", ArgTrue, (LPVOID) &appData.getMoveList, FALSE }, - { "xmoves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE }, - { "-moves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE }, - { "testLegality", ArgBoolean, (LPVOID) &appData.testLegality, TRUE }, - { "legal", ArgTrue, (LPVOID) &appData.testLegality, FALSE }, - { "xlegal", ArgFalse, (LPVOID) &appData.testLegality, FALSE }, - { "-legal", ArgFalse, (LPVOID) &appData.testLegality, FALSE }, - { "premove", ArgBoolean, (LPVOID) &appData.premove, TRUE }, - { "pre", ArgTrue, (LPVOID) &appData.premove, FALSE }, - { "xpre", ArgFalse, (LPVOID) &appData.premove, FALSE }, - { "-pre", ArgFalse, (LPVOID) &appData.premove, FALSE }, - { "premoveWhite", ArgBoolean, (LPVOID) &appData.premoveWhite, TRUE }, - { "prewhite", ArgTrue, (LPVOID) &appData.premoveWhite, FALSE }, - { "xprewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE }, - { "-prewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE }, - { "premoveWhiteText", ArgString, (LPVOID) &appData.premoveWhiteText, TRUE }, - { "premoveBlack", ArgBoolean, (LPVOID) &appData.premoveBlack, TRUE }, - { "preblack", ArgTrue, (LPVOID) &appData.premoveBlack, FALSE }, - { "xpreblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE }, - { "-preblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE }, - { "premoveBlackText", ArgString, (LPVOID) &appData.premoveBlackText, TRUE }, - { "icsAlarm", ArgBoolean, (LPVOID) &appData.icsAlarm, TRUE}, + FALSE, (ArgIniType) TRUE }, /* historical; kept only so old winboard.ini files will parse */ + { "bell", ArgTrue, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB + { "xbell", ArgFalse, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB + { "movesound", ArgTrue, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB + { "xmovesound", ArgFalse, (LPVOID) &appData.ringBellAfterMoves, FALSE, INVALID }, // for XB + { "alwaysOnTop", ArgBoolean, (LPVOID) &alwaysOnTop, TRUE, INVALID }, + { "top", ArgTrue, (LPVOID) &alwaysOnTop, FALSE, INVALID }, + { "xtop", ArgFalse, (LPVOID) &alwaysOnTop, FALSE, INVALID }, + { "-top", ArgFalse, (LPVOID) &alwaysOnTop, FALSE, INVALID }, + { "autoCallFlag", ArgBoolean, (LPVOID) &appData.autoCallFlag, TRUE, (ArgIniType) FALSE }, + { "autoflag", ArgTrue, (LPVOID) &appData.autoCallFlag, FALSE, INVALID }, + { "xautoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE, INVALID }, + { "-autoflag", ArgFalse, (LPVOID) &appData.autoCallFlag, FALSE, INVALID }, + { "autoComment", ArgBoolean, (LPVOID) &appData.autoComment, TRUE, (ArgIniType) FALSE }, + { "autocomm", ArgTrue, (LPVOID) &appData.autoComment, FALSE, INVALID }, + { "xautocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE, INVALID }, + { "-autocomm", ArgFalse, (LPVOID) &appData.autoComment, FALSE, INVALID }, + { "autoObserve", ArgBoolean, (LPVOID) &appData.autoObserve, TRUE, (ArgIniType) FALSE }, + { "autobs", ArgTrue, (LPVOID) &appData.autoObserve, FALSE, INVALID }, + { "xautobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE, INVALID }, + { "-autobs", ArgFalse, (LPVOID) &appData.autoObserve, FALSE, INVALID }, + { "flipView", ArgBoolean, (LPVOID) &appData.flipView, FALSE, (ArgIniType) FALSE }, + { "flip", ArgTrue, (LPVOID) &appData.flipView, FALSE, INVALID }, + { "xflip", ArgFalse, (LPVOID) &appData.flipView, FALSE, INVALID }, + { "-flip", ArgFalse, (LPVOID) &appData.flipView, FALSE, INVALID }, + { "autoFlipView", ArgBoolean, (LPVOID) &appData.autoFlipView, TRUE, (ArgIniType) TRUE }, + { "autoflip", ArgTrue, (LPVOID) &appData.autoFlipView, FALSE, INVALID }, + { "xautoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE, INVALID }, + { "-autoflip", ArgFalse, (LPVOID) &appData.autoFlipView, FALSE, INVALID }, + { "autoRaiseBoard", ArgBoolean, (LPVOID) &appData.autoRaiseBoard, TRUE, (ArgIniType) TRUE }, + { "autoraise", ArgTrue, (LPVOID) &appData.autoRaiseBoard, FALSE, INVALID }, + { "xautoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE, INVALID }, + { "-autoraise", ArgFalse, (LPVOID) &appData.autoRaiseBoard, FALSE, INVALID }, + { "alwaysPromoteToQueen", ArgBoolean, (LPVOID) &appData.alwaysPromoteToQueen, TRUE, (ArgIniType) FALSE }, + { "queen", ArgTrue, (LPVOID) &appData.alwaysPromoteToQueen, FALSE, INVALID }, + { "xqueen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE, INVALID }, + { "-queen", ArgFalse, (LPVOID) &appData.alwaysPromoteToQueen, FALSE, INVALID }, + { "oldSaveStyle", ArgBoolean, (LPVOID) &appData.oldSaveStyle, TRUE, (ArgIniType) FALSE }, + { "oldsave", ArgTrue, (LPVOID) &appData.oldSaveStyle, FALSE, INVALID }, + { "xoldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE, INVALID }, + { "-oldsave", ArgFalse, (LPVOID) &appData.oldSaveStyle, FALSE, INVALID }, + { "quietPlay", ArgBoolean, (LPVOID) &appData.quietPlay, TRUE, (ArgIniType) FALSE }, + { "quiet", ArgTrue, (LPVOID) &appData.quietPlay, FALSE, INVALID }, + { "xquiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE, INVALID }, + { "-quiet", ArgFalse, (LPVOID) &appData.quietPlay, FALSE, INVALID }, + { "getMoveList", ArgBoolean, (LPVOID) &appData.getMoveList, TRUE, (ArgIniType) TRUE }, + { "moves", ArgTrue, (LPVOID) &appData.getMoveList, FALSE, INVALID }, + { "xmoves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE, INVALID }, + { "-moves", ArgFalse, (LPVOID) &appData.getMoveList, FALSE, INVALID }, + { "testLegality", ArgBoolean, (LPVOID) &appData.testLegality, TRUE, (ArgIniType) TRUE }, + { "legal", ArgTrue, (LPVOID) &appData.testLegality, FALSE, INVALID }, + { "xlegal", ArgFalse, (LPVOID) &appData.testLegality, FALSE, INVALID }, + { "-legal", ArgFalse, (LPVOID) &appData.testLegality, FALSE, INVALID }, + { "premove", ArgBoolean, (LPVOID) &appData.premove, TRUE, (ArgIniType) TRUE }, + { "pre", ArgTrue, (LPVOID) &appData.premove, FALSE, INVALID }, + { "xpre", ArgFalse, (LPVOID) &appData.premove, FALSE, INVALID }, + { "-pre", ArgFalse, (LPVOID) &appData.premove, FALSE, INVALID }, + { "premoveWhite", ArgBoolean, (LPVOID) &appData.premoveWhite, TRUE, (ArgIniType) FALSE }, + { "prewhite", ArgTrue, (LPVOID) &appData.premoveWhite, FALSE, INVALID }, + { "xprewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE, INVALID }, + { "-prewhite", ArgFalse, (LPVOID) &appData.premoveWhite, FALSE, INVALID }, + { "premoveWhiteText", ArgString, (LPVOID) &appData.premoveWhiteText, TRUE, (ArgIniType) "" }, + { "premoveBlack", ArgBoolean, (LPVOID) &appData.premoveBlack, TRUE, (ArgIniType) FALSE }, + { "preblack", ArgTrue, (LPVOID) &appData.premoveBlack, FALSE, INVALID }, + { "xpreblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE, INVALID }, + { "-preblack", ArgFalse, (LPVOID) &appData.premoveBlack, FALSE, INVALID }, + { "premoveBlackText", ArgString, (LPVOID) &appData.premoveBlackText, TRUE, (ArgIniType) "" }, + { "icsAlarm", ArgBoolean, (LPVOID) &appData.icsAlarm, TRUE, (ArgIniType) TRUE}, { "alarm", ArgTrue, (LPVOID) &appData.icsAlarm, FALSE}, { "xalarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE}, { "-alarm", ArgFalse, (LPVOID) &appData.icsAlarm, FALSE}, - { "icsAlarmTime", ArgInt, (LPVOID) &appData.icsAlarmTime, TRUE}, - { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE}, - { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE}, - { "edit", ArgTrue, (LPVOID) &appData.localLineEditing, FALSE }, - { "xedit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE }, - { "-edit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE }, - { "animateMoving", ArgBoolean, (LPVOID) &appData.animate, TRUE }, - { "animate", ArgTrue, (LPVOID) &appData.animate, FALSE }, - { "xanimate", ArgFalse, (LPVOID) &appData.animate, FALSE }, - { "-animate", ArgFalse, (LPVOID) &appData.animate, FALSE }, - { "animateSpeed", ArgInt, (LPVOID) &appData.animSpeed, TRUE }, - { "animateDragging", ArgBoolean, (LPVOID) &appData.animateDragging, TRUE }, - { "drag", ArgTrue, (LPVOID) &appData.animateDragging, FALSE }, - { "xdrag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE }, - { "-drag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE }, - { "blindfold", ArgBoolean, (LPVOID) &appData.blindfold, TRUE }, - { "blind", ArgTrue, (LPVOID) &appData.blindfold, FALSE }, - { "xblind", ArgFalse, (LPVOID) &appData.blindfold, FALSE }, - { "-blind", ArgFalse, (LPVOID) &appData.blindfold, FALSE }, + { "icsAlarmTime", ArgInt, (LPVOID) &appData.icsAlarmTime, TRUE, (ArgIniType) 5000}, + { "localLineEditing", ArgBoolean, (LPVOID) &appData.localLineEditing, FALSE, (ArgIniType) TRUE}, + { "edit", ArgTrue, (LPVOID) &appData.localLineEditing, FALSE, INVALID }, + { "xedit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE, INVALID }, + { "-edit", ArgFalse, (LPVOID) &appData.localLineEditing, FALSE, INVALID }, + { "animateMoving", ArgBoolean, (LPVOID) &appData.animate, TRUE, (ArgIniType) TRUE }, + { "animate", ArgTrue, (LPVOID) &appData.animate, FALSE, INVALID }, + { "xanimate", ArgFalse, (LPVOID) &appData.animate, FALSE, INVALID }, + { "-animate", ArgFalse, (LPVOID) &appData.animate, FALSE, INVALID }, + { "animateSpeed", ArgInt, (LPVOID) &appData.animSpeed, TRUE, (ArgIniType) 10 }, + { "animateDragging", ArgBoolean, (LPVOID) &appData.animateDragging, TRUE, (ArgIniType) TRUE }, + { "drag", ArgTrue, (LPVOID) &appData.animateDragging, FALSE, INVALID }, + { "xdrag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE, INVALID }, + { "-drag", ArgFalse, (LPVOID) &appData.animateDragging, FALSE, INVALID }, + { "blindfold", ArgBoolean, (LPVOID) &appData.blindfold, TRUE, (ArgIniType) FALSE }, + { "blind", ArgTrue, (LPVOID) &appData.blindfold, FALSE, INVALID }, + { "xblind", ArgFalse, (LPVOID) &appData.blindfold, FALSE, INVALID }, + { "-blind", ArgFalse, (LPVOID) &appData.blindfold, FALSE, INVALID }, { "highlightLastMove", ArgBoolean, - (LPVOID) &appData.highlightLastMove, TRUE }, - { "highlight", ArgTrue, (LPVOID) &appData.highlightLastMove, FALSE }, - { "xhighlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE }, - { "-highlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE }, + (LPVOID) &appData.highlightLastMove, TRUE, (ArgIniType) TRUE }, + { "highlight", ArgTrue, (LPVOID) &appData.highlightLastMove, FALSE, INVALID }, + { "xhighlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE, INVALID }, + { "-highlight", ArgFalse, (LPVOID) &appData.highlightLastMove, FALSE, INVALID }, { "highlightDragging", ArgBoolean, - (LPVOID) &appData.highlightDragging, TRUE }, - { "highdrag", ArgTrue, (LPVOID) &appData.highlightDragging, FALSE }, - { "xhighdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE }, - { "-highdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE }, - { "colorizeMessages", ArgBoolean, (LPVOID) &appData.colorize, TRUE }, - { "colorize", ArgTrue, (LPVOID) &appData.colorize, FALSE }, - { "xcolorize", ArgFalse, (LPVOID) &appData.colorize, FALSE }, - { "-colorize", ArgFalse, (LPVOID) &appData.colorize, FALSE }, - { "colorShout", ArgAttribs, (LPVOID) ColorShout, TRUE }, - { "colorSShout", ArgAttribs, (LPVOID) ColorSShout, TRUE }, - { "colorChannel1", ArgAttribs, (LPVOID) ColorChannel1, TRUE }, - { "colorChannel", ArgAttribs, (LPVOID) ColorChannel, TRUE }, - { "colorKibitz", ArgAttribs, (LPVOID) ColorKibitz, TRUE }, - { "colorTell", ArgAttribs, (LPVOID) ColorTell, TRUE }, - { "colorChallenge", ArgAttribs, (LPVOID) ColorChallenge, TRUE }, - { "colorRequest", ArgAttribs, (LPVOID) ColorRequest, TRUE }, - { "colorSeek", ArgAttribs, (LPVOID) ColorSeek, TRUE }, - { "colorNormal", ArgAttribs, (LPVOID) ColorNormal, TRUE }, - { "colorBackground", ArgColor, (LPVOID) &consoleBackgroundColor, TRUE }, - { "soundShout", ArgFilename, - (LPVOID) &textAttribs[ColorShout].sound.name, TRUE }, - { "soundSShout", ArgFilename, - (LPVOID) &textAttribs[ColorSShout].sound.name, TRUE }, - { "soundChannel1", ArgFilename, - (LPVOID) &textAttribs[ColorChannel1].sound.name, TRUE }, - { "soundChannel", ArgFilename, - (LPVOID) &textAttribs[ColorChannel].sound.name, TRUE }, - { "soundKibitz", ArgFilename, - (LPVOID) &textAttribs[ColorKibitz].sound.name, TRUE }, - { "soundTell", ArgFilename, - (LPVOID) &textAttribs[ColorTell].sound.name, TRUE }, - { "soundChallenge", ArgFilename, - (LPVOID) &textAttribs[ColorChallenge].sound.name, TRUE }, - { "soundRequest", ArgFilename, - (LPVOID) &textAttribs[ColorRequest].sound.name, TRUE }, - { "soundSeek", ArgFilename, - (LPVOID) &textAttribs[ColorSeek].sound.name, TRUE }, - { "soundMove", ArgFilename, (LPVOID) &sounds[(int)SoundMove].name, TRUE }, - { "soundBell", ArgFilename, (LPVOID) &sounds[(int)SoundBell].name, TRUE }, - { "soundIcsWin", ArgFilename, (LPVOID) &sounds[(int)SoundIcsWin].name,TRUE }, - { "soundIcsLoss", ArgFilename, - (LPVOID) &sounds[(int)SoundIcsLoss].name, TRUE }, - { "soundIcsDraw", ArgFilename, - (LPVOID) &sounds[(int)SoundIcsDraw].name, TRUE }, - { "soundIcsUnfinished", ArgFilename, - (LPVOID) &sounds[(int)SoundIcsUnfinished].name, TRUE}, - { "soundIcsAlarm", ArgFilename, - (LPVOID) &sounds[(int)SoundAlarm].name, TRUE }, - { "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE }, - { "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE }, - { "xreuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE }, - { "-reuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE }, + (LPVOID) &appData.highlightDragging, TRUE, INVALID }, + { "highdrag", ArgTrue, (LPVOID) &appData.highlightDragging, FALSE, INVALID }, + { "xhighdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE, INVALID }, + { "-highdrag", ArgFalse, (LPVOID) &appData.highlightDragging, FALSE, INVALID }, + { "colorizeMessages", ArgBoolean, (LPVOID) &appData.colorize, TRUE, (ArgIniType) TRUE }, + { "colorize", ArgTrue, (LPVOID) &appData.colorize, FALSE, INVALID }, + { "xcolorize", ArgFalse, (LPVOID) &appData.colorize, FALSE, INVALID }, + { "-colorize", ArgFalse, (LPVOID) &appData.colorize, FALSE, INVALID }, + { "colorShout", ArgAttribs, (LPVOID) ColorShout, TRUE, INVALID }, + { "colorSShout", ArgAttribs, (LPVOID) ColorSShout, TRUE, INVALID }, + { "colorChannel1", ArgAttribs, (LPVOID) ColorChannel1, TRUE, INVALID }, + { "colorChannel", ArgAttribs, (LPVOID) ColorChannel, TRUE, INVALID }, + { "colorKibitz", ArgAttribs, (LPVOID) ColorKibitz, TRUE, INVALID }, + { "colorTell", ArgAttribs, (LPVOID) ColorTell, TRUE, INVALID }, + { "colorChallenge", ArgAttribs, (LPVOID) ColorChallenge, TRUE, INVALID }, + { "colorRequest", ArgAttribs, (LPVOID) ColorRequest, TRUE, INVALID }, + { "colorSeek", ArgAttribs, (LPVOID) ColorSeek, TRUE, INVALID }, + { "colorNormal", ArgAttribs, (LPVOID) ColorNormal, TRUE, INVALID }, + { "colorBackground", ArgColor, (LPVOID) &consoleBackgroundColor, TRUE, INVALID }, + { "soundShout", ArgFilename, (LPVOID) &appData.soundShout, TRUE, (ArgIniType) "" }, + { "soundSShout", ArgFilename, (LPVOID) &appData.soundSShout, TRUE, (ArgIniType) "" }, + { "soundCShout", ArgFilename, (LPVOID) &appData.soundSShout, TRUE, (ArgIniType) "" }, // for XB + { "soundChannel1", ArgFilename, (LPVOID) &appData.soundChannel1, TRUE, (ArgIniType) "" }, + { "soundChannel", ArgFilename, (LPVOID) &appData.soundChannel, TRUE, (ArgIniType) "" }, + { "soundKibitz", ArgFilename, (LPVOID) &appData.soundKibitz, TRUE, (ArgIniType) "" }, + { "soundTell", ArgFilename, (LPVOID) &appData.soundTell, TRUE, (ArgIniType) "" }, + { "soundChallenge", ArgFilename, (LPVOID) &appData.soundChallenge, TRUE, (ArgIniType) "" }, + { "soundRequest", ArgFilename, (LPVOID) &appData.soundRequest, TRUE, (ArgIniType) "" }, + { "soundSeek", ArgFilename, (LPVOID) &appData.soundSeek, TRUE, (ArgIniType) "" }, + { "soundMove", ArgFilename, (LPVOID) &appData.soundMove, TRUE, (ArgIniType) "" }, + { "soundBell", ArgFilename, (LPVOID) &appData.soundBell, TRUE, (ArgIniType) SOUND_BELL }, + { "soundIcsWin", ArgFilename, (LPVOID) &appData.soundIcsWin, TRUE, (ArgIniType) "" }, + { "soundIcsLoss", ArgFilename, (LPVOID) &appData.soundIcsLoss, TRUE, (ArgIniType) "" }, + { "soundIcsDraw", ArgFilename, (LPVOID) &appData.soundIcsDraw, TRUE, (ArgIniType) "" }, + { "soundIcsUnfinished", ArgFilename, (LPVOID) &appData.soundIcsUnfinished, TRUE, (ArgIniType) "" }, + { "soundIcsAlarm", ArgFilename, (LPVOID) &appData.soundIcsAlarm, TRUE, (ArgIniType) "" }, + { "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE, (ArgIniType) TRUE }, + { "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE, INVALID }, + { "xreuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE, INVALID }, + { "-reuse", ArgFalse, (LPVOID) &appData.reuseFirst, FALSE, INVALID }, { "reuseChessPrograms", ArgBoolean, - (LPVOID) &appData.reuseFirst, FALSE }, /* backward compat only */ - { "reuseSecond", ArgBoolean, (LPVOID) &appData.reuseSecond, FALSE }, - { "reuse2", ArgTrue, (LPVOID) &appData.reuseSecond, FALSE }, - { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE }, - { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE }, - { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE }, - { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE }, - { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE }, - { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE }, - { "chessProgram", ArgBoolean, (LPVOID) &chessProgram, FALSE }, - { "cp", ArgTrue, (LPVOID) &chessProgram, FALSE }, - { "xcp", ArgFalse, (LPVOID) &chessProgram, FALSE }, - { "-cp", ArgFalse, (LPVOID) &chessProgram, FALSE }, - { "icsMenu", ArgString, (LPVOID) &icsTextMenuString, TRUE }, - { "icsNames", ArgString, (LPVOID) &icsNames, TRUE }, + (LPVOID) &appData.reuseFirst, FALSE, INVALID }, /* backward compat only */ + { "reuseSecond", ArgBoolean, (LPVOID) &appData.reuseSecond, FALSE, (ArgIniType) TRUE }, + { "reuse2", ArgTrue, (LPVOID) &appData.reuseSecond, FALSE, INVALID }, + { "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE, INVALID }, + { "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE, INVALID }, + { "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE, INVALID }, + { "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE, (ArgIniType) SETTINGS_FILE }, + { "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE, INVALID }, + { "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE, (ArgIniType) TRUE }, + { "chessProgram", ArgBoolean, (LPVOID) &chessProgram, FALSE, (ArgIniType) FALSE }, + { "cp", ArgTrue, (LPVOID) &chessProgram, FALSE, INVALID }, + { "xcp", ArgFalse, (LPVOID) &chessProgram, FALSE, INVALID }, + { "-cp", ArgFalse, (LPVOID) &chessProgram, FALSE, INVALID }, + { "icsMenu", ArgString, (LPVOID) &icsTextMenuString, TRUE, (ArgIniType) ICS_TEXT_MENU_DEFAULT }, + { "icsNames", ArgString, (LPVOID) &icsNames, TRUE, (ArgIniType) ICS_NAMES }, { "firstChessProgramNames", ArgString, (LPVOID) &firstChessProgramNames, - TRUE }, + TRUE, (ArgIniType) FCP_NAMES }, { "secondChessProgramNames", ArgString, (LPVOID) &secondChessProgramNames, - TRUE }, - { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE }, - { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE }, - { "variant", ArgString, (LPVOID) &appData.variant, FALSE }, - { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE }, - { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE }, - { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE }, - { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE }, - { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE }, - { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE }, + TRUE, (ArgIniType) SCP_NAMES }, + { "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE, (ArgIniType) "" }, + { "mode", ArgString, (LPVOID) &appData.initialMode, FALSE, INVALID }, + { "variant", ArgString, (LPVOID) &appData.variant, FALSE, (ArgIniType) "normal" }, + { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE, (ArgIniType) PROTOVER }, + { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE, (ArgIniType) PROTOVER }, + { "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE, (ArgIniType) TRUE }, + { "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE, INVALID }, + { "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE, INVALID }, + { "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE, INVALID }, + /* [AS] New features */ - { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE }, - { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE }, - { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE }, - { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE }, - { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE }, - { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE }, - { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE }, - { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE }, - { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE }, - { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE }, - { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE }, - { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE }, - { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE }, - { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE }, - { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE }, - { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE }, - { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE }, - { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE }, - { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE }, - { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE }, - { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE }, - { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE }, - { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE }, - { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE }, - { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE }, - { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE }, - { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE }, - { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE }, - { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE }, - { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE }, - { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE }, - { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE }, - { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE }, - { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE }, - { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE }, - { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE }, - { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE }, - { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE }, - { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE }, - { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE }, - { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE }, - { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE }, - { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE }, - { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE }, - { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE }, - { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE }, - { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE }, - { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE }, - { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE }, - { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE }, + { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE, (ArgIniType) FALSE }, + { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE, (ArgIniType) FALSE }, + { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE, (ArgIniType) FALSE }, + { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE, (ArgIniType) FALSE }, + { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE, (ArgIniType) "" }, + { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE, (ArgIniType) "" }, + { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE, (ArgIniType) BACK_TEXTURE_MODE_PLAIN }, + { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE, (ArgIniType) BACK_TEXTURE_MODE_PLAIN }, + { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE, (ArgIniType) "" }, + { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE, (ArgIniType) "" }, + { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE, (ArgIniType) 0 }, + { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE, (ArgIniType) 0 }, + { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE, (ArgIniType) 0 }, + { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE, (ArgIniType) 0 }, + { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE, (ArgIniType) 80 }, + { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE, (ArgIniType) 1 }, + { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE, (ArgIniType) 0 }, + { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE, (ArgIniType) 0 }, + { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE, (ArgIniType) 0 }, + { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE, (ArgIniType) "winboard.debug" }, + { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE, INVALID }, + { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE, (ArgIniType) "Computer Chess Game" }, + { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE, (ArgIniType) -1 }, + { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE, (ArgIniType) GLT_DEFAULT_TAGS }, + { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE, (ArgIniType) TRUE }, + { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE, (ArgIniType) TRUE }, + { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE, INVALID }, + { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE, INVALID }, + { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE, (ArgIniType) FALSE }, + { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE, INVALID }, + { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE, (ArgIniType) TRUE }, + { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE, (ArgIniType) TRUE }, + { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE, (ArgIniType) TRUE }, + { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE, (ArgIniType) TRUE }, + { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE, (ArgIniType) FALSE }, + { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE, INVALID }, + { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE, (ArgIniType) FALSE }, + { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE, INVALID }, + { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE, (ArgIniType) TRUE }, + { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE, INVALID }, + { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE, INVALID }, + { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE, (ArgIniType) TRUE }, + { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE, INVALID }, + { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE, INVALID }, + { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE, (ArgIniType) "" }, + { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE, (ArgIniType) FALSE }, + { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE, (ArgIniType) "" }, + { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE, (ArgIniType) 64 }, + { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE, (ArgIniType) 4 }, + { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE, (ArgIniType) "c:\\egtb" }, /* [HGM] board-size, adjudication and misc. options */ - { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE }, - { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE }, - { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE }, - { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE }, - { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE }, - { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE }, - { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE }, - { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE }, - { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE }, - { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE }, - { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE }, - { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE }, - { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE }, - { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE }, - { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE }, - { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE }, - { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE }, - { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE }, - { "userName", ArgString, (LPVOID) &appData.userName, FALSE }, - { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE }, - { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE }, - { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE }, - { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE }, - { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE }, - { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE }, - { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE }, - { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE }, - { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE }, - { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE }, - { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE }, - { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE }, - { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE }, - { "icstype", ArgInt, (LPVOID) &ics_type, FALSE }, - { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE }, + { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE, (ArgIniType) -1 }, + { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE, (ArgIniType) -1 }, + { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE, (ArgIniType) -1 }, + { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE, (ArgIniType) 10000 }, + { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE, INVALID }, + { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE, (ArgIniType) FALSE }, + { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE, (ArgIniType) FALSE }, + { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE, (ArgIniType) FALSE }, + { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE, (ArgIniType) FALSE }, + { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE, (ArgIniType) FALSE }, + { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE, (ArgIniType) FALSE }, + { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE, (ArgIniType) FALSE }, + { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE, (ArgIniType) FALSE }, + { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE, (ArgIniType) FALSE }, + { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE, (ArgIniType) 51 }, + { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE, (ArgIniType) 6 }, + { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE, INVALID }, + { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE, (ArgIniType) 1 }, + { "userName", ArgString, (LPVOID) &appData.userName, FALSE, INVALID }, + { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE, INVALID }, + { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE, INVALID }, + { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE, (ArgIniType) 1 }, + { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE, (ArgIniType) "" }, + { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE, INVALID }, + { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE, INVALID }, + { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE, INVALID }, + { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE, INVALID }, + { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE, (ArgIniType) "" }, + { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE, (ArgIniType) "" }, + { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE, (ArgIniType) "" }, + { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE, (ArgIniType) "" }, + { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE, INVALID }, + { "icstype", ArgInt, (LPVOID) &ics_type, FALSE, INVALID }, + { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE, INVALID }, #ifdef ZIPPY - { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE }, - { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE }, - { "xzt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE }, - { "-zt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE }, - { "zippyPlay", ArgBoolean, (LPVOID) &appData.zippyPlay, FALSE }, - { "zp", ArgTrue, (LPVOID) &appData.zippyPlay, FALSE }, - { "xzp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE }, - { "-zp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE }, - { "zippyLines", ArgFilename, (LPVOID) &appData.zippyLines, FALSE }, - { "zippyPinhead", ArgString, (LPVOID) &appData.zippyPinhead, FALSE }, - { "zippyPassword", ArgString, (LPVOID) &appData.zippyPassword, FALSE }, - { "zippyPassword2", ArgString, (LPVOID) &appData.zippyPassword2, FALSE }, + { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE, (ArgIniType) ZIPPY_TALK }, + { "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE, INVALID }, + { "xzt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE, INVALID }, + { "-zt", ArgFalse, (LPVOID) &appData.zippyTalk, FALSE, INVALID }, + { "zippyPlay", ArgBoolean, (LPVOID) &appData.zippyPlay, FALSE, (ArgIniType) ZIPPY_PLAY }, + { "zp", ArgTrue, (LPVOID) &appData.zippyPlay, FALSE, INVALID }, + { "xzp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE, INVALID }, + { "-zp", ArgFalse, (LPVOID) &appData.zippyPlay, FALSE, INVALID }, + { "zippyLines", ArgFilename, (LPVOID) &appData.zippyLines, FALSE, (ArgIniType) ZIPPY_LINES }, + { "zippyPinhead", ArgString, (LPVOID) &appData.zippyPinhead, FALSE, (ArgIniType) ZIPPY_PINHEAD }, + { "zippyPassword", ArgString, (LPVOID) &appData.zippyPassword, FALSE, (ArgIniType) ZIPPY_PASSWORD }, + { "zippyPassword2", ArgString, (LPVOID) &appData.zippyPassword2, FALSE, (ArgIniType) ZIPPY_PASSWORD2 }, { "zippyWrongPassword", ArgString, (LPVOID) &appData.zippyWrongPassword, - FALSE }, - { "zippyAcceptOnly", ArgString, (LPVOID) &appData.zippyAcceptOnly, FALSE }, - { "zippyUseI", ArgBoolean, (LPVOID) &appData.zippyUseI, FALSE }, - { "zui", ArgTrue, (LPVOID) &appData.zippyUseI, FALSE }, - { "xzui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE }, - { "-zui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE }, - { "zippyBughouse", ArgInt, (LPVOID) &appData.zippyBughouse, FALSE }, + FALSE, (ArgIniType) ZIPPY_WRONG_PASSWORD }, + { "zippyAcceptOnly", ArgString, (LPVOID) &appData.zippyAcceptOnly, FALSE, (ArgIniType) ZIPPY_ACCEPT_ONLY }, + { "zippyUseI", ArgBoolean, (LPVOID) &appData.zippyUseI, FALSE, (ArgIniType) ZIPPY_USE_I }, + { "zui", ArgTrue, (LPVOID) &appData.zippyUseI, FALSE, INVALID }, + { "xzui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE, INVALID }, + { "-zui", ArgFalse, (LPVOID) &appData.zippyUseI, FALSE, INVALID }, + { "zippyBughouse", ArgInt, (LPVOID) &appData.zippyBughouse, FALSE, (ArgIniType) ZIPPY_BUGHOUSE }, { "zippyNoplayCrafty", ArgBoolean, (LPVOID) &appData.zippyNoplayCrafty, - FALSE }, - { "znc", ArgTrue, (LPVOID) &appData.zippyNoplayCrafty, FALSE }, - { "xznc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE }, - { "-znc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE }, - { "zippyGameEnd", ArgString, (LPVOID) &appData.zippyGameEnd, FALSE }, - { "zippyGameStart", ArgString, (LPVOID) &appData.zippyGameStart, FALSE }, - { "zippyAdjourn", ArgBoolean, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "zadj", ArgTrue, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "xzadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "-zadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE }, - { "zippyAbort", ArgBoolean, (LPVOID) &appData.zippyAbort, FALSE }, - { "zab", ArgTrue, (LPVOID) &appData.zippyAbort, FALSE }, - { "xzab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE }, - { "-zab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE }, - { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE }, - { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE }, - { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE }, - { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE }, + FALSE, (ArgIniType) ZIPPY_NOPLAY_CRAFTY }, + { "znc", ArgTrue, (LPVOID) &appData.zippyNoplayCrafty, FALSE, INVALID }, + { "xznc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE, INVALID }, + { "-znc", ArgFalse, (LPVOID) &appData.zippyNoplayCrafty, FALSE, INVALID }, + { "zippyGameEnd", ArgString, (LPVOID) &appData.zippyGameEnd, FALSE, (ArgIniType) ZIPPY_GAME_END }, + { "zippyGameStart", ArgString, (LPVOID) &appData.zippyGameStart, FALSE, (ArgIniType) ZIPPY_GAME_START }, + { "zippyAdjourn", ArgBoolean, (LPVOID) &appData.zippyAdjourn, FALSE, (ArgIniType) ZIPPY_ADJOURN }, + { "zadj", ArgTrue, (LPVOID) &appData.zippyAdjourn, FALSE, INVALID }, + { "xzadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE, INVALID }, + { "-zadj", ArgFalse, (LPVOID) &appData.zippyAdjourn, FALSE, INVALID }, + { "zippyAbort", ArgBoolean, (LPVOID) &appData.zippyAbort, FALSE, (ArgIniType) ZIPPY_ABORT }, + { "zab", ArgTrue, (LPVOID) &appData.zippyAbort, FALSE, INVALID }, + { "xzab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE, INVALID }, + { "-zab", ArgFalse, (LPVOID) &appData.zippyAbort, FALSE, INVALID }, + { "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE, (ArgIniType) ZIPPY_VARIANTS }, + { "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE, (ArgIniType) ZIPPY_MAX_GAMES}, + { "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE, (ArgIniType) ZIPPY_REPLAY_TIMEOUT }, + { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE, INVALID }, /* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */ - { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE }, + { "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE, INVALID }, #endif /* [HGM] options for broadcasting and time odds */ - { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE }, - { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE }, - { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE }, - { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE }, - { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE }, - { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE }, - { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE }, - { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE }, - { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE }, - { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE }, - { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE }, - { "keepLineBreaksICS", ArgBoolean, (LPVOID) &appData.noJoin, TRUE }, - { "wrapContinuationSequence", ArgString, (LPVOID) &appData.wrapContSeq, FALSE }, - { "useInternalWrap", ArgTrue, (LPVOID) &appData.useInternalWrap, FALSE }, /* noJoin usurps this if set */ + { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE, (ArgIniType) NULL }, + { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE, (ArgIniType) FALSE }, + { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE, (ArgIniType) 15 }, + { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE, (ArgIniType) 1 }, + { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE, (ArgIniType) 1 }, + { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE, INVALID }, + { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE, (ArgIniType) 1 }, + { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE, (ArgIniType) 1 }, + { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE, (ArgIniType) -1 }, + { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE, (ArgIniType) -1 }, + { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE, INVALID }, + { "keepLineBreaksICS", ArgBoolean, (LPVOID) &appData.noJoin, TRUE, INVALID }, + { "wrapContinuationSequence", ArgString, (LPVOID) &appData.wrapContSeq, FALSE, INVALID }, + { "useInternalWrap", ArgTrue, (LPVOID) &appData.useInternalWrap, FALSE, INVALID }, /* noJoin usurps this if set */ // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others - { "minX", ArgZ, (LPVOID) &minX, FALSE }, // [HGM] placement: to make suer auxialary windows can be placed - { "minY", ArgZ, (LPVOID) &minY, FALSE }, - { "winWidth", ArgInt, (LPVOID) &winWidth, TRUE }, // [HGM] placement: dummies to remember right & bottom - { "winHeight", ArgInt, (LPVOID) &winHeight, TRUE }, // for attaching auxiliary windows to them - { "x", ArgInt, (LPVOID) &boardX, TRUE }, - { "y", ArgInt, (LPVOID) &boardY, TRUE }, - { "icsX", ArgX, (LPVOID) &wpConsole.x, TRUE }, - { "icsY", ArgY, (LPVOID) &wpConsole.y, TRUE }, - { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE }, - { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE }, - { "analysisX", ArgX, (LPVOID) &analysisX, FALSE }, // [HGM] placement: analysis window no longer exists - { "analysisY", ArgY, (LPVOID) &analysisY, FALSE }, // provided for compatibility with old ini files - { "analysisW", ArgInt, (LPVOID) &analysisW, FALSE }, - { "analysisH", ArgInt, (LPVOID) &analysisH, FALSE }, - { "commentX", ArgX, (LPVOID) &commentX, TRUE }, - { "commentY", ArgY, (LPVOID) &commentY, TRUE }, - { "commentW", ArgInt, (LPVOID) &commentW, TRUE }, - { "commentH", ArgInt, (LPVOID) &commentH, TRUE }, - { "tagsX", ArgX, (LPVOID) &editTagsX, TRUE }, - { "tagsY", ArgY, (LPVOID) &editTagsY, TRUE }, - { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE }, - { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE }, - { "gameListX", ArgX, (LPVOID) &wpGameList.x, TRUE }, - { "gameListY", ArgY, (LPVOID) &wpGameList.y, TRUE }, - { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE }, - { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE }, + { "minX", ArgZ, (LPVOID) &minX, FALSE, INVALID }, // [HGM] placement: to make suer auxialary windows can be placed + { "minY", ArgZ, (LPVOID) &minY, FALSE, INVALID }, + { "winWidth", ArgInt, (LPVOID) &wpMain.width, TRUE, INVALID }, // [HGM] placement: dummies to remember right & bottom + { "winHeight", ArgInt, (LPVOID) &wpMain.height, TRUE, INVALID }, // for attaching auxiliary windows to them + { "x", ArgInt, (LPVOID) &wpMain.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "y", ArgInt, (LPVOID) &wpMain.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "icsX", ArgX, (LPVOID) &wpConsole.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "icsY", ArgY, (LPVOID) &wpConsole.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "analysisX", ArgX, (LPVOID) &dummy, FALSE, INVALID }, // [HGM] placement: analysis window no longer exists + { "analysisY", ArgY, (LPVOID) &dummy, FALSE, INVALID }, // provided for compatibility with old ini files + { "analysisW", ArgInt, (LPVOID) &dummy, FALSE, INVALID }, + { "analysisH", ArgInt, (LPVOID) &dummy, FALSE, INVALID }, + { "commentX", ArgX, (LPVOID) &wpComment.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "commentY", ArgY, (LPVOID) &wpComment.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "commentW", ArgInt, (LPVOID) &wpComment.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "commentH", ArgInt, (LPVOID) &wpComment.height, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "tagsX", ArgX, (LPVOID) &wpTags.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "tagsY", ArgY, (LPVOID) &wpTags.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "tagsW", ArgInt, (LPVOID) &wpTags.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "tagsH", ArgInt, (LPVOID) &wpTags.height, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "gameListX", ArgX, (LPVOID) &wpGameList.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "gameListY", ArgY, (LPVOID) &wpGameList.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE, (ArgIniType) CW_USEDEFAULT }, /* [AS] Layout stuff */ - { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE }, - { "moveHistoryX", ArgX, (LPVOID) &wpMoveHistory.x, TRUE }, - { "moveHistoryY", ArgY, (LPVOID) &wpMoveHistory.y, TRUE }, - { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE }, - { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE }, - - { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE }, - { "evalGraphX", ArgX, (LPVOID) &wpEvalGraph.x, TRUE }, - { "evalGraphY", ArgY, (LPVOID) &wpEvalGraph.y, TRUE }, - { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE }, - { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE }, - - { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE }, - { "engineOutputX", ArgX, (LPVOID) &wpEngineOutput.x, TRUE }, - { "engineOutputY", ArgY, (LPVOID) &wpEngineOutput.y, TRUE }, - { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE }, - { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE }, - - { NULL, ArgNone, NULL, FALSE } + { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE, (ArgIniType) TRUE }, + { "moveHistoryX", ArgX, (LPVOID) &wpMoveHistory.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "moveHistoryY", ArgY, (LPVOID) &wpMoveHistory.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE, (ArgIniType) CW_USEDEFAULT }, + + { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE, (ArgIniType) TRUE }, + { "evalGraphX", ArgX, (LPVOID) &wpEvalGraph.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "evalGraphY", ArgY, (LPVOID) &wpEvalGraph.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE, (ArgIniType) CW_USEDEFAULT }, + + { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE, (ArgIniType) TRUE }, + { "engineOutputX", ArgX, (LPVOID) &wpEngineOutput.x, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "engineOutputY", ArgY, (LPVOID) &wpEngineOutput.y, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE, (ArgIniType) CW_USEDEFAULT }, + { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE, (ArgIniType) CW_USEDEFAULT }, + + { NULL, ArgNone, NULL, FALSE, INVALID } }; @@ -1777,16 +1779,16 @@ ParseArgs(GetFunc get, void *cl) break; case ArgX: - *(int *) ad->argLoc = atoi(argValue) + boardX; // [HGM] placement: translate stored relative to absolute + *(int *) ad->argLoc = atoi(argValue) + wpMain.x; // [HGM] placement: translate stored relative to absolute break; case ArgY: - *(int *) ad->argLoc = atoi(argValue) + boardY; // (this is really kludgey, it should be done where used...) + *(int *) ad->argLoc = atoi(argValue) + wpMain.y; // (this is really kludgey, it should be done where used...) break; case ArgZ: *(int *) ad->argLoc = atoi(argValue); - EnsureOnScreen(&boardX, &boardY, minX, minY); + EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY); break; case ArgFloat: @@ -1903,33 +1905,64 @@ SetDefaultTextAttribs() VOID SetDefaultSounds() -{ +{ // [HGM] only sounds for which no option exists ColorClass cc; - SoundClass sc; - for (cc = (ColorClass)0; cc < NColorClasses; cc++) { + for (cc = ColorNormal; cc < NColorClasses; cc++) { textAttribs[cc].sound.name = strdup(""); textAttribs[cc].sound.data = NULL; } - for (sc = (SoundClass)0; sc < NSoundClasses; sc++) { - sounds[sc].name = strdup(""); - sounds[sc].data = NULL; - } - sounds[(int)SoundBell].name = strdup(SOUND_BELL); } VOID LoadAllSounds() -{ +{ // [HGM] import name from appData first ColorClass cc; SoundClass sc; - for (cc = (ColorClass)0; cc < NColorClasses; cc++) { + for (cc = (ColorClass)0; cc < ColorNormal; cc++) { + textAttribs[cc].sound.name = strdup((&appData.soundShout)[cc]); + textAttribs[cc].sound.data = NULL; MyLoadSound(&textAttribs[cc].sound); } for (sc = (SoundClass)0; sc < NSoundClasses; sc++) { + sounds[sc].name = strdup((&appData.soundMove)[sc]); + sounds[sc].data = NULL; MyLoadSound(&sounds[sc]); } } +void +SetDefaultsFromList() +{ // [HGM] ini: take defaults from argDescriptor list + int i; + + for(i=0; argDescriptors[i].argName != NULL; i++) { + if(argDescriptors[i].defaultValue != INVALID) + switch(argDescriptors[i].argType) { + case ArgBoolean: + case ArgTrue: + case ArgFalse: + *(Boolean *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue; + break; + case ArgInt: + case ArgX: + case ArgY: + case ArgZ: + *(int *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue; + break; + case ArgString: + case ArgFilename: + case ArgSettingsFilename: + *(char **) argDescriptors[i].argLoc = (char *)argDescriptors[i].defaultValue; + break; + case ArgBoardSize: + *(BoardSize *) argDescriptors[i].argLoc = (BoardSize)argDescriptors[i].defaultValue; + break; + case ArgFloat: // floats cannot be casted to int without precision loss + default: ; // some arg types cannot be initialized through table + } + } +} + VOID InitAppData(LPSTR lpCmdLine) { @@ -1940,6 +1973,18 @@ InitAppData(LPSTR lpCmdLine) programName = szAppName; /* Initialize to defaults */ + SetDefaultsFromList(); // this sets most defaults + + // some parameters for which there are no options! + appData.Iconic = FALSE; /*unused*/ + appData.cmailGameName = ""; + appData.icsEngineAnalyze = FALSE; + + // float: casting to int is not harmless, so default cannot be contained in table + appData.timeDelay = TIME_DELAY; + + // colors have platform-dependent option format and internal representation + // their setting and parsing must remain in front-end lightSquareColor = ParseColorName(LIGHT_SQUARE_COLOR); darkSquareColor = ParseColorName(DARK_SQUARE_COLOR); whitePieceColor = ParseColorName(WHITE_PIECE_COLOR); @@ -1947,89 +1992,15 @@ InitAppData(LPSTR lpCmdLine) highlightSquareColor = ParseColorName(HIGHLIGHT_SQUARE_COLOR); premoveHighlightColor = ParseColorName(PREMOVE_HIGHLIGHT_COLOR); consoleBackgroundColor = ParseColorName(COLOR_BKGD); + // the following must be moved out of appData to front-end variables + appData.evalHistColorWhite = ParseColorName( "#FFFFB0" ); + appData.evalHistColorBlack = ParseColorName( "#AD5D3D" ); + appData.highlightArrowColor = ParseColorName( "#FFFF80" ); + + // some complex, platform-dependent stuff SetDefaultTextAttribs(); SetDefaultSounds(); - appData.movesPerSession = MOVES_PER_SESSION; - appData.initString = INIT_STRING; - appData.secondInitString = INIT_STRING; - appData.firstComputerString = COMPUTER_STRING; - appData.secondComputerString = COMPUTER_STRING; - appData.firstChessProgram = FIRST_CHESS_PROGRAM; - appData.secondChessProgram = SECOND_CHESS_PROGRAM; - appData.firstPlaysBlack = FALSE; - appData.noChessProgram = FALSE; - chessProgram = FALSE; - appData.firstHost = FIRST_HOST; - appData.secondHost = SECOND_HOST; - appData.firstDirectory = FIRST_DIRECTORY; - appData.secondDirectory = SECOND_DIRECTORY; - appData.bitmapDirectory = ""; - appData.remoteShell = REMOTE_SHELL; - appData.remoteUser = ""; - appData.timeDelay = TIME_DELAY; - appData.timeControl = TIME_CONTROL; - appData.timeIncrement = TIME_INCREMENT; - appData.icsActive = FALSE; - appData.icsHost = ""; - appData.icsPort = ICS_PORT; - appData.icsCommPort = ICS_COMM_PORT; - appData.icsLogon = ICS_LOGON; - appData.icsHelper = ""; - appData.useTelnet = FALSE; - appData.telnetProgram = TELNET_PROGRAM; - appData.gateway = ""; - appData.loadGameFile = ""; - appData.loadGameIndex = 0; - appData.saveGameFile = ""; - appData.autoSaveGames = FALSE; - appData.loadPositionFile = ""; - appData.loadPositionIndex = 1; - appData.savePositionFile = ""; - appData.matchMode = FALSE; - appData.matchGames = 0; - appData.monoMode = FALSE; - appData.debugMode = FALSE; - appData.clockMode = TRUE; - boardSize = (BoardSize) -1; /* determine by screen size */ - appData.Iconic = FALSE; /*unused*/ - appData.searchTime = ""; - appData.searchDepth = 0; - appData.showCoords = FALSE; - appData.ringBellAfterMoves = TRUE; /*obsolete in WinBoard*/ - appData.autoCallFlag = FALSE; - appData.flipView = FALSE; - appData.autoFlipView = TRUE; - appData.cmailGameName = ""; - appData.alwaysPromoteToQueen = FALSE; - appData.oldSaveStyle = FALSE; - appData.quietPlay = FALSE; - appData.showThinking = FALSE; - appData.ponderNextMove = TRUE; - appData.periodicUpdates = TRUE; - appData.popupExitMessage = TRUE; - appData.popupMoveErrors = FALSE; - appData.autoObserve = FALSE; - appData.autoComment = FALSE; - appData.animate = TRUE; - appData.animSpeed = 10; - appData.animateDragging = TRUE; - appData.highlightLastMove = TRUE; - appData.getMoveList = TRUE; - appData.testLegality = TRUE; - appData.premove = TRUE; - appData.premoveWhite = FALSE; - appData.premoveWhiteText = ""; - appData.premoveBlack = FALSE; - appData.premoveBlackText = ""; - appData.icsAlarm = TRUE; - appData.icsAlarmTime = 5000; - appData.autoRaiseBoard = TRUE; - appData.localLineEditing = TRUE; - appData.colorize = TRUE; - appData.reuseFirst = TRUE; - appData.reuseSecond = TRUE; - appData.blindfold = FALSE; - appData.icsEngineAnalyze = FALSE; + memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 + dcb.DCBlength = sizeof(DCB); dcb.BaudRate = 9600; @@ -2048,132 +2019,6 @@ InitAppData(LPSTR lpCmdLine) dcb.ByteSize = 7; dcb.Parity = SPACEPARITY; dcb.StopBits = ONESTOPBIT; - settingsFileName = SETTINGS_FILE; - saveSettingsOnExit = TRUE; - boardX = CW_USEDEFAULT; - boardY = CW_USEDEFAULT; - analysisX = CW_USEDEFAULT; - analysisY = CW_USEDEFAULT; - analysisW = CW_USEDEFAULT; - analysisH = CW_USEDEFAULT; - commentX = CW_USEDEFAULT; - commentY = CW_USEDEFAULT; - commentW = CW_USEDEFAULT; - commentH = CW_USEDEFAULT; - editTagsX = CW_USEDEFAULT; - editTagsY = CW_USEDEFAULT; - editTagsW = CW_USEDEFAULT; - editTagsH = CW_USEDEFAULT; - icsTextMenuString = ICS_TEXT_MENU_DEFAULT; - icsNames = ICS_NAMES; - firstChessProgramNames = FCP_NAMES; - secondChessProgramNames = SCP_NAMES; - appData.initialMode = ""; - appData.variant = "normal"; - appData.firstProtocolVersion = PROTOVER; - appData.secondProtocolVersion = PROTOVER; - appData.showButtonBar = TRUE; - - /* [AS] New properties (see comments in header file) */ - appData.firstScoreIsAbsolute = FALSE; - appData.secondScoreIsAbsolute = FALSE; - appData.saveExtendedInfoInPGN = FALSE; - appData.hideThinkingFromHuman = FALSE; - appData.liteBackTextureFile = ""; - appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN; - appData.darkBackTextureFile = ""; - appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN; - appData.renderPiecesWithFont = ""; - appData.fontToPieceTable = ""; - appData.fontBackColorWhite = 0; - appData.fontForeColorWhite = 0; - appData.fontBackColorBlack = 0; - appData.fontForeColorBlack = 0; - appData.fontPieceSize = 80; - appData.overrideLineGap = 1; - appData.adjudicateLossThreshold = 0; - appData.delayBeforeQuit = 0; - appData.delayAfterQuit = 0; - appData.nameOfDebugFile = "winboard.debug"; - appData.pgnEventHeader = "Computer Chess Game"; - appData.defaultFrcPosition = -1; - appData.gameListTags = GLT_DEFAULT_TAGS; - appData.saveOutOfBookInfo = TRUE; - appData.showEvalInMoveHistory = TRUE; - appData.evalHistColorWhite = ParseColorName( "#FFFFB0" ); - appData.evalHistColorBlack = ParseColorName( "#AD5D3D" ); - appData.highlightMoveWithArrow = FALSE; - appData.highlightArrowColor = ParseColorName( "#FFFF80" ); - appData.useStickyWindows = TRUE; - appData.adjudicateDrawMoves = 0; - appData.autoDisplayComment = TRUE; - appData.autoDisplayTags = TRUE; - appData.firstIsUCI = FALSE; - appData.secondIsUCI = FALSE; - appData.firstHasOwnBookUCI = TRUE; - appData.secondHasOwnBookUCI = TRUE; - appData.polyglotDir = ""; - appData.usePolyglotBook = FALSE; - appData.polyglotBook = ""; - appData.defaultHashSize = 64; - appData.defaultCacheSizeEGTB = 4; - appData.defaultPathEGTB = "c:\\egtb"; - appData.firstOptions = ""; - appData.secondOptions = ""; - - InitWindowPlacement( &wpGameList ); - InitWindowPlacement( &wpMoveHistory ); - InitWindowPlacement( &wpEvalGraph ); - InitWindowPlacement( &wpEngineOutput ); - InitWindowPlacement( &wpConsole ); - - /* [HGM] User-selectable board size, adjudication control, miscellaneous */ - appData.NrFiles = -1; - appData.NrRanks = -1; - appData.holdingsSize = -1; - appData.testClaims = FALSE; - appData.checkMates = FALSE; - appData.materialDraws= FALSE; - appData.trivialDraws = FALSE; - appData.ruleMoves = 51; - appData.drawRepeats = 6; - appData.matchPause = 10000; - appData.alphaRank = FALSE; - appData.allWhite = FALSE; - appData.upsideDown = FALSE; - appData.serverPause = 15; - appData.serverMovesName = NULL; - appData.suppressLoadMoves = FALSE; - appData.firstTimeOdds = 1; - appData.secondTimeOdds = 1; - appData.firstAccumulateTC = 1; // combine previous and current sessions - appData.secondAccumulateTC = 1; - appData.firstNPS = -1; // [HGM] nps: use wall-clock time - appData.secondNPS = -1; - appData.engineComments = 1; - appData.smpCores = 1; // [HGM] SMP: max nr of cores - appData.egtFormats = ""; - -#ifdef ZIPPY - appData.zippyTalk = ZIPPY_TALK; - appData.zippyPlay = ZIPPY_PLAY; - appData.zippyLines = ZIPPY_LINES; - appData.zippyPinhead = ZIPPY_PINHEAD; - appData.zippyPassword = ZIPPY_PASSWORD; - appData.zippyPassword2 = ZIPPY_PASSWORD2; - appData.zippyWrongPassword = ZIPPY_WRONG_PASSWORD; - appData.zippyAcceptOnly = ZIPPY_ACCEPT_ONLY; - appData.zippyUseI = ZIPPY_USE_I; - appData.zippyBughouse = ZIPPY_BUGHOUSE; - appData.zippyNoplayCrafty = ZIPPY_NOPLAY_CRAFTY; - appData.zippyGameEnd = ZIPPY_GAME_END; - appData.zippyGameStart = ZIPPY_GAME_START; - appData.zippyAdjourn = ZIPPY_ADJOURN; - appData.zippyAbort = ZIPPY_ABORT; - appData.zippyVariants = ZIPPY_VARIANTS; - appData.zippyMaxGames = ZIPPY_MAX_GAMES; - appData.zippyReplayTimeout = ZIPPY_REPLAY_TIMEOUT; -#endif /* Point font array elements to structures and parse default font names */ @@ -2193,9 +2038,9 @@ InitAppData(LPSTR lpCmdLine) ParseArgs(StringGet, &lpCmdLine); /* [HGM] 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 BOARD_RANKS or BOARD_FILES, to support this size", 0, 2); /* [HGM] After parsing the options from the .ini file, and overruling them * with options from the command line, we now make an even higher priority @@ -2304,16 +2149,73 @@ InitMenuChecks() MF_CHECKED : MF_UNCHECKED)); } +// [HGM] args: these three cases taken out to stay in front-end +void +SaveFontArg(FILE *f, ArgDescriptor *ad) +{ // in WinBoard every board size has its own font, and the "argLoc" identifies the table, + // while the curent board size determines the element. This system should be ported to XBoard. + // What the table contains pointers to, and how to print the font description, remains platform-dependent + int bs; + for (bs=0; bsargLoc]->mfp; + fprintf(f, "/size=%s ", sizeInfo[bs].name); + fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n", + ad->argName, mfp->faceName, mfp->pointSize, + mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "", + mfp->bold ? "b" : "", + mfp->italic ? "i" : "", + mfp->underline ? "u" : "", + mfp->strikeout ? "s" : "", + (int)mfp->charset); + } + } + +VOID +ExportSounds() +{ // [HGM] copy the names from the internal WB variables to appData + ColorClass cc; + SoundClass sc; + for (cc = (ColorClass)0; cc < ColorNormal; cc++) + (&appData.soundShout)[cc] = textAttribs[cc].sound.name; + for (sc = (SoundClass)0; sc < NSoundClasses; sc++) + (&appData.soundMove)[sc] = sounds[sc].name; +} + +void +SaveAttribsArg(FILE *f, ArgDescriptor *ad) +{ // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though + MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc]; + fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName, + (ta->effects & CFE_BOLD) ? "b" : "", + (ta->effects & CFE_ITALIC) ? "i" : "", + (ta->effects & CFE_UNDERLINE) ? "u" : "", + (ta->effects & CFE_STRIKEOUT) ? "s" : "", + (ta->effects) ? " " : "", + ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff); + } + +void +SaveColor(FILE *f, ArgDescriptor *ad) +{ // in WinBoard the color is an int and has to be converted to text. In X it would be a string already? + COLORREF color = *(COLORREF *)ad->argLoc; + fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, + color&0xff, (color>>8)&0xff, (color>>16)&0xff); +} + +int +MainWindowUp() +{ // [HGM] args: allows testing if main window is realized from back-end + return hwndMain != NULL; +} VOID SaveSettings(char* name) { FILE *f; ArgDescriptor *ad; - WINDOWPLACEMENT wp; char dir[MSG_SIZ]; - if (!hwndMain) return; + if (!MainWindowUp()) return; GetCurrentDirectory(MSG_SIZ, dir); SetCurrentDirectory(installDir); @@ -2331,83 +2233,26 @@ SaveSettings(char* name) fprintf(f, "; Use a shortcut, an @indirection file, or a .bat file instead.\n"); fprintf(f, ";\n"); - wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(hwndMain, &wp); - boardX = wp.rcNormalPosition.left; - boardY = wp.rcNormalPosition.top; - - if (hwndConsole) { - GetWindowPlacement(hwndConsole, &wp); - wpConsole.x = wp.rcNormalPosition.left; - wpConsole.y = wp.rcNormalPosition.top; - wpConsole.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - wpConsole.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } - - if (analysisDialog) { - GetWindowPlacement(analysisDialog, &wp); - analysisX = wp.rcNormalPosition.left; - analysisY = wp.rcNormalPosition.top; - analysisW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - analysisH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } - - if (commentDialog) { - GetWindowPlacement(commentDialog, &wp); - commentX = wp.rcNormalPosition.left; - commentY = wp.rcNormalPosition.top; - commentW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - commentH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } - - if (editTagsDialog) { - GetWindowPlacement(editTagsDialog, &wp); - editTagsX = wp.rcNormalPosition.left; - editTagsY = wp.rcNormalPosition.top; - editTagsW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - editTagsH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } - - if (gameListDialog) { - GetWindowPlacement(gameListDialog, &wp); - wpGameList.x = wp.rcNormalPosition.left; - wpGameList.y = wp.rcNormalPosition.top; - wpGameList.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - wpGameList.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } + GetActualPlacement(hwndMain, &wpMain); + GetActualPlacement(hwndConsole, &wpConsole); + GetActualPlacement(commentDialog, &wpComment); + GetActualPlacement(editTagsDialog, &wpTags); + GetActualPlacement(gameListDialog, &wpGameList); /* [AS] Move history */ wpMoveHistory.visible = MoveHistoryIsUp(); - - if( moveHistoryDialog ) { - GetWindowPlacement(moveHistoryDialog, &wp); - wpMoveHistory.x = wp.rcNormalPosition.left; - wpMoveHistory.y = wp.rcNormalPosition.top; - wpMoveHistory.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - wpMoveHistory.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } + GetActualPlacement(moveHistoryDialog, &wpMoveHistory); /* [AS] Eval graph */ wpEvalGraph.visible = EvalGraphIsUp(); - - if( evalGraphDialog ) { - GetWindowPlacement(evalGraphDialog, &wp); - wpEvalGraph.x = wp.rcNormalPosition.left; - wpEvalGraph.y = wp.rcNormalPosition.top; - wpEvalGraph.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - wpEvalGraph.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } + GetActualPlacement(evalGraphDialog, &wpEvalGraph); /* [AS] Engine output */ wpEngineOutput.visible = EngineOutputIsUp(); + GetActualPlacement(engineOutputDialog, &wpEngineOutput); - if( engineOutputDialog ) { - GetWindowPlacement(engineOutputDialog, &wp); - wpEngineOutput.x = wp.rcNormalPosition.left; - wpEngineOutput.y = wp.rcNormalPosition.top; - wpEngineOutput.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - wpEngineOutput.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } + // [HGM] in WB we have to copy sound names to appData first + ExportSounds(); for (ad = argDescriptors; ad->argName != NULL; ad++) { if (!ad->save) continue; @@ -2443,10 +2288,10 @@ SaveSettings(char* name) fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc); break; case ArgX: - fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardX); // [HGM] placement: stor relative value + fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - wpMain.x); // [HGM] placement: stor relative value break; case ArgY: - fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardY); + fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - wpMain.y); break; case ArgFloat: fprintf(f, "/%s=%g\n", ad->argName, *(float *)ad->argLoc); @@ -2462,23 +2307,9 @@ SaveSettings(char* name) if (!*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName); break; case ArgColor: - { - COLORREF color = *(COLORREF *)ad->argLoc; - fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName, - color&0xff, (color>>8)&0xff, (color>>16)&0xff); - } + SaveColor(f, ad); break; case ArgAttribs: - { - MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc]; - fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName, - (ta->effects & CFE_BOLD) ? "b" : "", - (ta->effects & CFE_ITALIC) ? "i" : "", - (ta->effects & CFE_UNDERLINE) ? "u" : "", - (ta->effects & CFE_STRIKEOUT) ? "s" : "", - (ta->effects) ? " " : "", - ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff); - } break; case ArgFilename: if (strchr(*(char **)ad->argLoc, '\"')) { @@ -2492,21 +2323,7 @@ SaveSettings(char* name) sizeInfo[*(BoardSize *)ad->argLoc].name); break; case ArgFont: - { - int bs; - for (bs=0; bsargLoc]->mfp; - fprintf(f, "/size=%s ", sizeInfo[bs].name); - fprintf(f, "/%s=\"%s:%g%s%s%s%s%sc%d\"\n", - ad->argName, mfp->faceName, mfp->pointSize, - mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "", - mfp->bold ? "b" : "", - mfp->italic ? "i" : "", - mfp->underline ? "u" : "", - mfp->strikeout ? "s" : "", - (int)mfp->charset); - } - } + SaveFontArg(f, ad); break; case ArgCommSettings: PrintCommSettings(f, ad->argName, (DCB *)ad->argLoc); @@ -3032,7 +2849,7 @@ void CreatePiecesFromFont() } else if( strstr(lf.lfFaceName,"GC2004D") != NULL ) { /* Good Companion (Some characters get warped as literal :-( */ - char s[] = "1cmWG0ñueOS¯®oYI23wgQU"; + char s[] = "1cmWG0??S??oYI23wgQU"; s[0]=0xB9; s[1]=0xA9; s[6]=0xB1; s[11]=0xBB; s[12]=0xAB; s[17]=0xB3; SetCharTable(pieceToFontChar, s); } @@ -3200,10 +3017,10 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */ if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize; - oldRect.left = boardX; //[HGM] placement: remember previous window params - oldRect.top = boardY; - oldRect.right = boardX + winWidth; - oldRect.bottom = boardY + winHeight; + oldRect.left = wpMain.x; //[HGM] placement: remember previous window params + oldRect.top = wpMain.y; + oldRect.right = wpMain.x + wpMain.width; + oldRect.bottom = wpMain.y + wpMain.height; tinyLayout = sizeInfo[boardSize].tinyLayout; smallLayout = sizeInfo[boardSize].smallLayout; @@ -3311,49 +3128,49 @@ InitDrawingSizes(BoardSize boardSize, int flags) winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN; if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only - winWidth = winW; // [HGM] placement: set through temporary which can used by initial sizing choice - winHeight = winH; // without disturbing window attachments + wpMain.width = winW; // [HGM] placement: set through temporary which can used by initial sizing choice + wpMain.height = winH; // without disturbing window attachments GetWindowRect(hwndMain, &wrect); - SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight, + SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE); // [HGM] placement: let attached windows follow size change. - ReattachAfterSize( &oldRect, winWidth, winHeight, moveHistoryDialog, &wpMoveHistory ); - ReattachAfterSize( &oldRect, winWidth, winHeight, evalGraphDialog, &wpEvalGraph ); - ReattachAfterSize( &oldRect, winWidth, winHeight, engineOutputDialog, &wpEngineOutput ); - ReattachAfterSize( &oldRect, winWidth, winHeight, gameListDialog, &wpGameList ); - ReattachAfterSize( &oldRect, winWidth, winHeight, hwndConsole, &wpConsole ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, moveHistoryDialog, &wpMoveHistory ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, evalGraphDialog, &wpEvalGraph ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, engineOutputDialog, &wpEngineOutput ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, gameListDialog, &wpGameList ); + ReattachAfterSize( &oldRect, wpMain.width, wpMain.height, hwndConsole, &wpConsole ); /* compensate if menu bar wrapped */ GetClientRect(hwndMain, &crect); offby = boardRect.bottom + OUTER_MARGIN - crect.bottom; - winHeight += offby; + wpMain.height += offby; switch (flags) { case WMSZ_TOPLEFT: SetWindowPos(hwndMain, NULL, - wrect.right - winWidth, wrect.bottom - winHeight, - winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER); + wrect.right - wpMain.width, wrect.bottom - wpMain.height, + wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER); break; case WMSZ_TOPRIGHT: case WMSZ_TOP: SetWindowPos(hwndMain, NULL, - wrect.left, wrect.bottom - winHeight, - winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER); + wrect.left, wrect.bottom - wpMain.height, + wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER); break; case WMSZ_BOTTOMLEFT: case WMSZ_LEFT: SetWindowPos(hwndMain, NULL, - wrect.right - winWidth, wrect.top, - winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER); + wrect.right - wpMain.width, wrect.top, + wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER); break; case WMSZ_BOTTOMRIGHT: case WMSZ_BOTTOM: case WMSZ_RIGHT: default: - SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight, + SetWindowPos(hwndMain, NULL, 0, 0, wpMain.width, wpMain.height, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE); break; } @@ -4234,8 +4051,8 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) if( liteBackTexture != NULL || darkBackTexture != NULL ) { static int backTextureBoardSize; /* [HGM] boardsize: also new texture if board format changed */ if( backTextureSquareSize != squareSize - || backTextureBoardSize != BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT) { - backTextureBoardSize = BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT; + || backTextureBoardSize != BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT) { + backTextureBoardSize = BOARD_WIDTH+BOARD_FILES*BOARD_HEIGHT; backTextureSquareSize = squareSize; RebuildTextureSquareInfo(); } @@ -6252,18 +6069,18 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) RECT rcMain; // GetWindowRect( hwnd, &rcMain ); //[HGM] sticky: in XP this returned new position, not old - rcMain.left = boardX; // replace by these 4 lines to reconstruct old rect - rcMain.right = boardX + winWidth; - rcMain.top = boardY; - rcMain.bottom = boardY + winHeight; + rcMain.left = wpMain.x; // replace by these 4 lines to reconstruct old rect + rcMain.right = wpMain.x + wpMain.width; + rcMain.top = wpMain.y; + rcMain.bottom = wpMain.y + wpMain.height; ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, gameListDialog, &wpGameList ); ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole ); - boardX = lpwp->x; - boardY = lpwp->y; + wpMain.x = lpwp->x; + wpMain.y = lpwp->y; } } break; @@ -7026,18 +6843,18 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetClientRect(hDlg, &rect); sizeX = rect.right; sizeY = rect.bottom; - if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT && - commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) { + if (wpComment.x != CW_USEDEFAULT && wpComment.y != CW_USEDEFAULT && + wpComment.width != CW_USEDEFAULT && wpComment.height != CW_USEDEFAULT) { WINDOWPLACEMENT wp; - EnsureOnScreen(&commentX, &commentY, 0, 0); + EnsureOnScreen(&wpComment.x, &wpComment.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; wp.showCmd = SW_SHOW; wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = commentX; - wp.rcNormalPosition.right = commentX + commentW; - wp.rcNormalPosition.top = commentY; - wp.rcNormalPosition.bottom = commentY + commentH; + wp.rcNormalPosition.left = wpComment.x; + wp.rcNormalPosition.right = wpComment.x + wpComment.width; + wp.rcNormalPosition.top = wpComment.y; + wp.rcNormalPosition.bottom = wpComment.y + wpComment.height; SetWindowPlacement(hDlg, &wp); GetClientRect(hDlg, &rect); @@ -7186,13 +7003,8 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) } // [HGM] movenum: allow move number to be typed in any mode if(sscanf(move, "%d", &n) == 1 && n != 0 ) { - currentMove = 2*n-1; - if(currentMove > forwardMostMove) currentMove = forwardMostMove; - if(currentMove < backwardMostMove) currentMove = backwardMostMove; + ToNrEvent(2*n-1); EndDialog(hDlg, TRUE); - DrawPosition(TRUE, boards[currentMove]); - if(currentMove > backwardMostMove) DisplayMove(currentMove - 1); - else DisplayMessage("", ""); return TRUE; } } @@ -7416,7 +7228,7 @@ GothicDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: GetWindowRect(hDlg, &rChild); - SetWindowPos(hDlg, NULL, boardX, boardY-height, winWidth, height, + SetWindowPos(hDlg, NULL, wpMain.x, wpMain.y-height, wpMain.width, height, SWP_NOZORDER); /* @@ -8037,10 +7849,10 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) // [HGM] Chessknight's change 2004-07-13 else { /* Determine Defaults */ WINDOWPLACEMENT wp; - wpConsole.x = winWidth + 1; - wpConsole.y = boardY; - wpConsole.width = screenWidth - winWidth; - wpConsole.height = winHeight; + wpConsole.x = wpMain.width + 1; + wpConsole.y = wpMain.y; + wpConsole.width = screenWidth - wpMain.width; + wpConsole.height = wpMain.height; EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0); wp.length = sizeof(WINDOWPLACEMENT); wp.flags = 0; @@ -8569,6 +8381,13 @@ typedef struct { } Enables; VOID +GreyRevert(Boolean grey) +{ // [HGM] vari: for retracting variations in local mode + HMENU hmenu = GetMenu(hwndMain); + EnableMenuItem(hmenu, IDM_Revert, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED)); +} + +VOID SetMenuEnables(HMENU hmenu, Enables *enab) { while (enab->item > 0) { @@ -10490,86 +10309,6 @@ StartAnalysisClock() (UINT) 2000, NULL); } -LRESULT CALLBACK -AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - static HANDLE hwndText; - RECT rect; - static int sizeX, sizeY; - int newSizeX, newSizeY, flags; - MINMAXINFO *mmi; - - switch (message) { - case WM_INITDIALOG: /* message: initialize dialog box */ - /* Initialize the dialog items */ - hwndText = GetDlgItem(hDlg, OPT_AnalysisText); - SetWindowText(hDlg, analysisTitle); - SetDlgItemText(hDlg, OPT_AnalysisText, analysisText); - /* Size and position the dialog */ - if (!analysisDialog) { - analysisDialog = hDlg; - flags = SWP_NOZORDER; - GetClientRect(hDlg, &rect); - sizeX = rect.right; - sizeY = rect.bottom; - if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT && - analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) { - WINDOWPLACEMENT wp; - EnsureOnScreen(&analysisX, &analysisY, 0, 0); - wp.length = sizeof(WINDOWPLACEMENT); - wp.flags = 0; - wp.showCmd = SW_SHOW; - wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; - wp.rcNormalPosition.left = analysisX; - wp.rcNormalPosition.right = analysisX + analysisW; - wp.rcNormalPosition.top = analysisY; - wp.rcNormalPosition.bottom = analysisY + analysisH; - SetWindowPlacement(hDlg, &wp); - - GetClientRect(hDlg, &rect); - newSizeX = rect.right; - newSizeY = rect.bottom; - ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, - newSizeX, newSizeY); - sizeX = newSizeX; - sizeY = newSizeY; - } - } - return FALSE; - - case WM_COMMAND: /* message: received a command */ - switch (LOWORD(wParam)) { - case IDCANCEL: - if (appData.icsActive && appData.icsEngineAnalyze) { /* [DM] icsEngineAnalyze */ - ExitAnalyzeMode(); - ModeHighlight(); - return TRUE; - } - EditGameEvent(); - return TRUE; - default: - break; - } - break; - - case WM_SIZE: - newSizeX = LOWORD(lParam); - newSizeY = HIWORD(lParam); - ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY, newSizeX, newSizeY); - sizeX = newSizeX; - sizeY = newSizeY; - break; - - case WM_GETMINMAXINFO: - /* Prevent resizing window too small */ - mmi = (MINMAXINFO *) lParam; - mmi->ptMinTrackSize.x = 100; - mmi->ptMinTrackSize.y = 100; - break; - } - return FALSE; -} - VOID SetHighlights(int fromX, int fromY, int toX, int toY) { @@ -10774,8 +10513,3 @@ HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current ) EvalGraphSet( first, last, current, pvInfoList ); } - -void SetProgramStats( FrontEndProgramStats * stats ) -{ - EngineOutputUpdate( stats ); -} diff --git a/winboard/winboard.h b/winboard/winboard.h index 973aab6..443f728 100644 --- a/winboard/winboard.h +++ b/winboard/winboard.h @@ -173,6 +173,19 @@ extern MyFont *font[NUM_SIZES][NUM_FONTS]; #define COPY_TMP "wbcopy.tmp" #define PASTE_TMP "wbpaste.tmp" +/* variables */ +extern HINSTANCE hInst; +extern HWND hwndMain; +extern BoardSize boardSize; + +// [HGM] Some stuff to allo a platform-independent reference to windows +// This should be moved to frontend.h in due time + +typedef enum { + W_Main, W_Console, W_Comment, W_Tags, W_GameList, + W_MoveHist, W_EngineOut, W_GameList, NUM_WINDOWS +} WindowID; + /* [AS] Layout management */ typedef struct { Boolean visible; @@ -182,10 +195,37 @@ typedef struct { int height; } WindowPlacement; -VOID InitWindowPlacement( WindowPlacement * wp ); +extern WindowPlacement placementTab[NUM_WINDOWS]; +extern HWND hwndTab[NUM_WINDOWS]; // this remains pure front-end. +VOID InitWindowPlacement( WindowPlacement * wp ); VOID RestoreWindowPlacement( HWND hWnd, WindowPlacement * wp ); - VOID ReattachAfterMove( LPRECT lprcOldPos, int new_x, int new_y, HWND hWndChild, WindowPlacement * pwpChild ); - VOID ReattachAfterSize( LPRECT lprcOldPos, int new_w, int new_h, HWND hWndChild, WindowPlacement * pwpChild ); +BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp ); + +extern WindowPlacement wpEngineOutput; +extern WindowPlacement wpEvalGraph; +extern WindowPlacement wpMoveHistory; +extern WindowPlacement wpGameList; +extern WindowPlacement wpTags; + +VOID MoveHistoryPopUp(); +VOID MoveHistoryPopDown(); +VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo ); +BOOL MoveHistoryIsUp(); +extern HWND moveHistoryDialog; + +VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo ); +VOID EvalGraphPopUp(); +VOID EvalGraphPopDown(); +Boolean EvalGraphIsUp(); +extern HWND evalGraphDialog; + +extern HWND engineOutputDialog; + +VOID ShowGameListProc(void); +extern HWND gameListDialog; + +VOID EditTagsProc(void); +extern HWND editTagsDialog; diff --git a/winboard/winboard.rc b/winboard/winboard.rc index c61067b..0214ca2 100644 --- a/winboard/winboard.rc +++ b/winboard/winboard.rc @@ -54,7 +54,7 @@ BEGIN OPT_MESS,6,85,120,16 END -DLG_TimeControl DIALOG DISCARDABLE 6, 18, 263, 172 +DLG_TimeControl DIALOG DISCARDABLE 6, 18, 263, 212 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Time Control" FONT 8, "MS Sans Serif" @@ -65,6 +65,8 @@ BEGIN BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,36,113,10 CONTROL "Incremental clock",OPT_TCUseInc,"Button", BS_AUTORADIOBUTTON | WS_TABSTOP,7,73,107,10 + CONTROL "Fixed time per move",OPT_TCUseFixed,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,7,124,107,10 LTEXT "Number of moves:",OPT_TCtext1,15,52,58,8,NOT WS_GROUP EDITTEXT OPT_TCMoves,77,52,22,12,ES_AUTOHSCROLL | WS_GROUP LTEXT "Within number of minutes:",OPT_TCtext2,113,54,81,8,NOT @@ -76,14 +78,17 @@ BEGIN LTEXT "Plus number of seconds per move:",406,15,105,109,8,NOT WS_GROUP EDITTEXT OPT_TCInc,127,103,32,12,ES_AUTOHSCROLL - LTEXT "",408,185,108,67,8,NOT WS_GROUP - LTEXT "Time-Odds Factors:",IDC_STATIC,6,118,150,8,NOT WS_GROUP - EDITTEXT OPT_TCOdds1,47,131,26,12,ES_AUTOHSCROLL | WS_GROUP - LTEXT "Engine #1:",IDC_STATIC,6,133,41,8,NOT WS_GROUP - EDITTEXT OPT_TCOdds2,124,131,26,12,ES_AUTOHSCROLL - LTEXT "Engine #2:",IDC_STATIC,83,133,41,8,NOT WS_GROUP - PUSHBUTTON "OK",IDOK,29,150,40,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,85,150,40,14 + LTEXT "Maximum seconds per move:",OPT_TCftext,15,142,109,8,NOT + WS_GROUP + EDITTEXT OPT_TCFixed,127,140,32,12,ES_AUTOHSCROLL + LTEXT "",408,185,148,67,8,NOT WS_GROUP + LTEXT "Time-Odds Factors:",IDC_STATIC,6,158,150,8,NOT WS_GROUP + EDITTEXT OPT_TCOdds1,47,171,32,12,ES_AUTOHSCROLL | WS_GROUP + LTEXT "Engine #1:",IDC_STATIC,6,173,40,8,NOT WS_GROUP + EDITTEXT OPT_TCOdds2,127,171,32,12,ES_AUTOHSCROLL + LTEXT "Engine #2:",IDC_STATIC,86,173,40,8,NOT WS_GROUP + PUSHBUTTON "OK",IDOK,29,190,40,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,85,190,40,14 END DLG_LoadOptions DIALOG DISCARDABLE 10, 18, 136, 55 diff --git a/winboard/wlayout.c b/winboard/wlayout.c index 04f6eb6..2442466 100644 --- a/winboard/wlayout.c +++ b/winboard/wlayout.c @@ -33,6 +33,7 @@ #include #include "common.h" +#include "frontend.h" #include "winboard.h" VOID RestoreWindowPlacement( HWND hWnd, WindowPlacement * wp ) @@ -93,7 +94,7 @@ static BOOL IsDefaultPlacement( WindowPlacement * wp ) return result; } -static BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp ) +BOOL GetActualPlacement( HWND hWnd, WindowPlacement * wp ) { BOOL result = FALSE; diff --git a/winboard/woptions.c b/winboard/woptions.c index aaab83b..dfc1bfb 100755 --- a/winboard/woptions.c +++ b/winboard/woptions.c @@ -1,2979 +1,3002 @@ -/* - * 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 /* required for all Windows applications */ -#include -#include -#include /* [AS] Requires NT 4.0 or Win95 */ -#include - -#include "common.h" -#include "winboard.h" -#include "backend.h" -#include "woptions.h" -#include "defaults.h" -#include "wedittags.h" -#include - -#if __GNUC__ -#include -#include -#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); - +/* + * 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 /* required for all Windows applications */ +#include +#include +#include /* [AS] Requires NT 4.0 or Win95 */ +#include + +#include "common.h" +#include "frontend.h" +#include "winboard.h" +#include "backend.h" +#include "woptions.h" +#include "defaults.h" +#include + +#if __GNUC__ +#include +#include +#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 */ +extern int searchTime; + +/* 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); + ChangedConsoleFont(); - 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); - - 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; idef, &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) { + CHARFORMAT cf; + COLORREF background = ParseColorName(COLOR_BKGD); + /* + SetDefaultTextAttribs(); + Colorize(currentColorClass); + */ + cf.cbSize = sizeof(CHARFORMAT); + cf.dwMask = CFM_COLOR; + cf.crTextColor = ParseColorName(COLOR_NORMAL); + + 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; idef, &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) + + 2*IsDlgButtonChecked(hDlg, OPT_TCUseFixed); + EnableWindow(GetDlgItem(hDlg, OPT_TCTime), state == 1); + EnableWindow(GetDlgItem(hDlg, OPT_TCMoves), state == 1); + EnableWindow(GetDlgItem(hDlg, OPT_TCtext1), state == 1); + EnableWindow(GetDlgItem(hDlg, OPT_TCtext2), state == 1); + 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); + EnableWindow(GetDlgItem(hDlg, OPT_TCFixed), state == 2); + EnableWindow(GetDlgItem(hDlg, OPT_TCftext), state == 2); +} + + +LRESULT CALLBACK +TimeControl(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + char buf[MSG_SIZ], *tc; + int mps, increment, odds1, odds2, st; + 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 (searchTime) { + CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed, + OPT_TCUseFixed); + SetDlgItemInt(hDlg, OPT_TCFixed, searchTime, FALSE); + } else + if (appData.timeIncrement == -1) { + CheckRadioButton(hDlg, OPT_TCUseMoves, OPT_TCUseFixed, + 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_TCUseFixed, + 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: + mps = appData.movesPerSession; + increment = appData.timeIncrement; + tc = appData.timeControl; + st = 0; + /* Read changed options from the dialog box */ + if (IsDlgButtonChecked(hDlg, OPT_TCUseFixed)) { + st = GetDlgItemInt(hDlg, OPT_TCFixed, &ok, FALSE); + if (!ok || st <= 0) { + MessageBox(hDlg, "Invalid max time per move", + "Option Error", MB_OK|MB_ICONEXCLAMATION); + return FALSE; + } + } else + 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; + } + tc = buf; + } else { + increment = GetDlgItemInt(hDlg, OPT_TCInc, &ok, FALSE); + 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; + } + tc = buf; + } + 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; + } + searchTime = st; + appData.timeControl = strdup(tc); + 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); +} diff --git a/xboard.c b/xboard.c index 1665f4c..a3fda95 100644 --- 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 int get_term_width() { diff --git a/xboard.h b/xboard.h index 5806d53..9f3cdd7 100644 --- 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); diff --git a/xengineoutput.c b/xengineoutput.c index 2096f2e..7162631 100644 --- a/xengineoutput.c +++ b/xengineoutput.c @@ -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); } diff --git a/xhistory.c b/xhistory.c index 1a29626..2b861eb 100644 --- a/xhistory.c +++ b/xhistory.c @@ -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() 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;iaNr;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 diff --git a/xoptions.c b/xoptions.c index 6c3d8aa..c154030 100644 --- a/xoptions.c +++ b/xoptions.c @@ -45,6 +45,7 @@ extern char *getenv(); #if HAVE_UNISTD_H # include #endif +#include #include #include