X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=7a3c73160ae32ea3080d4e0b5eca3f27d98352c3;hb=refs%2Ftags%2Fhgm-4.20100223;hp=c33c164ba9f9727a66827376321884eba9888b07;hpb=ba19c79e683860fba8cafa5ca24b0f8191b4c1d5;p=xboard.git diff --git a/backend.c b/backend.c index c33c164..7a3c731 100644 --- a/backend.c +++ b/backend.c @@ -243,7 +243,11 @@ static int exiting = 0; /* [HGM] moved to top */ static int setboardSpoiledMachineBlack = 0 /*, errorExitFlag = 0*/; int startedFromPositionFile = FALSE; Board filePosition; /* [HGM] loadPos */ Board partnerBoard; /* [HGM] bughouse: for peeking at partner game */ +Boolean partnerBoardValid = 0; +char partnerStatus[MSG_SIZ]; Boolean partnerUp; +Boolean originalFlip; +Boolean twoBoards = 0; char endingGame = 0; /* [HGM] crash: flag to prevent recursion of GameEnds() */ int whiteNPS, blackNPS; /* [HGM] nps: for easily making clocks aware of NPS */ VariantClass currentlyInitializedVariant; /* [HGM] variantswitch */ @@ -2740,6 +2744,9 @@ read_from_ics(isr, closure, data, count, error) channel = -1; if(started == STARTED_NONE && (looking_at(buf, &i, "* tells you:") || looking_at(buf, &i, "* says:") || looking_at(buf, &i, "* whispers:") || + looking_at(buf, &i, "* shouts:") || + looking_at(buf, &i, "* c-shouts:") || + looking_at(buf, &i, "--> * ") || looking_at(buf, &i, "*(*):") && (sscanf(star_match[1], "%d", &channel),1) || looking_at(buf, &i, "*(*)(*):") && (sscanf(star_match[2], "%d", &channel),1) || looking_at(buf, &i, "*(*)(*)(*):") && (sscanf(star_match[3], "%d", &channel),1) || @@ -2752,22 +2759,33 @@ read_from_ics(isr, closure, data, count, error) for(p=0; p') // shout, c-shout or it; look if there is a 'shouts' chatbox + for(p=0; p') { talker[0] = '<'; strcat(talker, "> "); Colorize(ColorShout, FALSE); } + else if(buf[i-8] == '-') { talker[0] = '('; strcat(talker, ") "); Colorize(ColorSShout, FALSE); } + else { talker[0] = '['; strcat(talker, "] "); Colorize(ColorShout, FALSE); } + chattingPartner = p; break; + } } if(chattingPartner<0) // if not, look if there is a chatbox for this indivdual for(p=0; p 0 && buf[oldi-1] == '\n') oldi--; if (oldi > next_out) SendToPlayer(&buf[next_out], oldi - next_out); started = STARTED_COMMENT; @@ -3447,6 +3465,7 @@ read_from_ics(isr, closure, data, count, error) ZippyGameStart(whitename, blackname); } #endif /*ZIPPY*/ + partnerBoardValid = FALSE; // [HGM] bughouse continue; } @@ -3487,6 +3506,7 @@ read_from_ics(isr, closure, data, count, error) Reset(TRUE, TRUE); } #endif /*ZIPPY*/ + if(appData.bgObserve && partnerBoardValid) DrawPosition(TRUE, partnerBoard); continue; } @@ -3633,7 +3653,7 @@ read_from_ics(isr, closure, data, count, error) gameInfo.white, white_holding, gameInfo.black, black_holding); } - + if(!partnerUp) // [HGM] bughouse: when peeking at partner game we already know what he captured... DrawPosition(FALSE, boards[currentMove]); DisplayTitle(str); } else if(appData.bgObserve) { // [HGM] bughouse: holdings of other game => background @@ -3645,7 +3665,9 @@ read_from_ics(isr, closure, data, count, error) /* [HGM] copy holdings to partner-board holdings area */ CopyHoldings(partnerBoard, white_holding, WhitePawn); CopyHoldings(partnerBoard, black_holding, BlackPawn); + if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual: always draw if(partnerUp) DrawPosition(FALSE, partnerBoard); + if(twoBoards) { partnerUp = 0; flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); } // [HGM] dual: redraw own } } /* Suppress following prompt */ @@ -3799,7 +3821,6 @@ ParseBoard12(string) if((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) && newGameMode == IcsObserving && appData.bgObserve) { // [HGM] bughouse: don't act on alien boards while we play. Just parse the board and save it */ - char buf[MSG_SIZ]; for (k = 0; k < ranks; k++) { for (j = 0; j < files; j++) board[k][j+gameInfo.holdingsWidth] = CharToPiece(board_chars[(ranks-1-k)*(files+1) + j]); @@ -3808,11 +3829,14 @@ ParseBoard12(string) board[k][1] = board[k][BOARD_WIDTH-2] = (ChessSquare) 0;; } } + if(appData.dualBoard) { twoBoards = partnerUp = 1; flipView = !flipView; InitDrawingSizes(-2,0); } // [HGM] dual CopyBoard(partnerBoard, board); if(partnerUp) DrawPosition(FALSE, partnerBoard); - sprintf(buf, "W: %d:%d B: %d:%d (%d-%d) %c", white_time/60000, (white_time%60000)/1000, + if(twoBoards) { partnerUp = 0; flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); } // [HGM] dual: redraw own game! + sprintf(partnerStatus, "W: %d:%d B: %d:%d (%d-%d) %c", white_time/60000, (white_time%60000)/1000, (black_time/60000), (black_time%60000)/1000, white_stren, black_stren, to_play); - DisplayMessage(buf, ""); + DisplayMessage(partnerStatus, ""); + partnerBoardValid = TRUE; return; } @@ -4345,6 +4369,7 @@ ParseBoard12(string) ClearPremoveHighlights(); j = seekGraphUp; seekGraphUp = FALSE; // [HGM] seekgraph: when we draw a board, it overwrites the seek graph + if(partnerUp) { flipView = originalFlip; partnerUp = FALSE; j = TRUE; } // [HGM] bughouse: restore view DrawPosition(j, boards[currentMove]); DisplayMove(moveNum - 1); @@ -4701,6 +4726,8 @@ AlphaRank(char *move, int n) } } +char yy_textstr[8000]; + /* Parser for moves from gnuchess, ICS, or user typein box */ Boolean ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) @@ -4713,7 +4740,7 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) if (appData.debugMode) { fprintf(debugFP, "move to parse: %s\n", move); } - *moveType = yylexstr(moveNum, move); + *moveType = yylexstr(moveNum, move, yy_textstr, sizeof yy_textstr); switch (*moveType) { case WhitePromotionChancellor: @@ -4802,7 +4829,7 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) void -ParsePV(char *pv) +ParsePV(char *pv, Boolean storeComments) { // Parse a string of PV moves, and append to current game, behind forwardMostMove int fromX, fromY, toX, toY; char promoChar; ChessMove moveType; @@ -4811,11 +4838,11 @@ ParsePV(char *pv) endPV = forwardMostMove; do { - while(*pv == ' ') pv++; - if(*pv == '(') pv++; // first (ponder) move can be in parentheses + while(*pv == ' ' || *pv == '\n' || *pv == '\t') pv++; // must still read away whitespace + if(nr == 0 && !storeComments && *pv == '(') pv++; // first (ponder) move can be in parentheses valid = ParseOneMove(pv, endPV, &moveType, &fromX, &fromY, &toX, &toY, &promoChar); if(appData.debugMode){ -fprintf(debugFP,"parsePV: %d %c%c%c%c '%s'\n", valid, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, pv); +fprintf(debugFP,"parsePV: %d %c%c%c%c yy='%s'\nPV = '%s'\n", valid, fromX+AAA, fromY+ONE, toX+AAA, toY+ONE, yy_textstr, pv); } if(!valid && nr == 0 && ParseOneMove(pv, endPV-1, &moveType, &fromX, &fromY, &toX, &toY, &promoChar)){ @@ -4834,9 +4861,13 @@ fprintf(debugFP,"parsePV: %d %c%c%c%c '%s'\n", valid, fromX+AAA, fromY+ONE, toX+ strcpy(moveList[endPV-2], "_0_0"); // suppress premove highlight on takeback move } } + pv = strstr(pv, yy_textstr) + strlen(yy_textstr); // skip what we parsed + if(nr == 0 && !storeComments && *pv == ')') pv++; // closing parenthesis of ponder move; + if(moveType == Comment && storeComments) AppendComment(endPV, yy_textstr, FALSE); + if(moveType == Comment || moveType == NAG || moveType == ElapsedTime) { + valid++; // allow comments in PV + continue; } - while(*pv && *pv++ != ' '); // skip what we parsed; assume space separators - if(moveType == Comment) { valid++; continue; } // allow comments in PV nr++; if(endPV+1 > framePtr) break; // no space, truncate if(!valid) break; @@ -4847,7 +4878,13 @@ fprintf(debugFP,"parsePV: %d %c%c%c%c '%s'\n", valid, fromX+AAA, fromY+ONE, toX+ moveList[endPV-1][1] = fromY + ONE; moveList[endPV-1][2] = toX + AAA; moveList[endPV-1][3] = toY + ONE; - parseList[endPV-1][0] = NULLCHAR; + if(storeComments) + CoordsToAlgebraic(boards[endPV - 1], + PosFlags(endPV - 1), + fromY, fromX, toY, toX, promoChar, + parseList[endPV - 1]); + else + parseList[endPV-1][0] = NULLCHAR; } while(valid); currentMove = endPV; if(currentMove == forwardMostMove) ClearPremoveHighlights(); else @@ -4862,16 +4899,19 @@ Boolean LoadMultiPV(int x, int y, char *buf, int index, int *start, int *end) { int startPV; + char *p; if(index < 0 || index >= strlen(buf)) return FALSE; // sanity lastX = x; lastY = y; while(index > 0 && buf[index-1] != '\n') index--; // beginning of line startPV = index; - while(buf[index] != '\n') if(buf[index++] == '\t') startPV = index; - index = startPV; - while(buf[index] && buf[index] != '\n') index++; + while(buf[index] != '\n') if(buf[index++] == '\t') startPV = index; + if(index == startPV && (p = StrCaseStr(buf+index, "PV="))) startPV = p - buf + 3; + index = startPV; + do{ while(buf[index] && buf[index] != '\n') index++; + } while(buf[index] == '\n' && buf[index+1] == '\\' && buf[index+2] == ' ' && index++); // join kibitzed PV continuation line buf[index] = 0; - ParsePV(buf+startPV); + ParsePV(buf+startPV, FALSE); *start = startPV; *end = index-1; return TRUE; } @@ -4881,7 +4921,7 @@ LoadPV(int x, int y) { // called on right mouse click to load PV int which = gameMode == TwoMachinesPlay && (WhiteOnMove(forwardMostMove) == (second.twoMachinesColor[0] == 'w')); lastX = x; lastY = y; - ParsePV(lastPV[which]); // load the PV of the thinking engine in the boards array. + ParsePV(lastPV[which], FALSE); // load the PV of the thinking engine in the boards array. return TRUE; } @@ -6407,8 +6447,19 @@ int RightClick(ClickType action, int x, int y, int *fromX, int *fromY) if((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) && !appData.zippyPlay && appData.bgObserve) { // [HGM] bughouse: show background game - if(action == Press) { flipView = !flipView; DrawPosition(TRUE, partnerBoard); partnerUp = TRUE; } else - if(action == Release) { flipView = !flipView; DrawPosition(TRUE, boards[currentMove]); partnerUp = FALSE; } + if(!partnerBoardValid) return -2; // suppress display of uninitialized boards + if( appData.dualBoard) return -2; // [HGM] dual: is already displayed + if(action == Press) { + originalFlip = flipView; + flipView = !flipView; // temporarily flip board to see game from partners perspective + DrawPosition(TRUE, partnerBoard); + DisplayMessage(partnerStatus, ""); + partnerUp = TRUE; + } else if(action == Release) { + flipView = originalFlip; + DrawPosition(TRUE, boards[currentMove]); + partnerUp = FALSE; + } return -2; } @@ -8853,6 +8904,7 @@ GameEnds(result, resultDetails, whosays) if(endingGame) return; /* [HGM] crash: forbid recursion */ endingGame = 1; + if(twoBoards) { twoBoards = partnerUp = 0; InitDrawingSizes(-2, 0); } // [HGM] dual if (appData.debugMode) { fprintf(debugFP, "GameEnds(%d, %s, %d)\n", @@ -12653,9 +12705,9 @@ ToNrEvent(int to) } void -RevertEvent() +RevertEvent(Boolean annotate) { - if(PopTail(TRUE)) { // [HGM] vari: restore old game tail + if(PopTail(annotate)) { // [HGM] vari: restore old game tail return; } if (gameMode != IcsExamining) { @@ -15016,7 +15068,7 @@ PushTail(int firstMove, int lastMove) } storedGames++; - forwardMostMove = currentMove; // truncte game so we can start variation + forwardMostMove = firstMove; // truncate game so we can start variation if(storedGames == 1) GreyRevert(FALSE); } @@ -15028,6 +15080,7 @@ PopTail(Boolean annotate) if(appData.icsActive) return FALSE; // only in local mode if(!storedGames) return FALSE; // sanity + CommentPopDown(); // make sure no stale variation comments to the destroyed line can remain open storedGames--; ToNrEvent(savedFirst[storedGames]); // sets currentMove @@ -15041,11 +15094,12 @@ PopTail(Boolean annotate) sprintf(moveBuf, " %d. %s", i+2>>1, SavePart(parseList[i])); else sprintf(moveBuf, " %s", SavePart(parseList[i])); strcat(buf, moveBuf); + if(commentList[i]) { strcat(buf, " "); strcat(buf, commentList[i]); } if(!--cnt) { strcat(buf, "\n"); cnt = 10; } } strcat(buf, ")"); } - for(i=1; i 0 && --level == 0 && p-text > index && end == NULL) end = p-1; + } + if(*p == wait) wait = NULLCHAR; // closing ]} found + p++; + } + if(!start || !end) return; // no variation found, or syntax error in PGN: ignore click + if(appData.debugMode) fprintf(debugFP, "at move %d load variation '%s'\n", currentMove, start); + end[1] = NULLCHAR; // clip off comment beyond variation + ToNrEvent(currentMove-1); + PushTail(currentMove, forwardMostMove); // shelve main variation. This truncates game + // kludge: use ParsePV() to append variation to game + move = currentMove; + ParsePV(start, TRUE); + forwardMostMove = endPV; endPV = -1; currentMove = move; // cleanup what ParsePV did + ClearPremoveHighlights(); + CommentPopDown(); + ToNrEvent(currentMove+1); +}