#include "backend.h"
#include "moves.h"
#include "board.h"
+#include "draw.h"
#ifdef __EMX__
AnimState anims[NrOfAnims];
static void DrawSquare P((int row, int column, ChessSquare piece, int do_flash));
+static Boolean IsDrawArrowEnabled P((void));
+static void DrawArrowHighlight P((int fromX, int fromY, int toX,int toY));
+static void ArrowDamage P((int s_col, int s_row, int d_col, int d_row));
static void
drawHighlight (int file, int rank, int type)
(squareSize + lineGap);
}
- DrawBorder(x,y, type);
+ DrawBorder(x,y, type, lineGap & 1); // pass whether lineGap is odd
}
int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1;
void
SetHighlights (int fromX, int fromY, int toX, int toY)
{
+ int arrow = hi2X >= 0 && hi1Y >= 0 && IsDrawArrowEnabled();
+
if (hi1X != fromX || hi1Y != fromY) {
if (hi1X >= 0 && hi1Y >= 0) {
drawHighlight(hi1X, hi1Y, 0);
drawHighlight(hi2X, hi2Y, 0);
}
}
+
+ if(arrow) // there currently is an arrow displayed
+ ArrowDamage(hi1X, hi1Y, hi2X, hi2Y); // mark which squares it damaged
+
if (hi1X != fromX || hi1Y != fromY) {
if (fromX >= 0 && fromY >= 0) {
drawHighlight(fromX, fromY, 1);
}
}
- if(toX<0) // clearing the highlights must have damaged arrow
- DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y); // for now, redraw it (should really be cleared!)
-
hi1X = fromX;
hi1Y = fromY;
hi2X = toX;
hi2Y = toY;
+
+ if(arrow || toX >= 0 && fromY >= 0 && IsDrawArrowEnabled())
+ DrawPosition(FALSE, NULL); // repair any arrow damage, or draw a new one
}
void
FrameDelay(appData.animSpeed);
}
board[fromY][toY] = piece;
+ DrawGrid();
}
/* Main control logic for deciding what to animate and how */
if(Explode(board, fromX, fromY, toX, toY)) { // mark as damaged
int i,j;
for(i=0; i<BOARD_WIDTH; i++) for(j=0; j<BOARD_HEIGHT; j++)
- if((i-toX)*(i-toX) + (j-toY)*(j-toY) < 6) damage[0][j][i] = True;
+ if((i-toX)*(i-toX) + (j-toY)*(j-toY) < 6) damage[0][j][i] |= 1 + ((i-toX ^ j-toY) & 1);
}
/* Be sure end square is redrawn */
- damage[0][toY][toX] = True;
+ damage[0][toY][toX] |= True;
}
void
if (do_flash && piece != EmptySquare && appData.flashCount > 0) {
for (i=0; i<appData.flashCount; ++i) {
DrawOneSquare(x, y, piece, square_color, 0, string, 0);
+ GraphExpose(currBoard, x, y, squareSize, squareSize);
FlashDelay(flash_delay);
DrawOneSquare(x, y, EmptySquare, square_color, 0, string, 0);
+ GraphExpose(currBoard, x, y, squareSize, squareSize);
FlashDelay(flash_delay);
}
}
void
DrawPosition (int repaint, Board board)
{
- int i, j, do_flash;
+ int i, j, do_flash, exposeAll = False;
static int lastFlipView = 0;
static int lastBoardValid[2] = {0, 0};
static Board lastBoard[2];
- Arg args[16];
+ static char lastMarker[BOARD_RANKS][BOARD_FILES];
int rrow, rcol;
int nr = twoBoards*partnerUp;
if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) {
- if ( lineGap && IsDrawArrowEnabled())
- DrawGrid();
+// if ( lineGap && IsDrawArrowEnabled())
+// DrawGrid();
/* If too much changes (begin observing new game, etc.), don't
do flashing */
and the rook (just flash the king). */
if (do_flash) {
if (check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) {
- /* Draw rook with NO flashing. King will be drawn flashing later */
- DrawSquare(rrow, rcol, board[rrow][rcol], 0);
- lastBoard[nr][rrow][rcol] = board[rrow][rcol];
+ /* Mark rook for drawing with NO flashing. */
+ damage[nr][rrow][rcol] |= 1;
}
}
is flashing on its new square */
for (i = 0; i < BOARD_HEIGHT; i++)
for (j = 0; j < BOARD_WIDTH; j++)
- if ((board[i][j] != lastBoard[nr][i][j] && board[i][j] == EmptySquare)
+ if (((board[i][j] != lastBoard[nr][i][j] || !nr && marker[i][j] != lastMarker[i][j]) && board[i][j] == EmptySquare)
|| damage[nr][i][j]) {
DrawSquare(i, j, board[i][j], 0);
- damage[nr][i][j] = False;
+ if(damage[nr][i][j] & 2) {
+ drawHighlight(j, i, 0); // repair arrow damage
+ damage[nr][i][j] = False; // this flushed the square as well
+ } else damage[nr][i][j] = 1; // mark for expose
}
/* Second pass -- Draw piece(s) in new position and flash them */
for (i = 0; i < BOARD_HEIGHT; i++)
for (j = 0; j < BOARD_WIDTH; j++)
- if (board[i][j] != lastBoard[nr][i][j]) {
+ if (board[i][j] != lastBoard[nr][i][j] || !nr && marker[i][j] != lastMarker[i][j]) {
DrawSquare(i, j, board[i][j], do_flash);
+ damage[nr][i][j] = 1; // mark for expose
}
} else {
if (lineGap > 0)
DrawSquare(i, j, board[i][j], 0);
damage[nr][i][j] = False;
}
+
+ exposeAll = True;
}
CopyBoard(lastBoard[nr], board);
lastBoardValid[nr] = 1;
if(nr == 0) { // [HGM] dual: no highlights on second board yet
lastFlipView = flipView;
+ for (i = 0; i < BOARD_HEIGHT; i++)
+ for (j = 0; j < BOARD_WIDTH; j++)
+ lastMarker[i][j] = marker[i][j];
/* Draw highlights */
if (pm1X >= 0 && pm1Y >= 0) {
drawHighlight(pm1X, pm1Y, 2);
+ damage[nr][pm1Y][pm1X] = False;
}
if (pm2X >= 0 && pm2Y >= 0) {
drawHighlight(pm2X, pm2Y, 2);
+ damage[nr][pm2Y][pm2X] = False;
}
if (hi1X >= 0 && hi1Y >= 0) {
drawHighlight(hi1X, hi1Y, 1);
+ damage[nr][hi1Y][hi1X] = False;
}
if (hi2X >= 0 && hi2Y >= 0) {
drawHighlight(hi2X, hi2Y, 1);
+ damage[nr][hi2Y][hi2X] = False;
}
DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y);
}
/* If piece being dragged around board, must redraw that too */
DrawDragPiece();
+ if(exposeAll)
+ GraphExpose(currBoard, 0, 0, BOARD_WIDTH*(squareSize + lineGap) + lineGap, BOARD_HEIGHT*(squareSize + lineGap) + lineGap);
+ else {
+ for (i = 0; i < BOARD_HEIGHT; i++)
+ for (j = 0; j < BOARD_WIDTH; j++)
+ if(damage[nr][i][j]) {
+ int x, y;
+ if (flipView) {
+ x = lineGap + ((BOARD_WIDTH-1)-j) *
+ (squareSize + lineGap);
+ y = lineGap + i * (squareSize + lineGap);
+ } else {
+ x = lineGap + j * (squareSize + lineGap);
+ y = lineGap + ((BOARD_HEIGHT-1)-i) *
+ (squareSize + lineGap);
+ }
+ if(damage[nr][i][j] & 2) // damage by old or new arrow
+ GraphExpose(currBoard, x - lineGap, y - lineGap, squareSize + 2*lineGap, squareSize + 2*lineGap);
+ else
+ GraphExpose(currBoard, x, y, squareSize, squareSize);
+ damage[nr][i][j] &= ~2; // remember damage by newly drawn error in '2' bit, to schedule it for erasure next draw
+ }
+ }
+
FlashDelay(0); // this flushes drawing queue;
if(nr) SwitchWindow();
}
}
/* Draw an arrow between two points using current settings */
-void
+static void
DrawArrowBetweenPoints (int s_x, int s_y, int d_x, int d_y)
{
Pnt arrow[8];
// Polygon( hdc, arrow, 7 );
}
-void
+static void
ArrowDamage (int s_col, int s_row, int d_col, int d_row)
{
int hor, vert, i, n = partnerUp * twoBoards;
hor = 64*s_col + 32; vert = 64*s_row + 32;
for(i=0; i<= 64; i++) {
- damage[n][vert+6>>6][hor+6>>6] = True;
- damage[n][vert-6>>6][hor+6>>6] = True;
- damage[n][vert+6>>6][hor-6>>6] = True;
- damage[n][vert-6>>6][hor-6>>6] = True;
+ damage[n][vert+6>>6][hor+6>>6] |= 2;
+ damage[n][vert-6>>6][hor+6>>6] |= 2;
+ damage[n][vert+6>>6][hor-6>>6] |= 2;
+ damage[n][vert-6>>6][hor-6>>6] |= 2;
hor += d_col - s_col; vert += d_row - s_row;
}
}
/* [AS] Draw an arrow between two squares */
-void
+static void
DrawArrowBetweenSquares (int s_col, int s_row, int d_col, int d_row)
{
int s_x, s_y, d_x, d_y;
ArrowDamage(s_col, s_row, d_col, d_row);
}
-Boolean
+static Boolean
IsDrawArrowEnabled ()
{
return (appData.highlightMoveWithArrow || twoBoards && partnerUp) && squareSize >= 32;
}
-void
+static void
DrawArrowHighlight (int fromX, int fromY, int toX,int toY)
{
if( IsDrawArrowEnabled() && fromX >= 0 && fromY >= 0 && toX >= 0 && toY >= 0)