]> git.pld-linux.org Git - packages/xboard.git/blame - xboard-hilight-threatened-pieces.patch
- stollen from MDK
[packages/xboard.git] / xboard-hilight-threatened-pieces.patch
CommitLineData
1c92b12d
PG
1--- xboard-4.2.7/common.h.hilite 2005-06-03 09:04:12.000000000 +0800
2+++ xboard-4.2.7/common.h 2005-06-03 09:33:57.000000000 +0800
3@@ -130,6 +130,8 @@ int pclose(FILE *);
4 #define DARK_SQUARE_COLOR "#77A26D"
5 #define JAIL_SQUARE_COLOR "#808080"
6 #define HIGHLIGHT_SQUARE_COLOR "#FFFF00"
7+#define MOVE_SQUARE_COLOR "#4C00FF"
8+#define THREATENED_SQUARE_COLOR "#D80000"
9 #define PREMOVE_HIGHLIGHT_COLOR "#FF0000"
10 #define BELLCHAR '\007'
11 #define NULLCHAR '\000'
12@@ -265,6 +267,8 @@ typedef struct {
13 char *darkSquareColor;
14 char *jailSquareColor;
15 char *highlightSquareColor;
16+ char *moveSquareColor;
17+ char *threatenedSquareColor;
18 char *premoveHighlightColor;
19 #else
20 int whitePieceColor;
21@@ -273,6 +277,7 @@ typedef struct {
22 int darkSquareColor;
23 int jailSquareColor;
24 int highlightSquareColor;
25+ int moveSquareColor;
26 int premoveHighlightColor;
27 #endif
28 int movesPerSession;
29@@ -424,6 +429,8 @@ typedef struct {
30 char *zippyVariants;
31 int zippyMaxGames;
32 int zippyReplayTimeout; /*seconds*/
33+ Boolean showLegalMoves;
34+ Boolean showThreatenedPieces;
35 #endif
36 #if LOWTIMEWARNING
37 char *lowTimeWarningColor;
38--- xboard-4.2.7/xboard.h.hilite 2005-06-03 09:04:12.000000000 +0800
39+++ xboard-4.2.7/xboard.h 2005-06-03 09:33:57.000000000 +0800
40@@ -113,6 +113,7 @@ typedef struct {
41
42 typedef int (*FileProc) P((FILE *f, int n, char *title));
43 void CatchDeleteWindow(Widget w, String procname);
44+void ShowThreatenedPieces(Board board);
45
46 #define TOPLEVEL 1 /* preference item; 1 = make popup windows toplevel */
47
48--- xboard-4.2.7/xboard.c.hilite 2005-06-03 09:04:12.000000000 +0800
49+++ xboard-4.2.7/xboard.c 2005-06-03 09:45:55.000000000 +0800
50@@ -185,6 +185,7 @@ extern char *getenv();
51 #include "common.h"
52 #include "frontend.h"
53 #include "backend.h"
54+#include "backendz.h"
55 #include "moves.h"
56 #include "xboard.h"
57 #include "childio.h"
58@@ -385,6 +386,10 @@ void ShowThinkingProc P((Widget w, XEven
59 Cardinal *nprms));
60 void TestLegalityProc P((Widget w, XEvent *event, String *prms,
61 Cardinal *nprms));
62+void ShowLegalMovesProc P((Widget w, XEvent *event, String *prms,
63+ Cardinal *nprms));
64+void ShowThreatenedPiecesProc P((Widget w, XEvent *event, String *prms,
65+ Cardinal *nprms));
66 void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
67 void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
68 void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
69@@ -408,6 +413,9 @@ static void DragPieceEnd P((int x, int y
70 static void DrawDragPiece P((void));
71 char *ModeToWidgetName P((GameMode mode));
72
73+static void ShowLegalPieceSquares(int boardX,int boardY);
74+static void UnShowLegalPieceSquares();
75+
76 /*
77 * XBoard depends on Xt R4 or higher
78 */
79@@ -417,6 +425,7 @@ int xScreen;
80 Display *xDisplay;
81 Window xBoardWindow;
82 Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor,
83+ moveSquareColor, threatenedSquareColor,
84 jailSquareColor, highlightSquareColor, premoveHighlightColor;
85 #if LOWTIMEWARNING
86 Pixel lowTimeWarningColor;
87@@ -608,6 +617,8 @@ MenuItem optionsMenu[] = {
88 {"Show Coords", ShowCoordsProc},
89 {"Show Thinking", ShowThinkingProc},
90 {"Test Legality", TestLegalityProc},
91+ {"Show Legal Moves",ShowLegalMovesProc},
92+ {"Show Threatened Pieces",ShowThreatenedPiecesProc},
93 {NULL, NULL}
94 };
95
96@@ -742,6 +753,12 @@ XtResource clientResources[] = {
97 { "highlightSquareColor", "highlightSquareColor", XtRString,
98 sizeof(String), XtOffset(AppDataPtr, highlightSquareColor),
99 XtRString, HIGHLIGHT_SQUARE_COLOR },
100+ { "moveSquareColor", "moveSquareColor", XtRString,
101+ sizeof(String), XtOffset(AppDataPtr, moveSquareColor),
102+ XtRString, MOVE_SQUARE_COLOR },
103+ { "threatenedSquareColor", "threatenedSquareColor", XtRString,
104+ sizeof(String), XtOffset(AppDataPtr, threatenedSquareColor),
105+ XtRString, THREATENED_SQUARE_COLOR },
106 { "premoveHighlightColor", "premoveHighlightColor", XtRString,
107 sizeof(String), XtOffset(AppDataPtr, premoveHighlightColor),
108 XtRString, PREMOVE_HIGHLIGHT_COLOR },
109@@ -1155,6 +1172,8 @@ XrmOptionDescRec shellOptions[] = {
110 { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
111 { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
112 { "-highlightSquareColor", "highlightSquareColor", XrmoptionSepArg, NULL },
113+ { "-moveSquareColor", "moveSquareColor", XrmoptionSepArg, NULL },
114+ { "-threatenedSquareColor", "threatenedSquareColor", XrmoptionSepArg, NULL },
115 { "-premoveHighlightColor", "premoveHighlightColor", XrmoptionSepArg,NULL},
116 { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
117 { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
118@@ -1537,6 +1556,7 @@ XtActionsRec boardActions[] = {
119 { "ShowCoordsProc", ShowCoordsProc },
120 { "ShowThinkingProc", ShowThinkingProc },
121 { "TestLegalityProc", TestLegalityProc },
122+ { "ShowLegalMovesProc", ShowLegalMovesProc },
123 { "InfoProc", InfoProc },
124 { "ManProc", ManProc },
125 { "HintProc", HintProc },
126@@ -2097,6 +2117,30 @@ main(argc, argv)
127 }
128
129 if (!appData.monoMode) {
130+ vFrom.addr = (caddr_t) appData.moveSquareColor;
131+ vFrom.size = strlen(appData.moveSquareColor);
132+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
133+ if (vTo.addr == NULL) {
134+ appData.monoMode = True;
135+ forceMono = True;
136+ } else {
137+ moveSquareColor = *(Pixel *) vTo.addr;
138+ }
139+ }
140+
141+ if (!appData.monoMode) {
142+ vFrom.addr = (caddr_t) appData.threatenedSquareColor;
143+ vFrom.size = strlen(appData.threatenedSquareColor);
144+ XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
145+ if (vTo.addr == NULL) {
146+ appData.monoMode = True;
147+ forceMono = True;
148+ } else {
149+ threatenedSquareColor = *(Pixel *) vTo.addr;
150+ }
151+ }
152+
153+ if (!appData.monoMode) {
154 vFrom.addr = (caddr_t) appData.premoveHighlightColor;
155 vFrom.size = strlen(appData.premoveHighlightColor);
156 XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
157@@ -4315,6 +4359,7 @@ void XDrawPosition(w, repaint, board)
158
159 /* If piece being dragged around board, must redraw that too */
160 DrawDragPiece();
161+ ShowThreatenedPieces(board);
162
163 XSync(xDisplay, False);
164 }
165@@ -6306,6 +6351,43 @@ void BlindfoldProc(w, event, prms, nprms
166 DrawPosition(True, NULL);
167 }
168
169+/* show legal moves on board when moving/dragging a piece */
170+void ShowLegalMovesProc(w, event, prms, nprms)
171+ Widget w;
172+ XEvent *event;
173+ String *prms;
174+ Cardinal *nprms;
175+{
176+ Arg args[16];
177+ appData.showLegalMoves = !appData.showLegalMoves;
178+
179+ if (appData.showLegalMoves) {
180+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
181+ } else {
182+ XtSetArg(args[0], XtNleftBitmap, None);
183+ }
184+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Legal Moves"),
185+ args, 1);
186+}
187+
188+void ShowThreatenedPiecesProc(w, event, prms, nprms)
189+ Widget w;
190+ XEvent *event;
191+ String *prms;
192+ Cardinal *nprms;
193+{
194+ Arg args[16];
195+ appData.showThreatenedPieces = !appData.showThreatenedPieces;
196+
197+ if (appData.showThreatenedPieces) {
198+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
199+ } else {
200+ XtSetArg(args[0], XtNleftBitmap, None);
201+ }
202+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Threatened Pieces"),
203+ args, 1);
204+}
205+
206 void TestLegalityProc(w, event, prms, nprms)
207 Widget w;
208 XEvent *event;
209@@ -8344,6 +8426,7 @@ EndAnimation (anim, finish)
210 0, 0, squareSize, squareSize,
211 anim->prevFrame.x, anim->prevFrame.y);
212 }
213+
214 }
215
216 static void
217@@ -8464,6 +8547,10 @@ DragPieceBegin(x, y)
218 if (player.dragPiece >= 0 && player.dragPiece < EmptySquare) {
219 player.dragActive = True;
220 BeginAnimation(&player, player.dragPiece, color, &corner);
221+
222+ /* show the squares where this piece can be legally moved */
223+ ShowLegalPieceSquares(fromX,fromY);
224+
225 /* Mark this square as needing to be redrawn. Note that
226 we don't remove the piece though, since logically (ie
227 as seen by opponent) the move hasn't been made yet. */
228@@ -8473,6 +8560,93 @@ DragPieceBegin(x, y)
229 }
230 }
231
232+/* squares that are highlighted from moving a piece */
233+static int xHighlights[BOARD_SIZE*BOARD_SIZE];
234+static int yHighlights[BOARD_SIZE*BOARD_SIZE];
235+
236+/* highlight squares where legal moves can be made by current piece */
237+static void ShowLegalPieceSquares(boardX,boardY)
238+ int boardX;int boardY;
239+{
240+
241+ int x, y, currHighlight = 0, i = 0;
242+
243+ if ( ! appData.showLegalMoves ) return;
244+
245+ for ( i = 0 ; i < BOARD_SIZE; i++ )
246+ {
247+ xHighlights[i] = -1;
248+ yHighlights[i] = -1;
249+ }
250+
251+ for ( x = 0; x < BOARD_SIZE ; x++)
252+ {
253+ for ( y = 0 ; y < BOARD_SIZE; y++)
254+ {
255+ int legalmove = LegalityTest(boards[currentMove],
256+ PosFlags(currentMove),
257+ EP_UNKNOWN, fromY, fromX, y,x,0);
258+#ifdef DEBUG_MOVE_PIECES
259+ printf("Move from %d %d to %d %d == %s - currentMove = %d\n",fromX,fromY,x,y,(legalmove == IllegalMove || legalmove == ImpossibleMove)?"Illegal move":"Legal move",currentMove);
260+
261+#endif
262+
263+ if ( legalmove != IllegalMove && legalmove != ImpossibleMove)
264+ {
265+ XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
266+ | GCBackground | GCFunction | GCPlaneMask;
267+ XGCValues gc_values;
268+ gc_values.plane_mask = AllPlanes;
269+ gc_values.line_width = lineGap;
270+ gc_values.line_style = LineSolid;
271+ gc_values.function = GXcopy;
272+
273+#ifdef DEBUG_MOVE_PIECES
274+ printf("Highlight x = %d y = %d\n",x,y);
275+#endif
276+ gc_values.foreground = moveSquareColor;
277+ gc_values.background = moveSquareColor;
278+
279+ drawHighlight(x,y,XtGetGC(shellWidget, value_mask, &gc_values));
280+ xHighlights[currHighlight] = x;
281+ yHighlights[currHighlight] = y;
282+ currHighlight++;
283+ }
284+ }
285+ }
286+}
287+
288+/* remove highlights from squares that were highlighted
289+ as a result of picking up a piece and showing the legal moves */
290+static void UnShowLegalPieceSquares()
291+{
292+ int i = 0;
293+ GC clearpieceGC;
294+ XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
295+ | GCBackground | GCFunction | GCPlaneMask;
296+ XGCValues gc_values;
297+ if ( ! appData.showLegalMoves ) return;
298+
299+ gc_values.plane_mask = AllPlanes;
300+ gc_values.line_width = lineGap;
301+ gc_values.line_style = LineSolid;
302+ gc_values.function = GXcopy;
303+
304+ gc_values.foreground = jailSquareColor;
305+ gc_values.background = jailSquareColor;
306+
307+ for ( i = 0 ; i < BOARD_SIZE*BOARD_SIZE && xHighlights[i] != -1 && yHighlights[i] != -1; i++ )
308+ {
309+ clearpieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
310+#ifdef DEBUG_MOVE_PIECES
311+ printf("Erasing %d %d\n",BOARD_SIZE*BOARD_SIZE,xHighlights[i],yHighlights[i]);
312+#endif
313+ drawHighlight(xHighlights[i], yHighlights[i],clearpieceGC);
314+ xHighlights[i] = -1;
315+ yHighlights[i] = -1;
316+ }
317+}
318+
319 static void
320 DragPieceMove(x, y)
321 int x; int y;
322@@ -8492,7 +8666,8 @@ DragPieceMove(x, y)
323 corner.y = y - player.mouseDelta.y;
324 AnimationFrame(&player, &corner, player.dragPiece);
325 #if HIGHDRAG
326- if (appData.highlightDragging) {
327+ if (appData.highlightDragging)
328+ {
329 int boardX, boardY;
330 BoardSquare(x, y, &boardX, &boardY);
331 SetHighlights(fromX, fromY, boardX, boardY);
332@@ -8526,12 +8701,156 @@ DragPieceEnd(x, y)
333 /* This prevents weird things happening with fast successive
334 clicks which on my Sun at least can cause motion events
335 without corresponding press/release. */
336+
337+ /* un highlight the squares where the piece can be legally moved */
338+ UnShowLegalPieceSquares();
339 player.dragActive = False;
340 }
341
342+/* return false (0) if not a white piece, true otherwise */
343+static int WhitePiece(piece)
344+ ChessSquare piece;
345+{
346+ return (int) piece >= (int) WhitePawn && (int) piece <= (int) WhiteKing;
347+}
348+
349+/* return false (0) if not a black piece, true otherwise */
350+static int BlackPiece(piece)
351+ ChessSquare piece;
352+{
353+ return (int) piece >= (int) BlackPawn && (int) piece <= (int) BlackKing;
354+}
355+
356+/* used for keeping track of whether a move was made or a
357+ screen refresh has occured */
358+static int old_currentMove = -1;
359+/* 2d array of board positions, used to indicate which
360+ square to highlight as threatened */
361+static int threatenedSquares[BOARD_SIZE][BOARD_SIZE];
362+
363+/* called from ShowThreatenedPieces, redraw screen (refresh) */
364+static void redrawBoard(Board board)
365+{
366+ int i, j;
367+ /* setup colors to show threatened squares */
368+ XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
369+ | GCBackground | GCFunction | GCPlaneMask;
370+ XGCValues gc_values;
371+ gc_values.plane_mask = AllPlanes;
372+ gc_values.line_width = lineGap;
373+ gc_values.line_style = LineSolid;
374+ gc_values.function = GXcopy;
375+
376+ gc_values.foreground = threatenedSquareColor;
377+ gc_values.background = threatenedSquareColor;
378+
379+ /* iterate through board and highlight threatened pieces */
380+ for ( i = 0 ; i < BOARD_SIZE ; i++ )
381+ for ( j = 0 ; j < BOARD_SIZE ; j++ )
382+ if ( threatenedSquares[i][j] == 1 )
383+ drawHighlight(j,i,XtGetGC(shellWidget, value_mask, &gc_values));
384+}
385+
386+void ShowThreatenedPieces(Board board)
387+{
388+ int x, y, boardX, boardY;
389+
390+ if ( !appData.showThreatenedPieces) return;
391+
392+ if ( old_currentMove == currentMove)
393+ redrawBoard(board);
394+ else /* piece was moved on the board */
395+ {
396+ int i, j;
397+
398+ /* setup color for threatened pieces squares */
399+ old_currentMove = currentMove;
400+ GC clearpieceGC;
401+ XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
402+ | GCBackground | GCFunction | GCPlaneMask;
403+ XGCValues gc_values;
404+
405+ gc_values.plane_mask = AllPlanes;
406+ gc_values.line_width = lineGap;
407+ gc_values.line_style = LineSolid;
408+ gc_values.function = GXcopy;
409+
410+ gc_values.foreground = jailSquareColor;
411+ gc_values.background = jailSquareColor;
412+
413+ clearpieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
414+
415+ /* clear previous storage of threatened squares coords */
416+ for ( i = 0 ; i < BOARD_SIZE ; i++ )
417+ for ( j = 0 ; j < BOARD_SIZE ; j++ )
418+ if (threatenedSquares[i][j] == 1 )
419+ {
420+ drawHighlight(j,i ,clearpieceGC);
421+ threatenedSquares[i][j] = 0 ;
422+ }
423+
424+ /* determine which squares need to be highlightened
425+ as threatened */
426+ for(boardX = 0 ; boardX < BOARD_SIZE ; boardX++ )
427+ for ( boardY = 0 ; boardY < BOARD_SIZE ; boardY++ )
428+ {
429+ /* not worth continuing if from or to square is blank */
430+ if ( !WhitePiece(board[boardY][boardX]) &&
431+ !BlackPiece(board[boardY][boardX]))
432+ continue;
433+
434+ for ( toX = 0; toX < BOARD_SIZE ; toX++)
435+ {
436+ for ( toY = 0 ; toY < BOARD_SIZE; toY++)
437+ {
438+ int legalmove, legalmove2;
439+ /* test if it's worth continuing, from piece moving to
440+ opponent piece */
441+ if ( !WhitePiece(board[toY][toX]) &&
442+ !BlackPiece(board[toY][toX]))
443+ continue;
444+
445+ if ( BlackPiece(board[boardY][boardX]) &&
446+ !WhitePiece(board[toY][toX]) )
447+ continue;
448+
449+ if ( WhitePiece(board[boardY][boardX]) &&
450+ !BlackPiece(board[toY][toX]) )
451+ continue;
452+
453+ /* the Posflags in the LegalityTest needs to be -1 because
454+ the LegalityTest is done for the current move, which is updated
455+ when the current piece was put down and switched to the other color
456+ whereas we want the legality test for the old color otherwise
457+ it will be classified as an IllegalMove */
458+
459+ /* legal moves for the previous color (user) */
460+ legalmove = LegalityTest(boards[currentMove],
461+ PosFlags(currentMove)-1,
462+ EP_UNKNOWN,
463+ boardY, boardX, toY,toX,0);
464+
465+ /* legal moves for the current color (user) */
466+ legalmove2 = LegalityTest(boards[currentMove],
467+ PosFlags(currentMove),
468+ EP_UNKNOWN,
469+ boardY, boardX, toY,toX,0);
470+
471+ if ( legalmove != IllegalMove ||
472+ legalmove2 != IllegalMove)
473+ threatenedSquares[toY][toX] = 1;
474+ }
475+ }
476+ }
477+ }
478+ /* redraw the board to reflect current changes */
479+ redrawBoard(board);
480+}
481+
482 /* Handle expose event while piece being dragged */
483
484-static void
485+static
486+void
487 DrawDragPiece ()
488 {
489 if (!player.dragActive || appData.blindfold)
490--- xboard-4.2.7/backend.c.hilite 2003-11-28 17:37:36.000000000 +0800
491+++ xboard-4.2.7/backend.c 2005-06-03 09:33:57.000000000 +0800
492@@ -4858,6 +4858,7 @@ ShowMove(fromX, fromY, toX, toY)
493 DrawPosition(FALSE, boards[currentMove]);
494 DisplayBothClocks();
495 HistorySet(parseList,backwardMostMove,forwardMostMove,currentMove-1);
496+ ShowThreatenedPieces(boards[currentMove]);
497 }
498
499
This page took 0.715417 seconds and 4 git commands to generate.