X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=a5e26db4576c751f30e395e2b7ae54f8022177df;hb=b0c4bb81c045add757b010dc8319da38bad1d510;hp=424463dad2eca1e8477a821e39fb78ca9b85c765;hpb=60876535e02fb87e638a0aa94aa80490093099fc;p=xboard.git diff --git a/backend.c b/backend.c index 424463d..a5e26db 100644 --- a/backend.c +++ b/backend.c @@ -243,7 +243,12 @@ 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 */ +int partnerHighlight[2]; +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 */ @@ -1103,6 +1108,11 @@ InitBackEnd3 P((void)) InitChessProgram(&first, startedFromSetupPosition); + if(!appData.noChessProgram) { /* [HGM] tidy: redo program version to use name from myname feature */ + free(programVersion); + programVersion = (char*) malloc(8 + strlen(PACKAGE_STRING) + strlen(first.tidy)); + sprintf(programVersion, "%s + %s", PACKAGE_STRING, first.tidy); + } if (appData.icsActive) { #ifdef WIN32 @@ -2701,7 +2711,7 @@ read_from_ics(isr, closure, data, count, error) if (appData.autoKibitz && started == STARTED_NONE && !appData.icsEngineAnalyze && // [HGM] [DM] ICS analyze (gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack || gameMode == IcsObserving)) { - if(looking_at(buf, &i, "* kibitzes: ") && + if((looking_at(buf, &i, "* kibitzes: ") || looking_at(buf, &i, "* whispers: ")) && (StrStr(star_match[0], gameInfo.white) == star_match[0] || StrStr(star_match[0], gameInfo.black) == star_match[0] )) { // kibitz of self or opponent suppressKibitz = TRUE; @@ -2740,6 +2750,7 @@ 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, "* kibitzes:") || looking_at(buf, &i, "* shouts:") || looking_at(buf, &i, "* c-shouts:") || looking_at(buf, &i, "--> * ") || @@ -2759,6 +2770,13 @@ read_from_ics(isr, closure, data, count, error) chattingPartner = p; break; } } else + if(buf[i-3] == 'e') // kibitz; look if there is a KIBITZ chatbox + for(p=0; p') // shout, c-shout or it; look if there is a 'shouts' chatbox - for(p=0; p') {// shout, c-shout or it; look if there is a 'shouts' chatbox + if(buf[i-8] == '-' && buf[i-3] == 't') + 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 background @@ -3659,7 +3688,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; } } } /* Suppress following prompt */ @@ -3813,7 +3844,7 @@ 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]; + char *toSqr; 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]); @@ -3823,10 +3854,22 @@ ParseBoard12(string) } } CopyBoard(partnerBoard, board); + if(toSqr = strchr(str, '/')) { // extract highlights from long move + partnerBoard[EP_STATUS-3] = toSqr[1] - AAA; // kludge: hide highlighting info in board + partnerBoard[EP_STATUS-4] = toSqr[2] - ONE; + } else partnerBoard[EP_STATUS-4] = partnerBoard[EP_STATUS-3] = -1; + if(toSqr = strchr(str, '-')) { + partnerBoard[EP_STATUS-1] = toSqr[1] - AAA; + partnerBoard[EP_STATUS-2] = toSqr[2] - ONE; + } else partnerBoard[EP_STATUS-1] = partnerBoard[EP_STATUS-2] = -1; + if(appData.dualBoard && !twoBoards) { twoBoards = 1; InitDrawingSizes(-2,0); } + if(twoBoards) { partnerUp = 1; flipView = !flipView; } // [HGM] dual 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; } // [HGM] dual + sprintf(partnerStatus, "W: %d:%02d B: %d:%02d (%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; } @@ -4359,6 +4402,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); @@ -4715,6 +4759,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) @@ -4727,7 +4773,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: @@ -4821,15 +4867,15 @@ ParsePV(char *pv, Boolean storeComments) int fromX, fromY, toX, toY; char promoChar; ChessMove moveType; Boolean valid; - int nr = 0, dummy; + int nr = 0; endPV = forwardMostMove; do { - while(*pv == ' ') pv++; - if(nr == 0 && *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)){ @@ -4848,30 +4894,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 } } - if(moveType == Comment) { - // [HGM] vari: try to skip comment - int level = 0; char c, *start = pv, wait = NULLCHAR; - do { - if(!wait) { - if(*pv == '(') level++; else - if(*pv == ')' && level) level--; - } - if(*pv == wait) wait = NULLCHAR; else - if(*pv == '{') wait = '}'; else - if(*pv == '[') wait = ']'; - pv++; - } while(*pv && (wait || level)); - if(storeComments) { - c = *pv; *pv = NULLCHAR; - AppendComment(endPV, start, FALSE); - *pv = c; - } - valid++; // allow comments in PV + 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; } - if(sscanf(pv, "%d...", &dummy) == 1 || sscanf(pv, "%d.", &dummy) == 1) - while(*pv && *pv++ != ' '); // skip any move numbers - while(*pv && *pv++ != ' '); // skip what we parsed; assume space separators nr++; if(endPV+1 > framePtr) break; // no space, truncate if(!valid) break; @@ -4903,14 +4932,17 @@ 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, FALSE); *start = startPV; *end = index-1; @@ -6448,8 +6480,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; } @@ -8894,7 +8937,10 @@ GameEnds(result, resultDetails, whosays) if(endingGame) return; /* [HGM] crash: forbid recursion */ endingGame = 1; - + if(twoBoards) { // [HGM] dual: switch back to one board + twoBoards = partnerUp = 0; InitDrawingSizes(-2, 0); + DrawPosition(TRUE, partnerBoard); // observed game becomes foreground + } if (appData.debugMode) { fprintf(debugFP, "GameEnds(%d, %s, %d)\n", result, resultDetails ? resultDetails : "(null)", whosays); @@ -10164,7 +10210,9 @@ LoadGame(f, gameNumber, title, useList) if (numPGNTags > 0){ char *tags; if (gameInfo.variant == VariantNormal) { - gameInfo.variant = StringToVariant(gameInfo.event); + VariantClass v = StringToVariant(gameInfo.event); + // [HGM] do not recognize variants from event tag that were introduced after supporting variant tag + if(v < VariantShogi) gameInfo.variant = v; } if (!matchMode) { if( appData.autoDisplayTags ) { @@ -13351,8 +13399,10 @@ ReceiveFromProgram(isr, closure, message, count, error) sscanf(message, "error %c", &c)!=1 && sscanf(message, "illegal %c", &c)!=1 && sscanf(message, "tell%c", &c)!=1 && sscanf(message, "0-1 %c", &c)!=1 && sscanf(message, "1-0 %c", &c)!=1 && sscanf(message, "1/2-1/2 %c", &c)!=1 && - sscanf(message, "pong %c", &c)!=1 && start != '#') - { quote = "# "; print = (appData.engineComments == 2); } + sscanf(message, "pong %c", &c)!=1 && start != '#') { + quote = appData.engineComments == 2 ? "# " : "### NON-COMPLIANT! ### "; + print = (appData.engineComments >= 2); + } message[0] = start; // restore original message } if(print) { @@ -15161,3 +15211,4 @@ LoadVariation(int index, char *text) CommentPopDown(); ToNrEvent(currentMove+1); } +