Bugfix for safeStrCpy patch for XBoard
[xboard.git] / backend.c
index d94da90..a3a06b7 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -4377,7 +4377,7 @@ ParseBoard12(string)
            strcat(parseList[moveNum - 1], " ");
            strcat(parseList[moveNum - 1], elapsed_time);
            /* currentMoveString is set as a side-effect of ParseOneMove */
-           if(gameInfo.variant == VariantShogi && currentMoveString[4]) currentMoveString[4] = '+';
+           if(gameInfo.variant == VariantShogi && currentMoveString[4]) currentMoveString[4] = '^';
            safeStrCpy(moveList[moveNum - 1], currentMoveString, sizeof(moveList[moveNum - 1])/sizeof(moveList[moveNum - 1][0]));
            strcat(moveList[moveNum - 1], "\n");
 
@@ -4884,9 +4884,6 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar)
      int *fromX, *fromY, *toX, *toY;
      char *promoChar;
 {
-    if (appData.debugMode) {
-        fprintf(debugFP, "move to parse: %s\n", move);
-    }
     *moveType = yylexstr(moveNum, move, yy_textstr, sizeof yy_textstr);
 
     switch (*moveType) {
@@ -5721,6 +5718,11 @@ HasPromotionChoice(int fromX, int fromY, int toX, int toY, char *promoChoice)
        *promoChoice = PieceToChar(BlackFerz);  // no choice
        return FALSE;
     }
+    // no sense asking what we must promote to if it is going to explode...
+    if(gameInfo.variant == VariantAtomic && boards[currentMove][toY][toX] != EmptySquare) {
+       *promoChoice = PieceToChar(BlackQueen); // Queen as good as any
+       return FALSE;
+    }
     if(autoQueen) { // predetermined
        if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantLosers)
             *promoChoice = PieceToChar(BlackKing); // in Suicide Q is the last thing we want
@@ -5733,7 +5735,7 @@ HasPromotionChoice(int fromX, int fromY, int toX, int toY, char *promoChoice)
              gameMode == IcsPlayingBlack &&  WhiteOnMove(currentMove);
     if(appData.testLegality && !premove) {
        moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
-                       fromY, fromX, toY, toX, NULLCHAR);
+                       fromY, fromX, toY, toX, gameInfo.variant == VariantShogi ? '+' : NULLCHAR);
        if(moveType != WhitePromotion && moveType  != BlackPromotion)
            return FALSE;
     }
@@ -6314,6 +6316,20 @@ MarkTargetSquares(int clear)
   DrawPosition(TRUE, NULL);
 }
 
+int
+Explode(Board board, int fromX, int fromY, int toX, int toY)
+{
+    if(gameInfo.variant == VariantAtomic &&
+       (board[toY][toX] != EmptySquare ||                     // capture?
+        toX != fromX && (board[fromY][fromX] == WhitePawn ||  // e.p. ?
+                         board[fromY][fromX] == BlackPawn   )
+      )) {
+        AnimateAtomicCapture(board, fromX, fromY, toX, toY);
+        return TRUE;
+    }
+    return FALSE;
+}
+
 void LeftClick(ClickType clickType, int xPix, int yPix)
 {
     int x, y;
@@ -6524,9 +6540,13 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
        }
        PromotionPopUp();
     } else {
+       int oldMove = currentMove;
        UserMoveEvent(fromX, fromY, toX, toY, promoChoice);
        if (!appData.highlightLastMove || gotPremove) ClearHighlights();
        if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
+       if(saveAnimate && !appData.animate && currentMove != oldMove && // drag-move was performed
+          Explode(boards[currentMove-1], fromX, fromY, toX, toY))
+           DrawPosition(TRUE, boards[currentMove]);
        fromX = fromY = -1;
     }
     appData.animate = saveAnimate;
@@ -8624,8 +8644,8 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board)
     if(promoChar == '+') {
         /* [HGM] Shogi-style promotions, to piece implied by original (Might overwrite orinary Pawn promotion) */
         board[toY][toX] = (ChessSquare) (PROMOTED piece);
-    } else if(!appData.testLegality) { // without legality testing, unconditionally believe promoChar
-        board[toY][toX] = CharToPiece(promoChar);
+    } else if(!appData.testLegality && promoChar != NULLCHAR && promoChar != '=') { // without legality testing, unconditionally believe promoChar
+        board[toY][toX] = CharToPiece(piece < BlackPawn ? ToUpper(promoChar) : ToLower(promoChar));
     }
     if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)
                && promoChar != NULLCHAR && gameInfo.holdingsSize) {
@@ -13308,7 +13328,7 @@ if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces);
     } else {
        commentList[index] = (char *) malloc(len + 6); // perhaps wastes 4...
        if(addBraces)
-         safeStrCpy(commentList[index], "{\n", sizeof(commentList[index])/sizeof(commentList[index][0]));
+         safeStrCpy(commentList[index], "{\n", 3);
        else commentList[index][0] = NULLCHAR;
        strcat(commentList[index], text);
        strcat(commentList[index], "\n");