Fix Seirawan gating at Rook square in PGN castling moves
[xboard.git] / backend.c
index 43d9b1f..c531656 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -952,6 +952,7 @@ SaveEngineList ()
 void
 AddToEngineList (int i)
 {
+    if(addToList) {
        int len;
        char quote, buf[MSG_SIZ];
        char *q = firstChessProgramNames, *p = newEngineCommand;
@@ -975,6 +976,7 @@ AddToEngineList (int i)
        SaveEngineList();
        FloatToFront(&appData.recentEngineList, buf);
        ASSIGN(currentEngine[i], buf);
+    }
 }
 
 void
@@ -983,7 +985,7 @@ LoadEngine ()
     int i;
     if(WaitForEngine(savCps, LoadEngine)) return;
     if(tryNr == 1 && !isUCI) { SendToProgram("uci\n", savCps); tryNr = 2; ScheduleDelayedEvent(LoadEngine, FEATURE_TIMEOUT); return; }
-    if(tryNr) v1 = (tryNr == 2), tryNr = 0, AddToEngineList(0); // deferred to after protocol determination
+    if(tryNr) v1 |= (tryNr == 2), tryNr = 0, AddToEngineList(0); // deferred to after protocol determination
     CommonEngineInit(); // recalculate time odds
     if(gameInfo.variant != StringToVariant(appData.variant)) {
        // we changed variant when loading the engine; this forces us to reset
@@ -1012,7 +1014,7 @@ ReplaceEngine (ChessProgramState *cps, int n)
     appData.clockMode = TRUE;
     InitEngine(cps, n);
     UpdateLogos(TRUE);
-    if(n) return; // only startup first engine immediately; second can wait
+    if(n && !tryNr) return; // only startup first engine immediately; second can wait (unless autodetect)
     savCps = cps; // parameter to LoadEngine passed as globals, to allow scheduled calling :-(
     LoadEngine();
 }
@@ -1060,13 +1062,14 @@ Load (ChessProgramState *cps, int i)
     }
     if(jar) { snprintf(buf3, MSG_SIZ, "java -jar %s", p); p = buf3; }
     ASSIGN(appData.chessProgram[i], p);
+    tryNr = 3; // requests adding to list without auto-detect
+    if(isUCI == 3) tryNr = 1, isUCI = 0; // auto-detect
     appData.isUCI[i] = isUCI;
     appData.protocolVersion[i] = v1 ? 1 : PROTOVER;
     appData.hasOwnBookUCI[i] = hasBook;
     if(!nickName[0]) useNick = FALSE;
     if(useNick) ASSIGN(appData.pgnName[i], nickName);
     safeStrCpy(newEngineCommand, p, MSG_SIZ);
-    tryNr = 1;
     ReplaceEngine(cps, i);
 }
 
@@ -9054,7 +9057,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
                 GameEnds(cps->twoMachinesColor[0] == 'w' ? BlackWins : WhiteWins,
                            buf1, GE_XBOARD);
                return;
-           } else if(!appData.fischerCastling)
+           } else if(!appData.fischerCastling && toX != BOARD_WIDTH>>1)
            /* [HGM] Kludge to handle engines that send FRC-style castling
               when they shouldn't (like TSCP-Gothic) */
            switch(moveType) {
@@ -9245,7 +9248,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
        cps->useSigterm = FALSE;
     }
     if (strncmp(message, "feature ", 8) == 0) { // [HGM] moved forward to pre-empt non-compliant commands
-      ParseFeatures(message+8, cps); if(tryNr < 3) tryNr = 3;
+      ParseFeatures(message+8, cps); if(tryNr && tryNr < 3) tryNr = 3;
       return; // [HGM] This return was missing, causing option features to be recognized as non-compliant commands!
     }
 
@@ -9457,8 +9460,9 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
        return;
     }
     if(strncmp(message, "uciok", 5) == 0) { // response to "uci" probe
-       appData.isUCI[0] = isUCI = 1;
-       ReplaceEngine(&first, 0); // retry install as UCI
+       int nr = (cps == &second);
+       appData.isUCI[nr] = isUCI = 1;
+       ReplaceEngine(cps, nr); // retry install as UCI
        return;
     }
     /*
@@ -11401,6 +11405,7 @@ SaveEngineSettings (int n)
 {
     int len; char *p, *q, *s, buf[MSG_SIZ], *optionSettings;
     if(!currentEngine[n] || !currentEngine[n][0]) { DisplayMessage("saving failed: engine not from list", ""); return; } // no engine from list is loaded
+    if(*engineListFile) ParseSettingsFile(engineListFile, &engineListFile); // update engine list
     p = strstr(firstChessProgramNames, currentEngine[n]);
     if(!p) { DisplayMessage("saving failed: engine not found in list", ""); return; } // sanity check; engine could be deleted from list after loading
     optionSettings = ResendOptions(n ? &second : &first, FALSE);
@@ -11420,6 +11425,7 @@ SaveEngineSettings (int n)
     s = malloc(len);
     snprintf(s, len, "%s%s%s", firstChessProgramNames, currentEngine[n], q);
     FREE(firstChessProgramNames); firstChessProgramNames = s; // new list
+    if(*engineListFile) SaveEngineList();
 }
 
 // following implemented as macro to avoid type limitations