Fix size limit on 'save as diagram'
[xboard.git] / backend.c
index 3f36345..677e21c 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1176,6 +1176,40 @@ InitBackEnd2()
 }
 
 void
+MatchEvent(int mode)
+{      // [HGM] moved out of InitBackend3, to make it callable when match starts through menu
+       /* Set up machine vs. machine match */
+       if (appData.noChessProgram) {
+           DisplayFatalError(_("Can't have a match with no chess programs"),
+                             0, 2);
+           return;
+       }
+       matchMode = mode;
+       matchGame = 1;
+       if (*appData.loadGameFile != NULLCHAR) {
+           int index = appData.loadGameIndex; // [HGM] autoinc
+           if(index<0) lastIndex = index = 1;
+           if (!LoadGameFromFile(appData.loadGameFile,
+                                 index,
+                                 appData.loadGameFile, FALSE)) {
+               DisplayFatalError(_("Bad game file"), 0, 1);
+               return;
+           }
+       } else if (*appData.loadPositionFile != NULLCHAR) {
+           int index = appData.loadPositionIndex; // [HGM] autoinc
+           if(index<0) lastIndex = index = 1;
+           if (!LoadPositionFromFile(appData.loadPositionFile,
+                                     index,
+                                     appData.loadPositionFile)) {
+               DisplayFatalError(_("Bad position file"), 0, 1);
+               return;
+           }
+       }
+       first.matchWins = second.matchWins = 0; // [HGM] match: needed in later matches\r
+       TwoMachinesEvent();
+}
+
+void
 InitBackEnd3 P((void))
 {
     GameMode initialMode;
@@ -1261,34 +1295,7 @@ InitBackEnd3 P((void))
     }
 
     if (appData.matchMode) {
-       /* Set up machine vs. machine match */
-       if (appData.noChessProgram) {
-           DisplayFatalError(_("Can't have a match with no chess programs"),
-                             0, 2);
-           return;
-       }
-       matchMode = TRUE;
-       matchGame = 1;
-       if (*appData.loadGameFile != NULLCHAR) {
-           int index = appData.loadGameIndex; // [HGM] autoinc
-           if(index<0) lastIndex = index = 1;
-           if (!LoadGameFromFile(appData.loadGameFile,
-                                 index,
-                                 appData.loadGameFile, FALSE)) {
-               DisplayFatalError(_("Bad game file"), 0, 1);
-               return;
-           }
-       } else if (*appData.loadPositionFile != NULLCHAR) {
-           int index = appData.loadPositionIndex; // [HGM] autoinc
-           if(index<0) lastIndex = index = 1;
-           if (!LoadPositionFromFile(appData.loadPositionFile,
-                                     index,
-                                     appData.loadPositionFile)) {
-               DisplayFatalError(_("Bad position file"), 0, 1);
-               return;
-           }
-       }
-       TwoMachinesEvent();
+       MatchEvent(TRUE);
     } else if (*appData.cmailGameName != NULLCHAR) {
        /* Set up cmail mode */
        ReloadCmailMsgEvent(TRUE);
@@ -6438,7 +6445,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
 {
     int x, y;
     Boolean saveAnimate;
-    static int second = 0, promotionChoice = 0;
+    static int second = 0, promotionChoice = 0, clearFlag = 0;
     char promoChoice = NULLCHAR;
     ChessSquare piece;
 
@@ -6534,7 +6541,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
                if (appData.highlightDragging) {
                    SetHighlights(fromX, fromY, -1, -1);
                }
-           }
+           } else fromX = fromY = -1;
            return;
        }
     }
@@ -6595,6 +6602,14 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
 
     if (clickType == Release && x == fromX && y == fromY) {
        DragPieceEnd(xPix, yPix); dragging = 0;
+       if(clearFlag) {
+           // a deferred attempt to click-click move an empty square on top of a piece
+           boards[currentMove][y][x] = EmptySquare;
+           ClearHighlights();
+           DrawPosition(FALSE, boards[currentMove]);
+           fromX = fromY = -1; clearFlag = 0;
+           return;
+       }
        if (appData.animateDragging) {
            /* Undo animation damage if any */
            DrawPosition(FALSE, NULL);
@@ -6614,12 +6629,20 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
        return;
     }
 
+    clearFlag = 0;
+
     /* we now have a different from- and (possibly off-board) to-square */
     /* Completed move */
     toX = x;
     toY = y;
     saveAnimate = appData.animate;
     if (clickType == Press) {
+       if(gameMode == EditPosition && boards[currentMove][fromY][fromX] == EmptySquare) {
+           // must be Edit Position mode with empty-square selected
+           fromX = x; fromY = y; DragPieceBegin(xPix, yPix); dragging = 1; // consider this a new attempt to drag
+           if(x >= BOARD_LEFT && x < BOARD_RGHT) clearFlag = 1; // and defer click-click move of empty-square to up-click
+           return;
+       }
        /* Finish clickclick move */
        if (appData.animate || appData.highlightLastMove) {
            SetHighlights(fromX, fromY, toX, toY);
@@ -12061,6 +12084,7 @@ TwoMachinesEvent P((void))
     char buf[MSG_SIZ];
     ChessProgramState *onmove;
     char *bookHit = NULL;
+    static int stalling = 0;
 
     if (appData.noChessProgram) return;
 
@@ -12097,13 +12121,23 @@ TwoMachinesEvent P((void))
     ResurrectChessProgram();   /* in case first program isn't running */
 
     if(WaitForSecond(TwoMachinesEventIfReady)) return;
-    DisplayMessage("", "");
-    InitChessProgram(&second, FALSE);
-    SendToProgram("force\n", &second);
     if(first.lastPing != first.lastPong) { // [HGM] wait till we are sure first engine has set up position
+      DisplayMessage("", _("Waiting for first chess program"));
       ScheduleDelayedEvent(TwoMachinesEvent, 10);
       return;
     }
+    if(!stalling) {
+      InitChessProgram(&second, FALSE);
+      SendToProgram("force\n", &second);
+    }
+    if(second.lastPing != second.lastPong) { // [HGM] second engine might have to reallocate hash
+      if(!stalling) DisplayMessage("", _("Waiting for second chess program"));
+      stalling = 1;
+      ScheduleDelayedEvent(TwoMachinesEvent, 10);
+      return;
+    }
+    stalling = 0;
+    DisplayMessage("", "");
     if (startedFromSetupPosition) {
        SendBoard(&second, backwardMostMove);
     if (appData.debugMode) {
@@ -14273,6 +14307,55 @@ AskQuestionEvent(title, question, replyPrefix, which)
 }
 
 void
+TypeInEvent(char firstChar)
+{
+    if ((gameMode == BeginningOfGame && !appData.icsActive) || \r
+        gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack ||\r
+       gameMode == AnalyzeMode || gameMode == EditGame || \r
+       gameMode == EditPosition || gameMode == IcsExamining ||\r
+       gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||\r
+       isdigit(firstChar) && // [HGM] movenum: allow typing in of move nr in 'passive' modes\r
+               ( gameMode == AnalyzeFile || gameMode == PlayFromGameFile ||\r
+                 gameMode == IcsObserving || gameMode == TwoMachinesPlay    ) ||\r
+       gameMode == Training) PopUpMoveDialog(firstChar);
+}
+
+void
+TypeInDoneEvent(char *move)
+{
+       Board board;
+       int n, fromX, fromY, toX, toY;
+       char promoChar;
+       ChessMove moveType;\r
+
+       // [HGM] FENedit\r
+       if(gameMode == EditPosition && ParseFEN(board, &n, move) ) {\r
+               EditPositionPasteFEN(move);\r
+               return;\r
+       }\r
+       // [HGM] movenum: allow move number to be typed in any mode\r
+       if(sscanf(move, "%d", &n) == 1 && n != 0 ) {\r
+         ToNrEvent(2*n-1);\r
+         return;\r
+       }\r
+
+      if (gameMode != EditGame && currentMove != forwardMostMove && \r
+       gameMode != Training) {\r
+       DisplayMoveError(_("Displayed move is not current"));\r
+      } else {\r
+       int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, \r
+         &moveType, &fromX, &fromY, &toX, &toY, &promoChar);\r
+       if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized\r
+       if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, \r
+         &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) {\r
+         UserMoveEvent(fromX, fromY, toX, toY, promoChar);     \r
+       } else {\r
+         DisplayMoveError(_("Could not parse move"));\r
+       }
+      }\r
+}\r
+
+void
 DisplayMove(moveNumber)
      int moveNumber;
 {