Allow second engine to analyze too
authorH.G. Muller <h.g.muller@hccnet.nl>
Thu, 27 Sep 2012 17:07:58 +0000 (19:07 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Thu, 27 Sep 2012 17:27:48 +0000 (19:27 +0200)
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
backend.h
engineoutput.c
winboard/wengineoutput.c
xengineoutput.c

index 8837d97..a463fa7 100644 (file)
--- 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.
index d21379f..074ab98 100644 (file)
--- 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));
index 0752428..438564d 100644 (file)
@@ -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]);
 }
 
 
index ad34427..96d156c 100644 (file)
@@ -239,7 +239,7 @@ GetMemoLine(HWND hDlg, int x, int y)
        memo = currentPV ? IDC_EngineMemo2 : IDC_EngineMemo1;\r
        index = SendDlgItemMessage( hDlg, memo, EM_CHARFROMPOS, 0, (LPARAM) &pt );\r
        GetDlgItemText(hDlg, memo, buf, sizeof(buf));\r
-       if(LoadMultiPV(x, y, buf, index, &start, &end)) {\r
+       if(LoadMultiPV(x, y, buf, index, &start, &end, currentPV)) {\r
            SetCapture(hDlg);\r
            SendMessage( outputField[currentPV][nMemo], EM_SETSEL, (WPARAM)start, (LPARAM)end );\r
            highTextStart[currentPV] = start; highTextEnd[currentPV] = end;\r
index 5221e6a..927f2f4 100644 (file)
@@ -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;
        }