From f38964b851874781439f481fd00b3eef6f592603 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Thu, 27 Sep 2012 19:07:58 +0200 Subject: [PATCH] Allow second engine to analyze too Clicking the Analysis menu when analysis is already in progress will now toggle the secon engine to analyze the same position. For now, this lasts only until the position changes (or you leave analyze mode), after which the second engine is always switched off, and the Engine Output window returns to single pane. Each pane now has its own header line; the exclude header is suppressed in the second pane. --- backend.c | 37 ++++++++++++++++++++++++++++++++----- backend.h | 2 +- engineoutput.c | 21 ++++++++++++--------- winboard/wengineoutput.c | 2 +- xengineoutput.c | 2 +- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/backend.c b/backend.c index 8837d97..a463fa7 100644 --- a/backend.c +++ b/backend.c @@ -222,6 +222,7 @@ int Pairing P((int nr, int nPlayers, int *w, int *b, int *sync)); FILE *WriteTourneyFile P((char *results, FILE *f)); void DisplayTwoMachinesTitle P(()); static void ExcludeClick P((int index)); +void ToggleSecond P((void)); #ifdef WIN32 extern void ConsoleCreate(); @@ -4905,6 +4906,7 @@ AnalysisPeriodicEvent (int force) /* Send . command to Crafty to collect stats */ SendToProgram(".\n", &first); + if(second.analyzing) SendToProgram(".\n", &second); /* Don't send another until we get a response (this makes us stop sending to old Crafty's which don't understand @@ -5447,10 +5449,11 @@ MultiPV (ChessProgramState *cps) } Boolean -LoadMultiPV (int x, int y, char *buf, int index, int *start, int *end) +LoadMultiPV (int x, int y, char *buf, int index, int *start, int *end, int pane) { int startPV, multi, lineStart, origIndex = index; char *p, buf2[MSG_SIZ]; + ChessProgramState *cps = (pane ? &second : &first); if(index < 0 || index >= strlen(buf)) return FALSE; // sanity lastX = x; lastY = y; @@ -5462,12 +5465,12 @@ LoadMultiPV (int x, int y, char *buf, int index, int *start, int *end) 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; - if(lineStart == 0 && gameMode == AnalyzeMode && (multi = MultiPV(&first)) >= 0) { - int n = first.option[multi].value; + if(lineStart == 0 && gameMode == AnalyzeMode && (multi = MultiPV(cps)) >= 0) { + int n = cps->option[multi].value; if(origIndex > 17 && origIndex < 24) { if(n>1) n--; } else if(origIndex > index - 6) n++; snprintf(buf2, MSG_SIZ, "option MultiPV=%d\n", n); - if(first.option[multi].value != n) SendToProgram(buf2, &first); - first.option[multi].value = n; + if(cps->option[multi].value != n) SendToProgram(buf2, cps); + cps->option[multi].value = n; *start = *end = 0; return FALSE; } else if(strstr(buf+lineStart, "exclude:") == buf+lineStart) { // exclude moves clicked @@ -6852,6 +6855,7 @@ FinishMove (ChessMove moveType, int fromX, int fromY, int toX, int toY, int prom } /* Relay move to ICS or chess engine */ + if(second.analyzing) ToggleSecond(); // for now, we just stop second analyzing engine if (appData.icsActive) { if (gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack || gameMode == IcsExamining) { @@ -13377,8 +13381,25 @@ EditTagsEvent () } void +ToggleSecond () +{ + if(second.analyzing) { + SendToProgram("exit\n", &second); + second.analyzing = FALSE; + } else { + if (second.pr == NoProc) StartChessProgram(&second); + InitChessProgram(&second, FALSE); + FeedMovesToProgram(&second, currentMove); + + SendToProgram("analyze\n", &second); + second.analyzing = TRUE; + } +} + +void AnalyzeModeEvent () { + if (gameMode == AnalyzeMode) { ToggleSecond(); return; } if (appData.noChessProgram || gameMode == AnalyzeMode) return; @@ -13979,6 +14000,10 @@ ExitAnalyzeMode () SendToProgram("exit\n", &first); first.analyzing = FALSE; } + if (second.analyzing) { + SendToProgram("exit\n", &second); + second.analyzing = FALSE; + } thinkOutput[0] = NULLCHAR; } @@ -14561,6 +14586,7 @@ ForwardInner (int target) if (gameMode == EditGame || gameMode == AnalyzeMode || gameMode == Training || gameMode == PlayFromGameFile || gameMode == AnalyzeFile) { + if(target != currentMove && second.analyzing) ToggleSecond(); // for now, we just stop second analyzing engine while (currentMove < target) { SendMoveToProgram(currentMove++, &first); } @@ -14665,6 +14691,7 @@ BackwardInner (int target) } if (gameMode == EditGame || gameMode==AnalyzeMode || gameMode == PlayFromGameFile || gameMode == AnalyzeFile) { + if(target != currentMove && second.analyzing) ToggleSecond(); // for now, we just stop second analyzing engine while (currentMove > target) { if(moveList[currentMove-1][1] == '@' && moveList[currentMove-1][0] == '@') { // null move cannot be undone. Reload program with move history before it. diff --git a/backend.h b/backend.h index d21379f..074ab98 100644 --- a/backend.h +++ b/backend.h @@ -232,7 +232,7 @@ void OutputChatMessage P((int partner, char *mess)); void EditPositionDone P((Boolean fakeRights)); Boolean GetArgValue P((char *name)); Boolean LoadPV P((int x, int y)); -Boolean LoadMultiPV P((int x, int y, char *buf, int index, int *start, int *end)); +Boolean LoadMultiPV P((int x, int y, char *buf, int index, int *start, int *end, int pane)); void UnLoadPV P(()); void MovePV P((int x, int y, int h)); int PromoScroll P((int x, int y)); diff --git a/engineoutput.c b/engineoutput.c index 0752428..438564d 100644 --- a/engineoutput.c +++ b/engineoutput.c @@ -89,7 +89,7 @@ static int lastDepth[2] = { -1, -1 }; static int lastForwardMostMove[2] = { -1, -1 }; static int engineState[2] = { -1, -1 }; static char lastLine[2][MSG_SIZ]; -static char header[MSG_SIZ]; +static char header[2][MSG_SIZ]; #define MAX_VAR 400 static int scores[MAX_VAR], textEnd[MAX_VAR], keys[MAX_VAR], curDepth[2], nrVariations[2]; @@ -223,14 +223,15 @@ SetProgramStats (FrontEndProgramStats * stats) // now directly called by back-en if( clearMemo ) { DoClearMemo(which); nrVariations[which] = 0; - header[0] = NULLCHAR; + header[which][0] = NULLCHAR; if(gameMode == AnalyzeMode) { - if((multi = MultiPV(&first)) >= 0) { - snprintf(header, MSG_SIZ, "\t%s viewpoint\t\tfewer / Multi-PV setting = %d / more\n", - appData.whitePOV || appData.scoreWhite ? "white" : "mover", first.option[multi].value); + ChessProgramState *cps = (which ? &second : &first); + if((multi = MultiPV(cps)) >= 0) { + snprintf(header[which], MSG_SIZ, "\t%s viewpoint\t\tfewer / Multi-PV setting = %d / more\n", + appData.whitePOV || appData.scoreWhite ? "white" : "mover", cps->option[multi].value); } - snprintf(header+strlen(header), MSG_SIZ-strlen(header), "%s", exclusionHeader); - InsertIntoMemo( which, header, 0); + if(!which) snprintf(header[which]+strlen(header[which]), MSG_SIZ-strlen(header[which]), "%s", exclusionHeader); + InsertIntoMemo( which, header[which], 0); } else if(appData.ponderNextMove && lastLine[which][0]) { InsertIntoMemo( which, lastLine[which], 0 ); @@ -347,12 +348,14 @@ VerifyDisplayMode () switch( gameMode ) { case IcsObserving: // [HGM] ICS analyze if(!appData.icsEngineAnalyze) return; - case AnalyzeMode: case AnalyzeFile: case MachinePlaysWhite: case MachinePlaysBlack: mode = 0; break; + case AnalyzeMode: + mode = second.analyzing; + break; case IcsPlayingWhite: case IcsPlayingBlack: mode = appData.zippyPlay && opponentKibitzes; // [HGM] kibitz @@ -420,7 +423,7 @@ InsertionPoint (int len, EngineOutputData *ed) scores[n] = newScore; } nrVariations[n] += 2; - return offs + (gameMode == AnalyzeMode)*strlen(header); + return offs + (gameMode == AnalyzeMode)*strlen(header[ed->which]); } diff --git a/winboard/wengineoutput.c b/winboard/wengineoutput.c index ad34427..96d156c 100644 --- a/winboard/wengineoutput.c +++ b/winboard/wengineoutput.c @@ -239,7 +239,7 @@ GetMemoLine(HWND hDlg, int x, int y) memo = currentPV ? IDC_EngineMemo2 : IDC_EngineMemo1; index = SendDlgItemMessage( hDlg, memo, EM_CHARFROMPOS, 0, (LPARAM) &pt ); GetDlgItemText(hDlg, memo, buf, sizeof(buf)); - if(LoadMultiPV(x, y, buf, index, &start, &end)) { + if(LoadMultiPV(x, y, buf, index, &start, &end, currentPV)) { SetCapture(hDlg); SendMessage( outputField[currentPV][nMemo], EM_SETSEL, (WPARAM)start, (LPARAM)end ); highTextStart[currentPV] = start; highTextEnd[currentPV] = end; diff --git a/xengineoutput.c b/xengineoutput.c index 5221e6a..927f2f4 100644 --- a/xengineoutput.c +++ b/xengineoutput.c @@ -184,7 +184,7 @@ SelectPV (Widget w, XEvent * event, String * params, Cardinal * nParams) XtSetArg(arg, XtNstring, &val); XtGetValues(w, &arg, 1); shiftKey = strcmp(params[0], "0"); - if(LoadMultiPV(x, y, val, index, &start, &end)) { + if(LoadMultiPV(x, y, val, index, &start, &end, currentPV)) { XawTextSetSelection( w, start, end ); highTextStart[currentPV] = start; highTextEnd[currentPV] = end; } -- 1.7.0.4