X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=e9d10dc85cafa86201af20e913c0ee5901152ae6;hb=9e76d58957a505620e6c5395989ad4f9bbbffe93;hp=6442bea2c47f9cc261907b07d3ef99da6929c16b;hpb=025a668716d9220ada1d2e3b6b87c8517ac7899a;p=xboard.git diff --git a/backend.c b/backend.c index 6442bea..e9d10dc 100644 --- a/backend.c +++ b/backend.c @@ -129,6 +129,7 @@ extern int gettimeofday(struct timeval *, struct timezone *); # include "zippy.h" #endif #include "backendz.h" +#include "evalgraph.h" #include "gettext.h" #ifdef ENABLE_NLS @@ -270,6 +271,7 @@ char lastMsg[MSG_SIZ]; ChessSquare pieceSweep = EmptySquare; ChessSquare promoSweep = EmptySquare, defaultPromoChoice; int promoDefaultAltered; +int keepInfo = 0; /* [HGM] to protect PGN tags in auto-step game analysis */ /* States for ics_getting_history */ #define H_FALSE 0 @@ -1843,6 +1845,7 @@ read_from_player (InputSourceRef isr, VOIDSTAR closure, char *message, int count { int outError, outCount; static int gotEof = 0; + static FILE *ini; /* Pass data read from player on to ICS */ if (count > 0) { @@ -1851,6 +1854,17 @@ read_from_player (InputSourceRef isr, VOIDSTAR closure, char *message, int count if (outCount < count) { DisplayFatalError(_("Error writing to ICS"), outError, 1); } + if(have_sent_ICS_logon == 2) { + if(ini = fopen(appData.icsLogon, "w")) { // save first two lines (presumably username & password) on init script file + fprintf(ini, "%s", message); + have_sent_ICS_logon = 3; + } else + have_sent_ICS_logon = 1; + } else if(have_sent_ICS_logon == 3) { + fprintf(ini, "%s", message); + fclose(ini); + have_sent_ICS_logon = 1; + } } else if (count < 0) { RemoveInputSource(isr); DisplayFatalError(_("Error reading from keyboard"), error, 1); @@ -2510,6 +2524,12 @@ PlotSeekAd (int i) } void +PlotSingleSeekAd (int i) +{ + PlotSeekAd(i); +} + +void AddAd (char *handle, char *rating, int base, int inc, char rated, char *type, int nr, Boolean plot) { char buf[MSG_SIZ], *ext = ""; @@ -2529,7 +2549,7 @@ AddAd (char *handle, char *rating, int base, int inc, char rated, char *type, i seekNrList[nrOfSeekAds] = nr; zList[nrOfSeekAds] = 0; seekAdList[nrOfSeekAds++] = StrSave(buf); - if(plot) PlotSeekAd(nrOfSeekAds-1); + if(plot) PlotSingleSeekAd(nrOfSeekAds-1); } } @@ -2599,7 +2619,7 @@ DrawSeekGraph () for(i=0; i<4000; i+= 100) if(i>=minRating && i= 0 && x < BOARD_LEFT || x >= BOARD_RGHT) { @@ -7288,6 +7319,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) } ClearHighlights(); fromX = fromY = -1; + MarkTargetSquares(1); DrawPosition(TRUE, boards[currentMove]); return; } @@ -7299,6 +7331,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) if (HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, appData.sweepSelect)) { SetHighlights(fromX, fromY, toX, toY); + MarkTargetSquares(1); if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat || gameInfo.variant == VariantGrand) { // [HGM] super: promotion to captured piece selected from holdings ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; @@ -7321,6 +7354,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) if(saveAnimate && !appData.animate && currentMove != oldMove && // drag-move was performed Explode(boards[currentMove-1], fromX, fromY, toX, toY)) DrawPosition(TRUE, boards[currentMove]); + MarkTargetSquares(1); fromX = fromY = -1; } appData.animate = saveAnimate; @@ -9392,8 +9426,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) ) { /* white pawn promotion */ board[toY][toX] = CharToPiece(ToUpper(promoChar)); - if(gameInfo.variant==VariantBughouse || - gameInfo.variant==VariantCrazyhouse) /* [HGM] use shadow piece */ + if((gameInfo.variant==VariantBughouse || gameInfo.variant==VariantCrazyhouse) + && PieceToChar(PROMOTED board[toY][toX]) == '~') /* [HGM] use shadow piece (if available) */ board[toY][toX] = (ChessSquare) (PROMOTED board[toY][toX]); board[fromY][fromX] = EmptySquare; } else if ((fromY >= BOARD_HEIGHT>>1) @@ -9453,8 +9487,8 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) ) { /* black pawn promotion */ board[toY][toX] = CharToPiece(ToLower(promoChar)); - if(gameInfo.variant==VariantBughouse || - gameInfo.variant==VariantCrazyhouse) /* [HGM] use shadow piece */ + if((gameInfo.variant==VariantBughouse || gameInfo.variant==VariantCrazyhouse) + && PieceToChar(PROMOTED board[toY][toX]) == '~') /* [HGM] use shadow piece (if available) */ board[toY][toX] = (ChessSquare) (PROMOTED board[toY][toX]); board[fromY][fromX] = EmptySquare; } else if ((fromY < BOARD_HEIGHT>>1) @@ -9707,9 +9741,6 @@ ShowMove (int fromX, int fromY, int toX, int toY) AnimateMove(boards[forwardMostMove - 1], fromX, fromY, toX, toY); } - if (appData.highlightLastMove) { - SetHighlights(fromX, fromY, toX, toY); - } } currentMove = forwardMostMove; } @@ -9717,6 +9748,11 @@ ShowMove (int fromX, int fromY, int toX, int toY) if (instant) return; DisplayMove(currentMove - 1); + if (!pausing || gameMode == PlayFromGameFile || gameMode == AnalyzeFile) { + if (appData.highlightLastMove) { // [HGM] moved to after DrawPosition, as with arrow it could redraw old board + SetHighlights(fromX, fromY, toX, toY); + } + } DrawPosition(FALSE, boards[currentMove]); DisplayBothClocks(); HistorySet(parseList,backwardMostMove,forwardMostMove,currentMove-1); @@ -10202,9 +10238,10 @@ GetEngineLine (char *s, int n) char buf[MSG_SIZ]; extern char *icsNames; if(!s || !*s) return 0; - NamesToList(n == 10 ? icsNames : firstChessProgramNames, command, mnemonic, "all"); + NamesToList(n >= 10 ? icsNames : firstChessProgramNames, command, mnemonic, "all"); for(i=1; mnemonic[i]; i++) if(!strcmp(s, mnemonic[i])) break; if(!mnemonic[i]) return 0; + if(n == 11) return 1; // just testing if there was a match snprintf(buf, MSG_SIZ, "-%s %s", n == 10 ? "icshost" : "fcp", command[i]); if(n == 1) SwapEngines(n); ParseArgsFromString(buf); @@ -10610,6 +10647,7 @@ GameEnds (ChessMove result, char *resultDetails, int whosays) if (*appData.savePositionFile != NULLCHAR) { SavePositionToFile(appData.savePositionFile); } + AddGameToBook(FALSE); // Only does something during Monte-Carlo book building } } @@ -11007,6 +11045,11 @@ AutoPlayGameLoop () } } +void +AnalyzeNextGame() +{ + ReloadGame(1); // next game +} int AutoPlayOneMove () @@ -11028,7 +11071,14 @@ AutoPlayOneMove () } if (currentMove >= forwardMostMove) { - if(gameMode == AnalyzeFile) { ExitAnalyzeMode(); SendToProgram("force\n", &first); } + if(gameMode == AnalyzeFile) { + if(appData.loadGameIndex == -1) { + GameEnds(EndOfFile, NULL, GE_FILE); + ScheduleDelayedEvent(AnalyzeNextGame, 10); + } else { + ExitAnalyzeMode(); SendToProgram("force\n", &first); + } + } // gameMode = EndOfGame; // ModeHighlight(); @@ -11730,6 +11780,7 @@ InitSearch () } GameInfo dummyInfo; +static int creatingBook; int GameContainsPosition (FILE *f, ListGame *lg) @@ -11872,6 +11923,9 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) gn = 1; } else { + if(gameMode == AnalyzeFile && appData.loadGameIndex == -1) + appData.loadGameIndex = 0; // [HGM] suppress error message if we reach file end after auto-stepping analysis + else DisplayError(_("Game number out of range"), 0); return FALSE; } @@ -12190,6 +12244,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) cm = (ChessMove) Myylex(); } + if(!creatingBook) { if (first.pr == NoProc) { StartChessProgram(&first); } @@ -12202,6 +12257,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) } DisplayBothClocks(); } + } /* [HGM] server: flag to write setup moves in broadcast file as one */ loadFlag = appData.suppressLoadMoves; @@ -12265,9 +12321,13 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) if (oldGameMode == AnalyzeFile || oldGameMode == AnalyzeMode) { + appData.loadGameIndex = -1; // [HGM] order auto-stepping through games + keepInfo = 1; AnalyzeFileEvent(); + keepInfo = 0; } + if(creatingBook) return TRUE; if (!matchMode && pos > 0) { ToNrEvent(pos); // [HGM] no autoplay if selected on position } else @@ -13359,6 +13419,7 @@ PauseEvent () WhiteOnMove(forwardMostMove))) { StopClocks(); } + case AnalyzeMode: pausing = TRUE; ModeHighlight(); break; @@ -13408,18 +13469,59 @@ ToggleSecond () } } +/* Toggle ShowThinking */ void +ToggleShowThinking() +{ + appData.showThinking = !appData.showThinking; + ShowThinkingEvent(); +} + +int AnalyzeModeEvent () { - if (gameMode == AnalyzeMode) { ToggleSecond(); return; } + char buf[MSG_SIZ]; + + if (!first.analysisSupport) { + snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy); + DisplayError(buf, 0); + return 0; + } + /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */ + if (appData.icsActive) { + if (gameMode != IcsObserving) { + snprintf(buf, MSG_SIZ, _("You are not observing a game")); + DisplayError(buf, 0); + /* secure check */ + if (appData.icsEngineAnalyze) { + if (appData.debugMode) + fprintf(debugFP, _("Found unexpected active ICS engine analyze \n")); + ExitAnalyzeMode(); + ModeHighlight(); + } + return 0; + } + /* if enable, user wants to disable icsEngineAnalyze */ + if (appData.icsEngineAnalyze) { + ExitAnalyzeMode(); + ModeHighlight(); + return 0; + } + appData.icsEngineAnalyze = TRUE; + if (appData.debugMode) + fprintf(debugFP, _("ICS engine analyze starting... \n")); + } + + if (gameMode == AnalyzeMode) { ToggleSecond(); return 0; } if (appData.noChessProgram || gameMode == AnalyzeMode) - return; + return 0; if (gameMode != AnalyzeFile) { if (!appData.icsEngineAnalyze) { EditGameEvent(); - if (gameMode != EditGame) return; + if (gameMode != EditGame) return 0; } + if (!appData.showThinking) ToggleShowThinking(); ResurrectChessProgram(); SendToProgram("analyze\n", &first); first.analyzing = TRUE; @@ -13435,6 +13537,7 @@ AnalyzeModeEvent () StartAnalysisClock(); GetTimeMark(&lastNodeCountTime); lastNodeCount = 0; + return 1; } void @@ -13443,9 +13546,17 @@ AnalyzeFileEvent () if (appData.noChessProgram || gameMode == AnalyzeFile) return; + if (!first.analysisSupport) { + char buf[MSG_SIZ]; + snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy); + DisplayError(buf, 0); + return; + } + if (gameMode != AnalyzeMode) { EditGameEvent(); if (gameMode != EditGame) return; + if (!appData.showThinking) ToggleShowThinking(); ResurrectChessProgram(); SendToProgram("analyze\n", &first); first.analyzing = TRUE; @@ -13462,6 +13573,7 @@ AnalyzeFileEvent () GetTimeMark(&lastNodeCountTime); lastNodeCount = 0; if(appData.timeDelay > 0) StartLoadGameTimer((long)(1000.0f * appData.timeDelay)); + AnalysisPeriodicEvent(1); } void @@ -14930,6 +15042,40 @@ HintEvent () } void +CreateBookEvent () +{ + ListGame * lg = (ListGame *) gameList.head; + FILE *f; + int nItem; + static int secondTime = FALSE; + + if( !(f = GameFile()) || ((ListGame *) gameList.tailPred)->number <= 0 ) { + DisplayError(_("Game list not loaded or empty"), 0); + return; + } + + if(!secondTime && (f = fopen(appData.polyglotBook, "r"))) { + fclose(f); + secondTime++; + DisplayNote(_("Book file exists! Try again for overwrite.")); + return; + } + + creatingBook = TRUE; + secondTime = FALSE; + + /* Get list size */ + for (nItem = 1; nItem <= ((ListGame *) gameList.tailPred)->number; nItem++){ + LoadGame(f, nItem, "", TRUE); + AddGameToBook(TRUE); + lg = (ListGame *) lg->node.succ; + } + + creatingBook = FALSE; + FlushBook(); +} + +void BookEvent () { if (appData.noChessProgram) return; @@ -15053,6 +15199,8 @@ SetGameInfo () ChessMove r = GameUnfinished; char *p = NULL; + if(keepInfo) return; + if(gameMode == EditGame) { // [HGM] vari: do not erase result on EditGame r = gameInfo.result; p = gameInfo.resultDetails; @@ -17392,3 +17540,59 @@ LoadVariation (int index, char *text) ToNrEvent(currentMove+1); } +void +LoadTheme () +{ + char *p, *q, buf[MSG_SIZ]; + if(engineLine && engineLine[0]) { // a theme was selected from the listbox + snprintf(buf, MSG_SIZ, "-theme %s", engineLine); + ParseArgsFromString(buf); + ActivateTheme(TRUE); // also redo colors + return; + } + p = nickName; + if(*p && !strchr(p, '"')) // theme name specified and well-formed; add settings to theme list + { + int len; + q = appData.themeNames; + snprintf(buf, MSG_SIZ, "\"%s\"", nickName); + if(appData.useBitmaps) { + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -ubt true -lbtf \"%s\" -dbtf \"%s\" -lbtm %d -dbtm %d", + appData.liteBackTextureFile, appData.darkBackTextureFile, + appData.liteBackTextureMode, + appData.darkBackTextureMode ); + } else { + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -ubt false -lsc %s -dsc %s", + Col2Text(2), // lightSquareColor + Col2Text(3) ); // darkSquareColor + } + if(appData.useBorder) { + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -ub true -border \"%s\"", + appData.border); + } else { + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -ub false"); + } + if(appData.useFont) { + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -upf true -pf \"%s\" -fptc \"%s\" -fpfcw %s -fpbcb %s", + appData.renderPiecesWithFont, + appData.fontToPieceTable, + Col2Text(9), // appData.fontBackColorWhite + Col2Text(10) ); // appData.fontForeColorBlack + } else { + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -upf false -pid \"%s\"", + appData.pieceDirectory); + if(!appData.pieceDirectory[0]) + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -wpc %s -bpc %s", + Col2Text(0), // whitePieceColor + Col2Text(1) ); // blackPieceColor + } + snprintf(buf+strlen(buf), MSG_SIZ-strlen(buf), " -hsc %s -phc %s\n", + Col2Text(4), // highlightSquareColor + Col2Text(5) ); // premoveHighlightColor + appData.themeNames = malloc(len = strlen(q) + strlen(buf) + 1); + if(insert != q) insert[-1] = NULLCHAR; + snprintf(appData.themeNames, len, "%s\n%s%s", q, buf, insert); + if(q) free(q); + } + ActivateTheme(FALSE); +}