#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
+#include <math.h>
#if !OMIT_SOCKETS
# if HAVE_SYS_SOCKET_H
Cardinal *nprms));
void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
Cardinal *nprms));
+void HighlightArrowProc P((Widget w, XEvent *event, String *prms,
+ Cardinal *nprms));
void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
- Cardinal *nprms));
+void OneClickProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms,
Cardinal *nprms));
void PonderNextMoveProc P((Widget w, XEvent *event, String *prms,
void update_ics_width P(());
int get_term_width P(());
int CopyMemoProc P(());
+void DrawArrowHighlight P((int fromX, int fromY, int toX,int toY));
+Boolean IsDrawArrowEnabled P(());
+
/*
* XBoard depends on Xt R4 or higher
*/
SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
MenuItem fileMenu[] = {
- {N_("New Game"), "New Game", ResetProc},
- {N_("New Shuffle Game ..."), "New Shuffle Game", ShuffleMenuProc},
- {N_("New Variant ..."), "New Variant", NewVariantProc}, // [HGM] variant: not functional yet
+ {N_("New Game Ctrl+N"), "New Game", ResetProc},
+ {N_("New Shuffle Game ..."), "New Shuffle Game", ShuffleMenuProc},
+ {N_("New Variant ... Alt+Shift+V"), "New Variant", NewVariantProc}, // [HGM] variant: not functional yet
{"----", NULL, NothingProc},
- {N_("Load Game"), "Load Game", LoadGameProc},
- {N_("Load Position"), "Load Position", LoadPositionProc},
+ {N_("Load Game Ctrl+O"), "Load Game", LoadGameProc},
+ {N_("Load Position Ctrl+Shift+O"), "Load Position", LoadPositionProc},
// {N_("Load Next Game"), "Load Next Game", LoadNextGameProc},
// {N_("Load Previous Game"), "Load Previous Game", LoadPrevGameProc},
// {N_("Reload Same Game"), "Reload Same Game", ReloadGameProc},
// {N_("Load Next Position"), "Load Next Position", LoadNextPositionProc},
// {N_("Load Previous Position"), "Load Previous Position", LoadPrevPositionProc},
// {N_("Reload Same Position"), "Reload Same Position", ReloadPositionProc},
- {N_("Save Game"), "Save Game", SaveGameProc},
- {N_("Save Position"), "Save Position", SavePositionProc},
+ {N_("Save Game Ctrl+S"), "Save Game", SaveGameProc},
+ {N_("Save Position Ctrl+Shift+S"), "Save Position", SavePositionProc},
{"----", NULL, NothingProc},
{N_("Mail Move"), "Mail Move", MailMoveProc},
{N_("Reload CMail Message"), "Reload CMail Message", ReloadCmailMsgProc},
{"----", NULL, NothingProc},
- {N_("Exit"), "Exit", QuitProc},
+ {N_("Quit Ctr+Q"), "Exit", QuitProc},
{NULL, NULL, NULL}
};
MenuItem editMenu[] = {
- {N_("Copy Game"), "Copy Game", CopyGameProc},
- {N_("Copy Position"), "Copy Position", CopyPositionProc},
+ {N_("Copy Game Ctrl+C"), "Copy Game", CopyGameProc},
+ {N_("Copy Position Ctrl+Shift+C"), "Copy Position", CopyPositionProc},
{"----", NULL, NothingProc},
- {N_("Paste Game"), "Paste Game", PasteGameProc},
- {N_("Paste Position"), "Paste Position", PastePositionProc},
+ {N_("Paste Game Ctrl+V"), "Paste Game", PasteGameProc},
+ {N_("Paste Position Ctrl+Shift+V"), "Paste Position", PastePositionProc},
{"----", NULL, NothingProc},
- {N_("Edit Game"), "Edit Game", EditGameProc},
- {N_("Edit Position"), "Edit Position", EditPositionProc},
+ {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc},
+ {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc},
+ {N_("Edit Tags"), "Edit Tags", EditTagsProc},
+ {N_("Edit Comment"), "Edit Comment", EditCommentProc},
{"----", NULL, NothingProc},
- {N_("Edit Tags"), "Edit Tags", EditTagsProc},
- {N_("Edit Comment"), "Edit Comment", EditCommentProc},
+ {N_("Revert Home"), "Revert", RevertProc},
+ {N_("Annotate"), "Annotate", AnnotateProc},
+ {N_("Truncate Game End"), "Truncate Game", TruncateGameProc},
{"----", NULL, NothingProc},
- {N_("Revert"), "Revert", RevertProc},
- {N_("Annotate"), "Annotate", AnnotateProc},
- {N_("Truncate Game"), "Truncate Game", TruncateGameProc},
- {"----", NULL, NothingProc},
- {N_("Backward"), "Backward", BackwardProc},
- {N_("Forward"), "Forward", ForwardProc},
- {N_("Back to Start"), "Back to Start", ToStartProc},
- {N_("Forward to End"), "Forward to End", ToEndProc},
+ {N_("Backward Alt+Left"), "Backward", BackwardProc},
+ {N_("Forward Alt+Right"), "Forward", ForwardProc},
+ {N_("Back to Start Alt+Home"), "Back to Start", ToStartProc},
+ {N_("Forward to End Alt+End"), "Forward to End", ToEndProc},
{NULL, NULL, NULL}
};
MenuItem viewMenu[] = {
- {N_("Flip View"), "Flip View", FlipViewProc},
+ {N_("Flip View F2"), "Flip View", FlipViewProc},
{"----", NULL, NothingProc},
- {N_("Engine Output"), "Show Engine Output", EngineOutputProc},
- {N_("Evaluation Graph"), "Show Evaluation Graph", EvalGraphProc},
- {N_("Game List"), "Show Game List", ShowGameListProc},
- {N_("Move History"), "Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
+ {N_("Engine Output Alt+Shift+O"), "Show Engine Output", EngineOutputProc},
+ {N_("Move History Alt+Shift+H"), "Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
+ {N_("Evaluation Graph Alt+Shift+E"), "Show Evaluation Graph", EvalGraphProc},
+ {N_("Game List Alt+Shift+G"), "Show Game List", ShowGameListProc},
{"----", NULL, NothingProc},
{N_("Tags"), "Show Tags", EditTagsProc},
{N_("Comments"), "Show Comments", EditCommentProc},
};
MenuItem modeMenu[] = {
- {N_("Machine White"), "Machine White", MachineWhiteProc},
- {N_("Machine Black"), "Machine Black", MachineBlackProc},
- {N_("Two Machines"), "Two Machines", TwoMachinesProc},
- {N_("Analysis Mode"), "Analysis Mode", AnalyzeModeProc},
- {N_("Analyze File"), "Analyze File", AnalyzeFileProc },
- {N_("Edit Game"), "Edit Game", EditGameProc},
- {N_("Edit Position"), "Edit Position", EditPositionProc},
+ {N_("Machine White Ctrl+W"), "Machine White", MachineWhiteProc},
+ {N_("Machine Black Ctrl+B"), "Machine Black", MachineBlackProc},
+ {N_("Two Machines Ctrl+T"), "Two Machines", TwoMachinesProc},
+ {N_("Analysis Mode Ctrl+A"), "Analysis Mode", AnalyzeModeProc},
+ {N_("Analyze File Ctrl+F"), "Analyze File", AnalyzeFileProc },
+ {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc},
+ {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc},
{N_("Training"), "Training", TrainingProc},
{N_("ICS Client"), "ICS Client", IcsClientProc},
{"----", NULL, NothingProc},
- {N_("Pause"), "Pause", PauseProc},
+ {N_("Pause Pause"), "Pause", PauseProc},
{NULL, NULL, NULL}
};
MenuItem actionMenu[] = {
- {N_("Accept"), "Accept", AcceptProc},
- {N_("Decline"), "Decline", DeclineProc},
- {N_("Rematch"), "Rematch", RematchProc},
+ {N_("Accept F3"), "Accept", AcceptProc},
+ {N_("Decline F4"), "Decline", DeclineProc},
+ {N_("Rematch F12"), "Rematch", RematchProc},
{"----", NULL, NothingProc},
- {N_("Call Flag"), "Call Flag", CallFlagProc},
- {N_("Draw"), "Draw", DrawProc},
- {N_("Adjourn"), "Adjourn", AdjournProc},
- {N_("Abort"), "Abort", AbortProc},
- {N_("Resign"), "Resign", ResignProc},
+ {N_("Call Flag F5"), "Call Flag", CallFlagProc},
+ {N_("Draw F6"), "Draw", DrawProc},
+ {N_("Adjourn F7"), "Adjourn", AdjournProc},
+ {N_("Abort F8"),"Abort", AbortProc},
+ {N_("Resign F9"), "Resign", ResignProc},
{"----", NULL, NothingProc},
- {N_("Stop Observing"), "Stop Observing", StopObservingProc},
- {N_("Stop Examining"), "Stop Examining", StopExaminingProc},
+ {N_("Stop Observing F10"), "Stop Observing", StopObservingProc},
+ {N_("Stop Examining F11"), "Stop Examining", StopExaminingProc},
{N_("Upload to Examine"), "Upload to Examine", UploadProc},
{"----", NULL, NothingProc},
{N_("Adjudicate to White"), "Adjudicate to White", AdjuWhiteProc},
{N_("Engine #1 Settings ..."), "Engine #1 Settings", FirstSettingsProc},
{N_("Engine #2 Settings ..."), "Engine #2 Settings", SecondSettingsProc},
{"----", NULL, NothingProc},
- {N_("Move Now"), "Move Now", MoveNowProc},
- {N_("Retract Move"), "Retract Move", RetractMoveProc},
+ {N_("Hint"), "Hint", HintProc},
+ {N_("Book"), "Book", BookProc},
+ {"----", NULL, NothingProc},
+ {N_("Move Now Ctrl+M"), "Move Now", MoveNowProc},
+ {N_("Retract Move Ctrl+X"), "Retract Move", RetractMoveProc},
{NULL, NULL, NULL}
};
MenuItem optionsMenu[] = {
- {N_("Time Control ..."), "Time Control", TimeControlProc},
- {N_("Common Engine ..."), "Common Engine", UciMenuProc},
- {N_("Adjudications ..."), "Adjudications", EngineMenuProc},
- {N_("Game List ..."), "Game List", GameListOptionsPopUp},
+ {N_("Time Control ... Alt+Shift+T"), "Time Control", TimeControlProc},
+ {N_("Common Engine ... Alt+Shift+U"), "Common Engine", UciMenuProc},
+ {N_("Adjudications ... Alt+Shift+J"), "Adjudications", EngineMenuProc},
+ {N_("Game List ..."), "Game List", GameListOptionsPopUp},
{"----", NULL, NothingProc},
- {N_("Always Queen"), "Always Queen", AlwaysQueenProc},
+ {N_("Always Queen Ctrl+Shift+Q"), "Always Queen", AlwaysQueenProc},
{N_("Animate Dragging"), "Animate Dragging", AnimateDraggingProc},
- {N_("Animate Moving"), "Animate Moving", AnimateMovingProc},
+ {N_("Animate Moving Ctrl+Shift+A"), "Animate Moving", AnimateMovingProc},
{N_("Auto Comment"), "Auto Comment", AutocommProc},
- {N_("Auto Flag"), "Auto Flag", AutoflagProc},
+ {N_("Auto Flag Ctrl+Shift+F"), "Auto Flag", AutoflagProc},
{N_("Auto Flip View"), "Auto Flip View", AutoflipProc},
{N_("Auto Observe"), "Auto Observe", AutobsProc},
{N_("Auto Raise Board"), "Auto Raise Board", AutoraiseProc},
{N_("Highlight Dragging"), "Highlight Dragging", HighlightDraggingProc},
#endif
{N_("Highlight Last Move"), "Highlight Last Move", HighlightLastMoveProc},
+ {N_("Highlight With Arrow"), "Arrow", HighlightArrowProc},
{N_("Move Sound"), "Move Sound", MoveSoundProc},
{N_("ICS Alarm"), "ICS Alarm", IcsAlarmProc},
- {N_("Old Save Style"), "Old Save Style", OldSaveStyleProc},
+ {N_("One-Click Moving"), "OneClick", OneClickProc},
{N_("Periodic Updates"), "Periodic Updates", PeriodicUpdatesProc},
- {N_("Ponder Next Move"), "Ponder Next Move", PonderNextMoveProc},
+ {N_("Ponder Next Move Ctrl+Shift+P"), "Ponder Next Move", PonderNextMoveProc},
{N_("Popup Exit Message"), "Popup Exit Message", PopupExitMessageProc},
{N_("Popup Move Errors"), "Popup Move Errors", PopupMoveErrorsProc},
{N_("Premove"), "Premove", PremoveProc},
{N_("Quiet Play"), "Quiet Play", QuietPlayProc},
{N_("Show Coords"), "Show Coords", ShowCoordsProc},
- {N_("Hide Thinking"), "Hide Thinking", HideThinkingProc},
- {N_("Test Legality"), "Test Legality", TestLegalityProc},
+ {N_("Hide Thinking Ctrl+Shift+H"), "Hide Thinking", HideThinkingProc},
+ {N_("Test Legality Ctrl+Shift+L"), "Test Legality", TestLegalityProc},
{"----", NULL, NothingProc},
{N_("Save Settings Now"), "Save Settings Now", SaveSettingsProc},
{N_("Save Settings on Exit"), "Save Settings on Exit", SaveOnExitProc},
};
MenuItem helpMenu[] = {
- {N_("Info XBoard"), "Info XBoard", InfoProc},
- {N_("Man XBoard"), "Man XBoard", ManProc},
- {"----", NULL, NothingProc},
- {N_("Hint"), "Hint", HintProc},
- {N_("Book"), "Book", BookProc},
+ {N_("Info XBoard"), "Info XBoard", InfoProc},
+ {N_("Man XBoard F1"), "Man XBoard", ManProc},
{"----", NULL, NothingProc},
{N_("About XBoard"), "About XBoard", AboutProc},
{NULL, NULL, NULL}
{ "HighlightLastMoveProc", HighlightLastMoveProc },
{ "IcsAlarmProc", IcsAlarmProc },
{ "MoveSoundProc", MoveSoundProc },
- { "OldSaveStyleProc", OldSaveStyleProc },
{ "PeriodicUpdatesProc", PeriodicUpdatesProc },
{ "PonderNextMoveProc", PonderNextMoveProc },
{ "PopupExitMessageProc", PopupExitMessageProc },
:Meta<Key>Right: ForwardProc() \n \
:Meta<Key>Home: ToStartProc() \n \
:Meta<Key>Left: BackwardProc() \n \
+ :<Key>Home: RevertProc() \n \
+ :<Key>End: TruncateGameProc() \n \
:Ctrl<Key>m: MoveNowProc() \n \
:Ctrl<Key>x: RetractMoveProc() \n \
:Meta<Key>J: EngineMenuProc() \n \
"menuOptions.Highlight Last Move"),
args, 1);
}
+ if (appData.highlightMoveWithArrow) {
+ XtSetValues(XtNameToWidget(menuBarWidget,
+ "menuOptions.Arrow"),
+ args, 1);
+ }
if (appData.icsAlarm) {
XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"),
args, 1);
XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"),
args, 1);
}
- if (appData.oldSaveStyle) {
+ if (appData.oneClick) {
XtSetValues(XtNameToWidget(menuBarWidget,
- "menuOptions.Old Save Style"), args, 1);
+ "menuOptions.OneClick"), args, 1);
}
if (appData.periodicUpdates) {
XtSetValues(XtNameToWidget(menuBarWidget,
{ "menuMode.Analyze File", False },
{ "menuMode.Two Machines", False },
#ifndef ZIPPY
- { "menuHelp.Hint", False },
- { "menuHelp.Book", False },
+ { "menuEngine.Hint", False },
+ { "menuEngine.Book", False },
{ "menuEngine.Move Now", False },
{ "menuOptions.Periodic Updates", False },
{ "menuOptions.Hide Thinking", False },
{ "menuOptions.Hide Thinking", False },
{ "menuOptions.Periodic Updates", False },
{ "menuOptions.Ponder Next Move", False },
- { "menuHelp.Hint", False },
- { "menuHelp.Book", False },
+ { "menuEngine.Hint", False },
+ { "menuEngine.Book", False },
{ NULL, False }
};
}
// [HGM] code borrowed from winboard.c (which should thus go to backend.c!)
-#define HISTORY_SIZE 64\r
-static char *history[HISTORY_SIZE];\r
-int histIn = 0, histP = 0;\r
-\r
-void\r
-SaveInHistory(char *cmd)\r
-{\r
- if (history[histIn] != NULL) {\r
- free(history[histIn]);\r
- history[histIn] = NULL;\r
- }\r
- if (*cmd == NULLCHAR) return;\r
- history[histIn] = StrSave(cmd);\r
- histIn = (histIn + 1) % HISTORY_SIZE;\r
- if (history[histIn] != NULL) {\r
- free(history[histIn]);\r
- history[histIn] = NULL;\r
- }\r
- histP = histIn;\r
-}\r
-\r
-char *\r
-PrevInHistory(char *cmd)\r
-{\r
- int newhp;\r
- if (histP == histIn) {\r
- if (history[histIn] != NULL) free(history[histIn]);\r
- history[histIn] = StrSave(cmd);\r
- }\r
- newhp = (histP - 1 + HISTORY_SIZE) % HISTORY_SIZE;\r
- if (newhp == histIn || history[newhp] == NULL) return NULL;\r
- histP = newhp;\r
- return history[histP];\r
-}\r
-\r
-char *\r
-NextInHistory()\r
-{\r
- if (histP == histIn) return NULL;\r
- histP = (histP + 1) % HISTORY_SIZE;\r
- return history[histP]; \r
-}
-// end of borrowed code\r
-\r
+#define HISTORY_SIZE 64
+static char *history[HISTORY_SIZE];
+int histIn = 0, histP = 0;
+
+void
+SaveInHistory(char *cmd)
+{
+ if (history[histIn] != NULL) {
+ free(history[histIn]);
+ history[histIn] = NULL;
+ }
+ if (*cmd == NULLCHAR) return;
+ history[histIn] = StrSave(cmd);
+ histIn = (histIn + 1) % HISTORY_SIZE;
+ if (history[histIn] != NULL) {
+ free(history[histIn]);
+ history[histIn] = NULL;
+ }
+ histP = histIn;
+}
+
+char *
+PrevInHistory(char *cmd)
+{
+ int newhp;
+ if (histP == histIn) {
+ if (history[histIn] != NULL) free(history[histIn]);
+ history[histIn] = StrSave(cmd);
+ }
+ newhp = (histP - 1 + HISTORY_SIZE) % HISTORY_SIZE;
+ if (newhp == histIn || history[newhp] == NULL) return NULL;
+ histP = newhp;
+ return history[histP];
+}
+
+char *
+NextInHistory()
+{
+ if (histP == histIn) return NULL;
+ histP = (histP + 1) % HISTORY_SIZE;
+ return history[histP];
+}
+// end of borrowed code
+
#define Abs(n) ((n)<0 ? -(n) : (n))
/*
{
int x, y;
- if (lineGap == 0 || appData.blindfold) return;
+ if (lineGap == 0) return;
if (flipView) {
x = lineGap/2 + ((BOARD_WIDTH-1)-file) *
}
break;
case MotionNotify:
- if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;\r
+ if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;
default:
return;
}
* but this causes a very distracting flicker.
*/
+ if ( lineGap && IsDrawArrowEnabled()) repaint = True;
if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) {
/* If too much changes (begin observing new game, etc.), don't
if (hi2X >= 0 && hi2Y >= 0) {
drawHighlight(hi2X, hi2Y, highlineGC);
}
+ DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y);
}
/* If piece being dragged around board, must redraw that too */
DrawDragPiece();
layout, args, j);
if(gameInfo.variant != VariantShogi) {
+ if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) {
+ XawDialogAddButton(dialog, _("Warlord"), PromotionCallback,
+ (XtPointer) dialog);
+ XawDialogAddButton(dialog, _("General"), PromotionCallback,
+ (XtPointer) dialog);
+ XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback,
+ (XtPointer) dialog);
+ XawDialogAddButton(dialog, _("Captain"), PromotionCallback,
+ (XtPointer) dialog);
+ } else {\r
XawDialogAddButton(dialog, _("Queen"), PromotionCallback,
(XtPointer) dialog);
XawDialogAddButton(dialog, _("Rook"), PromotionCallback,
(XtPointer) dialog);
XawDialogAddButton(dialog, _("Knight"), PromotionCallback,
(XtPointer) dialog);
+ }
if (!appData.testLegality || gameInfo.variant == VariantSuicide ||
+ gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) ||\r
gameInfo.variant == VariantGiveaway) {
XawDialogAddButton(dialog, _("King"), PromotionCallback,
(XtPointer) dialog);
"menuOptions.Highlight Last Move"), args, 1);
}
+void HighlightArrowProc(w, event, prms, nprms)
+ Widget w;
+ XEvent *event;
+ String *prms;
+ Cardinal *nprms;
+{
+ Arg args[16];
+
+ appData.highlightMoveWithArrow = !appData.highlightMoveWithArrow;
+
+ if (appData.highlightMoveWithArrow) {
+ XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
+ } else {
+ XtSetArg(args[0], XtNleftBitmap, None);
+ }
+ XtSetValues(XtNameToWidget(menuBarWidget,
+ "menuOptions.Arrow"), args, 1);
+}
+
void IcsAlarmProc(w, event, prms, nprms)
Widget w;
XEvent *event;
args, 1);
}
-
-void OldSaveStyleProc(w, event, prms, nprms)
+void OneClickProc(w, event, prms, nprms)
Widget w;
XEvent *event;
String *prms;
{
Arg args[16];
- appData.oldSaveStyle = !appData.oldSaveStyle;
+ appData.oneClick = !appData.oneClick;
- if (appData.oldSaveStyle) {
+ if (appData.oneClick) {
XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
} else {
XtSetArg(args[0], XtNleftBitmap, None);
}
- XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
+ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.OneClick"),
args, 1);
}
{
update_ics_width();
}
+
+/* [AS] Arrow highlighting support */
+
+static double A_WIDTH = 5; /* Width of arrow body */
+
+#define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */
+#define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */
+
+static double Sqr( double x )
+{
+ return x*x;
+}
+
+static int Round( double x )
+{
+ return (int) (x + 0.5);
+}
+
+void SquareToPos(int rank, int file, int *x, int *y)
+{
+ if (flipView) {
+ *x = lineGap + ((BOARD_WIDTH-1)-file) * (squareSize + lineGap);
+ *y = lineGap + rank * (squareSize + lineGap);
+ } else {
+ *x = lineGap + file * (squareSize + lineGap);
+ *y = lineGap + ((BOARD_HEIGHT-1)-rank) * (squareSize + lineGap);
+ }
+}
+
+/* Draw an arrow between two points using current settings */
+void DrawArrowBetweenPoints( int s_x, int s_y, int d_x, int d_y )
+{
+ XPoint arrow[7];
+ double dx, dy, j, k, x, y;
+
+ if( d_x == s_x ) {
+ int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;
+
+ arrow[0].x = s_x + A_WIDTH + 0.5;
+ arrow[0].y = s_y;
+
+ arrow[1].x = s_x + A_WIDTH + 0.5;
+ arrow[1].y = d_y - h;
+
+ arrow[2].x = arrow[1].x + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5;
+ arrow[2].y = d_y - h;
+
+ arrow[3].x = d_x;
+ arrow[3].y = d_y;
+
+ arrow[5].x = arrow[1].x - 2*A_WIDTH + 0.5;
+ arrow[5].y = d_y - h;
+
+ arrow[4].x = arrow[5].x - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5;
+ arrow[4].y = d_y - h;
+
+ arrow[6].x = arrow[1].x - 2*A_WIDTH + 0.5;
+ arrow[6].y = s_y;
+ }
+ else if( d_y == s_y ) {
+ int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;
+
+ arrow[0].x = s_x;
+ arrow[0].y = s_y + A_WIDTH + 0.5;
+
+ arrow[1].x = d_x - w;
+ arrow[1].y = s_y + A_WIDTH + 0.5;
+
+ arrow[2].x = d_x - w;
+ arrow[2].y = arrow[1].y + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5;
+
+ arrow[3].x = d_x;
+ arrow[3].y = d_y;
+
+ arrow[5].x = d_x - w;
+ arrow[5].y = arrow[1].y - 2*A_WIDTH + 0.5;
+
+ arrow[4].x = d_x - w;
+ arrow[4].y = arrow[5].y - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5;
+
+ arrow[6].x = s_x;
+ arrow[6].y = arrow[1].y - 2*A_WIDTH + 0.5;
+ }
+ else {
+ /* [AS] Needed a lot of paper for this! :-) */
+ dy = (double) (d_y - s_y) / (double) (d_x - s_x);
+ dx = (double) (s_x - d_x) / (double) (s_y - d_y);
+
+ j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) );
+
+ k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) );
+
+ x = s_x;
+ y = s_y;
+
+ arrow[0].x = Round(x - j);
+ arrow[0].y = Round(y + j*dx);
+
+ arrow[1].x = Round(arrow[0].x + 2*j); // [HGM] prevent width to be affected by rounding twice
+ arrow[1].y = Round(arrow[0].y - 2*j*dx);
+
+ if( d_x > s_x ) {
+ x = (double) d_x - k;
+ y = (double) d_y - k*dy;
+ }
+ else {
+ x = (double) d_x + k;
+ y = (double) d_y + k*dy;
+ }
+
+ x = Round(x); y = Round(y); // [HGM] make sure width of shaft is rounded the same way on both ends
+
+ arrow[6].x = Round(x - j);
+ arrow[6].y = Round(y + j*dx);
+
+ arrow[2].x = Round(arrow[6].x + 2*j);
+ arrow[2].y = Round(arrow[6].y - 2*j*dx);
+
+ arrow[3].x = Round(arrow[2].x + j*(A_WIDTH_FACTOR-1));
+ arrow[3].y = Round(arrow[2].y - j*(A_WIDTH_FACTOR-1)*dx);
+
+ arrow[4].x = d_x;
+ arrow[4].y = d_y;
+
+ arrow[5].x = Round(arrow[6].x - j*(A_WIDTH_FACTOR-1));
+ arrow[5].y = Round(arrow[6].y + j*(A_WIDTH_FACTOR-1)*dx);
+ }
+
+ XFillPolygon(xDisplay, xBoardWindow, highlineGC, arrow, 7, Nonconvex, CoordModeOrigin);
+// Polygon( hdc, arrow, 7 );
+}
+
+/* [AS] Draw an arrow between two squares */
+void DrawArrowBetweenSquares( int s_col, int s_row, int d_col, int d_row )
+{
+ int s_x, s_y, d_x, d_y, hor, vert, i;
+
+ if( s_col == d_col && s_row == d_row ) {
+ return;
+ }
+
+ /* Get source and destination points */
+ SquareToPos( s_row, s_col, &s_x, &s_y);
+ SquareToPos( d_row, d_col, &d_x, &d_y);
+
+ if( d_y > s_y ) {
+ d_y += squareSize / 2 - squareSize / 4; // [HGM] round towards same centers on all sides!
+ }
+ else if( d_y < s_y ) {
+ d_y += squareSize / 2 + squareSize / 4;
+ }
+ else {
+ d_y += squareSize / 2;
+ }
+
+ if( d_x > s_x ) {
+ d_x += squareSize / 2 - squareSize / 4;
+ }
+ else if( d_x < s_x ) {
+ d_x += squareSize / 2 + squareSize / 4;
+ }
+ else {
+ d_x += squareSize / 2;
+ }
+
+ s_x += squareSize / 2;
+ s_y += squareSize / 2;
+
+ /* Adjust width */
+ A_WIDTH = squareSize / 14.; //[HGM] make float
+
+ DrawArrowBetweenPoints( s_x, s_y, d_x, d_y );
+
+ if(lineGap == 0) {
+ // this is a good idea, but it only works when lineGap == 0, because 'damage' on grid lines is not repaired
+ hor = 64*s_col + 32; vert = 64*s_row + 32;
+ for(i=0; i<= 64; i++) {
+ damage[0][vert+6>>6][hor+6>>6] = True;
+ damage[0][vert-6>>6][hor+6>>6] = True;
+ damage[0][vert+6>>6][hor-6>>6] = True;
+ damage[0][vert-6>>6][hor-6>>6] = True;
+ hor += d_col - s_col; vert += d_row - s_row;
+ }
+ }
+}
+
+Boolean IsDrawArrowEnabled()
+{
+ return appData.highlightMoveWithArrow && squareSize >= 32;
+}
+
+void DrawArrowHighlight(int fromX, int fromY, int toX,int toY)
+{
+ if( IsDrawArrowEnabled() && fromX >= 0 && fromY >= 0 && toX >= 0 && toY >= 0)
+ DrawArrowBetweenSquares(fromX, fromY, toX, toY);
+}