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);
- }
- } // [HGM] first erase both, then draw new!
+{ // [HGM] schedule old for erasure, and leave drawing new to DrawPosition
+ int change = 0;
- if (hi2X != toX || hi2Y != toY) {
- if (hi2X >= 0 && hi2Y >= 0) {
- drawHighlight(hi2X, hi2Y, 0);
+ if (hi1X >= 0 && hi1Y >= 0) {
+ if (hi1X != fromX || hi1Y != fromY) {
+ damage[0][hi1Y][hi1X] |= 2;
+ change |= 1;
}
+ change |= 4;
}
- 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 (hi2X != toX || hi2Y != toY) {
- if (toX >= 0 && toY >= 0) {
- drawHighlight(toX, toY, 1);
+ if (hi2X >= 0 && hi2Y >= 0) {
+ if (hi2X != toX || hi2Y != toY) {
+ damage[0][hi2Y][hi2X] |= 2;
+ change |= 2;
}
+ change |= 8;
}
+ if(change > 12 && IsDrawArrowEnabled()) ArrowDamage(hi1X, hi1Y, hi2X, hi2Y);
+
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
{
if (pm1X != fromX || pm1Y != fromY) {
if (pm1X >= 0 && pm1Y >= 0) {
- drawHighlight(pm1X, pm1Y, 0);
- }
- if (fromX >= 0 && fromY >= 0) {
- drawHighlight(fromX, fromY, 2);
+ damage[0][pm1Y][pm1X] |= 2;
}
}
if (pm2X != toX || pm2Y != toY) {
if (pm2X >= 0 && pm2Y >= 0) {
- drawHighlight(pm2X, pm2Y, 0);
- }
- if (toX >= 0 && toY >= 0) {
- drawHighlight(toX, toY, 2);
+ damage[0][pm2Y][pm2X] |= 2;
}
}
pm1X = fromX;
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;
+ /* Be sure end square is redrawn, with piece in it */
+ damage[0][toY][toX] |= 4;
if(toX == x2 && toY == kill2Y) { fromX = toX; fromY = toY; toX = killX; toY = killY; x2 = -1; goto again; } // second leg
if(toX != x || toY != y) { fromX = toX; fromY = toY; toX = x; toY = y; goto again; } // second leg
/* Mark this square as needing to be redrawn. Note that
we don't remove the piece though, since logically (ie
as seen by opponent) the move hasn't been made yet. */
- damage[0][boardY][boardX] = True;
+ damage[0][boardY][boardX] |= True;
} else {
anims[Player].dragActive = False;
}
DrawOneSquare(anims[Player].startSquare.x, anims[Player].startSquare.y,
EmptySquare, anims[Player].startColor, 0, NULL, NULL, 0);
AnimationFrame(Player, &anims[Player].prevFrame, anims[Player].dragPiece);
- damage[0][anims[Player].startBoardY][anims[Player].startBoardX] = TRUE;
+ damage[0][anims[Player].startBoardY][anims[Player].startBoardX] |= TRUE;
}
static void
for (i=0; i<appData.flashCount; ++i) {
DrawOneSquare(x, y, piece, square_color, 0, tString, bString, 0);
GraphExpose(currBoard, x, y, squareSize, squareSize);
+ DoEvents(); // requires event processing to actually update screen :-(
FlashDelay(flash_delay);
DrawOneSquare(x, y, EmptySquare, square_color, 0, tString, bString, 0);
GraphExpose(currBoard, x, y, squareSize, squareSize);
+ DoEvents();
FlashDelay(flash_delay);
}
}
}
void
+SquareExpose(int i, int j, int d)
+{
+ 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);
+ }
+ GraphExpose(currBoard, x-d, y-d, squareSize+2*d, squareSize+2*d);
+}
+
+void
DrawPosition (int repaint, Board board)
{
int i, j, do_flash, exposeAll = False;
static int lastBoardValid[2] = {0, 0};
static Board lastBoard[2];
static char lastMarker[BOARD_RANKS][BOARD_FILES], messedUp;
- int rrow, rcol;
+ int rrow = -1, rcol = -1;
int nr = twoBoards*partnerUp;
repaint |= messedUp;
if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) {
-// if ( lineGap && IsDrawArrowEnabled())
-// DrawGrid();
-
/* If too much changes (begin observing new game, etc.), don't
do flashing */
do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1;
/* Special check for castling so we don't flash both the king
and the rook (just flash the king). */
if (do_flash) {
- if (check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) {
+ if(check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) {
/* Mark rook for drawing with NO flashing. */
damage[nr][rrow][rcol] |= 1;
}
}
- /* First pass -- Draw (newly) empty squares and repair damage.
+ /* First pass -- Erase arrow and grid highlights, but keep square content unchanged. Except for new markers. */
+ for (i = 0; i < BOARD_HEIGHT; i++)
+ for (j = 0; j < BOARD_WIDTH; j++)
+ if (damage[nr][i][j] || !nr && marker[i][j] != lastMarker[i][j]) {
+ DrawSquare(i, j, board[i][j], 0);
+ if(lineGap && damage[nr][i][j] & 2) {
+ drawHighlight(j, i, 0);
+ SquareExpose(i, j, lineGap);
+ } else SquareExpose(i, j, 0);
+ damage[nr][i][j] = 0;
+ }
+
+ /* Second pass -- Draw (newly) empty squares
This prevents you from having a piece show up twice while it
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] || !nr && marker[i][j] != lastMarker[i][j]) && board[i][j] == EmptySquare)
- || damage[nr][i][j]) {
+ if (board[i][j] != lastBoard[nr][i][j] && board[i][j] == EmptySquare) {
DrawSquare(i, j, board[i][j], 0);
- if(damage[nr][i][j] & 2) {
- drawHighlight(j, i, 0); // repair arrow damage
- if(lineGap) damage[nr][i][j] = False; // this flushed the square as well
- } else damage[nr][i][j] = 1; // mark for expose
+ SquareExpose(i, j, 0);
}
- /* Second pass -- Draw piece(s) in new position and flash them */
+ /* Third 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] || !nr && marker[i][j] != lastMarker[i][j]) {
- DrawSquare(i, j, board[i][j], do_flash);
+ if (board[i][j] != lastBoard[nr][i][j]) {
+ DrawSquare(i, j, board[i][j], do_flash && (i != rrow || j != rcol));
damage[nr][i][j] = 1; // mark for expose
}
+
} else {
if (lineGap > 0)
DrawGrid();
/* Draw highlights */
if (pm1X >= 0 && pm1Y >= 0) {
drawHighlight(pm1X, pm1Y, 2);
- if(lineGap) damage[nr][pm1Y][pm1X] = False;
+ if(lineGap) damage[nr][pm1Y][pm1X] |= 2;
}
if (pm2X >= 0 && pm2Y >= 0) {
drawHighlight(pm2X, pm2Y, 2);
- if(lineGap) damage[nr][pm2Y][pm2X] = False;
+ if(lineGap) damage[nr][pm2Y][pm2X] |= 2;
}
if (hi1X >= 0 && hi1Y >= 0) {
drawHighlight(hi1X, hi1Y, 1);
- if(lineGap) damage[nr][hi1Y][hi1X] = False;
+ if(lineGap) damage[nr][hi1Y][hi1X] |= 2;
}
if (hi2X >= 0 && hi2Y >= 0) {
drawHighlight(hi2X, hi2Y, 1);
- if(lineGap) damage[nr][hi2Y][hi2X] = False;
+ if(lineGap) damage[nr][hi2Y][hi2X] |= 2;
}
DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y);
}
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);
+ SquareExpose(i, j, 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
+ SquareExpose(i, j, 0);
+ if(nr == 0) damage[nr][i][j] = 0; // on auxiliary board we retain arrow damage
}
}
else {
TimeMark now;
GetTimeMark(&now);
- if(SubtractTimeMarks(&now, &programStartTime) < 1000) {
- DrawSeekBackground(2*squareSize, 3*squareSize, 6*squareSize, 5*squareSize);
- DrawText("Right-clicking dialog texts", 2*squareSize + 5, 3*squareSize + 5, 2);
- DrawText("pops up help on them", 2*squareSize + 5, (int) (3.3*squareSize) + 5, 2);
+ if(repaint && SubtractTimeMarks(&now, &programStartTime) < 1000) {
+ char *p = appData.message, *q;
+ i = 0;
+ while(*p) {
+ q = strchr(p, '\n');
+ if(q) *q = NULLCHAR;
+ if(!strstr(appData.suppress, p)) {
+ if(i == 0) DrawSeekBackground(2*squareSize, 3*squareSize, 6.5*squareSize, 5*squareSize);
+ DrawText(p, 2*squareSize + 5, (int) ((3 + 0.3*i++)*squareSize) + 5, 2);
+ }
+ if(q) *q++ = '\n'; else q = "";
+ p = q;
+ }
GraphExpose(currBoard, 2*squareSize, 3*squareSize, 4*squareSize, 2*squareSize);
messedUp = TRUE;
} else messedUp = FALSE;