From eb0b8eabe5bf8d5139bc82bf79b88aded98d96c8 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Thu, 28 Oct 2010 17:51:34 +0200 Subject: [PATCH] Animate piece explosions in drag-drop moves and in XB This required some code restructuring: the decision if an explosion is needed is now taken in a new routine Explode() in the backend. This then calls the front-end driver, and it returns the info if there was an explosion or not, so the caller (AnimateMove() or the mouse driver) can take action to repair the damage to the board caused by the blast wave. A front-end driver for XBoard is provided as well, so that both click-click (and replay, which is the same) and drag-drop atomic captures are animated in XB as well as WB. Explosions on rejected moves are suppressed. --- backend.c | 18 ++++++++++++++++++ backend.h | 1 + frontend.h | 1 + winboard/winboard.c | 23 +++++++++++------------ xboard.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/backend.c b/backend.c index 6c18a36..16fdc62 100644 --- a/backend.c +++ b/backend.c @@ -6319,6 +6319,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; @@ -6529,9 +6543,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; diff --git a/backend.h b/backend.h index 7b39f88..0b901c1 100644 --- a/backend.h +++ b/backend.h @@ -286,6 +286,7 @@ extern char* StripHighlightAndTitle P((char *)); /* returns static data */ extern void ics_update_width P((int new_width)); extern Boolean set_cont_sequence P((char *new_seq)); extern int wrap P((char *dest, char *src, int count, int width, int *lp)); +int Explode P((Board board, int fromX, int fromY, int toX, int toY)); typedef enum { CheckBox, ComboBox, TextBox, Button, Spin, ResetButton, SaveButton, FileName, PathName, Slider, Message } Control; diff --git a/frontend.h b/frontend.h index 14fa176..8e57e58 100644 --- a/frontend.h +++ b/frontend.h @@ -191,6 +191,7 @@ void ClearHighlights P((void)); void SetPremoveHighlights P((int fromX, int fromY, int toX, int toY)); void ClearPremoveHighlights P((void)); +void AnimateAtomicCapture P((Board board, int fromX, int fromY, int toX, int toY)); void ShutDownFrontEnd P((void)); void BoardToTop P((void)); void AnimateMove P((Board board, int fromX, int fromY, int toX, int toY)); diff --git a/winboard/winboard.c b/winboard/winboard.c index 73a36b6..f818927 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -105,7 +105,6 @@ void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber); VOID NewVariantPopup(HWND hwnd); int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, /*char*/int promoChar)); -void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames); void DisplayMove P((int moveNumber)); Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); void ChatPopUp P((char *s)); @@ -3667,6 +3666,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(explodeInfo.radius) { // [HGM] atomic HBRUSH oldBrush; int x, y, r=(explodeInfo.radius * squareSize)/100; + ChessSquare piece = board[explodeInfo.fromY][explodeInfo.fromX]; board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y); x += squareSize/2; @@ -3679,6 +3679,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); DrawBoardOnDC(hdcmem, board, tmphdc); + board[explodeInfo.fromY][explodeInfo.fromX] = piece; oldBrush = SelectObject(hdcmem, explodeBrush); Ellipse(hdcmem, x-r, y-r, x+r, y+r); SelectObject(hdcmem, oldBrush); @@ -9616,26 +9617,26 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor, POINT frames[], int * nFrames); +#define kFactor 4 + void -AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames) +AnimateAtomicCapture(Board board, int fromX, int fromY, int toX, int toY) { // [HGM] atomic: animate blast wave int i; -if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY); + explodeInfo.fromX = fromX; explodeInfo.fromY = fromY; explodeInfo.toX = toX; explodeInfo.toY = toY; - for(i=1; i