animate explosions in variant atomic (if animate moves is on).
authorH.G. Muller <h.g.muller@hccnet.nl>
Thu, 11 Jun 2009 04:32:22 +0000 (21:32 -0700)
committerArun Persaud <arun@nubati.net>
Thu, 11 Jun 2009 04:32:22 +0000 (21:32 -0700)
winboard/winboard.c

index f4e6c0d..7d8c272 100644 (file)
@@ -103,6 +103,7 @@ void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber);
 VOID NewVariantPopup(HWND hwnd);\r
 int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,\r
                   /*char*/int promoChar));\r
+void AnimateAtomicCapture(int toX, int toY, int nFrames);\r
 \r
 typedef struct {\r
   ChessSquare piece;  \r
@@ -130,6 +131,12 @@ typedef struct {
 static HighlightInfo highlightInfo        = { {{-1, -1}, {-1, -1}} };\r
 static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} };\r
 \r
+typedef struct { // [HGM] atomic\r
+  int x, y, radius;\r
+} ExplodeInfo;\r
+\r
+static ExplodeInfo explodeInfo = {0, 0, 0};\r
+\r
 /* Window class names */\r
 char szAppName[] = "WinBoard";\r
 char szConsoleName[] = "WBConsole";\r
@@ -181,6 +188,7 @@ static HWND hwndPause;    /* pause button */
 static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred to bP in stead of wK */\r
 static HBRUSH lightSquareBrush, darkSquareBrush,\r
   blackSquareBrush, /* [HGM] for band between board and holdings */\r
+  explodeBrush,     /* [HGM] atomic */\r
   whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/;\r
 static POINT gridEndpoints[(BOARD_SIZE + 1) * 4];\r
 static DWORD gridVertexCounts[(BOARD_SIZE + 1) * 2];\r
@@ -3012,7 +3020,7 @@ InitDrawingColors()
   whitePieceBrush = CreateSolidBrush(whitePieceColor);\r
   blackPieceBrush = CreateSolidBrush(blackPieceColor);\r
   iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));\r
-\r
+  explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic\r
   /* [AS] Force rendering of the font-based pieces */\r
   if( fontBitmapSquareSize > 0 ) {\r
     fontBitmapSquareSize = 0;\r
@@ -4473,14 +4481,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
       x2 = boardRect.left + animInfo.pos.x;\r
       y2 = boardRect.top + animInfo.pos.y;\r
       clips[num_clips++] = CreateRectRgn(MIN(x,x2), MIN(y,y2), MAX(x,x2)+squareSize, MAX(y,y2)+squareSize);\r
-      /* Slight kludge.  The real problem is that after AnimateMove is\r
-        done, the position on the screen does not match lastDrawn.\r
-        This currently causes trouble only on e.p. captures in\r
-        atomic, where the piece moves to an empty square and then\r
-        explodes.  The old and new positions both had an empty square\r
-        at the destination, but animation has drawn a piece there and\r
-        we have to remember to erase it. */\r
-      lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
+      /* [HGM] old location of "slight kludge" below */\r
     }\r
   }\r
 \r
@@ -4498,10 +4499,27 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
   }\r
 \r
   /* Do all the drawing to the memory DC */\r
-  DrawGridOnDC(hdcmem);\r
-  DrawHighlightsOnDC(hdcmem);\r
-  DrawBoardOnDC(hdcmem, board, tmphdc);\r
-\r
+  if(explodeInfo.radius) { // [HGM] atomic\r
+       HBRUSH oldBrush;\r
+       int x, y, r=(explodeInfo.radius * squareSize)/100;\r
+       SquareToPos(explodeInfo.y, explodeInfo.x, &x, &y);\r
+       x += squareSize/2;\r
+       y += squareSize/2;\r
+        if(!fullrepaint) {\r
+         clips[num_clips] = CreateRectRgn(x-r, y-r, x+r, y+r);\r
+         ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR);\r
+       }\r
+       DrawGridOnDC(hdcmem);\r
+       DrawHighlightsOnDC(hdcmem);\r
+       DrawBoardOnDC(hdcmem, board, tmphdc);\r
+       oldBrush = SelectObject(hdcmem, explodeBrush);\r
+       Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
+       SelectObject(hdcmem, oldBrush);\r
+  } else {\r
+    DrawGridOnDC(hdcmem);\r
+    DrawHighlightsOnDC(hdcmem);\r
+    DrawBoardOnDC(hdcmem, board, tmphdc);\r
+  }\r
   if(logoHeight) {\r
        DrawLogoOnDC(hdc, leftLogoRect, flipClock ? &second : &first);\r
        DrawLogoOnDC(hdc, rightLogoRect, flipClock ? &first : &second);\r
@@ -4540,6 +4558,14 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
     DrawPieceOnDC(hdcmem, animInfo.piece,\r
                  ((int) animInfo.piece < (int) BlackPawn),\r
                   (animInfo.from.y + animInfo.from.x) % 2, x, y, tmphdc);\r
+      /* Slight kludge.  The real problem is that after AnimateMove is\r
+        done, the position on the screen does not match lastDrawn.\r
+        This currently causes trouble only on e.p. captures in\r
+        atomic, where the piece moves to an empty square and then\r
+        explodes.  The old and new positions both had an empty square\r
+        at the destination, but animation has drawn a piece there and\r
+        we have to remember to erase it. [HGM] moved until after setting lastDrawn */\r
+      lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
   }\r
 \r
   /* Release the bufferBitmap by selecting in the old bitmap \r
@@ -5026,7 +5052,11 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                    break;\r
                  } else\r
                PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */\r
-        } else FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
+          } else {\r
+           if(saveAnimate /* ^$!%@#$!$ */  && gameInfo.variant == VariantAtomic \r
+                       && boards[currentMove][toY][toX] != EmptySquare) AnimateAtomicCapture(toX, toY, 20);\r
+           FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
+         }\r
       }\r
       if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
       appData.animate = saveAnimate;\r
@@ -10556,6 +10586,22 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor,
      POINT frames[], int * nFrames);\r
 \r
 \r
+void\r
+AnimateAtomicCapture(int toX, int toY, int nFrames)\r
+{      // [HGM] atomic: animate blast wave\r
+       int i;\r
+if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY);\r
+       explodeInfo.x = toX;\r
+       explodeInfo.y = toY;\r
+       for(i=0; i<nFrames; i++) {\r
+           explodeInfo.radius = (i*180)/(nFrames-1);\r
+           DrawPosition(FALSE, NULL);\r
+           Sleep(appData.animSpeed);\r
+       }\r
+       explodeInfo.radius = 0;\r
+       DrawPosition(TRUE, NULL);\r
+}\r
+\r
 #define kFactor 4\r
 \r
 void\r
@@ -10616,6 +10662,8 @@ AnimateMove(board, fromX, fromY, toX, toY)
   animInfo.pos = finish;\r
   DrawPosition(FALSE, NULL);\r
   animInfo.piece = EmptySquare;\r
+  if(gameInfo.variant == VariantAtomic && board[toY][toX] != EmptySquare)\r
+    AnimateAtomicCapture(toX, toY, 2*nFrames);\r
 }\r
 \r
 /*      Convert board position to corner of screen rect and color       */\r